magic-8.0.210/0000755000175000001440000000000012574746564011476 5ustar timusersmagic-8.0.210/plow/0000755000175000001440000000000012032325053012426 5ustar timusersmagic-8.0.210/plow/PlowJogs.c0000644000175000001440000004260510751423606014356 0ustar timusers/* * PlowJogs.c -- * * Jog cleanup. * * ********************************************************************* * * 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/plow/PlowJogs.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/undo.h" #include "plow/plow.h" #include "plow/plowInt.h" #include "utils/malloc.h" #include "debug/debug.h" /* Passed to filter functions */ Edge *jogEdge; /* Points to RHS edge of jog */ Rect *jogArea; /* Area in which jogs are eliminated, in * plowYankDef coordinates. */ int jogTopDir, jogBotDir; /* Direction of top and bottom of the outline * at the top and bottom of the jog candidate. */ Point jogTopPoint, jogBotPoint; /* Location of top and bot of above outline */ /* Used when applying plowing rules */ Rect *plowJogLHS; /* If non-NULL, it's also OK for any edge * along this rectangle's LHS to move as * a result of applying the plowing rules. */ bool plowJogMoved; /* TRUE if any other edges moved */ LinkedRect *plowJogEraseList; /* List of areas to erase */ Rect plowJogChangedArea; /* Area changed */ /* * Codes for jogTopDir, jogBotDir above. * For jogBotDir, we use the same codes, except "up" really means "down". */ #define J_N 0 /* Left via top of clip area */ #define J_NE 1 /* Left via RHS of clip area */ #define J_NW 2 /* Went up then turned left */ #define J_NES 3 /* Went up, turned right, then turned down */ #define J_NEN 4 /* Went up, turned right, then turned up */ /* Imports from PlowMain.c */ extern int plowInitialPaint(); /* Forward declarations */ int plowJogPropagateLeft(); int plowProcessJogFunc(); int plowJogMoveFunc(); int plowJogDragLHS(); int plowJogTopProc(); int plowJogBotProc(); extern void plowProcessJog(); /* * ---------------------------------------------------------------------------- * * plowCleanupJogs -- * * Clean up all jogs in the interior of the Rect 'area', in the CellDef * plowYankDef, by scanning from right to left and eliminating jogs if * we can do so without moving any new edges. * * Results: * None. * * Side effects: * Modifies the geometry of plowYankDef in the area 'area'. * Updates changedArea via GeoIncludes to reflect the area * modified by jog reduction. * * ---------------------------------------------------------------------------- */ void plowCleanupJogs(area, changedArea) Rect *area; Rect *changedArea; { Edge edge; /* * We use our own procedure for propagating the effects of * moving an edge. Instead of adding more edges to a queue, * our procedure simply keeps track of whether any edges moved * at all, since we won't want to eliminate a jog if it causes * other stuff to move. */ plowPropagateProcPtr = plowJogMoveFunc; /* Initialize the queue of edges to move */ plowQueueInit(area, area->r_xtop - area->r_xbot); /* We store the area changed in a global for easy access */ plowJogChangedArea = *changedArea; /* * Process as though the RHS of the area were an edge. * This means searching leftward for edges with material * on their LHS and space on their RHS. */ edge.e_x = edge.e_newx = area->r_xtop; edge.e_ybot = area->r_ybot; edge.e_ytop = area->r_ytop; edge.e_use = (CellUse *) NULL; edge.e_flags = 0; for (edge.e_pNum = PL_TECHDEPBASE; edge.e_pNum < DBNumPlanes; edge.e_pNum++) plowProcessJog(&edge, area); /* While edges remain, process them, and propagate leftward */ while (plowQueueRightmost(&edge)) plowProcessJog(&edge, area); /* Clean up */ plowQueueDone(); *changedArea = plowJogChangedArea; } /* * ---------------------------------------------------------------------------- * * plowProcessJog -- * * Process an edge between space and material for jog elimination. * The idea is to search to the left of this edge for jogs that * can be straightened without forcing other material to move. * We repeat this, searching for a jog and eliminating it, until * we can move no more jogs. * * When finally done, we search leftward for any edges between * space and material, and add these to the queue to be processed. * * The argument 'area' bounds the area in which jog elimination * will take place. * * Results: * None. * * Side effects: * Updates the geometry of plowYankDef. * * ---------------------------------------------------------------------------- */ void plowProcessJog(edge, area) Edge *edge; Rect *area; { Rect r; if (DebugIsSet(plowDebugID, plowDebJogs)) plowDebugEdge(edge, (RuleTableEntry *) NULL, "plowProcessJog"); /* Scan left from this edge to the LHS of the jog reduction area */ r.r_xbot = area->r_xbot; r.r_xtop = edge->e_x; r.r_ybot = edge->e_ybot; r.r_ytop = edge->e_ytop; /* * Scan leftward for edges between material and space. Such edges * are potentially jogs that can be removed. If plowProcessJogFunc * does in fact remove a jog containing one of the edges it finds, * it returns 1 and aborts. We must therefore iterate until no more * jogs are eliminated. */ while (plowSrShadowBack(edge->e_pNum, &r, DBSpaceBits, plowProcessJogFunc, (ClientData) area)) /* Nothing */; /* Scan to next edge between space and material */ (void) plowSrShadowBack(edge->e_pNum, &r, DBAllButSpaceBits, plowJogPropagateLeft, (ClientData) NULL); } /* * ---------------------------------------------------------------------------- * * plowJogPropagateLeft -- * * Called by plowSrShadowBack(), we add edges between space and material * to the queue for further processing. * * Results: * Always returns 0. * * Side effects: * Adds the edge to the queue of edges to move via plowQueueAdd() * if e_ltype == TT_SPACE and e_rtype != TT_SPACE. * Leaves edge->e_newx == edge->e_x. * * ---------------------------------------------------------------------------- */ int plowJogPropagateLeft(edge) Edge *edge; { if (DebugIsSet(plowDebugID, plowDebJogs)) plowDebugEdge(edge, (RuleTableEntry *) NULL, "plowJogPropagateLeft"); edge->e_newx = edge->e_x; if (edge->e_ltype == TT_SPACE && edge->e_rtype != TT_SPACE) (void) plowQueueAdd(edge); return (0); } /* * ---------------------------------------------------------------------------- * * plowProcessJogFunc -- * * Do the real work of eliminating a jog. * This procedure is called via plowSrShadowBack() for each non-space * edge in the shadow of a space edge. Each edge we find will have * e_ltype != TT_SPACE and e_rtype == TT_SPACE. * * We start following the outline of this edge; if it turns out that we * can eliminate a jog, we do so and return 1 to stop the search; otherwise, * we return 0 to force the search to continue. * * Results: * Returns 1 if we eliminated a jog, 0 otherwise. * * Side effects: * May update the geometry of plowYankDef. * * ---------------------------------------------------------------------------- */ int plowProcessJogFunc(edge, area) Edge *edge; /* Edge found by shadow search */ Rect *area; /* Area in which jogs are being eliminated */ { LinkedRect *lr; Rect r, lhs; TileTypeBitMask mask; Point startPoint; int width, ret; Edge newedge; Plane *plane; if (DebugIsSet(plowDebugID, plowDebJogs)) plowDebugEdge(edge, (RuleTableEntry *) NULL, "plowProcessJogFunc"); TTMaskSetOnlyType(&mask, edge->e_ltype); startPoint.p_x = edge->e_x; jogEdge = edge; jogArea = area; /* Walk up the outline of which this edge is a part */ startPoint.p_y = edge->e_ytop; jogTopPoint = startPoint; jogTopDir = J_N; plowSrOutline(edge->e_pNum, &startPoint, mask, GEO_NORTH, GMASK_NORTH|GMASK_WEST|GMASK_EAST, plowJogTopProc, (ClientData) NULL); /* Walk down the outline of which this edge is a part */ TTMaskCom(&mask); startPoint.p_y = edge->e_ybot; jogBotPoint = startPoint; jogBotDir = J_N; plowSrOutline(edge->e_pNum, &startPoint, mask, GEO_SOUTH, GMASK_SOUTH|GMASK_WEST|GMASK_EAST, plowJogBotProc, (ClientData) NULL); /* Try to reject this jog based solely on the geometry */ if (jogTopDir == J_N || jogBotDir == J_N) return (0); if (jogTopDir != J_NEN && jogBotDir != J_NEN) return (0); /* * More geometry-based rejection. * Reject if we found either of the following configurations: * * +-----+ | * | | | * | | * +-------+ +-------+ * | | * | | | * | +-----+ */ if (jogTopDir == J_NES && jogTopPoint.p_x <= jogBotPoint.p_x) return (0); if (jogBotDir == J_NES && jogBotPoint.p_x <= jogTopPoint.p_x) return (0); /* * Extend the edge to the full height of the jog. * The jog will move as far as the leftmost of the two endpoints * (jogTopPoint.p_x, jogBotPoint.p_x) if it is a C-shaped jog, or the * farther of the two if it is a Z-shaped jog. */ newedge = *edge; newedge.e_ybot = jogBotPoint.p_y; newedge.e_ytop = jogTopPoint.p_y; newedge.e_newx = (jogTopDir == J_NW || jogBotDir == J_NW) ? MAX(jogTopPoint.p_x, jogBotPoint.p_x) : MIN(jogTopPoint.p_x, jogBotPoint.p_x); jogEdge = &newedge; if (DebugIsSet(plowDebugID, plowDebJogs)) plowDebugEdge(&newedge, (RuleTableEntry *) NULL, "jog extended edge"); /* Reject if this jog extends outside of the area */ if (!GEO_SURROUND(area, &newedge.e_rect)) return (0); /* * Apply the plowing rules. * Don't do anything if moving the RHS edge will cause * other edges to move. */ plowJogMoved = FALSE; plowJogLHS = (Rect *) NULL; plowApplySearchRules(&newedge); if (plowJogMoved) return (0); /* * Now handle the LHS. * Find the width of this wire (looking leftward) and * search for edges 'width' to the left of the RHS. * Extend the search area by 'width' to the top or bottom * depending on the shape of this jog, to be sure to catch * all of the LHS of the jog. */ TTMaskSetOnlyType(&mask, edge->e_ltype); width = plowFindWidthBack(&newedge, mask, area, (Rect *) NULL); r.r_xtop = newedge.e_x; r.r_xbot = newedge.e_x - width - 1; r.r_ytop = newedge.e_ytop; r.r_ybot = newedge.e_ybot; if (jogTopDir != J_NW) r.r_ytop += width; /* Extend */ if (jogBotDir != J_NW) r.r_ybot -= width; /* Extend */ /* Reject if the LHS extends outside of area */ if (!GEO_SURROUND(area, &r)) return (0); /* Also OK to move parts of the LHS (e.g, sliver elimination) */ lhs = r; lhs.r_xbot++; plowJogLHS = &lhs; ret = 0; plowJogEraseList = (LinkedRect *) NULL; if (plowSrShadowBack(newedge.e_pNum, &r, mask, plowJogDragLHS, (ClientData) newedge.e_newx - width) == 0) { /* Success: first paint to extend the RHS of the jog */ plane = plowYankDef->cd_planes[newedge.e_pNum]; DBPaintPlane(plane, &newedge.e_rect, DBWriteResultTbl[newedge.e_ltype], (PaintUndoInfo *) NULL); (void) GeoInclude(&newedge.e_rect, &plowJogChangedArea); /* Now erase to extend the pieces of the LHS of the jog */ for (lr = plowJogEraseList; lr; lr = lr->r_next) { DBPaintPlane(plane, &lr->r_r, DBWriteResultTbl[TT_SPACE], (PaintUndoInfo *) NULL); (void) GeoInclude(&lr->r_r, &plowJogChangedArea); } ret = 1; } /* Free the erase list we built in plowJogDragLHS */ for (lr = plowJogEraseList; lr; lr = lr->r_next) freeMagic((char *) lr); plowJogEraseList = (LinkedRect *) NULL; return (ret); } /* * ---------------------------------------------------------------------------- * * plowJogTopProc -- * plowJogBotProc -- * * Procedures called by plowSrOutline() to trace the outline of * a potential jog. * * Results: * Both procedures return 1 to stop the search, 0 to continue it. * * Side effects: * plowJogTopProc fills in jogTopDir, jogTopPoint. * plowJogBotProc fills in jogBotDir, jogBotPoint. * * ---------------------------------------------------------------------------- */ int plowJogTopProc(outline) Outline *outline; { /* Stop if we're no longer adjacent to space */ if (TiGetTypeExact(outline->o_outside) != TT_SPACE) return (1); switch (outline->o_currentDir) { case GEO_WEST: jogTopDir = J_NW; return (1); case GEO_NORTH: jogTopPoint = outline->o_rect.r_ur; jogTopDir = J_N; if (outline->o_rect.r_ytop > jogArea->r_ytop) { jogTopPoint.p_y = jogArea->r_ytop; jogTopDir = J_N; return (1); } break; case GEO_EAST: jogTopPoint = outline->o_rect.r_ur; jogTopDir = J_NE; if (outline->o_rect.r_xtop >= jogArea->r_xtop) { jogTopPoint.p_x = jogArea->r_xtop; jogTopDir = J_NE; return (1); } switch (outline->o_nextDir) { case GEO_NORTH: jogTopDir = J_NEN; return (1); case GEO_SOUTH: jogTopDir = J_NES; return (1); } break; } return (0); } int plowJogBotProc(outline) Outline *outline; { /* Stop if we're no longer adjacent to space */ if (TiGetTypeExact(outline->o_inside) != TT_SPACE) return (1); switch (outline->o_currentDir) { case GEO_WEST: jogBotDir = J_NW; return (1); case GEO_SOUTH: jogBotPoint = outline->o_rect.r_ll; jogBotDir = J_N; if (outline->o_rect.r_ybot < jogArea->r_ybot) { jogBotPoint.p_y = jogArea->r_ybot; jogBotDir = J_N; return (1); } break; case GEO_EAST: jogBotPoint = outline->o_rect.r_ur; jogBotDir = J_NE; if (outline->o_rect.r_xtop >= jogArea->r_xtop) { jogBotPoint.p_x = jogArea->r_xtop; jogBotDir = J_NE; return (1); } /* Note that these directions are reversed from plowJogTopProc */ switch (outline->o_nextDir) { case GEO_NORTH: jogBotDir = J_NES; return (1); case GEO_SOUTH: jogBotDir = J_NEN; return (1); } break; } return (0); } /* * ---------------------------------------------------------------------------- * * plowJogDragLHS -- * * Procedure called via plowSrShadowBack() from the RHS of a potential * jog, to see if dragging each of the pieces of the LHS will cause * any other edges to move. We ignore 'edge' if it doesn't have space * to its left. * * Results: * Returns 1 if we detect that something else must move, 0 otherwise. * * Side effects: * Prepends a LinkedRect to plowJogEraseList if we return 0. * This LinkedRect has a rectangle equal to the Edge 'edge' * with e_newx == newx. * * ---------------------------------------------------------------------------- */ int plowJogDragLHS(edge, newx) Edge *edge; /* Edge potentially on the LHS of the jog */ int newx; /* Move the edge to this position */ { LinkedRect *lr; /* Ignore edges that are not to space */ if (edge->e_ltype != TT_SPACE) return (0); /* See what will happen if we move this edge right to newx */ edge->e_newx = newx; plowJogMoved = FALSE; plowApplySearchRules(edge); if (plowJogMoved) return (1); /* * Success: nothing else (except perhaps the original RHS edge) moved. * Append this edge to the list of linked rectangles. */ lr = (LinkedRect *) mallocMagic((unsigned) (sizeof (LinkedRect))); lr->r_r = edge->e_rect; lr->r_next = plowJogEraseList; plowJogEraseList = lr; /* Keep going */ return (0); } /* * ---------------------------------------------------------------------------- * * plowJogMoveFunc -- * * Procedure called via (*plowPropagateProcPtr)() if we find that * eliminating a jog might cause other edges to move. If our argument * edge is not a sub-piece of the RHS of the jog (jogEdge), * then we set plowJogMoved to TRUE. * * Results: * Returns 0 always. * * Side effects: * Sets plowJogMoved as described above. * * ---------------------------------------------------------------------------- */ int plowJogMoveFunc(edge) Edge *edge; { Edge *origEdge = jogEdge; if (DebugIsSet(plowDebugID, plowDebJogs)) plowDebugEdge(edge, (RuleTableEntry *) NULL, "plowJogMoveFunc"); if (origEdge->e_pNum == edge->e_pNum) { /* It's OK to move the original edge */ if (origEdge->e_x == edge->e_x && origEdge->e_ytop >= edge->e_ytop && origEdge->e_ybot <= edge->e_ybot) { return (0); } /* It's OK to move other parts of the LHS, e.g, slivers */ if (plowJogLHS && edge->e_x == plowJogLHS->r_xbot && edge->e_ybot >= plowJogLHS->r_ybot && edge->e_ytop <= plowJogLHS->r_ytop && edge->e_ltype == TT_SPACE && edge->e_rtype == origEdge->e_ltype) { return (0); } } plowJogMoved = TRUE; return (0); } magic-8.0.210/plow/PlowRules1.c0000664000175000001440000007556012032325053014626 0ustar timusers/* * PlowRules1.c -- * * Plowing rules. * These are applied by plowProcessEdge() for each edge that is to be moved. * * ********************************************************************* * * 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/plow/PlowRules1.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/undo.h" #include "plow/plow.h" #include "plow/plowInt.h" #include "drc/drc.h" /* Forward declarations */ int plowPenumbraTopProc(); int plowPenumbraBotProc(); int plowSliverTopExtent(), plowSliverTopMove(); int plowSliverBotExtent(), plowSliverBotMove(); int plowApplyRule(); int plowPenumbraRule(); bool plowSliverApplyRules(); /* * ---------------------------------------------------------------------------- * * prClearUmbra -- * * SEARCH RULE. * Sweep all edges out of the umbra. * This rule preserves horizontal edge orderings within a plane. * Two segments that overlap in Y cannot cross each other in X: * * * 1 2 * 1 ------------> 2 1 will force 2 to move * 1 2 regardless of design rules * * * Below, this rule doesn't apply, so 1 can slide past 2. * * 1 * 1 ------------------> * 1 * 2 * 2 * 2 * * Results: * None. * * Side effects: * May add edges to the queue of edges to be processed. * * ---------------------------------------------------------------------------- */ void prClearUmbra(edge) Edge *edge; /* Edge being moved */ { TileTypeBitMask rhsTypes; struct applyRule ar; TTMaskSetOnlyType(&rhsTypes, edge->e_rtype); ar.ar_moving = edge; ar.ar_rule = (PlowRule *) NULL; (void) plowSrShadow(edge->e_pNum, &edge->e_rect, rhsTypes, plowApplyRule, (ClientData) &ar); } /* * ---------------------------------------------------------------------------- * * prUmbra -- * * SEARCH RULE. * Apply width or spacing rules in the umbra. * The umbra of an edge is the area through which it moves from its * initial position (I) to its final position (F): * * I ======================F-------D * I F D * I umbra F halo D * I F D * I ======================F-------D * * --------------------> + --d--> * * For each rule in the list 'rules', we shadow-search the umbra plus an * additional area of width 'd' to the right (ending at (D) above), where * 'd' is the distance associated with the rule. We queue to be moved the * edges of any material found that is not in the rule's pr_oktypes set. * * Results: * None. * * Side effects: * May add edges to the queue of edges to be processed. * * ---------------------------------------------------------------------------- */ void prUmbra(edge, rules) Edge *edge; /* Edge being moved */ PlowRule *rules; /* List of rules */ { PlowRule *pr; struct applyRule ar; Rect searchArea; ar.ar_moving = edge; searchArea = edge->e_rect; for (pr = rules; pr; pr = pr->pr_next) { ar.ar_rule = pr; searchArea.r_xtop = edge->e_newx + pr->pr_dist; (void) plowSrShadow(pr->pr_pNum, &searchArea, pr->pr_oktypes, plowApplyRule, (ClientData) &ar); } } /* * ---------------------------------------------------------------------------- * * prPenumbraTop -- * prPenumbraBot -- * * Search the penumbra of the supplied edge for each rule in the list * 'list', moving all edges necessary to insure that width or spacing * rules are satisfied. The upper part of the penumbra is searched by * plowPenumbraTop, and the lower part by plowPenumbraBot. * * The penumbra of an edge (E) is that region above and below it, in the * direction the edge is moving. The left-hand border of the penumbra, * and the distance it extends to the right of the final position of * the edge (F), are equal to the distance associated with the design * rule (d). * * ^ T===============| * | T | * d T | * | TTTTTTTTT upper | * v T=======================| * E F * E F * E ------------> F <--d--> * E F * E F * ^ BBBBBBBBB===============| * | B lower | * d BBBBBBBBB | * | B | * v B=======| * * The left-hand border of the penumbra (T, B) for a rule is not a * simple extension of the original edge E, but is instead the result * of following the outline of the material in the pr_ltypes set * associated with that rule. * * If the outline (O) turns left before reaching the top (bottom) of the * clip area, the remainder of the left-hand border (X) of the penumbra * is considered to extend from where the outline turned left, out to * the top (bottom) of the clip area: * * ^ X=======================+ * extension| X * v X * OOOOOOOOO * O * O * OOOOOOOOO======================= * E * E * E * * Results: * None. * * Side effects: * May add edges to the queue of edges to be processed. * * Algorithm notes: * We use plowSrOutline() to trace the penumbra outlines. Since * it moves counterclockwise around the outline of a collection of * types, this is ideal for following the top penumbra's boundary. * Ideally, we wish to follow the bottom penumbra's boundary in a * clockwise direction instead. To achieve this, we follow the * outline of the complementary set of types in a counterclockwise * direction. * * ---------------------------------------------------------------------------- */ void prPenumbraTop(edge, rules) Edge *edge; /* Edge being moved */ PlowRule *rules; /* Rules to apply (must be non-NULL) */ { PlowRule *pr; struct applyRule ar; Point startPoint; ar.ar_moving = edge; startPoint.p_x = edge->e_x; startPoint.p_y = edge->e_ytop; for (pr = rules; pr; pr = pr->pr_next) { ar.ar_rule = pr; ar.ar_clip.p_x = edge->e_newx + pr->pr_dist; ar.ar_clip.p_y = edge->e_ytop + pr->pr_dist; plowSrOutline(edge->e_pNum, &startPoint, pr->pr_ltypes, GEO_NORTH, GMASK_WEST|GMASK_NORTH|GMASK_SOUTH, plowPenumbraTopProc, (ClientData) &ar); } } int prPenumbraBot(edge, rules) Edge *edge; /* Edge being moved */ PlowRule *rules; /* Rules to apply (must be non-NULL) */ { TileTypeBitMask insideTypes; PlowRule *pr; struct applyRule ar; Point startPoint; ar.ar_moving = edge; startPoint.p_x = edge->e_x; startPoint.p_y = edge->e_ybot; for (pr = rules; pr; pr = pr->pr_next) { ar.ar_rule = pr; ar.ar_clip.p_x = edge->e_newx + pr->pr_dist; ar.ar_clip.p_y = edge->e_ybot - pr->pr_dist; TTMaskCom2(&insideTypes, &pr->pr_ltypes); plowSrOutline(edge->e_pNum, &startPoint, insideTypes, GEO_SOUTH, GMASK_WEST|GMASK_NORTH|GMASK_SOUTH, plowPenumbraBotProc, (ClientData) &ar); } return 0; } /* * ---------------------------------------------------------------------------- * * plowPenumbraTopProc -- * plowPenumbraBotProc -- * * Process a vertical (GEO_NORTH or GEO_SOUTH) segment of the left-hand * boundary of the penumbra, for purposes of applying a width or spacing * rule. Width and spacing rules for the upper part of the penumbra are * processed by plowPenumbraTopProc(); rules for the lower part are * processed by plowPenumbraBotProc(). * * We expect the following fields of the applyRule struct 'ar' to be filled in: * * ar_clip -- boundary of the penumbra. If a segment of the * penumbra's outline extends to the right of this * boundary point, we stop. If a segment extends * above this point (if plowPenumbraTopProc), or * below this point (if plowPenumbraBotProc), we stop. * ar_moving -- edge being moved that caused this search. * ar_rule -- design rule (width or spacing) being applied. * * When processing the upper penumbra, the "inside" material is to the left, * and the "outside" to the right. When processing the lower penumbra, the * situation is reversed because we are following the complementary material: * "inside" is to the right and "outside" to the left. See the algorithm * notes for prPenumbraTop() and prPenumbraBot() above. * * Results: * 0 if plowSrOutline should keep going, 1 if not. * * Side effects: * May add edges to the queue of edges to be processed. * * ---------------------------------------------------------------------------- */ int plowPenumbraTopProc(outline, ar) Outline *outline; /* Segment along penumbra border */ struct applyRule *ar; /* Info needed for shadow search */ { Edge *movingEdge = ar->ar_moving; PlowRule *pr = ar->ar_rule; Rect searchArea; int ret = 0; /* * Test for immediate termination conditions: * - a southward-bound edge * - a northward-bound edge to the right of the clip point */ if (outline->o_currentDir == GEO_SOUTH || outline->o_rect.r_xbot >= ar->ar_clip.p_x) return (1); /* * Test for termination after processing this edge: * - a northward-bound edge touching or crossing the top * of the clip area. * If this is true, clip the search area to the top of the clip area. */ searchArea = outline->o_rect; if (searchArea.r_ytop >= ar->ar_clip.p_y) ret = 1, searchArea.r_ytop = ar->ar_clip.p_y; searchArea.r_xtop = movingEdge->e_newx + pr->pr_dist; /* * If we just turned left and haven't reached the outside of * the clip area, extend for one last shadow search. */ if (outline->o_currentDir == GEO_WEST) { if (outline->o_rect.r_ytop < ar->ar_clip.p_y) { searchArea.r_xbot = outline->o_rect.r_xtop - 1; searchArea.r_ybot = outline->o_rect.r_ytop; searchArea.r_ytop = ar->ar_clip.p_y; (void) plowSrShadow(pr->pr_pNum, &searchArea, pr->pr_oktypes, plowPenumbraRule, (ClientData) ar); } return (1); } /* Shadow search to right of this segment of the penumbra boundary */ (void) plowSrShadow(pr->pr_pNum, &searchArea, pr->pr_oktypes, plowApplyRule, (ClientData) ar); return (ret); } int plowPenumbraBotProc(outline, ar) Outline *outline; /* Segment along penumbra border */ struct applyRule *ar; /* Info needed for shadow search */ { Edge *movingEdge = ar->ar_moving; PlowRule *pr = ar->ar_rule; Rect searchArea; int ret = 0; /* * Test for immediate termination conditions: * - a northward-bound edge * - a southward-bound edge to the right of the clip point */ if (outline->o_currentDir == GEO_NORTH || outline->o_rect.r_xbot >= ar->ar_clip.p_x) return (1); /* * Test for termination after processing this edge: * - a southward-bound edge touching or crossing the bottom * of the clip area. * If this is true, clip the search area to the bottom of the clip area. */ searchArea = outline->o_rect; if (searchArea.r_ybot <= ar->ar_clip.p_y) ret = 1, searchArea.r_ybot = ar->ar_clip.p_y; searchArea.r_xtop = movingEdge->e_newx + pr->pr_dist; /* * If we just turned left and haven't reached the outside of * the clip area, extend for one last shadow search. */ if (outline->o_currentDir == GEO_WEST) { if (outline->o_rect.r_ybot > ar->ar_clip.p_y) { searchArea.r_xbot = outline->o_rect.r_xtop - 1; searchArea.r_ybot = ar->ar_clip.p_y; searchArea.r_ytop = outline->o_rect.r_ybot; (void) plowSrShadow(pr->pr_pNum, &searchArea, pr->pr_oktypes, plowPenumbraRule, (ClientData) ar); } return (1); } /* Shadow search to right of this segment of the penumbra boundary */ (void) plowSrShadow(pr->pr_pNum, &searchArea, pr->pr_oktypes, plowApplyRule, (ClientData) ar); return (ret); } /* * plowPenumbraRule -- * * Like plowApplyRule, except we don't queue an edge whose LHS * is not in ar->ar_rule->pr_oktypes. This should prevent the * penumbra extension search from finding bad edges. * * Results: * Returns 0 always. * * Side effects: * May queue the edge. */ int plowPenumbraRule(impactedEdge, ar) Edge *impactedEdge; /* Edge found by shadow search */ struct applyRule *ar; /* Edge causing the shadow search, and * the design rule to apply. */ { PlowRule *pr; Edge *movingEdge = ar->ar_moving; int newsep, oldsep, newx; oldsep = impactedEdge->e_x - movingEdge->e_x; if (pr = ar->ar_rule) { if (!TTMaskHasType(&pr->pr_oktypes, impactedEdge->e_ltype)) return (0); newsep = pr->pr_dist; } else newsep = 0; if (oldsep < newsep) newsep = oldsep; /* Queue the edge if it hasn't already moved far enough */ newx = movingEdge->e_newx + newsep; if (newx > impactedEdge->e_newx) { impactedEdge->e_newx = newx; (void) (*plowPropagateProcPtr)(impactedEdge); } return (0); } /* * ---------------------------------------------------------------------------- * * prSliverTop -- * prSliverBot -- * * Avoid introducing slivers due to width or spacing rule violations. * For each design rule in 'rules', we perform two passes. The first * pass determines which slivers must move, and how far they must move. * The second pass actually queues the edges to be moved. * * Results: * Return 0 always * * Side effects: * May add an edge to the queue of edges to be processed. * * ---------------------------------------------------------------------------- */ int prSliverTop(edge, rules) Edge *edge; PlowRule *rules; { PlowRule *pr; struct applyRule ar; Point startPoint; /* * The rules in the list 'rules' only determine the outline that will be * traced, not the rules that will be applied to detect slivers. Hence * the halo will depend on edge->e_ltype and the "sliver type" that will * be stored in ar.ar_type. Since we don't know ar.ar_type at the start, * we play conservative and just use the maximum halo size. */ if (plowMaxDist[edge->e_ltype] == 0) return 0; ar.ar_clip.p_x = edge->e_newx; ar.ar_clip.p_y = edge->e_ytop + plowMaxDist[edge->e_ltype]; startPoint.p_x = edge->e_x; startPoint.p_y = edge->e_ytop; ar.ar_moving = edge; /* We don't use ar.ar_rule */ for (pr = rules; pr; pr = pr->pr_next) { /* * Pass 1. * Find out how far slivers will have to move to the right. * After the call to plowSrOutline, ar.ar_mustmove is set to * the distance rightward we will have to move each sliver. */ ar.ar_slivtype = (TileType) -1; ar.ar_lastx = ar.ar_mustmove = edge->e_x; plowSrOutline(edge->e_pNum, &startPoint, pr->pr_ltypes, GEO_NORTH, GMASK_NORTH|GMASK_EAST|GMASK_SOUTH, plowSliverTopExtent, (ClientData) &ar); /* * Pass 2. * No work is required if there aren't any potential slivers. * If we must do any work, move each sliver as far rightward * as ar.ar_mustmove. This second pass doesn't use ar_slivtype, * ar_lastx, or ar_clip. */ if (ar.ar_mustmove > edge->e_x) plowSrOutline(edge->e_pNum, &startPoint, pr->pr_ltypes, GEO_NORTH, GMASK_SOUTH|GMASK_NORTH, plowSliverTopMove, (ClientData) &ar); } return 0; } int prSliverBot(edge, rules) Edge *edge; PlowRule *rules; { TileTypeBitMask insideTypes; PlowRule *pr; struct applyRule ar; Point startPoint; /* * The rules in the list 'rules' only determine the outline that will be * traced, not the rules that will be applied to detect slivers. Hence * the halo will depend on edge->e_ltype and the "sliver type" that will * be stored in ar.ar_type. Since we don't know ar.ar_type at the start, * we play conservative and just use the maximum halo size. */ if (plowMaxDist[edge->e_ltype] == 0) return 0; ar.ar_clip.p_x = edge->e_newx; ar.ar_clip.p_y = edge->e_ybot - plowMaxDist[edge->e_ltype]; startPoint.p_x = edge->e_x; startPoint.p_y = edge->e_ybot; ar.ar_moving = edge; /* We don't use ar.ar_rule */ for (pr = rules; pr; pr = pr->pr_next) { /* * Pass 1. * Find out how far slivers will have to move to the right. * After the call to plowSrOutline, ar.ar_mustmove is set to * the distance rightward we will have to move each sliver. */ ar.ar_slivtype = (TileType) -1; ar.ar_lastx = ar.ar_mustmove = edge->e_x; TTMaskCom2(&insideTypes, &pr->pr_ltypes); plowSrOutline(edge->e_pNum, &startPoint, insideTypes, GEO_SOUTH, GMASK_NORTH|GMASK_EAST|GMASK_SOUTH, plowSliverBotExtent, (ClientData) &ar); /* * Pass 2. * No work is required if there aren't any potential slivers. * If we must do any work, move each sliver as far rightward * as ar.ar_mustmove. This second pass doesn't use ar_slivtype, * ar_lastx, or ar_clip. */ if (ar.ar_mustmove > edge->e_x) plowSrOutline(edge->e_pNum, &startPoint, insideTypes, GEO_SOUTH, GMASK_SOUTH|GMASK_NORTH, plowSliverBotMove, (ClientData) &ar); } return 0; } /* * ---------------------------------------------------------------------------- * * plowSliverTopMove -- * plowSliverBotMove -- * * After a first pass through plowSrOutline using plowSliverTopExtent() * or plowSliverBotExtent() has filled in ar->ar_mustmove, we get called * by a second pass of plowSrOutline to eliminate slivers by moving * vertical edges in the outline. * * All slivers must be moved as far as ar->ar_mustmove. If we see a vertical * edge as far as or farther right than ar->ar_mustmove, we are done. * (We know from plowSliverTopExtent() or plowSliverBotExtent() that the final * X coordinates of all vertical edges passed to this procedure are * monotonically nondecreasing up to ar->ar_mustmove). * * If the vertical edge is going GEO_SOUTH instead of GEO_NORTH (in the * case of plowSliverTopMove), or going GEO_NORTH instead of GEO_SOUTH * (in the case of plowSliverBotMove), this is also a stopping condition. * * Results: * Returns 1 to stop plowSrOutline from following the outline * any more, or 0 to continue. * * Side effects: * May add an edge to the queue of edges to be processed. * * ---------------------------------------------------------------------------- */ int plowSliverTopMove(outline, ar) Outline *outline; /* Segment of outline being followed */ struct applyRule *ar; { int howfar = ar->ar_moving->e_newx - ar->ar_moving->e_x; Edge edge; /* Done if we turned south or if this edge is far enough to the right */ if (outline->o_currentDir == GEO_SOUTH || TRAILING(outline->o_outside) >= ar->ar_mustmove) return (1); /* Queue the edge to be moved */ edge.e_rect = outline->o_rect; edge.e_newx = ar->ar_mustmove; edge.e_ltype = TiGetTypeExact(outline->o_inside); edge.e_rtype = TiGetTypeExact(outline->o_outside); if (TTMaskHasType(&PlowFixedTypes, edge.e_rtype) && edge.e_newx > edge.e_x + howfar) edge.e_newx = edge.e_x + howfar; edge.e_pNum = outline->o_pNum; edge.e_use = (CellUse *) NULL; edge.e_flags = 0; (void) (*plowPropagateProcPtr)(&edge); /* Keep going */ return (0); } int plowSliverBotMove(outline, ar) Outline *outline; /* Segment of outline being followed. * The sense of "inside" and "outside" * is reversed from that when handling * the top half of the penumbra. */ struct applyRule *ar; { int howfar = ar->ar_moving->e_newx - ar->ar_moving->e_x; Edge edge; /* Done if we turned north or if this edge is far enough to the right */ if (outline->o_currentDir == GEO_NORTH || TRAILING(outline->o_inside) >= ar->ar_mustmove) return (1); /* Queue the edge to be moved */ edge.e_rect = outline->o_rect; edge.e_newx = ar->ar_mustmove; edge.e_ltype = TiGetTypeExact(outline->o_outside); edge.e_rtype = TiGetTypeExact(outline->o_inside); if (TTMaskHasType(&PlowFixedTypes, edge.e_rtype) && edge.e_newx > edge.e_x + howfar) edge.e_newx = edge.e_x + howfar; edge.e_pNum = outline->o_pNum; edge.e_use = (CellUse *) NULL; edge.e_flags = 0; (void) (*plowPropagateProcPtr)(&edge); /* Keep going */ return (0); } /* * ---------------------------------------------------------------------------- * * plowSliverTopExtent -- * plowSliverBotExtent -- * * Called by plowSrOutline() to follow the upper/lower penumbra's * outline(s), and see how much of that outline must be moved to * avoid introducing slivers. * * Results: * Returns 1 to stop plowSrOutline from following the outline * any more, or 0 to continue. * * Side effects: * Modifies the following fields of the applyRule struct pointed * to by 'ar': * * ar_lastx -- continuously updated to the rightmost * final X coordinate of any vertical * edge. When a vertical edge is seen * with a final X coordinate less than * ar_lastx, we know we're done. * ar_mustmove -- new X to which each sliver must be moved. * ar_slivtype -- material forming the sliver itself. * * ---------------------------------------------------------------------------- */ int plowSliverTopExtent(outline, ar) Outline *outline; /* Segment of outline being followed */ struct applyRule *ar; { Edge *movingEdge = ar->ar_moving; int newx, xmove, ret = 0; /* * The direction in which we are following an outline * segment generally determines how it is processed. * * If heading south, we are definitely done. * If heading north, we check (by comparing with ar->ar_lastx) * to make sure the outline's X coordinate is monotonically * nondecreating. * If heading east, we check to see if this segment of the outline * causes a design-rule violation (i.e, if there is a sliver * between movingEdge->e_ltype and outline->o_inside). * * A few exceptions arise because we are considering final instead * of initial coordinates. These are both when heading north. See * the code for details. */ switch (outline->o_currentDir) { case GEO_SOUTH: /* Done if we turn back down */ return (1); case GEO_NORTH: /* Done if we turned left in final coordinates */ if (TRAILING(outline->o_outside) < ar->ar_lastx) return (1); /* Almost done if we exit the right or top of the clip area */ newx = TRAILING(outline->o_outside); if (newx >= ar->ar_clip.p_x || outline->o_rect.r_ytop >= ar->ar_clip.p_y) ret = 1; /* Set the type to be used in applying the design rules */ if (outline->o_rect.r_ybot == movingEdge->e_ytop) ar->ar_slivtype = TiGetTypeExact(outline->o_outside); /* * If this is not a special case where we have to check for * a sliver, we're done. * * Normally, slivers are only checked for when going east. * There are two exceptions, both because we are looking at * final coordinates. * * 1. If we were going west and then turned north, check * for a sliver with the bottom of the inside material. * * initial | ------------> | final * +-------+ * | * * 2. If we were going north and kept going, and this segment * is further right than the last one (in final coordinates), * check for a sliver with the bottom of the inside material. * * initial | ------------> | final * | */ if (outline->o_prevDir == GEO_WEST || (outline->o_prevDir == GEO_NORTH && newx > ar->ar_lastx)) { ar->ar_lastx = newx; xmove = MIN(newx, ar->ar_clip.p_x); break; } /* We know newx >= ar->ar_lastx, so update the latter */ ar->ar_lastx = newx; return (ret); case GEO_EAST: /* Almost done if we leave the clipping area */ if (outline->o_rect.r_xtop >= ar->ar_clip.p_x) ret = 1; /* * Return if we haven't yet processed a vertical segment of * the outline (i.e, no potential slivers have been seen yet). */ if (ar->ar_slivtype == (TileType) -1) return (ret); /* How far the penumbra LHS will have to move to avoid a sliver */ xmove = ar->ar_clip.p_x; if (outline->o_nextDir == GEO_NORTH && TRAILING(outline->o_nextOut) < xmove) xmove = TRAILING(outline->o_nextOut); break; } /* Apply the plowing rules to see if this is a sliver */ if (plowSliverApplyRules(ar, TiGetTypeExact(outline->o_inside), outline->o_rect.r_ybot - movingEdge->e_ytop)) ar->ar_mustmove = xmove; return (ret); } int plowSliverBotExtent(outline, ar) Outline *outline; /* Segment of outline being followed */ struct applyRule *ar; { Edge *movingEdge = ar->ar_moving; int newx, xmove, ret = 0; /* * The direction in which we are following an outline * segment generally determines how it is processed. * * If heading north, we are definitely done. * If heading south, we check (by comparing with ar->ar_lastx) * to make sure the outline's X coordinate is monotonically * nondecreating. * If heading east, we check to see if this segment of the outline * causes a design-rule violation (i.e, if there is a sliver * between movingEdge->e_ltype and outline->o_outside). * * A few exceptions arise because we are considering final instead * of initial coordinates. These are both when heading south. See * the code for details. */ switch (outline->o_currentDir) { case GEO_NORTH: /* Done if we turn back up */ return (1); case GEO_SOUTH: /* Done if we turned left in final coordinates */ if (TRAILING(outline->o_inside) < ar->ar_lastx) return (1); /* Almost done if we exit the right or bottom of the clip area */ newx = TRAILING(outline->o_inside); if (newx >= ar->ar_clip.p_x || outline->o_rect.r_ybot <= ar->ar_clip.p_y) ret = 1; /* Set the type to be used in applying the design rules */ if (outline->o_rect.r_ytop == movingEdge->e_ybot) ar->ar_slivtype = TiGetTypeExact(outline->o_inside); /* * If this is not a special case where we have to check for * a sliver, we're done. * * Normally, slivers are only checked for when going east. * There are two exceptions, both because we are looking at * final coordinates. * * 1. If we were going west and then turned south, check * for a sliver with the top of the outside material. * * | * +-------+ * initial | ------------> | final * * 2. If we were going south and kept going, and this segment * is further right than the last one (in final coordinates), * check for a sliver with the top of the outside material. * * | * initial | ------------> | final */ if (outline->o_prevDir == GEO_WEST || (outline->o_prevDir == GEO_SOUTH && newx > ar->ar_lastx)) { ar->ar_lastx = newx; xmove = MIN(newx, ar->ar_clip.p_x); break; } /* We know newx >= ar->ar_lastx, so update the latter */ ar->ar_lastx = newx; return (ret); case GEO_EAST: /* Almost done if we leave the clipping area */ if (outline->o_rect.r_xtop >= ar->ar_clip.p_x) ret = 1; /* * Return if we haven't yet processed a vertical segment of * the outline (i.e, no potential slivers have been seen yet). */ if (ar->ar_slivtype == (TileType) -1) return (ret); /* How far the penumbra LHS will have to move to avoid a sliver */ xmove = ar->ar_clip.p_x; if (outline->o_nextDir == GEO_SOUTH && TRAILING(outline->o_nextIn) < xmove) xmove = TRAILING(outline->o_nextIn); break; } /* Apply the plowing rules to see if this is a sliver */ if (plowSliverApplyRules(ar, TiGetTypeExact(outline->o_outside), movingEdge->e_ybot - outline->o_rect.r_ytop)) ar->ar_mustmove = xmove; return (ret); } /* * ---------------------------------------------------------------------------- * * plowSliverApplyRules -- * * Determine whether a sliver exists that must be moved. The configuration * we are evaluating is: * * * far * -------- * ^ * | * | farDist * | * s v * -------- * near * * where s = ar->ar_slivtype and near = ar->ar_moving->e_ltype. * We apply all the plowing rules triggered by the near|s edge * (both width and spacing rules). * * Results: * TRUE if the sliver must move, FALSE if not. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool plowSliverApplyRules(ar, far, farDist) struct applyRule *ar; TileType far; int farDist; { TileType near = ar->ar_moving->e_ltype; PlowRule *pr; for (pr = plowWidthRulesTbl[near][ar->ar_slivtype]; pr; pr = pr->pr_next) if (pr->pr_dist > farDist && !TTMaskHasType(&pr->pr_oktypes, far)) return (TRUE); for (pr = plowSpacingRulesTbl[near][ar->ar_slivtype]; pr; pr = pr->pr_next) if (pr->pr_dist > farDist && !TTMaskHasType(&pr->pr_oktypes, far)) return (TRUE); return (FALSE); } /* * ---------------------------------------------------------------------------- * * plowApplyRule -- * * Add an edge ('impactedEdge') found by shadow search to the edge queue. * Normally, this edge will be added at a new position equal to the new * position of the original moving edge (ar->ar_moving), plus the distance * associated with the design rule (ar->ar_rule->pr_dist). However, if * the impacted edge were already closer than ar->ar_rule->pr_dist to the * moving edge (i.e, there was a design-rule violation in the original * layout), we use the original separation instead of the minimum separation. * * If the impacted edge has already moved far enough (impactedEdge->e_newx * is far enough to the right), we don't add it. * * If ar->ar_rule is NULL, we assume a distance of zero. * * Results: * Always returns 0. * * Side effects: * May add an edge to the queue of edges to be processed. * * ---------------------------------------------------------------------------- */ int plowApplyRule(impactedEdge, ar) Edge *impactedEdge; /* Edge found by shadow search */ struct applyRule *ar; /* Edge causing the shadow search, and * the design rule to apply. */ { Edge *movingEdge = ar->ar_moving; int newsep, oldsep, newx; oldsep = impactedEdge->e_x - movingEdge->e_x; newsep = ar->ar_rule ? ar->ar_rule->pr_dist : 0; if (oldsep < newsep) newsep = oldsep; /* Queue the edge if it hasn't already moved far enough */ newx = movingEdge->e_newx + newsep; if (newx > impactedEdge->e_newx) { impactedEdge->e_newx = newx; (void) (*plowPropagateProcPtr)(impactedEdge); } return (0); } magic-8.0.210/plow/TODO0000644000175000001440000000042410751423606013127 0ustar timusersAvoid introducing slivers with subcell flypaper Better width computation (if upper bound is too big, use different algorithm). Move labels with straighten. Straighten should pull trailing tabs. Fix nonlinear boundary effects (runtime) Rule to pull trailing tabs when plowing. magic-8.0.210/plow/PlowRules3.c0000664000175000001440000002710612032325053014621 0ustar timusers/* * PlowRules3.c -- * * Plowing rules: new sliver-avoidance rules. * These are applied by plowProcessEdge() for each edge that is to be moved. * * ********************************************************************* * * 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/plow/PlowRules3.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/undo.h" #include "plow/plow.h" #include "plow/plowInt.h" #include "drc/drc.h" /* Imports from other rules files */ extern int plowApplyRule(); /* Forward declarations */ int plowInSliverProc(); int scanDown(), scanUp(); int scanDownError(), scanUpError(); /* Argument passed to above filter functions */ struct inarg { Rect ina_area; /* Area to search for violations */ Edge *ina_moving; /* Edge causing this search */ TileType ina_t0; /* See comments in the procedures */ int (*ina_proc)(); /* Apply to look for rule violations */ /* Used while appling design rules */ PlowRule *ina_rule; /* Plowing design rule being applied */ int ina_incursion; /* Height of biggest DRC error */ bool ina_cantMove; /* TRUE if couldn't fix some error */ }; /* * ---------------------------------------------------------------------------- * * prInSliver -- * * Avoid introducing slivers because the plow is too small. * This rule only applies if the plow height is less than the * maximum design-rule distance DRCTechHalo. * * Results: * None. * * Side effects: * May add edges to the queue of edges to be processed. * * ---------------------------------------------------------------------------- */ void prInSliver(edge) Edge *edge; /* Edge being moved */ { struct inarg inarg; Rect edgeBorder; Plane *plane; if ((edge->e_flags & E_ISINITIAL) == 0 || edge->e_ytop - edge->e_ybot >= DRCTechHalo) return; /* Look down from the top of the edge */ edgeBorder.r_xbot = edge->e_x - 1; edgeBorder.r_xtop = edge->e_newx; edgeBorder.r_ybot = edge->e_ytop; edgeBorder.r_ytop = edge->e_ytop + 1; plane = plowYankDef->cd_planes[edge->e_pNum]; inarg.ina_moving = edge; inarg.ina_t0 = (TileType) -1; inarg.ina_area.r_ytop = edge->e_ybot; inarg.ina_proc = scanDown; plowSrFinalArea(plane, &edgeBorder, &DBAllTypeBits, plowInSliverProc, (ClientData) &inarg); /* Look up from the bottom of the edge */ edgeBorder.r_ybot = edge->e_ybot - 1; edgeBorder.r_ytop = edge->e_ybot; inarg.ina_t0 = (TileType) -1; inarg.ina_area.r_ybot = edge->e_ytop; inarg.ina_proc = scanUp; plowSrFinalArea(plane, &edgeBorder, &DBAllTypeBits, plowInSliverProc, (ClientData) &inarg); } int plowInSliverProc(tile, inarg) Tile *tile; struct inarg *inarg; { Edge *movingEdge = inarg->ina_moving; #ifdef notdef Edge newEdge; #endif /* notdef */ TileType t1; int xtop; /* Is this the first tile we've seen? */ if (inarg->ina_t0 == (TileType) -1) { inarg->ina_t0 = TiGetType(tile); inarg->ina_area.r_xbot = movingEdge->e_x; inarg->ina_area.r_xtop = MIN(movingEdge->e_newx, LEADING(tile)); if (LEADING(tile) >= movingEdge->e_newx) { (*inarg->ina_proc)(inarg, inarg->ina_t0, FALSE); return (1); } return (0); } /* Is this still the same material? */ if (TiGetType(tile) == inarg->ina_t0) { /* Extend the edge to the right */ xtop = MIN(movingEdge->e_newx, LEADING(tile)); if (xtop > inarg->ina_area.r_xtop) inarg->ina_area.r_xtop = xtop; /* Is this the last tile? */ if (LEADING(tile) >= movingEdge->e_newx) { (*inarg->ina_proc)(inarg, inarg->ina_t0, FALSE); return (1); } /* Keep looking */ return (0); } /* New type of material */ t1 = TiGetType(tile); /* Can we not slide past the t0 | t1 edge? */ if ((movingEdge->e_ltype != TT_SPACE && movingEdge->e_rtype != TT_SPACE) || TTMaskHasType(&PlowCoveredTypes, inarg->ina_t0) || TTMaskHasType(&PlowCoveredTypes, t1) || inarg->ina_t0 != movingEdge->e_ltype || t1 != movingEdge->e_rtype) { #ifdef notdef /* Move a 1-lambda high strip of the t0 | t1 edge */ newEdge.e_x = LEFT(tile); newEdge.e_newx = movingEdge->e_newx; newEdge.e_ybot = movingEdge->e_ytop; newEdge.e_ytop = movingEdge->e_ytop + 1; newEdge.e_pNum = movingEdge->e_pNum; newEdge.e_ltype = inarg->ina_t0; newEdge.e_rtype = t1; newEdge.e_use = (CellUse *) NULL; (*plowPropagateProcPtr)(&newEdge); #endif /* notdef */ (*inarg->ina_proc)(inarg, inarg->ina_t0, FALSE); return (1); } /* * Search the t0 edge up to the LHS of t1. * We can only move violation edges to eliminate the errors we find. */ (*inarg->ina_proc)(inarg, inarg->ina_t0, FALSE); /* * Search the t1 edge as well. * Move violation edges if possible, but we can move the * t0 | t1 edge if we can't fix the violations. */ inarg->ina_area.r_xbot = inarg->ina_area.r_xtop; inarg->ina_area.r_xtop = movingEdge->e_newx; (*inarg->ina_proc)(inarg, t1, TRUE); return (1); } int scanDown(inarg, type, canMoveInargEdge) struct inarg *inarg; TileType type; bool canMoveInargEdge; { TileType ltype = inarg->ina_moving->e_ltype; Edge *movingEdge = inarg->ina_moving; TileTypeBitMask badTypes; PlowRule *pr; int height; inarg->ina_incursion = 0; inarg->ina_cantMove = FALSE; height = movingEdge->e_ytop - movingEdge->e_ybot; for (pr = plowSpacingRulesTbl[type][ltype]; pr; pr = pr->pr_next) { if ((pr->pr_flags & PR_PENUMBRAONLY) || pr->pr_dist <= height) continue; inarg->ina_area.r_ybot = movingEdge->e_ytop - pr->pr_dist; inarg->ina_rule = pr; TTMaskCom2(&badTypes, &pr->pr_oktypes); plowSrFinalArea(plowYankDef->cd_planes[pr->pr_pNum], &inarg->ina_area, &badTypes, scanDownError, (ClientData) inarg); } for (pr = plowWidthRulesTbl[type][ltype]; pr; pr = pr->pr_next) { if ((pr->pr_flags & PR_PENUMBRAONLY) || pr->pr_dist <= height) continue; inarg->ina_area.r_ybot = movingEdge->e_ytop - pr->pr_dist; inarg->ina_rule = pr; TTMaskCom2(&badTypes, &pr->pr_oktypes); plowSrFinalArea(plowYankDef->cd_planes[pr->pr_pNum], &inarg->ina_area, &badTypes, scanDownError, (ClientData) inarg); } #ifdef notdef /* Move the top edge if necessary */ if (canMoveInargEdge && inarg->ina_cantMove) { struct applyRule ar; Rect shadowRect; shadowRect.r_xbot = inarg->ina_area.r_xbot - 1; shadowRect.r_ybot = movingEdge->e_ytop; shadowRect.r_xtop = movingEdge->e_newx; shadowRect.r_ytop = movingEdge->e_ytop + inarg->ina_incursion; ar.ar_moving = movingEdge; ar.ar_rule = (PlowRule *) NULL; plowSrShadow(movingEdge->e_pNum, &shadowRect, DBZeroTypeBits, plowApplyRule, (ClientData) &ar); } #endif /* notdef */ return 0; } int scanDownError(tile, inarg) Tile *tile; struct inarg *inarg; { Rect atomRect; int incursion; incursion = MIN(TOP(tile), inarg->ina_area.r_ytop) - inarg->ina_area.r_ybot; if (incursion > inarg->ina_incursion) inarg->ina_incursion = incursion; /* * The following relies on maximal horizontal strips. * If the violating tile extends to the left of the area * we're checking, we can't eliminate the violation by * moving its LHS. */ if (LEFT(tile) < inarg->ina_area.r_xbot) { inarg->ina_cantMove = TRUE; return (0); } /* * Eliminate the violation by moving the LHS of * the violating tile. */ atomRect.r_xbot = LEFT(tile); atomRect.r_xtop = inarg->ina_moving->e_newx; atomRect.r_ybot = MAX(BOTTOM(tile), inarg->ina_area.r_ybot); atomRect.r_ytop = MIN(TOP(tile), inarg->ina_area.r_ytop); (void) plowAtomize(inarg->ina_rule->pr_pNum, &atomRect, plowPropagateProcPtr, (ClientData) NULL); return (0); } int scanUp(inarg, type, canMoveInargEdge) struct inarg *inarg; TileType type; bool canMoveInargEdge; { TileType ltype = inarg->ina_moving->e_ltype; Edge *movingEdge = inarg->ina_moving; TileTypeBitMask badTypes; PlowRule *pr; int height; inarg->ina_incursion = 0; inarg->ina_cantMove = FALSE; height = movingEdge->e_ytop - movingEdge->e_ybot; for (pr = plowSpacingRulesTbl[type][ltype]; pr; pr = pr->pr_next) { if ((pr->pr_flags & PR_PENUMBRAONLY) || pr->pr_dist <= height) continue; inarg->ina_area.r_ytop = movingEdge->e_ybot + pr->pr_dist; inarg->ina_rule = pr; TTMaskCom2(&badTypes, &pr->pr_oktypes); plowSrFinalArea(plowYankDef->cd_planes[pr->pr_pNum], &inarg->ina_area, &badTypes, scanUpError, (ClientData) inarg); } for (pr = plowWidthRulesTbl[type][ltype]; pr; pr = pr->pr_next) { if ((pr->pr_flags & PR_PENUMBRAONLY) || pr->pr_dist <= height) continue; inarg->ina_area.r_ytop = movingEdge->e_ybot + pr->pr_dist; inarg->ina_rule = pr; TTMaskCom2(&badTypes, &pr->pr_oktypes); plowSrFinalArea(plowYankDef->cd_planes[pr->pr_pNum], &inarg->ina_area, &badTypes, scanUpError, (ClientData) inarg); } #ifdef notdef /* Move the bottom edge if necessary */ if (canMoveInargEdge && inarg->ina_cantMove) { struct applyRule ar; Rect shadowRect; shadowRect.r_xbot = inarg->ina_area.r_xbot - 1; shadowRect.r_ybot = movingEdge->e_ybot - inarg->ina_incursion; shadowRect.r_xtop = movingEdge->e_newx; shadowRect.r_ytop = movingEdge->e_ybot; ar.ar_moving = movingEdge; ar.ar_rule = (PlowRule *) NULL; plowSrShadow(movingEdge->e_pNum, &shadowRect, DBZeroTypeBits, plowApplyRule, (ClientData) &ar); } #endif /* notdef */ return 0; } int scanUpError(tile, inarg) Tile *tile; struct inarg *inarg; { Rect atomRect; int incursion; incursion = inarg->ina_area.r_ytop; incursion -= MAX(BOTTOM(tile), inarg->ina_area.r_ybot); if (incursion > inarg->ina_incursion) inarg->ina_incursion = incursion; /* * The following relies on maximal horizontal strips. * If the violating tile extends to the left of the area * we're checking, we can't eliminate the violation by * moving its LHS. */ if (LEFT(tile) < inarg->ina_area.r_xbot) { inarg->ina_cantMove = TRUE; return (0); } /* * Eliminate the violation by moving the LHS of * the violating tile. */ atomRect.r_xbot = LEFT(tile); atomRect.r_xtop = inarg->ina_moving->e_newx; atomRect.r_ybot = MAX(BOTTOM(tile), inarg->ina_area.r_ybot); atomRect.r_ytop = MIN(TOP(tile), inarg->ina_area.r_ytop); (void) plowAtomize(inarg->ina_rule->pr_pNum, &atomRect, plowPropagateProcPtr, (ClientData) NULL); return (0); } int plowSrFinalArea(plane, area, okTypes, proc, cdata) Plane *plane; Rect *area; TileTypeBitMask *okTypes; int (*proc)(); ClientData cdata; { return (DBSrPaintArea((Tile *) NULL, plane, area, okTypes, proc, cdata)); } magic-8.0.210/plow/Makefile0000644000175000001440000000060210751423606014075 0ustar timusers# # rcsid $Header: /usr/cvsroot/magic-8.0/plow/Makefile,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ # MODULE = plow MAGICDIR = .. SRCS = PlowCmd.c PlowJogs.c PlowMain.c PlowQueue.c PlowRandom.c \ PlowRules1.c PlowRules2.c PlowRules3.c PlowSearch.c PlowTech.c \ PlowTest.c PlowWidth.c PlowYank.c include ${MAGICDIR}/defs.mak include ${MAGICDIR}/rules.mak magic-8.0.210/plow/PlowMain.c0000664000175000001440000017770412032325053014342 0ustar timusers/* * PlowMain.c -- * * Plowing. * Main loop: set everything up, and then repeatedly remove an * edge from the queue of pending edges and process it. * * ********************************************************************* * * 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/plow/PlowMain.c,v 1.2 2008/12/11 04:20:12 tim Exp $"; #endif /* not lint */ #include #include #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/undo.h" #include "debug/debug.h" #include "plow/plow.h" #include "plow/plowInt.h" #include "textio/textio.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "drc/drc.h" #include "utils/styles.h" #include "utils/malloc.h" #include "utils/signals.h" #include "utils/main.h" #include "select/select.h" #include "graphics/graphics.h" #if defined(SYSV) || defined(__APPLE__) # define NO_RUSAGE #endif /* Plowing jog horizon: see PlowExtendJogHorizon() for an explanation */ global int PlowJogHorizon = 0; /* TRUE if we should straighten jogs automatically after each plow */ global bool PlowDoStraighten = FALSE; /* * Search rule table. These rules are used to search from a moving * edge to find the other edges it causes to move. The procedure * implementing each rule should be of the form: * * (*proc)(edge, rules) * Edge *edge; * PlowRule *rules; * { * } * * It may not modify the Edge pointed to by 'edge'. * The edge is in the cell plowYankDef. */ RuleTableEntry plowSearchRulesTbl[MAXRULES]; RuleTableEntry *plowSearchRulesPtr = plowSearchRulesTbl; /* * Cell rules. * Same as above. */ RuleTableEntry plowCellRulesTbl[MAXRULES]; RuleTableEntry *plowCellRulesPtr = plowCellRulesTbl; /* Imported rules */ extern int prClearUmbra(); extern int prUmbra(); extern int prPenumbraTop(), prPenumbraBot(); extern int prFixedPenumbraTop(), prFixedPenumbraBot(); extern int prSliverTop(), prSliverBot(); extern int prInSliver(); extern int prIllegalTop(), prIllegalBot(); extern int prCoverTop(), prCoverBot(); extern int prFixedLHS(), prFixedRHS(), prFixedDragStubs(); extern int prContactLHS(), prContactRHS(); extern int prFindCells(); extern int prCell(); /* Defined elsewhere in this module */ extern CellDef *plowYankDef; extern CellUse *plowYankUse; extern CellDef *plowSpareDef; extern CellUse *plowSpareUse; extern Rect plowYankedArea; extern int plowYankHalo; /* Plow boundary information */ typedef struct pb { CellDef *pb_editDef; /* Cell to which this applies */ Rect pb_editArea; /* Area of boundary in edit cell coords */ /* The following exist for redisplay only */ CellDef *pb_rootDef; /* Display in all windows with this root */ Rect pb_rootArea; /* Area of boundary in root cell coords */ struct pb *pb_next; /* Next record in chain */ } PlowBoundary; /* If the following is TRUE, enable checking of boundaries */ bool plowCheckBoundary = FALSE; /* List of PlowBoundary records above */ PlowBoundary *plowBoundaryList = NULL; /* TRUE if labels or cells were changed by plowing */ bool plowLabelsChanged; /* Transform information to yank cell coordinates */ Transform plowYankTrans; /* Transform from original cell to yank cell */ Transform plowInverseTrans; /* Transform from yank cell to original cell */ Rect plowCellBbox; /* Transformed initial cell bounding box */ int plowDirection; /* Direction of plowing (GEO_*) */ /* Dummy whose cu_def pointer is reset to point to the def being plowed */ CellUse *plowDummyUse = (CellUse *) NULL; /* Debugging */ RuleTableEntry *plowCurrentRule;/* Rule currently being applied */ RuleTableEntry plowRuleInitial; /* Dummy rule for debugging */ /* Procedure called for each edge affected by the one being moved */ int (*plowPropagateProcPtr)() = (int (*)()) NULL; /* Statistics */ int plowQueuedEdges; /* Number of edges passed to plowQueueAdd */ int plowProcessedEdges; /* Number of times plowProcessEdge called */ int plowMovedEdges; /* Number of edges actually moved */ /* Forward declarations */ int plowInitialPaint(), plowInitialCell(); int plowUpdatePaintTile(), plowUpdateCell(); bool plowPastBoundary(); bool plowPropagateSel(); bool plowPropagateRect(); PlowRule *plowBuildWidthRules(); void plowMergeBottom(Tile *, Plane *); void plowInitRule(); extern void PlowRedrawBound(); extern void PlowClearBound(); extern void plowUpdate(); extern void plowSetTrans(); extern void plowProcessEdge(); extern void plowMoveEdge(); extern void plowMergeTop(); extern void plowYankCreate(); /* * ---------------------------------------------------------------------------- * * PlowSetBound -- * * Set the bounding box for plowing. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void PlowSetBound(def, area, rootDef, rootArea) CellDef *def; /* Def in which bounding area applies */ Rect *area; /* Area in 'def' coordinates */ CellDef *rootDef; /* Display bounding area in windows with this root */ Rect *rootArea; /* Area in 'rootDef' coordinates */ { static bool firstTime = TRUE; PlowBoundary *pb; /* May eventually support a list, but for now, there's just one */ PlowClearBound(); pb = (PlowBoundary *) mallocMagic(sizeof (PlowBoundary)); pb->pb_rootDef = rootDef; pb->pb_rootArea = *rootArea; pb->pb_editDef = def; pb->pb_editArea = *area; pb->pb_next = (PlowBoundary *) NULL; plowBoundaryList = pb; plowCheckBoundary = TRUE; /* Add ourselves as a client of the highlight handler */ if (firstTime) DBWHLAddClient(PlowRedrawBound), firstTime = FALSE; /* Redisplay the highlight we just added */ DBWHLRedraw(rootDef, rootArea, FALSE); } /* * ---------------------------------------------------------------------------- * * PlowClearBound -- * * Eliminate boundary checking for plowing. * * Results: * None. * * Side effects: * Eliminates the highlight of the plowing bounding box. * * ---------------------------------------------------------------------------- */ void PlowClearBound() { PlowBoundary *pb; pb = plowBoundaryList; plowCheckBoundary = FALSE; plowBoundaryList = (PlowBoundary *) NULL; for ( ; pb; pb = pb->pb_next) { DBWHLRedraw(pb->pb_rootDef, &pb->pb_rootArea, TRUE); freeMagic((char *) pb); } } /* * ---------------------------------------------------------------------------- * * PlowRedrawBound -- * * This procedure is called by the highlight manager to redisplay * plowing highlights. The window is locked before entry. * * Results: * None. * * Side effects: * Plowing highlight information is redrawn, if there is any * that needs redisplaying. * * ---------------------------------------------------------------------------- */ void PlowRedrawBound(window, plane) MagWindow *window; /* Window in which to redraw. */ Plane *plane; /* Non-space tiles on this plane indicate * areas where highlights need to be * redisplayed. */ { Rect worldArea, screenArea; CellDef *windowRoot; PlowBoundary *pb; extern int plowBoundAlways1(); /* Forward reference. */ /* Nothing to do if no boundaries */ if (!plowCheckBoundary) return; windowRoot = ((CellUse *) (window->w_surfaceID))->cu_def; GrSetStuff(STYLE_DOTTEDHIGHLIGHTS); WindSurfaceToScreen(window, &window->w_surfaceArea, &worldArea); for (pb = plowBoundaryList; pb; pb = pb->pb_next) { /* Nothing to do if not in the right window */ if (windowRoot != pb->pb_rootDef) continue; /* See if the current area needs to be redisplayed */ if (!DBSrPaintArea((Tile *) NULL, plane, &pb->pb_rootArea, &DBAllButSpaceBits, plowBoundAlways1, (ClientData) NULL)) continue; WindSurfaceToScreen(window, &pb->pb_rootArea, &screenArea); GeoClip(&screenArea, &worldArea); GrFastBox(&screenArea); } } int plowBoundAlways1() { return 1; } /* * ---------------------------------------------------------------------------- * * PlowStraighten -- * * Straighten all jogs in the interior of the Rect 'area' in the CellDef 'def' * by pulling them all in 'direction' (one of GEO_NORTH, GEO_SOUTH, GEO_EAST, * or GEO_WEST) in such a way as to avoid moving any edges other than the jogs. * * Results: * None. * * Side effects: * Modifies the geometry of def in the area 'area'. * * ---------------------------------------------------------------------------- */ void PlowStraighten(def, area, direction) CellDef *def; /* Def whose jogs we should straighten */ Rect *area; /* Area in which jogs are to be straightened */ int direction; /* Pull all jogs in this direction to straighten them */ { Rect changedArea, changedUserArea, yankArea; bool saveCheckBoundary; int saveJogHorizon; SearchContext scx; PaintUndoInfo ui; /* Make sure the yank buffers exist */ plowYankCreate(); /* Set the yank transforms plowYankTrans and plowInverseTrans */ plowSetTrans(direction); /* Set the bounding box of this cell in yanked coordinates */ GeoTransRect(&plowYankTrans, &def->cd_bbox, &plowCellBbox); /* Transform the straightening area into yank def coordinates */ GeoTransRect(&plowYankTrans, area, &yankArea); /* * Yank into yank buffer. * Yank at least a tech halo around the area to make sure * we detect all potential design-rule violations. */ plowDummyUse->cu_def = def; UndoDisable(); DBCellClearDef(plowYankDef); plowYankedArea.r_xbot = yankArea.r_xbot - DRCTechHalo; plowYankedArea.r_ybot = yankArea.r_ybot - DRCTechHalo; plowYankedArea.r_xtop = yankArea.r_xtop + DRCTechHalo; plowYankedArea.r_ytop = yankArea.r_ytop + DRCTechHalo; scx.scx_use = plowDummyUse; scx.scx_trans = plowYankTrans; GeoTransRect(&plowInverseTrans, &plowYankedArea, &scx.scx_area); (void) DBCellCopyPaint(&scx, &DBAllButSpaceAndDRCBits, 0, plowYankUse); (void) DBCellCopyCells(&scx, plowYankUse, (Rect *) NULL); DBReComputeBbox(plowYankDef); UndoEnable(); /* Temporarily disable boundary checking and jog horizon for the plow */ saveCheckBoundary = plowCheckBoundary; saveJogHorizon = PlowJogHorizon; plowCheckBoundary = FALSE; PlowJogHorizon = 0; /* Reduce jogs */ UndoDisable(); changedArea.r_xbot = changedArea.r_xtop = 0; changedArea.r_ybot = changedArea.r_ytop = 0; plowCleanupJogs(&yankArea, &changedArea); UndoEnable(); /* Debugging */ DBWAreaChanged(plowYankDef,&TiPlaneRect,DBW_ALLWINDOWS,&DBAllButSpaceBits); DBReComputeBbox(plowYankDef); /* Restore previous state of boundary checking and jog horizon */ plowCheckBoundary = saveCheckBoundary; PlowJogHorizon = saveJogHorizon; /* Done if nothing was changed */ if (GEO_RECTNULL(&changedArea)) return; /* Erase area in original def */ ui.pu_def = def; GeoTransRect(&plowInverseTrans, &changedArea, &changedUserArea); GeoClip(&changedUserArea, &TiPlaneRect); for (ui.pu_pNum = PL_TECHDEPBASE; ui.pu_pNum < DBNumPlanes; ui.pu_pNum++) DBPaintPlane(def->cd_planes[ui.pu_pNum], &changedUserArea, DBWriteResultTbl[TT_SPACE], &ui); /* Stuff from yank buffer back into original def */ scx.scx_area = changedArea; scx.scx_use = plowYankUse; scx.scx_trans = plowInverseTrans; (void) DBCellCopyPaint(&scx, &DBAllButSpaceAndDRCBits, 0, plowDummyUse); DBReComputeBbox(def); DBWAreaChanged(def, &changedUserArea, DBW_ALLWINDOWS, &DBAllButSpaceBits); DRCCheckThis(def, TT_CHECKPAINT, &changedUserArea); } /* * ---------------------------------------------------------------------------- * * PlowSelection -- * * Plow the entire selection by the distance indicated. * * Results: * Returns FALSE if *pdistance had to be modified in order to keep the * effects of plowing entirely within the limits specified by * plowBoundaryList, or TRUE otherwise. * * Side effects: * Plows. * If we return FALSE, then *pdistance will be modified as described above. * * ---------------------------------------------------------------------------- */ bool PlowSelection(def, pdistance, direction) CellDef *def; /* Cell being plowed */ int *pdistance; /* Distance to plow */ int direction; /* One of GEO_NORTH, GEO_SOUTH, GEO_WEST, or GEO_EAST */ { Rect changedArea; bool firstTime; /* Create the dummy yank buffers if they don't already exist */ plowYankCreate(); /* Set plowYankTrans and plowInverseTrans */ plowSetTrans(direction); /* Set the bounding box of this cell in yanked coordinates */ GeoTransRect(&plowYankTrans, &def->cd_bbox, &plowCellBbox); /* * If boundary checking is enabled, the following loop may be * executed several times because the original plow affected too * much of the circuit. In this case, userRect gets updated to * the amount the plow finally did move. */ firstTime = TRUE; while (plowPropagateSel(def, pdistance, &changedArea)) firstTime = FALSE; if (!GEO_RECTNULL(&changedArea)) plowUpdate(def, direction, &changedArea); return (firstTime); } /* * ---------------------------------------------------------------------------- * * Plow -- * * Plow a given collection of layers. * * Results: * Returns FALSE if userRect had to be modified in order to keep the * effects of plowing entirely within the limits specified by * plowBoundaryList, or TRUE otherwise. * * Side effects: * Plows. * If we return FALSE, then userRect will be modified as described above. * * ---------------------------------------------------------------------------- */ bool Plow(def, userRect, layers, direction) CellDef *def; /* Cell being plowed */ Rect *userRect; /* The plow. Interpreted as per direction * below. */ TileTypeBitMask layers; /* The initial plow only sees these layers */ int direction; /* One of GEO_NORTH, GEO_SOUTH, GEO_WEST, * or GEO_EAST. */ { #ifdef COUNTWIDTHCALLS extern int plowWidthNumCalls; extern int plowWidthNumChoices; #endif /* COUNTWIDTHCALLS */ TileTypeBitMask lc; Rect changedArea; bool firstTime; /* Create the dummy yank buffers if they don't already exist */ plowYankCreate(); /* Set plowYankTrans and plowInverseTrans */ plowSetTrans(direction); /* Set the bounding box of this cell in yanked coordinates */ GeoTransRect(&plowYankTrans, &def->cd_bbox, &plowCellBbox); /* * If boundary checking is enabled, the following loop may be * executed several times because the original plow affected too * much of the circuit. In this case, userRect gets updated to * the amount the plow finally did move. */ firstTime = TRUE; TTMaskCom2(&lc, &layers); while (plowPropagateRect(def, userRect, lc, &changedArea)) firstTime = FALSE; if (!GEO_RECTNULL(&changedArea)) plowUpdate(def, direction, &changedArea); #ifdef COUNTWIDTHCALLS TxPrintf("Choices = %d Calls = %d Choices/Call = %.1f\n", plowWidthNumChoices, plowWidthNumCalls, ((double) plowWidthNumChoices) / ((double) plowWidthNumCalls)); #endif /* COUNTWIDTHCALLS */ return (firstTime); } /* * ---------------------------------------------------------------------------- * * plowUpdate -- * * Update the original def after plowing. * * Results: * None. * * Side effects: * Updates the layout from plowYankDef. * * ---------------------------------------------------------------------------- */ void plowUpdate(def, direction, pChangedArea) CellDef *def; int direction; Rect *pChangedArea; { Rect changedUserArea; TileTypeBitMask *m; PaintUndoInfo ui; if (SigInterruptPending) goto done; /* Mark cell as modified */ def->cd_flags |= CDMODIFIED|CDGETNEWSTAMP; /* Bloat the changed area to catch edges on the LHS */ pChangedArea->r_xbot--, pChangedArea->r_ybot--; pChangedArea->r_xtop++, pChangedArea->r_ytop++; GeoTransRect(&plowInverseTrans, pChangedArea, &changedUserArea); GeoClip(&changedUserArea, &TiPlaneRect); /* SANITY */ plowLabelsChanged = FALSE; /* * Update the cells. Find whether each cell in the plowed * planes has moved, and if so, move the corresponding cell * in the original def. */ (void) DBCellEnum(plowYankDef, plowUpdateCell, (ClientData) def); /* * Update the labels. This consists of changing the positions * of each label that was dragged along with its paint. The * labels come from the original def, since they didn't have * to be yanked. */ plowUpdateLabels(plowYankDef, def, &changedUserArea); /* * Update the paint. Erase the changed area from the original * layout, and then paint back from the new layout. Use the * transform plowInverseTrans to transform back from the yanked * planes into coordinates of the original def. */ ui.pu_def = def; for (ui.pu_pNum = PL_TECHDEPBASE; ui.pu_pNum < DBNumPlanes; ui.pu_pNum++) { /* Erase area in original def */ DBPaintPlane(def->cd_planes[ui.pu_pNum], &changedUserArea, DBWriteResultTbl[TT_SPACE], &ui); /* Update from yanked def */ (void) DBSrPaintArea((Tile *) NULL, plowYankDef->cd_planes[ui.pu_pNum], pChangedArea, &DBAllButSpaceBits, plowUpdatePaintTile, (ClientData) &ui); } /* Ashes to ashes */ done: DBAdjustLabels(def, &changedUserArea); DBReComputeBbox(plowYankDef); DBReComputeBbox(def); m = &DBAllButSpaceBits; if (plowLabelsChanged) m = (TileTypeBitMask *) NULL; DBWAreaChanged(def, &changedUserArea, DBW_ALLWINDOWS, m); DRCCheckThis(def, TT_CHECKSUBCELL, &changedUserArea); /* * Final postpass: straighten any jogs in the area * affected by this plow operation. */ if (PlowDoStraighten && !SigInterruptPending) PlowStraighten(def, &changedUserArea, direction); } /* * ---------------------------------------------------------------------------- * * plowPropagateRect -- * * Do the actual work of plowing a single plow, propagating the * effects of the initial plow to all geometry eventually affected by it. * * If the global bool plowCheckBoundary is TRUE, then we check against * the boundaries in the list plowBoundaryList for edges that violate * the limits set by those boundaries. If the effects of plowing extend * outside of this area, we adjust userRect to the largest plowing rectangle * that will not cause propagation into illegal areas. If userRect had to * be adjusted, we return TRUE. * * Results: * Returns TRUE if we had to adjust userRect, FALSE if not. * If plowCheckBoundary is FALSE, we never return TRUE. * * Side effects: * See above. * Sets the rectangle pointed to by 'changedArea' to be a * bounding box around the area modified by plowing. * * ---------------------------------------------------------------------------- */ bool plowPropagateRect(def, userRect, lc, changedArea) CellDef *def; /* Def being plowed */ Rect *userRect; /* User-specified plow (we transform this) */ TileTypeBitMask lc; /* Complement of set of layers to plow */ Rect *changedArea; /* Set to bounding box around area modified */ { Rect cellPlowRect, plowRect, r; #ifndef NO_RUSAGE struct rusage t1, t2; #endif int tooFar, pNum; SearchContext scx; Edge edge; changedArea->r_xbot = changedArea->r_xtop = 0; changedArea->r_ybot = changedArea->r_ytop = 0; /* * Back off by one lambda to catch edges underneath the plow. * If no work to do, then we return FALSE. */ GeoTransRect(&plowYankTrans, userRect, &plowRect); if (plowRect.r_xbot == plowRect.r_xtop) return (FALSE); cellPlowRect = plowRect; plowRect.r_xbot--; /* Clear the yank buffer for this iteration */ DBCellClearDef(plowYankDef); /* * Part 0. * Yank the area of the plow, plus plowYankHalo, into a separate * set of tile planes. */ plowDummyUse->cu_def = def; UndoDisable(); scx.scx_use = plowDummyUse; scx.scx_trans = plowYankTrans; if (DebugIsSet(plowDebugID, plowDebYankAll)) { scx.scx_area.r_xbot = def->cd_bbox.r_xbot - 1; scx.scx_area.r_ybot = def->cd_bbox.r_ybot - 1; scx.scx_area.r_xtop = def->cd_bbox.r_xtop + 1; scx.scx_area.r_ytop = def->cd_bbox.r_ytop + 1; GeoTransRect(&plowYankTrans, &scx.scx_area, &plowYankedArea); } else { plowYankedArea.r_xbot = plowRect.r_xbot - plowYankHalo; plowYankedArea.r_xtop = plowRect.r_xtop + plowYankHalo; plowYankedArea.r_ybot = plowRect.r_ybot - plowYankHalo; plowYankedArea.r_ytop = plowRect.r_ytop + plowYankHalo; GeoTransRect(&plowInverseTrans, &plowYankedArea, &scx.scx_area); } (void) DBCellCopyPaint(&scx, &DBAllButSpaceAndDRCBits, 0, plowYankUse); (void) DBCellCopyCells(&scx, plowYankUse, (Rect *) NULL); UndoEnable(); /* * Part 1. * Searching. This finds all the edges in the layout that have * to move, and marks them with the distance they must move. * Everything here works with the transformed cell. We initialize * plowCurrentRule to null here so the debugging output for plowQueueAdd * will reflect the fact that the edges found below are "initial" edges * (those found by the plow itself, as opposed to by other edges). */ #ifndef NO_RUSAGE if (DebugIsSet(plowDebugID, plowDebTime)) getrusage(RUSAGE_SELF, &t1); #endif plowMovedEdges = plowProcessedEdges = plowQueuedEdges = 0; plowQueueInit(&plowCellBbox, plowRect.r_xtop - plowRect.r_xbot); /* Queue each edge found by the plowing rules */ plowPropagateProcPtr = plowQueueAdd; /* Debugging */ plowCurrentRule = &plowRuleInitial; /* Add the initial edges */ for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) (void) plowSrShadowInitial(pNum, &plowRect, lc, plowInitialPaint, (ClientData) plowRect.r_xtop); /* Find any subcells crossed by the plow */ (void) TiSrArea((Tile *) NULL, plowYankDef->cd_planes[PL_CELL], &cellPlowRect, plowInitialCell, (ClientData) &cellPlowRect); /* While edges remain, process them */ tooFar = 0; while (plowQueueLeftmost(&edge)) { /* Ignore edges that don't move (sanity check) */ if (edge.e_x == edge.e_newx) continue; /* * If we are doing boundary checking, don't add edges to the right of * the boundary; just record how far they move. Edges whose original * position is to the left of the boundary but cross it must still be * queued for processing, since they can affect edges on the right of * the boundary. */ if (plowCheckBoundary && plowPastBoundary(def, &edge, &tooFar)) continue; if (!SigInterruptPending) plowProcessEdge(&edge, changedArea); } /* Clean up */ plowQueueDone(); #ifndef NO_RUSAGE if (DebugIsSet(plowDebugID, plowDebTime)) { getrusage(RUSAGE_SELF, &t2); plowShowTime(&t1, &t2, plowQueuedEdges, plowProcessedEdges, plowMovedEdges); } #endif /* * If geometry to the right of the boundary moved, adjust * the user's plow. */ if (tooFar) { GeoTransRect(&plowYankTrans, userRect, &r); r.r_xtop -= tooFar; GeoTransRect(&plowInverseTrans, &r, userRect); return (TRUE); } /* Successful plow */ return (FALSE); } /* * ---------------------------------------------------------------------------- * * plowPropagateSel -- * * Do the actual work of plowing the selection, propagating the * effects of each initial plow to all geometry eventually affected * by them. * * If the global bool plowCheckBoundary is TRUE, then we check against * the boundaries in the list plowBoundaryList for edges that violate * the limits set by those boundaries. If the effects of plowing extend * outside of this area, we adjust *pdistance to the largest plowing distance * that will not cause propagation into illegal areas. If *pdistance had to * be adjusted, we return TRUE. * * Results: * Returns TRUE if we had to adjust *pdistance, FALSE if not. * If plowCheckBoundary is FALSE, we never return TRUE. * * Side effects: * See above. * Sets the rectangle pointed to by 'changedArea' to be a * bounding box around the area modified by plowing. * * ---------------------------------------------------------------------------- */ bool plowPropagateSel(def, pdistance, changedArea) CellDef *def; /* Def being plowed */ int *pdistance; /* Distance to plow */ Rect *changedArea; /* Set to bounding box around area modified */ { #ifndef NO_RUSAGE struct rusage t1, t2; #endif int plowSelPaintBox(), plowSelCellBox(); int plowSelPaintPlow(), plowSelCellPlow(); Rect selBox; int tooFar; SearchContext scx; bool dummy; Edge edge; changedArea->r_xbot = changedArea->r_xtop = 0; changedArea->r_ybot = changedArea->r_ytop = 0; if (*pdistance <= 0) return (FALSE); /* * Find the bounding box for all material in the selection * that lies in the edit cell. */ selBox.r_xbot = selBox.r_ybot = INFINITY; selBox.r_xtop = selBox.r_ytop = MINFINITY; SelEnumPaint(&DBAllButSpaceBits, TRUE, &dummy, plowSelPaintBox, (ClientData) &selBox); SelEnumCells(TRUE, &dummy, (SearchContext *) NULL, plowSelCellBox, (ClientData) &selBox); if (GEO_RECTNULL(&selBox)) return (FALSE); /* Clear the yank buffer for this iteration */ DBCellClearDef(plowYankDef); /* * Yank the area of the selection, plus plowYankHalo, * into a separate set of tile planes. */ plowDummyUse->cu_def = def; UndoDisable(); scx.scx_use = plowDummyUse; scx.scx_trans = plowYankTrans; if (DebugIsSet(plowDebugID, plowDebYankAll)) { scx.scx_area.r_xbot = def->cd_bbox.r_xbot - 1; scx.scx_area.r_ybot = def->cd_bbox.r_ybot - 1; scx.scx_area.r_xtop = def->cd_bbox.r_xtop + 1; scx.scx_area.r_ytop = def->cd_bbox.r_ytop + 1; GeoTransRect(&plowYankTrans, &scx.scx_area, &plowYankedArea); } else { /* Note selBox is in parent def coordinates */ GeoTransRect(&plowYankTrans, &selBox, &plowYankedArea); plowYankedArea.r_xtop += *pdistance + plowYankHalo; plowYankedArea.r_xbot -= plowYankHalo; plowYankedArea.r_ybot -= plowYankHalo; plowYankedArea.r_ytop += plowYankHalo; GeoTransRect(&plowInverseTrans, &plowYankedArea, &scx.scx_area); } (void) DBCellCopyPaint(&scx, &DBAllButSpaceAndDRCBits, 0, plowYankUse); (void) DBCellCopyCells(&scx, plowYankUse, (Rect *) NULL); UndoEnable(); /* * Searching. This finds all the edges in the layout that have * to move, and marks them with the distance they must move. * Everything here works with the transformed cell. We initialize * plowCurrentRule to null here so the debugging output for plowQueueAdd * will reflect the fact that the edges found below are "initial" edges * (those found by the plow itself, as opposed to by other edges). */ #ifndef NO_RUSAGE if (DebugIsSet(plowDebugID, plowDebTime)) getrusage(RUSAGE_SELF, &t1); #endif plowMovedEdges = plowProcessedEdges = plowQueuedEdges = 0; plowQueueInit(&plowCellBbox, *pdistance); /* Queue each edge found by the plowing rules */ plowPropagateProcPtr = plowQueueAdd; /* Debugging */ plowCurrentRule = &plowRuleInitial; /* Add everything in the selection */ SelEnumPaint(&DBAllButSpaceBits, TRUE, &dummy, plowSelPaintPlow, (ClientData) *pdistance); SelEnumCells(TRUE, &dummy, (SearchContext *) NULL, plowSelCellPlow, (ClientData) *pdistance); /* While edges remain, process them */ tooFar = 0; while (plowQueueLeftmost(&edge)) { /* Ignore edges that don't move (sanity check) */ if (edge.e_x == edge.e_newx) continue; /* * If we are doing boundary checking, don't add edges to the right of * the boundary; just record how far they move. Edges whose original * position is to the left of the boundary but cross it must still be * queued for processing, since they can affect edges on the right of * the boundary. */ if (plowCheckBoundary && plowPastBoundary(def, &edge, &tooFar)) continue; if (!SigInterruptPending) plowProcessEdge(&edge, changedArea); } /* Clean up */ plowQueueDone(); #ifndef NO_RUSAGE if (DebugIsSet(plowDebugID, plowDebTime)) { getrusage(RUSAGE_SELF, &t2); plowShowTime(&t1, &t2, plowQueuedEdges, plowProcessedEdges, plowMovedEdges); } #endif /* * If geometry to the right of the boundary moved, * adjust the plow distance. */ if (tooFar) { *pdistance -= tooFar; return (TRUE); } /* Successful plow */ return (FALSE); } /* * ---------------------------------------------------------------------------- * * plowSelPaintBox -- * plowSelCellBox -- * * Called on behalf of plowPropagateSel() above to find the bounding * box for the material in the selection. Each is called for an element * in the selection: a paint tile for plowSelPaintBox, or a subcell for * plowSelCellBox. The bounding box *pSelBox is updated to include the * area of the element. * * Results: * Both return 0 always. * * Side effects: * Both adjust *pSelBox; * * ---------------------------------------------------------------------------- */ int plowSelPaintBox(rect, type, pSelBox) Rect *rect; TileType type; Rect *pSelBox; { Rect editRect; GeoTransRect(&RootToEditTransform, rect, &editRect); GeoInclude(&editRect, pSelBox); return (0); } int plowSelCellBox(selUse, realUse, transform, pSelBox) CellUse *selUse; CellUse *realUse; Transform *transform; Rect *pSelBox; { GeoInclude(&realUse->cu_bbox, pSelBox); return (0); } /* * ---------------------------------------------------------------------------- * * plowSelPaintPlow -- * * Called on behalf of plowPropagateSel() above to queue the initial * edges belonging to material in the selection. For paint, we create * a plow at both the right and left edges of the tile. * * Results: * Returns 0 always. * * Side effects: * Queues edges marked as initial (e_flags has E_ISINITIAL set). * * ---------------------------------------------------------------------------- */ int plowSelPaintPlow(rect, type, distance) Rect *rect; TileType type; int distance; { int plowSelPaintAdd(); Rect editRect, plowRect, plowLHS, plowRHS; TileTypeBitMask mask; GeoTransRect(&RootToEditTransform, rect, &editRect); GeoTransRect(&plowYankTrans, &editRect, &plowRect); plowLHS = plowRHS = plowRect; /* Queue the LHS */ plowLHS.r_xtop = plowLHS.r_xbot + distance; #ifdef notdef plowAtomize(DBPlane(type), &plowLHS, plowSelPaintAdd, (ClientData) NULL); #endif /* notdef */ plowLHS.r_xbot--; plowSrShadow(DBPlane(type), &plowLHS, DBZeroTypeBits, plowInitialPaint, (ClientData) plowLHS.r_xtop); /* Queue the RHS */ plowRHS.r_xbot = plowRHS.r_xtop; plowRHS.r_xtop += distance; #ifdef notdef plowAtomize(DBPlane(type), &plowRHS, plowSelPaintAdd, (ClientData) NULL); #endif /* notdef */ plowRHS.r_xbot--; TTMaskSetOnlyType(&mask, type); plowSrShadow(DBPlane(type), &plowRHS, mask, plowInitialPaint, (ClientData) plowRHS.r_xtop); return (0); } int plowSelPaintAdd(edge) Edge *edge; { int saveFlags = edge->e_flags; edge->e_flags |= E_ISINITIAL; plowQueueAdd(edge); edge->e_flags = saveFlags; return (0); } /* * ---------------------------------------------------------------------------- * * plowSelCellPlow -- * * Called on behalf of plowPropagateSel() above to queue the initial * edges belonging to material in the selection. For subcells, we * have to look for the subcell with the same use-id in our yank * buffer, and then move it by its leading edge. * * Results: * Returns 0 always. * * Side effects: * Queues edges. * * ---------------------------------------------------------------------------- */ int plowSelCellPlow(selUse, realUse, transform, distance) CellUse *selUse; /* Cell in selection */ CellUse *realUse; /* Corresponding cell in def being plowed */ Transform *transform; /* UNUSED */ int distance; /* Plow distance */ { int plowFindSelCell(); ClientData save; /* Find the cell in the yanked def that has the same use-id as this one */ save = realUse->cu_client; realUse->cu_client = (ClientData)distance; (void) DBCellEnum(plowYankDef, plowFindSelCell, (ClientData)realUse); realUse->cu_client = save; return (0); } int plowFindSelCell(yankUse, editUse) CellUse *yankUse; /* Cell in the plow yank buffer */ CellUse *editUse; /* Cell from the original cell def */ { Edge edge; if (strcmp(yankUse->cu_id, editUse->cu_id) != 0) return (0); edge.e_flags = 0; edge.e_pNum = PL_CELL; edge.e_use = yankUse; edge.e_ytop = yankUse->cu_bbox.r_ytop; edge.e_ybot = yankUse->cu_bbox.r_ybot; edge.e_x = yankUse->cu_bbox.r_xtop; edge.e_newx = yankUse->cu_bbox.r_xtop + (int)editUse->cu_client; edge.e_ltype = PLOWTYPE_CELL; edge.e_rtype = PLOWTYPE_CELL; (void) plowQueueAdd(&edge); return (1); } /* * ---------------------------------------------------------------------------- * * PlowExtendJogHorizon -- * * Search above and below 'edge' for the closest "natural" jogs within * plowJogHorizon of the top or bottom of the edge, and extend 'edge' * to these jogs if they are found. If no jog is found in a particular * direction, we leave that end of 'edge' (top/bottom) alone. * * A "natural" jog is nothing more than a change in the direction of * an edge being followed. The following diagram gives an example, with * the vertical arrows indicating the jog horizons. Note that the edge * is extended up, because there is a natural jog there, but not down * because the jog on the bottom is outside the horizon. * * +-------- ^ E-------- * | | E * | | E * | v E * E E * E E * E E * | ^ | * | | | * | | | * | v | * | | * --------+ --------+ * * Results: * None. * * Side effects: * May modify its argument 'edge' by extending it vertically. * May also add additional edges via plowAtomizeEdge(). * * ---------------------------------------------------------------------------- */ void PlowExtendJogHorizon(edge) Edge *edge; /* Edge being moved */ { int horizonTop, horizonBot, eTop, eBot; Tile *tpR, *tpL; Point startPoint; bool rhsChanged; Rect r, newEdgeR; if (PlowJogHorizon == 0) return; horizonTop = edge->e_ytop + PlowJogHorizon; horizonBot = edge->e_ybot - PlowJogHorizon; r.r_xbot = edge->e_x - 1; r.r_xtop = edge->e_x + 1; newEdgeR = edge->e_rect; /* Extend to the top */ restarttop: startPoint.p_x = edge->e_x - 1; startPoint.p_y = edge->e_ytop; tpL = TiSrPointNoHint(plowYankDef->cd_planes[edge->e_pNum], &startPoint); r.r_ybot = r.r_ytop = edge->e_ytop; /* * Walk upwards. * The loop terminates with r.r_ytop equal to the Y coordinate * of the closest jog to our top, and eTop equal to the smaller * of r.r_ytop and the Y coordinate of the closest point at which * the RHS of the edge changed type. */ rhsChanged = FALSE; while (RIGHT(tpL) == edge->e_x && TiGetTypeExact(tpL) == edge->e_ltype && BOTTOM(tpL) < horizonTop) { r.r_ytop = TOP(tpL); if (plowYankMore(&r, 1, 1)) goto restarttop; /* * Walk along RHS to see if its type changed. * If so, make eTop record the lowest point * at which this happened. */ if (!rhsChanged) for (tpR = TR(tpL); TOP(tpR) > r.r_ybot; tpR = LB(tpR)) if (TiGetTypeExact(tpR) != edge->e_rtype) rhsChanged = TRUE, eTop = BOTTOM(tpR); tpL = RT(tpL); r.r_ybot = r.r_ytop; } /* Update if within the jog horizon */ if (r.r_ytop <= horizonTop && r.r_ytop > edge->e_ytop) { newEdgeR.r_ytop = r.r_ytop; edge->e_ytop = (rhsChanged) ? eTop : r.r_ytop; } /* Extend to the bottom */ restartbot: startPoint.p_x = edge->e_x; startPoint.p_y = edge->e_ybot - 1; tpR = TiSrPointNoHint(plowYankDef->cd_planes[edge->e_pNum], &startPoint); r.r_ybot = r.r_ytop = edge->e_ybot; /* * Walk down. * The loop terminates with r.r_ybot equal to the Y coordinate * of the closest jog to our bottom, and eBot equal to the larger * of r.r_ytop and the Y coordinate of the closest point at which * the RHS of the edge changed type. */ rhsChanged = FALSE; while (LEFT(tpR) == edge->e_x && TOP(tpR) > horizonBot) { r.r_ybot = BOTTOM(tpR); if (plowYankMore(&r, 1, 1)) goto restartbot; /* Record where the RHS type changed if it did */ if (!rhsChanged && TiGetTypeExact(tpR) != edge->e_rtype) rhsChanged = TRUE, eBot = TOP(tpR); /* Walk up the LHS */ for (tpL = BL(tpR); BOTTOM(tpL) < r.r_ytop; tpL = RT(tpL)) if (TiGetTypeExact(tpL) != edge->e_ltype) r.r_ybot = TOP(tpL); if (r.r_ybot > BOTTOM(tpR)) break; tpR = LB(tpR); r.r_ytop = r.r_ybot; } /* Update if within the jog horizon */ if (r.r_ybot >= horizonBot && r.r_ybot < edge->e_ybot) { newEdgeR.r_ybot = r.r_ybot; edge->e_ybot = (rhsChanged) ? eBot : r.r_ybot; } if (newEdgeR.r_ytop > edge->e_ytop) { r = newEdgeR; r.r_ybot = edge->e_ytop; (void) plowAtomize(edge->e_pNum, &r, plowQueueAdd, (ClientData) NULL); } if (newEdgeR.r_ybot < edge->e_ybot) { r = newEdgeR; r.r_ytop = edge->e_ybot; (void) plowAtomize(edge->e_pNum, &r, plowQueueAdd, (ClientData) NULL); } } /* * ---------------------------------------------------------------------------- * * plowSetTrans -- * * Set up the transforms based on the direction we will be plowing. * Just use simple rotations, since we always have the inverse * transform around for copying stuff back. * * Results: * None. * * Side effects: * Sets plowYankTrans and plowInverseTrans. * * ---------------------------------------------------------------------------- */ void plowSetTrans(direction) int direction; { plowDirection = direction; switch (direction) { case GEO_NORTH: plowYankTrans = Geo90Transform; break; case GEO_SOUTH: plowYankTrans = Geo270Transform; break; case GEO_WEST: plowYankTrans = Geo180Transform; break; case GEO_EAST: plowYankTrans = GeoIdentityTransform; break; } GeoInvertTrans(&plowYankTrans, &plowInverseTrans); } /* * ---------------------------------------------------------------------------- * * plowPastBoundary -- * * Check to see if the edge is in an illegal region according to the * boundaries on the list plowBoundaryList. * * Results: * TRUE if we should not even bother to process this edge (because * its initial position was in an invalid area), FALSE otherwise. * * Side effects: * Updates *pmove to the farthest distance by which anything in an * illegal area moves. * * ---------------------------------------------------------------------------- */ bool plowPastBoundary(def, edge, pmove) CellDef *def; /* Def being plowed */ Edge *edge; /* Edge being moved */ int *pmove; /* Updated to be the maximum distance by * which something moves in an illegal area. */ { PlowBoundary *pb; int delta; bool ret; Rect r; ret = FALSE; delta = 0; for (pb = plowBoundaryList; pb; pb = pb->pb_next) { if (pb->pb_editDef != def) continue; GeoTransRect(&plowYankTrans, &pb->pb_editArea, &r); if (edge->e_x < r.r_xbot) { /* To the left of the boundary */ delta = MAX(edge->e_newx, r.r_xbot) - edge->e_x; } else if (edge->e_newx > r.r_xtop) { /* To the right of the boundary */ delta = edge->e_newx - MAX(edge->e_x, r.r_xtop); if (edge->e_x > r.r_xtop) ret = TRUE; } else if (edge->e_ytop > r.r_ytop || edge->e_ybot < r.r_ybot) { /* Above or below the boundary */ delta = edge->e_newx - edge->e_x; } if (delta > *pmove) *pmove = delta; } return (ret); } /* * ---------------------------------------------------------------------------- * * plowInitialPaint -- * * Add one of the edges found initially by the plow to the queue * of edges to move. The edge will move as far as 'xnew'. * * Results: * Always returns 0. * * Side effects: * Adds the edge to the queue of edges to move via plowQueueAdd(). * * ---------------------------------------------------------------------------- */ int plowInitialPaint(edge, xnew) Edge *edge; int xnew; { edge->e_newx = xnew; edge->e_flags = E_ISINITIAL; (void) plowQueueAdd(edge); return (0); } /* * ---------------------------------------------------------------------------- * * plowInitialCell -- * * Add a cell to the queue of edges to move. The cell will move as far * as 'plowRect->r_xtop'. * * Results: * Always returns 0. * * Side effects: * Adds an edge to the queue of edges to move via plowQueueAdd(). * * ---------------------------------------------------------------------------- */ int plowInitialCell(cellTile, plowRect) Tile *cellTile; Rect *plowRect; { CellTileBody *ctb; CellUse *use; int xmove; Edge edge; edge.e_pNum = PL_CELL; for (ctb = (CellTileBody *) TiGetBody(cellTile); ctb; ctb = ctb->ctb_next) { use = ctb->ctb_use; if (use->cu_bbox.r_xbot < plowRect->r_xbot) { if (use->cu_bbox.r_xtop >= plowRect->r_xtop) continue; /* Dragging this cell by its front edge */ xmove = plowRect->r_xtop - use->cu_bbox.r_xtop; } else { /* Pushing this cell by its back edge */ xmove = plowRect->r_xtop - use->cu_bbox.r_xbot; } edge.e_use = use; edge.e_flags = E_ISINITIAL; edge.e_ytop = use->cu_bbox.r_ytop; edge.e_ybot = use->cu_bbox.r_ybot; edge.e_x = use->cu_bbox.r_xtop; edge.e_newx = use->cu_bbox.r_xtop + xmove; edge.e_ltype = PLOWTYPE_CELL; edge.e_rtype = PLOWTYPE_CELL; (void) plowQueueAdd(&edge); } return (0); } /* * ---------------------------------------------------------------------------- * * plowProcessEdge -- * * Process a single edge from the queue. * Plowing is rule-based, so processing an edge consists of applying * a sequence of rules. The overall algorithm is: * * - Yank more of the original cell if necessary. * - Check to see if the edge has already moved; if so, we don't do * anything further. * - Apply extension rules. These are allowed to extend the edge * but shouldn't search for new edges to be added to the edge queue. * - Compute the real width rules for this material. * - Apply search rules to each remaining segment of the clipped edge. * These look for other edges to be added to the edge queue. * - Update the edge's position. This consists of modifying the * LEADING coordinates in the tiles along the edge, possibly * splitting the tiles at the top and bottom of the edge. * * Results: * None. * * Side effects: * May split and merge tiles. * May cause additional area to be yanked from the original cell. * Updates changedArea to include any additional area modified. * * ---------------------------------------------------------------------------- */ void plowProcessEdge(edge, changedArea) Edge *edge; /* Edge to be processed (in plowYankDef) */ Rect *changedArea; /* Include any additional area changed in this area */ { int amountToMove = edge->e_newx - edge->e_x; RuleTableEntry *rte; Tile *tp; Point p; Rect r; /* Debugging */ if ((plowWhenTop && edge->e_x == plowWhenTopPoint.p_x && edge->e_ytop == plowWhenTopPoint.p_y) || (plowWhenBot && edge->e_x == plowWhenBotPoint.p_x && edge->e_ybot == plowWhenBotPoint.p_y)) { plowDebugEdge(edge, (RuleTableEntry *) NULL, "matched edge"); } /* * Process cells specially. * These don't get clipped, but are either processed * completely or not at all. */ plowProcessedEdges++; if (edge->e_use) { if (amountToMove > (int)edge->e_use->cu_client) { /* Update area modified by plowing */ (void) GeoInclude(&edge->e_rect, changedArea); /* * See if the cell's bbox plus the distance to move * forces us to yank more from the original cell. */ r = edge->e_use->cu_bbox; r.r_xtop = edge->e_newx; (void) plowYankMore(&r, plowYankHalo, 1); /* * Update the cell's position. * We do this here so we don't see the cell a * second time. The whole cell moves, so we have * to update the area changed by the area of the * cell PLUS the area swept out by its RHS. */ edge->e_use->cu_client = (ClientData)amountToMove; r = edge->e_use->cu_bbox; r.r_xbot += amountToMove; r.r_xtop += amountToMove; (void) GeoInclude(&r, changedArea); /* Apply cell rules */ for (rte = plowCellRulesTbl; rte < plowCellRulesPtr; rte++) { if (TTMaskHasType(&rte->rte_ltypes, edge->e_ltype) && TTMaskHasType(&rte->rte_rtypes, edge->e_rtype)) { plowCurrentRule = rte; (*rte->rte_proc)(edge, (PlowRule *) NULL); } } plowMovedEdges++; } return; } /* * Check to see if any of this edge needs to move. If it has * already moved far enough, we can just return; otherwise, * we process the entire edge as a whole. This check is necessary * to avoid infinite loops. */ p.p_x = edge->e_x, p.p_y = edge->e_ytop - 1; tp = TiSrPointNoHint(plowYankDef->cd_planes[edge->e_pNum], &p); for ( ; TOP(tp) > edge->e_ybot; tp = LB(tp)) if (TRAILING(tp) < edge->e_newx) goto worktodo; return; /* * Some or all of this edge must be moved. * Extend it if necessary. * Yank more if necessary. * Compute its width. * Apply the search rules. * Update the coordinates of all tiles along this edge. */ worktodo: /* * Extend this edge if we're reducing jogs. * May cause other edges to be added. */ plowMovedEdges++; if (PlowJogHorizon > 0) PlowExtendJogHorizon(edge); /* * Update area modified by plowing. * This must happen after applying the extension rules above. */ (void) GeoInclude(&edge->e_rect, changedArea); /* Apply search rules */ plowApplySearchRules(edge); /* Update edge position */ plowMoveEdge(edge); } /* * ---------------------------------------------------------------------------- * * plowApplySearchRules -- * * Apply the search rules to an edge. * * Results: * None. * * Side effects: * May call (*plowPropagateProcPtr)() if the search rules * determine that edges must move. May yank more. * May cause additional area to be yanked from the original cell. * * ---------------------------------------------------------------------------- */ int plowApplySearchRules(edge) Edge *edge; { PlowRule *widthRules, *rules; RuleTableEntry *rte; int halo; /* * Build list of width rules using computed (instead of min) width. * This can also yank more. */ halo = plowYankHalo; widthRules = plowBuildWidthRules(edge, &plowCellBbox, &halo); /* Yank more if necessary */ (void) plowYankMore(&edge->e_rect, halo, 1); /* * Search rules. * These generally won't need to yank more unless they deal * with entire tiles. */ for (rte = plowSearchRulesTbl; rte < plowSearchRulesPtr; rte++) { if (TTMaskHasType(&rte->rte_ltypes, edge->e_ltype) && TTMaskHasType(&rte->rte_rtypes, edge->e_rtype)) { plowCurrentRule = rte; switch (rte->rte_whichRules) { /* Apply no rules */ case RTE_NULL: rules = (PlowRule *) NULL; break; /* Apply width rules, but use actual widths */ case RTE_REALWIDTH: rules = widthRules; break; /* Apply minimum-width rules */ case RTE_MINWIDTH: rules = plowWidthRulesTbl[edge->e_ltype][edge->e_rtype]; break; /* Apply spacing rules */ case RTE_SPACING: rules = plowSpacingRulesTbl[edge->e_ltype][edge->e_rtype]; break; /* Only apply rule if no spacing rules apply */ case RTE_NOSPACING: rules = plowSpacingRulesTbl[edge->e_ltype][edge->e_rtype]; if (rules) continue; break; } (*rte->rte_proc)(edge, rules); } } return 0; } /* * ---------------------------------------------------------------------------- * * plowBuildWidthRules -- * * Find the real width of the material being plowed, and construct * a list of width rules that is the same as the normal list for * this type of edge, but with the minimum distance replaced by the * actual width if the actual width is greater than the minimum * distance. (If the actual width is less than or equal to the * minimum distance, we use the minimum distance instead). * * If the minimum-width rectangle about the starting edge touches the * boundary of the yanked area, yank more and retry. * * Results: * Returns a pointer to the statically constructed rules list, * or NULL if no width rules apply. * * Side effects: * Since the width rules list is statically allocated, subsequent * calls to plowBuildWidthRules() will trash the results of previous * calls. * * May cause more of the original cell to be yanked. * * ---------------------------------------------------------------------------- */ PlowRule * plowBuildWidthRules(edge, bbox, phalo) Edge *edge; /* Edge being moved */ Rect *bbox; /* Bounding box of def being plowed */ int *phalo; /* Update *phalo to be the max of its initial value * and each of the widths we compute for the rules * we return. */ { extern char *maskToPrint(); static PlowRule widthRuleList[MAXRULES]; PlowRule *prMin, *prReal; Rect maxBox; int dist; retry: prMin = plowWidthRulesTbl[edge->e_ltype][edge->e_rtype]; if (prMin == NULL) return ((PlowRule *) NULL); /* At this point, know there will be at least one rule in the list */ for (prReal = widthRuleList; prMin && prReal < &widthRuleList[MAXRULES]; prMin = prMin->pr_next, prReal++) { *prReal = *prMin; prReal->pr_next = prReal + 1; dist = plowFindWidth(edge, prMin->pr_oktypes, bbox, &maxBox); /* Conservative test of whether we need to yank more */ if (plowYankMore(&maxBox, 1, 1)) { if (DebugIsSet(plowDebugID, plowDebWidth)) TxPrintf("width: yank more and retry\n"); goto retry; } prReal->pr_dist = MAX(dist, prReal->pr_dist); *phalo = MAX(*phalo, dist); if (DebugIsSet(plowDebugID, plowDebWidth)) TxPrintf("width: %d types: %s\n", prReal->pr_dist, maskToPrint(&prReal->pr_oktypes)); } (--prReal)->pr_next = (PlowRule *) NULL; if (DebugIsSet(plowDebugID, plowDebWidth)) plowDebugEdge(edge, (RuleTableEntry *) NULL, "find width"); return (widthRuleList); } /* * ---------------------------------------------------------------------------- * * plowMoveEdge -- * * Do the actual work of updating the coordinates of an edge. In general, * the edge may have more than one tile on either side, as below: * * | * | * --------+ * +--------- * | * | * --------+ * |--------- * | * --------+ * | * * Updating the coordinates consists of first clipping the tiles on * either side so they do not extend vertically past the edge, then * updating the TRAILING coordinates of all tiles along the RHS, and * then merging vertically where possible. * * We only update TRAILING coordinates if they are not already far * enough to the right. * * Results: * None. * * Side effects: * May split and merge tiles. * * ---------------------------------------------------------------------------- */ void plowMoveEdge(edge) Edge *edge; /* Edge to be moved */ { Plane *plane = plowYankDef->cd_planes[edge->e_pNum]; Tile *tp, *tpL; Point p; /* * Find topmost tile along LHS of edge. * The goal is to clip the topmost LHS and topmost RHS tiles * so their tops are equal to the top of the edge. */ p.p_x = edge->e_x - 1; p.p_y = edge->e_ytop - 1; tp = TiSrPointNoHint(plane, &p); ASSERT(RIGHT(tp) == edge->e_x, "plowMoveEdge"); /* Only clip top tiles if we must update their coordinates */ if (LEADING(tp) < edge->e_newx) { if (TOP(tp) > edge->e_ytop) (void) plowSplitY(tp, edge->e_ytop); /* Tp is bottom tile */ tp = TR(tp); /* Top tile on RHS */ if (TOP(tp) > edge->e_ytop) (void) plowSplitY(tp, edge->e_ytop); /* Tp is bottom tile */ } else for (tp = TR(tp); BOTTOM(tp) >= edge->e_ytop; tp = LB(tp)) /* Nothing */; /* * Now 'tp' is the top-right tile. Walk down the RHS, updating TRAILING * coordinates if necessary, and merging each tile with its upper neighbor. * Stop one short of the last tile. */ for (; BOTTOM(tp) > edge->e_ybot; tp = LB(tp)) { if (TRAILING(tp) < edge->e_newx) plowSetTrailing(tp, edge->e_newx); plowMergeTop(tp, plane); } /* * Now 'tp' is the bottom-right tile. * Clip it if necessary, and update its TRAILING coordinate. Merge it * with both its upper and lower neighbors. If tp is the only tile on * the RHS, its TRAILING coordinate doesn't get updated until here. */ if (TRAILING(tp) < edge->e_newx) { if (BOTTOM(tp) < edge->e_ybot) { /* Clip (no merging will be necessary) */ tp = plowSplitY(tp, edge->e_ybot); plowSetTrailing(tp, edge->e_newx); tpL = BL(tp); } else /* BOTTOM(tp) == edge->e_ybot */ { /* Merge (no clipping was necessary) */ tpL = BL(tp); plowSetTrailing(tp, edge->e_newx); plowMergeBottom(tp, plane); } /* Split the bottom-left tile if necessary; otherwise, merge down */ if (BOTTOM(tpL) < edge->e_ybot) tpL = plowSplitY(tpL, edge->e_ybot); /* TpL is upper tile */ else plowMergeBottom(tpL, plane); } else for (tpL = BL(tp); TOP(tpL) <= edge->e_ybot; tpL = RT(tpL)) /* Nothing */; plowMergeTop(tp, plane); /* * Now 'tpL' is the bottom-left tile, which has already been merged * with its lower neighbor. Walk up the rest of the LHS, merging * each tile with its lower neighbor. */ for (tp = RT(tpL); BOTTOM(tp) < edge->e_ytop; tp = RT(tp)) plowMergeBottom(tp, plane); /* * If tp now extends above edge->e_ytop, then it must not have been split * way up in the first step in this procedure, which means that its LEADING * coordinate was already far enough to the right, which means that it was * not changed. Hence, we needn't try to merge to its bottom. */ if (BOTTOM(tp) == edge->e_ytop) plowMergeBottom(tp, plane); if (DebugIsSet(plowDebugID, plowDebMove)) plowDebugEdge(edge, (RuleTableEntry *) NULL, "move"); } /* * ---------------------------------------------------------------------------- * * plowSplitY -- * * Split a tile vertically in two, returning a pointer to * the newly created upper tile. * * The new tile has its ti_client edge positions set to that * of the original tile. * * Results: * Returns a pointer to the newly created tile. * * Side effects: * Splits the tile 'tp'. * * ---------------------------------------------------------------------------- */ Tile * plowSplitY(tp, y) Tile *tp; { Tile *newTile; newTile = TiSplitY(tp, y); newTile->ti_client = tp->ti_client; TiSetBody(newTile, TiGetBody(tp)); return (newTile); } /* * ---------------------------------------------------------------------------- * * plowMergeTop -- * plowMergeBottom -- * * Merge the given tile with its upper/lower neighbor if appropriate: * plowMergeTop merges with the upper neighbor, plowMergeBottom with * the lower. This may happen only if the types are the same, the * LEADING/TRAILING coordinate the same, and the LEFT and RIGHT * coordinates the same. * * Guarantees that the tile pointer passed it as an argument will * remain valid after the call. * * Results: * None. * * Side effects: * May cause two tiles to be joined. * * ---------------------------------------------------------------------------- */ void plowMergeTop(tp, plane) Tile *tp; Plane *plane; { Tile *tpRT = RT(tp); if (TiGetTypeExact(tp) == TiGetTypeExact(tpRT) && LEFT(tp) == LEFT(tpRT) && RIGHT(tp) == RIGHT(tpRT) && LEADING(tp) == LEADING(tpRT) && TRAILING(tp) == TRAILING(tpRT)) { TiJoinY(tp, tpRT, plane); } } void plowMergeBottom(tp, plane) Tile *tp; Plane *plane; { Tile *tpLB = LB(tp); if (TiGetTypeExact(tp) == TiGetTypeExact(tpLB) && LEFT(tp) == LEFT(tpLB) && RIGHT(tp) == RIGHT(tpLB) && LEADING(tp) == LEADING(tpLB) && TRAILING(tp) == TRAILING(tpLB)) { TiJoinY(tp, tpLB, plane); } } /* * ---------------------------------------------------------------------------- * * PlowInit -- * * Initialize the rule tables for plowing. This gets called after * the technology file has been read, since we need to know about * fixed-width objects. * * Also initialize the debugging information. * * Sets plowYankHalo to be the size of the halo around each edge that * we use when checking to see if plowProcessEdge must yank more area * from the original cell. If this halo extends outside plowYankedArea * or touches it, we yank more. The size of the halo should be such * that most of the plowing rules are guaranteed not to visit any area * outside of it. Currently, DRCTechHalo is sufficient; only the rules * moving whole tiles need anything bigger than this, and they are * responsible for doing their own yanking if they need it. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void PlowInit() { RuleTableEntry *rp, *re; TileTypeBitMask allButSpace, allBits; TileTypeBitMask cellTypes; TileTypeBitMask widthL, widthR; TileTypeBitMask spaceL, spaceR; TileTypeBitMask mask; TileType i, j; /* Set the masks we will use for all the rules below */ allButSpace = DBAllButSpaceAndDRCBits; allBits = DBAllTypeBits; TTMaskSetOnlyType(&cellTypes, PLOWTYPE_CELL); TTMaskZero(&widthL); TTMaskZero(&widthR); TTMaskZero(&spaceL); TTMaskZero(&spaceR); for (i = 0; i < DBNumTypes; i++) { for (j = 0; j < DBNumTypes; j++) { if (plowWidthRulesTbl[i][j]) { TTMaskSetType(&widthL, i); TTMaskSetType(&widthR, j); } if (plowSpacingRulesTbl[i][j]) { TTMaskSetType(&spaceL, i); TTMaskSetType(&spaceR, j); } } } /* Dummy rule for debugging */ plowInitRule(&plowRuleInitial, (&plowRuleInitial) + 1, RTE_NULL, (int (*)()) NULL, "initial edge", DBZeroTypeBits, DBZeroTypeBits); /* Cell rules */ rp = plowCellRulesPtr; re = &plowCellRulesTbl[MAXRULES]; /* Drag geometry with cells */ plowInitRule(rp++, re, RTE_NULL, prCell, "drag paint with cells", allBits, cellTypes); if (rp >= re) rp = re; plowCellRulesPtr = rp; /* Search rules */ rp = plowSearchRulesPtr; re = &plowSearchRulesTbl[MAXRULES]; /* Clear the umbra */ plowInitRule(rp++, re, RTE_NULL, prClearUmbra, "clear umbra", allBits, allButSpace); plowInitRule(rp++, re, RTE_REALWIDTH, prUmbra, "umbra width", widthL, widthR); plowInitRule(rp++, re, RTE_SPACING, prUmbra, "umbra spacing", spaceL, spaceR); /* Clear the penumbra */ plowInitRule(rp++, re, RTE_REALWIDTH, prPenumbraTop, "top penumbra width", widthL, widthR); plowInitRule(rp++, re, RTE_SPACING, prPenumbraTop, "top penumbra spacing", spaceL, spaceR); plowInitRule(rp++, re, RTE_REALWIDTH, prPenumbraBot, "bottom penumbra width", widthL, widthR); plowInitRule(rp++, re, RTE_SPACING, prPenumbraBot, "bottom penumbra spacing", spaceL, spaceR); /* Special penumbra searching when RHS is fixed */ plowInitRule(rp++, re, RTE_NOSPACING, prFixedPenumbraTop, "top penumbra spacing (RHS fixed-width)", allBits, PlowFixedTypes); plowInitRule(rp++, re, RTE_NOSPACING, prFixedPenumbraBot, "bottom penumbra spacing (RHS fixed-width)", allBits, PlowFixedTypes); /* Avoid introducing slivers */ plowInitRule(rp++, re, RTE_MINWIDTH, prSliverTop, "top width slivers", widthL, widthR); plowInitRule(rp++, re, RTE_SPACING, prSliverTop, "top spacing slivers", spaceL, spaceR); plowInitRule(rp++, re, RTE_MINWIDTH, prSliverBot, "bottom width slivers", widthL, widthR); plowInitRule(rp++, re, RTE_SPACING, prSliverBot, "bottom spacing slivers", spaceL, spaceR); /* Inside slivers (plow too small) */ TTMaskCom2(&mask, &PlowFixedTypes); plowInitRule(rp++, re, RTE_NULL, prInSliver, "inside slivers", mask, mask); /* Avoid introducing illegal edges */ plowInitRule(rp++, re, RTE_NULL, prIllegalTop, "top illegal edges", allBits, allBits); plowInitRule(rp++, re, RTE_NULL, prIllegalBot, "bottom illegal edges", allBits, allBits); /* Avoid uncovering "covered" materials (e.g, fets) */ plowInitRule(rp++, re, RTE_NULL, prCoverTop, "top covering", PlowCoveredTypes, allBits); plowInitRule(rp++, re, RTE_NULL, prCoverBot, "bottom covering", PlowCoveredTypes, allBits); /* Preserve fixed-width objects */ plowInitRule(rp++, re, RTE_NULL, prFixedLHS, "LHS is fixed", PlowFixedTypes, allBits); plowInitRule(rp++, re, RTE_NULL, prFixedRHS, "RHS is fixed", allBits, PlowFixedTypes); /* Fixed-width objects drag trailing stubs */ TTMaskCom2(&mask, &PlowDragTypes); TTMaskClearType(&mask, TT_SPACE); plowInitRule(rp++, re, RTE_NULL, prFixedDragStubs, "RHS fixed dragging stubs", mask, PlowDragTypes); /* Couple contacts */ plowInitRule(rp++, re, RTE_NULL, prContactLHS, "LHS is contact", PlowContactTypes, allBits); plowInitRule(rp++, re, RTE_NULL, prContactRHS, "RHS is contact", allBits, PlowContactTypes); /* Move cells out of the way */ plowInitRule(rp++, re, RTE_NULL, prFindCells, "find cells", allBits, allBits); if (rp >= re) rp = re; plowSearchRulesPtr = rp; /* Initialize debugging flags */ plowDebugInit(); /* Initialize the yank halo */ plowYankHalo = DRCTechHalo; } void plowInitRule(rtePtr, rteEnd, whichRules, proc, name, ltypes, rtypes) RuleTableEntry *rtePtr; /* Pointer to entry to be added */ RuleTableEntry *rteEnd; /* Pointer to one past last entry in table */ int whichRules; /* Which rules to use (RTE_* from earlier) */ int (*proc)(); /* Procedure implementing the rule */ char *name; /* Name of this rule */ TileTypeBitMask ltypes, rtypes; { if (rtePtr >= rteEnd) { TxError("Too many rules in PlowMain.c (maximum %d)\n", MAXRULES); return; } rtePtr->rte_whichRules = whichRules; rtePtr->rte_proc = proc; rtePtr->rte_name = name; rtePtr->rte_ltypes = ltypes; rtePtr->rte_rtypes = rtypes; } /* * ---------------------------------------------------------------------------- * * plowYankCreate -- * * Create the yank buffers used for plowing. * * Results: * None. * * Side effects: * Creates the cells __PLOWYANK__ and __PLOWINCR__ if they * don't already exist, and initializes plowYankDef, plowYankUse, * and plowDummyUse. * * ---------------------------------------------------------------------------- */ void plowYankCreate() { if (plowYankDef == NULL) { DBNewYank("__PLOWYANK__", &plowYankUse, &plowYankDef); DBNewYank("__PLOWYANK__", &plowDummyUse, &plowYankDef); DBNewYank("__PLOWINCR__", &plowSpareUse, &plowSpareDef); } } #ifndef NO_RUSAGE plowShowTime(t1, t2, nqueued, nprocessed, nmoved) struct rusage *t1, *t2; int nqueued, nprocessed, nmoved; { double secs, usecs; secs = t2->ru_utime.tv_sec - t1->ru_utime.tv_sec; usecs = (secs * 1000000.) + (t2->ru_utime.tv_usec - t1->ru_utime.tv_usec); printf("%.2f sec, %d queued, %d processed, %d moved\n", usecs/1000000., nqueued, nprocessed, nmoved); } #endif magic-8.0.210/plow/PlowYank.c0000644000175000001440000004116410751423606014355 0ustar timusers/* * PlowYank.c -- * * Plowing. * Incremental yanking, and painting the results back into the * original cell when done. * * ********************************************************************* * * 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/plow/PlowYank.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #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 "utils/undo.h" #include "debug/debug.h" #include "plow/plow.h" #include "plow/plowInt.h" #include "textio/textio.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "drc/drc.h" /* Yank buffer used to hold the actual geometry being plowed */ CellDef *plowYankDef; CellUse *plowYankUse; /* Incremental yanking information */ CellDef *plowSpareDef; /* Def into which we do each incremental yank */ CellUse *plowSpareUse; /* Use of above */ Rect plowYankedArea; /* Area yanked so far. Cells may extend outside * this area, so when we do incremental yanking, * we need to avoid copying any cells that were * already yanked on a previous pass. */ int plowYankHalo; /* Halo around each edge. If this halo extends * outside the area already yanked, or touches * its border, we yank more. */ /* Imports from the rest of this module */ extern Rect plowCellBbox; extern Transform plowYankTrans; extern Transform plowInverseTrans; extern int plowDirection; extern bool plowLabelsChanged; /* Dummy whose cu_def pointer is reset to point to the def being plowed */ extern CellUse *plowDummyUse; /* Forward declarations */ int plowYankUpdateCell(); int plowYankUpdatePaint(); int plowCheckLabel(); /* * ---------------------------------------------------------------------------- * * plowYankMore -- * * Yank more area from the original cell. This is a little tricky in * the case of subcells, because we don't always update plowYankedArea * to enclose all subcell bounding boxes. This means that a subcell * may appear in more than a single yank area. To combat this, we do * not actually copy a cell if it already has been copied (which we * determine based on the use-id). * * The rectangle causing us to yank more area is 'area'. To try to * make the cost of yanking stay roughly linear in the area plowed, * we try to make the area grow by the same factor each time we yank * more. * * We don't do anything if we don't have to yank any more area; this * is the case if 'area' plus its halo lies entirely inside plowYankedArea. * * Results: * TRUE if we yanked more, FALSE if not. * * Side effects: * May yank more area from the original cell. * The spare cell (plowSpareDef) is always left cleared. * * ---------------------------------------------------------------------------- */ bool plowYankMore(area, halo, back) Rect *area; int halo; /* Distance to right, top, bottom of area that * must have been yanked. */ int back; /* Distance to left that must have been * yanked. */ { Rect grownR, newArea, oldArea; SearchContext scx; int xsize, ysize; CellDef tmpDef; int pNum; grownR.r_xbot = area->r_xbot - back; grownR.r_xtop = area->r_xtop + halo; grownR.r_ybot = area->r_ybot - halo; grownR.r_ytop = area->r_ytop + halo; GEOCLIP(&grownR, &plowCellBbox); /* Don't have to yank if entirely within the yanked area */ if (GEO_SURROUND_STRONG(&plowYankedArea, &grownR)) return (FALSE); /* Figure out the additional area to yank */ xsize = (plowYankedArea.r_xtop - plowYankedArea.r_xbot) >> 1; ysize = (plowYankedArea.r_ytop - plowYankedArea.r_ybot) >> 1; newArea = plowYankedArea; if (grownR.r_xbot <= plowYankedArea.r_xbot) newArea.r_xbot -= xsize >> 1; if (grownR.r_xtop >= plowYankedArea.r_xtop) newArea.r_xtop += xsize; if (grownR.r_ybot <= plowYankedArea.r_ybot) newArea.r_ybot -= ysize; if (grownR.r_ytop >= plowYankedArea.r_ytop) newArea.r_ytop += ysize; (void) GeoInclude(&grownR, &newArea); /* Clip to the cell bbox; if inside the existing yanked area, we're done */ GEOCLIP(&newArea, &plowCellBbox); if (GEO_SURROUND(&plowYankedArea, &newArea)) return (FALSE); oldArea = plowYankedArea; plowYankedArea = newArea; /* * Work to do. * Right now, we use a very simple approach: * * Yank the complete area into a separate set of tile planes. * Use the original set to update cu_clients and trailing tile * coordinates. * * Run without undo since we're mucking with yank cells. */ /* Yank the larger area into the spare cell */ UndoDisable(); scx.scx_use = plowDummyUse; scx.scx_trans = plowYankTrans; GeoTransRect(&plowInverseTrans, &plowYankedArea, &scx.scx_area); (void) DBCellCopyPaint(&scx, &DBAllButSpaceAndDRCBits, 0, plowSpareUse); (void) DBCellCopyCells(&scx, plowSpareUse, (Rect *) NULL); /* * Update cell positions in the new cell. * The following loop executes as many times as there * are cells in the original yank def; each cell gets * deleted and replaces its counterpart in the new yank * buffer. */ while (DBCellEnum(plowYankDef, plowYankUpdateCell, (ClientData) NULL)) /* Nothing */; /* * Update paint edges in the new cell. * We extend the search one lambda to the right to catch the * trailing edges of space tiles in the original yank buffer. */ oldArea.r_xtop++; for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) { (void) DBSrPaintArea((Tile *) NULL, plowYankDef->cd_planes[pNum], &oldArea, &DBAllTypeBits, plowYankUpdatePaint, (ClientData) pNum); } /* Switch the yank cell and the spare cell */ DBCellClearDef(plowYankDef); DBCellSetAvail(plowYankDef); DBCellCopyDefBody(plowYankDef, &tmpDef); DBCellCopyDefBody(plowSpareDef, plowYankDef); DBCellCopyDefBody(&tmpDef, plowSpareDef); UndoEnable(); return (TRUE); } /* * ---------------------------------------------------------------------------- * * plowYankUpdateCell -- * * Called for each cell in the old yank buffer. We search the * new yank buffer for the corresponding cell (same child def, * same use-id) delete the cell from the new yank buffer, and * replace it with the cell from the old one. * * We have to do this, rather than simply updating the deltas * in the new yank buffer, because edges in the queue may have * pointers to the uses from the old yank buffer. * * Results: * Always returns 1. * * Side effects: * Moves its argument cell over to plowSpareUse, replacing * the cell by the same name in plowSpareUse. * * ---------------------------------------------------------------------------- */ int plowYankUpdateCell(yankChildUse) CellUse *yankChildUse; /* Use in the yank cell */ { CellUse *spareChildUse; ClientData savedelta; savedelta = yankChildUse->cu_client; for (spareChildUse = yankChildUse->cu_def->cd_parents; spareChildUse; spareChildUse = spareChildUse->cu_nextuse) { if (spareChildUse->cu_parent == plowSpareDef && strcmp(spareChildUse->cu_id, yankChildUse->cu_id) == 0) { /* Delete the use from the new yank def */ DBDeleteCell(spareChildUse); /* Move the use from the old yank def to the new yank def */ DBDeleteCell(yankChildUse); DBPlaceCell(yankChildUse, plowSpareDef); /* Restore the delta since DBPlaceCell re-initializes it to 0 */ yankChildUse->cu_client = savedelta; /* Return 1 so TiSrArea doesn't bomb */ return (1); } } TxError("Couldn't find use %s in spare yank buffer\n", yankChildUse->cu_id); return (0); } /* * ---------------------------------------------------------------------------- * * plowYankUpdatePaint -- * * Called for each paint tile in the old yank buffer. We search the new * yank buffer for the corresponding tile. The new yank buffer's tile * may need to be clipped at its top and bottom if it is bigger than the * old yank buffer's tile. We set the TRAILING coordinate of the clipped * tile to that of the old yank buffer's tile. * * Results: * Always returns 0. * * Side effects: * May update the TRAILING coordinate of the corresponding tile * in plowSpareUse. * * ---------------------------------------------------------------------------- */ int plowYankUpdatePaint(yankTp, pNum) Tile *yankTp; int pNum; { Tile *spareTp; Point startPoint; Plane *plane; /* * Walk down the inside of the LHS of yankTp, finding all tiles * spareTp along that LHS and updating their client values. * There may be more than one spareTp along this edge, owing * to additional material added outside the original yank buffer * that caused re-merging into maximal horizontal strips. */ startPoint.p_x = LEFT(yankTp); startPoint.p_y = TOP(yankTp) - 1; plane = plowSpareDef->cd_planes[pNum]; spareTp = (Tile *) NULL; do { spareTp = TiSrPoint(spareTp, plane, &startPoint); /* * Only update if both tiles are of the same type. * This should always be true except when yankTp is a space tile * from the RHS of the original yank buffer that lies over a * non-space tile in the new yank buffer (spare). */ if (TiGetTypeExact(spareTp) == TiGetTypeExact(yankTp)) { if (TOP(spareTp) > TOP(yankTp)) (void) plowSplitY(spareTp, TOP(yankTp)); if (BOTTOM(spareTp) < BOTTOM(yankTp)) spareTp = plowSplitY(spareTp, BOTTOM(yankTp)); spareTp->ti_client = yankTp->ti_client; } startPoint.p_y = BOTTOM(spareTp) - 1; } while (startPoint.p_y >= BOTTOM(yankTp)); return (0); } /* * ---------------------------------------------------------------------------- * * plowUpdateLabels -- * * For each label in the original cell that is attached to geometry that * has moved in the plow yank cell, determine how far the label must move * and move it. * * Results: * None. * * Side effects: * Moves labels. * Sets plowLabelsChanged if we actually move a label. * * ---------------------------------------------------------------------------- */ struct labelUpdate { Rect lu_rect; /* Label itself */ int lu_adjust; /* How much to adjust it rightwards */ }; void plowUpdateLabels(yankDef, origDef, origArea) CellDef *yankDef; /* Def containing plowed paint */ CellDef *origDef; /* Original def whose labels are to be adjusted */ Rect *origArea; /* Area in original def that was modified */ { extern void DBUndoPutLabel(), DBUndoEraseLabel(); Rect yankSearch; TileTypeBitMask typeBits; struct labelUpdate lu; Label *origLab; int pNum; for (origLab = origDef->cd_labels; origLab; origLab = origLab->lab_next) { /* Labels attached to space don't ever move */ if (origLab->lab_type == TT_SPACE) continue; /* Labels outside the area changed don't move either */ if (!GEO_TOUCH(&origLab->lab_rect, origArea)) continue; /* * If any of the tiles to which this label "belongs" * moved far enough to touch or pass this label, drag * it along with them. */ pNum = DBPlane(origLab->lab_type); GeoTransRect(&plowYankTrans, &origLab->lab_rect, &lu.lu_rect); lu.lu_adjust = 0; yankSearch = lu.lu_rect; yankSearch.r_xbot--, yankSearch.r_xtop++; yankSearch.r_ybot--, yankSearch.r_ytop++; TTMaskSetOnlyType(&typeBits, origLab->lab_type); (void) DBSrPaintArea((Tile *) NULL, yankDef->cd_planes[pNum], &yankSearch, &typeBits, plowCheckLabel, (ClientData) &lu); if (lu.lu_adjust) { lu.lu_rect.r_xbot += lu.lu_adjust; lu.lu_rect.r_xtop += lu.lu_adjust; DBUndoEraseLabel(origDef, origLab); GeoTransRect(&plowInverseTrans, &lu.lu_rect, &origLab->lab_rect); DBUndoPutLabel(origDef, origLab); plowLabelsChanged = TRUE; } } } int plowCheckLabel(tile, lu) Tile *tile; struct labelUpdate *lu; { int adjust; /* * If the RHS of the label touches the RHS of this tile, move * the label with the leading edge; otherwise, move it with the * trailing edge. */ if (lu->lu_rect.r_xtop == RIGHT(tile)) adjust = LEADING(tile) - lu->lu_rect.r_xtop; else adjust = TRAILING(tile) - lu->lu_rect.r_xbot; if (adjust > lu->lu_adjust) lu->lu_adjust = adjust; return (0); } /* * ---------------------------------------------------------------------------- * * plowUpdateCell -- * * Called by DBCellEnum(). * Update the positions of each cell moved by plowing. The cu_client * fields of various cells in the cell plane of yankDef have been updated * as a result of plowing. For each cell with a non-zero cu_client, we * find the corresponding one in the parent (the use with the same * instance-id), rip it up, and replace it. * * Results: * Returns 0 always. * * Side effects: * Sets plowLabelsChanged if we have to move a cell. * May cause the cell corresponding to 'use' to be re-placed * in the original def, 'origDef'. * * ---------------------------------------------------------------------------- */ int plowUpdateCell(use, origDef) CellUse *use; /* Use from yank def; corresponding use in 'def' will * be moved if use->cu_client is non-zero. */ CellDef *origDef; /* Original def whose cells are to be adjusted based * on the corresponding cells in yankDef. */ { CellUse *origUse; Transform newTrans; int x, y; if (use->cu_client == (ClientData)CLIENTDEFAULT || use->cu_client == (ClientData)0) return (0); /* * Find the corresponding use in the original parent. * This will be a use of the same def with the same * instance identifier; if we can't find it, something * very strange is going on. */ for (origUse = use->cu_def->cd_parents; origUse; origUse = origUse->cu_nextuse) { if (origUse->cu_parent == plowDummyUse->cu_def && strcmp(origUse->cu_id, use->cu_id) == 0) break; } if (origUse == NULL) { TxError("Oops! Can't find cell use %s in parent\n", use->cu_id); return (0); } plowLabelsChanged = TRUE; /* Figure out how much to translate by based on the plowing direction */ x = y = 0; switch (plowDirection) { case GEO_NORTH: y = (int)use->cu_client; break; case GEO_SOUTH: y = -(int)use->cu_client; break; case GEO_WEST: x = -(int)use->cu_client; break; case GEO_EAST: x = (int)use->cu_client; break; } GeoTranslateTrans(&origUse->cu_transform, x, y, &newTrans); DBDeleteCell(origUse); DBWAreaChanged(origDef, &origUse->cu_bbox, DBW_ALLWINDOWS, (TileTypeBitMask *) NULL); DBSetTrans(origUse, &newTrans); DBPlaceCell(origUse, origDef); DBWAreaChanged(origDef, &origUse->cu_bbox, DBW_ALLWINDOWS, (TileTypeBitMask *) NULL); return (0); } /* * ---------------------------------------------------------------------------- * * plowUpdatePaintTile -- * * Copy back a tile from the plowed planes into the orignal cell def. * Instead of using the normal left and right coordinates of this tile, * however, we use the leading/trailing edges. * * Results: * Always return 0 to keep the search alive. * * Side effects: * Paints a tile of the same type as 'tile' into the * original def, after first transforming by the inverse * transform of that used to rotate the original def * into the plowing yank buffer. * * ---------------------------------------------------------------------------- */ int plowUpdatePaintTile(tile, ui) Tile *tile; /* Tile in yanked, plowed def */ PaintUndoInfo *ui; /* Identifies original cell and plane being searched */ { Rect r, rtrans; TileType type = TiGetTypeExact(tile); r.r_ybot = BOTTOM(tile); r.r_ytop = TOP(tile); r.r_xbot = TRAILING(tile); r.r_xtop = LEADING(tile); GeoTransRect(&plowInverseTrans, &r, &rtrans); DBPaintPlane(ui->pu_def->cd_planes[DBPlane(type)], &rtrans, DBWriteResultTbl[type], ui); return (0); } magic-8.0.210/plow/PlowWidth.c0000644000175000001440000004241210751423606014527 0ustar timusers/* * PlowWidth.c -- * * Plowing. * Determine the true minimum width of a piece of geometry. * * ********************************************************************* * * 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/plow/PlowWidth.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "plow/plowInt.h" struct wclip { Edge *wc_edge; /* Initial edge */ Rect wc_area; /* Area being clipped repeatedly */ }; int plowInitWidthFunc(), plowWidthFunc(); int plowInitWidthBackFunc(), plowWidthBackFunc(); #ifdef COUNTWIDTHCALLS int plowWidthNumCalls = 0; int plowWidthNumChoices = 0; #endif /* COUNTWIDTHCALLS */ /* * ---------------------------------------------------------------------------- * * plowFindWidth -- * * Find the minimum width of material consisting of those types in the * TileTypeBitMask 'types', starting the search from the Edge 'edge'. * * Results: * Returns the minimum width. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ int plowFindWidth(edge, types, bbox, prect) Edge *edge; /* Edge along the LHS of this material */ TileTypeBitMask types; /* Types whose width is being computed. Note * that this set is passed by value. */ Rect *bbox; /* Bounding box of the cell */ Rect *prect; /* (Debugging only): if this is non-NULL, * the rectangle it points to is filled * in with the rectangle found by this * algorithm to be the largest containing * the edge 'edge' with only types in the * set 'types'. */ { Plane *plane = plowYankDef->cd_planes[edge->e_pNum]; TileTypeBitMask ctypes; struct wclip wc; int x, y; TTMaskCom2(&ctypes, &types); #ifdef COUNTWIDTHCALLS plowWidthNumCalls++; #endif /* COUNTWIDTHCALLS */ /* * Start with wc.wc_area extending from the edge rightward to the * cell boundary. Search right to find some tile (not necessarily * the leftmost) that is not one of 'types'. This provides an * upper bound on the minimum width, which we use to set wa.wa_area * for the next loop. */ wc.wc_edge = edge; wc.wc_area.r_xtop = bbox->r_xtop + 1; wc.wc_area.r_xbot = edge->e_x; wc.wc_area.r_ybot = edge->e_ybot; wc.wc_area.r_ytop = edge->e_ytop; #ifdef DEBUGWIDTH TxPrintf("Initial area: X: %d .. %d Y: %d .. %d\n", wc.wc_area.r_xbot, wc.wc_area.r_xtop, wc.wc_area.r_ybot, wc.wc_area.r_ytop); #endif /* DEBUGWIDTH */ (void) DBSrPaintArea((Tile *) NULL, plane, &wc.wc_area, &ctypes, plowInitWidthFunc, (ClientData) &wc); #ifdef DEBUGWIDTH TxPrintf("After first search, area: X: %d .. %d Y: %d .. %d\n", wc.wc_area.r_xbot, wc.wc_area.r_xtop, wc.wc_area.r_ybot, wc.wc_area.r_ytop); #endif /* DEBUGWIDTH */ /* * Repeatedly search wc.wc_area for tiles whose * types are not in the set 'types'. Each time we find such a * tile, we clip wc.wc_area so it still contains the original * edge in its entirety, but excludes the offending tile. * Continue until either the edge is degenerate (shouldn't * happen!) or everything in wc_area is of types in 'types'. */ while (DBSrPaintArea((Tile *) NULL, plane, &wc.wc_area, &ctypes, plowWidthFunc, (ClientData) &wc)) { #ifdef DEBUGWIDTH TxPrintf("Next area: X: %d .. %d Y: %d .. %d\n", wc.wc_area.r_xbot, wc.wc_area.r_xtop, wc.wc_area.r_ybot, wc.wc_area.r_ytop); #endif /* DEBUGWIDTH */ if (wc.wc_area.r_xbot == wc.wc_area.r_xtop) break; } if (prect) *prect = wc.wc_area; x = wc.wc_area.r_xtop - wc.wc_area.r_xbot; y = wc.wc_area.r_ytop - wc.wc_area.r_ybot; #ifdef DEBUGWIDTH TxPrintf("Width = %d\n", MIN(x, y)); #endif /* DEBUGWIDTH */ return (MIN(x, y)); } /* * ---------------------------------------------------------------------------- * * plowInitWidthFunc -- * * Called by area search to obtain an initial estimate of the minimum * width of a wire. The argument 'tile' will be of a type not included * in the set 'types' passed to plowFindWidth() above. * * We set our upper bound on minimum width to be the distance between * wc->wc_edge and the LHS of tile. This means that the search rectangle * wc->wc_area has to be modified as follows: * * wc_area.r_xtop will be (upper bound) to the right of wc_edge * wc_area.r_ybot will be (upper bound) below the top of wc_edge * wc_area.r_ytop will be (upper bound) above the bottom of wc_edge * * Results: * Returns 1 always. * * Side effects: * Modifies wc->wc_area as described above. * * ---------------------------------------------------------------------------- */ int plowInitWidthFunc(tile, wc) Tile *tile; /* Tile whose type is not among the types * passed to plowFindWidth(), whose LHS will * provide the right-hand boundary. */ struct wclip *wc; /* Contains original edge and area to clip */ { Edge *edge = wc->wc_edge; int upperBound = LEFT(tile) - edge->e_x; #ifdef DEBUGWIDTH TxPrintf("Tile type = %s, edgeHeight = %d, upperBound = %d\n", DBTypeLongName(TiGetTypeExact(tile)), edge->e_ytop-edge->e_ybot, upperBound); #endif /* DEBUGWIDTH */ wc->wc_area.r_ytop = MAX(edge->e_ybot + upperBound, edge->e_ytop); wc->wc_area.r_ybot = MIN(edge->e_ytop - upperBound, edge->e_ybot); wc->wc_area.r_xtop = LEFT(tile); return (1); } /* * ---------------------------------------------------------------------------- * * plowWidthFunc -- * * Called by area search to update an estimate of the minimum width of * a wire. The argument 'tile' will be of a type not included in the * set 'types' passed to plowFindWidth() above. * * The basic idea is to modify wc->wc_area so it does not contain the * area of 'tile', but still contains the entire edge wc->wc_edge. * When 'tile' overlaps wc->wc_edge in Y, this can only be achieved * by throwing away everything to the right of LEFT(tile). When 'tile' * doesn't overlap wc->wc_edge in Y, there are generally two choices: * clip away the right-hand side of wc_area, or clip away the top (or * bottom). To avoid a combinatoric explosion, we act greedily and * clip in such a way as to keep the largest dimension largest. * * Results: * Returns 1 always. * * Side effects: * Modifies wc->wc_area as described above. * * ---------------------------------------------------------------------------- */ int plowWidthFunc(tile, wc) Tile *tile; /* Tile whose type is not among the types * passed to plowFindWidth(), which will be * clipped out of the area wc->wc_area in * such a way that the original edge will * remain a part of wc->wc_area. */ struct wclip *wc; /* Contains original edge and area to clip */ { Edge *edge = wc->wc_edge; int xw, yw; int yt, yb; /* * If the tile overlaps the edge in Y, we have to clip the * RHS of the area. If clipping the RHS makes X the new * smallest dimension, clip Y appropriately. */ xw = LEFT(tile) - wc->wc_area.r_xbot; if (BOTTOM(tile) < edge->e_ytop && TOP(tile) > edge->e_ybot) { wc->wc_area.r_xtop = LEFT(tile); goto clipvert; } /* * If the tile is above the edge in Y, consider both * alternatives (clipping the top, and clipping the * right), choosing whichever one leaves us with the * larger minimum width. This may not always work, * but is simple. */ #ifdef COUNTWIDTHCALLS plowWidthNumChoices++; #endif /* COUNTWIDTHCALLS */ if (BOTTOM(tile) >= edge->e_ytop) { yw = BOTTOM(tile) - wc->wc_area.r_ybot; if (xw >= yw) { wc->wc_area.r_xtop = LEFT(tile); goto clipvert; } else { wc->wc_area.r_ytop = BOTTOM(tile); goto clipright; } } /* * The tile is below the edge in Y, so consider both * alternatives (clipping the bottom, and clipping the * right), choosing whichever one leaves us with the * larger minimum width. This may not always work, * but is simple. */ yw = wc->wc_area.r_ytop - TOP(tile); if (xw >= yw) { wc->wc_area.r_xtop = LEFT(tile); goto clipvert; } else { wc->wc_area.r_ybot = TOP(tile); goto clipright; } clipvert: yt = MIN(edge->e_ybot + xw, wc->wc_area.r_ytop); yb = MAX(edge->e_ytop - xw, wc->wc_area.r_ybot); if (yt > wc->wc_edge->e_ytop) wc->wc_area.r_ytop = yt; if (yb < wc->wc_edge->e_ybot) wc->wc_area.r_ybot = yb; return (1); clipright: yw = wc->wc_area.r_ytop - wc->wc_area.r_ybot; xw = wc->wc_area.r_xtop - wc->wc_area.r_xbot; if (yw < xw) wc->wc_area.r_xtop = wc->wc_area.r_xbot + yw; return (1); } /* * ---------------------------------------------------------------------------- * * plowFindWidthBack -- * * Find the minimum width of material consisting of those types in the * TileTypeBitMask 'types', starting the search from the Edge 'edge', * but searching to the left instead of to the right. * * Results: * Returns the minimum width. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ int plowFindWidthBack(edge, types, bbox, prect) Edge *edge; /* Edge along the RHS of this material */ TileTypeBitMask types; /* Types whose width is being computed. Note * that this set is passed by value. */ Rect *bbox; /* Bounding box of the cell */ Rect *prect; /* (Debugging only): if this is non-NULL, * the rectangle it points to is filled * in with the rectangle found by this * algorithm to be the largest containing * the edge 'edge' with only types in the * set 'types'. */ { Plane *plane = plowYankDef->cd_planes[edge->e_pNum]; TileTypeBitMask ctypes; struct wclip wc; int x, y; TTMaskCom2(&ctypes, &types); /* * Start with wc.wc_area extending from the edge rightward to the * cell boundary. Search left to find some tile (not necessarily * the rightmost) that is not one of 'types'. This provides an * upper bound on the minimum width, which we use to set wa.wa_area * for the next loop. */ wc.wc_edge = edge; wc.wc_area.r_xtop = edge->e_x; wc.wc_area.r_xbot = bbox->r_xbot - 1; wc.wc_area.r_ybot = edge->e_ybot; wc.wc_area.r_ytop = edge->e_ytop; #ifdef DEBUGWIDTH TxPrintf("Initial area: X: %d .. %d Y: %d .. %d\n", wc.wc_area.r_xbot, wc.wc_area.r_xtop, wc.wc_area.r_ybot, wc.wc_area.r_ytop); #endif /* DEBUGWIDTH */ (void) DBSrPaintArea((Tile *) NULL, plane, &wc.wc_area, &ctypes, plowInitWidthBackFunc, (ClientData) &wc); #ifdef DEBUGWIDTH TxPrintf("After first search, area: X: %d .. %d Y: %d .. %d\n", wc.wc_area.r_xbot, wc.wc_area.r_xtop, wc.wc_area.r_ybot, wc.wc_area.r_ytop); #endif /* DEBUGWIDTH */ /* * Repeatedly search wc.wc_area for tiles whose * types are not in the set 'types'. Each time we find such a * tile, we clip wc.wc_area so it still contains the original * edge in its entirety, but excludes the offending tile. * Continue until either the edge is degenerate (shouldn't * happen!) or everything in wc_area is of types in 'types'. */ while (DBSrPaintArea((Tile *) NULL, plane, &wc.wc_area, &ctypes, plowWidthBackFunc, (ClientData) &wc)) { #ifdef DEBUGWIDTH TxPrintf("Next area: X: %d .. %d Y: %d .. %d\n", wc.wc_area.r_xbot, wc.wc_area.r_xtop, wc.wc_area.r_ybot, wc.wc_area.r_ytop); #endif /* DEBUGWIDTH */ if (wc.wc_area.r_xbot == wc.wc_area.r_xtop) break; } if (prect) *prect = wc.wc_area; x = wc.wc_area.r_xtop - wc.wc_area.r_xbot; y = wc.wc_area.r_ytop - wc.wc_area.r_ybot; #ifdef DEBUGWIDTH TxPrintf("Width = %d\n", MIN(x, y)); #endif /* DEBUGWIDTH */ return (MIN(x, y)); } /* * ---------------------------------------------------------------------------- * * plowInitWidthBackFunc -- * * Called by area search to obtain an initial estimate of the minimum * width of a wire. The argument 'tile' will be of a type not included * in the set 'types' passed to plowFindWidth() above. * * We set our upper bound on minimum width to be the distance between * wc->wc_edge and the RHS of tile. This means that the search rectangle * wc->wc_area has to be modified as follows: * * wc_area.r_xbot will be (upper bound) to the left of wc_edge * wc_area.r_ybot will be (upper bound) below the top of wc_edge * wc_area.r_ytop will be (upper bound) above the bottom of wc_edge * * Results: * Returns 1 always. * * Side effects: * Modifies wc->wc_area as described above. * * ---------------------------------------------------------------------------- */ int plowInitWidthBackFunc(tile, wc) Tile *tile; /* Tile whose type is not among the types * passed to plowFindWidthBack(), whose RHS will * provide the left-hand boundary. */ struct wclip *wc; /* Contains original edge and area to clip */ { Edge *edge = wc->wc_edge; int upperBound = edge->e_x - RIGHT(tile); #ifdef DEBUGWIDTH TxPrintf("Tile type = %s, edgeHeight = %d, upperBound = %d\n", DBTypeLongName(TiGetTypeExact(tile)), edge->e_ytop-edge->e_ybot, upperBound); #endif /* DEBUGWIDTH */ wc->wc_area.r_ytop = MAX(edge->e_ybot + upperBound, edge->e_ytop); wc->wc_area.r_ybot = MIN(edge->e_ytop - upperBound, edge->e_ybot); wc->wc_area.r_xbot = RIGHT(tile); return (1); } /* * ---------------------------------------------------------------------------- * * plowWidthBackFunc -- * * Called by area search to update an estimate of the minimum width of * a wire. The argument 'tile' will be of a type not included in the * set 'types' passed to plowFindWidth() above. * * The basic idea is to modify wc->wc_area so it does not contain the * area of 'tile', but still contains the entire edge wc->wc_edge. * When 'tile' overlaps wc->wc_edge in Y, this can only be achieved * by throwing away everything to the left of RIGHT(tile). When 'tile' * doesn't overlap wc->wc_edge in Y, there are generally two choices: * clip away the left-hand side of wc_area, or clip away the top (or * bottom). To avoid a combinatoric explosion, we act greedily and * clip in such a way as to keep the largest dimension largest. * * Results: * Returns 1 always. * * Side effects: * Modifies wc->wc_area as described above. * * ---------------------------------------------------------------------------- */ int plowWidthBackFunc(tile, wc) Tile *tile; /* Tile whose type is not among the types * passed to plowFindWidth(), which will be * clipped out of the area wc->wc_area in * such a way that the original edge will * remain a part of wc->wc_area. */ struct wclip *wc; /* Contains original edge and area to clip */ { Edge *edge = wc->wc_edge; int xw, yw; int yt, yb; /* * If the tile overlaps the edge in Y, we have to clip the * LHS of the area. If clipping the LHS makes X the new * smallest dimension, clip Y appropriately. */ xw = wc->wc_area.r_xtop - RIGHT(tile); if (BOTTOM(tile) < edge->e_ytop && TOP(tile) > edge->e_ybot) { wc->wc_area.r_xbot = RIGHT(tile); goto clipvert; } /* * If the tile is above the edge in Y, consider both * alternatives (clipping the top, and clipping the * right), choosing whichever one leaves us with the * larger minimum width. This may not always work, * but is simple. */ if (BOTTOM(tile) >= edge->e_ytop) { yw = BOTTOM(tile) - wc->wc_area.r_ybot; if (xw >= yw) { wc->wc_area.r_xbot = RIGHT(tile); goto clipvert; } else { wc->wc_area.r_ytop = BOTTOM(tile); goto clipright; } } /* * The tile is below the edge in Y, so consider both * alternatives (clipping the bottom, and clipping the * right), choosing whichever one leaves us with the * larger minimum width. This may not always work, * but is simple. */ yw = wc->wc_area.r_ytop - TOP(tile); if (xw >= yw) { wc->wc_area.r_xbot = RIGHT(tile); goto clipvert; } else { wc->wc_area.r_ybot = TOP(tile); goto clipright; } clipvert: yt = MIN(edge->e_ybot + xw, wc->wc_area.r_ytop); yb = MAX(edge->e_ytop - xw, wc->wc_area.r_ybot); if (yt > wc->wc_edge->e_ytop) wc->wc_area.r_ytop = yt; if (yb < wc->wc_edge->e_ybot) wc->wc_area.r_ybot = yb; return (1); clipright: yw = wc->wc_area.r_ytop - wc->wc_area.r_ybot; xw = wc->wc_area.r_xtop - wc->wc_area.r_xbot; if (yw < xw) wc->wc_area.r_xbot = wc->wc_area.r_xtop - yw; return (1); } magic-8.0.210/plow/PlowCmd.c0000644000175000001440000002456410751423606014163 0ustar timusers/* * PlowCmd.c -- * * Commands for the plow module only. * * ********************************************************************* * * 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/plow/PlowCmd.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include #include #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 "plow/plow.h" #include "select/select.h" /* * ---------------------------------------------------------------------------- * * CmdPlow -- * * Implement the "plow" command: snowplow. * One side of the box forms the plow, which is swept through the layout * until it coincides with the opposite side of the box. The direction * depends on that specified by the user. * * Usage: * plow [options] * * Results: * None. * * Side effects: * Modifies the edit cell. * * ---------------------------------------------------------------------------- */ /* * The order of the following must be identical to that in * the table cmdPlowOption[] below. */ #define PLOWBOUND 0 #define PLOWHELP 1 #define PLOWHORIZON 2 #define PLOWJOGS 3 #define PLOWSELECTION 4 #define PLOWSTRAIGHTEN 5 #define PLOWNOBOUND 6 #define PLOWNOJOGS 7 #define PLOWNOSTRAIGHTEN 8 #define PLOWPLOW 9 /* Implicit when direction specified */ void CmdPlow(w, cmd) MagWindow *w; TxCommand *cmd; { int xdelta, ydelta, absX, absY; int option, dir, distance; char *layers, **msg; TileTypeBitMask mask; Rect rootBox, editBox, newBox; CellDef *rootDef, *editDef; Point rootPoint; MagWindow *window; Transform t; static char *cmdPlowOption[] = { "boundary set boundary around area plowing may affect", "help print this help information", "horizon n set the horizon for jog introduction to n lambda", "jogs reenable jog insertion (set horizon to 0)", "selection [direction [amount]]\n\ plow the selection", "straighten automatically straighten jogs after each plow", "noboundary remove boundary around area plowing may affect", "nojogs disable jog insertion (infinite jog horizon)", "nostraighten don't automatically straighten jogs after each plow", NULL }; if (cmd->tx_argc < 2) goto usage2; option = Lookup(cmd->tx_argv[1], cmdPlowOption); if (option == -1) { TxError("Ambiguous plowing option: \"%s\"\n", cmd->tx_argv[1]); goto usage2; } if (option < 0) { dir = GeoNameToPos(cmd->tx_argv[1], TRUE, FALSE); if (dir < 0) goto usage; dir = GeoTransPos(&RootToEditTransform, dir); option = PLOWPLOW; } switch (option) { case PLOWBOUND: case PLOWSELECTION: case PLOWNOBOUND: case PLOWPLOW: windCheckOnlyWindow(&w, DBWclientID); if (w == (MagWindow *) NULL) { TxError("Point to a window first\n"); return; } if (EditCellUse == (CellUse *) NULL) { TxError("There is no edit cell!\n"); return; } if (!ToolGetEditBox(&editBox) || !ToolGetBox(&rootDef, &rootBox)) return; editDef = EditCellUse->cu_def; break; } switch (option) { case PLOWHELP: TxPrintf("Plow commands have the form \"plow option\",\n"); TxPrintf("where option is one of:\n\n"); for (msg = &(cmdPlowOption[0]); *msg != NULL; msg++) { if (**msg == '*') continue; TxPrintf(" %s\n", *msg); } TxPrintf("\n"); TxPrintf("Option may also be any Manhattan direction, which\n"); TxPrintf("causes the plow to be moved in that direction.\n"); return; case PLOWBOUND: if (cmd->tx_argc != 2) { wrongNumArgs: TxError("Wrong number of arguments to %s option.\n", cmd->tx_argv[1]); TxError("Type \":plow help\" for help.\n"); return; } PlowSetBound(editDef, &editBox, rootDef, &rootBox); break; case PLOWHORIZON: if (cmd->tx_argc == 3) PlowJogHorizon = cmdParseCoord(w, cmd->tx_argv[2], TRUE, TRUE); else if (cmd->tx_argc != 2) goto wrongNumArgs; if (PlowJogHorizon == INFINITY) TxPrintf("Jog horizon set to infinity.\n"); else TxPrintf("Jog horizon set to %d units.\n", PlowJogHorizon); break; case PLOWSTRAIGHTEN: PlowDoStraighten = TRUE; TxPrintf("Jogs will be straightened after each plow.\n"); break; case PLOWNOBOUND: if (cmd->tx_argc != 2) goto wrongNumArgs; PlowClearBound(); break; case PLOWNOJOGS: if (cmd->tx_argc != 2) goto wrongNumArgs; PlowJogHorizon = INFINITY; TxPrintf("Jog insertion disabled.\n"); break; case PLOWJOGS: if (cmd->tx_argc != 2) goto wrongNumArgs; PlowJogHorizon = 0; TxPrintf("Jog insertion re-enabled (horizon 0).\n"); break; case PLOWNOSTRAIGHTEN: PlowDoStraighten = FALSE; TxPrintf("Jogs will not be straightened automatically.\n"); break; case PLOWPLOW: if (cmd->tx_argc > 3) goto wrongNumArgs; layers = cmd->tx_argc == 2 ? "*,l,subcell,space" : cmd->tx_argv[2]; if (!CmdParseLayers(layers, &mask)) break; if (Plow(editDef, &editBox, mask, dir)) break; TxPrintf("Reduced plow size to stay within the boundary.\n"); GeoTransRect(&EditToRootTransform, &editBox, &rootBox); ToolMoveBox(TOOL_BL, &rootBox.r_ll, FALSE, rootDef); ToolMoveCorner(TOOL_TR, &rootBox.r_ur, FALSE, rootDef); break; case PLOWSELECTION: if (cmd->tx_argc > 2) { dir = GeoNameToPos(cmd->tx_argv[2], TRUE, TRUE); if (dir < 0) return; if (cmd->tx_argc == 4) { switch (dir) { case GEO_EAST: case GEO_WEST: distance = cmdParseCoord(w, cmd->tx_argv[3], TRUE, TRUE); break; case GEO_NORTH: case GEO_SOUTH: distance = cmdParseCoord(w, cmd->tx_argv[3], TRUE, FALSE); break; } } else distance = 1; switch (dir) { case GEO_NORTH: xdelta = 0; ydelta = distance; break; case GEO_SOUTH: xdelta = 0; ydelta = -distance; break; case GEO_EAST: xdelta = distance; ydelta = 0; break; case GEO_WEST: xdelta = -distance; ydelta = 0; break; default: ASSERT(FALSE, "Bad direction in CmdPlow"); return; } } else { /* * Use the displacement between the box lower-left corner * and the point as the transform. */ if (rootDef != SelectRootDef) { TxError("\"plow selection\" uses the box lower-left\n"); TxError("corner as a place to pick up the selection\n"); TxError("for plowing, but the box isn't in a window\n"); TxError("containing the selection\n"); return; } window = ToolGetPoint(&rootPoint, (Rect *) NULL); if ((window == NULL) || (EditRootDef != ((CellUse *) window->w_surfaceID)->cu_def)) { TxError("\"plow selection\" uses the point as the\n"); TxError("place to plow the selection, but the point\n"); TxError("doesn't point to the edit cell.\n"); return; } xdelta = rootPoint.p_x - rootBox.r_xbot; ydelta = rootPoint.p_y - rootBox.r_ybot; if (xdelta < 0) absX = -xdelta; else absX = xdelta; if (ydelta < 0) absY = -ydelta; else absY = ydelta; if (absY <= absX) { ydelta = 0; distance = absX; dir = xdelta > 0 ? GEO_EAST : GEO_WEST; } else { xdelta = 0; distance = absY; dir = ydelta > 0 ? GEO_NORTH : GEO_SOUTH; } } if (!PlowSelection(editDef, &distance, dir)) { TxPrintf("Reduced distance to stay in the boundary.\n"); switch (dir) { case GEO_EAST: xdelta = distance; break; case GEO_NORTH: ydelta = distance; break; case GEO_WEST: xdelta = -distance; break; case GEO_SOUTH: ydelta = -distance; break; } } GeoTransTranslate(xdelta, ydelta, &GeoIdentityTransform, &t); GeoTransRect(&t, &rootBox, &newBox); DBWSetBox(rootDef, &newBox); SelectClear(); break; } return; usage: TxError("\"%s\" isn't a valid plow option.", cmd->tx_argv[1]); usage2: TxError(" Type \"plow help\" for help.\n"); return; } /* * ---------------------------------------------------------------------------- * * CmdStraighten -- * * Straighten jogs in an area by pulling in a particular direction. * * Results: * None. * * Side effects: * Modifies the geometry of the edit cell. * * ---------------------------------------------------------------------------- */ void CmdStraighten(w, cmd) MagWindow *w; TxCommand *cmd; { Rect editBox; int dir; windCheckOnlyWindow(&w, DBWclientID); if (w == (MagWindow *) NULL) { TxError("Point to a window first\n"); return; } if (cmd->tx_argc != 2) goto usage; dir = GeoNameToPos(cmd->tx_argv[1], TRUE, FALSE); if (dir < 0) goto usage; dir = GeoTransPos(&RootToEditTransform, dir); if (EditCellUse == (CellUse *) NULL) { TxError("There is no edit cell!\n"); return; } if (!ToolGetEditBox(&editBox)) { TxError("The box is not in a window over the edit cell.\n"); return; } PlowStraighten(EditCellUse->cu_def, &editBox, dir); return; usage: TxError("Usage: straighten manhattan-direction\n"); } /* * ---------------------------------------------------------------------------- * * CmdPlowTest -- * * Debugging of plowing. * * Usage: * *plow cmd [args] * * Results: * None. * * Side effects: * See comments in PlowTest() in plow/PlowTest.c for details. * * ---------------------------------------------------------------------------- */ void CmdPlowTest(w, cmd) MagWindow *w; TxCommand *cmd; { PlowTest(w, cmd); } magic-8.0.210/plow/PlowQueue.c0000644000175000001440000003720210751423606014535 0ustar timusers/* * PlowQueue.c -- * * Plowing. * Queue of edges to move. * * ********************************************************************* * * 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/plow/PlowQueue.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "debug/debug.h" #include "plow/plowInt.h" #include "utils/malloc.h" /* * The following describe the queue of edges to be moved. * The array plowBinArray is indexed by the initial X coordinate * of an edge (relative to plowBinXBase). Each element plowBinArray[n] * is a pointer to a list of Edges whose initial X coordinates are * plowBinXBase + n. * * There is an array for each plane in a CellDef. */ int plowNumBins; /* Number of horizontal bins */ int plowDistance; /* Distance the plow is moving */ int plowBinXBase; /* Left-hand coordinate of cell's bbox */ int plowNumEdges; /* Number of edges currently in queue */ Edge **plowBinArray[NP]; /* Array of bins for each X coordinate */ Edge **plowFirstBin[NP]; /* First bin that has any edges in it */ Edge **plowLastBin[NP]; /* Last bin that has any edges in it */ /* Debugging */ int plowTooFar; /* # times we reduced plow size */ /* * ---------------------------------------------------------------------------- * * plowQueueInit -- * * Initialize the queue of edges to be moved by plowing. * The argument 'bbox' is the bounding box of the cell * being plowed. * * Results: * None. * * Side effects: * Obvious. * * ---------------------------------------------------------------------------- */ void plowQueueInit(bbox, dist) Rect *bbox; /* Bounding box for the cell being plowed */ int dist; /* Distance the plow moves */ { Edge **pptr, **pend; int pNum; unsigned binArraySize; plowNumBins = bbox->r_xtop - bbox->r_xbot + 1; plowDistance = dist; plowBinXBase = bbox->r_xbot; plowNumEdges = 0; plowTooFar = 0; binArraySize = plowNumBins * sizeof (Edge *); for (pNum = 0; pNum < DBNumPlanes; pNum++) { /* Don't need planes for DRC, etc. */ if (pNum > 0 && pNum < PL_TECHDEPBASE) continue; plowBinArray[pNum] = (Edge **) mallocMagic(binArraySize); plowFirstBin[pNum] = (Edge **) NULL; plowLastBin[pNum] = (Edge **) NULL; pptr = plowBinArray[pNum]; pend = &pptr[plowNumBins]; while (pptr < pend) *pptr++ = (Edge *) NULL; } } /* * ---------------------------------------------------------------------------- * * plowQueueDone -- * * Free the memory allocated by plowQueueInit above. * * Results: * None. * * Side effects: * Frees memory. * * ---------------------------------------------------------------------------- */ void plowQueueDone() { int pNum; for (pNum = 0; pNum < DBNumPlanes; pNum++) { if (pNum == 0 || pNum >= PL_TECHDEPBASE) freeMagic((char *) plowBinArray[pNum]); } } /* * ---------------------------------------------------------------------------- * * plowQueueAdd -- * * Add an edge to the queue of those to be moved. * * Results: * Returns 0 always (so it can be used as a filter function). * * Side effects: * Adds edges to the queue. * * ---------------------------------------------------------------------------- */ #define SAMETYPE(e1, e2) ((e1)->e_ltype == (e2)->e_ltype \ && (e1)->e_rtype == (e2)->e_rtype) int plowQueueAdd(eadd) Edge *eadd; /* Edge added to queue. We assume that * e_ltype and e_rtype have been set to * the types on the LHS and RHS of this * edge, respectively. */ { extern CellDef *plowYankDef; extern int plowQueuedEdges; int xbin = eadd->e_x - plowBinXBase; Edge *enew, *eprev, *ep; Edge **pbin; int pNum; Rect addRect; ASSERT(eadd->e_ybot < eadd->e_ytop, "plowQueueAdd"); ASSERT(xbin < plowNumBins, "plowQueueAdd"); /* * Make sure we're not moving the edge too far. * This should only happen in the event of design * rule violations in the initial circuit, but we * keep track of the number of times it happened * for the sake of debugging. */ if (eadd->e_newx > eadd->e_x + plowDistance) { eadd->e_newx = eadd->e_x + plowDistance; plowTooFar++; } /* Display this edge if we're debugging */ plowQueuedEdges++; if (DebugIsSet(plowDebugID, plowDebAdd)) plowDebugEdge(eadd, plowCurrentRule, "add"); /* Which plane is this on? */ pNum = eadd->e_pNum; /* * If this is the first edge added to this bin, we may have to update * the first or last pointers. */ pbin = &plowBinArray[pNum][xbin]; if (*pbin == (Edge *) NULL) { if (plowFirstBin[pNum] == (Edge **) NULL) plowFirstBin[pNum] = plowLastBin[pNum] = pbin; else if (pbin < plowFirstBin[pNum]) plowFirstBin[pNum] = pbin; else if (pbin > plowLastBin[pNum]) plowLastBin[pNum] = pbin; goto prepend; } /* * If a cell, see if there is already an edge ep in the queue * for this cell. If so, update ep->e_newx to the larger of * eadd->e_newx and ep->e_newx and we're done. Otherwise, * just prepend this edge to the queue. */ if (pNum == 0) { ASSERT(eadd->e_use != (CellUse *) NULL, "plowQueueAdd"); for (ep = *pbin; ep; ep = ep->e_next) { if (ep->e_use == eadd->e_use) { if (eadd->e_newx > ep->e_newx) ep->e_newx = eadd->e_newx; goto done; } } goto prepend; } /* * There was one or more edge in this bin. * Edges are sorted on increasing e_ybot coordinate, so we can * stop when ep->e_ybot > eadd->e_ytop. * The edges are disjoint in Y. */ /* Skip all edges strictly below eadd */ for (ep = *pbin, eprev = (Edge *) NULL; ep && ep->e_ytop < eadd->e_ybot; eprev = ep, ep = ep->e_next) { /* Nothing */; } /* * Keep going until we find an edge above or touching eadd's top, * or we run out of edges in this bin. We keep addRect updated * to the unprocessed portion of eadd->e_rect. Initially, this * rectangle is non-degenerate since eadd->e_ybot < eadd->e_ytop. * THE FOLLOWING LOOP IS HAIRY. */ addRect = eadd->e_rect; for ( ; ep && ep->e_ybot < addRect.r_ytop; eprev = ep, ep = ep->e_next) { /* * Done when we've processed all of addRect. * Since we may have changed eprev->e_newx, we * want to check to see if it can merge with * the new ep. */ if (addRect.r_ybot >= addRect.r_ytop) goto mergeFinal; /* * ep->e_ybot < addRect.r_ytop * addRect.r_ybot <= ep->e_ytop * addRect.r_ybot < addRect.r_ytop * * We know that addRect is non-degenerate and either overlaps * ep or touches its top. Whatever portion of addRect that lies * below ep we KNOW does not overlap any other edges. */ if (!SAMETYPE(ep, eadd)) { /* * If not the same type of edge, then they can't overlap. * Handle creating the new edge for addRect on the next iteration, * since we never merge up. */ ASSERT(addRect.r_ybot == ep->e_ytop, "plowQueueAdd"); continue; } /* If moving by the same amount as ep, absorb eadd into ep */ if (ep->e_newx == eadd->e_newx) { if (addRect.r_ybot < ep->e_ybot) ep->e_ybot = addRect.r_ybot; goto mergeDown; } /* Remember, ep->e_ybot < addRect.r_ytop */ if (addRect.r_ybot < ep->e_ybot) { /* * Clip the portion of addRect below ep (we know * that there is a non-degenerate part of addRect * above ep by the comment above). * Try to merge the lower part of addRect with eprev; * otherwise, create a new edge for this portion. */ if (eprev && SAMETYPE(eadd, eprev) && eprev->e_newx == eadd->e_newx && eprev->e_ytop == addRect.r_ybot) { /* Merge with eprev */ eprev->e_ytop = ep->e_ybot; } else { /* Create a new edge, replacing eprev */ enew = (Edge *) mallocMagic((unsigned) (sizeof (Edge))); *enew = *ep; enew->e_ybot = addRect.r_ybot; enew->e_ytop = ep->e_ybot; enew->e_newx = eadd->e_newx; if (eprev) eprev->e_next = enew; else *pbin = enew; enew->e_next = ep; eprev = enew; plowNumEdges++; } addRect.r_ybot = ep->e_ybot; } else if (ep->e_ybot < addRect.r_ybot) { /* Done except for merging if ep and addRect only touch */ if (ep->e_ytop == addRect.r_ybot) goto mergeDown; /* * Clip the portion of ep below addRect. * The new edge becomes eprev. */ enew = (Edge *) mallocMagic((unsigned) (sizeof (Edge))); *enew = *ep; enew->e_ytop = ep->e_ybot = addRect.r_ybot; enew->e_next = ep; if (eprev) eprev->e_next = enew; else *pbin = enew; eprev = enew; plowNumEdges++; } /* * At this point, addRect.r_ybot == ep->e_ybot, and * addRect.r_ytop > ep->e_ybot. Clip the portion of * ep above addRect. */ if (ep->e_ytop > addRect.r_ytop) { enew = (Edge *) mallocMagic((unsigned) (sizeof (Edge))); *enew = *ep; enew->e_ybot = ep->e_ytop = addRect.r_ytop; enew->e_next = ep->e_next; ep->e_next = enew; plowNumEdges++; } /* * Update the portion of the original ep that * was overlapped by addRect. */ ep->e_newx = MAX(ep->e_newx, eadd->e_newx); /* * Try to merge ep with eprev. * If successful, eprev->e_ytop gets updated, ep gets * freed, and we leave ep pointing to eprev. */ mergeDown: addRect.r_ybot = ep->e_ytop; if (eprev && SAMETYPE(ep, eprev) && eprev->e_newx == ep->e_newx && eprev->e_ytop == ep->e_ybot) { eprev->e_ytop = ep->e_ytop; eprev->e_next = ep->e_next; freeMagic((char *) ep); ep = eprev; plowNumEdges--; } /* NOTE: we switched ep above if we merged with eprev */ } /* * Something may be left of addRect. * Try to merge with eprev if possible; otherwise, allocate * a new edge and make this the new eprev. */ if (addRect.r_ybot < addRect.r_ytop) { if (eprev && SAMETYPE(eprev, eadd) && eprev->e_newx == eadd->e_newx && eprev->e_ytop == addRect.r_ybot) { eprev->e_ytop = addRect.r_ytop; } else { enew = (Edge *) mallocMagic((unsigned) (sizeof (Edge))); *enew = *eadd; enew->e_ybot = addRect.r_ybot; if (eprev) eprev->e_next = enew; else *pbin = enew; enew->e_next = ep; eprev = enew; plowNumEdges++; } } mergeFinal: /* * If ep is non-NULL, it is above or touching the top of * eprev (either as extended in the first branch above, or * as newly allocated in the second). */ if (ep && SAMETYPE(ep, eprev) && ep->e_newx == eprev->e_newx && ep->e_ybot == eprev->e_ytop) { eprev->e_ytop = ep->e_ytop; eprev->e_next = ep->e_next; freeMagic((char *) ep); plowNumEdges--; } goto done; /* * Prepend eadd to the current bin. */ prepend: enew = (Edge *) mallocMagic((unsigned) (sizeof (Edge))); *enew = *eadd; enew->e_next = *pbin; *pbin = enew; plowNumEdges++; done: return (0); } /* * ---------------------------------------------------------------------------- * * plowQueueLeftmost -- * * Returns the leftmost edge from the queue. * * Results: * TRUE if an edge was filled in, FALSE otherwise. * * Side effects: * Removes an edge from the queue and deallocates it * after filling in the caller's Edge. * * ---------------------------------------------------------------------------- */ bool plowQueueLeftmost(edge) Edge *edge; { Edge *enew, **pp, **plast; int pNum; int pMin, xMin; if (plowNumEdges <= 0) return (FALSE); /* Find the leftmost edge in any of the planes */ xMin = INFINITY, pMin = -1; for (pNum = 0; pNum < DBNumPlanes; pNum++) if (pNum == 0 || pNum >= PL_TECHDEPBASE) if ((pp = plowFirstBin[pNum]) && (pp - plowBinArray[pNum]) < xMin) xMin = pp - plowBinArray[pMin = pNum]; pNum = pMin; ASSERT(pNum >= 0, "plowQueueLeftmost"); ASSERT(*plowFirstBin[pNum] != (Edge *) NULL, "plowQueueLeftmost"); plowNumEdges--; enew = *plowFirstBin[pNum]; *plowFirstBin[pNum] = enew->e_next; if (*plowFirstBin[pNum] == (Edge *) NULL) { /* * No more edges left in this bin, so we have to advance the bounds * pointer plowFirstBin[pNum]. */ pp = plowFirstBin[pNum]; plast = plowLastBin[pNum]; while (pp < plast && *pp == (Edge *) NULL) pp++; /* * If there are no more edges on this plane, set both * plowFirstBin[pNum] and plowLastBin[pNum] to NULL. */ if (*pp) plowFirstBin[pNum] = pp; else plowFirstBin[pNum] = plowLastBin[pNum] = (Edge **) NULL; } /* Display this edge if we're debugging */ if (DebugIsSet(plowDebugID, plowDebNext)) plowDebugEdge(enew, (RuleTableEntry *) NULL, "next"); /* Debugging */ ASSERT(enew->e_ytop > enew->e_ybot, "plowQueueLeftmost"); ASSERT(enew->e_newx >= enew->e_x, "plowQueueLeftmost"); /* Fill in the caller's edge */ *edge = *enew; freeMagic((char *) enew); return (TRUE); } /* * ---------------------------------------------------------------------------- * * plowQueueRightmost -- * * Returns the rightmost edge from the queue. * * Results: * TRUE if an edge was filled in, FALSE otherwise. * * Side effects: * Removes an edge from the queue and deallocates it * after filling in the caller's Edge. * * ---------------------------------------------------------------------------- */ bool plowQueueRightmost(edge) Edge *edge; { Edge *enew, **pp, **plast; int pNum; int pMax, xMax; if (plowNumEdges <= 0) return (FALSE); /* Find the rightmost edge in any of the planes */ xMax = MINFINITY, pMax = -1; for (pNum = 0; pNum < DBNumPlanes; pNum++) if (pNum == 0 || pNum >= PL_TECHDEPBASE) if ((pp = plowLastBin[pNum]) && (pp - plowBinArray[pNum]) > xMax) xMax = pp - plowBinArray[pMax = pNum]; pNum = pMax; ASSERT(pNum >= 0, "plowQueueRightmost"); ASSERT(*plowLastBin[pNum] != (Edge *) NULL, "plowQueueRightmost"); plowNumEdges--; enew = *plowLastBin[pNum]; *plowLastBin[pNum] = enew->e_next; if (*plowLastBin[pNum] == (Edge *) NULL) { /* * No more edges left in this bin, so we have to advance the bounds * pointer plowLastBin[pNum]. */ pp = plowLastBin[pNum]; plast = plowFirstBin[pNum]; while (pp > plast && *pp == (Edge *) NULL) pp--; /* * If there are no more edges on this plane, set both * plowFirstBin[pNum] and plowLastBin[pNum] to NULL. */ if (*pp) plowLastBin[pNum] = pp; else plowFirstBin[pNum] = plowLastBin[pNum] = (Edge **) NULL; } /* Display this edge if we're debugging */ if (DebugIsSet(plowDebugID, plowDebNext)) plowDebugEdge(enew, (RuleTableEntry *) NULL, "next"); /* Debugging */ ASSERT(enew->e_ytop > enew->e_ybot, "plowQueueRightmost"); ASSERT(enew->e_newx >= enew->e_x, "plowQueueRightmost"); /* Fill in the caller's edge */ *edge = *enew; freeMagic((char *) enew); return (TRUE); } magic-8.0.210/plow/PlowTest.c0000644000175000001440000005432410751423606014374 0ustar timusers/* * PlowTest.c -- * * Plowing. * Debugging and testing. * * ********************************************************************* * * 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/plow/PlowTest.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include "utils/magic.h" #include "utils/styles.h" #include "utils/utils.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "utils/undo.h" #include "database/database.h" #include "windows/windows.h" #include "graphics/graphics.h" #include "dbwind/dbwind.h" #include "utils/main.h" #include "commands/commands.h" #include "drc/drc.h" #include "debug/debug.h" #include "plow/plowInt.h" #include "textio/textio.h" #include "textio/txcommands.h" /* Forward declarations */ extern void plowShowShadow(); extern int plowShowOutline(); extern void plowTestJog(); extern void plowDebugMore(); /* Imports from PlowMain.c */ extern CellDef *plowYankDef; extern CellUse *plowDummyUse; /* Debugging flags */ ClientData plowDebugID; int plowDebAdd; int plowDebMove; int plowDebNext; int plowDebTime; int plowDebWidth; int plowDebJogs; int plowDebYankAll; /* Other debugging info */ bool plowWhenTop, plowWhenBot; Point plowWhenTopPoint, plowWhenBotPoint; /* Imports */ extern CellDef *plowSpareDef; /* * ---------------------------------------------------------------------------- * * PlowTest -- * * Real command interface for debugging plowing. * * Results: * None. * * Side effects: * See individual commands. * * ---------------------------------------------------------------------------- */ typedef enum { PC_HELP, PC_ERROR, PC_PLOW, PC_JOG, PC_RANDOM, PC_TECHSHOW, PC_OUTLINE, PC_LSHADOW, PC_SHADOW, PC_WIDTH, PC_LWIDTH, PC_SPLIT, PC_MERGEUP, PC_MERGEDOWN, PC_MOVE, PC_TRAIL, PC_PRINT, PC_WHENTOP, PC_WHENBOT, PC_SETD, PC_CLRD, PC_SHOWD } pCmd; struct { char *p_name; pCmd p_cmd; char *p_help; } plowCmds[] = { "clrdebug", PC_CLRD, "flags", "help", PC_HELP, "", "jogreduce", PC_JOG, "", "lwidth", PC_LWIDTH, "layers", "lshadow", PC_LSHADOW, "layers", "mergedown", PC_MERGEDOWN, "", "mergeup", PC_MERGEUP, "", "move", PC_MOVE, "", "outline", PC_OUTLINE, "direction layers", "plow", PC_PLOW, "direction [layers]", "print", PC_PRINT, "", "random", PC_RANDOM, "", "setdebug", PC_SETD, "flags", "shadow", PC_SHADOW, "layers", "showdebug", PC_SHOWD, "", "split", PC_SPLIT, "", "techshow", PC_TECHSHOW, "[file]", "trail", PC_TRAIL, "[value]", "whenbot", PC_WHENBOT, "[xbot ybot]", "whentop", PC_WHENTOP, "[xtop ytop]", "width", PC_WIDTH, "layers", 0, }; void PlowTest(w, cmd) MagWindow *w; TxCommand *cmd; { pCmd plowCmd, plowGetCommand(); Rect editArea, dummyRect, rootBox, area2; CellDef *def, *rootBoxDef, *saveDef; TileTypeBitMask okTypes; int dir, n, trail; Point editPoint; Plane *plane; Edge edge; Tile *tp; FILE *f; if (!ToolGetEditBox(&editArea) || !ToolGetBox(&rootBoxDef, &rootBox)) return; (void) CmdGetEditPoint(&editPoint, &dummyRect); if ((plowCmd = plowGetCommand(cmd)) == PC_ERROR) return; def = EditCellUse->cu_def; plane = def->cd_planes[PL_TECHDEPBASE]; switch (plowCmd) { case PC_HELP: TxPrintf("Usage: *plow cmd [args]\n"); TxPrintf("Valid plowing command are:\n"); for (n = 0; plowCmds[n].p_name; n++) TxPrintf("%-15s %s\n", plowCmds[n].p_name, plowCmds[n].p_help); break; case PC_RANDOM: PlowRandomTest(def); break; case PC_JOG: plowTestJog(def, &editArea); break; case PC_SETD: DebugSet(plowDebugID, cmd->tx_argc - 2, &cmd->tx_argv[2], TRUE); break; case PC_CLRD: DebugSet(plowDebugID, cmd->tx_argc - 2, &cmd->tx_argv[2], FALSE); break; case PC_SHOWD: DebugShow(plowDebugID); break; case PC_OUTLINE: if (cmd->tx_argc < 4) { TxError("Usage: *plow outline direction layers\n"); return; } dir = GeoNameToPos(cmd->tx_argv[2], TRUE, TRUE); if (dir != GEO_NORTH && dir != GEO_SOUTH) { TxError("Only legal starting directions are north or south\n"); return; } if (!CmdParseLayers(cmd->tx_argv[3], &okTypes)) return; (void) plowSrOutline(PL_TECHDEPBASE, &editArea.r_ll, okTypes, dir, GMASK_NORTH|GMASK_SOUTH|GMASK_EAST|GMASK_WEST, plowShowOutline, (ClientData) &editArea); break; case PC_PLOW: if (cmd->tx_argc < 3) { TxError("Usage: *plow plow direction [layers]\n"); return; } dir = GeoNameToPos(cmd->tx_argv[2], TRUE, TRUE); okTypes = DBAllTypeBits; if (cmd->tx_argc > 3 && !CmdParseLayers(cmd->tx_argv[3], &okTypes)) return; if (!Plow(def, &editArea, okTypes, dir)) { TxPrintf("Reduced plow size since we ran into the barrier.\n"); GeoTransRect(&EditToRootTransform, &editArea, &rootBox); ToolMoveBox(TOOL_BL, &rootBox.r_ll, FALSE, rootBoxDef); ToolMoveCorner(TOOL_TR, &rootBox.r_ur, FALSE, rootBoxDef); } break; case PC_LSHADOW: if (cmd->tx_argc < 3) { TxError("Usage: *plow lshadow layers\n"); return; } if (!CmdParseLayers(cmd->tx_argv[2], &okTypes)) return; saveDef = plowYankDef; plowYankDef = def; (void) plowSrShadowBack(PL_TECHDEPBASE, &editArea, okTypes, plowShowShadow, (ClientData) def); plowYankDef = saveDef; break; case PC_SHADOW: if (cmd->tx_argc < 3) { TxError("Usage: *plow shadow layers\n"); return; } if (!CmdParseLayers(cmd->tx_argv[2], &okTypes)) return; saveDef = plowYankDef; plowYankDef = def; (void) plowSrShadow(PL_TECHDEPBASE, &editArea, okTypes, plowShowShadow, (ClientData) def); plowYankDef = saveDef; break; case PC_TECHSHOW: f = stdout; if (cmd->tx_argc >= 3) { f = fopen(cmd->tx_argv[2], "w"); if (f == NULL) { perror(cmd->tx_argv[2]); break; } } plowTechShow(f); if (f != stdout) (void) fclose(f); break; case PC_WIDTH: if (cmd->tx_argc < 3) { TxError("Usage: *plow width layers\n"); return; } if (!CmdParseLayers(cmd->tx_argv[2], &okTypes)) return; edge.e_rect = editArea; edge.e_pNum = PL_TECHDEPBASE; TxPrintf("Box: X: %d .. %d Y: %d .. %d\n", editArea.r_xbot, editArea.r_xtop, editArea.r_ybot, editArea.r_ytop); saveDef = plowYankDef; plowYankDef = def; (void) plowFindWidth(&edge, okTypes, &def->cd_bbox, &editArea); plowYankDef = saveDef; GeoTransRect(&EditToRootTransform, &editArea, &rootBox); ToolMoveBox(TOOL_BL, &rootBox.r_ll, FALSE, rootBoxDef); ToolMoveCorner(TOOL_TR, &rootBox.r_ur, FALSE, rootBoxDef); break; case PC_LWIDTH: if (cmd->tx_argc < 3) { TxError("Usage: *plow lwidth layers\n"); return; } if (!CmdParseLayers(cmd->tx_argv[2], &okTypes)) return; edge.e_rect = editArea; edge.e_pNum = PL_TECHDEPBASE; TxPrintf("Box: X: %d .. %d Y: %d .. %d\n", editArea.r_xbot, editArea.r_xtop, editArea.r_ybot, editArea.r_ytop); saveDef = plowYankDef; plowYankDef = def; (void) plowFindWidthBack(&edge, okTypes, &def->cd_bbox, &editArea); plowYankDef = saveDef; GeoTransRect(&EditToRootTransform, &editArea, &rootBox); ToolMoveBox(TOOL_BL, &rootBox.r_ll, FALSE, rootBoxDef); ToolMoveCorner(TOOL_TR, &rootBox.r_ur, FALSE, rootBoxDef); break; case PC_TRAIL: if (cmd->tx_argc > 3) { TxError("Usage: *plow trail [value]\n"); return; } tp = TiSrPointNoHint(plane, &editArea.r_ll); if (cmd->tx_argc == 3) trail = atoi(cmd->tx_argv[2]); else trail = editArea.r_xtop; TxPrintf("Trailing coordinate of tile 0x%x updated from %d to %d\n", tp, TRAILING(tp), trail); plowSetTrailing(tp, trail); break; case PC_MOVE: edge.e_pNum = PL_TECHDEPBASE; edge.e_rect = editArea; TxPrintf("Moving edge from %d to %d\n", editArea.r_xbot, editArea.r_xtop); plowMoveEdge(&edge); editArea.r_xbot--; DBWAreaChanged(def, &editArea, DBW_ALLWINDOWS, &DBAllButSpaceBits); break; case PC_SPLIT: tp = TiSrPointNoHint(plane, &editArea.r_ll); if (editArea.r_ybot == BOTTOM(tp) || editArea.r_ybot == TOP(tp)) { TxError("Can't split at top or bottom of tile\n"); return; } TiToRect(tp, &area2); TxPrintf("Splitting tile 0x%x at y=%d yielding 0x%x\n", tp, editArea.r_ybot, plowSplitY(tp, editArea.r_ybot)); DBWAreaChanged(def, &area2, DBW_ALLWINDOWS, &DBAllButSpaceBits); break; case PC_MERGEDOWN: tp = TiSrPointNoHint(plane, &editArea.r_ll); TxPrintf("Merging tile 0x%x below\n", tp); TiToRect(tp, &editArea); TiToRect(RT(tp), &area2); (void) GeoInclude(&area2, &editArea); plowMergeBottom(tp, plane); DBWAreaChanged(def, &editArea, DBW_ALLWINDOWS, &DBAllButSpaceBits); break; case PC_MERGEUP: tp = TiSrPointNoHint(plane, &editArea.r_ll); TxPrintf("Merging tile 0x%x above\n", tp); TiToRect(tp, &editArea); TiToRect(RT(tp), &area2); (void) GeoInclude(&area2, &editArea); plowMergeTop(tp, plane); DBWAreaChanged(def, &editArea, DBW_ALLWINDOWS, &DBAllButSpaceBits); break; case PC_PRINT: tp = TiSrPointNoHint(plane, &editArea.r_ll); TxPrintf("Tile 0x%x LEFT=%d RIGHT=%d BOTTOM=%d TOP=%d\n", tp, LEFT(tp), RIGHT(tp), BOTTOM(tp), TOP(tp)); TxPrintf(" TRAILING=%d LEADING=%d TYPE=%s\n", TRAILING(tp), LEADING(tp), DBTypeLongName(TiGetTypeExact(tp))); break; case PC_WHENTOP: if (cmd->tx_argc == 2) { plowWhenTop = FALSE; break; } if (cmd->tx_argc != 4) { TxError("Usage: *plow whentop xtop ytop\n"); break; } plowWhenTopPoint.p_x = atoi(cmd->tx_argv[2]); plowWhenTopPoint.p_y = atoi(cmd->tx_argv[3]); plowWhenTop = TRUE; break; case PC_WHENBOT: if (cmd->tx_argc == 2) { plowWhenBot = FALSE; break; } if (cmd->tx_argc != 4) { TxError("Usage: *plow whenbot xbot ybot\n"); break; } plowWhenBotPoint.p_x = atoi(cmd->tx_argv[2]); plowWhenBotPoint.p_y = atoi(cmd->tx_argv[3]); plowWhenBot = TRUE; break; } } /* * ---------------------------------------------------------------------------- * * plowGetCommand -- * * Pull off the subcommand from the TxCommand passed to PlowTest() * above. Verify that it is a valid command. * * Results: * Returns PC_ERROR on error; otherwise, returns the command * code (pCmd) corresponding to the command in cmd->tx_argv[1]. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ pCmd plowGetCommand(cmd) TxCommand *cmd; { int plowIndex; if (cmd->tx_argc <= 1) { TxError("Usage: *plow cmd [args]\n"); return (PC_ERROR); } plowIndex = LookupStruct(cmd->tx_argv[1], (LookupTable *) plowCmds, sizeof plowCmds[0]); if (plowIndex < 0) { TxError("Bad plowing command '%s'.\n", cmd->tx_argv[1]); TxError("Try '*plow help' for a list of commands.\n"); return (PC_ERROR); } return (plowCmds[plowIndex].p_cmd); } /* * ---------------------------------------------------------------------------- * * plowDebugInit -- * * Initialize debugging flags. * * Results: * None. * * Side effects: * Registers various debugging flags with the debugging module. * * ---------------------------------------------------------------------------- */ void plowDebugInit() { int n; static struct { char *di_name; int *di_id; } debug[] = { "addedge", &plowDebAdd, "jogs", &plowDebJogs, "moveedge", &plowDebMove, "nextedge", &plowDebNext, "time", &plowDebTime, "width", &plowDebWidth, "yankall", &plowDebYankAll, 0 }; /* Register ourselves with the debugging module */ plowDebugID = DebugAddClient("plow", sizeof debug/sizeof debug[0]); for (n = 0; debug[n].di_name; n++) *(debug[n].di_id) = DebugAddFlag(plowDebugID, debug[n].di_name); } /* * ---------------------------------------------------------------------------- * * plowShowShadow -- * * Debug shadow search. Called for each edge found, we display * feedback over the area of the edge. * * Results: * None. * * Side effects: * Leaves feedback. * * ---------------------------------------------------------------------------- */ void plowShowShadow(edge, def) Edge *edge; CellDef *def; { char mesg[512]; int scaleFactor = 10; Rect edgeArea; (void) sprintf(mesg, "Edge between %s and %s", DBTypeLongName(edge->e_ltype), DBTypeLongName(edge->e_rtype)); edgeArea.r_xbot = edge->e_x * scaleFactor - 1; edgeArea.r_xtop = edge->e_x * scaleFactor + 1; edgeArea.r_ybot = edge->e_ybot * scaleFactor; edgeArea.r_ytop = edge->e_ytop * scaleFactor; DBWFeedbackAdd(&edgeArea, mesg, def, scaleFactor, STYLE_SOLIDHIGHLIGHTS); } /* * ---------------------------------------------------------------------------- * * plowTestJog -- * * Test jog elimination. * Yank the area enclosed by the box, plus a TechHalo-lambda halo around it, * into plowYankDef, and then call plowCleanupJogs() to reduce jogs in this * yank buffer. * * Results: * None. * * Side effects: * Modifies plowYankDef. * Redisplays. * * ---------------------------------------------------------------------------- */ void plowTestJog(def, area) CellDef *def; Rect *area; { extern CellUse *plowYankUse; extern Rect plowYankedArea; extern CellDef *plowYankDef; Rect changedArea; SearchContext scx; PaintUndoInfo ui; /* Make sure the yank buffers exist */ plowYankCreate(); /* Yank into yank buffer */ UndoDisable(); DBCellClearDef(plowYankDef); plowDummyUse->cu_def = def; scx.scx_use = plowDummyUse; scx.scx_trans = GeoIdentityTransform; scx.scx_area.r_xbot = area->r_xbot - DRCTechHalo; scx.scx_area.r_ybot = area->r_ybot - DRCTechHalo; scx.scx_area.r_xtop = area->r_xtop + DRCTechHalo; scx.scx_area.r_ytop = area->r_ytop + DRCTechHalo; (void) DBCellCopyPaint(&scx, &DBAllButSpaceAndDRCBits, 0, plowYankUse); DBReComputeBbox(plowYankDef); DBWAreaChanged(plowYankDef,&TiPlaneRect,DBW_ALLWINDOWS,&DBAllButSpaceBits); plowYankedArea = TiPlaneRect; /* Reduce jogs */ changedArea.r_xbot = changedArea.r_xtop = 0; changedArea.r_ybot = changedArea.r_ytop = 0; plowCleanupJogs(area, &changedArea); DBReComputeBbox(plowYankDef); DBWAreaChanged(plowYankDef,&changedArea,DBW_ALLWINDOWS,&DBAllButSpaceBits); UndoEnable(); /* Erase area in original def */ ui.pu_def = def; for (ui.pu_pNum = PL_TECHDEPBASE; ui.pu_pNum < DBNumPlanes; ui.pu_pNum++) DBPaintPlane(def->cd_planes[ui.pu_pNum], area, DBWriteResultTbl[TT_SPACE], &ui); /* Stuff from yank buffer back into original def */ scx.scx_area = *area; scx.scx_use = plowYankUse; scx.scx_trans = GeoIdentityTransform; (void) DBCellCopyPaint(&scx, &DBAllButSpaceAndDRCBits, 0, plowDummyUse); DBReComputeBbox(def); DBWAreaChanged(def, area, DBW_ALLWINDOWS, &DBAllButSpaceBits); DRCCheckThis(def, TT_CHECKPAINT, area); } /* * ---------------------------------------------------------------------------- * * plowDebugEdge -- * * Display an edge for debugging purposes. * This consists of showing the edge, and its final position, highlighted * with feedback, then erasing the feedback after requesting "more" from * the user. * * If the user responds with "d" to the "more" request, everything is forcibly * redisplayed. * * Results: * None. * * Side effects: * None permanent. * * ---------------------------------------------------------------------------- */ void plowDebugEdge(edge, rtePtr, mesg) Edge *edge; RuleTableEntry *rtePtr; char *mesg; { int scaleFactor = 10; Rect edgeArea; if (rtePtr) TxPrintf("Rule being applied: \"%s\"\n", rtePtr->rte_name); TxPrintf("%s edge (%s :: %s) YL=%d YH=%d X=%d XNEW=%d", mesg, DBTypeShortName(edge->e_ltype), DBTypeShortName(edge->e_rtype), edge->e_ybot, edge->e_ytop, edge->e_x, edge->e_newx); /* LHS */ edgeArea.r_xbot = edge->e_x * scaleFactor - 1; edgeArea.r_xtop = edge->e_x * scaleFactor + 1; edgeArea.r_ybot = edge->e_ybot * scaleFactor; edgeArea.r_ytop = edge->e_ytop * scaleFactor; DBWFeedbackAdd(&edgeArea, "", plowYankDef, scaleFactor, STYLE_SOLIDHIGHLIGHTS); /* RHS */ edgeArea.r_xbot = edge->e_newx * scaleFactor - 1; edgeArea.r_xtop = edge->e_newx * scaleFactor + 1; edgeArea.r_ybot = edge->e_ybot * scaleFactor; edgeArea.r_ytop = edge->e_ytop * scaleFactor; DBWFeedbackAdd(&edgeArea, "", plowYankDef, scaleFactor, STYLE_MEDIUMHIGHLIGHTS); /* TOP */ edgeArea.r_xbot = edge->e_x * scaleFactor; edgeArea.r_xtop = edge->e_newx * scaleFactor; edgeArea.r_ybot = edge->e_ytop * scaleFactor - 1; edgeArea.r_ytop = edge->e_ytop * scaleFactor + 1; DBWFeedbackAdd(&edgeArea, "", plowYankDef, scaleFactor, STYLE_MEDIUMHIGHLIGHTS); /* BOTTOM */ edgeArea.r_xbot = edge->e_x * scaleFactor; edgeArea.r_xtop = edge->e_newx * scaleFactor; edgeArea.r_ybot = edge->e_ybot * scaleFactor - 1; edgeArea.r_ytop = edge->e_ybot * scaleFactor + 1; DBWFeedbackAdd(&edgeArea, "", plowYankDef, scaleFactor, STYLE_MEDIUMHIGHLIGHTS); WindUpdate(); plowDebugMore(); DBWFeedbackClear(NULL); WindUpdate(); } /* * ---------------------------------------------------------------------------- * * plowDebugMore -- * * Request "more" from the user. * If the user responds with "d" to the "more" request, * everything is forcibly redisplayed. * * Results: * None. * * Side effects: * May cause redisplay. * * ---------------------------------------------------------------------------- */ void plowDebugMore() { char answer[100]; again: if (TxGetLinePrompt(answer, sizeof answer, " -- more -- ") == NULL) return; if (answer[0] == 'd') { DBWAreaChanged(plowYankDef, &TiPlaneRect, DBW_ALLWINDOWS, &DBAllButSpaceBits); WindUpdate(); goto again; } } /* * ---------------------------------------------------------------------------- * * plowShowOutline -- * * Debug outline search. Called for each outline segment found, we display * feedback over the area of the segment and then ask for more. * * Results: * Normally returns 0, but will return 1 if the boundary segment * leaves the clipping rectangle clipArea, or if its endpoint is * the lower-left of the clipping rectangle. * * Side effects: * Leaves feedback. * * ---------------------------------------------------------------------------- */ int plowShowOutline(outline, clipArea) Outline *outline; Rect *clipArea; { static char *dirNames[] = { "center", "north", "northeast", "east", "southeast", "south", "southwest", "west", "northwest", "eastnorth", "eastsouth", "westnorth", "westsouth" }; char mesg[512], prompt[612], answer[128]; int scaleFactor = 10; Rect edgeArea; (void) sprintf(mesg, "%s/%s/%s segment in=%s out=%s", dirNames[outline->o_prevDir], dirNames[outline->o_currentDir], dirNames[outline->o_nextDir], DBTypeLongName(TiGetTypeExact(outline->o_inside)), DBTypeLongName(TiGetTypeExact(outline->o_outside))); switch (outline->o_currentDir) { case GEO_NORTH: case GEO_SOUTH: edgeArea.r_xbot = outline->o_rect.r_xbot * scaleFactor - 1; edgeArea.r_xtop = outline->o_rect.r_xbot * scaleFactor + 1; edgeArea.r_ybot = outline->o_rect.r_ybot * scaleFactor; edgeArea.r_ytop = outline->o_rect.r_ytop * scaleFactor; break; case GEO_EAST: case GEO_WEST: edgeArea.r_xbot = outline->o_rect.r_xbot * scaleFactor; edgeArea.r_xtop = outline->o_rect.r_xtop * scaleFactor; edgeArea.r_ybot = outline->o_rect.r_ybot * scaleFactor - 1; edgeArea.r_ytop = outline->o_rect.r_ytop * scaleFactor + 1; break; } DBWFeedbackAdd(&edgeArea, mesg, EditCellUse->cu_def, scaleFactor, STYLE_SOLIDHIGHLIGHTS); WindUpdate(); (void) sprintf(prompt, "%s --more--", mesg); (void) TxGetLinePrompt(answer, sizeof answer, prompt); if (answer[0] == 'n') return (1); #ifdef notdef /* Does this segment cross the clipping area? */ if (outline->o_rect.r_xtop >= clipArea->r_xtop || outline->o_rect.r_ytop >= clipArea->r_ytop || outline->o_rect.r_xbot < clipArea->r_xbot || outline->o_rect.r_ybot < clipArea->r_ybot) return (1); #endif /* notdef */ /* Are we back at the starting point? */ switch (outline->o_currentDir) { case GEO_NORTH: case GEO_EAST: if (outline->o_rect.r_xtop == clipArea->r_xbot && outline->o_rect.r_ytop == clipArea->r_ybot) return (1); break; case GEO_SOUTH: case GEO_WEST: if (outline->o_rect.r_xbot == clipArea->r_xbot && outline->o_rect.r_ybot == clipArea->r_ybot) return (1); break; } return (0); } /* * ---------------------------------------------------------------------------- * * plowDisplay -- * * Debugging procedure to redisplay the yank and spare buffers. * If 'dodef' is TRUE, we also redisplay the original cell. * * Results: * None. * * Side effects: * Forces redisplay. * * ---------------------------------------------------------------------------- */ void plowDisplay(dodef) bool dodef; { if (dodef) DBWAreaChanged(plowDummyUse->cu_def, &TiPlaneRect, DBW_ALLWINDOWS, &DBAllButSpaceBits); DBWAreaChanged(plowYankDef, &TiPlaneRect, DBW_ALLWINDOWS, &DBAllButSpaceBits); DBWAreaChanged(plowSpareDef, &TiPlaneRect, DBW_ALLWINDOWS, &DBAllButSpaceBits); WindUpdate(); } magic-8.0.210/plow/plowDebugInt.h0000644000175000001440000000270710751423606015221 0ustar timusers/* * plowDebugInt.h -- * * Definitions of debugging flags for plowing. * This is a separate include file so that new debugging flags * can be added to it without forcing recompilation of the * entire plow module. * * ********************************************************************* * * 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. * * ********************************************************************* * * rcsid $Header: /usr/cvsroot/magic-8.0/plow/plowDebugInt.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ */ extern int plowDebAdd; extern int plowDebMove; extern int plowDebNext; extern int plowDebTime; extern int plowDebWidth; extern int plowDebJogs; extern int plowDebYankAll; extern ClientData plowDebugID; extern Point plowWhenTopPoint, plowWhenBotPoint; extern bool plowWhenTop, plowWhenBot; magic-8.0.210/plow/PlowRules2.c0000664000175000001440000007562612032325053014632 0ustar timusers/* * PlowRules2.c -- * * Plowing rules. * These are applied by plowProcessEdge() for each edge that is to be moved. * * ********************************************************************* * * 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/plow/PlowRules2.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/undo.h" #include "plow/plow.h" #include "plow/plowInt.h" #include "drc/drc.h" /* Imports from other rules files */ extern int plowApplyRule(); /* Forward declarations */ int plowFoundCell(); int plowCellDragPaint(), plowCellPushPaint(); int plowCoverTopProc(), plowCoverBotProc(); int plowIllegalTopProc(), plowIllegalBotProc(); int plowDragEdgeProc(); /* * ---------------------------------------------------------------------------- * * prFixedLHS -- * prFixedRHS -- * * The type on the LHS or RHS of an edge is a fixed-width. * Make sure that the opposite edge of the tile also moves. * When processing an edge whose RHS is fixed-width, we also * walk along the top and bottom of each tilef making sure all * fixed-width tiles move by the same amount. This is necessary * in order to preserve transistor geometries. * * Results: * None. * * Side effects: * May add edges to the queue of edges to be processed. * * ---------------------------------------------------------------------------- */ void prFixedLHS(edge) Edge *edge; /* Edge being moved */ { int distance = edge->e_newx - edge->e_x; Tile *tpL; Point startPoint; Rect atomRect; Plane *plane; restart: startPoint.p_x = edge->e_x - 1; startPoint.p_y = edge->e_ybot; plane = plowYankDef->cd_planes[edge->e_pNum]; for (tpL = TiSrPointNoHint(plane, &startPoint); BOTTOM(tpL) < edge->e_ytop; tpL = RT(tpL)) { /* Add the entire LHS of each of the tiles comprising this edge */ atomRect.r_xbot = LEFT(tpL); atomRect.r_xtop = LEFT(tpL) + distance; atomRect.r_ybot = BOTTOM(tpL); atomRect.r_ytop = TOP(tpL); if (plowYankMore(&atomRect, 1, 1)) goto restart; /* Only queue if it hasn't already moved far enough */ if (TRAILING(tpL) < LEFT(tpL) + distance) (void) plowAtomize(edge->e_pNum, &atomRect, plowPropagateProcPtr, (ClientData) NULL); } } int prFixedRHS(edge) Edge *edge; /* Edge being moved */ { int distance = edge->e_newx - edge->e_x; Tile *tpR, *tp; Point startPoint; Rect atomRect; Plane *plane; restart: startPoint.p_x = edge->e_x; startPoint.p_y = edge->e_ytop - 1; plane = plowYankDef->cd_planes[edge->e_pNum]; tpR = TiSrPointNoHint(plane, &startPoint); /* Move the RHS of all the tiles comprising this edge */ for ( ; TOP(tpR) > edge->e_ybot; tpR = LB(tpR)) { /* Queue the RHS of this tile */ atomRect.r_xbot = RIGHT(tpR); atomRect.r_xtop = RIGHT(tpR) + distance; atomRect.r_ybot = BOTTOM(tpR); atomRect.r_ytop = TOP(tpR); if (plowYankMore(&atomRect, 1, 1)) goto restart; /* Only queue RHS if it hasn't already moved far enough */ if (LEADING(tpR) < RIGHT(tpR) + distance) (void) plowAtomize(edge->e_pNum, &atomRect, plowPropagateProcPtr, (ClientData) NULL); /* Move all fixed-width tiles along the top */ for (tp = RT(tpR); RIGHT(tp) > LEFT(tpR); tp = BL(tp)) { if (TTMaskHasType(&PlowFixedTypes, TiGetTypeExact(tp))) { atomRect.r_xbot = LEFT(tp); atomRect.r_xtop = LEFT(tp) + distance; atomRect.r_ybot = BOTTOM(tp); atomRect.r_ytop = TOP(tp); if (plowYankMore(&atomRect, 1, 1)) goto restart; /* Only queue if it hasn't moved far enough */ if (TRAILING(tp) < LEFT(tp) + distance) (void) plowAtomize(edge->e_pNum, &atomRect, plowPropagateProcPtr, (ClientData) NULL); } } /* Move all fixed-width tiles along the bottom */ for (tp = LB(tpR); LEFT(tp) < RIGHT(tpR); tp = TR(tp)) { if (TTMaskHasType(&PlowFixedTypes, TiGetTypeExact(tp))) { atomRect.r_xbot = LEFT(tp); atomRect.r_xtop = LEFT(tp) + distance; atomRect.r_ybot = BOTTOM(tp); atomRect.r_ytop = TOP(tp); if (plowYankMore(&atomRect, 1, 1)) goto restart; /* Only queue if it hasn't moved far enough */ if (TRAILING(tp) < LEFT(tp) + distance) (void) plowAtomize(edge->e_pNum, &atomRect, plowPropagateProcPtr, (ClientData) NULL); } } } return 0; } /* * ---------------------------------------------------------------------------- * * prFixedPenumbraTop -- * prFixedPenumbraBot -- * * When the RHS material is fixed-width and no spacing rules apply * across the edge, these rules get applied. The case handled is * the following (E is the edge): * * OOOOOOOOOOOOOOOOO * O O * O ------------> O * top O O * OOOOOOOOOOOOOOOOO * ========= * E * ltype E rtype ------> * E * * where spacing rules DO apply across the ltype -- top edge. * For each such spacing rule, we search the area O above, where * the height of O is the distance of the spacing rule. All * edges not in the 'oktypes' for the spacing rule are moved as * far as the edge E. * * Results: * None. * * Side effects: * May add edges to the queue of edges to be processed. * * ---------------------------------------------------------------------------- */ void prFixedPenumbraTop(edge) Edge *edge; /* Edge being moved */ { struct applyRule ar; PlowRule *pr; Tile *tp; Rect searchRect; Point p; p.p_x = edge->e_x - 1; p.p_y = edge->e_ytop; tp = TiSrPointNoHint(plowYankDef->cd_planes[edge->e_pNum], &p); pr = plowSpacingRulesTbl[edge->e_ltype][TiGetTypeExact(tp)]; if (pr == (PlowRule *) NULL) return; searchRect.r_xbot = edge->e_x - 1; searchRect.r_ybot = edge->e_ytop; searchRect.r_xtop = edge->e_newx; ar.ar_rule = (PlowRule *) NULL; ar.ar_moving = edge; for ( ; pr; pr = pr->pr_next) { searchRect.r_ytop = edge->e_ytop + pr->pr_dist; (void) plowSrShadow(pr->pr_pNum, &searchRect, pr->pr_oktypes, plowApplyRule, (ClientData) &ar); } } int prFixedPenumbraBot(edge) Edge *edge; /* Edge being moved */ { struct applyRule ar; PlowRule *pr; Tile *tp; Rect searchRect; Point p; p.p_x = edge->e_x - 1; p.p_y = edge->e_ybot - 1; tp = TiSrPointNoHint(plowYankDef->cd_planes[edge->e_pNum], &p); pr = plowSpacingRulesTbl[edge->e_ltype][TiGetTypeExact(tp)]; if (pr == (PlowRule *) NULL) return 0; searchRect.r_xbot = edge->e_x - 1; searchRect.r_ytop = edge->e_ybot; searchRect.r_xtop = edge->e_newx; ar.ar_rule = (PlowRule *) NULL; ar.ar_moving = edge; for ( ; pr; pr = pr->pr_next) { searchRect.r_ybot = edge->e_ybot - pr->pr_dist; (void) plowSrShadow(pr->pr_pNum, &searchRect, pr->pr_oktypes, plowApplyRule, (ClientData) &ar); } return 0; } /* * ---------------------------------------------------------------------------- * * prFixedDragStubs -- * * The type on the RHS of an edge is a fixed-width, and the type on the * LHS is neither fixed-width nor space. Our job is to drag alone the * left-hand side of the LHS tiles if they are minimum-width or less. * * The purpose of this rule is mainly to prevent transistors from * leaving their gates trailing behind. * * Results: * None. * * Side effects: * May add edges to the queue of edges to be processed. * * ---------------------------------------------------------------------------- */ void prFixedDragStubs(edge) Edge *edge; /* Edge being moved; RHS is fixed-width */ { int distance = edge->e_newx - edge->e_x; Tile *tpL; Point startPoint; Rect atomRect; Plane *plane; restart: startPoint.p_x = edge->e_x - 1; startPoint.p_y = edge->e_ybot; plane = plowYankDef->cd_planes[edge->e_pNum]; for (tpL = TiSrPointNoHint(plane, &startPoint); BOTTOM(tpL) < edge->e_ytop; tpL = RT(tpL)) { /* * Add the entire LHS of each of the tiles comprising this edge, * if the LHS is minimum-width and exposed to space. */ atomRect.r_xbot = LEFT(tpL); atomRect.r_xtop = LEFT(tpL) + distance; atomRect.r_ybot = BOTTOM(tpL); atomRect.r_ytop = TOP(tpL); if (plowYankMore(&atomRect, 1, 1)) goto restart; if (TRAILING(tpL) < atomRect.r_xtop) (void) plowAtomize(edge->e_pNum, &atomRect, plowDragEdgeProc, (ClientData) edge); } } /* * ---------------------------------------------------------------------------- * * plowDragEdgeProc -- * * Called for each segment along the LHS of the tiles processed by * prFixedDragStubs() above. If lhsEdge->e_ltype is space, and * lhsEdge is the minimum-distance from movingEdge, we queue it * to move by the same amount as movingEdge. * * Results: * Returns 0 always. * * Side effects: * May add edges to the queue of edges to be processed. * * ---------------------------------------------------------------------------- */ int plowDragEdgeProc(lhsEdge, movingEdge) Edge *lhsEdge; /* Edge on LHS; the caller has already * determined that this edge has not * already moved far enough. */ Edge *movingEdge; /* RHS of this edge is fixed-width */ { PlowRule *pr; int xsep, width; /* Don't move the edge if it isn't to space */ if (lhsEdge->e_ltype != TT_SPACE) return (0); /* Don't bother doing any more work if it's too far to the left */ if (lhsEdge->e_x + DRCTechHalo < movingEdge->e_x) return (0); /* * Try to guess at minimum width. * Then, if lhsEdge is less than minimum width to the left * of movingEdge, we queue lhsEdge to move by the same * amount. */ width = INFINITY; /* Apply width rules from lhsEdge rightward */ for (pr = plowWidthRulesTbl[lhsEdge->e_ltype][lhsEdge->e_rtype]; pr; pr = pr->pr_next) width = MIN(width, pr->pr_dist); /* Apply spacing rules from movingEdge leftward */ for (pr = plowSpacingRulesTbl[movingEdge->e_rtype][movingEdge->e_ltype]; pr; pr = pr->pr_next) if (!TTMaskHasType(&pr->pr_oktypes, TT_SPACE)) width = MIN(width, pr->pr_dist); /* No width, so assume we don't move it */ if (width == INFINITY) return (0); /* Only move if minimum width or less */ xsep = movingEdge->e_x - lhsEdge->e_x; if (xsep <= width) (*plowPropagateProcPtr)(lhsEdge); return (0); } /* * ---------------------------------------------------------------------------- * * prContactLHS -- * prContactRHS -- * * The type on the LHS or RHS of an edge is a contact. * Couple to each of the planes connected by the contact. * Contacts must be fixed-width. * * Results: * None. * * Side effects: * May add edges to the queue of edges to be processed. * * ---------------------------------------------------------------------------- */ void prContactLHS(edge) Edge *edge; /* Edge being moved (LHS is contact) */ { int pNum, pMax; PlaneMask connPlanes = DBConnPlanes[edge->e_ltype]; /* Add the edges of the contact on its other planes */ connPlanes &= ~(edge->e_pNum); pMax = DBPlane(edge->e_ltype) + 1; for (pNum = pMax - 2; pNum <= pMax; pNum++) if (PlaneMaskHasPlane(connPlanes, pNum)) (void) plowAtomize(pNum, &edge->e_rect, plowPropagateProcPtr, (ClientData) NULL); } int prContactRHS(edge) Edge *edge; /* Edge being moved (RHS is contact) */ { int pNum, pMax; PlaneMask connPlanes = DBConnPlanes[edge->e_rtype]; /* Add the edges of the contact on its other planes */ connPlanes &= ~(edge->e_pNum); pMax = DBPlane(edge->e_ltype) + 1; for (pNum = pMax - 2; pNum <= pMax; pNum++) if (PlaneMaskHasPlane(connPlanes, pNum)) (void) plowAtomize(pNum, &edge->e_rect, plowPropagateProcPtr, (ClientData) NULL); return 0; } /* * ---------------------------------------------------------------------------- * * prCoverTop -- * prCoverBot -- * * SEARCH RULE. * The material on the LHS of this edge must always stay covered. * To insure this, we drag along the material attached to its top * right and bottom right corners. * * Results: * None. * * Side effects: * May add edges to the queue of edges to be moved. * * ---------------------------------------------------------------------------- */ void prCoverTop(edge) Edge *edge; /* Edge being moved */ { TileType ltype, rtype; PlowRule *pr; Tile *tp; struct applyRule ar; Point startPoint; Rect searchArea; startPoint.p_x = edge->e_x - 1; startPoint.p_y = edge->e_ytop; tp = TiSrPointNoHint(plowYankDef->cd_planes[edge->e_pNum], &startPoint); if (TiGetTypeExact(tp) == TT_SPACE) return; ltype = edge->e_ltype; rtype = TiGetTypeExact(tp); ar.ar_moving = edge; ar.ar_rule = (PlowRule *) NULL; searchArea.r_xbot = edge->e_x - 1; searchArea.r_xtop = edge->e_newx; searchArea.r_ybot = edge->e_ytop; for (pr = plowWidthRulesTbl[ltype][rtype]; pr; pr = pr->pr_next) { searchArea.r_ytop = edge->e_ytop + pr->pr_dist; (void) plowSrShadow(edge->e_pNum, &searchArea, pr->pr_oktypes, plowApplyRule, (ClientData) &ar); } for (pr = plowSpacingRulesTbl[ltype][rtype]; pr; pr = pr->pr_next) { searchArea.r_ytop = edge->e_ytop + pr->pr_dist; (void) plowSrShadow(edge->e_pNum, &searchArea, pr->pr_oktypes, plowApplyRule, (ClientData) &ar); } } int prCoverBot(edge) Edge *edge; /* Edge being moved */ { TileType ltype, rtype; PlowRule *pr; Tile *tp; struct applyRule ar; Point startPoint; Rect searchArea; startPoint.p_x = edge->e_x - 1; startPoint.p_y = edge->e_ybot - 1; tp = TiSrPointNoHint(plowYankDef->cd_planes[edge->e_pNum], &startPoint); if (TiGetTypeExact(tp) == TT_SPACE) return 0; ltype = edge->e_ltype; rtype = TiGetTypeExact(tp); ar.ar_moving = edge; ar.ar_rule = (PlowRule *) NULL; searchArea.r_xbot = edge->e_x - 1; searchArea.r_xtop = edge->e_newx; searchArea.r_ytop = edge->e_ybot; for (pr = plowWidthRulesTbl[ltype][rtype]; pr; pr = pr->pr_next) { searchArea.r_ybot = edge->e_ybot - pr->pr_dist; (void) plowSrShadow(edge->e_pNum, &searchArea, pr->pr_oktypes, plowApplyRule, (ClientData) &ar); } for (pr = plowSpacingRulesTbl[ltype][rtype]; pr; pr = pr->pr_next) { searchArea.r_ybot = edge->e_ybot - pr->pr_dist; (void) plowSrShadow(edge->e_pNum, &searchArea, pr->pr_oktypes, plowApplyRule, (ClientData) &ar); } return 0; } /* * ---------------------------------------------------------------------------- * * prIllegalTop -- * prIllegalBot -- * * Insure that the material on the LHS of 'edge' doesn't form an illegal * edge with material to its top or bottom, as it slides to the right. * * Results: * None. * * Side effects: * May add edges to the queue of edges to be moved. * * ---------------------------------------------------------------------------- */ void prIllegalTop(edge) Edge *edge; { TileTypeBitMask insideTypes; struct applyRule ar; Point startPoint; ar.ar_moving = edge; startPoint.p_x = edge->e_x; startPoint.p_y = edge->e_ytop; TTMaskSetOnlyType(&insideTypes, edge->e_rtype); TTMaskCom(&insideTypes); ar.ar_slivtype = (TileType) -1; ar.ar_clip.p_x = edge->e_newx; plowSrOutline(edge->e_pNum, &startPoint, insideTypes, GEO_NORTH, GMASK_EAST|GMASK_WEST|GMASK_NORTH|GMASK_SOUTH, plowIllegalTopProc, (ClientData) &ar); if (ar.ar_slivtype == (TileType) -1) return; startPoint.p_x = ar.ar_mustmove; TTMaskSetOnlyType(&insideTypes, ar.ar_slivtype); TTMaskCom(&insideTypes); plowSrOutline(edge->e_pNum, &startPoint, insideTypes, GEO_NORTH, GMASK_WEST|GMASK_NORTH|GMASK_SOUTH, plowCoverTopProc, (ClientData) &ar); } int prIllegalBot(edge) Edge *edge; { TileTypeBitMask insideTypes; struct applyRule ar; Point startPoint; ar.ar_moving = edge; startPoint.p_x = edge->e_x; startPoint.p_y = edge->e_ybot; TTMaskSetOnlyType(&insideTypes, edge->e_rtype); ar.ar_slivtype = (TileType) -1; ar.ar_clip.p_x = edge->e_newx; plowSrOutline(edge->e_pNum, &startPoint, insideTypes, GEO_SOUTH, GMASK_EAST|GMASK_WEST|GMASK_NORTH|GMASK_SOUTH, plowIllegalBotProc, (ClientData) &ar); if (ar.ar_slivtype == (TileType) -1) return 0; startPoint.p_x = ar.ar_mustmove; TTMaskSetOnlyType(&insideTypes, ar.ar_slivtype); plowSrOutline(edge->e_pNum, &startPoint, insideTypes, GEO_SOUTH, GMASK_WEST|GMASK_NORTH|GMASK_SOUTH, plowCoverBotProc, (ClientData) &ar); return 0; } /* * ---------------------------------------------------------------------------- * * plowCoverTopProc -- * plowCoverBotProc -- * * Called by plowSrOutline() on behalf of prIllegalTop() or prIllegalBot() * above. Move all vertical edges found along the outline being searched * until we reach either ar->ar_clip.p_x in the X direction, or ar->ar_clip.p_y * in the Y direction, or turn left. * * Results: * Returns 0 if we will keep going, or 1 if any of the termination * conditions above are met. * * Side effects: * May add edges to the queue of edges to be moved. * * ---------------------------------------------------------------------------- */ int plowCoverTopProc(outline, ar) Outline *outline; struct applyRule *ar; { Edge edge; int ret = 0; /* Done if not headed north */ if (outline->o_currentDir != GEO_NORTH) return (1); /* Done if outside of the clip area */ if (outline->o_rect.r_xbot >= ar->ar_clip.p_x) return (1); /* Done after this time if we touch the clip area */ edge.e_rect = outline->o_rect; if (edge.e_ytop >= ar->ar_clip.p_y) edge.e_ytop = ar->ar_clip.p_y, ret = 1; if (edge.e_ytop > edge.e_ybot && TRAILING(outline->o_outside) < ar->ar_moving->e_newx) { edge.e_newx = ar->ar_moving->e_newx; edge.e_pNum = ar->ar_moving->e_pNum; edge.e_use = (CellUse *) NULL; edge.e_flags = 0; edge.e_ltype = TiGetTypeExact(outline->o_inside); edge.e_rtype = TiGetTypeExact(outline->o_outside); (void) (*plowPropagateProcPtr)(&edge); } return (ret); } int plowCoverBotProc(outline, ar) Outline *outline; struct applyRule *ar; { Edge edge; int ret = 0; /* Done if not headed south */ if (outline->o_currentDir != GEO_SOUTH) return (1); /* Done if outside of the clip area */ if (outline->o_rect.r_xbot >= ar->ar_clip.p_x) return (1); /* Done after this time if we touch the clip area */ edge.e_rect = outline->o_rect; if (edge.e_ybot <= ar->ar_clip.p_y) edge.e_ybot = ar->ar_clip.p_y, ret = 1; if (edge.e_ytop > edge.e_ybot && TRAILING(outline->o_inside) < ar->ar_moving->e_newx) { edge.e_newx = ar->ar_moving->e_newx; edge.e_pNum = ar->ar_moving->e_pNum; edge.e_use = (CellUse *) NULL; edge.e_flags = 0; edge.e_ltype = TiGetTypeExact(outline->o_outside); edge.e_rtype = TiGetTypeExact(outline->o_inside); (void) (*plowPropagateProcPtr)(&edge); } return (ret); } /* * ---------------------------------------------------------------------------- * * plowIllegalTopProc -- * plowIllegalBotProc -- * * Called by plowSrOutline() on behalf of prIllegalTop() and prIllegalBot() * above. We walk along the outline of the RHS of the edge ar->ar_moving. * If the outline turns up, down, or west, we're done. If the outline * segment is to the right of ar->ar_clip.p_x, we're also done. Otherwise, * we keep going until the type to the top/bottom of the outline is one * that cannot be adjacent to ar->ar_moving->e_ltype. At this point, * set ar->ar_slivtype to this type and ar->ar_mustmove to the LHS of this * segment. Set ar->ar_clip.p_y to 'width' above the top of the edge * ar->ar_moving or below its bottom, where 'width' is the minimum spacing * between the LHS material of ar->ar_moving and the illegal type. * * Results: * Returns 0 to continue, or 1 if the above termination conditions * are met. * * Side effects: * Sets ar_slivtype and ar_clip.p_y. * * ---------------------------------------------------------------------------- */ int plowIllegalTopProc(outline, ar) Outline *outline; struct applyRule *ar; { TileType badType = TiGetTypeExact(outline->o_inside), leftType; Edge *movingEdge = ar->ar_moving; DRCCookie *dp; PlowRule *pr; int width; if (outline->o_currentDir != GEO_EAST || outline->o_rect.r_xbot >= ar->ar_clip.p_x) return (1); /* Ignore if this is a legal edge */ for (dp = DRCCurStyle->DRCRulesTbl[movingEdge->e_ltype][badType]; dp; dp = dp->drcc_next) { if (!TTMaskHasType(&dp->drcc_mask, badType)) goto found_bad; } return (0); /* Found a bad type */ found_bad: /* Don't do anything if there was already a design-rule violation */ if (LEFT(outline->o_inside) < movingEdge->e_x) return (0); ar->ar_slivtype = badType; ar->ar_mustmove = outline->o_rect.r_xbot; leftType = TiGetTypeExact(BL(outline->o_inside)); width = 1; for (pr = plowSpacingRulesTbl[movingEdge->e_ltype][leftType]; pr; pr = pr->pr_next) { if (!TTMaskHasType(&pr->pr_oktypes, badType)) width = MAX(width, pr->pr_dist); } ar->ar_clip.p_y = movingEdge->e_ytop + width; return (1); } int plowIllegalBotProc(outline, ar) Outline *outline; struct applyRule *ar; { TileType badType = TiGetTypeExact(outline->o_outside), leftType; Edge *movingEdge = ar->ar_moving; DRCCookie *dp; PlowRule *pr; Tile *tp; int width; if (outline->o_currentDir != GEO_EAST || outline->o_rect.r_xbot >= ar->ar_clip.p_x) return (1); /* Ignore if this is a legal edge */ for (dp = DRCCurStyle->DRCRulesTbl[movingEdge->e_ltype][badType]; dp; dp = dp->drcc_next) { if (!TTMaskHasType(&dp->drcc_mask, badType)) goto found_bad; } return (0); /* Found a bad type */ found_bad: /* Don't do anything if there was already a design-rule violation */ if (LEFT(outline->o_outside) < movingEdge->e_x) return (0); ar->ar_slivtype = badType; ar->ar_mustmove = outline->o_rect.r_xbot; for (tp = BL(outline->o_outside); TOP(tp) < outline->o_rect.r_ybot; tp = RT(tp)) /* Nothing */; leftType = TiGetTypeExact(tp); width = 1; for (pr = plowSpacingRulesTbl[movingEdge->e_ltype][leftType]; pr; pr = pr->pr_next) { if (!TTMaskHasType(&pr->pr_oktypes, badType)) width = MAX(width, pr->pr_dist); } ar->ar_clip.p_y = movingEdge->e_ybot - width; return (1); } /* * ---------------------------------------------------------------------------- * * prFindCells -- * * Find any cells within a DRC halo of the swath cut by the edge 'edge' * as it moves, and move them. * * Results: * None. * * Side effects: * May add cells to the queue of edges to be processed. * * ---------------------------------------------------------------------------- */ void prFindCells(edge) Edge *edge; /* Edge being moved */ { Plane *cellPlane = plowYankDef->cd_planes[PL_CELL]; Tile *cellTile = cellPlane->pl_hint; struct applyRule ar; Rect searchArea; searchArea.r_xbot = edge->e_x - 1; searchArea.r_ybot = edge->e_ybot - DRCTechHalo; searchArea.r_ytop = edge->e_ytop + DRCTechHalo; searchArea.r_xtop = edge->e_newx + DRCTechHalo; ar.ar_moving = edge; /* * Don't bother doing anything if there is a single space tile * beneath the plow. */ if (TiGetBody(cellTile) == (ClientData) NULL && LEFT(cellTile) <= searchArea.r_xbot && BOTTOM(cellTile) <= searchArea.r_ybot && RIGHT(cellTile) >= searchArea.r_xtop && TOP(cellTile) >= searchArea.r_ytop) return; (void) TiSrArea(cellTile, cellPlane, &searchArea, plowFoundCell, (ClientData) &ar); } /* * ---------------------------------------------------------------------------- * * prCell -- * * The Edge 'edge' corresponds to a cell that is moving. Search the * area of the cell plus a DRCTechHalo around it for geometry to move, * and queue each edge found. Also, search to its right for other * cells to move and move them. * * Results: * None. * * Side effects: * May add cells or edges to the queue of edges to be processed. * * ---------------------------------------------------------------------------- */ void prCell(edge) Edge *edge; /* Cell edge being moved */ { Rect cellArea, shadowArea; CellUse *use = edge->e_use; struct applyRule ar; int pNum; ar.ar_moving = edge; /* Search area for paint to drag */ ar.ar_search.r_xbot = use->cu_bbox.r_xbot - 1; ar.ar_search.r_xtop = use->cu_bbox.r_xtop + DRCTechHalo; ar.ar_search.r_ybot = edge->e_ybot - DRCTechHalo; ar.ar_search.r_ytop = edge->e_ytop + DRCTechHalo; /* Shadow search area for the paint planes */ shadowArea.r_xbot = edge->e_x - 1; shadowArea.r_xtop = edge->e_newx + DRCTechHalo; shadowArea.r_ybot = edge->e_ybot - DRCTechHalo; shadowArea.r_ytop = edge->e_ytop + DRCTechHalo; /* Search all the paint planes */ for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) { ar.ar_pNum = pNum; (void) DBSrPaintArea((Tile *) NULL, plowYankDef->cd_planes[pNum], &ar.ar_search, &DBAllTypeBits, plowCellDragPaint, (ClientData) &ar); (void) plowSrShadow(pNum, &shadowArea, DBZeroTypeBits, plowCellPushPaint, (ClientData) &ar); } /* * Search for cells to move. * We could do a shadow search, but just use area search instead * since we don't expect there to be too many cells in the path. * Cells to the left of the RHS of use get dragged by the same * amount as use is moving; cells to its right stay DRCTechHalo away * (or closer if they were originally closer). */ cellArea.r_xbot = use->cu_bbox.r_xbot - 1; cellArea.r_xtop = edge->e_newx + DRCTechHalo; cellArea.r_ybot = edge->e_ybot - DRCTechHalo; cellArea.r_ytop = edge->e_ytop + DRCTechHalo; (void) TiSrArea((Tile *) NULL, plowYankDef->cd_planes[edge->e_pNum], &cellArea, plowFoundCell, (ClientData) &ar); } /* * ---------------------------------------------------------------------------- * * plowCellDragPaint -- * * Called by DBSrPaintArea() on behalf of prCell() above for each tile * overlapping the cell being moved (ar->ar_moving->e_use), or a DRCTechHalo * wide halo around it to the right, top, or bottom. * * If the LHS of the tile lies to the right of the LHS of the cell, we * move it; otherwise, we move the RHS of the tile. * * Results: * Returns 0 always. * * Side effects: * May add edges to the queue of edges to be processed. * * ---------------------------------------------------------------------------- */ int plowCellDragPaint(tile, ar) Tile *tile; struct applyRule *ar; { Edge *movingEdge = ar->ar_moving; int distance = movingEdge->e_newx - movingEdge->e_x; Rect atomRect; if (LEFT(tile) <= ar->ar_search.r_xbot) { if (LEADING(tile) >= ar->ar_search.r_xtop) return (0); atomRect.r_xtop = RIGHT(tile) + distance; if (LEADING(tile) >= atomRect.r_xtop) return (0); atomRect.r_xbot = RIGHT(tile); } else { atomRect.r_xtop = LEFT(tile) + distance; if (TRAILING(tile) >= atomRect.r_xtop) return (0); atomRect.r_xbot = LEFT(tile); } atomRect.r_ybot = MAX(BOTTOM(tile), ar->ar_search.r_ybot); atomRect.r_ytop = MIN(TOP(tile), ar->ar_search.r_ytop); (void) plowAtomize(ar->ar_pNum, &atomRect, plowPropagateProcPtr, (ClientData) NULL); return (0); } /* * ---------------------------------------------------------------------------- * * plowCellPushPaint -- * * Filter procedure called by plowSrShadow() on behalf of prCell above. * Each paint tile in the shadow of the RHS of the cell being moved * gets pushed DRCTechHalo in front of the cell when it moves. (If the * paint was already closer than DRCTechHalo to the front of the cell, * it stays that close). * * Results: * Returns 0 always. * * Side effects: * May add edges to the queue of edges to be processed. * * ---------------------------------------------------------------------------- */ int plowCellPushPaint(impactedEdge, ar) Edge *impactedEdge; /* Edge found by shadow search */ struct applyRule *ar; /* Describes edge being moved and search area */ { Edge *movingEdge = ar->ar_moving; int xsep, newx; xsep = impactedEdge->e_x - movingEdge->e_x; if (xsep > DRCTechHalo) xsep = DRCTechHalo; /* Queue the edge if it hasn't already moved far enough */ newx = movingEdge->e_newx + xsep; if (newx > impactedEdge->e_newx) { impactedEdge->e_newx = newx; (void) (*plowPropagateProcPtr)(impactedEdge); } return (0); } /* * ---------------------------------------------------------------------------- * * plowFoundCell -- * * Called for each cell tile found by an area enumeration of the umbra of * a moving edge, plus a DRCTechHalo-wide halo above, below, and to its right. * Determine how far each use associated with that cell tile must move. If * that cell has not already moved far enough, queue it. * * Results: * Returns 0 always. * * Side effects: * May add cells to the queue of edges to be processed. * * ---------------------------------------------------------------------------- */ int plowFoundCell(cellTile, ar) Tile *cellTile; struct applyRule *ar; { Edge *movingEdge = ar->ar_moving; CellTileBody *ctb; int xmove, xsep; CellUse *use; Edge edge; edge.e_pNum = PL_CELL; for (ctb = (CellTileBody *) TiGetBody(cellTile); ctb; ctb = ctb->ctb_next) { use = ctb->ctb_use; if (use->cu_bbox.r_xbot <= movingEdge->e_x) { /* * If dragging the cell, move it by as much as this edge. */ xmove = movingEdge->e_newx - movingEdge->e_x; } else { /* * If pushing the cell, keep it DRCTechHalo in front of the edge * unless it was already closer. */ xsep = use->cu_bbox.r_xbot - movingEdge->e_x; if (xsep > DRCTechHalo) xsep = DRCTechHalo; xmove = movingEdge->e_newx + xsep - use->cu_bbox.r_xbot; } /* Only queue the edge if the cell has not moved far enough */ if ((use->cu_client != (ClientData)CLIENTDEFAULT) && ((int)(use->cu_client) < xmove)) { edge.e_use = use; edge.e_flags = 0; edge.e_ytop = use->cu_bbox.r_ytop; edge.e_ybot = use->cu_bbox.r_ybot; edge.e_x = use->cu_bbox.r_xtop; edge.e_newx = use->cu_bbox.r_xtop + xmove; edge.e_ltype = PLOWTYPE_CELL; edge.e_rtype = PLOWTYPE_CELL; (void) (*plowPropagateProcPtr)(&edge); } } return (0); } magic-8.0.210/plow/plow.h0000664000175000001440000000363612027341350013574 0ustar timusers/* * plow.h -- * * Exported definitions for the plow module. * * ********************************************************************* * * 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. * * ********************************************************************* * * rcsid $Header: /usr/cvsroot/magic-8.0/plow/plow.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ */ #ifndef _PLOW_H #define _PLOW_H #include "utils/magic.h" /* Technology file clients */ extern int PlowTechInit(), PlowTechFinal(); extern bool PlowTechLine(); extern void PlowAfterTech(); /* Called by CmdPlow() */ extern bool Plow(); /* Debugging command procedure */ extern int PlowTest(); extern void PlowExtendJogHorizon(); /* Exported tile type masks */ extern TileTypeBitMask PlowFixedTypes; /* Non-stretchable types */ extern TileTypeBitMask PlowContactTypes; /* Contact types */ extern TileTypeBitMask PlowCoveredTypes; /* Types that cannot be * uncovered by plowing. */ extern TileTypeBitMask PlowDragTypes; /* Types that drag along * trailing min-width * material when they move. */ /* Jog horizon ("plow horizon" command) */ extern int PlowJogHorizon; /* TRUE if we should eliminate jogs after each plow operation */ extern bool PlowDoStraighten; #endif /* _PLOW_H */ magic-8.0.210/plow/plowInt.h0000644000175000001440000002176310751423606014255 0ustar timusers/* * plowInt.h -- * * Internal definitions for the plow module. * * ********************************************************************* * * 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. * * ********************************************************************* * * Needs to include: magic.h, geometry.h, tile.h * * rcsid $Header: /usr/cvsroot/magic-8.0/plow/plowInt.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ */ #ifndef _PLOWINT_H #define _PLOWINT_H #include "tiles/tile.h" /* * The following is a TileType used by plowing to refer to an * edge on the subcell plane. */ #define PLOWTYPE_CELL (TT_MAXTYPES - 1) /* --------------------------- Plowing rules -------------------------- */ /* * Plowing rules tables. (These are not the plowing forms of * design rules, but rather the procedures that apply those * rules). * * These are initialized by PlowInit after the technology * file has been read. Each entry in a rules table contains * two masks: rte_ltypes and rte_rtypes. If the type on the * LHS of an edge is in rte_ltypes, and the type on the RHS * is in rte_rtypes, the procedure rte_proc is applied. */ typedef struct { TileTypeBitMask rte_ltypes; /* Apply if LHS type is in this set */ TileTypeBitMask rte_rtypes; /* Apply if RHS type is in this set */ int rte_whichRules;/* See below */ int (*rte_proc)(); /* Procedure implementing rule */ char *rte_name; /* Name of rule (for debugging) */ } RuleTableEntry; #define MAXRULES 100 /* Ridiculously high */ #define RTE_NULL 0 /* Don't use any rules at all */ #define RTE_MINWIDTH 1 /* Use minimum width */ #define RTE_REALWIDTH 2 /* Use computed real widths */ #define RTE_SPACING 3 /* Use spacing rules */ #define RTE_NOSPACING 4 /* Only apply rule if there are no spacing * rules across this edge. */ extern RuleTableEntry *plowCurrentRule; /* For debugging */ /* ----------------------------- Edges -------------------------------- */ /* * An Edge describes the boundary between tiles of two different types. * It is used by shadow search to describe an edge it found, and also * to store edges in the edge queue (these latter along with their final * positions). * * If e_use is non-NULL, the "edge" is really the right-hand side of * a cell use. */ typedef struct edge { Rect e_rect; /* Rectangle describing the edge (see below) */ int e_pNum; /* Plane # in plowYankDef */ TileType e_ltype; /* Type of LHS of edge */ TileType e_rtype; /* Type of RHS of edge */ int e_flags; /* Miscellaneous flags: see below */ /* Non-NULL if this is a cell moving instead of a piece of geometry */ CellUse *e_use; /* Cell use to be moved */ /* Only used in the queue of edges to move */ struct edge *e_next; /* Next edge in list */ } Edge; /* Flags from above */ #define E_ISINITIAL 0x01 /* Edge was added from initial plow */ /* When an edge moves, it has an initial and final X position */ #define e_x e_rect.r_xbot /* Initial X coordinate */ #define e_newx e_rect.r_xtop /* Final X coordinate */ /* The top and bottom of an edge don't change during plowing */ #define e_ytop e_rect.r_ytop #define e_ybot e_rect.r_ybot extern CellDef *plowYankDef; /* Cell def containing planes above */ /* ----------------------- Outline searching -------------------------- */ /* * The following describes the outline of a boundary followed by * plowSrOutline(). * * The following structure also reflects the directions associated * with a particular edge in the outline of a collection of types. * It gives the direction from which we turned to follow the current * edge, the direction along which we are following the current edge, * and the direction we will turn for following the next edge along * the outline. * * All directions are one of: GEO_NORTH, GEO_WEST, GEO_SOUTH, GEO_EAST. * When facing the indicated direction, the material on the inside of * the region being followed is always to the left. */ typedef struct { Rect o_rect; /* Degenerate rectangle defining the * outline segment being processed. */ Tile *o_inside; /* Tile on inside of outline */ Tile *o_outside; /* Tile on outside of outline */ int o_pNum; /* Plane # on which outline was found */ int o_prevDir; /* Previous direction */ int o_currentDir; /* Direction following this segment */ int o_nextDir; /* Direction to be followed next */ /* Used only by plowSrOutline() */ TileTypeBitMask o_insideTypes; /* Mask of types inside the outline */ Tile *o_nextIn; /* Next inside tile */ Tile *o_nextOut; /* Next outside tile */ Rect o_nextRect; /* Next segment of boundary */ } Outline; /* Masks of directions */ #define GMaskHasDir(m, d) ((m & DirToGMask(d)) != 0) #define DirToGMask(d) (1 << (d)) #define GMASK_NORTH DirToGMask(GEO_NORTH) #define GMASK_SOUTH DirToGMask(GEO_SOUTH) #define GMASK_EAST DirToGMask(GEO_EAST) #define GMASK_WEST DirToGMask(GEO_WEST) /* ------------------- Leading and trailing edges --------------------- */ /* * The leading and trailing edge of a tile are the "new" positions * as determined by plowing, as opposed to the "initial" positions * still stored in LEFT and RIGHT. * * As with LEFT and RIGHT, only the trailing coordinate of a tile is * stored explicitly; the leading coordinate is the trailing coordinate * of the tile to its right. */ #define TRAIL_UNINIT CLIENTDEFAULT #define TRAILING(tp) (((tp)->ti_client == (ClientData)TRAIL_UNINIT) \ ? LEFT(tp) : ((int)(tp)->ti_client)) #define LEADING(tp) TRAILING(TR(tp)) #define plowSetTrailing(tp, n) ((tp)->ti_client = (ClientData) (n)) /* ------------------ Design rules used by plowing -------------------- */ /* * The following structure is used both for spacing rules and * for width rules. */ typedef struct prule { TileTypeBitMask pr_ltypes; /* Material to the left of the * outline of the LHS of the * penumbra. */ TileTypeBitMask pr_oktypes; /* Anything in the umbra or penumbra * not of this type must be pr_dist * away from the moving edge. */ int pr_dist; /* Distance associated with this * design rule. */ short pr_pNum; /* Plane on which to apply rule * (for spacing rules only). */ short pr_flags; /* See below */ struct prule *pr_next; /* Next rule in bucket */ } PlowRule; /* Flags */ #define PR_WIDTH 0x01 /* Spacing has this bit clear */ #define PR_PENUMBRAONLY 0x02 /* Apply rule only in penumbra */ #define PR_EDGE 0x04 /* Debugging: came from "edge" rule */ #define PR_EDGE4WAY 0x08 /* Debugging: came from "edge4way" rule */ #define PR_EDGEBACK 0x10 /* Debugging: backward part of "edge4way" */ extern PlowRule *plowSpacingRulesTbl[TT_MAXTYPES][TT_MAXTYPES]; extern PlowRule *plowWidthRulesTbl[TT_MAXTYPES][TT_MAXTYPES]; /* * Entry [t] of the following table is the maximum distance associated * with any design rules in a bucket with type 't' on the LHS. */ extern int plowMaxDist[TT_MAXTYPES]; /* --------------- Structure when applying plowing rules -------------- */ /* * Structure used by rules procedures for passing information * down to their filter functions. Not all rules fill in all * the information in this structure; see the comments in each * rule for details. */ struct applyRule { Edge *ar_moving; /* Edge being moved */ PlowRule *ar_rule; /* Plowing rule being applied */ /* Only used in penumbra */ Point ar_clip; /* Boundary of clipping rectangle */ /* Only used in slivers */ TileType ar_slivtype; /* Material in middle of sliver sandwich */ int ar_lastx; /* Rightmost X we've seen so far */ int ar_mustmove; /* Must move slivers this far right */ /* Only used with cells */ int ar_pNum; /* Plane being searched (area search only) */ Rect ar_search; /* Area being searched */ }; /* ----------------------- Internal procedures ------------------------ */ /* Procedure called when we've found a new edge to add */ extern int (*plowPropagateProcPtr)(); /* Other exports */ extern int plowQueueAdd(); extern bool plowQueueLeftmost(); extern bool plowQueueRightmost(); extern Tile *plowSplitY(); /* ------------------------- Debugging flags -------------------------- */ /* * The following come from a separate file so we can add more * debugging flags without forcing the entire system to be * recompiled. */ #include "plowDebugInt.h" #endif /* _PLOWINT_H */ magic-8.0.210/plow/PlowRandom.c0000644000175000001440000001774010751423606014676 0ustar timusers/* * PlowRandom.c -- * * Plowing. * Random testing: generate a whole bunch of random plows * and make sure each one produces a design-rule-correct * result that has the same extracted circuit (minus the * parasitics) as the initial cell. * * ********************************************************************* * * 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/plow/PlowRandom.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include #include #include #ifdef SYSV #include #endif #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "plow/plowInt.h" #include "textio/textio.h" #include "utils/undo.h" #include "utils/signals.h" #include "extract/extract.h" /* Imports from PlowMain.c */ extern CellDef *plowYankDef; /* Forward declarations */ int plowFindFirstError(); void plowGenRect(); /* * ---------------------------------------------------------------------------- * * PlowRandomTest -- * * Random testing: generate a whole bunch of random plows * and make sure each one produces a design-rule-correct * result that has the same extracted circuit (minus the * parasitics) as the initial cell. * * Output the coordinates and direction of each plow as * we go, flagging it as one producing a DRC violation * or a connectivity violation as we go. * * Results: * None. * * Side effects: * Writes a whole bunch of information via TxPrintf(), * as described above. * * ---------------------------------------------------------------------------- */ void PlowRandomTest(def) CellDef *def; { #ifdef notdef static char *tempgood = "/tmp/PlowGoodaXXXXX"; static char *temptemp = "/tmp/PlowTempaXXXXX"; char goodName[64], tempName[64], goodExt[64], tempExt[64]; char command[256]; #endif /* notdef */ static int dirs[] = { GEO_NORTH, GEO_SOUTH, GEO_EAST, GEO_WEST }; static char *dirnames[] = { "up", "down", "right", "left" }; Rect plowRect; int dir, plowDir; #ifdef notdef strcpy(goodName, tempgood); strcpy(tempName, temptemp); mkstemp(goodName); mkstemp(tempName); sprintf(goodExt, "%s.ext", goodName); sprintf(tempExt, "%s.ext", tempName); /* Generate "good" extracted file */ ExtCell(def, goodName, FALSE); (void) sprintf(command, "sedplow %s", goodExt); system(command); #endif /* notdef */ /* Repeatedly try to break plowing */ while (!SigInterruptPending) { /* Generate a random plow direction and rectangle */ dir = plowGenRandom(0, 3); plowDir = dirs[dir]; plowGenRect(&def->cd_bbox, &plowRect); (void) Plow(def, &plowRect, DBAllTypeBits, plowDir); TxPrintf("%s %d %d %d %d\n", dirnames[dir], plowRect.r_xbot, plowRect.r_ybot, plowRect.r_xtop, plowRect.r_ytop); TxFlush(); /* Finish the design-rule check and count any errors */ DRCCatchUp(); if (DBSrPaintArea((Tile *) NULL, def->cd_planes[PL_DRC_ERROR], &def->cd_bbox, &DBAllButSpaceBits, plowFindFirstError, (ClientData) NULL)) { TxPrintf("%s %d %d %d %d: DRC error\n", dirnames[dir], plowRect.r_xbot, plowRect.r_ybot, plowRect.r_xtop, plowRect.r_ytop); TxFlush(); } /* Turn off the modified bit so we get the same timestamp */ def->cd_flags &= ~CDMODIFIED; #ifdef notdef /* Extract to the temp file */ ExtCell(def, tempName, FALSE); (void) sprintf(command, "sedplow %s", tempExt); system(command); /* Check for any differences */ if (plowFileDiff(goodExt, tempExt)) { TxPrintf("%s %d %d %d %d: EXT error\n", dirnames[dir], plowRect.r_xbot, plowRect.r_ybot, plowRect.r_xtop, plowRect.r_ytop); TxFlush(); } #endif /* notdef */ /* Make sure there's always something to undo */ DBPutLabel(def, &def->cd_bbox, -1, "dummylabel", TT_SPACE, 0); /* Undo */ UndoBackward(1); } #ifdef notdef (void) unlink(goodExt); (void) unlink(tempExt); #endif /* notdef */ } /* * ---------------------------------------------------------------------------- * * plowFindFirstError -- * * Filter procedure called via DBSrPaintArea by PlowRandomTest() * above, on the PL_DRC_ERROR plane, looking for non-space tiles. * * Results: * Returns 1 always, to force DBSrPaintArea to abort and * return 1. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ int plowFindFirstError() { return (1); } /* * ---------------------------------------------------------------------------- * * plowGenRect -- * * Generate a random plow rectangle. * This rectangle is guaranteed to lie within the bounding box of * the cell. The four coordinates are chosen randomly from a uniform * distribution, and then the rectangle is flipped to insure that its * upper-right is above and to the right of its lower-left. * * Results: * None. * * Side effects: * Fills in the rectangle pointed to by 'r'. * * ---------------------------------------------------------------------------- */ void plowGenRect(bbox, r) Rect *bbox; /* Bounding box of the cell being plowed */ Rect *r; /* Fill in this rectangle */ { int temp; r->r_xbot = plowGenRandom(bbox->r_xbot, bbox->r_xtop); r->r_xtop = plowGenRandom(bbox->r_xbot, bbox->r_xtop); r->r_ybot = plowGenRandom(bbox->r_ybot, bbox->r_ytop); r->r_ytop = plowGenRandom(bbox->r_ybot, bbox->r_ytop); if (r->r_xbot == r->r_xtop) r->r_xtop = r->r_xbot + 1; if (r->r_ybot == r->r_ytop) r->r_ytop = r->r_ybot + 1; if (r->r_xbot > r->r_xtop) { temp = r->r_xtop; r->r_xtop = r->r_xbot; r->r_xbot = temp; } if (r->r_ybot > r->r_ytop) { temp = r->r_ytop; r->r_ytop = r->r_ybot; r->r_ybot = temp; } } /* * ---------------------------------------------------------------------------- * * plowGenRandom -- * * Generate a random integer chosen from the integers lo, lo+1, ..., hi, * with each integer having equal probability. * * Results: * Returns the integer described above. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ int plowGenRandom(lo, hi) int lo, hi; /* Inclusive bounds for the integer we'll generate */ { int range = hi - lo + 1; #ifdef SYSV int r = rand(); #else int r = random(); #endif /* SYSV */ return ((r % range) + lo); } /* * ---------------------------------------------------------------------------- * * plowFileDiff -- * * Compare two files for equality. * * Results: * Returns TRUE if they are identical and the same length, * FALSE if they differ. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool plowFileDiff(file1, file2) char *file1; char *file2; { char b1[BUFSIZ], b2[BUFSIZ]; int f1, f2; int n1, n2; bool ret = FALSE; if ((f1 = open(file1, O_RDONLY, 0)) < 0) goto done; if ((f2 = open(file2, O_RDONLY, 0)) < 0) goto done; while ((n1 = read(f1, b1, BUFSIZ)) > 0) { n2 = read(f2, b2, BUFSIZ); if (n1 != n2 || bcmp(b1, b2, n1) != 0) goto done; } ret = TRUE; done: (void) close(f1); (void) close(f2); return (ret); } magic-8.0.210/plow/PlowSearch.c0000644000175000001440000010524710751423606014663 0ustar timusers/* * PlowSearch.c -- * * Plowing. * Shadow and other searches. * * ********************************************************************* * * 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/plow/PlowSearch.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "plow/plowInt.h" #include "utils/stack.h" #include "textio/textio.h" /* Argument used in shadow search */ struct shadow { Rect s_area; /* Area being searched */ TileTypeBitMask s_okTypes; /* Complement of this set is the RHS * boundary of the shadow. */ Edge s_edge; /* Edge being built up */ int (*s_proc)(); /* Filter procedure */ ClientData s_cdata; /* Additional argument to (*s_proc)() */ }; /* Stack used by plowSrOutline */ Stack *plowOutlineStack = NULL; #define FLUSHSTACK(s) while (STACKLOOK(s)) (void) STACKPOP(s) /* Outline tracing: is tile inside the outline */ #define IsInside(tp, out) TTMaskHasType(&(out)->o_insideTypes, TiGetTypeExact(tp)) /* Forward declarations */ extern void plowSrOutlineInit(); extern void plowSrOutlineNext(); /* * ---------------------------------------------------------------------------- * * EXTENDOUTLINE -- * * EXTENDOUTLINE(outline) * Outline *outline; * { * } * * Used to extend outline->o_nextRect in the direction being followed, * based on the tiles outline->o_nextIn and outline->o_nextOut. * * Assumes that outline->o_nextRect is initially a degenerate box equal * to the starting point of the segment. We update exactly one coordinate * of outline->o_nextRect, depending on the direction outline->o_nextDir: * * GEO_NORTH r_ytop * GEO_SOUTH r_ybot * GEO_EAST r_xtop * GEO_WEST r_xbot * * Results: * None. * * Side effects: * Updates outline->o_nextRect as described above. * * ---------------------------------------------------------------------------- */ #define EXTENDOUTLINE(o) { \ Tile *in = (o)->o_nextIn; \ Tile *out = (o)->o_nextOut; \ switch ((o)->o_nextDir) \ { \ case GEO_NORTH: (o)->o_nextRect.r_ytop=MIN(TOP(out),TOP(in)); break; \ case GEO_SOUTH: (o)->o_nextRect.r_ybot=MAX(BOTTOM(out),BOTTOM(in)); break; \ case GEO_EAST: (o)->o_nextRect.r_xtop=MIN(RIGHT(in),RIGHT(out)); break; \ case GEO_WEST: (o)->o_nextRect.r_xbot=MAX(LEFT(in),LEFT(out)); break; \ } \ } /* * ---------------------------------------------------------------------------- * * STACKOUTLINE -- * * STACKOUTLINE(outline) * Outline *outline; * * Called whenever we advance to a new inside/outside tile to * load the tile stack with the tiles on the opposite side of * the tile we just advanced to. * * The tile stack contains all the tiles along the outside of * outline->o_nextIn if we are going up or down, or all the * tiles along the inside of outline->o_nextOut if we are going * going left or right. * * Flushes the tile stack before we push any tiles of our own. * * Results: * None. * * Side effects: * May push tiles on plowOutlineStack. * Sets outline->o_nextIn if going east or west. * Sets outline->o_nextOut if going north or south. * * ---------------------------------------------------------------------------- */ #define STACKOUTLINE(o) { \ Tile *tp; \ \ FLUSHSTACK(plowOutlineStack); \ switch ((o)->o_nextDir) \ { \ case GEO_NORTH: \ for (tp = TR((o)->o_nextIn); \ BOTTOM(tp) > (o)->o_nextRect.r_ybot; tp = LB(tp)) \ STACKPUSH((ClientData) tp, plowOutlineStack); \ (o)->o_nextOut = tp; \ break; \ case GEO_SOUTH: \ for (tp = BL((o)->o_nextIn); \ TOP(tp) < (o)->o_nextRect.r_ytop; tp = RT(tp)) \ STACKPUSH((ClientData) tp, plowOutlineStack); \ (o)->o_nextOut = tp; \ break; \ case GEO_EAST: \ for (tp = RT((o)->o_nextOut); \ LEFT(tp) > (o)->o_nextRect.r_xbot; tp = BL(tp)) \ STACKPUSH((ClientData) tp, plowOutlineStack); \ (o)->o_nextIn = tp; \ break; \ case GEO_WEST: \ for (tp = LB((o)->o_nextOut); \ RIGHT(tp) < (o)->o_nextRect.r_xtop; tp = TR(tp)) \ STACKPUSH((ClientData) tp, plowOutlineStack); \ (o)->o_nextIn = tp; \ break; \ } \ } /* * ---------------------------------------------------------------------------- * * plowSrShadow -- * * Shadow search. * Searches area from left to right for edges whose far side is not in * okTypes. The edges we find will have exactly one tile on each side. * * This is similar to an area search, except we call the procedure with * edges instead of tiles: * * (*proc)(edge, cdata) * Edge *edge; * ClientData cdata; * { * } * * The Edge specifies the initial X location of the edge (e_x), the final * X location (e_newx, taken from the TRAILING coordinate of the tile on the * edge's right-hand side), and the edge's top and bottom (e_ytop, e_ybot). * It also contains the plane on which this edge was found (our argument * 'plane'), and the types of the tiles on each side of the edge (e_ltype * and e_rtype). * * The client is allowed to modify e_newx, but none of the other fields * of the Edge. * * If the procedure returns 1, we abort the shadow search. * * Results: * Returns 1 if aborted, 0 if the search completed normally. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ int plowSrShadow(pNum, area, okTypes, proc, cdata) int pNum; /* Plane from plowYankDef to search */ Rect *area; /* Area to search. Edges coincident with the * right-hand side of this area are not seen; * they must lie to the left of area->r_xtop. */ TileTypeBitMask okTypes; int (*proc)(); /* Function to apply at each edge */ ClientData cdata; /* Additional argument to pass to (*proc)() */ { Plane *plane = plowYankDef->cd_planes[pNum]; struct shadow s; Tile *tp; int bottom, ret; Point p; ret = 0; /* Copy our arguments into 's' */ s.s_area = *area; s.s_okTypes = okTypes; s.s_proc = proc; s.s_cdata = cdata; s.s_edge.e_use = (CellUse *) NULL; s.s_edge.e_flags = 0; s.s_edge.e_pNum = pNum; s.s_edge.e_ytop = s.s_area.r_ytop; /* Walk along the LHS of the sweep area from top to bottom */ p.p_x = s.s_area.r_xbot; p.p_y = s.s_area.r_ytop - 1; tp = plane->pl_hint; while (p.p_y >= s.s_area.r_ybot) { /* Find the next tile along the LHS of the sweep area */ GOTOPOINT(tp, &p); p.p_y = BOTTOM(tp) - 1; bottom = MAX(BOTTOM(tp), s.s_area.r_ybot); if (RIGHT(tp) >= s.s_area.r_xtop) { s.s_edge.e_ytop = bottom; } else if (plowShadowRHS(tp, &s, bottom)) { ret = 1; break; } } plane->pl_hint = tp; return (ret); } /* * ---------------------------------------------------------------------------- * * plowShadowRHS -- * * Walk along the right-hand side of tile 'tp', enumerating all edges formed * with tiles whose RHS is not a member of s->s_okTypes, and whose tops are * larger than 'bottomLeft'. * * Results: * Returns 0 normally, but returns 1 if a client decided to * interrupt the search by returning 1. * * Side effects: * May call the filter function. * Modifies s->s_edge. * * ---------------------------------------------------------------------------- */ int plowShadowRHS(tp, s, bottomLeft) Tile *tp; /* Tile whose RHS is to be followed */ struct shadow *s; /* Shadow search argument */ int bottomLeft; /* Bottom of 'tp', clipped to area */ { Tile *tpR; int bottom, left; /* Walk along the RHS of 'tp' from top to bottom */ tpR = TR(tp), left = LEFT(tpR); do { /* * Only process tiles between s->s_edge.e_ytop (on the top) * and bottomLeft (on the bottom). */ bottom = MAX(bottomLeft, BOTTOM(tpR)); if (bottom < s->s_edge.e_ytop) { /* If tpR is not in okTypes, pass the edge to the client function */ if (!TTMaskHasType(&s->s_okTypes, TiGetTypeExact(tpR))) { /* Left, right hand types */ s->s_edge.e_ltype = TiGetTypeExact(tp); s->s_edge.e_rtype = TiGetTypeExact(tpR); /* Coordinates */ s->s_edge.e_x = left; s->s_edge.e_newx = TRAILING(tpR); s->s_edge.e_ybot = bottom; if ((*s->s_proc)(&s->s_edge, s->s_cdata)) return (1); /* Skip to bottom of the edge we just processed */ s->s_edge.e_ytop = s->s_edge.e_ybot; } else if (RIGHT(tpR) >= s->s_area.r_xtop) { /* Skip this edge segment */ s->s_edge.e_ytop = bottom; } else { if (plowShadowRHS(tpR, s, bottom)) return (1); /* Here s->s_edge.e_ytop == bottom */ } } tpR = LB(tpR); } while (TOP(tpR) > bottomLeft); return (0); } /* * ---------------------------------------------------------------------------- * * plowSrShadowInitial -- * * Shadow search. * Searches area from left to right for edges whose far side is not in * okTypes, or whose near side is not in okTypes, and for which both * sides are different types. * * See plowSrShadow() above for more details. * * Results: * Returns 1 if aborted, 0 if the search completed normally. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ int plowSrShadowInitial(pNum, area, okTypes, proc, cdata) int pNum; /* Plane from plowYankDef to search */ Rect *area; /* Area to search. Edges coincident with the * right-hand side of this area are not seen; * they must lie to the left of area->r_xtop. */ TileTypeBitMask okTypes; int (*proc)(); /* Function to apply at each edge */ ClientData cdata; /* Additional argument to pass to (*proc)() */ { Plane *plane = plowYankDef->cd_planes[pNum]; struct shadow s; Tile *tp; int bottom, ret; Point p; ret = 0; /* Copy our arguments into 's' */ s.s_area = *area; s.s_okTypes = okTypes; s.s_proc = proc; s.s_cdata = cdata; s.s_edge.e_use = (CellUse *) NULL; s.s_edge.e_flags = 0; s.s_edge.e_pNum = pNum; s.s_edge.e_ytop = s.s_area.r_ytop; /* Walk along the LHS of the sweep area from top to bottom */ p.p_x = s.s_area.r_xbot; p.p_y = s.s_area.r_ytop - 1; tp = plane->pl_hint; while (p.p_y >= s.s_area.r_ybot) { /* Find the next tile along the LHS of the sweep area */ GOTOPOINT(tp, &p); p.p_y = BOTTOM(tp) - 1; bottom = MAX(BOTTOM(tp), s.s_area.r_ybot); if (RIGHT(tp) >= s.s_area.r_xtop) { s.s_edge.e_ytop = bottom; } else if (plowShadowInitialRHS(tp, &s, bottom)) { ret = 1; break; } } plane->pl_hint = tp; return (ret); } /* * ---------------------------------------------------------------------------- * * plowShadowInitialRHS -- * * Walk along the right-hand side of tile 'tp', enumerating all edges formed * with tiles whose RHS is not a member of s->s_okTypes, or whose LHS is not * a member of s->s_okTypes, and whose LHS and RHS are different, and whose * tops are larger than 'bottomLeft'. * * Results: * Returns 0 normally, but returns 1 if a client decided to * interrupt the search by returning 1. * * Side effects: * May call the filter function. * Modifies s->s_edge. * * ---------------------------------------------------------------------------- */ int plowShadowInitialRHS(tp, s, bottomLeft) Tile *tp; /* Tile whose RHS is to be followed */ struct shadow *s; /* Shadow search argument */ int bottomLeft; /* Bottom of 'tp', clipped to area */ { Tile *tpR; int bottom, left; /* Walk along the RHS of 'tp' from top to bottom */ tpR = TR(tp), left = LEFT(tpR); do { /* * Only process tiles between s->s_edge.e_ytop (on the top) * and bottomLeft (on the bottom). */ bottom = MAX(bottomLeft, BOTTOM(tpR)); if (bottom < s->s_edge.e_ytop) { /* If tpR is not in okTypes, pass the edge to the client function */ if (TiGetTypeExact(tp) != TiGetTypeExact(tpR) && (!TTMaskHasType(&s->s_okTypes, TiGetTypeExact(tpR)) || !TTMaskHasType(&s->s_okTypes, TiGetTypeExact(tp)))) { /* Left, right hand types */ s->s_edge.e_ltype = TiGetTypeExact(tp); s->s_edge.e_rtype = TiGetTypeExact(tpR); /* Coordinates */ s->s_edge.e_x = left; s->s_edge.e_newx = TRAILING(tpR); s->s_edge.e_ybot = bottom; if ((*s->s_proc)(&s->s_edge, s->s_cdata)) return (1); /* Skip to bottom of the edge we just processed */ s->s_edge.e_ytop = s->s_edge.e_ybot; } else if (RIGHT(tpR) >= s->s_area.r_xtop) { /* Skip this edge segment */ s->s_edge.e_ytop = bottom; } else { if (plowShadowRHS(tpR, s, bottom)) return (1); /* Here s->s_edge.e_ytop == bottom */ } } tpR = LB(tpR); } while (TOP(tpR) > bottomLeft); return (0); } /* * ---------------------------------------------------------------------------- * * plowSrShadowBack -- * * Shadow search, backwards. * Searches area from right to left for edges whose far side is not in * okTypes. The edges we find will have exactly one tile on each side. * * See the comments in plowSrShadow() for details on the client procedure. * * Results: * Returns 1 if aborted, 0 if the search completed normally. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ int plowSrShadowBack(pNum, area, okTypes, proc, cdata) int pNum; /* Plane from plowYankDef to search */ Rect *area; /* Area to search. Edges coincident with the * left-hand side of this area are not seen; * they must lie to the right of area->r_xbot. */ TileTypeBitMask okTypes; int (*proc)(); /* Function to apply at each edge */ ClientData cdata; /* Additional argument to pass to (*proc)() */ { Plane *plane = plowYankDef->cd_planes[pNum]; struct shadow s; Tile *tp; int top, ret; Point p; ret = 0; /* Copy our arguments into 's' */ s.s_area = *area; s.s_okTypes = okTypes; s.s_proc = proc; s.s_cdata = cdata; s.s_edge.e_use = (CellUse *) NULL; s.s_edge.e_flags = 0; s.s_edge.e_pNum = pNum; s.s_edge.e_ybot = s.s_area.r_ybot; /* Walk along the RHS of the sweep area from bottom to top */ p.p_x = s.s_area.r_xtop - 1; p.p_y = s.s_area.r_ybot; tp = plane->pl_hint; while (p.p_y < s.s_area.r_ytop) { /* Find the next tile along the RHS of the sweep area */ GOTOPOINT(tp, &p); p.p_y = TOP(tp); top = MIN(TOP(tp), s.s_area.r_ytop); if (LEFT(tp) <= s.s_area.r_xbot) { s.s_edge.e_ybot = top; } else if (plowShadowLHS(tp, &s, top)) { ret = 1; break; } } /* if ret = 1 then tp may point to an invalid tile --- Tim 6/15/01 */ if (!ret) plane->pl_hint = tp; return (ret); } /* * ---------------------------------------------------------------------------- * * plowShadowLHS -- * * Walk along the left-hand side of tile 'tp', enumerating all edges formed * with tiles whose LHS is not a member of s->s_okTypes, and whose bottoms are * less than 'topRight'. * * Results: * Returns 0 normally, but returns 1 if a client decided to * interrupt the search by returning 1. * * Side effects: * May call the filter function. * Modifies s->s_edge. * * ---------------------------------------------------------------------------- */ int plowShadowLHS(tp, s, topRight) Tile *tp; /* Tile whose LHS is to be followed */ struct shadow *s; /* Shadow search argument */ int topRight; /* Top of 'tp', clipped to area */ { Tile *tpL; int top, right; /* Walk along the LHS of 'tp' from bottom to top */ tpL = BL(tp), right = RIGHT(tpL); do { /* * Only process tiles between s->s_edge.e_ybot (on the bottom) * and topRight (on the top). */ top = MIN(topRight, TOP(tpL)); if (top > s->s_edge.e_ybot) { /* If tpL is not in okTypes, pass the edge to the client function */ if (!TTMaskHasType(&s->s_okTypes, TiGetTypeExact(tpL))) { /* Left, right hand types */ s->s_edge.e_ltype = TiGetTypeExact(tpL); s->s_edge.e_rtype = TiGetTypeExact(tp); /* Coordinates */ s->s_edge.e_x = right; s->s_edge.e_newx = TRAILING(tp); s->s_edge.e_ytop = top; if ((*s->s_proc)(&s->s_edge, s->s_cdata)) return (1); /* Skip to top of the edge we just processed */ s->s_edge.e_ybot = s->s_edge.e_ytop; } else if (LEFT(tpL) <= s->s_area.r_xbot) { /* Skip this edge segment */ s->s_edge.e_ybot = top; } else { if (plowShadowLHS(tpL, s, top)) return (1); /* Here s->s_edge.e_ybot == top */ } } tpL = RT(tpL); } while (BOTTOM(tpL) < topRight); return (0); } /* * ---------------------------------------------------------------------------- * * plowAtomize -- * * Given a geometrical edge (the LHS of the rectangle 'rect'), call * (*proc)() for each real Edge (between two tiles) found along * the geometrical edge. Each Edge added will have a new x value of * rect->r_xtop. * * The procedure (*proc)() should be the same kind (in arguments and * return value) as that used in plowSrShadow() above. * * Don't call the procedure if the final coordinate of the tiles along * a given Edge is already farther right than rect->r_xtop. * * Results: * Returns 1 if (*proc)() returned 1 to abort the atomizing; * otherwise, returns 0. * * Side effects: * Whatever the client procedure has. * * ---------------------------------------------------------------------------- */ int plowAtomize(pNum, rect, proc, cdata) int pNum; /* Plane from plowYankDef to search */ Rect *rect; /* LHS is the geometrical edge we search; each * Edge found will have an e_newx coordinate * equal to the RHS of this rect. */ int (*proc)(); /* Procedure to apply to each Edge */ ClientData cdata; /* Additional argument to (*proc)() */ { Tile *tpL, *tpR; Plane *plane = plowYankDef->cd_planes[pNum]; Point startPoint; Edge edge; int ytop; edge.e_x = rect->r_xbot; edge.e_newx = rect->r_xtop; edge.e_use = (CellUse *) NULL; edge.e_flags = 0; edge.e_pNum = pNum; ytop = rect->r_ytop; startPoint.p_x = rect->r_xbot; startPoint.p_y = rect->r_ytop - 1; /* Walk down the RHS of the edge */ tpR = plane->pl_hint; GOTOPOINT(tpR, &startPoint); plane->pl_hint = tpR; for ( ; TOP(tpR) > rect->r_ybot; tpR = LB(tpR)) { /* Only process edges that haven't moved far enough */ if (TRAILING(tpR) < rect->r_xtop) { edge.e_rtype = TiGetTypeExact(tpR); edge.e_ybot = MAX(BOTTOM(tpR), rect->r_ybot); /* Walk up the LHS of the edge */ for (tpL = BL(tpR); BOTTOM(tpL) < ytop; tpL = RT(tpL)) { /* Only process edges above the bottom of the clip area */ if (TOP(tpL) > edge.e_ybot) { edge.e_ytop = MIN(ytop, TOP(tpL)); edge.e_ltype = TiGetTypeExact(tpL); if ((*proc)(&edge, cdata)) return (1); edge.e_ybot = edge.e_ytop; } } } /* Advance the top of the clipping are downward */ ytop = BOTTOM(tpR); } return (0); } /* * ---------------------------------------------------------------------------- * * plowSrOutline -- * * Outline enumeration. * This procedure follows the outline of a collection of materials in a * counter-clockwise direction. For each edge found while moving in a * direction specified in dirMask, call a supplied client procedure: * * (*proc)(outline, cdata) * Outline *outline; * ClientData cdata; * { * } * * The bits in dirMask are GMASK_SOUTH, GMASK_NORTH, GMASK_EAST, * or GMASK_WEST. They may be or'd together in any combination. * * The Outline gives a degenerate rectangle for this segment of the * outline. Either this rectangle has zero height, or zero width. * It also contains the plane on which this segment was found (our * argument 'plane'), and pointers to the tiles on each side of the * outline (o_inside, o_outside). Finally, it contains the direction * followed before this segment (o_prevDir), the direction being * followed along this segment (o_currentDir), and the direction to * be followed after this segment (o_nextDir). * * If the procedure returns 1, we abort the outline enumeration. * Otherwise, we keep going indefinitely. * * Results: * None. * * Side effects: * Whatever occur as a result of applying the supplied client * procedure. * * Assumptions: * The interior of the region whose perimeter is being traced * cannot extend to infinity in any direction. Hence it is unwise * to try tracing the perimeter of a region consisting of empty * space, unless the client can be counted on to abort the search * by returning 1. * * ---------------------------------------------------------------------------- */ void plowSrOutline(pNum, startPoint, insideTypes, initialDir, dirMask, proc, cdata) int pNum; /* Plane # in plowYankDef to search */ Point *startPoint; /* Point on boundary; material of types * in insideTypes should be to the * inside (as determined by initialDir * below). */ TileTypeBitMask insideTypes; /* Mask of types inside the region * whose outline is being traced. */ int initialDir; /* Initial direction to go from the * starting point. One of GEO_NORTH, * or GEO_SOUTH. */ int dirMask; /* Mask of those directions for which * we will call the client procedure. */ int (*proc)(); /* Client procedure */ ClientData cdata; /* Argument to client procedure */ { Outline outline; /* * Initialize the stack used for processing tiles * along the outside of the perimeter. */ if (plowOutlineStack == (Stack *) NULL) plowOutlineStack = StackNew(50); /* * Push a bottom marker on the stack. * This allows plowSrOutline to be re-entrant. */ STACKPUSH((ClientData) NULL, plowOutlineStack); /* * Start out going in the direction specified by initialDir. * This direction is really just a hint; we may go either 90 degrees * to the left or to the right if appropriate. */ outline.o_pNum = pNum; outline.o_insideTypes = insideTypes; outline.o_currentDir = initialDir; outline.o_rect.r_ll = outline.o_rect.r_ur = *startPoint; plowSrOutlineInit(&outline); EXTENDOUTLINE(&outline); /* * Now we have found the initial segment and are ready for the main loop. * On entry to each iteration of this loop, o_currentDir and o_nextDir * are set from the previous iteration; we advance by one (current becomes * prev, next becomes current) and find the next direction, etc. before * calling the client procedure. */ for (;;) { /* Advance along the boundary */ outline.o_prevDir = outline.o_currentDir; outline.o_currentDir = outline.o_nextDir; outline.o_inside = outline.o_nextIn; outline.o_outside = outline.o_nextOut; outline.o_rect = outline.o_nextRect; /* Find outline.o_nextDir and next two tiles along boundary */ plowSrOutlineNext(&outline); EXTENDOUTLINE(&outline); /* Now we know the next direction: apply the filter procedure */ if (GMaskHasDir(dirMask, outline.o_currentDir)) if ((*proc)(&outline, cdata)) break; } /* Flush anything remaining on the stack */ while (STACKPOP(plowOutlineStack) != (ClientData) NULL) /* Nothing */; } /* * ---------------------------------------------------------------------------- * * plowSrOutlineInit -- * * Initialization for outline enumeration. * Find the first edge in outline enumeration. * On entry, o_rect should be degenerate (ll == ur) around the starting * point for the search. This starting point should be on the outline. * The direction o_currentDir should be one of GEO_NORTH or GEO_SOUTH; we * pretend as though we arrived at the starting point from this direction. * * Results: * None. * * Side effects: * Fills in fields of 'outline': * o_nextIn, o_nextOut -- tiles on inside and outside of * current edge. * o_nextDir -- direction of current edge; this will * differ by at most 90 degrees from * o_currentDir. * o_nextRect -- current edge itself. * * ---------------------------------------------------------------------------- */ void plowSrOutlineInit(outline) Outline *outline; { Plane *plane = plowYankDef->cd_planes[outline->o_pNum]; Tile *in, *out; Point p; outline->o_nextDir = outline->o_currentDir; outline->o_nextRect = outline->o_rect; switch (outline->o_nextDir) { case GEO_NORTH: /* * Find the tiles on either side of the starting point (+): * * | * in | out * --------+-------- * | * | * * It is possible for 'in' and 'out' to be the same tile. */ out = plane->pl_hint; p = outline->o_rect.r_ll; GOTOPOINT(out, &p); p.p_x--; in = out; GOTOPOINT(in, &p); if (!IsInside(in, outline)) { /* * Tile 'in' is really outside the outline, so go left. * We know that BOTTOM(in) == outline->o_rect.r_xbot because * the starting point is on the outline. We want: * | * out | * --------+-------- * in | * | */ outline->o_nextDir = GEO_WEST; outline->o_nextOut = in; } else if (IsInside(out, outline)) { /* * Tile 'out' is really inside the outline, so go right. * We know that TOP(out) == outline->o_rect.r_xbot because * the starting point is on the outline. We want: * | * | in * --------+-------- * | out * | */ outline->o_nextDir = GEO_EAST; for (out = LB(out); RIGHT(out) <= outline->o_rect.r_xbot; out = TR(out)) /* Nothing */; outline->o_nextOut = out; } else { /* * Tile 'in' is really inside the outline, and tile 'out' * is really outside, so we already are where we want to be. */ outline->o_nextIn = in; } break; case GEO_SOUTH: /* * Find the tiles on either side of the starting point (+): * * | * | * --------+-------- * out | in * | * * It is possible for 'in' and 'out' to be the same tile. */ p.p_x = outline->o_rect.r_xbot - 1; p.p_y = outline->o_rect.r_ybot - 1; out = plane->pl_hint; GOTOPOINT(out, &p); p.p_x++; in = out; GOTOPOINT(in, &p); if (!IsInside(in, outline)) { /* * Tile 'in' is really outside the outline, so go right. * We know that TOP(in) == outline->o_rect.r_xbot because * the starting point is on the outline. We want: * | * | in * --------+-------- * | out * | */ outline->o_nextDir = GEO_EAST; outline->o_nextOut = in; } else if (IsInside(out, outline)) { /* * Tile 'out' is really inside the outline, so go left. * We know that TOP(out) == outline->o_rect.r_xbot because * the starting point is on the outline. We want: * | * out | * --------+-------- * in | * | */ outline->o_nextDir = GEO_WEST; for (out = RT(out); LEFT(out) >= outline->o_rect.r_xbot; out = BL(out)) /* Nothing */; outline->o_nextOut = out; } else { /* * Tile 'in' is really inside the outline, and tile 'out' * is really outside, so we already are where we want to be. */ outline->o_nextIn = in; } break; default: TxError("Illegal initialDir (%d) for plowSrOutline\n", outline->o_nextDir); niceabort(); return; } STACKOUTLINE(outline); } /* * ---------------------------------------------------------------------------- * * plowSrOutlineNext -- * * Find the next edge in outline enumeration. * * Results: * None. * * Side effects: * Fills in fields of 'outline': * o_nextIn, o_nextOut -- tiles on inside and outside of * next edge. * o_nextDir -- direction of next edge. * o_nextRect -- next edge's rectangle * * ---------------------------------------------------------------------------- */ void plowSrOutlineNext(outline) Outline *outline; { Tile *tpL, *tpR; /* * Initialize the "next" segment to be the degenerate * endpoint of the current segment. */ outline->o_nextDir = outline->o_currentDir; switch (outline->o_currentDir) { case GEO_NORTH: case GEO_EAST: outline->o_nextRect.r_ur = outline->o_rect.r_ur; outline->o_nextRect.r_ll = outline->o_rect.r_ur; break; case GEO_SOUTH: case GEO_WEST: outline->o_nextRect.r_ur = outline->o_rect.r_ll; outline->o_nextRect.r_ll = outline->o_rect.r_ll; break; } /* * If the tile stack was not yet empty, we do things the * easy way. Advance to the next tile along the side of * the one inside (if going north/south) or the one outside * (if going east/west). */ if (STACKLOOK(plowOutlineStack)) { switch (outline->o_currentDir) { /* * Heading north. * * | nextOut * nextIn +-------- * | outside * * Turn east if nextOut is in o_insideTypes. * Otherwise, keep going north. */ case GEO_NORTH: outline->o_nextOut = (Tile *) STACKPOP(plowOutlineStack); if (IsInside(outline->o_nextOut, outline)) { outline->o_nextOut = LB(outline->o_nextOut); outline->o_nextDir = GEO_EAST; } break; /* * Heading south. * * outside | * --------+ nextIn * nextOut | * * Turn west if nextOut is in o_insideTypes. * Otherwise, keep going south. */ case GEO_SOUTH: outline->o_nextOut = (Tile *) STACKPOP(plowOutlineStack); if (IsInside(outline->o_nextOut, outline)) { outline->o_nextOut = RT(outline->o_nextOut); outline->o_nextDir = GEO_WEST; } break; /* * Heading east. * * inside | nextIn * --------+-------- * nextOut * * Turn north if nextIn is not in o_insideTypes. * Otherwise, keep going east. */ case GEO_EAST: outline->o_nextIn = (Tile *) STACKPOP(plowOutlineStack); if (!IsInside(outline->o_nextIn, outline)) { outline->o_nextIn = BL(outline->o_nextIn); outline->o_nextDir = GEO_NORTH; } break; /* * Heading west. * * nextOut * --------+-------- * nextIn | inside * * Turn south if nextIn is not in o_insideTypes. * Otherwise, keep going west. */ case GEO_WEST: outline->o_nextIn = (Tile *) STACKPOP(plowOutlineStack); if (!IsInside(outline->o_nextIn, outline)) { outline->o_nextIn = TR(outline->o_nextIn); outline->o_nextDir = GEO_SOUTH; } break; } /* * Stack a new set of tiles along the opposite side if * we changed direction, and set the appropriate one of * o_nextIn (if going east/west) or o_nextOut (if going * north/south). */ if (outline->o_nextDir != outline->o_currentDir) STACKOUTLINE(outline); return; } /* * The tile stack was empty, so we must advance the primary * tile (inside for north/south, outside for east/west). * This code is more complex than that above, because we * have three choices: continue going straight ahead, turn * left, or turn right. */ switch (outline->o_currentDir) { /* * Heading north. * * tpL tpR * --------+ * nextIn | * * If tpL is outside, turn west. * If tpR is inside, turn east. * Otherwise, continue north. */ case GEO_NORTH: tpL = RT(outline->o_nextIn); if (!IsInside(tpL, outline)) { outline->o_nextOut = tpL; outline->o_nextDir = GEO_WEST; break; } /* Find tpR */ if (RIGHT(tpL) > outline->o_nextRect.r_xbot) tpR = tpL; else for (tpR = TR(tpL); BOTTOM(tpR) > outline->o_nextRect.r_ybot; tpR = LB(tpR)) /* Nothing */; if (IsInside(tpR, outline)) { outline->o_nextOut = TR(outline->o_nextIn); outline->o_nextDir = GEO_EAST; } else outline->o_nextIn = tpL; break; /* * Heading south. * * | nextIn * --------+-------- * tpL tpR * * If tpR is outside, turn east. * If tpL is inside, turn west. * Otherwise, continue south. */ case GEO_SOUTH: tpR = LB(outline->o_nextIn); if (!IsInside(tpR, outline)) { outline->o_nextOut = tpR; outline->o_nextDir = GEO_EAST; break; } /* Find tpL */ if (LEFT(tpR) < outline->o_nextRect.r_xbot) tpL = tpR; else for (tpL = BL(tpR); TOP(tpL) < outline->o_nextRect.r_ytop; tpL = RT(tpL)) /* Nothing */; if (IsInside(tpL, outline)) { outline->o_nextOut = BL(outline->o_nextIn); outline->o_nextDir = GEO_WEST; } else outline->o_nextIn = tpR; break; /* * Heading east. * * tpL * --------+ * nextOut | tpR * * If tpR is inside, turn south. * If tpL is outside, turn north. * Otherwise, continue east. */ case GEO_EAST: tpR = TR(outline->o_nextOut); if (TOP(tpR) > outline->o_nextRect.r_ybot) tpL = tpR; else for (tpL = RT(tpR); LEFT(tpL) > outline->o_nextRect.r_xbot; tpL = BL(tpL)) /* Nothing */; if (!IsInside(tpL, outline)) { outline->o_nextIn = RT(outline->o_nextOut); outline->o_nextDir = GEO_NORTH; } else if (IsInside(tpR, outline)) { outline->o_nextIn = tpR; outline->o_nextDir = GEO_SOUTH; } else outline->o_nextOut = tpR; break; /* * Heading west. * * tpL nextOut * +-------- * tpR * * If tpL is inside, turn north. * If tpR is outside, turn south. * Otherwise, continue west. */ case GEO_WEST: tpL = BL(outline->o_nextOut); if (BOTTOM(tpL) < outline->o_nextRect.r_ybot) tpR = tpL; else for (tpR = LB(tpL); RIGHT(tpR) < outline->o_nextRect.r_xbot; tpR = TR(tpR)) /* Nothing */; if (!IsInside(tpR, outline)) { outline->o_nextIn = LB(outline->o_nextOut); outline->o_nextDir = GEO_SOUTH; } else if (IsInside(tpL, outline)) { outline->o_nextIn = tpL; outline->o_nextDir = GEO_NORTH; } else outline->o_nextOut = tpL; break; } /* * Stack a new set of tiles along the opposite side always, * since we either advanced to the next tile or changed * direction. Set the appropriate one of o_nextIn (if * going east/west) or o_nextOut (if going north/south). */ STACKOUTLINE(outline); } magic-8.0.210/plow/PlowTech.c0000644000175000001440000002336010751423606014334 0ustar timusers/* * PlowTech.c -- * * Plowing. * Read the "drc" section of the technology file and construct the * design rules used by plowing. * * ********************************************************************* * * 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/plow/PlowTech.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/utils.h" #include "utils/malloc.h" #include "plow/plowInt.h" #include "drc/drc.h" /* Imports from DRC */ extern char *maskToPrint(); /* Rule tables */ PlowRule *plowSpacingRulesTbl[TT_MAXTYPES][TT_MAXTYPES]; PlowRule *plowWidthRulesTbl[TT_MAXTYPES][TT_MAXTYPES]; /* Special type masks */ TileTypeBitMask PlowContactTypes; /* All types that are contacts */ TileTypeBitMask PlowCoveredTypes; /* All types that can't be uncovered * (i.e, have an edge slide past them) */ TileTypeBitMask PlowDragTypes; /* All types that drag along trailing * minimum-width material when they * move. */ TileTypeBitMask PlowFixedTypes; /* Fixed-width types (e.g, fets). * Note that this is the one variable * used outside the plow module (see * select/selOps.c), for the "stretch" * command. */ /* * Entry [t] of the following table is the maximum distance associated * with any design rules in a bucket with type 't' on the LHS. */ int plowMaxDist[TT_MAXTYPES]; /* Forward declarations */ extern void plowEdgeRule(), plowWidthRule(), plowSpacingRule(); PlowRule *plowTechOptimizeRule(); /* * ---------------------------------------------------------------------------- * * plowTechOptimizeRule -- * * Called to optimize the chain of rules in a single bin of either * the spacing or width rules tables. * * In general, we want to remove any rule A "covered" by another * rule B, i.e., * * B's distance >= A's distance, * B's OKTypes is a subset of A's OKTypes, and * B's Ltypes == A's Ltypes * B's check plane == A's check plane * * Results: * Returns a pointer to the new chain of rules for this bin. * * Side effects: * May deallocate memory. * * ---------------------------------------------------------------------------- */ PlowRule * plowTechOptimizeRule(ruleList) PlowRule *ruleList; { PlowRule *pCand, *pCandLast, *pr; TileTypeBitMask tmpMask; /* * The pointer 'pCand' in the following loop will iterate over * candidates for deletion, and pCandLast will trail by one. */ pCand = ruleList; pCandLast = (PlowRule *) NULL; while (pCand) { for (pr = ruleList; pr; pr = pr->pr_next) { if (pr != pCand && pr->pr_dist >= pCand->pr_dist && pr->pr_flags == pCand->pr_flags && pr->pr_pNum == pCand->pr_pNum && TTMaskEqual(&pr->pr_ltypes, &pCand->pr_ltypes)) { /* * Is pr->pr_oktypes a subset of pCand->pr_oktypes, * i.e, is it more restrictive? */ TTMaskAndMask3(&tmpMask, &pr->pr_oktypes, &pCand->pr_oktypes); if (TTMaskEqual(&tmpMask, &pr->pr_oktypes)) { /* * Delete pCand, and resume outer loop with the * new values of pCand and pCandLast set below. */ freeMagic((char *) pCand); if (pCandLast) pCandLast->pr_next = pCand->pr_next; else ruleList = pCand->pr_next; pCand = pCand->pr_next; goto next; } } } /* Normal continuation: advance to next rule in bin */ pCandLast = pCand, pCand = pCand->pr_next; next: ; } return (ruleList); } /* * ---------------------------------------------------------------------------- * * PlowTechInit -- * * Initialize the masks of types PlowFixedTypes, PlowCoveredTypes, * and PlowDragTypes to be empty. * * Results: * None. * * Side effects: * Zeroes PlowFixedTypes, PlowCoveredTypes, and PlowDragTypes. * * ---------------------------------------------------------------------------- */ void PlowTechInit() { PlowFixedTypes = DBZeroTypeBits; PlowCoveredTypes = DBZeroTypeBits; PlowDragTypes = DBZeroTypeBits; } /* * ---------------------------------------------------------------------------- * * PlowTechLine -- * * Process a line from the plowing section of a technology file. * Such a line is currently of the following form: * * keyword types * * where 'types' is a comma-separated list of type names. * * Keywords: * * fixed each of 'types' is fixed-width; regions consisting * of fixed-width types are not deformed by plowing. * Contacts are automatically fixed size and so do not * need to be included in this list. Space can never * be fixed-size and so is automatically omitted from * the list. * * covered each of 'types' cannot be uncovered as a result of * plowing. This means that if material of type X * covers a horizontal edge initially, it will continue * to cover it after plowing. * * drag each of 'types' will drag along with it the LHS of * any trailing minimum-width material when it moves. * This is so transistors will drag their gates when * the transistor moves, so we don't leave huge amounts * of poly behind us. * * Results: * Returns TRUE always. * * Side effects: * Updates PlowFixedTypes, PlowCoveredTypes, and PlowDragTypes. * * ---------------------------------------------------------------------------- */ bool PlowTechLine(sectionName, argc, argv) char *sectionName; /* Unused */ int argc; char *argv[]; { TileTypeBitMask types; if (argc != 2) { TechError("Malformed line\n"); return (TRUE); } DBTechNoisyNameMask(argv[1], &types); TTMaskAndMask(&types, &DBAllButSpaceBits); if (strcmp(argv[0], "fixed") == 0) { TTMaskSetMask(&PlowFixedTypes, &types); } else if (strcmp(argv[0], "covered") == 0) { TTMaskSetMask(&PlowCoveredTypes, &types); } else if (strcmp(argv[0], "drag") == 0) { TTMaskSetMask(&PlowDragTypes, &types); } else { TechError("Illegal keyword \"%s\".\n", argv[0]); } return (TRUE); } /* * ---------------------------------------------------------------------------- * * PlowTechFinal -- * * Final processing of the lines from the plowing section of a technology * file. Add all contacts to the list of fixed types. Also sets the mask * PlowContactTypes to have bits set for each image of each contact. * * Results: * None. * * Side effects: * Updates PlowFixedTypes and PlowContactTypes. * * ---------------------------------------------------------------------------- */ void PlowTechFinal() { TileType t; TTMaskZero(&PlowContactTypes); for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) if (DBIsContact(t)) TTMaskSetType(&PlowContactTypes, t); TTMaskSetMask(&PlowFixedTypes, &PlowContactTypes); } /* * ---------------------------------------------------------------------------- * * PlowAfterTech --- * * Routine to run after the entire techfile has been processed (or reloaded), * or when the DRC rules have been rescaled, after an internal grid rescaling. * It derives all of the plow width and spacing rules from the DRC rules. * * ---------------------------------------------------------------------------- */ void PlowAfterTech() { /* This remains to be done. . . */ } /* * ---------------------------------------------------------------------------- * * plowTechPrintRule -- * plowTechShowTable -- * plowTechShow -- * * For debugging purposes. * Print the complete table of all plowing rules. * * Results: * None. * * Side effects: * Prints to the file 'f'. * * ---------------------------------------------------------------------------- */ void plowTechPrintRule(pr, f) PlowRule *pr; FILE *f; { fprintf(f, "\tDISTANCE=%d, PLANE=%s, FLAGS=", pr->pr_dist, DBPlaneLongName(pr->pr_pNum)); if (pr->pr_flags & PR_WIDTH) fprintf(f, " Width"); if (pr->pr_flags & PR_PENUMBRAONLY) fprintf(f, " PenumbraOnly"); if (pr->pr_flags & PR_EDGE) fprintf(f, " Edge"); if (pr->pr_flags & PR_EDGE4WAY) fprintf(f, " Edge4way"); if (pr->pr_flags & PR_EDGEBACK) fprintf(f, " EdgeBack"); fprintf(f, "\n"); fprintf(f, "\tLTYPES = %s\n", maskToPrint(&pr->pr_ltypes)); fprintf(f, "\tOKTYPES = %s\n", maskToPrint(&pr->pr_oktypes)); fprintf(f, "\t-------------------------------\n"); } void plowTechShowTable(table, header, f) PlowRule *table[TT_MAXTYPES][TT_MAXTYPES]; char *header; FILE *f; { PlowRule *pr; TileType i, j; fprintf(f, "\n\n------------ %s ------------\n", header); for (i = 0; i < DBNumTypes; i++) for (j = 0; j < DBNumTypes; j++) if (pr = table[i][j]) { fprintf(f, "\n%s -- %s:\n", DBTypeLongName(i), DBTypeLongName(j)); for ( ; pr; pr = pr->pr_next) plowTechPrintRule(pr, f); } } void plowTechShow(f) FILE *f; { plowTechShowTable(plowWidthRulesTbl, "Width Rules", f); plowTechShowTable(plowSpacingRulesTbl, "Spacing Rules", f); } magic-8.0.210/drc/0000755000175000001440000000000012503062345012222 5ustar timusersmagic-8.0.210/drc/DRCarray.c0000644000175000001440000003054511176643240014050 0ustar timusers/* * DRCarray.c -- * * This file provides routines that check arrays to be sure * there are no unpleasant interactions between adjacent * elements. Note: the routines in this file are NOT generally * re-entrant. * * ********************************************************************* * * 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/drc/DRCarray.c,v 1.2 2009/05/01 18:59:44 tim Exp $"; #endif /* not lint */ #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "drc/drc.h" #include "windows/windows.h" #include "commands/commands.h" /* Forward references: */ extern int drcArrayYankFunc(), drcArrayOverlapFunc(); /* Dummy DRC cookie used to pass the error message to DRC error * routines. */ static DRCCookie drcArrayCookie = { 0, 0, 0, 0, { 0 }, { 0 }, 0, 0, 0, "This layer can't abut or partially overlap between array elements", (DRCCookie *) NULL }; /* Static variables used to pass information between DRCArrayCheck * and drcArrayFunc: */ static int drcArrayCount; /* Count of number of errors found. */ static void (*drcArrayErrorFunc)(); /* Function to call on violations. */ static ClientData drcArrayClientData; /* Extra parameter to pass to func. */ /* * ---------------------------------------------------------------------------- * * drcArrayFunc -- * * This procedure is invoked by DBCellSrArea once for each cell * overlapping the area being checked. If the celluse is for * an array, then it is checked for array correctness. * * Results: * Always returns 2, to skip the remaining instances in the * current array. * * Side effects: * Design rules are checked for the subcell, if it is an array, * and the count of errors is added into drcSubCount. * * Design: * To verify that an array is correct, we only have to check * four interaction areas, shaded as A, B, C, and D in the diagram * below. The exact size of the interaction areas depends on * how much overlap there is. In the extreme cases, there may be * no areas to check at all (instances widely separated), or there * may even be areas with more than four instances overlapping * (spacing less than half the size of the instance). * * --------------DDDDD------------------------------ * | DDDDD | | * | | | | * | | | | * | | | | * ------------------------------------------------- * | | | | * | | | | * | | | | * AAAAAAAAAAAAAAAAAAA | CCC * AAAAAAAAAAAAAAAAAAA---------------------------CCC * AAAAAAAAAAAAAAAAAAA | CCC * | BBBBB | | * | BBBBB | | * | BBBBB | | * --------------BBBBB------------------------------ * * ---------------------------------------------------------------------------- */ int drcArrayFunc(scx, area) SearchContext *scx; /* Information about the search. */ Rect *area; /* Area in which errors are to be * regenerated. */ { int xsep, ysep; int xsize, ysize; Rect errorArea, yankArea, tmp, tmp2; CellUse *use = scx->scx_use; struct drcClientData arg; if ((use->cu_xlo == use->cu_xhi) && (use->cu_ylo == use->cu_yhi)) return 2; /* Set up the client data that will be passed down during * checks for exact overlaps. */ arg.dCD_celldef = DRCdef; arg.dCD_errors = &drcArrayCount; arg.dCD_clip = &errorArea; arg.dCD_cptr = &drcArrayCookie; arg.dCD_function = drcArrayErrorFunc; arg.dCD_clientData = drcArrayClientData; /* Compute the sizes and separations of elements, in coordinates * of the parend. If the array is 1-dimensional, we set the * corresponding spacing to an impossibly large distance. */ tmp.r_xbot = 0; tmp.r_ybot = 0; if (use->cu_xlo == use->cu_xhi) tmp.r_xtop = DRCTechHalo + use->cu_def->cd_bbox.r_xtop - use->cu_def->cd_bbox.r_xbot; else tmp.r_xtop = use->cu_xsep; if (use->cu_ylo == use->cu_yhi) tmp.r_ytop = DRCTechHalo + use->cu_def->cd_bbox.r_ytop - use->cu_def->cd_bbox.r_ybot; else tmp.r_ytop = use->cu_ysep; GeoTransRect(&use->cu_transform, &tmp, &tmp2); xsep = tmp2.r_xtop - tmp2.r_xbot; ysep = tmp2.r_ytop - tmp2.r_ybot; GeoTransRect(&use->cu_transform, &use->cu_def->cd_bbox, &tmp2); xsize = tmp2.r_xtop - tmp2.r_xbot; ysize = tmp2.r_ytop - tmp2.r_ybot; /* Check each of the four areas A, B, C, and D. Remember that * absolutely arbitrary overlaps between cells are allowed. * Skip some or all of the areas if the cell isn't arrayed in * that direction or if the instances are widely spaced. */ if (ysep < ysize + DRCTechHalo) { /* A */ errorArea.r_xbot = use->cu_bbox.r_xbot; errorArea.r_xtop = use->cu_bbox.r_xbot + xsize + DRCTechHalo; errorArea.r_ybot = use->cu_bbox.r_ybot + ysep - DRCTechHalo; errorArea.r_ytop = use->cu_bbox.r_ybot + ysize + DRCTechHalo; GeoClip(&errorArea, area); if (!GEO_RECTNULL(&errorArea)) { GEO_EXPAND(&errorArea, DRCTechHalo, &yankArea); DBCellClearDef(DRCdef); (void) DBArraySr(use, &yankArea, drcArrayYankFunc, (ClientData) &yankArea); drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea, drcArrayErrorFunc, drcArrayClientData); (void) DBArraySr(use, &errorArea, drcArrayOverlapFunc, (ClientData) &arg); } /* C */ errorArea.r_xtop = use->cu_bbox.r_xtop; errorArea.r_xbot = use->cu_bbox.r_xtop - DRCTechHalo; GeoClip(&errorArea, area); if (!GEO_RECTNULL(&errorArea)) { GEO_EXPAND(&errorArea, DRCTechHalo, &yankArea); DBCellClearDef(DRCdef); (void) DBArraySr(use, &yankArea, drcArrayYankFunc, (ClientData) &yankArea); drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea, drcArrayErrorFunc, drcArrayClientData); (void) DBArraySr(use, &errorArea, drcArrayOverlapFunc, (ClientData) &arg); } } if (xsep < xsize + DRCTechHalo) { /* B */ errorArea.r_xbot = use->cu_bbox.r_xbot + xsep - DRCTechHalo; errorArea.r_xtop = use->cu_bbox.r_xbot + xsize + DRCTechHalo; errorArea.r_ybot = use->cu_bbox.r_ybot; errorArea.r_ytop = errorArea.r_ybot + ysep - DRCTechHalo; GeoClip(&errorArea, area); if (!GEO_RECTNULL(&errorArea)) { GEO_EXPAND(&errorArea, DRCTechHalo, &yankArea); DBCellClearDef(DRCdef); (void) DBArraySr(use, &yankArea, drcArrayYankFunc, (ClientData) &yankArea); drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea, drcArrayErrorFunc, drcArrayClientData); (void) DBArraySr(use, &errorArea, drcArrayOverlapFunc, (ClientData) &arg); } /* D */ errorArea.r_ytop = use->cu_bbox.r_ytop; errorArea.r_ybot = use->cu_bbox.r_ytop - DRCTechHalo; GeoClip(&errorArea, area); if (!GEO_RECTNULL(&errorArea)) { GEO_EXPAND(&errorArea, DRCTechHalo, &yankArea); DBCellClearDef(DRCdef); (void) DBArraySr(use, &yankArea, drcArrayYankFunc, (ClientData) &yankArea); drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea, drcArrayErrorFunc, drcArrayClientData); (void) DBArraySr(use, &errorArea, drcArrayOverlapFunc, (ClientData) &arg); } } return 2; } /* * ---------------------------------------------------------------------------- * DRCArrayCheck -- * * This procedure finds all DRC errors in a given area of * a given cell that stem from array formation errors in * children of that cell. Func is called for each violation * found. Func should have the same form as in DRCBasicCheck. * Note: the def passed to func is the dummy DRC definition, * and the errors are all expressed in coordinates of celluse. * * Results: * The number of errors found. * * Side effects: * Whatever is done by func. * * ---------------------------------------------------------------------------- */ int DRCArrayCheck(def, area, func, cdarg) CellDef *def; /* Parent cell containing the arrays to * be rechecked. */ Rect *area; /* Area, in def's coordinates, where all * array violations are to be regenerated. */ void (*func)(); /* Function to call for each error. */ ClientData cdarg; /* Client data to be passed to func. */ { SearchContext scx; int oldTiles; PaintResultType (*savedPaintTable)[NT][NT]; PaintResultType (*savedEraseTable)[NT][NT]; void (*savedPaintPlane)(); /* Use DRCDummyUse to fake up a celluse for searching purposes. */ DRCDummyUse->cu_def = def; drcArrayErrorFunc = func; drcArrayClientData = cdarg; drcArrayCount = 0; oldTiles = DRCstatTiles; scx.scx_area = *area; scx.scx_use = DRCDummyUse; scx.scx_trans = GeoIdentityTransform; /* During array processing, switch the paint table to catch * illegal overlaps. */ savedPaintTable = DBNewPaintTable(DRCCurStyle->DRCPaintTable); savedPaintPlane = DBNewPaintPlane(DBPaintPlaneMark); (void) DBCellSrArea(&scx, drcArrayFunc, (ClientData) area); (void) DBNewPaintTable(savedPaintTable); (void) DBNewPaintPlane(savedPaintPlane); /* Update count of array tiles processed. */ DRCstatArrayTiles += DRCstatTiles - oldTiles; return drcArrayCount; } /* * ---------------------------------------------------------------------------- * * drcArrayYankFunc -- * * Search action function called while yanking pieces of an array. * * Results: * Always returns 0, to keep the search going. * * Side effects: * Yanks from an array element into the DRC yank buffer. * * ---------------------------------------------------------------------------- */ /* ARGSUSED */ int drcArrayYankFunc(use, transform, x, y, yankArea) CellUse *use; /* CellUse being array-checked. */ Transform *transform; /* Transform from instance to parent.*/ int x, y; /* Element indices (not used). */ Rect *yankArea; /* Area to yank (in parent coords). */ { SearchContext scx; Transform tinv; GeoInvertTrans(transform, &tinv); GeoTransRect(&tinv, yankArea, &scx.scx_area); scx.scx_use = use; scx.scx_trans = *transform; (void) DBCellCopyAllPaint(&scx, &DBAllButSpaceBits, 0, DRCuse); return 0; } /* * ---------------------------------------------------------------------------- * * drcArrayOverlapFunc -- * * This is a search action function called while checking pieces * of an array to be sure that there aren't any illegal partial * overlaps. It just invokes overlap checking facilities in * DRCsubcell.c * * Results: * Always returns 0 to keep the search alive. * * Side effects: * The client's error function may be invoked. * * ---------------------------------------------------------------------------- */ /* ARGSUSED */ int drcArrayOverlapFunc(use, transform, x, y, arg) CellUse *use; /* CellUse for array element. */ Transform *transform; /* Transform from use to parent. */ int x, y; /* Indices of element. */ struct drcClientData *arg; /* Information used in overlap * checking. See drcExactOverlapTile. */ { Transform tinv; SearchContext scx; GeoInvertTrans(transform, &tinv); GeoTransRect(&tinv, arg->dCD_clip, &scx.scx_area); scx.scx_use = use; scx.scx_trans = *transform; (void) DBTreeSrTiles(&scx, &DRCCurStyle->DRCExactOverlapTypes, 0, drcExactOverlapTile, (ClientData) arg); return 0; } magic-8.0.210/drc/DRCcontin.c0000664000175000001440000006122711725464767014246 0ustar timusers/* * DRCcontinuous.c -- * * This file provides the facilities for continuously keeping * design-rule violation information up to date in Magic. It * records areas that need to be rechecked, and provides a * routine to perform those checks in background. * * ********************************************************************* * * 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/drc/DRCcontin.c,v 1.7 2010/03/12 17:19:45 tim Exp $"; #endif /* not lint */ #include #include #include "tcltk/tclmagic.h" #include "utils/magic.h" #include "textio/textio.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 "dbwind/dbwtech.h" #include "utils/main.h" #include "commands/commands.h" #include "drc/drc.h" #include "utils/signals.h" #include "graphics/graphics.h" #include "utils/undo.h" #include "utils/malloc.h" #ifdef MAGIC_WRAPPER /* Global variable which indicates that the background checker is * still registered as an idle process. */ global unsigned char DRCStatus = DRC_NOT_RUNNING; #endif /* Global variable, settable by outside world, that enables * and disables the background checker. If disabled, check * tiles pile up but nothing is checked. */ global u_char DRCBackGround = DRC_NOT_SET; /* Global variable, settable by outside world, that enables * and disables Euclidean DRC checking. If enabled, magic * computes corner-to-corner distances using a Euclidean metric. * If disabled, magic computes corner-to-corner distances using * a Manhattan metric. * * Note: should this feature be settable from the technology * file, rather than from the command line? */ global bool DRCEuclidean = FALSE; /* Global variable that defines the size of chunks into which * to decompose large DRC areas. Also used to guarantee a * canonical determination of interaction areas. May be * set either while reading the tech file, or automatically * when DRCInit() is called. */ /*------- Things used by other DRC modules but not outside world. -------*/ /* Base of linked list of CellDefs waiting for background DRC. * Can be read by outside world to see if there's any work * to do. */ global DRCPendingCookie * DRCPendingRoot = (DRCPendingCookie *) NULL; /* Pointers to yank buffer's use and def on the heap */ CellDef * DRCdef = (CellDef *) NULL; CellUse * DRCuse = (CellUse *) NULL; /* Boolean indicating whether DRC initialization has been done. */ bool DRCInitialized = FALSE; /* Boolean indicating whether or not check tiles are being displayed. */ bool DRCDisplayCheckTiles = FALSE; /* The following use is a dummy, provided because the DBCellCopyAll * routine requires a cellUse, and we don't generally have one. * As a kludge, we just keep around this dummy, with identity * transform and no arraying, and just change the def pointer * in it before calling DBCellCopyAll. */ CellUse *DRCDummyUse = (CellUse *) NULL; /*------- Things used only within this module. -------*/ /* Layer mask for the DRC layers. */ TileTypeBitMask DRCLayers; /* In order to reduce the amount of DRC redisplay, whenever an area * is rechecked we log all the previous violations in that area, * XOR them with all of the new violations in the area, and only * redisplay the bounding box of the changes. The plane and paint * tables below are used for storing the information and doing the * XOR. */ static Plane *drcDisplayPlane; #define DRC_SOLID 1 static PaintResultType drcXorTable[] = {DRC_SOLID, TT_SPACE}; /* When computing DRC violations, they don't get painted directly * into the database. Instead, they get painted first into a * temporary plane. That way, if DRC is interrupted we can exit * quickly without leaving error information in a weird state. * Once everything has been computed, then it's painted into the * cell in one fell swoop. */ static Plane *drcTempPlane; /* Forward declarations and imports from other drc modules: */ extern int drcCheckTile(); extern CellDef *DRCErrorDef; extern TileType DRCErrorType; /* * ---------------------------------------------------------------------------- * DRCCheckThis -- * * Mark an area of a CellDef so that it will be checked by continuous * DRC. Add the CellDef to the list of Defs to be checked. If the * pointer to the area rectangle is NULL, just add the CellDef to the * list. * * Two types of check tiles (CHECKPAINT and CHECKSUBCELL) are used * to distinguish areas of new paint in the CellDef from areas where * subcells of the CellDef have changed. Painted areas will be * checked for internal consistency and their interactions with * subcells. Areas where a subcell has changed will be checked * for interactions with paint, interactions with other subcells, and * correct array structure (if the subcell is used as an array). * * Called by paint, erase and cell operations in the commands module. * Also calls itself recursively in order to propagate check areas up * through a hierarchy of CellDefs and CellUses. * * Results: * None. * * Side effects: * Modifies the PL_DRC_CHECK plane of given CellDef. The area * recorded on the plane is one halo larger than the area modified, * i.e. the area where errors must be regenerated. Inserts the * CellDef into the list of Defs waiting to be checked. * ---------------------------------------------------------------------------- */ /* ARGSUSED */ void DRCCheckThis (celldef, operation, area) CellDef * celldef; /* Allows check areas to propagate * up from EditCell. */ TileType operation; /* TT_CHECKPAINT or TT_CHECKSUBCELL */ Rect * area; /* Area that changed. */ { CellUse * cu; /* Ptr to uses of the given CellDef */ Rect transRect; /* Area in coords of parent CellDefs, * expanded if the use is in an array */ Rect dummyRect, dummyRect2; DRCPendingCookie * p, ** pback; /* Used to insert new element in list * of CellDefs waiting for DRC */ /* Ignore read-only, internal, and vendor GDS cells. None of these */ /* can contain DRC errors that could be fixed in magic. */ if (celldef->cd_flags & (CDVENDORGDS | CDNOEDIT | CDINTERNAL)) return; /* Insert celldef into list of Defs waiting to be checked, unless */ /* it is already there. */ pback = &DRCPendingRoot; p = DRCPendingRoot; while (p != (DRCPendingCookie *) NULL) { if (p->dpc_def == celldef) { *pback = p->dpc_next; break; } pback = &(p->dpc_next); p = p->dpc_next; } if (p == (DRCPendingCookie *) NULL) { p = (DRCPendingCookie *) mallocMagic(sizeof (DRCPendingCookie)); p->dpc_def = celldef; } p->dpc_next = DRCPendingRoot; DRCPendingRoot = p; /* Mark the area in this celldef (but don't worry about this stuff * for undo purposes). Also, it's important to disable interrupts * in here, or the paint operation could get aborted underneath us. */ if (area != (Rect *) NULL) { GEO_EXPAND(area, DRCTechHalo, &dummyRect); SigDisableInterrupts(); DBPaintPlane(celldef->cd_planes[PL_DRC_CHECK], &dummyRect, DBStdPaintTbl(TT_CHECKPAINT, PL_DRC_CHECK), (PaintUndoInfo *) NULL); SigEnableInterrupts(); } else return; /* Call recursively for each use of this * CellDef in a parent. */ for (cu = celldef->cd_parents; cu != (CellUse *) NULL; cu = cu->cu_nextuse) { if (cu->cu_parent == (CellDef *) NULL) /* use for a Window */ continue; /* area in coordinates of the parent Def */ GeoTransRect (&(cu->cu_transform), area, &transRect); if ((cu->cu_xlo != cu->cu_xhi) || (cu->cu_ylo != cu->cu_yhi)) { /* transRect needs to include all images * of "area" in the array, in coordinates * of the parent Def */ DBComputeArrayArea(area, cu, cu->cu_xhi, cu->cu_yhi, &dummyRect); GeoTransRect(&cu->cu_transform, &dummyRect, &dummyRect2); (void) GeoInclude (&dummyRect2, &transRect); } DRCCheckThis (cu->cu_parent, TT_CHECKSUBCELL, &transRect); } } /* * ---------------------------------------------------------------------------- * * DRCRemovePending -- * * Remove a cell def from the DRC pending list. * * Results: * None. * * Side effects: * DRCPendingRoot linked list modified * * ---------------------------------------------------------------------------- */ void DRCRemovePending(def) CellDef *def; { DRCPendingCookie *p, *plast; p = DRCPendingRoot; plast = NULL; while (p != NULL) { if (p->dpc_def == def) { if (plast == NULL) DRCPendingRoot = p->dpc_next; else plast->dpc_next = p->dpc_next; freeMagic(p); return; } plast = p; p = p->dpc_next; } } /* * ---------------------------------------------------------------------------- * * DRCInit -- * * This procedure initializes DRC data. It must be called after * the technology file has been read. * * Results: * None. * * Side effects: * Owns shared between the DRC modules are initialized. * * ---------------------------------------------------------------------------- */ void DRCInit() { int i; TileTypeBitMask displayedTypes; /* Only do initialization once. */ if (DRCInitialized) return; DRCInitialized = TRUE; /* Create a cell use to use for holding yank data in interaction checks. */ DRCdef = DBCellLookDef(DRCYANK); if (DRCdef == (CellDef *) NULL) { DRCdef = DBCellNewDef (DRCYANK,(char *) NULL); ASSERT(DRCdef != (CellDef *) NULL, "DRCInit"); DBCellSetAvail(DRCdef); DRCdef->cd_flags |= CDINTERNAL; } DRCuse = DBCellNewUse (DRCdef, (char *) NULL); DBSetTrans (DRCuse, &GeoIdentityTransform); DRCuse->cu_expandMask = CU_DESCEND_SPECIAL; /* This is always expanded. */ /* Create a dummy cell use to use for passing to procedures * that need a use when all we've got is a def. */ DRCDummyUse = DBCellNewUse(DRCdef, (char *) NULL); DBSetTrans (DRCDummyUse, &GeoIdentityTransform); /* See if check tiles are being displayed. */ TTMaskZero(&displayedTypes); for (i = 0; i < DBWNumStyles; i++) TTMaskSetMask(&displayedTypes, DBWStyleToTypes(i)); DRCDisplayCheckTiles = TTMaskHasType(&displayedTypes, TT_CHECKPAINT) || TTMaskHasType(&displayedTypes, TT_CHECKSUBCELL); /* Initialize mask of DRC layer types. */ TTMaskZero(&DRCLayers); TTMaskSetType(&DRCLayers, TT_ERROR_P); TTMaskSetType(&DRCLayers, TT_ERROR_S); TTMaskSetType(&DRCLayers, TT_ERROR_PS); /* Create planes to hold error areas to redisplay and to hold * temporary error information. */ drcDisplayPlane = DBNewPlane((ClientData) TT_SPACE); drcTempPlane = DBNewPlane((ClientData) TT_SPACE); } #ifdef MAGIC_WRAPPER /* Needs to be global so the DRCBreak() routine can use the value */ Rect drc_orig_bbox; /* * ---------------------------------------------------------------------------- * DRCBreak -- * * This is called by "window" or "file" event callbacks from magic * which would invalidate the current DRC process. This routine * is just a copy of the exit code for DRCContinuous. Because Tcl * doesn't have a "peek" routine for examining its event queue, we * can only execute pending events and break the DRC process from * the event callback code. * This is called prior to running commands which do their own * WindUpdate() call, so it is not necessary to call it here. * ---------------------------------------------------------------------------- */ void DRCBreak() { if (DRCHasWork && (DRCStatus == DRC_IN_PROGRESS)) { UndoEnable(); /* fprintf(stderr, "DRC breaking. . .\n"); fflush(stderr); */ /* As a convenience for debugging DRC stuff, we pretend the DRC * cell is a real one and recompute its bounding box, and redisplay * both its old area (currently in box) and its current area. */ DBReComputeBbox(DRCdef); (void) GeoInclude(&DRCdef->cd_bbox, &drc_orig_bbox); DBWAreaChanged(DRCdef, &drc_orig_bbox, DBW_ALLWINDOWS, &DBAllButSpaceBits); DRCStatus = DRC_BREAK_PENDING; } } #endif /* * ---------------------------------------------------------------------------- * DRCContinuous -- * * Called by WindDispatch() before it goes to sleep waiting for user input. * This routine checks to see if there are any areas of the layout that * need to be design-rule-checked. If so, it does the appropriate checks. * This procedure will abort itself at the earliest convenient moment * after the user types a new command. * * Results: * None. * * Side effects: * Modifies the DRC_CHECK and DRC_ERROR planes * of the CellDefs on the DRCPending list. * ---------------------------------------------------------------------------- */ void DRCContinuous() { #ifndef MAGIC_WRAPPER Rect drc_orig_bbox; /* Area of DRC def that changed. */ #endif if (DRCHasWork == FALSE) { #ifdef MAGIC_WRAPPER DRCStatus = DRC_NOT_RUNNING; #endif return; } #ifdef MAGIC_WRAPPER if (DRCStatus != DRC_NOT_RUNNING) return; /* Avoid infinitely recursive loop */ GrFlush(); DRCStatus = DRC_IN_PROGRESS; Tcl_EvalEx(magicinterp, "after idle magic::drcstate busy", -1, 0); if (TxInputRedirect != TX_INPUT_REDIRECTED) TxSetPrompt(']'); /* fprintf(stderr, "Starting DRC\n"); fflush(stderr); */ #endif UndoDisable(); /* Don't want to undo error info. */ drc_orig_bbox = DRCdef->cd_bbox; while (DRCPendingRoot != (DRCPendingCookie *) NULL) { /* DBSrPaintArea() returns 1 if drcCheckTile() * returns 1, meaning that a CHECK tile * was found and processed. */ while ((DRCPendingRoot != (DRCPendingCookie *)NULL) && DBSrPaintArea ((Tile *) NULL, DRCPendingRoot->dpc_def->cd_planes [PL_DRC_CHECK], &TiPlaneRect, &DBAllButSpaceBits, drcCheckTile, (ClientData) NULL)) { /* check for new user command (without blocking) */ #ifdef MAGIC_WRAPPER /* Execute pending Tcl events, so the DRC process doesn't block. */ /* NOTE: Exclude file events, or else "drc catchup" will not work */ /* in batch mode. */ UndoEnable(); while (Tcl_DoOneEvent(TCL_DONT_WAIT)) { if (DRCStatus == DRC_BREAK_PENDING) { /* fprintf(stderr, "DRC exiting loop. . .\n"); fflush(stderr); */ DRCStatus = DRC_NOT_RUNNING; return; } } UndoDisable(); /* fprintf(stderr, "DRC continuing internally. . .\n"); fflush(stderr); */ #else #ifndef USE_IO_PROBE if (SigInterruptPending) goto checkDone; #else if (TxGetInputEvent (FALSE, FALSE) == TRUE) goto checkDone; #endif #endif } /* No check tiles were found, so knock this cell off the list. */ if (DRCPendingRoot != (DRCPendingCookie *)NULL) { DBReComputeBbox(DRCPendingRoot->dpc_def); freeMagic((char *) DRCPendingRoot); DRCPendingRoot = DRCPendingRoot->dpc_next; } /* Give the timestamp manager a chance to update any mismatches. */ DBFixMismatch(); } #ifdef MAGIC_WRAPPER DRCStatus = DRC_NOT_RUNNING; Tcl_EvalEx(magicinterp, "after idle magic::drcstate idle", -1, 0); /* fprintf(stderr, "DRC is finished\n"); fflush(stderr); */ if (TxInputRedirect != TX_INPUT_REDIRECTED) TxSetPrompt('%'); #endif checkDone: UndoEnable(); /* As a convenience for debugging DRC stuff, we pretend the DRC * cell is a real one and recompute its bounding box, and redisplay * both its old area (currently in box) and its current area. */ DBReComputeBbox(DRCdef); (void) GeoInclude(&DRCdef->cd_bbox, &drc_orig_bbox); DBWAreaChanged(DRCdef, &drc_orig_bbox, DBW_ALLWINDOWS, &DBAllButSpaceBits); #ifdef MAGIC_WRAPPER WindUpdate(); GrFlush(); #endif } /* * ---------------------------------------------------------------------------- * drcCheckTile -- * * This procedure is called when a check tile is found in * the DRC_CHECK plane of the CellDef at the front of the * DRCPending list. This procedure is the heart of Magic's * continuous checker. * * For DRC purposes, each cell is divided up checkerboard-style * into areas DRCStepSize on each side. All checking is done * in terms of these squares. When a check tile is found, we * find the outer area of all check tiles in the square containing * the original check tile's lower-left corner. Errors within * this area are regenerated, then all check tiles in that area * are erased. The checkerboard approach serves three purposes. * First, it allows nearby small tiles to be combined for checking * purposes. Second, it limits the maximum amount of work that * is done at once, so if we're getting interrupted by new commands * there is still some hope of eventually getting the DRC caught up. * And third, it provides a canonical form for the checks, particularly * those involving subcells, so the same results are produced no * matter what the original check area is. * * The three DRC meta-rules are: * (1) paint in one CellDef must be consistent by itself, * that is, without regard to subcells * (2) subtrees must be consistent -- this includes both * paint interacting with subcells, and subcells * interacting with each other. * (3) an arrayed use of a CellDef must be consistent by itself, * that is, without regard to paint or other subcells * in the parent. This check happens automatically as * part of the subtree check. * * Two types of error tiles are kept independently in the * DRC_ERROR plane: (1) paint * (2) subtree * * This function is passed to DBSrPaintArea(). * * Results: * Always returns one. This function is only called on non-space * (CHECK) tiles, so if it is called a CHECK tile must have been * processed and we want DBSrPaintArea to abort the search. * * Side effects: * Modifies both DRC planes of the CellDef at the front of the * DRCPending list. * ---------------------------------------------------------------------------- */ /* ARGSUSED */ int drcCheckTile(tile, arg) Tile * tile; /* tile in DRC_CHECK plane */ ClientData arg; /* Not used. */ { Rect square; /* Square area of the checkerboard * being processed right now. */ Rect erasebox; /* erase old ERROR tiles in this * region and clip new ERRORs to it */ CellDef * celldef; /* First CellDef on DRCPending list. */ Rect redisplayArea; /* Area to be redisplayed. */ extern int drcXorFunc(); /* Forward declarations. */ extern int drcPutBackFunc(); celldef = DRCPendingRoot->dpc_def; DRCErrorDef = celldef; /* Find the checkerboard square containing the lower-left corner * of the check tile, then find all check tiles within that square. */ DRCstatSquares += 1; square.r_xbot = (LEFT(tile)/DRCStepSize) * DRCStepSize; if (square.r_xbot > LEFT(tile)) square.r_xbot -= DRCStepSize; square.r_ybot = (BOTTOM(tile)/DRCStepSize) * DRCStepSize; if (square.r_ybot > BOTTOM(tile)) square.r_ybot -= DRCStepSize; square.r_xtop = square.r_xbot + DRCStepSize; square.r_ytop = square.r_ybot + DRCStepSize; erasebox = GeoNullRect; (void) DBSrPaintArea((Tile *) NULL, celldef->cd_planes[PL_DRC_CHECK], &square, &DBAllButSpaceBits, drcIncludeArea, (ClientData) &erasebox); GeoClip(&erasebox, &square); /* TxPrintf("Check area = (%d, %d) (%d, %d)\n", erasebox.r_xbot, erasebox.r_ybot, erasebox.r_xtop, erasebox.r_ytop); */ /* Use drcDisplayPlane to save all the current errors in the * area we're about to recheck. */ DBClearPaintPlane(drcDisplayPlane); (void) DBSrPaintArea((Tile *) NULL, celldef->cd_planes[PL_DRC_ERROR], &square, &DBAllButSpaceBits, drcXorFunc, (ClientData) NULL); /* Check #1: recheck the paint of the cell, ignoring subcells. */ DRCErrorType = TT_ERROR_P; DBClearPaintPlane(drcTempPlane); /* May 4, 2008: Moved DRCBasicCheck into DRCInteractionCheck * to avoid requiring DRC rules to be satisfied independently * of subcells (checkbox was [erasebox + DRCTechHalo], now * computed within DRCInteractionCheck()). */ /* DRCBasicCheck (celldef, &checkbox, &erasebox, drcPaintError, (ClientData) drcTempPlane); */ /* Check #2: check interactions between paint and subcells, and * also between subcells and other subcells. If any part of a * square is rechecked for interactions, the whole thing has to * be rechecked. We use TT_ERROR_S tiles for this so that we * don't have to recheck paint and array errors over the whole * square. */ DRCErrorType = TT_ERROR_S; (void) DRCInteractionCheck(celldef, &square, &erasebox, drcPaintError, (ClientData) drcTempPlane); /* Check #3: check for array formation errors in the area. */ DRCErrorType = TT_ERROR_P; (void) DRCArrayCheck(celldef, &erasebox, drcPaintError, (ClientData) drcTempPlane); /* If there was an interrupt, return without modifying the cell * at all. */ if (SigInterruptPending) return 1; /* Erase the check tile from the check plane, erase the pre-existing * error tiles, and paint back in the new error tiles. Do this all * with interrupts disabled to be sure that it won't be aborted. */ SigDisableInterrupts(); DBPaintPlane(celldef->cd_planes[PL_DRC_CHECK], &erasebox, DBStdEraseTbl(TiGetType(tile), PL_DRC_CHECK), (PaintUndoInfo *) NULL); DBPaintPlane(celldef->cd_planes[PL_DRC_ERROR], &erasebox, DBStdEraseTbl(TT_ERROR_P, PL_DRC_ERROR), (PaintUndoInfo *) NULL); DBPaintPlane(celldef->cd_planes[PL_DRC_ERROR], &square, DBStdEraseTbl(TT_ERROR_S, PL_DRC_ERROR), (PaintUndoInfo *) NULL); (void) DBSrPaintArea((Tile *) NULL, drcTempPlane, &TiPlaneRect, &DBAllButSpaceBits, drcPutBackFunc, (ClientData) celldef); /* XOR the new errors in the tile with the old errors we * saved in drcDisplayPlane. Where information has changed, * clip to square and redisplay. If check tiles are being * displayed, then always redisplay the entire area. */ (void) DBSrPaintArea((Tile *) NULL, celldef->cd_planes[PL_DRC_ERROR], &square, &DBAllButSpaceBits, drcXorFunc, (ClientData) NULL); if (DBBoundPlane(drcDisplayPlane, &redisplayArea)) { GeoClip(&redisplayArea, &square); if (!GEO_RECTNULL(&redisplayArea)) DBWAreaChanged (celldef, &redisplayArea, DBW_ALLWINDOWS, &DRCLayers); } if (DRCDisplayCheckTiles) DBWAreaChanged(celldef, &square, DBW_ALLWINDOWS, &DRCLayers); DBCellSetModified (celldef, TRUE); SigEnableInterrupts(); return (1); /* stop the area search: we modified the database! */ } /* The utility function below gets called for each error tile in a * region. It just XOR's the area of the tile into drcDisplayPlane. */ int drcXorFunc(tile) Tile *tile; { Rect area; TiToRect(tile, &area); DBPaintPlane(drcDisplayPlane, &area, drcXorTable, (PaintUndoInfo *) NULL); return 0; } /* This procedure is the one that actually paints error tiles into the * database cells. */ int drcPutBackFunc(tile, cellDef) Tile *tile; /* Error tile, from drcTempPlane. */ CellDef *cellDef; /* Celldef in which to paint error. */ { Rect area; TiToRect(tile, &area); DBPaintPlane(cellDef->cd_planes[PL_DRC_ERROR], &area, DBStdPaintTbl(TiGetType(tile), PL_DRC_ERROR), (PaintUndoInfo *) NULL); return 0; } /* * ---------------------------------------------------------------------------- * * drcIncludeArea -- * * This is a drc utility procedure called by DBSrPaintArea. It * merely computes the total area of non-space tiles in the * given area of the plane. It is only called for non-space * tiles. * * Results: * Always returns 0 so the search continues. * * Side effects: * The client data must be a pointer to a rectangle. The * rectangle is enlarged to include the area of this tile. * * ---------------------------------------------------------------------------- */ int drcIncludeArea(tile, rect) Tile *tile; Rect *rect; /* Rectangle in which to record total area. */ { Rect dum; TiToRect(tile, &dum); (void) GeoInclude(&dum, rect); return 0; } magic-8.0.210/drc/DRCsubcell.c0000664000175000001440000005610711725464767014406 0ustar timusers/* * DRCsubcell.c -- * * This file provides the facilities for finding design-rule * violations that occur as a result of interactions between * subcells and either paint or other subcells. * * ********************************************************************* * * 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/drc/DRCsubcell.c,v 1.4 2009/05/01 18:59:44 tim Exp $"; #endif /* not lint */ #include #include #include "utils/magic.h" #include "textio/textio.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "drc/drc.h" #include "windows/windows.h" #include "commands/commands.h" #include "utils/undo.h" /* The variables below are made owns so that they can be used to * pass information to the various search functions. */ static Rect drcSubIntArea; /* Accumulates area of interactions. */ static CellDef *drcSubDef; /* Cell definition we're checking. */ static int drcSubRadius; /* Interaction radius. */ static CellUse *drcSubCurUse; /* Holds current use when checking to see * if more than one use in an area. */ static Rect drcSubLookArea; /* Area where we're looking for interactions */ static void (*drcSubFunc)(); /* Error function. */ static ClientData drcSubClientData; /* To be passed to error function. */ /* The cookie below is dummied up to provide an error message for * errors that occur because of inexact overlaps between subcells. */ static DRCCookie drcSubcellCookie = { 0, 0, 0, 0, { 0 }, { 0 }, 0, 0, 0, "This layer can't abut or partially overlap between subcells", (DRCCookie *) NULL }; extern int DRCErrorType; /* * ---------------------------------------------------------------------------- * * drcFindOtherCells -- * * This is a search function invoked when looking around a given * cell for interactions. If a cell is found other than drcSubCurUse, * then it constitutes an interaction, and its area is included * into the area parameter. * * Results: * Always returns 0 to keep the search alive. * * Side effects: * The area parameter may be modified by including the area * of the current tile. * * ---------------------------------------------------------------------------- */ int drcFindOtherCells(tile, area) Tile *tile; /* Tile in subcell plane. */ Rect *area; /* Area in which to include interactions. */ { Rect r; CellTileBody *ctbptr = (CellTileBody *) tile->ti_body; if (ctbptr == NULL) return 0; if ((ctbptr->ctb_use != drcSubCurUse) || (ctbptr->ctb_next != NULL)) { TiToRect(tile, &r); (void) GeoInclude(&r, area); } return 0; } /* * ---------------------------------------------------------------------------- * * drcSubcellTileFunc -- * * Called by TiSrArea when looking for interactions in * a given area. It sees if this subcell tile participates * in any interactions in the area we're rechecking. * * Results: * Always returns 0 to keep the search alive. * * Side effects: * The area drcSubIntArea is modified to include interactions * stemming from this subcell. * * ---------------------------------------------------------------------------- */ int drcSubcellTileFunc(tile) Tile *tile; /* Subcell tile. */ { Rect area, haloArea, intArea; int i; CellTileBody *ctbptr = (CellTileBody *) tile->ti_body; if (ctbptr == NULL) return 0; /* To determine interactions, find the bounding box of * all paint and other subcells within one halo of this * subcell tile (and also within the original area where * we're recomputing errors). */ TiToRect(tile, &area); GEO_EXPAND(&area, drcSubRadius, &haloArea); GeoClip(&haloArea, &drcSubLookArea); intArea = GeoNullRect; for (i = PL_TECHDEPBASE; i < DBNumPlanes; i++) { (void) DBSrPaintArea((Tile *) NULL, drcSubDef->cd_planes[i], &haloArea, &DBAllButSpaceBits, drcIncludeArea, (ClientData) &intArea); } drcSubCurUse = ctbptr->ctb_use; (void) TiSrArea((Tile *) NULL, drcSubDef->cd_planes[PL_CELL], &haloArea, drcFindOtherCells, (ClientData) &intArea); if (GEO_RECTNULL(&intArea)) return 0; GEO_EXPAND(&intArea, drcSubRadius, &intArea); GeoClip(&intArea, &haloArea); (void) GeoInclude(&intArea, &drcSubIntArea); return 0; } /* * ---------------------------------------------------------------------------- * * drcAlwaysOne -- * * This is a utility procedure that always returns 1 when it * is called. It aborts searches and notifies the invoker that * an item was found during the search. * * Results: * Always returns 1 to abort searches. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ int drcAlwaysOne() { return 1; } /* * ---------------------------------------------------------------------------- * * drcSubCheckPaint -- * * This procedure is invoked once for each subcell in a * particular interaction area. It checks to see whether the * subcell's subtree actually contains some paint in the potential * interaction area. As soon as the second such subcell is found, * it aborts the search. * * Results: * Returns 0 to keep the search alive, unless we've found the * second subcell containing paint in the interaction area. * When this occurs, the search is aborted by returning 1. * * Side effects: * When the first use with paint is found, curUse is modified * to contain its address. * * ---------------------------------------------------------------------------- */ int drcSubCheckPaint(scx, curUse) SearchContext *scx; /* Contains information about the celluse * that was found. */ CellUse **curUse; /* Points to a celluse, or NULL, or -1. -1 * means paint was found in the root cell, * and non-NULL means some other celluse had * paint in it. If we find another celluse * with paint, when this is non-NULL, it * means there really are two cells with * interacting paint, so we abort the * search to tell the caller to really check * this area. */ { if (DBTreeSrTiles(scx, &DBAllButSpaceAndDRCBits, 0, drcAlwaysOne, (ClientData) NULL) != 0) { /* This subtree has stuff under the interaction area. */ if (*curUse != NULL) return 1; *curUse = scx->scx_use; } return 0; } /* * ---------------------------------------------------------------------------- * * DRCFindInteractions -- * * This procedure finds the bounding box of all subcell-subcell * or subcell-paint interactions in a given area of a given cell. * * Results: * Returns TRUE if there were any interactions in the given * area, FALSE if there were none. * * Side effects: * The parameter interaction is set to contain the bounding box * of all places in area where one subcell comes within radius * of another subcell, or where paint in def comes within radius * of a subcell. Interactions between elements of array are not * considered here, but interactions between arrays and other * things are considered. This routine is a bit clever, in that * it not only checks for bounding boxes interacting, but also * makes sure the cells really contain material in the interaction * area. * ---------------------------------------------------------------------------- */ bool DRCFindInteractions(def, area, radius, interaction) CellDef *def; /* Cell to check for interactions. */ Rect *area; /* Area of def to check for interacting * material. */ int radius; /* How close two pieces of material must be * to be considered interacting. Two pieces * radius apart do NOT interact, but if they're * close than this they do. */ Rect *interaction; /* Gets filled in with the bounding box of * the interaction area, if any. Doesn't * have a defined value when FALSE is returned. */ { int i; CellUse *use; SearchContext scx; drcSubDef = def; drcSubRadius = radius; DRCDummyUse->cu_def = def; /* Find all the interactions in the area and compute the * outer bounding box of all those interactions. An interaction * exists whenever material in one cell approaches within radius * of material in another cell. As a first approximation, assume * each cell has material everywhere within its bounding box. */ drcSubIntArea = GeoNullRect; GEO_EXPAND(area, radius, &drcSubLookArea); (void) TiSrArea((Tile *) NULL, def->cd_planes[PL_CELL], &drcSubLookArea, drcSubcellTileFunc, (ClientData) NULL); /* If there seems to be an interaction area, make a second pass * to make sure there's more than one cell with paint in the * area. This will save us a lot of work where two cells * have overlapping bounding boxes without overlapping paint. */ if (GEO_RECTNULL(&drcSubIntArea)) return FALSE; use = NULL; for (i = PL_TECHDEPBASE; i < DBNumPlanes; i++) { if (DBSrPaintArea((Tile *) NULL, def->cd_planes[i], &drcSubIntArea, &DBAllButSpaceBits, drcAlwaysOne, (ClientData) NULL) != 0) { use = (CellUse *) -1; break; } } scx.scx_use = DRCDummyUse; scx.scx_trans = GeoIdentityTransform; scx.scx_area = drcSubIntArea; if (DBTreeSrCells(&scx, 0, drcSubCheckPaint, (ClientData) &use) == 0) return FALSE; /* OK, no more excuses, there's really an interaction area here. */ *interaction = drcSubIntArea; GeoClip(interaction, area); if (GEO_RECTNULL(interaction)) return FALSE; return TRUE; } /* * ---------------------------------------------------------------------------- * * drcExactOverlapCheck -- * * This procedure is invoked to check for overlap violations. * It is invoked by DBSrPaintArea from drcExactOverlapTile. * Any tiles passed to this procedure must lie within * arg->dCD_rect, or an error is reported. * * Results: * Always returns 0 to keep the search alive. * * Side effects: * If an error occurs, the client error function is called and * the error count is incremented. * * ---------------------------------------------------------------------------- */ int drcExactOverlapCheck(tile, arg) Tile *tile; /* Tile to check. */ struct drcClientData *arg; /* How to detect and process errors. */ { Rect rect; TiToRect(tile, &rect); GeoClip(&rect, arg->dCD_clip); if (GEO_RECTNULL(&rect)) return 0; (*(arg->dCD_function)) (arg->dCD_celldef, &rect, arg->dCD_cptr, arg->dCD_clientData); (*(arg->dCD_errors))++; return 0; } /* * ---------------------------------------------------------------------------- * * drcExactOverlapTile -- * * This procedure is invoked by DBTreeSrTiles for each tile * in each constituent cell of a subcell interaction. It * makes sure that if this tile overlaps other tiles of the * same type in other cells, then the overlaps are EXACT: * each cell contains exactly the same information. * * Results: * Always returns 0 to keep the search alive. * * Side effects: * If there are errors, the client error handling routine * is invoked and the count in the drcClientData record is * incremented. * * ---------------------------------------------------------------------------- */ int drcExactOverlapTile(tile, cxp) Tile *tile; /* Tile that must overlap exactly. */ TreeContext *cxp; /* Tells how to translate out of subcell. * The client data must be a drcClientData * record, and the caller must have filled * in the celldef, clip, errors, function, * cptr, and clientData fields. */ { struct drcClientData *arg; TileTypeBitMask typeMask, invMask, *rmask; TileType type, t; Tile *tp; Rect r1, r2, r3, rex; int i; arg = (struct drcClientData *) cxp->tc_filter->tf_arg; TiToRect(tile, &r1); GeoTransRect(&(cxp->tc_scx->scx_trans), &r1, &r2); GEO_EXPAND(&r2, 1, &rex); /* Area includes abutting tiles */ GeoClip(&rex, arg->dCD_clip); /* Except areas outside search area */ type = TiGetType(tile); TTMaskSetOnlyType(&typeMask, type); for (t = DBNumUserLayers; t < DBNumTypes; t++) { rmask = DBResidueMask(t); if (TTMaskHasType(rmask, type)) TTMaskSetType(&typeMask, t); } TTMaskCom2(&invMask, &typeMask); for (i = PL_TECHDEPBASE; i < DBNumPlanes; i++) { if (DBSrPaintArea((Tile *) NULL, DRCdef->cd_planes[i], &rex, &typeMask, drcAlwaysOne, (ClientData) NULL)) { /* There is an overlap or abutment of ExactOverlap types. */ /* 1) Check if any invalid type is under this tile. */ arg->dCD_rect = &r2; DBSrPaintArea((Tile *) NULL, DRCdef->cd_planes[i], &r2, &invMask, drcExactOverlapCheck, (ClientData) arg); /* 2) Search the neighboring tiles for types that do not */ /* match the exact overlap type, and flag abutment errors. */ /* Search bottom */ arg->dCD_rect = &r3; for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp)) if (TTMaskHasType(&invMask, TiGetType(tp))) { TiToRect(tp, &r1); GeoTransRect(&(cxp->tc_scx->scx_trans), &r1, &r3); GeoClip(&r3, &rex); if (!GEO_RECTNULL(&r3)) DBSrPaintArea((Tile *) NULL, DRCdef->cd_planes[i], &r3, &typeMask, drcExactOverlapCheck, (ClientData) arg); } /* Search right */ for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp)) if (TTMaskHasType(&invMask, TiGetType(tp))) { TiToRect(tp, &r1); GeoTransRect(&(cxp->tc_scx->scx_trans), &r1, &r3); GeoClip(&r3, &rex); if (!GEO_RECTNULL(&r3)) DBSrPaintArea((Tile *) NULL, DRCdef->cd_planes[i], &r3, &typeMask, drcExactOverlapCheck, (ClientData) arg); } /* Search top */ for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp)) if (TTMaskHasType(&invMask, TiGetType(tp))) { TiToRect(tp, &r1); GeoTransRect(&(cxp->tc_scx->scx_trans), &r1, &r3); GeoClip(&r3, &rex); if (!GEO_RECTNULL(&r3)) DBSrPaintArea((Tile *) NULL, DRCdef->cd_planes[i], &r3, &typeMask, drcExactOverlapCheck, (ClientData) arg); } /* Search left */ for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp)) if (TTMaskHasType(&invMask, TiGetType(tp))) { TiToRect(tp, &r1); GeoTransRect(&(cxp->tc_scx->scx_trans), &r1, &r3); GeoClip(&r3, &rex); if (!GEO_RECTNULL(&r3)) DBSrPaintArea((Tile *) NULL, DRCdef->cd_planes[i], &r3, &typeMask, drcExactOverlapCheck, (ClientData) arg); } } } return 0; } /* * ---------------------------------------------------------------------------- * * DRCInteractionCheck -- * * This is the top-level procedure that performs subcell interaction * checks. All interaction rule violations in area of def are * found, and func is called for each one. * * Results: * The number of errors found. * * Side effects: * The procedure func is called for each violation found. See * the header for DRCBasicCheck for information about how func * is called. The violations passed to func are expressed in * the coordinates of def. Only violations stemming from * interactions in def, as opposed to def's children, are reported. * * Design Note: * This procedure is trickier than you think. The problem is that * DRC must be guaranteed to produce EXACTLY the same collection * of errors in an area, no matter how the area is checked. Checking * it all as one big area should produce the same results as * checking it in several smaller pieces. Otherwise, "drc why" * won't work correctly, and the error configuration will depend * on how the chip was checked, which is intolerable. This problem * is solved here by dividing the world up into squares along a grid * of dimension DRCStepSize aligned at the origin. Interaction areas * are always computed by considering everything inside one grid square * at a time. We may have to consider several grid squares in order * to cover the area passed in by the client. * ---------------------------------------------------------------------------- */ int DRCInteractionCheck(def, area, erasebox, func, cdarg) CellDef *def; /* Definition in which to do check. */ Rect *area; /* Area in which all errors are to be found. */ Rect *erasebox; /* Smaller area containing DRC check tiles */ void (*func)(); /* Function to call for each error. */ ClientData cdarg; /* Extra info to be passed to func. */ { int oldTiles, count, x, y, errorSaveType; Rect intArea, square, subArea; PaintResultType (*savedPaintTable)[NT][NT]; void (*savedPaintPlane)(); struct drcClientData arg; SearchContext scx; drcSubFunc = func; drcSubClientData = cdarg; oldTiles = DRCstatTiles; count = 0; /* Divide the area to be checked up into squares. Process each * square separately. */ x = (area->r_xbot/DRCStepSize) * DRCStepSize; if (x > area->r_xbot) x -= DRCStepSize; y = (area->r_ybot/DRCStepSize) * DRCStepSize; if (y > area->r_ybot) y -= DRCStepSize; for (square.r_xbot = x; square.r_xbot < area->r_xtop; square.r_xbot += DRCStepSize) for (square.r_ybot = y; square.r_ybot < area->r_ytop; square.r_ybot += DRCStepSize) { square.r_xtop = square.r_xbot + DRCStepSize; square.r_ytop = square.r_ybot + DRCStepSize; /* Find all the interactions in the square, and clip to the error * area we're interested in. */ if (!DRCFindInteractions(def, &square, DRCTechHalo, &intArea)) { /* Added May 4, 2008---if there are no subcells, run the * basic check over the area of the square. */ subArea = *erasebox; GeoClip(&subArea, &square); GEO_EXPAND(&subArea, DRCTechHalo, &intArea); errorSaveType = DRCErrorType; DRCErrorType = TT_ERROR_P; // Basic check is always ERROR_P DRCBasicCheck(def, &intArea, &subArea, func, cdarg); DRCErrorType = errorSaveType; continue; } else { /* Added March 6, 2012: Any area(s) outside the * interaction area are processed with the basic * check. This avoids unnecessary copying, so it * speeds up the DRC without requiring that geometry * passes DRC rules independently of subcell geometry * around it. * * As intArea can be smaller than square, we may have * to process as many as four independent rectangles. * NOTE that the area of (intArea + halo) will be checked * in the subcell interaction check, so we can ignore * that. */ Rect eraseClip, eraseHalo, subArea; errorSaveType = DRCErrorType; DRCErrorType = TT_ERROR_P; // Basic check is always ERROR_P eraseClip = *erasebox; GeoClip(&eraseClip, &square); subArea = eraseClip; /* check above */ if (intArea.r_ytop < eraseClip.r_ytop) { subArea.r_ybot = intArea.r_ytop; GEO_EXPAND(&subArea, DRCTechHalo, &eraseHalo); DRCBasicCheck(def, &eraseHalo, &subArea, func, cdarg); } /* check below */ if (intArea.r_ybot > eraseClip.r_ybot) { subArea.r_ybot = eraseClip.r_ybot; subArea.r_ytop = intArea.r_ybot; GEO_EXPAND(&subArea, DRCTechHalo, &eraseHalo); DRCBasicCheck(def, &eraseHalo, &subArea, func, cdarg); } subArea.r_ytop = intArea.r_ytop; subArea.r_ybot = intArea.r_ybot; /* check right */ if (intArea.r_xtop < eraseClip.r_xtop) { subArea.r_xbot = intArea.r_xtop; GEO_EXPAND(&subArea, DRCTechHalo, &eraseHalo); DRCBasicCheck(def, &eraseHalo, &subArea, func, cdarg); } /* check left */ if (intArea.r_xbot > eraseClip.r_xbot) { subArea.r_xtop = intArea.r_xbot; subArea.r_xbot = eraseClip.r_xbot; GEO_EXPAND(&subArea, DRCTechHalo, &eraseHalo); DRCBasicCheck(def, &eraseHalo, &subArea, func, cdarg); } DRCErrorType = errorSaveType; } /* Flatten the interaction area. */ DRCstatInteractions += 1; GEO_EXPAND(&intArea, DRCTechHalo, &scx.scx_area); DRCDummyUse->cu_def = def; scx.scx_use = DRCDummyUse; scx.scx_trans = GeoIdentityTransform; DBCellClearDef(DRCdef); savedPaintTable = DBNewPaintTable(DRCCurStyle->DRCPaintTable); savedPaintPlane = DBNewPaintPlane(DBPaintPlaneMark); (void) DBCellCopyAllPaint(&scx, &DBAllButSpaceBits, 0, DRCuse); (void) DBNewPaintTable(savedPaintTable); (void) DBNewPaintPlane(savedPaintPlane); /* Run the basic checker over the interaction area. */ count += DRCBasicCheck(DRCdef, &scx.scx_area, &intArea, func, cdarg); /* TxPrintf("Interaction area: (%d, %d) (%d %d)\n", intArea.r_xbot, intArea.r_ybot, intArea.r_xtop, intArea.r_ytop); */ /* Check for illegal partial overlaps. */ scx.scx_use = DRCDummyUse; scx.scx_area = intArea; scx.scx_trans = GeoIdentityTransform; arg.dCD_celldef = DRCdef; arg.dCD_clip = &intArea; arg.dCD_errors = &count; arg.dCD_cptr = &drcSubcellCookie; arg.dCD_function = func; arg.dCD_clientData = cdarg; (void) DBTreeSrUniqueTiles(&scx, &DRCCurStyle->DRCExactOverlapTypes, 0, drcExactOverlapTile, (ClientData) &arg); } /* Update count of interaction tiles processed. */ DRCstatIntTiles += DRCstatTiles - oldTiles; return count; } void DRCFlatCheck(use, area) CellUse *use; Rect *area; { int x, y; Rect chunk; SearchContext scx; void drcIncCount(); PaintResultType (*savedPaintTable)[NT][NT]; void (*savedPaintPlane)(); int drcFlatCount = 0; UndoDisable(); for (y = area->r_ybot; y < area->r_ytop; y += 300) { for (x = area->r_xbot; x < area->r_xtop; x += 300) { chunk.r_xbot = x; chunk.r_ybot = y; chunk.r_xtop = x+300; chunk.r_ytop = y+300; if (chunk.r_xtop > area->r_xtop) chunk.r_xtop = area->r_xtop; if (chunk.r_ytop > area->r_ytop) chunk.r_ytop = area->r_ytop; GEO_EXPAND(&chunk, DRCTechHalo, &scx.scx_area); scx.scx_use = use; scx.scx_trans = GeoIdentityTransform; DBCellClearDef(DRCdef); savedPaintTable = DBNewPaintTable(DRCCurStyle->DRCPaintTable); savedPaintPlane = DBNewPaintPlane(DBPaintPlaneMark); (void) DBCellCopyAllPaint(&scx, &DBAllButSpaceBits, 0, DRCuse); (void) DBNewPaintTable(savedPaintTable); (void) DBNewPaintPlane(savedPaintPlane); (void) DRCBasicCheck(DRCdef, &scx.scx_area, &chunk, drcIncCount, (ClientData) &drcFlatCount); } } TxPrintf("%d total errors found.\n", drcFlatCount); UndoEnable(); } void drcIncCount(def, area, rule, count) CellDef *def; Rect *area; DRCCookie *rule; int *count; { *count++; } magic-8.0.210/drc/DRCtech.c0000664000175000001440000031425512360275367013671 0ustar timusers/* * DRCtech.c -- * * Technology initialization for the DRC module. * * ********************************************************************* * * 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/drc/DRCtech.c,v 1.12 2010/10/20 12:04:12 tim Exp $"; #endif /* not lint */ #include #include #include #include "tcltk/tclmagic.h" #include "utils/magic.h" #include "utils/geometry.h" #include "utils/utils.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "drc/drc.h" #include "utils/tech.h" #include "textio/textio.h" #include "utils/malloc.h" #include "cif/cif.h" #include "cif/CIFint.h" CIFStyle *drcCifStyle = NULL; bool DRCForceReload = FALSE; /* * DRC interaction radius being used (not necessarily the same as * what's defined in the current DRC style). */ global int DRCTechHalo; global int DRCStepSize; /* The following variable can be set to zero to turn off * any optimizations of design rule lists. */ global int DRCRuleOptimization = TRUE; /* The following variables count how many rules were specified by * the technology file and how many edge rules were optimized away. */ static int drcRulesSpecified = 0; static int drcRulesOptimized = 0; /* * Forward declarations. */ int drcWidth(), drcSpacing(), drcEdge(), drcNoOverlap(); int drcExactOverlap(), drcExtend(); int drcSurround(), drcRectOnly(), drcOverhang(); int drcStepSize(); int drcMaxwidth(), drcArea(), drcRectangle(), drcAngles(); int drcCifSetStyle(), drcCifWidth(), drcCifSpacing(); int drcCifMaxwidth(), drcCifArea(); void DRCTechStyleInit(); void drcLoadStyle(); void DRCTechFinal(); void drcTechFinalStyle(); /* * ---------------------------------------------------------------------------- * * Given a TileType bit mask, return the plane mask of planes that are * coincident with all types. This is roughly equivalent to the deprecated * DBTechMinSetPlanes(), but does not attempt to produce a reduced set of * tile types. Since the collective mask of all possible planes is usually * found by a call to DBTechNoisyNameMask, we don't attempt to OR all the * plane masks together, but assume this collective mask is available and * passed as an argument. * * ---------------------------------------------------------------------------- */ PlaneMask CoincidentPlanes(typeMask, pmask) TileTypeBitMask *typeMask; /* Mask of types to check coincidence */ PlaneMask pmask; /* Mask of all possible planes of types */ { PlaneMask planes = pmask; TileType i; /* AND each plane against the collective mask */ for (i = TT_SELECTBASE; i < DBNumTypes; i++) if (TTMaskHasType(typeMask, i)) planes &= DBTypePlaneMaskTbl[i]; return planes; } /* * ---------------------------------------------------------------------------- * * Given a plane mask, return the plane number of the lowest plane in the mask. * * ---------------------------------------------------------------------------- */ int LowestMaskBit(PlaneMask pmask) { PlaneMask pset = pmask; int plane = 0; if (pmask == 0) return DBNumPlanes; while ((pset & 0x1) == 0) { plane++; pset >>= 1; } return plane; } /* * ---------------------------------------------------------------------------- * * DRCPrintStyle -- * * Print the available and/or current extraction styles. * * Results: * None. * * Side effects: * Output. * * ---------------------------------------------------------------------------- */ void DRCPrintStyle(dolist, doforall, docurrent) bool dolist, doforall, docurrent; { DRCKeep *style; if (docurrent) { if (DRCCurStyle == NULL) TxError("Error: No style is set\n"); else { if (!dolist) TxPrintf("The current style is \""); #ifdef MAGIC_WRAPPER if (dolist) Tcl_SetResult(magicinterp, DRCCurStyle->ds_name, NULL); else #endif TxPrintf("%s", DRCCurStyle->ds_name); if (!dolist) TxPrintf("\".\n"); } } if (doforall) { if (!dolist) TxPrintf("The DRC styles are: "); for (style = DRCStyleList; style; style = style->ds_next) { if (dolist) { #ifdef MAGIC_WRAPPER Tcl_AppendElement(magicinterp, style->ds_name); #else if (style != DRCStyleList) TxPrintf(" "); TxPrintf("%s", style->ds_name); #endif } else { if (style != DRCStyleList) TxPrintf(", "); TxPrintf("%s", style->ds_name); } } if (!dolist) TxPrintf(".\n"); } } /* * ---------------------------------------------------------------------------- * * DRCSetStyle -- * * Set the current DRC style to 'name'. * * Results: * None. * * Side effects: * Output. * * ---------------------------------------------------------------------------- */ void DRCSetStyle(name) char *name; { DRCKeep *style, *match; int length; if (name == NULL) return; match = NULL; length = strlen(name); for (style = DRCStyleList; style; style = style->ds_next) { if (strncmp(name, style->ds_name, length) == 0) { if (match != NULL) { TxError("DRC style \"%s\" is ambiguous.\n", name); DRCPrintStyle(FALSE, TRUE, TRUE); return; } match = style; } } if (match != NULL) { drcLoadStyle(match->ds_name); TxPrintf("DRC style is now \"%s\"\n", name); return; } TxError("\"%s\" is not one of the DRC styles Magic knows.\n", name); DRCPrintStyle(FALSE, TRUE, TRUE); } /* * ---------------------------------------------------------------------------- * * drcTechFreeStyle -- * * This procedure frees all memory associated with a DRC style. * * Results: * None. * * Side effects: * Memory free'd. * * ---------------------------------------------------------------------------- */ void drcTechFreeStyle() { int i, j; char *old; DRCCookie *dp; if (DRCCurStyle != NULL) { /* Remove all old rules from the DRC rules table */ for (i = 0; i < TT_MAXTYPES; i++) for (j = 0; j < TT_MAXTYPES; j++) { dp = DRCCurStyle->DRCRulesTbl[i][j]; while (dp != NULL) { char *old = (char *) dp; dp = dp->drcc_next; freeMagic(old); } } /* Clear the DRCWhyList */ while (DRCCurStyle->DRCWhyList != NULL) { old = (char *) DRCCurStyle->DRCWhyList; StrDup(&(DRCCurStyle->DRCWhyList->dwl_string), (char *) NULL); DRCCurStyle->DRCWhyList = DRCCurStyle->DRCWhyList->dwl_next; freeMagic(old); } freeMagic(DRCCurStyle); DRCCurStyle = NULL; } } /* * ---------------------------------------------------------------------------- * * drcTechNewStyle -- * * This procedure creates a new DRC style at the end of the list * of styles and initializes it to completely null. * * Results: * None. * * Side effects: * A new element is added to the end of DRCStyleList, and DRCCurStyle * is set to point to it. * * ---------------------------------------------------------------------------- */ void drcTechNewStyle() { drcTechFreeStyle(); DRCTechStyleInit(); } /* * ---------------------------------------------------------------------------- * drcWhyDup -- * * Duplicate a shared "why" string using StrDup() and remember it so we can * free it sometime later, in drcWhyClear(). * * Returns: * A copy of the given string. * * Side effects: * Adds to the DRCWhyList. Calls StrDup(). * ---------------------------------------------------------------------------- */ char * drcWhyDup(why) char * why; { struct drcwhylist * new; new = (struct drcwhylist *) mallocMagic((unsigned) (sizeof *new)); new->dwl_string = StrDup((char **) NULL, why); new->dwl_next = DRCCurStyle->DRCWhyList; DRCCurStyle->DRCWhyList = new; return new->dwl_string; } /* * ---------------------------------------------------------------------------- * * drcFindBucket -- * * Find the bucket preceding the point where we with to insert a new DRC * cookie. Don't insert a cookie in the middle of a pair of coupled * (trigger + check) rules. * * Results: * Returns a pointer to the location where we want to insert a rule * * Side effects: * None. * * ---------------------------------------------------------------------------- */ DRCCookie * drcFindBucket(i, j, distance) int i, j, distance; { DRCCookie *dp; if (DRCCurStyle == NULL) return NULL; /* find bucket preceding the new one we wish to insert */ for (dp = DRCCurStyle->DRCRulesTbl[i][j]; dp->drcc_next != (DRCCookie *) NULL; dp = dp->drcc_next) { if (dp->drcc_next->drcc_flags & DRC_TRIGGER) { if (dp->drcc_next->drcc_next->drcc_dist >= distance) break; else dp = dp->drcc_next; } else if (dp->drcc_next->drcc_dist >= distance) break; } return dp; } /* * ---------------------------------------------------------------------------- * * drcLoadStyle -- * * Re-read the technology file to load the specified technology DRC style * into structure DRCCurStyle. It incurs a complete reading of the tech * file on startup and every time the extraction style is changed, but we * can assume that this does not happen often. The first style in the * technology file is assumed to be the default, so that re-reading the * tech file is not necessary on startup unless the default DRC style is * changed by a call do "drc style". * * ---------------------------------------------------------------------------- */ void drcLoadStyle(stylename) char *stylename; { SectionID invdrc; if (DRCCurStyle->ds_name == stylename) return; drcTechNewStyle(); /* Reinitialize and mark as not loaded */ DRCCurStyle->ds_name = stylename; invdrc = TechSectionGetMask("drc", NULL); TechLoad(NULL, invdrc); DRCTechScale(DBLambda[0], DBLambda[1]); } /* * ---------------------------------------------------------------------------- * DRCReloadCurStyle --- * * This routine is used by CIFLoadStyle whenever the DRC section makes * reference to CIF layers. * * Results: * None. * * Side Effects: * DRC rule database is deleted and regenerated. * * ---------------------------------------------------------------------------- */ void DRCReloadCurStyle() { char *stylename; DRCKeep * style; if (DRCCurStyle == NULL) return; for (style = DRCStyleList; style != NULL; style = style->ds_next) { if (!strcmp(style->ds_name, DRCCurStyle->ds_name)) { DRCCurStyle->ds_name = NULL; drcLoadStyle(style->ds_name); break; } } } /* * ---------------------------------------------------------------------------- * DRCTechInit -- * * Free and re-initialize the technology-specific variables for the DRC module. * This routine is *only* called upon a "tech load" command, when all existing * DRC data must be cleaned up and free'd. * * Results: * None. * * Side effects: * Clears out all the DRC tables. * ---------------------------------------------------------------------------- */ void DRCTechInit() { DRCKeep *style; /* Clean up any old info */ drcTechFreeStyle(); for (style = DRCStyleList; style != NULL; style = style->ds_next) { freeMagic(style->ds_name); freeMagic(style); } DRCStyleList = NULL; } /* * ---------------------------------------------------------------------------- * DRCTechStyleInit -- * * Initialize the technology-specific variables for the DRC module. * * Results: * None. * * Side effects: * Clears out all the DRC tables. * ---------------------------------------------------------------------------- */ void DRCTechStyleInit() { int i, j, plane; DRCCookie *dp; PaintResultType result; drcRulesOptimized = 0; drcRulesSpecified = 0; if (DRCCurStyle == NULL) { DRCCurStyle = (DRCStyle *) mallocMagic(sizeof(DRCStyle)); DRCCurStyle->ds_name = NULL; } DRCCurStyle->ds_status = TECH_NOT_LOADED; TTMaskZero(&DRCCurStyle->DRCExactOverlapTypes); DRCCurStyle->DRCWhyList = NULL; DRCCurStyle->DRCTechHalo = 0; DRCCurStyle->DRCScaleFactorN = 1; DRCCurStyle->DRCScaleFactorD = 1; DRCCurStyle->DRCStepSize = 0; DRCTechHalo = 0; /* Put a dummy rule at the beginning of the rules table for each entry */ for (i = 0; i < TT_MAXTYPES; i++) { for (j = 0; j < TT_MAXTYPES; j++) { dp = DRCCurStyle->DRCRulesTbl[i][j]; dp = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); dp->drcc_dist = -1; dp->drcc_next = (DRCCookie *) NULL; TTMaskZero(&dp->drcc_mask); DRCCurStyle->DRCRulesTbl[i][j] = dp; } } /* Copy the default paint table into the DRC paint table. The DRC * paint table will be modified as we read the drc section. Also * make sure that the error layer is super-persistent (once it * appears, it can't be gotten rid of by painting). Also, make * some crossings automatically illegal: two layers can't cross * unless the result of painting one on top of the other is to * get one of the layers, and it doesn't matter which is painted * on top of which. */ for (plane = 0; plane < DBNumPlanes; plane++) for (i = 0; i < DBNumTypes; i++) for (j = 0; j < DBNumTypes; j++) { result = DBPaintResultTbl[plane][i][j]; if ((i == TT_ERROR_S) || (j == TT_ERROR_S)) DRCCurStyle->DRCPaintTable[plane][i][j] = TT_ERROR_S; else if ((i == TT_SPACE) || (j == TT_SPACE) || !DBTypeOnPlane(j, plane) || !DBPaintOnTypePlanes(i, j)) DRCCurStyle->DRCPaintTable[plane][i][j] = result; /* Modified for stackable types (Tim, 10/3/03) */ else if ((i >= DBNumUserLayers) || ((result >= DBNumUserLayers) && (DBTechFindStacking(i, j) == result))) { DRCCurStyle->DRCPaintTable[plane][i][j] = result; } else if ((!TTMaskHasType(&DBLayerTypeMaskTbl[i], result) && !TTMaskHasType(&DBLayerTypeMaskTbl[j], result)) || ((result != DBPaintResultTbl[plane][j][i]) && DBTypeOnPlane(i, plane) && DBPaintOnTypePlanes(j, i))) { DRCCurStyle->DRCPaintTable[plane][i][j] = TT_ERROR_S; /* TxError("Error: %s on %s, was %s\n", DBTypeLongNameTbl[i], DBTypeLongNameTbl[j], DBTypeLongNameTbl[result]); */ } else DRCCurStyle->DRCPaintTable[plane][i][j] = result; } drcCifInit(); } /* * ---------------------------------------------------------------------------- * * DRCTechLine -- * * Parse a line in the DRC section from the technology file. Handle DRC * styles. The rules themselves are handled by DRCTechAddRule. * * Results: * TRUE if line parsed correctly; FALSE if fatal error condition * encountered. * * Side effects: * Appends information to the DRC tables. * * ---------------------------------------------------------------------------- */ bool DRCTechLine(sectionName, argc, argv) char *sectionName; /* The name of this section */ int argc; /* Number of fields on the line */ char *argv[]; /* Values of the fields */ { int j, l; DRCKeep *newStyle, *p; char *tptr, *cptr; if (argc <= 0) return TRUE; else if (argc >= 2) l = strlen(argv[1]); if (strcmp(argv[0], "style") == 0) { if (argc != 2) { if ((argc != 4) || (strncmp(argv[2], "variant", 7))) { wrongNumArgs: TechError("Wrong number of arguments in %s statement.\n", argv[0]); return TRUE; } } for (newStyle = DRCStyleList; newStyle != NULL; newStyle = newStyle->ds_next) { /* Here we're only establishing existance; break on * the first variant found. */ if (!strncmp(newStyle->ds_name, argv[1], l)) break; } if (newStyle == NULL) { if (argc == 2) { newStyle = (DRCKeep *)mallocMagic(sizeof(DRCKeep)); newStyle->ds_next = NULL; newStyle->ds_name = StrDup((char **) NULL, argv[1]); /* Append to end of style list */ if (DRCStyleList == NULL) DRCStyleList = newStyle; else { for (p = DRCStyleList; p->ds_next; p = p->ds_next); p->ds_next = newStyle; } } else /* Handle style variants */ { DRCKeep *saveStyle = NULL; /* 4th argument is a comma-separated list of variants */ tptr = argv[3]; while (*tptr != '\0') { cptr = strchr(tptr, ','); if (cptr != NULL) *cptr = '\0'; newStyle = (DRCKeep *)mallocMagic(sizeof(DRCKeep)); newStyle->ds_next = NULL; newStyle->ds_name = (char *)mallocMagic(l + strlen(tptr) + 1); sprintf(newStyle->ds_name, "%s%s", argv[1], tptr); /* Remember the 1st variant as the default */ if (saveStyle == NULL) saveStyle = newStyle; /* Append to end of style list */ if (DRCStyleList == NULL) DRCStyleList = newStyle; else { for (p = DRCStyleList; p->ds_next; p = p->ds_next); p->ds_next = newStyle; } if (cptr == NULL) break; else tptr = cptr + 1; } newStyle = saveStyle; } } if (DRCCurStyle == NULL) /* Shouldn't happen, but be safe. . .*/ { drcTechNewStyle(); DRCCurStyle->ds_name = newStyle->ds_name; DRCCurStyle->ds_status = TECH_PENDING; } else if ((DRCCurStyle->ds_status == TECH_PENDING) || (DRCCurStyle->ds_status == TECH_SUSPENDED)) DRCCurStyle->ds_status = TECH_LOADED; else if (DRCCurStyle->ds_status == TECH_NOT_LOADED) { if (DRCCurStyle->ds_name == NULL) { DRCCurStyle->ds_name = newStyle->ds_name; DRCCurStyle->ds_status = TECH_PENDING; } else if (argc == 2) { if (!strcmp(argv[1], DRCCurStyle->ds_name)) DRCCurStyle->ds_status = TECH_PENDING; } else if (argc == 4) { /* Verify that the style matches one variant */ if (!strncmp(DRCCurStyle->ds_name, argv[1], l)) { tptr = argv[3]; while (*tptr != '\0') { cptr = strchr(tptr, ','); if (cptr != NULL) *cptr = '\0'; if (!strcmp(DRCCurStyle->ds_name + l, tptr)) { DRCCurStyle->ds_status = TECH_PENDING; return TRUE; } if (cptr == NULL) return TRUE; else tptr = cptr + 1; } } } } return (TRUE); } if (DRCCurStyle == NULL) return FALSE; /* For backwards compatibility, if we have encountered a line that */ /* is not "style" prior to setting a style, then we create a style */ /* called "default". */ if (DRCStyleList == NULL) { char *locargv[2][10] = {"style", "default"}; if (DRCTechLine(sectionName, 2, locargv) == FALSE) return FALSE; } else if (DRCStyleList->ds_next == NULL) { /* On reload, if there is only one style, use it. This is */ /* necessary for the DRC-CIF extensions, since even though */ /* the one-and-only DRC section may have been loaded, the DRC- */ /* CIF parts of it become enabled or disabled depending on what */ /* CIFCurStyle is active. */ DRCCurStyle->ds_status = TECH_PENDING; } /* Only continue past this point if we are loading the DRC style */ if ((DRCCurStyle->ds_status != TECH_PENDING) && (DRCCurStyle->ds_status != TECH_SUSPENDED)) return TRUE; /* Process "scalefactor" line next (if any) */ if (strcmp(argv[0], "scalefactor") == 0) { int scaleN, scaleD; if (argc != 2 && argc != 3) goto wrongNumArgs; scaleN = atof(argv[1]); if (argc == 3) scaleD = atof(argv[2]); else scaleD = 1; if (scaleN <= 0 || scaleN > 255 || scaleD <= 0 || scaleD > 255) { TechError("Scale factor must be between 1 and 255.\n"); TechError("Setting scale factor to default value 1.\n"); DRCCurStyle->DRCScaleFactorN = 1; DRCCurStyle->DRCScaleFactorD = 1; return TRUE; } DRCCurStyle->DRCScaleFactorN = scaleN; DRCCurStyle->DRCScaleFactorD = scaleD; return TRUE; } /* Process "variant" lines next. */ if (strncmp(argv[0], "variant", 7) == 0) { /* If our style variant is not one of the ones declared */ /* on the line, then we ignore all input until we */ /* either reach the end of the style, the end of the */ /* section, or another "variant" line. */ if (argc != 2) goto wrongNumArgs; tptr = argv[1]; while (*tptr != '\0') { cptr = strchr(tptr, ','); if (cptr != NULL) { *cptr = '\0'; for (j = 1; isspace(*(cptr - j)); j++) *(cptr - j) = '\0'; } if (*tptr == '*') { DRCCurStyle->ds_status = TECH_PENDING; return TRUE; } else { l = strlen(DRCCurStyle->ds_name) - strlen(tptr); if (!strcmp(tptr, DRCCurStyle->ds_name + l)) { DRCCurStyle->ds_status = TECH_PENDING; return TRUE; } } if (cptr == NULL) break; else tptr = cptr + 1; } DRCCurStyle->ds_status = TECH_SUSPENDED; } /* Anything below this line is not parsed if we're in TECH_SUSPENDED mode */ if (DRCCurStyle->ds_status != TECH_PENDING) return TRUE; return DRCTechAddRule(sectionName, argc, argv); } void drcAssign(cookie, dist, next, mask, corner, why, cdist, flags, planeto, planefrom) DRCCookie *cookie, *next; int dist, cdist; TileTypeBitMask *mask, *corner; char *why; int flags, planeto, planefrom; { /* Diagnostic */ if (planeto >= DBNumPlanes) { TxError("Bad plane in DRC assign!\n"); } (cookie)->drcc_dist = dist; (cookie)->drcc_next = next; (cookie)->drcc_mask = *mask; (cookie)->drcc_corner = *corner; (cookie)->drcc_why = why; (cookie)->drcc_cdist = cdist; (cookie)->drcc_flags = flags; (cookie)->drcc_edgeplane = planefrom; (cookie)->drcc_plane = planeto; (cookie)->drcc_mod = 0; (cookie)->drcc_cmod = 0; } /* * ---------------------------------------------------------------------------- * * DRCTechAddRule -- * * Add a new entry to the DRC table. * * Results: * Always returns TRUE so that tech file read-in doesn't abort. * * Side effects: * Updates the DRC technology variables. * * Organization: * We select a procedure based on the first keyword (argv[0]) * and call it to do the work of implementing the rule. Each * such procedure is of the following form: * * int * proc(argc, argv) * int argc; * char *argv[]; * { * } * * It returns the distance associated with the design rule, * or -1 in the event of a fatal error that should cause * DRCTechAddRule() to return FALSE (currently, none of them * do, so we always return TRUE). If there is no distance * associated with the design rule, 0 is returned. * * ---------------------------------------------------------------------------- */ /* ARGSUSED */ bool DRCTechAddRule(sectionName, argc, argv) char *sectionName; /* Unused */ int argc; char *argv[]; { int which, distance, mdist; char *fmt; static struct { char *rk_keyword; /* Initial keyword */ int rk_minargs; /* Min # arguments */ int rk_maxargs; /* Max # arguments */ int (*rk_proc)(); /* Procedure implementing this keyword */ char *rk_err; /* Error message */ } ruleKeys[] = { "angles", 4, 4, drcAngles, "layers 45|90 why", "edge", 8, 9, drcEdge, "layers1 layers2 distance okTypes cornerTypes cornerDistance why [plane]", "edge4way", 8, 9, drcEdge, "layers1 layers2 distance okTypes cornerTypes cornerDistance why [plane]", "exact_overlap", 2, 2, drcExactOverlap, "layers", "extend", 5, 6, drcExtend, "layers1 layers2 distance why", "no_overlap", 3, 3, drcNoOverlap, "layers1 layers2", "overhang", 5, 5, drcOverhang, "layers1 layers2 distance why", "rect_only", 3, 3, drcRectOnly, "layers why", "spacing", 6, 7, drcSpacing, "layers1 layers2 separation [layers3] adjacency why", "stepsize", 2, 2, drcStepSize, "step_size", "surround", 6, 6, drcSurround, "layers1 layers2 distance presence why", "width", 4, 4, drcWidth, "layers width why", "widespacing", 7, 7, drcSpacing, "layers1 width layers2 separation adjacency why", "area", 5, 5, drcArea, "layers area horizon why", "maxwidth", 4, 5, drcMaxwidth, "layers maxwidth bends why", "cifstyle", 2, 2, drcCifSetStyle, "cif_style", "cifwidth", 4, 4, drcCifWidth, "layers width why", "cifspacing", 6, 6, drcCifSpacing, "layers1 layers2 separation adjacency why", "cifarea", 5, 5, drcCifArea, "layers area horizon why", "cifmaxwidth", 5, 5, drcCifMaxwidth, "layers maxwidth bends why", "rectangle", 5, 5, drcRectangle, "layers maxwidth [even|odd|any] why", 0 }, *rp; drcRulesSpecified += 1; which = LookupStruct(argv[0], (LookupTable *) ruleKeys, sizeof ruleKeys[0]); if (which < 0) { TechError("Bad DRC rule type \"%s\"\n", argv[0]); TxError("Valid rule types are:\n"); for (fmt = "%s", rp = ruleKeys; rp->rk_keyword; rp++, fmt = ", %s") TxError(fmt, rp->rk_keyword); TxError(".\n"); return (TRUE); } rp = &ruleKeys[which]; if (argc < rp->rk_minargs || argc > rp->rk_maxargs) { TechError("Rule type \"%s\" usage: %s %s\n", rp->rk_keyword, rp->rk_keyword, rp->rk_err); return (TRUE); } distance = (*rp->rk_proc)(argc, argv); if (distance < 0) return (FALSE); /* Update the halo to be the maximum distance (in magic units) of */ /* any design rule */ mdist = distance; if (mdist > DRCTechHalo) DRCTechHalo = mdist; return (TRUE); } /* * ---------------------------------------------------------------------------- * * drcExtend -- * * Process an extension rule. * This is of the form: * * extend layers1 layers2 distance [exact_width] why * * indicating that if "layers1" extends from "layers2", then it must * have a width of at least "distance". This is very much like the * "overhang" rule, except that the extension is optional. Example: * * extend nfet ndiff 2 "n-transistor length must be at least 2" * * "extend" implements the following general-purpose edge rule: * * edge4way layers2 layers1 distance layers1 0 0 why * * Option "exact_width" implements an additional rule that checks for * maximum extension at distance. This is intended for use with, for * example, a fixed gate length for a specific type of device. * * Results: * Returns distance. * * Side effects: * Updates the DRC technology variables. * * ---------------------------------------------------------------------------- */ int drcExtend(argc, argv) int argc; char *argv[]; { char *layers1 = argv[1]; char *layers2 = argv[2]; int distance = atoi(argv[3]); char *why; TileTypeBitMask set1, setC; DRCCookie *dp, *dpnew, *dptrig; TileType i, j; int plane, plane2; TileTypeBitMask set2, setZ, setN; PlaneMask pMask1, pMask2, pset, ptest; bool exact = FALSE; if (!strncmp(argv[4], "exact_", 6)) { exact = TRUE; why = drcWhyDup(argv[5]); } else why = drcWhyDup(argv[4]); ptest = DBTechNoisyNameMask(layers1, &set1); pMask1 = CoincidentPlanes(&set1, ptest); if (pMask1 == 0) { TechError("All layers in first set for \"extend\" must be on " "the same plane\n"); return (0); } TTMaskCom2(&setN, &set1); ptest = DBTechNoisyNameMask(layers2, &set2); pMask2 = CoincidentPlanes(&set2, ptest); if (pMask2 == 0) { TechError("All layers in second set for \"extend\" must be on " "the same plane\n"); return (0); } TTMaskCom2(&setC, &set2); /* Zero mask */ TTMaskZero(&setZ); for (i = 0; i < DBNumTypes; i++) { for (j = 0; j < DBNumTypes; j++) { if (i == j) continue; if (pset = (DBTypesOnSamePlane(i, j) & pMask2)) { /* Edge depends on whether or not the extension is */ /* on the same plane as the layer from which it is */ /* measured. */ if ((pset & pMask1) != 0) { if (TTMaskHasType(&set2, i) && TTMaskHasType(&set1, j)) { plane = LowestMaskBit(pset & pMask1); /* find bucket preceding the new one we wish to insert */ dp = drcFindBucket(i, j, distance); dpnew = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &set1, &setZ, why, 0, DRC_FORWARD, plane, plane); dp->drcc_next = dpnew; dp = drcFindBucket(j, i, distance); dpnew = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &set1, &setZ, why, 0, DRC_REVERSE, plane, plane); dp->drcc_next = dpnew; if (exact) { /* find bucket preceding the new one we wish to insert */ dp = drcFindBucket(i, j, distance); dpnew = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &setN, &setZ, why, 0, DRC_FORWARD | DRC_OUTSIDE, plane, plane); dp->drcc_next = dpnew; dp = drcFindBucket(j, i, distance); dpnew = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &setN, &setZ, why, 0, DRC_REVERSE | DRC_OUTSIDE, plane, plane); dp->drcc_next = dpnew; } } } else /* Multi-plane extend rule */ { if (TTMaskHasType(&set2, i) && TTMaskHasType(&setC, j)) { plane = LowestMaskBit(pset); plane2 = LowestMaskBit(pMask1); /* find bucket preceding the new one we wish to insert */ dp = drcFindBucket(i, j, distance); dpnew = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &set1, &setZ, why, 0, DRC_FORWARD, plane2, plane); dptrig = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); drcAssign(dptrig, 1, dpnew, &setN, &setZ, why, 0, DRC_FORWARD | DRC_TRIGGER, plane2, plane); dp->drcc_next = dptrig; dp = drcFindBucket(j, i, distance); dpnew = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &set1, &setZ, why, 0, DRC_REVERSE, plane2, plane); dptrig = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); drcAssign(dptrig, 1, dpnew, &setN, &setZ, why, 0, DRC_REVERSE | DRC_TRIGGER, plane2, plane); dp->drcc_next = dptrig; } } } } } return (distance); } /* * ---------------------------------------------------------------------------- * * drcWidth -- * * Process a width rule. * This is of the form: * * width layers distance why * * e.g, * * width poly,pmc 2 "poly width must be at least 2" * * Optional "from layers2" is useful when defining a device width; * effectively, it represents an overhang rule where the presence of * the overhanging material is optional. The equivalent rule is: * * edge4way layers2 layers distance layers 0 0 why * * * Results: * Returns distance. * * Side effects: * Updates the DRC technology variables. * * ---------------------------------------------------------------------------- */ int drcWidth(argc, argv) int argc; char *argv[]; { char *layers = argv[1]; int distance = atoi(argv[2]); char *why = drcWhyDup(argv[3]); TileTypeBitMask set, setC; PlaneMask pmask, pset, ptest; DRCCookie *dp, *dpnew; TileType i, j; int plane; ptest = DBTechNoisyNameMask(layers, &set); pmask = CoincidentPlanes(&set, ptest); TTMaskCom2(&setC, &set); if (pmask == 0) { TechError("All layers for \"width\" must be on same plane\n"); return (0); } for (i = 0; i < DBNumTypes; i++) { for (j = 0; j < DBNumTypes; j++) { if (i == j) continue; /* * Must have types in 'set' for at least 'distance' * to the right of any edge between a type in '~set' * and a type in 'set'. */ if (pset = (DBTypesOnSamePlane(i, j) & pmask)) { if (TTMaskHasType(&setC, i) && TTMaskHasType(&set, j)) { plane = LowestMaskBit(pset); /* Find bucket preceding the new one we wish to insert */ dp = drcFindBucket(i, j, distance); dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &set, &set, why, distance, DRC_FORWARD, plane, plane); dp->drcc_next = dpnew; } } } } return (distance); } /* * ---------------------------------------------------------------------------- * * drcArea -- * * Process an area rule. * This is of the form: * * area layers area horizon why * * e.g, * * area pmc 4 2 "poly contact area must be at least 4" * * "area" is the total area in lambda^2. * * "horizon" is the halo distance for the check. Normally, this would * be the area (in lambda^2) divided by the minimum width rule (in * lambda). Anything larger would not be a violation as long as the * minimum width rule is satisfied. * * Results: * Returns distance. * * Side effects: * Updates the DRC technology variables. * * ---------------------------------------------------------------------------- */ int drcArea(argc, argv) int argc; char *argv[]; { char *layers = argv[1]; int distance = atoi(argv[2]); int horizon = atoi(argv[3]); char *why = drcWhyDup(argv[4]); TileTypeBitMask set, setC; DRCCookie *dp, *dpnew; TileType i, j; PlaneMask pmask, ptest, pset; int plane; ptest = DBTechNoisyNameMask(layers, &set); pmask = CoincidentPlanes(&set, ptest); TTMaskCom2(&setC, &set); if (pmask == 0) { TechError("All layers for \"area\" must be on same plane\n"); return (0); } for (i = 0; i < DBNumTypes; i++) { for (j = 0; j < DBNumTypes; j++) { if (i == j) continue; /* * Must have types in 'set' for at least 'distance' * to the right of any edge between a type in '~set' * and a type in 'set'. */ if (pset = (DBTypesOnSamePlane(i, j) & pmask)) { if (TTMaskHasType(&setC, i) && TTMaskHasType(&set, j)) { plane = LowestMaskBit(pset); /* find bucket preceding the new one we wish to insert */ dp = drcFindBucket(i, j, horizon); dpnew = (DRCCookie *) mallocMagic(sizeof (DRCCookie)); drcAssign(dpnew, horizon, dp->drcc_next, &set, &set, why, distance, DRC_AREA|DRC_FORWARD, plane, plane); dp->drcc_next = dpnew; } } } } return (horizon); } /* * ---------------------------------------------------------------------------- * * drcMaxwidth -- * * Process a maxwidth rule. * This is of the form: * * maxwidth layers distance [bends] why * * This routine was updated 3/6/05 to match the "canonical" definition of * a maxwidth region, which is any rectangle containing that is * at least in both width and height. If the keyword * "bend_illegal" is present, then the definition reverts to the original * (see below) for backwards-compatibility. Otherwise ("bend_ok" or * nothing), the new routine is used. * * maxwidth metal1 389 "metal1 width > 35um must be slotted" * maxwidth pmc 4 bend_illegal "poly contact area must be no wider than 4" * maxwidth trench 4 bend_ok "trench width must be exactly 4" * * bend_illegal - means that one_dimension must be distance for any * point in the region. This is used for emitters and contacts * that are rectangular (so we can't generate them with the * squares command) and some exact width in one direction. * bend_ok - Used mainly for wide metal rules where metal greater than * some given width must be slotted. Also, used for things * like trench, where the width is some fixed value: * * XXXXX XXXXXX * X X XXXXXX * X X X X * XXXXX XXXXXX * * OK BAD * * Results: * Returns distance. * * Side effects: * Updates the DRC technology variables. * * ---------------------------------------------------------------------------- */ int drcMaxwidth(argc, argv) int argc; char *argv[]; { char *layers = argv[1]; int distance = atoi(argv[2]); char *bends = argv[3]; char *why; TileTypeBitMask set, setC; DRCCookie *dp, *dpnew; TileType i, j; PlaneMask pmask, ptest, pset; int plane; int bend; ptest = DBTechNoisyNameMask(layers, &set); pmask = CoincidentPlanes(&set, ptest); TTMaskCom2(&setC, &set); if (pmask == 0) { TechError("All layers for \"maxwidth\" must be on same plane\n"); return (0); } if (argc == 4) { /* "bends" is irrelevent if distance is zero, so choose the */ /* faster algorithm to process */ if (distance == 0) bend = 0; else bend = DRC_BENDS; why = drcWhyDup(argv[3]); } else { if (strcmp(bends,"bend_illegal") == 0) bend = 0; else if (strcmp(bends,"bend_ok") == 0) bend = DRC_BENDS; else { TechError("unknown bend option %s\n",bends); return (0); } why = drcWhyDup(argv[4]); } for (i = 0; i < DBNumTypes; i++) { for (j = 0; j < DBNumTypes; j++) { if (i == j) continue; /* * Must have types in 'set' for at least 'distance' * to the right of any edge between a type in '~set' * and a type in 'set'. */ if (pset = (DBTypesOnSamePlane(i, j) & pmask)) { if (TTMaskHasType(&setC, i) && TTMaskHasType(&set, j)) { plane = LowestMaskBit(pset); /* find bucket preceding the new one we wish to insert */ dp = drcFindBucket(i, j, distance); dpnew = (DRCCookie *) mallocMagic(sizeof (DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &set, &set, why, distance, DRC_MAXWIDTH | bend, plane, plane); dp->drcc_next = dpnew; } } } } return (distance); } /* * ---------------------------------------------------------------------------- * drcAngles -- * * Process an "angles" rule specifying that geometry for a certain layer * must be limited to 90 degrees or 45 degrees. If not specified, any * angle is allowed, although width rules will flag errors on acute angles. * * ---------------------------------------------------------------------------- */ int drcAngles(argc, argv) int argc; char *argv[]; { char *layers = argv[1]; int angles = atoi(argv[2]); char *why = drcWhyDup(argv[3]); TileTypeBitMask set; DRCCookie *dp, *dpnew; int plane; TileType i, j; DBTechNoisyNameMask(layers, &set); angles /= 45; angles--; /* angles now 0 for 45s and 1 for 90s */ if ((angles != 0) && (angles != 1)) { TechError("angles must be 45 or 90\n"); return 0; } for (i = 0; i < DBNumTypes; i++) { if (TTMaskHasType(&set, i)) { plane = DBPlane(i); /* Insert rule at boundary of tile and TT_SPACE. This is */ /* processed for each tile, separately from other rules, so */ /* we don't really care what the edge is; TT_SPACE is */ /* chosen as an arbitrary place to hold the rule. */ dp = drcFindBucket(TT_SPACE, i, 1); dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dpnew, 1, dp->drcc_next, &set, &set, why, 1, DRC_ANGLES | angles, plane, plane); dp->drcc_next = dpnew; } } return 1; } /* * ---------------------------------------------------------------------------- * * drcSpacing3 -- * * Process a special spacing rule of the form: * * spacing layers1 layers2 distance corner_ok layers3 why * * This spacing rule is not checked when a type from "layers3" fills the * corner between "layers1" and "layers2". This is used, e.g., for * diffusion-to-poly spacing, where diffusion and poly may touch at the * corner of a FET type. It is equivalent to: * * edge4way layers1 ~(layers3,layers1) distance ~(layers2) 0 0 why * * ---------------------------------------------------------------------------- */ int drcSpacing3(argc, argv) int argc; char *argv[]; { char *layers1 = argv[1], *layers2 = argv[2]; char *layers3 = argv[5]; int distance = atoi(argv[3]); char *adjacency = argv[4]; char *why = drcWhyDup(argv[6]); TileTypeBitMask set1, set2, set3; int plane; DRCCookie *dp, *dpnew; TileType i, j; PlaneMask pmask, pset, ptest; ptest = DBTechNoisyNameMask(layers1, &set1); pmask = CoincidentPlanes(&set1, ptest); ptest = DBTechNoisyNameMask(layers2, &set2); pmask &= CoincidentPlanes(&set2, ptest); ptest = DBTechNoisyNameMask(layers3, &set3); pmask &= CoincidentPlanes(&set3, ptest); if (pmask == 0) { TechError("Spacing check with \"corner_ok\" must have" " all types in one plane.\n"); return (0); } /* In this usage everything must fall in the same plane. */ /* We need masks for (~types2)/plane and for (~(types1,types3))/plane */ TTMaskCom(&set2); TTMaskSetMask(&set3, &set1); TTMaskCom(&set3); for (i = 0; i < DBNumTypes; i++) { for (j = 0; j < DBNumTypes; j++) { if (i == j) continue; if (pset = (DBTypesOnSamePlane(i, j) & pmask)) { if (TTMaskHasType(&set1, i) && TTMaskHasType(&set3, j)) { plane = LowestMaskBit(pset); /* Find bucket preceding the new one we wish to insert */ dp = drcFindBucket(i, j, distance); dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &set2, &set3, why, distance, DRC_FORWARD | DRC_BOTHCORNERS, plane, plane); dp->drcc_next = dpnew; /* find bucket preceding new one we wish to insert */ dp = drcFindBucket(j, i, distance); dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &set2, &set3, why, distance, DRC_REVERSE | DRC_BOTHCORNERS, plane, plane); dp->drcc_next = dpnew; } } } } return distance; } /* *------------------------------------------------------------------- * * drcMaskSpacing --- * * This is the core of the drcSpacing routine. When the spacing * rule layers independently cover more than one plane, this routine * is invoked for each independent plane. * * Results: * Returns the rule's maximum distance * * Side effects: * Adds rules to the DRC rule table. * *------------------------------------------------------------------- */ int drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency, why, widerule, multiplane) TileTypeBitMask *set1, *set2; PlaneMask pmask1, pmask2; int wwidth, distance; char *adjacency, *why; bool widerule, multiplane; { TileTypeBitMask tmp1, tmp2, setR, setRreverse; int plane, plane2; PlaneMask pset, ptest; DRCCookie *dp, *dpnew; int needReverse = (widerule) ? TRUE : FALSE; TileType i, j, pref; bool needtrigger = FALSE; bool touchingok = TRUE; bool cornerok = FALSE; if (!strcmp(adjacency, "surround_ok")) { if (multiplane) { TechError("\"surround_ok\" requires surrounding types to " "be in the same plane.\n"); return (0); } else if ((pmask1 & pmask2) == 0) { /* New rule implementation (7/8/06): When types */ /* are on different planes and "surround_ok" is */ /* declared, implement as a triggered rule (but not */ /* for widespacing, which already uses the */ /* triggering rule mechanism). */ if (!widerule) { needtrigger = TRUE; touchingok = FALSE; } else { TechError("Widespacing checks cannot use \"surround_ok\".\n"); return (0); } } else { TechError("\"surround_ok\" used when spacing rule types are in " "the same plane. Did you mean \"touching_ok\"?\n"); touchingok = TRUE; /* Treat like "touching_ok" */ } } else if (!strcmp(adjacency, "touching_ok")) { /* If touching is OK, everything must fall in the same plane. */ if (multiplane || ((pmask1 & pmask2) == 0)) { TechError("Spacing check with \"touching_ok\" must have" " all types in one plane. Possibly you want" " \"surround_ok\"?\n"); return (0); } else touchingok = TRUE; } else if (!strcmp(adjacency, "touching_illegal")) { touchingok = FALSE; needtrigger = FALSE; } else { TechError("Badly formed drc spacing line: need \"touching_ok\", " "\"touching_illegal\", or \"surround_ok\".\n"); return (0); } if (touchingok) { /* In "touching_ok rules, spacing to set2 is be checked in FORWARD * direction at edges between set1 and (setR = ~set1 AND ~set2). * * In addition, spacing to set1 is checked in FORWARD direction * at edges between set2 and (setRreverse = ~set1 AND ~set2). * * If set1 and set2 are different, above are checked in REVERSE as * well as forward direction. This is important since touching * material frequently masks violations in one direction. * * setR and setRreverse are set appropriately below. */ tmp1 = *set1; tmp2 = *set2; /* Restrict planes to those that are coincident */ pmask1 &= pmask2; pmask2 = pmask1; TTMaskCom(&tmp1); TTMaskCom(&tmp2); TTMaskAndMask(&tmp1, &tmp2); setR = tmp1; setRreverse = tmp1; /* If set1 != set2, set flag to check rules in both directions */ if (!TTMaskEqual(set1, set2)) needReverse = TRUE; } else { /* In "touching_illegal" rules, spacing to set2 will be checked * in FORWARD direction at edges between set1 and (setR=~set1). * * In addition, spacing to set1 will be checked in FORWARD direction * at edges between set2 and (setRreverse= ~set2). * * setR and setRreverse are set appropriately below. */ TTMaskCom2(&setR, set1); TTMaskCom2(&setRreverse, set2); } for (i = 0; i < DBNumTypes; i++) { for (j = 0; j < DBNumTypes; j++) { if (i == j) continue; if (pset = (DBTypesOnSamePlane(i, j) & pmask1)) { plane = LowestMaskBit(pset); /* LHS is an element of set1, RHS is an element of setR */ if (TTMaskHasType(set1, i) && TTMaskHasType(&setR, j)) { plane2 = LowestMaskBit(pmask2); /* * Must not have 'set2' for 'distance' to the right of * an edge between 'set1' and the types not in 'set1' * (touching_illegal case) or in neither * 'set1' nor 'set2' (touching_ok case). */ /* Find bucket preceding the new one we wish to insert */ dp = drcFindBucket(i, j, distance); dpnew = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); TTMaskClearMask3(&tmp1, &DBPlaneTypes[plane2], set2); TTMaskAndMask3(&tmp2, &DBPlaneTypes[plane], &setR); if (widerule) { DRCCookie *dptrig; /* Create two contiguous rules, one for spacing */ /* and one for width. These are created in */ /* reverse order due to the stack property of */ /* the linked list. */ drcAssign(dpnew, distance, dp->drcc_next, &tmp1, &tmp2, why, distance, DRC_FORWARD, plane2, plane); dptrig = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dptrig, wwidth, dpnew, set1, set1, why, wwidth, DRC_REVERSE | DRC_MAXWIDTH | DRC_TRIGGER | DRC_BENDS, plane2, plane); dp->drcc_next = dptrig; } else if (needtrigger) { DRCCookie *dptrig; /* Create two contiguous spacing rules */ drcAssign(dpnew, distance, dp->drcc_next, &tmp1, &tmp2, why, wwidth, DRC_FORWARD | DRC_BOTHCORNERS, plane2, plane); dptrig = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dptrig, 1, dpnew, set2, &tmp2, why, 1, DRC_FORWARD | DRC_TRIGGER, plane2, plane); dp->drcc_next = dptrig; } else { drcAssign(dpnew, distance, dp->drcc_next, &tmp1, &tmp2, why, wwidth, DRC_FORWARD, plane2, plane); dp->drcc_next = dpnew; } if (needReverse) dpnew->drcc_flags |= DRC_BOTHCORNERS; if (needReverse) { /* Add check in reverse direction, * NOTE: am assuming single plane rule here (since reverse * rules only used with touching_ok which must be * single plane) */ /* find bucket preceding new one we wish to insert */ dp = drcFindBucket(j, i, distance); dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie)); if (widerule) { DRCCookie *dptrig; /* Assign two coupled rules (see above) */ drcAssign(dpnew, distance, dp->drcc_next, &tmp1, &tmp2, why, distance, DRC_REVERSE | DRC_BOTHCORNERS, plane2, plane); dptrig = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dptrig, wwidth, dpnew, set1, set1, why, wwidth, DRC_FORWARD | DRC_MAXWIDTH | DRC_TRIGGER | DRC_BENDS, plane2, plane); dp->drcc_next = dptrig; } else if (needtrigger) { DRCCookie *dptrig; /* Create two contiguous spacing rules */ drcAssign(dpnew, distance, dp->drcc_next, &tmp1, &tmp2, why, wwidth, DRC_REVERSE | DRC_BOTHCORNERS, plane2, plane); dptrig = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dptrig, 1, dpnew, set2, &tmp2, why, 1, DRC_REVERSE | DRC_TRIGGER, plane2, plane); dp->drcc_next = dptrig; } else { drcAssign(dpnew,distance,dp->drcc_next, &tmp1, &tmp2, why, wwidth, DRC_REVERSE | DRC_BOTHCORNERS, plane2, plane); dp->drcc_next = dpnew; } } } } if (TTMaskEqual(set1, set2)) continue; if (widerule) continue; /* Can't determine width of set1 */ /* when looking at the edge of set2 */ /* * Now, if set1 and set2 are distinct apply the rule for LHS in set1 * and RHS in set2. */ if (pset = (DBTypesOnSamePlane(i, j) & pmask2)) { plane = LowestMaskBit(pset); /* LHS is an element of set2, RHS is an element of setRreverse */ if (TTMaskHasType(set2, i) && TTMaskHasType(&setRreverse, j)) { plane2 = LowestMaskBit(pmask1); /* Find bucket preceding the new one we wish to insert */ dp = drcFindBucket(i, j, distance); dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie)); TTMaskClearMask3(&tmp1, &DBPlaneTypes[plane2], set1); TTMaskAndMask3(&tmp2, &DBPlaneTypes[plane], &setRreverse); if (needtrigger) { DRCCookie *dptrig; /* Create two contiguous spacing rules */ drcAssign(dpnew, distance, dp->drcc_next, &tmp1, &tmp2, why, distance, DRC_FORWARD | DRC_BOTHCORNERS, plane2, plane); dptrig = (DRCCookie *)mallocMagic(sizeof (DRCCookie)); drcAssign(dptrig, 1, dpnew, set1, &tmp2, why, 1, DRC_FORWARD | DRC_TRIGGER, plane2, plane); dp->drcc_next = dptrig; } else { drcAssign(dpnew, distance, dp->drcc_next, &tmp1, &tmp2, why, distance, DRC_FORWARD, plane2, plane); dp->drcc_next = dpnew; } if (needReverse) dpnew->drcc_flags |= DRC_BOTHCORNERS; if (needReverse) { /* Add check in reverse direction, * NOTE: am assuming single plane rule here (since reverse * rules only used with touching_ok which must be * single plane) */ /* find bucket preceding new one we wish to insert */ dp = drcFindBucket(j, i, distance); dpnew = (DRCCookie *) mallocMagic(sizeof (DRCCookie)); if (needtrigger) { DRCCookie *dptrig; /* Create two contiguous spacing rules */ drcAssign(dpnew, distance, dp->drcc_next, &tmp1, &tmp2, why, distance, DRC_REVERSE | DRC_BOTHCORNERS, plane2, plane); dptrig = (DRCCookie *)mallocMagic(sizeof (DRCCookie)); drcAssign(dptrig, 1, dpnew, set1, &tmp2, why, 1, DRC_REVERSE | DRC_TRIGGER, plane2, plane); dp->drcc_next = dptrig; } else { drcAssign(dpnew, distance, dp->drcc_next, &tmp1, &tmp2, why, distance, DRC_REVERSE | DRC_BOTHCORNERS, plane2, plane); dp->drcc_next = dpnew; } } } } /* Finally, if multiplane rule then check that set2 types * are not present just to right of edges with setR on LHS * and set1 on RHS. This check is necessary to make sure * that a set1 rectangle doesn't coincide exactly with a * set2 rectangle. * (This check added by Michael Arnold on 4/10/86.) */ if (needtrigger) continue; if (pset = (DBTypesOnSamePlane(i, j) & pmask1)) { plane = LowestMaskBit(pset); /* LHS is an element of setR, RHS is an element of set1 */ if (TTMaskHasType(&setR, i) && TTMaskHasType(set1, j)) { /* * Must not have 'set2' for 'distance' to the right of * an edge between the types not in set1 and set1. * (is only checked for cross plane rules - these are * all of type touching_illegal) */ /* Walk list to last check. New checks ("cookies") go * at end of list since we are checking for distance of * 1 and the list is sorted in order of decreasing distance. */ for (dp = DRCCurStyle->DRCRulesTbl [i][j]; dp->drcc_next != (DRCCookie *) NULL; dp = dp->drcc_next); /* null body */ /* Insert one check for each plane involved in set2 */ plane2 = LowestMaskBit(pmask2); /* filter out checks that are not cross plane */ if (i == TT_SPACE) { if (DBTypeOnPlane(j, plane2)) continue; } else { if (DBTypeOnPlane(i, plane2)) continue; } /* create new check and add it to list */ dpnew = (DRCCookie *) mallocMagic(sizeof (DRCCookie)); TTMaskClearMask3(&tmp1, &DBPlaneTypes[plane2], set2); TTMaskZero(&tmp2); drcAssign(dpnew, 1, dp->drcc_next, &tmp1, &tmp2, why, distance, DRC_FORWARD, plane2, plane); dp->drcc_next = dpnew; } } } } return (MAX(wwidth, distance)); } /* * ---------------------------------------------------------------------------- * * drcSpacing -- * * Process a spacing rule. * This is of the form: * * spacing layers1 layers2 distance adjacency why * * e.g, * * spacing metal,pmc/m,dmc/m metal,pmc/m,dmc/m 4 touching_ok \ * "metal spacing must be at least 4" * * Adjacency may be either "touching_ok" or "touching_illegal" * In the first case, no violation occurs when types in layers1 are * immediately adjacent to types in layers2. In the second case, * such adjacency causes a violation. * * Results: * Returns distance. * * Side effects: * Updates the DRC technology variables. * * Notes: * Extended to include the rule syntax: * * widespacing layers1 width layers2 distance adjacency why * * This extension covers rules such as "If m1 width > 10um, then spacing to * unconnected m1 must be at least 0.6um". This assumes that the instantiated * edge4way rule is a standard "spacing" rule in which "dist" and "cdist" * (corner extension) distances are always the same, so we can use the "cdist" * record to encode the width of "layers1" which triggers the rule. We re-use * the CheckMaxwidth() code, but with the following differences: 1) it does not * trigger any error painting functions, 2) it returns a value stating whether * the maxwidth rule applies or not, 3) it uses the DBLayerTypeMaskTbl[] for * the tile type in question, not "oktypes", for its search, and 4) it uses * the max width in the "cdist" record, not the "dist" record, for the max * width rule. The "dist" record is copied to "cdist" before actually applying * the spacing rule, so that the rule acts like a proper spacing rule. * * Added adjacency rule "surround_ok" to check spacing to a type that * may also abut or surround the first layer---the portion of the layer * that is abutting or surrounding is not checked. This allows checks * of, e.g., diffusion in well to a separate well edge, or distance from * a poly bottom plate to unconnected poly. * * (Added 11/6/06) Adjacency may be "corner_ok", in which case it calls * routing drcSpacing3() (see above). * * ---------------------------------------------------------------------------- */ int drcSpacing(argc, argv) int argc; char *argv[]; { char *layers1 = argv[1], *layers2; char *adjacency; char *why; TileTypeBitMask set1, set2, tmp1, tmp2; PlaneMask pmask1, pmask2, pmaskA, pmaskB, ptest; int wwidth, distance, plane, plane2; bool widerule, multiplane = FALSE; if ((argc == 7) && (!strcmp(argv[4], "corner_ok"))) return drcSpacing3(argc, argv); widerule = (strncmp(argv[0], "wide", 4) == 0); if (widerule) { wwidth = atoi(argv[2]); layers2 = argv[3]; distance = atoi(argv[4]); adjacency = argv[5]; why = drcWhyDup(argv[6]); /* TxPrintf("Info: DRCtech: widespacing rule for %s width %d:" " spacing must be %d\n", layers1, wwidth, distance); */ } else { layers2 = argv[2]; distance = atoi(argv[3]); adjacency = argv[4]; wwidth = distance; why = drcWhyDup(argv[5]); if (argc == 7) { TechError("Unknown argument in spacing line.\n"); return(0); } } /* Either list of types may contain independent types on different */ /* planes. However, if so, then we may not use touching_ok, and */ /* there are other restrictions. */ ptest = DBTechNoisyNameMask(layers1, &set1); pmask1 = CoincidentPlanes(&set1, ptest); if ((pmask1 == 0) && (ptest != 0)) { pmask1 = ptest; multiplane = TRUE; for (plane = 0; plane < DBNumPlanes; plane++) for (plane2 = 0; plane2 < DBNumPlanes; plane2++) { if (plane == plane2) continue; if (PlaneMaskHasPlane(pmask1, plane) && PlaneMaskHasPlane(pmask1, plane2)) { TTMaskAndMask3(&tmp1, &DBPlaneTypes[plane], &DBPlaneTypes[plane2]); TTMaskAndMask(&tmp1, &set1); if (!TTMaskIsZero(&tmp1)) { TechError("Types in first list must either be in" " one plane or else types must not share" " planes.\n"); return (0); } } } } ptest = DBTechNoisyNameMask(layers2, &set2); pmask2 = CoincidentPlanes(&set2, ptest); if ((pmask2 == 0) && (ptest != 0)) { pmask2 = ptest; multiplane = TRUE; for (plane = 0; plane < DBNumPlanes; plane++) for (plane2 = 0; plane2 < DBNumPlanes; plane2++) { if (plane == plane2) continue; if (PlaneMaskHasPlane(pmask2, plane) && PlaneMaskHasPlane(pmask2, plane2)) { TTMaskAndMask3(&tmp1, &DBPlaneTypes[plane], &DBPlaneTypes[plane2]); TTMaskAndMask(&tmp1, &set2); if (!TTMaskIsZero(&tmp1)) { TechError("Types in second list must either be in" " one plane or else types must not share" " planes.\n"); return (0); } } } } if (multiplane) { /* Loop over independent plane/layer combinations */ for (plane = 0; plane < DBNumPlanes; plane++) for (plane2 = 0; plane2 < DBNumPlanes; plane2++) { if (PlaneMaskHasPlane(pmask1, plane) && PlaneMaskHasPlane(pmask2, plane2)) { pmaskA = PlaneNumToMaskBit(plane); pmaskB = PlaneNumToMaskBit(plane2); TTMaskAndMask3(&tmp1, &set1, &DBPlaneTypes[plane]); TTMaskAndMask3(&tmp2, &set2, &DBPlaneTypes[plane2]); return drcMaskSpacing(&tmp1, &tmp2, pmaskA, pmaskB, wwidth, distance, adjacency, why, widerule, multiplane); } } } else return drcMaskSpacing(&set1, &set2, pmask1, pmask2, wwidth, distance, adjacency, why, widerule, multiplane); return 0; } /* * ---------------------------------------------------------------------------- * * drcEdge -- * * Process a primitive edge rule. * This is of the form: * * edge layers1 layers2 dist OKtypes cornerTypes cornerDist why [plane] * or edge4way layers1 layers2 dist OKtypes cornerTypes cornerDist why [plane] * * e.g, * * edge poly,pmc s 1 diff poly,pmc "poly-diff separation must be 2" * * An "edge" rule is applied only down and to the left. * An "edge4way" rule is applied in all four directions. * * Results: * Returns greater of dist and cdist. * * Side effects: * Updates the DRC technology variables. * * ---------------------------------------------------------------------------- */ int drcEdge(argc, argv) int argc; char *argv[]; { char *layers1 = argv[1], *layers2 = argv[2]; int distance = atoi(argv[3]); char *okTypes = argv[4], *cornerTypes = argv[5]; int cdist = atoi(argv[6]); char *why = drcWhyDup(argv[7]); bool fourway = (strcmp(argv[0], "edge4way") == 0); TileTypeBitMask set1, set2, setC, setM; DRCCookie *dp, *dpnew; int plane, checkPlane, tmpPlane; PlaneMask pMask1, pMaskM, pMaskC, pset, ptest; TileType i, j; /* * Edge4way rules produce [j][i] entries as well as [i][j] * ones, and check both corners rather than just one corner. */ ptest = DBTechNoisyNameMask(layers1, &set1); pMask1 = CoincidentPlanes(&set1, ptest); ptest = DBTechNoisyNameMask(layers2, &set2); pMask1 &= CoincidentPlanes(&set2, ptest); if (pMask1 == 0) { TechError("All edges in edge rule must lie in shared planes.\n"); return (0); } /* Give warning if types1 and types2 intersect */ if (TTMaskIntersect(&set1, &set2)) TechError("Warning: types1 and types2 have nonempty intersection. " "DRC does not check edges with the same type on both " "sides.\n"); ptest = DBTechNoisyNameMask(cornerTypes, &setC); pMaskC = CoincidentPlanes(&setC, ptest); if ((pMaskC & pMask1) == 0) { TechError("Corner types aren't in same plane as edges.\n"); return (0); } if (argc == 9) tmpPlane = DBTechNoisyNamePlane(argv[8]); /* * OKtypes determine the checkPlane. If checkPlane exists, it should * only be used to check against the plane of OKtypes. */ ptest = DBTechNoisyNameMask(okTypes, &setM); pMaskM = CoincidentPlanes(&setM, ptest); if (pMaskM == 0 || pMaskM == DBTypePlaneMaskTbl[TT_SPACE]) { /* Technically it should be illegal to specify simply "space" * in the types list for a DRC rule, as it is ambiguous. * However, we will assume that the plane of the edge is * intended. The "plane" argument may be used to do the * qualification (for backwards compatibility); any other use * gets a warning. */ if (TTMaskEqual(&DBSpaceBits, &setM)) { if (argc == 9) pMaskM = PlaneNumToMaskBit(tmpPlane); else { TechError("OK types \"%s\" in more than one plane.\n" " Assuming same plane (%s) as edge.\n", okTypes, DBPlaneLongNameTbl[LowestMaskBit(pMask1)]); pMaskM = pMask1; } } /* The case okTypes="0" is explicitly allowed according */ /* to the manual, so we parse it accordingly. */ else if (!strcmp(okTypes, "0")) pMaskM = pMask1; else { TechError("All OK types must lie in one plane.\n"); return (0); } } /* "plane" argument deprecated; kept for backward compatibility only */ if ((argc == 9) && (PlaneNumToMaskBit(tmpPlane) != pMaskM)) TechError("Ignoring bad plane argument.\n"); for (i = 0; i < DBNumTypes; i++) { for (j = 0; j < DBNumTypes; j++) { if (i == j) continue; if (pset = (DBTypesOnSamePlane(i, j) & pMask1)) { if (TTMaskHasType(&set1, i) && TTMaskHasType(&set2, j)) { /* For fastest DRC, checkPlane and plane should be */ /* the same, if possible. */ if (pset & pMaskM != 0) { plane = LowestMaskBit(pset & pMaskM); checkPlane = plane; } else { plane = LowestMaskBit(pset); checkPlane = LowestMaskBit(pMaskM); } /* Find bucket preceding the new one we wish to insert */ dp = drcFindBucket(i, j, distance); dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &setM, &setC, why, cdist, DRC_FORWARD, checkPlane, plane); if (fourway) dpnew->drcc_flags |= DRC_BOTHCORNERS; dp->drcc_next = dpnew; if (!fourway) continue; /* find bucket preceding new one we wish to insert */ dp = drcFindBucket(j, i, distance); dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie)); drcAssign(dpnew,distance,dp->drcc_next, &setM, &setC, why, cdist, DRC_REVERSE, checkPlane, plane); dpnew->drcc_flags |= DRC_BOTHCORNERS; dp->drcc_next = dpnew; } } } } return (MAX(distance, cdist)); } /* * ---------------------------------------------------------------------------- * * drcOverhang -- * * Process an overhang rule. * This is of the form: * * overhang layers2 layers1 dist why * * indicating that layers2 must overhang layers1 by a distance of at least * dist. * * This rule is equivalent to: * * edge4way layers1 space/p2|layers2 dist layers1|layers2 \ * space/p2|layers2 dist why * * ---------------------------------------------------------------------------- */ int drcOverhang(argc, argv) int argc; char *argv[]; { char *layers2 = argv[1], *layers1 = argv[2]; int distance = atoi(argv[3]); char *why = drcWhyDup(argv[4]); TileTypeBitMask set1, set2, setM, setC, setN, set2inv; DRCCookie *dp, *dpnew, *dptrig; int plane, plane2; TileType i, j; PlaneMask pMask1, pMask2, pset, ptest; ptest = DBTechNoisyNameMask(layers1, &set1); pMask1 = CoincidentPlanes(&set1, ptest); if (pMask1 == 0) { TechError("All layers in first set for \"overhang\" must be on " "the same plane\n"); return (0); } TTMaskCom2(&setN, &set1); ptest = DBTechNoisyNameMask(layers2, &set2); pMask2 = CoincidentPlanes(&set2, ptest); if (pMask2 == 0) { TechError("All layers in second set for \"overhang\" must be on " "the same plane\n"); return (0); } TTMaskCom2(&set2inv, &set2); /* Warn if types1 and types2 intersect */ if (TTMaskIntersect(&set1, &set2)) TechError("Warning: inside and outside types have nonempty intersection. " "DRC does not check edges with the same type on both sides.\n"); /* SetM is the union of set1 and set2 */ TTMaskZero(&setM); TTMaskSetMask3(&setM, &set1, &set2); /* Add space to set2 */ TTMaskSetType(&set2, TT_SPACE); /* SetC is the empty set */ TTMaskZero(&setC); for (i = 0; i < DBNumTypes; i++) { for (j = 0; j < DBNumTypes; j++) { if (i == j) continue; if (pset = (DBTypesOnSamePlane(i, j) & pMask2)) { if ((pset & pMask1) != 0) { if (TTMaskHasType(&set1, i) && TTMaskHasType(&set2, j)) { plane = LowestMaskBit(pset); /* Find bucket preceding the new one we wish to insert */ dp = drcFindBucket(i, j, distance); dpnew = (DRCCookie *)mallocMagic (sizeof (DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &setM, &setM, why, distance, DRC_FORWARD | DRC_BOTHCORNERS, plane, plane); dp->drcc_next = dpnew; /* find bucket preceding new one we wish to insert */ dp = drcFindBucket(j, i, distance); dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &setM, &setM, why, distance, DRC_REVERSE | DRC_BOTHCORNERS, plane, plane); dp->drcc_next = dpnew; } } else /* Multi-plane overhang rule */ { if (TTMaskHasType(&set2, i) && TTMaskHasType(&set2inv, j)) { plane = LowestMaskBit(pset); plane2 = LowestMaskBit(pMask1); /* find bucket preceding the new one we wish to insert */ dp = drcFindBucket(i, j, distance); dpnew = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &set1, &set1, why, distance, DRC_FORWARD, plane2, plane); dptrig = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); drcAssign(dptrig, 1, dpnew, &setN, &setC, why, 0, DRC_FORWARD | DRC_TRIGGER, plane2, plane); dp->drcc_next = dptrig; dp = drcFindBucket(j, i, distance); dpnew = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &set1, &set1, why, distance, DRC_REVERSE, plane2, plane); dptrig = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); drcAssign(dptrig, 1, dpnew, &setN, &setC, why, 0, DRC_REVERSE | DRC_TRIGGER, plane2, plane); dp->drcc_next = dptrig; } } } } } return distance; } /* * ---------------------------------------------------------------------------- * * drcRectOnly -- * * Process a rectangle-only rule. This rule prohibits non-rectangular * geometry, and is used especially for contacts, as the "squares" operator * in the CIF/GDS output generator can't handle non-rectangular areas. * The rule is of the form: * * rect_only layers why * * and is equivalent to: * * edge4way layers ~(layers)/plane 1 ~(layers)/plane (all_layers)/plane 1 * * The rect_only rule avoids the above contrived construction, especially the * requirement of specifying "all_layers" as something like (~(x),x)/p, a sure- * fire obfuscation. * * ---------------------------------------------------------------------------- */ int drcRectOnly(argc, argv) int argc; char *argv[]; { char *layers = argv[1]; char *why = drcWhyDup(argv[2]); TileTypeBitMask set1, set2, setC; PlaneMask pmask, pset, ptest; DRCCookie *dp, *dpnew; int plane; TileType i, j; ptest = DBTechNoisyNameMask(layers, &set1); pmask = CoincidentPlanes(&set1, ptest); if (pmask == 0) { TechError("All types for \"rect_only\" must be on the same plane.\n"); return (0); } /* set2 is the inverse of set1 */ TTMaskCom2(&set2, &set1); for (i = 0; i < DBNumTypes; i++) { for (j = 0; j < DBNumTypes; j++) { if (i == j) continue; if (pset = (DBTypesOnSamePlane(i, j) & pmask)) { if (TTMaskHasType(&set1, i) && TTMaskHasType(&set2, j)) { plane = LowestMaskBit(pset); /* setC = all types in plane */ TTMaskZero(&setC); TTMaskSetMask(&setC, &DBPlaneTypes[plane]); /* Find bucket preceding the new one we wish to insert */ dp = drcFindBucket(i, j, 1); dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie)); drcAssign(dpnew, 1, dp->drcc_next, &set2, &setC, why, 1, DRC_FORWARD | DRC_BOTHCORNERS, plane, plane); dp->drcc_next = dpnew; /* find bucket preceding new one we wish to insert */ dp = drcFindBucket(j, i, 1); dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie)); drcAssign(dpnew,1,dp->drcc_next, &set2, &setC, why, 1, DRC_REVERSE | DRC_BOTHCORNERS, plane, plane); dp->drcc_next = dpnew; } } } } return 1; } /* * ---------------------------------------------------------------------------- * * drcSurround -- * * Process a surround rule. * This is of the form: * * surround layers1 layers2 dist presence why * * indicating that layers2 must surround layers1 by at least distance * dist in all directions. * * This rule is equivalent to: * * edge4way ~(layers2)/plane2 layers2 dist ~(layers1)/plane1 \ * layers2 dist why * * When presence=absence_illegal, the following additional rule is needed: * * edge4way layers1 ~(layers2)/plane1 dist NULL ~(layers2)/plane1 \ * dist why * * Extension added July 12, 2014: For via rules where an asymmetric * surround is allowed, with a smaller surround allowed on two sides if * the remaining two sides have a larger surround. This can be implemented * with a trigger rule, and is specified by the syntax above with "presence" * being "directional". Note that the rule expresses that the overhang rule * requires the presence of the material on one side of a corner. If the * other side has a non-zero minimum surround requirement, then it should * be implemented with an additional (absence_illegal) surround rule. * Otherwise, any width of material less than "dist" on one side of a * corner will trigger the rule requiring at least "dist" width of the same * material on the other side of the corner. * * ---------------------------------------------------------------------------- */ int drcSurround(argc, argv) int argc; char *argv[]; { char *layers1 = argv[1], *layers2 = argv[2]; int distance = atoi(argv[3]); char *presence = argv[4]; char *why = drcWhyDup(argv[5]); TileTypeBitMask set1, set2, setM, invM, setR; DRCCookie *dp, *dpnew, *dptrig; int plane1, plane2; PlaneMask pmask, pmask2, pset, ptest; TileType i, j; bool isExact = FALSE; bool isDirectional = FALSE; ptest = DBTechNoisyNameMask(layers1, &setM); pmask = CoincidentPlanes(&setM, ptest); if (pmask == 0) { TechError("Inside types in \"surround\" must be on the same plane\n"); return (0); } ptest = DBTechNoisyNameMask(layers2, &set2); pmask2 = CoincidentPlanes(&set2, ptest); if (pmask2 == 0) { TechError("Outside types in \"surround\" must be on the same plane\n"); return (0); } /* "exact_width" rule implemented 9/16/10. This enforces an exact */ /* surround distance. "absence_illegal" is implied. */ if (!strncmp(presence, "exact_", 6)) isExact = TRUE; else if (!strncmp(presence, "directional", 11)) { isDirectional = TRUE; /* Combined mask */ TTMaskZero(&setR); TTMaskSetMask(&setR, &setM); TTMaskSetMask(&setR, &set2); } /* invert setM */ TTMaskCom2(&invM, &setM); /* set1 is the inverse of set2 */ TTMaskCom2(&set1, &set2); for (i = 0; i < DBNumTypes; i++) { for (j = 0; j < DBNumTypes; j++) { if (i == j) continue; /* Ignore false edges */ if (pset = (DBTypesOnSamePlane(i, j) & pmask2)) { if (isDirectional) { /* Directional surround is done entirely differently */ if (TTMaskHasType(&setM, i) && TTMaskHasType(&invM, j)) { plane1 = LowestMaskBit(pmask); plane2 = LowestMaskBit(pset); /* Find bucket preceding the new one we wish to insert */ dp = drcFindBucket(i, j, distance); dpnew = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); /* Insert triggered rule */ drcAssign(dpnew, distance, dp->drcc_next, &setR, &DBAllTypeBits, why, distance, DRC_REVERSE | DRC_BOTHCORNERS, plane1, plane2); dptrig = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); drcAssign(dptrig, distance, dpnew, &set2, &DBZeroTypeBits, why, 0, DRC_FORWARD | DRC_TRIGGER, plane1, plane2); dp->drcc_next = dptrig; /* And the other direction. . . */ dp = drcFindBucket(j, i, distance); dpnew = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); /* Insert triggered rule */ drcAssign(dpnew, distance, dp->drcc_next, &setR, &DBAllTypeBits, why, distance, DRC_FORWARD | DRC_BOTHCORNERS, plane1, plane2); dptrig = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); drcAssign(dptrig, distance, dpnew, &set2, &DBZeroTypeBits, why, 0, DRC_REVERSE | DRC_TRIGGER, plane1, plane2); dp->drcc_next = dptrig; } } else { if (TTMaskHasType(&set1, i) && TTMaskHasType(&set2, j)) { plane1 = LowestMaskBit(pmask); plane2 = LowestMaskBit(pset); /* Find bucket preceding the new one we wish to insert */ dp = drcFindBucket(i, j, distance); dpnew = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &invM, &set2, why, distance, DRC_FORWARD | DRC_BOTHCORNERS, plane1, plane2); dp->drcc_next = dpnew; /* find bucket preceding new one we wish to insert */ dp = drcFindBucket(j, i, distance); dpnew = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &invM, &set2, why, distance, DRC_REVERSE | DRC_BOTHCORNERS, plane1, plane2); dp->drcc_next = dpnew; } } } } } if (isExact) { for (i = 0; i < DBNumTypes; i++) { for (j = 0; j < DBNumTypes; j++) { if (i == j) continue; /* Ignore false edges */ if (pset = (DBTypesOnSamePlane(i, j) & pmask)) { if (TTMaskHasType(&setM, i) && TTMaskHasType(&set2, j)) { plane1 = LowestMaskBit(pset); /* Find bucket preceding the new one we wish to insert */ dp = drcFindBucket(i, j, distance); dpnew = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &set1, &set2, why, distance, DRC_FORWARD | DRC_BOTHCORNERS | DRC_OUTSIDE, plane1, plane1); dp->drcc_next = dpnew; /* find bucket preceding new one we wish to insert */ dp = drcFindBucket(j, i, distance); dpnew = (DRCCookie *)mallocMagic(sizeof(DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &set1, &set2, why, distance, DRC_REVERSE | DRC_BOTHCORNERS | DRC_OUTSIDE, plane1, plane1); dp->drcc_next = dpnew; } } } } } if ((!isExact) && strcmp(presence, "absence_illegal")) return distance; /* Add an extra rule when presence of the surrounding */ /* layer is required. Rule is different if planes match. */ if (pset = pmask & pmask2) { TTMaskZero(&invM); TTMaskSetMask(&invM, &setM); TTMaskSetMask(&invM, &set2); TTMaskCom(&invM); TTMaskZero(&set1); for (i = 0; i < DBNumTypes; i++) for (j = 0; j < DBNumTypes; j++) { if (i == j) continue; if (pset = (DBTypesOnSamePlane(i, j) & pmask & pmask2)) { plane1 = LowestMaskBit(pset); if (TTMaskHasType(&setM, i) && TTMaskHasType(&invM, j)) { /* Find bucket preceding the new one we wish to insert */ dp = drcFindBucket(i, j, distance); dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dpnew, distance, dp->drcc_next, &set1, &invM, why, distance, DRC_FORWARD | DRC_BOTHCORNERS, plane1, plane1); dp->drcc_next = dpnew; /* find bucket preceding new one we wish to insert */ dp = drcFindBucket(j, i, distance); dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dpnew,distance,dp->drcc_next, &set1, &invM, why, distance, DRC_REVERSE | DRC_BOTHCORNERS, plane1, plane1); dp->drcc_next = dpnew; } } } } else { for (i = 0; i < DBNumTypes; i++) for (j = 0; j < DBNumTypes; j++) { if (i == j) continue; if (pset = (DBTypesOnSamePlane(i, j) & pmask)) { if (TTMaskHasType(&setM, i) && TTMaskHasType(&invM, j)) { plane1 = LowestMaskBit(pset); plane2 = LowestMaskBit(pmask2); /* Find bucket preceding the new one we wish to insert */ dp = drcFindBucket(i, j, distance); dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dpnew, distance, dp->drcc_next, &set2, &invM, why, distance, DRC_FORWARD | DRC_BOTHCORNERS, plane2, plane1); dp->drcc_next = dpnew; /* find bucket preceding new one we wish to insert */ dp = drcFindBucket(j, i, distance); dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dpnew,distance,dp->drcc_next, &set2, &invM, why, distance, DRC_REVERSE | DRC_BOTHCORNERS, plane2, plane1); dp->drcc_next = dpnew; } } } } return distance; } /* * ---------------------------------------------------------------------------- * * drcNoOverlap -- * * Process a no-overlap rule. * This is of the form: * * no_overlap layers1 layers2 * * e.g, * * no_overlap poly m2contact * * Results: * Returns 0. * * Side effects: * Updates the DRC technology variables. * * ---------------------------------------------------------------------------- */ int drcNoOverlap(argc, argv) int argc; char *argv[]; { char *layers1 = argv[1], *layers2 = argv[2]; TileTypeBitMask set1, set2; TileType i, j; int plane; /* * Grab up two sets of tile types, and make sure that if * any type from one set is painted over any type from the * other, then an error results. */ DBTechNoisyNameMask(layers1, &set1); DBTechNoisyNameMask(layers2, &set2); for (i = 0; i < DBNumTypes; i++) for (j = 0; j < DBNumTypes; j++) if (TTMaskHasType(&set1, i) && TTMaskHasType(&set2, j)) for (plane = 0; plane < DBNumPlanes; plane++) { DRCCurStyle->DRCPaintTable[plane][j][i] = TT_ERROR_S; DRCCurStyle->DRCPaintTable[plane][i][j] = TT_ERROR_S; } return (0); } /* * ---------------------------------------------------------------------------- * * drcExactOverlap -- * * Process an exact overlap * This is of the form: * * exact_overlap layers * * e.g, * * exact_overlap pmc,dmc * * Results: * Returns 0. * * Side effects: * Updates DRCExactOverlapTypes. * * ---------------------------------------------------------------------------- */ int drcExactOverlap(argc, argv) int argc; char *argv[]; { char *layers = argv[1]; TileTypeBitMask set; /* * Grab up a bunch of tile types, and remember these: tiles * of these types cannot overlap themselves in different cells * unless they overlap exactly. */ DBTechNoisyNameMask(layers, &set); TTMaskSetMask(&DRCCurStyle->DRCExactOverlapTypes, &set); return (0); } /* * ---------------------------------------------------------------------------- * * drcRectangle -- * * Process a rectangle rule. This is of the form: * * rectangle layers maxwidth [even|odd|any] why * * The rule checks to make sure that the region is rectangular and that the * width and length are even or odd, as specified. These two criteria ensure * that the squares rule of the cifout section can properly produce via * holes without misaligning them between cells and without putting the via * holes off grid. The maxwidth is required to make the extent of this rule * a finite size, so that we can set the DRChalo to something finite. * * Results: * maxwidth * * Side effects: * Updates the DRC technology variables. * * ---------------------------------------------------------------------------- */ int drcRectangle(argc, argv) int argc; char *argv[]; { char *layers = argv[1]; char *why = drcWhyDup(argv[4]); TileTypeBitMask types, nottypes; int maxwidth; static char *drcRectOpt[4] = {"any", "even", "odd", 0}; int i, j, even, plane; PlaneMask pMask, pset, ptest; /* parse arguments */ ptest = DBTechNoisyNameMask(layers, &types); pMask = CoincidentPlanes(&types, ptest); if (pMask == 0) { TechError("Layers in rectangle rule must lie in a single plane."); return 0; } TTMaskCom2(¬types, &types); if (sscanf(argv[2], "%d", &maxwidth) != 1) { TechError("bad maxwidth in rectangle rule"); return 0; } even = Lookup(argv[3], drcRectOpt); if (even < 0) { TechError("bad [even|odd|any] selection in rectangle rule"); return 0; } even--; /* -1: any, 0: even, 1: odd */ /* Install 2 edge rules: one that checks rectangle-ness, and one that * checks size */ for (i = 0; i < DBNumTypes; i++) { for (j = 0; j < DBNumTypes; j++) { if (i == j) continue; if (pset = (DBTypesOnSamePlane(i, j) & pMask)) { if (TTMaskHasType(&types, i) && TTMaskHasType(¬types, j)) { DRCCookie *dp, *dpnew; plane = LowestMaskBit(pset); /* * A rule that checks rectangle-ness. * left: oktypes, right: other types * This rule needs to be checked in all 4 directions */ int distance = 1; /* Find bucket preceding the new one we wish to insert */ dp = drcFindBucket(i, j, distance); dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dpnew, distance, dp->drcc_next, ¬types, &DBAllTypeBits, why, distance, DRC_FORWARD, plane, plane); dp->drcc_next = dpnew; /* Find bucket preceding the new one we wish to insert */ dp = drcFindBucket(j, i, distance); /* note: j, i not i, j */ dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dpnew, distance, dp->drcc_next, ¬types, &DBAllTypeBits, why, distance, DRC_REVERSE, plane, plane); dp->drcc_next = dpnew; if (maxwidth > 0) { /* * A rule that checks size. * left: other types, right: oktypes */ distance = maxwidth; /* note: j, i not i, j */ for (dp = DRCCurStyle->DRCRulesTbl[j][i]; dp->drcc_next != (DRCCookie *) NULL && dp->drcc_next->drcc_dist < distance; dp = dp->drcc_next); /* null body */ dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie)); drcAssign(dpnew, distance, dp->drcc_next, &types, &DBZeroTypeBits, why, even, DRC_RECTSIZE, plane, plane); dp->drcc_next = dpnew; } } } } } return maxwidth; } /* * ---------------------------------------------------------------------------- * * drcStepSize -- * * Process a declaration of the step size. * This is of the form: * * stepsize step_size * * e.g, * * stepsize 1000 * * Results: * Returns 0. * * Side effects: * Updates DRCStepSize. * * ---------------------------------------------------------------------------- */ int drcStepSize(argc, argv) int argc; char *argv[]; { if (DRCCurStyle == NULL) return 0; DRCCurStyle->DRCStepSize = atoi(argv[1]); if (DRCCurStyle->DRCStepSize <= 0) { TechError("Step size must be a positive integer.\n"); DRCCurStyle->DRCStepSize = 0; } else if (DRCCurStyle->DRCStepSize < 16) { TechError("Warning: abnormally small DRC step size (%d)\n", DRCCurStyle->DRCStepSize); } return (0); } /* * ---------------------------------------------------------------------------- * * DRCTechFinal -- * * Called after all lines of the drc section in the technology file have been * read. Ensures that a valid style is in effect, and then calls * drcTechFinalStyle(). * * Results: * None. * * Side effects: * See drcTechFinalStyle(); * * ---------------------------------------------------------------------------- */ void DRCTechFinal() { DRCStyle *ds; /* Create a "default" style if there isn't one */ if (DRCStyleList == NULL) { DRCStyleList = (DRCKeep *)mallocMagic(sizeof(DRCKeep)); DRCStyleList->ds_next = NULL; DRCStyleList->ds_name = StrDup((char **)NULL, "default"); drcTechNewStyle(); DRCCurStyle->ds_name = DRCStyleList->ds_name; DRCCurStyle->ds_status = TECH_LOADED; } drcTechFinalStyle(DRCCurStyle); } /* * ---------------------------------------------------------------------------- * drcScaleDown --- * * DRC distances may be specified with a scale factor so that physically * based rules can be recorded, but the rules used will be rounded (up) * to the nearest lambda. The fractional part of the true distance in * lambda is saved, so that the original value can be recovered when * the magic grid is rescaled. * * Results: * None. * * Side Effects: * Scales all the DRC distances by dividing by the DRC scale factor. * ---------------------------------------------------------------------------- */ void drcScaleDown(style, scalefactor) DRCStyle *style; int scalefactor; { TileType i, j; DRCCookie *dp; int dist; if (scalefactor > 1) { for (i = 0; i < TT_MAXTYPES; i++) for (j = 0; j < TT_MAXTYPES; j++) for (dp = style->DRCRulesTbl[i][j]; dp != NULL; dp = dp->drcc_next) { if (dp->drcc_dist > 0) { dist = dp->drcc_dist; dp->drcc_dist /= scalefactor; if ((dp->drcc_mod = (unsigned char)(dist % scalefactor)) != 0) if (!(dp->drcc_flags & DRC_MAXWIDTH)) dp->drcc_dist++; } if (dp->drcc_cdist > 0) { int locscale = scalefactor; if (dp->drcc_flags & DRC_AREA) locscale *= scalefactor; dist = dp->drcc_cdist; dp->drcc_cdist /= locscale; if ((dp->drcc_cmod = (unsigned char)(dist % locscale)) != 0) dp->drcc_cdist++; } } } } /* * ---------------------------------------------------------------------------- * drcScaleUp --- * * Recovers the original (pre-scaled) values for drcc_dist and * drcc_cdist in the DRC cookies. * * Results: * None. * * Side Effects: * Scales all the DRC distances by multiplying by the DRC scale factor. * ---------------------------------------------------------------------------- */ void drcScaleUp(style, scalefactor) DRCStyle *style; int scalefactor; { TileType i, j; DRCCookie *dp; int dist; if (style == NULL) return; if (scalefactor > 1) { for (i = 0; i < TT_MAXTYPES; i++) for (j = 0; j < TT_MAXTYPES; j++) for (dp = style->DRCRulesTbl[i][j]; dp != NULL; dp = dp->drcc_next) { if (dp->drcc_dist > 0) { dist = dp->drcc_dist; if (dp->drcc_mod != 0) if (!(dp->drcc_flags & DRC_MAXWIDTH)) dp->drcc_dist--; dp->drcc_dist *= scalefactor; dp->drcc_dist += (short)dp->drcc_mod; dp->drcc_mod = 0; } if (dp->drcc_cdist > 0) { dist = dp->drcc_cdist; if (dp->drcc_cmod != 0) dp->drcc_cdist--; dp->drcc_cdist *= scalefactor; if (dp->drcc_flags & DRC_AREA) dp->drcc_cdist *= scalefactor; dp->drcc_cdist += (short)dp->drcc_cmod; dp->drcc_cmod = 0; } } } } /* * ---------------------------------------------------------------------------- * * drcTechFinalStyle -- * * Called after all lines of the drc section in the technology file have been * read. The preliminary DRC Rules Table is pruned by removing rules covered * by other (longer distance) rules, and by removing the dummy rule at the * front of each list. Where edges are completely illegal, the rule list is * pruned to a single rule. * * Results: * None. * * Side effects: * May remove DRCCookies from the linked lists of the DRCRulesTbl. * * ---------------------------------------------------------------------------- */ void drcTechFinalStyle(style) DRCStyle *style; { TileTypeBitMask tmpMask, nextMask; DRCCookie *dummy, *dp, *next, *dptrig; DRCCookie **dpp, **dp2back; TileType i, j; /* If the scale factor is not 1, then divide all distances by */ /* the scale factor, take the ceiling, and save the (negative) */ /* remainder. */ drcScaleUp(style, style->DRCScaleFactorD); drcScaleDown(style, style->DRCScaleFactorN); /* Set maximum halo */ style->DRCTechHalo = DRCTechHalo; /* A reasonable chunk size for design-rule checking is about * 16 times the maximum design-rule interaction distance. This * results in a halo overhead of about 27%. If there's no DRC * information at all (TechHalo is zero), just pick any size. * (Update 1/13/09: "any size" needs a bit of modification, * because 64 will be way too small for a layout with a small * scalefactor. Assuming that the CIF output style is valid, * use its scalefactor to adjust the step size). */ if (style->DRCStepSize == 0) { if (style->DRCTechHalo == 0) { if (CIFCurStyle != NULL) style->DRCStepSize = 6400 / CIFCurStyle->cs_scaleFactor; else style->DRCStepSize = 64; } else style->DRCStepSize = 16 * style->DRCTechHalo; } DRCStepSize = style->DRCStepSize; /* Remove dummy buckets */ for (i = 0; i < TT_MAXTYPES; i++) { for (j = 0; j < TT_MAXTYPES; j++) { dpp = &(style->DRCRulesTbl [i][j]); dummy = *dpp; *dpp = dummy->drcc_next; freeMagic((char *) dummy); } } drcCifFinal(); if (!DRCRuleOptimization) return; /* Check for edges that are completely illegal. Where this is the * case, eliminate all of the edge's rules except one. */ for (i = 0; i < DBNumTypes; i++) { for (j = 0; j < DBNumTypes; j++) { DRCCookie *keep = NULL, *dptest, *dptemp, *dpnew; for (dp = style->DRCRulesTbl[i][j]; dp != NULL; dp = dp->drcc_next) { if (dp->drcc_flags & (DRC_NONSTANDARD || DRC_OUTSIDE)) continue; if (dp->drcc_flags & DRC_REVERSE) { if ((i == TT_SPACE) || TTMaskHasType(&dp->drcc_mask, i)) continue; } else { if ((j == TT_SPACE) || TTMaskHasType(&dp->drcc_mask, j)) continue; } /* Rules where okTypes are in a different plane don't count, */ /* unless i or j also appear in the checked plane. */ if (dp->drcc_plane != dp->drcc_edgeplane) { if (dp->drcc_flags & DRC_REVERSE) { if ((i == TT_SPACE) || !DBTypeOnPlane(i, dp->drcc_plane)) continue; } else { if ((j == TT_SPACE) || !DBTypeOnPlane(j, dp->drcc_plane)) continue; } } // if (DBIsContact(i) || DBIsContact(j) || i == TT_SPACE || // j == TT_SPACE) continue; dpnew = NULL; keep = dp; /* This edge is illegal. Throw away all rules except the one * needed that is always violated. */ dptest = style->DRCRulesTbl[i][j]; while (dptest != NULL) { dptemp = dptest->drcc_next; if ((dptest == keep) || (dptest->drcc_edgeplane != keep->drcc_edgeplane)) { dptest->drcc_next = NULL; if (dpnew == NULL) style->DRCRulesTbl[i][j] = dptest; else dpnew->drcc_next = dptest; dpnew = dptest; /* "keep" can't be a trigger rule! */ if (dptest == keep) keep->drcc_flags &= ~DRC_TRIGGER; } else { /* Don't free the shared drcc_why string here! */ freeMagic((char *)dptest); drcRulesOptimized++; } dptest = dptemp; } } /* TxPrintf("Edge %s-%s is illegal.\n", DBTypeShortName(i), DBTypeShortName(j)); */ } } /* * Remove any rule A "covered" by another rule B, i.e., * B's distance >= A's distance, * B's corner distance >= A's corner distance, * B's RHS type mask is a subset of A's RHS type mask, and * B's corner mask == A's corner mask * B's check plane == A's check plane * either both A and B or neither is a REVERSE direction rule * if A is BOTHCORNERS then B must be, too */ for (i = 0; i < DBNumTypes; i++) { for (j = 0; j < DBNumTypes; j++) { for (dp = style->DRCRulesTbl[i][j]; dp != NULL; dp = dp->drcc_next) { /* Don't optimize on trigger rules; optimize on the */ /* rule that gets triggered. */ if (dp->drcc_flags & DRC_TRIGGER) { dptrig = dp; dp = dp->drcc_next; } else dptrig = NULL; /* * Check following buckets to see if any is a superset. */ if (dp->drcc_flags & DRC_NONSTANDARD) continue; for (next = dp->drcc_next; next != NULL; next = next->drcc_next) { if (next->drcc_flags & DRC_TRIGGER) { /* A triggered rule cannot be considered */ /* a superset of a non-triggered rule or */ /* a rule with a different trigger, so */ /* we skip all triggered rules and their */ /* triggering rule. */ next = next->drcc_next; continue; } tmpMask = nextMask = next->drcc_mask; TTMaskAndMask(&tmpMask, &dp->drcc_mask); if (!TTMaskEqual(&tmpMask, &nextMask)) continue; if (!TTMaskEqual(&dp->drcc_corner, &next->drcc_corner)) continue; if (dp->drcc_dist > next->drcc_dist) continue; if (dp->drcc_cdist > next->drcc_cdist) continue; if (dp->drcc_plane != next->drcc_plane) continue; if (dp->drcc_flags & DRC_REVERSE) { if (!(next->drcc_flags & DRC_REVERSE)) continue; } else if (next->drcc_flags & DRC_REVERSE) continue; if ((next->drcc_flags & DRC_BOTHCORNERS) && (dp->drcc_flags & DRC_BOTHCORNERS) == 0) continue; if (next->drcc_flags & DRC_NONSTANDARD) continue; if (dp->drcc_dist == next->drcc_dist) { if ((next->drcc_flags & DRC_OUTSIDE) && !(dp->drcc_flags & DRC_OUTSIDE)) continue; if (!(next->drcc_flags & DRC_OUTSIDE) && (dp->drcc_flags & DRC_OUTSIDE)) continue; } break; } if (next == NULL) continue; /* "dp" is a subset of "next". Eliminate it. */ /* For triggered rules, eliminate both the rule */ /* and the trigger. */ if (dptrig != NULL) dp = dptrig; /* TxPrintf("For edge %s-%s, \"%s\" covers \"%s\"\n", DBTypeShortName(i), DBTypeShortName(j), next->drcc_why, dp->drcc_why); */ dp2back = &(style->DRCRulesTbl[i][j]); while (*dp2back != dp) dp2back = &(*dp2back)->drcc_next; /* Trigger rules */ if (dptrig != NULL) { dptrig = dp->drcc_next; freeMagic((char *)dp->drcc_next); *dp2back = dp->drcc_next->drcc_next; /* Replace this entry so on the next cycle */ /* dp will be the next rule. This works */ /* even though dp is free'd (below), due to */ /* the one-delayed free mechanism. */ dp->drcc_next = *dp2back; } else *dp2back = dp->drcc_next; /* Don't free the shared drcc_why string here! */ freeMagic((char *) dp); drcRulesOptimized += 1; } } } } /* * ---------------------------------------------------------------------------- * * DRCTechRuleStats -- * * Print out some statistics about the design rule database. * * Results: * None. * * Side effects: * A bunch of stuff gets printed on the terminal. * * ---------------------------------------------------------------------------- */ #define MAXBIN 10 void DRCTechRuleStats() { int counts[MAXBIN+1]; int edgeRules, overflow; int i, j; DRCCookie *dp; /* Count up the total number of edge rules, and histogram them * by the number of rules per edge. */ edgeRules = 0; overflow = 0; for (i=0; i<=MAXBIN; i++) counts[i] = 0; for (i=0; iDRCRulesTbl[i][j]; dp != NULL; dp = dp->drcc_next) thisCount++; edgeRules += thisCount; if (!DBTypesOnSamePlane(i, j)) continue; if (thisCount <= MAXBIN) counts[thisCount] += 1; else overflow += 1; } /* Print out the results. */ TxPrintf("Total number of rules specifed in tech file: %d\n", drcRulesSpecified); TxPrintf("Edge rules optimized away: %d\n", drcRulesOptimized); TxPrintf("Edge rules left in database: %d\n", edgeRules); TxPrintf("Histogram of # edges vs. rules per edge:\n"); for (i=0; i<=MAXBIN; i++) { TxPrintf(" %2d rules/edge: %d.\n", i, counts[i]); } TxPrintf(" >%2d rules/edge: %d.\n", MAXBIN, overflow); } /* * ---------------------------------------------------------------------------- * * DRCTechScale -- * * Multiply all DRC rule widths and spacings by a factor of scaled/scalen. * (Don't need to use DBScaleValue() because all values must be positive * and cannot be (M)INFINITY.) * * ---------------------------------------------------------------------------- */ void DRCTechScale(scalen, scaled) int scalen, scaled; { DRCCookie *dp; TileType i, j; int scalegcf; if (DRCCurStyle == NULL) return; else if (scalen == scaled == 1) return; /* Revert DRC rules to original (unscaled) values */ drcScaleUp(DRCCurStyle, DRCCurStyle->DRCScaleFactorN); drcScaleDown(DRCCurStyle, DRCCurStyle->DRCScaleFactorD); DRCCurStyle->DRCScaleFactorD *= scaled; DRCCurStyle->DRCScaleFactorN *= scalen; /* Reduce scalefactor ratio by greatest common factor */ scalegcf = FindGCF(DRCCurStyle->DRCScaleFactorD, DRCCurStyle->DRCScaleFactorN); DRCCurStyle->DRCScaleFactorD /= scalegcf; DRCCurStyle->DRCScaleFactorN /= scalegcf; /* Rescale all rules to the new scalefactor */ drcScaleUp(DRCCurStyle, DRCCurStyle->DRCScaleFactorD); drcScaleDown(DRCCurStyle, DRCCurStyle->DRCScaleFactorN); DRCTechHalo *= scaled; DRCTechHalo /= scalen; DRCStepSize *= scaled; DRCStepSize /= scalen; DRCCurStyle->DRCTechHalo *= scaled; DRCCurStyle->DRCTechHalo /= scalen; DRCCurStyle->DRCStepSize *= scaled; DRCCurStyle->DRCStepSize /= scalen; } /* The following routines are used by the "tech" command (and in other places, * such as the LEF file reader) to query the DRC database. */ /* *----------------------------------------------------------------------------- * DRCGetDefaultLayerWidth --- * * Determine a default layer width from the DRC width rules * of a layer. Continue processing until we have processed all * rules, since rules are ordered from shortest to longest distance, * and the maximum distance rule will mask any rules with a shorter * distance. * * Results: * The minimum width of the magic layer, in magic internal units * * Side effects: * None. * *----------------------------------------------------------------------------- */ int DRCGetDefaultLayerWidth(ttype) TileType ttype; { int routeWidth = 0; DRCCookie *cptr; TileTypeBitMask *set; for (cptr = DRCCurStyle->DRCRulesTbl[TT_SPACE][ttype]; cptr != (DRCCookie *) NULL; cptr = cptr->drcc_next) { /* FORWARD rules only, and no MAXWIDTH */ if ((cptr->drcc_flags & (DRC_REVERSE | DRC_MAXWIDTH)) == 0) { set = &cptr->drcc_mask; if (TTMaskHasType(set, ttype) && TTMaskEqual(set, &cptr->drcc_corner)) if ((cptr->drcc_plane == DBPlane(ttype)) && (cptr->drcc_dist == cptr->drcc_cdist)) { routeWidth = cptr->drcc_dist; /* Diagnostic */ /* TxPrintf("DRC: Layer %s has default width %d\n", DBTypeLongNameTbl[ttype], routeWidth); */ } } } return routeWidth; } /* *----------------------------------------------------------------------------- * DRCGetDefaultLayerSpacing --- * * Determine a default layer-to-layer spacing from the DRC width * rules of a layer. Continue processing all rules, since rules * are ordered from shortest to longest distance, and the largest * distance matching the criteria sets the rule. * * Results: * The minimum spacing between the specified magic layer types, * in magic internal units * * Side effects: * None. * *----------------------------------------------------------------------------- */ int DRCGetDefaultLayerSpacing(ttype1, ttype2) TileType ttype1, ttype2; { int routeSpacing = 0; DRCCookie *cptr; TileTypeBitMask *set; for (cptr = DRCCurStyle->DRCRulesTbl[ttype1][TT_SPACE]; cptr != (DRCCookie *) NULL; cptr = cptr->drcc_next) { if (cptr->drcc_flags & DRC_TRIGGER) { /* Skip widespacing rules */ cptr = cptr->drcc_next; continue; } if ((cptr->drcc_flags & DRC_REVERSE) == 0) /* FORWARD only */ { set = &cptr->drcc_mask; if (!TTMaskHasType(set, ttype2)) if (PlaneMaskHasPlane(DBTypePlaneMaskTbl[ttype2], cptr->drcc_plane) && (cptr->drcc_dist == cptr->drcc_cdist)) { routeSpacing = cptr->drcc_dist; /* Diagnostic */ /* TxPrintf("DRC: Layer %s has default spacing %d to layer %s\n", DBTypeLongNameTbl[ttype1], routeSpacing, DBTypeLongNameTbl[ttype2]); */ } } } return routeSpacing; } /* *----------------------------------------------------------------------------- * DRCGetDefaultLayerSurround --- * * Determine the default minimum required surround amount * of layer type 2 around layer type 1. * Continue processing all rules, since rules are ordered from * shortest to longest distance, and the largest value of the * surround material sets the minimum required width. * * Results: * The minimum spacing between the specified magic layer types, * in magic internal units * * Side effects: * None. * *----------------------------------------------------------------------------- */ int DRCGetDefaultLayerSurround(ttype1, ttype2) TileType ttype1, ttype2; { int layerSurround = 0; DRCCookie *cptr; TileTypeBitMask *set; for (cptr = DRCCurStyle->DRCRulesTbl[ttype1][TT_SPACE]; cptr != (DRCCookie *) NULL; cptr = cptr->drcc_next) { if ((cptr->drcc_flags & DRC_REVERSE) == 0) /* FORWARD only */ { set = &cptr->drcc_mask; if (!TTMaskHasType(set, TT_SPACE)) if (PlaneMaskHasPlane(DBTypePlaneMaskTbl[ttype2], cptr->drcc_plane) && (cptr->drcc_dist == cptr->drcc_cdist)) { layerSurround = cptr->drcc_dist; /* Diagnostic */ /* TxPrintf("DRC: Layer %s has default surround %d over layer %s\n", DBTypeLongNameTbl[ttype2], layerSurround, DBTypeLongNameTbl[ttype1]); */ } } } return layerSurround; } magic-8.0.210/drc/DRCextend.c0000664000175000001440000003544011745550372014227 0ustar timusers #ifndef lint static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/drc/DRCextend.c,v 1.6 2010/09/20 21:13:22 tim Exp $"; #endif #include #include #include #include "utils/magic.h" #include "utils/malloc.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 "dbwind/dbwtech.h" #include "drc/drc.h" #include "utils/signals.h" #include "utils/stack.h" #include "utils/maxrect.h" Stack *DRCstack = (Stack *)NULL; #define PUSHTILE(tp) \ if ((tp)->ti_client == (ClientData) DRC_UNPROCESSED) { \ (tp)->ti_client = (ClientData) DRC_PENDING; \ STACKPUSH((ClientData) (tp), DRCstack); \ } /* *------------------------------------------------------------------------- * * drcCheckAngles --- checks whether a tile conforms to orthogonal-only * geometry (90 degree angles only) or 45-degree geometry (x must * be equal to y on all non-Manhattan tiles). * * Results: none * * Side Effects: may cause errors to be painted. * *------------------------------------------------------------------------- */ void drcCheckAngles(tile, arg, cptr) Tile *tile; struct drcClientData *arg; DRCCookie *cptr; { Rect rect; int ortho = (cptr->drcc_flags & 0x01); /* 1 = orthogonal, 0 = 45s */ if (IsSplit(tile)) { if (ortho || (RIGHT(tile) - LEFT(tile)) != (TOP(tile) - BOTTOM(tile))) { TiToRect(tile, &rect); GeoClip(&rect, arg->dCD_clip); if (!GEO_RECTNULL(&rect)) { arg->dCD_cptr = cptr; (*(arg->dCD_function)) (arg->dCD_celldef, &rect, arg->dCD_cptr, arg->dCD_clientData); (*(arg->dCD_errors))++; } } } } /* *------------------------------------------------------------------------- * * drcCheckArea- checks to see that a collection of tiles of a given * type have more than a minimum area. * * Results: none * * Side Effects: may cause errors to be painted. * *------------------------------------------------------------------------- */ void drcCheckArea(starttile,arg,cptr) Tile *starttile; struct drcClientData *arg; DRCCookie *cptr; { int arealimit; int area=0; TileTypeBitMask *oktypes = &cptr->drcc_mask; Tile *tile,*tp; Rect *cliprect = arg->dCD_rect; arealimit = cptr->drcc_cdist; arg->dCD_cptr = cptr; if (DRCstack == (Stack *) NULL) DRCstack = StackNew(64); /* Mark this tile as pending and push it */ PUSHTILE(starttile); while (!StackEmpty(DRCstack)) { tile = (Tile *) STACKPOP(DRCstack); if (tile->ti_client != (ClientData)DRC_PENDING) continue; area += (RIGHT(tile)-LEFT(tile))*(TOP(tile)-BOTTOM(tile)); tile->ti_client = (ClientData)DRC_PROCESSED; /* are we at the clip boundary? If so, skip to the end */ if (RIGHT(tile) == cliprect->r_xtop || LEFT(tile) == cliprect->r_xbot || BOTTOM(tile) == cliprect->r_ybot || TOP(tile) == cliprect->r_ytop) goto forgetit; if (area >= arealimit) goto forgetit; /* Top */ for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp)) if (TTMaskHasType(oktypes, TiGetBottomType(tp))) PUSHTILE(tp); /* Left */ for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp)) if (TTMaskHasType(oktypes, TiGetRightType(tp))) PUSHTILE(tp); /* Bottom */ for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp)) if (TTMaskHasType(oktypes, TiGetTopType(tp))) PUSHTILE(tp); /* Right */ for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp)) if (TTMaskHasType(oktypes, TiGetLeftType(tp))) PUSHTILE(tp); } if (area < arealimit) { Rect rect; TiToRect(starttile,&rect); GeoClip(&rect, arg->dCD_clip); if (!GEO_RECTNULL(&rect)) { (*(arg->dCD_function)) (arg->dCD_celldef, &rect, arg->dCD_cptr, arg->dCD_clientData); /*** DBWAreaChanged(arg->dCD_celldef,&rect, DBW_ALLWINDOWS, &DBAllButSpaceBits); ***/ (*(arg->dCD_errors))++; } } forgetit: while (!StackEmpty(DRCstack)) tile = (Tile *) STACKPOP(DRCstack); /* reset the tiles */ starttile->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(starttile, DRCstack); while (!StackEmpty(DRCstack)) { tile = (Tile *) STACKPOP(DRCstack); /* Top */ for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp)) if (tp->ti_client != (ClientData)DRC_UNPROCESSED) { tp->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(tp,DRCstack); } /* Left */ for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp)) if (tp->ti_client != (ClientData)DRC_UNPROCESSED) { tp->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(tp,DRCstack); } /* Bottom */ for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp)) if (tp->ti_client != (ClientData)DRC_UNPROCESSED) { tp->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(tp,DRCstack); } /* Right */ for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp)) if (tp->ti_client != (ClientData)DRC_UNPROCESSED) { tp->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(tp,DRCstack); } } } /* *------------------------------------------------------------------------- * * drcCheckMaxwidth - checks to see that at least one dimension of a region * does not exceed some amount (original version---for "bends_illegal" * option only). * * This should really be folded together with drcCheckArea, since the routines * are nearly identical, but I'm feeling lazy, so I'm just duplicating * the code for now. * * Results: 1 if within max bounds, 0 otherwise. * * Side Effects: may cause errors to be painted. * *------------------------------------------------------------------------- */ int drcCheckMaxwidth(starttile,arg,cptr) Tile *starttile; struct drcClientData *arg; DRCCookie *cptr; { int edgelimit; int retval = 0; Rect boundrect; TileTypeBitMask *oktypes; Tile *tile,*tp; oktypes = &cptr->drcc_mask; edgelimit = cptr->drcc_dist; arg->dCD_cptr = cptr; if (DRCstack == (Stack *) NULL) DRCstack = StackNew(64); /* Mark this tile as pending and push it */ PUSHTILE(starttile); TiToRect(starttile,&boundrect); while (!StackEmpty(DRCstack)) { tile = (Tile *) STACKPOP(DRCstack); if (tile->ti_client != (ClientData)DRC_PENDING) continue; tile->ti_client = (ClientData)DRC_PROCESSED; if (boundrect.r_xbot > LEFT(tile)) boundrect.r_xbot = LEFT(tile); if (boundrect.r_xtop < RIGHT(tile)) boundrect.r_xtop = RIGHT(tile); if (boundrect.r_ybot > BOTTOM(tile)) boundrect.r_ybot = BOTTOM(tile); if (boundrect.r_ytop < TOP(tile)) boundrect.r_ytop = TOP(tile); if (boundrect.r_xtop - boundrect.r_xbot > edgelimit && boundrect.r_ytop - boundrect.r_ybot > edgelimit) { while (!StackEmpty(DRCstack)) tile = (Tile *) STACKPOP(DRCstack); break; } /* Top */ for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp)) if (TTMaskHasType(oktypes, TiGetBottomType(tp))) PUSHTILE(tp); /* Left */ for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp)) if (TTMaskHasType(oktypes, TiGetRightType(tp))) PUSHTILE(tp); /* Bottom */ for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp)) if (TTMaskHasType(oktypes, TiGetTopType(tp))) PUSHTILE(tp); /* Right */ for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp)) if (TTMaskHasType(oktypes, TiGetLeftType(tp))) PUSHTILE(tp); } if (boundrect.r_xtop - boundrect.r_xbot > edgelimit && boundrect.r_ytop - boundrect.r_ybot > edgelimit) { Rect rect; TiToRect(starttile,&rect); GeoClip(&rect, arg->dCD_clip); if (!GEO_RECTNULL(&rect)) { (*(arg->dCD_function)) (arg->dCD_celldef, &rect, arg->dCD_cptr, arg->dCD_clientData); (*(arg->dCD_errors))++; retval = 1; } } /* reset the tiles */ starttile->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(starttile, DRCstack); while (!StackEmpty(DRCstack)) { tile = (Tile *) STACKPOP(DRCstack); /* Top */ for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp)) if (tp->ti_client != (ClientData)DRC_UNPROCESSED) { tp->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(tp,DRCstack); } /* Left */ for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp)) if (tp->ti_client != (ClientData)DRC_UNPROCESSED) { tp->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(tp,DRCstack); } /* Bottom */ for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp)) if (tp->ti_client != (ClientData)DRC_UNPROCESSED) { tp->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(tp,DRCstack); } /* Right */ for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp)) if (tp->ti_client != (ClientData)DRC_UNPROCESSED) { tp->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(tp,DRCstack); } } return retval; } /* *------------------------------------------------------------------------- * * drcCheckRectSize- * * Checks to see that a collection of tiles of given * types have the proper size (max size and also even or odd size). * * Results: none * * Side Effects: may cause errors to be painted. * *------------------------------------------------------------------------- */ void drcCheckRectSize(starttile, arg, cptr) Tile *starttile; struct drcClientData *arg; DRCCookie *cptr; { int maxsize, even; TileTypeBitMask *oktypes = &cptr->drcc_mask; int width; int height; int errwidth; int errheight; Tile *t; bool error = FALSE; maxsize = cptr->drcc_dist; even = cptr->drcc_cdist; /* This code only has to work for rectangular regions, since we always * check for rectangular-ness using normal edge rules produced when * we read in the tech file. */ arg->dCD_cptr = cptr; ASSERT(TTMaskHasType(oktypes, TiGetType(starttile)), "drcCheckRectSize"); for (t = starttile; TTMaskHasType(oktypes, TiGetType(t)); t = TR(t)) /* loop has empty body */ ; errwidth = width = LEFT(t) - LEFT(starttile); for (t = starttile; TTMaskHasType(oktypes, TiGetType(t)); t = RT(t)) /* loop has empty body */ ; errheight = height = BOTTOM(t) - BOTTOM(starttile); ASSERT(width > 0 && height > 0, "drcCheckRectSize"); if (width > maxsize) {error = TRUE; errwidth = (width - maxsize);} else if (height > maxsize) {error = TRUE; errheight = (height - maxsize);} else if (even >= 0) { /* meaning of "even" variable: -1, any; 0, even; 1, odd */ if (ABS(width - ((width/2)*2)) != even) {error = TRUE; errwidth = 1;} else if (ABS(height - ((height/2)*2)) != even) {error = TRUE; errheight = 1;} } if (error) { Rect rect; TiToRect(starttile, &rect); rect.r_xtop = rect.r_xbot + errwidth; rect.r_ytop = rect.r_ybot + errheight; GeoClip(&rect, arg->dCD_clip); if (!GEO_RECTNULL(&rect)) { (*(arg->dCD_function)) (arg->dCD_celldef, &rect, arg->dCD_cptr, arg->dCD_clientData); (*(arg->dCD_errors))++; } } } /* *------------------------------------------------------------------------- * * drcCanonicalMaxwidth - checks to see that at least one dimension of a * rectangular region does not exceed some amount. * * This differs from "CheckMaxwidth" in being more rigorous about * determining where a region of max width might be found. There * is no "bend" rule here. We check from the edge being observed * and back, and adjust the bounds on the sides, forking as * necessary to consider alternative arrangements of the interior * rectangle. A distance "dist" is passed to the routine. We * may push the interior rectangle back by up to this amount from * the observed edge. For "widespacing" rules, we check all * interior regions that satisfy maxwidth and whose edge is * within "dist" of the original edge. For slotting requirement * rules, "dist" is zero (inability to find a rectangle touching * the original edge ensures that no such rectangle exists that * can't be found touching a different edge). Also, we only * need to check one of the four possible edge combinations * (this part of it is handled in the drcBasic code). * * Results: * LinkedRect list of areas satisfying maxwidth. There may be * more than one rectangle, and rectangles may overlap. It * may make more sense to return only one rectangle, the union * of all rectangles in the list. * * Side Effects: * None. * *------------------------------------------------------------------------- */ MaxRectsData * drcCanonicalMaxwidth(starttile, dir, arg, cptr) Tile *starttile; int dir; /* direction of rule */ struct drcClientData *arg; DRCCookie *cptr; { int s, edgelimit; Tile *tile,*tp; TileTypeBitMask wrongtypes; static MaxRectsData *mrd = (MaxRectsData *)NULL; Rect *boundrect, boundorig; /* Generate an initial array size of 8 for rlist and swap. */ if (mrd == (MaxRectsData *)NULL) { mrd = (MaxRectsData *)mallocMagic(sizeof(MaxRectsData)); mrd->rlist = (Rect *)mallocMagic(8 * sizeof(Rect)); mrd->swap = (Rect *)mallocMagic(8 * sizeof(Rect)); mrd->listdepth = 8; } if (starttile == NULL) return mrd; boundrect = &(mrd->rlist[0]); mrd->match = CLIENTDEFAULT; edgelimit = cptr->drcc_dist; arg->dCD_cptr = cptr; TiToRect(starttile, boundrect); /* Determine area to be searched */ switch (dir) { case GEO_NORTH: boundrect->r_ytop = boundrect->r_ybot; boundrect->r_xbot -= (edgelimit - 1); boundrect->r_xtop += (edgelimit - 1); boundrect->r_ytop += edgelimit; break; case GEO_SOUTH: boundrect->r_ybot = boundrect->r_ytop; boundrect->r_xbot -= (edgelimit - 1); boundrect->r_xtop += (edgelimit - 1); boundrect->r_ybot -= edgelimit; break; case GEO_EAST: boundrect->r_xtop = boundrect->r_xbot; boundrect->r_ybot -= (edgelimit - 1); boundrect->r_ytop += (edgelimit - 1); boundrect->r_xtop += edgelimit; break; case GEO_WEST: boundrect->r_xbot = boundrect->r_xtop; boundrect->r_ybot -= (edgelimit - 1); boundrect->r_ytop += (edgelimit - 1); boundrect->r_xbot -= edgelimit; break; case GEO_CENTER: boundrect->r_xbot -= edgelimit; boundrect->r_xtop += edgelimit; boundrect->r_ybot -= edgelimit; boundrect->r_ytop += edgelimit; break; } /* Do an area search on boundrect to find all materials not */ /* in oktypes. Each such tile clips or subdivides */ /* boundrect. Any rectangles remaining after the search */ /* satisfy the maxwidth rule. */ mrd->entries = 1; mrd->maxdist = edgelimit; TTMaskCom2(&wrongtypes, &cptr->drcc_mask); boundorig = *boundrect; DBSrPaintArea(starttile, arg->dCD_celldef->cd_planes[cptr->drcc_plane], &boundorig, &wrongtypes, FindMaxRects, mrd); if (mrd->entries == 0) return NULL; else return (MaxRectsData *)mrd; } magic-8.0.210/drc/Makefile0000644000175000001440000000046510751423606013673 0ustar timusers# # rcsid "$Header: /usr/cvsroot/magic-8.0/drc/Makefile,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $" # MODULE = drc MAGICDIR = .. SRCS = DRCarray.c DRCbasic.c DRCcif.c DRCcontin.c DRCmain.c \ DRCsubcell.c DRCtech.c DRCprint.c DRCextend.c include ${MAGICDIR}/defs.mak include ${MAGICDIR}/rules.mak magic-8.0.210/drc/DRCcif.c0000664000175000001440000011363012411611232013457 0ustar timusers/* * DRCcif.c -- * ****************************************************************************** * Copyright (C) 1989 Digital Equipment Corporation * 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. Digital Equipment Corporation * makes no representations about the suitability of this * software for any purpose. It is provided "as is" without * express or implied warranty. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. **************************************************************************** * */ #ifndef lint static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/drc/DRCcif.c,v 1.5 2010/10/20 20:34:20 tim Exp $"; #endif /* not lint */ #include #include #include #include #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 "dbwind/dbwtech.h" #include "drc/drc.h" #include "cif/cif.h" #include "cif/CIFint.h" #include "utils/signals.h" #include "utils/stack.h" #include "utils/malloc.h" #include "utils/utils.h" extern char *drcWhyDup(); extern int drcCifTile(); extern int areaCifCheck(); extern void drcCheckCifMaxwidth(); extern void drcCheckCifArea(); extern Stack *DRCstack; #define PUSHTILE(tp) \ if ((tp)->ti_client == (ClientData) DRC_UNPROCESSED) { \ (tp)->ti_client = (ClientData) DRC_PENDING; \ STACKPUSH((ClientData) (tp), DRCstack); \ } extern CIFStyle *drcCifStyle; extern bool DRCForceReload; TileTypeBitMask drcCifGenLayers; DRCCookie *drcCifRules[MAXCIFLAYERS][2]; DRCCookie *drcCifCur=NULL; int drcCifValid = FALSE; int beenWarned; #define DRC_CIF_SPACE 0 #define DRC_CIF_SOLID 1 /* * ---------------------------------------------------------------------------- * * drcCifSetStyle -- * * Process a declaration of the cif style. * This is of the form: * * cifstyle cif_style * * e.g, * * cifstyle pg * * Results: * Returns 0. * * Side effects: * Updates drcCifStyle. Do NOT attempt to update the CIF style * in the middle of reading the DRC section. Instead, if the * reported CIF style is not current, flag a warning. The DRC * will be re-read with the CIF extensions when the CIF output * style is changed. * * ---------------------------------------------------------------------------- */ int drcCifSetStyle(argc, argv) int argc; char *argv[]; { CIFKeep *new; for (new = CIFStyleList; new != NULL; new = new->cs_next) { if (!strcmp(new->cs_name, argv[1])) { DRCForceReload = TRUE; if (!strcmp(new->cs_name, CIFCurStyle->cs_name)) drcCifStyle = CIFCurStyle; else { TechError("DRC cif extensions are not enabled.\n\t" "Use \"cif ostyle %s\" to enable them.\n", new->cs_name); drcCifStyle = NULL; beenWarned = TRUE; /* post no more error messages */ } return 0; } } TechError("Unknown DRC cifstyle %s\n",argv[1]); return (0); } /* * ---------------------------------------------------------------------------- * ---------------------------------------------------------------------------- */ int drcCifWarning() { if (!beenWarned) { TechError("Missing cif style for drc\n\t" "This message will not be repeated.\n"); beenWarned = TRUE; } return 0; } /* * ---------------------------------------------------------------------------- * * drcCifWidth -- same this as drcCifWidth, except that it works on * cif layers * * Results: * Returns distance. * * Side effects: * Updates the DRC technology variables. * * ---------------------------------------------------------------------------- */ int drcCifWidth(argc, argv) int argc; char *argv[]; { char *layername = argv[1]; int scalefactor; int centidistance = atoi(argv[2]); char *why = drcWhyDup(argv[3]); TileTypeBitMask set, setC, tmp1; int thislayer = -1; DRCCookie *dpnew,*dpnext; TileType i; if (drcCifStyle == NULL) return drcCifWarning(); for (i = 0; i < drcCifStyle->cs_nLayers;i++) { CIFLayer *layer = drcCifStyle->cs_layers[i]; if (strcmp(layer->cl_name,layername) == 0) { thislayer = i; break; } } if (thislayer == -1) { TechError("Unknown cif layer: %s\n",layername); return (0); } scalefactor = drcCifStyle->cs_scaleFactor; centidistance *= drcCifStyle->cs_expander; // BSI dpnext = drcCifRules[thislayer][DRC_CIF_SPACE]; dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dpnew, centidistance, dpnext, &CIFSolidBits, &CIFSolidBits, why, centidistance, DRC_FORWARD, thislayer, 0); drcCifRules[thislayer][DRC_CIF_SPACE] = dpnew; return ((centidistance+scalefactor-1)/scalefactor); } /* * ---------------------------------------------------------------------------- * * drcCifSpacing -- same this as drcSpacing, except that it works on cif * layers. * * Results: * Returns distance. * * Side effects: * Updates the DRC technology variables. * * ---------------------------------------------------------------------------- */ int drcCifSpacing(argc, argv) int argc; char *argv[]; { char *adjacency = argv[4]; char *why = drcWhyDup(argv[5]); DRCCookie *dpnext, *dpnew; int needReverse = FALSE; TileType i, j; int scalefactor; int centidistance = atoi(argv[3]); char *layers[2]; TileType layer[2]; TileTypeBitMask cmask; int k; layers[0] = argv[1]; layers[1] = argv[2]; if (drcCifStyle == NULL) return drcCifWarning(); for (k=0; k!= 2;k++) { for (i = 0; i < drcCifStyle->cs_nLayers;i++) { CIFLayer *l = drcCifStyle->cs_layers[i]; if (strcmp(l->cl_name,layers[k]) == 0) { layer[k]=i; break; } } if (i == drcCifStyle->cs_nLayers || layer[k] == -1) { TechError("Unknown cif layer: %s",layers[k]); return (0); } } if (strcmp (adjacency, "touching_ok") == 0) { /* If touching is OK, everything must fall in the same plane. */ if (layer[0] != layer[1]) { TechError( "Spacing check with touching ok must all be in one plane.\n"); return (0); } cmask = DBSpaceBits; } else if (strcmp (adjacency, "touching_illegal") == 0) { cmask = DBAllTypeBits; needReverse = TRUE; /* nothing for now */ } else { TechError("Badly formed drc spacing line\n"); return (0); } scalefactor = drcCifStyle->cs_scaleFactor; centidistance *= drcCifStyle->cs_expander; // BSI dpnext = drcCifRules[layer[0]][DRC_CIF_SOLID]; dpnew = (DRCCookie *) mallocMagic((unsigned) sizeof (DRCCookie)); drcAssign(dpnew, centidistance, dpnext, &DBSpaceBits, &cmask, why, centidistance, DRC_FORWARD, layer[1], 0); drcCifRules[layer[0]][DRC_CIF_SOLID] = dpnew; if (needReverse) { dpnew->drcc_flags |= DRC_BOTHCORNERS; dpnext = drcCifRules[layer[1]][DRC_CIF_SOLID]; dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dpnew, centidistance, dpnext, &DBSpaceBits, &cmask, why, centidistance, DRC_FORWARD|DRC_BOTHCORNERS, layer[0], 0); drcCifRules[layer[1]][DRC_CIF_SOLID] = dpnew; if (layer[0] == layer[1]) { dpnext = drcCifRules[layer[1]][DRC_CIF_SPACE]; dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dpnew, centidistance, dpnext, &DBSpaceBits, &cmask, why, centidistance, DRC_REVERSE | DRC_BOTHCORNERS, layer[0], 0); drcCifRules[layer[1]][DRC_CIF_SPACE] = dpnew; dpnext = drcCifRules[layer[0]][DRC_CIF_SPACE]; dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dpnew, centidistance, dpnext, &DBSpaceBits, &cmask, why, centidistance, DRC_REVERSE | DRC_BOTHCORNERS, layer[1], 0); drcCifRules[layer[0]][DRC_CIF_SPACE] = dpnew; } } if (layer[0] != layer[1]) /* make sure they don't overlap exactly */ { dpnext = drcCifRules[layer[1]][DRC_CIF_SPACE]; dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dpnew, scalefactor, dpnext, &DBSpaceBits, &DBZeroTypeBits, why, scalefactor, DRC_FORWARD, layer[0], 0); drcCifRules[layer[1]][DRC_CIF_SPACE] = dpnew; dpnext = drcCifRules[layer[0]][DRC_CIF_SPACE]; dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dpnew, scalefactor, dpnext, &DBSpaceBits, &DBZeroTypeBits, why, scalefactor, DRC_FORWARD, layer[1], 0); drcCifRules[layer[0]][DRC_CIF_SPACE] = dpnew; } return ((centidistance+scalefactor-1)/scalefactor); } /* * ---------------------------------------------------------------------------- * Scale CIF/DRC rules to match grid scaling. Scale by factor (n / d) * ---------------------------------------------------------------------------- */ void drcCifScale(int n, int d) { DRCCookie *dp; int i, j; if (DRCCurStyle != NULL) { for (i = 0; i != MAXCIFLAYERS; i++) for (j = 0; j < 2; j++) for (dp = drcCifRules[i][j]; dp != NULL; dp = dp->drcc_next) { if (dp->drcc_dist != 0) { dp->drcc_dist *= n; dp->drcc_dist /= d; } if (dp->drcc_cdist != 0) { dp->drcc_cdist *= n; dp->drcc_cdist /= d; } } } } /* * ---------------------------------------------------------------------------- * ---------------------------------------------------------------------------- */ void drcCifFreeStyle() { DRCCookie *dp; int i; char *old; if (DRCCurStyle != NULL) { for (i = 0; i != MAXCIFLAYERS; i++) { dp = drcCifRules[i][DRC_CIF_SPACE]; while (dp != NULL) { old = (char *)dp; dp = dp->drcc_next; freeMagic(old); } dp = drcCifRules[i][DRC_CIF_SOLID]; while (dp != NULL) { old = (char *)dp; dp = dp->drcc_next; freeMagic(old); } } } } /* * ---------------------------------------------------------------------------- * ---------------------------------------------------------------------------- */ void drcCifInit() { int i; if (drcCifValid == TRUE) drcCifFreeStyle(); for (i = 0; i != MAXCIFLAYERS; i++) { drcCifRules[i][DRC_CIF_SPACE] = NULL; drcCifRules[i][DRC_CIF_SOLID] = NULL; } drcCifValid = FALSE; TTMaskZero(&drcCifGenLayers); beenWarned = FALSE; } /* * ---------------------------------------------------------------------------- * ---------------------------------------------------------------------------- */ void drcCifFinal() { int i; for (i = 0; i != MAXCIFLAYERS; i++) { DRCCookie *dp; for (dp = drcCifRules[i][DRC_CIF_SPACE]; dp; dp = dp->drcc_next) { drcCifValid = TRUE; TTMaskSetType(&drcCifGenLayers, i); TTMaskSetType(&drcCifGenLayers, dp->drcc_plane); } for (dp = drcCifRules[i][DRC_CIF_SOLID]; dp; dp = dp->drcc_next) { drcCifValid = TRUE; TTMaskSetType(&drcCifGenLayers, i); TTMaskSetType(&drcCifGenLayers, dp->drcc_plane); } } } /* * ---------------------------------------------------------------------------- * drcCifCheck--- * * This is the primary routine for design-rule checking on CIF layers. * * Results: * None. * * Side effects: * Error paint, CIF layer generation, lots of stuff going on. * * ---------------------------------------------------------------------------- */ void drcCifCheck(arg) struct drcClientData *arg; { Rect *checkRect = arg->dCD_rect; Rect cifrect; int scale; int i,j; int oldTiles; if (drcCifValid == FALSE) return; else if (CIFCurStyle != drcCifStyle) return; scale = drcCifStyle->cs_scaleFactor; cifrect = *checkRect; cifrect.r_xbot *= scale; cifrect.r_xtop *= scale; cifrect.r_ybot *= scale; cifrect.r_ytop *= scale; arg->dCD_rect = &cifrect; oldTiles = DRCstatTiles; CIFGen(arg->dCD_celldef, checkRect, CIFPlanes, &DBAllTypeBits, TRUE, TRUE); for (i = 0; i < drcCifStyle->cs_nLayers; i++) { for (j = 0; j != 2; j++) { for (drcCifCur = drcCifRules[i][j]; drcCifCur; drcCifCur = drcCifCur->drcc_next) { TileTypeBitMask *mask; arg->dCD_plane = i; DBSrPaintArea((Tile *) NULL, CIFPlanes[i], &cifrect, (j == DRC_CIF_SOLID) ? &DBSpaceBits : &CIFSolidBits, drcCifTile, arg); } } } arg->dCD_rect = checkRect; DRCstatCifTiles += DRCstatTiles - oldTiles; } /* * ---------------------------------------------------------------------------- * * drcCifTile -- * * Results: * Zero (so that the search will continue), unless an interrupt * occurs, in which case 1 is returned to stop the check. * * Side effects: * Calls the client's error function if errors are found. * * ---------------------------------------------------------------------------- */ int drcCifTile (tile, arg) Tile *tile; /* Tile being examined */ struct drcClientData *arg; { DRCCookie *cptr; /* Current design rule on list */ Tile *tp; /* Used for corner checks */ Rect *rect = arg->dCD_rect; /* Area being checked */ Rect errRect; /* Area checked for an individual rule */ TileTypeBitMask tmpMask; arg->dCD_constraint = &errRect; arg->dCD_radial = 0; /* * If we were interrupted, we want to * abort the check as quickly as possible. */ if (SigInterruptPending) return 1; DRCstatTiles++; /* * Check design rules along a vertical boundary between two tiles. * * 1 | 4 * T * | * tpleft | tile * | * B * 2 | 3 * * The labels "T" and "B" indicate pointT and pointB respectively. * * If a rule's direction is FORWARD, then check from left to right. * * * Check the top right corner if the 1x1 lambda square * on the top left corner (1) of pointT matches the design * rule's "corner" mask. * * * Check the bottom right corner if the rule says check * BOTHCORNERS and the 1x1 lambda square on the bottom left * corner (2) of pointB matches the design rule's "corner" mask. * * If a rule's direction is REVERSE, then check from right to left. * * * Check the bottom left corner if the 1x1 lambda square * on the bottom right corner (3) of pointB matches the design * rule's "corner" mask. * * * Check the top left corner if the rule says check BOTHCORNERS * and the 1x1 lambda square on the top right corner (4) of * pointT matches the design rule's "corner" mask. */ if (drcCifCur->drcc_flags & DRC_AREA) { drcCheckCifArea(tile, arg, drcCifCur); return 0; } if (drcCifCur->drcc_flags & DRC_MAXWIDTH) { drcCheckCifMaxwidth(tile, arg, drcCifCur); return 0; } if (LEFT(tile) >= rect->r_xbot) /* check tile against rect */ { Tile *tpleft; int edgeTop, edgeBot; int top = MIN(TOP(tile), rect->r_ytop); int bottom = MAX(BOTTOM(tile), rect->r_ybot); int edgeX = LEFT(tile); for (tpleft = BL(tile); BOTTOM(tpleft) < top; tpleft = RT(tpleft)) { /* Don't check synthetic edges, i.e. edges with same type on * both sides. Such "edges" have no physical significance, and * depend on internal-details of how paint is spit into tiles. * Thus checking them just leads to confusion. (When edge rules * involving such edges are encountered during technology readin * the user is warned that such edges are not checked). */ if (TiGetRightType(tpleft) == TiGetLeftType(tile)) continue; /* * Go through list of design rules triggered by the * left-to-right edge. */ edgeTop = MIN(TOP (tpleft), top); edgeBot = MAX(BOTTOM(tpleft), bottom); if (edgeTop <= edgeBot) continue; /* do this more intelligently later XXX */ cptr = drcCifCur; { errRect.r_ytop = edgeTop; errRect.r_ybot = edgeBot; if (cptr->drcc_flags & DRC_REVERSE) { /* * Determine corner extensions. * Find the point (3) to the bottom right of pointB */ for (tp = tile; BOTTOM(tp) >= errRect.r_ybot; tp = LB(tp)) /* Nothing */; if (TTMaskHasType(&cptr->drcc_corner, TiGetTopType(tp))) { errRect.r_ybot -= cptr->drcc_cdist; if (DRCEuclidean) arg->dCD_radial |= 0x1000; } if (cptr->drcc_flags & DRC_BOTHCORNERS) { /* * Check the other corner by finding the * point (4) to the top right of pointT. */ if (TOP(tp = tile) <= errRect.r_ytop) for (tp = RT(tp); LEFT(tp) > edgeX; tp = BL(tp)) /* Nothing */; if (TTMaskHasType(&cptr->drcc_corner, TiGetBottomType(tp))) { errRect.r_ytop += cptr->drcc_cdist; if (DRCEuclidean) arg->dCD_radial |= 0x2000; } } /* * Just for grins, see if we could avoid a messy search * by looking only at tpleft. */ errRect.r_xbot = edgeX - cptr->drcc_dist; if (LEFT(tpleft) <= errRect.r_xbot && BOTTOM(tpleft) <= errRect.r_ybot && TOP(tpleft) >= errRect.r_ytop && arg->dCD_plane == cptr->drcc_plane && TTMaskHasType(&cptr->drcc_mask, TiGetType(tpleft))) continue; errRect.r_xtop = edgeX; arg->dCD_initial = tile; } else /* FORWARD */ { /* * Determine corner extensions. * Find the point (1) to the top left of pointT */ for (tp = tpleft; TOP(tp) <= errRect.r_ytop; tp = RT(tp)) /* Nothing */; if (TTMaskHasType(&cptr->drcc_corner, TiGetBottomType(tp))) { errRect.r_ytop += cptr->drcc_cdist; if (DRCEuclidean) arg->dCD_radial |= 0x8000; } if (cptr->drcc_flags & DRC_BOTHCORNERS) { /* * Check the other corner by finding the * point (2) to the bottom left of pointB. */ if (BOTTOM(tp = tpleft) >= errRect.r_ybot) for (tp = LB(tp); RIGHT(tp) < edgeX; tp = TR(tp)) /* Nothing */; if (TTMaskHasType(&cptr->drcc_corner, TiGetTopType(tp))) { errRect.r_ybot -= cptr->drcc_cdist; if (DRCEuclidean) arg->dCD_radial |= 0x4000; } } /* * Just for grins, see if we could avoid a messy search * by looking only at tile. */ errRect.r_xtop = edgeX + cptr->drcc_dist; if (RIGHT(tile) >= errRect.r_xtop && BOTTOM(tile) <= errRect.r_ybot && TOP(tile) >= errRect.r_ytop && arg->dCD_plane == cptr->drcc_plane && TTMaskHasType(&cptr->drcc_mask, TiGetLeftType(tile))) continue; errRect.r_xbot = edgeX; arg->dCD_initial= tpleft; } if (arg->dCD_radial) { arg->dCD_radial &= 0xf0000; arg->dCD_radial |= (0xfff & cptr->drcc_cdist); } DRCstatSlow++; arg->dCD_cptr = (DRCCookie *)cptr; TTMaskCom2(&tmpMask, &cptr->drcc_mask); (void) DBSrPaintArea((Tile *) NULL, CIFPlanes[cptr->drcc_plane], &errRect, &tmpMask, areaCifCheck, (ClientData) arg); } DRCstatEdges++; } } /* * Check design rules along a horizontal boundary between two tiles. * * 4 tile 3 * --L----------------R-- * 1 tpbot 2 * * The labels "L" and "R" indicate pointL and pointR respectively. * If a rule's direction is FORWARD, then check from bottom to top. * * * Check the top left corner if the 1x1 lambda square on the bottom * left corner (1) of pointL matches the design rule's "corner" mask. * * * Check the top right corner if the rule says check BOTHCORNERS and * the 1x1 lambda square on the bottom right (2) corner of pointR * matches the design rule's "corner" mask. * * If a rule's direction is REVERSE, then check from top to bottom. * * * Check the bottom right corner if the 1x1 lambda square on the top * right corner (3) of pointR matches the design rule's "corner" * mask. * * * Check the bottom left corner if the rule says check BOTHCORNERS * and the 1x1 lambda square on the top left corner (4) of pointL * matches the design rule's "corner" mask. */ if (BOTTOM(tile) >= rect->r_ybot) { Tile *tpbot; int edgeLeft, edgeRight; int left = MAX(LEFT(tile), rect->r_xbot); int right = MIN(RIGHT(tile), rect->r_xtop); int edgeY = BOTTOM(tile); /* Go right across bottom of tile */ for (tpbot = LB(tile); LEFT(tpbot) < right; tpbot = TR(tpbot)) { /* Don't check synthetic edges, i.e. edges with same type on * both sides. Such "edges" have no physical significance, and * depend on internal-details of how paint is spit into tiles. * Thus checking them just leads to confusion. (When edge rules * involving such edges are encountered during technology readin * the user is warned that such edges are not checked). */ if(TiGetTopType(tpbot) == TiGetBottomType(tile)) continue; /* * Check to insure that we are inside the clip area. * Go through list of design rules triggered by the * bottom-to-top edge. */ edgeLeft = MAX(LEFT(tpbot), left); edgeRight = MIN(RIGHT(tpbot), right); if (edgeLeft >= edgeRight) continue; cptr = drcCifCur; { DRCstatRules++; errRect.r_xbot = edgeLeft; errRect.r_xtop = edgeRight; /* top to bottom */ if (cptr->drcc_flags & DRC_REVERSE) { /* * Determine corner extensions. * Find the point (3) to the top right of pointR */ if (RIGHT(tp = tile) <= errRect.r_xtop) for (tp = TR(tp); BOTTOM(tp) > edgeY; tp = LB(tp)) /* Nothing */; if (TTMaskHasType(&cptr->drcc_corner, TiGetLeftType(tp))) { errRect.r_xtop += cptr->drcc_cdist; if (DRCEuclidean) arg->dCD_radial |= 0x4000; } if (cptr->drcc_flags & DRC_BOTHCORNERS) { /* * Check the other corner by finding the * point (4) to the top left of pointL. */ for (tp = tile; LEFT(tp) >= errRect.r_xbot; tp = BL(tp)) /* Nothing */; if (TTMaskHasType(&cptr->drcc_corner, TiGetRightType(tp))) { errRect.r_xbot -= cptr->drcc_cdist; if (DRCEuclidean) arg->dCD_radial |= 0x1000; } } /* * Just for grins, see if we could avoid * a messy search by looking only at tpbot. */ errRect.r_ybot = edgeY - cptr->drcc_dist; if (BOTTOM(tpbot) <= errRect.r_ybot && LEFT(tpbot) <= errRect.r_xbot && RIGHT(tpbot) >= errRect.r_xtop && arg->dCD_plane == cptr->drcc_plane && TTMaskHasType(&cptr->drcc_mask, TiGetTopType(tpbot))) continue; errRect.r_ytop = edgeY; arg->dCD_initial = tile; } else /* FORWARD */ { /* * Determine corner extensions. * Find the point (1) to the bottom left of pointL */ if (LEFT(tp = tpbot) >= errRect.r_xbot) for (tp = BL(tp); TOP(tp) < edgeY; tp = RT(tp)) /* Nothing */; if (TTMaskHasType(&cptr->drcc_corner, TiGetRightType(tp))) { errRect.r_xbot -= cptr->drcc_cdist; if (DRCEuclidean) arg->dCD_radial |= 0x2000; } if (cptr->drcc_flags & DRC_BOTHCORNERS) { /* * Check the other corner by finding the * point (2) to the bottom right of pointR. */ for (tp=tpbot; RIGHT(tp) <= errRect.r_xtop; tp=TR(tp)) /* Nothing */; if (TTMaskHasType(&cptr->drcc_corner, TiGetLeftType(tp))) { errRect.r_xtop += cptr->drcc_cdist; if (DRCEuclidean) arg->dCD_radial |= 0x8000; } } /* * Just for grins, see if we could avoid * a messy search by looking only at tile. */ errRect.r_ytop = edgeY + cptr->drcc_dist; if (TOP(tile) >= errRect.r_ytop && LEFT(tile) <= errRect.r_xbot && RIGHT(tile) >= errRect.r_xtop && arg->dCD_plane == cptr->drcc_plane && TTMaskHasType(&cptr->drcc_mask, TiGetType(tile))) continue; errRect.r_ybot = edgeY; arg->dCD_initial = tpbot; } if (arg->dCD_radial) { arg->dCD_radial &= 0xf000; arg->dCD_radial |= (0xfff & cptr->drcc_cdist); } DRCstatSlow++; arg->dCD_cptr = (DRCCookie *)cptr; TTMaskCom2(&tmpMask, &cptr->drcc_mask); (void) DBSrPaintArea((Tile *) NULL, CIFPlanes[cptr->drcc_plane], &errRect, &tmpMask, areaCifCheck, (ClientData) arg); } DRCstatEdges++; } } return (0); } /* * ---------------------------------------------------------------------------- * * areaCifCheck -- * * Call the function passed down from DRCBasicCheck() if the current tile * violates the rule in the given DRCCookie. If the rule's connectivity * flag is set, then make sure the violating material isn't connected * to what's on the initial side of the edge before calling the client * error function. * * This function is called from DBSrPaintArea(). * * Results: * Zero (so that the search will continue). * * Side effects: * Applies the function passed as an argument. * * ---------------------------------------------------------------------------- */ int areaCifCheck(tile, arg) Tile *tile; struct drcClientData *arg; { Rect rect; /* Area where error is to be recorded. */ int scale = drcCifStyle->cs_scaleFactor; /* If the tile has a legal type, then return. */ if (TTMaskHasType(&arg->dCD_cptr->drcc_mask, TiGetType(tile))) return 0; /* Only consider the portion of the suspicious tile that overlaps * the clip area for errors. */ TiToRect(tile, &rect); GeoClip(&rect, arg->dCD_constraint); if ((rect.r_xbot >= rect.r_xtop) || (rect.r_ybot >= rect.r_ytop)) return 0; rect.r_xbot /= scale; rect.r_xtop /= scale; if (rect.r_xbot == rect.r_xtop) { if (rect.r_xbot < 0) rect.r_xbot--; else rect.r_xtop++; } rect.r_ybot /= scale; rect.r_ytop /= scale; if (rect.r_ybot == rect.r_ytop) { if (rect.r_ybot < 0) rect.r_ybot--; else rect.r_ytop++; } GeoClip(&rect, arg->dCD_clip); if ((rect.r_xbot >= rect.r_xtop) || (rect.r_ybot >= rect.r_ytop)) return 0; (*(arg->dCD_function)) (arg->dCD_celldef, &rect, arg->dCD_cptr, arg->dCD_clientData); (*(arg->dCD_errors))++; return (0); } /* * ---------------------------------------------------------------------------- * * drcCifArea -- * * Process an area rule. * This is of the form: * * cifarea layers distance why * * e.g, * * cifarea VIA 4 "via area must be at least 4" * * Results: * Returns distance. * * Side effects: * Updates the DRC technology variables. * * ---------------------------------------------------------------------------- */ int drcCifArea(argc, argv) int argc; char *argv[]; { char *layers = argv[1]; int centiarea = atoi(argv[2]); int centihorizon = atoi(argv[3]); char *why = drcWhyDup(argv[4]); TileTypeBitMask set, setC, tmp1; DRCCookie *dpnext, *dpnew; TileType i, j; int plane; int thislayer; int scalefactor; if (drcCifStyle == NULL) return drcCifWarning(); for (i = 0; i < drcCifStyle->cs_nLayers;i++) { CIFLayer *layer = drcCifStyle->cs_layers[i]; if (strcmp(layer->cl_name,layers) == 0) { thislayer = i; break; } } if (thislayer == -1) { TechError("Unknown cif layer: %s\n",layers); return (0); } scalefactor = drcCifStyle->cs_scaleFactor; centiarea *= (drcCifStyle->cs_expander * drcCifStyle->cs_expander); dpnext = drcCifRules[thislayer][DRC_CIF_SPACE]; dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dpnew, centihorizon, dpnext, &CIFSolidBits, &CIFSolidBits, why, centiarea, DRC_AREA | DRC_FORWARD, thislayer, 0); drcCifRules[thislayer][DRC_CIF_SPACE] = dpnew; return ((centihorizon+scalefactor-1)/scalefactor); } /* * ---------------------------------------------------------------------------- * * drcCifMaxwidth -- cif version of drc list. * * Results: * Returns distance. * * Side effects: * Updates the DRC technology variables. * * ---------------------------------------------------------------------------- */ int drcCifMaxwidth(argc, argv) int argc; char *argv[]; { char *layers = argv[1]; int centidistance = atoi(argv[2]); char *bends = argv[3]; char *why = drcWhyDup(argv[4]); TileTypeBitMask set, setC, tmp1; DRCCookie *dpnext, *dpnew; TileType i, j; int plane; int bend; int thislayer; int scalefactor; if (drcCifStyle == NULL) return drcCifWarning(); for (i = 0; i < drcCifStyle->cs_nLayers;i++) { CIFLayer *layer = drcCifStyle->cs_layers[i]; if (strcmp(layer->cl_name,layers) == 0) { thislayer = i; break; } } if (thislayer == -1) { TechError("Unknown cif layer: %s\n",layers); return (0); } if (strcmp(bends,"bend_illegal") == 0) bend =0; else if (strcmp(bends,"bend_ok") == 0) bend =DRC_BENDS; else { TechError("unknown bend option %s\n",bends); return (0); } scalefactor = drcCifStyle->cs_scaleFactor; centidistance *= drcCifStyle->cs_expander; // BSI dpnext = drcCifRules[thislayer][DRC_CIF_SPACE]; dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie))); drcAssign(dpnew, centidistance, dpnext, &CIFSolidBits, &CIFSolidBits, why, centidistance, DRC_MAXWIDTH | bend, thislayer, 0); drcCifRules[thislayer][DRC_CIF_SPACE] = dpnew; return ((centidistance+scalefactor-1)/scalefactor); } /* *------------------------------------------------------------------------- * * drcCifCheckArea-- * * checks to see that a collection of cif tiles * have more than a minimum area. * * Results: * None * * Side Effects: * May cause errors to be painted. * *------------------------------------------------------------------------- */ void drcCheckCifArea(starttile, arg, cptr) Tile *starttile; struct drcClientData *arg; DRCCookie *cptr; { int arealimit = cptr->drcc_cdist; int area=0; TileTypeBitMask *oktypes = &cptr->drcc_mask; Tile *tile,*tp; Rect *cliprect = arg->dCD_rect; int scale = drcCifStyle->cs_scaleFactor; arg->dCD_cptr = (DRCCookie *)cptr; if (DRCstack == (Stack *) NULL) DRCstack = StackNew(64); /* Mark this tile as pending and push it */ PUSHTILE(starttile); while (!StackEmpty(DRCstack)) { tile = (Tile *) STACKPOP(DRCstack); if (tile->ti_client != (ClientData)DRC_PENDING) continue; area += (RIGHT(tile)-LEFT(tile))*(TOP(tile)-BOTTOM(tile)); tile->ti_client = (ClientData)DRC_PROCESSED; /* are we at the clip boundary? If so, skip to the end */ if (RIGHT(tile) == cliprect->r_xtop || LEFT(tile) == cliprect->r_xbot || BOTTOM(tile) == cliprect->r_ybot || TOP(tile) == cliprect->r_ytop) goto forgetit; if (area >= arealimit) goto forgetit; /* Top */ for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp)) if (TTMaskHasType(oktypes, TiGetType(tp))) PUSHTILE(tp); /* Left */ for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp)) if (TTMaskHasType(oktypes, TiGetType(tp))) PUSHTILE(tp); /* Bottom */ for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp)) if (TTMaskHasType(oktypes, TiGetType(tp))) PUSHTILE(tp); /* Right */ for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp)) if (TTMaskHasType(oktypes, TiGetType(tp))) PUSHTILE(tp); } if (area dCD_clip); if (!GEO_RECTNULL(&rect)) { (*(arg->dCD_function)) (arg->dCD_celldef, &rect, arg->dCD_cptr, arg->dCD_clientData); (*(arg->dCD_errors))++; } } forgetit: /* reset the tiles */ starttile->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(starttile, DRCstack); while (!StackEmpty(DRCstack)) { tile = (Tile *) STACKPOP(DRCstack); /* Top */ for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp)) if (tp->ti_client != (ClientData)DRC_UNPROCESSED) { tp->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(tp,DRCstack); } /* Left */ for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp)) if (tp->ti_client != (ClientData)DRC_UNPROCESSED) { tp->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(tp,DRCstack); } /* Bottom */ for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp)) if (tp->ti_client != (ClientData)DRC_UNPROCESSED) { tp->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(tp,DRCstack); } /* Right */ for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp)) if (tp->ti_client != (ClientData)DRC_UNPROCESSED) { tp->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(tp,DRCstack); } } } /* *------------------------------------------------------------------------- * * drcCheckCifMaxwidth -- * * Checks to see that at least one dimension of a region * does not exceed some amount. * * Results: * None. * * Side Effects: * May cause errors to be painted. * *------------------------------------------------------------------------- */ void drcCheckCifMaxwidth(starttile,arg,cptr) Tile *starttile; struct drcClientData *arg; DRCCookie *cptr; { int edgelimit = cptr->drcc_dist; Rect boundrect; TileTypeBitMask *oktypes = &cptr->drcc_mask; Tile *tile,*tp; int scale = drcCifStyle->cs_scaleFactor; arg->dCD_cptr = (DRCCookie *)cptr; if (DRCstack == (Stack *) NULL) DRCstack = StackNew(64); /* if bends are allowed, just check on a tile-by-tile basis that one dimension is the max. This is pretty stupid, but it correctly calculates the trench width rule. dcs 12.06.89 */ if (cptr->drcc_flags & DRC_BENDS) { Rect rect; TiToRect(starttile,&rect); if (rect.r_xtop-rect.r_xbot > edgelimit && rect.r_ytop-rect.r_ybot > edgelimit) { rect.r_xbot /= scale; rect.r_xtop /= scale; rect.r_ybot /= scale; rect.r_ytop /= scale; GeoClip(&rect, arg->dCD_clip); if (!GEO_RECTNULL(&rect)) { (*(arg->dCD_function)) (arg->dCD_celldef, &rect, arg->dCD_cptr, arg->dCD_clientData); (*(arg->dCD_errors))++; } } return; } /* Mark this tile as pending and push it */ PUSHTILE(starttile); TiToRect(starttile,&boundrect); while (!StackEmpty(DRCstack)) { tile = (Tile *) STACKPOP(DRCstack); if (tile->ti_client != (ClientData)DRC_PENDING) continue; if (boundrect.r_xbot > LEFT(tile)) boundrect.r_xbot = LEFT(tile); if (boundrect.r_xtop < RIGHT(tile)) boundrect.r_xtop = RIGHT(tile); if (boundrect.r_ybot > BOTTOM(tile)) boundrect.r_ybot = BOTTOM(tile); if (boundrect.r_ytop < TOP(tile)) boundrect.r_ytop = TOP(tile); tile->ti_client = (ClientData)DRC_PROCESSED; if (boundrect.r_xtop - boundrect.r_xbot > edgelimit && boundrect.r_ytop - boundrect.r_ybot > edgelimit) break; /* Top */ for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp)) if (TTMaskHasType(oktypes, TiGetType(tp))) PUSHTILE(tp); /* Left */ for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp)) if (TTMaskHasType(oktypes, TiGetType(tp))) PUSHTILE(tp); /* Bottom */ for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp)) if (TTMaskHasType(oktypes, TiGetType(tp))) PUSHTILE(tp); /* Right */ for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp)) if (TTMaskHasType(oktypes, TiGetType(tp))) PUSHTILE(tp); } if (boundrect.r_xtop - boundrect.r_xbot > edgelimit && boundrect.r_ytop - boundrect.r_ybot > edgelimit) { Rect rect; TiToRect(starttile,&rect); { rect.r_xbot /= scale; rect.r_xtop /= scale; rect.r_ybot /= scale; rect.r_ytop /= scale; GeoClip(&rect, arg->dCD_clip); if (!GEO_RECTNULL(&rect)) { (*(arg->dCD_function)) (arg->dCD_celldef, &rect, arg->dCD_cptr, arg->dCD_clientData); (*(arg->dCD_errors))++; } } } /* reset the tiles */ starttile->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(starttile, DRCstack); while (!StackEmpty(DRCstack)) { tile = (Tile *) STACKPOP(DRCstack); /* Top */ for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp)) if (tp->ti_client != (ClientData)DRC_UNPROCESSED) { tp->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(tp,DRCstack); } /* Left */ for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp)) if (tp->ti_client != (ClientData)DRC_UNPROCESSED) { tp->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(tp,DRCstack); } /* Bottom */ for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp)) if (tp->ti_client != (ClientData)DRC_UNPROCESSED) { tp->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(tp,DRCstack); } /* Right */ for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp)) if (tp->ti_client != (ClientData)DRC_UNPROCESSED) { tp->ti_client = (ClientData)DRC_UNPROCESSED; STACKPUSH(tp,DRCstack); } } } magic-8.0.210/drc/DRCbasic.c0000664000175000001440000007624112411555072014016 0ustar timusers/* * DRCbasic.c -- * * This file provides routines that make perform basic design-rule * checking: given an area of a cell definition, this file will * find all of the rule violations and call a client procedure for * each one. * * ********************************************************************* * * 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/drc/DRCbasic.c,v 1.7 2010/09/20 21:13:22 tim Exp $"; #endif /* not lint */ #include #include #include // for memcpy() #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "drc/drc.h" #include "utils/signals.h" #include "utils/maxrect.h" #include "utils/malloc.h" int dbDRCDebug = 0; /* The following DRC cookie is used when there are tiles of type * TT_ERROR_S found during the basic DRC. These arise during * hierarchical checking when there are illegal overlaps. */ static DRCCookie drcOverlapCookie = { 0, 0, 0, 0, { 0 }, { 0 }, 0, 0, 0, "Can't overlap those layers", (DRCCookie *) NULL }; /* Forward references: */ extern int areaCheck(); extern int drcTile(); extern MaxRectsData *drcCanonicalMaxwidth(); /* *----------------------------------------------------------------------- * * point_to_segment * * Euclidean-distance point-to-segment distance (squared) * calculation (borrowed from XCircuit) * * Results: * Squared Euclidean distance of the closest approach of the * line segment to the point (long result). * * Side Effects: * None. * *----------------------------------------------------------------------- */ long point_to_segment(px, py, s1x, s1y, s2x, s2y) int px, py; /* The position of the point */ int s1x, s1y; /* One endpoint of the line segment */ int s2x, s2y; /* The other endpoint of the line segment */ { long x, y; long a, b, c, frac; float protod; x = (long)s2x - (long)s1x; y = (long)s2y - (long)s1y; c = (x * x + y * y); x = (long)px - (long)s1x; y = (long)py - (long)s1y; a = (x * x + y * y); x = (long)px - (long)s2x; y = (long)py - (long)s2y; b = (x * x + y * y); frac = a - b; if (frac >= c) return b; else if (-frac >= c) return a; else { protod = (float)(c + a - b); return (a - (long)((protod * protod) / (float)(c << 2))); } } /* Define Euclidean distance checks */ #define RADIAL_NW 0x1000 #define RADIAL_NE 0x8000 #define RADIAL_SW 0x2000 #define RADIAL_SE 0x4000 /* * ---------------------------------------------------------------------------- * * areaCheck -- * * Call the function passed down from DRCBasicCheck() if the current tile * violates the rule in the given DRCCookie. If the rule's connectivity * flag is set, then make sure the violating material isn't connected * to what's on the initial side of the edge before calling the client * error function. * * This function is called from DBSrPaintArea(). * * Results: * Zero (so that the search will continue). * * Side effects: * Applies the function passed as an argument. * * ---------------------------------------------------------------------------- */ int areaCheck(tile, arg) Tile *tile; struct drcClientData *arg; { Rect rect; /* Area where error is to be recorded. */ TiToRect(tile, &rect); /* Only consider the portion of the suspicious tile that overlaps * the clip area for errors, unless this is a trigger rule. */ if (!(arg->dCD_cptr->drcc_flags & DRC_TRIGGER)) GeoClip(&rect, arg->dCD_clip); GeoClip(&rect, arg->dCD_constraint); if ((rect.r_xbot >= rect.r_xtop) || (rect.r_ybot >= rect.r_ytop)) return 0; /* * When Euclidean distance checks are enabled, check for error tiles * outside of the perimeter of the circle in the corner extension area * that extends "sdist" from the corner of the edge. * * Also check the relatively rare case where the tile is inside the * circle perimeter, but only the corner of the triangle projects into * the error check rectangle, and is outside of the circle. */ if (arg->dCD_radial != 0) { unsigned int i; int sqx, sqy; int sdist = arg->dCD_radial & 0xfff; long sstest, ssdist = sdist * sdist; if ((arg->dCD_radial & RADIAL_NW) != 0) { if (((sqx = arg->dCD_constraint->r_xbot + sdist - rect.r_xtop) >= 0) && ((sqy = rect.r_ybot - arg->dCD_constraint->r_ytop + sdist) >= 0) && ((sqx * sqx + sqy * sqy) >= ssdist)) return 0; else if (IsSplit(tile) && !SplitDirection(tile) && !SplitSide(tile)) { sstest = point_to_segment(arg->dCD_constraint->r_xbot + sdist, arg->dCD_constraint->r_ytop - sdist, LEFT(tile), BOTTOM(tile), RIGHT(tile), TOP(tile)); if (sstest > ssdist) return 0; } } if ((arg->dCD_radial & RADIAL_NE) != 0) { if (((sqx = rect.r_xbot - arg->dCD_constraint->r_xtop + sdist) >= 0) && ((sqy = rect.r_ybot - arg->dCD_constraint->r_ytop + sdist) >= 0) && ((sqx * sqx + sqy * sqy) >= ssdist)) return 0; else if (IsSplit(tile) && SplitDirection(tile) && SplitSide(tile)) { sstest = point_to_segment(arg->dCD_constraint->r_xtop - sdist, arg->dCD_constraint->r_ytop - sdist, LEFT(tile), TOP(tile), RIGHT(tile), BOTTOM(tile)); if (sstest > ssdist) return 0; } } if ((arg->dCD_radial & RADIAL_SW) != 0) { if (((sqx = arg->dCD_constraint->r_xbot + sdist - rect.r_xtop) >= 0) && ((sqy = arg->dCD_constraint->r_ybot + sdist - rect.r_ytop) >= 0) && ((sqx * sqx + sqy * sqy) >= ssdist)) return 0; else if (IsSplit(tile) && SplitDirection(tile) && !SplitSide(tile)) { sstest = point_to_segment(arg->dCD_constraint->r_xbot + sdist, arg->dCD_constraint->r_ybot + sdist, LEFT(tile), TOP(tile), RIGHT(tile), BOTTOM(tile)); if (sstest > ssdist) return 0; } } if ((arg->dCD_radial & RADIAL_SE) != 0) { if (((sqx = rect.r_xbot - arg->dCD_constraint->r_xtop + sdist) >= 0) && ((sqy = arg->dCD_constraint->r_ybot + sdist - rect.r_ytop) >= 0) && ((sqx * sqx + sqy * sqy) >= ssdist)) return 0; else if (IsSplit(tile) && !SplitDirection(tile) && SplitSide(tile)) { sstest = point_to_segment(arg->dCD_constraint->r_xtop - sdist, arg->dCD_constraint->r_ybot + sdist, LEFT(tile), BOTTOM(tile), RIGHT(tile), TOP(tile)); if (sstest > ssdist) return 0; } } } if (arg->dCD_cptr->drcc_flags & DRC_TRIGGER) { Rect *newrlist; int entries = arg->dCD_entries; /* The following code allows the rect list to be expanded by */ /* multiples of 8, when necessary. */ arg->dCD_entries++; if (arg->dCD_rlist == NULL) arg->dCD_rlist = (Rect *)mallocMagic(8 * sizeof(Rect)); else if ((arg->dCD_entries & ~(entries | 7)) == arg->dCD_entries) { newrlist = (Rect *)mallocMagic((arg->dCD_entries << 1) * sizeof(Rect)); memcpy((void *)newrlist, (void *)arg->dCD_rlist, (size_t)entries * sizeof(Rect)); freeMagic(arg->dCD_rlist); arg->dCD_rlist = newrlist; } arg->dCD_rlist[arg->dCD_entries - 1] = rect; } else { (*(arg->dCD_function))(arg->dCD_celldef, &rect, arg->dCD_cptr, arg->dCD_clientData); (*(arg->dCD_errors))++; } return 0; } /* * ---------------------------------------------------------------------------- * * DRCBasicCheck -- * * This is the top-level routine for basic design-rule checking. * * Results: * Number of errors found. * * Side effects: * Calls function for each design-rule violation in celldef * that is triggered by an edge in rect and whose violation * area falls withing clipRect. This routine makes a flat check: * it considers only information in the paint planes of celldef, * and does not expand children. Function should have the form: * void * function(def, area, rule, cdarg) * CellDef *def; * Rect *area; * DRCCookie *rule; * ClientData cdarg; * { * } * * In the call to function, def is the definition containing the * basic area being checked, area is the actual area where a * rule is violated, rule is the rule being violated, and cdarg * is the client data passed through all of our routines. * * Note: * If an interrupt occurs (SigInterruptPending gets set), then * the basic will be aborted immediately. This means the check * may be incomplete. * * ---------------------------------------------------------------------------- */ int DRCBasicCheck (celldef, checkRect, clipRect, function, cdata) CellDef *celldef; /* CellDef being checked */ Rect *checkRect; /* Check rules in this area -- usually two Haloes * larger than the area where changes were made. */ Rect *clipRect; /* Clip error tiles against this area. */ void (*function)(); /* Function to apply for each error found. */ ClientData cdata; /* Passed to function as argument. */ { struct drcClientData arg; int errors; int planeNum; if (DRCCurStyle == NULL) return 0; /* No DRC, no errors */ /* Insist on top quality rectangles. */ if ((checkRect->r_xbot >= checkRect->r_xtop) || (checkRect->r_ybot >= checkRect->r_ytop)) return (0); errors = 0; arg.dCD_celldef = celldef; arg.dCD_rect = checkRect; arg.dCD_errors = &errors; arg.dCD_function = function; arg.dCD_clip = clipRect; arg.dCD_clientData = cdata; arg.dCD_rlist = NULL; arg.dCD_entries = 0; for (planeNum = PL_TECHDEPBASE; planeNum < DBNumPlanes; planeNum++) { arg.dCD_plane = planeNum; DBResetTilePlane(celldef->cd_planes[planeNum], DRC_UNPROCESSED); (void) DBSrPaintArea ((Tile *) NULL, celldef->cd_planes[planeNum], checkRect, &DBAllTypeBits, drcTile, (ClientData) &arg); } drcCifCheck(&arg); if (arg.dCD_rlist != NULL) freeMagic(arg.dCD_rlist); return (errors); } /* * ---------------------------------------------------------------------------- * * drcTile -- * * This is a search function invoked once for each tile in * the area to be checked. It checks design rules along the left * and bottom of the given tile. If the tile extends beyond the * clipping rectangle in any direction, then the boundary on that * side of the tile will be skipped. * * Results: * Zero (so that the search will continue), unless an interrupt * occurs, in which case 1 is returned to stop the check. * * Side effects: * Calls the client's error function if errors are found. * * ---------------------------------------------------------------------------- */ int drcTile (tile, arg) Tile *tile; /* Tile being examined */ struct drcClientData *arg; { DRCCookie *cptr; /* Current design rule on list */ Rect *rect = arg->dCD_rect; /* Area being checked */ Rect errRect; /* Area checked for an individual rule */ MaxRectsData *mrd; /* Used by widespacing rule */ TileTypeBitMask tmpMask, *rMask; bool trigpending; /* Hack for widespacing rule */ bool firsttile; int triggered; int cdist, dist, ccdist, result; arg->dCD_constraint = &errRect; /* * If we were interrupted, we want to * abort the check as quickly as possible. */ if (SigInterruptPending) return 1; DRCstatTiles++; /* If this tile is an error tile, it arose because of an illegal * overlap between things in adjacent cells. This means that * there's an automatic violation over the area of the tile. */ if (TiGetType(tile) == TT_ERROR_S) { TiToRect(tile, &errRect); GeoClip(&errRect, rect); (*(arg->dCD_function)) (arg->dCD_celldef, &errRect, &drcOverlapCookie, arg->dCD_clientData); (*(arg->dCD_errors))++; } if (IsSplit(tile)) { /* Check rules for DRC_ANGLES rule and process */ TileType tt = TiGetLeftType(tile); if (tt != TT_SPACE) { for (cptr = DRCCurStyle->DRCRulesTbl[TT_SPACE][tt]; cptr != (DRCCookie *) NULL; cptr = cptr->drcc_next) if (cptr->drcc_flags & DRC_ANGLES) { drcCheckAngles(tile, arg, cptr); break; } } tt = TiGetRightType(tile); if (tt != TT_SPACE) { for (cptr = DRCCurStyle->DRCRulesTbl[TT_SPACE][tt]; cptr != (DRCCookie *) NULL; cptr = cptr->drcc_next) if (cptr->drcc_flags & DRC_ANGLES) { drcCheckAngles(tile, arg, cptr); break; } } /* This drc is only for the left edge of the tile */ if (SplitSide(tile)) goto checkbottom; } /* * Check design rules along a vertical boundary between two tiles. * * 1 | 4 * T * | * tpleft | tile * | * B * 2 | 3 * * The labels "T" and "B" indicate pointT and pointB respectively. * * If a rule's direction is FORWARD, then check from left to right. * * * Check the top right corner if the 1x1 lambda square * on the top left corner (1) of pointT matches the design * rule's "corner" mask. * * * Check the bottom right corner if the rule says check * BOTHCORNERS and the 1x1 lambda square on the bottom left * corner (2) of pointB matches the design rule's "corner" mask. * * If a rule's direction is REVERSE, then check from right to left. * * * Check the bottom left corner if the 1x1 lambda square * on the bottom right corner (3) of pointB matches the design * rule's "corner" mask. * * * Check the top left corner if the rule says check BOTHCORNERS * and the 1x1 lambda square on the top right corner (4) of * pointT matches the design rule's "corner" mask. */ if (LEFT(tile) >= rect->r_xbot) /* check tile against rect */ { Tile *tpleft, *tpl, *tpr; TileType tt, to; int edgeTop, edgeBot; int top = MIN(TOP(tile), rect->r_ytop); int bottom = MAX(BOTTOM(tile), rect->r_ybot); int edgeX = LEFT(tile); firsttile = TRUE; for (tpleft = BL(tile); BOTTOM(tpleft) < top; tpleft = RT(tpleft)) { /* Get the tile types to the left and right of the edge */ tt = TiGetLeftType(tile); to = TiGetRightType(tpleft); /* Don't check synthetic edges, i.e. edges with same type on * both sides. Such "edges" have no physical significance, and * depend on internal-details of how paint is spit into tiles. * Thus checking them just leads to confusion. (When edge rules * involving such edges are encountered during technology read-in * the user is warned that such edges are not checked). */ if (tt == to) continue; /* * Go through list of design rules triggered by the * left-to-right edge. */ edgeTop = MIN(TOP (tpleft), top); edgeBot = MAX(BOTTOM(tpleft), bottom); if (edgeTop <= edgeBot) continue; triggered = 0; for (cptr = DRCCurStyle->DRCRulesTbl[to][tt]; cptr != (DRCCookie *) NULL; cptr = cptr->drcc_next) { if (cptr->drcc_flags & DRC_ANGLES) continue; /* Find the rule distances according to the scale factor */ dist = cptr->drcc_dist; cdist = cptr->drcc_cdist; trigpending = (cptr->drcc_flags & DRC_TRIGGER) ? TRUE : FALSE; /* drcc_edgeplane is used to avoid checks on edges */ /* in more than one plane */ if (arg->dCD_plane != cptr->drcc_edgeplane) { if (trigpending) cptr = cptr->drcc_next; continue; } DRCstatRules++; if (cptr->drcc_flags & DRC_AREA) { if (firsttile) drcCheckArea(tile, arg, cptr); continue; } if ((cptr->drcc_flags & (DRC_MAXWIDTH | DRC_BENDS)) == (DRC_MAXWIDTH | DRC_BENDS)) { /* New algorithm --- Tim 3/6/05 */ Rect *lr; int i; if (!trigpending) cptr->drcc_dist++; if (cptr->drcc_flags & DRC_REVERSE) mrd = drcCanonicalMaxwidth(tpleft, GEO_WEST, arg, cptr); else if (firsttile) mrd = drcCanonicalMaxwidth(tile, GEO_EAST, arg, cptr); else mrd = NULL; if (!trigpending) cptr->drcc_dist--; if (trigpending) { if (mrd) triggered = mrd->entries; else cptr = cptr->drcc_next; } else if (mrd) { for (i = 0; i < mrd->entries; i++) { lr = &mrd->rlist[i]; GeoClip(lr, arg->dCD_clip); if (!GEO_RECTNULL(lr)) { (*(arg->dCD_function)) (arg->dCD_celldef, lr, cptr, arg->dCD_clientData); (*(arg->dCD_errors))++; } } } continue; } else if (cptr->drcc_flags & DRC_MAXWIDTH) { /* bends_illegal option only */ if (firsttile) drcCheckMaxwidth(tile, arg, cptr); continue; } else if (!triggered) mrd = NULL; if (cptr->drcc_flags & DRC_RECTSIZE) { /* only checked for bottom-left tile in a rect area */ if (firsttile && !TTMaskHasType(&cptr->drcc_mask, TiGetRightType(BL(tile))) && !TTMaskHasType(&cptr->drcc_mask, TiGetTopType(LB(tile)))) drcCheckRectSize(tile, arg, cptr); continue; } result = 0; arg->dCD_radial = 0; do { if (triggered) { /* For triggered rules, we want to look at the */ /* clipped region found by the triggering rule */ if (mrd) errRect = mrd->rlist[--triggered]; else errRect = arg->dCD_rlist[--triggered]; errRect.r_ytop += cdist; errRect.r_ybot -= cdist; if (errRect.r_ytop > edgeTop) errRect.r_ytop = edgeTop; if (errRect.r_ybot < edgeBot) errRect.r_ybot = edgeBot; } else { errRect.r_ytop = edgeTop; errRect.r_ybot = edgeBot; } if (cptr->drcc_flags & DRC_REVERSE) { /* * Determine corner extensions. */ /* Find the point (3) to the bottom right of pointB */ if (BOTTOM(tile) >= errRect.r_ybot) tpr = LB(tile); else tpr = tile; /* Also find point (2) to check for edge continuation */ if (BOTTOM(tpleft) >= errRect.r_ybot) for (tpl = LB(tpleft); RIGHT(tpl) < edgeX; tpl = TR(tpl)); else tpl = tpleft; /* Make sure the edge stops at edgeBot */ if ((TiGetTopType(tpl) != TiGetBottomType(tpleft)) || (TiGetTopType(tpr) != TiGetBottomType(tile))) { if (TTMaskHasType(&cptr->drcc_corner, TiGetTopType(tpr))) { errRect.r_ybot -= cdist; if (DRCEuclidean) arg->dCD_radial |= RADIAL_SW; } } if (cptr->drcc_flags & DRC_BOTHCORNERS) { /* * Check the other corner */ /* Find point (4) to the top right of pointT */ if (TOP(tile) <= errRect.r_ytop) for (tpr = RT(tile); LEFT(tpr) > edgeX; tpr = BL(tpr)); else tpr = tile; /* Also find point (1) to check for edge continuation */ if (TOP(tpleft) <= errRect.r_ytop) tpl = RT(tpleft); else tpl = tpleft; /* Make sure the edge stops at edgeTop */ if ((TiGetBottomType(tpl) != TiGetTopType(tpleft)) || (TiGetBottomType(tpr) != TiGetTopType(tile))) { if (TTMaskHasType(&cptr->drcc_corner, TiGetBottomType(tpr))) { errRect.r_ytop += cdist; if (DRCEuclidean) arg->dCD_radial |= RADIAL_NW; } } } /* * Just for grins, see if we could avoid a messy search * by looking only at tpleft. */ errRect.r_xbot = edgeX - dist; if (cptr->drcc_flags & DRC_OUTSIDE) errRect.r_xbot--; if (LEFT(tpleft) <= errRect.r_xbot && BOTTOM(tpleft) <= errRect.r_ybot && TOP(tpleft) >= errRect.r_ytop && arg->dCD_plane == cptr->drcc_plane && TTMaskHasType(&cptr->drcc_mask, TiGetRightType(tpleft))) continue; errRect.r_xtop = edgeX; if (cptr->drcc_flags & DRC_OUTSIDE) errRect.r_xtop -= dist; arg->dCD_initial = tile; } else /* FORWARD */ { /* * Determine corner extensions. */ /* Find the point (1) to the top left of pointT */ if (TOP(tpleft) <= errRect.r_ytop) tpl = RT(tpleft); else tpl = tpleft; /* Also find point (4) to check for edge continuation */ if (TOP(tile) <= errRect.r_ytop) for (tpr = RT(tile); LEFT(tpr) > edgeX; tpr = BL(tpr)); else tpr = tile; /* Make sure the edge stops at edgeTop */ if ((TiGetBottomType(tpl) != TiGetTopType(tpleft)) || (TiGetBottomType(tpr) != TiGetTopType(tile))) { if (TTMaskHasType(&cptr->drcc_corner, TiGetBottomType(tpl))) { errRect.r_ytop += cdist; if (DRCEuclidean) arg->dCD_radial |= RADIAL_NE; } } if (cptr->drcc_flags & DRC_BOTHCORNERS) { /* * Check the other corner */ /* Find point (2) to the bottom left of pointB. */ if (BOTTOM(tpleft) >= errRect.r_ybot) for (tpl = LB(tpleft); RIGHT(tpl) < edgeX; tpl = TR(tpl)); else tpl = tpleft; /* Also find point (3) to check for edge continuation */ if (BOTTOM(tile) >= errRect.r_ybot) tpr = LB(tile); else tpr = tile; /* Make sure the edge stops at edgeBot */ if ((TiGetTopType(tpl) != TiGetBottomType(tpleft)) || (TiGetTopType(tpr) != TiGetBottomType(tile))) { if (TTMaskHasType(&cptr->drcc_corner, TiGetTopType(tpl))) { errRect.r_ybot -= cdist; if (DRCEuclidean) arg->dCD_radial |= RADIAL_SE; } } } /* * Just for grins, see if we could avoid a messy search * by looking only at tile. */ errRect.r_xtop = edgeX + dist; if (cptr->drcc_flags & DRC_OUTSIDE) errRect.r_xtop++; if (RIGHT(tile) >= errRect.r_xtop && BOTTOM(tile) <= errRect.r_ybot && TOP(tile) >= errRect.r_ytop && arg->dCD_plane == cptr->drcc_plane && TTMaskHasType(&cptr->drcc_mask, TiGetLeftType(tile))) continue; errRect.r_xbot = edgeX; if (cptr->drcc_flags & DRC_OUTSIDE) errRect.r_xbot += dist; arg->dCD_initial= tpleft; } if (arg->dCD_radial) { arg->dCD_radial &= 0xf000; arg->dCD_radial |= (0xfff & cdist); } DRCstatSlow++; arg->dCD_cptr = cptr; arg->dCD_entries = 0; TTMaskCom2(&tmpMask, &cptr->drcc_mask); TTMaskClearType(&tmpMask, TT_ERROR_S); DBSrPaintArea((Tile *) NULL, arg->dCD_celldef->cd_planes[cptr->drcc_plane], &errRect, &tmpMask, areaCheck, (ClientData) arg); } while (triggered); if (arg->dCD_entries == 0) { /* Trigger rule: If rule check found errors, */ /* do the next rule. Otherwise, skip it. */ if (trigpending) cptr = cptr->drcc_next; } else triggered = arg->dCD_entries; } DRCstatEdges++; firsttile = FALSE; } } /* This drc is only for the bottom edge of the tile */ checkbottom: if (IsSplit(tile)) if (SplitSide(tile) == SplitDirection(tile)) return 0; /* * Check design rules along a horizontal boundary between two tiles. * * 4 tile 3 * --L----------------R-- * 1 tpbot 2 * * The labels "L" and "R" indicate pointL and pointR respectively. * If a rule's direction is FORWARD, then check from bottom to top. * * * Check the top left corner if the 1x1 lambda square on the bottom * left corner (1) of pointL matches the design rule's "corner" mask. * * * Check the top right corner if the rule says check BOTHCORNERS and * the 1x1 lambda square on the bottom right (2) corner of pointR * matches the design rule's "corner" mask. * * If a rule's direction is REVERSE, then check from top to bottom. * * * Check the bottom right corner if the 1x1 lambda square on the top * right corner (3) of pointR matches the design rule's "corner" * mask. * * * Check the bottom left corner if the rule says check BOTHCORNERS * and the 1x1 lambda square on the top left corner (4) of pointL * matches the design rule's "corner" mask. */ if (BOTTOM(tile) >= rect->r_ybot) { Tile *tpbot, *tpx; TileType tt, to; int edgeLeft, edgeRight; int left = MAX(LEFT(tile), rect->r_xbot); int right = MIN(RIGHT(tile), rect->r_xtop); int edgeY = BOTTOM(tile); /* Go right across bottom of tile */ firsttile = TRUE; for (tpbot = LB(tile); LEFT(tpbot) < right; tpbot = TR(tpbot)) { /* Get the tile types to the top and bottom of the edge */ tt = TiGetBottomType(tile); to = TiGetTopType(tpbot); /* Don't check synthetic edges, i.e. edges with same type on * both sides. Such "edges" have no physical significance, and * depend on internal-details of how paint is spit into tiles. * Thus checking them just leads to confusion. (When edge rules * involving such edges are encountered during technology readin * the user is warned that such edges are not checked). */ if (tt == to) continue; /* * Check to insure that we are inside the clip area. * Go through list of design rules triggered by the * bottom-to-top edge. */ edgeLeft = MAX(LEFT(tpbot), left); edgeRight = MIN(RIGHT(tpbot), right); if (edgeLeft >= edgeRight) continue; triggered = 0; for (cptr = DRCCurStyle->DRCRulesTbl[to][tt]; cptr != (DRCCookie *) NULL; cptr = cptr->drcc_next) { if (cptr->drcc_flags & DRC_ANGLES) continue; /* Find the rule distances according to the scale factor */ dist = cptr->drcc_dist; cdist = cptr->drcc_cdist; trigpending = (cptr->drcc_flags & DRC_TRIGGER) ? TRUE : FALSE; /* drcc_edgeplane is used to avoid checks on edges */ /* in more than one plane */ if (arg->dCD_plane != cptr->drcc_edgeplane) { if (trigpending) cptr = cptr->drcc_next; continue; } DRCstatRules++; /* top to bottom */ if ((cptr->drcc_flags & (DRC_MAXWIDTH | DRC_BENDS)) == (DRC_MAXWIDTH | DRC_BENDS)) { /* New algorithm --- Tim 3/6/05 */ Rect *lr; int i; if (!trigpending) cptr->drcc_dist++; if (cptr->drcc_flags & DRC_REVERSE) mrd = drcCanonicalMaxwidth(tpbot, GEO_SOUTH, arg, cptr); else if (firsttile) mrd = drcCanonicalMaxwidth(tile, GEO_NORTH, arg, cptr); else mrd = NULL; if (!trigpending) cptr->drcc_dist--; if (trigpending) { if (mrd) triggered = mrd->entries; else cptr = cptr->drcc_next; } else if (mrd) { for (i = 0; i < mrd->entries; i++) { lr = &mrd->rlist[i]; GeoClip(lr, arg->dCD_clip); if (!GEO_RECTNULL(lr)) { (*(arg->dCD_function)) (arg->dCD_celldef, lr, cptr, arg->dCD_clientData); (*(arg->dCD_errors))++; } } } continue; } else if (cptr->drcc_flags & (DRC_AREA | DRC_RECTSIZE | DRC_MAXWIDTH)) { /* only have to do these checks in one direction */ if (trigpending) cptr = cptr->drcc_next; continue; } else if (!triggered) mrd = NULL; result = 0; arg->dCD_radial = 0; do { if (triggered) { /* For triggered rules, we want to look at the */ /* clipped region found by the triggering rule */ if (mrd) errRect = mrd->rlist[--triggered]; else errRect = arg->dCD_rlist[--triggered]; errRect.r_xtop += cdist; errRect.r_xbot -= cdist; if (errRect.r_xtop > edgeRight) errRect.r_xtop = edgeRight; if (errRect.r_xbot < edgeLeft) errRect.r_xbot = edgeLeft; } else { errRect.r_xbot = edgeLeft; errRect.r_xtop = edgeRight; } if (cptr->drcc_flags & DRC_REVERSE) { /* * Determine corner extensions. * Find the point (3) to the top right of pointR */ if (RIGHT(tile) <= errRect.r_xtop) for (tpx = TR(tile); BOTTOM(tpx) > edgeY; tpx = LB(tpx)); else tpx = tile; if (TTMaskHasType(&cptr->drcc_corner, TiGetLeftType(tpx))) { errRect.r_xtop += cdist; if (DRCEuclidean) arg->dCD_radial |= RADIAL_SE; } if (cptr->drcc_flags & DRC_BOTHCORNERS) { /* * Check the other corner by finding the * point (4) to the top left of pointL. */ if (LEFT(tile) >= errRect.r_xbot) tpx = BL(tile); else tpx = tile; if (TTMaskHasType(&cptr->drcc_corner, TiGetRightType(tpx))) { errRect.r_xbot -= cdist; if (DRCEuclidean) arg->dCD_radial |= RADIAL_SW; } } /* * Just for grins, see if we could avoid * a messy search by looking only at tpbot. */ errRect.r_ybot = edgeY - dist; if (cptr->drcc_flags & DRC_OUTSIDE) errRect.r_ybot--; if (BOTTOM(tpbot) <= errRect.r_ybot && LEFT(tpbot) <= errRect.r_xbot && RIGHT(tpbot) >= errRect.r_xtop && arg->dCD_plane == cptr->drcc_plane && TTMaskHasType(&cptr->drcc_mask, TiGetTopType(tpbot))) continue; errRect.r_ytop = edgeY; if (cptr->drcc_flags & DRC_OUTSIDE) errRect.r_ytop -= dist; arg->dCD_initial = tile; } else /* FORWARD */ { /* * Determine corner extensions. * Find the point (1) to the bottom left of pointL */ if (LEFT(tpbot) >= errRect.r_xbot) for (tpx = BL(tpbot); TOP(tpx) < edgeY; tpx = RT(tpx)); else tpx = tpbot; if (TTMaskHasType(&cptr->drcc_corner, TiGetRightType(tpx))) { errRect.r_xbot -= cdist; if (DRCEuclidean) arg->dCD_radial |= RADIAL_NW; } if (cptr->drcc_flags & DRC_BOTHCORNERS) { /* * Check the other corner by finding the * point (2) to the bottom right of pointR. */ if (RIGHT(tpbot) <= errRect.r_xtop) tpx = TR(tpbot); else tpx = tpbot; if (TTMaskHasType(&cptr->drcc_corner, TiGetLeftType(tpx))) { errRect.r_xtop += cdist; if (DRCEuclidean) arg->dCD_radial |= RADIAL_NE; } } /* * Just for grins, see if we could avoid * a messy search by looking only at tile. */ errRect.r_ytop = edgeY + dist; if (cptr->drcc_flags & DRC_OUTSIDE) errRect.r_ytop++; if (TOP(tile) >= errRect.r_ytop && LEFT(tile) <= errRect.r_xbot && RIGHT(tile) >= errRect.r_xtop && arg->dCD_plane == cptr->drcc_plane && TTMaskHasType(&cptr->drcc_mask, TiGetBottomType(tile))) continue; errRect.r_ybot = edgeY; if (cptr->drcc_flags & DRC_OUTSIDE) errRect.r_ybot += dist; arg->dCD_initial = tpbot; } if (arg->dCD_radial) { arg->dCD_radial &= 0xf000; arg->dCD_radial |= (0xfff & cdist); } DRCstatSlow++; arg->dCD_cptr = cptr; arg->dCD_entries = 0; TTMaskCom2(&tmpMask, &cptr->drcc_mask); TTMaskClearType(&tmpMask, TT_ERROR_S); DBSrPaintArea((Tile *) NULL, arg->dCD_celldef->cd_planes[cptr->drcc_plane], &errRect, &tmpMask, areaCheck, (ClientData) arg); } while (triggered); if (arg->dCD_entries == 0) { /* Trigger rule: If rule check found errors, */ /* do the next rule. Otherwise, skip it. */ if (trigpending) cptr = cptr->drcc_next; } else triggered = arg->dCD_entries; } DRCstatEdges++; firsttile = FALSE; } } return (0); } magic-8.0.210/drc/DRCmain.c0000664000175000001440000006243312503062345013655 0ustar timusers/* * DRCmain.c -- * * This file provides global routines that are invoked at * command-level. They do things like give information about * errors and print statistics. * * ********************************************************************* * * 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/drc/DRCmain.c,v 1.4 2010/06/24 12:37:16 tim Exp $"; #endif /* not lint */ #include #include #include "tcltk/tclmagic.h" #include "utils/magic.h" #include "utils/malloc.h" #include "textio/textio.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 "drc/drc.h" #include "utils/undo.h" /* The global variables defined below are parameters between * the DRC error routines (drcPaintError and drcPrintError) * and the higher-level routines that start up DRC error checks. * It seemed simpler to do the communication this way rather * than creating a special new record that is passed down as * ClientData. Any routine invoking DRCBasicCheck with drcPaintError * or drcPrintError as action routine should fill in the relevant * variables. */ /* The following points to a list of all the DRC styles currently * understood: */ DRCKeep *DRCStyleList = NULL; DRCStyle *DRCCurStyle = NULL; /* Used by both routines: */ int DRCErrorCount; /* Incremented by each call to either routine. */ /* Used by drcPaintError: */ CellDef *DRCErrorDef; /* Place to paint error tiles. */ TileType DRCErrorType; /* Type of error tile to paint. */ /* Used by drcPrintError: */ HashTable DRCErrorTable; /* Hash table used to eliminate duplicate * error strings. */ /* Global variables used by all DRC modules to record statistics. * For each statistic we keep two values, the count since stats * were last printed (in DRCstatXXX), and the total count (in * drcTotalXXX). */ int DRCstatSquares = 0; /* Number of DRCStepSize-by-DRCStepSize * squares processed by continuous checker. */ int DRCstatTiles = 0; /* Number of tiles processed by basic * checker. */ int DRCstatEdges = 0; /* Number of "atomic" edges processed * by basic checker. */ int DRCstatRules = 0; /* Number of rules processed by basic checker * (rule = one constraint for one edge). */ int DRCstatSlow = 0; /* Number of places where constraint doesn't * all fall in a single tile. */ int DRCstatInteractions = 0; /* Number of times drcInt is called to check * an interaction area. */ int DRCstatIntTiles = 0; /* Number of tiles processed as part of * subcell interaction checks. */ int DRCstatCifTiles = 0; /* Number of tiles processed as part of * cif checks. */ int DRCstatArrayTiles = 0; /* Number of tiles processed as part of * array interaction checks. */ #ifdef DRCRULESHISTO int DRCstatVRulesHisto[DRC_MAXRULESHISTO]; int DRCstatHRulesHisto[DRC_MAXRULESHISTO]; #endif /* DRCRULESHISTO */ static int drcTotalSquares = 0; static int drcTotalTiles = 0; static int drcTotalEdges = 0; static int drcTotalRules = 0; static int drcTotalSlow = 0; static int drcTotalInteractions = 0; static int drcTotalIntTiles = 0; static int drcTotalArrayTiles = 0; #ifdef DRCRULESHISTO static int drcTotalVRulesHisto[DRC_MAXRULESHISTO]; static int drcTotalHRulesHisto[DRC_MAXRULESHISTO]; #endif /* DRCRULESHISTO */ /* * ---------------------------------------------------------------------------- * drcPaintError -- * * Action function that paints error tiles for each violation found. * * Results: * None. * * Side effects: * A tile of type DRCErrorType is painted over the area of * the error, in the plane given by "plane". Also, DRCErrorCount * is incremented. * ---------------------------------------------------------------------------- */ void drcPaintError(celldef, rect, cptr, plane) CellDef * celldef; /* CellDef being checked */ Rect * rect; /* Area of error */ DRCCookie * cptr; /* Design rule violated -- not used */ Plane * plane; /* Where to paint error tiles. */ { PaintUndoInfo ui; ui.pu_def = celldef; ui.pu_pNum = PL_DRC_ERROR; DBPaintPlane(plane, rect, DBStdPaintTbl(DRCErrorType, PL_DRC_ERROR), &ui); DRCErrorCount += 1; } /* * ---------------------------------------------------------------------------- * drcPrintError -- * * Action function that prints the error message associated with each * violation found. * * Results: * None. * * Side effects: * DRCErrorCount is incremented. The text associated with * the error is entered into DRCErrorTable, and, if this is * the first time that entry has been seen, then the error * text is printed. If the area parameter is non-NULL, then * only errors intersecting that area are considered. * ---------------------------------------------------------------------------- */ void drcPrintError (celldef, rect, cptr, scx) CellDef * celldef; /* CellDef being checked -- not used here */ Rect * rect; /* Area of error */ DRCCookie * cptr; /* Design rule violated */ SearchContext * scx; /* Only errors in scx->scx_area get reported. */ { HashEntry *h; int i; Rect *area; ASSERT (cptr != (DRCCookie *) NULL, "drcPrintError"); area = &scx->scx_area; if ((area != NULL) && (!GEO_OVERLAP(area, rect))) return; DRCErrorCount += 1; h = HashFind(&DRCErrorTable, cptr->drcc_why); i = (spointertype) HashGetValue(h); if (i == 0) TxPrintf("%s\n", cptr->drcc_why); i += 1; HashSetValue(h, (spointertype)i); } /* Same routine as above, but output goes to a Tcl list and is appended */ /* to the interpreter result. */ #ifdef MAGIC_WRAPPER void drcListError (celldef, rect, cptr, scx) CellDef * celldef; /* CellDef being checked -- not used here */ Rect * rect; /* Area of error */ DRCCookie * cptr; /* Design rule violated */ SearchContext * scx; /* Only errors in scx->scx_area get reported */ { HashEntry *h; int i; Rect *area; ASSERT (cptr != (DRCCookie *) NULL, "drcListError"); area = &scx->scx_area; if ((area != NULL) && (!GEO_OVERLAP(area, rect))) return; DRCErrorCount += 1; h = HashFind(&DRCErrorTable, cptr->drcc_why); i = (spointertype) HashGetValue(h); if (i == 0) { Tcl_Obj *lobj; lobj = Tcl_GetObjResult(magicinterp); Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_NewStringObj(cptr->drcc_why, -1)); Tcl_SetObjResult(magicinterp, lobj); } i += 1; HashSetValue(h, (spointertype)i); } /* Same routine as above, but output for every single error is recorded */ /* along with position information. */ void drcListallError (celldef, rect, cptr, scx) CellDef * celldef; /* CellDef being checked -- not used here */ Rect * rect; /* Area of error */ DRCCookie * cptr; /* Design rule violated */ SearchContext * scx; /* Only errors in scx->scx_area get reported. */ { Tcl_Obj *lobj, *pobj; HashEntry *h; Rect *area, r; ASSERT (cptr != (DRCCookie *) NULL, "drcListallError"); GeoTransRect(&scx->scx_trans, rect, &r); area = &scx->scx_area; if ((area != NULL) && (!GEO_OVERLAP(area, rect))) return; DRCErrorCount += 1; h = HashFind(&DRCErrorTable, cptr->drcc_why); lobj = (Tcl_Obj *) HashGetValue(h); if (lobj == NULL) lobj = Tcl_NewListObj(0, NULL); pobj = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(r.r_xbot)); Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(r.r_ybot)); Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(r.r_xtop)); Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(r.r_ytop)); Tcl_ListObjAppendElement(magicinterp, lobj, pobj); HashSetValue(h, lobj); } #else #define drcListError drcPrintError #endif /* * ---------------------------------------------------------------------------- * * DRCPrintStats -- * * Prints out statistics gathered by the DRC checking routines. * * Results: * None. * * Side effects: * Statistics are printed. Two values are printed for each * statistic: the number since statistics were last printed, * and the total to date. The own variables used to keep * track of statistics are updated. * * ---------------------------------------------------------------------------- */ void DRCPrintStats() { #ifdef DRCRULESHISTO int n; #endif /* DRCRULESHISTO */ TxPrintf("Design-rule checker statistics (recent/total):\n"); drcTotalSquares += DRCstatSquares; TxPrintf(" Squares processed: %d/%d\n", DRCstatSquares, drcTotalSquares); DRCstatSquares = 0; drcTotalTiles += DRCstatTiles; TxPrintf(" Tiles processed: %d/%d\n", DRCstatTiles, drcTotalTiles); DRCstatTiles = 0; drcTotalEdges += DRCstatEdges; TxPrintf(" Edges pieces processed: %d/%d\n", DRCstatEdges, drcTotalEdges); DRCstatEdges = 0; drcTotalRules += DRCstatRules; TxPrintf(" Constraint areas checked: %d/%d\n", DRCstatRules, drcTotalRules); DRCstatRules = 0; drcTotalSlow += DRCstatSlow; TxPrintf(" Multi-tile constraints: %d/%d\n", DRCstatSlow, drcTotalSlow); DRCstatSlow = 0; drcTotalInteractions += DRCstatInteractions; TxPrintf(" Interaction areas processed: %d/%d\n", DRCstatInteractions, drcTotalInteractions); DRCstatInteractions = 0; drcTotalIntTiles += DRCstatIntTiles; TxPrintf(" Tiles processed for interactions: %d/%d\n", DRCstatIntTiles, drcTotalIntTiles); DRCstatIntTiles = 0; drcTotalArrayTiles += DRCstatArrayTiles; TxPrintf(" Tiles processed for arrays: %d/%d\n", DRCstatArrayTiles, drcTotalArrayTiles); DRCstatArrayTiles = 0; #ifdef DRCRULESHISTO TxPrintf(" Number of rules applied per edge:\n"); TxPrintf(" # rules Horiz freq Vert freq\n"); for (n = 0; n < DRC_MAXRULESHISTO; n++) { drcTotalHRulesHisto[n] += DRCstatHRulesHisto[n]; drcTotalVRulesHisto[n] += DRCstatVRulesHisto[n]; if (drcTotalHRulesHisto[n] == 0 && drcTotalVRulesHisto[n] == 0) continue; TxPrintf(" %3d %10d/%10d %10d/%10d\n", n, DRCstatHRulesHisto[n], drcTotalHRulesHisto[n], DRCstatVRulesHisto[n], drcTotalVRulesHisto[n]); DRCstatHRulesHisto[n] = DRCstatVRulesHisto[n] = 0; } #endif /* DRCRULESHISTO */ } /* * ---------------------------------------------------------------------------- * * DRCWhy -- * * This procedure finds all errors within an area and prints messages * about each distinct kind of violation found. * * Results: * None. * * Side effects: * None, except that error messages are printed. The given * area is DRC'ed for both paint and subcell violations in every * cell of def's tree that it intersects. * * ---------------------------------------------------------------------------- */ void DRCWhy(dolist, use, area) bool dolist; /* * Generate Tcl list for value */ CellUse *use; /* Use in whose definition to start * the hierarchical check. */ Rect *area; /* Area, in def's coordinates, that * is to be checked. */ { SearchContext scx; Rect box; extern int drcWhyFunc(); /* Forward reference. */ /* Create a hash table to used for eliminating duplicate messages. */ HashInit(&DRCErrorTable, 16, HT_STRINGKEYS); DRCErrorCount = 0; box = DRCdef->cd_bbox; /* Undo will only slow things down in here, so turn it off. */ UndoDisable(); scx.scx_use = use; scx.scx_x = use->cu_xlo; scx.scx_y = use->cu_ylo; scx.scx_area = *area; scx.scx_trans = GeoIdentityTransform; drcWhyFunc(&scx, (pointertype)dolist); UndoEnable(); /* Delete the hash table now that we're finished (otherwise there * will be a core leak. */ HashKill(&DRCErrorTable); /* Redisplay the DRC yank definition in case anyone is looking * at it. */ DBReComputeBbox(DRCdef); (void) GeoInclude(&DRCdef->cd_bbox, &box); DBWAreaChanged(DRCdef, &box, DBW_ALLWINDOWS, &DBAllButSpaceBits); if (DRCErrorCount == 0) TxPrintf("No errors found.\n"); } #ifdef MAGIC_WRAPPER void DRCWhyAll(use, area, fout) CellUse *use; /* Use in whose definition to start * the hierarchical check. */ Rect *area; /* Area, in def's coordinates, that * is to be checked. */ FILE *fout; /* * Write formatted output to fout */ { SearchContext scx; Rect box; extern int drcWhyAllFunc(); /* Forward reference. */ HashSearch hs; HashEntry *he; Tcl_Obj *lobj, *robj; /* Create a hash table to used for eliminating duplicate messages. */ HashInit(&DRCErrorTable, 16, HT_STRINGKEYS); DRCErrorCount = 0; box = DRCdef->cd_bbox; /* Undo will only slow things down in here, so turn it off. */ UndoDisable(); scx.scx_use = use; scx.scx_x = use->cu_xlo; scx.scx_y = use->cu_ylo; scx.scx_area = *area; scx.scx_trans = GeoIdentityTransform; drcWhyAllFunc(&scx, NULL); UndoEnable(); /* Generate results */ robj = Tcl_NewListObj(0, NULL); HashStartSearch(&hs); while ((he = HashNext(&DRCErrorTable, &hs)) != (HashEntry *)NULL) { lobj = (Tcl_Obj *)HashGetValue(he); if (lobj != NULL) { Tcl_ListObjAppendElement(magicinterp, robj, Tcl_NewStringObj((char *)he->h_key.h_name, -1)); Tcl_ListObjAppendElement(magicinterp, robj, lobj); } } Tcl_SetObjResult(magicinterp, robj); /* Delete the hash table now that we're finished (otherwise there * will be a core leak. */ HashKill(&DRCErrorTable); /* Redisplay the DRC yank definition in case anyone is looking * at it. */ DBReComputeBbox(DRCdef); (void) GeoInclude(&DRCdef->cd_bbox, &box); DBWAreaChanged(DRCdef, &box, DBW_ALLWINDOWS, &DBAllButSpaceBits); if (DRCErrorCount == 0) TxPrintf("No errors found.\n"); } #endif /* MAGIC_WRAPPER */ /* * ---------------------------------------------------------------------------- * * drcWhyFunc -- * * This function is invoked underneath DrcWhy. It's called once * for each subcell instance of the current cell. If the subcell * is expanded, then it computes errors in that subcell and * searches the subcell recursively. * * Results: * Always returns 0 to keep the search alive. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ /* ARGSUSED */ int drcWhyFunc(scx, cdarg) SearchContext *scx; /* Describes current state of search. */ ClientData cdarg; /* Used to hold boolean value "dolist" */ { CellDef *def = scx->scx_use->cu_def; bool dolist = (bool)((pointertype)cdarg); /* Check paint and interactions in this subcell. */ // (void) DRCBasicCheck(def, &haloArea, &scx->scx_area, // (dolist) ? drcListError : drcPrintError, // (ClientData) scx); (void) DRCInteractionCheck(def, &scx->scx_area, &scx->scx_area, (dolist) ? drcListError : drcPrintError, (ClientData) scx); (void) DRCArrayCheck(def, &scx->scx_area, (dolist) ? drcListError : drcPrintError, (ClientData) scx); /* Also search children. */ (void) DBCellSrArea(scx, drcWhyFunc, (ClientData)cdarg); return 0; } #ifdef MAGIC_WRAPPER int drcWhyAllFunc(scx, cdarg) SearchContext *scx; /* Describes current state of search. */ ClientData cdarg; /* Unused */ { CellDef *def = scx->scx_use->cu_def; /* Check paint and interactions in this subcell. */ (void) DRCInteractionCheck(def, &scx->scx_area, &scx->scx_area, drcListallError, (ClientData)scx); (void) DRCArrayCheck(def, &scx->scx_area, drcListallError, (ClientData)scx); /* Also search children. */ (void) DBCellSrArea(scx, drcWhyAllFunc, (ClientData)cdarg); return 0; } #endif /* MAGIC_WRAPPER */ /* * ---------------------------------------------------------------------------- * * DRCCheck -- * * Marks all areas underneath the cursor, forcing them to be * rechecked by the DRC. * * Results: * None. * * Side effects: * Check tiles are painted. * * ---------------------------------------------------------------------------- */ void DRCCheck(use, area) CellUse *use; /* Top-level use of hierarchy. */ Rect *area; /* This area is rechecked everywhere in the * hierarchy underneath use. */ { SearchContext scx; extern int drcCheckFunc(); /* Forward reference. */ DBCellReadArea(use, area); scx.scx_use = use; scx.scx_x = use->cu_xlo; scx.scx_y = use->cu_ylo; scx.scx_area = *area; scx.scx_trans = GeoIdentityTransform; (void) drcCheckFunc(&scx, (ClientData) NULL); } /* ARGSUSED */ int drcCheckFunc(scx, cdarg) SearchContext *scx; ClientData cdarg; /* Not used. */ { Rect cellArea; CellDef *def; /* Clip the area to the size of the cell, then recheck that area. * The recheck is handled by painting the check info directly * and then calling DRCCheckThis only to add the cell to the * list of those to be checked. This avoids the hierarchical * upwards search that would normally be made by DRCCheckThis, * but which is unwelcome (and slow) here. */ cellArea = scx->scx_area; def = scx->scx_use->cu_def; GeoClip(&cellArea, &def->cd_bbox); GEO_EXPAND(&cellArea, DRCTechHalo, &cellArea); DBPaintPlane(def->cd_planes[PL_DRC_CHECK], &cellArea, DBStdPaintTbl(TT_CHECKPAINT, PL_DRC_CHECK), (PaintUndoInfo *) NULL); DRCCheckThis(def, TT_CHECKPAINT, (Rect *) NULL); /* Check child cells also. */ (void) DBCellSrArea(scx, drcCheckFunc, (ClientData) NULL); /* As a special performance hack, if the complete cell area is * handled here, don't bother to look at any more array elements. */ if (GEO_SURROUND(&cellArea, &def->cd_bbox)) return 2; else return 0; } /* * ---------------------------------------------------------------------------- * * DRCCount -- * * Searches the entire hierarchy underneath the given area. * For each cell found, counts design-rule violations in * that cell and outputs the counts. * * Results: * Return linked list of cell definitions and their error counts. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ DRCCountList * DRCCount(use, area) CellUse *use; /* Top-level use of hierarchy. */ Rect *area; /* Area in which violations are counted. */ { DRCCountList *dcl, *newdcl; HashTable dupTable; HashEntry *he; HashSearch hs; int count; SearchContext scx; extern int drcCountFunc(); /* Forward reference. */ /* Use a hash table to make sure that we don't output information * for any cell more than once. */ HashInit(&dupTable, 16, HT_WORDKEYS); scx.scx_use = use; scx.scx_x = use->cu_xlo; scx.scx_y = use->cu_ylo; scx.scx_area = *area; scx.scx_trans = GeoIdentityTransform; (void) drcCountFunc(&scx, &dupTable); /* Create the list from the hash table */ dcl = NULL; if (dupTable.ht_table != (HashEntry **) NULL) { HashStartSearch(&hs); while ((he = HashNext(&dupTable, &hs)) != (HashEntry *)NULL) { count = (spointertype)HashGetValue(he); if (count > 1) { newdcl = (DRCCountList *)mallocMagic(sizeof(DRCCountList)); newdcl->dcl_count = count - 1; newdcl->dcl_def = (CellDef *)he->h_key.h_ptr; newdcl->dcl_next = dcl; dcl = newdcl; } } } HashKill(&dupTable); return dcl; } int drcCountFunc(scx, dupTable) SearchContext *scx; HashTable *dupTable; /* Passed as client data, used to * avoid searching any cell twice. */ { int count; HashEntry *h; CellDef *def; extern int drcCountFunc2(); /* If we've already seen this cell definition before, then skip it * now. */ def = scx->scx_use->cu_def; h = HashFind(dupTable, (char *)def); if (HashGetValue(h) != 0) goto done; HashSetValue(h, 1); /* Count errors in this cell definition by scanning the error plane. */ count = 0; (void) DBSrPaintArea((Tile *) NULL, def->cd_planes[PL_DRC_ERROR], &def->cd_bbox, &DBAllButSpaceBits, drcCountFunc2, (ClientData) &count); HashSetValue(h, (spointertype)count + 1); /* Ignore children that have not been loaded---we will only report */ /* errors that can be seen. This avoids immediately loading and */ /* drc processing large layouts simply because we asked for an */ /* error count. When the cell is loaded, drc will be checked */ /* anyway, and the count can be updated in response to that check. */ if ((scx->scx_use->cu_def->cd_flags & CDAVAILABLE) == 0) return 0; /* Scan children recursively. */ (void) DBCellSrArea(scx, drcCountFunc, (ClientData) dupTable); /* As a special performance hack, if the complete cell area is * handled here, don't bother to look at any more array elements. */ done: if (GEO_SURROUND(&scx->scx_area, &def->cd_bbox)) return 2; else return 0; } int drcCountFunc2(tile, pCount) Tile *tile; /* Tile found in error plane. */ int *pCount; /* Address of count word. */ { if (TiGetType(tile) != (TileType) TT_SPACE) *pCount += 1; return 0; } /* * ---------------------------------------------------------------------------- * * DRCCatchUp-- * * This procedure just runs the background checker, regardless * of whether it's enabled or not, and waits for it to complete. * * Results: * None. * * Side effects: * Error and check tiles get painted and erased by the checker. * * ---------------------------------------------------------------------------- */ void DRCCatchUp() { int background; background = DRCBackGround; DRCBackGround = DRC_SET_ON; DRCContinuous(); DRCBackGround = background; } /* * ---------------------------------------------------------------------------- * * DRCFind -- * * Locates the next violation tile in the cell pointed to by * "use" and its children. * Successive calls will located successive violations, in * circular order. * * Results: * If an error tile was found in def, returns the indx of * the error tile (> 0). Returns 0 if there were no error * tiles in def. Returns -1 if indx was out-of-range * (not that many errors in def). * * Side effects: * Rect is filled with the location of the tile, if one is found. * * ---------------------------------------------------------------------------- */ typedef struct { int current; /* count of current error */ int target; /* count of target error */ Rect *rect; /* Return rectangle */ Transform trans; /* Return transform */ HashTable *deft; /* Table of cell definitions to avoid duplicates */ } Sindx; int DRCFind(use, area, rect, indx) CellUse *use; /* Cell use to check. */ Rect *area; /* Area of search */ Rect *rect; /* Rectangle to fill in with tile location. */ int indx; /* Go to this error. */ { SearchContext scx; Sindx finddata; Rect trect; int result; int drcFindFunc(); HashTable defTable; scx.scx_use = use; scx.scx_x = use->cu_xlo; scx.scx_y = use->cu_ylo; scx.scx_area = *area; scx.scx_trans = GeoIdentityTransform; HashInit(&defTable, 16, HT_WORDKEYS); finddata.current = 0; finddata.target = indx; finddata.rect = &trect; finddata.trans = scx.scx_trans; finddata.deft = &defTable; result = drcFindFunc(&scx, &finddata); HashKill(&defTable); if (result == 0) { if (finddata.current == 0) return 0; else return -1; } /* Translate rectangle back into coordinate system of "use" */ GeoTransRect(&finddata.trans, &trect, rect); return indx; } int drcFindFunc(scx, finddata) SearchContext *scx; Sindx *finddata; { CellDef *def; HashEntry *h; int drcFindFunc2(); def = scx->scx_use->cu_def; h = HashFind(finddata->deft, (char *)def); if (HashGetValue(h) != 0) return 0; HashSetValue(h, 1); (void) DBCellRead(def, (char *) NULL, TRUE); if (DBSrPaintArea((Tile *) NULL, def->cd_planes[PL_DRC_ERROR], &def->cd_bbox, &DBAllButSpaceBits, drcFindFunc2, (ClientData)finddata) != 0) { finddata->trans = scx->scx_trans; return 1; } /* Recursively search children */ return DBCellSrArea(scx, drcFindFunc, (ClientData)finddata); } int drcFindFunc2(tile, finddata) Tile *tile; /* Tile in error plane. */ Sindx *finddata; /* Information about error to find */ { if (TiGetType(tile) == (TileType) TT_SPACE) return 0; if (++finddata->current == finddata->target) { TiToRect(tile, finddata->rect); return 1; } return 0; } magic-8.0.210/drc/drc.h0000644000175000001440000002144511445747162013164 0ustar timusers/* * drc.h -- * * Definitions for the DRC module. * * ********************************************************************* * * 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. * * ********************************************************************* * * Needs to include: magic.h database.h * * rcsid $Header: /usr/cvsroot/magic-8.0/drc/drc.h,v 1.6 2010/09/20 21:13:22 tim Exp $ */ #ifndef _DRC_H #define _DRC_H #include "database/database.h" /* ----------------- component of DRC table ---------------------------- */ typedef struct drccookie { int drcc_dist; /* Extent of rule from edge. */ unsigned char drcc_mod; /* Fractional part of drcc_dist */ int drcc_cdist; /* Size of corner extension.* */ unsigned char drcc_cmod; /* Fractional part of drcc_cdist */ TileTypeBitMask drcc_mask; /* Legal types on RHS */ TileTypeBitMask drcc_corner; /* Types that trigger corner check */ unsigned char drcc_flags; /* Miscellaneous flags, see below. */ int drcc_edgeplane; /* Plane of edge */ int drcc_plane; /* Index of plane on which to check * legal types. */ char *drcc_why; /* Explanation of error found */ struct drccookie *drcc_next; } DRCCookie; /* *This is size "int" because it holds an area for DRC_AREA rules, */ /* and therefore may have twice the bit length of a normal rule distance. */ /* DRCCookie flags: * DRC_FORWARD: Rule applies from left to right (or bottom to top). * DRC_REVERSE: Rule applies from right to left (or top to bottom). * DRC_BOTHCORNERS: Must make corner extensions in both directions. * DRC_OUTSIDE: Rule applies only to the outside edge of the rule area. * DRC_TRIGGER: Violation of rule triggers a secondary rule. * * All other flags denote special DRC rules that do not use the standard 4-way * edge processing. */ #define DRC_FORWARD 0x00 #define DRC_REVERSE 0x01 #define DRC_BOTHCORNERS 0x02 #define DRC_TRIGGER 0x04 #define DRC_BENDS 0x08 #define DRC_OUTSIDE 0x08 // Note: Shared with DRC_BENDS #define DRC_AREA 0x10 #define DRC_MAXWIDTH 0x20 #define DRC_RECTSIZE 0x40 #define DRC_ANGLES 0x80 #define DRC_NONSTANDARD (DRC_AREA|DRC_MAXWIDTH|DRC_RECTSIZE|DRC_ANGLES) #define DRC_PENDING 0 #define DRC_UNPROCESSED CLIENTDEFAULT #define DRC_PROCESSED 1 /* * Background DRC (DRC Idle proc) for Tcl-based Magic */ #ifdef MAGIC_WRAPPER enum { DRC_NOT_RUNNING, DRC_IN_PROGRESS, DRC_BREAK_PENDING }; extern unsigned char DRCStatus; #endif /* * States of the background checker. This allows us to force an off state * during initialization while allowing the startup scripts to set the * state on or off. */ enum { DRC_SET_OFF, DRC_SET_ON, DRC_NOT_SET }; /* This is client data passed down through the various DRC checking * routines, and contains information about the area and rule being * checked. */ struct drcClientData { CellDef * dCD_celldef; /* CellDef, plane and area to DRC. */ int dCD_plane; Rect * dCD_rect; Tile * dCD_initial; /* Initial tile for search (left side * for forward rules, right for reverse * rules). */ Rect * dCD_clip; /* Clip error tiles against this. */ int * dCD_errors; /* Count of errors found. */ int dCD_radial; /* Radial check for corner extensions */ DRCCookie * dCD_cptr; /* Rule being checked. */ Rect * dCD_constraint; /* Constraint area from rule. */ Rect * dCD_rlist; /* Multiple constraints for triggered rules */ int dCD_entries; /* Number of constraints for triggered rules */ void (* dCD_function)(); /* Function to call for each * error found. */ ClientData dCD_clientData; /* Parameter for dCD_function */ }; /* Describes a cell whose contents require design-rule checking of * some sort. These are linked together for processing by the * continuous checker. */ #define DRCYANK "__DRCYANK__" /* predefined DRC yank buffer */ typedef struct drcpendingcookie { CellDef *dpc_def; struct drcpendingcookie *dpc_next; } DRCPendingCookie; /* Structure used to pass back lists of cell definitions and error tile counts */ typedef struct drccountlist { CellDef *dcl_def; int dcl_count; struct drccountlist *dcl_next; } DRCCountList; /* Structure used to keep information about the current DRC style */ typedef struct drckeep { struct drckeep *ds_next; char *ds_name; } DRCKeep; /* * DRC "why" strings are potentially referred to hundreds of times by * DRC cookies in the rule table. Rather than creating hundreds of * copies of each string, we create just one copy and let all the cookies * point to that one copy. * * Since we can't free these shared "why" strings when we delete a cookie, * we keep a list of these strings and free them all when convenient. */ typedef struct drcwhylist { char * dwl_string; struct drcwhylist * dwl_next; } drcWhyList; /* * Structure defining a DRC style */ typedef struct drcstyle { char ds_status; /* Status: Loaded, not loaded, or pending */ char *ds_name; /* Name of this DRC style */ DRCCookie *DRCRulesTbl[TT_MAXTYPES][TT_MAXTYPES]; TileTypeBitMask DRCExactOverlapTypes; int DRCScaleFactorN; /* Divide dist by this to get magic units */ int DRCScaleFactorD; /* Multiply dist by this to get magic units */ int DRCTechHalo; /* largest action distance of design rules */ int DRCStepSize; /* chunk size for decomposing large areas */ drcWhyList *DRCWhyList; PaintResultType DRCPaintTable[NP][NT][NT]; } DRCStyle; /* Things shared between DRC functions, but not used by the * outside world: */ extern int DRCstatEdges; /* counters for statistics gathering */ extern int DRCstatSlow; extern int DRCstatRules; extern int DRCstatTiles; extern int DRCstatInteractions; extern int DRCstatIntTiles; extern int DRCstatCifTiles; extern int DRCstatSquares; extern int DRCstatArrayTiles; #ifdef DRCRULESHISTO # define DRC_MAXRULESHISTO 30 /* Max rules per edge for statistics */ extern int DRCstatHRulesHisto[DRC_MAXRULESHISTO]; extern int DRCstatVRulesHisto[DRC_MAXRULESHISTO]; #endif /* DRCRULESHISTO */ extern int DRCTechHalo; /* Current halo being used */ extern int DRCStepSize; /* Current step size being used */ extern DRCPendingCookie * DRCPendingRoot; extern u_char DRCBackGround; /* global flag to enable/disable * continuous DRC */ extern bool DRCEuclidean; /* global flag to enable/disable * Euclidean distance measure */ extern int dbDRCDebug; extern bool DRCForceReload; /* TRUE if we have to reload DRC on a * change of the CIF output style */ extern DRCKeep *DRCStyleList; /* List of available DRC styles */ extern DRCStyle *DRCCurStyle; /* Current DRC style in effect */ extern CellDef *DRCdef; /* Current cell being checked for DRC */ extern CellUse *DRCuse, *DRCDummyUse; /* * Internal procedures */ extern void drcPaintError(); extern void drcPrintError(); extern int drcIncludeArea(); extern int drcExactOverlapTile(); extern void drcInitRulesTbl(); /* * Exported procedures */ extern int DRCGetDefaultLayerWidth(); extern int DRCGetDefaultLayerSpacing(); extern int DRCGetDefaultLayerSurround(); extern void DRCTechInit(); extern bool DRCTechLine(); extern bool DRCTechAddRule(); extern void DRCTechStyleInit(); extern void DRCTechFinal(); extern void DRCTechRuleStats(); extern void DRCTechScale(); extern void DRCReloadCurStyle(); extern void DRCInit(); extern void DRCContinuous(); extern void DRCCheckThis(); extern void DRCRemovePending(); extern void DRCPrintRulesTable(); extern void DRCWhy(); extern void DRCPrintStats(); extern void DRCCheck(); extern DRCCountList *DRCCount(); extern int DRCFind(); extern void DRCCatchUp(); extern bool DRCFindInteractions(); extern void DRCPrintStyle(); extern void DRCSetStyle(); extern void DRCLoadStyle(); /* The following macro can be used by the outside world to see if * the background checker needs to be called. */ #ifdef MAGIC_WRAPPER #define DRCHasWork ((DRCPendingRoot != NULL) && (DRCBackGround == DRC_SET_ON)) #else #define DRCHasWork ((DRCPendingRoot != NULL) && (DRCBackGround != DRC_SET_OFF)) #endif #endif /* _DRC_H */ magic-8.0.210/drc/DRCprint.c0000644000175000001440000001156610751423606014070 0ustar timusers/* * DRCPrint.c -- * * Edge-based design rule checker * * ********************************************************************* * * 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/drc/DRCprint.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "drc/drc.h" extern char *maskToPrint(); extern char *DBTypeShortName(); /* * ---------------------------------------------------------------------------- * * drcGetName -- * * This is a utility procedure that returns a convenient name for * a mask layer. * * Results: * The result is the first 8 characters of the long name for * the layer. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ char * drcGetName(layer, string) int layer; char *string; /* Used to hold name. Must have length >= 8 */ { (void) strncpy(string, DBTypeShortName(layer), 8); string[8] = '\0'; if (layer == TT_SPACE) return "space"; return string; } /* * ---------------------------------------------------------------------------- * DRCPrintRulesTable -- * * Write compiled DRC rules table and adjacency matrix to the given file. * * Results: * None. * * Side effects: * None. * ---------------------------------------------------------------------------- */ void DRCPrintRulesTable (fp) FILE *fp; { int i, j, k; DRCCookie * dp; char buf1[20], buf2[20]; int gotAny; /* print the rules table */ for (i = 0; i < DBNumTypes; i++) { gotAny = FALSE; for (j = 0; j < DBNumTypes; j++) { if (DRCCurStyle->DRCRulesTbl [i][j] != (DRCCookie *) NULL) { k = 1; for (dp = DRCCurStyle->DRCRulesTbl [i][j]; dp != (DRCCookie *) NULL; dp = dp->drcc_next) { gotAny = TRUE; if (k == 1) { fprintf(fp,"%-8s %-8s ",drcGetName(i, buf1), drcGetName(j, buf2)); k++; } else fprintf(fp," "); fprintf(fp,"%d x %d %s (%s)\n", dp->drcc_dist, dp->drcc_cdist, maskToPrint(&dp->drcc_mask), DBPlaneLongName(dp->drcc_plane)); fprintf(fp," %s", maskToPrint(&dp->drcc_corner)); if (dp->drcc_flags > 0) fprintf(fp, "\n "); if (dp->drcc_flags & DRC_REVERSE) fprintf(fp," reverse"); if (dp->drcc_flags & DRC_BOTHCORNERS) fprintf(fp," both-corners"); if (dp->drcc_flags & DRC_TRIGGER) fprintf(fp," trigger"); if (dp->drcc_flags & DRC_AREA) fprintf(fp," area"); if (dp->drcc_flags & DRC_MAXWIDTH) fprintf(fp," maxwidth"); if (dp->drcc_flags & DRC_BENDS) fprintf(fp," bends"); if (dp->drcc_flags & DRC_RECTSIZE) fprintf(fp," rect-size"); if (dp->drcc_flags & DRC_ANGLES) fprintf(fp," angles"); fprintf(fp,"\n"); } } } if (gotAny) fprintf(fp,"\n"); } /* Print out overlaps that are illegal between subcells. */ for (i = 0; i < DBNumTypes; i++) { for (j = 0; j < DBNumTypes; j++) { if ((i == TT_ERROR_S) || (j == TT_ERROR_S)) continue; if (DRCCurStyle->DRCPaintTable[0][i][j] == TT_ERROR_S) fprintf(fp, "Tile type %s can't overlap type %s.\n", drcGetName(i, buf1), drcGetName(j, buf2)); } } /* Print out tile types that must have exact overlaps. */ if (!TTMaskIsZero(&DRCCurStyle->DRCExactOverlapTypes)) { fprintf(fp, "Types that must overlap exactly: %s\n", maskToPrint(&DRCCurStyle->DRCExactOverlapTypes)); } } char * maskToPrint (mask) TileTypeBitMask *mask; { int i; int gotSome = FALSE; static char printchain[400]; char buffer[20]; if (TTMaskIsZero(mask)) return ""; printchain[0] = '\0'; for (i = 0; i < DBNumTypes; i++) if (TTMaskHasType(mask, i)) { if (gotSome) strcat(printchain, ","); else gotSome = TRUE; strcat(printchain, drcGetName(i, buffer)); } return (printchain); } magic-8.0.210/VERSION0000644000175000001440000000001012574746561012532 0ustar timusers8.0.210 magic-8.0.210/windows/0000755000175000001440000000000012405633025013144 5ustar timusersmagic-8.0.210/windows/windSearch.c0000644000175000001440000001330210751423606015402 0ustar timusers /* windSearch.c - * * Functions to find & enumerate windows. * * ********************************************************************* * * 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/windows/windSearch.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "windows/windows.h" #include "graphics/glyphs.h" #include "windows/windInt.h" /* * ---------------------------------------------------------------------------- * windSearchPoint -- * * Find the window that is displayed at a given screen point. * * Results: * A pointer to the window that contains the point, or NULL if no * window fits the bill. This routine is dangerous, since in some * window packages more that one window may contain that point. In * particular, under Sun Windows ALL windows contain the point (0, 0). * * If 'inside' is non-NULL, it points to a boolean variable which will be * set to TRUE if the point is in the interior of the window, and FALSE * if it is in the border of the window. * * Side effects: * None. * ---------------------------------------------------------------------------- */ MagWindow * windSearchPoint(p, inside) Point *p; /* A point in screen coordinates */ bool *inside; /* A pointer to a boolean variable that is set to * TRUE if the point is in the interior of the window, * and FALSE if it is in the border. If this pointer * is NULL then 'inside' is not filled in. */ { MagWindow *w; for(w = windTopWindow; w != (MagWindow *) NULL; w = w->w_nextWindow) { if (GEO_ENCLOSE(p, &(w->w_allArea) )) { if (inside != (bool *) NULL) *inside = GEO_ENCLOSE(p, &(w->w_screenArea) ); return w; } } return (MagWindow *) NULL; } /* * ---------------------------------------------------------------------------- * * WindSearchWid -- * * Find a window given its window ID. * * Results: * A pointer to the window, of NULL if not found.. * * Side Effects: * None. * * ---------------------------------------------------------------------------- */ MagWindow * WindSearchWid(wid) int wid; { MagWindow *w; for(w = windTopWindow; w != (MagWindow *) NULL; w = w->w_nextWindow) { if (w->w_wid == wid) return w; } return NULL; } /* * ---------------------------------------------------------------------------- * * WindSearchData -- * * Find a window with a matching w_grdata record. * * Results: * A pointer to the window, of NULL if not found.. * * Side Effects: * None. * * ---------------------------------------------------------------------------- */ MagWindow * WindSearchData(grdata) ClientData grdata; { MagWindow *w; for(w = windTopWindow; w != (MagWindow *) NULL; w = w->w_nextWindow) { if (w->w_grdata == grdata) return w; } return NULL; } /* * ---------------------------------------------------------------------------- * WindSearch -- * * Search for all of the client's windows that contain a particular * surface area, whether exposed or not. * * Results: * None. * * Side effects: * Calls the function 'func' for each window that matches. 'func' should * be of the form * * int func(window, clientData) * MagWindow *window; * ClientData clientData; * { * } * * Window is the window that matched the search, and clientData is the * clientData parameter supplied to this procedure. * If the function returns a non-zero value the search is aborted, and * that value is returned. Otherwise the search continues and 0 is * returned. * ---------------------------------------------------------------------------- */ int WindSearch(client, surfaceID, surfaceArea, func, clientData) WindClient client; /* Search for the windows that belong to * this client. NULL means all clients. */ ClientData surfaceID; /* The unique ID of the surface that we * are looking for. If NULL then look for * any surface. */ Rect *surfaceArea; /* The area that we are looking for in surface * coordinates. If NULL then match without * regard to the area in the window. */ int (*func)(); /* The function to call with each window * that matches. */ ClientData clientData; /* The client data to be passed to the caller's * function. */ { MagWindow *w; int res = 0; for (w = windTopWindow; w != (MagWindow *) NULL; w = w->w_nextWindow) { if ( ((client == (WindClient) NULL) || (w->w_client == client)) && ((surfaceID == (ClientData) NULL) || (w->w_surfaceID == surfaceID)) ) { if (surfaceArea == (Rect *) NULL) { res = (*func)(w, clientData); if (res != 0) return res; continue; /* continue on to next window */ } else if (GEO_TOUCH(surfaceArea, &(w->w_surfaceArea) )) { res = (*func)(w, clientData); if (res != 0) return res; } } } return 0; } magic-8.0.210/windows/windSend.c0000644000175000001440000002756410751423606015105 0ustar timusers/* windSend.c - * * Send button pushes and commands to the window's command * interpreters. * * ********************************************************************* * * 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/windows/windSend.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include #include "tcltk/tclmagic.h" #include "utils/magic.h" #include "textio/textio.h" #include "utils/geometry.h" #include "windows/windows.h" #include "graphics/glyphs.h" #include "windows/windInt.h" #include "utils/stack.h" #include "utils/utils.h" #include "utils/signals.h" #include "textio/txcommands.h" clientRec *windClient = NULL; bool windPrintCommands = FALSE; /* debugging flag */ global TxCommand *WindCurrentCmd; /* The current command. */ global MagWindow *WindCurrentWindow; /* The window at which the current command * was invoked. */ global int WindOldButtons; /* The buttons for the last command */ global int WindNewButtons; /* The buttons this time */ static WindClient windGrabber = (WindClient) NULL; /* If this variable is non-null then send * all commands to it */ Stack *windGrabberStack = NULL; /* Forward declarations */ extern void WindGrabInput(); extern void WindReleaseInput(); extern void windHelp(); /* * ---------------------------------------------------------------------------- * WindSendCommand -- * * Send a command to a window to be executed. If the window passed is * NULL then whatever window is at the point given in the command is * used. * * Results: * TRUE if the command was able to be processed. * * Side effects: * Whatever the window wishes to do with the command. * ---------------------------------------------------------------------------- */ bool WindSendCommand(w, cmd) MagWindow *w; TxCommand *cmd; /* A pointer to a command */ { int windCmdNum, clientCmdNum; clientRec *rc; bool inside; /* tells us if we are inside of a window */ /* This thing is a horrendous mess. Changing WindClient to */ /* MagWindow in the arguments list is a big help, but the */ /* following code should be simplified. Namely, w == 0 */ /* only when the command comes from the command line. */ /* Tcl/Tk commands and graphics are set up to supply a */ /* valid w. Under normal conditions, we should not need to */ /* guess what the client is. */ /* The big problem here is that all windows are expected */ /* to take windClient commands---but that prevents setting */ /* up windows which don't. This should be handled better, */ /* probably at the low level of the MagWindow structure */ /* itself. */ if (windClient == (clientRec *) NULL) windClient = (clientRec *) WindGetClient(WINDOW_CLIENT, TRUE); /* ignore no-op commands */ if ( (cmd->tx_button == TX_NO_BUTTON) && (cmd->tx_argc == 0) ) { return TRUE; } inside = FALSE; ASSERT( (cmd->tx_button == TX_NO_BUTTON) || (cmd->tx_argc == 0), "WindSendCommand"); WindOldButtons = WindNewButtons; if (cmd->tx_button == TX_NO_BUTTON) { if (windClient == (clientRec *)NULL) return FALSE; /* If window commands are disallowed by the client (set by */ /* the client's WIND_COMMANDS flag), report no command. */ if ((w != NULL) && !(w->w_flags & WIND_COMMANDS)) windCmdNum = -2; else windCmdNum = Lookup(cmd->tx_argv[0], windClient->w_commandTable); } else { if (cmd->tx_buttonAction == TX_BUTTON_DOWN) WindNewButtons |= cmd->tx_button; else WindNewButtons &= ~(cmd->tx_button); } /* If we were passed a NULL MagWindow pointer, try to determine the */ /* window from the command's window ID number. */ if (w == (MagWindow *)NULL) { if (cmd->tx_wid == WIND_UNKNOWN_WINDOW) { w = windSearchPoint( &(cmd->tx_p), &inside); if (w != NULL) cmd->tx_wid = w->w_wid; } else if (cmd->tx_wid >= 0) w = WindSearchWid(cmd->tx_wid); } if (w != (MagWindow *) NULL) { inside = GEO_ENCLOSE(&cmd->tx_p, &w->w_screenArea); if ((!inside) && (w->w_flags & WIND_COMMANDS)) rc = windClient; /* Handles border regions */ else rc = (clientRec *) w->w_client; } else /* Can't determine a window---assume a windowless layout client */ rc = (clientRec *) WindGetClient(DEFAULT_CLIENT, TRUE); if (windGrabber != (WindClient) NULL) { /* this client wants to hog all commands */ rc = (clientRec *) windGrabber; } /* At this point, the command is all set up and ready to send to * the client. */ ASSERT(rc != (clientRec *) NULL, "WindSendCommand"); if (windPrintCommands) { TxPrintf("Sending command:\n"); windPrintCommand(cmd); } WindCurrentCmd = cmd; WindCurrentWindow = w; if (cmd->tx_button == TX_NO_BUTTON) { clientCmdNum = Lookup(cmd->tx_argv[0], rc->w_commandTable); if ((clientCmdNum == -1) || (windCmdNum == -1)) { TxError("That command abbreviation is ambiguous.\n"); return FALSE; } if ((windCmdNum == -2) && (clientCmdNum == -2)) { /* Not a valid command. Help the user out by telling him * what might be wrong. And also print out the command! */ TxError("Unknown command:"); windPrintCommand(cmd); if (WindNewButtons != 0) { char *bname = "unknown"; if (WindNewButtons & TX_LEFT_BUTTON) bname = "left"; else if (WindNewButtons & TX_RIGHT_BUTTON) bname = "right"; else if (WindNewButtons & TX_MIDDLE_BUTTON) bname = "middle"; TxError( "'%s' window is waiting for %s button to be released.\n", rc->w_clientName, bname); } else if (windGrabber != (WindClient) NULL) { TxError( "'%s' window is grabbing all input.\n", rc->w_clientName); } else TxError("Did you point to the correct window?\n"); return FALSE; } /* intercept 'help' */ if ((windCmdNum >= 0) && (strncmp(windClient->w_commandTable[windCmdNum], "help", 4) == 0) ) { TxUseMore(); windHelp(cmd, "Global", windClient->w_commandTable); if (rc != windClient) windHelp(cmd, rc->w_clientName, rc->w_commandTable); TxStopMore(); return TRUE; } /* If both command tables point to window commands, */ /* only do the command once. */ if (rc == windClient) clientCmdNum = -2; /* Ambiguity resolution. If only one client reports a */ /* valid command, then execute it. If both clients */ /* report a valid command, then compare them against */ /* each other so that a full command name will take */ /* precedence over an ambiguous command abbreviation. */ /* Finally, if this doesn't resolve the command, the */ /* registered client takes precedence over the general- */ /* purpose window client, allowing clients to override */ /* the general-purpose functions (like "zoom" and */ /* "view", for instance). This is the reverse of how */ /* it was implemented prior to magic-7.3.61, but that */ /* makes no sense. */ if ((windCmdNum < 0) && (clientCmdNum >= 0)) (*(rc->w_command))(w, cmd); else if ((windCmdNum >= 0) && (clientCmdNum < 0)) (*(windClient->w_command))(w, cmd); else if ((windCmdNum >= 0) && (clientCmdNum >= 0)) { char *(ownTable[3]); int ownCmdNum; ownTable[0] = rc->w_commandTable[clientCmdNum]; ownTable[1] = windClient->w_commandTable[windCmdNum]; ownTable[2] = NULL; ownCmdNum = Lookup(cmd->tx_argv[0], ownTable); ASSERT(ownCmdNum != -2, "WindSendCommand"); if (ownCmdNum == -1) { TxError("That command abbreviation is ambiguous\n"); return FALSE; } if (ownCmdNum == 0) (*(rc->w_command))(w, cmd); else (*(windClient->w_command))(w, cmd); } } else { /* A button has been pushed. * If there were no buttons pressed on the last command * now there are, and direct all future button pushes to this * client until all buttons are up again. */ /* windClient is responsible for processing actions in the */ /* window border, assuming that the window handles its own */ /* borders. Scrollbars are only available on the layout */ /* window, which is the "default" client. So we check for a */ /* position in the border region, and launch the window client */ /* if it is. */ if (WindOldButtons == 0) WindGrabInput((WindClient) rc); else if (WindNewButtons == 0) WindReleaseInput((WindClient) rc); (*(rc->w_command))(w, cmd); } /* A client may modify WindNewButtons & WindOldButtons in rare cases, * so we better check again. */ if ((WindNewButtons == 0) && (windGrabber != (WindClient) NULL)) WindReleaseInput((WindClient) rc); return TRUE; } /* * ---------------------------------------------------------------------------- * WindGrabInput -- * * Grab all input -- that is, send all further commands to the * specified client. * * Results: * None. * * Side effects: * pushes old grabber onto a stack. * ---------------------------------------------------------------------------- */ void WindGrabInput(client) WindClient client; { ASSERT( client != NULL, "WindGrabInput"); StackPush( (ClientData) windGrabber, windGrabberStack); windGrabber = client; } /* * ---------------------------------------------------------------------------- * WindReleaseInput -- * * Stop grabbing the input (the inverse of WindGrabInput). * * Results: * None. * * Side effects: * The previous grabber (if any) is restored. * ---------------------------------------------------------------------------- */ void WindReleaseInput(client) WindClient client; { ASSERT( client == windGrabber, "WindReleaseInput"); windGrabber = (WindClient) StackPop(windGrabberStack); } /* * ---------------------------------------------------------------------------- * windHelp -- * * Print out help information for a client. * * Results: * None. * * Side effects: * None. * ---------------------------------------------------------------------------- */ void windHelp(cmd, name, table) TxCommand *cmd; /* Information about command options. */ char *name; /* Name of client for whom help is being * printed. */ char *table[]; /* Client's command table. */ { static char *capName = NULL; static char patString[200], *pattern; bool wiz; char **tp; #define WIZARD_CHAR '*' if (cmd->tx_argc > 2) { TxError("Usage: help [pattern]\n"); return; } if (SigInterruptPending) return; (void) StrDup(&capName, name); if (islower(capName[0])) capName[0] += 'A' - 'a'; TxPrintf("\n"); if ((cmd->tx_argc == 2) && strcmp(cmd->tx_argv[1], "wizard") == 0) { pattern = "*"; wiz = TRUE; TxPrintf("Wizard %s Commands\n", capName); TxPrintf("----------------------\n"); } else { if (cmd->tx_argc == 2) { pattern = patString; (void) sprintf(patString, "*%.195s*", cmd->tx_argv[1]); } else pattern = "*"; wiz = FALSE; TxPrintf("%s Commands\n", capName); TxPrintf("---------------\n"); } for (tp = table; *tp != (char *) NULL; tp++) { if (SigInterruptPending) return; if (Match(pattern, *tp) && (wiz ^ (**tp != WIZARD_CHAR)) ) TxPrintf("%s\n", *tp); } } magic-8.0.210/windows/windInt.h0000644000175000001440000000564710751423606014751 0ustar timusers/* * windInt.h -- * * Internal definitions for the window package. * * ********************************************************************* * * 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. * * ********************************************************************* * * rcsid $Header: /usr/cvsroot/magic-8.0/windows/windInt.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ * */ #ifndef _WINDINT_H #define _WINDINT_H #include "windows/windows.h" #include "graphics/glyphs.h" /* ----------------- data structures ----------------- */ typedef struct WIND_S3 { char *w_clientName; bool (*w_create)(); bool (*w_delete)(); void (*w_redisplay)(); void (*w_command)(); void (*w_update)(); bool (*w_exit)(); void (*w_reposition)(); /* called when a window moves or changes size */ GrGlyph *w_icon; char **w_commandTable; void (**w_functionTable)(); struct WIND_S3 *w_nextClient; } clientRec; /* ----------------- variables ----------------- */ extern MagWindow *windTopWindow; extern MagWindow *windBottomWindow; extern clientRec *windFirstClientRec; extern char *butTable[]; extern char *actTable[]; extern bool windPrintCommands; /* ----------------- procedures ----------------- */ extern void windDisplayArea(); extern void windPrintCommand(); extern void windSetPoint(); extern void windDump(); extern void windClientInit(); extern MagWindow *windSearchPoint(); /* ----------------- constants ----------------- */ /* the width of window borders */ extern int windCaptionPixels; #define THIN_LINE (((w)->w_flags & WIND_BORDER) ? 2 : 0) #define TOP_BORDER(w) (((w)->w_flags & WIND_CAPTION) \ ? windCaptionPixels : 2*THIN_LINE) #define BOT_BORDER(w) (((w)->w_flags & WIND_SCROLLBARS) \ ? 2*THIN_LINE + WindScrollBarWidth : 2*THIN_LINE) #define LEFT_BORDER(w) (((w)->w_flags & WIND_SCROLLBARS) \ ? 2*THIN_LINE + WindScrollBarWidth : 2*THIN_LINE) #define RIGHT_BORDER(w) 2*THIN_LINE /* Always leave room for the borders plus 25 pixels */ #define WIND_MIN_WIDTH (6*THIN_LINE + 3*WindScrollBarWidth + 25) #define WIND_MIN_HEIGHT (windCaptionPixels + 4*THIN_LINE + \ 3*WindScrollBarWidth + 25) #define DEFAULT_CLIENT "layout" #define WINDOW_CLIENT "*window" /* Default size for new windows. */ #define CREATE_HEIGHT 300 #define CREATE_WIDTH 300 #endif /* _WINDINT_H */ magic-8.0.210/windows/windows22.glyphs0000644000175000001440000001177310751423606016247 0ustar timusers# # 22-pixel sized glyphs for the Window package # # rcsid $Header: /usr/cvsroot/magic-8.0/windows/windows22.glyphs,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ # # syntax of first line: size size 5 22 22 #up W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W K K W W W W W W W W W W W W W W W W W W W K K K K W W W W W W W W W W W W W W W W W K K K K K K W W W W W W W W W W W W W W W K K K K K K K K W W W W W W W W W W W W W K K K K K K K K K K W W W W W W W W W W W K K K K K K K K K K K K W W W W W W W W W K K K K K K K K K K K K K K W W W W W W W K K K K K K K K K K K K K K K K W W W W W K K K K K K K K K K K K K K K K K K W W W W W W W W W W K K K K K K W W W W W W W W W W W W W W W W K K K K K K W W W W W W W W W W W W W W W W K K K K K K W W W W W W W W W W W W W W W W K K K K K K W W W W W W W W W W W W W W W W K K K K K K W W W W W W W W W W W W W W W W K K K K K K W W W W W W W W W W W W W W W W K K K K K K W W W W W W W W W W W W W W W W K K K K K K W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W #down W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W K K K K K K W W W W W W W W W W W W W W W W K K K K K K W W W W W W W W W W W W W W W W K K K K K K W W W W W W W W W W W W W W W W K K K K K K W W W W W W W W W W W W W W W W K K K K K K W W W W W W W W W W W W W W W W K K K K K K W W W W W W W W W W W W W W W W K K K K K K W W W W W W W W W W W W W W W W K K K K K K W W W W W W W W W W K K K K K K K K K K K K K K K K K K W W W W W K K K K K K K K K K K K K K K K W W W W W W W K K K K K K K K K K K K K K W W W W W W W W W K K K K K K K K K K K K W W W W W W W W W W W K K K K K K K K K K W W W W W W W W W W W W W K K K K K K K K W W W W W W W W W W W W W W W K K K K K K W W W W W W W W W W W W W W W W W K K K K W W W W W W W W W W W W W W W W W W W K K W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W #left W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W K W W W W W W W W W W W W W W W W W W W W K K W W W W W W W W W W W W W W W W W W W K K K W W W W W W W W W W W W W W W W W W K K K K W W W W W W W W W W W W W W W W W K K K K K W W W W W W W W W W W W W W W W K K K K K K W W W W W W W W W W W W W W W K K K K K K K K K K K K K K K W W W W W W K K K K K K K K K K K K K K K K W W W W W K K K K K K K K K K K K K K K K K W W W W W K K K K K K K K K K K K K K K K K W W W W W W K K K K K K K K K K K K K K K K W W W W W W W K K K K K K K K K K K K K K K W W W W W W W W K K K K K K W W W W W W W W W W W W W W W W W K K K K K W W W W W W W W W W W W W W W W W W K K K K W W W W W W W W W W W W W W W W W W W K K K W W W W W W W W W W W W W W W W W W W W K K W W W W W W W W W W W W W W W W W W W W W K W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W #right W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W K W W W W W W W W W W W W W W W W W W W W W K K W W W W W W W W W W W W W W W W W W W W K K K W W W W W W W W W W W W W W W W W W W K K K K W W W W W W W W W W W W W W W W W W K K K K K W W W W W W W W W W W W W W W W W K K K K K K W W W W W W W W K K K K K K K K K K K K K K K W W W W W W W K K K K K K K K K K K K K K K K W W W W W W K K K K K K K K K K K K K K K K K W W W W W K K K K K K K K K K K K K K K K K W W W W W K K K K K K K K K K K K K K K K W W W W W W K K K K K K K K K K K K K K K W W W W W W W W W W W W W W W K K K K K K W W W W W W W W W W W W W W W W K K K K K W W W W W W W W W W W W W W W W W K K K K W W W W W W W W W W W W W W W W W W K K K W W W W W W W W W W W W W W W W W W W K K W W W W W W W W W W W W W W W W W W W W K W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W #zoom W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W K K K K K K K K K K K K K K W W W W W W W W K K K K K K K K K K K K K K W W W W W W W W K K W W W W W W W W W W K K W W W W W W W W K K W W W W W W W W W W K K W W W W W W W W K K W W W W W W W W W W K K W W W W W W W W K K W W W W W W W W W W K K W W W W W W W W K K W W W W K K W W W W K K W W W W W W W W K K W W W W K K W W W W K K W W W W W W W W K K W W W W W W W W W W K K W W W W W W W W K K W W W W W W W W W W K K W W W W W W W W K K W W W W W W W W W W K K W W W W W W W W K K W W W W W W W W W W K K W W W W W W W W K K K K K K K K K K K K K K W W W W W W W W K K K K K K K K K K K K K K W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W magic-8.0.210/windows/windows7.glyphs0000644000175000001440000000142310751423606016161 0ustar timusers# # 7-pixel wide glyphs for the window package # # rcsid $Header: /usr/cvsroot/magic-8.0/windows/windows7.glyphs,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ # # # syntax of first line: size size 5 7 7 #up W W W K W W W W W K K K W W W K K K K K W K K K K K K K W W K K K W W W W K K K W W W W K K K W W #down W W K K K W W W W K K K W W W W K K K W W K K K K K K K W K K K K K W W W K K K W W W W W K W W W #left W W W K W W W W W K K W W W W K K K K K K K K K K K K K W K K K K K K W W K K W W W W W W K W W W #right W W W K W W W W W W K K W W K K K K K K W K K K K K K K K K K K K K W W W W K K W W W W W K W W W #zoom W W W W W W W W K K K K K W W K W W W K W W K W K W K W W K W W W K W W K K K K K W W W W W W W W magic-8.0.210/windows/windCmdNR.c0000644000175000001440000002200310751423606015136 0ustar timusers/* windCmdNR.c - * * This file contains Magic command routines for those commands * that are valid in all windows. * * ********************************************************************* * * 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/windows/windCmdNR.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include #include #include #include #include "utils/magic.h" #include "textio/textio.h" #include "utils/geometry.h" #include "windows/windows.h" #include "graphics/glyphs.h" #include "windows/windInt.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/main.h" #include "utils/tech.h" #include "utils/runstats.h" #include "utils/undo.h" #include "utils/utils.h" #include "graphics/graphics.h" #include "textio/txcommands.h" #include "dbwind/dbwind.h" /* * ---------------------------------------------------------------------------- * windOpenCmd -- * * Open a new window at the cursor position. Give it a default size, * and default client, and pass the command line args off to the client. * * Results: * None. * * Side effects: * None. * ---------------------------------------------------------------------------- */ void windOpenCmd(w, cmd) MagWindow *w; TxCommand *cmd; { Rect area; Point frame; WindClient wc; if ( w == (MagWindow *) NULL ) { frame.p_x = (GrScreenRect.r_xtop - GrScreenRect.r_xbot) / 2; frame.p_y = (GrScreenRect.r_ytop - GrScreenRect.r_ybot) / 2; } else windScreenToFrame(w, &cmd->tx_p, &frame); area.r_xbot = frame.p_x - CREATE_WIDTH/2; area.r_xtop = frame.p_x + CREATE_WIDTH/2; area.r_ybot = frame.p_y - CREATE_HEIGHT/2; area.r_ytop = frame.p_y + CREATE_HEIGHT/2; wc = WindGetClient(DEFAULT_CLIENT, TRUE); ASSERT(wc != (WindClient) NULL, "windOpenCmd"); if (WindCreate(wc, &area, TRUE, cmd->tx_argc - 1, cmd->tx_argv + 1) == (MagWindow *) NULL) { TxError("Could not create window\n"); } } /* * ---------------------------------------------------------------------------- * windOverCmd -- * * Move a window over (on top of) the other windows. * * Results: * None. * * Side effects: * Screen updates. * ---------------------------------------------------------------------------- */ void windOverCmd(w, cmd) MagWindow *w; TxCommand *cmd; { if (cmd->tx_argc != 1) { TxError("Usage: %s\n", cmd->tx_argv[0]); } if (w == (MagWindow *) NULL) { TxError("Point to a window first\n"); return; } WindOver(w); } /* * ---------------------------------------------------------------------------- * * windPauseCmd -- * * Print out the arguments and wait for or a command. * * Usage: * *pause [args] * * Results: * None. * * Side effects: * prints its args. * * ---------------------------------------------------------------------------- */ void windPauseCmd(w, cmd) MagWindow *w; TxCommand *cmd; { int i; static char ssline[TX_MAX_CMDLEN]; WindUpdate(); GrFlush(); for (i = 1; i < cmd->tx_argc; i++) { TxPrintf(cmd->tx_argv[i]); TxPrintf(" "); if (i+1 == cmd->tx_argc) TxPrintf(" "); } TxPrintf("Pausing: type to continue: "); (void) TxGetLine(ssline, 98); } char *butTable[] = { "left", "middle", "right", 0 }; char *actTable[] = { "down", "up", 0 }; /* * ---------------------------------------------------------------------------- * windPushbuttonCmd -- * * Pretend that a button was pushed * * Results: * None. * * Side effects: * None. * ---------------------------------------------------------------------------- */ void windPushbuttonCmd(w, cmd) MagWindow *w; TxCommand *cmd; { int but, act; static TxCommand txcmd; if (cmd->tx_argc != 3) goto badusage; but = Lookup(cmd->tx_argv[1], butTable); if (but < 0) goto badusage; act = Lookup(cmd->tx_argv[2], actTable); if (act < 0) goto badusage; switch (but) { case 0: txcmd.tx_button = TX_LEFT_BUTTON; break; case 1: txcmd.tx_button = TX_MIDDLE_BUTTON; break; case 2: txcmd.tx_button = TX_RIGHT_BUTTON; break; } if (act == 0) txcmd.tx_buttonAction = TX_BUTTON_DOWN; else txcmd.tx_buttonAction = TX_BUTTON_UP; txcmd.tx_argc = 0; txcmd.tx_p = cmd->tx_p; txcmd.tx_wid = cmd->tx_wid; (void) WindSendCommand(w, &txcmd); return; badusage: TxError("Usage: %s button action\n", cmd->tx_argv[0]); return; } /* * ---------------------------------------------------------------------------- * WindQuitCmd -- * * Leave the system, but first notify all clients. * * Results: * None. * * Side effects: * the system may exit. * ---------------------------------------------------------------------------- */ void windQuitCmd(w, cmd) MagWindow *w; TxCommand *cmd; { clientRec *cr; bool checkfirst = TRUE; if (cmd->tx_argc == 2) if (!strcmp(cmd->tx_argv[1], "-noprompt")) checkfirst = FALSE; if (checkfirst) for (cr = windFirstClientRec; cr != (clientRec *) NULL; cr = cr->w_nextClient) if (cr->w_exit != NULL) if (!(*(cr->w_exit))()) return; MainExit(0); } /* * ---------------------------------------------------------------------------- * * windRedoCmd * * Implement the "redo" command. * * Usage: * redo [count] * * If a count is supplied, the last count events are redone. The default * count if none is given is 1. * * Results: * None. * * Side effects: * Calls the undo module. * * ---------------------------------------------------------------------------- */ void windRedoCmd(w, cmd) MagWindow *w; TxCommand *cmd; { int count; if (cmd->tx_argc > 3) { TxError("Usage: redo [count]\n"); return; } else if (cmd->tx_argc == 3) { if (strncmp(cmd->tx_argv[1], "print", 5)) { TxError("Usage: redo print count\n"); return; } else if (!StrIsInt(cmd->tx_argv[2])) { TxError("Usage: redo print count\n"); return; } else { /* Implement redo stack trace */ UndoStackTrace(atoi(cmd->tx_argv[2])); return; } } else if (cmd->tx_argc == 2) { if (!StrIsInt(cmd->tx_argv[1])) { TxError("Count must be numeric\n"); return; } count = atoi(cmd->tx_argv[1]); if (count < 0) { TxError("Count must be a positive integer\n"); return; } } else count = 1; if (count == 0) { UndoDisable(); } else { if (UndoForward(count) == 0) TxPrintf("Nothing more to redo\n"); } } /* * ---------------------------------------------------------------------------- * windRedrawCmd -- * * Redraw the screen. * * Results: * None. * * Side effects: * The screen is redrawn by calling the window package's clients. * ---------------------------------------------------------------------------- */ void windRedrawCmd(w, cmd) MagWindow *w; TxCommand *cmd; { WindAreaChanged((MagWindow *) NULL, (Rect *) NULL); } /* * ---------------------------------------------------------------------------- * windResetCmd -- * * Re-initialize the graphics device. * * Usage: * reset * * Results: * None. * * Side effects: * The graphics file is closed and reopened, and the display is reset. * ---------------------------------------------------------------------------- */ void windResetCmd(w, cmd) MagWindow *w; TxCommand *cmd; { if (cmd->tx_argc != 1) { TxError("Usage: %s\n", cmd->tx_argv[0]); return; } if (WindPackageType != WIND_MAGIC_WINDOWS) { TxError("The :reset command doesn't make sense unless you are\nusing a serial-line graphics terminal.\n"); return; } GrClose(); /* open files */ if (!GrSetDisplay(MainDisplayType, MainGraphicsFile, MainMouseFile)) { TxError("Unable to set up graphics display.\n"); return; } if (GrReadCMap(DBWStyleType, (char *)NULL, MainMonType, ".", SysLibPath) == 0) return; if (GrLoadStyles(DBWStyleType, ".", SysLibPath) != 0) return; DBWTechInitStyles(); if (!GrLoadCursors(".", SysLibPath)) return; GrSetCursor(0); WindAreaChanged((MagWindow *) NULL, (Rect *) NULL); } magic-8.0.210/windows/Makefile0000644000175000001440000000153610751423606014615 0ustar timusers# # rcsid $Header: /usr/cvsroot/magic-8.0/windows/Makefile,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ # MODULE = windows MAGICDIR = .. SRCS = windClient.c windCmdAM.c windCmdNR.c windCmdSZ.c \ windSend.c windDebug.c windDisp.c windMain.c windMove.c \ windSearch.c windTrans.c windView.c GLYPHS = windows7.glyphs windows11.glyphs windows14.glyphs windows22.glyphs FONTS = vfont.B.12 vfont.I.12 vfont.R.8 include ${MAGICDIR}/defs.mak include ${MAGICDIR}/rules.mak install-tcl: @echo --- installing glyphs to $(DESTDIR)${SYSDIR} for i in ${GLYPHS} ${FONTS}; do \ (cd $(DESTDIR)${SYSDIR} && ${RM} $$i); \ ${CP} $$i $(DESTDIR)${SYSDIR}; done install: @echo --- installing glyphs to $(DESTDIR)${SYSDIR} for i in ${GLYPHS} ${FONTS}; do \ (cd $(DESTDIR)${SYSDIR} && ${RM} $$i); \ ${CP} $$i $(DESTDIR)${SYSDIR}; done magic-8.0.210/windows/windClient.c0000644000175000001440000005300010751423606015412 0ustar timusers/* windClient.c - * * Send button pushes and commands to the window's command * interpreters. * * ********************************************************************* * * 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/windows/windClient.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "textio/textio.h" #include "utils/geometry.h" #include "windows/windows.h" #include "graphics/glyphs.h" #include "windows/windInt.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/main.h" #include "utils/macros.h" #include "utils/utils.h" #include "utils/malloc.h" #include "graphics/graphics.h" #include "utils/styles.h" #include "textio/txcommands.h" #include "utils/undo.h" /* The following defines are used to indicate corner positions * of the box: */ #define WIND_BL 0 #define WIND_BR 1 #define WIND_TR 2 #define WIND_TL 3 #define WIND_ILG -1 /* our window client ID */ global WindClient windClientID = (WindClient) NULL; extern int windBorderCmd(); extern int windCaptionCmd(), windCrashCmd(), windCursorCmd(); extern int windFilesCmd(), windCloseCmd(), windOpenCmd(); extern int windQuitCmd(), windRedrawCmd(); extern int windResetCmd(), windSpecialOpenCmd(); extern int windOverCmd(), windUnderCmd(), windDebugCmd(); extern int windDumpCmd(), windHelpCmd(); extern int windMacroCmd(), windIntMacroCmd(); extern int windLogCommandsCmd(), windUpdateCmd(), windSleepCmd(); extern int windSetpointCmd(); extern int windPushbuttonCmd(); extern int windPauseCmd(), windGrstatsCmd(); extern int windGrowCmd(); extern int windUndoCmd(), windRedoCmd(); extern int windCenterCmd(), windScrollCmd(); extern int windVersionCmd(), windViewCmd(), windXviewCmd(), windZoomCmd(); extern int windScrollBarsCmd(), windPositionsCmd(); extern int windNamesCmd(); #ifdef MAGIC_WRAPPER extern int windBypassCmd(); #else extern int windEchoCmd(), windSourceCmd(), windSendCmd(); #endif static Rect windFrameRect; static MagWindow *windFrameWindow; static int windButton = TX_LEFT_BUTTON; static int windCorner = WIND_ILG; /* Nearest corner when button went * down. */ /* * ---------------------------------------------------------------------------- * windButtonSetCursor -- * * Used to set the programmable cursor for a particular * button state. * * Results: * None. * * Side effects: * Selects and sets a programmable cursor based on the given * button (for sizing or moving) and corner. * ---------------------------------------------------------------------------- */ void windButtonSetCursor(button, corner) int button; /* Button that is down. */ int corner; /* Corner to be displayed in cursor. */ { switch (corner) { case WIND_BL: if (button == TX_LEFT_BUTTON) GrSetCursor(STYLE_CURS_LLWIND); else GrSetCursor(STYLE_CURS_LLWINDCORN); break; case WIND_BR: if (button == TX_LEFT_BUTTON) GrSetCursor(STYLE_CURS_LRWIND); else GrSetCursor(STYLE_CURS_LRWINDCORN); break; case WIND_TL: if (button == TX_LEFT_BUTTON) GrSetCursor(STYLE_CURS_ULWIND); else GrSetCursor(STYLE_CURS_ULWINDCORN); break; case WIND_TR: if (button == TX_LEFT_BUTTON) GrSetCursor(STYLE_CURS_URWIND); else GrSetCursor(STYLE_CURS_URWINDCORN); break; } } /* * ---------------------------------------------------------------------------- * windGetCorner -- * * Returns the corner of the window closest to a given screen location. * * Results: * An integer value is returned, indicating the corner closest to * the given screen location. * * Side effects: * None. * ---------------------------------------------------------------------------- */ int windGetCorner(screenPoint, screenRect) Point *screenPoint; Rect *screenRect; { Rect r; /* Find out which corner is closest. Consider only the * intersection of the box with the window (otherwise it * may not be possible to select off-screen corners. */ r = *screenRect; GeoClip(&r, &GrScreenRect); if (screenPoint->p_x < ((r.r_xbot + r.r_xtop)/2)) { if (screenPoint->p_y < ((r.r_ybot + r.r_ytop)/2)) return WIND_BL; else return WIND_TL; } else { if (screenPoint->p_y < ((r.r_ybot + r.r_ytop)/2)) return WIND_BR; else return WIND_TR; } } /* * ---------------------------------------------------------------------------- * windMoveRect -- * * Repositions a rectangle by one of its corners. * * Results: * None. * * Side effects: * The rectangle is changed so that the given corner is at the * given position. * ---------------------------------------------------------------------------- */ void windMoveRect(wholeRect, corner, p, rect) bool wholeRect; /* move the whole thing? or just a corner? */ int corner; /* Specifies a corner in the format * returned by ToolGetCorner. */ Point *p; /* New position of corner, in screen * coordinates. */ Rect *rect; { int x, y, tmp; /* Move the rect. If an illegal corner is specified, then * move by the bottom-left corner. */ if (wholeRect) { switch (corner) { case WIND_BL: x = p->p_x - rect->r_xbot; y = p->p_y - rect->r_ybot; break; case WIND_BR: x = p->p_x - rect->r_xtop; y = p->p_y - rect->r_ybot; break; case WIND_TR: x = p->p_x - rect->r_xtop; y = p->p_y - rect->r_ytop; break; case WIND_TL: x = p->p_x - rect->r_xbot; y = p->p_y - rect->r_ytop; break; default: x = p->p_x - rect->r_xbot; y = p->p_y - rect->r_ybot; break; } rect->r_xbot += x; rect->r_ybot += y; rect->r_xtop += x; rect->r_ytop += y; } else { switch (corner) { case WIND_BL: rect->r_xbot = p->p_x; rect->r_ybot = p->p_y; break; case WIND_BR: rect->r_xtop = p->p_x; rect->r_ybot = p->p_y; break; case WIND_TR: rect->r_xtop = p->p_x; rect->r_ytop = p->p_y; break; case WIND_TL: rect->r_xbot = p->p_x; rect->r_ytop = p->p_y; break; } /* If the movement turned the box inside out, turn it right * side out again. */ if (rect->r_xbot > rect->r_xtop) { tmp = rect->r_xtop; rect->r_xtop = rect->r_xbot; rect->r_xbot = tmp; } if (rect->r_ybot > rect->r_ytop) { tmp = rect->r_ytop; rect->r_ytop = rect->r_ybot; rect->r_ybot = tmp; } } } /* * ---------------------------------------------------------------------------- * Button Routines -- * * This page contains a set of routines to handle the puck * buttons within the window border. * * Results: * None. * * Side effects: * Left button: used to move the whole window by the lower-left corner. * Right button: used to re-size the window by its upper-right corner. * If one of the left or right buttons is pushed, then the * other is pushed, the corner is switched to the nearest * one to the cursor. This corner is remembered for use * in box positioning/sizing when both buttons have gone up. * Bottom button: Center the view on the point where the crosshair is * at when the button is released. * ---------------------------------------------------------------------------- */ void windFrameDown(w, cmd) MagWindow *w; TxCommand *cmd; { if (WindOldButtons == 0) { windFrameRect = w->w_frameArea; windFrameWindow = w; windButton = cmd->tx_button; } #define BOTHBUTTONS (TX_LEFT_BUTTON | TX_RIGHT_BUTTON) if ((WindNewButtons & BOTHBUTTONS) == BOTHBUTTONS) { windCorner = windGetCorner(&(cmd->tx_p), &(windFrameWindow->w_frameArea)); } else if (cmd->tx_button == TX_LEFT_BUTTON) { windCorner = WIND_BL; windButtonSetCursor(windButton, windCorner); } else if (cmd->tx_button == TX_RIGHT_BUTTON) { windCorner = WIND_TR; windButtonSetCursor(windButton, windCorner); } } /*ARGSUSED*/ void windFrameUp(w, cmd) MagWindow *w; TxCommand *cmd; { if (WindNewButtons == 0) { GrSetCursor(STYLE_CURS_NORMAL); switch (cmd->tx_button) { case TX_LEFT_BUTTON: case TX_RIGHT_BUTTON: windMoveRect( (windButton == TX_LEFT_BUTTON), windCorner, &(cmd->tx_p), &windFrameRect); WindReframe(windFrameWindow, &windFrameRect, FALSE, (windButton == TX_LEFT_BUTTON) ); break; } } else { /* If both buttons are down and one is released, we just change * the cursor to reflect the current corner and the remaining * button (i.e. move or size window). */ windCorner = windGetCorner(&(cmd->tx_p), &(windFrameWindow->w_frameArea)); windButtonSetCursor(windButton, windCorner); } } /* * ---------------------------------------------------------------------------- * windFrameButtons -- * * Handle button pushes to the window frame area (zoom and scroll) * Always handle scroll bars ourselves, even if there is an external * window package. BUT---in the Tcl/Tk version of Magic, the * window does not set WIND_SCROLLBARS, causing this routine to be * bypassed. * * Results: * TRUE if the button was pushed in the frame and handled by one * of the button handler routines, FALSE if not. * * Side effects: * Depends upon where the button was pushed. * ---------------------------------------------------------------------------- */ bool windFrameButtons(w, cmd) MagWindow *w; TxCommand *cmd; { extern void windBarLocations(); Rect leftBar, botBar, up, down, right, left, zoom; Point p; if (w == NULL) return FALSE; p.p_x = w->w_screenArea.r_xtop - w->w_screenArea.r_xbot; p.p_y = w->w_screenArea.r_ytop - w->w_screenArea.r_ybot; if ((w->w_flags & WIND_SCROLLBARS) != 0) { windBarLocations(w, &leftBar, &botBar, &up, &down, &right, &left, &zoom); if (cmd->tx_button == TX_MIDDLE_BUTTON) { if (GEO_ENCLOSE(&cmd->tx_p, &leftBar)) { /* move elevator */ p.p_x = 0; p.p_y = w->w_bbox->r_ybot + ((w->w_bbox->r_ytop - w->w_bbox->r_ybot) * (cmd->tx_p.p_y - leftBar.r_ybot)) / (leftBar.r_ytop - leftBar.r_ybot) - (w->w_surfaceArea.r_ytop + w->w_surfaceArea.r_ybot)/2; WindScroll(w, &p, (Point *) NULL); return TRUE; } else if (GEO_ENCLOSE(&cmd->tx_p, &botBar)) { /* move elevator */ p.p_y = 0; p.p_x = w->w_bbox->r_xbot + ((w->w_bbox->r_xtop - w->w_bbox->r_xbot) * (cmd->tx_p.p_x - botBar.r_xbot)) / (botBar.r_xtop - botBar.r_xbot) - (w->w_surfaceArea.r_xtop + w->w_surfaceArea.r_xbot)/2; WindScroll(w, &p, (Point *) NULL); return TRUE; } else if (GEO_ENCLOSE(&cmd->tx_p, &up)) { /* scroll up */ p.p_y = -p.p_y; p.p_x = 0; WindScroll(w, (Point *) NULL, &p); return TRUE; } else if (GEO_ENCLOSE(&cmd->tx_p, &down)) { /* scroll down */ p.p_x = 0; WindScroll(w, (Point *) NULL, &p); return TRUE; } else if (GEO_ENCLOSE(&cmd->tx_p, &right)) { /* scroll right */ p.p_x = -p.p_x; p.p_y = 0; WindScroll(w, (Point *) NULL, &p); return TRUE; } else if (GEO_ENCLOSE(&cmd->tx_p, &left)) { /* scroll left */ p.p_y = 0; WindScroll(w, (Point *) NULL, &p); return TRUE; } } if (GEO_ENCLOSE(&cmd->tx_p, &zoom)) { /* zoom in, out, or view */ switch (cmd->tx_button) { case TX_LEFT_BUTTON: WindZoom(w, 2.0); break; case TX_MIDDLE_BUTTON: WindView(w); break; case TX_RIGHT_BUTTON: WindZoom(w, 0.5); break; } return TRUE; } } return FALSE; } /* * ---------------------------------------------------------------------------- * windClientButtons -- * * Handle button pushes to the window border. * * Results: * None. * * Side effects: * depends upon where the button was pushed. * ---------------------------------------------------------------------------- */ void windClientButtons(w, cmd) MagWindow *w; TxCommand *cmd; { /* * Is this an initial 'down push' in a non-iconic window? If so, we * will initiate some user-interaction sequence, such as moving the corner * of the window or growing it to full-screen size. * * (An 'iconic' window is one that is closed down to an icon -- this * currently only happens when we are using the Sun window package, but * in the future it might happen in other cases too.) * */ if ((WindOldButtons == 0) && ((w->w_flags & WIND_ISICONIC) == 0)) { /* single button down */ Point p; Rect caption; windFrameWindow = NULL; if (w == NULL) return; p.p_x = w->w_screenArea.r_xtop - w->w_screenArea.r_xbot; p.p_y = w->w_screenArea.r_ytop - w->w_screenArea.r_ybot; caption = w->w_allArea; if ((w->w_flags & WIND_CAPTION) != 0) caption.r_ybot = caption.r_ytop - TOP_BORDER(w) + 1; else caption.r_ybot = caption.r_ytop; /* Handle 'grow' for our window package. */ if (WindPackageType == WIND_MAGIC_WINDOWS) { if ((cmd->tx_button == TX_MIDDLE_BUTTON) && GEO_ENCLOSE(&cmd->tx_p, &caption)) { WindFullScreen(w); return; } } if (windFrameButtons(w, cmd)) return; /* Otherwise, continue onward */ } /* * At this point, we have decided that the button was not an initial * button push for Magic's window package. Maybe an external window * package wants it, or maybe it is a continuation of a previous Magic * sequence (such as moving a corner of a window). */ switch ( WindPackageType ) { case WIND_X_WINDOWS: break; default: /* Magic Windows */ if (cmd->tx_button == TX_MIDDLE_BUTTON) return; if ((cmd->tx_buttonAction == TX_BUTTON_UP) && (windFrameWindow == NULL)) return; /* no special area or else an up push -- reframe window */ switch (cmd->tx_buttonAction) { case TX_BUTTON_DOWN: windFrameDown(w, cmd); break; case TX_BUTTON_UP: windFrameUp(w, cmd); break; default: TxError("windClientButtons() failed!\n"); break; } } } /* * ---------------------------------------------------------------------------- * WindButtonInFrame -- * * To be called from the graphics packages. Handle button pushes to * the window frame area (zoom and scroll) by calling windFrameButtons() * if it appears to be appropriate for this MagWindow structure. * This bypasses the key macro handler, thus hard-coding the button * actions for the frame. * * Results: * TRUE if the button was pushed in the frame and handled by one * of the button handler routines, FALSE if not. * * Side effects: * Depends upon where the button was pushed. * ---------------------------------------------------------------------------- */ bool WindButtonInFrame(w, x, y, b) MagWindow *w; int x; int y; int b; { TxCommand cmd; cmd.tx_p.p_x = x; cmd.tx_p.p_y = y; cmd.tx_button = b; if (windFrameButtons(w, &cmd)) { WindUpdate(); return TRUE; } return FALSE; } /* * ---------------------------------------------------------------------------- * * windClientInterp * * Window's command interpreter. * Dispatches to long commands, providing them with the window and command * we are passed. * * Results: * none. * * Side effects: * Whatever occur as a result of executing the long * command supplied. * * ---------------------------------------------------------------------------- */ void windCmdInterp(w, cmd) MagWindow *w; TxCommand *cmd; { int cmdNum; switch (cmd->tx_button) { case TX_LEFT_BUTTON: case TX_RIGHT_BUTTON: case TX_MIDDLE_BUTTON: windClientButtons(w, cmd); break; case TX_NO_BUTTON: if (WindExecute(w, windClientID, cmd) >= 0) UndoNext(); break; default: ASSERT(FALSE, "windCmdInterp"); break; } } /* * ---------------------------------------------------------------------------- * windCmdInit -- * * Initialize the window client. * * Results: * None. * * Side effects: * None. * ---------------------------------------------------------------------------- */ void windClientInit() { windClientID = WindAddClient(WINDOW_CLIENT, ( bool (*)() ) NULL, ( bool (*)() ) NULL, ( void (*)() ) NULL, windCmdInterp, ( void (*)() ) NULL, ( bool (*)() ) NULL, ( void (*)() ) NULL, (GrGlyph *) NULL); /* Set up all of the window commands */ #ifdef MAGIC_WRAPPER WindAddCommand(windClientID, "*bypass command run command independently of the command line", windBypassCmd, FALSE); #endif WindAddCommand(windClientID, "*crash cause a core dump", windCrashCmd, FALSE); WindAddCommand(windClientID, "*files print out currently open files", windFilesCmd, FALSE); WindAddCommand(windClientID, "*grstats print out stats on graphics", windGrstatsCmd, FALSE); WindAddCommand(windClientID, "*pause [args] print args and wait for ", windPauseCmd, FALSE); WindAddCommand(windClientID, "*winddebug set debugging mode", windDebugCmd, FALSE); WindAddCommand(windClientID, "*winddump print out debugging info", windDumpCmd, FALSE); WindAddCommand(windClientID, "center [x y] center window on the cursor or indicated coordinate", windCenterCmd, FALSE); WindAddCommand(windClientID, "closewindow [name] close a window", windCloseCmd, FALSE); WindAddCommand(windClientID, "cursor return magic coordinates of the cursor", windCursorCmd, FALSE); WindAddCommand(windClientID, "grow blow a window up to full-screen size or back again", windGrowCmd, FALSE); WindAddCommand(windClientID, "help [pattern] print out synopses for all commands valid\n\ in the current window (or just those\n\ containing pattern)", windHelpCmd, FALSE); WindAddCommand(windClientID, "imacro [char [string]] define or print an interactive macro called char", windIntMacroCmd, FALSE); WindAddCommand(windClientID, "logcommands [file [update]]\n\ log all commands into a file", windLogCommandsCmd, FALSE); WindAddCommand(windClientID, "macro [char [string]] define or print a macro called char", windMacroCmd, FALSE); WindAddCommand(windClientID, "openwindow [cell][name]\n\ open a new window with indicated name, bound to indicated cell", windOpenCmd, FALSE); WindAddCommand(windClientID, "over move a window over (on top of) the rest", windOverCmd, FALSE); WindAddCommand(windClientID, "pushbutton button act push a mouse button", windPushbuttonCmd, FALSE); WindAddCommand(windClientID, "redo [count] redo commands", windRedoCmd, FALSE); WindAddCommand(windClientID, "redraw redraw the display", windRedrawCmd, FALSE); WindAddCommand(windClientID, "reset reset the display", windResetCmd, FALSE); WindAddCommand(windClientID, "scroll dir [amount] scroll the window", windScrollCmd, FALSE); WindAddCommand(windClientID, "setpoint [x y [WID]] force to cursor (point) to x,y in window WID", windSetpointCmd, FALSE); WindAddCommand(windClientID, "sleep seconds sleep for a number of seconds", windSleepCmd, FALSE); WindAddCommand(windClientID, "specialopen [coords] type [args]\n\ open a special window", windSpecialOpenCmd, FALSE); WindAddCommand(windClientID, "quit exit magic", windQuitCmd, FALSE); WindAddCommand(windClientID, "underneath move a window underneath the rest", windUnderCmd, FALSE); WindAddCommand(windClientID, "undo [count] undo commands", windUndoCmd, FALSE); WindAddCommand(windClientID, #ifdef MAGIC_WRAPPER "updatedisplay [suspend|resume]\n\ force display update, or suspend/resume updates", #else "updatedisplay force the display to be updated", #endif windUpdateCmd, FALSE); WindAddCommand(windClientID, "version print out version info", windVersionCmd, FALSE); WindAddCommand(windClientID, "view [get] zoom window out so everything is visible", windViewCmd, FALSE); WindAddCommand(windClientID, "windowborder [on|off] toggle border drawing for new windows", windBorderCmd, FALSE); WindAddCommand(windClientID, "windowcaption [on|off] toggle title caption for new windows", windCaptionCmd, FALSE); WindAddCommand(windClientID, "windowscrollbars [on|off]\n\ toggle scroll bars for new windows", windScrollBarsCmd, FALSE); WindAddCommand(windClientID, "windowpositions [file] print out window positions", windPositionsCmd, FALSE); WindAddCommand(windClientID, "xview zoom window out so everything is unexpanded", windXviewCmd, FALSE); WindAddCommand(windClientID, "zoom amount zoom window by amount", windZoomCmd, FALSE); WindAddCommand(windClientID, "windownames [all|type] get name of current or all windows", windNamesCmd, FALSE); #ifndef MAGIC_WRAPPER WindAddCommand(windClientID, "echo [-n] [strings] print text on the terminal", windEchoCmd, FALSE); WindAddCommand(windClientID, "send type command send a command to a certain window type", windSendCmd, FALSE); WindAddCommand(windClientID, "source filename read in commands from file", windSourceCmd, FALSE); #endif } magic-8.0.210/windows/vfont.I.120000644000175000001440000002201710751423606014641 0ustar timusers@(|||ø|t ÷þzü€ûüˆû šû ¬›!G›"âóý ô:þ. òý76ùþm0ùþ.ýüËcÿ.cþ‘fÿ÷û òùWþuKüÀ\ýEüañ÷ hDú¬Dÿð÷÷ 9üCü J ÷þ Nü QBú“EûØ,úHýLEü‘BüÓBü Hû] Eø¢ Hüê Eû/ û ? ý S <ü ûü­ <üé .ý Eý\ Hÿ¤ `þ HúL Hþ” `þô `þT Húœ `þü 0þ ,Hýt`þÔHþ`þ|`þÜHú$`þ„WúÛ`þ;HýƒHùËHùHù[Hø£`ÿHùKHý“"ü µ,ýá"ý öýüñü !0ýQ.ü ýŸEýä ý]aHÿ©Eþî.ÿ > ZEþŸ.ý Í@þ"# 0ÿ= ý]H¥0ýÕ0ÿ þ%.ýS0ÿƒ0ÿ³@þó0þ#Hÿk ý‹"û ­"üÏ!û ð÷ýþ瀃€ÀÀÿþÿÿ0ppp` àààÀÀ8À8À8€9€€€€€ççîüøÿ瀀€€8ÿÿÿÿppp`` ààÀÀÀ8À8€8€9€€€€€ãçæüø~ÿÿƒ÷çÂÀÀ€ÿÿü8€880ppp`àà ààÀÀÀÀ8€8€0sŽp÷àîÀ|€ÿÿüÿÿüÿÿÀÿÿÀÿÿÿàÿÿÿà>ÿ€ÿ€ÿ€ÿ€ÿ€€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€à|ùÿ€?ÀàgñÃðà0p00`À€ 0`À€ 00p```ÀÀÀÀÀÀÀÀÀ`` 0`00 00p`àÀ€ 0`ÀÀ€€3¸{øà?à÷ðîà ````````ÿÿàÿÿà`````````àà` `@ÀÿÀÿÀàà@ @À€0`À€ 0`@€ÿÀ€ÀÀ ÀÀÀ0À0€p€p€`€```ààà`8pp9à0ð°p```ÀÀÀÀ€€€ÿà?àÀp880pàÀ<à€ 0€ €`€~€Ãþ€üÿÀà```à ÀÀ€~€€€ €pðÀ@@xxÀ€7fƆ  0`ÿÿÀ000p``üÿð ü€0€€€€€ €pðÀ@@8xð€€àÀ€@ÀÀ €8ø3ž~xpààÀÀÀÀ à<`pyà€_Á€`óÀ?À€€ 0`à€ 8000`?€ààÀ`€```àÀÀ€þ€8€p€p€`€`àà``xxÀÿÇ€ÀÀ ÀÀ8À8À8À8€8€€ €ó pðÀxÀàãÀ> Àà€0800`ÀÀ€<pÀ8àp€Àp€ÀÿÿàÿÿàÿÿàÿÿààpÀ`8ÀÀpà€8`Àà8p`8Ààà `8pà€ÿÀ p0`þÌAÃÄCÆÃƒ‚‡‚†‚†‚ƆG„CƒŒaýø 00àÇ€|ÀÀÀÀÀÀ ÀÀÀÀ À`À@ÀÀà€ààÿààà à```ÿøÿÿ0€0€`€`À`€à€ÀÀÀ€xÿø€€     8p à Àÿþ€àà€888080```àÀÀÀÀÀ€àà`p<ð€ÿø00```àÀÀÀ€€€€ 8ppà € ÿøÿÿÀ0€0€`€`€`àÀ€À€Áÿƒ‚00 p `ÿÿàÿÿÀ0€0€`€`€`àÀ€À€Áÿƒ‚ ÿ€Àà`€888080```àÀÀøÀ€À€À€à€à`p<ö†ÿø0À0À`À`À`€à€À€ÀÀ€ÿÿ€€    8 0ÿþÿ00```àÀÀÀ€€€€ ÿ€?à 800p`0`p`pàÀÀÁÀÀw<ÿø0€0```0à`Á€ÃÆŽ¿ãÀ€ÀÀÀÀà` p pÿüÿ00```àÀÀÀ€€€€  `` À ÀÿÿÀÿø0`0àpàpàxÀøÀ¸À¸ €˜ €€3€#cdž†  ÿÿðð8€8€X€L€L̆††„„ŒÈÈÈøp pp ÿ €Áà€àp0008000p0`0`pà`ààÀÀÀÀÀ€À€àà`p8<ð€ÿÿ0€0€`€`À`€à€À€ÀÀ€€xÿÀ€ ÿ€€Áà€àp0008000p0`0`pà`ààÀÀÀÀÃÁ€Îc€è'ð7p>p8<ð 02v~<ÿþ0€0€`€`À`€à€ÀÀÀ€xÿÀ€€ÀÀÀÀÀÀÄä ü øÿ€pâÀ€   àøÀÀà`` ` @0@pÀp€xOƒð?ÿà `````@`@@à@ÀÀ@€À@À€€€€ ÿ?à   0  0 0`0@p@`À`€`€àààpp<ð€ÿü`@€€   0 ` @ € €  ÿ~,(08h 8X`0Ø@0˜@1€1€3€264|x4h8p8p8`0`0@ @ üðp08 0` À€3#€C€€€ÀÀÀàÿøÿ€ü0 `À€  À€€€ €ÿþ€ 0pàÀ€ 8pàÀ€ @@À8Àp€`€ÿÿ€ÿÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÿÀ@` 0 €€À@`00 ÿÿÀðøp€àÀÿÿàÿÿà`À€àà`Ãç<78ppààÀÀÀ8À8`àx`àøÀ{ù€?¿|88;Àð~xx8ððàÀÀÀ<À8Àxàpððyà?Ààø<xpàààÀÀÀÀà0àpqà?ÀÀÀÀ€€€€Çç<78p`ààÀÀÀ8À8`Àxà`yÀqù€?¿àø<8p`à8àðÃÀÿðÀÀ`0pà?Àðøøp0ÿÀÿÀ<<888xppppààààÀÀÀa€s€÷~<ðÀùÀ €€€€8800000|ü8À8àpàpÀàÀ?x üŽ<<88p p`0à0à`àÀÀÀÀàà?c€c€ƒ€ƒ  0 0`à àð0 0 000ppàààÀÀÀÀ€€€Çïîüð  ?€7€Ã8À??3€s€s€aÁ€áÀàÃàîÀü> 888ppp`ààá€ÃÇîü<€~?àÇøpÇÁð0‡€à0À0Àp€p€`€ààÁÃ8Ã8î0ü?€cáÀcààƒÀ`‡€à€àÀÀ€€† †Œ˜øÀà<88p`ààÀÀÀ8À8Àp`pqà?ÀÃÀïð |8 xpð à àÀÀÀ8à8àp p¹àÀÿ€ÿ€Ãç<68p`ààÀÀÀ8À8Àx`pqð?ð``ààÀÀøø?€cã€c瀃Ç€€ àø8 0 <?€àðp0ÀÀðpà€ÿàÿà880ppp€a€a€w~0?pc€pc€`ƒ€àƒààÀÀ€€ † †Œ;˜ñøÀ?Àc€Àc€Àƒ€@ƒÀÀ€€€   8ð@`?ÀàgÀ`ÃÀ`ƒÀ ‡À À`€`€@€À À À € ƒ;Îñüƒ€ÏÀ9ÝÀ0ûÀ`ñ€@ààÀÀÀÀÁ€çÀïÃýÎøü0?pc€pc€`ƒ€àƒààÀÀ€€ € €?÷08808ðÀÃ?þp>`@8pà€p|Ïøƒø 0``ÀÀÀÀÀ``08`00```ÀÀÀÀà``0ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ`00`À`00ÀÀ`000`À>€cÀÀð0€x`€à€Àmagic-8.0.210/windows/windows.h0000644000175000001440000003050010751423606015011 0ustar timusers/* * windows.h -- * * Interface definitions for Magic's window manager. This * package manages a set of overlapping windows. * * ********************************************************************* * * 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. * * ********************************************************************* * * rcsid $Header: /usr/cvsroot/magic-8.0/windows/windows.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ * */ #ifndef _WINDOWS_H #define _WINDOWS_H #include "utils/magic.h" #include "utils/geometry.h" /* SUBPIXELBITS represents a fixed-point shift for representing the */ /* scale factor between the screen and the layout. It is only */ /* necessary that the screen resolution * SUBPIXEL does not overflow */ /* type (int). The original value of 12 has become too small for */ /* large chips on nanometer grids, so it has been upped to 16. */ #define SUBPIXELBITS 16 #define SUBPIXEL (1 << SUBPIXELBITS) #define HSUBPIXEL (1 << (SUBPIXELBITS - 1)) typedef ClientData WindClient; /* A unique ID of a client of the * window package. The value 'NULL' is * indicates an invalid value. */ /* * The following structure describes a window. Windows are overlapping * rectangles. Each window contains a 'surface', whose contents are maintained * by a client of the window package. The client is responsible for redrawing * the surface when requested. The window package maintains the transform * from surface coordinates to screen coordinates and also controls which * portion of the surface is currently visable in the window. See the * comments in windMain.c and above the proc 'WindAddClient' for more info. * * To see an example of a simple window client, look at the colormap window * located in 'cmwind/CMWmain.c'. A more complex window is the layout window, * located in 'dbwind/DBWprocs.c'. * * The following key letters in parens after a field indicate who should * read & write it: * * P - Private (window package use only). * R - Read-only (clients should not modify this, but may read it). * W - Writable by client at any time. * C - Writable by the client only during window creation time (in the * create proc passed to WindAddClient) and readable at all times. * L - Writable by the client at creation time and when the window is * loaded with a new surface. * G - Private to the graphics module. * * The comments below often mention a procedure that sets a given field. This * is the normal procedure used to set the field, but there may be other seldom * used procs in the window package that set the field. */ typedef struct WIND_S1 { struct WIND_S1 *w_nextWindow; /* A doubly-linked list (P) */ struct WIND_S1 *w_prevWindow; /* A doubly-linked list (P) */ ClientData w_clientData; /* Used by the client an any manner (W) */ WindClient w_client; /* The client of this window (R) */ char *w_caption; /* The caption at the top of the window. (R) * Set via WindCaption(). */ ClientData w_surfaceID; /* A unique ID for this surface, other than * NULL. (R) * Set via WindLoad(). */ Rect w_allArea; /* The entire area of the window in the screen * coordinates for the window, including the * border and obscured areas. (R) * * If we are using Magic's window package, * then this field is equal to w_frameArea * since all windows share the same coordinate * system. In SunWindows, the lower-left * corner of this area is at (0, 0) because * each Sun window has it's own coordinate * system with the origin in the lower left * corner. * * This field is recomputed by WindReframe(). */ Rect w_frameArea; /* The location of the window on the screen (C) * If a window's create proc modifies this, it * needs to set w_allArea and w_screenArea by * calling WindSetWindowAreas(). * * Also, see comments for w_allArea. * * This field is initialized to a reasonable * value at window creation time, but the * 'reposition' proc passed to WindAddClient * has a way of overriding it. */ Rect w_screenArea; /* The area of the window in the screen * coordinates of the window -- not including * the border but including obscured areas. (R) * * This field is recomputed by WindReframe(). */ Rect w_surfaceArea; /* An area in surface coordinates that * is large enough to contain everything * displayed in w_screenArea plus at least * one pixel of border on all sides. (R) * This field, and w_origin and w_scale below, * are modified by procedures that move and * scroll windows, e.g. WindMove and WindScroll. */ Point w_origin; /* This screen point, in 1/SUBPIXEL pixels, * corresponds to w_surfaceArea.r_ll. * Used to transform between surface and screen * coordinates. (R) */ int w_scale; /* Defines how many 1/SUBPIXEL of a pixel * correspond to 1 world unit. Used to * transform between surface and screen * coordinates. (R) */ LinkedRect *w_clipAgainst; /* A linked list of areas which obscure * portions of this window. (R) * Normally clients just pass this down to the * graphics package. * Changed via WindOver(), WindUnder(), and * WindFullScreen(). */ Point w_stippleOrigin; /* A point that serves as the origin (in screen * coordinates) of stipple patterns within * this window. (R) * This field is maintained for the benifit of * device drivers, but is often unused. */ int w_flags; /* A collection of flag bits: * * WIND_SCROLLABLE (C) * WIND_SCROLLBARS (C) * WIND_CAPTION (C) * WIND_BORDER (C) * WIND_COMMANDS (C) * WIND_FULLSCREEN (P) * WIND_OFFSCREEN (P) * WIND_ISICONIC (P) * WIND_REDRAWICON (P) * WIND_OBSCURED (G) * * Note: It is an error for a client to set * WIND_SCROLLBARS but not WIND_SCROLLABLE. * If WIND_SCROLLABLE is set, then the client * must fill in the pointer w_bbox; */ Rect w_oldArea; /* If the window has been blown up to full- * screen size, this records its old area so * it can be shrunk back later. (P) */ int w_oldDepth; /* If the window is full-screen, this records * its old depth on the list of windows, so * it can be put back where it came from. (P) */ Rect *w_bbox; /* A pointer to the bounding box of the stuff * in this window. Used for WindView() and for * scroll bars. (L) * This MUST be set if WIND_SCROLLABLE is set. */ int w_wid; /* The window ID for this window. Windows are * assigned small non-negative integers for * easy reference. (R) * Set at window creation time. */ ClientData w_grdata; /* Data private to the graphics package. (G) * Often used to contain variables needed to * interface to SUNs window package. */ ClientData w_backingStore; /* Specific data private to the graphics * package. Used to save and restore the * image under the cursor for fast redraw. */ char *w_iconname; /* Short name for the icon. */ ClientData w_redrawAreas; /* List of areas that need to be redrawn. (P) * Set by WindAreaChanged(), cleared by * WindUpdate(). Initialized by * WindSeparateRedisplay(). */ } MagWindow; /* Window flags, for w->w_flags */ #define WIND_FULLSCREEN 0x001 /* Set if the window has been blown up to * full-screen size. */ #define WIND_OFFSCREEN 0x002 /* Set if the window is to be rendered off- * screen (i.e., onto a pixmap) */ #define WIND_COMMANDS 0x004 /* Set if the window accepts the standard * set of window commands */ #define WIND_SCROLLABLE 0x008 /* Set if the window can scroll & zoom. */ #define WIND_SCROLLBARS 0x010 /* Set if the window has scroll bars. */ #define WIND_CAPTION 0x020 /* Set if the window displays its own caption. */ #define WIND_BORDER 0x040 /* Set if the window should display a border * (includes scrollbars and caption area) */ #define WIND_ISICONIC 0x080 /* Set if the window is closed down to an * icon (on Suns only) */ #define WIND_REDRAWICON 0x100 /* The icon needs to be redrawn. */ #define WIND_OBSCURED 0x200 /* The window is partially or fully obscured */ /* Special values for Window IDs. Some procedures that expect a Window ID will * also accept one of these flags instead. */ #define WIND_UNKNOWN_WINDOW -2 /* We should pick one by looking at * the location of the point. */ #define WIND_NO_WINDOW -3 /* Use NULL for the window */ /* utility procs & special stuff */ extern MagWindow *WindCreate(); extern WindClient WindGetClient(); extern WindClient WindNextClient(); extern WindClient WindAddClient(); extern void WindInit(); extern void WindUpdate(); extern void WindDrawBorder(); extern void WindOutToIn(); extern void WindInToOut(); extern void WindSetWindowAreas(); extern void windFixSurfaceArea(); extern int WindExecute(); extern void WindAddCommand(); extern int WindReplaceCommand(); extern char **WindGetCommandTable(); extern int windCheckOnlyWindow(MagWindow **, WindClient); /* searching procs */ extern int WindSearch(); extern MagWindow *WindSearchWid(); extern MagWindow *WindSearchData(); /* procs for moving the surface inside of a window (changing the view) */ extern void WindZoom(); extern void WindMove(); extern void WindView(); extern void WindScroll(); /* procs for moving the window itself */ extern void WindOver(); extern void WindUnder(); extern void WindReframe(); extern void WindFullScreen(); /* procs to transform into and out of screen coordinates */ extern void WindScreenToSurface(); extern void WindSurfaceToScreen(); extern void WindPointToSurface(); extern void WindPointToScreen(); extern void WindSurfaceToScreenNoClip(); /* procs to change things or inform the window manager about changes */ extern void WindCaption(); extern void WindAreaChanged(); extern void WindIconChanged(); extern bool WindLoad(); extern void WindSeparateRedisplay(); /* handler for window buttons in the scrollbar/zoom (non-wrapper) frame */ extern bool WindButtonInFrame(); /* interface variables */ extern int WindDefaultFlags; /* Mask of properties applied to new windows */ extern int WindNewButtons; /* A mask of the buttons that are down now. */ extern int WindOldButtons; /* The buttons that were down on the previous * command. */ extern Point WindCommandPoint; /* The point for the current command. */ extern bool WindAnotherUpdatePlease; /* Set by a client during redisplay if it * discovers that more stuff needs to be * displayed, and wants the window package * to do another WindUpdate(). Used by * dbwind in dbwhlRedrawFunc() when it suddenly * discovers that drawing feedback areas * requires that all the mask geometry be * redrawn. */ /* Macro to set the maximum number of windows */ #define WIND_MAX_WINDOWS(x) (windMaxWindows = MIN(windMaxWindows, (x))) extern int windMaxWindows; /* Use above macro, never increase this! */ /* The type of windows that we will implement. This variable must be set by * the graphics package before WindInit() is called. */ extern int WindPackageType; #define WIND_MAGIC_WINDOWS 0 #define WIND_X_WINDOWS 1 /* Scroll bar width. * May be set by the graphics package before WindInit() is called. * If the width is XX, the window package tries to load glyphs from * the file 'windowsXX.glyphs' located in $CAD_ROOT/magic/sys. This file * contains the arrow for the scroll bars, and those icons should be of * this width. */ extern int WindScrollBarWidth; /* Global identifier for the window client structure */ extern WindClient windClientID; #endif /* _WINDOWS_H */ magic-8.0.210/windows/windDebug.c0000644000175000001440000001110210751423606015217 0ustar timusers /* windDebug.c - * * Print out the window package's internal data structures. * * ********************************************************************* * * 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/windows/windDebug.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "windows/windows.h" #include "graphics/glyphs.h" #include "windows/windInt.h" #include "textio/textio.h" #include "textio/txcommands.h" /* * ---------------------------------------------------------------------------- * windPrintWindow -- * * Print out the window data structure. * * Results: * None. * * Side effects: * Text appears on the text terminal. * ---------------------------------------------------------------------------- */ void windPrintWindow(w) MagWindow *w; { LinkedRect *lr; TxPrintf("\nWindow %d: '%s'\n", w->w_wid, w->w_caption); TxPrintf(" Client %x Surface %x \n", w->w_client, w->w_surfaceID); TxPrintf(" All area (%d, %d) (%d, %d)\n", w->w_allArea.r_xbot, w->w_allArea.r_ybot, w->w_allArea.r_xtop, w->w_allArea.r_ytop); TxPrintf(" Screen area (%d, %d) (%d, %d)\n", w->w_screenArea.r_xbot, w->w_screenArea.r_ybot, w->w_screenArea.r_xtop, w->w_screenArea.r_ytop); TxPrintf(" Frame area (%d, %d) (%d, %d)\n", w->w_frameArea.r_xbot, w->w_frameArea.r_ybot, w->w_frameArea.r_xtop, w->w_frameArea.r_ytop); if (w->w_clipAgainst == NULL) TxPrintf(" No areas obscure the window.\n"); else TxPrintf(" These areas obscure the window:\n"); for (lr = w->w_clipAgainst; lr != NULL; lr = lr->r_next) { TxPrintf(" (%d, %d) (%d, %d) \n", lr->r_r.r_xbot, lr->r_r.r_ybot, lr->r_r.r_xtop, lr->r_r.r_ytop); } TxPrintf(" Surface area (%d, %d) (%d, %d) \n", w->w_surfaceArea.r_xbot, w->w_surfaceArea.r_ybot, w->w_surfaceArea.r_xtop, w->w_surfaceArea.r_ytop); TxPrintf(" Origin (%d, %d)\n", w->w_origin.p_x, w->w_origin.p_y); TxPrintf(" Scale %d\n", w->w_scale); } /* * ---------------------------------------------------------------------------- * windDump -- * * Print out all the tables and windows. * * Results: * None. * * Side effects: * Lots of text is dumped to the text terminal. * ---------------------------------------------------------------------------- */ void windDump() { MagWindow *w; clientRec *rc; TxPrintf("\n\n------------ Clients ----------\n"); for (rc = windFirstClientRec; rc != (clientRec * ) NULL; rc = rc->w_nextClient) { TxPrintf("'%10s' %x %x %x %x\n", rc->w_clientName, rc->w_create, rc->w_delete, rc->w_redisplay, rc->w_command); } TxPrintf("\n"); for (w = windTopWindow; w != (MagWindow *) NULL; w = w->w_nextWindow) { windPrintWindow(w); } } /* * ---------------------------------------------------------------------------- * windPrintCommand -- * * Print out a command. * * Results: * None. * * Side effects: * Text appears on the text terminal. * ---------------------------------------------------------------------------- */ void windPrintCommand(cmd) TxCommand *cmd; { if (cmd->tx_button == TX_NO_BUTTON) { int i; for (i = 0; i < cmd->tx_argc; i++) { TxPrintf(" '%s'", cmd->tx_argv[i]); } } else { switch (cmd->tx_button) { case TX_LEFT_BUTTON: TxPrintf("Left"); break; case TX_RIGHT_BUTTON: TxPrintf("Right"); break; case TX_MIDDLE_BUTTON: TxPrintf("Middle"); break; default: TxPrintf("STRANGE"); break; } TxPrintf(" button "); switch (cmd->tx_buttonAction) { case TX_BUTTON_DOWN: TxPrintf("down"); break; case TX_BUTTON_UP: TxPrintf("up"); break; } } TxPrintf(" at (%d, %d)\n", cmd->tx_p.p_x, cmd->tx_p.p_y); } magic-8.0.210/windows/windows11.glyphs0000644000175000001440000000271610751423606016242 0ustar timusers# # 11-pixel sized glyphs for the window package # # rcsid $Header: /usr/cvsroot/magic-8.0/windows/windows11.glyphs,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ # # syntax of first line: size size 5 11 11 #up W W W W W W W W W W W W W W W W K W W W W W W W W W K K K W W W W W W W K K K K K W W W W W K K K K K K K W W W K K K K K K K K K W W W W W K K K W W W W W W W W K K K W W W W W W W W K K K W W W W W W W W K K K W W W W W W W W W W W W W W W #down W W W W W W W W W W W W W W W K K K W W W W W W W W K K K W W W W W W W W K K K W W W W W W W W K K K W W W W W K K K K K K K K K W W W K K K K K K K W W W W W K K K K K W W W W W W W K K K W W W W W W W W W K W W W W W W W W W W W W W W W W #left W W W W W W W W W W W W W W W W K W W W W W W W W W K K W W W W W W W W K K K W W W W W W W K K K K K K K K W W K K K K K K K K K W W W K K K K K K K K W W W W K K K W W W W W W W W W K K W W W W W W W W W W K W W W W W W W W W W W W W W W W #right W W W W W W W W W W W W W W W W K W W W W W W W W W W K K W W W W W W W W W K K K W W W W K K K K K K K K W W W K K K K K K K K K W W K K K K K K K K W W W W W W W K K K W W W W W W W W K K W W W W W W W W W K W W W W W W W W W W W W W W W W #zoom W W W W W W W W W W W W W W W W W W W W W W W W K K K K K K K W W W W K W W W W W K W W W W K W W W W W K W W W W K W W K W W K W W W W K W W W W W K W W W W K W W W W W K W W W W K K K K K K K W W W W W W W W W W W W W W W W W W W W W W W W magic-8.0.210/windows/vfont.R.80000644000175000001440000001264210751423606014602 0ustar timusers˜ @( ÿ ÿ@ ÿ`ûÿdý hýýk ýq ýw0þ§0þ×øþ Þ(ÿ ÷þ üÿ $üþ <þý Z,ÿ†,ÿ²,ÿÞýí÷þ ó(þ"þ = þ] þ}öý‚ý ™þ ° ûü º ýÔýÚûÿ Üýßü ý þ ü , þ L þ lÿ Šþ ¨ þ È þ è þ  þ ( ý3 ýA ý] ýýk þ‡ þ § þÇ"ÿé"þ "þ-"þO"þq"þ“"þµ"þ×þè"þ "þ,"þ N"þp"þ’"þ´"þÖ*þ"þ""þ D"þ f"þˆ"ª3ÿÝ"ÿ32"þ Tý kþ ‰þ   úþªý®öý² þ È"ÿ ê þ "þ"  þ 8 ÿ H ÿ h "ÿŠ ÿš ÿ¯ "ÿÑ ÿâ ! þ  ÿ  þ / ÿ O þo  ÿ …  þ › ÿ ¹  ÿÏ  ÿ å  ÿû  ÿ  ÿ 1  þ G ü ^ ýu ü Œ ûþÀppÿð000000000üüÀpp00ÿð000000000üüÎ~v00ÿü000000000üüÿþÿþÿðÿðÿÿÀ|üþþü|þþþþþþ€üÀ8ðÀ0` `ÿÿà `` `` `` `` `` `` `` `` ``ùùðýà8ñà0`` ``ÿÿà `` `` `` `` `` `` `` `` ``ùùð8̆‚†ì8 %ÿÀe€ ``ÀÀ€€?ÀàwpϰݰØ0Ù°ÿ°ðxð?à€€áÀÞàß`Ÿ`Ÿ`Ÿ`ÛàààÿÀ?€ ?í€Ï€Ï€ÌÌÌ̀퀀> ðð08000p0`0À1À1€ÿàÿàààààà>à?øpà`àÀàÃððð00000`0`0À1À1€ÿøÿüÌÌ 8p0àpÀ`ÀÀüÀ|ÿÇÃ80pðàÀÃÀÿààààààà>à?øpà`àààÃðÀÀÀÀÀÀÀÀÀ@ÀÀÀcc‚``@@ À À€ð€€ÿà3#""ffDD jÀÊ`ŠàÊ@ê~€ À à Ê ê Ê`kÀ0ÿø„„0Ì`xÀ€ xÌ0„`ŒÀØ€p <6 c ÃàÁÀÀÀÁäãt>ÀÀ@@À 0```ÀÀÀÀÀÀÀÀÀÀ@` 0À` 0 00`À€8ºþ|þö88ÿøÿøÀÀÀ@À€þþÀÀÀ€€ 00``À€?€`À`ÀÀ@À`À`À`À`À`À`ÀÀ`À`À;€8xØþ€sÀÀàÀ`à`àÀ€8`À € ø`À‡À?ÀÀÀÀÀàÀÀ€€À``à`À`ÀàaÀ€€€€ €€€1€a€A€ÿð€€€àÀ@@@ÿá€ÀÀ```à`ÀàÀÀc€€=ÀpÀ`À`€À߀ñÀàÀÀ`À`À`Àà`À;€8þ`Çà€`€@À€ ?€`À`À`À`À`À€{ÀàÀÀ`À`À`À`ààqÀ?€`ÀÀàÀ`À`À``àqà?```À`ÀaÀc€>ÀÀÀÀÀÀÀÀÀÀ@À€pÀ xàà0À`0ÿøÿøÿø@p€à88`Àpà>w€Á€À€à€€€  Àx0 `GòÎ2Œ3ˆ1ˆ3ˆ2ÌbOþ`0 8À€€ €ÀÀÀ`à0` 0 0`0ø|ÿÀ p 8    8 p?ð 0     8 pÿÀà80``àÀÀÀÀÀà``00à€ÿ€ À ` 0 0        8 0 p àÿ€ÿð 0   !!!?!!!    ÿðÿð 0   !!!?!!! ü€à80`0`àÀÀÀÀÀþà0`0`000ð°ü~       ?ø       ü~ü ü?€„ÄŒŒÌxü>  0 ` À!€#&/;€1€ À à ` 0 8ü~ü ÿàü?0 0088,(,,,,l,L&L&Œ&Œ#Œ#Œ# ù?à~088,.&'#!!Ð Ð p p 0 0øÀ0``0`0`ÀÀÀÀÀ``0`00pà€ÿÀ p 8     0?ð üÀ0``0`0`ÀÀÀÀÀfo°x°0ðàÀhxx0ÿÀ ð 8    8 p?À € À À ` ` | <ü8yàÀ`€ À à x?Àà`€ À À à øà€ÿà„ „ „ „ „ ?€ü>           0080`€ü?0  0   @@À€€€üŸ€0Æ1Ä1ÄDDdlhh888 00ü?8 0 `À€€€À` `080|>þ€8  `@À€€€€€€€àÿàÀ`ÀàÀÀ€€  8 0 ` à ÿàøÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀüÀÀ` 0 €€€ü ü€9ÀpðÀÿøÿøÀ€ÀÀ?a€`€€?€à€À€À€ÁÀãà>`ðÀàp00pà€1€`ÀÀÀÀ€ÀÀÀ`À9€ÀÀÀÀÀÀÀ1À`ÀÀÀÀÀÀÀÀÀÀÀ`À;Àð1€`ÀÀÀÿÀÀÀÀ`À9€þü`à0À0À0À0À9€o@pÀ@àÀ À pà€ðàp00000000üü00ðüxØðàðø`À€€ÀàpüøðüïÏ€8øÀ0`À `@ `@ `@ `@ `@ `@ `@ùùø÷àp00000000üü1€`ÀÀ`À`À`À`Àà`À;€÷Ààp00pà€üÀ1À`ÀÀÀÀÀÀÀÀÀÀÀ`À;ÀÀÀÀÀÀðóÀÀÀü~€Ã€€à€|€€À€ã€¾þ€€ðð0000000pð¼ùð`@0À0€€ýŸ1„1ÌÈÈXp p p 0 ýð8`À € €À0`ýðýð0`0@@À € €Lø`ÿ€Á€ƒ† 0€`€à€ÿ€ `À€€€€À` àà `À€€€€ÀÀ` €€€€€€€€€€€€€€€€€€€€€€€€à` ``À€àà€À`` ``À€8~Ç ƒØø€pmagic-8.0.210/windows/windTrans.c0000644000175000001440000003001010751423606015257 0ustar timusers /* windTransform.c - * * Routines to transform from screen coords to surface coords and the * other way. * * ********************************************************************* * * 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/windows/windTrans.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "windows/windows.h" #include "graphics/glyphs.h" #include "windows/windInt.h" /* * ---------------------------------------------------------------------------- * WindScreenToSurface -- * * Convert a rectangle in screen coordinates to surface coords. * * Results: * None. * * Side effects: * Returns a rectangle that is big enough to fully contain everything * that is displayed in the screen rectangle. * ---------------------------------------------------------------------------- */ void WindScreenToSurface(w, screen, surface) MagWindow *w; /* Window in whose coordinates screen is * is defined. */ Rect *screen; /* A rectangle in screen coordinates */ Rect *surface; /* A pointer to a rectangle to be filled * in with a rectangle in surface coords that * is big enough to contain everything * displayed within the screen rectangle. */ { Rect r; WindPointToSurface(w, &(screen->r_ll), (Point *) NULL, surface); WindPointToSurface(w, &(screen->r_ur), (Point *) NULL, &r); surface->r_ur = r.r_ur; } /* * ---------------------------------------------------------------------------- * WindPointToSurface -- * * Take a point in screen coordinates and find the nearest point * in surface coordinates. Also return a box in surface coords * that completely surrounds the pixel. * * Results: * None. * * Side effects: * The parameters surfaceBox and surfacePoint are modified, if * they are non-NULL. The box is always at least 1x1, but it * will be larger if the scale is so coarse that a single screen * coordinate is more than one surface coordinate. In this case * the box is large enough to include every surface coordinate * that can map to the given pixel (this feature is essential * if WindScreenToSurface is to use this routine). * * ---------------------------------------------------------------------------- */ void WindPointToSurface(w, screenPoint, surfacePoint, surfaceBox) MagWindow *w; /* Window in whose coordinate system the * transformation is to be done. */ Point *screenPoint; /* The point in screen coordinates. */ Point *surfacePoint;/* Filled in with the nearest surface coordinate. * Nothing is filled in if the pointer is NULL. */ Rect *surfaceBox; /* Filled in with a box in surface coordinates that * surrounds the point. It is not filled in if this * is a NULL pointer. */ { int tmp, adjust, unitsPerPixel; /* Do the inverse transformation twice, once with rounding for * the point and once with truncation for the box. */ unitsPerPixel = SUBPIXEL/w->w_scale; if (surfaceBox != NULL) { tmp = (SUBPIXEL*screenPoint->p_x) - w->w_origin.p_x; if (tmp < 0) tmp -= w->w_scale-1; surfaceBox->r_xbot = w->w_surfaceArea.r_xbot + tmp/w->w_scale; surfaceBox->r_xtop = surfaceBox->r_xbot + unitsPerPixel + 1; tmp = (SUBPIXEL*screenPoint->p_y) - w->w_origin.p_y; if (tmp < 0) tmp -= w->w_scale-1; surfaceBox->r_ybot = w->w_surfaceArea.r_ybot + tmp/w->w_scale; surfaceBox->r_ytop = surfaceBox->r_ybot + unitsPerPixel + 1; } if (surfacePoint != NULL) { adjust = w->w_scale/2; tmp = (SUBPIXEL*screenPoint->p_x) - w->w_origin.p_x; if (tmp >= 0) tmp += adjust; else tmp -= adjust; surfacePoint->p_x = w->w_surfaceArea.r_xbot + tmp/w->w_scale; tmp = (SUBPIXEL*screenPoint->p_y) - w->w_origin.p_y; if (tmp >= 0) tmp += adjust; else tmp -= adjust; surfacePoint->p_y = w->w_surfaceArea.r_ybot + tmp/w->w_scale; } } /* * ---------------------------------------------------------------------------- * * WindSurfaceToScreen -- * * This procedure transforms a rectangle in surface coordinates * to a rectangle in the screen coordinates of a particular window. * * Results: * None. * * Side effects: * The rectangle pointed to by screen is filled in with the * coordinates (in pixels) of the screen area corresponding * to surface. A pixel is included in screen if it is * touched in any way by surface. If any of the edges of * screen is outside w->w_surfaceArea, the corresponding * edge of the result will also be outside w->w_screenArea. * * Design Note: * This procedure is trickier than it looks, for a couple of * reasons having to do with numerical accuracy. The * transformation is done in units of 1/SUBPIXEL pixel (fix-point * arithmetic), in order to avoid accumulated round-off error * when there are fractional pixels per surface unit. Furthermore, * it's important that the transformation to screen units NOT be * done with a procedure like GeoTransRect. The reason is that * GeoTransRect does the multiplication before the addition or * subtraction, which can result in arithmeic overflow. We use * a different form for the transform here, in terms of an origin * and a scale, with the translation done FIRST and multiplication * later. This, combined with the clipping to w->w_surfaceArea, * guarantees numerical accuracy as long as surface coordinates * fit into an integer and SUBPIXEL*screenSize fits into an integer. * * ---------------------------------------------------------------------------- */ void WindSurfaceToScreen(w, surface, screen) MagWindow *w; /* Window in whose coordinate system the * transform is to be done. */ Rect *surface; /* Rectangle in surface coordinates of w. */ Rect *screen; /* Rectangle filled in with screen coordinates * (in w) of surface. */ { int tmp; /* Do the four coordinates one at a time. */ /* The apparently redundant clipping (also done later by the box */ /* drawing routine) is necessary for two reasons: 1) it prevents */ /* having to do a multiply and shift function for any box extending */ /* outside the viewport, and more critically 2) it prevents integer */ /* overflow when a tile extends very far out of the viewport. */ tmp = surface->r_xbot; if (tmp > w->w_surfaceArea.r_xtop) screen->r_xbot = w->w_screenArea.r_xtop + 1; else { tmp -= w->w_surfaceArea.r_xbot; if (tmp < 0) screen->r_xbot = w->w_screenArea.r_xbot - 1; else screen->r_xbot = (w->w_origin.p_x + (tmp * w->w_scale)) >> SUBPIXELBITS; } tmp = surface->r_ybot; if (tmp > w->w_surfaceArea.r_ytop) screen->r_ybot = w->w_screenArea.r_ytop + 1; else { tmp -= w->w_surfaceArea.r_ybot; if (tmp < 0) screen->r_ybot = w->w_screenArea.r_ybot - 1; else screen->r_ybot = (w->w_origin.p_y + (tmp * w->w_scale)) >> SUBPIXELBITS; } tmp = surface->r_xtop; if (tmp > w->w_surfaceArea.r_xtop) screen->r_xtop = w->w_screenArea.r_xtop + 1; else { tmp -= w->w_surfaceArea.r_xbot; if (tmp < 0) screen->r_xtop = w->w_screenArea.r_xbot - 1; else screen->r_xtop = (w->w_origin.p_x + (tmp * w->w_scale)) >> SUBPIXELBITS; } tmp = surface->r_ytop; if (tmp > w->w_surfaceArea.r_ytop) screen->r_ytop = w->w_screenArea.r_ytop + 1; else { tmp -= w->w_surfaceArea.r_ybot; if (tmp < 0) screen->r_ytop = w->w_screenArea.r_ybot - 1; else screen->r_ytop = (w->w_origin.p_y + (tmp * w->w_scale)) >> SUBPIXELBITS; } } /* * ---------------------------------------------------------------------------- * * WindSurfaceToScreenNoClip -- * * This procedure is like WindSurfaceToScreen except that it * does not clip to the window boundary. This is necessary for * non-Manhattan tiles to make sure they are not clipped. * However, this routine is also useful for Manhattan geometry * when, for example, determining the transformation of a unit * coordinate. * * We convert to type double long because at close-in scales, large * values of w_scale can cause integer overflow on 32-bit integers. * * Results: * None. * * Side effects: * Pointer argument "screen" is filled with the transformed * coordinates. * * ---------------------------------------------------------------------------- */ void WindSurfaceToScreenNoClip(w, surface, screen) MagWindow *w; Rect *surface; Rect *screen; { dlong tmp, dval; tmp = (dlong)(surface->r_xbot - w->w_surfaceArea.r_xbot); dval = (dlong)w->w_origin.p_x + (tmp * (dlong)w->w_scale); screen->r_xbot = (int)(dval >> SUBPIXELBITS); tmp = surface->r_ybot - w->w_surfaceArea.r_ybot; dval = (dlong)w->w_origin.p_y + (tmp * (dlong)w->w_scale); screen->r_ybot = (int)(dval >> SUBPIXELBITS); tmp = surface->r_xtop - w->w_surfaceArea.r_xbot; dval = (dlong)w->w_origin.p_x + (tmp * (dlong)w->w_scale); screen->r_xtop = (int)(dval >> SUBPIXELBITS); tmp = surface->r_ytop - w->w_surfaceArea.r_ybot; dval = (dlong)w->w_origin.p_y + (tmp * (dlong)w->w_scale); screen->r_ytop = (int)(dval >> SUBPIXELBITS); } /* * ---------------------------------------------------------------------------- * * WindPointToScreen -- * * This is just like WindSurfaceToScreen, except it transforms a * point instead of a rectangle. * * Results: * None. * * Side effects: * Screen is modified to contain screen coordinates. They may be * clipped just as in WindSurfaceToScreen. * * ---------------------------------------------------------------------------- */ void WindPointToScreen(w, surface, screen) MagWindow *w; /* Window in whose coordinate system the * transform is to be done. */ Point *surface; /* Point in surface coordinates of w. */ Point *screen; /* Point filled in with screen coordinates * (in w) of surface. */ { int tmp; /* Do the coordinates one at a time. */ tmp = surface->p_x; if (tmp > w->w_surfaceArea.r_xtop) tmp = w->w_surfaceArea.r_xtop; tmp -= w->w_surfaceArea.r_xbot; if (tmp < 0) tmp = 0; screen->p_x = (w->w_origin.p_x + (tmp*w->w_scale)) >> SUBPIXELBITS; tmp = surface->p_y; if (tmp > w->w_surfaceArea.r_ytop) tmp = w->w_surfaceArea.r_ytop; tmp -= w->w_surfaceArea.r_ybot; if (tmp < 0) tmp = 0; screen->p_y = (w->w_origin.p_y + (tmp*w->w_scale)) >> SUBPIXELBITS; } /* * ---------------------------------------------------------------------------- * * windScreenToFrame -- * * Transform a point from screen coordinates to frame coordinates. * * Results: * None. * * Side effects: * Frame is filled in with the frame coordinates corresponding to * the screen coordinates. * * ---------------------------------------------------------------------------- */ void windScreenToFrame(w, screen, frame) MagWindow *w; /* Window in whose coordinate system the * transform is to be done. */ Point *screen; /* Point in screen coordinates of w. */ Point *frame; /* Point filled in with frame coordinates. */ { switch ( WindPackageType ) { case WIND_X_WINDOWS: frame->p_x = screen->p_x + w->w_frameArea.r_xbot; frame->p_y = screen->p_y + w->w_frameArea.r_ybot; break; default: /* WIND_MAGIC_WINDOWS */ *frame = *screen; } } magic-8.0.210/windows/vfont.B.120000644000175000001440000002151610751423606014635 0ustar timusersD@(HþHHþHþØ ÷þÞüäûü!ìû þû xþ# ˆsþ# ûóý :þG òýP6ùþ†0ùþ¶.ýüäcÿGcþªfÿü 'òý7WýŽKýÙEýEýcñü jDü®Dý ò÷û 9üEü L ÷þPü S,úEýÄ,úðHý8Eý}Bþ¿BýHýIEýŽHýÖEý ü + ü ? <ü{ ûü™ <üÕ .ý \ý_ Hÿ§ Hþï Hý7 Hþ HþÇ Hþ HýW `þ· 0þ ç 0þ `þw Hþ¿ `þHþgHý¯Hþ÷WýNHþ–HýÞHþ&`þ†`æ`ÿF`¦`HýNDü’,ý¾Dý öýüñü 0ýPHþ˜0ýÈHý0ý@0þpEþµHþý.þ +<ÿ gHþ¯0þ ßPþ# /0þ_0ýEþÔEý0þI ýi,þ•0þÅ0ÿõ@ÿ50þeEþª ýÊ"û ì"ü!û /÷ý~ÿ€çÀÃàƒÀÿÿàààààààààààààààÿÏü<ÿçàÇà‡ààààÿÿàààààààààààààààÿÏü>ÿÿçÿÇÿ‡îàààÿÿüààààààààààààààÿÏüÿÿÿÿÿÿÿÿðÿÿðÿÿÿøÿÿÿø?€ÀÿàÿàÿàÿàÿààÀÿàÿàÿàÿàÿàÿàÿàÿàÿà|ÿŸðãü|Ãø|ƒð<ðààÿÿÿüà<à<à<à<à<à<à<à<à<à<à<à<à<à<ÿÏýÿ€ÿ¿ðãüüÃøüƒð|ð<à<à<ÿÿÿüà<à<à<à<à<à<à<à<à<à<à<à<à<à<ÿÏýÿ€?Àyàðàààààààðàyà?ÀÀÀÀÀ€¾ÿÿþ€€€ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ€€€xxxxppððàüÿ?ÿ€~À|àûÿàÿÿàÿŸà÷à÷à÷àÿŸàÿÿàûà~à?ÿÀÿ€þÿÿ€>Àÿà{ÿàûÿàóßàóÿàóýàóùàóÿàûÿà|à~À?ÿ€ÿÀÀÀ?üþÿÞûþóþóþóÀóÀóÀóÀóÀóÞûÞþ?þøÀÀÀÀ<<|øøðààÀÀ€€>ÿÀÿÀÿÀÿÀÿÀÿÀÿÀÿÀÿÀÿÀ÷ÀÿüÀ>À>À|ÀxÀøðþxþøþð>ð>à>à>À>À>€>>>>>><>|ÿÿüÿÿüÿ<ï<à<À<À|€øðàÀ€<|xøüðþðø<ø|xx|xxüpxøyøûðóàÿàÀÀ€p€x|þ?ÿÀÿÀÿÀÿÀÿÀÿÀÿÀÿÀÿÀÿÀ÷ÀÿüÀ>À~À|ÀøÀøðppøøøøøøxxxxxpppøøpxñÀ|ûÀx€ø?€ð?€ðð€øÀx?î~ùþà|xøx8xpðÀÀ€<<|xxxxøððððððøxxx|<<€ÀÀàø|<€€ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ€€<8xð€€€ÿüÿü?ðÀ?ðÿüÿü€€€xxxxxxxxÿÿøÿÿøxxxxxxxxxøøx8xpðÿðÿðøøp<<xpðààÀÀ€<<xpðàü>>|x€x€x€ø€ðÀðÀðÀðÀðÀðÀø€x€x€x€|€<þðÿÿøðþ<x€ðÀøÀøÀxÀ€€~øÀ<xpÀðÀàÀÿƒÀçï€áÿ€àÿþ€€ÀpÀøÀøÀðÀp€x€??ø>>~þþÞžž<8pÿÿðÿÀ?ÿ€8xpppøþ~øð€€€ÀÀpÀøÀø€ð€p€x?~ðøþ€>€|€xxxûøÿþþü€ø€ø€ðÀðÀøÀx€x€|€>þð€ÿãÀùÿÀð?ÀàÀà€à€>|øððàààÀÀÀÀÀÀü>|€x€x€x€x€|>ü??|€x€øÀðÀðÀðÀðÀøÀx€|€??øü~>|€x€øÀðÀðÀøÀxÀ|À>À?ÀÿÀ€€8€|€|x8>>üàxøxøøpxøxøøx8xpððà€?|ðÀ€>ø|€àð|Ààðÿÿøÿÿøÿÿøÿÿøø|Àðx>€ÀððÀ|øà€>xðø>|x>ðøøx>|øà€€€ÀÀÀÿÀÁð|<xÿÿqó÷sá÷€óÁó€ãÁã€çÁã€çã€çã€÷ç€wÃçsãïyÿþ8<<€ø÷à8|||þþþÿÏÏÏ€‡€‡€‡ÀÀÀÿàààððð<øÿÇþÿÿàøx|<<<|xøàÿàøx|<<<<|xøðÿÿ€ÿ‡Àð>ð<ð|ðxpxøðððððøxx|p<ð>ààƒÀÿ€üÿÿ€Ààðøxx|<<<<<<<|xxøððàÀÿþÿÿøxxxx88ü88xxxxxÿÿøÿÿøxxxx88üÿàÿ€ƒÀð>ð<ð|ðxpxøðððððøþxðxð|ð<ð>ððƒðÿðüðÿáÿ€<<<<<<<<<<ÿü<<<<<<<<<<<ÿáÿ€ÿàÿàþðððððððððððððððxðøðøðàðñðqàà€ÿáÿ€xðàÀ€<xüüþŸ€ÀÀàððø|ÿáÿÿàppðððððÿÿðÿàÿÀ>€>€>€~À~À~ÀþàþàþáþñÞñÞóÞûž{žž??>ÿÜÿÀÿÿ€8À8À8à8à8ð8ø8ø8|8<8>888¸øøøøøøxxÿÀ8þ€À>à<ð|ðxðxðxøøxðxðxðxøxxøxøxð|ð<ð>àà‡Àÿ€üÿÿðøx|<<<<|xøðÿ€ÿàþ€À>à<ð|ðxðxðxøøxðxðxðxøxxøxøyøðþð?ð?àà‡Àÿ€ÿ€¸øøðÿÿàðx|<<<|xøàÿ€€€ÀÀÀàîþþþÿà|þà<àxàðàààðàxà|?àüÿ€ÀààààðàðàøàüÀþÀÿŸ€ãüÿÿðððððððððððððàðpàðpððððððððððððððððþÿàÿ€8€8Àxàðÿà?ÿáÿ€88€x€p€pÀðÀàÀàáàáÀáÀóÀó€ó€ÿ€>>>ÿï?à‡‡ŽŽŸŽŸÎŸÎŸÞ»ÜûÜûüùüùüùøñøñøðøðøððàðàðàðàpÿáÿ€€8€pÀðÁàáÀóÀ÷€ÿ>>>€÷€çÀÃÀÁàððø|ãÿÿàÀ€€<ÀxàpàðñàñÀ{À€??ÿÀÿÿàðÀð€ð€ððà><|xððààÀ€€ààà>à<à|àxàÿÿàÿÀððððððððððððððððððððððððððððððððÿÀðpx8<€ÀÀààðpx<<ÿÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÿÀðüþŸ€|àøðÿÿøÿÿøxðàøøxð<|xxÿ~xøððøx?€~ÿÀãàþþÿ€‡Àààðððððààà‡Àÿ€üø>>|€x€øðððøxx|€>þð€€€€€€€€÷€€>€|€x€ø€ð€ð€ð€ø€x€x€|€>€ÿ€÷ðø>>|x€ø€ÿÿ€ððøxx|€>þðàðððÿàÿÀóÀÀ<<<<><?øxpx??ÿÿ€ðÀàÀàÀð€|€þþÿïÀƒÀààààààààààààÿÏü>þÿÀ€€€?€€€€€€€€€€€€€€€€€€€ÿ€ÿ€ÿ~þø€<xøøü¾€ÀàÿÏøþÿÀþÿàïþøƒð|à<à<à<à<à<à<à<à<à<à<à<à<ÿÏýÿ€þÿïÀƒÀààààààààààààÿÏüø~>|€x€ø€ðÀðÀðÀøÀx€x€|€>þðþþÿ€‡Àààðððððààà‡Àÿ€üÿÀ÷€€>€|€x€ø€ð€ð€ð€ø€x€x€|€>€ÿ€÷€€€€€€€?ðþÿ€Ï€ÿÀ?þxþð>àøþ?€ðü|àððøþ|ïðÿàüðþààààààààààààààÿàùüÿ¿ð>€€€ŽŽÜÜüøøððàÿÏÀœ?œ¿¼¿¸ÿøóøóðóðáðáðáàáàÀàÿŸð€Þüøðøü¼ž€<ÀÿŸðÿŸð>€€€ŽŽÜÜüøøððàààÀÀ€ÿ|ÿÿðð>ð|àøðààÀ€>|øÿÿx< #include #include "utils/magic.h" #include "utils/geometry.h" #include "graphics/glyphs.h" #include "windows/windows.h" #include "windows/windInt.h" #include "utils/stack.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "textio/textio.h" #include "graphics/graphics.h" #include "utils/malloc.h" #include "utils/utils.h" #include "textio/txcommands.h" /* The type of windows that this package will implement */ int WindPackageType = WIND_MAGIC_WINDOWS; /* The size of our scroll bars -- may be set externally (see windows.h) */ int WindScrollBarWidth = 7; /* ------ Internal variables that are global within the window package ----- */ clientRec *windFirstClientRec = NULL; /* the head of the linked list * of clients */ MagWindow *windTopWindow = NULL; /* the topmost window */ MagWindow *windBottomWindow = NULL; /* ...and the bottom window */ extern Plane *windRedisplayArea; /* See windDisplay.c for details. */ /* * ---------------------------------------------------------------------------- * WindInit -- * * Initialize the window package. No windows are created, but the * package will be initialized so that it can do these things in the * future. * * Results: * None. * * Side effects: * Variables internal to the window package are initialized. * ---------------------------------------------------------------------------- */ void WindInit() { extern Stack *windGrabberStack; extern GrGlyphs *windGlyphs; Rect ts; char glyphName[30]; windClientInit(); windGrabberStack = StackNew(2); windRedisplayArea = DBNewPlane((ClientData) TT_SPACE); sprintf(glyphName, "windows%d", WindScrollBarWidth); if (!GrReadGlyphs(glyphName, ".", SysLibPath, &windGlyphs)) MainExit(1); GrTextSize("XWyqP", GR_TEXT_DEFAULT, &ts); windCaptionPixels = ts.r_ytop - ts.r_ybot + 3; WindAreaChanged((MagWindow *) NULL, (Rect *) NULL); } /* * ---------------------------------------------------------------------------- * WindAddClient -- * * Add a new client of the window package. The client must supply a * set of routines, as described below. * * Results: * A unique ID (of type WindClient) is returned. * This is used to identify the client in future calls to the window * package. * * Routines supplied: * * ( A new window was just created for this client. Do things to * initialize the window, such as filling in the caption and making * the contents be empty. The client may refuse to create a new * window by returning FALSE, otherwise the client should return * TRUE. The client will get passed argc and argv, with the command * name stripped off. The client may do whatever it wants with this. * It may even modify parts of the window record -- such as changing * the window's location on the screen.) * * bool * create(w, argc, argv) * MagWindow *w; * int argc; * char *argv[]; * { * } * * ( One of the client's windows is about to be deleted. Do whatever * needs to be done, such as freeing up dynamically allocated data * structures. Fields manipulated by the window package, such as * the caption, should not be freed by the client. The client should * normally return TRUE. If the client returns FALSE, the window * manager will refuse the request to delete the window.) * * bool * delete(w) * MagWindow *w; * { * } * * ( Redisplay an area of the screen. The client is passed the window, * the area in his coordinate system, and a clipping rectangle in * screen coordinates. ) * * redisplay(w, clientArea, screenArea) * MagWindow *w; * Rect *clientArea, *screenArea; * { * } * * * ( The window is about to be moved or resized. This procedure will * be called twice. * * The first time (with 'final' == FALSE), the window * will be passed in 'w' as it is now and a suggested new w_screenarea * is passed in 'newpos'. The client is free to modify 'newpos' to * be whatever screen location it desires. The routine should not * pass 'w' to any window procedure such as windMove since 'w' has * the old transform, etc. instead of the new one. * * On the second call ('final' == TRUE), the window 'w' has all of * it's fields updated, newpos is equal to w->w_frameArea, and the * client is free to do things like windMove which require a window * as an argument. It should not modify newpos. * * reposition(w, newpos, final) * MagWindow *w; * Rect *newpos -- new w_framearea (screen area of window) * bool final; * { * } * * * ( A command has been issued to this window. The client should * process it. It is split into Unix-style argc and argv words. ) * * command(w, client, cmd) * MagWindow *w; * TxCommand *cmd; * { * } * * ( A command has just finished. Update any screen info that may have * been changed as a result. ) * * update() * { * } * * Side effects: * Internal tables are expanded to include the new client. * ---------------------------------------------------------------------------- */ WindClient WindAddClient(clientName, create, delete, redisplay, command, update, exitproc, reposition, icon) char *clientName; /* A textual name for the client. This * name will be visable in the user * interface as the name to use to switch * a window over to a new client */ bool (*create)(); bool (*delete)(); void (*redisplay)(); void (*command)(); void (*update)(); bool (*exitproc)(); void (*reposition)(); GrGlyph *icon; /* An icon to draw when the window is closed. * (currently for Sun Windows only). */ { clientRec *res; ASSERT( (clientName != NULL), "WindAddClient"); ASSERT( (command != NULL), "WindAddClient"); res = (clientRec *) mallocMagic(sizeof(clientRec)); res->w_clientName = clientName; res->w_create = create; res->w_delete = delete; res->w_redisplay = redisplay; res->w_command = command; res->w_update = update; res->w_exit = exitproc; res->w_reposition = reposition; res->w_icon = icon; res->w_nextClient = windFirstClientRec; /* The command and function tables are dynamically allocated. */ /* Commands and functions should be registered with the client */ /* using the WindAddCommand() function. */ res->w_commandTable = (char **)mallocMagic(sizeof(char *)); *(res->w_commandTable) = NULL; res->w_functionTable = (void (**)())mallocMagic(sizeof(void (*)())); *(res->w_functionTable) = NULL; windFirstClientRec = res; return (WindClient) res; } /* * ---------------------------------------------------------------------------- * WindGetClient -- * * Looks up the unique ID of a client of the window package. * * Results: * A variable of type WindClient is returned if the client was found, * otherwise NULL is returned. * * Side effects: * None. * ---------------------------------------------------------------------------- */ WindClient WindGetClient(clientName, exact) char *clientName; /* the textual name of the client */ bool exact; /* must the name be exact, or are abbreviations allowed */ { clientRec *cr, *found; int length; /* Accept only an exact match */ if (exact) { for (cr = windFirstClientRec; cr != (clientRec *) NULL; cr = cr->w_nextClient) if (!strcmp(clientName, cr->w_clientName)) return (WindClient)cr; return (WindClient) NULL; } /* Accept any unique abbreviation */ found = NULL; length = strlen(clientName); for (cr = windFirstClientRec; cr != (clientRec *) NULL; cr = cr->w_nextClient) { if (!strncmp(clientName, cr->w_clientName, length)) { if (found != NULL) return (WindClient) NULL; found = cr; } } return (WindClient) found; } /* * ---------------------------------------------------------------------------- * WindNextClient -- * * Return the w_nextClient record to the caller as a WindClient * variable. If "client" is 0, pass the first client record. * This allows the calling routine to enumerate all the known * clients. * * Results: * Type WindClient is returned. If the end of the list is * reached, (WindClient)NULL (0) is returned. * * Side effects: * None. * ---------------------------------------------------------------------------- */ WindClient WindNextClient(client) WindClient client; { clientRec *cr = (clientRec *)client; int length; if (cr == NULL) return (WindClient)windFirstClientRec; else return (WindClient)(cr->w_nextClient); } /* * ---------------------------------------------------------------------------- * WindPrintClientList -- * * Print the name of each client of the window package. * * Results: * None. * * Side effects: * None. * ---------------------------------------------------------------------------- */ void WindPrintClientList(wizard) bool wizard; /* If true print the names of ALL clients, even those * that don't have user-visable windows */ { clientRec *cr; for (cr = windFirstClientRec; cr != (clientRec *) NULL; cr = cr->w_nextClient) { if (wizard || (cr->w_clientName[0] != '*')) TxError(" %s\n", cr->w_clientName); } } /* * ---------------------------------------------------------------------------- * WindExecute -- * * Execute the command associated with a windClient * * Results: * Returns the command index on success. Returns -1 if the * command was not found in the client's command list. Returns * -2 if the procedure was sent an empty command. * * Side effects: * Whatever is done by the command execution. * * ---------------------------------------------------------------------------- */ int WindExecute(w, rc, cmd) MagWindow *w; WindClient rc; TxCommand *cmd; { int cmdNum; clientRec *client = (clientRec *) rc; char **commandTable = client->w_commandTable; void (**functionTable)() = client->w_functionTable; if (cmd->tx_argc > 0) { cmdNum = Lookup(cmd->tx_argv[0], commandTable); if (cmdNum >= 0) { (*functionTable[cmdNum])(w, cmd); return cmdNum; } return -1; } return -2; } /* * ---------------------------------------------------------------------------- * WindAddCommand -- * * Add a command to the indicated client. The command is passed * in "text", which also contains the (1-line) help text for the * command. "func" is a function pointer, and "volatile" is TRUE * if the command "text" is dynamically allocated and must be * copied before adding to the client. * * Results: * None * * Side effects: * The memory allocated to the command and function pointers may * be reallocated and the entries in the client record updated. * * ---------------------------------------------------------------------------- */ void WindAddCommand(rc, text, func, dynamic) WindClient rc; char *text; void (*func)(); bool dynamic; { int cidx, numCommands = 0; clientRec *client = (clientRec *) rc; char **commandTable = client->w_commandTable; void (**functionTable)() = client->w_functionTable; char **newcmdTable; void (**newfnTable)(); /* Find the number of commands and functions, increment by one, and */ /* Allocate a new array of pointers. */ while (commandTable[numCommands] != NULL) numCommands++; numCommands++; newcmdTable = (char **)mallocMagic((numCommands + 1) * sizeof(char *)); newfnTable = (void (**)())mallocMagic((numCommands + 1) * sizeof(void (*)())); /* Copy the old values, inserting the new command in alphabetical */ /* order. */ for (cidx = 0; (commandTable[cidx] != NULL) && (strcmp(commandTable[cidx], text) < 0); cidx++) { newcmdTable[cidx] = commandTable[cidx]; newfnTable[cidx] = functionTable[cidx]; } if (dynamic) newcmdTable[cidx] = StrDup(NULL, text); else newcmdTable[cidx] = text; newfnTable[cidx] = func; for (; commandTable[cidx] != NULL; cidx++) { newcmdTable[cidx + 1] = commandTable[cidx]; newfnTable[cidx + 1] = functionTable[cidx]; } newcmdTable[cidx + 1] = NULL; /* Release memory for the original pointers, and replace the */ /* pointers in the client record. */ freeMagic(commandTable); freeMagic(functionTable); client->w_commandTable = newcmdTable; client->w_functionTable = newfnTable; } /* * ---------------------------------------------------------------------------- * WindReplaceCommand -- * * Change the function for the indicated command. This routine * is mainly used by the Tcl module interface, where commands * are registered with the command interpreter pointing to an * "auto" function which loads the module, then calls this routine * to replace the auto-load function with the real one. * * Note that this routine matches to the length of "command", then * checks one character beyond in the command table to ensure that * we don't inadvertently change a command which happens to be a * substring of the intended command. In cases where this is * intended (e.g., "ext" and "extract"), the routine must be called * separately for each command string. * * Results: * 0 on success, -1 if the command was not found. * * Side effects: * The clientRec structure for the DBWind interface is altered. * * ---------------------------------------------------------------------------- */ int WindReplaceCommand(rc, command, newfunc) WindClient rc; char *command; void (*newfunc)(); { int cidx, clen; clientRec *client = (clientRec *) rc; char **commandTable = client->w_commandTable; void (**functionTable)() = client->w_functionTable; clen = strlen(command); for (cidx = 0; commandTable[cidx] != NULL; cidx++) if (!strncmp(commandTable[cidx], command, clen)) if (!isalnum(*(commandTable[cidx] + clen))) { functionTable[cidx] = newfunc; return 0; } return -1; } /* * ---------------------------------------------------------------------------- * WindGetCommandTable -- * * For functions wishing to parse the command table of a client * directly, this routine returns a pointer to the top of the * table. The only purpose of this routine is to export the * w_commandTable value inside the clientRec structure, which is * not itself exported. * * Results: * A pointer to the top of the command table of the indicated * client. * * Side effects: * None. * ---------------------------------------------------------------------------- */ char ** WindGetCommandTable(rc) WindClient rc; { clientRec *client = (clientRec *) rc; return client->w_commandTable; } magic-8.0.210/windows/windView.c0000644000175000001440000003632710751423606015123 0ustar timusers/* windView.c - * * Routines in this file control what is viewed in the contents * of the windows. This includes things like pan, zoom, and loading * of windows. * * ********************************************************************* * * 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/windows/windView.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "windows/windows.h" #include "graphics/glyphs.h" #include "graphics/graphics.h" #include "windows/windInt.h" #include "textio/textio.h" extern void windNewView(); /* * ---------------------------------------------------------------------------- * * windFixSurfaceArea -- * * When a window's surface or screen area has been changed, * this procedure is usually called to fix up w->w_surfaceArea and * w_origin. Before calling this procedure, w->w_origin gives the * screen location of w_surfaceArea.r_ll in SUBPIXEL of a pixel and * w->w_scale is correct, but w->w_surfaceArea may no longer be a * slight overlap of w->w_screenArea as it should be. This procedure * regenerates w->w_surfaceArea to correspond to w->w_screenArea and * changes w->w_origin to correspond to w->w_surfaceArea.r_ll again. * * Results: * None. * * Side effects: * w->w_origin and w->w_surfaceArea are modified. * * ---------------------------------------------------------------------------- */ void windFixSurfaceArea(w) MagWindow *w; /* Window to fix up. */ { Rect newArea, tmp; GEO_EXPAND(&w->w_screenArea, 1, &tmp); WindScreenToSurface(w, &tmp, &newArea); w->w_origin.p_x += (newArea.r_xbot - w->w_surfaceArea.r_xbot) * w->w_scale; w->w_origin.p_y += (newArea.r_ybot - w->w_surfaceArea.r_ybot) * w->w_scale; w->w_surfaceArea = newArea; } /* * ---------------------------------------------------------------------------- * * WindUnload -- * * Remove a client with the indicated surfaceID and reset the window * to default cell (UNKNOWN). * * Results: * None. * * Side effects: * None. * ---------------------------------------------------------------------------- */ void WindUnload(surfaceID) ClientData surfaceID; /* A unique ID for this surface */ { MagWindow *mw; for (mw = windTopWindow; mw != NULL; mw = mw->w_nextWindow) if (mw->w_surfaceID == surfaceID) DBWloadWindow(mw, (char *)NULL, TRUE, FALSE); } /* * ---------------------------------------------------------------------------- * WindLoad -- * * Load a new client surface into a window. An initial surface area * must be specified -- this is the area that will be visible in * the window initially. * * Results: * True if everything went well, false if the client does not * own the window. * * Side effects: * None. * ---------------------------------------------------------------------------- */ bool WindLoad(w, client, surfaceID, surfaceArea) MagWindow *w; WindClient client; /* The unique identifier of the client */ ClientData surfaceID; /* A unique ID for this surface */ Rect *surfaceArea; /* The area that should appear in the window */ { if (client != w->w_client) return FALSE; w->w_surfaceID = surfaceID; WindMove(w, surfaceArea); return TRUE; } /* * ---------------------------------------------------------------------------- * WindMove -- * * Move the surface under the window so that the given area is visible * and as large as possible. * * Results: * None. * * Side effects: * The window will be now view a different portion of the clients area. * The client may be called to redisplay the areas that moved. * ---------------------------------------------------------------------------- */ void WindMove(w, surfaceArea) MagWindow *w; /* the window to be panned */ Rect *surfaceArea; /* The area to be viewed */ { int size, xscale, yscale; int halfSizePixels, halfSizeUnits; /* Compute the scale factor from world coordinates to 1/SUBPIXEL * of a pixel. To be sure that surfaceArea will all fit in the * window, compute the scale twice, once using the y-dimension * alone, and once using x alone. Then use the smaller scale factor. */ size = (surfaceArea->r_xtop - surfaceArea->r_xbot + 1); xscale = ((dlong)(w->w_screenArea.r_xtop - w->w_screenArea.r_xbot + 1) * SUBPIXEL) / size; size = (surfaceArea->r_ytop - surfaceArea->r_ybot + 1); yscale = ((w->w_screenArea.r_ytop - w->w_screenArea.r_ybot + 1) * SUBPIXEL) / size; w->w_scale = MIN(xscale, yscale); if (w->w_scale < 1) { /* If this message appears, then it is likely that the */ /* definition for SUBPIXELBITS should be increased. */ TxError("Warning: At minimum scale!\n"); w->w_scale = 1; } /* Recompute w->surfaceArea and w->w_origin, which determine the * screen-surface mapping along with w->w_scale. In order to * center surfaceArea in the window, compute the windows's half-size * in units of SUBPIXEL of a pixel and in units. Be sure to round * things up so that w->w_surfaceArea actually overlaps the window * slightly. */ halfSizePixels = (w->w_screenArea.r_xtop - w->w_screenArea.r_xbot) * HSUBPIXEL; halfSizeUnits = (halfSizePixels / w->w_scale) + 1; w->w_surfaceArea.r_xbot = (surfaceArea->r_xbot + surfaceArea->r_xtop) / 2 - halfSizeUnits; w->w_surfaceArea.r_xtop = w->w_surfaceArea.r_xbot + 2 * halfSizeUnits + 1; w->w_origin.p_x = ((w->w_screenArea.r_xtop + w->w_screenArea.r_xbot) * HSUBPIXEL) - (halfSizeUnits * w->w_scale); halfSizePixels = (w->w_screenArea.r_ytop - w->w_screenArea.r_ybot) * HSUBPIXEL; halfSizeUnits = (halfSizePixels/w->w_scale) + 1; w->w_surfaceArea.r_ybot = (surfaceArea->r_ybot + surfaceArea->r_ytop) / 2 - halfSizeUnits; w->w_surfaceArea.r_ytop = w->w_surfaceArea.r_ybot + 2 * halfSizeUnits + 1; w->w_origin.p_y = ((w->w_screenArea.r_ytop + w->w_screenArea.r_ybot) * HSUBPIXEL) - (halfSizeUnits * w->w_scale); WindAreaChanged(w, &(w->w_screenArea)); windNewView(w); } /* * ---------------------------------------------------------------------------- * WindZoom -- * * Zoom a window. The window will stay centered about the same point * as it is currently. A factor greater than 1 increases the scale * of the window (higher magnification), while a factor smaller than 1 * results in a lower scale (lower magnification). * * Results: * None. * * Side effects: * The window will be now view a different portion of the client's area. * The client may be called to redisplay part of the screen. * ---------------------------------------------------------------------------- */ void WindZoom(w, factor) MagWindow *w; /* the window to be zoomed */ float factor; /* The amount to zoom by (1 is no change), * greater than 1 is a larger magnification * (zoom in), and less than 1 is less mag. * (zoom out) ) */ { int centerx, centery; Rect newArea; centerx = (w->w_surfaceArea.r_xbot + w->w_surfaceArea.r_xtop) / 2; centery = (w->w_surfaceArea.r_ybot + w->w_surfaceArea.r_ytop) / 2; newArea.r_xbot = centerx - (centerx - w->w_surfaceArea.r_xbot) * factor; newArea.r_xtop = centerx + (w->w_surfaceArea.r_xtop - centerx) * factor; newArea.r_ybot = centery - (centery - w->w_surfaceArea.r_ybot) * factor; newArea.r_ytop = centery + (w->w_surfaceArea.r_ytop - centery) * factor; WindMove(w, &newArea); } /* * ---------------------------------------------------------------------------- * * WindScale -- * * Zoom all viewing windows by the given factor. Because this is done * in conjunction with rescaling the geometry, we don't preserve the * center position like WindZoom() does. The net effect is that the * image in the window doesn't appear to change. * * Results: * None. * * Side effects: * All windows will be now view a different portion of the client's area. * * ---------------------------------------------------------------------------- */ void WindScale(scalen, scaled) int scalen, scaled; { extern void DBScalePoint(); MagWindow *w2; Rect newArea; for (w2 = windTopWindow; w2 != NULL; w2 = w2->w_nextWindow) { newArea.r_xbot = w2->w_surfaceArea.r_xbot; newArea.r_xtop = w2->w_surfaceArea.r_xtop; newArea.r_ybot = w2->w_surfaceArea.r_ybot; newArea.r_ytop = w2->w_surfaceArea.r_ytop; DBScalePoint(&newArea.r_ll, scalen, scaled); DBScalePoint(&newArea.r_ur, scalen, scaled); WindMove(w2, &newArea); } } /* * ---------------------------------------------------------------------------- * * WindView -- * * Change the view in the selected window to just contain the * bounding box for that window. * * * Results: * None. * * Side effects: * The window underneath the cursor is changed. * * ---------------------------------------------------------------------------- */ /* ARGSUSED */ void WindView(w) MagWindow *w; { Rect bbox; #define SLOP 10 /* Amount of border (in fraction of a screenfull) * to add. */ if (w == NULL) return; if (w->w_bbox == NULL) { TxError("Can't do 'view' because w_bbox is NULL.\n"); TxError("Report this to a magic implementer.\n"); return; }; bbox = *(w->w_bbox); bbox.r_xbot -= (bbox.r_xtop - bbox.r_xbot + 1) / SLOP; bbox.r_xtop += (bbox.r_xtop - bbox.r_xbot + 1) / SLOP; bbox.r_ybot -= (bbox.r_ytop - bbox.r_ybot + 1) / SLOP; bbox.r_ytop += (bbox.r_ytop - bbox.r_ybot + 1) / SLOP; WindMove(w, &bbox); } /* * ---------------------------------------------------------------------------- * * WindScroll -- * * Scroll the view around. * * Results: * None. * * Side effects: * The window underneath the cursor is changed. The offset can * be specified either in screen coordinates or surface coordinates * or both. * * ---------------------------------------------------------------------------- */ void WindScroll(w, surfaceOffset, screenOffset) MagWindow *w; Point *surfaceOffset; /* An offset in surface coordinates. The * screen point that used to display surface * point (0,0) will now display surface point * surfaceOffset. Can be NULL to indicate * no offset. */ Point *screenOffset; /* An additional offset in screen coordinates. * Can be NULL to indicate no offset. If * non-NULL, then after scrolling according * to surfaceOffset, the view is adjusted again * so that the surface unit that used to be * displayed at (0,0) will now be displayed * at screenOffset. Be careful to make sure * the coordinates in here are relatively * small (e.g. the same order as the screen * size), or else there may be arithmetic * overflow and unexpected results. Use only * surfaceOffset if you're going to be * scrolling a long distance. */ { Rect screenorigin; bool useBackingStore = FALSE; Point moveorigin; Rect refresh, norefresh; WindSurfaceToScreenNoClip(w, &GeoNullRect, &screenorigin); if (surfaceOffset != NULL) { w->w_surfaceArea.r_xbot += surfaceOffset->p_x; w->w_surfaceArea.r_ybot += surfaceOffset->p_y; w->w_surfaceArea.r_xtop += surfaceOffset->p_x; w->w_surfaceArea.r_ytop += surfaceOffset->p_y; } /* Screen offsets are trickier. Divide up into a whole-unit part * (which is applied to w->w_surfaceArea) and a fractional-unit * part (which is applied to w->w_origin. Then readjust both to * make sure that w->w_surfaceArea still overlaps the window area * on all sides. */ if (screenOffset != NULL) { int units, pixels; pixels = screenOffset->p_x * SUBPIXEL; units = pixels/w->w_scale; w->w_surfaceArea.r_xbot -= units; w->w_surfaceArea.r_xtop -= units; w->w_origin.p_x += pixels - (w->w_scale*units); pixels = screenOffset->p_y * SUBPIXEL; units = pixels/w->w_scale; w->w_surfaceArea.r_ybot -= units; w->w_surfaceArea.r_ytop -= units; w->w_origin.p_y += pixels - (w->w_scale*units); } /* For now, we forget about using backing store in the case */ /* of diagonal scrolls. Ideally, we would want to register */ /* two rectangles for the window redraw in this case. */ if (w->w_backingStore != (ClientData)NULL) { if (surfaceOffset) if (surfaceOffset->p_x == 0 || surfaceOffset->p_y == 0) useBackingStore = TRUE; if (screenOffset) if (screenOffset->p_x == 0 || screenOffset->p_y == 0) if (useBackingStore == FALSE) useBackingStore = TRUE; } windFixSurfaceArea(w); /* Finally, if we are going to use backing store, we ought */ /* to adjust the screen movement to the nearest multiple of */ /* 8 so that stipples will remain aligned. This must be */ /* done after windFixSurfaceArea(), but cannot screw up the */ /* coordinate system, so we do windFixSurfaceArea() again. */ if (useBackingStore) { int units, pixels; WindSurfaceToScreenNoClip(w, &GeoNullRect, &refresh); moveorigin.p_x = refresh.r_xbot - screenorigin.r_xbot; moveorigin.p_y = refresh.r_ybot - screenorigin.r_ybot; pixels = (moveorigin.p_x % 8) * SUBPIXEL; units = pixels/w->w_scale; w->w_surfaceArea.r_xbot += units; w->w_surfaceArea.r_xtop += units; w->w_origin.p_x -= (pixels - (w->w_scale*units)); pixels = (moveorigin.p_y % 8) * SUBPIXEL; units = pixels/w->w_scale; w->w_surfaceArea.r_ybot += units; w->w_surfaceArea.r_ytop += units; w->w_origin.p_y -= (pixels - (w->w_scale*units)); moveorigin.p_x -= (moveorigin.p_x % 8); moveorigin.p_y -= (moveorigin.p_y % 8); windFixSurfaceArea(w); } /* If we have backing store available, shift the contents. */ if (useBackingStore) { refresh = w->w_screenArea; norefresh = w->w_screenArea; if (moveorigin.p_x > 0) { refresh.r_xtop = moveorigin.p_x + w->w_screenArea.r_xbot; norefresh.r_xbot = refresh.r_xtop; } else if (moveorigin.p_x < 0) { refresh.r_xbot = refresh.r_xtop + moveorigin.p_x; norefresh.r_xtop += moveorigin.p_x; } if (moveorigin.p_y > 0) { refresh.r_ytop = moveorigin.p_y + w->w_screenArea.r_ybot; norefresh.r_ybot = refresh.r_ytop; } else if (moveorigin.p_y < 0) { refresh.r_ybot = refresh.r_ytop + moveorigin.p_y; norefresh.r_ytop += moveorigin.p_y; } (*GrScrollBackingStorePtr)(w, &moveorigin); (*GrGetBackingStorePtr)(w, &norefresh); WindAreaChanged(w, &refresh); /* Update highlights over entire screen area */ DBWHLRedrawPrepWindow(w, &(w->w_surfaceArea)); } else WindAreaChanged(w, &(w->w_screenArea)); windNewView(w); } magic-8.0.210/windows/windDisp.c0000664000175000001440000007004712027341350015100 0ustar timusers/* windDisplay.c - * * Display the borders of the window, including the caption area. * * ********************************************************************* * * 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/windows/windDisp.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "tcltk/tclmagic.h" #include "utils/magic.h" #include "utils/utils.h" #include "textio/textio.h" #include "utils/geometry.h" #include "graphics/glyphs.h" #include "windows/windows.h" #include "windows/windInt.h" #include "graphics/graphics.h" #include "utils/styles.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/undo.h" #include "utils/signals.h" #include "utils/malloc.h" /* The following Plane is used to keep track of areas of the * screen that have changed. ERROR_P tiles are used to record * areas of the screen (in pixels) that must be redisplayed. * * If windows have speparate coordinate spaces (as on a SUN), this plane * is ignored and the one in w->w_redrawAreas is used instead. */ global Plane *windRedisplayArea = NULL; static Plane *windCurRedrawPlane = NULL; /* used for sharing between procs */ static LinkedRect *windCoveredAreas = NULL; global GrGlyphs *windGlyphs = NULL; /* windCaptionPixels is the height of the caption strip. It is internal to * this module. */ int windCaptionPixels = 0; /* Are the windows in their own coordinate system? */ bool windSomeSeparateRedisplay = FALSE; /* * ---------------------------------------------------------------------------- * * windCheckOnlyWindow -- * * Check if the TopWindow is the only window---if so, we shouldn't * generate bothersome messages about the cursor not being in a window, * because there is no confusion. * * We want to make sure that we don't count windows which are not of * the same client type. * * ---------------------------------------------------------------------------- */ int windCheckOnlyWindow(MagWindow **w, WindClient client) { MagWindow *sw, *tw; int wct = 0; if (*w != NULL) return 0; if (windTopWindow != NULL) { for (sw = windTopWindow; sw != NULL; sw = sw->w_nextWindow) { if (sw->w_client == client) { wct++; tw = sw; } } if (wct == 1) *w = tw; } return 0; } /* * ---------------------------------------------------------------------------- * windFreeList -- * * Free up a list of linked rectangles. * * Results: * None. * * Side effects: * Storage is reclaimed. The original pointer is NULLed out. * ---------------------------------------------------------------------------- */ void windFreeList(llr) LinkedRect **llr; /* A pointer to a list of linked rectangles */ { LinkedRect *lr, *freelr; lr = *llr; while (lr != (LinkedRect *) NULL) { freelr = lr; lr = lr->r_next; freeMagic( (char *) freelr); } *llr = (LinkedRect *) NULL; } /* * ---------------------------------------------------------------------------- * windReClip -- * * Traverse the linked list of windows, updating w_clipAgainst * for each window. * * Results: * None. * * Side effects: * Changes w_clipAgainst for some windows. * ---------------------------------------------------------------------------- */ void windReClip() { MagWindow *w1, *w2; /* an O(n**2) operation!! */ windFreeList(&windCoveredAreas); for (w1 = windBottomWindow; w1 != (MagWindow *) NULL; w1 = w1->w_prevWindow) { LinkedRect *tmp; /* add window onto windCoveredAreas */ tmp = (LinkedRect *) mallocMagic((unsigned) (sizeof (LinkedRect))); tmp->r_next = windCoveredAreas; tmp->r_r = w1->w_frameArea; windCoveredAreas = tmp; /* free up the old clipping areas and make new ones */ windFreeList( &(w1->w_clipAgainst) ); w1->w_clipAgainst = (LinkedRect *) NULL; /* Leave w_clipAgainst to be NULL if we are using some other * window package, because that package will handle overlapping * windows. */ if (WindPackageType == WIND_MAGIC_WINDOWS) { for (w2 = w1->w_prevWindow; w2 != (MagWindow *) NULL; w2 = w2->w_prevWindow) { if ( GEO_TOUCH( &(w1->w_frameArea), &(w2->w_frameArea) )) { tmp = (LinkedRect *) mallocMagic((unsigned) (sizeof (LinkedRect))); tmp->r_next = w1->w_clipAgainst; tmp->r_r = w2->w_frameArea; w1->w_clipAgainst = tmp; } } } } } /* * ---------------------------------------------------------------------------- * * WindSeparateRedisplay -- * * Tells the window manager to record redisplay areas for this window * separately -- probably because the window has its own separate * coordinate system. (Used on the Sun with Suntools or X.) * * Results: * None. * * Side Effects: * None. * * ---------------------------------------------------------------------------- */ void WindSeparateRedisplay(w) MagWindow *w; { windSomeSeparateRedisplay = TRUE; if (w->w_redrawAreas != (ClientData)NULL) return; w->w_redrawAreas = (ClientData) DBNewPlane((ClientData) TT_SPACE); } /* * ---------------------------------------------------------------------------- * WindIconChanged -- * * Mark the icon for this window as needing to be redisplayed. * * Results: * None. * * Side effects: * None. * ---------------------------------------------------------------------------- */ void WindIconChanged(w) MagWindow *w; { ASSERT(w != NULL, "WindIconChanged"); w->w_flags |= WIND_REDRAWICON; } /* * ---------------------------------------------------------------------------- * WindAreaChanged -- * * Notify the window package that a certain area of the screen has * changed, and now needs to be redrawn. * * Results: * None. * * Side effects: * The area is noted as having changed in window w. When * WindUpdate is called, this area will be redisplayed, but * only in w. If w is NULL, then this area will be redisplayed * in all windows. If area is NULL, then the whole area of * the window will be redisplayed. If both are NULL, then * the whole screen will be redisplayed. * ---------------------------------------------------------------------------- */ void WindAreaChanged(w, area) MagWindow *w; /* The window that changed. */ Rect *area; /* The area in screen coordinates. * NULL means the whole screen. Caller * should clip this rectangle to the area * of the window. */ { Rect biggerArea; int windChangedFunc(); /* Forward declaration. */ if (w == NULL) { if (windSomeSeparateRedisplay) { MagWindow *nw; for (nw = windTopWindow; nw != NULL; nw = nw->w_nextWindow) WindAreaChanged(nw, area); return; } else windCurRedrawPlane = windRedisplayArea; } else { if (w->w_redrawAreas != (ClientData)NULL) windCurRedrawPlane = (Plane *) w->w_redrawAreas; else windCurRedrawPlane = windRedisplayArea; } if (area == (Rect *) NULL) { /* Everything changed -- all the window's area as well as the icon. */ if (w != (MagWindow *) NULL) { area = &w->w_allArea; WindIconChanged(w); } else { MagWindow *nw; area = &GrScreenRect; for (nw = windTopWindow; nw != NULL; nw = nw->w_nextWindow) WindIconChanged(nw); } } /* We have to increase the upper x- and y-coordinates of * the redisplay area by one. This is because a pixel is * considered to include its entire area (up to the beginning * of the next pixel). Without this code and corresponding * hacks in WindUpdate and windBackgroundFunc, little slivers * get left lying around. */ biggerArea = *area; biggerArea.r_xtop += 1; biggerArea.r_ytop += 1; /* If no window is given, or if the window is unobscured, * then just paint an error tile over the area to be redisplayed. * Otherwise, clip the area against all the obscuring areas * for the window. Be careful to keep undo away from this. */ UndoDisable(); if ((w == NULL) || (w->w_clipAgainst == NULL)) DBPaintPlane(windCurRedrawPlane, &biggerArea, DBStdPaintTbl(TT_ERROR_P, PL_DRC_ERROR), (PaintUndoInfo *) NULL); else { (void) GeoDisjoint(&biggerArea, &w->w_clipAgainst->r_r, windChangedFunc, (ClientData) w->w_clipAgainst->r_next); } UndoEnable(); /* If the area is NULL or encompasses the whole screen area, and */ /* there is no backing store, then we should create it so that it */ /* will be copied into on the next display redraw. */ if ((w != NULL) && (w->w_backingStore == (ClientData)NULL) && (!(w->w_flags & WIND_OBSCURED)) && (GrCreateBackingStorePtr != NULL)) if ((area == (Rect *)NULL) || GEO_SURROUND(&biggerArea, &w->w_screenArea)) (*GrCreateBackingStorePtr)(w); } int windChangedFunc(area, next) Rect *area; /* Area that is still unobscured. */ LinkedRect *next; /* Next obscuring area. */ { /* If we're at the end of obscuring areas, paint an error * tile to mark what's to be redisplayed. Otherwise, * clip against the next obscuring area. */ if (next == NULL) DBPaintPlane(windCurRedrawPlane, area, DBStdPaintTbl(TT_ERROR_P, PL_DRC_ERROR), (PaintUndoInfo *) NULL); else (void) GeoDisjoint(area, &next->r_r, windChangedFunc, (ClientData) next->r_next); return 0; } /* * ---------------------------------------------------------------------------- * windBarLocations -- * * Find the scroll bars and icons in the window. * Each argument must point to a different piece of memory. * * Results: * None. * * Side effects: * Returns a bunch of rectangles describing the locations of things. * See comments next to the argument list for details. * ---------------------------------------------------------------------------- */ void windBarLocations(w, leftBar, botBar, up, down, right, left, zoom) MagWindow *w; /* The window under consideration. */ /* The following are rectangles that will be filled * in by this procedure. The values will be in the * same coordinate sytem as w->w_allArea. */ Rect *leftBar; /* The location of the left scrollbar area (not the * bar itself). */ Rect *botBar; /* The location of the bottom scrollbar area. */ Rect *up; /* The location of the 'up arrow' icon above the * left scroll bar. */ Rect *down; /* The location of the 'down arrow' icon below the * left scroll bar. */ Rect *right; /* The location of the 'right arrow' icon to the right * of the bottom scroll bar. */ Rect *left; /* The location of the 'left arrow' icon to the left of * the bottom scroll bar. */ Rect *zoom; /* The location of the 'zoom' icon in the lower-left * corner of the window. */ { /* left scroll bar area */ leftBar->r_xbot = w->w_allArea.r_xbot + THIN_LINE; leftBar->r_ybot = w->w_allArea.r_ybot + THIN_LINE + WindScrollBarWidth + BOT_BORDER(w); leftBar->r_xtop = leftBar->r_xbot + WindScrollBarWidth - GrPixelCorrect; leftBar->r_ytop = w->w_allArea.r_ytop - THIN_LINE - WindScrollBarWidth - TOP_BORDER(w); /* bottom scroll bar area */ botBar->r_ybot = w->w_allArea.r_ybot + THIN_LINE; botBar->r_xbot = w->w_allArea.r_xbot + THIN_LINE + WindScrollBarWidth + LEFT_BORDER(w); botBar->r_ytop = botBar->r_ybot + WindScrollBarWidth - GrPixelCorrect; botBar->r_xtop = w->w_allArea.r_xtop - THIN_LINE - WindScrollBarWidth - RIGHT_BORDER(w); /* border icons */ down->r_xbot = up->r_xbot = leftBar->r_xbot; down->r_xtop = up->r_xtop = leftBar->r_xtop; up->r_ybot = leftBar->r_ytop + THIN_LINE + 1; up->r_ytop = up->r_ybot + WindScrollBarWidth - 1; down->r_ytop = leftBar->r_ybot - THIN_LINE - 1; down->r_ybot = down->r_ytop - WindScrollBarWidth + 1; left->r_ybot = right->r_ybot = botBar->r_ybot; left->r_ytop = right->r_ytop = botBar->r_ytop; right->r_xbot = botBar->r_xtop + THIN_LINE + 1; right->r_xtop = right->r_xbot + WindScrollBarWidth - 1; left->r_xtop = botBar->r_xbot - THIN_LINE - 1; left->r_xbot = left->r_xtop - WindScrollBarWidth + 1; zoom->r_xbot = w->w_allArea.r_xbot + THIN_LINE; zoom->r_ybot = w->w_allArea.r_ybot + THIN_LINE; zoom->r_xtop = zoom->r_xbot + WindScrollBarWidth - 1; zoom->r_ytop = zoom->r_ybot + WindScrollBarWidth - 1; } /* * ---------------------------------------------------------------------------- * WindDrawBorder -- * * Draw the border of windows. A window lock is created & then destroyed. * * Results: * None. * * Side effects: * Redisplays the scroll bar & caption areas of a window's border. * ---------------------------------------------------------------------------- */ void WindDrawBorder(w, clip) MagWindow *w; Rect *clip; { Rect r; Rect leftBar, botBar, up, down, left, right, zoom; Rect leftElev, botElev; int bar, bbox, viewl, viewu; Point capp; Rect capr; GrLock(w, FALSE); GrClipTo(clip); /* Redisplay the caption if it overlaps the area. */ capr = w->w_allArea; capr.r_ybot = capr.r_ytop - TOP_BORDER(w) + GrPixelCorrect; capp.p_x = (capr.r_xbot + capr.r_xtop) / 2; capp.p_y = (capr.r_ybot + capr.r_ytop + 1) / 2; if (GEO_TOUCH(&capr, clip)) { if (w->w_flags & WIND_BORDER) GrClipBox(&capr, STYLE_BORDER); if ((w->w_flags & WIND_CAPTION) && (w->w_caption != NULL)) { (void) GrPutText(w->w_caption, STYLE_CAPTION, &capp, GEO_CENTER, GR_TEXT_DEFAULT, FALSE, &capr, (Rect *) NULL); } } if ((w->w_flags & WIND_BORDER) != 0) { /* right border */ r = w->w_allArea; r.r_xbot = w->w_allArea.r_xtop - RIGHT_BORDER(w) + GrPixelCorrect; r.r_ytop = w->w_allArea.r_ytop - TOP_BORDER(w); if (GEO_TOUCH(&r, clip)) GrClipBox(&r, STYLE_BORDER); if ((w->w_flags & WIND_SCROLLBARS) == 0) { /* windows without scroll bars */ /* left border */ r = w->w_allArea; r.r_xtop = w->w_allArea.r_xbot + LEFT_BORDER(w) - GrPixelCorrect; r.r_ytop = w->w_allArea.r_ytop - TOP_BORDER(w); if (GEO_TOUCH(&r, clip)) GrClipBox(&r, STYLE_BORDER); /* bottom border */ r = w->w_allArea; r.r_ytop = w->w_allArea.r_ybot + BOT_BORDER(w) - GrPixelCorrect; if (GEO_TOUCH(&r, clip)) GrClipBox(&r, STYLE_BORDER); } } if ((w->w_flags & WIND_SCROLLBARS) != 0) { /* windows with scroll bars */ /* left vertical lines */ r = w->w_allArea; r.r_ytop = w->w_allArea.r_ytop - TOP_BORDER(w); r.r_xtop = r.r_xbot + THIN_LINE - GrPixelCorrect; if (GEO_TOUCH(&r, clip)) GrClipBox(&r, STYLE_BORDER); r.r_xbot += WindScrollBarWidth + THIN_LINE; r.r_xtop = r.r_xbot + THIN_LINE - GrPixelCorrect; if (GEO_TOUCH(&r, clip)) GrClipBox(&r, STYLE_BORDER); /* bottom horizontal lines */ r = w->w_allArea; r.r_ytop = r.r_ybot + THIN_LINE - GrPixelCorrect; if (GEO_TOUCH(&r, clip)) GrClipBox(&r, STYLE_BORDER); r.r_ybot += WindScrollBarWidth + THIN_LINE; r.r_ytop = r.r_ybot + THIN_LINE - GrPixelCorrect; if (GEO_TOUCH(&r, clip)) GrClipBox(&r, STYLE_BORDER); /* scroll bars */ windBarLocations(w, &leftBar, &botBar, &up, &down, &right, &left, &zoom); GrClipBox(&leftBar, STYLE_CAPTION); GrClipBox(&botBar, STYLE_CAPTION); if (w->w_bbox == NULL) { TxError("Warning: scroll bars but no w->w_bbox!\n"); TxError("Report this to a magic implementer.\n"); goto leave; }; /* left scroll bar */ bar = MAX(1, leftBar.r_ytop - leftBar.r_ybot + 1); bbox = MAX(1, w->w_bbox->r_ytop - w->w_bbox->r_ybot + 1); viewl = w->w_surfaceArea.r_ybot - w->w_bbox->r_ybot + 1; viewu = w->w_surfaceArea.r_ytop - w->w_bbox->r_ybot + 1; leftElev.r_xbot = leftBar.r_xbot + 2; leftElev.r_xtop = leftBar.r_xtop - 3 + GrPixelCorrect; leftElev.r_ybot = (bar * viewl) / bbox + leftBar.r_ybot; leftElev.r_ytop = (bar * viewu) / bbox + leftBar.r_ybot; leftElev.r_ytop = MIN(leftElev.r_ytop, leftBar.r_ytop - 2); leftElev.r_ybot = MIN(leftElev.r_ybot, leftElev.r_ytop - 3); leftElev.r_ybot = MAX(leftElev.r_ybot, leftBar.r_ybot + 2); leftElev.r_ytop = MAX(leftElev.r_ytop, leftElev.r_ybot + 1 + GrPixelCorrect + GrPixelCorrect); GrClipBox(&leftElev, STYLE_ELEVATOR); r.r_xbot = leftBar.r_xbot; r.r_xtop = leftBar.r_xtop; r.r_ybot = leftBar.r_ybot - THIN_LINE; r.r_ytop = leftBar.r_ybot - GrPixelCorrect; if (GEO_TOUCH(&r, clip)) GrClipBox(&r, STYLE_BORDER); r.r_ybot = leftBar.r_ytop + GrPixelCorrect; r.r_ytop = leftBar.r_ytop + THIN_LINE; if (GEO_TOUCH(&r, clip)) GrClipBox(&r, STYLE_BORDER); /* bottom scroll bar */ bar = MAX(1, botBar.r_xtop - botBar.r_xbot + 1); bbox = MAX(1, w->w_bbox->r_xtop - w->w_bbox->r_xbot + 1); viewl = w->w_surfaceArea.r_xbot - w->w_bbox->r_xbot + 1; viewu = w->w_surfaceArea.r_xtop - w->w_bbox->r_xbot + 1; botElev.r_ybot = botBar.r_ybot + 2; botElev.r_ytop = botBar.r_ytop - 3 + GrPixelCorrect; botElev.r_xbot = (bar * viewl) / bbox + botBar.r_xbot; botElev.r_xtop = (bar * viewu) / bbox + botBar.r_xbot; botElev.r_xtop = MIN(botElev.r_xtop, botBar.r_xtop - 2); botElev.r_xbot = MIN(botElev.r_xbot, botElev.r_xtop - 3); botElev.r_xbot = MAX(botElev.r_xbot, botBar.r_xbot + 2); botElev.r_xtop = MAX(botElev.r_xtop, botElev.r_xbot + 1 + GrPixelCorrect + GrPixelCorrect); GrClipBox(&botElev, STYLE_ELEVATOR); r.r_ybot = botBar.r_ybot; r.r_ytop = botBar.r_ytop; r.r_xbot = botBar.r_xbot - THIN_LINE; r.r_xtop = botBar.r_xbot - GrPixelCorrect; if (GEO_TOUCH(&r, clip)) GrClipBox(&r, STYLE_BORDER); r.r_xbot = botBar.r_xtop + GrPixelCorrect; r.r_xtop = botBar.r_xtop + THIN_LINE; if (GEO_TOUCH(&r, clip)) GrClipBox(&r, STYLE_BORDER); /* icons */ GrDrawGlyph(windGlyphs->gr_glyph[0], &(up.r_ll)); GrDrawGlyph(windGlyphs->gr_glyph[1], &(down.r_ll)); GrDrawGlyph(windGlyphs->gr_glyph[2], &(left.r_ll)); GrDrawGlyph(windGlyphs->gr_glyph[3], &(right.r_ll)); GrDrawGlyph(windGlyphs->gr_glyph[4], &(zoom.r_ll)); } leave: GrUnlock(w); } /* * ---------------------------------------------------------------------------- * WindCaption -- * * Set the caption on the window. * * Results: * None. * * Side effects: * The caption is changed in the data structure and is redisplayed on the * screen (if any of it is visible). If anything overlaps the caption and * the caption was redisplayed then the overlap material will be * redisplayed. * * If the new caption is identical to the old then only redisplay is done. * ---------------------------------------------------------------------------- */ void WindCaption(w, caption) MagWindow *w; char *caption; /* The string that is to be copied into the caption. * (The string is copied, not just pointed at.) */ { Rect r; if (w->w_caption != caption) (void) StrDup( &(w->w_caption), caption); r = w->w_allArea; r.r_ybot = r.r_ytop - TOP_BORDER(w) + 1; WindAreaChanged(w, &r); if (GrUpdateIconPtr)(*GrUpdateIconPtr)(w,w->w_caption); } /* * ---------------------------------------------------------------------------- * windNewView -- * * The window's view has moved -- update the scroll bars. * * Results: * None. * * Side effects: * Records areas for redisplay. * ---------------------------------------------------------------------------- */ void windNewView(w) MagWindow *w; { Rect leftBar, botBar, up, down, right, left, zoom; if ((w->w_flags & WIND_SCROLLBARS) != 0) { windBarLocations(w, &leftBar, &botBar, &up, &down, &right, &left, &zoom); WindAreaChanged(w, &leftBar); WindAreaChanged(w, &botBar); } } /* * ---------------------------------------------------------------------------- * WindRedisplay -- * * Redisplay the entire window, including the border areas. * Called without any window locks. * * Results: * None. * * Side effects: * Areas of the screen will be redrawn. * ---------------------------------------------------------------------------- */ void WindRedisplay(w) MagWindow *w; { WindAreaChanged(w, &(w->w_allArea)); } /* * ---------------------------------------------------------------------------- * windRedrawIcon -- * * Redraw a windows icon. * * Results: * None. * * Side effects: * None. * ---------------------------------------------------------------------------- */ void windRedrawIcon(w) MagWindow *w; { Point p; clientRec *cl; char *name; /* Prepare for graphics. */ cl = (clientRec *) w->w_client; GrLock(w, FALSE); GrClipBox(&w->w_allArea, STYLE_ERASEALL); if (cl->w_icon != NULL) { /* Draw the glyph */ GrDrawGlyph(cl->w_icon, &(w->w_allArea.r_ll)); } /* Now label the icon */ if (w->w_iconname != NULL) name = w->w_iconname; else name = cl->w_clientName; p.p_y = w->w_allArea.r_ybot; p.p_x = (w->w_allArea.r_xbot + w->w_allArea.r_xtop) / 2; GrPutText(name, STYLE_BORDER, &p, GEO_NORTH, GR_TEXT_SMALL, TRUE, &w->w_allArea, (Rect *) NULL); /* We are done */ w->w_flags &= ~WIND_REDRAWICON; GrUnlock(w); } /* * ---------------------------------------------------------------------------- * WindUpdate -- * * Update the screen areas that were previously passed to WindAreaChanged. * Calls clients without any window locks. * * Results: * None. * * Side effects: * Clients will be called to update portions of the screen. * ---------------------------------------------------------------------------- */ bool WindAnotherUpdatePlease; void WindUpdate() { clientRec *cr; MagWindow *w; TileTypeBitMask windTileMask; extern int windUpdateFunc(); /* Forward declaration. */ extern int windBackgroundFunc(); /* Forward declaration. */ Rect r; WindAnotherUpdatePlease = FALSE; /* First, if there was a SigWinch (as on a Sun160), then call the * graphics module so that it can record additional areas to be * redisplayed. */ if (SigGotSigWinch) { SigGotSigWinch = FALSE; if (GrDamagedPtr != NULL) (*GrDamagedPtr)(); } #ifdef MAGIC_WRAPPER /* Honor the display redraw suspension state */ if (GrDisplayStatus == DISPLAY_SUSPEND) return; GrDisplayStatus = DISPLAY_IN_PROGRESS; SigSetTimer(0); #endif TTMaskSetOnlyType(&windTileMask, TT_ERROR_P); /* Make a scan through each of the windows, in order from top * down. For each window, redisplay the areas of that window * that have changed, then erase the area of that window from * the redisplay plane. Since our window areas INCLUDE their * border pixels on both sides, expand the area on the top and * right sides before erasing. Without this expansion, and * corresponding hacks in WindAreaChanged and windBackgroundFunc, * slivers will accidentally be left undisplayed. */ UndoDisable(); for (w = windTopWindow; w != NULL; w = w->w_nextWindow) { if (w->w_flags & WIND_ISICONIC) { if (w->w_flags & WIND_REDRAWICON) windRedrawIcon(w); } else { if (w->w_redrawAreas == (ClientData)NULL) windCurRedrawPlane = windRedisplayArea; else windCurRedrawPlane = (Plane *) w->w_redrawAreas; (void) DBSrPaintArea((Tile *) NULL, windCurRedrawPlane, &w->w_allArea, &windTileMask, windUpdateFunc, (ClientData) w); if (windCurRedrawPlane == windRedisplayArea) { /* Erase this window from our list, since we have redrawn it. */ r = w->w_allArea; r.r_xtop += 1; r.r_ytop += 1; DBPaintPlane(windRedisplayArea, &r, DBStdEraseTbl(TT_ERROR_P, PL_DRC_ERROR), (PaintUndoInfo *) NULL); } else { /* We are finished with this window's redisplay plane. Clear * any remaining redisplay tiles, as we may have interrupted * the redislay and don't want this stuff any more. */ DBClearPaintPlane(windCurRedrawPlane); } } } if (WindPackageType == WIND_MAGIC_WINDOWS) { /* For any tiles left that intersect the screen, draw the background * color (there are no windows over these tiles). */ (void) DBSrPaintArea((Tile *) NULL, windRedisplayArea, &GrScreenRect, &windTileMask, windBackgroundFunc, (ClientData) NULL); /* Clear any remaining redisplay tiles, as we may have interrupted * the redislay and don't want this stuff any more. */ DBClearPaintPlane(windRedisplayArea); }; UndoEnable(); /* Now give the clients a chance to update anything that they wish */ for (cr = windFirstClientRec; cr != (clientRec *) NULL; cr = cr->w_nextClient) { if (cr->w_update != NULL) (*(cr->w_update)) (); } GrFlush(); #ifdef MAGIC_WRAPPER SigRemoveTimer(); GrDisplayStatus = DISPLAY_IDLE; #endif /* See comment in windows.h */ if (WindAnotherUpdatePlease) WindUpdate(); } /* * ---------------------------------------------------------------------------- * * windUpdateFunc -- * * This procedure is invoked during WindUpdate for each tile that * intersects a particular window. If the tile type is TT_ERROR_P * then the intersection between the tile and the window is * redisplayed. * * Results: * Always returns 0 to keep the search from aborting. * * Side effects: * Information is redisplayed on the screen. * * ---------------------------------------------------------------------------- */ int windUpdateFunc(tile, w) Tile *tile; /* Tile in the redisplay plane. */ MagWindow *w; /* Window we're currently interested in. */ { Rect area; /* If this is a space tile, there's nothing to do. */ if (TiGetType(tile) == TT_SPACE) return 0; TiToRect(tile, &area); GeoClip(&area, &w->w_allArea); GeoClip(&area, &GrScreenRect); if ((area.r_xbot > area.r_xtop) || (area.r_ybot > area.r_ytop)) /* nothing to display */ return 0; /* Skip the border stuff if it isn't going to change. This * test has to be especially tricky because of the decision * that pixel at (0,0) extends from (0,0) up to but not including * (1,1). */ if (!((w->w_screenArea.r_xbot <= area.r_xbot) && (w->w_screenArea.r_xtop+1 >= area.r_xtop) && (w->w_screenArea.r_ybot <= area.r_ybot) && (w->w_screenArea.r_ytop+1 >= area.r_ytop))) { /* Redisplay the border areas. */ WindDrawBorder(w, &area); }; /* Now call the client to redisplay the interior of the window. */ if (GEO_TOUCH(&(w->w_screenArea), &area)) { Rect clientArea; WindScreenToSurface(w, &area, &clientArea); GeoClip(&area, &w->w_screenArea); if ( ((clientRec *) (w->w_client))->w_redisplay != NULL) { (*(( (clientRec *) (w->w_client))->w_redisplay)) (w, &clientArea, &area); } } return 0; } /* * ---------------------------------------------------------------------------- * * windBackgroundFunc -- * * Called for each tile left after redisplaying all of the windows. * This procedure just draws the background colors in any remaining * areas that have changed. * * Results: * Always returns 0 to keep the search from aborting. * * Side effects: * The background color gets drawn on the screen. * * ---------------------------------------------------------------------------- */ /* ARGSUSED */ int windBackgroundFunc(tile, notUsed) Tile *tile; ClientData notUsed; { Rect area; if (TiGetType(tile) == (TileType) TT_SPACE) return 0; TiToRect(tile, &area); /* Since windows include their border pixels, we have to be * a bit careful. If the upper or right edge of the area isn't * the edge of the screen, it is a window. In that case, decrement * the coordinate so we don't overwrite the edge of the window. */ if (area.r_xtop < GrScreenRect.r_xtop) area.r_xtop -= 1; if (area.r_ytop < GrScreenRect.r_ytop) area.r_ytop -= 1; GrLock(GR_LOCK_SCREEN, FALSE); GrClipBox(&area, STYLE_BACKGROUND); GrUnlock(GR_LOCK_SCREEN); return 0; } magic-8.0.210/windows/windCmdSZ.c0000644000175000001440000006517410751423606015173 0ustar timusers/* windCmdSZ.c - * * This file contains Magic command routines for those commands * that are valid in all windows. * * ********************************************************************* * * 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/windows/windCmdSZ.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include /* for sleep() */ #include #include #include "tcltk/tclmagic.h" #include "utils/magic.h" #include "textio/textio.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "windows/windows.h" #include "graphics/glyphs.h" #include "windows/windInt.h" #include "utils/undo.h" #include "utils/utils.h" #include "utils/signals.h" #include "textio/txcommands.h" #include "utils/hash.h" #include "database/database.h" #include "dbwind/dbwind.h" #include "graphics/graphics.h" /* * ---------------------------------------------------------------------------- * * windScrollCmd -- * * Scroll the view around * * Usage: * scroll dir [amount [units]] * * Results: * None. * * Side effects: * The window underneath the cursor is changed. * Note: behavior has been changed from original. To have "amount" * parsed as a fractional scroll amount, "units" *must* be declared * as "w". Otherwise, no units implies that "amount" is an absolute * value. * * * ---------------------------------------------------------------------------- */ void windScrollCmd(w, cmd) MagWindow *w; TxCommand *cmd; { Rect r; int xsize, ysize; Point p; int pos, locargc = cmd->tx_argc; float amount; bool doFractional = FALSE; if ( (cmd->tx_argc < 2) || (cmd->tx_argc > 4) ) { TxError("Usage: %s direction [amount [units]]\n", cmd->tx_argv[0]); return; } if (w == NULL) { TxError("Point to a window first.\n"); return; } if ((w->w_flags & WIND_SCROLLABLE) == 0) { TxError("Sorry, can't scroll this window.\n"); return; }; pos = GeoNameToPos(cmd->tx_argv[1], FALSE, TRUE); if (pos < 0 || pos == GEO_CENTER) return; if (cmd->tx_argc == 2) /* default = half-screen pan */ { r = w->w_screenArea; amount = 0.5; doFractional = TRUE; } else if (cmd->tx_argc == 4) { char unitc = cmd->tx_argv[3][0]; if (unitc == 'w') r = w->w_screenArea; else if (unitc == 'l') r = *(w->w_bbox); else { TxError("Usage: %s direction [amount [units]]\n", cmd->tx_argv[0]); TxError(" 'units' must be one of 'w' (window) or 'l' (layout);\n"); return; } if (sscanf(cmd->tx_argv[2], "%f", &amount) != 1) { TxError("Usage: %s direction [amount [units]]\n", cmd->tx_argv[0]); TxError(" 'amount' is a fractional value.\n"); return; } doFractional = TRUE; } if (doFractional) { xsize = (r.r_xtop - r.r_xbot) * amount; ysize = (r.r_ytop - r.r_ybot) * amount; } else { /* Alternate syntax: parse for integer coordinate amount to scroll */ xsize = cmdParseCoord(w, cmd->tx_argv[2], TRUE, TRUE); ysize = cmdParseCoord(w, cmd->tx_argv[2], TRUE, FALSE); } p.p_x = 0; p.p_y = 0; switch (pos) { case GEO_NORTH: p.p_y = -ysize; break; case GEO_SOUTH: p.p_y = ysize; break; case GEO_EAST: p.p_x = -xsize; break; case GEO_WEST: p.p_x = xsize; break; case GEO_NORTHEAST: p.p_x = -xsize; p.p_y = -ysize; break; case GEO_NORTHWEST: p.p_x = xsize; p.p_y = -ysize; break; case GEO_SOUTHEAST: p.p_x = -xsize; p.p_y = ysize; break; case GEO_SOUTHWEST: p.p_x = xsize; p.p_y = ysize; break; } if (doFractional) WindScroll(w, (Point *) NULL, &p); else { /* Direction is reversed w/respect to above call to WindScroll() */ p.p_x = -p.p_x; p.p_y = -p.p_y; WindScroll(w, &p, (Point *) NULL); } return; } /* * ---------------------------------------------------------------------------- * windSetpointCmd -- * * Use the x, y specified as the location of the point tool for the * next command. * * Results: * None. Under the Tcl interpreter, returns the screen and layout * coordinates as a list of four integers: sx sy lx ly. * * Side effects: * global variables. * ---------------------------------------------------------------------------- */ void windSetpointCmd(w, cmd) MagWindow *w; TxCommand *cmd; { int wid; Point rootPoint; #ifdef MAGIC_WRAPPER char *ptstr; #endif if ((cmd->tx_argc != 4) && (cmd->tx_argc != 3) && (cmd->tx_argc != 1)) goto usage; if ((cmd->tx_argc != 1) && ! (StrIsInt(cmd->tx_argv[1]) && StrIsInt(cmd->tx_argv[2])) ) goto usage; if (cmd->tx_argc == 4) { if (StrIsInt(cmd->tx_argv[3])) wid = atoi(cmd->tx_argv[3]); else if (GrWindowIdPtr) wid = (*GrWindowIdPtr)(cmd->tx_argv[3]); else wid = WIND_UNKNOWN_WINDOW; } else if (w != NULL) wid = w->w_wid; else { windCheckOnlyWindow(&w, DBWclientID); if (w != NULL) wid = w->w_wid; else wid = WIND_UNKNOWN_WINDOW; } /* Ensure a valid window, if possible */ if (w == NULL) w = WindSearchWid(wid); if (cmd->tx_argc == 1) { if (w != (MagWindow *) NULL) { WindPointToSurface(w, &cmd->tx_p, &rootPoint, (Rect *) NULL); #ifdef MAGIC_WRAPPER ptstr = (char *)Tcl_Alloc(50); sprintf(ptstr, "%d %d %d %d", cmd->tx_p.p_x, cmd->tx_p.p_y, rootPoint.p_x, rootPoint.p_y); Tcl_SetResult(magicinterp, ptstr, TCL_DYNAMIC); #else TxPrintf("Point is at screen coordinates (%d, %d) in window %d.\n", cmd->tx_p.p_x, cmd->tx_p.p_y, w->w_wid); TxPrintf("Point is at layout coordinates (%d, %d)\n", rootPoint.p_x, rootPoint.p_y); #endif } else { TxPrintf("Point is at screen coordinates (%d, %d).\n", cmd->tx_p.p_x, cmd->tx_p.p_y); } } else { int yval; yval = atoi(cmd->tx_argv[2]); /* Reinterpret coordinates according to the graphics package */ switch (WindPackageType) { case WIND_X_WINDOWS: /* Windows have origin at lower-left corner */ yval = w->w_allArea.r_ytop - yval; break; } TxSetPoint(atoi(cmd->tx_argv[1]), yval, wid); } return; usage: TxError("Usage: %s [x y [window ID|name]]\n", cmd->tx_argv[0]); } int windSetPrintProc(name, val) char *name; char *val; { TxPrintf("%s = \"%s\"\n", name, val); return 0; } /* * ---------------------------------------------------------------------------- * windSleepCmd -- * * Take a nap. * * Results: * None. * * Side effects: * None. * ---------------------------------------------------------------------------- */ void windSleepCmd(w, cmd) MagWindow *w; TxCommand *cmd; { int time; if (cmd->tx_argc != 2) { TxError("Usage: %s seconds\n", cmd->tx_argv[0]); return; } time = atoi(cmd->tx_argv[1]); for ( ; time > 1; time--) { sleep(1); if (SigInterruptPending) return; } } #ifndef MAGIC_WRAPPER /* * ---------------------------------------------------------------------------- * * windSourceCmd -- * * Implement the "source" command. * Process a file as a list of commands. * * Usage: * source filename * * Results: * None. * * Side effects: * Whatever the commands request. * * ---------------------------------------------------------------------------- */ void windSourceCmd(w, cmd) MagWindow *w; TxCommand *cmd; { FILE *f; if (cmd->tx_argc != 2) { TxError("Usage: %s filename\n", cmd->tx_argv[0]); return; } f = PaOpen(cmd->tx_argv[1], "r", (char *) NULL, ".", SysLibPath, (char **) NULL); if (f == NULL) TxError("Couldn't read from %s.\n", cmd->tx_argv[1]); else { TxDispatch(f); (void) fclose(f); }; } #endif /* * ---------------------------------------------------------------------------- * windSpecialOpenCmd -- * * Open a new window at the cursor position. Give it a default size, * and take the client's name from the command line. Pass the rest of * the command arguments off to the client. * * Results: * None. * * Side effects: * None. * ---------------------------------------------------------------------------- */ void windSpecialOpenCmd(w, cmd) MagWindow *w; TxCommand *cmd; { WindClient wc; Rect area; bool haveCoords; char *client; haveCoords = FALSE; if (cmd->tx_argc < 2) goto usage; haveCoords = StrIsInt(cmd->tx_argv[1]); if (haveCoords && ( (cmd->tx_argc < 6) || !StrIsInt(cmd->tx_argv[2]) || !StrIsInt(cmd->tx_argv[3]) || !StrIsInt(cmd->tx_argv[4]) )) goto usage; if (haveCoords) client = cmd->tx_argv[5]; else client = cmd->tx_argv[1]; wc = WindGetClient(client, FALSE); /* clients whose names begin with '*' are hidden */ if ((wc == (WindClient) NULL) || (client[0] == '*')) goto usage; if (haveCoords) { area.r_xbot = atoi(cmd->tx_argv[1]); area.r_ybot = atoi(cmd->tx_argv[2]); area.r_xtop = MAX(atoi(cmd->tx_argv[3]), area.r_xbot + WIND_MIN_WIDTH); area.r_ytop = MAX(atoi(cmd->tx_argv[4]), area.r_ybot + WIND_MIN_HEIGHT); /* Assume that the client will print an error message if it fails */ (void) WindCreate(wc, &area, FALSE, cmd->tx_argc - 6, cmd->tx_argv + 6); } else { area.r_xbot = cmd->tx_p.p_x - CREATE_WIDTH/2; area.r_xtop = cmd->tx_p.p_x + CREATE_WIDTH/2; area.r_ybot = cmd->tx_p.p_y - CREATE_HEIGHT/2; area.r_ytop = cmd->tx_p.p_y + CREATE_HEIGHT/2; /* Assume that the client will print an error message if it fails */ (void) WindCreate(wc, &area, TRUE, cmd->tx_argc - 2, cmd->tx_argv + 2); } return; usage: TxPrintf("Usage: specialopen [leftx bottomy rightx topy] type [args]\n"); TxPrintf("Valid window types are:\n"); WindPrintClientList(FALSE); return; } /* * ---------------------------------------------------------------------------- * windNamesCmd -- * * Register or retrieve the name associated with the layout window * * Results: * Returns the name as a Tcl string result. If "all" is selected, * or if w is NULL and cannot be determined, returns a list of all * window names. The first argument may also be a window client * type, in which case only windows of that type are returned. * * Note: * This routine can easily be made "generic", not Tcl-specific. * However, of the graphics interfaces available, only Tcl/Tk keeps * track of windows by name. * * ---------------------------------------------------------------------------- */ void windNamesCmd(w, cmd) MagWindow *w; TxCommand *cmd; { bool doforall = FALSE; WindClient wc = (WindClient)NULL; MagWindow *sw; if (cmd->tx_argc > 2) { TxError("Usage: windownames [all | client_type]\n"); return; } if (cmd->tx_argc == 2) { if (!strncmp(cmd->tx_argv[1], "all", 3)) doforall = TRUE; else { wc = WindGetClient(cmd->tx_argv[1], FALSE); if (wc == (WindClient) NULL) { TxError("Usage: windownames [all | client_type]\n"); TxPrintf("Valid window types are:\n"); WindPrintClientList(FALSE); return; } doforall = TRUE; } } if (cmd->tx_argc == 1) { wc = DBWclientID; windCheckOnlyWindow(&w, wc); if (w == (MagWindow *)NULL) doforall = TRUE; } #ifdef MAGIC_WRAPPER if (doforall == TRUE) { Tcl_Obj *tlist; tlist = Tcl_NewListObj(0, NULL); for (sw = windTopWindow; sw != NULL; sw = sw->w_nextWindow) if ((wc == NULL) || (sw->w_client == wc)) { if (GrWindowNamePtr) Tcl_ListObjAppendElement(magicinterp, tlist, Tcl_NewStringObj((*GrWindowNamePtr)(sw), -1)); else Tcl_ListObjAppendElement(magicinterp, tlist, Tcl_NewIntObj(sw->w_wid)); } Tcl_SetObjResult(magicinterp, tlist); } else { if (GrWindowNamePtr) Tcl_SetResult(magicinterp, (*GrWindowNamePtr)(w), NULL); else Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(w->w_wid)); } #else if (doforall == TRUE) { if (GrWindowNamePtr) TxPrintf("Window ID Window Name\n"); else TxPrintf("Window ID\n"); for (sw = windTopWindow; sw != NULL; sw = sw->w_nextWindow) if ((wc == (WindClient)NULL) || (sw->w_client == wc)) { if (GrWindowNamePtr) TxPrintf("%d %s\n", sw->w_wid, (*GrWindowNamePtr)(sw)); else TxPrintf("%d\n", sw->w_wid); } } else { if (GrWindowNamePtr) TxPrintf("Window ID = %d, Name = %s\n", w->w_wid, (*GrWindowNamePtr)(w)); else TxPrintf("Window ID = %d\n", w->w_wid); } #endif /* !MAGIC_WRAPPER */ } /* * ---------------------------------------------------------------------------- * windUnderCmd -- * * Move a window underneath the other windows. * * Results: * None. * * Side effects: * Screen updates. * ---------------------------------------------------------------------------- */ void windUnderCmd(w, cmd) MagWindow *w; TxCommand *cmd; { if (cmd->tx_argc != 1) { TxError("Usage: %s\n", cmd->tx_argv[0]); } if (w == NULL) { TxError("Point to a window first.\n"); return; } WindUnder(w); } /* * ---------------------------------------------------------------------------- * * windUndoCmd * * Implement the "undo" command. * * Usage: * undo [count] * * If a count is supplied, the last count events are undone. The default * count if none is given is 1. * * Results: * None. * * Side effects: * Calls the undo module. * * ---------------------------------------------------------------------------- */ void windUndoCmd(w, cmd) MagWindow *w; TxCommand *cmd; { int count; if (cmd->tx_argc > 3) { TxError("Usage: undo [count]\n"); TxError(" undo print [count]\n"); TxError(" undo enable|disable\n"); return; } else if (cmd->tx_argc == 3) { if (strncmp(cmd->tx_argv[1], "print", 5)) { TxError("Usage: undo print count\n"); return; } else if (!StrIsInt(cmd->tx_argv[2])) { TxError("Usage: undo print count\n"); return; } else { /* Implement undo stack trace */ UndoStackTrace((-1) - atoi(cmd->tx_argv[2])); return; } } else if (cmd->tx_argc == 2) { if (!StrIsInt(cmd->tx_argv[1])) { if (!strcmp(cmd->tx_argv[1], "enable")) UndoEnable(); else if (!strcmp(cmd->tx_argv[1], "disable")) UndoDisable(); else TxError("Option must be a count (integer)\n"); return; } count = atoi(cmd->tx_argv[1]); if (count < 0) { TxError("Count must be a positive integer\n"); return; } } else count = 1; if (count == 0) { UndoEnable(); } else { if (UndoBackward(count) == 0) TxPrintf("Nothing more to undo\n"); } } /* * ---------------------------------------------------------------------------- * windUpdateCmd -- * * Force an update of the graphics screen. This is usually only called * from command scripts. * * Results: * None. * * Side effects: * Display updates. * ---------------------------------------------------------------------------- */ void windUpdateCmd(w, cmd) MagWindow *w; TxCommand *cmd; { if (cmd->tx_argc == 1) WindUpdate(); #ifdef MAGIC_WRAPPER else if (cmd->tx_argc > 2) goto badusage; else if (!strcmp(cmd->tx_argv[1], "suspend")) GrDisplayStatus = DISPLAY_SUSPEND; else if (!strcmp(cmd->tx_argv[1], "resume")) GrDisplayStatus = DISPLAY_IDLE; else goto badusage; #else else if (cmd->tx_argc >= 2) goto badusage; #endif return; badusage: TxError("Usage: %s [suspend | resume]\n", cmd->tx_argv[0]); return; } /* * ---------------------------------------------------------------------------- * * windVersionCmd -- * * Print version information. * * Usage: * version * * Results: * None. * * Side effects: * Prints on stdout. * * ---------------------------------------------------------------------------- */ void windVersionCmd(w, cmd) MagWindow *w; TxCommand *cmd; { if (cmd->tx_argc != 1) { TxError("Usage: %s\n", cmd->tx_argv[0]); return; } TxPrintf("Version %s revision %s. Compiled on %s.\n", MagicVersion, MagicRevision, MagicCompileTime); } /* * ---------------------------------------------------------------------------- * * windViewCmd -- * * Implement the "View" command. * Change the view in the selected window so everything is visible. * * Usage: * view * * Results: * None. * * Side effects: * The window underneath the cursor is changed. * In Tcl version, if supplied with the argument "get", the * interpreter return value is set to the current view position. * * ---------------------------------------------------------------------------- */ void windViewCmd(w, cmd) MagWindow *w; TxCommand *cmd; { if (w == NULL) return; if (cmd->tx_argc == 1) { if ((w->w_flags & WIND_SCROLLABLE) == 0) { TxError("Sorry, can't zoom out this window.\n"); return; } WindView(w); } else if (cmd->tx_argc == 2) { #ifdef MAGIC_WRAPPER Tcl_Obj *listxy, *fval; listxy = Tcl_NewListObj(0, NULL); #endif if (!strncmp(cmd->tx_argv[1], "get", 3)) { #ifndef MAGIC_WRAPPER TxPrintf("(%d, %d) to (%d, %d)\n", w->w_surfaceArea.r_xbot, w->w_surfaceArea.r_ybot, w->w_surfaceArea.r_xtop, w->w_surfaceArea.r_ytop); #else Tcl_ListObjAppendElement(magicinterp, listxy, Tcl_NewIntObj((int)w->w_surfaceArea.r_xbot)); Tcl_ListObjAppendElement(magicinterp, listxy, Tcl_NewIntObj((int)w->w_surfaceArea.r_ybot)); Tcl_ListObjAppendElement(magicinterp, listxy, Tcl_NewIntObj((int)w->w_surfaceArea.r_xtop)); Tcl_ListObjAppendElement(magicinterp, listxy, Tcl_NewIntObj((int)w->w_surfaceArea.r_ytop)); Tcl_SetObjResult(magicinterp, listxy); #endif } else if (!strncmp(cmd->tx_argv[1], "bbox", 4)) { #ifndef MAGIC_WRAPPER TxPrintf("(%d, %d) to (%d, %d)\n", w->w_bbox->r_xbot, w->w_bbox->r_ybot, w->w_bbox->r_xtop, w->w_bbox->r_ytop); #else Tcl_ListObjAppendElement(magicinterp, listxy, Tcl_NewIntObj((int)w->w_bbox->r_xbot)); Tcl_ListObjAppendElement(magicinterp, listxy, Tcl_NewIntObj((int)w->w_bbox->r_ybot)); Tcl_ListObjAppendElement(magicinterp, listxy, Tcl_NewIntObj((int)w->w_bbox->r_xtop)); Tcl_ListObjAppendElement(magicinterp, listxy, Tcl_NewIntObj((int)w->w_bbox->r_ytop)); Tcl_SetObjResult(magicinterp, listxy); #endif } } else if (cmd->tx_argc == 5) { Rect r; r.r_xbot = cmdParseCoord(w, cmd->tx_argv[1], FALSE, TRUE); r.r_ybot = cmdParseCoord(w, cmd->tx_argv[2], FALSE, FALSE); r.r_xtop = cmdParseCoord(w, cmd->tx_argv[3], FALSE, TRUE); r.r_ytop = cmdParseCoord(w, cmd->tx_argv[4], FALSE, FALSE); /* Redisplay */ WindMove(w, &r); } else { TxError("Usage: view [get|bbox|llx lly urx ury]\n"); } } /* * ---------------------------------------------------------------------------- * * windXviewCmd -- * * Implement the "Xview" command. * Change the view in the selected window so everything is visible, but * not expanded. * * Usage: * xview * * Results: * None. * * Side effects: * The window underneath the cursor is changed. The root cell of the * window is unexpanded. * * ---------------------------------------------------------------------------- */ void windXviewCmd(w, cmd) MagWindow *w; TxCommand *cmd; { CellUse *celluse; int ViewUnexpandFunc(); if (w == NULL) return; if ((w->w_flags & WIND_SCROLLABLE) == 0) { TxError("Sorry, can't zoom out this window.\n"); return; }; celluse = (CellUse *) (w->w_surfaceID); DBExpandAll(celluse, &(celluse->cu_bbox), ((DBWclientRec *)w->w_clientData)->dbw_bitmask, FALSE, ViewUnexpandFunc, (ClientData)(pointertype) (((DBWclientRec *)w->w_clientData)->dbw_bitmask)); WindView(w); } /* This function is called for each cell whose expansion status changed. * It forces the cells area to be redisplayed, then returns 0 to keep * looking for more cells to unexpand. */ int ViewUnexpandFunc(use, windowMask) CellUse *use; /* Use that was just unexpanded. */ int windowMask; /* Window where it was unexpanded. */ { if (use->cu_parent == NULL) return 0; DBWAreaChanged(use->cu_parent, &use->cu_bbox, windowMask, (TileTypeBitMask *) NULL); return 0; } /* * ---------------------------------------------------------------------------- * * windScrollBarsCmd -- * * Change the flag which says whether new windows will have scroll bars. * * Usage: * windscrollbars [on|off] * * Results: * None. * * Side effects: * A flag is changed. * * ---------------------------------------------------------------------------- */ void windScrollBarsCmd(w, cmd) MagWindow *w; TxCommand *cmd; { int place; static char *onoff[] = {"on", "off", 0}; static bool truth[] = {TRUE, FALSE}; if (cmd->tx_argc != 2) goto usage; place = Lookup(cmd->tx_argv[1], onoff); if (place < 0) goto usage; if (truth[place]) { WindDefaultFlags |= WIND_SCROLLBARS; TxPrintf("New windows will have scroll bars.\n"); } else { WindDefaultFlags &= ~WIND_SCROLLBARS; TxPrintf("New windows will not have scroll bars.\n"); } return; usage: TxError("Usage: %s [on|off]\n", cmd->tx_argv[0]); return; } #ifndef MAGIC_WRAPPER /* * ---------------------------------------------------------------------------- * * windSendCmd -- * * Send a command to a certain window type. If possible we will pass a * arbitrarily chosen window of that type down to the client. * * Usage: * send type command * * Results: * None. * * Side effects: * Whatever the client does * * ---------------------------------------------------------------------------- */ void windSendCmd(w, cmd) MagWindow *w; TxCommand *cmd; { MagWindow *toWindow; WindClient client; TxCommand newcmd; extern int windSendCmdFunc(); if (cmd->tx_argc < 3) goto usage; if (cmd->tx_argv[1][0] == '*') goto usage; /* hidden window client */ client = WindGetClient(cmd->tx_argv[1], FALSE); if (client == (WindClient) NULL) goto usage; toWindow = (MagWindow *) NULL; (void) WindSearch(client, (ClientData) NULL, (Rect *) NULL, windSendCmdFunc, (ClientData) &toWindow); { int i; newcmd = *cmd; newcmd.tx_argc -= 2; for (i = 0; i < newcmd.tx_argc; i++) { newcmd.tx_argv[i] = newcmd.tx_argv[i + 2]; }; } newcmd.tx_wid = WIND_UNKNOWN_WINDOW; if (toWindow != NULL) newcmd.tx_wid = toWindow->w_wid; (void) WindSendCommand(toWindow, &newcmd); return; usage: TxError("Usage: send type command\n"); TxPrintf("Valid window types are:\n"); WindPrintClientList(FALSE); return; } int windSendCmdFunc(w, cd) MagWindow *w; ClientData cd; { *((MagWindow **) cd) = w; return 1; } #endif /* Structure used by "position" command to pass to WindSearch */ /* as client data. */ typedef struct _cdwpos { FILE *file; bool doFrame; } cdwpos; /* * ---------------------------------------------------------------------------- * * windPositionsCmd -- * * Print out the positions of the windows. * * Usage: * windowpositions [file] * * Results: * None. * * Side effects: * A file is written. * * ---------------------------------------------------------------------------- */ void windPositionsCmd(w, cmd) MagWindow *w; TxCommand *cmd; { extern int windPositionsFunc(); char *filename = NULL; cdwpos windpos; windpos.doFrame = FALSE; windpos.file = stdout; if (cmd->tx_argc > 3) goto usage; if (cmd->tx_argc > 1) { if (!strncmp(cmd->tx_argv[1], "frame", 5)) { windpos.doFrame = TRUE; if (cmd->tx_argc == 3) filename = cmd->tx_argv[2]; } else if (cmd->tx_argc == 2) filename = cmd->tx_argv[1]; else goto usage; } if (filename) { windpos.file = fopen(filename, "w"); if (windpos.file == (FILE *) NULL) { TxError("Could not open file %s for writing.\n", filename); return; }; } (void) WindSearch((WindClient) NULL, (ClientData) NULL, (Rect *) NULL, windPositionsFunc, (ClientData) &windpos); if (filename) (void) fclose(windpos.file); return; usage: TxError("Usage: windowpositions [file]\n"); return; } int windPositionsFunc(w, cdata) MagWindow *w; ClientData cdata; { cdwpos *windpos = (cdwpos *)cdata; Rect r; if (windpos->doFrame) r = w->w_frameArea; else r = w->w_screenArea; if (windpos->file == stdout) #ifdef MAGIC_WRAPPER { Tcl_Obj *lobj; lobj = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_NewIntObj((int)r.r_xbot)); Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_NewIntObj((int)r.r_ybot)); Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_NewIntObj((int)r.r_xtop)); Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_NewIntObj((int)r.r_ytop)); Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_NewStringObj(((clientRec *)w->w_client)->w_clientName, strlen(((clientRec *)w->w_client)->w_clientName))); Tcl_SetObjResult(magicinterp, lobj); } #else TxPrintf("specialopen %d %d %d %d %s\n", r.r_xbot, r.r_ybot, r.r_xtop, r.r_ytop, ((clientRec *) w->w_client)->w_clientName); #endif else fprintf((FILE *)cdata, "specialopen %d %d %d %d %s\n", r.r_xbot, r.r_ybot, r.r_xtop, r.r_ytop, ((clientRec *) w->w_client)->w_clientName); return 0; } /* * ---------------------------------------------------------------------------- * * windZoomCmd -- * * Implement the "zoom" command. * Change the view in the selected window by the given scale factor. * * Usage: * zoom amount * * Results: * None. * * Side effects: * The window underneath the cursor is changed. * * ---------------------------------------------------------------------------- */ void windZoomCmd(w, cmd) MagWindow *w; TxCommand *cmd; { float factor; if (w == NULL) return; if ((w->w_flags & WIND_SCROLLABLE) == 0) { TxError("Sorry, can't zoom this window.\n"); return; }; if (cmd->tx_argc != 2) { TxError("Usage: %s factor\n", cmd->tx_argv[0]); return; } factor = MagAtof(cmd->tx_argv[1]); if ((factor <= 0) || (factor >= 20)) { TxError("zoom factor must be between 0 and 20.\n"); return; } WindZoom(w, factor); } magic-8.0.210/windows/windMove.c0000644000175000001440000005405410751423606015114 0ustar timusers/* windMove.c - * * This file contains the functions which move windows around on * the screen. It does not contain the functions that change the * contents of the windows. * * ********************************************************************* * * 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/windows/windMove.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include "utils/magic.h" #include "textio/textio.h" #include "utils/geometry.h" #include "windows/windows.h" #include "graphics/graphics.h" #include "graphics/glyphs.h" #include "windows/windInt.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/malloc.h" /* The following own variable is used to pass information between * WindReframe and windFindUnobscured. */ static MagWindow *sharedW; /* * By default, new windows have scroll bars, border, a title caption, * and allow standard window commands. */ int WindDefaultFlags = WIND_SCROLLBARS | WIND_CAPTION | WIND_BORDER | WIND_COMMANDS | WIND_SCROLLABLE; /* * A mask of the current window IDs, as well as a limit on the number of * windows we can create. */ int windWindowMask = 0; /* One bit per window ID */ int windMaxWindows = 32; /* May be decreased via the WIND_MAX_WINDOWS() macro */ int windCurNumWindows = 0; /* * ---------------------------------------------------------------------------- * windUnlink -- * * Unlink a window from the doubly linked list of windows. * * Results: * None. * * Side effects: * The window is unlinked. * ---------------------------------------------------------------------------- */ void windUnlink(w) MagWindow *w; { ASSERT(w != (MagWindow *) NULL, "windUnlink"); ASSERT(windTopWindow != (MagWindow *) NULL, "windUnlink"); ASSERT(windBottomWindow != (MagWindow *) NULL, "windUnlink"); ASSERT(windTopWindow->w_prevWindow == (MagWindow *) NULL, "windUnlink"); ASSERT(windBottomWindow->w_nextWindow == (MagWindow *) NULL, "windUnlink"); if ( (windTopWindow == w) || (windBottomWindow == w) ) { if (windTopWindow == w) { windTopWindow = w->w_nextWindow; if (windTopWindow != (MagWindow *) NULL) windTopWindow->w_prevWindow = (MagWindow *) NULL; } if (windBottomWindow == w) { windBottomWindow = w->w_prevWindow; if (windBottomWindow != (MagWindow *) NULL) windBottomWindow->w_nextWindow = (MagWindow *) NULL; } } else { w->w_nextWindow->w_prevWindow = w->w_prevWindow; w->w_prevWindow->w_nextWindow = w->w_nextWindow; } w->w_nextWindow = (MagWindow *) NULL; w->w_prevWindow = (MagWindow *) NULL; } /* * ---------------------------------------------------------------------------- * * windFree -- * * This local procedure does the dirty work of freeing up * memory in a window. * * Results: * None. * * Side effects: * All storage associated with w is returned to the free pool. * * ---------------------------------------------------------------------------- */ void windFree(w) MagWindow *w; { windWindowMask &= ~(1 << w->w_wid); windCurNumWindows--; if (w->w_caption != (char *) NULL) freeMagic(w->w_caption); if (w->w_iconname != (char *) NULL) freeMagic(w->w_iconname); if (GrFreeBackingStorePtr != NULL) (*GrFreeBackingStorePtr)(w); if (w->w_redrawAreas != (ClientData) NULL) { DBFreePaintPlane( (Plane *) w->w_redrawAreas); TiFreePlane( (Plane *) w->w_redrawAreas); } freeMagic( (char *) w); } /* * ---------------------------------------------------------------------------- * WindSetWindowAreas -- * * Given the location of the window on the screen, compute w->w_allArea * and w->w_screenArea in the window's own coordinate system. * * Results: * None. * * Side effects: * Modifies w->w_allArea and w->w_screenArea. * ---------------------------------------------------------------------------- */ void WindSetWindowAreas(w) MagWindow *w; { switch ( WindPackageType ) { case WIND_X_WINDOWS: /* Windows have origin at lower-left corner */ w->w_allArea.r_xbot = w->w_allArea.r_ybot = 0; w->w_allArea.r_xtop = w->w_frameArea.r_xtop - w->w_frameArea.r_xbot; w->w_allArea.r_ytop = w->w_frameArea.r_ytop - w->w_frameArea.r_ybot; break; default: /* Windows are all in the same coordinate system */ w->w_allArea = w->w_frameArea; } WindOutToIn(w, &w->w_allArea, &w->w_screenArea); } /* * ---------------------------------------------------------------------------- * windSetWindowPosition -- * * (deprecated function) * * Results: * None. * * Side effects: * None. * ---------------------------------------------------------------------------- */ void windSetWindowPosition(w) MagWindow *w; { } /* * ---------------------------------------------------------------------------- * WindDelete -- * * Delete a window. * * Results: * TRUE if the window was deleted, FALSE otherwise. * * Side effects: * The window disappears from the sreen. The window's client is notified * that this is about to happen, and it may refuse to let it happen. * ---------------------------------------------------------------------------- */ bool WindDelete(w) MagWindow *w; { clientRec *cr; ASSERT(w != (MagWindow *) NULL, "WindDelete"); cr = (clientRec *) w->w_client; if ( (cr->w_delete == NULL) || (*(cr->w_delete))(w) ) { WindAreaChanged(w, &(w->w_allArea) ); if (GrDeleteWindowPtr != NULL) (*GrDeleteWindowPtr)(w); windUnlink(w); windReClip(); windFree(w); return TRUE; } else return FALSE; } /* * ---------------------------------------------------------------------------- * WindCreate -- * * Create a new window for the specified client. * * Results: * A pointer to the new window, or NULL if one couldn't be created. * * Side effects: * An empty window is created, and it is displayed. * The new window is place on top of all the other * windows. * ---------------------------------------------------------------------------- */ MagWindow * WindCreate(client, frameArea, isHint, argc, argv) WindClient client; /* The client that will control this window */ Rect *frameArea; /* The area that the window is to occupy */ bool isHint; /* TRUE if the above rectangle is only a * hint and it is OK for a window package to * override it to maintain a consistent * user interface. */ int argc; /* Passed to the client */ char *argv[]; { MagWindow *w; clientRec *cr; bool OK; int id; if (windCurNumWindows + 1 > windMaxWindows) { TxError("Can't have more than %d windows.\n", windMaxWindows); return NULL; } windCurNumWindows++; cr = (clientRec *) client; /* initialize the window */ w = (MagWindow *) mallocMagic( sizeof(MagWindow) ); w->w_client = client; w->w_flags = WindDefaultFlags; w->w_clipAgainst = (LinkedRect *) NULL; w->w_caption = (char *) NULL; w->w_stippleOrigin.p_x = 0; w->w_stippleOrigin.p_y = 0; w->w_bbox = NULL; w->w_grdata = (ClientData) NULL; w->w_backingStore = (ClientData)NULL; w->w_redrawAreas = (ClientData) NULL; w->w_iconname = NULL; for (id = 0; ((1 << id) & windWindowMask) != 0; id++) /* advance id */ ; windWindowMask |= (1 << id); w->w_wid = id; /* locate window on the screen */ if (frameArea == (Rect *) NULL) { switch ( WindPackageType ) { case WIND_X_WINDOWS: /* * Create default size window in upper left corner * of screen. */ w->w_frameArea.r_xbot = GrScreenRect.r_xbot; w->w_frameArea.r_ytop = GrScreenRect.r_ytop; w->w_frameArea.r_xtop = (GrScreenRect.r_xtop - GrScreenRect.r_xbot) / 2; w->w_frameArea.r_ybot = (GrScreenRect.r_ytop - GrScreenRect.r_ybot) / 2; break; default: w->w_frameArea = GrScreenRect; } } else w->w_frameArea = *frameArea; WindSetWindowAreas(w); /* now link the window in on top */ w->w_nextWindow = windTopWindow; w->w_prevWindow = (MagWindow *) NULL; if (windTopWindow == (MagWindow *) NULL) windBottomWindow = w; else windTopWindow->w_prevWindow = w; windTopWindow = w; /* notify the client */ OK = ((cr->w_create == NULL) || (*(cr->w_create))(w, argc, argv)); #ifdef THREE_D if (strcmp(cr->w_clientName, "wind3d")) #endif if (OK && (GrCreateWindowPtr != NULL)) OK = (*GrCreateWindowPtr)(w, (argc > 1) ? argv[1] : NULL); if (OK) { WindSetWindowAreas(w); windSetWindowPosition(w); WindAreaChanged(w, &(w->w_allArea)); } else { /* the client refused the new window */ windUnlink(w); windFree(w); w = (MagWindow *) NULL; } windReClip(); if ((GrCreateBackingStorePtr != NULL) && (w != NULL) && (!(w->w_flags & WIND_OBSCURED))) (*GrCreateBackingStorePtr)(w); return w; } /* * ---------------------------------------------------------------------------- * * WindOutToIn and WindInToOut -- * * The two procedures on this page translate from window inside * area (the area used to display the surface) to window * outside area (the total area of the window including caption), * and vice versa. * * Results: * None. * * Side effects: * Each procedure modifies its third parameter. WindOutToIn * fills in the third parameter with the inside area of the * window whose outside area is out, and WindInToOut does the * opposite. * * ---------------------------------------------------------------------------- */ void WindOutToIn(w, out, in) MagWindow *w; /* Window under consideration */ Rect *out; /* Pointer to rectangle of outside area of * a window. */ Rect *in; /* Pointer to rectangle to be filled in with * inside area corresponding to out. */ { *in = *out; in->r_xbot += LEFT_BORDER(w); in->r_xtop -= RIGHT_BORDER(w); in->r_ybot += BOT_BORDER(w); in->r_ytop -= TOP_BORDER(w); } void WindInToOut(w, in, out) MagWindow *w; /* Window under consideration */ Rect *in; /* Pointer to rectangle of outside area of * a window. */ Rect *out; /* Pointer to rectangle to be filled in with * inside area corresponding to out. */ { *out = *in; out->r_xbot -= LEFT_BORDER(w); out->r_xtop += RIGHT_BORDER(w); out->r_ybot -= BOT_BORDER(w); out->r_ytop += TOP_BORDER(w); } /* * ---------------------------------------------------------------------------- * WindUnder -- * * Move a window underneath the rest. * * Results: * None. * * Side effects: * The window is moved so that it is underneath the rest. This will * cause portions of uncovered windows to be redisplayed. * ---------------------------------------------------------------------------- */ void WindUnder(w) MagWindow *w; /* the window to be moved */ { Rect area; MagWindow *w2; switch ( WindPackageType ) { case WIND_X_WINDOWS: if ( GrUnderWindowPtr ) (*GrUnderWindowPtr)(w); break; default: /* Mark for redisplay all the areas that this window * currently obscures. */ for (w2 = w->w_nextWindow; w2 != NULL; w2 = w2->w_nextWindow) { area = w2->w_allArea; GeoClip(&area, &w->w_allArea); if ((area.r_xbot <= area.r_xtop) && (area.r_ybot <= area.r_ytop)) WindAreaChanged(w, &area); } /* take the window out of the linked list */ windUnlink(w); /* now link it back in at the bottom */ w->w_prevWindow = windBottomWindow; if (windBottomWindow != (MagWindow *) NULL) windBottomWindow->w_nextWindow = w; else windTopWindow = w; windBottomWindow = w; windReClip(); } } /* * ---------------------------------------------------------------------------- * WindOver -- * * Move a window so that it is over (on top of) the other windows. * * Results: * None. * * Side effects: * The window is moved to the top. This may obscure some other windows. * The window that is moved will be redisplayed. * ---------------------------------------------------------------------------- */ void WindOver(w) MagWindow *w; /* the window to be moved */ { LinkedRect *r; Rect area; switch ( WindPackageType ) { case WIND_X_WINDOWS: if ( GrOverWindowPtr ) (*GrOverWindowPtr)(w); break; default: /* Mark for redisplay all of the areas of the screen that * currently obscure this window. */ for (r = w->w_clipAgainst; r != NULL; r = r->r_next) { area = r->r_r; GeoClip(&area, &w->w_frameArea); if ((area.r_xbot <= area.r_xtop) && (area.r_ybot <= area.r_ytop)) WindAreaChanged((MagWindow *) NULL, &area); } /* take the window out of the linked list */ windUnlink(w); /* now link it back in at the top */ w->w_nextWindow = windTopWindow; if (windTopWindow != (MagWindow *) NULL) windTopWindow->w_prevWindow = w; else windBottomWindow = w; windTopWindow = w; windReClip(); } } /* * ---------------------------------------------------------------------------- * * windFindUnobscured -- * * Locates one portion of a rectangle that is unobscured, if * any part of the rectangle is unobscured. Used only by * WindReframe. * * Results: * Always returns TRUE. * * Side effects: * The caller must place in the shared variable sharedW the * name of a window, or NULL. That window, and all windows * above it, are checked to see if any obscure area. If * there is any unobscured part of area, it is placed in * okArea. If several distinct parts of area are unobscured, * one, but only one, of them will be placed in okArea. * * ---------------------------------------------------------------------------- */ int windFindUnobscured(area, okArea) Rect *area; /* Area that may be obscured. */ Rect *okArea; /* Modified to contain one of the * unobscured areas. */ { MagWindow *w; w = sharedW; if (w == NULL) { *okArea = *area; return FALSE; } sharedW = w->w_prevWindow; (void) GeoDisjoint(area, &w->w_frameArea, windFindUnobscured, (ClientData) okArea); return FALSE; } /* * ---------------------------------------------------------------------------- * WindReframe -- * * Change the size or location of a window. * * Results: * None. * * Side effects: * The window is moved, and areas of the screen are marked for * redisplay. This routine tries to be tricky in order to avoid * massive redisplay for small changes. * ---------------------------------------------------------------------------- */ void WindReframe(w, r, inside, move) MagWindow *w; /* the window to be reframed */ Rect *r; /* the new location in screen coordinates */ bool inside; /* TRUE if the rectangle is the screen location of * the inside of the window, FALSE if the above * rectangle includes border areas. */ bool move; /* Move the coordinate system of the window the same * amount as the lower left corner of the window? */ { Rect newFrameArea; /* New w_frameArea. */ Rect dontRedisplay; /* Used to record an area that does * not have to be redisplayed. */ int xmove, ymove; /* Distance window is moving. */ extern int windReframeFunc(); /* Forward declaration. */ clientRec *cr; cr = (clientRec *) w->w_client; /* Ensure that the new window size is not inside out and has some size to * it. Compute the new w_frameArea (in newFrameArea). */ GeoCanonicalRect(r, &newFrameArea); if (inside) WindInToOut(w, &newFrameArea, &newFrameArea); if ((w->w_flags & WIND_ISICONIC) == 0) { /* Not iconic -- enforce a minimum size */ newFrameArea.r_xtop = MAX(newFrameArea.r_xtop, newFrameArea.r_xbot + WIND_MIN_WIDTH); newFrameArea.r_ytop = MAX(newFrameArea.r_ytop, newFrameArea.r_ybot + WIND_MIN_HEIGHT); } /* Give the client a chance to modify the change. */ if (cr->w_reposition != NULL) (*(cr->w_reposition))(w, &newFrameArea, FALSE); /* If the window coordinates are moving, update the transform * so that the lower-left corner of the window remains at the * same location in surface coordinates. */ if (move) { xmove = newFrameArea.r_xbot - w->w_frameArea.r_xbot; w->w_origin.p_x += xmove << SUBPIXELBITS; ymove = newFrameArea.r_ybot - w->w_frameArea.r_ybot; w->w_origin.p_y += ymove << SUBPIXELBITS; w->w_stippleOrigin.p_x += xmove; w->w_stippleOrigin.p_y += ymove; } switch ( WindPackageType ) { case WIND_X_WINDOWS: break; default: /* Now comes the tricky part: figuring out what to redisplay. * The simple way out is to force redisplay at both the old and * new window positions. Naturally this code is going to be more * ambitious. There are two steps. First, figure out what piece * of the old window must be redisplayed, then move the window, * then figure out what pieces of the new window must be redisplayed. * If the window coordinates aren't moving, then any screen area * common to the old and new positions needn't be redisplayed, * since its contents won't change. */ if (!move) { /* Compute the intersection of the old and new areas in * dontRedisplay. Mark old areas outside of this common area as * needing to be redisplayed. */ WindOutToIn(w, &newFrameArea, &dontRedisplay); GeoClip(&dontRedisplay, &w->w_screenArea); (void) GeoDisjoint(&w->w_frameArea, &dontRedisplay, windReframeFunc, (ClientData) w); } else { /* Record the entire old area as needing to be redisplayed. */ WindAreaChanged(w, &w->w_allArea); dontRedisplay = w->w_allArea; } } /* At this point, we've recorded any old area that needs to be * redisplayed. */ w->w_frameArea = newFrameArea; WindSetWindowAreas(w); windSetWindowPosition(w); windFixSurfaceArea(w); windReClip(); switch (WindPackageType) { case WIND_X_WINDOWS: /* Regenerate backing store, if enabled */ if ((GrCreateBackingStorePtr != NULL) && (!(w->w_flags & WIND_OBSCURED))) (*GrCreateBackingStorePtr)(w); break; default: /* Now that the window has been moved, record any of the new area that * has to be redisplayed. */ (void) GeoDisjoint(&w->w_allArea, &dontRedisplay, windReframeFunc, (ClientData) w); } /* Give the client a chance to do things like windMove(). */ if (cr->w_reposition != NULL) (*(cr->w_reposition))(w, &newFrameArea, TRUE); } int windReframeFunc(area, w) Rect *area; /* Area to redisplay. */ MagWindow *w; /* Window in which to redisplay. */ { WindAreaChanged(w, area); return 0; } /* * ---------------------------------------------------------------------------- * * WindFullScreen -- * * This procedure blows a window up so it's on top of all the others * and is full-screen. Or, if the window was already full-screen, * it is put back where it came from before it was made full-screen. * * Results: * None. * * Side effects: * The window's size and location are changed. * * ---------------------------------------------------------------------------- */ void WindFullScreen(w) MagWindow *w; /* Window to be blown up or shrunk back. */ { int i; MagWindow *w2; Rect newFrameArea; clientRec *cr; int newDepth; cr = (clientRec *) w->w_client; /* Compute default new location. */ if (w->w_flags & WIND_FULLSCREEN) newFrameArea = w->w_oldArea; else newFrameArea = GrScreenRect; /* Give the client a chance to modify newFrameArea. */ if (cr->w_reposition != NULL) (*(cr->w_reposition))(w, &newFrameArea, FALSE); /* * Now, actually modify the window and its position. */ /* Compute new stuff. */ if (w->w_flags & WIND_FULLSCREEN) { newDepth = w->w_oldDepth; w->w_flags &= ~WIND_FULLSCREEN; } else { newDepth = 0; w->w_flags |= WIND_FULLSCREEN; /* Record old depth and area. */ w->w_oldArea = w->w_frameArea; w->w_oldDepth = 0; for (w2 = windTopWindow; w2 != w; w2 = w2->w_nextWindow) { ASSERT(w2 != (MagWindow *) NULL, "WindFullScreen"); w->w_oldDepth += 1; } } /* Change the view and screen location. */ w->w_frameArea = newFrameArea; WindSetWindowAreas(w); windSetWindowPosition(w); WindMove(w, &w->w_surfaceArea); /* Move the window to the proper depth. */ if (windTopWindow != (MagWindow *) NULL) { if (newDepth == 0) { switch ( WindPackageType ) { case WIND_X_WINDOWS: break; default: WindOver(w); } } else { windUnlink(w); w2 = windTopWindow; for (i=1; iw_nextWindow != NULL) w2 = w2->w_nextWindow; w->w_nextWindow = w2->w_nextWindow; w->w_prevWindow = w2; w2->w_nextWindow = w; if (w->w_nextWindow == NULL) windBottomWindow = w; else w->w_nextWindow->w_prevWindow = w; windReClip(); } } /* Notify the client. */ if (cr->w_reposition != NULL) (*(cr->w_reposition))(w, &newFrameArea, TRUE); /* Record new display areas. */ switch (WindPackageType) { case WIND_X_WINDOWS: if (GrConfigureWindowPtr != NULL) (*GrConfigureWindowPtr)(w); if (GrCreateBackingStorePtr != NULL && (!(w->w_flags & WIND_OBSCURED))) (*GrCreateBackingStorePtr)(w); break; default: WindAreaChanged((MagWindow *) NULL, (Rect *) NULL); } } magic-8.0.210/windows/windows14.glyphs0000644000175000001440000000435410751423606016245 0ustar timusers# # 14-pixel wide glyphs for the window package # # rcsid $Header: /usr/cvsroot/magic-8.0/windows/windows14.glyphs,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ # # # syntax of first line: size size 5 14 14 #up W W W W W W W W W W W W W W W W W W W W K K W W W W W W W W W W W K K K K W W W W W W W W W K K K K K K W W W W W W W K K K K K K K K W W W W W K K K K K K K K K K W W W K K K K K K K K K K K K W K K K K K K K K K K K K K K W W W W K K K K K K W W W W W W W W K K K K K K W W W W W W W W K K K K K K W W W W W W W W K K K K K K W W W W W W W W K K K K K K W W W W W W W W W W W W W W W W W W #down W W W W W W W W W W W W W W W W W W K K K K K K W W W W W W W W K K K K K K W W W W W W W W K K K K K K W W W W W W W W K K K K K K W W W W W W W W K K K K K K W W W W K K K K K K K K K K K K K K W K K K K K K K K K K K K W W W K K K K K K K K K K W W W W W K K K K K K K K W W W W W W W K K K K K K W W W W W W W W W K K K K W W W W W W W W W W W K K W W W W W W W W W W W W W W W W W W W W #left W W W W W W W K W W W W W W W W W W W W K K W W W W W W W W W W W K K K W W W W W W W W W W K K K K W W W W W W W W W K K K K K K K K K K W W W K K K K K K K K K K K W W K K K K K K K K K K K K W W K K K K K K K K K K K K W W W K K K K K K K K K K K W W W W K K K K K K K K K K W W W W W K K K K W W W W W W W W W W W K K K W W W W W W W W W W W W K K W W W W W W W W W W W W W K W W W W W W #right W W W W W W K W W W W W W W W W W W W W K K W W W W W W W W W W W W K K K W W W W W W W W W W W K K K K W W W W W K K K K K K K K K K W W W W K K K K K K K K K K K W W W K K K K K K K K K K K K W W K K K K K K K K K K K K W W K K K K K K K K K K K W W W K K K K K K K K K K W W W W W W W W W K K K K W W W W W W W W W W K K K W W W W W W W W W W W K K W W W W W W W W W W W W K W W W W W W W #zoom W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W K K K K K K K K K K W W W W K K K K K K K K K K W W W W K K W W W W W W K K W W W W K K W W W W W W K K W W W W K K W W K K W W K K W W W W K K W W K K W W K K W W W W K K W W W W W W K K W W W W K K W W W W W W K K W W W W K K K K K K K K K K W W W W K K K K K K K K K K W W W W W W W W W W W W W W W W W W W W W W W W W W W W W W magic-8.0.210/windows/windCmdAM.c0000664000175000001440000006047212405633025015126 0ustar timusers/* windCmdAM.c - * * This file contains Magic command routines for those commands * that are valid in all windows. * * ********************************************************************* * * 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/windows/windCmdAM.c,v 1.2 2008/12/11 04:20:15 tim Exp $"; #endif /* not lint */ #include #include #include #include #include #include #include #include #include /* for round() function */ #include "tcltk/tclmagic.h" #include "utils/magic.h" #include "textio/textio.h" #include "utils/geometry.h" #include "windows/windows.h" #include "utils/malloc.h" #include "utils/runstats.h" #include "utils/macros.h" #include "utils/signals.h" #include "graphics/graphics.h" #include "utils/styles.h" #include "textio/txcommands.h" #include "graphics/glyphs.h" #include "windows/windInt.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "dbwind/dbwind.h" #include "utils/utils.h" #include "cif/cif.h" /* Forward declarations */ void windDoMacro(); /* * ---------------------------------------------------------------------------- * * windBorderCmd -- * * Change the flag which says whether new windows will have a border. * * Usage: * windborder [on|off] * * Results: * None. * * Side effects: * A flag is changed. * In Tcl, if no options are presented, the border status is returned * in the command exit status. * * ---------------------------------------------------------------------------- */ void windBorderCmd(w, cmd) MagWindow *w; TxCommand *cmd; { int place; bool value; static char *onoff[] = {"on", "off", 0}; static bool truth[] = {TRUE, FALSE}; if (cmd->tx_argc > 2) goto usage; else if (cmd->tx_argc == 1) { if (w == (MagWindow *)NULL) { TxError("No window specified for caption command\n"); goto usage; } value = (w->w_flags & WIND_BORDER) ? 0 : 1; #ifdef MAGIC_WRAPPER Tcl_SetResult(magicinterp, onoff[value], TCL_STATIC); #else TxPrintf("Window border is %s\n", onoff[value]); #endif return; } place = Lookup(cmd->tx_argv[1], onoff); if (place < 0) goto usage; if (truth[place]) { WindDefaultFlags |= WIND_BORDER; TxPrintf("New windows will have a border.\n"); } else { WindDefaultFlags &= ~WIND_BORDER; TxPrintf("New windows will not have a border.\n"); } return; usage: TxError("Usage: %s [on|off]\n", cmd->tx_argv[0]); return; } /* * ---------------------------------------------------------------------------- * * windCaptionCmd -- * * Change the flag which says whether new windows will have a title caption. * * Usage: * windcaption [on|off] * * Results: * None. * * Side effects: * A flag is changed. * In Tcl, if no options are presented, the window title caption is * returned in the command status. * * ---------------------------------------------------------------------------- */ void windCaptionCmd(w, cmd) MagWindow *w; TxCommand *cmd; { int place; Rect ts; static char *onoff[] = {"on", "off", 0}; static bool truth[] = {TRUE, FALSE}; if (cmd->tx_argc > 2) goto usage; else if (cmd->tx_argc == 1) { if (w == (MagWindow *)NULL) { TxError("No window specified for caption command\n"); goto usage; } #ifdef MAGIC_WRAPPER Tcl_SetResult(magicinterp, w->w_caption, TCL_STATIC); #else TxPrintf("Window caption is \"%s\"\n", w->w_caption); #endif return; } place = Lookup(cmd->tx_argv[1], onoff); if (place < 0) goto usage; if (truth[place]) { WindDefaultFlags |= WIND_CAPTION; TxPrintf("New windows will have a title caption.\n"); } else { WindDefaultFlags &= ~WIND_CAPTION; TxPrintf("New windows will not have a title caption.\n"); } return; usage: TxError("Usage: %s [on|off]\n", cmd->tx_argv[0]); return; } /* * ---------------------------------------------------------------------------- * * windCenterCmd -- * * Implement the "center" command. * Move a window's view to center the point underneath the cursor, or to * the specified coordinate (in surface units). * * Usage: * center [x y] * center horizontal|vertical f * * Results: * None. * * Side effects: * The view in the window underneath the cursor is changed * to center the point underneath the cursor. * * ---------------------------------------------------------------------------- */ void windCenterCmd(w, cmd) MagWindow *w; TxCommand *cmd; { Point rootPoint; Rect newArea, oldArea; if (w == NULL) { TxError("Point to a window first.\n"); return; } if (cmd->tx_argc == 1) { if ((w->w_flags & WIND_SCROLLABLE) == 0) { TxError("Sorry, can't scroll this window.\n"); return; } WindPointToSurface(w, &cmd->tx_p, &rootPoint, (Rect *) NULL); } else if (cmd->tx_argc == 3) { if ((w->w_flags & WIND_SCROLLABLE) == 0) { TxError("Sorry, can't scroll this window.\n"); return; } if (cmd->tx_argv[1][0] == 'h' || cmd->tx_argv[1][0] == 'v') { double frac; if (!StrIsNumeric(cmd->tx_argv[2])) { TxError("Must specify a fractional value.\n"); return; } frac = atof(cmd->tx_argv[2]); if (cmd->tx_argv[1][0] == 'h') { rootPoint.p_y = 0; rootPoint.p_x = w->w_bbox->r_xbot + frac * (w->w_bbox->r_xtop - w->w_bbox->r_xbot) - (w->w_surfaceArea.r_xtop + w->w_surfaceArea.r_xbot)/2; } else { rootPoint.p_x = 0; rootPoint.p_y = w->w_bbox->r_ybot + frac * (w->w_bbox->r_ytop - w->w_bbox->r_ybot) - (w->w_surfaceArea.r_ytop + w->w_surfaceArea.r_ybot)/2; } WindScroll(w, &rootPoint, (Point *)NULL); return; } else { if (!StrIsInt(cmd->tx_argv[1]) || !StrIsInt(cmd->tx_argv[2])) { TxError("Coordinates must be integer values\n"); return; } rootPoint.p_x = atoi(cmd->tx_argv[1]); rootPoint.p_y = atoi(cmd->tx_argv[2]); } } else { TxError("Usage: center [x y]\n"); TxError(" center horizontal|vertical f\n"); return; } oldArea = w->w_surfaceArea; newArea.r_xbot = rootPoint.p_x - (oldArea.r_xtop - oldArea.r_xbot)/2; newArea.r_xtop = newArea.r_xbot - oldArea.r_xbot + oldArea.r_xtop; newArea.r_ybot = rootPoint.p_y - (oldArea.r_ytop - oldArea.r_ybot)/2; newArea.r_ytop = newArea.r_ybot - oldArea.r_ybot + oldArea.r_ytop; WindMove(w, &newArea); } /* * ---------------------------------------------------------------------------- * windCloseCmd -- * * Close the window that is pointed at. * * Results: * None. * * Side effects: * The window is closed, and the client is notified. The client may * refuse to have the window closed, in which case nothing happens. * ---------------------------------------------------------------------------- */ void windCloseCmd(w, cmd) MagWindow *w; TxCommand *cmd; { if ((cmd->tx_argc == 2) && GrWindowNamePtr) { char *mwname; for (w = windTopWindow; w != (MagWindow *)NULL; w = w->w_nextWindow) { mwname = (*GrWindowNamePtr)(w); if (!strcmp(mwname, cmd->tx_argv[1])) break; } if (w == NULL) { TxError("Window named %s cannot be found\n", cmd->tx_argv[1]); return; } } if (w == (MagWindow *) NULL) { TxError("Point to a window first\n"); return; } if (!WindDelete(w)) { TxError("Unable to close that window\n"); return; } } #ifdef MAGIC_WRAPPER /* * ---------------------------------------------------------------------------- * windBypassCmd -- * * Run a magic command independently of the command line. That is, * if a command is being typed on the command line, the input * redirection will not be reset by the execution of this command. * * Results: * None. * * Side effects: * * * ---------------------------------------------------------------------------- */ void windBypassCmd(w, cmd) MagWindow *w; TxCommand *cmd; { if (cmd->tx_argc == 1) { TxError("Usage: *bypass \n"); return; } /* Dispatch the referenced command */ TxTclDispatch((ClientData)w, cmd->tx_argc - 1, cmd->tx_argv + 1); if (TxInputRedirect == TX_INPUT_PENDING_RESET) TxInputRedirect = TX_INPUT_REDIRECTED; } #endif /* MAGIC_WRAPPER */ /* * ---------------------------------------------------------------------------- * windCrashCmd -- * * Generate a core dump. * * Results: * None. * * Side effects: * Dumps core by calling niceabort(). * * ---------------------------------------------------------------------------- */ void windCrashCmd(w, cmd) MagWindow *w; TxCommand *cmd; { if (cmd->tx_argc != 1) { TxError("Usage: *crash\n"); return; } TxPrintf("OK -- crashing...\n"); TxFlush(); niceabort(); } /* * ---------------------------------------------------------------------------- * windCursorCmd -- * * Report the cursor position in Magic (internal) coordinates * If an argument of a number is given, then the cursor icon * is changed to the glyph of that number. * * Results: * None. * * Side effects: * Prints coordinates (non-Tcl version) * Return value set to the cursor position as a list (Tcl version) * ---------------------------------------------------------------------------- */ void windCursorCmd(w, cmd) MagWindow *w; TxCommand *cmd; { Point p_in, p_out; int resulttype = DBW_SNAP_INTERNAL; double cursx, cursy, oscale; DBWclientRec *crec; #ifdef MAGIC_WRAPPER Tcl_Obj *listxy; #endif if (cmd->tx_argc == 2) { if (StrIsInt(cmd->tx_argv[1])) { if (GrSetCursorPtr != NULL) (*GrSetCursorPtr)(atoi(cmd->tx_argv[1])); return; } else if (*cmd->tx_argv[1] == 'l') { resulttype = DBW_SNAP_LAMBDA; } else if (*cmd->tx_argv[1] == 'u') { resulttype = DBW_SNAP_USER; } else if (*cmd->tx_argv[1] == 'm') { resulttype = DBW_SNAP_MICRONS; } else if (*cmd->tx_argv[1] != 'i') { TxError("Usage: cursor glyphnum\n"); TxError(" (or): cursor [internal | lambda | microns | user]\n"); return; } } if (GrGetCursorPosPtr == NULL) return; GrGetCursorPos(w, &p_in); WindPointToSurface(w, &p_in, &p_out, (Rect *)NULL); /* Snap the cursor position if snap is in effect */ if (DBWSnapToGrid != DBW_SNAP_INTERNAL) ToolSnapToGrid(w, &p_out, (Rect *)NULL); /* Transform the result to declared units with option "lambda" or "grid" */ switch (resulttype) { case DBW_SNAP_INTERNAL: cursx = (double)p_out.p_x; cursy = (double)p_out.p_y; break; case DBW_SNAP_LAMBDA: cursx = (double)(p_out.p_x * DBLambda[0]) / (double)DBLambda[1]; cursy = (double)(p_out.p_y * DBLambda[0]) / (double)DBLambda[1]; break; case DBW_SNAP_MICRONS: oscale = (double)CIFGetOutputScale(1000); cursx = (double)(p_out.p_x * oscale); cursy = (double)(p_out.p_y * oscale); break; case DBW_SNAP_USER: crec = (DBWclientRec *)w->w_clientData; cursx = (double)((p_out.p_x - crec->dbw_gridRect.r_xbot) / (crec->dbw_gridRect.r_xtop - crec->dbw_gridRect.r_xbot)); cursy = (double)((p_out.p_y - crec->dbw_gridRect.r_ybot) / (crec->dbw_gridRect.r_ytop - crec->dbw_gridRect.r_ybot)); break; } #ifdef MAGIC_WRAPPER listxy = Tcl_NewListObj(0, NULL); if ((cursx == round(cursx)) && (cursy == round(cursy))) { Tcl_ListObjAppendElement(magicinterp, listxy, Tcl_NewIntObj((int)cursx)); Tcl_ListObjAppendElement(magicinterp, listxy, Tcl_NewIntObj((int)cursy)); } else { Tcl_ListObjAppendElement(magicinterp, listxy, Tcl_NewDoubleObj(cursx)); Tcl_ListObjAppendElement(magicinterp, listxy, Tcl_NewDoubleObj(cursy)); } Tcl_SetObjResult(magicinterp, listxy); #else TxPrintf("%g %g\n", cursx, cursy); #endif } /* * ---------------------------------------------------------------------------- * windDebugCmd -- * * Change to a new debugging mode. * * Results: * None. * * Side effects: * None. * ---------------------------------------------------------------------------- */ void windDebugCmd(w, cmd) MagWindow *w; TxCommand *cmd; { if (cmd->tx_argc != 1) goto usage; windPrintCommands = !windPrintCommands; TxError("Window command debugging set to %s\n", (windPrintCommands ? "TRUE" : "FALSE")); return; usage: TxError("Usage: *winddebug\n"); } /* * ---------------------------------------------------------------------------- * windDumpCmd -- * * Dump out debugging info. * * Results: * None. * * Side effects: * None. * ---------------------------------------------------------------------------- */ void windDumpCmd(w, cmd) MagWindow *w; TxCommand *cmd; { (void) windDump(); } #ifndef MAGIC_WRAPPER /* * ---------------------------------------------------------------------------- * * windEchoCmd -- * * Echo the arguments * * Results: * None. * * Side effects: * Text may appear on the terminal * * ---------------------------------------------------------------------------- */ void windEchoCmd(w, cmd) MagWindow *w; TxCommand *cmd; { int i; bool newline = TRUE; for (i = 1; i < cmd->tx_argc; i++) { if (i != 1) TxPrintf(" "); if ( (i == 1) && (strcmp(cmd->tx_argv[i], "-n") == 0) ) newline = FALSE; else TxPrintf("%s", cmd->tx_argv[i]); } if (newline) TxPrintf("\n"); TxFlush(); } #endif /* * ---------------------------------------------------------------------------- * * windFilesCmd -- * * Find out what files are currently open. * * Usage: * *files * * Side Effects: * None. * * ---------------------------------------------------------------------------- */ /*ARGSUSED*/ void windFilesCmd(w, cmd) MagWindow *w; TxCommand *cmd; { #define NUM_FD 20 /* max number of open files per process */ int fd; struct stat buf; int unopen, open; open = unopen = 0; for (fd = 0; fd < NUM_FD; fd++) { if (fstat(fd, &buf) != 0) { if (errno == EBADF) unopen++; else TxError("file descriptor %d: %s\n", fd, strerror(errno)); } else { char *type; switch (buf.st_mode & S_IFMT) { case S_IFDIR: {type = "directory"; break;} case S_IFCHR: {type = "character special"; break;} case S_IFBLK: {type = "block special"; break;} case S_IFREG: {type = "regular"; break;} case S_IFLNK: {type = "symbolic link"; break;} case S_IFSOCK: {type = "socket"; break;} default: {type = "unknown"; break;} } TxError("file descriptor %d: open (type: '%s', inode number %ld)\n", fd, type, buf.st_ino); open++; } } TxError("%d open files, %d unopened file descriptors left\n", open, unopen); } /* * ---------------------------------------------------------------------------- * * windGrowCmd -- * * Grow a window to full-screen size or back to previous size. * * Results: * None. * * Side effects: * Text may appear on the terminal * * ---------------------------------------------------------------------------- */ void windGrowCmd(w, cmd) MagWindow *w; TxCommand *cmd; { if (w == NULL) { TxError("Point to a window first.\n"); return; }; WindFullScreen(w); } /* * ---------------------------------------------------------------------------- * windGrstatsCmd -- * * Take statistics on the graphics code. * * Results: * None. * * Side effects: * None. * ---------------------------------------------------------------------------- */ void windGrstatsCmd(w, cmd) MagWindow *w; TxCommand *cmd; { char *RunStats(), *rstatp; static struct tms tlast, tdelta; int i, style, count; int us; extern int GrNumClipBoxes; int usPerRect, rectsPerSec; if (cmd->tx_argc < 2 || cmd->tx_argc > 3) { TxError("Usage: grstats num [ style ]\n"); return; } if (!StrIsInt(cmd->tx_argv[1]) || (cmd->tx_argc == 3 && !StrIsInt(cmd->tx_argv[2]))) { TxError("Count & style must be numeric\n"); return; } if (w == (MagWindow *) NULL) { TxError("Point to a window first.\n"); return; } count = atoi(cmd->tx_argv[1]); if (cmd->tx_argc == 3) style = atoi(cmd->tx_argv[2]); else style = -1; WindUpdate(); if (style >= 0) GrLock(w, TRUE); (void) RunStats(RS_TINCR, &tlast, &tdelta); GrNumClipBoxes = 0; for (i = 0; i < count; i++) { if (SigInterruptPending) break; if (style < 0) { WindAreaChanged(w, (Rect *) NULL); WindUpdate(); } else { Rect r; #define GRSIZE 15 #define GRSPACE 20 r.r_xbot = w->w_screenArea.r_xbot - GRSIZE/2; r.r_ybot = w->w_screenArea.r_ybot - GRSIZE/2; r.r_xtop = r.r_xbot + GRSIZE - 1; r.r_ytop = r.r_ybot + GRSIZE - 1; GrClipBox(&w->w_screenArea, STYLE_ERASEALL); GrSetStuff(style); while (r.r_xbot <= w->w_screenArea.r_xtop) { while (r.r_ybot <= w->w_screenArea.r_ytop) { GrFastBox(&r); r.r_ybot += GRSPACE; r.r_ytop += GRSPACE; } r.r_xbot += GRSPACE; r.r_xtop += GRSPACE; r.r_ybot = w->w_screenArea.r_ybot - GRSIZE/2; r.r_ytop = r.r_ybot + GRSIZE - 1; } } } rstatp = RunStats(RS_TINCR, &tlast, &tdelta); us = tdelta.tms_utime * (1000000 / 60); usPerRect = us / MAX(1, GrNumClipBoxes); rectsPerSec = 1000000 / MAX(1, usPerRect); TxPrintf("[%s]\n%d rectangles, %d uS, %d uS/rectangle, %d rects/sec\n", rstatp, GrNumClipBoxes, us, usPerRect, rectsPerSec); if (style >= 0) GrUnlock(w); } /* * ---------------------------------------------------------------------------- * windHelpCmd -- * * Just a dummy proc. (Only for this particular, global, client) * This is just here so that there is an entry in our help table! * * Results: * None. * * Side effects: * None. * ---------------------------------------------------------------------------- */ void windHelpCmd(w, cmd) MagWindow *w; TxCommand *cmd; { ASSERT(FALSE, windHelpCmd); } static char *logKeywords[] = { "update", 0 }; /* * ---------------------------------------------------------------------------- * windLogCommandsCmd -- * * Log the commands and button pushes in a file. * * Results: * None. * * Side effects: * None. * ---------------------------------------------------------------------------- */ void windLogCommandsCmd(w, cmd) MagWindow *w; TxCommand *cmd; { char *fileName; bool update; if ((cmd->tx_argc < 1) || (cmd->tx_argc > 3)) goto usage; update = FALSE; if (cmd->tx_argc == 1) fileName = NULL; else fileName = cmd->tx_argv[1]; if (cmd->tx_argc == 3) { int i; i = Lookup(cmd->tx_argv[cmd->tx_argc - 1], logKeywords); if (i != 0) goto usage; update = TRUE; } TxLogCommands(fileName, update); return; usage: TxError("Usage: %s [filename [update]]\n", cmd->tx_argv[0]); } /* * ---------------------------------------------------------------------------- * * windIntMacroCmd -- * * Define a new interactive macro. * * Results: * None. * * Side effects: * Calls windDoMacro. * * ---------------------------------------------------------------------------- */ void windIntMacroCmd(w, cmd) MagWindow *w; TxCommand *cmd; { windDoMacro(w, cmd, TRUE); } /* * ---------------------------------------------------------------------------- * * windMacroCmd -- * * Define a new macro. * * Results: * None. * * Side effects: * Calls windDoMacro * * ---------------------------------------------------------------------------- */ void windMacroCmd(w, cmd) MagWindow *w; TxCommand *cmd; { windDoMacro(w, cmd, FALSE); } /* * ---------------------------------------------------------------------------- * * windDoMacro -- * * Working function for CmdIntMacro and CmdMacro * * Results: * None. * * Side effects: * Causes the macro package to define a new macro. * * ---------------------------------------------------------------------------- */ void windDoMacro(w, cmd, interactive) MagWindow *w; TxCommand *cmd; bool interactive; { char *cp, *cn; char ch; int ct, argstart; bool any, iReturn; bool do_list = FALSE; macrodef *cMacro; HashTable *clienttable; HashEntry *h; HashSearch hs; WindClient wc; /* If the second argument is a window name, we attempt to */ /* retrieve a client ID from it. This overrides the actual */ /* window the command was called from, so technically we */ /* can define macros for clients from inside other clients. */ /* The main use, though, is to define macros for a client */ /* from a script, rc file, or command-line. */ /* Default to the layout window if the command has no */ /* associated window. */ argstart = 1; if (cmd->tx_argc == 1) wc = DBWclientID; /* Added by NP 11/15/04 */ if (cmd->tx_argc > 1) { wc = WindGetClient(cmd->tx_argv[1], TRUE); if (wc == (WindClient)NULL) if (cmd->tx_argc == 4) { /* This may look odd, but it has a reason. If */ /* we don't register a client, such as wind3d */ /* when running a non-OpenGL magic, then we */ /* shuffle off macros for that window type to */ /* a "fake" NULL client, where it won't be seen */ /* again, but won't cause an error. */ wc = 0; argstart = 2; } else if (w != NULL) wc = w->w_client; else wc = DBWclientID; else argstart = 2; } if (cmd->tx_argc > argstart) { if (!strcmp(cmd->tx_argv[argstart], "list")) { do_list = TRUE; argstart++; } } if (cmd->tx_argc == argstart) { h = HashLookOnly(&MacroClients, wc); if (h == NULL) return; else { clienttable = (HashTable *)HashGetValue(h); if (clienttable == (HashTable *)NULL) { TxError("No such client.\n"); return; } } any = FALSE; ch = 0; HashStartSearch(&hs); while (TRUE) { h = HashNext(clienttable, &hs); if (h == NULL) break; cMacro = (macrodef *) HashGetValue(h); if (cMacro == (macrodef *)NULL) break; cn = MacroName((spointertype)h->h_key.h_ptr); cp = cMacro->macrotext; if (do_list) { #ifdef MAGIC_WRAPPER Tcl_AppendElement(magicinterp, cp); #else TxPrintf("%s\n", cp); #endif } else { if (cMacro->interactive) TxPrintf("Interactive macro '%s' contains \"%s\"\n", cn, cp); else TxPrintf("Macro '%s' contains \"%s\"\n", cn, cp); } freeMagic(cn); any = TRUE; } if (!any) { if (!do_list) TxPrintf("No macros are defined for this client.\n"); } return; } else if (cmd->tx_argc == (argstart + 1)) { int verbose; ct = MacroKey(cmd->tx_argv[argstart], &verbose); if (ct == 0) { if (verbose) TxError("Unrecognized macro name %s\n", cmd->tx_argv[argstart]); return; } cp = MacroRetrieve(wc, ct, &iReturn); if (cp != NULL) { cn = MacroName(ct); if (do_list) { #ifdef MAGIC_WRAPPER Tcl_SetResult(magicinterp, cp, TCL_VOLATILE); #else TxPrintf("%s\n", cp); #endif } else { if (iReturn) { TxPrintf("Interactive macro '%s' contains \"%s\"\n", cn, cp); } else { TxPrintf("Macro '%s' contains \"%s\"\n", cn, cp); } } freeMagic(cp); freeMagic(cn); } return; } else if (cmd->tx_argc == (argstart + 2)) { int verbose; ct = MacroKey(cmd->tx_argv[argstart], &verbose); if (ct == 0) { if (verbose) TxError("Unrecognized macro name %s\n", cmd->tx_argv[argstart]); return; } argstart++; if (cmd->tx_argv[argstart][0] == '\0') MacroDelete(wc, ct); else if (interactive) MacroDefine(wc, ct, cmd->tx_argv[argstart], TRUE); else MacroDefine(wc, ct, cmd->tx_argv[argstart], FALSE); return; } TxError("Usage: %s [macro_name [string]]\n", cmd->tx_argv[0]); } magic-8.0.210/tcltk/0000755000175000001440000000000012500371713012572 5ustar timusersmagic-8.0.210/tcltk/magicps.pro0000644000175000001440000000561410751423606014752 0ustar timusers%%BeginProlog % % PostScript prolog for output from magic plot % Version: 1.0 % written by Tim Edwards 4/05/00 JHU Applied Physics Laboratory % %%BeginResource: procset MAGICproc 1.0 1 % supporting definitions /MAGICsave save def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /ninit { /nChars matrix currentmatrix dup 0 get 0 eq {1} {0} ifelse get abs 72 8.5 mul mul 64 div ceiling cvi def } def /minit { 1 1 dtransform abs dup 1 exch div /onePix exch def dup /resY exch def 1 exch div /iresY exch def abs dup /resX exch def 1 exch div /iresX exch def /bX 64 iresX mul def /bY 64 iresY mul def /pattFont StipplePattern definefont pop /patterns /pattFont findfont [iresX 64 mul 0 0 iresY 64 mul 0 0] makefont def /ca nChars 1 add string def } def /StipplePattern 45 dict def StipplePattern begin /FontType 3 def /FontMatrix [1 0 0 1 0 0] def /FontBBox [0 0 1 1] def /Encoding 256 array def /PattName (P0) def /tmpStr 1 string def /NoPatt {<00>} def 0 1 255 { Encoding exch /NoPatt put } for /BuildChar { 1 0 0 0 1 1 setcachedevice exch begin Encoding exch get load 64 64 true [64 0 0 64 0 0] 5 -1 roll imagemask end } def end /dp { StipplePattern begin dup 30 tmpStr cvrs PattName exch 1 exch putinterval PattName cvn dup Encoding exch 4 -1 roll exch put exch store end } def /sf { findfont exch scalefont setfont } bind def /sp { patterns setfont 2 setlinewidth } def /lb { gsave translate 0 0 moveto /just exch def gsave dup true charpath flattenpath pathbbox grestore exch 4 -1 roll exch sub 3 1 roll sub just 4 and 0 gt {just 8 and 0 eq {0.5 mul} if}{pop 0} ifelse exch just 1 and 0 gt {just 2 and 0 eq {0.5 mul} if}{pop 0} ifelse exch rmoveto show grestore } def /sl { 0 1 nChars { exch dup 3 1 roll ca 3 1 roll put } for pop } def /sc { setcmykcolor } bind def /l1 { onePix setlinewidth } def /l2 { onePix 2 mul setlinewidth } def /l3 { onePix 3 mul setlinewidth } def /ml { moveto lineto stroke } bind def /vl { moveto 0 exch rlineto stroke } bind def /hl { moveto 0 rlineto stroke } bind def /mr { rectstroke } bind def /mx { 4 copy rectstroke 4 -1 roll 4 -1 roll 4 copy moveto rlineto stroke 3 -1 roll dup neg 4 1 roll add moveto rlineto stroke } bind def /pl { gsave translate /d exch def 0 d neg moveto 0 d lineto stroke d neg 0 moveto d 0 lineto stroke grestore } bind def /bx { x resX mul cvi 63 not and dup iresX mul exch w resX mul sub abs 63 add cvi 64 idiv /w exch def y resY mul cvi 63 not and dup iresY mul exch h resY mul sub abs 63 add cvi 64 idiv /h exch def /ch ca 0 w getinterval def moveto h { ch gsave show grestore 0 bY rmoveto } repeat grestore } def /fb {/h exch def /w exch def /y exch def /x exch def gsave newpath x y moveto w y lineto w h lineto x h lineto closepath clip bx } def /tb {1 sub 3 1 roll gsave newpath moveto {lineto} repeat closepath clip pathbbox /h exch def /w exch def /y exch def /x exch def bx } def magic-8.0.210/tcltk/drc.tcl0000664000175000001440000000245512400104154014046 0ustar timusers#!/bin/tclsh #---------------------------------------------- # Dump a file of DRC errors from magic #---------------------------------------------- namespace path {::tcl::mathop ::tcl::mathfunc} magic::suspendall set fout [open "drc.out" w] set oscale [cif scale out] select top cell set origcell [cellname list self] drc check set celllist [drc list count] puts stdout "celllist is $celllist" puts stdout "" flush stdout foreach pair $celllist { set cellname [lindex $pair 0] set count [lindex $pair 1] puts stdout "loading $cellname" flush stdout load $cellname select top cell puts $fout "$cellname $count" puts $fout "----------------------------------------" set drcresult [drc listall why] foreach {errtype coordlist} $drcresult { puts $fout $errtype puts $fout "----------------------------------------" foreach coord $coordlist { set bllx [* $oscale [lindex $coord 0]] set blly [* $oscale [lindex $coord 1]] set burx [* $oscale [lindex $coord 2]] set bury [* $oscale [lindex $coord 3]] set coords [format "%.3f %.3f %.3f %.3f" $bllx $blly $burx $bury] puts $fout "$coords" } puts $fout "----------------------------------------" } puts $fout "" } close $fout load $origcell magic::resumeall magic-8.0.210/tcltk/magic.sh.in0000775000175000001440000000322612034064611014621 0ustar timusers#!/bin/sh # # For installation, put this file (magic.sh) in a known executable path. # Put startup script "magic.tcl", shared library "tclmagic.so", and # "wish" replacement "magicexec" in ${CAD_ROOT}/magic/tcl/. # # This script starts magic under the Tcl interpreter, # reading commands from a special startup script which # launches magic and retains the Tcl interactive interpreter. # Parse for the argument "-c[onsole]". If it exists, run magic # with the TkCon console. Strip this argument from the argument list. TKCON=true DNULL= MAGIC_WISH=WISH_EXE export MAGIC_WISH # Hacks for Cygwin if [ "`uname | cut -d_ -f1`" = "CYGWIN" ]; then export PATH="$PATH:TCLLIB_DIR" export DISPLAY=${DISPLAY:=":0"} fi for i in $@ ; do case $i in -noc*) TKCON=;; -dnull) DNULL=true;; esac done if [ $TKCON ]; then if [ $DNULL ]; then exec TCL_DIR/tkcon.tcl -eval "source TCL_DIR/console.tcl" \ -slave "set argc $#; set argv [list $*]; source TCL_DIR/magic.tcl" else exec TCL_DIR/tkcon.tcl -eval "source TCL_DIR/console.tcl" \ -slave "package require Tk; set argc $#; set argv [list $*]; \ source TCL_DIR/magic.tcl" fi else # # Run the stand-in for wish (magicexec), which acts exactly like "wish" # except that it replaces ~/.wishrc with magic.tcl. This executable is # *only* needed when running without the console; the console itself is # capable of sourcing the startup script. # # With option "-dnull" we set up for operation without Tk (simple interpreter # only, efficient for running in batch mode). # if [ $DNULL ]; then exec TCL_DIR/magicdnull -nowrapper $@ else exec TCL_DIR/magicexec -- $@ fi fi magic-8.0.210/tcltk/tclmagic.h0000644000175000001440000000132210751423606014531 0ustar timusers/* * tclmagic.h -- * * Header file for including Tcl/Tk stuff. Note that this must be * included prior to all the other magic include files; otherwise * the definition for "ClientData" is in conflict. */ #ifndef _TCLMAGIC_H #define _TCLMAGIC_H #ifdef MAGIC_WRAPPER #include #include /* Externally-defined global variables */ extern Tcl_Interp *magicinterp; extern Tcl_Interp *consoleinterp; /* Forward declaration of procedures */ extern char *Tcl_escape(); extern int TagVerify(); /* Backward compatibility issues */ #ifndef CONST84 #define CONST84 /* indicates something was changed to "const" */ /* in Tcl version 8.4. */ #endif #endif /* MAGIC_WRAPPER */ #endif /* _TCLMAGIC_H */ magic-8.0.210/tcltk/console.tcl0000755000175000001440000001106210751423606014750 0ustar timusers# console.tcl: # # Defines Procedures which should be defined within the console # (master) interpreter (i.e., tkcon, if it is executed as a separate # interpreter). Note that this can always be worked around via the # "tkcon master" or "tkcon slave" commands, but this method organizes # things in a more natural way. wm geometry . 120x16+150-50 proc gettext {{prompt {}} {response {}}} { # Differentiate between console command-line and button execution # (Determines whether to prompt before or after execution) if {[.text index output] == [.text index end]} { ::tkcon::Prompt set mode 1 } else { set mode 0 } replaceprompt "?" if {$prompt != {}} { .text insert end $prompt {stdout} } if {$response != {}} { set result [tkcon congets $response] } else { set result [tkcon congets] } tkcon set ::tkcon::OPT(prompt1) "% " if {$mode == 0} { ::tkcon::Prompt } else { .text mark set output end tkcon console see output ;# adjust view to encompass newline update idletasks } return $result } slave alias magic::dialog gettext slave alias magic::consolegeometry wm geometry . slave alias magic::consolefocus focus -force .text slave alias magic::suspendout rename temp_puts puts slave alias magic::resumeout rename puts temp_puts # Ensure that destroying the console window queries for saving # modified layouts rather than forcing an immediate exit. wm protocol . WM_DELETE_WINDOW {tkcon slave slave magic::quit} proc temp_puts { args } { # null procedure; output is suspended. } proc magiccolor { ch } { tkcon slave slave magic::magiccolor $ch } proc replaceprompt { ch } { tkcon set ::tkcon::OPT(prompt1) "$ch " .text delete prompt.last-2c .text insert [.text index prompt.last-1c] $ch {prompt} .text mark set output [.text index output-1c] } # This procedure repaints the magic console to match the magic colormap. # It's only called if magic is run in 8-bit (PseudoColor) visual mode. # This is called from inside magic (graphics/grTk1.c). proc repaintconsole {} { puts stdout "Repainting console in magic layout window colors" # Because the console invokes a slave interpreter, we have to evaluate # magic command "magiccolor" in the slave interpreter. Note that all of # these colors are short names from the ".dstyle6" file. Long names are # also acceptable. ::set yellow [interp eval $::tkcon::OPT(exec) magiccolor yellow2] ::set black [interp eval $::tkcon::OPT(exec) magiccolor black] ::set gray [interp eval $::tkcon::OPT(exec) magiccolor gray2] ::set green [interp eval $::tkcon::OPT(exec) magiccolor green3] ::set purple [interp eval $::tkcon::OPT(exec) magiccolor purple1] ::set border [interp eval $::tkcon::OPT(exec) magiccolor window_border] ::set blue [interp eval $::tkcon::OPT(exec) magiccolor blue2] ::set red [interp eval $::tkcon::OPT(exec) magiccolor red3] ::set bgcolor [interp eval $::tkcon::OPT(exec) magiccolor no_color_at_all] tkcon set ::tkcon::COLOR(bg) $bgcolor tkcon set ::tkcon::COLOR(blink) $yellow tkcon set ::tkcon::COLOR(cursor) $black tkcon set ::tkcon::COLOR(disabled) $gray tkcon set ::tkcon::COLOR(proc) $green tkcon set ::tkcon::COLOR(var) $purple tkcon set ::tkcon::COLOR(prompt) $border tkcon set ::tkcon::COLOR(stdin) $black tkcon set ::tkcon::COLOR(stdout) $blue tkcon set ::tkcon::COLOR(stderr) $red .text configure -background $bgcolor .text configure -foreground $black .text configure -insertbackground $black .text tag configure var -background $bgcolor .text tag configure blink -background $bgcolor .text tag configure find -background $bgcolor .text tag configure stdout -background $bgcolor .text tag configure stderr -background $bgcolor .text tag configure proc -background $bgcolor .text tag configure prompt -background $bgcolor .text tag configure var -foreground $purple .text tag configure blink -foreground $yellow .text tag configure find -foreground $yellow .text tag configure stdout -foreground $blue .text tag configure stderr -foreground $red .text tag configure proc -foreground $green .text tag configure prompt -foreground $border .sy configure -background $bgcolor } # Rewrite the ::tkcon::New procedure so that it does not attempt to # load a second version of magic into the interpreter, which is fatal. rename ::tkcon::New ::tkcon::NewConsole proc ::tkcon::New {} { global argv0 argc argv set argc 1 list set argv $argv0 ::tkcon::NewConsole } magic-8.0.210/tcltk/wrapper.tcl0000664000175000001440000012337412411542001014761 0ustar timusers# This is the "Magic wrapper". # It's main purpose is to redefine the "openwindow" command in magic so that # opening a new window creates a window wrapped by a GUI interface. # # Written by Tim Edwards, August 23, 2002. # revision A: proof-of-concept. Add whatever you want to this basic wrapper. # revision B: Adds Tk scrollbars and caption # revision C: Adds a layer manager toolbar on the left side # revision D: Adds a menubar on top with cell and tech manager tools global windowsopen global tk_version global Glyph global Opts global Winopts set tk_version $::tk_version # Simple console commands (like TkCon, but much simpler) if {[lsearch [namespace children] ::tkshell] < 0} { catch {source ${CAD_ROOT}/magic/tcl/tkshell.tcl} } # Button images set Glyph(up) [image create bitmap \ -file ${CAD_ROOT}/magic/tcl/bitmaps/up.xbm \ -background gray -foreground steelblue] set Glyph(down) [image create bitmap \ -file ${CAD_ROOT}/magic/tcl/bitmaps/down.xbm \ -background gray -foreground steelblue] set Glyph(left) [image create bitmap \ -file ${CAD_ROOT}/magic/tcl/bitmaps/left.xbm \ -background gray -foreground steelblue] set Glyph(right) [image create bitmap \ -file ${CAD_ROOT}/magic/tcl/bitmaps/right.xbm \ -background gray -foreground steelblue] set Glyph(zoom) [image create bitmap \ -file ${CAD_ROOT}/magic/tcl/bitmaps/zoom.xbm \ -background gray -foreground steelblue] # Menu button callback functions proc magic::promptload {type} { global CAD_ROOT switch $type { cif { set Layoutfilename [ tk_getOpenFile -filetypes \ {{CIF {.cif {.cif}}} {"All files" {*}}}] if {$Layoutfilename != ""} { set cifname [file tail [file root $Layoutfilename]] magic::cellname create cif_temp magic::load cif_temp magic::cif read [file root $Layoutfilename] set childcells [magic::cellname list children cif_temp] magic::load [lindex $childcells 0] magic::cellname delete cif_temp -noprompt if {[llength $childcells] > 1} { puts stdout "Cells read from GDS file: $childcells" } } } gds { set Layoutfilename [ tk_getOpenFile -filetypes \ {{GDS {.gds .strm .cal {.gds .strm .cal}}} {"All files" {*}}}] if {$Layoutfilename != ""} { set origlist [magic::cellname list top] magic::gds read [file root $Layoutfilename] set newlist [magic::cellname list top] # Find entries in newlist that are not in origlist. # If there's only one, load it into the window. set newtopcells {} foreach n $newlist { if {[lsearch $origlist $n] < 0} { lappend newtopcells $n } } if {[llength $newtopcells] == 1} { magic::load [lindex $newtopcells 0] } elseif {[llength $newtopcells] != 0} { puts stdout "Top-level cells read from GDS file: $newtopcells" } } } magic { set Layoutfilename [ tk_getOpenFile -filetypes \ {{Magic {.mag {.mag}}} {"All files" {*}}}] if {$Layoutfilename != ""} { magic::load [file root $Layoutfilename] } } getcell { set Layoutfilename [ tk_getOpenFile -filetypes \ {{Magic {.mag {.mag}}} {"All files" {*}}}] if {$Layoutfilename != ""} { set fdir [file dirname $Layoutfilename] set lidx [lsearch [path search] $fdir] if {$lidx < 0} {path search +$fdir} magic::getcell [file tail $Layoutfilename] # Append path to cell search path if it's not there already if {[string index $Layoutfilename 0] != "/"} { set $Layoutfilename "./$Layoutfilename" } set sidx [string last "/" $Layoutfilename] if {$sidx > 0} { set cellpath [string range $Layoutfilename 0 $sidx] magic::path cell +$cellpath } } } } } proc magic::promptsave {type} { global CAD_ROOT switch $type { cif { set Layoutfilename [ tk_getSaveFile -filetypes \ {{CIF {.cif {.cif}}} {"All files" {*}}}] if {$Layoutfilename != ""} { magic::cif write $Layoutfilename } } gds { set Layoutfilename [ tk_getSaveFile -filetypes \ {{GDS {.gds .strm .cal {.gds .strm .cal}}} {"All files" {*}}}] if {$Layoutfilename != ""} { magic::gds write $Layoutfilename } } magic { set CellList [ magic::cellname list window ] if {[lsearch $CellList "(UNNAMED)"] >= 0} { set Layoutfilename [ tk_getSaveFile -filetypes \ {{Magic {.mag {.mag}}} {"All files" {*}}}] if {$Layoutfilename != ""} { set cellpath [file dirname $Layoutfilename] if {$cellpath == [pwd]} { set Layoutfilename [file tail $Layoutfilename] } else { magic::path cell +$cellpath } magic::save $Layoutfilename } } magic::writeall } } } # Callback functions used by the DRC. proc magic::drcupdate { option } { global Opts if {[info level] <= 1} { switch $option { on {set Opts(drc) 1} off {set Opts(drc) 0} } } } proc magic::drcstate { status } { set winlist [*bypass windownames layout] foreach lwin $winlist { set framename [winfo parent $lwin] switch $status { idle { set dct [*bypass drc list count total] if {$dct > 0} { ${framename}.titlebar.drcbutton configure -selectcolor red } else { ${framename}.titlebar.drcbutton configure -selectcolor green } ${framename}.titlebar.drcbutton configure -text "DRC=$dct" } busy { ${framename}.titlebar.drcbutton configure -selectcolor yellow } } } } # Create the menu of windows. This is kept separate from the cell manager, # and linked into it by the "clone" command. menu .winmenu -tearoff 0 proc magic::setgrid {gridsize} { set techlambda [magic::tech lambda] set tech1 [lindex $techlambda 1] set tech0 [lindex $techlambda 0] set tscale [expr {$tech1 / $tech0}] set lambdaout [expr {[magic::cif scale output] * $tscale}] set gridlambda [expr {$gridsize/$lambdaout}] magic::grid ${gridlambda}l magic::snap on } # Technology manager callback functions proc magic::techparseunits {} { set techlambda [magic::tech lambda] set tech1 [lindex $techlambda 1] set tech0 [lindex $techlambda 0] set target0 [.techmgr.lambda1.lval0 get] set target1 [.techmgr.lambda1.lval1 get] set newval0 [expr {$target0 * $tech0}] set newval1 [expr {$target1 * $tech1}] magic::scalegrid $newval1 $newval0 magic::techmanager update } # The technology manager proc magic::maketechmanager { mgrpath } { toplevel $mgrpath wm withdraw $mgrpath frame ${mgrpath}.title label ${mgrpath}.title.tlab -text "Technology: " menubutton ${mgrpath}.title.tname -text "(none)" -foreground red3 \ -menu ${mgrpath}.title.tname.menu label ${mgrpath}.title.tvers -text "" -foreground blue label ${mgrpath}.subtitle -text "" -foreground sienna4 frame ${mgrpath}.lambda0 label ${mgrpath}.lambda0.llab -text "Microns per lambda (CIF): " label ${mgrpath}.lambda0.lval -text "1" -foreground blue frame ${mgrpath}.lambda1 label ${mgrpath}.lambda1.llab -text "Internal units per lambda: " entry ${mgrpath}.lambda1.lval0 -foreground red3 -background white -width 3 label ${mgrpath}.lambda1.ldiv -text " / " entry ${mgrpath}.lambda1.lval1 -foreground red3 -background white -width 3 frame ${mgrpath}.cif0 label ${mgrpath}.cif0.llab -text "CIF input style: " menubutton ${mgrpath}.cif0.lstyle -text "" -foreground blue \ -menu ${mgrpath}.cif0.lstyle.menu label ${mgrpath}.cif0.llab2 -text " Microns/lambda=" label ${mgrpath}.cif0.llambda -text "" -foreground red3 frame ${mgrpath}.cif1 label ${mgrpath}.cif1.llab -text "CIF output style: " menubutton ${mgrpath}.cif1.lstyle -text "" -foreground blue \ -menu ${mgrpath}.cif1.lstyle.menu label ${mgrpath}.cif1.llab2 -text " Microns/lambda=" label ${mgrpath}.cif1.llambda -text "" -foreground red3 frame ${mgrpath}.extract label ${mgrpath}.extract.llab -text "Extract style: " menubutton ${mgrpath}.extract.lstyle -text "" -foreground blue \ -menu ${mgrpath}.extract.lstyle.menu frame ${mgrpath}.drc label ${mgrpath}.drc.llab -text "DRC style: " menubutton ${mgrpath}.drc.lstyle -text "" -foreground blue \ -menu ${mgrpath}.drc.lstyle.menu pack ${mgrpath}.title.tlab -side left pack ${mgrpath}.title.tname -side left pack ${mgrpath}.title.tvers -side left pack ${mgrpath}.lambda0.llab -side left pack ${mgrpath}.lambda0.lval -side left pack ${mgrpath}.lambda1.llab -side left pack ${mgrpath}.lambda1.lval0 -side left pack ${mgrpath}.lambda1.ldiv -side left pack ${mgrpath}.lambda1.lval1 -side left pack ${mgrpath}.cif0.llab -side left pack ${mgrpath}.cif0.lstyle -side left pack ${mgrpath}.cif0.llab2 -side left pack ${mgrpath}.cif0.llambda -side left pack ${mgrpath}.cif1.llab -side left pack ${mgrpath}.cif1.lstyle -side left pack ${mgrpath}.cif1.llab2 -side left pack ${mgrpath}.cif1.llambda -side left pack ${mgrpath}.extract.llab -side left pack ${mgrpath}.extract.lstyle -side left pack ${mgrpath}.drc.llab -side left pack ${mgrpath}.drc.lstyle -side left pack ${mgrpath}.title -side top -fill x pack ${mgrpath}.subtitle -side top -fill x pack ${mgrpath}.lambda0 -side top -fill x pack ${mgrpath}.lambda1 -side top -fill x pack ${mgrpath}.cif0 -side top -fill x pack ${mgrpath}.cif1 -side top -fill x pack ${mgrpath}.extract -side top -fill x bind ${mgrpath}.lambda1.lval0 magic::techparseunits bind ${mgrpath}.lambda1.lval1 magic::techparseunits #Withdraw the window when the close button is pressed wm protocol ${mgrpath} WM_DELETE_WINDOW "set Opts(techmgr) 0 ; wm withdraw ${mgrpath}" } # Generate the cell manager catch {source ${CAD_ROOT}/magic/tcl/cellmgr.tcl} # Generate the text helper catch {source ${CAD_ROOT}/magic/tcl/texthelper.tcl} # Create or redisplay the technology manager proc magic::techmanager {{option "update"}} { global CAD_ROOT if {[catch {wm state .techmgr}]} { if {$option == "create"} { magic::maketechmanager .techmgr } else { return } } elseif { $option == "create"} { return } if {$option == "create"} { menu .techmgr.title.tname.menu -tearoff 0 menu .techmgr.cif0.lstyle.menu -tearoff 0 menu .techmgr.cif1.lstyle.menu -tearoff 0 menu .techmgr.extract.lstyle.menu -tearoff 0 menu .techmgr.drc.lstyle.menu -tearoff 0 } if {$option == "init"} { .techmgr.title.tname.menu delete 0 end .techmgr.cif0.lstyle.menu delete 0 end .techmgr.cif1.lstyle.menu delete 0 end .techmgr.extract.lstyle.menu delete 0 end .techmgr.drc.lstyle.menu delete 0 end } if {$option == "init" || $option == "create"} { set tlist [magic::cif listall istyle] foreach i $tlist { .techmgr.cif0.lstyle.menu add command -label $i -command \ "magic::cif istyle $i ; \ magic::techmanager update" } set tlist [magic::cif listall ostyle] foreach i $tlist { .techmgr.cif1.lstyle.menu add command -label $i -command \ "magic::cif ostyle $i ; \ magic::techmanager update" } set tlist [magic::extract listall style] foreach i $tlist { .techmgr.extract.lstyle.menu add command -label $i -command \ "magic::extract style $i ; \ magic::techmanager update" } set tlist [magic::drc listall style] foreach i $tlist { .techmgr.drc.lstyle.menu add command -label $i -command \ "magic::drc style $i ; \ magic::techmanager update" } set dirlist [subst [magic::path sys]] set tlist {} foreach i $dirlist { lappend tlist [glob -nocomplain ${i}/*.tech] lappend tlist [glob -nocomplain ${i}/*.tech27] } foreach i [join $tlist] { set j [file tail [file rootname ${i}]] .techmgr.title.tname.menu add command -label $j -command \ "magic::tech load $j ; \ magic::techmanager update" } } set techlambda [magic::tech lambda] set tech1 [lindex $techlambda 1] set tech0 [lindex $techlambda 0] set tscale [expr {$tech1 / $tech0}] .techmgr.title.tname configure -text [magic::tech name] set techstuff [magic::tech version] .techmgr.title.tvers configure -text "(version [lindex $techstuff 0])" .techmgr.subtitle configure -text [lindex $techstuff 1] set lotext [format "%g" [expr {[magic::cif scale output] * $tscale}]] .techmgr.lambda0.lval configure -text $lotext .techmgr.cif0.lstyle configure -text [magic::cif list istyle] set litext [format "%g" [expr {[magic::cif scale input] * $tscale}]] .techmgr.cif0.llambda configure -text $litext .techmgr.cif1.lstyle configure -text [magic::cif list ostyle] .techmgr.cif1.llambda configure -text $lotext .techmgr.extract.lstyle configure -text [magic::extract list style] .techmgr.drc.lstyle configure -text [magic::drc list style] .techmgr.lambda1.lval0 delete 0 end .techmgr.lambda1.lval1 delete 0 end .techmgr.lambda1.lval0 insert end $tech1 .techmgr.lambda1.lval1 insert end $tech0 } proc magic::captions {{subcommand {}}} { global Opts if {$subcommand != {} && $subcommand != "writeable" && $subcommand != "load"} { return } set winlist [magic::windownames layout] foreach winpath $winlist { set framename [winfo parent $winpath] set caption [$winpath windowcaption] set subcaption1 [lindex $caption 0] set techname [tech name] if {[catch {set Opts(tool)}]} { set Opts(tool) unknown } if {[lindex $caption 1] == "EDITING"} { set subcaption2 [lindex $caption 2] } else { # set subcaption2 [join [lrange $caption 1 end]] set subcaption2 $caption } ${framename}.titlebar.caption configure -text \ "Loaded: ${subcaption1} Editing: ${subcaption2} Tool: $Opts(tool) \ Technology: ${techname}" } } # Allow captioning in the title window by tagging the "load" and "edit" commands # Note that the "box" tag doesn't apply to mouse-button events, so this function # is duplicated by Tk binding of mouse events in the layout window. magic::tag load "[magic::tag load]; magic::captions" magic::tag edit "magic::captions" magic::tag save "magic::captions" magic::tag down "magic::captions" magic::tag box "magic::boxview %W %1" magic::tag move "magic::boxview %W" magic::tag scroll "magic::scrollupdate %W" magic::tag view "magic::scrollupdate %W" magic::tag zoom "magic::scrollupdate %W" magic::tag findbox "magic::scrollupdate %W" magic::tag see "magic::toolupdate %W %1 %2" magic::tag tech "magic::techrebuild %W %1; magic::captions %1" magic::tag drc "magic::drcupdate %1" magic::tag path "magic::techmanager update" magic::tag cellname "magic::mgrupdate %W %1" magic::tag cif "magic::mgrupdate %W %1" magic::tag gds "magic::mgrupdate %W %1" # This should be a list. . . do be done later set windowsopen 0 set Opts(techmgr) 0 set Opts(target) default set Opts(netlist) 0 set Opts(colormap) 0 set Opts(wind3d) 0 set Opts(crosshair) 0 set Opts(drc) 1 # Update cell and tech managers in response to a cif or gds read command proc magic::mgrupdate {win {cmdstr ""}} { if {${cmdstr} == "read"} { catch {magic::cellmanager} magic::captions magic::techmanager update } elseif {${cmdstr} == "delete" || ${cmdstr} == "rename"} { catch {magic::cellmanager} magic::captions } elseif {${cmdstr} == "writeable"} { magic::captions } } # Set default width and height to be 3/4 of the screen size. set Opts(geometry) \ "[expr 3 * [winfo screenwidth .] / 4]x[expr 3 * [winfo screenheight .] \ / 4]+100+100" # Procedures for the layout scrollbars, which are made from canvas # objects to avoid the problems associated with Tk's stupid scrollbar # implementation. # Repainting function for scrollbars, title, etc., to match the magic # Change the colormap (most useful in 8-bit PseudoColor) proc magic::repaintwrapper { win } { set bgcolor [magic::magiccolor -] ${win}.xscroll configure -background $bgcolor ${win}.xscroll configure -highlightbackground $bgcolor ${win}.xscroll configure -highlightcolor [magic::magiccolor K] ${win}.yscroll configure -background $bgcolor ${win}.yscroll configure -highlightbackground $bgcolor ${win}.yscroll configure -highlightcolor [magic::magiccolor K] ${win}.titlebar.caption configure -background [magic::magiccolor w] ${win}.titlebar.caption configure -foreground [magic::magiccolor c] ${win}.titlebar.message configure -background [magic::magiccolor w] ${win}.titlebar.message configure -foreground [magic::magiccolor c] ${win}.titlebar.pos configure -background [magic::magiccolor w] ${win}.titlebar.pos configure -foreground [magic::magiccolor c] } # Coordinate display callback function # Because "box" calls "box", use the "info level" command to avoid # infinite recursion. proc magic::boxview {win {cmdstr ""}} { if {${cmdstr} == "exists" || ${cmdstr} == "help" || ${cmdstr} == ""} { # do nothing. . . informational only, no change to the box } elseif {[info level] <= 1} { # For NULL window, find all layout windows and apply update to each. if {$win == {}} { set winlist [magic::windownames layout] foreach lwin $winlist { magic::boxview $lwin } return } set framename [winfo parent $win] set lambda [${win} tech lambda] set lr [expr {(0.0 + [lindex $lambda 0]) / [lindex $lambda 1]}] set bval [${win} box values] set bllx [expr {[lindex $bval 0] * $lr }] set blly [expr {[lindex $bval 1] * $lr }] set burx [expr {[lindex $bval 2] * $lr }] set bury [expr {[lindex $bval 3] * $lr }] if {[expr {$bllx == int($bllx)}]} {set bllx [expr {int($bllx)}]} if {[expr {$blly == int($blly)}]} {set blly [expr {int($blly)}]} if {[expr {$burx == int($burx)}]} {set burx [expr {int($burx)}]} if {[expr {$bury == int($bury)}]} {set bury [expr {int($bury)}]} ${framename}.titlebar.pos configure -text \ "box ($bllx, $blly) to ($burx, $bury) lambda" } } proc magic::cursorview {win} { global Opts if {$win == {}} { return } set framename [winfo parent $win] set lambda [${win} tech lambda] if {[llength $lambda] != 2} {return} set lr [expr {(0.0 + [lindex $lambda 0]) / [lindex $lambda 1]}] set olst [${win} cursor lambda] set olstx [lindex $olst 0] set olsty [lindex $olst 1] if {$Opts(crosshair)} { *bypass crosshair ${olstx}l ${olsty}l } if {[${win} box exists]} { set dlst [${win} box position] set dx [expr {$olstx - ([lindex $dlst 0]) * $lr }] set dy [expr {$olsty - ([lindex $dlst 1]) * $lr }] if {[expr {$dx == int($dx)}]} {set dx [expr {int($dx)}]} if {[expr {$dy == int($dy)}]} {set dy [expr {int($dy)}]} if {$dx >= 0} {set dx "+$dx"} if {$dy >= 0} {set dy "+$dy"} set titletext [format "(%g %g) %g %g lambda" $olstx $olsty $dx $dy] ${framename}.titlebar.pos configure -text $titletext } else { set titletext [format "(%g %g) lambda" $olstx $olsty] ${framename}.titlebar.pos configure -text $titletext } } proc magic::toolupdate {win {yesno "yes"} {layerlist "none"}} { global Winopts # For NULL window, get current window if {$win == {}} { set win [magic::windownames] } # Wind3d has a "see" function, so make sure this is not a 3d window if {$win == [magic::windownames wind3d]} { return } set framename [winfo parent $win] # Don't do anything if toolbar is not present if { $Winopts(${framename},toolbar) == 0 } { return } if {$layerlist == "none"} { set layerlist $yesno set yesno "yes" } if {$layerlist == "*"} { set layerlist [magic::tech layer "*"] } foreach layer $layerlist { switch $layer { none {} errors {set canon $layer} subcell {set canon $layer} labels {set canon $layer} default {set canon [magic::tech layer $layer]} } if {$layer != "none"} { if {$yesno == "yes"} { ${framename}.toolbar.b$canon configure -image img_$canon } else { ${framename}.toolbar.b$canon configure -image img_space } } } } # Generate the toolbar for the wrapper proc magic::maketoolbar { framename } { # Destroy any existing toolbar before starting set alltools [winfo children ${framename}.toolbar] foreach i $alltools { destroy $i } # All toolbar commands will be passed to the appropriate window set win ${framename}.magic # Make sure that window has been created so we will get the correct # height value. update idletasks set winheight [expr {[winfo height ${framename}] - \ [winfo height ${framename}.titlebar]}] # Generate a layer image for "space" that will be used when layers are # invisible. image create layer img_space -name none # Generate layer images and buttons for toolbar set all_layers [concat {errors labels subcell} [magic::tech layer "*"]] foreach layername $all_layers { image create layer img_$layername -name $layername button ${framename}.toolbar.b$layername -image img_$layername -command \ "$win see $layername" # Bindings: Entering the button puts the canonical layer name in the # message window. bind ${framename}.toolbar.b$layername \ [subst {focus %W ; ${framename}.titlebar.message configure \ -text "$layername"}] bind ${framename}.toolbar.b$layername \ [subst {${framename}.titlebar.message configure -text ""}] # 3rd mouse button makes layer invisible; 1st mouse button restores it. # 2nd mouse button paints the layer color. Key "p" also does paint, esp. # for users with 2-button mice. Key "e" erases, as does Shift-Button-2. bind ${framename}.toolbar.b$layername \ "$win paint $layername" bind ${framename}.toolbar.b$layername \ "$win paint $layername" bind ${framename}.toolbar.b$layername \ "$win erase $layername" bind ${framename}.toolbar.b$layername \ "$win erase $layername" bind ${framename}.toolbar.b$layername \ "$win see no $layername" bind ${framename}.toolbar.b$layername \ "$win select more area $layername" bind ${framename}.toolbar.b$layername \ "$win select less area $layername" } # Figure out how many columns we need to fit all the layer buttons inside # the toolbar without going outside the window area. set ncols 1 while {1} { incr ncols set i 0 set j 0 foreach layername $all_layers { grid ${framename}.toolbar.b$layername -row $i -column $j -sticky news incr j if {$j == $ncols} { set j 0 incr i } } # tkwait visibility ${framename}.toolbar update idletasks set toolheight [lindex [grid bbox ${framename}.toolbar] 3] if {$toolheight <= $winheight} {break} } } # Delete and rebuild the toolbar buttons in response to a "tech load" # command. proc magic::techrebuild {winpath {cmdstr ""}} { # For NULL window, find all layout windows and apply update to each. if {$winpath == {}} { set winlist [magic::windownames layout] foreach lwin $winlist { magic::techrebuild $lwin $cmdstr } return } set framename [winfo parent $winpath] if {${cmdstr} == "load"} { maketoolbar ${framename} magic::techmanager init } } # Scrollbar callback procs # Procedure to return the effective X and Y scrollbar bounds for the # current view in magic (in pixels) proc magic::setscrollvalues {win} { set svalues [${win} view get] set bvalues [${win} view bbox] set bwidth [expr {[lindex $bvalues 2] - [lindex $bvalues 0]}] set bheight [expr {[lindex $bvalues 3] - [lindex $bvalues 1]}] set framename [winfo parent ${win}] set wwidth [winfo width ${framename}.xscroll.bar] ;# horizontal scrollbar set wheight [winfo height ${framename}.yscroll.bar] ;# vertical scrollbar # Note that adding 0.0 here forces floating-point set xscale [expr {(0.0 + $wwidth) / $bwidth}] set yscale [expr {(0.0 + $wheight) / $bheight}] set xa [expr {$xscale * ([lindex $svalues 0] - [lindex $bvalues 0]) }] set xb [expr {$xscale * ([lindex $svalues 2] - [lindex $bvalues 0]) }] set ya [expr {$yscale * ([lindex $svalues 1] - [lindex $bvalues 1]) }] set yb [expr {$yscale * ([lindex $svalues 3] - [lindex $bvalues 1]) }] # Magic's Y axis is inverted with respect to X11 window coordinates set ya [expr { $wheight - $ya }] set yb [expr { $wheight - $yb }] ${framename}.xscroll.bar coords slider $xa 2 $xb 15 ${framename}.yscroll.bar coords slider 2 $ya 15 $yb set xb [expr { 1 + ($xa + $xb) / 2 }] set xa [expr { $xb - 2 }] ${framename}.xscroll.bar coords centre $xa 4 $xb 13 set yb [expr { 1 + ($ya + $yb) / 2 }] set ya [expr { $yb - 2 }] ${framename}.yscroll.bar coords centre 4 $ya 13 $yb } # Procedure to update scrollbars in response to an internal command # "view" calls "view", so avoid infinite recursion. proc magic::scrollupdate {win} { if {[info level] <= 1} { # For NULL window, find current window if {$win == {}} { set win [magic::windownames] } # Make sure we're not a 3D window, which doesn't take window commands # This is only necessary because the 3D window declares a "view" # command, too. if {$win != [magic::windownames wind3d]} { magic::setscrollvalues $win } } } # scrollview: update the magic display to match the # scrollbar positions. proc magic::scrollview { w win orient } { global scale set v1 $scale($orient,origin) set v2 $scale($orient,update) set delta [expr {$v2 - $v1}] set bvalues [${win} view bbox] set wvalues [${win} windowpositions] # Note that adding 0.000 in expression forces floating-point if {"$orient" == "x"} { set bwidth [expr {[lindex $bvalues 2] - [lindex $bvalues 0]}] set wwidth [expr {0.000 + [lindex $wvalues 2] - [lindex $wvalues 0]}] set xscale [expr {$bwidth / $wwidth}] ${win} scroll e [expr {$delta * $xscale}]i } else { set bheight [expr {[lindex $bvalues 3] - [lindex $bvalues 1]}] set wheight [expr {0.000 + [lindex $wvalues 3] - [lindex $wvalues 1]}] set yscale [expr {$bheight / $wheight}] ${win} scroll s [expr {$delta * $yscale}]i } } # setscroll: get the current cursor position and save it as a # reference point. proc magic::setscroll { w v orient } { global scale set scale($orient,origin) $v set scale($orient,update) $v } proc magic::dragscroll { w v orient } { global scale set v1 $scale($orient,update) set scale($orient,update) $v set delta [expr {$v - $v1}] if { "$orient" == "x" } { $w move slider $delta 0 $w move centre $delta 0 } else { $w move slider 0 $delta $w move centre 0 $delta } } # Scrollbar generator for the wrapper window proc magic::makescrollbar { fname orient win } { global scale global Glyph set scale($orient,update) 0 set scale($orient,origin) 0 # To be done: add glyphs for the arrows if { "$orient" == "x" } { canvas ${fname}.bar -height 13 -relief sunken -borderwidth 1 button ${fname}.lb -image $Glyph(left) -borderwidth 1 \ -command "${win} scroll left .1 w" button ${fname}.ub -image $Glyph(right) -borderwidth 1 \ -command "${win} scroll right .1 w" pack ${fname}.lb -side left pack ${fname}.bar -fill $orient -expand true -side left pack ${fname}.ub -side right } else { canvas ${fname}.bar -width 13 -relief sunken -borderwidth 1 button ${fname}.lb -image $Glyph(down) -borderwidth 1 \ -command "${win} scroll down .1 w" button ${fname}.ub -image $Glyph(up) -borderwidth 1 \ -command "${win} scroll up .1 w" pack ${fname}.ub pack ${fname}.bar -fill $orient -expand true pack ${fname}.lb } # Create the bar which controls the scrolling and bind actions to it ${fname}.bar create rect 2 2 15 15 -fill steelblue -width 0 -tag slider ${fname}.bar bind slider "magic::setscroll %W %$orient $orient" ${fname}.bar bind slider "magic::scrollview %W $win $orient" ${fname}.bar bind slider "magic::dragscroll %W %$orient $orient" # Create a small mark in the center of the scrolling rectangle which aids # in determining how much the window is being scrolled when the full # scrollbar extends past the window edges. ${fname}.bar create rect 4 4 13 13 -fill black -width 0 -tag centre ${fname}.bar bind centre "magic::setscroll %W %$orient $orient" ${fname}.bar bind centre "magic::scrollview %W $win $orient" ${fname}.bar bind centre "magic::dragscroll %W %$orient $orient" } # Create the wrapper and open up a layout window in it. proc magic::openwrapper {{cell ""} {framename ""}} { global windowsopen global tk_version global Glyph global Opts global Winopts # Disallow scrollbars and title caption on windows---we'll do these ourselves if {$windowsopen == 0} { windowcaption off windowscrollbars off windowborder off } incr windowsopen if {$framename == ""} { set framename .layout${windowsopen} } set winname ${framename}.magic toplevel $framename tkwait visibility $framename frame ${framename}.xscroll -height 13 frame ${framename}.yscroll -width 13 magic::makescrollbar ${framename}.xscroll x ${winname} magic::makescrollbar ${framename}.yscroll y ${winname} button ${framename}.zb -image $Glyph(zoom) -borderwidth 1 -command "${winname} zoom 2" # Add bindings for mouse buttons 2 and 3 to the zoom button bind ${framename}.zb "${winname} zoom 0.5" bind ${framename}.zb "${winname} view" frame ${framename}.titlebar label ${framename}.titlebar.caption -text "Loaded: none Editing: none Tool: box" \ -foreground white -background sienna4 -anchor w -padx 15 label ${framename}.titlebar.message -text "" -foreground white \ -background sienna4 -anchor w -padx 5 label ${framename}.titlebar.pos -text "" -foreground white \ -background sienna4 -anchor w -padx 5 # Menu buttons frame ${framename}.titlebar.mbuttons menubutton ${framename}.titlebar.mbuttons.file -text File -relief raised \ -menu ${framename}.titlebar.mbuttons.file.filemenu -borderwidth 2 menubutton ${framename}.titlebar.mbuttons.edit -text Edit -relief raised \ -menu ${framename}.titlebar.mbuttons.edit.editmenu -borderwidth 2 menubutton ${framename}.titlebar.mbuttons.view -text View -relief raised \ -menu ${framename}.titlebar.mbuttons.view.viewmenu -borderwidth 2 menubutton ${framename}.titlebar.mbuttons.opts -text Options -relief raised \ -menu ${framename}.titlebar.mbuttons.opts.optsmenu -borderwidth 2 pack ${framename}.titlebar.mbuttons.file -side left pack ${framename}.titlebar.mbuttons.edit -side left pack ${framename}.titlebar.mbuttons.view -side left pack ${framename}.titlebar.mbuttons.opts -side left # DRC status button checkbutton ${framename}.titlebar.drcbutton -text "DRC" -anchor w \ -borderwidth 2 -variable Opts(drc) \ -foreground white -background sienna4 -selectcolor green \ -command [subst { if { \$Opts(drc) } { drc on } else { drc off } }] magic::openwindow $cell $winname # Create toolbar frame. Make sure it has the same visual and depth as # the layout window, so there will be no problem using the GCs from the # layout window to paint into the toolbar. frame ${framename}.toolbar \ -visual "[winfo visual ${winname}] [winfo depth ${winname}]" # Repaint to magic colors magic::repaintwrapper ${framename} grid ${framename}.titlebar -row 0 -column 0 -columnspan 3 -sticky news grid ${framename}.yscroll -row 1 -column 0 -sticky ns grid $winname -row 1 -column 1 -sticky news grid ${framename}.zb -row 2 -column 0 grid ${framename}.xscroll -row 2 -column 1 -sticky ew # The toolbar is not attached by default grid rowconfigure ${framename} 1 -weight 1 grid columnconfigure ${framename} 1 -weight 1 grid ${framename}.titlebar.mbuttons -row 0 -column 0 -sticky news grid ${framename}.titlebar.drcbutton -row 0 -column 1 -sticky news grid ${framename}.titlebar.caption -row 0 -column 2 -sticky news grid ${framename}.titlebar.message -row 0 -column 3 -sticky news grid ${framename}.titlebar.pos -row 0 -column 4 -sticky news grid columnconfigure ${framename}.titlebar 2 -weight 1 bind $winname "focus %W ; set Opts(focus) $framename" # Note: Tk binding bypasses the event proc, so it is important to # set the current point; otherwise, the cursor will report the # wrong position and/or the wrong window. HOWEVER we should wrap # this command with the "bypass" command such that it does not # reset any current input redirection to the terminal. bind ${winname} "*bypass setpoint %x %y ${winname}; \ magic::cursorview ${winname}" # Resize the window if {[catch {wm geometry ${framename} $Winopts(${framename},geometry)}]} { catch {wm geometry ${framename} $Opts(geometry)} } set Winopts(${framename},toolbar) 0 set Winopts(${framename},cmdentry) 0 # Generate the file menu set m [menu ${framename}.titlebar.mbuttons.file.filemenu -tearoff 0] $m add command -label "New window" -command "magic::openwrapper \ [${winname} cellname list window]" $m add command -label "Close" -command "magic::closewrapper ${framename}" $m add separator $m add command -label "Place Cell" -command {magic::promptload getcell} $m add separator $m add command -label "Load layout" -command {magic::promptload magic} $m add command -label "Read CIF" -command {magic::promptload cif} $m add command -label "Read GDS" -command {magic::promptload gds} $m add separator $m add command -label "Save layout" -command {magic::promptsave magic} $m add command -label "Write CIF" -command {magic::promptsave cif} $m add command -label "Write GDS" -command {magic::promptsave gds} $m add separator $m add command -label "Flush current" -command {magic::flush} $m add command -label "Delete current" -command {magic::cellname delete \ [magic::cellname list window]} $m add separator $m add command -label "Quit" -command {magic::quit} # Generate the edit menu set m [menu ${framename}.titlebar.mbuttons.edit.editmenu -tearoff 0] $m add command -label "Undo (u)" -command {magic::undo} $m add command -label "Redo (U)" -command {magic::redo} $m add separator $m add command -label "Rotate 90 degree " -command {magic::clock} $m add command -label "Flip Horizontal" -command {magic::sideways} $m add command -label "Flip Vertical" -command {magic::upsidedown} $m add separator $m add command -label "Text ..." \ -command [subst { magic::update_texthelper; \ wm deiconify .texthelper ; raise .texthelper } ] $m add separator $m add command -label "Lock Cell " -command {magic::instance lock} $m add command -label "Unlock Cell " -command {magic::instance unlock} $m add separator $m add command -label "Unlock Base Layers" -command {magic::tech layer unlock *} # Generate the view menu set m [menu ${framename}.titlebar.mbuttons.view.viewmenu -tearoff 0] $m add command -label "Zoom In " -command {magic::zoom 0.5} $m add command -label "Zoom Out (Z)" -command {magic::zoom 2} $m add command -label "Zoom Sel (z)" -command {magic::findbox zoom} $m add command -label "Full" -command {magic::select top cell ; findbox zoom} $m add separator $m add command -label "Grid 0.10u " -command {magic::setgrid 0.1} $m add command -label "Grid 0.20u " -command {magic::setgrid 0.2} $m add command -label "Grid 0.25u " -command {magic::setgrid 0.25} $m add command -label "Grid 0.40u " -command {magic::setgrid 0.4} $m add command -label "Grid 0.5u " -command {magic::setgrid 0.5} $m add command -label "Grid 1.0u " -command {magic::setgrid 1} $m add command -label "Grid 2.0u " -command {magic::setgrid 2} $m add command -label "Grid 4.0u " -command {magic::setgrid 4} $m add command -label "Grid 5.0u " -command {magic::setgrid 5} $m add command -label "Grid 10.0u " -command {magic::setgrid 10} $m add command -label "Grid 50.0u " -command {magic::setgrid 50} $m add separator $m add command -label "Expand Toggle (/)" -command {magic::expand toggle} $m add command -label "Expand (x)" -command {magic::expand } $m add command -label "Unexpand (X)" -command {magic::unexpand } # Generate the options menu set m [menu ${framename}.titlebar.mbuttons.opts.optsmenu -tearoff 0] $m add check -label "Toolbar" -variable Winopts(${framename},toolbar) \ -command [subst {if { \$Winopts(${framename},toolbar) } { \ magic::maketoolbar ${framename} ; \ grid ${framename}.toolbar -row 1 -column 2 -rowspan 2 -sticky new ; \ } else { \ grid forget ${framename}.toolbar } }] .winmenu add radio -label ${framename} -variable Opts(target) -value ${winname} if {$tk_version >= 8.5} { $m add check -label "Cell Manager" -variable Opts(cellmgr) \ -command [subst { magic::cellmanager create; \ if { \$Opts(cellmgr) } { \ wm deiconify .cellmgr ; raise .cellmgr \ } else { \ wm withdraw .cellmgr } }] .winmenu entryconfigure last -command ".cellmgr.target.list configure \ -text ${framename}" } $m add check -label "Tech Manager" -variable Opts(techmgr) \ -command [subst { magic::techmanager create; \ if { \$Opts(techmgr) } { \ wm deiconify .techmgr ; raise .techmgr \ } else { \ wm withdraw .techmgr } }] $m add check -label "Netlist Window" -variable Opts(netlist) \ -command [subst { if { \[windownames netlist\] != {}} { \ set Opts(netlist) 0 ; closewindow \[windownames netlist\] \ } else { \ set Opts(netlist) 1 ; specialopen netlist \ } }] $m add check -label "Colormap Window" -variable Opts(colormap) \ -command [subst { if { \[windownames color\] != {}} { \ set Opts(colormap) 0 ; closewindow \[windownames color\] \ } else { \ set Opts(colormap) 1 ; specialopen color \ } }] $m add check -label "3D Display" -variable Opts(wind3d) \ -command [subst { if { \[windownames wind3d\] != {}} { \ set Opts(wind3d) 0 ; .render.magic closewindow ; \ destroy .render \ } else { \ set Opts(wind3d) 1 ; \ magic::render3d \[${winname} cellname list window\] \ } }] $m add check -label "Window Command Entry" \ -variable Winopts(${framename},cmdentry) \ -command [subst { if { \$Winopts(${framename},cmdentry) } { \ addcommandentry $framename \ } else { \ deletecommandentry $framename } }] $m add check -label "Crosshair" \ -variable Opts(crosshair) \ -command "if {$Opts(crosshair) == 0} {crosshair off}" catch {addmazehelper $m} # Set the default view update idletasks ${winname} magic::view magic::captions # Remove "open" and "close" macros so they don't generate non-GUI # windows or (worse) blow away the window inside the GUI frame if {[magic::macro list o] == "openwindow"} { magic::macro o "openwrapper" } if {[magic::macro list O] == "closewindow"} { magic::macro O {closewrapper $Opts(focus)} } # Make sure that closing from the window manager is equivalent to # the command "closewrapper" wm protocol ${framename} WM_DELETE_WINDOW "closewrapper $framename" # If the variable $Opts(callback) is defined, then attempt to execute it. catch {eval $Opts(callback)} # If the variable $Winopts(callback) is defined, then attempt to execute it. catch {eval $Winopts(${framename}, callback)} return ${winname} } # Delete the wrapper and the layout window in it. proc magic::closewrapper { framename } { global tk_version global Opts # Remove this window from the target list in .winmenu # (used by, e.g., cellmanager) if { $Opts(target) == "${framename}.magic" } { set Opts(target) "default" if {$tk_version >= 8.5} { if {![catch {wm state .cellmgr}]} { .cellmgr.target.list configure -text "default" } } } set idx [.winmenu index $framename] .winmenu delete $idx ${framename}.magic magic::closewindow destroy $framename } # This procedure adds a command-line entry window to the bottom of # a wrapper window (rudimentary functionality---incomplete) proc magic::addcommandentry { framename } { if {![winfo exists ${framename}.eval]} { tkshell::YScrolled_Text ${framename}.eval -height 5 tkshell::MakeEvaluator ${framename}.eval.text \ "${framename}> " "${framename}.magic " tkshell::MainInit } set rc [grid size ${framename}] set cols [lindex $rc 0] grid ${framename}.eval -row 3 -column 0 -columnspan $cols -sticky ew bind ${framename}.eval.text {focus %W} } # Remove the command entry window from the bottom of a frame. proc magic::deletecommandentry { framename } { grid forget ${framename}.eval } namespace import magic::openwrapper puts "Use openwrapper to create a new GUI-based layout window" namespace import magic::closewrapper puts "Use closewrapper to remove a new GUI-based layout window" # Create a simple wrapper for the 3D window. . . this can be # greatly expanded upon. proc magic::render3d {{cell ""}} { global Opts toplevel .render tkwait visibility .render magic::specialopen wind3d $cell .render.magic .render.magic cutbox box set Opts(cutbox) 1 wm protocol .render WM_DELETE_WINDOW "set Opts(wind3d) 0 ; \ .render.magic closewindow ; destroy .render" frame .render.title pack .render.title -expand true -fill x -side top checkbutton .render.title.cutbox -text "Cutbox" -variable Opts(cutbox) \ -foreground white -background sienna4 -anchor w -padx 15 \ -command [subst { if { \$Opts(cutbox) } { .render.magic cutbox box \ } else { \ .render.magic cutbox none } }] if {$cell == ""} {set cell default} label .render.title.msg -text "3D Rendering window Cell: $cell" \ -foreground white -background sienna4 -anchor w -padx 15 pack .render.title.cutbox -side left pack .render.title.msg -side right -fill x -expand true pack .render.magic -expand true -fill both -side bottom bind .render.magic {focus %W} } magic-8.0.210/tcltk/tclmagic.c0000664000175000001440000007226712032660336014543 0ustar timusers/*----------------------------------------------------------------------*/ /* tclmagic.c --- Creates the interpreter-wrapped version of magic. */ /* */ /* Written by Tim Edwards August 2002 */ /* */ /* Note that this file is tied to Tcl. The original version (from */ /* around April 2002) relied on SWIG, the only differences being */ /* as few %{ ... %} boundaries and the replacement of the */ /* Tclmagic_Init function header with "%init %{", and call the */ /* file "tclmagic.i". However, the rest of the associated wrapper */ /* code got so dependent on Tcl commands that there is no longer any */ /* point in using SWIG. */ /* */ /* When using SWIG, the Makefile requires: */ /* */ /* tclmagic.c: tclmagic.i */ /* swig -tcl8 -o tclmagic.c tclmagic.i */ /* */ /*----------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include "tcltk/tclmagic.h" #include "utils/main.h" #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "utils/dqueue.h" #include "database/database.h" #include "windows/windows.h" #include "commands/commands.h" #include "utils/utils.h" #include "textio/textio.h" #include "textio/txcommands.h" #include "utils/signals.h" #include "graphics/graphics.h" #include "utils/malloc.h" #include "dbwind/dbwind.h" /* * String containing the version number of magic. Don't change the string * here, nor its format. It is updated by the Makefile in this directory. */ char *MagicVersion = MAGIC_VERSION; char *MagicRevision = MAGIC_REVISION; char *MagicCompileTime = MAGIC_DATE; Tcl_Interp *magicinterp; Tcl_Interp *consoleinterp; HashTable txTclTagTable; /* Forward declarations */ int TerminalInputProc(ClientData, char *, int, int *); void TxFlushErr(); void TxFlushOut(); void RegisterTkCommands(); /*--------------------------------------------------------------*/ /* Verify if a command has a tag callback. */ /*--------------------------------------------------------------*/ int TagVerify(keyword) char *keyword; { char *croot, *postcmd; HashEntry *entry; /* Skip over namespace qualifier, if any */ croot = keyword; if (!strncmp(croot, "::", 2)) croot += 2; if (!strncmp(croot, "magic::", 7)) croot += 7; entry = HashLookOnly(&txTclTagTable, croot); postcmd = (entry) ? (char *)HashGetValue(entry) : NULL; return (postcmd) ? TRUE : FALSE; } /*--------------------------------------------------------------*/ /* Find any tags associated with a command and execute them. */ /*--------------------------------------------------------------*/ static int TagCallback(interp, tkpath, argc, argv) Tcl_Interp *interp; char *tkpath; int argc; /* original command's number of arguments */ char *argv[]; /* original command's argument list */ { int argidx, result = TCL_OK; char *postcmd, *substcmd, *newcmd, *sptr, *sres; char *croot; HashEntry *entry; Tcl_SavedResult state; bool reset = FALSE; int cmdnum; /* No command, no action */ if (argc == 0) return TCL_OK; /* Skip over namespace qualifier, if any */ croot = argv[0]; if (!strncmp(croot, "::", 2)) croot += 2; if (!strncmp(croot, "magic::", 7)) croot += 7; entry = HashLookOnly(&txTclTagTable, croot); postcmd = (entry) ? (char *)HashGetValue(entry) : NULL; if (postcmd) { /* The Tag callback should not increase the command number */ /* sequence, so save it now and restore it before returning. */ cmdnum = TxCommandNumber; substcmd = (char *)mallocMagic(strlen(postcmd) + 1); strcpy(substcmd, postcmd); sptr = substcmd; /*--------------------------------------------------------------*/ /* Parse "postcmd" for Tk-substitution escapes */ /* Allowed escapes are: */ /* %W substitute the tk path of the layout window */ /* %r substitute the previous Tcl result string */ /* %R substitute the previous Tcl result string and */ /* reset the Tcl result. */ /* %[0-5] substitute the argument to the original command */ /* %% substitute a single percent character */ /* %* (all others) no action: print as-is. */ /*--------------------------------------------------------------*/ while ((sptr = strchr(sptr, '%')) != NULL) { switch (*(sptr + 1)) { case 'W': /* In the case of the %W escape, first we see if a Tk */ /* path has been passed in the argument. If not, get */ /* the window path if there is only one window. */ /* Otherwise, the window is unknown so we substitute */ /* a null list "{}". */ if (tkpath == NULL) { MagWindow *w = NULL; windCheckOnlyWindow(&w, DBWclientID); if (w != NULL && !(w->w_flags & WIND_OFFSCREEN)) { Tk_Window tkwind = (Tk_Window) w->w_grdata; if (tkwind != NULL) tkpath = Tk_PathName(tkwind); } } if (tkpath == NULL) newcmd = (char *)mallocMagic(strlen(substcmd) + 2); else newcmd = (char *)mallocMagic(strlen(substcmd) + strlen(tkpath)); strcpy(newcmd, substcmd); if (tkpath == NULL) strcpy(newcmd + (int)(sptr - substcmd), "{}"); else strcpy(newcmd + (int)(sptr - substcmd), tkpath); strcat(newcmd, sptr + 2); freeMagic(substcmd); substcmd = newcmd; sptr = substcmd; break; case 'R': reset = TRUE; case 'r': sres = (char *)Tcl_GetStringResult(magicinterp); newcmd = (char *)mallocMagic(strlen(substcmd) + strlen(sres) + 1); strcpy(newcmd, substcmd); sprintf(newcmd + (int)(sptr - substcmd), "\"%s\"", sres); strcat(newcmd, sptr + 2); freeMagic(substcmd); substcmd = newcmd; sptr = substcmd; break; case '0': case '1': case '2': case '3': case '4': case '5': argidx = (int)(*(sptr + 1) - '0'); if ((argidx >= 0) && (argidx < argc)) { newcmd = (char *)mallocMagic(strlen(substcmd) + strlen(argv[argidx])); strcpy(newcmd, substcmd); strcpy(newcmd + (int)(sptr - substcmd), argv[argidx]); strcat(newcmd, sptr + 2); freeMagic(substcmd); substcmd = newcmd; sptr = substcmd; } else if (argidx >= argc) { newcmd = (char *)mallocMagic(strlen(substcmd) + 1); strcpy(newcmd, substcmd); strcpy(newcmd + (int)(sptr - substcmd), sptr + 2); freeMagic(substcmd); substcmd = newcmd; sptr = substcmd; } else sptr++; break; case '%': newcmd = (char *)mallocMagic(strlen(substcmd) + 1); strcpy(newcmd, substcmd); strcpy(newcmd + (int)(sptr - substcmd), sptr + 1); freeMagic(substcmd); substcmd = newcmd; sptr = substcmd; break; default: break; } } /* fprintf(stderr, "Substituted tag callback is \"%s\"\n", substcmd); */ /* fflush(stderr); */ Tcl_SaveResult(interp, &state); result = Tcl_EvalEx(interp, substcmd, -1, 0); if ((result == TCL_OK) && (reset == FALSE)) Tcl_RestoreResult(interp, &state); else Tcl_DiscardResult(&state); freeMagic(substcmd); TxCommandNumber = cmdnum; /* restore original value */ } return result; } /*--------------------------------------------------------------*/ /* Add a command tag callback */ /*--------------------------------------------------------------*/ static int AddCommandTag(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { HashEntry *entry; char *hstring; if (argc != 2 && argc != 3) return TCL_ERROR; entry = HashFind(&txTclTagTable, argv[1]); if (entry == NULL) return TCL_ERROR; hstring = (char *)HashGetValue(entry); if (argc == 2) { Tcl_SetResult(magicinterp, hstring, NULL); return TCL_OK; } if (hstring != NULL) freeMagic(hstring); if (strlen(argv[2]) == 0) { HashSetValue(entry, NULL); } else { hstring = StrDup((char **)NULL, argv[2]); HashSetValue(entry, hstring); } return TCL_OK; } /*--------------------------------------------------------------*/ /* Dispatch a command from Tcl */ /* See TxTclDispatch() in textio/txCommands.c */ /*--------------------------------------------------------------*/ static int _tcl_dispatch(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { int result, idx; Tcl_Obj *objv0; char *argv0, *tkwind; /* Check command (argv[0]) against known conflicting */ /* command names. If the command is potentially a */ /* Tcl/Tk command, try it as such, first. If a Tcl */ /* error is returned, then try it as a magic */ /* command. Note that the other way (try the magic */ /* command first) would necessitate setting Tcl */ /* results for every magic command. Too much work. */ static char *conflicts[] = { "clockwise", "flush", "load", "label", "array", "grid", NULL }; static char *resolutions[] = { "orig_clock", "tcl_flush", "tcl_load", "tcl_label", "tcl_array", "tcl_grid", NULL }; typedef enum { IDX_CLOCK, IDX_FLUSH, IDX_LOAD, IDX_LABEL, IDX_ARRAY, IDX_GRID } conflictCommand; /* Skip any "::" namespace prefix before parsing */ argv0 = argv[0]; if (!strncmp(argv0, "::", 2)) argv0 += 2; objv0 = Tcl_NewStringObj(argv0, strlen(argv0)); if (Tcl_GetIndexFromObj(interp, objv0, (CONST84 char **)conflicts, "overloaded command", 0, &idx) == TCL_OK) { int i; Tcl_Obj **objv = (Tcl_Obj **)Tcl_Alloc(argc * sizeof(Tcl_Obj *)); /* Create a Tcl_Obj array suitable for calling Tcl_EvalObjv. */ /* The first argument is changed from the magic command name to */ /* "tcl" + the command name. This assumes that all conflicting */ /* command names have been so renamed in the startup script! */ objv[0] = Tcl_NewStringObj(resolutions[idx], strlen(resolutions[idx])); Tcl_IncrRefCount(objv[0]); for (i = 1; i < argc; i++) { objv[i] = Tcl_NewStringObj(argv[i], strlen(argv[i])); Tcl_IncrRefCount(objv[i]); } result = Tcl_EvalObjv(interp, argc, objv, 0); for (i = 0; i < argc; i++) Tcl_DecrRefCount(objv[i]); Tcl_Free((char *)objv); if (result == TCL_OK) return result; /* The rule is to execute Magic commands for any Tcl command */ /* with the same name that returns an error. However, this */ /* rule hangs magic when the "load" command is used on a shared */ /* object file that fails to load properly. So if the filename */ /* has an extension which is not ".mag", we will return the */ /* error. */ if (idx == IDX_LOAD) { char *dotptr; if ((argc >= 2) && (dotptr = strrchr(argv[1], '.')) != NULL) if (strcmp(dotptr + 1, "mag")) return result; } } Tcl_ResetResult(interp); if (TxInputRedirect == TX_INPUT_REDIRECTED) TxInputRedirect = TX_INPUT_PENDING_RESET; TxTclDispatch(clientData, argc, argv); if (TxInputRedirect == TX_INPUT_PENDING_RESET) TxInputRedirect = TX_INPUT_NORMAL; /* If the command did not pass through _tk_dispatch, but the command was */ /* entered by key redirection from a window, then TxInputRedirect will be */ /* set to TX_INPUT_PROCESSING and the window ID will have been set by */ /* TxSetPoint(). Do our level best to find the Tk window name. */ if (TxInputRedirect == TX_INPUT_PROCESSING) { if (GrWindowNamePtr) { MagWindow *mw = WindSearchWid(TxGetPoint(NULL)); if (mw != NULL) tkwind = (*GrWindowNamePtr)(mw); else tkwind = NULL; } else tkwind = NULL; } else tkwind = NULL; return TagCallback(interp, tkwind, argc, argv); } /*--------------------------------------------------------------*/ /* Dispatch a window-related command. The first argument is */ /* the window to which the command should be directed, so we */ /* determine which window this is, set "TxCurCommand" values */ /* to point to the window, then dispatch the command. */ /*--------------------------------------------------------------*/ static int _tk_dispatch(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { int id; char *tkpath; char *arg0; Point txp; if (GrWindowIdPtr) { /* Key macros set the point from the graphics module code but */ /* set up the command to be dispatched via _tk_dispatch(). */ /* Therefore it is necessary to check if a point position */ /* has already been set for this command. If not, then the */ /* command was probably called from the command entry window, */ /* so we choose an arbitrary point which is somewhere in the */ /* window, so that command functions have a point of reference. */ id = (*GrWindowIdPtr)(argv[0]); if (TxGetPoint(&txp) != id) { /* This is a point in the window, inside the */ /* scrollbars if they are managed by magic. */ txp.p_x = 20; txp.p_y = 20; } TxSetPoint(txp.p_x, txp.p_y, id); arg0 = argv[0]; argc--; argv++; } TxTclDispatch(clientData, argc, argv); /* Get pathname of window and pass to TagCallback */ return TagCallback(interp, arg0, argc, argv); } /*--------------------------------------------------------------*/ /* Set up a window to use commands via _tk_dispatch */ /*--------------------------------------------------------------*/ void MakeWindowCommand(char *wname, MagWindow *mw) { char *tclcmdstr; Tcl_CreateCommand(magicinterp, wname, (Tcl_CmdProc *)_tk_dispatch, (ClientData)mw, (Tcl_CmdDeleteProc *) NULL); /* Force the window manager to use magic's "close" command to close */ /* down a window. */ tclcmdstr = (char *)mallocMagic(52 + 2 * strlen(wname)); sprintf(tclcmdstr, "wm protocol %s WM_DELETE_WINDOW " "{magic::closewindow %s}", wname, wname); Tcl_EvalEx(magicinterp, tclcmdstr, -1, 0); freeMagic(tclcmdstr); } /*------------------------------------------------------*/ /* Main startup procedure */ /*------------------------------------------------------*/ static int _magic_initialize(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { WindClient client; int n, i; char keyword[100]; char *kwptr = keyword + 7; char **commandTable; int result; /* Is magic being executed in a slave interpreter? */ if ((consoleinterp = Tcl_GetMaster(interp)) == NULL) consoleinterp = interp; /* Did we start in the same interpreter as we initialized? */ if (magicinterp != interp) { TxError("Warning: Switching interpreters. Tcl-magic is not set up " "to handle this.\n"); magicinterp = interp; } TxPrintf("Starting magic under Tcl interpreter\n"); if (mainInitBeforeArgs(argc, argv) != 0) goto magicfatal; if (mainDoArgs(argc, argv) != 0) goto magicfatal; if (TxTkConsole) TxPrintf("Using Tk console window\n"); else TxPrintf("Using the terminal as the console.\n"); TxFlushOut(); if (mainInitAfterArgs() != 0) goto magicfatal; /* Registration of commands is performed after calling the */ /* start function, not after initialization, as the command */ /* modularization requires magic initialization to get a */ /* valid DBWclientID, windClientID, etc. */ sprintf(keyword, "magic::"); /* Work through all the known clients, and register the */ /* commands of all of them. */ client = (WindClient)NULL; while ((client = WindNextClient(client)) != NULL) { commandTable = WindGetCommandTable(client); for (n = 0; commandTable[n] != NULL; n++) { sscanf(commandTable[n], "%s ", kwptr); /* get first word */ Tcl_CreateCommand(interp, keyword, (Tcl_CmdProc *)_tcl_dispatch, (ClientData)NULL, (Tcl_CmdDeleteProc *) NULL); } } /* Extra commands provided by the Tk graphics routines */ /* (See graphics/grTkCommon.c) */ /* (Unless "-dnull" option has been given) */ if (strcmp(MainDisplayType, "NULL")) RegisterTkCommands(interp); return TCL_OK; magicfatal: TxResetTerminal(); Tcl_SetResult(interp, "Magic initialization encountered a fatal error.", NULL); return TCL_ERROR; } /*--------------------------------------------------------------*/ /* Post-initialization: read in the magic startup files and */ /* load any initial layout. Note that this is not done via */ /* script, but probably should be. */ /*--------------------------------------------------------------*/ static int _magic_startup(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { Tcl_ChannelType *inChannel; /* Execute contents of startup files and load any initial cell */ if (mainInitFinal() != 0) { /* We don't want mainInitFinal errors to return TCL_ERROR from */ /* magic::start; otherwise, the window won't come up. As long */ /* as we have successfully passed mainInitAfterArgs(), magic is */ /* fundamentally sound. */ Tcl_SetResult(interp, "Magic encountered problems with the startup files.", NULL); } TxResetTerminal(); if (TxTkConsole) { Tcl_EvalEx(consoleinterp, "tkcon set ::tkcon::OPT(showstatusbar) 1", -1, 0); TxSetPrompt('%'); } else { /* Use the terminal. */ /* Replace the input proc for stdin with our own. */ inChannel = Tcl_GetChannelType(Tcl_GetStdChannel(TCL_STDIN)); inChannel->inputProc = TerminalInputProc; } return TCL_OK; } /*--------------------------------------------------------------*/ /* Tk version of TxDialog */ /*--------------------------------------------------------------*/ int TxDialog(prompt, responses, defresp) char *prompt; char *(responses[]); int defresp; { Tcl_Obj *objPtr; int code, result, pos; char *evalstr, *newstr; /* Ensure that use of TxPrintString doesn't overwrite the */ /* value of prompt my making a copy of it. */ /* 5/11/05---use Tcl_escape() to do the duplication; this */ /* ensures that cell names with special characters like '$' */ /* will be handled properly. */ newstr = Tcl_escape(prompt); /* newstr = StrDup((char **)NULL, prompt); */ evalstr = TxPrintString("tk_dialog .dialog \"Dialog\"" " \"%s\" {} %d ", newstr, defresp); /* freeMagic(newstr); */ Tcl_Free(newstr); /* Tcl_escape() uses Tcl_Alloc() */ for (pos = 0; responses[pos] != 0; pos++) { newstr = StrDup((char **)NULL, evalstr); evalstr = TxPrintString("%s \"%s\" ", newstr, responses[pos]); freeMagic(newstr); } Tcl_EvalEx(magicinterp, evalstr, -1, 0); objPtr = Tcl_GetObjResult(magicinterp); result = Tcl_GetIntFromObj(magicinterp, objPtr, &code); if (result == TCL_OK) return code; else return -1; } /*--------------------------------------------------------------*/ /* TxUseMore and TxStopMore are dummy functions, although they */ /* could be used to set up a top-level window containing the */ /* result (redefine "puts" to write to the window). */ /*--------------------------------------------------------------*/ void TxUseMore() { } /*--------------------------------------------------------------*/ void TxStopMore() { } /*--------------------------------------------------------------*/ /* Set the prompt, if we are using the TkCon console */ /*--------------------------------------------------------------*/ extern char txPromptChar; void TxSetPrompt(ch) char ch; { Tcl_SavedResult state; char promptline[16]; if (TxTkConsole) { sprintf(promptline, "replaceprompt %c", ch); Tcl_SaveResult(consoleinterp, &state); Tcl_EvalEx(consoleinterp, promptline, 15, 0); Tcl_RestoreResult(consoleinterp, &state); } } /*--------------------------------------------------------------*/ /* Get a line from stdin (Tcl replacement for Tx function) */ /*--------------------------------------------------------------*/ char * TxGetLinePfix(dest, maxChars, prefix) char *dest; int maxChars; char *prefix; { Tcl_Obj *objPtr; int charsStored, length; char *string; if (TxTkConsole) { /* Use dialog function (must be defined in magic.tcl!) */ if (prefix != NULL) { string = Tcl_Alloc(20 + strlen(prefix)); sprintf(string, "magic::dialog \"\" \"%s\"\n", prefix); Tcl_EvalEx(magicinterp, string, -1, 0); Tcl_Free(string); } else Tcl_EvalEx(magicinterp, "magic::dialog", 13, 0); } else { if (prefix != NULL) { TxPrintf("%s", prefix); TxFlushOut(); } Tcl_EvalEx(magicinterp, "gets stdin", 10, 0); } objPtr = Tcl_GetObjResult(magicinterp); string = Tcl_GetStringFromObj(objPtr, &length); if (length > 0) if (*(string + length - 1) == '\n') length--; if (length == 0) return NULL; else if (length >= maxChars) length = (maxChars - 1); strncpy(dest, string, length); *(dest + length) = '\0'; return dest; } /*--------------------------------------------------------------*/ /* Parse a file. This is a skeleton version of the TxDispatch */ /* routine in textio/txCommands.c */ /*--------------------------------------------------------------*/ void TxDispatch(f) FILE *f; /* Under Tcl, we never call this with NULL */ { if (f == NULL) { TxError("Error: TxDispatch(NULL) was called\n"); } while (!feof(f)) { if (SigInterruptPending) { TxError("Read-in of file aborted.\n"); SigInterruptPending = FALSE; return; } txGetFileCommand(f, NULL); } } /*--------------------------------------------------------------*/ /* Send a command line which was collected by magic's TxEvent */ /* handler to the interpreter's event queue. */ /*--------------------------------------------------------------*/ void TxParseString(str, q, event) char *str; caddr_t q; /* unused */ caddr_t event; /* always NULL (ignored) */ { char *reply; Tcl_EvalEx(magicinterp, str, -1, 0); reply = (char *)Tcl_GetStringResult(magicinterp); if (strlen(reply) > 0) TxPrintf("%s: %s\n", str, reply); } /*--------------------------------------------------------------*/ /* Replacement for TxFlush(): use Tcl interpreter */ /* If we just call "flush", _tcl_dispatch gets called, and */ /* bad things will happen. */ /*--------------------------------------------------------------*/ void TxFlushErr() { Tcl_SavedResult state; Tcl_SaveResult(magicinterp, &state); Tcl_EvalEx(magicinterp, "::tcl_flush stderr", 18, 0); Tcl_RestoreResult(magicinterp, &state); } /*--------------------------------------------------------------*/ void TxFlushOut() { Tcl_SavedResult state; Tcl_SaveResult(magicinterp, &state); Tcl_EvalEx(magicinterp, "::tcl_flush stdout", 18, 0); Tcl_RestoreResult(magicinterp, &state); } /*--------------------------------------------------------------*/ void TxFlush() { TxFlushOut(); TxFlushErr(); } /*--------------------------------------------------------------*/ /* Tcl_printf() replaces vfprintf() for use by every Tx output */ /* function (namely, TxError() for stderr and TxPrintf() for */ /* stdout). It changes the result to a Tcl "puts" call, which */ /* can be changed inside Tcl, as, for example, by TkCon. */ /* */ /* 6/17/04---Routine extended to escape double-dollar-sign '$$' */ /* which is used by some tools when generating via cells. */ /*--------------------------------------------------------------*/ int Tcl_printf(FILE *f, char *fmt, va_list args_in) { va_list args; static char outstr[128] = "puts -nonewline std"; char *outptr, *bigstr = NULL, *finalstr = NULL; int i, nchars, result, escapes = 0, limit; Tcl_Interp *printinterp = (TxTkConsole) ? consoleinterp : magicinterp; strcpy (outstr + 19, (f == stderr) ? "err \"" : "out \""); va_copy(args, args_in); outptr = outstr; nchars = vsnprintf(outptr + 24, 102, fmt, args); va_end(args); if (nchars >= 102) { va_copy(args, args_in); bigstr = Tcl_Alloc(nchars + 26); strncpy(bigstr, outptr, 24); outptr = bigstr; vsnprintf(outptr + 24, nchars + 2, fmt, args); va_end(args); } else if (nchars == -1) nchars = 126; for (i = 24; *(outptr + i) != '\0'; i++) { if (*(outptr + i) == '\"' || *(outptr + i) == '[' || *(outptr + i) == ']' || *(outptr + i) == '\\') escapes++; else if (*(outptr + i) == '$' && *(outptr + i + 1) == '$') escapes += 2; } if (escapes > 0) { /* "+ 4" required to process "$$...$$"; haven't figured out why. */ finalstr = Tcl_Alloc(nchars + escapes + 26 + 4); strncpy(finalstr, outptr, 24); escapes = 0; for (i = 24; *(outptr + i) != '\0'; i++) { if (*(outptr + i) == '\"' || *(outptr + i) == '[' || *(outptr + i) == ']' || *(outptr + i) == '\\') { *(finalstr + i + escapes) = '\\'; escapes++; } else if (*(outptr + i) == '$' && *(outptr + i + 1) == '$') { *(finalstr + i + escapes) = '\\'; *(finalstr + i + escapes + 1) = '$'; *(finalstr + i + escapes + 2) = '\\'; escapes += 2; i++; } *(finalstr + i + escapes) = *(outptr + i); } outptr = finalstr; } *(outptr + 24 + nchars + escapes) = '\"'; *(outptr + 25 + nchars + escapes) = '\0'; result = Tcl_EvalEx(printinterp, outptr, -1, 0); if (bigstr != NULL) Tcl_Free(bigstr); if (finalstr != NULL) Tcl_Free(finalstr); return result; } /*--------------------------------------------------------------*/ /* Tcl_escape() takes a string as input and produces a string */ /* in which characters are escaped as necessary to make them */ /* printable from Tcl. The new string is allocated by */ /* Tcl_Alloc() which needs to be free'd with Tcl_Free(). */ /* */ /* 6/17/04---extended like Tcl_printf to escape double-dollar- */ /* sign ('$$') in names. */ /*--------------------------------------------------------------*/ char * Tcl_escape(instring) char *instring; { char *newstr; int nchars = 0; int escapes = 0; int i; for (i = 0; *(instring + i) != '\0'; i++) { nchars++; if (*(instring + i) == '\"' || *(instring + i) == '[' || *(instring + i) == ']') escapes++; else if (*(instring + i) == '$' && *(instring + i + 1) == '$') escapes += 2; } newstr = Tcl_Alloc(nchars + escapes + 1); escapes = 0; for (i = 0; *(instring + i) != '\0'; i++) { if (*(instring + i) == '\"' || *(instring + i) == '[' || *(instring + i) == ']') { *(newstr + i + escapes) = '\\'; escapes++; } else if (*(instring + i) == '$' && *(instring + i + 1) == '$') { *(newstr + i + escapes) = '\\'; *(newstr + i + escapes + 1) = '$'; *(newstr + i + escapes + 2) = '\\'; escapes += 2; i++; } *(newstr + i + escapes) = *(instring + i); } *(newstr + i + escapes) = '\0'; return newstr; } /*--------------------------------------------------------------*/ /* Provide input to Tcl from outside the terminal window by */ /* stacking the "stdin" channel. */ /*--------------------------------------------------------------*/ typedef struct { Tcl_Channel channel; /* This is all the info we need */ int fd; } FileState; /*--------------------------------------------------------------*/ int TerminalInputProc(instanceData, buf, toRead, errorCodePtr) ClientData instanceData; char *buf; int toRead; int *errorCodePtr; { FileState *fsPtr = (FileState *) instanceData; int bytesRead, i, tlen; char *locbuf; *errorCodePtr = 0; TxInputRedirect = TX_INPUT_NORMAL; if (TxBuffer != NULL) { tlen = strlen(TxBuffer); if (tlen < toRead) { strcpy(buf, TxBuffer); Tcl_Free(TxBuffer); TxBuffer = NULL; return tlen; } else { strncpy(buf, TxBuffer, toRead); locbuf = Tcl_Alloc(tlen - toRead + 1); strcpy(locbuf, TxBuffer + toRead); Tcl_Free(TxBuffer); TxBuffer = locbuf; return toRead; } } bytesRead = read(fsPtr->fd, buf, (size_t) toRead); if (bytesRead > -1) return bytesRead; *errorCodePtr = errno; return -1; } /*--------------------------------------------------------------*/ int Tclmagic_Init(interp) Tcl_Interp *interp; { char *cadroot; /* Sanity check! */ if (interp == NULL) return TCL_ERROR; /* Remember the interpreter */ magicinterp = interp; if (Tcl_InitStubs(interp, "8.1", 0) == NULL) return TCL_ERROR; /* Initialization and Startup commands */ Tcl_CreateCommand(interp, "magic::initialize", (Tcl_CmdProc *)_magic_initialize, (ClientData)NULL, (Tcl_CmdDeleteProc *) NULL); Tcl_CreateCommand(interp, "magic::startup", (Tcl_CmdProc *)_magic_startup, (ClientData)NULL, (Tcl_CmdDeleteProc *) NULL); /* Initialize the command-tag callback feature */ HashInit(&txTclTagTable, 10, HT_STRINGKEYS); Tcl_CreateCommand(interp, "magic::tag", (Tcl_CmdProc *)AddCommandTag, (ClientData)NULL, (Tcl_CmdDeleteProc *) NULL); /* Add the magic TCL directory to the Tcl library search path */ Tcl_Eval(interp, "lappend auto_path " TCL_DIR ); /* Set $CAD_ROOT as a Tcl variable */ cadroot = getenv("CAD_ROOT"); if (cadroot == NULL) cadroot = CAD_DIR; Tcl_SetVar(interp, "CAD_ROOT", cadroot, TCL_GLOBAL_ONLY); Tcl_PkgProvide(interp, "Tclmagic", MAGIC_VERSION); return TCL_OK; } /*--------------------------------------------------------------*/ /* Define a "safe init" function for those platforms that */ /* require it. */ /*--------------------------------------------------------------*/ int Tclmagic_SafeInit(interp) Tcl_Interp *interp; { return Tclmagic_Init(interp); } magic-8.0.210/tcltk/tools.tcl0000664000175000001440000004416212404142456014452 0ustar timusers#------------------------------------------------------- # Useful tools for the Tcl-based version of magic #------------------------------------------------------- # This file is included by wrapper.tcl if it is found # in the magic install directory. #------------------------------------------------------- # Suspend and resume drawing in windows # Modified 8/17/04 so that calls to suspendall and resumeall # may nest. proc magic::suspendall {} { global Winopts foreach window [magic::windownames layout] { set framename [winfo parent $window] if {$framename == "."} { set framename $window } if {[catch {incr Winopts(${framename},suspend)}]} { set Winopts(${framename},suspend) 1 $window update suspend } } } proc magic::resumeall {} { global Winopts foreach window [magic::windownames layout] { set framename [winfo parent $window] if {$framename == "."} { set framename $window } if {[catch {incr Winopts($framename,suspend) -1}]} { error "resume called without suspend" } else { if { $Winopts(${framename},suspend) <= 0 } { unset Winopts(${framename},suspend) $window update resume } } } } #-------------------------------------------------------------------------- # Crash backups. Create a new crash recovery backup every 10 minutes, or # at the interval specified by Opts(backupinterval) #-------------------------------------------------------------------------- proc magic::makecrashbackup {} { global Opts crash save if {$Opts(backupinterval) > 0} { after $Opts(backupinterval) magic::makecrashbackup } } proc magic::crashbackups {{option start}} { global Opts switch -exact $option { start { if {[catch set Opts(backupinterval)]} { set Opts(backupinterval) 600000 } after $Opts(backupinterval) magic::makecrashbackup } stop - cancel { after cancel magic::makecrashbackup } } } #-------------------------------------------------------------------------- # Push and Pop---Treat the edit hierarchy like a stack. #-------------------------------------------------------------------------- proc magic::pushstack {{name ""}} { global editstack if {$name == ""} { # no cell selected, so see if we can select one set selected [what -list] if {[llength [lindex $selected 2]] == 0} { pushbox select cell popbox } set name [cellname list self] } if {$name == ""} { error "No cell to push!" } elseif {[llength $name] > 1} { error "Too many cells selected!" } if {[catch {lindex $editstack end}]} { set editstack {} } lappend editstack [cellname list window] set ltag [tag load] tag load {} load $name catch {magic::cellmanager} magic::captions tag load $ltag return } proc magic::popstack {} { global editstack if {[llength $editstack] == 0} { error "No subcell stack!" } else { set ltag [tag load] tag load {} load [lindex $editstack end] tag load $ltag set editstack [lrange $editstack 0 end-1] catch {magic::cellmanager} magic::captions } return } proc magic::clearstack {} { global editstack set editstack {} } # More stacking stuff---stacked box values #--------------------------------------------------------------------- # pushbox -- # Remember the current box values # #--------------------------------------------------------------------- proc magic::pushbox {{values {}}} { global boxstack set snaptype [snap list] snap internal if {[catch {set boxstack}]} { set boxstack {} } if {$values == {}} { lappend boxstack [box values] } else { lappend boxstack $values } snap $snaptype return } #--------------------------------------------------------------------- # popbox -- # Recall the last pushed box position # # Option "type" may be empty, or "size" or "position" to pop a specific # box size or position without affecting the other box parameters. #--------------------------------------------------------------------- proc magic::popbox {{type values}} { global boxstack set snaptype [snap list] snap internal if {[catch {set boxstack}]} { error "No stack" } elseif {$boxstack == {}} { error "Empty stack" } set b [lindex $boxstack end] switch -exact $type { values { box values [lindex $b 0] [lindex $b 1] [lindex $b 2] [lindex $b 3] } size { box size [expr {[lindex $b 2] - [lindex $b 0]}] \ [expr {[lindex $b 3] - [lindex $b 1]}] } position { box position [lindex $b 0] [lindex $b 1] } } set boxstack [lrange $boxstack 0 end-1] snap $snaptype return $b } #--------------------------------------------------------------------- # peekbox -- # Shell procedure that calls popbox but follows by pushing the # popped value back onto the stack, resulting in a "peek" mode. # # Options are the same as for "popbox" (see above). #--------------------------------------------------------------------- proc magic::peekbox {{type values}} { global bidx if {![catch {set b [magic::popbox $type]}]} { magic::pushbox $b } else { error "No stack" } return $b } #--------------------------------------------------------------------- # Text auto-increment and auto-decrement #--------------------------------------------------------------------- proc magic::autoincr {{amount 1}} { set mtext [macro list .] set num [regexp -inline {[+-]*[[:digit:]]+} $mtext] if {$num != ""} { incr num $amount regsub {[+-]*[[:digit:]]+} $mtext $num mtext eval $mtext macro . "$mtext" } } magic::macro XK_plus {magic::autoincr 1} magic::macro XK_minus {magic::autoincr -1} #--------------------------------------------------------------------- # The following several routines are designed to aid in generating # documentation for technology files, or to generate design rule # documents using magic layout windows in a Tk tabbed-window # framework. #--------------------------------------------------------------------- #--------------------------------------------------------------------- # Ruler generation using the "element" command # A line with arrows is drawn showing the dimension of the cursor box. # The text of "text", if non-NULL, is placed in the middle of the # ruler area. The orientation of "orient" describes whether the # ruler is a vertical or horizontal measurement. By default, the # longest dimension of the box is the orientation. #--------------------------------------------------------------------- proc magic::ruler {{text {}} {orient auto}} { global Opts if {[catch {set Opts(rulers)}]} { set Opts(rulers) 0 } else { incr Opts(rulers) } set bv [box values] set llx [lindex $bv 0] set lly [lindex $bv 1] set urx [lindex $bv 2] set ury [lindex $bv 3] set width [expr {[lindex $bv 2] - [lindex $bv 0]}] set height [expr {[lindex $bv 3] - [lindex $bv 1]}] if {$orient == "auto"} { if {$width > $height} { set orient "horizontal" } else { set orient "vertical" } } if {[llength $text] > 0} { if {$orient == "horizontal"} { set tclr 4 } else { set tclr 2 } } else { set tclr 0 } set mmx [expr {($llx + $urx) / 2}] set mmy [expr {($lly + $ury) / 2}] if {$orient == "horizontal"} { element add line l1_$Opts(rulers) black $llx $lly $llx $ury element add line l4_$Opts(rulers) black $urx $lly $urx $ury set mmx1 [expr {$mmx - $tclr}] set mmx2 [expr {$mmx + $tclr}] if {$mmx1 == $llx} {set mmx1 [expr {$llx - 2}]} if {$mmx2 == $urx} {set mmx2 [expr {$urx + 2}]} element add line l2_$Opts(rulers) black $llx $mmy $mmx1 $mmy element add line l3_$Opts(rulers) black $mmx2 $mmy $urx $mmy if {$tclr > 0} { element add text t_$Opts(rulers) black $mmx $mmy $text } if {$llx < $mmx1} { element configure l2_$Opts(rulers) flags arrowleft } else { element configure l2_$Opts(rulers) flags arrowright } if {$urx > $mmx2} { element configure l3_$Opts(rulers) flags arrowright } else { element configure l3_$Opts(rulers) flags arrowleft } } else { element add line l1_$Opts(rulers) black $llx $lly $urx $lly element add line l4_$Opts(rulers) black $llx $ury $urx $ury set mmy1 [expr {$mmy - $tclr}] set mmy2 [expr {$mmy + $tclr}] if {$mmy1 == $lly} {set mmy1 [expr {$lly - 2}]} if {$mmy2 == $ury} {set mmy2 [expr {$ury + 2}]} element add line l2_$Opts(rulers) black $mmx $lly $mmx $mmy1 element add line l3_$Opts(rulers) black $mmx $mmy2 $mmx $ury if {$tclr > 0} { element add text t_$Opts(rulers) black $mmx $mmy $text } if {$lly < $mmy1} { element configure l2_$Opts(rulers) flags arrowbottom } else { element configure l2_$Opts(rulers) flags arrowtop } if {$ury > $mmy2} { element configure l3_$Opts(rulers) flags arrowtop } else { element configure l3_$Opts(rulers) flags arrowbottom } } } #--------------------------------------------------------------------- # Automatic measurement ruler #--------------------------------------------------------------------- proc magic::measure {{orient auto}} { set scale [cif scale out] set bv [box values] set llx [lindex $bv 0] set lly [lindex $bv 1] set urx [lindex $bv 2] set ury [lindex $bv 3] set width [expr {[lindex $bv 2] - [lindex $bv 0]}] set height [expr {[lindex $bv 3] - [lindex $bv 1]}] if {$orient == "auto"} { if {$width > $height} { set orient "horizontal" } else { set orient "vertical" } } if {$orient == "horizontal"} { set tval [expr {$scale * $width}] } else { set tval [expr {$scale * $height}] } set text [format "%g um" $tval] ruler $text $orient } #--------------------------------------------------------------------- # Remove all rulers (this should probably be refined to remove # just the rulers under the box). #--------------------------------------------------------------------- proc magic::unmeasure {} { set blist [element inbox] set mlist {} foreach m $blist { switch -regexp $m { l[1-4]_[0-9] { lappend mlist [string range $m 3 end] } t_[0-9] { lappend mlist [string range $m 2 end] } } } set blist [lsort -unique $mlist] foreach m $blist { element delete t_$m element delete l1_$m element delete l2_$m element delete l3_$m element delete l4_$m } } #--------------------------------------------------------------------- # Key generation for annotating layouts. #--------------------------------------------------------------------- proc magic::genkey {layer {keysize 4}} { global Opts box size $keysize $keysize paint $layer if {[catch {set Opts(keys)}]} { set Opts(keys) 0 } else { incr Opts(keys) } # eval "element add rectangle keyrect$Opts(keys) subcircuit [box values]" box move e $keysize set bv [box values] set cx [expr {([lindex $bv 2] + [lindex $bv 0]) / 2}] set cy [expr {([lindex $bv 3] + [lindex $bv 1]) / 2}] element add text key$Opts(keys) white $cx $cy $layer element configure key$Opts(keys) flags east } #--------------------------------------------------------------------- # Because this file is read prior to setting the magic command # names in Tcl, we cannot run the magic commands here. Create # a procedure to enable the commands, then run that procedure # from the system .magic script. #--------------------------------------------------------------------- proc magic::enable_tools {} { global Opts # Set keystrokes for push and pop magic::macro XK_greater {magic::pushstack [cellname list self]} magic::macro XK_less {magic::popstack} # Set keystrokes for the "tool" command. magic::macro space {magic::tool} magic::macro Shift_space {magic::tool box} set Opts(tool) box set Opts(motion) {} set Opts(origin) {0 0} set Opts(backupinterval) 60000 magic::crashbackups start } #--------------------------------------------------------------------- # routine which tracks wire generation #--------------------------------------------------------------------- proc magic::trackwire {window {option {}}} { global Opts if {$Opts(motion) == {}} { if {$option == "done"} { wire switch } elseif {$option == "pick"} { puts stdout $window wire type set Opts(motion) [bind ${window} ] bind ${window} [subst {$Opts(motion); *bypass wire show}] if {$Opts(motion) == {}} {set Opts(motion) "null"} cursor 21 } } else { if {$option != "cancel"} { wire leg } if {$option == "done" || $option == "cancel"} { select clear if {$Opts(motion) == "null"} { bind ${window} {} } else { bind ${window} "$Opts(motion)" } set Opts(motion) {} cursor 19 } } } #--------------------------------------------------------------------- # routine which tracks a selection pick #--------------------------------------------------------------------- proc magic::keepselect {window} { global Opts if {$Opts(motion) == {}} { box move bl cursor } else { select keep } } proc magic::startselect {window {option {}}} { global Opts if {$Opts(motion) == {}} { if {$option == "pick"} { select pick } else { set slist [what -list] if {$slist == {{} {} {}}} { select nocycle } } set Opts(origin) [cursor] set Opts(motion) [bind ${window} ] bind ${window} [subst {$Opts(motion); set p \[cursor\]; \ set x \[expr {\[lindex \$p 0\] - [lindex $Opts(origin) 0]}\]i; \ set y \[expr {\[lindex \$p 1\] - [lindex $Opts(origin) 1]}\]i; \ *bypass select move \${x} \${y}}] if {$Opts(motion) == {}} {set Opts(motion) "null"} cursor 21 } else { if {$Opts(motion) == "null"} { bind ${window} {} } else { bind ${window} "$Opts(motion)" } copy center 0 set Opts(motion) {} cursor 22 } } proc magic::cancelselect {window} { global Opts if {$Opts(motion) == {}} { box corner ur cursor } else { if {$Opts(motion) == "null"} { bind ${window} {} } else { bind ${window} "$Opts(motion)" } select clear set Opts(motion) {} cursor 22 } } #--------------------------------------------------------------------- # tool --- A scripted replacement for the "tool" # command, as handling of button events has been modified # to act like the handling of key events, so the "tool" # command just swaps macros for the buttons. # # Added By NP 10/27/2004 #--------------------------------------------------------------------- proc magic::tool {{type next}} { global Opts # Don't attempt to switch tools while a selection drag is active if {$Opts(motion) != {}} { return } if {$type == "next"} { switch $Opts(tool) { box { set type wiring } wiring { set type netlist } netlist { set type pick } pick { set type box } } } switch $type { info { # print information about the current tool. puts stdout "Current tool is $Opts(tool)." puts stdout "Button command bindings:" if {[llength [macro Button1]] > 0} { macro Button1 } if {[llength [macro Button2]] > 0} { macro Button2 } if {[llength [macro Button3]] > 0} { macro Button3 } if {[llength [macro Shift_Button1]] > 0} { macro Shift_Button1 } if {[llength [macro Shift_Button2]] > 0} { macro Shift_Button2 } if {[llength [macro Shift_Button3]] > 0} { macro Shift_Button3 } if {[llength [macro Control_Button1]] > 0} { macro Control_Button1 } if {[llength [macro Control_Button2]] > 0} { macro Control_Button2 } if {[llength [macro Control_Button3]] > 0} { macro Control_Button3 } } box { puts stdout {Switching to BOX tool.} set Opts(tool) box cursor 0 ;# sets the cursor macro Button1 "box move bl cursor" macro Shift_Button1 "box corner bl cursor" macro Button2 "paint cursor" macro Shift_Button2 "erase cursor" macro Button3 "box corner ur cursor" macro Shift_Button3 "box move ur cursor" macro Button4 "scroll u .05 w" macro Button5 "scroll d .05 w" macro Shift_Button4 "scroll r .05 w" macro Shift_Button5 "scroll l .05 w" } wiring { puts stdout {Switching to WIRING tool.} set Opts(tool) wiring cursor 19 ;# sets the cursor macro Button1 "magic::trackwire %W pick" macro Button2 "magic::trackwire %W done" macro Button3 "magic::trackwire %W cancel" macro Shift_Button1 "wire incr type" macro Shift_Button2 "wire switch" macro Shift_Button3 "wire decr type" macro Button4 "wire incr width" macro Button5 "wire decr width" } netlist { puts stdout {Switching to NETLIST tool.} set Opts(tool) netlist cursor 18 ;# sets the cursor macro Button1 "netlist select" macro Button2 "netlist join" macro Button3 "netlist terminal" # Remove shift-button bindings macro Shift_Button1 "" macro Shift_Button2 "" macro Shift_Button3 "" macro Button4 "scroll u .05 w" macro Button5 "scroll d .05 w" } pick { puts stdout {Switching to PICK tool.} set Opts(tool) pick cursor 22 ;# set the cursor macro Button1 "magic::keepselect %W" macro Shift_Button2 "magic::startselect %W copy" macro Button2 "magic::startselect %W pick" macro Button3 "magic::cancelselect %W" macro Shift_Button1 "box corner bl cursor" macro Shift_Button3 "box move ur cursor" macro Button4 "scroll u .05 w" macro Button5 "scroll d .05 w" } } # Update window captions with the new tool info foreach window [magic::windownames layout] { catch {magic::caption $window} } } magic-8.0.210/tcltk/Makefile0000664000175000001440000000515012205170336014235 0ustar timusers# # rcsid $Header: /usr/cvsroot/magic-8.0/tcltk/Makefile,v 1.6 2010/06/24 12:37:56 tim Exp $ # MODULE = tcltk MAGICDIR = .. SRCS = tclmagic.c include ${MAGICDIR}/defs.mak DFLAGS += -DMAGIC_DATE="\"`date`\"" CLEANS += magic.sh magic.tcl magicexec magicdnull TCL_FILES = \ tkcon.tcl \ tkshell.tcl \ wrapper.tcl \ console.tcl \ techbuilder.tcl \ cellmgr.tcl \ texthelper.tcl \ tools.tcl \ mazeroute.tcl \ strip_reflibs.tcl \ drc.tcl \ toolkit.tcl \ magic.tcl BIN_FILES = \ $(DESTDIR)${BINDIR}/magic.sh \ $(DESTDIR)${BINDIR}/ext2spice.sh \ $(DESTDIR)${BINDIR}/ext2sim.sh tcl-main: magicexec magicdnull magic.tcl magic.sh ext2spice.sh ext2sim.sh install-tcl: magicexec magicdnull ${BIN_FILES} ${TCL_FILES} ${RM} $(DESTDIR)${TCLDIR}/magicexec ${CP} magicexec $(DESTDIR)${TCLDIR}/magicexec ${RM} $(DESTDIR)${TCLDIR}/magicdnull ${CP} magicdnull $(DESTDIR)${TCLDIR}/magicdnull (cd $(DESTDIR)${TCLDIR}; ${RM} ${TCL_FILES}) for i in ${TCL_FILES}; do \ ${CP} $$i $(DESTDIR)${TCLDIR}; done (cd $(DESTDIR)${TCLDIR}; chmod 0755 tkcon.tcl tkshell.tcl) magicexec: magicexec.c ${MAGICDIR}/defs.mak ${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS} ${LDFLAGS} magicexec.c \ -o magicexec ${LD_RUN_PATH} ${LIBS} ${LIB_SPECS} magicdnull: magicdnull.c ${MAGICDIR}/defs.mak ${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS} ${LDFLAGS} magicdnull.c \ -o magicdnull ${LD_RUN_PATH} ${LIBS} ${LIB_SPECS} magic.tcl: magic.tcl.in ${MAGICDIR}/defs.mak sed -e /TCL_DIR/s%TCL_DIR%${TCLDIR}%g \ -e /SHDLIB_EXT/s%SHDLIB_EXT%${SHDLIB_EXT}%g magic.tcl.in > magic.tcl magic.sh: magic.sh.in ${MAGICDIR}/defs.mak sed -e /TCL_DIR/s%TCL_DIR%${TCLDIR}%g \ -e /TCLLIB_DIR/s%TCLLIB_DIR%${TCL_LIB_DIR}%g \ -e /WISH_EXE/s%WISH_EXE%${WISH_EXE}%g magic.sh.in > magic.sh ext2spice.sh: ext2spice.sh.in ${MAGICDIR}/defs.mak sed -e /TCL_DIR/s%TCL_DIR%${TCLDIR}%g ext2spice.sh.in > ext2spice.sh ext2sim.sh: ext2sim.sh.in ${MAGICDIR}/defs.mak sed -e /TCL_DIR/s%TCL_DIR%${TCLDIR}%g ext2sim.sh.in > ext2sim.sh $(DESTDIR)${TCLDIR}/%: % ${RM} $(DESTDIR)${TCLDIR}/$* ${CP} $* $(DESTDIR)${TCLDIR}/$* $(DESTDIR)${BINDIR}/magic.sh: magic.sh ${RM} $(DESTDIR)${BINDIR}/magic.sh $(DESTDIR)${BINDIR}/magic ${CP} magic.sh $(DESTDIR)${BINDIR}/magic (cd $(DESTDIR)${BINDIR}; chmod 0755 magic) $(DESTDIR)${BINDIR}/ext2spice.sh: ext2spice.sh ${RM} $(DESTDIR)${BINDIR}/ext2spice ${CP} ext2spice.sh $(DESTDIR)${BINDIR}/ext2spice (cd $(DESTDIR)${BINDIR}; chmod 0755 ext2spice) $(DESTDIR)${BINDIR}/ext2sim.sh: ext2sim.sh ${RM} $(DESTDIR)${BINDIR}/ext2sim ${CP} ext2sim.sh $(DESTDIR)${BINDIR}/ext2sim (cd $(DESTDIR)${BINDIR}; chmod 0755 ext2sim) include ${MAGICDIR}/rules.mak magic-8.0.210/tcltk/magic.tcl.in0000775000175000001440000002520112405633025014771 0ustar timusers# Wishrc startup for ToolScript (magic) # # For installation: Put this file and also magicwrap.so into # directory TCL_DIR, and set the "load" line below # to point to the location of magicwrap.so. Also see comments # in shell script "magic.sh". global Opts # If we called magic via the non-console script, then we want to reset # the environment variable HOME to its original value. load TCL_DIR/tclmagicSHDLIB_EXT # It is important to make sure no magic commands overlap with Tcl built-in # commands, because otherwise the namespace import will fail. proc pushnamespace { name } { set y [namespace eval ${name} info commands ::${name}::*] set z [info commands] # Watch especially for magic "wizard" commands, as we don't want to confuse # the literal "*" with a regular expression *. "regsub" below takes care of it. foreach v $y { regsub -all {\*} $v {\\*} i set x [namespace tail $i] if {[lsearch $z $x] < 0} { namespace import $i } } } proc popnamespace { name } { set z [info commands] set l [expr [string length ${name}] + 5] while {[set v [lsearch $z ${name}_tcl_*]] >= 0} { set y [lindex $z $v] set w [string range $y $l end] interp alias {} ::$w {} rename ::$y ::$w puts "Info: replacing ::$w with ::$y" } namespace forget ::${name}::* } #---------------------------------------------------------------------- # Define the drcstate procedure expected by the background DRC code. proc magic::drcstate {option} { # (Null proc---see wrapper.tcl for a useful version) } #----------------------------------------------------------------- # Define these console routines so that they don't produce errors # when Magic is run in batch mode if {[catch {tkcon title}]} { proc magic::suspendout {} {} proc magic::resumeout {} {} proc magic::dialog {} {} proc magic::consolegeometry {} {} proc magic::consolefocus {} {} } #---------------------------------------------------------------------- # Cross-Application section #---------------------------------------------------------------------- # Check namespaces for existence of other applications set UsingIRSIM 0 set UsingXCircuit 0 set UsingNetgen 0 set nlist [namespace children] foreach i $nlist { switch $i { ::irsim { set UsingIRSIM 1 } ::xcircuit { set UsingXCircuit 1 } ::netgen { set UsingNetgen 1 } } } # Setup IRSIM assuming that the Tcl version is installed. # We do not need to rename procedure irsim to NULL because it is # redefined in a script, which simply overwrites the original. proc irsim { args } { global CAD_ROOT set irsimscript [glob -nocomplain ${CAD_ROOT}/irsim/tcl/irsim.tcl] if { ${irsimscript} == {} } { puts stderr "\"irsim\" requires Tcl-based IRSIM version 9.6 or newer." puts stderr "Could not find script \"irsim.tcl\". If IRSIM is installed in a" puts stderr "place other than CAD_ROOT (=${CAD_ROOT}), use the command" puts stderr "\"source /irsim.tcl\" before doing \"irsim\"." } else { source $irsimscript eval {irsim} $args } } # Setup Xcircuit assuming that the Tcl version is installed. proc xcircuit { args } { global CAD_ROOT global argc global argv set xcircscript [glob -nocomplain ${CAD_ROOT}/xcircuit*/xcircuit.tcl] if { ${xcircscript} == {} } { puts stderr "\"xcircuit\" requires Tcl-based XCircuit version 3.1 or newer." puts stderr "Could not find script \"xcircuit.tcl\". If XCircuit is installed in a" puts stderr "place other than CAD_ROOT (=${CAD_ROOT}), use the command" puts stderr "\"source /xcircuit.tcl\"." } else { # if there are multiple installed versions, choose the highest version. if {[llength $xcircscript] > 1} { set xcircscript [lindex [lsort -decreasing -dictionary $xcircscript] 0] } # execute script in the scope of magic, because its variable space is # not modularized. set argv $args set argc [llength $args] uplevel #0 source $xcircscript } } # Setup Netgen assuming that the Tcl version is installed. proc netgen { args } { global CAD_ROOT global argc global argv set netgenscript [glob -nocomplain ${CAD_ROOT}/netgen/tcl/netgen.tcl] if { ${netgenscript} == {} } { puts stderr "\"netgen\" requires Tcl-based Netgen version 1.2 or newer." puts stderr "Could not find script \"netgen.tcl\". If Netgen is installed in a" puts stderr "place other than CAD_ROOT (=${CAD_ROOT}), use the command" puts stderr "\"source /netgen.tcl\"." } else { set argv $args set argc [llength $args] uplevel #0 source $netgenscript } } # Add the "echo" command proc echo {args} { puts stdout $args } # Parse argument list for "-c[onsole]" and "-now[rapper]". set cellname "" set do_wrapper true set do_recover false set argafter {magic::initialize} set x {} for {set i 0} {$i < $argc} {incr i 1} { set x [lindex $argv $i] # # Command-line argument handling goes here # We have to handle all of magic's command line arguments so we can # figure out if a cell has been named for preloading. # switch -regexp -- $x { ^-now(rap)?(per)?$ { ;# This regexp accepts -now, -nowrap, and -nowrapper set do_wrapper false } ^-dnull { set do_wrapper false lappend argafter $x } ^-r(e)?(cover)?$ { set do_recover true } ^-rc(file)?$ { lappend argafter $x incr i 1 lappend argafter [lindex $argv $i] } ^-d - ^-g - ^-m - ^-i - ^-T { lappend argafter $x incr i 1 lappend argafter [lindex $argv $i] } ^-F { lappend argafter $x incr i 1 lappend argafter [lindex $argv $i] incr i 1 lappend argafter [lindex $argv $i] } ^-D - ^-n* { lappend argafter $x } default { set cellname $x lappend argafter $x } } } if {$do_wrapper} { source ${CAD_ROOT}/magic/tcl/wrapper.tcl lappend argafter "-nowindow" ;# Set no-initial-window option in magic. } unset x i do_wrapper eval $argafter ;# magic::initialize ${argv} #---------------------------------------------------------------------- # Check for presence of padlist manager script and include it if {[file exists ${CAD_ROOT}/magic/tcl/padlist.tcl]} { source ${CAD_ROOT}/magic/tcl/padlist.tcl set Opts(padlist) 0 } #---------------------------------------------------------------------- # Check for presence of the miscellaneous tools script and include it if {[file exists ${CAD_ROOT}/magic/tcl/tools.tcl]} { source ${CAD_ROOT}/magic/tcl/tools.tcl set Opts(tools) 0 } #---------------------------------------------------------------------- # Check for presence of the mazerouter script and include it if {[file exists ${CAD_ROOT}/magic/tcl/mazeroute.tcl]} { source ${CAD_ROOT}/magic/tcl/mazeroute.tcl set Opts(mazeroute) 0 } #---------------------------------------------------------------------- # Check for presence of the toolkit script and include it if {[file exists ${CAD_ROOT}/magic/tcl/toolkit.tcl]} { source ${CAD_ROOT}/magic/tcl/toolkit.tcl set Opts(toolkit) 0 } #---------------------------------------------------------------------- # Magic start function drops back to interpreter after initialization & setup set auto_noexec 1 ;# don't EVER call UNIX commands w/o "shell" in front # Have we called magic from tkcon or a clone thereof? If so, set MagicConsole if {[lsearch [interp aliases] tkcon] != -1} { set MagicConsole tkcon catch {wm withdraw .} # Get rid of some overlapping tkcon commands which are not needed. if {[lsearch [info commands] orig_edit] < 0} {rename edit orig_edit} if {[lsearch [info commands] orig_dump] < 0} {rename dump orig_dump} if {[lsearch [info commands] orig_what] < 0} {rename what orig_what} } else { rename unknown tcl_unknown proc unknown { args } { # CAD tools special: # Check for commands which were renamed to tcl_(command) set cmd [lindex $args 0] if {[lsearch [info commands] tcl_$cmd] >= 0} { set arglist [concat tcl_$cmd [lrange $args 1 end]] set ret [catch {eval $arglist} result] if {$ret == 0} { return $result } else { return -code $ret -errorcode $errorCode $result } } return [eval [concat tcl_unknown $args]] } } # Set up certain commands to act like they do in non-Tcl-based magic; # These are the commands whose names have been extended so they don't # conflict with existing Tcl/Tk commands. This renaming & importing # *requires* the special code in the magic Tcl command dispatcher to # find and deal with each of these renamed commands! if {[lsearch [info commands] orig_clock] < 0} {rename clock orig_clock} if {[lsearch [info commands] tcl_flush] < 0} {rename flush tcl_flush} if {[lsearch [info commands] tcl_load] < 0} {rename load tcl_load} if {[lsearch [info commands] tcl_array] < 0} {rename array tcl_array} if {[lsearch [info commands] tcl_label] < 0} {catch {rename label tcl_label}} if {[lsearch [info commands] tcl_grid] < 0} {catch {rename grid tcl_grid}} namespace eval magic namespace export * pushnamespace magic #---------------------------------------------------------------------- # Read system startup files (mostly macro definitions) # Read user startup file, if any # Load initial cell, if any magic::startup if {![catch {set toptitle [wm title .]}]} { if {[string range $toptitle 0 3] == "wish"} { wm withdraw . } if {[string range $toptitle 0 8] == "magicexec"} { wm withdraw . } unset toptitle } # After loading, magic will wander off and do a complete DRC check # before executing the rest of the script unless we temporarily # disable the DRC checker. set drcstate [drc status] drc off # Initial window for wrapper, if defined. # empty string is equivalent to passing NULL cell name. if {![catch {set winname [magic::openwrapper $cellname]}]} { magic::techmanager initall magic::scrollupdate $winname } else { # Initial geometry handler for the default window, non-wrapper version catch {wm geometry .magic1 ${Opts(geometry)}} } # Set a box, and set the view; if no cell has been loaded, choose a default # view. if {![box exists]} { box 0 0 1 1 ;# create a unit box } if {[llength $cellname] > 0} { view } else { view -9 -9 10 10 } # The Tcl version handles the "-r" on the command line by calling # command crash recover. if {$do_recover} {crash recover} # Unset global TCL variables so they don't conflict with magic nodes. unset cellname nlist do_recover if {$drcstate == 1} { drc on } unset drcstate magic-8.0.210/tcltk/ext2sim.sh.in0000755000175000001440000000064111135117610015127 0ustar timusers#!/bin/sh # # Standalone script for ext2sim, for Tcl-based magic 8.0 # # Parse arguments. "--" separates arguments to magic # from arguments to ext2sim. # mgargs="" esargs="" for i in $@; do case $i in --) mgargs="$esargs" esargs="" ;; *) esargs="$esargs $i" ;; esac done # eval TCL_DIR/magicdnull -dnull -noconsole -nowrapper $mgargs < { \ .techwizard.parts.tech.tinfo.tset configure -text \ [.techwizard.parts.tech.tinfo.tentry get]; \ pack forget .techwizard.parts.tech.tinfo.tentry; \ } button .techwizard.parts.tech.tinfo.tset -text "[magic::tech name]" \ -relief groove \ -foreground green4 \ -command { \ pack .techwizard.parts.tech.tinfo.tentry -side left -expand true; \ } pack .techwizard.parts.tech.tinfo.tname -side left pack .techwizard.parts.tech.tinfo.tset -side left pack .techwizard.parts.tech.tinfo -side top frame .techwizard.parts.planes ::set pnames [magic::tech planes] ::set j 0 foreach i $pnames { entry .techwizard.parts.planes.e$i -width 50 bind .techwizard.parts.planes.e$i \ ".techwizard.parts.planes.p$i configure -text \ [.techwizard.parts.planes.e$i get]; \ ::grid forget .techwizard.parts.planes.e$i" button .techwizard.parts.planes.p$i -text "$i" \ -foreground green4 \ -relief groove \ -command "::grid .techwizard.parts.planes.e$i -row $j -column 1 -sticky news" ::grid .techwizard.parts.planes.p$i -row $j -column 0 -sticky news incr j } ::unset pnames ::unset j .techwizard.parts configure -tiers 2 .techwizard.parts insert end "tech" "planes" "layers" "connect" "compose" \ "cifinput" "cifoutput" "extract" "drc" \ "wiring" "router" "plowing" "plot" .techwizard.parts tab configure "layers" -window .techwizard.parts.layers -fill both .techwizard.parts tab configure "drc" -window .techwizard.parts.drc -fill both .techwizard.parts tab configure "tech" -window .techwizard.parts.tech .techwizard.parts tab configure "planes" -window .techwizard.parts.planes # Add styles to layout for selection ::set i 0 ::set j 0 ::set k 50 while { $k <= 127 } { ::set rx [expr $i + 8] ::set ry [expr $j + 8] .techwizard.parts.layers.layout element add rect style$k $k $i $j $rx $ry incr k incr i 10 if {$i >= 80} {::set i 0; incr j 10} } catch {.techwizard.parts.layers.layout box -100 -10 90 90} catch {.techwizard.parts.layers.layout findbox zoom} catch {.techwizard.parts.layers.layout box -100 -10 -10 90} .techwizard.parts.layers.layout element add text ltitle black 40 85 "Layer Styles" # To do: Add all existing layers and draw their styles pack .techwizard.parts -fill both -expand true wm geometry .techwizard 800x500 magic-8.0.210/tcltk/mazeroute.tcl0000644000175000001440000005062710751423606015330 0ustar timusers#----------------------------------------------------------------- # mazeroute.tcl #----------------------------------------------------------------- # Defines procedure "mazeroute ", requiring a .net file as # an argument. Attempts a single-pass maze route of the contents # of the netlist. #----------------------------------------------------------------- global Opts proc mazeroute {netfile} { if [catch {open $netfile r} fnet] { set netname [file rootname $netfile] if [catch {open ${netfile}.net r} fnet] { puts stderr "Can't read netlist file $netfile" return 1; } } # 1st line of the netlist file is throw-away gets $fnet line set destnet {} while {[gets $fnet line] >= 0} { if {$line == ""} { set destnet {} } elseif {$destnet == {}} { set destnet $line } else { set startnet $line iroute route -dlabel $destnet -slabel $startnet -timeout 3 set destnet $startnet } } } #----------------------------------------------------------------- # Interactive mazerouter GUI. Shows a list of nets from the # selected netlist. Allows one to select the order of routing, # route individual nets, rip up individual nets, etc. # # This GUI more or less replaces the "specialopen netlist" window. #----------------------------------------------------------------- proc genmazehelper {} { global Opts set Opts(preproutes) 0 set Opts(fenced) 0 if {![catch {wm deiconify .mazehelper ; raise .mazehelper}]} {return} toplevel .mazehelper wm protocol .mazehelper WM_DELETE_WINDOW {destroy .mazehelper} frame .mazehelper.mazemenu frame .mazehelper.unrouted frame .mazehelper.transfer frame .mazehelper.routed pack .mazehelper.mazemenu -side top -anchor w button .mazehelper.mazemenu.load -text "Load" -command {loadnetlist} label .mazehelper.mazemenu.netlist -text "(no netlist loaded)" button .mazehelper.mazemenu.fence -text "Fence" -command {buildfence} button .mazehelper.mazemenu.sort -text "Sort" -command {sortnets} button .mazehelper.mazemenu.params -text "Params" -command {genmazeparams} pack .mazehelper.mazemenu.load -side left pack .mazehelper.mazemenu.netlist -side left -fill x -expand true pack .mazehelper.mazemenu.fence -side left pack .mazehelper.mazemenu.sort -side left pack .mazehelper.mazemenu.params -side left label .mazehelper.unrouted.title -text "Unrouted:" listbox .mazehelper.unrouted.contents -background white -selectmode extended label .mazehelper.routed.title -text "Routed:" listbox .mazehelper.routed.contents -background white -selectmode extended button .mazehelper.transfer.ripup -text "<--" -command {ripupnet} button .mazehelper.transfer.route -text "-->" -command {routenet} pack .mazehelper.transfer.ripup -side top pack .mazehelper.transfer.route -side top pack .mazehelper.unrouted.title -side top pack .mazehelper.unrouted.contents -side top -fill both -expand true pack .mazehelper.routed.title -side top pack .mazehelper.routed.contents -side top -fill both -expand true pack .mazehelper.unrouted -side left -fill both -expand true pack .mazehelper.transfer -side left pack .mazehelper.routed -side left -fill both -expand true } #----------------------------------------------------------------- # Route parameters (to be completed) #----------------------------------------------------------------- proc genmazeparams {} { global Opts if {![catch {wm deiconify .mazeparams ; raise .mazeparams}]} {return} toplevel .mazeparams wm protocol .mazeparams WM_DELETE_WINDOW {destroy .mazeparams} set routeparams {layer active width hCost vCost jogCost hintCost overCost} set curRparams [iroute layers -list] set contparams {contact active width cost} set curCparams [iroute contact -list] set k 0 label .mazeparams.t1 -text "Layer" label .mazeparams.t2 -text "Active" label .mazeparams.t3 -text "Width" label .mazeparams.t4 -text "Horizontal Cost" label .mazeparams.t5 -text "Vertical Cost" label .mazeparams.t6 -text "Jog Cost" label .mazeparams.t7 -text "Hint Cost" label .mazeparams.t8 -text "Overroute Cost" foreach layer $curRparams { incr k label .mazeparams.r${k}0 -text [lindex $layer 0] checkbox .mazeparams.r${k}1 for {set j 2} {$j < 8} {incr j} { entry .mazeparams.r${k}${j} -text [lindex $contact $j] } } incr k label .mazeparams.t1 -text "Contact" label .mazeparams.t2 -text "Active" label .mazeparams.t3 -text "Size" label .mazeparams.t4 -text "Cost" foreach contact $curCparams { incr k label .mazeparams.r${k}0 -text [lindex $contact 0] checkbox .mazeparams.r${k}1 for {set j 2} {$j < 4} {incr j} { entry .mazeparams.r${k}${j} -text [lindex $contact $j] } } } #----------------------------------------------------------------- # Load a magic-style netlist #----------------------------------------------------------------- proc loadnetlist { {netfile {}} } { global Opts if {$netfile == {}} { set netfile [ tk_getOpenFile -filetypes \ {{NET {.net {.net}}} {"All files" {*}}}] } if [catch {open $netfile r} fnet] { set netname [file rootname $netfile] if [catch {open ${netfile}.net r} fnet] { puts stderr "Can't read netlist file $netfile" return 1; } } # Clear out the listbox contents. .mazehelper.unrouted.contents delete 0 end .mazehelper.routed.contents delete 0 end set $Opts(preproutes) 0 # 1st line of the netlist file is throw-away gets $fnet line set currentnet {} while {[gets $fnet line] >= 0} { if {$line == ""} { if {[llength $currentnet] > 0} { .mazehelper.unrouted.contents insert end $currentnet set currentnet {} } } else { lappend currentnet $line } } # Make sure final net gets added. . . if {[llength $currentnet] > 0} { .mazehelper.unrouted.contents insert end $currentnet } .mazehelper.mazemenu.netlist configure -text [file tail $netfile] # Verify all unrouted nets (check if any are already routed) .mazehelper.unrouted.contents select set 0 end verifynet unrouted quiet .mazehelper.unrouted.contents select clear 0 end close $fnet } #----------------------------------------------------------------- # Place a contact on each network endpoint. Aids in preventing # the router from routing over pins by blocking access to the # space over every pin that will be routed to. # # Changed 9/25/06---contact only in subcells. # Changed 9/26/06---use obstruction layer, not contacts #----------------------------------------------------------------- proc obstructendpoints {} { global Opts set Opts(preproutes) 1 box values 0 0 0 0 foreach net [.mazehelper.unrouted.contents get 0 end] { foreach endpoint $net { set layer [goto $endpoint] # Ignore via layers; these are already obstructed for our purposes. if {[string first metal $layer] == 0} { set lnum [string range $layer 5 end] incr lnum set obslayer obsm${lnum} set viasize [tech drc width m${lnum}c] box size ${viasize}i ${viasize}i paint $obslayer } } } } #----------------------------------------------------------------- # Free the obstruction above endpoints for each endpoint in the # current network. #----------------------------------------------------------------- proc freeendpoints {net} { box values 0 0 0 0 foreach endpoint $net { if {[string first / $endpoint] > 0} { set layer [goto $endpoint] if {[string first metal $layer] == 0} { set lnum [string range $layer 5 end] incr lnum set obslayer obsm${lnum} set viasize [tech drc width m${lnum}c] box size ${viasize}i ${viasize}i erase $obslayer } } } } #----------------------------------------------------------------- # Free the obstruction above each pin in the current network. #----------------------------------------------------------------- proc freepinobstructions {net} { box values 0 0 0 0 foreach endpoint $net { if {[string first / $endpoint] <= 0} { set layer [goto $endpoint] if {[string first metal $layer] == 0} { set lnum [string range $layer 5 end] incr lnum set obslayer obsm${lnum} set viasize [tech drc width m${lnum}c] box size ${viasize}i ${viasize}i erase $obslayer } } } } #----------------------------------------------------------------- # Sorting routine for two pins---sort by leftmost pin position. #----------------------------------------------------------------- proc sortpinslr {pina pinb} { goto $pina set xa [lindex [box values] 0] goto $pinb set xb [lindex [box values] 0] if {$xa > $xb} {return 1} else {return -1} } #----------------------------------------------------------------- # Sort a net so that the endpoints are ordered left to right #----------------------------------------------------------------- proc sortnetslr {} { set allnets [.mazehelper.unrouted.contents get 0 end] .mazehelper.unrouted.contents delete 0 end magic::suspendall foreach net $allnets { set netafter [lsort -command sortpinslr $net] .mazehelper.unrouted.contents insert 0 $netafter } magic::resumeall } #----------------------------------------------------------------- # Procedure to find the leftmost point of a net. #----------------------------------------------------------------- proc getnetleft {net} { foreach endpoint $net { set layer [goto $endpoint] set xtest [lindex [box values] 0] if [catch {if {$xtest < $xmin} {set xmin $xtest}}] {set xmin $xtest} } return $xmin } #----------------------------------------------------------------- # Procedure to compare nets according to the number of nodes #----------------------------------------------------------------- proc routecomp {a b} { set alen [llength $a] set blen [llength $b] if {$alen > $blen} { return -1 } elseif {$alen < $blen} { return 1 } else { # Sort by leftmost route. set aleft [getnetleft $a] set bleft [getnetleft $b] if {$aleft > $bleft} {return 1} else {return -1} } } #----------------------------------------------------------------- # Sort unrouted nets from longest to shortest #----------------------------------------------------------------- proc sortnets {} { set listbefore [.mazehelper.unrouted.contents get 0 end] .mazehelper.unrouted.contents delete 0 end magic::suspendall set listafter [lsort -command routecomp $listbefore] foreach net $listafter { .mazehelper.unrouted.contents insert end $net } magic::resumeall } #----------------------------------------------------------------- # Disassemble all networks into 2-point routes #----------------------------------------------------------------- proc disassemble {} { set allnets [.mazehelper.unrouted.contents get 0 end] .mazehelper.unrouted.contents delete 0 end foreach net $allnets { for {set i 1} {$i < [llength $net]} {incr i} { set j $i incr j -1 set newnet [lrange $net $j $i] .mazehelper.unrouted.contents insert end $newnet } } } #----------------------------------------------------------------- # Fence the area around the cell #----------------------------------------------------------------- proc buildfence {} { global Opts pushbox if {$Opts(fenced) == 0} { select top cell box grow c 1i set ibounds [box values] set illx [lindex $ibounds 0] set illy [lindex $ibounds 1] set iurx [lindex $ibounds 2] set iury [lindex $ibounds 3] box grow c 10i set obounds [box values] set ollx [lindex $obounds 0] set olly [lindex $obounds 1] set ourx [lindex $obounds 2] set oury [lindex $obounds 3] box values ${ollx}i ${iury}i ${ourx}i ${oury}i paint fence box values ${ollx}i ${olly}i ${ourx}i ${illy}i paint fence box values ${ollx}i ${olly}i ${illx}i ${oury}i paint fence box values ${iurx}i ${olly}i ${ourx}i ${oury}i paint fence set Opts(fenced) 1 } else { select top cell box grow c 12i erase fence set Opts(fenced) 0 } popbox } #----------------------------------------------------------------- # Load a list of failed routes #----------------------------------------------------------------- proc loadfailed { {netfile {}} } { if {$netfile == {}} { set netfile [ tk_getOpenFile -filetypes \ {{FAILED {.failed {.failed}}} {"All files" {*}}}] } if [catch {open $netfile r} fnet] { set netname [file rootname $netfile] if [catch {open ${netfile}.failed r} fnet] { puts stderr "Can't read file of failed routes $netfile" return 1; } } # Clear out the listbox contents. .mazehelper.unrouted.contents delete 0 end .mazehelper.routed.contents delete 0 end # Read each line into the "unrouted" list. while {[gets $fnet line] >= 0} { .mazehelper.unrouted.contents insert end $line } .mazehelper.mazemenu.netlist configure -text $netfile close $fnet } #----------------------------------------------------------------- # Save the list of failed routes #----------------------------------------------------------------- proc savefailed { {netfile {}} } { set netfile [.mazehelper.mazemenu.netlist cget -text] if {$netfile == {}} { set netfile [ tk_getOpenFile -filetypes \ {{FAILED {.failed {.failed}}} {"All files" {*}}}] } else { set netname [file rootname $netfile] set netname ${netname}.failed } if [catch {open $netfile w} fnet] { set netname [file rootname $netfile] if [catch {open ${netfile}.failed w} fnet] { puts stderr "Can't write file of failed routes $netfile" return 1; } } foreach net [.mazehelper.unrouted.contents get 0 end] { puts $fnet "$net" } close $fnet } #----------------------------------------------------------------- # Get the selected network and maze route it #----------------------------------------------------------------- proc routenet {} { global Opts set drcstate [drc status] drc off # Prepare routes by placing an obstruction layer on each pin # Only do this if we have defined obstruction layers! if {$Opts(preproutes) == 0} { set allLayers [tech layers *] if {[lsearch $allLayers obs*] >= 0} { magic::suspendall obstructendpoints magic::resumeall } } set unroutable {} set sellist [.mazehelper.unrouted.contents curselection] set startidx [lindex $sellist 0] while {[llength $sellist] > 0} { set cidx [lindex $sellist 0] set rlist [.mazehelper.unrouted.contents get $cidx] if {$Opts(preproutes) == 1} {freeendpoints $rlist} for {set i 1} {$i < [llength $rlist]} {incr i} { set j $i incr j -1 set startnet [lindex $rlist $j] set destnet [lindex $rlist $i] set rresult [iroute route -slabel $startnet -dlabel $destnet -timeout 3] # break on any failure if {$rresult != "Route success" && \ $rresult != "Route best before interrupt" && \ $rresult != "Route already routed"} { break } else { set rresult "success" } } .mazehelper.unrouted.contents delete $cidx $cidx if {$rresult == "success"} { .mazehelper.routed.contents insert end $rlist } else { # scramble list; we may have better luck routing in a different order set rfirst [lindex $rlist 0] set rlist [lrange $rlist 1 end] lappend rlist $rfirst lappend unroutable $rlist } set sellist [.mazehelper.unrouted.contents curselection] if {$Opts(preproutes) == 1} {freepinobstructions $rlist} } .mazehelper.unrouted.contents selection set $startidx foreach badnet $unroutable { .mazehelper.unrouted.contents insert $startidx $badnet } if {$drcstate == 1} {drc on} } #----------------------------------------------------------------- # Get the selected network and remove it #----------------------------------------------------------------- proc ripupnet {} { set sellist [.mazehelper.routed.contents curselection] set startidx [lindex $sellist 0] while {[llength $sellist] > 0} { set cidx [lindex $sellist 0] set rlist [.mazehelper.routed.contents get $cidx] set netname [lindex $rlist 0] select clear set layertype [goto $netname] select more box ${layertype},connect ;# chunk select more box ${layertype},connect ;# region select more box ${layertype},connect ;# net delete .mazehelper.routed.contents delete $cidx $cidx .mazehelper.unrouted.contents insert end $rlist set sellist [.mazehelper.routed.contents curselection] } .mazehelper.routed.contents selection set $startidx } #----------------------------------------------------------------- # Get the selected network and verify the route #----------------------------------------------------------------- proc verifynet { {column routed} {infolevel verbose} } { set sellist [.mazehelper.${column}.contents curselection] set startidx [lindex $sellist 0] magic::suspendall while {$sellist != {}} { set cidx [lindex $sellist 0] set errors 0 set rlist [.mazehelper.${column}.contents get $cidx] set netname [lindex $rlist 0] select clear set layertype [goto $netname] if {$layertype == {}} { incr errors } else { select more box ${layertype},connect ;# chunk select more box ${layertype},connect ;# region select more box ${layertype},connect ;# net set sellist [what -list] set sellabels [lindex $sellist 1] set labellist {} foreach label $sellabels { set labtext [lindex $label 0] set labinst [lindex $label 2] if {$labinst == {}} { set labname ${labtext} } else { set labname ${labinst}/${labtext} } lappend labellist $labname } # Backslash substitute brackets prior to using lsearch, or this won't work # on such labels. Hopefully this won't confuse things. . . set newrlist [string map {\[ < \] >} $rlist] set newlabellist [string map {\[ < \] >} $labellist] # Compare labellist to rlist---they are supposed to be the same! foreach entry $newlabellist { if {[lsearch $newrlist $entry] < 0} { if {"$infolevel" == "verbose"} { puts stderr "ERROR: Net entry $entry in layout is not in the netlist!" } incr errors } } foreach entry $newrlist { if {[lsearch $newlabellist $entry] < 0} { if {"$infolevel" == "verbose"} { puts stderr "ERROR: Net entry $entry in netlist is not in the layout!" } incr errors } } if {$errors == 0 && "$infolevel" == "verbose"} {puts stdout "VERIFIED"} } # If column is "routed" and we're not verified, move to "unrouted". # If column is "unrouted" and we're verified, move to "routed". if {"$column" == "routed"} { if {$errors > 0} { .mazehelper.routed.contents delete $cidx $cidx .mazehelper.unrouted.contents insert end $rlist } else { .mazehelper.routed.contents selection clear $cidx incr startidx } } else { if {$errors == 0} { .mazehelper.unrouted.contents delete $cidx $cidx .mazehelper.routed.contents insert end $rlist } else { .mazehelper.unrouted.contents selection clear $cidx incr startidx } } # Get the selection list again set sellist [.mazehelper.${column}.contents curselection] } magic::resumeall .mazehelper.${column}.contents selection set $startidx } #----------------------------------------------------------------- # Reset the maze helper, deleting all routes. #----------------------------------------------------------------- proc resetmazehelper {} { .mazehelper.routed.contents delete 0 end .mazehelper.unrouted.contents delete 0 end } #----------------------------------------------------------------- # Add the "mazehelper" function to the Magic Options #----------------------------------------------------------------- proc addmazehelper {optmenu} { global Opts $optmenu add check -label "Maze Router" -variable Opts(mazeroute) -command \ {if {$Opts(mazeroute) == 0} {destroy .mazehelper} else {genmazehelper}} } #----------------------------------------------------------------- magic-8.0.210/tcltk/strip_reflibs.tcl0000755000175000001440000000251510751423606016160 0ustar timusers#!/usr/local/bin/tclsh # # Strip GDS cell references from magic files. # # This is necessary to make sure that no geometry goes into the output # for files swapped between Cadence and Magic. To import into Magic # from Cadence, "Retain Reference Library" should be FALSE, so that # Magic gets all of the cell contents. Then run this file on the # resulting Magic database directory, and read back into Cadence using # "Retain Reference Library" = TRUE. This will prevent Cadence from # generating local copies of every cell, instead retaining the original # library definition. # # 1. delete lines beginning "string GDS_START" # 2. delete lines beginning "string GDS_END" # 3. do NOT delete "string GDS_FILE" lines. # # Note that if all cells are treated as library references, then the # GDS file itself does not need to exist. foreach fname [glob *.mag] { if [catch {open $fname r} fIn] { puts stdout "Error: can't open file $fname" } else { set fOut [open tmp.mag w] while {[gets $fIn line] >= 0} { if [regexp {^string GDS_} $line] { if [regexp {^string GDS_START} $line ] { } elseif [regexp {^string GDS_END} $line] { } else { puts $fOut $line } } else { puts $fOut $line } } close $fIn close $fOut file rename -force tmp.mag $fname } } magic-8.0.210/tcltk/magicdnull.c0000644000175000001440000000302610751423606015063 0ustar timusers/*----------------------------------------------------------------------*/ /* magicdnull.c */ /* */ /* See comments for "magicexec.c". This has the same function as */ /* magicexec.c, but does not initialize the Tk package. This avoids */ /* bringing up a default window when "magic -dnull -noconsole" is */ /* called, running more efficiently when used in batch mode. */ /*----------------------------------------------------------------------*/ #include #include /*----------------------------------------------------------------------*/ /* Application initiation. This is exactly like the AppInit routine */ /* for "wish", minus the cruft, but with "tcl_rcFileName" set to */ /* "magic.tcl" instead of "~/.wishrc". */ /*----------------------------------------------------------------------*/ int magic_AppInit(interp) Tcl_Interp *interp; { if (Tcl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } /* This is where we replace the home ".tclshrc" file with */ /* magic's startup script. */ Tcl_SetVar(interp, "tcl_rcFileName", TCL_DIR "/magic.tcl", TCL_GLOBAL_ONLY); return TCL_OK; } /*----------------------------------------------------------------------*/ /* The main procedure; replacement for "tclsh". */ /*----------------------------------------------------------------------*/ int main(argc, argv) int argc; char **argv; { Tcl_Main(argc, argv, magic_AppInit); return 0; } /*----------------------------------------------------------------------*/ magic-8.0.210/tcltk/cellmgr.tcl0000644000175000001440000002446711435536243014747 0ustar timusers#------------------------------------------------------ # Script for generating the "cell manager" window. # # Written by Daniel Bearden and Tim Edwards, 2009-2010 #------------------------------------------------------ global Opts if {$::tk_version >= 8.5} { set Opts(cellmgr) 0 magic::tag select "magic::mgrselect %R" magic::tag load "catch {magic::clearstack}; magic::cellmanager" magic::tag getcell "magic::cellmanager" # Callback to the cell manager proc magic::instcallback {command} { global Opts set rpath [ split [.cellmgr.box.view focus] "/"] set rootdef [lindex $rpath 0] set cellpath [lrange $rpath 1 end] set celldef [lrange $rpath end end] if { $Opts(target) == "default" } { set winlist [magic::windownames layout] set winname [lindex $winlist 0] } else { set winname $Opts(target) } if { $cellpath == {} } { switch $command { load {$winname load $rootdef} default { magic::select top cell switch $command { edit {$winname expand; $winname edit} expand {$winname expand} zoom {$winname view} } } } } else { set celluse [join $cellpath "/"] set curpath [$winname windowcaption] set curname [lindex $curpath 2] set curroot [lindex $curpath 0] switch $command { load {$winname load $celldef} default { # Here: need to check first for the select cell belonging to the # current loaded root cell (get the first use). set defpath [list $rootdef] foreach i $cellpath { lappend defpath [magic::instance list celldef $i] } set rootpos [lsearch $defpath $curroot] if {$rootpos < 0} { $winname load $rootdef set rootpos 0 } # set usepath [join [lrange $cellpath $rootpos end] "/"] set usepath [magic::findinstance .cellmgr.box.view \ [.cellmgr.box.view selection]] $winname select cell ${usepath} switch $command { edit {$winname expand; $winname edit} expand {$winname expand toggle} zoom {$winname findbox zoom} } } } } } # The cell manager proc magic::makecellmanager { mgrpath } { toplevel ${mgrpath} wm withdraw ${mgrpath} frame ${mgrpath}.actionbar frame ${mgrpath}.box frame ${mgrpath}.target ttk::treeview ${mgrpath}.box.view -show tree -selectmode browse \ -yscrollcommand "${mgrpath}.box.vert set" \ -xscrollcommand "${mgrpath}.box.vert set" \ -columns 1 scrollbar ${mgrpath}.box.vert -orient vertical -command "${mgrpath}.box.view yview" pack ${mgrpath}.actionbar -side top -fill x pack ${mgrpath}.box.view -side left -fill both -expand true pack ${mgrpath}.box.vert -side right -fill y pack ${mgrpath}.box -side top -fill both -expand true pack ${mgrpath}.target -side top -fill x button ${mgrpath}.actionbar.done -text "Zoom" -command {magic::instcallback zoom} button ${mgrpath}.actionbar.edit -text "Edit" -command {magic::instcallback edit} button ${mgrpath}.actionbar.load -text "Load" -command {magic::instcallback load} button ${mgrpath}.actionbar.expand -text "Expand" -command \ {magic::instcallback expand} pack ${mgrpath}.actionbar.load -side left pack ${mgrpath}.actionbar.edit -side left pack ${mgrpath}.actionbar.expand -side left pack ${mgrpath}.actionbar.done -side right label ${mgrpath}.target.name -text "Target window:" menubutton ${mgrpath}.target.list -text "default" \ -menu ${mgrpath}.target.list.winmenu pack ${mgrpath}.target.name -side left -padx 2 pack ${mgrpath}.target.list -side left .winmenu clone ${mgrpath}.target.list.winmenu #Withdraw the window when the close button is pressed wm protocol ${mgrpath} WM_DELETE_WINDOW "set Opts(cellmgr) 0 ; \ wm withdraw ${mgrpath}" #------------------------------------------------- # Callback when a treeview item is opened #------------------------------------------------- bind .cellmgr <> { set s [.cellmgr.box.view selection] # puts stdout "open $s" foreach i [.cellmgr.box.view children $s] { magic::addlistset $i .cellmgr.box.view item $i -open false } } bind .cellmgr <> { set s [.cellmgr.box.view selection] # puts stdout "close $s" foreach i [.cellmgr.box.view children $s] { foreach j [.cellmgr.box.view children $i] { .cellmgr.box.view delete $j } } } } proc magic::addlistentry {parent child cinst} { if {$child != 0} { set hiername [join [list $parent $child] "/"] # puts stdout "listentry $hiername" if {[.cellmgr.box.view exists $hiername] == 0} { .cellmgr.box.view insert $parent end -id $hiername -text "$child" .cellmgr.box.view set $hiername 0 "$cinst" } } } proc magic::addlistset {item} { set cellname [.cellmgr.box.view item $item -text] set cd [magic::cellname list children $cellname] if {$cd != 0} { foreach i $cd { set inst [lindex [magic::cellname list instances $i] 0] magic::addlistentry $item $i $inst } } } #-------------------------------------------------------------- # Get the hierarchical name of the treeview item corresponding # to the cell view in the window #-------------------------------------------------------------- proc magic::getwindowitem {} { set tl [magic::cellname list window] if {![catch {set editstack}]} { set tl [concat $editstack $tl] } set pl [magic::cellname list parents [lindex $tl 0]] while {$pl != {}} { set tl [concat [lindex $pl 0] $tl] set pl [magic::cellname list parents [lindex $tl 0]] } set newpl "" set parent {} foreach j $tl { set parent $pl set pl "${newpl}$j" if {[.cellmgr.box.view exists $pl] == 0} { .cellmgr.box.view insert $parent end -id $pl -text "$j" set inst [lindex [magic::cellname linst instances $i] 0] .cellmgr.box.view set $pl 0 "$inst" magic::addlistset $pl } .cellmgr.box.view item $pl -open true set newpl "${pl}/" } return $pl } #-------------------------------------------------------------- # The cell manager window main callback function #-------------------------------------------------------------- proc magic::cellmanager {{option "update"}} { global editstack # Check for existence of the manager widget if {[catch {wm state .cellmgr}]} { if {$option == "create"} { magic::makecellmanager .cellmgr } else { return } } elseif { $option == "create"} { return } magic::suspendall # determine the full cell heirarchy set tl [magic::cellname list topcells] foreach i $tl { if {[file extension $i] == ".mag"} { set nameroot [file rootname $i] } else { set nameroot $i } set nameroot [file tail $nameroot] if {[.cellmgr.box.view exists $i] == 0} { .cellmgr.box.view insert {} end -id $i -text $nameroot } magic::addlistset $i .cellmgr.box.view item $i -open false } # Open view to current cell, generating the hierarchy as necessary. # Accept the first hierarchy, unless the push/pop stack has been # used. set pl [magic::getwindowitem] .cellmgr.box.view selection set $pl .cellmgr.box.view see $pl # Generate next level of hierarchy (not open) magic::addlistset $pl .cellmgr.box.view item $pl -open false magic::resumeall } #-------------------------------------------------------------- # Redirect and reformat Tcl output of "select" command #-------------------------------------------------------------- proc magic::mgrselect {{sstr ""}} { # Make sure we have a valid option, and the cell manager exists. if {$sstr == ""} { return } elseif {[catch {wm state .cellmgr}]} { return } set savetag [magic::tag select] magic::tag select {} .cellmgr.box.view selection remove [.cellmgr.box.view selection] # puts stdout "selecting $sstr" if {[llength $sstr] == 5} { # sstr is "Topmost cell in the window" set item [magic::getwindowitem] } else { regsub -all {\[.*\]} $sstr {[^a-z]+} gsrch if {[catch {set item [magic::scantree .cellmgr.box.view $gsrch]}]} { set item "" } } if {$item != ""} { .cellmgr.box.view item $item -open false .cellmgr.box.view selection set $item if {[wm state .cellmgr] == "normal"} { .cellmgr.box.view see $item } if {$sstr != ""} { puts stdout "Selected cell is $item ($sstr)" } } magic::tag select $savetag } #------------------------------------------------------------ # Given an item in the tree view, return a string of slash- # separated instances that can be used by "select cell". # This is effectively the inverse of magic::scantree #------------------------------------------------------------ proc magic::findinstance {tree item} { set start [magic::getwindowitem] set start ${start}/ set pathhead [string first $start $item] if {$pathhead >= 0} { set ss [expr {$pathhead -1}] set sb [expr {[string length $start] + $pathhead}] set pathtail [string range $item 0 $ss][string range $item $sb end] set rpath [ split [join $pathtail] "/"] set cinst "" while {$rpath != {}} { set item ${start}[lindex $rpath 0] set rpath [lrange $rpath 1 end] if {[string length $cinst] == 0} { set cinst [$tree set $item 0] } else { set cinst ${cinst}/[$tree set $item 0] } set start ${item}/ } return $cinst } return {} } #------------------------------------------------------------ # Given an item in the form of a string returned by magic's # "select list" command (list of slash-separated instances), # find the corresponding tree item. #------------------------------------------------------------ proc magic::scantree {tree item} { set start [magic::getwindowitem] set rpath [ split [join $item] "/"] while {$rpath != {}} { set pathhead [lindex $rpath 0] set pathtail [join [lrange $rpath 1 end] "/"] set cellname [magic::instance list celldef $pathhead] set item [join [list $start [join $cellname]] "/"] magic::addlistset $item $tree set $item 0 $pathhead $tree item $item -open true set start $item set item $pathtail set rpath [ split [join $item] "/"] } $tree item $start -open false return $start } } ;# (if Tk version 8.5) magic-8.0.210/tcltk/tkshell.tcl0000755000175000001440000001415110751423606014756 0ustar timusers#!/usr/bin/wish # # A Tcl shell in a text widget # Brent Welch, from "Practical Programming in Tcl and Tk" # package provide tkshell 1.0 # "namespace eval" is needed to force the creation of the namespace, # even if it doesn't actually evaluate anything. Otherwise, the use # of "proc tkshell::..." generates an undefined namespace error. namespace eval tkshell {} #----------------------------------------------- # Create a simple text widget with a Y scrollbar #----------------------------------------------- proc tkshell::YScrolled_Text { f args } { frame $f eval {text $f.text -wrap none \ -yscrollcommand [list $f.yscroll set]} $args scrollbar $f.yscroll -orient vertical \ -command [list $f.text yview] ::grid $f.text $f.yscroll -sticky news ::grid rowconfigure $f 0 -weight 1 ::grid columnconfigure $f 0 -weight 1 return $f.text } #----------------------------------------------- # Add an X scrollbar #----------------------------------------------- proc tkshell::XScrolled_Text { f } { ::set t $f.text $t configure -xscrollcommand [list $f.xscroll set] catch {scrollbar $f.xscroll -orient horizontal \ -command [list $t xview]} ::grid $f.xscroll -sticky news return $t } #----------------------------------------------- # Remove an X scrollbar #----------------------------------------------- proc tkshell::NoXScrolled_Text { f } { ::set t $f.text $t configure -xscrollcommand {} ::grid forget $f.xscroll } #--------------------------------------------------------- # Create the shell window in Tk #--------------------------------------------------------- proc tkshell::MakeEvaluator { {t .eval} {prompt "tcl> "} {prefix ""}} { global eval # Text tags give script output, command errors, command # results, and the prompt a different appearance $t tag configure prompt -foreground brown3 $t tag configure result -foreground purple $t tag configure stderr -foreground red $t tag configure stdout -foreground blue # Insert the prompt and initialize the limit mark ::set eval(prompt) $prompt ::set eval(prefix) $prefix $t insert insert $eval(prompt) prompt $t mark set limit insert $t mark gravity limit left focus $t ::set eval(text) $t # Key bindings that limit input and eval things. The break in # the bindings skips the default Text binding for the event. bind $t {tkshell::EvalTypein ; break} bind $t { if {[%W tag nextrange sel 1.0 end] != ""} { %W delete sel.first sel.last } elseif {[%W compare insert > limit]} { %W delete insert-1c %W see insert } break } bind $t { if [%W compare insert < limit] { %W mark set insert end } } } #----------------------------------------------------------- # Evaluate everything between limit and end as a Tcl command #----------------------------------------------------------- proc tkshell::EvalTypein {} { global eval $eval(text) insert insert \n ::set command [$eval(text) get limit end] if [info complete $command] { $eval(text) mark set limit insert tkshell::Eval $command } } #----------------------------------------------------------- # Echo the command and evaluate it #----------------------------------------------------------- proc tkshell::EvalEcho {command} { global eval $eval(text) mark set insert end $eval(text) insert insert $command\n tkshell::Eval $command } #----------------------------------------------------------- # Evaluate a command and display its result #----------------------------------------------------------- proc tkshell::Eval {command} { global eval $eval(text) mark set insert end ::set fullcommand $eval(prefix) append fullcommand $command if [catch {interp eval $eval(slave) $fullcommand} result] { $eval(text) insert insert $result error } else { $eval(text) insert insert $result result } if {[$eval(text) compare insert != "insert linestart"]} { $eval(text) insert insert \n } $eval(text) insert insert $eval(prompt) prompt $eval(text) see insert $eval(text) mark set limit insert return } #----------------------------------------------------------- # Create and initialize the slave interpreter #----------------------------------------------------------- proc tkshell::SlaveInit {slave} { global eval interp create $slave load {} Tk $slave interp alias $slave reset {} tkshell::ResetAlias $slave interp alias $slave puts {} tkshell::PutsAlias $slave ::set eval(slave) $slave return $slave } #----------------------------------------------------------- # Evaluate commands in the master interpreter #----------------------------------------------------------- proc tkshell::MainInit {} { global eval interp alias {} puts {} tkshell::PutsAlias {} ::set eval(slave) {} } #----------------------------------------------------------- # The "reset" alias deletes the slave and starts a new one #----------------------------------------------------------- proc tkshell::ResetAlias {slave} { interp delete $slave SlaveInit $slave } #-------------------------------------------------------------- # The "puts" alias puts stdout and stderr into the text widget #-------------------------------------------------------------- proc tkshell::PutsAlias {slave args} { if {[llength $args] > 3} { error "invalid arguments" } ::set newline "\n" if {[string match "-nonewline" [lindex $args 0]]} { ::set newline "" ::set args [lreplace $args 0 0] } if {[llength $args] == 1} { ::set chan stdout ::set string [lindex $args 0]$newline } else { ::set chan [lindex $args 0] ::set string [lindex $args 1]$newline } if [regexp (stdout|stderr) $chan] { global eval $eval(text) mark gravity limit right $eval(text) insert limit $string $chan $eval(text) see limit $eval(text) mark gravity limit left } else { puts -nonewline $chan $string } } #-------------------------------------------------------------- # A few lines is all that's needed to run this thing. #-------------------------------------------------------------- # tkshell::YScrolled_Text .eval -width 90 -height 5 # pack .eval -fill both -expand true # tkshell::MakeEvaluator .eval.text "magic> " # tkshell::MainInit #-------------------------------------------------------------- magic-8.0.210/tcltk/texthelper.tcl0000664000175000001440000002274112144741007015473 0ustar timusers# Text helper window proc magic::make_texthelper { mgrpath } { global typedflt typesticky toplevel ${mgrpath} wm withdraw ${mgrpath} frame ${mgrpath}.title frame ${mgrpath}.text frame ${mgrpath}.font frame ${mgrpath}.size frame ${mgrpath}.just frame ${mgrpath}.rotate frame ${mgrpath}.offset frame ${mgrpath}.layer frame ${mgrpath}.buttonbar label ${mgrpath}.title.tlab -text "New label: " label ${mgrpath}.text.tlab -text "Text string: " label ${mgrpath}.font.tlab -text "Font: " label ${mgrpath}.size.tlab -text "Size: " label ${mgrpath}.just.tlab -text "Justification: " label ${mgrpath}.rotate.tlab -text "Rotation: " label ${mgrpath}.offset.tlab -text "Offset from reference: " label ${mgrpath}.layer.tlab -text "Attach to layer: " entry ${mgrpath}.text.tent -background white entry ${mgrpath}.size.tent -background white entry ${mgrpath}.rotate.tent -background white entry ${mgrpath}.offset.tent -background white entry ${mgrpath}.layer.tent -background white set typedflt 1 set typesticky 0 checkbutton ${mgrpath}.layer.btn1 -text "default" -variable typedflt \ -command [subst {if {\$typedflt} {pack forget ${mgrpath}.layer.tent \ } else {pack forget ${mgrpath}.layer.btn2; \ pack ${mgrpath}.layer.tent -side left -fill x -expand true; \ pack ${mgrpath}.layer.btn2 -side left}}] checkbutton ${mgrpath}.layer.btn2 -text "sticky" -variable typesticky menubutton ${mgrpath}.just.btn -text "default" -menu ${mgrpath}.just.btn.menu menubutton ${mgrpath}.font.btn -text "default" -menu ${mgrpath}.font.btn.menu button ${mgrpath}.buttonbar.cancel -text "Cancel" -command "wm withdraw ${mgrpath}" button ${mgrpath}.buttonbar.apply -text "Apply" pack ${mgrpath}.title.tlab pack ${mgrpath}.text.tlab -side left pack ${mgrpath}.text.tent -side right -fill x -expand true pack ${mgrpath}.font.tlab -side left pack ${mgrpath}.font.btn -side left pack ${mgrpath}.size.tlab -side left pack ${mgrpath}.size.tent -side right -fill x -expand true pack ${mgrpath}.just.tlab -side left pack ${mgrpath}.just.btn -side left pack ${mgrpath}.rotate.tlab -side left pack ${mgrpath}.rotate.tent -side right -fill x -expand true pack ${mgrpath}.offset.tlab -side left pack ${mgrpath}.offset.tent -side right -fill x -expand true pack ${mgrpath}.layer.tlab -side left pack ${mgrpath}.layer.btn1 -side left pack ${mgrpath}.layer.btn2 -side left pack ${mgrpath}.buttonbar.apply -side left pack ${mgrpath}.buttonbar.cancel -side right pack ${mgrpath}.title -side top pack ${mgrpath}.text -side top -anchor w -expand true pack ${mgrpath}.font -side top -anchor w pack ${mgrpath}.size -side top -anchor w -expand true pack ${mgrpath}.just -side top -anchor w pack ${mgrpath}.rotate -side top -anchor w -expand true pack ${mgrpath}.offset -side top -anchor w -expand true pack ${mgrpath}.layer -side top -anchor w -expand true pack ${mgrpath}.buttonbar -side bottom -fill x -expand true # Create menus for Font and Justification records menu ${mgrpath}.just.btn.menu -tearoff 0 menu ${mgrpath}.font.btn.menu -tearoff 0 ${mgrpath}.just.btn.menu add command -label "default" -command \ "${mgrpath}.just.btn config -text default" ${mgrpath}.just.btn.menu add command -label "N" -command \ "${mgrpath}.just.btn config -text N" ${mgrpath}.just.btn.menu add command -label "NE" -command \ "${mgrpath}.just.btn config -text NE" ${mgrpath}.just.btn.menu add command -label "E" -command \ "${mgrpath}.just.btn config -text E" ${mgrpath}.just.btn.menu add command -label "SE" -command \ "${mgrpath}.just.btn config -text SE" ${mgrpath}.just.btn.menu add command -label "S" -command \ "${mgrpath}.just.btn config -text S" ${mgrpath}.just.btn.menu add command -label "SW" -command \ "${mgrpath}.just.btn config -text SW" ${mgrpath}.just.btn.menu add command -label "W" -command \ "${mgrpath}.just.btn config -text W" ${mgrpath}.just.btn.menu add command -label "NW" -command \ "${mgrpath}.just.btn config -text NW" ${mgrpath}.just.btn.menu add command -label "center" -command \ "${mgrpath}.just.btn config -text center" set flist [magic::setlabel fontlist] ${mgrpath}.font.btn.menu add command -label default -command \ "${mgrpath}.font.btn config -text default" foreach i $flist { ${mgrpath}.font.btn.menu add command -label $i -command \ "${mgrpath}.font.btn config -text $i" } # Set up tag callbacks magic::tag select "[magic::tag select]; magic::update_texthelper" } proc magic::analyze_labels {} { global typedflt typesticky set tlist [lsort -uniq [setlabel text]] set jlist [lsort -uniq [setlabel justify]] set flist [lsort -uniq [setlabel font]] set slist [lsort -uniq [setlabel size]] set rlist [lsort -uniq [setlabel rotate]] set olist [lsort -uniq [setlabel offset]] set llist [lsort -uniq [setlabel layer]] set klist [lsort -uniq [setlabel sticky]] .texthelper.text.tent delete 0 end if {[llength $tlist] == 1} { .texthelper.text.tent insert 0 $tlist } if {[llength $jlist] == 1} { set jbtn [string map {NORTH N WEST W SOUTH S EAST E CENTER center} $jlist] .texthelper.just.btn.menu invoke $jbtn } else { .texthelper.just.btn config -text "" } if {[llength $flist] == 1} { .texthelper.font.btn.menu invoke $flist } else { .texthelper.font.btn config -text "" } .texthelper.size.tent delete 0 end if {[llength $slist] == 1} { .texthelper.size.tent insert 0 $slist } .texthelper.offset.tent delete 0 end if {[llength $olist] == 1} { .texthelper.offset.tent insert 0 [join $olist] } .texthelper.rotate.tent delete 0 end if {[llength $rlist] == 1} { .texthelper.rotate.tent insert 0 $rlist } .texthelper.layer.tent delete 0 end if {[llength $llist] == 1} { .texthelper.layer.tent insert 0 $llist } if {[llength $klist] == 1} { set typesticky $klist } } proc magic::change_label {} { global typedflt typesticky set ltext [.texthelper.text.tent get] set lfont [.texthelper.font.btn cget -text] set lsize [.texthelper.size.tent get] set lrot [.texthelper.rotate.tent get] set loff [.texthelper.offset.tent get] set ljust [.texthelper.just.btn cget -text] set ltype [.texthelper.layer.tent get] if {$ltext != ""} { setlabel text $ltext } if {$lfont != ""} { if {$lfont == "default"} { setlabel font -1 } else { setlabel font $lfont } } if {$ljust != ""} { if {$ljust == "default"} { setlabel justify -1 } else { setlabel justify $ljust } } if {$lsize != ""} { setlabel size ${lsize}i } if {$loff != ""} { set oldsnap [snap list] snap internal setlabel offset [join $loff] snap $oldsnap } if {$lrot != ""} { setlabel rotate $lrot } if {$ltype != ""} { setlabel layer $ltype } setlabel sticky $typesticky } proc magic::make_new_label {} { global typedflt typesticky set ltext [.texthelper.text.tent get] set lfont [.texthelper.font.btn cget -text] set lsize [.texthelper.size.tent get] set lrot [.texthelper.rotate.tent get] set loff [.texthelper.offset.tent get] set ljust [.texthelper.just.btn cget -text] set ltype [.texthelper.layer.tent get] if {$ltext == ""} return ;# don't generate null label strings! if {$lfont == {} || $lfont == "default"} { label $ltext $ljust return } if {$lsize == "0" || $lsize == ""} {set lsize 1} if {$lrot == ""} {set lrot 0} if {$loff == ""} {set loff "0 0"} if {$typedflt == 1 || $ltype == ""} { if {$ljust == "default"} { label $ltext $lfont $lsize $lrot [join $loff] } else { label $ltext $lfont $lsize $lrot [join $loff] $ljust } } else { if {$typesticky == 1} {set ltype "-$ltype"} if {$ljust == "default"} { label $ltext $lfont $lsize $lrot [join $loff] center $ltype } else { label $ltext $lfont $lsize $lrot [join $loff] $ljust $ltype } } # puts stdout "label $ltext $lfont $lsize $lrot $loff $ljust" } #-------------------------------------------------------------------- # Update and redisplay the text helper #-------------------------------------------------------------------- proc magic::update_texthelper {} { global CAD_ROOT if {[catch {wm state .texthelper}]} { magic::make_texthelper .texthelper } # Update: Determine if a label has been selected or not. If so, # analyze the label list to determine which properties are common # to all the selected labels set slist [lindex [what -list] 1] if {$slist == {}} { .texthelper.title.tlab configure -text "New label: " .texthelper.text.tent delete 0 end .texthelper.font.btn.menu invoke 0 .texthelper.just.btn.menu invoke 0 .texthelper.size.tent delete 0 end .texthelper.size.tent insert 0 "1" .texthelper.rotate.tent delete 0 end .texthelper.rotate.tent insert 0 "0" .texthelper.offset.tent delete 0 end .texthelper.offset.tent insert 0 "0 1" .texthelper.buttonbar.apply configure -command magic::make_new_label } else { if {[llength $slist] == 1} { .texthelper.title.tlab configure -text "Selected label: " } else { .texthelper.title.tlab configure -text "Selected labels: " } magic::analyze_labels .texthelper.buttonbar.apply configure -command magic::change_label } } magic-8.0.210/tcltk/ext2spice.sh0000664000175000001440000000067312500371713015044 0ustar timusers#!/bin/sh # # Standalone script for ext2spice, for Tcl-based magic 8.0 # # Parse arguments. "--" separates arguments to magic # from arguments to ext2spice. # mgargs="" esargs="" for i in $@; do case $i in --) mgargs="$esargs" esargs="" ;; *) esargs="$esargs $i" ;; esac done # eval /home/tim/cad/lib/magic/tcl/magicdnull -dnull -noconsole -nowrapper $mgargs <, Jan Nijtmans ## Crimmins , Wart ## ## Copyright 1995-2001 Jeffrey Hobbs ## Initiated: Thu Aug 17 15:36:47 PDT 1995 ## ## jeff.hobbs@acm.org, jeff@hobbs.org ## ## source standard_disclaimer.tcl ## source bourbon_ware.tcl ## # Proxy support for retrieving the current version of Tkcon. # # Mon Jun 25 12:19:56 2001 - Pat Thoyts # # In your tkcon.cfg or .tkconrc file put your proxy details into the # `proxy' member of the `PRIV' array. e.g.: # # set ::tkcon::PRIV(proxy) wwwproxy:8080 # # If you want to be prompted for proxy authentication details (eg for # an NT proxy server) make the second element of this variable non-nil - eg: # # set ::tkcon::PRIV(proxy) {wwwproxy:8080 1} # # Or you can set the above variable from within tkcon by calling # # tkcon master set ::tkcon:PRIV(proxy) wwwproxy:8080 # if {$tcl_version < 8.0} { return -code error "tkcon requires at least Tcl/Tk8" } else { # Prevent breaking on version 8.5.2 # package require -exact Tk $tcl_version package require Tk $tcl_version } catch {package require bogus-package-name} foreach pkg [info loaded {}] { set file [lindex $pkg 0] set name [lindex $pkg 1] if {![catch {set version [package require $name]}]} { if {[string match {} [package ifneeded $name $version]]} { package ifneeded $name $version [list load $file $name] } } } catch {unset pkg file name version} # Tk 8.4 makes previously exposed stuff private. # FIX: Update tkcon to not rely on the private Tk code. # if {![llength [info globals tkPriv]]} { ::tk::unsupported::ExposePrivateVariable tkPriv } foreach cmd {SetCursor UpDownLine Transpose ScrollPages} { if {![llength [info commands tkText$cmd]]} { ::tk::unsupported::ExposePrivateCommand tkText$cmd } } # Initialize the ::tkcon namespace # namespace eval ::tkcon { # The OPT variable is an array containing most of the optional # info to configure. COLOR has the color data. variable OPT variable COLOR # PRIV is used for internal data that only tkcon should fiddle with. variable PRIV set PRIV(WWW) [info exists embed_args] } ## ::tkcon::Init - inits tkcon # # Calls: ::tkcon::InitUI # Outputs: errors found in tkcon's resource file ## proc ::tkcon::Init {} { variable OPT variable COLOR variable PRIV global tcl_platform env argc argv tcl_interactive errorInfo if {![info exists argv]} { set argv {} set argc 0 } set tcl_interactive 1 if {[info exists PRIV(name)]} { set title $PRIV(name) } else { MainInit # some main initialization occurs later in this proc, # to go after the UI init set MainInit 1 set title Main } ## ## When setting up all the default values, we always check for ## prior existence. This allows users who embed tkcon to modify ## the initial state before tkcon initializes itself. ## # bg == {} will get bg color from the main toplevel (in InitUI) foreach {key default} { bg {} blink \#FFFF00 cursor \#000000 disabled \#4D4D4D proc \#008800 var \#FFC0D0 prompt \#8F4433 stdin \#000000 stdout \#0000FF stderr \#FF0000 } { if {![info exists COLOR($key)]} { set COLOR($key) $default } } foreach {key default} { autoload {} blinktime 500 blinkrange 1 buffer 512 calcmode 0 cols 80 debugPrompt {(level \#$level) debug [history nextid] > } dead {} expandorder {Pathname Variable Procname} font {} history 48 hoterrors 1 library {} lightbrace 1 lightcmd 1 maineval {} maxmenu 15 nontcl 0 prompt1 {ignore this, it's set below} rows 20 scrollypos right showmenu 1 showmultiple 1 showstatusbar 0 slaveeval {} slaveexit close subhistory 1 gc-delay 60000 gets {congets} usehistory 1 exec slave } { if {![info exists OPT($key)]} { set OPT($key) $default } } foreach {key default} { app {} appname {} apptype slave namesp :: cmd {} cmdbuf {} cmdsave {} event 1 deadapp 0 deadsock 0 debugging 0 displayWin . histid 0 find {} find,case 0 find,reg 0 errorInfo {} showOnStartup 1 slavealias { edit more less tkcon } slaveprocs { alias clear dir dump echo idebug lremove tkcon_puts tkcon_gets observe observe_var unalias which what } version 2.3 RCS {RCS: @(#) $Id: tkcon.tcl,v 1.2 2008/09/03 17:32:42 tim Exp $} HEADURL {http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/tkcon/tkcon/tkcon.tcl?rev=HEAD} docs "http://tkcon.sourceforge.net/" email {jeff@hobbs.org} root . } { if {![info exists PRIV($key)]} { set PRIV($key) $default } } ## NOTES FOR STAYING IN PRIMARY INTERPRETER: ## ## If you set ::tkcon::OPT(exec) to {}, then instead of a multiple ## interp model, you get tkcon operating in the main interp by default. ## This can be useful when attaching to programs that like to operate ## in the main interpter (for example, based on special wish'es). ## You can set this from the command line with -exec "" ## A side effect is that all tkcon command line args will be used ## by the first console only. #set OPT(exec) {} if {$PRIV(WWW)} { lappend PRIV(slavealias) history set OPT(prompt1) {[history nextid] % } } else { lappend PRIV(slaveprocs) tcl_unknown unknown set OPT(prompt1) {([file tail [pwd]]) [history nextid] % } } ## If we are using the default '.' toplevel, and there appear to be ## children of '.', then make sure we use a disassociated toplevel. if {$PRIV(root) == "." && [llength [winfo children .]]} { set PRIV(root) .tkcon } ## Do platform specific configuration here, other than defaults ### Use tkcon.cfg filename for resource filename on non-unix systems ### Determine what directory the resource file should be in switch $tcl_platform(platform) { macintosh { if {![interp issafe]} {cd [file dirname [info script]]} set envHome PREF_FOLDER set rcfile tkcon.cfg set histfile tkcon.hst catch {console hide} } windows { set envHome HOME set rcfile tkcon.cfg set histfile tkcon.hst } unix { set envHome HOME set rcfile .tkconrc set histfile .tkcon_history } } if {[info exists env($envHome)]} { if {![info exists PRIV(rcfile)]} { set PRIV(rcfile) [file join $env($envHome) $rcfile] } if {![info exists PRIV(histfile)]} { set PRIV(histfile) [file join $env($envHome) $histfile] } } ## Handle command line arguments before sourcing resource file to ## find if resource file is being specified (let other args pass). if {[set i [lsearch -exact $argv -rcfile]] != -1} { set PRIV(rcfile) [lindex $argv [incr i]] } if {!$PRIV(WWW) && [file exists $PRIV(rcfile)]} { set code [catch {uplevel \#0 [list source $PRIV(rcfile)]} err] } if {[info exists env(TK_CON_LIBRARY)]} { lappend ::auto_path $env(TK_CON_LIBRARY) } else { lappend ::auto_path $OPT(library) } if {![info exists ::tcl_pkgPath]} { set dir [file join [file dirname [info nameofexec]] lib] if {[llength [info commands @scope]]} { set dir [file join $dir itcl] } catch {source [file join $dir pkgIndex.tcl]} } catch {tclPkgUnknown dummy-name dummy-version} ## Handle rest of command line arguments after sourcing resource file ## and slave is created, but before initializing UI or setting packages. set slaveargs {} set slavefiles {} set truth {^(1|yes|true|on)$} for {set i 0} {$i < $argc} {incr i} { set arg [lindex $argv $i] if {[string match {-*} $arg]} { set val [lindex $argv [incr i]] ## Handle arg based options switch -glob -- $arg { -- - -argv { set argv [concat -- [lrange $argv $i end]] set argc [llength $argv] break } -color-* { set COLOR([string range $arg 7 end]) $val } -exec { set OPT(exec) $val } -main - -e - -eval { append OPT(maineval) \n$val\n } -package - -load { lappend OPT(autoload) $val } -slave { append OPT(slaveeval) \n$val\n } -nontcl { set OPT(nontcl) [regexp -nocase $truth $val]} -root { set PRIV(root) $val } -font { set OPT(font) $val } -rcfile {} default { lappend slaveargs $arg; incr i -1 } } } elseif {[file isfile $arg]} { lappend slavefiles $arg } else { lappend slaveargs $arg } } ## Create slave executable if {[string compare {} $OPT(exec)]} { uplevel \#0 ::tkcon::InitSlave $OPT(exec) $slaveargs } else { set argc [llength $slaveargs] set argv $slaveargs uplevel \#0 $slaveargs } ## Attach to the slave, EvalAttached will then be effective Attach $PRIV(appname) $PRIV(apptype) InitUI $title ## swap puts and gets with the tkcon versions to make sure all ## input and output is handled by tkcon if {![catch {rename ::puts ::tkcon_tcl_puts}]} { interp alias {} ::puts {} ::tkcon_puts } if {($OPT(gets) != "") && ![catch {rename ::gets ::tkcon_tcl_gets}]} { interp alias {} ::gets {} ::tkcon_gets } EvalSlave history keep $OPT(history) if {[info exists MainInit]} { # Source history file only for the main console, as all slave # consoles will adopt from the main's history, but still # keep separate histories if {!$PRIV(WWW) && $OPT(usehistory) && [file exists $PRIV(histfile)]} { puts -nonewline "loading history file ... " # The history file is built to be loaded in and # understood by tkcon if {[catch {uplevel \#0 [list source $PRIV(histfile)]} herr]} { puts stderr "error:\n$herr" append PRIV(errorInfo) $errorInfo\n } set PRIV(event) [EvalSlave history nextid] puts "[expr {$PRIV(event)-1}] events added" } } ## Autoload specified packages in slave set pkgs [EvalSlave package names] foreach pkg $OPT(autoload) { puts -nonewline "autoloading package \"$pkg\" ... " if {[lsearch -exact $pkgs $pkg]>-1} { if {[catch {EvalSlave package require [list $pkg]} pkgerr]} { puts stderr "error:\n$pkgerr" append PRIV(errorInfo) $errorInfo\n } else { puts "OK" } } else { puts stderr "error: package does not exist" } } ## Evaluate maineval in slave if {[string compare {} $OPT(maineval)] && \ [catch {uplevel \#0 $OPT(maineval)} merr]} { puts stderr "error in eval:\n$merr" append PRIV(errorInfo) $errorInfo\n } ## Source extra command line argument files into slave executable foreach fn $slavefiles { puts -nonewline "slave sourcing \"$fn\" ... " if {[catch {EvalSlave source [list $fn]} fnerr]} { puts stderr "error:\n$fnerr" append PRIV(errorInfo) $errorInfo\n } else { puts "OK" } } ## Evaluate slaveeval in slave if {[string compare {} $OPT(slaveeval)] && \ [catch {interp eval $OPT(exec) $OPT(slaveeval)} serr]} { puts stderr "error in slave eval:\n$serr" append PRIV(errorInfo) $errorInfo\n } ## Output any error/output that may have been returned from rcfile if {[info exists code] && $code && [string compare {} $err]} { puts stderr "error in $PRIV(rcfile):\n$err" append PRIV(errorInfo) $errorInfo } if {[string compare {} $OPT(exec)]} { StateCheckpoint [concat $PRIV(name) $OPT(exec)] slave } StateCheckpoint $PRIV(name) slave Prompt "$title console display active (Tcl$::tcl_patchLevel / Tk$::tk_patchLevel)\n" } ## ::tkcon::InitSlave - inits the slave by placing key procs and aliases in it ## It's arg[cv] are based on passed in options, while argv0 is the same as ## the master. tcl_interactive is the same as the master as well. # ARGS: slave - name of slave to init. If it does not exist, it is created. # args - args to pass to a slave as argv/argc ## proc ::tkcon::InitSlave {slave args} { variable OPT variable COLOR variable PRIV global argv0 tcl_interactive tcl_library env auto_path if {[string match {} $slave]} { return -code error "Don't init the master interpreter, goofball" } if {![interp exists $slave]} { interp create $slave } if {[interp eval $slave info command source] == ""} { $slave alias source SafeSource $slave $slave alias load SafeLoad $slave $slave alias open SafeOpen $slave $slave alias file file interp eval $slave [dump var -nocomplain tcl_library auto_path env] interp eval $slave { catch {source [file join $tcl_library init.tcl]} } interp eval $slave { catch unknown } } $slave alias exit exit interp eval $slave { # Do package require before changing around puts/gets catch {package require bogus-package-name} catch {rename ::puts ::tkcon_tcl_puts} } foreach cmd $PRIV(slaveprocs) { $slave eval [dump proc $cmd] } foreach cmd $PRIV(slavealias) { $slave alias $cmd $cmd } interp alias $slave ::ls $slave ::dir -full interp alias $slave ::puts $slave ::tkcon_puts if {$OPT(gets) != ""} { interp eval $slave { catch {rename ::gets ::tkcon_tcl_gets} } interp alias $slave ::gets $slave ::tkcon_gets } if {[info exists argv0]} {interp eval $slave [list set argv0 $argv0]} interp eval $slave set tcl_interactive $tcl_interactive \; \ set auto_path [list $auto_path] \; \ set argc [llength $args] \; \ set argv [list $args] \; { if {![llength [info command bgerror]]} { proc bgerror err { global errorInfo set body [info body bgerror] rename ::bgerror {} if {[auto_load bgerror]} { return [bgerror $err] } proc bgerror err $body tkcon bgerror $err $errorInfo } } } foreach pkg [lremove [package names] Tcl] { foreach v [package versions $pkg] { interp eval $slave [list package ifneeded $pkg $v \ [package ifneeded $pkg $v]] } } } ## ::tkcon::InitInterp - inits an interpreter by placing key ## procs and aliases in it. # ARGS: name - interp name # type - interp type (slave|interp) ## proc ::tkcon::InitInterp {name type} { variable OPT variable PRIV ## Don't allow messing up a local master interpreter if {[string match namespace $type] || ([string match slave $type] && \ [regexp {^([Mm]ain|Slave[0-9]+)$} $name])} return set old [Attach] set oldname $PRIV(namesp) catch { Attach $name $type EvalAttached { catch {rename ::puts ::tkcon_tcl_puts} } foreach cmd $PRIV(slaveprocs) { EvalAttached [dump proc $cmd] } switch -exact $type { slave { foreach cmd $PRIV(slavealias) { Main interp alias $name ::$cmd $PRIV(name) ::$cmd } } interp { set thistkcon [tk appname] foreach cmd $PRIV(slavealias) { EvalAttached "proc $cmd args { send [list $thistkcon] $cmd \$args }" } } } ## Catch in case it's a 7.4 (no 'interp alias') interp EvalAttached { catch {interp alias {} ::ls {} ::dir -full} if {[catch {interp alias {} ::puts {} ::tkcon_puts}]} { catch {rename ::tkcon_puts ::puts} } } if {$OPT(gets) != ""} { EvalAttached { catch {rename ::gets ::tkcon_tcl_gets} if {[catch {interp alias {} ::gets {} ::tkcon_gets}]} { catch {rename ::tkcon_gets ::gets} } } } return } {err} eval Attach $old AttachNamespace $oldname if {[string compare {} $err]} { return -code error $err } } ## ::tkcon::InitUI - inits UI portion (console) of tkcon ## Creates all elements of the console window and sets up the text tags # ARGS: root - widget pathname of the tkcon console root # title - title for the console root and main (.) windows # Calls: ::tkcon::InitMenus, ::tkcon::Prompt ## proc ::tkcon::InitUI {title} { variable OPT variable PRIV variable COLOR set root $PRIV(root) if {[string match . $root]} { set w {} } else { set w [toplevel $root] } if {!$PRIV(WWW)} { wm withdraw $root wm protocol $root WM_DELETE_WINDOW exit } set PRIV(base) $w ## Text Console set PRIV(console) [set con $w.text] text $con -wrap char -yscrollcommand [list $w.sy set] \ -foreground $COLOR(stdin) \ -insertbackground $COLOR(cursor) $con mark set output 1.0 $con mark set limit 1.0 if {[string compare {} $COLOR(bg)]} { $con configure -background $COLOR(bg) } set COLOR(bg) [$con cget -background] if {[string compare {} $OPT(font)]} { ## Set user-requested font, if any $con configure -font $OPT(font) } else { ## otherwise make sure the font is monospace set font [$con cget -font] if {![font metrics $font -fixed]} { font create tkconfixed -family Courier -size 12 $con configure -font tkconfixed } } set OPT(font) [$con cget -font] if {!$PRIV(WWW)} { $con configure -setgrid 1 -width $OPT(cols) -height $OPT(rows) } bindtags $con [list $con TkConsole TkConsolePost $root all] ## Menus ## catch against use in plugin if {[catch {menu $w.mbar} PRIV(menubar)]} { set PRIV(menubar) [frame $w.mbar -relief raised -bd 1] } ## Scrollbar set PRIV(scrolly) [scrollbar $w.sy -takefocus 0 -bd 1 \ -command [list $con yview]] InitMenus $PRIV(menubar) $title Bindings if {$OPT(showmenu)} { $root configure -menu $PRIV(menubar) } pack $w.sy -side $OPT(scrollypos) -fill y pack $con -fill both -expand 1 set PRIV(statusbar) [set sbar [frame $w.sbar]] label $sbar.attach -relief sunken -bd 1 -anchor w \ -textvariable ::tkcon::PRIV(StatusAttach) label $sbar.mode -relief sunken -bd 1 -anchor w \ -textvariable ::tkcon::PRIV(StatusMode) label $sbar.cursor -relief sunken -bd 1 -anchor w -width 6 \ -textvariable ::tkcon::PRIV(StatusCursor) grid $sbar.attach $sbar.mode $sbar.cursor -sticky news -padx 1 grid columnconfigure $sbar 0 -weight 1 grid columnconfigure $sbar 1 -weight 1 grid columnconfigure $sbar 2 -weight 0 if {$OPT(showstatusbar)} { pack $sbar -side bottom -fill x -before $::tkcon::PRIV(scrolly) } foreach col {prompt stdout stderr stdin proc} { $con tag configure $col -foreground $COLOR($col) } $con tag configure var -background $COLOR(var) $con tag raise sel $con tag configure blink -background $COLOR(blink) $con tag configure find -background $COLOR(blink) if {!$PRIV(WWW)} { wm title $root "tkcon $PRIV(version) $title" bind $con { scan [wm geometry [winfo toplevel %W]] "%%dx%%d" \ ::tkcon::OPT(cols) ::tkcon::OPT(rows) } if {$PRIV(showOnStartup)} { wm deiconify $root } } if {$PRIV(showOnStartup)} { focus -force $PRIV(console) } if {$OPT(gc-delay)} { after $OPT(gc-delay) ::tkcon::GarbageCollect } } ## ::tkcon::GarbageCollect - do various cleanup ops periodically to our setup ## proc ::tkcon::GarbageCollect {} { variable OPT variable PRIV set w $PRIV(console) ## Remove error tags that no longer span anything ## Make sure the tag pattern matches the unique tag prefix foreach tag [$w tag names] { if {[string match _tag* $tag] && ![llength [$w tag ranges $tag]]} { $w tag delete $tag } } if {$OPT(gc-delay)} { after $OPT(gc-delay) ::tkcon::GarbageCollect } } ## ::tkcon::Eval - evaluates commands input into console window ## This is the first stage of the evaluating commands in the console. ## They need to be broken up into consituent commands (by ::tkcon::CmdSep) in ## case a multiple commands were pasted in, then each is eval'ed (by ## ::tkcon::EvalCmd) in turn. Any uncompleted command will not be eval'ed. # ARGS: w - console text widget # Calls: ::tkcon::CmdGet, ::tkcon::CmdSep, ::tkcon::EvalCmd ## proc ::tkcon::Eval {w} { set incomplete [CmdSep [CmdGet $w] cmds last] $w mark set insert end-1c $w insert end \n if {[llength $cmds]} { foreach c $cmds {EvalCmd $w $c} $w insert insert $last {} } elseif {!$incomplete} { EvalCmd $w $last } $w see insert } ## ::tkcon::EvalCmd - evaluates a single command, adding it to history # ARGS: w - console text widget # cmd - the command to evaluate # Calls: ::tkcon::Prompt # Outputs: result of command to stdout (or stderr if error occured) # Returns: next event number ## proc ::tkcon::EvalCmd {w cmd} { variable OPT variable PRIV $w mark set output end if {[string compare {} $cmd]} { set code 0 if {$OPT(subhistory)} { set ev [EvalSlave history nextid] incr ev -1 if {[string match !! $cmd]} { set code [catch {EvalSlave history event $ev} cmd] if {!$code} {$w insert output $cmd\n stdin} } elseif {[regexp {^!(.+)$} $cmd dummy event]} { ## Check last event because history event is broken set code [catch {EvalSlave history event $ev} cmd] if {!$code && ![string match ${event}* $cmd]} { set code [catch {EvalSlave history event $event} cmd] } if {!$code} {$w insert output $cmd\n stdin} } elseif {[regexp {^\^([^^]*)\^([^^]*)\^?$} $cmd dummy old new]} { set code [catch {EvalSlave history event $ev} cmd] if {!$code} { regsub -all -- $old $cmd $new cmd $w insert output $cmd\n stdin } } elseif {$OPT(calcmode) && ![catch {expr $cmd} err]} { EvalSlave history add $cmd set cmd $err set code -1 } } if {$code} { $w insert output $cmd\n stderr } else { ## We are about to evaluate the command, so move the limit ## mark to ensure that further s don't cause double ## evaluation of this command - for cases like the command ## has a vwait or something in it $w mark set limit end if {$OPT(nontcl) && [string match interp $PRIV(apptype)]} { set code [catch {EvalSend $cmd} res] if {$code == 1} { set PRIV(errorInfo) "Non-Tcl errorInfo not available" } } elseif {[string match socket $PRIV(apptype)]} { set code [catch {EvalSocket $cmd} res] if {$code == 1} { set PRIV(errorInfo) "Socket-based errorInfo not available" } } else { set code [catch {EvalAttached $cmd} res] if {$code == 1} { if {[catch {EvalAttached [list set errorInfo]} err]} { set PRIV(errorInfo) "Error getting errorInfo:\n$err" } else { set PRIV(errorInfo) $err } } } EvalSlave history add $cmd if {$code} { if {$OPT(hoterrors)} { set tag [UniqueTag $w] $w insert output $res [list stderr $tag] \n stderr $w tag bind $tag \ [list $w tag configure $tag -under 1] $w tag bind $tag \ [list $w tag configure $tag -under 0] $w tag bind $tag \ "if {!\[info exists tkPriv(mouseMoved)\] || !\$tkPriv(mouseMoved)} \ {[list edit -attach [Attach] -type error -- $PRIV(errorInfo)]}" } else { $w insert output $res\n stderr } } elseif {[string compare {} $res]} { $w insert output $res\n stdout } } } Prompt set PRIV(event) [EvalSlave history nextid] } ## ::tkcon::EvalSlave - evaluates the args in the associated slave ## args should be passed to this procedure like they would be at ## the command line (not like to 'eval'). # ARGS: args - the command and args to evaluate ## proc ::tkcon::EvalSlave args { interp eval $::tkcon::OPT(exec) $args } ## ::tkcon::EvalOther - evaluate a command in a foreign interp or slave ## without attaching to it. No check for existence is made. # ARGS: app - interp/slave name # type - (slave|interp) ## proc ::tkcon::EvalOther { app type args } { if {[string compare slave $type]==0} { return [Slave $app $args] } else { return [uplevel 1 send [list $app] $args] } } ## ::tkcon::EvalSend - sends the args to the attached interpreter ## Varies from 'send' by determining whether attachment is dead ## when an error is received # ARGS: cmd - the command string to send across # Returns: the result of the command ## proc ::tkcon::EvalSend cmd { variable OPT variable PRIV if {$PRIV(deadapp)} { if {[lsearch -exact [winfo interps] $PRIV(app)]<0} { return } else { set PRIV(appname) [string range $PRIV(appname) 5 end] set PRIV(deadapp) 0 Prompt "\n\"$PRIV(app)\" alive\n" [CmdGet $PRIV(console)] } } set code [catch {send -displayof $PRIV(displayWin) $PRIV(app) $cmd} result] if {$code && [lsearch -exact [winfo interps] $PRIV(app)]<0} { ## Interpreter disappeared if {[string compare leave $OPT(dead)] && \ ([string match ignore $OPT(dead)] || \ [tk_dialog $PRIV(base).dead "Dead Attachment" \ "\"$PRIV(app)\" appears to have died.\ \nReturn to primary slave interpreter?" questhead 0 OK No])} { set PRIV(appname) "DEAD:$PRIV(appname)" set PRIV(deadapp) 1 } else { set err "Attached Tk interpreter \"$PRIV(app)\" died." Attach {} set PRIV(deadapp) 0 EvalSlave set errorInfo $err } Prompt \n [CmdGet $PRIV(console)] } return -code $code $result } ## ::tkcon::EvalSocket - sends the string to an interpreter attached via ## a tcp/ip socket ## ## In the EvalSocket case, ::tkcon::PRIV(app) is the socket id ## ## Must determine whether socket is dead when an error is received # ARGS: cmd - the data string to send across # Returns: the result of the command ## proc ::tkcon::EvalSocket cmd { variable OPT variable PRIV global tcl_version if {$PRIV(deadapp)} { if {![info exists PRIV(app)] || \ [catch {eof $PRIV(app)} eof] || $eof} { return } else { set PRIV(appname) [string range $PRIV(appname) 5 end] set PRIV(deadapp) 0 Prompt "\n\"$PRIV(app)\" alive\n" [CmdGet $PRIV(console)] } } # Sockets get \'s interpreted, so that users can # send things like \n\r or explicit hex values set cmd [subst -novariables -nocommands $cmd] #puts [list $PRIV(app) $cmd] set code [catch {puts $PRIV(app) $cmd ; flush $PRIV(app)} result] if {$code && [eof $PRIV(app)]} { ## Interpreter died or disappeared puts "$code eof [eof $PRIV(app)]" EvalSocketClosed } return -code $code $result } ## ::tkcon::EvalSocketEvent - fileevent command for an interpreter attached ## via a tcp/ip socket ## Must determine whether socket is dead when an error is received # ARGS: args - the args to send across # Returns: the result of the command ## proc ::tkcon::EvalSocketEvent {} { variable PRIV if {[gets $PRIV(app) line] == -1} { if {[eof $PRIV(app)]} { EvalSocketClosed } return } puts $line } ## ::tkcon::EvalSocketClosed - takes care of handling a closed eval socket ## # ARGS: args - the args to send across # Returns: the result of the command ## proc ::tkcon::EvalSocketClosed {} { variable OPT variable PRIV catch {close $PRIV(app)} if {[string compare leave $OPT(dead)] && \ ([string match ignore $OPT(dead)] || \ [tk_dialog $PRIV(base).dead "Dead Attachment" \ "\"$PRIV(app)\" appears to have died.\ \nReturn to primary slave interpreter?" questhead 0 OK No])} { set PRIV(appname) "DEAD:$PRIV(appname)" set PRIV(deadapp) 1 } else { set err "Attached Tk interpreter \"$PRIV(app)\" died." Attach {} set PRIV(deadapp) 0 EvalSlave set errorInfo $err } Prompt \n [CmdGet $PRIV(console)] } ## ::tkcon::EvalNamespace - evaluates the args in a particular namespace ## This is an override for ::tkcon::EvalAttached for when the user wants ## to attach to a particular namespace of the attached interp # ARGS: attached # namespace the namespace to evaluate in # args the args to evaluate # RETURNS: the result of the command ## proc ::tkcon::EvalNamespace { attached namespace args } { if {[llength $args]} { uplevel \#0 $attached \ [list [concat [list namespace eval $namespace] $args]] } } ## ::tkcon::Namespaces - return all the namespaces descendent from $ns ## # ## proc ::tkcon::Namespaces {{ns ::} {l {}}} { if {[string compare {} $ns]} { lappend l $ns } foreach i [EvalAttached [list namespace children $ns]] { set l [Namespaces $i $l] } return $l } ## ::tkcon::CmdGet - gets the current command from the console widget # ARGS: w - console text widget # Returns: text which compromises current command line ## proc ::tkcon::CmdGet w { if {![llength [$w tag nextrange prompt limit end]]} { $w tag add stdin limit end-1c return [$w get limit end-1c] } } ## ::tkcon::CmdSep - separates multiple commands into a list and remainder # ARGS: cmd - (possible) multiple command to separate # list - varname for the list of commands that were separated. # last - varname of any remainder (like an incomplete final command). # If there is only one command, it's placed in this var. # Returns: constituent command info in varnames specified by list & rmd. ## proc ::tkcon::CmdSep {cmd list last} { upvar 1 $list cmds $last inc set inc {} set cmds {} foreach c [split [string trimleft $cmd] \n] { if {[string compare $inc {}]} { append inc \n$c } else { append inc [string trimleft $c] } if {[info complete $inc] && ![regexp {[^\\]\\$} $inc]} { if {[regexp "^\[^#\]" $inc]} {lappend cmds $inc} set inc {} } } set i [string compare $inc {}] if {!$i && [string compare $cmds {}] && ![string match *\n $cmd]} { set inc [lindex $cmds end] set cmds [lreplace $cmds end end] } return $i } ## ::tkcon::CmdSplit - splits multiple commands into a list # ARGS: cmd - (possible) multiple command to separate # Returns: constituent commands in a list ## proc ::tkcon::CmdSplit {cmd} { set inc {} set cmds {} foreach cmd [split [string trimleft $cmd] \n] { if {[string compare {} $inc]} { append inc \n$cmd } else { append inc [string trimleft $cmd] } if {[info complete $inc] && ![regexp {[^\\]\\$} $inc]} { #set inc [string trimright $inc] if {[regexp "^\[^#\]" $inc]} {lappend cmds $inc} set inc {} } } if {[regexp "^\[^#\]" $inc]} {lappend cmds $inc} return $cmds } ## ::tkcon::UniqueTag - creates a uniquely named tag, reusing names ## Called by ::tkcon::EvalCmd # ARGS: w - text widget # Outputs: tag name guaranteed unique in the widget ## proc ::tkcon::UniqueTag {w} { set tags [$w tag names] set idx 0 while {[lsearch -exact $tags _tag[incr idx]] != -1} {} return _tag$idx } ## ::tkcon::ConstrainBuffer - This limits the amount of data in the text widget ## Called by ::tkcon::Prompt and in tkcon proc buffer/console switch cases # ARGS: w - console text widget # size - # of lines to constrain to # Outputs: may delete data in console widget ## proc ::tkcon::ConstrainBuffer {w size} { if {[$w index end] > $size} { $w delete 1.0 [expr {int([$w index end])-$size}].0 } } ## ::tkcon::Prompt - displays the prompt in the console widget # ARGS: w - console text widget # Outputs: prompt (specified in ::tkcon::OPT(prompt1)) to console ## proc ::tkcon::Prompt {{pre {}} {post {}} {prompt {}}} { variable OPT variable PRIV set w $PRIV(console) if {[string compare {} $pre]} { $w insert end $pre stdout } set i [$w index end-1c] if {!$OPT(showstatusbar)} { if {[string compare {} $PRIV(appname)]} { $w insert end ">$PRIV(appname)< " prompt } if {[string compare :: $PRIV(namesp)]} { $w insert end "<$PRIV(namesp)> " prompt } } if {[string compare {} $prompt]} { $w insert end $prompt prompt } else { $w insert end [EvalSlave subst $OPT(prompt1)] prompt } $w mark set output $i $w mark set insert end $w mark set limit insert $w mark gravity limit left if {[string compare {} $post]} { $w insert end $post stdin } ConstrainBuffer $w $OPT(buffer) set ::tkcon::PRIV(StatusCursor) [$w index insert] $w see end } ## ::tkcon::About - gives about info for tkcon ## proc ::tkcon::About {} { variable OPT variable PRIV variable COLOR set w $PRIV(base).about if {[winfo exists $w]} { wm deiconify $w } else { global tk_patchLevel tcl_patchLevel tcl_version toplevel $w wm title $w "About tkcon v$PRIV(version)" button $w.b -text Dismiss -command [list wm withdraw $w] text $w.text -height 9 -bd 1 -width 60 \ -foreground $COLOR(stdin) \ -background $COLOR(bg) \ -font $OPT(font) pack $w.b -fill x -side bottom pack $w.text -fill both -side left -expand 1 $w.text tag config center -justify center $w.text tag config title -justify center -font {Courier -18 bold} # strip down the RCS info displayed in the about box regexp {,v ([0-9\./: ]*)} $PRIV(RCS) -> RCS $w.text insert 1.0 "About tkcon v$PRIV(version)" title \ "\n\nCopyright 1995-2001 Jeffrey Hobbs, $PRIV(email)\ \nRelease Info: v$PRIV(version), CVS v$RCS\ \nDocumentation available at:\n$PRIV(docs)\ \nUsing: Tcl v$tcl_patchLevel / Tk v$tk_patchLevel" center $w.text config -state disabled } } ## ::tkcon::InitMenus - inits the menubar and popup for the console # ARGS: w - console text widget ## proc ::tkcon::InitMenus {w title} { variable OPT variable PRIV variable COLOR global tcl_platform if {[catch {menu $w.pop -tearoff 0}]} { label $w.label -text "Menus not available in plugin mode" pack $w.label return } menu $w.context -tearoff 0 -disabledforeground $COLOR(disabled) set PRIV(context) $w.context set PRIV(popup) $w.pop proc MenuButton {w m l} { $w add cascade -label $m -underline 0 -menu $w.$l return $w.$l } foreach m [list File Console Edit Interp Prefs History Help] { set l [string tolower $m] MenuButton $w $m $l $w.pop add cascade -label $m -underline 0 -menu $w.pop.$l } ## File Menu ## foreach m [list [menu $w.file -disabledforeground $COLOR(disabled)] \ [menu $w.pop.file -disabledforeground $COLOR(disabled)]] { $m add command -label "Load File" -underline 0 -command ::tkcon::Load $m add cascade -label "Save ..." -underline 0 -menu $m.save $m add separator $m add command -label "Quit" -underline 0 -accel Ctrl-q -command exit ## Save Menu ## set s $m.save menu $s -disabledforeground $COLOR(disabled) -tearoff 0 $s add command -label "All" -underline 0 \ -command {::tkcon::Save {} all} $s add command -label "History" -underline 0 \ -command {::tkcon::Save {} history} $s add command -label "Stdin" -underline 3 \ -command {::tkcon::Save {} stdin} $s add command -label "Stdout" -underline 3 \ -command {::tkcon::Save {} stdout} $s add command -label "Stderr" -underline 3 \ -command {::tkcon::Save {} stderr} } ## Console Menu ## foreach m [list [menu $w.console -disabledfore $COLOR(disabled)] \ [menu $w.pop.console -disabledfore $COLOR(disabled)]] { $m add command -label "$title Console" -state disabled $m add command -label "New Console" -underline 0 -accel Ctrl-N \ -command ::tkcon::New $m add command -label "Close Console" -underline 0 -accel Ctrl-w \ -command ::tkcon::Destroy $m add command -label "Clear Console" -underline 1 -accel Ctrl-l \ -command { clear; ::tkcon::Prompt } if {[string match unix $tcl_platform(platform)]} { $m add separator $m add command -label "Make Xauth Secure" -und 5 \ -command ::tkcon::XauthSecure } $m add separator $m add cascade -label "Attach To ..." -underline 0 -menu $m.attach ## Attach Console Menu ## set sub [menu $m.attach -disabledforeground $COLOR(disabled)] $sub add cascade -label "Interpreter" -underline 0 -menu $sub.apps $sub add cascade -label "Namespace" -underline 1 -menu $sub.name $sub add cascade -label "Socket" -underline 1 -menu $sub.sock \ -state [expr {([info tclversion] < 8.3)?"disabled":"normal"}] ## Attach Console Menu ## menu $sub.apps -disabledforeground $COLOR(disabled) \ -postcommand [list ::tkcon::AttachMenu $sub.apps] ## Attach Namespace Menu ## menu $sub.name -disabledforeground $COLOR(disabled) -tearoff 0 \ -postcommand [list ::tkcon::NamespaceMenu $sub.name] if {$::tcl_version >= 8.3} { # This uses [file channels] to create the menu, so we only # want it for newer versions of Tcl. ## Attach Socket Menu ## menu $sub.sock -disabledforeground $COLOR(disabled) -tearoff 0 \ -postcommand [list ::tkcon::SocketMenu $sub.sock] } ## Attach Display Menu ## if {![string compare "unix" $tcl_platform(platform)]} { $sub add cascade -label "Display" -und 1 -menu $sub.disp menu $sub.disp -disabledforeground $COLOR(disabled) \ -tearoff 0 \ -postcommand [list ::tkcon::DisplayMenu $sub.disp] } } ## Edit Menu ## set text $PRIV(console) foreach m [list [menu $w.edit] [menu $w.pop.edit]] { $m add command -label "Cut" -underline 2 -accel Ctrl-x \ -command [list ::tkcon::Cut $text] $m add command -label "Copy" -underline 0 -accel Ctrl-c \ -command [list ::tkcon::Copy $text] $m add command -label "Paste" -underline 0 -accel Ctrl-v \ -command [list ::tkcon::Paste $text] $m add separator $m add command -label "Find" -underline 0 -accel Ctrl-F \ -command [list ::tkcon::FindBox $text] } ## Interp Menu ## foreach m [list $w.interp $w.pop.interp] { menu $m -disabledforeground $COLOR(disabled) \ -postcommand [list ::tkcon::InterpMenu $m] } ## Prefs Menu ## foreach m [list [menu $w.prefs] [menu $w.pop.prefs]] { $m add check -label "Brace Highlighting" \ -underline 0 -variable ::tkcon::OPT(lightbrace) $m add check -label "Command Highlighting" \ -underline 0 -variable ::tkcon::OPT(lightcmd) $m add check -label "History Substitution" \ -underline 0 -variable ::tkcon::OPT(subhistory) $m add check -label "Hot Errors" \ -underline 0 -variable ::tkcon::OPT(hoterrors) $m add check -label "Non-Tcl Attachments" \ -underline 0 -variable ::tkcon::OPT(nontcl) $m add check -label "Calculator Mode" \ -underline 1 -variable ::tkcon::OPT(calcmode) $m add check -label "Show Multiple Matches" \ -underline 0 -variable ::tkcon::OPT(showmultiple) $m add check -label "Show Menubar" \ -underline 5 -variable ::tkcon::OPT(showmenu) \ -command {$::tkcon::PRIV(root) configure -menu [expr \ {$::tkcon::OPT(showmenu) ? $::tkcon::PRIV(menubar) : {}}]} $m add check -label "Show Statusbar" \ -underline 5 -variable ::tkcon::OPT(showstatusbar) \ -command { if {$::tkcon::OPT(showstatusbar)} { pack $::tkcon::PRIV(statusbar) -side bottom -fill x \ -before $::tkcon::PRIV(scrolly) } else { pack forget $::tkcon::PRIV(statusbar) } } $m add cascade -label "Scrollbar" -underline 2 -menu $m.scroll ## Scrollbar Menu ## set m [menu $m.scroll -tearoff 0] $m add radio -label "Left" -value left \ -variable ::tkcon::OPT(scrollypos) \ -command { pack config $::tkcon::PRIV(scrolly) -side left } $m add radio -label "Right" -value right \ -variable ::tkcon::OPT(scrollypos) \ -command { pack config $::tkcon::PRIV(scrolly) -side right } } ## History Menu ## foreach m [list $w.history $w.pop.history] { menu $m -disabledforeground $COLOR(disabled) \ -postcommand [list ::tkcon::HistoryMenu $m] } ## Help Menu ## foreach m [list [menu $w.help] [menu $w.pop.help]] { $m add command -label "About " -underline 0 -accel Ctrl-A \ -command ::tkcon::About $m add command -label "Retrieve Latest Version" -underline 0 \ -command ::tkcon::Retrieve } } ## ::tkcon::HistoryMenu - dynamically build the menu for attached interpreters ## # ARGS: m - menu widget ## proc ::tkcon::HistoryMenu m { variable PRIV if {![winfo exists $m]} return set id [EvalSlave history nextid] if {$PRIV(histid)==$id} return set PRIV(histid) $id $m delete 0 end while {($id>1) && ($id>$PRIV(histid)-10) && \ ![catch {EvalSlave history event [incr id -1]} tmp]} { set lbl $tmp if {[string len $lbl]>32} { set lbl [string range $tmp 0 28]... } $m add command -label "$id: $lbl" -command " $::tkcon::PRIV(console) delete limit end $::tkcon::PRIV(console) insert limit [list $tmp] $::tkcon::PRIV(console) see end ::tkcon::Eval $::tkcon::PRIV(console)" } } ## ::tkcon::InterpMenu - dynamically build the menu for attached interpreters ## # ARGS: w - menu widget ## proc ::tkcon::InterpMenu w { variable OPT variable PRIV variable COLOR if {![winfo exists $w]} return $w delete 0 end foreach {app type} [Attach] break $w add command -label "[string toupper $type]: $app" -state disabled if {($OPT(nontcl) && [string match interp $type]) || $PRIV(deadapp)} { $w add separator $w add command -state disabled -label "Communication disabled to" $w add command -state disabled -label "dead or non-Tcl interps" return } ## Show Last Error ## $w add separator $w add command -label "Show Last Error" \ -command [list tkcon error $app $type] ## Packages Cascaded Menu ## $w add separator $w add cascade -label Packages -underline 0 -menu $w.pkg set m $w.pkg if {![winfo exists $m]} { menu $m -tearoff no -disabledforeground $COLOR(disabled) \ -postcommand [list ::tkcon::PkgMenu $m $app $type] } ## State Checkpoint/Revert ## $w add separator $w add command -label "Checkpoint State" \ -command [list ::tkcon::StateCheckpoint $app $type] $w add command -label "Revert State" \ -command [list ::tkcon::StateRevert $app $type] $w add command -label "View State Change" \ -command [list ::tkcon::StateCompare $app $type] ## Init Interp ## $w add separator $w add command -label "Send tkcon Commands" \ -command [list ::tkcon::InitInterp $app $type] } ## ::tkcon::PkgMenu - fill in in the applications sub-menu ## with a list of all the applications that currently exist. ## proc ::tkcon::PkgMenu {m app type} { # just in case stuff has been added to the auto_path # we have to make sure that the errorInfo doesn't get screwed up EvalAttached { set __tkcon_error $errorInfo catch {package require bogus-package-name} set errorInfo ${__tkcon_error} unset __tkcon_error } $m delete 0 end foreach pkg [EvalAttached [list info loaded {}]] { set loaded([lindex $pkg 1]) [package provide $pkg] } foreach pkg [lremove [EvalAttached {package names}] Tcl] { set version [EvalAttached [list package provide $pkg]] if {[string compare {} $version]} { set loaded($pkg) $version } elseif {![info exists loaded($pkg)]} { set loadable($pkg) [list package require $pkg] } } foreach pkg [EvalAttached {info loaded}] { set pkg [lindex $pkg 1] if {![info exists loaded($pkg)] && ![info exists loadable($pkg)]} { set loadable($pkg) [list load {} $pkg] } } set npkg 0 foreach pkg [lsort -dictionary [array names loadable]] { foreach v [EvalAttached [list package version $pkg]] { set brkcol [expr {([incr npkg]%16)==0}] $m add command -label "Load $pkg ($v)" -command \ "::tkcon::EvalOther [list $app] $type $loadable($pkg) $v" \ -columnbreak $brkcol } } if {[info exists loaded] && [info exists loadable]} { $m add separator } foreach pkg [lsort -dictionary [array names loaded]] { $m add command -label "${pkg}$loaded($pkg) Loaded" -state disabled } } ## ::tkcon::AttachMenu - fill in in the applications sub-menu ## with a list of all the applications that currently exist. ## proc ::tkcon::AttachMenu m { variable OPT variable PRIV array set interps [set tmp [Interps]] foreach {i j} $tmp { set tknames($j) {} } $m delete 0 end set cmd {::tkcon::Prompt \n [::tkcon::CmdGet $::tkcon::PRIV(console)]} $m add radio -label {None (use local slave) } -accel Ctrl-1 \ -variable ::tkcon::PRIV(app) \ -value [concat $::tkcon::PRIV(name) $::tkcon::OPT(exec)] \ -command "::tkcon::Attach {}; $cmd" $m add separator $m add command -label "Foreign Tk Interpreters" -state disabled foreach i [lsort [lremove [winfo interps] [array names tknames]]] { $m add radio -label $i -variable ::tkcon::PRIV(app) -value $i \ -command "::tkcon::Attach [list $i] interp; $cmd" } $m add separator $m add command -label "tkcon Interpreters" -state disabled foreach i [lsort [array names interps]] { if {[string match {} $interps($i)]} { set interps($i) "no Tk" } if {[regexp {^Slave[0-9]+} $i]} { set opts [list -label "$i ($interps($i))" \ -variable ::tkcon::PRIV(app) -value $i \ -command "::tkcon::Attach [list $i] slave; $cmd"] if {[string match $PRIV(name) $i]} { append opts " -accel Ctrl-2" } eval $m add radio $opts } else { set name [concat Main $i] if {[string match Main $name]} { $m add radio -label "$name ($interps($i))" -accel Ctrl-3 \ -variable ::tkcon::PRIV(app) -value Main \ -command "::tkcon::Attach [list $name] slave; $cmd" } else { $m add radio -label "$name ($interps($i))" \ -variable ::tkcon::PRIV(app) -value $i \ -command "::tkcon::Attach [list $name] slave; $cmd" } } } } ## Displays Cascaded Menu ## proc ::tkcon::DisplayMenu m { $m delete 0 end set cmd {::tkcon::Prompt \n [::tkcon::CmdGet $::tkcon::PRIV(console)]} $m add command -label "New Display" -command ::tkcon::NewDisplay foreach disp [Display] { $m add separator $m add command -label $disp -state disabled set res [Display $disp] set win [lindex $res 0] foreach i [lsort [lindex $res 1]] { $m add radio -label $i -variable ::tkcon::PRIV(app) -value $i \ -command "::tkcon::Attach [list $i] [list dpy:$win]; $cmd" } } } ## Sockets Cascaded Menu ## proc ::tkcon::SocketMenu m { $m delete 0 end set cmd {::tkcon::Prompt \n [::tkcon::CmdGet $::tkcon::PRIV(console)]} $m add command -label "Create Connection" \ -command "::tkcon::NewSocket; $cmd" foreach sock [file channels sock*] { $m add radio -label $sock -variable ::tkcon::PRIV(app) -value $sock \ -command "::tkcon::Attach $sock socket; $cmd" } } ## Namepaces Cascaded Menu ## proc ::tkcon::NamespaceMenu m { variable PRIV variable OPT $m delete 0 end if {($PRIV(deadapp) || [string match socket $PRIV(apptype)] || \ ($OPT(nontcl) && [string match interp $PRIV(apptype)]))} { $m add command -label "No Namespaces" -state disabled return } ## Same command as for ::tkcon::AttachMenu items set cmd {::tkcon::Prompt \n [::tkcon::CmdGet $::tkcon::PRIV(console)]} set names [lsort [Namespaces ::]] if {[llength $names] > $OPT(maxmenu)} { $m add command -label "Attached to $PRIV(namesp)" -state disabled $m add command -label "List Namespaces" \ -command [list ::tkcon::NamespacesList $names] } else { foreach i $names { if {[string match :: $i]} { $m add radio -label "Main" -value $i \ -variable ::tkcon::PRIV(namesp) \ -command "::tkcon::AttachNamespace [list $i]; $cmd" } else { $m add radio -label $i -value $i \ -variable ::tkcon::PRIV(namesp) \ -command "::tkcon::AttachNamespace [list $i]; $cmd" } } } } ## Namepaces List ## proc ::tkcon::NamespacesList {names} { variable PRIV set f $PRIV(base).namespaces catch {destroy $f} toplevel $f listbox $f.names -width 30 -height 15 -selectmode single \ -yscrollcommand [list $f.scrollv set] \ -xscrollcommand [list $f.scrollh set] scrollbar $f.scrollv -command [list $f.names yview] scrollbar $f.scrollh -command [list $f.names xview] -orient horizontal frame $f.buttons button $f.cancel -text "Cancel" -command [list destroy $f] grid $f.names $f.scrollv -sticky nesw grid $f.scrollh -sticky ew grid $f.buttons -sticky nesw grid $f.cancel -in $f.buttons -pady 6 grid columnconfigure $f 0 -weight 1 grid rowconfigure $f 0 -weight 1 #fill the listbox foreach i $names { if {[string match :: $i]} { $f.names insert 0 Main } else { $f.names insert end $i } } #Bindings bind $f.names { ## Catch in case the namespace disappeared on us catch { ::tkcon::AttachNamespace [%W get [%W nearest %y]] } ::tkcon::Prompt "\n" [::tkcon::CmdGet $::tkcon::PRIV(console)] destroy [winfo toplevel %W] } } # ::tkcon::XauthSecure -- # # This removes all the names in the xhost list, and secures # the display for Tk send commands. Of course, this prevents # what might have been otherwise allowable X connections # # Arguments: # none # Results: # Returns nothing # proc ::tkcon::XauthSecure {} { global tcl_platform if {[string compare unix $tcl_platform(platform)]} { # This makes no sense outside of Unix return } set hosts [exec xhost] # the first line is info only foreach host [lrange [split $hosts \n] 1 end] { exec xhost -$host } exec xhost - tk_messageBox -title "Xhost secured" -message "Xhost secured" -icon info } ## ::tkcon::FindBox - creates minimal dialog interface to ::tkcon::Find # ARGS: w - text widget # str - optional seed string for ::tkcon::PRIV(find) ## proc ::tkcon::FindBox {w {str {}}} { variable PRIV set base $PRIV(base).find if {![winfo exists $base]} { toplevel $base wm withdraw $base wm title $base "tkcon Find" pack [frame $base.f] -fill x -expand 1 label $base.f.l -text "Find:" entry $base.f.e -textvariable ::tkcon::PRIV(find) pack [frame $base.opt] -fill x checkbutton $base.opt.c -text "Case Sensitive" \ -variable ::tkcon::PRIV(find,case) checkbutton $base.opt.r -text "Use Regexp" -variable ::tkcon::PRIV(find,reg) pack $base.f.l -side left pack $base.f.e $base.opt.c $base.opt.r -side left -fill both -expand 1 pack [frame $base.sep -bd 2 -relief sunken -height 4] -fill x pack [frame $base.btn] -fill both button $base.btn.fnd -text "Find" -width 6 button $base.btn.clr -text "Clear" -width 6 button $base.btn.dis -text "Dismiss" -width 6 eval pack [winfo children $base.btn] -padx 4 -pady 2 \ -side left -fill both focus $base.f.e bind $base.f.e [list $base.btn.fnd invoke] bind $base.f.e [list $base.btn.dis invoke] } $base.btn.fnd config -command "::tkcon::Find [list $w] \$::tkcon::PRIV(find) \ -case \$::tkcon::PRIV(find,case) -reg \$::tkcon::PRIV(find,reg)" $base.btn.clr config -command " [list $w] tag remove find 1.0 end set ::tkcon::PRIV(find) {} " $base.btn.dis config -command " [list $w] tag remove find 1.0 end wm withdraw [list $base] " if {[string compare {} $str]} { set PRIV(find) $str $base.btn.fnd invoke } if {[string compare normal [wm state $base]]} { wm deiconify $base } else { raise $base } $base.f.e select range 0 end } ## ::tkcon::Find - searches in text widget $w for $str and highlights it ## If $str is empty, it just deletes any highlighting # ARGS: w - text widget # str - string to search for # -case TCL_BOOLEAN whether to be case sensitive DEFAULT: 0 # -regexp TCL_BOOLEAN whether to use $str as pattern DEFAULT: 0 ## proc ::tkcon::Find {w str args} { $w tag remove find 1.0 end set truth {^(1|yes|true|on)$} set opts {} foreach {key val} $args { switch -glob -- $key { -c* { if {[regexp -nocase $truth $val]} { set case 1 } } -r* { if {[regexp -nocase $truth $val]} { lappend opts -regexp } } default { return -code error "Unknown option $key" } } } if {![info exists case]} { lappend opts -nocase } if {[string match {} $str]} return $w mark set findmark 1.0 while {[string compare {} [set ix [eval $w search $opts -count numc -- \ [list $str] findmark end]]]} { $w tag add find $ix ${ix}+${numc}c $w mark set findmark ${ix}+1c } $w tag configure find -background $::tkcon::COLOR(blink) catch {$w see find.first} return [expr {[llength [$w tag ranges find]]/2}] } ## ::tkcon::Attach - called to attach tkcon to an interpreter # ARGS: name - application name to which tkcon sends commands # This is either a slave interperter name or tk appname. # type - (slave|interp) type of interpreter we're attaching to # slave means it's a tkcon interpreter # interp means we'll need to 'send' to it. # Results: ::tkcon::EvalAttached is recreated to evaluate in the # appropriate interpreter ## proc ::tkcon::Attach {{name } {type slave}} { variable PRIV variable OPT if {[llength [info level 0]] == 1} { # no args were specified, return the attach info instead if {[string match {} $PRIV(appname)]} { return [list [concat $PRIV(name) $OPT(exec)] $PRIV(apptype)] } else { return [list $PRIV(appname) $PRIV(apptype)] } } set path [concat $PRIV(name) $OPT(exec)] set PRIV(displayWin) . if {[string match namespace $type]} { return [uplevel 1 ::tkcon::AttachNamespace $name] } elseif {[string match dpy:* $type]} { set PRIV(displayWin) [string range $type 4 end] } elseif {[string match sock* $type]} { global tcl_version if {[catch {eof $name} res]} { return -code error "No known channel \"$name\"" } elseif {$res} { catch {close $name} return -code error "Channel \"$name\" returned EOF" } set app $name set type socket } elseif {[string compare {} $name]} { array set interps [Interps] if {[string match {[Mm]ain} [lindex $name 0]]} { set name [lrange $name 1 end] } if {[string match $path $name]} { set name {} set app $path set type slave } elseif {[info exists interps($name)]} { if {[string match {} $name]} { set name Main; set app Main } set type slave } elseif {[interp exists $name]} { set name [concat $PRIV(name) $name] set type slave } elseif {[interp exists [concat $OPT(exec) $name]]} { set name [concat $path $name] set type slave } elseif {[lsearch -exact [winfo interps] $name] > -1} { if {[EvalSlave info exists tk_library] \ && [string match $name [EvalSlave tk appname]]} { set name {} set app $path set type slave } elseif {[set i [lsearch -exact \ [Main set ::tkcon::PRIV(interps)] $name]] != -1} { set name [lindex [Main set ::tkcon::PRIV(slaves)] $i] if {[string match {[Mm]ain} $name]} { set app Main } set type slave } else { set type interp } } else { return -code error "No known interpreter \"$name\"" } } else { set app $path } if {![info exists app]} { set app $name } array set PRIV [list app $app appname $name apptype $type deadapp 0] ## ::tkcon::EvalAttached - evaluates the args in the attached interp ## args should be passed to this procedure as if they were being ## passed to the 'eval' procedure. This procedure is dynamic to ## ensure evaluation occurs in the right interp. # ARGS: args - the command and args to evaluate ## switch -glob -- $type { slave { if {[string match {} $name]} { interp alias {} ::tkcon::EvalAttached {} \ ::tkcon::EvalSlave uplevel \#0 } elseif {[string match Main $PRIV(app)]} { interp alias {} ::tkcon::EvalAttached {} ::tkcon::Main } elseif {[string match $PRIV(name) $PRIV(app)]} { interp alias {} ::tkcon::EvalAttached {} uplevel \#0 } else { interp alias {} ::tkcon::EvalAttached {} \ ::tkcon::Slave $::tkcon::PRIV(app) } } sock* { interp alias {} ::tkcon::EvalAttached {} \ ::tkcon::EvalSlave uplevel \#0 # The file event will just puts whatever data is found # into the interpreter fconfigure $name -buffering line -blocking 0 fileevent $name readable ::tkcon::EvalSocketEvent } dpy:* - interp { if {$OPT(nontcl)} { interp alias {} ::tkcon::EvalAttached {} ::tkcon::EvalSlave set PRIV(namesp) :: } else { interp alias {} ::tkcon::EvalAttached {} ::tkcon::EvalSend } } default { return -code error "[lindex [info level 0] 0] did not specify\ a valid type: must be slave or interp" } } if {[string match slave $type] || \ (!$OPT(nontcl) && [regexp {^(interp|dpy)} $type])} { set PRIV(namesp) :: } set PRIV(StatusAttach) "$PRIV(app) ($PRIV(apptype))" return } ## ::tkcon::AttachNamespace - called to attach tkcon to a namespace # ARGS: name - namespace name in which tkcon should eval commands # Results: ::tkcon::EvalAttached will be modified ## proc ::tkcon::AttachNamespace { name } { variable PRIV variable OPT if {($OPT(nontcl) && [string match interp $PRIV(apptype)]) \ || [string match socket $PRIV(apptype)] \ || $PRIV(deadapp)} { return -code error "can't attach to namespace in attached environment" } if {[string match Main $name]} {set name ::} if {[string compare {} $name] && \ [lsearch [Namespaces ::] $name] == -1} { return -code error "No known namespace \"$name\"" } if {[regexp {^(|::)$} $name]} { ## If name=={} || ::, we want the primary namespace set alias [interp alias {} ::tkcon::EvalAttached] if {[string match ::tkcon::EvalNamespace* $alias]} { eval [list interp alias {} ::tkcon::EvalAttached {}] \ [lindex $alias 1] } set name :: } else { interp alias {} ::tkcon::EvalAttached {} ::tkcon::EvalNamespace \ [interp alias {} ::tkcon::EvalAttached] [list $name] } set PRIV(namesp) $name set PRIV(StatusAttach) "$PRIV(app) $PRIV(namesp) ($PRIV(apptype))" } ## ::tkcon::NewSocket - called to create a socket to connect to # ARGS: none # Results: It will create a socket, and attach if requested ## proc ::tkcon::NewSocket {} { variable PRIV set t $PRIV(base).newsock if {![winfo exists $t]} { toplevel $t wm withdraw $t wm title $t "tkcon Create Socket" label $t.lhost -text "Host: " entry $t.host -width 20 label $t.lport -text "Port: " entry $t.port -width 4 button $t.ok -text "OK" -command {set ::tkcon::PRIV(grab) 1} bind $t.host [list focus $t.port] bind $t.port [list focus $t.ok] bind $t.ok [list $t.ok invoke] grid $t.lhost $t.host $t.lport $t.port -sticky ew grid $t.ok - - - -sticky ew grid columnconfig $t 1 -weight 1 grid rowconfigure $t 1 -weight 1 wm transient $t $PRIV(root) wm geometry $t +[expr {([winfo screenwidth $t]-[winfo \ reqwidth $t]) / 2}]+[expr {([winfo \ screenheight $t]-[winfo reqheight $t]) / 2}] } #$t.host delete 0 end #$t.port delete 0 end wm deiconify $t raise $t grab $t focus $t.host vwait ::tkcon::PRIV(grab) grab release $t wm withdraw $t set host [$t.host get] set port [$t.port get] if {$host == ""} { return } if {[catch { set sock [socket $host $port] } err]} { tk_messageBox -title "Socket Connection Error" \ -message "Unable to connect to \"$host:$port\":\n$err" \ -icon error -type ok } else { Attach $sock socket } } ## ::tkcon::Load - sources a file into the console ## The file is actually sourced in the currently attached's interp # ARGS: fn - (optional) filename to source in # Returns: selected filename ({} if nothing was selected) ## proc ::tkcon::Load { {fn ""} } { set types { {{Tcl Files} {.tcl .tk}} {{Text Files} {.txt}} {{All Files} *} } if { [string match {} $fn] && ([catch {tk_getOpenFile -filetypes $types \ -title "Source File"} fn] || [string match {} $fn]) } { return } EvalAttached [list source $fn] } ## ::tkcon::Save - saves the console or other widget buffer to a file ## This does not eval in a slave because it's not necessary # ARGS: w - console text widget # fn - (optional) filename to save to ## proc ::tkcon::Save { {fn ""} {type ""} {opt ""} {mode w} } { variable PRIV if {![regexp -nocase {^(all|history|stdin|stdout|stderr|widget)$} $type]} { array set s { 0 All 1 History 2 Stdin 3 Stdout 4 Stderr 5 Cancel } ## Allow user to specify what kind of stuff to save set type [tk_dialog $PRIV(base).savetype "Save Type" \ "What part of the text do you want to save?" \ questhead 0 $s(0) $s(1) $s(2) $s(3) $s(4) $s(5)] if {$type == 5 || $type == -1} return set type $s($type) } if {[string match {} $fn]} { set types { {{Tcl Files} {.tcl .tk}} {{Text Files} {.txt}} {{All Files} *} } if {[catch {tk_getSaveFile -defaultextension .tcl -filetypes $types \ -title "Save $type"} fn] || [string match {} $fn]} return } set type [string tolower $type] switch $type { stdin - stdout - stderr { set data {} foreach {first last} [$PRIV(console) tag ranges $type] { lappend data [$PRIV(console) get $first $last] } set data [join $data \n] } history { set data [tkcon history] } all - default { set data [$PRIV(console) get 1.0 end-1c] } widget { set data [$opt get 1.0 end-1c] } } if {[catch {open $fn $mode} fid]} { return -code error "Save Error: Unable to open '$fn' for writing\n$fid" } puts -nonewline $fid $data close $fid } ## ::tkcon::MainInit ## This is only called for the main interpreter to include certain procs ## that we don't want to include (or rather, just alias) in slave interps. ## proc ::tkcon::MainInit {} { variable PRIV if {![info exists PRIV(slaves)]} { array set PRIV [list slave 0 slaves Main name {} \ interps [list [tk appname]]] } interp alias {} ::tkcon::Main {} ::tkcon::InterpEval Main interp alias {} ::tkcon::Slave {} ::tkcon::InterpEval proc ::tkcon::GetSlaveNum {} { set i -1 while {[interp exists Slave[incr i]]} { # oh my god, an empty loop! } return $i } ## ::tkcon::New - create new console window ## Creates a slave interpreter and sources in this script. ## All other interpreters also get a command to eval function in the ## new interpreter. ## proc ::tkcon::New {} { variable PRIV global argv0 argc argv set tmp [interp create Slave[GetSlaveNum]] lappend PRIV(slaves) $tmp load {} Tk $tmp lappend PRIV(interps) [$tmp eval [list tk appname \ "[tk appname] $tmp"]] if {[info exist argv0]} {$tmp eval [list set argv0 $argv0]} $tmp eval set argc $argc $tmp eval [list set argv $argv] $tmp eval [list namespace eval ::tkcon {}] $tmp eval [list set ::tkcon::PRIV(name) $tmp] $tmp eval [list set ::tkcon::PRIV(SCRIPT) $::tkcon::PRIV(SCRIPT)] $tmp alias exit ::tkcon::Exit $tmp $tmp alias ::tkcon::Destroy ::tkcon::Destroy $tmp $tmp alias ::tkcon::New ::tkcon::New $tmp alias ::tkcon::Main ::tkcon::InterpEval Main $tmp alias ::tkcon::Slave ::tkcon::InterpEval $tmp alias ::tkcon::Interps ::tkcon::Interps $tmp alias ::tkcon::NewDisplay ::tkcon::NewDisplay $tmp alias ::tkcon::Display ::tkcon::Display $tmp alias ::tkcon::StateCheckpoint ::tkcon::StateCheckpoint $tmp alias ::tkcon::StateCleanup ::tkcon::StateCleanup $tmp alias ::tkcon::StateCompare ::tkcon::StateCompare $tmp alias ::tkcon::StateRevert ::tkcon::StateRevert $tmp eval { if [catch {source -rsrc tkcon}] { source $::tkcon::PRIV(SCRIPT) } } return $tmp } ## ::tkcon::Exit - full exit OR destroy slave console ## This proc should only be called in the main interpreter from a slave. ## The master determines whether we do a full exit or just kill the slave. ## proc ::tkcon::Exit {slave args} { variable PRIV variable OPT ## Slave interpreter exit request if {[string match exit $OPT(slaveexit)]} { ## Only exit if it specifically is stated to do so uplevel 1 exit $args } ## Otherwise we will delete the slave interp and associated data set name [InterpEval $slave] set PRIV(interps) [lremove $PRIV(interps) [list $name]] set PRIV(slaves) [lremove $PRIV(slaves) [list $slave]] interp delete $slave StateCleanup $slave return } ## ::tkcon::Destroy - destroy console window ## This proc should only be called by the main interpreter. If it is ## called from there, it will ask before exiting tkcon. All others ## (slaves) will just have their slave interpreter deleted, closing them. ## proc ::tkcon::Destroy {{slave {}}} { variable PRIV if {[string match {} $slave]} { ## Main interpreter close request if {[tk_dialog $PRIV(base).destroyme {Quit tkcon?} \ {Closing the Main console will quit tkcon} \ warning 0 "Don't Quit" "Quit tkcon"]} exit } else { ## Slave interpreter close request set name [InterpEval $slave] set PRIV(interps) [lremove $PRIV(interps) [list $name]] set PRIV(slaves) [lremove $PRIV(slaves) [list $slave]] interp delete $slave } StateCleanup $slave return } ## We want to do a couple things before exiting... if {[catch {rename ::exit ::tkcon::FinalExit} err]} { puts stderr "tkcon might panic:\n$err" } proc ::exit args { if {$::tkcon::OPT(usehistory)} { if {[catch {open $::tkcon::PRIV(histfile) w} fid]} { puts stderr "unable to save history file:\n$fid" # pause a moment, because we are about to die finally... after 1000 } else { set max [::tkcon::EvalSlave history nextid] set id [expr {$max - $::tkcon::OPT(history)}] if {$id < 1} { set id 1 } ## FIX: This puts history in backwards!! while {($id < $max) && \ ![catch {::tkcon::EvalSlave history event $id} cmd]} { if {[string compare {} $cmd]} { puts $fid "::tkcon::EvalSlave history add [list $cmd]" } incr id } close $fid } } uplevel 1 ::tkcon::FinalExit $args } ## ::tkcon::InterpEval - passes evaluation to another named interpreter ## If the interpreter is named, but no args are given, it returns the ## [tk appname] of that interps master (not the associated eval slave). ## proc ::tkcon::InterpEval {{slave {}} args} { variable PRIV if {[string match {} $slave]} { return $PRIV(slaves) } elseif {[string match {[Mm]ain} $slave]} { set slave {} } if {[llength $args]} { return [interp eval $slave uplevel \#0 $args] } else { return [interp eval $slave tk appname] } } proc ::tkcon::Interps {{ls {}} {interp {}}} { if {[string match {} $interp]} { lappend ls {} [tk appname] } foreach i [interp slaves $interp] { if {[string compare {} $interp]} { set i "$interp $i" } if {[string compare {} [interp eval $i package provide Tk]]} { lappend ls $i [interp eval $i tk appname] } else { lappend ls $i {} } set ls [Interps $ls $i] } return $ls } proc ::tkcon::Display {{disp {}}} { variable DISP set res {} if {$disp != ""} { if {![info exists DISP($disp)]} { return } return [list $DISP($disp) [winfo interps -displayof $DISP($disp)]] } return [lsort -dictionary [array names DISP]] } proc ::tkcon::NewDisplay {} { variable PRIV variable DISP set t $PRIV(base).newdisp if {![winfo exists $t]} { toplevel $t wm withdraw $t wm title $t "tkcon Attach to Display" label $t.gets -text "New Display: " entry $t.data -width 32 button $t.ok -text "OK" -command {set ::tkcon::PRIV(grab) 1} bind $t.data [list $t.ok invoke] bind $t.ok [list $t.ok invoke] grid $t.gets $t.data -sticky ew grid $t.ok - -sticky ew grid columnconfig $t 1 -weight 1 grid rowconfigure $t 1 -weight 1 wm transient $t $PRIV(root) wm geometry $t +[expr {([winfo screenwidth $t]-[winfo \ reqwidth $t]) / 2}]+[expr {([winfo \ screenheight $t]-[winfo reqheight $t]) / 2}] } $t.data delete 0 end wm deiconify $t raise $t grab $t focus $t.data vwait ::tkcon::PRIV(grab) grab release $t wm withdraw $t set disp [$t.data get] if {$disp == ""} { return } regsub -all {\.} [string tolower $disp] ! dt set dt $PRIV(base).$dt destroy $dt if {[catch { toplevel $dt -screen $disp set interps [winfo interps -displayof $dt] if {![llength $interps]} { error "No other Tk interpreters on $disp" } send -displayof $dt [lindex $interps 0] [list info tclversion] } err]} { global env if {[info exists env(DISPLAY)]} { set myd $env(DISPLAY) } else { set myd "myDisplay:0" } tk_messageBox -title "Display Connection Error" \ -message "Unable to connect to \"$disp\":\n$err\ \nMake sure you have xauth-based permissions\ (xauth add $myd . `mcookie`), and xhost is disabled\ (xhost -) on \"$disp\"" \ -icon error -type ok destroy $dt return } set DISP($disp) $dt wm withdraw $dt bind $dt [subst {catch {unset ::tkcon::DISP($disp)}}] tk_messageBox -title "$disp Connection" \ -message "Connected to \"$disp\", found:\n[join $interps \n]" \ -type ok } ## ## The following state checkpoint/revert procedures are very sketchy ## and prone to problems. They do not track modifications to currently ## existing procedures/variables, and they can really screw things up ## if you load in libraries (especially Tk) between checkpoint and ## revert. Only with this knowledge in mind should you use these. ## ## ::tkcon::StateCheckpoint - checkpoints the current state of the system ## This allows you to return to this state with ::tkcon::StateRevert # ARGS: ## proc ::tkcon::StateCheckpoint {app type} { variable CPS variable PRIV if {[info exists CPS($type,$app,cmd)] && \ [tk_dialog $PRIV(base).warning "Overwrite Previous State?" \ "Are you sure you want to lose previously checkpointed\ state of $type \"$app\"?" questhead 1 "Do It" "Cancel"]} return set CPS($type,$app,cmd) [EvalOther $app $type info commands *] set CPS($type,$app,var) [EvalOther $app $type info vars *] return } ## ::tkcon::StateCompare - compare two states and output difference # ARGS: ## proc ::tkcon::StateCompare {app type {verbose 0}} { variable CPS variable PRIV variable OPT variable COLOR if {![info exists CPS($type,$app,cmd)]} { return -code error \ "No previously checkpointed state for $type \"$app\"" } set w $PRIV(base).compare if {[winfo exists $w]} { $w.text config -state normal $w.text delete 1.0 end } else { toplevel $w frame $w.btn scrollbar $w.sy -takefocus 0 -bd 1 -command [list $w.text yview] text $w.text -yscrollcommand [list $w.sy set] -height 12 \ -foreground $COLOR(stdin) \ -background $COLOR(bg) \ -insertbackground $COLOR(cursor) \ -font $OPT(font) pack $w.btn -side bottom -fill x pack $w.sy -side right -fill y pack $w.text -fill both -expand 1 button $w.btn.close -text "Dismiss" -width 11 \ -command [list destroy $w] button $w.btn.check -text "Recheckpoint" -width 11 button $w.btn.revert -text "Revert" -width 11 button $w.btn.expand -text "Verbose" -width 11 button $w.btn.update -text "Update" -width 11 pack $w.btn.check $w.btn.revert $w.btn.expand $w.btn.update \ $w.btn.close -side left -fill x -padx 4 -pady 2 -expand 1 $w.text tag config red -foreground red } wm title $w "Compare State: $type [list $app]" $w.btn.check config \ -command "::tkcon::StateCheckpoint [list $app] $type; \ ::tkcon::StateCompare [list $app] $type $verbose" $w.btn.revert config \ -command "::tkcon::StateRevert [list $app] $type; \ ::tkcon::StateCompare [list $app] $type $verbose" $w.btn.update config -command [info level 0] if {$verbose} { $w.btn.expand config -text Brief \ -command [list ::tkcon::StateCompare $app $type 0] } else { $w.btn.expand config -text Verbose \ -command [list ::tkcon::StateCompare $app $type 1] } ## Don't allow verbose mode unless 'dump' exists in $app ## We're assuming this is tkcon's dump command set hasdump [llength [EvalOther $app $type info commands dump]] if {$hasdump} { $w.btn.expand config -state normal } else { $w.btn.expand config -state disabled } set cmds [lremove [EvalOther $app $type info commands *] \ $CPS($type,$app,cmd)] set vars [lremove [EvalOther $app $type info vars *] \ $CPS($type,$app,var)] if {$hasdump && $verbose} { set cmds [EvalOther $app $type eval dump c -nocomplain $cmds] set vars [EvalOther $app $type eval dump v -nocomplain $vars] } $w.text insert 1.0 "NEW COMMANDS IN \"$app\":\n" red \ $cmds {} "\n\nNEW VARIABLES IN \"$app\":\n" red $vars {} raise $w $w.text config -state disabled } ## ::tkcon::StateRevert - reverts interpreter to previous state # ARGS: ## proc ::tkcon::StateRevert {app type} { variable CPS variable PRIV if {![info exists CPS($type,$app,cmd)]} { return -code error \ "No previously checkpointed state for $type \"$app\"" } if {![tk_dialog $PRIV(base).warning "Revert State?" \ "Are you sure you want to revert the state in $type \"$app\"?"\ questhead 1 "Do It" "Cancel"]} { foreach i [lremove [EvalOther $app $type info commands *] \ $CPS($type,$app,cmd)] { catch {EvalOther $app $type rename $i {}} } foreach i [lremove [EvalOther $app $type info vars *] \ $CPS($type,$app,var)] { catch {EvalOther $app $type unset $i} } } } ## ::tkcon::StateCleanup - cleans up state information in master array # ## proc ::tkcon::StateCleanup {args} { variable CPS if {![llength $args]} { foreach state [array names CPS slave,*] { if {![interp exists [string range $state 6 end]]} { unset CPS($state) } } } else { set app [lindex $args 0] set type [lindex $args 1] if {[regexp {^(|slave)$} $type]} { foreach state [array names CPS "slave,$app\[, \]*"] { if {![interp exists [string range $state 6 end]]} { unset CPS($state) } } } else { catch {unset CPS($type,$app)} } } } } ## ::tkcon::Event - get history event, search if string != {} ## look forward (next) if $int>0, otherwise look back (prev) # ARGS: W - console widget ## proc ::tkcon::Event {int {str {}}} { if {!$int} return variable PRIV set w $PRIV(console) set nextid [EvalSlave history nextid] if {[string compare {} $str]} { ## String is not empty, do an event search set event $PRIV(event) if {$int < 0 && $event == $nextid} { set PRIV(cmdbuf) $str } set len [string len $PRIV(cmdbuf)] incr len -1 if {$int > 0} { ## Search history forward while {$event < $nextid} { if {[incr event] == $nextid} { $w delete limit end $w insert limit $PRIV(cmdbuf) break } elseif { ![catch {EvalSlave history event $event} res] && [set p [string first $PRIV(cmdbuf) $res]] > -1 } { set p2 [expr {$p + [string length $PRIV(cmdbuf)]}] $w delete limit end $w insert limit $res Blink $w "limit + $p c" "limit + $p2 c" break } } set PRIV(event) $event } else { ## Search history reverse while {![catch {EvalSlave history event [incr event -1]} res]} { if {[set p [string first $PRIV(cmdbuf) $res]] > -1} { set p2 [expr {$p + [string length $PRIV(cmdbuf)]}] $w delete limit end $w insert limit $res set PRIV(event) $event Blink $w "limit + $p c" "limit + $p2 c" break } } } } else { ## String is empty, just get next/prev event if {$int > 0} { ## Goto next command in history if {$PRIV(event) < $nextid} { $w delete limit end if {[incr PRIV(event)] == $nextid} { $w insert limit $PRIV(cmdbuf) } else { $w insert limit [EvalSlave history event $PRIV(event)] } } } else { ## Goto previous command in history if {$PRIV(event) == $nextid} { set PRIV(cmdbuf) [CmdGet $w] } if {[catch {EvalSlave history event [incr PRIV(event) -1]} res]} { incr PRIV(event) } else { $w delete limit end $w insert limit $res } } } $w mark set insert end $w see end } ## ::tkcon::ErrorHighlight - magic error highlighting ## beware: voodoo included # ARGS: ## proc ::tkcon::ErrorHighlight w { variable COLOR ## do voodoo here set app [Attach] # we have to pull the text out, because text regexps are screwed on \n's. set info [$w get 1.0 end-1c] # Check for specific line error in a proc set exp(proc) "\"(\[^\"\]+)\"\n\[\t \]+\\\(procedure \"(\[^\"\]+)\"" # Check for too few args to a proc set exp(param) "parameter \"(\[^\"\]+)\" to \"(\[^\"\]+)\"" set start 1.0 while { [regexp -indices -- $exp(proc) $info junk what cmd] || [regexp -indices -- $exp(param) $info junk what cmd] } { foreach {w0 w1} $what {c0 c1} $cmd {break} set what [string range $info $w0 $w1] set cmd [string range $info $c0 $c1] if {[string match *::* $cmd]} { set res [uplevel 1 ::tkcon::EvalOther $app namespace eval \ [list [namespace qualifiers $cmd] \ [list info procs [namespace tail $cmd]]]] } else { set res [uplevel 1 ::tkcon::EvalOther $app info procs [list $cmd]] } if {[llength $res]==1} { set tag [UniqueTag $w] $w tag add $tag $start+${c0}c $start+1c+${c1}c $w tag configure $tag -foreground $COLOR(stdout) $w tag bind $tag [list $w tag configure $tag -under 1] $w tag bind $tag [list $w tag configure $tag -under 0] $w tag bind $tag "if {!\$tkPriv(mouseMoved)} \ {[list edit -attach $app -type proc -find $what -- $cmd]}" } set info [string range $info $c1 end] set start [$w index $start+${c1}c] } ## Next stage, check for procs that start a line set start 1.0 set exp(cmd) "^\"\[^\" \t\n\]+" while { [string compare {} [set ix \ [$w search -regexp -count numc -- $exp(cmd) $start end]]] } { set start [$w index $ix+${numc}c] # +1c to avoid the first quote set cmd [$w get $ix+1c $start] if {[string match *::* $cmd]} { set res [uplevel 1 ::tkcon::EvalOther $app namespace eval \ [list [namespace qualifiers $cmd] \ [list info procs [namespace tail $cmd]]]] } else { set res [uplevel 1 ::tkcon::EvalOther $app info procs [list $cmd]] } if {[llength $res]==1} { set tag [UniqueTag $w] $w tag add $tag $ix+1c $start $w tag configure $tag -foreground $COLOR(proc) $w tag bind $tag [list $w tag configure $tag -under 1] $w tag bind $tag [list $w tag configure $tag -under 0] $w tag bind $tag "if {!\$tkPriv(mouseMoved)} \ {[list edit -attach $app -type proc -- $cmd]}" } } } ## tkcon - command that allows control over the console ## This always exists in the main interpreter, and is aliased into ## other connected interpreters # ARGS: totally variable, see internal comments ## proc tkcon {cmd args} { global errorInfo switch -glob -- $cmd { buf* { ## 'buffer' Sets/Query the buffer size if {[llength $args]} { if {[regexp {^[1-9][0-9]*$} $args]} { set ::tkcon::OPT(buffer) $args # catch in case the console doesn't exist yet catch {::tkcon::ConstrainBuffer $::tkcon::PRIV(console) \ $::tkcon::OPT(buffer)} } else { return -code error "buffer must be a valid integer" } } return $::tkcon::OPT(buffer) } bg* { ## 'bgerror' Brings up an error dialog set errorInfo [lindex $args 1] bgerror [lindex $args 0] } cl* { ## 'close' Closes the console ::tkcon::Destroy } cons* { ## 'console' - passes the args to the text widget of the console. set result [uplevel 1 $::tkcon::PRIV(console) $args] ::tkcon::ConstrainBuffer $::tkcon::PRIV(console) \ $::tkcon::OPT(buffer) return $result } congets { ## 'congets' a replacement for [gets stdin] # Use the 'gets' alias of 'tkcon_gets' command instead of # calling the *get* methods directly for best compatability if {[llength $args] > 1} { return -code error "wrong # args: must be \"tkcon congets [pfix]\"" } tkcon show set old [bind TkConsole <>] bind TkConsole <> { set ::tkcon::PRIV(wait) 0 } set w $::tkcon::PRIV(console) # Make sure to move the limit to get the right data $w mark set insert end if {[llength $args]} { $w mark set limit insert $w insert end $args } else { $w mark set limit insert } $w see end vwait ::tkcon::PRIV(wait) set line [::tkcon::CmdGet $w] $w insert end \n bind TkConsole <> $old return $line } getc* { ## 'getcommand' a replacement for [gets stdin] ## This forces a complete command to be input though if {[llength $args]} { return -code error "wrong # args: must be \"tkcon getcommand\"" } tkcon show set old [bind TkConsole <>] bind TkConsole <> { set ::tkcon::PRIV(wait) 0 } set w $::tkcon::PRIV(console) # Make sure to move the limit to get the right data $w mark set insert end $w mark set limit insert $w see end vwait ::tkcon::PRIV(wait) set line [::tkcon::CmdGet $w] $w insert end \n while {![info complete $line] || [regexp {[^\\]\\$} $line]} { vwait ::tkcon::PRIV(wait) set line [::tkcon::CmdGet $w] $w insert end \n $w see end } bind TkConsole <> $old return $line } get - gets { ## 'gets' - a replacement for [gets stdin] ## This pops up a text widget to be used for stdin (local grabbed) if {[llength $args]} { return -code error "wrong # args: should be \"tkcon gets\"" } set t $::tkcon::PRIV(base).gets if {![winfo exists $t]} { toplevel $t wm withdraw $t wm title $t "tkcon gets stdin request" label $t.gets -text "\"gets stdin\" request:" text $t.data -width 32 -height 5 -wrap none \ -xscrollcommand [list $t.sx set] \ -yscrollcommand [list $t.sy set] scrollbar $t.sx -orient h -takefocus 0 -highlightthick 0 \ -command [list $t.data xview] scrollbar $t.sy -orient v -takefocus 0 -highlightthick 0 \ -command [list $t.data yview] button $t.ok -text "OK" -command {set ::tkcon::PRIV(grab) 1} bind $t.ok { %W invoke } grid $t.gets - -sticky ew grid $t.data $t.sy -sticky news grid $t.sx -sticky ew grid $t.ok - -sticky ew grid columnconfig $t 0 -weight 1 grid rowconfig $t 1 -weight 1 wm transient $t $::tkcon::PRIV(root) wm geometry $t +[expr {([winfo screenwidth $t]-[winfo \ reqwidth $t]) / 2}]+[expr {([winfo \ screenheight $t]-[winfo reqheight $t]) / 2}] } $t.data delete 1.0 end wm deiconify $t raise $t grab $t focus $t.data vwait ::tkcon::PRIV(grab) grab release $t wm withdraw $t return [$t.data get 1.0 end-1c] } err* { ## Outputs stack caused by last error. ## error handling with pizazz (but with pizza would be nice too) if {[llength $args]==2} { set app [lindex $args 0] set type [lindex $args 1] if {[catch {::tkcon::EvalOther $app $type set errorInfo} info]} { set info "error getting info from $type $app:\n$info" } } else { set info $::tkcon::PRIV(errorInfo) } if {[string match {} $info]} { set info "errorInfo empty" } ## If args is empty, the -attach switch just ignores it edit -attach $args -type error -- $info } fi* { ## 'find' string ::tkcon::Find $::tkcon::PRIV(console) $args } fo* { ## 'font' ?fontname? - gets/sets the font of the console if {[llength $args]} { if {[info exists ::tkcon::PRIV(console)] && \ [winfo exists $::tkcon::PRIV(console)]} { $::tkcon::PRIV(console) config -font $args set ::tkcon::OPT(font) [$::tkcon::PRIV(console) cget -font] } else { set ::tkcon::OPT(font) $args } } return $::tkcon::OPT(font) } hid* - with* { ## 'hide' 'withdraw' - hides the console. wm withdraw $::tkcon::PRIV(root) } his* { ## 'history' set sub {\2} if {[string match -new* $args]} { append sub "\n"} set h [::tkcon::EvalSlave history] regsub -all "( *\[0-9\]+ |\t)(\[^\n\]*\n?)" $h $sub h return $h } ico* { ## 'iconify' - iconifies the console with 'iconify'. wm iconify $::tkcon::PRIV(root) } mas* - eval { ## 'master' - evals contents in master interpreter uplevel \#0 $args } set { ## 'set' - set (or get, or unset) simple vars (not whole arrays) ## from the master console interpreter ## possible formats: ## tkcon set ## tkcon set ## tkcon set w ## tkcon set u ## tkcon set r if {[llength $args]==5} { ## This is for use w/ 'tkcon upvar' and only works with slaves foreach {var i var1 var2 op} $args break if {[string compare {} $var2]} { append var1 "($var2)" } switch $op { u { uplevel \#0 [list unset $var] } w { return [uplevel \#0 [list set $var \ [interp eval $i [list set $var1]]]] } r { return [interp eval $i [list set $var1 \ [uplevel \#0 [list set $var]]]] } } } elseif {[llength $args] == 1} { upvar \#0 [lindex $args 0] var if {[array exists var]} { return [array get var] } else { return $var } } return [uplevel \#0 set $args] } append { ## Modify a var in the master environment using append return [uplevel \#0 append $args] } lappend { ## Modify a var in the master environment using lappend return [uplevel \#0 lappend $args] } sh* - dei* { ## 'show|deiconify' - deiconifies the console. wm deiconify $::tkcon::PRIV(root) raise $::tkcon::PRIV(root) focus -force $::tkcon::PRIV(console) } ti* { ## 'title' ?title? - gets/sets the console's title if {[llength $args]} { return [wm title $::tkcon::PRIV(root) [join $args]] } else { return [wm title $::tkcon::PRIV(root)] } } upv* { ## 'upvar' masterVar slaveVar ## link slave variable slaveVar to the master variable masterVar ## only works masters<->slave set masterVar [lindex $args 0] set slaveVar [lindex $args 1] if {[info exists $masterVar]} { interp eval $::tkcon::OPT(exec) \ [list set $slaveVar [set $masterVar]] } else { catch {interp eval $::tkcon::OPT(exec) [list unset $slaveVar]} } interp eval $::tkcon::OPT(exec) \ [list trace variable $slaveVar rwu \ [list tkcon set $masterVar $::tkcon::OPT(exec)]] return } v* { return $::tkcon::PRIV(version) } default { ## tries to determine if the command exists, otherwise throws error set new ::tkcon::[string toupper \ [string index $cmd 0]][string range $cmd 1 end] if {[llength [info command $new]]} { uplevel \#0 $new $args } else { return -code error "bad option \"$cmd\": must be\ [join [lsort [list attach close console destroy \ font hide iconify load main master new save show \ slave deiconify version title bgerror]] {, }]" } } } } ## ## Some procedures to make up for lack of built-in shell commands ## ## tkcon_puts - ## This allows me to capture all stdout/stderr to the console window ## This will be renamed to 'puts' at the appropriate time during init ## # ARGS: same as usual # Outputs: the string with a color-coded text tag ## proc tkcon_puts args { set len [llength $args] foreach {arg1 arg2 arg3} $args { break } if {$len == 1} { set sarg $arg1 set nl 1 set farg stdout } elseif {$len == 2} { if {![string compare $arg1 -nonewline]} { set sarg $arg2 set farg stdout set nl 0 } elseif {![string compare $arg1 stdout] \ || ![string compare $arg1 stderr]} { set sarg $arg2 set farg $arg1 set nl 1 } else { set len 0 } } elseif {$len == 3} { if {![string compare $arg1 -nonewline] \ && (![string compare $arg2 stdout] \ || ![string compare $arg2 stderr])} { set sarg $arg3 set farg $arg2 set nl 0 } elseif {(![string compare $arg1 stdout] \ || ![string compare $arg1 stderr]) \ && ![string compare $arg3 nonewline]} { set sarg $arg2 set farg $arg1 set nl 0 } else { set len 0 } } else { set len 0 } ## $len == 0 means it wasn't handled by tkcon above. ## if {$len != 0} { ## "poor man's" \r substitution---erase everything on the output ## line and print from character after the \r set rpt [string last \r $sarg] if {$rpt >= 0} { tkcon console delete "insert linestart" "insert lineend" set sarg [string range $sarg [expr {$rpt + 1}] end] } set bpt [string first \b $sarg] if {$bpt >= 0} { set narg [string range $sarg [expr {$bpt + 1}] end] set sarg [string range $sarg 0 [expr {$bpt - 1}]] set nl 0 } if {$nl == 0} { tkcon console insert output $sarg $farg } else { tkcon console insert output "$sarg\n" $farg } if {$bpt >= 0} { tkcon console delete "insert -1 char" insert if {$nl == 0} { tkcon_puts $farg $narg nonewline } else { tkcon_puts $farg $narg } } } else { global errorCode errorInfo if {[catch "tkcon_tcl_puts $args" msg]} { regsub tkcon_tcl_puts $msg puts msg regsub -all tkcon_tcl_puts $errorInfo puts errorInfo return -code error $msg } return $msg } ## WARNING: This update should behave well because it uses idletasks, ## however, if there are weird looping problems with events, or ## hanging in waits, try commenting this out. if {$len} { tkcon console see output update idletasks } } ## tkcon_gets - ## This allows me to capture all stdin input without needing to stdin ## This will be renamed to 'gets' at the appropriate time during init ## # ARGS: same as gets # Outputs: same as gets ## proc tkcon_gets args { set len [llength $args] if {$len != 1 && $len != 2} { return -code error \ "wrong # args: should be \"gets channelId ?varName?\"" } if {[string compare stdin [lindex $args 0]]} { return [uplevel 1 tkcon_tcl_gets $args] } set gtype [tkcon set ::tkcon::OPT(gets)] if {$gtype == ""} { set gtype congets } set data [tkcon $gtype] if {$len == 2} { upvar 1 [lindex $args 1] var set var $data return [string length $data] } return $data } ## edit - opens a file/proc/var for reading/editing ## # Arguments: # type proc/file/var # what the actual name of the item # Returns: nothing ## proc edit {args} { array set opts {-find {} -type {} -attach {}} while {[string match -* [lindex $args 0]]} { switch -glob -- [lindex $args 0] { -f* { set opts(-find) [lindex $args 1] } -a* { set opts(-attach) [lindex $args 1] } -t* { set opts(-type) [lindex $args 1] } -- { set args [lreplace $args 0 0]; break } default {return -code error "unknown option \"[lindex $args 0]\""} } set args [lreplace $args 0 1] } # determine who we are dealing with if {[llength $opts(-attach)]} { foreach {app type} $opts(-attach) {break} } else { foreach {app type} [tkcon attach] {break} } set word [lindex $args 0] if {[string match {} $opts(-type)]} { if {[llength [::tkcon::EvalOther $app $type info commands [list $word]]]} { set opts(-type) "proc" } elseif {[llength [::tkcon::EvalOther $app $type info vars [list $word]]]} { set opts(-type) "var" } elseif {[::tkcon::EvalOther $app $type file isfile [list $word]]} { set opts(-type) "file" } } if {[string compare $opts(-type) {}]} { # Create unique edit window toplevel set w $::tkcon::PRIV(base).__edit set i 0 while {[winfo exists $w[incr i]]} {} append w $i toplevel $w wm withdraw $w if {[string length $word] > 12} { wm title $w "tkcon Edit: [string range $word 0 9]..." } else { wm title $w "tkcon Edit: $word" } text $w.text -wrap none \ -xscrollcommand [list $w.sx set] \ -yscrollcommand [list $w.sy set] \ -foreground $::tkcon::COLOR(stdin) \ -background $::tkcon::COLOR(bg) \ -insertbackground $::tkcon::COLOR(cursor) \ -font $::tkcon::OPT(font) scrollbar $w.sx -orient h -takefocus 0 -bd 1 \ -command [list $w.text xview] scrollbar $w.sy -orient v -takefocus 0 -bd 1 \ -command [list $w.text yview] set menu [menu $w.mbar] $w configure -menu $menu ## File Menu ## set m [menu [::tkcon::MenuButton $menu File file]] $m add command -label "Save As..." -underline 0 \ -command [list ::tkcon::Save {} widget $w.text] $m add command -label "Append To..." -underline 0 \ -command [list ::tkcon::Save {} widget $w.text a+] $m add separator $m add command -label "Dismiss" -underline 0 -accel "Ctrl-w" \ -command [list destroy $w] bind $w [list destroy $w] bind $w <$::tkcon::PRIV(meta)-w> [list destroy $w] ## Edit Menu ## set text $w.text set m [menu [::tkcon::MenuButton $menu Edit edit]] $m add command -label "Cut" -under 2 \ -command [list tk_textCut $text] $m add command -label "Copy" -under 0 \ -command [list tk_textCopy $text] $m add command -label "Paste" -under 0 \ -command [list tk_textPaste $text] $m add separator $m add command -label "Find" -under 0 \ -command [list ::tkcon::FindBox $text] ## Send To Menu ## set m [menu [::tkcon::MenuButton $menu "Send To..." send]] $m add command -label "Send To $app" -underline 0 \ -command "::tkcon::EvalOther [list $app] $type \ eval \[$w.text get 1.0 end-1c\]" set other [tkcon attach] if {[string compare $other [list $app $type]]} { $m add command -label "Send To [lindex $other 0]" \ -command "::tkcon::EvalOther $other \ eval \[$w.text get 1.0 end-1c\]" } grid $w.text - $w.sy -sticky news grid $w.sx - -sticky ew grid columnconfigure $w 0 -weight 1 grid columnconfigure $w 1 -weight 1 grid rowconfigure $w 0 -weight 1 } else { return -code error "unrecognized type '$word'" } switch -glob -- $opts(-type) { proc* { $w.text insert 1.0 \ [::tkcon::EvalOther $app $type dump proc [list $word]] } var* { $w.text insert 1.0 \ [::tkcon::EvalOther $app $type dump var [list $word]] } file { $w.text insert 1.0 [::tkcon::EvalOther $app $type eval \ [subst -nocommands { set __tkcon(fid) [open $word r] set __tkcon(data) [read \$__tkcon(fid)] close \$__tkcon(fid) after 1000 unset __tkcon return \$__tkcon(data) } ]] } error* { $w.text insert 1.0 [join $args \n] ::tkcon::ErrorHighlight $w.text } default { $w.text insert 1.0 [join $args \n] } } wm deiconify $w focus $w.text if {[string compare $opts(-find) {}]} { ::tkcon::Find $w.text $opts(-find) -case 1 } } interp alias {} ::more {} ::edit interp alias {} ::less {} ::edit ## echo ## Relaxes the one string restriction of 'puts' # ARGS: any number of strings to output to stdout ## proc echo args { puts [concat $args] } ## clear - clears the buffer of the console (not the history though) ## This is executed in the parent interpreter ## proc clear {{pcnt 100}} { if {![regexp {^[0-9]*$} $pcnt] || $pcnt < 1 || $pcnt > 100} { return -code error \ "invalid percentage to clear: must be 1-100 (100 default)" } elseif {$pcnt == 100} { tkcon console delete 1.0 end } else { set tmp [expr {$pcnt/100.0*[tkcon console index end]}] tkcon console delete 1.0 "$tmp linestart" } } ## alias - akin to the csh alias command ## If called with no args, then it dumps out all current aliases ## If called with one arg, returns the alias of that arg (or {} if none) # ARGS: newcmd - (optional) command to bind alias to # args - command and args being aliased ## proc alias {{newcmd {}} args} { if {[string match {} $newcmd]} { set res {} foreach a [interp aliases] { lappend res [list $a -> [interp alias {} $a]] } return [join $res \n] } elseif {![llength $args]} { interp alias {} $newcmd } else { eval interp alias [list {} $newcmd {}] $args } } ## unalias - unaliases an alias'ed command # ARGS: cmd - command to unbind as an alias ## proc unalias {cmd} { interp alias {} $cmd {} } ## dump - outputs variables/procedure/widget info in source'able form. ## Accepts glob style pattern matching for the names # # ARGS: type - type of thing to dump: must be variable, procedure, widget # # OPTS: -nocomplain # don't complain if no items of the specified type are found # -filter pattern # specifies a glob filter pattern to be used by the variable # method as an array filter pattern (it filters down for # nested elements) and in the widget method as a config # option filter pattern # -- forcibly ends options recognition # # Returns: the values of the requested items in a 'source'able form ## proc dump {type args} { set whine 1 set code ok if {![llength $args]} { ## If no args, assume they gave us something to dump and ## we'll try anything set args $type set type any } while {[string match -* [lindex $args 0]]} { switch -glob -- [lindex $args 0] { -n* { set whine 0; set args [lreplace $args 0 0] } -f* { set fltr [lindex $args 1]; set args [lreplace $args 0 1] } -- { set args [lreplace $args 0 0]; break } default {return -code error "unknown option \"[lindex $args 0]\""} } } if {$whine && ![llength $args]} { return -code error "wrong \# args: [lindex [info level 0] 0] type\ ?-nocomplain? ?-filter pattern? ?--? pattern ?pattern ...?" } set res {} switch -glob -- $type { c* { # command # outputs commands by figuring out, as well as possible, what it is # this does not attempt to auto-load anything foreach arg $args { if {[llength [set cmds [info commands $arg]]]} { foreach cmd [lsort $cmds] { if {[lsearch -exact [interp aliases] $cmd] > -1} { append res "\#\# ALIAS: $cmd =>\ [interp alias {} $cmd]\n" } elseif { [llength [info procs $cmd]] || ([string match *::* $cmd] && [llength [namespace eval [namespace qual $cmd] \ info procs [namespace tail $cmd]]]) } { if {[catch {dump p -- $cmd} msg] && $whine} { set code error } append res $msg\n } else { append res "\#\# COMMAND: $cmd\n" } } } elseif {$whine} { append res "\#\# No known command $arg\n" set code error } } } v* { # variable # outputs variables value(s), whether array or simple. if {![info exists fltr]} { set fltr * } foreach arg $args { if {![llength [set vars [uplevel 1 info vars [list $arg]]]]} { if {[uplevel 1 info exists $arg]} { set vars $arg } elseif {$whine} { append res "\#\# No known variable $arg\n" set code error continue } else { continue } } foreach var [lsort $vars] { if {[uplevel 1 [list info locals $var]] == ""} { # use the proper scope of the var, but # namespace which won't id locals correctly set var [uplevel 1 \ [list namespace which -variable $var]] } upvar 1 $var v if {[array exists v] || [catch {string length $v}]} { set nst {} append res "array set [list $var] \{\n" if {[array size v]} { foreach i [lsort [array names v $fltr]] { upvar 0 v\($i\) __a if {[array exists __a]} { append nst "\#\# NESTED ARRAY ELEM: $i\n" append nst "upvar 0 [list $var\($i\)] __a;\ [dump v -filter $fltr __a]\n" } else { append res " [list $i]\t[list $v($i)]\n" } } } else { ## empty array append res " empty array\n" append nst "unset [list $var](empty)\n" } append res "\}\n$nst" } else { append res [list set $var $v]\n } } } } p* { # procedure foreach arg $args { if { ![llength [set procs [info proc $arg]]] && ([string match *::* $arg] && [llength [set ps [namespace eval \ [namespace qualifier $arg] \ info procs [namespace tail $arg]]]]) } { set procs {} set namesp [namespace qualifier $arg] foreach p $ps { lappend procs ${namesp}::$p } } if {[llength $procs]} { foreach p [lsort $procs] { set as {} foreach a [info args $p] { if {[info default $p $a tmp]} { lappend as [list $a $tmp] } else { lappend as $a } } append res [list proc $p $as [info body $p]]\n } } elseif {$whine} { append res "\#\# No known proc $arg\n" set code error } } } w* { # widget ## The user should have Tk loaded if {![llength [info command winfo]]} { return -code error "winfo not present, cannot dump widgets" } if {![info exists fltr]} { set fltr .* } foreach arg $args { if {[llength [set ws [info command $arg]]]} { foreach w [lsort $ws] { if {[winfo exists $w]} { if {[catch {$w configure} cfg]} { append res "\#\# Widget $w\ does not support configure method" set code error } else { append res "\#\# [winfo class $w]\ $w\n$w configure" foreach c $cfg { if {[llength $c] != 5} continue ## Check to see that the option does ## not match the default, then check ## the item against the user filter if {[string compare [lindex $c 3] \ [lindex $c 4]] && \ [regexp -nocase -- $fltr $c]} { append res " \\\n\t[list [lindex $c 0]\ [lindex $c 4]]" } } append res \n } } } } elseif {$whine} { append res "\#\# No known widget $arg\n" set code error } } } a* { ## see if we recognize it, other complain if {[regexp {(var|com|proc|widget)} \ [set types [uplevel 1 what $args]]]} { foreach type $types { if {[regexp {(var|com|proc|widget)} $type]} { append res "[uplevel 1 dump $type $args]\n" } } } else { set res "dump was unable to resolve type for \"$args\"" set code error } } default { return -code error "bad [lindex [info level 0] 0] option\ \"$type\": must be variable, command, procedure,\ or widget" } } return -code $code [string trimright $res \n] } ## idebug - interactive debugger # # idebug body ?level? # # Prints out the body of the command (if it is a procedure) at the # specified level. level defaults to the current level. # # idebug break # # Creates a breakpoint within a procedure. This will only trigger # if idebug is on and the id matches the pattern. If so, TkCon will # pop to the front with the prompt changed to an idebug prompt. You # are given the basic ability to observe the call stack an query/set # variables or execute Tcl commands at any level. A separate history # is maintained in debugging mode. # # idebug echo|{echo ?id?} ?args? # # Behaves just like "echo", but only triggers when idebug is on. # You can specify an optional id to further restrict triggering. # If no id is specified, it defaults to the name of the command # in which the call was made. # # idebug id ?id? # # Query or set the idebug id. This id is used by other idebug # methods to determine if they should trigger or not. The idebug # id can be a glob pattern and defaults to *. # # idebug off # # Turns idebug off. # # idebug on ?id? # # Turns idebug on. If 'id' is specified, it sets the id to it. # # idebug puts|{puts ?id?} args # # Behaves just like "puts", but only triggers when idebug is on. # You can specify an optional id to further restrict triggering. # If no id is specified, it defaults to the name of the command # in which the call was made. # # idebug show type ?level? ?VERBOSE? # # 'type' must be one of vars, locals or globals. This method # will output the variables/locals/globals present in a particular # level. If VERBOSE is added, then it actually 'dump's out the # values as well. 'level' defaults to the level in which this # method was called. # # idebug trace ?level? # # Prints out the stack trace from the specified level up to the top # level. 'level' defaults to the current level. # ## proc idebug {opt args} { global IDEBUG if {![info exists IDEBUG(on)]} { array set IDEBUG { on 0 id * debugging 0 } } set level [expr {[info level]-1}] switch -glob -- $opt { on { if {[llength $args]} { set IDEBUG(id) $args } return [set IDEBUG(on) 1] } off { return [set IDEBUG(on) 0] } id { if {![llength $args]} { return $IDEBUG(id) } else { return [set IDEBUG(id) $args] } } break { if {!$IDEBUG(on) || $IDEBUG(debugging) || \ ([llength $args] && \ ![string match $IDEBUG(id) $args]) || [info level]<1} { return } set IDEBUG(debugging) 1 puts stderr "idebug at level \#$level: [lindex [info level -1] 0]" set tkcon [llength [info command tkcon]] if {$tkcon} { tkcon master eval set ::tkcon::OPT(prompt2) \$::tkcon::OPT(prompt1) tkcon master eval set ::tkcon::OPT(prompt1) \$::tkcon::OPT(debugPrompt) set slave [tkcon set ::tkcon::OPT(exec)] set event [tkcon set ::tkcon::PRIV(event)] tkcon set ::tkcon::OPT(exec) [tkcon master interp create debugger] tkcon set ::tkcon::PRIV(event) 1 } set max $level while 1 { set err {} if {$tkcon} { # tkcon's overload of gets is advanced enough to not need # this, but we get a little better control this way. tkcon evalSlave set level $level tkcon prompt set line [tkcon getcommand] tkcon console mark set output end } else { puts -nonewline stderr "(level \#$level) debug > " gets stdin line while {![info complete $line]} { puts -nonewline "> " append line "\n[gets stdin]" } } if {[string match {} $line]} continue set key [lindex $line 0] if {![regexp {^([#-]?[0-9]+)} [lreplace $line 0 0] lvl]} { set lvl \#$level } set res {}; set c 0 switch -- $key { + { ## Allow for jumping multiple levels if {$level < $max} { idebug trace [incr level] $level 0 VERBOSE } } - { ## Allow for jumping multiple levels if {$level > 1} { idebug trace [incr level -1] $level 0 VERBOSE } } . { set c [catch {idebug trace $level $level 0 VERBOSE} res] } v { set c [catch {idebug show vars $lvl } res] } V { set c [catch {idebug show vars $lvl VERBOSE} res] } l { set c [catch {idebug show locals $lvl } res] } L { set c [catch {idebug show locals $lvl VERBOSE} res] } g { set c [catch {idebug show globals $lvl } res] } G { set c [catch {idebug show globals $lvl VERBOSE} res] } t { set c [catch {idebug trace 1 $max $level } res] } T { set c [catch {idebug trace 1 $max $level VERBOSE} res]} b { set c [catch {idebug body $lvl} res] } o { set res [set IDEBUG(on) [expr {!$IDEBUG(on)}]] } h - ? { puts stderr " + Move down in call stack - Move up in call stack . Show current proc name and params v Show names of variables currently in scope V Show names of variables currently in scope with values l Show names of local (transient) variables L Show names of local (transient) variables with values g Show names of declared global variables G Show names of declared global variables with values t Show a stack trace T Show a verbose stack trace b Show body of current proc o Toggle on/off any further debugging c,q Continue regular execution (Quit debugger) h,? Print this help default Evaluate line at current level (\#$level)" } c - q break default { set c [catch {uplevel \#$level $line} res] } } if {$tkcon} { tkcon set ::tkcon::PRIV(event) \ [tkcon evalSlave eval history add [list $line]\ \; history nextid] } if {$c} { puts stderr $res } elseif {[string compare {} $res]} { puts $res } } set IDEBUG(debugging) 0 if {$tkcon} { tkcon master interp delete debugger tkcon master eval set ::tkcon::OPT(prompt1) \$::tkcon::OPT(prompt2) tkcon set ::tkcon::OPT(exec) $slave tkcon set ::tkcon::PRIV(event) $event tkcon prompt } } bo* { if {[regexp {^([#-]?[0-9]+)} $args level]} { return [uplevel $level {dump c -no [lindex [info level 0] 0]}] } } t* { if {[llength $args]<2} return set min [set max [set lvl $level]] set exp {^#?([0-9]+)? ?#?([0-9]+) ?#?([0-9]+)? ?(VERBOSE)?} if {![regexp $exp $args junk min max lvl verbose]} return for {set i $max} { $i>=$min && ![catch {uplevel \#$i info level 0} info] } {incr i -1} { if {$i==$lvl} { puts -nonewline stderr "* \#$i:\t" } else { puts -nonewline stderr " \#$i:\t" } set name [lindex $info 0] if {[string compare VERBOSE $verbose] || \ ![llength [info procs $name]]} { puts $info } else { puts "proc $name {[info args $name]} { ... }" set idx 0 foreach arg [info args $name] { if {[string match args $arg]} { puts "\t$arg = [lrange $info [incr idx] end]" break } else { puts "\t$arg = [lindex $info [incr idx]]" } } } } } s* { #var, local, global set level \#$level if {![regexp {^([vgl][^ ]*) ?([#-]?[0-9]+)? ?(VERBOSE)?} \ $args junk type level verbose]} return switch -glob -- $type { v* { set vars [uplevel $level {lsort [info vars]}] } l* { set vars [uplevel $level {lsort [info locals]}] } g* { set vars [lremove [uplevel $level {info vars}] \ [uplevel $level {info locals}]] } } if {[string match VERBOSE $verbose]} { return [uplevel $level dump var -nocomplain $vars] } else { return $vars } } e* - pu* { if {[llength $opt]==1 && [catch {lindex [info level -1] 0} id]} { set id [lindex [info level 0] 0] } else { set id [lindex $opt 1] } if {$IDEBUG(on) && [string match $IDEBUG(id) $id]} { if {[string match e* $opt]} { puts [concat $args] } else { eval puts $args } } } default { return -code error "bad [lindex [info level 0] 0] option \"$opt\",\ must be: [join [lsort [list on off id break print body\ trace show puts echo]] {, }]" } } } ## observe - like trace, but not # ARGS: opt - option # name - name of variable or command ## proc observe {opt name args} { global tcl_observe switch -glob -- $opt { co* { if {[regexp {^(catch|lreplace|set|puts|for|incr|info|uplevel)$} \ $name]} { return -code error "cannot observe \"$name\":\ infinite eval loop will occur" } set old ${name}@ while {[llength [info command $old]]} { append old @ } rename $name $old set max 4 regexp {^[0-9]+} $args max ## idebug trace could be used here proc $name args " for {set i \[info level\]; set max \[expr \[info level\]-$max\]} { \$i>=\$max && !\[catch {uplevel \#\$i info level 0} info\] } {incr i -1} { puts -nonewline stderr \" \#\$i:\t\" puts \$info } uplevel \[lreplace \[info level 0\] 0 0 $old\] " set tcl_observe($name) $old } cd* { if {[info exists tcl_observe($name)] && [catch { rename $name {} rename $tcl_observe($name) $name unset tcl_observe($name) } err]} { return -code error $err } } ci* { ## What a useless method... if {[info exists tcl_observe($name)]} { set i $tcl_observe($name) set res "\"$name\" observes true command \"$i\"" while {[info exists tcl_observe($i)]} { append res "\n\"$name\" observes true command \"$i\"" set i $tcl_observe($name) } return $res } } va* - vd* { set type [lindex $args 0] set args [lrange $args 1 end] if {![regexp {^[rwu]} $type type]} { return -code error "bad [lindex [info level 0] 0] $opt type\ \"$type\", must be: read, write or unset" } if {![llength $args]} { set args observe_var } uplevel 1 [list trace $opt $name $type $args] } vi* { uplevel 1 [list trace vinfo $name] } default { return -code error "bad [lindex [info level 0] 0] option\ \"[lindex $args 0]\", must be: [join [lsort \ [list command cdelete cinfo variable vdelete vinfo]] {, }]" } } } ## observe_var - auxilary function for observing vars, called by trace ## via observe # ARGS: name - variable name # el - array element name, if any # op - operation type (rwu) ## proc observe_var {name el op} { if {[string match u $op]} { if {[string compare {} $el]} { puts "unset \"${name}($el)\"" } else { puts "unset \"$name\"" } } else { upvar 1 $name $name if {[info exists ${name}($el)]} { puts [dump v ${name}($el)] } else { puts [dump v $name] } } } ## which - tells you where a command is found # ARGS: cmd - command name # Returns: where command is found (internal / external / unknown) ## proc which cmd { ## This tries to auto-load a command if not recognized set types [uplevel 1 [list what $cmd 1]] if {[llength $types]} { set out {} foreach type $types { switch -- $type { alias { set res "$cmd: aliased to [alias $cmd]" } procedure { set res "$cmd: procedure" } command { set res "$cmd: internal command" } executable { lappend out [auto_execok $cmd] } variable { lappend out "$cmd: $type" } } if {[info exists res]} { global auto_index if {[info exists auto_index($cmd)]} { ## This tells you where the command MIGHT have come from - ## not true if the command was redefined interactively or ## existed before it had to be auto_loaded. This is just ## provided as a hint at where it MAY have come from append res " ($auto_index($cmd))" } lappend out $res unset res } } return [join $out \n] } else { return -code error "$cmd: command not found" } } ## what - tells you what a string is recognized as # ARGS: str - string to id # Returns: id types of command as list ## proc what {str {autoload 0}} { set types {} if {[llength [info commands $str]] || ($autoload && \ [auto_load $str] && [llength [info commands $str]])} { if {[lsearch -exact [interp aliases] $str] > -1} { lappend types "alias" } elseif { [llength [info procs $str]] || ([string match *::* $str] && [llength [namespace eval [namespace qualifier $str] \ info procs [namespace tail $str]]]) } { lappend types "procedure" } else { lappend types "command" } } if {[llength [uplevel 1 info vars $str]]} { upvar 1 $str var if {[array exists var]} { lappend types array variable } else { lappend types scalar variable } } if {[file isdirectory $str]} { lappend types "directory" } if {[file isfile $str]} { lappend types "file" } if {[llength [info commands winfo]] && [winfo exists $str]} { lappend types "widget" } if {[string compare {} [auto_execok $str]]} { lappend types "executable" } return $types } ## dir - directory list # ARGS: args - names/glob patterns of directories to list # OPTS: -all - list hidden files as well (Unix dot files) # -long - list in full format "permissions size date filename" # -full - displays / after directories and link paths for links # Returns: a directory listing ## proc dir {args} { array set s { all 0 full 0 long 0 0 --- 1 --x 2 -w- 3 -wx 4 r-- 5 r-x 6 rw- 7 rwx } while {[string match \-* [lindex $args 0]]} { set str [lindex $args 0] set args [lreplace $args 0 0] switch -glob -- $str { -a* {set s(all) 1} -f* {set s(full) 1} -l* {set s(long) 1} -- break default { return -code error "unknown option \"$str\",\ should be one of: -all, -full, -long" } } } set sep [string trim [file join . .] .] if {![llength $args]} { set args . } if {$::tcl_version >= 8.3} { # Newer glob args allow safer dir processing. The user may still # want glob chars, but really only for file matching. foreach arg $args { if {[file isdirectory $arg]} { if {$s(all)} { lappend out [list $arg [lsort \ [glob -nocomplain -directory $arg .* *]]] } else { lappend out [list $arg [lsort \ [glob -nocomplain -directory $arg *]]] } } else { set dir [file dirname $arg] lappend out [list $dir$sep [lsort \ [glob -nocomplain -directory $dir [file tail $arg]]]] } } } else { foreach arg $args { if {[file isdirectory $arg]} { set arg [string trimright $arg $sep]$sep if {$s(all)} { lappend out [list $arg [lsort [glob -nocomplain -- $arg.* $arg*]]] } else { lappend out [list $arg [lsort [glob -nocomplain -- $arg*]]] } } else { lappend out [list [file dirname $arg]$sep \ [lsort [glob -nocomplain -- $arg]]] } } } if {$s(long)} { set old [clock scan {1 year ago}] set fmt "%s%9d %s %s\n" foreach o $out { set d [lindex $o 0] append res $d:\n foreach f [lindex $o 1] { file lstat $f st set f [file tail $f] if {$s(full)} { switch -glob $st(type) { d* { append f $sep } l* { append f "@ -> [file readlink $d$sep$f]" } default { if {[file exec $d$sep$f]} { append f * } } } } if {[string match file $st(type)]} { set mode - } else { set mode [string index $st(type) 0] } foreach j [split [format %03o [expr {$st(mode)&0777}]] {}] { append mode $s($j) } if {$st(mtime)>$old} { set cfmt {%b %d %H:%M} } else { set cfmt {%b %d %Y} } append res [format $fmt $mode $st(size) \ [clock format $st(mtime) -format $cfmt] $f] } append res \n } } else { foreach o $out { set d [lindex $o 0] append res "$d:\n" set i 0 foreach f [lindex $o 1] { if {[string len [file tail $f]] > $i} { set i [string len [file tail $f]] } } set i [expr {$i+2+$s(full)}] set j 80 ## This gets the number of cols in the tkcon console widget if {[llength [info commands tkcon]]} { set j [expr {[tkcon master set ::tkcon::OPT(cols)]/$i}] } set k 0 foreach f [lindex $o 1] { set f [file tail $f] if {$s(full)} { switch -glob [file type $d$sep$f] { d* { append f $sep } l* { append f @ } default { if {[file exec $d$sep$f]} { append f * } } } } append res [format "%-${i}s" $f] if {$j == 0 || [incr k]%$j == 0} { set res [string trimright $res]\n } } append res \n\n } } return [string trimright $res] } interp alias {} ::ls {} ::dir -full ## lremove - remove items from a list # OPTS: # -all remove all instances of each item # -glob remove all instances matching glob pattern # -regexp remove all instances matching regexp pattern # ARGS: l a list to remove items from # args items to remove (these are 'join'ed together) ## proc lremove {args} { array set opts {-all 0 pattern -exact} while {[string match -* [lindex $args 0]]} { switch -glob -- [lindex $args 0] { -a* { set opts(-all) 1 } -g* { set opts(pattern) -glob } -r* { set opts(pattern) -regexp } -- { set args [lreplace $args 0 0]; break } default {return -code error "unknown option \"[lindex $args 0]\""} } set args [lreplace $args 0 0] } set l [lindex $args 0] foreach i [join [lreplace $args 0 0]] { if {[set ix [lsearch $opts(pattern) $l $i]] == -1} continue set l [lreplace $l $ix $ix] if {$opts(-all)} { while {[set ix [lsearch $opts(pattern) $l $i]] != -1} { set l [lreplace $l $ix $ix] } } } return $l } if {!$::tkcon::PRIV(WWW)} {; ## Unknown changed to get output into tkcon window # unknown: # Invoked automatically whenever an unknown command is encountered. # Works through a list of "unknown handlers" that have been registered # to deal with unknown commands. Extensions can integrate their own # handlers into the 'unknown' facility via 'unknown_handler'. # # If a handler exists that recognizes the command, then it will # take care of the command action and return a valid result or a # Tcl error. Otherwise, it should return "-code continue" (=2) # and responsibility for the command is passed to the next handler. # # Arguments: # args - A list whose elements are the words of the original # command, including the command name. proc unknown args { global unknown_handler_order unknown_handlers errorInfo errorCode # # Be careful to save error info now, and restore it later # for each handler. Some handlers generate their own errors # and disrupt handling. # set savedErrorCode $errorCode set savedErrorInfo $errorInfo if {![info exists unknown_handler_order] || \ ![info exists unknown_handlers]} { set unknown_handlers(tcl) tcl_unknown set unknown_handler_order tcl } foreach handler $unknown_handler_order { set status [catch {uplevel 1 $unknown_handlers($handler) $args} result] if {$status == 1} { # # Strip the last five lines off the error stack (they're # from the "uplevel" command). # set new [split $errorInfo \n] set new [join [lrange $new 0 [expr {[llength $new]-6}]] \n] return -code $status -errorcode $errorCode \ -errorinfo $new $result } elseif {$status != 4} { return -code $status $result } set errorCode $savedErrorCode set errorInfo $savedErrorInfo } set name [lindex $args 0] return -code error "invalid command name \"$name\"" } # tcl_unknown: # Invoked when a Tcl command is invoked that doesn't exist in the # interpreter: # # 1. See if the autoload facility can locate the command in a # Tcl script file. If so, load it and execute it. # 2. If the command was invoked interactively at top-level: # (a) see if the command exists as an executable UNIX program. # If so, "exec" the command. # (b) see if the command requests csh-like history substitution # in one of the common forms !!, !, or ^old^new. If # so, emulate csh's history substitution. # (c) see if the command is a unique abbreviation for another # command. If so, invoke the command. # # Arguments: # args - A list whose elements are the words of the original # command, including the command name. proc tcl_unknown args { global auto_noexec auto_noload env unknown_pending tcl_interactive global errorCode errorInfo # If the command word has the form "namespace inscope ns cmd" # then concatenate its arguments onto the end and evaluate it. set cmd [lindex $args 0] if {[regexp "^namespace\[ \t\n\]+inscope" $cmd] && [llength $cmd] == 4} { set arglist [lrange $args 1 end] set ret [catch {uplevel 1 $cmd $arglist} result] if {$ret == 0} { return $result } else { return -code $ret -errorcode $errorCode $result } } # CAD tools special: # Check for commands which were renamed to tcl_(command) if {[lsearch [info commands] tcl_$cmd] >= 0} { set arglist [concat tcl_$cmd [lrange $args 1 end]] set ret [catch {eval $arglist} result] if {$ret == 0} { return $result } else { return -code $ret -errorcode $errorCode $result } } # Save the values of errorCode and errorInfo variables, since they # may get modified if caught errors occur below. The variables will # be restored just before re-executing the missing command. set savedErrorCode $errorCode set savedErrorInfo $errorInfo set name [lindex $args 0] if {![info exists auto_noload]} { # # Make sure we're not trying to load the same proc twice. # if {[info exists unknown_pending($name)]} { return -code error "self-referential recursion in \"unknown\" for command \"$name\"" } set unknown_pending($name) pending if {[llength [info args auto_load]]==1} { set ret [catch {auto_load $name} msg] } else { set ret [catch {auto_load $name [uplevel 1 {namespace current}]} msg] } unset unknown_pending($name) if {$ret} { return -code $ret -errorcode $errorCode \ "error while autoloading \"$name\": $msg" } # # Avoid problems with renaming "array"! (for tcl-based magic only) # set arraycmd array if {[lsearch [info commands] tcl_array] >= 0} {set arraycmd tcl_array} if {![$arraycmd size unknown_pending]} { unset unknown_pending } if {$msg} { set errorCode $savedErrorCode set errorInfo $savedErrorInfo set code [catch {uplevel 1 $args} msg] if {$code == 1} { # # Strip the last five lines off the error stack (they're # from the "uplevel" command). # set new [split $errorInfo \n] set new [join [lrange $new 0 [expr {[llength $new]-6}]] \n] return -code error -errorcode $errorCode \ -errorinfo $new $msg } else { return -code $code $msg } } } if {[info level] == 1 && [string match {} [info script]] \ && [info exists tcl_interactive] && $tcl_interactive} { if {![info exists auto_noexec]} { set new [auto_execok $name] if {[string compare {} $new]} { set errorCode $savedErrorCode set errorInfo $savedErrorInfo return [uplevel 1 exec $new [lrange $args 1 end]] #return [uplevel exec >&@stdout <@stdin $new [lrange $args 1 end]] } } set errorCode $savedErrorCode set errorInfo $savedErrorInfo ## ## History substitution moved into ::tkcon::EvalCmd ## set ret [catch {set cmds [info commands $name*]} msg] if {[string compare $name "::"] == 0} { set name "" } if {$ret != 0} { return -code $ret -errorcode $errorCode \ "error in unknown while checking if \"$name\" is a unique command abbreviation: $msg" } set cmds [info commands $name*] if {[llength $cmds] == 1} { return [uplevel 1 [lreplace $args 0 0 $cmds]] } if {[llength $cmds]} { if {$name == ""} { return -code error "empty command name \"\"" } else { return -code error \ "ambiguous command name \"$name\": [lsort $cmds]" } } ## We've got nothing so far ## Check and see if Tk wasn't loaded, but it appears to be a Tk cmd if {![uplevel \#0 info exists tk_version]} { lappend tkcmds bell bind bindtags button \ canvas checkbutton clipboard destroy \ entry event focus font frame grab grid image \ label listbox lower menu menubutton message \ option pack place radiobutton raise \ scale scrollbar selection send spinbox \ text tk tkwait toplevel winfo wm if {[lsearch -exact $tkcmds $name] >= 0 && \ [tkcon master tk_messageBox -icon question -parent . \ -title "Load Tk?" -type retrycancel -default retry \ -message "This appears to be a Tk command, but Tk\ has not yet been loaded. Shall I retry the command\ with loading Tk first?"] == "retry"} { return [uplevel 1 "load {} Tk; $args"] } } } return -code continue } } ; # end exclusionary code for WWW proc ::tkcon::Bindings {} { variable PRIV global tcl_platform tk_version #----------------------------------------------------------------------- # Elements of tkPriv that are used in this file: # # char - Character position on the line; kept in order # to allow moving up or down past short lines while # still remembering the desired position. # mouseMoved - Non-zero means the mouse has moved a significant # amount since the button went down (so, for example, # start dragging out a selection). # prevPos - Used when moving up or down lines via the keyboard. # Keeps track of the previous insert position, so # we can distinguish a series of ups and downs, all # in a row, from a new up or down. # selectMode - The style of selection currently underway: # char, word, or line. # x, y - Last known mouse coordinates for scanning # and auto-scanning. #----------------------------------------------------------------------- switch -glob $tcl_platform(platform) { win* { set PRIV(meta) Alt } mac* { set PRIV(meta) Command } default { set PRIV(meta) Meta } } ## Get all Text bindings into TkConsole foreach ev [bind Text] { bind TkConsole $ev [bind Text $ev] } ## We really didn't want the newline insertion bind TkConsole {} ## in 8.6b3, the virtual events <> and <> # mess up our history feature bind TkConsole <> {} bind TkConsole <> {} ## Now make all our virtual event bindings foreach {ev key} [subst -nocommand -noback { <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <$PRIV(meta)-i> <> <> <$PRIV(meta)-o> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> }] { event add $ev $key ## Make sure the specific key won't be defined bind TkConsole $key {} } ## Make the ROOT bindings bind $PRIV(root) <> exit bind $PRIV(root) <> { ::tkcon::New } bind $PRIV(root) <> { ::tkcon::Destroy } bind $PRIV(root) <> { ::tkcon::About } bind $PRIV(root) <> { ::tkcon::Help } bind $PRIV(root) <> { ::tkcon::FindBox $::tkcon::PRIV(console) } bind $PRIV(root) <> { ::tkcon::Attach {} ::tkcon::Prompt "\n" [::tkcon::CmdGet $::tkcon::PRIV(console)] } bind $PRIV(root) <> { if {[string compare {} $::tkcon::PRIV(name)]} { ::tkcon::Attach $::tkcon::PRIV(name) } else { ::tkcon::Attach Main } ::tkcon::Prompt "\n" [::tkcon::CmdGet $::tkcon::PRIV(console)] } bind $PRIV(root) <> { ::tkcon::Attach Main ::tkcon::Prompt "\n" [::tkcon::CmdGet $::tkcon::PRIV(console)] } bind $PRIV(root) <> { ::tkcon::PopupMenu %X %Y } ## Menu items need null TkConsolePost bindings to avoid the TagProc ## foreach ev [bind $PRIV(root)] { bind TkConsolePost $ev { # empty } } # ::tkcon::ClipboardKeysyms -- # This procedure is invoked to identify the keys that correspond to # the copy, cut, and paste functions for the clipboard. # # Arguments: # copy - Name of the key (keysym name plus modifiers, if any, # such as "Meta-y") used for the copy operation. # cut - Name of the key used for the cut operation. # paste - Name of the key used for the paste operation. proc ::tkcon::ClipboardKeysyms {copy cut paste} { bind TkConsole <$copy> {::tkcon::Copy %W} bind TkConsole <$cut> {::tkcon::Cut %W} bind TkConsole <$paste> {::tkcon::Paste %W} } proc ::tkcon::GetSelection {w} { if { ![catch {selection get -displayof $w -type UTF8_STRING} txt] || ![catch {selection get -displayof $w} txt] || ![catch {selection get -displayof $w -selection CLIPBOARD} txt] } { return $txt } return -code error "could not find default selection" } proc ::tkcon::Cut w { if {[string match $w [selection own -displayof $w]]} { clipboard clear -displayof $w catch { set txt [selection get -displayof $w] clipboard append -displayof $w $txt if {[$w compare sel.first >= limit]} { $w delete sel.first sel.last } } } } proc ::tkcon::Copy w { if {[string match $w [selection own -displayof $w]]} { clipboard clear -displayof $w catch { set txt [selection get -displayof $w] clipboard append -displayof $w $txt } } } proc ::tkcon::Paste w { if {![catch {GetSelection $w} txt]} { if {[$w compare insert < limit]} { $w mark set insert end } $w insert insert $txt $w see insert if {[string match *\n* $txt]} { ::tkcon::Eval $w } } } ## Redefine for TkConsole what we need ## event delete <> ::tkcon::ClipboardKeysyms bind TkConsole { catch { ::tkcon::Insert %W [::tkcon::GetSelection %W] } } bind TkConsole {+ catch { eval %W tag remove sel [%W tag nextrange prompt sel.first sel.last] eval %W tag remove sel sel.last-1c %W mark set insert sel.first } } ## binding editor needed ## binding for .tkconrc bind TkConsole <> { if {[%W compare insert > limit]} {::tkcon::Expand %W path} break } bind TkConsole <> { if {[%W compare insert > limit]} {::tkcon::Expand %W proc} } bind TkConsole <> { if {[%W compare insert > limit]} {::tkcon::Expand %W var} } bind TkConsole <> { if {[%W compare insert > limit]} {::tkcon::Expand %W} } bind TkConsole <> { if {[%W compare insert >= limit]} { ::tkcon::Insert %W \t } } bind TkConsole <> { if {[%W compare insert >= limit]} { ::tkcon::Insert %W \n } } bind TkConsole <> { ::tkcon::Eval %W } bind TkConsole { if {[llength [%W tag nextrange sel 1.0 end]] \ && [%W compare sel.first >= limit]} { %W delete sel.first sel.last } elseif {[%W compare insert >= limit]} { %W delete insert %W see insert } } bind TkConsole { if {[llength [%W tag nextrange sel 1.0 end]] \ && [%W compare sel.first >= limit]} { %W delete sel.first sel.last } elseif {[%W compare insert != 1.0] && [%W compare insert > limit]} { %W delete insert-1c %W see insert } } bind TkConsole [bind TkConsole ] bind TkConsole { ::tkcon::Insert %W %A } bind TkConsole { if {[%W compare {limit linestart} == {insert linestart}]} { tkTextSetCursor %W limit } else { tkTextSetCursor %W {insert linestart} } } bind TkConsole [bind TkConsole ] bind TkConsole { if {[%W compare insert < limit]} break %W delete insert } bind TkConsole { if {[%W compare insert < limit]} break if {[%W compare insert == {insert lineend}]} { %W delete insert } else { %W delete insert {insert lineend} } } bind TkConsole <> { ## Clear console buffer, without losing current command line input set ::tkcon::PRIV(tmp) [::tkcon::CmdGet %W] clear ::tkcon::Prompt {} $::tkcon::PRIV(tmp) } bind TkConsole <> { if {[%W compare {insert linestart} != {limit linestart}]} { tkTextSetCursor %W [tkTextUpDownLine %W -1] } else { ::tkcon::Event -1 } } bind TkConsole <> { if {[%W compare {insert linestart} != {end-1c linestart}]} { tkTextSetCursor %W [tkTextUpDownLine %W 1] } else { ::tkcon::Event 1 } } bind TkConsole <> { ::tkcon::Event 1 } bind TkConsole <> { ::tkcon::Event -1 } bind TkConsole <> { ::tkcon::Event -1 [::tkcon::CmdGet %W] } bind TkConsole <> { ::tkcon::Event 1 [::tkcon::CmdGet %W] } bind TkConsole <> { ## Transpose current and previous chars if {[%W compare insert > "limit+1c"]} { tkTextTranspose %W } } bind TkConsole <> { ## Clear command line (Unix shell staple) %W delete limit end } bind TkConsole <> { ## Save command buffer (swaps with current command) set ::tkcon::PRIV(tmp) $::tkcon::PRIV(cmdsave) set ::tkcon::PRIV(cmdsave) [::tkcon::CmdGet %W] if {[string match {} $::tkcon::PRIV(cmdsave)]} { set ::tkcon::PRIV(cmdsave) $::tkcon::PRIV(tmp) } else { %W delete limit end-1c } ::tkcon::Insert %W $::tkcon::PRIV(tmp) %W see end } catch {bind TkConsole { tkTextScrollPages %W -1 }} catch {bind TkConsole { tkTextScrollPages %W -1 }} catch {bind TkConsole { tkTextScrollPages %W 1 }} catch {bind TkConsole { tkTextScrollPages %W 1 }} bind TkConsole <$PRIV(meta)-d> { if {[%W compare insert >= limit]} { %W delete insert {insert wordend} } } bind TkConsole <$PRIV(meta)-BackSpace> { if {[%W compare {insert -1c wordstart} >= limit]} { %W delete {insert -1c wordstart} insert } } bind TkConsole <$PRIV(meta)-Delete> { if {[%W compare insert >= limit]} { %W delete insert {insert wordend} } } bind TkConsole { if { (!$tkPriv(mouseMoved) || $tk_strictMotif) && ![catch {::tkcon::GetSelection %W} ::tkcon::PRIV(tmp)] } { if {[%W compare @%x,%y < limit]} { %W insert end $::tkcon::PRIV(tmp) } else { %W insert @%x,%y $::tkcon::PRIV(tmp) } if {[string match *\n* $::tkcon::PRIV(tmp)]} {::tkcon::Eval %W} } } ## ## End TkConsole bindings ## ## ## Bindings for doing special things based on certain keys ## bind TkConsolePost { if {$::tkcon::OPT(lightbrace) && $::tkcon::OPT(blinktime)>99 && \ [string compare \\ [%W get insert-2c]]} { ::tkcon::MatchPair %W \( \) limit } set ::tkcon::PRIV(StatusCursor) [%W index insert] } bind TkConsolePost { if {$::tkcon::OPT(lightbrace) && $::tkcon::OPT(blinktime)>99 && \ [string compare \\ [%W get insert-2c]]} { ::tkcon::MatchPair %W \[ \] limit } set ::tkcon::PRIV(StatusCursor) [%W index insert] } bind TkConsolePost { if {$::tkcon::OPT(lightbrace) && $::tkcon::OPT(blinktime)>99 && \ [string compare \\ [%W get insert-2c]]} { ::tkcon::MatchPair %W \{ \} limit } set ::tkcon::PRIV(StatusCursor) [%W index insert] } bind TkConsolePost { if {$::tkcon::OPT(lightbrace) && $::tkcon::OPT(blinktime)>99 && \ [string compare \\ [%W get insert-2c]]} { ::tkcon::MatchQuote %W limit } set ::tkcon::PRIV(StatusCursor) [%W index insert] } bind TkConsolePost { if {$::tkcon::OPT(lightcmd) && [string compare {} %A]} { ::tkcon::TagProc %W } set ::tkcon::PRIV(StatusCursor) [%W index insert] } bind TkConsolePost { set ::tkcon::PRIV(StatusCursor) [%W index insert] } bind TkConsolePost { set ::tkcon::PRIV(StatusCursor) [%W index insert] } } ## # ::tkcon::PopupMenu - what to do when the popup menu is requested ## proc ::tkcon::PopupMenu {X Y} { variable PRIV set w $PRIV(console) if {[string compare $w [winfo containing $X $Y]]} { tk_popup $PRIV(popup) $X $Y return } set x [expr {$X-[winfo rootx $w]}] set y [expr {$Y-[winfo rooty $w]}] if {[llength [set tags [$w tag names @$x,$y]]]} { if {[lsearch -exact $tags "proc"] >= 0} { lappend type "proc" foreach {first last} [$w tag prevrange proc @$x,$y] { set word [$w get $first $last]; break } } if {[lsearch -exact $tags "var"] >= 0} { lappend type "var" foreach {first last} [$w tag prevrange var @$x,$y] { set word [$w get $first $last]; break } } } if {![info exists type]} { set exp "(^|\[^\\\\\]\[ \t\n\r\])" set exp2 "\[\[\\\\\\?\\*\]" set i [$w search -backwards -regexp $exp @$x,$y "@$x,$y linestart"] if {[string compare {} $i]} { if {![string match *.0 $i]} {append i +2c} if {[string compare {} \ [set j [$w search -regexp $exp $i "$i lineend"]]]} { append j +1c } else { set j "$i lineend" } regsub -all $exp2 [$w get $i $j] {\\\0} word set word [string trim $word {\"$[]{}',?#*}] if {[llength [EvalAttached [list info commands $word]]]} { lappend type "proc" } if {[llength [EvalAttached [list info vars $word]]]} { lappend type "var" } if {[EvalAttached [list file isfile $word]]} { lappend type "file" } } } if {![info exists type] || ![info exists word]} { tk_popup $PRIV(popup) $X $Y return } $PRIV(context) delete 0 end $PRIV(context) add command -label "$word" -state disabled $PRIV(context) add separator set app [Attach] if {[lsearch $type proc] != -1} { $PRIV(context) add command -label "View Procedure" \ -command [list edit -attach $app -type proc -- $word] } if {[lsearch $type var] != -1} { $PRIV(context) add command -label "View Variable" \ -command [list edit -attach $app -type var -- $word] } if {[lsearch $type file] != -1} { $PRIV(context) add command -label "View File" \ -command [list edit -attach $app -type file -- $word] } tk_popup $PRIV(context) $X $Y } ## ::tkcon::TagProc - tags a procedure in the console if it's recognized ## This procedure is not perfect. However, making it perfect wastes ## too much CPU time... ## proc ::tkcon::TagProc w { set exp "\[^\\\\\]\[\[ \t\n\r\;{}\"\$\]" set i [$w search -backwards -regexp $exp insert-1c limit-1c] if {[string compare {} $i]} {append i +2c} else {set i limit} regsub -all "\[\[\\\\\\?\\*\]" [$w get $i "insert-1c wordend"] {\\\0} c if {[llength [EvalAttached [list info commands $c]]]} { $w tag add proc $i "insert-1c wordend" } else { $w tag remove proc $i "insert-1c wordend" } if {[llength [EvalAttached [list info vars $c]]]} { $w tag add var $i "insert-1c wordend" } else { $w tag remove var $i "insert-1c wordend" } } ## ::tkcon::MatchPair - blinks a matching pair of characters ## c2 is assumed to be at the text index 'insert'. ## This proc is really loopy and took me an hour to figure out given ## all possible combinations with escaping except for escaped \'s. ## It doesn't take into account possible commenting... Oh well. If ## anyone has something better, I'd like to see/use it. This is really ## only efficient for small contexts. # ARGS: w - console text widget # c1 - first char of pair # c2 - second char of pair # Calls: ::tkcon::Blink ## proc ::tkcon::MatchPair {w c1 c2 {lim 1.0}} { if {[string compare {} [set ix [$w search -back $c1 insert $lim]]]} { while { [string match {\\} [$w get $ix-1c]] && [string compare {} [set ix [$w search -back $c1 $ix-1c $lim]]] } {} set i1 insert-1c while {[string compare {} $ix]} { set i0 $ix set j 0 while {[string compare {} [set i0 [$w search $c2 $i0 $i1]]]} { append i0 +1c if {[string match {\\} [$w get $i0-2c]]} continue incr j } if {!$j} break set i1 $ix while {$j && [string compare {} \ [set ix [$w search -back $c1 $ix $lim]]]} { if {[string match {\\} [$w get $ix-1c]]} continue incr j -1 } } if {[string match {} $ix]} { set ix [$w index $lim] } } else { set ix [$w index $lim] } if {$::tkcon::OPT(blinkrange)} { Blink $w $ix [$w index insert] } else { Blink $w $ix $ix+1c [$w index insert-1c] [$w index insert] } } ## ::tkcon::MatchQuote - blinks between matching quotes. ## Blinks just the quote if it's unmatched, otherwise blinks quoted string ## The quote to match is assumed to be at the text index 'insert'. # ARGS: w - console text widget # Calls: ::tkcon::Blink ## proc ::tkcon::MatchQuote {w {lim 1.0}} { set i insert-1c set j 0 while {[string compare [set i [$w search -back \" $i $lim]] {}]} { if {[string match {\\} [$w get $i-1c]]} continue if {!$j} {set i0 $i} incr j } if {$j&1} { if {$::tkcon::OPT(blinkrange)} { Blink $w $i0 [$w index insert] } else { Blink $w $i0 $i0+1c [$w index insert-1c] [$w index insert] } } else { Blink $w [$w index insert-1c] [$w index insert] } } ## ::tkcon::Blink - blinks between n index pairs for a specified duration. # ARGS: w - console text widget # i1 - start index to blink region # i2 - end index of blink region # dur - duration in usecs to blink for # Outputs: blinks selected characters in $w ## proc ::tkcon::Blink {w args} { eval [list $w tag add blink] $args after $::tkcon::OPT(blinktime) [list $w] tag remove blink $args return } ## ::tkcon::Insert ## Insert a string into a text console at the point of the insertion cursor. ## If there is a selection in the text, and it covers the point of the ## insertion cursor, then delete the selection before inserting. # ARGS: w - text window in which to insert the string # s - string to insert (usually just a single char) # Outputs: $s to text widget ## proc ::tkcon::Insert {w s} { if {[string match {} $s] || [string match disabled [$w cget -state]]} { return } if {[$w comp insert < limit]} { $w mark set insert end } if {[llength [$w tag ranges sel]] && \ [$w comp sel.first <= insert] && [$w comp sel.last >= insert]} { $w delete sel.first sel.last } $w insert insert $s $w see insert } ## ::tkcon::Expand - # ARGS: w - text widget in which to expand str # type - type of expansion (path / proc / variable) # Calls: ::tkcon::Expand(Pathname|Procname|Variable) # Outputs: The string to match is expanded to the longest possible match. # If ::tkcon::OPT(showmultiple) is non-zero and the user longest # match equaled the string to expand, then all possible matches # are output to stdout. Triggers bell if no matches are found. # Returns: number of matches found ## proc ::tkcon::Expand {w {type ""}} { set exp "\[^\\\\\]\[\[ \t\n\r\\\{\"$\]" set tmp [$w search -backwards -regexp $exp insert-1c limit-1c] if {[string compare {} $tmp]} {append tmp +2c} else {set tmp limit} if {[$w compare $tmp >= insert]} return set str [$w get $tmp insert] switch -glob $type { pa* { set res [ExpandPathname $str] } pr* { set res [ExpandProcname $str] } v* { set res [ExpandVariable $str] } default { set res {} foreach t $::tkcon::OPT(expandorder) { if {![catch {Expand$t $str} res] && \ [string compare {} $res]} break } } } set len [llength $res] if {$len} { $w delete $tmp insert $w insert $tmp [lindex $res 0] if {$len > 1} { if {$::tkcon::OPT(showmultiple) && \ ![string compare [lindex $res 0] $str]} { puts stdout [lsort [lreplace $res 0 0]] } } } else { bell } return [incr len -1] } ## ::tkcon::ExpandPathname - expand a file pathname based on $str ## This is based on UNIX file name conventions # ARGS: str - partial file pathname to expand # Calls: ::tkcon::ExpandBestMatch # Returns: list containing longest unique match followed by all the # possible further matches ## proc ::tkcon::ExpandPathname str { set pwd [EvalAttached pwd] # Cause a string like {C:/Program\ Files/} to become "C:/Program Files/" regsub -all {\\([][ ])} $str {\1} str if {[catch {EvalAttached [list cd [file dirname $str]]} err]} { return -code error $err } set dir [file tail $str] ## Check to see if it was known to be a directory and keep the trailing ## slash if so (file tail cuts it off) if {[string match */ $str]} { append dir / } # Create a safely glob-able name regsub -all {([][])} $dir {\\\1} safedir if {[catch {lsort [EvalAttached [list glob $safedir*]]} m]} { set match {} } else { if {[llength $m] > 1} { global tcl_platform if {[string match windows $tcl_platform(platform)]} { ## Windows is screwy because it's case insensitive set tmp [ExpandBestMatch [string tolower $m] \ [string tolower $dir]] ## Don't change case if we haven't changed the word if {[string length $dir]==[string length $tmp]} { set tmp $dir } } else { set tmp [ExpandBestMatch $m $dir] } if {[string match */* $str]} { set tmp [string trimright [file dirname $str] /]/$tmp } regsub -all {([^\\])([][ ])} $tmp {\1\\\2} tmp set match [linsert $m 0 $tmp] } else { ## This may look goofy, but it handles spaces in path names eval append match $m if {[file isdirectory $match]} {append match /} if {[string match */* $str]} { set match [string trimright [file dirname $str] /]/$match } regsub -all {([^\\])([][ ])} $match {\1\\\2} match ## Why is this one needed and the ones below aren't!! set match [list $match] } } EvalAttached [list cd $pwd] return $match } ## ::tkcon::ExpandProcname - expand a tcl proc name based on $str # ARGS: str - partial proc name to expand # Calls: ::tkcon::ExpandBestMatch # Returns: list containing longest unique match followed by all the # possible further matches ## proc ::tkcon::ExpandProcname str { set match [EvalAttached [list info commands $str*]] if {[llength $match] == 0} { set ns [EvalAttached \ "namespace children \[namespace current\] [list $str*]"] if {[llength $ns]==1} { set match [EvalAttached [list info commands ${ns}::*]] } else { set match $ns } } if {[llength $match] > 1} { regsub -all {([^\\]) } [ExpandBestMatch $match $str] {\1\\ } str set match [linsert $match 0 $str] } else { regsub -all {([^\\]) } $match {\1\\ } match } return $match } ## ::tkcon::ExpandVariable - expand a tcl variable name based on $str # ARGS: str - partial tcl var name to expand # Calls: ::tkcon::ExpandBestMatch # Returns: list containing longest unique match followed by all the # possible further matches ## proc ::tkcon::ExpandVariable str { if {[regexp {([^\(]*)\((.*)} $str junk ary str]} { ## Looks like they're trying to expand an array. set match [EvalAttached [list array names $ary $str*]] if {[llength $match] > 1} { set vars $ary\([ExpandBestMatch $match $str] foreach var $match {lappend vars $ary\($var\)} return $vars } else {set match $ary\($match\)} ## Space transformation avoided for array names. } else { set match [EvalAttached [list info vars $str*]] if {[llength $match] > 1} { regsub -all {([^\\]) } [ExpandBestMatch $match $str] {\1\\ } str set match [linsert $match 0 $str] } else { regsub -all {([^\\]) } $match {\1\\ } match } } return $match } ## ::tkcon::ExpandBestMatch2 - finds the best unique match in a list of names ## Improves upon the speed of the below proc only when $l is small ## or $e is {}. $e is extra for compatibility with proc below. # ARGS: l - list to find best unique match in # Returns: longest unique match in the list ## proc ::tkcon::ExpandBestMatch2 {l {e {}}} { set s [lindex $l 0] if {[llength $l]>1} { set i [expr {[string length $s]-1}] foreach l $l { while {$i>=0 && [string first $s $l]} { set s [string range $s 0 [incr i -1]] } } } return $s } ## ::tkcon::ExpandBestMatch - finds the best unique match in a list of names ## The extra $e in this argument allows us to limit the innermost loop a ## little further. This improves speed as $l becomes large or $e becomes long. # ARGS: l - list to find best unique match in # e - currently best known unique match # Returns: longest unique match in the list ## proc ::tkcon::ExpandBestMatch {l {e {}}} { set ec [lindex $l 0] if {[llength $l]>1} { set e [string length $e]; incr e -1 set ei [string length $ec]; incr ei -1 foreach l $l { while {$ei>=$e && [string first $ec $l]} { set ec [string range $ec 0 [incr ei -1]] } } } return $ec } # Here is a group of functions that is only used when Tkcon is # executed in a safe interpreter. It provides safe versions of # missing functions. For example: # # - "tk appname" returns "tkcon.tcl" but cannot be set # - "toplevel" is equivalent to 'frame', only it is automatically # packed. # - The 'source', 'load', 'open', 'file' and 'exit' functions are # mapped to corresponding functions in the parent interpreter. # # Further on, Tk cannot be really loaded. Still the safe 'load' # provedes a speciall case. The Tk can be divided into 4 groups, # that each has a safe handling procedure. # # - "::tkcon::SafeItem" handles commands like 'button', 'canvas' ...... # Each of these functions has the window name as first argument. # - "::tkcon::SafeManage" handles commands like 'pack', 'place', 'grid', # 'winfo', which can have multiple window names as arguments. # - "::tkcon::SafeWindow" handles all windows, such as '.'. For every # window created, a new alias is formed which also is handled by # this function. # - Other (e.g. bind, bindtag, image), which need their own function. # ## These functions courtesy Jan Nijtmans (nijtmans@nici.kun.nl) ## if {[string compare [info command tk] tk]} { proc tk {option args} { if {![string match app* $option]} { error "wrong option \"$option\": should be appname" } return "tkcon.tcl" } } if {[string compare [info command toplevel] toplevel]} { proc toplevel {name args} { eval frame $name $args pack $name } } proc ::tkcon::SafeSource {i f} { set fd [open $f r] set r [read $fd] close $fd if {[catch {interp eval $i $r} msg]} { error $msg } } proc ::tkcon::SafeOpen {i f {m r}} { set fd [open $f $m] interp transfer {} $fd $i return $fd } proc ::tkcon::SafeLoad {i f p} { global tk_version tk_patchLevel tk_library auto_path if {[string compare $p Tk]} { load $f $p $i } else { foreach command {button canvas checkbutton entry frame label listbox message radiobutton scale scrollbar spinbox text toplevel} { $i alias $command ::tkcon::SafeItem $i $command } $i alias image ::tkcon::SafeImage $i foreach command {pack place grid destroy winfo} { $i alias $command ::tkcon::SafeManage $i $command } if {[llength [info command event]]} { $i alias event ::tkcon::SafeManage $i $command } frame .${i}_dot -width 300 -height 300 -relief raised pack .${i}_dot -side left $i alias tk tk $i alias bind ::tkcon::SafeBind $i $i alias bindtags ::tkcon::SafeBindtags $i $i alias . ::tkcon::SafeWindow $i {} foreach var {tk_version tk_patchLevel tk_library auto_path} { $i eval set $var [list [set $var]] } $i eval { package provide Tk $tk_version if {[lsearch -exact $auto_path $tk_library] < 0} { lappend auto_path $tk_library } } return "" } } proc ::tkcon::SafeSubst {i a} { set arg1 "" foreach {arg value} $a { if {![string compare $arg -textvariable] || ![string compare $arg -variable]} { set newvalue "[list $i] $value" global $newvalue if {[interp eval $i info exists $value]} { set $newvalue [interp eval $i set $value] } else { catch {unset $newvalue} } $i eval trace variable $value rwu \{[list tkcon set $newvalue $i]\} set value $newvalue } elseif {![string compare $arg -command]} { set value [list $i eval $value] } lappend arg1 $arg $value } return $arg1 } proc ::tkcon::SafeItem {i command w args} { set args [::tkcon::SafeSubst $i $args] set code [catch "$command [list .${i}_dot$w] $args" msg] $i alias $w ::tkcon::SafeWindow $i $w regsub -all .${i}_dot $msg {} msg return -code $code $msg } proc ::tkcon::SafeManage {i command args} { set args1 "" foreach arg $args { if {[string match . $arg]} { set arg .${i}_dot } elseif {[string match .* $arg]} { set arg ".${i}_dot$arg" } lappend args1 $arg } set code [catch "$command $args1" msg] regsub -all .${i}_dot $msg {} msg return -code $code $msg } # # FIX: this function doesn't work yet if the binding starts with '+'. # proc ::tkcon::SafeBind {i w args} { if {[string match . $w]} { set w .${i}_dot } elseif {[string match .* $w]} { set w ".${i}_dot$w" } if {[llength $args] > 1} { set args [list [lindex $args 0] \ "[list $i] eval [list [lindex $args 1]]"] } set code [catch "bind $w $args" msg] if {[llength $args] <2 && $code == 0} { set msg [lindex $msg 3] } return -code $code $msg } proc ::tkcon::SafeImage {i option args} { set code [catch "image $option $args" msg] if {[string match cr* $option]} { $i alias $msg $msg } return -code $code $msg } proc ::tkcon::SafeBindtags {i w {tags {}}} { if {[string match . $w]} { set w .${i}_dot } elseif {[string match .* $w]} { set w ".${i}_dot$w" } set newtags {} foreach tag $tags { if {[string match . $tag]} { lappend newtags .${i}_dot } elseif {[string match .* $tag]} { lappend newtags ".${i}_dot$tag" } else { lappend newtags $tag } } if {[string match $tags {}]} { set code [catch {bindtags $w} msg] regsub -all \\.${i}_dot $msg {} msg } else { set code [catch {bindtags $w $newtags} msg] } return -code $code $msg } proc ::tkcon::SafeWindow {i w option args} { if {[string match conf* $option] && [llength $args] > 1} { set args [::tkcon::SafeSubst $i $args] } elseif {[string match itemco* $option] && [llength $args] > 2} { set args "[list [lindex $args 0]] [::tkcon::SafeSubst $i [lrange $args 1 end]]" } elseif {[string match cr* $option]} { if {[llength $args]%2} { set args "[list [lindex $args 0]] [::tkcon::SafeSubst $i [lrange $args 1 end]]" } else { set args [::tkcon::SafeSubst $i $args] } } elseif {[string match bi* $option] && [llength $args] > 2} { set args [list [lindex $args 0] [lindex $args 1] "[list $i] eval [list [lindex $args 2]]"] } set code [catch ".${i}_dot$w $option $args" msg] if {$code} { regsub -all .${i}_dot $msg {} msg } elseif {[string match conf* $option] || [string match itemco* $option]} { if {[llength $args] == 1} { switch -- $args { -textvariable - -variable { set msg "[lrange $msg 0 3] [list [lrange [lindex $msg 4] 1 end]]" } -command - updatecommand { set msg "[lrange $msg 0 3] [list [lindex [lindex $msg 4] 2]]" } } } elseif {[llength $args] == 0} { set args1 "" foreach el $msg { switch -- [lindex $el 0] { -textvariable - -variable { set el "[lrange $el 0 3] [list [lrange [lindex $el 4] 1 end]]" } -command - updatecommand { set el "[lrange $el 0 3] [list [lindex [lindex $el 4] 2]]" } } lappend args1 $el } set msg $args1 } } elseif {[string match cg* $option] || [string match itemcg* $option]} { switch -- $args { -textvariable - -variable { set msg [lrange $msg 1 end] } -command - updatecommand { set msg [lindex $msg 2] } } } elseif {[string match bi* $option]} { if {[llength $args] == 2 && $code == 0} { set msg [lindex $msg 2] } } return -code $code $msg } proc ::tkcon::RetrieveFilter {host} { variable PRIV set result {} if {[info exists PRIV(proxy)]} { if {![regexp "^(localhost|127\.0\.0\.1)" $host]} { set result [lrange [split [lindex $PRIV(proxy) 0] :] 0 1] } } return $result } proc ::tkcon::RetrieveAuthentication {} { package require Tk if {[catch {package require base64}]} { if {[catch {package require Trf}]} { error "base64 support not available" } else { set local64 "base64 -mode enc" } } else { set local64 "base64::encode" } set dlg [toplevel .auth] wm title $dlg "Authenticating Proxy Configuration" set f1 [frame ${dlg}.f1] set f2 [frame ${dlg}.f2] button $f2.b -text "OK" -command "destroy $dlg" pack $f2.b -side right label $f1.l2 -text "Username" label $f1.l3 -text "Password" entry $f1.e2 -textvariable "[namespace current]::conf_userid" entry $f1.e3 -textvariable "[namespace current]::conf_passwd" -show * grid $f1.l2 -column 0 -row 0 -sticky e grid $f1.l3 -column 0 -row 1 -sticky e grid $f1.e2 -column 1 -row 0 -sticky news grid $f1.e3 -column 1 -row 1 -sticky news grid columnconfigure $f1 1 -weight 1 pack $f2 -side bottom -fill x pack $f1 -side top -anchor n -fill both -expand 1 tkwait window $dlg set result {} if {[info exists [namespace current]::conf_userid]} { set data [subst $[namespace current]::conf_userid] append data : [subst $[namespace current]::conf_passwd] set data [$local64 $data] set result [list "Proxy-Authorization" "Basic $data"] } unset [namespace current]::conf_passwd return $result } proc ::tkcon::Retrieve {} { # A little bit'o'magic to grab the latest tkcon from CVS and # save it locally. It doesn't support proxies though... variable PRIV set defExt "" if {[string match "windows" $::tcl_platform(platform)]} { set defExt ".tcl" } set file [tk_getSaveFile -title "Save Latest tkcon to ..." \ -defaultextension $defExt \ -initialdir [file dirname $PRIV(SCRIPT)] \ -initialfile [file tail $PRIV(SCRIPT)] \ -parent $PRIV(root) \ -filetypes {{"Tcl Files" {.tcl .tk}} {"All Files" {*.*}}}] if {[string compare $file ""]} { package require http 2 set token [::http::geturl $PRIV(HEADURL) -timeout 30000] ::http::wait $token set code [catch { if {[::http::status $token] == "ok"} { set fid [open $file w] # We don't want newline mode to change fconfigure $fid -translation binary set data [::http::data $token] puts -nonewline $fid $data close $fid regexp {Id: tkcon.tcl,v (\d+\.\d+)} $data -> rcsVersion regexp {version\s+(\d+\.\d[^\n]*)} $data -> tkconVersion } } err] ::http::cleanup $token if {$code} { return -code error $err } elseif {[tk_messageBox -type yesno -icon info -parent $PRIV(root) \ -title "Retrieved tkcon v$tkconVersion, RCS $rcsVersion" \ -message "Successfully retrieved tkcon v$tkconVersion,\ RCS $rcsVersion. Shall I resource (not restart) this\ version now?"] == "yes"} { set PRIV(SCRIPT) $file set PRIV(version) $tkconVersion.$rcsVersion ::tkcon::Resource } } } ## ::tkcon::Resource - re'source's this script into current console ## Meant primarily for my development of this program. It follows ## links until the ultimate source is found. ## set ::tkcon::PRIV(SCRIPT) [info script] if {!$::tkcon::PRIV(WWW) && [string compare $::tkcon::PRIV(SCRIPT) {}]} { # we use a catch here because some wrap apps choke on 'file type' # because TclpLstat wasn't wrappable until 8.4. catch { while {[string match link [file type $::tkcon::PRIV(SCRIPT)]]} { set link [file readlink $::tkcon::PRIV(SCRIPT)] if {[string match relative [file pathtype $link]]} { set ::tkcon::PRIV(SCRIPT) \ [file join [file dirname $::tkcon::PRIV(SCRIPT)] $link] } else { set ::tkcon::PRIV(SCRIPT) $link } } catch {unset link} if {[string match relative [file pathtype $::tkcon::PRIV(SCRIPT)]]} { set ::tkcon::PRIV(SCRIPT) [file join [pwd] $::tkcon::PRIV(SCRIPT)] } } } proc ::tkcon::Resource {} { uplevel \#0 { if {[catch {source -rsrc tkcon}]} { source $::tkcon::PRIV(SCRIPT) } } Bindings InitSlave $::tkcon::OPT(exec) } ## Initialize only if we haven't yet ## if {![info exists ::tkcon::PRIV(root)] || \ ![winfo exists $::tkcon::PRIV(root)]} { ::tkcon::Init } magic-8.0.210/tcltk/toolkit.tcl0000644000175000001440000002151710751423606014776 0ustar timusers#----------------------------------------------------- # Magic/TCL general-purpose toolkit procedures #----------------------------------------------------- # Tim Edwards # February 11, 2007 # Revision 0 #-------------------------------------------------------------- # Sets up the environment for a toolkit. The toolkit must # supply a namespace that is the "library name". For each # parameter-defined device ("gencell") type, the toolkit must # supply three procedures: # # 1. ${library}::${gencell_type}_params {gname} {...} # 2. ${library}::${gencell_type}_check {gname} {...} # 3. ${library}::${gencell_type}_draw {gname} {...} # # The first defines the parameters used by the gencell, and # declares default parameters to use when first generating # the window that prompts for the device parameters prior to # creating the device. The second checks the parameters for # legal values. The third draws the device. #-------------------------------------------------------------- # Initialize toolkit menus to the wrapper window global Opts #---------------------------------------------------------------- # Add a menu button to the Magic wrapper window for the toolkit #---------------------------------------------------------------- proc magic::add_toolkit_menu {framename button_text} { menubutton ${framename}.titlebar.mbuttons.toolkit \ -text $button_text \ -relief raised \ -menu ${framename}.titlebar.mbuttons.toolkit.toolmenu \ -borderwidth 2 menu ${framename}.titlebar.mbuttons.toolkit.toolmenu -tearoff 0 pack ${framename}.titlebar.mbuttons.toolkit -side left } #---------------------------------------------------------------- # Add a menu item to the toolkit menu #---------------------------------------------------------------- proc magic::add_toolkit_button {framename button_text gencell_type library} { set m ${framename}.titlebar.mbuttons.toolkit.toolmenu $m add command -label "$button_text" -command \ "magic::gencell_params {} $gencell_type $library" } #----------------------------------------------------- # Device selection #----------------------------------------------------- proc magic::gen_params {} { # Find selected item (to-do: handle multiple selections) set wlist [what -list] set clist [lindex $wlist 2] set ccell [lindex $clist 0] set cdef [lindex $ccell 1] if {[regexp {^(.*_[0-9]*)$} $cdef valid gname] != 0} { set library [cellname property $gname library] if {$library == {}} { error "Gencell has no associated library!" } else { regexp {^(.*)_[0-9]*$} $cdef valid gencell_type magic::gencell_params $gname $gencell_type $library } } else { # Error message error "No gencell device is selected!" } } #----------------------------------------------------- # Add "Ctrl-P" key callback for device selection #----------------------------------------------------- magic::macro ^P magic::gen_params #------------------------------------------------------------- # gencell_setparams # # Go through the parameter window and collect all of the # named parameters and their values, and generate the # associated properties in celldef "$gname". #------------------------------------------------------------- proc magic::gencell_setparams {gname} { set slist [grid slaves .params.edits] foreach s $slist { if {[regexp {^.params.edits.(.*)_ent$} $s valid pname] != 0} { set value [$s get] cellname property $gname $pname $value } } } #------------------------------------------------------------- # gencell_getparam # # Go through the parameter window, find the named parameter, # and return its value. #------------------------------------------------------------- proc magic::gencell_getparam {gname pname} { set slist [grid slaves .params.edits] foreach s $slist { if {[regexp {^.params.edits.(.*)_ent$} $s valid ptest] != 0} { if {$pname == $ptest} { return [$s get] } } } } #------------------------------------------------------------- # gencell_change # # Redraw a gencell with new parameters. #------------------------------------------------------------- proc magic::gencell_change {gname gencell_type library} { if {[cellname list exists $gname] != 0} { if {[eval "${library}::${gencell_type}_check $gname"]} { suspendall pushstack $gname select cell erase * magic::gencell_draw $gname $gencell_type $library popstack resumeall } else { error "Parameter out of range!" } } else { error "Cell $gname does not exist!" } } #------------------------------------------------------------- # gencell_create # # Instantiate a new gencell called $gname. If $gname # does not already exist, create it by calling its # drawing routine. # # Don't rely on pushbox/popbox since we don't know what # the drawing routine is going to do to the stack! #------------------------------------------------------------- proc magic::gencell_create {gname gencell_type library} { suspendall if {[cellname list exists $gname] == 0} { cellname create $gname set snaptype [snap list] snap internal set savebox [box values] pushstack $gname magic::gencell_draw $gname $gencell_type $library popstack eval "box values $savebox" snap $snaptype } getcell $gname expand resumeall } #------------------------------------------------------------- #------------------------------------------------------------- proc magic::gencell_check {gname gencell_type library} { return [eval "${library}::${gencell_type}_check $gname"] } #------------------------------------------------------------- #------------------------------------------------------------- proc magic::gencell_draw {gname gencell_type library} { # Set the parameters passed from the window text entries magic::gencell_setparams $gname # Call the draw routine eval "${library}::${gencell_type}_draw $gname" # Find the namespace of the draw procedure and set propery "library" cellname property $gname library $library } #----------------------------------------------------- # Add a standard parameter to the gencell window #----------------------------------------------------- proc magic::add_param {gname pname ptext default_value} { # Check if the parameter exists. If so, override the default # value with the current value. set value {} if {[cellname list exists $gname] != 0} { set value [cellname property $gname $pname] } if {$value == {}} {set value $default_value} set numrows [lindex [grid size .params.edits] 0] label .params.edits.${pname}_lab -text $ptext entry .params.edits.${pname}_ent -background white grid .params.edits.${pname}_lab -row $numrows -column 0 grid .params.edits.${pname}_ent -row $numrows -column 1 .params.edits.${pname}_ent insert end $value } #----------------------------------------------------- # Update the properties of a cell #----------------------------------------------------- proc magic::update_params {gname ptext default_value} { } #------------------------------------------------------------- # gencell_params --- # 1) If gname is NULL and gencell_type is set, then we # create a new cell of type gencell_type. # 2) If gname is non-NULL, then we edit the existing # cell of type $gname. # 3) If gname is non-NULL and gencell_type or library # is NULL or unspecified, then we derive the gencell_type # and library from the existing cell's property strings #------------------------------------------------------------- proc magic::gencell_params {gname {gencell_type {}} {library {}}} { if {$gname == {}} { set pidx 1 while {[cellname list exists ${gencell_type}_$pidx] != 0} { incr pidx } set gname ${gencell_type}_$pidx set ttext "New device" set btext "Create" set bcmd "magic::gencell_create $gname $gencell_type $library" } else { if {$gencell_type == {}} { set gencell_type [cellname property ${gname} gencell] } if {$library == {}} { set library [cellname property ${gname} library] } set ttext "Edit device" set btext "Apply" set bcmd "magic::gencell_change $gname $gencell_type $library" } catch {destroy .params} toplevel .params label .params.title -text "$ttext $gname" frame .params.edits frame .params.buttons pack .params.title pack .params.edits pack .params.buttons button .params.buttons.apply \ -text "$btext" \ -command [subst { $bcmd ; \ .params.buttons.apply configure -text Apply}] button .params.buttons.close -text "Close" -command {destroy .params} pack .params.buttons.apply -padx 10 -side left pack .params.buttons.close -padx 10 -side right # Invoke the callback procedure that creates the parameter entries eval "${library}::${gencell_type}_params $gname" } #------------------------------------------------------------- magic-8.0.210/tcltk/ext2sim.sh0000664000175000001440000000066512500371713014532 0ustar timusers#!/bin/sh # # Standalone script for ext2sim, for Tcl-based magic 8.0 # # Parse arguments. "--" separates arguments to magic # from arguments to ext2sim. # mgargs="" esargs="" for i in $@; do case $i in --) mgargs="$esargs" esargs="" ;; *) esargs="$esargs $i" ;; esac done # eval /home/tim/cad/lib/magic/tcl/magicdnull -dnull -noconsole -nowrapper $mgargs < #include #include /*----------------------------------------------------------------------*/ /* Application initiation. This is exactly like the AppInit routine */ /* for "wish", minus the cruft, but with "tcl_rcFileName" set to */ /* "magic.tcl" instead of "~/.wishrc". */ /*----------------------------------------------------------------------*/ int magic_AppInit(interp) Tcl_Interp *interp; { if (Tcl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } if (Tk_Init(interp) == TCL_ERROR) { return TCL_ERROR; } Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit); /* This is where we replace the home ".wishrc" file with */ /* magic's startup script. */ Tcl_SetVar(interp, "tcl_rcFileName", TCL_DIR "/magic.tcl", TCL_GLOBAL_ONLY); return TCL_OK; } /*----------------------------------------------------------------------*/ /* The main procedure; replacement for "wish". */ /*----------------------------------------------------------------------*/ int main(argc, argv) int argc; char **argv; { Tk_Main(argc, argv, magic_AppInit); return 0; } /*----------------------------------------------------------------------*/ magic-8.0.210/TODO0000644000175000001440000000051511120112362012130 0ustar timusersI. Bugs to fix (also in magic-7.5 [stable]): 1. The "extresist" code only recognizes original "fet" types, not the new "device" types in the extract file. 2. "plow" has been broken for some time. It should derive its rules from the DRC decks (using the new routines that are meant for just that sort of thing). magic-8.0.210/scmos/0000755000175000001440000000000012402623676012606 5ustar timusersmagic-8.0.210/scmos/test.out0000664000175000001440000033165311755243452014333 0ustar timusers/* --------------------------------------------------------------------* * * * scmos.tech -- MOSIS Scalable CMOS (SCMOS) Magic technology file. * * * * MOSIS distribution Version 8.2 * * * * Defines the MOSIS 0.6/0.8/1.0/1.2/2.0 micron Scalable CMOS * * (SCMOS) technology. * * * * (C) Copyright 1992, 1993, 1994, 1995 by * * * * Jen-I Pi pi@isi.edu * * The MOSIS Service * * USC Information Sciences Institute * * 4676 Admiralty Way * * Marina del Rey, CA 90292 * * voice: (310) 822-1511 x640, fax: (310)823-5624 * * * * All Rights Reserved. * * Last Modified Date: 04/26/1995 * * * * Permission to use, copy, modify, and distribute this technology * * file and its associated documentation for any purpose and without * * fee is hereby granted, provided that the above copyright notice * * appears in all copies and that both that copyright notice and this * * permission notice appear in supporting documentation, and that the * * name of the University of Southern California not be used in * * advertising or publicity pertaining to distribution of this * * technology file without specific, written prior permission. * * The University of Southern California makes no representations * * about the suitability of this technology file for any purpose. * * This technology file is provided "as is" without express or implied * * warranty and the University of Southern California retains the * * right to change its content at any time without notice any other * * party. * * * * THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH * * REGARD TO THIS TECHNOLOGY FILE, INCLUDING ALL IMPLIED WARRANTIES OF * * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF * * SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR * * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * * CONNECTION WITH THE USE OR PERFORMANCE OF THIS TECHNOLOGY FILE. * * * * ------------------------------------------------------------------- */ /* --------------------------------------------------------------------* * Some of the characteristics of this technology are: * * * * 1. 3 levels of metal - for HP's CMOS26B (lambda=0.5) and CMOS26G * * (lambda=0.4) and CMOS14TB (lambda=0.35 or 0.3) processes * * 3 levels of metal stack via - for IBM's CMSX2185 (lambda=0.4) * * process * * 2 levels of metal interconnection for all other technologies * * 2. 2 levels of poly - for ORBIT's low-noise analog process * * second poly is used for poly-capacitor or electrode fet (efet) * * 3. Vertical NPN transistor, BCCD device, Floating-gate device for * * ORBIT's low-noise anaolog process * * 4. All contacts are composite (with the necessary enclosure) * * 5. No stacked contacts (all contacts are to 1st-level metal) * * 6. An open layer is added for fabrication of micromachined devices * * as in Janet C. Marshall's paper in IEEE Circuit and Devices, * * Vol. 8, N0. 6, 1992. * * This layer is currently NOT available for standard MOSIS SCMOS * * techonology installation. You need to define OPEN with the C- * * preprocessor for installation. See README file for detail... * * 7 A pstop layer is used also in micromachineing device fabrication * * to stop the EDP etchant as used in Marshall's article. * * 8 A Cap-well (cwell) for HP's CMOS34 (lambda=0.6) process, It is * * used for consctruction of linear capacitors * * Must be drawn explicitly * * 9. Wells (Pwell or Nwell) can be implicit or explicit in the layout * * and both types of diffusion must have well contacts * *10. Painting Nwell over N-type diffusion will result in P-type * * diffusion * *11. Scalable with Default to be 2.0 micron rules for Nwell process * *12. Substrate contacts must be 3 units away from gates * *13. Stacked via supported through special compiled option -DSTACKVIA * * for IBM process. * * * * Revision 8.2.8 (pi) * * fix CCD CIF input style for "bd" layer. * * 12/13/95 pi@isi.edu * * Revision 8.2.7 (pi) * * Add Magic 6.4.4 new extraction plane orders. * * 07/25/95 pi@isi.edu * * Revision 8.2.5 (pi) * * Fix some typos... * * 05/12/95 pi@isi.edu * * Revision 8.2.4 (pi) * * Fix CBA generation for pbase and add extension rules for pbase * * as resistors. * * Gratitude goes to Tetsuya Kajita (kaj@ssac.yamatake.co.jp) * * 04/26/95 pi@isi.edu * * Revision 8.2.3 (pi) * * fix for SUBMICRON DRC rule. * * Thanks goes to Toby Schaffer (jtschaff@eos.ncsu.edu) * * 04/06/95 pi@isi.edu * * Revision 8.2.2 (pi) * * add XP GDS official number to fix CIF input problem for "pad". * * Thanks goes to Brian Kingsbury (bedk@ICSI.Berkeley.EDU). * * 04/03/95 pi@isi.edu * * Revision 8.2.1 (pi) * * Some fixes for CMOS14B CIF output section. * * 03/21/95 pi@isi.edu * * Revision 8.2.0 (pi) * * support for HP CMOS26G and CMOS14TB process. * * 03/15/95 pi@isi.edu * * Revision 8.1.1 (pi) * * add connection of "ndiff" to "psd". Thank goes to Alireza Moini* * (moini@eleceng.adelaide.edu.au). * * 12/21/94 pi@isi.edu * * Revision 8.1.0 (pi) * * major revision of bipolar transistor rules. It now support * * both ORBIT 2.0 and 1.2 micron processes. NOTE: active layer * * for pbase is now generated in CIF file explicitly. * * 10/31/94 pi@isi.edu * * Revision 8.0.7 (pi) * * remove both VTI and IBM support * * 10/10/94 pi@isi.edu * * Revision 8.0.7 (pi) * * compose for high-voltage transistors corrected. Thank goes to * * Bob Durie (bobd@ee.cornell.edu) * * 8/25/94 pi@isi.edu * * Revision 8.0.6 (pi) * * DRC rule 2.2 add allNOhmic to allNOhmic and allPOhmic to * * allPOhmic rule. Thank goes to Shih-Lien Lu. * * (sllu@caleb.ECE.ORST.EDU) * * 6/28/94 pi@isi.edu * * Revision 8.0.5 (pi) * * DRC rule 3.5 reverse back to old style to avoid a mischeck on * * corners. Thank goes to Wen-King Su. * * (wen-king@vlsi.cs.caltech.edu) * * 4/20/94 pi@isi.edu * * Revision 8.0.4 (pi) * * SCPE20(ORB) extraction P-well sheet resistance fixed. Thank * * goes to Nagendra Shivakumar (nshivaku@phyast.nhn.uoknor.edu). * * 3/04/94 pi@isi.edu * * Revision 8.0.3 (pi) * * Wellcap drawing problem fixed. Thank goes to Mario Aranha * * (mario@cad4.lbl.gov). * * 2/03/94 pi@isi.edu * * Revision 8.0.2 (pi) * * CIF read fix for linear capacitor. Thank goes to Issy Kipnis * * (kipnis@cad4.lbl.gov). * * 2/03/94 pi@isi.edu * * Revision 8.0.1 (pi) * * DRC updates for separate diffusion width check. Thank goes to * * John Poulton (jp@cs.unc.edu). * * 10/04/93 pi@isi.edu * * Revision 8.0.0 (pi) * * DRC revision 8 installed and layer support for High-Voltage * * MOSFETs for SCNA16 process. * * 10/04/93 pi@isi.edu * * Revision 7.4.0 (pi) * * Brand new extraction section and other fixes :-) * * 10/01/93 pi@isi.edu * * Revision 7.3.3 (pi) * * pbc surrounding rule fixed. 4.1.c fixed also * * 6/01/93 pi@isi.edu * * Revision 7.3.2 (pi) * * exchnage CCD and CBA calma (GDS) number to the correct setting * * 4/27/93 pi@isi.edu * * Revision 7.3.1 (pi) * * Various DRC rule changes contributed by Barry Boes at AuE * * (boes@corona.AuE.com). * * allNDiff/allPOhmic in connection section update, thanks go to * * Brian Kingsbury from Bekerley (bedk@icsi.berkeley.edu). * * 3/30/93 pi@isi.edu * * Revision 7.3.0 (pi) * * add three new layers intended for ESD preotection devices * * remove the temporary "pad2" layer, now all pads use "pad" * * CIFin and CIFout now in templates, thank goes to Shih-Lien Lu * * at Origon State Univ. sllu@caleb.ECE.ORST.EDU. * * Some design rule changes (relabeling for doc)... * * 3/19/93 pi@isi.edu * * Revision 7.2.2 (pi) * * change all "bloat-min" select generation back to "bloat-or" * * restore all lambda=0.8 style since some people use ORBIT's run * * though MOSIS does NOT provide HP's process anymore * * 3/09/93 pi@isi.edu * * Revision 7.2.1 (pi) * * add missing Cifinput "pbase" layer for lambda=1.0(oldnwell) * * style. Thank goes to Brian Von Herzen at Synaptics, Inc. * * 2/18/93 pi@isi.edu * * Revision 7.2.0 (pi) * * A serious bug in CIF well generation is fixed... * * 1/14/93 pi@isi.edu * * Revision 7.1.4 (pi) * * Remove lambda=1.5 and lambda=0.8 technology which are not * * provided by MOSIS any more. * * 1/12/93 pi@isi.edu * * Revision 7.1.3 (pi) * * Add pstop layer and the corresponding CIFin CIFout stuff * * Reverse the last change about CCA layer under pad for CMOS26B * * 1/08/93 pi@isi.edu * * Revision 7.1.2 (pi) * * Various problem fix... and make the "open" layer as an option * * Reverse the last change about CCA layer under pad for CMOS26B * * 12/29/92 pi@isi.edu * * Revision 7.1.1 (pi) * * A series bug fix for HP's CMOS26B pad layers - remove CCA CIF * * layer. Thank goes to ndu@aue.com * * 12/12/92 pi@isi.edu * * Revision 7.1.0 (pi) * * A new layer "open" for micromachined device fabracation. * * Thanks goes to Janet Marchall from NIST. * * (marshall@sed.eeel.nist.gov) * * 12/15/92 pi@isi.edu * * Revision 7.0.4 (pi) * * C-preprocessing fix. Thanks goes to Jeffrey C. Gealow form * * MIT (jgealow@mtl.mit.edu). * * 10/20/92 pi@isi.edu * * Revision 7.0.3 (pi) * * Colorversatec support. Thanks got to Jeffrey C. Gealow form * * MIT (jgealow@mtl.mit.edu). * * 10/8/92 pi@isi.edu * * Revision 7.0.2 (pi) * * Separate 'spacing allWell...' rule into two rules to avoid * * well adjacency problem... * * 10/2/92 pi@isi.edu * * Revision 7.0.1 (pi) * * CIFoutput for "pad2" layer, CCA contact fix, CIFinput for HP's * * 1.0 um process... * * 9/28/92 pi@isi.edu * * Revision 7.0 (pi) * * Major revision which includes * * HP's cap_well and well-capacitance, NPN & BCCD DRC rules... * * 9/22/92 pi@isi.edu * * Revision 6.2.0 (pi) * * Merging 'scmos26.tech' into scmos.tech * * 9/7/92 pi@isi.edu * * Revision 6.1.4 (pi) * * Select CIF layers generation is revised based on Brian * * Kingsbury's (bedk@icsi.berkeley.edu) notice of inconsistency * * 9/4/92 pi@isi.edu * * Revision 6.1.3 (pi) * * Install MITRE's (Mike Butler) fix for CIFinput "cap" layer and * * poly1/poly2 crossing in DRC section * * 9/3/92 pi@isi.edu * * Revision 6.1.2 (pi) * * Fixed metal2 contact on falt surface bug for poly2 layer * * 8/3/92 pi@lepton.isi.edu * * Revision 6.1.1 (pi) * * fixed CIFoutput CSP layer bug for lambda=0.8(gen) technology * * 4/13/92 pi@lepton.isi.edu * * Revision 6.1.0 (pi) * * add implant plane for Buried CCD devices * * both cifin and cifoutput are changed correspondingly * * Revision 6.0.2 (pi) * * remove bug for nbdc not generate CMF in cifoutput section * * Revision 6.0.1 (sllu) * * added CX for collector layer * * Revised for Magic Version 6. * * Revision 6.0 90/05/11 20:12:34 pi * * include color versatech support * * eliminated active2 plane * * (rule version # 5.01 (S. Lu) = rule 5.0 + mod. for cc spacing * * (rule version # 5.0 (Shih-Lien Lu sllu@MOSIS.EDU) 8/15/89) * * (rule 5.0 = rule 4.01 + new layers for analog process * * (rule 4.01 = rule 4.0 + comments + cifout style lambda=0.8(pwell) * * (correction made by L. McMurchie of UW) * * (rule 4.0 = rule 3.1 + new layer : electrode) * * (rule 3.1 = rule 3.0 + new cifout method for select layers ) * * (design can be more compact now with this version ) * * (layout should be upward compatible:: you old layout will not) * * (flag any drc violations) * * (rule 3.0 = rule 2.0 + rev #6 + new cifin section for new nwell) * * * * (rule version # 2.0 10/28/87) * * (rule 2.0 = rule 1.9 + modification to extract section * * (rule 1.9 = rule 1.82 + additions of two more CIF in/output styles * * (rule 1.82 = rule 1.81+ modification of drc #4.1 & cifoutput of * * wells * * (rule 1.81 = rule 1.8 + modification on line 1761 * * (rule 1.8 = rule 1.7 + Rev 5 of the SCMOS rules) * * (difference from rule 1.7: * * (1) well width = 9 lambda * * (2) N well process accepts both N and P selects * * ------------------------------------------------------------------- */ /* Definition for actives */ /* NOTE: Some version of cpp may have problem with two consective tabs * or even two consective space... So we put only single space * here... */ #define allNDiff ndiff,ndc/a #define allPDiff pdiff,pdc/a #define allNActive ndiff,ndc/a,nfet,enfet,nffet,wcap #define allPActive pdiff,pdc/a,pfet,epfet,pffet #define allNOhmic nsd,nsc/a #define allPOhmic psd,psc/a #define allOhmic allNOhmic,allPOhmic #define allBiNDiff emit,emc/a,col,clc/a #define allBiPDiff pbase,pbc/a #define allBiDiff allBiNDiff,allBiPDiff #define allCCDiff bd,nbd,nbdc/a #define allDiff allNDiff,allPDiff #define allActive allNActive,allPActive,allOhmic #define PNplus ndiff,pdiff,ndc/a,pdc/a #define allHVNDiff hndiff,hndc/a #define allHVPDiff hpdiff,hpdc/a #define allHVNOhmic hnsd,hnsc/a #define allHVPOhmic hpsd,hpsc/a #define allHVDiff allHVNDiff,allHVPDiff #define allHVOhmic allHVNOhmic,allHVPOhmic /* first poly without those overlapped with the second */ #define allP poly,pc/a #define allP1 poly,pc/a,nfet,pfet,wcap /* all first poly */ #define allPoly allP1,cap,capc/a,nffet,pffet /* second poly without those overlapped with the first */ #define allP2 poly2,ec/a,enfet,epfet /* all second poly */ #define allPoly2 allP2,cap,capc/a,nffet,pffet,hnfet,hpfet /* MOSFETs */ #define NFet nfet,enfet,nffet #define PFet pfet,epfet,pffet #define allFet NFet,PFet /* Definitions for contacts */ #define DiffCut pdc,ndc,psc,nsc #define HVDiffCut hpdc,hndc,hpsc,hnsc #define PolyCut pc #define CapCut ec,capc #define BiCut clc,emc,pbc #define allCut DiffCut,HVDiffCut,PolyCut,CapCut,nbdc /* Definitions for metals */ #define DiffMetal pdc/m1,ndc/m1,psc/m1,nsc/m1 #define HVDiffMetal hpdc/m1,hndc/m1,hpsc/m1,hnsc/m1 #define PolyMetal pc/m1,ec/m1,capc/m1 #define BiMetal clc/m1,emc/m1,pbc/m1 #define CCDMetal nbdc/m1 #define allMetal1 DiffMetal,HVDiffMetal,PolyMetal,BiMetal,CCDMetal,m1,m2c/m1,gc #define allMetal2 m2,m2c/m2,m3c/m2,pad #define allMetal3 m3,m3c/m3 /* All types containing metal, on their respective home planes */ #define homeMetal1 allCut,m1,m2c,gc /* Definitions for wells */ #define allWell nwell,pwell #define allNwell nwell,nsc,nsd #define allPwell pwell,psc,psd #define allHVNwell hnwell,hnsc,hnsd #define allHVPwell hpwell,hpsc,hpsd tech format 28 scmos end #if V4 || V5 version version 8.2.8 #ifdef SUBMICRON description "MOSIS Scalable CMOS Technology for HP CMOS26G and CMOS14B processes" #else /* TIGHTMETAL */ #ifdef IBMTECH description "MOSIS Scalable CMOS Technology for IBM" #else /* IBMTECH */ #ifdef HPTECH description "MOSIS Scalable CMOS Technology for Tight Metal Rules" #else #ifndef WELL_ROUTE_CHECK description "MOSIS Scalable CMOS Technology for Standard Rules" #else description "MOSIS Scalable CMOS Technology for Standard Rules (No routing through wells)" #endif #endif /* HPTECH */ #endif /* IBMTECH */ #endif /* TIGHTMETAL */ end #endif /* V4 */ planes well,w implant,i active,a metal1,m1 metal2,m2 #ifdef STACKVIA v2oxide,v2x #endif metal3,m3 oxide,ox end types /* primary layers -16 */ well pwell,pw well nwell,nw well capwell,cwell,cw well highvoltnwell,hvnwell,hnwell,hnw well highvoltpwell,hvpwell,hpwell,hpw active polysilicon,red,poly,p active electrode,poly2,el,p2 active capacitor,polycap,pcap,cap active wellcapacitor,wellcap,wcap active ndiffusion,ndiff,green active pdiffusion,pdiff,brown active highvoltndiffusion,hvndiff,hndiff active highvoltpdiffusion,hvpdiff,hpdiff metal1 metal1,m1,blue metal2 metal2,m2,purple metal3 metal3,m3,cyan /* MOSFETs -8 */ active ntransistor,nfet active ptransistor,pfet active entransistor,enfet active eptransistor,epfet active doublentransistor,nfloating-gate,nfloatg,nfg,nffet active doubleptransistor,pfloating-gate,pfloatg,pfg,pffet active highvoltntransistor,hvnfet,hnfet active highvoltptransistor,hvpfet,hpfet /* NPN transistor layers -3 */ active collector,coll,col,co,cl active emitter,emit,em active pbase,pb /* layers for BCCD devices -2 */ implant bccdiffusion,bd active nbccdiffusion,nbd /* Contacts between interconnection layers -13 */ active polycontact,pcontact,polycut,pc active ndcontact,ndiffcut,ndc active pdcontact,pdiffcut,pdc active highvoltndcontact,hndiffcut,hndc active highvoltpdcontact,hpdiffcut,hpdc active capcontact,ccontact,capc,cc active electrodecontact,econtact,ec,poly2contact,p2c active collectorcontact,colcontact,colc,coc,clc active emittercontact,emitcontact,emc active pbasecontact,pbcontact,pbc active nbccdiffcontact,nbdc metal1 m2contact,m2cut,m2c,via,v #ifdef STACKVIA v2x m3contact,m3cut,m3c,via2,v2 #else metal2 m3contact,m3cut,m3c,via2,v2 #endif /* Well contacts -8 */ /* pohmic and nohmic are included for compatibility */ /* nwc, pwc, etc ... are included for compatibility */ active psubstratepcontact,ppcontact,ppc,pwcontact,pwc,psc active nsubstratencontact,nncontact,nnc,nwcontact,nwc,nsc active psubstratepdiff,ppdiff,pohmic,ppd,psd active nsubstratendiff,nndiff,nohmic,nnd,nsd active highvoltpsubcontact,hpwcontact,hpsc active highvoltnsubcontact,hnwcontact,hnsc active highvoltpsubdiff,hpohmic,hpsd active highvoltnsubdiff,hnohmic,hnsd /* Special tiles needed for ESD protection design -3 */ active nplusdoping,ndoping,ndop active pplusdoping,pdoping,pdop metal1 genericcontact,gcontact,gc /* Special tiles needed for micromachine fab. in CMOS -2 */ oxide substrateopen,subopen,open oxide pdiffusionstop,pdiffstop,pstop /* Additional stuff, used in pads. -2 */ metal2 pad oxide glass end contact /* polys */ ec poly2 metal1 cc cap metal1 pc poly metal1 /* active contacts */ ndc ndiff metal1 pdc pdiff metal1 nsc nsd metal1 psc psd metal1 hndc hndiff metal1 hpdc hpdiff metal1 hnsc hnsd metal1 hpsc hpsd metal1 /* bipolar contacts */ clc col metal1 emc emit metal1 pbc pbase metal1 /* BCCD contact */ nbdc nbd metal1 /* vias */ m2c metal1 metal2 #ifdef STACKVIA m3c metal2 m3c metal3 #else m3c metal2 metal3 #endif /* pad metal1 metal2 metal3 */ end styles styletype mos /* wells */ cwell 10 nwell 12 pwell 13 hnwell 18 hpwell 11 /* poly */ poly 1 poly2 14 /* diffusions */ ndiff 2 pdiff 4 psd 5 nsd 3 hndiff 2 hndiff 11 hpdiff 4 hpdiff 18 hpsd 5 hpsd 11 hnsd 3 hnsd 18 ndop 2 ndop 38 pdop 4 pdop 38 /* transistors */ nfet 6 nfet 7 pfet 8 pfet 9 enfet 6 enfet 30 /* enfet 14 */ epfet 8 epfet 31 /* epfet 14 */ nffet 6 nffet 7 /* nffet 14 */ nffet 30 pffet 8 pffet 9 /* pffet 14 */ pffet 31 hnfet 6 hnfet 7 hnfet 30 hpfet 8 hpfet 9 hpfet 31 /* base */ pbase 15 pbc 15 pbc 20 pbc 32 /* emitter */ emit 16 emc 16 emc 20 emc 32 /* collector */ col 3 clc 3 clc 20 clc 32 /* capacitors */ cap 1 cap 14 wcap 6 wcap 10 cc 1 cc 14 cc 20 cc 32 /* metals */ metal1 20 metal2 21 metal3 22 /* generic contact */ gc 19 /* poly contacts */ pcontact 26 pcontact 32 ec 14 ec 20 ec 32 /* diffusion contacts */ ndc 2 ndc 20 ndc 32 pdc 4 pdc 20 pdc 32 psc 5 psc 20 psc 32 nsc 3 nsc 20 nsc 32 /* high-voltage diffusion contacts */ hndc 2 hndc 20 hndc 32 hndc 11 hpdc 4 hpdc 20 hpdc 32 hpdc 18 hpsc 5 hpsc 20 hpsc 32 hpsc 11 hnsc 3 hnsc 20 hnsc 32 hnsc 18 /* vias */ m2contact 20 m2contact 21 m2contact 33 m3contact 21 m3contact 22 m3contact 37 /* pads and overglass */ pad 20 pad 21 pad 33 pad 34 glass 34 /* CCDs */ bd 17 nbd 17 nbd 3 nbdc 3 nbdc 17 nbdc 20 nbdc 32 /* MEMs */ open 2 open 20 pstop 8 /* System */ error_p 42 error_s 42 error_ps 42 end compose /* MOSFET combination rules */ compose nfet poly hndiff compose pfet poly hpdiff compose nfet poly ndiff compose pfet poly pdiff compose hnfet poly2 hndiff compose hpfet poly2 hpdiff compose enfet poly2 ndiff compose epfet poly2 pdiff compose nffet nfet poly2 compose pffet pfet poly2 compose nffet enfet poly compose pffet epfet poly compose cap poly poly2 /* Transistor combination rules */ paint clc col clc paint emc emit emc paint emc pbase emc /* Poly2 capacitor combination rules */ paint poly2 poly cap paint poly poly2 cap paint poly cap cap paint poly2 cap cap paint cap poly cap paint cap poly2 cap /* ILLEGAL declaration by 7.3 standards */ /* paint poly ec cc */ paint ec poly cc /* These rules allow nwell to be painted over an area to * flip all the p-well types to n-well types. Pwell can be * painted to flip in the reverse. */ paint pdc pwell ndc paint pfet pwell nfet paint epfet pwell enfet paint pffet pwell nffet paint pdiff pwell ndiff paint nsd pwell psd paint nsc pwell psc paint ndc nwell pdc paint nfet nwell pfet paint enfet nwell epfet paint nffet nwell pffet paint ndiff nwell pdiff paint psd nwell nsd paint psc nwell nsc paint pdc hpwell hndc paint epfet hpwell hnfet paint pffet hpwell hnfet paint pdiff hpwell hndiff paint nsd hpwell hpsd paint nsc hpwell hpsc paint ndc hnwell hpdc paint enfet hnwell hpfet paint nffet hnwell hpfet paint ndiff hnwell hpdiff paint psd hnwell hnsd paint psc hnwell hnsc /* BCCD layers combination rules */ /* paint bd ndiff 0 implant */ /* erase nbd bd ndiff erase nbd ndiff bd erase nbdc/a bd ndc/a */ /* Well capacitor combination rules */ paint nfet cwell wcap paint poly wcap wcap paint ndiff wcap wcap paint wcap poly wcap paint wcap ndiff wcap erase wcap poly ndiff erase wcap ndiff poly erase wcap cwell nfet paint cwell nfet wcap active erase wcap nfet cwell well /* Generic contact */ paint gc m1 gc /* For pads */ paint pad m1 pad paint pad m2 pad paint pad m3 pad paint pad m2c pad /* These rules allow nwell to be painted over an area to * flip all the p-well types to n-well types. Pwell can be * painted to flip in the reverse. */ paint hpdc hpwell hndc paint hpfet hpwell hnfet paint hpdiff hpwell hndiff paint hnsd hpwell hpsd paint hnsc hpwell hpsc paint hndc hnwell hpdc paint hnfet hnwell hpfet paint hndiff hnwell hpdiff paint hpsd hnwell hnsd paint hpsc hnwell hnsc paint hpdc pwell ndc paint hpfet pwell enfet paint hpdiff pwell ndiff paint hnsd pwell psd paint hnsc pwell psc paint hndc nwell pdc paint hnfet nwell epfet paint hndiff nwell pdiff paint hpsd nwell nsd paint hpsc nwell nsc end connect #ifndef WELL_ROUTE_CHECK /* This creates a tech file where the wells are not connected therefore enabling extractions to check whether the wells are used accidentaly to route signals or power. To check for these cases you have to compare the netlists generated with the normal tech file with those generated with the special one (eg. using gemini). */ allNwell allNwell allPwell allPwell #endif allHVNwell allHVNwell allHVPwell allHVPwell /* for capacitor-well */ allNDiff cwell /* for all metals */ allMetal1 allMetal1 allMetal2 allMetal2 allMetal3 allMetal3 /* for all polys */ allP1 allP1 allPoly2 allPoly2 /* for all diffusions/well plugs */ /* Ndiffusion and Ohmic wells dont connect !! */ /* you get a diode instead */ allNDiff,ndop allPOhmic,pdop,pstop allPDiff,pdop,pstop allNOhmic,ndop allHVNDiff,ndop allHVPOhmic,pdop,pstop allHVPDiff,pdop,pstop allHVNOhmic,ndop ndiff ndc pdiff pdc hndiff hndc hpdiff hpdc /* for BCCD device */ nbd nbdc /* for NPN transistor */ pbase pbc collector clc,nwell emitter emc /* for new generic contact */ gc allActive,allOhmic,allHVDiff,metal1 gc allP1 gc allPoly2 /* for pad */ pad allMetal1 pad allMetal2 pad allMetal3 end /* WARNING ::::: automatic generation of wells does not guarantee */ /* rules on width and spacing of wells are followed !! */ /* It is strongly recommanded that designers layout their own wells */ /* PWELL styles cannot generate CBA and CCD correctly */ /* BOTH NWELL and GEN can do CCD and CBA */ /* ONLY GEN can be used for micro-machining fabrication */ cifoutput /* default: fab on 2.0 micron (Nwell) rules each magic unit is 100 */ /* centmicrons */ /* SCN technology : Both CSN and CSP are generated to reduce field */ /* poly sheet resistance */ #ifdef STANDARD #include "cif_template/objs/CIFout" #endif /* STANDARD */ #ifdef TIGHTMETAL #include "cif_template/objs/TMCIFout" #endif /* TIGHTMETAL */ #ifdef SUBMICRON #include "cif_template/objs/SUBCIFout" #endif /* SUBMICRON */ #ifdef IBMTECH #include "cif_template/objs/IBMCIFout" #endif /* IBMTECH */ style plot /* pplot output style */ scalefactor 100 50 layer CM2 m2,m2c/m2,pad/m2 labels m2 layer CM1 pad grow 100 or m1,m2c/m1,pc/m1,ndc/m1,pdc/m1,ppcont/m1,nncont/m1 labels m1,m2c/m1,pc/m1,ndc/m1,pdc/m1,ppcont/m1,nncont/m1,pad/m1 layer CP poly,pc/active,nfet,pfet labels poly,nfet,pfet layer CND ndiff,ndc,nfet,pwc,psd labels ndiff layer CPD pdiff,pdc,pfet,nwc,nsd labels pdiff layer CNP bloat-or nsd,nwc * 150 ndiff,pdiff,ndc/active,pdc/active,ppcont/active,nncont/active,pfet,nfet,psd,nsd 0 layer CPP bloat-or psd,pwc * 150 ndiff,pdiff,ndc/active,pdc/active,ppcont/active,nncont/active,pfet,nfet,psd,nsd 0 layer CV m2c squares 100 200 300 layer CC ndc,pdc,pc,pwc,nwc squares 200 layer CNW nwell grow 400 shrink 400 layer CG pad shrink 600 or glass labels glass end /* -------------------------------------------------------------------- * * In the CIFinput section, the order of layer specifications is very * * important. Each layer overrides any of the previous layers. There * * are places where one layer is generated over an area that is too * * large, but with the knowledge that later layers will "take over" * * the extraneous area, leaving the first layer only where it belongs. * * This happens for various flavors of diffusion, for example. * * Note: when reading in CMOS, wells are created in the Magic files. * * They can be eliminated manually if desired. * * ---------------------------------------------------------------------*/ cifinput #ifdef STANDARD #include "cif_template/objs/CIFin" #endif /* STANDARD */ #ifdef TIGHTMETAL #include "cif_template/objs/TMCIFin" #endif /* TIGHTMETAL */ #ifdef SUBMICRON #include "cif_template/objs/SUBCIFin" #endif /* SUBMICRON */ #ifdef IBMTECH #include "cif_template/objs/IBMCIFin" #endif /* IBMTECH */ end mzrouter style irouter layer m2 32 64 256 1 layer m1 64 32 256 1 layer poly 128 128 512 1 contact m2contact metal1 metal2 1024 contact pcontact metal1 poly 2056 notactive poly pcontact style garouter layer m2 32 64 256 1 layer m1 64 32 256 1 contact m2contact metal1 metal2 1024 end /* SCMOS rules revision 7 */ drc /* ---------------------------------------------------------------- */ /* Well */ /* ---------------------------------------------------------------- */ /* 1.1 */ /* Now use "edge" for width DRC... A test only for rule1 */ /* Other rules may follow in the near future... */ #ifdef SUBMICRON edge4way (~nwell)/w nwell 12 nwell nwell 12\\ "N-Well width must be at least 12 (MOSIS rule #1.1)" edge4way (~pwell)/w pwell 12 pwell pwell 12\\ "P-Well width must be at least 12 (MOSIS rule #1.1)" #else edge4way (~nwell)/w nwell 10 nwell nwell 10\\ "N-Well width must be at least 10 (MOSIS rule #1.1)" edge4way (~pwell)/w pwell 10 pwell pwell 10\\ "P-Well width must be at least 10 (MOSIS rule #1.1)" #endif /* original "width" rule which use 'width'command: width allWell 10 \\ "Well width must be at least 10 (MOSIS rule #1.1)" */ /* 1.2 */ /* Now use "edge4way" for spacing DRC... A test only for rule1 */ /* Other rules may follow in the near future... */ #ifdef SUBMICRON edge4way nwell ~(nwell)/w 18 (~nwell)/w (~nwell)/w 18\\ "N-Well spacing must be at least 18 (MOSIS rule #1.2)" edge4way pwell (~pwell)/w 18 (~pwell)/w (~pwell)/w 18\\ "P-Well spacing must be at least 18 (MOSIS rule #1.2)" #else edge4way nwell (~nwell)/w 9 (~nwell)/w (~nwell)/w 9\\ "N-Well spacing must be at least 9 (MOSIS rule #1.2)" edge4way pwell (~pwell)/w 9 (~pwell)/w (~pwell)/w 9\\ "P-Well spacing must be at least 9 (MOSIS rule #1.2)" #endif /* original spacing rule which use 'spacing' command: spacing allWell allWell 9 touching_ok \\ "Well spacing must be at least 9 (MOSIS rule #1.2)" */ /* NOTE: rule 1.2 is equivalent to the following three rules where the third is a new one. This rule is added to force designers to be cautious about the wells... spacing nwell nwell 9 touching_ok \\ "N-well spacing must be at least 9 (MOSIS rule #1.2)" spacing pwell pwell 9 touching_ok \\ "P-well spacing must be at least 9 (MOSIS rule #1.2)" spacing nwell pwell 9 touching_ok \\ "Well spacing must be at least 9 (MOSIS rule #1.2)" */ /* 1.3 is not checked */ /* NOTE: for digital ckts where wells are not explicitly put, * * auto-generation may not ensure the minimul spacing and width * * rule: this happens usually when two geometries are in diagonal * * positions. * * NOTE: when both pwell and nwell are submitted they cannot * * overlap this is assured with the compose section - painting one * * well over another will erase the original well. */ /* ---------------------------------------------------------------- */ /* Active */ /* ---------------------------------------------------------------- */ /* 2.1 */ /* Test active width separately... */ width allNActive 3 \\ "N-type Diffusion width must be at least 3 (MOSIS rule #2.1a)" width allPActive 3 \\ "P-type Diffusion width must be at least 3 (MOSIS rule #2.1b)" width allOhmic 3 \\ "Ohmic diffusion width must be at least 3 (MOSIS rule #2.1c)" /* 2.2 */ spacing allNActive allNActive 3 touching_ok \\ "Diffusion spacing must be at least 3 (MOSIS rule #2.2)" spacing allPActive allPActive 3 touching_ok \\ "Diffusion spacing must be at least 3 (MOSIS rule #2.2)" spacing allNOhmic allNOhmic 3 touching_ok \\ "Diffusion spacing must be at least 3 (MOSIS rule #2.2)" spacing allPOhmic allPOhmic 3 touching_ok \\ "Diffusion spacing must be at least 3 (MOSIS rule #2.2)" /* 2.3 without explicit well definition: 6+6 and 5+5 respectively */ #ifdef SUBMICRON spacing allNDiff allPDiff 12 touching_illegal \\ "P-type diffusion must be 12 away from N-type diffusion (MOSIS rule #2.3b)" #else spacing allNDiff allPDiff 10 touching_illegal \\ "P-type diffusion must be 10 away from N-type diffusion (MOSIS rule #2.3a)" #endif /* 2.3 + 2.4 without explicit well definition: 6+3 and 5+3 respectively */ #ifdef SUBMICRON spacing allNDiff allNOhmic 9 touching_illegal \\ "N-type diffusion must be 9 away from N-substrate contact (MOSIS rule #2.3b,4b)" spacing allPDiff allPOhmic 9 touching_illegal \\ "P-type diffusion must be 9 away from P-substrate contact (MOSIS rule #2.3b,4b)" #else spacing allNDiff allNOhmic 8 touching_illegal \\ "N-type diffusion must be 8 away from N-substrate contact (MOSIS rule #2.3a,4a)" spacing allPDiff allPOhmic 8 touching_illegal \\ "P-type diffusion must be 8 away from P-substrate contact (MOSIS rule #2.3a,4a)" #endif /* 2.4 3 + 3 */ spacing allNOhmic allPOhmic 6 touching_illegal \\ "Opposite well contacts must be separated by 6 (MOSIS rule #2.4)" /* 2.3 with explicit well: 6 and 5 respectively */ #ifdef SUBMICRON spacing allNActive nwell 6 touching_illegal \\ "N-diffusion and N-well must be separated by 6 (MOSIS rule #2.3b)" spacing allPActive pwell 6 touching_illegal \\ "P-diffusion and P-well must be separated by 6 (MOSIS rule #2.3b)" #else spacing allNActive nwell 5 touching_illegal \\ "N-diffusion and N-well must be separated by 5 (MOSIS rule #2.3a)" spacing allPActive pwell 5 touching_illegal \\ "P-diffusion and P-well must be separated by 5 (MOSIS rule #2.3a)" #endif /* 2.4 with explicit well */ spacing allNOhmic pwell 3 touching_illegal \\ "N-substrate diffusion and P-well must be separated by 3 (MOSIS rule #2.4)" spacing allPOhmic nwell 3 touching_illegal \\ "P-substrate diffusion and N-well must be separated by 3 (MOSIS rule #2.4)" /* MOSIS extension rule for diffusion and substrate contact of */ /* opposite type. We could do without this rule, but it is now */ /* added for safety reason. */ spacing allNActive allPOhmic 4 touching_ok \\ "Opposite diffusion spacing must be at least 4 (MOSIS extension rule)" spacing allPActive allNOhmic 4 touching_ok \\ "Opposite diffusion spacing must be at least 4 (MOSIS extension rule)" /* ---------------------------------------------------------------- */ /* Poly */ /* ---------------------------------------------------------------- */ /* 3.1 */ width allPoly 2 \\ "Polysilicon width must be at least 2 (MOSIS rule #3.1)" /* 3.2 */ #ifdef SUBMICRON spacing allPoly allPoly 3 touching_ok \\ "Polysilicon spacing must be at least 3 (MOSIS rule #3.2b)" #else spacing allPoly allPoly 2 touching_ok \\ "Polysilicon spacing must be at least 2 (MOSIS rule #3.2a)" #endif /* 3.3 */ edge4way nfet,pfet poly,pc/act 2 poly,pc/act 0 0 \\ "Poly must overhang transistor by at least 2 (MOSIS rule #3.3)" /* 3.4 */ edge4way nfet,enfet ndiff,ndc/a 3 allNActive ndiff,ndc/a 3 \\ "Diffusion must overhang transistor by at least 3 (MOSIS rule #3.4)" edge4way pfet,epfet pdiff,pdc/a 3 allPActive ndiff,ndc/a 3 \\ "Diffusion must overhang transistor by at least 3 (MOSIS rule #3.4)" /* 3.3 + 3.4 */ edge4way nfet,pfet space 1 poly 0 0 \\ "Transistor overhang is missing (MOSIS rule #3.3,4)" edge4way enfet,epfet space 1 poly2 0 0 \\ "Transistor overhang is missing (MOSIS rule #3.3,4)" edge4way nffet,pffet space 1 poly 0 0 \\ "Transistor overhang is missing (MOSIS rule #3.3,4)" edge4way nffet,pffet space 1 poly2 0 0 \\ "Transistor overhang is missing (MOSIS rule #3.3,4)" /* 3.5 */ edge4way allDiff,allOhmic poly,pc 1 space/a 0 1 \\ "Poly and diffusion must be separated by at least 1 (MOSIS rule #3.5)" edge4way poly,pc allDiff,allOhmic 1 space/a 0 1 \\ "Poly and diffusion must be separated by at least 1 (MOSIS rule #3.5)" edge poly,pc space/a 1 space/a space/a 1 \\ "Poly and diffusion must be separated by at least 1 (MOSIS rule #3.5)" edge allOhmic,allDiff space/a 1 space/a space/a 1 \\ "Poly and diffusion must be separated by at least 1 (MOSIS rule #3.5)" /* These following checks will miss the corner, so we add something above edge4way allDiff,allOhmic poly,pc 1 space space 1 \\ "Poly and diffusion must be separated by at least 1 (MOSIS rule #3.5.a)" spacing allDiff,allOhmic poly,pc 1 touching_illegal \\ "Poly and diffusion must be separated by at least 1 (MOSIS rule #3.5.b)" */ /* Extra transistor rules */ /* These rules is really NOT necessary because others have already taken care of it. It is here for future reference... edge4way poly,pc/act pfet 3 pfet 0 0 \\ "Transistors must be at least 3 units wide (MOSIS rule #2)" edge4way poly,pc/act nfet 3 nfet 0 0 \\ "Transistors must be at least 3 units wide (MOSIS rule #2)" */ /* ---------------------------------------------------------------- */ /* Select */ /* ---------------------------------------------------------------- */ /* 4.1 */ spacing PFet allNOhmic 3 touching_illegal \\ "Transistors must be separated from substrate contacts by 3 (MOSIS rule #4.1.a)" spacing NFet allPOhmic 3 touching_illegal \\ "Transistors must be separated from substrate contacts by 3 (MOSIS rule #4.1.b)" edge4way allPOhmic space/act 3 ~(NFet)/act allPOhmic,allNDiff 3 \\ "Transistors must be separated from selects(generated by well cont) by 3 (MOSIS rule #4.1.c)" edge4way allNOhmic space/act 3 ~(PFet)/act allNOhmic,allPDiff 3 \\ "Transistors must be separated from selects(generated by well cont) by 3 (MOSIS rule #4.1.d)" edge4way allPOhmic ~(ndiff,ndc,psc,psd)/act 4 ~(nfet,enfet)/act ~(ndiff,ndc,psc,psd)/act 4 \\ "Transistors must be separated from selects(generated by well cont) by 4 (MOSIS rule #4.1.e)" edge4way allNOhmic ~(pdiff,pdc,nsc,nsd)/act 4 ~(pfet,epfet)/act ~(pdiff,pdc,nsc,nsd)/act 4 \\ "Transistors must be separated from selects(generated by well cont) by 4 (MOSIS rule #4.1.f)" /* 4.2 */ /* This one is very difficult.... Most likely done by CIF output */ edge4way ~(allPActive)/act pdiff,pdc,pfet 4 ~(allNOhmic)/act allPActive 2 \\ "Backedge of diffusion must be 4 from substrate diff (MOSIS rule #4.2.a)" edge4way ~(allNActive)/act ndiff,ndc,nfet 4 ~(allPOhmic)/act allNActive 2 \\ "Backedge of diffusion must be 4 from substrate diff (MOSIS rule #4.2.b)" /* 4.3 -- guaranteed automatically by CIF generator. */ /* 4.4 -- guaranteed automatically by CIF generator except diag. where this rule is not crucial */ /* ---------------------------------------------------------------- */ /* Contact to Poly */ /* ---------------------------------------------------------------- */ /* 5B.1 + 5B.2 + 5B.3 */ width pc 4 \\ "Poly contact width must be at least 4 (MOSIS rule #5B.1,2,3)" /* 5B.4 is guaranteed by 5B.1,2,3 with rule 7.2 (metal1 spacing) */ /* 5B.5 -- * Watch out here: a spacing "touching_ok" rule CANNOT be used here: * it will miss certain checks. */ edge4way allPoly ~(allPoly)/act 3 ~pc/act ~(allPoly)/act 3 \\ "Poly contact must be at least 3 from other poly (MOSIS rule #5B.4,5)" /* 5B.6 -- * This is mostly handled by 3.5 already, but need rule here to handle * case of pc abutting transistor. */ spacing pc allActive 1 touching_illegal \\ "Poly contact must be 1 unit from diffusion (MOSIS rule #5B.6)" /* 5B.7 -- not implemented */ /* ---------------------------------------------------------------- */ /* Contact to Active */ /* ---------------------------------------------------------------- */ /* 6B.1 + 6B.2 + 6B.3 */ width ndc,pdc 4 \\ "Diffusion contact width must be at least 4 (MOSIS rule #6B.1,2,3)" width nsc,psc 4 \\ "Substrate contact width must be at least 4 (MOSIS rule #6B.1,2,3)" /* 6B.2 this is here to explicit check the contact spacing rule 3. */ #ifdef SUBMICRON spacing nsc pdc 1 touching_illegal \\ "Substrate contact must be 1 unit from diffusion contact (MOSIS rule #6B.2b)" spacing psc ndc 1 touching_illegal \\ "Substrate contact must be 1 unit from diffusion contact (MOSIS rule #6B.2b)" #endif /* edge4way psc (~psc)/a 1 psd psd 1 \\ "Substrate contact must overlapped by diffusion by at least 1 (MOSIS 26G rule)" edge4way nsc (~nsc)/a 1 nsd nsd 1 \\ "Substrate contact must overlapped by diffusion by at least 1 (MOSIS 26G rule)" */ /* 6B.4 & 6B.5 -- * Watch out here: a spacing "touching_ok" rule CANNOT be used here: * it will miss certain checks. */ edge4way allActive ~(allActive)/act 4 ~(ndc,pdc,nsc,psc)/act \\ ~(allActive)/act 4 \\ "Diffusion contacts must be 4 from other diffusions (MOSIS rule #6B.4,5)" /* 6B.6 */ spacing DiffCut allFet 1 touching_illegal \\ "Diffusion contacts cannot touch transistors (MOSIS rule #6B.6)" /* 6B.7 */ spacing DiffCut poly 1 touching_illegal \\ "Diffusion contact to field poly must be at least 1 (MOSIS rule #6B.7)" /* 6.8 -- not implemented */ /* 6B.9 */ spacing DiffCut pc/act 2 touching_illegal \\ "Poly contacts must be 2 away from diffusion contacts (MOSIS rule #6B.9)" /* ---------------------------------------------------------------- */ /* Contacts must all be rectangular (no adjacent contacts */ /* of same type) because of the way their contact is generated by */ /* CIFoutput section rules. This is handled using the corner checks */ /* in the rules below. Overlaps between contacts must be exact */ /* overlaps. The only exception is overpad, which doesn't matter. */ edge4way m3c/m3 ~m3c/m3 1 ~m3c/m3 (~m3c,m3c)/m3 1 \\ "Metal3 contacts must be rectangular (Magic rules)" edge4way m2c/m2 ~m2c/m2 1 ~m2c/m2 (~m2c,m2c)/m2 1 \\ "Metal2 contacts must be rectangular (Magic rules)" edge4way ndc/m1 ~ndc/m1 1 ~ndc/m1 (~ndc,ndc)/m1 1 \\ "N-diffusion contacts must be rectangular (Magic rules)" edge4way pdc/m1 ~pdc/m1 1 ~pdc/m1 (~pdc,pdc)/m1 1 \\ "P-diffusion contacts must be rectangular (Magic rules)" edge4way psc/m1 ~psc/m1 1 ~psc/m1 (~psc,psc)/m1 1 \\ "P-substrate contacts must be rectangular (Magic rules)" edge4way nsc/m1 ~nsc/m1 1 ~nsc/m1 (~nsc,nsc)/m1 1 \\ "N-substrate contacts must be rectangular (Magic rules)" edge4way pc/m1 ~pc/m1 1 ~pc/m1 (~pc,pc)/m1 1 \\ "Polysilicon contacts must be rectangular (Magic rules)" edge4way ec/m1 ~ec/m1 1 ~ec/m1 (~ec,ec)/m1 1 \\ "Electrode contacts must be rectangular (Magic rules)" edge4way cc/m1 ~cc/m1 1 ~cc/m1 (~cc,cc)/m1 1 \\ "Capacitor contacts must be rectangular (Magic rules)" edge4way emc/m1 ~emc/m1 1 ~emc/m1 (~emc,emc)/m1 1 \\ "Emitter contacts must be rectangular (Magic rules)" edge4way clc/m1 ~clc/m1 1 ~clc/m1 (~clc,clc)/m1 1 \\ "Collector contacts must be rectangular (Magic rules)" edge4way pbc/m1 ~pbc/m1 1 ~pbc/m1 (~pbc,pbc)/m1 1 \\ "P-base Contacts must be rectangular (Magic rules)" edge4way nbdc/m1 ~nbdc/m1 1 ~nbdc/m1 (~nbdc,nbdc)/m1 1 \\ "CCD-diffusion Contacts must be rectangular (Magic rules)" /* ---------------------------------------------------------------- */ /* Metal 1 */ /* ---------------------------------------------------------------- */ /* 7.1 + 7.2 */ width allMetal1,pad/m1 3 \\ "First-level metal width must be at least 3 (MOSIS rule #7.1)" #ifdef TIGHTMETAL spacing allMetal1,pad/m1 allMetal1,pad/m1 2 touching_ok \\ "First-level metal spacing must be at least 2 (MOSIS rule #7.2)" #else spacing allMetal1,pad/m1 allMetal1,pad/m1 3 touching_ok \\ "First-level metal spacing must be at least 3 (MOSIS rule #7.2)" #endif /* TIGHTMETAL */ /* 7.3 + 7.4 */ /* guaranteed with 4x4 poly and diffusion contacts */ /* ---------------------------------------------------------------- */ /* Via */ /* ---------------------------------------------------------------- */ /* 8.1 + 8.2 + 8.3 */ width m2c 4 \\ "Contact width must be at least 4 (MOSIS rule #8.1,2,3)" /* 8.4 + 8.5 */ /* Vias have to be on flat surface */ /* Don't allow poly or diffusion edges underneath metal2 contacts: */ /* this rule is only valid for standard processes, not for those */ /* processes use planarized interconnection technology. */ #ifdef STANDARD edge4way allPoly ~(allPoly)/a 1 ~m2c/m2 ~(allPoly)/a 1 \\ "Via must be on a flat surface (MOSIS rule #8.4,5)" metal2 edge4way allPoly2 ~(allPoly2)/a 1 ~m2c/m2 ~(allPoly2)/a 1 \\ "Via must be on a flat surface (MOSIS rule #8.4,5)" metal2 edge4way allActive ~(allActive)/a 1 ~m2c/m2 ~(allActive)/a 1 \\ "Via must be on a flat surface (MOSIS rule #8.4,5)" metal2 edge4way ~(allPoly)/a allPoly 1 ~m2c/m2 allPoly 1 \\ "Via must be on a flat surface (MOSIS rule #8.4,5)" metal2 edge4way ~(allPoly2)/a allPoly2 1 ~m2c/m2 allPoly2 1 \\ "Via must be on a flat surface (MOSIS rule #8.4,5)" metal2 edge4way ~(allActive)/a allActive 1 ~m2c/m2 allActive 1 \\ "Via must be on a flat surface (MOSIS rule #8.4,5)" metal2 #endif /* STANDARD */ /* ---------------------------------------------------------------- */ /* Metal 2 */ /* ---------------------------------------------------------------- */ /* 9.1 */ width allMetal2 3 \\ "Second-level metal width must be at least 3 (MOSIS rule #9.1)" /* 9.2 */ #ifdef TIGHTMETAL spacing allMetal2 allMetal2 3 touching_ok \\ "Second-level metal spacing must be at least 3 (MOSIS rule #9.2b)" #else #ifdef SUBMICRON spacing allMetal2 allMetal2 3 touching_ok \\ "Second-level metal spacing must be at least 3 (MOSIS rule #9.2b)" #else spacing allMetal2 allMetal2 4 touching_ok \\ "Second-level metal spacing must be at least 4 (MOSIS rule #9.2a)" #endif /* SUBMICRON */ #endif /* TIGHTMETAL */ /* 9.3 */ /* achieved with via size of 4x4 */ /* ---------------------------------------------------------------- */ /* Overglass */ /* ---------------------------------------------------------------- */ /* Rules for overglass (10.1-5) are not check because they are */ /* either */ /* 1. absolute micron rules, and */ /* 2. vender/process dependent. */ /* except the metal overlap of overglass rule (10.3) can be handled */ /* case by case in CIFoutput section. */ /* NOTE: glass layer is NOT usually used. Use "pad" layer for pad */ /* and the corresponding overglass will be generated automatically. */ /* MOSIS rules to make sure there are m2 under glass - for those */ /* users who like to use explicit "glass" layer... */ /* */ /* edge4way space glass 1 allMetal2 0 0 \ */ /* "There must be metal 2 under the glass openning" metal2 */ /* */ /* I am removing this rule simply we have metal3 now and there's no */ /* way to tell which process the pad is intended for. Basically, I */ /* am enforcing the use of "pad" layer... */ /* ---------------------------------------------------------------- */ /* Open and Pstop */ /* ---------------------------------------------------------------- */ /* The open layer is actually a combination of overglass and */ /* contacts to expose the intrinsic silicon surface for future */ /* etchimg process for micromachining device fabrication. */ /* Since lots of applications are possible, there is no rules */ /* enforced by Magic. Designers aimed at micromachining devices */ /* must do DRC themself :-) */ /* See the following reference for detail: */ /* "High-Level CAD Melds Micromachined Devices with Foundaries", */ /* Janet C. Marshall, M. Parameswaran, Mona E. Zaghloul, and */ /* Michael Gaitan, IEEE Circuit and Devices, Vol. 8, No. 6, */ /* pp. 10-17, 1992 */ /* ---------------------------------------------------------------- */ /* Poly2 as Capacitor */ /* ---------------------------------------------------------------- */ /* 11.1 */ /* The exact rule asks for 3 lambda minimum width for 'capacitor'. */ /* But there are overlaps of poly/eletrode structures such that 2 */ /* is fine, such as the overlaps in floating gates. So we are risk- */ /* ing a little here... */ width cap,capc/a 2 \\ "Electrode capacitor width must be at least 3 (MOSIS rule #11.1)" /* 11.2 + 12.2 */ spacing allPoly2 allPoly2 3 touching_ok \\ "Second-level poly spacing must be at least 3 (MOSIS rule #11.2,12.2)" /* 11.3 */ edge4way cap,cc space 1 0 0 0 \\ "Cap must be overlapped by poly or poly2 (MOSIS rule #11.3)" edge4way cap,cc poly 2 poly poly 2 \\ "Cap must be overlapped by poly or poly2 (MOSIS rule #11.3)" edge4way cap,cc poly2 2 poly2 poly2 2 \\ "Cap must be overlapped by poly or poly2 (MOSIS rule #11.3)" /* 11.4 */ edge4way nw,pw,cw ~(nw,pw,cw)/w 2 ~(cap,cc)/a ~(nw,pw,cw)/w 2 \\ "Cap must be on a flat surface (MOSIS rule #11.4)" active edge4way ~(nw,pw,cw)/w nw,pw,cw 2 ~(cap,cc)/a nw,pw,cw 2 \\ "Cap must be on a flat surface (MOSIS rule #11.4)" active edge4way cap ~(cap)/a 2 allFet,poly,poly2,space/a,cc/a \\ allDiff,poly 2 "Cap must be on a flat surface (MOSIS rule #11.4)" active /* 11.5 */ /* Done by 11.3 and 11.4 */ /* ---------------------------------------------------------------- */ /* Poly2 as Transistor */ /* ---------------------------------------------------------------- */ /* 12.1 */ width allPoly2 2 \\ "Electrode width must be at least 2 (MOSIS rule #12.1)" /* 12.2 */ /* Done by 11.2 */ /* 12.3 */ edge4way enfet,epfet poly2,ec/a 2 poly2,ec/a 0 0 \\ "Poly2 must overhang transistor by at least 2 (MOSIS rule #12.3)" edge4way nffet,pffet cap 2 cap 0 0 \\ "Cap must overhang transistor by at least 2 (MOSIS rule #12.3)" edge4way nffet ~(cap,nffet,enfet,nfet)/a 2 cap 0 0 \\ "Cap must overhang doubletransistor by at least 2 (MOSIS rule #12.3)" edge4way pffet ~(cap,pffet,epfet,pfet)/a 2 cap 0 0 \\ "Cap must overhang doubletransistor by at least 2 (MOSIS rule #12.3)" /* 12.4 */ edge4way allDiff,allOhmic el 1 space/a 0 1 \\ "Poly2 and diffusion must be separated by at least 1 (MOSIS rule #12.4)" /* 12.5 */ /* 12.6 */ spacing allPoly2 pc,ndc,pdc 2 touching_illegal \\ "Poly2 spacing to poly or diffusion contact must be at least 3 (MOSIS rule #12.6)" /* edge4way poly2,ec/a epfet 3 epfet 0 0 \\ "Transistors must be at least 3 units wide (MOSIS rule #2)" edge4way poly2,ec/a enfet 3 enfet 0 0 \\ "Transistors must be at least 3 units wide (MOSIS rule #2)" edge4way cap,capc/a pffet 3 pffet 0 0 \\ "Transistors must be at least 3 units wide (MOSIS rule #2)" edge4way cap,capc/a nffet 3 nffet 0 0 \\ "Transistors must be at least 3 units wide (MOSIS rule #2)" */ /* ---------------------------------------------------------------- */ /* Poly2 Contact */ /* ---------------------------------------------------------------- */ /* 13.1 + 13.2 */ width ec,capc 4 \\ "Electrode contact width must be at least 4 (MOSIS rule #13.1)" /* 13.3 */ /* Done by 11.3 */ /* 13.4 */ edge4way ec/a space 1 poly2 poly2 1 \\ "Electrode contact must be overlaped by poly2 (MOSIS rule #13.4)" edge4way ec/a poly2 1 poly2 poly2 1 \\ "Electrode contact must be overlaped by poly2 by 1 (MOSIS rule #13.4)" /* 13.5 */ edge4way allDiff,allOhmic ec 2 space/a 0 2 \\ "Poly2 and diffusion contact must be separated by at least 2 (MOSIS rule #13.5)" /* ---------------------------------------------------------------- */ /* Via 2 */ /* ---------------------------------------------------------------- */ /* 14.1 + 14.2 + 14.3 */ /* By CIF output generation */ width m3c 4 \\ "Third-level metal contact width must be at least 4 (MOSIS rule #14.1,2,3)" /* 14.4 */ /* guaranteed by 4x4 m2c and 4x4 m3c */ /* Via2, i.e "m3c" can overlap anything except m2c layer */ /* ---------------------------------------------------------------- */ /* Metal 3 */ /* ---------------------------------------------------------------- */ /* 15.1 */ #ifdef SUBMICRON width allMetal3 5 \\ "Third-level metal width must be at least 5 (MOSIS rule #15.1b)" #else width allMetal3 6 \\ "Third-level metal width must be at least 6 (MOSIS rule #15.1a)" #endif /* 15.2 */ #ifdef SUBMICRON spacing allMetal3 allMetal3 3 touching_ok \\ "Third-level metal spacing must be at least 3 from other third-level metal (MOSIS rule #15.2b)" #else spacing allMetal3 allMetal3 4 touching_ok \\ "Third-level metal spacing must be at least 4 from other third-level metal (MOSIS rule #15.2a)" #endif /* 15.3 */ edge4way m3c/m3 ~m3c/m3 1 m3 m3 1 \\ "Mimimum metal3 overlap of via must be at least 1 (MOSIS rule #15.3)" /* ---------------------------------------------------------------- */ /* NPN Bipolar */ /* ---------------------------------------------------------------- */ /* 16.1 */ /* As always, composite contacts are 4x4, where the actual */ /* transistor contacts are 2x2 by CIF output generator */ width clc,pbc,emc 4 \\ "Transistor contact width must be at least 4 (MOSIS rule #16.1)" /* 16.2 */ /* Done by 16.1 4x4 emc and CIF output generation */ /* 16.3 */ /* This rule is guaranteed by the way the CIF output generates */ /* N-Select for emitter (expand by 2 lambda), so we have Pbase */ /* overlap of emitter(or emc) by 2+2 =4 */ edge4way emc/a,emit pbase 4 pbase pbase 4 \\ "Pbase overlap of emitter must be at least 4 (MOSIS rule #16.3)" /* 16.4 */ /* NOTE; NO need to make this an edge rule... */ spacing pbc emc/a,emit 7 touching_illegal \\ "Base must be 7 (4+2+1) away from emitter (MOSIS rule #16.3,4,11)" /* 16.5 */ /* This rule is guaranteed by requiring that base contact has */ /* at least 3 (1+2) lambda base enclosure... */ /* edge4way pbc/a pb,space 3 pb pb,space 3 */ edge4way pbc (~pbc)/a 3 pb,pbc/a pb,pbc/a 3 \\ "Pbase overlap of base contact must be at least 3 (MOSIS rule #16.5)" /* 16.6 */ /* This rule is guaranteed by the CIF output generation of P-select */ /* 16.6 */ /* This rule is enforced by checking whether collector is out of */ /* Nwell and the fact that collector width is required to be at */ /* least 6 */ width col,clc/a 6 \\ "Collector width must be at least 6 (MOSIS rule #16.6)" /* 16.7 */ /* Explicit Nwell required for Bipolar transistors... */ edge4way pbase space/a 6 nwell space/a 6 \\ "Nwell overlap of Pbase must be at least 6 (MOSIS rule #16.7)" well /* 16.8 */ edge4way pbase (~pbase)/a 4 ~(col,clc)/a ~(col,clc)/a 4 \\ "Pbase must be at least 4 away from collector (MOSIS rule #16.8)" /* 16.9 */ edge4way clc (~clc)/a 1 col col 1 \\ "Collector overlap of contact must be at least 1 (MOSIS rule #16.9)" /* 16.10 */ /* This rule is guaranteed by making sure that collector is within */ /* PBase and the corresponding CIF output generation */ /* 16.11 */ edge4way nw ~(nw)/w 3 ~(col,clc)/a ~(nw)/w 3 \\ "N-well overlap of collector must be at least 3 (MOSIS rule #16.11)" active edge4way ~(nw)/w nw 3 ~(col,clc)/a nw 3 \\ "N-well overlap of collector must be at least 3 (MOSIS rule #16.11)" active /* This is a special rule to gurantee the emitter width */ width em,emc/a 4 \\ "Emitter width must be at least 4 (Magic Bipolar Transistor rule)" /* This is a special rule for multi-emitters transistor according */ /* to rule 16.2 and 2.2 */ spacing em,emc/a em,emc/a 7 touching_ok \\ "Unrelated emitter must be at least 7 apart (Magic Bipolar transistor rule)" /* The following rules are added for pbase resistor implementation. */ /* They are not in the official SCMOS design rules since I have no */ /* foundry rules available at this moment and the numbers here is */ /* considered to be conservative... */ width pbase,pbc/a 4 \\ "Pbase width must be at least 4 (MOSIS extension rule)" spacing pbase,pbc/a pbase,pbc/a 4 touching_ok \\ "Pbase spacing must be at least 4 (MOSIS extension rule)" /* ---------------------------------------------------------------- */ /* Capacitor Well */ /* ---------------------------------------------------------------- */ /* These are DRC rules for Capacitor Well (CWell) according to HP's */ /* 1.2um linear capacitor process pi@isi.edu 9/18/92 */ /* ---------------------------------------------------------------- */ /* 17.1 */ width cwell 10 \\ "Cap-well width must be at least 10 (MOSIS rule #17.1)" /* 17.2 */ spacing cwell cwell 9 touching_ok \\ "Cap-well spacing must be at least 9 (MOSIS rule #17.2)" spacing cwell nwell 9 touching_illegal \\ "Cap-well spacing must be at least 9 (MOSIS rule #17.2)" /* 17.3 */ edge4way cwell space 5 ~(allNActive)/a ~(allNActive)/w 5 \\ "Cap-well spacing to external active must be at least 5 (MOSIS rule #17.3)" active edge4way cwell space 3 ~(allPOhmic)/a ~(allPOhmic)/w 3 \\ "P-substrate diffusion and Cap-well must be separated by 3 (MOSIS rule #17.3)" active /* 17.4 */ /* Need to do this check from the Cap-well plane - in order Not */ /* to conflict with the general rules for N-diffusion */ edge4way space cwell 3 (space,poly,pc)/a 0 0 \\ "Cap-well overlap of diffusion must be at least 3 (MOSIS rule #17.4)" active /* ---------------------------------------------------------------- */ /* Well-capacitor */ /* ---------------------------------------------------------------- */ /* These are DRC rules for Well-capacitor (wcap) according to HP's */ /* 1.2um linear capacitor process pi@isi.edu 9/18/92 */ /* Rule 18.5 and 18.6 are preliminary, they are conservative here! */ /* ---------------------------------------------------------------- */ /* 18.1 */ width wcap 3 \\ "Well-capacitor must be at least 3 (MOSIS rule #18.1)" /* 18.2 */ /* achieved by rule 3.5 */ /* 18.3 */ edge4way wcap space 1 poly poly 1 \\ "Well-capacitor overhang is missing (MOSIS rule #18.3)" /* 18.4 */ edge4way wcap ndiff 3 ndiff ndiff 3 \\ "N-diffusion overlap of well-capacitor must be at least 3 (MOSIS rule #18.4)" /* 18.5 */ /* achieved by rule 5B.6 */ spacing wcap pc 2 touching_illegal \\ "Well-capacitor spacing to poly contact must be at least 2 (MOSIS rule #18.5)" /* 18.6 */ /* similar to rule 6A.4 or 6B.6 */ spacing wcap ndc 4 touching_illegal \\ "Well-capacitor spacing to diffusion contact must be at least 4 (MOSIS rule #18.6)" /* ---------------------------------------------------------------- */ /* Buried CCD */ /* ---------------------------------------------------------------- */ /* 19.1 */ /* Have to do it seperately... */ width nbd,nbdc,bd/a 4 \\ "CCD channel width must be at least 4 (MOSIS rule #19.1)" width nbdc 4 \\ "CCD contact width must be at least 4 (MOSIS rule #19.1)" /* 19.2 */ /* The 4 lambda spacing is a conservative guess here... */ /* This following rule will NOT work! Need to check 2 planes */ /* separately.... */ /* spacing bd/a,nbd,nbdc bd/a,nbd,nbdc 4 touching_ok \\ "CCD channel spacing must be at least 4 (MOSIS rule #19.2)" */ edge4way nbd,nbdc ~(bd,nbd,nbdc)/a 4 (bd,space)/i 0 0 \\ "CCD channel spacing must be at least 4 (MOSIS rule #19.2)" implant edge4way nbd,nbdc ~(poly,nbd,nbdc)/a 4 ~(poly,nbd,nbdc)/a ~(poly,nbd,nbdc)/a 4 \\ "CCD channel spacing must be at least 4 (MOSIS rule #19.2)" active /* 19.3 + 19.4 + 19.5 */ /* guranteed by the CIF output generation */ /* 19.6 */ /* This first one check poly and electrode overhang */ edge4way bd space 2 nbd,poly,cap,el 0 0 \\ "CCD channel overhang is missing (MOSIS rule #19.6)" active /* There is a problem with capacitor overhang, I have no way to do */ /* it now... */ /* MOSIS extension BCCD layout rule */ spacing nbdc poly,el 1 touching_illegal \\ "CCD-diffusion contact spacing to poly must be at least 1 (MOSIS CCD rule)" edge4way nbd poly,el 1 bd 0 0 \\ "Missing Buried CCD Difussion layer (MOSIS CCD rule)" implant /* ---------------------------------------------------------------- */ /* High-Voltage MOSFETs */ /* ---------------------------------------------------------------- */ /* These are DRC rules for AMI 1.5 micron process for high-voltage */ /* MOSFETs pi@isi.edu 10/01/92 */ /* */ /* ---------------------------------------------------------------- */ /* 20.1 */ /* Well spacing for different potential must be 12 lambda away now. */ /* These rules correspond to 1.1 + 1.2 rules */ /* width rule is as usual */ edge (~hnwell)/w hnwell 10 hnwell hnwell 10\\ "High-Voltage N-Well width must be at least 10 (MOSIS rule #1.1)" edge (~hpwell)/w hpwell 10 hpwell hpwell 10\\ "High-Voltage P-Well width must be at least 10 (MOSIS rule #1.1)" /* spacing rules are new */ edge hnwell space,pw,hpw 9 space,pw,hpw space,pw,hpw 9\\ "High-Voltage N-Well spacing to N-Well must be at least 9 (MOSIS rule #1.2)" edge hpwell space,nw,hnw 9 space,nw,hnw space,nw,hnw 9\\ "High-Voltage P-Well spacing to P-Well must be at least 9 (MOSIS rule #1.2)" edge hnwell space,pw,hpw,nw 12 space,pw,hpw,nw space,pw,hpw,nw 12\\ "High-Voltage N-Well spacing must be at least 12 (MOSIS rule #20.1)" edge hpwell space,nw,hnw,pw 12 space,nw,hnw,pw space,nw,hnw,pw 12\\ "High-Voltage P-Well spacing must be at least 12 (MOSIS rule #20.1)" /* 20.2 */ /* High-Voltage Active spacing must be at least 5 lambda away */ /* This rule corresponds to 2.2 rule */ #define allHVNActive hndiff,hndc/a,hnfet #define allHVPActive hpdiff,hpdc/a,hpfet edge4way ~(allHVDiff)/a allHVDiff 3 allHVDiff allHVDiff 3\\ "High-Voltage Diffusion width must be at least 3 (MOSIS rule #2.1)" spacing allHVNActive allHVNActive 5 touching_ok \\ "High-Voltage Diffusion spacing must be at least 5 (MOSIS rule #20.2)" spacing allHVPActive allHVPActive 5 touching_ok \\ "High-Voltage Diffusion spacing must be at least 5 (MOSIS rule #20.2)" /* 20.3 */ /* High-Voltage transistors spacing to Well edge must be 7 lambda */ /* This rule corresponds to rule 2.3 */ /* without explicit well definition */ spacing hndiff,hndc/a hpdiff,hpdc/a 14 touching_illegal \\ "P-type diffusion must be 14 away from N-type diffusion (MOSIS rule #20.3)" spacing hndiff,hndc/a allPDiff 12 touching_illegal \\ "P-type diffusion must be 12 away from N-type diffusion (MOSIS rule #20.3+2.3)" spacing hpdiff,hpdc/a allNDiff 12 touching_illegal \\ "P-type diffusion must be 12 away from N-type diffusion (MOSIS rule #20.3+2.3)" /* with explicit well definition */ spacing hndiff,hnfet,hndc/a hnwell 7 touching_illegal \\ "HVN-diffusion and HVN-well must be separated by 7 (MOSIS rule #20.3)" spacing hpdiff,hpfet,hpdc/a hpwell 7 touching_illegal \\ "HVP-diffusion and HVP-well must be separated by 7 (MOSIS rule #20.3)" spacing allNOhmic hpwell 3 touching_illegal \\ "N-substrate diffusion and HVP-well must be separated by 3 (MOSIS rule #2.4+20.3)" spacing allPOhmic hnwell 3 touching_illegal \\ "P-substrate diffusion and HVN-well must be separated by 3 (MOSIS rule #2.4+20.3)" /* 20.4 */ /* Poly1 must not be used as an transistor for high-voltage design */ /* guranteed by the composition rules */ /* 20.5 */ /* High-Voltage Active overlap of contact is now 2 lambda */ /* This rule corresponds to rule 6B.2 */ edge (~hndc)/a hndc/a 6 hndc/a hndc/a 6\\ "High-Voltage Diffusion contact width must be at least 6 (MOSIS rule #20.5)" edge (~hpdc)/a hpdc/a 6 hpdc/a hpdc/a 6\\ "High-Voltage Diffusion contact width must be at least 6 (MOSIS rule #20.5)" /* 20.6 */ /* High-Voltage transistor channel length must be at least 4 lambda */ edge hpdiff,hpdc/a hpfet 4 hpfet 0 0 \\ "High-Voltage transistor must be at least 4 units long (MOSIS rule #20.6)" edge hndiff,hndc/a hnfet 4 hnfet 0 0 \\ "High-Voltage transistor must be at least 4 units long (MOSIS rule #20.6)" /* ---------------------------------------------------------------- */ /* overlapping rules */ exact_overlap m3c,m2c,ndc,pdc,pc,psc,nsc,ec,capc,clc,emc,pbc,hndc,hpdc,hnsc,hpsc no_overlap pfet,nfet pfet,nfet no_overlap epfet,enfet epfet,enfet no_overlap pffet,nffet pffet,nffet no_overlap hpfet,hnfet hpfet,hnfet end extract #ifndef OLD_EXTRACT_STYLE #include "scmosExt.tech.in" #else /* In the following, MOSIS provides 9 extraction styles as follows: SCNA20(ORB) - ORBIT 2.0 micron low-noise analog N-well CMOS/BJT process. *default* SCPE20(ORB) - ORBIT 2.0 micron P-well CMOS/Bulk process. SCNA16(AMI) - AMI 1.6 micron N-well CMOS/Junction-isolated BJT process. SCN12LC(HP) - HP CMOS34 1.2 micron N-well CMOS/Bulk process with linear capacitor option. SCNE12(ORB) - ORBIT 1.2 micron 2 poly N/P-well CMOS process. SCN10(MOT) - MOTOROLA 1.0 micron N-well/P-epi CMOS process. * Not Available at this moment * SCN08(HP) - HP CMOS26B 1.0 micron N-well CMOS/Bulk process. SCN08(IBM) - IBM 0.8 micron N-well CMOS/Bulk process. * Not Available at this moment * Whenever it is available, measured data on MOSIS test structures is used. Data is obtained from a representitive run (usually the latest run at the time). If not available, typical (or nominal) data from vendor wafer specification is used if not specifically noted. */ /* Have to redefine allMetal1 to make it pure metal line here... */ #undef allMetal1 #define allMetal1 m1,m2c/m1 #ifdef STANDARD style SCNA20(ORB) /* The following data is obtained from MOSIS run 'n34o' */ /* Last modified by pi@isi.edu, 9/29/93 */ /* Define plane order first */ #ifdef V5 planeorder well 0 planeorder implant 1 planeorder active 2 planeorder metal1 3 planeorder metal2 4 planeorder metal3 5 planeorder oxide 6 #endif cscale 1 lambda 100 step 100 /* No parallel wire coupling capacitances */ sidehalo 0 /* Sheet resistance (in milliohms per square) */ resist ndiff,nsd,ndc/a,nsc/a 27260 resist pdiff,psd,pdc/a,psc/a 59550 resist allPoly 23430 resist allPoly2 19690 resist em,emc/a 27260 resist pbase,pbc/a 2000000 resist metal1,m2c/metal1 52 resist metal2,pad 26 resist nwell 2505830 /* Contact resistance (in milliohms per square) */ contact pc/a 4 11000 contact ec/a,capc/a 4 9000 contact ndc/a,nsc/a 4 18710 contact pdc/a,psc/a 4 100560 /* Area parasitic capacitance to substrate (in attofarads per lambda square) [ 1 lambda = 1.0 micron ---> multiplication factor 1.0 ] NOTE: Since most of the simulation tools have already included the gate-oxide capacitance, it is NOT extracted here. If you need it explictly, remove the following comment. */ areacap poly,pc/a 39 areacap metal1,pad,m2c/metal1 24 areacap metal2 19 /* areacap ndiff,ndc/a 220 areacap pdiff,pdc/a 270 */ areacap cc/a,cap 39 areacap poly2,ec/a 50 /* Inter-layer capacitance */ overlap metal1 pdiff,ndiff,psd,nsd 47 overlap metal2 pdiff,ndiff,psd,nsd 22 metal1 overlap metal1 poly 30 overlap metal2 poly 19 metal1 overlap metal2 metal1 45 overlap metal1 poly2 40 /* Perimeter parasitic capacitances (in attofarads per lambda) [ 1 lambda = 1.0 micron ---> multiplication factor 1.0 ] */ /* perimc ndiff,ndc/a space,pwell 559 perimc pdiff,pdc/a space,nwell 402 */ perimc poly,pc/a space,pwell,nwell 80 /* Active devices: N-Well process */ fet pfet pdiff,pdc,pffet 2 pfet Vdd! nwell 0 0 fet nfet ndiff,ndc,nffet 2 nfet GND! pwell 0 0 fet epfet pdiff,pdc,pffet 2 epfet Vdd! 0 0 fet enfet ndiff,ndc,nffet 2 enfet GND! 0 0 /* Kludge for MOS capacitance extraction, where source and drain are connected together */ fet pfet pdiff,pdc,pffet 1 pfet Vdd! nwell 0 0 fet nfet ndiff,ndc,nffet 1 nfet GND! pwell 0 0 /* Electrode capacitance extraction */ device capacitor None cap,capc/a poly,pc 120 735 /* DRAM capacitance extraction */ device capacitor None wcap ndiff,ndc 300 0 /* bipolar NPN extraction */ device bjt npn emit,emc/a pbase,pbc/a nwell style SCPE20(ORB) /* The following data is obtained from MOSIS run 'n35s', 6/93 */ /* Last modified by pi@isi.edu, 9/29/93 */ cscale 1 lambda 100 step 100 /* No parallel wire coupling capacitances */ sidehalo 0 /* Define plane order first */ #ifdef V5 planeorder well 0 planeorder implant 1 planeorder active 2 planeorder metal1 3 planeorder metal2 4 planeorder metal3 5 planeorder oxide 6 #endif /* Sheet resistance (in milliohms per square) */ resist ndiff,nsd,ndc/a,nsc/a 26670 resist pdiff,psd,pdc/a,psc/a 72860 resist allPoly 23860 resist allPoly2 18540 resist metal1,m2c/metal1 49 resist metal2,pad 26 resist pwell 2128280 /* Contact resistance (in milliohm per contact) */ contact pc/a 4 12800 contact ec/a,capc/a 4 8420 contact ndc/a,nsc/a 4 36660 contact pdc/a,psc/a 4 56300 contact m2c/m1 5 30 /* Area parasitic capacitance to substrate (in attofarads per lambda square) [ 1 lambda = 1.0 micron ---> multiplication factor 1.0 ] NOTE: Since most of the simulation tools have already included the gate-oxide capacitance, it is NOT extracted here. If you need it explictly, remove the following comment. */ areacap poly,pc/a 57 areacap allMetal1,DiffMetal,HVDiffMetal 41 areacap PolyMetal,BiMetal,CCDMetal 41 areacap allMetal2 21 /* areacap ndiff,ndc/a 398 areacap pdiff,pdc/a 230 */ /* Inter-layer capacitance */ overlap metal1 pdiff,ndiff,psd,nsd 36 overlap metal2 pdiff,ndiff,psd,nsd 16 metal1 overlap metal1 poly 33 overlap metal2 poly 15 metal1 overlap metal2 metal1 29 overlap metal1 poly2,cap 33 /* Perimeter parasitic capacitances (in attofarads per lambda) [ 1 lambda = 1.0 micron ---> multiplication factor 1.0 ] */ /* perimc ndiff,ndc/a space,pwell 423 perimc pdiff,pdc/a space,nwell 85 */ perimc poly,pc/a space,pwell,nwell 168 /* Active devices: P-Well process */ fet pfet pdiff,pdc 2 pfet Vdd! nwell 0 0 fet nfet ndiff,ndc 2 nfet GND! pwell 0 0 style SCNA16(AMI) /* The following data is obtained from MOSIS run 'n34l', 6/93 */ /* Last modified by pi@isi.edu, 9/29/93 */ cscale 1 lambda 80 step 100 /* No parallel wire coupling capacitances */ sidehalo 0 /* Define plane order first */ #ifdef V5 planeorder well 0 planeorder implant 1 planeorder active 2 planeorder metal1 3 planeorder metal2 4 planeorder metal3 5 planeorder oxide 6 #endif /* Sheet resistance (in milliohms per square) */ resist ndiff,nsd,ndc/a,nsc/a 51680 resist pdiff,psd,pdc/a,psc/a 74800 resist allPoly 34780 resist allPoly2 22400 resist allMetal1 48 resist allMetal2 28 resist nwell 1446400 /* Contact resistance (in milliohm per contact) */ contact pc 4 61560 contact ec 4 12010 contact ndc,nsc 4 45780 contact pdc,psc 4 32310 contact m2c 5 37570 /* Area parasitic capacitances (in attofarads per lambda square) [ 1 lambda = 0.8 micron ---> multiplication factor 0.64 ] NOTE: Since most of the simulation tools have already included the gate-oxide capacitance, it is NOT extracted here. If you need it explictly, remove the following comment. */ /* areacap nfet 709 */ /* areacap pfet 669 */ areacap poly,pc/a 22 areacap allMetal1,DiffMetal,HVDiffMetal 15 areacap PolyMetal,BiMetal,CCDMetal 15 areacap allMetal2 10 /* Inter-layer capacitance */ overlap allMetal1 ndiff,nsd 27 overlap allMetal1 pdiff,psd 27 overlap allMetal2 pdiff,psd 12 metal1 overlap allMetal1 allPoly 25 overlap allMetal1 allP2 25 overlap allMetal2 allPoly 11 metal1 overlap metal2 metal1 23 /* Junction capacitance */ /* overlap ndiff,ndc/a space,pwell 172 overlap pdiff,pdc/a space,nwell 200 */ /* Perimeter parasitic capacitances (in attofarads per lambda) [ 1 lambda = 0.8 micron ---> multiplication factor 0.8 ] */ /* perimc ndiff,ndc/a space,allWell 6 perimc pdiff,pdc/a space,allWell 68 */ /* Active devices: N-Well process, */ fet pfet pdiff,pdc 2 pfet Vdd! nwell 0 0 fet nfet ndiff,ndc 2 nfet GND! pwell 0 0 style SCNE12(ORB) /* The following data is obtained from MOSIS run 'n37d', 7/93 */ /* Last modified by pi@isi.edu, 9/29/93 */ cscale 1 lambda 60 step 100 /* No parallel wire coupling capacitances */ sidehalo 0 /* Define plane order first */ #ifdef V5 planeorder well 0 planeorder implant 1 planeorder active 2 planeorder metal1 3 planeorder metal2 4 planeorder metal3 5 planeorder oxide 6 #endif /* Sheet resistances (in milliohms per square) */ resist ndiff,nsd,ndc/a,nsc/a 43180 resist pdiff,psd,pdc/a,psc/a 79770 resist allPoly 22160 resist allPoly2 21140 resist allMetal1 51 resist allMetal2 26 resist nwell 1195000 /* Contact resistances (in milliohm per contact) */ contact pc 4 13230 contact ec 4 13510 contact ndc,nsc 4 56490 contact pdc,psc 4 181400 contact m2c 5 43330 /* Area parasitic capacitances (in attofarads per lambda square) [ 1 lambda = 0.6 micron ---> multiplication factor 0.36 ] NOTE: Since most of the simulation tools have already included the gate-oxide capacitance, it is NOT extracted here. If you need it explictly, remove the following comment. */ /* areacap nfet 454 */ /* areacap pfet 368 */ areacap poly,pc/a 29 areacap allMetal1,DiffMetal,HVDiffMetal 16 areacap PolyMetal,BiMetal,CCDMetal 16 areacap allMetal2 10 overlap allMetal1 ndiff,ndc/a 22 overlap allMetal1 allPoly 19 overlap allMetal1 allP2 21 overlap allMetal2 ndiff,ndc/a 8 overlap allMetal2 allPoly 7 overlap metal2 metal1 12 /* Junction capacitance */ overlap ndiff,ndc/a space,pwell 185 overlap pdiff,pdc/a space,nwell 148 /* Perimeter parasitic capacitances (in attofarads per lambda) [ 1 lambda = 0.6 micron ---> multiplication factor 0.6 ] */ perimc allMetal1 space,allWell 41 perimc allMetal2 space,allWell 42 /* Junction capacitances */ /* perimc ndiff,ndc/a space,pwell 236 perimc pdiff,pdc/a space,nwell 147 */ /* No measurements for this run, but leave here for future... sideoverlap allMetal1 space,allWell PNplus 60 sideoverlap allMetal2 space,allWell allPoly 60 sideoverlap allMetal2 space,allWell PNplus 57 sideoverlap allMetal2 space,allWell allPoly 57 sideoverlap allMetal2 space,allWell allMetal1 64 */ /* Nwell process, so PMOS has "nwell" defined for analog designs... */ fet pfet pdiff,pdc 2 pfet Vdd! nwell 0 0 fet nfet ndiff,ndc 2 nfet GND! pwell 0 0 #endif /* STANDARD */ #ifdef TIGHTMETAL style SCN12LC(HP) /* The following data is obtained from MOSIS run 'n36y', 7/93 */ /* Last modified by pi@isi.edu, 9/29/93 */ cscale 1 lambda 60 step 100 /* No parallel wire coupling capacitances */ sidehalo 0 /* Define plane order first */ #ifdef V5 planeorder well 0 planeorder implant 1 planeorder active 2 planeorder metal1 3 planeorder metal2 4 planeorder metal3 5 planeorder oxide 6 #endif /* Sheet resistance (in milliohms per square) */ resist ndiff,nnd,ndc/a,nsc/a 74630 resist pdiff,ppd,pdc/a,psc/a 109590 resist poly,pc/a,pfet,nfet 26620 resist allMetal1 60 resist allMetal2 39 resist nwell 1500000 /* Contact resistance (in milliohm per contact) */ contact ndc 4 77000 contact pdc 4 44260 contact pc 4 16210 contact m2c 5 86560 /* Area parasitic capacitances (in attofarads per lambda square) [ 1 lambda = 0.6 micron ---> multiplication factor 0.36 ] NOTE: Since most of the simulation tools have already included the gate-oxide capacitance, it is NOT extracted here. If you need it explictly, remove the following comment. */ /* areacap nfet 556 */ /* areacap pfet 489 */ areacap poly,pc/a 22 areacap allMetal1,DiffMetal,HVDiffMetal 14 areacap PolyMetal,BiMetal,CCDMetal 14 areacap allMetal2 9 /* Inter-layer capacitance */ overlap allMetal1 allPoly 24 overlap allMetal2 allPoly 7 metal1 overlap metal2 metal1 14 /* Junction capacitance */ /* overlap ndiff,ndc/a space,pwell 106 overlap pdiff,pdc/a space,nwell 183 */ /* Perimeter parasitic capacitances (in attofarads per lambda) [ 1 lambda = 0.6 micron ---> multiplication factor 0.6 ] */ /* perimc nfet ndiff 90 */ /* perimc pfet pdiff 817 */ /* Junction capacitances */ /* perimc ndiff,ndc/a space,allWell 102 perimc pdiff,pdc/a space,allWell 2 */ /* Active devices: Nwell process, so PMOS has "nwell" defined for analog designs... */ fet pfet pdiff,pdc 2 pfet Vdd! nwell 0 0 fet nfet ndiff,ndc 2 nfet GND! pwell 0 0 /* Kludge for DRAM capacitance extraction */ fet wcap ndiff,ndc 1 wcap GND! 300 0 /* These stuff are experimental..... fake npn: fet emit,emc/a pbase 1 d1np XSLLU! nwell 0 0 fet fpb nwell 1 d2pn YSLLU! col,clc 0 0 */ /* saturation :: R = V (5V) / Idss fetresist nfet saturation 12000 fetresist pfet saturation 28000 fetresist enfet saturation 12000 fetresist epfet saturation 28000 I am not sure how to do this yet, so I give the same value as saturation! fetresist nfet linear 12000 fetresist pfet linear 28000 fetresist enfet linear 12000 fetresist epfet linear 28000 */ style SCN08(HP) /* The following data is obtained from MOSIS run 'n33h', 7/93 */ /* Last modified by pi@isi.edu, 9/29/93 */ cscale 1 lambda 50 step 100 /* Parallel wire coupling capacitance enabled */ sidehalo 8 /* Define plane order first */ #ifdef V5 planeorder well 0 planeorder implant 1 planeorder active 2 planeorder metal1 3 planeorder metal2 4 planeorder metal3 5 planeorder oxide 6 #endif /* Sheet resistance (in milliohms per square) */ resist ndiff,nsd,ndc/a,nsc/a 2280 resist pdiff,psd,pdc/a,psc/a 1990 resist poly 3480 resist allMetal1 67 resist allMetal2 65 resist allMetal3 29 resist nwell 1265560 /* Contact resistance (in milliohm per contact) */ contact pc 4 1680 contact ndc,pdc,nsc,psc 4 1100 contact m2c 5 305 contact m3c 5 259 /* Area parasitic capacitances (in attofarads per lambda square) [ 1 lambda = 0.5 micron ---> multiplication factor 0.25 ] NOTE: Since most of the simulation tools have already included the gate-oxide capacitance, it is NOT extracted here. If you need it explictly, remove the following comment. */ /* areacap nfet 457 */ /* areacap pfet 403 */ areacap poly,pc/a 16 areacap allMetal1,DiffMetal,HVDiffMetal 9 areacap PolyMetal,BiMetal,CCDMetal 9 areacap allMetal2 5 areacap allMetal3 4 /* Inter-layer capacitance */ overlap allMetal1 PNplus 13 overlap allMetal1 allPoly 13 overlap allMetal2 PNplus 4 overlap allMetal2 allPoly 4 overlap allMetal2 allMetal1 6 overlap allMetal3 PNplus 2 overlap allMetal3 allPoly 2 overlap allMetal3 allMetal1 3 overlap allMetal3 allMetal2 7 /* Junction capacitance */ overlap ndiff,ndc/a space,pwell 27 overlap pdiff,pdc/a space,nwell 148 /* Perimeter parasitic capacitance (in attofarads per lambda) [ 1 lambda = 0.5 micron ---> multiplication factor 0.5 ] */ perimc allMetal1 space,allWell 43 perimc allMetal2 space,allWell 36 perimc allMetal3 space,allWell 36 sideoverlap allMetal1 space,allWell allPoly 14 sideoverlap allMetal2 space,allWell allPoly 5 /* no such data for m2-to-m1, use data from specification file */ sideoverlap allMetal2 space,allWell allMetal1 13 sideoverlap allMetal3 space,allWell allPoly 1 sideoverlap allMetal3 space,allWell allMetal1 4 sideoverlap allMetal3 space,allWell allMetal2 13 /* Active devices: N-well process */ fet pfet pdiff,pdc 2 pfet Vdd! nwell 0 0 fet nfet ndiff,ndc 2 nfet GND! pwell 0 0 #endif /* TIGHTMETAL */ #ifdef IBMTECH style SCN08(IBM) /* The following data is obtained from MOSIS run 'n42s', 1/94 */ /* Last modified by pi@isi.edu, 6/27/94 */ cscale 1 lambda 40 step 100 /* Parallel wire coupling capacitance disabled */ sidehalo 0 /* Define plane order first */ #ifdef V5 planeorder well 0 planeorder implant 1 planeorder active 2 planeorder metal1 3 planeorder metal2 4 planeorder metal3 5 planeorder oxide 6 #endif /* Sheet resistance (in milliohms per square) */ resist ndiff,nsd,ndc/a,nsc/a 3300 resist pdiff,psd,pdc/a,psc/a 3180 resist poly 3630 resist allMetal1 43 resist allMetal2 36 resist allMetal3 36 /* not monitored on PCM, use specification value */ resist nwell 520000 /* Contact resistance (in milliohm per contact) */ contact ndc,nsc 4 2530 contact pc 4 7510 contact pdc,psc 4 2160 contact m2c 5 330 contact m3c 5 292 /* Area parasitic capacitances (in attofarads per lambda square) [ 1 lambda = 0.4 micron ---> multiplication factor 0.16 ] */ #endif /* IBMTECH */ #ifdef SUBMICRON style SCN08(HP26G) /* The following data is obtained from MOSIS run 'n48r', 10/94 */ /* Last modified by pi@isi.edu, 11/02/94 */ cscale 1 lambda 40 step 100 /* Parallel wire coupling capacitance enabled */ sidehalo 8 /* Define plane order first */ #ifdef V5 planeorder well 0 planeorder implant 1 planeorder active 2 planeorder metal1 3 planeorder metal2 4 planeorder metal3 5 planeorder oxide 6 #endif /* Sheet resistance (in milliohms per square) */ resist ndiff,nsd,ndc/a,nsc/a 2375 resist pdiff,psd,pdc/a,psc/a 2000 resist allPoly 2350 resist allMetal1 70 resist allMetal2 67 resist allMetal3 30 resist nwell 1265000 /* Contact resistance (in milliohm per contact) */ contact pc 4 1250 contact ndc,nsc 4 1300 contact pdc,psc 4 1125 contact m2c 5 430 contact m3c 5 300 /* The following are 10 types of capacitance extracted: 1. poly to substrate. 2. metal1 to substrate. 3. metal1 to poly. 4. metal2 to substrate. 5. metal2 to poly. 6. metal2 to metal1. 7. metal3 to substrate. 8. metal3 to poly. 9. metal3 to metal1. 10. metal3 to metal2. NOTE: Since most of the simulation tools have already included the gate-oxide capacitance, it is NOT extracted here. If you need it explictly, remove the following comment. */ /* areacap nfet 334 */ /* areacap pfet 315 */ /* Type 1,2,4,7 (to substrate) */ /* Area parasitic capacitances (in attofarads per lambda square) [ 1 lambda = 0.4 micron ---> multiplication factor 0.16 ] */ areacap poly,pc/a 13 areacap allMetal1,DiffMetal,HVDiffMetal 6 areacap PolyMetal,BiMetal,CCDMetal 6 areacap allMetal2 3 areacap allMetal3 2 /* Perimeter parasitic capacitance (in attofarads per lambda) [ 1 lambda = 0.4 micron ---> multiplication factor 0.4 ] */ perimc poly,pc/a ~(poly,pc/a) 19 perimc allMetal1 ~(allMetal1) 20 perimc allMetal2 ~(allMetal2) 16 perimc allMetal3 ~(allMetal3) 14 /* Inter-layer capacitance, type 3,5,6,8,9,10 */ /* Area parasitic capacitances (in attofarads per lambda square) [ 1 lambda = 0.4 micron ---> multiplication factor 0.16 ] */ overlap allMetal1 allPoly 9 overlap allMetal2 allPoly 3 overlap allMetal2 allMetal1 5 overlap allMetal3 allPoly 2 overlap allMetal3 allMetal1 3 overlap allMetal3 allMetal2 5 /* Perimeter parasitic capacitance (in attofarads per lambda) [ 1 lambda = 0.4 micron ---> multiplication factor 0.4 ] */ sideoverlap allMetal1 space,allWell allPoly 23 sideoverlap allMetal2 space,allWell allPoly 17 sideoverlap allMetal2 space,allWell allMetal1 19 sideoverlap allMetal3 space,allWell allPoly 15 sideoverlap allMetal3 space,allWell allMetal1 17 sideoverlap allMetal3 space,allWell allMetal2 21 /* Cross-couple capacitance */ /* Perimeter parasitic capacitance (in attofarads per lambda) [ 1 lambda = 0.4 micron ---> multiplication factor 0.4 ] */ sidewall allP ~(allP) ~(allP) allP 11 sidewall allMetal1 ~(allMetal1) ~(allMetal1) allMetal1 24 sidewall allMetal2 ~(allMetal2) ~(allMetal2) allMetal2 27 sidewall allMetal3 ~(allMetal3) ~(allMetal3) allMetal3 39 /* Active devices: N-well process */ fet pfet pdiff,pdc 2 pfet Vdd! nwell 0 0 fet nfet ndiff,ndc 2 nfet GND! pwell 0 0 style SCN06(HP14B) /* Not yet.... */ /* Last modified by pi@isi.edu, 03/10/95 */ cscale 1 lambda 30 step 100 /* Parallel wire coupling capacitance enabled */ sidehalo 8 /* Define plane order first */ #ifdef V5 planeorder well 0 planeorder implant 1 planeorder active 2 planeorder metal1 3 planeorder metal2 4 planeorder metal3 5 planeorder oxide 6 #endif /* Sheet resistance (in milliohms per square) */ resist ndiff,nsd,ndc/a,nsc/a 2375 resist pdiff,psd,pdc/a,psc/a 2000 resist allPoly 2350 resist allMetal1 70 resist allMetal2 67 resist allMetal3 30 resist nwell 1265000 /* Contact resistance (in milliohm per contact) */ contact pc 4 1250 contact ndc,nsc 4 1300 contact pdc,psc 4 1125 contact m2c 5 430 contact m3c 5 300 /* The following are 10 types of capacitance extracted: 1. poly to substrate. 2. metal1 to substrate. 3. metal1 to poly. 4. metal2 to substrate. 5. metal2 to poly. 6. metal2 to metal1. 7. metal3 to substrate. 8. metal3 to poly. 9. metal3 to metal1. 10. metal3 to metal2. NOTE: Since most of the simulation tools have already included the gate-oxide capacitance, it is NOT extracted here. If you need it explictly, remove the following comment. */ /* areacap nfet 334 */ /* areacap pfet 315 */ /* Type 1,2,4,7 (to substrate) */ /* Area parasitic capacitances (in attofarads per lambda square) [ 1 lambda = 0.3 micron ---> multiplication factor 0.09 ] */ areacap poly,pc/a 7 areacap allMetal1,DiffMetal,HVDiffMetal 3 areacap PolyMetal,BiMetal,CCDMetal 3 areacap allMetal2 1 areacap allMetal3 1 /* Perimeter parasitic capacitance (in attofarads per lambda) [ 1 lambda = 0.3 micron ---> multiplication factor 0.3 ] */ perimc poly,pc/a ~(poly,pc/a) 14 perimc allMetal1 ~(allMetal1) 15 perimc allMetal2 ~(allMetal2) 12 perimc allMetal3 ~(allMetal3) 10 /* Inter-layer capacitance, type 3,5,6,8,9,10 */ /* Area parasitic capacitances (in attofarads per lambda square) [ 1 lambda = 0.3 micron ---> multiplication factor 0.09 ] */ overlap allMetal1 allPoly 5 overlap allMetal2 allPoly 2 overlap allMetal2 allMetal1 3 overlap allMetal3 allPoly 1 overlap allMetal3 allMetal1 1 overlap allMetal3 allMetal2 3 /* Perimeter parasitic capacitance (in attofarads per lambda) [ 1 lambda = 0.3 micron ---> multiplication factor 0.3 ] */ sideoverlap allMetal1 space,allWell allPoly 17 sideoverlap allMetal2 space,allWell allPoly 14 sideoverlap allMetal2 space,allWell allMetal1 15 sideoverlap allMetal3 space,allWell allPoly 11 sideoverlap allMetal3 space,allWell allMetal1 13 sideoverlap allMetal3 space,allWell allMetal2 16 /* Cross-couple capacitance */ /* Perimeter parasitic capacitance (in attofarads per lambda) [ 1 lambda = 0.3 micron ---> multiplication factor 0.3 ] */ sidewall allP ~(allP) ~(allP) allP 9 sidewall allMetal1 ~(allMetal1) ~(allMetal1) allMetal1 19 sidewall allMetal2 ~(allMetal2) ~(allMetal2) allMetal2 21 sidewall allMetal3 ~(allMetal3) ~(allMetal3) allMetal3 31 /* Active devices: N-well process */ fet pfet pdiff,pdc 2 pfet Vdd! nwell 0 0 fet nfet ndiff,ndc 2 nfet GND! pwell 0 0 #endif /* SUBMICRON */ #endif /* OLD_EXTRACT_STYLE */ end wiring contact pdcontact 4 pdiff 0 metal1 0 contact ndcontact 4 ndiff 0 metal1 0 contact pcontact 4 poly 0 metal1 0 contact ec 6 poly2 0 metal1 0 contact m2contact 4 metal1 0 metal2 0 contact m3contact 5 metal2 0 metal3 0 end router layer1 metal1 3 allMetal1 3 layer2 metal2 3 allMetal2 4 allPoly,allDiff 1 contacts m2contact 4 gridspacing 8 end plowing fixed allFet,glass,pad covered allFet drag allFet end plot /* based on Jeffrey C. Gealow's (jgealow@mtl.mit.edu) contribution */ style colorversatec ndiff,ndc yellow \\ 5555 AAAA 5555 AAAA \\ 5555 AAAA 5555 AAAA \\ 5555 AAAA 5555 AAAA \\ 5555 AAAA 5555 AAAA ndiff,ndc cyan \\ 0000 5555 0000 5555 \\ 0000 5555 0000 5555 \\ 0000 5555 0000 5555 \\ 0000 5555 0000 5555 nsd,nsc,col,clc yellow \\ 1515 2A2A 5151 A2A2 \\ 1515 2A2A 5151 A2A2 \\ 1515 2A2A 5151 A2A2 \\ 1515 2A2A 5151 A2A2 nsd,nsc,col,clc cyan \\ 0000 1515 0000 5151 \\ 0000 1515 0000 5151 \\ 0000 1515 0000 5151 \\ 0000 1515 0000 5151 pdiff,pdc yellow \\ 5555 AAAA 5555 AAAA \\ 5555 AAAA 5555 AAAA \\ 5555 AAAA 5555 AAAA \\ 5555 AAAA 5555 AAAA pdiff,pdc cyan \\ 0000 5555 0000 5555 \\ 0000 5555 0000 5555 \\ 0000 5555 0000 5555 \\ 0000 5555 0000 5555 pdiff,pdc magenta \\ AAAA 0000 AAAA 0000 \\ AAAA 0000 AAAA 0000 \\ AAAA 0000 AAAA 0000 \\ AAAA 0000 AAAA 0000 psd,psc yellow \\ 1515 2A2A 5151 A2A2 \\ 1515 2A2A 5151 A2A2 \\ 1515 2A2A 5151 A2A2 \\ 1515 2A2A 5151 A2A2 psd,psc cyan \\ 0000 1515 0000 5151 \\ 0000 1515 0000 5151 \\ 0000 1515 0000 5151 \\ 0000 1515 0000 5151 psd,psc magenta \\ 2A2A 0000 A2A2 0000 \\ 2A2A 0000 A2A2 0000 \\ 2A2A 0000 A2A2 0000 \\ 2A2A 0000 A2A2 0000 poly,pc/a magenta \\ 5555 AAAA 5555 AAAA \\ 5555 AAAA 5555 AAAA \\ 5555 AAAA 5555 AAAA \\ 5555 AAAA 5555 AAAA poly2,ec/a yellow \\ FFFF FFFF FFFF FFFF \\ FFFF FFFF FFFF FFFF \\ FFFF FFFF FFFF FFFF \\ FFFF FFFF FFFF FFFF nfet yellow \\ 0505 8282 1414 0A0A \\ 5050 2828 4141 A0A0 \\ 0505 8282 1414 0A0A \\ 5050 2828 4141 A0A0 nfet cyan \\ 0000 0505 0000 1414 \\ 0000 5050 0000 4141 \\ 0000 0505 0000 1414 \\ 0000 5050 0000 4141 nfet magenta \\ 5050 2828 4141 A0A0 \\ 0505 8282 1414 0A0A \\ 5050 2828 4141 A0A0 \\ 0505 8282 1414 0A0A enfet yellow \\ BABA 7575 EAEA D5D5 \\ ABAB 5757 AEAE 5D5D \\ BABA 7575 EAEA D5D5 \\ ABAB 5757 AEAE 5D5D enfet cyan \\ 4141 0A0A 0505 2828 \\ 1414 A0A0 5050 8282 \\ 4141 0A0A 0505 2828 \\ 1414 A0A0 5050 8282 nffet yellow \\ 8E8E 0707 8B8B D5D5 \\ E8E8 7070 B8B8 5D5D \\ 8E8E 0707 8B8B D5D5 \\ E8E8 7070 B8B8 5D5D nffet cyan \\ 0101 0808 1414 2828 \\ 1010 8080 4141 8282 \\ 0101 0808 1414 2828 \\ 1010 8080 4141 8282 nffet magenta \\ 5050 A0A0 4040 0202 \\ 0505 0A0A 0404 2020 \\ 5050 A0A0 4040 0202 \\ 0505 0A0A 0404 2020 pfet yellow \\ 6363 A0A0 5050 2828 \\ 3636 0A0A 0505 8282 \\ 6363 A0A0 5050 2828 \\ 3636 0A0A 0505 8282 pfet cyan \\ 0000 5151 0000 5454 \\ 0000 1515 0000 1515 \\ 0000 5151 0000 5454 \\ 0000 1515 0000 1515 pfet magenta \\ 9494 0A0A 2525 8282 \\ 4949 A0A0 5252 2828 \\ 9494 0A0A 2525 8282 \\ 4949 A0A0 5252 2828 epfet yellow \\ BCBC 4F4F 2F2F D3D3 \\ CBCB F4F4 F2F2 3D3D \\ BCBC 4F4F 2F2F D3D3 \\ CBCB F4F4 F2F2 3D3D epfet cyan \\ 0000 A0A0 0000 2828 \\ 0000 0A0A 0000 8282 \\ 0000 A0A0 0000 2828 \\ 0000 0A0A 0000 8282 epfet magenta \\ 4141 0000 5050 0000 \\ 1414 0000 0505 0000 \\ 4141 0000 5050 0000 \\ 1414 0000 0505 0000 pffet yellow \\ 7B7B F0F0 F0F0 E9E9 \\ B7B7 0F0F 0F0F 9E9E \\ 7B7B F0F0 F0F0 E9E9 \\ B7B7 0F0F 0F0F 9E9E pffet cyan \\ 0000 0101 0000 1414 \\ 0000 1010 0000 4141 \\ 0000 0101 0000 1414 \\ 0000 1010 0000 4141 pffet magenta \\ 8484 0A0A 2525 8282 \\ 4848 A0A0 5252 2828 \\ 8484 0A0A 2525 8282 \\ 4848 A0A0 5252 2828 cap,cc/a yellow \\ 3E3E 7777 E3E3 C1C1 \\ E3E3 7777 3E3E 1C1C \\ 3E3E 7777 E3E3 C1C1 \\ E3E3 7777 3E3E 1C1C cap,cc/a magenta \\ 4141 8888 1414 2A2A \\ 1414 8888 4141 A2A2 \\ 4141 8888 1414 2A2A \\ 1414 8888 4141 A2A2 allMetal1 cyan \\ AAAA 0000 AAAA 0000 \\ AAAA 0000 AAAA 0000 \\ AAAA 0000 AAAA 0000 \\ AAAA 0000 AAAA 0000 allMetal2 cyan \\ 0000 1111 0000 4444 \\ 0000 1111 0000 4444 \\ 0000 1111 0000 4444 \\ 0000 1111 0000 4444 allMetal2 magenta \\ 0000 4444 0000 1111 \\ 0000 4444 0000 1111 \\ 0000 4444 0000 1111 \\ 0000 4444 0000 1111 m2c/m1 black \\ 0000 6666 6666 0000 \\ 0000 9999 9999 0000 \\ 0000 6666 6666 0000 \\ 0000 9999 9999 0000 pad,glass black \\ 0300 0700 0E00 1C00 \\ 3800 7000 E000 C000 \\ 00C0 00E0 0070 0038 \\ 001C 000E 0007 0003 nwell yellow \\ 0800 1000 2000 4000 \\ 8000 0001 0002 0004 \\ 0008 0010 0020 0040 \\ 0080 0010 0200 0400 nwell cyan \\ 1000 2000 4000 8000 \\ 0001 0002 0004 0008 \\ 0010 0020 0040 0080 \\ 0100 0200 0400 0800 pwell yellow \\ 1000 0400 0400 0100 \\ 0100 0040 0040 0010 \\ 0010 0004 0004 0001 \\ 0001 4000 4000 1000 pwell cyan \\ 0000 0800 0000 0200 \\ 0000 0080 0000 0020 \\ 0000 0008 0000 0002 \\ 0000 8000 0000 2000 pwell magenta \\ 0800 0000 0200 0000 \\ 0080 0000 0020 0000 \\ 0008 0000 0002 0000 \\ 8000 0000 2000 0000 bd yellow \\ 4444 8888 4444 8888 \\ 4444 8888 4444 8888 \\ 4444 8888 4444 8888 \\ 4444 8888 4444 8888 bd cyan \\ 0000 4444 0000 4444 \\ 0000 4444 0000 4444 \\ 0000 4444 0000 4444 \\ 0000 4444 0000 4444 bd magenta \\ 8888 0000 8888 0000 \\ 8888 0000 8888 0000 \\ 8888 0000 8888 0000 \\ 8888 0000 8888 0000 nbd,nbdc yellow \\ 5555 AAAA 5555 AAAA \\ 5555 AAAA 5555 AAAA \\ 5555 AAAA 5555 AAAA \\ 5555 AAAA 5555 AAAA nbd,nbdc cyan \\ 0000 5555 0000 5555 \\ 0000 5555 0000 5555 \\ 0000 5555 0000 5555 \\ 0000 5555 0000 5555 nbd,nbdc magenta \\ 8888 0000 8888 0000 \\ 8888 0000 8888 0000 \\ 8888 0000 8888 0000 \\ 8888 0000 8888 0000 em,emc yellow \\ 4444 8888 4444 8888 \\ 4444 8888 4444 8888 \\ 4444 8888 4444 8888 \\ 4444 8888 4444 8888 em,emc cyan \\ 0000 4444 0000 4444 \\ 0000 4444 0000 4444 \\ 0000 4444 0000 4444 \\ 0000 4444 0000 4444 pbase,pbc yellow \\ 5555 AAAA 0000 0000 \\ 5555 AAAA 0000 0000 \\ 5555 AAAA 0000 0000 \\ 5555 AAAA 0000 0000 pbase,pbc cyan \\ 0000 5555 0000 0000 \\ 0000 5555 0000 0000 \\ 0000 5555 0000 0000 \\ 0000 5555 0000 0000 pbase,pbc magenta \\ AAAA 0000 0000 0000 \\ AAAA 0000 0000 0000 \\ AAAA 0000 0000 0000 \\ AAAA 0000 0000 0000 allMetal3 black \\ 0100 0000 0000 0000 \\ 1010 0000 0000 0000 \\ 0001 0000 0000 0000 \\ 1010 0000 0000 0000 allMetal3 cyan \\ 0280 0000 0820 0000 \\ 2008 0000 8002 0000 \\ 8002 0000 2008 0000 \\ 0820 0000 0280 0000 allMetal3 magenta \\ 0100 06C0 0440 1830 \\ 1010 600C 4004 8003 \\ 0001 C006 4004 3018 \\ 1010 0C60 0440 0380 m3c/m2 black \\ 0820 0820 0820 0FE0 \\ E00F 2008 2008 2008 \\ 2008 2008 2008 E00F \\ 0000 0FE0 0820 0820 error_p,error_s,error_ps black \\ 0000 3C3C 4646 4A4A \\ 5252 6262 3C3C 0000 \\ 0000 3C3C 4646 4A4A \\ 5252 6262 3C3C 0000 magnet yellow \\ AAAA 0000 5555 0000 \\ AAAA 0000 5555 0000 \\ AAAA 0000 5555 0000 \\ AAAA 0000 5555 0000 fence magenta \\ FFFF 0000 0000 0000 \\ 0000 0000 0000 0000 \\ FFFF 0000 0000 0000 \\ 0000 0000 0000 0000 rotate cyan \\ 0000 E0E0 E0E0 E0E0 \\ 0000 0000 0000 0000 \\ 0000 E0E0 E0E0 E0E0 \\ 0000 0000 0000 0000 allCut,BiCut X style versatec pfet \\ 07c0 0f80 1f00 3e00 \\ 7c00 f800 f001 e003 \\ c007 800f 001f 003e \\ 00c7 00f8 01f0 03e0 nfet \\ 1f00 0f80 07c0 03e0 \\ 01f0 00f8 007c 003e \\ 001f 800f c007 e003 \\ f001 f800 7c00 3e00 m2c \\ c3c3 c3c3 0000 0000 \\ 0000 0000 c3c3 c3c3 \\ c3c3 c3c3 0000 0000 \\ 0000 0000 c3c3 c3c3 pwell \\ 2020 2020 2020 2020 \\ 2020 2020 2020 2020 \\ 0000 0000 0000 0000 \\ 0000 0000 0000 0000 nwell \\ 0808 0404 0202 0101 \\ 0000 0000 0000 0000 \\ 0808 0404 0202 0101 \\ 0000 0000 0000 0000 allPoly \\ 0808 0400 0202 0101 \\ 8080 4000 2020 1010 \\ 0808 0004 0202 0101 \\ 8080 0040 2020 1010 allMetal1 \\ 8080 0000 0000 0000 \\ 0808 0000 0000 0000 \\ 8080 0000 0000 0000 \\ 0808 0000 0000 0000 pad,glass \\ 0000 0000 1c1c 3e3e \\ 3636 3e3e 1c1c 0000 \\ 0000 0000 1c1c 3e3e \\ 3636 3e3e 1c1c 0000 nsd,nsc,col,clc \\ 0808 1414 2222 4141 \\ 8080 4040 2020 1010 \\ 0808 1414 2222 4141 \\ 8080 4040 2020 1010 allMetal2 \\ 0000 1111 0000 0000 \\ 0000 1111 0000 0000 \\ 0000 1111 0000 0000 \\ 0000 1111 0000 0000 pdiff,pdc,pfet \\ 0000 0808 5555 8080 \\ 0000 8080 5555 0808 \\ 0000 0808 5555 8080 \\ 0000 8080 5555 0808 psd,psc \\ 1414 2222 0000 2222 \\ 4141 2222 0000 2222 \\ 1414 2222 0000 2222 \\ 4141 2222 0000 2222 ndiff,nfet,ndc \\ 0808 1010 2020 4040 \\ 8080 4141 2222 1414 \\ 0808 1010 2020 4040 \\ 8080 4141 2222 1414 allPoly2 \\ 0000 2020 5050 2020 \\ 0000 0202 0505 0202 \\ 0000 2020 5050 2020 \\ 0000 0202 0505 0202 allCut,BiCut X /* -------------------------------------------------------------- */ style gremlin pfet 9 nfet 10 m2c 11 pwell 15 nwell 16 allPoly 19 allMetal1 22 pad,glass 23 nsd,nsc 24 allMetal2 28 pdiff,pdc,pfet 29 psd,psc 30 ndiff,nfet,ndc 31 m2c/m1,pc/m1,ndc/m1,pdc/m1,psc/m1,nsc/m1,pad/m1 X /* -------------------------------------------------------------- */ style postscript /* * stipple definitions for 32x8 bitmaps * # row1 row2 row3 row4 row5 row6 row7 row8 */ 1 C0C0C0C0 C0C0C0C0 00000000 00000000 0C0C0C0C 0C0C0C0C 00000000 00000000 2 A0A0A0A0 0A0A0A0A A0A0A0A0 0A0A0A0A A0A0A0A0 0A0A0A0A A0A0A0A0 0A0A0A0A 3 00030003 000C000C 00300030 00C000C0 03000300 0C000C00 30003000 C000C000 4 00000000 00000000 C0C0C0C0 00000000 00000000 00000000 0C0C0C0C 00000000 5 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 6 07070707 0E0E0E0E 1C1C1C1C 38383838 70707070 E0E0E0E0 C1C1C1C1 83838383 7 18181818 30303030 60606060 C0C0C0C0 81818181 03030303 06060606 0C0C0C0C 8 18181818 0C0C0C0C 06060606 03030303 81818181 C0C0C0C0 60606060 30303030 9 18181818 3C3C3C3C 3C3C3C3C 18181818 81818181 C3C3C3C3 C3C3C3C3 81818181 10 F0F0F0F0 60606060 06060606 0F0F0F0F 0F0F0F0F 06060606 60606060 F0F0F0F0 11 01000080 02000040 0C000030 F000000F 000FF000 00300C00 00400200 00800100 12 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 13 00000000 00000000 33333333 33333333 00000000 00000000 CCCCCCCC CCCCCCCC /* * color definitions in CMYK format * # C M Y K closest named color in RGB space */ 1 47 95 111 0 /* RosyBrown3 */ 2 223 31 223 0 /* limegreen */ 3 0 0 0 192 /* gray25 */ 4 31 111 31 0 /* plum */ 5 31 111 255 0 /* orange2 */ 6 63 95 191 0 /* goldenrod3 */ 7 255 63 255 0 /* green3 */ 8 0 0 0 127 /* gray50 */ 9 223 47 223 0 /* limegreen */ 10 0 255 255 0 /* red */ 11 0 0 255 0 /* yellow */ 12 191 127 0 0 /* RoyalBlue1 */ 13 95 223 63 0 /* DarkOrchid3 */ 14 0 0 0 255 /* black */ 15 191 127 63 0 /* steelblue */ 16 111 151 244 0 /* goldenrod4 */ 17 23 175 183 0 /* tomato2 */ /* * magic layer definitions (plotted top to bottom) * layer(s) color# stipple# (plus B=box, X=cross & box) */ cc,pc,ndc,pdc,psc,nsc 14 X m2c,pad,glass 14 B pad,glass 14 11 m2c 14 13 m2,m2c,pad 13 10 pdc,ndc,psc,nsc,hpdc,hndc,hpsc,hnsc,pc,ec,capc,clc,emc,pbc,nbdc,m1,m2c,gc 12 9 cap,cc,poly2 11 7 nsd,nsc 7 1 psd,psc 6 1 nfet,nffet 9 8 pfet,wcap,pffet 1 7 poly,pc,cap,cc 10 5 nfet 16 5 pfet,wcap 17 5 pdiff,pdc,pffet 1 5 ndiff,ndc,nffet 9 5 pwell 1 4 nwell 2 4 /* ------------------------------------------------------------------------ */ style pnm draw metal1 draw metal2 draw polysilicon draw ndiffusion draw pdiffusion draw ntransistor draw ptransistor map psubstratepdiff pdiffusion map nsubstratendiff ndiffusion map polycontact polysilicon metal1 map m2contact metal1 metal2 map m3contact metal2 metal3 map ndcontact ndiffusion metal1 map pdcontact pdiffusion metal1 map nsubstratencontact ndiffusion metal1 map psubstratepcontact pdiffusion metal1 end magic-8.0.210/scmos/rules/0000755000175000001440000000000011504623577013742 5ustar timusersmagic-8.0.210/scmos/rules/rule1.mag0000644000175000001440000000030010751423606015443 0ustar timusersmagic tech scmos timestamp 736070757 << pwell >> rect -10 0 0 16 << nwell >> rect 0 0 10 16 rect 19 0 29 16 << labels >> rlabel space 0 -3 10 -3 1 1.1 rlabel space 10 18 19 18 1 1.2 << end >> magic-8.0.210/scmos/rules/rule2.mag0000644000175000001440000000072710751423606015461 0ustar timusersmagic tech scmos timestamp 736070890 << nwell >> rect -2 -2 20 8 << ndiffusion >> rect 0 13 4 16 rect 7 13 11 16 << pdiffusion >> rect 0 0 4 3 rect 7 0 11 3 << psubstratepdiff >> rect 15 11 18 16 << nsubstratendiff >> rect 15 0 18 5 << labels >> rlabel nwell -1 8 20 8 1 P-Region rlabel nwell -1 8 20 8 5 N-Region rlabel space -1 13 -1 16 3 2.1 rlabel space 4 12 7 12 1 2.2 rlabel space 17 8 17 11 3 2.4 rlabel space 12 8 12 13 3 2.3 rlabel nwell 6 3 6 8 3 2.3 << end >> magic-8.0.210/scmos/rules/rule4_2.mag0000644000175000001440000000442510751423606015703 0ustar timusersmagic tech scmos timestamp 751931635 << polysilicon >> rect 18 73 26 75 rect 18 72 20 73 rect 18 52 20 62 rect 49 60 51 66 rect 49 58 52 60 rect 62 58 72 60 rect 82 58 85 60 rect 83 51 85 58 rect 18 41 20 42 rect 11 39 20 41 rect 55 32 64 34 rect 55 31 57 32 rect -3 17 -1 24 rect -3 15 0 17 rect 10 15 20 17 rect 30 15 33 17 rect 31 9 33 15 rect 55 11 57 21 rect 55 0 57 1 rect 49 -2 57 0 << ndiffusion >> rect 72 65 82 66 rect 72 61 75 65 rect 79 61 82 65 rect 72 60 82 61 rect 8 44 11 46 rect 15 44 18 52 rect 8 42 18 44 rect 20 49 26 52 rect 72 55 82 58 rect 80 51 82 55 rect 20 45 21 49 rect 25 45 26 49 rect 78 48 82 51 rect 20 42 26 45 rect 49 28 55 31 rect 0 24 4 27 rect 49 24 50 28 rect 54 24 55 28 rect 0 20 2 24 rect 0 17 10 20 rect 49 21 55 24 rect 57 29 67 31 rect 57 21 60 29 rect 64 27 67 29 rect 0 14 10 15 rect 0 10 3 14 rect 7 10 10 14 rect 0 9 10 10 << pdiffusion >> rect 8 64 11 66 rect 15 64 18 72 rect 8 62 18 64 rect 20 69 26 72 rect 20 65 21 69 rect 25 65 26 69 rect 20 62 26 65 rect 52 65 62 66 rect 52 61 55 65 rect 59 61 62 65 rect 52 60 62 61 rect 52 55 62 58 rect 60 51 62 55 rect 58 48 62 51 rect 20 24 24 27 rect 20 20 22 24 rect 20 17 30 20 rect 20 14 30 15 rect 20 10 23 14 rect 27 10 30 14 rect 20 9 30 10 rect 49 8 55 11 rect 49 4 50 8 rect 54 4 55 8 rect 49 1 55 4 rect 57 9 67 11 rect 57 1 60 9 rect 64 7 67 9 << ntransistor >> rect 72 58 82 60 rect 18 42 20 52 rect 55 21 57 31 rect 0 15 10 17 << ptransistor >> rect 18 62 20 72 rect 52 58 62 60 rect 20 15 30 17 rect 55 1 57 11 << ndcontact >> rect 75 61 79 65 rect 11 44 15 48 rect 76 51 80 55 rect 21 45 25 49 rect 50 24 54 28 rect 2 20 6 24 rect 60 25 64 29 rect 3 10 7 14 << pdcontact >> rect 11 64 15 68 rect 21 65 25 69 rect 55 61 59 65 rect 56 51 60 55 rect 22 20 26 24 rect 23 10 27 14 rect 50 4 54 8 rect 60 5 64 9 << psubstratepcontact >> rect 11 48 15 52 rect 72 51 76 55 rect 6 20 10 24 rect 60 21 64 25 << nsubstratencontact >> rect 11 68 15 72 rect 52 51 56 55 rect 26 20 30 24 rect 60 1 64 5 << labels >> rlabel space 47 31 47 33 3 4.2 rlabel space 65 24 65 25 3 4.3 rlabel space 57 19 60 19 5 4.1 rlabel space 75 50 76 50 5 4.3 rlabel space 70 55 70 58 7 4.1 rlabel space 10 48 10 49 7 4.3 rlabel space 15 54 18 54 1 4.1 rlabel space -2 7 0 7 1 4.2 rlabel space 6 25 7 25 1 4.3 rlabel space 12 17 12 20 3 4.1 << end >> magic-8.0.210/scmos/rules/rule8.mag0000644000175000001440000000134510751423606015464 0ustar timusersmagic tech scmos timestamp 772488492 << polysilicon >> rect 0 10 12 12 << ndiffusion >> rect 0 0 12 4 << metal1 >> rect 3 23 7 25 rect 3 19 4 23 rect 3 18 7 19 rect 22 11 23 15 rect 18 9 23 11 rect 0 5 3 9 << metal2 >> rect 3 23 7 25 rect 3 19 4 23 rect 3 18 7 19 rect 18 9 22 11 rect 12 5 20 9 << m2contact >> rect 3 25 7 33 rect 4 19 10 23 rect 3 14 7 18 rect 18 11 22 15 rect 3 5 12 9 rect 20 5 24 9 << psubstratepcontact >> rect 24 5 28 9 << psubstratepdiff >> rect 18 9 28 10 rect 18 5 24 9 rect 18 4 28 5 << labels >> rlabel space -1 8 -1 10 7 8.4 rlabel space -1 4 -1 6 7 8.4 rlabel space 6 -2 9 -2 1 8.2 rlabel space 23 11 25 11 1 8.5 rlabel space 30 8 30 10 3 8.4 rlabel space 31 5 31 6 3 8.3 rlabel space 21 2 23 2 5 8.1 << end >> magic-8.0.210/scmos/rules/rule12.mag0000644000175000001440000000167110751423606015541 0ustar timusersmagic tech scmos timestamp 736073091 << polysilicon >> rect 14 10 16 12 rect 19 10 23 12 rect 21 8 23 10 rect 43 10 45 12 rect 48 10 52 12 rect 50 8 52 10 << poly2 >> rect 7 0 9 20 rect 12 8 14 10 rect 41 8 43 10 rect 12 6 16 8 rect 19 6 21 8 rect 41 7 45 8 rect 34 6 45 7 rect 48 6 50 8 rect 34 2 35 6 rect 43 2 44 6 rect 34 1 44 2 << capacitor >> rect 14 8 16 10 rect 19 8 21 10 rect 43 8 45 10 rect 48 8 50 10 << ndiffusion >> rect 16 12 19 13 rect 16 4 19 6 rect 16 0 17 4 << pdiffusion >> rect 45 12 48 13 rect 45 4 48 6 rect 45 0 46 4 << ntransistor >> rect 16 10 19 12 << ptransistor >> rect 45 10 48 12 << entransistor >> rect 16 6 19 8 << eptransistor >> rect 45 6 48 8 << doublentransistor >> rect 16 8 19 10 << doubleptransistor >> rect 45 8 48 10 << polycontact >> rect 23 8 27 12 rect 52 8 56 12 << ndcontact >> rect 16 13 20 17 rect 17 0 21 4 << pdcontact >> rect 45 13 49 17 rect 46 0 50 4 << electrodecontact >> rect 35 2 43 6 << end >> magic-8.0.210/scmos/rules/rule17.mag0000644000175000001440000000076610751423606015552 0ustar timusersmagic tech scmos timestamp 736076273 << capwell >> rect 0 0 10 12 rect 19 0 29 12 << polysilicon >> rect 9 22 12 24 rect 16 22 21 24 rect 25 22 28 24 << ndiffusion >> rect 12 24 16 27 rect 21 24 25 27 rect 12 17 16 22 rect 21 21 25 22 rect 3 3 7 9 << ntransistor >> rect 12 22 16 24 rect 21 22 25 24 << ndcontact >> rect 21 17 25 21 rect 31 17 35 21 << psubstratepcontact >> rect -6 15 -2 19 rect 4 15 8 19 << labels >> rlabel space 14 -5 34 17 1 boundary rlabel space -3 -3 13 15 1 boundary << end >> magic-8.0.210/scmos/rules/rule16.mag0000644000175000001440000000271610751423606015546 0ustar timusersmagic tech scmos timestamp 783738099 << nwell >> rect 2 54 40 59 rect -1 40 40 54 rect 2 35 40 40 rect 49 36 90 60 rect 49 26 62 27 rect -1 0 40 24 rect 49 0 95 26 << collector >> rect 2 49 8 50 rect 2 45 3 49 rect 7 45 8 49 rect 2 44 8 45 rect 52 50 58 51 rect 52 46 53 50 rect 57 46 58 50 rect 52 45 58 46 rect 52 23 58 24 rect 52 19 53 23 rect 57 19 58 23 rect 52 18 58 19 rect 2 14 8 15 rect 2 10 3 14 rect 7 10 8 14 rect 2 9 8 10 rect 86 15 92 21 rect 52 13 58 14 rect 52 9 53 13 rect 57 9 58 13 rect 52 8 58 9 rect 86 6 92 12 << emitter >> rect 66 46 70 50 << pbase >> rect 12 52 24 53 rect 12 49 34 52 rect 12 45 16 49 rect 20 45 27 49 rect 31 45 34 49 rect 62 50 84 54 rect 62 46 66 50 rect 70 46 77 50 rect 81 46 84 50 rect 12 42 34 45 rect 62 42 84 46 rect 12 41 25 42 rect 12 14 34 18 rect 62 14 82 18 rect 12 10 16 14 rect 20 10 27 14 rect 31 10 34 14 rect 12 6 34 10 rect 62 10 66 14 rect 78 10 82 14 rect 62 6 82 10 << collectorcontact >> rect 3 45 7 49 rect 53 46 57 50 rect 53 19 57 23 rect 3 10 7 14 rect 53 9 57 13 << emittercontact >> rect 16 45 20 49 rect 16 10 20 14 rect 66 10 78 14 << pbasecontact >> rect 27 45 31 49 rect 77 46 81 50 rect 27 10 31 14 << labels >> rlabel pbase 23 15 23 15 1 a rlabel emittercontact 18 12 18 12 1 b rlabel emittercontact 18 47 18 47 1 a rlabel collectorcontact 5 47 5 47 1 c rlabel pbasecontact 29 47 29 47 1 b rlabel collector 89 18 89 18 1 d rlabel collectorcontact 55 48 55 48 1 c rlabel pbasecontact 79 48 79 48 1 b << end >> magic-8.0.210/scmos/rules/rule3.mag0000644000175000001440000000215410751423606015456 0ustar timusersmagic tech scmos timestamp 736070986 << polysilicon >> rect -3 12 -1 17 rect 35 12 37 17 rect -3 10 0 12 rect 8 10 10 12 rect 24 10 26 12 rect 34 10 37 12 rect -3 6 0 8 rect 8 6 10 8 rect 24 6 26 8 rect 34 6 37 8 rect -3 1 -1 6 rect 35 1 37 6 << ndiffusion >> rect 0 13 12 16 rect 0 12 8 13 rect 0 8 8 10 rect 0 3 8 6 rect 0 0 3 3 << pdiffusion >> rect 22 13 34 16 rect 26 12 34 13 rect 26 8 34 10 rect 26 3 34 6 rect 31 0 34 3 << ntransistor >> rect 0 10 8 12 rect 0 6 8 8 << ptransistor >> rect 26 10 34 12 rect 26 6 34 8 << labels >> rlabel space 12 10 12 12 3 3.1 rlabel space 11 8 11 10 3 3.2 rlabel space 12 3 12 6 3 3.4 rlabel space -1 18 0 18 1 3.5 rlabel space 22 10 22 12 7 3.1 rlabel space 23 8 23 10 7 3.2 rlabel space 22 3 22 6 7 3.4 rlabel space 24 2 26 2 1 3.3 rlabel space -1 -17 34 -2 1 poly rlabel space 2 -4 2 -4 3 3.1______width______2 rlabel space 2 -7 2 -7 3 3.2______space______2 rlabel space 2 -10 2 -10 3 3.3______gate_overlap____2 rlabel space 2 -13 2 -13 3 3.4______active_overlap__3 rlabel space 2 -16 2 -16 3 3.5______to_active_____1 rlabel space 34 18 35 18 1 3.5 rlabel space 8 2 10 2 1 3.3 << end >> magic-8.0.210/scmos/rules/rule19.mag0000644000175000001440000000174510751423606015552 0ustar timusersmagic tech scmos timestamp 736034963 << polysilicon >> rect 12 -2 15 14 rect 21 -2 24 14 rect 30 -2 35 14 rect 10 -4 17 -2 rect 10 -8 11 -4 rect 15 -8 17 -4 rect 19 -4 26 -2 rect 19 -8 20 -4 rect 24 -8 26 -4 rect 28 -4 35 -2 rect 28 -8 29 -4 rect 33 -8 35 -4 << poly2 >> rect 6 20 12 21 rect 6 16 7 20 rect 11 16 12 20 rect 6 14 12 16 rect 15 20 21 21 rect 15 16 16 20 rect 20 16 21 20 rect 15 14 21 16 rect 24 20 30 21 rect 24 16 25 20 rect 29 16 30 20 rect 24 14 30 16 rect 6 -2 10 14 rect 17 -2 19 14 rect 26 -2 28 14 << capacitor >> rect 10 -2 12 14 rect 15 -2 17 14 rect 19 -2 21 14 rect 24 -2 26 14 rect 28 -2 30 14 << bccdiffusion >> rect 15 12 17 14 rect 6 8 35 12 rect 6 0 35 4 << nbccdiffusion >> rect 4 8 6 12 rect 4 0 6 4 rect 35 8 37 12 rect 35 0 37 4 << polycontact >> rect 11 -8 15 -4 rect 20 -8 24 -4 rect 29 -8 33 -4 << electrodecontact >> rect 7 16 11 20 rect 16 16 20 20 rect 25 16 29 20 << nbccdiffcontact >> rect 0 8 4 12 rect 0 0 4 4 rect 37 8 41 12 rect 37 0 41 4 << end >> magic-8.0.210/scmos/rules/all-rules.mag0000644000175000001440000002763410751423606016336 0ustar timusersmagic tech scmos timestamp 783720303 << pwell >> rect 104 132 114 144 << nwell >> rect -9 203 1 219 rect 10 203 20 219 rect 150 114 190 138 << capwell >> rect 200 123 216 141 rect 141 83 151 93 rect 160 83 170 93 << polysilicon >> rect 65 213 67 218 rect 103 213 105 218 rect 65 211 68 213 rect 76 211 78 213 rect 92 211 94 213 rect 102 211 105 213 rect 119 210 121 217 rect 202 216 204 219 rect 165 214 175 215 rect 165 210 166 214 rect 174 210 175 214 rect 190 213 194 215 rect 208 212 210 219 rect 65 207 68 209 rect 76 207 78 209 rect 92 207 94 209 rect 102 207 105 209 rect 119 208 122 210 rect 132 208 142 210 rect 152 208 155 210 rect 165 209 175 210 rect 219 209 221 212 rect 65 202 67 207 rect 103 202 105 207 rect 153 202 155 208 rect 219 204 221 205 rect -1 185 1 187 rect 31 179 33 181 rect 37 179 40 181 rect -1 169 1 179 rect 38 178 40 179 rect 38 176 53 178 rect 106 174 118 176 rect -1 161 1 163 rect 89 162 91 168 rect 81 142 107 144 rect 81 134 83 142 rect 91 134 94 142 rect 102 140 107 142 rect 130 143 142 145 rect 102 136 104 140 rect 102 134 107 136 rect 81 132 107 134 rect 130 133 132 143 rect 140 135 142 143 rect 138 133 142 135 rect 97 119 99 121 rect 102 119 106 121 rect 104 117 106 119 rect 139 123 141 130 rect 202 127 203 130 rect 213 127 214 130 rect 202 125 214 127 rect 97 92 99 94 rect 102 92 106 94 rect 104 90 106 92 rect 201 89 204 97 rect 210 89 213 97 rect 219 89 224 97 rect 199 87 206 89 rect 199 83 200 87 rect 204 83 206 87 rect 208 87 215 89 rect 208 83 209 87 rect 213 83 215 87 rect 217 87 224 89 rect 217 83 218 87 rect 222 83 224 87 << electrode >> rect 132 131 138 133 rect 83 84 85 122 rect 95 117 97 119 rect 132 123 133 131 rect 137 123 138 131 rect 132 122 138 123 rect 95 116 99 117 rect 88 115 99 116 rect 102 115 104 117 rect 88 111 89 115 rect 97 111 98 115 rect 88 110 98 111 rect 195 103 201 104 rect 195 99 196 103 rect 200 99 201 103 rect 195 97 201 99 rect 204 103 210 104 rect 204 99 205 103 rect 209 99 210 103 rect 204 97 210 99 rect 213 103 219 104 rect 213 99 214 103 rect 218 99 219 103 rect 213 97 219 99 rect 95 90 97 92 rect 95 88 99 90 rect 102 88 104 90 rect 195 89 199 97 rect 206 89 208 97 rect 215 89 217 97 << capacitor >> rect 83 140 91 142 rect 83 136 85 140 rect 89 136 91 140 rect 83 134 91 136 rect 94 140 102 142 rect 94 136 96 140 rect 100 136 102 140 rect 94 134 102 136 rect 132 141 140 143 rect 132 137 134 141 rect 138 137 140 141 rect 132 135 140 137 rect 132 133 138 135 rect 97 117 99 119 rect 102 117 104 119 rect 97 90 99 92 rect 102 90 104 92 rect 199 89 201 97 rect 204 89 206 97 rect 208 89 210 97 rect 213 89 215 97 rect 217 89 219 97 << wellcapacitor >> rect 203 127 213 130 << ndiffusion >> rect 38 213 42 216 rect 45 213 49 216 rect 68 214 80 217 rect 68 213 76 214 rect 68 209 76 211 rect 122 213 124 217 rect 122 210 132 213 rect 68 204 76 207 rect 68 201 71 204 rect 122 202 132 208 rect 189 205 205 209 rect 33 181 37 184 rect 33 178 37 179 rect -14 168 -1 169 rect -14 164 -10 168 rect -2 164 -1 168 rect -14 163 -1 164 rect 1 163 5 169 rect 41 166 44 170 rect 30 163 44 166 rect 80 166 83 173 rect 106 164 118 168 rect 128 119 131 126 rect 203 130 213 134 rect 99 94 102 95 rect 99 86 102 88 rect 131 86 136 91 rect 144 86 148 90 rect 99 82 100 86 << pdiffusion >> rect 90 214 102 217 rect 94 213 102 214 rect 142 217 146 220 rect 94 209 102 211 rect 142 213 144 217 rect 142 210 152 213 rect 38 200 42 203 rect 45 200 49 203 rect 94 204 102 207 rect 99 201 102 204 rect 142 202 152 208 rect 216 205 219 209 rect 221 205 224 209 rect -14 184 -1 185 rect -14 180 -10 184 rect -2 180 -1 184 rect -14 179 -1 180 rect 1 179 5 185 rect 99 121 102 122 rect 99 113 102 115 rect 99 109 100 113 << metal1 >> rect 49 168 53 170 rect 78 169 88 172 rect 106 169 109 173 rect 175 171 179 176 rect 83 162 93 165 rect 157 162 160 165 rect 175 162 179 167 rect 133 141 137 147 rect 81 136 85 140 rect 89 136 96 140 rect 133 137 134 141 rect 133 131 137 137 rect 133 121 137 123 rect 48 102 63 117 << metal2 >> rect 150 173 161 176 rect 118 169 136 173 rect 201 171 205 179 rect 150 166 156 169 rect 160 166 161 169 rect 193 167 205 171 rect 201 162 205 163 rect 63 127 73 142 << metal3 >> rect 200 172 214 178 rect 178 171 194 172 rect 178 167 179 171 rect 193 167 194 171 rect 178 166 194 167 rect 200 167 214 168 rect 200 163 201 167 rect 205 163 214 167 rect 200 162 214 163 << ntransistor >> rect 68 211 76 213 rect 68 207 76 209 rect 122 208 132 210 rect 33 179 37 181 rect -1 163 1 169 rect 99 92 102 94 << ptransistor >> rect 94 211 102 213 rect 94 207 102 209 rect 142 208 152 210 rect 219 205 221 209 rect -1 179 1 185 rect 99 119 102 121 << entransistor >> rect 99 88 102 90 << eptransistor >> rect 99 115 102 117 << doublentransistor >> rect 99 90 102 92 << doubleptransistor >> rect 99 117 102 119 << collector >> rect 152 128 158 129 rect 152 124 153 128 rect 157 124 158 128 rect 152 123 158 124 << pbase >> rect 162 128 184 132 rect 162 124 166 128 rect 170 124 177 128 rect 181 124 184 128 rect 162 120 184 124 << bccdiffusion >> rect 195 91 224 95 << nbccdiffusion >> rect 193 91 195 95 rect 224 91 226 95 << polycontact >> rect 166 210 174 214 rect 194 212 198 216 rect 201 212 205 216 rect 165 199 175 205 rect 189 199 205 203 rect 218 200 222 204 rect 49 164 53 168 rect 88 168 92 172 rect 104 136 108 140 rect 106 117 110 121 rect 202 121 214 125 rect 106 90 110 94 rect 200 83 204 87 rect 209 83 213 87 rect 218 83 222 87 << ndcontact >> rect 124 213 128 217 rect 33 170 37 178 rect 41 170 53 174 rect -10 164 -2 168 rect 79 162 83 166 rect 203 134 213 138 rect 99 95 103 99 rect 100 82 104 86 << pdcontact >> rect 144 213 148 217 rect -10 180 -2 184 rect 99 122 103 126 rect 100 109 104 113 << capcontact >> rect 85 136 89 140 rect 96 136 100 140 rect 134 137 138 141 << electrodecontact >> rect 133 123 137 131 rect 89 111 97 115 rect 196 99 200 103 rect 205 99 209 103 rect 214 99 218 103 << collectorcontact >> rect 153 124 157 128 << emittercontact >> rect 166 124 170 128 << pbasecontact >> rect 177 124 181 128 << nbccdiffcontact >> rect 189 91 193 95 rect 226 91 230 95 << m2contact >> rect 109 169 118 173 rect 136 169 140 173 rect 156 165 160 169 rect 175 167 179 171 << m3contact >> rect 179 167 193 171 rect 201 163 205 167 << psubstratepcontact >> rect 128 213 132 217 rect 140 169 144 173 << nsubstratencontact >> rect 148 213 152 217 << psubstratepdiff >> rect 53 211 57 216 rect 135 173 144 174 rect 135 169 140 173 rect 135 168 144 169 << nsubstratendiff >> rect 53 200 57 205 << pad >> rect -7 102 33 142 << labels >> rlabel space 163 173 163 176 3 9.1 rlabel space 165 169 165 173 3 9.2 rlabel space 163 165 163 166 3 9.3 rlabel polysilicon 36 179 38 179 1 6b.7 rlabel ndcontact 34 171 36 173 5 6b.1 rlabel ndcontact 33 173 33 175 7 6b.3 rlabel ndiffusion 37 166 42 166 1 6b.4 rlabel ndcontact 50 171 52 173 1 _ rlabel ndcontact 46 171 48 173 1 _ rlabel ndcontact 42 171 44 173 1 _ rlabel ndcontact 34 175 36 177 1 _ rlabel ndiffusion 33 177 33 179 7 6b.6 rlabel polycontact 50 165 52 167 1 _ rlabel space 53 173 53 176 3 6b.8 rlabel space 33 166 33 171 7 6b.5 rlabel space 38 170 38 171 3 6b.2 rlabel metal1 53 167 53 171 3 6b.9 rlabel space 34 159 34 159 3 not_enforced rlabel space 34 161 34 161 3 6b.8 rlabel metal3 214 172 214 178 3 15.1 rlabel space 208 168 208 172 3 15.2 rlabel metal3 192 166 192 168 3 15.3 rlabel space -7 144 33 144 1 10.1,10.2 rlabel space 33 110 48 110 1 10.5 rlabel space 33 132 63 132 1 10.4 rlabel pad 23 132 23 142 3 10.3 rlabel capacitor 83 142 91 142 1 11.1 rlabel polysilicon 91 134 94 134 1 11.2 rlabel polysilicon 81 142 81 144 7 11.3 rlabel polysilicon 102 132 104 132 1 11.4 rlabel polysilicon 102 137 105 137 1 11.5 rlabel polycontact 105 137 107 139 1 _ rlabel polycontact 107 118 109 120 1 _ rlabel polysilicon 104 118 107 118 1 12.6 rlabel space 94 117 94 119 7 12.5 rlabel space 98 110 99 110 5 12.4 rlabel space 85 115 88 115 1 12.2 rlabel electrode 83 122 85 122 1 12.1 rlabel m3contact 190 168 192 170 1 14.1 rlabel m3contact 185 168 187 170 1 _ rlabel m3contact 187 167 190 167 5 14.2 rlabel m3contact 180 168 182 170 1 _ rlabel m2contact 176 168 178 170 1 _ rlabel metal3 178 171 180 171 1 14.4 rlabel m3contact 202 164 204 166 1 _ rlabel metal3 204 162 205 162 5 14.3 rlabel nwell 158 123 162 123 1 16.2 rlabel nwell 176 123 182 129 1 _ rlabel nwell 164 122 172 130 1 _ rlabel pbase 172 132 176 132 1 16.3 rlabel pbase 162 132 164 132 1 16.4 rlabel pbase 180 132 182 132 1 16.5 rlabel pbasecontact 178 125 180 127 1 _ rlabel nwell 152 114 158 114 1 16.6 rlabel nwell 150 131 152 131 1 16.7 rlabel emittercontact 167 125 169 127 1 16.8 rlabel pbase 176 120 178 120 1 16.9 rlabel collectorcontact 154 125 156 127 1 _ rlabel nwell 156 130 158 130 1 16.10 rlabel nwell 164 118 167 118 1 16.11 rlabel polycontact 203 122 205 124 1 _ rlabel polycontact 207 122 209 124 1 _ rlabel polycontact 211 122 213 124 1 _ rlabel space 199 124 199 127 7 18.4 rlabel space 199 130 199 135 7 18.5 rlabel capwell 202 141 203 141 1 18.2 rlabel space 217 127 217 130 3 18.1 rlabel space 221 130 221 138 3 18.3 rlabel space 37 213 37 216 3 2.1 rlabel space 42 212 45 212 1 2.2 rlabel space 55 208 55 211 3 2.4 rlabel space 50 208 50 213 3 2.3 rlabel space 37 208 58 208 5 N-Region rlabel space 37 208 58 208 1 P-Region rlabel space 39 203 39 208 3 2.3 rlabel space 59 205 59 208 3 2.4 rlabel space 128 218 129 218 1 4.3 rlabel space 134 210 134 213 3 4.1 rlabel space 121 218 122 218 1 4.2 rlabel space 173 216 175 216 1 5a.2 rlabel polycontact 169 210 171 210 1 5a.3 rlabel space 164 196 164 196 3 5a.2 rlabel space 164 194 164 194 3 not_enforced rlabel polycontact 167 211 169 213 1 _ rlabel polycontact 171 211 173 213 1 5a.1 rlabel polycontact 167 201 169 203 1 _ rlabel polycontact 171 201 173 203 1 _ rlabel space 80 211 80 213 3 3.1 rlabel space 79 209 79 211 3 3.2 rlabel space 80 204 80 207 3 3.4 rlabel space 76 203 78 203 1 3.3 rlabel space 67 219 68 219 1 3.5 rlabel space 90 211 90 213 7 3.1 rlabel space 91 209 91 211 7 3.2 rlabel space 90 204 90 207 7 3.4 rlabel space 92 203 94 203 1 3.3 rlabel space 102 219 103 219 1 3.5 rlabel space 197 218 198 218 1 5b.2 rlabel space 197 212 202 212 1 5b.4 rlabel space 204 212 208 212 1 5b.5 rlabel polycontact 192 199 194 199 1 5b.3 rlabel space 205 202 205 205 3 5b.7 rlabel space 192 196 192 196 3 5b.7 rlabel space 192 194 192 194 3 not_enforced rlabel polycontact 202 200 204 202 1 _ rlabel polycontact 198 200 200 202 1 _ rlabel polycontact 194 200 196 202 1 _ rlabel polycontact 190 200 192 202 1 _ rlabel polycontact 195 213 197 215 1 5b.1 rlabel polycontact 202 213 204 215 1 _ rlabel space 223 203 223 205 3 5b.6 rlabel space 216 199 216 199 3 (one_contact) rlabel polycontact 219 201 221 203 1 _ rlabel space 199 81 201 81 1 19.6 rlabel space 195 87 197 87 5 19.5 rlabel space 220 97 220 100 3 19.4 rlabel space 189 95 189 97 7 19.3 rlabel space 215 80 217 80 1 19.2 rlabel space 232 91 232 95 3 19.1 rlabel space -9 200 1 200 1 1.1 rlabel space 1 221 10 221 1 1.2 rlabel pdiffusion -3 182 -1 182 1 6a.4 rlabel space -9 159 -9 159 3 not_enforced rlabel space -9 161 -9 161 3 6a.2 rlabel ndcontact -7 167 -5 167 1 6a.3 rlabel pdcontact -9 181 -7 181 1 6a.1 rlabel ndiffusion -10 167 -10 169 7 6a.2 rlabel space 136 87 141 87 1 17.3 rlabel capwell 141 83 144 83 5 17.4 rlabel space 141 94 151 94 1 17.1 rlabel space 151 87 160 87 1 17.2 rlabel space 95 162 95 165 3 7.1 rlabel space 93 168 93 169 3 7.3 rlabel space 96 165 96 168 3 7.2 rlabel space 77 165 77 166 7 7.4 rlabel capcontact 135 138 137 140 1 13.1 rlabel polysilicon 130 140 130 143 7 13.3 rlabel space 132 147 134 147 1 13.4 rlabel nwell 184 114 190 114 5 16.1 rlabel space 112 162 115 162 1 8.2 rlabel space 104 168 104 170 7 8.4 rlabel space 104 172 104 174 7 8.4 rlabel space 139 175 141 175 1 8.5 rlabel space 137 166 139 166 5 8.1 rlabel space 147 169 147 170 3 8.3 rlabel space 146 172 146 174 3 8.4 rlabel space 129 114 129 114 3 not_enforced rlabel space 129 117 129 117 3 13.3,13.5* rlabel space 142 126 142 128 3 13.2 rlabel space 138 123 139 123 5 13.d* rlabel electrodecontact 134 124 136 126 1 _ rlabel electrodecontact 134 128 136 130 1 _ rlabel space 131 127 132 127 5 13.5 << end >> magic-8.0.210/scmos/rules/rule10.mag0000644000175000001440000000023110751423606015526 0ustar timusersmagic tech scmos timestamp 736072873 << metal1 >> rect 54 0 69 15 rect 115 0 130 30 << metal2 >> rect 130 50 140 90 << pad >> rect 0 0 100 100 << end >> magic-8.0.210/scmos/rules/rule11.mag0000644000175000001440000000063110751423606015533 0ustar timusersmagic tech scmos timestamp 736072947 << nwell >> rect 12 0 24 12 << polysilicon >> rect 0 19 15 21 rect 0 13 2 19 rect 10 13 15 19 rect 0 10 15 13 rect 0 2 2 10 rect 10 8 15 10 rect 10 4 12 8 rect 10 2 15 4 rect 0 0 15 2 << capacitor >> rect 2 13 10 19 rect 2 8 10 10 rect 2 4 4 8 rect 8 4 10 8 rect 2 2 10 4 << metal1 >> rect -3 4 4 8 << polycontact >> rect 12 4 16 8 << capcontact >> rect 4 4 8 8 << end >> magic-8.0.210/scmos/rules/rule15.mag0000644000175000001440000000036110751423606015537 0ustar timusersmagic tech scmos timestamp 736072621 << metal2 >> rect 1 5 5 16 rect 5 1 6 5 rect 1 0 5 1 << metal3 >> rect 0 10 14 16 rect 0 5 14 6 rect 0 1 1 5 rect 5 1 6 5 rect 10 1 14 5 rect 0 0 14 1 << m3contact >> rect 1 1 5 5 rect 6 1 10 5 << end >> magic-8.0.210/scmos/rules/rule7.mag0000644000175000001440000000052710751423606015464 0ustar timusersmagic tech scmos timestamp 715648344 << polysilicon >> rect 11 0 13 6 << ndiffusion >> rect 2 4 5 11 << metal1 >> rect 0 7 10 10 rect 5 0 15 3 << polycontact >> rect 10 6 14 10 << ndcontact >> rect 1 0 5 4 << labels >> rlabel space 0 3 0 4 7 7.4 rlabel space 17 0 17 3 3 7.1 rlabel space 15 6 15 7 3 7.3 rlabel space 18 3 18 6 3 7.2 << end >> magic-8.0.210/scmos/rules/rule6b.mag0000644000175000001440000000053010751423606015617 0ustar timusersmagic tech scmos timestamp 736071673 << polysilicon >> rect 1 17 3 19 rect 7 17 10 19 rect 8 16 10 17 rect 8 14 23 16 << ndiffusion >> rect 3 19 7 22 rect 3 16 7 17 rect 11 4 14 9 rect 0 1 14 4 << metal1 >> rect 19 7 23 9 << ntransistor >> rect 3 17 7 19 << polycontact >> rect 19 3 23 7 << ndcontact >> rect 3 8 7 16 rect 11 9 23 13 << end >> magic-8.0.210/scmos/rules/rule4.mag0000644000175000001440000000132610751423606015457 0ustar timusersmagic tech scmos timestamp 717145414 << polysilicon >> rect -3 8 -1 15 rect -3 6 0 8 rect 10 6 20 8 rect 30 6 33 8 rect 31 0 33 6 << ndiffusion >> rect 0 15 4 18 rect 0 11 2 15 rect 0 8 10 11 rect 0 5 10 6 rect 0 1 3 5 rect 7 1 10 5 rect 0 0 10 1 << pdiffusion >> rect 20 15 24 18 rect 20 11 22 15 rect 20 8 30 11 rect 20 5 30 6 rect 20 1 23 5 rect 27 1 30 5 rect 20 0 30 1 << ntransistor >> rect 0 6 10 8 << ptransistor >> rect 20 6 30 8 << ndcontact >> rect 2 11 6 15 rect 3 1 7 5 << pdcontact >> rect 22 11 26 15 rect 23 1 27 5 << psubstratepcontact >> rect 6 11 10 15 << nsubstratencontact >> rect 26 11 30 15 << labels >> rlabel space -2 -2 0 -2 1 4.2 rlabel space 6 16 7 16 1 4.3 rlabel space 12 8 12 11 3 4.1 << end >> magic-8.0.210/scmos/rules/rule14.mag0000644000175000001440000000117110751423606015536 0ustar timusersmagic tech scmos timestamp 726211220 << metal1 >> rect 0 19 4 23 rect 0 15 14 19 rect 0 9 4 15 rect 0 0 4 5 << metal2 >> rect 18 15 19 19 rect 23 15 24 19 rect 19 14 24 15 rect 19 10 20 14 rect 19 9 24 10 rect 13 5 19 9 rect 23 5 28 9 << metal3 >> rect 18 19 25 23 rect 18 15 19 19 rect 23 15 25 19 rect 18 14 25 15 rect 8 10 14 14 rect 3 9 14 10 rect 3 5 4 9 rect 13 5 14 9 rect 3 4 14 5 rect 8 0 14 4 rect 18 10 20 14 rect 24 10 25 14 rect 18 9 25 10 rect 18 5 19 9 rect 23 5 25 9 rect 18 0 25 5 << m2contact >> rect 14 15 18 19 rect 0 5 4 9 << m3contact >> rect 19 15 23 19 rect 20 10 24 14 rect 4 5 13 9 rect 19 5 23 9 << end >> magic-8.0.210/scmos/rules/rule18.mag0000644000175000001440000000065410751423606015547 0ustar timusersmagic tech scmos timestamp 732461619 << capwell >> rect 0 0 12 26 rect 21 0 45 26 << polysilicon >> rect 2 4 3 15 rect 42 13 46 16 rect 2 2 6 4 << wellcapacitor >> rect 3 4 6 15 rect 27 16 39 20 rect 27 13 42 16 rect 27 6 39 13 << ndiffusion >> rect 3 15 9 19 rect 6 4 9 15 rect 24 20 42 23 rect 24 6 27 20 rect 39 16 42 20 rect 39 6 42 13 rect 24 3 42 6 << polycontact >> rect 2 -2 6 2 << ndcontact >> rect 3 19 9 23 << end >> magic-8.0.210/scmos/rules/rule6a.mag0000644000175000001440000000054610751423606015625 0ustar timusersmagic tech scmos timestamp 715647645 << polysilicon >> rect 9 20 11 22 rect 9 6 11 16 rect 9 0 11 2 << ndiffusion >> rect 0 2 4 6 rect 8 2 9 6 rect 11 2 15 6 << pdiffusion >> rect 0 16 4 20 rect 8 16 9 20 rect 11 16 15 20 << ndcontact >> rect 4 2 8 6 << pdcontact >> rect 4 16 8 20 << ntransistor >> rect 9 2 11 6 << ptransistor >> rect 9 16 11 20 << end >> magic-8.0.210/scmos/rules/rule5a.mag0000644000175000001440000000011710751423606015616 0ustar timusersmagic tech scmos timestamp 716090279 << polycontact >> rect 0 0 12 4 << end >> magic-8.0.210/scmos/rules/rule9.mag0000644000175000001440000000041010751423606015455 0ustar timusersmagic tech scmos timestamp 715648933 << metal1 >> rect 7 0 10 3 << metal2 >> rect 0 11 11 14 rect 0 4 6 7 rect 10 4 11 7 << m2contact >> rect 6 3 10 7 << labels >> rlabel space 13 11 13 14 3 9.1 rlabel space 15 7 15 11 3 9.2 rlabel space 13 3 13 4 3 9.3 << end >> magic-8.0.210/scmos/rules/rule5b.mag0000644000175000001440000000077710751423606015633 0ustar timusersmagic tech scmos timestamp 736035532 << polysilicon >> rect 13 16 15 19 rect 1 13 5 15 rect 19 12 21 19 rect 31 9 33 12 rect 31 4 33 5 << ndiffusion >> rect 0 5 16 9 << pdiffusion >> rect 28 5 31 9 rect 33 5 36 9 << ptransistor >> rect 31 5 33 9 << polycontact >> rect 5 12 9 16 rect 12 12 16 16 rect 0 0 16 4 rect 30 0 34 4 << labels >> rlabel ndiffusion 4 7 4 7 1 a rlabel ptransistor 32 7 32 7 1 b rlabel polycontact 32 2 32 2 1 c rlabel pdiffusion 29 7 29 7 1 f rlabel polysilicon 20 15 20 15 1 d << end >> magic-8.0.210/scmos/mos.7bit.mraster.cmap0000644000175000001440000000162610751423606016567 0ustar timusers0 0 0 0 220 95 95 1 66 213 66 2 202 160 115 3 169 131 101 4 184 73 83 5 230 230 0 6 0 0 0 7 125 166 250 8 160 48 191 9 89 162 165 10 150 153 168 11 139 117 155 12 134 102 149 13 190 190 120 14 0 0 0 15 190 153 222 16 182 94 158 17 143 161 169 18 174 140 165 19 148 114 152 20 146 118 154 21 220 204 169 22 0 0 0 23 153 130 218 24 144 40 178 25 113 143 168 26 141 132 171 27 128 121 143 28 127 111 146 29 168 156 129 30 0 0 0 31 255 223 229 32 237 163 165 33 160 207 153 34 228 187 173 35 212 176 167 36 219 154 160 37 242 214 127 38 255 223 229 39 190 189 227 40 207 145 203 41 172 188 193 42 202 185 194 43 197 171 189 44 194 165 186 45 222 199 175 46 255 223 229 47 222 185 215 48 218 162 190 49 199 188 194 50 214 180 193 51 201 170 188 52 200 171 188 53 237 204 194 54 255 223 229 55 204 176 214 56 199 142 198 57 184 181 194 58 198 177 195 59 191 173 184 60 191 169 185 61 211 186 178 62 255 223 229 63 0 0 0 255 magic-8.0.210/scmos/mos.7bit.std.cmap0000644000175000001440000000314211120112374015663 0ustar timusers#-------------------------------------- # Colormap file for X11, 8-bit graphics #-------------------------------------- 200 200 200 0 background_gray 220 95 95 1 poly_red 66 213 66 2 diff_green 202 160 115 3 diff_brown 169 131 101 4 nfet_brown 184 73 83 5 pfet_brown 230 230 0 6 well_yellow 0 0 0 7 contact_black 125 166 250 8 metal_blue 160 48 191 9 pc_purple 89 162 165 10 150 153 168 11 139 117 155 12 134 102 149 13 190 190 120 14 0 0 0 15 190 153 222 16 metal_purple 182 94 158 17 143 161 169 18 174 140 165 19 148 114 152 20 146 118 154 21 220 204 169 22 0 0 0 23 153 130 218 24 144 40 178 25 113 143 168 26 141 132 171 27 128 121 143 28 127 111 146 29 168 156 129 30 0 0 0 31 255 255 255 32 cursor_white 170 170 170 33 pale_gray 145 145 145 34 dark_gray 0 0 0 35 box_black 239 188 198 36 pale_red 239 125 162 37 medium_red 210 0 155 38 dark_red 165 216 175 39 pale_green 124 191 148 40 medium_green 0 181 0 41 dark_green 170 202 242 42 light_blue 0 0 250 43 dark_blue 40 169 166 44 teal_blue 45 94 179 45 deep_purple 167 0 200 46 bright_purple 255 248 179 47 light_yellow 255 255 0 48 bright_yellow 235 198 160 49 yellow_orange 234 132 73 50 medium_orange 198 152 0 51 ochre_brown 139 108 0 52 medium_brown 195 176 211 53 pale_purple 50 228 225 54 port_cyan 120 81 29 55 border_brown 200 230 230 56 caption_blue 180 210 180 57 window_gray 0 0 0 58 246 246 7 59 label_yellow 180 180 180 60 medium_gray 230 180 50 61 pale_orange 235 235 235 62 light_gray 0 0 0 63 255 255 255 127 0 0 0 255 magic-8.0.210/scmos/minimum.tech.m40000644000175000001440000000052410751423606015442 0ustar timuserstech format 28 minimum end version version 0.0 description "Minimum technology file structure" end planes end types end contact end styles styletype mos end compose end connect end cifoutput end cifinput end # mzrouter # end drc end extract end # wiring # end # router # end # plowing # end # plot # end magic-8.0.210/scmos/examples/0000755000175000001440000000000011504623577014426 5ustar timusersmagic-8.0.210/scmos/examples/bipolar/0000755000175000001440000000000011504623577016056 5ustar timusersmagic-8.0.210/scmos/examples/bipolar/guardring-npn.mag0000644000175000001440000000276110751423606021317 0ustar timusersmagic tech scmos timestamp 796597909 << nwell >> rect -28 -20 30 38 << metal1 >> rect -38 41 -35 45 rect 32 41 33 45 rect -38 30 -23 34 rect 21 33 26 34 rect 21 30 22 33 rect -8 18 -6 22 rect 8 21 14 22 rect 8 18 10 21 rect -38 7 -1 11 rect -38 -4 -12 0 rect -8 -4 -6 0 rect 8 -3 10 0 rect 8 -4 14 -3 rect 21 -15 22 -12 rect 21 -16 26 -15 rect -38 -27 -35 -23 rect 32 -27 33 -23 << collector >> rect -25 34 27 35 rect -25 30 -23 34 rect 21 33 27 34 rect 21 30 22 33 rect -25 29 22 30 rect -25 -11 -19 29 rect 21 -11 22 29 rect -25 -12 22 -11 rect -25 -16 -23 -12 rect 21 -15 22 -12 rect 26 -15 27 33 rect 21 -16 27 -15 rect -25 -17 27 -16 << pbase >> rect -15 22 17 25 rect -15 14 -12 22 rect -8 18 -6 22 rect 8 21 17 22 rect 8 18 10 21 rect -8 14 10 18 rect -15 11 10 14 rect -15 7 -1 11 rect 3 7 10 11 rect -15 4 10 7 rect -15 -4 -12 4 rect -8 0 10 4 rect -8 -4 -6 0 rect 8 -3 10 0 rect 14 -3 17 21 rect 8 -4 17 -3 rect -15 -7 17 -4 << collectorcontact >> rect -23 30 21 34 rect -23 -16 21 -12 rect 22 -15 26 33 << emittercontact >> rect -1 7 3 11 << pbasecontact >> rect -12 14 -8 22 rect -6 18 8 22 rect -12 -4 -8 4 rect -6 -4 8 0 rect 10 -3 14 21 << psubstratepcontact >> rect -35 41 32 45 rect -35 -27 32 -23 rect 33 -27 37 45 << psubstratepdiff >> rect 32 41 33 45 rect -35 -23 -31 41 rect 32 -27 33 -23 << labels >> rlabel metal1 -37 9 -37 9 4 EMITTER rlabel metal1 -37 -2 -37 -2 2 BASE rlabel metal1 -37 -25 -37 -25 2 GUARDRING rlabel metal1 -37 43 -37 43 4 GND rlabel metal1 -37 32 -37 32 4 COLLECTOR << end >> magic-8.0.210/scmos/examples/bipolar/npn_array16.cif0000644000175000001440000051431210751423606020701 0ustar timusersDS 1 40 2; 9 npn_array16; L CWN; B 192 128 1296 632; B 192 172 2008 658; B 808 172 2864 658; B 1516 172 4386 658; B 456 172 5748 658; B 280 172 6452 658; L CMS; B 400 400 264 1056; B 400 400 1064 1056; B 400 400 1864 1056; B 400 400 2664 1056; B 400 400 3464 1056; B 400 400 4264 1056; B 400 400 5064 1056; B 400 400 5864 1056; B 400 400 6664 1056; B 400 400 7464 1056; B 400 400 264 256; B 400 400 1064 256; B 400 400 1864 256; B 400 400 2664 256; B 400 400 3464 256; B 400 400 4264 256; B 400 400 5064 256; B 400 400 5864 256; B 400 400 6664 256; B 400 400 7464 256; L CMF; B 7736 32 3868 1296; B 32 1248 16 656; B 400 400 264 1056; B 44 160 670 1200; B 400 224 1064 1144; B 484 20 1106 1022; B 400 156 1064 934; B 20 108 258 802; B 1072 16 784 740; B 88 16 1248 684; B 16 88 1212 632; B 16 68 1312 698; B 32 12 1304 658; B 16 28 1252 626; B 16 28 1296 638; B 16 400 1340 812; B 400 400 1864 1056; B 44 160 2270 1200; B 400 400 2664 1056; B 400 400 3464 1056; B 44 160 3870 1200; B 400 400 4264 1056; B 400 400 5064 1056; B 44 160 5470 1200; B 400 400 5864 1056; B 400 400 6664 1056; B 44 160 7070 1200; B 64 24 7468 1268; B 400 400 7464 1056; B 88 16 1960 732; B 28 16 1374 684; B 104 12 1296 606; B 16 88 1380 632; B 184 16 1296 580; B 16 132 1924 658; B 16 152 2024 780; B 24 60 2652 826; B 32 16 2016 696; B 620 20 2354 786; B 16 72 1964 652; B 16 60 2008 658; B 16 160 2052 696; B 16 116 3436 798; B 32 72 4280 820; B 808 20 4668 774; B 28 16 2086 732; B 104 12 2008 610; B 16 132 2092 658; B 184 16 2008 584; B 980 16 2954 732; B 1412 16 4338 732; B 16 132 2472 658; B 720 12 2864 706; B 16 72 2512 664; B 16 72 2556 652; B 16 72 2600 664; B 16 72 2644 652; B 16 72 2688 664; B 16 72 2732 652; B 16 72 2776 664; B 16 72 2820 652; B 16 72 2864 664; B 16 72 2908 652; B 16 72 2952 664; B 16 72 2996 652; B 16 72 3040 664; B 16 72 3084 652; B 16 72 3128 664; B 16 72 3172 652; B 648 12 2872 610; B 700 16 2814 584; B 16 116 1212 514; B 16 120 1924 516; B 16 76 3188 566; B 472 16 2960 520; B 20 56 2734 484; B 400 400 264 256; B 400 400 1064 256; B 64 24 252 44; B 44 160 1462 112; B 400 400 1864 256; B 400 400 2664 256; B 16 404 3216 498; B 16 132 3256 658; B 28 16 3250 584; B 16 132 3640 658; B 16 52 5064 738; B 1356 12 4394 706; B 16 72 3680 652; B 16 72 3724 664; B 16 72 3768 652; B 16 72 3812 664; B 16 72 3856 652; B 16 72 3900 664; B 16 72 3944 652; B 16 72 3988 664; B 16 72 4032 652; B 16 72 4076 664; B 16 72 4120 652; B 16 72 4164 664; B 16 72 4208 652; B 16 72 4252 664; B 16 72 4296 652; B 16 72 4340 664; B 16 72 4384 652; B 16 72 4428 664; B 16 72 4472 652; B 16 72 4516 664; B 16 72 4560 652; B 16 72 4604 664; B 16 72 4648 652; B 16 72 4692 664; B 16 72 4736 652; B 16 72 4784 664; B 16 72 4828 652; B 16 72 4872 664; B 16 72 4916 652; B 16 72 4960 664; B 16 72 5004 652; B 16 72 5048 664; B 20 240 5094 736; B 20 116 5862 798; B 20 116 6698 798; B 24 16 5128 732; B 1432 12 4388 610; B 16 132 5132 658; B 1508 16 4386 584; B 448 16 5748 732; B 16 132 5532 658; B 368 12 5748 706; B 28 16 5538 584; B 32 120 4276 516; B 16 212 5572 594; B 16 72 5616 652; B 16 72 5660 664; B 16 72 5704 652; B 16 72 5748 664; B 16 72 5792 652; B 16 72 5836 664; B 16 72 5880 652; B 16 72 5924 664; B 340 16 5410 480; B 296 12 5740 610; B 24 16 5252 464; B 400 160 3464 376; B 456 16 3436 288; B 44 160 3062 112; B 400 224 3464 168; B 400 400 4264 256; B 44 160 4662 112; B 400 400 5064 256; B 16 368 5600 420; B 16 132 5964 658; B 352 16 5796 584; B 392 16 6512 732; B 16 132 6324 658; B 192 12 6452 706; B 16 72 6364 664; B 16 72 6408 652; B 16 72 6452 664; B 16 72 6496 652; B 120 12 6460 610; B 176 16 6404 584; B 16 148 6512 530; B 16 160 6540 620; B 16 132 6580 658; B 28 16 6574 584; B 960 16 7012 532; B 24 68 7480 490; B 400 220 5864 346; B 472 16 5828 228; B 400 164 5864 138; B 44 160 6262 112; B 400 400 6664 256; B 400 400 7464 256; B 32 1248 7720 656; B 7736 32 3868 16; L CAA; B 44 72 670 1156; B 44 72 2270 1156; B 44 72 3870 1156; B 44 72 5470 1156; B 44 72 7070 1156; B 192 24 2008 732; B 192 24 1296 684; B 24 80 1212 632; B 112 48 1296 632; B 24 80 1380 632; B 192 24 1296 580; B 24 124 1924 658; B 112 92 2008 658; B 24 124 2092 658; B 192 24 2008 584; B 808 24 2864 732; B 24 124 2472 658; B 728 92 2864 658; B 24 124 3256 658; B 808 24 2864 584; B 1516 24 4386 732; B 24 124 3640 658; B 1436 92 4386 658; B 24 124 5132 658; B 1516 24 4386 584; B 456 24 5748 732; B 24 124 5532 658; B 376 92 5748 658; B 24 124 5964 658; B 456 24 5748 584; B 280 24 6452 732; B 24 124 6324 658; B 200 92 6452 658; B 24 124 6580 658; B 280 24 6452 584; B 44 72 1462 156; B 44 72 3062 156; B 44 72 4662 156; B 44 72 6262 156; L CX; B 200 32 2008 732; B 200 32 1296 684; B 32 72 1212 632; B 32 72 1380 632; B 200 32 1296 580; B 32 116 1924 658; B 32 116 2092 658; B 200 32 2008 584; B 816 32 2864 732; B 32 116 2472 658; B 32 116 3256 658; B 816 32 2864 584; B 1524 32 4386 732; B 32 116 3640 658; B 32 116 5132 658; B 1524 32 4386 584; B 464 32 5748 732; B 32 116 5532 658; B 32 116 5964 658; B 464 32 5748 584; B 288 32 6452 732; B 32 116 6324 658; B 32 116 6580 658; B 288 32 6452 584; L CVA; B 8 8 84 1236; B 8 8 104 1236; B 8 8 124 1236; B 8 8 144 1236; B 8 8 164 1236; B 8 8 184 1236; B 8 8 204 1236; B 8 8 224 1236; B 8 8 244 1236; B 8 8 264 1236; B 8 8 284 1236; B 8 8 304 1236; B 8 8 324 1236; B 8 8 344 1236; B 8 8 364 1236; B 8 8 384 1236; B 8 8 404 1236; B 8 8 424 1236; B 8 8 444 1236; B 8 8 884 1236; B 8 8 904 1236; B 8 8 924 1236; B 8 8 944 1236; B 8 8 964 1236; B 8 8 984 1236; B 8 8 1004 1236; B 8 8 1024 1236; B 8 8 1044 1236; B 8 8 1064 1236; B 8 8 1084 1236; B 8 8 1104 1236; B 8 8 1124 1236; B 8 8 1144 1236; B 8 8 1164 1236; B 8 8 1184 1236; B 8 8 1204 1236; B 8 8 1224 1236; B 8 8 1244 1236; B 8 8 1684 1236; B 8 8 1704 1236; B 8 8 1724 1236; B 8 8 1744 1236; B 8 8 1764 1236; B 8 8 1784 1236; B 8 8 1804 1236; B 8 8 1824 1236; B 8 8 1844 1236; B 8 8 1864 1236; B 8 8 1884 1236; B 8 8 1904 1236; B 8 8 1924 1236; B 8 8 1944 1236; B 8 8 1964 1236; B 8 8 1984 1236; B 8 8 2004 1236; B 8 8 2024 1236; B 8 8 2044 1236; B 8 8 2484 1236; B 8 8 2504 1236; B 8 8 2524 1236; B 8 8 2544 1236; B 8 8 2564 1236; B 8 8 2584 1236; B 8 8 2604 1236; B 8 8 2624 1236; B 8 8 2644 1236; B 8 8 2664 1236; B 8 8 2684 1236; B 8 8 2704 1236; B 8 8 2724 1236; B 8 8 2744 1236; B 8 8 2764 1236; B 8 8 2784 1236; B 8 8 2804 1236; B 8 8 2824 1236; B 8 8 2844 1236; B 8 8 3284 1236; B 8 8 3304 1236; B 8 8 3324 1236; B 8 8 3344 1236; B 8 8 3364 1236; B 8 8 3384 1236; B 8 8 3404 1236; B 8 8 3424 1236; B 8 8 3444 1236; B 8 8 3464 1236; B 8 8 3484 1236; B 8 8 3504 1236; B 8 8 3524 1236; B 8 8 3544 1236; B 8 8 3564 1236; B 8 8 3584 1236; B 8 8 3604 1236; B 8 8 3624 1236; B 8 8 3644 1236; B 8 8 4084 1236; B 8 8 4104 1236; B 8 8 4124 1236; B 8 8 4144 1236; B 8 8 4164 1236; B 8 8 4184 1236; B 8 8 4204 1236; B 8 8 4224 1236; B 8 8 4244 1236; B 8 8 4264 1236; B 8 8 4284 1236; B 8 8 4304 1236; B 8 8 4324 1236; B 8 8 4344 1236; B 8 8 4364 1236; B 8 8 4384 1236; B 8 8 4404 1236; B 8 8 4424 1236; B 8 8 4444 1236; B 8 8 4884 1236; B 8 8 4904 1236; B 8 8 4924 1236; B 8 8 4944 1236; B 8 8 4964 1236; B 8 8 4984 1236; B 8 8 5004 1236; B 8 8 5024 1236; B 8 8 5044 1236; B 8 8 5064 1236; B 8 8 5084 1236; B 8 8 5104 1236; B 8 8 5124 1236; B 8 8 5144 1236; B 8 8 5164 1236; B 8 8 5184 1236; B 8 8 5204 1236; B 8 8 5224 1236; B 8 8 5244 1236; B 8 8 5684 1236; B 8 8 5704 1236; B 8 8 5724 1236; B 8 8 5744 1236; B 8 8 5764 1236; B 8 8 5784 1236; B 8 8 5804 1236; B 8 8 5824 1236; B 8 8 5844 1236; B 8 8 5864 1236; B 8 8 5884 1236; B 8 8 5904 1236; B 8 8 5924 1236; B 8 8 5944 1236; B 8 8 5964 1236; B 8 8 5984 1236; B 8 8 6004 1236; B 8 8 6024 1236; B 8 8 6044 1236; B 8 8 6484 1236; B 8 8 6504 1236; B 8 8 6524 1236; B 8 8 6544 1236; B 8 8 6564 1236; B 8 8 6584 1236; B 8 8 6604 1236; B 8 8 6624 1236; B 8 8 6644 1236; B 8 8 6664 1236; B 8 8 6684 1236; B 8 8 6704 1236; B 8 8 6724 1236; B 8 8 6744 1236; B 8 8 6764 1236; B 8 8 6784 1236; B 8 8 6804 1236; B 8 8 6824 1236; B 8 8 6844 1236; B 8 8 7284 1236; B 8 8 7304 1236; B 8 8 7324 1236; B 8 8 7344 1236; B 8 8 7364 1236; B 8 8 7384 1236; B 8 8 7404 1236; B 8 8 7424 1236; B 8 8 7444 1236; B 8 8 7464 1236; B 8 8 7484 1236; B 8 8 7504 1236; B 8 8 7524 1236; B 8 8 7544 1236; B 8 8 7564 1236; B 8 8 7584 1236; B 8 8 7604 1236; B 8 8 7624 1236; B 8 8 7644 1236; B 8 8 84 1216; B 8 8 104 1216; B 8 8 124 1216; B 8 8 144 1216; B 8 8 164 1216; B 8 8 184 1216; B 8 8 204 1216; B 8 8 224 1216; B 8 8 244 1216; B 8 8 264 1216; B 8 8 284 1216; B 8 8 304 1216; B 8 8 324 1216; B 8 8 344 1216; B 8 8 364 1216; B 8 8 384 1216; B 8 8 404 1216; B 8 8 424 1216; B 8 8 444 1216; B 8 8 884 1216; B 8 8 904 1216; B 8 8 924 1216; B 8 8 944 1216; B 8 8 964 1216; B 8 8 984 1216; B 8 8 1004 1216; B 8 8 1024 1216; B 8 8 1044 1216; B 8 8 1064 1216; B 8 8 1084 1216; B 8 8 1104 1216; B 8 8 1124 1216; B 8 8 1144 1216; B 8 8 1164 1216; B 8 8 1184 1216; B 8 8 1204 1216; B 8 8 1224 1216; B 8 8 1244 1216; B 8 8 1684 1216; B 8 8 1704 1216; B 8 8 1724 1216; B 8 8 1744 1216; B 8 8 1764 1216; B 8 8 1784 1216; B 8 8 1804 1216; B 8 8 1824 1216; B 8 8 1844 1216; B 8 8 1864 1216; B 8 8 1884 1216; B 8 8 1904 1216; B 8 8 1924 1216; B 8 8 1944 1216; B 8 8 1964 1216; B 8 8 1984 1216; B 8 8 2004 1216; B 8 8 2024 1216; B 8 8 2044 1216; B 8 8 2484 1216; B 8 8 2504 1216; B 8 8 2524 1216; B 8 8 2544 1216; B 8 8 2564 1216; B 8 8 2584 1216; B 8 8 2604 1216; B 8 8 2624 1216; B 8 8 2644 1216; B 8 8 2664 1216; B 8 8 2684 1216; B 8 8 2704 1216; B 8 8 2724 1216; B 8 8 2744 1216; B 8 8 2764 1216; B 8 8 2784 1216; B 8 8 2804 1216; B 8 8 2824 1216; B 8 8 2844 1216; B 8 8 3284 1216; B 8 8 3304 1216; B 8 8 3324 1216; B 8 8 3344 1216; B 8 8 3364 1216; B 8 8 3384 1216; B 8 8 3404 1216; B 8 8 3424 1216; B 8 8 3444 1216; B 8 8 3464 1216; B 8 8 3484 1216; B 8 8 3504 1216; B 8 8 3524 1216; B 8 8 3544 1216; B 8 8 3564 1216; B 8 8 3584 1216; B 8 8 3604 1216; B 8 8 3624 1216; B 8 8 3644 1216; B 8 8 4084 1216; B 8 8 4104 1216; B 8 8 4124 1216; B 8 8 4144 1216; B 8 8 4164 1216; B 8 8 4184 1216; B 8 8 4204 1216; B 8 8 4224 1216; B 8 8 4244 1216; B 8 8 4264 1216; B 8 8 4284 1216; B 8 8 4304 1216; B 8 8 4324 1216; B 8 8 4344 1216; B 8 8 4364 1216; B 8 8 4384 1216; B 8 8 4404 1216; B 8 8 4424 1216; B 8 8 4444 1216; B 8 8 4884 1216; B 8 8 4904 1216; B 8 8 4924 1216; B 8 8 4944 1216; B 8 8 4964 1216; B 8 8 4984 1216; B 8 8 5004 1216; B 8 8 5024 1216; B 8 8 5044 1216; B 8 8 5064 1216; B 8 8 5084 1216; B 8 8 5104 1216; B 8 8 5124 1216; B 8 8 5144 1216; B 8 8 5164 1216; B 8 8 5184 1216; B 8 8 5204 1216; B 8 8 5224 1216; B 8 8 5244 1216; B 8 8 5684 1216; B 8 8 5704 1216; B 8 8 5724 1216; B 8 8 5744 1216; B 8 8 5764 1216; B 8 8 5784 1216; B 8 8 5804 1216; B 8 8 5824 1216; B 8 8 5844 1216; B 8 8 5864 1216; B 8 8 5884 1216; B 8 8 5904 1216; B 8 8 5924 1216; B 8 8 5944 1216; B 8 8 5964 1216; B 8 8 5984 1216; B 8 8 6004 1216; B 8 8 6024 1216; B 8 8 6044 1216; B 8 8 6484 1216; B 8 8 6504 1216; B 8 8 6524 1216; B 8 8 6544 1216; B 8 8 6564 1216; B 8 8 6584 1216; B 8 8 6604 1216; B 8 8 6624 1216; B 8 8 6644 1216; B 8 8 6664 1216; B 8 8 6684 1216; B 8 8 6704 1216; B 8 8 6724 1216; B 8 8 6744 1216; B 8 8 6764 1216; B 8 8 6784 1216; B 8 8 6804 1216; B 8 8 6824 1216; B 8 8 6844 1216; B 8 8 7284 1216; B 8 8 7304 1216; B 8 8 7324 1216; B 8 8 7344 1216; B 8 8 7364 1216; B 8 8 7384 1216; B 8 8 7404 1216; B 8 8 7424 1216; B 8 8 7444 1216; B 8 8 7464 1216; B 8 8 7484 1216; B 8 8 7504 1216; B 8 8 7524 1216; B 8 8 7544 1216; B 8 8 7564 1216; B 8 8 7584 1216; B 8 8 7604 1216; B 8 8 7624 1216; B 8 8 7644 1216; B 8 8 84 1196; B 8 8 104 1196; B 8 8 124 1196; B 8 8 144 1196; B 8 8 164 1196; B 8 8 184 1196; B 8 8 204 1196; B 8 8 224 1196; B 8 8 244 1196; B 8 8 264 1196; B 8 8 284 1196; B 8 8 304 1196; B 8 8 324 1196; B 8 8 344 1196; B 8 8 364 1196; B 8 8 384 1196; B 8 8 404 1196; B 8 8 424 1196; B 8 8 444 1196; B 8 8 884 1196; B 8 8 904 1196; B 8 8 924 1196; B 8 8 944 1196; B 8 8 964 1196; B 8 8 984 1196; B 8 8 1004 1196; B 8 8 1024 1196; B 8 8 1044 1196; B 8 8 1064 1196; B 8 8 1084 1196; B 8 8 1104 1196; B 8 8 1124 1196; B 8 8 1144 1196; B 8 8 1164 1196; B 8 8 1184 1196; B 8 8 1204 1196; B 8 8 1224 1196; B 8 8 1244 1196; B 8 8 1684 1196; B 8 8 1704 1196; B 8 8 1724 1196; B 8 8 1744 1196; B 8 8 1764 1196; B 8 8 1784 1196; B 8 8 1804 1196; B 8 8 1824 1196; B 8 8 1844 1196; B 8 8 1864 1196; B 8 8 1884 1196; B 8 8 1904 1196; B 8 8 1924 1196; B 8 8 1944 1196; B 8 8 1964 1196; B 8 8 1984 1196; B 8 8 2004 1196; B 8 8 2024 1196; B 8 8 2044 1196; B 8 8 2484 1196; B 8 8 2504 1196; B 8 8 2524 1196; B 8 8 2544 1196; B 8 8 2564 1196; B 8 8 2584 1196; B 8 8 2604 1196; B 8 8 2624 1196; B 8 8 2644 1196; B 8 8 2664 1196; B 8 8 2684 1196; B 8 8 2704 1196; B 8 8 2724 1196; B 8 8 2744 1196; B 8 8 2764 1196; B 8 8 2784 1196; B 8 8 2804 1196; B 8 8 2824 1196; B 8 8 2844 1196; B 8 8 3284 1196; B 8 8 3304 1196; B 8 8 3324 1196; B 8 8 3344 1196; B 8 8 3364 1196; B 8 8 3384 1196; B 8 8 3404 1196; B 8 8 3424 1196; B 8 8 3444 1196; B 8 8 3464 1196; B 8 8 3484 1196; B 8 8 3504 1196; B 8 8 3524 1196; B 8 8 3544 1196; B 8 8 3564 1196; B 8 8 3584 1196; B 8 8 3604 1196; B 8 8 3624 1196; B 8 8 3644 1196; B 8 8 4084 1196; B 8 8 4104 1196; B 8 8 4124 1196; B 8 8 4144 1196; B 8 8 4164 1196; B 8 8 4184 1196; B 8 8 4204 1196; B 8 8 4224 1196; B 8 8 4244 1196; B 8 8 4264 1196; B 8 8 4284 1196; B 8 8 4304 1196; B 8 8 4324 1196; B 8 8 4344 1196; B 8 8 4364 1196; B 8 8 4384 1196; B 8 8 4404 1196; B 8 8 4424 1196; B 8 8 4444 1196; B 8 8 4884 1196; B 8 8 4904 1196; B 8 8 4924 1196; B 8 8 4944 1196; B 8 8 4964 1196; B 8 8 4984 1196; B 8 8 5004 1196; B 8 8 5024 1196; B 8 8 5044 1196; B 8 8 5064 1196; B 8 8 5084 1196; B 8 8 5104 1196; B 8 8 5124 1196; B 8 8 5144 1196; B 8 8 5164 1196; B 8 8 5184 1196; B 8 8 5204 1196; B 8 8 5224 1196; B 8 8 5244 1196; B 8 8 5684 1196; B 8 8 5704 1196; B 8 8 5724 1196; B 8 8 5744 1196; B 8 8 5764 1196; B 8 8 5784 1196; B 8 8 5804 1196; B 8 8 5824 1196; B 8 8 5844 1196; B 8 8 5864 1196; B 8 8 5884 1196; B 8 8 5904 1196; B 8 8 5924 1196; B 8 8 5944 1196; B 8 8 5964 1196; B 8 8 5984 1196; B 8 8 6004 1196; B 8 8 6024 1196; B 8 8 6044 1196; B 8 8 6484 1196; B 8 8 6504 1196; B 8 8 6524 1196; B 8 8 6544 1196; B 8 8 6564 1196; B 8 8 6584 1196; B 8 8 6604 1196; B 8 8 6624 1196; B 8 8 6644 1196; B 8 8 6664 1196; B 8 8 6684 1196; B 8 8 6704 1196; B 8 8 6724 1196; B 8 8 6744 1196; B 8 8 6764 1196; B 8 8 6784 1196; B 8 8 6804 1196; B 8 8 6824 1196; B 8 8 6844 1196; B 8 8 7284 1196; B 8 8 7304 1196; B 8 8 7324 1196; B 8 8 7344 1196; B 8 8 7364 1196; B 8 8 7384 1196; B 8 8 7404 1196; B 8 8 7424 1196; B 8 8 7444 1196; B 8 8 7464 1196; B 8 8 7484 1196; B 8 8 7504 1196; B 8 8 7524 1196; B 8 8 7544 1196; B 8 8 7564 1196; B 8 8 7584 1196; B 8 8 7604 1196; B 8 8 7624 1196; B 8 8 7644 1196; B 8 8 84 1176; B 8 8 104 1176; B 8 8 124 1176; B 8 8 144 1176; B 8 8 164 1176; B 8 8 184 1176; B 8 8 204 1176; B 8 8 224 1176; B 8 8 244 1176; B 8 8 264 1176; B 8 8 284 1176; B 8 8 304 1176; B 8 8 324 1176; B 8 8 344 1176; B 8 8 364 1176; B 8 8 384 1176; B 8 8 404 1176; B 8 8 424 1176; B 8 8 444 1176; B 8 8 884 1176; B 8 8 904 1176; B 8 8 924 1176; B 8 8 944 1176; B 8 8 964 1176; B 8 8 984 1176; B 8 8 1004 1176; B 8 8 1024 1176; B 8 8 1044 1176; B 8 8 1064 1176; B 8 8 1084 1176; B 8 8 1104 1176; B 8 8 1124 1176; B 8 8 1144 1176; B 8 8 1164 1176; B 8 8 1184 1176; B 8 8 1204 1176; B 8 8 1224 1176; B 8 8 1244 1176; B 8 8 1684 1176; B 8 8 1704 1176; B 8 8 1724 1176; B 8 8 1744 1176; B 8 8 1764 1176; B 8 8 1784 1176; B 8 8 1804 1176; B 8 8 1824 1176; B 8 8 1844 1176; B 8 8 1864 1176; B 8 8 1884 1176; B 8 8 1904 1176; B 8 8 1924 1176; B 8 8 1944 1176; B 8 8 1964 1176; B 8 8 1984 1176; B 8 8 2004 1176; B 8 8 2024 1176; B 8 8 2044 1176; B 8 8 2484 1176; B 8 8 2504 1176; B 8 8 2524 1176; B 8 8 2544 1176; B 8 8 2564 1176; B 8 8 2584 1176; B 8 8 2604 1176; B 8 8 2624 1176; B 8 8 2644 1176; B 8 8 2664 1176; B 8 8 2684 1176; B 8 8 2704 1176; B 8 8 2724 1176; B 8 8 2744 1176; B 8 8 2764 1176; B 8 8 2784 1176; B 8 8 2804 1176; B 8 8 2824 1176; B 8 8 2844 1176; B 8 8 3284 1176; B 8 8 3304 1176; B 8 8 3324 1176; B 8 8 3344 1176; B 8 8 3364 1176; B 8 8 3384 1176; B 8 8 3404 1176; B 8 8 3424 1176; B 8 8 3444 1176; B 8 8 3464 1176; B 8 8 3484 1176; B 8 8 3504 1176; B 8 8 3524 1176; B 8 8 3544 1176; B 8 8 3564 1176; B 8 8 3584 1176; B 8 8 3604 1176; B 8 8 3624 1176; B 8 8 3644 1176; B 8 8 4084 1176; B 8 8 4104 1176; B 8 8 4124 1176; B 8 8 4144 1176; B 8 8 4164 1176; B 8 8 4184 1176; B 8 8 4204 1176; B 8 8 4224 1176; B 8 8 4244 1176; B 8 8 4264 1176; B 8 8 4284 1176; B 8 8 4304 1176; B 8 8 4324 1176; B 8 8 4344 1176; B 8 8 4364 1176; B 8 8 4384 1176; B 8 8 4404 1176; B 8 8 4424 1176; B 8 8 4444 1176; B 8 8 4884 1176; B 8 8 4904 1176; B 8 8 4924 1176; B 8 8 4944 1176; B 8 8 4964 1176; B 8 8 4984 1176; B 8 8 5004 1176; B 8 8 5024 1176; B 8 8 5044 1176; B 8 8 5064 1176; B 8 8 5084 1176; B 8 8 5104 1176; B 8 8 5124 1176; B 8 8 5144 1176; B 8 8 5164 1176; B 8 8 5184 1176; B 8 8 5204 1176; B 8 8 5224 1176; B 8 8 5244 1176; B 8 8 5684 1176; B 8 8 5704 1176; B 8 8 5724 1176; B 8 8 5744 1176; B 8 8 5764 1176; B 8 8 5784 1176; B 8 8 5804 1176; B 8 8 5824 1176; B 8 8 5844 1176; B 8 8 5864 1176; B 8 8 5884 1176; B 8 8 5904 1176; B 8 8 5924 1176; B 8 8 5944 1176; B 8 8 5964 1176; B 8 8 5984 1176; B 8 8 6004 1176; B 8 8 6024 1176; B 8 8 6044 1176; B 8 8 6484 1176; B 8 8 6504 1176; B 8 8 6524 1176; B 8 8 6544 1176; B 8 8 6564 1176; B 8 8 6584 1176; B 8 8 6604 1176; B 8 8 6624 1176; B 8 8 6644 1176; B 8 8 6664 1176; B 8 8 6684 1176; B 8 8 6704 1176; B 8 8 6724 1176; B 8 8 6744 1176; B 8 8 6764 1176; B 8 8 6784 1176; B 8 8 6804 1176; B 8 8 6824 1176; B 8 8 6844 1176; B 8 8 7284 1176; B 8 8 7304 1176; B 8 8 7324 1176; B 8 8 7344 1176; B 8 8 7364 1176; B 8 8 7384 1176; B 8 8 7404 1176; B 8 8 7424 1176; B 8 8 7444 1176; B 8 8 7464 1176; B 8 8 7484 1176; B 8 8 7504 1176; B 8 8 7524 1176; B 8 8 7544 1176; B 8 8 7564 1176; B 8 8 7584 1176; B 8 8 7604 1176; B 8 8 7624 1176; B 8 8 7644 1176; B 8 8 84 1156; B 8 8 104 1156; B 8 8 124 1156; B 8 8 144 1156; B 8 8 164 1156; B 8 8 184 1156; B 8 8 204 1156; B 8 8 224 1156; B 8 8 244 1156; B 8 8 264 1156; B 8 8 284 1156; B 8 8 304 1156; B 8 8 324 1156; B 8 8 344 1156; B 8 8 364 1156; B 8 8 384 1156; B 8 8 404 1156; B 8 8 424 1156; B 8 8 444 1156; B 8 8 884 1156; B 8 8 904 1156; B 8 8 924 1156; B 8 8 944 1156; B 8 8 964 1156; B 8 8 984 1156; B 8 8 1004 1156; B 8 8 1024 1156; B 8 8 1044 1156; B 8 8 1064 1156; B 8 8 1084 1156; B 8 8 1104 1156; B 8 8 1124 1156; B 8 8 1144 1156; B 8 8 1164 1156; B 8 8 1184 1156; B 8 8 1204 1156; B 8 8 1224 1156; B 8 8 1244 1156; B 8 8 1684 1156; B 8 8 1704 1156; B 8 8 1724 1156; B 8 8 1744 1156; B 8 8 1764 1156; B 8 8 1784 1156; B 8 8 1804 1156; B 8 8 1824 1156; B 8 8 1844 1156; B 8 8 1864 1156; B 8 8 1884 1156; B 8 8 1904 1156; B 8 8 1924 1156; B 8 8 1944 1156; B 8 8 1964 1156; B 8 8 1984 1156; B 8 8 2004 1156; B 8 8 2024 1156; B 8 8 2044 1156; B 8 8 2484 1156; B 8 8 2504 1156; B 8 8 2524 1156; B 8 8 2544 1156; B 8 8 2564 1156; B 8 8 2584 1156; B 8 8 2604 1156; B 8 8 2624 1156; B 8 8 2644 1156; B 8 8 2664 1156; B 8 8 2684 1156; B 8 8 2704 1156; B 8 8 2724 1156; B 8 8 2744 1156; B 8 8 2764 1156; B 8 8 2784 1156; B 8 8 2804 1156; B 8 8 2824 1156; B 8 8 2844 1156; B 8 8 3284 1156; B 8 8 3304 1156; B 8 8 3324 1156; B 8 8 3344 1156; B 8 8 3364 1156; B 8 8 3384 1156; B 8 8 3404 1156; B 8 8 3424 1156; B 8 8 3444 1156; B 8 8 3464 1156; B 8 8 3484 1156; B 8 8 3504 1156; B 8 8 3524 1156; B 8 8 3544 1156; B 8 8 3564 1156; B 8 8 3584 1156; B 8 8 3604 1156; B 8 8 3624 1156; B 8 8 3644 1156; B 8 8 4084 1156; B 8 8 4104 1156; B 8 8 4124 1156; B 8 8 4144 1156; B 8 8 4164 1156; B 8 8 4184 1156; B 8 8 4204 1156; B 8 8 4224 1156; B 8 8 4244 1156; B 8 8 4264 1156; B 8 8 4284 1156; B 8 8 4304 1156; B 8 8 4324 1156; B 8 8 4344 1156; B 8 8 4364 1156; B 8 8 4384 1156; B 8 8 4404 1156; B 8 8 4424 1156; B 8 8 4444 1156; B 8 8 4884 1156; B 8 8 4904 1156; B 8 8 4924 1156; B 8 8 4944 1156; B 8 8 4964 1156; B 8 8 4984 1156; B 8 8 5004 1156; B 8 8 5024 1156; B 8 8 5044 1156; B 8 8 5064 1156; B 8 8 5084 1156; B 8 8 5104 1156; B 8 8 5124 1156; B 8 8 5144 1156; B 8 8 5164 1156; B 8 8 5184 1156; B 8 8 5204 1156; B 8 8 5224 1156; B 8 8 5244 1156; B 8 8 5684 1156; B 8 8 5704 1156; B 8 8 5724 1156; B 8 8 5744 1156; B 8 8 5764 1156; B 8 8 5784 1156; B 8 8 5804 1156; B 8 8 5824 1156; B 8 8 5844 1156; B 8 8 5864 1156; B 8 8 5884 1156; B 8 8 5904 1156; B 8 8 5924 1156; B 8 8 5944 1156; B 8 8 5964 1156; B 8 8 5984 1156; B 8 8 6004 1156; B 8 8 6024 1156; B 8 8 6044 1156; B 8 8 6484 1156; B 8 8 6504 1156; B 8 8 6524 1156; B 8 8 6544 1156; B 8 8 6564 1156; B 8 8 6584 1156; B 8 8 6604 1156; B 8 8 6624 1156; B 8 8 6644 1156; B 8 8 6664 1156; B 8 8 6684 1156; B 8 8 6704 1156; B 8 8 6724 1156; B 8 8 6744 1156; B 8 8 6764 1156; B 8 8 6784 1156; B 8 8 6804 1156; B 8 8 6824 1156; B 8 8 6844 1156; B 8 8 7284 1156; B 8 8 7304 1156; B 8 8 7324 1156; B 8 8 7344 1156; B 8 8 7364 1156; B 8 8 7384 1156; B 8 8 7404 1156; B 8 8 7424 1156; B 8 8 7444 1156; B 8 8 7464 1156; B 8 8 7484 1156; B 8 8 7504 1156; B 8 8 7524 1156; B 8 8 7544 1156; B 8 8 7564 1156; B 8 8 7584 1156; B 8 8 7604 1156; B 8 8 7624 1156; B 8 8 7644 1156; B 8 8 84 1136; B 8 8 104 1136; B 8 8 124 1136; B 8 8 144 1136; B 8 8 164 1136; B 8 8 184 1136; B 8 8 204 1136; B 8 8 224 1136; B 8 8 244 1136; B 8 8 264 1136; B 8 8 284 1136; B 8 8 304 1136; B 8 8 324 1136; B 8 8 344 1136; B 8 8 364 1136; B 8 8 384 1136; B 8 8 404 1136; B 8 8 424 1136; B 8 8 444 1136; B 8 8 884 1136; B 8 8 904 1136; B 8 8 924 1136; B 8 8 944 1136; B 8 8 964 1136; B 8 8 984 1136; B 8 8 1004 1136; B 8 8 1024 1136; B 8 8 1044 1136; B 8 8 1064 1136; B 8 8 1084 1136; B 8 8 1104 1136; B 8 8 1124 1136; B 8 8 1144 1136; B 8 8 1164 1136; B 8 8 1184 1136; B 8 8 1204 1136; B 8 8 1224 1136; B 8 8 1244 1136; B 8 8 1684 1136; B 8 8 1704 1136; B 8 8 1724 1136; B 8 8 1744 1136; B 8 8 1764 1136; B 8 8 1784 1136; B 8 8 1804 1136; B 8 8 1824 1136; B 8 8 1844 1136; B 8 8 1864 1136; B 8 8 1884 1136; B 8 8 1904 1136; B 8 8 1924 1136; B 8 8 1944 1136; B 8 8 1964 1136; B 8 8 1984 1136; B 8 8 2004 1136; B 8 8 2024 1136; B 8 8 2044 1136; B 8 8 2484 1136; B 8 8 2504 1136; B 8 8 2524 1136; B 8 8 2544 1136; B 8 8 2564 1136; B 8 8 2584 1136; B 8 8 2604 1136; B 8 8 2624 1136; B 8 8 2644 1136; B 8 8 2664 1136; B 8 8 2684 1136; B 8 8 2704 1136; B 8 8 2724 1136; B 8 8 2744 1136; B 8 8 2764 1136; B 8 8 2784 1136; B 8 8 2804 1136; B 8 8 2824 1136; B 8 8 2844 1136; B 8 8 3284 1136; B 8 8 3304 1136; B 8 8 3324 1136; B 8 8 3344 1136; B 8 8 3364 1136; B 8 8 3384 1136; B 8 8 3404 1136; B 8 8 3424 1136; B 8 8 3444 1136; B 8 8 3464 1136; B 8 8 3484 1136; B 8 8 3504 1136; B 8 8 3524 1136; B 8 8 3544 1136; B 8 8 3564 1136; B 8 8 3584 1136; B 8 8 3604 1136; B 8 8 3624 1136; B 8 8 3644 1136; B 8 8 4084 1136; B 8 8 4104 1136; B 8 8 4124 1136; B 8 8 4144 1136; B 8 8 4164 1136; B 8 8 4184 1136; B 8 8 4204 1136; B 8 8 4224 1136; B 8 8 4244 1136; B 8 8 4264 1136; B 8 8 4284 1136; B 8 8 4304 1136; B 8 8 4324 1136; B 8 8 4344 1136; B 8 8 4364 1136; B 8 8 4384 1136; B 8 8 4404 1136; B 8 8 4424 1136; B 8 8 4444 1136; B 8 8 4884 1136; B 8 8 4904 1136; B 8 8 4924 1136; B 8 8 4944 1136; B 8 8 4964 1136; B 8 8 4984 1136; B 8 8 5004 1136; B 8 8 5024 1136; B 8 8 5044 1136; B 8 8 5064 1136; B 8 8 5084 1136; B 8 8 5104 1136; B 8 8 5124 1136; B 8 8 5144 1136; B 8 8 5164 1136; B 8 8 5184 1136; B 8 8 5204 1136; B 8 8 5224 1136; B 8 8 5244 1136; B 8 8 5684 1136; B 8 8 5704 1136; B 8 8 5724 1136; B 8 8 5744 1136; B 8 8 5764 1136; B 8 8 5784 1136; B 8 8 5804 1136; B 8 8 5824 1136; B 8 8 5844 1136; B 8 8 5864 1136; B 8 8 5884 1136; B 8 8 5904 1136; B 8 8 5924 1136; B 8 8 5944 1136; B 8 8 5964 1136; B 8 8 5984 1136; B 8 8 6004 1136; B 8 8 6024 1136; B 8 8 6044 1136; B 8 8 6484 1136; B 8 8 6504 1136; B 8 8 6524 1136; B 8 8 6544 1136; B 8 8 6564 1136; B 8 8 6584 1136; B 8 8 6604 1136; B 8 8 6624 1136; B 8 8 6644 1136; B 8 8 6664 1136; B 8 8 6684 1136; B 8 8 6704 1136; B 8 8 6724 1136; B 8 8 6744 1136; B 8 8 6764 1136; B 8 8 6784 1136; B 8 8 6804 1136; B 8 8 6824 1136; B 8 8 6844 1136; B 8 8 7284 1136; B 8 8 7304 1136; B 8 8 7324 1136; B 8 8 7344 1136; B 8 8 7364 1136; B 8 8 7384 1136; B 8 8 7404 1136; B 8 8 7424 1136; B 8 8 7444 1136; B 8 8 7464 1136; B 8 8 7484 1136; B 8 8 7504 1136; B 8 8 7524 1136; B 8 8 7544 1136; B 8 8 7564 1136; B 8 8 7584 1136; B 8 8 7604 1136; B 8 8 7624 1136; B 8 8 7644 1136; B 8 8 84 1116; B 8 8 104 1116; B 8 8 124 1116; B 8 8 144 1116; B 8 8 164 1116; B 8 8 184 1116; B 8 8 204 1116; B 8 8 224 1116; B 8 8 244 1116; B 8 8 264 1116; B 8 8 284 1116; B 8 8 304 1116; B 8 8 324 1116; B 8 8 344 1116; B 8 8 364 1116; B 8 8 384 1116; B 8 8 404 1116; B 8 8 424 1116; B 8 8 444 1116; B 8 8 884 1116; B 8 8 904 1116; B 8 8 924 1116; B 8 8 944 1116; B 8 8 964 1116; B 8 8 984 1116; B 8 8 1004 1116; B 8 8 1024 1116; B 8 8 1044 1116; B 8 8 1064 1116; B 8 8 1084 1116; B 8 8 1104 1116; B 8 8 1124 1116; B 8 8 1144 1116; B 8 8 1164 1116; B 8 8 1184 1116; B 8 8 1204 1116; B 8 8 1224 1116; B 8 8 1244 1116; B 8 8 1684 1116; B 8 8 1704 1116; B 8 8 1724 1116; B 8 8 1744 1116; B 8 8 1764 1116; B 8 8 1784 1116; B 8 8 1804 1116; B 8 8 1824 1116; B 8 8 1844 1116; B 8 8 1864 1116; B 8 8 1884 1116; B 8 8 1904 1116; B 8 8 1924 1116; B 8 8 1944 1116; B 8 8 1964 1116; B 8 8 1984 1116; B 8 8 2004 1116; B 8 8 2024 1116; B 8 8 2044 1116; B 8 8 2484 1116; B 8 8 2504 1116; B 8 8 2524 1116; B 8 8 2544 1116; B 8 8 2564 1116; B 8 8 2584 1116; B 8 8 2604 1116; B 8 8 2624 1116; B 8 8 2644 1116; B 8 8 2664 1116; B 8 8 2684 1116; B 8 8 2704 1116; B 8 8 2724 1116; B 8 8 2744 1116; B 8 8 2764 1116; B 8 8 2784 1116; B 8 8 2804 1116; B 8 8 2824 1116; B 8 8 2844 1116; B 8 8 3284 1116; B 8 8 3304 1116; B 8 8 3324 1116; B 8 8 3344 1116; B 8 8 3364 1116; B 8 8 3384 1116; B 8 8 3404 1116; B 8 8 3424 1116; B 8 8 3444 1116; B 8 8 3464 1116; B 8 8 3484 1116; B 8 8 3504 1116; B 8 8 3524 1116; B 8 8 3544 1116; B 8 8 3564 1116; B 8 8 3584 1116; B 8 8 3604 1116; B 8 8 3624 1116; B 8 8 3644 1116; B 8 8 4084 1116; B 8 8 4104 1116; B 8 8 4124 1116; B 8 8 4144 1116; B 8 8 4164 1116; B 8 8 4184 1116; B 8 8 4204 1116; B 8 8 4224 1116; B 8 8 4244 1116; B 8 8 4264 1116; B 8 8 4284 1116; B 8 8 4304 1116; B 8 8 4324 1116; B 8 8 4344 1116; B 8 8 4364 1116; B 8 8 4384 1116; B 8 8 4404 1116; B 8 8 4424 1116; B 8 8 4444 1116; B 8 8 4884 1116; B 8 8 4904 1116; B 8 8 4924 1116; B 8 8 4944 1116; B 8 8 4964 1116; B 8 8 4984 1116; B 8 8 5004 1116; B 8 8 5024 1116; B 8 8 5044 1116; B 8 8 5064 1116; B 8 8 5084 1116; B 8 8 5104 1116; B 8 8 5124 1116; B 8 8 5144 1116; B 8 8 5164 1116; B 8 8 5184 1116; B 8 8 5204 1116; B 8 8 5224 1116; B 8 8 5244 1116; B 8 8 5684 1116; B 8 8 5704 1116; B 8 8 5724 1116; B 8 8 5744 1116; B 8 8 5764 1116; B 8 8 5784 1116; B 8 8 5804 1116; B 8 8 5824 1116; B 8 8 5844 1116; B 8 8 5864 1116; B 8 8 5884 1116; B 8 8 5904 1116; B 8 8 5924 1116; B 8 8 5944 1116; B 8 8 5964 1116; B 8 8 5984 1116; B 8 8 6004 1116; B 8 8 6024 1116; B 8 8 6044 1116; B 8 8 6484 1116; B 8 8 6504 1116; B 8 8 6524 1116; B 8 8 6544 1116; B 8 8 6564 1116; B 8 8 6584 1116; B 8 8 6604 1116; B 8 8 6624 1116; B 8 8 6644 1116; B 8 8 6664 1116; B 8 8 6684 1116; B 8 8 6704 1116; B 8 8 6724 1116; B 8 8 6744 1116; B 8 8 6764 1116; B 8 8 6784 1116; B 8 8 6804 1116; B 8 8 6824 1116; B 8 8 6844 1116; B 8 8 7284 1116; B 8 8 7304 1116; B 8 8 7324 1116; B 8 8 7344 1116; B 8 8 7364 1116; B 8 8 7384 1116; B 8 8 7404 1116; B 8 8 7424 1116; B 8 8 7444 1116; B 8 8 7464 1116; B 8 8 7484 1116; B 8 8 7504 1116; B 8 8 7524 1116; B 8 8 7544 1116; B 8 8 7564 1116; B 8 8 7584 1116; B 8 8 7604 1116; B 8 8 7624 1116; B 8 8 7644 1116; B 8 8 84 1096; B 8 8 104 1096; B 8 8 124 1096; B 8 8 144 1096; B 8 8 164 1096; B 8 8 184 1096; B 8 8 204 1096; B 8 8 224 1096; B 8 8 244 1096; B 8 8 264 1096; B 8 8 284 1096; B 8 8 304 1096; B 8 8 324 1096; B 8 8 344 1096; B 8 8 364 1096; B 8 8 384 1096; B 8 8 404 1096; B 8 8 424 1096; B 8 8 444 1096; B 8 8 884 1096; B 8 8 904 1096; B 8 8 924 1096; B 8 8 944 1096; B 8 8 964 1096; B 8 8 984 1096; B 8 8 1004 1096; B 8 8 1024 1096; B 8 8 1044 1096; B 8 8 1064 1096; B 8 8 1084 1096; B 8 8 1104 1096; B 8 8 1124 1096; B 8 8 1144 1096; B 8 8 1164 1096; B 8 8 1184 1096; B 8 8 1204 1096; B 8 8 1224 1096; B 8 8 1244 1096; B 8 8 1684 1096; B 8 8 1704 1096; B 8 8 1724 1096; B 8 8 1744 1096; B 8 8 1764 1096; B 8 8 1784 1096; B 8 8 1804 1096; B 8 8 1824 1096; B 8 8 1844 1096; B 8 8 1864 1096; B 8 8 1884 1096; B 8 8 1904 1096; B 8 8 1924 1096; B 8 8 1944 1096; B 8 8 1964 1096; B 8 8 1984 1096; B 8 8 2004 1096; B 8 8 2024 1096; B 8 8 2044 1096; B 8 8 2484 1096; B 8 8 2504 1096; B 8 8 2524 1096; B 8 8 2544 1096; B 8 8 2564 1096; B 8 8 2584 1096; B 8 8 2604 1096; B 8 8 2624 1096; B 8 8 2644 1096; B 8 8 2664 1096; B 8 8 2684 1096; B 8 8 2704 1096; B 8 8 2724 1096; B 8 8 2744 1096; B 8 8 2764 1096; B 8 8 2784 1096; B 8 8 2804 1096; B 8 8 2824 1096; B 8 8 2844 1096; B 8 8 3284 1096; B 8 8 3304 1096; B 8 8 3324 1096; B 8 8 3344 1096; B 8 8 3364 1096; B 8 8 3384 1096; B 8 8 3404 1096; B 8 8 3424 1096; B 8 8 3444 1096; B 8 8 3464 1096; B 8 8 3484 1096; B 8 8 3504 1096; B 8 8 3524 1096; B 8 8 3544 1096; B 8 8 3564 1096; B 8 8 3584 1096; B 8 8 3604 1096; B 8 8 3624 1096; B 8 8 3644 1096; B 8 8 4084 1096; B 8 8 4104 1096; B 8 8 4124 1096; B 8 8 4144 1096; B 8 8 4164 1096; B 8 8 4184 1096; B 8 8 4204 1096; B 8 8 4224 1096; B 8 8 4244 1096; B 8 8 4264 1096; B 8 8 4284 1096; B 8 8 4304 1096; B 8 8 4324 1096; B 8 8 4344 1096; B 8 8 4364 1096; B 8 8 4384 1096; B 8 8 4404 1096; B 8 8 4424 1096; B 8 8 4444 1096; B 8 8 4884 1096; B 8 8 4904 1096; B 8 8 4924 1096; B 8 8 4944 1096; B 8 8 4964 1096; B 8 8 4984 1096; B 8 8 5004 1096; B 8 8 5024 1096; B 8 8 5044 1096; B 8 8 5064 1096; B 8 8 5084 1096; B 8 8 5104 1096; B 8 8 5124 1096; B 8 8 5144 1096; B 8 8 5164 1096; B 8 8 5184 1096; B 8 8 5204 1096; B 8 8 5224 1096; B 8 8 5244 1096; B 8 8 5684 1096; B 8 8 5704 1096; B 8 8 5724 1096; B 8 8 5744 1096; B 8 8 5764 1096; B 8 8 5784 1096; B 8 8 5804 1096; B 8 8 5824 1096; B 8 8 5844 1096; B 8 8 5864 1096; B 8 8 5884 1096; B 8 8 5904 1096; B 8 8 5924 1096; B 8 8 5944 1096; B 8 8 5964 1096; B 8 8 5984 1096; B 8 8 6004 1096; B 8 8 6024 1096; B 8 8 6044 1096; B 8 8 6484 1096; B 8 8 6504 1096; B 8 8 6524 1096; B 8 8 6544 1096; B 8 8 6564 1096; B 8 8 6584 1096; B 8 8 6604 1096; B 8 8 6624 1096; B 8 8 6644 1096; B 8 8 6664 1096; B 8 8 6684 1096; B 8 8 6704 1096; B 8 8 6724 1096; B 8 8 6744 1096; B 8 8 6764 1096; B 8 8 6784 1096; B 8 8 6804 1096; B 8 8 6824 1096; B 8 8 6844 1096; B 8 8 7284 1096; B 8 8 7304 1096; B 8 8 7324 1096; B 8 8 7344 1096; B 8 8 7364 1096; B 8 8 7384 1096; B 8 8 7404 1096; B 8 8 7424 1096; B 8 8 7444 1096; B 8 8 7464 1096; B 8 8 7484 1096; B 8 8 7504 1096; B 8 8 7524 1096; B 8 8 7544 1096; B 8 8 7564 1096; B 8 8 7584 1096; B 8 8 7604 1096; B 8 8 7624 1096; B 8 8 7644 1096; B 8 8 84 1076; B 8 8 104 1076; B 8 8 124 1076; B 8 8 144 1076; B 8 8 164 1076; B 8 8 184 1076; B 8 8 204 1076; B 8 8 224 1076; B 8 8 244 1076; B 8 8 264 1076; B 8 8 284 1076; B 8 8 304 1076; B 8 8 324 1076; B 8 8 344 1076; B 8 8 364 1076; B 8 8 384 1076; B 8 8 404 1076; B 8 8 424 1076; B 8 8 444 1076; B 8 8 884 1076; B 8 8 904 1076; B 8 8 924 1076; B 8 8 944 1076; B 8 8 964 1076; B 8 8 984 1076; B 8 8 1004 1076; B 8 8 1024 1076; B 8 8 1044 1076; B 8 8 1064 1076; B 8 8 1084 1076; B 8 8 1104 1076; B 8 8 1124 1076; B 8 8 1144 1076; B 8 8 1164 1076; B 8 8 1184 1076; B 8 8 1204 1076; B 8 8 1224 1076; B 8 8 1244 1076; B 8 8 1684 1076; B 8 8 1704 1076; B 8 8 1724 1076; B 8 8 1744 1076; B 8 8 1764 1076; B 8 8 1784 1076; B 8 8 1804 1076; B 8 8 1824 1076; B 8 8 1844 1076; B 8 8 1864 1076; B 8 8 1884 1076; B 8 8 1904 1076; B 8 8 1924 1076; B 8 8 1944 1076; B 8 8 1964 1076; B 8 8 1984 1076; B 8 8 2004 1076; B 8 8 2024 1076; B 8 8 2044 1076; B 8 8 2484 1076; B 8 8 2504 1076; B 8 8 2524 1076; B 8 8 2544 1076; B 8 8 2564 1076; B 8 8 2584 1076; B 8 8 2604 1076; B 8 8 2624 1076; B 8 8 2644 1076; B 8 8 2664 1076; B 8 8 2684 1076; B 8 8 2704 1076; B 8 8 2724 1076; B 8 8 2744 1076; B 8 8 2764 1076; B 8 8 2784 1076; B 8 8 2804 1076; B 8 8 2824 1076; B 8 8 2844 1076; B 8 8 3284 1076; B 8 8 3304 1076; B 8 8 3324 1076; B 8 8 3344 1076; B 8 8 3364 1076; B 8 8 3384 1076; B 8 8 3404 1076; B 8 8 3424 1076; B 8 8 3444 1076; B 8 8 3464 1076; B 8 8 3484 1076; B 8 8 3504 1076; B 8 8 3524 1076; B 8 8 3544 1076; B 8 8 3564 1076; B 8 8 3584 1076; B 8 8 3604 1076; B 8 8 3624 1076; B 8 8 3644 1076; B 8 8 4084 1076; B 8 8 4104 1076; B 8 8 4124 1076; B 8 8 4144 1076; B 8 8 4164 1076; B 8 8 4184 1076; B 8 8 4204 1076; B 8 8 4224 1076; B 8 8 4244 1076; B 8 8 4264 1076; B 8 8 4284 1076; B 8 8 4304 1076; B 8 8 4324 1076; B 8 8 4344 1076; B 8 8 4364 1076; B 8 8 4384 1076; B 8 8 4404 1076; B 8 8 4424 1076; B 8 8 4444 1076; B 8 8 4884 1076; B 8 8 4904 1076; B 8 8 4924 1076; B 8 8 4944 1076; B 8 8 4964 1076; B 8 8 4984 1076; B 8 8 5004 1076; B 8 8 5024 1076; B 8 8 5044 1076; B 8 8 5064 1076; B 8 8 5084 1076; B 8 8 5104 1076; B 8 8 5124 1076; B 8 8 5144 1076; B 8 8 5164 1076; B 8 8 5184 1076; B 8 8 5204 1076; B 8 8 5224 1076; B 8 8 5244 1076; B 8 8 5684 1076; B 8 8 5704 1076; B 8 8 5724 1076; B 8 8 5744 1076; B 8 8 5764 1076; B 8 8 5784 1076; B 8 8 5804 1076; B 8 8 5824 1076; B 8 8 5844 1076; B 8 8 5864 1076; B 8 8 5884 1076; B 8 8 5904 1076; B 8 8 5924 1076; B 8 8 5944 1076; B 8 8 5964 1076; B 8 8 5984 1076; B 8 8 6004 1076; B 8 8 6024 1076; B 8 8 6044 1076; B 8 8 6484 1076; B 8 8 6504 1076; B 8 8 6524 1076; B 8 8 6544 1076; B 8 8 6564 1076; B 8 8 6584 1076; B 8 8 6604 1076; B 8 8 6624 1076; B 8 8 6644 1076; B 8 8 6664 1076; B 8 8 6684 1076; B 8 8 6704 1076; B 8 8 6724 1076; B 8 8 6744 1076; B 8 8 6764 1076; B 8 8 6784 1076; B 8 8 6804 1076; B 8 8 6824 1076; B 8 8 6844 1076; B 8 8 7284 1076; B 8 8 7304 1076; B 8 8 7324 1076; B 8 8 7344 1076; B 8 8 7364 1076; B 8 8 7384 1076; B 8 8 7404 1076; B 8 8 7424 1076; B 8 8 7444 1076; B 8 8 7464 1076; B 8 8 7484 1076; B 8 8 7504 1076; B 8 8 7524 1076; B 8 8 7544 1076; B 8 8 7564 1076; B 8 8 7584 1076; B 8 8 7604 1076; B 8 8 7624 1076; B 8 8 7644 1076; B 8 8 84 1056; B 8 8 104 1056; B 8 8 124 1056; B 8 8 144 1056; B 8 8 164 1056; B 8 8 184 1056; B 8 8 204 1056; B 8 8 224 1056; B 8 8 244 1056; B 8 8 264 1056; B 8 8 284 1056; B 8 8 304 1056; B 8 8 324 1056; B 8 8 344 1056; B 8 8 364 1056; B 8 8 384 1056; B 8 8 404 1056; B 8 8 424 1056; B 8 8 444 1056; B 8 8 884 1056; B 8 8 904 1056; B 8 8 924 1056; B 8 8 944 1056; B 8 8 964 1056; B 8 8 984 1056; B 8 8 1004 1056; B 8 8 1024 1056; B 8 8 1044 1056; B 8 8 1064 1056; B 8 8 1084 1056; B 8 8 1104 1056; B 8 8 1124 1056; B 8 8 1144 1056; B 8 8 1164 1056; B 8 8 1184 1056; B 8 8 1204 1056; B 8 8 1224 1056; B 8 8 1244 1056; B 8 8 1684 1056; B 8 8 1704 1056; B 8 8 1724 1056; B 8 8 1744 1056; B 8 8 1764 1056; B 8 8 1784 1056; B 8 8 1804 1056; B 8 8 1824 1056; B 8 8 1844 1056; B 8 8 1864 1056; B 8 8 1884 1056; B 8 8 1904 1056; B 8 8 1924 1056; B 8 8 1944 1056; B 8 8 1964 1056; B 8 8 1984 1056; B 8 8 2004 1056; B 8 8 2024 1056; B 8 8 2044 1056; B 8 8 2484 1056; B 8 8 2504 1056; B 8 8 2524 1056; B 8 8 2544 1056; B 8 8 2564 1056; B 8 8 2584 1056; B 8 8 2604 1056; B 8 8 2624 1056; B 8 8 2644 1056; B 8 8 2664 1056; B 8 8 2684 1056; B 8 8 2704 1056; B 8 8 2724 1056; B 8 8 2744 1056; B 8 8 2764 1056; B 8 8 2784 1056; B 8 8 2804 1056; B 8 8 2824 1056; B 8 8 2844 1056; B 8 8 3284 1056; B 8 8 3304 1056; B 8 8 3324 1056; B 8 8 3344 1056; B 8 8 3364 1056; B 8 8 3384 1056; B 8 8 3404 1056; B 8 8 3424 1056; B 8 8 3444 1056; B 8 8 3464 1056; B 8 8 3484 1056; B 8 8 3504 1056; B 8 8 3524 1056; B 8 8 3544 1056; B 8 8 3564 1056; B 8 8 3584 1056; B 8 8 3604 1056; B 8 8 3624 1056; B 8 8 3644 1056; B 8 8 4084 1056; B 8 8 4104 1056; B 8 8 4124 1056; B 8 8 4144 1056; B 8 8 4164 1056; B 8 8 4184 1056; B 8 8 4204 1056; B 8 8 4224 1056; B 8 8 4244 1056; B 8 8 4264 1056; B 8 8 4284 1056; B 8 8 4304 1056; B 8 8 4324 1056; B 8 8 4344 1056; B 8 8 4364 1056; B 8 8 4384 1056; B 8 8 4404 1056; B 8 8 4424 1056; B 8 8 4444 1056; B 8 8 4884 1056; B 8 8 4904 1056; B 8 8 4924 1056; B 8 8 4944 1056; B 8 8 4964 1056; B 8 8 4984 1056; B 8 8 5004 1056; B 8 8 5024 1056; B 8 8 5044 1056; B 8 8 5064 1056; B 8 8 5084 1056; B 8 8 5104 1056; B 8 8 5124 1056; B 8 8 5144 1056; B 8 8 5164 1056; B 8 8 5184 1056; B 8 8 5204 1056; B 8 8 5224 1056; B 8 8 5244 1056; B 8 8 5684 1056; B 8 8 5704 1056; B 8 8 5724 1056; B 8 8 5744 1056; B 8 8 5764 1056; B 8 8 5784 1056; B 8 8 5804 1056; B 8 8 5824 1056; B 8 8 5844 1056; B 8 8 5864 1056; B 8 8 5884 1056; B 8 8 5904 1056; B 8 8 5924 1056; B 8 8 5944 1056; B 8 8 5964 1056; B 8 8 5984 1056; B 8 8 6004 1056; B 8 8 6024 1056; B 8 8 6044 1056; B 8 8 6484 1056; B 8 8 6504 1056; B 8 8 6524 1056; B 8 8 6544 1056; B 8 8 6564 1056; B 8 8 6584 1056; B 8 8 6604 1056; B 8 8 6624 1056; B 8 8 6644 1056; B 8 8 6664 1056; B 8 8 6684 1056; B 8 8 6704 1056; B 8 8 6724 1056; B 8 8 6744 1056; B 8 8 6764 1056; B 8 8 6784 1056; B 8 8 6804 1056; B 8 8 6824 1056; B 8 8 6844 1056; B 8 8 7284 1056; B 8 8 7304 1056; B 8 8 7324 1056; B 8 8 7344 1056; B 8 8 7364 1056; B 8 8 7384 1056; B 8 8 7404 1056; B 8 8 7424 1056; B 8 8 7444 1056; B 8 8 7464 1056; B 8 8 7484 1056; B 8 8 7504 1056; B 8 8 7524 1056; B 8 8 7544 1056; B 8 8 7564 1056; B 8 8 7584 1056; B 8 8 7604 1056; B 8 8 7624 1056; B 8 8 7644 1056; B 8 8 84 1036; B 8 8 104 1036; B 8 8 124 1036; B 8 8 144 1036; B 8 8 164 1036; B 8 8 184 1036; B 8 8 204 1036; B 8 8 224 1036; B 8 8 244 1036; B 8 8 264 1036; B 8 8 284 1036; B 8 8 304 1036; B 8 8 324 1036; B 8 8 344 1036; B 8 8 364 1036; B 8 8 384 1036; B 8 8 404 1036; B 8 8 424 1036; B 8 8 444 1036; B 8 8 884 1036; B 8 8 904 1036; B 8 8 924 1036; B 8 8 944 1036; B 8 8 964 1036; B 8 8 984 1036; B 8 8 1004 1036; B 8 8 1024 1036; B 8 8 1044 1036; B 8 8 1064 1036; B 8 8 1084 1036; B 8 8 1104 1036; B 8 8 1124 1036; B 8 8 1144 1036; B 8 8 1164 1036; B 8 8 1184 1036; B 8 8 1204 1036; B 8 8 1224 1036; B 8 8 1244 1036; B 8 8 1684 1036; B 8 8 1704 1036; B 8 8 1724 1036; B 8 8 1744 1036; B 8 8 1764 1036; B 8 8 1784 1036; B 8 8 1804 1036; B 8 8 1824 1036; B 8 8 1844 1036; B 8 8 1864 1036; B 8 8 1884 1036; B 8 8 1904 1036; B 8 8 1924 1036; B 8 8 1944 1036; B 8 8 1964 1036; B 8 8 1984 1036; B 8 8 2004 1036; B 8 8 2024 1036; B 8 8 2044 1036; B 8 8 2484 1036; B 8 8 2504 1036; B 8 8 2524 1036; B 8 8 2544 1036; B 8 8 2564 1036; B 8 8 2584 1036; B 8 8 2604 1036; B 8 8 2624 1036; B 8 8 2644 1036; B 8 8 2664 1036; B 8 8 2684 1036; B 8 8 2704 1036; B 8 8 2724 1036; B 8 8 2744 1036; B 8 8 2764 1036; B 8 8 2784 1036; B 8 8 2804 1036; B 8 8 2824 1036; B 8 8 2844 1036; B 8 8 3284 1036; B 8 8 3304 1036; B 8 8 3324 1036; B 8 8 3344 1036; B 8 8 3364 1036; B 8 8 3384 1036; B 8 8 3404 1036; B 8 8 3424 1036; B 8 8 3444 1036; B 8 8 3464 1036; B 8 8 3484 1036; B 8 8 3504 1036; B 8 8 3524 1036; B 8 8 3544 1036; B 8 8 3564 1036; B 8 8 3584 1036; B 8 8 3604 1036; B 8 8 3624 1036; B 8 8 3644 1036; B 8 8 4084 1036; B 8 8 4104 1036; B 8 8 4124 1036; B 8 8 4144 1036; B 8 8 4164 1036; B 8 8 4184 1036; B 8 8 4204 1036; B 8 8 4224 1036; B 8 8 4244 1036; B 8 8 4264 1036; B 8 8 4284 1036; B 8 8 4304 1036; B 8 8 4324 1036; B 8 8 4344 1036; B 8 8 4364 1036; B 8 8 4384 1036; B 8 8 4404 1036; B 8 8 4424 1036; B 8 8 4444 1036; B 8 8 4884 1036; B 8 8 4904 1036; B 8 8 4924 1036; B 8 8 4944 1036; B 8 8 4964 1036; B 8 8 4984 1036; B 8 8 5004 1036; B 8 8 5024 1036; B 8 8 5044 1036; B 8 8 5064 1036; B 8 8 5084 1036; B 8 8 5104 1036; B 8 8 5124 1036; B 8 8 5144 1036; B 8 8 5164 1036; B 8 8 5184 1036; B 8 8 5204 1036; B 8 8 5224 1036; B 8 8 5244 1036; B 8 8 5684 1036; B 8 8 5704 1036; B 8 8 5724 1036; B 8 8 5744 1036; B 8 8 5764 1036; B 8 8 5784 1036; B 8 8 5804 1036; B 8 8 5824 1036; B 8 8 5844 1036; B 8 8 5864 1036; B 8 8 5884 1036; B 8 8 5904 1036; B 8 8 5924 1036; B 8 8 5944 1036; B 8 8 5964 1036; B 8 8 5984 1036; B 8 8 6004 1036; B 8 8 6024 1036; B 8 8 6044 1036; B 8 8 6484 1036; B 8 8 6504 1036; B 8 8 6524 1036; B 8 8 6544 1036; B 8 8 6564 1036; B 8 8 6584 1036; B 8 8 6604 1036; B 8 8 6624 1036; B 8 8 6644 1036; B 8 8 6664 1036; B 8 8 6684 1036; B 8 8 6704 1036; B 8 8 6724 1036; B 8 8 6744 1036; B 8 8 6764 1036; B 8 8 6784 1036; B 8 8 6804 1036; B 8 8 6824 1036; B 8 8 6844 1036; B 8 8 7284 1036; B 8 8 7304 1036; B 8 8 7324 1036; B 8 8 7344 1036; B 8 8 7364 1036; B 8 8 7384 1036; B 8 8 7404 1036; B 8 8 7424 1036; B 8 8 7444 1036; B 8 8 7464 1036; B 8 8 7484 1036; B 8 8 7504 1036; B 8 8 7524 1036; B 8 8 7544 1036; B 8 8 7564 1036; B 8 8 7584 1036; B 8 8 7604 1036; B 8 8 7624 1036; B 8 8 7644 1036; B 8 8 84 1016; B 8 8 104 1016; B 8 8 124 1016; B 8 8 144 1016; B 8 8 164 1016; B 8 8 184 1016; B 8 8 204 1016; B 8 8 224 1016; B 8 8 244 1016; B 8 8 264 1016; B 8 8 284 1016; B 8 8 304 1016; B 8 8 324 1016; B 8 8 344 1016; B 8 8 364 1016; B 8 8 384 1016; B 8 8 404 1016; B 8 8 424 1016; B 8 8 444 1016; B 8 8 884 1016; B 8 8 904 1016; B 8 8 924 1016; B 8 8 944 1016; B 8 8 964 1016; B 8 8 984 1016; B 8 8 1004 1016; B 8 8 1024 1016; B 8 8 1044 1016; B 8 8 1064 1016; B 8 8 1084 1016; B 8 8 1104 1016; B 8 8 1124 1016; B 8 8 1144 1016; B 8 8 1164 1016; B 8 8 1184 1016; B 8 8 1204 1016; B 8 8 1224 1016; B 8 8 1244 1016; B 8 8 1684 1016; B 8 8 1704 1016; B 8 8 1724 1016; B 8 8 1744 1016; B 8 8 1764 1016; B 8 8 1784 1016; B 8 8 1804 1016; B 8 8 1824 1016; B 8 8 1844 1016; B 8 8 1864 1016; B 8 8 1884 1016; B 8 8 1904 1016; B 8 8 1924 1016; B 8 8 1944 1016; B 8 8 1964 1016; B 8 8 1984 1016; B 8 8 2004 1016; B 8 8 2024 1016; B 8 8 2044 1016; B 8 8 2484 1016; B 8 8 2504 1016; B 8 8 2524 1016; B 8 8 2544 1016; B 8 8 2564 1016; B 8 8 2584 1016; B 8 8 2604 1016; B 8 8 2624 1016; B 8 8 2644 1016; B 8 8 2664 1016; B 8 8 2684 1016; B 8 8 2704 1016; B 8 8 2724 1016; B 8 8 2744 1016; B 8 8 2764 1016; B 8 8 2784 1016; B 8 8 2804 1016; B 8 8 2824 1016; B 8 8 2844 1016; B 8 8 3284 1016; B 8 8 3304 1016; B 8 8 3324 1016; B 8 8 3344 1016; B 8 8 3364 1016; B 8 8 3384 1016; B 8 8 3404 1016; B 8 8 3424 1016; B 8 8 3444 1016; B 8 8 3464 1016; B 8 8 3484 1016; B 8 8 3504 1016; B 8 8 3524 1016; B 8 8 3544 1016; B 8 8 3564 1016; B 8 8 3584 1016; B 8 8 3604 1016; B 8 8 3624 1016; B 8 8 3644 1016; B 8 8 4084 1016; B 8 8 4104 1016; B 8 8 4124 1016; B 8 8 4144 1016; B 8 8 4164 1016; B 8 8 4184 1016; B 8 8 4204 1016; B 8 8 4224 1016; B 8 8 4244 1016; B 8 8 4264 1016; B 8 8 4284 1016; B 8 8 4304 1016; B 8 8 4324 1016; B 8 8 4344 1016; B 8 8 4364 1016; B 8 8 4384 1016; B 8 8 4404 1016; B 8 8 4424 1016; B 8 8 4444 1016; B 8 8 4884 1016; B 8 8 4904 1016; B 8 8 4924 1016; B 8 8 4944 1016; B 8 8 4964 1016; B 8 8 4984 1016; B 8 8 5004 1016; B 8 8 5024 1016; B 8 8 5044 1016; B 8 8 5064 1016; B 8 8 5084 1016; B 8 8 5104 1016; B 8 8 5124 1016; B 8 8 5144 1016; B 8 8 5164 1016; B 8 8 5184 1016; B 8 8 5204 1016; B 8 8 5224 1016; B 8 8 5244 1016; B 8 8 5684 1016; B 8 8 5704 1016; B 8 8 5724 1016; B 8 8 5744 1016; B 8 8 5764 1016; B 8 8 5784 1016; B 8 8 5804 1016; B 8 8 5824 1016; B 8 8 5844 1016; B 8 8 5864 1016; B 8 8 5884 1016; B 8 8 5904 1016; B 8 8 5924 1016; B 8 8 5944 1016; B 8 8 5964 1016; B 8 8 5984 1016; B 8 8 6004 1016; B 8 8 6024 1016; B 8 8 6044 1016; B 8 8 6484 1016; B 8 8 6504 1016; B 8 8 6524 1016; B 8 8 6544 1016; B 8 8 6564 1016; B 8 8 6584 1016; B 8 8 6604 1016; B 8 8 6624 1016; B 8 8 6644 1016; B 8 8 6664 1016; B 8 8 6684 1016; B 8 8 6704 1016; B 8 8 6724 1016; B 8 8 6744 1016; B 8 8 6764 1016; B 8 8 6784 1016; B 8 8 6804 1016; B 8 8 6824 1016; B 8 8 6844 1016; B 8 8 7284 1016; B 8 8 7304 1016; B 8 8 7324 1016; B 8 8 7344 1016; B 8 8 7364 1016; B 8 8 7384 1016; B 8 8 7404 1016; B 8 8 7424 1016; B 8 8 7444 1016; B 8 8 7464 1016; B 8 8 7484 1016; B 8 8 7504 1016; B 8 8 7524 1016; B 8 8 7544 1016; B 8 8 7564 1016; B 8 8 7584 1016; B 8 8 7604 1016; B 8 8 7624 1016; B 8 8 7644 1016; B 8 8 84 996; B 8 8 104 996; B 8 8 124 996; B 8 8 144 996; B 8 8 164 996; B 8 8 184 996; B 8 8 204 996; B 8 8 224 996; B 8 8 244 996; B 8 8 264 996; B 8 8 284 996; B 8 8 304 996; B 8 8 324 996; B 8 8 344 996; B 8 8 364 996; B 8 8 384 996; B 8 8 404 996; B 8 8 424 996; B 8 8 444 996; B 8 8 884 996; B 8 8 904 996; B 8 8 924 996; B 8 8 944 996; B 8 8 964 996; B 8 8 984 996; B 8 8 1004 996; B 8 8 1024 996; B 8 8 1044 996; B 8 8 1064 996; B 8 8 1084 996; B 8 8 1104 996; B 8 8 1124 996; B 8 8 1144 996; B 8 8 1164 996; B 8 8 1184 996; B 8 8 1204 996; B 8 8 1224 996; B 8 8 1244 996; B 8 8 1684 996; B 8 8 1704 996; B 8 8 1724 996; B 8 8 1744 996; B 8 8 1764 996; B 8 8 1784 996; B 8 8 1804 996; B 8 8 1824 996; B 8 8 1844 996; B 8 8 1864 996; B 8 8 1884 996; B 8 8 1904 996; B 8 8 1924 996; B 8 8 1944 996; B 8 8 1964 996; B 8 8 1984 996; B 8 8 2004 996; B 8 8 2024 996; B 8 8 2044 996; B 8 8 2484 996; B 8 8 2504 996; B 8 8 2524 996; B 8 8 2544 996; B 8 8 2564 996; B 8 8 2584 996; B 8 8 2604 996; B 8 8 2624 996; B 8 8 2644 996; B 8 8 2664 996; B 8 8 2684 996; B 8 8 2704 996; B 8 8 2724 996; B 8 8 2744 996; B 8 8 2764 996; B 8 8 2784 996; B 8 8 2804 996; B 8 8 2824 996; B 8 8 2844 996; B 8 8 3284 996; B 8 8 3304 996; B 8 8 3324 996; B 8 8 3344 996; B 8 8 3364 996; B 8 8 3384 996; B 8 8 3404 996; B 8 8 3424 996; B 8 8 3444 996; B 8 8 3464 996; B 8 8 3484 996; B 8 8 3504 996; B 8 8 3524 996; B 8 8 3544 996; B 8 8 3564 996; B 8 8 3584 996; B 8 8 3604 996; B 8 8 3624 996; B 8 8 3644 996; B 8 8 4084 996; B 8 8 4104 996; B 8 8 4124 996; B 8 8 4144 996; B 8 8 4164 996; B 8 8 4184 996; B 8 8 4204 996; B 8 8 4224 996; B 8 8 4244 996; B 8 8 4264 996; B 8 8 4284 996; B 8 8 4304 996; B 8 8 4324 996; B 8 8 4344 996; B 8 8 4364 996; B 8 8 4384 996; B 8 8 4404 996; B 8 8 4424 996; B 8 8 4444 996; B 8 8 4884 996; B 8 8 4904 996; B 8 8 4924 996; B 8 8 4944 996; B 8 8 4964 996; B 8 8 4984 996; B 8 8 5004 996; B 8 8 5024 996; B 8 8 5044 996; B 8 8 5064 996; B 8 8 5084 996; B 8 8 5104 996; B 8 8 5124 996; B 8 8 5144 996; B 8 8 5164 996; B 8 8 5184 996; B 8 8 5204 996; B 8 8 5224 996; B 8 8 5244 996; B 8 8 5684 996; B 8 8 5704 996; B 8 8 5724 996; B 8 8 5744 996; B 8 8 5764 996; B 8 8 5784 996; B 8 8 5804 996; B 8 8 5824 996; B 8 8 5844 996; B 8 8 5864 996; B 8 8 5884 996; B 8 8 5904 996; B 8 8 5924 996; B 8 8 5944 996; B 8 8 5964 996; B 8 8 5984 996; B 8 8 6004 996; B 8 8 6024 996; B 8 8 6044 996; B 8 8 6484 996; B 8 8 6504 996; B 8 8 6524 996; B 8 8 6544 996; B 8 8 6564 996; B 8 8 6584 996; B 8 8 6604 996; B 8 8 6624 996; B 8 8 6644 996; B 8 8 6664 996; B 8 8 6684 996; B 8 8 6704 996; B 8 8 6724 996; B 8 8 6744 996; B 8 8 6764 996; B 8 8 6784 996; B 8 8 6804 996; B 8 8 6824 996; B 8 8 6844 996; B 8 8 7284 996; B 8 8 7304 996; B 8 8 7324 996; B 8 8 7344 996; B 8 8 7364 996; B 8 8 7384 996; B 8 8 7404 996; B 8 8 7424 996; B 8 8 7444 996; B 8 8 7464 996; B 8 8 7484 996; B 8 8 7504 996; B 8 8 7524 996; B 8 8 7544 996; B 8 8 7564 996; B 8 8 7584 996; B 8 8 7604 996; B 8 8 7624 996; B 8 8 7644 996; B 8 8 84 976; B 8 8 104 976; B 8 8 124 976; B 8 8 144 976; B 8 8 164 976; B 8 8 184 976; B 8 8 204 976; B 8 8 224 976; B 8 8 244 976; B 8 8 264 976; B 8 8 284 976; B 8 8 304 976; B 8 8 324 976; B 8 8 344 976; B 8 8 364 976; B 8 8 384 976; B 8 8 404 976; B 8 8 424 976; B 8 8 444 976; B 8 8 884 976; B 8 8 904 976; B 8 8 924 976; B 8 8 944 976; B 8 8 964 976; B 8 8 984 976; B 8 8 1004 976; B 8 8 1024 976; B 8 8 1044 976; B 8 8 1064 976; B 8 8 1084 976; B 8 8 1104 976; B 8 8 1124 976; B 8 8 1144 976; B 8 8 1164 976; B 8 8 1184 976; B 8 8 1204 976; B 8 8 1224 976; B 8 8 1244 976; B 8 8 1684 976; B 8 8 1704 976; B 8 8 1724 976; B 8 8 1744 976; B 8 8 1764 976; B 8 8 1784 976; B 8 8 1804 976; B 8 8 1824 976; B 8 8 1844 976; B 8 8 1864 976; B 8 8 1884 976; B 8 8 1904 976; B 8 8 1924 976; B 8 8 1944 976; B 8 8 1964 976; B 8 8 1984 976; B 8 8 2004 976; B 8 8 2024 976; B 8 8 2044 976; B 8 8 2484 976; B 8 8 2504 976; B 8 8 2524 976; B 8 8 2544 976; B 8 8 2564 976; B 8 8 2584 976; B 8 8 2604 976; B 8 8 2624 976; B 8 8 2644 976; B 8 8 2664 976; B 8 8 2684 976; B 8 8 2704 976; B 8 8 2724 976; B 8 8 2744 976; B 8 8 2764 976; B 8 8 2784 976; B 8 8 2804 976; B 8 8 2824 976; B 8 8 2844 976; B 8 8 3284 976; B 8 8 3304 976; B 8 8 3324 976; B 8 8 3344 976; B 8 8 3364 976; B 8 8 3384 976; B 8 8 3404 976; B 8 8 3424 976; B 8 8 3444 976; B 8 8 3464 976; B 8 8 3484 976; B 8 8 3504 976; B 8 8 3524 976; B 8 8 3544 976; B 8 8 3564 976; B 8 8 3584 976; B 8 8 3604 976; B 8 8 3624 976; B 8 8 3644 976; B 8 8 4084 976; B 8 8 4104 976; B 8 8 4124 976; B 8 8 4144 976; B 8 8 4164 976; B 8 8 4184 976; B 8 8 4204 976; B 8 8 4224 976; B 8 8 4244 976; B 8 8 4264 976; B 8 8 4284 976; B 8 8 4304 976; B 8 8 4324 976; B 8 8 4344 976; B 8 8 4364 976; B 8 8 4384 976; B 8 8 4404 976; B 8 8 4424 976; B 8 8 4444 976; B 8 8 4884 976; B 8 8 4904 976; B 8 8 4924 976; B 8 8 4944 976; B 8 8 4964 976; B 8 8 4984 976; B 8 8 5004 976; B 8 8 5024 976; B 8 8 5044 976; B 8 8 5064 976; B 8 8 5084 976; B 8 8 5104 976; B 8 8 5124 976; B 8 8 5144 976; B 8 8 5164 976; B 8 8 5184 976; B 8 8 5204 976; B 8 8 5224 976; B 8 8 5244 976; B 8 8 5684 976; B 8 8 5704 976; B 8 8 5724 976; B 8 8 5744 976; B 8 8 5764 976; B 8 8 5784 976; B 8 8 5804 976; B 8 8 5824 976; B 8 8 5844 976; B 8 8 5864 976; B 8 8 5884 976; B 8 8 5904 976; B 8 8 5924 976; B 8 8 5944 976; B 8 8 5964 976; B 8 8 5984 976; B 8 8 6004 976; B 8 8 6024 976; B 8 8 6044 976; B 8 8 6484 976; B 8 8 6504 976; B 8 8 6524 976; B 8 8 6544 976; B 8 8 6564 976; B 8 8 6584 976; B 8 8 6604 976; B 8 8 6624 976; B 8 8 6644 976; B 8 8 6664 976; B 8 8 6684 976; B 8 8 6704 976; B 8 8 6724 976; B 8 8 6744 976; B 8 8 6764 976; B 8 8 6784 976; B 8 8 6804 976; B 8 8 6824 976; B 8 8 6844 976; B 8 8 7284 976; B 8 8 7304 976; B 8 8 7324 976; B 8 8 7344 976; B 8 8 7364 976; B 8 8 7384 976; B 8 8 7404 976; B 8 8 7424 976; B 8 8 7444 976; B 8 8 7464 976; B 8 8 7484 976; B 8 8 7504 976; B 8 8 7524 976; B 8 8 7544 976; B 8 8 7564 976; B 8 8 7584 976; B 8 8 7604 976; B 8 8 7624 976; B 8 8 7644 976; B 8 8 84 956; B 8 8 104 956; B 8 8 124 956; B 8 8 144 956; B 8 8 164 956; B 8 8 184 956; B 8 8 204 956; B 8 8 224 956; B 8 8 244 956; B 8 8 264 956; B 8 8 284 956; B 8 8 304 956; B 8 8 324 956; B 8 8 344 956; B 8 8 364 956; B 8 8 384 956; B 8 8 404 956; B 8 8 424 956; B 8 8 444 956; B 8 8 884 956; B 8 8 904 956; B 8 8 924 956; B 8 8 944 956; B 8 8 964 956; B 8 8 984 956; B 8 8 1004 956; B 8 8 1024 956; B 8 8 1044 956; B 8 8 1064 956; B 8 8 1084 956; B 8 8 1104 956; B 8 8 1124 956; B 8 8 1144 956; B 8 8 1164 956; B 8 8 1184 956; B 8 8 1204 956; B 8 8 1224 956; B 8 8 1244 956; B 8 8 1684 956; B 8 8 1704 956; B 8 8 1724 956; B 8 8 1744 956; B 8 8 1764 956; B 8 8 1784 956; B 8 8 1804 956; B 8 8 1824 956; B 8 8 1844 956; B 8 8 1864 956; B 8 8 1884 956; B 8 8 1904 956; B 8 8 1924 956; B 8 8 1944 956; B 8 8 1964 956; B 8 8 1984 956; B 8 8 2004 956; B 8 8 2024 956; B 8 8 2044 956; B 8 8 2484 956; B 8 8 2504 956; B 8 8 2524 956; B 8 8 2544 956; B 8 8 2564 956; B 8 8 2584 956; B 8 8 2604 956; B 8 8 2624 956; B 8 8 2644 956; B 8 8 2664 956; B 8 8 2684 956; B 8 8 2704 956; B 8 8 2724 956; B 8 8 2744 956; B 8 8 2764 956; B 8 8 2784 956; B 8 8 2804 956; B 8 8 2824 956; B 8 8 2844 956; B 8 8 3284 956; B 8 8 3304 956; B 8 8 3324 956; B 8 8 3344 956; B 8 8 3364 956; B 8 8 3384 956; B 8 8 3404 956; B 8 8 3424 956; B 8 8 3444 956; B 8 8 3464 956; B 8 8 3484 956; B 8 8 3504 956; B 8 8 3524 956; B 8 8 3544 956; B 8 8 3564 956; B 8 8 3584 956; B 8 8 3604 956; B 8 8 3624 956; B 8 8 3644 956; B 8 8 4084 956; B 8 8 4104 956; B 8 8 4124 956; B 8 8 4144 956; B 8 8 4164 956; B 8 8 4184 956; B 8 8 4204 956; B 8 8 4224 956; B 8 8 4244 956; B 8 8 4264 956; B 8 8 4284 956; B 8 8 4304 956; B 8 8 4324 956; B 8 8 4344 956; B 8 8 4364 956; B 8 8 4384 956; B 8 8 4404 956; B 8 8 4424 956; B 8 8 4444 956; B 8 8 4884 956; B 8 8 4904 956; B 8 8 4924 956; B 8 8 4944 956; B 8 8 4964 956; B 8 8 4984 956; B 8 8 5004 956; B 8 8 5024 956; B 8 8 5044 956; B 8 8 5064 956; B 8 8 5084 956; B 8 8 5104 956; B 8 8 5124 956; B 8 8 5144 956; B 8 8 5164 956; B 8 8 5184 956; B 8 8 5204 956; B 8 8 5224 956; B 8 8 5244 956; B 8 8 5684 956; B 8 8 5704 956; B 8 8 5724 956; B 8 8 5744 956; B 8 8 5764 956; B 8 8 5784 956; B 8 8 5804 956; B 8 8 5824 956; B 8 8 5844 956; B 8 8 5864 956; B 8 8 5884 956; B 8 8 5904 956; B 8 8 5924 956; B 8 8 5944 956; B 8 8 5964 956; B 8 8 5984 956; B 8 8 6004 956; B 8 8 6024 956; B 8 8 6044 956; B 8 8 6484 956; B 8 8 6504 956; B 8 8 6524 956; B 8 8 6544 956; B 8 8 6564 956; B 8 8 6584 956; B 8 8 6604 956; B 8 8 6624 956; B 8 8 6644 956; B 8 8 6664 956; B 8 8 6684 956; B 8 8 6704 956; B 8 8 6724 956; B 8 8 6744 956; B 8 8 6764 956; B 8 8 6784 956; B 8 8 6804 956; B 8 8 6824 956; B 8 8 6844 956; B 8 8 7284 956; B 8 8 7304 956; B 8 8 7324 956; B 8 8 7344 956; B 8 8 7364 956; B 8 8 7384 956; B 8 8 7404 956; B 8 8 7424 956; B 8 8 7444 956; B 8 8 7464 956; B 8 8 7484 956; B 8 8 7504 956; B 8 8 7524 956; B 8 8 7544 956; B 8 8 7564 956; B 8 8 7584 956; B 8 8 7604 956; B 8 8 7624 956; B 8 8 7644 956; B 8 8 84 936; B 8 8 104 936; B 8 8 124 936; B 8 8 144 936; B 8 8 164 936; B 8 8 184 936; B 8 8 204 936; B 8 8 224 936; B 8 8 244 936; B 8 8 264 936; B 8 8 284 936; B 8 8 304 936; B 8 8 324 936; B 8 8 344 936; B 8 8 364 936; B 8 8 384 936; B 8 8 404 936; B 8 8 424 936; B 8 8 444 936; B 8 8 884 936; B 8 8 904 936; B 8 8 924 936; B 8 8 944 936; B 8 8 964 936; B 8 8 984 936; B 8 8 1004 936; B 8 8 1024 936; B 8 8 1044 936; B 8 8 1064 936; B 8 8 1084 936; B 8 8 1104 936; B 8 8 1124 936; B 8 8 1144 936; B 8 8 1164 936; B 8 8 1184 936; B 8 8 1204 936; B 8 8 1224 936; B 8 8 1244 936; B 8 8 1684 936; B 8 8 1704 936; B 8 8 1724 936; B 8 8 1744 936; B 8 8 1764 936; B 8 8 1784 936; B 8 8 1804 936; B 8 8 1824 936; B 8 8 1844 936; B 8 8 1864 936; B 8 8 1884 936; B 8 8 1904 936; B 8 8 1924 936; B 8 8 1944 936; B 8 8 1964 936; B 8 8 1984 936; B 8 8 2004 936; B 8 8 2024 936; B 8 8 2044 936; B 8 8 2484 936; B 8 8 2504 936; B 8 8 2524 936; B 8 8 2544 936; B 8 8 2564 936; B 8 8 2584 936; B 8 8 2604 936; B 8 8 2624 936; B 8 8 2644 936; B 8 8 2664 936; B 8 8 2684 936; B 8 8 2704 936; B 8 8 2724 936; B 8 8 2744 936; B 8 8 2764 936; B 8 8 2784 936; B 8 8 2804 936; B 8 8 2824 936; B 8 8 2844 936; B 8 8 3284 936; B 8 8 3304 936; B 8 8 3324 936; B 8 8 3344 936; B 8 8 3364 936; B 8 8 3384 936; B 8 8 3404 936; B 8 8 3424 936; B 8 8 3444 936; B 8 8 3464 936; B 8 8 3484 936; B 8 8 3504 936; B 8 8 3524 936; B 8 8 3544 936; B 8 8 3564 936; B 8 8 3584 936; B 8 8 3604 936; B 8 8 3624 936; B 8 8 3644 936; B 8 8 4084 936; B 8 8 4104 936; B 8 8 4124 936; B 8 8 4144 936; B 8 8 4164 936; B 8 8 4184 936; B 8 8 4204 936; B 8 8 4224 936; B 8 8 4244 936; B 8 8 4264 936; B 8 8 4284 936; B 8 8 4304 936; B 8 8 4324 936; B 8 8 4344 936; B 8 8 4364 936; B 8 8 4384 936; B 8 8 4404 936; B 8 8 4424 936; B 8 8 4444 936; B 8 8 4884 936; B 8 8 4904 936; B 8 8 4924 936; B 8 8 4944 936; B 8 8 4964 936; B 8 8 4984 936; B 8 8 5004 936; B 8 8 5024 936; B 8 8 5044 936; B 8 8 5064 936; B 8 8 5084 936; B 8 8 5104 936; B 8 8 5124 936; B 8 8 5144 936; B 8 8 5164 936; B 8 8 5184 936; B 8 8 5204 936; B 8 8 5224 936; B 8 8 5244 936; B 8 8 5684 936; B 8 8 5704 936; B 8 8 5724 936; B 8 8 5744 936; B 8 8 5764 936; B 8 8 5784 936; B 8 8 5804 936; B 8 8 5824 936; B 8 8 5844 936; B 8 8 5864 936; B 8 8 5884 936; B 8 8 5904 936; B 8 8 5924 936; B 8 8 5944 936; B 8 8 5964 936; B 8 8 5984 936; B 8 8 6004 936; B 8 8 6024 936; B 8 8 6044 936; B 8 8 6484 936; B 8 8 6504 936; B 8 8 6524 936; B 8 8 6544 936; B 8 8 6564 936; B 8 8 6584 936; B 8 8 6604 936; B 8 8 6624 936; B 8 8 6644 936; B 8 8 6664 936; B 8 8 6684 936; B 8 8 6704 936; B 8 8 6724 936; B 8 8 6744 936; B 8 8 6764 936; B 8 8 6784 936; B 8 8 6804 936; B 8 8 6824 936; B 8 8 6844 936; B 8 8 7284 936; B 8 8 7304 936; B 8 8 7324 936; B 8 8 7344 936; B 8 8 7364 936; B 8 8 7384 936; B 8 8 7404 936; B 8 8 7424 936; B 8 8 7444 936; B 8 8 7464 936; B 8 8 7484 936; B 8 8 7504 936; B 8 8 7524 936; B 8 8 7544 936; B 8 8 7564 936; B 8 8 7584 936; B 8 8 7604 936; B 8 8 7624 936; B 8 8 7644 936; B 8 8 84 916; B 8 8 104 916; B 8 8 124 916; B 8 8 144 916; B 8 8 164 916; B 8 8 184 916; B 8 8 204 916; B 8 8 224 916; B 8 8 244 916; B 8 8 264 916; B 8 8 284 916; B 8 8 304 916; B 8 8 324 916; B 8 8 344 916; B 8 8 364 916; B 8 8 384 916; B 8 8 404 916; B 8 8 424 916; B 8 8 444 916; B 8 8 884 916; B 8 8 904 916; B 8 8 924 916; B 8 8 944 916; B 8 8 964 916; B 8 8 984 916; B 8 8 1004 916; B 8 8 1024 916; B 8 8 1044 916; B 8 8 1064 916; B 8 8 1084 916; B 8 8 1104 916; B 8 8 1124 916; B 8 8 1144 916; B 8 8 1164 916; B 8 8 1184 916; B 8 8 1204 916; B 8 8 1224 916; B 8 8 1244 916; B 8 8 1684 916; B 8 8 1704 916; B 8 8 1724 916; B 8 8 1744 916; B 8 8 1764 916; B 8 8 1784 916; B 8 8 1804 916; B 8 8 1824 916; B 8 8 1844 916; B 8 8 1864 916; B 8 8 1884 916; B 8 8 1904 916; B 8 8 1924 916; B 8 8 1944 916; B 8 8 1964 916; B 8 8 1984 916; B 8 8 2004 916; B 8 8 2024 916; B 8 8 2044 916; B 8 8 2484 916; B 8 8 2504 916; B 8 8 2524 916; B 8 8 2544 916; B 8 8 2564 916; B 8 8 2584 916; B 8 8 2604 916; B 8 8 2624 916; B 8 8 2644 916; B 8 8 2664 916; B 8 8 2684 916; B 8 8 2704 916; B 8 8 2724 916; B 8 8 2744 916; B 8 8 2764 916; B 8 8 2784 916; B 8 8 2804 916; B 8 8 2824 916; B 8 8 2844 916; B 8 8 3284 916; B 8 8 3304 916; B 8 8 3324 916; B 8 8 3344 916; B 8 8 3364 916; B 8 8 3384 916; B 8 8 3404 916; B 8 8 3424 916; B 8 8 3444 916; B 8 8 3464 916; B 8 8 3484 916; B 8 8 3504 916; B 8 8 3524 916; B 8 8 3544 916; B 8 8 3564 916; B 8 8 3584 916; B 8 8 3604 916; B 8 8 3624 916; B 8 8 3644 916; B 8 8 4084 916; B 8 8 4104 916; B 8 8 4124 916; B 8 8 4144 916; B 8 8 4164 916; B 8 8 4184 916; B 8 8 4204 916; B 8 8 4224 916; B 8 8 4244 916; B 8 8 4264 916; B 8 8 4284 916; B 8 8 4304 916; B 8 8 4324 916; B 8 8 4344 916; B 8 8 4364 916; B 8 8 4384 916; B 8 8 4404 916; B 8 8 4424 916; B 8 8 4444 916; B 8 8 4884 916; B 8 8 4904 916; B 8 8 4924 916; B 8 8 4944 916; B 8 8 4964 916; B 8 8 4984 916; B 8 8 5004 916; B 8 8 5024 916; B 8 8 5044 916; B 8 8 5064 916; B 8 8 5084 916; B 8 8 5104 916; B 8 8 5124 916; B 8 8 5144 916; B 8 8 5164 916; B 8 8 5184 916; B 8 8 5204 916; B 8 8 5224 916; B 8 8 5244 916; B 8 8 5684 916; B 8 8 5704 916; B 8 8 5724 916; B 8 8 5744 916; B 8 8 5764 916; B 8 8 5784 916; B 8 8 5804 916; B 8 8 5824 916; B 8 8 5844 916; B 8 8 5864 916; B 8 8 5884 916; B 8 8 5904 916; B 8 8 5924 916; B 8 8 5944 916; B 8 8 5964 916; B 8 8 5984 916; B 8 8 6004 916; B 8 8 6024 916; B 8 8 6044 916; B 8 8 6484 916; B 8 8 6504 916; B 8 8 6524 916; B 8 8 6544 916; B 8 8 6564 916; B 8 8 6584 916; B 8 8 6604 916; B 8 8 6624 916; B 8 8 6644 916; B 8 8 6664 916; B 8 8 6684 916; B 8 8 6704 916; B 8 8 6724 916; B 8 8 6744 916; B 8 8 6764 916; B 8 8 6784 916; B 8 8 6804 916; B 8 8 6824 916; B 8 8 6844 916; B 8 8 7284 916; B 8 8 7304 916; B 8 8 7324 916; B 8 8 7344 916; B 8 8 7364 916; B 8 8 7384 916; B 8 8 7404 916; B 8 8 7424 916; B 8 8 7444 916; B 8 8 7464 916; B 8 8 7484 916; B 8 8 7504 916; B 8 8 7524 916; B 8 8 7544 916; B 8 8 7564 916; B 8 8 7584 916; B 8 8 7604 916; B 8 8 7624 916; B 8 8 7644 916; B 8 8 84 896; B 8 8 104 896; B 8 8 124 896; B 8 8 144 896; B 8 8 164 896; B 8 8 184 896; B 8 8 204 896; B 8 8 224 896; B 8 8 244 896; B 8 8 264 896; B 8 8 284 896; B 8 8 304 896; B 8 8 324 896; B 8 8 344 896; B 8 8 364 896; B 8 8 384 896; B 8 8 404 896; B 8 8 424 896; B 8 8 444 896; B 8 8 884 896; B 8 8 904 896; B 8 8 924 896; B 8 8 944 896; B 8 8 964 896; B 8 8 984 896; B 8 8 1004 896; B 8 8 1024 896; B 8 8 1044 896; B 8 8 1064 896; B 8 8 1084 896; B 8 8 1104 896; B 8 8 1124 896; B 8 8 1144 896; B 8 8 1164 896; B 8 8 1184 896; B 8 8 1204 896; B 8 8 1224 896; B 8 8 1244 896; B 8 8 1684 896; B 8 8 1704 896; B 8 8 1724 896; B 8 8 1744 896; B 8 8 1764 896; B 8 8 1784 896; B 8 8 1804 896; B 8 8 1824 896; B 8 8 1844 896; B 8 8 1864 896; B 8 8 1884 896; B 8 8 1904 896; B 8 8 1924 896; B 8 8 1944 896; B 8 8 1964 896; B 8 8 1984 896; B 8 8 2004 896; B 8 8 2024 896; B 8 8 2044 896; B 8 8 2484 896; B 8 8 2504 896; B 8 8 2524 896; B 8 8 2544 896; B 8 8 2564 896; B 8 8 2584 896; B 8 8 2604 896; B 8 8 2624 896; B 8 8 2644 896; B 8 8 2664 896; B 8 8 2684 896; B 8 8 2704 896; B 8 8 2724 896; B 8 8 2744 896; B 8 8 2764 896; B 8 8 2784 896; B 8 8 2804 896; B 8 8 2824 896; B 8 8 2844 896; B 8 8 3284 896; B 8 8 3304 896; B 8 8 3324 896; B 8 8 3344 896; B 8 8 3364 896; B 8 8 3384 896; B 8 8 3404 896; B 8 8 3424 896; B 8 8 3444 896; B 8 8 3464 896; B 8 8 3484 896; B 8 8 3504 896; B 8 8 3524 896; B 8 8 3544 896; B 8 8 3564 896; B 8 8 3584 896; B 8 8 3604 896; B 8 8 3624 896; B 8 8 3644 896; B 8 8 4084 896; B 8 8 4104 896; B 8 8 4124 896; B 8 8 4144 896; B 8 8 4164 896; B 8 8 4184 896; B 8 8 4204 896; B 8 8 4224 896; B 8 8 4244 896; B 8 8 4264 896; B 8 8 4284 896; B 8 8 4304 896; B 8 8 4324 896; B 8 8 4344 896; B 8 8 4364 896; B 8 8 4384 896; B 8 8 4404 896; B 8 8 4424 896; B 8 8 4444 896; B 8 8 4884 896; B 8 8 4904 896; B 8 8 4924 896; B 8 8 4944 896; B 8 8 4964 896; B 8 8 4984 896; B 8 8 5004 896; B 8 8 5024 896; B 8 8 5044 896; B 8 8 5064 896; B 8 8 5084 896; B 8 8 5104 896; B 8 8 5124 896; B 8 8 5144 896; B 8 8 5164 896; B 8 8 5184 896; B 8 8 5204 896; B 8 8 5224 896; B 8 8 5244 896; B 8 8 5684 896; B 8 8 5704 896; B 8 8 5724 896; B 8 8 5744 896; B 8 8 5764 896; B 8 8 5784 896; B 8 8 5804 896; B 8 8 5824 896; B 8 8 5844 896; B 8 8 5864 896; B 8 8 5884 896; B 8 8 5904 896; B 8 8 5924 896; B 8 8 5944 896; B 8 8 5964 896; B 8 8 5984 896; B 8 8 6004 896; B 8 8 6024 896; B 8 8 6044 896; B 8 8 6484 896; B 8 8 6504 896; B 8 8 6524 896; B 8 8 6544 896; B 8 8 6564 896; B 8 8 6584 896; B 8 8 6604 896; B 8 8 6624 896; B 8 8 6644 896; B 8 8 6664 896; B 8 8 6684 896; B 8 8 6704 896; B 8 8 6724 896; B 8 8 6744 896; B 8 8 6764 896; B 8 8 6784 896; B 8 8 6804 896; B 8 8 6824 896; B 8 8 6844 896; B 8 8 7284 896; B 8 8 7304 896; B 8 8 7324 896; B 8 8 7344 896; B 8 8 7364 896; B 8 8 7384 896; B 8 8 7404 896; B 8 8 7424 896; B 8 8 7444 896; B 8 8 7464 896; B 8 8 7484 896; B 8 8 7504 896; B 8 8 7524 896; B 8 8 7544 896; B 8 8 7564 896; B 8 8 7584 896; B 8 8 7604 896; B 8 8 7624 896; B 8 8 7644 896; B 8 8 84 876; B 8 8 104 876; B 8 8 124 876; B 8 8 144 876; B 8 8 164 876; B 8 8 184 876; B 8 8 204 876; B 8 8 224 876; B 8 8 244 876; B 8 8 264 876; B 8 8 284 876; B 8 8 304 876; B 8 8 324 876; B 8 8 344 876; B 8 8 364 876; B 8 8 384 876; B 8 8 404 876; B 8 8 424 876; B 8 8 444 876; B 8 8 884 876; B 8 8 904 876; B 8 8 924 876; B 8 8 944 876; B 8 8 964 876; B 8 8 984 876; B 8 8 1004 876; B 8 8 1024 876; B 8 8 1044 876; B 8 8 1064 876; B 8 8 1084 876; B 8 8 1104 876; B 8 8 1124 876; B 8 8 1144 876; B 8 8 1164 876; B 8 8 1184 876; B 8 8 1204 876; B 8 8 1224 876; B 8 8 1244 876; B 8 8 1684 876; B 8 8 1704 876; B 8 8 1724 876; B 8 8 1744 876; B 8 8 1764 876; B 8 8 1784 876; B 8 8 1804 876; B 8 8 1824 876; B 8 8 1844 876; B 8 8 1864 876; B 8 8 1884 876; B 8 8 1904 876; B 8 8 1924 876; B 8 8 1944 876; B 8 8 1964 876; B 8 8 1984 876; B 8 8 2004 876; B 8 8 2024 876; B 8 8 2044 876; B 8 8 2484 876; B 8 8 2504 876; B 8 8 2524 876; B 8 8 2544 876; B 8 8 2564 876; B 8 8 2584 876; B 8 8 2604 876; B 8 8 2624 876; B 8 8 2644 876; B 8 8 2664 876; B 8 8 2684 876; B 8 8 2704 876; B 8 8 2724 876; B 8 8 2744 876; B 8 8 2764 876; B 8 8 2784 876; B 8 8 2804 876; B 8 8 2824 876; B 8 8 2844 876; B 8 8 3284 876; B 8 8 3304 876; B 8 8 3324 876; B 8 8 3344 876; B 8 8 3364 876; B 8 8 3384 876; B 8 8 3404 876; B 8 8 3424 876; B 8 8 3444 876; B 8 8 3464 876; B 8 8 3484 876; B 8 8 3504 876; B 8 8 3524 876; B 8 8 3544 876; B 8 8 3564 876; B 8 8 3584 876; B 8 8 3604 876; B 8 8 3624 876; B 8 8 3644 876; B 8 8 4084 876; B 8 8 4104 876; B 8 8 4124 876; B 8 8 4144 876; B 8 8 4164 876; B 8 8 4184 876; B 8 8 4204 876; B 8 8 4224 876; B 8 8 4244 876; B 8 8 4264 876; B 8 8 4284 876; B 8 8 4304 876; B 8 8 4324 876; B 8 8 4344 876; B 8 8 4364 876; B 8 8 4384 876; B 8 8 4404 876; B 8 8 4424 876; B 8 8 4444 876; B 8 8 4884 876; B 8 8 4904 876; B 8 8 4924 876; B 8 8 4944 876; B 8 8 4964 876; B 8 8 4984 876; B 8 8 5004 876; B 8 8 5024 876; B 8 8 5044 876; B 8 8 5064 876; B 8 8 5084 876; B 8 8 5104 876; B 8 8 5124 876; B 8 8 5144 876; B 8 8 5164 876; B 8 8 5184 876; B 8 8 5204 876; B 8 8 5224 876; B 8 8 5244 876; B 8 8 5684 876; B 8 8 5704 876; B 8 8 5724 876; B 8 8 5744 876; B 8 8 5764 876; B 8 8 5784 876; B 8 8 5804 876; B 8 8 5824 876; B 8 8 5844 876; B 8 8 5864 876; B 8 8 5884 876; B 8 8 5904 876; B 8 8 5924 876; B 8 8 5944 876; B 8 8 5964 876; B 8 8 5984 876; B 8 8 6004 876; B 8 8 6024 876; B 8 8 6044 876; B 8 8 6484 876; B 8 8 6504 876; B 8 8 6524 876; B 8 8 6544 876; B 8 8 6564 876; B 8 8 6584 876; B 8 8 6604 876; B 8 8 6624 876; B 8 8 6644 876; B 8 8 6664 876; B 8 8 6684 876; B 8 8 6704 876; B 8 8 6724 876; B 8 8 6744 876; B 8 8 6764 876; B 8 8 6784 876; B 8 8 6804 876; B 8 8 6824 876; B 8 8 6844 876; B 8 8 7284 876; B 8 8 7304 876; B 8 8 7324 876; B 8 8 7344 876; B 8 8 7364 876; B 8 8 7384 876; B 8 8 7404 876; B 8 8 7424 876; B 8 8 7444 876; B 8 8 7464 876; B 8 8 7484 876; B 8 8 7504 876; B 8 8 7524 876; B 8 8 7544 876; B 8 8 7564 876; B 8 8 7584 876; B 8 8 7604 876; B 8 8 7624 876; B 8 8 7644 876; B 8 8 84 436; B 8 8 104 436; B 8 8 124 436; B 8 8 144 436; B 8 8 164 436; B 8 8 184 436; B 8 8 204 436; B 8 8 224 436; B 8 8 244 436; B 8 8 264 436; B 8 8 284 436; B 8 8 304 436; B 8 8 324 436; B 8 8 344 436; B 8 8 364 436; B 8 8 384 436; B 8 8 404 436; B 8 8 424 436; B 8 8 444 436; B 8 8 884 436; B 8 8 904 436; B 8 8 924 436; B 8 8 944 436; B 8 8 964 436; B 8 8 984 436; B 8 8 1004 436; B 8 8 1024 436; B 8 8 1044 436; B 8 8 1064 436; B 8 8 1084 436; B 8 8 1104 436; B 8 8 1124 436; B 8 8 1144 436; B 8 8 1164 436; B 8 8 1184 436; B 8 8 1204 436; B 8 8 1224 436; B 8 8 1244 436; B 8 8 1684 436; B 8 8 1704 436; B 8 8 1724 436; B 8 8 1744 436; B 8 8 1764 436; B 8 8 1784 436; B 8 8 1804 436; B 8 8 1824 436; B 8 8 1844 436; B 8 8 1864 436; B 8 8 1884 436; B 8 8 1904 436; B 8 8 1924 436; B 8 8 1944 436; B 8 8 1964 436; B 8 8 1984 436; B 8 8 2004 436; B 8 8 2024 436; B 8 8 2044 436; B 8 8 2484 436; B 8 8 2504 436; B 8 8 2524 436; B 8 8 2544 436; B 8 8 2564 436; B 8 8 2584 436; B 8 8 2604 436; B 8 8 2624 436; B 8 8 2644 436; B 8 8 2664 436; B 8 8 2684 436; B 8 8 2704 436; B 8 8 2724 436; B 8 8 2744 436; B 8 8 2764 436; B 8 8 2784 436; B 8 8 2804 436; B 8 8 2824 436; B 8 8 2844 436; B 8 8 3284 436; B 8 8 3304 436; B 8 8 3324 436; B 8 8 3344 436; B 8 8 3364 436; B 8 8 3384 436; B 8 8 3404 436; B 8 8 3424 436; B 8 8 3444 436; B 8 8 3464 436; B 8 8 3484 436; B 8 8 3504 436; B 8 8 3524 436; B 8 8 3544 436; B 8 8 3564 436; B 8 8 3584 436; B 8 8 3604 436; B 8 8 3624 436; B 8 8 3644 436; B 8 8 4084 436; B 8 8 4104 436; B 8 8 4124 436; B 8 8 4144 436; B 8 8 4164 436; B 8 8 4184 436; B 8 8 4204 436; B 8 8 4224 436; B 8 8 4244 436; B 8 8 4264 436; B 8 8 4284 436; B 8 8 4304 436; B 8 8 4324 436; B 8 8 4344 436; B 8 8 4364 436; B 8 8 4384 436; B 8 8 4404 436; B 8 8 4424 436; B 8 8 4444 436; B 8 8 4884 436; B 8 8 4904 436; B 8 8 4924 436; B 8 8 4944 436; B 8 8 4964 436; B 8 8 4984 436; B 8 8 5004 436; B 8 8 5024 436; B 8 8 5044 436; B 8 8 5064 436; B 8 8 5084 436; B 8 8 5104 436; B 8 8 5124 436; B 8 8 5144 436; B 8 8 5164 436; B 8 8 5184 436; B 8 8 5204 436; B 8 8 5224 436; B 8 8 5244 436; B 8 8 5684 436; B 8 8 5704 436; B 8 8 5724 436; B 8 8 5744 436; B 8 8 5764 436; B 8 8 5784 436; B 8 8 5804 436; B 8 8 5824 436; B 8 8 5844 436; B 8 8 5864 436; B 8 8 5884 436; B 8 8 5904 436; B 8 8 5924 436; B 8 8 5944 436; B 8 8 5964 436; B 8 8 5984 436; B 8 8 6004 436; B 8 8 6024 436; B 8 8 6044 436; B 8 8 6484 436; B 8 8 6504 436; B 8 8 6524 436; B 8 8 6544 436; B 8 8 6564 436; B 8 8 6584 436; B 8 8 6604 436; B 8 8 6624 436; B 8 8 6644 436; B 8 8 6664 436; B 8 8 6684 436; B 8 8 6704 436; B 8 8 6724 436; B 8 8 6744 436; B 8 8 6764 436; B 8 8 6784 436; B 8 8 6804 436; B 8 8 6824 436; B 8 8 6844 436; B 8 8 7284 436; B 8 8 7304 436; B 8 8 7324 436; B 8 8 7344 436; B 8 8 7364 436; B 8 8 7384 436; B 8 8 7404 436; B 8 8 7424 436; B 8 8 7444 436; B 8 8 7464 436; B 8 8 7484 436; B 8 8 7504 436; B 8 8 7524 436; B 8 8 7544 436; B 8 8 7564 436; B 8 8 7584 436; B 8 8 7604 436; B 8 8 7624 436; B 8 8 7644 436; B 8 8 84 416; B 8 8 104 416; B 8 8 124 416; B 8 8 144 416; B 8 8 164 416; B 8 8 184 416; B 8 8 204 416; B 8 8 224 416; B 8 8 244 416; B 8 8 264 416; B 8 8 284 416; B 8 8 304 416; B 8 8 324 416; B 8 8 344 416; B 8 8 364 416; B 8 8 384 416; B 8 8 404 416; B 8 8 424 416; B 8 8 444 416; B 8 8 884 416; B 8 8 904 416; B 8 8 924 416; B 8 8 944 416; B 8 8 964 416; B 8 8 984 416; B 8 8 1004 416; B 8 8 1024 416; B 8 8 1044 416; B 8 8 1064 416; B 8 8 1084 416; B 8 8 1104 416; B 8 8 1124 416; B 8 8 1144 416; B 8 8 1164 416; B 8 8 1184 416; B 8 8 1204 416; B 8 8 1224 416; B 8 8 1244 416; B 8 8 1684 416; B 8 8 1704 416; B 8 8 1724 416; B 8 8 1744 416; B 8 8 1764 416; B 8 8 1784 416; B 8 8 1804 416; B 8 8 1824 416; B 8 8 1844 416; B 8 8 1864 416; B 8 8 1884 416; B 8 8 1904 416; B 8 8 1924 416; B 8 8 1944 416; B 8 8 1964 416; B 8 8 1984 416; B 8 8 2004 416; B 8 8 2024 416; B 8 8 2044 416; B 8 8 2484 416; B 8 8 2504 416; B 8 8 2524 416; B 8 8 2544 416; B 8 8 2564 416; B 8 8 2584 416; B 8 8 2604 416; B 8 8 2624 416; B 8 8 2644 416; B 8 8 2664 416; B 8 8 2684 416; B 8 8 2704 416; B 8 8 2724 416; B 8 8 2744 416; B 8 8 2764 416; B 8 8 2784 416; B 8 8 2804 416; B 8 8 2824 416; B 8 8 2844 416; B 8 8 3284 416; B 8 8 3304 416; B 8 8 3324 416; B 8 8 3344 416; B 8 8 3364 416; B 8 8 3384 416; B 8 8 3404 416; B 8 8 3424 416; B 8 8 3444 416; B 8 8 3464 416; B 8 8 3484 416; B 8 8 3504 416; B 8 8 3524 416; B 8 8 3544 416; B 8 8 3564 416; B 8 8 3584 416; B 8 8 3604 416; B 8 8 3624 416; B 8 8 3644 416; B 8 8 4084 416; B 8 8 4104 416; B 8 8 4124 416; B 8 8 4144 416; B 8 8 4164 416; B 8 8 4184 416; B 8 8 4204 416; B 8 8 4224 416; B 8 8 4244 416; B 8 8 4264 416; B 8 8 4284 416; B 8 8 4304 416; B 8 8 4324 416; B 8 8 4344 416; B 8 8 4364 416; B 8 8 4384 416; B 8 8 4404 416; B 8 8 4424 416; B 8 8 4444 416; B 8 8 4884 416; B 8 8 4904 416; B 8 8 4924 416; B 8 8 4944 416; B 8 8 4964 416; B 8 8 4984 416; B 8 8 5004 416; B 8 8 5024 416; B 8 8 5044 416; B 8 8 5064 416; B 8 8 5084 416; B 8 8 5104 416; B 8 8 5124 416; B 8 8 5144 416; B 8 8 5164 416; B 8 8 5184 416; B 8 8 5204 416; B 8 8 5224 416; B 8 8 5244 416; B 8 8 5684 416; B 8 8 5704 416; B 8 8 5724 416; B 8 8 5744 416; B 8 8 5764 416; B 8 8 5784 416; B 8 8 5804 416; B 8 8 5824 416; B 8 8 5844 416; B 8 8 5864 416; B 8 8 5884 416; B 8 8 5904 416; B 8 8 5924 416; B 8 8 5944 416; B 8 8 5964 416; B 8 8 5984 416; B 8 8 6004 416; B 8 8 6024 416; B 8 8 6044 416; B 8 8 6484 416; B 8 8 6504 416; B 8 8 6524 416; B 8 8 6544 416; B 8 8 6564 416; B 8 8 6584 416; B 8 8 6604 416; B 8 8 6624 416; B 8 8 6644 416; B 8 8 6664 416; B 8 8 6684 416; B 8 8 6704 416; B 8 8 6724 416; B 8 8 6744 416; B 8 8 6764 416; B 8 8 6784 416; B 8 8 6804 416; B 8 8 6824 416; B 8 8 6844 416; B 8 8 7284 416; B 8 8 7304 416; B 8 8 7324 416; B 8 8 7344 416; B 8 8 7364 416; B 8 8 7384 416; B 8 8 7404 416; B 8 8 7424 416; B 8 8 7444 416; B 8 8 7464 416; B 8 8 7484 416; B 8 8 7504 416; B 8 8 7524 416; B 8 8 7544 416; B 8 8 7564 416; B 8 8 7584 416; B 8 8 7604 416; B 8 8 7624 416; B 8 8 7644 416; B 8 8 84 396; B 8 8 104 396; B 8 8 124 396; B 8 8 144 396; B 8 8 164 396; B 8 8 184 396; B 8 8 204 396; B 8 8 224 396; B 8 8 244 396; B 8 8 264 396; B 8 8 284 396; B 8 8 304 396; B 8 8 324 396; B 8 8 344 396; B 8 8 364 396; B 8 8 384 396; B 8 8 404 396; B 8 8 424 396; B 8 8 444 396; B 8 8 884 396; B 8 8 904 396; B 8 8 924 396; B 8 8 944 396; B 8 8 964 396; B 8 8 984 396; B 8 8 1004 396; B 8 8 1024 396; B 8 8 1044 396; B 8 8 1064 396; B 8 8 1084 396; B 8 8 1104 396; B 8 8 1124 396; B 8 8 1144 396; B 8 8 1164 396; B 8 8 1184 396; B 8 8 1204 396; B 8 8 1224 396; B 8 8 1244 396; B 8 8 1684 396; B 8 8 1704 396; B 8 8 1724 396; B 8 8 1744 396; B 8 8 1764 396; B 8 8 1784 396; B 8 8 1804 396; B 8 8 1824 396; B 8 8 1844 396; B 8 8 1864 396; B 8 8 1884 396; B 8 8 1904 396; B 8 8 1924 396; B 8 8 1944 396; B 8 8 1964 396; B 8 8 1984 396; B 8 8 2004 396; B 8 8 2024 396; B 8 8 2044 396; B 8 8 2484 396; B 8 8 2504 396; B 8 8 2524 396; B 8 8 2544 396; B 8 8 2564 396; B 8 8 2584 396; B 8 8 2604 396; B 8 8 2624 396; B 8 8 2644 396; B 8 8 2664 396; B 8 8 2684 396; B 8 8 2704 396; B 8 8 2724 396; B 8 8 2744 396; B 8 8 2764 396; B 8 8 2784 396; B 8 8 2804 396; B 8 8 2824 396; B 8 8 2844 396; B 8 8 3284 396; B 8 8 3304 396; B 8 8 3324 396; B 8 8 3344 396; B 8 8 3364 396; B 8 8 3384 396; B 8 8 3404 396; B 8 8 3424 396; B 8 8 3444 396; B 8 8 3464 396; B 8 8 3484 396; B 8 8 3504 396; B 8 8 3524 396; B 8 8 3544 396; B 8 8 3564 396; B 8 8 3584 396; B 8 8 3604 396; B 8 8 3624 396; B 8 8 3644 396; B 8 8 4084 396; B 8 8 4104 396; B 8 8 4124 396; B 8 8 4144 396; B 8 8 4164 396; B 8 8 4184 396; B 8 8 4204 396; B 8 8 4224 396; B 8 8 4244 396; B 8 8 4264 396; B 8 8 4284 396; B 8 8 4304 396; B 8 8 4324 396; B 8 8 4344 396; B 8 8 4364 396; B 8 8 4384 396; B 8 8 4404 396; B 8 8 4424 396; B 8 8 4444 396; B 8 8 4884 396; B 8 8 4904 396; B 8 8 4924 396; B 8 8 4944 396; B 8 8 4964 396; B 8 8 4984 396; B 8 8 5004 396; B 8 8 5024 396; B 8 8 5044 396; B 8 8 5064 396; B 8 8 5084 396; B 8 8 5104 396; B 8 8 5124 396; B 8 8 5144 396; B 8 8 5164 396; B 8 8 5184 396; B 8 8 5204 396; B 8 8 5224 396; B 8 8 5244 396; B 8 8 5684 396; B 8 8 5704 396; B 8 8 5724 396; B 8 8 5744 396; B 8 8 5764 396; B 8 8 5784 396; B 8 8 5804 396; B 8 8 5824 396; B 8 8 5844 396; B 8 8 5864 396; B 8 8 5884 396; B 8 8 5904 396; B 8 8 5924 396; B 8 8 5944 396; B 8 8 5964 396; B 8 8 5984 396; B 8 8 6004 396; B 8 8 6024 396; B 8 8 6044 396; B 8 8 6484 396; B 8 8 6504 396; B 8 8 6524 396; B 8 8 6544 396; B 8 8 6564 396; B 8 8 6584 396; B 8 8 6604 396; B 8 8 6624 396; B 8 8 6644 396; B 8 8 6664 396; B 8 8 6684 396; B 8 8 6704 396; B 8 8 6724 396; B 8 8 6744 396; B 8 8 6764 396; B 8 8 6784 396; B 8 8 6804 396; B 8 8 6824 396; B 8 8 6844 396; B 8 8 7284 396; B 8 8 7304 396; B 8 8 7324 396; B 8 8 7344 396; B 8 8 7364 396; B 8 8 7384 396; B 8 8 7404 396; B 8 8 7424 396; B 8 8 7444 396; B 8 8 7464 396; B 8 8 7484 396; B 8 8 7504 396; B 8 8 7524 396; B 8 8 7544 396; B 8 8 7564 396; B 8 8 7584 396; B 8 8 7604 396; B 8 8 7624 396; B 8 8 7644 396; B 8 8 84 376; B 8 8 104 376; B 8 8 124 376; B 8 8 144 376; B 8 8 164 376; B 8 8 184 376; B 8 8 204 376; B 8 8 224 376; B 8 8 244 376; B 8 8 264 376; B 8 8 284 376; B 8 8 304 376; B 8 8 324 376; B 8 8 344 376; B 8 8 364 376; B 8 8 384 376; B 8 8 404 376; B 8 8 424 376; B 8 8 444 376; B 8 8 884 376; B 8 8 904 376; B 8 8 924 376; B 8 8 944 376; B 8 8 964 376; B 8 8 984 376; B 8 8 1004 376; B 8 8 1024 376; B 8 8 1044 376; B 8 8 1064 376; B 8 8 1084 376; B 8 8 1104 376; B 8 8 1124 376; B 8 8 1144 376; B 8 8 1164 376; B 8 8 1184 376; B 8 8 1204 376; B 8 8 1224 376; B 8 8 1244 376; B 8 8 1684 376; B 8 8 1704 376; B 8 8 1724 376; B 8 8 1744 376; B 8 8 1764 376; B 8 8 1784 376; B 8 8 1804 376; B 8 8 1824 376; B 8 8 1844 376; B 8 8 1864 376; B 8 8 1884 376; B 8 8 1904 376; B 8 8 1924 376; B 8 8 1944 376; B 8 8 1964 376; B 8 8 1984 376; B 8 8 2004 376; B 8 8 2024 376; B 8 8 2044 376; B 8 8 2484 376; B 8 8 2504 376; B 8 8 2524 376; B 8 8 2544 376; B 8 8 2564 376; B 8 8 2584 376; B 8 8 2604 376; B 8 8 2624 376; B 8 8 2644 376; B 8 8 2664 376; B 8 8 2684 376; B 8 8 2704 376; B 8 8 2724 376; B 8 8 2744 376; B 8 8 2764 376; B 8 8 2784 376; B 8 8 2804 376; B 8 8 2824 376; B 8 8 2844 376; B 8 8 3284 376; B 8 8 3304 376; B 8 8 3324 376; B 8 8 3344 376; B 8 8 3364 376; B 8 8 3384 376; B 8 8 3404 376; B 8 8 3424 376; B 8 8 3444 376; B 8 8 3464 376; B 8 8 3484 376; B 8 8 3504 376; B 8 8 3524 376; B 8 8 3544 376; B 8 8 3564 376; B 8 8 3584 376; B 8 8 3604 376; B 8 8 3624 376; B 8 8 3644 376; B 8 8 4084 376; B 8 8 4104 376; B 8 8 4124 376; B 8 8 4144 376; B 8 8 4164 376; B 8 8 4184 376; B 8 8 4204 376; B 8 8 4224 376; B 8 8 4244 376; B 8 8 4264 376; B 8 8 4284 376; B 8 8 4304 376; B 8 8 4324 376; B 8 8 4344 376; B 8 8 4364 376; B 8 8 4384 376; B 8 8 4404 376; B 8 8 4424 376; B 8 8 4444 376; B 8 8 4884 376; B 8 8 4904 376; B 8 8 4924 376; B 8 8 4944 376; B 8 8 4964 376; B 8 8 4984 376; B 8 8 5004 376; B 8 8 5024 376; B 8 8 5044 376; B 8 8 5064 376; B 8 8 5084 376; B 8 8 5104 376; B 8 8 5124 376; B 8 8 5144 376; B 8 8 5164 376; B 8 8 5184 376; B 8 8 5204 376; B 8 8 5224 376; B 8 8 5244 376; B 8 8 5684 376; B 8 8 5704 376; B 8 8 5724 376; B 8 8 5744 376; B 8 8 5764 376; B 8 8 5784 376; B 8 8 5804 376; B 8 8 5824 376; B 8 8 5844 376; B 8 8 5864 376; B 8 8 5884 376; B 8 8 5904 376; B 8 8 5924 376; B 8 8 5944 376; B 8 8 5964 376; B 8 8 5984 376; B 8 8 6004 376; B 8 8 6024 376; B 8 8 6044 376; B 8 8 6484 376; B 8 8 6504 376; B 8 8 6524 376; B 8 8 6544 376; B 8 8 6564 376; B 8 8 6584 376; B 8 8 6604 376; B 8 8 6624 376; B 8 8 6644 376; B 8 8 6664 376; B 8 8 6684 376; B 8 8 6704 376; B 8 8 6724 376; B 8 8 6744 376; B 8 8 6764 376; B 8 8 6784 376; B 8 8 6804 376; B 8 8 6824 376; B 8 8 6844 376; B 8 8 7284 376; B 8 8 7304 376; B 8 8 7324 376; B 8 8 7344 376; B 8 8 7364 376; B 8 8 7384 376; B 8 8 7404 376; B 8 8 7424 376; B 8 8 7444 376; B 8 8 7464 376; B 8 8 7484 376; B 8 8 7504 376; B 8 8 7524 376; B 8 8 7544 376; B 8 8 7564 376; B 8 8 7584 376; B 8 8 7604 376; B 8 8 7624 376; B 8 8 7644 376; B 8 8 84 356; B 8 8 104 356; B 8 8 124 356; B 8 8 144 356; B 8 8 164 356; B 8 8 184 356; B 8 8 204 356; B 8 8 224 356; B 8 8 244 356; B 8 8 264 356; B 8 8 284 356; B 8 8 304 356; B 8 8 324 356; B 8 8 344 356; B 8 8 364 356; B 8 8 384 356; B 8 8 404 356; B 8 8 424 356; B 8 8 444 356; B 8 8 884 356; B 8 8 904 356; B 8 8 924 356; B 8 8 944 356; B 8 8 964 356; B 8 8 984 356; B 8 8 1004 356; B 8 8 1024 356; B 8 8 1044 356; B 8 8 1064 356; B 8 8 1084 356; B 8 8 1104 356; B 8 8 1124 356; B 8 8 1144 356; B 8 8 1164 356; B 8 8 1184 356; B 8 8 1204 356; B 8 8 1224 356; B 8 8 1244 356; B 8 8 1684 356; B 8 8 1704 356; B 8 8 1724 356; B 8 8 1744 356; B 8 8 1764 356; B 8 8 1784 356; B 8 8 1804 356; B 8 8 1824 356; B 8 8 1844 356; B 8 8 1864 356; B 8 8 1884 356; B 8 8 1904 356; B 8 8 1924 356; B 8 8 1944 356; B 8 8 1964 356; B 8 8 1984 356; B 8 8 2004 356; B 8 8 2024 356; B 8 8 2044 356; B 8 8 2484 356; B 8 8 2504 356; B 8 8 2524 356; B 8 8 2544 356; B 8 8 2564 356; B 8 8 2584 356; B 8 8 2604 356; B 8 8 2624 356; B 8 8 2644 356; B 8 8 2664 356; B 8 8 2684 356; B 8 8 2704 356; B 8 8 2724 356; B 8 8 2744 356; B 8 8 2764 356; B 8 8 2784 356; B 8 8 2804 356; B 8 8 2824 356; B 8 8 2844 356; B 8 8 3284 356; B 8 8 3304 356; B 8 8 3324 356; B 8 8 3344 356; B 8 8 3364 356; B 8 8 3384 356; B 8 8 3404 356; B 8 8 3424 356; B 8 8 3444 356; B 8 8 3464 356; B 8 8 3484 356; B 8 8 3504 356; B 8 8 3524 356; B 8 8 3544 356; B 8 8 3564 356; B 8 8 3584 356; B 8 8 3604 356; B 8 8 3624 356; B 8 8 3644 356; B 8 8 4084 356; B 8 8 4104 356; B 8 8 4124 356; B 8 8 4144 356; B 8 8 4164 356; B 8 8 4184 356; B 8 8 4204 356; B 8 8 4224 356; B 8 8 4244 356; B 8 8 4264 356; B 8 8 4284 356; B 8 8 4304 356; B 8 8 4324 356; B 8 8 4344 356; B 8 8 4364 356; B 8 8 4384 356; B 8 8 4404 356; B 8 8 4424 356; B 8 8 4444 356; B 8 8 4884 356; B 8 8 4904 356; B 8 8 4924 356; B 8 8 4944 356; B 8 8 4964 356; B 8 8 4984 356; B 8 8 5004 356; B 8 8 5024 356; B 8 8 5044 356; B 8 8 5064 356; B 8 8 5084 356; B 8 8 5104 356; B 8 8 5124 356; B 8 8 5144 356; B 8 8 5164 356; B 8 8 5184 356; B 8 8 5204 356; B 8 8 5224 356; B 8 8 5244 356; B 8 8 5684 356; B 8 8 5704 356; B 8 8 5724 356; B 8 8 5744 356; B 8 8 5764 356; B 8 8 5784 356; B 8 8 5804 356; B 8 8 5824 356; B 8 8 5844 356; B 8 8 5864 356; B 8 8 5884 356; B 8 8 5904 356; B 8 8 5924 356; B 8 8 5944 356; B 8 8 5964 356; B 8 8 5984 356; B 8 8 6004 356; B 8 8 6024 356; B 8 8 6044 356; B 8 8 6484 356; B 8 8 6504 356; B 8 8 6524 356; B 8 8 6544 356; B 8 8 6564 356; B 8 8 6584 356; B 8 8 6604 356; B 8 8 6624 356; B 8 8 6644 356; B 8 8 6664 356; B 8 8 6684 356; B 8 8 6704 356; B 8 8 6724 356; B 8 8 6744 356; B 8 8 6764 356; B 8 8 6784 356; B 8 8 6804 356; B 8 8 6824 356; B 8 8 6844 356; B 8 8 7284 356; B 8 8 7304 356; B 8 8 7324 356; B 8 8 7344 356; B 8 8 7364 356; B 8 8 7384 356; B 8 8 7404 356; B 8 8 7424 356; B 8 8 7444 356; B 8 8 7464 356; B 8 8 7484 356; B 8 8 7504 356; B 8 8 7524 356; B 8 8 7544 356; B 8 8 7564 356; B 8 8 7584 356; B 8 8 7604 356; B 8 8 7624 356; B 8 8 7644 356; B 8 8 84 336; B 8 8 104 336; B 8 8 124 336; B 8 8 144 336; B 8 8 164 336; B 8 8 184 336; B 8 8 204 336; B 8 8 224 336; B 8 8 244 336; B 8 8 264 336; B 8 8 284 336; B 8 8 304 336; B 8 8 324 336; B 8 8 344 336; B 8 8 364 336; B 8 8 384 336; B 8 8 404 336; B 8 8 424 336; B 8 8 444 336; B 8 8 884 336; B 8 8 904 336; B 8 8 924 336; B 8 8 944 336; B 8 8 964 336; B 8 8 984 336; B 8 8 1004 336; B 8 8 1024 336; B 8 8 1044 336; B 8 8 1064 336; B 8 8 1084 336; B 8 8 1104 336; B 8 8 1124 336; B 8 8 1144 336; B 8 8 1164 336; B 8 8 1184 336; B 8 8 1204 336; B 8 8 1224 336; B 8 8 1244 336; B 8 8 1684 336; B 8 8 1704 336; B 8 8 1724 336; B 8 8 1744 336; B 8 8 1764 336; B 8 8 1784 336; B 8 8 1804 336; B 8 8 1824 336; B 8 8 1844 336; B 8 8 1864 336; B 8 8 1884 336; B 8 8 1904 336; B 8 8 1924 336; B 8 8 1944 336; B 8 8 1964 336; B 8 8 1984 336; B 8 8 2004 336; B 8 8 2024 336; B 8 8 2044 336; B 8 8 2484 336; B 8 8 2504 336; B 8 8 2524 336; B 8 8 2544 336; B 8 8 2564 336; B 8 8 2584 336; B 8 8 2604 336; B 8 8 2624 336; B 8 8 2644 336; B 8 8 2664 336; B 8 8 2684 336; B 8 8 2704 336; B 8 8 2724 336; B 8 8 2744 336; B 8 8 2764 336; B 8 8 2784 336; B 8 8 2804 336; B 8 8 2824 336; B 8 8 2844 336; B 8 8 3284 336; B 8 8 3304 336; B 8 8 3324 336; B 8 8 3344 336; B 8 8 3364 336; B 8 8 3384 336; B 8 8 3404 336; B 8 8 3424 336; B 8 8 3444 336; B 8 8 3464 336; B 8 8 3484 336; B 8 8 3504 336; B 8 8 3524 336; B 8 8 3544 336; B 8 8 3564 336; B 8 8 3584 336; B 8 8 3604 336; B 8 8 3624 336; B 8 8 3644 336; B 8 8 4084 336; B 8 8 4104 336; B 8 8 4124 336; B 8 8 4144 336; B 8 8 4164 336; B 8 8 4184 336; B 8 8 4204 336; B 8 8 4224 336; B 8 8 4244 336; B 8 8 4264 336; B 8 8 4284 336; B 8 8 4304 336; B 8 8 4324 336; B 8 8 4344 336; B 8 8 4364 336; B 8 8 4384 336; B 8 8 4404 336; B 8 8 4424 336; B 8 8 4444 336; B 8 8 4884 336; B 8 8 4904 336; B 8 8 4924 336; B 8 8 4944 336; B 8 8 4964 336; B 8 8 4984 336; B 8 8 5004 336; B 8 8 5024 336; B 8 8 5044 336; B 8 8 5064 336; B 8 8 5084 336; B 8 8 5104 336; B 8 8 5124 336; B 8 8 5144 336; B 8 8 5164 336; B 8 8 5184 336; B 8 8 5204 336; B 8 8 5224 336; B 8 8 5244 336; B 8 8 5684 336; B 8 8 5704 336; B 8 8 5724 336; B 8 8 5744 336; B 8 8 5764 336; B 8 8 5784 336; B 8 8 5804 336; B 8 8 5824 336; B 8 8 5844 336; B 8 8 5864 336; B 8 8 5884 336; B 8 8 5904 336; B 8 8 5924 336; B 8 8 5944 336; B 8 8 5964 336; B 8 8 5984 336; B 8 8 6004 336; B 8 8 6024 336; B 8 8 6044 336; B 8 8 6484 336; B 8 8 6504 336; B 8 8 6524 336; B 8 8 6544 336; B 8 8 6564 336; B 8 8 6584 336; B 8 8 6604 336; B 8 8 6624 336; B 8 8 6644 336; B 8 8 6664 336; B 8 8 6684 336; B 8 8 6704 336; B 8 8 6724 336; B 8 8 6744 336; B 8 8 6764 336; B 8 8 6784 336; B 8 8 6804 336; B 8 8 6824 336; B 8 8 6844 336; B 8 8 7284 336; B 8 8 7304 336; B 8 8 7324 336; B 8 8 7344 336; B 8 8 7364 336; B 8 8 7384 336; B 8 8 7404 336; B 8 8 7424 336; B 8 8 7444 336; B 8 8 7464 336; B 8 8 7484 336; B 8 8 7504 336; B 8 8 7524 336; B 8 8 7544 336; B 8 8 7564 336; B 8 8 7584 336; B 8 8 7604 336; B 8 8 7624 336; B 8 8 7644 336; B 8 8 84 316; B 8 8 104 316; B 8 8 124 316; B 8 8 144 316; B 8 8 164 316; B 8 8 184 316; B 8 8 204 316; B 8 8 224 316; B 8 8 244 316; B 8 8 264 316; B 8 8 284 316; B 8 8 304 316; B 8 8 324 316; B 8 8 344 316; B 8 8 364 316; B 8 8 384 316; B 8 8 404 316; B 8 8 424 316; B 8 8 444 316; B 8 8 884 316; B 8 8 904 316; B 8 8 924 316; B 8 8 944 316; B 8 8 964 316; B 8 8 984 316; B 8 8 1004 316; B 8 8 1024 316; B 8 8 1044 316; B 8 8 1064 316; B 8 8 1084 316; B 8 8 1104 316; B 8 8 1124 316; B 8 8 1144 316; B 8 8 1164 316; B 8 8 1184 316; B 8 8 1204 316; B 8 8 1224 316; B 8 8 1244 316; B 8 8 1684 316; B 8 8 1704 316; B 8 8 1724 316; B 8 8 1744 316; B 8 8 1764 316; B 8 8 1784 316; B 8 8 1804 316; B 8 8 1824 316; B 8 8 1844 316; B 8 8 1864 316; B 8 8 1884 316; B 8 8 1904 316; B 8 8 1924 316; B 8 8 1944 316; B 8 8 1964 316; B 8 8 1984 316; B 8 8 2004 316; B 8 8 2024 316; B 8 8 2044 316; B 8 8 2484 316; B 8 8 2504 316; B 8 8 2524 316; B 8 8 2544 316; B 8 8 2564 316; B 8 8 2584 316; B 8 8 2604 316; B 8 8 2624 316; B 8 8 2644 316; B 8 8 2664 316; B 8 8 2684 316; B 8 8 2704 316; B 8 8 2724 316; B 8 8 2744 316; B 8 8 2764 316; B 8 8 2784 316; B 8 8 2804 316; B 8 8 2824 316; B 8 8 2844 316; B 8 8 3284 316; B 8 8 3304 316; B 8 8 3324 316; B 8 8 3344 316; B 8 8 3364 316; B 8 8 3384 316; B 8 8 3404 316; B 8 8 3424 316; B 8 8 3444 316; B 8 8 3464 316; B 8 8 3484 316; B 8 8 3504 316; B 8 8 3524 316; B 8 8 3544 316; B 8 8 3564 316; B 8 8 3584 316; B 8 8 3604 316; B 8 8 3624 316; B 8 8 3644 316; B 8 8 4084 316; B 8 8 4104 316; B 8 8 4124 316; B 8 8 4144 316; B 8 8 4164 316; B 8 8 4184 316; B 8 8 4204 316; B 8 8 4224 316; B 8 8 4244 316; B 8 8 4264 316; B 8 8 4284 316; B 8 8 4304 316; B 8 8 4324 316; B 8 8 4344 316; B 8 8 4364 316; B 8 8 4384 316; B 8 8 4404 316; B 8 8 4424 316; B 8 8 4444 316; B 8 8 4884 316; B 8 8 4904 316; B 8 8 4924 316; B 8 8 4944 316; B 8 8 4964 316; B 8 8 4984 316; B 8 8 5004 316; B 8 8 5024 316; B 8 8 5044 316; B 8 8 5064 316; B 8 8 5084 316; B 8 8 5104 316; B 8 8 5124 316; B 8 8 5144 316; B 8 8 5164 316; B 8 8 5184 316; B 8 8 5204 316; B 8 8 5224 316; B 8 8 5244 316; B 8 8 5684 316; B 8 8 5704 316; B 8 8 5724 316; B 8 8 5744 316; B 8 8 5764 316; B 8 8 5784 316; B 8 8 5804 316; B 8 8 5824 316; B 8 8 5844 316; B 8 8 5864 316; B 8 8 5884 316; B 8 8 5904 316; B 8 8 5924 316; B 8 8 5944 316; B 8 8 5964 316; B 8 8 5984 316; B 8 8 6004 316; B 8 8 6024 316; B 8 8 6044 316; B 8 8 6484 316; B 8 8 6504 316; B 8 8 6524 316; B 8 8 6544 316; B 8 8 6564 316; B 8 8 6584 316; B 8 8 6604 316; B 8 8 6624 316; B 8 8 6644 316; B 8 8 6664 316; B 8 8 6684 316; B 8 8 6704 316; B 8 8 6724 316; B 8 8 6744 316; B 8 8 6764 316; B 8 8 6784 316; B 8 8 6804 316; B 8 8 6824 316; B 8 8 6844 316; B 8 8 7284 316; B 8 8 7304 316; B 8 8 7324 316; B 8 8 7344 316; B 8 8 7364 316; B 8 8 7384 316; B 8 8 7404 316; B 8 8 7424 316; B 8 8 7444 316; B 8 8 7464 316; B 8 8 7484 316; B 8 8 7504 316; B 8 8 7524 316; B 8 8 7544 316; B 8 8 7564 316; B 8 8 7584 316; B 8 8 7604 316; B 8 8 7624 316; B 8 8 7644 316; B 8 8 84 296; B 8 8 104 296; B 8 8 124 296; B 8 8 144 296; B 8 8 164 296; B 8 8 184 296; B 8 8 204 296; B 8 8 224 296; B 8 8 244 296; B 8 8 264 296; B 8 8 284 296; B 8 8 304 296; B 8 8 324 296; B 8 8 344 296; B 8 8 364 296; B 8 8 384 296; B 8 8 404 296; B 8 8 424 296; B 8 8 444 296; B 8 8 884 296; B 8 8 904 296; B 8 8 924 296; B 8 8 944 296; B 8 8 964 296; B 8 8 984 296; B 8 8 1004 296; B 8 8 1024 296; B 8 8 1044 296; B 8 8 1064 296; B 8 8 1084 296; B 8 8 1104 296; B 8 8 1124 296; B 8 8 1144 296; B 8 8 1164 296; B 8 8 1184 296; B 8 8 1204 296; B 8 8 1224 296; B 8 8 1244 296; B 8 8 1684 296; B 8 8 1704 296; B 8 8 1724 296; B 8 8 1744 296; B 8 8 1764 296; B 8 8 1784 296; B 8 8 1804 296; B 8 8 1824 296; B 8 8 1844 296; B 8 8 1864 296; B 8 8 1884 296; B 8 8 1904 296; B 8 8 1924 296; B 8 8 1944 296; B 8 8 1964 296; B 8 8 1984 296; B 8 8 2004 296; B 8 8 2024 296; B 8 8 2044 296; B 8 8 2484 296; B 8 8 2504 296; B 8 8 2524 296; B 8 8 2544 296; B 8 8 2564 296; B 8 8 2584 296; B 8 8 2604 296; B 8 8 2624 296; B 8 8 2644 296; B 8 8 2664 296; B 8 8 2684 296; B 8 8 2704 296; B 8 8 2724 296; B 8 8 2744 296; B 8 8 2764 296; B 8 8 2784 296; B 8 8 2804 296; B 8 8 2824 296; B 8 8 2844 296; B 8 8 3284 296; B 8 8 3304 296; B 8 8 3324 296; B 8 8 3344 296; B 8 8 3364 296; B 8 8 3384 296; B 8 8 3404 296; B 8 8 3424 296; B 8 8 3444 296; B 8 8 3464 296; B 8 8 3484 296; B 8 8 3504 296; B 8 8 3524 296; B 8 8 3544 296; B 8 8 3564 296; B 8 8 3584 296; B 8 8 3604 296; B 8 8 3624 296; B 8 8 3644 296; B 8 8 4084 296; B 8 8 4104 296; B 8 8 4124 296; B 8 8 4144 296; B 8 8 4164 296; B 8 8 4184 296; B 8 8 4204 296; B 8 8 4224 296; B 8 8 4244 296; B 8 8 4264 296; B 8 8 4284 296; B 8 8 4304 296; B 8 8 4324 296; B 8 8 4344 296; B 8 8 4364 296; B 8 8 4384 296; B 8 8 4404 296; B 8 8 4424 296; B 8 8 4444 296; B 8 8 4884 296; B 8 8 4904 296; B 8 8 4924 296; B 8 8 4944 296; B 8 8 4964 296; B 8 8 4984 296; B 8 8 5004 296; B 8 8 5024 296; B 8 8 5044 296; B 8 8 5064 296; B 8 8 5084 296; B 8 8 5104 296; B 8 8 5124 296; B 8 8 5144 296; B 8 8 5164 296; B 8 8 5184 296; B 8 8 5204 296; B 8 8 5224 296; B 8 8 5244 296; B 8 8 5684 296; B 8 8 5704 296; B 8 8 5724 296; B 8 8 5744 296; B 8 8 5764 296; B 8 8 5784 296; B 8 8 5804 296; B 8 8 5824 296; B 8 8 5844 296; B 8 8 5864 296; B 8 8 5884 296; B 8 8 5904 296; B 8 8 5924 296; B 8 8 5944 296; B 8 8 5964 296; B 8 8 5984 296; B 8 8 6004 296; B 8 8 6024 296; B 8 8 6044 296; B 8 8 6484 296; B 8 8 6504 296; B 8 8 6524 296; B 8 8 6544 296; B 8 8 6564 296; B 8 8 6584 296; B 8 8 6604 296; B 8 8 6624 296; B 8 8 6644 296; B 8 8 6664 296; B 8 8 6684 296; B 8 8 6704 296; B 8 8 6724 296; B 8 8 6744 296; B 8 8 6764 296; B 8 8 6784 296; B 8 8 6804 296; B 8 8 6824 296; B 8 8 6844 296; B 8 8 7284 296; B 8 8 7304 296; B 8 8 7324 296; B 8 8 7344 296; B 8 8 7364 296; B 8 8 7384 296; B 8 8 7404 296; B 8 8 7424 296; B 8 8 7444 296; B 8 8 7464 296; B 8 8 7484 296; B 8 8 7504 296; B 8 8 7524 296; B 8 8 7544 296; B 8 8 7564 296; B 8 8 7584 296; B 8 8 7604 296; B 8 8 7624 296; B 8 8 7644 296; B 8 8 84 276; B 8 8 104 276; B 8 8 124 276; B 8 8 144 276; B 8 8 164 276; B 8 8 184 276; B 8 8 204 276; B 8 8 224 276; B 8 8 244 276; B 8 8 264 276; B 8 8 284 276; B 8 8 304 276; B 8 8 324 276; B 8 8 344 276; B 8 8 364 276; B 8 8 384 276; B 8 8 404 276; B 8 8 424 276; B 8 8 444 276; B 8 8 884 276; B 8 8 904 276; B 8 8 924 276; B 8 8 944 276; B 8 8 964 276; B 8 8 984 276; B 8 8 1004 276; B 8 8 1024 276; B 8 8 1044 276; B 8 8 1064 276; B 8 8 1084 276; B 8 8 1104 276; B 8 8 1124 276; B 8 8 1144 276; B 8 8 1164 276; B 8 8 1184 276; B 8 8 1204 276; B 8 8 1224 276; B 8 8 1244 276; B 8 8 1684 276; B 8 8 1704 276; B 8 8 1724 276; B 8 8 1744 276; B 8 8 1764 276; B 8 8 1784 276; B 8 8 1804 276; B 8 8 1824 276; B 8 8 1844 276; B 8 8 1864 276; B 8 8 1884 276; B 8 8 1904 276; B 8 8 1924 276; B 8 8 1944 276; B 8 8 1964 276; B 8 8 1984 276; B 8 8 2004 276; B 8 8 2024 276; B 8 8 2044 276; B 8 8 2484 276; B 8 8 2504 276; B 8 8 2524 276; B 8 8 2544 276; B 8 8 2564 276; B 8 8 2584 276; B 8 8 2604 276; B 8 8 2624 276; B 8 8 2644 276; B 8 8 2664 276; B 8 8 2684 276; B 8 8 2704 276; B 8 8 2724 276; B 8 8 2744 276; B 8 8 2764 276; B 8 8 2784 276; B 8 8 2804 276; B 8 8 2824 276; B 8 8 2844 276; B 8 8 3284 276; B 8 8 3304 276; B 8 8 3324 276; B 8 8 3344 276; B 8 8 3364 276; B 8 8 3384 276; B 8 8 3404 276; B 8 8 3424 276; B 8 8 3444 276; B 8 8 3464 276; B 8 8 3484 276; B 8 8 3504 276; B 8 8 3524 276; B 8 8 3544 276; B 8 8 3564 276; B 8 8 3584 276; B 8 8 3604 276; B 8 8 3624 276; B 8 8 3644 276; B 8 8 4084 276; B 8 8 4104 276; B 8 8 4124 276; B 8 8 4144 276; B 8 8 4164 276; B 8 8 4184 276; B 8 8 4204 276; B 8 8 4224 276; B 8 8 4244 276; B 8 8 4264 276; B 8 8 4284 276; B 8 8 4304 276; B 8 8 4324 276; B 8 8 4344 276; B 8 8 4364 276; B 8 8 4384 276; B 8 8 4404 276; B 8 8 4424 276; B 8 8 4444 276; B 8 8 4884 276; B 8 8 4904 276; B 8 8 4924 276; B 8 8 4944 276; B 8 8 4964 276; B 8 8 4984 276; B 8 8 5004 276; B 8 8 5024 276; B 8 8 5044 276; B 8 8 5064 276; B 8 8 5084 276; B 8 8 5104 276; B 8 8 5124 276; B 8 8 5144 276; B 8 8 5164 276; B 8 8 5184 276; B 8 8 5204 276; B 8 8 5224 276; B 8 8 5244 276; B 8 8 5684 276; B 8 8 5704 276; B 8 8 5724 276; B 8 8 5744 276; B 8 8 5764 276; B 8 8 5784 276; B 8 8 5804 276; B 8 8 5824 276; B 8 8 5844 276; B 8 8 5864 276; B 8 8 5884 276; B 8 8 5904 276; B 8 8 5924 276; B 8 8 5944 276; B 8 8 5964 276; B 8 8 5984 276; B 8 8 6004 276; B 8 8 6024 276; B 8 8 6044 276; B 8 8 6484 276; B 8 8 6504 276; B 8 8 6524 276; B 8 8 6544 276; B 8 8 6564 276; B 8 8 6584 276; B 8 8 6604 276; B 8 8 6624 276; B 8 8 6644 276; B 8 8 6664 276; B 8 8 6684 276; B 8 8 6704 276; B 8 8 6724 276; B 8 8 6744 276; B 8 8 6764 276; B 8 8 6784 276; B 8 8 6804 276; B 8 8 6824 276; B 8 8 6844 276; B 8 8 7284 276; B 8 8 7304 276; B 8 8 7324 276; B 8 8 7344 276; B 8 8 7364 276; B 8 8 7384 276; B 8 8 7404 276; B 8 8 7424 276; B 8 8 7444 276; B 8 8 7464 276; B 8 8 7484 276; B 8 8 7504 276; B 8 8 7524 276; B 8 8 7544 276; B 8 8 7564 276; B 8 8 7584 276; B 8 8 7604 276; B 8 8 7624 276; B 8 8 7644 276; B 8 8 84 256; B 8 8 104 256; B 8 8 124 256; B 8 8 144 256; B 8 8 164 256; B 8 8 184 256; B 8 8 204 256; B 8 8 224 256; B 8 8 244 256; B 8 8 264 256; B 8 8 284 256; B 8 8 304 256; B 8 8 324 256; B 8 8 344 256; B 8 8 364 256; B 8 8 384 256; B 8 8 404 256; B 8 8 424 256; B 8 8 444 256; B 8 8 884 256; B 8 8 904 256; B 8 8 924 256; B 8 8 944 256; B 8 8 964 256; B 8 8 984 256; B 8 8 1004 256; B 8 8 1024 256; B 8 8 1044 256; B 8 8 1064 256; B 8 8 1084 256; B 8 8 1104 256; B 8 8 1124 256; B 8 8 1144 256; B 8 8 1164 256; B 8 8 1184 256; B 8 8 1204 256; B 8 8 1224 256; B 8 8 1244 256; B 8 8 1684 256; B 8 8 1704 256; B 8 8 1724 256; B 8 8 1744 256; B 8 8 1764 256; B 8 8 1784 256; B 8 8 1804 256; B 8 8 1824 256; B 8 8 1844 256; B 8 8 1864 256; B 8 8 1884 256; B 8 8 1904 256; B 8 8 1924 256; B 8 8 1944 256; B 8 8 1964 256; B 8 8 1984 256; B 8 8 2004 256; B 8 8 2024 256; B 8 8 2044 256; B 8 8 2484 256; B 8 8 2504 256; B 8 8 2524 256; B 8 8 2544 256; B 8 8 2564 256; B 8 8 2584 256; B 8 8 2604 256; B 8 8 2624 256; B 8 8 2644 256; B 8 8 2664 256; B 8 8 2684 256; B 8 8 2704 256; B 8 8 2724 256; B 8 8 2744 256; B 8 8 2764 256; B 8 8 2784 256; B 8 8 2804 256; B 8 8 2824 256; B 8 8 2844 256; B 8 8 3284 256; B 8 8 3304 256; B 8 8 3324 256; B 8 8 3344 256; B 8 8 3364 256; B 8 8 3384 256; B 8 8 3404 256; B 8 8 3424 256; B 8 8 3444 256; B 8 8 3464 256; B 8 8 3484 256; B 8 8 3504 256; B 8 8 3524 256; B 8 8 3544 256; B 8 8 3564 256; B 8 8 3584 256; B 8 8 3604 256; B 8 8 3624 256; B 8 8 3644 256; B 8 8 4084 256; B 8 8 4104 256; B 8 8 4124 256; B 8 8 4144 256; B 8 8 4164 256; B 8 8 4184 256; B 8 8 4204 256; B 8 8 4224 256; B 8 8 4244 256; B 8 8 4264 256; B 8 8 4284 256; B 8 8 4304 256; B 8 8 4324 256; B 8 8 4344 256; B 8 8 4364 256; B 8 8 4384 256; B 8 8 4404 256; B 8 8 4424 256; B 8 8 4444 256; B 8 8 4884 256; B 8 8 4904 256; B 8 8 4924 256; B 8 8 4944 256; B 8 8 4964 256; B 8 8 4984 256; B 8 8 5004 256; B 8 8 5024 256; B 8 8 5044 256; B 8 8 5064 256; B 8 8 5084 256; B 8 8 5104 256; B 8 8 5124 256; B 8 8 5144 256; B 8 8 5164 256; B 8 8 5184 256; B 8 8 5204 256; B 8 8 5224 256; B 8 8 5244 256; B 8 8 5684 256; B 8 8 5704 256; B 8 8 5724 256; B 8 8 5744 256; B 8 8 5764 256; B 8 8 5784 256; B 8 8 5804 256; B 8 8 5824 256; B 8 8 5844 256; B 8 8 5864 256; B 8 8 5884 256; B 8 8 5904 256; B 8 8 5924 256; B 8 8 5944 256; B 8 8 5964 256; B 8 8 5984 256; B 8 8 6004 256; B 8 8 6024 256; B 8 8 6044 256; B 8 8 6484 256; B 8 8 6504 256; B 8 8 6524 256; B 8 8 6544 256; B 8 8 6564 256; B 8 8 6584 256; B 8 8 6604 256; B 8 8 6624 256; B 8 8 6644 256; B 8 8 6664 256; B 8 8 6684 256; B 8 8 6704 256; B 8 8 6724 256; B 8 8 6744 256; B 8 8 6764 256; B 8 8 6784 256; B 8 8 6804 256; B 8 8 6824 256; B 8 8 6844 256; B 8 8 7284 256; B 8 8 7304 256; B 8 8 7324 256; B 8 8 7344 256; B 8 8 7364 256; B 8 8 7384 256; B 8 8 7404 256; B 8 8 7424 256; B 8 8 7444 256; B 8 8 7464 256; B 8 8 7484 256; B 8 8 7504 256; B 8 8 7524 256; B 8 8 7544 256; B 8 8 7564 256; B 8 8 7584 256; B 8 8 7604 256; B 8 8 7624 256; B 8 8 7644 256; B 8 8 84 236; B 8 8 104 236; B 8 8 124 236; B 8 8 144 236; B 8 8 164 236; B 8 8 184 236; B 8 8 204 236; B 8 8 224 236; B 8 8 244 236; B 8 8 264 236; B 8 8 284 236; B 8 8 304 236; B 8 8 324 236; B 8 8 344 236; B 8 8 364 236; B 8 8 384 236; B 8 8 404 236; B 8 8 424 236; B 8 8 444 236; B 8 8 884 236; B 8 8 904 236; B 8 8 924 236; B 8 8 944 236; B 8 8 964 236; B 8 8 984 236; B 8 8 1004 236; B 8 8 1024 236; B 8 8 1044 236; B 8 8 1064 236; B 8 8 1084 236; B 8 8 1104 236; B 8 8 1124 236; B 8 8 1144 236; B 8 8 1164 236; B 8 8 1184 236; B 8 8 1204 236; B 8 8 1224 236; B 8 8 1244 236; B 8 8 1684 236; B 8 8 1704 236; B 8 8 1724 236; B 8 8 1744 236; B 8 8 1764 236; B 8 8 1784 236; B 8 8 1804 236; B 8 8 1824 236; B 8 8 1844 236; B 8 8 1864 236; B 8 8 1884 236; B 8 8 1904 236; B 8 8 1924 236; B 8 8 1944 236; B 8 8 1964 236; B 8 8 1984 236; B 8 8 2004 236; B 8 8 2024 236; B 8 8 2044 236; B 8 8 2484 236; B 8 8 2504 236; B 8 8 2524 236; B 8 8 2544 236; B 8 8 2564 236; B 8 8 2584 236; B 8 8 2604 236; B 8 8 2624 236; B 8 8 2644 236; B 8 8 2664 236; B 8 8 2684 236; B 8 8 2704 236; B 8 8 2724 236; B 8 8 2744 236; B 8 8 2764 236; B 8 8 2784 236; B 8 8 2804 236; B 8 8 2824 236; B 8 8 2844 236; B 8 8 3284 236; B 8 8 3304 236; B 8 8 3324 236; B 8 8 3344 236; B 8 8 3364 236; B 8 8 3384 236; B 8 8 3404 236; B 8 8 3424 236; B 8 8 3444 236; B 8 8 3464 236; B 8 8 3484 236; B 8 8 3504 236; B 8 8 3524 236; B 8 8 3544 236; B 8 8 3564 236; B 8 8 3584 236; B 8 8 3604 236; B 8 8 3624 236; B 8 8 3644 236; B 8 8 4084 236; B 8 8 4104 236; B 8 8 4124 236; B 8 8 4144 236; B 8 8 4164 236; B 8 8 4184 236; B 8 8 4204 236; B 8 8 4224 236; B 8 8 4244 236; B 8 8 4264 236; B 8 8 4284 236; B 8 8 4304 236; B 8 8 4324 236; B 8 8 4344 236; B 8 8 4364 236; B 8 8 4384 236; B 8 8 4404 236; B 8 8 4424 236; B 8 8 4444 236; B 8 8 4884 236; B 8 8 4904 236; B 8 8 4924 236; B 8 8 4944 236; B 8 8 4964 236; B 8 8 4984 236; B 8 8 5004 236; B 8 8 5024 236; B 8 8 5044 236; B 8 8 5064 236; B 8 8 5084 236; B 8 8 5104 236; B 8 8 5124 236; B 8 8 5144 236; B 8 8 5164 236; B 8 8 5184 236; B 8 8 5204 236; B 8 8 5224 236; B 8 8 5244 236; B 8 8 5684 236; B 8 8 5704 236; B 8 8 5724 236; B 8 8 5744 236; B 8 8 5764 236; B 8 8 5784 236; B 8 8 5804 236; B 8 8 5824 236; B 8 8 5844 236; B 8 8 5864 236; B 8 8 5884 236; B 8 8 5904 236; B 8 8 5924 236; B 8 8 5944 236; B 8 8 5964 236; B 8 8 5984 236; B 8 8 6004 236; B 8 8 6024 236; B 8 8 6044 236; B 8 8 6484 236; B 8 8 6504 236; B 8 8 6524 236; B 8 8 6544 236; B 8 8 6564 236; B 8 8 6584 236; B 8 8 6604 236; B 8 8 6624 236; B 8 8 6644 236; B 8 8 6664 236; B 8 8 6684 236; B 8 8 6704 236; B 8 8 6724 236; B 8 8 6744 236; B 8 8 6764 236; B 8 8 6784 236; B 8 8 6804 236; B 8 8 6824 236; B 8 8 6844 236; B 8 8 7284 236; B 8 8 7304 236; B 8 8 7324 236; B 8 8 7344 236; B 8 8 7364 236; B 8 8 7384 236; B 8 8 7404 236; B 8 8 7424 236; B 8 8 7444 236; B 8 8 7464 236; B 8 8 7484 236; B 8 8 7504 236; B 8 8 7524 236; B 8 8 7544 236; B 8 8 7564 236; B 8 8 7584 236; B 8 8 7604 236; B 8 8 7624 236; B 8 8 7644 236; B 8 8 84 216; B 8 8 104 216; B 8 8 124 216; B 8 8 144 216; B 8 8 164 216; B 8 8 184 216; B 8 8 204 216; B 8 8 224 216; B 8 8 244 216; B 8 8 264 216; B 8 8 284 216; B 8 8 304 216; B 8 8 324 216; B 8 8 344 216; B 8 8 364 216; B 8 8 384 216; B 8 8 404 216; B 8 8 424 216; B 8 8 444 216; B 8 8 884 216; B 8 8 904 216; B 8 8 924 216; B 8 8 944 216; B 8 8 964 216; B 8 8 984 216; B 8 8 1004 216; B 8 8 1024 216; B 8 8 1044 216; B 8 8 1064 216; B 8 8 1084 216; B 8 8 1104 216; B 8 8 1124 216; B 8 8 1144 216; B 8 8 1164 216; B 8 8 1184 216; B 8 8 1204 216; B 8 8 1224 216; B 8 8 1244 216; B 8 8 1684 216; B 8 8 1704 216; B 8 8 1724 216; B 8 8 1744 216; B 8 8 1764 216; B 8 8 1784 216; B 8 8 1804 216; B 8 8 1824 216; B 8 8 1844 216; B 8 8 1864 216; B 8 8 1884 216; B 8 8 1904 216; B 8 8 1924 216; B 8 8 1944 216; B 8 8 1964 216; B 8 8 1984 216; B 8 8 2004 216; B 8 8 2024 216; B 8 8 2044 216; B 8 8 2484 216; B 8 8 2504 216; B 8 8 2524 216; B 8 8 2544 216; B 8 8 2564 216; B 8 8 2584 216; B 8 8 2604 216; B 8 8 2624 216; B 8 8 2644 216; B 8 8 2664 216; B 8 8 2684 216; B 8 8 2704 216; B 8 8 2724 216; B 8 8 2744 216; B 8 8 2764 216; B 8 8 2784 216; B 8 8 2804 216; B 8 8 2824 216; B 8 8 2844 216; B 8 8 3284 216; B 8 8 3304 216; B 8 8 3324 216; B 8 8 3344 216; B 8 8 3364 216; B 8 8 3384 216; B 8 8 3404 216; B 8 8 3424 216; B 8 8 3444 216; B 8 8 3464 216; B 8 8 3484 216; B 8 8 3504 216; B 8 8 3524 216; B 8 8 3544 216; B 8 8 3564 216; B 8 8 3584 216; B 8 8 3604 216; B 8 8 3624 216; B 8 8 3644 216; B 8 8 4084 216; B 8 8 4104 216; B 8 8 4124 216; B 8 8 4144 216; B 8 8 4164 216; B 8 8 4184 216; B 8 8 4204 216; B 8 8 4224 216; B 8 8 4244 216; B 8 8 4264 216; B 8 8 4284 216; B 8 8 4304 216; B 8 8 4324 216; B 8 8 4344 216; B 8 8 4364 216; B 8 8 4384 216; B 8 8 4404 216; B 8 8 4424 216; B 8 8 4444 216; B 8 8 4884 216; B 8 8 4904 216; B 8 8 4924 216; B 8 8 4944 216; B 8 8 4964 216; B 8 8 4984 216; B 8 8 5004 216; B 8 8 5024 216; B 8 8 5044 216; B 8 8 5064 216; B 8 8 5084 216; B 8 8 5104 216; B 8 8 5124 216; B 8 8 5144 216; B 8 8 5164 216; B 8 8 5184 216; B 8 8 5204 216; B 8 8 5224 216; B 8 8 5244 216; B 8 8 5684 216; B 8 8 5704 216; B 8 8 5724 216; B 8 8 5744 216; B 8 8 5764 216; B 8 8 5784 216; B 8 8 5804 216; B 8 8 5824 216; B 8 8 5844 216; B 8 8 5864 216; B 8 8 5884 216; B 8 8 5904 216; B 8 8 5924 216; B 8 8 5944 216; B 8 8 5964 216; B 8 8 5984 216; B 8 8 6004 216; B 8 8 6024 216; B 8 8 6044 216; B 8 8 6484 216; B 8 8 6504 216; B 8 8 6524 216; B 8 8 6544 216; B 8 8 6564 216; B 8 8 6584 216; B 8 8 6604 216; B 8 8 6624 216; B 8 8 6644 216; B 8 8 6664 216; B 8 8 6684 216; B 8 8 6704 216; B 8 8 6724 216; B 8 8 6744 216; B 8 8 6764 216; B 8 8 6784 216; B 8 8 6804 216; B 8 8 6824 216; B 8 8 6844 216; B 8 8 7284 216; B 8 8 7304 216; B 8 8 7324 216; B 8 8 7344 216; B 8 8 7364 216; B 8 8 7384 216; B 8 8 7404 216; B 8 8 7424 216; B 8 8 7444 216; B 8 8 7464 216; B 8 8 7484 216; B 8 8 7504 216; B 8 8 7524 216; B 8 8 7544 216; B 8 8 7564 216; B 8 8 7584 216; B 8 8 7604 216; B 8 8 7624 216; B 8 8 7644 216; B 8 8 84 196; B 8 8 104 196; B 8 8 124 196; B 8 8 144 196; B 8 8 164 196; B 8 8 184 196; B 8 8 204 196; B 8 8 224 196; B 8 8 244 196; B 8 8 264 196; B 8 8 284 196; B 8 8 304 196; B 8 8 324 196; B 8 8 344 196; B 8 8 364 196; B 8 8 384 196; B 8 8 404 196; B 8 8 424 196; B 8 8 444 196; B 8 8 884 196; B 8 8 904 196; B 8 8 924 196; B 8 8 944 196; B 8 8 964 196; B 8 8 984 196; B 8 8 1004 196; B 8 8 1024 196; B 8 8 1044 196; B 8 8 1064 196; B 8 8 1084 196; B 8 8 1104 196; B 8 8 1124 196; B 8 8 1144 196; B 8 8 1164 196; B 8 8 1184 196; B 8 8 1204 196; B 8 8 1224 196; B 8 8 1244 196; B 8 8 1684 196; B 8 8 1704 196; B 8 8 1724 196; B 8 8 1744 196; B 8 8 1764 196; B 8 8 1784 196; B 8 8 1804 196; B 8 8 1824 196; B 8 8 1844 196; B 8 8 1864 196; B 8 8 1884 196; B 8 8 1904 196; B 8 8 1924 196; B 8 8 1944 196; B 8 8 1964 196; B 8 8 1984 196; B 8 8 2004 196; B 8 8 2024 196; B 8 8 2044 196; B 8 8 2484 196; B 8 8 2504 196; B 8 8 2524 196; B 8 8 2544 196; B 8 8 2564 196; B 8 8 2584 196; B 8 8 2604 196; B 8 8 2624 196; B 8 8 2644 196; B 8 8 2664 196; B 8 8 2684 196; B 8 8 2704 196; B 8 8 2724 196; B 8 8 2744 196; B 8 8 2764 196; B 8 8 2784 196; B 8 8 2804 196; B 8 8 2824 196; B 8 8 2844 196; B 8 8 3284 196; B 8 8 3304 196; B 8 8 3324 196; B 8 8 3344 196; B 8 8 3364 196; B 8 8 3384 196; B 8 8 3404 196; B 8 8 3424 196; B 8 8 3444 196; B 8 8 3464 196; B 8 8 3484 196; B 8 8 3504 196; B 8 8 3524 196; B 8 8 3544 196; B 8 8 3564 196; B 8 8 3584 196; B 8 8 3604 196; B 8 8 3624 196; B 8 8 3644 196; B 8 8 4084 196; B 8 8 4104 196; B 8 8 4124 196; B 8 8 4144 196; B 8 8 4164 196; B 8 8 4184 196; B 8 8 4204 196; B 8 8 4224 196; B 8 8 4244 196; B 8 8 4264 196; B 8 8 4284 196; B 8 8 4304 196; B 8 8 4324 196; B 8 8 4344 196; B 8 8 4364 196; B 8 8 4384 196; B 8 8 4404 196; B 8 8 4424 196; B 8 8 4444 196; B 8 8 4884 196; B 8 8 4904 196; B 8 8 4924 196; B 8 8 4944 196; B 8 8 4964 196; B 8 8 4984 196; B 8 8 5004 196; B 8 8 5024 196; B 8 8 5044 196; B 8 8 5064 196; B 8 8 5084 196; B 8 8 5104 196; B 8 8 5124 196; B 8 8 5144 196; B 8 8 5164 196; B 8 8 5184 196; B 8 8 5204 196; B 8 8 5224 196; B 8 8 5244 196; B 8 8 5684 196; B 8 8 5704 196; B 8 8 5724 196; B 8 8 5744 196; B 8 8 5764 196; B 8 8 5784 196; B 8 8 5804 196; B 8 8 5824 196; B 8 8 5844 196; B 8 8 5864 196; B 8 8 5884 196; B 8 8 5904 196; B 8 8 5924 196; B 8 8 5944 196; B 8 8 5964 196; B 8 8 5984 196; B 8 8 6004 196; B 8 8 6024 196; B 8 8 6044 196; B 8 8 6484 196; B 8 8 6504 196; B 8 8 6524 196; B 8 8 6544 196; B 8 8 6564 196; B 8 8 6584 196; B 8 8 6604 196; B 8 8 6624 196; B 8 8 6644 196; B 8 8 6664 196; B 8 8 6684 196; B 8 8 6704 196; B 8 8 6724 196; B 8 8 6744 196; B 8 8 6764 196; B 8 8 6784 196; B 8 8 6804 196; B 8 8 6824 196; B 8 8 6844 196; B 8 8 7284 196; B 8 8 7304 196; B 8 8 7324 196; B 8 8 7344 196; B 8 8 7364 196; B 8 8 7384 196; B 8 8 7404 196; B 8 8 7424 196; B 8 8 7444 196; B 8 8 7464 196; B 8 8 7484 196; B 8 8 7504 196; B 8 8 7524 196; B 8 8 7544 196; B 8 8 7564 196; B 8 8 7584 196; B 8 8 7604 196; B 8 8 7624 196; B 8 8 7644 196; B 8 8 84 176; B 8 8 104 176; B 8 8 124 176; B 8 8 144 176; B 8 8 164 176; B 8 8 184 176; B 8 8 204 176; B 8 8 224 176; B 8 8 244 176; B 8 8 264 176; B 8 8 284 176; B 8 8 304 176; B 8 8 324 176; B 8 8 344 176; B 8 8 364 176; B 8 8 384 176; B 8 8 404 176; B 8 8 424 176; B 8 8 444 176; B 8 8 884 176; B 8 8 904 176; B 8 8 924 176; B 8 8 944 176; B 8 8 964 176; B 8 8 984 176; B 8 8 1004 176; B 8 8 1024 176; B 8 8 1044 176; B 8 8 1064 176; B 8 8 1084 176; B 8 8 1104 176; B 8 8 1124 176; B 8 8 1144 176; B 8 8 1164 176; B 8 8 1184 176; B 8 8 1204 176; B 8 8 1224 176; B 8 8 1244 176; B 8 8 1684 176; B 8 8 1704 176; B 8 8 1724 176; B 8 8 1744 176; B 8 8 1764 176; B 8 8 1784 176; B 8 8 1804 176; B 8 8 1824 176; B 8 8 1844 176; B 8 8 1864 176; B 8 8 1884 176; B 8 8 1904 176; B 8 8 1924 176; B 8 8 1944 176; B 8 8 1964 176; B 8 8 1984 176; B 8 8 2004 176; B 8 8 2024 176; B 8 8 2044 176; B 8 8 2484 176; B 8 8 2504 176; B 8 8 2524 176; B 8 8 2544 176; B 8 8 2564 176; B 8 8 2584 176; B 8 8 2604 176; B 8 8 2624 176; B 8 8 2644 176; B 8 8 2664 176; B 8 8 2684 176; B 8 8 2704 176; B 8 8 2724 176; B 8 8 2744 176; B 8 8 2764 176; B 8 8 2784 176; B 8 8 2804 176; B 8 8 2824 176; B 8 8 2844 176; B 8 8 3284 176; B 8 8 3304 176; B 8 8 3324 176; B 8 8 3344 176; B 8 8 3364 176; B 8 8 3384 176; B 8 8 3404 176; B 8 8 3424 176; B 8 8 3444 176; B 8 8 3464 176; B 8 8 3484 176; B 8 8 3504 176; B 8 8 3524 176; B 8 8 3544 176; B 8 8 3564 176; B 8 8 3584 176; B 8 8 3604 176; B 8 8 3624 176; B 8 8 3644 176; B 8 8 4084 176; B 8 8 4104 176; B 8 8 4124 176; B 8 8 4144 176; B 8 8 4164 176; B 8 8 4184 176; B 8 8 4204 176; B 8 8 4224 176; B 8 8 4244 176; B 8 8 4264 176; B 8 8 4284 176; B 8 8 4304 176; B 8 8 4324 176; B 8 8 4344 176; B 8 8 4364 176; B 8 8 4384 176; B 8 8 4404 176; B 8 8 4424 176; B 8 8 4444 176; B 8 8 4884 176; B 8 8 4904 176; B 8 8 4924 176; B 8 8 4944 176; B 8 8 4964 176; B 8 8 4984 176; B 8 8 5004 176; B 8 8 5024 176; B 8 8 5044 176; B 8 8 5064 176; B 8 8 5084 176; B 8 8 5104 176; B 8 8 5124 176; B 8 8 5144 176; B 8 8 5164 176; B 8 8 5184 176; B 8 8 5204 176; B 8 8 5224 176; B 8 8 5244 176; B 8 8 5684 176; B 8 8 5704 176; B 8 8 5724 176; B 8 8 5744 176; B 8 8 5764 176; B 8 8 5784 176; B 8 8 5804 176; B 8 8 5824 176; B 8 8 5844 176; B 8 8 5864 176; B 8 8 5884 176; B 8 8 5904 176; B 8 8 5924 176; B 8 8 5944 176; B 8 8 5964 176; B 8 8 5984 176; B 8 8 6004 176; B 8 8 6024 176; B 8 8 6044 176; B 8 8 6484 176; B 8 8 6504 176; B 8 8 6524 176; B 8 8 6544 176; B 8 8 6564 176; B 8 8 6584 176; B 8 8 6604 176; B 8 8 6624 176; B 8 8 6644 176; B 8 8 6664 176; B 8 8 6684 176; B 8 8 6704 176; B 8 8 6724 176; B 8 8 6744 176; B 8 8 6764 176; B 8 8 6784 176; B 8 8 6804 176; B 8 8 6824 176; B 8 8 6844 176; B 8 8 7284 176; B 8 8 7304 176; B 8 8 7324 176; B 8 8 7344 176; B 8 8 7364 176; B 8 8 7384 176; B 8 8 7404 176; B 8 8 7424 176; B 8 8 7444 176; B 8 8 7464 176; B 8 8 7484 176; B 8 8 7504 176; B 8 8 7524 176; B 8 8 7544 176; B 8 8 7564 176; B 8 8 7584 176; B 8 8 7604 176; B 8 8 7624 176; B 8 8 7644 176; B 8 8 84 156; B 8 8 104 156; B 8 8 124 156; B 8 8 144 156; B 8 8 164 156; B 8 8 184 156; B 8 8 204 156; B 8 8 224 156; B 8 8 244 156; B 8 8 264 156; B 8 8 284 156; B 8 8 304 156; B 8 8 324 156; B 8 8 344 156; B 8 8 364 156; B 8 8 384 156; B 8 8 404 156; B 8 8 424 156; B 8 8 444 156; B 8 8 884 156; B 8 8 904 156; B 8 8 924 156; B 8 8 944 156; B 8 8 964 156; B 8 8 984 156; B 8 8 1004 156; B 8 8 1024 156; B 8 8 1044 156; B 8 8 1064 156; B 8 8 1084 156; B 8 8 1104 156; B 8 8 1124 156; B 8 8 1144 156; B 8 8 1164 156; B 8 8 1184 156; B 8 8 1204 156; B 8 8 1224 156; B 8 8 1244 156; B 8 8 1684 156; B 8 8 1704 156; B 8 8 1724 156; B 8 8 1744 156; B 8 8 1764 156; B 8 8 1784 156; B 8 8 1804 156; B 8 8 1824 156; B 8 8 1844 156; B 8 8 1864 156; B 8 8 1884 156; B 8 8 1904 156; B 8 8 1924 156; B 8 8 1944 156; B 8 8 1964 156; B 8 8 1984 156; B 8 8 2004 156; B 8 8 2024 156; B 8 8 2044 156; B 8 8 2484 156; B 8 8 2504 156; B 8 8 2524 156; B 8 8 2544 156; B 8 8 2564 156; B 8 8 2584 156; B 8 8 2604 156; B 8 8 2624 156; B 8 8 2644 156; B 8 8 2664 156; B 8 8 2684 156; B 8 8 2704 156; B 8 8 2724 156; B 8 8 2744 156; B 8 8 2764 156; B 8 8 2784 156; B 8 8 2804 156; B 8 8 2824 156; B 8 8 2844 156; B 8 8 3284 156; B 8 8 3304 156; B 8 8 3324 156; B 8 8 3344 156; B 8 8 3364 156; B 8 8 3384 156; B 8 8 3404 156; B 8 8 3424 156; B 8 8 3444 156; B 8 8 3464 156; B 8 8 3484 156; B 8 8 3504 156; B 8 8 3524 156; B 8 8 3544 156; B 8 8 3564 156; B 8 8 3584 156; B 8 8 3604 156; B 8 8 3624 156; B 8 8 3644 156; B 8 8 4084 156; B 8 8 4104 156; B 8 8 4124 156; B 8 8 4144 156; B 8 8 4164 156; B 8 8 4184 156; B 8 8 4204 156; B 8 8 4224 156; B 8 8 4244 156; B 8 8 4264 156; B 8 8 4284 156; B 8 8 4304 156; B 8 8 4324 156; B 8 8 4344 156; B 8 8 4364 156; B 8 8 4384 156; B 8 8 4404 156; B 8 8 4424 156; B 8 8 4444 156; B 8 8 4884 156; B 8 8 4904 156; B 8 8 4924 156; B 8 8 4944 156; B 8 8 4964 156; B 8 8 4984 156; B 8 8 5004 156; B 8 8 5024 156; B 8 8 5044 156; B 8 8 5064 156; B 8 8 5084 156; B 8 8 5104 156; B 8 8 5124 156; B 8 8 5144 156; B 8 8 5164 156; B 8 8 5184 156; B 8 8 5204 156; B 8 8 5224 156; B 8 8 5244 156; B 8 8 5684 156; B 8 8 5704 156; B 8 8 5724 156; B 8 8 5744 156; B 8 8 5764 156; B 8 8 5784 156; B 8 8 5804 156; B 8 8 5824 156; B 8 8 5844 156; B 8 8 5864 156; B 8 8 5884 156; B 8 8 5904 156; B 8 8 5924 156; B 8 8 5944 156; B 8 8 5964 156; B 8 8 5984 156; B 8 8 6004 156; B 8 8 6024 156; B 8 8 6044 156; B 8 8 6484 156; B 8 8 6504 156; B 8 8 6524 156; B 8 8 6544 156; B 8 8 6564 156; B 8 8 6584 156; B 8 8 6604 156; B 8 8 6624 156; B 8 8 6644 156; B 8 8 6664 156; B 8 8 6684 156; B 8 8 6704 156; B 8 8 6724 156; B 8 8 6744 156; B 8 8 6764 156; B 8 8 6784 156; B 8 8 6804 156; B 8 8 6824 156; B 8 8 6844 156; B 8 8 7284 156; B 8 8 7304 156; B 8 8 7324 156; B 8 8 7344 156; B 8 8 7364 156; B 8 8 7384 156; B 8 8 7404 156; B 8 8 7424 156; B 8 8 7444 156; B 8 8 7464 156; B 8 8 7484 156; B 8 8 7504 156; B 8 8 7524 156; B 8 8 7544 156; B 8 8 7564 156; B 8 8 7584 156; B 8 8 7604 156; B 8 8 7624 156; B 8 8 7644 156; B 8 8 84 136; B 8 8 104 136; B 8 8 124 136; B 8 8 144 136; B 8 8 164 136; B 8 8 184 136; B 8 8 204 136; B 8 8 224 136; B 8 8 244 136; B 8 8 264 136; B 8 8 284 136; B 8 8 304 136; B 8 8 324 136; B 8 8 344 136; B 8 8 364 136; B 8 8 384 136; B 8 8 404 136; B 8 8 424 136; B 8 8 444 136; B 8 8 884 136; B 8 8 904 136; B 8 8 924 136; B 8 8 944 136; B 8 8 964 136; B 8 8 984 136; B 8 8 1004 136; B 8 8 1024 136; B 8 8 1044 136; B 8 8 1064 136; B 8 8 1084 136; B 8 8 1104 136; B 8 8 1124 136; B 8 8 1144 136; B 8 8 1164 136; B 8 8 1184 136; B 8 8 1204 136; B 8 8 1224 136; B 8 8 1244 136; B 8 8 1684 136; B 8 8 1704 136; B 8 8 1724 136; B 8 8 1744 136; B 8 8 1764 136; B 8 8 1784 136; B 8 8 1804 136; B 8 8 1824 136; B 8 8 1844 136; B 8 8 1864 136; B 8 8 1884 136; B 8 8 1904 136; B 8 8 1924 136; B 8 8 1944 136; B 8 8 1964 136; B 8 8 1984 136; B 8 8 2004 136; B 8 8 2024 136; B 8 8 2044 136; B 8 8 2484 136; B 8 8 2504 136; B 8 8 2524 136; B 8 8 2544 136; B 8 8 2564 136; B 8 8 2584 136; B 8 8 2604 136; B 8 8 2624 136; B 8 8 2644 136; B 8 8 2664 136; B 8 8 2684 136; B 8 8 2704 136; B 8 8 2724 136; B 8 8 2744 136; B 8 8 2764 136; B 8 8 2784 136; B 8 8 2804 136; B 8 8 2824 136; B 8 8 2844 136; B 8 8 3284 136; B 8 8 3304 136; B 8 8 3324 136; B 8 8 3344 136; B 8 8 3364 136; B 8 8 3384 136; B 8 8 3404 136; B 8 8 3424 136; B 8 8 3444 136; B 8 8 3464 136; B 8 8 3484 136; B 8 8 3504 136; B 8 8 3524 136; B 8 8 3544 136; B 8 8 3564 136; B 8 8 3584 136; B 8 8 3604 136; B 8 8 3624 136; B 8 8 3644 136; B 8 8 4084 136; B 8 8 4104 136; B 8 8 4124 136; B 8 8 4144 136; B 8 8 4164 136; B 8 8 4184 136; B 8 8 4204 136; B 8 8 4224 136; B 8 8 4244 136; B 8 8 4264 136; B 8 8 4284 136; B 8 8 4304 136; B 8 8 4324 136; B 8 8 4344 136; B 8 8 4364 136; B 8 8 4384 136; B 8 8 4404 136; B 8 8 4424 136; B 8 8 4444 136; B 8 8 4884 136; B 8 8 4904 136; B 8 8 4924 136; B 8 8 4944 136; B 8 8 4964 136; B 8 8 4984 136; B 8 8 5004 136; B 8 8 5024 136; B 8 8 5044 136; B 8 8 5064 136; B 8 8 5084 136; B 8 8 5104 136; B 8 8 5124 136; B 8 8 5144 136; B 8 8 5164 136; B 8 8 5184 136; B 8 8 5204 136; B 8 8 5224 136; B 8 8 5244 136; B 8 8 5684 136; B 8 8 5704 136; B 8 8 5724 136; B 8 8 5744 136; B 8 8 5764 136; B 8 8 5784 136; B 8 8 5804 136; B 8 8 5824 136; B 8 8 5844 136; B 8 8 5864 136; B 8 8 5884 136; B 8 8 5904 136; B 8 8 5924 136; B 8 8 5944 136; B 8 8 5964 136; B 8 8 5984 136; B 8 8 6004 136; B 8 8 6024 136; B 8 8 6044 136; B 8 8 6484 136; B 8 8 6504 136; B 8 8 6524 136; B 8 8 6544 136; B 8 8 6564 136; B 8 8 6584 136; B 8 8 6604 136; B 8 8 6624 136; B 8 8 6644 136; B 8 8 6664 136; B 8 8 6684 136; B 8 8 6704 136; B 8 8 6724 136; B 8 8 6744 136; B 8 8 6764 136; B 8 8 6784 136; B 8 8 6804 136; B 8 8 6824 136; B 8 8 6844 136; B 8 8 7284 136; B 8 8 7304 136; B 8 8 7324 136; B 8 8 7344 136; B 8 8 7364 136; B 8 8 7384 136; B 8 8 7404 136; B 8 8 7424 136; B 8 8 7444 136; B 8 8 7464 136; B 8 8 7484 136; B 8 8 7504 136; B 8 8 7524 136; B 8 8 7544 136; B 8 8 7564 136; B 8 8 7584 136; B 8 8 7604 136; B 8 8 7624 136; B 8 8 7644 136; B 8 8 84 116; B 8 8 104 116; B 8 8 124 116; B 8 8 144 116; B 8 8 164 116; B 8 8 184 116; B 8 8 204 116; B 8 8 224 116; B 8 8 244 116; B 8 8 264 116; B 8 8 284 116; B 8 8 304 116; B 8 8 324 116; B 8 8 344 116; B 8 8 364 116; B 8 8 384 116; B 8 8 404 116; B 8 8 424 116; B 8 8 444 116; B 8 8 884 116; B 8 8 904 116; B 8 8 924 116; B 8 8 944 116; B 8 8 964 116; B 8 8 984 116; B 8 8 1004 116; B 8 8 1024 116; B 8 8 1044 116; B 8 8 1064 116; B 8 8 1084 116; B 8 8 1104 116; B 8 8 1124 116; B 8 8 1144 116; B 8 8 1164 116; B 8 8 1184 116; B 8 8 1204 116; B 8 8 1224 116; B 8 8 1244 116; B 8 8 1684 116; B 8 8 1704 116; B 8 8 1724 116; B 8 8 1744 116; B 8 8 1764 116; B 8 8 1784 116; B 8 8 1804 116; B 8 8 1824 116; B 8 8 1844 116; B 8 8 1864 116; B 8 8 1884 116; B 8 8 1904 116; B 8 8 1924 116; B 8 8 1944 116; B 8 8 1964 116; B 8 8 1984 116; B 8 8 2004 116; B 8 8 2024 116; B 8 8 2044 116; B 8 8 2484 116; B 8 8 2504 116; B 8 8 2524 116; B 8 8 2544 116; B 8 8 2564 116; B 8 8 2584 116; B 8 8 2604 116; B 8 8 2624 116; B 8 8 2644 116; B 8 8 2664 116; B 8 8 2684 116; B 8 8 2704 116; B 8 8 2724 116; B 8 8 2744 116; B 8 8 2764 116; B 8 8 2784 116; B 8 8 2804 116; B 8 8 2824 116; B 8 8 2844 116; B 8 8 3284 116; B 8 8 3304 116; B 8 8 3324 116; B 8 8 3344 116; B 8 8 3364 116; B 8 8 3384 116; B 8 8 3404 116; B 8 8 3424 116; B 8 8 3444 116; B 8 8 3464 116; B 8 8 3484 116; B 8 8 3504 116; B 8 8 3524 116; B 8 8 3544 116; B 8 8 3564 116; B 8 8 3584 116; B 8 8 3604 116; B 8 8 3624 116; B 8 8 3644 116; B 8 8 4084 116; B 8 8 4104 116; B 8 8 4124 116; B 8 8 4144 116; B 8 8 4164 116; B 8 8 4184 116; B 8 8 4204 116; B 8 8 4224 116; B 8 8 4244 116; B 8 8 4264 116; B 8 8 4284 116; B 8 8 4304 116; B 8 8 4324 116; B 8 8 4344 116; B 8 8 4364 116; B 8 8 4384 116; B 8 8 4404 116; B 8 8 4424 116; B 8 8 4444 116; B 8 8 4884 116; B 8 8 4904 116; B 8 8 4924 116; B 8 8 4944 116; B 8 8 4964 116; B 8 8 4984 116; B 8 8 5004 116; B 8 8 5024 116; B 8 8 5044 116; B 8 8 5064 116; B 8 8 5084 116; B 8 8 5104 116; B 8 8 5124 116; B 8 8 5144 116; B 8 8 5164 116; B 8 8 5184 116; B 8 8 5204 116; B 8 8 5224 116; B 8 8 5244 116; B 8 8 5684 116; B 8 8 5704 116; B 8 8 5724 116; B 8 8 5744 116; B 8 8 5764 116; B 8 8 5784 116; B 8 8 5804 116; B 8 8 5824 116; B 8 8 5844 116; B 8 8 5864 116; B 8 8 5884 116; B 8 8 5904 116; B 8 8 5924 116; B 8 8 5944 116; B 8 8 5964 116; B 8 8 5984 116; B 8 8 6004 116; B 8 8 6024 116; B 8 8 6044 116; B 8 8 6484 116; B 8 8 6504 116; B 8 8 6524 116; B 8 8 6544 116; B 8 8 6564 116; B 8 8 6584 116; B 8 8 6604 116; B 8 8 6624 116; B 8 8 6644 116; B 8 8 6664 116; B 8 8 6684 116; B 8 8 6704 116; B 8 8 6724 116; B 8 8 6744 116; B 8 8 6764 116; B 8 8 6784 116; B 8 8 6804 116; B 8 8 6824 116; B 8 8 6844 116; B 8 8 7284 116; B 8 8 7304 116; B 8 8 7324 116; B 8 8 7344 116; B 8 8 7364 116; B 8 8 7384 116; B 8 8 7404 116; B 8 8 7424 116; B 8 8 7444 116; B 8 8 7464 116; B 8 8 7484 116; B 8 8 7504 116; B 8 8 7524 116; B 8 8 7544 116; B 8 8 7564 116; B 8 8 7584 116; B 8 8 7604 116; B 8 8 7624 116; B 8 8 7644 116; B 8 8 84 96; B 8 8 104 96; B 8 8 124 96; B 8 8 144 96; B 8 8 164 96; B 8 8 184 96; B 8 8 204 96; B 8 8 224 96; B 8 8 244 96; B 8 8 264 96; B 8 8 284 96; B 8 8 304 96; B 8 8 324 96; B 8 8 344 96; B 8 8 364 96; B 8 8 384 96; B 8 8 404 96; B 8 8 424 96; B 8 8 444 96; B 8 8 884 96; B 8 8 904 96; B 8 8 924 96; B 8 8 944 96; B 8 8 964 96; B 8 8 984 96; B 8 8 1004 96; B 8 8 1024 96; B 8 8 1044 96; B 8 8 1064 96; B 8 8 1084 96; B 8 8 1104 96; B 8 8 1124 96; B 8 8 1144 96; B 8 8 1164 96; B 8 8 1184 96; B 8 8 1204 96; B 8 8 1224 96; B 8 8 1244 96; B 8 8 1684 96; B 8 8 1704 96; B 8 8 1724 96; B 8 8 1744 96; B 8 8 1764 96; B 8 8 1784 96; B 8 8 1804 96; B 8 8 1824 96; B 8 8 1844 96; B 8 8 1864 96; B 8 8 1884 96; B 8 8 1904 96; B 8 8 1924 96; B 8 8 1944 96; B 8 8 1964 96; B 8 8 1984 96; B 8 8 2004 96; B 8 8 2024 96; B 8 8 2044 96; B 8 8 2484 96; B 8 8 2504 96; B 8 8 2524 96; B 8 8 2544 96; B 8 8 2564 96; B 8 8 2584 96; B 8 8 2604 96; B 8 8 2624 96; B 8 8 2644 96; B 8 8 2664 96; B 8 8 2684 96; B 8 8 2704 96; B 8 8 2724 96; B 8 8 2744 96; B 8 8 2764 96; B 8 8 2784 96; B 8 8 2804 96; B 8 8 2824 96; B 8 8 2844 96; B 8 8 3284 96; B 8 8 3304 96; B 8 8 3324 96; B 8 8 3344 96; B 8 8 3364 96; B 8 8 3384 96; B 8 8 3404 96; B 8 8 3424 96; B 8 8 3444 96; B 8 8 3464 96; B 8 8 3484 96; B 8 8 3504 96; B 8 8 3524 96; B 8 8 3544 96; B 8 8 3564 96; B 8 8 3584 96; B 8 8 3604 96; B 8 8 3624 96; B 8 8 3644 96; B 8 8 4084 96; B 8 8 4104 96; B 8 8 4124 96; B 8 8 4144 96; B 8 8 4164 96; B 8 8 4184 96; B 8 8 4204 96; B 8 8 4224 96; B 8 8 4244 96; B 8 8 4264 96; B 8 8 4284 96; B 8 8 4304 96; B 8 8 4324 96; B 8 8 4344 96; B 8 8 4364 96; B 8 8 4384 96; B 8 8 4404 96; B 8 8 4424 96; B 8 8 4444 96; B 8 8 4884 96; B 8 8 4904 96; B 8 8 4924 96; B 8 8 4944 96; B 8 8 4964 96; B 8 8 4984 96; B 8 8 5004 96; B 8 8 5024 96; B 8 8 5044 96; B 8 8 5064 96; B 8 8 5084 96; B 8 8 5104 96; B 8 8 5124 96; B 8 8 5144 96; B 8 8 5164 96; B 8 8 5184 96; B 8 8 5204 96; B 8 8 5224 96; B 8 8 5244 96; B 8 8 5684 96; B 8 8 5704 96; B 8 8 5724 96; B 8 8 5744 96; B 8 8 5764 96; B 8 8 5784 96; B 8 8 5804 96; B 8 8 5824 96; B 8 8 5844 96; B 8 8 5864 96; B 8 8 5884 96; B 8 8 5904 96; B 8 8 5924 96; B 8 8 5944 96; B 8 8 5964 96; B 8 8 5984 96; B 8 8 6004 96; B 8 8 6024 96; B 8 8 6044 96; B 8 8 6484 96; B 8 8 6504 96; B 8 8 6524 96; B 8 8 6544 96; B 8 8 6564 96; B 8 8 6584 96; B 8 8 6604 96; B 8 8 6624 96; B 8 8 6644 96; B 8 8 6664 96; B 8 8 6684 96; B 8 8 6704 96; B 8 8 6724 96; B 8 8 6744 96; B 8 8 6764 96; B 8 8 6784 96; B 8 8 6804 96; B 8 8 6824 96; B 8 8 6844 96; B 8 8 7284 96; B 8 8 7304 96; B 8 8 7324 96; B 8 8 7344 96; B 8 8 7364 96; B 8 8 7384 96; B 8 8 7404 96; B 8 8 7424 96; B 8 8 7444 96; B 8 8 7464 96; B 8 8 7484 96; B 8 8 7504 96; B 8 8 7524 96; B 8 8 7544 96; B 8 8 7564 96; B 8 8 7584 96; B 8 8 7604 96; B 8 8 7624 96; B 8 8 7644 96; B 8 8 84 76; B 8 8 104 76; B 8 8 124 76; B 8 8 144 76; B 8 8 164 76; B 8 8 184 76; B 8 8 204 76; B 8 8 224 76; B 8 8 244 76; B 8 8 264 76; B 8 8 284 76; B 8 8 304 76; B 8 8 324 76; B 8 8 344 76; B 8 8 364 76; B 8 8 384 76; B 8 8 404 76; B 8 8 424 76; B 8 8 444 76; B 8 8 884 76; B 8 8 904 76; B 8 8 924 76; B 8 8 944 76; B 8 8 964 76; B 8 8 984 76; B 8 8 1004 76; B 8 8 1024 76; B 8 8 1044 76; B 8 8 1064 76; B 8 8 1084 76; B 8 8 1104 76; B 8 8 1124 76; B 8 8 1144 76; B 8 8 1164 76; B 8 8 1184 76; B 8 8 1204 76; B 8 8 1224 76; B 8 8 1244 76; B 8 8 1684 76; B 8 8 1704 76; B 8 8 1724 76; B 8 8 1744 76; B 8 8 1764 76; B 8 8 1784 76; B 8 8 1804 76; B 8 8 1824 76; B 8 8 1844 76; B 8 8 1864 76; B 8 8 1884 76; B 8 8 1904 76; B 8 8 1924 76; B 8 8 1944 76; B 8 8 1964 76; B 8 8 1984 76; B 8 8 2004 76; B 8 8 2024 76; B 8 8 2044 76; B 8 8 2484 76; B 8 8 2504 76; B 8 8 2524 76; B 8 8 2544 76; B 8 8 2564 76; B 8 8 2584 76; B 8 8 2604 76; B 8 8 2624 76; B 8 8 2644 76; B 8 8 2664 76; B 8 8 2684 76; B 8 8 2704 76; B 8 8 2724 76; B 8 8 2744 76; B 8 8 2764 76; B 8 8 2784 76; B 8 8 2804 76; B 8 8 2824 76; B 8 8 2844 76; B 8 8 3284 76; B 8 8 3304 76; B 8 8 3324 76; B 8 8 3344 76; B 8 8 3364 76; B 8 8 3384 76; B 8 8 3404 76; B 8 8 3424 76; B 8 8 3444 76; B 8 8 3464 76; B 8 8 3484 76; B 8 8 3504 76; B 8 8 3524 76; B 8 8 3544 76; B 8 8 3564 76; B 8 8 3584 76; B 8 8 3604 76; B 8 8 3624 76; B 8 8 3644 76; B 8 8 4084 76; B 8 8 4104 76; B 8 8 4124 76; B 8 8 4144 76; B 8 8 4164 76; B 8 8 4184 76; B 8 8 4204 76; B 8 8 4224 76; B 8 8 4244 76; B 8 8 4264 76; B 8 8 4284 76; B 8 8 4304 76; B 8 8 4324 76; B 8 8 4344 76; B 8 8 4364 76; B 8 8 4384 76; B 8 8 4404 76; B 8 8 4424 76; B 8 8 4444 76; B 8 8 4884 76; B 8 8 4904 76; B 8 8 4924 76; B 8 8 4944 76; B 8 8 4964 76; B 8 8 4984 76; B 8 8 5004 76; B 8 8 5024 76; B 8 8 5044 76; B 8 8 5064 76; B 8 8 5084 76; B 8 8 5104 76; B 8 8 5124 76; B 8 8 5144 76; B 8 8 5164 76; B 8 8 5184 76; B 8 8 5204 76; B 8 8 5224 76; B 8 8 5244 76; B 8 8 5684 76; B 8 8 5704 76; B 8 8 5724 76; B 8 8 5744 76; B 8 8 5764 76; B 8 8 5784 76; B 8 8 5804 76; B 8 8 5824 76; B 8 8 5844 76; B 8 8 5864 76; B 8 8 5884 76; B 8 8 5904 76; B 8 8 5924 76; B 8 8 5944 76; B 8 8 5964 76; B 8 8 5984 76; B 8 8 6004 76; B 8 8 6024 76; B 8 8 6044 76; B 8 8 6484 76; B 8 8 6504 76; B 8 8 6524 76; B 8 8 6544 76; B 8 8 6564 76; B 8 8 6584 76; B 8 8 6604 76; B 8 8 6624 76; B 8 8 6644 76; B 8 8 6664 76; B 8 8 6684 76; B 8 8 6704 76; B 8 8 6724 76; B 8 8 6744 76; B 8 8 6764 76; B 8 8 6784 76; B 8 8 6804 76; B 8 8 6824 76; B 8 8 6844 76; B 8 8 7284 76; B 8 8 7304 76; B 8 8 7324 76; B 8 8 7344 76; B 8 8 7364 76; B 8 8 7384 76; B 8 8 7404 76; B 8 8 7424 76; B 8 8 7444 76; B 8 8 7464 76; B 8 8 7484 76; B 8 8 7504 76; B 8 8 7524 76; B 8 8 7544 76; B 8 8 7564 76; B 8 8 7584 76; B 8 8 7604 76; B 8 8 7624 76; B 8 8 7644 76; L CCA; B 8 8 1924 728; B 8 8 1948 732; B 8 8 1964 732; B 8 8 1980 732; B 8 8 1996 732; B 8 8 2084 732; B 8 8 2472 728; B 8 8 2496 732; B 8 8 2512 732; B 8 8 2528 732; B 8 8 2544 732; B 8 8 2560 732; B 8 8 2576 732; B 8 8 2592 732; B 8 8 2608 732; B 8 8 2624 732; B 8 8 2640 732; B 8 8 2656 732; B 8 8 2672 732; B 8 8 2688 732; B 8 8 2704 732; B 8 8 2720 732; B 8 8 2736 732; B 8 8 2752 732; B 8 8 2768 732; B 8 8 2784 732; B 8 8 2800 732; B 8 8 2816 732; B 8 8 2832 732; B 8 8 2848 732; B 8 8 2864 732; B 8 8 2880 732; B 8 8 2896 732; B 8 8 2912 732; B 8 8 2928 732; B 8 8 2944 732; B 8 8 2960 732; B 8 8 2976 732; B 8 8 2992 732; B 8 8 3008 732; B 8 8 3024 732; B 8 8 3040 732; B 8 8 3056 732; B 8 8 3072 732; B 8 8 3088 732; B 8 8 3104 732; B 8 8 3120 732; B 8 8 3136 732; B 8 8 3152 732; B 8 8 3168 732; B 8 8 3184 732; B 8 8 3200 732; B 8 8 3216 732; B 8 8 3232 732; B 8 8 3256 732; B 8 8 3640 728; B 8 8 3660 732; B 8 8 3676 732; B 8 8 3692 732; B 8 8 3708 732; B 8 8 3724 732; B 8 8 3740 732; B 8 8 3756 732; B 8 8 3772 732; B 8 8 3788 732; B 8 8 3804 732; B 8 8 3820 732; B 8 8 3836 732; B 8 8 3852 732; B 8 8 3868 732; B 8 8 3884 732; B 8 8 3900 732; B 8 8 3916 732; B 8 8 3932 732; B 8 8 3948 732; B 8 8 3964 732; B 8 8 3980 732; B 8 8 3996 732; B 8 8 4012 732; B 8 8 4028 732; B 8 8 4044 732; B 8 8 4060 732; B 8 8 4076 732; B 8 8 4092 732; B 8 8 4108 732; B 8 8 4124 732; B 8 8 4140 732; B 8 8 4156 732; B 8 8 4172 732; B 8 8 4188 732; B 8 8 4204 732; B 8 8 4220 732; B 8 8 4236 732; B 8 8 4252 732; B 8 8 4268 732; B 8 8 4284 732; B 8 8 4300 732; B 8 8 4316 732; B 8 8 4332 732; B 8 8 4348 732; B 8 8 4364 732; B 8 8 4380 732; B 8 8 4396 732; B 8 8 4412 732; B 8 8 4428 732; B 8 8 4444 732; B 8 8 4460 732; B 8 8 4476 732; B 8 8 4492 732; B 8 8 4508 732; B 8 8 4524 732; B 8 8 4540 732; B 8 8 4556 732; B 8 8 4572 732; B 8 8 4588 732; B 8 8 4604 732; B 8 8 4620 732; B 8 8 4636 732; B 8 8 4652 732; B 8 8 4668 732; B 8 8 4684 732; B 8 8 4700 732; B 8 8 4716 732; B 8 8 4732 732; B 8 8 4748 732; B 8 8 4764 732; B 8 8 4780 732; B 8 8 4796 732; B 8 8 4812 732; B 8 8 4828 732; B 8 8 4844 732; B 8 8 4860 732; B 8 8 4876 732; B 8 8 4892 732; B 8 8 4908 732; B 8 8 4924 732; B 8 8 4940 732; B 8 8 4956 732; B 8 8 4972 732; B 8 8 4988 732; B 8 8 5004 732; B 8 8 5020 732; B 8 8 5036 732; B 8 8 5128 732; B 8 8 5532 732; B 8 8 5556 732; B 8 8 5572 732; B 8 8 5588 732; B 8 8 5604 732; B 8 8 5620 732; B 8 8 5636 732; B 8 8 5652 732; B 8 8 5668 732; B 8 8 5684 732; B 8 8 5700 732; B 8 8 5716 732; B 8 8 5732 732; B 8 8 5748 732; B 8 8 5764 732; B 8 8 5780 732; B 8 8 5796 732; B 8 8 5812 732; B 8 8 5828 732; B 8 8 5844 732; B 8 8 5860 732; B 8 8 5876 732; B 8 8 5892 732; B 8 8 5908 732; B 8 8 5924 732; B 8 8 5940 732; B 8 8 5956 732; B 8 8 6324 728; B 8 8 6348 732; B 8 8 6364 732; B 8 8 6380 732; B 8 8 6396 732; B 8 8 6412 732; B 8 8 6428 732; B 8 8 6444 732; B 8 8 6460 732; B 8 8 6476 732; B 8 8 6492 732; B 8 8 6508 732; B 8 8 6524 732; B 8 8 6540 732; B 8 8 6556 732; B 8 8 6580 732; B 8 8 1924 712; B 8 8 2472 712; B 8 8 3256 716; B 8 8 3640 712; B 8 8 5132 712; B 8 8 5532 716; B 8 8 6324 712; B 8 8 6580 716; B 8 8 2092 704; B 8 8 1924 696; B 8 8 2472 696; B 8 8 3256 700; B 8 8 3640 696; B 8 8 5132 696; B 8 8 5532 700; B 8 8 5964 704; B 8 8 6324 696; B 8 8 6580 700; B 8 8 1212 680; B 8 8 1232 684; B 8 8 1248 684; B 8 8 1264 684; B 8 8 1280 684; B 8 8 1372 684; B 8 8 2092 688; B 8 8 1924 680; B 8 8 2008 680; B 8 8 2472 680; B 8 8 2556 680; B 8 8 2644 680; B 8 8 2732 680; B 8 8 2820 680; B 8 8 2908 680; B 8 8 2996 680; B 8 8 3084 680; B 8 8 3172 680; B 8 8 3256 684; B 8 8 3640 680; B 8 8 3724 680; B 8 8 3812 680; B 8 8 3900 680; B 8 8 3988 680; B 8 8 4076 680; B 8 8 4164 680; B 8 8 4252 680; B 8 8 4340 680; B 8 8 4428 680; B 8 8 4516 680; B 8 8 4604 680; B 8 8 4692 680; B 8 8 4784 680; B 8 8 4872 680; B 8 8 4960 680; B 8 8 5048 680; B 8 8 5132 680; B 8 8 5532 684; B 8 8 5964 688; B 8 8 5616 680; B 8 8 5704 680; B 8 8 5792 680; B 8 8 5880 680; B 8 8 6324 680; B 8 8 6408 680; B 8 8 6496 680; B 8 8 6580 684; B 8 8 1964 672; B 8 8 2052 672; B 8 8 2092 672; B 8 8 2512 672; B 8 8 2600 672; B 8 8 2688 672; B 8 8 2776 672; B 8 8 2864 672; B 8 8 2952 672; B 8 8 3040 672; B 8 8 3128 672; B 8 8 3216 672; B 8 8 1212 664; B 8 8 1924 664; B 8 8 2472 664; B 8 8 3256 668; B 8 8 3680 672; B 8 8 3768 672; B 8 8 3856 672; B 8 8 3944 672; B 8 8 4032 672; B 8 8 4120 672; B 8 8 4208 672; B 8 8 4296 672; B 8 8 4384 672; B 8 8 4472 672; B 8 8 4560 672; B 8 8 4648 672; B 8 8 4736 672; B 8 8 4828 672; B 8 8 4916 672; B 8 8 5004 672; B 8 8 5092 672; B 8 8 3640 664; B 8 8 5132 664; B 8 8 5532 668; B 8 8 5572 672; B 8 8 5660 672; B 8 8 5748 672; B 8 8 5836 672; B 8 8 5924 672; B 8 8 5964 672; B 8 8 6364 672; B 8 8 6452 672; B 8 8 6540 672; B 8 8 6324 664; B 8 8 6580 668; B 8 8 1212 648; B 8 8 1380 652; B 8 8 1964 656; B 8 8 2052 656; B 8 8 2092 656; B 8 8 2512 656; B 8 8 2600 656; B 8 8 2688 656; B 8 8 2776 656; B 8 8 2864 656; B 8 8 2952 656; B 8 8 3040 656; B 8 8 3128 656; B 8 8 3216 656; B 8 8 1924 648; B 8 8 2472 648; B 8 8 3256 652; B 8 8 3680 656; B 8 8 3768 656; B 8 8 3856 656; B 8 8 3944 656; B 8 8 4032 656; B 8 8 4120 656; B 8 8 4208 656; B 8 8 4296 656; B 8 8 4384 656; B 8 8 4472 656; B 8 8 4560 656; B 8 8 4648 656; B 8 8 4736 656; B 8 8 4828 656; B 8 8 4916 656; B 8 8 5004 656; B 8 8 5092 656; B 8 8 3640 648; B 8 8 5132 648; B 8 8 5532 652; B 8 8 5572 656; B 8 8 5660 656; B 8 8 5748 656; B 8 8 5836 656; B 8 8 5924 656; B 8 8 5964 656; B 8 8 6364 656; B 8 8 6452 656; B 8 8 6540 656; B 8 8 6324 648; B 8 8 6580 652; B 8 8 1212 632; B 8 8 1252 632; B 8 8 1296 632; B 8 8 1340 632; B 8 8 1380 636; B 8 8 1964 640; B 8 8 1924 632; B 8 8 2008 636; B 8 8 2052 640; B 8 8 2092 640; B 8 8 2512 640; B 8 8 2472 632; B 8 8 2556 636; B 8 8 2600 640; B 8 8 2644 636; B 8 8 2688 640; B 8 8 2732 636; B 8 8 2776 640; B 8 8 2820 636; B 8 8 2864 640; B 8 8 2908 636; B 8 8 2952 640; B 8 8 2996 636; B 8 8 3040 640; B 8 8 3084 636; B 8 8 3128 640; B 8 8 3172 636; B 8 8 3216 640; B 8 8 3256 636; B 8 8 3680 640; B 8 8 3640 632; B 8 8 3724 636; B 8 8 3768 640; B 8 8 3812 636; B 8 8 3856 640; B 8 8 3900 636; B 8 8 3944 640; B 8 8 3988 636; B 8 8 4032 640; B 8 8 4076 636; B 8 8 4120 640; B 8 8 4164 636; B 8 8 4208 640; B 8 8 4252 636; B 8 8 4296 640; B 8 8 4340 636; B 8 8 4384 640; B 8 8 4428 636; B 8 8 4472 640; B 8 8 4516 636; B 8 8 4560 640; B 8 8 4604 636; B 8 8 4648 640; B 8 8 4692 636; B 8 8 4736 640; B 8 8 4784 636; B 8 8 4828 640; B 8 8 4872 636; B 8 8 4916 640; B 8 8 4960 636; B 8 8 5004 640; B 8 8 5048 636; B 8 8 5092 640; B 8 8 5132 632; B 8 8 5532 636; B 8 8 5572 640; B 8 8 5616 636; B 8 8 5660 640; B 8 8 5704 636; B 8 8 5748 640; B 8 8 5792 636; B 8 8 5836 640; B 8 8 5880 636; B 8 8 5924 640; B 8 8 5964 640; B 8 8 6364 640; B 8 8 6324 632; B 8 8 6408 636; B 8 8 6452 640; B 8 8 6496 636; B 8 8 6540 640; B 8 8 6580 636; B 8 8 1212 616; B 8 8 1380 620; B 8 8 2092 624; B 8 8 1924 616; B 8 8 2472 616; B 8 8 3256 620; B 8 8 3640 616; B 8 8 5132 616; B 8 8 5532 620; B 8 8 5964 624; B 8 8 6324 616; B 8 8 6580 620; B 8 8 1212 600; B 8 8 1380 604; B 8 8 2092 608; B 8 8 1924 600; B 8 8 2472 600; B 8 8 3256 604; B 8 8 3640 600; B 8 8 5132 600; B 8 8 5532 604; B 8 8 5964 608; B 8 8 6324 600; B 8 8 6580 604; B 8 8 1216 580; B 8 8 1232 580; B 8 8 1248 580; B 8 8 1264 580; B 8 8 1280 580; B 8 8 1296 580; B 8 8 1312 580; B 8 8 1328 580; B 8 8 1344 580; B 8 8 1360 580; B 8 8 1376 580; B 8 8 1924 584; B 8 8 1944 584; B 8 8 1960 584; B 8 8 1976 584; B 8 8 1992 584; B 8 8 2008 584; B 8 8 2024 584; B 8 8 2040 584; B 8 8 2056 584; B 8 8 2072 584; B 8 8 2088 584; B 8 8 2472 584; B 8 8 2496 584; B 8 8 2512 584; B 8 8 2528 584; B 8 8 2544 584; B 8 8 2560 584; B 8 8 2576 584; B 8 8 2592 584; B 8 8 2608 584; B 8 8 2624 584; B 8 8 2640 584; B 8 8 2656 584; B 8 8 2672 584; B 8 8 2688 584; B 8 8 2704 584; B 8 8 2720 584; B 8 8 2736 584; B 8 8 2752 584; B 8 8 2768 584; B 8 8 2784 584; B 8 8 2800 584; B 8 8 2816 584; B 8 8 2832 584; B 8 8 2848 584; B 8 8 2864 584; B 8 8 2880 584; B 8 8 2896 584; B 8 8 2912 584; B 8 8 2928 584; B 8 8 2944 584; B 8 8 2960 584; B 8 8 2976 584; B 8 8 2992 584; B 8 8 3008 584; B 8 8 3024 584; B 8 8 3040 584; B 8 8 3056 584; B 8 8 3072 584; B 8 8 3088 584; B 8 8 3104 584; B 8 8 3120 584; B 8 8 3136 584; B 8 8 3152 584; B 8 8 3248 584; B 8 8 3640 584; B 8 8 3664 584; B 8 8 3680 584; B 8 8 3696 584; B 8 8 3712 584; B 8 8 3728 584; B 8 8 3744 584; B 8 8 3760 584; B 8 8 3776 584; B 8 8 3792 584; B 8 8 3808 584; B 8 8 3824 584; B 8 8 3840 584; B 8 8 3856 584; B 8 8 3872 584; B 8 8 3888 584; B 8 8 3904 584; B 8 8 3920 584; B 8 8 3936 584; B 8 8 3952 584; B 8 8 3968 584; B 8 8 3984 584; B 8 8 4000 584; B 8 8 4016 584; B 8 8 4032 584; B 8 8 4048 584; B 8 8 4064 584; B 8 8 4080 584; B 8 8 4096 584; B 8 8 4112 584; B 8 8 4128 584; B 8 8 4144 584; B 8 8 4160 584; B 8 8 4176 584; B 8 8 4192 584; B 8 8 4208 584; B 8 8 4224 584; B 8 8 4240 584; B 8 8 4256 584; B 8 8 4272 584; B 8 8 4288 584; B 8 8 4304 584; B 8 8 4320 584; B 8 8 4336 584; B 8 8 4352 584; B 8 8 4368 584; B 8 8 4384 584; B 8 8 4400 584; B 8 8 4416 584; B 8 8 4432 584; B 8 8 4448 584; B 8 8 4464 584; B 8 8 4480 584; B 8 8 4496 584; B 8 8 4512 584; B 8 8 4528 584; B 8 8 4544 584; B 8 8 4560 584; B 8 8 4576 584; B 8 8 4592 584; B 8 8 4608 584; B 8 8 4624 584; B 8 8 4640 584; B 8 8 4656 584; B 8 8 4672 584; B 8 8 4688 584; B 8 8 4704 584; B 8 8 4720 584; B 8 8 4736 584; B 8 8 4752 584; B 8 8 4768 584; B 8 8 4784 584; B 8 8 4800 584; B 8 8 4816 584; B 8 8 4832 584; B 8 8 4848 584; B 8 8 4864 584; B 8 8 4880 584; B 8 8 4896 584; B 8 8 4912 584; B 8 8 4928 584; B 8 8 4944 584; B 8 8 4960 584; B 8 8 4976 584; B 8 8 4992 584; B 8 8 5008 584; B 8 8 5024 584; B 8 8 5040 584; B 8 8 5056 584; B 8 8 5072 584; B 8 8 5088 584; B 8 8 5104 584; B 8 8 5132 584; B 8 8 5536 584; B 8 8 5628 584; B 8 8 5644 584; B 8 8 5660 584; B 8 8 5676 584; B 8 8 5692 584; B 8 8 5708 584; B 8 8 5724 584; B 8 8 5740 584; B 8 8 5756 584; B 8 8 5772 584; B 8 8 5788 584; B 8 8 5804 584; B 8 8 5820 584; B 8 8 5836 584; B 8 8 5852 584; B 8 8 5868 584; B 8 8 5884 584; B 8 8 5900 584; B 8 8 5916 584; B 8 8 5932 584; B 8 8 5948 584; B 8 8 5964 584; B 8 8 6324 584; B 8 8 6348 584; B 8 8 6364 584; B 8 8 6380 584; B 8 8 6396 584; B 8 8 6412 584; B 8 8 6428 584; B 8 8 6444 584; B 8 8 6460 584; B 8 8 6476 584; B 8 8 6572 584; L CCA; B 8 8 656 1184; B 8 8 684 1184; B 8 8 2256 1184; B 8 8 2284 1184; B 8 8 3856 1184; B 8 8 3884 1184; B 8 8 5456 1184; B 8 8 5484 1184; B 8 8 7056 1184; B 8 8 7084 1184; B 8 8 656 1156; B 8 8 684 1156; B 8 8 2256 1156; B 8 8 2284 1156; B 8 8 3856 1156; B 8 8 3884 1156; B 8 8 5456 1156; B 8 8 5484 1156; B 8 8 7056 1156; B 8 8 7084 1156; B 8 8 656 1128; B 8 8 684 1128; B 8 8 2256 1128; B 8 8 2284 1128; B 8 8 3856 1128; B 8 8 3884 1128; B 8 8 5456 1128; B 8 8 5484 1128; B 8 8 7056 1128; B 8 8 7084 1128; B 8 8 1448 184; B 8 8 1476 184; B 8 8 3048 184; B 8 8 3076 184; B 8 8 4648 184; B 8 8 4676 184; B 8 8 6248 184; B 8 8 6276 184; B 8 8 1448 156; B 8 8 1476 156; B 8 8 3048 156; B 8 8 3076 156; B 8 8 4648 156; B 8 8 4676 156; B 8 8 6248 156; B 8 8 6276 156; B 8 8 1448 128; B 8 8 1476 128; B 8 8 3048 128; B 8 8 3076 128; B 8 8 4648 128; B 8 8 4676 128; B 8 8 6248 128; B 8 8 6276 128; L CBA; B 112 48 1296 632; B 112 92 2008 658; B 728 92 2864 658; B 1436 92 4386 658; B 376 92 5748 658; B 200 92 6452 658; L CSN; B 88 4 1972 750; B 112 36 1960 730; B 40 28 2084 738; B 800 4 2876 750; B 1416 4 4348 750; B 48 12 2088 718; B 88 4 1256 702; B 108 36 1246 682; B 40 32 1372 688; B 48 8 1376 668; B 40 64 1212 632; B 40 64 1380 632; B 208 16 1296 592; B 40 108 1924 658; B 40 108 2092 658; B 208 16 2008 596; B 824 36 2864 730; B 40 108 2472 658; B 40 108 3256 658; B 204 4 1294 582; B 200 20 1296 570; B 204 24 2006 576; B 720 40 2812 584; B 48 20 3252 594; B 1436 36 4338 730; B 40 20 5128 742; B 44 20 5130 722; B 40 108 3640 658; B 40 108 5132 658; B 40 20 3248 574; B 1532 40 4386 584; B 464 28 5744 738; B 272 4 6464 750; B 472 12 5748 718; B 40 108 5532 658; B 40 108 5964 658; B 44 20 5534 594; B 40 20 5536 574; B 376 40 5796 584; B 296 36 6452 730; B 40 108 6324 658; B 40 108 6580 658; B 192 40 6400 584; B 48 20 6576 594; B 40 20 6572 574; L CSN; B 208 40 2008 732; B 208 40 1296 684; B 40 64 1212 632; B 32 32 1296 632; B 40 64 1380 632; B 208 40 1296 580; B 40 108 1924 658; B 32 32 2008 680; B 32 32 2008 636; B 40 108 2092 658; B 208 40 2008 584; B 824 40 2864 732; B 40 108 2472 658; B 32 32 2556 680; B 32 32 2644 680; B 32 32 2732 680; B 32 32 2820 680; B 32 32 2908 680; B 32 32 2996 680; B 32 32 3084 680; B 32 32 3172 680; B 32 32 2556 636; B 32 32 2644 636; B 32 32 2732 636; B 32 32 2820 636; B 32 32 2908 636; B 32 32 2996 636; B 32 32 3084 636; B 32 32 3172 636; B 40 108 3256 658; B 824 40 2864 584; B 1532 40 4386 732; B 40 108 3640 658; B 32 32 3724 680; B 32 32 3812 680; B 32 32 3900 680; B 32 32 3988 680; B 32 32 4076 680; B 32 32 4164 680; B 32 32 4252 680; B 32 32 4340 680; B 32 32 4428 680; B 32 32 4516 680; B 32 32 4604 680; B 32 32 4692 680; B 32 32 4784 680; B 32 32 4872 680; B 32 32 4960 680; B 32 32 5048 680; B 32 32 3724 636; B 32 32 3812 636; B 32 32 3900 636; B 32 32 3988 636; B 32 32 4076 636; B 32 32 4164 636; B 32 32 4252 636; B 32 32 4340 636; B 32 32 4428 636; B 32 32 4516 636; B 32 32 4604 636; B 32 32 4692 636; B 32 32 4784 636; B 32 32 4872 636; B 32 32 4960 636; B 32 32 5048 636; B 40 108 5132 658; B 1532 40 4386 584; B 472 40 5748 732; B 40 108 5532 658; B 32 32 5616 680; B 32 32 5704 680; B 32 32 5792 680; B 32 32 5880 680; B 32 32 5616 636; B 32 32 5704 636; B 32 32 5792 636; B 32 32 5880 636; B 40 108 5964 658; B 472 40 5748 584; B 296 40 6452 732; B 40 108 6324 658; B 32 32 6408 680; B 32 32 6496 680; B 32 32 6408 636; B 32 32 6496 636; B 40 108 6580 658; B 296 40 6452 584; L CSP; B 60 88 670 1156; B 60 88 2270 1156; B 60 88 3870 1156; B 60 88 5470 1156; B 60 88 7070 1156; B 24 24 1252 632; B 24 24 1340 632; B 24 56 1964 656; B 24 56 2052 656; B 24 56 2512 656; B 24 56 2600 656; B 24 56 2688 656; B 24 56 2776 656; B 24 56 2864 656; B 24 56 2952 656; B 24 56 3040 656; B 24 56 3128 656; B 24 56 3216 656; B 24 56 3680 656; B 24 56 3768 656; B 24 56 3856 656; B 24 56 3944 656; B 24 56 4032 656; B 24 56 4120 656; B 24 56 4208 656; B 24 56 4296 656; B 24 56 4384 656; B 24 56 4472 656; B 24 56 4560 656; B 24 56 4648 656; B 24 56 4736 656; B 24 56 4828 656; B 24 56 4916 656; B 24 56 5004 656; B 24 56 5092 656; B 24 56 5572 656; B 24 56 5660 656; B 24 56 5748 656; B 24 56 5836 656; B 24 56 5924 656; B 24 56 6364 656; B 24 56 6452 656; B 24 56 6540 656; B 60 88 1462 156; B 60 88 3062 156; B 60 88 4662 156; B 60 88 6262 156; L COG; B 376 376 264 1056; B 376 376 1064 1056; B 376 376 1864 1056; B 376 376 2664 1056; B 376 376 3464 1056; B 376 376 4264 1056; B 376 376 5064 1056; B 376 376 5864 1056; B 376 376 6664 1056; B 376 376 7464 1056; B 376 376 264 256; B 376 376 1064 256; B 376 376 1864 256; B 376 376 2664 256; B 376 376 3464 256; B 376 376 4264 256; B 376 376 5064 256; B 376 376 5864 256; B 376 376 6664 256; B 376 376 7464 256; DF; C 1; End magic-8.0.210/scmos/examples/bipolar/npn12_array_core.cif0000644000175000001440000005224410751423606021706 0ustar timusers( @@user : hansford ); ( @@machine : tesla.isi.edu ); ( @@source : npn_array_core.mag ); ( @@tool : Magic 6.4.4 ); ( @@patch : 1 ); ( @@patchnames : release-6.4, linux1 ); ( @@compiled : Thu Sep 22 16:55:06 PDT 1994 ); ( @@technology : scmos ); ( @@version : 8.0.0 ); ( @@techdesc : MOSIS Scalable CMOS Technology for Orbit, AMI, and VTI ); ( @@style : lambda=0.6(gen) ); ( @@date : Fri Oct 7 16:25:52 1994 ); DS 1 30 2; 9 npn_array_core; L CWN; B 216 152 432 456; B 216 196 1144 482; B 832 196 2000 482; B 1540 196 3522 482; B 480 196 4884 482; B 304 196 5588 482; L CMF; B 16 4 312 574; B 16 4 648 574; B 152 16 380 564; B 88 16 384 508; B 16 88 348 456; B 16 68 448 522; B 32 12 440 482; B 188 16 562 564; B 16 28 388 450; B 16 28 432 462; B 16 120 476 496; B 88 16 1096 556; B 28 16 510 508; B 104 12 432 430; B 16 88 516 456; B 184 16 432 404; B 16 132 1060 482; B 16 48 1160 552; B 32 16 1152 520; B 16 72 1100 476; B 16 60 1144 482; B 16 136 1188 508; B 16 12 2392 570; B 28 16 1222 556; B 104 12 1144 434; B 16 132 1228 482; B 184 16 1144 408; B 800 16 2000 556; B 16 132 1608 482; B 720 12 2000 530; B 16 72 1648 488; B 16 72 1692 476; B 16 72 1736 488; B 16 72 1780 476; B 16 72 1824 488; B 16 72 1868 476; B 16 72 1912 488; B 16 72 1956 476; B 16 72 2000 488; B 16 72 2044 476; B 16 72 2088 488; B 16 72 2132 476; B 16 72 2176 488; B 16 72 2220 476; B 16 72 2264 488; B 16 72 2308 476; B 648 12 2008 434; B 700 16 1950 408; B 16 8 484 392; B 16 12 1228 394; B 16 40 2324 408; B 16 136 2352 456; B 16 132 2392 482; B 28 16 2386 408; B 1412 16 3474 556; B 16 132 2776 482; B 16 40 4200 556; B 1356 12 3530 530; B 16 72 2816 476; B 16 72 2860 488; B 16 72 2904 476; B 16 72 2948 488; B 16 72 2992 476; B 16 72 3036 488; B 16 72 3080 476; B 16 72 3124 488; B 16 72 3168 476; B 16 72 3212 488; B 16 72 3256 476; B 16 72 3300 488; B 16 72 3344 476; B 16 72 3388 488; B 16 72 3432 476; B 16 72 3476 488; B 16 72 3520 476; B 16 72 3564 488; B 16 72 3608 476; B 16 72 3652 488; B 16 72 3696 476; B 16 72 3740 488; B 16 72 3784 476; B 16 72 3828 488; B 16 72 3872 476; B 16 72 3920 488; B 16 72 3964 476; B 16 72 4008 488; B 16 72 4052 476; B 16 72 4096 488; B 16 72 4140 476; B 16 72 4184 488; B 16 136 4228 508; B 16 12 4788 570; B 16 12 5436 570; B 24 16 4264 556; B 1428 12 3522 434; B 16 132 4268 482; B 1508 16 3522 408; B 448 16 4884 556; B 296 16 5576 556; B 16 132 4668 482; B 368 12 4884 530; B 28 16 4674 408; B 16 12 3512 394; B 16 136 4708 456; B 16 72 4752 476; B 16 72 4796 488; B 16 72 4840 476; B 16 72 4884 488; B 16 72 4928 476; B 16 72 4972 488; B 16 72 5016 476; B 16 72 5060 488; B 296 12 4876 434; B 16 40 4736 408; B 16 132 5100 482; B 352 16 4932 408; B 16 132 5460 482; B 192 12 5588 530; B 16 72 5500 488; B 16 72 5544 476; B 16 72 5588 488; B 16 72 5632 476; B 120 12 5596 434; B 176 16 5540 408; B 16 40 5648 408; B 16 136 5676 456; B 16 132 5716 482; B 28 16 5710 408; L CAA; B 192 24 1144 556; B 192 24 432 508; B 24 80 348 456; B 16 16 432 456; B 24 80 516 456; B 192 24 432 404; B 24 124 1060 482; B 16 16 1144 504; B 16 16 1144 460; B 24 124 1228 482; B 192 24 1144 408; B 808 24 2000 556; B 24 124 1608 482; B 16 16 1692 504; B 16 16 1780 504; B 16 16 1868 504; B 16 16 1956 504; B 16 16 2044 504; B 16 16 2132 504; B 16 16 2220 504; B 16 16 2308 504; B 16 16 1692 460; B 16 16 1780 460; B 16 16 1868 460; B 16 16 1956 460; B 16 16 2044 460; B 16 16 2132 460; B 16 16 2220 460; B 16 16 2308 460; B 24 124 2392 482; B 808 24 2000 408; B 1516 24 3522 556; B 24 124 2776 482; B 16 16 2860 504; B 16 16 2948 504; B 16 16 3036 504; B 16 16 3124 504; B 16 16 3212 504; B 16 16 3300 504; B 16 16 3388 504; B 16 16 3476 504; B 16 16 3564 504; B 16 16 3652 504; B 16 16 3740 504; B 16 16 3828 504; B 16 16 3920 504; B 16 16 4008 504; B 16 16 4096 504; B 16 16 4184 504; B 16 16 2860 460; B 16 16 2948 460; B 16 16 3036 460; B 16 16 3124 460; B 16 16 3212 460; B 16 16 3300 460; B 16 16 3388 460; B 16 16 3476 460; B 16 16 3564 460; B 16 16 3652 460; B 16 16 3740 460; B 16 16 3828 460; B 16 16 3920 460; B 16 16 4008 460; B 16 16 4096 460; B 16 16 4184 460; B 24 124 4268 482; B 1516 24 3522 408; B 456 24 4884 556; B 24 124 4668 482; B 16 16 4752 504; B 16 16 4840 504; B 16 16 4928 504; B 16 16 5016 504; B 16 16 4752 460; B 16 16 4840 460; B 16 16 4928 460; B 16 16 5016 460; B 24 124 5100 482; B 456 24 4884 408; B 280 24 5588 556; B 24 124 5460 482; B 16 16 5544 504; B 16 16 5632 504; B 16 16 5544 460; B 16 16 5632 460; B 24 124 5716 482; B 280 24 5588 408; L CCA; B 8 8 1144 504; B 8 8 1692 504; B 8 8 1780 504; B 8 8 1868 504; B 8 8 1956 504; B 8 8 2044 504; B 8 8 2132 504; B 8 8 2220 504; B 8 8 2308 504; B 8 8 2860 504; B 8 8 2948 504; B 8 8 3036 504; B 8 8 3124 504; B 8 8 3212 504; B 8 8 3300 504; B 8 8 3388 504; B 8 8 3476 504; B 8 8 3564 504; B 8 8 3652 504; B 8 8 3740 504; B 8 8 3828 504; B 8 8 3920 504; B 8 8 4008 504; B 8 8 4096 504; B 8 8 4184 504; B 8 8 4752 504; B 8 8 4840 504; B 8 8 4928 504; B 8 8 5016 504; B 8 8 5544 504; B 8 8 5632 504; B 8 8 1100 496; B 8 8 1188 496; B 8 8 1648 496; B 8 8 1736 496; B 8 8 1824 496; B 8 8 1912 496; B 8 8 2000 496; B 8 8 2088 496; B 8 8 2176 496; B 8 8 2264 496; B 8 8 2352 496; B 8 8 2816 496; B 8 8 2904 496; B 8 8 2992 496; B 8 8 3080 496; B 8 8 3168 496; B 8 8 3256 496; B 8 8 3344 496; B 8 8 3432 496; B 8 8 3520 496; B 8 8 3608 496; B 8 8 3696 496; B 8 8 3784 496; B 8 8 3872 496; B 8 8 3964 496; B 8 8 4052 496; B 8 8 4140 496; B 8 8 4228 496; B 8 8 4708 496; B 8 8 4796 496; B 8 8 4884 496; B 8 8 4972 496; B 8 8 5060 496; B 8 8 5500 496; B 8 8 5588 496; B 8 8 5676 496; B 8 8 1100 480; B 8 8 1188 480; B 8 8 1648 480; B 8 8 1736 480; B 8 8 1824 480; B 8 8 1912 480; B 8 8 2000 480; B 8 8 2088 480; B 8 8 2176 480; B 8 8 2264 480; B 8 8 2352 480; B 8 8 2816 480; B 8 8 2904 480; B 8 8 2992 480; B 8 8 3080 480; B 8 8 3168 480; B 8 8 3256 480; B 8 8 3344 480; B 8 8 3432 480; B 8 8 3520 480; B 8 8 3608 480; B 8 8 3696 480; B 8 8 3784 480; B 8 8 3872 480; B 8 8 3964 480; B 8 8 4052 480; B 8 8 4140 480; B 8 8 4228 480; B 8 8 4708 480; B 8 8 4796 480; B 8 8 4884 480; B 8 8 4972 480; B 8 8 5060 480; B 8 8 5500 480; B 8 8 5588 480; B 8 8 5676 480; B 8 8 1100 464; B 8 8 388 456; B 8 8 432 456; B 8 8 476 456; B 8 8 1144 460; B 8 8 1188 464; B 8 8 1648 464; B 8 8 1692 460; B 8 8 1736 464; B 8 8 1780 460; B 8 8 1824 464; B 8 8 1868 460; B 8 8 1912 464; B 8 8 1956 460; B 8 8 2000 464; B 8 8 2044 460; B 8 8 2088 464; B 8 8 2132 460; B 8 8 2176 464; B 8 8 2220 460; B 8 8 2264 464; B 8 8 2308 460; B 8 8 2352 464; B 8 8 2816 464; B 8 8 2860 460; B 8 8 2904 464; B 8 8 2948 460; B 8 8 2992 464; B 8 8 3036 460; B 8 8 3080 464; B 8 8 3124 460; B 8 8 3168 464; B 8 8 3212 460; B 8 8 3256 464; B 8 8 3300 460; B 8 8 3344 464; B 8 8 3388 460; B 8 8 3432 464; B 8 8 3476 460; B 8 8 3520 464; B 8 8 3564 460; B 8 8 3608 464; B 8 8 3652 460; B 8 8 3696 464; B 8 8 3740 460; B 8 8 3784 464; B 8 8 3828 460; B 8 8 3872 464; B 8 8 3920 460; B 8 8 3964 464; B 8 8 4008 460; B 8 8 4052 464; B 8 8 4096 460; B 8 8 4140 464; B 8 8 4184 460; B 8 8 4228 464; B 8 8 4708 464; B 8 8 4752 460; B 8 8 4796 464; B 8 8 4840 460; B 8 8 4884 464; B 8 8 4928 460; B 8 8 4972 464; B 8 8 5016 460; B 8 8 5060 464; B 8 8 5500 464; B 8 8 5544 460; B 8 8 5588 464; B 8 8 5632 460; B 8 8 5676 464; L CCA; B 8 8 1060 554; B 8 8 1082 556; B 8 8 1098 556; B 8 8 1114 556; B 8 8 1130 556; B 8 8 1222 556; B 8 8 1608 554; B 8 8 1632 556; B 8 8 1648 556; B 8 8 1664 556; B 8 8 1680 556; B 8 8 1696 556; B 8 8 1712 556; B 8 8 1728 556; B 8 8 1744 556; B 8 8 1760 556; B 8 8 1776 556; B 8 8 1792 556; B 8 8 1808 556; B 8 8 1824 556; B 8 8 1840 556; B 8 8 1856 556; B 8 8 1872 556; B 8 8 1888 556; B 8 8 1904 556; B 8 8 1920 556; B 8 8 1936 556; B 8 8 1952 556; B 8 8 1968 556; B 8 8 1984 556; B 8 8 2000 556; B 8 8 2016 556; B 8 8 2032 556; B 8 8 2048 556; B 8 8 2064 556; B 8 8 2080 556; B 8 8 2096 556; B 8 8 2112 556; B 8 8 2128 556; B 8 8 2144 556; B 8 8 2160 556; B 8 8 2176 556; B 8 8 2192 556; B 8 8 2208 556; B 8 8 2224 556; B 8 8 2240 556; B 8 8 2256 556; B 8 8 2272 556; B 8 8 2288 556; B 8 8 2304 556; B 8 8 2320 556; B 8 8 2336 556; B 8 8 2352 556; B 8 8 2368 556; B 8 8 2392 556; B 8 8 2776 554; B 8 8 2796 556; B 8 8 2812 556; B 8 8 2828 556; B 8 8 2844 556; B 8 8 2860 556; B 8 8 2876 556; B 8 8 2892 556; B 8 8 2908 556; B 8 8 2924 556; B 8 8 2940 556; B 8 8 2956 556; B 8 8 2972 556; B 8 8 2988 556; B 8 8 3004 556; B 8 8 3020 556; B 8 8 3036 556; B 8 8 3052 556; B 8 8 3068 556; B 8 8 3084 556; B 8 8 3100 556; B 8 8 3116 556; B 8 8 3132 556; B 8 8 3148 556; B 8 8 3164 556; B 8 8 3180 556; B 8 8 3196 556; B 8 8 3212 556; B 8 8 3228 556; B 8 8 3244 556; B 8 8 3260 556; B 8 8 3276 556; B 8 8 3292 556; B 8 8 3308 556; B 8 8 3324 556; B 8 8 3340 556; B 8 8 3356 556; B 8 8 3372 556; B 8 8 3388 556; B 8 8 3404 556; B 8 8 3420 556; B 8 8 3436 556; B 8 8 3452 556; B 8 8 3468 556; B 8 8 3484 556; B 8 8 3500 556; B 8 8 3516 556; B 8 8 3532 556; B 8 8 3548 556; B 8 8 3564 556; B 8 8 3580 556; B 8 8 3596 556; B 8 8 3612 556; B 8 8 3628 556; B 8 8 3644 556; B 8 8 3660 556; B 8 8 3676 556; B 8 8 3692 556; B 8 8 3708 556; B 8 8 3724 556; B 8 8 3740 556; B 8 8 3756 556; B 8 8 3772 556; B 8 8 3788 556; B 8 8 3804 556; B 8 8 3820 556; B 8 8 3836 556; B 8 8 3852 556; B 8 8 3868 556; B 8 8 3884 556; B 8 8 3900 556; B 8 8 3916 556; B 8 8 3932 556; B 8 8 3948 556; B 8 8 3964 556; B 8 8 3980 556; B 8 8 3996 556; B 8 8 4012 556; B 8 8 4028 556; B 8 8 4044 556; B 8 8 4060 556; B 8 8 4076 556; B 8 8 4092 556; B 8 8 4108 556; B 8 8 4124 556; B 8 8 4140 556; B 8 8 4156 556; B 8 8 4172 556; B 8 8 4264 556; B 8 8 4668 556; B 8 8 4692 556; B 8 8 4708 556; B 8 8 4724 556; B 8 8 4740 556; B 8 8 4756 556; B 8 8 4772 556; B 8 8 4788 556; B 8 8 4804 556; B 8 8 4820 556; B 8 8 4836 556; B 8 8 4852 556; B 8 8 4868 556; B 8 8 4884 556; B 8 8 4900 556; B 8 8 4916 556; B 8 8 4932 556; B 8 8 4948 556; B 8 8 4964 556; B 8 8 4980 556; B 8 8 4996 556; B 8 8 5012 556; B 8 8 5028 556; B 8 8 5044 556; B 8 8 5060 556; B 8 8 5076 556; B 8 8 5092 556; B 8 8 5460 552; B 8 8 5484 556; B 8 8 5500 556; B 8 8 5516 556; B 8 8 5532 556; B 8 8 5548 556; B 8 8 5564 556; B 8 8 5580 556; B 8 8 5596 556; B 8 8 5612 556; B 8 8 5628 556; B 8 8 5644 556; B 8 8 5660 556; B 8 8 5676 556; B 8 8 5692 556; B 8 8 5716 556; B 8 8 1060 538; B 8 8 1608 538; B 8 8 2392 540; B 8 8 2776 538; B 8 8 1228 530; B 8 8 4268 536; B 8 8 4668 540; B 8 8 5460 536; B 8 8 5716 540; B 8 8 1060 522; B 8 8 1608 522; B 8 8 2392 524; B 8 8 2776 522; B 8 8 348 506; B 8 8 370 508; B 8 8 386 508; B 8 8 402 508; B 8 8 418 508; B 8 8 510 508; B 8 8 1228 514; B 8 8 4268 520; B 8 8 4668 524; B 8 8 5100 528; B 8 8 5460 520; B 8 8 5716 524; B 8 8 1060 506; B 8 8 1608 506; B 8 8 2392 508; B 8 8 2776 506; B 8 8 1228 498; B 8 8 4268 504; B 8 8 4668 508; B 8 8 5100 512; B 8 8 5460 504; B 8 8 5716 508; B 8 8 348 490; B 8 8 1060 490; B 8 8 1608 490; B 8 8 2392 492; B 8 8 2776 490; B 8 8 516 482; B 8 8 1228 482; B 8 8 4268 488; B 8 8 4668 492; B 8 8 5100 496; B 8 8 5460 488; B 8 8 5716 492; B 8 8 348 474; B 8 8 1060 474; B 8 8 1608 474; B 8 8 2392 476; B 8 8 2776 474; B 8 8 516 466; B 8 8 1228 466; B 8 8 4268 472; B 8 8 4668 476; B 8 8 5100 480; B 8 8 5460 472; B 8 8 5716 476; B 8 8 348 458; B 8 8 1060 458; B 8 8 1608 458; B 8 8 2392 460; B 8 8 2776 458; B 8 8 516 450; B 8 8 1228 450; B 8 8 4268 456; B 8 8 4668 460; B 8 8 5100 464; B 8 8 5460 456; B 8 8 5716 460; B 8 8 348 442; B 8 8 1060 442; B 8 8 1608 442; B 8 8 2392 444; B 8 8 2776 442; B 8 8 516 434; B 8 8 1228 434; B 8 8 4268 440; B 8 8 4668 444; B 8 8 5100 448; B 8 8 5460 440; B 8 8 5716 444; B 8 8 348 426; B 8 8 1060 426; B 8 8 1608 426; B 8 8 2392 428; B 8 8 2776 426; B 8 8 4268 424; B 8 8 4668 428; B 8 8 5100 432; B 8 8 5460 424; B 8 8 5716 428; B 8 8 350 404; B 8 8 366 404; B 8 8 382 404; B 8 8 398 404; B 8 8 414 404; B 8 8 430 404; B 8 8 446 404; B 8 8 462 404; B 8 8 478 404; B 8 8 494 404; B 8 8 510 404; B 8 8 1060 410; B 8 8 1082 408; B 8 8 1098 408; B 8 8 1114 408; B 8 8 1130 408; B 8 8 1146 408; B 8 8 1162 408; B 8 8 1178 408; B 8 8 1194 408; B 8 8 1210 408; B 8 8 1226 408; B 8 8 1608 410; B 8 8 1632 408; B 8 8 1648 408; B 8 8 1664 408; B 8 8 1680 408; B 8 8 1696 408; B 8 8 1712 408; B 8 8 1728 408; B 8 8 1744 408; B 8 8 1760 408; B 8 8 1776 408; B 8 8 1792 408; B 8 8 1808 408; B 8 8 1824 408; B 8 8 1840 408; B 8 8 1856 408; B 8 8 1872 408; B 8 8 1888 408; B 8 8 1904 408; B 8 8 1920 408; B 8 8 1936 408; B 8 8 1952 408; B 8 8 1968 408; B 8 8 1984 408; B 8 8 2000 408; B 8 8 2016 408; B 8 8 2032 408; B 8 8 2048 408; B 8 8 2064 408; B 8 8 2080 408; B 8 8 2096 408; B 8 8 2112 408; B 8 8 2128 408; B 8 8 2144 408; B 8 8 2160 408; B 8 8 2176 408; B 8 8 2192 408; B 8 8 2208 408; B 8 8 2224 408; B 8 8 2240 408; B 8 8 2256 408; B 8 8 2272 408; B 8 8 2288 408; B 8 8 2386 408; B 8 8 2776 410; B 8 8 2800 408; B 8 8 2816 408; B 8 8 2832 408; B 8 8 2848 408; B 8 8 2864 408; B 8 8 2880 408; B 8 8 2896 408; B 8 8 2912 408; B 8 8 2928 408; B 8 8 2944 408; B 8 8 2960 408; B 8 8 2976 408; B 8 8 2992 408; B 8 8 3008 408; B 8 8 3024 408; B 8 8 3040 408; B 8 8 3056 408; B 8 8 3072 408; B 8 8 3088 408; B 8 8 3104 408; B 8 8 3120 408; B 8 8 3136 408; B 8 8 3152 408; B 8 8 3168 408; B 8 8 3184 408; B 8 8 3200 408; B 8 8 3216 408; B 8 8 3232 408; B 8 8 3248 408; B 8 8 3264 408; B 8 8 3280 408; B 8 8 3296 408; B 8 8 3312 408; B 8 8 3328 408; B 8 8 3344 408; B 8 8 3360 408; B 8 8 3376 408; B 8 8 3392 408; B 8 8 3408 408; B 8 8 3424 408; B 8 8 3440 408; B 8 8 3456 408; B 8 8 3472 408; B 8 8 3488 408; B 8 8 3504 408; B 8 8 3520 408; B 8 8 3536 408; B 8 8 3552 408; B 8 8 3568 408; B 8 8 3584 408; B 8 8 3600 408; B 8 8 3616 408; B 8 8 3632 408; B 8 8 3648 408; B 8 8 3664 408; B 8 8 3680 408; B 8 8 3696 408; B 8 8 3712 408; B 8 8 3728 408; B 8 8 3744 408; B 8 8 3760 408; B 8 8 3776 408; B 8 8 3792 408; B 8 8 3808 408; B 8 8 3824 408; B 8 8 3840 408; B 8 8 3856 408; B 8 8 3872 408; B 8 8 3888 408; B 8 8 3904 408; B 8 8 3920 408; B 8 8 3936 408; B 8 8 3952 408; B 8 8 3968 408; B 8 8 3984 408; B 8 8 4000 408; B 8 8 4016 408; B 8 8 4032 408; B 8 8 4048 408; B 8 8 4064 408; B 8 8 4080 408; B 8 8 4096 408; B 8 8 4112 408; B 8 8 4128 408; B 8 8 4144 408; B 8 8 4160 408; B 8 8 4176 408; B 8 8 4192 408; B 8 8 4208 408; B 8 8 4224 408; B 8 8 4240 408; B 8 8 4268 408; B 8 8 4672 408; B 8 8 4764 408; B 8 8 4780 408; B 8 8 4796 408; B 8 8 4812 408; B 8 8 4828 408; B 8 8 4844 408; B 8 8 4860 408; B 8 8 4876 408; B 8 8 4892 408; B 8 8 4908 408; B 8 8 4924 408; B 8 8 4940 408; B 8 8 4956 408; B 8 8 4972 408; B 8 8 4988 408; B 8 8 5004 408; B 8 8 5020 408; B 8 8 5036 408; B 8 8 5052 408; B 8 8 5068 408; B 8 8 5084 408; B 8 8 5100 408; B 8 8 5460 408; B 8 8 5486 408; B 8 8 5502 408; B 8 8 5518 408; B 8 8 5534 408; B 8 8 5550 408; B 8 8 5566 408; B 8 8 5582 408; B 8 8 5598 408; B 8 8 5614 408; B 8 8 5710 408; L CBA; B 112 48 432 456; B 112 92 1144 482; B 728 92 2000 482; B 1436 92 3522 482; B 376 92 4884 482; B 200 92 5588 482; L CSN; B 208 40 1144 556; B 208 40 432 508; B 40 64 348 456; B 32 32 432 456; B 40 64 516 456; B 208 40 432 404; B 40 108 1060 482; B 32 32 1144 504; B 32 32 1144 460; B 40 108 1228 482; B 208 40 1144 408; B 824 40 2000 556; B 40 108 1608 482; B 32 32 1692 504; B 32 32 1780 504; B 32 32 1868 504; B 32 32 1956 504; B 32 32 2044 504; B 32 32 2132 504; B 32 32 2220 504; B 32 32 2308 504; B 32 32 1692 460; B 32 32 1780 460; B 32 32 1868 460; B 32 32 1956 460; B 32 32 2044 460; B 32 32 2132 460; B 32 32 2220 460; B 32 32 2308 460; B 40 108 2392 482; B 824 40 2000 408; B 1532 40 3522 556; B 40 108 2776 482; B 32 32 2860 504; B 32 32 2948 504; B 32 32 3036 504; B 32 32 3124 504; B 32 32 3212 504; B 32 32 3300 504; B 32 32 3388 504; B 32 32 3476 504; B 32 32 3564 504; B 32 32 3652 504; B 32 32 3740 504; B 32 32 3828 504; B 32 32 3920 504; B 32 32 4008 504; B 32 32 4096 504; B 32 32 4184 504; B 32 32 2860 460; B 32 32 2948 460; B 32 32 3036 460; B 32 32 3124 460; B 32 32 3212 460; B 32 32 3300 460; B 32 32 3388 460; B 32 32 3476 460; B 32 32 3564 460; B 32 32 3652 460; B 32 32 3740 460; B 32 32 3828 460; B 32 32 3920 460; B 32 32 4008 460; B 32 32 4096 460; B 32 32 4184 460; B 40 108 4268 482; B 1532 40 3522 408; B 472 40 4884 556; B 40 108 4668 482; B 32 32 4752 504; B 32 32 4840 504; B 32 32 4928 504; B 32 32 5016 504; B 32 32 4752 460; B 32 32 4840 460; B 32 32 4928 460; B 32 32 5016 460; B 40 108 5100 482; B 472 40 4884 408; B 296 40 5588 556; B 40 108 5460 482; B 32 32 5544 504; B 32 32 5632 504; B 32 32 5544 460; B 32 32 5632 460; B 40 108 5716 482; B 296 40 5588 408; L CSP; B 24 24 388 456; B 24 24 476 456; B 24 56 1100 480; B 24 56 1188 480; B 24 56 1648 480; B 24 56 1736 480; B 24 56 1824 480; B 24 56 1912 480; B 24 56 2000 480; B 24 56 2088 480; B 24 56 2176 480; B 24 56 2264 480; B 24 56 2352 480; B 24 56 2816 480; B 24 56 2904 480; B 24 56 2992 480; B 24 56 3080 480; B 24 56 3168 480; B 24 56 3256 480; B 24 56 3344 480; B 24 56 3432 480; B 24 56 3520 480; B 24 56 3608 480; B 24 56 3696 480; B 24 56 3784 480; B 24 56 3872 480; B 24 56 3964 480; B 24 56 4052 480; B 24 56 4140 480; B 24 56 4228 480; B 24 56 4708 480; B 24 56 4796 480; B 24 56 4884 480; B 24 56 4972 480; B 24 56 5060 480; B 24 56 5500 480; B 24 56 5588 480; B 24 56 5676 480; 94 south_8 5648 388 CMF; 94 south_9 5676 388 CMF; 94 south_6 4708 388 CMF; 94 south_7 4736 388 CMF; 94 south_5 3512 388 CMF; 94 south_3 2324 388 CMF; 94 south_4 2352 388 CMF; 94 south_2 1228 388 CMF; 94 south_1 484 388 CMF; 94 north_3 1160 576 CMF; 94 north_4 1188 576 CMF; 94 north_5 2392 576 CMF; 94 north_6 4200 576 CMF; 94 north_7 4228 576 CMF; 94 north_8 4788 576 CMF; 94 north_9 5436 576 CMF; 94 north_2 648 576 CMF; 94 north_1 312 576 CMF; DF; C 1; End magic-8.0.210/scmos/examples/bipolar/README0000644000175000001440000000145610751423606016736 0ustar timusers SCMOS rules for vertical NPN transistor has been revised from version 6 to 7 due to the requirement to support ORBIT 1.2 micron process. If you use the "scmos" technology to load the cell "npn_array.mag", you'll find the following DRCs: N-well overlap of collector must be at least 3 (MOSIS rule #16.11) Pbase overlap of base contact must be at least 3 (MOSIS rule #16.5) The cell "npn_array.mag" is the actual test vehicle for the ORBIT 2.0 micron process, so it should work OK if you target for that process. It is included here (without modification) to illustrate the difference between thees processes. All other cells have been modified according to the latest SCMOS DRC rules - revision 7. Please send attention e-mail to mosis@mosis.edu if you have any problem or comments... Jen-I pi@isi.edu ;-) magic-8.0.210/scmos/examples/bipolar/min.mag0000644000175000001440000000113510751423606017321 0ustar timusersmagic tech scmos timestamp 783737348 << nwell >> rect 5 3 46 27 << metal1 >> rect 9 0 13 13 rect 22 0 26 13 rect 33 0 37 13 << collector >> rect 8 17 14 18 rect 8 13 9 17 rect 13 13 14 17 rect 8 12 14 13 << pbase >> rect 18 17 40 21 rect 18 13 22 17 rect 26 13 33 17 rect 37 13 40 17 rect 18 9 40 13 << collectorcontact >> rect 9 13 13 17 << emittercontact >> rect 22 13 26 17 << pbasecontact >> rect 33 13 37 17 << labels >> rlabel space 0 17 0 17 3 without rlabel space 0 13 0 13 3 guardring rlabel metal1 35 1 35 1 5 base rlabel metal1 24 1 24 1 5 emitter rlabel metal1 11 1 11 1 5 collector << end >> magic-8.0.210/scmos/examples/bipolar/npn_array20.cif0000644000175000001440000005432710751423606020701 0ustar timusersDS1 100/4; C2 T0 15360 ; DF; DS2 100/4; C3 ; C4 ; C5 ; C6 ; C7 ; C8 ; C9 ; C10 ; C11 ; LCOG; B296 296 160 -14560; B296 296 800 -14560; B296 296 1440 -14560; B296 296 2080 -14560; B296 296 2720 -14560; B296 296 3360 -14560; B296 296 4000 -14560; B296 296 4640 -14560; DF; DS11 100/4; LCCA; B8 8 3964 -14804; B8 8 3948 -14804; B8 8 3932 -14804; B8 8 3916 -14804; B8 8 3900 -14804; B8 8 3884 -14804; B8 8 3868 -14804; B8 8 3852 -14804; B8 8 3836 -14804; B8 8 3820 -14804; B8 8 3804 -14804; B8 8 3788 -14804; B8 8 3772 -14804; B8 8 3756 -14804; B8 8 3740 -14804; B8 8 3724 -14804; B8 8 3708 -14804; B8 8 3692 -14804; B8 8 3676 -14804; B8 8 3660 -14804; B8 8 3644 -14804; B8 8 3628 -14804; B8 8 3612 -14804; B8 8 3596 -14804; B8 8 3580 -14804; B8 8 3564 -14804; B8 8 3548 -14804; B8 8 3532 -14804; B8 8 3516 -14804; B8 8 3500 -14804; B8 8 3484 -14804; B8 8 3468 -14804; B8 8 3452 -14804; B8 8 3436 -14804; B8 8 3420 -14804; B8 8 3404 -14804; B8 8 3388 -14804; B8 8 3372 -14804; B8 8 3356 -14804; B8 8 3340 -14804; B8 8 3324 -14804; B8 8 3308 -14804; B8 8 3292 -14804; B8 8 3276 -14804; B8 8 3260 -14804; B8 8 3244 -14804; B8 8 3228 -14804; B8 8 3212 -14804; B8 8 3196 -14804; B8 8 3180 -14804; B8 8 3164 -14804; B8 8 3148 -14804; B8 8 3132 -14804; B8 8 3116 -14804; B8 8 3100 -14804; B8 8 3084 -14804; B8 8 3068 -14804; B8 8 3052 -14804; B8 8 3036 -14804; B8 8 3020 -14804; B8 8 3004 -14804; B8 8 2988 -14804; B8 8 2972 -14804; B8 8 2956 -14804; B8 8 2940 -14804; B8 8 2924 -14804; B8 8 2908 -14804; B8 8 2892 -14804; B8 8 2876 -14804; B8 8 2860 -14804; B8 8 2844 -14804; B8 8 2828 -14804; B8 8 2812 -14804; B8 8 2796 -14804; B8 8 2776 -14806; B8 8 2392 -14804; B8 8 2368 -14804; B8 8 2352 -14804; B8 8 2336 -14804; B8 8 2320 -14804; B8 8 2304 -14804; B8 8 2288 -14804; B8 8 2272 -14804; B8 8 2256 -14804; B8 8 2240 -14804; B8 8 2224 -14804; B8 8 2208 -14804; B8 8 2192 -14804; B8 8 2176 -14804; B8 8 2160 -14804; B8 8 2144 -14804; B8 8 2128 -14804; B8 8 2112 -14804; B8 8 2096 -14804; B8 8 2080 -14804; B8 8 2064 -14804; B8 8 2048 -14804; B8 8 2032 -14804; B8 8 2016 -14804; B8 8 2000 -14804; B8 8 1984 -14804; B8 8 1968 -14804; B8 8 1952 -14804; B8 8 1936 -14804; B8 8 1920 -14804; B8 8 1904 -14804; B8 8 1888 -14804; B8 8 1872 -14804; B8 8 1856 -14804; B8 8 1840 -14804; B8 8 1824 -14804; B8 8 1808 -14804; B8 8 1792 -14804; B8 8 1776 -14804; B8 8 1760 -14804; B8 8 1744 -14804; B8 8 1728 -14804; B8 8 1712 -14804; B8 8 1696 -14804; B8 8 1680 -14804; B8 8 1664 -14804; B8 8 1648 -14804; B8 8 1632 -14804; B8 8 1608 -14806; B8 8 1222 -14804; B8 8 1132 -14804; B8 8 1116 -14804; B8 8 1100 -14804; B8 8 1084 -14804; B8 8 1060 -14806; DF; DS10 100/4; LCCA; B8 8 3608 -14862; B8 8 3564 -14856; B8 8 3520 -14862; B8 8 3476 -14856; B8 8 3432 -14862; B8 8 3388 -14856; B8 8 3344 -14862; B8 8 3300 -14856; B8 8 3256 -14862; B8 8 3212 -14856; B8 8 3168 -14862; B8 8 3124 -14856; B8 8 3080 -14862; B8 8 3036 -14856; B8 8 2992 -14862; B8 8 2948 -14856; B8 8 2904 -14862; B8 8 2860 -14856; B8 8 2816 -14862; B8 8 2392 -14868; B8 8 1608 -14870; B8 8 1060 -14870; B8 8 348 -14870; B8 8 2352 -14862; B8 8 2776 -14854; B8 8 2392 -14852; B8 8 2308 -14856; B8 8 2264 -14862; B8 8 2220 -14856; B8 8 2176 -14862; B8 8 2132 -14856; B8 8 2088 -14862; B8 8 2044 -14856; B8 8 2000 -14862; B8 8 1956 -14856; B8 8 1912 -14862; B8 8 1868 -14856; B8 8 1824 -14862; B8 8 1780 -14856; B8 8 1736 -14862; B8 8 1692 -14856; B8 8 1648 -14862; B8 8 1228 -14862; B8 8 1188 -14862; B8 8 1608 -14854; B8 8 1144 -14856; B8 8 1100 -14862; B8 8 1060 -14854; B8 8 5716 -14836; B8 8 5460 -14838; B8 8 5100 -14830; B8 8 4668 -14836; B8 8 4268 -14840; B8 8 1228 -14846; B8 8 510 -14852; B8 8 418 -14852; B8 8 402 -14852; B8 8 386 -14852; B8 8 370 -14852; B8 8 348 -14854; B8 8 2776 -14838; B8 8 2392 -14836; B8 8 1608 -14838; B8 8 1060 -14838; B8 8 5716 -14820; B8 8 5460 -14822; B8 8 4668 -14820; B8 8 4268 -14824; B8 8 1228 -14830; B8 8 2776 -14822; B8 8 2392 -14820; B8 8 1608 -14822; B8 8 1060 -14822; B8 8 5716 -14804; B8 8 5692 -14804; B8 8 5676 -14804; B8 8 5660 -14804; B8 8 5644 -14804; B8 8 5628 -14804; B8 8 5612 -14804; B8 8 5596 -14804; B8 8 5580 -14804; B8 8 5564 -14804; B8 8 5548 -14804; B8 8 5532 -14804; B8 8 5516 -14804; B8 8 5500 -14804; B8 8 5484 -14804; B8 8 5460 -14806; B8 8 5094 -14804; B8 8 5078 -14804; B8 8 5062 -14804; B8 8 5046 -14804; B8 8 5030 -14804; B8 8 5014 -14804; B8 8 4998 -14804; B8 8 4982 -14804; B8 8 4966 -14804; B8 8 4950 -14804; B8 8 4934 -14804; B8 8 4918 -14804; B8 8 4902 -14804; B8 8 4886 -14804; B8 8 4870 -14804; B8 8 4854 -14804; B8 8 4838 -14804; B8 8 4822 -14804; B8 8 4806 -14804; B8 8 4790 -14804; B8 8 4774 -14804; B8 8 4758 -14804; B8 8 4742 -14804; B8 8 4726 -14804; B8 8 4710 -14804; B8 8 4694 -14804; B8 8 4668 -14804; B8 8 4264 -14804; B8 8 4172 -14804; B8 8 4156 -14804; B8 8 4140 -14804; B8 8 4124 -14804; B8 8 4108 -14804; B8 8 4092 -14804; B8 8 4076 -14804; B8 8 4060 -14804; B8 8 4044 -14804; B8 8 4028 -14804; B8 8 4012 -14804; B8 8 3996 -14804; B8 8 3980 -14804; DF; DS9 100/4; LCCA; B8 8 3920 -14900; B8 8 3872 -14894; B8 8 3828 -14900; B8 8 3784 -14894; B8 8 3740 -14900; B8 8 3696 -14894; B8 8 3652 -14900; B8 8 3608 -14894; B8 8 3564 -14900; B8 8 3520 -14894; B8 8 3476 -14900; B8 8 3432 -14894; B8 8 3388 -14900; B8 8 3344 -14894; B8 8 3300 -14900; B8 8 3256 -14894; B8 8 3212 -14900; B8 8 3168 -14894; B8 8 3124 -14900; B8 8 3080 -14894; B8 8 3036 -14900; B8 8 2992 -14894; B8 8 2948 -14900; B8 8 2904 -14894; B8 8 2860 -14900; B8 8 2776 -14902; B8 8 2816 -14894; B8 8 2392 -14900; B8 8 2352 -14894; B8 8 2308 -14900; B8 8 2264 -14894; B8 8 2220 -14900; B8 8 2176 -14894; B8 8 2132 -14900; B8 8 2088 -14894; B8 8 2044 -14900; B8 8 2000 -14894; B8 8 1956 -14900; B8 8 1912 -14894; B8 8 1868 -14900; B8 8 1824 -14894; B8 8 1780 -14900; B8 8 1736 -14894; B8 8 1692 -14900; B8 8 1608 -14902; B8 8 1648 -14894; B8 8 1228 -14894; B8 8 1188 -14894; B8 8 1144 -14900; B8 8 1060 -14902; B8 8 1100 -14894; B8 8 516 -14898; B8 8 476 -14904; B8 8 432 -14904; B8 8 388 -14904; B8 8 348 -14902; B8 8 2776 -14886; B8 8 5716 -14868; B8 8 5460 -14870; B8 8 5676 -14862; B8 8 5716 -14852; B8 8 5632 -14856; B8 8 5588 -14862; B8 8 5544 -14856; B8 8 5500 -14862; B8 8 5100 -14862; B8 8 5060 -14862; B8 8 5460 -14854; B8 8 5016 -14856; B8 8 4972 -14862; B8 8 4928 -14856; B8 8 4884 -14862; B8 8 4840 -14856; B8 8 4796 -14862; B8 8 4752 -14856; B8 8 4708 -14862; B8 8 4668 -14868; B8 8 4268 -14872; B8 8 4228 -14878; B8 8 4140 -14878; B8 8 4052 -14878; B8 8 3964 -14878; B8 8 3872 -14878; B8 8 3784 -14878; B8 8 3696 -14878; B8 8 3608 -14878; B8 8 3520 -14878; B8 8 3432 -14878; B8 8 3344 -14878; B8 8 3256 -14878; B8 8 3168 -14878; B8 8 3080 -14878; B8 8 2992 -14878; B8 8 2904 -14878; B8 8 2816 -14878; B8 8 2392 -14884; B8 8 1608 -14886; B8 8 1060 -14886; B8 8 2352 -14878; B8 8 2264 -14878; B8 8 2176 -14878; B8 8 2088 -14878; B8 8 2000 -14878; B8 8 1912 -14878; B8 8 1824 -14878; B8 8 1736 -14878; B8 8 1648 -14878; B8 8 1228 -14878; B8 8 1188 -14878; B8 8 1100 -14878; B8 8 516 -14882; B8 8 348 -14886; B8 8 2776 -14870; B8 8 5100 -14846; B8 8 4668 -14852; B8 8 4268 -14856; B8 8 4228 -14862; B8 8 4184 -14856; B8 8 4140 -14862; B8 8 4096 -14856; B8 8 4052 -14862; B8 8 4008 -14856; B8 8 3964 -14862; B8 8 3920 -14856; B8 8 3872 -14862; B8 8 3828 -14856; B8 8 3784 -14862; B8 8 3740 -14856; B8 8 3696 -14862; B8 8 3652 -14856; DF; DS8 100/4; LCCA; B8 8 2776 -14950; B8 8 2386 -14952; B8 8 2288 -14952; B8 8 2272 -14952; B8 8 2256 -14952; B8 8 2240 -14952; B8 8 2224 -14952; B8 8 2208 -14952; B8 8 2192 -14952; B8 8 2176 -14952; B8 8 2160 -14952; B8 8 2144 -14952; B8 8 2128 -14952; B8 8 2112 -14952; B8 8 2096 -14952; B8 8 2080 -14952; B8 8 2064 -14952; B8 8 2048 -14952; B8 8 2032 -14952; B8 8 2016 -14952; B8 8 2000 -14952; B8 8 1984 -14952; B8 8 1968 -14952; B8 8 1952 -14952; B8 8 1936 -14952; B8 8 1920 -14952; B8 8 1904 -14952; B8 8 1888 -14952; B8 8 1872 -14952; B8 8 1856 -14952; B8 8 1840 -14952; B8 8 1824 -14952; B8 8 1808 -14952; B8 8 1792 -14952; B8 8 1776 -14952; B8 8 1760 -14952; B8 8 1744 -14952; B8 8 1728 -14952; B8 8 1712 -14952; B8 8 1696 -14952; B8 8 1680 -14952; B8 8 1664 -14952; B8 8 1648 -14952; B8 8 1632 -14952; B8 8 1608 -14950; B8 8 1226 -14952; B8 8 1210 -14952; B8 8 1194 -14952; B8 8 1178 -14952; B8 8 1162 -14952; B8 8 1146 -14952; B8 8 1130 -14952; B8 8 1114 -14952; B8 8 1098 -14952; B8 8 1082 -14952; B8 8 1060 -14950; B8 8 512 -14956; B8 8 496 -14956; B8 8 480 -14956; B8 8 464 -14956; B8 8 448 -14956; B8 8 432 -14956; B8 8 416 -14956; B8 8 400 -14956; B8 8 384 -14956; B8 8 368 -14956; B8 8 352 -14956; B8 8 5716 -14932; B8 8 5460 -14934; B8 8 5100 -14926; B8 8 4668 -14932; B8 8 4268 -14936; B8 8 2776 -14934; B8 8 2392 -14932; B8 8 1608 -14934; B8 8 1060 -14934; B8 8 5716 -14916; B8 8 5460 -14918; B8 8 5100 -14910; B8 8 4668 -14916; B8 8 4268 -14920; B8 8 1228 -14926; B8 8 516 -14930; B8 8 348 -14934; B8 8 2776 -14918; B8 8 2392 -14916; B8 8 1608 -14918; B8 8 1060 -14918; B8 8 5716 -14900; B8 8 5676 -14894; B8 8 5632 -14900; B8 8 5588 -14894; B8 8 5544 -14900; B8 8 5460 -14902; B8 8 5500 -14894; B8 8 5100 -14894; B8 8 5060 -14894; B8 8 5016 -14900; B8 8 4972 -14894; B8 8 4928 -14900; B8 8 4884 -14894; B8 8 4840 -14900; B8 8 4796 -14894; B8 8 4752 -14900; B8 8 4708 -14894; B8 8 4668 -14900; B8 8 4268 -14904; B8 8 1228 -14910; B8 8 516 -14914; B8 8 348 -14918; B8 8 5716 -14884; B8 8 5460 -14886; B8 8 5676 -14878; B8 8 5588 -14878; B8 8 5500 -14878; B8 8 5100 -14878; B8 8 5060 -14878; B8 8 4972 -14878; B8 8 4884 -14878; B8 8 4796 -14878; B8 8 4708 -14878; B8 8 4668 -14884; B8 8 4268 -14888; B8 8 4228 -14894; B8 8 4184 -14900; B8 8 4140 -14894; B8 8 4096 -14900; B8 8 4052 -14894; B8 8 4008 -14900; B8 8 3964 -14894; DF; DS7 100/4; LCVA; B288 288 4000 -15200; B288 288 4640 -15200; B288 288 5280 -15200; B288 288 5920 -15200; LCCA; B8 8 5710 -14952; B8 8 5614 -14952; B8 8 5598 -14952; B8 8 5582 -14952; B8 8 5566 -14952; B8 8 5550 -14952; B8 8 5534 -14952; B8 8 5518 -14952; B8 8 5502 -14952; B8 8 5486 -14952; B8 8 5460 -14950; B8 8 5100 -14952; B8 8 5084 -14952; B8 8 5068 -14952; B8 8 5052 -14952; B8 8 5036 -14952; B8 8 5020 -14952; B8 8 5004 -14952; B8 8 4988 -14952; B8 8 4972 -14952; B8 8 4956 -14952; B8 8 4940 -14952; B8 8 4924 -14952; B8 8 4908 -14952; B8 8 4892 -14952; B8 8 4876 -14952; B8 8 4860 -14952; B8 8 4844 -14952; B8 8 4828 -14952; B8 8 4812 -14952; B8 8 4796 -14952; B8 8 4780 -14952; B8 8 4764 -14952; B8 8 4674 -14952; B8 8 4268 -14952; B8 8 4242 -14952; B8 8 4226 -14952; B8 8 4210 -14952; B8 8 4194 -14952; B8 8 4178 -14952; B8 8 4162 -14952; B8 8 4146 -14952; B8 8 4130 -14952; B8 8 4114 -14952; B8 8 4098 -14952; B8 8 4082 -14952; B8 8 4066 -14952; B8 8 4050 -14952; B8 8 4034 -14952; B8 8 4018 -14952; B8 8 4002 -14952; B8 8 3986 -14952; B8 8 3970 -14952; B8 8 3954 -14952; B8 8 3938 -14952; B8 8 3922 -14952; B8 8 3906 -14952; B8 8 3890 -14952; B8 8 3874 -14952; B8 8 3858 -14952; B8 8 3842 -14952; B8 8 3826 -14952; B8 8 3810 -14952; B8 8 3794 -14952; B8 8 3778 -14952; B8 8 3762 -14952; B8 8 3746 -14952; B8 8 3730 -14952; B8 8 3714 -14952; B8 8 3698 -14952; B8 8 3682 -14952; B8 8 3666 -14952; B8 8 3650 -14952; B8 8 3634 -14952; B8 8 3618 -14952; B8 8 3602 -14952; B8 8 3586 -14952; B8 8 3570 -14952; B8 8 3554 -14952; B8 8 3538 -14952; B8 8 3522 -14952; B8 8 3506 -14952; B8 8 3490 -14952; B8 8 3474 -14952; B8 8 3458 -14952; B8 8 3442 -14952; B8 8 3426 -14952; B8 8 3410 -14952; B8 8 3394 -14952; B8 8 3378 -14952; B8 8 3362 -14952; B8 8 3346 -14952; B8 8 3330 -14952; B8 8 3314 -14952; B8 8 3298 -14952; B8 8 3282 -14952; B8 8 3266 -14952; B8 8 3250 -14952; B8 8 3234 -14952; B8 8 3218 -14952; B8 8 3202 -14952; B8 8 3186 -14952; B8 8 3170 -14952; B8 8 3154 -14952; B8 8 3138 -14952; B8 8 3122 -14952; B8 8 3106 -14952; B8 8 3090 -14952; B8 8 3074 -14952; B8 8 3058 -14952; B8 8 3042 -14952; B8 8 3026 -14952; B8 8 3010 -14952; B8 8 2994 -14952; B8 8 2978 -14952; B8 8 2962 -14952; B8 8 2946 -14952; B8 8 2930 -14952; B8 8 2914 -14952; B8 8 2898 -14952; B8 8 2882 -14952; B8 8 2866 -14952; B8 8 2850 -14952; B8 8 2834 -14952; B8 8 2818 -14952; B8 8 2802 -14952; DF; DS6 100/4; LCSN; B40 108 5100 -14878; B40 108 4668 -14878; B472 40 4884 -14804; B1532 40 3522 -14952; B40 108 4268 -14878; B40 108 2776 -14878; B48 40 4264 -14804; B1436 40 3474 -14804; B52 40 2386 -14952; B724 40 1950 -14952; B40 108 2392 -14878; B40 108 1608 -14878; B824 40 2000 -14804; B208 40 1144 -14952; B40 108 1228 -14878; B40 108 1060 -14878; B208 40 432 -14956; B40 64 516 -14904; B40 64 348 -14904; B52 40 510 -14852; B112 40 384 -14852; B52 40 1222 -14804; B112 40 1096 -14804; B84 20 5662 -14962; B20 16 5470 -14960; B84 20 4722 -14962; B20 16 4258 -14960; B20 16 2786 -14960; B88 20 2336 -14962; B20 16 1618 -14960; B20 16 1070 -14960; B272 20 5596 -14942; B464 20 4884 -14942; B1492 20 3522 -14942; B800 20 2008 -14942; B184 20 1152 -14942; B200 20 432 -14946; B20 108 5706 -14878; B32 32 5632 -14900; B32 32 5544 -14900; B32 32 5632 -14856; B32 32 5544 -14856; B20 108 5470 -14878; B20 108 5090 -14878; B32 32 5016 -14900; B32 32 4928 -14900; B32 32 4840 -14900; B32 32 4752 -14900; B32 32 5016 -14856; B32 32 4928 -14856; B32 32 4840 -14856; B32 32 4752 -14856; B20 108 4678 -14878; B20 108 4258 -14878; B32 32 4184 -14900; B32 32 4096 -14900; B32 32 4008 -14900; B32 32 3920 -14900; B32 32 3828 -14900; B32 32 3740 -14900; B32 32 3652 -14900; B32 32 3564 -14900; B32 32 3476 -14900; B32 32 3388 -14900; B32 32 3300 -14900; B32 32 3212 -14900; B32 32 3124 -14900; B32 32 3036 -14900; B32 32 2948 -14900; B32 32 2860 -14900; B32 32 4184 -14856; B32 32 4096 -14856; B32 32 4008 -14856; B32 32 3920 -14856; B32 32 3828 -14856; B32 32 3740 -14856; B32 32 3652 -14856; B32 32 3564 -14856; B32 32 3476 -14856; B32 32 3388 -14856; B32 32 3300 -14856; B32 32 3212 -14856; B32 32 3124 -14856; B32 32 3036 -14856; B32 32 2948 -14856; B32 32 2860 -14856; B20 108 2786 -14878; B256 20 5588 -14814; B448 20 4892 -14814; B1508 20 3530 -14814; B20 16 5706 -14796; B20 16 5470 -14796; B20 16 4678 -14796; B88 20 4216 -14794; B20 16 2786 -14796; B20 108 2382 -14878; B32 32 2308 -14900; B32 32 2220 -14900; B32 32 2132 -14900; B32 32 2044 -14900; B32 32 1956 -14900; B32 32 1868 -14900; B32 32 1780 -14900; B32 32 1692 -14900; B32 32 2308 -14856; B32 32 2220 -14856; B32 32 2132 -14856; B32 32 2044 -14856; B32 32 1956 -14856; B32 32 1868 -14856; B32 32 1780 -14856; B32 32 1692 -14856; B20 108 1618 -14878; B20 108 1218 -14878; B32 32 1144 -14900; B32 32 1144 -14856; B20 108 1070 -14878; B20 60 506 -14906; B32 32 432 -14904; B36 4 514 -14874; B20 64 358 -14904; B184 20 440 -14862; B84 20 462 -14842; B20 16 358 -14844; B784 20 2000 -14814; B184 20 1152 -14814; B20 16 2382 -14796; B20 16 1618 -14796; B84 20 1174 -14794; B24 16 1072 -14796; DF; DS5 100/4; LCSP; B60 88 478 -14500; B60 88 1758 -14500; B60 88 3038 -14500; B60 88 4318 -14500; B60 88 5598 -14500; B24 24 388 -14904; B24 24 476 -14904; B24 68 1100 -14878; B24 68 1188 -14878; B24 68 1648 -14878; B24 68 1736 -14878; B24 68 1824 -14878; B24 68 1912 -14878; B24 68 2000 -14878; B24 68 2088 -14878; B24 68 2176 -14878; B24 68 2264 -14878; B24 68 2352 -14878; B24 68 2816 -14878; B24 68 2904 -14878; B24 68 2992 -14878; B24 68 3080 -14878; B24 68 3168 -14878; B24 68 3256 -14878; B24 68 3344 -14878; B24 68 3432 -14878; B24 68 3520 -14878; B24 68 3608 -14878; B24 68 3696 -14878; B24 68 3784 -14878; B24 68 3872 -14878; B24 68 3964 -14878; B24 68 4052 -14878; B24 68 4140 -14878; B24 68 4228 -14878; B24 68 4708 -14878; B24 68 4796 -14878; B24 68 4884 -14878; B24 68 4972 -14878; B24 68 5060 -14878; B24 68 5500 -14878; B24 68 5588 -14878; B24 68 5676 -14878; B60 88 1118 -15260; B60 88 2398 -15260; B60 88 3678 -15260; B60 88 4958 -15260; LCCA; B8 8 464 -14472; B8 8 492 -14472; B8 8 1744 -14472; B8 8 1772 -14472; B8 8 3024 -14472; B8 8 3052 -14472; B8 8 4304 -14472; B8 8 4332 -14472; B8 8 5584 -14472; B8 8 5612 -14472; B8 8 464 -14500; B8 8 492 -14500; B8 8 1744 -14500; B8 8 1772 -14500; B8 8 3024 -14500; B8 8 3052 -14500; B8 8 4304 -14500; B8 8 4332 -14500; B8 8 5584 -14500; B8 8 5612 -14500; B8 8 464 -14528; B8 8 492 -14528; B8 8 1744 -14528; B8 8 1772 -14528; B8 8 3024 -14528; B8 8 3052 -14528; B8 8 4304 -14528; B8 8 4332 -14528; B8 8 5584 -14528; B8 8 5612 -14528; B8 8 1104 -15232; B8 8 1132 -15232; B8 8 2384 -15232; B8 8 2412 -15232; B8 8 3664 -15232; B8 8 3692 -15232; B8 8 4944 -15232; B8 8 4972 -15232; B8 8 1104 -15260; B8 8 1132 -15260; B8 8 2384 -15260; B8 8 2412 -15260; B8 8 3664 -15260; B8 8 3692 -15260; B8 8 4944 -15260; B8 8 4972 -15260; B8 8 1104 -15288; B8 8 1132 -15288; B8 8 2384 -15288; B8 8 2412 -15288; B8 8 3664 -15288; B8 8 3692 -15288; B8 8 4944 -15288; B8 8 4972 -15288; LCVA; B288 288 160 -14560; B288 288 800 -14560; B288 288 1440 -14560; B288 288 2080 -14560; B288 288 2720 -14560; B288 288 3360 -14560; B288 288 4000 -14560; B288 288 4640 -14560; B288 288 5280 -14560; B288 288 5920 -14560; B288 288 160 -15200; B288 288 800 -15200; B288 288 1440 -15200; B288 288 2080 -15200; B288 288 2720 -15200; B288 288 3360 -15200; LCBA; B200 92 5588 -14878; B376 92 4884 -14878; B1436 92 3522 -14878; B728 92 2000 -14878; B112 92 1144 -14878; B112 48 432 -14904; LCSN; B52 40 5710 -14952; B200 40 5540 -14952; B40 108 5716 -14878; B40 108 5460 -14878; B296 40 5588 -14804; B376 40 4932 -14952; B52 40 4674 -14952; DF; DS4 100/4; LCMF; B368 12 4884 -14830; B16 132 4668 -14878; B448 16 4884 -14804; B1508 16 3522 -14952; B16 132 4268 -14878; B1432 12 3524 -14926; B24 16 4264 -14804; B20 76 5430 -14758; B20 76 4790 -14758; B20 200 4230 -14820; B16 72 4184 -14872; B16 72 4140 -14884; B16 72 4096 -14872; B16 72 4052 -14884; B16 72 4008 -14872; B16 72 3964 -14884; B16 72 3920 -14872; B16 72 3872 -14884; B16 72 3828 -14872; B16 72 3784 -14884; B16 72 3740 -14872; B16 72 3696 -14884; B16 72 3652 -14872; B16 72 3608 -14884; B16 72 3564 -14872; B16 72 3520 -14884; B16 72 3476 -14872; B16 72 3432 -14884; B16 72 3388 -14872; B16 72 3344 -14884; B16 72 3300 -14872; B16 72 3256 -14884; B16 72 3212 -14872; B16 72 3168 -14884; B16 72 3124 -14872; B16 72 3080 -14884; B16 72 3036 -14872; B16 72 2992 -14884; B16 72 2948 -14872; B16 72 2904 -14884; B16 72 2860 -14872; B16 72 2816 -14884; B1356 12 3530 -14830; B16 52 4200 -14798; B16 132 2776 -14878; B1412 16 3474 -14804; B28 16 2386 -14952; B16 132 2392 -14878; B16 184 2352 -14928; B108 20 2278 -15030; B16 88 2324 -14976; B20 28 1590 -15026; B380 20 1410 -15002; B16 32 1228 -14976; B16 76 648 -15002; B700 16 1950 -14952; B648 12 2008 -14926; B16 72 2308 -14884; B16 72 2264 -14872; B16 72 2220 -14884; B16 72 2176 -14872; B16 72 2132 -14884; B16 72 2088 -14872; B16 72 2044 -14884; B16 72 2000 -14872; B16 72 1956 -14884; B16 72 1912 -14872; B16 72 1868 -14884; B16 72 1824 -14872; B16 72 1780 -14884; B16 72 1736 -14872; B16 72 1692 -14884; B16 72 1648 -14872; B720 12 2000 -14830; B16 132 1608 -14878; B800 16 2000 -14804; B184 16 1144 -14952; B316 16 498 -14956; B16 132 1228 -14878; B104 12 1144 -14926; B28 16 1222 -14804; B720 28 3848 -14758; B16 28 2392 -14782; B16 140 1188 -14850; B16 60 1144 -14878; B16 72 1100 -14884; B32 24 3504 -14732; B196 20 2482 -14758; B760 20 1560 -14770; B32 16 1152 -14840; B20 28 2570 -14734; B20 40 1930 -14740; B16 84 1160 -14790; B16 132 1060 -14878; B16 88 516 -14904; B104 12 432 -14930; B28 16 510 -14852; B88 16 1096 -14804; B16 120 476 -14864; B16 28 432 -14898; B16 28 388 -14910; B148 20 1226 -14738; B188 16 562 -14796; B32 12 440 -14878; B16 68 448 -14838; B16 88 348 -14904; B88 16 384 -14852; B152 16 380 -14796; B20 8 1290 -14724; B16 68 648 -14754; B320 320 5920 -14560; B44 24 5922 -14388; B44 160 5598 -14456; B320 320 5280 -14560; B320 320 4640 -14560; B400 20 4040 -14710; B44 160 4318 -14456; B320 300 4000 -14550; B320 320 3360 -14560; B44 160 3038 -14456; B320 320 2720 -14560; B320 320 2080 -14560; B44 160 1758 -14456; B320 320 1440 -14560; B320 320 800 -14560; B16 68 312 -14754; B44 160 478 -14456; B320 320 160 -14560; B32 1008 -40 -14880; B6192 32 3040 -14360; DF; DS3 100/4; LCOG; B296 296 5280 -14560; B296 296 5920 -14560; B296 296 160 -15200; B296 296 800 -15200; B296 296 1440 -15200; B296 296 2080 -15200; B296 296 2720 -15200; B296 296 3360 -15200; B296 296 4000 -15200; B296 296 4640 -15200; B296 296 5280 -15200; B296 296 5920 -15200; LCAA; B44 72 478 -14500; B44 72 1758 -14500; B44 72 3038 -14500; B44 72 4318 -14500; B44 72 5598 -14500; B192 24 1144 -14804; B192 24 432 -14852; B24 80 348 -14904; B112 48 432 -14904; B24 80 516 -14904; B192 24 432 -14956; B24 124 1060 -14878; B112 92 1144 -14878; B24 124 1228 -14878; B192 24 1144 -14952; B808 24 2000 -14804; B24 124 1608 -14878; B728 92 2000 -14878; B24 124 2392 -14878; B808 24 2000 -14952; B1516 24 3522 -14804; B24 124 2776 -14878; B1436 92 3522 -14878; B24 124 4268 -14878; B1516 24 3522 -14952; B456 24 4884 -14804; B24 124 4668 -14878; B376 92 4884 -14878; B24 124 5100 -14878; B456 24 4884 -14952; B280 24 5588 -14804; B24 124 5460 -14878; B200 92 5588 -14878; B24 124 5716 -14878; B280 24 5588 -14952; B44 72 1118 -15260; B44 72 2398 -15260; B44 72 3678 -15260; B44 72 4958 -15260; LCMS; B320 320 160 -14560; B320 320 800 -14560; B320 320 1440 -14560; B320 320 2080 -14560; B320 320 2720 -14560; B320 320 3360 -14560; B320 320 4000 -14560; B320 320 4640 -14560; B320 320 5280 -14560; B320 320 5920 -14560; B320 320 160 -15200; B320 320 800 -15200; B320 320 1440 -15200; B320 320 2080 -15200; B320 320 2720 -15200; B320 320 3360 -15200; B320 320 4000 -15200; B320 320 4640 -15200; B320 320 5280 -15200; B320 320 5920 -15200; LCWN; B280 172 5588 -14878; B456 172 4884 -14878; B1516 172 3522 -14878; B808 172 2000 -14878; B192 172 1144 -14878; B192 128 432 -14904; LCMF; B6192 32 3040 -15400; B32 1008 6120 -14880; B320 320 5920 -15200; B20 28 5770 -15026; B320 320 5280 -15200; B44 160 4958 -15304; B320 320 4640 -15200; B320 320 4000 -15200; B44 160 3678 -15304; B320 320 3360 -15200; B320 320 2720 -15200; B44 160 2398 -15304; B320 320 2080 -15200; B320 320 1440 -15200; B44 160 1118 -15304; B44 24 162 -15372; B320 320 800 -15200; B320 320 160 -15200; B20 28 5430 -15026; B112 16 5724 -15004; B28 16 5710 -14952; B16 132 5716 -14878; B16 160 5676 -14916; B236 16 5538 -15004; B16 64 5648 -14964; B176 16 5540 -14952; B120 12 5596 -14926; B16 72 5632 -14884; B16 72 5588 -14872; B16 72 5544 -14884; B16 72 5500 -14872; B192 12 5588 -14830; B16 124 5460 -14882; B352 16 4932 -14952; B48 8 5444 -14816; B304 16 5572 -14804; B16 132 5100 -14878; B16 108 4736 -14986; B20 24 4150 -15028; B296 12 4876 -14926; B576 20 4428 -15006; B16 72 5060 -14872; B16 72 5016 -14884; B16 72 4972 -14872; B16 72 4928 -14884; B16 72 4884 -14872; B16 72 4840 -14884; B16 72 4796 -14872; B16 72 4752 -14884; B16 160 4708 -14916; B32 80 3504 -15000; B232 20 2460 -15030; B28 16 4674 -14952; DF; C1 ; E magic-8.0.210/scmos/examples/bipolar/min2e.mag0000644000175000001440000000203110751423606017544 0ustar timusersmagic tech scmos timestamp 783737406 << nwell >> rect 0 1 60 39 << metal1 >> rect 4 30 8 31 rect 16 22 22 40 rect 16 18 17 22 rect 21 18 22 22 rect 16 17 22 18 rect 27 22 33 40 rect 27 18 28 22 rect 32 18 33 22 rect 27 17 33 18 rect 38 22 44 40 rect 38 18 39 22 rect 43 18 44 22 rect 38 17 44 18 rect 52 30 56 31 rect 4 9 8 10 rect 52 9 56 10 rect 27 0 33 5 << collector >> rect 3 35 57 36 rect 3 31 4 35 rect 12 31 48 35 rect 56 31 57 35 rect 3 30 57 31 rect 3 10 4 30 rect 8 10 9 30 rect 51 10 52 30 rect 56 10 57 30 rect 3 9 57 10 rect 3 5 4 9 rect 56 5 57 9 rect 3 4 57 5 << pbase >> rect 13 22 47 26 rect 13 18 17 22 rect 21 18 28 22 rect 32 18 39 22 rect 43 18 47 22 rect 13 14 47 18 << collectorcontact >> rect 4 31 12 35 rect 48 31 56 35 rect 4 10 8 30 rect 52 10 56 30 rect 4 5 56 9 << emittercontact >> rect 17 18 21 22 rect 39 18 43 22 << pbasecontact >> rect 28 18 32 22 << labels >> rlabel metal1 30 1 30 1 1 collector rlabel metal1 30 39 30 39 1 base rlabel metal1 19 39 19 39 1 emitter1 rlabel metal1 41 39 41 39 1 emitter2 << end >> magic-8.0.210/scmos/examples/bipolar/large_npn.mag0000644000175000001440000002013410751423606020503 0ustar timusersmagic tech scmos timestamp 783737922 << nwell >> rect 18 19 174 135 << metal1 >> rect 0 146 179 155 rect 15 139 17 143 rect 44 125 53 127 rect 57 118 63 146 rect 67 125 76 127 rect 116 125 125 127 rect 129 118 135 146 rect 175 139 177 143 rect 139 125 148 127 rect 21 114 35 118 rect 50 114 70 118 rect 85 114 107 118 rect 122 114 142 118 rect 157 114 171 118 rect 21 92 27 114 rect 44 105 53 107 rect 57 92 63 114 rect 67 105 76 107 rect 93 92 99 114 rect 116 105 125 107 rect 129 92 135 114 rect 139 105 148 107 rect 165 92 171 114 rect 21 88 35 92 rect 50 88 70 92 rect 85 88 107 92 rect 122 88 142 92 rect 157 88 171 92 rect 21 66 27 88 rect 44 79 53 81 rect 57 66 63 88 rect 67 79 76 81 rect 93 66 99 88 rect 116 79 125 81 rect 129 66 135 88 rect 139 79 148 81 rect 165 66 171 88 rect 21 62 35 66 rect 50 62 70 66 rect 85 62 107 66 rect 122 62 142 66 rect 157 62 171 66 rect 21 40 27 62 rect 44 53 53 55 rect 57 40 63 62 rect 67 53 76 55 rect 93 40 99 62 rect 116 53 125 55 rect 129 40 135 62 rect 139 53 148 55 rect 165 40 171 62 rect 21 36 35 40 rect 50 36 70 40 rect 85 36 107 40 rect 122 36 142 40 rect 157 36 171 40 rect 21 8 27 36 rect 44 27 53 29 rect 67 27 76 29 rect 93 8 99 36 rect 116 27 125 29 rect 139 27 148 29 rect 165 8 171 36 rect 181 16 182 143 rect 177 15 182 16 rect 180 11 182 15 rect 0 -1 180 8 << metal2 >> rect 53 139 68 143 rect 124 139 139 143 rect 175 139 182 143 rect -2 125 149 126 rect -2 121 44 125 rect 53 121 67 125 rect 76 121 116 125 rect 125 121 139 125 rect 148 121 149 125 rect -2 120 149 121 rect -2 112 8 120 rect -2 111 149 112 rect -2 107 44 111 rect 53 107 67 111 rect 76 107 116 111 rect 125 107 139 111 rect 148 107 149 111 rect -2 106 149 107 rect -2 86 8 106 rect -2 85 149 86 rect -2 81 44 85 rect 53 81 67 85 rect 76 81 116 85 rect 125 81 139 85 rect 148 81 149 85 rect -2 80 149 81 rect -2 60 8 80 rect -2 59 59 60 rect -2 55 44 59 rect 53 55 59 59 rect -2 54 59 55 rect 63 59 149 60 rect 63 55 67 59 rect 76 55 116 59 rect 125 55 139 59 rect 148 55 149 59 rect 63 54 149 55 rect -2 34 8 54 rect -2 33 149 34 rect -2 29 44 33 rect 53 29 67 33 rect 76 29 116 33 rect 125 29 139 33 rect 148 29 149 33 rect -2 28 149 29 rect -2 12 8 28 rect 177 15 182 139 rect 90 11 102 15 rect 162 11 176 15 rect 180 11 182 15 rect 186 11 187 143 << collector >> rect 21 131 171 132 rect 21 127 22 131 rect 54 127 66 131 rect 126 127 138 131 rect 170 127 171 131 rect 21 126 171 127 rect 21 106 27 126 rect 57 106 63 126 rect 93 106 99 126 rect 129 106 135 126 rect 165 106 171 126 rect 21 105 171 106 rect 21 101 30 105 rect 54 101 66 105 rect 90 101 102 105 rect 126 101 138 105 rect 162 101 171 105 rect 21 100 171 101 rect 21 80 27 100 rect 57 80 63 100 rect 93 80 99 100 rect 129 80 135 100 rect 165 80 171 100 rect 21 79 171 80 rect 21 75 30 79 rect 54 75 66 79 rect 90 75 102 79 rect 126 75 138 79 rect 162 75 171 79 rect 21 74 171 75 rect 21 54 27 74 rect 57 54 63 74 rect 93 54 99 74 rect 129 54 135 74 rect 165 54 171 74 rect 21 53 171 54 rect 21 49 30 53 rect 54 49 66 53 rect 90 49 102 53 rect 126 49 138 53 rect 162 49 171 53 rect 21 48 171 49 rect 21 28 27 48 rect 57 28 63 48 rect 93 28 99 48 rect 129 28 135 48 rect 165 28 171 48 rect 21 27 171 28 rect 21 23 30 27 rect 90 23 102 27 rect 162 23 171 27 rect 21 22 171 23 << pbase >> rect 31 118 53 122 rect 31 114 35 118 rect 39 114 46 118 rect 50 114 53 118 rect 31 110 53 114 rect 67 118 89 122 rect 67 114 70 118 rect 74 114 81 118 rect 85 114 89 118 rect 67 110 89 114 rect 103 118 125 122 rect 103 114 107 118 rect 111 114 118 118 rect 122 114 125 118 rect 103 110 125 114 rect 139 118 161 122 rect 139 114 142 118 rect 146 114 153 118 rect 157 114 161 118 rect 139 110 161 114 rect 31 92 53 96 rect 31 88 35 92 rect 39 88 46 92 rect 50 88 53 92 rect 31 84 53 88 rect 67 92 89 96 rect 67 88 70 92 rect 74 88 81 92 rect 85 88 89 92 rect 67 84 89 88 rect 103 92 125 96 rect 103 88 107 92 rect 111 88 118 92 rect 122 88 125 92 rect 103 84 125 88 rect 139 92 161 96 rect 139 88 142 92 rect 146 88 153 92 rect 157 88 161 92 rect 139 84 161 88 rect 31 66 53 70 rect 31 62 35 66 rect 39 62 46 66 rect 50 62 53 66 rect 31 58 53 62 rect 67 66 89 70 rect 67 62 70 66 rect 74 62 81 66 rect 85 62 89 66 rect 67 58 89 62 rect 103 66 125 70 rect 103 62 107 66 rect 111 62 118 66 rect 122 62 125 66 rect 103 58 125 62 rect 139 66 161 70 rect 139 62 142 66 rect 146 62 153 66 rect 157 62 161 66 rect 139 58 161 62 rect 31 40 53 44 rect 31 36 35 40 rect 39 36 46 40 rect 50 36 53 40 rect 31 32 53 36 rect 67 40 89 44 rect 67 36 70 40 rect 74 36 81 40 rect 85 36 89 40 rect 67 32 89 36 rect 103 40 125 44 rect 103 36 107 40 rect 111 36 118 40 rect 122 36 125 40 rect 103 32 125 36 rect 139 40 161 44 rect 139 36 142 40 rect 146 36 153 40 rect 157 36 161 40 rect 139 32 161 36 << collectorcontact >> rect 22 127 54 131 rect 66 127 126 131 rect 138 127 170 131 rect 30 101 54 105 rect 66 101 90 105 rect 102 101 126 105 rect 138 101 162 105 rect 30 75 54 79 rect 66 75 90 79 rect 102 75 126 79 rect 138 75 162 79 rect 30 49 54 53 rect 66 49 90 53 rect 102 49 126 53 rect 138 49 162 53 rect 30 23 90 27 rect 102 23 162 27 << emittercontact >> rect 35 114 39 118 rect 81 114 85 118 rect 107 114 111 118 rect 153 114 157 118 rect 35 88 39 92 rect 81 88 85 92 rect 107 88 111 92 rect 153 88 157 92 rect 35 62 39 66 rect 81 62 85 66 rect 107 62 111 66 rect 153 62 157 66 rect 35 36 39 40 rect 81 36 85 40 rect 107 36 111 40 rect 153 36 157 40 << pbasecontact >> rect 46 114 50 118 rect 70 114 74 118 rect 118 114 122 118 rect 142 114 146 118 rect 46 88 50 92 rect 70 88 74 92 rect 118 88 122 92 rect 142 88 146 92 rect 46 62 50 66 rect 70 62 74 66 rect 118 62 122 66 rect 142 62 146 66 rect 46 36 50 40 rect 70 36 74 40 rect 118 36 122 40 rect 142 36 146 40 << m2contact >> rect 17 139 21 143 rect 25 139 29 143 rect 33 139 37 143 rect 41 139 45 143 rect 49 139 53 143 rect 44 121 53 125 rect 68 139 72 143 rect 76 139 80 143 rect 84 139 88 143 rect 92 139 96 143 rect 100 139 104 143 rect 108 139 112 143 rect 116 139 120 143 rect 67 121 76 125 rect 116 121 125 125 rect 139 139 143 143 rect 147 139 151 143 rect 155 139 159 143 rect 163 139 167 143 rect 171 139 175 143 rect 139 121 148 125 rect 44 107 53 111 rect 67 107 76 111 rect 116 107 125 111 rect 139 107 148 111 rect 44 81 53 85 rect 67 81 76 85 rect 116 81 125 85 rect 139 81 148 85 rect 44 55 53 59 rect 67 55 76 59 rect 116 55 125 59 rect 139 55 148 59 rect 44 29 53 33 rect 67 29 76 33 rect 30 11 34 15 rect 38 11 42 15 rect 46 11 50 15 rect 54 11 58 15 rect 62 11 66 15 rect 70 11 74 15 rect 78 11 82 15 rect 86 11 90 15 rect 116 29 125 33 rect 139 29 148 33 rect 102 11 106 15 rect 110 11 114 15 rect 118 11 122 15 rect 126 11 130 15 rect 134 11 138 15 rect 142 11 146 15 rect 150 11 154 15 rect 158 11 162 15 rect 176 11 180 15 rect 182 11 186 143 << psubstratepcontact >> rect 11 12 15 143 rect 21 139 25 143 rect 29 139 33 143 rect 37 139 41 143 rect 45 139 49 143 rect 72 139 76 143 rect 80 139 84 143 rect 88 139 92 143 rect 96 139 100 143 rect 104 139 108 143 rect 112 139 116 143 rect 120 139 124 143 rect 143 139 147 143 rect 151 139 155 143 rect 159 139 163 143 rect 167 139 171 143 rect 177 16 181 143 rect 34 11 38 15 rect 42 11 46 15 rect 50 11 54 15 rect 58 11 62 15 rect 66 11 70 15 rect 74 11 78 15 rect 82 11 86 15 rect 106 11 110 15 rect 114 11 118 15 rect 122 11 126 15 rect 130 11 134 15 rect 138 11 142 15 rect 146 11 150 15 rect 154 11 158 15 << psubstratepdiff >> rect 11 143 181 144 rect 15 139 21 143 rect 25 139 29 143 rect 33 139 37 143 rect 41 139 45 143 rect 49 139 72 143 rect 76 139 80 143 rect 84 139 88 143 rect 92 139 96 143 rect 100 139 104 143 rect 108 139 112 143 rect 116 139 120 143 rect 124 139 143 143 rect 147 139 151 143 rect 155 139 159 143 rect 163 139 167 143 rect 171 139 177 143 rect 15 138 177 139 rect 15 15 181 16 rect 15 12 34 15 rect 11 11 34 12 rect 38 11 42 15 rect 46 11 50 15 rect 54 11 58 15 rect 62 11 66 15 rect 70 11 74 15 rect 78 11 82 15 rect 86 11 106 15 rect 110 11 114 15 rect 118 11 122 15 rect 126 11 130 15 rect 134 11 138 15 rect 142 11 146 15 rect 150 11 154 15 rect 158 11 181 15 rect 11 10 181 11 << labels >> rlabel metal1 0 -1 179 8 0 emitter rlabel metal2 187 13 187 140 7 GND rlabel metal1 0 146 179 155 0 base rlabel metal2 -2 13 8 125 0 collector << end >> magic-8.0.210/scmos/examples/bipolar/min2b.mag0000644000175000001440000000175410751423606017554 0ustar timusersmagic tech scmos timestamp 783737384 << nwell >> rect 0 1 58 39 << metal1 >> rect 4 30 8 31 rect 16 22 20 40 rect 26 22 32 40 rect 26 18 27 22 rect 31 18 32 22 rect 38 22 42 40 rect 16 15 20 18 rect 38 15 42 18 rect 16 12 42 15 rect 50 30 54 31 rect 4 9 8 10 rect 50 9 54 10 rect 4 5 5 9 rect 53 5 54 9 rect 26 0 32 5 << collector >> rect 3 35 55 36 rect 3 31 4 35 rect 12 31 46 35 rect 54 31 55 35 rect 3 30 55 31 rect 3 10 4 30 rect 8 10 9 30 rect 49 10 50 30 rect 54 10 55 30 rect 3 9 55 10 rect 3 5 5 9 rect 53 5 55 9 rect 3 4 55 5 << pbase >> rect 13 22 45 26 rect 13 18 16 22 rect 20 18 27 22 rect 31 18 38 22 rect 42 18 45 22 rect 13 14 45 18 << collectorcontact >> rect 4 31 12 35 rect 46 31 54 35 rect 4 10 8 30 rect 50 10 54 30 rect 5 5 53 9 << emittercontact >> rect 27 18 31 22 << pbasecontact >> rect 16 18 20 22 rect 38 18 42 22 << labels >> rlabel metal1 29 1 29 1 1 collector rlabel metal1 40 39 40 39 1 base rlabel metal1 29 39 29 39 1 emitter rlabel metal1 18 39 18 39 1 base << end >> magic-8.0.210/scmos/examples/bipolar/vertical-pnp.mag0000644000175000001440000000073710751423606021151 0ustar timusersmagic tech scmos timestamp 801256319 << nwell >> rect 0 -1 20 13 << metal1 >> rect -1 4 5 8 rect 17 4 21 8 << pdcontact >> rect 5 4 9 8 << psubstratepcontact >> rect -7 16 27 20 rect -7 -8 27 -4 << nsubstratencontact >> rect 13 4 17 8 << psubstratepdiff >> rect -7 -4 -3 16 rect 23 -4 27 16 << labels >> rlabel metal1 21 6 21 6 3 base rlabel metal1 -1 6 -1 6 7 emitter rlabel psubstratepcontact 10 18 10 18 1 collector rlabel psubstratepcontact 10 -6 10 -6 5 collector << end >> magic-8.0.210/scmos/examples/bipolar/npn_array.mag0000644000175000001440000006563210751423606020543 0ustar timusersmagic tech scmos timestamp 716915316 << nwell >> rect 84 -3742 132 -3710 rect 262 -3741 310 -3698 rect 399 -3741 601 -3698 rect 691 -3741 1070 -3698 rect 1164 -3741 1278 -3698 rect 1362 -3741 1432 -3698 << metal1 >> rect -14 -3594 1534 -3586 rect -14 -3846 -6 -3594 rect 0 -3603 80 -3600 rect 0 -3677 3 -3603 rect 77 -3677 80 -3603 rect 114 -3616 125 -3594 rect 118 -3620 121 -3616 rect 114 -3623 125 -3620 rect 118 -3627 121 -3623 rect 114 -3630 125 -3627 rect 118 -3634 121 -3630 rect 160 -3603 240 -3600 rect 0 -3680 80 -3677 rect 76 -3697 80 -3680 rect 160 -3677 163 -3603 rect 237 -3677 240 -3603 rect 160 -3680 240 -3677 rect 320 -3603 400 -3600 rect 320 -3677 323 -3603 rect 397 -3677 400 -3603 rect 434 -3616 445 -3594 rect 438 -3620 441 -3616 rect 434 -3623 445 -3620 rect 438 -3627 441 -3623 rect 434 -3630 445 -3627 rect 438 -3634 441 -3630 rect 480 -3603 560 -3600 rect 320 -3680 400 -3677 rect 480 -3677 483 -3603 rect 557 -3677 560 -3603 rect 480 -3680 560 -3677 rect 640 -3603 720 -3600 rect 640 -3677 643 -3603 rect 717 -3677 720 -3603 rect 754 -3616 765 -3594 rect 758 -3620 761 -3616 rect 754 -3623 765 -3620 rect 758 -3627 761 -3623 rect 754 -3630 765 -3627 rect 758 -3634 761 -3630 rect 800 -3603 880 -3600 rect 640 -3680 720 -3677 rect 800 -3677 803 -3603 rect 877 -3677 880 -3603 rect 800 -3680 880 -3677 rect 960 -3603 1040 -3600 rect 960 -3677 963 -3603 rect 1037 -3675 1040 -3603 rect 1074 -3616 1085 -3594 rect 1078 -3620 1081 -3616 rect 1074 -3623 1085 -3620 rect 1078 -3627 1081 -3623 rect 1074 -3630 1085 -3627 rect 1078 -3634 1081 -3630 rect 1120 -3603 1200 -3600 rect 1037 -3677 1060 -3675 rect 960 -3680 1060 -3677 rect 1120 -3677 1123 -3603 rect 1197 -3677 1200 -3603 rect 1120 -3680 1200 -3677 rect 1280 -3603 1360 -3600 rect 1280 -3677 1283 -3603 rect 1357 -3677 1360 -3603 rect 1394 -3616 1405 -3594 rect 1475 -3600 1486 -3594 rect 1398 -3620 1401 -3616 rect 1394 -3623 1405 -3620 rect 1398 -3627 1401 -3623 rect 1394 -3630 1405 -3627 rect 1398 -3634 1401 -3630 rect 1440 -3603 1520 -3600 rect 1280 -3680 1360 -3677 rect 1440 -3677 1443 -3603 rect 1517 -3677 1520 -3603 rect 1440 -3680 1520 -3677 rect 160 -3697 164 -3680 rect 320 -3682 325 -3680 rect 76 -3701 112 -3697 rect 85 -3716 89 -3715 rect 108 -3718 112 -3701 rect 106 -3724 112 -3718 rect 110 -3728 112 -3724 rect 115 -3701 164 -3697 rect 288 -3687 325 -3682 rect 263 -3700 269 -3699 rect 115 -3721 119 -3701 rect 127 -3716 131 -3715 rect 115 -3724 121 -3721 rect 115 -3728 117 -3724 rect 95 -3731 99 -3728 rect 115 -3731 121 -3728 rect 95 -3734 121 -3731 rect 85 -3737 89 -3736 rect 127 -3737 131 -3736 rect 85 -3741 86 -3737 rect 130 -3741 164 -3737 rect 267 -3703 269 -3700 rect 288 -3708 292 -3687 rect 480 -3690 485 -3680 rect 640 -3687 645 -3680 rect 284 -3712 292 -3708 rect 295 -3695 485 -3690 rect 596 -3692 645 -3687 rect 872 -3686 880 -3680 rect 273 -3714 277 -3712 rect 273 -3730 277 -3726 rect 284 -3723 288 -3716 rect 295 -3714 299 -3695 rect 596 -3699 600 -3692 rect 872 -3693 1052 -3686 rect 302 -3703 303 -3699 rect 307 -3703 309 -3699 rect 295 -3730 299 -3726 rect 273 -3733 299 -3730 rect 305 -3706 309 -3703 rect 305 -3736 309 -3734 rect 267 -3740 268 -3736 rect 308 -3740 309 -3736 rect 400 -3700 406 -3699 rect 404 -3703 406 -3700 rect 594 -3703 596 -3699 rect 410 -3709 590 -3706 rect 410 -3714 414 -3709 rect 410 -3727 414 -3726 rect 421 -3723 425 -3716 rect 432 -3714 436 -3709 rect 432 -3727 436 -3726 rect 443 -3723 447 -3716 rect 454 -3714 458 -3709 rect 454 -3727 458 -3726 rect 465 -3723 469 -3716 rect 476 -3714 480 -3709 rect 476 -3727 480 -3726 rect 487 -3723 491 -3716 rect 498 -3714 502 -3709 rect 498 -3727 502 -3726 rect 509 -3723 513 -3716 rect 520 -3714 524 -3709 rect 520 -3727 524 -3726 rect 531 -3723 535 -3716 rect 542 -3714 546 -3709 rect 542 -3727 546 -3726 rect 553 -3723 557 -3716 rect 564 -3714 568 -3709 rect 564 -3727 568 -3726 rect 575 -3723 579 -3716 rect 421 -3730 425 -3727 rect 443 -3730 447 -3727 rect 465 -3730 469 -3727 rect 487 -3730 491 -3727 rect 509 -3730 513 -3727 rect 531 -3730 535 -3727 rect 553 -3730 557 -3727 rect 575 -3730 579 -3727 rect 586 -3714 590 -3709 rect 421 -3733 583 -3730 rect 404 -3740 406 -3736 rect 574 -3740 575 -3736 rect 160 -3760 164 -3741 rect 305 -3748 309 -3740 rect 305 -3753 400 -3748 rect 395 -3760 400 -3753 rect 579 -3755 583 -3733 rect 556 -3760 583 -3755 rect 586 -3755 590 -3726 rect 596 -3736 600 -3735 rect 593 -3740 594 -3736 rect 598 -3740 600 -3736 rect 692 -3700 697 -3699 rect 696 -3703 697 -3700 rect 1048 -3706 1052 -3693 rect 713 -3709 1052 -3706 rect 713 -3712 717 -3709 rect 735 -3712 739 -3709 rect 757 -3712 761 -3709 rect 779 -3712 783 -3709 rect 801 -3712 805 -3709 rect 823 -3712 827 -3709 rect 845 -3712 849 -3709 rect 867 -3712 871 -3709 rect 889 -3712 893 -3709 rect 911 -3712 915 -3709 rect 933 -3712 937 -3709 rect 955 -3712 959 -3709 rect 978 -3712 982 -3709 rect 1000 -3712 1004 -3709 rect 1022 -3712 1026 -3709 rect 1044 -3712 1048 -3709 rect 702 -3714 706 -3712 rect 702 -3730 706 -3726 rect 713 -3723 717 -3716 rect 724 -3714 728 -3712 rect 724 -3730 728 -3726 rect 735 -3723 739 -3716 rect 746 -3714 750 -3712 rect 746 -3730 750 -3726 rect 757 -3723 761 -3716 rect 768 -3714 772 -3712 rect 768 -3730 772 -3726 rect 779 -3723 783 -3716 rect 790 -3714 794 -3712 rect 790 -3730 794 -3726 rect 801 -3723 805 -3716 rect 812 -3714 816 -3712 rect 812 -3730 816 -3726 rect 823 -3723 827 -3716 rect 834 -3714 838 -3712 rect 834 -3730 838 -3726 rect 845 -3723 849 -3716 rect 856 -3714 860 -3712 rect 856 -3730 860 -3726 rect 867 -3723 871 -3716 rect 878 -3714 882 -3712 rect 878 -3730 882 -3726 rect 889 -3723 893 -3716 rect 900 -3714 904 -3712 rect 900 -3730 904 -3726 rect 911 -3723 915 -3716 rect 922 -3714 926 -3712 rect 922 -3730 926 -3726 rect 933 -3723 937 -3716 rect 944 -3714 948 -3712 rect 944 -3730 948 -3726 rect 955 -3723 959 -3716 rect 966 -3714 970 -3712 rect 966 -3730 970 -3726 rect 978 -3723 982 -3716 rect 989 -3714 993 -3712 rect 989 -3730 993 -3726 rect 1000 -3723 1004 -3716 rect 1011 -3714 1015 -3712 rect 1011 -3730 1015 -3726 rect 1022 -3723 1026 -3716 rect 1033 -3714 1037 -3712 rect 1033 -3730 1037 -3726 rect 1044 -3723 1048 -3716 rect 1055 -3714 1060 -3680 rect 1195 -3699 1200 -3680 rect 1355 -3699 1360 -3680 rect 1063 -3703 1064 -3699 rect 1068 -3703 1069 -3699 rect 1059 -3726 1060 -3714 rect 1055 -3730 1060 -3726 rect 702 -3733 1060 -3730 rect 1065 -3704 1069 -3703 rect 696 -3740 698 -3736 rect 1062 -3740 1065 -3736 rect 1169 -3703 1171 -3699 rect 1275 -3703 1277 -3699 rect 1273 -3706 1277 -3703 rect 1355 -3700 1369 -3699 rect 1355 -3705 1363 -3700 rect 1165 -3736 1169 -3735 rect 1175 -3709 1267 -3706 rect 1175 -3714 1179 -3709 rect 1165 -3740 1166 -3736 rect 1170 -3740 1172 -3736 rect 586 -3760 644 -3755 rect 872 -3760 880 -3740 rect 1175 -3749 1179 -3726 rect 1186 -3723 1190 -3716 rect 1197 -3714 1201 -3709 rect 1197 -3727 1201 -3726 rect 1208 -3723 1212 -3716 rect 1219 -3714 1223 -3709 rect 1219 -3727 1223 -3726 rect 1230 -3723 1234 -3716 rect 1241 -3714 1245 -3709 rect 1241 -3727 1245 -3726 rect 1252 -3723 1256 -3716 rect 1263 -3714 1267 -3709 rect 1263 -3727 1267 -3726 rect 1186 -3730 1190 -3727 rect 1208 -3730 1212 -3727 rect 1230 -3730 1234 -3727 rect 1252 -3730 1256 -3727 rect 1035 -3754 1179 -3749 rect 1182 -3733 1256 -3730 rect 1035 -3760 1040 -3754 rect 1182 -3760 1186 -3733 rect 1273 -3736 1277 -3734 rect 1367 -3703 1369 -3700 rect 1425 -3703 1427 -3699 rect 1373 -3709 1421 -3706 rect 1373 -3714 1377 -3709 rect 1373 -3727 1377 -3726 rect 1384 -3723 1388 -3716 rect 1395 -3714 1399 -3709 rect 1395 -3727 1399 -3726 rect 1406 -3723 1410 -3716 rect 1384 -3730 1388 -3727 rect 1406 -3730 1410 -3727 rect 1417 -3714 1421 -3709 rect 1384 -3733 1414 -3730 rect 1367 -3740 1369 -3736 rect 1405 -3740 1407 -3736 rect 1410 -3749 1414 -3733 rect 1355 -3753 1414 -3749 rect 1417 -3749 1421 -3726 rect 1427 -3736 1431 -3735 rect 1424 -3740 1425 -3736 rect 1429 -3740 1431 -3736 rect 1417 -3753 1445 -3749 rect 1355 -3760 1360 -3753 rect 0 -3763 80 -3760 rect 0 -3837 3 -3763 rect 77 -3837 80 -3763 rect 0 -3840 80 -3837 rect 160 -3763 240 -3760 rect 160 -3837 163 -3763 rect 237 -3837 240 -3763 rect 320 -3763 400 -3760 rect 160 -3840 240 -3837 rect 278 -3810 281 -3806 rect 274 -3813 285 -3810 rect 278 -3817 281 -3813 rect 274 -3820 285 -3817 rect 278 -3824 281 -3820 rect 35 -3846 46 -3840 rect 274 -3846 285 -3824 rect 320 -3837 323 -3763 rect 397 -3837 400 -3763 rect 320 -3840 400 -3837 rect 480 -3763 560 -3760 rect 480 -3837 483 -3763 rect 557 -3837 560 -3763 rect 640 -3763 720 -3760 rect 480 -3840 560 -3837 rect 598 -3810 601 -3806 rect 594 -3813 605 -3810 rect 598 -3817 601 -3813 rect 594 -3820 605 -3817 rect 598 -3824 601 -3820 rect 594 -3846 605 -3824 rect 640 -3837 643 -3763 rect 717 -3837 720 -3763 rect 640 -3840 720 -3837 rect 800 -3763 880 -3760 rect 800 -3837 803 -3763 rect 877 -3837 880 -3763 rect 960 -3763 1040 -3760 rect 800 -3840 880 -3837 rect 918 -3810 921 -3806 rect 914 -3813 925 -3810 rect 918 -3817 921 -3813 rect 914 -3820 925 -3817 rect 918 -3824 921 -3820 rect 914 -3846 925 -3824 rect 960 -3837 963 -3763 rect 1037 -3837 1040 -3763 rect 960 -3840 1040 -3837 rect 1120 -3763 1200 -3760 rect 1120 -3837 1123 -3763 rect 1197 -3837 1200 -3763 rect 1280 -3763 1360 -3760 rect 1120 -3840 1200 -3837 rect 1238 -3810 1241 -3806 rect 1234 -3813 1245 -3810 rect 1238 -3817 1241 -3813 rect 1234 -3820 1245 -3817 rect 1238 -3824 1241 -3820 rect 1234 -3846 1245 -3824 rect 1280 -3837 1283 -3763 rect 1357 -3837 1360 -3763 rect 1280 -3840 1360 -3837 rect 1440 -3760 1445 -3753 rect 1440 -3763 1520 -3760 rect 1440 -3837 1443 -3763 rect 1517 -3837 1520 -3763 rect 1440 -3840 1520 -3837 rect 1526 -3846 1534 -3594 rect -14 -3854 1534 -3846 << metal2 >> rect 0 -3603 80 -3600 rect 0 -3677 3 -3603 rect 77 -3677 80 -3603 rect 0 -3680 80 -3677 rect 160 -3603 240 -3600 rect 160 -3677 163 -3603 rect 237 -3677 240 -3603 rect 160 -3680 240 -3677 rect 320 -3603 400 -3600 rect 320 -3677 323 -3603 rect 397 -3677 400 -3603 rect 320 -3680 400 -3677 rect 480 -3603 560 -3600 rect 480 -3677 483 -3603 rect 557 -3677 560 -3603 rect 480 -3680 560 -3677 rect 640 -3603 720 -3600 rect 640 -3677 643 -3603 rect 717 -3677 720 -3603 rect 640 -3680 720 -3677 rect 800 -3603 880 -3600 rect 800 -3677 803 -3603 rect 877 -3677 880 -3603 rect 800 -3680 880 -3677 rect 960 -3603 1040 -3600 rect 960 -3677 963 -3603 rect 1037 -3677 1040 -3603 rect 960 -3680 1040 -3677 rect 1120 -3603 1200 -3600 rect 1120 -3677 1123 -3603 rect 1197 -3677 1200 -3603 rect 1120 -3680 1200 -3677 rect 1280 -3603 1360 -3600 rect 1280 -3677 1283 -3603 rect 1357 -3677 1360 -3603 rect 1280 -3680 1360 -3677 rect 1440 -3603 1520 -3600 rect 1440 -3677 1443 -3603 rect 1517 -3677 1520 -3603 rect 1440 -3680 1520 -3677 rect 0 -3763 80 -3760 rect 0 -3837 3 -3763 rect 77 -3837 80 -3763 rect 0 -3840 80 -3837 rect 160 -3763 240 -3760 rect 160 -3837 163 -3763 rect 237 -3837 240 -3763 rect 160 -3840 240 -3837 rect 320 -3763 400 -3760 rect 320 -3837 323 -3763 rect 397 -3837 400 -3763 rect 320 -3840 400 -3837 rect 480 -3763 560 -3760 rect 480 -3837 483 -3763 rect 557 -3837 560 -3763 rect 480 -3840 560 -3837 rect 640 -3763 720 -3760 rect 640 -3837 643 -3763 rect 717 -3837 720 -3763 rect 640 -3840 720 -3837 rect 800 -3763 880 -3760 rect 800 -3837 803 -3763 rect 877 -3837 880 -3763 rect 800 -3840 880 -3837 rect 960 -3763 1040 -3760 rect 960 -3837 963 -3763 rect 1037 -3837 1040 -3763 rect 960 -3840 1040 -3837 rect 1120 -3763 1200 -3760 rect 1120 -3837 1123 -3763 rect 1197 -3837 1200 -3763 rect 1120 -3840 1200 -3837 rect 1280 -3763 1360 -3760 rect 1280 -3837 1283 -3763 rect 1357 -3837 1360 -3763 rect 1280 -3840 1360 -3837 rect 1440 -3763 1520 -3760 rect 1440 -3837 1443 -3763 rect 1517 -3837 1520 -3763 rect 1440 -3840 1520 -3837 << collector >> rect 262 -3699 310 -3698 rect 262 -3700 269 -3699 rect 84 -3711 132 -3710 rect 84 -3715 85 -3711 rect 105 -3715 122 -3711 rect 131 -3715 132 -3711 rect 84 -3716 132 -3715 rect 84 -3736 85 -3716 rect 89 -3736 90 -3716 rect 126 -3736 127 -3716 rect 131 -3736 132 -3716 rect 84 -3737 132 -3736 rect 84 -3741 86 -3737 rect 130 -3741 132 -3737 rect 262 -3740 263 -3700 rect 267 -3703 269 -3700 rect 285 -3703 303 -3699 rect 307 -3703 310 -3699 rect 267 -3704 310 -3703 rect 267 -3735 268 -3704 rect 304 -3706 310 -3704 rect 304 -3734 305 -3706 rect 309 -3734 310 -3706 rect 304 -3735 310 -3734 rect 267 -3736 310 -3735 rect 267 -3740 268 -3736 rect 308 -3740 310 -3736 rect 262 -3741 310 -3740 rect 399 -3699 601 -3698 rect 399 -3700 406 -3699 rect 399 -3740 400 -3700 rect 404 -3703 406 -3700 rect 594 -3703 596 -3699 rect 404 -3704 596 -3703 rect 404 -3735 405 -3704 rect 595 -3735 596 -3704 rect 600 -3735 601 -3699 rect 404 -3736 601 -3735 rect 404 -3740 406 -3736 rect 574 -3740 594 -3736 rect 598 -3740 601 -3736 rect 399 -3741 601 -3740 rect 691 -3699 1070 -3698 rect 691 -3700 697 -3699 rect 691 -3740 692 -3700 rect 696 -3703 697 -3700 rect 1045 -3703 1064 -3699 rect 1068 -3703 1070 -3699 rect 696 -3704 1070 -3703 rect 696 -3735 697 -3704 rect 1064 -3735 1065 -3704 rect 696 -3736 1065 -3735 rect 696 -3740 698 -3736 rect 1062 -3740 1065 -3736 rect 1069 -3740 1070 -3704 rect 691 -3741 1070 -3740 rect 1164 -3699 1278 -3698 rect 1164 -3735 1165 -3699 rect 1169 -3703 1171 -3699 rect 1275 -3703 1278 -3699 rect 1169 -3704 1278 -3703 rect 1169 -3735 1170 -3704 rect 1272 -3706 1278 -3704 rect 1272 -3734 1273 -3706 rect 1277 -3734 1278 -3706 rect 1272 -3735 1278 -3734 rect 1164 -3736 1278 -3735 rect 1164 -3740 1166 -3736 rect 1170 -3740 1189 -3736 rect 1277 -3740 1278 -3736 rect 1164 -3741 1278 -3740 rect 1362 -3699 1432 -3698 rect 1362 -3700 1369 -3699 rect 1362 -3740 1363 -3700 rect 1367 -3703 1369 -3700 rect 1425 -3703 1427 -3699 rect 1367 -3704 1427 -3703 rect 1367 -3735 1368 -3704 rect 1426 -3735 1427 -3704 rect 1431 -3735 1432 -3699 rect 1367 -3736 1432 -3735 rect 1367 -3740 1369 -3736 rect 1405 -3740 1425 -3736 rect 1429 -3740 1432 -3736 rect 1362 -3741 1432 -3740 rect 84 -3742 132 -3741 << pbase >> rect 94 -3724 122 -3720 rect 94 -3728 95 -3724 rect 99 -3728 106 -3724 rect 110 -3728 117 -3724 rect 121 -3728 122 -3724 rect 94 -3732 122 -3728 rect 272 -3712 300 -3708 rect 272 -3714 284 -3712 rect 272 -3726 273 -3714 rect 277 -3716 284 -3714 rect 288 -3714 300 -3712 rect 288 -3716 295 -3714 rect 277 -3723 295 -3716 rect 277 -3726 284 -3723 rect 272 -3727 284 -3726 rect 288 -3726 295 -3723 rect 299 -3726 300 -3714 rect 288 -3727 300 -3726 rect 272 -3731 300 -3727 rect 409 -3712 591 -3708 rect 409 -3714 421 -3712 rect 409 -3726 410 -3714 rect 414 -3716 421 -3714 rect 425 -3714 443 -3712 rect 425 -3716 432 -3714 rect 414 -3723 432 -3716 rect 414 -3726 421 -3723 rect 409 -3727 421 -3726 rect 425 -3726 432 -3723 rect 436 -3716 443 -3714 rect 447 -3714 465 -3712 rect 447 -3716 454 -3714 rect 436 -3723 454 -3716 rect 436 -3726 443 -3723 rect 425 -3727 443 -3726 rect 447 -3726 454 -3723 rect 458 -3716 465 -3714 rect 469 -3714 487 -3712 rect 469 -3716 476 -3714 rect 458 -3723 476 -3716 rect 458 -3726 465 -3723 rect 447 -3727 465 -3726 rect 469 -3726 476 -3723 rect 480 -3716 487 -3714 rect 491 -3714 509 -3712 rect 491 -3716 498 -3714 rect 480 -3723 498 -3716 rect 480 -3726 487 -3723 rect 469 -3727 487 -3726 rect 491 -3726 498 -3723 rect 502 -3716 509 -3714 rect 513 -3714 531 -3712 rect 513 -3716 520 -3714 rect 502 -3723 520 -3716 rect 502 -3726 509 -3723 rect 491 -3727 509 -3726 rect 513 -3726 520 -3723 rect 524 -3716 531 -3714 rect 535 -3714 553 -3712 rect 535 -3716 542 -3714 rect 524 -3723 542 -3716 rect 524 -3726 531 -3723 rect 513 -3727 531 -3726 rect 535 -3726 542 -3723 rect 546 -3716 553 -3714 rect 557 -3714 575 -3712 rect 557 -3716 564 -3714 rect 546 -3723 564 -3716 rect 546 -3726 553 -3723 rect 535 -3727 553 -3726 rect 557 -3726 564 -3723 rect 568 -3716 575 -3714 rect 579 -3714 591 -3712 rect 579 -3716 586 -3714 rect 568 -3723 586 -3716 rect 568 -3726 575 -3723 rect 557 -3727 575 -3726 rect 579 -3726 586 -3723 rect 590 -3726 591 -3714 rect 579 -3727 591 -3726 rect 409 -3731 591 -3727 rect 701 -3712 1060 -3708 rect 701 -3714 713 -3712 rect 701 -3726 702 -3714 rect 706 -3716 713 -3714 rect 717 -3714 735 -3712 rect 717 -3716 724 -3714 rect 706 -3723 724 -3716 rect 706 -3726 713 -3723 rect 701 -3727 713 -3726 rect 717 -3726 724 -3723 rect 728 -3716 735 -3714 rect 739 -3714 757 -3712 rect 739 -3716 746 -3714 rect 728 -3723 746 -3716 rect 728 -3726 735 -3723 rect 717 -3727 735 -3726 rect 739 -3726 746 -3723 rect 750 -3716 757 -3714 rect 761 -3714 779 -3712 rect 761 -3716 768 -3714 rect 750 -3723 768 -3716 rect 750 -3726 757 -3723 rect 739 -3727 757 -3726 rect 761 -3726 768 -3723 rect 772 -3716 779 -3714 rect 783 -3714 801 -3712 rect 783 -3716 790 -3714 rect 772 -3723 790 -3716 rect 772 -3726 779 -3723 rect 761 -3727 779 -3726 rect 783 -3726 790 -3723 rect 794 -3716 801 -3714 rect 805 -3714 823 -3712 rect 805 -3716 812 -3714 rect 794 -3723 812 -3716 rect 794 -3726 801 -3723 rect 783 -3727 801 -3726 rect 805 -3726 812 -3723 rect 816 -3716 823 -3714 rect 827 -3714 845 -3712 rect 827 -3716 834 -3714 rect 816 -3723 834 -3716 rect 816 -3726 823 -3723 rect 805 -3727 823 -3726 rect 827 -3726 834 -3723 rect 838 -3716 845 -3714 rect 849 -3714 867 -3712 rect 849 -3716 856 -3714 rect 838 -3723 856 -3716 rect 838 -3726 845 -3723 rect 827 -3727 845 -3726 rect 849 -3726 856 -3723 rect 860 -3716 867 -3714 rect 871 -3714 889 -3712 rect 871 -3716 878 -3714 rect 860 -3723 878 -3716 rect 860 -3726 867 -3723 rect 849 -3727 867 -3726 rect 871 -3726 878 -3723 rect 882 -3716 889 -3714 rect 893 -3714 911 -3712 rect 893 -3716 900 -3714 rect 882 -3723 900 -3716 rect 882 -3726 889 -3723 rect 871 -3727 889 -3726 rect 893 -3726 900 -3723 rect 904 -3716 911 -3714 rect 915 -3714 933 -3712 rect 915 -3716 922 -3714 rect 904 -3723 922 -3716 rect 904 -3726 911 -3723 rect 893 -3727 911 -3726 rect 915 -3726 922 -3723 rect 926 -3716 933 -3714 rect 937 -3714 955 -3712 rect 937 -3716 944 -3714 rect 926 -3723 944 -3716 rect 926 -3726 933 -3723 rect 915 -3727 933 -3726 rect 937 -3726 944 -3723 rect 948 -3716 955 -3714 rect 959 -3714 978 -3712 rect 959 -3716 966 -3714 rect 948 -3723 966 -3716 rect 948 -3726 955 -3723 rect 937 -3727 955 -3726 rect 959 -3726 966 -3723 rect 970 -3716 978 -3714 rect 982 -3714 1000 -3712 rect 982 -3716 989 -3714 rect 970 -3723 989 -3716 rect 970 -3726 978 -3723 rect 959 -3727 978 -3726 rect 982 -3726 989 -3723 rect 993 -3716 1000 -3714 rect 1004 -3714 1022 -3712 rect 1004 -3716 1011 -3714 rect 993 -3723 1011 -3716 rect 993 -3726 1000 -3723 rect 982 -3727 1000 -3726 rect 1004 -3726 1011 -3723 rect 1015 -3716 1022 -3714 rect 1026 -3714 1044 -3712 rect 1026 -3716 1033 -3714 rect 1015 -3723 1033 -3716 rect 1015 -3726 1022 -3723 rect 1004 -3727 1022 -3726 rect 1026 -3726 1033 -3723 rect 1037 -3716 1044 -3714 rect 1048 -3714 1060 -3712 rect 1048 -3716 1055 -3714 rect 1037 -3723 1055 -3716 rect 1037 -3726 1044 -3723 rect 1026 -3727 1044 -3726 rect 1048 -3726 1055 -3723 rect 1059 -3726 1060 -3714 rect 1048 -3727 1060 -3726 rect 701 -3731 1060 -3727 rect 1174 -3712 1268 -3708 rect 1174 -3714 1186 -3712 rect 1174 -3726 1175 -3714 rect 1179 -3716 1186 -3714 rect 1190 -3714 1208 -3712 rect 1190 -3716 1197 -3714 rect 1179 -3723 1197 -3716 rect 1179 -3726 1186 -3723 rect 1174 -3727 1186 -3726 rect 1190 -3726 1197 -3723 rect 1201 -3716 1208 -3714 rect 1212 -3714 1230 -3712 rect 1212 -3716 1219 -3714 rect 1201 -3723 1219 -3716 rect 1201 -3726 1208 -3723 rect 1190 -3727 1208 -3726 rect 1212 -3726 1219 -3723 rect 1223 -3716 1230 -3714 rect 1234 -3714 1252 -3712 rect 1234 -3716 1241 -3714 rect 1223 -3723 1241 -3716 rect 1223 -3726 1230 -3723 rect 1212 -3727 1230 -3726 rect 1234 -3726 1241 -3723 rect 1245 -3716 1252 -3714 rect 1256 -3714 1268 -3712 rect 1256 -3716 1263 -3714 rect 1245 -3723 1263 -3716 rect 1245 -3726 1252 -3723 rect 1234 -3727 1252 -3726 rect 1256 -3726 1263 -3723 rect 1267 -3726 1268 -3714 rect 1256 -3727 1268 -3726 rect 1174 -3731 1268 -3727 rect 1372 -3712 1422 -3708 rect 1372 -3714 1384 -3712 rect 1372 -3726 1373 -3714 rect 1377 -3716 1384 -3714 rect 1388 -3714 1406 -3712 rect 1388 -3716 1395 -3714 rect 1377 -3723 1395 -3716 rect 1377 -3726 1384 -3723 rect 1372 -3727 1384 -3726 rect 1388 -3726 1395 -3723 rect 1399 -3716 1406 -3714 rect 1410 -3714 1422 -3712 rect 1410 -3716 1417 -3714 rect 1399 -3723 1417 -3716 rect 1399 -3726 1406 -3723 rect 1388 -3727 1406 -3726 rect 1410 -3726 1417 -3723 rect 1421 -3726 1422 -3714 rect 1410 -3727 1422 -3726 rect 1372 -3731 1422 -3727 << collectorcontact >> rect 85 -3715 105 -3711 rect 122 -3715 131 -3711 rect 85 -3736 89 -3716 rect 127 -3736 131 -3716 rect 86 -3741 130 -3737 rect 263 -3740 267 -3700 rect 269 -3703 285 -3699 rect 303 -3703 307 -3699 rect 305 -3734 309 -3706 rect 268 -3740 308 -3736 rect 400 -3740 404 -3700 rect 406 -3703 594 -3699 rect 596 -3735 600 -3699 rect 406 -3740 574 -3736 rect 594 -3740 598 -3736 rect 692 -3740 696 -3700 rect 697 -3703 1045 -3699 rect 1064 -3703 1068 -3699 rect 698 -3740 1062 -3736 rect 1065 -3740 1069 -3704 rect 1165 -3735 1169 -3699 rect 1171 -3703 1275 -3699 rect 1273 -3734 1277 -3706 rect 1166 -3740 1170 -3736 rect 1189 -3740 1277 -3736 rect 1363 -3740 1367 -3700 rect 1369 -3703 1425 -3699 rect 1427 -3735 1431 -3699 rect 1369 -3740 1405 -3736 rect 1425 -3740 1429 -3736 << emittercontact >> rect 106 -3728 110 -3724 rect 284 -3716 288 -3712 rect 284 -3727 288 -3723 rect 421 -3716 425 -3712 rect 421 -3727 425 -3723 rect 443 -3716 447 -3712 rect 443 -3727 447 -3723 rect 465 -3716 469 -3712 rect 465 -3727 469 -3723 rect 487 -3716 491 -3712 rect 487 -3727 491 -3723 rect 509 -3716 513 -3712 rect 509 -3727 513 -3723 rect 531 -3716 535 -3712 rect 531 -3727 535 -3723 rect 553 -3716 557 -3712 rect 553 -3727 557 -3723 rect 575 -3716 579 -3712 rect 575 -3727 579 -3723 rect 713 -3716 717 -3712 rect 713 -3727 717 -3723 rect 735 -3716 739 -3712 rect 735 -3727 739 -3723 rect 757 -3716 761 -3712 rect 757 -3727 761 -3723 rect 779 -3716 783 -3712 rect 779 -3727 783 -3723 rect 801 -3716 805 -3712 rect 801 -3727 805 -3723 rect 823 -3716 827 -3712 rect 823 -3727 827 -3723 rect 845 -3716 849 -3712 rect 845 -3727 849 -3723 rect 867 -3716 871 -3712 rect 867 -3727 871 -3723 rect 889 -3716 893 -3712 rect 889 -3727 893 -3723 rect 911 -3716 915 -3712 rect 911 -3727 915 -3723 rect 933 -3716 937 -3712 rect 933 -3727 937 -3723 rect 955 -3716 959 -3712 rect 955 -3727 959 -3723 rect 978 -3716 982 -3712 rect 978 -3727 982 -3723 rect 1000 -3716 1004 -3712 rect 1000 -3727 1004 -3723 rect 1022 -3716 1026 -3712 rect 1022 -3727 1026 -3723 rect 1044 -3716 1048 -3712 rect 1044 -3727 1048 -3723 rect 1186 -3716 1190 -3712 rect 1186 -3727 1190 -3723 rect 1208 -3716 1212 -3712 rect 1208 -3727 1212 -3723 rect 1230 -3716 1234 -3712 rect 1230 -3727 1234 -3723 rect 1252 -3716 1256 -3712 rect 1252 -3727 1256 -3723 rect 1384 -3716 1388 -3712 rect 1384 -3727 1388 -3723 rect 1406 -3716 1410 -3712 rect 1406 -3727 1410 -3723 << pbasecontact >> rect 95 -3728 99 -3724 rect 117 -3728 121 -3724 rect 273 -3726 277 -3714 rect 295 -3726 299 -3714 rect 410 -3726 414 -3714 rect 432 -3726 436 -3714 rect 454 -3726 458 -3714 rect 476 -3726 480 -3714 rect 498 -3726 502 -3714 rect 520 -3726 524 -3714 rect 542 -3726 546 -3714 rect 564 -3726 568 -3714 rect 586 -3726 590 -3714 rect 702 -3726 706 -3714 rect 724 -3726 728 -3714 rect 746 -3726 750 -3714 rect 768 -3726 772 -3714 rect 790 -3726 794 -3714 rect 812 -3726 816 -3714 rect 834 -3726 838 -3714 rect 856 -3726 860 -3714 rect 878 -3726 882 -3714 rect 900 -3726 904 -3714 rect 922 -3726 926 -3714 rect 944 -3726 948 -3714 rect 966 -3726 970 -3714 rect 989 -3726 993 -3714 rect 1011 -3726 1015 -3714 rect 1033 -3726 1037 -3714 rect 1055 -3726 1059 -3714 rect 1175 -3726 1179 -3714 rect 1197 -3726 1201 -3714 rect 1219 -3726 1223 -3714 rect 1241 -3726 1245 -3714 rect 1263 -3726 1267 -3714 rect 1373 -3726 1377 -3714 rect 1395 -3726 1399 -3714 rect 1417 -3726 1421 -3714 << m2contact >> rect 3 -3677 77 -3603 rect 163 -3677 237 -3603 rect 323 -3677 397 -3603 rect 483 -3677 557 -3603 rect 643 -3677 717 -3603 rect 803 -3677 877 -3603 rect 963 -3677 1037 -3603 rect 1123 -3677 1197 -3603 rect 1283 -3677 1357 -3603 rect 1443 -3677 1517 -3603 rect 3 -3837 77 -3763 rect 163 -3837 237 -3763 rect 323 -3837 397 -3763 rect 483 -3837 557 -3763 rect 643 -3837 717 -3763 rect 803 -3837 877 -3763 rect 963 -3837 1037 -3763 rect 1123 -3837 1197 -3763 rect 1283 -3837 1357 -3763 rect 1443 -3837 1517 -3763 << psubstratepcontact >> rect 114 -3620 118 -3616 rect 121 -3620 125 -3616 rect 114 -3627 118 -3623 rect 121 -3627 125 -3623 rect 114 -3634 118 -3630 rect 121 -3634 125 -3630 rect 434 -3620 438 -3616 rect 441 -3620 445 -3616 rect 434 -3627 438 -3623 rect 441 -3627 445 -3623 rect 434 -3634 438 -3630 rect 441 -3634 445 -3630 rect 754 -3620 758 -3616 rect 761 -3620 765 -3616 rect 754 -3627 758 -3623 rect 761 -3627 765 -3623 rect 754 -3634 758 -3630 rect 761 -3634 765 -3630 rect 1074 -3620 1078 -3616 rect 1081 -3620 1085 -3616 rect 1074 -3627 1078 -3623 rect 1081 -3627 1085 -3623 rect 1074 -3634 1078 -3630 rect 1081 -3634 1085 -3630 rect 1394 -3620 1398 -3616 rect 1401 -3620 1405 -3616 rect 1394 -3627 1398 -3623 rect 1401 -3627 1405 -3623 rect 1394 -3634 1398 -3630 rect 1401 -3634 1405 -3630 rect 274 -3810 278 -3806 rect 281 -3810 285 -3806 rect 274 -3817 278 -3813 rect 281 -3817 285 -3813 rect 274 -3824 278 -3820 rect 281 -3824 285 -3820 rect 594 -3810 598 -3806 rect 601 -3810 605 -3806 rect 594 -3817 598 -3813 rect 601 -3817 605 -3813 rect 594 -3824 598 -3820 rect 601 -3824 605 -3820 rect 914 -3810 918 -3806 rect 921 -3810 925 -3806 rect 914 -3817 918 -3813 rect 921 -3817 925 -3813 rect 914 -3824 918 -3820 rect 921 -3824 925 -3820 rect 1234 -3810 1238 -3806 rect 1241 -3810 1245 -3806 rect 1234 -3817 1238 -3813 rect 1241 -3817 1245 -3813 rect 1234 -3824 1238 -3820 rect 1241 -3824 1245 -3820 << psubstratepdiff >> rect 118 -3620 121 -3616 rect 114 -3623 125 -3620 rect 118 -3627 121 -3623 rect 114 -3630 125 -3627 rect 118 -3634 121 -3630 rect 438 -3620 441 -3616 rect 434 -3623 445 -3620 rect 438 -3627 441 -3623 rect 434 -3630 445 -3627 rect 438 -3634 441 -3630 rect 758 -3620 761 -3616 rect 754 -3623 765 -3620 rect 758 -3627 761 -3623 rect 754 -3630 765 -3627 rect 758 -3634 761 -3630 rect 1078 -3620 1081 -3616 rect 1074 -3623 1085 -3620 rect 1078 -3627 1081 -3623 rect 1074 -3630 1085 -3627 rect 1078 -3634 1081 -3630 rect 1398 -3620 1401 -3616 rect 1394 -3623 1405 -3620 rect 1398 -3627 1401 -3623 rect 1394 -3630 1405 -3627 rect 1398 -3634 1401 -3630 rect 278 -3810 281 -3806 rect 274 -3813 285 -3810 rect 278 -3817 281 -3813 rect 274 -3820 285 -3817 rect 278 -3824 281 -3820 rect 598 -3810 601 -3806 rect 594 -3813 605 -3810 rect 598 -3817 601 -3813 rect 594 -3820 605 -3817 rect 598 -3824 601 -3820 rect 918 -3810 921 -3806 rect 914 -3813 925 -3810 rect 918 -3817 921 -3813 rect 914 -3820 925 -3817 rect 918 -3824 921 -3820 rect 1238 -3810 1241 -3806 rect 1234 -3813 1245 -3810 rect 1238 -3817 1241 -3813 rect 1234 -3820 1245 -3817 rect 1238 -3824 1241 -3820 << glass >> rect 3 -3677 77 -3603 rect 163 -3677 237 -3603 rect 323 -3677 397 -3603 rect 483 -3677 557 -3603 rect 643 -3677 717 -3603 rect 803 -3677 877 -3603 rect 963 -3677 1037 -3603 rect 1123 -3677 1197 -3603 rect 1283 -3677 1357 -3603 rect 1443 -3677 1517 -3603 rect 3 -3837 77 -3763 rect 163 -3837 237 -3763 rect 323 -3837 397 -3763 rect 483 -3837 557 -3763 rect 643 -3837 717 -3763 rect 803 -3837 877 -3763 rect 963 -3837 1037 -3763 rect 1123 -3837 1197 -3763 rect 1283 -3837 1357 -3763 rect 1443 -3837 1517 -3763 << end >> magic-8.0.210/scmos/examples/bipolar/min_npn.mag0000644000175000001440000000237510751423606020203 0ustar timusersmagic tech scmos timestamp 783737496 << nwell >> rect 8 58 49 82 rect 62 51 100 89 rect 0 0 48 38 << metal1 >> rect 12 55 16 68 rect 25 55 29 68 rect 36 55 40 68 << collector >> rect 65 85 97 86 rect 65 81 66 85 rect 96 81 97 85 rect 65 80 97 81 rect 11 72 17 73 rect 11 68 12 72 rect 16 68 17 72 rect 11 67 17 68 rect 65 59 97 60 rect 65 55 66 59 rect 96 55 97 59 rect 65 54 97 55 rect 3 34 45 35 rect 3 30 9 34 rect 37 30 45 34 rect 3 29 45 30 rect 3 9 9 29 rect 39 9 45 29 rect 3 8 45 9 rect 3 4 8 8 rect 39 4 45 8 rect 3 3 45 4 << pbase >> rect 21 75 33 76 rect 21 72 43 75 rect 21 68 25 72 rect 29 68 36 72 rect 40 68 43 72 rect 21 65 43 68 rect 71 72 93 76 rect 71 68 75 72 rect 79 68 86 72 rect 90 68 93 72 rect 21 64 33 65 rect 71 64 93 68 rect 13 21 35 25 rect 13 17 17 21 rect 21 17 28 21 rect 32 17 35 21 rect 13 13 35 17 << collectorcontact >> rect 66 81 96 85 rect 12 68 16 72 rect 66 55 96 59 rect 9 30 37 34 rect 8 4 39 8 << emittercontact >> rect 25 68 29 72 rect 75 68 79 72 rect 17 17 21 21 << pbasecontact >> rect 36 68 40 72 rect 86 68 90 72 rect 28 17 32 21 << labels >> rlabel space 3 72 3 72 3 without rlabel space 3 68 3 68 3 guardring rlabel metal1 12 55 16 55 5 collector rlabel metal1 25 55 29 55 5 emitter rlabel metal1 36 55 40 55 5 base << end >> magic-8.0.210/scmos/examples/bipolar/pbase-resis.mag0000644000175000001440000000472310751423606020761 0ustar timusersmagic tech scmos timestamp 801255023 << nwell >> rect -4 52 96 140 rect 0 -2 92 43 << metal1 >> rect 21 124 39 128 rect 65 124 83 128 rect 10 110 28 114 rect 54 110 72 114 rect -5 75 17 79 rect 43 75 61 79 rect 83 65 87 75 rect -5 61 6 65 rect 32 61 50 65 rect 76 61 87 65 rect 78 34 92 35 rect 78 30 79 34 rect 83 30 92 34 rect 78 29 92 30 rect 0 11 14 12 rect 0 7 9 11 rect 13 7 14 11 rect 0 6 14 7 << pbase >> rect 14 128 24 131 rect 14 124 17 128 rect 21 124 24 128 rect 14 121 24 124 rect 36 128 46 131 rect 36 124 39 128 rect 43 124 46 128 rect 36 121 46 124 rect 58 128 68 131 rect 58 124 61 128 rect 65 124 68 128 rect 58 121 68 124 rect 80 128 90 131 rect 80 124 83 128 rect 87 124 90 128 rect 80 121 90 124 rect 3 114 13 117 rect 3 110 6 114 rect 10 110 13 114 rect 3 107 13 110 rect 6 68 10 107 rect 17 82 21 121 rect 25 114 35 117 rect 25 110 28 114 rect 32 110 35 114 rect 25 107 35 110 rect 14 79 24 82 rect 14 75 17 79 rect 21 75 24 79 rect 14 72 24 75 rect 28 68 32 107 rect 39 82 43 121 rect 47 114 57 117 rect 47 110 50 114 rect 54 110 57 114 rect 47 107 57 110 rect 36 79 46 82 rect 36 75 39 79 rect 43 75 46 79 rect 36 72 46 75 rect 50 68 54 107 rect 61 82 65 121 rect 69 114 79 117 rect 69 110 72 114 rect 76 110 79 114 rect 69 107 79 110 rect 58 79 68 82 rect 58 75 61 79 rect 65 75 68 79 rect 58 72 68 75 rect 72 68 76 107 rect 83 82 87 121 rect 80 79 90 82 rect 80 75 83 79 rect 87 75 90 79 rect 80 72 90 75 rect 3 65 13 68 rect 3 61 6 65 rect 10 61 13 65 rect 3 58 13 61 rect 25 65 35 68 rect 25 61 28 65 rect 32 61 35 65 rect 25 58 35 61 rect 47 65 57 68 rect 47 61 50 65 rect 54 61 57 65 rect 47 58 57 61 rect 69 65 79 68 rect 69 61 72 65 rect 76 61 79 65 rect 69 58 79 61 rect 9 33 24 37 rect 9 14 13 33 rect 6 11 16 14 rect 6 7 9 11 rect 13 7 16 11 rect 6 4 16 7 rect 20 8 24 33 rect 28 33 40 37 rect 28 8 32 33 rect 20 4 32 8 rect 36 8 40 33 rect 44 33 56 37 rect 44 8 48 33 rect 36 4 48 8 rect 52 8 56 33 rect 60 33 72 37 rect 60 8 64 33 rect 52 4 64 8 rect 68 8 72 33 rect 76 34 86 37 rect 76 30 79 34 rect 83 30 86 34 rect 76 27 86 30 rect 79 8 83 27 rect 68 4 83 8 << pbasecontact >> rect 17 124 21 128 rect 39 124 43 128 rect 61 124 65 128 rect 83 124 87 128 rect 6 110 10 114 rect 28 110 32 114 rect 17 75 21 79 rect 50 110 54 114 rect 39 75 43 79 rect 72 110 76 114 rect 61 75 65 79 rect 83 75 87 79 rect 6 61 10 65 rect 28 61 32 65 rect 50 61 54 65 rect 72 61 76 65 rect 9 7 13 11 rect 79 30 83 34 << labels >> rlabel metal1 2 9 2 9 3 a rlabel metal1 90 32 90 32 7 b << end >> magic-8.0.210/scmos/examples/nist-mems-library/0000755000175000001440000000000011504623577020004 5ustar timusersmagic-8.0.210/scmos/examples/nist-mems-library/thermal-converter.mag0000644000175000001440000002500210751423606024124 0ustar timusersmagic tech scmos timestamp 760840748 << polysilicon >> rect 1 87 118 91 rect 1 76 5 87 rect 7 84 13 85 rect 7 80 8 84 rect 12 80 13 84 rect 7 79 13 80 rect 16 84 22 85 rect 16 80 17 84 rect 21 80 22 84 rect 16 79 22 80 rect 25 84 31 85 rect 25 80 26 84 rect 30 80 31 84 rect 25 79 31 80 rect 34 84 40 85 rect 34 80 35 84 rect 39 80 40 84 rect 34 79 40 80 rect 43 84 49 85 rect 43 80 44 84 rect 48 80 49 84 rect 43 79 49 80 rect 52 84 58 85 rect 52 80 53 84 rect 57 80 58 84 rect 52 79 58 80 rect 10 76 13 79 rect 19 76 22 79 rect 28 76 31 79 rect 37 76 40 79 rect 46 76 49 79 rect 1 75 7 76 rect 1 71 2 75 rect 6 71 7 75 rect 10 73 16 76 rect 19 73 25 76 rect 28 73 34 76 rect 37 73 43 76 rect 46 73 52 76 rect 1 70 7 71 rect 13 70 16 73 rect 22 70 25 73 rect 31 70 34 73 rect 40 70 43 73 rect 13 67 19 70 rect 22 67 28 70 rect 31 67 37 70 rect 40 67 46 70 rect 16 64 19 67 rect 25 64 28 67 rect 34 64 37 67 rect 16 61 22 64 rect 25 61 31 64 rect 34 61 40 64 rect 19 58 22 61 rect 28 58 31 61 rect 19 55 25 58 rect 28 55 34 58 rect 22 52 25 55 rect 22 49 28 52 rect 25 -65 28 49 rect 22 -68 28 -65 rect 22 -71 25 -68 rect 31 -71 34 55 rect 19 -74 25 -71 rect 28 -74 34 -71 rect 19 -77 22 -74 rect 28 -77 31 -74 rect 37 -77 40 61 rect 16 -80 22 -77 rect 25 -80 31 -77 rect 34 -80 40 -77 rect 16 -95 19 -80 rect 25 -95 28 -80 rect 34 -95 37 -80 rect 43 -95 46 67 rect 49 -89 52 73 rect 55 -83 58 79 rect 61 84 67 85 rect 61 80 62 84 rect 66 80 67 84 rect 61 79 67 80 rect 70 84 76 85 rect 70 80 71 84 rect 75 80 76 84 rect 70 79 76 80 rect 79 84 85 85 rect 79 80 80 84 rect 84 80 85 84 rect 79 79 85 80 rect 88 84 94 85 rect 88 80 89 84 rect 93 80 94 84 rect 88 79 94 80 rect 97 84 103 85 rect 97 80 98 84 rect 102 80 103 84 rect 97 79 103 80 rect 106 84 112 85 rect 106 80 107 84 rect 111 80 112 84 rect 106 79 112 80 rect 61 -77 64 79 rect 70 76 73 79 rect 79 76 82 79 rect 88 76 91 79 rect 97 76 100 79 rect 106 76 109 79 rect 114 76 118 87 rect 67 73 73 76 rect 76 73 82 76 rect 85 73 91 76 rect 94 73 100 76 rect 103 73 109 76 rect 112 75 118 76 rect 67 -71 70 73 rect 76 70 79 73 rect 85 70 88 73 rect 94 70 97 73 rect 103 70 106 73 rect 112 71 113 75 rect 117 71 118 75 rect 112 70 118 71 rect 73 67 79 70 rect 82 67 88 70 rect 91 67 97 70 rect 100 67 106 70 rect 73 -65 76 67 rect 82 64 85 67 rect 91 64 94 67 rect 100 64 103 67 rect 79 61 85 64 rect 88 61 94 64 rect 97 61 103 64 rect 79 -59 82 61 rect 88 58 91 61 rect 97 58 100 61 rect 85 55 91 58 rect 94 55 100 58 rect 85 -53 88 55 rect 94 52 97 55 rect 91 49 97 52 rect 91 -47 94 49 rect 91 -50 100 -47 rect 85 -56 94 -53 rect 79 -62 88 -59 rect 73 -68 82 -65 rect 67 -74 76 -71 rect 61 -80 70 -77 rect 55 -86 64 -83 rect 49 -92 55 -89 rect 52 -95 55 -92 rect 61 -95 64 -86 rect 67 -89 70 -80 rect 73 -83 76 -74 rect 79 -77 82 -68 rect 85 -71 88 -62 rect 91 -65 94 -56 rect 97 -59 100 -50 rect 97 -62 103 -59 rect 100 -65 103 -62 rect 91 -68 97 -65 rect 100 -68 106 -65 rect 94 -71 97 -68 rect 103 -71 106 -68 rect 85 -74 91 -71 rect 94 -74 100 -71 rect 103 -74 109 -71 rect 88 -77 91 -74 rect 97 -77 100 -74 rect 106 -77 109 -74 rect 79 -80 85 -77 rect 88 -80 94 -77 rect 97 -80 103 -77 rect 106 -80 112 -77 rect 82 -83 85 -80 rect 91 -83 94 -80 rect 100 -83 103 -80 rect 109 -83 112 -80 rect 73 -86 79 -83 rect 82 -86 88 -83 rect 91 -86 97 -83 rect 100 -86 106 -83 rect 109 -86 115 -83 rect 76 -89 79 -86 rect 85 -89 88 -86 rect 94 -89 97 -86 rect 103 -89 106 -86 rect 112 -88 115 -86 rect 67 -92 73 -89 rect 76 -92 82 -89 rect 85 -92 91 -89 rect 94 -92 100 -89 rect 103 -92 109 -89 rect 112 -91 118 -88 rect 70 -95 73 -92 rect 79 -95 82 -92 rect 88 -95 91 -92 rect 97 -95 100 -92 rect 106 -95 109 -92 rect 115 -95 118 -91 rect 16 -96 22 -95 rect 16 -100 17 -96 rect 21 -100 22 -96 rect 16 -101 22 -100 rect 25 -96 31 -95 rect 25 -100 26 -96 rect 30 -100 31 -96 rect 25 -101 31 -100 rect 34 -96 40 -95 rect 34 -100 35 -96 rect 39 -100 40 -96 rect 34 -101 40 -100 rect 43 -96 49 -95 rect 43 -100 44 -96 rect 48 -100 49 -96 rect 43 -101 49 -100 rect 52 -96 58 -95 rect 52 -100 53 -96 rect 57 -100 58 -96 rect 52 -101 58 -100 rect 61 -96 67 -95 rect 61 -100 62 -96 rect 66 -100 67 -96 rect 61 -101 67 -100 rect 70 -96 76 -95 rect 70 -100 71 -96 rect 75 -100 76 -96 rect 70 -101 76 -100 rect 79 -96 85 -95 rect 79 -100 80 -96 rect 84 -100 85 -96 rect 79 -101 85 -100 rect 88 -96 94 -95 rect 88 -100 89 -96 rect 93 -100 94 -96 rect 88 -101 94 -100 rect 97 -96 103 -95 rect 97 -100 98 -96 rect 102 -100 103 -96 rect 97 -101 103 -100 rect 106 -96 112 -95 rect 106 -100 107 -96 rect 111 -100 112 -96 rect 106 -101 112 -100 rect 115 -96 121 -95 rect 115 -100 116 -96 rect 120 -100 121 -96 rect 115 -101 121 -100 << metal1 >> rect 7 84 13 85 rect 7 80 8 84 rect 12 80 13 84 rect 7 79 13 80 rect 16 84 22 85 rect 16 80 17 84 rect 21 80 22 84 rect 16 79 22 80 rect 25 84 31 85 rect 25 80 26 84 rect 30 80 31 84 rect 25 79 31 80 rect 34 84 40 85 rect 34 80 35 84 rect 39 80 40 84 rect 34 79 40 80 rect 43 84 49 85 rect 43 80 44 84 rect 48 80 49 84 rect 43 79 49 80 rect 52 84 58 85 rect 52 80 53 84 rect 57 80 58 84 rect 52 79 58 80 rect 10 76 13 79 rect 19 76 22 79 rect 28 76 31 79 rect 37 76 40 79 rect 46 76 49 79 rect 1 75 7 76 rect 1 71 2 75 rect 6 71 7 75 rect 10 73 16 76 rect 19 73 25 76 rect 28 73 34 76 rect 37 73 43 76 rect 46 73 52 76 rect 1 70 7 71 rect 13 70 16 73 rect 22 70 25 73 rect 31 70 34 73 rect 40 70 43 73 rect 4 67 10 70 rect 13 67 19 70 rect 22 67 28 70 rect 31 67 37 70 rect 40 67 46 70 rect 7 64 10 67 rect 16 64 19 67 rect 25 64 28 67 rect 34 64 37 67 rect 7 61 13 64 rect 16 61 22 64 rect 25 61 31 64 rect 34 61 40 64 rect 10 58 13 61 rect 19 58 22 61 rect 28 58 31 61 rect 10 55 16 58 rect 19 55 25 58 rect 28 55 34 58 rect 13 52 16 55 rect 22 52 25 55 rect 13 49 19 52 rect 22 49 28 52 rect 16 46 19 49 rect 16 43 22 46 rect 19 -59 22 43 rect 16 -62 22 -59 rect 16 -65 19 -62 rect 25 -65 28 49 rect 13 -68 19 -65 rect 22 -68 28 -65 rect 13 -71 16 -68 rect 22 -71 25 -68 rect 31 -71 34 55 rect 10 -74 16 -71 rect 19 -74 25 -71 rect 28 -74 34 -71 rect 10 -77 13 -74 rect 19 -77 22 -74 rect 28 -77 31 -74 rect 37 -77 40 61 rect 4 -80 13 -77 rect 16 -80 22 -77 rect 25 -80 31 -77 rect 34 -80 40 -77 rect 4 -110 7 -80 rect 16 -83 19 -80 rect 25 -83 28 -80 rect 34 -83 37 -80 rect 43 -83 46 67 rect 10 -86 19 -83 rect 22 -86 28 -83 rect 31 -86 37 -83 rect 40 -86 46 -83 rect 10 -110 13 -86 rect 22 -89 25 -86 rect 31 -89 34 -86 rect 40 -89 43 -86 rect 49 -89 52 73 rect 19 -92 25 -89 rect 28 -92 34 -89 rect 37 -92 43 -89 rect 46 -92 52 -89 rect 19 -95 22 -92 rect 28 -95 31 -92 rect 37 -95 40 -92 rect 46 -95 49 -92 rect 55 -95 58 79 rect 16 -96 22 -95 rect 16 -100 17 -96 rect 21 -100 22 -96 rect 16 -101 22 -100 rect 25 -96 31 -95 rect 25 -100 26 -96 rect 30 -100 31 -96 rect 25 -101 31 -100 rect 34 -96 40 -95 rect 34 -100 35 -96 rect 39 -100 40 -96 rect 34 -101 40 -100 rect 43 -96 49 -95 rect 43 -100 44 -96 rect 48 -100 49 -96 rect 43 -101 49 -100 rect 52 -96 58 -95 rect 52 -100 53 -96 rect 57 -100 58 -96 rect 52 -101 58 -100 rect 61 84 67 85 rect 61 80 62 84 rect 66 80 67 84 rect 61 79 67 80 rect 70 84 76 85 rect 70 80 71 84 rect 75 80 76 84 rect 70 79 76 80 rect 79 84 85 85 rect 79 80 80 84 rect 84 80 85 84 rect 79 79 85 80 rect 88 84 94 85 rect 88 80 89 84 rect 93 80 94 84 rect 88 79 94 80 rect 97 84 103 85 rect 97 80 98 84 rect 102 80 103 84 rect 97 79 103 80 rect 106 84 112 85 rect 106 80 107 84 rect 111 80 112 84 rect 106 79 112 80 rect 61 -95 64 79 rect 70 76 73 79 rect 79 76 82 79 rect 88 76 91 79 rect 97 76 100 79 rect 106 76 109 79 rect 67 73 73 76 rect 76 73 82 76 rect 85 73 91 76 rect 94 73 100 76 rect 103 73 109 76 rect 112 75 118 76 rect 67 -89 70 73 rect 76 70 79 73 rect 85 70 88 73 rect 94 70 97 73 rect 103 70 106 73 rect 112 71 113 75 rect 117 71 118 75 rect 112 70 118 71 rect 73 67 79 70 rect 82 67 88 70 rect 91 67 97 70 rect 100 67 106 70 rect 109 67 115 70 rect 73 -83 76 67 rect 82 64 85 67 rect 91 64 94 67 rect 100 64 103 67 rect 109 64 112 67 rect 79 61 85 64 rect 88 61 94 64 rect 97 61 103 64 rect 106 61 112 64 rect 79 -77 82 61 rect 88 58 91 61 rect 97 58 100 61 rect 106 58 109 61 rect 85 55 91 58 rect 94 55 100 58 rect 103 55 109 58 rect 85 -71 88 55 rect 94 52 97 55 rect 103 52 106 55 rect 91 49 97 52 rect 100 49 106 52 rect 91 -65 94 49 rect 100 46 103 49 rect 97 43 103 46 rect 97 -59 100 43 rect 97 -62 103 -59 rect 100 -65 103 -62 rect 91 -68 97 -65 rect 100 -68 106 -65 rect 94 -71 97 -68 rect 103 -71 106 -68 rect 85 -74 91 -71 rect 94 -74 100 -71 rect 103 -74 109 -71 rect 88 -77 91 -74 rect 97 -77 100 -74 rect 106 -77 109 -74 rect 79 -80 85 -77 rect 88 -80 94 -77 rect 97 -80 103 -77 rect 106 -80 112 -77 rect 82 -83 85 -80 rect 91 -83 94 -80 rect 100 -83 103 -80 rect 109 -83 112 -80 rect 73 -86 79 -83 rect 82 -86 88 -83 rect 91 -86 97 -83 rect 100 -86 106 -83 rect 109 -86 115 -83 rect 76 -89 79 -86 rect 85 -89 88 -86 rect 94 -89 97 -86 rect 103 -89 106 -86 rect 112 -88 115 -86 rect 67 -92 73 -89 rect 76 -92 82 -89 rect 85 -92 91 -89 rect 94 -92 100 -89 rect 103 -92 109 -89 rect 112 -91 127 -88 rect 70 -95 73 -92 rect 79 -95 82 -92 rect 88 -95 91 -92 rect 97 -95 100 -92 rect 106 -95 109 -92 rect 61 -96 67 -95 rect 61 -100 62 -96 rect 66 -100 67 -96 rect 61 -101 67 -100 rect 70 -96 76 -95 rect 70 -100 71 -96 rect 75 -100 76 -96 rect 70 -101 76 -100 rect 79 -96 85 -95 rect 79 -100 80 -96 rect 84 -100 85 -96 rect 79 -101 85 -100 rect 88 -96 94 -95 rect 88 -100 89 -96 rect 93 -100 94 -96 rect 88 -101 94 -100 rect 97 -96 103 -95 rect 97 -100 98 -96 rect 102 -100 103 -96 rect 97 -101 103 -100 rect 106 -96 112 -95 rect 106 -100 107 -96 rect 111 -100 112 -96 rect 106 -101 112 -100 rect 115 -96 121 -95 rect 115 -100 116 -96 rect 120 -100 121 -96 rect 115 -101 121 -100 rect 115 -110 118 -101 rect 124 -110 127 -91 << polycontact >> rect 8 80 12 84 rect 17 80 21 84 rect 26 80 30 84 rect 35 80 39 84 rect 44 80 48 84 rect 53 80 57 84 rect 2 71 6 75 rect 62 80 66 84 rect 71 80 75 84 rect 80 80 84 84 rect 89 80 93 84 rect 98 80 102 84 rect 107 80 111 84 rect 113 71 117 75 rect 17 -100 21 -96 rect 26 -100 30 -96 rect 35 -100 39 -96 rect 44 -100 48 -96 rect 53 -100 57 -96 rect 62 -100 66 -96 rect 71 -100 75 -96 rect 80 -100 84 -96 rect 89 -100 93 -96 rect 98 -100 102 -96 rect 107 -100 111 -96 rect 116 -100 120 -96 << substrateopen >> rect -16 94 134 110 rect -16 67 -3 94 rect 121 67 134 94 rect -16 64 0 67 rect 118 64 134 67 rect -16 58 3 64 rect 115 58 134 64 rect -16 52 6 58 rect 112 52 134 58 rect -16 46 9 52 rect 109 46 134 52 rect -16 40 12 46 rect 106 40 134 46 rect -16 -10 16 40 rect 102 -10 134 40 << labels >> rlabel metal1 125 -109 125 -109 8 heater2 rlabel metal1 5 -109 5 -109 8 heater1 rlabel metal1 11 -109 11 -109 8 Vmeas1 rlabel metal1 116 -109 116 -109 8 Vmeas2 << end >> magic-8.0.210/scmos/examples/nist-mems-library/gas-sensor.mag0000644000175000001440000005062510751423606022555 0ustar timusersmagic tech scmos timestamp 760840948 << polysilicon >> rect 250 265 260 266 rect 249 264 260 265 rect 248 263 260 264 rect 247 262 253 263 rect 246 261 253 262 rect 245 260 253 261 rect 244 259 253 260 rect 257 259 260 263 rect 243 258 260 259 rect 242 257 260 258 rect 241 256 260 257 rect 240 255 259 256 rect 239 254 258 255 rect 238 253 257 254 rect 237 252 256 253 rect 236 251 255 252 rect 235 250 254 251 rect 234 249 253 250 rect 233 248 252 249 rect 232 247 251 248 rect 231 246 250 247 rect 230 245 249 246 rect 229 244 248 245 rect 228 243 247 244 rect 227 242 246 243 rect 226 241 245 242 rect 225 240 244 241 rect 224 239 243 240 rect 223 238 242 239 rect 222 237 241 238 rect 221 236 240 237 rect 220 235 239 236 rect 219 234 238 235 rect 218 233 237 234 rect 217 232 236 233 rect 216 231 235 232 rect 215 230 234 231 rect 214 229 233 230 rect 213 228 232 229 rect 212 227 231 228 rect 211 226 230 227 rect 210 225 229 226 rect 209 224 228 225 rect 208 223 227 224 rect 207 222 226 223 rect 206 221 225 222 rect 205 220 224 221 rect 204 219 223 220 rect 203 218 222 219 rect 202 217 221 218 rect 201 216 220 217 rect 200 215 219 216 rect 199 214 218 215 rect 198 213 217 214 rect 197 212 216 213 rect 196 211 215 212 rect 195 210 214 211 rect 194 209 213 210 rect 193 208 212 209 rect 192 207 211 208 rect 191 206 210 207 rect 190 205 209 206 rect 189 204 208 205 rect 188 203 207 204 rect 187 202 206 203 rect 186 201 205 202 rect 185 200 204 201 rect 184 199 203 200 rect 183 198 202 199 rect 182 197 201 198 rect 181 196 200 197 rect 180 195 199 196 rect 179 194 198 195 rect 178 193 197 194 rect 177 192 196 193 rect 176 191 195 192 rect 175 190 194 191 rect 174 189 193 190 rect 173 188 192 189 rect 172 187 191 188 rect 171 186 190 187 rect 170 185 189 186 rect 169 184 188 185 rect 168 183 187 184 rect 167 182 186 183 rect 166 181 185 182 rect 165 180 184 181 rect 164 179 183 180 rect 163 178 182 179 rect 162 177 181 178 rect 162 176 180 177 rect 90 175 179 176 rect 90 174 178 175 rect 90 173 177 174 rect 90 172 176 173 rect 90 171 175 172 rect 90 170 174 171 rect 90 169 173 170 rect 90 168 172 169 rect 90 164 98 168 rect 90 156 170 164 rect 162 152 170 156 rect 90 144 170 152 rect 90 140 98 144 rect 90 132 170 140 rect 162 128 170 132 rect 90 120 170 128 rect 90 116 98 120 rect 90 108 170 116 rect 162 104 170 108 rect 88 103 170 104 rect 87 102 170 103 rect 86 101 170 102 rect 85 100 170 101 rect 84 99 170 100 rect 83 98 170 99 rect 82 97 170 98 rect 81 96 170 97 rect 80 95 98 96 rect 79 94 98 95 rect 78 93 97 94 rect 77 92 96 93 rect 76 91 95 92 rect 75 90 94 91 rect 74 89 93 90 rect 73 88 92 89 rect 72 87 91 88 rect 71 86 90 87 rect 70 85 89 86 rect 69 84 88 85 rect 68 83 87 84 rect 67 82 86 83 rect 66 81 85 82 rect 65 80 84 81 rect 64 79 83 80 rect 63 78 82 79 rect 62 77 81 78 rect 61 76 80 77 rect 60 75 79 76 rect 59 74 78 75 rect 58 73 77 74 rect 57 72 76 73 rect 56 71 75 72 rect 55 70 74 71 rect 54 69 73 70 rect 53 68 72 69 rect 52 67 71 68 rect 51 66 70 67 rect 50 65 69 66 rect 49 64 68 65 rect 48 63 67 64 rect 47 62 66 63 rect 46 61 65 62 rect 45 60 64 61 rect 44 59 63 60 rect 43 58 62 59 rect 42 57 61 58 rect 41 56 60 57 rect 40 55 59 56 rect 39 54 58 55 rect 38 53 57 54 rect 37 52 56 53 rect 36 51 55 52 rect 35 50 54 51 rect 34 49 53 50 rect 33 48 52 49 rect 32 47 51 48 rect 31 46 50 47 rect 30 45 49 46 rect 29 44 48 45 rect 28 43 47 44 rect 27 42 46 43 rect 26 41 45 42 rect 25 40 44 41 rect 24 39 43 40 rect 23 38 42 39 rect 22 37 41 38 rect 21 36 40 37 rect 20 35 39 36 rect 19 34 38 35 rect 18 33 37 34 rect 17 32 36 33 rect 16 31 35 32 rect 15 30 34 31 rect 14 29 33 30 rect 13 28 32 29 rect 12 27 31 28 rect 11 26 30 27 rect 10 25 29 26 rect 9 24 28 25 rect 8 23 27 24 rect 7 22 26 23 rect 6 21 25 22 rect 5 20 24 21 rect 4 19 23 20 rect 3 18 22 19 rect 2 17 21 18 rect 1 16 20 17 rect 0 15 19 16 rect 0 14 18 15 rect 0 13 17 14 rect 0 9 3 13 rect 7 12 16 13 rect 7 11 15 12 rect 7 10 14 11 rect 7 9 13 10 rect 0 8 12 9 rect 0 7 11 8 rect 0 6 10 7 << metal1 >> rect 250 263 260 266 rect 250 259 253 263 rect 257 259 260 263 rect 250 256 260 259 rect 0 240 30 246 rect 230 240 260 246 rect 0 239 31 240 rect 229 239 260 240 rect 0 238 32 239 rect 228 238 260 239 rect 0 237 33 238 rect 227 237 260 238 rect 0 236 34 237 rect 226 236 260 237 rect 26 235 35 236 rect 225 235 234 236 rect 27 234 36 235 rect 224 234 233 235 rect 28 233 37 234 rect 223 233 232 234 rect 29 232 38 233 rect 222 232 231 233 rect 30 231 39 232 rect 221 231 230 232 rect 31 230 40 231 rect 220 230 229 231 rect 32 229 41 230 rect 219 229 228 230 rect 33 228 42 229 rect 218 228 227 229 rect 34 227 43 228 rect 217 227 226 228 rect 35 226 44 227 rect 216 226 225 227 rect 36 225 45 226 rect 215 225 224 226 rect 37 224 46 225 rect 214 224 223 225 rect 38 223 47 224 rect 213 223 222 224 rect 39 222 48 223 rect 212 222 221 223 rect 40 221 49 222 rect 211 221 220 222 rect 41 220 50 221 rect 210 220 219 221 rect 42 219 51 220 rect 209 219 218 220 rect 43 218 52 219 rect 208 218 217 219 rect 44 217 53 218 rect 207 217 216 218 rect 45 216 54 217 rect 206 216 215 217 rect 46 215 55 216 rect 205 215 214 216 rect 47 214 56 215 rect 204 214 213 215 rect 48 213 57 214 rect 203 213 212 214 rect 49 212 58 213 rect 202 212 211 213 rect 50 211 59 212 rect 201 211 210 212 rect 51 210 60 211 rect 200 210 209 211 rect 52 209 61 210 rect 199 209 208 210 rect 53 208 62 209 rect 198 208 207 209 rect 54 207 63 208 rect 197 207 206 208 rect 55 206 64 207 rect 196 206 205 207 rect 56 205 65 206 rect 195 205 204 206 rect 57 204 66 205 rect 194 204 203 205 rect 58 203 67 204 rect 193 203 202 204 rect 59 202 68 203 rect 192 202 201 203 rect 60 201 69 202 rect 191 201 200 202 rect 61 200 70 201 rect 190 200 199 201 rect 62 199 71 200 rect 189 199 198 200 rect 63 198 72 199 rect 188 198 197 199 rect 64 197 73 198 rect 187 197 196 198 rect 65 196 74 197 rect 186 196 195 197 rect 66 195 75 196 rect 185 195 194 196 rect 67 194 76 195 rect 184 194 193 195 rect 68 193 77 194 rect 183 193 192 194 rect 69 192 78 193 rect 182 192 191 193 rect 70 191 79 192 rect 181 191 190 192 rect 71 190 80 191 rect 180 190 189 191 rect 72 189 81 190 rect 179 189 188 190 rect 73 188 82 189 rect 178 188 187 189 rect 74 187 83 188 rect 177 187 186 188 rect 75 186 84 187 rect 176 186 185 187 rect 76 185 85 186 rect 175 185 184 186 rect 77 184 86 185 rect 174 184 183 185 rect 78 183 87 184 rect 173 183 182 184 rect 79 182 88 183 rect 172 182 181 183 rect 80 181 89 182 rect 171 181 180 182 rect 81 180 179 181 rect 82 179 178 180 rect 83 178 177 179 rect 84 177 176 178 rect 85 95 175 177 rect 84 94 176 95 rect 83 93 177 94 rect 82 92 178 93 rect 81 91 179 92 rect 80 90 89 91 rect 171 90 180 91 rect 79 89 88 90 rect 172 89 181 90 rect 78 88 87 89 rect 173 88 182 89 rect 77 87 86 88 rect 174 87 183 88 rect 76 86 85 87 rect 175 86 184 87 rect 75 85 84 86 rect 176 85 185 86 rect 74 84 83 85 rect 177 84 186 85 rect 73 83 82 84 rect 178 83 187 84 rect 72 82 81 83 rect 179 82 188 83 rect 71 81 80 82 rect 180 81 189 82 rect 70 80 79 81 rect 181 80 190 81 rect 69 79 78 80 rect 182 79 191 80 rect 68 78 77 79 rect 183 78 192 79 rect 67 77 76 78 rect 184 77 193 78 rect 66 76 75 77 rect 185 76 194 77 rect 65 75 74 76 rect 186 75 195 76 rect 64 74 73 75 rect 187 74 196 75 rect 63 73 72 74 rect 188 73 197 74 rect 62 72 71 73 rect 189 72 198 73 rect 61 71 70 72 rect 190 71 199 72 rect 60 70 69 71 rect 191 70 200 71 rect 59 69 68 70 rect 192 69 201 70 rect 58 68 67 69 rect 193 68 202 69 rect 57 67 66 68 rect 194 67 203 68 rect 56 66 65 67 rect 195 66 204 67 rect 55 65 64 66 rect 196 65 205 66 rect 54 64 63 65 rect 197 64 206 65 rect 53 63 62 64 rect 198 63 207 64 rect 52 62 61 63 rect 199 62 208 63 rect 51 61 60 62 rect 200 61 209 62 rect 50 60 59 61 rect 201 60 210 61 rect 49 59 58 60 rect 202 59 211 60 rect 48 58 57 59 rect 203 58 212 59 rect 47 57 56 58 rect 204 57 213 58 rect 46 56 55 57 rect 205 56 214 57 rect 45 55 54 56 rect 206 55 215 56 rect 44 54 53 55 rect 207 54 216 55 rect 43 53 52 54 rect 208 53 217 54 rect 42 52 51 53 rect 209 52 218 53 rect 41 51 50 52 rect 210 51 219 52 rect 40 50 49 51 rect 211 50 220 51 rect 39 49 48 50 rect 212 49 221 50 rect 38 48 47 49 rect 213 48 222 49 rect 37 47 46 48 rect 214 47 223 48 rect 36 46 45 47 rect 215 46 224 47 rect 35 45 44 46 rect 216 45 225 46 rect 34 44 43 45 rect 217 44 226 45 rect 33 43 42 44 rect 218 43 227 44 rect 32 42 41 43 rect 219 42 228 43 rect 31 41 40 42 rect 220 41 229 42 rect 30 40 39 41 rect 221 40 230 41 rect 29 39 38 40 rect 222 39 231 40 rect 28 38 37 39 rect 223 38 232 39 rect 27 37 36 38 rect 224 37 233 38 rect 26 36 35 37 rect 225 36 234 37 rect 0 35 34 36 rect 226 35 260 36 rect 0 34 33 35 rect 227 34 260 35 rect 0 33 32 34 rect 228 33 260 34 rect 0 32 31 33 rect 229 32 260 33 rect 0 26 30 32 rect 230 26 260 32 rect 0 13 10 16 rect 0 9 3 13 rect 7 9 10 13 rect 0 0 10 9 << metal2 >> rect 20 240 30 266 rect 230 240 240 266 rect 20 239 31 240 rect 229 239 240 240 rect 20 238 32 239 rect 228 238 240 239 rect 20 237 33 238 rect 227 237 240 238 rect 20 236 34 237 rect 226 236 240 237 rect 26 235 35 236 rect 225 235 234 236 rect 27 234 36 235 rect 224 234 233 235 rect 28 233 37 234 rect 223 233 232 234 rect 29 232 38 233 rect 222 232 231 233 rect 30 231 39 232 rect 221 231 230 232 rect 31 230 40 231 rect 220 230 229 231 rect 32 229 41 230 rect 219 229 228 230 rect 33 228 42 229 rect 218 228 227 229 rect 34 227 43 228 rect 217 227 226 228 rect 35 226 44 227 rect 216 226 225 227 rect 36 225 45 226 rect 215 225 224 226 rect 37 224 46 225 rect 214 224 223 225 rect 38 223 47 224 rect 213 223 222 224 rect 39 222 48 223 rect 212 222 221 223 rect 40 221 49 222 rect 211 221 220 222 rect 41 220 50 221 rect 210 220 219 221 rect 42 219 51 220 rect 209 219 218 220 rect 43 218 52 219 rect 208 218 217 219 rect 44 217 53 218 rect 207 217 216 218 rect 45 216 54 217 rect 206 216 215 217 rect 46 215 55 216 rect 205 215 214 216 rect 47 214 56 215 rect 204 214 213 215 rect 48 213 57 214 rect 203 213 212 214 rect 49 212 58 213 rect 202 212 211 213 rect 50 211 59 212 rect 201 211 210 212 rect 51 210 60 211 rect 200 210 209 211 rect 52 209 61 210 rect 199 209 208 210 rect 53 208 62 209 rect 198 208 207 209 rect 54 207 63 208 rect 197 207 206 208 rect 55 206 64 207 rect 196 206 205 207 rect 56 205 65 206 rect 195 205 204 206 rect 57 204 66 205 rect 194 204 203 205 rect 58 203 67 204 rect 193 203 202 204 rect 59 202 68 203 rect 192 202 201 203 rect 60 201 69 202 rect 191 201 200 202 rect 61 200 70 201 rect 190 200 199 201 rect 62 199 71 200 rect 189 199 198 200 rect 63 198 72 199 rect 188 198 197 199 rect 64 197 73 198 rect 187 197 196 198 rect 65 196 74 197 rect 186 196 195 197 rect 66 195 75 196 rect 185 195 194 196 rect 67 194 76 195 rect 184 194 193 195 rect 68 193 77 194 rect 183 193 192 194 rect 69 192 78 193 rect 182 192 191 193 rect 70 191 79 192 rect 181 191 190 192 rect 71 190 80 191 rect 180 190 189 191 rect 72 189 81 190 rect 179 189 188 190 rect 73 188 82 189 rect 178 188 187 189 rect 74 187 83 188 rect 177 187 186 188 rect 75 186 84 187 rect 176 186 185 187 rect 76 185 85 186 rect 175 185 184 186 rect 77 184 86 185 rect 174 184 183 185 rect 78 183 87 184 rect 173 183 182 184 rect 79 182 88 183 rect 172 182 181 183 rect 80 181 89 182 rect 171 181 180 182 rect 81 180 90 181 rect 170 180 179 181 rect 82 179 91 180 rect 169 179 178 180 rect 83 178 92 179 rect 168 178 177 179 rect 84 177 93 178 rect 167 177 176 178 rect 85 176 94 177 rect 166 176 175 177 rect 86 175 125 176 rect 87 174 125 175 rect 88 173 125 174 rect 89 172 125 173 rect 90 141 125 172 rect 135 175 174 176 rect 135 174 173 175 rect 135 173 172 174 rect 135 172 171 173 rect 135 141 170 172 rect 90 100 125 131 rect 89 99 125 100 rect 88 98 125 99 rect 87 97 125 98 rect 86 96 125 97 rect 135 100 170 131 rect 135 99 171 100 rect 135 98 172 99 rect 135 97 173 98 rect 135 96 174 97 rect 85 95 94 96 rect 166 95 175 96 rect 84 94 93 95 rect 167 94 176 95 rect 83 93 92 94 rect 168 93 177 94 rect 82 92 91 93 rect 169 92 178 93 rect 81 91 90 92 rect 170 91 179 92 rect 80 90 89 91 rect 171 90 180 91 rect 79 89 88 90 rect 172 89 181 90 rect 78 88 87 89 rect 173 88 182 89 rect 77 87 86 88 rect 174 87 183 88 rect 76 86 85 87 rect 175 86 184 87 rect 75 85 84 86 rect 176 85 185 86 rect 74 84 83 85 rect 177 84 186 85 rect 73 83 82 84 rect 178 83 187 84 rect 72 82 81 83 rect 179 82 188 83 rect 71 81 80 82 rect 180 81 189 82 rect 70 80 79 81 rect 181 80 190 81 rect 69 79 78 80 rect 182 79 191 80 rect 68 78 77 79 rect 183 78 192 79 rect 67 77 76 78 rect 184 77 193 78 rect 66 76 75 77 rect 185 76 194 77 rect 65 75 74 76 rect 186 75 195 76 rect 64 74 73 75 rect 187 74 196 75 rect 63 73 72 74 rect 188 73 197 74 rect 62 72 71 73 rect 189 72 198 73 rect 61 71 70 72 rect 190 71 199 72 rect 60 70 69 71 rect 191 70 200 71 rect 59 69 68 70 rect 192 69 201 70 rect 58 68 67 69 rect 193 68 202 69 rect 57 67 66 68 rect 194 67 203 68 rect 56 66 65 67 rect 195 66 204 67 rect 55 65 64 66 rect 196 65 205 66 rect 54 64 63 65 rect 197 64 206 65 rect 53 63 62 64 rect 198 63 207 64 rect 52 62 61 63 rect 199 62 208 63 rect 51 61 60 62 rect 200 61 209 62 rect 50 60 59 61 rect 201 60 210 61 rect 49 59 58 60 rect 202 59 211 60 rect 48 58 57 59 rect 203 58 212 59 rect 47 57 56 58 rect 204 57 213 58 rect 46 56 55 57 rect 205 56 214 57 rect 45 55 54 56 rect 206 55 215 56 rect 44 54 53 55 rect 207 54 216 55 rect 43 53 52 54 rect 208 53 217 54 rect 42 52 51 53 rect 209 52 218 53 rect 41 51 50 52 rect 210 51 219 52 rect 40 50 49 51 rect 211 50 220 51 rect 39 49 48 50 rect 212 49 221 50 rect 38 48 47 49 rect 213 48 222 49 rect 37 47 46 48 rect 214 47 223 48 rect 36 46 45 47 rect 215 46 224 47 rect 35 45 44 46 rect 216 45 225 46 rect 34 44 43 45 rect 217 44 226 45 rect 33 43 42 44 rect 218 43 227 44 rect 32 42 41 43 rect 219 42 228 43 rect 31 41 40 42 rect 220 41 229 42 rect 30 40 39 41 rect 221 40 230 41 rect 29 39 38 40 rect 222 39 231 40 rect 28 38 37 39 rect 223 38 232 39 rect 27 37 36 38 rect 224 37 233 38 rect 26 36 35 37 rect 225 36 234 37 rect 20 35 34 36 rect 226 35 240 36 rect 20 34 33 35 rect 227 34 240 35 rect 20 33 32 34 rect 228 33 240 34 rect 20 32 31 33 rect 229 32 240 33 rect 20 6 30 32 rect 230 6 240 32 << polycontact >> rect 253 259 257 263 rect 3 9 7 13 << substrateopen >> rect 50 235 210 236 rect 51 234 209 235 rect 52 233 208 234 rect 53 232 207 233 rect 54 231 206 232 rect 55 230 205 231 rect 56 229 204 230 rect 57 228 203 229 rect 58 227 202 228 rect 59 226 201 227 rect 60 225 200 226 rect 61 224 199 225 rect 62 223 198 224 rect 63 222 197 223 rect 64 221 196 222 rect 65 220 195 221 rect 66 219 194 220 rect 67 218 193 219 rect 68 217 192 218 rect 69 216 191 217 rect 30 215 31 216 rect 70 215 190 216 rect 229 215 230 216 rect 30 214 32 215 rect 71 214 189 215 rect 228 214 230 215 rect 30 213 33 214 rect 72 213 188 214 rect 227 213 230 214 rect 30 212 34 213 rect 73 212 187 213 rect 226 212 230 213 rect 30 211 35 212 rect 74 211 186 212 rect 225 211 230 212 rect 30 210 36 211 rect 75 210 185 211 rect 224 210 230 211 rect 30 209 37 210 rect 76 209 184 210 rect 223 209 230 210 rect 30 208 38 209 rect 77 208 183 209 rect 222 208 230 209 rect 30 207 39 208 rect 78 207 182 208 rect 221 207 230 208 rect 30 206 40 207 rect 79 206 181 207 rect 220 206 230 207 rect 30 205 41 206 rect 80 205 180 206 rect 219 205 230 206 rect 30 204 42 205 rect 81 204 179 205 rect 218 204 230 205 rect 30 203 43 204 rect 82 203 178 204 rect 217 203 230 204 rect 30 202 44 203 rect 83 202 177 203 rect 216 202 230 203 rect 30 201 45 202 rect 84 201 176 202 rect 215 201 230 202 rect 30 200 46 201 rect 85 200 175 201 rect 214 200 230 201 rect 30 199 47 200 rect 86 199 174 200 rect 213 199 230 200 rect 30 198 48 199 rect 87 198 173 199 rect 212 198 230 199 rect 30 197 49 198 rect 88 197 172 198 rect 211 197 230 198 rect 30 196 50 197 rect 89 196 171 197 rect 210 196 230 197 rect 30 195 51 196 rect 90 195 170 196 rect 209 195 230 196 rect 30 194 52 195 rect 91 194 169 195 rect 208 194 230 195 rect 30 193 53 194 rect 92 193 168 194 rect 207 193 230 194 rect 30 192 54 193 rect 93 192 167 193 rect 206 192 230 193 rect 30 191 55 192 rect 94 191 166 192 rect 205 191 230 192 rect 30 190 56 191 rect 95 190 165 191 rect 204 190 230 191 rect 30 189 57 190 rect 96 189 164 190 rect 203 189 230 190 rect 30 188 58 189 rect 97 188 163 189 rect 202 188 230 189 rect 30 187 59 188 rect 98 187 162 188 rect 201 187 230 188 rect 30 186 60 187 rect 99 186 161 187 rect 200 186 230 187 rect 30 185 61 186 rect 199 185 230 186 rect 30 184 62 185 rect 198 184 230 185 rect 30 183 63 184 rect 197 183 230 184 rect 30 182 64 183 rect 196 182 230 183 rect 30 181 65 182 rect 195 181 230 182 rect 30 180 66 181 rect 194 180 230 181 rect 30 179 67 180 rect 193 179 230 180 rect 30 178 68 179 rect 192 178 230 179 rect 30 177 69 178 rect 191 177 230 178 rect 30 176 70 177 rect 190 176 230 177 rect 30 175 71 176 rect 189 175 230 176 rect 30 174 72 175 rect 188 174 230 175 rect 30 173 73 174 rect 187 173 230 174 rect 30 172 74 173 rect 186 172 230 173 rect 30 171 75 172 rect 185 171 230 172 rect 30 170 76 171 rect 30 169 77 170 rect 30 168 78 169 rect 30 167 79 168 rect 30 105 80 167 rect 184 170 230 171 rect 183 169 230 170 rect 182 168 230 169 rect 181 167 230 168 rect 30 104 79 105 rect 30 103 78 104 rect 30 102 77 103 rect 30 101 76 102 rect 180 105 230 167 rect 181 104 230 105 rect 182 103 230 104 rect 183 102 230 103 rect 184 101 230 102 rect 30 100 75 101 rect 185 100 230 101 rect 30 99 74 100 rect 186 99 230 100 rect 30 98 73 99 rect 187 98 230 99 rect 30 97 72 98 rect 188 97 230 98 rect 30 96 71 97 rect 189 96 230 97 rect 30 95 70 96 rect 190 95 230 96 rect 30 94 69 95 rect 191 94 230 95 rect 30 93 68 94 rect 192 93 230 94 rect 30 92 67 93 rect 193 92 230 93 rect 30 91 66 92 rect 194 91 230 92 rect 30 90 65 91 rect 195 90 230 91 rect 30 89 64 90 rect 196 89 230 90 rect 30 88 63 89 rect 197 88 230 89 rect 30 87 62 88 rect 198 87 230 88 rect 30 86 61 87 rect 199 86 230 87 rect 30 85 60 86 rect 99 85 161 86 rect 200 85 230 86 rect 30 84 59 85 rect 98 84 162 85 rect 201 84 230 85 rect 30 83 58 84 rect 97 83 163 84 rect 202 83 230 84 rect 30 82 57 83 rect 96 82 164 83 rect 203 82 230 83 rect 30 81 56 82 rect 95 81 165 82 rect 204 81 230 82 rect 30 80 55 81 rect 94 80 166 81 rect 205 80 230 81 rect 30 79 54 80 rect 93 79 167 80 rect 206 79 230 80 rect 30 78 53 79 rect 92 78 168 79 rect 207 78 230 79 rect 30 77 52 78 rect 91 77 169 78 rect 208 77 230 78 rect 30 76 51 77 rect 90 76 170 77 rect 209 76 230 77 rect 30 75 50 76 rect 89 75 171 76 rect 210 75 230 76 rect 30 74 49 75 rect 88 74 172 75 rect 211 74 230 75 rect 30 73 48 74 rect 87 73 173 74 rect 212 73 230 74 rect 30 72 47 73 rect 86 72 174 73 rect 213 72 230 73 rect 30 71 46 72 rect 85 71 175 72 rect 214 71 230 72 rect 30 70 45 71 rect 84 70 176 71 rect 215 70 230 71 rect 30 69 44 70 rect 83 69 177 70 rect 216 69 230 70 rect 30 68 43 69 rect 82 68 178 69 rect 217 68 230 69 rect 30 67 42 68 rect 81 67 179 68 rect 218 67 230 68 rect 30 66 41 67 rect 80 66 180 67 rect 219 66 230 67 rect 30 65 40 66 rect 79 65 181 66 rect 220 65 230 66 rect 30 64 39 65 rect 78 64 182 65 rect 221 64 230 65 rect 30 63 38 64 rect 77 63 183 64 rect 222 63 230 64 rect 30 62 37 63 rect 76 62 184 63 rect 223 62 230 63 rect 30 61 36 62 rect 75 61 185 62 rect 224 61 230 62 rect 30 60 35 61 rect 74 60 186 61 rect 225 60 230 61 rect 30 59 34 60 rect 73 59 187 60 rect 226 59 230 60 rect 30 58 33 59 rect 72 58 188 59 rect 227 58 230 59 rect 30 57 32 58 rect 71 57 189 58 rect 228 57 230 58 rect 30 56 31 57 rect 70 56 190 57 rect 229 56 230 57 rect 69 55 191 56 rect 68 54 192 55 rect 67 53 193 54 rect 66 52 194 53 rect 65 51 195 52 rect 64 50 196 51 rect 63 49 197 50 rect 62 48 198 49 rect 61 47 199 48 rect 60 46 200 47 rect 59 45 201 46 rect 58 44 202 45 rect 57 43 203 44 rect 56 42 204 43 rect 55 41 205 42 rect 54 40 206 41 rect 53 39 207 40 rect 52 38 208 39 rect 51 37 209 38 rect 50 36 210 37 << pdiffusionstop >> rect 20 245 230 246 rect 20 244 229 245 rect 20 243 228 244 rect 20 242 227 243 rect 20 241 226 242 rect 20 240 225 241 rect 20 239 224 240 rect 20 238 223 239 rect 20 237 222 238 rect 20 236 221 237 rect 20 45 30 236 rect 239 235 240 236 rect 238 234 240 235 rect 237 233 240 234 rect 236 232 240 233 rect 235 231 240 232 rect 234 230 240 231 rect 233 229 240 230 rect 232 228 240 229 rect 231 227 240 228 rect 20 44 29 45 rect 20 43 28 44 rect 20 42 27 43 rect 20 41 26 42 rect 20 40 25 41 rect 20 39 24 40 rect 20 38 23 39 rect 20 37 22 38 rect 20 36 21 37 rect 230 36 240 227 rect 39 35 240 36 rect 38 34 240 35 rect 37 33 240 34 rect 36 32 240 33 rect 35 31 240 32 rect 34 30 240 31 rect 33 29 240 30 rect 32 28 240 29 rect 31 27 240 28 rect 30 26 240 27 << glass >> rect 95 146 120 171 rect 140 146 165 171 rect 95 101 120 126 rect 140 101 165 126 << end >> magic-8.0.210/scmos/examples/nist-mems-library/micro-hot-plate.mag0000644000175000001440000003612410751423606023476 0ustar timusersmagic tech scmos timestamp 760840982 << polysilicon >> rect 250 265 260 266 rect 249 264 260 265 rect 248 263 260 264 rect 247 262 253 263 rect 246 261 253 262 rect 245 260 253 261 rect 244 259 253 260 rect 257 259 260 263 rect 243 258 260 259 rect 242 257 260 258 rect 241 256 260 257 rect 240 255 259 256 rect 239 254 258 255 rect 238 253 257 254 rect 237 252 256 253 rect 236 251 255 252 rect 235 250 254 251 rect 234 249 253 250 rect 233 248 252 249 rect 232 247 251 248 rect 231 246 250 247 rect 230 245 249 246 rect 229 244 248 245 rect 228 243 247 244 rect 227 242 246 243 rect 226 241 245 242 rect 225 240 244 241 rect 224 239 243 240 rect 223 238 242 239 rect 222 237 241 238 rect 221 236 240 237 rect 220 235 239 236 rect 219 234 238 235 rect 218 233 237 234 rect 217 232 236 233 rect 216 231 235 232 rect 215 230 234 231 rect 214 229 233 230 rect 213 228 232 229 rect 212 227 231 228 rect 211 226 230 227 rect 210 225 229 226 rect 209 224 228 225 rect 208 223 227 224 rect 207 222 226 223 rect 206 221 225 222 rect 205 220 224 221 rect 204 219 223 220 rect 203 218 222 219 rect 202 217 221 218 rect 201 216 220 217 rect 200 215 219 216 rect 199 214 218 215 rect 198 213 217 214 rect 197 212 216 213 rect 196 211 215 212 rect 195 210 214 211 rect 194 209 213 210 rect 193 208 212 209 rect 192 207 211 208 rect 191 206 210 207 rect 190 205 209 206 rect 189 204 208 205 rect 188 203 207 204 rect 187 202 206 203 rect 186 201 205 202 rect 185 200 204 201 rect 184 199 203 200 rect 183 198 202 199 rect 182 197 201 198 rect 181 196 200 197 rect 180 195 199 196 rect 179 194 198 195 rect 178 193 197 194 rect 177 192 196 193 rect 176 191 195 192 rect 175 190 194 191 rect 174 189 193 190 rect 173 188 192 189 rect 172 187 191 188 rect 171 186 190 187 rect 170 185 189 186 rect 169 184 188 185 rect 168 183 187 184 rect 167 182 186 183 rect 166 181 185 182 rect 165 180 184 181 rect 164 179 183 180 rect 163 178 182 179 rect 162 177 181 178 rect 162 176 180 177 rect 90 175 179 176 rect 90 174 178 175 rect 90 173 177 174 rect 90 172 176 173 rect 90 171 175 172 rect 90 170 174 171 rect 90 169 173 170 rect 90 168 172 169 rect 90 164 98 168 rect 90 156 170 164 rect 162 152 170 156 rect 90 144 170 152 rect 90 140 98 144 rect 90 132 170 140 rect 162 128 170 132 rect 90 120 170 128 rect 90 116 98 120 rect 90 108 170 116 rect 162 104 170 108 rect 88 103 170 104 rect 87 102 170 103 rect 86 101 170 102 rect 85 100 170 101 rect 84 99 170 100 rect 83 98 170 99 rect 82 97 170 98 rect 81 96 170 97 rect 80 95 98 96 rect 79 94 98 95 rect 78 93 97 94 rect 77 92 96 93 rect 76 91 95 92 rect 75 90 94 91 rect 74 89 93 90 rect 73 88 92 89 rect 72 87 91 88 rect 71 86 90 87 rect 70 85 89 86 rect 69 84 88 85 rect 68 83 87 84 rect 67 82 86 83 rect 66 81 85 82 rect 65 80 84 81 rect 64 79 83 80 rect 63 78 82 79 rect 62 77 81 78 rect 61 76 80 77 rect 60 75 79 76 rect 59 74 78 75 rect 58 73 77 74 rect 57 72 76 73 rect 56 71 75 72 rect 55 70 74 71 rect 54 69 73 70 rect 53 68 72 69 rect 52 67 71 68 rect 51 66 70 67 rect 50 65 69 66 rect 49 64 68 65 rect 48 63 67 64 rect 47 62 66 63 rect 46 61 65 62 rect 45 60 64 61 rect 44 59 63 60 rect 43 58 62 59 rect 42 57 61 58 rect 41 56 60 57 rect 40 55 59 56 rect 39 54 58 55 rect 38 53 57 54 rect 37 52 56 53 rect 36 51 55 52 rect 35 50 54 51 rect 34 49 53 50 rect 33 48 52 49 rect 32 47 51 48 rect 31 46 50 47 rect 30 45 49 46 rect 29 44 48 45 rect 28 43 47 44 rect 27 42 46 43 rect 26 41 45 42 rect 25 40 44 41 rect 24 39 43 40 rect 23 38 42 39 rect 22 37 41 38 rect 21 36 40 37 rect 20 35 39 36 rect 19 34 38 35 rect 18 33 37 34 rect 17 32 36 33 rect 16 31 35 32 rect 15 30 34 31 rect 14 29 33 30 rect 13 28 32 29 rect 12 27 31 28 rect 11 26 30 27 rect 10 25 29 26 rect 9 24 28 25 rect 8 23 27 24 rect 7 22 26 23 rect 6 21 25 22 rect 5 20 24 21 rect 4 19 23 20 rect 3 18 22 19 rect 2 17 21 18 rect 1 16 20 17 rect 0 15 19 16 rect 0 14 18 15 rect 0 13 17 14 rect 0 9 3 13 rect 7 12 16 13 rect 7 11 15 12 rect 7 10 14 11 rect 7 9 13 10 rect 0 8 12 9 rect 0 7 11 8 rect 0 6 10 7 << metal1 >> rect 250 263 260 266 rect 250 259 253 263 rect 257 259 260 263 rect 250 256 260 259 rect 0 240 30 246 rect 230 240 260 246 rect 0 239 31 240 rect 229 239 260 240 rect 0 238 32 239 rect 228 238 260 239 rect 0 237 33 238 rect 227 237 260 238 rect 0 236 34 237 rect 226 236 260 237 rect 26 235 35 236 rect 225 235 234 236 rect 27 234 36 235 rect 224 234 233 235 rect 28 233 37 234 rect 223 233 232 234 rect 29 232 38 233 rect 222 232 231 233 rect 30 231 39 232 rect 221 231 230 232 rect 31 230 40 231 rect 220 230 229 231 rect 32 229 41 230 rect 219 229 228 230 rect 33 228 42 229 rect 218 228 227 229 rect 34 227 43 228 rect 217 227 226 228 rect 35 226 44 227 rect 216 226 225 227 rect 36 225 45 226 rect 215 225 224 226 rect 37 224 46 225 rect 214 224 223 225 rect 38 223 47 224 rect 213 223 222 224 rect 39 222 48 223 rect 212 222 221 223 rect 40 221 49 222 rect 211 221 220 222 rect 41 220 50 221 rect 210 220 219 221 rect 42 219 51 220 rect 209 219 218 220 rect 43 218 52 219 rect 208 218 217 219 rect 44 217 53 218 rect 207 217 216 218 rect 45 216 54 217 rect 206 216 215 217 rect 46 215 55 216 rect 205 215 214 216 rect 47 214 56 215 rect 204 214 213 215 rect 48 213 57 214 rect 203 213 212 214 rect 49 212 58 213 rect 202 212 211 213 rect 50 211 59 212 rect 201 211 210 212 rect 51 210 60 211 rect 200 210 209 211 rect 52 209 61 210 rect 199 209 208 210 rect 53 208 62 209 rect 198 208 207 209 rect 54 207 63 208 rect 197 207 206 208 rect 55 206 64 207 rect 196 206 205 207 rect 56 205 65 206 rect 195 205 204 206 rect 57 204 66 205 rect 194 204 203 205 rect 58 203 67 204 rect 193 203 202 204 rect 59 202 68 203 rect 192 202 201 203 rect 60 201 69 202 rect 191 201 200 202 rect 61 200 70 201 rect 190 200 199 201 rect 62 199 71 200 rect 189 199 198 200 rect 63 198 72 199 rect 188 198 197 199 rect 64 197 73 198 rect 187 197 196 198 rect 65 196 74 197 rect 186 196 195 197 rect 66 195 75 196 rect 185 195 194 196 rect 67 194 76 195 rect 184 194 193 195 rect 68 193 77 194 rect 183 193 192 194 rect 69 192 78 193 rect 182 192 191 193 rect 70 191 79 192 rect 181 191 190 192 rect 71 190 80 191 rect 180 190 189 191 rect 72 189 81 190 rect 179 189 188 190 rect 73 188 82 189 rect 178 188 187 189 rect 74 187 83 188 rect 177 187 186 188 rect 75 186 84 187 rect 176 186 185 187 rect 76 185 85 186 rect 175 185 184 186 rect 77 184 86 185 rect 174 184 183 185 rect 78 183 87 184 rect 173 183 182 184 rect 79 182 88 183 rect 172 182 181 183 rect 80 181 89 182 rect 171 181 180 182 rect 81 180 179 181 rect 82 179 178 180 rect 83 178 177 179 rect 84 177 176 178 rect 85 95 175 177 rect 84 94 176 95 rect 83 93 177 94 rect 82 92 178 93 rect 81 91 179 92 rect 80 90 89 91 rect 171 90 180 91 rect 79 89 88 90 rect 172 89 181 90 rect 78 88 87 89 rect 173 88 182 89 rect 77 87 86 88 rect 174 87 183 88 rect 76 86 85 87 rect 175 86 184 87 rect 75 85 84 86 rect 176 85 185 86 rect 74 84 83 85 rect 177 84 186 85 rect 73 83 82 84 rect 178 83 187 84 rect 72 82 81 83 rect 179 82 188 83 rect 71 81 80 82 rect 180 81 189 82 rect 70 80 79 81 rect 181 80 190 81 rect 69 79 78 80 rect 182 79 191 80 rect 68 78 77 79 rect 183 78 192 79 rect 67 77 76 78 rect 184 77 193 78 rect 66 76 75 77 rect 185 76 194 77 rect 65 75 74 76 rect 186 75 195 76 rect 64 74 73 75 rect 187 74 196 75 rect 63 73 72 74 rect 188 73 197 74 rect 62 72 71 73 rect 189 72 198 73 rect 61 71 70 72 rect 190 71 199 72 rect 60 70 69 71 rect 191 70 200 71 rect 59 69 68 70 rect 192 69 201 70 rect 58 68 67 69 rect 193 68 202 69 rect 57 67 66 68 rect 194 67 203 68 rect 56 66 65 67 rect 195 66 204 67 rect 55 65 64 66 rect 196 65 205 66 rect 54 64 63 65 rect 197 64 206 65 rect 53 63 62 64 rect 198 63 207 64 rect 52 62 61 63 rect 199 62 208 63 rect 51 61 60 62 rect 200 61 209 62 rect 50 60 59 61 rect 201 60 210 61 rect 49 59 58 60 rect 202 59 211 60 rect 48 58 57 59 rect 203 58 212 59 rect 47 57 56 58 rect 204 57 213 58 rect 46 56 55 57 rect 205 56 214 57 rect 45 55 54 56 rect 206 55 215 56 rect 44 54 53 55 rect 207 54 216 55 rect 43 53 52 54 rect 208 53 217 54 rect 42 52 51 53 rect 209 52 218 53 rect 41 51 50 52 rect 210 51 219 52 rect 40 50 49 51 rect 211 50 220 51 rect 39 49 48 50 rect 212 49 221 50 rect 38 48 47 49 rect 213 48 222 49 rect 37 47 46 48 rect 214 47 223 48 rect 36 46 45 47 rect 215 46 224 47 rect 35 45 44 46 rect 216 45 225 46 rect 34 44 43 45 rect 217 44 226 45 rect 33 43 42 44 rect 218 43 227 44 rect 32 42 41 43 rect 219 42 228 43 rect 31 41 40 42 rect 220 41 229 42 rect 30 40 39 41 rect 221 40 230 41 rect 29 39 38 40 rect 222 39 231 40 rect 28 38 37 39 rect 223 38 232 39 rect 27 37 36 38 rect 224 37 233 38 rect 26 36 35 37 rect 225 36 234 37 rect 0 35 34 36 rect 226 35 260 36 rect 0 34 33 35 rect 227 34 260 35 rect 0 33 32 34 rect 228 33 260 34 rect 0 32 31 33 rect 229 32 260 33 rect 0 26 30 32 rect 230 26 260 32 rect 0 13 10 16 rect 0 9 3 13 rect 7 9 10 13 rect 0 0 10 9 << polycontact >> rect 253 259 257 263 rect 3 9 7 13 << substrateopen >> rect 50 235 210 236 rect 51 234 209 235 rect 52 233 208 234 rect 53 232 207 233 rect 54 231 206 232 rect 55 230 205 231 rect 56 229 204 230 rect 57 228 203 229 rect 58 227 202 228 rect 59 226 201 227 rect 60 225 200 226 rect 61 224 199 225 rect 62 223 198 224 rect 63 222 197 223 rect 64 221 196 222 rect 65 220 195 221 rect 66 219 194 220 rect 67 218 193 219 rect 68 217 192 218 rect 69 216 191 217 rect 30 215 31 216 rect 70 215 190 216 rect 229 215 230 216 rect 30 214 32 215 rect 71 214 189 215 rect 228 214 230 215 rect 30 213 33 214 rect 72 213 188 214 rect 227 213 230 214 rect 30 212 34 213 rect 73 212 187 213 rect 226 212 230 213 rect 30 211 35 212 rect 74 211 186 212 rect 225 211 230 212 rect 30 210 36 211 rect 75 210 185 211 rect 224 210 230 211 rect 30 209 37 210 rect 76 209 184 210 rect 223 209 230 210 rect 30 208 38 209 rect 77 208 183 209 rect 222 208 230 209 rect 30 207 39 208 rect 78 207 182 208 rect 221 207 230 208 rect 30 206 40 207 rect 79 206 181 207 rect 220 206 230 207 rect 30 205 41 206 rect 80 205 180 206 rect 219 205 230 206 rect 30 204 42 205 rect 81 204 179 205 rect 218 204 230 205 rect 30 203 43 204 rect 82 203 178 204 rect 217 203 230 204 rect 30 202 44 203 rect 83 202 177 203 rect 216 202 230 203 rect 30 201 45 202 rect 84 201 176 202 rect 215 201 230 202 rect 30 200 46 201 rect 85 200 175 201 rect 214 200 230 201 rect 30 199 47 200 rect 86 199 174 200 rect 213 199 230 200 rect 30 198 48 199 rect 87 198 173 199 rect 212 198 230 199 rect 30 197 49 198 rect 88 197 172 198 rect 211 197 230 198 rect 30 196 50 197 rect 89 196 171 197 rect 210 196 230 197 rect 30 195 51 196 rect 90 195 170 196 rect 209 195 230 196 rect 30 194 52 195 rect 91 194 169 195 rect 208 194 230 195 rect 30 193 53 194 rect 92 193 168 194 rect 207 193 230 194 rect 30 192 54 193 rect 93 192 167 193 rect 206 192 230 193 rect 30 191 55 192 rect 94 191 166 192 rect 205 191 230 192 rect 30 190 56 191 rect 95 190 165 191 rect 204 190 230 191 rect 30 189 57 190 rect 96 189 164 190 rect 203 189 230 190 rect 30 188 58 189 rect 97 188 163 189 rect 202 188 230 189 rect 30 187 59 188 rect 98 187 162 188 rect 201 187 230 188 rect 30 186 60 187 rect 99 186 161 187 rect 200 186 230 187 rect 30 185 61 186 rect 199 185 230 186 rect 30 184 62 185 rect 198 184 230 185 rect 30 183 63 184 rect 197 183 230 184 rect 30 182 64 183 rect 196 182 230 183 rect 30 181 65 182 rect 195 181 230 182 rect 30 180 66 181 rect 194 180 230 181 rect 30 179 67 180 rect 193 179 230 180 rect 30 178 68 179 rect 192 178 230 179 rect 30 177 69 178 rect 191 177 230 178 rect 30 176 70 177 rect 190 176 230 177 rect 30 175 71 176 rect 189 175 230 176 rect 30 174 72 175 rect 188 174 230 175 rect 30 173 73 174 rect 187 173 230 174 rect 30 172 74 173 rect 186 172 230 173 rect 30 171 75 172 rect 185 171 230 172 rect 30 170 76 171 rect 184 170 230 171 rect 30 169 77 170 rect 183 169 230 170 rect 30 168 78 169 rect 182 168 230 169 rect 30 167 79 168 rect 181 167 230 168 rect 30 105 80 167 rect 180 105 230 167 rect 30 104 79 105 rect 181 104 230 105 rect 30 103 78 104 rect 182 103 230 104 rect 30 102 77 103 rect 183 102 230 103 rect 30 101 76 102 rect 184 101 230 102 rect 30 100 75 101 rect 185 100 230 101 rect 30 99 74 100 rect 186 99 230 100 rect 30 98 73 99 rect 187 98 230 99 rect 30 97 72 98 rect 188 97 230 98 rect 30 96 71 97 rect 189 96 230 97 rect 30 95 70 96 rect 190 95 230 96 rect 30 94 69 95 rect 191 94 230 95 rect 30 93 68 94 rect 192 93 230 94 rect 30 92 67 93 rect 193 92 230 93 rect 30 91 66 92 rect 194 91 230 92 rect 30 90 65 91 rect 195 90 230 91 rect 30 89 64 90 rect 196 89 230 90 rect 30 88 63 89 rect 197 88 230 89 rect 30 87 62 88 rect 198 87 230 88 rect 30 86 61 87 rect 199 86 230 87 rect 30 85 60 86 rect 99 85 161 86 rect 200 85 230 86 rect 30 84 59 85 rect 98 84 162 85 rect 201 84 230 85 rect 30 83 58 84 rect 97 83 163 84 rect 202 83 230 84 rect 30 82 57 83 rect 96 82 164 83 rect 203 82 230 83 rect 30 81 56 82 rect 95 81 165 82 rect 204 81 230 82 rect 30 80 55 81 rect 94 80 166 81 rect 205 80 230 81 rect 30 79 54 80 rect 93 79 167 80 rect 206 79 230 80 rect 30 78 53 79 rect 92 78 168 79 rect 207 78 230 79 rect 30 77 52 78 rect 91 77 169 78 rect 208 77 230 78 rect 30 76 51 77 rect 90 76 170 77 rect 209 76 230 77 rect 30 75 50 76 rect 89 75 171 76 rect 210 75 230 76 rect 30 74 49 75 rect 88 74 172 75 rect 211 74 230 75 rect 30 73 48 74 rect 87 73 173 74 rect 212 73 230 74 rect 30 72 47 73 rect 86 72 174 73 rect 213 72 230 73 rect 30 71 46 72 rect 85 71 175 72 rect 214 71 230 72 rect 30 70 45 71 rect 84 70 176 71 rect 215 70 230 71 rect 30 69 44 70 rect 83 69 177 70 rect 216 69 230 70 rect 30 68 43 69 rect 82 68 178 69 rect 217 68 230 69 rect 30 67 42 68 rect 81 67 179 68 rect 218 67 230 68 rect 30 66 41 67 rect 80 66 180 67 rect 219 66 230 67 rect 30 65 40 66 rect 79 65 181 66 rect 220 65 230 66 rect 30 64 39 65 rect 78 64 182 65 rect 221 64 230 65 rect 30 63 38 64 rect 77 63 183 64 rect 222 63 230 64 rect 30 62 37 63 rect 76 62 184 63 rect 223 62 230 63 rect 30 61 36 62 rect 75 61 185 62 rect 224 61 230 62 rect 30 60 35 61 rect 74 60 186 61 rect 225 60 230 61 rect 30 59 34 60 rect 73 59 187 60 rect 226 59 230 60 rect 30 58 33 59 rect 72 58 188 59 rect 227 58 230 59 rect 30 57 32 58 rect 71 57 189 58 rect 228 57 230 58 rect 30 56 31 57 rect 70 56 190 57 rect 229 56 230 57 rect 69 55 191 56 rect 68 54 192 55 rect 67 53 193 54 rect 66 52 194 53 rect 65 51 195 52 rect 64 50 196 51 rect 63 49 197 50 rect 62 48 198 49 rect 61 47 199 48 rect 60 46 200 47 rect 59 45 201 46 rect 58 44 202 45 rect 57 43 203 44 rect 56 42 204 43 rect 55 41 205 42 rect 54 40 206 41 rect 53 39 207 40 rect 52 38 208 39 rect 51 37 209 38 rect 50 36 210 37 << pdiffusionstop >> rect 20 245 230 246 rect 20 244 229 245 rect 20 243 228 244 rect 20 242 227 243 rect 20 241 226 242 rect 20 240 225 241 rect 20 239 224 240 rect 20 238 223 239 rect 20 237 222 238 rect 20 236 221 237 rect 20 45 30 236 rect 239 235 240 236 rect 238 234 240 235 rect 237 233 240 234 rect 236 232 240 233 rect 235 231 240 232 rect 234 230 240 231 rect 233 229 240 230 rect 232 228 240 229 rect 231 227 240 228 rect 20 44 29 45 rect 20 43 28 44 rect 20 42 27 43 rect 20 41 26 42 rect 20 40 25 41 rect 20 39 24 40 rect 20 38 23 39 rect 20 37 22 38 rect 20 36 21 37 rect 230 36 240 227 rect 39 35 240 36 rect 38 34 240 35 rect 37 33 240 34 rect 36 32 240 33 rect 35 31 240 32 rect 34 30 240 31 rect 33 29 240 30 rect 32 28 240 29 rect 31 27 240 28 rect 30 26 240 27 << end >> magic-8.0.210/scmos/examples/nist-mems-library/pixel-160x160.cif0000644000175000001440000012615610751423606022540 0ustar timusersDS 1 1 2; 9 pixel-160x160; L CMF; B 1400 200 89900 30500; B 1600 200 89800 30300; B 1800 200 89700 30100; B 2000 200 89600 29900; B 2200 200 89500 29700; B 2400 200 89400 29500; B 2400 200 89200 29300; B 2400 200 89000 29100; B 2400 200 88800 28900; B 2400 200 88600 28700; B 2400 200 88400 28500; B 2400 200 88200 28300; B 2400 200 88000 28100; B 2400 200 87800 27900; B 2400 200 87600 27700; B 2400 200 87400 27500; B 2400 200 87200 27300; B 2400 200 87000 27100; B 2400 200 86800 26900; B 2400 200 86600 26700; B 2400 200 86400 26500; B 2400 200 86200 26300; B 2400 200 86000 26100; B 2400 200 85800 25900; B 2400 200 85600 25700; B 2400 200 85400 25500; B 2400 200 85200 25300; B 2400 200 85000 25100; B 2400 200 84800 24900; B 2400 200 84600 24700; B 2400 200 84400 24500; B 2400 200 84200 24300; B 2400 200 84000 24100; B 2400 200 83800 23900; B 2400 200 83600 23700; B 2400 200 83400 23500; B 2400 200 83200 23300; B 2400 200 83000 23100; B 2400 200 82800 22900; B 2400 200 82600 22700; B 2400 200 82400 22500; B 2400 200 82200 22300; B 2400 200 82000 22100; B 2400 200 81800 21900; B 2400 200 81600 21700; B 2400 200 81400 21500; B 2400 200 81200 21300; B 2400 200 81000 21100; B 2400 200 80800 20900; B 2400 200 80600 20700; B 2400 200 80400 20500; B 4800 200 79000 20300; B 4600 200 78900 20100; B 4400 200 78800 19900; B 4200 200 78700 19700; B 4000 200 78600 19500; B 3800 200 78500 19300; B 3600 200 78400 19100; B 3400 200 78300 18900; B 3200 200 78200 18700; B 3800 200 78500 10500; B 4000 200 78600 10300; B 4200 200 78700 10100; B 4400 200 78800 9900; B 4600 200 78900 9700; B 4800 200 79000 9500; B 5000 200 79100 9300; B 5200 200 79200 9100; B 2800 200 80600 8900; B 2800 200 80800 8700; B 2800 200 81000 8500; B 2800 200 81200 8300; B 2800 200 81400 8100; B 2800 200 81600 7900; B 2800 200 81800 7700; B 2800 200 82000 7500; B 2800 200 82200 7300; B 2800 200 82400 7100; B 2800 200 82600 6900; B 2800 200 82800 6700; B 2800 200 83000 6500; B 2800 200 83200 6300; B 2800 200 83400 6100; B 2800 200 83600 5900; B 2800 200 83800 5700; B 2800 200 84000 5500; B 2800 200 84200 5300; B 2800 200 84400 5100; B 2800 200 84600 4900; B 2800 200 84800 4700; B 2800 200 85000 4500; B 2800 200 85200 4300; B 2800 200 85400 4100; B 2800 200 85600 3900; B 2800 200 85800 3700; B 2800 200 86000 3500; B 2800 200 86200 3300; B 2800 200 86400 3100; B 2800 200 86600 2900; B 2800 200 86800 2700; B 2800 200 87000 2500; B 2800 200 87200 2300; B 2800 200 87400 2100; B 2800 200 87600 1900; B 2800 200 87800 1700; B 2800 200 88000 1500; B 2800 200 88200 1300; B 2800 200 88400 1100; B 2800 200 88600 900; B 2800 200 88800 700; B 2800 200 89000 500; B 2800 200 89200 300; B 2600 200 89300 100; B 2400 200 89400 -100; B 2200 200 89500 -300; B 2000 200 89600 -500; B 1800 200 89700 -700; B 1600 200 89800 -900; B 1400 200 89900 -1100; B 1200 200 90000 -1300; L CPG; B 3000 800 78100 20000; B 8400 800 75400 19200; B 800 400 71600 18600; B 6800 800 74600 18000; B 800 600 77600 17300; B 6800 800 74600 16600; B 800 600 71600 15900; B 6800 800 74600 15200; B 800 400 77600 14600; B 6800 800 74600 14000; B 800 400 71600 13400; B 6800 800 74600 12800; B 800 600 77600 12100; B 6800 800 74600 11400; B 800 600 71600 10700; B 8400 800 75400 10000; B 3000 600 78100 9300; L CAA; B 34000 1000 74600 31100; B 1000 2800 58100 29200; B 25800 200 74700 30500; B 25400 200 74700 30300; B 25000 200 74700 30100; B 24600 200 74700 29900; B 24200 200 74700 29700; B 23800 200 74700 29500; B 23400 200 74700 29300; B 23000 200 74700 29100; B 22600 200 74700 28900; B 22200 200 74700 28700; B 21800 200 74700 28500; B 21400 200 74700 28300; B 21000 200 74700 28100; B 20600 200 74700 27900; B 1000 2800 91100 29200; B 1200 200 58200 27700; B 20200 200 74700 27700; B 1200 200 91000 27700; B 1400 200 58300 27500; B 19800 200 74700 27500; B 1400 200 90900 27500; B 1600 200 58400 27300; B 19400 200 74700 27300; B 1600 200 90800 27300; B 1800 200 58500 27100; B 19000 200 74700 27100; B 1800 200 90700 27100; B 2000 200 58600 26900; B 18600 200 74700 26900; B 2000 200 90600 26900; B 2200 200 58700 26700; B 18200 200 74700 26700; B 2200 200 90500 26700; B 2400 200 58800 26500; B 17800 200 74700 26500; B 2400 200 90400 26500; B 2600 200 58900 26300; B 17400 200 74700 26300; B 2600 200 90300 26300; B 2800 200 59000 26100; B 17000 200 74700 26100; B 2800 200 90200 26100; B 3000 200 59100 25900; B 16600 200 74700 25900; B 3000 200 90100 25900; B 3200 200 59200 25700; B 16200 200 74700 25700; B 3200 200 90000 25700; B 3400 200 59300 25500; B 15800 200 74700 25500; B 3400 200 89900 25500; B 3600 200 59400 25300; B 15400 200 74700 25300; B 3600 200 89800 25300; B 3800 200 59500 25100; B 15000 200 74700 25100; B 3800 200 89700 25100; B 4000 200 59600 24900; B 14600 200 74700 24900; B 4000 200 89600 24900; B 4200 200 59700 24700; B 14200 200 74700 24700; B 4200 200 89500 24700; B 4400 200 59800 24500; B 13800 200 74700 24500; B 4400 200 89400 24500; B 4600 200 59900 24300; B 13400 200 74700 24300; B 4600 200 89300 24300; B 4800 200 60000 24100; B 13000 200 74700 24100; B 4800 200 89200 24100; B 5000 200 60100 23900; B 12600 200 74700 23900; B 5000 200 89100 23900; B 5200 200 60200 23700; B 12200 200 74700 23700; B 5200 200 89000 23700; B 5400 200 60300 23500; B 11800 200 74700 23500; B 5400 200 88900 23500; B 5600 200 60400 23300; B 11400 200 74700 23300; B 5600 200 88800 23300; B 5800 200 60500 23100; B 11000 200 74700 23100; B 5800 200 88700 23100; B 6000 200 60600 22900; B 10600 200 74700 22900; B 6000 200 88600 22900; B 6200 200 60700 22700; B 10200 200 74700 22700; B 6200 200 88500 22700; B 6400 200 60800 22500; B 9800 200 74700 22500; B 6400 200 88400 22500; B 6600 200 60900 22300; B 9400 200 74700 22300; B 6600 200 88300 22300; B 6800 200 61000 22100; B 9000 200 74700 22100; B 6800 200 88200 22100; B 7000 200 61100 21900; B 8600 200 74700 21900; B 7000 200 88100 21900; B 7200 200 61200 21700; B 8200 200 74700 21700; B 7200 200 88000 21700; B 7400 200 61300 21500; B 7800 200 74700 21500; B 7400 200 87900 21500; B 7600 200 61400 21300; B 7400 200 74700 21300; B 7600 200 87800 21300; B 7800 200 61500 21100; B 7000 200 74700 21100; B 7800 200 87700 21100; B 8000 200 61600 20900; B 8000 200 87600 20900; B 8200 200 61700 20700; B 8200 200 87500 20700; B 8400 200 61800 20500; B 8400 200 87400 20500; B 8600 200 61900 20300; B 8600 200 87300 20300; B 8800 200 62000 20100; B 8800 200 87200 20100; B 9000 200 62100 19900; B 9000 200 87100 19900; B 9200 200 62200 19700; B 9200 200 87000 19700; B 9400 200 62300 19500; B 9400 200 86900 19500; B 9600 200 62400 19300; B 9600 200 86800 19300; B 9800 200 62500 19100; B 9800 200 86700 19100; B 10000 200 62600 18900; B 10000 200 86600 18900; B 10200 200 62700 18700; B 10200 200 86500 18700; B 10400 200 62800 18500; B 10400 200 86400 18500; B 10600 7000 62900 14900; B 10600 7000 86300 14900; B 10400 200 62800 11300; B 10400 200 86400 11300; B 10200 200 62700 11100; B 10200 200 86500 11100; B 10000 200 62600 10900; B 10000 200 86600 10900; B 9800 200 62500 10700; B 9800 200 86700 10700; B 9600 200 62400 10500; B 9600 200 86800 10500; B 9400 200 62300 10300; B 9400 200 86900 10300; B 9200 200 62200 10100; B 9200 200 87000 10100; B 9000 200 62100 9900; B 9000 200 87100 9900; B 8800 200 62000 9700; B 8800 200 87200 9700; B 8600 200 61900 9500; B 8600 200 87300 9500; B 8400 200 61800 9300; B 8400 200 87400 9300; B 8200 200 61700 9100; B 8200 200 87500 9100; B 8000 200 61600 8900; B 8000 200 87600 8900; B 7800 200 61500 8700; B 7800 200 87700 8700; B 7600 200 61400 8500; B 7600 200 87800 8500; B 7400 200 61300 8300; B 7400 200 87900 8300; B 7200 200 61200 8100; B 7000 200 74700 8100; B 7200 200 88000 8100; B 7000 200 61100 7900; B 7400 200 74700 7900; B 7000 200 88100 7900; B 6800 200 61000 7700; B 7800 200 74700 7700; B 6800 200 88200 7700; B 6600 200 60900 7500; B 8200 200 74700 7500; B 6600 200 88300 7500; B 6400 200 60800 7300; B 8600 200 74700 7300; B 6400 200 88400 7300; B 6200 200 60700 7100; B 9000 200 74700 7100; B 6200 200 88500 7100; B 6000 200 60600 6900; B 9400 200 74700 6900; B 6000 200 88600 6900; B 5800 200 60500 6700; B 9800 200 74700 6700; B 5800 200 88700 6700; B 5600 200 60400 6500; B 10200 200 74700 6500; B 5600 200 88800 6500; B 5400 200 60300 6300; B 10600 200 74700 6300; B 5400 200 88900 6300; B 5200 200 60200 6100; B 11000 200 74700 6100; B 5200 200 89000 6100; B 5000 200 60100 5900; B 11400 200 74700 5900; B 5000 200 89100 5900; B 4800 200 60000 5700; B 11800 200 74700 5700; B 4800 200 89200 5700; B 4600 200 59900 5500; B 12200 200 74700 5500; B 4600 200 89300 5500; B 4400 200 59800 5300; B 12600 200 74700 5300; B 4400 200 89400 5300; B 4200 200 59700 5100; B 13000 200 74700 5100; B 4200 200 89500 5100; B 4000 200 59600 4900; B 13400 200 74700 4900; B 4000 200 89600 4900; B 3800 200 59500 4700; B 13800 200 74700 4700; B 3800 200 89700 4700; B 3600 200 59400 4500; B 14200 200 74700 4500; B 3600 200 89800 4500; B 3400 200 59300 4300; B 14600 200 74700 4300; B 3400 200 89900 4300; B 3200 200 59200 4100; B 15000 200 74700 4100; B 3200 200 90000 4100; B 3000 200 59100 3900; B 15400 200 74700 3900; B 3000 200 90100 3900; B 2800 200 59000 3700; B 15800 200 74700 3700; B 2800 200 90200 3700; B 2600 200 58900 3500; B 16200 200 74700 3500; B 2600 200 90300 3500; B 2400 200 58800 3300; B 16600 200 74700 3300; B 2400 200 90400 3300; B 2200 200 58700 3100; B 17000 200 74700 3100; B 2200 200 90500 3100; B 2000 200 58600 2900; B 17400 200 74700 2900; B 2000 200 90600 2900; B 1800 200 58500 2700; B 17800 200 74700 2700; B 1800 200 90700 2700; B 1600 200 58400 2500; B 18200 200 74700 2500; B 1600 200 90800 2500; B 1400 200 58300 2300; B 18600 200 74700 2300; B 1400 200 90900 2300; B 1200 200 58200 2100; B 19000 200 74700 2100; B 1200 200 91000 2100; B 1000 3400 58100 300; B 19400 200 74700 1900; B 19800 200 74700 1700; B 20200 200 74700 1500; B 20600 200 74700 1300; B 21000 200 74700 1100; B 21400 200 74700 900; B 21800 200 74700 700; B 22200 200 74700 500; B 22600 200 74700 300; B 23000 200 74700 100; B 23400 200 74700 -100; B 23800 200 74700 -300; B 24200 200 74700 -500; B 24600 200 74700 -700; B 25000 200 74700 -900; B 25400 200 74700 -1100; B 25800 200 74700 -1300; B 1000 3400 91100 300; B 34000 1000 74600 -1900; L CVA; B 25800 200 74700 30500; B 25400 200 74700 30300; B 25000 200 74700 30100; B 24600 200 74700 29900; B 24200 200 74700 29700; B 23800 200 74700 29500; B 23400 200 74700 29300; B 23000 200 74700 29100; B 22600 200 74700 28900; B 22200 200 74700 28700; B 21800 200 74700 28500; B 21400 200 74700 28300; B 21000 200 74700 28100; B 20600 200 74700 27900; B 200 200 58700 27700; B 20200 200 74700 27700; B 200 200 90500 27700; B 400 200 58800 27500; B 19800 200 74700 27500; B 400 200 90400 27500; B 600 200 58900 27300; B 19400 200 74700 27300; B 600 200 90300 27300; B 800 200 59000 27100; B 19000 200 74700 27100; B 800 200 90200 27100; B 1000 200 59100 26900; B 18600 200 74700 26900; B 1000 200 90100 26900; B 1200 200 59200 26700; B 18200 200 74700 26700; B 1200 200 90000 26700; B 1400 200 59300 26500; B 17800 200 74700 26500; B 1400 200 89900 26500; B 1600 200 59400 26300; B 17400 200 74700 26300; B 1600 200 89800 26300; B 1800 200 59500 26100; B 17000 200 74700 26100; B 1800 200 89700 26100; B 2000 200 59600 25900; B 16600 200 74700 25900; B 2000 200 89600 25900; B 2200 200 59700 25700; B 16200 200 74700 25700; B 2200 200 89500 25700; B 2400 200 59800 25500; B 15800 200 74700 25500; B 2400 200 89400 25500; B 2600 200 59900 25300; B 15400 200 74700 25300; B 2600 200 89300 25300; B 2800 200 60000 25100; B 15000 200 74700 25100; B 2800 200 89200 25100; B 3000 200 60100 24900; B 14600 200 74700 24900; B 3000 200 89100 24900; B 3200 200 60200 24700; B 14200 200 74700 24700; B 3200 200 89000 24700; B 3400 200 60300 24500; B 13800 200 74700 24500; B 3400 200 88900 24500; B 3600 200 60400 24300; B 13400 200 74700 24300; B 3600 200 88800 24300; B 3800 200 60500 24100; B 13000 200 74700 24100; B 3800 200 88700 24100; B 4000 200 60600 23900; B 12600 200 74700 23900; B 4000 200 88600 23900; B 4200 200 60700 23700; B 12200 200 74700 23700; B 4200 200 88500 23700; B 4400 200 60800 23500; B 11800 200 74700 23500; B 4400 200 88400 23500; B 4600 200 60900 23300; B 11400 200 74700 23300; B 4600 200 88300 23300; B 4800 200 61000 23100; B 11000 200 74700 23100; B 4800 200 88200 23100; B 5000 200 61100 22900; B 10600 200 74700 22900; B 5000 200 88100 22900; B 5200 200 61200 22700; B 10200 200 74700 22700; B 5200 200 88000 22700; B 5400 200 61300 22500; B 9800 200 74700 22500; B 5400 200 87900 22500; B 5600 200 61400 22300; B 9400 200 74700 22300; B 5600 200 87800 22300; B 5800 200 61500 22100; B 9000 200 74700 22100; B 5800 200 87700 22100; B 6000 200 61600 21900; B 8600 200 74700 21900; B 6000 200 87600 21900; B 6200 200 61700 21700; B 8200 200 74700 21700; B 6200 200 87500 21700; B 6400 200 61800 21500; B 7800 200 74700 21500; B 6400 200 87400 21500; B 6600 200 61900 21300; B 7400 200 74700 21300; B 6600 200 87300 21300; B 6800 200 62000 21100; B 7000 200 74700 21100; B 6800 200 87200 21100; B 7000 200 62100 20900; B 7000 200 87100 20900; B 7200 200 62200 20700; B 7200 200 87000 20700; B 7400 200 62300 20500; B 7400 200 86900 20500; B 7600 200 62400 20300; B 7600 200 86800 20300; B 7800 200 62500 20100; B 7800 200 86700 20100; B 8000 200 62600 19900; B 8000 200 86600 19900; B 8200 200 62700 19700; B 8200 200 86500 19700; B 8400 200 62800 19500; B 8400 200 86400 19500; B 8600 200 62900 19300; B 8600 200 86300 19300; B 8800 200 63000 19100; B 8800 200 86200 19100; B 9000 200 63100 18900; B 9000 200 86100 18900; B 9200 200 63200 18700; B 9200 200 86000 18700; B 9400 200 63300 18500; B 9400 200 85900 18500; B 9600 7000 63400 14900; B 9600 7000 85800 14900; B 9400 200 63300 11300; B 9400 200 85900 11300; B 9200 200 63200 11100; B 9200 200 86000 11100; B 9000 200 63100 10900; B 9000 200 86100 10900; B 8800 200 63000 10700; B 8800 200 86200 10700; B 8600 200 62900 10500; B 8600 200 86300 10500; B 8400 200 62800 10300; B 8400 200 86400 10300; B 8200 200 62700 10100; B 8200 200 86500 10100; B 8000 200 62600 9900; B 8000 200 86600 9900; B 7800 200 62500 9700; B 7800 200 86700 9700; B 7600 200 62400 9500; B 7600 200 86800 9500; B 7400 200 62300 9300; B 7400 200 86900 9300; B 7200 200 62200 9100; B 7200 200 87000 9100; B 7000 200 62100 8900; B 7000 200 87100 8900; B 6800 200 62000 8700; B 6800 200 87200 8700; B 6600 200 61900 8500; B 6600 200 87300 8500; B 6400 200 61800 8300; B 6400 200 87400 8300; B 6200 200 61700 8100; B 7000 200 74700 8100; B 6200 200 87500 8100; B 6000 200 61600 7900; B 7400 200 74700 7900; B 6000 200 87600 7900; B 5800 200 61500 7700; B 7800 200 74700 7700; B 5800 200 87700 7700; B 5600 200 61400 7500; B 8200 200 74700 7500; B 5600 200 87800 7500; B 5400 200 61300 7300; B 8600 200 74700 7300; B 5400 200 87900 7300; B 5200 200 61200 7100; B 9000 200 74700 7100; B 5200 200 88000 7100; B 5000 200 61100 6900; B 9400 200 74700 6900; B 5000 200 88100 6900; B 4800 200 61000 6700; B 9800 200 74700 6700; B 4800 200 88200 6700; B 4600 200 60900 6500; B 10200 200 74700 6500; B 4600 200 88300 6500; B 4400 200 60800 6300; B 10600 200 74700 6300; B 4400 200 88400 6300; B 4200 200 60700 6100; B 11000 200 74700 6100; B 4200 200 88500 6100; B 4000 200 60600 5900; B 11400 200 74700 5900; B 4000 200 88600 5900; B 3800 200 60500 5700; B 11800 200 74700 5700; B 3800 200 88700 5700; B 3600 200 60400 5500; B 12200 200 74700 5500; B 3600 200 88800 5500; B 3400 200 60300 5300; B 12600 200 74700 5300; B 3400 200 88900 5300; B 3200 200 60200 5100; B 13000 200 74700 5100; B 3200 200 89000 5100; B 3000 200 60100 4900; B 13400 200 74700 4900; B 3000 200 89100 4900; B 2800 200 60000 4700; B 13800 200 74700 4700; B 2800 200 89200 4700; B 2600 200 59900 4500; B 14200 200 74700 4500; B 2600 200 89300 4500; B 2400 200 59800 4300; B 14600 200 74700 4300; B 2400 200 89400 4300; B 2200 200 59700 4100; B 15000 200 74700 4100; B 2200 200 89500 4100; B 2000 200 59600 3900; B 15400 200 74700 3900; B 2000 200 89600 3900; B 1800 200 59500 3700; B 15800 200 74700 3700; B 1800 200 89700 3700; B 1600 200 59400 3500; B 16200 200 74700 3500; B 1600 200 89800 3500; B 1400 200 59300 3300; B 16600 200 74700 3300; B 1400 200 89900 3300; B 1200 200 59200 3100; B 17000 200 74700 3100; B 1200 200 90000 3100; B 1000 200 59100 2900; B 17400 200 74700 2900; B 1000 200 90100 2900; B 800 200 59000 2700; B 17800 200 74700 2700; B 800 200 90200 2700; B 600 200 58900 2500; B 18200 200 74700 2500; B 600 200 90300 2500; B 400 200 58800 2300; B 18600 200 74700 2300; B 400 200 90400 2300; B 200 200 58700 2100; B 19000 200 74700 2100; B 200 200 90500 2100; B 19400 200 74700 1900; B 19800 200 74700 1700; B 20200 200 74700 1500; B 20600 200 74700 1300; B 21000 200 74700 1100; B 21400 200 74700 900; B 21800 200 74700 700; B 22200 200 74700 500; B 22600 200 74700 300; B 23000 200 74700 100; B 23400 200 74700 -100; B 23800 200 74700 -300; B 24200 200 74700 -500; B 24600 200 74700 -700; B 25000 200 74700 -900; B 25400 200 74700 -1100; B 25800 200 74700 -1300; L CCA; B 25800 200 74700 30500; B 25400 200 74700 30300; B 25000 200 74700 30100; B 24600 200 74700 29900; B 24200 200 74700 29700; B 23800 200 74700 29500; B 23400 200 74700 29300; B 23000 200 74700 29100; B 22600 200 74700 28900; B 22200 200 74700 28700; B 21800 200 74700 28500; B 21400 200 74700 28300; B 21000 200 74700 28100; B 20600 200 74700 27900; B 200 200 58700 27700; B 20200 200 74700 27700; B 200 200 90500 27700; B 400 200 58800 27500; B 19800 200 74700 27500; B 400 200 90400 27500; B 600 200 58900 27300; B 19400 200 74700 27300; B 600 200 90300 27300; B 800 200 59000 27100; B 19000 200 74700 27100; B 800 200 90200 27100; B 1000 200 59100 26900; B 18600 200 74700 26900; B 1000 200 90100 26900; B 1200 200 59200 26700; B 18200 200 74700 26700; B 1200 200 90000 26700; B 1400 200 59300 26500; B 17800 200 74700 26500; B 1400 200 89900 26500; B 1600 200 59400 26300; B 17400 200 74700 26300; B 1600 200 89800 26300; B 1800 200 59500 26100; B 17000 200 74700 26100; B 1800 200 89700 26100; B 2000 200 59600 25900; B 16600 200 74700 25900; B 2000 200 89600 25900; B 2200 200 59700 25700; B 16200 200 74700 25700; B 2200 200 89500 25700; B 2400 200 59800 25500; B 15800 200 74700 25500; B 2400 200 89400 25500; B 2600 200 59900 25300; B 15400 200 74700 25300; B 2600 200 89300 25300; B 2800 200 60000 25100; B 15000 200 74700 25100; B 2800 200 89200 25100; B 3000 200 60100 24900; B 14600 200 74700 24900; B 3000 200 89100 24900; B 3200 200 60200 24700; B 14200 200 74700 24700; B 3200 200 89000 24700; B 3400 200 60300 24500; B 13800 200 74700 24500; B 3400 200 88900 24500; B 3600 200 60400 24300; B 13400 200 74700 24300; B 3600 200 88800 24300; B 3800 200 60500 24100; B 13000 200 74700 24100; B 3800 200 88700 24100; B 4000 200 60600 23900; B 12600 200 74700 23900; B 4000 200 88600 23900; B 4200 200 60700 23700; B 12200 200 74700 23700; B 4200 200 88500 23700; B 4400 200 60800 23500; B 11800 200 74700 23500; B 4400 200 88400 23500; B 4600 200 60900 23300; B 11400 200 74700 23300; B 4600 200 88300 23300; B 4800 200 61000 23100; B 11000 200 74700 23100; B 4800 200 88200 23100; B 5000 200 61100 22900; B 10600 200 74700 22900; B 5000 200 88100 22900; B 5200 200 61200 22700; B 10200 200 74700 22700; B 5200 200 88000 22700; B 5400 200 61300 22500; B 9800 200 74700 22500; B 5400 200 87900 22500; B 5600 200 61400 22300; B 9400 200 74700 22300; B 5600 200 87800 22300; B 5800 200 61500 22100; B 9000 200 74700 22100; B 5800 200 87700 22100; B 6000 200 61600 21900; B 8600 200 74700 21900; B 6000 200 87600 21900; B 6200 200 61700 21700; B 8200 200 74700 21700; B 6200 200 87500 21700; B 6400 200 61800 21500; B 7800 200 74700 21500; B 6400 200 87400 21500; B 6600 200 61900 21300; B 7400 200 74700 21300; B 6600 200 87300 21300; B 6800 200 62000 21100; B 7000 200 74700 21100; B 6800 200 87200 21100; B 7000 200 62100 20900; B 7000 200 87100 20900; B 7200 200 62200 20700; B 7200 200 87000 20700; B 7400 200 62300 20500; B 7400 200 86900 20500; B 7600 200 62400 20300; B 7600 200 86800 20300; B 7800 200 62500 20100; B 7800 200 86700 20100; B 8000 200 62600 19900; B 8000 200 86600 19900; B 8200 200 62700 19700; B 8200 200 86500 19700; B 8400 200 62800 19500; B 8400 200 86400 19500; B 8600 200 62900 19300; B 8600 200 86300 19300; B 8800 200 63000 19100; B 8800 200 86200 19100; B 9000 200 63100 18900; B 9000 200 86100 18900; B 9200 200 63200 18700; B 9200 200 86000 18700; B 9400 200 63300 18500; B 9400 200 85900 18500; B 9600 7000 63400 14900; B 9600 7000 85800 14900; B 9400 200 63300 11300; B 9400 200 85900 11300; B 9200 200 63200 11100; B 9200 200 86000 11100; B 9000 200 63100 10900; B 9000 200 86100 10900; B 8800 200 63000 10700; B 8800 200 86200 10700; B 8600 200 62900 10500; B 8600 200 86300 10500; B 8400 200 62800 10300; B 8400 200 86400 10300; B 8200 200 62700 10100; B 8200 200 86500 10100; B 8000 200 62600 9900; B 8000 200 86600 9900; B 7800 200 62500 9700; B 7800 200 86700 9700; B 7600 200 62400 9500; B 7600 200 86800 9500; B 7400 200 62300 9300; B 7400 200 86900 9300; B 7200 200 62200 9100; B 7200 200 87000 9100; B 7000 200 62100 8900; B 7000 200 87100 8900; B 6800 200 62000 8700; B 6800 200 87200 8700; B 6600 200 61900 8500; B 6600 200 87300 8500; B 6400 200 61800 8300; B 6400 200 87400 8300; B 6200 200 61700 8100; B 7000 200 74700 8100; B 6200 200 87500 8100; B 6000 200 61600 7900; B 7400 200 74700 7900; B 6000 200 87600 7900; B 5800 200 61500 7700; B 7800 200 74700 7700; B 5800 200 87700 7700; B 5600 200 61400 7500; B 8200 200 74700 7500; B 5600 200 87800 7500; B 5400 200 61300 7300; B 8600 200 74700 7300; B 5400 200 87900 7300; B 5200 200 61200 7100; B 9000 200 74700 7100; B 5200 200 88000 7100; B 5000 200 61100 6900; B 9400 200 74700 6900; B 5000 200 88100 6900; B 4800 200 61000 6700; B 9800 200 74700 6700; B 4800 200 88200 6700; B 4600 200 60900 6500; B 10200 200 74700 6500; B 4600 200 88300 6500; B 4400 200 60800 6300; B 10600 200 74700 6300; B 4400 200 88400 6300; B 4200 200 60700 6100; B 11000 200 74700 6100; B 4200 200 88500 6100; B 4000 200 60600 5900; B 11400 200 74700 5900; B 4000 200 88600 5900; B 3800 200 60500 5700; B 11800 200 74700 5700; B 3800 200 88700 5700; B 3600 200 60400 5500; B 12200 200 74700 5500; B 3600 200 88800 5500; B 3400 200 60300 5300; B 12600 200 74700 5300; B 3400 200 88900 5300; B 3200 200 60200 5100; B 13000 200 74700 5100; B 3200 200 89000 5100; B 3000 200 60100 4900; B 13400 200 74700 4900; B 3000 200 89100 4900; B 2800 200 60000 4700; B 13800 200 74700 4700; B 2800 200 89200 4700; B 2600 200 59900 4500; B 14200 200 74700 4500; B 2600 200 89300 4500; B 2400 200 59800 4300; B 14600 200 74700 4300; B 2400 200 89400 4300; B 2200 200 59700 4100; B 15000 200 74700 4100; B 2200 200 89500 4100; B 2000 200 59600 3900; B 15400 200 74700 3900; B 2000 200 89600 3900; B 1800 200 59500 3700; B 15800 200 74700 3700; B 1800 200 89700 3700; B 1600 200 59400 3500; B 16200 200 74700 3500; B 1600 200 89800 3500; B 1400 200 59300 3300; B 16600 200 74700 3300; B 1400 200 89900 3300; B 1200 200 59200 3100; B 17000 200 74700 3100; B 1200 200 90000 3100; B 1000 200 59100 2900; B 17400 200 74700 2900; B 1000 200 90100 2900; B 800 200 59000 2700; B 17800 200 74700 2700; B 800 200 90200 2700; B 600 200 58900 2500; B 18200 200 74700 2500; B 600 200 90300 2500; B 400 200 58800 2300; B 18600 200 74700 2300; B 400 200 90400 2300; B 200 200 58700 2100; B 19000 200 74700 2100; B 200 200 90500 2100; B 19400 200 74700 1900; B 19800 200 74700 1700; B 20200 200 74700 1500; B 20600 200 74700 1300; B 21000 200 74700 1100; B 21400 200 74700 900; B 21800 200 74700 700; B 22200 200 74700 500; B 22600 200 74700 300; B 23000 200 74700 100; B 23400 200 74700 -100; B 23800 200 74700 -300; B 24200 200 74700 -500; B 24600 200 74700 -700; B 25000 200 74700 -900; B 25400 200 74700 -1100; B 25800 200 74700 -1300; L CCP; B 400 400 77500 19500; B 400 400 78700 19500; B 400 400 77500 9900; B 400 400 78700 9900; L CSP; B 34800 1800 74600 31100; B 1800 31200 58100 14600; B 1800 31200 91100 14600; B 34800 1800 74600 -1900; L COG; B 25800 200 74700 30500; B 25400 200 74700 30300; B 25000 200 74700 30100; B 24600 200 74700 29900; B 24200 200 74700 29700; B 23800 200 74700 29500; B 23400 200 74700 29300; B 23000 200 74700 29100; B 22600 200 74700 28900; B 22200 200 74700 28700; B 21800 200 74700 28500; B 21400 200 74700 28300; B 21000 200 74700 28100; B 20600 200 74700 27900; B 200 200 58700 27700; B 20200 200 74700 27700; B 200 200 90500 27700; B 400 200 58800 27500; B 19800 200 74700 27500; B 400 200 90400 27500; B 600 200 58900 27300; B 19400 200 74700 27300; B 600 200 90300 27300; B 800 200 59000 27100; B 19000 200 74700 27100; B 800 200 90200 27100; B 1000 200 59100 26900; B 18600 200 74700 26900; B 1000 200 90100 26900; B 1200 200 59200 26700; B 18200 200 74700 26700; B 1200 200 90000 26700; B 1400 200 59300 26500; B 17800 200 74700 26500; B 1400 200 89900 26500; B 1600 200 59400 26300; B 17400 200 74700 26300; B 1600 200 89800 26300; B 1800 200 59500 26100; B 17000 200 74700 26100; B 1800 200 89700 26100; B 2000 200 59600 25900; B 16600 200 74700 25900; B 2000 200 89600 25900; B 2200 200 59700 25700; B 16200 200 74700 25700; B 2200 200 89500 25700; B 2400 200 59800 25500; B 15800 200 74700 25500; B 2400 200 89400 25500; B 2600 200 59900 25300; B 15400 200 74700 25300; B 2600 200 89300 25300; B 2800 200 60000 25100; B 15000 200 74700 25100; B 2800 200 89200 25100; B 3000 200 60100 24900; B 14600 200 74700 24900; B 3000 200 89100 24900; B 3200 200 60200 24700; B 14200 200 74700 24700; B 3200 200 89000 24700; B 3400 200 60300 24500; B 13800 200 74700 24500; B 3400 200 88900 24500; B 3600 200 60400 24300; B 13400 200 74700 24300; B 3600 200 88800 24300; B 3800 200 60500 24100; B 13000 200 74700 24100; B 3800 200 88700 24100; B 4000 200 60600 23900; B 12600 200 74700 23900; B 4000 200 88600 23900; B 4200 200 60700 23700; B 12200 200 74700 23700; B 4200 200 88500 23700; B 4400 200 60800 23500; B 11800 200 74700 23500; B 4400 200 88400 23500; B 4600 200 60900 23300; B 11400 200 74700 23300; B 4600 200 88300 23300; B 4800 200 61000 23100; B 11000 200 74700 23100; B 4800 200 88200 23100; B 5000 200 61100 22900; B 10600 200 74700 22900; B 5000 200 88100 22900; B 5200 200 61200 22700; B 10200 200 74700 22700; B 5200 200 88000 22700; B 5400 200 61300 22500; B 9800 200 74700 22500; B 5400 200 87900 22500; B 5600 200 61400 22300; B 9400 200 74700 22300; B 5600 200 87800 22300; B 5800 200 61500 22100; B 9000 200 74700 22100; B 5800 200 87700 22100; B 6000 200 61600 21900; B 8600 200 74700 21900; B 6000 200 87600 21900; B 6200 200 61700 21700; B 8200 200 74700 21700; B 6200 200 87500 21700; B 6400 200 61800 21500; B 7800 200 74700 21500; B 6400 200 87400 21500; B 6600 200 61900 21300; B 7400 200 74700 21300; B 6600 200 87300 21300; B 6800 200 62000 21100; B 7000 200 74700 21100; B 6800 200 87200 21100; B 7000 200 62100 20900; B 7000 200 87100 20900; B 7200 200 62200 20700; B 7200 200 87000 20700; B 7400 200 62300 20500; B 7400 200 86900 20500; B 7600 200 62400 20300; B 7600 200 86800 20300; B 7800 200 62500 20100; B 7800 200 86700 20100; B 8000 200 62600 19900; B 8000 200 86600 19900; B 8200 200 62700 19700; B 8200 200 86500 19700; B 8400 200 62800 19500; B 8400 200 86400 19500; B 8600 200 62900 19300; B 8600 200 86300 19300; B 8800 200 63000 19100; B 8800 200 86200 19100; B 9000 200 63100 18900; B 9000 200 86100 18900; B 9200 200 63200 18700; B 9200 200 86000 18700; B 9400 200 63300 18500; B 9400 200 85900 18500; B 9600 7000 63400 14900; B 9600 7000 85800 14900; B 9400 200 63300 11300; B 9400 200 85900 11300; B 9200 200 63200 11100; B 9200 200 86000 11100; B 9000 200 63100 10900; B 9000 200 86100 10900; B 8800 200 63000 10700; B 8800 200 86200 10700; B 8600 200 62900 10500; B 8600 200 86300 10500; B 8400 200 62800 10300; B 8400 200 86400 10300; B 8200 200 62700 10100; B 8200 200 86500 10100; B 8000 200 62600 9900; B 8000 200 86600 9900; B 7800 200 62500 9700; B 7800 200 86700 9700; B 7600 200 62400 9500; B 7600 200 86800 9500; B 7400 200 62300 9300; B 7400 200 86900 9300; B 7200 200 62200 9100; B 7200 200 87000 9100; B 7000 200 62100 8900; B 7000 200 87100 8900; B 6800 200 62000 8700; B 6800 200 87200 8700; B 6600 200 61900 8500; B 6600 200 87300 8500; B 6400 200 61800 8300; B 6400 200 87400 8300; B 6200 200 61700 8100; B 7000 200 74700 8100; B 6200 200 87500 8100; B 6000 200 61600 7900; B 7400 200 74700 7900; B 6000 200 87600 7900; B 5800 200 61500 7700; B 7800 200 74700 7700; B 5800 200 87700 7700; B 5600 200 61400 7500; B 8200 200 74700 7500; B 5600 200 87800 7500; B 5400 200 61300 7300; B 8600 200 74700 7300; B 5400 200 87900 7300; B 5200 200 61200 7100; B 9000 200 74700 7100; B 5200 200 88000 7100; B 5000 200 61100 6900; B 9400 200 74700 6900; B 5000 200 88100 6900; B 4800 200 61000 6700; B 9800 200 74700 6700; B 4800 200 88200 6700; B 4600 200 60900 6500; B 10200 200 74700 6500; B 4600 200 88300 6500; B 4400 200 60800 6300; B 10600 200 74700 6300; B 4400 200 88400 6300; B 4200 200 60700 6100; B 11000 200 74700 6100; B 4200 200 88500 6100; B 4000 200 60600 5900; B 11400 200 74700 5900; B 4000 200 88600 5900; B 3800 200 60500 5700; B 11800 200 74700 5700; B 3800 200 88700 5700; B 3600 200 60400 5500; B 12200 200 74700 5500; B 3600 200 88800 5500; B 3400 200 60300 5300; B 12600 200 74700 5300; B 3400 200 88900 5300; B 3200 200 60200 5100; B 13000 200 74700 5100; B 3200 200 89000 5100; B 3000 200 60100 4900; B 13400 200 74700 4900; B 3000 200 89100 4900; B 2800 200 60000 4700; B 13800 200 74700 4700; B 2800 200 89200 4700; B 2600 200 59900 4500; B 14200 200 74700 4500; B 2600 200 89300 4500; B 2400 200 59800 4300; B 14600 200 74700 4300; B 2400 200 89400 4300; B 2200 200 59700 4100; B 15000 200 74700 4100; B 2200 200 89500 4100; B 2000 200 59600 3900; B 15400 200 74700 3900; B 2000 200 89600 3900; B 1800 200 59500 3700; B 15800 200 74700 3700; B 1800 200 89700 3700; B 1600 200 59400 3500; B 16200 200 74700 3500; B 1600 200 89800 3500; B 1400 200 59300 3300; B 16600 200 74700 3300; B 1400 200 89900 3300; B 1200 200 59200 3100; B 17000 200 74700 3100; B 1200 200 90000 3100; B 1000 200 59100 2900; B 17400 200 74700 2900; B 1000 200 90100 2900; B 800 200 59000 2700; B 17800 200 74700 2700; B 800 200 90200 2700; B 600 200 58900 2500; B 18200 200 74700 2500; B 600 200 90300 2500; B 400 200 58800 2300; B 18600 200 74700 2300; B 400 200 90400 2300; B 200 200 58700 2100; B 19000 200 74700 2100; B 200 200 90500 2100; B 19400 200 74700 1900; B 19800 200 74700 1700; B 20200 200 74700 1500; B 20600 200 74700 1300; B 21000 200 74700 1100; B 21400 200 74700 900; B 21800 200 74700 700; B 22200 200 74700 500; B 22600 200 74700 300; B 23000 200 74700 100; B 23400 200 74700 -100; B 23800 200 74700 -300; B 24200 200 74700 -500; B 24600 200 74700 -700; B 25000 200 74700 -900; B 25400 200 74700 -1100; B 25800 200 74700 -1300; L COP; B 25800 200 74700 30500; B 25400 200 74700 30300; B 25000 200 74700 30100; B 24600 200 74700 29900; B 24200 200 74700 29700; B 23800 200 74700 29500; B 23400 200 74700 29300; B 23000 200 74700 29100; B 22600 200 74700 28900; B 22200 200 74700 28700; B 21800 200 74700 28500; B 21400 200 74700 28300; B 21000 200 74700 28100; B 20600 200 74700 27900; B 200 200 58700 27700; B 20200 200 74700 27700; B 200 200 90500 27700; B 400 200 58800 27500; B 19800 200 74700 27500; B 400 200 90400 27500; B 600 200 58900 27300; B 19400 200 74700 27300; B 600 200 90300 27300; B 800 200 59000 27100; B 19000 200 74700 27100; B 800 200 90200 27100; B 1000 200 59100 26900; B 18600 200 74700 26900; B 1000 200 90100 26900; B 1200 200 59200 26700; B 18200 200 74700 26700; B 1200 200 90000 26700; B 1400 200 59300 26500; B 17800 200 74700 26500; B 1400 200 89900 26500; B 1600 200 59400 26300; B 17400 200 74700 26300; B 1600 200 89800 26300; B 1800 200 59500 26100; B 17000 200 74700 26100; B 1800 200 89700 26100; B 2000 200 59600 25900; B 16600 200 74700 25900; B 2000 200 89600 25900; B 2200 200 59700 25700; B 16200 200 74700 25700; B 2200 200 89500 25700; B 2400 200 59800 25500; B 15800 200 74700 25500; B 2400 200 89400 25500; B 2600 200 59900 25300; B 15400 200 74700 25300; B 2600 200 89300 25300; B 2800 200 60000 25100; B 15000 200 74700 25100; B 2800 200 89200 25100; B 3000 200 60100 24900; B 14600 200 74700 24900; B 3000 200 89100 24900; B 3200 200 60200 24700; B 14200 200 74700 24700; B 3200 200 89000 24700; B 3400 200 60300 24500; B 13800 200 74700 24500; B 3400 200 88900 24500; B 3600 200 60400 24300; B 13400 200 74700 24300; B 3600 200 88800 24300; B 3800 200 60500 24100; B 13000 200 74700 24100; B 3800 200 88700 24100; B 4000 200 60600 23900; B 12600 200 74700 23900; B 4000 200 88600 23900; B 4200 200 60700 23700; B 12200 200 74700 23700; B 4200 200 88500 23700; B 4400 200 60800 23500; B 11800 200 74700 23500; B 4400 200 88400 23500; B 4600 200 60900 23300; B 11400 200 74700 23300; B 4600 200 88300 23300; B 4800 200 61000 23100; B 11000 200 74700 23100; B 4800 200 88200 23100; B 5000 200 61100 22900; B 10600 200 74700 22900; B 5000 200 88100 22900; B 5200 200 61200 22700; B 10200 200 74700 22700; B 5200 200 88000 22700; B 5400 200 61300 22500; B 9800 200 74700 22500; B 5400 200 87900 22500; B 5600 200 61400 22300; B 9400 200 74700 22300; B 5600 200 87800 22300; B 5800 200 61500 22100; B 9000 200 74700 22100; B 5800 200 87700 22100; B 6000 200 61600 21900; B 8600 200 74700 21900; B 6000 200 87600 21900; B 6200 200 61700 21700; B 8200 200 74700 21700; B 6200 200 87500 21700; B 6400 200 61800 21500; B 7800 200 74700 21500; B 6400 200 87400 21500; B 6600 200 61900 21300; B 7400 200 74700 21300; B 6600 200 87300 21300; B 6800 200 62000 21100; B 7000 200 74700 21100; B 6800 200 87200 21100; B 7000 200 62100 20900; B 7000 200 87100 20900; B 7200 200 62200 20700; B 7200 200 87000 20700; B 7400 200 62300 20500; B 7400 200 86900 20500; B 7600 200 62400 20300; B 7600 200 86800 20300; B 7800 200 62500 20100; B 7800 200 86700 20100; B 8000 200 62600 19900; B 8000 200 86600 19900; B 8200 200 62700 19700; B 8200 200 86500 19700; B 8400 200 62800 19500; B 8400 200 86400 19500; B 8600 200 62900 19300; B 8600 200 86300 19300; B 8800 200 63000 19100; B 8800 200 86200 19100; B 9000 200 63100 18900; B 9000 200 86100 18900; B 9200 200 63200 18700; B 9200 200 86000 18700; B 9400 200 63300 18500; B 9400 200 85900 18500; B 9600 7000 63400 14900; B 9600 7000 85800 14900; B 9400 200 63300 11300; B 9400 200 85900 11300; B 9200 200 63200 11100; B 9200 200 86000 11100; B 9000 200 63100 10900; B 9000 200 86100 10900; B 8800 200 63000 10700; B 8800 200 86200 10700; B 8600 200 62900 10500; B 8600 200 86300 10500; B 8400 200 62800 10300; B 8400 200 86400 10300; B 8200 200 62700 10100; B 8200 200 86500 10100; B 8000 200 62600 9900; B 8000 200 86600 9900; B 7800 200 62500 9700; B 7800 200 86700 9700; B 7600 200 62400 9500; B 7600 200 86800 9500; B 7400 200 62300 9300; B 7400 200 86900 9300; B 7200 200 62200 9100; B 7200 200 87000 9100; B 7000 200 62100 8900; B 7000 200 87100 8900; B 6800 200 62000 8700; B 6800 200 87200 8700; B 6600 200 61900 8500; B 6600 200 87300 8500; B 6400 200 61800 8300; B 6400 200 87400 8300; B 6200 200 61700 8100; B 7000 200 74700 8100; B 6200 200 87500 8100; B 6000 200 61600 7900; B 7400 200 74700 7900; B 6000 200 87600 7900; B 5800 200 61500 7700; B 7800 200 74700 7700; B 5800 200 87700 7700; B 5600 200 61400 7500; B 8200 200 74700 7500; B 5600 200 87800 7500; B 5400 200 61300 7300; B 8600 200 74700 7300; B 5400 200 87900 7300; B 5200 200 61200 7100; B 9000 200 74700 7100; B 5200 200 88000 7100; B 5000 200 61100 6900; B 9400 200 74700 6900; B 5000 200 88100 6900; B 4800 200 61000 6700; B 9800 200 74700 6700; B 4800 200 88200 6700; B 4600 200 60900 6500; B 10200 200 74700 6500; B 4600 200 88300 6500; B 4400 200 60800 6300; B 10600 200 74700 6300; B 4400 200 88400 6300; B 4200 200 60700 6100; B 11000 200 74700 6100; B 4200 200 88500 6100; B 4000 200 60600 5900; B 11400 200 74700 5900; B 4000 200 88600 5900; B 3800 200 60500 5700; B 11800 200 74700 5700; B 3800 200 88700 5700; B 3600 200 60400 5500; B 12200 200 74700 5500; B 3600 200 88800 5500; B 3400 200 60300 5300; B 12600 200 74700 5300; B 3400 200 88900 5300; B 3200 200 60200 5100; B 13000 200 74700 5100; B 3200 200 89000 5100; B 3000 200 60100 4900; B 13400 200 74700 4900; B 3000 200 89100 4900; B 2800 200 60000 4700; B 13800 200 74700 4700; B 2800 200 89200 4700; B 2600 200 59900 4500; B 14200 200 74700 4500; B 2600 200 89300 4500; B 2400 200 59800 4300; B 14600 200 74700 4300; B 2400 200 89400 4300; B 2200 200 59700 4100; B 15000 200 74700 4100; B 2200 200 89500 4100; B 2000 200 59600 3900; B 15400 200 74700 3900; B 2000 200 89600 3900; B 1800 200 59500 3700; B 15800 200 74700 3700; B 1800 200 89700 3700; B 1600 200 59400 3500; B 16200 200 74700 3500; B 1600 200 89800 3500; B 1400 200 59300 3300; B 16600 200 74700 3300; B 1400 200 89900 3300; B 1200 200 59200 3100; B 17000 200 74700 3100; B 1200 200 90000 3100; B 1000 200 59100 2900; B 17400 200 74700 2900; B 1000 200 90100 2900; B 800 200 59000 2700; B 17800 200 74700 2700; B 800 200 90200 2700; B 600 200 58900 2500; B 18200 200 74700 2500; B 600 200 90300 2500; B 400 200 58800 2300; B 18600 200 74700 2300; B 400 200 90400 2300; B 200 200 58700 2100; B 19000 200 74700 2100; B 200 200 90500 2100; B 19400 200 74700 1900; B 19800 200 74700 1700; B 20200 200 74700 1500; B 20600 200 74700 1300; B 21000 200 74700 1100; B 21400 200 74700 900; B 21800 200 74700 700; B 22200 200 74700 500; B 22600 200 74700 300; B 23000 200 74700 100; B 23400 200 74700 -100; B 23800 200 74700 -300; B 24200 200 74700 -500; B 24600 200 74700 -700; B 25000 200 74700 -900; B 25400 200 74700 -1100; B 25800 200 74700 -1300; L CPS; B 34000 1000 74600 31100; B 1000 32000 58100 14600; B 1000 32000 91100 14600; B 34000 1000 74600 -1900; DF; C 1; End magic-8.0.210/scmos/examples/nist-mems-library/pixel-80x80.cif0000644000175000001440000004500410751423606022372 0ustar timusersDS 1 1 2; 9 pixel-80x80; L CMS; B 1200 1200 115800 15800; L CMF; B 1200 600 115800 16100; B 1400 200 115700 15700; B 1600 200 115600 15500; B 1800 200 115500 15300; B 1400 200 115100 15100; B 1400 200 114900 14900; B 1400 200 114700 14700; B 1400 200 114500 14500; B 1400 200 114300 14300; B 1400 200 114100 14100; B 1400 200 113900 13900; B 1400 200 113700 13700; B 1400 200 113500 13500; B 1400 200 113300 13300; B 1400 200 113100 13100; B 1400 200 112900 12900; B 1400 200 112700 12700; B 1400 200 112500 12500; B 1400 200 112300 12300; B 1400 200 112100 12100; B 1400 200 111900 11900; B 1400 200 111700 11700; B 1800 200 111300 11500; B 1600 200 111200 11300; B 1400 200 111100 11100; B 1200 1600 111000 10200; B 1200 1600 111000 6600; B 1400 200 111100 5700; B 1600 200 111200 5500; B 1800 200 111300 5300; B 1400 200 111700 5100; B 1400 200 111900 4900; B 1400 200 112100 4700; B 1400 200 112300 4500; B 1400 200 112500 4300; B 1400 200 112700 4100; B 1400 200 112900 3900; B 1400 200 113100 3700; B 1400 200 113300 3500; B 1400 200 113500 3300; B 1400 200 113700 3100; B 1400 200 113900 2900; B 1400 200 114100 2700; B 1400 200 114300 2500; B 1400 200 114500 2300; B 1400 200 114700 2100; B 1400 200 114900 1900; B 1400 200 115100 1700; B 1400 200 115300 1500; B 1400 200 115500 1300; B 1400 200 115700 1100; B 1200 200 115800 900; B 1000 200 115900 700; B 800 200 116000 500; L CPG; B 1200 400 106200 11400; B 400 5600 105800 8400; B 400 2200 106600 10100; B 1200 400 107800 11400; B 400 2200 107400 10100; B 1200 400 107000 8800; B 400 2200 108200 10100; B 1200 400 109400 11400; B 400 2200 109000 10100; B 1200 400 108600 8800; B 400 2200 109800 10100; B 1200 2200 111000 10500; B 800 400 111000 9200; B 1800 400 110500 8800; B 1200 400 107000 8000; B 400 2200 106600 6700; B 1200 400 106200 5400; B 400 2200 107400 6700; B 1200 400 108600 8000; B 400 2200 108200 6700; B 1200 400 107800 5400; B 400 2200 109000 6700; B 1800 400 110500 8000; B 400 2200 109800 6700; B 800 400 111000 7600; B 1200 400 109400 5400; B 1200 2200 111000 6300; L CAA; B 18000 1000 108400 16900; B 1000 2000 99900 15400; B 12000 200 108400 16300; B 11600 200 108400 16100; B 11200 200 108400 15900; B 10800 200 108400 15700; B 10400 200 108400 15500; B 10000 200 108400 15300; B 9600 200 108400 15100; B 9200 200 108400 14900; B 8800 200 108400 14700; B 8400 200 108400 14500; B 1000 2000 116900 15400; B 1200 200 100000 14300; B 8000 200 108400 14300; B 1200 200 116800 14300; B 1400 200 100100 14100; B 7600 200 108400 14100; B 1400 200 116700 14100; B 1600 200 100200 13900; B 7200 200 108400 13900; B 1600 200 116600 13900; B 1800 200 100300 13700; B 6800 200 108400 13700; B 1800 200 116500 13700; B 2000 200 100400 13500; B 6400 200 108400 13500; B 2000 200 116400 13500; B 2200 200 100500 13300; B 6000 200 108400 13300; B 2200 200 116300 13300; B 2400 200 100600 13100; B 5600 200 108400 13100; B 2400 200 116200 13100; B 2600 200 100700 12900; B 5200 200 108400 12900; B 2600 200 116100 12900; B 2800 200 100800 12700; B 4800 200 108400 12700; B 2800 200 116000 12700; B 3000 200 100900 12500; B 3000 200 115900 12500; B 3200 200 101000 12300; B 3200 200 115800 12300; B 3400 200 101100 12100; B 3400 200 115700 12100; B 3600 200 101200 11900; B 3600 200 115600 11900; B 3800 200 101300 11700; B 3800 200 115500 11700; B 4000 200 101400 11500; B 4000 200 115400 11500; B 4200 200 101500 11300; B 4200 200 115300 11300; B 4400 200 101600 11100; B 4400 200 115200 11100; B 4600 200 101700 10900; B 4600 200 115100 10900; B 4800 4800 101800 8400; B 4800 4800 115000 8400; B 4600 200 101700 5900; B 4600 200 115100 5900; B 4400 200 101600 5700; B 4400 200 115200 5700; B 4200 200 101500 5500; B 4200 200 115300 5500; B 4000 200 101400 5300; B 4000 200 115400 5300; B 3800 200 101300 5100; B 3800 200 115500 5100; B 3600 200 101200 4900; B 3600 200 115600 4900; B 3400 200 101100 4700; B 3400 200 115700 4700; B 3200 200 101000 4500; B 3200 200 115800 4500; B 3000 200 100900 4300; B 3000 200 115900 4300; B 2800 200 100800 4100; B 4800 200 108400 4100; B 2800 200 116000 4100; B 2600 200 100700 3900; B 5200 200 108400 3900; B 2600 200 116100 3900; B 2400 200 100600 3700; B 5600 200 108400 3700; B 2400 200 116200 3700; B 2200 200 100500 3500; B 6000 200 108400 3500; B 2200 200 116300 3500; B 2000 200 100400 3300; B 6400 200 108400 3300; B 2000 200 116400 3300; B 1800 200 100300 3100; B 6800 200 108400 3100; B 1800 200 116500 3100; B 1600 200 100200 2900; B 7200 200 108400 2900; B 1600 200 116600 2900; B 1400 200 100100 2700; B 7600 200 108400 2700; B 1400 200 116700 2700; B 1200 200 100000 2500; B 8000 200 108400 2500; B 1200 200 116800 2500; B 1000 2000 99900 1400; B 8400 200 108400 2300; B 8800 200 108400 2100; B 9200 200 108400 1900; B 9600 200 108400 1700; B 10000 200 108400 1500; B 10400 200 108400 1300; B 10800 200 108400 1100; B 11200 200 108400 900; B 11600 200 108400 700; B 12000 200 108400 500; B 1000 2000 116900 1400; B 18000 1000 108400 -100; L CVA; B 12000 200 108400 16300; B 11600 200 108400 16100; B 11200 200 108400 15900; B 10800 200 108400 15700; B 400 400 115800 15800; B 10400 200 108400 15500; B 10000 200 108400 15300; B 9600 200 108400 15100; B 9200 200 108400 14900; B 8800 200 108400 14700; B 8400 200 108400 14500; B 200 200 100500 14300; B 8000 200 108400 14300; B 200 200 116300 14300; B 400 200 100600 14100; B 7600 200 108400 14100; B 400 200 116200 14100; B 600 200 100700 13900; B 7200 200 108400 13900; B 600 200 116100 13900; B 800 200 100800 13700; B 6800 200 108400 13700; B 800 200 116000 13700; B 1000 200 100900 13500; B 6400 200 108400 13500; B 1000 200 115900 13500; B 1200 200 101000 13300; B 6000 200 108400 13300; B 1200 200 115800 13300; B 1400 200 101100 13100; B 5600 200 108400 13100; B 1400 200 115700 13100; B 1600 200 101200 12900; B 5200 200 108400 12900; B 1600 200 115600 12900; B 1800 200 101300 12700; B 4800 200 108400 12700; B 1800 200 115500 12700; B 2000 200 101400 12500; B 2000 200 115400 12500; B 2200 200 101500 12300; B 2200 200 115300 12300; B 2400 200 101600 12100; B 2400 200 115200 12100; B 2600 200 101700 11900; B 2600 200 115100 11900; B 2800 200 101800 11700; B 2800 200 115000 11700; B 3000 200 101900 11500; B 3000 200 114900 11500; B 3200 200 102000 11300; B 3200 200 114800 11300; B 3400 200 102100 11100; B 3400 200 114700 11100; B 3600 200 102200 10900; B 3600 200 114600 10900; B 3800 4800 102300 8400; B 3800 4800 114500 8400; B 3600 200 102200 5900; B 3600 200 114600 5900; B 3400 200 102100 5700; B 3400 200 114700 5700; B 3200 200 102000 5500; B 3200 200 114800 5500; B 3000 200 101900 5300; B 3000 200 114900 5300; B 2800 200 101800 5100; B 2800 200 115000 5100; B 2600 200 101700 4900; B 2600 200 115100 4900; B 2400 200 101600 4700; B 2400 200 115200 4700; B 2200 200 101500 4500; B 2200 200 115300 4500; B 2000 200 101400 4300; B 2000 200 115400 4300; B 1800 200 101300 4100; B 4800 200 108400 4100; B 1800 200 115500 4100; B 1600 200 101200 3900; B 5200 200 108400 3900; B 1600 200 115600 3900; B 1400 200 101100 3700; B 5600 200 108400 3700; B 1400 200 115700 3700; B 1200 200 101000 3500; B 6000 200 108400 3500; B 1200 200 115800 3500; B 1000 200 100900 3300; B 6400 200 108400 3300; B 1000 200 115900 3300; B 800 200 100800 3100; B 6800 200 108400 3100; B 800 200 116000 3100; B 600 200 100700 2900; B 7200 200 108400 2900; B 600 200 116100 2900; B 400 200 100600 2700; B 7600 200 108400 2700; B 400 200 116200 2700; B 200 200 100500 2500; B 8000 200 108400 2500; B 200 200 116300 2500; B 8400 200 108400 2300; B 8800 200 108400 2100; B 9200 200 108400 1900; B 9600 200 108400 1700; B 10000 200 108400 1500; B 10400 200 108400 1300; B 10800 200 108400 1100; B 11200 200 108400 900; B 11600 200 108400 700; B 12000 200 108400 500; L CCA; B 12000 200 108400 16300; B 11600 200 108400 16100; B 11200 200 108400 15900; B 10800 200 108400 15700; B 10400 200 108400 15500; B 10000 200 108400 15300; B 9600 200 108400 15100; B 9200 200 108400 14900; B 8800 200 108400 14700; B 8400 200 108400 14500; B 200 200 100500 14300; B 8000 200 108400 14300; B 200 200 116300 14300; B 400 200 100600 14100; B 7600 200 108400 14100; B 400 200 116200 14100; B 600 200 100700 13900; B 7200 200 108400 13900; B 600 200 116100 13900; B 800 200 100800 13700; B 6800 200 108400 13700; B 800 200 116000 13700; B 1000 200 100900 13500; B 6400 200 108400 13500; B 1000 200 115900 13500; B 1200 200 101000 13300; B 6000 200 108400 13300; B 1200 200 115800 13300; B 1400 200 101100 13100; B 5600 200 108400 13100; B 1400 200 115700 13100; B 1600 200 101200 12900; B 5200 200 108400 12900; B 1600 200 115600 12900; B 1800 200 101300 12700; B 4800 200 108400 12700; B 1800 200 115500 12700; B 2000 200 101400 12500; B 2000 200 115400 12500; B 2200 200 101500 12300; B 2200 200 115300 12300; B 2400 200 101600 12100; B 2400 200 115200 12100; B 2600 200 101700 11900; B 2600 200 115100 11900; B 2800 200 101800 11700; B 2800 200 115000 11700; B 3000 200 101900 11500; B 3000 200 114900 11500; B 3200 200 102000 11300; B 3200 200 114800 11300; B 3400 200 102100 11100; B 3400 200 114700 11100; B 3600 200 102200 10900; B 3600 200 114600 10900; B 3800 4800 102300 8400; B 3800 4800 114500 8400; B 3600 200 102200 5900; B 3600 200 114600 5900; B 3400 200 102100 5700; B 3400 200 114700 5700; B 3200 200 102000 5500; B 3200 200 114800 5500; B 3000 200 101900 5300; B 3000 200 114900 5300; B 2800 200 101800 5100; B 2800 200 115000 5100; B 2600 200 101700 4900; B 2600 200 115100 4900; B 2400 200 101600 4700; B 2400 200 115200 4700; B 2200 200 101500 4500; B 2200 200 115300 4500; B 2000 200 101400 4300; B 2000 200 115400 4300; B 1800 200 101300 4100; B 4800 200 108400 4100; B 1800 200 115500 4100; B 1600 200 101200 3900; B 5200 200 108400 3900; B 1600 200 115600 3900; B 1400 200 101100 3700; B 5600 200 108400 3700; B 1400 200 115700 3700; B 1200 200 101000 3500; B 6000 200 108400 3500; B 1200 200 115800 3500; B 1000 200 100900 3300; B 6400 200 108400 3300; B 1000 200 115900 3300; B 800 200 100800 3100; B 6800 200 108400 3100; B 800 200 116000 3100; B 600 200 100700 2900; B 7200 200 108400 2900; B 600 200 116100 2900; B 400 200 100600 2700; B 7600 200 108400 2700; B 400 200 116200 2700; B 200 200 100500 2500; B 8000 200 108400 2500; B 200 200 116300 2500; B 8400 200 108400 2300; B 8800 200 108400 2100; B 9200 200 108400 1900; B 9600 200 108400 1700; B 10000 200 108400 1500; B 10400 200 108400 1300; B 10800 200 108400 1100; B 11200 200 108400 900; B 11600 200 108400 700; B 12000 200 108400 500; L CCP; B 400 400 111000 11000; B 400 400 111000 10000; B 400 400 111000 6800; B 400 400 111000 5800; L CSP; B 18800 1800 108400 16900; B 1800 15200 99900 8400; B 1800 15200 116900 8400; B 18800 1800 108400 -100; L COG; B 12000 200 108400 16300; B 11600 200 108400 16100; B 11200 200 108400 15900; B 10800 200 108400 15700; B 10400 200 108400 15500; B 10000 200 108400 15300; B 9600 200 108400 15100; B 9200 200 108400 14900; B 8800 200 108400 14700; B 8400 200 108400 14500; B 200 200 100500 14300; B 8000 200 108400 14300; B 200 200 116300 14300; B 400 200 100600 14100; B 7600 200 108400 14100; B 400 200 116200 14100; B 600 200 100700 13900; B 7200 200 108400 13900; B 600 200 116100 13900; B 800 200 100800 13700; B 6800 200 108400 13700; B 800 200 116000 13700; B 1000 200 100900 13500; B 6400 200 108400 13500; B 1000 200 115900 13500; B 1200 200 101000 13300; B 6000 200 108400 13300; B 1200 200 115800 13300; B 1400 200 101100 13100; B 5600 200 108400 13100; B 1400 200 115700 13100; B 1600 200 101200 12900; B 5200 200 108400 12900; B 1600 200 115600 12900; B 1800 200 101300 12700; B 4800 200 108400 12700; B 1800 200 115500 12700; B 2000 200 101400 12500; B 2000 200 115400 12500; B 2200 200 101500 12300; B 2200 200 115300 12300; B 2400 200 101600 12100; B 2400 200 115200 12100; B 2600 200 101700 11900; B 2600 200 115100 11900; B 2800 200 101800 11700; B 2800 200 115000 11700; B 3000 200 101900 11500; B 3000 200 114900 11500; B 3200 200 102000 11300; B 3200 200 114800 11300; B 3400 200 102100 11100; B 3400 200 114700 11100; B 3600 200 102200 10900; B 3600 200 114600 10900; B 3800 4800 102300 8400; B 3800 4800 114500 8400; B 3600 200 102200 5900; B 3600 200 114600 5900; B 3400 200 102100 5700; B 3400 200 114700 5700; B 3200 200 102000 5500; B 3200 200 114800 5500; B 3000 200 101900 5300; B 3000 200 114900 5300; B 2800 200 101800 5100; B 2800 200 115000 5100; B 2600 200 101700 4900; B 2600 200 115100 4900; B 2400 200 101600 4700; B 2400 200 115200 4700; B 2200 200 101500 4500; B 2200 200 115300 4500; B 2000 200 101400 4300; B 2000 200 115400 4300; B 1800 200 101300 4100; B 4800 200 108400 4100; B 1800 200 115500 4100; B 1600 200 101200 3900; B 5200 200 108400 3900; B 1600 200 115600 3900; B 1400 200 101100 3700; B 5600 200 108400 3700; B 1400 200 115700 3700; B 1200 200 101000 3500; B 6000 200 108400 3500; B 1200 200 115800 3500; B 1000 200 100900 3300; B 6400 200 108400 3300; B 1000 200 115900 3300; B 800 200 100800 3100; B 6800 200 108400 3100; B 800 200 116000 3100; B 600 200 100700 2900; B 7200 200 108400 2900; B 600 200 116100 2900; B 400 200 100600 2700; B 7600 200 108400 2700; B 400 200 116200 2700; B 200 200 100500 2500; B 8000 200 108400 2500; B 200 200 116300 2500; B 8400 200 108400 2300; B 8800 200 108400 2100; B 9200 200 108400 1900; B 9600 200 108400 1700; B 10000 200 108400 1500; B 10400 200 108400 1300; B 10800 200 108400 1100; B 11200 200 108400 900; B 11600 200 108400 700; B 12000 200 108400 500; L COP; B 12000 200 108400 16300; B 11600 200 108400 16100; B 11200 200 108400 15900; B 10800 200 108400 15700; B 10400 200 108400 15500; B 10000 200 108400 15300; B 9600 200 108400 15100; B 9200 200 108400 14900; B 8800 200 108400 14700; B 8400 200 108400 14500; B 200 200 100500 14300; B 8000 200 108400 14300; B 200 200 116300 14300; B 400 200 100600 14100; B 7600 200 108400 14100; B 400 200 116200 14100; B 600 200 100700 13900; B 7200 200 108400 13900; B 600 200 116100 13900; B 800 200 100800 13700; B 6800 200 108400 13700; B 800 200 116000 13700; B 1000 200 100900 13500; B 6400 200 108400 13500; B 1000 200 115900 13500; B 1200 200 101000 13300; B 6000 200 108400 13300; B 1200 200 115800 13300; B 1400 200 101100 13100; B 5600 200 108400 13100; B 1400 200 115700 13100; B 1600 200 101200 12900; B 5200 200 108400 12900; B 1600 200 115600 12900; B 1800 200 101300 12700; B 4800 200 108400 12700; B 1800 200 115500 12700; B 2000 200 101400 12500; B 2000 200 115400 12500; B 2200 200 101500 12300; B 2200 200 115300 12300; B 2400 200 101600 12100; B 2400 200 115200 12100; B 2600 200 101700 11900; B 2600 200 115100 11900; B 2800 200 101800 11700; B 2800 200 115000 11700; B 3000 200 101900 11500; B 3000 200 114900 11500; B 3200 200 102000 11300; B 3200 200 114800 11300; B 3400 200 102100 11100; B 3400 200 114700 11100; B 3600 200 102200 10900; B 3600 200 114600 10900; B 3800 4800 102300 8400; B 3800 4800 114500 8400; B 3600 200 102200 5900; B 3600 200 114600 5900; B 3400 200 102100 5700; B 3400 200 114700 5700; B 3200 200 102000 5500; B 3200 200 114800 5500; B 3000 200 101900 5300; B 3000 200 114900 5300; B 2800 200 101800 5100; B 2800 200 115000 5100; B 2600 200 101700 4900; B 2600 200 115100 4900; B 2400 200 101600 4700; B 2400 200 115200 4700; B 2200 200 101500 4500; B 2200 200 115300 4500; B 2000 200 101400 4300; B 2000 200 115400 4300; B 1800 200 101300 4100; B 4800 200 108400 4100; B 1800 200 115500 4100; B 1600 200 101200 3900; B 5200 200 108400 3900; B 1600 200 115600 3900; B 1400 200 101100 3700; B 5600 200 108400 3700; B 1400 200 115700 3700; B 1200 200 101000 3500; B 6000 200 108400 3500; B 1200 200 115800 3500; B 1000 200 100900 3300; B 6400 200 108400 3300; B 1000 200 115900 3300; B 800 200 100800 3100; B 6800 200 108400 3100; B 800 200 116000 3100; B 600 200 100700 2900; B 7200 200 108400 2900; B 600 200 116100 2900; B 400 200 100600 2700; B 7600 200 108400 2700; B 400 200 116200 2700; B 200 200 100500 2500; B 8000 200 108400 2500; B 200 200 116300 2500; B 8400 200 108400 2300; B 8800 200 108400 2100; B 9200 200 108400 1900; B 9600 200 108400 1700; B 10000 200 108400 1500; B 10400 200 108400 1300; B 10800 200 108400 1100; B 11200 200 108400 900; B 11600 200 108400 700; B 12000 200 108400 500; L CPS; B 18000 1000 108400 16900; B 1000 16000 99900 8400; B 1000 16000 116900 8400; B 18000 1000 108400 -100; DF; C 1; End magic-8.0.210/scmos/examples/nist-mems-library/open-oxide-80x80.mag0000644000175000001440000000512310751423606023321 0ustar timusersmagic tech scmos timestamp 760840453 << substrateopen >> rect 647 -163 707 -162 rect 648 -164 706 -163 rect 649 -165 705 -164 rect 650 -166 704 -165 rect 651 -167 703 -166 rect 652 -168 702 -167 rect 653 -169 701 -168 rect 654 -170 700 -169 rect 655 -171 699 -170 rect 656 -172 698 -171 rect 637 -173 638 -172 rect 657 -173 697 -172 rect 716 -173 717 -172 rect 637 -174 639 -173 rect 658 -174 696 -173 rect 715 -174 717 -173 rect 637 -175 640 -174 rect 659 -175 695 -174 rect 714 -175 717 -174 rect 637 -176 641 -175 rect 660 -176 694 -175 rect 713 -176 717 -175 rect 637 -177 642 -176 rect 661 -177 693 -176 rect 712 -177 717 -176 rect 637 -178 643 -177 rect 662 -178 692 -177 rect 711 -178 717 -177 rect 637 -179 644 -178 rect 663 -179 691 -178 rect 710 -179 717 -178 rect 637 -180 645 -179 rect 664 -180 690 -179 rect 709 -180 717 -179 rect 637 -181 646 -180 rect 665 -181 689 -180 rect 708 -181 717 -180 rect 637 -182 647 -181 rect 707 -182 717 -181 rect 637 -183 648 -182 rect 706 -183 717 -182 rect 637 -184 649 -183 rect 705 -184 717 -183 rect 637 -185 650 -184 rect 704 -185 717 -184 rect 637 -186 651 -185 rect 703 -186 717 -185 rect 637 -187 652 -186 rect 702 -187 717 -186 rect 637 -188 653 -187 rect 701 -188 717 -187 rect 637 -189 654 -188 rect 700 -189 717 -188 rect 637 -190 655 -189 rect 699 -190 717 -189 rect 637 -214 656 -190 rect 698 -214 717 -190 rect 637 -215 655 -214 rect 699 -215 717 -214 rect 637 -216 654 -215 rect 700 -216 717 -215 rect 637 -217 653 -216 rect 701 -217 717 -216 rect 637 -218 652 -217 rect 702 -218 717 -217 rect 637 -219 651 -218 rect 703 -219 717 -218 rect 637 -220 650 -219 rect 704 -220 717 -219 rect 637 -221 649 -220 rect 705 -221 717 -220 rect 637 -222 648 -221 rect 706 -222 717 -221 rect 637 -223 647 -222 rect 707 -223 717 -222 rect 637 -224 646 -223 rect 665 -224 689 -223 rect 708 -224 717 -223 rect 637 -225 645 -224 rect 664 -225 690 -224 rect 709 -225 717 -224 rect 637 -226 644 -225 rect 663 -226 691 -225 rect 710 -226 717 -225 rect 637 -227 643 -226 rect 662 -227 692 -226 rect 711 -227 717 -226 rect 637 -228 642 -227 rect 661 -228 693 -227 rect 712 -228 717 -227 rect 637 -229 641 -228 rect 660 -229 694 -228 rect 713 -229 717 -228 rect 637 -230 640 -229 rect 659 -230 695 -229 rect 714 -230 717 -229 rect 637 -231 639 -230 rect 658 -231 696 -230 rect 715 -231 717 -230 rect 637 -232 638 -231 rect 657 -232 697 -231 rect 716 -232 717 -231 rect 656 -233 698 -232 rect 655 -234 699 -233 rect 654 -235 700 -234 rect 653 -236 701 -235 rect 652 -237 702 -236 rect 651 -238 703 -237 rect 650 -239 704 -238 rect 649 -240 705 -239 rect 648 -241 706 -240 rect 647 -242 707 -241 << end >> magic-8.0.210/scmos/examples/nist-mems-library/micro-hot-plate.cif0000644000175000001440000016117310751423606023476 0ustar timusersDS 1 1 2; 9 micro-hot-plate; L CMF; B 2000 2000 51000 52200; B 6000 1200 3000 48600; B 6000 1200 49000 48600; B 6200 200 3100 47900; B 6200 200 48900 47900; B 6400 200 3200 47700; B 6400 200 48800 47700; B 6600 200 3300 47500; B 6600 200 48700 47500; B 6800 200 3400 47300; B 6800 200 48600 47300; B 1800 200 6100 47100; B 1800 200 45900 47100; B 1800 200 6300 46900; B 1800 200 45700 46900; B 1800 200 6500 46700; B 1800 200 45500 46700; B 1800 200 6700 46500; B 1800 200 45300 46500; B 1800 200 6900 46300; B 1800 200 45100 46300; B 1800 200 7100 46100; B 1800 200 44900 46100; B 1800 200 7300 45900; B 1800 200 44700 45900; B 1800 200 7500 45700; B 1800 200 44500 45700; B 1800 200 7700 45500; B 1800 200 44300 45500; B 1800 200 7900 45300; B 1800 200 44100 45300; B 1800 200 8100 45100; B 1800 200 43900 45100; B 1800 200 8300 44900; B 1800 200 43700 44900; B 1800 200 8500 44700; B 1800 200 43500 44700; B 1800 200 8700 44500; B 1800 200 43300 44500; B 1800 200 8900 44300; B 1800 200 43100 44300; B 1800 200 9100 44100; B 1800 200 42900 44100; B 1800 200 9300 43900; B 1800 200 42700 43900; B 1800 200 9500 43700; B 1800 200 42500 43700; B 1800 200 9700 43500; B 1800 200 42300 43500; B 1800 200 9900 43300; B 1800 200 42100 43300; B 1800 200 10100 43100; B 1800 200 41900 43100; B 1800 200 10300 42900; B 1800 200 41700 42900; B 1800 200 10500 42700; B 1800 200 41500 42700; B 1800 200 10700 42500; B 1800 200 41300 42500; B 1800 200 10900 42300; B 1800 200 41100 42300; B 1800 200 11100 42100; B 1800 200 40900 42100; B 1800 200 11300 41900; B 1800 200 40700 41900; B 1800 200 11500 41700; B 1800 200 40500 41700; B 1800 200 11700 41500; B 1800 200 40300 41500; B 1800 200 11900 41300; B 1800 200 40100 41300; B 1800 200 12100 41100; B 1800 200 39900 41100; B 1800 200 12300 40900; B 1800 200 39700 40900; B 1800 200 12500 40700; B 1800 200 39500 40700; B 1800 200 12700 40500; B 1800 200 39300 40500; B 1800 200 12900 40300; B 1800 200 39100 40300; B 1800 200 13100 40100; B 1800 200 38900 40100; B 1800 200 13300 39900; B 1800 200 38700 39900; B 1800 200 13500 39700; B 1800 200 38500 39700; B 1800 200 13700 39500; B 1800 200 38300 39500; B 1800 200 13900 39300; B 1800 200 38100 39300; B 1800 200 14100 39100; B 1800 200 37900 39100; B 1800 200 14300 38900; B 1800 200 37700 38900; B 1800 200 14500 38700; B 1800 200 37500 38700; B 1800 200 14700 38500; B 1800 200 37300 38500; B 1800 200 14900 38300; B 1800 200 37100 38300; B 1800 200 15100 38100; B 1800 200 36900 38100; B 1800 200 15300 37900; B 1800 200 36700 37900; B 1800 200 15500 37700; B 1800 200 36500 37700; B 1800 200 15700 37500; B 1800 200 36300 37500; B 1800 200 15900 37300; B 1800 200 36100 37300; B 1800 200 16100 37100; B 1800 200 35900 37100; B 1800 200 16300 36900; B 1800 200 35700 36900; B 1800 200 16500 36700; B 1800 200 35500 36700; B 1800 200 16700 36500; B 1800 200 35300 36500; B 1800 200 16900 36300; B 1800 200 35100 36300; B 19600 200 26000 36100; B 19200 200 26000 35900; B 18800 200 26000 35700; B 18400 200 26000 35500; B 18000 16400 26000 27200; B 18400 200 26000 18900; B 18800 200 26000 18700; B 19200 200 26000 18500; B 19600 200 26000 18300; B 1800 200 16900 18100; B 1800 200 35100 18100; B 1800 200 16700 17900; B 1800 200 35300 17900; B 1800 200 16500 17700; B 1800 200 35500 17700; B 1800 200 16300 17500; B 1800 200 35700 17500; B 1800 200 16100 17300; B 1800 200 35900 17300; B 1800 200 15900 17100; B 1800 200 36100 17100; B 1800 200 15700 16900; B 1800 200 36300 16900; B 1800 200 15500 16700; B 1800 200 36500 16700; B 1800 200 15300 16500; B 1800 200 36700 16500; B 1800 200 15100 16300; B 1800 200 36900 16300; B 1800 200 14900 16100; B 1800 200 37100 16100; B 1800 200 14700 15900; B 1800 200 37300 15900; B 1800 200 14500 15700; B 1800 200 37500 15700; B 1800 200 14300 15500; B 1800 200 37700 15500; B 1800 200 14100 15300; B 1800 200 37900 15300; B 1800 200 13900 15100; B 1800 200 38100 15100; B 1800 200 13700 14900; B 1800 200 38300 14900; B 1800 200 13500 14700; B 1800 200 38500 14700; B 1800 200 13300 14500; B 1800 200 38700 14500; B 1800 200 13100 14300; B 1800 200 38900 14300; B 1800 200 12900 14100; B 1800 200 39100 14100; B 1800 200 12700 13900; B 1800 200 39300 13900; B 1800 200 12500 13700; B 1800 200 39500 13700; B 1800 200 12300 13500; B 1800 200 39700 13500; B 1800 200 12100 13300; B 1800 200 39900 13300; B 1800 200 11900 13100; B 1800 200 40100 13100; B 1800 200 11700 12900; B 1800 200 40300 12900; B 1800 200 11500 12700; B 1800 200 40500 12700; B 1800 200 11300 12500; B 1800 200 40700 12500; B 1800 200 11100 12300; B 1800 200 40900 12300; B 1800 200 10900 12100; B 1800 200 41100 12100; B 1800 200 10700 11900; B 1800 200 41300 11900; B 1800 200 10500 11700; B 1800 200 41500 11700; B 1800 200 10300 11500; B 1800 200 41700 11500; B 1800 200 10100 11300; B 1800 200 41900 11300; B 1800 200 9900 11100; B 1800 200 42100 11100; B 1800 200 9700 10900; B 1800 200 42300 10900; B 1800 200 9500 10700; B 1800 200 42500 10700; B 1800 200 9300 10500; B 1800 200 42700 10500; B 1800 200 9100 10300; B 1800 200 42900 10300; B 1800 200 8900 10100; B 1800 200 43100 10100; B 1800 200 8700 9900; B 1800 200 43300 9900; B 1800 200 8500 9700; B 1800 200 43500 9700; B 1800 200 8300 9500; B 1800 200 43700 9500; B 1800 200 8100 9300; B 1800 200 43900 9300; B 1800 200 7900 9100; B 1800 200 44100 9100; B 1800 200 7700 8900; B 1800 200 44300 8900; B 1800 200 7500 8700; B 1800 200 44500 8700; B 1800 200 7300 8500; B 1800 200 44700 8500; B 1800 200 7100 8300; B 1800 200 44900 8300; B 1800 200 6900 8100; B 1800 200 45100 8100; B 1800 200 6700 7900; B 1800 200 45300 7900; B 1800 200 6500 7700; B 1800 200 45500 7700; B 1800 200 6300 7500; B 1800 200 45700 7500; B 1800 200 6100 7300; B 1800 200 45900 7300; B 6800 200 3400 7100; B 6800 200 48600 7100; B 6600 200 3300 6900; B 6600 200 48700 6900; B 6400 200 3200 6700; B 6400 200 48800 6700; B 6200 200 3100 6500; B 6200 200 48900 6500; B 6000 1200 3000 5800; B 6000 1200 49000 5800; B 2000 3200 1000 1600; L CPG; B 2000 200 51000 53100; B 2200 200 50900 52900; B 2400 200 50800 52700; B 2600 200 50700 52500; B 2800 200 50600 52300; B 3000 200 50500 52100; B 3200 200 50400 51900; B 3400 200 50300 51700; B 3600 200 50200 51500; B 3800 200 50100 51300; B 3800 200 49900 51100; B 3800 200 49700 50900; B 3800 200 49500 50700; B 3800 200 49300 50500; B 3800 200 49100 50300; B 3800 200 48900 50100; B 3800 200 48700 49900; B 3800 200 48500 49700; B 3800 200 48300 49500; B 3800 200 48100 49300; B 3800 200 47900 49100; B 3800 200 47700 48900; B 3800 200 47500 48700; B 3800 200 47300 48500; B 3800 200 47100 48300; B 3800 200 46900 48100; B 3800 200 46700 47900; B 3800 200 46500 47700; B 3800 200 46300 47500; B 3800 200 46100 47300; B 3800 200 45900 47100; B 3800 200 45700 46900; B 3800 200 45500 46700; B 3800 200 45300 46500; B 3800 200 45100 46300; B 3800 200 44900 46100; B 3800 200 44700 45900; B 3800 200 44500 45700; B 3800 200 44300 45500; B 3800 200 44100 45300; B 3800 200 43900 45100; B 3800 200 43700 44900; B 3800 200 43500 44700; B 3800 200 43300 44500; B 3800 200 43100 44300; B 3800 200 42900 44100; B 3800 200 42700 43900; B 3800 200 42500 43700; B 3800 200 42300 43500; B 3800 200 42100 43300; B 3800 200 41900 43100; B 3800 200 41700 42900; B 3800 200 41500 42700; B 3800 200 41300 42500; B 3800 200 41100 42300; B 3800 200 40900 42100; B 3800 200 40700 41900; B 3800 200 40500 41700; B 3800 200 40300 41500; B 3800 200 40100 41300; B 3800 200 39900 41100; B 3800 200 39700 40900; B 3800 200 39500 40700; B 3800 200 39300 40500; B 3800 200 39100 40300; B 3800 200 38900 40100; B 3800 200 38700 39900; B 3800 200 38500 39700; B 3800 200 38300 39500; B 3800 200 38100 39300; B 3800 200 37900 39100; B 3800 200 37700 38900; B 3800 200 37500 38700; B 3800 200 37300 38500; B 3800 200 37100 38300; B 3800 200 36900 38100; B 3800 200 36700 37900; B 3800 200 36500 37700; B 3800 200 36300 37500; B 3800 200 36100 37300; B 3800 200 35900 37100; B 3800 200 35700 36900; B 3800 200 35500 36700; B 3800 200 35300 36500; B 3800 200 35100 36300; B 3800 200 34900 36100; B 3800 200 34700 35900; B 3800 200 34500 35700; B 3800 200 34300 35500; B 3600 200 34200 35300; B 17800 200 26900 35100; B 17600 200 26800 34900; B 17400 200 26700 34700; B 17200 200 26600 34500; B 17000 200 26500 34300; B 16800 200 26400 34100; B 16600 200 26300 33900; B 16400 200 26200 33700; B 1600 800 18800 33200; B 16000 1600 26000 32000; B 1600 800 33200 30800; B 16000 1600 26000 29600; B 1600 800 18800 28400; B 16000 1600 26000 27200; B 1600 800 33200 26000; B 16000 1600 26000 24800; B 1600 800 18800 23600; B 16000 1600 26000 22400; B 1600 800 33200 21200; B 16400 200 25800 20700; B 16600 200 25700 20500; B 16800 200 25600 20300; B 17000 200 25500 20100; B 17200 200 25400 19900; B 17400 200 25300 19700; B 17600 200 25200 19500; B 17800 200 25100 19300; B 3600 200 17800 19100; B 3800 200 17700 18900; B 3800 200 17500 18700; B 3800 200 17300 18500; B 3800 200 17100 18300; B 3800 200 16900 18100; B 3800 200 16700 17900; B 3800 200 16500 17700; B 3800 200 16300 17500; B 3800 200 16100 17300; B 3800 200 15900 17100; B 3800 200 15700 16900; B 3800 200 15500 16700; B 3800 200 15300 16500; B 3800 200 15100 16300; B 3800 200 14900 16100; B 3800 200 14700 15900; B 3800 200 14500 15700; B 3800 200 14300 15500; B 3800 200 14100 15300; B 3800 200 13900 15100; B 3800 200 13700 14900; B 3800 200 13500 14700; B 3800 200 13300 14500; B 3800 200 13100 14300; B 3800 200 12900 14100; B 3800 200 12700 13900; B 3800 200 12500 13700; B 3800 200 12300 13500; B 3800 200 12100 13300; B 3800 200 11900 13100; B 3800 200 11700 12900; B 3800 200 11500 12700; B 3800 200 11300 12500; B 3800 200 11100 12300; B 3800 200 10900 12100; B 3800 200 10700 11900; B 3800 200 10500 11700; B 3800 200 10300 11500; B 3800 200 10100 11300; B 3800 200 9900 11100; B 3800 200 9700 10900; B 3800 200 9500 10700; B 3800 200 9300 10500; B 3800 200 9100 10300; B 3800 200 8900 10100; B 3800 200 8700 9900; B 3800 200 8500 9700; B 3800 200 8300 9500; B 3800 200 8100 9300; B 3800 200 7900 9100; B 3800 200 7700 8900; B 3800 200 7500 8700; B 3800 200 7300 8500; B 3800 200 7100 8300; B 3800 200 6900 8100; B 3800 200 6700 7900; B 3800 200 6500 7700; B 3800 200 6300 7500; B 3800 200 6100 7300; B 3800 200 5900 7100; B 3800 200 5700 6900; B 3800 200 5500 6700; B 3800 200 5300 6500; B 3800 200 5100 6300; B 3800 200 4900 6100; B 3800 200 4700 5900; B 3800 200 4500 5700; B 3800 200 4300 5500; B 3800 200 4100 5300; B 3800 200 3900 5100; B 3800 200 3700 4900; B 3800 200 3500 4700; B 3800 200 3300 4500; B 3800 200 3100 4300; B 3800 200 2900 4100; B 3800 200 2700 3900; B 3800 200 2500 3700; B 3800 200 2300 3500; B 3800 200 2100 3300; B 3800 200 1900 3100; B 3600 200 1800 2900; B 3400 200 1700 2700; B 3200 200 1600 2500; B 3000 200 1500 2300; B 2800 200 1400 2100; B 2600 200 1300 1900; B 2400 200 1200 1700; B 2200 200 1100 1500; B 2000 200 1000 1300; L CAA; B 42000 200 25000 49100; B 41800 200 24900 48900; B 41600 200 24800 48700; B 41400 200 24700 48500; B 41200 200 24600 48300; B 41000 200 24500 48100; B 40800 200 24400 47900; B 40600 200 24300 47700; B 40400 200 24200 47500; B 40200 200 24100 47300; B 2000 4000 5000 45200; B 32000 200 26000 47100; B 200 200 47900 47100; B 31600 200 26000 46900; B 400 200 47800 46900; B 31200 200 26000 46700; B 600 200 47700 46700; B 30800 200 26000 46500; B 800 200 47600 46500; B 30400 200 26000 46300; B 1000 200 47500 46300; B 30000 200 26000 46100; B 1200 200 47400 46100; B 29600 200 26000 45900; B 1400 200 47300 45900; B 29200 200 26000 45700; B 1600 200 47200 45700; B 28800 200 26000 45500; B 1800 200 47100 45500; B 28400 200 26000 45300; B 28000 200 26000 45100; B 27600 200 26000 44900; B 27200 200 26000 44700; B 26800 200 26000 44500; B 26400 200 26000 44300; B 26000 200 26000 44100; B 25600 200 26000 43900; B 25200 200 26000 43700; B 24800 200 26000 43500; B 24400 200 26000 43300; B 2000 2200 47000 44300; B 2200 200 5100 43100; B 24000 200 26000 43100; B 2200 200 46900 43100; B 2400 200 5200 42900; B 23600 200 26000 42900; B 2400 200 46800 42900; B 2600 200 5300 42700; B 23200 200 26000 42700; B 2600 200 46700 42700; B 2800 200 5400 42500; B 22800 200 26000 42500; B 2800 200 46600 42500; B 3000 200 5500 42300; B 22400 200 26000 42300; B 3000 200 46500 42300; B 3200 200 5600 42100; B 22000 200 26000 42100; B 3200 200 46400 42100; B 3400 200 5700 41900; B 21600 200 26000 41900; B 3400 200 46300 41900; B 3600 200 5800 41700; B 21200 200 26000 41700; B 3600 200 46200 41700; B 3800 200 5900 41500; B 20800 200 26000 41500; B 3800 200 46100 41500; B 4000 200 6000 41300; B 20400 200 26000 41300; B 4000 200 46000 41300; B 4200 200 6100 41100; B 20000 200 26000 41100; B 4200 200 45900 41100; B 4400 200 6200 40900; B 19600 200 26000 40900; B 4400 200 45800 40900; B 4600 200 6300 40700; B 19200 200 26000 40700; B 4600 200 45700 40700; B 4800 200 6400 40500; B 18800 200 26000 40500; B 4800 200 45600 40500; B 5000 200 6500 40300; B 18400 200 26000 40300; B 5000 200 45500 40300; B 5200 200 6600 40100; B 18000 200 26000 40100; B 5200 200 45400 40100; B 5400 200 6700 39900; B 17600 200 26000 39900; B 5400 200 45300 39900; B 5600 200 6800 39700; B 17200 200 26000 39700; B 5600 200 45200 39700; B 5800 200 6900 39500; B 16800 200 26000 39500; B 5800 200 45100 39500; B 6000 200 7000 39300; B 16400 200 26000 39300; B 6000 200 45000 39300; B 6200 200 7100 39100; B 16000 200 26000 39100; B 6200 200 44900 39100; B 6400 200 7200 38900; B 15600 200 26000 38900; B 6400 200 44800 38900; B 6600 200 7300 38700; B 15200 200 26000 38700; B 6600 200 44700 38700; B 6800 200 7400 38500; B 14800 200 26000 38500; B 6800 200 44600 38500; B 7000 200 7500 38300; B 14400 200 26000 38300; B 7000 200 44500 38300; B 7200 200 7600 38100; B 14000 200 26000 38100; B 7200 200 44400 38100; B 7400 200 7700 37900; B 13600 200 26000 37900; B 7400 200 44300 37900; B 7600 200 7800 37700; B 13200 200 26000 37700; B 7600 200 44200 37700; B 7800 200 7900 37500; B 12800 200 26000 37500; B 7800 200 44100 37500; B 8000 200 8000 37300; B 12400 200 26000 37300; B 8000 200 44000 37300; B 8200 200 8100 37100; B 8200 200 43900 37100; B 8400 200 8200 36900; B 8400 200 43800 36900; B 8600 200 8300 36700; B 8600 200 43700 36700; B 8800 200 8400 36500; B 8800 200 43600 36500; B 9000 200 8500 36300; B 9000 200 43500 36300; B 9200 200 8600 36100; B 9200 200 43400 36100; B 9400 200 8700 35900; B 9400 200 43300 35900; B 9600 200 8800 35700; B 9600 200 43200 35700; B 9800 200 8900 35500; B 9800 200 43100 35500; B 10000 200 9000 35300; B 10000 200 43000 35300; B 10200 200 9100 35100; B 10200 200 42900 35100; B 10400 200 9200 34900; B 10400 200 42800 34900; B 10600 200 9300 34700; B 10600 200 42700 34700; B 10800 200 9400 34500; B 10800 200 42600 34500; B 11000 200 9500 34300; B 11000 200 42500 34300; B 11200 200 9600 34100; B 11200 200 42400 34100; B 11400 200 9700 33900; B 11400 200 42300 33900; B 11600 200 9800 33700; B 11600 200 42200 33700; B 11800 200 9900 33500; B 11800 200 42100 33500; B 12000 12400 10000 27200; B 12000 12400 42000 27200; B 11800 200 9900 20900; B 11800 200 42100 20900; B 11600 200 9800 20700; B 11600 200 42200 20700; B 11400 200 9700 20500; B 11400 200 42300 20500; B 11200 200 9600 20300; B 11200 200 42400 20300; B 11000 200 9500 20100; B 11000 200 42500 20100; B 10800 200 9400 19900; B 10800 200 42600 19900; B 10600 200 9300 19700; B 10600 200 42700 19700; B 10400 200 9200 19500; B 10400 200 42800 19500; B 10200 200 9100 19300; B 10200 200 42900 19300; B 10000 200 9000 19100; B 10000 200 43000 19100; B 9800 200 8900 18900; B 9800 200 43100 18900; B 9600 200 8800 18700; B 9600 200 43200 18700; B 9400 200 8700 18500; B 9400 200 43300 18500; B 9200 200 8600 18300; B 9200 200 43400 18300; B 9000 200 8500 18100; B 9000 200 43500 18100; B 8800 200 8400 17900; B 8800 200 43600 17900; B 8600 200 8300 17700; B 8600 200 43700 17700; B 8400 200 8200 17500; B 8400 200 43800 17500; B 8200 200 8100 17300; B 8200 200 43900 17300; B 8000 200 8000 17100; B 12400 200 26000 17100; B 8000 200 44000 17100; B 7800 200 7900 16900; B 12800 200 26000 16900; B 7800 200 44100 16900; B 7600 200 7800 16700; B 13200 200 26000 16700; B 7600 200 44200 16700; B 7400 200 7700 16500; B 13600 200 26000 16500; B 7400 200 44300 16500; B 7200 200 7600 16300; B 14000 200 26000 16300; B 7200 200 44400 16300; B 7000 200 7500 16100; B 14400 200 26000 16100; B 7000 200 44500 16100; B 6800 200 7400 15900; B 14800 200 26000 15900; B 6800 200 44600 15900; B 6600 200 7300 15700; B 15200 200 26000 15700; B 6600 200 44700 15700; B 6400 200 7200 15500; B 15600 200 26000 15500; B 6400 200 44800 15500; B 6200 200 7100 15300; B 16000 200 26000 15300; B 6200 200 44900 15300; B 6000 200 7000 15100; B 16400 200 26000 15100; B 6000 200 45000 15100; B 5800 200 6900 14900; B 16800 200 26000 14900; B 5800 200 45100 14900; B 5600 200 6800 14700; B 17200 200 26000 14700; B 5600 200 45200 14700; B 5400 200 6700 14500; B 17600 200 26000 14500; B 5400 200 45300 14500; B 5200 200 6600 14300; B 18000 200 26000 14300; B 5200 200 45400 14300; B 5000 200 6500 14100; B 18400 200 26000 14100; B 5000 200 45500 14100; B 4800 200 6400 13900; B 18800 200 26000 13900; B 4800 200 45600 13900; B 4600 200 6300 13700; B 19200 200 26000 13700; B 4600 200 45700 13700; B 4400 200 6200 13500; B 19600 200 26000 13500; B 4400 200 45800 13500; B 4200 200 6100 13300; B 20000 200 26000 13300; B 4200 200 45900 13300; B 4000 200 6000 13100; B 20400 200 26000 13100; B 4000 200 46000 13100; B 3800 200 5900 12900; B 20800 200 26000 12900; B 3800 200 46100 12900; B 3600 200 5800 12700; B 21200 200 26000 12700; B 3600 200 46200 12700; B 3400 200 5700 12500; B 21600 200 26000 12500; B 3400 200 46300 12500; B 3200 200 5600 12300; B 22000 200 26000 12300; B 3200 200 46400 12300; B 3000 200 5500 12100; B 22400 200 26000 12100; B 3000 200 46500 12100; B 2800 200 5400 11900; B 22800 200 26000 11900; B 2800 200 46600 11900; B 2600 200 5300 11700; B 23200 200 26000 11700; B 2600 200 46700 11700; B 2400 200 5200 11500; B 23600 200 26000 11500; B 2400 200 46800 11500; B 2200 200 5100 11300; B 24000 200 26000 11300; B 2200 200 46900 11300; B 2000 2200 5000 10100; B 24400 200 26000 11100; B 24800 200 26000 10900; B 25200 200 26000 10700; B 25600 200 26000 10500; B 26000 200 26000 10300; B 26400 200 26000 10100; B 26800 200 26000 9900; B 27200 200 26000 9700; B 27600 200 26000 9500; B 28000 200 26000 9300; B 28400 200 26000 9100; B 1800 200 4900 8900; B 28800 200 26000 8900; B 1600 200 4800 8700; B 29200 200 26000 8700; B 1400 200 4700 8500; B 29600 200 26000 8500; B 1200 200 4600 8300; B 30000 200 26000 8300; B 1000 200 4500 8100; B 30400 200 26000 8100; B 800 200 4400 7900; B 30800 200 26000 7900; B 600 200 4300 7700; B 31200 200 26000 7700; B 400 200 4200 7500; B 31600 200 26000 7500; B 200 200 4100 7300; B 32000 200 26000 7300; B 2000 4000 47000 9200; B 40200 200 27900 7100; B 40400 200 27800 6900; B 40600 200 27700 6700; B 40800 200 27600 6500; B 41000 200 27500 6300; B 41200 200 27400 6100; B 41400 200 27300 5900; B 41600 200 27200 5700; B 41800 200 27100 5500; B 42000 200 27000 5300; L CVA; B 32000 200 26000 47100; B 31600 200 26000 46900; B 31200 200 26000 46700; B 30800 200 26000 46500; B 30400 200 26000 46300; B 30000 200 26000 46100; B 29600 200 26000 45900; B 29200 200 26000 45700; B 28800 200 26000 45500; B 28400 200 26000 45300; B 28000 200 26000 45100; B 27600 200 26000 44900; B 27200 200 26000 44700; B 26800 200 26000 44500; B 26400 200 26000 44300; B 26000 200 26000 44100; B 25600 200 26000 43900; B 25200 200 26000 43700; B 24800 200 26000 43500; B 24400 200 26000 43300; B 200 200 6100 43100; B 24000 200 26000 43100; B 200 200 45900 43100; B 400 200 6200 42900; B 23600 200 26000 42900; B 400 200 45800 42900; B 600 200 6300 42700; B 23200 200 26000 42700; B 600 200 45700 42700; B 800 200 6400 42500; B 22800 200 26000 42500; B 800 200 45600 42500; B 1000 200 6500 42300; B 22400 200 26000 42300; B 1000 200 45500 42300; B 1200 200 6600 42100; B 22000 200 26000 42100; B 1200 200 45400 42100; B 1400 200 6700 41900; B 21600 200 26000 41900; B 1400 200 45300 41900; B 1600 200 6800 41700; B 21200 200 26000 41700; B 1600 200 45200 41700; B 1800 200 6900 41500; B 20800 200 26000 41500; B 1800 200 45100 41500; B 2000 200 7000 41300; B 20400 200 26000 41300; B 2000 200 45000 41300; B 2200 200 7100 41100; B 20000 200 26000 41100; B 2200 200 44900 41100; B 2400 200 7200 40900; B 19600 200 26000 40900; B 2400 200 44800 40900; B 2600 200 7300 40700; B 19200 200 26000 40700; B 2600 200 44700 40700; B 2800 200 7400 40500; B 18800 200 26000 40500; B 2800 200 44600 40500; B 3000 200 7500 40300; B 18400 200 26000 40300; B 3000 200 44500 40300; B 3200 200 7600 40100; B 18000 200 26000 40100; B 3200 200 44400 40100; B 3400 200 7700 39900; B 17600 200 26000 39900; B 3400 200 44300 39900; B 3600 200 7800 39700; B 17200 200 26000 39700; B 3600 200 44200 39700; B 3800 200 7900 39500; B 16800 200 26000 39500; B 3800 200 44100 39500; B 4000 200 8000 39300; B 16400 200 26000 39300; B 4000 200 44000 39300; B 4200 200 8100 39100; B 16000 200 26000 39100; B 4200 200 43900 39100; B 4400 200 8200 38900; B 15600 200 26000 38900; B 4400 200 43800 38900; B 4600 200 8300 38700; B 15200 200 26000 38700; B 4600 200 43700 38700; B 4800 200 8400 38500; B 14800 200 26000 38500; B 4800 200 43600 38500; B 5000 200 8500 38300; B 14400 200 26000 38300; B 5000 200 43500 38300; B 5200 200 8600 38100; B 14000 200 26000 38100; B 5200 200 43400 38100; B 5400 200 8700 37900; B 13600 200 26000 37900; B 5400 200 43300 37900; B 5600 200 8800 37700; B 13200 200 26000 37700; B 5600 200 43200 37700; B 5800 200 8900 37500; B 12800 200 26000 37500; B 5800 200 43100 37500; B 6000 200 9000 37300; B 12400 200 26000 37300; B 6000 200 43000 37300; B 6200 200 9100 37100; B 6200 200 42900 37100; B 6400 200 9200 36900; B 6400 200 42800 36900; B 6600 200 9300 36700; B 6600 200 42700 36700; B 6800 200 9400 36500; B 6800 200 42600 36500; B 7000 200 9500 36300; B 7000 200 42500 36300; B 7200 200 9600 36100; B 7200 200 42400 36100; B 7400 200 9700 35900; B 7400 200 42300 35900; B 7600 200 9800 35700; B 7600 200 42200 35700; B 7800 200 9900 35500; B 7800 200 42100 35500; B 8000 200 10000 35300; B 8000 200 42000 35300; B 8200 200 10100 35100; B 8200 200 41900 35100; B 8400 200 10200 34900; B 8400 200 41800 34900; B 8600 200 10300 34700; B 8600 200 41700 34700; B 8800 200 10400 34500; B 8800 200 41600 34500; B 9000 200 10500 34300; B 9000 200 41500 34300; B 9200 200 10600 34100; B 9200 200 41400 34100; B 9400 200 10700 33900; B 9400 200 41300 33900; B 9600 200 10800 33700; B 9600 200 41200 33700; B 9800 200 10900 33500; B 9800 200 41100 33500; B 10000 12400 11000 27200; B 10000 12400 41000 27200; B 9800 200 10900 20900; B 9800 200 41100 20900; B 9600 200 10800 20700; B 9600 200 41200 20700; B 9400 200 10700 20500; B 9400 200 41300 20500; B 9200 200 10600 20300; B 9200 200 41400 20300; B 9000 200 10500 20100; B 9000 200 41500 20100; B 8800 200 10400 19900; B 8800 200 41600 19900; B 8600 200 10300 19700; B 8600 200 41700 19700; B 8400 200 10200 19500; B 8400 200 41800 19500; B 8200 200 10100 19300; B 8200 200 41900 19300; B 8000 200 10000 19100; B 8000 200 42000 19100; B 7800 200 9900 18900; B 7800 200 42100 18900; B 7600 200 9800 18700; B 7600 200 42200 18700; B 7400 200 9700 18500; B 7400 200 42300 18500; B 7200 200 9600 18300; B 7200 200 42400 18300; B 7000 200 9500 18100; B 7000 200 42500 18100; B 6800 200 9400 17900; B 6800 200 42600 17900; B 6600 200 9300 17700; B 6600 200 42700 17700; B 6400 200 9200 17500; B 6400 200 42800 17500; B 6200 200 9100 17300; B 6200 200 42900 17300; B 6000 200 9000 17100; B 12400 200 26000 17100; B 6000 200 43000 17100; B 5800 200 8900 16900; B 12800 200 26000 16900; B 5800 200 43100 16900; B 5600 200 8800 16700; B 13200 200 26000 16700; B 5600 200 43200 16700; B 5400 200 8700 16500; B 13600 200 26000 16500; B 5400 200 43300 16500; B 5200 200 8600 16300; B 14000 200 26000 16300; B 5200 200 43400 16300; B 5000 200 8500 16100; B 14400 200 26000 16100; B 5000 200 43500 16100; B 4800 200 8400 15900; B 14800 200 26000 15900; B 4800 200 43600 15900; B 4600 200 8300 15700; B 15200 200 26000 15700; B 4600 200 43700 15700; B 4400 200 8200 15500; B 15600 200 26000 15500; B 4400 200 43800 15500; B 4200 200 8100 15300; B 16000 200 26000 15300; B 4200 200 43900 15300; B 4000 200 8000 15100; B 16400 200 26000 15100; B 4000 200 44000 15100; B 3800 200 7900 14900; B 16800 200 26000 14900; B 3800 200 44100 14900; B 3600 200 7800 14700; B 17200 200 26000 14700; B 3600 200 44200 14700; B 3400 200 7700 14500; B 17600 200 26000 14500; B 3400 200 44300 14500; B 3200 200 7600 14300; B 18000 200 26000 14300; B 3200 200 44400 14300; B 3000 200 7500 14100; B 18400 200 26000 14100; B 3000 200 44500 14100; B 2800 200 7400 13900; B 18800 200 26000 13900; B 2800 200 44600 13900; B 2600 200 7300 13700; B 19200 200 26000 13700; B 2600 200 44700 13700; B 2400 200 7200 13500; B 19600 200 26000 13500; B 2400 200 44800 13500; B 2200 200 7100 13300; B 20000 200 26000 13300; B 2200 200 44900 13300; B 2000 200 7000 13100; B 20400 200 26000 13100; B 2000 200 45000 13100; B 1800 200 6900 12900; B 20800 200 26000 12900; B 1800 200 45100 12900; B 1600 200 6800 12700; B 21200 200 26000 12700; B 1600 200 45200 12700; B 1400 200 6700 12500; B 21600 200 26000 12500; B 1400 200 45300 12500; B 1200 200 6600 12300; B 22000 200 26000 12300; B 1200 200 45400 12300; B 1000 200 6500 12100; B 22400 200 26000 12100; B 1000 200 45500 12100; B 800 200 6400 11900; B 22800 200 26000 11900; B 800 200 45600 11900; B 600 200 6300 11700; B 23200 200 26000 11700; B 600 200 45700 11700; B 400 200 6200 11500; B 23600 200 26000 11500; B 400 200 45800 11500; B 200 200 6100 11300; B 24000 200 26000 11300; B 200 200 45900 11300; B 24400 200 26000 11100; B 24800 200 26000 10900; B 25200 200 26000 10700; B 25600 200 26000 10500; B 26000 200 26000 10300; B 26400 200 26000 10100; B 26800 200 26000 9900; B 27200 200 26000 9700; B 27600 200 26000 9500; B 28000 200 26000 9300; B 28400 200 26000 9100; B 28800 200 26000 8900; B 29200 200 26000 8700; B 29600 200 26000 8500; B 30000 200 26000 8300; B 30400 200 26000 8100; B 30800 200 26000 7900; B 31200 200 26000 7700; B 31600 200 26000 7500; B 32000 200 26000 7300; L CCA; B 32000 200 26000 47100; B 31600 200 26000 46900; B 31200 200 26000 46700; B 30800 200 26000 46500; B 30400 200 26000 46300; B 30000 200 26000 46100; B 29600 200 26000 45900; B 29200 200 26000 45700; B 28800 200 26000 45500; B 28400 200 26000 45300; B 28000 200 26000 45100; B 27600 200 26000 44900; B 27200 200 26000 44700; B 26800 200 26000 44500; B 26400 200 26000 44300; B 26000 200 26000 44100; B 25600 200 26000 43900; B 25200 200 26000 43700; B 24800 200 26000 43500; B 24400 200 26000 43300; B 200 200 6100 43100; B 24000 200 26000 43100; B 200 200 45900 43100; B 400 200 6200 42900; B 23600 200 26000 42900; B 400 200 45800 42900; B 600 200 6300 42700; B 23200 200 26000 42700; B 600 200 45700 42700; B 800 200 6400 42500; B 22800 200 26000 42500; B 800 200 45600 42500; B 1000 200 6500 42300; B 22400 200 26000 42300; B 1000 200 45500 42300; B 1200 200 6600 42100; B 22000 200 26000 42100; B 1200 200 45400 42100; B 1400 200 6700 41900; B 21600 200 26000 41900; B 1400 200 45300 41900; B 1600 200 6800 41700; B 21200 200 26000 41700; B 1600 200 45200 41700; B 1800 200 6900 41500; B 20800 200 26000 41500; B 1800 200 45100 41500; B 2000 200 7000 41300; B 20400 200 26000 41300; B 2000 200 45000 41300; B 2200 200 7100 41100; B 20000 200 26000 41100; B 2200 200 44900 41100; B 2400 200 7200 40900; B 19600 200 26000 40900; B 2400 200 44800 40900; B 2600 200 7300 40700; B 19200 200 26000 40700; B 2600 200 44700 40700; B 2800 200 7400 40500; B 18800 200 26000 40500; B 2800 200 44600 40500; B 3000 200 7500 40300; B 18400 200 26000 40300; B 3000 200 44500 40300; B 3200 200 7600 40100; B 18000 200 26000 40100; B 3200 200 44400 40100; B 3400 200 7700 39900; B 17600 200 26000 39900; B 3400 200 44300 39900; B 3600 200 7800 39700; B 17200 200 26000 39700; B 3600 200 44200 39700; B 3800 200 7900 39500; B 16800 200 26000 39500; B 3800 200 44100 39500; B 4000 200 8000 39300; B 16400 200 26000 39300; B 4000 200 44000 39300; B 4200 200 8100 39100; B 16000 200 26000 39100; B 4200 200 43900 39100; B 4400 200 8200 38900; B 15600 200 26000 38900; B 4400 200 43800 38900; B 4600 200 8300 38700; B 15200 200 26000 38700; B 4600 200 43700 38700; B 4800 200 8400 38500; B 14800 200 26000 38500; B 4800 200 43600 38500; B 5000 200 8500 38300; B 14400 200 26000 38300; B 5000 200 43500 38300; B 5200 200 8600 38100; B 14000 200 26000 38100; B 5200 200 43400 38100; B 5400 200 8700 37900; B 13600 200 26000 37900; B 5400 200 43300 37900; B 5600 200 8800 37700; B 13200 200 26000 37700; B 5600 200 43200 37700; B 5800 200 8900 37500; B 12800 200 26000 37500; B 5800 200 43100 37500; B 6000 200 9000 37300; B 12400 200 26000 37300; B 6000 200 43000 37300; B 6200 200 9100 37100; B 6200 200 42900 37100; B 6400 200 9200 36900; B 6400 200 42800 36900; B 6600 200 9300 36700; B 6600 200 42700 36700; B 6800 200 9400 36500; B 6800 200 42600 36500; B 7000 200 9500 36300; B 7000 200 42500 36300; B 7200 200 9600 36100; B 7200 200 42400 36100; B 7400 200 9700 35900; B 7400 200 42300 35900; B 7600 200 9800 35700; B 7600 200 42200 35700; B 7800 200 9900 35500; B 7800 200 42100 35500; B 8000 200 10000 35300; B 8000 200 42000 35300; B 8200 200 10100 35100; B 8200 200 41900 35100; B 8400 200 10200 34900; B 8400 200 41800 34900; B 8600 200 10300 34700; B 8600 200 41700 34700; B 8800 200 10400 34500; B 8800 200 41600 34500; B 9000 200 10500 34300; B 9000 200 41500 34300; B 9200 200 10600 34100; B 9200 200 41400 34100; B 9400 200 10700 33900; B 9400 200 41300 33900; B 9600 200 10800 33700; B 9600 200 41200 33700; B 9800 200 10900 33500; B 9800 200 41100 33500; B 10000 12400 11000 27200; B 10000 12400 41000 27200; B 9800 200 10900 20900; B 9800 200 41100 20900; B 9600 200 10800 20700; B 9600 200 41200 20700; B 9400 200 10700 20500; B 9400 200 41300 20500; B 9200 200 10600 20300; B 9200 200 41400 20300; B 9000 200 10500 20100; B 9000 200 41500 20100; B 8800 200 10400 19900; B 8800 200 41600 19900; B 8600 200 10300 19700; B 8600 200 41700 19700; B 8400 200 10200 19500; B 8400 200 41800 19500; B 8200 200 10100 19300; B 8200 200 41900 19300; B 8000 200 10000 19100; B 8000 200 42000 19100; B 7800 200 9900 18900; B 7800 200 42100 18900; B 7600 200 9800 18700; B 7600 200 42200 18700; B 7400 200 9700 18500; B 7400 200 42300 18500; B 7200 200 9600 18300; B 7200 200 42400 18300; B 7000 200 9500 18100; B 7000 200 42500 18100; B 6800 200 9400 17900; B 6800 200 42600 17900; B 6600 200 9300 17700; B 6600 200 42700 17700; B 6400 200 9200 17500; B 6400 200 42800 17500; B 6200 200 9100 17300; B 6200 200 42900 17300; B 6000 200 9000 17100; B 12400 200 26000 17100; B 6000 200 43000 17100; B 5800 200 8900 16900; B 12800 200 26000 16900; B 5800 200 43100 16900; B 5600 200 8800 16700; B 13200 200 26000 16700; B 5600 200 43200 16700; B 5400 200 8700 16500; B 13600 200 26000 16500; B 5400 200 43300 16500; B 5200 200 8600 16300; B 14000 200 26000 16300; B 5200 200 43400 16300; B 5000 200 8500 16100; B 14400 200 26000 16100; B 5000 200 43500 16100; B 4800 200 8400 15900; B 14800 200 26000 15900; B 4800 200 43600 15900; B 4600 200 8300 15700; B 15200 200 26000 15700; B 4600 200 43700 15700; B 4400 200 8200 15500; B 15600 200 26000 15500; B 4400 200 43800 15500; B 4200 200 8100 15300; B 16000 200 26000 15300; B 4200 200 43900 15300; B 4000 200 8000 15100; B 16400 200 26000 15100; B 4000 200 44000 15100; B 3800 200 7900 14900; B 16800 200 26000 14900; B 3800 200 44100 14900; B 3600 200 7800 14700; B 17200 200 26000 14700; B 3600 200 44200 14700; B 3400 200 7700 14500; B 17600 200 26000 14500; B 3400 200 44300 14500; B 3200 200 7600 14300; B 18000 200 26000 14300; B 3200 200 44400 14300; B 3000 200 7500 14100; B 18400 200 26000 14100; B 3000 200 44500 14100; B 2800 200 7400 13900; B 18800 200 26000 13900; B 2800 200 44600 13900; B 2600 200 7300 13700; B 19200 200 26000 13700; B 2600 200 44700 13700; B 2400 200 7200 13500; B 19600 200 26000 13500; B 2400 200 44800 13500; B 2200 200 7100 13300; B 20000 200 26000 13300; B 2200 200 44900 13300; B 2000 200 7000 13100; B 20400 200 26000 13100; B 2000 200 45000 13100; B 1800 200 6900 12900; B 20800 200 26000 12900; B 1800 200 45100 12900; B 1600 200 6800 12700; B 21200 200 26000 12700; B 1600 200 45200 12700; B 1400 200 6700 12500; B 21600 200 26000 12500; B 1400 200 45300 12500; B 1200 200 6600 12300; B 22000 200 26000 12300; B 1200 200 45400 12300; B 1000 200 6500 12100; B 22400 200 26000 12100; B 1000 200 45500 12100; B 800 200 6400 11900; B 22800 200 26000 11900; B 800 200 45600 11900; B 600 200 6300 11700; B 23200 200 26000 11700; B 600 200 45700 11700; B 400 200 6200 11500; B 23600 200 26000 11500; B 400 200 45800 11500; B 200 200 6100 11300; B 24000 200 26000 11300; B 200 200 45900 11300; B 24400 200 26000 11100; B 24800 200 26000 10900; B 25200 200 26000 10700; B 25600 200 26000 10500; B 26000 200 26000 10300; B 26400 200 26000 10100; B 26800 200 26000 9900; B 27200 200 26000 9700; B 27600 200 26000 9500; B 28000 200 26000 9300; B 28400 200 26000 9100; B 28800 200 26000 8900; B 29200 200 26000 8700; B 29600 200 26000 8500; B 30000 200 26000 8300; B 30400 200 26000 8100; B 30800 200 26000 7900; B 31200 200 26000 7700; B 31600 200 26000 7500; B 32000 200 26000 7300; L CCP; B 400 400 51000 52200; B 400 400 1000 2200; L CSP; B 42800 1000 25000 49100; B 42600 200 24900 48500; B 42400 200 24800 48300; B 42200 200 24700 48100; B 42000 200 24600 47900; B 41800 200 24500 47700; B 41600 200 24400 47500; B 1000 200 47900 47500; B 41400 200 24300 47300; B 1200 200 47800 47300; B 41200 200 24200 47100; B 1400 200 47700 47100; B 41000 200 24100 46900; B 1600 200 47600 46900; B 2800 38200 5000 27700; B 1800 200 47500 46700; B 2000 200 47400 46500; B 2200 200 47300 46300; B 2400 200 47200 46100; B 2600 200 47100 45900; B 2600 200 4900 8500; B 2400 200 4800 8300; B 2200 200 4700 8100; B 2000 200 4600 7900; B 1800 200 4500 7700; B 2800 38200 47000 26700; B 1600 200 4400 7500; B 41000 200 27900 7500; B 1400 200 4300 7300; B 41200 200 27800 7300; B 1200 200 4200 7100; B 41400 200 27700 7100; B 1000 200 4100 6900; B 41600 200 27600 6900; B 41800 200 27500 6700; B 42000 200 27400 6500; B 42200 200 27300 6300; B 42400 200 27200 6100; B 42600 200 27100 5900; B 42800 1000 27000 5300; L COG; B 32000 200 26000 47100; B 31600 200 26000 46900; B 31200 200 26000 46700; B 30800 200 26000 46500; B 30400 200 26000 46300; B 30000 200 26000 46100; B 29600 200 26000 45900; B 29200 200 26000 45700; B 28800 200 26000 45500; B 28400 200 26000 45300; B 28000 200 26000 45100; B 27600 200 26000 44900; B 27200 200 26000 44700; B 26800 200 26000 44500; B 26400 200 26000 44300; B 26000 200 26000 44100; B 25600 200 26000 43900; B 25200 200 26000 43700; B 24800 200 26000 43500; B 24400 200 26000 43300; B 200 200 6100 43100; B 24000 200 26000 43100; B 200 200 45900 43100; B 400 200 6200 42900; B 23600 200 26000 42900; B 400 200 45800 42900; B 600 200 6300 42700; B 23200 200 26000 42700; B 600 200 45700 42700; B 800 200 6400 42500; B 22800 200 26000 42500; B 800 200 45600 42500; B 1000 200 6500 42300; B 22400 200 26000 42300; B 1000 200 45500 42300; B 1200 200 6600 42100; B 22000 200 26000 42100; B 1200 200 45400 42100; B 1400 200 6700 41900; B 21600 200 26000 41900; B 1400 200 45300 41900; B 1600 200 6800 41700; B 21200 200 26000 41700; B 1600 200 45200 41700; B 1800 200 6900 41500; B 20800 200 26000 41500; B 1800 200 45100 41500; B 2000 200 7000 41300; B 20400 200 26000 41300; B 2000 200 45000 41300; B 2200 200 7100 41100; B 20000 200 26000 41100; B 2200 200 44900 41100; B 2400 200 7200 40900; B 19600 200 26000 40900; B 2400 200 44800 40900; B 2600 200 7300 40700; B 19200 200 26000 40700; B 2600 200 44700 40700; B 2800 200 7400 40500; B 18800 200 26000 40500; B 2800 200 44600 40500; B 3000 200 7500 40300; B 18400 200 26000 40300; B 3000 200 44500 40300; B 3200 200 7600 40100; B 18000 200 26000 40100; B 3200 200 44400 40100; B 3400 200 7700 39900; B 17600 200 26000 39900; B 3400 200 44300 39900; B 3600 200 7800 39700; B 17200 200 26000 39700; B 3600 200 44200 39700; B 3800 200 7900 39500; B 16800 200 26000 39500; B 3800 200 44100 39500; B 4000 200 8000 39300; B 16400 200 26000 39300; B 4000 200 44000 39300; B 4200 200 8100 39100; B 16000 200 26000 39100; B 4200 200 43900 39100; B 4400 200 8200 38900; B 15600 200 26000 38900; B 4400 200 43800 38900; B 4600 200 8300 38700; B 15200 200 26000 38700; B 4600 200 43700 38700; B 4800 200 8400 38500; B 14800 200 26000 38500; B 4800 200 43600 38500; B 5000 200 8500 38300; B 14400 200 26000 38300; B 5000 200 43500 38300; B 5200 200 8600 38100; B 14000 200 26000 38100; B 5200 200 43400 38100; B 5400 200 8700 37900; B 13600 200 26000 37900; B 5400 200 43300 37900; B 5600 200 8800 37700; B 13200 200 26000 37700; B 5600 200 43200 37700; B 5800 200 8900 37500; B 12800 200 26000 37500; B 5800 200 43100 37500; B 6000 200 9000 37300; B 12400 200 26000 37300; B 6000 200 43000 37300; B 6200 200 9100 37100; B 6200 200 42900 37100; B 6400 200 9200 36900; B 6400 200 42800 36900; B 6600 200 9300 36700; B 6600 200 42700 36700; B 6800 200 9400 36500; B 6800 200 42600 36500; B 7000 200 9500 36300; B 7000 200 42500 36300; B 7200 200 9600 36100; B 7200 200 42400 36100; B 7400 200 9700 35900; B 7400 200 42300 35900; B 7600 200 9800 35700; B 7600 200 42200 35700; B 7800 200 9900 35500; B 7800 200 42100 35500; B 8000 200 10000 35300; B 8000 200 42000 35300; B 8200 200 10100 35100; B 8200 200 41900 35100; B 8400 200 10200 34900; B 8400 200 41800 34900; B 8600 200 10300 34700; B 8600 200 41700 34700; B 8800 200 10400 34500; B 8800 200 41600 34500; B 9000 200 10500 34300; B 9000 200 41500 34300; B 9200 200 10600 34100; B 9200 200 41400 34100; B 9400 200 10700 33900; B 9400 200 41300 33900; B 9600 200 10800 33700; B 9600 200 41200 33700; B 9800 200 10900 33500; B 9800 200 41100 33500; B 10000 12400 11000 27200; B 10000 12400 41000 27200; B 9800 200 10900 20900; B 9800 200 41100 20900; B 9600 200 10800 20700; B 9600 200 41200 20700; B 9400 200 10700 20500; B 9400 200 41300 20500; B 9200 200 10600 20300; B 9200 200 41400 20300; B 9000 200 10500 20100; B 9000 200 41500 20100; B 8800 200 10400 19900; B 8800 200 41600 19900; B 8600 200 10300 19700; B 8600 200 41700 19700; B 8400 200 10200 19500; B 8400 200 41800 19500; B 8200 200 10100 19300; B 8200 200 41900 19300; B 8000 200 10000 19100; B 8000 200 42000 19100; B 7800 200 9900 18900; B 7800 200 42100 18900; B 7600 200 9800 18700; B 7600 200 42200 18700; B 7400 200 9700 18500; B 7400 200 42300 18500; B 7200 200 9600 18300; B 7200 200 42400 18300; B 7000 200 9500 18100; B 7000 200 42500 18100; B 6800 200 9400 17900; B 6800 200 42600 17900; B 6600 200 9300 17700; B 6600 200 42700 17700; B 6400 200 9200 17500; B 6400 200 42800 17500; B 6200 200 9100 17300; B 6200 200 42900 17300; B 6000 200 9000 17100; B 12400 200 26000 17100; B 6000 200 43000 17100; B 5800 200 8900 16900; B 12800 200 26000 16900; B 5800 200 43100 16900; B 5600 200 8800 16700; B 13200 200 26000 16700; B 5600 200 43200 16700; B 5400 200 8700 16500; B 13600 200 26000 16500; B 5400 200 43300 16500; B 5200 200 8600 16300; B 14000 200 26000 16300; B 5200 200 43400 16300; B 5000 200 8500 16100; B 14400 200 26000 16100; B 5000 200 43500 16100; B 4800 200 8400 15900; B 14800 200 26000 15900; B 4800 200 43600 15900; B 4600 200 8300 15700; B 15200 200 26000 15700; B 4600 200 43700 15700; B 4400 200 8200 15500; B 15600 200 26000 15500; B 4400 200 43800 15500; B 4200 200 8100 15300; B 16000 200 26000 15300; B 4200 200 43900 15300; B 4000 200 8000 15100; B 16400 200 26000 15100; B 4000 200 44000 15100; B 3800 200 7900 14900; B 16800 200 26000 14900; B 3800 200 44100 14900; B 3600 200 7800 14700; B 17200 200 26000 14700; B 3600 200 44200 14700; B 3400 200 7700 14500; B 17600 200 26000 14500; B 3400 200 44300 14500; B 3200 200 7600 14300; B 18000 200 26000 14300; B 3200 200 44400 14300; B 3000 200 7500 14100; B 18400 200 26000 14100; B 3000 200 44500 14100; B 2800 200 7400 13900; B 18800 200 26000 13900; B 2800 200 44600 13900; B 2600 200 7300 13700; B 19200 200 26000 13700; B 2600 200 44700 13700; B 2400 200 7200 13500; B 19600 200 26000 13500; B 2400 200 44800 13500; B 2200 200 7100 13300; B 20000 200 26000 13300; B 2200 200 44900 13300; B 2000 200 7000 13100; B 20400 200 26000 13100; B 2000 200 45000 13100; B 1800 200 6900 12900; B 20800 200 26000 12900; B 1800 200 45100 12900; B 1600 200 6800 12700; B 21200 200 26000 12700; B 1600 200 45200 12700; B 1400 200 6700 12500; B 21600 200 26000 12500; B 1400 200 45300 12500; B 1200 200 6600 12300; B 22000 200 26000 12300; B 1200 200 45400 12300; B 1000 200 6500 12100; B 22400 200 26000 12100; B 1000 200 45500 12100; B 800 200 6400 11900; B 22800 200 26000 11900; B 800 200 45600 11900; B 600 200 6300 11700; B 23200 200 26000 11700; B 600 200 45700 11700; B 400 200 6200 11500; B 23600 200 26000 11500; B 400 200 45800 11500; B 200 200 6100 11300; B 24000 200 26000 11300; B 200 200 45900 11300; B 24400 200 26000 11100; B 24800 200 26000 10900; B 25200 200 26000 10700; B 25600 200 26000 10500; B 26000 200 26000 10300; B 26400 200 26000 10100; B 26800 200 26000 9900; B 27200 200 26000 9700; B 27600 200 26000 9500; B 28000 200 26000 9300; B 28400 200 26000 9100; B 28800 200 26000 8900; B 29200 200 26000 8700; B 29600 200 26000 8500; B 30000 200 26000 8300; B 30400 200 26000 8100; B 30800 200 26000 7900; B 31200 200 26000 7700; B 31600 200 26000 7500; B 32000 200 26000 7300; L COP; B 32000 200 26000 47100; B 31600 200 26000 46900; B 31200 200 26000 46700; B 30800 200 26000 46500; B 30400 200 26000 46300; B 30000 200 26000 46100; B 29600 200 26000 45900; B 29200 200 26000 45700; B 28800 200 26000 45500; B 28400 200 26000 45300; B 28000 200 26000 45100; B 27600 200 26000 44900; B 27200 200 26000 44700; B 26800 200 26000 44500; B 26400 200 26000 44300; B 26000 200 26000 44100; B 25600 200 26000 43900; B 25200 200 26000 43700; B 24800 200 26000 43500; B 24400 200 26000 43300; B 200 200 6100 43100; B 24000 200 26000 43100; B 200 200 45900 43100; B 400 200 6200 42900; B 23600 200 26000 42900; B 400 200 45800 42900; B 600 200 6300 42700; B 23200 200 26000 42700; B 600 200 45700 42700; B 800 200 6400 42500; B 22800 200 26000 42500; B 800 200 45600 42500; B 1000 200 6500 42300; B 22400 200 26000 42300; B 1000 200 45500 42300; B 1200 200 6600 42100; B 22000 200 26000 42100; B 1200 200 45400 42100; B 1400 200 6700 41900; B 21600 200 26000 41900; B 1400 200 45300 41900; B 1600 200 6800 41700; B 21200 200 26000 41700; B 1600 200 45200 41700; B 1800 200 6900 41500; B 20800 200 26000 41500; B 1800 200 45100 41500; B 2000 200 7000 41300; B 20400 200 26000 41300; B 2000 200 45000 41300; B 2200 200 7100 41100; B 20000 200 26000 41100; B 2200 200 44900 41100; B 2400 200 7200 40900; B 19600 200 26000 40900; B 2400 200 44800 40900; B 2600 200 7300 40700; B 19200 200 26000 40700; B 2600 200 44700 40700; B 2800 200 7400 40500; B 18800 200 26000 40500; B 2800 200 44600 40500; B 3000 200 7500 40300; B 18400 200 26000 40300; B 3000 200 44500 40300; B 3200 200 7600 40100; B 18000 200 26000 40100; B 3200 200 44400 40100; B 3400 200 7700 39900; B 17600 200 26000 39900; B 3400 200 44300 39900; B 3600 200 7800 39700; B 17200 200 26000 39700; B 3600 200 44200 39700; B 3800 200 7900 39500; B 16800 200 26000 39500; B 3800 200 44100 39500; B 4000 200 8000 39300; B 16400 200 26000 39300; B 4000 200 44000 39300; B 4200 200 8100 39100; B 16000 200 26000 39100; B 4200 200 43900 39100; B 4400 200 8200 38900; B 15600 200 26000 38900; B 4400 200 43800 38900; B 4600 200 8300 38700; B 15200 200 26000 38700; B 4600 200 43700 38700; B 4800 200 8400 38500; B 14800 200 26000 38500; B 4800 200 43600 38500; B 5000 200 8500 38300; B 14400 200 26000 38300; B 5000 200 43500 38300; B 5200 200 8600 38100; B 14000 200 26000 38100; B 5200 200 43400 38100; B 5400 200 8700 37900; B 13600 200 26000 37900; B 5400 200 43300 37900; B 5600 200 8800 37700; B 13200 200 26000 37700; B 5600 200 43200 37700; B 5800 200 8900 37500; B 12800 200 26000 37500; B 5800 200 43100 37500; B 6000 200 9000 37300; B 12400 200 26000 37300; B 6000 200 43000 37300; B 6200 200 9100 37100; B 6200 200 42900 37100; B 6400 200 9200 36900; B 6400 200 42800 36900; B 6600 200 9300 36700; B 6600 200 42700 36700; B 6800 200 9400 36500; B 6800 200 42600 36500; B 7000 200 9500 36300; B 7000 200 42500 36300; B 7200 200 9600 36100; B 7200 200 42400 36100; B 7400 200 9700 35900; B 7400 200 42300 35900; B 7600 200 9800 35700; B 7600 200 42200 35700; B 7800 200 9900 35500; B 7800 200 42100 35500; B 8000 200 10000 35300; B 8000 200 42000 35300; B 8200 200 10100 35100; B 8200 200 41900 35100; B 8400 200 10200 34900; B 8400 200 41800 34900; B 8600 200 10300 34700; B 8600 200 41700 34700; B 8800 200 10400 34500; B 8800 200 41600 34500; B 9000 200 10500 34300; B 9000 200 41500 34300; B 9200 200 10600 34100; B 9200 200 41400 34100; B 9400 200 10700 33900; B 9400 200 41300 33900; B 9600 200 10800 33700; B 9600 200 41200 33700; B 9800 200 10900 33500; B 9800 200 41100 33500; B 10000 12400 11000 27200; B 10000 12400 41000 27200; B 9800 200 10900 20900; B 9800 200 41100 20900; B 9600 200 10800 20700; B 9600 200 41200 20700; B 9400 200 10700 20500; B 9400 200 41300 20500; B 9200 200 10600 20300; B 9200 200 41400 20300; B 9000 200 10500 20100; B 9000 200 41500 20100; B 8800 200 10400 19900; B 8800 200 41600 19900; B 8600 200 10300 19700; B 8600 200 41700 19700; B 8400 200 10200 19500; B 8400 200 41800 19500; B 8200 200 10100 19300; B 8200 200 41900 19300; B 8000 200 10000 19100; B 8000 200 42000 19100; B 7800 200 9900 18900; B 7800 200 42100 18900; B 7600 200 9800 18700; B 7600 200 42200 18700; B 7400 200 9700 18500; B 7400 200 42300 18500; B 7200 200 9600 18300; B 7200 200 42400 18300; B 7000 200 9500 18100; B 7000 200 42500 18100; B 6800 200 9400 17900; B 6800 200 42600 17900; B 6600 200 9300 17700; B 6600 200 42700 17700; B 6400 200 9200 17500; B 6400 200 42800 17500; B 6200 200 9100 17300; B 6200 200 42900 17300; B 6000 200 9000 17100; B 12400 200 26000 17100; B 6000 200 43000 17100; B 5800 200 8900 16900; B 12800 200 26000 16900; B 5800 200 43100 16900; B 5600 200 8800 16700; B 13200 200 26000 16700; B 5600 200 43200 16700; B 5400 200 8700 16500; B 13600 200 26000 16500; B 5400 200 43300 16500; B 5200 200 8600 16300; B 14000 200 26000 16300; B 5200 200 43400 16300; B 5000 200 8500 16100; B 14400 200 26000 16100; B 5000 200 43500 16100; B 4800 200 8400 15900; B 14800 200 26000 15900; B 4800 200 43600 15900; B 4600 200 8300 15700; B 15200 200 26000 15700; B 4600 200 43700 15700; B 4400 200 8200 15500; B 15600 200 26000 15500; B 4400 200 43800 15500; B 4200 200 8100 15300; B 16000 200 26000 15300; B 4200 200 43900 15300; B 4000 200 8000 15100; B 16400 200 26000 15100; B 4000 200 44000 15100; B 3800 200 7900 14900; B 16800 200 26000 14900; B 3800 200 44100 14900; B 3600 200 7800 14700; B 17200 200 26000 14700; B 3600 200 44200 14700; B 3400 200 7700 14500; B 17600 200 26000 14500; B 3400 200 44300 14500; B 3200 200 7600 14300; B 18000 200 26000 14300; B 3200 200 44400 14300; B 3000 200 7500 14100; B 18400 200 26000 14100; B 3000 200 44500 14100; B 2800 200 7400 13900; B 18800 200 26000 13900; B 2800 200 44600 13900; B 2600 200 7300 13700; B 19200 200 26000 13700; B 2600 200 44700 13700; B 2400 200 7200 13500; B 19600 200 26000 13500; B 2400 200 44800 13500; B 2200 200 7100 13300; B 20000 200 26000 13300; B 2200 200 44900 13300; B 2000 200 7000 13100; B 20400 200 26000 13100; B 2000 200 45000 13100; B 1800 200 6900 12900; B 20800 200 26000 12900; B 1800 200 45100 12900; B 1600 200 6800 12700; B 21200 200 26000 12700; B 1600 200 45200 12700; B 1400 200 6700 12500; B 21600 200 26000 12500; B 1400 200 45300 12500; B 1200 200 6600 12300; B 22000 200 26000 12300; B 1200 200 45400 12300; B 1000 200 6500 12100; B 22400 200 26000 12100; B 1000 200 45500 12100; B 800 200 6400 11900; B 22800 200 26000 11900; B 800 200 45600 11900; B 600 200 6300 11700; B 23200 200 26000 11700; B 600 200 45700 11700; B 400 200 6200 11500; B 23600 200 26000 11500; B 400 200 45800 11500; B 200 200 6100 11300; B 24000 200 26000 11300; B 200 200 45900 11300; B 24400 200 26000 11100; B 24800 200 26000 10900; B 25200 200 26000 10700; B 25600 200 26000 10500; B 26000 200 26000 10300; B 26400 200 26000 10100; B 26800 200 26000 9900; B 27200 200 26000 9700; B 27600 200 26000 9500; B 28000 200 26000 9300; B 28400 200 26000 9100; B 28800 200 26000 8900; B 29200 200 26000 8700; B 29600 200 26000 8500; B 30000 200 26000 8300; B 30400 200 26000 8100; B 30800 200 26000 7900; B 31200 200 26000 7700; B 31600 200 26000 7500; B 32000 200 26000 7300; L CPS; B 42000 200 25000 49100; B 41800 200 24900 48900; B 41600 200 24800 48700; B 41400 200 24700 48500; B 41200 200 24600 48300; B 41000 200 24500 48100; B 40800 200 24400 47900; B 40600 200 24300 47700; B 40400 200 24200 47500; B 40200 200 24100 47300; B 2000 38200 5000 28100; B 200 200 47900 47100; B 400 200 47800 46900; B 600 200 47700 46700; B 800 200 47600 46500; B 1000 200 47500 46300; B 1200 200 47400 46100; B 1400 200 47300 45900; B 1600 200 47200 45700; B 1800 200 47100 45500; B 1800 200 4900 8900; B 1600 200 4800 8700; B 1400 200 4700 8500; B 1200 200 4600 8300; B 1000 200 4500 8100; B 800 200 4400 7900; B 600 200 4300 7700; B 400 200 4200 7500; B 200 200 4100 7300; B 2000 38200 47000 26300; B 40200 200 27900 7100; B 40400 200 27800 6900; B 40600 200 27700 6700; B 40800 200 27600 6500; B 41000 200 27500 6300; B 41200 200 27400 6100; B 41400 200 27300 5900; B 41600 200 27200 5700; B 41800 200 27100 5500; B 42000 200 27000 5300; DF; C 1; End magic-8.0.210/scmos/examples/nist-mems-library/memslib.cif0000644000175000001440000004704110751423606022117 0ustar timusersDS 1 1 2; 9 memslib; L CMF; B 10000 2000 26000 43000; B 2000 8000 22000 38000; B 2000 8000 26000 38000; B 2000 8000 30000 38000; B 6000 2000 36000 43000; B 10000 2000 46000 43000; B 2000 2000 34000 41000; B 4000 2000 35000 39000; B 2000 2000 34000 37000; B 6000 2000 36000 35000; B 2000 8000 42000 38000; B 2000 8000 46000 38000; B 2000 8000 50000 38000; B 6000 2000 56000 43000; B 2000 2000 54000 41000; B 6000 2000 56000 39000; B 2000 2000 58000 37000; B 6000 2000 56000 35000; B 2000 8000 70000 40000; B 6000 2000 80000 43000; B 6000 2000 88000 43000; B 2000 6000 80000 39000; B 2000 2000 86000 41000; B 2000 2000 90000 41000; B 6000 2000 88000 39000; B 2000 2000 86000 37000; B 2000 2000 90000 37000; B 6000 2000 72000 35000; B 6000 2000 80000 35000; B 6000 2000 88000 35000; B 5000 1000 95500 43500; B 6000 1000 96000 42500; B 2000 2000 94000 41000; B 2000 2000 98000 41000; B 6000 2000 104000 43000; B 2000 2000 102000 41000; B 2000 2000 106000 41000; B 5000 2000 95500 39000; B 6000 2000 104000 39000; B 2000 4000 94000 36000; B 2000 4000 98000 36000; B 2000 4000 102000 36000; B 2000 4000 106000 36000; B 5000 1000 111500 43500; B 6000 1000 112000 42500; B 2000 2000 110000 41000; B 2000 2000 114000 41000; B 2000 4000 118000 42000; B 2000 4000 122000 42000; B 5000 2000 111500 39000; B 6000 2000 120000 39000; B 2000 4000 110000 36000; B 2000 4000 114000 36000; B 2000 4000 120000 36000; L CPG; B 4000 200 16400 98500; B 4200 200 16300 98300; B 4600 200 16300 98100; B 4800 200 16200 97900; B 5200 200 16200 97700; B 5400 200 16100 97500; B 5800 200 16100 97300; B 6000 200 16000 97100; B 6400 200 16000 96900; B 6600 200 15900 96700; B 7000 200 15900 96500; B 7200 200 15800 96300; B 7600 200 15800 96100; B 7800 200 15700 95900; B 8200 200 15700 95700; B 8400 200 15600 95500; B 8800 200 15600 95300; B 9000 200 15500 95100; B 9400 200 15500 94900; B 9600 200 15400 94700; B 10000 400 15400 94400; B 10200 400 15500 94000; B 10400 400 15600 93600; B 10600 400 15700 93200; B 10800 400 15800 92800; B 11000 400 15900 92400; B 11200 200 16000 92100; B 5200 200 13000 91900; B 5800 200 18700 91900; B 5000 200 12900 91700; B 4800 200 12800 91500; B 5800 400 18900 91600; B 4600 200 12700 91300; B 4400 200 12600 91100; B 5800 400 19100 91200; B 4200 200 12500 90900; B 4000 28200 12400 76700; B 5800 400 19300 90800; B 5800 400 19500 90400; B 5800 400 19700 90000; B 5800 400 19900 89600; B 5800 400 20100 89200; B 5800 400 20300 88800; B 5800 400 20500 88400; B 5800 400 20700 88000; B 5800 400 20900 87600; B 5800 400 21100 87200; B 5800 400 21300 86800; B 5800 400 21500 86400; B 5800 400 21700 86000; B 5800 400 21900 85600; B 5800 400 22100 85200; B 5800 400 22300 84800; B 5800 400 22500 84400; B 5800 400 22700 84000; B 5800 400 22900 83600; B 5800 400 23100 83200; B 5800 400 23300 82800; B 5800 400 23500 82400; B 5800 400 23700 82000; B 5800 400 23900 81600; B 5800 400 24100 81200; B 5800 400 24300 80800; B 5800 400 24500 80400; B 5800 400 24700 80000; B 5800 400 24900 79600; B 5800 400 25100 79200; B 5800 400 25300 78800; B 5800 400 25500 78400; B 5800 400 25700 78000; B 5800 400 25900 77600; B 5800 400 26100 77200; B 5800 400 26300 76800; B 5800 400 26500 76400; B 5800 400 26700 76000; B 5800 400 26900 75600; B 5800 400 27100 75200; B 5800 400 27300 74800; B 5800 400 27500 74400; B 5800 400 27700 74000; B 5800 400 27900 73600; B 5800 400 28100 73200; B 5800 400 28300 72800; B 5800 400 28500 72400; B 5800 400 28700 72000; B 5800 400 28900 71600; B 5800 400 29100 71200; B 5800 400 29300 70800; B 5800 400 29500 70400; B 4000 28200 36400 84500; B 4200 200 36300 70300; B 5800 400 29700 70000; B 4400 200 36200 70100; B 4600 200 36100 69900; B 5800 400 29900 69600; B 4800 200 36000 69700; B 5000 200 35900 69500; B 5800 200 30100 69300; B 5200 200 35800 69300; B 11200 200 32800 69100; B 11000 400 32900 68800; B 10800 400 33000 68400; B 10600 400 33100 68000; B 10400 400 33200 67600; B 10200 400 33300 67200; B 10000 400 33400 66800; B 4000 28200 44400 84500; B 44000 200 76400 98500; B 44200 200 76300 98300; B 44400 200 76200 98100; B 44600 200 76100 97900; B 44800 200 76000 97700; B 45000 200 75900 97500; B 45200 200 75800 97300; B 45400 200 75700 97100; B 45600 200 75600 96900; B 45800 200 75500 96700; B 46000 200 75400 96500; B 46200 200 75300 96300; B 46400 200 75200 96100; B 46600 200 75100 95900; B 46800 200 75000 95700; B 47000 200 74900 95500; B 47200 200 74800 95300; B 47400 200 74700 95100; B 47600 200 74600 94900; B 47800 200 74500 94700; B 7800 200 54300 94500; B 7600 200 54200 94300; B 7400 200 54100 94100; B 7200 200 54000 93900; B 7000 200 53900 93700; B 6800 200 53800 93500; B 6600 200 53700 93300; B 6400 200 53600 93100; B 6200 200 53500 92900; B 6000 200 53400 92700; B 5800 200 53300 92500; B 5600 200 53200 92300; B 5400 200 53100 92100; B 5200 200 53000 91900; B 5000 200 52900 91700; B 4800 200 52800 91500; B 4600 200 52700 91300; B 4400 200 52600 91100; B 4200 200 52500 90900; B 4000 4400 52400 88600; B 4200 200 52500 86300; B 4400 200 52600 86100; B 4600 200 52700 85900; B 4800 200 52800 85700; B 5000 200 52900 85500; B 5200 200 53000 85300; B 5400 200 53100 85100; B 5600 200 53200 84900; B 5800 200 53300 84700; B 6000 200 53400 84500; B 6200 200 53500 84300; B 6400 200 53600 84100; B 6600 200 53700 83900; B 6800 200 53800 83700; B 7000 200 53900 83500; B 7200 200 54000 83300; B 7400 200 54100 83100; B 7600 200 54200 82900; B 7800 200 54300 82700; B 23800 200 62500 82500; B 23800 200 62700 82300; B 23800 200 62900 82100; B 23800 200 63100 81900; B 23800 200 63300 81700; B 23800 200 63500 81500; B 23800 200 63700 81300; B 23800 200 63900 81100; B 23800 200 64100 80900; B 23800 200 64300 80700; B 23800 200 64500 80500; B 23800 200 64700 80300; B 23800 200 64900 80100; B 23800 200 65100 79900; B 23800 200 65300 79700; B 23800 200 65500 79500; B 23800 200 65700 79300; B 23800 200 65900 79100; B 23800 200 66100 78900; B 23800 200 66300 78700; B 7800 200 74500 78500; B 7600 200 74600 78300; B 7400 200 74700 78100; B 7200 200 74800 77900; B 7000 200 74900 77700; B 6800 200 75000 77500; B 6600 200 75100 77300; B 6400 200 75200 77100; B 6200 200 75300 76900; B 6000 200 75400 76700; B 5800 200 75500 76500; B 5600 200 75600 76300; B 5400 200 75700 76100; B 5200 200 75800 75900; B 5000 200 75900 75700; B 4800 200 76000 75500; B 4600 200 76100 75300; B 4400 200 76200 75100; B 4200 200 76300 74900; B 4000 4400 76400 72600; B 4200 200 44500 70300; B 4200 200 76300 70300; B 4400 200 44600 70100; B 4400 200 76200 70100; B 4600 200 44700 69900; B 4600 200 76100 69900; B 4800 200 44800 69700; B 4800 200 76000 69700; B 5000 200 44900 69500; B 5000 200 75900 69500; B 5200 200 45000 69300; B 5200 200 75800 69300; B 5400 200 45100 69100; B 5400 200 75700 69100; B 5600 200 45200 68900; B 5600 200 75600 68900; B 5800 200 45300 68700; B 5800 200 75500 68700; B 6000 200 45400 68500; B 6000 200 75400 68500; B 6200 200 45500 68300; B 6200 200 75300 68300; B 6400 200 45600 68100; B 6400 200 75200 68100; B 6600 200 45700 67900; B 6600 200 75100 67900; B 6800 200 45800 67700; B 6800 200 75000 67700; B 7000 200 45900 67500; B 7000 200 74900 67500; B 7200 200 46000 67300; B 7200 200 74800 67300; B 7400 200 46100 67100; B 7400 200 74700 67100; B 7600 200 46200 66900; B 7600 200 74600 66900; B 7800 200 46300 66700; B 7800 200 74500 66700; B 9600 200 33400 66500; B 35800 200 60500 66500; B 9400 200 33300 66300; B 35200 200 60400 66300; B 9000 200 33300 66100; B 34800 200 60400 66100; B 8800 200 33200 65900; B 34400 200 60400 65900; B 8400 200 33200 65700; B 34000 200 60400 65700; B 8200 200 33100 65500; B 33600 200 60400 65500; B 7800 200 33100 65300; B 33200 200 60400 65300; B 7600 200 33000 65100; B 32800 200 60400 65100; B 7200 200 33000 64900; B 32400 200 60400 64900; B 7000 200 32900 64700; B 32000 200 60400 64700; B 6600 200 32900 64500; B 31600 200 60400 64500; B 6400 200 32800 64300; B 31200 200 60400 64300; B 6000 200 32800 64100; B 30800 200 60400 64100; B 5800 200 32700 63900; B 30400 200 60400 63900; B 5400 200 32700 63700; B 30000 200 60400 63700; B 5200 200 32600 63500; B 29600 200 60400 63500; B 4800 200 32600 63300; B 29200 200 60400 63300; B 4600 200 32500 63100; B 28800 200 60400 63100; B 4200 200 32500 62900; B 28400 200 60400 62900; B 4000 200 32400 62700; B 28000 200 60400 62700; B 4000 32000 84400 78600; B 30000 6000 116600 86800; B 24000 6000 185600 86800; B 6000 18000 116600 74800; B 6000 200 140600 83700; B 6000 200 164600 83700; B 6200 200 140700 83500; B 6200 200 164500 83500; B 6400 200 140800 83300; B 6400 200 164400 83300; B 6600 200 140900 83100; B 6600 200 164300 83100; B 6800 200 141000 82900; B 6800 200 164200 82900; B 7000 200 141100 82700; B 7000 200 164100 82700; B 7200 200 141200 82500; B 7200 200 164000 82500; B 7400 200 141300 82300; B 7400 200 163900 82300; B 7600 200 141400 82100; B 7600 200 163800 82100; B 7800 200 141500 81900; B 7800 200 163700 81900; B 8000 200 141600 81700; B 8000 200 163600 81700; B 8200 200 141700 81500; B 8200 200 163500 81500; B 8400 200 141800 81300; B 8400 200 163400 81300; B 8600 200 141900 81100; B 8600 200 163300 81100; B 8800 200 142000 80900; B 8800 200 163200 80900; B 9000 200 142100 80700; B 9000 200 163100 80700; B 9200 200 142200 80500; B 9200 200 163000 80500; B 9400 200 142300 80300; B 9400 200 162900 80300; B 9600 200 142400 80100; B 9600 200 162800 80100; B 9800 200 142500 79900; B 9800 200 162700 79900; B 10000 200 142600 79700; B 10000 200 162600 79700; B 10200 200 142700 79500; B 10200 200 162500 79500; B 10400 200 142800 79300; B 10400 200 162400 79300; B 10600 200 142900 79100; B 10600 200 162300 79100; B 10800 200 143000 78900; B 10800 200 162200 78900; B 11000 200 143100 78700; B 11000 200 162100 78700; B 11200 200 143200 78500; B 11200 200 162000 78500; B 11400 200 143300 78300; B 11400 200 161900 78300; B 11600 200 143400 78100; B 11600 200 161800 78100; B 11800 200 143500 77900; B 11800 200 161700 77900; B 12000 200 143600 77700; B 12000 200 161600 77700; B 12200 200 143700 77500; B 12200 200 161500 77500; B 12400 200 143800 77300; B 12400 200 161400 77300; B 12600 200 143900 77100; B 12600 200 161300 77100; B 12800 200 144000 76900; B 12800 200 161200 76900; B 13000 200 144100 76700; B 13000 200 161100 76700; B 13200 200 144200 76500; B 13200 200 161000 76500; B 13400 200 144300 76300; B 13400 200 160900 76300; B 13600 200 144400 76100; B 13600 200 160800 76100; B 13800 200 144500 75900; B 13800 200 160700 75900; B 14000 200 144600 75700; B 14000 200 160600 75700; B 14200 200 144700 75500; B 14200 200 160500 75500; B 14400 200 144800 75300; B 14400 200 160400 75300; B 14600 200 144900 75100; B 14600 200 160300 75100; B 14800 200 145000 74900; B 14800 200 160200 74900; B 30000 3000 152600 73300; B 6000 6000 176600 80800; B 24000 6000 185600 74800; B 30000 6000 116600 62800; B 3000 1000 102100 57300; B 1000 600 104500 57500; B 1000 2000 102100 55800; B 1400 600 104700 56900; B 1800 600 104900 56300; B 1000 1800 106500 56900; B 3000 1000 108900 57300; B 3000 1000 112300 57300; B 3000 1000 115700 57300; B 3000 1000 119100 57300; B 3000 400 105500 55800; B 3000 1000 102100 54300; B 1000 1800 104500 54700; B 1800 600 106100 55300; B 1400 600 106300 54700; B 1000 600 106500 54100; B 1000 3000 108900 55300; B 1000 600 111300 56500; B 2000 1000 111800 55700; B 1000 400 111300 55000; B 1000 2000 114700 55800; B 1000 600 118100 56500; B 1000 600 120100 56500; B 1400 1000 116500 55700; B 1000 400 116700 55000; B 3000 1000 112300 54300; B 3000 1000 115700 54300; B 3000 1000 119100 55700; B 3000 1000 122500 57300; B 3000 1000 125900 57300; B 3000 1000 129300 57300; B 2000 200 132600 57700; B 2400 200 132800 57500; B 2800 600 133000 57100; B 1000 600 121500 56500; B 1000 600 123500 56500; B 3000 1000 122500 55700; B 2600 200 118900 55100; B 2800 200 119000 54900; B 1000 1000 118100 54300; B 1800 200 119700 54700; B 1600 200 119800 54500; B 1400 200 119900 54300; B 1200 200 120000 54100; B 1000 200 120100 53900; B 1000 1400 121500 54500; B 1000 1400 123500 54500; B 1000 3000 125900 55300; B 1000 600 128300 56500; B 2000 1000 128800 55700; B 1000 400 128300 55000; B 1000 2000 132100 55800; B 1600 200 133800 56700; B 1200 200 134000 56500; B 1000 1200 134100 55800; B 1200 200 134000 55100; B 1600 200 133800 54900; B 3000 1000 129300 54300; B 2800 600 133000 54500; B 2400 200 132800 54100; B 2000 200 132600 53900; B 6000 18000 140600 62800; B 17600 200 152600 71700; B 17200 200 152600 71500; B 16800 200 152600 71300; B 16400 200 152600 71100; B 16000 200 152600 70900; B 15600 200 152600 70700; B 15200 200 152600 70500; B 14800 200 152600 70300; B 14400 200 152600 70100; B 14000 200 152600 69900; B 13600 200 152600 69700; B 13200 200 152600 69500; B 12800 200 152600 69300; B 12400 200 152600 69100; B 12000 200 152600 68900; B 11600 200 152600 68700; B 11200 200 152600 68500; B 10800 200 152600 68300; B 10400 200 152600 68100; B 10000 200 152600 67900; B 9600 200 152600 67700; B 9200 200 152600 67500; B 8800 200 152600 67300; B 8400 200 152600 67100; B 8000 200 152600 66900; B 7600 200 152600 66700; B 7200 200 152600 66500; B 6800 200 152600 66300; B 6400 200 152600 66100; B 6000 200 152600 65900; B 5600 200 152600 65700; B 5200 200 152600 65500; B 4800 200 152600 65300; B 4400 200 152600 65100; B 4000 200 152600 64900; B 3600 200 152600 64700; B 3200 200 152600 64500; B 2800 200 152600 64300; B 2400 200 152600 64100; B 2000 200 152600 63900; B 1600 200 152600 63700; B 1200 200 152600 63500; B 800 200 152600 63300; B 400 200 152600 63100; B 6000 18000 164600 62800; B 6000 6000 194600 68800; B 24000 6000 185600 62800; B 3000 1000 174100 57300; B 1000 600 176500 57500; B 1000 600 179500 57500; B 1400 400 176700 57000; B 1000 600 173100 56500; B 1000 200 176900 56700; B 1400 400 179300 57000; B 3000 1000 181900 57300; B 3000 1000 185300 57300; B 3000 1000 188700 57300; B 1000 600 191100 57500; B 1000 600 194100 57500; B 1000 200 179100 56700; B 1400 400 177100 56400; B 3000 1000 174100 55700; B 1000 200 177300 56100; B 1400 400 178900 56400; B 1000 600 180900 56500; B 1000 200 178700 56100; B 2400 400 178000 55800; B 1000 400 175100 55000; B 1600 600 178000 55300; B 3000 1000 181900 55700; B 3000 1000 174100 54300; B 1000 1200 178100 54400; B 1000 400 182900 55000; B 3000 1000 181900 54300; B 1000 3000 185300 55300; B 1000 600 187700 56500; B 1400 600 191300 56900; B 1400 600 193900 56900; B 2000 1000 188200 55700; B 1800 600 191500 56300; B 1800 600 193700 56300; B 4000 400 192600 55800; B 1000 400 187700 55000; B 3000 1000 188700 54300; B 1000 1800 191100 54700; B 1600 600 192600 55300; B 1000 1800 194100 54700; B 3000 1000 196500 57300; B 1000 600 195500 56500; B 3000 1000 196500 55700; B 1000 400 197500 55000; B 3000 1000 196500 54300; B 1000 600 133700 50500; B 1000 600 136700 50500; B 1400 600 133900 49900; B 1400 600 136500 49900; B 1800 600 134100 49300; B 1800 600 136300 49300; B 4000 400 135200 48800; B 1000 1800 133700 47700; B 1600 600 135200 48300; B 1000 1800 136700 47700; B 3000 1000 139100 50300; B 3000 1000 142500 50300; B 1000 600 138100 49500; B 1000 600 141500 49500; B 1000 600 143500 49500; B 2000 1000 138600 48700; B 3000 1000 142500 48700; B 3000 1000 145900 50300; B 1000 600 144900 49500; B 3000 1000 145900 48700; B 1000 400 138100 48000; B 3000 1000 139100 47300; B 1000 1400 141500 47500; B 1000 1400 143500 47500; B 1000 400 146900 48000; B 3000 1000 145900 47300; B 1000 3000 148300 49300; B 1000 3000 150300 49300; B 3000 1000 149300 47300; B 3000 1000 152700 50300; B 1000 600 151700 49500; B 1000 600 153700 49500; B 3000 1000 152700 48700; B 3000 1000 156300 50300; B 1000 600 158700 50500; B 1000 600 161700 50500; B 1000 600 155300 49500; B 1400 600 158900 49900; B 1400 600 161500 49900; B 2000 1000 155800 48700; B 1800 600 159100 49300; B 1800 600 161300 49300; B 4000 400 160200 48800; B 2600 200 152500 48100; B 2800 200 152600 47900; B 1000 400 155300 48000; B 1000 1000 151700 47300; B 1800 200 153300 47700; B 1600 200 153400 47500; B 1400 200 153500 47300; B 1200 200 153600 47100; B 1000 200 153700 46900; B 3000 1000 156300 47300; B 1000 1800 158700 47700; B 1600 600 160200 48300; B 1000 1800 161700 47700; B 3000 1000 164100 50300; B 1000 600 166500 50500; B 1000 600 163100 49500; B 1400 600 166700 49900; B 2000 1000 163600 48700; B 1800 600 166900 49300; B 1000 1800 168500 49900; B 3000 1000 170900 50300; B 3000 400 167500 48800; B 1000 400 163100 48000; B 3000 1000 164100 47300; B 1000 1800 166500 47700; B 1800 600 168100 48300; B 1400 600 168300 47700; B 1000 600 168500 47100; B 1000 3000 170900 48300; C 2 R 1 0 T -42000 51800; C 3 R 1 0 T -71800 28400; C 4 R 1 0 T 92200 2000; C 5 R 1 0 T 135000 -20000; C 6 R 1 0 T -86000 -67200; C 7 R 1 0 T -16000 -73400; C 8 R 1 0 T 84000 -86000; C 9 R 1 0 T 144000 -86000; DF; DS 9 1 2; 9 gas-sensora; L CMS; B 52000 53200 26000 26600; DF; DS 8 1 2; 9 micro-hot-platea; L CMS; B 52000 53200 26000 26600; DF; DS 7 1 2; 9 pixel-160x160a; L CMS; B 34000 34000 74600 14600; DF; DS 6 1 2; 9 pixel-80x80a; L CMS; B 18000 18000 108400 8400; DF; DS 5 1 2; 9 thermal-actuatora; L CMS; B 18000 44000 9000 22000; DF; DS 4 1 2; 9 thermal-convertera; L CMS; B 30000 44000 11800 0; DF; DS 3 1 2; 9 open-oxide-80x80a; L CMS; B 16000 16000 135400 -40400; DF; DS 2 1 2; 9 open-80x80a; L CMS; B 16000 16000 105600 -39800; DF; C 1; End magic-8.0.210/scmos/examples/nist-mems-library/open-80x80.mag0000644000175000001440000000013210751423606022206 0ustar timusersmagic tech scmos timestamp 760840415 << substrateopen >> rect 488 -239 568 -159 << end >> magic-8.0.210/scmos/examples/nist-mems-library/open-oxide-80x80.cif0000644000175000001440000004074510751423606023327 0ustar timusersDS 1 1 2; 9 open-oxide-80x80; L CAA; B 12000 200 135400 -32500; B 11600 200 135400 -32700; B 11200 200 135400 -32900; B 10800 200 135400 -33100; B 10400 200 135400 -33300; B 10000 200 135400 -33500; B 9600 200 135400 -33700; B 9200 200 135400 -33900; B 8800 200 135400 -34100; B 8400 200 135400 -34300; B 200 200 127500 -34500; B 8000 200 135400 -34500; B 200 200 143300 -34500; B 400 200 127600 -34700; B 7600 200 135400 -34700; B 400 200 143200 -34700; B 600 200 127700 -34900; B 7200 200 135400 -34900; B 600 200 143100 -34900; B 800 200 127800 -35100; B 6800 200 135400 -35100; B 800 200 143000 -35100; B 1000 200 127900 -35300; B 6400 200 135400 -35300; B 1000 200 142900 -35300; B 1200 200 128000 -35500; B 6000 200 135400 -35500; B 1200 200 142800 -35500; B 1400 200 128100 -35700; B 5600 200 135400 -35700; B 1400 200 142700 -35700; B 1600 200 128200 -35900; B 5200 200 135400 -35900; B 1600 200 142600 -35900; B 1800 200 128300 -36100; B 4800 200 135400 -36100; B 1800 200 142500 -36100; B 2000 200 128400 -36300; B 2000 200 142400 -36300; B 2200 200 128500 -36500; B 2200 200 142300 -36500; B 2400 200 128600 -36700; B 2400 200 142200 -36700; B 2600 200 128700 -36900; B 2600 200 142100 -36900; B 2800 200 128800 -37100; B 2800 200 142000 -37100; B 3000 200 128900 -37300; B 3000 200 141900 -37300; B 3200 200 129000 -37500; B 3200 200 141800 -37500; B 3400 200 129100 -37700; B 3400 200 141700 -37700; B 3600 200 129200 -37900; B 3600 200 141600 -37900; B 3800 4800 129300 -40400; B 3800 4800 141500 -40400; B 3600 200 129200 -42900; B 3600 200 141600 -42900; B 3400 200 129100 -43100; B 3400 200 141700 -43100; B 3200 200 129000 -43300; B 3200 200 141800 -43300; B 3000 200 128900 -43500; B 3000 200 141900 -43500; B 2800 200 128800 -43700; B 2800 200 142000 -43700; B 2600 200 128700 -43900; B 2600 200 142100 -43900; B 2400 200 128600 -44100; B 2400 200 142200 -44100; B 2200 200 128500 -44300; B 2200 200 142300 -44300; B 2000 200 128400 -44500; B 2000 200 142400 -44500; B 1800 200 128300 -44700; B 4800 200 135400 -44700; B 1800 200 142500 -44700; B 1600 200 128200 -44900; B 5200 200 135400 -44900; B 1600 200 142600 -44900; B 1400 200 128100 -45100; B 5600 200 135400 -45100; B 1400 200 142700 -45100; B 1200 200 128000 -45300; B 6000 200 135400 -45300; B 1200 200 142800 -45300; B 1000 200 127900 -45500; B 6400 200 135400 -45500; B 1000 200 142900 -45500; B 800 200 127800 -45700; B 6800 200 135400 -45700; B 800 200 143000 -45700; B 600 200 127700 -45900; B 7200 200 135400 -45900; B 600 200 143100 -45900; B 400 200 127600 -46100; B 7600 200 135400 -46100; B 400 200 143200 -46100; B 200 200 127500 -46300; B 8000 200 135400 -46300; B 200 200 143300 -46300; B 8400 200 135400 -46500; B 8800 200 135400 -46700; B 9200 200 135400 -46900; B 9600 200 135400 -47100; B 10000 200 135400 -47300; B 10400 200 135400 -47500; B 10800 200 135400 -47700; B 11200 200 135400 -47900; B 11600 200 135400 -48100; B 12000 200 135400 -48300; L CVA; B 12000 200 135400 -32500; B 11600 200 135400 -32700; B 11200 200 135400 -32900; B 10800 200 135400 -33100; B 10400 200 135400 -33300; B 10000 200 135400 -33500; B 9600 200 135400 -33700; B 9200 200 135400 -33900; B 8800 200 135400 -34100; B 8400 200 135400 -34300; B 200 200 127500 -34500; B 8000 200 135400 -34500; B 200 200 143300 -34500; B 400 200 127600 -34700; B 7600 200 135400 -34700; B 400 200 143200 -34700; B 600 200 127700 -34900; B 7200 200 135400 -34900; B 600 200 143100 -34900; B 800 200 127800 -35100; B 6800 200 135400 -35100; B 800 200 143000 -35100; B 1000 200 127900 -35300; B 6400 200 135400 -35300; B 1000 200 142900 -35300; B 1200 200 128000 -35500; B 6000 200 135400 -35500; B 1200 200 142800 -35500; B 1400 200 128100 -35700; B 5600 200 135400 -35700; B 1400 200 142700 -35700; B 1600 200 128200 -35900; B 5200 200 135400 -35900; B 1600 200 142600 -35900; B 1800 200 128300 -36100; B 4800 200 135400 -36100; B 1800 200 142500 -36100; B 2000 200 128400 -36300; B 2000 200 142400 -36300; B 2200 200 128500 -36500; B 2200 200 142300 -36500; B 2400 200 128600 -36700; B 2400 200 142200 -36700; B 2600 200 128700 -36900; B 2600 200 142100 -36900; B 2800 200 128800 -37100; B 2800 200 142000 -37100; B 3000 200 128900 -37300; B 3000 200 141900 -37300; B 3200 200 129000 -37500; B 3200 200 141800 -37500; B 3400 200 129100 -37700; B 3400 200 141700 -37700; B 3600 200 129200 -37900; B 3600 200 141600 -37900; B 3800 4800 129300 -40400; B 3800 4800 141500 -40400; B 3600 200 129200 -42900; B 3600 200 141600 -42900; B 3400 200 129100 -43100; B 3400 200 141700 -43100; B 3200 200 129000 -43300; B 3200 200 141800 -43300; B 3000 200 128900 -43500; B 3000 200 141900 -43500; B 2800 200 128800 -43700; B 2800 200 142000 -43700; B 2600 200 128700 -43900; B 2600 200 142100 -43900; B 2400 200 128600 -44100; B 2400 200 142200 -44100; B 2200 200 128500 -44300; B 2200 200 142300 -44300; B 2000 200 128400 -44500; B 2000 200 142400 -44500; B 1800 200 128300 -44700; B 4800 200 135400 -44700; B 1800 200 142500 -44700; B 1600 200 128200 -44900; B 5200 200 135400 -44900; B 1600 200 142600 -44900; B 1400 200 128100 -45100; B 5600 200 135400 -45100; B 1400 200 142700 -45100; B 1200 200 128000 -45300; B 6000 200 135400 -45300; B 1200 200 142800 -45300; B 1000 200 127900 -45500; B 6400 200 135400 -45500; B 1000 200 142900 -45500; B 800 200 127800 -45700; B 6800 200 135400 -45700; B 800 200 143000 -45700; B 600 200 127700 -45900; B 7200 200 135400 -45900; B 600 200 143100 -45900; B 400 200 127600 -46100; B 7600 200 135400 -46100; B 400 200 143200 -46100; B 200 200 127500 -46300; B 8000 200 135400 -46300; B 200 200 143300 -46300; B 8400 200 135400 -46500; B 8800 200 135400 -46700; B 9200 200 135400 -46900; B 9600 200 135400 -47100; B 10000 200 135400 -47300; B 10400 200 135400 -47500; B 10800 200 135400 -47700; B 11200 200 135400 -47900; B 11600 200 135400 -48100; B 12000 200 135400 -48300; L CCA; B 12000 200 135400 -32500; B 11600 200 135400 -32700; B 11200 200 135400 -32900; B 10800 200 135400 -33100; B 10400 200 135400 -33300; B 10000 200 135400 -33500; B 9600 200 135400 -33700; B 9200 200 135400 -33900; B 8800 200 135400 -34100; B 8400 200 135400 -34300; B 200 200 127500 -34500; B 8000 200 135400 -34500; B 200 200 143300 -34500; B 400 200 127600 -34700; B 7600 200 135400 -34700; B 400 200 143200 -34700; B 600 200 127700 -34900; B 7200 200 135400 -34900; B 600 200 143100 -34900; B 800 200 127800 -35100; B 6800 200 135400 -35100; B 800 200 143000 -35100; B 1000 200 127900 -35300; B 6400 200 135400 -35300; B 1000 200 142900 -35300; B 1200 200 128000 -35500; B 6000 200 135400 -35500; B 1200 200 142800 -35500; B 1400 200 128100 -35700; B 5600 200 135400 -35700; B 1400 200 142700 -35700; B 1600 200 128200 -35900; B 5200 200 135400 -35900; B 1600 200 142600 -35900; B 1800 200 128300 -36100; B 4800 200 135400 -36100; B 1800 200 142500 -36100; B 2000 200 128400 -36300; B 2000 200 142400 -36300; B 2200 200 128500 -36500; B 2200 200 142300 -36500; B 2400 200 128600 -36700; B 2400 200 142200 -36700; B 2600 200 128700 -36900; B 2600 200 142100 -36900; B 2800 200 128800 -37100; B 2800 200 142000 -37100; B 3000 200 128900 -37300; B 3000 200 141900 -37300; B 3200 200 129000 -37500; B 3200 200 141800 -37500; B 3400 200 129100 -37700; B 3400 200 141700 -37700; B 3600 200 129200 -37900; B 3600 200 141600 -37900; B 3800 4800 129300 -40400; B 3800 4800 141500 -40400; B 3600 200 129200 -42900; B 3600 200 141600 -42900; B 3400 200 129100 -43100; B 3400 200 141700 -43100; B 3200 200 129000 -43300; B 3200 200 141800 -43300; B 3000 200 128900 -43500; B 3000 200 141900 -43500; B 2800 200 128800 -43700; B 2800 200 142000 -43700; B 2600 200 128700 -43900; B 2600 200 142100 -43900; B 2400 200 128600 -44100; B 2400 200 142200 -44100; B 2200 200 128500 -44300; B 2200 200 142300 -44300; B 2000 200 128400 -44500; B 2000 200 142400 -44500; B 1800 200 128300 -44700; B 4800 200 135400 -44700; B 1800 200 142500 -44700; B 1600 200 128200 -44900; B 5200 200 135400 -44900; B 1600 200 142600 -44900; B 1400 200 128100 -45100; B 5600 200 135400 -45100; B 1400 200 142700 -45100; B 1200 200 128000 -45300; B 6000 200 135400 -45300; B 1200 200 142800 -45300; B 1000 200 127900 -45500; B 6400 200 135400 -45500; B 1000 200 142900 -45500; B 800 200 127800 -45700; B 6800 200 135400 -45700; B 800 200 143000 -45700; B 600 200 127700 -45900; B 7200 200 135400 -45900; B 600 200 143100 -45900; B 400 200 127600 -46100; B 7600 200 135400 -46100; B 400 200 143200 -46100; B 200 200 127500 -46300; B 8000 200 135400 -46300; B 200 200 143300 -46300; B 8400 200 135400 -46500; B 8800 200 135400 -46700; B 9200 200 135400 -46900; B 9600 200 135400 -47100; B 10000 200 135400 -47300; B 10400 200 135400 -47500; B 10800 200 135400 -47700; B 11200 200 135400 -47900; B 11600 200 135400 -48100; B 12000 200 135400 -48300; L COG; B 12000 200 135400 -32500; B 11600 200 135400 -32700; B 11200 200 135400 -32900; B 10800 200 135400 -33100; B 10400 200 135400 -33300; B 10000 200 135400 -33500; B 9600 200 135400 -33700; B 9200 200 135400 -33900; B 8800 200 135400 -34100; B 8400 200 135400 -34300; B 200 200 127500 -34500; B 8000 200 135400 -34500; B 200 200 143300 -34500; B 400 200 127600 -34700; B 7600 200 135400 -34700; B 400 200 143200 -34700; B 600 200 127700 -34900; B 7200 200 135400 -34900; B 600 200 143100 -34900; B 800 200 127800 -35100; B 6800 200 135400 -35100; B 800 200 143000 -35100; B 1000 200 127900 -35300; B 6400 200 135400 -35300; B 1000 200 142900 -35300; B 1200 200 128000 -35500; B 6000 200 135400 -35500; B 1200 200 142800 -35500; B 1400 200 128100 -35700; B 5600 200 135400 -35700; B 1400 200 142700 -35700; B 1600 200 128200 -35900; B 5200 200 135400 -35900; B 1600 200 142600 -35900; B 1800 200 128300 -36100; B 4800 200 135400 -36100; B 1800 200 142500 -36100; B 2000 200 128400 -36300; B 2000 200 142400 -36300; B 2200 200 128500 -36500; B 2200 200 142300 -36500; B 2400 200 128600 -36700; B 2400 200 142200 -36700; B 2600 200 128700 -36900; B 2600 200 142100 -36900; B 2800 200 128800 -37100; B 2800 200 142000 -37100; B 3000 200 128900 -37300; B 3000 200 141900 -37300; B 3200 200 129000 -37500; B 3200 200 141800 -37500; B 3400 200 129100 -37700; B 3400 200 141700 -37700; B 3600 200 129200 -37900; B 3600 200 141600 -37900; B 3800 4800 129300 -40400; B 3800 4800 141500 -40400; B 3600 200 129200 -42900; B 3600 200 141600 -42900; B 3400 200 129100 -43100; B 3400 200 141700 -43100; B 3200 200 129000 -43300; B 3200 200 141800 -43300; B 3000 200 128900 -43500; B 3000 200 141900 -43500; B 2800 200 128800 -43700; B 2800 200 142000 -43700; B 2600 200 128700 -43900; B 2600 200 142100 -43900; B 2400 200 128600 -44100; B 2400 200 142200 -44100; B 2200 200 128500 -44300; B 2200 200 142300 -44300; B 2000 200 128400 -44500; B 2000 200 142400 -44500; B 1800 200 128300 -44700; B 4800 200 135400 -44700; B 1800 200 142500 -44700; B 1600 200 128200 -44900; B 5200 200 135400 -44900; B 1600 200 142600 -44900; B 1400 200 128100 -45100; B 5600 200 135400 -45100; B 1400 200 142700 -45100; B 1200 200 128000 -45300; B 6000 200 135400 -45300; B 1200 200 142800 -45300; B 1000 200 127900 -45500; B 6400 200 135400 -45500; B 1000 200 142900 -45500; B 800 200 127800 -45700; B 6800 200 135400 -45700; B 800 200 143000 -45700; B 600 200 127700 -45900; B 7200 200 135400 -45900; B 600 200 143100 -45900; B 400 200 127600 -46100; B 7600 200 135400 -46100; B 400 200 143200 -46100; B 200 200 127500 -46300; B 8000 200 135400 -46300; B 200 200 143300 -46300; B 8400 200 135400 -46500; B 8800 200 135400 -46700; B 9200 200 135400 -46900; B 9600 200 135400 -47100; B 10000 200 135400 -47300; B 10400 200 135400 -47500; B 10800 200 135400 -47700; B 11200 200 135400 -47900; B 11600 200 135400 -48100; B 12000 200 135400 -48300; L COP; B 12000 200 135400 -32500; B 11600 200 135400 -32700; B 11200 200 135400 -32900; B 10800 200 135400 -33100; B 10400 200 135400 -33300; B 10000 200 135400 -33500; B 9600 200 135400 -33700; B 9200 200 135400 -33900; B 8800 200 135400 -34100; B 8400 200 135400 -34300; B 200 200 127500 -34500; B 8000 200 135400 -34500; B 200 200 143300 -34500; B 400 200 127600 -34700; B 7600 200 135400 -34700; B 400 200 143200 -34700; B 600 200 127700 -34900; B 7200 200 135400 -34900; B 600 200 143100 -34900; B 800 200 127800 -35100; B 6800 200 135400 -35100; B 800 200 143000 -35100; B 1000 200 127900 -35300; B 6400 200 135400 -35300; B 1000 200 142900 -35300; B 1200 200 128000 -35500; B 6000 200 135400 -35500; B 1200 200 142800 -35500; B 1400 200 128100 -35700; B 5600 200 135400 -35700; B 1400 200 142700 -35700; B 1600 200 128200 -35900; B 5200 200 135400 -35900; B 1600 200 142600 -35900; B 1800 200 128300 -36100; B 4800 200 135400 -36100; B 1800 200 142500 -36100; B 2000 200 128400 -36300; B 2000 200 142400 -36300; B 2200 200 128500 -36500; B 2200 200 142300 -36500; B 2400 200 128600 -36700; B 2400 200 142200 -36700; B 2600 200 128700 -36900; B 2600 200 142100 -36900; B 2800 200 128800 -37100; B 2800 200 142000 -37100; B 3000 200 128900 -37300; B 3000 200 141900 -37300; B 3200 200 129000 -37500; B 3200 200 141800 -37500; B 3400 200 129100 -37700; B 3400 200 141700 -37700; B 3600 200 129200 -37900; B 3600 200 141600 -37900; B 3800 4800 129300 -40400; B 3800 4800 141500 -40400; B 3600 200 129200 -42900; B 3600 200 141600 -42900; B 3400 200 129100 -43100; B 3400 200 141700 -43100; B 3200 200 129000 -43300; B 3200 200 141800 -43300; B 3000 200 128900 -43500; B 3000 200 141900 -43500; B 2800 200 128800 -43700; B 2800 200 142000 -43700; B 2600 200 128700 -43900; B 2600 200 142100 -43900; B 2400 200 128600 -44100; B 2400 200 142200 -44100; B 2200 200 128500 -44300; B 2200 200 142300 -44300; B 2000 200 128400 -44500; B 2000 200 142400 -44500; B 1800 200 128300 -44700; B 4800 200 135400 -44700; B 1800 200 142500 -44700; B 1600 200 128200 -44900; B 5200 200 135400 -44900; B 1600 200 142600 -44900; B 1400 200 128100 -45100; B 5600 200 135400 -45100; B 1400 200 142700 -45100; B 1200 200 128000 -45300; B 6000 200 135400 -45300; B 1200 200 142800 -45300; B 1000 200 127900 -45500; B 6400 200 135400 -45500; B 1000 200 142900 -45500; B 800 200 127800 -45700; B 6800 200 135400 -45700; B 800 200 143000 -45700; B 600 200 127700 -45900; B 7200 200 135400 -45900; B 600 200 143100 -45900; B 400 200 127600 -46100; B 7600 200 135400 -46100; B 400 200 143200 -46100; B 200 200 127500 -46300; B 8000 200 135400 -46300; B 200 200 143300 -46300; B 8400 200 135400 -46500; B 8800 200 135400 -46700; B 9200 200 135400 -46900; B 9600 200 135400 -47100; B 10000 200 135400 -47300; B 10400 200 135400 -47500; B 10800 200 135400 -47700; B 11200 200 135400 -47900; B 11600 200 135400 -48100; B 12000 200 135400 -48300; DF; C 1; End magic-8.0.210/scmos/examples/nist-mems-library/gas-sensor.cif0000644000175000001440000020050010751423606022537 0ustar timusersDS 1 1 2; 9 gas-sensor; L CMS; B 2000 5200 5000 50600; B 2000 5200 47000 50600; B 2200 200 5100 47900; B 2200 200 46900 47900; B 2400 200 5200 47700; B 2400 200 46800 47700; B 2600 200 5300 47500; B 2600 200 46700 47500; B 2800 200 5400 47300; B 2800 200 46600 47300; B 1800 200 6100 47100; B 1800 200 45900 47100; B 1800 200 6300 46900; B 1800 200 45700 46900; B 1800 200 6500 46700; B 1800 200 45500 46700; B 1800 200 6700 46500; B 1800 200 45300 46500; B 1800 200 6900 46300; B 1800 200 45100 46300; B 1800 200 7100 46100; B 1800 200 44900 46100; B 1800 200 7300 45900; B 1800 200 44700 45900; B 1800 200 7500 45700; B 1800 200 44500 45700; B 1800 200 7700 45500; B 1800 200 44300 45500; B 1800 200 7900 45300; B 1800 200 44100 45300; B 1800 200 8100 45100; B 1800 200 43900 45100; B 1800 200 8300 44900; B 1800 200 43700 44900; B 1800 200 8500 44700; B 1800 200 43500 44700; B 1800 200 8700 44500; B 1800 200 43300 44500; B 1800 200 8900 44300; B 1800 200 43100 44300; B 1800 200 9100 44100; B 1800 200 42900 44100; B 1800 200 9300 43900; B 1800 200 42700 43900; B 1800 200 9500 43700; B 1800 200 42500 43700; B 1800 200 9700 43500; B 1800 200 42300 43500; B 1800 200 9900 43300; B 1800 200 42100 43300; B 1800 200 10100 43100; B 1800 200 41900 43100; B 1800 200 10300 42900; B 1800 200 41700 42900; B 1800 200 10500 42700; B 1800 200 41500 42700; B 1800 200 10700 42500; B 1800 200 41300 42500; B 1800 200 10900 42300; B 1800 200 41100 42300; B 1800 200 11100 42100; B 1800 200 40900 42100; B 1800 200 11300 41900; B 1800 200 40700 41900; B 1800 200 11500 41700; B 1800 200 40500 41700; B 1800 200 11700 41500; B 1800 200 40300 41500; B 1800 200 11900 41300; B 1800 200 40100 41300; B 1800 200 12100 41100; B 1800 200 39900 41100; B 1800 200 12300 40900; B 1800 200 39700 40900; B 1800 200 12500 40700; B 1800 200 39500 40700; B 1800 200 12700 40500; B 1800 200 39300 40500; B 1800 200 12900 40300; B 1800 200 39100 40300; B 1800 200 13100 40100; B 1800 200 38900 40100; B 1800 200 13300 39900; B 1800 200 38700 39900; B 1800 200 13500 39700; B 1800 200 38500 39700; B 1800 200 13700 39500; B 1800 200 38300 39500; B 1800 200 13900 39300; B 1800 200 38100 39300; B 1800 200 14100 39100; B 1800 200 37900 39100; B 1800 200 14300 38900; B 1800 200 37700 38900; B 1800 200 14500 38700; B 1800 200 37500 38700; B 1800 200 14700 38500; B 1800 200 37300 38500; B 1800 200 14900 38300; B 1800 200 37100 38300; B 1800 200 15100 38100; B 1800 200 36900 38100; B 1800 200 15300 37900; B 1800 200 36700 37900; B 1800 200 15500 37700; B 1800 200 36500 37700; B 1800 200 15700 37500; B 1800 200 36300 37500; B 1800 200 15900 37300; B 1800 200 36100 37300; B 1800 200 16100 37100; B 1800 200 35900 37100; B 1800 200 16300 36900; B 1800 200 35700 36900; B 1800 200 16500 36700; B 1800 200 35500 36700; B 1800 200 16700 36500; B 1800 200 35300 36500; B 1800 200 16900 36300; B 1800 200 35100 36300; B 1800 200 17100 36100; B 1800 200 34900 36100; B 1800 200 17300 35900; B 1800 200 34700 35900; B 1800 200 17500 35700; B 1800 200 34500 35700; B 1800 200 17700 35500; B 1800 200 34300 35500; B 1800 200 17900 35300; B 1800 200 34100 35300; B 7800 200 21100 35100; B 7600 200 21200 34900; B 7400 200 21300 34700; B 7200 200 21400 34500; B 7000 6200 21500 31300; B 7800 200 30900 35100; B 7600 200 30800 34900; B 7400 200 30700 34700; B 7200 200 30600 34500; B 7000 6200 30500 31300; B 7000 6200 21500 23100; B 7200 200 21400 19900; B 7400 200 21300 19700; B 7600 200 21200 19500; B 7800 200 21100 19300; B 7000 6200 30500 23100; B 7200 200 30600 19900; B 7400 200 30700 19700; B 7600 200 30800 19500; B 7800 200 30900 19300; B 1800 200 17900 19100; B 1800 200 34100 19100; B 1800 200 17700 18900; B 1800 200 34300 18900; B 1800 200 17500 18700; B 1800 200 34500 18700; B 1800 200 17300 18500; B 1800 200 34700 18500; B 1800 200 17100 18300; B 1800 200 34900 18300; B 1800 200 16900 18100; B 1800 200 35100 18100; B 1800 200 16700 17900; B 1800 200 35300 17900; B 1800 200 16500 17700; B 1800 200 35500 17700; B 1800 200 16300 17500; B 1800 200 35700 17500; B 1800 200 16100 17300; B 1800 200 35900 17300; B 1800 200 15900 17100; B 1800 200 36100 17100; B 1800 200 15700 16900; B 1800 200 36300 16900; B 1800 200 15500 16700; B 1800 200 36500 16700; B 1800 200 15300 16500; B 1800 200 36700 16500; B 1800 200 15100 16300; B 1800 200 36900 16300; B 1800 200 14900 16100; B 1800 200 37100 16100; B 1800 200 14700 15900; B 1800 200 37300 15900; B 1800 200 14500 15700; B 1800 200 37500 15700; B 1800 200 14300 15500; B 1800 200 37700 15500; B 1800 200 14100 15300; B 1800 200 37900 15300; B 1800 200 13900 15100; B 1800 200 38100 15100; B 1800 200 13700 14900; B 1800 200 38300 14900; B 1800 200 13500 14700; B 1800 200 38500 14700; B 1800 200 13300 14500; B 1800 200 38700 14500; B 1800 200 13100 14300; B 1800 200 38900 14300; B 1800 200 12900 14100; B 1800 200 39100 14100; B 1800 200 12700 13900; B 1800 200 39300 13900; B 1800 200 12500 13700; B 1800 200 39500 13700; B 1800 200 12300 13500; B 1800 200 39700 13500; B 1800 200 12100 13300; B 1800 200 39900 13300; B 1800 200 11900 13100; B 1800 200 40100 13100; B 1800 200 11700 12900; B 1800 200 40300 12900; B 1800 200 11500 12700; B 1800 200 40500 12700; B 1800 200 11300 12500; B 1800 200 40700 12500; B 1800 200 11100 12300; B 1800 200 40900 12300; B 1800 200 10900 12100; B 1800 200 41100 12100; B 1800 200 10700 11900; B 1800 200 41300 11900; B 1800 200 10500 11700; B 1800 200 41500 11700; B 1800 200 10300 11500; B 1800 200 41700 11500; B 1800 200 10100 11300; B 1800 200 41900 11300; B 1800 200 9900 11100; B 1800 200 42100 11100; B 1800 200 9700 10900; B 1800 200 42300 10900; B 1800 200 9500 10700; B 1800 200 42500 10700; B 1800 200 9300 10500; B 1800 200 42700 10500; B 1800 200 9100 10300; B 1800 200 42900 10300; B 1800 200 8900 10100; B 1800 200 43100 10100; B 1800 200 8700 9900; B 1800 200 43300 9900; B 1800 200 8500 9700; B 1800 200 43500 9700; B 1800 200 8300 9500; B 1800 200 43700 9500; B 1800 200 8100 9300; B 1800 200 43900 9300; B 1800 200 7900 9100; B 1800 200 44100 9100; B 1800 200 7700 8900; B 1800 200 44300 8900; B 1800 200 7500 8700; B 1800 200 44500 8700; B 1800 200 7300 8500; B 1800 200 44700 8500; B 1800 200 7100 8300; B 1800 200 44900 8300; B 1800 200 6900 8100; B 1800 200 45100 8100; B 1800 200 6700 7900; B 1800 200 45300 7900; B 1800 200 6500 7700; B 1800 200 45500 7700; B 1800 200 6300 7500; B 1800 200 45700 7500; B 1800 200 6100 7300; B 1800 200 45900 7300; B 2800 200 5400 7100; B 2800 200 46600 7100; B 2600 200 5300 6900; B 2600 200 46700 6900; B 2400 200 5200 6700; B 2400 200 46800 6700; B 2200 200 5100 6500; B 2200 200 46900 6500; B 2000 5200 5000 3800; B 2000 5200 47000 3800; L CMF; B 2000 2000 51000 52200; B 6000 1200 3000 48600; B 6000 1200 49000 48600; B 6200 200 3100 47900; B 6200 200 48900 47900; B 6400 200 3200 47700; B 6400 200 48800 47700; B 6600 200 3300 47500; B 6600 200 48700 47500; B 6800 200 3400 47300; B 6800 200 48600 47300; B 1800 200 6100 47100; B 1800 200 45900 47100; B 1800 200 6300 46900; B 1800 200 45700 46900; B 1800 200 6500 46700; B 1800 200 45500 46700; B 1800 200 6700 46500; B 1800 200 45300 46500; B 1800 200 6900 46300; B 1800 200 45100 46300; B 1800 200 7100 46100; B 1800 200 44900 46100; B 1800 200 7300 45900; B 1800 200 44700 45900; B 1800 200 7500 45700; B 1800 200 44500 45700; B 1800 200 7700 45500; B 1800 200 44300 45500; B 1800 200 7900 45300; B 1800 200 44100 45300; B 1800 200 8100 45100; B 1800 200 43900 45100; B 1800 200 8300 44900; B 1800 200 43700 44900; B 1800 200 8500 44700; B 1800 200 43500 44700; B 1800 200 8700 44500; B 1800 200 43300 44500; B 1800 200 8900 44300; B 1800 200 43100 44300; B 1800 200 9100 44100; B 1800 200 42900 44100; B 1800 200 9300 43900; B 1800 200 42700 43900; B 1800 200 9500 43700; B 1800 200 42500 43700; B 1800 200 9700 43500; B 1800 200 42300 43500; B 1800 200 9900 43300; B 1800 200 42100 43300; B 1800 200 10100 43100; B 1800 200 41900 43100; B 1800 200 10300 42900; B 1800 200 41700 42900; B 1800 200 10500 42700; B 1800 200 41500 42700; B 1800 200 10700 42500; B 1800 200 41300 42500; B 1800 200 10900 42300; B 1800 200 41100 42300; B 1800 200 11100 42100; B 1800 200 40900 42100; B 1800 200 11300 41900; B 1800 200 40700 41900; B 1800 200 11500 41700; B 1800 200 40500 41700; B 1800 200 11700 41500; B 1800 200 40300 41500; B 1800 200 11900 41300; B 1800 200 40100 41300; B 1800 200 12100 41100; B 1800 200 39900 41100; B 1800 200 12300 40900; B 1800 200 39700 40900; B 1800 200 12500 40700; B 1800 200 39500 40700; B 1800 200 12700 40500; B 1800 200 39300 40500; B 1800 200 12900 40300; B 1800 200 39100 40300; B 1800 200 13100 40100; B 1800 200 38900 40100; B 1800 200 13300 39900; B 1800 200 38700 39900; B 1800 200 13500 39700; B 1800 200 38500 39700; B 1800 200 13700 39500; B 1800 200 38300 39500; B 1800 200 13900 39300; B 1800 200 38100 39300; B 1800 200 14100 39100; B 1800 200 37900 39100; B 1800 200 14300 38900; B 1800 200 37700 38900; B 1800 200 14500 38700; B 1800 200 37500 38700; B 1800 200 14700 38500; B 1800 200 37300 38500; B 1800 200 14900 38300; B 1800 200 37100 38300; B 1800 200 15100 38100; B 1800 200 36900 38100; B 1800 200 15300 37900; B 1800 200 36700 37900; B 1800 200 15500 37700; B 1800 200 36500 37700; B 1800 200 15700 37500; B 1800 200 36300 37500; B 1800 200 15900 37300; B 1800 200 36100 37300; B 1800 200 16100 37100; B 1800 200 35900 37100; B 1800 200 16300 36900; B 1800 200 35700 36900; B 1800 200 16500 36700; B 1800 200 35500 36700; B 1800 200 16700 36500; B 1800 200 35300 36500; B 1800 200 16900 36300; B 1800 200 35100 36300; B 19600 200 26000 36100; B 19200 200 26000 35900; B 18800 200 26000 35700; B 18400 200 26000 35500; B 18000 16400 26000 27200; B 18400 200 26000 18900; B 18800 200 26000 18700; B 19200 200 26000 18500; B 19600 200 26000 18300; B 1800 200 16900 18100; B 1800 200 35100 18100; B 1800 200 16700 17900; B 1800 200 35300 17900; B 1800 200 16500 17700; B 1800 200 35500 17700; B 1800 200 16300 17500; B 1800 200 35700 17500; B 1800 200 16100 17300; B 1800 200 35900 17300; B 1800 200 15900 17100; B 1800 200 36100 17100; B 1800 200 15700 16900; B 1800 200 36300 16900; B 1800 200 15500 16700; B 1800 200 36500 16700; B 1800 200 15300 16500; B 1800 200 36700 16500; B 1800 200 15100 16300; B 1800 200 36900 16300; B 1800 200 14900 16100; B 1800 200 37100 16100; B 1800 200 14700 15900; B 1800 200 37300 15900; B 1800 200 14500 15700; B 1800 200 37500 15700; B 1800 200 14300 15500; B 1800 200 37700 15500; B 1800 200 14100 15300; B 1800 200 37900 15300; B 1800 200 13900 15100; B 1800 200 38100 15100; B 1800 200 13700 14900; B 1800 200 38300 14900; B 1800 200 13500 14700; B 1800 200 38500 14700; B 1800 200 13300 14500; B 1800 200 38700 14500; B 1800 200 13100 14300; B 1800 200 38900 14300; B 1800 200 12900 14100; B 1800 200 39100 14100; B 1800 200 12700 13900; B 1800 200 39300 13900; B 1800 200 12500 13700; B 1800 200 39500 13700; B 1800 200 12300 13500; B 1800 200 39700 13500; B 1800 200 12100 13300; B 1800 200 39900 13300; B 1800 200 11900 13100; B 1800 200 40100 13100; B 1800 200 11700 12900; B 1800 200 40300 12900; B 1800 200 11500 12700; B 1800 200 40500 12700; B 1800 200 11300 12500; B 1800 200 40700 12500; B 1800 200 11100 12300; B 1800 200 40900 12300; B 1800 200 10900 12100; B 1800 200 41100 12100; B 1800 200 10700 11900; B 1800 200 41300 11900; B 1800 200 10500 11700; B 1800 200 41500 11700; B 1800 200 10300 11500; B 1800 200 41700 11500; B 1800 200 10100 11300; B 1800 200 41900 11300; B 1800 200 9900 11100; B 1800 200 42100 11100; B 1800 200 9700 10900; B 1800 200 42300 10900; B 1800 200 9500 10700; B 1800 200 42500 10700; B 1800 200 9300 10500; B 1800 200 42700 10500; B 1800 200 9100 10300; B 1800 200 42900 10300; B 1800 200 8900 10100; B 1800 200 43100 10100; B 1800 200 8700 9900; B 1800 200 43300 9900; B 1800 200 8500 9700; B 1800 200 43500 9700; B 1800 200 8300 9500; B 1800 200 43700 9500; B 1800 200 8100 9300; B 1800 200 43900 9300; B 1800 200 7900 9100; B 1800 200 44100 9100; B 1800 200 7700 8900; B 1800 200 44300 8900; B 1800 200 7500 8700; B 1800 200 44500 8700; B 1800 200 7300 8500; B 1800 200 44700 8500; B 1800 200 7100 8300; B 1800 200 44900 8300; B 1800 200 6900 8100; B 1800 200 45100 8100; B 1800 200 6700 7900; B 1800 200 45300 7900; B 1800 200 6500 7700; B 1800 200 45500 7700; B 1800 200 6300 7500; B 1800 200 45700 7500; B 1800 200 6100 7300; B 1800 200 45900 7300; B 6800 200 3400 7100; B 6800 200 48600 7100; B 6600 200 3300 6900; B 6600 200 48700 6900; B 6400 200 3200 6700; B 6400 200 48800 6700; B 6200 200 3100 6500; B 6200 200 48900 6500; B 6000 1200 3000 5800; B 6000 1200 49000 5800; B 2000 3200 1000 1600; L CPG; B 2000 200 51000 53100; B 2200 200 50900 52900; B 2400 200 50800 52700; B 2600 200 50700 52500; B 2800 200 50600 52300; B 3000 200 50500 52100; B 3200 200 50400 51900; B 3400 200 50300 51700; B 3600 200 50200 51500; B 3800 200 50100 51300; B 3800 200 49900 51100; B 3800 200 49700 50900; B 3800 200 49500 50700; B 3800 200 49300 50500; B 3800 200 49100 50300; B 3800 200 48900 50100; B 3800 200 48700 49900; B 3800 200 48500 49700; B 3800 200 48300 49500; B 3800 200 48100 49300; B 3800 200 47900 49100; B 3800 200 47700 48900; B 3800 200 47500 48700; B 3800 200 47300 48500; B 3800 200 47100 48300; B 3800 200 46900 48100; B 3800 200 46700 47900; B 3800 200 46500 47700; B 3800 200 46300 47500; B 3800 200 46100 47300; B 3800 200 45900 47100; B 3800 200 45700 46900; B 3800 200 45500 46700; B 3800 200 45300 46500; B 3800 200 45100 46300; B 3800 200 44900 46100; B 3800 200 44700 45900; B 3800 200 44500 45700; B 3800 200 44300 45500; B 3800 200 44100 45300; B 3800 200 43900 45100; B 3800 200 43700 44900; B 3800 200 43500 44700; B 3800 200 43300 44500; B 3800 200 43100 44300; B 3800 200 42900 44100; B 3800 200 42700 43900; B 3800 200 42500 43700; B 3800 200 42300 43500; B 3800 200 42100 43300; B 3800 200 41900 43100; B 3800 200 41700 42900; B 3800 200 41500 42700; B 3800 200 41300 42500; B 3800 200 41100 42300; B 3800 200 40900 42100; B 3800 200 40700 41900; B 3800 200 40500 41700; B 3800 200 40300 41500; B 3800 200 40100 41300; B 3800 200 39900 41100; B 3800 200 39700 40900; B 3800 200 39500 40700; B 3800 200 39300 40500; B 3800 200 39100 40300; B 3800 200 38900 40100; B 3800 200 38700 39900; B 3800 200 38500 39700; B 3800 200 38300 39500; B 3800 200 38100 39300; B 3800 200 37900 39100; B 3800 200 37700 38900; B 3800 200 37500 38700; B 3800 200 37300 38500; B 3800 200 37100 38300; B 3800 200 36900 38100; B 3800 200 36700 37900; B 3800 200 36500 37700; B 3800 200 36300 37500; B 3800 200 36100 37300; B 3800 200 35900 37100; B 3800 200 35700 36900; B 3800 200 35500 36700; B 3800 200 35300 36500; B 3800 200 35100 36300; B 3800 200 34900 36100; B 3800 200 34700 35900; B 3800 200 34500 35700; B 3800 200 34300 35500; B 3600 200 34200 35300; B 17800 200 26900 35100; B 17600 200 26800 34900; B 17400 200 26700 34700; B 17200 200 26600 34500; B 17000 200 26500 34300; B 16800 200 26400 34100; B 16600 200 26300 33900; B 16400 200 26200 33700; B 1600 800 18800 33200; B 16000 1600 26000 32000; B 1600 800 33200 30800; B 16000 1600 26000 29600; B 1600 800 18800 28400; B 16000 1600 26000 27200; B 1600 800 33200 26000; B 16000 1600 26000 24800; B 1600 800 18800 23600; B 16000 1600 26000 22400; B 1600 800 33200 21200; B 16400 200 25800 20700; B 16600 200 25700 20500; B 16800 200 25600 20300; B 17000 200 25500 20100; B 17200 200 25400 19900; B 17400 200 25300 19700; B 17600 200 25200 19500; B 17800 200 25100 19300; B 3600 200 17800 19100; B 3800 200 17700 18900; B 3800 200 17500 18700; B 3800 200 17300 18500; B 3800 200 17100 18300; B 3800 200 16900 18100; B 3800 200 16700 17900; B 3800 200 16500 17700; B 3800 200 16300 17500; B 3800 200 16100 17300; B 3800 200 15900 17100; B 3800 200 15700 16900; B 3800 200 15500 16700; B 3800 200 15300 16500; B 3800 200 15100 16300; B 3800 200 14900 16100; B 3800 200 14700 15900; B 3800 200 14500 15700; B 3800 200 14300 15500; B 3800 200 14100 15300; B 3800 200 13900 15100; B 3800 200 13700 14900; B 3800 200 13500 14700; B 3800 200 13300 14500; B 3800 200 13100 14300; B 3800 200 12900 14100; B 3800 200 12700 13900; B 3800 200 12500 13700; B 3800 200 12300 13500; B 3800 200 12100 13300; B 3800 200 11900 13100; B 3800 200 11700 12900; B 3800 200 11500 12700; B 3800 200 11300 12500; B 3800 200 11100 12300; B 3800 200 10900 12100; B 3800 200 10700 11900; B 3800 200 10500 11700; B 3800 200 10300 11500; B 3800 200 10100 11300; B 3800 200 9900 11100; B 3800 200 9700 10900; B 3800 200 9500 10700; B 3800 200 9300 10500; B 3800 200 9100 10300; B 3800 200 8900 10100; B 3800 200 8700 9900; B 3800 200 8500 9700; B 3800 200 8300 9500; B 3800 200 8100 9300; B 3800 200 7900 9100; B 3800 200 7700 8900; B 3800 200 7500 8700; B 3800 200 7300 8500; B 3800 200 7100 8300; B 3800 200 6900 8100; B 3800 200 6700 7900; B 3800 200 6500 7700; B 3800 200 6300 7500; B 3800 200 6100 7300; B 3800 200 5900 7100; B 3800 200 5700 6900; B 3800 200 5500 6700; B 3800 200 5300 6500; B 3800 200 5100 6300; B 3800 200 4900 6100; B 3800 200 4700 5900; B 3800 200 4500 5700; B 3800 200 4300 5500; B 3800 200 4100 5300; B 3800 200 3900 5100; B 3800 200 3700 4900; B 3800 200 3500 4700; B 3800 200 3300 4500; B 3800 200 3100 4300; B 3800 200 2900 4100; B 3800 200 2700 3900; B 3800 200 2500 3700; B 3800 200 2300 3500; B 3800 200 2100 3300; B 3800 200 1900 3100; B 3600 200 1800 2900; B 3400 200 1700 2700; B 3200 200 1600 2500; B 3000 200 1500 2300; B 2800 200 1400 2100; B 2600 200 1300 1900; B 2400 200 1200 1700; B 2200 200 1100 1500; B 2000 200 1000 1300; L CAA; B 42000 200 25000 49100; B 41800 200 24900 48900; B 41600 200 24800 48700; B 41400 200 24700 48500; B 41200 200 24600 48300; B 41000 200 24500 48100; B 40800 200 24400 47900; B 40600 200 24300 47700; B 40400 200 24200 47500; B 40200 200 24100 47300; B 2000 4000 5000 45200; B 32000 200 26000 47100; B 200 200 47900 47100; B 31600 200 26000 46900; B 400 200 47800 46900; B 31200 200 26000 46700; B 600 200 47700 46700; B 30800 200 26000 46500; B 800 200 47600 46500; B 30400 200 26000 46300; B 1000 200 47500 46300; B 30000 200 26000 46100; B 1200 200 47400 46100; B 29600 200 26000 45900; B 1400 200 47300 45900; B 29200 200 26000 45700; B 1600 200 47200 45700; B 28800 200 26000 45500; B 1800 200 47100 45500; B 28400 200 26000 45300; B 28000 200 26000 45100; B 27600 200 26000 44900; B 27200 200 26000 44700; B 26800 200 26000 44500; B 26400 200 26000 44300; B 26000 200 26000 44100; B 25600 200 26000 43900; B 25200 200 26000 43700; B 24800 200 26000 43500; B 24400 200 26000 43300; B 2000 2200 47000 44300; B 2200 200 5100 43100; B 24000 200 26000 43100; B 2200 200 46900 43100; B 2400 200 5200 42900; B 23600 200 26000 42900; B 2400 200 46800 42900; B 2600 200 5300 42700; B 23200 200 26000 42700; B 2600 200 46700 42700; B 2800 200 5400 42500; B 22800 200 26000 42500; B 2800 200 46600 42500; B 3000 200 5500 42300; B 22400 200 26000 42300; B 3000 200 46500 42300; B 3200 200 5600 42100; B 22000 200 26000 42100; B 3200 200 46400 42100; B 3400 200 5700 41900; B 21600 200 26000 41900; B 3400 200 46300 41900; B 3600 200 5800 41700; B 21200 200 26000 41700; B 3600 200 46200 41700; B 3800 200 5900 41500; B 20800 200 26000 41500; B 3800 200 46100 41500; B 4000 200 6000 41300; B 20400 200 26000 41300; B 4000 200 46000 41300; B 4200 200 6100 41100; B 20000 200 26000 41100; B 4200 200 45900 41100; B 4400 200 6200 40900; B 19600 200 26000 40900; B 4400 200 45800 40900; B 4600 200 6300 40700; B 19200 200 26000 40700; B 4600 200 45700 40700; B 4800 200 6400 40500; B 18800 200 26000 40500; B 4800 200 45600 40500; B 5000 200 6500 40300; B 18400 200 26000 40300; B 5000 200 45500 40300; B 5200 200 6600 40100; B 18000 200 26000 40100; B 5200 200 45400 40100; B 5400 200 6700 39900; B 17600 200 26000 39900; B 5400 200 45300 39900; B 5600 200 6800 39700; B 17200 200 26000 39700; B 5600 200 45200 39700; B 5800 200 6900 39500; B 16800 200 26000 39500; B 5800 200 45100 39500; B 6000 200 7000 39300; B 16400 200 26000 39300; B 6000 200 45000 39300; B 6200 200 7100 39100; B 16000 200 26000 39100; B 6200 200 44900 39100; B 6400 200 7200 38900; B 15600 200 26000 38900; B 6400 200 44800 38900; B 6600 200 7300 38700; B 15200 200 26000 38700; B 6600 200 44700 38700; B 6800 200 7400 38500; B 14800 200 26000 38500; B 6800 200 44600 38500; B 7000 200 7500 38300; B 14400 200 26000 38300; B 7000 200 44500 38300; B 7200 200 7600 38100; B 14000 200 26000 38100; B 7200 200 44400 38100; B 7400 200 7700 37900; B 13600 200 26000 37900; B 7400 200 44300 37900; B 7600 200 7800 37700; B 13200 200 26000 37700; B 7600 200 44200 37700; B 7800 200 7900 37500; B 12800 200 26000 37500; B 7800 200 44100 37500; B 8000 200 8000 37300; B 12400 200 26000 37300; B 8000 200 44000 37300; B 8200 200 8100 37100; B 8200 200 43900 37100; B 8400 200 8200 36900; B 8400 200 43800 36900; B 8600 200 8300 36700; B 8600 200 43700 36700; B 8800 200 8400 36500; B 8800 200 43600 36500; B 9000 200 8500 36300; B 9000 200 43500 36300; B 9200 200 8600 36100; B 9200 200 43400 36100; B 9400 200 8700 35900; B 9400 200 43300 35900; B 9600 200 8800 35700; B 9600 200 43200 35700; B 9800 200 8900 35500; B 9800 200 43100 35500; B 10000 200 9000 35300; B 10000 200 43000 35300; B 10200 200 9100 35100; B 10200 200 42900 35100; B 10400 200 9200 34900; B 10400 200 42800 34900; B 10600 200 9300 34700; B 10600 200 42700 34700; B 10800 200 9400 34500; B 10800 200 42600 34500; B 11000 200 9500 34300; B 11000 200 42500 34300; B 11200 200 9600 34100; B 11200 200 42400 34100; B 11400 200 9700 33900; B 11400 200 42300 33900; B 11600 200 9800 33700; B 11600 200 42200 33700; B 11800 200 9900 33500; B 11800 200 42100 33500; B 12000 12400 10000 27200; B 12000 12400 42000 27200; B 11800 200 9900 20900; B 11800 200 42100 20900; B 11600 200 9800 20700; B 11600 200 42200 20700; B 11400 200 9700 20500; B 11400 200 42300 20500; B 11200 200 9600 20300; B 11200 200 42400 20300; B 11000 200 9500 20100; B 11000 200 42500 20100; B 10800 200 9400 19900; B 10800 200 42600 19900; B 10600 200 9300 19700; B 10600 200 42700 19700; B 10400 200 9200 19500; B 10400 200 42800 19500; B 10200 200 9100 19300; B 10200 200 42900 19300; B 10000 200 9000 19100; B 10000 200 43000 19100; B 9800 200 8900 18900; B 9800 200 43100 18900; B 9600 200 8800 18700; B 9600 200 43200 18700; B 9400 200 8700 18500; B 9400 200 43300 18500; B 9200 200 8600 18300; B 9200 200 43400 18300; B 9000 200 8500 18100; B 9000 200 43500 18100; B 8800 200 8400 17900; B 8800 200 43600 17900; B 8600 200 8300 17700; B 8600 200 43700 17700; B 8400 200 8200 17500; B 8400 200 43800 17500; B 8200 200 8100 17300; B 8200 200 43900 17300; B 8000 200 8000 17100; B 12400 200 26000 17100; B 8000 200 44000 17100; B 7800 200 7900 16900; B 12800 200 26000 16900; B 7800 200 44100 16900; B 7600 200 7800 16700; B 13200 200 26000 16700; B 7600 200 44200 16700; B 7400 200 7700 16500; B 13600 200 26000 16500; B 7400 200 44300 16500; B 7200 200 7600 16300; B 14000 200 26000 16300; B 7200 200 44400 16300; B 7000 200 7500 16100; B 14400 200 26000 16100; B 7000 200 44500 16100; B 6800 200 7400 15900; B 14800 200 26000 15900; B 6800 200 44600 15900; B 6600 200 7300 15700; B 15200 200 26000 15700; B 6600 200 44700 15700; B 6400 200 7200 15500; B 15600 200 26000 15500; B 6400 200 44800 15500; B 6200 200 7100 15300; B 16000 200 26000 15300; B 6200 200 44900 15300; B 6000 200 7000 15100; B 16400 200 26000 15100; B 6000 200 45000 15100; B 5800 200 6900 14900; B 16800 200 26000 14900; B 5800 200 45100 14900; B 5600 200 6800 14700; B 17200 200 26000 14700; B 5600 200 45200 14700; B 5400 200 6700 14500; B 17600 200 26000 14500; B 5400 200 45300 14500; B 5200 200 6600 14300; B 18000 200 26000 14300; B 5200 200 45400 14300; B 5000 200 6500 14100; B 18400 200 26000 14100; B 5000 200 45500 14100; B 4800 200 6400 13900; B 18800 200 26000 13900; B 4800 200 45600 13900; B 4600 200 6300 13700; B 19200 200 26000 13700; B 4600 200 45700 13700; B 4400 200 6200 13500; B 19600 200 26000 13500; B 4400 200 45800 13500; B 4200 200 6100 13300; B 20000 200 26000 13300; B 4200 200 45900 13300; B 4000 200 6000 13100; B 20400 200 26000 13100; B 4000 200 46000 13100; B 3800 200 5900 12900; B 20800 200 26000 12900; B 3800 200 46100 12900; B 3600 200 5800 12700; B 21200 200 26000 12700; B 3600 200 46200 12700; B 3400 200 5700 12500; B 21600 200 26000 12500; B 3400 200 46300 12500; B 3200 200 5600 12300; B 22000 200 26000 12300; B 3200 200 46400 12300; B 3000 200 5500 12100; B 22400 200 26000 12100; B 3000 200 46500 12100; B 2800 200 5400 11900; B 22800 200 26000 11900; B 2800 200 46600 11900; B 2600 200 5300 11700; B 23200 200 26000 11700; B 2600 200 46700 11700; B 2400 200 5200 11500; B 23600 200 26000 11500; B 2400 200 46800 11500; B 2200 200 5100 11300; B 24000 200 26000 11300; B 2200 200 46900 11300; B 2000 2200 5000 10100; B 24400 200 26000 11100; B 24800 200 26000 10900; B 25200 200 26000 10700; B 25600 200 26000 10500; B 26000 200 26000 10300; B 26400 200 26000 10100; B 26800 200 26000 9900; B 27200 200 26000 9700; B 27600 200 26000 9500; B 28000 200 26000 9300; B 28400 200 26000 9100; B 1800 200 4900 8900; B 28800 200 26000 8900; B 1600 200 4800 8700; B 29200 200 26000 8700; B 1400 200 4700 8500; B 29600 200 26000 8500; B 1200 200 4600 8300; B 30000 200 26000 8300; B 1000 200 4500 8100; B 30400 200 26000 8100; B 800 200 4400 7900; B 30800 200 26000 7900; B 600 200 4300 7700; B 31200 200 26000 7700; B 400 200 4200 7500; B 31600 200 26000 7500; B 200 200 4100 7300; B 32000 200 26000 7300; B 2000 4000 47000 9200; B 40200 200 27900 7100; B 40400 200 27800 6900; B 40600 200 27700 6700; B 40800 200 27600 6500; B 41000 200 27500 6300; B 41200 200 27400 6100; B 41400 200 27300 5900; B 41600 200 27200 5700; B 41800 200 27100 5500; B 42000 200 27000 5300; L CVA; B 32000 200 26000 47100; B 31600 200 26000 46900; B 31200 200 26000 46700; B 30800 200 26000 46500; B 30400 200 26000 46300; B 30000 200 26000 46100; B 29600 200 26000 45900; B 29200 200 26000 45700; B 28800 200 26000 45500; B 28400 200 26000 45300; B 28000 200 26000 45100; B 27600 200 26000 44900; B 27200 200 26000 44700; B 26800 200 26000 44500; B 26400 200 26000 44300; B 26000 200 26000 44100; B 25600 200 26000 43900; B 25200 200 26000 43700; B 24800 200 26000 43500; B 24400 200 26000 43300; B 200 200 6100 43100; B 24000 200 26000 43100; B 200 200 45900 43100; B 400 200 6200 42900; B 23600 200 26000 42900; B 400 200 45800 42900; B 600 200 6300 42700; B 23200 200 26000 42700; B 600 200 45700 42700; B 800 200 6400 42500; B 22800 200 26000 42500; B 800 200 45600 42500; B 1000 200 6500 42300; B 22400 200 26000 42300; B 1000 200 45500 42300; B 1200 200 6600 42100; B 22000 200 26000 42100; B 1200 200 45400 42100; B 1400 200 6700 41900; B 21600 200 26000 41900; B 1400 200 45300 41900; B 1600 200 6800 41700; B 21200 200 26000 41700; B 1600 200 45200 41700; B 1800 200 6900 41500; B 20800 200 26000 41500; B 1800 200 45100 41500; B 2000 200 7000 41300; B 20400 200 26000 41300; B 2000 200 45000 41300; B 2200 200 7100 41100; B 20000 200 26000 41100; B 2200 200 44900 41100; B 2400 200 7200 40900; B 19600 200 26000 40900; B 2400 200 44800 40900; B 2600 200 7300 40700; B 19200 200 26000 40700; B 2600 200 44700 40700; B 2800 200 7400 40500; B 18800 200 26000 40500; B 2800 200 44600 40500; B 3000 200 7500 40300; B 18400 200 26000 40300; B 3000 200 44500 40300; B 3200 200 7600 40100; B 18000 200 26000 40100; B 3200 200 44400 40100; B 3400 200 7700 39900; B 17600 200 26000 39900; B 3400 200 44300 39900; B 3600 200 7800 39700; B 17200 200 26000 39700; B 3600 200 44200 39700; B 3800 200 7900 39500; B 16800 200 26000 39500; B 3800 200 44100 39500; B 4000 200 8000 39300; B 16400 200 26000 39300; B 4000 200 44000 39300; B 4200 200 8100 39100; B 16000 200 26000 39100; B 4200 200 43900 39100; B 4400 200 8200 38900; B 15600 200 26000 38900; B 4400 200 43800 38900; B 4600 200 8300 38700; B 15200 200 26000 38700; B 4600 200 43700 38700; B 4800 200 8400 38500; B 14800 200 26000 38500; B 4800 200 43600 38500; B 5000 200 8500 38300; B 14400 200 26000 38300; B 5000 200 43500 38300; B 5200 200 8600 38100; B 14000 200 26000 38100; B 5200 200 43400 38100; B 5400 200 8700 37900; B 13600 200 26000 37900; B 5400 200 43300 37900; B 5600 200 8800 37700; B 13200 200 26000 37700; B 5600 200 43200 37700; B 5800 200 8900 37500; B 12800 200 26000 37500; B 5800 200 43100 37500; B 6000 200 9000 37300; B 12400 200 26000 37300; B 6000 200 43000 37300; B 6200 200 9100 37100; B 6200 200 42900 37100; B 6400 200 9200 36900; B 6400 200 42800 36900; B 6600 200 9300 36700; B 6600 200 42700 36700; B 6800 200 9400 36500; B 6800 200 42600 36500; B 7000 200 9500 36300; B 7000 200 42500 36300; B 7200 200 9600 36100; B 7200 200 42400 36100; B 7400 200 9700 35900; B 7400 200 42300 35900; B 7600 200 9800 35700; B 7600 200 42200 35700; B 7800 200 9900 35500; B 7800 200 42100 35500; B 8000 200 10000 35300; B 8000 200 42000 35300; B 8200 200 10100 35100; B 8200 200 41900 35100; B 8400 200 10200 34900; B 8400 200 41800 34900; B 8600 200 10300 34700; B 8600 200 41700 34700; B 8800 200 10400 34500; B 8800 200 41600 34500; B 9000 200 10500 34300; B 9000 200 41500 34300; B 9200 200 10600 34100; B 9200 200 41400 34100; B 9400 200 10700 33900; B 9400 200 41300 33900; B 9600 200 10800 33700; B 9600 200 41200 33700; B 9800 200 10900 33500; B 9800 200 41100 33500; B 10000 12400 11000 27200; B 10000 12400 41000 27200; B 9800 200 10900 20900; B 9800 200 41100 20900; B 9600 200 10800 20700; B 9600 200 41200 20700; B 9400 200 10700 20500; B 9400 200 41300 20500; B 9200 200 10600 20300; B 9200 200 41400 20300; B 9000 200 10500 20100; B 9000 200 41500 20100; B 8800 200 10400 19900; B 8800 200 41600 19900; B 8600 200 10300 19700; B 8600 200 41700 19700; B 8400 200 10200 19500; B 8400 200 41800 19500; B 8200 200 10100 19300; B 8200 200 41900 19300; B 8000 200 10000 19100; B 8000 200 42000 19100; B 7800 200 9900 18900; B 7800 200 42100 18900; B 7600 200 9800 18700; B 7600 200 42200 18700; B 7400 200 9700 18500; B 7400 200 42300 18500; B 7200 200 9600 18300; B 7200 200 42400 18300; B 7000 200 9500 18100; B 7000 200 42500 18100; B 6800 200 9400 17900; B 6800 200 42600 17900; B 6600 200 9300 17700; B 6600 200 42700 17700; B 6400 200 9200 17500; B 6400 200 42800 17500; B 6200 200 9100 17300; B 6200 200 42900 17300; B 6000 200 9000 17100; B 12400 200 26000 17100; B 6000 200 43000 17100; B 5800 200 8900 16900; B 12800 200 26000 16900; B 5800 200 43100 16900; B 5600 200 8800 16700; B 13200 200 26000 16700; B 5600 200 43200 16700; B 5400 200 8700 16500; B 13600 200 26000 16500; B 5400 200 43300 16500; B 5200 200 8600 16300; B 14000 200 26000 16300; B 5200 200 43400 16300; B 5000 200 8500 16100; B 14400 200 26000 16100; B 5000 200 43500 16100; B 4800 200 8400 15900; B 14800 200 26000 15900; B 4800 200 43600 15900; B 4600 200 8300 15700; B 15200 200 26000 15700; B 4600 200 43700 15700; B 4400 200 8200 15500; B 15600 200 26000 15500; B 4400 200 43800 15500; B 4200 200 8100 15300; B 16000 200 26000 15300; B 4200 200 43900 15300; B 4000 200 8000 15100; B 16400 200 26000 15100; B 4000 200 44000 15100; B 3800 200 7900 14900; B 16800 200 26000 14900; B 3800 200 44100 14900; B 3600 200 7800 14700; B 17200 200 26000 14700; B 3600 200 44200 14700; B 3400 200 7700 14500; B 17600 200 26000 14500; B 3400 200 44300 14500; B 3200 200 7600 14300; B 18000 200 26000 14300; B 3200 200 44400 14300; B 3000 200 7500 14100; B 18400 200 26000 14100; B 3000 200 44500 14100; B 2800 200 7400 13900; B 18800 200 26000 13900; B 2800 200 44600 13900; B 2600 200 7300 13700; B 19200 200 26000 13700; B 2600 200 44700 13700; B 2400 200 7200 13500; B 19600 200 26000 13500; B 2400 200 44800 13500; B 2200 200 7100 13300; B 20000 200 26000 13300; B 2200 200 44900 13300; B 2000 200 7000 13100; B 20400 200 26000 13100; B 2000 200 45000 13100; B 1800 200 6900 12900; B 20800 200 26000 12900; B 1800 200 45100 12900; B 1600 200 6800 12700; B 21200 200 26000 12700; B 1600 200 45200 12700; B 1400 200 6700 12500; B 21600 200 26000 12500; B 1400 200 45300 12500; B 1200 200 6600 12300; B 22000 200 26000 12300; B 1200 200 45400 12300; B 1000 200 6500 12100; B 22400 200 26000 12100; B 1000 200 45500 12100; B 800 200 6400 11900; B 22800 200 26000 11900; B 800 200 45600 11900; B 600 200 6300 11700; B 23200 200 26000 11700; B 600 200 45700 11700; B 400 200 6200 11500; B 23600 200 26000 11500; B 400 200 45800 11500; B 200 200 6100 11300; B 24000 200 26000 11300; B 200 200 45900 11300; B 24400 200 26000 11100; B 24800 200 26000 10900; B 25200 200 26000 10700; B 25600 200 26000 10500; B 26000 200 26000 10300; B 26400 200 26000 10100; B 26800 200 26000 9900; B 27200 200 26000 9700; B 27600 200 26000 9500; B 28000 200 26000 9300; B 28400 200 26000 9100; B 28800 200 26000 8900; B 29200 200 26000 8700; B 29600 200 26000 8500; B 30000 200 26000 8300; B 30400 200 26000 8100; B 30800 200 26000 7900; B 31200 200 26000 7700; B 31600 200 26000 7500; B 32000 200 26000 7300; L CCA; B 32000 200 26000 47100; B 31600 200 26000 46900; B 31200 200 26000 46700; B 30800 200 26000 46500; B 30400 200 26000 46300; B 30000 200 26000 46100; B 29600 200 26000 45900; B 29200 200 26000 45700; B 28800 200 26000 45500; B 28400 200 26000 45300; B 28000 200 26000 45100; B 27600 200 26000 44900; B 27200 200 26000 44700; B 26800 200 26000 44500; B 26400 200 26000 44300; B 26000 200 26000 44100; B 25600 200 26000 43900; B 25200 200 26000 43700; B 24800 200 26000 43500; B 24400 200 26000 43300; B 200 200 6100 43100; B 24000 200 26000 43100; B 200 200 45900 43100; B 400 200 6200 42900; B 23600 200 26000 42900; B 400 200 45800 42900; B 600 200 6300 42700; B 23200 200 26000 42700; B 600 200 45700 42700; B 800 200 6400 42500; B 22800 200 26000 42500; B 800 200 45600 42500; B 1000 200 6500 42300; B 22400 200 26000 42300; B 1000 200 45500 42300; B 1200 200 6600 42100; B 22000 200 26000 42100; B 1200 200 45400 42100; B 1400 200 6700 41900; B 21600 200 26000 41900; B 1400 200 45300 41900; B 1600 200 6800 41700; B 21200 200 26000 41700; B 1600 200 45200 41700; B 1800 200 6900 41500; B 20800 200 26000 41500; B 1800 200 45100 41500; B 2000 200 7000 41300; B 20400 200 26000 41300; B 2000 200 45000 41300; B 2200 200 7100 41100; B 20000 200 26000 41100; B 2200 200 44900 41100; B 2400 200 7200 40900; B 19600 200 26000 40900; B 2400 200 44800 40900; B 2600 200 7300 40700; B 19200 200 26000 40700; B 2600 200 44700 40700; B 2800 200 7400 40500; B 18800 200 26000 40500; B 2800 200 44600 40500; B 3000 200 7500 40300; B 18400 200 26000 40300; B 3000 200 44500 40300; B 3200 200 7600 40100; B 18000 200 26000 40100; B 3200 200 44400 40100; B 3400 200 7700 39900; B 17600 200 26000 39900; B 3400 200 44300 39900; B 3600 200 7800 39700; B 17200 200 26000 39700; B 3600 200 44200 39700; B 3800 200 7900 39500; B 16800 200 26000 39500; B 3800 200 44100 39500; B 4000 200 8000 39300; B 16400 200 26000 39300; B 4000 200 44000 39300; B 4200 200 8100 39100; B 16000 200 26000 39100; B 4200 200 43900 39100; B 4400 200 8200 38900; B 15600 200 26000 38900; B 4400 200 43800 38900; B 4600 200 8300 38700; B 15200 200 26000 38700; B 4600 200 43700 38700; B 4800 200 8400 38500; B 14800 200 26000 38500; B 4800 200 43600 38500; B 5000 200 8500 38300; B 14400 200 26000 38300; B 5000 200 43500 38300; B 5200 200 8600 38100; B 14000 200 26000 38100; B 5200 200 43400 38100; B 5400 200 8700 37900; B 13600 200 26000 37900; B 5400 200 43300 37900; B 5600 200 8800 37700; B 13200 200 26000 37700; B 5600 200 43200 37700; B 5800 200 8900 37500; B 12800 200 26000 37500; B 5800 200 43100 37500; B 6000 200 9000 37300; B 12400 200 26000 37300; B 6000 200 43000 37300; B 6200 200 9100 37100; B 6200 200 42900 37100; B 6400 200 9200 36900; B 6400 200 42800 36900; B 6600 200 9300 36700; B 6600 200 42700 36700; B 6800 200 9400 36500; B 6800 200 42600 36500; B 7000 200 9500 36300; B 7000 200 42500 36300; B 7200 200 9600 36100; B 7200 200 42400 36100; B 7400 200 9700 35900; B 7400 200 42300 35900; B 7600 200 9800 35700; B 7600 200 42200 35700; B 7800 200 9900 35500; B 7800 200 42100 35500; B 8000 200 10000 35300; B 8000 200 42000 35300; B 8200 200 10100 35100; B 8200 200 41900 35100; B 8400 200 10200 34900; B 8400 200 41800 34900; B 8600 200 10300 34700; B 8600 200 41700 34700; B 8800 200 10400 34500; B 8800 200 41600 34500; B 9000 200 10500 34300; B 9000 200 41500 34300; B 9200 200 10600 34100; B 9200 200 41400 34100; B 9400 200 10700 33900; B 9400 200 41300 33900; B 9600 200 10800 33700; B 9600 200 41200 33700; B 9800 200 10900 33500; B 9800 200 41100 33500; B 10000 12400 11000 27200; B 10000 12400 41000 27200; B 9800 200 10900 20900; B 9800 200 41100 20900; B 9600 200 10800 20700; B 9600 200 41200 20700; B 9400 200 10700 20500; B 9400 200 41300 20500; B 9200 200 10600 20300; B 9200 200 41400 20300; B 9000 200 10500 20100; B 9000 200 41500 20100; B 8800 200 10400 19900; B 8800 200 41600 19900; B 8600 200 10300 19700; B 8600 200 41700 19700; B 8400 200 10200 19500; B 8400 200 41800 19500; B 8200 200 10100 19300; B 8200 200 41900 19300; B 8000 200 10000 19100; B 8000 200 42000 19100; B 7800 200 9900 18900; B 7800 200 42100 18900; B 7600 200 9800 18700; B 7600 200 42200 18700; B 7400 200 9700 18500; B 7400 200 42300 18500; B 7200 200 9600 18300; B 7200 200 42400 18300; B 7000 200 9500 18100; B 7000 200 42500 18100; B 6800 200 9400 17900; B 6800 200 42600 17900; B 6600 200 9300 17700; B 6600 200 42700 17700; B 6400 200 9200 17500; B 6400 200 42800 17500; B 6200 200 9100 17300; B 6200 200 42900 17300; B 6000 200 9000 17100; B 12400 200 26000 17100; B 6000 200 43000 17100; B 5800 200 8900 16900; B 12800 200 26000 16900; B 5800 200 43100 16900; B 5600 200 8800 16700; B 13200 200 26000 16700; B 5600 200 43200 16700; B 5400 200 8700 16500; B 13600 200 26000 16500; B 5400 200 43300 16500; B 5200 200 8600 16300; B 14000 200 26000 16300; B 5200 200 43400 16300; B 5000 200 8500 16100; B 14400 200 26000 16100; B 5000 200 43500 16100; B 4800 200 8400 15900; B 14800 200 26000 15900; B 4800 200 43600 15900; B 4600 200 8300 15700; B 15200 200 26000 15700; B 4600 200 43700 15700; B 4400 200 8200 15500; B 15600 200 26000 15500; B 4400 200 43800 15500; B 4200 200 8100 15300; B 16000 200 26000 15300; B 4200 200 43900 15300; B 4000 200 8000 15100; B 16400 200 26000 15100; B 4000 200 44000 15100; B 3800 200 7900 14900; B 16800 200 26000 14900; B 3800 200 44100 14900; B 3600 200 7800 14700; B 17200 200 26000 14700; B 3600 200 44200 14700; B 3400 200 7700 14500; B 17600 200 26000 14500; B 3400 200 44300 14500; B 3200 200 7600 14300; B 18000 200 26000 14300; B 3200 200 44400 14300; B 3000 200 7500 14100; B 18400 200 26000 14100; B 3000 200 44500 14100; B 2800 200 7400 13900; B 18800 200 26000 13900; B 2800 200 44600 13900; B 2600 200 7300 13700; B 19200 200 26000 13700; B 2600 200 44700 13700; B 2400 200 7200 13500; B 19600 200 26000 13500; B 2400 200 44800 13500; B 2200 200 7100 13300; B 20000 200 26000 13300; B 2200 200 44900 13300; B 2000 200 7000 13100; B 20400 200 26000 13100; B 2000 200 45000 13100; B 1800 200 6900 12900; B 20800 200 26000 12900; B 1800 200 45100 12900; B 1600 200 6800 12700; B 21200 200 26000 12700; B 1600 200 45200 12700; B 1400 200 6700 12500; B 21600 200 26000 12500; B 1400 200 45300 12500; B 1200 200 6600 12300; B 22000 200 26000 12300; B 1200 200 45400 12300; B 1000 200 6500 12100; B 22400 200 26000 12100; B 1000 200 45500 12100; B 800 200 6400 11900; B 22800 200 26000 11900; B 800 200 45600 11900; B 600 200 6300 11700; B 23200 200 26000 11700; B 600 200 45700 11700; B 400 200 6200 11500; B 23600 200 26000 11500; B 400 200 45800 11500; B 200 200 6100 11300; B 24000 200 26000 11300; B 200 200 45900 11300; B 24400 200 26000 11100; B 24800 200 26000 10900; B 25200 200 26000 10700; B 25600 200 26000 10500; B 26000 200 26000 10300; B 26400 200 26000 10100; B 26800 200 26000 9900; B 27200 200 26000 9700; B 27600 200 26000 9500; B 28000 200 26000 9300; B 28400 200 26000 9100; B 28800 200 26000 8900; B 29200 200 26000 8700; B 29600 200 26000 8500; B 30000 200 26000 8300; B 30400 200 26000 8100; B 30800 200 26000 7900; B 31200 200 26000 7700; B 31600 200 26000 7500; B 32000 200 26000 7300; L CCP; B 400 400 51000 52200; B 400 400 1000 2200; L CSP; B 42800 1000 25000 49100; B 42600 200 24900 48500; B 42400 200 24800 48300; B 42200 200 24700 48100; B 42000 200 24600 47900; B 41800 200 24500 47700; B 41600 200 24400 47500; B 1000 200 47900 47500; B 41400 200 24300 47300; B 1200 200 47800 47300; B 41200 200 24200 47100; B 1400 200 47700 47100; B 41000 200 24100 46900; B 1600 200 47600 46900; B 2800 38200 5000 27700; B 1800 200 47500 46700; B 2000 200 47400 46500; B 2200 200 47300 46300; B 2400 200 47200 46100; B 2600 200 47100 45900; B 2600 200 4900 8500; B 2400 200 4800 8300; B 2200 200 4700 8100; B 2000 200 4600 7900; B 1800 200 4500 7700; B 2800 38200 47000 26700; B 1600 200 4400 7500; B 41000 200 27900 7500; B 1400 200 4300 7300; B 41200 200 27800 7300; B 1200 200 4200 7100; B 41400 200 27700 7100; B 1000 200 4100 6900; B 41600 200 27600 6900; B 41800 200 27500 6700; B 42000 200 27400 6500; B 42200 200 27300 6300; B 42400 200 27200 6100; B 42600 200 27100 5900; B 42800 1000 27000 5300; L COG; B 32000 200 26000 47100; B 31600 200 26000 46900; B 31200 200 26000 46700; B 30800 200 26000 46500; B 30400 200 26000 46300; B 30000 200 26000 46100; B 29600 200 26000 45900; B 29200 200 26000 45700; B 28800 200 26000 45500; B 28400 200 26000 45300; B 28000 200 26000 45100; B 27600 200 26000 44900; B 27200 200 26000 44700; B 26800 200 26000 44500; B 26400 200 26000 44300; B 26000 200 26000 44100; B 25600 200 26000 43900; B 25200 200 26000 43700; B 24800 200 26000 43500; B 24400 200 26000 43300; B 200 200 6100 43100; B 24000 200 26000 43100; B 200 200 45900 43100; B 400 200 6200 42900; B 23600 200 26000 42900; B 400 200 45800 42900; B 600 200 6300 42700; B 23200 200 26000 42700; B 600 200 45700 42700; B 800 200 6400 42500; B 22800 200 26000 42500; B 800 200 45600 42500; B 1000 200 6500 42300; B 22400 200 26000 42300; B 1000 200 45500 42300; B 1200 200 6600 42100; B 22000 200 26000 42100; B 1200 200 45400 42100; B 1400 200 6700 41900; B 21600 200 26000 41900; B 1400 200 45300 41900; B 1600 200 6800 41700; B 21200 200 26000 41700; B 1600 200 45200 41700; B 1800 200 6900 41500; B 20800 200 26000 41500; B 1800 200 45100 41500; B 2000 200 7000 41300; B 20400 200 26000 41300; B 2000 200 45000 41300; B 2200 200 7100 41100; B 20000 200 26000 41100; B 2200 200 44900 41100; B 2400 200 7200 40900; B 19600 200 26000 40900; B 2400 200 44800 40900; B 2600 200 7300 40700; B 19200 200 26000 40700; B 2600 200 44700 40700; B 2800 200 7400 40500; B 18800 200 26000 40500; B 2800 200 44600 40500; B 3000 200 7500 40300; B 18400 200 26000 40300; B 3000 200 44500 40300; B 3200 200 7600 40100; B 18000 200 26000 40100; B 3200 200 44400 40100; B 3400 200 7700 39900; B 17600 200 26000 39900; B 3400 200 44300 39900; B 3600 200 7800 39700; B 17200 200 26000 39700; B 3600 200 44200 39700; B 3800 200 7900 39500; B 16800 200 26000 39500; B 3800 200 44100 39500; B 4000 200 8000 39300; B 16400 200 26000 39300; B 4000 200 44000 39300; B 4200 200 8100 39100; B 16000 200 26000 39100; B 4200 200 43900 39100; B 4400 200 8200 38900; B 15600 200 26000 38900; B 4400 200 43800 38900; B 4600 200 8300 38700; B 15200 200 26000 38700; B 4600 200 43700 38700; B 4800 200 8400 38500; B 14800 200 26000 38500; B 4800 200 43600 38500; B 5000 200 8500 38300; B 14400 200 26000 38300; B 5000 200 43500 38300; B 5200 200 8600 38100; B 14000 200 26000 38100; B 5200 200 43400 38100; B 5400 200 8700 37900; B 13600 200 26000 37900; B 5400 200 43300 37900; B 5600 200 8800 37700; B 13200 200 26000 37700; B 5600 200 43200 37700; B 5800 200 8900 37500; B 12800 200 26000 37500; B 5800 200 43100 37500; B 6000 200 9000 37300; B 12400 200 26000 37300; B 6000 200 43000 37300; B 6200 200 9100 37100; B 6200 200 42900 37100; B 6400 200 9200 36900; B 6400 200 42800 36900; B 6600 200 9300 36700; B 6600 200 42700 36700; B 6800 200 9400 36500; B 6800 200 42600 36500; B 7000 200 9500 36300; B 7000 200 42500 36300; B 7200 200 9600 36100; B 7200 200 42400 36100; B 7400 200 9700 35900; B 7400 200 42300 35900; B 7600 200 9800 35700; B 7600 200 42200 35700; B 7800 200 9900 35500; B 7800 200 42100 35500; B 8000 200 10000 35300; B 8000 200 42000 35300; B 8200 200 10100 35100; B 8200 200 41900 35100; B 8400 200 10200 34900; B 8400 200 41800 34900; B 8600 200 10300 34700; B 8600 200 41700 34700; B 8800 200 10400 34500; B 8800 200 41600 34500; B 9000 200 10500 34300; B 9000 200 41500 34300; B 9200 200 10600 34100; B 9400 200 10700 33900; B 9600 200 10800 33700; B 9800 200 10900 33500; B 10000 12400 11000 27200; B 5000 5000 21500 31700; B 5000 5000 30500 31700; B 9200 200 41400 34100; B 9400 200 41300 33900; B 9600 200 41200 33700; B 9800 200 41100 33500; B 9800 200 10900 20900; B 9600 200 10800 20700; B 9400 200 10700 20500; B 9200 200 10600 20300; B 5000 5000 21500 22700; B 5000 5000 30500 22700; B 10000 12400 41000 27200; B 9800 200 41100 20900; B 9600 200 41200 20700; B 9400 200 41300 20500; B 9200 200 41400 20300; B 9000 200 10500 20100; B 9000 200 41500 20100; B 8800 200 10400 19900; B 8800 200 41600 19900; B 8600 200 10300 19700; B 8600 200 41700 19700; B 8400 200 10200 19500; B 8400 200 41800 19500; B 8200 200 10100 19300; B 8200 200 41900 19300; B 8000 200 10000 19100; B 8000 200 42000 19100; B 7800 200 9900 18900; B 7800 200 42100 18900; B 7600 200 9800 18700; B 7600 200 42200 18700; B 7400 200 9700 18500; B 7400 200 42300 18500; B 7200 200 9600 18300; B 7200 200 42400 18300; B 7000 200 9500 18100; B 7000 200 42500 18100; B 6800 200 9400 17900; B 6800 200 42600 17900; B 6600 200 9300 17700; B 6600 200 42700 17700; B 6400 200 9200 17500; B 6400 200 42800 17500; B 6200 200 9100 17300; B 6200 200 42900 17300; B 6000 200 9000 17100; B 12400 200 26000 17100; B 6000 200 43000 17100; B 5800 200 8900 16900; B 12800 200 26000 16900; B 5800 200 43100 16900; B 5600 200 8800 16700; B 13200 200 26000 16700; B 5600 200 43200 16700; B 5400 200 8700 16500; B 13600 200 26000 16500; B 5400 200 43300 16500; B 5200 200 8600 16300; B 14000 200 26000 16300; B 5200 200 43400 16300; B 5000 200 8500 16100; B 14400 200 26000 16100; B 5000 200 43500 16100; B 4800 200 8400 15900; B 14800 200 26000 15900; B 4800 200 43600 15900; B 4600 200 8300 15700; B 15200 200 26000 15700; B 4600 200 43700 15700; B 4400 200 8200 15500; B 15600 200 26000 15500; B 4400 200 43800 15500; B 4200 200 8100 15300; B 16000 200 26000 15300; B 4200 200 43900 15300; B 4000 200 8000 15100; B 16400 200 26000 15100; B 4000 200 44000 15100; B 3800 200 7900 14900; B 16800 200 26000 14900; B 3800 200 44100 14900; B 3600 200 7800 14700; B 17200 200 26000 14700; B 3600 200 44200 14700; B 3400 200 7700 14500; B 17600 200 26000 14500; B 3400 200 44300 14500; B 3200 200 7600 14300; B 18000 200 26000 14300; B 3200 200 44400 14300; B 3000 200 7500 14100; B 18400 200 26000 14100; B 3000 200 44500 14100; B 2800 200 7400 13900; B 18800 200 26000 13900; B 2800 200 44600 13900; B 2600 200 7300 13700; B 19200 200 26000 13700; B 2600 200 44700 13700; B 2400 200 7200 13500; B 19600 200 26000 13500; B 2400 200 44800 13500; B 2200 200 7100 13300; B 20000 200 26000 13300; B 2200 200 44900 13300; B 2000 200 7000 13100; B 20400 200 26000 13100; B 2000 200 45000 13100; B 1800 200 6900 12900; B 20800 200 26000 12900; B 1800 200 45100 12900; B 1600 200 6800 12700; B 21200 200 26000 12700; B 1600 200 45200 12700; B 1400 200 6700 12500; B 21600 200 26000 12500; B 1400 200 45300 12500; B 1200 200 6600 12300; B 22000 200 26000 12300; B 1200 200 45400 12300; B 1000 200 6500 12100; B 22400 200 26000 12100; B 1000 200 45500 12100; B 800 200 6400 11900; B 22800 200 26000 11900; B 800 200 45600 11900; B 600 200 6300 11700; B 23200 200 26000 11700; B 600 200 45700 11700; B 400 200 6200 11500; B 23600 200 26000 11500; B 400 200 45800 11500; B 200 200 6100 11300; B 24000 200 26000 11300; B 200 200 45900 11300; B 24400 200 26000 11100; B 24800 200 26000 10900; B 25200 200 26000 10700; B 25600 200 26000 10500; B 26000 200 26000 10300; B 26400 200 26000 10100; B 26800 200 26000 9900; B 27200 200 26000 9700; B 27600 200 26000 9500; B 28000 200 26000 9300; B 28400 200 26000 9100; B 28800 200 26000 8900; B 29200 200 26000 8700; B 29600 200 26000 8500; B 30000 200 26000 8300; B 30400 200 26000 8100; B 30800 200 26000 7900; B 31200 200 26000 7700; B 31600 200 26000 7500; B 32000 200 26000 7300; L COP; B 32000 200 26000 47100; B 31600 200 26000 46900; B 31200 200 26000 46700; B 30800 200 26000 46500; B 30400 200 26000 46300; B 30000 200 26000 46100; B 29600 200 26000 45900; B 29200 200 26000 45700; B 28800 200 26000 45500; B 28400 200 26000 45300; B 28000 200 26000 45100; B 27600 200 26000 44900; B 27200 200 26000 44700; B 26800 200 26000 44500; B 26400 200 26000 44300; B 26000 200 26000 44100; B 25600 200 26000 43900; B 25200 200 26000 43700; B 24800 200 26000 43500; B 24400 200 26000 43300; B 200 200 6100 43100; B 24000 200 26000 43100; B 200 200 45900 43100; B 400 200 6200 42900; B 23600 200 26000 42900; B 400 200 45800 42900; B 600 200 6300 42700; B 23200 200 26000 42700; B 600 200 45700 42700; B 800 200 6400 42500; B 22800 200 26000 42500; B 800 200 45600 42500; B 1000 200 6500 42300; B 22400 200 26000 42300; B 1000 200 45500 42300; B 1200 200 6600 42100; B 22000 200 26000 42100; B 1200 200 45400 42100; B 1400 200 6700 41900; B 21600 200 26000 41900; B 1400 200 45300 41900; B 1600 200 6800 41700; B 21200 200 26000 41700; B 1600 200 45200 41700; B 1800 200 6900 41500; B 20800 200 26000 41500; B 1800 200 45100 41500; B 2000 200 7000 41300; B 20400 200 26000 41300; B 2000 200 45000 41300; B 2200 200 7100 41100; B 20000 200 26000 41100; B 2200 200 44900 41100; B 2400 200 7200 40900; B 19600 200 26000 40900; B 2400 200 44800 40900; B 2600 200 7300 40700; B 19200 200 26000 40700; B 2600 200 44700 40700; B 2800 200 7400 40500; B 18800 200 26000 40500; B 2800 200 44600 40500; B 3000 200 7500 40300; B 18400 200 26000 40300; B 3000 200 44500 40300; B 3200 200 7600 40100; B 18000 200 26000 40100; B 3200 200 44400 40100; B 3400 200 7700 39900; B 17600 200 26000 39900; B 3400 200 44300 39900; B 3600 200 7800 39700; B 17200 200 26000 39700; B 3600 200 44200 39700; B 3800 200 7900 39500; B 16800 200 26000 39500; B 3800 200 44100 39500; B 4000 200 8000 39300; B 16400 200 26000 39300; B 4000 200 44000 39300; B 4200 200 8100 39100; B 16000 200 26000 39100; B 4200 200 43900 39100; B 4400 200 8200 38900; B 15600 200 26000 38900; B 4400 200 43800 38900; B 4600 200 8300 38700; B 15200 200 26000 38700; B 4600 200 43700 38700; B 4800 200 8400 38500; B 14800 200 26000 38500; B 4800 200 43600 38500; B 5000 200 8500 38300; B 14400 200 26000 38300; B 5000 200 43500 38300; B 5200 200 8600 38100; B 14000 200 26000 38100; B 5200 200 43400 38100; B 5400 200 8700 37900; B 13600 200 26000 37900; B 5400 200 43300 37900; B 5600 200 8800 37700; B 13200 200 26000 37700; B 5600 200 43200 37700; B 5800 200 8900 37500; B 12800 200 26000 37500; B 5800 200 43100 37500; B 6000 200 9000 37300; B 12400 200 26000 37300; B 6000 200 43000 37300; B 6200 200 9100 37100; B 6200 200 42900 37100; B 6400 200 9200 36900; B 6400 200 42800 36900; B 6600 200 9300 36700; B 6600 200 42700 36700; B 6800 200 9400 36500; B 6800 200 42600 36500; B 7000 200 9500 36300; B 7000 200 42500 36300; B 7200 200 9600 36100; B 7200 200 42400 36100; B 7400 200 9700 35900; B 7400 200 42300 35900; B 7600 200 9800 35700; B 7600 200 42200 35700; B 7800 200 9900 35500; B 7800 200 42100 35500; B 8000 200 10000 35300; B 8000 200 42000 35300; B 8200 200 10100 35100; B 8200 200 41900 35100; B 8400 200 10200 34900; B 8400 200 41800 34900; B 8600 200 10300 34700; B 8600 200 41700 34700; B 8800 200 10400 34500; B 8800 200 41600 34500; B 9000 200 10500 34300; B 9000 200 41500 34300; B 9200 200 10600 34100; B 9200 200 41400 34100; B 9400 200 10700 33900; B 9400 200 41300 33900; B 9600 200 10800 33700; B 9600 200 41200 33700; B 9800 200 10900 33500; B 9800 200 41100 33500; B 10000 12400 11000 27200; B 10000 12400 41000 27200; B 9800 200 10900 20900; B 9800 200 41100 20900; B 9600 200 10800 20700; B 9600 200 41200 20700; B 9400 200 10700 20500; B 9400 200 41300 20500; B 9200 200 10600 20300; B 9200 200 41400 20300; B 9000 200 10500 20100; B 9000 200 41500 20100; B 8800 200 10400 19900; B 8800 200 41600 19900; B 8600 200 10300 19700; B 8600 200 41700 19700; B 8400 200 10200 19500; B 8400 200 41800 19500; B 8200 200 10100 19300; B 8200 200 41900 19300; B 8000 200 10000 19100; B 8000 200 42000 19100; B 7800 200 9900 18900; B 7800 200 42100 18900; B 7600 200 9800 18700; B 7600 200 42200 18700; B 7400 200 9700 18500; B 7400 200 42300 18500; B 7200 200 9600 18300; B 7200 200 42400 18300; B 7000 200 9500 18100; B 7000 200 42500 18100; B 6800 200 9400 17900; B 6800 200 42600 17900; B 6600 200 9300 17700; B 6600 200 42700 17700; B 6400 200 9200 17500; B 6400 200 42800 17500; B 6200 200 9100 17300; B 6200 200 42900 17300; B 6000 200 9000 17100; B 12400 200 26000 17100; B 6000 200 43000 17100; B 5800 200 8900 16900; B 12800 200 26000 16900; B 5800 200 43100 16900; B 5600 200 8800 16700; B 13200 200 26000 16700; B 5600 200 43200 16700; B 5400 200 8700 16500; B 13600 200 26000 16500; B 5400 200 43300 16500; B 5200 200 8600 16300; B 14000 200 26000 16300; B 5200 200 43400 16300; B 5000 200 8500 16100; B 14400 200 26000 16100; B 5000 200 43500 16100; B 4800 200 8400 15900; B 14800 200 26000 15900; B 4800 200 43600 15900; B 4600 200 8300 15700; B 15200 200 26000 15700; B 4600 200 43700 15700; B 4400 200 8200 15500; B 15600 200 26000 15500; B 4400 200 43800 15500; B 4200 200 8100 15300; B 16000 200 26000 15300; B 4200 200 43900 15300; B 4000 200 8000 15100; B 16400 200 26000 15100; B 4000 200 44000 15100; B 3800 200 7900 14900; B 16800 200 26000 14900; B 3800 200 44100 14900; B 3600 200 7800 14700; B 17200 200 26000 14700; B 3600 200 44200 14700; B 3400 200 7700 14500; B 17600 200 26000 14500; B 3400 200 44300 14500; B 3200 200 7600 14300; B 18000 200 26000 14300; B 3200 200 44400 14300; B 3000 200 7500 14100; B 18400 200 26000 14100; B 3000 200 44500 14100; B 2800 200 7400 13900; B 18800 200 26000 13900; B 2800 200 44600 13900; B 2600 200 7300 13700; B 19200 200 26000 13700; B 2600 200 44700 13700; B 2400 200 7200 13500; B 19600 200 26000 13500; B 2400 200 44800 13500; B 2200 200 7100 13300; B 20000 200 26000 13300; B 2200 200 44900 13300; B 2000 200 7000 13100; B 20400 200 26000 13100; B 2000 200 45000 13100; B 1800 200 6900 12900; B 20800 200 26000 12900; B 1800 200 45100 12900; B 1600 200 6800 12700; B 21200 200 26000 12700; B 1600 200 45200 12700; B 1400 200 6700 12500; B 21600 200 26000 12500; B 1400 200 45300 12500; B 1200 200 6600 12300; B 22000 200 26000 12300; B 1200 200 45400 12300; B 1000 200 6500 12100; B 22400 200 26000 12100; B 1000 200 45500 12100; B 800 200 6400 11900; B 22800 200 26000 11900; B 800 200 45600 11900; B 600 200 6300 11700; B 23200 200 26000 11700; B 600 200 45700 11700; B 400 200 6200 11500; B 23600 200 26000 11500; B 400 200 45800 11500; B 200 200 6100 11300; B 24000 200 26000 11300; B 200 200 45900 11300; B 24400 200 26000 11100; B 24800 200 26000 10900; B 25200 200 26000 10700; B 25600 200 26000 10500; B 26000 200 26000 10300; B 26400 200 26000 10100; B 26800 200 26000 9900; B 27200 200 26000 9700; B 27600 200 26000 9500; B 28000 200 26000 9300; B 28400 200 26000 9100; B 28800 200 26000 8900; B 29200 200 26000 8700; B 29600 200 26000 8500; B 30000 200 26000 8300; B 30400 200 26000 8100; B 30800 200 26000 7900; B 31200 200 26000 7700; B 31600 200 26000 7500; B 32000 200 26000 7300; L CPS; B 42000 200 25000 49100; B 41800 200 24900 48900; B 41600 200 24800 48700; B 41400 200 24700 48500; B 41200 200 24600 48300; B 41000 200 24500 48100; B 40800 200 24400 47900; B 40600 200 24300 47700; B 40400 200 24200 47500; B 40200 200 24100 47300; B 2000 38200 5000 28100; B 200 200 47900 47100; B 400 200 47800 46900; B 600 200 47700 46700; B 800 200 47600 46500; B 1000 200 47500 46300; B 1200 200 47400 46100; B 1400 200 47300 45900; B 1600 200 47200 45700; B 1800 200 47100 45500; B 1800 200 4900 8900; B 1600 200 4800 8700; B 1400 200 4700 8500; B 1200 200 4600 8300; B 1000 200 4500 8100; B 800 200 4400 7900; B 600 200 4300 7700; B 400 200 4200 7500; B 200 200 4100 7300; B 2000 38200 47000 26300; B 40200 200 27900 7100; B 40400 200 27800 6900; B 40600 200 27700 6700; B 40800 200 27600 6500; B 41000 200 27500 6300; B 41200 200 27400 6100; B 41400 200 27300 5900; B 41600 200 27200 5700; B 41800 200 27100 5500; B 42000 200 27000 5300; DF; C 1; End magic-8.0.210/scmos/examples/nist-mems-library/thermal-converter.cif0000644000175000001440000003173710751423606024135 0ustar timusersDS 1 1 2; 9 thermal-converter; L CMF; B 1200 1200 2000 16400; B 1200 1200 3800 16400; B 1200 1200 5600 16400; B 1200 1200 7400 16400; B 1200 1200 9200 16400; B 1200 1200 11000 16400; B 600 600 2300 15500; B 600 600 4100 15500; B 600 600 5900 15500; B 600 600 7700 15500; B 600 600 9500 15500; B 1200 1200 800 14600; B 1200 600 2600 14900; B 1200 600 4400 14900; B 1200 600 6200 14900; B 1200 600 8000 14900; B 1200 600 9800 14900; B 600 600 2900 14300; B 600 600 4700 14300; B 600 600 6500 14300; B 600 600 8300 14300; B 1200 600 1400 13700; B 1200 600 3200 13700; B 1200 600 5000 13700; B 1200 600 6800 13700; B 1200 600 8600 13700; B 600 600 1700 13100; B 600 600 3500 13100; B 600 600 5300 13100; B 600 600 7100 13100; B 1200 600 2000 12500; B 1200 600 3800 12500; B 1200 600 5600 12500; B 1200 600 7400 12500; B 600 600 2300 11900; B 600 600 4100 11900; B 600 600 5900 11900; B 1200 600 2600 11300; B 1200 600 4400 11300; B 1200 600 6200 11300; B 600 600 2900 10700; B 600 600 4700 10700; B 1200 600 3200 10100; B 1200 600 5000 10100; B 600 600 3500 9500; B 1200 600 3800 8900; B 600 20400 4100 -1600; B 1200 600 3800 -12100; B 600 600 3500 -12700; B 600 22800 5300 -1600; B 1200 600 3200 -13300; B 1200 600 5000 -13300; B 600 600 2900 -13900; B 600 600 4700 -13900; B 600 25200 6500 -1600; B 1200 600 2600 -14500; B 1200 600 4400 -14500; B 1200 600 6200 -14500; B 600 600 2300 -15100; B 600 600 4100 -15100; B 600 600 5900 -15100; B 600 27600 7700 -1600; B 1800 600 1700 -15700; B 1200 600 3800 -15700; B 1200 600 5600 -15700; B 1200 600 7400 -15700; B 600 6000 1100 -19000; B 600 600 3500 -16300; B 600 600 5300 -16300; B 600 600 7100 -16300; B 600 30000 8900 -1600; B 1800 600 2900 -16900; B 1200 600 5000 -16900; B 1200 600 6800 -16900; B 1200 600 8600 -16900; B 600 4800 2300 -19600; B 600 600 4700 -17500; B 600 600 6500 -17500; B 600 600 8300 -17500; B 600 32400 10100 -1600; B 1200 600 4400 -18100; B 1200 600 6200 -18100; B 1200 600 8000 -18100; B 1200 600 9800 -18100; B 600 600 4100 -18700; B 600 600 5900 -18700; B 600 600 7700 -18700; B 600 600 9500 -18700; B 600 34800 11300 -1600; B 1200 1200 3800 -19600; B 1200 1200 5600 -19600; B 1200 1200 7400 -19600; B 1200 1200 9200 -19600; B 1200 1200 11000 -19600; B 1200 1200 12800 16400; B 1200 1200 14600 16400; B 1200 1200 16400 16400; B 1200 1200 18200 16400; B 1200 1200 20000 16400; B 1200 1200 21800 16400; B 600 34800 12500 -1600; B 600 600 14300 15500; B 600 600 16100 15500; B 600 600 17900 15500; B 600 600 19700 15500; B 600 600 21500 15500; B 1200 600 14000 14900; B 1200 600 15800 14900; B 1200 600 17600 14900; B 1200 600 19400 14900; B 1200 600 21200 14900; B 600 32400 13700 -1600; B 600 600 15500 14300; B 600 600 17300 14300; B 600 600 19100 14300; B 600 600 20900 14300; B 1200 1200 23000 14600; B 1200 600 15200 13700; B 1200 600 17000 13700; B 1200 600 18800 13700; B 1200 600 20600 13700; B 1200 600 22400 13700; B 600 30000 14900 -1600; B 600 600 16700 13100; B 600 600 18500 13100; B 600 600 20300 13100; B 600 600 22100 13100; B 1200 600 16400 12500; B 1200 600 18200 12500; B 1200 600 20000 12500; B 1200 600 21800 12500; B 600 27600 16100 -1600; B 600 600 17900 11900; B 600 600 19700 11900; B 600 600 21500 11900; B 1200 600 17600 11300; B 1200 600 19400 11300; B 1200 600 21200 11300; B 600 25200 17300 -1600; B 600 600 19100 10700; B 600 600 20900 10700; B 1200 600 18800 10100; B 1200 600 20600 10100; B 600 22800 18500 -1600; B 600 600 20300 9500; B 1200 600 20000 8900; B 600 20400 19700 -1600; B 1200 600 20000 -12100; B 600 600 20300 -12700; B 1200 600 18800 -13300; B 1200 600 20600 -13300; B 600 600 19100 -13900; B 600 600 20900 -13900; B 1200 600 17600 -14500; B 1200 600 19400 -14500; B 1200 600 21200 -14500; B 600 600 17900 -15100; B 600 600 19700 -15100; B 600 600 21500 -15100; B 1200 600 16400 -15700; B 1200 600 18200 -15700; B 1200 600 20000 -15700; B 1200 600 21800 -15700; B 600 600 16700 -16300; B 600 600 18500 -16300; B 600 600 20300 -16300; B 600 600 22100 -16300; B 1200 600 15200 -16900; B 1200 600 17000 -16900; B 1200 600 18800 -16900; B 1200 600 20600 -16900; B 1200 600 22400 -16900; B 600 600 15500 -17500; B 600 600 17300 -17500; B 600 600 19100 -17500; B 600 600 20900 -17500; B 600 400 22700 -17400; B 1200 600 14000 -18100; B 1200 600 15800 -18100; B 1200 600 17600 -18100; B 1200 600 19400 -18100; B 1200 600 21200 -18100; B 3000 600 23900 -17900; B 600 600 14300 -18700; B 600 600 16100 -18700; B 600 600 17900 -18700; B 600 600 19700 -18700; B 600 600 21500 -18700; B 1200 1200 12800 -19600; B 1200 1200 14600 -19600; B 1200 1200 16400 -19600; B 1200 1200 18200 -19600; B 1200 1200 20000 -19600; B 1200 1200 21800 -19600; B 1200 1200 23600 -19600; B 600 1800 23300 -21100; B 600 3800 25100 -20100; L CPG; B 23400 800 11900 17800; B 800 2200 600 16300; B 1200 1200 2000 16400; B 1200 1200 3800 16400; B 1200 1200 5600 16400; B 1200 1200 7400 16400; B 1200 1200 9200 16400; B 1200 1200 11000 16400; B 600 600 2300 15500; B 600 600 4100 15500; B 600 600 5900 15500; B 600 600 7700 15500; B 600 600 9500 15500; B 1200 1200 800 14600; B 1200 600 2600 14900; B 1200 600 4400 14900; B 1200 600 6200 14900; B 1200 600 8000 14900; B 1200 600 9800 14900; B 600 600 2900 14300; B 600 600 4700 14300; B 600 600 6500 14300; B 600 600 8300 14300; B 1200 600 3200 13700; B 1200 600 5000 13700; B 1200 600 6800 13700; B 1200 600 8600 13700; B 600 600 3500 13100; B 600 600 5300 13100; B 600 600 7100 13100; B 1200 600 3800 12500; B 1200 600 5600 12500; B 1200 600 7400 12500; B 600 600 4100 11900; B 600 600 5900 11900; B 1200 600 4400 11300; B 1200 600 6200 11300; B 600 600 4700 10700; B 1200 600 5000 10100; B 600 22800 5300 -1600; B 1200 600 5000 -13300; B 600 600 4700 -13900; B 600 25200 6500 -1600; B 1200 600 4400 -14500; B 1200 600 6200 -14500; B 600 600 4100 -15100; B 600 600 5900 -15100; B 600 27600 7700 -1600; B 1200 600 3800 -15700; B 1200 600 5600 -15700; B 1200 600 7400 -15700; B 600 3000 3500 -17500; B 600 3000 5300 -17500; B 600 3000 7100 -17500; B 600 32400 8900 -2800; B 600 32400 10100 -1600; B 600 32400 11300 -400; B 1200 1200 12800 16400; B 1200 1200 14600 16400; B 1200 1200 16400 16400; B 1200 1200 18200 16400; B 1200 1200 20000 16400; B 1200 1200 21800 16400; B 600 31200 12500 200; B 600 600 14300 15500; B 600 600 16100 15500; B 600 600 17900 15500; B 600 600 19700 15500; B 600 600 21500 15500; B 800 2200 23200 16300; B 1200 600 14000 14900; B 1200 600 15800 14900; B 1200 600 17600 14900; B 1200 600 19400 14900; B 1200 600 21200 14900; B 600 28800 13700 200; B 600 600 15500 14300; B 600 600 17300 14300; B 600 600 19100 14300; B 600 600 20900 14300; B 1200 1200 23000 14600; B 1200 600 15200 13700; B 1200 600 17000 13700; B 1200 600 18800 13700; B 1200 600 20600 13700; B 600 26400 14900 200; B 600 600 16700 13100; B 600 600 18500 13100; B 600 600 20300 13100; B 1200 600 16400 12500; B 1200 600 18200 12500; B 1200 600 20000 12500; B 600 24000 16100 200; B 600 600 17900 11900; B 600 600 19700 11900; B 1200 600 17600 11300; B 1200 600 19400 11300; B 600 21600 17300 200; B 600 600 19100 10700; B 1200 600 18800 10100; B 600 19200 18500 200; B 1800 600 19100 -9700; B 1800 600 17900 -10900; B 1800 600 16700 -12100; B 1800 600 15500 -13300; B 1800 600 14300 -14500; B 1800 600 13100 -15700; B 1800 600 11900 -16900; B 1200 600 10400 -18100; B 600 600 10700 -18700; B 600 1800 12500 -18100; B 600 1800 13700 -16900; B 600 1800 14900 -15700; B 600 1800 16100 -14500; B 600 1800 17300 -13300; B 600 1800 18500 -12100; B 600 1800 19700 -10900; B 1200 600 20000 -12100; B 600 600 20300 -12700; B 1200 600 18800 -13300; B 1200 600 20600 -13300; B 600 600 19100 -13900; B 600 600 20900 -13900; B 1200 600 17600 -14500; B 1200 600 19400 -14500; B 1200 600 21200 -14500; B 600 600 17900 -15100; B 600 600 19700 -15100; B 600 600 21500 -15100; B 1200 600 16400 -15700; B 1200 600 18200 -15700; B 1200 600 20000 -15700; B 1200 600 21800 -15700; B 600 600 16700 -16300; B 600 600 18500 -16300; B 600 600 20300 -16300; B 600 600 22100 -16300; B 1200 600 15200 -16900; B 1200 600 17000 -16900; B 1200 600 18800 -16900; B 1200 600 20600 -16900; B 1200 600 22400 -16900; B 600 600 15500 -17500; B 600 600 17300 -17500; B 600 600 19100 -17500; B 600 600 20900 -17500; B 600 400 22700 -17400; B 1200 600 14000 -18100; B 1200 600 15800 -18100; B 1200 600 17600 -18100; B 1200 600 19400 -18100; B 1200 600 21200 -18100; B 1200 600 23000 -17900; B 600 600 14300 -18700; B 600 600 16100 -18700; B 600 600 17900 -18700; B 600 600 19700 -18700; B 600 600 21500 -18700; B 600 800 23300 -18600; B 1200 1200 3800 -19600; B 1200 1200 5600 -19600; B 1200 1200 7400 -19600; B 1200 1200 9200 -19600; B 1200 1200 11000 -19600; B 1200 1200 12800 -19600; B 1200 1200 14600 -19600; B 1200 1200 16400 -19600; B 1200 1200 18200 -19600; B 1200 1200 20000 -19600; B 1200 1200 21800 -19600; B 1200 1200 23600 -19600; L CAA; B 30000 3200 11800 20400; B 2600 5400 -1900 16100; B 2600 5400 25500 16100; B 3200 600 -1600 13100; B 3200 600 25200 13100; B 3800 1200 -1300 12200; B 3800 1200 24900 12200; B 4400 1200 -1000 11000; B 4400 1200 24600 11000; B 5000 1200 -700 9800; B 5000 1200 24300 9800; B 5600 1200 -400 8600; B 5600 1200 24000 8600; B 6400 10000 0 3000; B 6400 10000 23600 3000; L CVA; B 30000 3200 11800 20400; B 2600 5400 -1900 16100; B 2600 5400 25500 16100; B 3200 600 -1600 13100; B 3200 600 25200 13100; B 3800 1200 -1300 12200; B 3800 1200 24900 12200; B 4400 1200 -1000 11000; B 4400 1200 24600 11000; B 5000 1200 -700 9800; B 5000 1200 24300 9800; B 5600 1200 -400 8600; B 5600 1200 24000 8600; B 6400 10000 0 3000; B 6400 10000 23600 3000; L CCA; B 30000 3200 11800 20400; B 2600 5400 -1900 16100; B 2600 5400 25500 16100; B 3200 600 -1600 13100; B 3200 600 25200 13100; B 3800 1200 -1300 12200; B 3800 1200 24900 12200; B 4400 1200 -1000 11000; B 4400 1200 24600 11000; B 5000 1200 -700 9800; B 5000 1200 24300 9800; B 5600 1200 -400 8600; B 5600 1200 24000 8600; B 6400 10000 0 3000; B 6400 10000 23600 3000; L CCP; B 400 400 2000 16400; B 400 400 3800 16400; B 400 400 5600 16400; B 400 400 7400 16400; B 400 400 9200 16400; B 400 400 11000 16400; B 400 400 12800 16400; B 400 400 14600 16400; B 400 400 16400 16400; B 400 400 18200 16400; B 400 400 20000 16400; B 400 400 21800 16400; B 400 400 800 14600; B 400 400 23000 14600; B 400 400 3800 -19600; B 400 400 5600 -19600; B 400 400 7400 -19600; B 400 400 9200 -19600; B 400 400 11000 -19600; B 400 400 12800 -19600; B 400 400 14600 -19600; B 400 400 16400 -19600; B 400 400 18200 -19600; B 400 400 20000 -19600; B 400 400 21800 -19600; B 400 400 23600 -19600; L COG; B 30000 3200 11800 20400; B 2600 5400 -1900 16100; B 2600 5400 25500 16100; B 3200 600 -1600 13100; B 3200 600 25200 13100; B 3800 1200 -1300 12200; B 3800 1200 24900 12200; B 4400 1200 -1000 11000; B 4400 1200 24600 11000; B 5000 1200 -700 9800; B 5000 1200 24300 9800; B 5600 1200 -400 8600; B 5600 1200 24000 8600; B 6400 10000 0 3000; B 6400 10000 23600 3000; L COP; B 30000 3200 11800 20400; B 2600 5400 -1900 16100; B 2600 5400 25500 16100; B 3200 600 -1600 13100; B 3200 600 25200 13100; B 3800 1200 -1300 12200; B 3800 1200 24900 12200; B 4400 1200 -1000 11000; B 4400 1200 24600 11000; B 5000 1200 -700 9800; B 5000 1200 24300 9800; B 5600 1200 -400 8600; B 5600 1200 24000 8600; B 6400 10000 0 3000; B 6400 10000 23600 3000; 94 heater2 25100 -21700; 94 heater1 1100 -21700; 94 Vmeas1 2300 -21700; 94 Vmeas2 23300 -21700; DF; C 1; End magic-8.0.210/scmos/examples/nist-mems-library/open-80x80.cif0000644000175000001440000000035610751423606022213 0ustar timusersDS 1 1 2; 9 open-80x80; L CAA; B 16000 16000 105600 -39800; L CVA; B 16000 16000 105600 -39800; L CCA; B 16000 16000 105600 -39800; L COG; B 16000 16000 105600 -39800; L COP; B 16000 16000 105600 -39800; DF; C 1; End magic-8.0.210/scmos/examples/nist-mems-library/pixel-160x160.mag0000644000175000001440000002126110751423606022532 0ustar timusersmagic tech scmos timestamp 760840608 << polysilicon >> rect 383 99 398 102 rect 383 98 385 99 rect 356 95 385 98 rect 389 95 391 99 rect 395 95 398 99 rect 356 94 398 95 rect 356 92 360 94 rect 356 88 390 92 rect 386 85 390 88 rect 356 81 390 85 rect 356 78 360 81 rect 356 74 390 78 rect 386 72 390 74 rect 356 68 390 72 rect 356 66 360 68 rect 356 62 390 66 rect 386 59 390 62 rect 356 55 390 59 rect 356 52 360 55 rect 356 51 398 52 rect 356 48 385 51 rect 383 47 385 48 rect 389 47 391 51 rect 395 47 398 51 rect 383 45 398 47 << metal1 >> rect 446 152 453 153 rect 445 151 453 152 rect 444 150 453 151 rect 443 149 453 150 rect 442 148 453 149 rect 441 147 453 148 rect 440 146 452 147 rect 439 145 451 146 rect 438 144 450 145 rect 437 143 449 144 rect 436 142 448 143 rect 435 141 447 142 rect 434 140 446 141 rect 433 139 445 140 rect 432 138 444 139 rect 431 137 443 138 rect 430 136 442 137 rect 429 135 441 136 rect 428 134 440 135 rect 427 133 439 134 rect 426 132 438 133 rect 425 131 437 132 rect 424 130 436 131 rect 423 129 435 130 rect 422 128 434 129 rect 421 127 433 128 rect 420 126 432 127 rect 419 125 431 126 rect 418 124 430 125 rect 417 123 429 124 rect 416 122 428 123 rect 415 121 427 122 rect 414 120 426 121 rect 413 119 425 120 rect 412 118 424 119 rect 411 117 423 118 rect 410 116 422 117 rect 409 115 421 116 rect 408 114 420 115 rect 407 113 419 114 rect 406 112 418 113 rect 405 111 417 112 rect 404 110 416 111 rect 403 109 415 110 rect 402 108 414 109 rect 401 107 413 108 rect 400 106 412 107 rect 399 105 411 106 rect 398 104 410 105 rect 397 103 409 104 rect 396 102 408 103 rect 383 101 407 102 rect 383 100 406 101 rect 383 99 405 100 rect 383 95 385 99 rect 389 95 391 99 rect 395 98 404 99 rect 395 97 403 98 rect 395 96 402 97 rect 395 95 401 96 rect 383 94 400 95 rect 383 93 399 94 rect 383 52 402 53 rect 383 51 403 52 rect 383 47 385 51 rect 389 47 391 51 rect 395 50 404 51 rect 395 49 405 50 rect 395 48 406 49 rect 395 47 407 48 rect 383 46 408 47 rect 383 45 409 46 rect 396 44 410 45 rect 397 43 411 44 rect 398 42 412 43 rect 399 41 413 42 rect 400 40 414 41 rect 401 39 415 40 rect 402 38 416 39 rect 403 37 417 38 rect 404 36 418 37 rect 405 35 419 36 rect 406 34 420 35 rect 407 33 421 34 rect 408 32 422 33 rect 409 31 423 32 rect 410 30 424 31 rect 411 29 425 30 rect 412 28 426 29 rect 413 27 427 28 rect 414 26 428 27 rect 415 25 429 26 rect 416 24 430 25 rect 417 23 431 24 rect 418 22 432 23 rect 419 21 433 22 rect 420 20 434 21 rect 421 19 435 20 rect 422 18 436 19 rect 423 17 437 18 rect 424 16 438 17 rect 425 15 439 16 rect 426 14 440 15 rect 427 13 441 14 rect 428 12 442 13 rect 429 11 443 12 rect 430 10 444 11 rect 431 9 445 10 rect 432 8 446 9 rect 433 7 447 8 rect 434 6 448 7 rect 435 5 449 6 rect 436 4 450 5 rect 437 3 451 4 rect 438 2 452 3 rect 439 1 453 2 rect 440 0 453 1 rect 441 -1 453 0 rect 442 -2 453 -1 rect 443 -3 453 -2 rect 444 -4 453 -3 rect 445 -5 453 -4 rect 446 -6 453 -5 rect 447 -7 453 -6 << polycontact >> rect 385 95 389 99 rect 391 95 395 99 rect 385 47 389 51 rect 391 47 395 51 << substrateopen >> rect 309 152 438 153 rect 310 151 437 152 rect 311 150 436 151 rect 312 149 435 150 rect 313 148 434 149 rect 314 147 433 148 rect 315 146 432 147 rect 316 145 431 146 rect 317 144 430 145 rect 318 143 429 144 rect 319 142 428 143 rect 320 141 427 142 rect 321 140 426 141 rect 322 139 425 140 rect 293 138 294 139 rect 323 138 424 139 rect 452 138 453 139 rect 293 137 295 138 rect 324 137 423 138 rect 451 137 453 138 rect 293 136 296 137 rect 325 136 422 137 rect 450 136 453 137 rect 293 135 297 136 rect 326 135 421 136 rect 449 135 453 136 rect 293 134 298 135 rect 327 134 420 135 rect 448 134 453 135 rect 293 133 299 134 rect 328 133 419 134 rect 447 133 453 134 rect 293 132 300 133 rect 329 132 418 133 rect 446 132 453 133 rect 293 131 301 132 rect 330 131 417 132 rect 445 131 453 132 rect 293 130 302 131 rect 331 130 416 131 rect 444 130 453 131 rect 293 129 303 130 rect 332 129 415 130 rect 443 129 453 130 rect 293 128 304 129 rect 333 128 414 129 rect 442 128 453 129 rect 293 127 305 128 rect 334 127 413 128 rect 441 127 453 128 rect 293 126 306 127 rect 335 126 412 127 rect 440 126 453 127 rect 293 125 307 126 rect 336 125 411 126 rect 439 125 453 126 rect 293 124 308 125 rect 337 124 410 125 rect 438 124 453 125 rect 293 123 309 124 rect 338 123 409 124 rect 437 123 453 124 rect 293 122 310 123 rect 339 122 408 123 rect 436 122 453 123 rect 293 121 311 122 rect 340 121 407 122 rect 435 121 453 122 rect 293 120 312 121 rect 341 120 406 121 rect 434 120 453 121 rect 293 119 313 120 rect 342 119 405 120 rect 433 119 453 120 rect 293 118 314 119 rect 343 118 404 119 rect 432 118 453 119 rect 293 117 315 118 rect 344 117 403 118 rect 431 117 453 118 rect 293 116 316 117 rect 345 116 402 117 rect 430 116 453 117 rect 293 115 317 116 rect 346 115 401 116 rect 429 115 453 116 rect 293 114 318 115 rect 347 114 400 115 rect 428 114 453 115 rect 293 113 319 114 rect 348 113 399 114 rect 427 113 453 114 rect 293 112 320 113 rect 349 112 398 113 rect 426 112 453 113 rect 293 111 321 112 rect 350 111 397 112 rect 425 111 453 112 rect 293 110 322 111 rect 351 110 396 111 rect 424 110 453 111 rect 293 109 323 110 rect 352 109 395 110 rect 423 109 453 110 rect 293 108 324 109 rect 353 108 394 109 rect 422 108 453 109 rect 293 107 325 108 rect 354 107 393 108 rect 421 107 453 108 rect 293 106 326 107 rect 355 106 392 107 rect 420 106 453 107 rect 293 105 327 106 rect 356 105 391 106 rect 419 105 453 106 rect 293 104 328 105 rect 418 104 453 105 rect 293 103 329 104 rect 417 103 453 104 rect 293 102 330 103 rect 416 102 453 103 rect 293 101 331 102 rect 415 101 453 102 rect 293 100 332 101 rect 414 100 453 101 rect 293 99 333 100 rect 413 99 453 100 rect 293 98 334 99 rect 412 98 453 99 rect 293 97 335 98 rect 411 97 453 98 rect 293 96 336 97 rect 410 96 453 97 rect 293 95 337 96 rect 409 95 453 96 rect 293 94 338 95 rect 408 94 453 95 rect 293 93 339 94 rect 407 93 453 94 rect 293 92 340 93 rect 406 92 453 93 rect 293 57 341 92 rect 405 57 453 92 rect 293 56 340 57 rect 406 56 453 57 rect 293 55 339 56 rect 407 55 453 56 rect 293 54 338 55 rect 408 54 453 55 rect 293 53 337 54 rect 409 53 453 54 rect 293 52 336 53 rect 410 52 453 53 rect 293 51 335 52 rect 411 51 453 52 rect 293 50 334 51 rect 412 50 453 51 rect 293 49 333 50 rect 413 49 453 50 rect 293 48 332 49 rect 414 48 453 49 rect 293 47 331 48 rect 415 47 453 48 rect 293 46 330 47 rect 416 46 453 47 rect 293 45 329 46 rect 417 45 453 46 rect 293 44 328 45 rect 418 44 453 45 rect 293 43 327 44 rect 419 43 453 44 rect 293 42 326 43 rect 420 42 453 43 rect 293 41 325 42 rect 421 41 453 42 rect 293 40 324 41 rect 356 40 391 41 rect 422 40 453 41 rect 293 39 323 40 rect 355 39 392 40 rect 423 39 453 40 rect 293 38 322 39 rect 354 38 393 39 rect 424 38 453 39 rect 293 37 321 38 rect 353 37 394 38 rect 425 37 453 38 rect 293 36 320 37 rect 352 36 395 37 rect 426 36 453 37 rect 293 35 319 36 rect 351 35 396 36 rect 427 35 453 36 rect 293 34 318 35 rect 350 34 397 35 rect 428 34 453 35 rect 293 33 317 34 rect 349 33 398 34 rect 429 33 453 34 rect 293 32 316 33 rect 348 32 399 33 rect 430 32 453 33 rect 293 31 315 32 rect 347 31 400 32 rect 431 31 453 32 rect 293 30 314 31 rect 346 30 401 31 rect 432 30 453 31 rect 293 29 313 30 rect 345 29 402 30 rect 433 29 453 30 rect 293 28 312 29 rect 344 28 403 29 rect 434 28 453 29 rect 293 27 311 28 rect 343 27 404 28 rect 435 27 453 28 rect 293 26 310 27 rect 342 26 405 27 rect 436 26 453 27 rect 293 25 309 26 rect 341 25 406 26 rect 437 25 453 26 rect 293 24 308 25 rect 340 24 407 25 rect 438 24 453 25 rect 293 23 307 24 rect 339 23 408 24 rect 439 23 453 24 rect 293 22 306 23 rect 338 22 409 23 rect 440 22 453 23 rect 293 21 305 22 rect 337 21 410 22 rect 441 21 453 22 rect 293 20 304 21 rect 336 20 411 21 rect 442 20 453 21 rect 293 19 303 20 rect 335 19 412 20 rect 443 19 453 20 rect 293 18 302 19 rect 334 18 413 19 rect 444 18 453 19 rect 293 17 301 18 rect 333 17 414 18 rect 445 17 453 18 rect 293 16 300 17 rect 332 16 415 17 rect 446 16 453 17 rect 293 15 299 16 rect 331 15 416 16 rect 447 15 453 16 rect 293 14 298 15 rect 330 14 417 15 rect 448 14 453 15 rect 293 13 297 14 rect 329 13 418 14 rect 449 13 453 14 rect 293 12 296 13 rect 328 12 419 13 rect 450 12 453 13 rect 293 11 295 12 rect 327 11 420 12 rect 451 11 453 12 rect 293 10 294 11 rect 326 10 421 11 rect 452 10 453 11 rect 325 9 422 10 rect 324 8 423 9 rect 323 7 424 8 rect 322 6 425 7 rect 321 5 426 6 rect 320 4 427 5 rect 319 3 428 4 rect 318 2 429 3 rect 317 1 430 2 rect 316 0 431 1 rect 315 -1 432 0 rect 314 -2 433 -1 rect 313 -3 434 -2 rect 312 -4 435 -3 rect 311 -5 436 -4 rect 310 -6 437 -5 rect 309 -7 438 -6 << pdiffusionstop >> rect 288 153 458 158 rect 288 -7 293 153 rect 453 -7 458 153 rect 288 -12 458 -7 << end >> magic-8.0.210/scmos/examples/nist-mems-library/memslib.mag0000644000175000001440000003441710751423606022125 0ustar timusersmagic tech scmos timestamp 765071885 << polysilicon >> rect 72 492 92 493 rect 71 491 92 492 rect 70 490 93 491 rect 69 489 93 490 rect 68 488 94 489 rect 67 487 94 488 rect 66 486 95 487 rect 65 485 95 486 rect 64 484 96 485 rect 63 483 96 484 rect 62 482 97 483 rect 61 481 97 482 rect 60 480 98 481 rect 59 479 98 480 rect 58 478 99 479 rect 57 477 99 478 rect 56 476 100 477 rect 55 475 100 476 rect 54 474 101 475 rect 53 473 101 474 rect 52 471 102 473 rect 52 469 103 471 rect 52 467 104 469 rect 52 465 105 467 rect 52 463 106 465 rect 52 461 107 463 rect 52 460 108 461 rect 52 459 78 460 rect 79 459 108 460 rect 52 458 77 459 rect 52 457 76 458 rect 80 457 109 459 rect 52 456 75 457 rect 52 455 74 456 rect 81 455 110 457 rect 52 454 73 455 rect 52 313 72 454 rect 82 453 111 455 rect 83 451 112 453 rect 84 449 113 451 rect 85 447 114 449 rect 86 445 115 447 rect 87 443 116 445 rect 88 441 117 443 rect 89 439 118 441 rect 90 437 119 439 rect 91 435 120 437 rect 92 433 121 435 rect 93 431 122 433 rect 94 429 123 431 rect 95 427 124 429 rect 96 425 125 427 rect 97 423 126 425 rect 98 421 127 423 rect 99 419 128 421 rect 100 417 129 419 rect 101 415 130 417 rect 102 413 131 415 rect 103 411 132 413 rect 104 409 133 411 rect 105 407 134 409 rect 106 405 135 407 rect 107 403 136 405 rect 108 401 137 403 rect 109 399 138 401 rect 110 397 139 399 rect 111 395 140 397 rect 112 393 141 395 rect 113 391 142 393 rect 114 389 143 391 rect 115 387 144 389 rect 116 385 145 387 rect 117 383 146 385 rect 118 381 147 383 rect 119 379 148 381 rect 120 377 149 379 rect 121 375 150 377 rect 122 373 151 375 rect 123 371 152 373 rect 124 369 153 371 rect 125 367 154 369 rect 126 365 155 367 rect 127 363 156 365 rect 128 361 157 363 rect 129 359 158 361 rect 130 357 159 359 rect 131 355 160 357 rect 132 353 161 355 rect 133 351 162 353 rect 172 352 192 493 rect 171 351 192 352 rect 134 349 163 351 rect 170 350 192 351 rect 169 349 192 350 rect 135 347 164 349 rect 168 348 192 349 rect 167 347 192 348 rect 136 346 165 347 rect 166 346 192 347 rect 136 345 192 346 rect 137 343 192 345 rect 138 341 192 343 rect 139 339 192 341 rect 140 337 192 339 rect 141 335 192 337 rect 142 333 192 335 rect 212 352 232 493 rect 272 492 492 493 rect 271 491 492 492 rect 270 490 492 491 rect 269 489 492 490 rect 268 488 492 489 rect 267 487 492 488 rect 266 486 492 487 rect 265 485 492 486 rect 264 484 492 485 rect 263 483 492 484 rect 262 482 492 483 rect 261 481 492 482 rect 260 480 492 481 rect 259 479 492 480 rect 258 478 492 479 rect 257 477 492 478 rect 256 476 492 477 rect 255 475 492 476 rect 254 474 492 475 rect 253 473 492 474 rect 252 472 291 473 rect 252 471 290 472 rect 252 470 289 471 rect 252 469 288 470 rect 252 468 287 469 rect 252 467 286 468 rect 252 466 285 467 rect 252 465 284 466 rect 252 464 283 465 rect 252 463 282 464 rect 252 462 281 463 rect 252 461 280 462 rect 252 460 279 461 rect 252 459 278 460 rect 252 458 277 459 rect 252 457 276 458 rect 252 456 275 457 rect 252 455 274 456 rect 252 454 273 455 rect 252 432 272 454 rect 252 431 273 432 rect 252 430 274 431 rect 252 429 275 430 rect 252 428 276 429 rect 252 427 277 428 rect 252 426 278 427 rect 252 425 279 426 rect 252 424 280 425 rect 252 423 281 424 rect 252 422 282 423 rect 252 421 283 422 rect 252 420 284 421 rect 252 419 285 420 rect 252 418 286 419 rect 252 417 287 418 rect 252 416 288 417 rect 252 415 289 416 rect 252 414 290 415 rect 252 413 291 414 rect 253 412 372 413 rect 254 411 373 412 rect 255 410 374 411 rect 256 409 375 410 rect 257 408 376 409 rect 258 407 377 408 rect 259 406 378 407 rect 260 405 379 406 rect 261 404 380 405 rect 262 403 381 404 rect 263 402 382 403 rect 264 401 383 402 rect 265 400 384 401 rect 266 399 385 400 rect 267 398 386 399 rect 268 397 387 398 rect 269 396 388 397 rect 270 395 389 396 rect 271 394 390 395 rect 272 393 391 394 rect 353 392 392 393 rect 354 391 392 392 rect 355 390 392 391 rect 356 389 392 390 rect 357 388 392 389 rect 358 387 392 388 rect 359 386 392 387 rect 360 385 392 386 rect 361 384 392 385 rect 362 383 392 384 rect 363 382 392 383 rect 364 381 392 382 rect 365 380 392 381 rect 366 379 392 380 rect 367 378 392 379 rect 368 377 392 378 rect 369 376 392 377 rect 370 375 392 376 rect 371 374 392 375 rect 372 352 392 374 rect 212 351 233 352 rect 371 351 392 352 rect 212 350 234 351 rect 370 350 392 351 rect 212 349 235 350 rect 369 349 392 350 rect 212 348 236 349 rect 368 348 392 349 rect 212 347 237 348 rect 367 347 392 348 rect 212 346 238 347 rect 366 346 392 347 rect 212 345 239 346 rect 365 345 392 346 rect 212 344 240 345 rect 364 344 392 345 rect 212 343 241 344 rect 363 343 392 344 rect 212 342 242 343 rect 362 342 392 343 rect 212 341 243 342 rect 361 341 392 342 rect 212 340 244 341 rect 360 340 392 341 rect 212 339 245 340 rect 359 339 392 340 rect 212 338 246 339 rect 358 338 392 339 rect 212 337 247 338 rect 357 337 392 338 rect 212 336 248 337 rect 356 336 392 337 rect 212 335 249 336 rect 355 335 392 336 rect 212 334 250 335 rect 354 334 392 335 rect 212 333 251 334 rect 353 333 392 334 rect 143 332 191 333 rect 213 332 392 333 rect 143 331 190 332 rect 214 331 390 332 rect 144 330 189 331 rect 215 330 389 331 rect 144 329 188 330 rect 216 329 388 330 rect 145 328 187 329 rect 217 328 387 329 rect 145 327 186 328 rect 218 327 386 328 rect 146 326 185 327 rect 219 326 385 327 rect 146 325 184 326 rect 220 325 384 326 rect 147 324 183 325 rect 221 324 383 325 rect 147 323 182 324 rect 222 323 382 324 rect 148 322 181 323 rect 223 322 381 323 rect 148 321 180 322 rect 224 321 380 322 rect 149 320 179 321 rect 225 320 379 321 rect 149 319 178 320 rect 226 319 378 320 rect 150 318 177 319 rect 227 318 377 319 rect 150 317 176 318 rect 228 317 376 318 rect 151 316 175 317 rect 229 316 375 317 rect 151 315 174 316 rect 230 315 374 316 rect 152 314 173 315 rect 231 314 373 315 rect 152 313 172 314 rect 232 313 372 314 rect 412 313 432 473 rect 508 419 658 449 rect 868 419 988 449 rect 568 329 598 419 rect 688 418 718 419 rect 808 418 838 419 rect 688 417 719 418 rect 807 417 838 418 rect 688 416 720 417 rect 806 416 838 417 rect 688 415 721 416 rect 805 415 838 416 rect 688 414 722 415 rect 804 414 838 415 rect 688 413 723 414 rect 803 413 838 414 rect 688 412 724 413 rect 802 412 838 413 rect 688 411 725 412 rect 801 411 838 412 rect 688 410 726 411 rect 800 410 838 411 rect 688 409 727 410 rect 799 409 838 410 rect 688 408 728 409 rect 798 408 838 409 rect 688 407 729 408 rect 797 407 838 408 rect 688 406 730 407 rect 796 406 838 407 rect 688 405 731 406 rect 795 405 838 406 rect 688 404 732 405 rect 794 404 838 405 rect 688 403 733 404 rect 793 403 838 404 rect 688 402 734 403 rect 792 402 838 403 rect 688 401 735 402 rect 791 401 838 402 rect 688 400 736 401 rect 790 400 838 401 rect 688 399 737 400 rect 789 399 838 400 rect 688 398 738 399 rect 788 398 838 399 rect 688 397 739 398 rect 787 397 838 398 rect 688 396 740 397 rect 786 396 838 397 rect 688 395 741 396 rect 785 395 838 396 rect 688 394 742 395 rect 784 394 838 395 rect 688 393 743 394 rect 783 393 838 394 rect 688 392 744 393 rect 782 392 838 393 rect 688 391 745 392 rect 781 391 838 392 rect 688 390 746 391 rect 780 390 838 391 rect 688 389 747 390 rect 779 389 838 390 rect 688 388 748 389 rect 778 388 838 389 rect 688 387 749 388 rect 777 387 838 388 rect 688 386 750 387 rect 776 386 838 387 rect 688 385 751 386 rect 775 385 838 386 rect 688 384 752 385 rect 774 384 838 385 rect 688 383 753 384 rect 773 383 838 384 rect 688 382 754 383 rect 772 382 838 383 rect 688 381 755 382 rect 771 381 838 382 rect 688 380 756 381 rect 770 380 838 381 rect 688 379 757 380 rect 769 379 838 380 rect 688 378 758 379 rect 768 378 838 379 rect 688 377 759 378 rect 767 377 838 378 rect 688 376 760 377 rect 766 376 838 377 rect 688 375 761 376 rect 765 375 838 376 rect 688 374 762 375 rect 764 374 838 375 rect 688 359 838 374 rect 868 389 898 419 rect 868 359 988 389 rect 508 299 658 329 rect 503 284 518 289 rect 520 286 525 289 rect 508 274 513 284 rect 520 283 527 286 rect 520 280 529 283 rect 530 280 535 289 rect 537 284 552 289 rect 554 284 569 289 rect 571 284 586 289 rect 588 284 603 289 rect 520 278 535 280 rect 503 269 518 274 rect 520 269 525 278 rect 526 275 535 278 rect 528 272 535 275 rect 530 269 535 272 rect 542 269 547 284 rect 554 281 559 284 rect 554 276 564 281 rect 554 274 559 276 rect 571 274 576 284 rect 588 281 593 284 rect 598 281 603 284 rect 579 276 586 281 rect 581 274 586 276 rect 554 269 569 274 rect 571 269 586 274 rect 588 276 603 281 rect 605 284 620 289 rect 622 284 637 289 rect 639 284 654 289 rect 658 288 668 289 rect 658 287 670 288 rect 658 284 672 287 rect 605 281 610 284 rect 615 281 620 284 rect 605 276 620 281 rect 588 275 601 276 rect 588 274 602 275 rect 588 269 593 274 rect 594 273 603 274 rect 595 272 603 273 rect 596 271 603 272 rect 597 270 603 271 rect 598 269 603 270 rect 605 269 610 276 rect 615 269 620 276 rect 627 269 632 284 rect 639 281 644 284 rect 639 276 649 281 rect 639 274 644 276 rect 658 274 663 284 rect 665 283 673 284 rect 667 282 673 283 rect 668 276 673 282 rect 667 275 673 276 rect 665 274 673 275 rect 639 269 654 274 rect 658 271 672 274 rect 658 270 670 271 rect 658 269 668 270 rect 688 269 718 359 rect 719 358 807 359 rect 720 357 806 358 rect 721 356 805 357 rect 722 355 804 356 rect 723 354 803 355 rect 724 353 802 354 rect 725 352 801 353 rect 726 351 800 352 rect 727 350 799 351 rect 728 349 798 350 rect 729 348 797 349 rect 730 347 796 348 rect 731 346 795 347 rect 732 345 794 346 rect 733 344 793 345 rect 734 343 792 344 rect 735 342 791 343 rect 736 341 790 342 rect 737 340 789 341 rect 738 339 788 340 rect 739 338 787 339 rect 740 337 786 338 rect 741 336 785 337 rect 742 335 784 336 rect 743 334 783 335 rect 744 333 782 334 rect 745 332 781 333 rect 746 331 780 332 rect 747 330 779 331 rect 748 329 778 330 rect 749 328 777 329 rect 750 327 776 328 rect 751 326 775 327 rect 752 325 774 326 rect 753 324 773 325 rect 754 323 772 324 rect 755 322 771 323 rect 756 321 770 322 rect 757 320 769 321 rect 758 319 768 320 rect 759 318 767 319 rect 760 317 766 318 rect 761 316 765 317 rect 762 315 764 316 rect 808 269 838 359 rect 958 329 988 359 rect 868 299 988 329 rect 863 284 878 289 rect 880 286 885 289 rect 895 286 900 289 rect 880 284 887 286 rect 863 281 868 284 rect 882 283 887 284 rect 893 284 900 286 rect 902 284 917 289 rect 919 284 934 289 rect 936 284 951 289 rect 953 286 958 289 rect 968 286 973 289 rect 893 283 898 284 rect 882 281 889 283 rect 863 276 878 281 rect 884 280 889 281 rect 891 281 898 283 rect 902 281 907 284 rect 891 280 896 281 rect 884 278 896 280 rect 873 274 878 276 rect 886 275 894 278 rect 902 276 917 281 rect 863 269 878 274 rect 888 269 893 275 rect 912 274 917 276 rect 902 269 917 274 rect 924 269 929 284 rect 936 281 941 284 rect 953 283 960 286 rect 966 283 973 286 rect 936 276 946 281 rect 953 280 962 283 rect 964 280 973 283 rect 953 278 973 280 rect 936 274 941 276 rect 936 269 951 274 rect 953 269 958 278 rect 959 275 967 278 rect 968 269 973 278 rect 975 284 990 289 rect 975 281 980 284 rect 975 276 990 281 rect 985 274 990 276 rect 975 269 990 274 rect 666 251 671 254 rect 681 251 686 254 rect 666 248 673 251 rect 679 248 686 251 rect 666 245 675 248 rect 677 245 686 248 rect 666 243 686 245 rect 666 234 671 243 rect 672 240 680 243 rect 681 234 686 243 rect 688 249 703 254 rect 705 249 720 254 rect 688 246 693 249 rect 705 246 710 249 rect 715 246 720 249 rect 688 241 698 246 rect 705 241 720 246 rect 722 249 737 254 rect 722 246 727 249 rect 722 241 737 246 rect 688 239 693 241 rect 688 234 703 239 rect 705 234 710 241 rect 715 234 720 241 rect 732 239 737 241 rect 722 234 737 239 rect 739 239 744 254 rect 749 239 754 254 rect 739 234 754 239 rect 756 249 771 254 rect 756 246 761 249 rect 766 246 771 249 rect 756 241 771 246 rect 774 249 789 254 rect 791 251 796 254 rect 806 251 811 254 rect 774 246 779 249 rect 791 248 798 251 rect 804 248 811 251 rect 774 241 784 246 rect 791 245 800 248 rect 802 245 811 248 rect 791 243 811 245 rect 756 240 769 241 rect 756 239 770 240 rect 774 239 779 241 rect 756 234 761 239 rect 762 238 771 239 rect 763 237 771 238 rect 764 236 771 237 rect 765 235 771 236 rect 766 234 771 235 rect 774 234 789 239 rect 791 234 796 243 rect 797 240 805 243 rect 806 234 811 243 rect 813 249 828 254 rect 830 251 835 254 rect 813 246 818 249 rect 830 248 837 251 rect 813 241 823 246 rect 830 245 839 248 rect 840 245 845 254 rect 847 249 862 254 rect 830 243 845 245 rect 813 239 818 241 rect 813 234 828 239 rect 830 234 835 243 rect 836 240 845 243 rect 838 237 845 240 rect 840 234 845 237 rect 852 234 857 249 << metal1 >> rect 105 210 155 220 rect 105 170 115 210 rect 125 170 135 210 rect 145 170 155 210 rect 165 210 195 220 rect 205 210 255 220 rect 165 200 175 210 rect 165 190 185 200 rect 165 180 175 190 rect 165 170 195 180 rect 205 170 215 210 rect 225 170 235 210 rect 245 170 255 210 rect 265 210 295 220 rect 265 200 275 210 rect 265 190 295 200 rect 285 180 295 190 rect 265 170 295 180 rect 345 180 355 220 rect 385 210 415 220 rect 425 210 455 220 rect 395 180 405 210 rect 425 200 435 210 rect 445 200 455 210 rect 425 190 455 200 rect 425 180 435 190 rect 445 180 455 190 rect 345 170 375 180 rect 385 170 415 180 rect 425 170 455 180 rect 465 215 490 220 rect 465 210 495 215 rect 465 200 475 210 rect 485 200 495 210 rect 505 210 535 220 rect 505 200 515 210 rect 525 200 535 210 rect 465 190 490 200 rect 505 190 535 200 rect 465 170 475 190 rect 485 170 495 190 rect 505 170 515 190 rect 525 170 535 190 rect 545 215 570 220 rect 545 210 575 215 rect 545 200 555 210 rect 565 200 575 210 rect 585 200 595 220 rect 605 200 615 220 rect 545 190 570 200 rect 585 190 615 200 rect 545 170 555 190 rect 565 170 575 190 rect 595 170 605 190 use open-80x80 2_0 timestamp 760840415 transform 1 0 -210 0 1 259 box 488 -239 568 -159 use open-oxide-80x80 3_0 timestamp 760840453 transform 1 0 -359 0 1 142 box 637 -242 717 -162 use thermal-converter 4_0 timestamp 760840748 transform 1 0 461 0 1 10 box -16 -110 134 110 use thermal-actuator 5_0 timestamp 760840666 transform 1 0 675 0 1 -100 box 0 0 90 220 use pixel-80x80 6_0 timestamp 760840526 transform 1 0 -430 0 1 -336 box 497 -3 587 87 use pixel-160x160 7_0 timestamp 760840608 transform 1 0 -80 0 1 -367 box 288 -12 458 158 use micro-hot-plate 8_0 timestamp 760840982 transform 1 0 420 0 1 -430 box 0 0 260 266 use gas-sensor 9_0 timestamp 760840948 transform 1 0 720 0 1 -430 box 0 0 260 266 << end >> magic-8.0.210/scmos/examples/nist-mems-library/thermal-actuator.cif0000644000175000001440000000143510751423606023740 0ustar timusersDS 1 1 2; 9 thermal-actuator; L CMF; B 4000 35000 9000 21500; B 11000 4000 5500 2000; L CPG; B 4000 35000 9000 21500; B 11000 4000 12500 2000; L CAA; B 14000 4000 9000 42000; B 4000 32000 4000 24000; B 4000 32000 14000 24000; L CVA; B 14000 4000 9000 42000; B 4000 32000 4000 24000; B 4000 32000 14000 24000; L CCA; B 14000 4000 9000 42000; B 4000 32000 4000 24000; B 4000 32000 14000 24000; L CCP; B 400 400 8600 38400; B 400 400 9400 38400; B 400 400 8600 37600; B 400 400 9400 37600; L COG; B 14000 4000 9000 42000; B 4000 32000 4000 24000; B 4000 32000 14000 24000; L COP; B 14000 4000 9000 42000; B 4000 32000 4000 24000; B 4000 32000 14000 24000; 94 Vin 2000 2000; 94 Vout 16000 2000; DF; C 1; End magic-8.0.210/scmos/examples/nist-mems-library/pixel-80x80.mag0000644000175000001440000001062710751423606022400 0ustar timusersmagic tech scmos timestamp 760840526 << polysilicon >> rect 528 56 534 58 rect 528 28 530 56 rect 532 45 534 56 rect 536 56 542 58 rect 536 45 538 56 rect 532 43 538 45 rect 540 45 542 56 rect 544 56 550 58 rect 544 45 546 56 rect 540 43 546 45 rect 548 45 550 56 rect 552 57 558 58 rect 552 53 553 57 rect 557 53 558 57 rect 552 52 558 53 rect 552 48 553 52 rect 557 48 558 52 rect 552 47 558 48 rect 553 45 557 47 rect 548 43 557 45 rect 532 39 538 41 rect 532 28 534 39 rect 528 26 534 28 rect 536 28 538 39 rect 540 39 546 41 rect 540 28 542 39 rect 536 26 542 28 rect 544 28 546 39 rect 548 39 557 41 rect 548 28 550 39 rect 553 37 557 39 rect 544 26 550 28 rect 552 36 558 37 rect 552 32 553 36 rect 557 32 558 36 rect 552 31 558 32 rect 552 27 553 31 rect 557 27 558 31 rect 552 26 558 27 << metal1 >> rect 576 81 582 82 rect 576 79 577 81 rect 575 78 577 79 rect 574 77 577 78 rect 581 77 582 81 rect 573 76 582 77 rect 572 75 579 76 rect 571 74 578 75 rect 570 73 577 74 rect 569 72 576 73 rect 568 71 575 72 rect 567 70 574 71 rect 566 69 573 70 rect 565 68 572 69 rect 564 67 571 68 rect 563 66 570 67 rect 562 65 569 66 rect 561 64 568 65 rect 560 63 567 64 rect 559 62 566 63 rect 558 61 565 62 rect 557 60 564 61 rect 556 59 563 60 rect 555 58 562 59 rect 552 57 561 58 rect 552 53 553 57 rect 557 56 560 57 rect 557 55 559 56 rect 557 53 558 55 rect 552 52 558 53 rect 552 48 553 52 rect 557 48 558 52 rect 552 47 558 48 rect 552 36 558 37 rect 552 32 553 36 rect 557 32 558 36 rect 552 31 558 32 rect 552 27 553 31 rect 557 29 558 31 rect 557 28 559 29 rect 557 27 560 28 rect 552 26 561 27 rect 555 25 562 26 rect 556 24 563 25 rect 557 23 564 24 rect 558 22 565 23 rect 559 21 566 22 rect 560 20 567 21 rect 561 19 568 20 rect 562 18 569 19 rect 563 17 570 18 rect 564 16 571 17 rect 565 15 572 16 rect 566 14 573 15 rect 567 13 574 14 rect 568 12 575 13 rect 569 11 576 12 rect 570 10 577 11 rect 571 9 578 10 rect 572 8 579 9 rect 573 7 580 8 rect 574 6 581 7 rect 575 5 582 6 rect 576 4 582 5 rect 577 3 582 4 rect 578 2 582 3 << metal2 >> rect 576 81 582 82 rect 576 77 577 81 rect 581 77 582 81 rect 576 76 582 77 << polycontact >> rect 553 53 557 57 rect 553 48 557 52 rect 553 32 557 36 rect 553 27 557 31 << m2contact >> rect 577 77 581 81 << substrateopen >> rect 512 81 572 82 rect 513 80 571 81 rect 514 79 570 80 rect 515 78 569 79 rect 516 77 568 78 rect 517 76 567 77 rect 518 75 566 76 rect 519 74 565 75 rect 520 73 564 74 rect 521 72 563 73 rect 502 71 503 72 rect 522 71 562 72 rect 581 71 582 72 rect 502 70 504 71 rect 523 70 561 71 rect 580 70 582 71 rect 502 69 505 70 rect 524 69 560 70 rect 579 69 582 70 rect 502 68 506 69 rect 525 68 559 69 rect 578 68 582 69 rect 502 67 507 68 rect 526 67 558 68 rect 577 67 582 68 rect 502 66 508 67 rect 527 66 557 67 rect 576 66 582 67 rect 502 65 509 66 rect 528 65 556 66 rect 575 65 582 66 rect 502 64 510 65 rect 529 64 555 65 rect 574 64 582 65 rect 502 63 511 64 rect 530 63 554 64 rect 573 63 582 64 rect 502 62 512 63 rect 572 62 582 63 rect 502 61 513 62 rect 571 61 582 62 rect 502 60 514 61 rect 570 60 582 61 rect 502 59 515 60 rect 569 59 582 60 rect 502 58 516 59 rect 568 58 582 59 rect 502 57 517 58 rect 567 57 582 58 rect 502 56 518 57 rect 566 56 582 57 rect 502 55 519 56 rect 565 55 582 56 rect 502 54 520 55 rect 564 54 582 55 rect 502 30 521 54 rect 563 30 582 54 rect 502 29 520 30 rect 564 29 582 30 rect 502 28 519 29 rect 565 28 582 29 rect 502 27 518 28 rect 566 27 582 28 rect 502 26 517 27 rect 567 26 582 27 rect 502 25 516 26 rect 568 25 582 26 rect 502 24 515 25 rect 569 24 582 25 rect 502 23 514 24 rect 570 23 582 24 rect 502 22 513 23 rect 571 22 582 23 rect 502 21 512 22 rect 572 21 582 22 rect 502 20 511 21 rect 530 20 554 21 rect 573 20 582 21 rect 502 19 510 20 rect 529 19 555 20 rect 574 19 582 20 rect 502 18 509 19 rect 528 18 556 19 rect 575 18 582 19 rect 502 17 508 18 rect 527 17 557 18 rect 576 17 582 18 rect 502 16 507 17 rect 526 16 558 17 rect 577 16 582 17 rect 502 15 506 16 rect 525 15 559 16 rect 578 15 582 16 rect 502 14 505 15 rect 524 14 560 15 rect 579 14 582 15 rect 502 13 504 14 rect 523 13 561 14 rect 580 13 582 14 rect 502 12 503 13 rect 522 12 562 13 rect 581 12 582 13 rect 521 11 563 12 rect 520 10 564 11 rect 519 9 565 10 rect 518 8 566 9 rect 517 7 567 8 rect 516 6 568 7 rect 515 5 569 6 rect 514 4 570 5 rect 513 3 571 4 rect 512 2 572 3 << pdiffusionstop >> rect 497 82 587 87 rect 497 2 502 82 rect 582 2 587 82 rect 497 -3 587 2 << end >> magic-8.0.210/scmos/examples/nist-mems-library/nist_mems_lib.doc0000644000175000001440000000577310751423606023325 0ustar timusersThe following are the cell names and cell descriptions of sample layouts designed at NIST for micromechanical designs. 1. open-80x80 A MEMS test structure to check the progress of the EDP etchant on an intended 80 um x 80 um cavity. This design consists of a single open tile. 2. open-oxide-80x80 An additional MEMS test structure to check the progress of the etchant on an intended 80 um x 80 um cavity with a trampoline-like suspended oxide. This design consists of four trapezoidal-shaped open tiles brought together in close vicinity such that the four cavities merge in the post-processing etch step creating one large 80 um x 80 um cavity with a suspended layer of oxide (see fig. 1). 3. thermal-converter A polysilicon (poly1) heater with a metal1/poly1 thermopile used as an ac power sensor. 4. thermal-actuator A cantilever structure consisting of poly1 with metal1 on top. These are connected at the end of the `diving board' and, when heated, the diving board bends upward due to the different thermal expansion coefficients of poly1 and metal1. 5. pixel-80x80 A heating element with an 80 um x 80 um cavity. The heating element is made of meandering polysilicon (poly1) and is suspended over top of the cavity with its encompassing oxide after the anisotropic etch. 6. pixel-160x160 Similar to the above structure but with a 160 um x 160 um cavity. 7. micro-hot-plate The microhotplate design consists of: a. A meandering polysilicon (poly1) heating element with two external connections. b. An aluminum (metal1) plate with four external connections over top of the polysilicon (poly1) heating element. There is an oxide separating the poly1 and metal1. The heat is uniformly distributed across this metal1 plate with the metal1 resistance changing linearly with temperature. The metal1 sheet resistance at the various temperatures can be obtained with a van der Pauw measurement. 8. gas-sensor The gas sensor design consists of the microhotplate design above with the addition of two layers: a. Four metal2 pads placed in the corners of the metal1 microhotplate (but not in contact with it). There are four external metal2 connections. b. Overglass openings centered on top of the metal2 pads. The metal2 pads and overglass openings allow a substance (e.g., tin oxide and palladium) to be placed on top of the whole pixel. When heated, the resistance of the substance changes in the presense of certain gases. The metal2 acts as a van der Pauw sheet resistor so the resistance change can be measured. This application of the microhotplate is called a gas sensor. (NIST has a patent pending on this gas sensor design.) magic-8.0.210/scmos/examples/nist-mems-library/thermal-actuator.mag0000644000175000001440000000070610751423606023743 0ustar timusersmagic tech scmos timestamp 760840666 << polysilicon >> rect 35 194 55 195 rect 35 186 41 194 rect 49 186 55 194 rect 35 20 55 186 rect 35 0 90 20 << metal1 >> rect 35 194 55 195 rect 35 186 41 194 rect 49 186 55 194 rect 35 20 55 186 rect 0 0 55 20 << polycontact >> rect 41 186 49 194 << substrateopen >> rect 10 200 80 220 rect 10 40 30 200 rect 60 40 80 200 << labels >> rlabel metal1 10 10 10 10 6 Vin rlabel polysilicon 80 10 80 10 6 Vout << end >> magic-8.0.210/scmos/examples/palette.mag0000644000175000001440000001414710751423606016553 0ustar timusersmagic tech scmos timestamp 775083658 << checkpaint >> rect 13 38 40 39 rect 5 37 40 38 rect 5 36 48 37 rect -42 32 -18 36 rect -46 24 -14 32 rect -54 20 -14 24 rect -90 -4 -66 20 rect -60 16 -14 20 rect -60 5 -6 16 rect 5 12 62 36 rect -60 4 -2 5 rect 5 4 70 12 rect -60 -4 70 4 rect -54 -8 70 -4 rect -51 -20 70 -8 rect -50 -28 -2 -20 rect 5 -22 54 -20 rect 22 -28 54 -22 rect -50 -30 -10 -28 << pwell >> rect 16 -10 20 -6 << nwell >> rect 0 -10 4 -6 << capwell >> rect 8 -10 12 -6 << highvoltnwell >> rect -8 -10 -4 -6 << highvoltpwell >> rect 24 -10 28 -6 << polysilicon >> rect 0 -2 4 2 << electrode >> rect 8 -2 12 2 << capacitor >> rect 16 -2 20 2 << wellcapacitor >> rect -40 -10 -36 -6 << ndiffusion >> rect -8 -2 -4 2 << pdiffusion >> rect 24 -2 28 2 << highvoltndiffusion >> rect -24 -2 -20 2 << highvoltpdiffusion >> rect 40 -2 44 2 << metal1 >> rect -24 22 -20 26 << metal2 >> rect -8 22 -4 26 << metal3 >> rect 8 22 12 26 << ntransistor >> rect -16 -10 -12 -6 << ptransistor >> rect 32 -10 36 -6 << entransistor >> rect -32 -10 -28 -6 << eptransistor >> rect 48 -10 52 -6 << doublentransistor >> rect -24 -10 -20 -6 << doubleptransistor >> rect 40 -10 44 -6 << highvoltntransistor >> rect -32 -2 -28 2 << highvoltptransistor >> rect 48 -2 52 2 << collector >> rect -24 14 -20 18 << emitter >> rect 8 14 12 18 << pbase >> rect 24 14 28 18 << bccdiffusion >> rect -16 14 -12 18 << nbccdiffusion >> rect -8 14 -4 18 << polycontact >> rect 0 6 4 10 << ndcontact >> rect -8 6 -4 10 << pdcontact >> rect 24 6 28 10 << highvoltndcontact >> rect -32 6 -28 10 << highvoltpdcontact >> rect 48 6 52 10 << capcontact >> rect 16 6 20 10 << electrodecontact >> rect 8 6 12 10 << collectorcontact >> rect -24 6 -20 10 << emittercontact >> rect 16 14 20 18 << pbasecontact >> rect 32 14 36 18 << nbccdiffcontact >> rect 0 14 4 18 << m2contact >> rect -16 22 -12 26 << m3contact >> rect 0 22 4 26 << psubstratepcontact >> rect 32 6 36 10 << nsubstratencontact >> rect -16 6 -12 10 << psubstratepdiff >> rect 32 -2 36 2 << nsubstratendiff >> rect -16 -2 -12 2 << highvoltpsubcontact >> rect 48 22 52 26 << highvoltnsubcontact >> rect -32 22 -28 26 << highvoltpsubdiff >> rect 48 14 52 18 << highvoltnsubdiff >> rect -32 14 -28 18 << nplusdoping >> rect -40 6 -36 10 << pplusdoping >> rect 40 6 44 10 << genericcontact >> rect 32 22 36 26 << substrateopen >> rect 40 22 44 26 << pdiffusionstop >> rect 40 14 44 18 << pad >> rect 16 22 20 26 << glass >> rect 24 22 28 26 << labels >> rlabel metal1 -24 22 -20 22 5 m1 rlabel m2contact -16 22 -12 22 5 m2c rlabel metal2 -8 22 -4 22 5 m2 rlabel capwell 8 -10 12 -10 5 cwell rlabel nwell 0 -10 4 -10 5 nwell rlabel ndiffusion -8 -2 -4 -2 5 ndiff rlabel polysilicon 0 -2 4 -2 5 poly rlabel electrode 8 -2 12 -2 5 poly2 rlabel nsubstratendiff -16 -2 -12 -2 5 nsd rlabel nsubstratencontact -16 6 -12 6 5 nsc rlabel collectorcontact -24 6 -20 6 5 clc rlabel ndcontact -8 6 -4 6 5 ndc rlabel polycontact 0 6 4 6 5 pc rlabel electrodecontact 8 6 12 6 5 ec rlabel emitter 8 14 12 14 5 em rlabel nbccdiffcontact 0 14 4 14 5 nbdc rlabel nbccdiffusion -8 14 -4 14 5 nbd rlabel bccdiffusion -16 14 -12 14 5 bd rlabel collector -24 14 -20 14 5 col rlabel metal3 8 22 12 22 5 m3 rlabel m3contact 0 22 4 22 5 m3c rlabel metal1 -22 24 -22 24 1 1 rlabel m2contact -14 24 -14 24 1 2 rlabel metal2 -6 24 -6 24 1 3 rlabel m3contact 2 24 2 24 1 4 rlabel metal3 10 24 10 24 1 5 rlabel collectorcontact -22 8 -22 8 1 21 rlabel nsubstratencontact -14 8 -14 8 1 22 rlabel ndcontact -6 8 -6 8 1 23 rlabel polycontact 2 8 2 8 1 24 rlabel electrodecontact 10 8 10 8 1 25 rlabel nsubstratendiff -14 0 -14 0 1 32 rlabel ndiffusion -6 0 -6 0 1 33 rlabel polysilicon 2 0 2 0 1 34 rlabel electrode 10 0 10 0 1 35 rlabel nwell 2 -8 2 -8 1 44 rlabel capwell 10 -8 10 -8 1 45 rlabel collector -22 16 -22 16 1 11 rlabel bccdiffusion -14 16 -14 16 1 12 rlabel nbccdiffusion -6 16 -6 16 1 13 rlabel nbccdiffcontact 2 16 2 16 1 14 rlabel emitter 10 16 10 16 1 15 rlabel pad 16 22 20 22 5 pad rlabel pwell 16 -10 20 -10 5 pwell rlabel capacitor 16 -2 20 -2 5 cap rlabel pdiffusion 24 -2 28 -2 5 pdiff rlabel emittercontact 16 14 20 14 5 emc rlabel pbase 24 14 28 14 5 pbase rlabel pbasecontact 32 14 36 14 5 pbc rlabel psubstratepcontact 32 6 36 6 5 psc rlabel pdcontact 24 6 28 6 5 pdc rlabel capcontact 16 6 20 6 5 capc rlabel psubstratepdiff 32 -2 36 -2 5 psd rlabel substrateopen 40 22 44 22 5 open rlabel pdiffusionstop 40 14 44 14 5 pstop rlabel glass 24 22 28 22 5 glass rlabel genericcontact 32 22 36 22 5 gc rlabel pad 18 24 18 24 1 6 rlabel glass 26 24 26 24 1 7 rlabel substrateopen 42 24 42 24 1 9 rlabel capcontact 18 8 18 8 1 26 rlabel pdcontact 26 8 26 8 1 27 rlabel psubstratepcontact 34 8 34 8 1 28 rlabel capacitor 18 0 18 0 1 36 rlabel pdiffusion 26 0 26 0 1 37 rlabel psubstratepdiff 34 0 34 0 1 38 rlabel pwell 18 -8 18 -8 1 46 rlabel emittercontact 18 16 18 16 1 16 rlabel pbase 26 16 26 16 1 17 rlabel pbasecontact 34 16 34 16 1 18 rlabel pdiffusionstop 42 16 42 16 1 19 rlabel genericcontact 34 24 34 24 1 8 rlabel highvoltntransistor -32 -2 -28 -2 5 hnfet rlabel highvoltndcontact -32 6 -28 6 5 hndc rlabel highvoltnsubdiff -32 14 -28 14 5 hnsd rlabel highvoltnsubcontact -32 22 -28 22 5 hnsc rlabel highvoltpsubcontact 48 22 52 22 5 hpsc rlabel highvoltpsubdiff 48 14 52 14 5 hpsd rlabel highvoltpdcontact 48 6 52 6 5 hpdc rlabel highvoltptransistor 48 -2 52 -2 5 hpfet rlabel highvoltpwell 24 -10 28 -10 5 hpwell rlabel doubleptransistor 40 -10 44 -10 5 pffet rlabel eptransistor 48 -10 52 -10 5 epfet rlabel doubleptransistor 42 -8 42 -8 1 47 rlabel eptransistor 50 -8 50 -8 1 48 rlabel ptransistor 32 -10 36 -10 5 pfet rlabel ptransistor 34 -8 34 -8 1 39 rlabel doublentransistor -24 -10 -20 -10 5 nffet rlabel entransistor -32 -10 -28 -10 5 enfet rlabel doublentransistor -22 -8 -22 -8 1 43 rlabel entransistor -30 -8 -30 -8 1 42 rlabel ntransistor -16 -10 -12 -10 5 nfet rlabel ntransistor -14 -8 -14 -8 1 31 rlabel highvoltnwell -8 -10 -4 -10 5 hnwell rlabel wellcapacitor -40 -10 -36 -10 5 wcap rlabel wellcapacitor -38 -8 -38 -8 1 41 rlabel highvoltndiffusion -24 -2 -20 -2 5 hndiff rlabel highvoltpdiffusion 40 -2 44 -2 5 hpdiff rlabel pplusdoping 40 6 44 6 5 pdop rlabel nplusdoping -40 6 -36 6 5 ndop << end >> magic-8.0.210/scmos/examples/poly_capacitor/0000755000175000001440000000000011504623577017436 5ustar timusersmagic-8.0.210/scmos/examples/poly_capacitor/cap_array.mag0000644000175000001440000000576610751423606022075 0ustar timusersmagic tech scmos timestamp 736115372 << capwell >> rect -3 -3 129 122 << polysilicon >> rect -1 103 0 107 rect -1 80 0 84 rect -1 57 0 61 rect -1 34 0 38 rect -1 11 0 15 << wellcapacitor >> rect 3 107 23 115 rect 26 107 46 115 rect 49 107 69 115 rect 72 107 92 115 rect 95 107 115 115 rect 3 103 115 107 rect 3 95 23 103 rect 26 95 46 103 rect 49 95 69 103 rect 72 95 92 103 rect 95 95 115 103 rect 11 92 15 95 rect 34 92 38 95 rect 57 92 61 95 rect 80 92 84 95 rect 103 92 107 95 rect 3 84 23 92 rect 26 84 46 92 rect 49 84 69 92 rect 72 84 92 92 rect 95 84 115 92 rect 3 80 115 84 rect 3 72 23 80 rect 26 72 46 80 rect 49 72 69 80 rect 72 72 92 80 rect 95 72 115 80 rect 11 69 15 72 rect 34 69 38 72 rect 57 69 61 72 rect 80 69 84 72 rect 103 69 107 72 rect 3 61 23 69 rect 26 61 46 69 rect 49 61 69 69 rect 72 61 92 69 rect 95 61 115 69 rect 3 57 115 61 rect 3 49 23 57 rect 26 49 46 57 rect 49 49 69 57 rect 72 49 92 57 rect 95 49 115 57 rect 11 46 15 49 rect 34 46 38 49 rect 57 46 61 49 rect 80 46 84 49 rect 103 46 107 49 rect 3 38 23 46 rect 26 38 46 46 rect 49 38 69 46 rect 72 38 92 46 rect 95 38 115 46 rect 3 34 115 38 rect 3 26 23 34 rect 26 26 46 34 rect 49 26 69 34 rect 72 26 92 34 rect 95 26 115 34 rect 11 23 15 26 rect 34 23 38 26 rect 57 23 61 26 rect 80 23 84 26 rect 103 23 107 26 rect 3 15 23 23 rect 26 15 46 23 rect 49 15 69 23 rect 72 15 92 23 rect 95 15 115 23 rect 3 11 115 15 rect 3 3 23 11 rect 26 3 46 11 rect 49 3 69 11 rect 72 3 92 11 rect 95 3 115 11 << ndiffusion >> rect 0 115 119 119 rect 0 107 3 115 rect 23 107 26 115 rect 46 107 49 115 rect 69 107 72 115 rect 92 107 95 115 rect 0 95 3 103 rect 23 95 26 103 rect 46 95 49 103 rect 69 95 72 103 rect 92 95 95 103 rect 115 95 119 115 rect 0 92 11 95 rect 15 92 34 95 rect 38 92 57 95 rect 61 92 80 95 rect 84 92 103 95 rect 107 92 119 95 rect 0 84 3 92 rect 23 84 26 92 rect 46 84 49 92 rect 69 84 72 92 rect 92 84 95 92 rect 0 72 3 80 rect 23 72 26 80 rect 46 72 49 80 rect 69 72 72 80 rect 92 72 95 80 rect 115 72 119 92 rect 0 69 11 72 rect 15 69 34 72 rect 38 69 57 72 rect 61 69 80 72 rect 84 69 103 72 rect 107 69 119 72 rect 0 61 3 69 rect 23 61 26 69 rect 46 61 49 69 rect 69 61 72 69 rect 92 61 95 69 rect 0 49 3 57 rect 23 49 26 57 rect 46 49 49 57 rect 69 49 72 57 rect 92 49 95 57 rect 115 49 119 69 rect 0 46 11 49 rect 15 46 34 49 rect 38 46 57 49 rect 61 46 80 49 rect 84 46 103 49 rect 107 46 119 49 rect 0 38 3 46 rect 23 38 26 46 rect 46 38 49 46 rect 69 38 72 46 rect 92 38 95 46 rect 0 26 3 34 rect 23 26 26 34 rect 46 26 49 34 rect 69 26 72 34 rect 92 26 95 34 rect 115 26 119 46 rect 0 23 11 26 rect 15 23 34 26 rect 38 23 57 26 rect 61 23 80 26 rect 84 23 103 26 rect 107 23 119 26 rect 0 15 3 23 rect 23 15 26 23 rect 46 15 49 23 rect 69 15 72 23 rect 92 15 95 23 rect 0 3 3 11 rect 23 3 26 11 rect 46 3 49 11 rect 69 3 72 11 rect 92 3 95 11 rect 115 3 119 23 rect 0 0 119 3 << ntransistor >> rect 0 103 3 107 rect 0 80 3 84 rect 0 57 3 61 rect 0 34 3 38 rect 0 11 3 15 << polycontact >> rect -5 3 -1 115 << ndcontact >> rect 119 0 123 119 << end >> magic-8.0.210/scmos/examples/linear_capacitor/0000755000175000001440000000000011504623577017725 5ustar timusersmagic-8.0.210/scmos/examples/linear_capacitor/wellcap.mag0000644000175000001440000000041710751423606022036 0ustar timusersmagic tech scmos timestamp 723775246 << capwell >> rect 0 0 30 24 << polysilicon >> rect 2 3 3 13 rect 2 1 24 3 << wellcapacitor >> rect 3 3 24 13 << ndiffusion >> rect 3 13 27 17 rect 24 3 27 13 << polycontact >> rect 2 -3 24 1 << ndcontact >> rect 3 17 27 21 << end >> magic-8.0.210/scmos/examples/linear_capacitor/wellcap.cif0000644000175000001440000000142010751423606022026 0ustar timusers( @@user : pi ); ( @@machine : dirac.isi.edu ); ( @@source : wellcap.mag ); ( @@tool : Magic 6.4.4 ); ( @@patch : 1 ); ( @@patchnames : release-6.4, linux1 ); ( @@compiled : Fri Jan 13 16:46:31 PST 1995 ); ( @@technology : scmos ); ( @@version : 8.2.6 ); ( @@techdesc : MOSIS Scalable CMOS Technology for Tight Metal Rules ); ( @@style : lambda=0.6(gen) ); ( @@date : Fri Jun 2 11:15:52 1995 ); DS 1 30 2; 9 wellcap; L CWC; B 120 96 60 48; L CMF; B 96 16 60 76; B 88 16 52 -4; L CPG; B 88 64 52 20; L CAA; B 96 72 60 48; L CCA; B 8 8 20 76; B 8 8 36 76; B 8 8 52 76; B 8 8 68 76; B 8 8 84 76; B 8 8 100 76; L CCP; B 8 8 20 -4; B 8 8 36 -4; B 8 8 52 -4; B 8 8 68 -4; B 8 8 84 -4; L CSN; B 112 88 60 48; DF; C 1; End magic-8.0.210/scmos/examples/ccd/0000755000175000001440000000000011504623577015157 5ustar timusersmagic-8.0.210/scmos/examples/ccd/ccd_array.mag0000644000175000001440000003154710751423606017600 0ustar timusersmagic tech scmos timestamp 813531883 << polysilicon >> rect -51 5 -48 15 rect -40 13 -34 15 rect -32 13 -25 15 rect -23 13 -16 15 rect -14 13 -7 15 rect -5 13 2 15 rect 4 13 11 15 rect 13 13 20 15 rect 22 13 29 15 rect 31 13 38 15 rect 40 13 47 15 rect 49 13 56 15 rect 58 13 65 15 rect 67 13 74 15 rect 76 13 83 15 rect 85 13 92 15 rect 94 13 101 15 rect 103 13 110 15 rect 112 13 119 15 rect 121 13 128 15 rect 130 13 137 15 rect 139 13 146 15 rect 148 13 155 15 rect 157 13 164 15 rect 166 13 173 15 rect 175 13 182 15 rect 184 13 191 15 rect 193 13 200 15 rect 202 13 209 15 rect 211 13 218 15 rect 220 13 227 15 rect -40 5 -36 13 rect -30 5 -27 13 rect -21 5 -18 13 rect -12 5 -9 13 rect -3 5 0 13 rect 6 5 9 13 rect 15 5 18 13 rect 24 5 27 13 rect 33 5 36 13 rect 42 5 45 13 rect 51 5 54 13 rect 60 5 63 13 rect 69 5 72 13 rect 78 5 81 13 rect 87 5 90 13 rect 96 5 99 13 rect 105 5 108 13 rect 114 5 117 13 rect 123 5 126 13 rect 132 5 135 13 rect 141 5 144 13 rect 150 5 153 13 rect 159 5 162 13 rect 168 5 171 13 rect 177 5 180 13 rect 186 5 189 13 rect 195 5 198 13 rect 204 5 207 13 rect 213 5 216 13 rect 222 5 225 13 rect 239 5 242 15 << electrode >> rect -34 5 -32 13 rect -25 5 -23 13 rect -16 5 -14 13 rect -7 5 -5 13 rect 2 5 4 13 rect 11 5 13 13 rect 20 5 22 13 rect 29 5 31 13 rect 38 5 40 13 rect 47 5 49 13 rect 56 5 58 13 rect 65 5 67 13 rect 74 5 76 13 rect 83 5 85 13 rect 92 5 94 13 rect 101 5 103 13 rect 110 5 112 13 rect 119 5 121 13 rect 128 5 130 13 rect 137 5 139 13 rect 146 5 148 13 rect 155 5 157 13 rect 164 5 166 13 rect 173 5 175 13 rect 182 5 184 13 rect 191 5 193 13 rect 200 5 202 13 rect 209 5 211 13 rect 218 5 220 13 rect 227 5 231 13 rect -36 3 -30 5 rect -36 -1 -35 3 rect -31 -1 -30 3 rect -36 -2 -30 -1 rect -27 3 -21 5 rect -27 -1 -26 3 rect -22 -1 -21 3 rect -27 -2 -21 -1 rect -18 3 -12 5 rect -18 -1 -17 3 rect -13 -1 -12 3 rect -18 -2 -12 -1 rect -9 3 -3 5 rect -9 -1 -8 3 rect -4 -1 -3 3 rect -9 -2 -3 -1 rect 0 3 6 5 rect 0 -1 1 3 rect 5 -1 6 3 rect 0 -2 6 -1 rect 9 3 15 5 rect 9 -1 10 3 rect 14 -1 15 3 rect 9 -2 15 -1 rect 18 3 24 5 rect 18 -1 19 3 rect 23 -1 24 3 rect 18 -2 24 -1 rect 27 3 33 5 rect 27 -1 28 3 rect 32 -1 33 3 rect 27 -2 33 -1 rect 36 3 42 5 rect 36 -1 37 3 rect 41 -1 42 3 rect 36 -2 42 -1 rect 45 3 51 5 rect 45 -1 46 3 rect 50 -1 51 3 rect 45 -2 51 -1 rect 54 3 60 5 rect 54 -1 55 3 rect 59 -1 60 3 rect 54 -2 60 -1 rect 63 3 69 5 rect 63 -1 64 3 rect 68 -1 69 3 rect 63 -2 69 -1 rect 72 3 78 5 rect 72 -1 73 3 rect 77 -1 78 3 rect 72 -2 78 -1 rect 81 3 87 5 rect 81 -1 82 3 rect 86 -1 87 3 rect 81 -2 87 -1 rect 90 3 96 5 rect 90 -1 91 3 rect 95 -1 96 3 rect 90 -2 96 -1 rect 99 3 105 5 rect 99 -1 100 3 rect 104 -1 105 3 rect 99 -2 105 -1 rect 108 3 114 5 rect 108 -1 109 3 rect 113 -1 114 3 rect 108 -2 114 -1 rect 117 3 123 5 rect 117 -1 118 3 rect 122 -1 123 3 rect 117 -2 123 -1 rect 126 3 132 5 rect 126 -1 127 3 rect 131 -1 132 3 rect 126 -2 132 -1 rect 135 3 141 5 rect 135 -1 136 3 rect 140 -1 141 3 rect 135 -2 141 -1 rect 144 3 150 5 rect 144 -1 145 3 rect 149 -1 150 3 rect 144 -2 150 -1 rect 153 3 159 5 rect 153 -1 154 3 rect 158 -1 159 3 rect 153 -2 159 -1 rect 162 3 168 5 rect 162 -1 163 3 rect 167 -1 168 3 rect 162 -2 168 -1 rect 171 3 177 5 rect 171 -1 172 3 rect 176 -1 177 3 rect 171 -2 177 -1 rect 180 3 186 5 rect 180 -1 181 3 rect 185 -1 186 3 rect 180 -2 186 -1 rect 189 3 195 5 rect 189 -1 190 3 rect 194 -1 195 3 rect 189 -2 195 -1 rect 198 3 204 5 rect 198 -1 199 3 rect 203 -1 204 3 rect 198 -2 204 -1 rect 207 3 213 5 rect 207 -1 208 3 rect 212 -1 213 3 rect 207 -2 213 -1 rect 216 3 222 5 rect 216 -1 217 3 rect 221 -1 222 3 rect 216 -2 222 -1 rect 225 3 231 5 rect 225 -1 226 3 rect 230 -1 231 3 rect 225 -2 231 -1 << capacitor >> rect -36 5 -34 13 rect -32 5 -30 13 rect -27 5 -25 13 rect -23 5 -21 13 rect -18 5 -16 13 rect -14 5 -12 13 rect -9 5 -7 13 rect -5 5 -3 13 rect 0 5 2 13 rect 4 5 6 13 rect 9 5 11 13 rect 13 5 15 13 rect 18 5 20 13 rect 22 5 24 13 rect 27 5 29 13 rect 31 5 33 13 rect 36 5 38 13 rect 40 5 42 13 rect 45 5 47 13 rect 49 5 51 13 rect 54 5 56 13 rect 58 5 60 13 rect 63 5 65 13 rect 67 5 69 13 rect 72 5 74 13 rect 76 5 78 13 rect 81 5 83 13 rect 85 5 87 13 rect 90 5 92 13 rect 94 5 96 13 rect 99 5 101 13 rect 103 5 105 13 rect 108 5 110 13 rect 112 5 114 13 rect 117 5 119 13 rect 121 5 123 13 rect 126 5 128 13 rect 130 5 132 13 rect 135 5 137 13 rect 139 5 141 13 rect 144 5 146 13 rect 148 5 150 13 rect 153 5 155 13 rect 157 5 159 13 rect 162 5 164 13 rect 166 5 168 13 rect 171 5 173 13 rect 175 5 177 13 rect 180 5 182 13 rect 184 5 186 13 rect 189 5 191 13 rect 193 5 195 13 rect 198 5 200 13 rect 202 5 204 13 rect 207 5 209 13 rect 211 5 213 13 rect 216 5 218 13 rect 220 5 222 13 rect 225 5 227 13 << metal1 >> rect -84 -19 -81 21 rect -77 -11 -74 29 rect -70 -3 -67 37 rect -56 19 -53 42 rect -40 19 -37 37 rect -31 19 -28 22 rect -22 19 -19 29 rect -13 19 -10 37 rect -4 19 -1 22 rect 5 19 8 29 rect 14 19 17 37 rect 23 19 26 22 rect 32 19 35 29 rect 41 19 44 37 rect 50 19 53 22 rect 59 19 62 29 rect 68 19 71 37 rect 77 19 80 22 rect 86 19 89 29 rect 95 19 98 37 rect 104 19 107 22 rect 113 19 116 29 rect 122 19 125 37 rect 131 19 134 22 rect 140 19 143 29 rect 149 19 152 37 rect 158 19 161 22 rect 167 19 170 29 rect 176 19 179 37 rect 185 19 188 22 rect 194 19 197 29 rect 203 19 206 37 rect 212 19 215 22 rect 221 19 224 29 rect 228 19 231 37 rect 244 19 247 42 rect -56 16 -52 19 rect 243 16 247 19 rect -60 7 -57 11 rect -60 5 -53 7 rect -60 1 -57 5 rect -60 -7 -53 1 rect -84 -22 -82 -19 rect -64 -23 -53 -7 rect -46 -23 -43 7 rect -35 -11 -32 -1 rect -26 -4 -23 -1 rect -17 -19 -14 -1 rect -8 -11 -5 -1 rect 1 -4 4 -1 rect 10 -19 13 -1 rect 19 -11 22 -1 rect 28 -4 31 -1 rect 37 -19 40 -1 rect 46 -11 49 -1 rect 55 -4 58 -1 rect 64 -19 67 -1 rect 73 -11 76 -1 rect 82 -4 85 -1 rect 91 -19 94 -1 rect 100 -11 103 -1 rect 109 -4 112 -1 rect 118 -19 121 -1 rect 127 -11 130 -1 rect 136 -4 139 -1 rect 145 -19 148 -1 rect 154 -11 157 -1 rect 163 -4 166 -1 rect 172 -19 175 -1 rect 181 -11 184 -1 rect 190 -4 193 -1 rect 199 -19 202 -1 rect 208 -11 211 -1 rect 217 -4 220 -1 rect 226 -19 229 -1 rect 234 -23 237 7 rect 248 7 251 11 rect 244 5 251 7 rect 248 1 251 5 rect 244 -7 251 1 rect 258 -3 261 37 rect 244 -23 255 -7 rect 265 -11 268 29 rect 272 -19 275 21 << metal2 >> rect -66 37 -40 40 rect -36 37 -13 40 rect -9 37 14 40 rect 18 37 41 40 rect 45 37 68 40 rect 72 37 95 40 rect 99 37 122 40 rect 126 37 149 40 rect 153 37 176 40 rect 180 37 203 40 rect 207 37 227 40 rect 231 37 257 40 rect -73 30 -22 33 rect -18 30 5 33 rect 9 30 32 33 rect 36 30 59 33 rect 63 30 86 33 rect 90 30 113 33 rect 117 30 140 33 rect 144 30 167 33 rect 171 30 194 33 rect 198 30 221 33 rect 225 30 264 33 rect -80 22 -31 25 rect -27 22 -4 25 rect 0 22 23 25 rect 27 22 50 25 rect 54 22 77 25 rect 81 22 104 25 rect 108 22 131 25 rect 135 22 158 25 rect 162 22 185 25 rect 189 22 212 25 rect 216 22 271 25 rect -64 5 255 18 rect -64 1 -57 5 rect -53 1 244 5 rect 248 1 255 5 rect -67 -7 -26 -4 rect -22 -7 1 -4 rect 5 -7 28 -4 rect 32 -7 55 -4 rect 59 -7 82 -4 rect 86 -7 109 -4 rect 113 -7 136 -4 rect 140 -7 163 -4 rect 167 -7 190 -4 rect 194 -7 217 -4 rect 221 -7 258 -4 rect -74 -15 -35 -12 rect -31 -15 -8 -12 rect -4 -15 19 -12 rect 23 -15 46 -12 rect 50 -15 73 -12 rect 77 -15 100 -12 rect 104 -15 127 -12 rect 131 -15 154 -12 rect 158 -15 181 -12 rect 185 -15 208 -12 rect 212 -15 265 -12 rect -78 -22 -17 -19 rect -13 -22 10 -19 rect 14 -22 37 -19 rect 41 -22 64 -19 rect 68 -22 91 -19 rect 95 -22 118 -19 rect 122 -22 145 -19 rect 149 -22 172 -19 rect 176 -22 199 -19 rect 203 -22 226 -19 rect 230 -22 271 -19 << bccdiffusion >> rect -51 7 -48 11 rect -40 7 231 11 rect 239 7 242 11 << nbccdiffusion >> rect -53 7 -51 11 rect -48 7 -46 11 rect -42 7 -40 11 rect 231 7 233 11 rect 237 7 239 11 rect 242 7 244 11 << polycontact >> rect -52 15 -48 19 rect -40 15 -36 19 rect -31 15 -27 19 rect -22 15 -18 19 rect -13 15 -9 19 rect -4 15 0 19 rect 5 15 9 19 rect 14 15 18 19 rect 23 15 27 19 rect 32 15 36 19 rect 41 15 45 19 rect 50 15 54 19 rect 59 15 63 19 rect 68 15 72 19 rect 77 15 81 19 rect 86 15 90 19 rect 95 15 99 19 rect 104 15 108 19 rect 113 15 117 19 rect 122 15 126 19 rect 131 15 135 19 rect 140 15 144 19 rect 149 15 153 19 rect 158 15 162 19 rect 167 15 171 19 rect 176 15 180 19 rect 185 15 189 19 rect 194 15 198 19 rect 203 15 207 19 rect 212 15 216 19 rect 221 15 225 19 rect 239 15 243 19 << electrodecontact >> rect -35 -1 -31 3 rect -26 -1 -22 3 rect -17 -1 -13 3 rect -8 -1 -4 3 rect 1 -1 5 3 rect 10 -1 14 3 rect 19 -1 23 3 rect 28 -1 32 3 rect 37 -1 41 3 rect 46 -1 50 3 rect 55 -1 59 3 rect 64 -1 68 3 rect 73 -1 77 3 rect 82 -1 86 3 rect 91 -1 95 3 rect 100 -1 104 3 rect 109 -1 113 3 rect 118 -1 122 3 rect 127 -1 131 3 rect 136 -1 140 3 rect 145 -1 149 3 rect 154 -1 158 3 rect 163 -1 167 3 rect 172 -1 176 3 rect 181 -1 185 3 rect 190 -1 194 3 rect 199 -1 203 3 rect 208 -1 212 3 rect 217 -1 221 3 rect 226 -1 230 3 << nbccdiffcontact >> rect -57 7 -53 11 rect -46 7 -42 11 rect 233 7 237 11 rect 244 7 248 11 << m2contact >> rect -70 37 -66 41 rect -77 29 -73 33 rect -84 21 -80 25 rect -40 37 -36 41 rect -13 37 -9 41 rect 14 37 18 41 rect 41 37 45 41 rect 68 37 72 41 rect 95 37 99 41 rect 122 37 126 41 rect 149 37 153 41 rect 176 37 180 41 rect 203 37 207 41 rect 227 37 231 41 rect -22 29 -18 33 rect -31 22 -27 26 rect 5 29 9 33 rect -4 22 0 26 rect 32 29 36 33 rect 23 22 27 26 rect 59 29 63 33 rect 50 22 54 26 rect 86 29 90 33 rect 77 22 81 26 rect 113 29 117 33 rect 104 22 108 26 rect 140 29 144 33 rect 131 22 135 26 rect 167 29 171 33 rect 158 22 162 26 rect 194 29 198 33 rect 185 22 189 26 rect 221 29 225 33 rect 212 22 216 26 rect 257 37 261 41 rect -71 -7 -67 -3 rect -57 1 -53 5 rect -78 -15 -74 -11 rect -82 -23 -78 -19 rect -26 -8 -22 -4 rect -35 -15 -31 -11 rect 1 -8 5 -4 rect -8 -15 -4 -11 rect 28 -8 32 -4 rect 19 -15 23 -11 rect 55 -8 59 -4 rect 46 -15 50 -11 rect 82 -8 86 -4 rect 73 -15 77 -11 rect 109 -8 113 -4 rect 100 -15 104 -11 rect 136 -8 140 -4 rect 127 -15 131 -11 rect 163 -8 167 -4 rect 154 -15 158 -11 rect 190 -8 194 -4 rect 181 -15 185 -11 rect 217 -8 221 -4 rect 208 -15 212 -11 rect -17 -23 -13 -19 rect 10 -23 14 -19 rect 37 -23 41 -19 rect 64 -23 68 -19 rect 91 -23 95 -19 rect 118 -23 122 -19 rect 145 -23 149 -19 rect 172 -23 176 -19 rect 199 -23 203 -19 rect 226 -23 230 -19 rect 244 1 248 5 rect 264 29 268 33 rect 258 -7 262 -3 rect 271 21 275 25 rect 265 -15 269 -11 rect 271 -23 275 -19 << psubstratepcontact >> rect -64 -7 -60 11 rect 251 -7 255 11 << psubstratepdiff >> rect -64 21 255 27 rect -64 11 -60 21 rect 251 11 255 21 rect -60 -7 251 -3 rect -64 -9 255 -7 << labels >> rlabel metal2 -35 30 -32 33 0 c2 rlabel metal2 -8 30 -5 33 0 c2 rlabel metal2 19 30 22 33 0 c2 rlabel metal2 46 30 49 33 0 c2 rlabel metal2 73 30 76 33 0 c2 rlabel metal2 100 30 103 33 0 c2 rlabel metal2 127 30 130 33 0 c2 rlabel metal2 154 30 157 33 0 c2 rlabel metal2 181 30 184 33 0 c2 rlabel metal2 208 30 211 33 0 c2 rlabel metal2 -35 37 -32 40 0 c1 rlabel metal2 -8 37 -5 40 0 c1 rlabel metal2 19 37 22 40 0 c1 rlabel metal2 46 37 49 40 0 c1 rlabel metal2 73 37 76 40 0 c1 rlabel metal2 100 37 103 40 0 c1 rlabel metal2 127 37 130 40 0 c1 rlabel metal2 154 37 157 40 0 c1 rlabel metal2 181 37 184 40 0 c1 rlabel metal2 208 37 211 40 0 c1 rlabel metal2 -35 22 -32 25 0 c3 rlabel metal2 -8 22 -5 25 0 c3 rlabel metal2 19 22 22 25 0 c3 rlabel metal2 46 22 49 25 0 c3 rlabel metal2 73 22 76 25 0 c3 rlabel metal2 100 22 103 25 0 c3 rlabel metal2 127 22 130 25 0 c3 rlabel metal2 154 22 157 25 0 c3 rlabel metal2 181 22 184 25 0 c3 rlabel metal2 208 22 211 25 0 c3 rlabel metal2 -39 -7 -36 -4 0 c1 rlabel metal2 -12 -7 -9 -4 0 c1 rlabel metal2 15 -7 18 -4 0 c1 rlabel metal2 42 -7 45 -4 0 c1 rlabel metal2 69 -7 72 -4 0 c1 rlabel metal2 96 -7 99 -4 0 c1 rlabel metal2 123 -7 126 -4 0 c1 rlabel metal2 150 -7 153 -4 0 c1 rlabel metal2 177 -7 180 -4 0 c1 rlabel metal2 204 -7 207 -4 0 c1 rlabel metal2 -39 -15 -36 -12 0 c2 rlabel metal2 -12 -15 -9 -12 0 c2 rlabel metal2 15 -15 18 -12 0 c2 rlabel metal2 42 -15 45 -12 0 c2 rlabel metal2 69 -15 72 -12 0 c2 rlabel metal2 96 -15 99 -12 0 c2 rlabel metal2 123 -15 126 -12 0 c2 rlabel metal2 150 -15 153 -12 0 c2 rlabel metal2 177 -15 180 -12 0 c2 rlabel metal2 204 -15 207 -12 0 c2 rlabel metal2 -39 -22 -36 -19 0 c3 rlabel metal2 -12 -22 -9 -19 0 c3 rlabel metal2 15 -22 18 -19 0 c3 rlabel metal2 42 -22 45 -19 0 c3 rlabel metal2 69 -22 72 -19 0 c3 rlabel metal2 96 -22 99 -19 0 c3 rlabel metal2 123 -22 126 -19 0 c3 rlabel metal2 150 -22 153 -19 0 c3 rlabel metal2 177 -22 180 -19 0 c3 rlabel metal2 204 -22 207 -19 0 c3 rlabel metal2 222 -22 225 -19 0 c3 rlabel metal2 222 -15 225 -12 0 c2 rlabel metal2 222 -7 225 -4 0 c1 rlabel metal2 235 37 238 40 0 c1 rlabel metal2 235 22 238 25 0 c3 rlabel metal2 235 30 238 33 0 c2 rlabel polycontact 239 15 243 19 0 reset rlabel nbccdiffcontact 244 7 248 11 0 GND rlabel nbccdiffcontact -46 7 -42 11 0 input rlabel polycontact -52 15 -48 19 0 reset rlabel nbccdiffcontact -57 7 -53 11 0 GND rlabel nbccdiffcontact 233 7 237 11 0 output << end >> magic-8.0.210/scmos/examples/ccd/ccd.mag0000644000175000001440000000225510751423606016374 0ustar timusersmagic tech scmos timestamp 783829926 << error_p >> rect 0 -12 41 -10 rect -2 -16 0 -12 rect 41 -16 43 -12 rect 0 -18 41 -16 << polysilicon >> rect 12 6 15 14 rect 21 6 24 14 rect 30 6 35 14 rect 10 4 17 6 rect 10 0 11 4 rect 15 0 17 4 rect 19 4 26 6 rect 19 0 20 4 rect 24 0 26 4 rect 28 4 35 6 rect 28 0 29 4 rect 33 0 35 4 << electrode >> rect 6 20 12 21 rect 6 16 7 20 rect 11 16 12 20 rect 6 14 12 16 rect 15 20 21 21 rect 15 16 16 20 rect 20 16 21 20 rect 15 14 21 16 rect 24 20 30 21 rect 24 16 25 20 rect 29 16 30 20 rect 24 14 30 16 rect 6 6 10 14 rect 17 6 19 14 rect 26 6 28 14 << capacitor >> rect 10 6 12 14 rect 15 6 17 14 rect 19 6 21 14 rect 24 6 26 14 rect 28 6 30 14 << bccdiffusion >> rect 6 8 35 12 rect 0 -16 41 -12 << nbccdiffusion >> rect 4 8 6 12 rect 35 8 37 12 rect 4 -8 6 -4 rect 35 -8 37 -4 << polycontact >> rect 11 0 15 4 rect 20 0 24 4 rect 29 0 33 4 << electrodecontact >> rect 7 16 11 20 rect 16 16 20 20 rect 25 16 29 20 << nbccdiffcontact >> rect 0 8 4 12 rect 37 8 41 12 rect 0 -8 4 -4 rect 37 -8 41 -4 << labels >> rlabel space -5 -7 -5 -7 3 layer rlabel space -5 -5 -5 -5 3 active rlabel space -5 -13 -5 -13 3 well rlabel space -5 -15 -5 -15 3 layer << end >> magic-8.0.210/scmos/examples/ccd/qq.cif0000644000175000001440000003114210751423606016256 0ustar timusers( @@user : pi ); ( @@machine : dirac.isi.edu ); ( @@source : ccd_array.mag ); ( @@tool : Magic 6.4.4 ); ( @@patch : 1 ); ( @@patchnames : release-6.4, linux1 ); ( @@compiled : Fri Jan 13 16:46:31 PST 1995 ); ( @@technology : scmos ); ( @@version : 8.2.7 ); ( @@techdesc : MOSIS Scalable CMOS Technology for Standard Rules ); ( @@style : lambda=1.0(gen) ); ( @@date : Wed Dec 13 10:30:30 1995 ); DS 1 50 2; 9 ccd_array; L CWP; B 1300 48 382 96; B 40 72 -248 36; B 40 72 1012 36; B 1300 48 382 -24; L CMS; B 16 4 -272 162; B 16 4 -152 162; B 16 4 -44 162; B 16 4 64 162; B 16 4 172 162; B 16 4 280 162; B 16 4 388 162; B 16 4 496 162; B 16 4 604 162; B 16 4 712 162; B 16 4 820 162; B 16 4 916 162; B 16 4 1036 162; B 1324 12 382 154; B 1380 12 382 126; B 16 4 -300 118; B 16 4 -80 118; B 16 4 28 118; B 16 4 136 118; B 16 4 244 118; B 16 4 352 118; B 16 4 460 118; B 16 4 568 118; B 16 4 676 118; B 16 4 784 118; B 16 4 892 118; B 16 4 1064 118; B 16 4 -116 102; B 16 4 -8 102; B 16 4 100 102; B 16 4 208 102; B 16 4 316 102; B 16 4 424 102; B 16 4 532 102; B 16 4 640 102; B 16 4 748 102; B 16 4 856 102; B 1436 12 382 94; B 16 4 -328 86; B 16 4 1092 86; B 1276 68 382 38; B 16 4 -276 -14; B 16 4 1040 -14; B 1332 12 382 -22; B 16 4 -96 -30; B 16 4 12 -30; B 16 4 120 -30; B 16 4 228 -30; B 16 4 336 -30; B 16 4 444 -30; B 16 4 552 -30; B 16 4 660 -30; B 16 4 768 -30; B 16 4 876 -30; B 16 4 -304 -46; B 16 4 -132 -46; B 16 4 -24 -46; B 16 4 84 -46; B 16 4 192 -46; B 16 4 300 -46; B 16 4 408 -46; B 16 4 516 -46; B 16 4 624 -46; B 16 4 732 -46; B 16 4 840 -46; B 16 4 1068 -46; B 1388 12 382 -54; B 1428 12 386 -82; B 16 4 -320 -90; B 16 4 -60 -90; B 16 4 48 -90; B 16 4 156 -90; B 16 4 264 -90; B 16 4 372 -90; B 16 4 480 -90; B 16 4 588 -90; B 16 4 696 -90; B 16 4 804 -90; B 16 4 912 -90; B 16 4 1092 -90; L CMF; B 16 16 -272 156; B 16 16 -300 124; B 16 16 -328 92; B 12 160 -330 4; B 12 160 -302 36; B 12 160 -274 68; B 12 92 -218 122; B 16 16 -152 156; B 16 16 -44 156; B 16 16 64 156; B 16 16 172 156; B 16 16 280 156; B 16 16 388 156; B 16 16 496 156; B 16 16 604 156; B 16 16 712 156; B 16 16 820 156; B 16 16 916 156; B 12 72 -154 112; B 16 16 -80 124; B 16 16 -116 96; B 12 12 -118 82; B 12 40 -82 96; B 12 72 -46 112; B 16 16 28 124; B 16 16 -8 96; B 12 12 -10 82; B 12 40 26 96; B 12 72 62 112; B 16 16 136 124; B 16 16 100 96; B 12 12 98 82; B 12 40 134 96; B 12 72 170 112; B 16 16 244 124; B 16 16 208 96; B 12 12 206 82; B 12 40 242 96; B 12 72 278 112; B 16 16 352 124; B 16 16 316 96; B 12 12 314 82; B 12 40 350 96; B 12 72 386 112; B 16 16 460 124; B 16 16 424 96; B 12 12 422 82; B 12 40 458 96; B 12 72 494 112; B 16 16 568 124; B 16 16 532 96; B 12 12 530 82; B 12 40 566 96; B 12 72 602 112; B 16 16 676 124; B 16 16 640 96; B 12 12 638 82; B 12 40 674 96; B 12 72 710 112; B 16 16 784 124; B 16 16 748 96; B 12 12 746 82; B 12 40 782 96; B 12 72 818 112; B 16 16 892 124; B 16 16 856 96; B 12 12 854 82; B 12 40 890 96; B 12 72 918 112; B 12 92 982 122; B 16 16 1036 156; B 32 12 -208 70; B 16 4 -200 62; B 16 16 -152 68; B 16 16 -116 68; B 16 16 -80 68; B 16 16 -44 68; B 16 16 -8 68; B 16 16 28 68; B 16 16 64 68; B 16 16 100 68; B 16 16 136 68; B 16 16 172 68; B 16 16 208 68; B 16 16 244 68; B 16 16 280 68; B 16 16 316 68; B 16 16 352 68; B 16 16 388 68; B 16 16 424 68; B 16 16 460 68; B 16 16 496 68; B 16 16 532 68; B 16 16 568 68; B 16 16 604 68; B 16 16 640 68; B 16 16 676 68; B 16 16 712 68; B 16 16 748 68; B 16 16 784 68; B 16 16 820 68; B 16 16 856 68; B 16 16 892 68; B 32 12 972 70; B 16 4 964 62; B 16 16 -276 -20; B 16 16 -304 -52; B 24 12 -324 -82; B 16 4 -320 -90; B 44 136 -234 -24; B 16 16 -176 36; B 16 16 940 36; B 12 120 -178 -32; B 16 16 -132 4; B 16 16 -96 4; B 16 16 -60 4; B 16 16 -24 4; B 16 16 12 4; B 16 16 48 4; B 16 16 84 4; B 16 16 120 4; B 16 16 156 4; B 16 16 192 4; B 16 16 228 4; B 16 16 264 4; B 16 16 300 4; B 16 16 336 4; B 16 16 372 4; B 16 16 408 4; B 16 16 444 4; B 16 16 480 4; B 16 16 516 4; B 16 16 552 4; B 16 16 588 4; B 16 16 624 4; B 16 16 660 4; B 16 16 696 4; B 16 16 732 4; B 16 16 768 4; B 16 16 804 4; B 16 16 840 4; B 16 16 876 4; B 16 16 912 4; B 12 40 -134 -24; B 12 12 -98 -10; B 16 16 -96 -24; B 16 16 -132 -52; B 12 72 -62 -40; B 12 40 -26 -24; B 12 12 10 -10; B 16 16 12 -24; B 16 16 -24 -52; B 12 72 46 -40; B 12 40 82 -24; B 12 12 118 -10; B 16 16 120 -24; B 16 16 84 -52; B 12 72 154 -40; B 12 40 190 -24; B 12 12 226 -10; B 16 16 228 -24; B 16 16 192 -52; B 12 72 262 -40; B 12 40 298 -24; B 12 12 334 -10; B 16 16 336 -24; B 16 16 300 -52; B 12 72 370 -40; B 12 40 406 -24; B 12 12 442 -10; B 16 16 444 -24; B 16 16 408 -52; B 12 72 478 -40; B 12 40 514 -24; B 12 12 550 -10; B 16 16 552 -24; B 16 16 516 -52; B 12 72 586 -40; B 12 40 622 -24; B 12 12 658 -10; B 16 16 660 -24; B 16 16 624 -52; B 12 72 694 -40; B 12 40 730 -24; B 12 12 766 -10; B 16 16 768 -24; B 16 16 732 -52; B 12 72 802 -40; B 12 40 838 -24; B 12 12 874 -10; B 16 16 876 -24; B 16 16 840 -52; B 12 72 910 -40; B 16 16 -60 -84; B 16 16 48 -84; B 16 16 156 -84; B 16 16 264 -84; B 16 16 372 -84; B 16 16 480 -84; B 16 16 588 -84; B 16 16 696 -84; B 16 16 804 -84; B 16 16 912 -84; B 12 120 942 -32; B 44 136 998 -24; B 12 160 1038 68; B 16 16 1064 124; B 16 16 1040 -20; B 12 160 1066 36; B 16 16 1092 92; B 16 16 1068 -52; B 12 160 1094 4; B 16 16 1092 -84; L CPG; B 16 16 -200 68; B 12 40 -198 40; B 16 16 -152 68; B 16 16 -116 68; B 16 16 -80 68; B 16 16 -44 68; B 16 16 -8 68; B 16 16 28 68; B 16 16 64 68; B 16 16 100 68; B 16 16 136 68; B 16 16 172 68; B 16 16 208 68; B 16 16 244 68; B 16 16 280 68; B 16 16 316 68; B 16 16 352 68; B 16 16 388 68; B 16 16 424 68; B 16 16 460 68; B 16 16 496 68; B 16 16 532 68; B 16 16 568 68; B 16 16 604 68; B 16 16 640 68; B 16 16 676 68; B 16 16 712 68; B 16 16 748 68; B 16 16 784 68; B 16 16 820 68; B 16 16 856 68; B 16 16 892 68; B 16 16 964 68; B 24 40 -148 40; B 28 40 -114 40; B 28 40 -78 40; B 28 40 -42 40; B 28 40 -6 40; B 28 40 30 40; B 28 40 66 40; B 28 40 102 40; B 28 40 138 40; B 28 40 174 40; B 28 40 210 40; B 28 40 246 40; B 28 40 282 40; B 28 40 318 40; B 28 40 354 40; B 28 40 390 40; B 28 40 426 40; B 28 40 462 40; B 28 40 498 40; B 28 40 534 40; B 28 40 570 40; B 28 40 606 40; B 28 40 642 40; B 28 40 678 40; B 28 40 714 40; B 28 40 750 40; B 28 40 786 40; B 28 40 822 40; B 28 40 858 40; B 28 40 894 40; B 12 40 962 40; L CAA; B 1276 24 382 96; B 16 96 -248 36; B 1220 16 382 36; B 16 96 1012 36; B 1276 24 382 -24; L CVA; B 8 8 -272 156; B 8 8 -152 156; B 8 8 -44 156; B 8 8 64 156; B 8 8 172 156; B 8 8 280 156; B 8 8 388 156; B 8 8 496 156; B 8 8 604 156; B 8 8 712 156; B 8 8 820 156; B 8 8 916 156; B 8 8 1036 156; B 8 8 -300 124; B 8 8 -80 124; B 8 8 28 124; B 8 8 136 124; B 8 8 244 124; B 8 8 352 124; B 8 8 460 124; B 8 8 568 124; B 8 8 676 124; B 8 8 784 124; B 8 8 892 124; B 8 8 1064 124; B 8 8 -328 92; B 8 8 -116 96; B 8 8 -8 96; B 8 8 100 96; B 8 8 208 96; B 8 8 316 96; B 8 8 424 96; B 8 8 532 96; B 8 8 640 96; B 8 8 748 96; B 8 8 856 96; B 8 8 1092 92; B 8 8 -220 12; B 8 8 984 12; B 8 8 -276 -20; B 8 8 -96 -24; B 8 8 12 -24; B 8 8 120 -24; B 8 8 228 -24; B 8 8 336 -24; B 8 8 444 -24; B 8 8 552 -24; B 8 8 660 -24; B 8 8 768 -24; B 8 8 876 -24; B 8 8 1040 -20; B 8 8 -304 -52; B 8 8 -132 -52; B 8 8 -24 -52; B 8 8 84 -52; B 8 8 192 -52; B 8 8 300 -52; B 8 8 408 -52; B 8 8 516 -52; B 8 8 624 -52; B 8 8 732 -52; B 8 8 840 -52; B 8 8 1068 -52; B 8 8 -320 -84; B 8 8 -60 -84; B 8 8 48 -84; B 8 8 156 -84; B 8 8 264 -84; B 8 8 372 -84; B 8 8 480 -84; B 8 8 588 -84; B 8 8 696 -84; B 8 8 804 -84; B 8 8 912 -84; B 8 8 1092 -84; L CEL; B 24 60 -132 22; B 24 60 -96 22; B 24 60 -60 22; B 24 60 -24 22; B 24 60 12 22; B 24 60 48 22; B 24 60 84 22; B 24 60 120 22; B 24 60 156 22; B 24 60 192 22; B 24 60 228 22; B 24 60 264 22; B 24 60 300 22; B 24 60 336 22; B 24 60 372 22; B 24 60 408 22; B 24 60 444 22; B 24 60 480 22; B 24 60 516 22; B 24 60 552 22; B 24 60 588 22; B 24 60 624 22; B 24 60 660 22; B 24 60 696 22; B 24 60 732 22; B 24 60 768 22; B 24 60 804 22; B 24 60 840 22; B 24 60 876 22; B 24 60 912 22; L CCE; B 8 8 -132 4; B 8 8 -96 4; B 8 8 -60 4; B 8 8 -24 4; B 8 8 12 4; B 8 8 48 4; B 8 8 84 4; B 8 8 120 4; B 8 8 156 4; B 8 8 192 4; B 8 8 228 4; B 8 8 264 4; B 8 8 300 4; B 8 8 336 4; B 8 8 372 4; B 8 8 408 4; B 8 8 444 4; B 8 8 480 4; B 8 8 516 4; B 8 8 552 4; B 8 8 588 4; B 8 8 624 4; B 8 8 660 4; B 8 8 696 4; B 8 8 732 4; B 8 8 768 4; B 8 8 804 4; B 8 8 840 4; B 8 8 876 4; B 8 8 912 4; L CCA; B 8 8 -220 36; B 8 8 -176 36; B 8 8 940 36; B 8 8 984 36; L CCA; B 8 8 -248 32; B 8 8 1012 32; B 8 8 -248 16; B 8 8 1012 16; B 8 8 -248 0; B 8 8 1012 0; B 8 8 -248 -16; B 8 8 1012 -16; L CCP; B 8 8 -200 68; B 8 8 -152 68; B 8 8 -116 68; B 8 8 -80 68; B 8 8 -44 68; B 8 8 -8 68; B 8 8 28 68; B 8 8 64 68; B 8 8 100 68; B 8 8 136 68; B 8 8 172 68; B 8 8 208 68; B 8 8 244 68; B 8 8 280 68; B 8 8 316 68; B 8 8 352 68; B 8 8 388 68; B 8 8 424 68; B 8 8 460 68; B 8 8 496 68; B 8 8 532 68; B 8 8 568 68; B 8 8 604 68; B 8 8 640 68; B 8 8 676 68; B 8 8 712 68; B 8 8 748 68; B 8 8 784 68; B 8 8 820 68; B 8 8 856 68; B 8 8 892 68; B 8 8 964 68; L CSN; B 84 32 -194 36; B 84 32 958 36; L CSP; B 1292 40 382 96; B 32 24 -248 64; B 32 24 1012 64; B 28 32 -250 36; B 28 32 1014 36; B 32 24 -248 8; B 32 24 1012 8; B 1292 40 382 -24; L CCD; B 1236 32 382 36; 94 c2 -134 126 CMS; 94 c2 -26 126 CMS; 94 c2 82 126 CMS; 94 c2 190 126 CMS; 94 c2 298 126 CMS; 94 c2 406 126 CMS; 94 c2 514 126 CMS; 94 c2 622 126 CMS; 94 c2 730 126 CMS; 94 c2 838 126 CMS; 94 c1 -134 154 CMS; 94 c1 -26 154 CMS; 94 c1 82 154 CMS; 94 c1 190 154 CMS; 94 c1 298 154 CMS; 94 c1 406 154 CMS; 94 c1 514 154 CMS; 94 c1 622 154 CMS; 94 c1 730 154 CMS; 94 c1 838 154 CMS; 94 c3 -134 94 CMS; 94 c3 -26 94 CMS; 94 c3 82 94 CMS; 94 c3 190 94 CMS; 94 c3 298 94 CMS; 94 c3 406 94 CMS; 94 c3 514 94 CMS; 94 c3 622 94 CMS; 94 c3 730 94 CMS; 94 c3 838 94 CMS; 94 c1 -150 -22 CMS; 94 c1 -42 -22 CMS; 94 c1 66 -22 CMS; 94 c1 174 -22 CMS; 94 c1 282 -22 CMS; 94 c1 390 -22 CMS; 94 c1 498 -22 CMS; 94 c1 606 -22 CMS; 94 c1 714 -22 CMS; 94 c1 822 -22 CMS; 94 c2 -150 -54 CMS; 94 c2 -42 -54 CMS; 94 c2 66 -54 CMS; 94 c2 174 -54 CMS; 94 c2 282 -54 CMS; 94 c2 390 -54 CMS; 94 c2 498 -54 CMS; 94 c2 606 -54 CMS; 94 c2 714 -54 CMS; 94 c2 822 -54 CMS; 94 c3 -150 -82 CMS; 94 c3 -42 -82 CMS; 94 c3 66 -82 CMS; 94 c3 174 -82 CMS; 94 c3 282 -82 CMS; 94 c3 390 -82 CMS; 94 c3 498 -82 CMS; 94 c3 606 -82 CMS; 94 c3 714 -82 CMS; 94 c3 822 -82 CMS; 94 c3 894 -82 CMS; 94 c2 894 -54 CMS; 94 c1 894 -22 CMS; 94 c1 946 154 CMS; 94 c3 946 94 CMS; 94 c2 946 126 CMS; 94 reset 964 68; 94 GND 984 36; 94 input -176 36; 94 reset -200 68; 94 GND -220 36; 94 output 940 36; DF; C 1; End magic-8.0.210/scmos/examples/float_gate/0000755000175000001440000000000011504623577016533 5ustar timusersmagic-8.0.210/scmos/examples/float_gate/float_gate.mag0000644000175000001440000000215510751423606021323 0ustar timusersmagic tech scmos timestamp 697876971 << polysilicon >> rect 0 16 2 18 rect 6 16 10 18 rect 24 16 29 18 rect 31 16 38 18 rect 40 16 42 18 << poly2 >> rect 10 23 24 24 rect 10 18 11 23 rect 23 18 24 23 rect 29 18 31 21 rect 38 18 40 21 rect 10 11 11 16 rect 23 11 24 16 rect 29 14 31 16 rect 38 14 40 16 rect 10 10 24 11 rect 27 13 33 14 rect 10 8 16 10 rect 27 9 28 13 rect 32 9 33 13 rect 27 8 33 9 rect 36 13 42 14 rect 36 9 37 13 rect 41 9 42 13 rect 36 8 42 9 rect 10 4 11 8 rect 15 4 16 8 rect 10 3 16 4 << capacitor >> rect 11 18 23 23 rect 10 16 24 18 rect 29 16 31 18 rect 38 16 40 18 rect 11 11 23 16 << ndiffusion >> rect 2 18 6 19 rect 2 15 6 16 << ntransistor >> rect 2 16 6 18 << ndcontact >> rect 2 19 6 23 rect 2 11 6 15 << electrodecontact >> rect 28 9 32 13 rect 37 9 41 13 rect 11 4 15 8 << labels >> rlabel space 2 9 2 9 3 transistor rlabel space -10 18 -10 18 3 floating rlabel space -10 16 -10 16 3 gate rlabel space 27 6 27 6 3 erase rlabel space 27 4 27 4 3 voltage rlabel space 36 6 36 6 3 programming rlabel space 36 4 36 4 3 voltage rlabel space 10 1 10 1 3 control rlabel space 10 -1 10 -1 3 gate << end >> magic-8.0.210/scmos/mos.OpenGL.dstyle.mark0000644000175000001440000003554310751423606016714 0ustar timusers# # MOSIS distribution Version 8.2 # # This file has been updated by MOSIS to be used for three metal, two poly # SCMOS technology files. # # (C) Copyright 1992, 1993, 1994, 1995 by # # Jen-I Pi pi@isi.edu # The MOSIS Service # USC Information Sciences Institute # 4676 Admiralty Way # Marina del Rey, CA 90292 # (310) 822-1511 x640 fax (310)823-5624 # # All Rights Reserved. # Last Modified Date: 03/15/95 # # Permission to use, copy, modify, and distribute this technology # file and its associated documentation for any purpose and without # fee is hereby granted, provided that the above copyright notice # appears in all copies and that both that copyright notice and this # permission notice appear in supporting documentation, and that the # name of the University of Southern California not be used in # advertising or publicity pertaining to distribution of the software # without specific, written prior permission. The University of # Southern California makes no representations about the suitability # of this technology file for any purpose. This technology file is # provided "as is" without express or implied warranty and the # University of Southern California retains the right to change its # content at any time without notice any other party. # # THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS TECHNOLOGY FILE, INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF # SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS # OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS TECHNOLOGY FILE. # # This file describes the various display styles that are available # in Magic. This new file is relatively technology-independent: it # contains enough different styles to support MOSIS's SCMOS process # without any changes. Each display style describes a particular # way of drawing things on the display. See "Magic Maintainer's # Manual #3: The Display Style and Glyph Files" for details on the # file format. # # Please send bug reports/comments to mosis@mosis.edu :-) # # "version" keyword replaces the version embedded in the filename. version 6 # # There is no bit plane usage in OpenGL. # The "mask" column used by other style files represents # the degree of opacity in the OpenGL version of magic. # opaque = 000 is completely transparent (nothing gets drawn), # while opaque = 170 is completely opaque. Note that these # numbers are octal. The bit planes argument of the # display_styles is set to 24 so we don't lose any bits in # color definitions. # display_styles 24 # # The style below means "no color at all". It is special, in that # it is used by cursors to indicate transparency. # # num opaque color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 0 177 000 000 solid 0 - no_color_at_all # # Opaque styles used for drawing and erasing highlights, window borders, # etc. # stipple short long # num opaque color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 1 177 100 000 solid 0 - solid_highlights 2 134 100 000 stipple 12 - medium_highlights 3 134 100 000 stipple 9 - pale_highlights 4 134 100 000 stipple 10 - horiz_highlights 5 134 100 000 stipple 11 - vert_highlights 6 177 100 377 outline 0 - outline_highlights 7 134 100 314 outline 0 - dotted_highlights # 8 134 000 377 outline 0 e erase_box 9 177 000 000 solid 0 - erase_highlights 10 177 000 000 solid 0 E erase_everything 11 134 000 000 solid 0 - erase_all_but_highl # 12 134 073 377 outline 0 l labels 13 134 066 377 outline 0 L ports 14 177 040 377 outline 0 i port_connections 15 134 043 377 outline 0 - bounding_boxes 16 134 074 377 grid 0 - solid_grid 17 134 043 252 grid 0 - dotted_grid 18 134 043 000 solid 0 - origin_square 19 134 043 377 outline 0 - draw_tile_details # 20 177 067 000 solid 0 w window_border 21 177 067 377 stipple 6 - window_elevator 22 177 070 000 solid 0 c window_caption 23 177 071 000 solid 0 x window_background # 24 177 072 000 solid 0 - color_editing # 25 177 074 000 solid 0 T tk_medium_gray 26 177 076 000 solid 0 t tk_light_gray # # General-purpose opaque colors. These entries define a whole # bunch of generally-useful colors. # # stipple short long # num opaque color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 27 177 040 000 solid 0 W white 28 177 041 000 solid 0 - gray1 (pale) 29 177 042 000 solid 0 k gray2 (dark) 30 177 043 000 solid 0 K black 31 177 044 000 solid 0 r red1 (pale) 32 177 045 000 solid 0 - red2 (medium) 33 177 046 000 solid 0 R red3 (dark) 34 177 047 000 solid 0 g green1 (pale) 35 177 050 000 solid 0 - green2 (medium) 36 177 051 000 solid 0 G green3 (dark) 37 177 052 000 solid 0 b blue1 38 177 053 000 solid 0 B blue2 (dark) 39 177 054 000 solid 0 - blue3 40 177 055 000 solid 0 p purple1 41 177 056 000 solid 0 P purple2 42 177 057 000 solid 0 y yellow1 43 177 060 000 solid 0 Y yellow2 44 177 061 000 solid 0 o orange1 45 177 062 000 solid 0 O orange2 46 177 063 000 solid 0 n brown1 47 177 064 000 solid 0 N brown2 48 177 065 000 solid 0 m magenta 49 177 066 000 solid 0 C cyan # #---------------------------------------------------------------------- # All of the styles above this point are used internally by Magic for # things like menus, drawing the box, etc. The style numbers and # number of styles must match the definitions in misc/style.h. # All of the styles below this point are used by the technology file, # addressed by name or number. Note that the numbers are only for # backwards compatibility with .tech27 files which specify styles # by number only. The order in which styles are drawn is the order # in which they appear in this file, not the "num" column. The # ordinal numbering reflects vagaries of the 8-bit-plane setup. # 24-bit styles have been re-ordered to match the physical vertical # position of layers in the layout. #---------------------------------------------------------------------- layout_styles # # num opaque color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 10 077 006 000 stipple 7 - cwell 52 134 002 000 stipple 19 - cwellnsc 18 077 004 000 stipple 21 - highvolt_nwell 11 077 005 000 stipple 22 - highvolt_pwell 12 077 002 377 stipple 2 - nwell 13 077 003 377 stipple 2 - pwell 67 170 011 377 outline 0 - subcircuit 1 170 001 000 solid 0 - polysilicon 2 170 002 000 solid 0 - ndiffusion 69 177 050 000 solid 0 - mvndiff 70 177 051 000 solid 0 - hvndiff 71 177 054 000 solid 0 - ncontact 3 170 002 000 stipple 13 - ndiff_in_nwell 4 170 003 000 solid 0 - pdiffusion 72 177 063 000 solid 0 - mvpdiff 73 177 064 000 solid 0 - hvpdiff 74 177 055 000 solid 0 - pcontact 5 170 003 000 stipple 13 - pdiff_in_pwell 6 170 004 000 solid 0 - ntransistor 7 170 002 000 stipple 8 - ntransistor_stripes 8 170 005 000 solid 0 - ptransistor 9 170 003 000 stipple 9 - ptransistor_stripes 53 134 007 000 stipple 7 - nwell_field_implant 54 134 007 000 stipple 5 - substrate_field_implant 30 134 002 000 stipple 22 - ndop_stripes 31 134 003 000 stipple 21 - pdop_stripes 36 134 002 377 stipple 15 - nselect 35 134 003 377 stipple 1 - pselect 43 134 002 000 stipple 5 - nselect2 44 134 003 000 stipple 7 - pselect2 47 134 001 000 solid 0 - poly_resist 48 134 003 000 stipple 7 - poly_resist_stripes 46 134 052 000 stipple 7 - silicide_block 14 134 006 000 solid 0 - electrode 27 134 003 000 stipple 9 - electrode_stripes 28 134 075 000 solid 0 - capacitor 15 134 003 000 stipple 10 - pbase 16 134 002 000 stipple 17 - emitter 17 134 003 000 stipple 11 - bccd 20 120 010 000 solid 0 - metal1 29 134 010 000 stipple 6 - metal1_alt 49 134 010 000 stipple 19 - metal1tight 26 134 011 000 solid 0 - poly_contact 21 120 020 000 solid 0 - metal2 50 134 020 000 stipple 19 - metal2tight 19 134 007 000 solid 0 - via # MNM hack 9-11-2003 55 134 143 377 stipple 29 - via1 22 120 065 000 solid 0 - metal3 51 134 065 000 stipple 8 - metal3tight 37 134 056 377 stipple 19 - via2 # MNM hack 9-11-2003 56 134 143 377 stipple 30 - via2alt 23 120 041 000 solid 0 - metal4 38 134 046 377 stipple 24 - via3 57 134 006 000 stipple 2 - via3alt 24 120 054 000 solid 0 - metal5 39 134 051 377 stipple 5 - via4 64 120 056 000 solid 0 - metal6 59 134 020 377 stipple 2 - via5 65 120 046 000 solid 0 - metal7 60 134 056 377 stipple 2 - via6 66 120 042 000 solid 0 - metal8 61 134 063 377 stipple 2 - via7 62 134 046 000 stipple 3 - mim_bottom 63 134 042 000 stipple 3 - mim_top 58 134 007 000 solid 0 - gen_contact 32 134 007 377 cross 0 - contact_X'es 33 134 007 377 stipple 2 - contact_waffle 25 134 045 000 solid 0 - pad4 34 134 042 377 stipple 10 - overglass 68 134 041 377 solid 0 - mems 40 134 065 000 stipple 5 - check_paint 41 134 066 000 stipple 7 - check_subcells 42 177 040 000 stipple 4 - error_waffle 45 134 043 000 solid 0 - comment # #---------------------------------------------------------------------- # All of the styles below this point must duplicate the styles in # the section above, and represent a version of each previous # layer to use in non-edit cells ("pale" styles): #---------------------------------------------------------------------- pale_styles # # Poly-diff styles: # stipple short long # num opaque color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 10 134 106 000 stipple 7 - cwell 52 134 002 000 stipple 13 - cwellnsc 18 134 107 000 stipple 21 - highvolt_nwell 11 134 105 000 stipple 22 - highvolt_pwell 12 134 102 377 stipple 2 - nwell 13 134 103 377 stipple 2 - pwell 67 134 111 377 outline 0 - subcircuit 1 134 101 000 solid 0 - polysilicon 2 134 102 000 solid 0 - ndiffusion 69 177 050 000 stipple 3 - mvndiff 70 177 051 000 stipple 3 - hvndiff 71 177 054 000 stipple 3 - ncontact 3 134 102 000 stipple 13 - ndiff_in_nwell 4 134 103 000 solid 0 - pdiffusion 72 177 063 000 stipple 25 - mvpdiff 73 177 064 000 stipple 25 - hvpdiff 74 177 055 000 stipple 25 - pcontact 5 134 103 000 stipple 13 - pdiff_in_pwell 6 134 104 000 solid 0 - ntransistor 7 134 102 000 stipple 7 - ntransistor_stripes 8 134 105 000 solid 0 - ptransistor 9 134 103 000 stipple 5 - ptransistor_stripes 53 134 007 000 stipple 7 - nwell_field_implant 54 134 007 000 stipple 5 - substrate_field_implant 30 134 102 000 stipple 22 - ndop_stripes 31 134 103 000 stipple 21 - pdop_stripes 36 134 102 377 stipple 15 - nselect 35 134 103 377 stipple 1 - pselect 43 134 002 000 stipple 5 - nselect2 44 134 003 000 stipple 7 - pselect2 47 134 001 000 solid 0 - poly_resist 48 134 003 000 stipple 7 - poly_resist_stripes 46 134 052 000 stipple 7 - silicide_block 14 134 106 000 solid 0 - electrode 27 134 103 000 stipple 9 - electrode_stripes 28 134 175 000 solid 0 - capacitor 15 134 103 000 stipple 10 - pbase 16 134 102 000 stipple 17 - emitter 17 134 103 000 stipple 11 - bccd 20 100 110 000 solid 0 - metal1 29 134 110 000 stipple 6 - metal1_alt 49 134 010 000 stipple 14 - metal1tight 26 134 111 000 solid 0 - poly_contact 21 100 120 000 solid 0 - metal2 50 134 020 000 stipple 5 - metal2tight 19 134 107 000 solid 0 - via #55 134 120 000 stipple 2 - via1 # MNM hack 9-11-2003 55 134 143 377 stipple 29 - via1 22 100 165 000 solid 0 - metal3 51 134 065 000 stipple 21 - metal3tight 37 134 156 377 stipple 19 - via2 # MNM hack 9-11-2003 56 134 143 377 stipple 30 - via2alt 23 100 141 000 solid 0 - metal4 38 134 146 377 stipple 24 - via3 57 134 106 000 stipple 2 - via3alt 24 100 154 000 solid 0 - metal5 39 134 151 377 stipple 5 - via4 64 100 156 000 solid 0 - metal6 59 134 120 377 stipple 2 - via5 65 100 146 000 solid 0 - metal7 60 134 156 377 stipple 2 - via6 66 100 142 000 solid 0 - metal8 61 134 163 377 stipple 2 - via7 62 134 146 000 stipple 3 - mim_bottom 63 134 142 000 stipple 3 - mim_top 58 134 042 000 solid 0 - gen_contact 32 134 143 377 cross 0 - contact_X'es 33 134 143 377 stipple 2 - contact_waffle 25 134 145 000 solid 0 - pad4 34 134 142 377 stipple 10 - overglass 68 134 141 377 solid 0 - mems 40 134 065 000 stipple 5 - check_paint 41 134 066 000 stipple 7 - check_subcells 42 177 040 000 stipple 4 - error_waffle 45 134 017 000 solid 0 - comment #---------------------------------------------------------------------- stipples #-----------------------------------+--------------------------------------- # bit pattern | description #-----------------------------------+--------------------------------------- 1 100 000 030 000 030 000 000 000 very sparsed stripes, ll to ur 2 314 314 000 000 063 063 000 000 coarse knight's move (waffle) 3 356 167 273 335 356 167 273 335 all but diagonal stripes, ll to ur 4 000 000 314 314 000 000 314 314 offset waffle 5 100 040 020 010 004 002 001 200 sparse diagonal stripes, ll to ur 6 252 125 252 125 252 125 252 125 half 'n half (checkerboard) 7 002 004 010 020 040 100 200 001 sparse diagonal stripes, lr to ul 8 201 003 006 014 030 060 140 300 wide sparse diagonal stripes, lr to ul 9 201 300 140 060 030 014 006 003 wide sparse diagonal stripes, ll to ur 10 000 000 000 377 000 000 000 377 horizontal stripes 11 104 104 104 104 104 104 104 104 vertical stripes 12 125 252 125 252 125 252 125 252 complement of half `n half 13 063 063 777 777 314 314 777 777 complement of #2 (coarse knight's move) 14 252 125 252 125 252 125 252 125 half 'n half (checkerboard) 15 000 001 000 030 000 000 000 030 very sparsed stripes, 11 to ur 16 300 007 377 377 300 007 377 377 wide horizontal stripes 17 307 307 307 307 307 307 307 307 wide vertical stripes 18 174 174 174 174 174 174 174 174 wide vertical stripes (reverse of 17) 19 074 303 102 102 303 074 044 044 bubbles 20 044 102 201 201 102 044 030 030 offset diagonal crossex 21 020 040 000 000 000 002 004 010 diagonal dotted line, lr to ul 22 010 004 000 000 000 100 040 020 diagonal dotted line, ll to ur 23 074 146 303 201 303 146 074 030 dense diagonal crossex 24 703 474 675 675 474 703 733 733 complement of #19 empty bubbles 25 335 273 167 356 335 273 167 356 all but diagonal stripes, lr to ul # attempt at new styles MNM 26 140 300 201 003 006 014 030 060 27 000 000 000 060 140 140 060 000 new gc thin 28 000 002 006 016 016 006 002 000 #29 000 000 000 000 030 074 176 000 29 000 176 074 030 000 000 000 000 #30 000 100 140 160 160 140 100 000 30 000 004 014 034 034 014 004 000 31 000 176 074 030 000 000 000 000 magic-8.0.210/scmos/README0000644000175000001440000001102310751423606013457 0ustar timusers####################################################################### # # # MOSIS distribution Version 8.2 # # # # This is a version control header file for MOSIS's distribution of # # Magic related technology files and system libraries.... # # # # Modified by Jen-I Pi, MOSIS Project, USC/ISI 06/02/1995 # # Please send bug reports/comments to mosis@mosis.edu :-) # # # ####################################################################### INTRODUCTION This officail MOSIS SCMOS technology release consists a famaly of SCMOS technology files for Magic version 6.4.4 (available from anonymous FTP gatekeeper.dec.com): * "scmos" - standard SCMOS technology for MOSIS process with minimum feature length larger than 1.5 micron. ORBIT 2.0 micron analog, ORBIT 1.2 micron processes are supported. * "scmos-tm" - SCMOS technology with tighter metal spacing rules for metal1 and metal2. HP-CMOS34, HP-CMOS26B (lambda=0.5 micron) and HP-CMOS14B (lambda=0.35 micron) processes are supported. * "scmos-sub" - SCMOS technology for HP's sub-micron CMOS processes. HP-CMOS26G (lambda=0.40 micron) and CMOS14B (lambda=0.30 micron) processes are supported. * "scmos-ibm" - SCMOS technology for IBM CMSX-2185 process. (not supported anymore, but it's there in case...) To invoke Magic with appropriate technology selection, you need to use the '-T' command option. For example, the command "magic -Tscmos-sub" start Magic with "scmos-sub" designated for HP's submicron processes. MOSIS's distribution of Magic technolofy file for SCMOS technology now has CIFinput and CIFoutput section in templates so that it will be easier to maintain. It also supports two layers, "open" and "pstop" for micro-machined design fabrication in CMOS process as described by Janet C. Marshall's paper in IEEE Circuit and Devices, Vol. 8, N0. 6, 1992. this layer is now in a 'preliminary' stage. Before installation, please read the file 'COPYRIGHT' for copyright notice. INSTALLATION Please install the latest release of Magic (version 6.4.4) available from anonymous FTP gatekeeper.dec.com. To generate all technology files, simply type "make" if your are using Magic 6.4.x, or "make version3" if your are using Magic 6.3.x To install all technology files into the standard ~cad library, just type "make install" to you system (Unix) prompt. You might want to check the path for standard ~cad/lib/magic/lib first before you do this... IRSIM PARAMETERS Parameter files of various MOSIS supported process for IRSIM switch-level simulator can be found under the sub-directory "irsim_parameters". DOCUMENTATION Please read the file UPDATE for the lates update information... In the doc subdirectory, you can find a preliminary PostScript file for MOSIS's SCMOS Technology Manual. Warning: This manualscript is in a very preliminary stage, if you have any problem with it don't hesitate to discuss it further with me...(pi@isi.edu) EXAMPLE In the 'examples' subdirectory, we have: palette.mag - palette of all layers available in MOSIS's SCMOS tech- nology". Turn your DRC off before viewing it!! ccd.mag - An example of a buried channel CCD layout. float_gate.mag - An example of a floating-gate device. wellcap.mag - An example of layout of linear capacitors available from SCNLC technology, i.e. HP's 1.2um process. npn.mag - An example of a Bipolar NPN transistor layout. For ORBIT's 2um lower-noise Analog process. large_npn.mag - A large NPN bipolar transistor consists of smalls unit transistors. all.mag - An example of part of the design rules... NOT Complete... m3padframe.mag - A TinyChip padframe for HP's 1.0um process. Notice that those m1 strip is required to complete a DRC free pad. These pads use all three metal layers. inf_source - An example of micromachined device fabrication. This layout is a reproduction of Fig. 8 of Janet C. Marshall's article titled "High Level Melds Micromachined Devices with Foundries", IEEE Circuits and Devices, Vol. 8, No. 6, pp. 10-17, Nov. 1992. A complete NIST MEMS library is also available from MOSIS's anonymous FTP archive. BUGs send you bug report or suggestions to mosis@mosis.edu Jen-I Pi ****** 05/24/95 The MOSIS Service, USC/ISI (310) 822-1511 x640 magic-8.0.210/scmos/mos.OpenGL.dstyle0000644000175000001440000003461611120112374015747 0ustar timusers# # Magic distribution Version 7.3 # # This file has been updated for 10-metal processes # # (C) Copyright 2001-2008 by # R. Timothy Edwards # MultiGiG, Inc., Scotts Valley, CA # # Last Modified Date: 12/03/03 # # This file describes the various display styles that are available # in Magic. Each display style describes a particular way of drawing # things on the display. See "Magic Maintainer's Manual #3: The # Display Style and Glyph Files" for details on the file format. # The "version" keyword replaces the version embedded in the filename. # Please send bug reports/comments to tim@opencircuitdesign.com version 8 # # There is no bit plane usage in OpenGL. # The "mask" column used by other style files represents # the degree of opacity in the OpenGL version of magic. # opaque = 0 is completely transparent (nothing gets drawn), # while opaque = 120 is completely opaque. Note that these # numbers are decimal (vs. octal in version 6 and earlier). # The bit planes argument of the display_styles is set to 24 # so we don't lose any bits in color definitions. display_styles 24 # # The style below means "no color at all". It is special, in that # it is used by cursors to indicate transparency. # # num opaque color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 0 127 0 0x00 solid 0 - no_color_at_all # # Opaque styles used for drawing and erasing highlights, window borders, # etc. # stipple short long # num opaque color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 1 127 64 0x00 solid 0 - solid_highlights 2 92 64 0x00 stipple 12 - medium_highlights 3 92 64 0x00 stipple 9 - pale_highlights 4 92 64 0x00 stipple 10 - horiz_highlights 5 92 64 0x00 stipple 11 - vert_highlights 6 127 64 0xff outline 0 - outline_highlights 7 92 64 0xcc outline 0 - dotted_highlights # 8 92 0 0xff outline 0 e erase_box 9 127 0 0x00 solid 0 - erase_highlights 10 127 0 0x00 solid 0 E erase_everything 11 92 0 0x00 solid 0 - erase_all_but_highl # 12 92 59 0xff outline 0 l labels 13 92 45 0xff outline 0 L ports 14 127 54 0xff outline 0 i port_connections 15 92 35 0xff outline 0 - bounding_boxes 16 92 60 0xff grid 0 - solid_grid 17 92 35 0xaa grid 0 - dotted_grid 18 92 35 0x00 solid 0 - origin_square 19 92 35 0xff outline 0 - draw_tile_details # 20 127 55 0x00 solid 0 w window_border 21 127 55 0xff stipple 6 - window_elevator 22 127 56 0x00 solid 0 c window_caption 23 127 57 0x00 solid 0 x window_background # 24 127 58 0x00 solid 0 - color_editing # 25 127 60 0x00 solid 0 T tk_medium_gray 26 127 62 0x00 solid 0 t tk_light_gray # 27 127 47 0xff outline 0 - pale_labels 28 127 80 0xff outline 0 - pale_ports # # General-purpose opaque colors. These entries define a whole # bunch of generally-useful colors. # # stipple short long # num opaque color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 29 127 32 0x00 solid 0 W white 30 127 33 0x00 solid 0 - gray1 (pale) 31 127 34 0x00 solid 0 k gray2 (dark) 32 127 35 0x00 solid 0 K black 33 127 36 0x00 solid 0 r red1 (pale) 34 127 37 0x00 solid 0 - red2 (medium) 35 127 38 0x00 solid 0 R red3 (dark) 36 127 39 0x00 solid 0 g green1 (pale) 37 127 40 0x00 solid 0 - green2 (medium) 38 127 41 0x00 solid 0 G green3 (dark) 39 127 42 0x00 solid 0 b blue1 40 127 43 0x00 solid 0 B blue2 (dark) 41 127 44 0x00 solid 0 - blue3 42 127 45 0x00 solid 0 p purple1 43 127 46 0x00 solid 0 P purple2 44 127 47 0x00 solid 0 y yellow1 45 127 48 0x00 solid 0 Y yellow2 46 127 49 0x00 solid 0 o orange1 47 127 50 0x00 solid 0 O orange2 48 127 51 0x00 solid 0 n brown1 49 127 52 0x00 solid 0 N brown2 50 127 53 0x00 solid 0 m magenta 51 127 54 0x00 solid 0 C cyan # #---------------------------------------------------------------------- # All of the styles above this point are used internally by Magic for # things like menus, drawing the box, etc. The style numbers and # number of styles must match the definitions in misc/style.h. # All of the styles below this point are used by the technology file, # addressed by name or number. Note that the numbers are only for # backwards compatibility with .tech27 files which specify styles # by number only. The order in which styles are drawn is the order # in which they appear in this file, not the "num" column. The # ordinal numbering reflects vagaries of the 8-bit-plane setup. # 24-bit styles have been re-ordered to match the physical vertical # position of layers in the layout. #---------------------------------------------------------------------- layout_styles # # num opaque color outline fill number name name #---------------------------------------------------------------------- 10 63 6 0x00 stipple 7 - cwell 52 92 2 0x00 stipple 19 - cwellnsc 79 63 4 0x00 stipple 21 - highvolt_nwell 80 63 5 0x00 stipple 22 - highvolt_pwell 12 63 2 0xff stipple 2 - nwell 13 63 3 0xff stipple 2 - pwell 67 120 9 0xff outline 0 - subcircuit 1 120 1 0x00 solid 0 - polysilicon 87 92 50 0x00 solid 0 - poly_light 88 63 1 0x00 stipple 1 - obspoly 2 120 2 0x00 solid 0 - ndiffusion 69 127 40 0x00 solid 0 - mvndiff 70 127 41 0x00 solid 0 - hvndiff 71 127 44 0x00 solid 0 - ncontact 3 120 2 0x00 stipple 13 - ndiff_in_nwell 11 63 5 0x00 stipple 22 - hvndiff_mask 4 120 3 0x00 solid 0 - pdiffusion 72 127 51 0x00 solid 0 - mvpdiff 73 127 52 0x00 solid 0 - hvpdiff 74 127 45 0x00 solid 0 - pcontact 5 120 3 0x00 stipple 13 - pdiff_in_pwell 18 63 4 0x00 stipple 21 - hvpdiff_mask 6 120 4 0x00 solid 0 - ntransistor 7 120 2 0x00 stipple 8 - ntransistor_stripes 8 120 5 0x00 solid 0 - ptransistor 9 120 3 0x00 stipple 9 - ptransistor_stripes 83 20 51 0x00 solid 0 - implant1 84 20 48 0x00 solid 0 - implant2 85 30 38 0x00 solid 0 - implant3 86 30 32 0x00 solid 0 - implant4 53 92 7 0x00 stipple 7 - nwell_field_implant 54 92 7 0x00 stipple 5 - substrate_field_implant 30 92 2 0x00 stipple 22 - ndop_stripes 31 92 3 0x00 stipple 21 - pdop_stripes 36 92 2 0xff stipple 15 - nselect 35 92 3 0xff stipple 1 - pselect 43 92 2 0x00 stipple 5 - nselect2 44 92 3 0x00 stipple 7 - pselect2 47 92 78 0x00 solid 0 - poly_resist 48 92 3 0x00 stipple 7 - poly_resist_stripes 46 92 42 0x00 stipple 7 - silicide_block 14 92 6 0x00 solid 0 - electrode 27 92 3 0x00 stipple 9 - electrode_stripes 28 92 61 0x00 solid 0 - capacitor 15 92 3 0x00 stipple 10 - pbase 16 92 2 0x00 stipple 17 - emitter 17 92 3 0x00 stipple 11 - bccd 20 80 8 0x00 solid 0 - metal1 29 92 8 0x00 stipple 6 - metal1_alt 49 92 8 0x00 stipple 19 - metal1tight 89 63 8 0x00 stipple 1 - obsmetal1 26 92 9 0x00 solid 0 - poly_contact 21 80 16 0x00 solid 0 - metal2 50 92 16 0x00 stipple 19 - metal2tight 90 63 16 0x00 stipple 1 - obsmetal2 19 92 7 0x00 solid 0 - via 55 120 43 0xff stipple 35 - via1arrow 81 120 43 0xff stipple 2 - via1 22 80 53 0x00 solid 0 - metal3 51 92 53 0x00 stipple 8 - metal3tight 91 63 53 0x00 stipple 1 - obsmetal3 37 92 46 0xff stipple 19 - via2 56 120 53 0xff stipple 36 - via2arrow 82 120 53 0xff stipple 2 - via2alt 23 80 33 0x00 solid 0 - metal4 92 63 33 0x00 stipple 1 - obsmetal4 38 92 38 0xff stipple 24 - via3 57 92 6 0x00 stipple 2 - via3alt 24 80 44 0x00 solid 0 - metal5 93 63 44 0x00 stipple 1 - obsmetal5 39 92 41 0xff stipple 26 - via4 64 80 46 0x00 solid 0 - metal6 94 63 46 0x00 stipple 1 - obsmetal6 59 92 74 0xff stipple 2 - via5 65 80 38 0x00 solid 0 - metal7 95 63 38 0x00 stipple 1 - obsmetal7 60 92 46 0xff stipple 28 - via6 66 80 34 0x00 solid 0 - metal8 96 63 34 0x00 stipple 1 - obsmetal8 61 92 9 0xff stipple 29 - via7 75 80 74 0x00 solid 0 - metal9 97 63 74 0x00 stipple 1 - obsmetal9 76 92 40 0xff stipple 30 - via8 77 80 75 0x00 solid 0 - metal10 98 63 75 0x00 stipple 1 - obsmetal10 78 92 7 0xff stipple 31 - via9 62 92 38 0x00 stipple 3 - mim_bottom 63 92 34 0x00 stipple 3 - mim_top 58 92 7 0x00 solid 0 - gen_contact 32 92 7 0xff cross 0 - contact_X'es 33 92 7 0xff stipple 2 - contact_waffle 25 92 37 0x00 solid 0 - pad4 34 92 34 0xff stipple 10 - overglass 68 92 33 0xff solid 0 - mems 40 92 53 0x00 stipple 5 - check_paint 41 92 54 0x00 stipple 7 - check_subcells 42 127 32 0x00 stipple 4 - error_waffle 45 92 35 0x00 solid 0 - comment # #---------------------------------------------------------------------- # All of the styles below this point must duplicate the styles in # the section above, and represent a version of each previous # layer to use in non-edit cells ("pale" styles): #---------------------------------------------------------------------- pale_styles # # Poly-diff styles: # stipple short long # num opaque color outline fill number name name #---------------------------------------------------------------------- 10 92 70 0x00 stipple 7 - cwell 52 92 2 0x00 stipple 13 - cwellnsc 79 92 71 0x00 stipple 21 - highvolt_nwell 80 92 69 0x00 stipple 22 - highvolt_pwell 12 92 66 0xff stipple 2 - nwell 13 92 67 0xff stipple 2 - pwell 67 92 73 0xff outline 0 - subcircuit 1 92 65 0x00 solid 0 - polysilicon 87 92 49 0x00 solid 0 - poly_light 88 92 65 0x00 stipple 1 - obspoly 2 92 66 0x00 solid 0 - ndiffusion 69 127 40 0x00 stipple 3 - mvndiff 70 127 41 0x00 stipple 3 - hvndiff 71 127 45 0x00 stipple 3 - ncontact 3 92 66 0x00 stipple 13 - ndiff_in_nwell 11 92 69 0x00 stipple 22 - hvndiff_mask 4 92 67 0x00 solid 0 - pdiffusion 72 127 51 0x00 stipple 25 - mvpdiff 73 127 52 0x00 stipple 25 - hvpdiff 74 127 44 0x00 stipple 25 - pcontact 5 92 67 0x00 stipple 13 - pdiff_in_pwell 18 92 71 0x00 stipple 21 - hnpdiff_mask 6 92 68 0x00 solid 0 - ntransistor 7 92 66 0x00 stipple 7 - ntransistor_stripes 8 92 69 0x00 solid 0 - ptransistor 9 92 67 0x00 stipple 5 - ptransistor_stripes 83 10 51 0x00 solid 0 - implant1 84 10 48 0x00 solid 0 - implant2 85 15 38 0x00 solid 0 - implant3 86 15 32 0x00 solid 0 - implant4 53 92 7 0x00 stipple 7 - nwell_field_implant 54 92 7 0x00 stipple 5 - substrate_field_implant 30 92 66 0x00 stipple 22 - ndop_stripes 31 92 67 0x00 stipple 21 - pdop_stripes 36 92 66 0xff stipple 15 - nselect 35 92 67 0xff stipple 1 - pselect 43 92 2 0x00 stipple 5 - nselect2 44 92 3 0x00 stipple 7 - pselect2 47 92 142 0x00 solid 0 - poly_resist 48 92 67 0x00 stipple 7 - poly_resist_stripes 46 92 42 0x00 stipple 7 - silicide_block 14 92 70 0x00 solid 0 - electrode 27 92 67 0x00 stipple 9 - electrode_stripes 28 92 125 0x00 solid 0 - capacitor 15 92 67 0x00 stipple 10 - pbase 16 92 66 0x00 stipple 17 - emitter 17 92 67 0x00 stipple 11 - bccd 20 64 72 0x00 solid 0 - metal1 29 92 72 0x00 stipple 6 - metal1_alt 49 92 8 0x00 stipple 14 - metal1tight 89 92 72 0x00 stipple 1 - obsmetal1 26 92 73 0x00 solid 0 - poly_contact 21 64 80 0x00 solid 0 - metal2 50 92 16 0x00 stipple 5 - metal2tight 90 92 80 0x00 stipple 1 - obsmetal2 19 92 71 0x00 solid 0 - via 55 92 107 0xff stipple 35 - via1arrow 81 92 107 0xff stipple 2 - via1 22 64 117 0x00 solid 0 - metal3 51 92 53 0x00 stipple 21 - metal3tight 91 92 117 0x00 stipple 1 - obsmetal3 37 92 110 0xff stipple 19 - via2 56 92 117 0xff stipple 36 - via2arrow 82 92 117 0xff stipple 2 - via2alt 23 64 97 0x00 solid 0 - metal4 92 92 97 0x00 stipple 1 - obsmetal4 38 92 102 0xff stipple 24 - via3 57 92 70 0x00 stipple 2 - via3alt 24 64 108 0x00 solid 0 - metal5 93 92 108 0x00 stipple 1 - obsmetal5 39 92 105 0xff stipple 26 - via4 64 64 110 0x00 solid 0 - metal6 94 92 110 0x00 stipple 1 - obsmetal6 59 92 80 0xff stipple 2 - via5 65 64 102 0x00 solid 0 - metal7 95 92 102 0x00 stipple 1 - obsmetal7 60 92 110 0xff stipple 28 - via6 66 64 98 0x00 solid 0 - metal8 96 92 98 0x00 stipple 1 - obsmetal8 61 92 110 0xff stipple 29 - via7 75 64 76 0x00 solid 0 - metal9 97 92 76 0x00 stipple 1 - obsmetal9 76 92 33 0xff stipple 30 - via8 77 64 77 0x00 solid 0 - metal10 98 92 77 0x00 stipple 1 - obsmetal10 78 92 34 0xff stipple 31 - via9 62 92 102 0x00 stipple 3 - mim_bottom 63 92 98 0x00 stipple 3 - mim_top 58 92 34 0x00 solid 0 - gen_contact 32 92 99 0xff cross 0 - contact_X'es 33 92 99 0xff stipple 2 - contact_waffle 25 92 101 0x00 solid 0 - pad4 34 92 98 0xff stipple 10 - overglass 68 92 97 0xff solid 0 - mems 40 92 53 0x00 stipple 5 - check_paint 41 92 54 0x00 stipple 7 - check_subcells 42 127 32 0x00 stipple 4 - error_waffle 45 92 15 0x00 solid 0 - comment #---------------------------------------------------------------------- stipples #------------------------------------------------------------------------- # hex bit pattern (8x8) description #------------------------------------------------------------------------- 1 40 00 18 00 18 00 00 00 very sparsed stripes, ll to ur 2 cc cc 00 00 33 33 00 00 coarse knight's move (waffle) 3 ee 77 bb dd ee 77 bb dd all but diagonal stripes, ll to ur 4 00 00 cc cc 00 00 cc cc offset waffle 5 40 20 10 08 04 02 01 80 sparse diagonal stripes, ll to ur 6 aa 55 aa 55 aa 55 aa 55 half 'n half (checkerboard) 7 02 04 08 10 20 40 80 01 sparse diagonal stripes, lr to ul 8 81 03 06 0c 18 30 60 c0 wide sparse diagonal stripes, lr to ul 9 81 c0 60 30 18 0c 06 03 wide sparse diagonal stripes, ll to ur 10 00 00 00 ff 00 00 00 ff horizontal stripes 11 44 44 44 44 44 44 44 44 vertical stripes 12 55 aa 55 aa 55 aa 55 aa complement of half `n half 13 33 33 ff ff cc cc ff ff complement of #2 (coarse knight's move) 14 aa 55 aa 55 aa 55 aa 55 half 'n half (checkerboard) 15 00 01 00 18 00 00 00 18 very sparsed stripes, 11 to ur 16 c0 07 ff ff c0 07 ff ff wide horizontal stripes 17 c7 c7 c7 c7 c7 c7 c7 c7 wide vertical stripes 18 7c 7c 7c 7c 7c 7c 7c 7c wide vertical stripes (reverse of 17) 19 3c c3 42 42 c3 3c 24 24 bubbles 20 24 42 81 81 42 24 18 18 offset diagonal crossex 21 10 20 00 00 00 02 04 08 diagonal dotted line, lr to ul 22 08 04 00 00 00 40 20 10 diagonal dotted line, ll to ur 23 3c 66 c3 81 c3 66 3c 18 dense diagonal crossex 24 c3 3c bd bd 3c c3 db db complement of #19 empty bubbles 25 dd bb 77 ee dd bb 77 ee all but diagonal stripes, lr to ul 26 e2 4e 52 29 94 e4 8e 11 T pattern 27 71 47 41 00 42 72 47 99 sparse offset T pattern 28 99 3c 7e e7 e7 7e 3c 99 alternating diamonds 29 44 88 55 22 44 88 55 22 bricks, ll to ur 30 30 60 c0 c1 63 36 1c 18 bricks, lr to ul 31 55 db 22 db 55 db 22 db linoleum 32 60 c0 81 03 06 0c 18 30 33 00 00 00 30 60 60 30 00 new gc thin 34 00 02 06 0e 0e 06 02 00 35 00 7e 3c 18 00 e7 c3 81 arrows pointing up 36 e0 62 26 0e 0e 26 62 e0 arrows pointing left magic-8.0.210/scmos/Makefile0000664000175000001440000000573711755243452014264 0ustar timusers####################################################################### # # MOSIS distribution Version 8.2 # ####################################################################### # # The intent in magic version 7.2 was to convert all the "c" style # files to m4. However, given the number of files, and the fact that # they are out of date and should all be replaced anyway, this doesn't # seem to be worth the effort. Therefore, some trivial things (like # minimum.tech) have been converted to m4 and the rest have been left # alone. # ####################################################################### MAGICDIR = .. include ${MAGICDIR}/defs.mak SC_M4 = ${M4} SC_CPP = ${CPP} -I./extract_template FILES = mos.7bit.dstyle mos.7bit.std.cmap \ mos.24bit.dstyle mos.24bit.std.cmap \ mos.7bit.mraster_dstyle mos.7bit.mraster.cmap \ mos.OpenGL.dstyle mos.OpenGL.std.cmap TECHFILES = minimum.tech gdsquery.tech scmos.tech scmos-tm.tech \ scmos-sub.tech scmosWR.tech CIFin = cif_template/objs/CIFin CIFout = cif_template/objs/CIFout ICIFin = cif_template/objs/IBMCIFin ICIFout = cif_template/objs/IBMCIFout HCIFin = cif_template/objs/TMCIFin HCIFout = cif_template/objs/TMCIFout SCIFin = cif_template/objs/SUBCIFin SCIFout = cif_template/objs/SUBCIFout OBJS =$(CIFin) $(CIFout) $(HCIFin) $(HCIFout) $(SCIFin) $(SCIFout) DEPEND = scmos.tech.in \ extract_template/scmosExt.tech.in \ extract_template/scmosExt26b-sub.tech.in \ extract_template/scmosExt060_orb.tech.in \ extract_template/scmosExt080.tech.in \ extract_template/scmosExt100.tech.in \ extract_template/scmosExt34.tech.in \ extract_template/scmosExt14b-sub.tech.in \ extract_template/scmosExtDiag.tech.in \ extract_template/scmosExt14b-tm.tech.in all: $(OBJS) $(DEPEND) ${TECHFILES} install-tcl: all for i in ${FILES} ${TECHFILES}; do \ ${CP} $$i $(DESTDIR)${SYSDIR}; done install: all for i in ${FILES} ${TECHFILES}; do \ ${CP} $$i $(DESTDIR)${SYSDIR}; done scmos.tech: $(OBJS) sed -e 's/\\/\\\\/' scmos.tech.in > scmos.tech.out $(SC_CPP) -DV5 -DSTANDARD scmos.tech.out > scmos.tech $(RM) scmos.tech.out scmos-tm.tech: $(OBJS) sed -e 's/\\/\\\\/' scmos.tech.in > scmos.tech.out $(SC_CPP) -DV5 -DHPTECH -DTIGHTMETAL scmos.tech.out > scmos-tm.tech $(RM) scmos.tech.out scmos-sub.tech: $(OBJS) sed -e 's/\\/\\\\/' scmos.tech.in > scmos.tech.out $(SC_CPP) -DV5 -DSUBMICRON scmos.tech.out > scmos-sub.tech $(RM) scmos.tech.out scmosWR.tech: $(OBJS) sed -e 's/\\/\\\\/' scmos.tech.in > scmos.tech.out $(SC_CPP) -DV5 -DSTANDARD -DWELL_ROUTE_CHECK scmos.tech.out > scmosWR.tech $(RM) scmos.tech.out minimum.tech: minimum.tech.m4 $(SC_M4) minimum.tech.m4 > minimum.tech gdsquery.tech: gdsquery.tech.m4 $(SC_M4) gdsquery.tech.m4 > gdsquery.tech $(CIFin): $(CIFout): $(ICIFin): $(ICIFout): $(HCIFin): $(HCIFout): $(SCIFin): $(SCIFout): cd cif_template; ${MAKE} clean; ${MAKE}; $(DESTDIR)${SYSDIR}/%: % cp $* $(DESTDIR)${SYSDIR}/$* clean:; -rm -f *.tech *.tech27 cd cif_template && ${MAKE} clean; magic-8.0.210/scmos/cif_template/0000755000175000001440000000000012364011455015233 5ustar timusersmagic-8.0.210/scmos/cif_template/cifout-cmos14b.gen0000644000175000001440000000655410751423606020502 0ustar timusers/* For HP CMOS14B process... No CCD, Bipolar, Poly2 layers. */ /* This is prelimanary, please let me know if anything here seems abnormal to you... pi@lepton.isi.edu 3/02/95 */ style lambda=lambda_v scalefactor lambda_1 calmaonly layer CWN nwell bloat-or allPDiff,PFet * lambda_5 bloat-or allNOhmic * lambda_3 grow lambda_3 shrink lambda_3 calma 42 1 layer CWP pwell bloat-or allNDiff,NFet * lambda_5 pdop 0 bloat-or allPOhmic * lambda_3 ndop 0 grow lambda_3 shrink lambda_3 calma 41 1 layer CMT allMetal3,pad labels m3 calma 62 1 layer CMS pad grow lambda_2 or allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_4 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 layer CAA allActive or ndop,pdop #ifdef OPEN or open,pstop #endif labels ndiff,pdiff calma 43 1 layer CVS pad shrink pad_via2 #ifdef OPEN or open #endif calma 61 1 layer CVS m3c squares lambda_1 lambda_2 lambda_3 calma 61 1 layer CVA pad shrink pad_via1 #ifdef OPEN or open #endif calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 /* Generic contact to (active,poly)... NOTE: no calma layer spec. for CCC, contact will not in stream file */ layer CCC gc calma 48 1 /* contacts for pdc/nsc (ndc/psc) must be generated separately */ layer CCA ndc,pdc squares lambda_2 #ifdef OPEN or open #endif calma 48 1 layer CCA nsc,psc squares lambda_2 calma 48 1 layer CCP pc squares lambda_2 calma 47 1 /* temp CIF layer - All diffusion N-Select layers */ templayer XTN bloat-or allNDiff,ndop * lambda_2 allPOhmic,allPDiff,pdop 0 bloat-or nbd,nbdc * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half /* temp CIF layer - All diffusion P-Select layers */ templayer XTP bloat-or allPDiff,pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half layer CSN bloat-or allNDiff * lambda_2 allPOhmic,pdop 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff,pdop 0 bloat-or ndop * lambda_2 allPOhmic,allPDiff,pdop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP calma 45 1 layer CSP bloat-or allPDiff * lambda_2 allNOhmic,ndop 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff,ndop 0 bloat-or pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half #ifdef OPEN bloat-min pstop * lambda_2 open 0 #endif and-not XTN and-not CSN calma 44 1 layer COP open calma 23 1 layer CPS pstop calma 24 1 layer COG pad shrink pad_glass or glass #ifdef OPEN or open #endif labels pad calma 52 1 layer XP pad shrink pad_glass calma 26 1 #undef cif_tech magic-8.0.210/scmos/cif_template/cifout-cmos26g.soi0000644000175000001440000000634710751423606020533 0ustar timusers style lambda=0.40(soi) scalefactor lambda_1 scaleunit layer CWN nwell bloat-or allPDiff,PFet * lambda_6 bloat-or allNOhmic * lambda_3 grow lambda_3 shrink lambda_3 calma 42 1 layer CWP pwell bloat-or allNDiff,NFet * lambda_6 pdop 0 bloat-or allPOhmic * lambda_3 ndop 0 grow lambda_3 shrink lambda_3 calma 41 1 layer CMT allMetal3,pad labels m3 calma 62 1 layer CMS pad grow lambda_2 or allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_4 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 layer CAA allActive or ndop,pdop #ifdef OPEN or open,pstop #endif labels ndiff,pdiff calma 43 1 layer CVS pad shrink lambda_3 squares lambda_3 or open calma 61 1 layer CVS m3c squares lambda_1 lambda_2 lambda_3 calma 61 1 layer CVA pad squares lambda_3 #ifdef OPEN or open #endif calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 /* Generic contact to (active,poly)... NOTE: no calma layer spec. for CCC, contact will not in stream file */ layer CCC gc calma 48 1 /* contacts for pdc/nsc (ndc/psc) must be generated separately */ layer CCA ndc,pdc squares lambda_1 lambda_2 lambda_3 #ifdef OPEN or open #endif calma 48 1 layer CCA nsc,psc squares lambda_1 lambda_2 lambda_3 calma 48 1 layer CCP pc squares lambda_1 lambda_2 lambda_3 calma 47 1 /* temp CIF layer - All diffusion N-Select layers */ templayer XTN bloat-or allNDiff,ndop * lambda_2 allPOhmic,allPDiff,pdop 0 bloat-or nbd,nbdc * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half /* temp CIF layer - All diffusion P-Select layers */ templayer XTP bloat-or allPDiff,pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half layer CSN bloat-or allNDiff * lambda_2 allPOhmic,pdop 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff,pdop 0 bloat-or ndop * lambda_2 allPOhmic,allPDiff,pdop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP calma 45 1 layer CSP bloat-or allPDiff * lambda_2 allNOhmic,ndop 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff,ndop 0 bloat-or pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half #ifdef OPEN bloat-min pstop * lambda_2 open 0 #endif and-not XTN and-not CSN calma 44 1 layer COP open calma 23 1 layer CPS pstop calma 24 1 layer COG pad shrink pad_glass or glass #ifdef OPEN or open #endif labels pad calma 52 1 layer XP pad shrink pad_glass calma 26 1 #undef cif_tech magic-8.0.210/scmos/cif_template/cifout.scgnw0000644000175000001440000000502510751423606017574 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet poly capacitor bipolar NPN transistor buried CCD devices linear capacitor */ #define cif_tech scg_nwell style lambda=lambda_v scalefactor lambda_1 scaleunit layer CWC cwell calma 59 1 layer CWG nwell bloat-or pbase,pbc/a * lambda_6 bloat-or allPDiff,PFet * lambda_5 bloat-or allNOhmic * lambda_3 bloat-or clc/a * lambda_1 or col grow lambda_3 shrink lambda_3 calma 53 1 layer CMS allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_1 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 layer CAA em,emc grow lambda_1 or clc,pbc grow lambda_1 or col or allActive or allHVDiff or allCCDiff labels ndiff,pdiff calma 43 1 /* use CX layer to distinguish "col" and "nsd" */ layer CX col,clc grow lambda_1 calma 60 1 layer CVA pad shrink pad_via calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 layer CEL allPoly2 calma 56 1 layer CCE capc,ec squares lambda_2 calma 55 1 /* NOTE: no calma layer spec. for CCC, generic contact will NOT in stream file */ layer CCC gc calma 63 1 /* contacts for pdc/nsc (ndc/psc) must be generated separately */ layer CCA ndc,pdc,BiCut,nbdc squares lambda_2 calma 48 1 layer CCA nsc,psc squares lambda_2 calma 48 1 layer CCP pc squares lambda_2 calma 47 1 layer CBA emc,emit grow lambda_4 bloat-or pbc * lambda_1 or pbase calma 58 1 /* temp CIF layer for select generation */ templayer XTN clc grow lambda_1 or em,emc,col grow lambda_2 bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or nbd,nbdc,ndop,wcap * lambda_2 templayer XTP pbc grow lambda_1 bloat-or allPDiff * lambda_2 allNOhmic 0 layer CSG emit,emc grow lambda_1 or clc grow lambda_1 or col grow lambda_2 bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff 0 bloat-or nbd,nbdc,ndop,wcap * lambda_2 and-not XTP calma 54 1 /* layer CSP pbc grow lambda_1 bloat-or allPDiff * lambda_2 allNOhmic 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff 0 bloat-or pdop * lambda_2 and-not XTN grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half calma 44 1 */ layer CCD allCCDiff grow lambda_2 calma 57 1 layer COG pad shrink pad_glass or glass calma 52 1 layer XP pad shrink pad_glass #undef cif_tech magic-8.0.210/scmos/cif_template/cifin.others0000644000175000001440000002355110751423606017562 0ustar timusers/* There is a need to read layouts in SCGA CIF lsyrs. This input * style is a first-order approximation. I've try this only on a * single example You maight have problems with some of the new DRC * rules. Both NPN transistors and BCCD devices are NOT included... */ style lambda=1.0(SCGA) scalefactor 100 layer m2 CMS labels CMS layer m1 CMF labels CMF layer poly CPG labels CPG layer psd and CAA and-not CWG and-not CSG layer nsd CAA and CWG layer pdiff CAA and-not CSG and CWG layer ndiff CSG and CAA and-not CWG and-not CCD layer pbase CBA labels CBA layer nfet CPG and CAA and CSG and-not CWG and-not CCD layer pfet CPG and CAA and CWG layer enfet CEL and CAA and CSG and-not CWG and-not CCD layer epfet CEL and CAA and CWG layer psc CCA grow 100 and CAA and-not CWG and CMF layer nsc CCA grow 100 and CAA and CWG and CMF layer ndc CCA grow 100 and CAA and CSG and-not CWG and CMF layer pdc CCA grow 100 and CAA and CWG and-not CSG and CMF layer m2c CVA grow 150 shrink 50 and CMS and CMF labels CMS layer electrode CEL labels CEL layer ec CCE grow 100 and CMF and CEL labels CMF layer cc CCE grow 100 and CMF and CEL and CPG labels CMF layer cap CPG and CEL and-not CAA labels CEL layer pc CCP grow 100 and CPG and CMF /* layer pbc CCA grow 100 and CBA and CMF labels CBA layer col CX and CAA and CSN and CWN labels CAA layer clc CCA grow 100 and CX and CAA and CSN and CWN and CMF labels CCA layer emit CBA and CSN shrink 200 labels CBA layer emc CCA grow 100 and CBA and CSN and CMF labels CBA layer nbd CSN shrink 200 and CCD and CAA and-not CPG layer nbdc CCA grow 100 and CCD and CSN and CAA layer bd CPG or CEL and CCD and CAA labels CCD */ layer glass COG layer pad CMF shrink 100 and CMS shrink 500 and CVA shrink 100 and COG grow 600 and XP calma CWG 53 * calma CAA 43 * calma CSG 54 * calma CPG 46 * calma CCP 47 * calma CCA 48 * calma CMF 49 * calma CVA 50 * calma CMS 51 * calma COG 52 * calma CCE 55 * calma CEL 56 * calma CCD 57 * calma CBA 58 * style cbpm3u scalefactor 50 layer pwell CW labels CW layer m2 CM2,CQ labels CM2,CQ layer m1 CM labels CM layer poly CP labels CP layer nsd CD and CNS layer ndiff CD and CW and CNS layer pdiff CD and CS layer psd CW and CS and CD layer pfet CP and CD and CS layer nfet CD and CP and CW and CNS layer m2c CC2,CV grow 150 and CM2,CQ and CM layer pc CC grow 150 and CP and CM layer nsc CC grow 150 and CD and CNS and CM layer pdc CC grow 150 and CD and CS and CM layer ndc CC grow 150 and CD and CW and CM and CNS layer psc CC grow 150 and CD and CS and CW and CM layer glass CG layer pad CM and CM2,CQ shrink 500 and CC2,CV and CG grow 500 calma CW 1 * calma CD 3 * calma CP 4 * calma CS 5 * calma CNS 6 * calma CC 7 * calma CM 8 * calma CG 9 * calma CV 13 * calma CQ 14 * style oldcbpm3u scalefactor 50 layer pwell CW labels CW layer m2 CM2,CQ labels CM2,CQ layer m1 CM labels CM layer poly CP labels CP layer nsd CD layer ndiff CD and CW layer pdiff CD and CS layer psd CW and CS and CD layer pfet CP and CD and CS layer nfet CD and CP and CW layer m2c CC2,CV grow 150 and CM2,CQ and CM layer pc CC grow 150 and CP and CM layer nsc CC grow 150 and CD and CM layer pdc CC grow 150 and CD and CS and CM layer ndc CC grow 150 and CD and CW and CM layer psc CC grow 150 and CD and CS and CW and CM layer glass CG layer pad CM and CM2,CQ shrink 500 and CC2,CV and CG grow 500 calma CW 1 * calma CD 3 * calma CP 4 * calma CS 5 * calma CC 7 * calma CM 8 * calma CG 9 * calma CV 13 * calma CQ 14 * style oldcbpe2u scalefactor 100 layer pwell CW labels CW layer m2 CM2,CQ labels CM2,CQ layer m1 CM labels CM layer poly CP labels CP layer nsd CD layer ndiff CD and CW layer pdiff CD and CS layer psd CW and CS and CD layer pfet CP and CD and CS layer nfet CD and CP and CW layer m2c CC2,CV grow 150 and CM2,CQ and CM layer electrode CE labels CE layer pc CC grow 150 and CP and CM layer capc CC grow 150 and CE and CM layer nsc CC grow 150 and CD and CM layer pdc CC grow 150 and CD and CS and CM layer ndc CC grow 150 and CD and CW and CM layer psc CC grow 150 and CD and CS and CW and CM layer glass CG layer pad CM and CM2,CQ shrink 500 and CC2,CV and CG grow 500 calma CW 1 * calma CD 3 * calma CP 4 * calma CS 5 * calma CC 7 * calma CM 8 * calma CG 9 * calma CV 13 * calma CQ 14 * /* style JPL scalefactor 20 layer m2 CMS labels CMS layer m1 CMF labels CMF layer poly CPG labels CPG layer pdiff CSP and CAA and CWN layer ndiff CSN and CAA and CWP and-not CCD layer nsd CWN and CSN and CAA layer psd CWP and CSP and CAA layer nfet CPG and CAA and CSN and-not CCD layer pfet CAA and CPG and CSP layer enfet CEL and CAA and CSN and-not CCD layer epfet CAA and CEL and CSP layer ndc CCA grow lambda_1 and CAA and CWP and CSN and CMF layer pdc CCA grow lambda_1 and CAA and CWN and CSP and CMF layer nsc CCA grow lambda_1 and CAA and CSN and CWN and CMF layer psc CCA grow lambda_1 and CAA and CSP and CWP and CMF layer gc CCC layer m2c CVA grow lambda_1 and CMS and CMF labels CMS layer electrode CEL labels CEL layer ec CCE grow lambda_1 and CMF and CEL labels CMF layer cc CCE grow lambda_1 and CMF and CEL and CPG labels CMF layer cap CPG and CEL and-not CAA labels CEL layer pbc CCA grow lambda_1 and CBA and CMF labels CBA layer col CX and CAA and CSN and CWN labels CAA layer clc CCA grow lambda_1 and CX and CAA and CSN and CWN and CMF labels CCA layer emit CBA and CSN shrink lambda_2 labels CBA layer emc CCA grow lambda_1 and CBA and CSN and CMF labels CBA layer pc CCP grow lambda_1 and CPG and CMF layer bd CAA and CCD and-not CSN grow lambda_2 and CAA labels CCD layer nbd CSN shrink lambda_2 and CCD and CAA labels CCD layer nbdc CCA grow lambda_1 and CCD and CSN and CAA labels CCD layer glass COG #ifdef OPEN layer open CAA and CCA and CVA and COG layer pstop CAA and CSP and-not CWP and-not CWN #endif layer pad CMF shrink lambda_1 and CMS shrink lambda_5 and CVA shrink lambda_1 and COG grow lambda_6 and XP layer error_p CER calma CWP 41 * calma CWN 42 * calma CAA 43 * calma CSP 44 * calma CSN 45 * calma CPG 46 * calma CCP 47 * calma CCA 48 * calma CMF 49 * calma CVA 50 * calma CMS 51 * calma COG 52 * calma CCE 55 * calma CEL 56 * calma CCD 57 * calma CBA 58 * calma CWC 59 * calma CX 60 * calma CER 61 * calma CCC 63 * #undef cif_tech */ /* These follwoing technologies are for DRC error display */ /* Remove comment if you want to install them... style lambda=1.0(error) scalefactor 100 layer error_s CX style lambda=0.8(error) scalefactor 80 layer error_s CX style lambda=0.6(error) scalefactor 60 layer gc CX style lambda=0.5(error) scalefactor 50 layer error_s CX */ magic-8.0.210/scmos/cif_template/cifout-cmos26b.gen0000644000175000001440000001014210751423606020471 0ustar timusers/* For HP CMOS26B process... No CCD, Bipolar, Poly2 layers. Two types of pad layer are supported, one (the pad layer) contains both metal1 and metal2 layer while the other (the pad2 layer) contains all three metals with all necessary via properly defined... */ /* This is prelimanary, please let me know if anything here seems abnormal to you... pi@lepton.isi.edu 3/15/93 */ style lambda=lambda_v scalefactor lambda_1 scaleunit layer CWN nwell bloat-or pbase,pbc/act * lambda_6 bloat-or allPDiff,PFet * lambda_5 bloat-or allNOhmic * lambda_3 bloat-or clc/act * lambda_1 or col grow lambda_3 shrink lambda_3 calma 42 1 layer CWP pwell bloat-or allNDiff,NFet * lambda_5 pdop 0 bloat-or allPOhmic * lambda_3 ndop 0 grow lambda_3 shrink lambda_3 calma 41 1 layer CMT allMetal3,pad labels m3 calma 62 1 layer CMS pad grow lambda_2 or allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_4 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 layer CAA allActive or ndop,pdop #ifdef OPEN or open,pstop #endif labels ndiff,pdiff calma 43 1 layer CVS pad shrink pad_via2 #ifdef OPEN or open #endif calma 61 1 layer CVS m3c squares lambda_1 lambda_2 lambda_3 calma 61 1 layer CVA pad shrink pad_via1 #ifdef OPEN or open #endif calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 /* Generic contact to (active,poly)... NOTE: no calma layer spec. for CCC, contact will not in stream file */ layer CCC gc calma 48 1 /* A contact under the pad is required by HP rule.... numbers here */ /* are fixed */ layer CCA pad shrink 400 calma 48 1 /* contacts for pdc/nsc (ndc/psc) must be generated separately */ layer CCA ndc,pdc squares lambda_2 #ifdef OPEN or open #endif calma 48 1 layer CCA nsc,psc squares lambda_2 calma 48 1 layer CCP pc squares lambda_2 calma 47 1 /* temp CIF layer - All diffusion N-Select layers */ templayer XTN bloat-or allNDiff,ndop * lambda_2 allPOhmic,allPDiff,pdop 0 bloat-or nbd,nbdc * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half /* temp CIF layer - All diffusion P-Select layers */ templayer XTP bloat-or allPDiff,pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half layer CSN bloat-or allNDiff * lambda_2 allPOhmic,pdop 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff,pdop 0 bloat-or ndop * lambda_2 allPOhmic,allPDiff,pdop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP calma 45 1 layer CSP bloat-or allPDiff * lambda_2 allNOhmic,ndop 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff,ndop 0 bloat-or pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half #ifdef OPEN bloat-min pstop * lambda_2 open 0 #endif and-not XTN and-not CSN calma 44 1 layer COP open calma 23 1 layer CPS pstop calma 24 1 layer COG pad shrink pad_glass or glass #ifdef OPEN or open #endif labels pad calma 52 1 layer XP pad shrink pad_glass calma 26 1 render CWN 12 -0.2 0.2 render CAA 2 -0.15 0.15 render CPG 1 0.025 0.05 render CEL 14 0.1 0.05 render CCC 19 0.0 0.2 render CCA 19 0.0 0.2 render CCP 19 0.075 0.125 render CMF 20 0.2 0.05 render CVA 19 0.25 0.05 render CMS 21 0.3 0.05 #undef cif_tech magic-8.0.210/scmos/cif_template/cifin-cmosn.gen0000644000175000001440000000304610751423606020141 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet poly capacitor bipolar NPN transistor buried CCD devices linear capacitor micro-machined devices */ #define cif_tech cmosn style lambda=lambda_v scalefactor lambda_1 layer nwell NWN labels NWN layer pwell NWP labels NWP layer m2 NMS labels NMS layer m1 NMF labels NMF layer poly NPG labels NPG layer pdiff NSP and NAA and NWN layer ndiff NSN and NAA layer nsd NWN and NSN and NAA layer psd NSP and NAA and-not NWN layer nfet NPG and NAA and NSN layer pfet NAA and NPG and NSP layer enfet NEL and NAA and NSN layer epfet NAA and NEL and NSP layer electrode NEL labels NEL layer cap NPG and NEL and-not NAA labels NEL layer gc NCT layer m2c NVA and NMS and NMF labels NMS layer open NAA and NCT and NVA and NOG and NOP layer pstop NAA and NPS and NSP and-not NWP and-not NWN layer pad NMF shrink lambda_1 and NMS shrink lambda_5 and NVA shrink lambda_1 and NOG grow lambda_6 and XP calma NWN 1 * calma NWP 2 * calma NAA 3 * calma NPG 4 * calma NEL 5 * calma NSN 7 * calma NSP 8 * calma NCT 9 * calma NMF 10 * calma NVA 11 * calma NMS 12 * calma NOG 13 * #undef cif_tech magic-8.0.210/scmos/cif_template/cifout.c0000644000175000001440000000517210751423606016700 0ustar timusers #ifdef STANDARD /* standard CMOS processes, ORBIT specifically... */ /* 3.0 micron technology - not supported anymore #define lambda_value 150 #include "calc.lambda" #include "cifout.gen" #include "cifout.nw" #include "cifout.pw" */ /* ORBIT 2.0 micron technology */ #define lambda_value 100 #include "calc.lambda" #include "cifout-orbit.gen" #include "cifout-orbit.nw" #include "cifout-orbit.pw" /* just testing... #include "cifout.test" */ /* ORBIT 1.6 micron technology - not supported, but retained for ORBIT */ #define lambda_value 80 #include "calc.lambda" #include "cifout-ami16.gen" /* just the generic style is enough at the moment... #include "cifout-ami16.nw" #include "cifout-ami16.pw" */ /* ORBIT 1.2 micron technology - ORBIT 1.2 micron process supported... */ #define lambda_value 60 #include "calc.lambda" #include "cifout-orbit.gen" #include "cifout-orbit.nw" #include "cifout-orbit.pw" /* 1.2 micron technology - for Mentor Graphics CMOSN technology */ /* not supported yet, for my own test... */ /* #define lambda_value 20 #include "calc.lambda" #include "cifout-cmosn.nw" */ #endif /* Standard SCMOS technologies */ #ifdef TIGHTMETAL /* HP CMOS34 1.2 micron technology */ #define lambda_value 60 #include "calc.lambda" #include "cifout-cmos34.gen" #include "cifout-cmos34.nw" #include "cifout-cmos34.pw" /* HP CMOS26b 1.0 micron technology */ #undef cif_tech #define cif_tech sub #define lambda_value 50 #include "calc.lambda" #include "cifout-cmos26b.gen" /* HP CMOS26b 1.0 micron technology */ /* This is used for generation of standard 2.0 micron layout for Cadence tool */ /* #define lambda_value 100 #include "calc.lambda" #include "cifout-cmos26b.gen" */ /* HP CMOS14b 0.6 micron technology */ #undef cif_tech #define cif_tech sub #define lambda_value 35 #include "calc.lambda" #include "cifout-cmos14b.gen" #endif /* Tight Metal SCMOS technologies */ #ifdef SUBMICRON /* HP CMOS26G 0.8 micron technology */ #define lambda_value 40 #include "calc.lambda" #include "cifout-cmos26g.gen" /* HP CMOS14B 0.6 micron technology */ #define cif_tech sub #define lambda_value 30 #include "calc.lambda" #include "cifout-cmos14b-sub.gen" /* This one is used for an internal SOI technology */ #define lambda_value 40 #include "calc.lambda" #include "cifout-cmos26g.soi" /* This one is used for an internal SOI technology */ #define cif_tech cmosx #define lambda_value 40 #include "calc.lambda" #include "cifout-cmosx.gen" #endif /* HP CMOS26G and HP CMOS14B */ #ifdef IBM /* IBM CMSX2185 0.8 micron technology */ #define lambda_value 40 #include "calc.lambda" #include "cifout-ibm.gen" #endif /* IBM */ magic-8.0.210/scmos/cif_template/cifout-ami16.gen0000644000175000001440000000751710751423606020147 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet hnfet,hpfet poly capacitor bipolar NPN transistor micro-machined devices */ #define cif_tech gen style lambda=lambda_v scalefactor lambda_1 scaleunit layer CVN hnwell bloat-or allHVPDiff,hpfet * lambda_7 bloat-or allHVNOhmic * lambda_3 calma 40 1 layer CVP hpwell bloat-or allHVNDiff,hnfet * lambda_7 bloat-or allHVPOhmic * lambda_3 calma 39 1 layer CWN nwell bloat-or pbase,pbc/act * lambda_6 bloat-or allPDiff,PFet * lambda_5 bloat-or allNOhmic * lambda_3 bloat-or clc/a * lambda_1 or col grow lambda_3 shrink lambda_3 calma 42 1 layer CWP pwell bloat-or allNDiff,NFet * lambda_5 bloat-or allPOhmic * lambda_3 grow lambda_3 shrink lambda_3 calma 41 1 layer CMS allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_1 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 layer CAA clc grow lambda_1 or em,emc,col or allActive or allHVDiff,allHVOhmic,hnfet,hpfet #ifdef OPEN or open,pstop #endif labels ndiff,pdiff calma 43 1 /* use CX layer to distinguish "col" and "nsd" while CIF input */ /* use CX layer for high-voltage MOSFETs too... (for cifin) */ layer CX col,clc grow lambda_1 /* or allHVDiff,allHVOhmic,hnfet,hpfet or hnw,hpw */ calma 60 1 layer CVA pad shrink pad_via #ifdef OPEN or open #endif calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 layer CEL allPoly2 calma 56 1 layer CCE capc,ec squares lambda_2 calma 55 1 /* NOTE: no calma layer spec. for CCC, contact will not in stream file */ layer CCC gc calma 63 1 /* contacts for pdc/nsc (ndc/psc) must be generated separatelt */ layer CCA ndc,pdc,BiCut squares lambda_2 #ifdef OPEN or open #endif calma 48 1 layer CCA nsc,psc squares lambda_2 calma 48 1 layer CCA hndc,hpdc squares lambda_2 lambda_2 lambda_2 calma 48 1 layer CCA hnsc,hpsc squares lambda_2 lambda_2 lambda_2 calma 48 1 layer CCP pc squares lambda_2 calma 47 1 layer CBA emc,emit grow lambda_4 bloat-or pbc * lambda_1 or pbase calma 58 1 /* temp CIF layer for select generation */ templayer XTN clc grow lambda_1 or em,emc,col grow lambda_2 bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or allHVNDiff * lambda_2 allHVPOhmic 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half templayer XTP pbc grow lambda_1 bloat-or allPDiff * lambda_2 allNOhmic 0 bloat-or allHVPDiff * lambda_2 allHVNOhmic 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half layer CSN clc grow lambda_1 or em,emc,col grow lambda_2 bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or allHVNDiff * lambda_2 allHVPOhmic 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or hnfet * lambda_2 hndiff lambda_3 allHVPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff 0 bloat-or allHVNOhmic * lambda_2 allHVPDiff 0 bloat-or ndop * lambda_2 allPOhmic,allPDiff,pdop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP calma 45 1 layer CSP pbc grow lambda_1 bloat-or allPDiff * lambda_2 allNOhmic 0 bloat-or allHVPDiff * lambda_2 allHVNOhmic 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or hpfet * lambda_2 hpdiff lambda_3 allHVNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff 0 bloat-or allHVPOhmic * lambda_2 allHVNDiff 0 bloat-or pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half #ifdef OPEN bloat-min pstop * lambda_2 open 0 #endif and-not XTN and-not CSN calma 44 1 layer COP open calma 23 1 layer CPS pstop calma 24 1 layer COG pad shrink pad_glass or glass #ifdef OPEN or open #endif labels pad calma 52 1 layer XP pad shrink pad_glass calma 26 1 #undef cif_tech magic-8.0.210/scmos/cif_template/calc.lambda0000644000175000001440000000714410751423606017310 0ustar timusers/* undefine all local define's used first ... */ #define OPEN #undef scaleunit #undef lambda_1 #undef lambda_2 #undef lambda_3 #undef lambda_4 #undef lambda_5 #undef lambda_6 #undef lambda_7 #undef lambda_8 #undef lambda_9 #undef lambda_v #undef lambda_half #undef pad_via #undef pad_glass /* for 2.0 micron process... */ #if (lambda_value==100) #define lambda_half 50 #define lambda_v 1.0(cif_tech) #define scaleunit 50 #define lambda_1 100 #define lambda_2 200 #define lambda_3 300 #define lambda_4 400 #define lambda_5 500 #define lambda_6 600 #define lambda_7 700 #define lambda_8 800 #define pad_via 500 #define pad_glass 600 /* for 3.0 micron process... */ #elif (lambda_value==150) #define lambda_half 75 #define lambda_v 1.5(cif_tech) #define scaleunit 25 #define lambda_1 150 #define lambda_2 300 #define lambda_3 450 #define lambda_4 600 #define lambda_5 750 #define lambda_6 900 #define lambda_7 1050 #define lambda_8 1200 #define pad_via 450 #define pad_glass 600 /* for 1.6 micron process... */ #elif (lambda_value==80) #define lambda_half 40 #define lambda_v 0.8(cif_tech) #define scaleunit 40 #define lambda_1 80 #define lambda_2 160 #define lambda_3 240 #define lambda_4 320 #define lambda_5 400 #define lambda_6 480 #define lambda_7 560 #define lambda_8 640 #define pad_via 560 #define pad_glass 640 /* for 1.2 micron process... */ #elif (lambda_value==60) #define lambda_half 30 #define lambda_v 0.6(cif_tech) #define scaleunit 30 #define lambda_1 60 #define lambda_2 120 #define lambda_3 180 #define lambda_4 240 #define lambda_5 300 #define lambda_6 360 #define lambda_7 420 #define lambda_8 480 #define pad_via 300 #define pad_glass 600 /* for HP CMOS26B - 1.0 micron process... */ #elif (lambda_value==50) #define lambda_half 25 #define lambda_v 0.5(cif_tech) #define scaleunit 5 #define lambda_1 50 #define lambda_2 100 #define lambda_3 150 #define lambda_4 200 #define lambda_5 250 #define lambda_6 300 #define lambda_7 350 #define lambda_8 400 #define pad_via1 300 #define pad_via2 200 #define pad_glass 600 /* for HP CMOS26G - 0.8 micron process... */ #elif (lambda_value==40) #define lambda_half 20 #define lambda_v 0.40(cif_tech) #define scaleunit 5 #define lambda_1 40 #define lambda_2 80 #define lambda_3 120 #define lambda_4 160 #define lambda_5 200 #define lambda_6 240 #define lambda_7 280 #define lambda_8 320 #undef pad_via2 #undef pad_via1 #define pad_via1 300 #define pad_via2 200 #define pad_glass 600 /* for HP CMOS14B - 0.6 micron process... */ #elif (lambda_value==35) #define lambda_half 20 #define lambda_v 0.35(cif_tech) #define scaleunit 5 #define lambda_1 35 #define lambda_2 70 #define lambda_3 105 #define lambda_4 140 #define lambda_5 175 #define lambda_6 210 #define lambda_7 245 #define lambda_8 280 #undef pad_via1 #undef pad_via2 #define pad_via1 300 #define pad_via2 200 #define pad_glass 600 /* for HP CMOS14B - 0.6 micron process... */ #elif (lambda_value==30) #define lambda_half 15 #define lambda_v 0.30(cif_tech) #define scaleunit 15 #define lambda_1 30 #define lambda_2 60 #define lambda_3 90 #define lambda_4 120 #define lambda_5 150 #define lambda_6 180 #define lambda_7 210 #define lambda_8 240 #undef pad_via1 #undef pad_via2 #define pad_via1 300 #define pad_via2 210 #define pad_glass 600 /* for 0.4 micron process... */ #elif (lambda_value==20) #define lambda_half 10 #define lambda_v 0.20(cif_tech) #define scaleunit 10 #define lambda_1 20 #define lambda_2 40 #define lambda_3 60 #define lambda_4 80 #define lambda_5 100 #define lambda_6 120 #define lambda_7 140 #define lambda_8 160 #undef pad_via1 #undef pad_via2 #define pad_via1 300 #define pad_via2 300 #define pad_glass 600 #endif #undef lambda_value magic-8.0.210/scmos/cif_template/cifin-cmosx.gen0000644000175000001440000000467710751423606020166 0ustar timusers/* For IBM triple metal process... No CCD, Bipolar, Poly2 layers. /* This is prelimanary, please let me know if anything here seems abnormal to you... pi@lepton.isi.edu 3/14/95 */ #ifdef NOWELL style lambda=0.4(cmosx-nowell) #else style lambda=0.4(cmosx) #endif scalefactor lambda_1 #ifndef NOWELL layer nwell CWN labels CWN layer pwell CWP labels CWN #endif layer m3 CMT /* to avoid a CIF read problem around pads */ and-not XP labels CMT layer m2 CMS labels CMS layer m1 CMF labels CMF layer poly CPG labels CPG layer ndop CSN and-not CWP and CAA layer pdop CSP and CAA and-not CWP and-not CPS layer pdiff CSP and CWN and CAA layer ndiff CSN and CWP and CAA layer nsd CWN and CSN and CAA layer psd CSP and CWP and CAA layer pbase CBA labels CBA layer nfet CPG and CAA and CSN labels CPG layer pfet CAA and CPG and CSP labels CPG layer ndc CCA grow lambda_1 and CAA and CWP and CSN and CMF layer pdc CCA grow lambda_1 and CAA and CWN and CSP and CMF layer nsc CCA grow lambda_1 and CAA and CSN and CWN and CMF layer psc CCA grow lambda_1 and CAA and CSP and CWP and CMF layer pbc CCA grow lambda_1 and CBA and CMF labels CBA layer m3c CVS grow lambda_1 and CMT and CMS and-not XP layer m2c CVA grow lambda_1 and CMS and CMF layer pc CCA grow lambda_1 and CPG and CMF layer gc CCC layer glass COG labels COG #ifdef OPEN layer open CAA and CCA and CVA and COG and COP layer pstop CAA and CPS and CSP and-not CWP and-not CWN #endif /* assume all contact are in place .. */ layer pad CMF shrink 100 and CMS shrink 100 and CMT shrink 500 and COG grow 500 and XP calma CWN 1 * calma CWP 2 * calma CAA 3 * calma CPG 4 * calma CSN 7 * calma CSP 8 * calma CCA 9 * calma CMF 10 * calma CVA 11 * calma CMS 12 * calma COG 13 * calma CVS 14 * calma CMT 15 * magic-8.0.210/scmos/cif_template/README0000644000175000001440000000075410751423606016124 0ustar timusersThis directory contains template files for MOSIS's SCMOS technology for Magic layout editor. A simple command "make" should be able to generate all appropriate files needed. You can also use "make clean" to remove all files and then "make all" to generate all-style files. After all CIF input/output styles has been generated, you'll have to go to the scmos directory to 're-make' the SCMOS technology file. Gook luck, Jen-I pi@isi.edu :-) The MOSIS Services, USC/ISI (310) 822-1511 x640 magic-8.0.210/scmos/cif_template/cifin.c0000644000175000001440000000536410751423606016502 0ustar timusers#ifdef STANDARD /* 3.0 micron technology - not supported anymore #define lambda_value 150 #include "calc.lambda" #include "cifin.gen" #include "cifin.nw" #include "cifin.oldnw" #include "cifin.pw" */ /* ORBIT 2.0 micron technology */ #define lambda_value 100 #include "calc.lambda" #include "cifin.gen" #include "cifin.nw" #include "cifin.oldnw" #include "cifin.pw" #define NOWELL #include "cifin.gen" #undef NOWELL /* ORBIT 1.6 micron technology - not supported, but retained for ORBIT */ #define lambda_value 80 #include "calc.lambda" #include "cifin-ami16.gen" #include "cifin.nw" #include "cifin.oldnw" #include "cifin.pw" #define NOWELL #include "cifin.gen" #undef NOWELL /* 1.2 micron technology */ #define lambda_value 60 #include "calc.lambda" #include "cifin.gen" #include "cifin.nw" #include "cifin.oldnw" #include "cifin.pw" #define NOWELL #include "cifin.gen" #undef NOWELL /* 1.2 micron technology - for Mentor Graphics CMOSN technology */ #define lambda_value 100 #include "calc.lambda" #include "cifin-cmosn.gen" /* all other technology */ /* #include "cifin.others" */ #endif /* Standard SCMOS technologies */ #ifdef TIGHTMETAL /* HP CMOS34 1.2 micron technology */ #define lambda_value 60 #include "calc.lambda" #include "cifin.gen" #include "cifin.nw" #include "cifin.oldnw" #define NOWELL #include "cifin.gen" #undef NOWELL /* HP CMOS26B 1.0 micron technology */ #define lambda_value 50 #include "calc.lambda" #include "cifin-cmos26b.gen" #include "cifin.nw" #include "cifin.oldnw" #define NOWELL #include "cifin-cmos26b.gen" #undef NOWELL /* HP CMOS14B 0.6 micron technology */ #define lambda_value 35 #include "calc.lambda" #include "cifin-cmos14b.gen" /* read HP's layer assignment from Mentor */ /* #define lambda_value 20 #include "calc.lambda" #include "cifin-hp-cif.nw" */ /* This is just testing... #define lambda_value 20 #include "calc.lambda" #include "cifin.cascade" */ #endif /* Tight Metal Technologies ends here .... */ #ifdef SUBMICRON /* HP CMOS26G 0.8 micron technology */ #define lambda_value 40 #include "calc.lambda" #include "cifin-cmos26g.gen" #define NOWELL #include "cifin-cmos26g.gen" #undef NOWELL #include "cifin.nw" /* HP CMOS14B 0.6 micron technology */ #define lambda_value 30 #include "calc.lambda" #include "cifin-cmos14b.gen" #define NOWELL #include "cifin-cmos14b.gen" #undef NOWELL /* 0.8 micron CMOSX technology */ /* #define lambda_value 40 #include "calc.lambda" #include "cifin-cmosx.gen" #define NOWELL #include "cifin-cmosx.gen" #undef NOWELL */ #endif /* HP CMOS26G and CMOS14B process */ #ifdef IBM /* IBM */ /* 0.8 micron technology */ #define lambda_value 40 #include "calc.lambda" #include "cifin-ibm.gen" #define NOWELL #include "cifin-ibm.gen" #include "cifin.nw" #undef NOWELL #endif /* IBM */ magic-8.0.210/scmos/cif_template/Makefile0000664000175000001440000000402412136553675016711 0ustar timusersMAGICDIR = ../.. MKDIR = $(MAGICDIR)/scripts/mkdirs OBJS_DIR = objs CIFIN = $(OBJS_DIR)/CIFin CIFOUT = $(OBJS_DIR)/CIFout IBMCIFIN = $(OBJS_DIR)/IBMCIFin IBMCIFOUT = $(OBJS_DIR)/IBMCIFout TMCIFIN = $(OBJS_DIR)/TMCIFin TMCIFOUT = $(OBJS_DIR)/TMCIFout SUBCIFIN = $(OBJS_DIR)/SUBCIFin SUBCIFOUT = $(OBJS_DIR)/SUBCIFout SED_CMD = sed -e "s/\\\\/\\\\\\\\/" -e "/^\#/D" -e "s/(gen )/(gen)/" -e "s/(nowell )/(nowell)/" -e "s/(nwell )/(nwell)/" -e "s/(pwell )/(pwell)/" include ${MAGICDIR}/defs.mak SC_CPP = ${CPP} all: $(OBJS_DIR) $(CIFIN) $(CIFOUT) $(IBMCIFIN) $(IBMCIFOUT) $(TMCIFIN) \ $(TMCIFOUT) $(SUBCIFIN) $(SUBCIFOUT) clean:; rm -f $(CIFIN) $(CIFOUT) $(IBMCIFIN) $(IBMCIFOUT) $(TMCIFIN) \ $(TMCIFOUT) $(SUBCIFIN) $(SUBCIFOUT) scg: cifout.c cifout-cmos26b.gen cifout.gen cifout.nw\ cifout.others cifout.pw cifout.scgnw cifout.scgpw rm -f $(CIFOUT) $(SC_CPP) scgcifout.c | ${SED_CMD} > $(CIFOUT) $(OBJS_DIR): $(MKDIR) $(OBJS_DIR) $(CIFIN): cifin.c cifin-cmos26b.gen cifin.gen cifin.nw cifin.oldnw\ cifin.others cifin.pw cifin-ami16.gen rm -f $(CIFIN) $(SC_CPP) -DSTANDARD cifin.c | ${SED_CMD} > $(CIFIN) $(CIFOUT): cifout.c cifout-cmos26b.gen cifout.gen cifout.nw\ cifout.others cifout.pw cifout-ami16.gen rm -f $(CIFOUT) $(SC_CPP) -DSTANDARD cifout.c | ${SED_CMD} > $(CIFOUT) $(IBMCIFIN): cifin.c cifin-ibm.gen rm -f $(IBMCIFIN) $(SC_CPP) -DIBM cifin.c | ${SED_CMD} > $(IBMCIFIN) $(IBMCIFOUT): cifout.c cifout-ibm.gen rm -f $(IBMCIFOUT) $(SC_CPP) -DIBM cifout.c | ${SED_CMD} > $(IBMCIFOUT) $(TMCIFIN): cifin.c cifin-cmos26b.gen rm -f $(TMCIFIN) $(SC_CPP) -DTIGHTMETAL cifin.c | ${SED_CMD} > $(TMCIFIN) $(TMCIFOUT): cifout.c cifout-cmos26b.gen rm -f $(TMCIFOUT) $(SC_CPP) -DTIGHTMETAL cifout.c | ${SED_CMD} > $(TMCIFOUT) $(SUBCIFIN): cifin.c cifin-cmos26g.gen cifin-cmos14b.gen rm -f $(SUBCIFIN) $(SC_CPP) -DSUBMICRON cifin.c | ${SED_CMD} > $(SUBCIFIN) $(SUBCIFOUT): cifout.c cifout-cmos26g.gen cifout-cmos14b.gen rm -f $(SUBCIFOUT) $(SC_CPP) -DSUBMICRON cifout.c | ${SED_CMD} > $(SUBCIFOUT) magic-8.0.210/scmos/cif_template/cifout26g.c0000644000175000001440000000050010751423606017205 0ustar timusers /* 0.8 micron technology */ #define lambda_value 40 #include "calc.lambda" #include "cifout-cmos26g.gen" /* This one is used for an internal SOI technology */ #include "cifout-cmos26g.soi" /* 0.6 micron technology */ #define cif_tech hp14b #define lambda_value 30 #include "calc.lambda" #include "cifout-cmos14b.gen" magic-8.0.210/scmos/cif_template/cifin.cascade0000644000175000001440000000303210751423606017631 0ustar timusers/* For CIF file generated by CASCADE's Epoch... */ #define cif_tech cascade style lambda=lambda_v scalefactor lambda_1 layer nwell CNW labels CNW layer pwell CPW labels CPW layer m2 CM2 labels CM2 layer m1 CM labels CM layer poly CP labels CP layer pdiff CPP and CD and CNW layer ndiff CNP and CD and CPW layer nsd CNW and CNP and CD layer psd CPW and CPP and CD layer nfet CP and CD and CNP layer pfet CD and CP and CPP layer ndc CC grow lambda_1 and CD and CPW and CNP and CM layer pdc CC grow lambda_1 and CD and CNW and CPP and CM layer nsc CC grow lambda_1 and CD and CNP and CNW and CM layer psc CC grow lambda_1 and CD and CPP and CPW and CM layer m2c CV grow lambda_1 and CM2 and CM labels CM2 layer pc CC grow lambda_1 and CP and CM layer glass CG layer pad CM shrink lambda_1 and CM2 shrink lambda_5 and CV shrink lambda_1 and CG grow lambda_6 calma CNW 1 * calma CPW 2 * calma CD 3 * calma CP 4 * calma CPP 31 * calma CNP 32 * calma CC 9 * calma CM 10 * calma CV 11 * calma CM2 12 * calma CG 13 * #undef cif_tech magic-8.0.210/scmos/cif_template/cifin-cmosn.nw0000644000175000001440000000441210751423606020012 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet poly capacitor bipolar NPN transistor buried CCD devices linear capacitor */ #define cif_tech cmosn style lambda=lambda_v scalefactor lambda_1 layer nwell CWN labels CWN layer m2 CMS labels CMS layer m1 CMF labels CMF layer poly CPG labels CPG layer psd CAA and CSP layer pdiff CWN and CAA and CSP labels CSP layer ndiff CAA and CSN labels CSN layer nsd CWN and CSN and CAA layer nfet CPG and CAA and CSN layer pfet CAA and CPG and CSP and CWN layer enfet CEL and CAA and CSN layer epfet CAA and CEL and CSP and CWN layer nffet CAA and CEL and CPG and CSN layer pffet CAA and CEL and CPG and CSP and CWN layer m2c CVA grow lambda_1 and CMS and CMF layer electrode CEL labels CEL layer ec CCC grow lambda_1 and CMF and CEL layer cc CCC grow lambda_1 and CMF and CEL and CPG labels CCC layer cap CPG and CEL and-not CAA layer psc CCC grow lambda_1 and CAA and CSP and CMF layer ndc CCC grow lambda_1 and CAA and CSN and CMF layer pdc CCC grow lambda_1 and CAA and CWN and CSP and CMF layer nsc CCC grow lambda_1 and CAA and CSN and CWN and CMF layer pbc CCC grow lambda_1 and CBA and CMF layer pc CCC grow lambda_1 and CPG and CMF labels CCC layer glass COG labels COG layer pad CMF shrink lambda_1 and CMS shrink lambda_5 and CVA shrink lambda_1 and COG grow lambda_6 and XP calma CWN 1 * calma CAA 3 * calma CSP 8 * calma CSN 7 * calma CPG 4 * calma CCC 9 * calma CMF 10 * calma CVA 11 * calma CMS 12 * calma COG 13 * calma CEL 5 * #undef cif_tech magic-8.0.210/scmos/cif_template/cifout-orbit.nw0000644000175000001440000000565010751423606020220 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet poly capacitor bipolar NPN transistor buried CCD devices linear capacitor metal3 and via2 "pad" layer generate *no* metal3 */ #define cif_tech nwell style lambda=lambda_v scalefactor lambda_1 scaleunit layer CWC cwell calma 59 1 layer CWN nwell bloat-or pbase,pbc/a * lambda_6 bloat-or allPDiff,PFet * lambda_5 bloat-or allNOhmic * lambda_3 bloat-or clc/a * lambda_1 or col grow lambda_3 shrink lambda_3 calma 42 1 layer CMS allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_1 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 layer CAA clc grow lambda_1 or em,emc,col,pbase,pbc or allActive or allHVDiff or allCCDiff #ifdef OPEN or open,pstop #endif labels ndiff,pdiff calma 43 1 /* use CX layer to distinguish "col" and "nsd" */ layer CX col,clc grow lambda_1 calma 60 1 layer CVA pad shrink pad_via #ifdef OPEN or open #endif calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 layer CEL allPoly2 calma 56 1 layer CCE capc,ec squares lambda_2 calma 55 1 /* NOTE: no calma layer spec. for CCC, contact will NOT in stream file */ layer CCC gc calma 63 1 /* contacts for pdc/nsc (ndc/psc) must be generated separately */ layer CCA ndc,pdc,BiCut,nbdc squares lambda_2 #ifdef OPEN or open #endif calma 48 1 layer CCA nsc,psc squares lambda_2 calma 48 1 layer CCP pc squares lambda_2 calma 47 1 layer CBA emc,emit grow lambda_4 bloat-or pbc * lambda_1 or pbase calma 58 1 /* temp CIF layer for select generation */ templayer XTN clc grow lambda_1 or em,emc,col grow lambda_2 bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or nbd,nbdc,ndop,wcap * lambda_2 templayer XTP pbc grow lambda_1 bloat-or allPDiff * lambda_2 allNOhmic 0 layer CSN clc grow lambda_1 or emc,emit,col grow lambda_2 bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff 0 bloat-or nbd,nbdc,ndop,wcap * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP calma 45 1 layer CSP pbc grow lambda_1 bloat-or allPDiff * lambda_2 allNOhmic 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff 0 bloat-or pdop * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half #ifdef OPEN bloat-min pstop * lambda_2 open 0 #endif and-not XTN and-not CSN calma 44 1 layer CCD allCCDiff grow lambda_2 calma 57 1 layer COP open calma 23 1 layer CPS pstop calma 24 1 layer COG pad shrink pad_glass or glass #ifdef OPEN or open #endif labels pad calma 52 1 layer XP pad shrink pad_glass calma 26 1 #undef cif_tech magic-8.0.210/scmos/cif_template/cifout.nw0000644000175000001440000000622510751423606017102 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet poly capacitor bipolar NPN transistor buried CCD devices linear capacitor metal3 and via2 "pad" layer generate *no* metal3 */ #define cif_tech nwell style lambda=lambda_v scalefactor lambda_1 scaleunit layer CWC cwell calma 59 1 layer CWN nwell bloat-or pbase,pbc/a * lambda_6 bloat-or allPDiff,PFet * lambda_5 bloat-or allNOhmic * lambda_3 bloat-or clc/a * lambda_1 or col grow lambda_3 shrink lambda_3 calma 42 1 layer CMT allMetal3 labels m3 calma 62 1 layer CMS allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_1 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 layer CAA clc grow lambda_1 or em,emc,col,pbase,pbc or allActive or allHVDiff or allCCDiff #ifdef OPEN or open,pstop #endif labels ndiff,pdiff calma 43 1 layer CVS pad shrink lambda_2 #ifdef OPEN or open #endif calma 61 1 layer CVS m3c squares lambda_1 lambda_2 lambda_3 calma 61 1 /* use CX layer to distinguish "col" and "nsd" */ layer CX col,clc grow lambda_1 calma 60 1 layer CVA pad shrink pad_via #ifdef OPEN or open #endif calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 layer CEL allPoly2 calma 56 1 layer CCE capc,ec squares lambda_2 calma 55 1 /* NOTE: no calma layer spec. for CCC, contact will NOT in stream file */ layer CCC gc calma 63 1 /* contacts for pdc/nsc (ndc/psc) must be generated separately */ layer CCA ndc,pdc,BiCut,nbdc squares lambda_2 #ifdef OPEN or open #endif calma 48 1 layer CCA nsc,psc squares lambda_2 calma 48 1 layer CCP pc squares lambda_2 calma 47 1 layer CBA emc,emit grow lambda_4 bloat-or pbc * lambda_1 or pbase calma 58 1 /* temp CIF layer for select generation */ templayer XTN clc grow lambda_1 or em,emc,col grow lambda_2 bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or nbd,nbdc,ndop,wcap * lambda_2 templayer XTP pbc grow lambda_1 bloat-or allPDiff * lambda_2 allNOhmic 0 layer CSN clc grow lambda_1 or emc,emit,col grow lambda_2 bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff 0 bloat-or nbd,nbdc,ndop,wcap * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP calma 45 1 layer CSP pbc grow lambda_1 bloat-or allPDiff * lambda_2 allNOhmic 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff 0 bloat-or pdop * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half #ifdef OPEN bloat-min pstop * lambda_2 open 0 #endif and-not XTN and-not CSN calma 44 1 layer CCD allCCDiff grow lambda_2 calma 57 1 layer COP open calma 23 1 layer CPS pstop calma 24 1 layer COG pad shrink pad_glass or glass #ifdef OPEN or open #endif labels pad calma 52 1 layer XP pad shrink pad_glass calma 26 1 #undef cif_tech magic-8.0.210/scmos/cif_template/cifin-cmos26g.gen0000644000175000001440000000542210751423606020302 0ustar timusers/* For HP CMOS26B process... No CCD, Bipolar, Poly2 layers. Two types of pad layer are supported, one (the pad layer) contains both metal1 and metal2 layer while the other (the pad2 layer) contains all three metals with all necessary via properly defined... */ /* This is prelimanary, please let me know if anything here seems abnormal to you... pi@lepton.isi.edu 3/15/93 */ #ifdef NOWELL #undef cif_tech #define cif_tech nowell style lambda=lambda_v #else #undef cif_tech #define cif_tech sub style lambda=lambda_v #endif scalefactor lambda_1 #ifndef NOWELL layer nwell CWN labels CWN layer pwell CWP labels CWP #endif layer m3 CMT /* to avoid a CIF read problem around pads */ and-not XP labels CMT layer m2 CMS labels CMS layer m1 CMF labels CMF layer poly CPG labels CPG layer ndop CSN and-not CWP and CAA layer pdop CSP and CAA and-not CWP and-not CPS layer pdiff CSP and CWN and CAA layer ndiff CSN and CWP and CAA layer nsd CWN and CSN and CAA layer psd CSP and CWP and CAA layer pbase CBA labels CBA layer nfet CPG and CAA and CSN labels CPG layer pfet CAA and CPG and CSP labels CPG layer ndc CCA grow lambda_1 and CAA and CWP and CSN and CMF layer pdc CCA grow lambda_1 and CAA and CWN and CSP and CMF layer nsc CCA grow lambda_1 and CAA and CSN and CWN and CMF layer psc CCA grow lambda_1 and CAA and CSP and CWP and CMF layer pbc CCA grow lambda_1 and CBA and CMF labels CBA layer m3c CVS grow lambda_1 and CMT and CMS and-not XP layer m2c CVA grow lambda_1 and CMS and CMF layer pc CCP grow lambda_1 and CPG and CMF layer gc CCC layer glass COG labels COG #ifdef OPEN layer open CAA and CCA and CVA and COG and COP layer pstop CAA and CPS and CSP and-not CWP and-not CWN #endif /* assume all contact are in place .. */ layer pad COG grow pad_glass and XP #ifdef OPEN calma COP 23 * calma CPS 24 * #endif calma CWP 41 * calma CWN 42 * calma CAA 43 * calma CSP 44 * calma CSN 45 * calma CPG 46 * calma CCP 47 * calma CCA 48 * calma CMF 49 * calma CVA 50 * calma CMS 51 * calma COG 52 * calma CVS 61 * calma CMT 62 * calma CCC 63 * magic-8.0.210/scmos/cif_template/cifout-cmos34.nw0000644000175000001440000000565010751423606020211 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet poly capacitor bipolar NPN transistor buried CCD devices linear capacitor metal3 and via2 "pad" layer generate *no* metal3 */ #define cif_tech nwell style lambda=lambda_v scalefactor lambda_1 scaleunit layer CWC cwell calma 59 1 layer CWN nwell bloat-or pbase,pbc/a * lambda_6 bloat-or allPDiff,PFet * lambda_5 bloat-or allNOhmic * lambda_3 bloat-or clc/a * lambda_1 or col grow lambda_3 shrink lambda_3 calma 42 1 layer CMS allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_1 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 layer CAA clc grow lambda_1 or em,emc,col,pbase,pbc or allActive or allHVDiff or allCCDiff #ifdef OPEN or open,pstop #endif labels ndiff,pdiff calma 43 1 /* use CX layer to distinguish "col" and "nsd" */ layer CX col,clc grow lambda_1 calma 60 1 layer CVA pad shrink pad_via #ifdef OPEN or open #endif calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 layer CEL allPoly2 calma 56 1 layer CCE capc,ec squares lambda_2 calma 55 1 /* NOTE: no calma layer spec. for CCC, contact will NOT in stream file */ layer CCC gc calma 63 1 /* contacts for pdc/nsc (ndc/psc) must be generated separately */ layer CCA ndc,pdc,BiCut,nbdc squares lambda_2 #ifdef OPEN or open #endif calma 48 1 layer CCA nsc,psc squares lambda_2 calma 48 1 layer CCP pc squares lambda_2 calma 47 1 layer CBA emc,emit grow lambda_4 bloat-or pbc * lambda_1 or pbase calma 58 1 /* temp CIF layer for select generation */ templayer XTN clc grow lambda_1 or em,emc,col grow lambda_2 bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or nbd,nbdc,ndop,wcap * lambda_2 templayer XTP pbc grow lambda_1 bloat-or allPDiff * lambda_2 allNOhmic 0 layer CSN clc grow lambda_1 or emc,emit,col grow lambda_2 bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff 0 bloat-or nbd,nbdc,ndop,wcap * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP calma 45 1 layer CSP pbc grow lambda_1 bloat-or allPDiff * lambda_2 allNOhmic 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff 0 bloat-or pdop * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half #ifdef OPEN bloat-min pstop * lambda_2 open 0 #endif and-not XTN and-not CSN calma 44 1 layer CCD allCCDiff grow lambda_2 calma 57 1 layer COP open calma 23 1 layer CPS pstop calma 24 1 layer COG pad shrink pad_glass or glass #ifdef OPEN or open #endif labels pad calma 52 1 layer XP pad shrink pad_glass calma 26 1 #undef cif_tech magic-8.0.210/scmos/cif_template/cifout.scgpw0000644000175000001440000000374610751423606017606 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet poly capacitor. NO Bipolar stuff */ #define cif_tech scg_pwell style lambda=lambda_v scalefactor lambda_1 scaleunit layer CWG pwell bloat-or allNDiff,NFet * lambda_5 bloat-or allPOhmic * lambda_3 grow lambda_3 shrink lambda_3 calma 53 1 layer CMS allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_1 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 layer CAA or allActive or allHVDiff labels ndiff,pdiff calma 43 1 /* use CX layer to distinguish "col" and "nsd" which CIF input */ layer CX col,clc grow lambda_1 calma 60 1 layer CVA pad shrink pad_via calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 layer CEL allPoly2 calma 56 1 layer CCE capc,ec squares lambda_2 calma 55 1 /* NOTE: no calma layer spec. for CCC, contact will not in stream file */ layer CCC gc calma 63 1 /* contacts for pdc/nsc (ndc/psc) must be generated separately */ layer CCA ndc,pdc,BiCut squares lambda_2 calma 48 1 layer CCA nsc,psc squares lambda_2 calma 48 1 layer CCP pc squares lambda_2 calma 47 1 /* temp CIF layer for select generation */ templayer XTN bloat-or allNDiff * lambda_2 allPOhmic 0 layer CSG bloat-or allPDiff * lambda_2 allNOhmic 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff 0 bloat-or pdop * lambda_2 and-not XTN grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half calma 54 1 /* layer CSN bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff 0 bloat-or ndop * lambda_2 and-not XTP grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half calma 45 1 */ layer COG pad shrink pad_glass or glass calma 52 1 layer XP pad shrink pad_glass #undef cif_tech magic-8.0.210/scmos/cif_template/cifin-hp-cif.nw0000644000175000001440000000212110751423606020034 0ustar timusers/* available devices: nfet,pfet */ #define cif_tech hp style lambda=lambda_v scalefactor lambda_1 layer nwell CWN labels CWN layer m3 CMT labels CMT layer m2 CMS labels CMS layer m1 CMF labels CMF layer poly CPG labels CPG layer psd CSP and-not CWN layer pdiff CWN and CSP labels CSP layer ndiff CSN and-not CWN labels CSN layer nsd CWN and CSN layer nfet CPG and CSN and-not CWN layer pfet CPG and CSP and CWN layer m3c CVS labels CVS layer m2c CVA labels CVA layer gc CCA labels CCA layer glass COG labels COG layer pad CMF shrink lambda_1 and CMS shrink lambda_5 and CVA shrink lambda_1 and COG grow lambda_6 calma CWN 1 * calma CPG 4 * calma CCA 8 * calma CMF 9 * calma CVA 10 * calma CMS 11 * calma CVS 12 * calma CMT 13 * calma COG 14 * calma CSN 21 * calma CSP 22 * #undef cif_tech magic-8.0.210/scmos/cif_template/cifout-orbit.pw0000644000175000001440000000505510751423606020221 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet poly capacitor meatl3 and via2 "pad" layer generate *no* metal3 */ #define cif_tech pwell style lambda=lambda_v scalefactor lambda_1 scaleunit layer CWP pwell bloat-or allNDiff,NFet * lambda_5 bloat-or allPOhmic * lambda_3 grow lambda_3 shrink lambda_3 calma 41 1 layer CMS allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_1 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 /* "clc" here for savety reason */ layer CAA clc grow lambda_1 or em,emc,col or allActive or allHVDiff #ifdef OPEN or open,pstop #endif labels ndiff,pdiff calma 43 1 /* use CX layer to distinguish "col" and "nsd" which CIF input */ layer CX col,clc grow lambda_1 calma 60 1 layer CVA pad shrink pad_via #ifdef OPEN or open #endif calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 layer CEL allPoly2 calma 56 1 layer CCE capc,ec squares lambda_2 calma 55 1 /* NOTE: no calma layer spec. for CCC, contact will not in stream file */ layer CCC gc calma 63 1 /* contacts for pdc/nsc (ndc/psc) must be generated separately */ layer CCA ndc,pdc,BiCut squares lambda_2 #ifdef OPEN or open #endif calma 48 1 layer CCA nsc,psc squares lambda_2 calma 48 1 layer CCP pc squares lambda_2 calma 47 1 layer CBA emc,emit grow lambda_4 bloat-or pbc * lambda_1 or pbase calma 58 1 /* temp CIF layer for select generation */ templayer XTN bloat-or allNDiff * lambda_2 allPOhmic 0 templayer XTP bloat-or allPDiff * lambda_2 allNOhmic 0 layer CSP bloat-or allPDiff * lambda_2 allNOhmic 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff 0 bloat-or pdop * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half #ifdef OPEN bloat-min pstop * lambda_2 open 0 #endif and-not XTN calma 44 1 layer CSN bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff 0 bloat-or ndop * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP and-not CSP calma 45 1 layer COP open calma 23 1 layer CPS pstop calma 24 1 layer COG pad shrink pad_glass or glass #ifdef OPEN or open #endif labels pad calma 52 1 layer XP pad shrink pad_glass calma 26 1 #undef cif_tech magic-8.0.210/scmos/cif_template/cifin.gen0000644000175000001440000000770010751423606017025 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet poly capacitor bipolar NPN transistor buried CCD devices linear capacitor micro-machined devices metal3 and via2 */ #ifndef NOWELL #define cif_tech gen #else #define cif_tech nowell #endif style lambda=lambda_v scalefactor lambda_1 #ifndef NOWELL layer nwell CWN labels CWN layer pwell CWP labels CWP #endif layer poly CPG labels CPG layer pdiff CSP and CAA and CWN layer ndiff CWP or CWC and CAA and CSN and-not CCD layer nsd CWN and CSN and CAA layer psd CWP and CSP and CAA layer pbase CBA labels CBA layer nfet CPG and CAA and CSN and-not CCD layer pfet CAA and CPG and CSP layer enfet CEL and CAA and CSN and-not CCD layer epfet CAA and CEL and CSP layer nffet CAA and CEL and CPG and CSN and CWP layer pffet CAA and CEL and CPG and CSP and CWN layer ndc CWP or CWC and CCA grow lambda_1 and CAA and CSN and CMF layer pdc CCA grow lambda_1 and CAA and CWN and CSP and CMF layer nsc CCA grow lambda_1 and CAA and CSN and CWN and CMF layer psc CCA grow lambda_1 and CAA and CSP and CWP and CMF layer gc CCC layer m2c CVA grow lambda_1 and CMS and CMF labels CMS layer m3c CVS grow lambda_1 and CMT and CMS and-not XP layer electrode CEL labels CEL layer ec CCE grow lambda_1 and CMF and CEL labels CMF layer cc CCE grow lambda_1 and CMF and CEL and CPG labels CMF layer cap CPG and CEL and-not CAA labels CEL layer pbc CCA grow lambda_1 and CBA and CMF labels CBA layer col CX and CAA and CSN and CWN labels CAA layer clc CCA grow lambda_1 and CX and CAA and CSN and CWN and CMF labels CCA layer emit CBA and CSN shrink lambda_2 labels CBA layer emc CCA grow lambda_1 and CBA and CSN and CMF labels CBA layer pc CCP grow lambda_1 and CPG and CMF layer nbd CSN shrink lambda_2 and CCD and CAA and-not CPG layer nbdc CCA grow lambda_1 and CCD and CSN and CAA layer bd CPG or CEL and CCD and CAA labels CCD /* place the Cap well at the end, so that we can read linear */ /* capacitor correctly... */ layer cwell CWC labels CWC layer glass COG #ifdef OPEN layer open CAA and CCA and CVA and COG and COP layer pstop CAA and CPS and CSP and-not CWP and-not CWN #endif layer pad CMF shrink lambda_1 and CMS shrink lambda_5 and CVA shrink lambda_1 and XP and COG grow lambda_6 layer m1 CMF labels CMF layer m2 CMS labels CMS layer m3 CMT /* to avoid a CIF read problem around pads */ and-not XP labels CMT #ifdef OPEN calma COP 23 * calma CPS 24 * #endif calma CCC 25 * calma XP 26 * calma CWP 41 * calma CWN 42 * calma CAA 43 * calma CSP 44 * calma CSN 45 * calma CPG 46 * calma CCP 47 * calma CCA 48 * calma CMF 49 * calma CVA 50 * calma CMS 51 * calma COG 52 * calma CCE 55 * calma CEL 56 * calma CCD 57 * calma CBA 58 * calma CWC 59 * calma CVS 61 * calma CMT 62 * calma CX 63 * #undef cif_tech magic-8.0.210/scmos/cif_template/scgcifout.c0000644000175000001440000000203710751423606017372 0ustar timusers/* 2.0 micron technology */ #define lambda_value 100 #include "calc.lambda" #include "cifout.gen" #include "cifout.nw" #include "cifout.pw" #include "cifout.scgnw" #include "cifout.scgpw" /* 3.0 micron technology - not supported #define lambda_value 150 #include "calc.lambda" #include "cifout.gen" #include "cifout.nw" #include "cifout.pw" */ /* 1.6 micron technology - not supported, but retained for ORBIT */ #define lambda_value 80 #include "calc.lambda" #include "cifout.gen" #include "cifout.nw" #include "cifout.pw" #include "cifout.scgnw" #include "cifout.scgpw" /* 1.2 micron technology */ #define lambda_value 60 #include "calc.lambda" #include "cifout.gen" #include "cifout.nw" #include "cifout.pw" #include "cifout.scgnw" #include "cifout.scgpw" /* 1.0 micron technology */ #define lambda_value 50 #include "calc.lambda" #include "cifout.cmos26-gen" /* 0.8 micron technology NOT included in this distribution #define lambda_value 40 #include "calc.lambda" #include "cifout.cmos14-gen" */ /* all other technology */ #include "cifout.others" magic-8.0.210/scmos/cif_template/cifout-cmos34.pw0000644000175000001440000000505510751423606020212 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet poly capacitor meatl3 and via2 "pad" layer generate *no* metal3 */ #define cif_tech pwell style lambda=lambda_v scalefactor lambda_1 scaleunit layer CWP pwell bloat-or allNDiff,NFet * lambda_5 bloat-or allPOhmic * lambda_3 grow lambda_3 shrink lambda_3 calma 41 1 layer CMS allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_1 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 /* "clc" here for savety reason */ layer CAA clc grow lambda_1 or em,emc,col or allActive or allHVDiff #ifdef OPEN or open,pstop #endif labels ndiff,pdiff calma 43 1 /* use CX layer to distinguish "col" and "nsd" which CIF input */ layer CX col,clc grow lambda_1 calma 60 1 layer CVA pad shrink pad_via #ifdef OPEN or open #endif calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 layer CEL allPoly2 calma 56 1 layer CCE capc,ec squares lambda_2 calma 55 1 /* NOTE: no calma layer spec. for CCC, contact will not in stream file */ layer CCC gc calma 63 1 /* contacts for pdc/nsc (ndc/psc) must be generated separately */ layer CCA ndc,pdc,BiCut squares lambda_2 #ifdef OPEN or open #endif calma 48 1 layer CCA nsc,psc squares lambda_2 calma 48 1 layer CCP pc squares lambda_2 calma 47 1 layer CBA emc,emit grow lambda_4 bloat-or pbc * lambda_1 or pbase calma 58 1 /* temp CIF layer for select generation */ templayer XTN bloat-or allNDiff * lambda_2 allPOhmic 0 templayer XTP bloat-or allPDiff * lambda_2 allNOhmic 0 layer CSP bloat-or allPDiff * lambda_2 allNOhmic 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff 0 bloat-or pdop * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half #ifdef OPEN bloat-min pstop * lambda_2 open 0 #endif and-not XTN calma 44 1 layer CSN bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff 0 bloat-or ndop * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP and-not CSP calma 45 1 layer COP open calma 23 1 layer CPS pstop calma 24 1 layer COG pad shrink pad_glass or glass #ifdef OPEN or open #endif labels pad calma 52 1 layer XP pad shrink pad_glass calma 26 1 #undef cif_tech magic-8.0.210/scmos/cif_template/cifout-cmosx.gen0000644000175000001440000000635210751423606020357 0ustar timusers/* This is prelimanary, please let me know if anything here seems abnormal to you... pi@lepton.isi.edu 3/02/95 */ style lambda=lambda_v scalefactor lambda_1 scaleunit layer CWN nwell bloat-or allPDiff,PFet * lambda_6 bloat-or allNOhmic * lambda_3 grow lambda_3 shrink lambda_3 calma 1 1 layer CWP pwell bloat-or allNDiff,NFet * lambda_6 pdop 0 bloat-or allPOhmic * lambda_3 ndop 0 grow lambda_3 shrink lambda_3 calma 2 1 layer CMT allMetal3,pad labels m3 calma 15 1 layer CMS pad grow lambda_2 or allMetal2 labels m2 calma 12 1 layer CMF pad grow lambda_4 or allMetal1 labels homeMetal1 calma 10 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 4 1 layer CAA allActive or ndop,pdop #ifdef OPEN or open,pstop #endif labels ndiff,pdiff calma 3 1 layer CVS pad shrink pad_via2 #ifdef OPEN or open #endif calma 14 1 layer CVS m3c squares lambda_1 lambda_2 lambda_3 calma 14 1 layer CVA pad shrink pad_via1 #ifdef OPEN or open #endif calma 11 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 11 1 /* Generic contact to (active,poly)... NOTE: no calma layer spec. for CCC, contact will not in stream file */ layer CCC gc calma 9 1 /* contacts for pdc/nsc (ndc/psc) must be generated separately */ layer CCA ndc,pdc squares lambda_1 lambda_2 lambda_3 #ifdef OPEN or open #endif calma 9 1 layer CCA nsc,psc squares lambda_1 lambda_2 lambda_3 calma 9 1 layer CCP pc squares lambda_1 lambda_2 lambda_3 calma 9 1 /* temp CIF layer - All diffusion N-Select layers */ templayer XTN bloat-or allNDiff,ndop * lambda_2 allPOhmic,allPDiff,pdop 0 bloat-or nbd,nbdc * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half /* temp CIF layer - All diffusion P-Select layers */ templayer XTP bloat-or allPDiff,pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half layer CSN bloat-or allNDiff * lambda_2 allPOhmic,pdop 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff,pdop 0 bloat-or ndop * lambda_2 allPOhmic,allPDiff,pdop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP calma 7 1 layer CSP bloat-or allPDiff * lambda_2 allNOhmic,ndop 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff,ndop 0 bloat-or pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half #ifdef OPEN bloat-min pstop * lambda_2 open 0 #endif and-not XTN and-not CSN calma 8 1 layer COG pad shrink pad_glass or glass #ifdef OPEN or open #endif labels pad calma 16 1 /* layer XP pad calma 26 1 */ #undef cif_tech magic-8.0.210/scmos/cif_template/cifout-cmos34.gen0000644000175000001440000000645310751423606020340 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet,hvnfet,hvpfet poly capacitor bipolar NPN transistor buried CCD devices linear capacitor micro-machined devices "pad" layer generate *no* metal3 */ #define cif_tech gen style lambda=lambda_v scalefactor lambda_1 scaleunit layer CWC cwell calma 59 1 layer CWN nwell bloat-or pbase,pbc/act * lambda_6 bloat-or allPDiff,PFet * lambda_5 bloat-or allNOhmic * lambda_3 bloat-or clc/a * lambda_1 or col grow lambda_3 shrink lambda_3 calma 42 1 layer CWP pwell bloat-or allNDiff,NFet * lambda_5 bloat-or allPOhmic * lambda_3 and-not CWC shrink lambda_3 grow lambda_3 grow lambda_3 shrink lambda_3 calma 41 1 layer CMS allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_1 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 layer CAA clc grow lambda_1 or em,emc,col,pbase,pbc or allActive or allHVDiff or allCCDiff #ifdef OPEN or open,pstop #endif labels ndiff,pdiff calma 43 1 /* use CX layer to distinguish "col" and "nsd" while CIF input */ layer CX col,clc grow lambda_1 calma 60 1 layer CVA pad shrink pad_via #ifdef OPEN or open #endif calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 layer CEL allPoly2 calma 56 1 layer CCE capc,ec squares lambda_2 calma 55 1 /* NOTE: no calma layer spec. for CCC, contact will not in stream file */ layer CCC gc calma 48 1 /* contacts for pdc/nsc (ndc/psc) must be generated separatelt */ layer CCA ndc,pdc,BiCut,nbdc squares lambda_2 #ifdef OPEN or open #endif calma 48 1 layer CCA nsc,psc squares lambda_2 calma 48 1 layer CCP pc squares lambda_2 calma 47 1 layer CBA emc,emit grow lambda_4 bloat-or pbc * lambda_1 or pbase calma 58 1 /* temp CIF layer for select generation */ templayer XTN clc grow lambda_1 or em,emc,col grow lambda_2 bloat-or allNDiff,ndop * lambda_2 allPOhmic,allPDiff,pdop 0 bloat-or nbd,nbdc,wcap * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half templayer XTP pbc grow lambda_1 bloat-or allPDiff,pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half layer CSN clc grow lambda_1 or em,emc,col grow lambda_2 bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff 0 bloat-or nbd,nbdc,wcap * lambda_2 bloat-or ndop * lambda_2 allPOhmic,allPDiff,pdop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP calma 45 1 layer CSP pbc grow lambda_1 bloat-or allPDiff * lambda_2 allNOhmic 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff 0 bloat-or pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half #ifdef OPEN bloat-min pstop * lambda_2 open 0 #endif and-not XTN and-not CSN calma 44 1 layer CCD allCCDiff grow lambda_2 calma 57 1 layer COP open calma 23 1 layer CPS pstop calma 24 1 layer COG pad shrink pad_glass or glass #ifdef OPEN or open #endif labels pad calma 52 1 layer XP pad shrink pad_glass calma 26 1 #undef cif_tech magic-8.0.210/scmos/cif_template/COPYRIGHT0000644000175000001440000000321510751423606016532 0ustar timusers/* * (C) Copyright 1992,1994,1995 by * * Jen-I Pi pi@isi.edu * The MOSIS Service * USC Information Sciences Institute * 4676 Admiralty Way * Marina del Rey, CA 90292 * (310) 822-1511 x640 fax (310)823-5624 * * All Rights Reserved. * * Permission to use, copy, modify, and distribute this technology * file and its associated documentation for any purpose and without * fee is hereby granted, provided that the above copyright notice * appears in all copies and that both that copyright notice and this * permission notice appear in supporting documentation, and that the * name of the University of Southern California not be used in * advertising or publicity pertaining to distribution of the software * without specific, written prior permission. The University of * Southern California makes no representations about the suitability * of this technology file for any purpose. This technology file is * provided "as is" without express or implied warranty and the * University of Southern California retains the right to change its * content at any time without notice any other party. * * THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS TECHNOLOGY FILE, INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF * SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS TECHNOLOGY FILE. * */ magic-8.0.210/scmos/cif_template/cifout-ibm.gen0000644000175000001440000000635410751423606017777 0ustar timusers style lambda=0.4(ibm) scalefactor lambda_1 scaleunit layer CWN nwell bloat-or pbase,pbc/act * lambda_6 bloat-or allPDiff,PFet * lambda_5 bloat-or allNOhmic * lambda_3 bloat-or clc/act * lambda_1 or col grow lambda_3 shrink lambda_3 calma 42 1 layer CWP pwell bloat-or allNDiff,NFet * lambda_5 pdop 0 bloat-or allPOhmic * lambda_3 ndop 0 grow lambda_3 shrink lambda_3 calma 41 1 layer CMT allMetal3,pad labels m3 calma 62 1 layer CMS pad grow lambda_2 or allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_4 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 layer CAA allActive or ndop,pdop #ifdef OPEN or open,pstop #endif labels ndiff,pdiff calma 43 1 layer CVS pad shrink lambda_2 or open calma 61 1 layer CVS m3c squares lambda_1 lambda_2 lambda_3 calma 61 1 layer CVA pad shrink lambda_5 #ifdef OPEN or open #endif calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 /* Generic contact to (active,poly)... NOTE: no calma layer spec. for CCC, contact will not in stream file */ layer CCC gc calma 63 1 /* contacts for pdc/nsc (ndc/psc) must be generated separately */ layer CCA ndc,pdc squares lambda_2 #ifdef OPEN or open #endif calma 48 1 layer CCA nsc,psc squares lambda_2 calma 48 1 layer CCP pc squares lambda_2 calma 47 1 /* temp CIF layer - All diffusion N-Select layers */ templayer XTN bloat-or allNDiff,ndop * lambda_2 allPOhmic,allPDiff,pdop 0 bloat-or nbd,nbdc * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half /* temp CIF layer - All diffusion P-Select layers */ templayer XTP bloat-or allPDiff,pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half layer CSN bloat-or allNDiff * lambda_2 allPOhmic,pdop 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff,pdop 0 bloat-or ndop * lambda_2 allPOhmic,allPDiff,pdop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP calma 45 1 layer CSP bloat-or allPDiff * lambda_2 allNOhmic,ndop 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff,ndop 0 bloat-or pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half #ifdef OPEN bloat-min pstop * lambda_2 open 0 #endif and-not XTN and-not CSN calma 44 1 layer COP open calma 23 1 layer CPS pstop calma 24 1 layer COG pad shrink pad_glass or glass #ifdef OPEN or open #endif labels pad calma 52 1 layer XP pad shrink pad_glass calma 26 1 #undef cif_tech magic-8.0.210/scmos/cif_template/cifout-cmosn.gen0000644000175000001440000000372210751423606020343 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet poly capacitor micro-machined devices */ #define cif_tech cmosn style lambda=lambda_v scalefactor lambda_1 scaleunit layer NWN nwell bloat-or allPDiff,PFet * lambda_5 bloat-or allNOhmic * lambda_3 grow lambda_3 shrink lambda_3 calma 1 1 layer NWP pwell bloat-or allNDiff,NFet * lambda_5 bloat-or allPOhmic * lambda_3 grow lambda_3 shrink lambda_3 calma 2 1 layer NMS allMetal2 labels m2 calma 12 1 layer NMF pad grow lambda_1 or allMetal1 labels homeMetal1 calma 10 1 layer NPG cap or allPoly labels poly,nfet,pfet calma 4 1 layer NAA allActive or open,pstop labels ndiff,pdiff calma 3 1 layer NVA pad shrink pad_via or open calma 11 1 layer NVA m2c calma 11 1 layer NEL allPoly2 calma 5 1 layer NCT gc or capc or ec calma 9 1 /* temp CIF layer for select generation */ templayer XTN bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or ndop * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half templayer XTP bloat-or allPDiff * lambda_2 allNOhmic 0 bloat-or pdop * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half layer NSN bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff 0 bloat-or ndop * lambda_2 allPOhmic,allPDiff,pdop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP calma 45 1 layer NSP bloat-or allPDiff * lambda_2 allNOhmic 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff 0 bloat-or pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half bloat-min pstop * lambda_2 open 0 and-not XTN and-not NSN calma 44 1 layer NOG pad shrink pad_glass or glass or open labels pad calma 52 1 layer XP pad shrink pad_glass #undef cif_tech magic-8.0.210/scmos/cif_template/cifout.gen0000644000175000001440000000727510751423606017235 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet,hvnfet,hvpfet poly capacitor bipolar NPN transistor buried CCD devices linear capacitor micro-machined devices "pad" layer generate *no* metal3 */ #define cif_tech gen style lambda=lambda_v scalefactor lambda_1 scaleunit layer CWC cwell calma 59 1 layer CWN nwell bloat-or pbase,pbc/act * lambda_6 bloat-or allPDiff,PFet * lambda_5 bloat-or allNOhmic * lambda_3 bloat-or clc/a * lambda_1 or col grow lambda_3 shrink lambda_3 calma 42 1 layer CWP pwell bloat-or allNDiff,NFet * lambda_5 bloat-or allPOhmic * lambda_3 and-not CWC shrink lambda_3 grow lambda_3 grow lambda_3 shrink lambda_3 calma 41 1 layer CMT allMetal3 labels m3 calma 62 1 layer CMS allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_1 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 layer CAA clc grow lambda_1 or em,emc,col,pbase,pbc or allActive or allHVDiff or allCCDiff #ifdef OPEN or open,pstop #endif labels ndiff,pdiff calma 43 1 /* use CX layer to distinguish "col" and "nsd" while CIF input */ layer CX col,clc grow lambda_1 calma 60 1 layer CVA pad shrink pad_via #ifdef OPEN or open #endif calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 layer CEL allPoly2 calma 56 1 layer CCE capc,ec squares lambda_2 calma 55 1 /* NOTE: no calma layer spec. for CCC, contact will not in stream file */ layer CCC gc calma 48 1 /* contacts for pdc/nsc (ndc/psc) must be generated separatelt */ layer CCA ndc,pdc,BiCut,nbdc squares lambda_2 #ifdef OPEN or open #endif calma 48 1 layer CCA nsc,psc squares lambda_2 calma 48 1 layer CCP pc squares lambda_2 calma 47 1 layer CBA emc,emit grow lambda_4 bloat-or pbc * lambda_1 or pbase grow lambda_2 shrink lambda_2 calma 58 1 /* temp CIF layer for select generation */ templayer XTN clc grow lambda_1 or em,emc,col grow lambda_2 bloat-or allNDiff,ndop * lambda_2 allPOhmic,allPDiff,pdop 0 bloat-or nbd,nbdc,wcap * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half templayer XTP pbc grow lambda_1 bloat-or allPDiff,pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half layer CSN clc grow lambda_1 or em,emc,col grow lambda_2 bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff 0 bloat-or nbd,nbdc,wcap * lambda_2 bloat-or ndop * lambda_2 allPOhmic,allPDiff,pdop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP calma 45 1 layer CSP pbc grow lambda_1 bloat-or allPDiff * lambda_2 allNOhmic 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff 0 bloat-or pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half #ifdef OPEN bloat-min pstop * lambda_2 open 0 #endif and-not XTN and-not CSN calma 44 1 layer CCD allCCDiff grow lambda_2 calma 57 1 layer COP open calma 23 1 layer CPS pstop calma 24 1 layer COG pad shrink pad_glass or glass #ifdef OPEN or open #endif labels pad calma 52 1 layer XP pad shrink pad_glass calma 26 1 render CWN 12 -0.2 0.2 render CAA 2 -0.15 0.15 render CPG 1 0.025 0.05 render CEL 14 0.1 0.05 render CCC 19 0.0 0.2 render CCA 19 0.0 0.2 render CCP 19 0.075 0.125 render CMF 20 0.2 0.05 render CVA 19 0.25 0.05 render CMS 21 0.3 0.05 #undef cif_tech magic-8.0.210/scmos/cif_template/cifin.pw0000644000175000001440000000473110751423606016703 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet poly capacitor */ #define cif_tech pwell style lambda=lambda_v scalefactor lambda_1 layer pwell CWP labels CWP layer m3 CMT /* to avoid a CIF read problem around pads */ and-not XP labels CMT layer m2 CMS labels CMS layer m1 CMF labels CMF layer poly CPG labels CPG layer nsd CAA and CSN layer ndiff CWP and CSN and CAA layer pdiff CAA and CSP and-not CPS layer psd CWP and CSP and CAA layer pfet CPG and CAA and CSP layer nfet CAA and CPG and CSN and CWP layer epfet CEL and CAA and CSP layer enfet CAA and CEL and CSN and CWP layer m2c CVA grow lambda_1 and CMS and CMF labels CMS layer electrode CEL labels CEL layer ec CCE grow lambda_1 and CMF and CEL labels CMF layer cc CCE grow lambda_1 and CMF and CEL and CPG labels CMF layer cap CPG and CEL and-not CAA labels CEL layer nsc CCA grow lambda_1 and CAA and CSN and CMF layer pdc CCA grow lambda_1 and CAA and CSP and CMF layer ndc CCA grow lambda_1 and CSN and CAA and CWP and CMF layer psc CCA grow lambda_1 and CAA and CSP and CWP and CMF layer pc CCP grow lambda_1 and CPG and CMF layer m3c CVS grow lambda_1 and CMT and CMS and-not XP layer glass COG #ifdef OPEN layer open CAA and CCA and CVA and COG and COP layer pstop CAA and CPS and CSP and-not CWP #endif layer pad CMF shrink lambda_1 and CMS shrink lambda_5 and CVA shrink lambda_1 and XP and COG grow lambda_6 #ifdef OPEN calma COP 23 * calma CPS 24 * #endif calma XP 26 * calma CWP 41 * calma CAA 43 * calma CSP 44 * calma CSN 45 * calma CPG 46 * calma CCP 47 * calma CCA 48 * calma CMF 49 * calma CVA 50 * calma CMS 51 * calma COG 52 * calma CCE 55 * calma CEL 56 * calma CVS 61 * calma CMT 62 * #undef cif_tech magic-8.0.210/scmos/cif_template/cifout-cmosn.nw0000644000175000001440000000506410751423606020217 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet poly capacitor bipolar NPN transistor buried CCD devices linear capacitor */ #define cif_tech nwell style lambda=lambda_v scalefactor lambda_1 scaleunit layer CWC cwell calma 59 1 layer CWN nwell bloat-or pbase,pbc/a * lambda_6 bloat-or allPDiff,PFet * lambda_5 bloat-or allNOhmic * lambda_3 bloat-or clc/a * lambda_1 or col grow lambda_3 shrink lambda_3 calma 42 1 layer CMS allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_1 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 layer CAA clc grow lambda_1 or em,emc,col or allActive or allHVDiff or allCCDiff labels ndiff,pdiff calma 43 1 /* use CX layer to distinguish "col" and "nsd" */ layer CX col,clc grow lambda_1 calma 60 1 layer CVA pad shrink pad_via calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 layer CEL allPoly2 calma 56 1 layer CCE capc,ec squares lambda_2 calma 55 1 /* NOTE: no calma layer spec. for CCC, contact will NOT in stream file */ layer CCC gc calma 63 1 /* contacts for pdc/nsc (ndc/psc) must be generated separately */ layer CCA ndc,pdc,BiCut,nbdc squares lambda_2 calma 48 1 layer CCA nsc,psc squares lambda_2 calma 48 1 layer CCP pc squares lambda_2 calma 47 1 layer CBA emc,emit grow lambda_4 bloat-or pbc * lambda_1 or pbase calma 58 1 /* temp CIF layer for select generation */ templayer XTN clc grow lambda_1 or em,emc,col grow lambda_2 bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or nbd,nbdc,ndop,wcap * lambda_2 templayer XTP pbc grow lambda_1 bloat-or allPDiff * lambda_2 allNOhmic 0 layer CSN clc grow lambda_1 or emc,emit,col grow lambda_2 bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff 0 bloat-or nbd,nbdc,ndop,wcap * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP calma 45 1 layer CSP pbc grow lambda_1 bloat-or allPDiff * lambda_2 allNOhmic 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff 0 bloat-or pdop * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTN and-not CSN calma 44 1 layer CCD allCCDiff grow lambda_2 calma 57 1 layer COG pad shrink pad_glass or glass labels pad calma 52 1 layer XP pad shrink pad_glass #undef cif_tech magic-8.0.210/scmos/cif_template/cifout-cmos14b-sub.gen0000644000175000001440000000663310751423606021267 0ustar timusers/* For HP CMOS14B process... No CCD, Bipolar, Poly2 layers. */ /* This is prelimanary, please let me know if anything here seems abnormal to you... pi@lepton.isi.edu 3/02/95 */ style lambda=lambda_v scalefactor lambda_1 scaleunit layer CWN nwell bloat-or allPDiff,PFet * lambda_6 bloat-or allNOhmic * lambda_3 grow lambda_3 shrink lambda_3 calma 42 1 layer CWP pwell bloat-or allNDiff,NFet * lambda_6 pdop 0 bloat-or allPOhmic * lambda_3 ndop 0 grow lambda_3 shrink lambda_3 calma 41 1 layer CMT allMetal3,pad labels m3 calma 62 1 layer CMS pad grow lambda_2 or allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_4 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 layer CAA allActive or ndop,pdop #ifdef OPEN or open,pstop #endif labels ndiff,pdiff calma 43 1 layer CVS pad shrink pad_via2 #ifdef OPEN or open #endif calma 61 1 layer CVS m3c squares lambda_1 lambda_2 lambda_3 calma 61 1 layer CVA pad shrink pad_via1 #ifdef OPEN or open #endif calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 /* Generic contact to (active,poly)... NOTE: no calma layer spec. for CCC, contact will not in stream file */ layer CCC gc calma 48 1 /* contacts for pdc/nsc (ndc/psc) must be generated separately */ layer CCA ndc,pdc squares lambda_1 lambda_2 lambda_3 #ifdef OPEN or open #endif calma 48 1 layer CCA nsc,psc squares lambda_1 lambda_2 lambda_3 calma 48 1 layer CCP pc squares lambda_1 lambda_2 lambda_3 calma 47 1 /* temp CIF layer - All diffusion N-Select layers */ templayer XTN bloat-or allNDiff,ndop * lambda_2 allPOhmic,allPDiff,pdop 0 bloat-or nbd,nbdc * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half /* temp CIF layer - All diffusion P-Select layers */ templayer XTP bloat-or allPDiff,pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half layer CSN bloat-or allNDiff * lambda_2 allPOhmic,pdop 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff,pdop 0 bloat-or ndop * lambda_2 allPOhmic,allPDiff,pdop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP calma 45 1 layer CSP bloat-or allPDiff * lambda_2 allNOhmic,ndop 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff,ndop 0 bloat-or pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half #ifdef OPEN bloat-min pstop * lambda_2 open 0 #endif and-not XTN and-not CSN calma 44 1 layer COP open calma 23 1 layer CPS pstop calma 24 1 layer COG pad shrink pad_glass or glass #ifdef OPEN or open #endif labels pad calma 52 1 layer XP pad shrink pad_glass calma 26 1 #undef cif_tech magic-8.0.210/scmos/cif_template/cifin-ami16.gen0000644000175000001440000001073710751423606017744 0ustar timusers/* available devices: * nfet,pfet,enfet,epfet,nffet,pffet * poly capacitor * bipolar NPN transistor * micro-machined devices */ #define cif_tech gen style lambda=lambda_v scalefactor lambda_1 layer nwell CWN labels CWN layer pwell CWP labels CWP layer hnwell CVN labels CWN layer hpwell CVP labels CWP layer poly CPG labels CPG layer pdiff CSP and CAA and CWN layer ndiff CSN and CAA and CWP and-not CCD layer nsd CWN and CSN and CAA layer psd CWP and CSP and CAA layer hpdiff CSP and CAA and CVN layer hndiff CSN and CAA and CVP layer hnsd CVN and CSN and CAA layer hpsd CVP and CSP and CAA layer pbase CBA labels CBA layer nfet CPG and CAA and CSN and CWP and-not CCD layer pfet CAA and CPG and CSP and CWN layer hnfet CPG and CAA and CSN and CVP and-not CCD layer hpfet CAA and CPG and CSP and CVN layer enfet CEL and CAA and CSN and CWP and-not CCD layer epfet CAA and CEL and CSP and CWN layer nffet CEL and CAA and CSN and CPG and CWP and-not CCD layer pffet CAA and CPG and CEL and CSP and CWN layer ndc CCA grow lambda_1 and CAA and CWP and CSN and CMF layer pdc CCA grow lambda_1 and CAA and CWN and CSP and CMF layer nsc CCA grow lambda_1 and CAA and CSN and CWN and CMF layer psc CCA grow lambda_1 and CAA and CSP and CWP and CMF layer hndc CCA grow lambda_2 and CAA and CVP and CSN and CMF layer hpdc CCA grow lambda_2 and CAA and CVN and CSP and CMF layer hnsc CCA grow lambda_2 and CAA and CSN and CVN and CMF layer hpsc CCA grow lambda_2 and CAA and CSP and CVP and CMF layer gc CCC layer m2c CVA grow lambda_1 and CMS and CMF labels CMS layer electrode CEL labels CEL layer ec CCE grow lambda_1 and CMF and CEL labels CMF layer cc CCE grow lambda_1 and CMF and CEL and CPG labels CMF layer cap CPG and CEL and-not CAA labels CEL layer pbc CCA grow lambda_1 and CBA and CMF labels CBA layer col CBA grow 1600 and-not CBA and CX and CAA and CSN and CWN labels CAA layer clc CBA grow 1600 and-not CBA and CCA grow lambda_1 and CX and CAA and CSN and CWN and CMF labels CCA layer emit CBA and CSN shrink lambda_2 labels CBA layer emc CCA grow lambda_1 and CBA and CSN and CMF labels CBA layer pc CCP grow lambda_1 and CPG and CMF layer bd CAA and CCD and-not CSN grow lambda_2 and CAA labels CCD layer nbd CSN shrink lambda_2 and CCD and CAA labels CCD layer nbdc CCA grow lambda_1 and CCD and CSN and CAA labels CCD layer glass COG #ifdef OPEN layer open CAA and CCA and CVA and COG and COP layer pstop CAA and CPS and CSP and-not CWP and-not CWN #endif layer pad CMF shrink lambda_1 and CMS shrink lambda_5 and CVA shrink lambda_1 and COG grow lambda_6 and XP layer m2 CMS labels CMS layer m1 CMF labels CMF calma CVP 21 * calma CVN 22 * #ifdef OPEN calma COP 23 * calma CPS 24 * #endif calma CCC 25 * calma XP 26 * calma CWP 41 * calma CWN 42 * calma CAA 43 * calma CSP 44 * calma CSN 45 * calma CPG 46 * calma CCP 47 * calma CCA 48 * calma CMF 49 * calma CVA 50 * calma CMS 51 * calma COG 52 * calma CCE 55 * calma CEL 56 * calma CCD 57 * calma CBA 58 * calma CX 63 * /* calma CVS 61 * calma CMT 62 * */ #undef cif_tech magic-8.0.210/scmos/cif_template/cifin-cmos14b.gen0000644000175000001440000000503110751423606020266 0ustar timusers/* For IBM triple metal process... No CCD, Bipolar, Poly2 layers. /* This is prelimanary, please let me know if anything here seems abnormal to you... pi@lepton.isi.edu 1/13/94 */ #ifdef NOWELL #undef cif_tech #define cif_tech nowell style lambda=lambda_v #else #undef cif_tech #define cif_tech sub style lambda=lambda_v #endif scalefactor lambda_1 #ifndef NOWELL layer nwell CWN labels CWN layer pwell CWP labels CWP #endif layer m3 CMT /* to avoid a CIF read problem around pads */ and-not XP labels CMT layer m2 CMS labels CMS layer m1 CMF labels CMF layer poly CPG labels CPG layer ndop CSN and-not CWP and CAA layer pdop CSP and CAA and-not CWP and-not CPS layer pdiff CSP and CWN and CAA layer ndiff CSN and CWP and CAA layer nsd CWN and CSN and CAA layer psd CSP and CWP and CAA layer pbase CBA labels CBA layer nfet CPG and CAA and CSN labels CPG layer pfet CAA and CPG and CSP labels CPG layer ndc CCA grow lambda_1 and CAA and CWP and CSN and CMF layer pdc CCA grow lambda_1 and CAA and CWN and CSP and CMF layer nsc CCA grow lambda_1 and CAA and CSN and CWN and CMF layer psc CCA grow lambda_1 and CAA and CSP and CWP and CMF layer pbc CCA grow lambda_1 and CBA and CMF labels CBA layer m3c CVS grow lambda_1 and CMT and CMS and-not XP layer m2c CVA grow lambda_1 and CMS and CMF layer pc CCP grow lambda_1 and CPG and CMF layer gc CCC layer glass COG labels COG #ifdef OPEN layer open CAA and CCA and CVA and COG and COP layer pstop CAA and CPS and CSP and-not CWP and-not CWN #endif /* assume all contact are in place .. */ layer pad COG grow pad_glass and XP #ifdef OPEN calma COP 23 * calma CPS 24 * #endif calma CCC 25 * calma XP 26 * calma CWP 41 * calma CWN 42 * calma CAA 43 * calma CSP 44 * calma CSN 45 * calma CPG 46 * calma CCP 47 * calma CCA 48 * calma CMF 49 * calma CVA 50 * calma CMS 51 * calma COG 52 * calma CVS 61 * calma CMT 62 * magic-8.0.210/scmos/cif_template/cifin-cmos26b.gen0000644000175000001440000000536610751423606020304 0ustar timusers/* For HP CMOS26B process... No CCD, Bipolar, Poly2 layers. Two types of pad layer are supported, one (the pad layer) contains both metal1 and metal2 layer while the other (the pad2 layer) contains all three metals with all necessary via properly defined... */ /* This is prelimanary, please let me know if anything here seems abnormal to you... pi@lepton.isi.edu 3/15/93 */ #ifdef NOWELL #undef cif_tech #define cif_tech nowell style lambda=lambda_v #else #undef cif_tech #define cif_tech sub style lambda=lambda_v #endif scalefactor lambda_1 #ifndef NOWELL layer nwell CWN labels CWN layer pwell CWP labels CWP #endif layer m3 CMT /* to avoid a CIF read problem around pads */ and-not XP labels CMT layer m2 CMS labels CMS layer m1 CMF labels CMF layer poly CPG labels CPG layer ndop CSN and-not CWP and CAA layer pdop CSP and CAA and-not CWP and-not CPS layer pdiff CSP and CWN and CAA layer ndiff CSN and CWP and CAA layer nsd CWN and CSN and CAA layer psd CSP and CWP and CAA layer pbase CBA labels CBA layer nfet CPG and CAA and CSN labels CPG layer pfet CAA and CPG and CSP labels CPG layer ndc CCA grow lambda_1 and CAA and CWP and CSN and CMF layer pdc CCA grow lambda_1 and CAA and CWN and CSP and CMF layer nsc CCA grow lambda_1 and CAA and CSN and CWN and CMF layer psc CCA grow lambda_1 and CAA and CSP and CWP and CMF layer pbc CCA grow lambda_1 and CBA and CMF labels CBA layer m3c CVS grow lambda_1 and CMT and CMS and-not XP layer m2c CVA grow lambda_1 and CMS and CMF layer pc CCP grow lambda_1 and CPG and CMF layer gc CCC layer glass COG labels COG #ifdef OPEN layer open CAA and CCA and CVA and COG and COP layer pstop CAA and CPS and CSP and-not CWP and-not CWN #endif /* assume all contact are in place .. */ layer pad COG grow pad_glass and XP #ifdef OPEN calma COP 23 * calma CPS 24 * #endif calma CCC 25 * calma XP 26 * calma CWP 41 * calma CWN 42 * calma CAA 43 * calma CSP 44 * calma CSN 45 * calma CPG 46 * calma CCP 47 * calma CCA 48 * calma CMF 49 * calma CVA 50 * calma CMS 51 * calma COG 52 * calma CVS 61 * calma CMT 62 * magic-8.0.210/scmos/cif_template/cifin.oldnw0000644000175000001440000000630610751423606017400 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet poly capacitor bipolar NPN transistor buried CCD devices linear capacitor */ #define cif_tech oldnwell style lambda=lambda_v scalefactor lambda_1 layer cwell CWC layer nwell CWN labels CWN layer m3 CMT /* to avoid a CIF read problem around pads */ and-not XP labels CMT layer m2 CMS labels CMS layer m1 CMF labels CMF layer poly CPG labels CPG layer psd CAA layer pdiff CWN and CAA layer ndiff CAA and CSN and-not CCD layer nsd CWN and CSN and CAA layer pbase CBA labels CBA layer nfet CPG and CAA and CSN and-not CCD layer pfet CAA and CPG and CWN layer enfet CEL and CAA and CSN and-not CCD layer epfet CAA and CEL and CWN layer nffet CAA and CEL and CPG and CSN labels CEL layer pffet CAA and CEL and CPG and CWN labels CEL layer m2c CVA grow 150 shrink 50 and CMS and CMF layer electrode CEL labels CEL layer ec CCE grow lambda_1 and CMF and CEL layer cc CCE grow lambda_1 and CMF and CEL and CPG layer cap CPG and CEL and-not CAA labels CEL layer psc CCA grow lambda_1 and CAA and CMF layer ndc CCA grow lambda_1 and CAA and CSN and CMF layer pdc CCA grow lambda_1 and CAA and CWN and CMF layer nsc CCA grow lambda_1 and CAA and CSN and CWN and CMF layer m3c CVS grow lambda_1 and CMT and CMS and-not XP layer gc CCC layer pbc CCA grow lambda_1 and CBA and CMF layer col CX and CAA and CSN and CWN labels CAA layer clc CCA grow lambda_1 and CX and CAA and CSN and CWN and CMF labels CCA layer emit CBA and CSN shrink lambda_2 layer emc CCA grow lambda_1 and CBA and CSN and CMF layer pc CCP grow lambda_1 and CPG and CMF layer nbd CSN shrink lambda_2 and CCD and CAA and-not CPG layer nbdc CCA grow lambda_1 and CCD and CSN and CAA layer bd CPG or CEL and CCD and CAA labels CCD layer glass COG layer pad CMF shrink lambda_1 and CMS shrink lambda_5 and CVA shrink lambda_1 and COG grow lambda_6 and XP calma CWN 42 * calma CAA 43 * /* NO CSP layer for old style of CIF files */ calma CSN 45 * calma CPG 46 * calma CCP 47 * calma CCA 48 * calma CMF 49 * calma CVA 50 * calma CMS 51 * calma COG 52 * calma CCE 55 * calma CEL 56 * calma CCD 57 * calma CBA 58 * calma CWC 59 * calma CX 60 * #undef cif_tech magic-8.0.210/scmos/cif_template/cifin.nw0000644000175000001440000000737010751423606016703 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet poly capacitor bipolar NPN transistor buried CCD devices linear capacitor */ #undef cif_tech #define cif_tech nwell style lambda=lambda_v scalefactor lambda_1 layer nwell CWN labels CWN layer m3 CMT /* to avoid a CIF read problem around pads */ and-not XP labels CMT layer m2 CMS labels CMS layer m1 CMF labels CMF layer poly CPG labels CPG layer psd CAA and CSP and-not CPS layer pdiff CWN and CAA and CSP labels CSP layer ndiff CAA and CSN and-not CCD labels CSN layer nsd CWN and CSN and CAA layer pbase CBA labels CBA layer nfet CPG and CAA and CSN and-not CCD layer pfet CAA and CPG and CSP and CWN layer enfet CEL and CAA and CSN and-not CCD layer epfet CAA and CEL and CSP and CWN layer nffet CAA and CEL and CPG and CSN layer pffet CAA and CEL and CPG and CSP and CWN layer m3c CVS grow lambda_1 and CMT and CMS and-not XP layer m2c CVA grow lambda_1 and CMS and CMF layer electrode CEL labels CEL layer ec CCE or CCC grow lambda_1 and CMF and CEL layer cc CCE grow lambda_1 and CMF and CEL and CPG labels CCE layer cap CPG and CEL and-not CAA layer psc CCA grow lambda_1 and CAA and CSP and CMF layer ndc CCA or CCC grow lambda_1 and CAA and CSN and CMF layer pdc CCA or CCC grow lambda_1 and CAA and CWN and CSP and CMF layer nsc CCA or CCC grow lambda_1 and CAA and CSN and CWN and CMF layer pbc CCA or CCC grow lambda_1 and CBA and CMF layer emit CBA and CSN shrink lambda_2 layer emc CCA grow lambda_1 and CBA and CSN and CMF layer col CX and CAA and CSN and CWN layer clc CCA grow lambda_1 and CX and CAA and CSN and CWN and CMF layer pc CCP or CCC grow lambda_1 and CPG and CMF labels CCP layer nbd CSN shrink lambda_2 and CCD and CAA and-not CPG layer nbdc CCA grow lambda_1 and CCD and CSN and CAA layer bd CPG or CEL and CCD and CAA labels CCD /* place the Cap well at the end, so that we can read linear */ /* capacitor correctly... */ layer cwell CWC labels CWC layer glass COG labels COG #ifdef OPEN layer open CAA and CCA and CVA and COG and COP layer pstop CAA and CPS and CSP and-not CWN #endif layer pad CMF shrink lambda_1 and CMS shrink lambda_5 and CVA shrink lambda_1 and XP and COG grow lambda_6 #ifdef OPEN calma COP 23 * calma CPS 24 * #endif calma XP 26 * calma CWN 42 * calma CAA 43 * calma CSP 44 * calma CSN 45 * calma CPG 46 * calma CCP 47 * calma CCA 48 * calma CMF 49 * calma CVA 50 * calma CMS 51 * calma COG 52 * calma CCE 55 * calma CEL 56 * calma CCD 57 * calma CBA 58 * calma CWC 59 * calma CVS 61 * calma CMT 62 * calma CX 63 * #undef cif_tech magic-8.0.210/scmos/cif_template/cifout.others0000644000175000001440000000310610751423606017755 0ustar timusers/* this style is provided for interface only */ /* usually you should not submit CIF files designed with SCMOS rules */ /* for CBPM 3U runs. The bloating and shrinking will be incorrrect */ style cbpm3u scalefactor 50 25 layer CW pwell bloat-or ndiff,ndc,nfet * 750 bloat-or psc,ppd * 450 grow 450 shrink 450 calma 1 1 layer CQ allMetal2 labels m2 calma 14 1 layer CM pad grow 150 or allMetal1 labels homeMetal1 calma 8 1 layer CP allPoly labels poly,nfet,pfet calma 4 1 layer CD allActive labels ndiff,pdiff calma 3 1 layer CV pad shrink 450 calma 13 1 layer CV m2c squares 150 300 450 calma 13 1 layer CC ndc,pdc,nsc,psc,pc squares 300 calma 7 1 templayer TNF bloat-or nfet ndiff 450 poly 300 layer CS bloat-or pdiff,pfet,pdc/a * 300 nsd,nsc/a 0 bloat-or pfet * 300 pdiff 450 nsd,nsc/a 0 bloat-or psc/a,psd * 300 ndiff,ndc/a,nfet 0 and-not TNF grow 150 shrink 150 calma 5 1 layer CG pad shrink 600 or glass calma 9 1 layer XP pad /* These following technologies are used to generate CIF */ /* used for for DRC batch jobs. Remove comment if you want to */ /* install it... style lambda=1.5(error) scalefactor 150 25 layer CX error_s,error_p,error_ps style lambda=1.0(error) scalefactor 100 50 layer CX error_s,error_p,error_ps style lambda=0.8(error) scalefactor 80 40 layer CX error_s,error_p,error_ps style lambda=0.6(error) scalefactor 60 30 layer CX error_s,error_p,error_ps style lambda=0.5(error) scalefactor 50 25 layer CX error_s,error_p,error_ps */ magic-8.0.210/scmos/cif_template/cifout.test0000644000175000001440000000507510751423606017437 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet poly capacitor bipolar NPN transistor buried CCD devices linear capacitor */ #define cif_tech test style lambda=lambda_v scalefactor lambda_1 scaleunit layer CWC cwell calma 59 1 layer CWN nwell bloat-or pbase,pbc/a * lambda_6 bloat-or allPDiff,PFet * lambda_5 bloat-or allNOhmic * lambda_3 bloat-or clc/a * lambda_1 or col grow lambda_3 shrink lambda_3 calma 42 1 layer CMS allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_1 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 layer CAA clc grow lambda_1 or em,emc,col or allActive or allHVDiff or allCCDiff labels ndiff,pdiff calma 43 1 /* use CX layer to distinguish "col" and "nsd" */ layer CX col,clc grow lambda_1 calma 60 1 layer CVA pad shrink pad_via calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 layer CEL allPoly2 calma 56 1 layer CCE capc,ec squares lambda_2 calma 55 1 /* NOTE: no calma layer spec. for CCC, contact will NOT in stream file */ layer CCC gc calma 63 1 /* contacts for pdc/nsc (ndc/psc) must be generated separately */ layer CCA ndc,pdc,BiCut,nbdc squares 150 200 200 calma 48 1 layer CCA nsc,psc squares 150 200 200 calma 48 1 layer CCP pc squares 150 200 200 calma 47 1 layer CBA emc,emit grow lambda_4 bloat-or pbc * lambda_1 or pbase calma 58 1 /* temp CIF layer for select generation */ templayer XTN clc grow lambda_1 or em,emc,col grow lambda_2 bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or nbd,nbdc,ndop,wcap * lambda_2 templayer XTP pbc grow lambda_1 bloat-or allPDiff * lambda_2 allNOhmic 0 layer CSN clc grow lambda_1 or emc,emit,col grow lambda_2 bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff 0 bloat-or nbd,nbdc,ndop,wcap * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP calma 45 1 layer CSP pbc grow lambda_1 bloat-or allPDiff * lambda_2 allNOhmic 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff 0 bloat-or pdop * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTN and-not CSN calma 44 1 layer CCD allCCDiff grow lambda_2 calma 57 1 layer COG pad shrink pad_glass or glass labels pad calma 52 1 layer XP pad shrink pad_glass #undef cif_tech magic-8.0.210/scmos/cif_template/cifout-orbit.gen0000644000175000001440000000717510751423606020351 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet,hvnfet,hvpfet poly capacitor bipolar NPN transistor buried CCD devices linear capacitor micro-machined devices metal3 and via2 "pad" layer generate *no* metal3 */ #define cif_tech gen style lambda=lambda_v scalefactor lambda_1 scaleunit layer CWC cwell calma 59 1 layer CWN nwell bloat-or pbase,pbc/act * lambda_6 bloat-or allPDiff,PFet * lambda_5 bloat-or allNOhmic * lambda_3 bloat-or clc/a * lambda_1 or col grow lambda_3 shrink lambda_3 calma 42 1 layer CWP pwell bloat-or allNDiff,NFet * lambda_5 bloat-or allPOhmic * lambda_3 and-not CWC shrink lambda_3 grow lambda_3 grow lambda_3 shrink lambda_3 calma 41 1 layer CMS allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_1 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 layer CAA clc grow lambda_1 or em,emc,col,pbase,pbc or allActive or allHVDiff or allCCDiff #ifdef OPEN or open,pstop #endif labels ndiff,pdiff calma 43 1 /* use CX layer to distinguish "col" and "nsd" while CIF input */ layer CX col,clc grow lambda_1 calma 60 1 layer CVA pad shrink pad_via #ifdef OPEN or open #endif calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 layer CEL allPoly2 calma 56 1 layer CCE capc,ec squares lambda_2 calma 55 1 /* NOTE: no calma layer spec. for CCC, contact will not in stream file */ layer CCC gc calma 48 1 /* contacts for pdc/nsc (ndc/psc) must be generated separatelt */ layer CCA ndc,pdc,BiCut,nbdc squares lambda_2 #ifdef OPEN or open #endif calma 48 1 layer CCA nsc,psc squares lambda_2 calma 48 1 layer CCP pc squares lambda_2 calma 47 1 layer CBA emc,emit grow lambda_4 bloat-or pbc * lambda_1 or pbase calma 58 1 /* temp CIF layer for select generation */ templayer XTN clc grow lambda_1 or em,emc,col grow lambda_2 bloat-or allNDiff,ndop * lambda_2 allPOhmic,allPDiff,pdop 0 bloat-or nbd,nbdc,wcap * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half templayer XTP pbc grow lambda_1 bloat-or allPDiff,pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half layer CSN clc grow lambda_1 or em,emc,col grow lambda_2 bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff 0 bloat-or nbd,nbdc,wcap * lambda_2 bloat-or ndop * lambda_2 allPOhmic,allPDiff,pdop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP calma 45 1 layer CSP pbc grow lambda_1 bloat-or allPDiff * lambda_2 allNOhmic 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff 0 bloat-or pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half #ifdef OPEN bloat-min pstop * lambda_2 open 0 #endif and-not XTN and-not CSN calma 44 1 layer CCD allCCDiff grow lambda_2 calma 57 1 layer COP open calma 23 1 layer CPS pstop calma 24 1 layer COG pad shrink pad_glass or glass #ifdef OPEN or open #endif labels pad calma 52 1 layer XP pad shrink pad_glass calma 26 1 render CWN 12 -0.2 0.2 render CAA 2 -0.15 0.15 render CPG 1 0.025 0.05 render CEL 14 0.1 0.05 render CCC 19 0.0 0.2 render CCA 19 0.0 0.2 render CCP 19 0.075 0.125 render CMF 20 0.2 0.05 render CVA 19 0.25 0.05 render CMS 21 0.3 0.05 #undef cif_tech magic-8.0.210/scmos/cif_template/cifout.gen-old0000644000175000001440000000613110751423606017777 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet,hvnfet,hvpfet poly capacitor bipolar NPN transistor buried CCD devices linear capacitor micro-machined devices */ #define cif_tech gen style lambda=lambda_v scalefactor lambda_1 scaleunit layer CWC cwell calma 59 1 layer CWN nwell bloat-or pbase,pbc/act * lambda_6 bloat-or allPDiff,PFet * lambda_5 bloat-or allNOhmic * lambda_3 bloat-or clc/a * lambda_1 or col grow lambda_3 shrink lambda_3 calma 42 1 layer CWP pwell bloat-or allNDiff,NFet * lambda_5 bloat-or allPOhmic * lambda_3 grow lambda_3 shrink lambda_3 calma 41 1 layer CMS allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_1 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 layer CAA clc grow lambda_1 or em,emc,col or allActive or allHVDiff or allCCDiff #ifdef OPEN or open,pstop #endif labels ndiff,pdiff calma 43 1 /* use CX layer to distinguish "col" and "nsd" while CIF input */ layer CX col,clc grow lambda_1 calma 60 1 layer CVA pad shrink pad_via #ifdef OPEN or open #endif calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 layer CEL allPoly2 calma 56 1 layer CCE capc,ec squares lambda_2 calma 55 1 /* NOTE: no calma layer spec. for CCC, contact will not in stream file */ layer CCC gc /* contacts for pdc/nsc (ndc/psc) must be generated separatelt */ layer CCA ndc,pdc,BiCut,nbdc squares lambda_2 #ifdef OPEN or open #endif calma 48 1 layer CCA nsc,psc squares lambda_2 calma 48 1 layer CCP pc squares lambda_2 calma 47 1 layer CBA emc,emit grow lambda_4 bloat-or pbc * lambda_1 or pbase calma 58 1 /* temp CIF layer for select generation */ templayer XTN clc grow lambda_1 or em,emc,col grow lambda_2 bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or nbd,nbdc,ndop,wcap * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half templayer XTP pbc grow lambda_1 bloat-or allPDiff * lambda_2 allNOhmic 0 bloat-or pdop * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half layer CSN clc grow lambda_1 or em,emc,col grow lambda_2 bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff 0 bloat-or nbd,nbdc,wcap * lambda_2 bloat-or ndop * lambda_2 allPOhmic,allPDiff,pdop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP calma 45 1 layer CSP pbc grow lambda_1 bloat-or allPDiff * lambda_2 allNOhmic 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff 0 bloat-or pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half #ifdef OPEN bloat-min pstop * lambda_2 open 0 #endif and-not XTN and-not CSN calma 44 1 layer CCD allCCDiff grow lambda_2 calma 57 1 layer COG pad shrink pad_glass or glass #ifdef OPEN or open #endif labels pad calma 52 1 layer XP pad calma 26 1 #undef cif_tech magic-8.0.210/scmos/cif_template/cifout.pw0000644000175000001440000000543210751423606017103 0ustar timusers/* available devices: nfet,pfet,enfet,epfet,nffet,pffet poly capacitor meatl3 and via2 "pad" layer generate *no* metal3 */ #define cif_tech pwell style lambda=lambda_v scalefactor lambda_1 scaleunit layer CWP pwell bloat-or allNDiff,NFet * lambda_5 bloat-or allPOhmic * lambda_3 grow lambda_3 shrink lambda_3 calma 41 1 layer CMT allMetal3 labels m3 calma 62 1 layer CMS allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_1 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 /* "clc" here for savety reason */ layer CAA clc grow lambda_1 or em,emc,col or allActive or allHVDiff #ifdef OPEN or open,pstop #endif labels ndiff,pdiff calma 43 1 layer CVS pad shrink lambda_2 #ifdef OPEN or open #endif calma 61 1 layer CVS m3c squares lambda_1 lambda_2 lambda_3 calma 61 1 /* use CX layer to distinguish "col" and "nsd" which CIF input */ layer CX col,clc grow lambda_1 calma 60 1 layer CVA pad shrink pad_via #ifdef OPEN or open #endif calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 layer CEL allPoly2 calma 56 1 layer CCE capc,ec squares lambda_2 calma 55 1 /* NOTE: no calma layer spec. for CCC, contact will not in stream file */ layer CCC gc calma 63 1 /* contacts for pdc/nsc (ndc/psc) must be generated separately */ layer CCA ndc,pdc,BiCut squares lambda_2 #ifdef OPEN or open #endif calma 48 1 layer CCA nsc,psc squares lambda_2 calma 48 1 layer CCP pc squares lambda_2 calma 47 1 layer CBA emc,emit grow lambda_4 bloat-or pbc * lambda_1 or pbase calma 58 1 /* temp CIF layer for select generation */ templayer XTN bloat-or allNDiff * lambda_2 allPOhmic 0 templayer XTP bloat-or allPDiff * lambda_2 allNOhmic 0 layer CSP bloat-or allPDiff * lambda_2 allNOhmic 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff 0 bloat-or pdop * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half #ifdef OPEN bloat-min pstop * lambda_2 open 0 #endif and-not XTN calma 44 1 layer CSN bloat-or allNDiff * lambda_2 allPOhmic 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff 0 bloat-or ndop * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP and-not CSP calma 45 1 layer COP open calma 23 1 layer CPS pstop calma 24 1 layer COG pad shrink pad_glass or glass #ifdef OPEN or open #endif labels pad calma 52 1 layer XP pad shrink pad_glass calma 26 1 #undef cif_tech magic-8.0.210/scmos/cif_template/cifin26g.c0000644000175000001440000000075310751423606017016 0ustar timusers /* 0.8 micron technology */ #define lambda_value 40 #include "calc.lambda" #include "cifin-cmos26g.gen" #define NOWELL #include "cifin-cmos26g.gen" #undef NOWELL /* 0.8 micron technology */ #define lambda_value 30 #include "calc.lambda" #include "cifin-cmos14b.gen" #define NOWELL #include "cifin-cmos14b.gen" #undef NOWELL /* 0.8 micron CMOSX technology */ #define lambda_value 40 #include "calc.lambda" #include "cifin-cmosx.gen" #define NOWELL #include "cifin-cmosx.gen" #undef NOWELL magic-8.0.210/scmos/cif_template/cifin-ibm.gen0000644000175000001440000000467310751423606017600 0ustar timusers/* For IBM triple metal process... No CCD, Bipolar, Poly2 layers. /* This is prelimanary, please let me know if anything here seems abnormal to you... pi@lepton.isi.edu 1/13/94 */ #ifdef NOWELL style lambda=0.4(nowell) #else style lambda=0.4(ibm) #endif scalefactor lambda_1 #ifndef NOWELL layer nwell CWN labels CWN #endif layer m3 CMT /* to avoid a CIF read problem around pads */ and-not XP labels CMT layer m2 CMS labels CMS layer m1 CMF labels CMF layer poly CPG labels CPG layer ndop CSN and-not CWP and CAA layer pdop CSP and CAA and-not CWP and-not CPS layer pdiff CSP and CWN and CAA layer ndiff CSN and CWP and CAA layer nsd CWN and CSN and CAA layer psd CSP and CWP and CAA layer pbase CBA labels CBA layer nfet CPG and CAA and CSN labels CPG layer pfet CAA and CPG and CSP labels CPG layer ndc CCA grow 50 and CAA and CWP and CSN and CMF layer pdc CCA grow 50 and CAA and CWN and CSP and CMF layer nsc CCA grow 50 and CAA and CSN and CWN and CMF layer psc CCA grow 50 and CAA and CSP and CWP and CMF layer pbc CCA grow 50 and CBA and CMF labels CBA layer m3c CVS grow 50 and CMT and CMS and-not XP layer m2c CVA grow 50 and CMS and CMF layer pc CCP grow 50 and CPG and CMF layer gc CCC layer glass COG labels COG #ifdef OPEN layer open CAA and CCA and CVA and COG and COP layer pstop CAA and CPS and CSP and-not CWP and-not CWN #endif /* assume all contact are in place .. */ layer pad CMF shrink 100 and CMS shrink 100 and CMT shrink 500 and COG grow 500 and XP #ifdef OPEN calma COP 23 * calma CPS 24 * #endif calma CWP 41 * calma CWN 42 * calma CAA 43 * calma CSP 44 * calma CSN 45 * calma CPG 46 * calma CCP 47 * calma CCA 48 * calma CMF 49 * calma CVA 50 * calma CMS 51 * calma COG 52 * calma CVS 61 * calma CMT 62 * calma CCC 63 * magic-8.0.210/scmos/cif_template/cifout-cmos26g.gen0000644000175000001440000000653710751423606020513 0ustar timusers style lambda=0.40(sub) scalefactor lambda_1 scaleunit layer CWN nwell bloat-or allPDiff,PFet * lambda_6 bloat-or allNOhmic * lambda_3 grow lambda_3 shrink lambda_3 calma 42 1 layer CWP pwell bloat-or allNDiff,NFet * lambda_6 pdop 0 bloat-or allPOhmic * lambda_3 ndop 0 grow lambda_3 shrink lambda_3 calma 41 1 layer CMT allMetal3,pad labels m3 calma 62 1 layer CMS pad grow lambda_2 or allMetal2 labels m2 calma 51 1 layer CMF pad grow lambda_4 or allMetal1 labels homeMetal1 calma 49 1 layer CPG cap,cc or allPoly labels poly,nfet,pfet calma 46 1 layer CAA allActive or ndop,pdop #ifdef OPEN or open,pstop #endif labels ndiff,pdiff calma 43 1 layer CVS pad shrink pad_via2 or open calma 61 1 layer CVS m3c squares lambda_1 lambda_2 lambda_3 calma 61 1 layer CVA pad shrink pad_via1 #ifdef OPEN or open #endif calma 50 1 layer CVA m2c squares lambda_1 lambda_2 lambda_3 calma 50 1 /* Generic contact to (active,poly)... NOTE: no calma layer spec. for CCC, contact will not in stream file */ layer CCC gc calma 48 1 /* A contact under the pad is required by HP rule.... numbers here */ /* are fixed */ layer CCA pad shrink 400 calma 48 1 /* contacts for pdc/nsc (ndc/psc) must be generated separately */ layer CCA ndc,pdc squares lambda_1 lambda_2 lambda_3 #ifdef OPEN or open #endif calma 48 1 layer CCA nsc,psc squares lambda_1 lambda_2 lambda_3 calma 48 1 layer CCP pc squares lambda_1 lambda_2 lambda_3 calma 47 1 /* temp CIF layer - All diffusion N-Select layers */ templayer XTN bloat-or allNDiff,ndop * lambda_2 allPOhmic,allPDiff,pdop 0 bloat-or nbd,nbdc * lambda_2 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half /* temp CIF layer - All diffusion P-Select layers */ templayer XTP bloat-or allPDiff,pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half layer CSN bloat-or allNDiff * lambda_2 allPOhmic,pdop 0 bloat-or NFet * lambda_2 ndiff lambda_3 allPOhmic 0 bloat-or allNOhmic * lambda_2 allPDiff,pdop 0 bloat-or ndop * lambda_2 allPOhmic,allPDiff,pdop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half and-not XTP calma 45 1 layer CSP bloat-or allPDiff * lambda_2 allNOhmic,ndop 0 bloat-or PFet * lambda_2 pdiff lambda_3 allNOhmic 0 bloat-or allPOhmic * lambda_2 allNDiff,ndop 0 bloat-or pdop * lambda_2 allNOhmic,allNDiff,ndop 0 grow lambda_1 shrink lambda_1 shrink lambda_half grow lambda_half #ifdef OPEN bloat-min pstop * lambda_2 open 0 #endif and-not XTN and-not CSN calma 44 1 layer COP open calma 23 1 layer CPS pstop calma 24 1 layer COG pad shrink pad_glass or glass #ifdef OPEN or open #endif labels pad calma 52 1 layer XP pad shrink pad_glass calma 26 1 #undef cif_tech magic-8.0.210/scmos/cif_template/cifin-hp.nw0000644000175000001440000000307610751423606017307 0ustar timusers/* available devices: nfet,pfet */ #define cif_tech hp style lambda=lambda_v scalefactor lambda_1 layer nwell CWN labels CWN layer m3 CMT labels CMT layer m2 CMS labels CMS layer m1 CMF labels CMF layer poly CPG labels CPG layer psd CSP and-not CWN layer pdiff CWN and CSP labels CSP layer ndiff CSN and-not CWN labels CSN layer nsd CWN and CSN layer nfet CPG and CSN and-not CWN layer pfet CPG and CSP and CWN layer m3c CVS grow lambda_1 and CMT and CMS layer m2c CVA grow lambda_1 and CMS and CMF layer psc CCA grow lambda_1 and-not CWN and CSP and CMF layer ndc CCA grow lambda_1 and-not CWN and CSN and CMF layer pdc CCA grow lambda_1 and CAA and CWN and CSP and CMF layer nsc CCA grow lambda_1 and CSN and CWN and CMF layer pc CCA grow lambda_1 and CPG and CMF labels CPG layer glass COG labels COG layer pad CMF shrink lambda_1 and CMS shrink lambda_5 and CVA shrink lambda_1 and COG grow lambda_6 calma CWN 1 * calma CPG 4 * calma CCA 8 * calma CMF 9 * calma CVA 10 * calma CMS 11 * calma CVS 12 * calma CMT 13 * calma COG 14 * calma CSN 21 * calma CSP 22 * #undef cif_tech magic-8.0.210/scmos/extract_template/0000755000175000001440000000000011504623577016155 5ustar timusersmagic-8.0.210/scmos/extract_template/scmosExt26b-sub.tech.in0000644000175000001440000001070510751423606022332 0ustar timusers/* This is for HP's CMOS26B 0.8 micron CMOS Bulk Process. Just a scale of the other file */ #ifdef extForSpice style lambda=0.4 #else style lambda_irsim=0.4 #endif lambda 40 step 100 sidehalo 8 /* 2 more than min m3 spacing */ #ifdef INCLUDE_FET_CAP /* Normally off since neither spice or irsim need it */ areacap allFet 692 /* af/lambda^2 */ #endif /* ------------ diff capacitances ---------------- */ areacap nwell 26 perimc nwell ~(nwell) 80 #ifdef extForSpice areacap (ndiff,nsd,ndc,nsc)/a 0 perimc (ndiff,nsd,ndc,nsc)/a space,pwell 0 areacap (pdiff,psd,pdc,psc)/a 0 perimc (pdiff,psd,pdc,psc)/a space,nwell 0 #else /* Real perim values increased a little to compensate for not counting CJGATE */ areacap (ndiff,nsd,ndc,nsc)/a 26 perimc (ndiff,nsd,ndc,nsc)/a space,pwell 240 areacap (pdiff,psd,pdc,psc)/a 136 perimc (pdiff,psd,pdc,psc)/a space,nwell 160 #endif /* ------------------------------------------------------ */ /* ------------ poly capacitances ---------------- */ areacap PolyCap 10 overlap PolyCap allWell 10 perimc PolyCap ~PolyCap 18 sideOverlap(PolyCap, ~PolyCap, allWell, 18, nothing) sideOverlap(PolyCap, ~PolyCap, M1Cap, 8, nothing) sideOverlap(PolyCap, ~PolyCap, M2Cap, 5, M1Cap) sideOverlap(PolyCap, ~PolyCap, M3Cap, 3, (M1Cap,M2Cap)) sidewall PolyCap ~PolyCap ~PolyCap PolyCap 9 /* ------------------------------------------------- */ /* ------------ metal1 capacitances ---------------- */ areacap M1Cap 6 overlap M1Cap allWell 6 PolyCap,PNplusCap overlap M1Cap PNplusCap 9 overlap M1Cap PolyCap 9 perimc M1Cap ~M1Cap 18 sideOverlap(M1Cap, ~M1Cap, allWell, 18, (PolyCap,PNplusCap)) sideOverlap(M1Cap, ~M1Cap, PNplusCap, 20, nothing) sideOverlap(M1Cap, ~M1Cap, PolyCap, 20, nothing) sideOverlap(M1Cap, ~M1Cap, M2Cap, 10, nothing) sideOverlap(M1Cap, ~M1Cap, M3Cap, 6, M2Cap) sidewall M1Cap ~M1Cap ~M1Cap M1Cap 22 /* ------------------------------------------------- */ /* ------------ metal2 capacitances ---------------- */ areacap M2Cap 2.5 overlap M2Cap allWell 2.5 PolyCap,M1Cap,PNplusCap overlap M2Cap PNplusCap 3 M1Cap overlap M2Cap PolyCap 4 M1Cap overlap M2Cap M1Cap 6 perimc M2Cap ~M2Cap 15 sideOverlap(M2Cap, ~M2Cap, allWell, 15, (M1Cap,PolyCap,PNplusCap) ) sideOverlap(M2Cap, ~M2Cap, PNplusCap, 16, M1Cap) sideOverlap(M2Cap, ~M2Cap, PolyCap, 16, M1Cap) sideOverlap(M2Cap, ~M2Cap, M1Cap, 18, nothing) sideOverlap(M2Cap, ~M2Cap, M3Cap, 8, nothing) sidewall M2Cap ~M2Cap ~M2Cap M2Cap 26 /* ------------------------------------------------- */ /* ------------ metal3 capacitances ---------------- */ areacap M3Cap 2 overlap M3Cap allWell 2 PolyCap,M1Cap,M2Cap,PNplusCap overlap M3Cap PNplusCap 2 M1Cap,M2Cap overlap M3Cap PolyCap 2 M1Cap,M2Cap overlap M3Cap M1Cap 3 M2Cap overlap M3Cap M2Cap 6 perimc M3Cap ~M3Cap 14 sideOverlap(M3Cap, ~M3Cap, allWell, 14, (PNplusCap,PolyCap,M1Cap,M2Cap)) sideOverlap(M3Cap, ~M3Cap, PNplusCap, 14, (M1Cap,M2Cap)) sideOverlap(M3Cap, ~M3Cap, PolyCap, 14, (M1Cap,M2Cap)) sideOverlap(M3Cap, ~M3Cap, M1Cap, 16, (M2Cap)) sideOverlap(M3Cap, ~M3Cap, M2Cap, 20, nothing) sidewall M3Cap ~M3Cap ~M3Cap M3Cap 40 /* ------------------------------------------------- */ /* -------------- Fets -----------------------------*/ /* cscab, cscap defined since extresis needs them */ fet pfet pdiff,pdc 2 pfet Vdd! nwell 204 450 fet nfet ndiff,ndc 2 nfet Gnd! pwell 150 450 /* These values are the equivalent resistance that irsim params for 3.3 V 125C though. Probably we want to make that 5V, 27C !!!! */ fetresis nfet linear 14100 /* resistance dyn L */ fetresis pfet linear 48100 /* resistance dyn H */ fetresis nfet saturation 14100 /* resistance dyn L */ fetresis pfet saturation 48100 /* resistance dyn H */ /* ------------------------------------------------- */ /* -------------- Resistivity (in milliohms per sq) -------*/ /* ---- assumed temp 85 C ----- */ resist NDRes 3800 resist PDRes 3800 resist PolyRes 5000 resist M1Res 81 resist M2Res 81 resist M3Res 34 resist nwell 1980000 contact pc 4 15000 contact ndc,pdc,nsc,psc 4 1500 contact m2c 4 500 contact m3c 4 500 /* ------------------------------------------------- */ /* Order the planes for correct shielding */ planeOrder(implant,0) planeOrder(well,1) planeOrder(active,2) planeOrder(metal1,3) planeOrder(metal2,4) planeOrder(metal3,5) planeOrder(oxide,6) magic-8.0.210/scmos/extract_template/scmosExt34.tech.in0000644000175000001440000000662410751423606021405 0ustar timusers/* This is for HP's CMOS34 1.2 micron CMOS Bulk Process. Again some parameters are defined by GPP others by Ersatzco and others are computed. */ #ifdef extForSpice style lambda=0.6(hp) #else style lambda_irsim=0.6(hp) #endif lambda 60 step 100 sidehalo 6 /* 2 more than min m2 spacing */ #ifdef INCLUDE_FET_CAP areacap allFet 433 #endif /* ------------ diff capacitances ---------------- */ areacap nwell 35 perimc nwell ~(nwell) 47 #ifdef extForSpice areacap ndiff,nsd,ndc/a,nsc/a 0 areacap pdiff,psd,pdc/a,psc/a 0 perimc ndiff,nsd,ndc/a,nsc/a space,pwell 0 perimc pdiff,psd,pdc/a,psc/a space,nwell 0 #else areacap ndiff,nsd,ndc/a,nsc/a 116 areacap pdiff,psd,pdc/a,psc/a 187 /* Real values increased to compensate for not counting CJGATE */ perimc ndiff,nsd,ndc/a,nsc/a space,pwell 176 /* 156 */ perimc pdiff,psd,pdc/a,psc/a space,nwell 162 /* 132 */ #endif /* ------------------------------------------------- */ /* ------------ poly capacitances ---------------- */ areacap PolyCap 28 overlap PolyCap allWell 28 perimc PolyCap ~PolyCap 38 sideOverlap(PolyCap, ~PolyCap, allWell, 38, nothing) sideOverlap(PolyCap, ~PolyCap, M1Cap, 34, nothing) sideOverlap(PolyCap, ~PolyCap, M2Cap, 27, M1Cap) sidewall PolyCap ~PolyCap ~PolyCap PolyCap 15 /* ------------------------------------------------- */ /* ------------ metal1 capacitances ---------------- */ areacap M1Cap 18 overlap M1Cap allWell 18 PolyCap,PNplusCap overlap M1Cap PNplusCap 46 overlap M1Cap PolyCap 46 perimc M1Cap ~M1Cap 33 sideOverlap(M1Cap, ~M1Cap, allWell, 33, (PolyCap,PNplusCap)) sideOverlap(M1Cap, ~M1Cap, PNplusCap, 33, nothing) sideOverlap(M1Cap, ~M1Cap, PolyCap, 33, nothing) sideOverlap(M1Cap, ~M1Cap, M2Cap, 28, nothing) sidewall M1Cap ~M1Cap ~M1Cap M1Cap 27 /* ------------------------------------------------- */ /* ------------ metal2 capacitances ---------------- */ areacap M2Cap 9 overlap M2Cap allWell 9 PolyCap,M1Cap,PNplusCap overlap M2Cap PNplusCap 12 M1Cap overlap M2Cap PolyCap 14 M1Cap overlap M2Cap M1Cap 30 perimc M2Cap ~M2Cap 22 sideOverlap(M2Cap, ~M2Cap, allWell, 22, (M1Cap,PolyCap,PNplusCap) ) sideOverlap(M2Cap, ~M2Cap, PNplusCap, 20, M1Cap) sideOverlap(M2Cap, ~M2Cap, PolyCap, 22, M1Cap) sideOverlap(M2Cap, ~M2Cap, M1Cap, 28, nothing) sidewall M2Cap ~M2Cap ~M2Cap M2Cap 33 /* ------------------------------------------------- */ /* -------------- Fets -----------------------------*/ /* cscab, cscap defined since extresis needs them */ fet pfet pdiff,pdc 2 pfet Vdd! nwell 270 623 fet nfet ndiff,ndc 2 nfet Gnd! pwell 90 623 fet wcap ndiff,ndc 1 wcap Gnd! pwell 300 0 /* From irsim */ fetresis nfet linear 9700 fetresis pfet linear 35700 /* ------------------------------------------------- */ /* -------------- Resistivity (in milliohms per sq) -------*/ contact pc 4 16210 contact ndc,nsc, 4 77000 contact pdc,psc, 4 44260 contact m2c 4 150 resist ndiff,nsd,ndc/a,nsc/a 99630 resist pdiff,psd,pdc/a,psc/a 120000 resist PolyRes 25000 resist M1Res 60 resist M2Res 40 resist nwell 1500000 /* ------------------------------------------------- */ /* Order the planes for correct shielding */ planeOrder(implant,0) planeOrder(well,1) planeOrder(active,2) planeOrder(metal1,3) planeOrder(metal2,4) planeOrder(metal3,5) planeOrder(oxide,6) magic-8.0.210/scmos/extract_template/scmosExt100.tech.in0000644000175000001440000001532210751423606021452 0ustar timusers/* This is for lambda=1.0um - ie orbit's 2 um technologies. Needs some more work for parallel coupling capacitances and upwards fringe. */ #ifdef extForSpice style lambda=1.0(scna20_orb) #else style lambda_irsim=1.0(scna20_orb) #endif cscale 1 lambda 100 step 100 sidehalo 0 /* no parallel coupling cap */ #ifdef INCLUDE_FET_CAP /* Normally off since neither spice or irsim need it */ areacap allFet 750 /* af/lambda^2 */ #endif #ifdef extForSpice areacap (ndiff,nsd,ndc,nsc)/a 0 perimc (ndiff,nsd,ndc,nsc)/a space,pwell 0 areacap (pdiff,psd,pdc,psc)/a 0 perimc (pdiff,psd,pdc,psc)/a space,nwell 0 #else areacap (ndiff,nsd,ndc,nsc)/a 398 perimc (ndiff,nsd,ndc,nsc)/a space,pwell 423 areacap (pdiff,psd,pdc,psc)/a 230 perimc (pdiff,psd,pdc,psc)/a space,nwell 85 #endif /* ------------------------------------------------------ */ /* ------------ poly capacitances ---------------- */ areacap PolyCap 39 areacap cc/a,cap 39 overlap PolyCap allWell 39 areacap poly2,ec/a 50 perimc PolyCap ~PolyCap 80 sideOverlap(PolyCap, ~PolyCap, allWell, 80, nothing) /* ------------------------------------------------- */ /* NO fringe data avaliable */ /* ------------ metal1 capacitances ---------------- */ areacap M1Cap 47 overlap M1Cap allWell 47 PolyCap,PNplusCap overlap M1Cap PNplusCap 47 overlap M1Cap PolyCap 30 overlap M1Cap poly2,cap 40 /* ------------------------------------------------- */ /* ------------ metal2 capacitances ---------------- */ areacap M2Cap 19 overlap M2Cap allWell 19 PolyCap,M1Cap,PNplusCap overlap M2Cap PNplusCap 22 M1Cap overlap M2Cap PolyCap 19 M1Cap overlap M2Cap poly2 40 M1Cap overlap M2Cap M1Cap 45 /* ------------------------------------------------- */ /* -------------- MOSFet Devices -------------------------------*/ /* syntax: device mosfet */ /* */ /* gscap, gccap defined since extresis needs them */ device mosfet pfet pfet pdiff,pdc nwell Vdd! 204 450 device mosfet nfet nfet ndiff,ndc pwell Gnd! 150 450 device mosfet epfet epfet pdiff,pdc nwell Vdd! 204 450 device mosfet enfet enfet ndiff,ndc pwell Gnd! 150 450 /* -------------------- Poly-Poly2 Caps ------------------------*/ /* syntax: device capacitor */ /* */ device capacitor None cap,capc/a poly,pc 120 745 /* ---------- NPN Vertical Bipolar Devices -------------*/ /* syntax: device bjt */ device bjt npn pbase,pbc/a emit,emc/a nwell fetresis nfet linear 14100 /* resistance dyn L */ fetresis pfet linear 48100 /* resistance dyn H */ fetresis nfet saturation 14100 /* resistance dyn L */ fetresis pfet saturation 48100 /* resistance dyn H */ fetresis enfet linear 14100 /* resistance dyn L */ fetresis epfet linear 48100 /* resistance dyn H */ fetresis enfet saturation 14100 /* resistance dyn L */ fetresis epfet saturation 48100 /* resistance dyn H */ /* ------------------------------------------------- */ /* -------------- Resistivity (in milliohms per sq) -------*/ /* ---- assumed temp 85 C ----- */ resist NDRes 26670 resist PDRes 59550 resist PolyRes 23860 resist allPoly2 19690 resist em,emc/a 27260 resist pbase,pbc/a 2000000 resist M1Res 49 resist M2Res 26 resist nwell 2505830 contact pc 4 11000 contact ec/a,capc/a 4 9000 contact ndc,pdc,nsc,psc 4 18710 contact pdc/a,psc/a 4 100560 contact m2c 4 30 /* ------------------------------------------------- */ /* Order the planes for correct shielding */ planeOrder(implant,0) planeOrder(well,1) planeOrder(active,2) planeOrder(metal1,3) planeOrder(metal2,4) planeOrder(metal3,5) planeOrder(oxide,6) /* Layer widths and thicknesses for inductance extraction */ /* and 3D rendering */ height nwell -0.1 0.1 height ndiff,pdiff,nndiff,ppdiff -0.075 0.075 height poly,pfet,nfet 0.1 0.05 height ndc,pdc,nsc,psc 0.001 0.25 height pc 0.1 0.15 height m1 0.2 0.05 height m2c 0.2 0.15 height m2 0.3 0.05 #ifdef extForSpice style lambdaSp=1.0(scpe20_orb) #else style lambda=1.0(scpe20_orb) #endif lambda 100 step 100 sidehalo 0 /* no parallel coupling cap */ #ifdef INCLUDE_FET_CAP /* Normally off since neither spice or irsim need it */ areacap allFet 750 /* af/lambda^2 */ #endif #ifdef extForSpice areacap (ndiff,nsd,ndc,nsc)/a 0 perimc (ndiff,nsd,ndc,nsc)/a space,pwell 0 areacap (pdiff,psd,pdc,psc)/a 0 perimc (pdiff,psd,pdc,psc)/a space,nwell 0 #else areacap (ndiff,nsd,ndc,nsc)/a 398 perimc (ndiff,nsd,ndc,nsc)/a space,pwell 423 areacap (pdiff,psd,pdc,psc)/a 230 perimc (pdiff,psd,pdc,psc)/a space,nwell 85 #endif /* ------------------------------------------------------ */ /* ------------ poly capacitances ---------------- */ areacap PolyCap 57 overlap PolyCap allWell 57 perimc PolyCap ~PolyCap 168 sideOverlap(PolyCap, ~PolyCap, allWell, 168, nothing) /* ------------------------------------------------- */ /* NO fringe data avaliable */ /* ------------ metal1 capacitances ---------------- */ areacap M1Cap 41 overlap M1Cap allWell 41 PolyCap,PNplusCap overlap M1Cap PNplusCap 41 overlap M1Cap PolyCap 33 overlap M1Cap poly2,cap 45 /* ------------------------------------------------- */ /* ------------ metal2 capacitances ---------------- */ areacap M2Cap 21 overlap M2Cap allWell 21 PolyCap,M1Cap,PNplusCap overlap M2Cap PNplusCap 21 M1Cap overlap M2Cap PolyCap 25 M1Cap overlap M2Cap M1Cap 33 /* ------------------------------------------------- */ /* -------------- Fets -----------------------------*/ /* gscap, gccap defined since extresis needs them */ fet pfet pdiff,pdc 2 pfet Vdd! nwell 204 450 fet nfet ndiff,ndc 2 nfet Gnd! pwell 150 450 fetresis nfet linear 14100 /* resistance dyn L */ fetresis pfet linear 48100 /* resistance dyn H */ fetresis nfet saturation 14100 /* resistance dyn L */ fetresis pfet saturation 48100 /* resistance dyn H */ /* ------------------------------------------------- */ /* -------------- Resistivity (in milliohms per sq) -------*/ /* ---- assumed temp 85 C ----- */ resist NDRes 26670 resist PDRes 72860 resist PolyRes 23860 resist allPoly2 18540 resist M1Res 49 resist M2Res 26 resist pwell 2128280 contact pc 4 12800 contact ec/a,capc/a 4 8420 contact (ndc,nsc)/a 4 36660 contact (psc,pdc)/a 4 56300 contact m2c 4 30 /* ------------------------------------------------- */ /* Order the planes for correct shielding */ planeOrder(implant,0) planeOrder(well,1) planeOrder(active,2) planeOrder(metal1,3) planeOrder(metal2,4) planeOrder(metal3,5) planeOrder(oxide,6) magic-8.0.210/scmos/extract_template/scmosExt080.tech.in0000644000175000001440000000545110751423606021463 0ustar timusers/* This is for lambda=0.8um - ie orbit's 2 um technologies. Needs some more work for parallel coupling capacitances and upwards fringe. */ #ifdef extForSpice style lambda=0.8(scna16_ami) #else style lambda_irsim=0.8(scna16_ami) #endif cscale 1 lambda 80 step 100 sidehalo 0 /* no parallel coupling cap */ #ifdef INCLUDE_FET_CAP /* Normally off since neither spice or irsim need it */ areacap allFet 750 /* af/lambda^2 */ #endif #ifdef extForSpice areacap (ndiff,nsd,ndc,nsc)/a 0 perimc (ndiff,nsd,ndc,nsc)/a space,pwell 0 areacap (pdiff,psd,pdc,psc)/a 0 perimc (pdiff,psd,pdc,psc)/a space,nwell 0 #else areacap (ndiff,nsd,ndc,nsc)/a 172 perimc (ndiff,nsd,ndc,nsc)/a space,pwell 60 areacap (pdiff,psd,pdc,psc)/a 200 perimc (pdiff,psd,pdc,psc)/a space,nwell 68 #endif /* ------------------------------------------------------ */ /* ------------ poly capacitances ---------------- */ areacap PolyCap 22 overlap PolyCap allWell 22 /* ------------------------------------------------- */ /* NO fringe data avaliable */ /* ------------ metal1 capacitances ---------------- */ areacap M1Cap 20 overlap M1Cap allWell 20 PolyCap,PNplusCap overlap M1Cap PNplusCap 20 overlap M1Cap PolyCap 25 /* ------------------------------------------------- */ /* ------------ metal2 capacitances ---------------- */ areacap M2Cap 10 overlap M2Cap allWell 12 PolyCap,M1Cap,PNplusCap overlap M2Cap PNplusCap 12 M1Cap overlap M2Cap PolyCap 11 M1Cap overlap M2Cap M1Cap 23 /* ------------------------------------------------- */ /* -------------- Fets -----------------------------*/ /* cscab, cscap defined since extresis needs them */ fet pfet pdiff,pdc 2 pfet Vdd! nwell 204 450 fet nfet ndiff,ndc 2 nfet Gnd! pwell 150 450 fet epfet pdiff,pdc 2 epfet Vdd! nwell 204 450 fet enfet ndiff,ndc 2 enfet Gnd! pwell 150 450 fetresis nfet linear 14100 /* resistance dyn L */ fetresis pfet linear 48100 /* resistance dyn H */ fetresis nfet saturation 14100 /* resistance dyn L */ fetresis pfet saturation 48100 /* resistance dyn H */ /* ------------------------------------------------- */ /* -------------- Resistivity (in milliohms per sq) -------*/ /* ---- assumed temp 85 C ----- */ resist NDRes 51680 resist PDRes 74800 resist PolyRes 34780 resist allPoly2 22400 resist M1Res 48 resist M2Res 28 resist nwell 1446400 contact pc 4 61560 contact ec/a,capc/a 4 12010 contact ndc,pdc,nsc,psc 4 45780 contact pdc/a,psc/a 4 32310 contact m2c 4 37570 /* ------------------------------------------------- */ /* Order the planes for correct shielding */ planeOrder(implant,0) planeOrder(well,1) planeOrder(active,2) planeOrder(metal1,3) planeOrder(metal2,4) planeOrder(metal3,5) planeOrder(oxide,6) magic-8.0.210/scmos/extract_template/scmosExt.tech.in0000644000175000001440000000521710751423606021233 0ustar timusers/* local definitions */ #define allContM1 ndc/m1,pdc/m1,nwc/m1,pwc/m1 #define PNplusWOC ndiff,pdiff,nnd/a,ppd/a #define CAPP allPoly #define SSEPP ~(allPoly)/act #define SSEP1 ~(allMetal1)/m1 #define SSEP2 ~(allMetal2)/m2 #define SSEP3 ~(allMetal3)/m3 /* Make sure local cap defs don't appear before regardless of what cpp does*/ #if defined(M1ContactsAct) \ || defined (M1Contacts) \ || defined (PNplusCap) \ || defined (PolyCap) \ || defined (M1Cap) \ || defined (M2Cap) \ || defined (M3Cap) \ || defined (M1CapNoDiff) \ || defined (NdRes) \ || defined (PdRes) \ || defined (M1Res) \ || defined (PolyRes) \ || defined (M2Res) \ || defined (M3Res) \ || defined (nothing) THERE_IS_AN_ERROR_SOME_LOCAL_CAPACITANCE_DEFINITIONS_HAVE_ALREADY_BEEN_DEFINED #endif /* Local capacitance definitions */ #define M1ContactsAct ndc,pdc,nwc,pwc,nbdc,capc,ec,clc,emc,pbc #define M1Contacts M1ContactsAct,pc,via #define PNplusCap (ndiff,pdiff,em,col,ppd,nnd,M1ContactsAct)/a #define PolyCap (poly,pc)/a #define M1Cap (m1,M1Contacts)/m1 #define M2Cap (m2,m2c,m3c,pad)/m2 #define M3Cap (m3,m3c,pad)/m3 #define M1CapNoDiff (m1,pc,via)/m1 #define NDRes (ndiff,nsd,ndc/act,nsc/act) #define PDRes (pdiff,psd,pdc/act,psc/act) #define PolyRes (poly,pc/act,pfet,nfet) #define M1Res (metal1,m2c/metal1) #define M2Res (metal2,via/m2,pad) #define M3Res (metal3,pad/m3,via2/m3) #define nothing /* Use macros for planeorder and sideoverlap for backwards compatibility */ #if defined(V5) #define planeOrder(l,ord) planeorder l ord #define noplaneOrdering noplaneordering #define sideOverlap(l1,sep,l2,cap,shield)\ sideoverlap l1 sep l2 cap shield #else /* V5 */ #define planeOrder(l,ord) #define noplaneOrdering #define sideOverlap(l1,sep,l2,cap,shield)\ sideoverlap l1 sep l2 cap #endif /* V5 */ #define extForSpice /* If you are using irsim-9.3 or older then you need to re-include all the files without defining extForSpice so that the junction capacitances will be extracted from magic instead of being calculated from irsim-9.4 based on the values in the prm file and the s/d attributes produced from magic-6.5 */ #if defined(STANDARD) /* include ORBIT 2um, AMI 1.6um, HP1.2, and HP1.0/0.8 */ #include "scmosExt100.tech.in" #include "scmosExt080.tech.in" #include "scmosExt060_orb.tech.in" #include "scmosExt34.tech.in" #include "scmosExt26b.tech.in" #endif /* STANDARD */ #if defined(TIGHTMETAL) #include "scmosExt34.tech.in" #include "scmosExt26b.tech.in" #include "scmosExt14b-tm.tech.in" #endif #if defined(SUBMICRON) #include "scmosExt26b-sub.tech.in" #include "scmosExt14b-sub.tech.in" #endif #include "scmosExtDiag.tech.in" magic-8.0.210/scmos/extract_template/scmosExtDiag.tech.in0000644000175000001440000000235710751423606022022 0ustar timusers/* DIAGNOSTIC EXTRACTIONS */ /* * The idea here is to simply re-extract caps between nwell and GND * as a test on whether all wells are plugged (with vdd) */ style check_nwell lambda 100 step 100 resist nwell 2000000 areacap nw,nwc,nsd 100 noplaneOrdering /* never do coupling on these styles */ style check_pwell lambda 100 step 100 resist pwell 2000000 areacap pw,pwc,psd 100 noplaneOrdering style check_psubstr /* The idea here is to simply re-extract caps between * p_guard_ring and GND as a test * to verify that the substrate is all contacted to the same ground * signal (i.e. insure the substrate isn't accidentally a big resistor! */ lambda 50 step 200 areacap psd,psc 1000 noplaneOrdering style check_nsubstr /* The idea here is to simply re-extract caps between * n_guard_ring and GND as a test * to verify that the substrate is all contacted to the same Vcc * signal (i.e. insure the substrate isn't accidentally a big resistor! */ lambda 50 step 200 areacap nsd,nsc 1000 noplaneOrdering magic-8.0.210/scmos/extract_template/scmosExt26b.tech.in0000644000175000001440000001140210751423606021536 0ustar timusers/* This is for HP's CMOS26B 1.0 micron CMOS Bulk Process. All parameters are defined based on HP's general process specifications (GPP). Sidewall fringing was taken from Ersatco fictitious process (johnson,jouppi). Upwards fringe caps (eg poly-->m1, poly-->m2) are computed by the program scaleCap by using the Skurai/Tamaru formula based on the known capacitances. */ #ifdef extForSpice style lambda=0.5 #else style lambda_irsim=0.5 #endif lambda 50 step 100 sidehalo 8 /* 2 more than min m3 spacing */ #ifdef INCLUDE_FET_CAP /* Normally off since neither spice or irsim need it */ areacap allFet 692 /* af/lambda^2 */ #endif /* ------------ diff capacitances ---------------- */ areacap nwell 40 perimc nwell ~(nwell) 100 #ifdef extForSpice areacap (ndiff,nsd,ndc,nsc)/a 0 perimc (ndiff,nsd,ndc,nsc)/a space,pwell 0 areacap (pdiff,psd,pdc,psc)/a 0 perimc (pdiff,psd,pdc,psc)/a space,nwell 0 #else /* Real perim values increased a little to compensate for not counting CJGATE */ areacap (ndiff,nsd,ndc,nsc)/a 40 perimc (ndiff,nsd,ndc,nsc)/a space,pwell 300 /* 250 */ areacap (pdiff,psd,pdc,psc)/a 170 perimc (pdiff,psd,pdc,psc)/a space,nwell 200 /* 160 */ #endif /* ------------------------------------------------------ */ /* ------------ poly capacitances ---------------- */ areacap PolyCap 15 overlap PolyCap allWell 15 perimc PolyCap ~PolyCap 22 sideOverlap(PolyCap, ~PolyCap, allWell, 22, nothing) sideOverlap(PolyCap, ~PolyCap, M1Cap, 10, nothing) sideOverlap(PolyCap, ~PolyCap, M2Cap, 6, M1Cap) sideOverlap(PolyCap, ~PolyCap, M3Cap, 4, (M1Cap,M2Cap)) sidewall PolyCap ~PolyCap ~PolyCap PolyCap 11 /* ------------------------------------------------- */ /* ------------ metal1 capacitances ---------------- */ areacap M1Cap 8 overlap M1Cap allWell 8 PolyCap,PNplusCap overlap M1Cap PNplusCap 14 overlap M1Cap PolyCap 14 perimc M1Cap ~M1Cap 22 sideOverlap(M1Cap, ~M1Cap, allWell, 22, (PolyCap,PNplusCap)) sideOverlap(M1Cap, ~M1Cap, PNplusCap, 25, nothing) sideOverlap(M1Cap, ~M1Cap, PolyCap, 25, nothing) sideOverlap(M1Cap, ~M1Cap, M2Cap, 12, nothing) sideOverlap(M1Cap, ~M1Cap, M3Cap, 7, M2Cap) sidewall M1Cap ~M1Cap ~M1Cap M1Cap 27 /* ------------------------------------------------- */ /* ------------ metal2 capacitances ---------------- */ areacap M2Cap 4 overlap M2Cap allWell 4 PolyCap,M1Cap,PNplusCap overlap M2Cap PNplusCap 5 M1Cap overlap M2Cap PolyCap 6 M1Cap overlap M2Cap M1Cap 9 perimc M2Cap ~M2Cap 18 sideOverlap(M2Cap, ~M2Cap, allWell, 18, (M1Cap,PolyCap,PNplusCap) ) sideOverlap(M2Cap, ~M2Cap, PNplusCap, 19, M1Cap) sideOverlap(M2Cap, ~M2Cap, PolyCap, 20, M1Cap) sideOverlap(M2Cap, ~M2Cap, M1Cap, 23, nothing) sideOverlap(M2Cap, ~M2Cap, M3Cap, 10, nothing) sidewall M2Cap ~M2Cap ~M2Cap M2Cap 33 /* ------------------------------------------------- */ /* ------------ metal3 capacitances ---------------- */ areacap M3Cap 3 overlap M3Cap allWell 3 PolyCap,M1Cap,M2Cap,PNplusCap overlap M3Cap PNplusCap 3 M1Cap,M2Cap overlap M3Cap PolyCap 3 M1Cap,M2Cap overlap M3Cap M1Cap 4 M2Cap overlap M3Cap M2Cap 9 perimc M3Cap ~M3Cap 17 sideOverlap(M3Cap, ~M3Cap, allWell, 17, (PNplusCap,PolyCap,M1Cap,M2Cap)) sideOverlap(M3Cap, ~M3Cap, PNplusCap, 17, (M1Cap,M2Cap)) sideOverlap(M3Cap, ~M3Cap, PolyCap, 17, (M1Cap,M2Cap)) sideOverlap(M3Cap, ~M3Cap, M1Cap, 20, (M2Cap)) sideOverlap(M3Cap, ~M3Cap, M2Cap, 25, nothing) sidewall M3Cap ~M3Cap ~M3Cap M3Cap 50 /* ------------------------------------------------- */ /* -------------- Fets -----------------------------*/ /* cscab, cscap defined since extresis needs them */ fet pfet pdiff,pdc 2 pfet Vdd! nwell 204 450 fet nfet ndiff,ndc 2 nfet Gnd! pwell 150 450 /* These values are the equivalent resistance that irsim params for 3.3 V 125C though. Probably we want to make that 5V, 27C !!!! */ fetresis nfet linear 14100 /* resistance dyn L */ fetresis pfet linear 48100 /* resistance dyn H */ fetresis nfet saturation 14100 /* resistance dyn L */ fetresis pfet saturation 48100 /* resistance dyn H */ /* ------------------------------------------------- */ /* -------------- Resistivity (in milliohms per sq) -------*/ /* ---- assumed temp 85 C ----- */ resist NDRes 3800 resist PDRes 3800 resist PolyRes 5000 resist M1Res 81 resist M2Res 81 resist M3Res 34 resist nwell 1980000 contact pc 4 15000 contact ndc,pdc,nsc,psc 4 1500 contact m2c 4 500 contact m3c 4 500 /* ------------------------------------------------- */ /* Order the planes for correct shielding */ planeOrder(implant,0) planeOrder(well,1) planeOrder(active,2) planeOrder(metal1,3) planeOrder(metal2,4) planeOrder(metal3,5) planeOrder(oxide,6) magic-8.0.210/scmos/extract_template/scmosExt14b-sub.tech.in0000644000175000001440000001212310751423606022323 0ustar timusers/* This is for HP's CMOS26B 1.0 micron CMOS Bulk Process. All parameters are defined based on HP's general process specifications (GPP). Sidewall fringing was taken from Ersatco fictitious process (johnson,jouppi). Upwards fringe caps (eg poly-->m1, poly-->m2) are computed by the program scaleCap by using the Sakurai/Tamaru formula based on the known capacitances. */ #ifdef extForSpice style lambda=0.30 #else style lambda_irsim=0.30 #endif lambda 30 step 100 sidehalo 10 /* 4 more than min m3 spacing */ #ifdef INCLUDE_FET_CAP /* Normally off since neither spice or irsim need it */ areacap allFet 692 /* af/lambda^2 */ #endif /* ------------ diff capacitances ---------------- */ areacap nwell 19 /* 208aF/um2*/ perimc nwell ~(nwell) 60 /* scale the 26b value */ #ifdef extForSpice areacap (ndiff,nsd,ndc,nsc)/a 0 perimc (ndiff,nsd,ndc,nsc)/a space,pwell 0 areacap (pdiff,psd,pdc,psc)/a 0 perimc (pdiff,psd,pdc,psc)/a space,nwell 0 #else /* Real perim values increased a little to compensate for not counting CJGATE */ areacap (ndiff,nsd,ndc,nsc)/a 23 perimc (ndiff,nsd,ndc,nsc)/a space,pwell 160 /* field - 320aF/um */ /* gate - 614aF/um */ areacap (pdiff,psd,pdc,psc)/a 52 perimc (pdiff,psd,pdc,psc)/a space,nwell 90 /* field - 213aF/um */ /* gate - 332aF/um */ #endif /* ------------------------------------------------------ */ /* ------------ poly capacitances ---------------- */ areacap PolyCap 8.2 overlap PolyCap allWell 8.2 perimc PolyCap ~PolyCap 12.6 sideOverlap(PolyCap, ~PolyCap, allWell, 12.6, nothing) sideOverlap(PolyCap, ~PolyCap, M1Cap, 5.7, nothing) sideOverlap(PolyCap, ~PolyCap, M2Cap, 2.7, M1Cap) sideOverlap(PolyCap, ~PolyCap, M3Cap, 1.8, (M1Cap,M2Cap)) sidewall PolyCap ~PolyCap ~PolyCap PolyCap 7.2 /* ------------------------------------------------- */ /* ------------ metal1 capacitances ---------------- */ areacap M1Cap 3.5 overlap M1Cap allWell 3.5 PolyCap,PNplusCap overlap M1Cap PNplusCap 5.7 overlap M1Cap PolyCap 5.7 perimc M1Cap ~M1Cap 15 sideOverlap(M1Cap, ~M1Cap, allWell, 15, (PolyCap,PNplusCap)) sideOverlap(M1Cap, ~M1Cap, PNplusCap, 17.4, nothing) sideOverlap(M1Cap, ~M1Cap, PolyCap, 17.4, nothing) sideOverlap(M1Cap, ~M1Cap, M2Cap, 8.7, nothing) sideOverlap(M1Cap, ~M1Cap, M3Cap, 4.8, M2Cap) sidewall M1Cap ~M1Cap ~M1Cap M1Cap 19.2 /* ------------------------------------------------- */ /* ------------ metal2 capacitances ---------------- */ areacap M2Cap 1.3 overlap M2Cap allWell 1.3 PolyCap,M1Cap,PNplusCap overlap M2Cap PNplusCap 1.5 M1Cap overlap M2Cap PolyCap 1.5 M1Cap overlap M2Cap M1Cap 3.5 perimc M2Cap ~M2Cap 12.3 sideOverlap(M2Cap, ~M2Cap, allWell, 12.3, (M1Cap,PolyCap,PNplusCap) ) sideOverlap(M2Cap, ~M2Cap, PNplusCap, 12.9, M1Cap) sideOverlap(M2Cap, ~M2Cap, PolyCap, 12.9, M1Cap) sideOverlap(M2Cap, ~M2Cap, M1Cap, 15, nothing) sideOverlap(M2Cap, ~M2Cap, M3Cap, 10.8, nothing) sidewall M2Cap ~M2Cap ~M2Cap M2Cap 21.6 /* ------------------------------------------------- */ /* ------------ metal3 capacitances ---------------- */ areacap M3Cap .81 overlap M3Cap allWell .81 PolyCap,M1Cap,M2Cap,PNplusCap overlap M3Cap PNplusCap .88 M1Cap,M2Cap overlap M3Cap PolyCap .88 M1Cap,M2Cap overlap M3Cap M1Cap 1.3 M2Cap overlap M3Cap M2Cap 3.3 perimc M3Cap ~M3Cap 12.3 sideOverlap(M3Cap, ~M3Cap, allWell, 12.3, (PNplusCap,PolyCap,M1Cap,M2Cap)) sideOverlap(M3Cap, ~M3Cap, PNplusCap, 12.9, (M1Cap,M2Cap)) sideOverlap(M3Cap, ~M3Cap, PolyCap, 12.9, (M1Cap,M2Cap)) sideOverlap(M3Cap, ~M3Cap, M1Cap, 15.3, (M2Cap)) sideOverlap(M3Cap, ~M3Cap, M2Cap, 19.2, nothing) sidewall M3Cap ~M3Cap ~M3Cap M3Cap 34.3 /* ------------------------------------------------- */ /* Unchanged yet for .35um*/ /* -------------- Fets -----------------------------*/ /* cscab, cscap defined since extresis needs them */ /* gate cap is actually 982aF/um^2 or .344fF/um*/ fet pfet pdiff,pdc 2 pfet Vdd! nwell 218 88 fet nfet ndiff,ndc 2 nfet Gnd! pwell 267 88 /* These values are the equivalent resistance that irsim params for 3.3 V 85C */ fetresis nfet linear 8500 /* resistance dyn L */ fetresis pfet linear 24500 /* resistance dyn H */ fetresis nfet saturation 8500 /* resistance dyn L */ fetresis pfet saturation 24500 /* resistance dyn H */ /* ------------------------------------------------- */ /* -------------- Resistivity (in milliohms per sq) -------*/ /* ---- assumed temp 85 C ----- */ resist NDRes 3100 resist PDRes 2500 resist PolyRes 7500 /*4400 for W>1.0um*/ resist M1Res 83 resist M2Res 84 resist M3Res 41 resist nwell 1980000 /*unchanged from 26b*/ /* Values are for per contact */ contact pc 4 10000 /*8k-nom 15k-max*/ contact ndc,pdc,nsc,psc 4 4500 contact m2c 4 1000 contact m3c 4 1000 /* ------------------------------------------------- */ /* Order the planes for correct shielding */ planeOrder(implant,0) planeOrder(well,1) planeOrder(active,2) planeOrder(metal1,3) planeOrder(metal2,4) planeOrder(metal3,5) planeOrder(oxide,6) magic-8.0.210/scmos/extract_template/scmosExt14b-tm.tech.in0000644000175000001440000001214110751423606022152 0ustar timusers/* This is for HP's CMOS26B 1.0 micron CMOS Bulk Process. All parameters are defined based on HP's general process specifications (GPP). Sidewall fringing was taken from Ersatco fictitious process (johnson,jouppi). Upwards fringe caps (eg poly-->m1, poly-->m2) are computed by the program scaleCap by using the Sakurai/Tamaru formula based on the known capacitances. */ #ifdef extForSpice style lambda=0.35 #else style lambda_irsim=0.35 #endif lambda 35 step 100 sidehalo 10 /* 4 more than min m3 spacing */ #ifdef INCLUDE_FET_CAP /* Normally off since neither spice or irsim need it */ areacap allFet 692 /* af/lambda^2 */ #endif /* ------------ diff capacitances ---------------- */ areacap nwell 25 /* 208aF/um2*/ perimc nwell ~(nwell) 70 /* scale the 26b value */ #ifdef extForSpice areacap (ndiff,nsd,ndc,nsc)/a 0 perimc (ndiff,nsd,ndc,nsc)/a space,pwell 0 areacap (pdiff,psd,pdc,psc)/a 0 perimc (pdiff,psd,pdc,psc)/a space,nwell 0 #else /* Real perim values increased a little to compensate for not counting CJGATE */ areacap (ndiff,nsd,ndc,nsc)/a 31 perimc (ndiff,nsd,ndc,nsc)/a space,pwell 180 /* field - 320aF/um */ /* gate - 614aF/um */ areacap (pdiff,psd,pdc,psc)/a 71 perimc (pdiff,psd,pdc,psc)/a space,nwell 100 /* field - 213aF/um */ /* gate - 332aF/um */ #endif /* ------------------------------------------------------ */ /* ------------ poly capacitances ---------------- */ areacap PolyCap 11.1 overlap PolyCap allWell 11.1 perimc PolyCap ~PolyCap 14.7 sideOverlap(PolyCap, ~PolyCap, allWell, 14.7, nothing) sideOverlap(PolyCap, ~PolyCap, M1Cap, 6.7, nothing) sideOverlap(PolyCap, ~PolyCap, M2Cap, 3.2, M1Cap) sideOverlap(PolyCap, ~PolyCap, M3Cap, 2.1, (M1Cap,M2Cap)) sidewall PolyCap ~PolyCap ~PolyCap PolyCap 8.4 /* ------------------------------------------------- */ /* ------------ metal1 capacitances ---------------- */ areacap M1Cap 4.8 overlap M1Cap allWell 4.8 PolyCap,PNplusCap overlap M1Cap PNplusCap 7.7 overlap M1Cap PolyCap 7.7 perimc M1Cap ~M1Cap 17.5 sideOverlap(M1Cap, ~M1Cap, allWell, 17.5, (PolyCap,PNplusCap)) sideOverlap(M1Cap, ~M1Cap, PNplusCap, 20.3, nothing) sideOverlap(M1Cap, ~M1Cap, PolyCap, 20.3, nothing) sideOverlap(M1Cap, ~M1Cap, M2Cap, 10.2, nothing) sideOverlap(M1Cap, ~M1Cap, M3Cap, 5.6, M2Cap) sidewall M1Cap ~M1Cap ~M1Cap M1Cap 22.4 /* ------------------------------------------------- */ /* ------------ metal2 capacitances ---------------- */ areacap M2Cap 1.8 overlap M2Cap allWell 1.8 PolyCap,M1Cap,PNplusCap overlap M2Cap PNplusCap 2.1 M1Cap overlap M2Cap PolyCap 2.1 M1Cap overlap M2Cap M1Cap 4.7 perimc M2Cap ~M2Cap 14.4 sideOverlap(M2Cap, ~M2Cap, allWell, 14.4, (M1Cap,PolyCap,PNplusCap) ) sideOverlap(M2Cap, ~M2Cap, PNplusCap, 15.1, M1Cap) sideOverlap(M2Cap, ~M2Cap, PolyCap, 15.1, M1Cap) sideOverlap(M2Cap, ~M2Cap, M1Cap, 17.5, nothing) sideOverlap(M2Cap, ~M2Cap, M3Cap, 12.6, nothing) sidewall M2Cap ~M2Cap ~M2Cap M2Cap 25.2 /* ------------------------------------------------- */ /* ------------ metal3 capacitances ---------------- */ areacap M3Cap 1.1 overlap M3Cap allWell 1.1 PolyCap,M1Cap,M2Cap,PNplusCap overlap M3Cap PNplusCap 1.2 M1Cap,M2Cap overlap M3Cap PolyCap 1.2 M1Cap,M2Cap overlap M3Cap M1Cap 1.8 M2Cap overlap M3Cap M2Cap 4.5 perimc M3Cap ~M3Cap 14.4 sideOverlap(M3Cap, ~M3Cap, allWell, 14.4, (PNplusCap,PolyCap,M1Cap,M2Cap)) sideOverlap(M3Cap, ~M3Cap, PNplusCap, 15.1, (M1Cap,M2Cap)) sideOverlap(M3Cap, ~M3Cap, PolyCap, 15.1, (M1Cap,M2Cap)) sideOverlap(M3Cap, ~M3Cap, M1Cap, 17.9, (M2Cap)) sideOverlap(M3Cap, ~M3Cap, M2Cap, 22.4, nothing) sidewall M3Cap ~M3Cap ~M3Cap M3Cap 40 /* ------------------------------------------------- */ /* Unchanged yet for .35um*/ /* -------------- Fets -----------------------------*/ /* cscab, cscap defined since extresis needs them */ /* gate cap is actually 982aF/um^2 or .344fF/um*/ fet pfet pdiff,pdc 2 pfet Vdd! nwell 254 120 fet nfet ndiff,ndc 2 nfet Gnd! pwell 311 120 /* These values are the equivalent resistance that irsim params for 3.3 V 85C */ fetresis nfet linear 14285 /* resistance dyn L */ fetresis pfet linear 40914 /* resistance dyn H */ fetresis nfet saturation 14285 /* resistance dyn L */ fetresis pfet saturation 40914 /* resistance dyn H */ /* ------------------------------------------------- */ /* -------------- Resistivity (in milliohms per sq) -------*/ /* ---- assumed temp 85 C ----- */ resist NDRes 3100 resist PDRes 2500 resist PolyRes 7500 /*4400 for W>1.0um*/ resist M1Res 83 resist M2Res 84 resist M3Res 41 resist nwell 1980000 /*unchanged from 26b*/ /* Values are for per contact */ contact pc 4 10000 /*8k-nom 15k-max*/ contact ndc,pdc,nsc,psc 4 4500 contact m2c 4 1000 contact m3c 4 1000 /* ------------------------------------------------- */ /* Order the planes for correct shielding */ planeOrder(implant,0) planeOrder(well,1) planeOrder(active,2) planeOrder(metal1,3) planeOrder(metal2,4) planeOrder(metal3,5) planeOrder(oxide,6) magic-8.0.210/scmos/extract_template/scmosExt060_orb.tech.in0000644000175000001440000000601110751423606022314 0ustar timusers/* This is for HP's CMOS34 1.2 micron CMOS Bulk Process. Again some parameters are defined by GPP others by Ersatzco and others are computed. */ #ifdef extForSpice style lambda=0.6(orb_scne12) #else style lambda_irsim=0.6(orb_scne12) #endif lambda 60 step 100 sidehalo 0 #ifdef INCLUDE_FET_CAP areacap allFet 433 #endif /* ------------ diff capacitances ---------------- */ areacap nwell 35 perimc nwell ~(nwell) 47 #ifdef extForSpice areacap ndiff,nsd,ndc/a,nsc/a 0 areacap pdiff,psd,pdc/a,psc/a 0 perimc ndiff,nsd,ndc/a,nsc/a space,pwell 0 perimc pdiff,psd,pdc/a,psc/a space,nwell 0 #else areacap ndiff,nsd,ndc/a,nsc/a 185 areacap pdiff,psd,pdc/a,psc/a 148 perimc ndiff,nsd,ndc/a,nsc/a space,pwell 236 perimc pdiff,psd,pdc/a,psc/a space,nwell 147 #endif /* ------------------------------------------------- */ /* ------------ poly capacitances ---------------- */ areacap PolyCap 29 overlap PolyCap allWell 29 perimc PolyCap ~PolyCap 37 /* ------------------------------------------------- */ /* ------------ metal1 capacitances ---------------- */ areacap M1Cap 16 overlap M1Cap allWell 16 PolyCap,PNplusCap overlap M1Cap PNplusCap 16 overlap M1Cap PolyCap 19 perimc M1Cap ~M1Cap 41 sideOverlap(M1Cap, ~M1Cap, allWell, 41, (PolyCap,PNplusCap)) sideOverlap(M1Cap, ~M1Cap, PNplusCap, 41, nothing) /* ------------------------------------------------- */ /* ------------ metal2 capacitances ---------------- */ areacap M2Cap 10 overlap M2Cap allWell 10 PolyCap,M1Cap,PNplusCap overlap M2Cap PNplusCap 10 M1Cap overlap M2Cap PolyCap 12 M1Cap overlap M2Cap M1Cap 14 perimc M2Cap ~M2Cap 42 sideOverlap(M2Cap, ~M2Cap, allWell, 42, (M1Cap,PolyCap,PNplusCap) ) sideOverlap(M2Cap, ~M2Cap, PNplusCap, 42, M1Cap) /* ------------------------------------------------- */ /* -------------- Fets -----------------------------*/ /* cscab, cscap defined since extresis needs them */ device mosfet pfet pfet pdiff,pdc nwell Vdd! 270 623 device mosfet nfet nfet ndiff,ndc pwell Gnd! 90 623 /* ------- Poly-Poly2 Caps and NPN Vertical Bipolars ----------*/ device capacitor None cap,capc/a poly,pc 90 730 device bjt npn pbase,pbc/a emit,emc/a nwell /* From irsim */ fetresis nfet linear 9700 fetresis pfet linear 35700 /* ------------------------------------------------- */ /* -------------- Resistivity (in milliohms per sq) -------*/ contact pc 4 16210 contact ec 4 13510 contact ndc,nsc, 4 56490 contact pdc,psc, 4 181400 contact m2c 4 43330 resist ndiff,nsd,ndc/a,nsc/a 43180 resist pdiff,psd,pdc/a,psc/a 79770 resist PolyRes 22160 resist allPoly2 21140 resist M1Res 51 resist M2Res 26 resist nwell 1195000 /* ------------------------------------------------- */ /* Order the planes for correct shielding */ planeOrder(implant,0) planeOrder(well,1) planeOrder(active,2) planeOrder(metal1,3) planeOrder(metal2,4) planeOrder(metal3,5) planeOrder(oxide,6) magic-8.0.210/scmos/mos.7bit.sgi.cmap0000644000175000001440000000142510751423606015671 0ustar timusers135 135 135 0 155 30 30 1 1 148 1 2 137 95 50 3 104 66 36 4 119 8 18 5 230 230 0 6 0 0 0 7 60 101 185 8 112 0 143 9 24 97 100 10 85 88 103 11 74 52 90 12 69 37 84 13 125 125 55 14 0 0 0 15 125 88 157 16 117 29 93 17 78 96 104 18 109 75 100 19 83 49 87 20 81 53 89 21 155 139 104 22 0 0 0 23 88 65 153 24 104 0 138 25 48 78 103 26 76 67 106 27 63 56 78 28 62 46 81 29 103 91 64 30 0 0 0 31 255 255 255 32 101 101 101 33 69 69 69 34 0 0 0 35 174 123 133 36 174 60 97 37 209 0 0 38 100 151 110 39 59 126 83 40 0 181 0 41 105 137 177 42 35 85 185 43 0 0 221 44 174 75 178 45 167 0 172 46 255 248 179 47 255 255 0 48 170 133 95 49 169 99 58 50 198 152 0 51 139 108 0 52 250 0 252 53 0 250 250 54 91 52 0 55 135 165 165 56 115 145 115 57 0 0 0 58 239 239 0 59 0 0 0 63 255 255 255 127 0 0 0 255 magic-8.0.210/scmos/mos.OpenGL.std.cmap0000644000175000001440000000407410751423606016163 0ustar timusers#--------------------------------------- # Colormap file for OpenGL graphics #--------------------------------------- # R G B idx color-name #--------------------------------------- 200 200 200 0 background_gray 220 95 95 1 poly_red 66 213 66 2 diff_green 202 160 115 3 diff_brown 169 131 101 4 nfet_brown 184 73 83 5 pfet_brown 230 230 0 6 well_yellow 0 0 0 7 contact_black 125 166 250 8 metal_blue 160 48 191 9 pc_purple 190 153 222 16 metal_purple 255 255 255 32 cursor_white 170 170 170 33 pale_gray 145 145 145 34 dark_gray 0 0 0 35 box_black 239 188 198 36 pale_red 239 125 162 37 medium_red 210 0 155 38 dark_red 165 216 175 39 pale_green 124 191 148 40 medium_green 0 181 0 41 dark_green 170 202 242 42 light_blue 100 150 250 43 bright_blue 40 169 166 44 teal_blue 45 94 179 45 deep_purple 167 0 200 46 bright_purple 255 248 179 47 light_yellow 255 255 0 48 bright_yellow 235 198 160 49 yellow_orange 234 132 73 50 medium_orange 198 152 0 51 ochre_brown 130 90 0 52 medium_brown 245 163 224 53 bright_lavender 50 228 225 54 port_cyan 120 81 29 55 border_brown 200 230 230 56 caption_blue 180 210 180 57 window_gray 0 0 0 58 246 246 7 59 label_yellow 180 180 180 60 medium_gray 230 180 50 61 pale_orange 235 235 235 62 light_gray 255 255 255 64 white 210 148 148 65 deep_pink 133 206 133 66 pale_green 201 170 157 67 peach_gray 184 165 150 68 gray_brown 192 136 141 69 rosy_brown 215 215 100 70 pale_ochre 130 130 130 71 gray50 163 183 225 72 steel_blue 180 124 196 73 medium_purple 137 210 179 74 pale_teal 200 185 255 75 bright_lavender2 169 213 198 76 pale_cyan 210 210 230 77 pale_steel 244 115 105 78 brick_red 195 176 211 80 pale_purple 185 185 185 97 gray75 160 160 160 98 gray62 100 100 100 99 gray40 220 163 181 101 pale_pink 220 120 200 102 medium_pink 80 175 80 105 sea_green 125 180 180 109 medium_steel 175 115 175 110 deep_lavender 215 170 90 115 medium_tan 228 160 201 117 light_lavender 215 190 125 125 light_tan 234 165 155 142 pale_pink2 0 0 0 255 magic-8.0.210/scmos/mos.24bit.dstyle0000664000175000001440000004164612402623676015572 0ustar timusers# # MOSIS distribution Version 8.2 # # This file has been updated by MOSIS to be used for three metal, two poly # SCMOS technology files. # # (C) Copyright 1992, 1993, 1994, 1995 by # # Jen-I Pi pi@isi.edu # The MOSIS Service # USC Information Sciences Institute # 4676 Admiralty Way # Marina del Rey, CA 90292 # (310) 822-1511 x640 fax (310)823-5624 # # All Rights Reserved. # Last Modified Date: 12/3/03 # # Permission to use, copy, modify, and distribute this technology # file and its associated documentation for any purpose and without # fee is hereby granted, provided that the above copyright notice # appears in all copies and that both that copyright notice and this # permission notice appear in supporting documentation, and that the # name of the University of Southern California not be used in # advertising or publicity pertaining to distribution of the software # without specific, written prior permission. The University of # Southern California makes no representations about the suitability # of this technology file for any purpose. This technology file is # provided "as is" without express or implied warranty and the # University of Southern California retains the right to change its # content at any time without notice any other party. # # THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS TECHNOLOGY FILE, INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF # SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS # OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS TECHNOLOGY FILE. # # This file describes the various display styles that are available # in Magic. This new file is relatively technology-independent: it # contains enough different styles to support MOSIS's SCMOS process # without any changes. Each display style describes a particular # way of drawing things on the display. See "Magic Maintainer's # Manual #3: The Display Style and Glyph Files" for details on the # file format. # # Please send bug reports/comments to mosis@mosis.edu :-) # # Version keyword replaces the version embedded in the filename. version 7 # # 24-bit True Color does not use bit planes. The "mask" value is # irrelevant. # display_styles 24 # # The style below means "no color at all". It is special, in that # it is used by cursors to indicate transparency. # # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 0 0x7f 0 0x00 solid 0 - no_color_at_all # # Opaque styles used for drawing and erasing highlights, window borders, # etc. # stipple short long # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 1 0x20 32 0x00 solid 0 - solid_highlights 2 0x20 32 0x00 stipple 12 - medium_highlights 3 0x20 32 0x00 stipple 9 - pale_highlights 4 0x20 32 0x00 stipple 10 - horiz_highlights 5 0x20 32 0x00 stipple 11 - vert_highlights 6 0x20 32 0xff outline 0 - outline_highlights 7 0x20 32 0xcc outline 0 - dotted_highlights # 8 0x40 0 0xff outline 0 - erase_box 9 0x7f 0 0x00 solid 0 - erase_highlights 10 0x7f 0 0x00 solid 0 - erase_everything 11 0x3f 0 0x00 solid 0 - erase_all_but_highl # 12 0x3f 59 0xff outline 0 - labels 13 0x3f 45 0xff outline 0 - ports 14 0x3f 54 0xff outline 0 - port_connections 15 0x3f 35 0xff outline 0 - bounding_boxes 16 0x3f 35 0xaa grid 0 - dotted_grid 17 0x3f 35 0xff grid 0 - solid_grid 18 0x3f 35 0x00 solid 0 - origin_square 19 0x3f 35 0xff outline 0 - draw_tile_details # 20 0x7f 55 0x00 solid 0 w window_border 21 0x7f 55 0xff stipple 6 - window_elevator 22 0x7f 56 0x00 solid 0 c window_caption 23 0x7f 57 0x00 solid 0 x window_background # 24 0x7f 58 0x00 solid 0 - color_editing # 25 0x7f 60 0x00 solid 0 T tk_medium_gray 26 0x7f 62 0x00 solid 0 t tk_light_gray # 27 0x7f 47 0xff outline 0 - pale_labels 28 0x7f 80 0xff outline 0 - pale_ports # # General-purpose opaque colors. These entries define a whole # bunch of generally-useful colors. # stipple short long # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 29 0x3f 32 0x00 solid 0 W white 30 0x3f 33 0x00 solid 0 - gray1 (pale) 31 0x3f 34 0x00 solid 0 k gray2 (dark) 32 0x3f 35 0x00 solid 0 K black 33 0x3f 36 0x00 solid 0 r red1 (pale) 34 0x3f 37 0x00 solid 0 - red2 (medium) 35 0x3f 38 0x00 solid 0 R red3 (dark) 36 0x3f 39 0x00 solid 0 g green1 (pale) 37 0x3f 40 0x00 solid 0 - green2 (medium) 38 0x3f 41 0x00 solid 0 G green3 (dark) 39 0x3f 42 0x00 solid 0 b blue1 40 0x3f 43 0x00 solid 0 B blue2 (dark) 41 0x3f 44 0x00 solid 0 - blue3 42 0x3f 45 0x00 solid 0 p purple1 43 0x3f 46 0x00 solid 0 P purple2 44 0x3f 47 0x00 solid 0 y yellow1 45 0x3f 48 0x00 solid 0 Y yellow2 46 0x3f 49 0x00 solid 0 o orange1 47 0x3f 50 0x00 solid 0 O orange2 48 0x3f 51 0x00 solid 0 - brown1 49 0x3f 52 0x00 solid 0 - brown2 50 0x3f 53 0x00 solid 0 - magenta 51 0x3f 54 0x00 solid 0 C cyan # #---------------------------------------------------------------------- # All of the styles above this point are used internally by Magic for # things like menus, drawing the box, etc. The style numbers must # match the definitions in misc/style.h. All of the styles below # this point are used by the technology file, addressed by number. # Note that the numbers are only for backwards compatibility with # .tech27 files which specify styles by number. .tech28 files may # specify styles by name, and numbers may be listed out of order. # The order in which styles are drawn is the order in which they # appear in this file. #---------------------------------------------------------------------- layout_styles # # Poly-diff styles: # stipple short long # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 1 0x07 1 0x00 solid 0 - polysilicon 87 0x07 50 0x00 solid 0 - poly_light 88 0x07 1 0x00 stipple 1 - obspoly 2 0x07 2 0x00 solid 0 - ndiffusion 69 0x07 40 0x00 solid 0 - mvndiff 70 0x07 41 0x00 solid 0 - hvndiff 71 0x07 44 0x00 solid 0 - ncontact 3 0x07 2 0x00 stipple 13 - ndiff_in_nwell 4 0x07 3 0x00 solid 0 - pdiffusion 72 0x07 51 0x00 solid 0 - mvpdiff 73 0x07 52 0x00 solid 0 - hvpdiff 74 0x07 45 0x00 solid 0 - pcontact 5 0x07 3 0x00 stipple 13 - pdiff_in_pwell 6 0x07 4 0x00 solid 0 - ntransistor 7 0x07 2 0x00 stipple 7 - ntransistor_stripes 8 0x07 5 0x00 solid 0 - ptransistor 9 0x07 3 0x00 stipple 5 - ptransistor_stripes 79 0x07 71 0x00 stipple 21 - highvolt_nwell 80 0x07 69 0x00 stipple 22 - highvolt_pwell 83 0x3f 51 0x00 stipple 5 - implant1 84 0x3f 48 0x00 stipple 5 - implant2 85 0x3f 38 0x00 stipple 5 - implant3 86 0x3f 32 0x00 stipple 5 - implant4 10 0x3f 6 0x00 stipple 7 - cwell 11 0x07 5 0x00 stipple 22 - hvndiff_mask 12 0x07 7 0x00 stipple 7 - nwell 13 0x07 3 0x00 stipple 5 - pwell 14 0x3f 6 0x00 stipple 2 - electrode 15 0x07 3 0x00 stipple 10 - pbase 16 0x07 2 0x00 stipple 17 - emitter 17 0x07 3 0x00 stipple 11 - bccd 18 0x07 4 0x00 stipple 21 - hvpdiff_mask 19 0x07 7 0x00 solid 0 - via # # Metal styles: # stipple short long # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 20 0x08 8 0x00 stipple 16 - metal1 21 0x10 16 0x00 stipple 12 - metal2 22 0x3f 53 0x00 stipple 23 - metal3 23 0x3f 33 0x00 stipple 20 - metal4 24 0x3f 44 0x00 stipple 8 - metal5 25 0x3f 37 0x00 solid 0 - pad4 26 0x0f 9 0x00 solid 0 - poly_contact 27 0x07 1 0x00 solid 0 - electrode_stripes 28 0x3f 6 0x00 stipple 2 - capacitor 29 0x08 8 0x00 stipple 16 - metal1_alt # # Opaque stipples and such for mask display: # stipple short long # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 30 0x3f 2 0x00 stipple 22 - ndop_stripes 31 0x3f 3 0x00 stipple 21 - pdop_stripes 35 0x3f 3 0xff stipple 1 - pselect 36 0x3f 2 0xff stipple 15 - nselect 37 0x3f 35 0xff stipple 19 - via2 38 0x3f 35 0xff stipple 4 - via3 39 0x3f 35 0xff stipple 5 - via4 # 40 0x3f 53 0x00 stipple 5 - check_paint 41 0x3f 54 0x00 stipple 7 - check_subcells 42 0x3f 32 0x00 stipple 4 - error_waffle # 43 0x07 2 0x00 stipple 5 - nselect2 44 0x07 3 0x00 stipple 7 - pselect2 45 0x07 35 0x00 solid 0 - comment 46 0x07 42 0x00 stipple 7 - silicide_block 47 0x07 1 0x00 solid 0 - poly_resist 48 0x07 3 0x00 stipple 7 - poly_resist_stripes 49 0x08 8 0x00 stipple 19 - metal1tight 89 0x08 8 0x00 stipple 1 - obsmetal1 50 0x10 16 0x00 stipple 19 - metal2tight 90 0x10 16 0x00 stipple 1 - obsmetal2 51 0x3f 53 0x00 stipple 8 - metal3tight 91 0x3f 53 0x00 stipple 1 - obsmetal3 92 0x3f 33 0x00 stipple 1 - obsmetal4 93 0x3f 44 0x00 stipple 1 - obsmetal5 52 0x07 2 0x00 stipple 19 - cwellnsc 53 0x07 7 0x00 stipple 7 - nwell_field_implant 54 0x07 7 0x00 stipple 5 - substrate_field_implant 55 0x3f 43 0xff stipple 35 - via1arrow 81 0x3f 43 0xff stipple 2 - via1 56 0x3f 53 0xff stipple 36 - via2arrow 82 0x3f 53 0xff stipple 2 - via2alt 57 0x3f 6 0xff stipple 2 - via3alt 58 0x3f 7 0x00 solid 0 - gen_contact 32 0x3f 35 0xff cross 0 - contact_X'es 33 0x3f 35 0xff stipple 2 - contact_waffle # 64 0x3f 46 0x00 stipple 8 - metal6 94 0x3f 46 0x00 stipple 1 - obsmetal6 59 0x3f 32 0xff stipple 2 - via5 65 0x3f 38 0x00 stipple 9 - metal7 95 0x3f 38 0x00 stipple 1 - obsmetal7 60 0x3f 46 0xff stipple 28 - via6 66 0x3f 34 0x00 stipple 16 - metal8 96 0x3f 34 0x00 stipple 1 - obsmetal8 61 0x3f 51 0xff stipple 29 - via7 75 0x3f 74 0x00 stipple 8 - metal9 97 0x3f 74 0x00 stipple 1 - obsmetal9 76 0x3f 7 0xff stipple 30 - via8 77 0x3f 75 0x00 stipple 9 - metal10 98 0x3f 75 0x00 stipple 1 - obsmetal10 78 0x3f 7 0xff stipple 31 - via9 # 62 0x3f 0 0x00 solid 0 - mim_bottom 63 0x3f 0 0x00 solid 0 - mim_top 34 0x3f 34 0xff stipple 10 - overglass 67 0x3f 9 0x00 outline 0 - subcircuit 68 0x3f 34 0xff stipple 12 - mems # #------------------------------------------------------------------ # All of the styles below this point must duplicate the styles in # the section above, and represent a version of each previous # layer to use in non-edit cells ("pale" styles): #------------------------------------------------------------------ pale_styles # # Poly-diff styles: # stipple short long # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 1 0x07 1 0x00 stipple 14 - polysilicon 87 0x07 49 0x00 solid 0 - poly_light 88 0x07 1 0x00 stipple 1 - obspoly 2 0x07 2 0x00 stipple 14 - ndiffusion 69 0x07 40 0x00 stipple 3 - mvndiff 70 0x07 41 0x00 stipple 3 - hvndiff 71 0x07 44 0x00 stipple 3 - ncontact 3 0x07 2 0x00 stipple 13 - ndiff_in_nwell 4 0x07 3 0x00 stipple 14 - pdiffusion 72 0x07 51 0x00 stipple 25 - mvpdiff 73 0x07 52 0x00 stipple 25 - hvpdiff 74 0x07 45 0x00 stipple 25 - pcontact 5 0x07 3 0x00 stipple 13 - pdiff_in_pwell 6 0x07 4 0x00 stipple 14 - ntransistor 7 0x07 2 0x00 stipple 7 - ntransistor_stripes 8 0x07 5 0x00 stipple 14 - ptransistor 9 0x07 3 0x00 stipple 5 - ptransistor_stripes 79 0x07 71 0x00 stipple 21 - highvolt_nwell 80 0x07 69 0x00 stipple 22 - highvolt_pwell 83 0x3f 51 0x00 stipple 5 - implant1 84 0x3f 48 0x00 stipple 5 - implant2 85 0x3f 38 0x00 stipple 5 - implant3 86 0x3f 32 0x00 stipple 5 - implant4 10 0x07 6 0x00 stipple 7 - cwell 11 0x07 5 0x00 stipple 22 - hvndiff_mask 12 0x07 7 0x00 stipple 7 - nwell 13 0x07 3 0x00 stipple 5 - pwell 14 0x3f 6 0x00 stipple 2 - electrode 15 0x07 3 0x00 stipple 10 - pbase 16 0x07 2 0x00 stipple 17 - emitter 17 0x07 3 0x00 stipple 11 - bccd 18 0x07 7 0x00 stipple 21 - hvpdiff_mask 19 0x07 7 0x00 stipple 2 - via # # Metal styles: # stipple short long # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 20 0x08 8 0x00 stipple 16 - metal1 21 0x10 16 0x00 stipple 12 - metal2 22 0x3f 53 0x00 stipple 5 - metal3 23 0x3f 33 0x00 stipple 21 - metal4 24 0x07 44 0x00 stipple 22 - metal5 25 0x07 37 0x00 stipple 18 - pad4 26 0x07 9 0x00 stipple 6 - poly_contact 27 0x07 3 0x00 stipple 9 - electrode_stripes 28 0x07 61 0x00 stipple 2 - capacitor 29 0x08 8 0x00 stipple 16 - metal1_alt # # Opaque stipples and such for mask display: # stipple short long # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 30 0x3f 2 0x00 stipple 22 - ndop_stripes 31 0x3f 3 0x00 stipple 21 - pdop_stripes 35 0x3f 3 0xff stipple 1 - pselect 36 0x3f 2 0xff stipple 15 - nselect 37 0x3f 35 0xff stipple 19 - via2 38 0x3f 35 0xff stipple 4 - via3 39 0x3f 35 0xff stipple 5 - via4 # 40 0x3f 53 0x00 stipple 5 - check_paint 41 0x3f 54 0x00 stipple 7 - check_subcells 42 0x3f 32 0x00 stipple 4 - error_waffle # 43 0x07 2 0x00 stipple 5 - nselect2 44 0x07 3 0x00 stipple 7 - pselect2 45 0x07 15 0x00 solid 0 - comment 46 0x07 42 0x00 stipple 7 - silicide_block 47 0x07 1 0x00 solid 0 - poly_resist 48 0x07 3 0x00 stipple 7 - poly_resist_stripes 49 0x08 8 0x00 stipple 14 - metal1tight 89 0x08 8 0x00 stipple 1 - obsmetal1 50 0x10 16 0x00 stipple 5 - metal2tight 90 0x10 16 0x00 stipple 1 - obsmetal2 51 0x3f 53 0x00 stipple 21 - metal3tight 91 0x3f 53 0x00 stipple 1 - obsmetal3 92 0x3f 33 0x00 stipple 1 - obsmetal4 93 0x3f 44 0x00 stipple 1 - obsmetal5 52 0x07 2 0x00 stipple 13 - cwellnsc 53 0x07 7 0x00 stipple 7 - nwell_field_implant 54 0x07 7 0x00 stipple 5 - substrate_field_implant 55 0x3f 43 0xff stipple 35 - via1arrow 81 0x3f 43 0xff stipple 2 - via1 56 0x3f 53 0xff stipple 36 - via2arrow 82 0x3f 53 0xff stipple 2 - via2alt 57 0x3f 6 0xff stipple 2 - via3alt 58 0x3f 34 0x00 stipple 1 - gen_contact 32 0x3f 35 0xff cross 0 - contact_X'es 33 0x3f 35 0xff stipple 2 - contact_waffle # 64 0x3f 46 0x00 stipple 7 - metal6 94 0x3f 46 0x00 stipple 1 - obsmetal6 59 0x3f 16 0xff stipple 2 - via5 65 0x3f 38 0x00 stipple 5 - metal7 95 0x3f 38 0x00 stipple 1 - obsmetal7 60 0x3f 46 0xff stipple 28 - via6 66 0x3f 34 0x00 stipple 10 - metal8 96 0x3f 34 0x00 stipple 1 - obsmetal8 61 0x3f 51 0xff stipple 29 - via7 75 0x3f 76 0x00 stipple 8 - metal9 97 0x3f 74 0x00 stipple 1 - obsmetal9 76 0x3f 34 0xff stipple 30 - via8 77 0x3f 76 0x00 stipple 9 - metal10 98 0x3f 75 0x00 stipple 1 - obsmetal10 78 0x3f 34 0xff stipple 31 - via9 # 62 0x3f 0 0x00 solid 0 - mim_bottom 63 0x3f 0 0x00 solid 0 - mim_top 34 0x3f 34 0xff stipple 10 - overglass 67 0x3f 9 0x00 outline 0 - subcircuit 68 0x3f 33 0x00 stipple 12 - mems # stipples #-----------------------------------+--------------------------------------- # hex bit pattern (8x8) description #-----------------------------------+--------------------------------------- 1 40 00 18 00 18 00 00 00 very sparsed stripes, ll to ur 2 cc cc 00 00 33 33 00 00 coarse knight's move (waffle) 3 ee 77 bb dd ee 77 bb dd all but diagonal stripes, ll to ur 4 00 00 cc cc 00 00 cc cc offset waffle 5 40 20 10 08 04 02 01 80 sparse diagonal stripes, ll to ur 6 aa 55 aa 55 aa 55 aa 55 half 'n half (checkerboard) 7 02 04 08 10 20 40 80 01 sparse diagonal stripes, lr to ul 8 81 03 06 0c 18 30 60 c0 wide sparse diagonal stripes, lr to ul 9 81 c0 60 30 18 0c 06 03 wide sparse diagonal stripes, ll to ur 10 00 00 00 ff 00 00 00 ff horizontal stripes 11 44 44 44 44 44 44 44 44 vertical stripes 12 55 aa 55 aa 55 aa 55 aa complement of half `n half 13 33 33 ff ff cc cc ff ff complement of #2 (coarse knight's move) 14 aa 55 aa 55 aa 55 aa 55 half 'n half (checkerboard) 15 00 01 00 18 00 00 00 18 very sparsed stripes, 11 to ur 16 c0 07 ff ff c0 07 ff ff wide horizontal stripes 17 c7 c7 c7 c7 c7 c7 c7 c7 wide vertical stripes 18 7c 7c 7c 7c 7c 7c 7c 7c wide vertical stripes (reverse of 17) 19 3c c3 42 42 c3 3c 24 24 bubbles 20 24 42 81 81 42 24 18 18 offset diagonal crossex 21 10 20 00 00 00 02 04 08 diagonal dotted line, lr to ul 22 08 04 00 00 00 40 20 10 diagonal dotted line, ll to ur 23 3c 66 c3 81 c3 66 3c 18 dense diagonal crossex 24 c3 3c bd bd 3c c3 db db complement of #19 empty bubbles 25 dd bb 77 ee dd bb 77 ee all but diagonal stripes, lr to ul 26 e2 4e 52 29 94 e4 8e 11 T pattern 27 71 47 41 00 42 72 47 99 sparse offset T pattern 28 99 3c 7e e7 e7 7e 3c 99 alternating diamonds 29 44 88 55 22 44 88 55 22 bricks, ll to ur 30 30 60 c0 c1 63 36 1c 18 bricks, lr to ul 31 55 db 22 db 55 db 22 db linoleum 32 60 c0 81 03 06 0c 18 30 33 00 00 00 30 60 60 30 00 new gc thin 34 00 02 06 0e 0e 06 02 00 35 00 7e 3c 18 00 e7 c3 81 arrows pointing up 36 e0 62 26 0e 0e 26 62 e0 arrows pointing left magic-8.0.210/scmos/doc/0000755000175000001440000000000011504623577013355 5ustar timusersmagic-8.0.210/scmos/doc/scmos-rules-rev7.ps0000644000175000001440000067441110751423606017065 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvips 5.47 Copyright 1986-91 Radical Eye Software %%Title: rules.dvi %%Pages: 28 1 %%BoundingBox: 0 0 612 792 %%EndComments %%BeginProcSet: tex.pro /TeXDict 200 dict def TeXDict begin /N /def load def /B{bind def}N /S /exch load def /X{S N}B /TR /translate load N /isls false N /vsize 10 N /@rigin{ isls{[0 1 -1 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale Resolution VResolution vsize neg mul TR matrix currentmatrix dup dup 4 get round 4 exch put dup dup 5 get round 5 exch put setmatrix}N /@letter{/vsize 10 N}B /@landscape{/isls true N /vsize -1 N}B /@a4{/vsize 10.6929133858 N}B /@a3{ /vsize 15.5531 N}B /@ledger{/vsize 16 N}B /@legal{/vsize 13 N}B /@manualfeed{ statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{/nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{/sf 1 N /fntrx FMat N df-tail} B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0]N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{128 ch-data dup length 3 sub get sub}B /ch-yoff{ ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 add]{ch-image} imagemask restore}B /D{/cc X dup type /stringtype ne{]}if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto}N /eop{clear SI restore showpage userdict /eop-hook known{eop-hook}if}N /@start{userdict /start-hook known{start-hook}if /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for}N /p /show load N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval(Display)eq}{pop false}ifelse}{false}ifelse end{{gsave TR -.1 -.1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 -.1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /a{ moveto}B /delta 0 N /tail{dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{ S p tail}B /c{-4 M}B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w }B /q{p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{clear SS restore}B end %%EndProcSet %%BeginProcSet: special.pro TeXDict begin /SDict 200 dict N SDict begin /@SpecialDefaults{/hs 612 N /vs 792 N /ho 0 N /vo 0 N /hsc 1 N /vsc 1 N /ang 0 N /CLIP false N /BBcalc false N /p 3 def}B /@scaleunit 100 N /@hscale{@scaleunit div /hsc X}B /@vscale{ @scaleunit div /vsc X}B /@hsize{/hs X /CLIP true N}B /@vsize{/vs X /CLIP true N}B /@hoffset{/ho X}B /@voffset{/vo X}B /@angle{/ang X}B /@rwi{10 div /rwi X} B /@llx{/llx X}B /@lly{/lly X}B /@urx{/urx X}B /@ury{/ury X /BBcalc true N}B /magscale true def end /@MacSetUp{userdict /md known{userdict /md get type /dicttype eq{md begin /letter{}N /note{}N /legal{}N /od{txpose 1 0 mtx defaultmatrix dtransform S atan/pa X newpath clippath mark{transform{ itransform moveto}}{transform{itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll curveto}}{{closepath}}pathforall newpath counttomark array astore /gc xdf pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{ PaintBlack}if}N /txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 -1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop 90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr 2 get ppr 0 get neg sub neg 0 S TR}if} ifelse scaleby96{ppr aload pop 4 -1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S TR}if}N /cp{pop pop showpage pm restore}N end}if} if}N /normalscale{Resolution 72 div VResolution 72 div neg scale magscale{ DVImag dup scale}if}N /psfts{S 65536 div N}N /startTexFig{/psf$SavedState save N userdict maxlength dict begin /magscale false def normalscale currentpoint TR /psf$ury psfts /psf$urx psfts /psf$lly psfts /psf$llx psfts /psf$y psfts /psf$x psfts currentpoint /psf$cy X /psf$cx X /psf$sx psf$x psf$urx psf$llx sub div N /psf$sy psf$y psf$ury psf$lly sub div N psf$sx psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub TR /showpage{}N /erasepage{}N /copypage{}N /p 3 def @MacSetUp}N /doclip{psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath moveto}N /endTexFig{end psf$SavedState restore}N /@beginspecial{SDict begin /SpecialSave save N gsave normalscale currentpoint TR @SpecialDefaults}N /@setspecial{CLIP{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto closepath clip}if ho vo TR hsc vsc scale ang rotate BBcalc{rwi urx llx sub div dup scale llx neg lly neg TR}if /showpage{}N /erasepage{}N /copypage{}N newpath}N /@endspecial{grestore clear SpecialSave restore end}N /@defspecial{SDict begin}N /@fedspecial{end}B /li{lineto}B /rl{rlineto}B /rc{rcurveto}B /np{/SaveX currentpoint /SaveY X N 1 setlinecap newpath}N /st{stroke SaveX SaveY moveto}N /fil{fill SaveX SaveY moveto}N /ellipse{/endangle X /startangle X /yrad X /xrad X /savematrix matrix currentmatrix N TR xrad yrad scale 0 0 1 startangle endangle arc savematrix setmatrix}N end %%EndProcSet TeXDict begin 1000 300 300 @start /Fa 1 23 df<0180300380700380700380700700E007 00E00700E00700E00E01C00E01C00E01C00E01C01C03881C03881C03881E07883E19903BE0E038 0000380000700000700000700000700000E00000E00000C00000151B7F9119>22 D E /Fb 1 23 df<0030003000780078007800780078007800F000F000F000F000F000F000F000 F001E001E001E001E001E001E001E001E003C003C003C003C003C003C003C003C0078007800780 078207800782078007820F800F040F800F040F8017040FC027081EE0C3881E3F00F01E0000001E 0000003C0000003C0000003C0000003C00000078000000780000007800000078000000F0000000 F0000000600000001F277E9924>22 D E /Fc 1 3 df<60000018F0000038780000783C0000F0 1E0001E00F0003C00780078003C00F0001E01E0000F03C0000787800003CF000001FE000000FC0 0000078000000FC000001FE000003CF0000078780000F03C0001E01E0003C00F00078007800F00 03C01E0001E03C0000F078000078F0000038600000181D1D789C2E>2 D E /Fd 1 16 df<03F0000FFC001FFE003FFF007FFF807FFF80FFFFC0FFFFC0FFFFC0FFFFC0FFFF C0FFFFC0FFFFC0FFFFC07FFF807FFF803FFF001FFE000FFC0003F00012147D9519>15 D E /Fe 3 51 df<00300000300000300000300000300000300000300000300000300000300000 3000FFFFFCFFFFFC00300000300000300000300000300000300000300000300000300000300000 300016187E931B>43 D<03000700FF000700070007000700070007000700070007000700070007 00070007000700070007007FF00C157E9412>49 D<0F8030E040708030C038E038403800380070 0070006000C00180030006000C08080810183FF07FF0FFF00D157E9412>I E /Ff 20 120 df<03FC000FFF003C1FC07007E07C07F0FE03F0FE03F8FE03F8FE01F87C01F838 03F80003F80003F00003F00007E00007C0000F80001F00003E0000380000700000E01801C01803 80180700180E00380FFFF01FFFF03FFFF07FFFF0FFFFF0FFFFF015207D9F1C>50 D<00FE0007FFC00F07E01E03F03F03F03F81F83F81F83F81F81F03F81F03F00003F00003E00007 C0001F8001FE0001FF000007C00001F00001F80000FC0000FC3C00FE7E00FEFF00FEFF00FEFF00 FEFF00FC7E01FC7801F81E07F00FFFC001FE0017207E9F1C>I<07FC001FFF803F07C03F03E03F 01E03F01F01E01F00001F00001F0003FF003FDF01FC1F03F01F07E01F0FC01F0FC01F0FC01F0FC 01F07E02F07E0CF81FF87F07E03F18167E951B>97 DI<00FF8007FFE00F83F01F03F03E03F07E03F07C01E07C0000FC00 00FC0000FC0000FC0000FC0000FC00007C00007E00007E00003E00301F00600FC0E007FF8000FE 0014167E9519>I<0001FE000001FE0000003E0000003E0000003E0000003E0000003E0000003E 0000003E0000003E0000003E0000003E0000003E0001FC3E0007FFBE000F81FE001F007E003E00 3E007E003E007C003E00FC003E00FC003E00FC003E00FC003E00FC003E00FC003E00FC003E00FC 003E007C003E007C003E003E007E001E00FE000F83BE0007FF3FC001FC3FC01A237EA21F>I<00 FE0007FF800F87C01E01E03E01F07C00F07C00F8FC00F8FC00F8FFFFF8FFFFF8FC0000FC0000FC 00007C00007C00007E00003E00181F00300FC07003FFC000FF0015167E951A>I104 D<1C003E007F007F007F003E001C 000000000000000000000000000000FF00FF001F001F001F001F001F001F001F001F001F001F00 1F001F001F001F001F001F001F001F00FFE0FFE00B247EA310>I108 DII<00FE0007FFC00F83E01E00 F03E00F87C007C7C007C7C007CFC007EFC007EFC007EFC007EFC007EFC007EFC007E7C007C7C00 7C3E00F81F01F00F83E007FFC000FE0017167E951C>II114 D<0FF3003FFF00781F00600700E00300E00300F00300FC00007FE0007FF8003FFE000FFF0001FF 00000F80C00780C00380E00380E00380F00700FC0E00EFFC00C7F00011167E9516>I<01800001 80000180000180000380000380000780000780000F80003F8000FFFF00FFFF000F80000F80000F 80000F80000F80000F80000F80000F80000F80000F80000F80000F81800F81800F81800F81800F 81800F830007C30003FE0000F80011207F9F16>IIII E /Fg 38 122 df<003F07E00001C09C18000380F01800 0701F03C000E01E03C000E00E018000E00E000000E00E000000E00E000000E00E000000E00E000 00FFFFFFFC000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C000E00E0 1C000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C000E00 E01C000E00E01C007FC7FCFF80211D809C23>14 D<60F0F0701010101020204080040C7C830C> 44 D<60F0F06004047C830C>46 D<07E01830201C201C781E780E781E381E001C001C00180030 006007E00030001C001C000E000F000F700FF80FF80FF80FF00E401C201C183007E0101D7E9B15 >51 D<000C00000C00001C00003C00003C00005C0000DC00009C00011C00031C00021C00041C00 0C1C00081C00101C00301C00201C00401C00C01C00FFFFC0001C00001C00001C00001C00001C00 001C00001C0001FFC0121C7F9B15>I<300C3FF83FF03FC020002000200020002000200023E024 302818301C200E000E000F000F000F600FF00FF00FF00F800E401E401C2038187007C0101D7E9B 15>I<00F0030C06040C0E181E301E300C700070006000E3E0E430E818F00CF00EE006E007E007 E007E007E007600760077006300E300C18180C3003E0101D7E9B15>I<4000007FFF807FFF007F FF0040020080040080040080080000100000100000200000600000400000C00000C00001C00001 800001800003800003800003800003800007800007800007800007800007800007800003000011 1D7E9B15>I<03E00C301008200C20066006600660067006780C3E083FB01FE007F007F818FC30 7E601E600FC007C003C003C003C00360026004300C1C1007E0101D7E9B15>I<03C00C30181830 0C700C600EE006E006E007E007E007E007E0076007700F300F18170C2707C700060006000E300C 780C78187010203030C00F80101D7E9B15>I<000600000006000000060000000F0000000F0000 000F00000017800000178000001780000023C0000023C0000023C0000041E0000041E0000041E0 000080F0000080F0000180F8000100780001FFF80003007C0002003C0002003C0006003E000400 1E0004001E000C001F001E001F00FF80FFF01C1D7F9C1F>65 D<001F808000E061800180198007 0007800E0003801C0003801C00018038000180780000807800008070000080F0000000F0000000 F0000000F0000000F0000000F0000000F0000000F0000000700000807800008078000080380000 801C0001001C0001000E000200070004000180080000E03000001FC000191E7E9C1E>67 DI73 D78 D<003F800000E0E0000380380007001C000E000E001C0007003C00078038000380780003C07800 03C0700001C0F00001E0F00001E0F00001E0F00001E0F00001E0F00001E0F00001E0F00001E070 0001C0780003C0780003C0380003803C0007801C0007000E000E0007001C000380380000E0E000 003F80001B1E7E9C20>I82 D<1FC000307000783800781C00301C00001C00001C00 01FC000F1C00381C00701C00601C00E01C40E01C40E01C40603C40304E801F870012127E9115> 97 DI<07E00C301878307870306000E000E000E000E000 E000E00060007004300418080C3007C00E127E9112>I<003F0000070000070000070000070000 070000070000070000070000070000070003E7000C1700180F00300700700700600700E00700E0 0700E00700E00700E00700E00700600700700700300700180F000C370007C7E0131D7E9C17>I< 03E00C301818300C700E6006E006FFFEE000E000E000E00060007002300218040C1803E00F127F 9112>I<00F8018C071E061E0E0C0E000E000E000E000E000E00FFE00E000E000E000E000E000E 000E000E000E000E000E000E000E000E000E000E007FE00F1D809C0D>I<00038003C4C00C38C0 1C3880181800381C00381C00381C00381C001818001C38000C300013C000100000300000180000 1FF8001FFF001FFF803003806001C0C000C0C000C0C000C06001803003001C0E0007F800121C7F 9215>II<18003C003C0018000000000000000000000000 000000FC001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C00FF80 091D7F9C0C>I108 DII<03F0000E1C00180600300300700380600180E001C0E001C0E001C0E001C0E001C0E001C0 6001807003803003001806000E1C0003F00012127F9115>II114 D<1F9030704030C010C010E010F8007F803FE00FF000F880388018C018C018E010D0608FC00D12 7F9110>I<04000400040004000C000C001C003C00FFE01C001C001C001C001C001C001C001C00 1C001C101C101C101C101C100C100E2003C00C1A7F9910>IIII121 D E /Fh 8 58 df<1F0060C06060F070F030603000700070006000C001C0018002000400081010 1020207FE0FFE00C137E9211>50 D<0FC030707038703870380038003000E00FC0007000380018 001C601CF01CF018E03860701FC00E137F9211>I<006000E000E00160026006600C6008601060 20606060C060FFFC0060006000600060006003FC0E137F9211>I<60607FC07F80440040004000 40004F0070C040E0006000700070E070E070E06040E021C01F000C137E9211>I<07C00C201070 207060006000C000CF00D0C0E060C020C030C030C03040306020206010C00F000C137E9211>I< 40007FFC7FF8401080108020004000800100010003000200060006000E000E000E000E000E0004 000E147E9311>I<0FC0107020186018601870183C303F600F800FE031F06078C01CC00CC00CC0 0C601830300FC00E137F9211>I<0F00308060404060C020C030C030C0304030607030B00F3000 3000200060E040E08041003E000C137E9211>I E /Fi 4 113 df<03800000E00000F000007000 007000007800003800003800003C00001C00001C00001C00001E00000E00000E00000F00000700 000700000780000780000F80001B800031C00021C00041C000C1E00180E00300E00600F00C0070 1C0070380078700038E00038C0001C16237DA21C>21 D<00C00C01C01C01C01C03803803803803 80380380380700700700700700700700700E00E00E00E00E00E00E00E11E01C21E01C21E03C21E 04C43F08C439F038380000380000700000700000700000700000E00000E00000E00000E00000C0 000018207E941D>I<70F8F8F87005057C840E>58 D<03C0F004631C04740E08780E0870070870 0708700F00E00F00E00F00E00F00E00F01C01E01C01E01C01E01C03C03803803803803C07003C0 E0072180071E000700000700000E00000E00000E00000E00001C00001C00001C0000FFC000181F 819418>112 D E /Fj 35 122 df<00001FFC00000001FFFF00000007FFFF8000001FF807C000 007FC003E00000FF0007F00000FE000FF00001FE000FF00003FC000FF00003FC000FF00003FC00 0FF00003FC0007E00003FC0001800003FC0000000003FC0000000003FC0000000003FC00000000 03FC00FFF800FFFFFFFFF800FFFFFFFFF800FFFFFFFFF80003FC0007F80003FC0007F80003FC00 07F80003FC0007F80003FC0007F80003FC0007F80003FC0007F80003FC0007F80003FC0007F800 03FC0007F80003FC0007F80003FC0007F80003FC0007F80003FC0007F80003FC0007F80003FC00 07F80003FC0007F80003FC0007F80003FC0007F80003FC0007F80003FC0007F80003FC0007F800 03FC0007F80003FC0007F80003FC0007F80003FC0007F8007FFFE0FFFFC07FFFE0FFFFC07FFFE0 FFFFC02A327FB12E>12 D45 D<0001E0000003E000000FE000007FE0001FFFE000FFFFE000FFBFE000E03FE000003FE000003F E000003FE000003FE000003FE000003FE000003FE000003FE000003FE000003FE000003FE00000 3FE000003FE000003FE000003FE000003FE000003FE000003FE000003FE000003FE000003FE000 003FE000003FE000003FE000003FE000003FE000003FE000003FE000003FE000003FE000003FE0 00003FE000003FE000003FE000003FE0007FFFFFF07FFFFFF07FFFFFF01C2E7AAD29>49 D<003FF00001FFFE0007FFFF800FC07FE01E001FF03C000FF87F0007FC7F8007FEFFC007FEFFC0 03FEFFC003FFFFC003FF7F8003FF7F8003FF3F0003FF000003FF000003FE000003FE000007FC00 0007FC00000FF800000FF000001FE000001FC000003F8000007F000000FE000001F8000001F000 0003E00000078007000F0007001E0007003C000F0078000E00F0000E01C0001E03FFFFFE07FFFF FE0FFFFFFE1FFFFFFE3FFFFFFE7FFFFFFCFFFFFFFCFFFFFFFCFFFFFFFC202E7CAD29>I<000FFC 0000007FFF800001F01FE00003C00FF000070007F8000FE007FC000FF007FC001FF007FE001FF8 07FE001FF807FE001FF807FE001FF807FE000FF007FC0007E007FC00018007FC0000000FF80000 000FF00000001FE00000001FC00000007F8000001FFE0000001FFC0000001FFF800000001FF000 000007F800000003FC00000003FE00000003FF00000001FF80000001FF800E0001FFC03F8001FF C07FC001FFC07FC001FFC0FFE001FFC0FFE001FFC0FFE001FF80FFE001FF80FFC003FF007F8003 FF003F0003FE001F0007FC000FE01FF80007FFFFE00001FFFF8000001FFC0000222E7DAD29>I< 0000007800000000F800000001F800000003F800000007F800000007F80000000FF80000001FF8 0000003FF80000007FF800000077F8000000F7F8000001E7F8000003C7F800000787F800000707 F800000F07F800001E07F800003C07F800007807F800007007F80000F007F80001E007F80003C0 07F800078007F8000F0007F8000F0007F8001E0007F8003C0007F800780007F800F00007F800FF FFFFFFF0FFFFFFFFF0FFFFFFFFF000000FF80000000FF80000000FF80000000FF80000000FF800 00000FF80000000FF80000000FF80000000FF800000FFFFFF0000FFFFFF0000FFFFFF0242E7EAD 29>I<0C0000380FC003F80FFFFFF80FFFFFF00FFFFFE00FFFFFC00FFFFF800FFFFE000FFFFC00 0FFFF0000FFF00000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0FF8 000F7FFF000FFFFFC00FF01FE00F800FF00F0007F80E0007FC000003FC000003FE000003FE0000 03FF000003FF1E0003FF3F0003FF7F8003FFFF8003FFFFC003FFFFC003FEFF8003FEFF8003FE7F 0007FC7C0007F83C000FF01E001FE00FC07FC007FFFF8001FFFE00003FE000202E7CAD29>I<00 0003FF80018000003FFFF003800001FFFFFC0F800007FF007F1F80001FF8000FBF80003FE00003 FF8000FF800000FF8001FF0000007F8003FE0000003F8007FC0000003F8007FC0000001F800FF8 0000001F801FF80000000F801FF00000000F803FF000000007803FF000000007807FF000000007 807FE000000007807FE000000000007FE00000000000FFE00000000000FFE00000000000FFE000 00000000FFE00000000000FFE00000000000FFE00000000000FFE00000000000FFE00000000000 FFE000000000007FE000000000007FE000000000007FE000000000007FF000000003803FF00000 0003803FF000000003801FF000000003801FF800000007800FF8000000070007FC000000070007 FC0000000E0003FE0000001E0001FF0000003C0000FF8000007800003FE00000F000001FF80003 E0000007FF003F80000001FFFFFE000000003FFFF80000000003FF80000031317BB03C>67 DI< FFFFFFFFFFF0FFFFFFFFFFF0FFFFFFFFFFF000FFC0003FF000FFC00007F800FFC00003F800FFC0 0000F800FFC00000F800FFC000007800FFC000007800FFC000003800FFC000003800FFC0000038 00FFC000001C00FFC000001C00FFC007001C00FFC007001C00FFC007000000FFC007000000FFC0 07000000FFC00F000000FFC01F000000FFC03F000000FFFFFF000000FFFFFF000000FFFFFF0000 00FFC03F000000FFC01F000000FFC00F000000FFC007000000FFC007000000FFC007000000FFC0 07000000FFC007000000FFC000000000FFC000000000FFC000000000FFC000000000FFC0000000 00FFC000000000FFC000000000FFC000000000FFC000000000FFC000000000FFC000000000FFC0 000000FFFFFFF00000FFFFFFF00000FFFFFFF000002E317EB034>70 D<000003FF80018000003F FFF003800001FFFFFC0F800007FF007F1F80001FF8000FBF80003FE00003FF8000FF800000FF80 01FF0000007F8003FE0000003F8007FC0000003F8007FC0000001F800FF80000001F801FF80000 000F801FF00000000F803FF000000007803FF000000007807FF000000007807FE000000007807F E000000000007FE00000000000FFE00000000000FFE00000000000FFE00000000000FFE0000000 0000FFE00000000000FFE00000000000FFE00000000000FFE00000000000FFE00007FFFFFE7FE0 0007FFFFFE7FE00007FFFFFE7FE0000001FF807FF0000001FF803FF0000001FF803FF0000001FF 801FF0000001FF801FF8000001FF800FF8000001FF8007FC000001FF8007FC000001FF8003FE00 0001FF8001FF000001FF8000FF800001FF80003FE00003FF80001FF80007FF800007FF803F3F80 0001FFFFFE1F8000003FFFF80780000003FFC0018037317BB041>I73 D76 DI<00000FFE0000000000FFFFE000000007FFFFFC 0000001FFC07FF0000003FE000FF800000FF80003FE00001FF00001FF00003FE00000FF80007FC 000007FC0007FC000007FC000FF8000003FE001FF8000003FF001FF0000001FF003FF0000001FF 803FF0000001FF803FF0000001FF807FE0000000FFC07FE0000000FFC07FE0000000FFC0FFE000 0000FFE0FFE0000000FFE0FFE0000000FFE0FFE0000000FFE0FFE0000000FFE0FFE0000000FFE0 FFE0000000FFE0FFE0000000FFE0FFE0000000FFE0FFE0000000FFE0FFE0000000FFE07FE00000 00FFC07FE0000000FFC07FF0000001FFC07FF0000001FFC03FF0000001FF803FF0000001FF801F F8000003FF001FF8000003FF000FFC000007FE000FFC000007FE0007FE00000FFC0003FF00001F F80001FF80003FF00000FFC0007FE000003FE000FF8000001FFC07FF00000007FFFFFC00000000 FFFFE0000000000FFE00000033317BB03E>79 D82 D<001FF0018000FFFF03 8003FFFFC78007F00FFF800F8001FF801F00007F803F00001F803E00000F807E00000F807E0000 0780FE00000780FE00000780FE00000380FF00000380FF00000380FF80000000FFE00000007FFC 0000007FFFE000007FFFFE00003FFFFFC0001FFFFFF0001FFFFFF8000FFFFFFC0003FFFFFE0001 FFFFFF00007FFFFF80001FFFFF800000FFFFC0000007FFC0000000FFE00000003FE00000003FE0 0000001FE06000001FE0E000000FE0E000000FE0E000000FE0E000000FC0F000000FC0F000000F C0F800001F80FC00001F80FF00003F00FFC0007E00FFFC01FC00F1FFFFF800E03FFFE000C007FF 000023317BB02E>I<007FF8000003FFFF000007FFFFC0000FE01FE0001FF007F0001FF003F800 1FF003FC001FF001FE000FE001FE0007C001FE00010001FE00000001FE00000001FE000001FFFE 00003FFFFE0001FFF1FE0007FE01FE000FF001FE001FC001FE003F8001FE007F8001FE00FF0001 FE00FF0001FE00FF0001FE00FF0001FE00FF0003FE007F8003FE007FC00EFE003FF03CFF000FFF F87FF807FFF03FF800FF800FF825207E9F28>97 D<01F8000000FFF8000000FFF8000000FFF800 00000FF800000007F800000007F800000007F800000007F800000007F800000007F800000007F8 00000007F800000007F800000007F800000007F800000007F800000007F800000007F80FF00007 F87FFE0007F9FFFF8007FFE03FC007FF000FE007FE0007F007F80003F807F80003FC07F80003FC 07F80001FE07F80001FE07F80001FE07F80001FF07F80001FF07F80001FF07F80001FF07F80001 FF07F80001FF07F80001FF07F80001FF07F80001FE07F80001FE07F80001FE07F80003FC07F800 03FC07FC0007F807FE0007F007F7001FE007E3E07FC007C1FFFF0007807FFE0007001FE0002832 7EB12E>I<0007FF00007FFFE000FFFFF003FC03F807F007FC0FE007FC1FE007FC3FC007FC3FC0 03F87FC001F07F8000407F800000FF800000FF800000FF800000FF800000FF800000FF800000FF 800000FF8000007F8000007FC000007FC000003FC0000E3FE0000E1FE0001C0FF0001C07F80078 03FF01F000FFFFE0007FFF800007FC001F207D9F25>I<00000007E0000003FFE0000003FFE000 0003FFE00000003FE00000001FE00000001FE00000001FE00000001FE00000001FE00000001FE0 0000001FE00000001FE00000001FE00000001FE00000001FE00000001FE00000001FE0000FF81F E0007FFF1FE001FFFFDFE003FE03FFE007F800FFE00FE0003FE01FE0001FE03FC0001FE03FC000 1FE07F80001FE07F80001FE07F80001FE0FF80001FE0FF80001FE0FF80001FE0FF80001FE0FF80 001FE0FF80001FE0FF80001FE0FF80001FE07F80001FE07F80001FE07F80001FE03FC0001FE03F C0001FE01FC0003FE00FE0007FE007F001FFE003FC07DFF001FFFF9FFF007FFE1FFF000FF01FFF 28327DB12E>I<0007FC0000003FFF800000FFFFE00003FC07F00007F801F8000FE000FC001FE0 007E003FC0007E003FC0003F007FC0003F007F80003F007F80003F80FF80003F80FF80003F80FF FFFFFF80FFFFFFFF80FFFFFFFF80FF80000000FF80000000FF800000007F800000007F80000000 3FC00000003FC00003801FC00003801FE00007800FF0000F0007F8001E0003FE00FC0000FFFFF8 00003FFFE0000003FF000021207E9F26>I<0000FF000007FFC0001FFFE0003FC7F0007F0FF800 FE0FF801FE0FF801FC0FF803FC07F003FC03E003FC01C003FC000003FC000003FC000003FC0000 03FC000003FC000003FC0000FFFFF800FFFFF800FFFFF80003FC000003FC000003FC000003FC00 0003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC 000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003FC000003 FC000003FC000003FC00007FFFF0007FFFF0007FFFF0001D327EB119>I<001FF007E000FFFE3F F001FFFF7FF807F83FF1F80FE00FE1F80FE00FE0F01FC007F0601FC007F0003FC007F8003FC007 F8003FC007F8003FC007F8003FC007F8001FC007F0001FC007F0000FE00FE0000FE00FE00007F8 3FC00007FFFF000006FFFE00000E1FF000000E000000001E000000001E000000001F000000001F 800000001FFFFFC0000FFFFFF8000FFFFFFE0007FFFFFF0003FFFFFF8007FFFFFFC01FFFFFFFE0 3F00007FE07E00000FF0FC000007F0FC000003F0FC000003F0FC000003F0FC000003F07E000007 E03F00000FC01FC0003F800FF801FF0007FFFFFE0000FFFFF000001FFF8000252F7E9F29>I<03 C0000FF0000FF0001FF8001FF8001FFC001FF8001FF8000FF0000FF00003C00000000000000000 000000000000000000000000000000000001F800FFF800FFF800FFF8000FF80007F80007F80007 F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007 F80007F80007F80007F80007F80007F80007F80007F80007F800FFFF80FFFF80FFFF8011337DB2 17>105 D<01F800FFF800FFF800FFF8000FF80007F80007F80007F80007F80007F80007F80007 F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007 F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007 F80007F80007F80007F80007F80007F80007F80007F80007F80007F800FFFFC0FFFFC0FFFFC012 327DB117>108 D<03F007F8000FF000FFF03FFF007FFE00FFF07FFF80FFFF00FFF0F03FC1E07F 800FF1C01FE3803FC007F3000FE6001FC007F6000FFC001FE007FE000FFC001FE007FC000FF800 1FE007FC000FF8001FE007F8000FF0001FE007F8000FF0001FE007F8000FF0001FE007F8000FF0 001FE007F8000FF0001FE007F8000FF0001FE007F8000FF0001FE007F8000FF0001FE007F8000F F0001FE007F8000FF0001FE007F8000FF0001FE007F8000FF0001FE007F8000FF0001FE007F800 0FF0001FE007F8000FF0001FE007F8000FF0001FE007F8000FF0001FE007F8000FF0001FE007F8 000FF0001FE0FFFFC1FFFF83FFFFFFFFC1FFFF83FFFFFFFFC1FFFF83FFFF40207D9F47>I<03F0 07F80000FFF03FFF0000FFF07FFF8000FFF0F03FC0000FF1C01FE00007F3000FE00007F6000FF0 0007FE000FF00007FC000FF00007FC000FF00007F8000FF00007F8000FF00007F8000FF00007F8 000FF00007F8000FF00007F8000FF00007F8000FF00007F8000FF00007F8000FF00007F8000FF0 0007F8000FF00007F8000FF00007F8000FF00007F8000FF00007F8000FF00007F8000FF00007F8 000FF00007F8000FF00007F8000FF000FFFFC1FFFF80FFFFC1FFFF80FFFFC1FFFF8029207D9F2E >I<0007FE0000003FFFC00000FFFFF00003FC03FC0007F000FE000FE0007F001FC0003F803FC0 003FC03FC0003FC07F80001FE07F80001FE07F80001FE0FF80001FF0FF80001FF0FF80001FF0FF 80001FF0FF80001FF0FF80001FF0FF80001FF0FF80001FF07F80001FE07F80001FE07F80001FE0 3FC0003FC03FC0003FC01FE0007F800FE0007F0007F801FE0003FE07FC0001FFFFF800003FFFC0 000007FE000024207E9F29>I<01F80FF000FFF87FFE00FFF9FFFF80FFFFE07FC00FFF001FE007 FE000FF007F80007F807F80007FC07F80003FC07F80003FE07F80003FE07F80001FE07F80001FF 07F80001FF07F80001FF07F80001FF07F80001FF07F80001FF07F80001FF07F80001FF07F80001 FE07F80003FE07F80003FE07F80003FC07F80007FC07FC0007F807FE000FF007FF001FE007FBE0 7FC007F9FFFF0007F87FFE0007F81FE00007F800000007F800000007F800000007F800000007F8 00000007F800000007F800000007F800000007F800000007F800000007F8000000FFFFC00000FF FFC00000FFFFC00000282E7E9F2E>I<03F03F00FFF07FC0FFF1FFE0FFF3C7F00FF38FF807F70F F807F60FF807FE0FF807FC07F007FC03E007FC008007F8000007F8000007F8000007F8000007F8 000007F8000007F8000007F8000007F8000007F8000007F8000007F8000007F8000007F8000007 F8000007F8000007F8000007F80000FFFFE000FFFFE000FFFFE0001D207E9F22>114 D<00FF870007FFEF001FFFFF003F007F003C001F0078000F00F8000700F8000700F8000700FC00 0700FF000000FFF800007FFFC0003FFFF0003FFFFC000FFFFE0007FFFF0001FFFF80001FFF8000 00FFC000001FC060000FC0E00007C0E00007C0F00007C0F8000780F8000F80FE000F00FF803E00 FFFFFC00F3FFF800C07FC0001A207D9F21>I<0038000038000038000038000038000078000078 0000780000F80000F80001F80003F80007F8001FF800FFFFFEFFFFFEFFFFFE07F80007F80007F8 0007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F80007F8 0007F80707F80707F80707F80707F80707F80707F80703F80E03FC0E01FE1C00FFF8007FF0000F E0182E7EAD20>I<01F80003F000FFF801FFF000FFF801FFF000FFF801FFF0000FF8001FF00007 F8000FF00007F8000FF00007F8000FF00007F8000FF00007F8000FF00007F8000FF00007F8000F F00007F8000FF00007F8000FF00007F8000FF00007F8000FF00007F8000FF00007F8000FF00007 F8000FF00007F8000FF00007F8000FF00007F8000FF00007F8000FF00007F8000FF00007F8001F F00007F8001FF00003F8003FF00003F8006FF00001FE03CFF80000FFFF8FFF80007FFF0FFF8000 0FFC0FFF8029207D9F2E>I121 D E /Fk 34 122 df45 D<07000F800F800F000E00000000000000000000000000000000000000000000007000F800F800 F000E00009157A940F>58 D<0000030000000300000007000000070000000F0000000F0000001F 0000002F0000002F0000004F0000004F8000008780000087800001078000020780000207800004 0780000407800008078000080780001007800030078000200780007FFF80004007C0008007C000 8003C0010003C0030003C0020003C0040003C0040003C00C0003C03C0007C0FF003FFC1E237DA2 24>65 D<00007F00800003808100000E00630000380027000070001F0000E0000E0001C0000E00 0380000E000700000E000F000004000E000004001E000004003C000004003C0000080078000000 0078000000007800000000F000000000F000000000F000000000F000000000F000000000E00000 0000E000002000E000002000E000004000E000004000F000008000700000800070000100003800 02000018000400001C0008000006003000000381C0000000FE000000212479A223>67 D<00FFFFF000000F003C00000F000E00000F000700001E000380001E000380001E0001C0001E00 01C0003C0001C0003C0001E0003C0001E0003C0001E000780001E000780001E000780001E00078 0001E000F00003C000F00003C000F00003C000F00003C001E000078001E000078001E000070001 E0000F0003C0000E0003C0001C0003C0003C0003C00038000780007000078000E000078001C000 07800700000F801C0000FFFFF0000023227DA125>I<00FFFFFF000F000F000F0003000F000300 1E0003001E0003001E0002001E0002003C0002003C0002003C0102003C01000078020000780200 0078060000780E0000FFFC0000F00C0000F00C0000F00C0001E0080001E0080001E0080001E000 0003C0000003C0000003C0000003C00000078000000780000007800000078000000F800000FFFC 000020227DA120>70 D<00007F00800003808100000E00630000380027000070001F0000E0000E 0001C0000E000380000E000700000E000F000004000E000004001E000004003C000004003C0000 0800780000000078000000007800000000F000000000F000000000F000000000F000000000F000 3FFC00E00001E000E00001E000E00001E000E00003C000E00003C000F00003C000700003C00070 00078000380007800018000F80001C0013800006002300000381C1000000FE000000212479A226 >I<00FFF8000F00000F00000F00001E00001E00001E00001E00003C00003C00003C00003C0000 780000780000780000780000F00000F00000F00000F00001E00001E00001E00001E00003C00003 C00003C00003C0000780000780000780000780000F8000FFF80015227DA113>73 D<00FFFC00000F8000000F0000000F0000001E0000001E0000001E0000001E0000003C0000003C 0000003C0000003C00000078000000780000007800000078000000F0000000F0000000F0000000 F0000001E0000001E0000001E0002001E0002003C0004003C0004003C0008003C0008007800180 078001000780030007800F000F803E00FFFFFE001B227DA11F>76 D<00FF800007FC000F80000F 80000F80001780000F80001780001780002F000013C0002F000013C0004F000013C0008F000023 C0009E000023C0011E000023C0011E000023C0021E000043C0043C000043C0043C000043C0083C 000041E0083C000081E01078000081E02078000081E02078000081E04078000101E040F0000101 E080F0000101E100F0000101E100F0000200F201E0000200F201E0000200F401E0000200F801E0 000400F803C0000400F003C0000400F003C0000C00E003C0001E00C007C000FFC0C07FFC002E22 7DA12C>I<0000FE0000078380000C00E0003800700070003800E0003801C0001C0380001C0700 001C0F00001E1E00001E1C00001E3C00001E3C00001E7800001E7800001E7800001EF000003CF0 00003CF000003CF0000078F0000078E0000078E00000F0E00000F0E00001E0E00001C0F00003C0 F00007807000070078000E0038001C001C0038000E00E0000703800001FC00001F2479A225>79 D<00FFFFE0000F0038000F001E000F000E001E0007001E0007001E0007001E0007003C000F003C 000F003C000F003C001E0078001E0078003C00780078007800E000F003C000FFFE0000F0000000 F0000001E0000001E0000001E0000001E0000003C0000003C0000003C0000003C0000007800000 0780000007800000078000000F800000FFF8000020227DA121>I<0001F020000E0C40001802C0 003001C0006001C000E0018000C0018001C0018001C0018003C0010003C0010003C0000003C000 0003E0000001F8000001FF000000FFE000007FF000001FF8000003FC0000007C0000003C000000 1E0000001E0000001E0020001C0020001C0020001C002000180060003800600030007000600070 00C000C8018000C607000081FC00001B247DA21B>83 D86 D<00F8C00185C00705C00E03800E03801C03803C0380380700 780700780700780700F00E00F00E00F00E00F00E10F01C20701C20703C20305C40308C400F0780 14157B9419>97 D<03C03F8003800380038007000700070007000E000E000E000E001C001CF81D 0C1E0E3C0638073807380F700F700F700F700FE01EE01EE01EE03CE038E038607060E031C01F00 10237BA216>I<007E0001C1000301800703800E07801C07803C00003800007800007800007800 00F00000F00000F00000F00000F00100700100700200300C001830000FC00011157B9416>I<00 003C0003F80000380000380000380000700000700000700000700000E00000E00000E00000E000 01C000F9C00185C00705C00E03800E03801C03803C0380380700780700780700780700F00E00F0 0E00F00E00F00E10F01C20701C20703C20305C40308C400F078016237BA219>I<00F803840E02 1C023C0238027804F018FFE0F000F000E000E000E000E000E002E0026004701830600F800F157A 9416>I<00003E0000470000CF00018F0001860003800003800003800007000007000007000007 00000700000E0000FFF0000E00000E00000E00001C00001C00001C00001C00001C000038000038 0000380000380000380000700000700000700000700000700000E00000E00000E00000E00000C0 0001C00001C000718000F18000F300006200003C0000182D82A20F>I<001F180030B800E0B801 C07001C0700380700780700700E00F00E00F00E00F00E01E01C01E01C01E01C01E01C01E03800E 03800E0780060B8006170001E700000700000700000E00000E00000E00701C00F01800F0300060 E0003F8000151F7E9416>I<00F0000FE00000E00000E00000E00001C00001C00001C00001C000 038000038000038000038000070000071F0007218007C0C00F00E00F00E00E00E00E00E01C01C0 1C01C01C01C01C01C0380380380380380380380704700708700E08700E10700610E006206003C0 16237DA219>I<00C001E001C001C0000000000000000000000000000000001C00230043004300 8700870087000E000E001C001C001C00380038003840708070807080710032001C000B217BA00F >I<01E01FC001C001C001C0038003800380038007000700070007000E000E000E000E001C001C 001C001C0038003800380038007000700070007100E200E200E200E200640038000B237CA20C> 108 D<1C0F80F8002610C10C00476066060087807807008780780700870070070087007007000E 00E00E000E00E00E000E00E00E000E00E00E001C01C01C001C01C01C001C01C01C001C01C03820 380380384038038070403803807080380380308070070031003003001E0023157B9428>I<1C0F 002631C04740C08780E08780E08700E08700E00E01C00E01C00E01C00E01C01C03801C03801C03 801C0704380708380E08380E103806107006203003C016157B941B>I<007E0001C30003818007 01C00E01C01C01E03C01E03801E07801E07801E07801E0F003C0F003C0F00380F0078070070070 0E00700C0030180018700007C00013157B9419>I<01C1F002621804741C08780C08700E08700E 08701E00E01E00E01E00E01E00E01E01C03C01C03C01C03C01C07803807003807003C0E003C1C0 072380071E000700000700000E00000E00000E00000E00001C00001C00001C0000FFC000171F7F 9419>I<1C1F002620804741C08783C08703C08701808700000E00000E00000E00000E00001C00 001C00001C00001C000038000038000038000038000070000030000012157B9415>114 D<00FC000183000200800401800C03800C03000C00000F00000FF00007FC0003FE00003E00000F 00000700700700F00600F00600E004004008002030001FC00011157D9414>I<00C001C001C001 C001C003800380038003800700FFF8070007000E000E000E000E001C001C001C001C0038003800 38003810702070207040708031001E000D1F7C9E10>I<1E00602300E04380E04381C08381C087 01C08701C00703800E03800E03800E03801C07001C07001C07001C07081C0E10180E101C0E101C 1E200C262007C3C015157B941A>I<1E03802307C04387C04383C08381C08700C08700C0070080 0E00800E00800E00801C01001C01001C01001C02001C02001C04001C08001C08000C300003C000 12157B9416>I<1E00302300704380704380E08380E08700E08700E00701C00E01C00E01C00E01 C01C03801C03801C03801C03801C07001C07001C07001C0F000C3E0003CE00000E00000E00001C 00601C00F03800F03000E0600080C0004380003E0000141F7B9418>121 D E /Fl 80 127 df<001F83E000706E3000C07C780180F8780380F07807007000070070000700 7000070070000700700007007000070070000700700007007000FFFFFFC0070070000700700007 007000070070000700700007007000070070000700700007007000070070000700700007007000 070070000700700007007000070070000700700007007000070078007FE3FF801D2380A21C>11 D<001FC0000070200000C010000180380003807800070078000700300007000000070000000700 000007000000070000000700000007000000FFFFF8000700780007003800070038000700380007 003800070038000700380007003800070038000700380007003800070038000700380007003800 07003800070038000700380007003800070038007FE1FF80192380A21B>I<001FD80000703800 00C078000180780003807800070038000700380007003800070038000700380007003800070038 000700380007003800FFFFF8000700380007003800070038000700380007003800070038000700 380007003800070038000700380007003800070038000700380007003800070038000700380007 00380007003800070038007FF3FF80192380A21B>I<000FC07F00007031C08000E00B00400180 1E00E003803E01E007003C01E007001C00C007001C000007001C000007001C000007001C000007 001C000007001C000007001C0000FFFFFFFFE007001C01E007001C00E007001C00E007001C00E0 07001C00E007001C00E007001C00E007001C00E007001C00E007001C00E007001C00E007001C00 E007001C00E007001C00E007001C00E007001C00E007001C00E007001C00E007001C00E07FF1FF CFFE272380A229>I<07070F1E1C38604080080976A218>19 D<70F8FCFC740404040408081010 2040060F7CA20E>39 D<00200040008001000300060004000C000C001800180030003000300070 00600060006000E000E000E000E000E000E000E000E000E000E000E000E000E000E00060006000 60007000300030003000180018000C000C0004000600030001000080004000200B327CA413>I< 800040002000100018000C000400060006000300030001800180018001C000C000C000C000E000 E000E000E000E000E000E000E000E000E000E000E000E000E000C000C000C001C0018001800180 030003000600060004000C00180010002000400080000B327DA413>I<70F8FCFC740404040408 0810102040060F7C840E>44 DI<70F8F8F87005057C840E>I<00008000 0180000180000300000300000300000600000600000600000C00000C00000C0000180000180000 180000300000300000300000600000600000600000C00000C00000C00001800001800001800001 80000300000300000300000600000600000600000C00000C00000C000018000018000018000030 0000300000300000600000600000600000C00000C00000C0000011317DA418>I<01F000071C00 0C06001803003803803803807001C07001C07001C07001C0F001E0F001E0F001E0F001E0F001E0 F001E0F001E0F001E0F001E0F001E0F001E0F001E0F001E0F001E07001C07001C07001C07803C0 3803803803801C07000C0600071C0001F00013227EA018>I<008003800F80F380038003800380 038003800380038003800380038003800380038003800380038003800380038003800380038003 80038003800380038007C0FFFE0F217CA018>I<03F0000C1C001007002007804003C04003C080 03E0F003E0F801E0F801E0F801E02003E00003E00003C00003C0000780000700000E00001C0000 180000300000600000C0000180000100000200200400200800201800603000403FFFC07FFFC0FF FFC013217EA018>I<03F8000C1E001007002007804007C07807C07803C07807C03807C0000780 000780000700000F00000E0000380003F000001C00000F000007800007800003C00003C00003E0 2003E07003E0F803E0F803E0F003C04003C0400780200780100F000C1C0003F00013227EA018> I<000200000600000E00000E00001E00001E00002E00004E00004E00008E00008E00010E00020E 00020E00040E00040E00080E00100E00100E00200E00200E00400E00800E00FFFFF8000E00000E 00000E00000E00000E00000E00000E00001F0001FFF015217FA018>I<1000801E07001FFF001F FE001FF80013E00010000010000010000010000010000010000010F800130E0014070018038010 03800001C00001C00001E00001E00001E00001E07001E0F001E0F001E0E001C08001C04003C040 03802007001006000C1C0003F00013227EA018>I<007E0001C1000300800601C00E03C01C03C0 180180380000380000780000700000700000F0F800F30C00F40600F40300F80380F801C0F001C0 F001E0F001E0F001E0F001E0F001E07001E07001E07001E03801C03801C01803801C03000C0600 070C0001F00013227EA018>I<4000006000007FFFE07FFFC07FFFC0400080C001008001008002 0080020000040000080000080000100000300000200000600000600000600000E00000C00000C0 0001C00001C00001C00001C00003C00003C00003C00003C00003C00003C00003C00003C0000180 0013237DA118>I<01F800060E000803001001802001802000C06000C06000C06000C07000C078 01803E01003F02001FC4000FF80003F80003FC00067F00083F80100F803007C06001C06000E0C0 00E0C00060C00060C00060C000606000406000C03000801803000E0E0003F00013227EA018>I< 01F000060C000C0600180700380380700380700380F001C0F001C0F001C0F001E0F001E0F001E0 F001E0F001E07001E07003E03803E01805E00C05E00619E003E1E00001C00001C00001C0000380 000380300300780700780600700C002018001030000FC00013227EA018>I<70F8F8F870000000 000000000000000070F8F8F87005157C940E>I<70F8F8F870000000000000000000000070F8F8 F87808080808101010204040051F7C940E>I61 D<000FE00000701C0000800200030001800400004008000020080000201007C010201830082030 08084060040440C0078441C0038481C00382838003828380038283800382838003828380038283 8003828380038281C0038241C0038240C007824060078420300B84201831881007C0F008000000 08000000040000000300000E00800078007007C0000FFC001F237DA226>64 D<0001800000018000000180000003C0000003C0000003C0000005E0000005E000000DF0000008 F0000008F0000010F800001078000010780000203C0000203C0000203C0000401E0000401E0000 401E0000800F0000800F0000FFFF000100078001000780030007C0020003C0020003C0040003E0 040001E0040001E00C0000F00C0000F03E0001F8FF800FFF20237EA225>II<0007E0100038183000E0063001C00170038000F007 0000F00E0000701E0000701C0000303C0000303C0000307C0000107800001078000010F8000000 F8000000F8000000F8000000F8000000F8000000F8000000F800000078000000780000107C0000 103C0000103C0000101C0000201E0000200E000040070000400380008001C0010000E002000038 1C000007E0001C247DA223>II< FFFFFFC00F8007C0078001C0078000C00780004007800040078000600780002007800020078000 2007802020078020000780200007802000078060000780E00007FFE0000780E000078060000780 200007802000078020000780200807800008078000080780001007800010078000100780003007 80003007800070078000E00F8003E0FFFFFFE01D227EA121>II<0007F008003C0C1800E0021801C001B8038000F8070000780F00 00381E0000381E0000183C0000183C0000187C0000087800000878000008F8000000F8000000F8 000000F8000000F8000000F8000000F8000000F8001FFF780000F8780000787C0000783C000078 3C0000781E0000781E0000780F00007807000078038000B801C000B800E00318003C0C080007F0 0020247DA226>III<03FFF0001F00000F 00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F 00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00700F00F80F00F80F 00F80E00F01E00401C0020380018700007C00014237EA119>IIIII<000FE00000783C0000E00E0003C00780078003C00F0001E00E0000E01E0000F03C000078 3C0000787C00007C7C00007C7800003C7800003CF800003EF800003EF800003EF800003EF80000 3EF800003EF800003EF800003EF800003E7800003C7C00007C7C00007C3C0000783E0000F81E00 00F00F0001E00F0001E0078003C003C0078000E00E0000783C00000FE0001F247DA226>II82 D<03F0200C0C601802603001E07000E0600060E00060E00060E00020 E00020E00020F00000F000007800007F00003FF0001FFE000FFF0003FF80003FC00007E00001E0 0000F00000F0000070800070800070800070800070C00060C00060E000C0F000C0C80180C60700 81FC0014247DA21B>I<7FFFFFF87807807860078018400780084007800840078008C007800C80 078004800780048007800480078004000780000007800000078000000780000007800000078000 000780000007800000078000000780000007800000078000000780000007800000078000000780 000007800000078000000780000007800000078000000FC00003FFFF001E227EA123>IIII<7FF807 FF0007E001F80003C000E00003E000C00001E000800000F001000000F80300000078020000007C 040000003E0C0000001E080000001F100000000FB000000007A000000007C000000003E0000000 01E000000001F000000003F80000000278000000047C0000000C3E000000081E000000101F0000 00300F80000020078000004007C00000C003E000008001E000010001F000030000F000070000F8 001F8001FC00FFE007FFC022227FA125>II< 7FFFFE7E003E78003C7000786000784000F0C000F0C001E08003C08003C0800780000780000F00 001F00001E00003C00003C0000780000780000F00001F00001E00103C00103C001078001078003 0F00031E00021E00023C00063C000E78001EF8007EFFFFFE18227DA11E>II93 D<0FE0001838003C0C003C0E00 18070000070000070000070000FF0007C7001E07003C0700780700700700F00708F00708F00708 F00F087817083C23900FC1E015157E9418>97 D<0E0000FE00001E00000E00000E00000E00000E 00000E00000E00000E00000E00000E00000E00000E00000E1F000E61C00E80600F00300E00380E 003C0E001C0E001E0E001E0E001E0E001E0E001E0E001E0E001E0E001C0E003C0E00380F00700C 80600C41C0083F0017237FA21B>I<01FE000703000C07801C0780380300780000700000F00000 F00000F00000F00000F00000F00000F000007000007800403800401C00800C010007060001F800 12157E9416>I<0000E0000FE00001E00000E00000E00000E00000E00000E00000E00000E00000 E00000E00000E00000E001F8E00704E00C02E01C01E03800E07800E07000E0F000E0F000E0F000 E0F000E0F000E0F000E0F000E07000E07800E03800E01801E00C02E0070CF001F0FE17237EA21B >I<01FC000707000C03801C01C03801C07801E07000E0F000E0FFFFE0F00000F00000F00000F0 0000F000007000007800203800201C00400E008007030000FC0013157F9416>I<003C00C6018F 038F030F070007000700070007000700070007000700FFF8070007000700070007000700070007 00070007000700070007000700070007000700070007807FF8102380A20F>I<00007001F19807 1E180E0E181C07001C07003C07803C07803C07803C07801C07001C07000E0E000F1C0019F00010 00001000001800001800001FFE000FFFC00FFFE03800F0600030400018C00018C00018C0001860 00306000303800E00E038003FE0015217F9518>I<0E0000FE00001E00000E00000E00000E0000 0E00000E00000E00000E00000E00000E00000E00000E00000E1F800E60C00E80E00F00700F0070 0E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E0070 0E00700E0070FFE7FF18237FA21B>I<1C003E003E003E001C0000000000000000000000000000 0000000E00FE001E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E00 0E000E00FFC00A227FA10E>I<01C003E003E003E001C000000000000000000000000000000000 01E00FE001E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000 E000E000E000E000E000E000E060E0F0C0F18061803E000B2C82A10F>I<0E0000FE00001E0000 0E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E03FC0E01F0 0E01C00E01800E02000E04000E08000E10000E38000EF8000F1C000E1E000E0E000E07000E0780 0E03C00E01C00E01E00E00F00E00F8FFE3FE17237FA21A>I<0E00FE001E000E000E000E000E00 0E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E 000E000E000E000E000E000E000E00FFE00B237FA20E>I<0E1FC07F00FE60E183801E807201C0 0F003C00E00F003C00E00E003800E00E003800E00E003800E00E003800E00E003800E00E003800 E00E003800E00E003800E00E003800E00E003800E00E003800E00E003800E00E003800E00E0038 00E00E003800E0FFE3FF8FFE27157F942A>I<0E1F80FE60C01E80E00F00700F00700E00700E00 700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00 70FFE7FF18157F941B>I<01FC000707000C01801800C03800E0700070700070F00078F00078F0 0078F00078F00078F00078F000787000707800F03800E01C01C00E038007070001FC0015157F94 18>I<0E1F00FE61C00E80600F00700E00380E003C0E001C0E001E0E001E0E001E0E001E0E001E 0E001E0E001E0E003C0E003C0E00380F00700E80E00E41C00E3F000E00000E00000E00000E0000 0E00000E00000E00000E00000E0000FFE000171F7F941B>I<01F8200704600E02601C01603801 E07800E07800E0F000E0F000E0F000E0F000E0F000E0F000E0F000E07000E07800E03801E01C01 E00C02E0070CE001F0E00000E00000E00000E00000E00000E00000E00000E00000E00000E0000F FE171F7E941A>I<0E3CFE461E8F0F0F0F060F000E000E000E000E000E000E000E000E000E000E 000E000E000E000F00FFF010157F9413>I<0F8830786018C018C008C008E008F0007F803FE00F F001F8003C801C800C800CC00CC008E018D0308FC00E157E9413>I<0200020002000200060006 0006000E001E003E00FFF80E000E000E000E000E000E000E000E000E000E000E000E040E040E04 0E040E040E040708030801F00E1F7F9E13>I<0E0070FE07F01E00F00E00700E00700E00700E00 700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00F00E00F00601700382 7800FC7F18157F941B>IIIII<3FFFC0380380300780 200700600E00401C00403C0040380000700000E00001E00001C0000380400700400F00400E00C0 1C0080380080780180700780FFFF8012157F9416>I<0E021F04238841F080E00F057CA018>126 D E /Fm 9 117 df<7FFCFFF8FFF8FFF80E047A8E15>45 D<003FFFE0003FFFE00001F8000001 F0000001F0000001F0000001F0000003E0000003E0000003E0000003E0000007C0000007C00000 07C0000007C000000F8000000F8000000F8000000F8000001F0000001F0000001F0000001F0000 003E0000003E0000003E0000003E0000007C0000007C0000007C0000007C000000F8000000F800 0000F8000000F8000001F0000001F0000001F0000003F00000FFFF8000FFFF80001B297DA817> 73 D<0003FFFC0003FFFC00000FC000000F8000000F8000000F8000000F8000001F0000001F00 00001F0000001F0000003E0000003E0000003E0000003E0000007C0000007C0000007C0000007C 000000F8000000F8000000F8000000F8000001F0000001F0000001F0000001F0000003E0000003 E0000003E0000003E0003807C0007C07C000FC07C000FC0F8000F80F8000F00F0000C01E0000C0 3C00004078000030F000001F8000001E2A7AA81F>I<003FFFFF80003FFFFFF00001F801F80001 F0007C0001F0003E0001F0003E0001F0003F0003E0003F0003E0003F0003E0003F0003E0003F00 07C0007E0007C0007E0007C0007E0007C000FC000F8000F8000F8001F0000F8003E0000F8007C0 001F001F00001FFFFC00001F000000001F000000003E000000003E000000003E000000003E0000 00007C000000007C000000007C000000007C00000000F800000000F800000000F800000000F800 000001F000000001F000000001F000000003F00000007FFF800000FFFF80000028297CA829>80 D<001F800070C001C0600380600700600F00601E00603E00C03C00C07C03807C1E007FF000F800 00F80000F80000F80000F80000F00000F00000F000207000607800C03801801807000C1C0007F0 00131A79991B>101 D<001C003E003E003C003800000000000000000000000000000000000007 800CE0186030F030F060F060F061E0C1E001E003C003C00780078007800F000F000F0C1E0C1E0C 1E183C181C301C200C4007800F287BA712>105 D<07807C0008C1870010E2038030F4038030FC 03C060F803C060F003C060F003C0C1E0078001E0078001E0078001E0078003C00F0003C00F0003 C00F0003C01E0007801E0007801E0C07803C0C07803C080F003C180F0078100F0038300F003860 1E0018C00C000F001E1A7B9922>110 D<000FC000787000E03803C01C07801C0F001E1F001E1E 001F3E001F3C001F7C001F7C001FF8003EF8003EF8003EF8003CF0007CF00078F000F8F000F070 01E07801C03803801807000E1C0003F000181A79991F>I<00300078007800F000F000F000F001 E001E001E001E0FFFFFFFF03C003C007800780078007800F000F000F000F001E001E001E001E00 3C003C063C063C0C780C78183810383018400F8010257AA414>116 D E /Fn 51 123 df<0007F81F80003C067060007003E0F000E007C1F001C00FC1F003C00F80E00780 078040078007800007800780000780078000078007800007800780000780078000078007800007 800780000780078000FFFFFFFF00FFFFFFFF000780078000078007800007800780000780078000 078007800007800780000780078000078007800007800780000780078000078007800007800780 000780078000078007800007800780000780078000078007800007800780000780078000078007 80000780078000078007C000FFF87FFE00FFF87FFE00242A7FA923>11 D<0007F800003C060000 70010000E0070001C00F8003C00F8007800F800780070007800000078000000780000007800000 07800000078000000780000007800000FFFFFF80FFFFFF8007800F800780078007800780078007 800780078007800780078007800780078007800780078007800780078007800780078007800780 07800780078007800780078007800780078007800780078007800780078007800780FFF87FFCFF F87FFC1E2A7FA921>I<0004000800100020004000C0018003000300060006000E000C001C0018 0038003800380030007000700070007000F000F000E000E000E000E000E000E000E000E000E000 E000E000F000F0007000700070007000300038003800380018001C000C000E0006000600030003 00018000C0004000200010000800040E3D7BAC17>40 D<800040002000100008000C0006000300 03000180018001C000C000E0006000700070007000300038003800380038003C003C001C001C00 1C001C001C001C001C001C001C001C001C003C003C003800380038003800300070007000700060 00E000C001C0018001800300030006000C00080010002000400080000E3D7DAC17>I<78FCFCFE FE7A02020202040404081010204007127B8511>44 DI<78FCFCFC FC7806067B8511>I<00000600000E00000E00001C00001C00001C000038000038000038000070 0000700000E00000E00000E00001C00001C00001C0000380000380000380000700000700000700 000E00000E00000E00001C00001C00001C0000380000380000700000700000700000E00000E000 00E00001C00001C00001C0000380000380000380000700000700000700000E00000E00000E0000 1C00001C0000380000380000380000700000700000700000E00000E00000C00000173C7DAC1E> I<007F000001C1C0000780F0000F0078000E0038001C001C003C001E003C001E003C001E007800 0F0078000F0078000F0078000F00F8000F80F8000F80F8000F80F8000F80F8000F80F8000F80F8 000F80F8000F80F8000F80F8000F80F8000F80F8000F80F8000F80F8000F80F8000F8078000F00 78000F0078000F0078000F003C001E003C001E003C001E001C001C000E0038000F0078000780F0 0001C1C000007F000019297EA71E>I<00100000700001F0000FF000FEF000F0F00000F00000F0 0000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F0 0000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F00000F0 0000F00000F00000F00001F8007FFFE07FFFE013287BA71E>I<00FE0007FF800E07E01803F020 01F82000F840007C40007CF8007EFC007EFC003EFC003EFC003E78007E00007E00007C00007C00 00F80000F80001F00001E00003C0000780000700000E00001C0000380000700000600000C00001 80020300020600040C000418000410000C3FFFFC7FFFF8FFFFF8FFFFF817287DA71E>I<007F00 0003FFC0000701F0000C00F80010007C001C007C003E007E003E003E003E003E001E003E000C00 7E0000007C0000007C00000078000000F0000000E0000001C0000007000000FF00000001E00000 00F0000000780000003C0000003E0000001F0000001F0000001F8000001F8030001F8078001F80 FC001F80FC001F80FC001F00F8001F0040003F0040003E0030007C001800F8000F01F00003FFC0 00007F000019297EA71E>I<00006000000060000000E0000001E0000001E0000003E0000003E0 000005E0000009E0000009E0000011E0000021E0000021E0000041E0000081E0000081E0000101 E0000201E0000201E0000401E0000801E0000801E0001001E0003001E0002001E0004001E000C0 01E000FFFFFF80FFFFFF800001E0000001E0000001E0000001E0000001E0000001E0000001E000 0001E0000003F000007FFF80007FFF8019287EA71E>I<1800181F00F01FFFE01FFFC01FFF801F FF0011F800100000100000100000100000100000100000100000100000107E001183801600C018 00E010007000007800003C00003C00003C00003E00003E00003E70003EF8003EF8003EF8003EF8 003C80003C40007C4000782000783000F01801E00E07C007FF0001FC0017297DA71E>I<000FE0 00003FF80000F81C0001E00C0003801E0007803E000F003E000E001C001E0000001C0000003C00 00003C0000007C0000007800000078000000F83F0000F840E000F9807000F9003800FA001C00FC 001E00FC001E00FC000F00F8000F00F8000F80F8000F80F8000F80F8000F8078000F8078000F80 78000F807C000F803C000F003C000F001C001E001E001E000E003C000700780003C0F00001FFC0 00007F000019297EA71E>I<20000000380000003FFFFF803FFFFF803FFFFF007FFFFF00600002 004000040040000400400008008000100080002000000020000000400000008000000080000001 000000030000000200000006000000060000000C0000000C0000001C0000001C0000001C000000 38000000380000003800000078000000780000007800000078000000F8000000F8000000F80000 00F8000000F8000000F8000000F8000000F8000000700000192A7DA81E>I<007F000001FFC000 0381F000060078000C003C001C001C0018000E0038000E0038000E0038000E003C000E003C000E 003E001C001F8018001FC038000FF0600007F8C00003FF800001FF0000007FC00000FFE000030F F8000603FC001C01FE0038007E0030003F0070000F0070000780E0000780E0000380E0000380E0 000380E0000380F0000300700007007800060038000C001E0038000F80F00003FFE000007F0000 19297EA71E>I<007F000001FFC00007C1E0000F0070001E0038001C003C003C001C0078001E00 78001E00F8000F00F8000F00F8000F00F8000F00F8000F80F8000F80F8000F80F8000F8078000F 8078001F803C001F803C001F801C002F800E004F800700CF8003810F80007E0F8000000F000000 0F0000000F0000001E0000001E0000001E0000003C001C003C003E0078003E0070003C00E00018 01C0001C0780000FFE000003F8000019297EA71E>I<78FCFCFCFC780000000000000000000000 00000078FCFCFCFC78061A7B9911>I<00001800000000180000000018000000003C000000003C 000000003C000000007E000000007E00000000FF000000009F000000009F000000011F80000001 0F800000010F8000000207C000000207C000000207C000000403E000000403E000000403E00000 0801F000000801F000001801F800001000F800001000F800002000FC000020007C00003FFFFC00 007FFFFE000040003E000040003E000080001F000080001F000080001F000100000F800100000F 800100000F8002000007C007000007C01F80000FE0FFF000FFFFFFF000FFFF282A7EA92D>65 D<0000FF00100007FFE030001FC07830003E000C7000F80006F001F00003F003E00001F007C000 00F00F800000700F800000701F000000303F000000303E000000303E000000107E000000107E00 0000107C00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC00000000FC 00000000FC00000000FC000000007C000000007E000000007E000000103E000000103E00000010 3F000000101F000000200F800000200F8000006007C000004003E000008001F000018000F80003 00003E000E00001FC038000007FFE0000000FF8000242B7DA92B>67 DII77 DI80 D<00FE010003FF83000F81E3001E0037003C001F0038000F007800070070000700F0000300 F0000300F0000300F0000100F8000100F8000100FC0000007C0000007F0000003FE000001FFF00 000FFFE00007FFF80003FFFC00007FFE000007FF0000007F0000001F8000000F80000007C00000 07C0800003C0800003C0800003C0800003C0C00003C0C0000380C0000380E0000780F0000700F8 000E00EE001C00C3C07800C1FFF000803FC0001A2B7DA921>83 D<01FC00000E0780001001C000 3C00E0003E00F0003E0078001C00780008007800000078000000780000007800007FF80003E078 000F8078001F0078003E0078007C00780078007820F8007820F8007820F8007820F800F8207C00 F8203C013C401F063FC007F80F001B1A7E991E>97 D<07800000FF800000FF8000000F80000007 800000078000000780000007800000078000000780000007800000078000000780000007800000 07800000078000000783F000078C1C0007B0070007A0038007C003C0078001E0078001E0078000 F0078000F0078000F8078000F8078000F8078000F8078000F8078000F8078000F8078000F00780 00F0078001F0078001E0078001C007C003C00740078007200E0006181C000407E0001D2A7FA921 >I<007F8001C0700780080F003C1E007C3C007C3C00387C0010780000F80000F80000F80000F8 0000F80000F80000F80000F800007800007C00003C00043C00041E00080F001007802001C0C000 7F00161A7E991B>I<00000F000001FF000001FF0000001F0000000F0000000F0000000F000000 0F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F00003F0F0001 C0CF0003802F000F001F001E001F001C000F003C000F007C000F0078000F0078000F00F8000F00 F8000F00F8000F00F8000F00F8000F00F8000F00F8000F0078000F0078000F003C000F003C000F 001E001F000E002F0007004F8001C18FF8007E0FF81D2A7EA921>I<007E0003C3800700E00E00 F01C00703C00783C003878003C78003CF8003CF8003CFFFFFCF80000F80000F80000F80000F800 007800007C00003C00043C00041E00080E001007002001C0C0007F00161A7E991B>I<001F0000 70C000E1E001C3E003C3E00381C007808007800007800007800007800007800007800007800007 8000078000FFFE00FFFE0007800007800007800007800007800007800007800007800007800007 800007800007800007800007800007800007800007800007800007800007800007800007C000FF FE00FFFE00132A7FA912>I<0000078001FC1840070721C00E03C1C01E03C0803C01E0003C01E0 007C01F0007C01F0007C01F0007C01F0007C01F0003C01E0003C01E0001E03C0000E0380001707 000011FC0000300000003000000030000000380000001C0000001FFFC0000FFFF80007FFFC001C 003E0030000F007000070060000380E0000380E0000380E0000380E00003807000070070000700 38000E000C0018000780F00000FF80001A287E9A1E>I<07800000FF800000FF8000000F800000 078000000780000007800000078000000780000007800000078000000780000007800000078000 0007800000078000000783F800078C1C0007900E0007A0070007A0078007C0078007C007800780 078007800780078007800780078007800780078007800780078007800780078007800780078007 800780078007800780078007800780078007800780078007800780FFFCFFFCFFFCFFFC1E2A7FA9 21>I<07000F801F801F800F80070000000000000000000000000000000000000007807F807F80 0F8007800780078007800780078007800780078007800780078007800780078007800780078007 800780FFF8FFF80D297FA811>I<0780FF80FF800F800780078007800780078007800780078007 800780078007800780078007800780078007800780078007800780078007800780078007800780 07800780078007800780078007800780FFFCFFFC0E2A7FA911>108 D<0781F800FC00FF860E03 0700FF98070C03800FA0079003C007A003D001E007C003E001E007C003E001E0078003C001E007 8003C001E0078003C001E0078003C001E0078003C001E0078003C001E0078003C001E0078003C0 01E0078003C001E0078003C001E0078003C001E0078003C001E0078003C001E0078003C001E007 8003C001E0078003C001E0078003C001E0FFFC7FFE3FFFFFFC7FFE3FFF301A7F9933>I<0783F8 00FF8C1C00FF900E000FA0070007A0078007C0078007C007800780078007800780078007800780 078007800780078007800780078007800780078007800780078007800780078007800780078007 800780078007800780078007800780FFFCFFFCFFFCFFFC1E1A7F9921>I<007F000001C1C00007 0070000E0038001C001C003C001E003C001E0078000F0078000F00F8000F80F8000F80F8000F80 F8000F80F8000F80F8000F80F8000F80F8000F8078000F0078000F003C001E003C001E001E003C 000E0038000700700001C1C000007F0000191A7E991E>I<0783F000FF8C1C00FFB00F0007A007 8007C003C0078003E0078001E0078001F0078001F0078000F8078000F8078000F8078000F80780 00F8078000F8078000F8078000F0078001F0078001F0078001E0078003C007C003C007C0078007 A00E0007983C000787E00007800000078000000780000007800000078000000780000007800000 078000000780000007800000FFFC0000FFFC00001D267F9921>I<003F008001E0C18003802180 0F0013801E000B801E000F803C0007807C0007807C00078078000780F8000780F8000780F80007 80F8000780F8000780F8000780F80007807C0007807C0007803C0007803E000F801E000F800F00 17800780278001E0C780007F078000000780000007800000078000000780000007800000078000 0007800000078000000780000007800000FFFC0000FFFC1E267E9920>I<0787C0FF98E0FF91F0 0FA1F007C1F007C0E007C000078000078000078000078000078000078000078000078000078000 07800007800007800007800007800007800007800007C000FFFE00FFFE00141A7F9917>I<07F8 401C06C03001C06000C06000C0E00040E00040F00040F800007E00007FF0003FFE000FFF0003FF 80003FC00007C08001E08001E0C000E0C000E0C000E0E000C0F001C0F80180C4070083F800131A 7E9918>I<0080000080000080000080000180000180000180000380000380000780000F80001F FF80FFFF8007800007800007800007800007800007800007800007800007800007800007800007 800007800007804007804007804007804007804007804007804003C08001C08000E100003E0012 257FA417>I<07800780FF80FF80FF80FF800F800F800780078007800780078007800780078007 800780078007800780078007800780078007800780078007800780078007800780078007800780 078007800780078007800F8007800F800380178001C027C000E047FC003F87FC1E1A7F9921>I< FFF00FF8FFF00FF80F8003C0078003800780010003C0020003C0020003E0020001E0040001E004 0000F0080000F0080000F818000078100000781000003C2000003C2000003E6000001E4000001E 4000000F8000000F8000000700000007000000070000000200001D1A7F9920>IIII<7FFFF87800F06001F04001E04003C0C007C0800780800F00801F0000 1E00003C00007C0000780000F00001F00001E00403C00407C0040780040F000C1F00081E00083C 00187C00387800F8FFFFF8161A7E991B>I E /Fo 48 122 df<0001FF81FE00001FFFEFFF8000 7F80FF87C000FC00FE0FE001F801FE0FE003F801FC0FE007F001FC0FE007F001FC07C007F001FC 000007F001FC000007F001FC000007F001FC000007F001FC000007F001FC000007F001FC0000FF FFFFFFF800FFFFFFFFF800FFFFFFFFF80007F001FC000007F001FC000007F001FC000007F001FC 000007F001FC000007F001FC000007F001FC000007F001FC000007F001FC000007F001FC000007 F001FC000007F001FC000007F001FC000007F001FC000007F001FC000007F001FC000007F001FC 000007F001FC000007F001FC000007F001FC000007F001FC00007FFF1FFFE0007FFF1FFFE0007F FF1FFFE0002B2A7FA928>11 D<00030007000E001C0038007000F001E003C003C007C007800F80 0F001F001F003F003E003E007E007E007E007C007C00FC00FC00FC00FC00FC00FC00FC00FC00FC 00FC00FC00FC007C007C007E007E007E003E003E003F001F001F000F000F80078007C003C003C0 01E000F000700038001C000E00070003103C7AAC1B>40 D<8000C000E000700038001C001E000F 000780078007C003C003E001E001F001F001F800F800F800FC00FC00FC007C007C007E007E007E 007E007E007E007E007E007E007E007E007E007C007C00FC00FC00FC00F800F801F801F001F001 E003E003C007C0078007800F001E001C0038007000E000C00080000F3C7BAC1B>I<1C007F007F 00FF80FFC0FFC07FC07FC01CC000C000C00180018001800300030006000C001800300020000A15 7B8813>44 DI<1C003E007F00FF80 FF80FF807F003E001C0009097B8813>I<000E00001E00007E0007FE00FFFE00FFFE00F8FE0000 FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000 FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000 FE0000FE0000FE007FFFFE7FFFFE7FFFFE17277BA622>49 D<00FF800003FFF0000FFFFC001F03 FE003800FF007C007F80FE003FC0FF003FC0FF003FE0FF001FE0FF001FE07E001FE03C003FE000 003FE000003FC000003FC000007F8000007F000000FE000000FC000001F8000003F0000003E000 00078000000F0000001E0000003C00E0007000E000E000E001C001C0038001C0070001C00FFFFF C01FFFFFC03FFFFFC07FFFFFC0FFFFFF80FFFFFF80FFFFFF801B277DA622>I<007F800003FFF0 0007FFFC000F81FE001F00FF003F80FF003F807F803F807F803F807F801F807F800F007F800000 FF000000FF000000FE000001FC000001F8000007F00000FFC00000FFF0000001FC0000007E0000 007F0000007F8000003FC000003FC000003FE000003FE03C003FE07E003FE0FF003FE0FF003FE0 FF003FC0FF007FC07E007F807C007F003F01FE001FFFFC0007FFF00000FF80001B277DA622>I< 380000003E0000003FFFFFF03FFFFFF03FFFFFF07FFFFFE07FFFFFC07FFFFF807FFFFF0070000E 0070000E0070001C00E0003800E0007000E000E0000000E0000001C00000038000000780000007 8000000F0000000F0000001F0000001F0000003F0000003E0000003E0000007E0000007E000000 7E0000007E000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE0000 007C0000003800001C297CA822>55 D<000003800000000007C00000000007C0000000000FE000 0000000FE0000000000FE0000000001FF0000000001FF0000000003FF8000000003FF800000000 3FF80000000073FC0000000073FC00000000F3FE00000000E1FE00000000E1FE00000001C0FF00 000001C0FF00000003C0FF80000003807F80000007807FC0000007003FC0000007003FC000000E 003FE000000E001FE000001E001FF000001C000FF000001FFFFFF000003FFFFFF800003FFFFFF8 0000780007FC0000700003FC0000700003FC0000E00001FE0000E00001FE0001E00001FF0001C0 0000FF0001C00000FF00FFFE001FFFFEFFFE001FFFFEFFFE001FFFFE2F297EA834>65 DI<00003FF001800003FFFE0380000FFFFF878000 3FF007DF8000FF8001FF8001FE00007F8003FC00003F8007F000001F800FF000000F801FE00000 07801FE0000007803FC0000007803FC0000003807FC0000003807F80000003807F8000000000FF 8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF800000 0000FF8000000000FF80000000007F80000000007F80000000007FC0000003803FC0000003803F C0000003801FE0000003801FE0000007000FF00000070007F000000E0003FC00001E0001FE0000 3C0000FF8000F800003FF007E000000FFFFFC0000003FFFF000000003FF8000029297CA832>I< FFFFFFF80000FFFFFFFF8000FFFFFFFFE00003FC001FF80003FC0007FC0003FC0001FE0003FC00 00FF0003FC00007F8003FC00003FC003FC00001FC003FC00001FE003FC00001FE003FC00000FF0 03FC00000FF003FC00000FF003FC00000FF003FC00000FF803FC00000FF803FC00000FF803FC00 000FF803FC00000FF803FC00000FF803FC00000FF803FC00000FF803FC00000FF803FC00000FF8 03FC00000FF003FC00000FF003FC00000FF003FC00001FE003FC00001FE003FC00001FC003FC00 003FC003FC00007F8003FC00007F0003FC0001FE0003FC0003FC0003FC001FF800FFFFFFFFE000 FFFFFFFF8000FFFFFFFC00002D297DA835>III<00007FE003000003FFFC0700001FFFFF0F00003FF00FFF0000 FF8001FF0001FE0000FF0003F800003F0007F000003F000FF000001F001FE000000F001FE00000 0F003FC000000F003FC0000007007FC0000007007F80000007007F8000000000FF8000000000FF 8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF8000000000FF800000 0000FF8001FFFFF87F8001FFFFF87F8001FFFFF87FC00000FF003FC00000FF003FC00000FF001F E00000FF001FE00000FF000FF00000FF0007F00000FF0003F80000FF0001FE0000FF0000FF8001 FF00003FF007BF00001FFFFF1F000003FFFE0F0000007FF003002D297CA836>I73 D76 DII<0000FFE000000007FFFC 0000003FC07F8000007F001FC00001FC0007F00003F80003F80007F00001FC000FF00001FE001F E00000FF001FE00000FF003FC000007F803FC000007F807FC000007FC07F8000003FC07F800000 3FC07F8000003FC0FF8000003FE0FF8000003FE0FF8000003FE0FF8000003FE0FF8000003FE0FF 8000003FE0FF8000003FE0FF8000003FE0FF8000003FE0FF8000003FE07F8000003FC07FC00000 7FC07FC000007FC03FC000007F803FC000007F801FE00000FF001FE00000FF000FF00001FE0007 F00001FC0003F80003F80001FC0007F00000FF001FE000003FC07F8000000FFFFE00000000FFE0 00002B297CA834>II82 D<007F806003FFF0E007FFF9E00F807FE01F001FE03E0007E07C0003E07C0001E0 FC0001E0FC0001E0FC0000E0FE0000E0FE0000E0FF000000FFC000007FFE00007FFFE0003FFFFC 001FFFFE000FFFFF8007FFFFC003FFFFE000FFFFE00007FFF000007FF000000FF8000007F80000 03F8600001F8E00001F8E00001F8E00001F8F00001F0F00001F0F80003F0FC0003E0FF0007C0FF E01F80F3FFFF00E0FFFE00C01FF0001D297CA826>I<7FFFFFFFFFC07FFFFFFFFFC07FFFFFFFFF C07F803FC03FC07E003FC007C078003FC003C078003FC003C070003FC001C0F0003FC001E0F000 3FC001E0E0003FC000E0E0003FC000E0E0003FC000E0E0003FC000E0E0003FC000E000003FC000 0000003FC0000000003FC0000000003FC0000000003FC0000000003FC0000000003FC000000000 3FC0000000003FC0000000003FC0000000003FC0000000003FC0000000003FC0000000003FC000 0000003FC0000000003FC0000000003FC0000000003FC0000000003FC0000000003FC000000000 3FC0000000003FC00000007FFFFFE000007FFFFFE000007FFFFFE0002B287EA730>I86 DI<01FF800007FFF0000F81F8001FC07E001FC07E001FC03F000F803F8007003F8000003F 8000003F8000003F80000FFF8000FFFF8007FC3F800FE03F803F803F803F003F807F003F80FE00 3F80FE003F80FE003F80FE003F807E007F807F00DF803F839FFC0FFF0FFC01FC03FC1E1B7E9A21 >97 DI<001FF80000FFFE0003F01F0007E0 3F800FC03F801F803F803F801F007F800E007F0000007F000000FF000000FF000000FF000000FF 000000FF000000FF000000FF0000007F0000007F0000007F8000003F8001C01F8001C00FC00380 07E0070003F01E0000FFFC00001FE0001A1B7E9A1F>I<00003FF80000003FF80000003FF80000 0003F800000003F800000003F800000003F800000003F800000003F800000003F800000003F800 000003F800000003F800000003F800000003F800001FE3F80000FFFBF80003F03FF80007E00FF8 000FC007F8001F8003F8003F8003F8007F0003F8007F0003F8007F0003F800FF0003F800FF0003 F800FF0003F800FF0003F800FF0003F800FF0003F800FF0003F8007F0003F8007F0003F8007F00 03F8003F8003F8001F8003F8000F8007F80007C00FF80003F03BFF8000FFF3FF80003FC3FF8021 2A7EA926>I<003FE00001FFF80003F07E0007C01F000F801F801F800F803F800FC07F000FC07F 0007C07F0007E0FF0007E0FF0007E0FFFFFFE0FFFFFFE0FF000000FF000000FF0000007F000000 7F0000007F0000003F8000E01F8000E00FC001C007E0038003F81F0000FFFE00001FF0001B1B7E 9A20>I<0007F0003FFC00FE3E01F87F03F87F03F07F07F07F07F03E07F00007F00007F00007F0 0007F00007F00007F000FFFFC0FFFFC0FFFFC007F00007F00007F00007F00007F00007F00007F0 0007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F0 0007F0007FFF807FFF807FFF80182A7EA915>I<00FF81F003FFE7F80FC1FE7C1F80FC7C1F007C 383F007E107F007F007F007F007F007F007F007F007F007F007F007F003F007E001F007C001F80 FC000FC1F8001FFFE00018FF800038000000380000003C0000003E0000003FFFF8001FFFFF001F FFFF800FFFFFC007FFFFE01FFFFFF03E0007F07C0001F8F80000F8F80000F8F80000F8F80000F8 7C0001F03C0001E01F0007C00FC01F8003FFFE00007FF0001E287E9A22>II<07000FC01FE03FE03FE03FE01FE00FC0070000000000000000 00000000000000FFE0FFE0FFE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE0 0FE00FE00FE00FE00FE00FE00FE00FE0FFFEFFFEFFFE0F2B7DAA14>I108 DII<003FE00001FFFC00 03F07E000FC01F801F800FC03F800FE03F0007E07F0007F07F0007F07F0007F0FF0007F8FF0007 F8FF0007F8FF0007F8FF0007F8FF0007F8FF0007F8FF0007F87F0007F07F0007F03F800FE03F80 0FE01F800FC00FC01F8007F07F0001FFFC00003FE0001D1B7E9A22>II114 D<03FE300FFFF01E03F03800F0700070F00070F00070F80070FC0000FFE000 7FFE007FFF803FFFE01FFFF007FFF800FFF80003FC0000FC60007CE0003CF0003CF00038F80038 FC0070FF01E0F7FFC0C1FF00161B7E9A1B>I<00700000700000700000700000F00000F00000F0 0001F00003F00003F00007F0001FFFF0FFFFF0FFFFF007F00007F00007F00007F00007F00007F0 0007F00007F00007F00007F00007F00007F00007F00007F03807F03807F03807F03807F03807F0 3803F03803F87001F86000FFC0001F8015267FA51B>III121 D E end %%EndProlog %%BeginSetup %%Feature: *Resolution 300 TeXDict begin %%EndSetup %%Page: 1 1 bop 410 195 a Fo(MOSIS)23 b(Scalable)f(CMOS)g(Design)g(Rules)806 351 y Fn(\()p Fo(revision)g(7)p Fn(\))866 498 y Fm(Jen-I)h(Pi)772 633 y Fl(the)16 b Fk(MOSIS)h Fl(Service)654 693 y(Information)f(Sciences)f (Institute)621 753 y(Univ)o(ersit)o(y)e(of)k(Southern)f(California)753 813 y(4676)i(Admiralt)o(y)c(W)l(a)o(y)692 873 y(Marina)i(del)f(Rey)l(,)g(CA)i (90292)868 934 y(pi@isi.edu)814 994 y(August)g(1,)f(1995)0 1160 y Fj(1)83 b(In)n(tro)r(duction)0 1284 y Fo(1.1)70 b(SCMOS)22 b(Design)g(Rules)0 1377 y Fl(This)17 b(do)q(cumen)o(t)e(de\014nes)h(the)g (o\016cial)g(la)o(y)o(out)g(design)h(rules)f(for)h(MOSIS)e(scalable)i(CMOS)f (\(SCMOS\))0 1437 y(design)g(tec)o(hnology)l(.)21 b(It)16 b(sup)q(ercedes)g (all)g(previous)g(revisions.)73 1497 y(In)k(SCMOS)g(tec)o(hnology)l(,)g (circuit)f(geometries)f(are)i(dra)o(wn)h(according)f(to)h(Mead)f(and)g(Con)o (w)o(a)o(y's)0 1557 y Fi(\025)p Fl(-based)k(metho)q(dology)e([3].)39 b(The)22 b(unit)g(of)h(measuremen)o(t,)d Fi(\025)p Fl(,)k(can)f(easily)f(b)q (e)g(scaled)g(to)h(di\013eren)o(t)0 1617 y(fabrication)16 b(pro)q(cesses)h (as)g(semiconductor)e(tec)o(hnology)h(adv)m(ances.)73 1678 y(A)21 b(user)h(design)f(submitted)f(to)i(MOSIS)e(in)h(SCMOS)h(tec)o(hnology) f(should)h(b)q(e)f(in)g(either)g(Calma)0 1738 y(GDSI)q(I)i(format)g([1])g(or) g(Caltec)o(h)g(In)o(termediate)d(F)l(orm)i(\(CIF)h(v)o(ersion)f(2.0\))i([3].) 42 b(Eac)o(h)23 b(design)g(has)0 1798 y(a)d(tec)o(hnology)f Fk(designation)i Fl(that)f(go)q(es)h(with)e(it)g(for)h(the)f(purp)q(ose)i(of) e(MOSIS's)g(data)i(prep.)31 b(A)o(t)18 b(the)0 1858 y(momen)o(t,)10 b(three)i(designations)i(are)e(used)h(to)g(sp)q(ecify)f(CMOS)h(pro)q(cesses.) 21 b(Eac)o(h)12 b(designation)i(ma)o(y)d(ha)o(v)o(e)0 1918 y(one)19 b(or)g(more)e Fk(options)i Fl(asso)q(ciated)g(for)g(the)g(purp)q (ose)g(of)g(either)f(\(1\))h(sp)q(ecial)f(features)g(for)h(the)g(target)0 1979 y(pro)q(cess)f(or)f(\(2\))h(the)f(presence)f(of)i(no)o(v)o(el)e(device)f (in)i(the)g(design.)24 b(A)o(t)16 b(the)h(time)e(of)j(writing,)f(MOSIS)f(is)0 2039 y(o\013ering)g(six)f(CMOS)h(pro)q(cesses)g(from)e(three)h(di\013eren)o (t)g(foundries)h(with)f(dra)o(wn)h(feature)f(sizes)g(ranging)0 2099 y(from)g(2.0)i Fi(\026)p Fl(m)e(do)o(wn)i(to)f(0.6)h Fi(\026)p Fl(m.)73 2159 y(A)g(list)g(of)h(the)f(things)h(that)g(ha)o(v)o(e)f(either)f (b)q(een)i(revised)e(or)i(added)g(since)f(our)h(last)f(release)g(can)h(b)q(e) 0 2219 y(found)f(in)f(App)q(endix)f(A.)h(Please)g(refer)f(to)i(the)f(sp)q (eci\014c)f(sections)h(for)h(detailed)e(descriptions.)0 2386 y Fj(2)83 b(Standard)27 b(SCMOS)0 2495 y Fl(The)19 b(standard)i(CMOS)f(tec)o (hnology)f(accessed)g(b)o(y)g(MOSIS)g(is)g(a)h(single)f(p)q(olysilicon,)g (double)g(metal,)0 2555 y(bulk)d(CMOS)g(pro)q(cess)h(with)f(enhancemen)o (t-mo)q(de)d Fk(n)p Fl(-MOSFET)k(and)g Fk(p)p Fl(-MOSFET)f(devices)f([4].)963 2828 y(1)p eop %%Page: 2 2 bop 0 195 a Fo(2.1)70 b(W)-6 b(ell)21 b(Fla)n(v)n(or)0 287 y Fl(Three)f(t)o(yp)q(es)f(of)i Fk(designation)g Fl(are)f(used)g(to)g (indicate)f(the)h(\015a)o(v)o(or)g(of)g(the)g(w)o(ell)e(\(substrate\))j(used) f(for)0 348 y(fabrication)c(as)h(sho)o(wn)g(in)f(T)l(able)g(1.)p 499 461 952 2 v 498 522 2 61 v 507 522 V 533 504 a(Designation)p 808 522 V 50 w(Description)p 1441 522 V 1450 522 V 499 523 952 2 v 498 583 2 61 v 507 583 V 533 565 a(SCN)p 808 583 V 202 w(Scalable)g(CMOS)g(N-w)o(ell)p 1441 583 V 1450 583 V 498 644 V 507 644 V 533 626 a(SCP)p 808 644 V 206 w(Scalable)g(CMOS)g(P-w)o(ell)p 1441 644 V 1450 644 V 498 704 V 507 704 V 533 686 a(SCE)p 808 704 V 206 w(Scalable)g(CMOS)g(Either-w)o(ell)p 1441 704 V 1450 704 V 499 705 952 2 v 537 840 a(T)l(able)g(1:)22 b(SCMOS)16 b(w)o(ell)f(\015a)o(v)o(or)h(designations)73 968 y(The)k(SCN)g(and)h(SCP)g (designations)f(with)g(a)h(submitted)d(pro)s(ject)i(are)g(designed)g(for)g (fabrication)0 1028 y(of)d(the)g(sp)q(eci\014ed)g(w)o(ell)e(only)l(.)24 b(F)l(or)17 b(con)o(v)o(enience,)d(in)j(b)q(oth)h(cases,)f(a)g(pro)s(ject)g (ma)o(y)e(include)h(the)h('other')0 1088 y(w)o(ell,)k(but)g(it)g(will)g(alw)o (a)o(ys)g(b)q(e)g(ignored.)37 b(SCE)22 b(pro)s(jects)f(are)g(used)h(for)f (fabrication)h(in)f(an)o(y)g(CMOS)0 1148 y(pro)q(cess,)d(N-w)o(ell)e(or)i (P-w)o(ell)f(\()p Fk(either)p Fl(\).)25 b(A)17 b(pro)s(ject)g(with)g(SCE)h (designation)g(m)o(ust)e(include)h Fk(b)n(oth)g Fl(w)o(ells)0 1208 y(\(and)22 b(corresp)q(ondingly)l(,)g(w)o(ell/substrate)e(con)o(tacts)i (for)f(prop)q(er)h(bias\).)36 b(F)l(or)21 b(an)o(y)g(giv)o(en)f(fabrication)0 1269 y(pro)q(cess,)f(the)f('other')g(w)o(ell)f(will)g(b)q(e)i(ignored)f (during)h(the)f(mask)f(generation.)28 b(If)18 b(t)o(win-tub)g(pro)q(cesses)0 1329 y(are)e(o\013ered)h(in)f(the)g(future,)f(b)q(oth)i(w)o(ells)f(will)f(b)q (e)h(used.)0 1473 y Fo(2.2)70 b(SCMOS)22 b(Options)0 1566 y Fl(SCMOS)15 b(options)h(are)g(used)f(to)h(designate)f(pro)s(jects)g(whic)o(h) g(use)g(additional)g(la)o(y)o(ers)g(b)q(ey)o(ond)g(the)g(stan-)0 1626 y(dard)h(CMOS)f(tec)o(hnology)l(.)20 b(Eac)o(h)c(option)f(is)g(named)f (b)o(y)h(a)h(designator)g(that)f(is)g(tac)o(k)o(ed)f(on)o(to)i(the)f(basic)0 1686 y(designator)k(for)g(its)g(w)o(ell)e(\015a)o(v)o(or.)28 b(Reader)19 b(should)g(note)g(that)g(not)g(all)f(p)q(ossible)h(com)o (binations)e(\(with)0 1746 y(w)o(ell)11 b(\015a)o(v)o(or\))i(are)g(actually)f (a)o(v)m(ailable.)19 b(The)13 b(curren)o(tly)e(a)o(v)m(ailable)h(SCMOS)h (options)g(are)g(listed)f(in)g(T)l(able)0 1806 y(2.)73 1867 y(In)24 b(addition)g(to)g(the)g(options)g(in)g(T)l(able)g(2,)h(t)o(w)o(o)f (undeclared)f(options)i(also)f(exist.)44 b(One)23 b(with)0 1927 y(resp)q(ect)18 b(to)h(the)g(existence)e(of)i Fk(high)h(voltage)g Fl(MOSFET)f(devices;)f(the)g(other,)h(a)g Fk(tight)h(metal)g Fl(rule)e(for)0 1987 y(high-densit)o(y)c(metal)f(in)o(terconnections.)20 b(F)l(or)15 b(options)g(a)o(v)m(ailable)f(to)i(sp)q(eci\014c)e(pro)q(cess,)h (please)g(refer)f(to)0 2047 y(T)l(able)i(3)h(for)f(the)g(curren)o(t)g(MOSIS)f (o\013erings.)0 2192 y Fo(2.3)70 b(SCMOS)22 b(O\013erings)0 2284 y Fl(MOSIS)14 b(is)h(curren)o(tly)f(o\013ering)h(the)g(fabrication)g (pro)q(cesses)h(as)f(sho)o(wn)h(in)f(T)l(able)g(3.)21 b(F)l(or)15 b(eac)o(h)g(pro)q(cess,)0 2344 y(the)e(list)g(of)h(appropriate)h(SCMOS)e(tec) o(hnology)h(designations)g(is)f(listed.)20 b(Note)13 b(that)h(whenev)o(er)f (SCNxx)0 2404 y(app)q(ears)i(in)e(the)h(table,)f(SCExx)h(is)g(also)g (appropriate.)21 b(Lik)o(ewise,)13 b(whenev)o(er)f(SCPxx)i(app)q(ears,)h (SCExx)0 2465 y(is)h(also)h(appropriate.)p 0 2608 780 2 v 56 2639 a Fh(2)75 2654 y Fg(CCD)c(la)o(y)o(er)h(not)f(included.)56 2689 y Fh(2)75 2704 y Fg(CCD)g(la)o(y)o(er)h(not)f(included.)963 2828 y Fl(2)p eop %%Page: 3 3 bop 49 387 1853 2 v 48 447 2 61 v 57 447 V 82 429 a Fl(Designation)p 358 447 V 51 w(Long)17 b(form)p 769 447 V 188 w(Description)p 1892 447 V 1901 447 V 49 449 1853 2 v 48 509 2 61 v 57 509 V 191 491 a(E)p 358 509 V 160 w(Electro)q(de)p 769 509 V 207 w(Adds)g(a)f(second)h(p)q(olysilicon)e(la)o(y)o(er)g(\()p Ff(electro)r(de)p Fl(\))p 1892 509 V 1901 509 V 48 569 V 57 569 V 358 569 V 769 569 V 794 551 a(that)i(can)g(serv)o(e)e(as)i(either)e(one)h(of)h(electro)q (de)e(of)i(a)f(p)q(oly)p 1892 569 V 1901 569 V 48 630 V 57 630 V 358 630 V 769 630 V 794 612 a(capacitor)h(or)f(as)h(a)g(gate)g(for)f (transistors.)22 b(A)16 b(con)o(tact)p 1892 630 V 1901 630 V 48 690 V 57 690 V 358 690 V 769 690 V 794 672 a(la)o(y)o(er)f(\()p Ff(electro)r(de)p 1159 672 17 2 v 18 w(con)n(tact)p Fl(\))i(to)f(metal)f (also)h(exists.)p 1892 690 2 61 v 1901 690 V 49 691 1853 2 v 48 752 2 61 v 57 752 V 190 734 a(A)p 358 752 V 157 w(Analog)p 769 752 V 260 w(Adds)h(electro)q(de)e(la)o(y)o(er)g(\(as)i(in)f(E)g(option\)) h(plus)f(a)p 1892 752 V 1901 752 V 48 812 V 57 812 V 358 812 V 769 812 V 794 794 a Ff(pbase)h Fl(la)o(y)o(er)e(for)h(the)g(construction)h (of)f(v)o(ertical)f(NPN)p 1892 812 V 1901 812 V 48 872 V 57 872 V 358 872 V 769 872 V 794 854 a(transistor.)22 b(A)16 b Ff(buried)p 1247 854 17 2 v 20 w(ccd)g Fl(la)o(y)o(er)f(is)h(also)h(presen)o (t.)p 1892 872 2 61 v 1901 872 V 48 932 V 57 932 V 358 932 V 769 932 V 794 914 a(for)g(buried-c)o(hannel)e(CCD)i(applications)p 1892 932 V 1901 932 V 49 934 1853 2 v 48 994 2 61 v 57 994 V 173 976 a(3M)p 358 994 V 142 w(T)l(riple)e(Metal)p 769 994 V 144 w(Adds)i(second)f(via)g(\()p Ff(via2)p Fl(\))g(and)h(third)e(metal)g (\()p Ff(metal3)p Fl(\))p 1892 994 V 1901 994 V 48 1054 V 57 1054 V 358 1054 V 769 1054 V 794 1036 a(la)o(y)o(ers.)p 1892 1054 V 1901 1054 V 49 1056 1853 2 v 48 1116 2 61 v 57 1116 V 175 1098 a(LC)p 358 1116 V 144 w(Linear)h(Capacitor)p 769 1116 V 50 w(Adds)h(a)f Ff(cap)p 1047 1098 17 2 v 21 w(w)n(ell)g Fl(la)o(y)o(er)f(for)h(the)g(implem)o(en)o(tation)d(of)p 1892 1116 2 61 v 1901 1116 V 48 1176 V 57 1176 V 358 1176 V 769 1176 V 794 1158 a(linear)j(capacitors.)p 1892 1176 V 1901 1176 V 49 1178 1853 2 v 48 1238 2 61 v 57 1238 V 127 1220 15 2 v 142 1220 a(MEMS)p 358 1238 2 61 v 92 w(Micromec)o(hanic)o(al)p 769 1238 V 50 w(Adds)h(t)o(w)o(o)f(new)g(la)o(y)o(ers,)f Ff(mems)p 1411 1220 17 2 v 17 w(op)r(en)h Fl(and)p 1892 1238 2 61 v 1901 1238 V 48 1298 V 57 1298 V 358 1298 V 384 1280 a(Systems)p 769 1298 V 236 w Ff(mems)p 941 1280 17 2 v 18 w(etc)n(h)p 1061 1280 V 20 w(stop)g Fl(for)h(the)f(purp)q(ose)h(of)f(micro-)p 1892 1298 2 61 v 1901 1298 V 48 1359 V 57 1359 V 358 1359 V 769 1359 V 794 1340 a(mec)o(hanical)e(device)h(construction.)p 1892 1359 V 1901 1359 V 49 1360 1853 2 v 585 1494 a(T)l(able)h(2:)21 b(SCMOS)c(tec)o(hnology)f(options)p 121 1957 1709 2 v 120 2017 2 61 v 129 2017 V 154 1999 a(F)l(oundry)p 356 2017 V 50 w(Pro)q(cess)p 788 2017 V 273 w(Lam)o(b)q(da)p 1012 2017 V 50 w(Options)p 1820 2017 V 1829 2017 V 121 2019 1709 2 v 120 2079 2 61 v 129 2079 V 154 2061 a(Orbit)p 356 2079 V 111 w(2.0)g Fi(\026)p Fl(m)g(N-w)o(ell)p 788 2079 V 142 w(1.0)h Fi(\026)p Fl(m)p 1012 2079 V 62 w(SCNA,)e(SCNE,)h(SCN,)f(SCNA)p 1632 2061 15 2 v 17 w(MEMS)p 1820 2079 2 61 v 1829 2079 V 120 2139 V 129 2139 V 154 2121 a(Orbit)p 356 2139 V 111 w(2.0)h Fi(\026)p Fl(m)g(P-w)o(ell)p 788 2139 V 146 w(1.0)h Fi(\026)p Fl(m)p 1012 2139 V 62 w(SCPE,)f(SCP)l(,)g(SCPE)p 1448 2121 15 2 v 19 w(MEMS)p 1820 2139 2 61 v 1829 2139 V 120 2200 V 129 2200 V 154 2181 a(AMI)p 356 2200 V 128 w(1.5)g Fi(\026)p Fl(m)g(N-w)o(ell)p 788 2200 V 142 w(0.8)h Fi(\026)p Fl(m)p 1012 2200 V 62 w(SCNA)1174 2163 y Fe(1)1193 2181 y Fl(,)f(SCNE,)f(SCN,)h(High)g(V)l(oltage)p 1820 2200 V 1829 2200 V 120 2260 V 129 2260 V 154 2242 a(Orbit)p 356 2260 V 111 w(1.2)g Fi(\026)p Fl(m)g(N-w)o(ell)p 788 2260 V 142 w(0.6)h Fi(\026)p Fl(m)p 1012 2260 V 62 w(SCNA)1174 2224 y Fe(2)p 1820 2260 V 1828 2260 V 120 2320 V 128 2320 V 154 2302 a Fl(HP)p 356 2320 V 158 w(AMOSI/CMOS34)p 788 2320 V 62 w(0.6)g Fi(\026)p Fl(m)p 1012 2320 V 62 w(SCNLC,)f(SCN,)g(Tigh)o(t)g(Metal)p 1820 2320 V 1829 2320 V 120 2380 V 129 2380 V 154 2362 a(HP)p 356 2380 V 158 w(CMOS26B/G)p 788 2380 V 154 w(0.5)h Fi(\026)p Fl(m)p 1012 2380 V 62 w(SCN3M,)e(SCN,)h(Tigh)o(t)g(Metal)p 1820 2380 V 1829 2380 V 121 2382 1709 2 v 488 2516 a(T)l(able)g(3:)22 b(MOSIS)15 b(SCMOS)i(tec)o(hnology)e(o\013erings)963 2828 y(3)p eop %%Page: 4 4 bop 0 203 a Fj(3)83 b(CIF)27 b(and)g(GDS)h(La)n(y)n(er)e(Sp)r(eci\014cation)0 313 y Fl(Design)17 b(geometries)e(\(or)h(mask)g(features\))g(can)h(b)q(e)g (represen)o(ted)e(either)h(in)g(GDS-I)q(I)h(or)g(Caltec)o(h)f(In)o(ter-)0 373 y(mediate)d(F)l(orm)h(\(CIF)h(V)l(ersion)g(2.0\).)21 b(While)14 b(the)h(former)f(is)h(co)q(ded)h(in)e(binary)i(format,)e(the)h(latter)g(is)g (a)0 433 y(plain)g(text)g(\014le)f(and)i(can)f(b)q(e)h(easily)e(in)o (terpreted.)19 b(F)l(or)d(detailed)e(syn)o(tax)h(and)h(seman)o(tic)d(sp)q (eci\014cations)0 493 y(of)k(Calma/GDS-I)q(I)f(or)g(CIF,)g(please)g(refer)f (to)i([1])f(and)g([3])g(resp)q(ectiv)o(ely)l(.)73 554 y(In)f(GDS)g(I)q(I)f (format,)g(a)h(mask)f(la)o(y)o(er)f(is)i(sp)q(eci\014ed)f(b)o(y)g(a)h(la)o(y) o(er)f(n)o(um)o(b)q(er)f(b)q(et)o(w)o(een)h(0)h(and)g(63.)22 b(MOSIS)0 614 y(no)o(w)h(reserv)o(es)f(la)o(y)o(ers)g(n)o(um)o(b)q(erd)g (from)f(21)j(to)g(62)f(for)h(mask)e(sp)q(eci\014cation)h(and)g(future)g (extension.)0 674 y(La)o(y)o(ers)c(de\014ned)f(out)i(of)f(this)g(range)g(can) g(b)q(e)g(used)g(b)o(y)g(customers)f(for)h(their)f(o)o(wn)h(purp)q(ose.)31 b(MOSIS)0 734 y(will)15 b(ignore)h(all)f(geometry)g(information)f(on)j(these) e(la)o(y)o(ers)g(\(0)h(to)h(20)f(and)h(63\))f(and)h(map)e(it)g(to)i(the)e (CIF)0 794 y(commen)o(t)c(la)o(y)o(er)h(\(CX\))i(if)g(necessary)l(.)20 b(In)14 b(this)g(revision,)f(6)h(new)g(la)o(y)o(ers)f(are)h(added)h(starting) f(from)f(la)o(y)o(er)0 855 y(n)o(um)o(b)q(er)h(21.)73 956 y Fd(\017)24 b Fl(CVP)f(\(la)o(y)o(er)g(21\))h(is)f(used)h(to)g(indicate)e (high-v)o(oltage)i Fk(p)p Fl(-t)o(yp)q(e)f(area.)44 b(More)23 b(comprehensiv)o(e)122 1017 y(information)15 b(can)i(b)q(e)f(found)h(in)f ([2].)73 1118 y Fd(\017)24 b Fl(CVN)16 b(\(la)o(y)o(er)e(22\))j(is)f(used)h (to)f(indicate)g(high-v)o(oltage)g Fk(p)p Fl(-t)o(yp)q(e)g(area.)73 1220 y Fd(\017)24 b Fl(COP)17 b(\(la)o(y)o(er)d(23\))j(is)f(used)h(to)f (indicate)g(substrate)h(pit)e(op)q(ening)i(area)g(for)g(MEMS)e(devices.)73 1322 y Fd(\017)24 b Fl(CPS)17 b(\(la)o(y)o(er)e(24\))i(is)f(used)g(to)h (indicate)e(substrate)i Fi(p)1095 1304 y Fe(+)1141 1322 y Fl(etc)o(hing-stop) f(area)h(for)f(MEMS)g(devices.)73 1423 y Fd(\017)24 b Fl(CCC)17 b(\(la)o(y)o(er)e(25\))i(is)f(used)g(for)h(generic)e(con)o(tact.)73 1525 y Fd(\017)24 b Fl(XP)16 b(\(la)o(y)o(er)f(26\))i(is)f(used)g(to)h (indicated)e(pad)i(lo)q(cation.)73 1627 y(Users)i(should)g(b)q(e)g(a)o(w)o (are)g(that)g(there)g(exist)f(only)g Fk(one)i Fl(t)o(yp)q(e)e(of)h(ph)o (ysical)f(con)o(tact)h(\(i.e.)28 b(b)q(et)o(w)o(een)0 1687 y(\014rst)19 b(metal)f(and)h(p)q(oly)g(or)h(activ)o(e\),)e(though)i(sev)o (eral)e(ha)o(v)o(e)g(b)q(een)h(de\014ned)g(for)g(historical)g(reason)g(and)0 1747 y(are)e(retained)g(for)h(bac)o(kw)o(ard)f(compatibilit)o(y)l(.)22 b(A)17 b(complete)e(list)i(of)g(SCMOS)h(la)o(y)o(ers)e(can)i(b)q(e)f(found)h (in)0 1807 y(T)l(able)e(4)h(on)g(next)e(page.)0 1974 y Fj(4)83 b(Sub-micron)25 b(Rules)0 2083 y Fl(The)18 b(SCMOS)g(design)h(rules)e(ha)o(v) o(e)h(b)q(een)g(historically)e(designed)i(for)h(1.0)f(-)h(3.0)f(micron)f (CMOS)h(tec)o(h-)0 2143 y(nology)l(.)j(T)l(o)15 b(tak)o(e)e(full)h(adv)m(an)o (tage)h(of)g(adv)m(anced)f(submicron)f(pro)q(cess)i(tec)o(hnology)l(,)f(a)g (set)h(of)f(rules)g(ha)o(v)o(e)0 2204 y(b)q(een)i(selected)f(to)i(b)q(e)f(mo) q(di\014ed)f(to)i(\014t)f(our)h(foundry's)f(rules.)73 2264 y(T)l(able)j(5)h(lists)f(those)h(rules)f(in)g(MOSIS's)g(HP)g(CMOS26G)h(pro)q (cess)g(that)g(are)f(di\013eren)o(t)g(b)q(et)o(w)o(een)0 2324 y(SCN3M)e(and)h(SCN3M)p 452 2324 15 2 v 17 w(26G)g(tec)o(hnology)f(sp)q (eci\014cation)g(with)g Fi(\025)g Fl(equals)g(to)h(0.5)f(and)h(0.4)f Fi(\026)p Fl(m)f(resp)q(ec-)0 2384 y(tiv)o(ely)l(.)963 2828 y(4)p eop %%Page: 5 5 bop 86 660 1778 2 v 85 721 2 61 v 94 721 V 119 703 a Fl(SCMOS)17 b(la)o(y)o(er)p 602 721 V 217 w(CIF)f(name)p 1157 721 V 339 w(GDS)h(I)q(I)e(n)o(um)o(b)q(er)p 1540 721 V 48 w(GDS)i(I)q(I)f(t)o(yp)q(e)p 1855 721 V 1864 721 V 86 722 1778 2 v 85 783 2 61 v 94 783 V 119 764 a(P)p 155 764 15 2 v 18 w(HIGH)p 303 764 V 17 w(V)o(OL)l(T)l(A)o (GE)p 602 783 2 61 v 73 w(CVP)p 1157 783 V 592 w(21)p 1540 783 V 317 w(-)p 1855 783 V 1864 783 V 85 843 V 94 843 V 119 825 a(N)p 159 825 15 2 v 17 w(HIGH)p 306 825 V 17 w(V)o(OL)l(T)l(A)o(GE)p 602 843 2 61 v 70 w(CVN)p 1157 843 V 588 w(22)p 1540 843 V 317 w(-)p 1855 843 V 1864 843 V 85 903 V 94 903 V 119 885 a(MEMS)p 272 885 15 2 v 18 w(OPEN)p 602 903 2 61 v 200 w(COP)p 1157 903 V 591 w(23)p 1540 903 V 317 w(-)p 1855 903 V 1864 903 V 85 963 V 94 963 V 119 945 a(MEMS)p 272 945 15 2 v 18 w(ETCH)p 430 945 V 17 w(STOP)p 602 963 2 61 v 51 w(CPS)p 1157 963 V 602 w(24)p 1540 963 V 317 w(-)p 1855 963 V 1864 963 V 85 1023 V 94 1023 V 119 1005 a(P)l(ADS)p 602 1023 V 379 w(XP)p 1157 1023 V 627 w(26)p 1540 1023 V 317 w(-)p 1855 1023 V 1864 1023 V 85 1083 V 94 1083 V 119 1065 a(P)p 155 1065 15 2 v 18 w(WELL)p 602 1083 2 61 v 315 w(CWP)p 1157 1083 V 579 w(41)p 1540 1083 V 317 w(-)p 1855 1083 V 1864 1083 V 85 1144 V 94 1144 V 119 1126 a(N)p 159 1126 15 2 v 17 w(WELL)p 602 1144 2 61 v 312 w(CWN)p 1157 1144 V 575 w(42)p 1540 1144 V 317 w(-)p 1855 1144 V 1864 1144 V 85 1204 V 94 1204 V 119 1186 a(A)o(CTIVE)p 602 1204 V 315 w(CAA)p 1157 1204 V 588 w(43)p 1540 1204 V 317 w(-)p 1855 1204 V 1864 1204 V 85 1264 V 94 1264 V 119 1246 a(P)p 155 1246 15 2 v 18 w(PLUS)p 300 1246 V 18 w(SELECT)p 602 1264 2 61 v 120 w(CSP)p 1157 1264 V 602 w(44)p 1540 1264 V 317 w(-)p 1855 1264 V 1864 1264 V 85 1324 V 94 1324 V 119 1306 a(N)p 159 1306 15 2 v 17 w(PLUS)p 303 1306 V 18 w(SELECT)p 602 1324 2 61 v 117 w(CSN)p 1157 1324 V 598 w(45)p 1540 1324 V 317 w(-)p 1855 1324 V 1864 1324 V 85 1384 V 94 1384 V 119 1366 a(POL)l(Y)p 602 1384 V 375 w(CPG)p 1157 1384 V 591 w(46)p 1540 1384 V 317 w(-)p 1855 1384 V 1864 1384 V 85 1445 V 94 1445 V 119 1427 a(CONT)l(A)o(CT)p 602 1445 V 262 w(CCC,)g(CCP)l(,)g(CCA,)g(CCE)p 1157 1445 V 75 w(25,)h(47,)f(48,)h(55)p 1540 1445 V 199 w(-)p 1855 1445 V 1864 1445 V 85 1505 V 94 1505 V 119 1487 a(MET)l(AL1)p 602 1505 V 309 w(CMF)p 1157 1505 V 585 w(49)p 1540 1505 V 317 w(-)p 1855 1505 V 1864 1505 V 85 1565 V 94 1565 V 119 1547 a(VIA)p 602 1565 V 417 w(CV)-5 b(A)p 1157 1565 V 593 w(50)p 1540 1565 V 317 w(-)p 1855 1565 V 1864 1565 V 85 1625 V 94 1625 V 119 1607 a(MET)l(AL2)p 602 1625 V 309 w(CMS)p 1157 1625 V 590 w(51)p 1540 1625 V 317 w(-)p 1855 1625 V 1864 1625 V 85 1685 V 94 1685 V 119 1667 a(GLASS)p 602 1685 V 350 w(COG)p 1157 1685 V 586 w(52)p 1540 1685 V 317 w(-)p 1855 1685 V 1864 1685 V 85 1746 V 94 1746 V 119 1728 a(ELECTR)o(ODE)p 602 1746 V 200 w(CEL)p 1157 1746 V 599 w(56)p 1540 1746 V 317 w(-)p 1855 1746 V 1864 1746 V 85 1806 V 94 1806 V 119 1788 a(BURIED)p 318 1788 15 2 v 17 w(CCD)p 602 1806 2 61 v 189 w(CCD)p 1157 1806 V 590 w(57)p 1540 1806 V 317 w(-)p 1855 1806 V 1864 1806 V 85 1866 V 94 1866 V 119 1848 a(PBASE)p 602 1866 V 344 w(CBA)p 1157 1866 V 590 w(58)p 1540 1866 V 317 w(-)p 1855 1866 V 1864 1866 V 85 1926 V 94 1926 V 119 1908 a(CAP)p 227 1908 15 2 v 18 w(WELL)p 602 1926 2 61 v 243 w(CW)o(C)p 1157 1926 V 578 w(59)p 1540 1926 V 317 w(-)p 1855 1926 V 1864 1926 V 85 1986 V 94 1986 V 119 1968 a(VIA2)p 602 1986 V 393 w(CVS)p 1157 1986 V 598 w(61)p 1540 1986 V 317 w(-)p 1855 1986 V 1864 1986 V 85 2047 V 94 2047 V 119 2028 a(MET)l(AL3)p 602 2047 V 309 w(CMT)p 1157 2047 V 582 w(62)p 1540 2047 V 317 w(-)p 1855 2047 V 1864 2047 V 85 2107 V 94 2107 V 119 2089 a(COMMENT)p 602 2107 V 241 w(CX)p 1157 2107 V 549 w(0)17 b(-)f(20,)h(63)p 1540 2107 V 241 w(-)p 1855 2107 V 1864 2107 V 86 2108 1778 2 v 444 2243 a(T)l(able)f(4:)22 b(SCMOS)16 b(tec)o(hnology)g(CIF)g(and)h(GDS)g(la)o(y)o (ers)963 2828 y(5)p eop %%Page: 6 6 bop 96 931 1758 2 v 95 992 2 61 v 104 992 V 640 992 V 897 992 V 950 973 a Fl(SCMOS)p 1173 992 V 138 w(SCMOS)p 1518 992 V 112 w(SCMOS)p 1719 973 15 2 v 17 w(26G)p 1845 992 2 61 v 1854 992 V 95 1052 V 104 1052 V 129 1034 a(Description)p 640 1052 V 347 w(Rule)p 897 1052 V 1173 1052 V 380 w(\(Tigh)o(t)16 b(Metal\))p 1518 1052 V 1845 1052 V 1854 1052 V 95 1112 V 104 1112 V 640 1112 V 897 1112 V 923 1094 a Fi(\025)e Fl(=)g(0)p Fi(:)p Fl(5)p Fi(\026)p Fl(m)p 1173 1112 V 83 w Fi(\025)g Fl(=)g(0)p Fi(:)p Fl(5)p Fi(\026)p Fl(m)p 1518 1112 V 109 w Fi(\025)g Fl(=)g(0)p Fi(:)p Fl(4)p Fi(\026)p Fl(m)p 1845 1112 V 1854 1112 V 96 1114 1758 2 v 95 1174 2 61 v 104 1174 V 129 1156 a(WELL)p 275 1156 15 2 v 19 w(W)p 640 1174 2 61 v 397 w(1.1)p 897 1174 V 211 w(10)p 1173 1174 V 263 w(10)p 1518 1174 V 288 w(12)p 1845 1174 V 1854 1174 V 95 1234 V 104 1234 V 129 1216 a(WELL)p 275 1216 15 2 v 19 w(S)p 321 1216 V 18 w(DIFF)p 640 1234 2 61 v 283 w(1.2)p 897 1234 V 224 w(9)p 1173 1234 V 286 w(9)p 1518 1234 V 300 w(18)p 1845 1234 V 1854 1234 V 95 1294 V 104 1294 V 129 1276 a(WELL)p 275 1276 15 2 v 19 w(O)p 332 1276 V 18 w(A)o(CT)p 456 1276 V 17 w(XTOR)p 640 1294 2 61 v 122 w(2.3)p 897 1294 V 224 w(5)p 1173 1294 V 286 w(5)p 1518 1294 V 312 w(6)p 1845 1294 V 1854 1294 V 95 1354 V 104 1354 V 129 1336 a(WELL)p 275 1336 15 2 v 19 w(S)p 321 1336 V 18 w(A)o(CT)p 445 1336 V 17 w(XTOR)p 640 1354 2 61 v 133 w(2.3)p 897 1354 V 224 w(5)p 1173 1354 V 286 w(5)p 1518 1354 V 312 w(6)p 1845 1354 V 1854 1354 V 95 1415 V 104 1415 V 129 1396 a(POL)l(Y)p 266 1396 15 2 v 18 w(S)p 640 1415 2 61 v 430 w(3.2)p 897 1415 V 224 w(2)p 1173 1415 V 286 w(2)p 1518 1415 V 312 w(3)p 1845 1415 V 1854 1415 V 95 1475 V 104 1475 V 129 1457 a(CON)p 242 1457 15 2 v 18 w(S)p 640 1475 2 61 v 381 w(5B.3,6B.3)p 897 1475 V 151 w(2)p 1173 1475 V 286 w(2)p 1518 1475 V 312 w(3)p 1845 1475 V 1854 1475 V 95 1535 V 104 1535 V 129 1517 a(M1)p 201 1517 15 2 v 18 w(W)p 640 1535 2 61 v 472 w(7.1)p 897 1535 V 224 w(3)p 1173 1535 V 286 w(3)p 1518 1535 V 312 w(3)p 1845 1535 V 1854 1535 V 95 1595 V 104 1595 V 129 1577 a(M1)p 201 1577 15 2 v 18 w(S)p 640 1595 2 61 v 495 w(7.2)p 897 1595 V 224 w(3)p 1173 1595 V 286 w(2)p 1518 1595 V 312 w(3)p 1845 1595 V 1854 1595 V 95 1655 V 104 1655 V 129 1637 a(M2)p 201 1637 15 2 v 18 w(W)p 640 1655 2 61 v 472 w(9.1)p 897 1655 V 224 w(3)p 1173 1655 V 286 w(3)p 1518 1655 V 312 w(3)p 1845 1655 V 1854 1655 V 95 1716 V 104 1716 V 129 1697 a(M2)p 201 1697 15 2 v 18 w(S)p 640 1716 2 61 v 495 w(9.2)p 897 1716 V 224 w(4)p 1173 1716 V 286 w(3)p 1518 1716 V 312 w(3)p 1845 1716 V 1854 1716 V 95 1776 V 104 1776 V 129 1758 a(M3)p 201 1758 15 2 v 18 w(W)p 640 1776 2 61 v 460 w(15.1)p 897 1776 V 212 w(6)p 1173 1776 V 286 w(6)p 1518 1776 V 312 w(5)p 1845 1776 V 1854 1776 V 95 1836 V 104 1836 V 129 1818 a(M3)p 201 1818 15 2 v 18 w(S)p 640 1836 2 61 v 483 w(15.2)p 897 1836 V 212 w(4)p 1173 1836 V 286 w(4)p 1518 1836 V 312 w(3)p 1845 1836 V 1854 1836 V 96 1838 1758 2 v 545 1972 a(T)l(able)i(5:)22 b(SCMOS)16 b(options)h(for)g (CMOS26G)963 2828 y(6)p eop %%Page: 7 7 bop 0 203 a Fj(5)83 b(SCMOS)27 b(Design)g(Rules)0 327 y Fo(W)-6 b(ell)21 b(\(CWN,)h(CWP\))30 456 y Fn(1.1)102 b(Minim)n(um)18 b(width)1073 b(10)30 531 y(1.2)102 b(Minim)n(um)18 b(spacing)g(b)r(et)n(w)n (een)i(w)n(ells)f(at)h(di\013eren)n(t)g(p)r(oten)n(tial)92 b(9)30 606 y(1.3)102 b(Minim)n(um)18 b(spacing)g(b)r(et)n(w)n(een)i(w)n(ells) f(at)h(same)e(p)r(oten)n(tial)178 b(0)19 b(or)i(6)30 680 y(1.4)102 b(Minim)n(um)18 b(spacing)g(b)r(et)n(w)n(een)i(w)n(ells)f(of)h(di\013eren)n (t)g(t)n(yp)r(e)209 755 y(\(if)g(b)r(oth)g(are)g(dra)n(wn\))993 b(0)263 1114 y 22497362 15721841 8880537 18155765 31377899 33877606 startTexFig 263 1114 a %%BeginDocument: ciffig/well2.ps /$F2psDict 32 dict def $F2psDict begin $F2psDict /mtrx matrix put end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin -45.000000 662.000000 translate 0.900000 -0.900000 scale 1.000 setlinewidth newpath 292.000 307.000 moveto 294.000 299.000 lineto 296.000 307.000 lineto stroke newpath 294 299 moveto 294 329 lineto stroke newpath 296.000 321.000 moveto 294.000 329.000 lineto 292.000 321.000 lineto stroke [1 3.000000] 0 setdash newpath 199 329 moveto 279 329 lineto 279 429 lineto 199 429 lineto closepath stroke [] 0 setdash newpath 349.000 316.000 moveto 341.000 314.000 lineto 349.000 312.000 lineto stroke newpath 341 314 moveto 417 314 lineto stroke newpath 409.000 312.000 moveto 417.000 314.000 lineto 409.000 316.000 lineto stroke newpath 429.000 186.000 moveto 421.000 184.000 lineto 429.000 182.000 lineto stroke newpath 421 184 moveto 497 184 lineto stroke newpath 489.000 182.000 moveto 497.000 184.000 lineto 489.000 186.000 lineto stroke newpath 289.000 186.000 moveto 281.000 184.000 lineto 289.000 182.000 lineto stroke newpath 281 184 moveto 337 184 lineto stroke newpath 329.000 182.000 moveto 337.000 184.000 lineto 329.000 186.000 lineto stroke [4.000000] 0 setdash newpath 499 299 moveto 579 299 lineto 579 199 lineto 499 199 lineto closepath stroke [] 0 setdash [4.000000] 0 setdash newpath 339 299 moveto 419 299 lineto 419 199 lineto 339 199 lineto closepath stroke [] 0 setdash [4.000000] 0 setdash newpath 199 299 moveto 279 299 lineto 279 199 lineto 199 199 lineto closepath stroke [] 0 setdash /fn0.16 /Times-Roman findfont 17.777778 scalefont def fn0.16 setfont (1.4) 265 320 moveto 1 -1 scale show 1 -1 scale /fn0.12 /Times-Roman findfont 13.333333 scalefont def fn0.12 setfont (CWN) 544 293 moveto 1 -1 scale show 1 -1 scale (CWN) 384 294 moveto 1 -1 scale show 1 -1 scale (CWN) 245 294 moveto 1 -1 scale show 1 -1 scale (CWP) 247 424 moveto 1 -1 scale show 1 -1 scale /fn0.15 /Times-Roman findfont 16.666667 scalefont def fn0.15 setfont (1.3) 448 178 moveto 1 -1 scale show 1 -1 scale (1.2) 297 177 moveto 1 -1 scale show 1 -1 scale (1.1) 369 334 moveto 1 -1 scale show 1 -1 scale showpage $F2psEnd %%EndDocument 263 1114 a endTexFig 963 2828 a Fl(7)p eop %%Page: 8 8 bop 0 198 a Fo(Activ)n(e)21 b(\(CAA\))30 327 y Fn(2.1)102 b(Minim)n(um)18 b(width)1073 b(3)30 402 y(2.2)102 b(Minim)n(um)18 b(spacing)1028 b(3)30 477 y(2.3)102 b(Source/drain)20 b(activ)n(e)f(to)h(w)n(ell)f(edge)652 b(5)30 551 y(2.4)102 b(Substrate/w)n(ell)20 b(con)n(tact)g(activ)n(e)e(to)j (w)n(ell)e(edge)399 b(3)30 626 y(2.5)102 b(Minim)n(um)18 b(spacing)g(b)r(et)n (w)n(een)i(activ)n(e)f(of)h(di\013eren)n(t)g(implan)n(t)100 b(0)19 b(or)i(4)338 1045 y 20129218 17300602 0 0 20129218 17300602 startTexFig 338 1045 a %%BeginDocument: ciffig/active.ps /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /l {lineto} bind def /m {moveto} bind def /s {stroke} bind def /n {newpath} bind def /gs {gsave} bind def /gr {grestore} bind def /clp {closepath} bind def /graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul setrgbcolor} bind def /col-1 {} def /col0 {0 0 0 setrgbcolor} bind def /col1 {0 0 1 setrgbcolor} bind def /col2 {0 1 0 setrgbcolor} bind def /col3 {0 1 1 setrgbcolor} bind def /col4 {1 0 0 setrgbcolor} bind def /col5 {1 0 1 setrgbcolor} bind def /col6 {1 1 0 setrgbcolor} bind def /col7 {1 1 1 setrgbcolor} bind def end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 0 setlinecap 0 setlinejoin -122.0 358.0 translate 0.900 -0.900 scale 0.500 setlinewidth n 442.000 229.000 m 444.000 221.000 l 446.000 229.000 l gs 2 setlinejoin col0 s gr n 444 221 m 444 247 l gs col0 s gr n 446.000 239.000 m 444.000 247.000 l 442.000 239.000 l gs 2 setlinejoin col0 s gr n 442.000 259.000 m 444.000 251.000 l 446.000 259.000 l gs 2 setlinejoin col0 s gr n 444 251 m 444 277 l gs col0 s gr n 446.000 269.000 m 444.000 277.000 l 442.000 269.000 l gs 2 setlinejoin col0 s gr n 259.000 126.000 m 251.000 124.000 l 259.000 122.000 l gs 2 setlinejoin col0 s gr n 251 124 m 277 124 l gs col0 s gr n 269.000 122.000 m 277.000 124.000 l 269.000 126.000 l gs 2 setlinejoin col0 s gr n 339.000 126.000 m 331.000 124.000 l 339.000 122.000 l gs 2 setlinejoin col0 s gr n 331 124 m 367 124 l gs col0 s gr n 359.000 122.000 m 367.000 124.000 l 359.000 126.000 l gs 2 setlinejoin col0 s gr n 339.000 376.000 m 331.000 374.000 l 339.000 372.000 l gs 2 setlinejoin col0 s gr n 331 374 m 367 374 l gs col0 s gr n 359.000 372.000 m 367.000 374.000 l 359.000 376.000 l gs 2 setlinejoin col0 s gr n 259.000 376.000 m 251.000 374.000 l 259.000 372.000 l gs 2 setlinejoin col0 s gr n 251 374 m 277 374 l gs col0 s gr n 269.000 372.000 m 277.000 374.000 l 269.000 376.000 l gs 2 setlinejoin col0 s gr n 162.000 169.000 m 164.000 161.000 l 166.000 169.000 l gs 2 setlinejoin col0 s gr n 164 161 m 164 197 l gs col0 s gr n 166.000 189.000 m 164.000 197.000 l 162.000 189.000 l gs 2 setlinejoin col0 s gr n 162.000 309.000 m 164.000 301.000 l 166.000 309.000 l gs 2 setlinejoin col0 s gr n 164 301 m 164 337 l gs col0 s gr n 166.000 329.000 m 164.000 337.000 l 162.000 329.000 l gs 2 setlinejoin col0 s gr n 439 249 m 459 249 l gs col0 s gr 1 setlinecap [1 3.000000] 3.000000 setdash n 349 239 m 429 239 l 429 139 l 349 139 l clp gs col0 s gr [] 0 setdash 0 setlinecap [4.000000] 0 setdash n 349 359 m 429 359 l 429 259 l 349 259 l clp gs col0 s gr [] 0 setdash 1 setlinecap [1 3.000000] 3.000000 setdash n 179 359 m 349 359 l 349 279 l 179 279 l clp gs col0 s gr [] 0 setdash 0 setlinecap [4.000000] 0 setdash n 179 219 m 349 219 l 349 139 l 179 139 l clp gs col0 s gr [] 0 setdash n 302.000 259.000 m 304.000 251.000 l 306.000 259.000 l gs 2 setlinejoin col0 s gr n 304 251 m 304 297 l gs col0 s gr n 306.000 289.000 m 304.000 297.000 l 302.000 289.000 l gs 2 setlinejoin col0 s gr n 302.000 209.000 m 304.000 201.000 l 306.000 209.000 l gs 2 setlinejoin col0 s gr n 304 201 m 304 247 l gs col0 s gr n 306.000 239.000 m 304.000 247.000 l 302.000 239.000 l gs 2 setlinejoin col0 s gr n 135 249 m 160 249 l gs col0 s gr n 159 249 m 439 249 l gs col0 s gr 0.000 setlinewidth n 199 299 m 249 299 l 249 339 l 199 339 l clp gs 0.75 setgray fill gr n 279 299 m 329 299 l 329 339 l 279 339 l clp gs 0.75 setgray fill gr n 369 279 m 409 279 l 409 339 l 369 339 l clp gs 0.75 setgray fill gr n 369 219 m 409 219 l 409 159 l 369 159 l clp gs 0.75 setgray fill gr n 279 199 m 329 199 l 329 159 l 279 159 l clp gs 0.75 setgray fill gr n 199 199 m 249 199 l 249 159 l 199 159 l clp gs 0.75 setgray fill gr /Times-Roman findfont 12.00 scalefont setfont 211 184 m gs 1 -1 scale (CAA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 211 324 m gs 1 -1 scale (CAA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 293 324 m gs 1 -1 scale (CAA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 377 194 m gs 1 -1 scale (CAA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 376 316 m gs 1 -1 scale (CAA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 293 184 m gs 1 -1 scale (CAA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 403 234 m gs 1 -1 scale (CSP) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 184 354 m gs 1 -1 scale (CSP) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 183 214 m gs 1 -1 scale (CSN) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 400 355 m gs 1 -1 scale (CSN) col0 show gr /Times-Roman findfont 9.00 scalefont setfont 159 229 m gs 1 -1 scale (_) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 169 243 m gs 1 -1 scale (region) col0 show gr /Times-Roman findfont 9.00 scalefont setfont 159 258 m gs 1 -1 scale (_) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 146 243 m gs 1 -1 scale (P) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 169 273 m gs 1 -1 scale (region) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 145 273 m gs 1 -1 scale (N) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 137 325 m gs 1 -1 scale (2.1) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 338 118 m gs 1 -1 scale (2.5) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 253 118 m gs 1 -1 scale (2.2) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 137 186 m gs 1 -1 scale (2.1) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 274 238 m gs 1 -1 scale (2.3) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 453 241 m gs 1 -1 scale (2.4) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 313 273 m gs 1 -1 scale (2.3) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 452 272 m gs 1 -1 scale (2.4) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 336 397 m gs 1 -1 scale (2.5) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 252 396 m gs 1 -1 scale (2.2) col0 show gr $F2psEnd %%EndDocument 338 1045 a endTexFig 963 2828 a Fl(8)p eop %%Page: 9 9 bop 0 198 a Fo(P)n(oly)23 b(\(CPG\))30 327 y Fn(3.1)102 b(Minim)n(um)18 b(width)1073 b(2)30 402 y(3.2)102 b(Minim)n(um)18 b(spacing)1028 b(2)30 477 y(3.3)102 b(Minim)n(um)18 b(gate)h(extension)f(of)i(activ)n(e)607 b(2)30 551 y(3.4)102 b(Minim)n(um)18 b(activ)n(e)g(extension)h(of)h(plo)n(y) 607 b(3)30 626 y(3.5)102 b(Minim)n(um)18 b(\014eld)h(p)r(oly)g(to)h(activ)n (e)733 b(1)548 940 y 13485260 14471987 0 0 13485260 14471987 startTexFig 548 940 a %%BeginDocument: ciffig/poly.ps /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /l {lineto} bind def /m {moveto} bind def /s {stroke} bind def /n {newpath} bind def /gs {gsave} bind def /gr {grestore} bind def /clp {closepath} bind def /graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul setrgbcolor} bind def /col-1 {} def /col0 {0 0 0 setrgbcolor} bind def /col1 {0 0 1 setrgbcolor} bind def /col2 {0 1 0 setrgbcolor} bind def /col3 {0 1 1 setrgbcolor} bind def /col4 {1 0 0 setrgbcolor} bind def /col5 {1 0 1 setrgbcolor} bind def /col6 {1 1 0 setrgbcolor} bind def /col7 {1 1 1 setrgbcolor} bind def end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 0 setlinecap 0 setlinejoin -182.0 291.0 translate 0.900 -0.900 scale 0.500 setlinewidth n 377.000 247.000 m 379.000 239.000 l 381.000 247.000 l gs 2 setlinejoin col0 s gr n 379 239 m 379 269 l gs col0 s gr n 381.000 261.000 m 379.000 269.000 l 377.000 261.000 l gs 2 setlinejoin col0 s gr n 399 164 m 399 177 l gs col0 s gr n 401.000 169.000 m 399.000 177.000 l 397.000 169.000 l gs 2 setlinejoin col0 s gr n 399 214 m 399 201 l gs col0 s gr n 397.000 209.000 m 399.000 201.000 l 401.000 209.000 l gs 2 setlinejoin col0 s gr n 359 234 m 359 221 l gs col0 s gr n 357.000 229.000 m 359.000 221.000 l 361.000 229.000 l gs 2 setlinejoin col0 s gr n 359 184 m 359 197 l gs col0 s gr n 361.000 189.000 m 359.000 197.000 l 357.000 189.000 l gs 2 setlinejoin col0 s gr n 354 299 m 341 299 l gs col0 s gr n 349.000 301.000 m 341.000 299.000 l 349.000 297.000 l gs 2 setlinejoin col0 s gr n 304 299 m 317 299 l gs col0 s gr n 309.000 297.000 m 317.000 299.000 l 309.000 301.000 l gs 2 setlinejoin col0 s gr n 274 99 m 261 99 l gs col0 s gr n 269.000 101.000 m 261.000 99.000 l 269.000 97.000 l gs 2 setlinejoin col0 s gr n 234 99 m 247 99 l gs col0 s gr n 239.000 97.000 m 247.000 99.000 l 239.000 101.000 l gs 2 setlinejoin col0 s gr 0.000 setlinewidth n 229 179 m 249 179 l 249 129 l 229 129 l clp gs 0.50 setgray fill gr n 229 239 m 249 239 l 249 279 l 229 279 l clp gs 0.50 setgray fill gr n 229 219 m 259 219 l 259 239 l 229 239 l clp gs 0.50 setgray fill gr n 229 179 m 259 179 l 259 199 l 229 199 l clp gs 0.50 setgray fill gr n 259 239 m 319 239 l 319 219 l 259 219 l clp gs 0.30 setgray fill gr n 259 199 m 319 199 l 319 179 l 259 179 l clp gs 0.30 setgray fill gr n 259 239 m 319 239 l 319 269 l 259 269 l clp gs 0.75 setgray fill gr n 259 219 m 319 219 l 319 199 l 259 199 l clp gs 0.75 setgray fill gr n 319 239 m 339 239 l 339 219 l 319 219 l clp gs 0.50 setgray fill gr n 319 199 m 339 199 l 339 179 l 319 179 l clp gs 0.50 setgray fill gr n 259 179 m 319 179 l 319 159 l 259 159 l clp gs 0.75 setgray fill gr n 259 159 m 379 159 l 379 119 l 259 119 l clp gs 0.75 setgray fill gr /Times-Roman findfont 12.00 scalefont setfont 288 263 m gs 1 -1 scale (CAA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 202 167 m gs 1 -1 scale (CPG) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 203 264 m gs 1 -1 scale (CPG) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 339 138 m gs 1 -1 scale (CAA) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 387 260 m gs 1 -1 scale (3.4) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 243 91 m gs 1 -1 scale (3.5) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 407 195 m gs 1 -1 scale (3.1) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 367 216 m gs 1 -1 scale (3.2) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 319 323 m gs 1 -1 scale (3.3) col0 show gr $F2psEnd %%EndDocument 548 940 a endTexFig 963 2828 a Fl(9)p eop %%Page: 10 10 bop 0 198 a Fo(Select)20 b(\(CSN,)j(CSP\))30 327 y Fn(4.1)102 b(Minim)n(um)18 b(select)g(spacing)g(to)j(c)n(hannel)e(of)h(transistor)g(to) 209 402 y(ensure)g(adequate)f(source/drain)g(width)556 b(3)30 477 y(4.2)102 b(Minim)n(um)18 b(select)g(o)n(v)n(erlap)h(of)h(activ)n(e)630 b(2)30 551 y(4.3)102 b(Minim)n(um)18 b(select)g(o)n(v)n(erlap)h(of)h(con)n (tact)593 b(1)30 626 y(4.4)102 b(Minim)n(um)18 b(select)g(width)i(and)g (spacing)580 b(2)209 701 y(\(Note:)26 b(P-select)18 b(and)i(N-select)e(ma)n (y)g(b)r(e)i(coinciden)n(t,)e(but)229 775 y(m)n(ust)h Fm(not)g Fn(o)n(v)n(erlap\))308 1165 y 21050163 14669332 0 0 21050163 14669332 startTexFig 308 1165 a %%BeginDocument: ciffig/select.ps /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /l {lineto} bind def /m {moveto} bind def /s {stroke} bind def /n {newpath} bind def /gs {gsave} bind def /gr {grestore} bind def /clp {closepath} bind def /graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul setrgbcolor} bind def /col-1 {} def /col0 {0 0 0 setrgbcolor} bind def /col1 {0 0 1 setrgbcolor} bind def /col2 {0 1 0 setrgbcolor} bind def /col3 {0 1 1 setrgbcolor} bind def /col4 {1 0 0 setrgbcolor} bind def /col5 {1 0 1 setrgbcolor} bind def /col6 {1 1 0 setrgbcolor} bind def /col7 {1 1 1 setrgbcolor} bind def end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 0 setlinecap 0 setlinejoin -112.0 302.0 translate 0.900 -0.900 scale 0.500 setlinewidth n 174 125 m 189 125 l gs col0 s gr n 181.000 123.000 m 189.000 125.000 l 181.000 127.000 l gs 2 setlinejoin col0 s gr n 208.000 127.000 m 200.000 125.000 l 208.000 123.000 l gs 2 setlinejoin col0 s gr n 200 125 m 215 125 l gs col0 s gr n 217.000 106.000 m 209.000 104.000 l 217.000 102.000 l gs 2 setlinejoin col0 s gr n 209 104 m 224 104 l gs col0 s gr n 184 104 m 199 104 l gs col0 s gr n 191.000 102.000 m 199.000 104.000 l 191.000 106.000 l gs 2 setlinejoin col0 s gr 0.000 setlinewidth n 159 179 m 169 179 l 169 159 l 159 159 l clp gs 0.75 setgray fill gr n 189 179 m 209 179 l 209 159 l 189 159 l clp gs 0.75 setgray fill gr n 159 159 m 209 159 l 209 149 l 159 149 l clp gs 0.75 setgray fill gr n 169 159 m 189 159 l 189 179 l 169 179 l clp gs 0.00 setgray fill gr 0.500 setlinewidth n 174 314 m 161 314 l gs col0 s gr n 169.000 316.000 m 161.000 314.000 l 169.000 312.000 l gs 2 setlinejoin col0 s gr n 124 314 m 137 314 l gs col0 s gr n 129.000 312.000 m 137.000 314.000 l 129.000 316.000 l gs 2 setlinejoin col0 s gr n 272.000 199.000 m 274.000 191.000 l 276.000 199.000 l gs 2 setlinejoin col0 s gr n 274 191 m 274 217 l gs col0 s gr n 276.000 209.000 m 274.000 217.000 l 272.000 209.000 l gs 2 setlinejoin col0 s gr 0.000 setlinewidth n 359 239 m 449 239 l 449 219 l 359 219 l clp gs 0.35 setgray fill gr n 159 239 m 239 239 l 239 219 l 159 219 l clp gs 0.35 setgray fill gr n 419 159 m 439 159 l 439 149 l 419 149 l clp gs 0.75 setgray fill gr n 359 179 m 419 179 l 419 149 l 359 149 l clp gs 0.75 setgray fill gr n 359 219 m 439 219 l 439 179 l 359 179 l clp gs 0.75 setgray fill gr n 419 179 m 439 179 l 439 159 l 419 159 l clp gs 0.00 setgray fill gr n 229 179 m 239 179 l 239 159 l 229 159 l clp gs 0.75 setgray fill gr n 209 159 m 239 159 l 239 149 l 209 149 l clp gs 0.75 setgray fill gr n 159 219 m 239 219 l 239 179 l 159 179 l clp gs 0.75 setgray fill gr 0.500 setlinewidth n 209 179 m 229 179 l 229 159 l 209 159 l clp gs 0.00 setgray fill gr gs col0 s gr 1.000 setlinewidth 1 setlinecap [1 3.000000] 3.000000 setdash n 409 189 m 469 189 l gs col0 s gr [] 0 setdash 0 setlinecap 1 setlinecap [1 3.000000] 3.000000 setdash n 409 109 m 409 189 l gs col0 s gr [] 0 setdash 0 setlinecap 1 setlinecap [1 3.000000] 3.000000 setdash n 339 109 m 409 109 l gs col0 s gr [] 0 setdash 0 setlinecap 1 setlinecap [1 3.000000] 3.000000 setdash n 469 299 m 469 189 l gs col0 s gr [] 0 setdash 0 setlinecap 1 setlinecap [1 3.000000] 3.000000 setdash n 339 299 m 469 299 l gs col0 s gr [] 0 setdash 0 setlinecap 1 setlinecap [1 3.000000] 3.000000 setdash n 339 109 m 339 299 l gs col0 s gr [] 0 setdash 0 setlinecap 1 setlinecap [1 3.000000] 3.000000 setdash n 199 189 m 259 189 l 259 129 l 199 129 l clp gs col0 s gr [] 0 setdash 0 setlinecap 0.500 setlinewidth n 319 109 m 319 319 l gs col0 s gr [4.000000] 0 setdash n 409 129 m 469 129 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 469 189 m 469 129 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 409 189 m 469 189 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 409 129 m 409 189 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 199 129 m 199 189 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 139 129 m 199 129 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 139 129 m 139 299 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 199 189 m 259 189 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 259 299 m 259 189 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 139 299 m 259 299 l gs col0 s gr [] 0 setdash 0.000 setlinewidth n 459 269 m 479 269 l 479 239 l 459 239 l clp gs 0.50 setgray fill gr n 449 239 m 479 239 l 479 219 l 449 219 l clp gs 0.50 setgray fill gr n 439 219 m 449 219 l 449 149 l 439 149 l clp gs 0.75 setgray fill gr n 439 279 m 449 279 l 449 239 l 439 239 l clp gs 0.75 setgray fill gr n 359 149 m 389 149 l 389 129 l 359 129 l clp gs 0.75 setgray fill gr n 359 279 m 439 279 l 439 239 l 359 239 l clp gs 0.75 setgray fill gr n 159 279 m 239 279 l 239 239 l 159 239 l clp gs 0.75 setgray fill gr n 339 239 m 359 239 l 359 219 l 339 219 l clp gs 0.50 setgray fill gr n 239 239 m 339 239 l 339 219 l 239 219 l clp gs 0.50 setgray fill gr n 139 239 m 159 239 l 159 219 l 139 219 l clp gs 0.50 setgray fill gr /Times-Roman findfont 15.00 scalefont setfont 185 122 m gs 1 -1 scale (4.3) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 232 174 m gs 1 -1 scale (CCA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 231 144 m gs 1 -1 scale (CSP) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 441 144 m gs 1 -1 scale (CSN) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 208 275 m gs 1 -1 scale (CAA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 278 253 m gs 1 -1 scale (CPG) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 416 274 m gs 1 -1 scale (CAA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 343 294 m gs 1 -1 scale (CSP) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 143 295 m gs 1 -1 scale (CSN) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 275 335 m gs 1 -1 scale (CWP) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 439 335 m gs 1 -1 scale (CWN) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 196 100 m gs 1 -1 scale (4.3) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 138 334 m gs 1 -1 scale (4.2) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 280 211 m gs 1 -1 scale (4.1) col0 show gr $F2psEnd %%EndDocument 308 1165 a endTexFig 951 2828 a Fl(10)p eop %%Page: 11 11 bop 0 198 a Fo(Simpl)o(e)19 b(Con)n(tact)k(to)g(P)n(oly)g(\(CCP\))30 327 y Fn(5.1.a)55 b(Exact)19 b(con)n(tact)h(size)1017 b(2)19 b Fc(\002)i Fn(2)30 402 y(5.2.a)55 b(Minim)n(um)18 b(p)r(oly)g(o)n(v)n(erlap) 902 b(1.5)30 477 y(5.3.a)55 b(Minim)n(um)18 b(con)n(tact)h(spacing)818 b(2)615 1136 y 11380244 7630684 0 0 11380244 7630684 startTexFig 615 1136 a %%BeginDocument: ciffig/contact1.ps /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /l {lineto} bind def /m {moveto} bind def /s {stroke} bind def /n {newpath} bind def /gs {gsave} bind def /gr {grestore} bind def /clp {closepath} bind def /graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul setrgbcolor} bind def /col-1 {} def /col0 {0 0 0 setrgbcolor} bind def /col1 {0 0 1 setrgbcolor} bind def /col2 {0 1 0 setrgbcolor} bind def /col3 {0 1 1 setrgbcolor} bind def /col4 {1 0 0 setrgbcolor} bind def /col5 {1 0 1 setrgbcolor} bind def /col6 {1 1 0 setrgbcolor} bind def /col7 {1 1 1 setrgbcolor} bind def end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 0 setlinecap 0 setlinejoin -238.0 267.0 translate 0.900 -0.900 scale n 264 204 m 394 204 l 394 254 l 264 254 l clp gs 0.70 setgray fill gr 0.500 setlinewidth n 414 234 m 414 221 l gs col0 s gr n 412.000 229.000 m 414.000 221.000 l 416.000 229.000 l gs 2 setlinejoin col0 s gr n 414 189 m 414 204 l gs col0 s gr n 416.000 196.000 m 414.000 204.000 l 412.000 196.000 l gs 2 setlinejoin col0 s gr n 372 189 m 359 189 l gs col0 s gr n 367.000 191.000 m 359.000 189.000 l 367.000 187.000 l gs 2 setlinejoin col0 s gr n 326 189 m 339 189 l gs col0 s gr n 331.000 187.000 m 339.000 189.000 l 331.000 191.000 l gs 2 setlinejoin col0 s gr n 314 274 m 301 274 l gs col0 s gr n 309.000 276.000 m 301.000 274.000 l 309.000 272.000 l gs 2 setlinejoin col0 s gr n 264 274 m 277 274 l gs col0 s gr n 269.000 272.000 m 277.000 274.000 l 269.000 276.000 l gs 2 setlinejoin col0 s gr 0.000 setlinewidth n 359 239 m 379 239 l 379 219 l 359 219 l clp gs 0.00 setgray fill gr n 319 239 m 339 239 l 339 219 l 319 219 l clp gs 0.00 setgray fill gr n 279 239 m 299 239 l 299 219 l 279 219 l clp gs 0.00 setgray fill gr /Times-Roman findfont 16.00 scalefont setfont 422 218 m gs 1 -1 scale (5.2.a) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 333 181 m gs 1 -1 scale (5.3.a) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 272 296 m gs 1 -1 scale (5.1.a) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 269 217 m gs 1 -1 scale (CCP) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 372 255 m gs 1 -1 scale (CPG) col0 show gr $F2psEnd %%EndDocument 615 1136 a endTexFig 951 2828 a Fl(11)p eop %%Page: 12 12 bop 0 198 a Fo(Simpl)o(e)19 b(Con)n(tact)k(to)g(Activ)n(e)e(\(CCA\))30 327 y Fn(6.1.a)55 b(Exact)19 b(con)n(tact)h(size)1017 b(2)19 b Fc(\002)i Fn(2)30 402 y(6.2.a)55 b(Minim)n(um)18 b(activ)n(e)g(o)n(v)n (erlap)862 b(1.5)30 477 y(6.3.a)55 b(Minim)n(um)18 b(con)n(tact)h(spacing)818 b(2)30 551 y(6.4.a)55 b(Minim)n(um)18 b(spacing)g(to)i(gate)g(of)g (transistor)489 b(2)590 1120 y 12169625 10788208 0 0 12169625 10788208 startTexFig 590 1120 a %%BeginDocument: ciffig/acon1.ps /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /l {lineto} bind def /m {moveto} bind def /s {stroke} bind def /n {newpath} bind def /gs {gsave} bind def /gr {grestore} bind def /clp {closepath} bind def /graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul setrgbcolor} bind def /col-1 {} def /col0 {0 0 0 setrgbcolor} bind def /col1 {0 0 1 setrgbcolor} bind def /col2 {0 1 0 setrgbcolor} bind def /col3 {0 1 1 setrgbcolor} bind def /col4 {1 0 0 setrgbcolor} bind def /col5 {1 0 1 setrgbcolor} bind def /col6 {1 1 0 setrgbcolor} bind def /col7 {1 1 1 setrgbcolor} bind def end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 0 setlinecap 0 setlinejoin -216.0 305.0 translate 0.900 -0.900 scale 0.500 setlinewidth n 404 254 m 404 241 l gs col0 s gr n 402.000 249.000 m 404.000 241.000 l 406.000 249.000 l gs 2 setlinejoin col0 s gr n 404 204 m 404 217 l gs col0 s gr n 406.000 209.000 m 404.000 217.000 l 402.000 209.000 l gs 2 setlinejoin col0 s gr n 354 179 m 341 179 l gs col0 s gr n 349.000 181.000 m 341.000 179.000 l 349.000 177.000 l gs 2 setlinejoin col0 s gr n 304 179 m 317 179 l gs col0 s gr n 309.000 177.000 m 317.000 179.000 l 309.000 181.000 l gs 2 setlinejoin col0 s gr n 314 204 m 301 204 l gs col0 s gr n 309.000 206.000 m 301.000 204.000 l 309.000 202.000 l gs 2 setlinejoin col0 s gr n 264 204 m 277 204 l gs col0 s gr n 269.000 202.000 m 277.000 204.000 l 269.000 206.000 l gs 2 setlinejoin col0 s gr n 296 294 m 279 294 l gs col0 s gr n 287.000 296.000 m 279.000 294.000 l 287.000 292.000 l gs 2 setlinejoin col0 s gr n 244 294 m 257 294 l gs col0 s gr n 249.000 292.000 m 257.000 294.000 l 249.000 296.000 l gs 2 setlinejoin col0 s gr 0.000 setlinewidth n 339 219 m 359 219 l 359 279 l 339 279 l clp gs 0.35 setgray fill gr n 339 219 m 359 219 l 359 199 l 339 199 l clp gs 0.50 setgray fill gr n 319 259 m 339 259 l 339 239 l 319 239 l clp gs 0.75 setgray fill gr n 279 259 m 299 259 l 299 239 l 279 239 l clp gs 0.75 setgray fill gr n 239 259 m 259 259 l 259 239 l 239 239 l clp gs 0.75 setgray fill gr n 239 239 m 339 239 l 339 219 l 239 219 l clp gs 0.75 setgray fill gr n 359 279 m 389 279 l 389 219 l 359 219 l clp gs 0.75 setgray fill gr n 239 279 m 339 279 l 339 259 l 239 259 l clp gs 0.75 setgray fill gr n 339 279 m 359 279 l 359 319 l 339 319 l clp gs 0.50 setgray fill gr n 299 259 m 319 259 l 319 239 l 299 239 l clp gs 0.00 setgray fill gr n 259 259 m 279 259 l 279 239 l 259 239 l clp gs 0.00 setgray fill gr /Times-Roman findfont 16.00 scalefont setfont 273 198 m gs 1 -1 scale (6.3.a) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 411 236 m gs 1 -1 scale (6.2.a) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 312 170 m gs 1 -1 scale (6.4.a) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 251 316 m gs 1 -1 scale (6.1.a) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 247 235 m gs 1 -1 scale (CCA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 305 275 m gs 1 -1 scale (CAA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 339 338 m gs 1 -1 scale (CPG) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 364 274 m gs 1 -1 scale (CAA) col0 show gr $F2psEnd %%EndDocument 590 1120 a endTexFig 951 2828 a Fl(12)p eop %%Page: 13 13 bop 0 202 a Fo(Alternativ)n(e)343 180 y Fg(3)387 202 y Fo(Con)n(tact)22 b(to)h(P)n(oly)g(\(CCP\))30 331 y Fn(5.1.b)52 b(Exact)19 b(con)n(tact)h(size) 1017 b(2)19 b Fc(\002)i Fn(2)30 405 y(5.2.b)52 b(Minim)n(um)18 b(p)r(oly)g(o)n(v)n(erlap)902 b(1)30 480 y(5.3.b)52 b(Minim)n(um)18 b(con)n(tact)h(spacing)818 b(2)30 555 y(5.4.b)52 b(Minim)n(um)18 b(spacing)g(to)i(other)h(p)r(oly)666 b(4)30 630 y(5.5.b)52 b(Minim)n(um)18 b(spacing)g(to)i(activ)n(e)f(\(one)h(con)n(tact\))417 b(2)30 704 y(5.6.b)52 b(Minim)n(um)18 b(spacing)g(to)i(activ)n(e)f(\(man)n(y) g(con)n(tacts\))340 b(3)202 1019 y 24405032 15327150 0 0 24405032 15327150 startTexFig 202 1019 a %%BeginDocument: ciffig/contact2.ps /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /l {lineto} bind def /m {moveto} bind def /s {stroke} bind def /n {newpath} bind def /gs {gsave} bind def /gr {grestore} bind def /clp {closepath} bind def /graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul setrgbcolor} bind def /col-1 {} def /col0 {0 0 0 setrgbcolor} bind def /col1 {0 0 1 setrgbcolor} bind def /col2 {0 1 0 setrgbcolor} bind def /col3 {0 1 1 setrgbcolor} bind def /col4 {1 0 0 setrgbcolor} bind def /col5 {1 0 1 setrgbcolor} bind def /col6 {1 1 0 setrgbcolor} bind def /col7 {1 1 1 setrgbcolor} bind def end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 0 setlinecap 0 setlinejoin -151.0 357.0 translate 0.900 -0.900 scale n 459 259 m 479 259 l 479 299 l 459 299 l clp gs 0.35 setgray fill gr 0.500 setlinewidth n 294 374 m 279 374 l gs 0.50 setgray fill gr gs col0 s gr n 287.000 376.000 m 279.000 374.000 l 287.000 372.000 l gs 2 setlinejoin col0 s gr n 244 374 m 259 374 l gs 0.50 setgray fill gr gs col0 s gr n 251.000 372.000 m 259.000 374.000 l 251.000 376.000 l gs 2 setlinejoin col0 s gr n 304 159 m 289 159 l gs 0.50 setgray fill gr gs col0 s gr n 297.000 161.000 m 289.000 159.000 l 297.000 157.000 l gs 2 setlinejoin col0 s gr n 254 159 m 269 159 l gs 0.50 setgray fill gr gs col0 s gr n 261.000 157.000 m 269.000 159.000 l 261.000 161.000 l gs 2 setlinejoin col0 s gr n 539 334 m 539 319 l gs 0.50 setgray fill gr gs col0 s gr n 537.000 327.000 m 539.000 319.000 l 541.000 327.000 l gs 2 setlinejoin col0 s gr n 539 284 m 539 299 l gs 0.50 setgray fill gr gs col0 s gr n 541.000 291.000 m 539.000 299.000 l 537.000 291.000 l gs 2 setlinejoin col0 s gr n 367.000 251.000 m 359.000 249.000 l 367.000 247.000 l gs 2 setlinejoin col0 s gr n 359 249 m 409 249 l gs 0.50 setgray fill gr gs col0 s gr n 401.000 247.000 m 409.000 249.000 l 401.000 251.000 l gs 2 setlinejoin col0 s gr n 209 164 m 209 179 l gs 0.50 setgray fill gr gs col0 s gr n 211.000 171.000 m 209.000 179.000 l 207.000 171.000 l gs 2 setlinejoin col0 s gr n 209 204 m 209 189 l gs 0.50 setgray fill gr gs col0 s gr n 207.000 197.000 m 209.000 189.000 l 211.000 197.000 l gs 2 setlinejoin col0 s gr n 207.000 307.000 m 209.000 299.000 l 211.000 307.000 l gs 2 setlinejoin col0 s gr n 209 299 m 209 329 l gs 0.50 setgray fill gr gs col0 s gr n 211.000 321.000 m 209.000 329.000 l 207.000 321.000 l gs 2 setlinejoin col0 s gr 0.000 setlinewidth [4.000000] 0 setdash n 229 349 m 239 349 l 239 329 l 229 329 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 379 359 m 389 359 l 389 329 l 379 329 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 339 349 m 359 349 l 359 329 l 339 329 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 299 349 m 319 349 l 319 329 l 299 329 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 259 349 m 279 349 l 279 329 l 259 329 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 229 329 m 389 329 l 389 319 l 229 319 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 359 349 m 379 349 l 379 329 l 359 329 l clp gs 0.00 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 229 359 m 379 359 l 379 349 l 229 349 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 229 299 m 369 299 l 369 259 l 229 259 l clp gs 0.75 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 449 339 m 459 339 l 459 319 l 449 319 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 479 339 m 489 339 l 489 319 l 479 319 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 449 349 m 489 349 l 489 339 l 449 339 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 459 309 m 479 309 l 479 299 l 459 299 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 449 309 m 489 309 l 489 319 l 449 319 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 459 319 m 479 319 l 479 339 l 459 339 l clp gs 0.00 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 479 299 m 519 299 l 519 259 l 479 259 l clp gs 0.75 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 419 299 m 459 299 l 459 259 l 419 259 l clp gs 0.75 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 459 219 m 479 219 l 479 259 l 459 259 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 339 189 m 359 189 l 359 159 l 339 159 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 339 219 m 359 219 l 359 209 l 339 209 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 359 219 m 369 219 l 369 179 l 359 179 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 329 219 m 339 219 l 339 179 l 329 179 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 229 209 m 269 209 l 269 189 l 229 189 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 289 209 m 299 209 l 299 189 l 289 189 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 259 189 m 299 189 l 299 179 l 259 179 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 259 219 m 299 219 l 299 209 l 259 209 l clp gs 0.50 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 339 209 m 359 209 l 359 189 l 339 189 l clp gs 0.00 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 269 209 m 289 209 l 289 189 l 269 189 l clp gs 0.00 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 319 349 m 339 349 l 339 329 l 319 329 l clp gs 0.00 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 279 349 m 299 349 l 299 329 l 279 329 l clp gs 0.00 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 239 349 m 259 349 l 259 329 l 239 329 l clp gs 0.00 setgray fill gr [] 0 setdash [4.000000] 0 setdash n 409 239 m 429 239 l 429 149 l 409 149 l clp gs 0.50 setgray fill gr [] 0 setdash /Times-Roman findfont 16.00 scalefont setfont 545 315 m gs 1 -1 scale (5.5.b) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 368 243 m gs 1 -1 scale (5.4.b) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 262 151 m gs 1 -1 scale (5.1.b) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 167 190 m gs 1 -1 scale (5.2.b) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 167 320 m gs 1 -1 scale (5.6.b) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 252 396 m gs 1 -1 scale (5.3.b) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 440 353 m gs 1 -1 scale (CCP) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 337 331 m gs 1 -1 scale (CCP) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 492 292 m gs 1 -1 scale (CAA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 434 178 m gs 1 -1 scale (CPG) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 288 292 m gs 1 -1 scale (CAA) col0 show gr $F2psEnd %%EndDocument 202 1019 a endTexFig 0 2658 780 2 v 56 2688 a Fh(3)75 2704 y Fg(If)13 b(y)o(ou)h(ha)o(v)o(e)f (di\016culties)h(with)f(half)g(lam)o(b)q(da)f(rule.)951 2828 y Fl(13)p eop %%Page: 14 14 bop 0 202 a Fo(Alternativ)n(e)343 180 y Fg(4)387 202 y Fo(Con)n(tact)22 b(to)h(Activ)n(e)e(\(CCA\))30 331 y Fn(6.1.b)52 b(Exact)19 b(con)n(tact)h(size)1017 b(2)19 b Fc(\002)i Fn(2)30 405 y(6.2.b)52 b(Minim)n(um)18 b(activ)n(e)g(o)n(v)n(erlap)862 b(1)30 480 y(6.3.b)52 b(Minim)n(um)18 b(con)n(tact)h(spacing)818 b(2)30 555 y(6.4.b)52 b(Minim)n(um)18 b(spacing)g(to)i(di\013usion)g(activ)n(e)541 b(5)30 630 y(6.5.b)52 b(Minim)n(um)18 b(spacing)g(to)i(gate)g(of)g (transistor)489 b(2)30 704 y(6.6.b)52 b(Minim)n(um)18 b(sap)r(cing)g(to)i (\014eld)g(p)r(oly)e(\(one)i(con)n(tact\))326 b(2)30 779 y(6.7.b)52 b(Minim)n(um)18 b(spacing)g(to)i(\014eld)g(p)r(oly)f(\(man)n(y)g(con)n (tacts\))250 b(3)30 854 y(6.8.b)52 b(Minim)n(um)18 b(spacing)g(to)i(p)r(oly)f (con)n(tact)613 b(4)310 988 y 20984381 14932459 0 0 20984381 14932459 startTexFig 310 988 a %%BeginDocument: ciffig/acon2.ps /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /l {lineto} bind def /m {moveto} bind def /s {stroke} bind def /n {newpath} bind def /gs {gsave} bind def /gr {grestore} bind def /clp {closepath} bind def /graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul setrgbcolor} bind def /col-1 {} def /col0 {0 0 0 setrgbcolor} bind def /col1 {0 0 1 setrgbcolor} bind def /col2 {0 1 0 setrgbcolor} bind def /col3 {0 1 1 setrgbcolor} bind def /col4 {1 0 0 setrgbcolor} bind def /col5 {1 0 1 setrgbcolor} bind def /col6 {1 1 0 setrgbcolor} bind def /col7 {1 1 1 setrgbcolor} bind def end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 0 setlinecap 0 setlinejoin -171.0 333.0 translate 0.900 -0.900 scale n 299 329 m 389 329 l 389 369 l 299 369 l clp gs 0.75 setgray fill gr 0.500 setlinewidth n 487.000 289.000 m 489.000 281.000 l 491.000 289.000 l gs 2 setlinejoin col0 s gr n 489 281 m 489 317 l gs col0 s gr n 491.000 309.000 m 489.000 317.000 l 487.000 309.000 l gs 2 setlinejoin col0 s gr n 499 274 m 499 261 l gs col0 s gr n 497.000 269.000 m 499.000 261.000 l 501.000 269.000 l gs 2 setlinejoin col0 s gr n 499 214 m 499 227 l gs col0 s gr n 501.000 219.000 m 499.000 227.000 l 497.000 219.000 l gs 2 setlinejoin col0 s gr n 319 304 m 319 291 l gs col0 s gr n 317.000 299.000 m 319.000 291.000 l 321.000 299.000 l gs 2 setlinejoin col0 s gr n 319 264 m 319 277 l gs col0 s gr n 321.000 269.000 m 319.000 277.000 l 317.000 269.000 l gs 2 setlinejoin col0 s gr n 334 139 m 321 139 l gs col0 s gr n 329.000 141.000 m 321.000 139.000 l 329.000 137.000 l gs 2 setlinejoin col0 s gr n 284 139 m 297 139 l gs col0 s gr n 289.000 137.000 m 297.000 139.000 l 289.000 141.000 l gs 2 setlinejoin col0 s gr n 229 184 m 229 197 l gs col0 s gr n 231.000 189.000 m 229.000 197.000 l 227.000 189.000 l gs 2 setlinejoin col0 s gr n 229 234 m 229 221 l gs col0 s gr n 227.000 229.000 m 229.000 221.000 l 231.000 229.000 l gs 2 setlinejoin col0 s gr n 249 224 m 249 237 l gs col0 s gr n 251.000 229.000 m 249.000 237.000 l 247.000 229.000 l gs 2 setlinejoin col0 s gr n 249 274 m 249 261 l gs col0 s gr n 247.000 269.000 m 249.000 261.000 l 251.000 269.000 l gs 2 setlinejoin col0 s gr n 227.000 289.000 m 229.000 281.000 l 231.000 289.000 l gs 2 setlinejoin col0 s gr n 229 281 m 229 327 l gs col0 s gr n 231.000 319.000 m 229.000 327.000 l 227.000 319.000 l gs 2 setlinejoin col0 s gr n 474 194 m 461 194 l gs col0 s gr n 469.000 196.000 m 461.000 194.000 l 469.000 192.000 l gs 2 setlinejoin col0 s gr n 424 194 m 437 194 l gs col0 s gr n 429.000 192.000 m 437.000 194.000 l 429.000 196.000 l gs 2 setlinejoin col0 s gr 0.000 setlinewidth n 269 289 m 309 289 l 309 279 l 269 279 l clp gs 0.75 setgray fill gr n 269 279 m 279 279 l 279 199 l 269 199 l clp gs 0.75 setgray fill gr n 299 279 m 309 279 l 309 199 l 299 199 l clp gs 0.75 setgray fill gr n 279 219 m 299 219 l 299 199 l 279 199 l clp gs 0.75 setgray fill gr n 459 341 m 469 341 l 469 309 l 459 309 l clp gs 0.50 setgray fill gr n 279 259 m 299 259 l 299 239 l 279 239 l clp gs 0.75 setgray fill gr n 269 199 m 309 199 l 309 179 l 269 179 l clp gs 0.35 setgray fill gr n 439 319 m 459 319 l 459 309 l 439 309 l clp gs 0.50 setgray fill gr n 439 349 m 469 349 l 469 339 l 439 339 l clp gs 0.50 setgray fill gr n 429 309 m 439 309 l 439 349 l 429 349 l clp gs 0.50 setgray fill gr n 459 279 m 479 279 l 479 259 l 459 259 l clp gs 0.75 setgray fill gr n 419 279 m 439 279 l 439 259 l 419 259 l clp gs 0.75 setgray fill gr n 379 279 m 399 279 l 399 259 l 379 259 l clp gs 0.75 setgray fill gr n 349 279 m 359 279 l 359 259 l 349 259 l clp gs 0.75 setgray fill gr n 349 339 m 389 339 l 389 289 l 349 289 l clp gs 0.75 setgray fill gr n 349 289 m 479 289 l 479 279 l 349 279 l clp gs 0.75 setgray fill gr n 349 259 m 479 259 l 479 249 l 349 249 l clp gs 0.75 setgray fill gr n 349 289 m 479 289 l 479 279 l 349 279 l clp gs 0.75 setgray fill gr n 339 229 m 479 229 l 479 209 l 339 209 l clp gs 0.50 setgray fill gr n 319 199 m 339 199 l 339 229 l 319 229 l clp gs 0.50 setgray fill gr n 309 199 m 339 199 l 339 179 l 309 179 l clp gs 0.50 setgray fill gr n 249 199 m 269 199 l 269 179 l 249 179 l clp gs 0.50 setgray fill gr n 269 179 m 310 179 l 310 148 l 269 148 l clp gs 0.75 setgray fill gr n 439 339 m 459 339 l 459 320 l 439 320 l clp gs 0.00 setgray fill gr n 439 280 m 459 280 l 459 259 l 439 259 l clp gs 0.00 setgray fill gr n 400 280 m 420 280 l 420 259 l 400 259 l clp gs 0.00 setgray fill gr n 359 280 m 380 280 l 380 259 l 359 259 l clp gs 0.00 setgray fill gr n 279 280 m 299 280 l 299 259 l 279 259 l clp gs 0.00 setgray fill gr n 279 240 m 299 240 l 299 220 l 279 220 l clp gs 0.00 setgray fill gr /Times-Roman findfont 16.00 scalefont setfont 509 248 m gs 1 -1 scale (6.7.b) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 500 304 m gs 1 -1 scale (6.8.b) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 306 320 m gs 1 -1 scale (6.2.b) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 434 188 m gs 1 -1 scale (6.1.b) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 294 131 m gs 1 -1 scale (6.6.b) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 191 216 m gs 1 -1 scale (6.5.b) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 211 258 m gs 1 -1 scale (6.3.b) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 190 308 m gs 1 -1 scale (6.4.b) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 376 257 m gs 1 -1 scale (CCA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 304 359 m gs 1 -1 scale (CAA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 348 203 m gs 1 -1 scale (CPG) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 276 170 m gs 1 -1 scale (CAA) col0 show gr $F2psEnd %%EndDocument 310 988 a endTexFig 0 2658 780 2 v 56 2688 a Fh(4)75 2704 y Fg(If)13 b(y)o(ou)h(ha)o(v)o(e)f (di\016culties)h(with)f(half)g(lam)o(b)q(da)f(rule.)951 2828 y Fl(14)p eop %%Page: 15 15 bop 0 198 a Fo(Metal1)22 b(\(CMF\))30 327 y Fn(7.1)102 b(Minim)n(um)18 b(width)1073 b(3)30 402 y(7.2.a)55 b(Minim)n(um)18 b(spacing)1028 b(3)30 477 y(7.2.b)157 455 y Fg(5)209 477 y Fn(Minim)n(um)18 b(tigh)n(t)i(metal)e(spacing)718 b(2)30 551 y(7.3)102 b(Minim)n(um)18 b(o)n(v)n(erlap)h(of)h(p)r(oly)f(con)n(tact)623 b(1)30 626 y(7.4)102 b(Minim)n(um)18 b(o)n(v)n(erlap)h(of)h(activ)n(e)f(con)n(tact)583 b(1)498 1180 y 15064023 10196172 0 0 15064023 10196172 startTexFig 498 1180 a %%BeginDocument: ciffig/metal1.ps /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /l {lineto} bind def /m {moveto} bind def /s {stroke} bind def /n {newpath} bind def /gs {gsave} bind def /gr {grestore} bind def /clp {closepath} bind def /graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul setrgbcolor} bind def /col-1 {} def /col0 {0 0 0 setrgbcolor} bind def /col1 {0 0 1 setrgbcolor} bind def /col2 {0 1 0 setrgbcolor} bind def /col3 {0 1 1 setrgbcolor} bind def /col4 {1 0 0 setrgbcolor} bind def /col5 {1 0 1 setrgbcolor} bind def /col6 {1 1 0 setrgbcolor} bind def /col7 {1 1 1 setrgbcolor} bind def end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 0 setlinecap 0 setlinejoin -176.0 294.0 translate 0.900 -0.900 scale 0.500 setlinewidth n 404 174 m 391 174 l gs col0 s gr n 399.000 176.000 m 391.000 174.000 l 399.000 172.000 l gs 2 setlinejoin col0 s gr n 364 174 m 377 174 l gs col0 s gr n 369.000 172.000 m 377.000 174.000 l 369.000 176.000 l gs 2 setlinejoin col0 s gr n 222.000 199.000 m 224.000 191.000 l 226.000 199.000 l gs 2 setlinejoin col0 s gr n 224 191 m 224 217 l gs col0 s gr n 226.000 209.000 m 224.000 217.000 l 222.000 209.000 l gs 2 setlinejoin col0 s gr n 417.000 239.000 m 419.000 231.000 l 421.000 239.000 l gs 2 setlinejoin col0 s gr n 419 231 m 419 257 l gs col0 s gr n 421.000 249.000 m 419.000 257.000 l 417.000 249.000 l gs 2 setlinejoin col0 s gr n 274 304 m 261 304 l gs col0 s gr n 269.000 306.000 m 261.000 304.000 l 269.000 302.000 l gs 2 setlinejoin col0 s gr n 234 304 m 247 304 l gs col0 s gr n 239.000 302.000 m 247.000 304.000 l 239.000 306.000 l gs 2 setlinejoin col0 s gr 0.000 setlinewidth n 259 219 m 289 219 l 289 189 l 259 189 l clp gs 0.60 setgray fill gr n 279 279 m 289 279 l 289 259 l 279 259 l clp gs 0.60 setgray fill gr n 279 279 m 284 279 l 284 259 l 279 259 l clp gs 0.60 setgray fill gr n 249 279 m 259 279 l 259 259 l 249 259 l clp gs 0.60 setgray fill gr n 249 259 m 289 259 l 289 249 l 249 249 l clp gs 0.60 setgray fill gr n 249 289 m 289 289 l 289 279 l 249 279 l clp gs 0.60 setgray fill gr n 349 219 m 359 219 l 359 199 l 349 199 l clp gs 0.40 setgray fill gr n 379 219 m 389 219 l 389 199 l 379 199 l clp gs 0.40 setgray fill gr n 349 199 m 389 199 l 389 189 l 349 189 l clp gs 0.40 setgray fill gr n 349 229 m 389 229 l 389 219 l 349 219 l clp gs 0.40 setgray fill gr n 359 289 m 379 289 l 379 259 l 359 259 l clp gs 0.40 setgray fill gr n 379 289 m 399 289 l 399 259 l 379 259 l clp gs 0.90 setgray fill gr n 289 289 m 359 289 l 359 259 l 289 259 l clp gs 0.90 setgray fill gr n 359 289 m 379 289 l 379 309 l 359 309 l clp gs 0.50 setgray fill gr n 359 229 m 379 229 l 379 259 l 359 259 l clp gs 0.50 setgray fill gr n 289 219 m 349 219 l 349 189 l 289 189 l clp gs 0.90 setgray fill gr n 239 219 m 259 219 l 259 189 l 239 189 l clp gs 0.90 setgray fill gr n 259 189 m 289 189 l 289 159 l 259 159 l clp gs 0.75 setgray fill gr n 259 249 m 289 249 l 289 219 l 259 219 l clp gs 0.75 setgray fill gr 0.500 setlinewidth n 359 219 m 379 219 l 379 199 l 359 199 l clp gs 0.00 setgray fill gr gs col0 s gr n 259 279 m 279 279 l 279 259 l 259 259 l clp gs 0.00 setgray fill gr gs col0 s gr /Times-Roman findfont 12.00 scalefont setfont 383 218 m gs 1 -1 scale (CCP) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 232 277 m gs 1 -1 scale (CCA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 359 325 m gs 1 -1 scale (CPG) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 262 177 m gs 1 -1 scale (CAA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 313 279 m gs 1 -1 scale (CMF) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 303 209 m gs 1 -1 scale (CMF) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 242 326 m gs 1 -1 scale (7.4) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 373 167 m gs 1 -1 scale (7.3) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 427 252 m gs 1 -1 scale (7.2) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 195 211 m gs 1 -1 scale (7.1) col0 show gr $F2psEnd %%EndDocument 498 1180 a endTexFig 0 2658 780 2 v 56 2688 a Fh(5)75 2704 y Fg(Only)13 b(allo)o(w)o(ed)g(b)q(et)o (w)o(een)i(minim)n(um)10 b(width)j(wires,)h(otherwise)h(use)g(regular)f (spacing)g(rule.)951 2828 y Fl(15)p eop %%Page: 16 16 bop 0 198 a Fo(Via1)23 b(\(CV)-8 b(A\))30 327 y Fn(8.1)102 b(Exact)19 b(size)1228 b(2)19 b Fc(\002)i Fn(2)30 402 y(8.2)102 b(Minim)n(um)18 b(via1)g(spacing)901 b(3)30 477 y(8.3)102 b(Minim)n(um)18 b(o)n(v)n(erlap)h(b)n(y)h(metal1)754 b(1)30 551 y(8.4)102 b(Minim)n(um)18 b(spacing)g(to)i(con)n(tact)746 b(2)30 626 y(8.5)102 b(Minim)n(um)18 b(spacing)g(to)i(p)r(oly)f(or)i(activ)n(e)d(edge)441 b(2)227 1120 y 23615652 9801483 8288501 21115944 31904153 30917427 startTexFig 227 1120 a %%BeginDocument: ciffig/via1.ps /$F2psDict 32 dict def $F2psDict begin $F2psDict /mtrx matrix put end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 39.000000 578.000000 translate 0.900000 -0.900000 scale newpath 349 199 moveto 359 199 lineto 359 179 lineto 349 179 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray newpath 379 199 moveto 389 199 lineto 389 179 lineto 379 179 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray newpath 349 179 moveto 389 179 lineto 389 169 lineto 349 169 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray newpath 344 209 moveto 389 209 lineto 389 199 lineto 344 199 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray newpath 259 199 moveto 269 199 lineto 269 179 lineto 259 179 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray newpath 209 199 moveto 239 199 lineto 239 179 lineto 209 179 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray newpath 179 199 moveto 189 199 lineto 189 179 lineto 179 179 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray newpath 179 179 moveto 269 179 lineto 269 169 lineto 179 169 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray newpath 179 209 moveto 269 209 lineto 269 199 lineto 179 199 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray newpath 359 199 moveto 379 199 lineto 379 179 lineto 359 179 lineto closepath 0.20 setgray gsave fill grestore 0.00 setgray newpath 239 199 moveto 259 199 lineto 259 179 lineto 239 179 lineto closepath 0.20 setgray gsave fill grestore 0.00 setgray newpath 189 199 moveto 209 199 lineto 209 179 lineto 189 179 lineto closepath 0.20 setgray gsave fill grestore 0.00 setgray 1.000 setlinewidth newpath 367.000 236.000 moveto 359.000 234.000 lineto 367.000 232.000 lineto stroke newpath 359 234 moveto 379 234 lineto stroke newpath 371.000 232.000 moveto 379.000 234.000 lineto 371.000 236.000 lineto stroke newpath 387.000 146.000 moveto 379.000 144.000 lineto 387.000 142.000 lineto stroke newpath 379 144 moveto 399 144 lineto stroke newpath 391.000 142.000 moveto 399.000 144.000 lineto 391.000 146.000 lineto stroke newpath 217.000 266.000 moveto 209.000 264.000 lineto 217.000 262.000 lineto stroke newpath 209 264 moveto 239 264 lineto stroke newpath 231.000 262.000 moveto 239.000 264.000 lineto 231.000 266.000 lineto stroke 0.000 setlinewidth newpath 269 169 moveto 349 169 lineto 349 209 lineto 269 209 lineto closepath 0.90 setgray gsave fill grestore 0.00 setgray newpath 159 219 moveto 289 219 lineto 289 249 lineto 159 249 lineto closepath 0.75 setgray gsave fill grestore 0.00 setgray newpath 159 139 moveto 289 139 lineto 289 159 lineto 159 159 lineto closepath 0.35 setgray gsave fill grestore 0.00 setgray 1.000 setlinewidth newpath 399 179 moveto 419 179 lineto 419 199 lineto 399 199 lineto closepath gsave fill grestore stroke newpath 122.000 167.000 moveto 124.000 159.000 lineto 126.000 167.000 lineto stroke newpath 124 159 moveto 124 179 lineto stroke newpath 126.000 171.000 moveto 124.000 179.000 lineto 122.000 171.000 lineto stroke newpath 122.000 207.000 moveto 124.000 199.000 lineto 126.000 207.000 lineto stroke newpath 124 199 moveto 124 219 lineto stroke newpath 126.000 211.000 moveto 124.000 219.000 lineto 122.000 211.000 lineto stroke [4.000000] 0 setdash newpath 139 209 moveto 269 209 lineto 269 169 lineto 139 169 lineto closepath stroke [] 0 setdash [4.000000] 0 setdash newpath 349 209 moveto 429 209 lineto 429 169 lineto 349 169 lineto closepath stroke [] 0 setdash newpath 459 224 moveto 459 211 lineto stroke newpath 457.000 219.000 moveto 459.000 211.000 lineto 461.000 219.000 lineto stroke newpath 459 184 moveto 459 197 lineto stroke newpath 461.000 189.000 moveto 459.000 197.000 lineto 457.000 189.000 lineto stroke newpath 339 159 moveto 439 159 lineto 439 219 lineto 339 219 lineto closepath stroke /fn0.15 /Times-Roman findfont 16.666667 scalefont def fn0.15 setfont (8.5) 96 215 moveto 1 -1 scale show 1 -1 scale (8.5) 96 177 moveto 1 -1 scale show 1 -1 scale /fn0.12 /Times-Roman findfont 13.333333 scalefont def fn0.12 setfont (CAA) 439 154 moveto 1 -1 scale show 1 -1 scale (CVA) 325 182 moveto 1 -1 scale show 1 -1 scale (CCA) 402 212 moveto 1 -1 scale show 1 -1 scale (CVA) 213 184 moveto 1 -1 scale show 1 -1 scale (CMS) 293 203 moveto 1 -1 scale show 1 -1 scale (CMF) 144 205 moveto 1 -1 scale show 1 -1 scale (CAA) 212 238 moveto 1 -1 scale show 1 -1 scale (CPG) 214 132 moveto 1 -1 scale show 1 -1 scale fn0.15 setfont (8.4) 378 134 moveto 1 -1 scale show 1 -1 scale (8.3) 473 210 moveto 1 -1 scale show 1 -1 scale (8.2) 214 286 moveto 1 -1 scale show 1 -1 scale (8.1) 359 257 moveto 1 -1 scale show 1 -1 scale showpage $F2psEnd %%EndDocument 227 1120 a endTexFig 951 2828 a Fl(16)p eop %%Page: 17 17 bop 0 198 a Fo(Metal2)22 b(\(CMS\))30 327 y Fn(9.1)102 b(Minim)n(um)18 b(width)1073 b(3)30 402 y(9.2.a)55 b(Minim)n(um)18 b(spacing)1028 b(4)30 477 y(9.2.b)157 455 y Fg(6)209 477 y Fn(Minim)n(um)18 b(tigh)n(t)i(metal)e(spacing)718 b(3)30 551 y(9.3)102 b(Minim)n(um)18 b(o)n(v)n(erlap)h(of)h(via1)838 b(1)515 1226 y 14537768 8880537 0 0 14537768 8880537 startTexFig 515 1226 a %%BeginDocument: ciffig/metal2.ps /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /l {lineto} bind def /m {moveto} bind def /s {stroke} bind def /n {newpath} bind def /gs {gsave} bind def /gr {grestore} bind def /clp {closepath} bind def /graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul setrgbcolor} bind def /col-1 {} def /col0 {0 0 0 setrgbcolor} bind def /col1 {0 0 1 setrgbcolor} bind def /col2 {0 1 0 setrgbcolor} bind def /col3 {0 1 1 setrgbcolor} bind def /col4 {1 0 0 setrgbcolor} bind def /col5 {1 0 1 setrgbcolor} bind def /col6 {1 1 0 setrgbcolor} bind def /col7 {1 1 1 setrgbcolor} bind def end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 0 setlinecap 0 setlinejoin -162.0 324.0 translate 0.900 -0.900 scale n 319 289 m 339 289 l 339 279 l 319 279 l clp gs 0.80 setgray fill gr n 319 319 m 339 319 l 339 309 l 319 309 l clp gs 0.80 setgray fill gr n 339 319 m 349 319 l 349 279 l 339 279 l clp gs 0.80 setgray fill gr n 309 319 m 319 319 l 319 279 l 309 279 l clp gs 0.80 setgray fill gr n 319 309 m 339 309 l 339 289 l 319 289 l clp gs 0.20 setgray fill gr 0.500 setlinewidth n 394 294 m 394 307 l gs col0 s gr n 396.000 299.000 m 394.000 307.000 l 392.000 299.000 l gs 2 setlinejoin col0 s gr n 394 334 m 394 321 l gs col0 s gr n 392.000 329.000 m 394.000 321.000 l 396.000 329.000 l gs 2 setlinejoin col0 s gr n 392.000 219.000 m 394.000 211.000 l 396.000 219.000 l gs 2 setlinejoin col0 s gr n 394 211 m 394 237 l gs col0 s gr n 396.000 229.000 m 394.000 237.000 l 392.000 229.000 l gs 2 setlinejoin col0 s gr n 222.000 249.000 m 224.000 241.000 l 226.000 249.000 l gs 2 setlinejoin col0 s gr n 224 241 m 224 277 l gs col0 s gr n 226.000 269.000 m 224.000 277.000 l 222.000 269.000 l gs 2 setlinejoin col0 s gr [4.000000] 0 setdash n 309 279 m 349 279 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 349 359 m 349 279 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 319 359 m 349 359 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 319 319 m 319 359 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 309 319 m 319 319 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 309 279 m 309 319 l gs col0 s gr [] 0 setdash 0.000 setlinewidth 1 setlinecap [1 3.000000] 3.000000 setdash n 349 309 m 379 309 l 379 279 l 349 279 l clp gs 0.80 setgray fill gr [] 0 setdash 0 setlinecap n 239 279 m 309 279 l 309 309 l 239 309 l clp gs 0.80 setgray fill gr n 239 239 m 379 239 l 379 209 l 239 209 l clp gs 0.80 setgray fill gr /Times-Roman findfont 16.00 scalefont setfont 179 257 m gs 1 -1 scale (9.2.a) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 179 275 m gs 1 -1 scale (9.2.b) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 260 301 m gs 1 -1 scale (CMS) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 334 285 m gs 1 -1 scale (CVA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 259 233 m gs 1 -1 scale (CMS) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 322 354 m gs 1 -1 scale (CMF) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 403 323 m gs 1 -1 scale (9.3) col0 show gr /Times-Roman findfont 16.00 scalefont setfont 403 230 m gs 1 -1 scale (9.1) col0 show gr $F2psEnd %%EndDocument 515 1226 a endTexFig 0 2658 780 2 v 56 2688 a Fh(6)75 2704 y Fg(Only)13 b(allo)o(w)o(ed)g(b)q(et)o (w)o(een)i(minim)n(um)10 b(width)j(wires,)h(otherwise)h(use)g(regular)f (spacing)g(rule.)951 2828 y Fl(17)p eop %%Page: 18 18 bop 0 202 a Fo(Ov)n(erglass)287 180 y Fg(7)333 202 y Fo(\(COG\))1706 318 y Fb(\026)p Fn(m)30 393 y(10.1)72 b(Minim)n(um)18 b(b)r(onding)h(pad)i (width)636 b(100)20 b Fc(\002)g Fn(100)30 468 y(10.2)72 b(Minim)n(um)18 b(prob)r(e)h(pad)i(width)731 b(75)20 b Fc(\002)g Fn(75)30 542 y(10.3)72 b(P)n(ad)20 b(o)n(v)n(erlap)g(of)g(glass)f(op)r(ening)778 b(6)30 617 y(10.4)72 b(Minim)n(um)18 b(pad)i(spacing)f(to)h(unrelated)g (metal2)1328 595 y Fg(8)1714 617 y Fn(30)30 692 y(10.5)72 b(Minim)n(um)18 b(pad)i(spacing)f(to)h(unrelated)g(metal1,)d(p)r(oly)-5 b(,)209 767 y(electro)r(de)18 b(or)j(activ)n(e)1023 b(15)331 1173 y 20326563 14471987 0 0 20326563 14471987 startTexFig 331 1173 a %%BeginDocument: ciffig/glass.ps /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /l {lineto} bind def /m {moveto} bind def /s {stroke} bind def /n {newpath} bind def /gs {gsave} bind def /gr {grestore} bind def /clp {closepath} bind def /graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul setrgbcolor} bind def /col-1 {} def /col0 {0 0 0 setrgbcolor} bind def /col1 {0 0 1 setrgbcolor} bind def /col2 {0 1 0 setrgbcolor} bind def /col3 {0 1 1 setrgbcolor} bind def /col4 {1 0 0 setrgbcolor} bind def /col5 {1 0 1 setrgbcolor} bind def /col6 {1 1 0 setrgbcolor} bind def /col7 {1 1 1 setrgbcolor} bind def end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 0 setlinecap 0 setlinejoin -123.0 306.0 translate 0.900 -0.900 scale 0.500 setlinewidth n 227.000 116.000 m 219.000 114.000 l 227.000 112.000 l gs 2 setlinejoin col0 s gr n 219 114 m 359 114 l gs col0 s gr n 351.000 112.000 m 359.000 114.000 l 351.000 116.000 l gs 2 setlinejoin col0 s gr n 172.000 139.000 m 174.000 131.000 l 176.000 139.000 l gs 2 setlinejoin col0 s gr n 174 131 m 174 157 l gs col0 s gr n 176.000 149.000 m 174.000 157.000 l 172.000 149.000 l gs 2 setlinejoin col0 s gr n 399.000 341.000 m 391.000 339.000 l 399.000 337.000 l gs 2 setlinejoin col0 s gr n 391 339 m 427 339 l gs col0 s gr n 419.000 337.000 m 427.000 339.000 l 419.000 341.000 l gs 2 setlinejoin col0 s gr n 399.000 231.000 m 391.000 229.000 l 399.000 227.000 l gs 2 setlinejoin col0 s gr n 391 229 m 437 229 l gs col0 s gr n 429.000 227.000 m 437.000 229.000 l 429.000 231.000 l gs 2 setlinejoin col0 s gr 0.000 setlinewidth n 220 161 m 360 298 l % Polyline n 219 299 m 359 299 l 359 159 l 219 159 l clp gs 0.40 setgray fill gr n 429 259 m 479 259 l 479 329 l 429 329 l clp gs 0.95 setgray fill gr n 439 129 m 479 129 l 479 219 l 439 219 l clp gs 0.85 setgray fill gr n 359 329 m 389 329 l 389 129 l 359 129 l clp gs 0.85 setgray fill gr n 219 329 m 359 329 l 359 299 l 219 299 l clp gs 0.85 setgray fill gr n 219 159 m 359 159 l 359 129 l 219 129 l clp gs 0.85 setgray fill gr n 189 129 m 219 129 l 219 329 l 189 329 l clp gs 0.85 setgray fill gr 0.500 setlinewidth n 219 159 m 359 159 l 359 299 l 219 299 l clp gs col0 s gr /Times-Roman findfont 12.00 scalefont setfont 352 322 m gs 1 -1 scale (CMS) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 447 323 m gs 1 -1 scale (CMF) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 448 210 m gs 1 -1 scale (CMS) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 228 294 m gs 1 -1 scale (COG) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 394 331 m gs 1 -1 scale (10.5) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 401 221 m gs 1 -1 scale (10.4) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 136 151 m gs 1 -1 scale (10.3) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 291 108 m gs 1 -1 scale (10.2) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 255 108 m gs 1 -1 scale (10.1) col0 show gr $F2psEnd %%EndDocument 331 1173 a endTexFig 0 2608 780 2 v 56 2639 a Fh(7)75 2654 y Fg(Rules)14 b(in)f(this)h(section)h (are)f(in)f(unit)h(of)f Fa(\026)p Fg(m.)56 2688 y Fh(8)75 2704 y Fg(And)h(metal3)e(if)h(triple)h(metal)e(used.)951 2828 y Fl(18)p eop %%Page: 19 19 bop 0 198 a Fo(Electro)r(de)21 b(for)j(Capacitor)e(\(CEL)h(-)g(Analog)g (Option\))30 327 y Fn(11.1)72 b(Minim)n(um)18 b(width)1073 b(3)30 402 y(11.2)72 b(Minim)n(um)18 b(spacing)1028 b(3)30 477 y(11.3)72 b(Minim)n(um)18 b(p)r(oly)g(o)n(v)n(erlap)902 b(2)30 551 y(11.4)72 b(Minim)n(um)18 b(spacing)g(to)i(activ)n(e)f(or)h(w)n (ell)g(edge)452 b(2)30 626 y(11.5)72 b(Minim)n(um)18 b(spacing)g(to)i(p)r (oly)f(con)n(tact)613 b(3)256 1225 y 22694707 11182899 0 0 22694707 11182899 startTexFig 256 1225 a %%BeginDocument: ciffig/el.ps /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /l {lineto} bind def /m {moveto} bind def /s {stroke} bind def /n {newpath} bind def /gs {gsave} bind def /gr {grestore} bind def /clp {closepath} bind def /graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul setrgbcolor} bind def /col-1 {} def /col0 {0 0 0 setrgbcolor} bind def /col1 {0 0 1 setrgbcolor} bind def /col2 {0 1 0 setrgbcolor} bind def /col3 {0 1 1 setrgbcolor} bind def /col4 {1 0 0 setrgbcolor} bind def /col5 {1 0 1 setrgbcolor} bind def /col6 {1 1 0 setrgbcolor} bind def /col7 {1 1 1 setrgbcolor} bind def end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 0 setlinecap 0 setlinejoin -60.0 256.0 translate 0.900 -0.900 scale n 119 249 m 389 249 l 389 129 l 119 129 l clp gs 0.85 setgray fill gr n 249 229 m 329 229 l 329 149 l 249 149 l clp gs 0.70 setgray fill gr n 139 229 m 219 229 l 219 149 l 139 149 l clp gs 0.70 setgray fill gr 0.500 setlinewidth n 104 164 m 104 151 l gs col0 s gr n 102.000 159.000 m 104.000 151.000 l 106.000 159.000 l gs 2 setlinejoin col0 s gr n 364 264 m 351 264 l gs col0 s gr n 359.000 266.000 m 351.000 264.000 l 359.000 262.000 l gs 2 setlinejoin col0 s gr n 314 264 m 327 264 l gs col0 s gr n 319.000 262.000 m 327.000 264.000 l 319.000 266.000 l gs 2 setlinejoin col0 s gr n 104 114 m 104 127 l gs col0 s gr n 106.000 119.000 m 104.000 127.000 l 102.000 119.000 l gs 2 setlinejoin col0 s gr 1 setlinecap [1 3.000000] 3.000000 setdash n 349 249 m 429 249 l 429 129 l 349 129 l clp gs col0 s gr [] 0 setdash 0 setlinecap n 229.000 116.000 m 221.000 114.000 l 229.000 112.000 l gs 2 setlinejoin col0 s gr n 221 114 m 247 114 l gs col0 s gr n 239.000 112.000 m 247.000 114.000 l 239.000 116.000 l gs 2 setlinejoin col0 s gr n 339.000 116.000 m 331.000 114.000 l 339.000 112.000 l gs 2 setlinejoin col0 s gr n 331 114 m 357 114 l gs col0 s gr n 349.000 112.000 m 357.000 114.000 l 349.000 116.000 l gs 2 setlinejoin col0 s gr n 149.000 266.000 m 141.000 264.000 l 149.000 262.000 l gs 2 setlinejoin col0 s gr n 141 264 m 217 264 l gs col0 s gr n 209.000 262.000 m 217.000 264.000 l 209.000 266.000 l gs 2 setlinejoin col0 s gr [4.000000] 0 setdash n 159 209 m 309 209 l 309 169 l 159 169 l clp gs col0 s gr [] 0 setdash 0.000 setlinewidth [4.000000] 0 setdash n 169 199 m 189 199 l 189 179 l 169 179 l clp gs 0.00 setgray fill gr [] 0 setdash 0.500 setlinewidth [4.000000] 0 setdash n 349 169 m 449 169 l 449 209 l 349 209 l clp gs col0 s gr [] 0 setdash n 359 199 m 379 199 l 379 179 l 359 179 l clp gs 0.00 setgray fill gr gs col0 s gr n 279 199 m 299 199 l 299 179 l 279 179 l clp gs 0.00 setgray fill gr gs col0 s gr /Times-Roman findfont 12.00 scalefont setfont 256 162 m gs 1 -1 scale (CEL) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 418 185 m gs 1 -1 scale (CMF) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 396 243 m gs 1 -1 scale (CWN) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 270 246 m gs 1 -1 scale (CPG) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 144 162 m gs 1 -1 scale (CEL) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 328 109 m gs 1 -1 scale (11.5) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 323 284 m gs 1 -1 scale (11.4) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 66 146 m gs 1 -1 scale (11.3) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 219 108 m gs 1 -1 scale (11.2) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 162 284 m gs 1 -1 scale (11.1) col0 show gr $F2psEnd %%EndDocument 256 1225 a endTexFig 951 2828 a Fl(19)p eop %%Page: 20 20 bop 0 198 a Fo(Electro)r(de)21 b(for)j(T)-6 b(ransistor)24 b(\(CEL)e(-)h(Analog)g(Option\))30 327 y Fn(12.1)72 b(Minim)n(um)18 b(width)1073 b(2)30 402 y(12.2)72 b(Minim)n(um)18 b(spacing)1028 b(3)30 477 y(12.3)72 b(Minim)n(um)18 b(electro)r(de)g(gate)h(o)n(v)n(erlap)h (of)g(activ)n(e)409 b(2)30 551 y(12.4)72 b(Minim)n(um)18 b(spacing)g(to)i (activ)n(e)783 b(1)30 626 y(12.5)72 b(Minim)n(um)18 b(spacing)g(or)j(o)n(v)n (erlap)e(of)h(p)r(oly)547 b(2)30 701 y(12.6)72 b(Minim)n(um)18 b(spacing)g(to)i(p)r(oly)f(or)i(activ)n(e)d(con)n(tact)367 b(3)417 1180 y 17629512 14143079 11314462 18945146 28943974 33088225 startTexFig 417 1180 a %%BeginDocument: ciffig/el2.ps /$F2psDict 32 dict def $F2psDict begin $F2psDict /mtrx matrix put end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin -20.000000 678.000000 translate 0.900000 -0.900000 scale 1.000 setlinewidth newpath 472.000 347.000 moveto 474.000 339.000 lineto 476.000 347.000 lineto stroke newpath 474 339 moveto 474 369 lineto stroke newpath 476.000 361.000 moveto 474.000 369.000 lineto 472.000 361.000 lineto stroke newpath 414 414 moveto 399 414 lineto stroke newpath 407.000 416.000 moveto 399.000 414.000 lineto 407.000 412.000 lineto stroke newpath 374 414 moveto 389 414 lineto stroke newpath 381.000 412.000 moveto 389.000 414.000 lineto 381.000 416.000 lineto stroke newpath 344 334 moveto 344 319 lineto stroke newpath 342.000 327.000 moveto 344.000 319.000 lineto 346.000 327.000 lineto stroke newpath 344 284 moveto 344 299 lineto stroke newpath 346.000 291.000 moveto 344.000 299.000 lineto 342.000 291.000 lineto stroke newpath 457.000 266.000 moveto 449.000 264.000 lineto 457.000 262.000 lineto stroke newpath 449 264 moveto 479 264 lineto stroke newpath 471.000 262.000 moveto 479.000 264.000 lineto 471.000 266.000 lineto stroke newpath 414 214 moveto 429 214 lineto stroke newpath 421.000 212.000 moveto 429.000 214.000 lineto 421.000 216.000 lineto stroke newpath 447.000 216.000 moveto 439.000 214.000 lineto 447.000 212.000 lineto stroke newpath 439 214 moveto 454 214 lineto stroke newpath 267.000 246.000 moveto 259.000 244.000 lineto 267.000 242.000 lineto stroke newpath 259 244 moveto 274 244 lineto stroke newpath 224 244 moveto 239 244 lineto stroke newpath 231.000 242.000 moveto 239.000 244.000 lineto 231.000 246.000 lineto stroke newpath 267.000 396.000 moveto 259.000 394.000 lineto 267.000 392.000 lineto stroke newpath 259 394 moveto 289 394 lineto stroke newpath 281.000 392.000 moveto 289.000 394.000 lineto 281.000 396.000 lineto stroke 0.000 setlinewidth [4.000000] 0 setdash newpath 399 279 moveto 429 279 lineto 429 319 lineto 399 319 lineto closepath 0.50 setgray gsave fill grestore 0.00 setgray [] 0 setdash [4.000000] 0 setdash newpath 379 279 moveto 399 279 lineto 399 319 lineto 379 319 lineto closepath 0.70 setgray gsave fill grestore 0.00 setgray [] 0 setdash [4.000000] 0 setdash newpath 499 289 moveto 509 289 lineto 509 309 lineto 499 309 lineto closepath 0.70 setgray gsave fill grestore 0.00 setgray [] 0 setdash [4.000000] 0 setdash newpath 479 279 moveto 509 279 lineto 509 289 lineto 479 289 lineto closepath 0.70 setgray gsave fill grestore 0.00 setgray [] 0 setdash [4.000000] 0 setdash newpath 479 319 moveto 509 319 lineto 509 309 lineto 479 309 lineto closepath 0.70 setgray gsave fill grestore 0.00 setgray [] 0 setdash [4.000000] 0 setdash newpath 429 319 moveto 479 319 lineto 479 279 lineto 429 279 lineto closepath 0.70 setgray gsave fill grestore 0.00 setgray [] 0 setdash [4.000000] 0 setdash newpath 449 369 moveto 459 369 lineto 459 389 lineto 449 389 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray [] 0 setdash [4.000000] 0 setdash newpath 429 389 moveto 459 389 lineto 459 399 lineto 429 399 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray [] 0 setdash [4.000000] 0 setdash newpath 429 359 moveto 459 359 lineto 459 369 lineto 429 369 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray [] 0 setdash [4.000000] 0 setdash newpath 399 319 moveto 429 319 lineto 429 399 lineto 399 399 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray [] 0 setdash [4.000000] 0 setdash newpath 399 269 moveto 429 269 lineto 429 279 lineto 399 279 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray [] 0 setdash [4.000000] 0 setdash newpath 399 239 moveto 409 239 lineto 409 259 lineto 399 259 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray [] 0 setdash [4.000000] 0 setdash newpath 429 239 moveto 439 239 lineto 439 259 lineto 429 259 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray [] 0 setdash [4.000000] 0 setdash newpath 399 229 moveto 439 229 lineto 439 239 lineto 399 239 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray [] 0 setdash [4.000000] 0 setdash newpath 399 259 moveto 439 259 lineto 439 269 lineto 399 269 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray [] 0 setdash [4.000000] 0 setdash newpath 409 239 moveto 429 239 lineto 429 259 lineto 409 259 lineto closepath gsave fill grestore [] 0 setdash [4.000000] 0 setdash newpath 429 369 moveto 449 369 lineto 449 389 lineto 429 389 lineto closepath gsave fill grestore [] 0 setdash [4.000000] 0 setdash newpath 479 289 moveto 499 289 lineto 499 309 lineto 479 309 lineto closepath gsave fill grestore [] 0 setdash 1.000 setlinewidth [4.000000] 0 setdash newpath 359 299 moveto 449 299 lineto stroke [] 0 setdash [4.000000] 0 setdash newpath 449 339 moveto 449 299 lineto stroke [] 0 setdash [4.000000] 0 setdash newpath 389 339 moveto 449 339 lineto stroke [] 0 setdash [4.000000] 0 setdash newpath 359 299 moveto 359 339 lineto stroke [] 0 setdash [4.000000] 0 setdash newpath 289 339 moveto 359 339 lineto stroke [] 0 setdash [4.000000] 0 setdash newpath 389 379 moveto 389 339 lineto stroke [] 0 setdash [4.000000] 0 setdash newpath 289 379 moveto 389 379 lineto stroke [] 0 setdash 0.000 setlinewidth [4.000000] 0 setdash newpath 349 349 moveto 369 349 lineto 369 369 lineto 349 369 lineto closepath gsave fill grestore [] 0 setdash [4.000000] 0 setdash newpath 309 349 moveto 329 349 lineto 329 369 lineto 309 369 lineto closepath gsave fill grestore [] 0 setdash 1.000 setlinewidth [4.000000] 0 setdash newpath 289 339 moveto 289 379 lineto stroke [] 0 setdash [4.000000] 0 setdash newpath 259 259 moveto 239 259 lineto stroke [] 0 setdash [4.000000] 0 setdash newpath 259 379 moveto 259 259 lineto stroke [] 0 setdash [4.000000] 0 setdash newpath 239 379 moveto 259 379 lineto stroke [] 0 setdash [4.000000] 0 setdash newpath 239 259 moveto 239 379 lineto stroke [] 0 setdash /fn0.12 /Times-Roman findfont 13.333333 scalefont def fn0.12 setfont (CEL) 213 375 moveto 1 -1 scale show 1 -1 scale /fn0.15 /Times-Roman findfont 16.666667 scalefont def fn0.15 setfont (12.6) 480 359 moveto 1 -1 scale show 1 -1 scale (12.6) 449 259 moveto 1 -1 scale show 1 -1 scale fn0.12 setfont (CCA) 430 238 moveto 1 -1 scale show 1 -1 scale (CCE) 295 347 moveto 1 -1 scale show 1 -1 scale fn0.15 setfont (12.2) 259 414 moveto 1 -1 scale show 1 -1 scale (12.5) 308 315 moveto 1 -1 scale show 1 -1 scale (12.4) 377 434 moveto 1 -1 scale show 1 -1 scale (12.3) 419 209 moveto 1 -1 scale show 1 -1 scale (12.1) 235 238 moveto 1 -1 scale show 1 -1 scale fn0.12 setfont (CAA) 403 361 moveto 1 -1 scale show 1 -1 scale (CPG) 440 294 moveto 1 -1 scale show 1 -1 scale (CEL) 366 334 moveto 1 -1 scale show 1 -1 scale showpage $F2psEnd %%EndDocument 417 1180 a endTexFig 951 2828 a Fl(20)p eop %%Page: 21 21 bop 0 198 a Fo(Electro)r(de)21 b(Con)n(tact)i(\(CCE)f(-)h(Analog)g(Option\)) 30 327 y Fn(13.1)72 b(Exact)19 b(con)n(tact)h(size)1017 b(2)19 b Fc(\002)i Fn(2)30 402 y(13.2)72 b(Minim)n(um)18 b(con)n(tact)h(spacing)818 b(2)30 477 y(13.3)72 b(Minim)n(um)18 b(electro)r(de)g(o)n(v)n(erlap)h(\(on)i (capacitor\))391 b(3)30 551 y(13.4)72 b(Minim)n(um)18 b(electro)r(de)g(o)n(v) n(erlap)h(\(not)i(on)f(capacitor\))285 b(2)30 626 y(13.5)72 b(Minim)n(um)18 b(spacing)g(to)i(p)r(oly)f(or)i(activ)n(e)576 b(3)563 1015 y 13024788 18418892 0 0 13024788 18418892 startTexFig 563 1015 a %%BeginDocument: ciffig/ec.ps /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /l {lineto} bind def /m {moveto} bind def /s {stroke} bind def /n {newpath} bind def /gs {gsave} bind def /gr {grestore} bind def /clp {closepath} bind def /graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul setrgbcolor} bind def /col-1 {} def /col0 {0 0 0 setrgbcolor} bind def /col1 {0 0 1 setrgbcolor} bind def /col2 {0 1 0 setrgbcolor} bind def /col3 {0 1 1 setrgbcolor} bind def /col4 {1 0 0 setrgbcolor} bind def /col5 {1 0 1 setrgbcolor} bind def /col6 {1 1 0 setrgbcolor} bind def /col7 {1 1 1 setrgbcolor} bind def end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 0 setlinecap 0 setlinejoin -162.0 349.0 translate 0.900 -0.900 scale n 229 129 m 349 129 l 349 249 l 229 249 l clp gs 0.90 setgray fill gr n 309 149 m 324 149 l 324 229 l 309 229 l clp gs 0.75 setgray fill gr n 249 149 m 309 149 l 309 339 l 249 339 l clp gs 0.75 setgray fill gr 0.500 setlinewidth n 297.000 366.000 m 289.000 364.000 l 297.000 362.000 l gs 2 setlinejoin col0 s gr n 289 364 m 319 364 l gs 0.85 setgray fill gr gs col0 s gr n 311.000 362.000 m 319.000 364.000 l 311.000 366.000 l gs 2 setlinejoin col0 s gr n 247.000 366.000 m 239.000 364.000 l 247.000 362.000 l gs 2 setlinejoin col0 s gr n 239 364 m 269 364 l gs 0.85 setgray fill gr gs col0 s gr n 261.000 362.000 m 269.000 364.000 l 261.000 366.000 l gs 2 setlinejoin col0 s gr n 284 94 m 271 94 l gs col0 s gr n 279.000 96.000 m 271.000 94.000 l 279.000 92.000 l gs 2 setlinejoin col0 s gr n 234 94 m 247 94 l gs col0 s gr n 239.000 92.000 m 247.000 94.000 l 239.000 96.000 l gs 2 setlinejoin col0 s gr n 364 314 m 364 301 l gs col0 s gr n 362.000 309.000 m 364.000 301.000 l 366.000 309.000 l gs 2 setlinejoin col0 s gr n 364 264 m 364 277 l gs col0 s gr n 366.000 269.000 m 364.000 277.000 l 362.000 269.000 l gs 2 setlinejoin col0 s gr n 364 214 m 364 201 l gs col0 s gr n 362.000 209.000 m 364.000 201.000 l 366.000 209.000 l gs 2 setlinejoin col0 s gr n 364 164 m 364 177 l gs col0 s gr n 366.000 169.000 m 364.000 177.000 l 362.000 169.000 l gs 2 setlinejoin col0 s gr n 214 194 m 214 181 l gs col0 s gr n 212.000 189.000 m 214.000 181.000 l 216.000 189.000 l gs 2 setlinejoin col0 s gr n 214 134 m 214 147 l gs col0 s gr n 216.000 139.000 m 214.000 147.000 l 212.000 139.000 l gs 2 setlinejoin col0 s gr 0.000 setlinewidth n 319 279 m 339 279 l 339 339 l 319 339 l clp gs 0.50 setgray fill gr n 199 279 m 239 279 l 239 339 l 199 339 l clp gs 0.75 setgray fill gr 0.500 setlinewidth [4.000000] 0 setdash n 259 109 m 309 109 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 309 174 m 309 109 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 309 209 m 309 169 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 299 209 m 309 209 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 299 349 m 299 209 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 259 349 m 299 349 l gs col0 s gr [] 0 setdash [4.000000] 0 setdash n 259 349 m 259 109 l gs col0 s gr [] 0 setdash 0.000 setlinewidth n 269 319 m 289 319 l 289 299 l 269 299 l clp gs 0.00 setgray fill gr n 269 279 m 289 279 l 289 259 l 269 259 l clp gs 0.00 setgray fill gr 0.500 setlinewidth n 279 199 m 299 199 l 299 179 l 279 179 l clp gs 0.00 setgray fill gr gs col0 s gr /Times-Roman findfont 15.00 scalefont setfont 238 387 m gs 1 -1 scale (13.5) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 344 333 m gs 1 -1 scale (CPG) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 207 333 m gs 1 -1 scale (CAA) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 289 386 m gs 1 -1 scale (13.5) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 243 89 m gs 1 -1 scale (13.4) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 179 172 m gs 1 -1 scale (13.3) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 369 295 m gs 1 -1 scale (13.2) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 367 196 m gs 1 -1 scale (13.1) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 272 125 m gs 1 -1 scale (CMF) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 280 171 m gs 1 -1 scale (CEL) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 321 144 m gs 1 -1 scale (CPG) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 269 333 m gs 1 -1 scale (CEL) col0 show gr $F2psEnd %%EndDocument 563 1015 a endTexFig 951 2828 a Fl(21)p eop %%Page: 22 22 bop 0 198 a Fo(Via2)23 b(\(CVS)f(-)h(T)-6 b(riple)21 b(Metal)h(Option\))30 327 y Fn(14.1)72 b(Exact)19 b(size)1228 b(2)19 b Fc(\002)i Fn(2)30 402 y(14.2)72 b(Minim)n(um)18 b(spacing)1028 b(3)30 477 y(14.3)72 b(Minim)n(um)18 b(o)n(v)n(erlap)h(b)n(y)h(metal2)754 b(1)30 551 y(14.4)72 b(Minim)n(um)18 b(spacing)g(to)i(via1)828 b(2)392 1136 y 18418892 10985553 0 0 18418892 10985553 startTexFig 392 1136 a %%BeginDocument: ciffig/via2.ps /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /l {lineto} bind def /m {moveto} bind def /s {stroke} bind def /n {newpath} bind def /gs {gsave} bind def /gr {grestore} bind def /clp {closepath} bind def /graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul setrgbcolor} bind def /col-1 {} def /col0 {0 0 0 setrgbcolor} bind def /col1 {0 0 1 setrgbcolor} bind def /col2 {0 1 0 setrgbcolor} bind def /col3 {0 1 1 setrgbcolor} bind def /col4 {1 0 0 setrgbcolor} bind def /col5 {1 0 1 setrgbcolor} bind def /col6 {1 1 0 setrgbcolor} bind def /col7 {1 1 1 setrgbcolor} bind def end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 0 setlinecap 0 setlinejoin -135.0 225.0 translate 0.900 -0.900 scale 0.500 setlinewidth n 249.000 176.000 m 241.000 174.000 l 249.000 172.000 l gs 2 setlinejoin col0 s gr n 241 174 m 267 174 l gs col0 s gr n 259.000 172.000 m 267.000 174.000 l 259.000 176.000 l gs 2 setlinejoin col0 s gr n 254 84 m 241 84 l gs col0 s gr n 249.000 86.000 m 241.000 84.000 l 249.000 82.000 l gs 2 setlinejoin col0 s gr n 374 84 m 361 84 l gs col0 s gr n 369.000 86.000 m 361.000 84.000 l 369.000 82.000 l gs 2 setlinejoin col0 s gr n 424 134 m 424 121 l gs col0 s gr n 422.000 129.000 m 424.000 121.000 l 426.000 129.000 l gs 2 setlinejoin col0 s gr n 424 94 m 424 107 l gs col0 s gr n 426.000 99.000 m 424.000 107.000 l 422.000 99.000 l gs 2 setlinejoin col0 s gr n 324 84 m 337 84 l gs col0 s gr n 329.000 82.000 m 337.000 84.000 l 329.000 86.000 l gs 2 setlinejoin col0 s gr n 204 84 m 217 84 l gs col0 s gr n 209.000 82.000 m 217.000 84.000 l 209.000 86.000 l gs 2 setlinejoin col0 s gr n 184 104 m 184 117 l gs col0 s gr n 186.000 109.000 m 184.000 117.000 l 182.000 109.000 l gs 2 setlinejoin col0 s gr n 184 154 m 184 141 l gs col0 s gr n 182.000 149.000 m 184.000 141.000 l 186.000 149.000 l gs 2 setlinejoin col0 s gr 0.000 setlinewidth n 209 109 m 349 109 l 349 149 l 209 149 l clp gs 0.90 setgray fill gr 0.500 setlinewidth n 199 99 m 409 99 l 409 159 l 199 159 l clp gs col0 s gr 0.000 setlinewidth n 349 109 m 389 109 l 389 249 l 349 249 l clp gs 0.90 setgray fill gr 0.500 setlinewidth n 359 219 m 379 219 l 379 239 l 359 239 l clp gs 0.00 setgray fill gr gs col0 s gr n 359 169 m 379 169 l 379 189 l 359 189 l clp gs 0.00 setgray fill gr gs col0 s gr n 359 119 m 379 119 l 379 139 l 359 139 l clp gs 0.00 setgray fill gr gs col0 s gr n 319 119 m 339 119 l 339 139 l 319 139 l clp gs 0.30 setgray fill gr gs col0 s gr n 269 119 m 289 119 l 289 139 l 269 139 l clp gs 0.30 setgray fill gr gs col0 s gr n 219 119 m 239 119 l 239 139 l 219 139 l clp gs 0.30 setgray fill gr gs col0 s gr /Times-Roman findfont 12.00 scalefont setfont 384 133 m gs 1 -1 scale (CVA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 268 114 m gs 1 -1 scale (CVS) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 386 184 m gs 1 -1 scale (CVA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 356 210 m gs 1 -1 scale (CMS) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 199 175 m gs 1 -1 scale (CMT) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 430 120 m gs 1 -1 scale (14.3) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 331 78 m gs 1 -1 scale (14.4) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 213 77 m gs 1 -1 scale (14.1) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 150 136 m gs 1 -1 scale (14.1) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 239 195 m gs 1 -1 scale (14.2) col0 show gr $F2psEnd %%EndDocument 392 1136 a endTexFig 951 2828 a Fl(22)p eop %%Page: 23 23 bop 0 198 a Fo(Metal3)22 b(\(CMT)h(-)f(T)-6 b(riple)22 b(Metal)g(Option\))30 327 y Fn(15.1)72 b(Minim)n(um)18 b(width)1073 b(6)30 402 y(15.2)72 b(Minim)n(um)18 b(spacing)g(to)i(metal3)759 b(4)30 477 y(15.3)72 b(Minim)n(um)18 b(o)n(v)n(erlap)h(of)h(via2)838 b(2)475 1136 y 15787622 10327736 0 0 15787622 10327736 startTexFig 475 1136 a %%BeginDocument: ciffig/metal3.ps /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /l {lineto} bind def /m {moveto} bind def /s {stroke} bind def /n {newpath} bind def /gs {gsave} bind def /gr {grestore} bind def /clp {closepath} bind def /graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul setrgbcolor} bind def /col-1 {} def /col0 {0 0 0 setrgbcolor} bind def /col1 {0 0 1 setrgbcolor} bind def /col2 {0 1 0 setrgbcolor} bind def /col3 {0 1 1 setrgbcolor} bind def /col4 {1 0 0 setrgbcolor} bind def /col5 {1 0 1 setrgbcolor} bind def /col6 {1 1 0 setrgbcolor} bind def /col7 {1 1 1 setrgbcolor} bind def end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 0 setlinecap 0 setlinejoin -133.0 319.0 translate 0.900 -0.900 scale 0.500 setlinewidth n 182.000 249.000 m 184.000 241.000 l 186.000 249.000 l gs 2 setlinejoin col0 s gr n 184 241 m 184 277 l gs col0 s gr n 186.000 269.000 m 184.000 277.000 l 182.000 269.000 l gs 2 setlinejoin col0 s gr n 374 354 m 374 341 l gs col0 s gr n 372.000 349.000 m 374.000 341.000 l 376.000 349.000 l gs 2 setlinejoin col0 s gr n 374 304 m 374 317 l gs col0 s gr n 376.000 309.000 m 374.000 317.000 l 372.000 309.000 l gs 2 setlinejoin col0 s gr n 372.000 189.000 m 374.000 181.000 l 376.000 189.000 l gs 2 setlinejoin col0 s gr n 374 181 m 374 237 l gs col0 s gr n 376.000 229.000 m 374.000 237.000 l 372.000 229.000 l gs 2 setlinejoin col0 s gr 0.000 setlinewidth n 299 319 m 319 319 l 319 299 l 299 299 l clp gs 0.20 setgray fill gr 0.500 setlinewidth n 199 239 m 359 239 l 359 179 l 199 179 l clp gs col0 s gr n 199 339 m 359 339 l 359 279 l 199 279 l clp gs col0 s gr /Times-Roman findfont 15.00 scalefont setfont 382 216 m gs 1 -1 scale (15.1) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 383 337 m gs 1 -1 scale (15.3) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 147 266 m gs 1 -1 scale (15.2) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 206 234 m gs 1 -1 scale (CMT) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 324 318 m gs 1 -1 scale (CVS) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 206 333 m gs 1 -1 scale (CMT) col0 show gr $F2psEnd %%EndDocument 475 1136 a endTexFig 951 2828 a Fl(23)p eop %%Page: 24 24 bop 0 198 a Fo(NPN)23 b(Bip)r(olar)f(T)-6 b(ransistor)23 b(\(CBA)g(-)f (Analog)i(Option\))30 327 y Fn(16.1)72 b(All)19 b(activ)n(e)g(con)n(tact)1033 b(2)19 b Fc(\002)i Fn(2)30 402 y(16.2)72 b(Minim)n(um)18 b(select)g(o)n(v)n (erlap)h(of)h(emitter)f(con)n(tact)383 b(3)30 477 y(16.3)72 b(Minim)n(um)18 b(pbase)h(o)n(v)n(erlap)h(of)g(emitter)e(select)426 b(2)30 551 y(16.4)72 b(Minim)n(um)18 b(spacing)g(b)r(et)n(w)n(een)i(emitter)f (select)f(and)i(base)f(select)12 b(4)30 626 y(16.5)72 b(Minim)n(um)18 b(pbase)h(o)n(v)n(erlap)h(of)g(base)f(select)502 b(2)30 701 y(16.6)72 b(Minim)n(um)18 b(select)g(o)n(v)n(erlap)h(of)h(base)g(con)n(tact) 459 b(2)30 775 y(16.7)72 b(Minim)n(um)18 b(n)n(w)n(ell)h(o)n(v)n(erlap)h(of)g (pbase)647 b(6)30 850 y(16.8)72 b(Minim)n(um)18 b(spacing)g(b)r(et)n(w)n(een) i(pbase)g(and)g(collector)e(activ)n(e)103 b(4)30 925 y(16.9)72 b(Minim)n(um)18 b(activ)n(e)g(o)n(v)n(erlap)i(of)g(collector)e(con)n(tact)344 b(2)30 1000 y(16.10)42 b(Minim)n(um)18 b(n)n(w)n(ell)h(o)n(v)n(erlap)h(of)g (collector)e(activ)n(e)401 b(3)30 1074 y(16.11)42 b(Minim)n(um)18 b(select)g(o)n(v)n(erlap)h(of)h(collector)f(activ)n(e)390 b(2)177 1284 y 25194414 18484675 7499120 16774348 32693534 35259023 startTexFig 177 1284 a %%BeginDocument: ciffig/npn3.ps /$F2psDict 32 dict def $F2psDict begin $F2psDict /mtrx matrix put end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin -25.000000 602.000000 translate 0.900000 -0.900000 scale 1.000 setlinewidth newpath 164 364 moveto 179 364 lineto stroke newpath 171.000 362.000 moveto 179.000 364.000 lineto 171.000 366.000 lineto stroke newpath 207.000 366.000 moveto 199.000 364.000 lineto 207.000 362.000 lineto stroke newpath 199 364 moveto 214 364 lineto stroke newpath 267.000 156.000 moveto 259.000 154.000 lineto 267.000 152.000 lineto stroke newpath 259 154 moveto 274 154 lineto stroke newpath 484 154 moveto 499 154 lineto stroke newpath 491.000 152.000 moveto 499.000 154.000 lineto 491.000 156.000 lineto stroke newpath 527.000 156.000 moveto 519.000 154.000 lineto 527.000 152.000 lineto stroke newpath 519 154 moveto 534 154 lineto stroke newpath 527.000 366.000 moveto 519.000 364.000 lineto 527.000 362.000 lineto stroke newpath 519 364 moveto 579 364 lineto stroke newpath 571.000 362.000 moveto 579.000 364.000 lineto 571.000 366.000 lineto stroke [4.000000] 0 setdash newpath 169 109 moveto 579 109 lineto stroke [] 0 setdash [4.000000] 0 setdash newpath 169 349 moveto 579 349 lineto stroke [] 0 setdash 2.000 setlinewidth newpath 299 169 moveto 299 289 lineto stroke newpath 519 169 moveto 299 169 lineto stroke newpath 519 289 moveto 519 169 lineto stroke newpath 299 289 moveto 519 289 lineto stroke 0.000 setlinewidth [1 3.000000] 0 setdash newpath 179 279 moveto 279 279 lineto 279 179 lineto 179 179 lineto closepath 0.75 setgray gsave fill grestore 0.00 setgray [] 0 setdash newpath 479 259 moveto 499 259 lineto 499 199 lineto 479 199 lineto closepath 0.75 setgray gsave fill grestore 0.00 setgray newpath 459 219 moveto 479 219 lineto 479 199 lineto 459 199 lineto closepath 0.75 setgray gsave fill grestore 0.00 setgray newpath 459 259 moveto 479 259 lineto 479 239 lineto 459 239 lineto closepath 0.75 setgray gsave fill grestore 0.00 setgray newpath 439 259 moveto 459 259 lineto 459 199 lineto 439 199 lineto closepath 0.75 setgray gsave fill grestore 0.00 setgray newpath 319 269 moveto 349 269 lineto 349 189 lineto 319 189 lineto closepath 0.75 setgray gsave fill grestore 0.00 setgray newpath 369 269 moveto 399 269 lineto 399 189 lineto 369 189 lineto closepath 0.75 setgray gsave fill grestore 0.00 setgray newpath 349 219 moveto 369 219 lineto 369 189 lineto 349 189 lineto closepath 0.75 setgray gsave fill grestore 0.00 setgray newpath 349 269 moveto 369 269 lineto 369 239 lineto 349 239 lineto closepath 0.75 setgray gsave fill grestore 0.00 setgray 1.000 setlinewidth newpath 459 239 moveto 479 239 lineto 479 219 lineto 459 219 lineto closepath gsave fill grestore stroke newpath 349 239 moveto 369 239 lineto 369 219 lineto 349 219 lineto closepath gsave fill grestore stroke newpath 219 239 moveto 239 239 lineto 239 219 lineto 219 219 lineto closepath gsave fill grestore stroke newpath 199 259 moveto 199 199 lineto stroke newpath 259 259 moveto 199 259 lineto stroke newpath 259 199 moveto 259 259 lineto stroke newpath 199 199 moveto 259 199 lineto stroke [4.000000] 0 setdash newpath 169 109 moveto 169 349 lineto stroke [] 0 setdash [4.000000] 0 setdash newpath 579 349 moveto 579 109 lineto stroke [] 0 setdash newpath 334 94 moveto 321 94 lineto stroke newpath 329.000 96.000 moveto 321.000 94.000 lineto 329.000 92.000 lineto stroke newpath 284 94 moveto 297 94 lineto stroke newpath 289.000 92.000 moveto 297.000 94.000 lineto 289.000 96.000 lineto stroke newpath 214 94 moveto 201 94 lineto stroke newpath 209.000 96.000 moveto 201.000 94.000 lineto 209.000 92.000 lineto stroke newpath 154 94 moveto 167 94 lineto stroke newpath 159.000 92.000 moveto 167.000 94.000 lineto 159.000 96.000 lineto stroke newpath 334 309 moveto 347 309 lineto stroke newpath 339.000 307.000 moveto 347.000 309.000 lineto 339.000 311.000 lineto stroke newpath 424 309 moveto 437 309 lineto stroke newpath 429.000 307.000 moveto 437.000 309.000 lineto 429.000 311.000 lineto stroke newpath 476 309 moveto 459 309 lineto stroke newpath 467.000 311.000 moveto 459.000 309.000 lineto 467.000 307.000 lineto stroke newpath 386 309 moveto 369 309 lineto stroke newpath 377.000 311.000 moveto 369.000 309.000 lineto 377.000 307.000 lineto stroke newpath 224 154 moveto 237 154 lineto stroke newpath 229.000 152.000 moveto 237.000 154.000 lineto 229.000 156.000 lineto stroke newpath 409.000 156.000 moveto 401.000 154.000 lineto 409.000 152.000 lineto stroke newpath 401 154 moveto 437 154 lineto stroke newpath 429.000 152.000 moveto 437.000 154.000 lineto 429.000 156.000 lineto stroke newpath 329.000 156.000 moveto 321.000 154.000 lineto 329.000 152.000 lineto stroke newpath 321 154 moveto 347 154 lineto stroke newpath 339.000 152.000 moveto 347.000 154.000 lineto 339.000 156.000 lineto stroke newpath 269.000 311.000 moveto 261.000 309.000 lineto 269.000 307.000 lineto stroke newpath 261 309 moveto 297 309 lineto stroke newpath 289.000 307.000 moveto 297.000 309.000 lineto 289.000 311.000 lineto stroke /fn0.12 /Times-Roman findfont 13.333333 scalefont def fn0.12 setfont (CCA) 203 214 moveto 1 -1 scale show 1 -1 scale (CCA) 445 216 moveto 1 -1 scale show 1 -1 scale (CCA) 334 214 moveto 1 -1 scale show 1 -1 scale (CWN) 541 341 moveto 1 -1 scale show 1 -1 scale (CSN) 249 275 moveto 1 -1 scale show 1 -1 scale (CSN) 368 256 moveto 1 -1 scale show 1 -1 scale (CSP) 471 255 moveto 1 -1 scale show 1 -1 scale (CAA) 228 255 moveto 1 -1 scale show 1 -1 scale (CBA) 486 282 moveto 1 -1 scale show 1 -1 scale /fn0.15 /Times-Roman findfont 16.666667 scalefont def fn0.15 setfont (16.11) 170 385 moveto 1 -1 scale show 1 -1 scale (16.10) 164 88 moveto 1 -1 scale show 1 -1 scale (16.9) 234 149 moveto 1 -1 scale show 1 -1 scale (16.8) 264 329 moveto 1 -1 scale show 1 -1 scale (16.7) 535 386 moveto 1 -1 scale show 1 -1 scale (16.6) 433 331 moveto 1 -1 scale show 1 -1 scale (16.5) 494 148 moveto 1 -1 scale show 1 -1 scale (16.4) 402 148 moveto 1 -1 scale show 1 -1 scale (16.3) 294 87 moveto 1 -1 scale show 1 -1 scale (16.2) 319 148 moveto 1 -1 scale show 1 -1 scale (16.1) 344 330 moveto 1 -1 scale show 1 -1 scale showpage $F2psEnd %%EndDocument 177 1284 a endTexFig 951 2828 a Fl(24)p eop %%Page: 25 25 bop 0 198 a Fo(Capacitor)23 b(W)-6 b(ell)21 b(\(CW)n(C)h(-)h(Linear)f (Capacitor)h(Option\))30 327 y Fn(17.1)72 b(Minim)n(um)18 b(width)1073 b(10)30 402 y(17.2)72 b(Minim)n(um)18 b(spacing)1028 b(9)30 477 y(17.3)72 b(Minim)n(um)18 b(spacing)g(to)i(external)f(activ)n(e)552 b(5)30 551 y(17.4)72 b(Minim)n(um)18 b(o)n(v)n(erlap)h(of)h(activ)n(e)793 b(3)187 1060 y 24865505 10590863 0 0 24865505 10590863 startTexFig 187 1060 a %%BeginDocument: ciffig/cwell.ps /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /l {lineto} bind def /m {moveto} bind def /s {stroke} bind def /n {newpath} bind def /gs {gsave} bind def /gr {grestore} bind def /clp {closepath} bind def /graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul setrgbcolor} bind def /col-1 {} def /col0 {0 0 0 setrgbcolor} bind def /col1 {0 0 1 setrgbcolor} bind def /col2 {0 1 0 setrgbcolor} bind def /col3 {0 1 1 setrgbcolor} bind def /col4 {1 0 0 setrgbcolor} bind def /col5 {1 0 1 setrgbcolor} bind def /col6 {1 1 0 setrgbcolor} bind def /col7 {1 1 1 setrgbcolor} bind def end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 0 setlinecap 0 setlinejoin -117.0 296.0 translate 0.900 -0.900 scale 0.500 setlinewidth n 249.000 166.000 m 241.000 164.000 l 249.000 162.000 l gs 2 setlinejoin col0 s gr n 241 164 m 279 164 l gs col0 s gr n 319 164 m 357 164 l gs col0 s gr n 349.000 162.000 m 357.000 164.000 l 349.000 166.000 l gs 2 setlinejoin col0 s gr n 419 294 m 447 294 l gs col0 s gr n 439.000 292.000 m 447.000 294.000 l 439.000 296.000 l gs 2 setlinejoin col0 s gr n 369.000 296.000 m 361.000 294.000 l 369.000 292.000 l gs 2 setlinejoin col0 s gr n 361 294 m 389 294 l gs col0 s gr n 224 294 m 237 294 l gs col0 s gr n 229.000 292.000 m 237.000 294.000 l 229.000 296.000 l gs 2 setlinejoin col0 s gr n 199.000 296.000 m 191.000 294.000 l 199.000 292.000 l gs 2 setlinejoin col0 s gr n 191 294 m 204 294 l gs col0 s gr n 249.000 311.000 m 241.000 309.000 l 249.000 307.000 l gs 2 setlinejoin col0 s gr n 241 309 m 267 309 l gs col0 s gr n 259.000 307.000 m 267.000 309.000 l 259.000 311.000 l gs 2 setlinejoin col0 s gr n 239 164 m 239 164 l gs col0 s gr 0.000 setlinewidth n 269 209 m 319 209 l 319 249 l 269 249 l clp gs 0.75 setgray fill gr n 129 209 m 189 209 l 189 249 l 129 249 l clp gs 0.75 setgray fill gr 0.500 setlinewidth n 449 179 m 549 179 l 549 279 l 449 279 l clp gs col0 s gr n 239 179 m 359 179 l 359 279 l 239 279 l clp gs col0 s gr /Times-Roman findfont 12.00 scalefont setfont 517 263 m gs 1 -1 scale (CWP) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 517 275 m gs 1 -1 scale (CWC) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 158 242 m gs 1 -1 scale (CAA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 517 250 m gs 1 -1 scale (CWN) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 327 274 m gs 1 -1 scale (CWC) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 291 242 m gs 1 -1 scale (CAA) col0 show gr /Times-Roman findfont 14.00 scalefont setfont 242 328 m gs 1 -1 scale (17.4) col0 show gr /Times-Roman findfont 14.00 scalefont setfont 201 288 m gs 1 -1 scale (17.3) col0 show gr /Times-Roman findfont 14.00 scalefont setfont 392 289 m gs 1 -1 scale (17.2) col0 show gr /Times-Roman findfont 14.00 scalefont setfont 286 160 m gs 1 -1 scale (17.1) col0 show gr $F2psEnd %%EndDocument 187 1060 a endTexFig 951 2828 a Fl(25)p eop %%Page: 26 26 bop 0 198 a Fo(Linear)23 b(Capacitor)f(\(Linear)h(Capacitor)g(Option\))30 327 y Fn(18.1)72 b(Minim)n(um)18 b(width)1073 b(3)30 402 y(18.2)72 b(Minim)n(um)18 b(p)r(oly)g(extension)h(of)h(activ)n(e)603 b(1)30 477 y(18.3)72 b(Minim)n(um)18 b(activ)n(e)g(o)n(v)n(erlap)i(of)g(p)r (oly)660 b(3)30 551 y(18.4)72 b(Minim)n(um)18 b(p)r(oly)g(con)n(tact)i(to)g (activ)n(e)652 b(2)30 626 y(18.5)72 b(Minim)n(um)18 b(activ)n(e)g(con)n(tact) i(to)g(p)r(oly)652 b(4)362 910 y 19339837 16116531 0 0 19339837 16116531 startTexFig 362 910 a %%BeginDocument: ciffig/lcap.ps /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /l {lineto} bind def /m {moveto} bind def /s {stroke} bind def /n {newpath} bind def /gs {gsave} bind def /gr {grestore} bind def /clp {closepath} bind def /graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul setrgbcolor} bind def /col-1 {} def /col0 {0 0 0 setrgbcolor} bind def /col1 {0 0 1 setrgbcolor} bind def /col2 {0 1 0 setrgbcolor} bind def /col3 {0 1 1 setrgbcolor} bind def /col4 {1 0 0 setrgbcolor} bind def /col5 {1 0 1 setrgbcolor} bind def /col6 {1 1 0 setrgbcolor} bind def /col7 {1 1 1 setrgbcolor} bind def end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 0 setlinecap 0 setlinejoin -169.0 306.0 translate 0.900 -0.900 scale n 269 129 m 409 129 l 409 289 l 269 289 l clp gs 0.75 setgray fill gr 0.500 setlinewidth n 439 319 m 429 319 l gs 0.75 setgray fill gr gs col0 s gr n 439 99 m 439 319 l gs 0.75 setgray fill gr gs col0 s gr n 429 99 m 439 99 l gs 0.75 setgray fill gr gs col0 s gr n 429 99 m 239 99 l gs 0.90 setgray fill gr gs col0 s gr n 239 319 m 429 319 l gs 0.90 setgray fill gr gs col0 s gr n 239 99 m 239 319 l gs 0.90 setgray fill gr gs col0 s gr n 224 274 m 224 287 l gs col0 s gr n 226.000 279.000 m 224.000 287.000 l 222.000 279.000 l gs 2 setlinejoin col0 s gr n 224 324 m 224 311 l gs col0 s gr n 222.000 319.000 m 224.000 311.000 l 226.000 319.000 l gs 2 setlinejoin col0 s gr n 284 84 m 271 84 l gs col0 s gr n 279.000 86.000 m 271.000 84.000 l 279.000 82.000 l gs 2 setlinejoin col0 s gr n 244 84 m 257 84 l gs col0 s gr n 249.000 82.000 m 257.000 84.000 l 249.000 86.000 l gs 2 setlinejoin col0 s gr 0.000 setlinewidth n 329 159 m 349 159 l 349 139 l 329 139 l clp gs 0.00 setgray fill gr n 289 159 m 309 159 l 309 139 l 289 139 l clp gs 0.00 setgray fill gr 0.500 setlinewidth n 472.000 209.000 m 474.000 201.000 l 476.000 209.000 l gs 2 setlinejoin col0 s gr n 474 201 m 474 287 l gs col0 s gr n 476.000 279.000 m 474.000 287.000 l 472.000 279.000 l gs 2 setlinejoin col0 s gr n 452.000 139.000 m 454.000 131.000 l 456.000 139.000 l gs 2 setlinejoin col0 s gr n 454 131 m 454 201 l gs col0 s gr n 456.000 193.000 m 454.000 201.000 l 452.000 193.000 l gs 2 setlinejoin col0 s gr n 222.000 169.000 m 224.000 161.000 l 226.000 169.000 l gs 2 setlinejoin col0 s gr n 224 161 m 224 197 l gs col0 s gr n 226.000 189.000 m 224.000 197.000 l 222.000 189.000 l gs 2 setlinejoin col0 s gr 1.000 setlinewidth [4.000000] 0 setdash n 259 199 m 379 199 l 379 339 l 259 339 l clp gs col0 s gr [] 0 setdash 0.000 setlinewidth n 349 309 m 369 309 l 369 329 l 349 329 l clp gs 0.00 setgray fill gr n 309 309 m 329 309 l 329 329 l 309 329 l clp gs 0.00 setgray fill gr n 269 309 m 289 309 l 289 329 l 269 329 l clp gs 0.00 setgray fill gr /Times-Roman findfont 12.00 scalefont setfont 277 173 m gs 1 -1 scale (CCA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 363 114 m gs 1 -1 scale (CWC) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 373 148 m gs 1 -1 scale (CAA) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 309 299 m gs 1 -1 scale (CPG) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 483 252 m gs 1 -1 scale (18.1) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 464 174 m gs 1 -1 scale (18.3) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 188 187 m gs 1 -1 scale (18.5) col0 show gr /Times-Roman findfont 15.00 scalefont setfont 187 305 m gs 1 -1 scale (18.4) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 297 253 m gs 1 -1 scale (capacitor) col0 show gr /Times-Roman findfont 12.00 scalefont setfont 304 235 m gs 1 -1 scale (linear) col0 show gr /Times-Roman findfont 14.00 scalefont setfont 253 77 m gs 1 -1 scale (18.2) col0 show gr $F2psEnd %%EndDocument 362 910 a endTexFig 951 2828 a Fl(26)p eop %%Page: 27 27 bop 0 202 a Fo(Buried)22 b(Channel)g(CCD)g(\(CCD)g(-)h(Analog)g(Option)1364 180 y Fg(9)1386 202 y Fo(\))30 318 y Fn(19.1)72 b(Minim)n(um)18 b(CCD)h(c)n(hannel)h(activ)n(e)f(width)531 b(4)30 393 y(19.2)72 b(Minim)n(um)18 b(CCD)h(c)n(hannel)h(activ)n(e)f(spacing)486 b(4)30 468 y(19.3)72 b(Minim)n(um)18 b(CCD)h(implan)n(t)g(o)n(v)n(erlap)h(of) g(c)n(hannel)g(activ)n(e)202 b(2)30 542 y(19.4)72 b(Minim)n(um)18 b(outside)h(con)n(tact)h(to)g(CCD)g(implan)n(t)378 b(3)30 617 y(19.5)72 b(Minim)n(um)18 b(select)g(o)n(v)n(erlap)h(of)h(electro)r(de)f (\(or)h(p)r(oly\))296 b(2)30 692 y(19.6)72 b(Minim)n(um)18 b(p)r(oly/electro)r(de)f(o)n(v)n(erlap)i(within)h(c)n(hannel)g(activ)n(e)60 b(2)30 767 y(19.7)72 b(Minim)n(um)18 b(con)n(tact)h(to)h(c)n(hannel)g (electro)r(de)e(\(or)j(p)r(oly\))233 b(2)-25 1129 y 31575244 19142492 4341596 16445440 35916840 35587932 startTexFig -25 1129 a %%BeginDocument: ciffig/ccd3.ps /$F2psDict 32 dict def $F2psDict begin $F2psDict /mtrx matrix put end /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin -21.000000 639.000000 translate 0.900000 -0.900000 scale 1.000 setlinewidth newpath 517.000 166.000 moveto 509.000 164.000 lineto 517.000 162.000 lineto stroke newpath 509 164 moveto 524 164 lineto stroke newpath 474 164 moveto 489 164 lineto stroke newpath 481.000 162.000 moveto 489.000 164.000 lineto 481.000 166.000 lineto stroke newpath 184 394 moveto 199 394 lineto stroke newpath 191.000 392.000 moveto 199.000 394.000 lineto 191.000 396.000 lineto stroke newpath 227.000 396.000 moveto 219.000 394.000 lineto 227.000 392.000 lineto stroke newpath 219 394 moveto 234 394 lineto stroke newpath 537.000 136.000 moveto 529.000 134.000 lineto 537.000 132.000 lineto stroke newpath 529 134 moveto 544 134 lineto stroke newpath 494 134 moveto 509 134 lineto stroke newpath 501.000 132.000 moveto 509.000 134.000 lineto 501.000 136.000 lineto stroke newpath 592.000 287.000 moveto 594.000 279.000 lineto 596.000 287.000 lineto stroke newpath 594 279 moveto 594 319 lineto stroke newpath 596.000 311.000 moveto 594.000 319.000 lineto 592.000 311.000 lineto stroke newpath 247.000 356.000 moveto 239.000 354.000 lineto 247.000 352.000 lineto stroke newpath 239 354 moveto 254 354 lineto stroke newpath 204 354 moveto 219 354 lineto stroke newpath 211.000 352.000 moveto 219.000 354.000 lineto 211.000 356.000 lineto stroke newpath 244 414 moveto 259 414 lineto stroke newpath 251.000 412.000 moveto 259.000 414.000 lineto 251.000 416.000 lineto stroke newpath 287.000 416.000 moveto 279.000 414.000 lineto 287.000 412.000 lineto stroke newpath 279 414 moveto 294 414 lineto stroke newpath 132.000 247.000 moveto 134.000 239.000 lineto 136.000 247.000 lineto stroke newpath 134 239 moveto 134 279 lineto stroke newpath 136.000 271.000 moveto 134.000 279.000 lineto 132.000 271.000 lineto stroke [1 3.000000] 0 setdash newpath 459 339 moveto 399 339 lineto stroke [] 0 setdash [1 3.000000] 0 setdash newpath 459 109 moveto 459 339 lineto stroke [] 0 setdash [1 3.000000] 0 setdash newpath 399 109 moveto 459 109 lineto stroke [] 0 setdash [1 3.000000] 0 setdash newpath 369 339 moveto 309 339 lineto stroke [] 0 setdash [1 3.000000] 0 setdash newpath 369 109 moveto 369 339 lineto stroke [] 0 setdash [1 3.000000] 0 setdash newpath 309 109 moveto 369 109 lineto stroke [] 0 setdash [1 3.000000] 0 setdash newpath 279 339 moveto 219 339 lineto stroke [] 0 setdash [1 3.000000] 0 setdash newpath 279 109 moveto 279 339 lineto stroke [] 0 setdash [1 3.000000] 0 setdash newpath 219 109 moveto 279 109 lineto stroke [] 0 setdash newpath 439 379 moveto 439 399 lineto 509 399 lineto 509 379 lineto stroke newpath 349 379 moveto 349 399 lineto 419 399 lineto 419 379 lineto stroke 0.000 setlinewidth [4.000000] 0 setdash newpath 489 339 moveto 579 339 lineto 579 179 lineto 489 179 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray [] 0 setdash [4.000000] 0 setdash newpath 149 339 moveto 239 339 lineto 239 179 lineto 149 179 lineto closepath 0.80 setgray gsave fill grestore 0.00 setgray [] 0 setdash newpath 529 309 moveto 549 309 lineto 549 289 lineto 529 289 lineto closepath gsave fill grestore % Polyline newpath 179 309 moveto 199 309 lineto 199 289 lineto 179 289 lineto closepath gsave fill grestore % Polyline newpath 179 229 moveto 199 229 lineto 199 209 lineto 179 209 lineto closepath gsave fill grestore [1 3.000000] 0 setdash newpath 419 149 moveto 439 149 lineto 439 129 lineto 419 129 lineto closepath gsave fill grestore [] 0 setdash [1 3.000000] 0 setdash newpath 329 149 moveto 349 149 lineto 349 129 lineto 329 129 lineto closepath gsave fill grestore [] 0 setdash [1 3.000000] 0 setdash newpath 239 149 moveto 259 149 lineto 259 129 lineto 239 129 lineto closepath gsave fill grestore [] 0 setdash [1 3.000000] 0 setdash newpath 459 389 moveto 479 389 lineto 479 369 lineto 459 369 lineto closepath gsave fill grestore [] 0 setdash [1 3.000000] 0 setdash newpath 369 389 moveto 389 389 lineto 389 369 lineto 369 369 lineto closepath gsave fill grestore [] 0 setdash [1 3.000000] 0 setdash newpath 279 389 moveto 299 389 lineto 299 369 lineto 279 369 lineto closepath gsave fill grestore [] 0 setdash newpath 529 229 moveto 549 229 lineto 549 209 lineto 529 209 lineto closepath gsave fill grestore 1.000 setlinewidth newpath 526.000 361.000 moveto 524.000 369.000 lineto 522.000 361.000 lineto stroke newpath 524 369 moveto 524 339 lineto stroke newpath 522.000 347.000 moveto 524.000 339.000 lineto 526.000 347.000 lineto stroke [1 3.000000] 0 setdash newpath 219 339 moveto 219 109 lineto stroke [] 0 setdash [1 3.000000] 0 setdash newpath 309 339 moveto 309 109 lineto stroke [] 0 setdash [1 3.000000] 0 setdash newpath 399 339 moveto 399 109 lineto stroke [] 0 setdash newpath 259 379 moveto 259 399 lineto 329 399 lineto 329 379 lineto stroke 2.000 setlinewidth [4.000000] 0 setdash newpath 579 179 moveto 579 339 lineto stroke [] 0 setdash [4.000000] 0 setdash newpath 149 179 moveto 579 179 lineto stroke [] 0 setdash [4.000000] 0 setdash newpath 149 339 moveto 579 339 lineto stroke [] 0 setdash [4.000000] 0 setdash newpath 149 179 moveto 149 339 lineto stroke [] 0 setdash 1.000 setlinewidth newpath 509 179 moveto 439 179 lineto stroke newpath 509 379 moveto 509 179 lineto stroke newpath 439 179 moveto 439 379 lineto stroke newpath 349 179 moveto 419 179 lineto stroke newpath 349 379 moveto 349 179 lineto stroke newpath 419 179 moveto 419 379 lineto stroke newpath 329 179 moveto 259 179 lineto stroke newpath 329 379 moveto 329 179 lineto stroke newpath 259 179 moveto 259 379 lineto stroke newpath 559 279 moveto 169 279 lineto stroke newpath 559 319 moveto 559 279 lineto stroke newpath 169 319 moveto 559 319 lineto stroke newpath 169 279 moveto 169 319 lineto stroke newpath 559 199 moveto 169 199 lineto stroke newpath 169 199 moveto 169 239 lineto 559 239 lineto stroke newpath 559 199 moveto 559 239 lineto stroke newpath 134 214 moveto 134 201 lineto stroke newpath 132.000 209.000 moveto 134.000 201.000 lineto 136.000 209.000 lineto stroke newpath 134 164 moveto 134 177 lineto stroke newpath 136.000 169.000 moveto 134.000 177.000 lineto 132.000 169.000 lineto stroke newpath 592.000 209.000 moveto 594.000 201.000 lineto 596.000 209.000 lineto stroke newpath 594 201 moveto 594 237 lineto stroke newpath 596.000 229.000 moveto 594.000 237.000 lineto 592.000 229.000 lineto stroke newpath 202.000 154.000 moveto 204.000 146.000 lineto 206.000 154.000 lineto stroke newpath 204 146 moveto 204 177 lineto stroke newpath 206.000 169.000 moveto 204.000 177.000 lineto 202.000 169.000 lineto stroke /fn0.15 /Times-Roman findfont 16.666667 scalefont def fn0.15 setfont (19.5) 484 159 moveto 1 -1 scale show 1 -1 scale /fn0.16 /Times-Roman findfont 17.777778 scalefont def fn0.16 setfont (19.7) 193 414 moveto 1 -1 scale show 1 -1 scale (19.7) 505 129 moveto 1 -1 scale show 1 -1 scale fn0.15 setfont (19.1) 598 305 moveto 1 -1 scale show 1 -1 scale (19.4) 531 360 moveto 1 -1 scale show 1 -1 scale fn0.16 setfont (19.2) 98 264 moveto 1 -1 scale show 1 -1 scale /fn0.12 /Times-Roman findfont 13.333333 scalefont def fn0.12 setfont (CAA) 277 276 moveto 1 -1 scale show 1 -1 scale (CSN) 549 334 moveto 1 -1 scale show 1 -1 scale (CEL) 431 123 moveto 1 -1 scale show 1 -1 scale (CEL) 343 123 moveto 1 -1 scale show 1 -1 scale (CPG) 392 395 moveto 1 -1 scale show 1 -1 scale (CPG) 302 395 moveto 1 -1 scale show 1 -1 scale (CCD) 548 173 moveto 1 -1 scale show 1 -1 scale (CEL) 253 123 moveto 1 -1 scale show 1 -1 scale (CPG) 483 395 moveto 1 -1 scale show 1 -1 scale (CSN) 153 333 moveto 1 -1 scale show 1 -1 scale (CAA) 387 236 moveto 1 -1 scale show 1 -1 scale fn0.15 setfont (19.6) 254 433 moveto 1 -1 scale show 1 -1 scale (19.5) 212 374 moveto 1 -1 scale show 1 -1 scale (19.4) 165 169 moveto 1 -1 scale show 1 -1 scale (19.3) 96 196 moveto 1 -1 scale show 1 -1 scale (19.1) 598 225 moveto 1 -1 scale show 1 -1 scale showpage $F2psEnd %%EndDocument -25 1129 a endTexFig 0 2658 780 2 v 56 2689 a Fh(9)75 2704 y Fg(Not)14 b(for)f(all)g(pro)q(cesses) 951 2828 y Fl(27)p eop %%Page: 28 28 bop 0 203 a Fj(References)0 313 y Fl([1])24 b(Cadence)12 b(Design)h(Systems,) e(Inc./Calma.)j Fk(GDSII)f(Str)n(e)n(am)h(F)l(ormat)f(Manual)p Fl(,)h(F)l(eb.)d(1987.)17 b(Release)76 373 y(6.0,)f(Do)q(cumen)o(tation)f (No.:)21 b(B97E060.)0 475 y([2])j(J.)g(Marshall,)h(M.)e(Gaitan,)k(M.)c (Zaghloul,)j(D.)e(No)o(v)o(otn)o(y)l(,)g(V.)g(T)o(yree,)g(J.-I.)f(Pi,)j(C.)e (Pi)q(~)-26 b(n\023)i(a,)26 b(and)76 535 y(W.)c(Hansford.)41 b(Realizing)22 b(susp)q(ended)h(structures)f(on)i(c)o(hips)e(fabricated)g(b)o (y)g(CMOS)h(foundry)76 595 y(pro)q(cesses)13 b(through)h(the)f(MOSIS)g (service.)h(T)l(ec)o(hnical)e(Rep)q(ort)h(NISTIR-5402,)h(National)f (Institute)76 655 y(of)j(Standards)i(and)f(T)l(ec)o(hnology)l(,)e(U.S.)g (Departmen)o(t)g(of)i(Commerce,)12 b(Gaithersburg,)17 b(MD,)f(1994.)0 757 y([3])24 b(C.)16 b(Mead)g(and)h(L.)f(Con)o(w)o(a)o(y)l(.)21 b Fk(Intr)n(o)n(duction)c(to)h(VLSI)f(Systems)p Fl(.)22 b(Addison-Wesley)l(,) 15 b(1980.)0 859 y([4])24 b(N.)17 b(H.)f(E.)i(W)l(este)f(and)h(K.)g (Eshraghian.)26 b Fk(Principles)20 b(of)f(CMOS)g(VLSI)g(Design:)25 b(A)19 b(System)h(Per-)76 919 y(sp)n(e)n(ctive)p Fl(.)i(Addison-Wesley)l(,)15 b(2nd.)h(edition,)f(1993.)951 2828 y(28)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/scmos/doc/scmos-hpsub-rules0000644000175000001440000001030010751423606016657 0ustar timusers******************************************************************** ** Notes for the use of special Magic technology file "scmos-sub" ** ** for HP's CMOS26G process with lambda = 0.4 micron. ** ** for HP's CMOS14B process with lambda = 0.3 micron. ** ******************************************************************** To submit a design in this technology, please specify "SCN3M_SUBM" in your technology field when triple metals are used in the design. If your design use only double metals, please use 'SCN_SUBM'. The following set of rules in conventional MOSIS SCMOS technology has been modified in order to better match HP's submicron CMOS processes, specifically, CMOS26G and CMOS14TB. ====================================================================== Description Rule # SCMOS SCMOS SCMOS_SUBM (Tight Metal) (submicron rules) ====================================================================== WELL_W 1.1 10 10 12 (4.8) WELL_S_DIFF 1.2 9 9 18 (7.2) WELL_O_ACT_XTOR 2.3 5 5 6 (2.4) WELL_S_ACT_XTOR 2.3 5 5 6 (2.4) POLY_S 3.2 2 2 3 (1.2) CON_S 5B.3,6B.3 2 2 3 (1.2) M1_W 7.1 3 3 3 (1.2) M1_S 7.2 3 2 3 (1.2) M2_W 9.1 3 3 3 (1.2) M2_S 9.2 4 3 3 (1.2) M3_W 15.1 6 6 5 (2.0) M3_S 15.2 4 4 3 (1.2) ====================================================================== The HP CMOS26G process is a derivative of the HP CMOS26B process with most of the rules intact except a 3.5 micron metal3 pitch (reduced from previous 5.0 micron pitch). Please refer to the on-line process specification file more detal - (ftp://ftp.mosis.edu:pub/mosis/vendors/hp-cmos26b-g/scn08-hp-specs.inf) The HP CMOS14TB process is a low-voltage (3.3Volt) CMOS one-poly, three-metal process with 0.6 micron minimum drawn channel length. Please refer to the on-line process specification file more detal - (ftp://ftp.mosis.edu:pub/mosis/vendors/hp-cmos14b/scn06_hp_specs.inf) A special Magic technology file is prepared for designs targeted for this process - "scmos-sub". The beta version of this technology file can be obtained on our anonymous FTP server ftp.mosis.edu (128.9.0.32) under pub/mosis/magic directory. Two files are there for your retrieval: (1) scmos-sub.tech (2) scmos-sub.tech26 You'll have to install the second file (with C-style comments removed) in the usual Magic library directory to be able to use it. ******************************************************************** ** TIPS for the transformation of traditional SCMOS layout to ** ** SCMOS-SUB layout ** ******************************************************************** Most of the problems happens in the following cases: (1) Poly spacing is now 3 lambda instead of 2 lambda previously. You'll have to stretch the seriously-connected MOSFETs now. (2) contact spacing is now 3 instead of 2 previously. This should be taken care of automatically by the CIF output generator. but it now requires the designer to use special sized contacts (ndc,pdc,nsc,psc,pc) so that the resulting contacts will be on the grid. You should verify this by the use of ":cif see CCA" command. (3) Due to the 3 lambda spacing rule for contacts, previously abutted diffusion/substrate contacts now have to be separated by one lambda. I have the follwoing three files to illustrate the necessary changes as described above: (1) scmos-div4.mag : standard SCMOS divide-by-4 cell. (2) hp26g-div4-v1.mag : HP CMOS26G divide-by-4 cell with DRC violation of diffusion/substrate contact spacing rule. (3) hp26g-div4-v2.mag : correct CMOS26G divide-by-4 cell. they can be obtained at the same FTP site under pub/pi/layout/hp26g directory. magic-8.0.210/scmos/mos.24bit.std.cmap0000644000175000001440000000375010751423606015763 0ustar timusers#--------------------------------------- # Colormap file for X11, 24-bit graphics #--------------------------------------- # R G B idx color-name #--------------------------------------- 200 200 200 0 background_gray 220 95 95 1 poly_red 66 213 66 2 diff_green 202 160 115 3 diff_brown 169 131 101 4 nfet_brown 184 73 83 5 pfet_brown 230 230 0 6 well_yellow 0 0 0 7 contact_black 125 166 250 8 metal_blue 160 48 191 9 pc_purple 190 153 222 16 metal_purple 255 255 255 32 cursor_white 170 170 170 33 pale_gray 145 145 145 34 dark_gray 0 0 0 35 box_black 239 188 198 36 pale_red 239 125 162 37 medium_red 210 0 155 38 dark_red 165 216 175 39 pale_green 124 191 148 40 medium_green 0 181 0 41 dark_green 170 202 242 42 light_blue 0 0 250 43 dark_blue 40 169 166 44 teal_blue 45 94 179 45 deep_purple 167 0 200 46 bright_purple 255 248 179 47 light_yellow 255 255 0 48 bright_yellow 235 198 160 49 yellow_orange 234 132 73 50 medium_orange 198 152 0 51 ochre_brown 139 108 0 52 medium_brown 255 119 202 53 bright_pink 50 228 225 54 port_cyan 120 81 29 55 border_brown 200 230 230 56 caption_blue 180 210 180 57 window_gray 0 0 0 58 246 246 7 59 label_yellow 180 180 180 60 medium_gray 230 180 50 61 pale_orange 235 235 235 62 light_gray 255 255 255 64 white 210 148 148 65 deep_pink 133 206 133 66 pale_green 201 170 157 67 peach_gray 184 165 150 68 gray_brown 192 136 141 69 rosy_brown 215 215 100 70 pale_ochre 130 130 130 71 gray50 163 183 225 72 steel_blue 180 124 196 73 medium_purple 137 210 179 74 pale_teal 200 185 255 75 bright_lavender 169 213 198 76 pale_cyan 210 210 230 77 pale_steel 195 176 211 80 pale_purple 185 185 185 97 gray75 160 160 160 98 gray62 100 100 100 99 gray40 220 163 181 101 pale_pink 220 120 200 102 medium_pink 80 175 80 105 sea_green 175 115 175 110 deep_lavender 215 170 90 115 medium_tan 228 160 201 117 light_lavender 215 190 125 125 light_tan 0 0 0 255 magic-8.0.210/scmos/COPYRIGHT0000644000175000001440000000321010751423606014071 0ustar timusers/* * (C) Copyright 1992,1994 by * * Jen-I Pi pi@isi.edu * The MOSIS Service * USC Information Sciences Institute * 4676 Admiralty Way * Marina del Rey, CA 90292 * (310) 822-1511 x640 fax (310)823-5624 * * All Rights Reserved. * * Permission to use, copy, modify, and distribute this technology * file and its associated documentation for any purpose and without * fee is hereby granted, provided that the above copyright notice * appears in all copies and that both that copyright notice and this * permission notice appear in supporting documentation, and that the * name of the University of Southern California not be used in * advertising or publicity pertaining to distribution of the software * without specific, written prior permission. The University of * Southern California makes no representations about the suitability * of this technology file for any purpose. This technology file is * provided "as is" without express or implied warranty and the * University of Southern California retains the right to change its * content at any time without notice any other party. * * THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS TECHNOLOGY FILE, INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF * SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS TECHNOLOGY FILE. * */ magic-8.0.210/scmos/mos.7bit.mraster_dstyle0000644000175000001440000000576610751423606017245 0ustar timusers# # This file describes the various display styles that are available # in Magic. This new file is relatively technology-independent: it # contains enough different styles to support MOSIS's SCMOS process # without any changes. Each display style describes a particular # way of drawing things on the display. See "Magic Maintainer's # Manual #3: The Display Style and Glyph Files" for details on the # file format. # # Please send bug reports/comments to mosis@mosis.edu :-) # # BitPlane Usage: # # # msb lsb # +-------+-----------+-----------+ # | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | # +-------+-----------+-----------+ # | | | | | \_______/ # not used -+ | | | | | # highlights ---+ | | | +---- poly, diff, fets # opaque/trans. ----+ | +------------ metal1 # +---------------- metal2 # # Bits 0-2 represent the material on the poly-diff plane (poly, # different flavors of diffusion, different flavors of transistor) # with mutually-opaque colors. # # Bits 3-4 are used for the two metal layers. Each layer has a # separate bit plane, so the two metal layers are mutually transparent, # and they are both transparent with respect to the poly-diff layers. # # If bit 5 is set, then bits 0-4 are used for one of 32 opaque colors # which override any other mask information. These colors are used # for various stipples, contact crosses, etc. They also provide a # palette of standard colors (red, green, etc.) for use in making # window borders, menus, etc. The last of these colors to be drawn in # an area is the one that will appear. # # Bit 6 is used for highlights such as the box, the selection, etc. # It overrides any of the other bits and produces a pure white color. # # Bit 7 is not used in this display style file. This is important for # Sun workstations, since they can't really give Magic all 8 bits. # For AEDs and other displays, this is a bit wasteful, but still seems # to work ok. display_styles 7 # # Poly-diff styles: # stipple short long # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 1 7 1 0 solid 0 - polysilicon 2 7 2 0 solid 0 - ndiffusion 3 7 2 0 stipple 13 - ndiff_in_nwell 4 7 3 0 solid 0 - pdiffusion 5 7 3 0 stipple 13 - pdiff_in_pwell 6 7 4 0 solid 0 - ntransistor 7 7 2 0 stipple 7 - ntransistor_stripes 8 7 5 0 solid 0 - ptransistor 9 7 3 0 stipple 5 - ptransistor_stripes 10 63 6 0 stipple 7 - cwell 11 7 5 0 stipple 22 - highvolt_pwell 12 7 7 0 stipple 7 - nwell 13 7 3 0 stipple 5 - pwell 14 63 6 0 stipple 2 - electrode 15 7 3 0 stipple 10 - pbase 16 7 2 0 stipple 17 - emitter 17 7 3 0 stipple 11 - bccd 18 7 4 0 stipple 21 - highvolt_nwell 19 7 7 0 solid 0 - via # # Metal styles: # stipple short long # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 20 8 8 0 solid 0 - metal1 21 16 16 0 solid 0 - metal2 22 32 32 0 stipple 23 - metal3 magic-8.0.210/scmos/scmos.tech.in0000644000175000001440000033071310751423606015207 0ustar timusers/* --------------------------------------------------------------------* * * * scmos.tech -- MOSIS Scalable CMOS (SCMOS) Magic technology file. * * * * MOSIS distribution Version 8.2 * * * * Defines the MOSIS 0.6/0.8/1.0/1.2/2.0 micron Scalable CMOS * * (SCMOS) technology. * * * * (C) Copyright 1992, 1993, 1994, 1995 by * * * * Jen-I Pi pi@isi.edu * * The MOSIS Service * * USC Information Sciences Institute * * 4676 Admiralty Way * * Marina del Rey, CA 90292 * * voice: (310) 822-1511 x640, fax: (310)823-5624 * * * * All Rights Reserved. * * Last Modified Date: 04/26/1995 * * * * Permission to use, copy, modify, and distribute this technology * * file and its associated documentation for any purpose and without * * fee is hereby granted, provided that the above copyright notice * * appears in all copies and that both that copyright notice and this * * permission notice appear in supporting documentation, and that the * * name of the University of Southern California not be used in * * advertising or publicity pertaining to distribution of this * * technology file without specific, written prior permission. * * The University of Southern California makes no representations * * about the suitability of this technology file for any purpose. * * This technology file is provided "as is" without express or implied * * warranty and the University of Southern California retains the * * right to change its content at any time without notice any other * * party. * * * * THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH * * REGARD TO THIS TECHNOLOGY FILE, INCLUDING ALL IMPLIED WARRANTIES OF * * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF * * SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR * * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * * CONNECTION WITH THE USE OR PERFORMANCE OF THIS TECHNOLOGY FILE. * * * * ------------------------------------------------------------------- */ /* --------------------------------------------------------------------* * Some of the characteristics of this technology are: * * * * 1. 3 levels of metal - for HP's CMOS26B (lambda=0.5) and CMOS26G * * (lambda=0.4) and CMOS14TB (lambda=0.35 or 0.3) processes * * 3 levels of metal stack via - for IBM's CMSX2185 (lambda=0.4) * * process * * 2 levels of metal interconnection for all other technologies * * 2. 2 levels of poly - for ORBIT's low-noise analog process * * second poly is used for poly-capacitor or electrode fet (efet) * * 3. Vertical NPN transistor, BCCD device, Floating-gate device for * * ORBIT's low-noise anaolog process * * 4. All contacts are composite (with the necessary enclosure) * * 5. No stacked contacts (all contacts are to 1st-level metal) * * 6. An open layer is added for fabrication of micromachined devices * * as in Janet C. Marshall's paper in IEEE Circuit and Devices, * * Vol. 8, N0. 6, 1992. * * This layer is currently NOT available for standard MOSIS SCMOS * * techonology installation. You need to define OPEN with the C- * * preprocessor for installation. See README file for detail... * * 7 A pstop layer is used also in micromachineing device fabrication * * to stop the EDP etchant as used in Marshall's article. * * 8 A Cap-well (cwell) for HP's CMOS34 (lambda=0.6) process, It is * * used for consctruction of linear capacitors * * Must be drawn explicitly * * 9. Wells (Pwell or Nwell) can be implicit or explicit in the layout * * and both types of diffusion must have well contacts * *10. Painting Nwell over N-type diffusion will result in P-type * * diffusion * *11. Scalable with Default to be 2.0 micron rules for Nwell process * *12. Substrate contacts must be 3 units away from gates * *13. Stacked via supported through special compiled option -DSTACKVIA * * for IBM process. * * * * Revision 8.2.8 (pi) * * fix CCD CIF input style for "bd" layer. * * 12/13/95 pi@isi.edu * * Revision 8.2.7 (pi) * * Add Magic 6.4.4 new extraction plane orders. * * 07/25/95 pi@isi.edu * * Revision 8.2.5 (pi) * * Fix some typos... * * 05/12/95 pi@isi.edu * * Revision 8.2.4 (pi) * * Fix CBA generation for pbase and add extension rules for pbase * * as resistors. * * Gratitude goes to Tetsuya Kajita (kaj@ssac.yamatake.co.jp) * * 04/26/95 pi@isi.edu * * Revision 8.2.3 (pi) * * fix for SUBMICRON DRC rule. * * Thanks goes to Toby Schaffer (jtschaff@eos.ncsu.edu) * * 04/06/95 pi@isi.edu * * Revision 8.2.2 (pi) * * add XP GDS official number to fix CIF input problem for "pad". * * Thanks goes to Brian Kingsbury (bedk@ICSI.Berkeley.EDU). * * 04/03/95 pi@isi.edu * * Revision 8.2.1 (pi) * * Some fixes for CMOS14B CIF output section. * * 03/21/95 pi@isi.edu * * Revision 8.2.0 (pi) * * support for HP CMOS26G and CMOS14TB process. * * 03/15/95 pi@isi.edu * * Revision 8.1.1 (pi) * * add connection of "ndiff" to "psd". Thank goes to Alireza Moini* * (moini@eleceng.adelaide.edu.au). * * 12/21/94 pi@isi.edu * * Revision 8.1.0 (pi) * * major revision of bipolar transistor rules. It now support * * both ORBIT 2.0 and 1.2 micron processes. NOTE: active layer * * for pbase is now generated in CIF file explicitly. * * 10/31/94 pi@isi.edu * * Revision 8.0.7 (pi) * * remove both VTI and IBM support * * 10/10/94 pi@isi.edu * * Revision 8.0.7 (pi) * * compose for high-voltage transistors corrected. Thank goes to * * Bob Durie (bobd@ee.cornell.edu) * * 8/25/94 pi@isi.edu * * Revision 8.0.6 (pi) * * DRC rule 2.2 add allNOhmic to allNOhmic and allPOhmic to * * allPOhmic rule. Thank goes to Shih-Lien Lu. * * (sllu@caleb.ECE.ORST.EDU) * * 6/28/94 pi@isi.edu * * Revision 8.0.5 (pi) * * DRC rule 3.5 reverse back to old style to avoid a mischeck on * * corners. Thank goes to Wen-King Su. * * (wen-king@vlsi.cs.caltech.edu) * * 4/20/94 pi@isi.edu * * Revision 8.0.4 (pi) * * SCPE20(ORB) extraction P-well sheet resistance fixed. Thank * * goes to Nagendra Shivakumar (nshivaku@phyast.nhn.uoknor.edu). * * 3/04/94 pi@isi.edu * * Revision 8.0.3 (pi) * * Wellcap drawing problem fixed. Thank goes to Mario Aranha * * (mario@cad4.lbl.gov). * * 2/03/94 pi@isi.edu * * Revision 8.0.2 (pi) * * CIF read fix for linear capacitor. Thank goes to Issy Kipnis * * (kipnis@cad4.lbl.gov). * * 2/03/94 pi@isi.edu * * Revision 8.0.1 (pi) * * DRC updates for separate diffusion width check. Thank goes to * * John Poulton (jp@cs.unc.edu). * * 10/04/93 pi@isi.edu * * Revision 8.0.0 (pi) * * DRC revision 8 installed and layer support for High-Voltage * * MOSFETs for SCNA16 process. * * 10/04/93 pi@isi.edu * * Revision 7.4.0 (pi) * * Brand new extraction section and other fixes :-) * * 10/01/93 pi@isi.edu * * Revision 7.3.3 (pi) * * pbc surrounding rule fixed. 4.1.c fixed also * * 6/01/93 pi@isi.edu * * Revision 7.3.2 (pi) * * exchnage CCD and CBA calma (GDS) number to the correct setting * * 4/27/93 pi@isi.edu * * Revision 7.3.1 (pi) * * Various DRC rule changes contributed by Barry Boes at AuE * * (boes@corona.AuE.com). * * allNDiff/allPOhmic in connection section update, thanks go to * * Brian Kingsbury from Bekerley (bedk@icsi.berkeley.edu). * * 3/30/93 pi@isi.edu * * Revision 7.3.0 (pi) * * add three new layers intended for ESD preotection devices * * remove the temporary "pad2" layer, now all pads use "pad" * * CIFin and CIFout now in templates, thank goes to Shih-Lien Lu * * at Origon State Univ. sllu@caleb.ECE.ORST.EDU. * * Some design rule changes (relabeling for doc)... * * 3/19/93 pi@isi.edu * * Revision 7.2.2 (pi) * * change all "bloat-min" select generation back to "bloat-or" * * restore all lambda=0.8 style since some people use ORBIT's run * * though MOSIS does NOT provide HP's process anymore * * 3/09/93 pi@isi.edu * * Revision 7.2.1 (pi) * * add missing Cifinput "pbase" layer for lambda=1.0(oldnwell) * * style. Thank goes to Brian Von Herzen at Synaptics, Inc. * * 2/18/93 pi@isi.edu * * Revision 7.2.0 (pi) * * A serious bug in CIF well generation is fixed... * * 1/14/93 pi@isi.edu * * Revision 7.1.4 (pi) * * Remove lambda=1.5 and lambda=0.8 technology which are not * * provided by MOSIS any more. * * 1/12/93 pi@isi.edu * * Revision 7.1.3 (pi) * * Add pstop layer and the corresponding CIFin CIFout stuff * * Reverse the last change about CCA layer under pad for CMOS26B * * 1/08/93 pi@isi.edu * * Revision 7.1.2 (pi) * * Various problem fix... and make the "open" layer as an option * * Reverse the last change about CCA layer under pad for CMOS26B * * 12/29/92 pi@isi.edu * * Revision 7.1.1 (pi) * * A series bug fix for HP's CMOS26B pad layers - remove CCA CIF * * layer. Thank goes to ndu@aue.com * * 12/12/92 pi@isi.edu * * Revision 7.1.0 (pi) * * A new layer "open" for micromachined device fabracation. * * Thanks goes to Janet Marchall from NIST. * * (marshall@sed.eeel.nist.gov) * * 12/15/92 pi@isi.edu * * Revision 7.0.4 (pi) * * C-preprocessing fix. Thanks goes to Jeffrey C. Gealow form * * MIT (jgealow@mtl.mit.edu). * * 10/20/92 pi@isi.edu * * Revision 7.0.3 (pi) * * Colorversatec support. Thanks got to Jeffrey C. Gealow form * * MIT (jgealow@mtl.mit.edu). * * 10/8/92 pi@isi.edu * * Revision 7.0.2 (pi) * * Separate 'spacing allWell...' rule into two rules to avoid * * well adjacency problem... * * 10/2/92 pi@isi.edu * * Revision 7.0.1 (pi) * * CIFoutput for "pad2" layer, CCA contact fix, CIFinput for HP's * * 1.0 um process... * * 9/28/92 pi@isi.edu * * Revision 7.0 (pi) * * Major revision which includes * * HP's cap_well and well-capacitance, NPN & BCCD DRC rules... * * 9/22/92 pi@isi.edu * * Revision 6.2.0 (pi) * * Merging 'scmos26.tech' into scmos.tech * * 9/7/92 pi@isi.edu * * Revision 6.1.4 (pi) * * Select CIF layers generation is revised based on Brian * * Kingsbury's (bedk@icsi.berkeley.edu) notice of inconsistency * * 9/4/92 pi@isi.edu * * Revision 6.1.3 (pi) * * Install MITRE's (Mike Butler) fix for CIFinput "cap" layer and * * poly1/poly2 crossing in DRC section * * 9/3/92 pi@isi.edu * * Revision 6.1.2 (pi) * * Fixed metal2 contact on falt surface bug for poly2 layer * * 8/3/92 pi@lepton.isi.edu * * Revision 6.1.1 (pi) * * fixed CIFoutput CSP layer bug for lambda=0.8(gen) technology * * 4/13/92 pi@lepton.isi.edu * * Revision 6.1.0 (pi) * * add implant plane for Buried CCD devices * * both cifin and cifoutput are changed correspondingly * * Revision 6.0.2 (pi) * * remove bug for nbdc not generate CMF in cifoutput section * * Revision 6.0.1 (sllu) * * added CX for collector layer * * Revised for Magic Version 6. * * Revision 6.0 90/05/11 20:12:34 pi * * include color versatech support * * eliminated active2 plane * * (rule version # 5.01 (S. Lu) = rule 5.0 + mod. for cc spacing * * (rule version # 5.0 (Shih-Lien Lu sllu@MOSIS.EDU) 8/15/89) * * (rule 5.0 = rule 4.01 + new layers for analog process * * (rule 4.01 = rule 4.0 + comments + cifout style lambda=0.8(pwell) * * (correction made by L. McMurchie of UW) * * (rule 4.0 = rule 3.1 + new layer : electrode) * * (rule 3.1 = rule 3.0 + new cifout method for select layers ) * * (design can be more compact now with this version ) * * (layout should be upward compatible:: you old layout will not) * * (flag any drc violations) * * (rule 3.0 = rule 2.0 + rev #6 + new cifin section for new nwell) * * * * (rule version # 2.0 10/28/87) * * (rule 2.0 = rule 1.9 + modification to extract section * * (rule 1.9 = rule 1.82 + additions of two more CIF in/output styles * * (rule 1.82 = rule 1.81+ modification of drc #4.1 & cifoutput of * * wells * * (rule 1.81 = rule 1.8 + modification on line 1761 * * (rule 1.8 = rule 1.7 + Rev 5 of the SCMOS rules) * * (difference from rule 1.7: * * (1) well width = 9 lambda * * (2) N well process accepts both N and P selects * * ------------------------------------------------------------------- */ /* Definition for actives */ /* NOTE: Some version of cpp may have problem with two consective tabs * or even two consective space... So we put only single space * here... */ #define allNDiff ndiff,ndc/a #define allPDiff pdiff,pdc/a #define allNActive ndiff,ndc/a,nfet,enfet,nffet,wcap #define allPActive pdiff,pdc/a,pfet,epfet,pffet #define allNOhmic nsd,nsc/a #define allPOhmic psd,psc/a #define allOhmic allNOhmic,allPOhmic #define allBiNDiff emit,emc/a,col,clc/a #define allBiPDiff pbase,pbc/a #define allBiDiff allBiNDiff,allBiPDiff #define allCCDiff bd,nbd,nbdc/a #define allDiff allNDiff,allPDiff #define allActive allNActive,allPActive,allOhmic #define PNplus ndiff,pdiff,ndc/a,pdc/a #define allHVNDiff hndiff,hndc/a #define allHVPDiff hpdiff,hpdc/a #define allHVNOhmic hnsd,hnsc/a #define allHVPOhmic hpsd,hpsc/a #define allHVDiff allHVNDiff,allHVPDiff #define allHVOhmic allHVNOhmic,allHVPOhmic /* first poly without those overlapped with the second */ #define allP poly,pc/a #define allP1 poly,pc/a,nfet,pfet,wcap /* all first poly */ #define allPoly allP1,cap,capc/a,nffet,pffet /* second poly without those overlapped with the first */ #define allP2 poly2,ec/a,enfet,epfet /* all second poly */ #define allPoly2 allP2,cap,capc/a,nffet,pffet,hnfet,hpfet /* MOSFETs */ #define NFet nfet,enfet,nffet #define PFet pfet,epfet,pffet #define allFet NFet,PFet /* Definitions for contacts */ #define DiffCut pdc,ndc,psc,nsc #define HVDiffCut hpdc,hndc,hpsc,hnsc #define PolyCut pc #define CapCut ec,capc #define BiCut clc,emc,pbc #define allCut DiffCut,HVDiffCut,PolyCut,CapCut,nbdc /* Definitions for metals */ #define DiffMetal pdc/m1,ndc/m1,psc/m1,nsc/m1 #define HVDiffMetal hpdc/m1,hndc/m1,hpsc/m1,hnsc/m1 #define PolyMetal pc/m1,ec/m1,capc/m1 #define BiMetal clc/m1,emc/m1,pbc/m1 #define CCDMetal nbdc/m1 #define allMetal1 DiffMetal,HVDiffMetal,PolyMetal,BiMetal,CCDMetal,m1,m2c/m1,gc #define allMetal2 m2,m2c/m2,m3c/m2,pad #define allMetal3 m3,m3c/m3 /* All types containing metal, on their respective home planes */ #define homeMetal1 allCut,m1,m2c,gc /* Definitions for wells */ #define allWell nwell,pwell #define allNwell nwell,nsc,nsd #define allPwell pwell,psc,psd #define allHVNwell hnwell,hnsc,hnsd #define allHVPwell hpwell,hpsc,hpsd tech format 28 scmos end #if V4 || V5 version version 8.2.8 #ifdef SUBMICRON description "MOSIS Scalable CMOS Technology for HP CMOS26G and CMOS14B processes" #else /* TIGHTMETAL */ #ifdef IBMTECH description "MOSIS Scalable CMOS Technology for IBM" #else /* IBMTECH */ #ifdef HPTECH description "MOSIS Scalable CMOS Technology for Tight Metal Rules" #else #ifndef WELL_ROUTE_CHECK description "MOSIS Scalable CMOS Technology for Standard Rules" #else description "MOSIS Scalable CMOS Technology for Standard Rules (No routing through wells)" #endif #endif /* HPTECH */ #endif /* IBMTECH */ #endif /* TIGHTMETAL */ end #endif /* V4 */ planes well,w implant,i active,a metal1,m1 metal2,m2 #ifdef STACKVIA v2oxide,v2x #endif metal3,m3 oxide,ox end types /* primary layers -16 */ well pwell,pw well nwell,nw well capwell,cwell,cw well highvoltnwell,hvnwell,hnwell,hnw well highvoltpwell,hvpwell,hpwell,hpw active polysilicon,red,poly,p active electrode,poly2,el,p2 active capacitor,polycap,pcap,cap active wellcapacitor,wellcap,wcap active ndiffusion,ndiff,green active pdiffusion,pdiff,brown active highvoltndiffusion,hvndiff,hndiff active highvoltpdiffusion,hvpdiff,hpdiff metal1 metal1,m1,blue metal2 metal2,m2,purple metal3 metal3,m3,cyan /* MOSFETs -8 */ active ntransistor,nfet active ptransistor,pfet active entransistor,enfet active eptransistor,epfet active doublentransistor,nfloating-gate,nfloatg,nfg,nffet active doubleptransistor,pfloating-gate,pfloatg,pfg,pffet active highvoltntransistor,hvnfet,hnfet active highvoltptransistor,hvpfet,hpfet /* NPN transistor layers -3 */ active collector,coll,col,co,cl active emitter,emit,em active pbase,pb /* layers for BCCD devices -2 */ implant bccdiffusion,bd active nbccdiffusion,nbd /* Contacts between interconnection layers -13 */ active polycontact,pcontact,polycut,pc active ndcontact,ndiffcut,ndc active pdcontact,pdiffcut,pdc active highvoltndcontact,hndiffcut,hndc active highvoltpdcontact,hpdiffcut,hpdc active capcontact,ccontact,capc,cc active electrodecontact,econtact,ec,poly2contact,p2c active collectorcontact,colcontact,colc,coc,clc active emittercontact,emitcontact,emc active pbasecontact,pbcontact,pbc active nbccdiffcontact,nbdc metal1 m2contact,m2cut,m2c,via,v #ifdef STACKVIA v2x m3contact,m3cut,m3c,via2,v2 #else metal2 m3contact,m3cut,m3c,via2,v2 #endif /* Well contacts -8 */ /* pohmic and nohmic are included for compatibility */ /* nwc, pwc, etc ... are included for compatibility */ active psubstratepcontact,ppcontact,ppc,pwcontact,pwc,psc active nsubstratencontact,nncontact,nnc,nwcontact,nwc,nsc active psubstratepdiff,ppdiff,pohmic,ppd,psd active nsubstratendiff,nndiff,nohmic,nnd,nsd active highvoltpsubcontact,hpwcontact,hpsc active highvoltnsubcontact,hnwcontact,hnsc active highvoltpsubdiff,hpohmic,hpsd active highvoltnsubdiff,hnohmic,hnsd /* Special tiles needed for ESD protection design -3 */ active nplusdoping,ndoping,ndop active pplusdoping,pdoping,pdop metal1 genericcontact,gcontact,gc /* Special tiles needed for micromachine fab. in CMOS -2 */ oxide substrateopen,subopen,open oxide pdiffusionstop,pdiffstop,pstop /* Additional stuff, used in pads. -2 */ metal2 pad oxide glass end contact /* polys */ ec poly2 metal1 cc cap metal1 pc poly metal1 /* active contacts */ ndc ndiff metal1 pdc pdiff metal1 nsc nsd metal1 psc psd metal1 hndc hndiff metal1 hpdc hpdiff metal1 hnsc hnsd metal1 hpsc hpsd metal1 /* bipolar contacts */ clc col metal1 emc emit metal1 pbc pbase metal1 /* BCCD contact */ nbdc nbd metal1 /* vias */ m2c metal1 metal2 #ifdef STACKVIA m3c metal2 m3c metal3 #else m3c metal2 metal3 #endif /* pad metal1 metal2 metal3 */ end styles styletype mos /* wells */ cwell 10 nwell 12 pwell 13 hnwell 18 hpwell 11 /* poly */ poly 1 poly2 14 /* diffusions */ ndiff 2 pdiff 4 psd 5 nsd 3 hndiff 2 hndiff 11 hpdiff 4 hpdiff 18 hpsd 5 hpsd 11 hnsd 3 hnsd 18 ndop 2 ndop 38 pdop 4 pdop 38 /* transistors */ nfet 6 nfet 7 pfet 8 pfet 9 enfet 6 enfet 30 /* enfet 14 */ epfet 8 epfet 31 /* epfet 14 */ nffet 6 nffet 7 /* nffet 14 */ nffet 30 pffet 8 pffet 9 /* pffet 14 */ pffet 31 hnfet 6 hnfet 7 hnfet 30 hpfet 8 hpfet 9 hpfet 31 /* base */ pbase 15 pbc 15 pbc 20 pbc 32 /* emitter */ emit 16 emc 16 emc 20 emc 32 /* collector */ col 3 clc 3 clc 20 clc 32 /* capacitors */ cap 1 cap 14 wcap 6 wcap 10 cc 1 cc 14 cc 20 cc 32 /* metals */ metal1 20 metal2 21 metal3 22 /* generic contact */ gc 19 /* poly contacts */ pcontact 26 pcontact 32 ec 14 ec 20 ec 32 /* diffusion contacts */ ndc 2 ndc 20 ndc 32 pdc 4 pdc 20 pdc 32 psc 5 psc 20 psc 32 nsc 3 nsc 20 nsc 32 /* high-voltage diffusion contacts */ hndc 2 hndc 20 hndc 32 hndc 11 hpdc 4 hpdc 20 hpdc 32 hpdc 18 hpsc 5 hpsc 20 hpsc 32 hpsc 11 hnsc 3 hnsc 20 hnsc 32 hnsc 18 /* vias */ m2contact 20 m2contact 21 m2contact 33 m3contact 21 m3contact 22 m3contact 37 /* pads and overglass */ pad 20 pad 21 pad 33 pad 34 glass 34 /* CCDs */ bd 17 nbd 17 nbd 3 nbdc 3 nbdc 17 nbdc 20 nbdc 32 /* MEMs */ open 2 open 20 pstop 8 /* System */ error_p 42 error_s 42 error_ps 42 end compose /* MOSFET combination rules */ compose nfet poly hndiff compose pfet poly hpdiff compose nfet poly ndiff compose pfet poly pdiff compose hnfet poly2 hndiff compose hpfet poly2 hpdiff compose enfet poly2 ndiff compose epfet poly2 pdiff compose nffet nfet poly2 compose pffet pfet poly2 compose nffet enfet poly compose pffet epfet poly compose cap poly poly2 /* Transistor combination rules */ paint clc col clc paint emc emit emc paint emc pbase emc /* Poly2 capacitor combination rules */ paint poly2 poly cap paint poly poly2 cap paint poly cap cap paint poly2 cap cap paint cap poly cap paint cap poly2 cap /* ILLEGAL declaration by 7.3 standards */ /* paint poly ec cc */ paint ec poly cc /* These rules allow nwell to be painted over an area to * flip all the p-well types to n-well types. Pwell can be * painted to flip in the reverse. */ paint pdc pwell ndc paint pfet pwell nfet paint epfet pwell enfet paint pffet pwell nffet paint pdiff pwell ndiff paint nsd pwell psd paint nsc pwell psc paint ndc nwell pdc paint nfet nwell pfet paint enfet nwell epfet paint nffet nwell pffet paint ndiff nwell pdiff paint psd nwell nsd paint psc nwell nsc paint pdc hpwell hndc paint epfet hpwell hnfet paint pffet hpwell hnfet paint pdiff hpwell hndiff paint nsd hpwell hpsd paint nsc hpwell hpsc paint ndc hnwell hpdc paint enfet hnwell hpfet paint nffet hnwell hpfet paint ndiff hnwell hpdiff paint psd hnwell hnsd paint psc hnwell hnsc /* BCCD layers combination rules */ /* paint bd ndiff 0 implant */ /* erase nbd bd ndiff erase nbd ndiff bd erase nbdc/a bd ndc/a */ /* Well capacitor combination rules */ paint nfet cwell wcap paint poly wcap wcap paint ndiff wcap wcap paint wcap poly wcap paint wcap ndiff wcap erase wcap poly ndiff erase wcap ndiff poly erase wcap cwell nfet paint cwell nfet wcap active erase wcap nfet cwell well /* Generic contact */ paint gc m1 gc /* For pads */ paint pad m1 pad paint pad m2 pad paint pad m3 pad paint pad m2c pad /* These rules allow nwell to be painted over an area to * flip all the p-well types to n-well types. Pwell can be * painted to flip in the reverse. */ paint hpdc hpwell hndc paint hpfet hpwell hnfet paint hpdiff hpwell hndiff paint hnsd hpwell hpsd paint hnsc hpwell hpsc paint hndc hnwell hpdc paint hnfet hnwell hpfet paint hndiff hnwell hpdiff paint hpsd hnwell hnsd paint hpsc hnwell hnsc paint hpdc pwell ndc paint hpfet pwell enfet paint hpdiff pwell ndiff paint hnsd pwell psd paint hnsc pwell psc paint hndc nwell pdc paint hnfet nwell epfet paint hndiff nwell pdiff paint hpsd nwell nsd paint hpsc nwell nsc end connect #ifndef WELL_ROUTE_CHECK /* This creates a tech file where the wells are not connected therefore enabling extractions to check whether the wells are used accidentaly to route signals or power. To check for these cases you have to compare the netlists generated with the normal tech file with those generated with the special one (eg. using gemini). */ allNwell allNwell allPwell allPwell #endif allHVNwell allHVNwell allHVPwell allHVPwell /* for capacitor-well */ allNDiff cwell /* for all metals */ allMetal1 allMetal1 allMetal2 allMetal2 allMetal3 allMetal3 /* for all polys */ allP1 allP1 allPoly2 allPoly2 /* for all diffusions/well plugs */ /* Ndiffusion and Ohmic wells dont connect !! */ /* you get a diode instead */ allNDiff,ndop allPOhmic,pdop,pstop allPDiff,pdop,pstop allNOhmic,ndop allHVNDiff,ndop allHVPOhmic,pdop,pstop allHVPDiff,pdop,pstop allHVNOhmic,ndop ndiff ndc pdiff pdc hndiff hndc hpdiff hpdc /* for BCCD device */ nbd nbdc /* for NPN transistor */ pbase pbc collector clc,nwell emitter emc /* for new generic contact */ gc allActive,allOhmic,allHVDiff,metal1 gc allP1 gc allPoly2 /* for pad */ pad allMetal1 pad allMetal2 pad allMetal3 end /* WARNING ::::: automatic generation of wells does not guarantee */ /* rules on width and spacing of wells are followed !! */ /* It is strongly recommanded that designers layout their own wells */ /* PWELL styles cannot generate CBA and CCD correctly */ /* BOTH NWELL and GEN can do CCD and CBA */ /* ONLY GEN can be used for micro-machining fabrication */ cifoutput /* default: fab on 2.0 micron (Nwell) rules each magic unit is 100 */ /* centmicrons */ /* SCN technology : Both CSN and CSP are generated to reduce field */ /* poly sheet resistance */ #ifdef STANDARD #include "cif_template/objs/CIFout" #endif /* STANDARD */ #ifdef TIGHTMETAL #include "cif_template/objs/TMCIFout" #endif /* TIGHTMETAL */ #ifdef SUBMICRON #include "cif_template/objs/SUBCIFout" #endif /* SUBMICRON */ #ifdef IBMTECH #include "cif_template/objs/IBMCIFout" #endif /* IBMTECH */ style plot /* pplot output style */ scalefactor 100 50 layer CM2 m2,m2c/m2,pad/m2 labels m2 layer CM1 pad grow 100 or m1,m2c/m1,pc/m1,ndc/m1,pdc/m1,ppcont/m1,nncont/m1 labels m1,m2c/m1,pc/m1,ndc/m1,pdc/m1,ppcont/m1,nncont/m1,pad/m1 layer CP poly,pc/active,nfet,pfet labels poly,nfet,pfet layer CND ndiff,ndc,nfet,pwc,psd labels ndiff layer CPD pdiff,pdc,pfet,nwc,nsd labels pdiff layer CNP bloat-or nsd,nwc * 150 ndiff,pdiff,ndc/active,pdc/active,ppcont/active,nncont/active,pfet,nfet,psd,nsd 0 layer CPP bloat-or psd,pwc * 150 ndiff,pdiff,ndc/active,pdc/active,ppcont/active,nncont/active,pfet,nfet,psd,nsd 0 layer CV m2c squares 100 200 300 layer CC ndc,pdc,pc,pwc,nwc squares 200 layer CNW nwell grow 400 shrink 400 layer CG pad shrink 600 or glass labels glass end /* -------------------------------------------------------------------- * * In the CIFinput section, the order of layer specifications is very * * important. Each layer overrides any of the previous layers. There * * are places where one layer is generated over an area that is too * * large, but with the knowledge that later layers will "take over" * * the extraneous area, leaving the first layer only where it belongs. * * This happens for various flavors of diffusion, for example. * * Note: when reading in CMOS, wells are created in the Magic files. * * They can be eliminated manually if desired. * * ---------------------------------------------------------------------*/ cifinput #ifdef STANDARD #include "cif_template/objs/CIFin" #endif /* STANDARD */ #ifdef TIGHTMETAL #include "cif_template/objs/TMCIFin" #endif /* TIGHTMETAL */ #ifdef SUBMICRON #include "cif_template/objs/SUBCIFin" #endif /* SUBMICRON */ #ifdef IBMTECH #include "cif_template/objs/IBMCIFin" #endif /* IBMTECH */ end mzrouter style irouter layer m2 32 64 256 1 layer m1 64 32 256 1 layer poly 128 128 512 1 contact m2contact metal1 metal2 1024 contact pcontact metal1 poly 2056 notactive poly pcontact style garouter layer m2 32 64 256 1 layer m1 64 32 256 1 contact m2contact metal1 metal2 1024 end /* SCMOS rules revision 7 */ drc /* ---------------------------------------------------------------- */ /* Well */ /* ---------------------------------------------------------------- */ /* 1.1 */ /* Now use "edge" for width DRC... A test only for rule1 */ /* Other rules may follow in the near future... */ #ifdef SUBMICRON edge4way (~nwell)/w nwell 12 nwell nwell 12\ "N-Well width must be at least 12 (MOSIS rule #1.1)" edge4way (~pwell)/w pwell 12 pwell pwell 12\ "P-Well width must be at least 12 (MOSIS rule #1.1)" #else edge4way (~nwell)/w nwell 10 nwell nwell 10\ "N-Well width must be at least 10 (MOSIS rule #1.1)" edge4way (~pwell)/w pwell 10 pwell pwell 10\ "P-Well width must be at least 10 (MOSIS rule #1.1)" #endif /* original "width" rule which use 'width'command: width allWell 10 \ "Well width must be at least 10 (MOSIS rule #1.1)" */ /* 1.2 */ /* Now use "edge4way" for spacing DRC... A test only for rule1 */ /* Other rules may follow in the near future... */ #ifdef SUBMICRON edge4way nwell ~(nwell)/w 18 (~nwell)/w (~nwell)/w 18\ "N-Well spacing must be at least 18 (MOSIS rule #1.2)" edge4way pwell (~pwell)/w 18 (~pwell)/w (~pwell)/w 18\ "P-Well spacing must be at least 18 (MOSIS rule #1.2)" #else edge4way nwell (~nwell)/w 9 (~nwell)/w (~nwell)/w 9\ "N-Well spacing must be at least 9 (MOSIS rule #1.2)" edge4way pwell (~pwell)/w 9 (~pwell)/w (~pwell)/w 9\ "P-Well spacing must be at least 9 (MOSIS rule #1.2)" #endif /* original spacing rule which use 'spacing' command: spacing allWell allWell 9 touching_ok \ "Well spacing must be at least 9 (MOSIS rule #1.2)" */ /* NOTE: rule 1.2 is equivalent to the following three rules where the third is a new one. This rule is added to force designers to be cautious about the wells... spacing nwell nwell 9 touching_ok \ "N-well spacing must be at least 9 (MOSIS rule #1.2)" spacing pwell pwell 9 touching_ok \ "P-well spacing must be at least 9 (MOSIS rule #1.2)" spacing nwell pwell 9 touching_ok \ "Well spacing must be at least 9 (MOSIS rule #1.2)" */ /* 1.3 is not checked */ /* NOTE: for digital ckts where wells are not explicitly put, * * auto-generation may not ensure the minimul spacing and width * * rule: this happens usually when two geometries are in diagonal * * positions. * * NOTE: when both pwell and nwell are submitted they cannot * * overlap this is assured with the compose section - painting one * * well over another will erase the original well. */ /* ---------------------------------------------------------------- */ /* Active */ /* ---------------------------------------------------------------- */ /* 2.1 */ /* Test active width separately... */ width allNActive 3 \ "N-type Diffusion width must be at least 3 (MOSIS rule #2.1a)" width allPActive 3 \ "P-type Diffusion width must be at least 3 (MOSIS rule #2.1b)" width allOhmic 3 \ "Ohmic diffusion width must be at least 3 (MOSIS rule #2.1c)" /* 2.2 */ spacing allNActive allNActive 3 touching_ok \ "Diffusion spacing must be at least 3 (MOSIS rule #2.2)" spacing allPActive allPActive 3 touching_ok \ "Diffusion spacing must be at least 3 (MOSIS rule #2.2)" spacing allNOhmic allNOhmic 3 touching_ok \ "Diffusion spacing must be at least 3 (MOSIS rule #2.2)" spacing allPOhmic allPOhmic 3 touching_ok \ "Diffusion spacing must be at least 3 (MOSIS rule #2.2)" /* 2.3 without explicit well definition: 6+6 and 5+5 respectively */ #ifdef SUBMICRON spacing allNDiff allPDiff 12 touching_illegal \ "P-type diffusion must be 12 away from N-type diffusion (MOSIS rule #2.3b)" #else spacing allNDiff allPDiff 10 touching_illegal \ "P-type diffusion must be 10 away from N-type diffusion (MOSIS rule #2.3a)" #endif /* 2.3 + 2.4 without explicit well definition: 6+3 and 5+3 respectively */ #ifdef SUBMICRON spacing allNDiff allNOhmic 9 touching_illegal \ "N-type diffusion must be 9 away from N-substrate contact (MOSIS rule #2.3b,4b)" spacing allPDiff allPOhmic 9 touching_illegal \ "P-type diffusion must be 9 away from P-substrate contact (MOSIS rule #2.3b,4b)" #else spacing allNDiff allNOhmic 8 touching_illegal \ "N-type diffusion must be 8 away from N-substrate contact (MOSIS rule #2.3a,4a)" spacing allPDiff allPOhmic 8 touching_illegal \ "P-type diffusion must be 8 away from P-substrate contact (MOSIS rule #2.3a,4a)" #endif /* 2.4 3 + 3 */ spacing allNOhmic allPOhmic 6 touching_illegal \ "Opposite well contacts must be separated by 6 (MOSIS rule #2.4)" /* 2.3 with explicit well: 6 and 5 respectively */ #ifdef SUBMICRON spacing allNActive nwell 6 touching_illegal \ "N-diffusion and N-well must be separated by 6 (MOSIS rule #2.3b)" spacing allPActive pwell 6 touching_illegal \ "P-diffusion and P-well must be separated by 6 (MOSIS rule #2.3b)" #else spacing allNActive nwell 5 touching_illegal \ "N-diffusion and N-well must be separated by 5 (MOSIS rule #2.3a)" spacing allPActive pwell 5 touching_illegal \ "P-diffusion and P-well must be separated by 5 (MOSIS rule #2.3a)" #endif /* 2.4 with explicit well */ spacing allNOhmic pwell 3 touching_illegal \ "N-substrate diffusion and P-well must be separated by 3 (MOSIS rule #2.4)" spacing allPOhmic nwell 3 touching_illegal \ "P-substrate diffusion and N-well must be separated by 3 (MOSIS rule #2.4)" /* MOSIS extension rule for diffusion and substrate contact of */ /* opposite type. We could do without this rule, but it is now */ /* added for safety reason. */ spacing allNActive allPOhmic 4 touching_ok \ "Opposite diffusion spacing must be at least 4 (MOSIS extension rule)" spacing allPActive allNOhmic 4 touching_ok \ "Opposite diffusion spacing must be at least 4 (MOSIS extension rule)" /* ---------------------------------------------------------------- */ /* Poly */ /* ---------------------------------------------------------------- */ /* 3.1 */ width allPoly 2 \ "Polysilicon width must be at least 2 (MOSIS rule #3.1)" /* 3.2 */ #ifdef SUBMICRON spacing allPoly allPoly 3 touching_ok \ "Polysilicon spacing must be at least 3 (MOSIS rule #3.2b)" #else spacing allPoly allPoly 2 touching_ok \ "Polysilicon spacing must be at least 2 (MOSIS rule #3.2a)" #endif /* 3.3 */ edge4way nfet,pfet poly,pc/act 2 poly,pc/act 0 0 \ "Poly must overhang transistor by at least 2 (MOSIS rule #3.3)" /* 3.4 */ edge4way nfet,enfet ndiff,ndc/a 3 allNActive ndiff,ndc/a 3 \ "Diffusion must overhang transistor by at least 3 (MOSIS rule #3.4)" edge4way pfet,epfet pdiff,pdc/a 3 allPActive ndiff,ndc/a 3 \ "Diffusion must overhang transistor by at least 3 (MOSIS rule #3.4)" /* 3.3 + 3.4 */ edge4way nfet,pfet space 1 poly 0 0 \ "Transistor overhang is missing (MOSIS rule #3.3,4)" edge4way enfet,epfet space 1 poly2 0 0 \ "Transistor overhang is missing (MOSIS rule #3.3,4)" edge4way nffet,pffet space 1 poly 0 0 \ "Transistor overhang is missing (MOSIS rule #3.3,4)" edge4way nffet,pffet space 1 poly2 0 0 \ "Transistor overhang is missing (MOSIS rule #3.3,4)" /* 3.5 */ edge4way allDiff,allOhmic poly,pc 1 space/a 0 1 \ "Poly and diffusion must be separated by at least 1 (MOSIS rule #3.5)" edge4way poly,pc allDiff,allOhmic 1 space/a 0 1 \ "Poly and diffusion must be separated by at least 1 (MOSIS rule #3.5)" edge poly,pc space/a 1 space/a space/a 1 \ "Poly and diffusion must be separated by at least 1 (MOSIS rule #3.5)" edge allOhmic,allDiff space/a 1 space/a space/a 1 \ "Poly and diffusion must be separated by at least 1 (MOSIS rule #3.5)" /* These following checks will miss the corner, so we add something above edge4way allDiff,allOhmic poly,pc 1 space space 1 \ "Poly and diffusion must be separated by at least 1 (MOSIS rule #3.5.a)" spacing allDiff,allOhmic poly,pc 1 touching_illegal \ "Poly and diffusion must be separated by at least 1 (MOSIS rule #3.5.b)" */ /* Extra transistor rules */ /* These rules is really NOT necessary because others have already taken care of it. It is here for future reference... edge4way poly,pc/act pfet 3 pfet 0 0 \ "Transistors must be at least 3 units wide (MOSIS rule #2)" edge4way poly,pc/act nfet 3 nfet 0 0 \ "Transistors must be at least 3 units wide (MOSIS rule #2)" */ /* ---------------------------------------------------------------- */ /* Select */ /* ---------------------------------------------------------------- */ /* 4.1 */ spacing PFet allNOhmic 3 touching_illegal \ "Transistors must be separated from substrate contacts by 3 (MOSIS rule #4.1.a)" spacing NFet allPOhmic 3 touching_illegal \ "Transistors must be separated from substrate contacts by 3 (MOSIS rule #4.1.b)" edge4way allPOhmic space/act 3 ~(NFet)/act allPOhmic,allNDiff 3 \ "Transistors must be separated from selects(generated by well cont) by 3 (MOSIS rule #4.1.c)" edge4way allNOhmic space/act 3 ~(PFet)/act allNOhmic,allPDiff 3 \ "Transistors must be separated from selects(generated by well cont) by 3 (MOSIS rule #4.1.d)" edge4way allPOhmic ~(ndiff,ndc,psc,psd)/act 4 ~(nfet,enfet)/act ~(ndiff,ndc,psc,psd)/act 4 \ "Transistors must be separated from selects(generated by well cont) by 4 (MOSIS rule #4.1.e)" edge4way allNOhmic ~(pdiff,pdc,nsc,nsd)/act 4 ~(pfet,epfet)/act ~(pdiff,pdc,nsc,nsd)/act 4 \ "Transistors must be separated from selects(generated by well cont) by 4 (MOSIS rule #4.1.f)" /* 4.2 */ /* This one is very difficult.... Most likely done by CIF output */ edge4way ~(allPActive)/act pdiff,pdc,pfet 4 ~(allNOhmic)/act allPActive 2 \ "Backedge of diffusion must be 4 from substrate diff (MOSIS rule #4.2.a)" edge4way ~(allNActive)/act ndiff,ndc,nfet 4 ~(allPOhmic)/act allNActive 2 \ "Backedge of diffusion must be 4 from substrate diff (MOSIS rule #4.2.b)" /* 4.3 -- guaranteed automatically by CIF generator. */ /* 4.4 -- guaranteed automatically by CIF generator except diag. where this rule is not crucial */ /* ---------------------------------------------------------------- */ /* Contact to Poly */ /* ---------------------------------------------------------------- */ /* 5B.1 + 5B.2 + 5B.3 */ width pc 4 \ "Poly contact width must be at least 4 (MOSIS rule #5B.1,2,3)" /* 5B.4 is guaranteed by 5B.1,2,3 with rule 7.2 (metal1 spacing) */ /* 5B.5 -- * Watch out here: a spacing "touching_ok" rule CANNOT be used here: * it will miss certain checks. */ edge4way allPoly ~(allPoly)/act 3 ~pc/act ~(allPoly)/act 3 \ "Poly contact must be at least 3 from other poly (MOSIS rule #5B.4,5)" /* 5B.6 -- * This is mostly handled by 3.5 already, but need rule here to handle * case of pc abutting transistor. */ spacing pc allActive 1 touching_illegal \ "Poly contact must be 1 unit from diffusion (MOSIS rule #5B.6)" /* 5B.7 -- not implemented */ /* ---------------------------------------------------------------- */ /* Contact to Active */ /* ---------------------------------------------------------------- */ /* 6B.1 + 6B.2 + 6B.3 */ width ndc,pdc 4 \ "Diffusion contact width must be at least 4 (MOSIS rule #6B.1,2,3)" width nsc,psc 4 \ "Substrate contact width must be at least 4 (MOSIS rule #6B.1,2,3)" /* 6B.2 this is here to explicit check the contact spacing rule 3. */ #ifdef SUBMICRON spacing nsc pdc 1 touching_illegal \ "Substrate contact must be 1 unit from diffusion contact (MOSIS rule #6B.2b)" spacing psc ndc 1 touching_illegal \ "Substrate contact must be 1 unit from diffusion contact (MOSIS rule #6B.2b)" #endif /* edge4way psc (~psc)/a 1 psd psd 1 \ "Substrate contact must overlapped by diffusion by at least 1 (MOSIS 26G rule)" edge4way nsc (~nsc)/a 1 nsd nsd 1 \ "Substrate contact must overlapped by diffusion by at least 1 (MOSIS 26G rule)" */ /* 6B.4 & 6B.5 -- * Watch out here: a spacing "touching_ok" rule CANNOT be used here: * it will miss certain checks. */ edge4way allActive ~(allActive)/act 4 ~(ndc,pdc,nsc,psc)/act \ ~(allActive)/act 4 \ "Diffusion contacts must be 4 from other diffusions (MOSIS rule #6B.4,5)" /* 6B.6 */ spacing DiffCut allFet 1 touching_illegal \ "Diffusion contacts cannot touch transistors (MOSIS rule #6B.6)" /* 6B.7 */ spacing DiffCut poly 1 touching_illegal \ "Diffusion contact to field poly must be at least 1 (MOSIS rule #6B.7)" /* 6.8 -- not implemented */ /* 6B.9 */ spacing DiffCut pc/act 2 touching_illegal \ "Poly contacts must be 2 away from diffusion contacts (MOSIS rule #6B.9)" /* ---------------------------------------------------------------- */ /* Contacts must all be rectangular (no adjacent contacts */ /* of same type) because of the way their contact is generated by */ /* CIFoutput section rules. This is handled using the corner checks */ /* in the rules below. Overlaps between contacts must be exact */ /* overlaps. The only exception is overpad, which doesn't matter. */ edge4way m3c/m3 ~m3c/m3 1 ~m3c/m3 (~m3c,m3c)/m3 1 \ "Metal3 contacts must be rectangular (Magic rules)" edge4way m2c/m2 ~m2c/m2 1 ~m2c/m2 (~m2c,m2c)/m2 1 \ "Metal2 contacts must be rectangular (Magic rules)" edge4way ndc/m1 ~ndc/m1 1 ~ndc/m1 (~ndc,ndc)/m1 1 \ "N-diffusion contacts must be rectangular (Magic rules)" edge4way pdc/m1 ~pdc/m1 1 ~pdc/m1 (~pdc,pdc)/m1 1 \ "P-diffusion contacts must be rectangular (Magic rules)" edge4way psc/m1 ~psc/m1 1 ~psc/m1 (~psc,psc)/m1 1 \ "P-substrate contacts must be rectangular (Magic rules)" edge4way nsc/m1 ~nsc/m1 1 ~nsc/m1 (~nsc,nsc)/m1 1 \ "N-substrate contacts must be rectangular (Magic rules)" edge4way pc/m1 ~pc/m1 1 ~pc/m1 (~pc,pc)/m1 1 \ "Polysilicon contacts must be rectangular (Magic rules)" edge4way ec/m1 ~ec/m1 1 ~ec/m1 (~ec,ec)/m1 1 \ "Electrode contacts must be rectangular (Magic rules)" edge4way cc/m1 ~cc/m1 1 ~cc/m1 (~cc,cc)/m1 1 \ "Capacitor contacts must be rectangular (Magic rules)" edge4way emc/m1 ~emc/m1 1 ~emc/m1 (~emc,emc)/m1 1 \ "Emitter contacts must be rectangular (Magic rules)" edge4way clc/m1 ~clc/m1 1 ~clc/m1 (~clc,clc)/m1 1 \ "Collector contacts must be rectangular (Magic rules)" edge4way pbc/m1 ~pbc/m1 1 ~pbc/m1 (~pbc,pbc)/m1 1 \ "P-base Contacts must be rectangular (Magic rules)" edge4way nbdc/m1 ~nbdc/m1 1 ~nbdc/m1 (~nbdc,nbdc)/m1 1 \ "CCD-diffusion Contacts must be rectangular (Magic rules)" /* ---------------------------------------------------------------- */ /* Metal 1 */ /* ---------------------------------------------------------------- */ /* 7.1 + 7.2 */ width allMetal1,pad/m1 3 \ "First-level metal width must be at least 3 (MOSIS rule #7.1)" #ifdef TIGHTMETAL spacing allMetal1,pad/m1 allMetal1,pad/m1 2 touching_ok \ "First-level metal spacing must be at least 2 (MOSIS rule #7.2)" #else spacing allMetal1,pad/m1 allMetal1,pad/m1 3 touching_ok \ "First-level metal spacing must be at least 3 (MOSIS rule #7.2)" #endif /* TIGHTMETAL */ /* 7.3 + 7.4 */ /* guaranteed with 4x4 poly and diffusion contacts */ /* ---------------------------------------------------------------- */ /* Via */ /* ---------------------------------------------------------------- */ /* 8.1 + 8.2 + 8.3 */ width m2c 4 \ "Contact width must be at least 4 (MOSIS rule #8.1,2,3)" /* 8.4 + 8.5 */ /* Vias have to be on flat surface */ /* Don't allow poly or diffusion edges underneath metal2 contacts: */ /* this rule is only valid for standard processes, not for those */ /* processes use planarized interconnection technology. */ #ifdef STANDARD edge4way allPoly ~(allPoly)/a 1 ~m2c/m2 ~(allPoly)/a 1 \ "Via must be on a flat surface (MOSIS rule #8.4,5)" metal2 edge4way allPoly2 ~(allPoly2)/a 1 ~m2c/m2 ~(allPoly2)/a 1 \ "Via must be on a flat surface (MOSIS rule #8.4,5)" metal2 edge4way allActive ~(allActive)/a 1 ~m2c/m2 ~(allActive)/a 1 \ "Via must be on a flat surface (MOSIS rule #8.4,5)" metal2 edge4way ~(allPoly)/a allPoly 1 ~m2c/m2 allPoly 1 \ "Via must be on a flat surface (MOSIS rule #8.4,5)" metal2 edge4way ~(allPoly2)/a allPoly2 1 ~m2c/m2 allPoly2 1 \ "Via must be on a flat surface (MOSIS rule #8.4,5)" metal2 edge4way ~(allActive)/a allActive 1 ~m2c/m2 allActive 1 \ "Via must be on a flat surface (MOSIS rule #8.4,5)" metal2 #endif /* STANDARD */ /* ---------------------------------------------------------------- */ /* Metal 2 */ /* ---------------------------------------------------------------- */ /* 9.1 */ width allMetal2 3 \ "Second-level metal width must be at least 3 (MOSIS rule #9.1)" /* 9.2 */ #ifdef TIGHTMETAL spacing allMetal2 allMetal2 3 touching_ok \ "Second-level metal spacing must be at least 3 (MOSIS rule #9.2b)" #else #ifdef SUBMICRON spacing allMetal2 allMetal2 3 touching_ok \ "Second-level metal spacing must be at least 3 (MOSIS rule #9.2b)" #else spacing allMetal2 allMetal2 4 touching_ok \ "Second-level metal spacing must be at least 4 (MOSIS rule #9.2a)" #endif /* SUBMICRON */ #endif /* TIGHTMETAL */ /* 9.3 */ /* achieved with via size of 4x4 */ /* ---------------------------------------------------------------- */ /* Overglass */ /* ---------------------------------------------------------------- */ /* Rules for overglass (10.1-5) are not check because they are */ /* either */ /* 1. absolute micron rules, and */ /* 2. vender/process dependent. */ /* except the metal overlap of overglass rule (10.3) can be handled */ /* case by case in CIFoutput section. */ /* NOTE: glass layer is NOT usually used. Use "pad" layer for pad */ /* and the corresponding overglass will be generated automatically. */ /* MOSIS rules to make sure there are m2 under glass - for those */ /* users who like to use explicit "glass" layer... */ /* */ /* edge4way space glass 1 allMetal2 0 0 \ */ /* "There must be metal 2 under the glass openning" metal2 */ /* */ /* I am removing this rule simply we have metal3 now and there's no */ /* way to tell which process the pad is intended for. Basically, I */ /* am enforcing the use of "pad" layer... */ /* ---------------------------------------------------------------- */ /* Open and Pstop */ /* ---------------------------------------------------------------- */ /* The open layer is actually a combination of overglass and */ /* contacts to expose the intrinsic silicon surface for future */ /* etchimg process for micromachining device fabrication. */ /* Since lots of applications are possible, there is no rules */ /* enforced by Magic. Designers aimed at micromachining devices */ /* must do DRC themself :-) */ /* See the following reference for detail: */ /* "High-Level CAD Melds Micromachined Devices with Foundaries", */ /* Janet C. Marshall, M. Parameswaran, Mona E. Zaghloul, and */ /* Michael Gaitan, IEEE Circuit and Devices, Vol. 8, No. 6, */ /* pp. 10-17, 1992 */ /* ---------------------------------------------------------------- */ /* Poly2 as Capacitor */ /* ---------------------------------------------------------------- */ /* 11.1 */ /* The exact rule asks for 3 lambda minimum width for 'capacitor'. */ /* But there are overlaps of poly/eletrode structures such that 2 */ /* is fine, such as the overlaps in floating gates. So we are risk- */ /* ing a little here... */ width cap,capc/a 2 \ "Electrode capacitor width must be at least 3 (MOSIS rule #11.1)" /* 11.2 + 12.2 */ spacing allPoly2 allPoly2 3 touching_ok \ "Second-level poly spacing must be at least 3 (MOSIS rule #11.2,12.2)" /* 11.3 */ edge4way cap,cc space 1 0 0 0 \ "Cap must be overlapped by poly or poly2 (MOSIS rule #11.3)" edge4way cap,cc poly 2 poly poly 2 \ "Cap must be overlapped by poly or poly2 (MOSIS rule #11.3)" edge4way cap,cc poly2 2 poly2 poly2 2 \ "Cap must be overlapped by poly or poly2 (MOSIS rule #11.3)" /* 11.4 */ edge4way nw,pw,cw ~(nw,pw,cw)/w 2 ~(cap,cc)/a ~(nw,pw,cw)/w 2 \ "Cap must be on a flat surface (MOSIS rule #11.4)" active edge4way ~(nw,pw,cw)/w nw,pw,cw 2 ~(cap,cc)/a nw,pw,cw 2 \ "Cap must be on a flat surface (MOSIS rule #11.4)" active edge4way cap ~(cap)/a 2 allFet,poly,poly2,space/a,cc/a \ allDiff,poly 2 "Cap must be on a flat surface (MOSIS rule #11.4)" active /* 11.5 */ /* Done by 11.3 and 11.4 */ /* ---------------------------------------------------------------- */ /* Poly2 as Transistor */ /* ---------------------------------------------------------------- */ /* 12.1 */ width allPoly2 2 \ "Electrode width must be at least 2 (MOSIS rule #12.1)" /* 12.2 */ /* Done by 11.2 */ /* 12.3 */ edge4way enfet,epfet poly2,ec/a 2 poly2,ec/a 0 0 \ "Poly2 must overhang transistor by at least 2 (MOSIS rule #12.3)" edge4way nffet,pffet cap 2 cap 0 0 \ "Cap must overhang transistor by at least 2 (MOSIS rule #12.3)" edge4way nffet ~(cap,nffet,enfet,nfet)/a 2 cap 0 0 \ "Cap must overhang doubletransistor by at least 2 (MOSIS rule #12.3)" edge4way pffet ~(cap,pffet,epfet,pfet)/a 2 cap 0 0 \ "Cap must overhang doubletransistor by at least 2 (MOSIS rule #12.3)" /* 12.4 */ edge4way allDiff,allOhmic el 1 space/a 0 1 \ "Poly2 and diffusion must be separated by at least 1 (MOSIS rule #12.4)" /* 12.5 */ /* 12.6 */ spacing allPoly2 pc,ndc,pdc 2 touching_illegal \ "Poly2 spacing to poly or diffusion contact must be at least 3 (MOSIS rule #12.6)" /* edge4way poly2,ec/a epfet 3 epfet 0 0 \ "Transistors must be at least 3 units wide (MOSIS rule #2)" edge4way poly2,ec/a enfet 3 enfet 0 0 \ "Transistors must be at least 3 units wide (MOSIS rule #2)" edge4way cap,capc/a pffet 3 pffet 0 0 \ "Transistors must be at least 3 units wide (MOSIS rule #2)" edge4way cap,capc/a nffet 3 nffet 0 0 \ "Transistors must be at least 3 units wide (MOSIS rule #2)" */ /* ---------------------------------------------------------------- */ /* Poly2 Contact */ /* ---------------------------------------------------------------- */ /* 13.1 + 13.2 */ width ec,capc 4 \ "Electrode contact width must be at least 4 (MOSIS rule #13.1)" /* 13.3 */ /* Done by 11.3 */ /* 13.4 */ edge4way ec/a space 1 poly2 poly2 1 \ "Electrode contact must be overlaped by poly2 (MOSIS rule #13.4)" edge4way ec/a poly2 1 poly2 poly2 1 \ "Electrode contact must be overlaped by poly2 by 1 (MOSIS rule #13.4)" /* 13.5 */ edge4way allDiff,allOhmic ec 2 space/a 0 2 \ "Poly2 and diffusion contact must be separated by at least 2 (MOSIS rule #13.5)" /* ---------------------------------------------------------------- */ /* Via 2 */ /* ---------------------------------------------------------------- */ /* 14.1 + 14.2 + 14.3 */ /* By CIF output generation */ width m3c 4 \ "Third-level metal contact width must be at least 4 (MOSIS rule #14.1,2,3)" /* 14.4 */ /* guaranteed by 4x4 m2c and 4x4 m3c */ /* Via2, i.e "m3c" can overlap anything except m2c layer */ /* ---------------------------------------------------------------- */ /* Metal 3 */ /* ---------------------------------------------------------------- */ /* 15.1 */ #ifdef SUBMICRON width allMetal3 5 \ "Third-level metal width must be at least 5 (MOSIS rule #15.1b)" #else width allMetal3 6 \ "Third-level metal width must be at least 6 (MOSIS rule #15.1a)" #endif /* 15.2 */ #ifdef SUBMICRON spacing allMetal3 allMetal3 3 touching_ok \ "Third-level metal spacing must be at least 3 from other third-level metal (MOSIS rule #15.2b)" #else spacing allMetal3 allMetal3 4 touching_ok \ "Third-level metal spacing must be at least 4 from other third-level metal (MOSIS rule #15.2a)" #endif /* 15.3 */ edge4way m3c/m3 ~m3c/m3 1 m3 m3 1 \ "Mimimum metal3 overlap of via must be at least 1 (MOSIS rule #15.3)" /* ---------------------------------------------------------------- */ /* NPN Bipolar */ /* ---------------------------------------------------------------- */ /* 16.1 */ /* As always, composite contacts are 4x4, where the actual */ /* transistor contacts are 2x2 by CIF output generator */ width clc,pbc,emc 4 \ "Transistor contact width must be at least 4 (MOSIS rule #16.1)" /* 16.2 */ /* Done by 16.1 4x4 emc and CIF output generation */ /* 16.3 */ /* This rule is guaranteed by the way the CIF output generates */ /* N-Select for emitter (expand by 2 lambda), so we have Pbase */ /* overlap of emitter(or emc) by 2+2 =4 */ edge4way emc/a,emit pbase 4 pbase pbase 4 \ "Pbase overlap of emitter must be at least 4 (MOSIS rule #16.3)" /* 16.4 */ /* NOTE; NO need to make this an edge rule... */ spacing pbc emc/a,emit 7 touching_illegal \ "Base must be 7 (4+2+1) away from emitter (MOSIS rule #16.3,4,11)" /* 16.5 */ /* This rule is guaranteed by requiring that base contact has */ /* at least 3 (1+2) lambda base enclosure... */ /* edge4way pbc/a pb,space 3 pb pb,space 3 */ edge4way pbc (~pbc)/a 3 pb,pbc/a pb,pbc/a 3 \ "Pbase overlap of base contact must be at least 3 (MOSIS rule #16.5)" /* 16.6 */ /* This rule is guaranteed by the CIF output generation of P-select */ /* 16.6 */ /* This rule is enforced by checking whether collector is out of */ /* Nwell and the fact that collector width is required to be at */ /* least 6 */ width col,clc/a 6 \ "Collector width must be at least 6 (MOSIS rule #16.6)" /* 16.7 */ /* Explicit Nwell required for Bipolar transistors... */ edge4way pbase space/a 6 nwell space/a 6 \ "Nwell overlap of Pbase must be at least 6 (MOSIS rule #16.7)" well /* 16.8 */ edge4way pbase (~pbase)/a 4 ~(col,clc)/a ~(col,clc)/a 4 \ "Pbase must be at least 4 away from collector (MOSIS rule #16.8)" /* 16.9 */ edge4way clc (~clc)/a 1 col col 1 \ "Collector overlap of contact must be at least 1 (MOSIS rule #16.9)" /* 16.10 */ /* This rule is guaranteed by making sure that collector is within */ /* PBase and the corresponding CIF output generation */ /* 16.11 */ edge4way nw ~(nw)/w 3 ~(col,clc)/a ~(nw)/w 3 \ "N-well overlap of collector must be at least 3 (MOSIS rule #16.11)" active edge4way ~(nw)/w nw 3 ~(col,clc)/a nw 3 \ "N-well overlap of collector must be at least 3 (MOSIS rule #16.11)" active /* This is a special rule to gurantee the emitter width */ width em,emc/a 4 \ "Emitter width must be at least 4 (Magic Bipolar Transistor rule)" /* This is a special rule for multi-emitters transistor according */ /* to rule 16.2 and 2.2 */ spacing em,emc/a em,emc/a 7 touching_ok \ "Unrelated emitter must be at least 7 apart (Magic Bipolar transistor rule)" /* The following rules are added for pbase resistor implementation. */ /* They are not in the official SCMOS design rules since I have no */ /* foundry rules available at this moment and the numbers here is */ /* considered to be conservative... */ width pbase,pbc/a 4 \ "Pbase width must be at least 4 (MOSIS extension rule)" spacing pbase,pbc/a pbase,pbc/a 4 touching_ok \ "Pbase spacing must be at least 4 (MOSIS extension rule)" /* ---------------------------------------------------------------- */ /* Capacitor Well */ /* ---------------------------------------------------------------- */ /* These are DRC rules for Capacitor Well (CWell) according to HP's */ /* 1.2um linear capacitor process pi@isi.edu 9/18/92 */ /* ---------------------------------------------------------------- */ /* 17.1 */ width cwell 10 \ "Cap-well width must be at least 10 (MOSIS rule #17.1)" /* 17.2 */ spacing cwell cwell 9 touching_ok \ "Cap-well spacing must be at least 9 (MOSIS rule #17.2)" spacing cwell nwell 9 touching_illegal \ "Cap-well spacing must be at least 9 (MOSIS rule #17.2)" /* 17.3 */ edge4way cwell space 5 ~(allNActive)/a ~(allNActive)/w 5 \ "Cap-well spacing to external active must be at least 5 (MOSIS rule #17.3)" active edge4way cwell space 3 ~(allPOhmic)/a ~(allPOhmic)/w 3 \ "P-substrate diffusion and Cap-well must be separated by 3 (MOSIS rule #17.3)" active /* 17.4 */ /* Need to do this check from the Cap-well plane - in order Not */ /* to conflict with the general rules for N-diffusion */ edge4way space cwell 3 (space,poly,pc)/a 0 0 \ "Cap-well overlap of diffusion must be at least 3 (MOSIS rule #17.4)" active /* ---------------------------------------------------------------- */ /* Well-capacitor */ /* ---------------------------------------------------------------- */ /* These are DRC rules for Well-capacitor (wcap) according to HP's */ /* 1.2um linear capacitor process pi@isi.edu 9/18/92 */ /* Rule 18.5 and 18.6 are preliminary, they are conservative here! */ /* ---------------------------------------------------------------- */ /* 18.1 */ width wcap 3 \ "Well-capacitor must be at least 3 (MOSIS rule #18.1)" /* 18.2 */ /* achieved by rule 3.5 */ /* 18.3 */ edge4way wcap space 1 poly poly 1 \ "Well-capacitor overhang is missing (MOSIS rule #18.3)" /* 18.4 */ edge4way wcap ndiff 3 ndiff ndiff 3 \ "N-diffusion overlap of well-capacitor must be at least 3 (MOSIS rule #18.4)" /* 18.5 */ /* achieved by rule 5B.6 */ spacing wcap pc 2 touching_illegal \ "Well-capacitor spacing to poly contact must be at least 2 (MOSIS rule #18.5)" /* 18.6 */ /* similar to rule 6A.4 or 6B.6 */ spacing wcap ndc 4 touching_illegal \ "Well-capacitor spacing to diffusion contact must be at least 4 (MOSIS rule #18.6)" /* ---------------------------------------------------------------- */ /* Buried CCD */ /* ---------------------------------------------------------------- */ /* 19.1 */ /* Have to do it seperately... */ width nbd,nbdc,bd/a 4 \ "CCD channel width must be at least 4 (MOSIS rule #19.1)" width nbdc 4 \ "CCD contact width must be at least 4 (MOSIS rule #19.1)" /* 19.2 */ /* The 4 lambda spacing is a conservative guess here... */ /* This following rule will NOT work! Need to check 2 planes */ /* separately.... */ /* spacing bd/a,nbd,nbdc bd/a,nbd,nbdc 4 touching_ok \ "CCD channel spacing must be at least 4 (MOSIS rule #19.2)" */ edge4way nbd,nbdc ~(bd,nbd,nbdc)/a 4 (bd,space)/i 0 0 \ "CCD channel spacing must be at least 4 (MOSIS rule #19.2)" implant edge4way nbd,nbdc ~(poly,nbd,nbdc)/a 4 ~(poly,nbd,nbdc)/a ~(poly,nbd,nbdc)/a 4 \ "CCD channel spacing must be at least 4 (MOSIS rule #19.2)" active /* 19.3 + 19.4 + 19.5 */ /* guranteed by the CIF output generation */ /* 19.6 */ /* This first one check poly and electrode overhang */ edge4way bd space 2 nbd,poly,cap,el 0 0 \ "CCD channel overhang is missing (MOSIS rule #19.6)" active /* There is a problem with capacitor overhang, I have no way to do */ /* it now... */ /* MOSIS extension BCCD layout rule */ spacing nbdc poly,el 1 touching_illegal \ "CCD-diffusion contact spacing to poly must be at least 1 (MOSIS CCD rule)" edge4way nbd poly,el 1 bd 0 0 \ "Missing Buried CCD Difussion layer (MOSIS CCD rule)" implant /* ---------------------------------------------------------------- */ /* High-Voltage MOSFETs */ /* ---------------------------------------------------------------- */ /* These are DRC rules for AMI 1.5 micron process for high-voltage */ /* MOSFETs pi@isi.edu 10/01/92 */ /* */ /* ---------------------------------------------------------------- */ /* 20.1 */ /* Well spacing for different potential must be 12 lambda away now. */ /* These rules correspond to 1.1 + 1.2 rules */ /* width rule is as usual */ edge (~hnwell)/w hnwell 10 hnwell hnwell 10\ "High-Voltage N-Well width must be at least 10 (MOSIS rule #1.1)" edge (~hpwell)/w hpwell 10 hpwell hpwell 10\ "High-Voltage P-Well width must be at least 10 (MOSIS rule #1.1)" /* spacing rules are new */ edge hnwell space,pw,hpw 9 space,pw,hpw space,pw,hpw 9\ "High-Voltage N-Well spacing to N-Well must be at least 9 (MOSIS rule #1.2)" edge hpwell space,nw,hnw 9 space,nw,hnw space,nw,hnw 9\ "High-Voltage P-Well spacing to P-Well must be at least 9 (MOSIS rule #1.2)" edge hnwell space,pw,hpw,nw 12 space,pw,hpw,nw space,pw,hpw,nw 12\ "High-Voltage N-Well spacing must be at least 12 (MOSIS rule #20.1)" edge hpwell space,nw,hnw,pw 12 space,nw,hnw,pw space,nw,hnw,pw 12\ "High-Voltage P-Well spacing must be at least 12 (MOSIS rule #20.1)" /* 20.2 */ /* High-Voltage Active spacing must be at least 5 lambda away */ /* This rule corresponds to 2.2 rule */ #define allHVNActive hndiff,hndc/a,hnfet #define allHVPActive hpdiff,hpdc/a,hpfet edge4way ~(allHVDiff)/a allHVDiff 3 allHVDiff allHVDiff 3\ "High-Voltage Diffusion width must be at least 3 (MOSIS rule #2.1)" spacing allHVNActive allHVNActive 5 touching_ok \ "High-Voltage Diffusion spacing must be at least 5 (MOSIS rule #20.2)" spacing allHVPActive allHVPActive 5 touching_ok \ "High-Voltage Diffusion spacing must be at least 5 (MOSIS rule #20.2)" /* 20.3 */ /* High-Voltage transistors spacing to Well edge must be 7 lambda */ /* This rule corresponds to rule 2.3 */ /* without explicit well definition */ spacing hndiff,hndc/a hpdiff,hpdc/a 14 touching_illegal \ "P-type diffusion must be 14 away from N-type diffusion (MOSIS rule #20.3)" spacing hndiff,hndc/a allPDiff 12 touching_illegal \ "P-type diffusion must be 12 away from N-type diffusion (MOSIS rule #20.3+2.3)" spacing hpdiff,hpdc/a allNDiff 12 touching_illegal \ "P-type diffusion must be 12 away from N-type diffusion (MOSIS rule #20.3+2.3)" /* with explicit well definition */ spacing hndiff,hnfet,hndc/a hnwell 7 touching_illegal \ "HVN-diffusion and HVN-well must be separated by 7 (MOSIS rule #20.3)" spacing hpdiff,hpfet,hpdc/a hpwell 7 touching_illegal \ "HVP-diffusion and HVP-well must be separated by 7 (MOSIS rule #20.3)" spacing allNOhmic hpwell 3 touching_illegal \ "N-substrate diffusion and HVP-well must be separated by 3 (MOSIS rule #2.4+20.3)" spacing allPOhmic hnwell 3 touching_illegal \ "P-substrate diffusion and HVN-well must be separated by 3 (MOSIS rule #2.4+20.3)" /* 20.4 */ /* Poly1 must not be used as an transistor for high-voltage design */ /* guranteed by the composition rules */ /* 20.5 */ /* High-Voltage Active overlap of contact is now 2 lambda */ /* This rule corresponds to rule 6B.2 */ edge (~hndc)/a hndc/a 6 hndc/a hndc/a 6\ "High-Voltage Diffusion contact width must be at least 6 (MOSIS rule #20.5)" edge (~hpdc)/a hpdc/a 6 hpdc/a hpdc/a 6\ "High-Voltage Diffusion contact width must be at least 6 (MOSIS rule #20.5)" /* 20.6 */ /* High-Voltage transistor channel length must be at least 4 lambda */ edge hpdiff,hpdc/a hpfet 4 hpfet 0 0 \ "High-Voltage transistor must be at least 4 units long (MOSIS rule #20.6)" edge hndiff,hndc/a hnfet 4 hnfet 0 0 \ "High-Voltage transistor must be at least 4 units long (MOSIS rule #20.6)" /* ---------------------------------------------------------------- */ /* overlapping rules */ exact_overlap m3c,m2c,ndc,pdc,pc,psc,nsc,ec,capc,clc,emc,pbc,hndc,hpdc,hnsc,hpsc no_overlap pfet,nfet pfet,nfet no_overlap epfet,enfet epfet,enfet no_overlap pffet,nffet pffet,nffet no_overlap hpfet,hnfet hpfet,hnfet end extract #ifndef OLD_EXTRACT_STYLE #include "scmosExt.tech.in" #else /* In the following, MOSIS provides 9 extraction styles as follows: SCNA20(ORB) - ORBIT 2.0 micron low-noise analog N-well CMOS/BJT process. *default* SCPE20(ORB) - ORBIT 2.0 micron P-well CMOS/Bulk process. SCNA16(AMI) - AMI 1.6 micron N-well CMOS/Junction-isolated BJT process. SCN12LC(HP) - HP CMOS34 1.2 micron N-well CMOS/Bulk process with linear capacitor option. SCNE12(ORB) - ORBIT 1.2 micron 2 poly N/P-well CMOS process. SCN10(MOT) - MOTOROLA 1.0 micron N-well/P-epi CMOS process. * Not Available at this moment * SCN08(HP) - HP CMOS26B 1.0 micron N-well CMOS/Bulk process. SCN08(IBM) - IBM 0.8 micron N-well CMOS/Bulk process. * Not Available at this moment * Whenever it is available, measured data on MOSIS test structures is used. Data is obtained from a representitive run (usually the latest run at the time). If not available, typical (or nominal) data from vendor wafer specification is used if not specifically noted. */ /* Have to redefine allMetal1 to make it pure metal line here... */ #undef allMetal1 #define allMetal1 m1,m2c/m1 #ifdef STANDARD style SCNA20(ORB) /* The following data is obtained from MOSIS run 'n34o' */ /* Last modified by pi@isi.edu, 9/29/93 */ /* Define plane order first */ #ifdef V5 planeorder well 0 planeorder implant 1 planeorder active 2 planeorder metal1 3 planeorder metal2 4 planeorder metal3 5 planeorder oxide 6 #endif cscale 1 lambda 100 step 100 /* No parallel wire coupling capacitances */ sidehalo 0 /* Sheet resistance (in milliohms per square) */ resist ndiff,nsd,ndc/a,nsc/a 27260 resist pdiff,psd,pdc/a,psc/a 59550 resist allPoly 23430 resist allPoly2 19690 resist em,emc/a 27260 resist pbase,pbc/a 2000000 resist metal1,m2c/metal1 52 resist metal2,pad 26 resist nwell 2505830 /* Contact resistance (in milliohms per square) */ contact pc/a 4 11000 contact ec/a,capc/a 4 9000 contact ndc/a,nsc/a 4 18710 contact pdc/a,psc/a 4 100560 /* Area parasitic capacitance to substrate (in attofarads per lambda square) [ 1 lambda = 1.0 micron ---> multiplication factor 1.0 ] NOTE: Since most of the simulation tools have already included the gate-oxide capacitance, it is NOT extracted here. If you need it explictly, remove the following comment. */ areacap poly,pc/a 39 areacap metal1,pad,m2c/metal1 24 areacap metal2 19 /* areacap ndiff,ndc/a 220 areacap pdiff,pdc/a 270 */ areacap cc/a,cap 39 areacap poly2,ec/a 50 /* Inter-layer capacitance */ overlap metal1 pdiff,ndiff,psd,nsd 47 overlap metal2 pdiff,ndiff,psd,nsd 22 metal1 overlap metal1 poly 30 overlap metal2 poly 19 metal1 overlap metal2 metal1 45 overlap metal1 poly2 40 /* Perimeter parasitic capacitances (in attofarads per lambda) [ 1 lambda = 1.0 micron ---> multiplication factor 1.0 ] */ /* perimc ndiff,ndc/a space,pwell 559 perimc pdiff,pdc/a space,nwell 402 */ perimc poly,pc/a space,pwell,nwell 80 /* Active devices: N-Well process */ fet pfet pdiff,pdc,pffet 2 pfet Vdd! nwell 0 0 fet nfet ndiff,ndc,nffet 2 nfet GND! pwell 0 0 fet epfet pdiff,pdc,pffet 2 epfet Vdd! 0 0 fet enfet ndiff,ndc,nffet 2 enfet GND! 0 0 /* Kludge for MOS capacitance extraction, where source and drain are connected together */ fet pfet pdiff,pdc,pffet 1 pfet Vdd! nwell 0 0 fet nfet ndiff,ndc,nffet 1 nfet GND! pwell 0 0 /* Electrode capacitance extraction */ device capacitor None cap,capc/a poly,pc 120 735 /* DRAM capacitance extraction */ device capacitor None wcap ndiff,ndc 300 0 /* bipolar NPN extraction */ device bjt npn emit,emc/a pbase,pbc/a nwell style SCPE20(ORB) /* The following data is obtained from MOSIS run 'n35s', 6/93 */ /* Last modified by pi@isi.edu, 9/29/93 */ cscale 1 lambda 100 step 100 /* No parallel wire coupling capacitances */ sidehalo 0 /* Define plane order first */ #ifdef V5 planeorder well 0 planeorder implant 1 planeorder active 2 planeorder metal1 3 planeorder metal2 4 planeorder metal3 5 planeorder oxide 6 #endif /* Sheet resistance (in milliohms per square) */ resist ndiff,nsd,ndc/a,nsc/a 26670 resist pdiff,psd,pdc/a,psc/a 72860 resist allPoly 23860 resist allPoly2 18540 resist metal1,m2c/metal1 49 resist metal2,pad 26 resist pwell 2128280 /* Contact resistance (in milliohm per contact) */ contact pc/a 4 12800 contact ec/a,capc/a 4 8420 contact ndc/a,nsc/a 4 36660 contact pdc/a,psc/a 4 56300 contact m2c/m1 5 30 /* Area parasitic capacitance to substrate (in attofarads per lambda square) [ 1 lambda = 1.0 micron ---> multiplication factor 1.0 ] NOTE: Since most of the simulation tools have already included the gate-oxide capacitance, it is NOT extracted here. If you need it explictly, remove the following comment. */ areacap poly,pc/a 57 areacap allMetal1,DiffMetal,HVDiffMetal 41 areacap PolyMetal,BiMetal,CCDMetal 41 areacap allMetal2 21 /* areacap ndiff,ndc/a 398 areacap pdiff,pdc/a 230 */ /* Inter-layer capacitance */ overlap metal1 pdiff,ndiff,psd,nsd 36 overlap metal2 pdiff,ndiff,psd,nsd 16 metal1 overlap metal1 poly 33 overlap metal2 poly 15 metal1 overlap metal2 metal1 29 overlap metal1 poly2,cap 33 /* Perimeter parasitic capacitances (in attofarads per lambda) [ 1 lambda = 1.0 micron ---> multiplication factor 1.0 ] */ /* perimc ndiff,ndc/a space,pwell 423 perimc pdiff,pdc/a space,nwell 85 */ perimc poly,pc/a space,pwell,nwell 168 /* Active devices: P-Well process */ fet pfet pdiff,pdc 2 pfet Vdd! nwell 0 0 fet nfet ndiff,ndc 2 nfet GND! pwell 0 0 style SCNA16(AMI) /* The following data is obtained from MOSIS run 'n34l', 6/93 */ /* Last modified by pi@isi.edu, 9/29/93 */ cscale 1 lambda 80 step 100 /* No parallel wire coupling capacitances */ sidehalo 0 /* Define plane order first */ #ifdef V5 planeorder well 0 planeorder implant 1 planeorder active 2 planeorder metal1 3 planeorder metal2 4 planeorder metal3 5 planeorder oxide 6 #endif /* Sheet resistance (in milliohms per square) */ resist ndiff,nsd,ndc/a,nsc/a 51680 resist pdiff,psd,pdc/a,psc/a 74800 resist allPoly 34780 resist allPoly2 22400 resist allMetal1 48 resist allMetal2 28 resist nwell 1446400 /* Contact resistance (in milliohm per contact) */ contact pc 4 61560 contact ec 4 12010 contact ndc,nsc 4 45780 contact pdc,psc 4 32310 contact m2c 5 37570 /* Area parasitic capacitances (in attofarads per lambda square) [ 1 lambda = 0.8 micron ---> multiplication factor 0.64 ] NOTE: Since most of the simulation tools have already included the gate-oxide capacitance, it is NOT extracted here. If you need it explictly, remove the following comment. */ /* areacap nfet 709 */ /* areacap pfet 669 */ areacap poly,pc/a 22 areacap allMetal1,DiffMetal,HVDiffMetal 15 areacap PolyMetal,BiMetal,CCDMetal 15 areacap allMetal2 10 /* Inter-layer capacitance */ overlap allMetal1 ndiff,nsd 27 overlap allMetal1 pdiff,psd 27 overlap allMetal2 pdiff,psd 12 metal1 overlap allMetal1 allPoly 25 overlap allMetal1 allP2 25 overlap allMetal2 allPoly 11 metal1 overlap metal2 metal1 23 /* Junction capacitance */ /* overlap ndiff,ndc/a space,pwell 172 overlap pdiff,pdc/a space,nwell 200 */ /* Perimeter parasitic capacitances (in attofarads per lambda) [ 1 lambda = 0.8 micron ---> multiplication factor 0.8 ] */ /* perimc ndiff,ndc/a space,allWell 6 perimc pdiff,pdc/a space,allWell 68 */ /* Active devices: N-Well process, */ fet pfet pdiff,pdc 2 pfet Vdd! nwell 0 0 fet nfet ndiff,ndc 2 nfet GND! pwell 0 0 style SCNE12(ORB) /* The following data is obtained from MOSIS run 'n37d', 7/93 */ /* Last modified by pi@isi.edu, 9/29/93 */ cscale 1 lambda 60 step 100 /* No parallel wire coupling capacitances */ sidehalo 0 /* Define plane order first */ #ifdef V5 planeorder well 0 planeorder implant 1 planeorder active 2 planeorder metal1 3 planeorder metal2 4 planeorder metal3 5 planeorder oxide 6 #endif /* Sheet resistances (in milliohms per square) */ resist ndiff,nsd,ndc/a,nsc/a 43180 resist pdiff,psd,pdc/a,psc/a 79770 resist allPoly 22160 resist allPoly2 21140 resist allMetal1 51 resist allMetal2 26 resist nwell 1195000 /* Contact resistances (in milliohm per contact) */ contact pc 4 13230 contact ec 4 13510 contact ndc,nsc 4 56490 contact pdc,psc 4 181400 contact m2c 5 43330 /* Area parasitic capacitances (in attofarads per lambda square) [ 1 lambda = 0.6 micron ---> multiplication factor 0.36 ] NOTE: Since most of the simulation tools have already included the gate-oxide capacitance, it is NOT extracted here. If you need it explictly, remove the following comment. */ /* areacap nfet 454 */ /* areacap pfet 368 */ areacap poly,pc/a 29 areacap allMetal1,DiffMetal,HVDiffMetal 16 areacap PolyMetal,BiMetal,CCDMetal 16 areacap allMetal2 10 overlap allMetal1 ndiff,ndc/a 22 overlap allMetal1 allPoly 19 overlap allMetal1 allP2 21 overlap allMetal2 ndiff,ndc/a 8 overlap allMetal2 allPoly 7 overlap metal2 metal1 12 /* Junction capacitance */ overlap ndiff,ndc/a space,pwell 185 overlap pdiff,pdc/a space,nwell 148 /* Perimeter parasitic capacitances (in attofarads per lambda) [ 1 lambda = 0.6 micron ---> multiplication factor 0.6 ] */ perimc allMetal1 space,allWell 41 perimc allMetal2 space,allWell 42 /* Junction capacitances */ /* perimc ndiff,ndc/a space,pwell 236 perimc pdiff,pdc/a space,nwell 147 */ /* No measurements for this run, but leave here for future... sideoverlap allMetal1 space,allWell PNplus 60 sideoverlap allMetal2 space,allWell allPoly 60 sideoverlap allMetal2 space,allWell PNplus 57 sideoverlap allMetal2 space,allWell allPoly 57 sideoverlap allMetal2 space,allWell allMetal1 64 */ /* Nwell process, so PMOS has "nwell" defined for analog designs... */ fet pfet pdiff,pdc 2 pfet Vdd! nwell 0 0 fet nfet ndiff,ndc 2 nfet GND! pwell 0 0 #endif /* STANDARD */ #ifdef TIGHTMETAL style SCN12LC(HP) /* The following data is obtained from MOSIS run 'n36y', 7/93 */ /* Last modified by pi@isi.edu, 9/29/93 */ cscale 1 lambda 60 step 100 /* No parallel wire coupling capacitances */ sidehalo 0 /* Define plane order first */ #ifdef V5 planeorder well 0 planeorder implant 1 planeorder active 2 planeorder metal1 3 planeorder metal2 4 planeorder metal3 5 planeorder oxide 6 #endif /* Sheet resistance (in milliohms per square) */ resist ndiff,nnd,ndc/a,nsc/a 74630 resist pdiff,ppd,pdc/a,psc/a 109590 resist poly,pc/a,pfet,nfet 26620 resist allMetal1 60 resist allMetal2 39 resist nwell 1500000 /* Contact resistance (in milliohm per contact) */ contact ndc 4 77000 contact pdc 4 44260 contact pc 4 16210 contact m2c 5 86560 /* Area parasitic capacitances (in attofarads per lambda square) [ 1 lambda = 0.6 micron ---> multiplication factor 0.36 ] NOTE: Since most of the simulation tools have already included the gate-oxide capacitance, it is NOT extracted here. If you need it explictly, remove the following comment. */ /* areacap nfet 556 */ /* areacap pfet 489 */ areacap poly,pc/a 22 areacap allMetal1,DiffMetal,HVDiffMetal 14 areacap PolyMetal,BiMetal,CCDMetal 14 areacap allMetal2 9 /* Inter-layer capacitance */ overlap allMetal1 allPoly 24 overlap allMetal2 allPoly 7 metal1 overlap metal2 metal1 14 /* Junction capacitance */ /* overlap ndiff,ndc/a space,pwell 106 overlap pdiff,pdc/a space,nwell 183 */ /* Perimeter parasitic capacitances (in attofarads per lambda) [ 1 lambda = 0.6 micron ---> multiplication factor 0.6 ] */ /* perimc nfet ndiff 90 */ /* perimc pfet pdiff 817 */ /* Junction capacitances */ /* perimc ndiff,ndc/a space,allWell 102 perimc pdiff,pdc/a space,allWell 2 */ /* Active devices: Nwell process, so PMOS has "nwell" defined for analog designs... */ fet pfet pdiff,pdc 2 pfet Vdd! nwell 0 0 fet nfet ndiff,ndc 2 nfet GND! pwell 0 0 /* Kludge for DRAM capacitance extraction */ fet wcap ndiff,ndc 1 wcap GND! 300 0 /* These stuff are experimental..... fake npn: fet emit,emc/a pbase 1 d1np XSLLU! nwell 0 0 fet fpb nwell 1 d2pn YSLLU! col,clc 0 0 */ /* saturation :: R = V (5V) / Idss fetresist nfet saturation 12000 fetresist pfet saturation 28000 fetresist enfet saturation 12000 fetresist epfet saturation 28000 I am not sure how to do this yet, so I give the same value as saturation! fetresist nfet linear 12000 fetresist pfet linear 28000 fetresist enfet linear 12000 fetresist epfet linear 28000 */ style SCN08(HP) /* The following data is obtained from MOSIS run 'n33h', 7/93 */ /* Last modified by pi@isi.edu, 9/29/93 */ cscale 1 lambda 50 step 100 /* Parallel wire coupling capacitance enabled */ sidehalo 8 /* Define plane order first */ #ifdef V5 planeorder well 0 planeorder implant 1 planeorder active 2 planeorder metal1 3 planeorder metal2 4 planeorder metal3 5 planeorder oxide 6 #endif /* Sheet resistance (in milliohms per square) */ resist ndiff,nsd,ndc/a,nsc/a 2280 resist pdiff,psd,pdc/a,psc/a 1990 resist poly 3480 resist allMetal1 67 resist allMetal2 65 resist allMetal3 29 resist nwell 1265560 /* Contact resistance (in milliohm per contact) */ contact pc 4 1680 contact ndc,pdc,nsc,psc 4 1100 contact m2c 5 305 contact m3c 5 259 /* Area parasitic capacitances (in attofarads per lambda square) [ 1 lambda = 0.5 micron ---> multiplication factor 0.25 ] NOTE: Since most of the simulation tools have already included the gate-oxide capacitance, it is NOT extracted here. If you need it explictly, remove the following comment. */ /* areacap nfet 457 */ /* areacap pfet 403 */ areacap poly,pc/a 16 areacap allMetal1,DiffMetal,HVDiffMetal 9 areacap PolyMetal,BiMetal,CCDMetal 9 areacap allMetal2 5 areacap allMetal3 4 /* Inter-layer capacitance */ overlap allMetal1 PNplus 13 overlap allMetal1 allPoly 13 overlap allMetal2 PNplus 4 overlap allMetal2 allPoly 4 overlap allMetal2 allMetal1 6 overlap allMetal3 PNplus 2 overlap allMetal3 allPoly 2 overlap allMetal3 allMetal1 3 overlap allMetal3 allMetal2 7 /* Junction capacitance */ overlap ndiff,ndc/a space,pwell 27 overlap pdiff,pdc/a space,nwell 148 /* Perimeter parasitic capacitance (in attofarads per lambda) [ 1 lambda = 0.5 micron ---> multiplication factor 0.5 ] */ perimc allMetal1 space,allWell 43 perimc allMetal2 space,allWell 36 perimc allMetal3 space,allWell 36 sideoverlap allMetal1 space,allWell allPoly 14 sideoverlap allMetal2 space,allWell allPoly 5 /* no such data for m2-to-m1, use data from specification file */ sideoverlap allMetal2 space,allWell allMetal1 13 sideoverlap allMetal3 space,allWell allPoly 1 sideoverlap allMetal3 space,allWell allMetal1 4 sideoverlap allMetal3 space,allWell allMetal2 13 /* Active devices: N-well process */ fet pfet pdiff,pdc 2 pfet Vdd! nwell 0 0 fet nfet ndiff,ndc 2 nfet GND! pwell 0 0 #endif /* TIGHTMETAL */ #ifdef IBMTECH style SCN08(IBM) /* The following data is obtained from MOSIS run 'n42s', 1/94 */ /* Last modified by pi@isi.edu, 6/27/94 */ cscale 1 lambda 40 step 100 /* Parallel wire coupling capacitance disabled */ sidehalo 0 /* Define plane order first */ #ifdef V5 planeorder well 0 planeorder implant 1 planeorder active 2 planeorder metal1 3 planeorder metal2 4 planeorder metal3 5 planeorder oxide 6 #endif /* Sheet resistance (in milliohms per square) */ resist ndiff,nsd,ndc/a,nsc/a 3300 resist pdiff,psd,pdc/a,psc/a 3180 resist poly 3630 resist allMetal1 43 resist allMetal2 36 resist allMetal3 36 /* not monitored on PCM, use specification value */ resist nwell 520000 /* Contact resistance (in milliohm per contact) */ contact ndc,nsc 4 2530 contact pc 4 7510 contact pdc,psc 4 2160 contact m2c 5 330 contact m3c 5 292 /* Area parasitic capacitances (in attofarads per lambda square) [ 1 lambda = 0.4 micron ---> multiplication factor 0.16 ] */ #endif /* IBMTECH */ #ifdef SUBMICRON style SCN08(HP26G) /* The following data is obtained from MOSIS run 'n48r', 10/94 */ /* Last modified by pi@isi.edu, 11/02/94 */ cscale 1 lambda 40 step 100 /* Parallel wire coupling capacitance enabled */ sidehalo 8 /* Define plane order first */ #ifdef V5 planeorder well 0 planeorder implant 1 planeorder active 2 planeorder metal1 3 planeorder metal2 4 planeorder metal3 5 planeorder oxide 6 #endif /* Sheet resistance (in milliohms per square) */ resist ndiff,nsd,ndc/a,nsc/a 2375 resist pdiff,psd,pdc/a,psc/a 2000 resist allPoly 2350 resist allMetal1 70 resist allMetal2 67 resist allMetal3 30 resist nwell 1265000 /* Contact resistance (in milliohm per contact) */ contact pc 4 1250 contact ndc,nsc 4 1300 contact pdc,psc 4 1125 contact m2c 5 430 contact m3c 5 300 /* The following are 10 types of capacitance extracted: 1. poly to substrate. 2. metal1 to substrate. 3. metal1 to poly. 4. metal2 to substrate. 5. metal2 to poly. 6. metal2 to metal1. 7. metal3 to substrate. 8. metal3 to poly. 9. metal3 to metal1. 10. metal3 to metal2. NOTE: Since most of the simulation tools have already included the gate-oxide capacitance, it is NOT extracted here. If you need it explictly, remove the following comment. */ /* areacap nfet 334 */ /* areacap pfet 315 */ /* Type 1,2,4,7 (to substrate) */ /* Area parasitic capacitances (in attofarads per lambda square) [ 1 lambda = 0.4 micron ---> multiplication factor 0.16 ] */ areacap poly,pc/a 13 areacap allMetal1,DiffMetal,HVDiffMetal 6 areacap PolyMetal,BiMetal,CCDMetal 6 areacap allMetal2 3 areacap allMetal3 2 /* Perimeter parasitic capacitance (in attofarads per lambda) [ 1 lambda = 0.4 micron ---> multiplication factor 0.4 ] */ perimc poly,pc/a ~(poly,pc/a) 19 perimc allMetal1 ~(allMetal1) 20 perimc allMetal2 ~(allMetal2) 16 perimc allMetal3 ~(allMetal3) 14 /* Inter-layer capacitance, type 3,5,6,8,9,10 */ /* Area parasitic capacitances (in attofarads per lambda square) [ 1 lambda = 0.4 micron ---> multiplication factor 0.16 ] */ overlap allMetal1 allPoly 9 overlap allMetal2 allPoly 3 overlap allMetal2 allMetal1 5 overlap allMetal3 allPoly 2 overlap allMetal3 allMetal1 3 overlap allMetal3 allMetal2 5 /* Perimeter parasitic capacitance (in attofarads per lambda) [ 1 lambda = 0.4 micron ---> multiplication factor 0.4 ] */ sideoverlap allMetal1 space,allWell allPoly 23 sideoverlap allMetal2 space,allWell allPoly 17 sideoverlap allMetal2 space,allWell allMetal1 19 sideoverlap allMetal3 space,allWell allPoly 15 sideoverlap allMetal3 space,allWell allMetal1 17 sideoverlap allMetal3 space,allWell allMetal2 21 /* Cross-couple capacitance */ /* Perimeter parasitic capacitance (in attofarads per lambda) [ 1 lambda = 0.4 micron ---> multiplication factor 0.4 ] */ sidewall allP ~(allP) ~(allP) allP 11 sidewall allMetal1 ~(allMetal1) ~(allMetal1) allMetal1 24 sidewall allMetal2 ~(allMetal2) ~(allMetal2) allMetal2 27 sidewall allMetal3 ~(allMetal3) ~(allMetal3) allMetal3 39 /* Active devices: N-well process */ fet pfet pdiff,pdc 2 pfet Vdd! nwell 0 0 fet nfet ndiff,ndc 2 nfet GND! pwell 0 0 style SCN06(HP14B) /* Not yet.... */ /* Last modified by pi@isi.edu, 03/10/95 */ cscale 1 lambda 30 step 100 /* Parallel wire coupling capacitance enabled */ sidehalo 8 /* Define plane order first */ #ifdef V5 planeorder well 0 planeorder implant 1 planeorder active 2 planeorder metal1 3 planeorder metal2 4 planeorder metal3 5 planeorder oxide 6 #endif /* Sheet resistance (in milliohms per square) */ resist ndiff,nsd,ndc/a,nsc/a 2375 resist pdiff,psd,pdc/a,psc/a 2000 resist allPoly 2350 resist allMetal1 70 resist allMetal2 67 resist allMetal3 30 resist nwell 1265000 /* Contact resistance (in milliohm per contact) */ contact pc 4 1250 contact ndc,nsc 4 1300 contact pdc,psc 4 1125 contact m2c 5 430 contact m3c 5 300 /* The following are 10 types of capacitance extracted: 1. poly to substrate. 2. metal1 to substrate. 3. metal1 to poly. 4. metal2 to substrate. 5. metal2 to poly. 6. metal2 to metal1. 7. metal3 to substrate. 8. metal3 to poly. 9. metal3 to metal1. 10. metal3 to metal2. NOTE: Since most of the simulation tools have already included the gate-oxide capacitance, it is NOT extracted here. If you need it explictly, remove the following comment. */ /* areacap nfet 334 */ /* areacap pfet 315 */ /* Type 1,2,4,7 (to substrate) */ /* Area parasitic capacitances (in attofarads per lambda square) [ 1 lambda = 0.3 micron ---> multiplication factor 0.09 ] */ areacap poly,pc/a 7 areacap allMetal1,DiffMetal,HVDiffMetal 3 areacap PolyMetal,BiMetal,CCDMetal 3 areacap allMetal2 1 areacap allMetal3 1 /* Perimeter parasitic capacitance (in attofarads per lambda) [ 1 lambda = 0.3 micron ---> multiplication factor 0.3 ] */ perimc poly,pc/a ~(poly,pc/a) 14 perimc allMetal1 ~(allMetal1) 15 perimc allMetal2 ~(allMetal2) 12 perimc allMetal3 ~(allMetal3) 10 /* Inter-layer capacitance, type 3,5,6,8,9,10 */ /* Area parasitic capacitances (in attofarads per lambda square) [ 1 lambda = 0.3 micron ---> multiplication factor 0.09 ] */ overlap allMetal1 allPoly 5 overlap allMetal2 allPoly 2 overlap allMetal2 allMetal1 3 overlap allMetal3 allPoly 1 overlap allMetal3 allMetal1 1 overlap allMetal3 allMetal2 3 /* Perimeter parasitic capacitance (in attofarads per lambda) [ 1 lambda = 0.3 micron ---> multiplication factor 0.3 ] */ sideoverlap allMetal1 space,allWell allPoly 17 sideoverlap allMetal2 space,allWell allPoly 14 sideoverlap allMetal2 space,allWell allMetal1 15 sideoverlap allMetal3 space,allWell allPoly 11 sideoverlap allMetal3 space,allWell allMetal1 13 sideoverlap allMetal3 space,allWell allMetal2 16 /* Cross-couple capacitance */ /* Perimeter parasitic capacitance (in attofarads per lambda) [ 1 lambda = 0.3 micron ---> multiplication factor 0.3 ] */ sidewall allP ~(allP) ~(allP) allP 9 sidewall allMetal1 ~(allMetal1) ~(allMetal1) allMetal1 19 sidewall allMetal2 ~(allMetal2) ~(allMetal2) allMetal2 21 sidewall allMetal3 ~(allMetal3) ~(allMetal3) allMetal3 31 /* Active devices: N-well process */ fet pfet pdiff,pdc 2 pfet Vdd! nwell 0 0 fet nfet ndiff,ndc 2 nfet GND! pwell 0 0 #endif /* SUBMICRON */ #endif /* OLD_EXTRACT_STYLE */ end wiring contact pdcontact 4 pdiff 0 metal1 0 contact ndcontact 4 ndiff 0 metal1 0 contact pcontact 4 poly 0 metal1 0 contact ec 6 poly2 0 metal1 0 contact m2contact 4 metal1 0 metal2 0 contact m3contact 5 metal2 0 metal3 0 end router layer1 metal1 3 allMetal1 3 layer2 metal2 3 allMetal2 4 allPoly,allDiff 1 contacts m2contact 4 gridspacing 8 end plowing fixed allFet,glass,pad covered allFet drag allFet end plot /* based on Jeffrey C. Gealow's (jgealow@mtl.mit.edu) contribution */ style colorversatec ndiff,ndc yellow \ 5555 AAAA 5555 AAAA \ 5555 AAAA 5555 AAAA \ 5555 AAAA 5555 AAAA \ 5555 AAAA 5555 AAAA ndiff,ndc cyan \ 0000 5555 0000 5555 \ 0000 5555 0000 5555 \ 0000 5555 0000 5555 \ 0000 5555 0000 5555 nsd,nsc,col,clc yellow \ 1515 2A2A 5151 A2A2 \ 1515 2A2A 5151 A2A2 \ 1515 2A2A 5151 A2A2 \ 1515 2A2A 5151 A2A2 nsd,nsc,col,clc cyan \ 0000 1515 0000 5151 \ 0000 1515 0000 5151 \ 0000 1515 0000 5151 \ 0000 1515 0000 5151 pdiff,pdc yellow \ 5555 AAAA 5555 AAAA \ 5555 AAAA 5555 AAAA \ 5555 AAAA 5555 AAAA \ 5555 AAAA 5555 AAAA pdiff,pdc cyan \ 0000 5555 0000 5555 \ 0000 5555 0000 5555 \ 0000 5555 0000 5555 \ 0000 5555 0000 5555 pdiff,pdc magenta \ AAAA 0000 AAAA 0000 \ AAAA 0000 AAAA 0000 \ AAAA 0000 AAAA 0000 \ AAAA 0000 AAAA 0000 psd,psc yellow \ 1515 2A2A 5151 A2A2 \ 1515 2A2A 5151 A2A2 \ 1515 2A2A 5151 A2A2 \ 1515 2A2A 5151 A2A2 psd,psc cyan \ 0000 1515 0000 5151 \ 0000 1515 0000 5151 \ 0000 1515 0000 5151 \ 0000 1515 0000 5151 psd,psc magenta \ 2A2A 0000 A2A2 0000 \ 2A2A 0000 A2A2 0000 \ 2A2A 0000 A2A2 0000 \ 2A2A 0000 A2A2 0000 poly,pc/a magenta \ 5555 AAAA 5555 AAAA \ 5555 AAAA 5555 AAAA \ 5555 AAAA 5555 AAAA \ 5555 AAAA 5555 AAAA poly2,ec/a yellow \ FFFF FFFF FFFF FFFF \ FFFF FFFF FFFF FFFF \ FFFF FFFF FFFF FFFF \ FFFF FFFF FFFF FFFF nfet yellow \ 0505 8282 1414 0A0A \ 5050 2828 4141 A0A0 \ 0505 8282 1414 0A0A \ 5050 2828 4141 A0A0 nfet cyan \ 0000 0505 0000 1414 \ 0000 5050 0000 4141 \ 0000 0505 0000 1414 \ 0000 5050 0000 4141 nfet magenta \ 5050 2828 4141 A0A0 \ 0505 8282 1414 0A0A \ 5050 2828 4141 A0A0 \ 0505 8282 1414 0A0A enfet yellow \ BABA 7575 EAEA D5D5 \ ABAB 5757 AEAE 5D5D \ BABA 7575 EAEA D5D5 \ ABAB 5757 AEAE 5D5D enfet cyan \ 4141 0A0A 0505 2828 \ 1414 A0A0 5050 8282 \ 4141 0A0A 0505 2828 \ 1414 A0A0 5050 8282 nffet yellow \ 8E8E 0707 8B8B D5D5 \ E8E8 7070 B8B8 5D5D \ 8E8E 0707 8B8B D5D5 \ E8E8 7070 B8B8 5D5D nffet cyan \ 0101 0808 1414 2828 \ 1010 8080 4141 8282 \ 0101 0808 1414 2828 \ 1010 8080 4141 8282 nffet magenta \ 5050 A0A0 4040 0202 \ 0505 0A0A 0404 2020 \ 5050 A0A0 4040 0202 \ 0505 0A0A 0404 2020 pfet yellow \ 6363 A0A0 5050 2828 \ 3636 0A0A 0505 8282 \ 6363 A0A0 5050 2828 \ 3636 0A0A 0505 8282 pfet cyan \ 0000 5151 0000 5454 \ 0000 1515 0000 1515 \ 0000 5151 0000 5454 \ 0000 1515 0000 1515 pfet magenta \ 9494 0A0A 2525 8282 \ 4949 A0A0 5252 2828 \ 9494 0A0A 2525 8282 \ 4949 A0A0 5252 2828 epfet yellow \ BCBC 4F4F 2F2F D3D3 \ CBCB F4F4 F2F2 3D3D \ BCBC 4F4F 2F2F D3D3 \ CBCB F4F4 F2F2 3D3D epfet cyan \ 0000 A0A0 0000 2828 \ 0000 0A0A 0000 8282 \ 0000 A0A0 0000 2828 \ 0000 0A0A 0000 8282 epfet magenta \ 4141 0000 5050 0000 \ 1414 0000 0505 0000 \ 4141 0000 5050 0000 \ 1414 0000 0505 0000 pffet yellow \ 7B7B F0F0 F0F0 E9E9 \ B7B7 0F0F 0F0F 9E9E \ 7B7B F0F0 F0F0 E9E9 \ B7B7 0F0F 0F0F 9E9E pffet cyan \ 0000 0101 0000 1414 \ 0000 1010 0000 4141 \ 0000 0101 0000 1414 \ 0000 1010 0000 4141 pffet magenta \ 8484 0A0A 2525 8282 \ 4848 A0A0 5252 2828 \ 8484 0A0A 2525 8282 \ 4848 A0A0 5252 2828 cap,cc/a yellow \ 3E3E 7777 E3E3 C1C1 \ E3E3 7777 3E3E 1C1C \ 3E3E 7777 E3E3 C1C1 \ E3E3 7777 3E3E 1C1C cap,cc/a magenta \ 4141 8888 1414 2A2A \ 1414 8888 4141 A2A2 \ 4141 8888 1414 2A2A \ 1414 8888 4141 A2A2 allMetal1 cyan \ AAAA 0000 AAAA 0000 \ AAAA 0000 AAAA 0000 \ AAAA 0000 AAAA 0000 \ AAAA 0000 AAAA 0000 allMetal2 cyan \ 0000 1111 0000 4444 \ 0000 1111 0000 4444 \ 0000 1111 0000 4444 \ 0000 1111 0000 4444 allMetal2 magenta \ 0000 4444 0000 1111 \ 0000 4444 0000 1111 \ 0000 4444 0000 1111 \ 0000 4444 0000 1111 m2c/m1 black \ 0000 6666 6666 0000 \ 0000 9999 9999 0000 \ 0000 6666 6666 0000 \ 0000 9999 9999 0000 pad,glass black \ 0300 0700 0E00 1C00 \ 3800 7000 E000 C000 \ 00C0 00E0 0070 0038 \ 001C 000E 0007 0003 nwell yellow \ 0800 1000 2000 4000 \ 8000 0001 0002 0004 \ 0008 0010 0020 0040 \ 0080 0010 0200 0400 nwell cyan \ 1000 2000 4000 8000 \ 0001 0002 0004 0008 \ 0010 0020 0040 0080 \ 0100 0200 0400 0800 pwell yellow \ 1000 0400 0400 0100 \ 0100 0040 0040 0010 \ 0010 0004 0004 0001 \ 0001 4000 4000 1000 pwell cyan \ 0000 0800 0000 0200 \ 0000 0080 0000 0020 \ 0000 0008 0000 0002 \ 0000 8000 0000 2000 pwell magenta \ 0800 0000 0200 0000 \ 0080 0000 0020 0000 \ 0008 0000 0002 0000 \ 8000 0000 2000 0000 bd yellow \ 4444 8888 4444 8888 \ 4444 8888 4444 8888 \ 4444 8888 4444 8888 \ 4444 8888 4444 8888 bd cyan \ 0000 4444 0000 4444 \ 0000 4444 0000 4444 \ 0000 4444 0000 4444 \ 0000 4444 0000 4444 bd magenta \ 8888 0000 8888 0000 \ 8888 0000 8888 0000 \ 8888 0000 8888 0000 \ 8888 0000 8888 0000 nbd,nbdc yellow \ 5555 AAAA 5555 AAAA \ 5555 AAAA 5555 AAAA \ 5555 AAAA 5555 AAAA \ 5555 AAAA 5555 AAAA nbd,nbdc cyan \ 0000 5555 0000 5555 \ 0000 5555 0000 5555 \ 0000 5555 0000 5555 \ 0000 5555 0000 5555 nbd,nbdc magenta \ 8888 0000 8888 0000 \ 8888 0000 8888 0000 \ 8888 0000 8888 0000 \ 8888 0000 8888 0000 em,emc yellow \ 4444 8888 4444 8888 \ 4444 8888 4444 8888 \ 4444 8888 4444 8888 \ 4444 8888 4444 8888 em,emc cyan \ 0000 4444 0000 4444 \ 0000 4444 0000 4444 \ 0000 4444 0000 4444 \ 0000 4444 0000 4444 pbase,pbc yellow \ 5555 AAAA 0000 0000 \ 5555 AAAA 0000 0000 \ 5555 AAAA 0000 0000 \ 5555 AAAA 0000 0000 pbase,pbc cyan \ 0000 5555 0000 0000 \ 0000 5555 0000 0000 \ 0000 5555 0000 0000 \ 0000 5555 0000 0000 pbase,pbc magenta \ AAAA 0000 0000 0000 \ AAAA 0000 0000 0000 \ AAAA 0000 0000 0000 \ AAAA 0000 0000 0000 allMetal3 black \ 0100 0000 0000 0000 \ 1010 0000 0000 0000 \ 0001 0000 0000 0000 \ 1010 0000 0000 0000 allMetal3 cyan \ 0280 0000 0820 0000 \ 2008 0000 8002 0000 \ 8002 0000 2008 0000 \ 0820 0000 0280 0000 allMetal3 magenta \ 0100 06C0 0440 1830 \ 1010 600C 4004 8003 \ 0001 C006 4004 3018 \ 1010 0C60 0440 0380 m3c/m2 black \ 0820 0820 0820 0FE0 \ E00F 2008 2008 2008 \ 2008 2008 2008 E00F \ 0000 0FE0 0820 0820 error_p,error_s,error_ps black \ 0000 3C3C 4646 4A4A \ 5252 6262 3C3C 0000 \ 0000 3C3C 4646 4A4A \ 5252 6262 3C3C 0000 magnet yellow \ AAAA 0000 5555 0000 \ AAAA 0000 5555 0000 \ AAAA 0000 5555 0000 \ AAAA 0000 5555 0000 fence magenta \ FFFF 0000 0000 0000 \ 0000 0000 0000 0000 \ FFFF 0000 0000 0000 \ 0000 0000 0000 0000 rotate cyan \ 0000 E0E0 E0E0 E0E0 \ 0000 0000 0000 0000 \ 0000 E0E0 E0E0 E0E0 \ 0000 0000 0000 0000 allCut,BiCut X style versatec pfet \ 07c0 0f80 1f00 3e00 \ 7c00 f800 f001 e003 \ c007 800f 001f 003e \ 00c7 00f8 01f0 03e0 nfet \ 1f00 0f80 07c0 03e0 \ 01f0 00f8 007c 003e \ 001f 800f c007 e003 \ f001 f800 7c00 3e00 m2c \ c3c3 c3c3 0000 0000 \ 0000 0000 c3c3 c3c3 \ c3c3 c3c3 0000 0000 \ 0000 0000 c3c3 c3c3 pwell \ 2020 2020 2020 2020 \ 2020 2020 2020 2020 \ 0000 0000 0000 0000 \ 0000 0000 0000 0000 nwell \ 0808 0404 0202 0101 \ 0000 0000 0000 0000 \ 0808 0404 0202 0101 \ 0000 0000 0000 0000 allPoly \ 0808 0400 0202 0101 \ 8080 4000 2020 1010 \ 0808 0004 0202 0101 \ 8080 0040 2020 1010 allMetal1 \ 8080 0000 0000 0000 \ 0808 0000 0000 0000 \ 8080 0000 0000 0000 \ 0808 0000 0000 0000 pad,glass \ 0000 0000 1c1c 3e3e \ 3636 3e3e 1c1c 0000 \ 0000 0000 1c1c 3e3e \ 3636 3e3e 1c1c 0000 nsd,nsc,col,clc \ 0808 1414 2222 4141 \ 8080 4040 2020 1010 \ 0808 1414 2222 4141 \ 8080 4040 2020 1010 allMetal2 \ 0000 1111 0000 0000 \ 0000 1111 0000 0000 \ 0000 1111 0000 0000 \ 0000 1111 0000 0000 pdiff,pdc,pfet \ 0000 0808 5555 8080 \ 0000 8080 5555 0808 \ 0000 0808 5555 8080 \ 0000 8080 5555 0808 psd,psc \ 1414 2222 0000 2222 \ 4141 2222 0000 2222 \ 1414 2222 0000 2222 \ 4141 2222 0000 2222 ndiff,nfet,ndc \ 0808 1010 2020 4040 \ 8080 4141 2222 1414 \ 0808 1010 2020 4040 \ 8080 4141 2222 1414 allPoly2 \ 0000 2020 5050 2020 \ 0000 0202 0505 0202 \ 0000 2020 5050 2020 \ 0000 0202 0505 0202 allCut,BiCut X /* -------------------------------------------------------------- */ style gremlin pfet 9 nfet 10 m2c 11 pwell 15 nwell 16 allPoly 19 allMetal1 22 pad,glass 23 nsd,nsc 24 allMetal2 28 pdiff,pdc,pfet 29 psd,psc 30 ndiff,nfet,ndc 31 m2c/m1,pc/m1,ndc/m1,pdc/m1,psc/m1,nsc/m1,pad/m1 X /* -------------------------------------------------------------- */ style postscript /* * stipple definitions for 32x8 bitmaps * # row1 row2 row3 row4 row5 row6 row7 row8 */ 1 C0C0C0C0 C0C0C0C0 00000000 00000000 0C0C0C0C 0C0C0C0C 00000000 00000000 2 A0A0A0A0 0A0A0A0A A0A0A0A0 0A0A0A0A A0A0A0A0 0A0A0A0A A0A0A0A0 0A0A0A0A 3 00030003 000C000C 00300030 00C000C0 03000300 0C000C00 30003000 C000C000 4 00000000 00000000 C0C0C0C0 00000000 00000000 00000000 0C0C0C0C 00000000 5 FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 6 07070707 0E0E0E0E 1C1C1C1C 38383838 70707070 E0E0E0E0 C1C1C1C1 83838383 7 18181818 30303030 60606060 C0C0C0C0 81818181 03030303 06060606 0C0C0C0C 8 18181818 0C0C0C0C 06060606 03030303 81818181 C0C0C0C0 60606060 30303030 9 18181818 3C3C3C3C 3C3C3C3C 18181818 81818181 C3C3C3C3 C3C3C3C3 81818181 10 F0F0F0F0 60606060 06060606 0F0F0F0F 0F0F0F0F 06060606 60606060 F0F0F0F0 11 01000080 02000040 0C000030 F000000F 000FF000 00300C00 00400200 00800100 12 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 13 00000000 00000000 33333333 33333333 00000000 00000000 CCCCCCCC CCCCCCCC /* * color definitions in CMYK format * # C M Y K closest named color in RGB space */ 1 47 95 111 0 /* RosyBrown3 */ 2 223 31 223 0 /* limegreen */ 3 0 0 0 192 /* gray25 */ 4 31 111 31 0 /* plum */ 5 31 111 255 0 /* orange2 */ 6 63 95 191 0 /* goldenrod3 */ 7 255 63 255 0 /* green3 */ 8 0 0 0 127 /* gray50 */ 9 223 47 223 0 /* limegreen */ 10 0 255 255 0 /* red */ 11 0 0 255 0 /* yellow */ 12 191 127 0 0 /* RoyalBlue1 */ 13 95 223 63 0 /* DarkOrchid3 */ 14 0 0 0 255 /* black */ 15 191 127 63 0 /* steelblue */ 16 111 151 244 0 /* goldenrod4 */ 17 23 175 183 0 /* tomato2 */ /* * magic layer definitions (plotted top to bottom) * layer(s) color# stipple# (plus B=box, X=cross & box) */ cc,pc,ndc,pdc,psc,nsc 14 X m2c,pad,glass 14 B pad,glass 14 11 m2c 14 13 m2,m2c,pad 13 10 pdc,ndc,psc,nsc,hpdc,hndc,hpsc,hnsc,pc,ec,capc,clc,emc,pbc,nbdc,m1,m2c,gc 12 9 cap,cc,poly2 11 7 nsd,nsc 7 1 psd,psc 6 1 nfet,nffet 9 8 pfet,wcap,pffet 1 7 poly,pc,cap,cc 10 5 nfet 16 5 pfet,wcap 17 5 pdiff,pdc,pffet 1 5 ndiff,ndc,nffet 9 5 pwell 1 4 nwell 2 4 /* ------------------------------------------------------------------------ */ style pnm draw metal1 draw metal2 draw polysilicon draw ndiffusion draw pdiffusion draw ntransistor draw ptransistor map psubstratepdiff pdiffusion map nsubstratendiff ndiffusion map polycontact polysilicon metal1 map m2contact metal1 metal2 map m3contact metal2 metal3 map ndcontact ndiffusion metal1 map pdcontact pdiffusion metal1 map nsubstratencontact ndiffusion metal1 map psubstratepcontact pdiffusion metal1 end magic-8.0.210/scmos/mos.7bit.dstyle0000664000175000001440000004471312402623676015511 0ustar timusers# # MOSIS distribution Version 8.2 # # jws 1997/06/26: added new styles for m1t-m3t (49-51) # tim 2002/12/19: redesigned format to eliminate 256 style limit # # This file has been updated by MOSIS to be used for three metal, two poly # SCMOS technology files. # # (C) Copyright 1992, 1993, 1994, 1995 by # # Jen-I Pi pi@isi.edu # The MOSIS Service # USC Information Sciences Institute # 4676 Admiralty Way # Marina del Rey, CA 90292 # (310) 822-1511 x640 fax (310)823-5624 # # All Rights Reserved. # Last Modified Date: 12/03/03 # # Permission to use, copy, modify, and distribute this technology # file and its associated documentation for any purpose and without # fee is hereby granted, provided that the above copyright notice # appears in all copies and that both that copyright notice and this # permission notice appear in supporting documentation, and that the # name of the University of Southern California not be used in # advertising or publicity pertaining to distribution of the software # without specific, written prior permission. The University of # Southern California makes no representations about the suitability # of this technology file for any purpose. This technology file is # provided "as is" without express or implied warranty and the # University of Southern California retains the right to change its # content at any time without notice any other party. # # THE UNIVERSITY OF SOUTHERN CALIFORNIA DISCLAIMS ALL WARRANTIES WITH # REGARD TO THIS TECHNOLOGY FILE, INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF # SOUTHERN CALIFORNIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS # OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS TECHNOLOGY FILE. # # This file describes the various display styles that are available # in Magic. This new file is relatively technology-independent: it # contains enough different styles to support MOSIS's SCMOS process # without any changes. Each display style describes a particular # way of drawing things on the display. See "Magic Maintainer's # Manual #3: The Display Style and Glyph Files" for details on the # file format. # # Please send bug reports/comments to mosis@mosis.edu :-) # # Version keyword replaces the version embedded in the filename. version 7 # # BitPlane Usage: # # # msb lsb # +-------+-----------+-----------+ # | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | # +-------+-----------+-----------+ # | | | | | \_______/ # not used -+ | | | | | # highlights ---+ | | | +---- poly, diff, fets # opaque/trans. ----+ | +------------ metal1 # +---------------- metal2 # # Bits 0-2 represent the material on the poly-diff plane (poly, # different flavors of diffusion, different flavors of transistor) # with mutually-opaque colors. # # Bits 3-4 are used for the two metal layers. Each layer has a # separate bit plane, so the two metal layers are mutually transparent, # and they are both transparent with respect to the poly-diff layers. # # If bit 5 is set, then bits 0-4 are used for one of 32 opaque colors # which override any other mask information. These colors are used # for various stipples, contact crosses, etc. They also provide a # palette of standard colors (red, green, etc.) for use in making # window borders, menus, etc. The last of these colors to be drawn in # an area is the one that will appear. # # Bit 6 is used for highlights such as the box, the selection, etc. # It overrides any of the other bits and produces a pure white color. # # Bit 7 is not used in this display style file. This is important for # Sun workstations, since they can't really give Magic all 8 bits. # For AEDs and other displays, this is a bit wasteful, but still seems # to work ok. display_styles 7 # # The style below means "no color at all". It is special, in that # it is used by cursors to indicate transparency. # # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 0 0x7f 000 0x00 solid 0 - no_color_at_all # # Opaque styles used for drawing and erasing highlights, window borders, # etc. # stipple short long # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 1 0x40 64 0x00 solid 0 - solid_highlights 2 0x40 64 0x00 stipple 12 - medium_highlights 3 0x40 64 0x00 stipple 9 - pale_highlights 4 0x40 64 0x00 stipple 10 - horiz_highlights 5 0x40 64 0x00 stipple 11 - vert_highlights 6 0x40 64 0xff outline 0 - outline_highlights 7 0x40 64 0xcc outline 0 - dotted_highlights # 8 0x40 0 0xff outline 0 - erase_box 9 0x40 0 0x00 solid 0 - erase_highlights 10 0x7f 0 0x00 solid 0 - erase_everything 11 0x3f 0 0x00 solid 0 - erase_all_but_highl # 12 0x3f 59 0xff outline 0 - labels 13 0x3f 45 0xff outline 0 - ports 14 0x3f 54 0xff outline 0 - port_connections 15 0x3f 35 0xff outline 0 - bounding_boxes 16 0x3f 35 0xaa grid 0 - dotted_grid 17 0x3f 35 0xff grid 0 - solid_grid 18 0x3f 35 0x00 solid 0 - origin_square 19 0x3f 35 0xff outline 0 - draw_tile_details # 20 0x7f 55 0x00 solid 0 w window_border 21 0x7f 55 0xff stipple 6 - window_elevator 22 0x7f 56 0x00 solid 0 c window_caption 23 0x7f 57 0x00 solid 0 x window_background # 24 0x7f 58 0x00 solid 0 - color_editing # 25 0x7f 60 0x00 solid 0 T tk_medium_gray 26 0x7f 62 0x00 solid 0 t tk_light_gray # 27 0x7f 47 0xff outline 0 - pale_labels 28 0x7f 53 0xff outline 0 - pale_ports # # # General-purpose opaque colors. These entries define a whole # bunch of generally-useful colors. # # stipple short long # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 29 0x3f 32 0x00 solid 0 W white 30 0x3f 33 0x00 solid 0 - gray1 (pale) 31 0x3f 34 0x00 solid 0 k gray2 (dark) 32 0x3f 35 0x00 solid 0 K black 33 0x3f 36 0x00 solid 0 r red1 (pale) 34 0x3f 37 0x00 solid 0 - red2 (medium) 35 0x3f 38 0x00 solid 0 R red3 (dark) 36 0x3f 39 0x00 solid 0 g green1 (pale) 37 0x3f 40 0x00 solid 0 - green2 (medium) 38 0x3f 41 0x00 solid 0 G green3 (dark) 39 0x3f 42 0x00 solid 0 b blue1 40 0x3f 43 0x00 solid 0 B blue2 (dark) 41 0x3f 44 0x00 solid 0 - blue3 42 0x3f 45 0x00 solid 0 p purple1 43 0x3f 46 0x00 solid 0 P purple2 44 0x3f 47 0x00 solid 0 y yellow1 45 0x3f 48 0x00 solid 0 Y yellow2 46 0x3f 49 0x00 solid 0 o orange1 47 0x3f 50 0x00 solid 0 O orange2 48 0x3f 51 0x00 solid 0 - brown1 49 0x3f 52 0x00 solid 0 - brown2 50 0x3f 53 0x00 solid 0 - magenta 51 0x3f 54 0x00 solid 0 C cyan # #---------------------------------------------------------------------- # All of the styles above this point are used internally by Magic for # things like menus, drawing the box, etc. The style numbers must # match the definitions in misc/style.h. All of the styles below # this point are used by the technology file, addressed by number. # Note that the numbers are only for backwards compatibility with # .tech27 files which specify styles by number. .tech28 files may # specify styles by name, and numbers may be listed out of order. # The order in which styles are drawn is the order in which they # appear in this file. #---------------------------------------------------------------------- layout_styles # # Poly-diff styles: # stipple short long # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 1 0x07 1 0x00 solid 0 - polysilicon 87 0x07 50 0x00 solid 0 - poly_light 88 0x07 1 0x00 stipple 1 - obspoly 2 0x07 2 0x00 solid 0 - ndiffusion 3 0x07 2 0x00 stipple 13 - ndiff_in_nwell 4 0x07 3 0x00 solid 0 - pdiffusion 5 0x07 3 0x00 stipple 13 - pdiff_in_pwell 6 0x07 4 0x00 solid 0 - ntransistor 7 0x07 2 0x00 stipple 7 - ntransistor_stripes 8 0x07 5 0x00 solid 0 - ptransistor 9 0x07 3 0x00 stipple 5 - ptransistor_stripes 10 0x3f 6 0x00 stipple 7 - cwell 11 0x07 5 0x00 stipple 22 - hvndiff_mask 12 0x07 7 0x00 stipple 7 - nwell 13 0x07 3 0x00 stipple 5 - pwell 79 0x07 71 0x00 stipple 21 - highvolt_nwell 80 0x07 69 0x00 stipple 22 - highvolt_pwell 83 0x3f 51 0x00 stipple 5 - implant1 84 0x3f 48 0x00 stipple 5 - implant2 85 0x3f 38 0x00 stipple 5 - implant3 86 0x3f 62 0x00 stipple 5 - implant4 14 0x3f 6 0x00 stipple 2 - electrode 15 0x07 3 0x00 stipple 10 - pbase 16 0x07 2 0x00 stipple 17 - emitter 17 0x07 3 0x00 stipple 11 - bccd 18 0x07 4 0x00 stipple 21 - hvpdiff_mask 19 0x07 7 0x00 solid 0 - via # # Metal styles: # stipple short long # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 20 0x08 8 0x00 solid 0 - metal1 21 0x10 16 0x00 solid 0 - metal2 22 0x3f 53 0x00 stipple 23 - metal3 23 0x3f 33 0x00 stipple 20 - metal4 24 0x3f 44 0x00 stipple 8 - metal5 25 0x3f 37 0x00 solid 0 - pad4 26 0x0f 9 0x00 solid 0 - poly_contact 27 0x07 1 0x00 solid 0 - electrode_stripes 28 0x3f 6 0x00 stipple 2 - capacitor 29 0x08 8 0x00 solid 0 - metal1_alt # # Opaque stipples and such for mask display: # stipple short long # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 30 0x3f 2 0x00 stipple 22 - ndop_stripes 31 0x3f 3 0x00 stipple 21 - pdop_stripes 32 0x3f 7 0xff cross 0 - contact_X'es 33 0x3f 7 0xff stipple 2 - contact_waffle 34 0x3f 34 0xff stipple 10 - overglass 35 0x3f 3 0xff stipple 1 - pselect 36 0x3f 2 0xff stipple 15 - nselect 37 0x3f 46 0xff stipple 19 - via2 38 0x3f 38 0xff stipple 24 - via3 39 0x3f 41 0xff stipple 5 - via4 # 40 0x3f 53 0x00 stipple 5 - check_paint 41 0x3f 54 0x00 stipple 7 - check_subcells 42 0x3f 32 0x00 stipple 4 - error_waffle 43 0x07 2 0x00 stipple 5 - nselect2 44 0x07 3 0x00 stipple 7 - pselect2 45 0x07 35 0x00 solid 0 - comment 46 0x07 42 0x00 stipple 7 - silicide_block 47 0x07 1 0x00 solid 0 - poly_resist 48 0x07 3 0x00 stipple 7 - poly_resist_stripes #jws 49 0x08 8 0x00 stipple 19 - metal1tight 89 0x08 8 0x00 stipple 1 - obsmetal1 50 0x10 16 0x00 stipple 19 - metal2tight 90 0x10 16 0x00 stipple 1 - obsmetal2 51 0x3f 53 0x00 stipple 8 - metal3tight 91 0x3f 53 0x00 stipple 1 - obsmetal3 92 0x3f 33 0x00 stipple 1 - obsmetal4 93 0x3f 44 0x00 stipple 1 - obsmetal5 52 0x07 2 0x00 stipple 19 - cwellnsc 53 0x07 7 0x00 stipple 7 - nwell_field_implant 54 0x07 7 0x00 stipple 5 - substrate_field_implant 55 0x3f 43 0xff stipple 35 - via1arrow 81 0x3f 43 0xff stipple 2 - via1 56 0x3f 53 0xff stipple 36 - via2arrow 82 0x3f 53 0xff stipple 2 - via2alt 57 0x3f 6 0xff stipple 2 - via3alt 58 0x3f 7 0x00 solid 0 - gen_contact # 59 0x3f 16 0xff stipple 2 - via5 60 0x3f 46 0xff stipple 28 - via6 61 0x3f 51 0xff stipple 29 - via7 76 0x3f 7 0xff stipple 30 - via8 78 0x3f 7 0xff stipple 31 - via9 # 64 0x3f 46 0x00 stipple 17 - metal6 94 0x3f 46 0x00 stipple 1 - obsmetal6 65 0x3f 38 0x00 stipple 9 - metal7 95 0x3f 38 0x00 stipple 1 - obsmetal7 66 0x3f 34 0x00 stipple 16 - metal8 96 0x3f 34 0x00 stipple 1 - obsmetal8 75 0x3f 40 0x00 stipple 26 - metal9 97 0x3f 40 0x00 stipple 1 - obsmetal9 77 0x3f 42 0x00 stipple 23 - metal10 98 0x3f 42 0x00 stipple 1 - obsmetal10 # 62 0x3f 0 0x00 solid 0 - mim_bottom 63 0x3f 0 0x00 solid 0 - mim_top 67 0x07 9 0x00 outline 0 - subcircuit 68 0x3f 34 0xff stipple 12 - mems # 69 0x3f 40 0x00 stipple 3 - mvndiff 70 0x3f 41 0x00 stipple 3 - hvndiff 71 0x3f 44 0x00 stipple 3 - ncontact 72 0x3f 51 0x00 solid 25 - mvpdiff 73 0x3f 52 0x00 solid 25 - hvpdiff 74 0x3f 45 0x00 solid 25 - pcontact # #---------------------------------------------------------------------- # All of the styles below this point must duplicate the styles in # the section above, and represent a version of each previous # layer to use in non-edit cells ("pale" styles): #---------------------------------------------------------------------- pale_styles # # Poly-diff styles: # stipple short long # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 1 0x07 1 0x00 stipple 14 - polysilicon 87 0x07 49 0x00 solid 0 - poly_light 88 0x07 1 0x00 stipple 1 - obspoly 2 0x07 2 0x00 stipple 14 - ndiffusion 3 0x07 2 0x00 stipple 13 - ndiff_in_nwell 4 0x07 3 0x00 stipple 14 - pdiffusion 5 0x07 3 0x00 stipple 13 - pdiff_in_pwell 6 0x07 4 0x00 stipple 14 - ntransistor 7 0x07 2 0x00 stipple 7 - ntransistor_stripes 8 0x07 5 0x00 stipple 14 - ptransistor 9 0x07 3 0x00 stipple 5 - ptransistor_stripes 10 0x07 6 0x00 stipple 7 - cwell 11 0x07 5 0x00 stipple 22 - hvndiff_mask 12 0x07 7 0x00 stipple 7 - nwell 13 0x07 3 0x00 stipple 5 - pwell 79 0x07 71 0x00 stipple 21 - highvolt_nwell 80 0x07 69 0x00 stipple 22 - highvolt_pwell 83 0x3f 51 0x00 stipple 5 - implant1 84 0x3f 48 0x00 stipple 5 - implant2 85 0x3f 38 0x00 stipple 5 - implant3 86 0x3f 62 0x00 stipple 5 - implant4 14 0x3f 6 0x00 stipple 2 - electrode 15 0x07 3 0x00 stipple 10 - pbase 16 0x07 2 0x00 stipple 17 - emitter 17 0x07 3 0x00 stipple 11 - bccd 18 0x07 7 0x00 stipple 21 - hvpdiff_mask 19 0x07 7 0x00 stipple 2 - via # # Metal styles: # stipple short long # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 20 0x08 8 0x00 stipple 14 - metal1 21 0x10 16 0x00 stipple 14 - metal2 22 0x3f 53 0x00 stipple 5 - metal3 23 0x3f 33 0x00 stipple 21 - metal4 24 0x3f 44 0x00 stipple 22 - metal5 25 0x3f 37 0x00 stipple 18 - pad4 26 0x09 9 0x00 stipple 14 - poly_contact 27 0x07 1 0x00 stipple 14 - electrode_stripes 28 0x3f 6 0x00 stipple 2 - capacitor 29 0x08 8 0x00 stipple 14 - metal1_alt # # Opaque stipples and such for mask display: # stipple short long # num mask color outline fill number name name # ----+------+--------+--------+------+-------+------+-------------- 30 0x3f 2 0x00 stipple 22 - ndop_stripes 31 0x3f 3 0x00 stipple 21 - pdop_stripes 32 0x3f 35 0xff cross 0 - contact_X'es 33 0x3f 35 0xff stipple 2 - contact_waffle 34 0x3f 34 0xff stipple 10 - overglass 35 0x3f 3 0xff stipple 1 - pselect 36 0x3f 2 0xff stipple 15 - nselect 37 0x3f 46 0xff stipple 19 - via2 38 0x3f 38 0xff stipple 24 - via3 39 0x3f 41 0xff stipple 5 - via4 # 40 0x3f 53 0x00 stipple 5 - check_paint 41 0x3f 54 0x00 stipple 7 - check_subcells 42 0x3f 32 0x00 stipple 4 - error_waffle 43 0x07 2 0x00 stipple 5 - nselect2 44 0x07 3 0x00 stipple 7 - pselect2 45 0x07 15 0x00 solid 0 - comment 46 0x07 42 0x00 stipple 7 - silicide_block 47 0x07 1 0x00 solid 0 - poly_resist 48 0x07 3 0x00 stipple 7 - poly_resist_stripes #jws: 49 0x08 8 0x00 stipple 14 - metal1tight 89 0x08 8 0x00 stipple 1 - obsmetal1 50 0x10 16 0x00 stipple 5 - metal2tight 90 0x10 16 0x00 stipple 1 - obsmetal2 51 0x3f 53 0x00 stipple 21 - metal3tight 91 0x3f 53 0x00 stipple 1 - obsmetal3 92 0x3f 33 0x00 stipple 1 - obsmetal4 93 0x3f 44 0x00 stipple 1 - obsmetal5 52 0x07 2 0x00 stipple 13 - cwellnsc 53 0x07 7 0x00 stipple 7 - nwell_field_implant 54 0x07 7 0x00 stipple 5 - substrate_field_implant 55 0x3f 43 0x00 stipple 35 - via1arrow 81 0x3f 43 0x00 stipple 2 - via1 56 0x3f 53 0x00 stipple 36 - via2arrow 82 0x3f 53 0x00 stipple 2 - via2 57 0x3f 6 0x00 stipple 2 - via3 58 0x3f 34 0x00 stipple 6 - gen_contact # 59 0x3f 16 0xff stipple 2 - via5 60 0x3f 46 0xff stipple 28 - via6 61 0x3f 51 0xff stipple 29 - via7 76 0x3f 34 0xff stipple 30 - via8 78 0x3f 34 0xff stipple 31 - via9 # 64 0x3f 46 0x00 stipple 11 - metal6 94 0x3f 46 0x00 stipple 1 - obsmetal6 65 0x3f 38 0x00 stipple 5 - metal7 95 0x3f 38 0x00 stipple 1 - obsmetal7 66 0x3f 34 0x00 stipple 10 - metal8 96 0x3f 34 0x00 stipple 1 - obsmetal8 75 0x3f 40 0x00 stipple 27 - metal9 97 0x3f 40 0x00 stipple 1 - obsmetal9 77 0x3f 42 0x00 stipple 20 - metal10 98 0x3f 42 0x00 stipple 1 - obsmetal10 # 62 0x3f 0 0x00 solid 0 - mim_bottom 63 0x3f 0 0x00 solid 0 - mim_top 67 0x07 9 0x00 outline 0 - subcircuit 68 0x3f 33 0xff stipple 12 - mems # 69 0x3f 40 0x00 stipple 5 - mvndiff 70 0x3f 41 0x00 stipple 5 - hvndiff 71 0x3f 44 0x00 stipple 5 - ncontact 72 0x3f 51 0x00 stipple 7 - mvpdiff 73 0x3f 52 0x00 stipple 7 - hvpdiff 74 0x3f 45 0x00 stipple 7 - pcontact stipples #-----------------------------------+--------------------------------------- # hex bit pattern (8x8) description #-----------------------------------+--------------------------------------- 1 40 00 18 00 18 00 00 00 very sparsed stripes, ll to ur 2 cc cc 00 00 33 33 00 00 coarse knight's move (waffle) 3 ee 77 bb dd ee 77 bb dd all but diagonal stripes, ll to ur 4 00 00 cc cc 00 00 cc cc offset waffle 5 40 20 10 08 04 02 01 80 sparse diagonal stripes, ll to ur 6 aa 55 aa 55 aa 55 aa 55 half 'n half (checkerboard) 7 02 04 08 10 20 40 80 01 sparse diagonal stripes, lr to ul 8 81 03 06 0c 18 30 60 c0 wide sparse diagonal stripes, lr to ul 9 81 c0 60 30 18 0c 06 03 wide sparse diagonal stripes, ll to ur 10 00 00 00 ff 00 00 00 ff horizontal stripes 11 44 44 44 44 44 44 44 44 vertical stripes 12 55 aa 55 aa 55 aa 55 aa complement of half `n half 13 33 33 ff ff cc cc ff ff complement of #2 (coarse knight's move) 14 aa 55 aa 55 aa 55 aa 55 half 'n half (checkerboard) 15 00 01 00 18 00 00 00 18 very sparsed stripes, 11 to ur 16 c0 07 ff ff c0 07 ff ff wide horizontal stripes 17 c7 c7 c7 c7 c7 c7 c7 c7 wide vertical stripes 18 7c 7c 7c 7c 7c 7c 7c 7c wide vertical stripes (reverse of 17) 19 3c c3 42 42 c3 3c 24 24 bubbles 20 24 42 81 81 42 24 18 18 offset diagonal crossex 21 10 20 00 00 00 02 04 08 diagonal dotted line, lr to ul 22 08 04 00 00 00 40 20 10 diagonal dotted line, ll to ur 23 3c 66 c3 81 c3 66 3c 18 dense diagonal crossex 24 c3 3c bd bd 3c c3 db db complement of #19 empty bubbles 25 dd bb 77 ee dd bb 77 ee all but diagonal stripes, lr to ul 26 e2 4e 52 29 94 e4 8e 11 T pattern 27 71 47 41 00 42 72 47 99 sparse offset T pattern 28 99 3c 7e e7 e7 7e 3c 99 alternating diamonds 29 44 88 55 22 44 88 55 22 bricks, ll to ur 30 30 60 c0 c1 63 36 1c 18 bricks, lr to ul 31 55 db 22 db 55 db 22 db linoleum 32 60 c0 81 03 06 0c 18 30 33 00 00 00 30 60 60 30 00 new gc thin 34 00 02 06 0e 0e 06 02 00 35 00 7e 3c 18 00 e7 c3 81 arrows pointing up 36 e0 62 26 0e 0e 26 62 e0 arrows pointing left magic-8.0.210/scmos/gdsquery.tech.m40000644000175000001440000000065410751423606015636 0ustar timuserstech format 28 gdsquery end version version 0.1 description "Minimal technology file for querying an unknown GDS database" end planes end types end contact end styles styletype mos end compose end connect end cifoutput style generic scalefactor 1 end cifinput style generic scalefactor 1 end # mzrouter # end drc end extract end # wiring # end # router # end # plowing # end # plot # end magic-8.0.210/oa/0000755000175000001440000000000011504623574012060 5ustar timusersmagic-8.0.210/oa/oa.c0000644000175000001440000001456410751423606012632 0ustar timusers/*--------------------------------------------------------------*/ /* oa.c -- */ /* OpenAccess database support for magic */ /* */ /* Written by R. Timothy Edwards 4/22/04 */ /* Open Circuit Design, Inc. for */ /* MultiGiG, Inc. */ /*--------------------------------------------------------------*/ #ifdef MAGIC_WRAPPER #ifdef OPENACCESS #include "tcltk/tclmagic.h" #include "utils/geometry.h" #include "utils/magic.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "oa/oa.h" /* *----------------------------------------------------------------------------- * * OAInit -- * * Initialize variables required by the OpenAccess module. * *----------------------------------------------------------------------------- */ void OAInit() { /* This generates the TCL commands for magicoa */ Magicoa_Init(magicinterp); } /* *----------------------------------------------------------------------------- * * OACellSearch -- * * The OpenAccess equivalent of DBTreeSrCells. This function is called by * DBTreeSrCells when the cell def has the flag CDOPENACCESS set. * * The procedure should be of the following form: * int * func(scx, cdarg) * SearchContext *scx; * ClientData cdarg; * { * } * * In the above, the transform scx->scx_trans is from coordinates of * the def of scx->scx_use to the "root". The array indices * scx->scx_x and scx->scx_y identify this element if it is a * component of an array. Func normally returns 0. If func returns * 1, then the search is aborted. If func returns 2, then all * remaining elements of the current array are skipped, but the * search is not aborted. * * Each element of an array is returned separately. * * Results: * 0 is returned if the search terminated normally. 1 is * returned if it was aborted. * * Side effects: * Whatever side effects are brought about by applying the * procedure supplied. * * Warnings: * The OpenAccess routines should only be used when (*func)() * is read-only; that is, the function should not attempt to * alter the cell structure. *----------------------------------------------------------------------------- */ int OACellSearch(scx, xMask, func, cdarg) SearchContext *scx; /* Pointer to search context specifying a cell use to * search, an area in the coordinates of the cell's * def, and a transform back to "root" coordinates. */ int xMask; /* All subcells are visited recursively until we * encounter uses whose flags, when anded with * xMask, are not equal to xMask. Func is called * for these cells. A zero mask means all cells in * the root use are considered not to be expanded, * and hence are passed to func. */ int (*func)(); /* Function to apply to each qualifying cell */ ClientData cdarg; /* Client data for above function */ { TreeContext context; TreeFilter filter; char *instname; filter.tf_xmask = xMask; filter.tf_func = func; filter.tf_arg = cdarg; context.tc_scx = scx; context.tc_filter = &filter; /* Get the name of the instance, which should have been set by */ /* rexlite when the OpenAccess database was opened under magic. */ instname = scx->scx_use->cu_id; /* Query the OpenAccess database. For each cell overlapping the * area scx->scx_area, call the function (*func)() with client * data cdarg. Currently, xMask is not used (assumed to be 0). */ /* The rexlite function is tentatively called REXSearchInstances(): */ /* REXSearchInstances(name, func, arg) { */ /* char *name; */ /* (int)(*func)(); */ /* ClientData arg; */ /* */ /* This function should return 0 normally, 1 in case of error. */ /* For each cell instance which is in the hierarchy of "instname", */ /* REXSearchInstances() should call "func" with arguments: */ /* */ /* (int)(*func)(char *iname, char *dname, int llx, int lly, */ /* int urx, int urx, ClientData arg); */ /* */ /* where "iname" is the name of the instance, "dname" is the name */ /* of the master cell, and "llx", "lly", "urx", and "ury" are the */ /* bounding box coordinates. "arg" is passed on from above. */ /* If func() returns 0, then the database search should continue. */ /* If func() returns 1, then the database search should stop and */ /* REXSearchInstances() should return 1. */ /* return REXSearchInstances(instname, oaTreeCellSrFunc, (ClientData)&context); */ return 0; /* placeholder */ } /* * Callback function called from REXSearchInstances() for each instance * encountered in the cell search. * * For the time being, we pass back a minimal amount of information: The * instance name and the bounding box. The bounding box will be compared * against the search area to check for overlap, and the function buried * in the TreeContext structure (passed as a generic client data pointer) * will be called. */ int oaTreeCellSrFunc(instname, defname, llx, lly, urx, ury, cdarg) char *instname; char *defname; int llx, lly, urx, ury; ClientData cdarg; { TreeContext *context = (TreeContext *)cdarg; TreeFilter *filter = context->tc_filter; SearchContext newscx, *scx = context->tc_scx; int fres; Rect r, *area = &scx->scx_area; CellUse newuse; /* Check for area overlap */ r.r_xbot = llx; r.r_xtop = urx; r.r_ybot = lly; r.r_ytop = ury; /* Transform---for now, assuming that llx, etc., are relative to */ /* the top-level coordinate system. */ /* Check for area overlap */ if (!GEO_OVERLAP(area, &r)) return 0; /* Don't call function but keep the search going */ newuse.cu_id = instname; newuse.cu_bbox = r; /* Need to fill in more of the CellUse structure! */ newscx.scx_use = &newuse; newscx.scx_area = scx->scx_area; /* Need to fill in more of the SearchContext structure! */ /* Call the function */ fres = (*(filter->tf_func))(newscx, (ClientData)filter->tf_arg); return fres; /* keep the search going */ } #endif /* OPENACCESS */ #endif /* MAGIC_WRAPPER */ magic-8.0.210/oa/Makefile0000644000175000001440000000146610751423606013524 0ustar timusers# # OpenAccess module Makefile # MODULE = oa MAGICDIR = .. SRCS = oa.c CXXSRCS = magicInit.cpp magicOA.cpp include ${MAGICDIR}/defs.mak #---------------------------------------- CXX_INCLUDES = -I. -I${OA}/oa/include DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) DEP_FILES = $(addprefix .deps/,$(SRCS:.c=.P))\ $(addprefix .deps/,$(CXXSRCS:.cpp=.P)) -include ${DEP_FILES} %.o: %.cpp @echo '$(COMPILE) -c $<'; \ ${CXX} ${CXX_CFLAGS} ${OTHER_CFLAGS} ${CXX_INCLUDES} -Wp,-MD,.deps/$(*F).pp -c $< @-cp .deps/$(*F).pp .deps/$(*F).P; \ tr ' ' '\012' < .deps/$(*F).pp \ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ >> .deps/$(*F).P; \ rm .deps/$(*F).pp clean: ${RM} *.o ${RM} -r .deps #------------------------------------------------------ include ${MAGICDIR}/rules.mak magic-8.0.210/oa/.deps/0000755000175000001440000000000011504623574013071 5ustar timusersmagic-8.0.210/oa/.deps/magicInit.P0000644000175000001440000013430310751423606015117 0ustar timusersmagicInit.o: magicInit.cpp /usr/local/include/c++/3.3.3/iostream \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/c++config.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/os_defines.h \ /usr/include/features.h /usr/include/sys/cdefs.h \ /usr/include/gnu/stubs.h /usr/local/include/c++/3.3.3/ostream \ /usr/local/include/c++/3.3.3/ios /usr/local/include/c++/3.3.3/iosfwd \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/c++locale.h \ /usr/local/include/c++/3.3.3/clocale /usr/include/locale.h \ /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/stddef.h \ /usr/include/bits/locale.h /usr/include/xlocale.h \ /usr/local/include/c++/3.3.3/cctype /usr/include/ctype.h \ /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ /usr/include/bits/sched.h /usr/include/endian.h \ /usr/include/bits/endian.h \ /usr/local/include/c++/3.3.3/bits/stringfwd.h \ /usr/local/include/c++/3.3.3/bits/fpos.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/c++io.h \ /usr/local/include/c++/3.3.3/cstdio \ /usr/local/include/c++/3.3.3/cstddef /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/include/bits/wchar.h /usr/include/gconv.h \ /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/stdarg.h \ /usr/include/bits/stdio_lim.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/gthr.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/gthr-default.h \ /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/pthread.h \ /usr/include/sched.h /usr/include/time.h /usr/include/bits/time.h \ /usr/include/signal.h /usr/include/bits/sigset.h \ /usr/include/bits/initspin.h \ /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/bits/sigthread.h \ /usr/include/unistd.h /usr/include/bits/posix_opt.h \ /usr/include/bits/environments.h /usr/include/bits/wordsize.h \ /usr/include/bits/confname.h /usr/include/getopt.h \ /usr/local/include/c++/3.3.3/cwchar /usr/local/include/c++/3.3.3/ctime \ /usr/local/include/c++/3.3.3/bits/functexcept.h \ /usr/local/include/c++/3.3.3/exception_defines.h \ /usr/local/include/c++/3.3.3/exception \ /usr/local/include/c++/3.3.3/bits/char_traits.h \ /usr/local/include/c++/3.3.3/cstring /usr/include/string.h \ /usr/local/include/c++/3.3.3/bits/localefwd.h \ /usr/local/include/c++/3.3.3/bits/ios_base.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/atomicity.h \ /usr/local/include/c++/3.3.3/bits/locale_classes.h \ /usr/local/include/c++/3.3.3/string /usr/local/include/c++/3.3.3/memory \ /usr/local/include/c++/3.3.3/bits/stl_algobase.h \ /usr/local/include/c++/3.3.3/climits \ /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/limits.h \ /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/syslimits.h \ /usr/include/limits.h /usr/include/bits/posix1_lim.h \ /usr/include/bits/local_lim.h /usr/include/linux/limits.h \ /usr/include/bits/posix2_lim.h /usr/include/bits/xopen_lim.h \ /usr/local/include/c++/3.3.3/cstdlib /usr/include/stdlib.h \ /usr/include/bits/waitflags.h /usr/include/bits/waitstatus.h \ /usr/include/sys/types.h /usr/include/sys/select.h \ /usr/include/bits/select.h /usr/include/sys/sysmacros.h \ /usr/include/alloca.h /usr/local/include/c++/3.3.3/new \ /usr/local/include/c++/3.3.3/bits/stl_pair.h \ /usr/local/include/c++/3.3.3/bits/type_traits.h \ /usr/local/include/c++/3.3.3/bits/stl_iterator_base_types.h \ /usr/local/include/c++/3.3.3/bits/stl_iterator_base_funcs.h \ /usr/local/include/c++/3.3.3/bits/concept_check.h \ /usr/local/include/c++/3.3.3/bits/stl_iterator.h \ /usr/local/include/c++/3.3.3/bits/stl_alloc.h \ /usr/local/include/c++/3.3.3/bits/stl_threads.h \ /usr/local/include/c++/3.3.3/bits/stl_construct.h \ /usr/local/include/c++/3.3.3/bits/stl_uninitialized.h \ /usr/local/include/c++/3.3.3/bits/stl_raw_storage_iter.h \ /usr/local/include/c++/3.3.3/bits/stl_function.h \ /usr/local/include/c++/3.3.3/bits/basic_string.h \ /usr/local/include/c++/3.3.3/algorithm \ /usr/local/include/c++/3.3.3/bits/stl_algo.h \ /usr/local/include/c++/3.3.3/bits/stl_heap.h \ /usr/local/include/c++/3.3.3/bits/stl_tempbuf.h \ /usr/local/include/c++/3.3.3/bits/basic_string.tcc \ /usr/local/include/c++/3.3.3/streambuf \ /usr/local/include/c++/3.3.3/bits/streambuf.tcc \ /usr/local/include/c++/3.3.3/bits/basic_ios.h \ /usr/local/include/c++/3.3.3/bits/streambuf_iterator.h \ /usr/local/include/c++/3.3.3/bits/locale_facets.h \ /usr/local/include/c++/3.3.3/cwctype /usr/include/wctype.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/ctype_base.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/ctype_inline.h \ /usr/local/include/c++/3.3.3/bits/codecvt.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/codecvt_specializations.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/time_members.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/messages_members.h \ /usr/local/include/c++/3.3.3/bits/basic_ios.tcc \ /usr/local/include/c++/3.3.3/bits/ostream.tcc \ /usr/local/include/c++/3.3.3/locale \ /usr/local/include/c++/3.3.3/bits/locale_facets.tcc \ /usr/local/include/c++/3.3.3/cerrno /usr/include/errno.h \ /usr/include/bits/errno.h /usr/include/linux/errno.h \ /usr/include/asm/errno.h /usr/local/include/c++/3.3.3/cmath \ /usr/include/math.h /usr/include/bits/huge_val.h \ /usr/include/bits/nan.h /usr/include/bits/mathdef.h \ /usr/include/bits/mathcalls.h \ /usr/local/include/c++/3.3.3/bits/cmath.tcc \ /usr/local/include/c++/3.3.3/limits \ /usr/local/include/c++/3.3.3/typeinfo \ /usr/local/include/c++/3.3.3/istream \ /usr/local/include/c++/3.3.3/bits/istream.tcc \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDB.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBase.h \ /usr/include/malloc.h /usr/include/sys/times.h /usr/include/dirent.h \ /usr/include/bits/dirent.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBaseTypes.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBaseModTypes.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBaseMsgs.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaMemory.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaString.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaException.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPoint.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaVector.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSegment.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBox.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPointArray.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOrient.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTransform.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTimeStamp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPackedData.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDir.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaFile.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaMapFile.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaMapWindow.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTimer.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaType.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDomain.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaObject.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaIntProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaFloatProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaStringProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAppProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaHierProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDoubleProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBooleanProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTimeProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaIntRangeProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaFloatRangeProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDoubleRangeProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTimeRangeProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaEnumProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDataCallback.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaGroup.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCallback.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaThread.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaNameSpace.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaName.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAppObjectDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAppDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCdbaNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaNativeNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaLefDefNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSpiceNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSpefNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSpfNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaUnixNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaVerilogNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaVhdlNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaWinNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCollection.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBaseCollection.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDump.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaComplex.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaHashTbl.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaLookupTbl.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTesselator.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaMutex.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDD.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDDMsgs.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDDException.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDDObject.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaFileSys.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaFSDir.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaLib.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCell.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaView.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaFSFile.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaLibFile.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCellFile.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaViewFile.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDDObjectDB.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDDCallback.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDDCollection.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDDDump.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAntennaData.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTC.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTCModTypes.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTCMsgs.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTCObject.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTech.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTCException.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRule.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaLayer.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDerivedLayer.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPhysicalLayer.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPurpose.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSiteDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaViaDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaViaDefArray.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaViaSpec.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteLayerSpec.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteSpec.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOpPoint.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAnalysisLib.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCumulativeRatios.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTechDump.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTCCallback.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTCCollection.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDBModTypes.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDBMsgs.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDBException.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDBObject.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBlockObject.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDBCollection.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaHeaderCollection.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaNetCollection.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTermCollection.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAttrType.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSigType.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSource.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCellView.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBlock.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaScalarNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBusNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBusNetBit.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBusNetDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBundleNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaScalarTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBusTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBusTermBit.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBusTermDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBundleTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaFig.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaLPPHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaLayerHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTextAlign.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaFont.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaInstHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRowHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRow.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaScalarInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaArrayInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaVectorInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaVectorInstDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaShape.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRect.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPolygon.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPath.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDonut.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDot.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaEllipse.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaArc.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaLine.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaText.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTextDisplay.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaViaParam.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteElement.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRoute.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaInstTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaInstPin.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAssignmentDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAssignment.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaConnectDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaHierPath.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRegionQuery.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPin.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTrackPattern.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaMarker.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDBDataCallback.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaParam.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCluster.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBoundary.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBlockage.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaViaHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaScanChainSet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaScanChain.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaScanChainInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSteiner.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCMap.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaGCellPattern.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDBDump.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPinGroup.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAnalysisPoint.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAnalysisOpPoint.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOpPointHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteSpecHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaReducedModel.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPoleResidue.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaLumpedElmore.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPiElmore.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPiPoleResidue.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaElmore.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaNode.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaGroundedNode.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDevice.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaStdDevice.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaResistor.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCouplingCap.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaInductor.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDiode.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSeriesRL.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaMutualInductor.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaParasiticNetwork.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaGuide.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSubNetwork.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteOptimizer.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModObject.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModule.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModCellViewInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModScalarInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModVectorInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModVectorInstDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModInstHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModModuleInstHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModBundleNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusNetBit.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModScalarNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusNetDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModInstTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModBundleTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusTermBit.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModScalarTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusTermDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModConnectDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModAssignment.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModModuleInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModScalarModuleInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModVectorModuleInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccObject.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccurrence.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccCellViewInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccScalarInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccVectorInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccVectorInstDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccInstHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccModuleInstHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBundleNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusNetBit.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccScalarNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusNetDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccInstTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBundleTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusTermBit.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccScalarTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusTermDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccConnectDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccAssignment.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccArrayInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccModuleInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccScalarModuleInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccVectorModuleInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDBCallback.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModCallback.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccCallback.h \ magicOA.h /usr/local/include/tcl.h /usr/local/include/tclDecls.h \ magicInit.h magicInit.cpp : /usr/local/include/c++/3.3.3/iostream : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/c++config.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/os_defines.h : /usr/include/features.h : /usr/include/sys/cdefs.h : /usr/include/gnu/stubs.h : /usr/local/include/c++/3.3.3/ostream : /usr/local/include/c++/3.3.3/ios : /usr/local/include/c++/3.3.3/iosfwd : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/c++locale.h : /usr/local/include/c++/3.3.3/clocale : /usr/include/locale.h : /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/stddef.h : /usr/include/bits/locale.h : /usr/include/xlocale.h : /usr/local/include/c++/3.3.3/cctype : /usr/include/ctype.h : /usr/include/bits/types.h : /usr/include/bits/pthreadtypes.h : /usr/include/bits/sched.h : /usr/include/endian.h : /usr/include/bits/endian.h : /usr/local/include/c++/3.3.3/bits/stringfwd.h : /usr/local/include/c++/3.3.3/bits/fpos.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/c++io.h : /usr/local/include/c++/3.3.3/cstdio : /usr/local/include/c++/3.3.3/cstddef : /usr/include/stdio.h : /usr/include/libio.h : /usr/include/_G_config.h : /usr/include/wchar.h : /usr/include/bits/wchar.h : /usr/include/gconv.h : /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/stdarg.h : /usr/include/bits/stdio_lim.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/gthr.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/gthr-default.h : /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/pthread.h : /usr/include/sched.h : /usr/include/time.h : /usr/include/bits/time.h : /usr/include/signal.h : /usr/include/bits/sigset.h : /usr/include/bits/initspin.h : /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/bits/sigthread.h : /usr/include/unistd.h : /usr/include/bits/posix_opt.h : /usr/include/bits/environments.h : /usr/include/bits/wordsize.h : /usr/include/bits/confname.h : /usr/include/getopt.h : /usr/local/include/c++/3.3.3/cwchar : /usr/local/include/c++/3.3.3/ctime : /usr/local/include/c++/3.3.3/bits/functexcept.h : /usr/local/include/c++/3.3.3/exception_defines.h : /usr/local/include/c++/3.3.3/exception : /usr/local/include/c++/3.3.3/bits/char_traits.h : /usr/local/include/c++/3.3.3/cstring : /usr/include/string.h : /usr/local/include/c++/3.3.3/bits/localefwd.h : /usr/local/include/c++/3.3.3/bits/ios_base.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/atomicity.h : /usr/local/include/c++/3.3.3/bits/locale_classes.h : /usr/local/include/c++/3.3.3/string : /usr/local/include/c++/3.3.3/memory : /usr/local/include/c++/3.3.3/bits/stl_algobase.h : /usr/local/include/c++/3.3.3/climits : /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/limits.h : /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/syslimits.h : /usr/include/limits.h : /usr/include/bits/posix1_lim.h : /usr/include/bits/local_lim.h : /usr/include/linux/limits.h : /usr/include/bits/posix2_lim.h : /usr/include/bits/xopen_lim.h : /usr/local/include/c++/3.3.3/cstdlib : /usr/include/stdlib.h : /usr/include/bits/waitflags.h : /usr/include/bits/waitstatus.h : /usr/include/sys/types.h : /usr/include/sys/select.h : /usr/include/bits/select.h : /usr/include/sys/sysmacros.h : /usr/include/alloca.h : /usr/local/include/c++/3.3.3/new : /usr/local/include/c++/3.3.3/bits/stl_pair.h : /usr/local/include/c++/3.3.3/bits/type_traits.h : /usr/local/include/c++/3.3.3/bits/stl_iterator_base_types.h : /usr/local/include/c++/3.3.3/bits/stl_iterator_base_funcs.h : /usr/local/include/c++/3.3.3/bits/concept_check.h : /usr/local/include/c++/3.3.3/bits/stl_iterator.h : /usr/local/include/c++/3.3.3/bits/stl_alloc.h : /usr/local/include/c++/3.3.3/bits/stl_threads.h : /usr/local/include/c++/3.3.3/bits/stl_construct.h : /usr/local/include/c++/3.3.3/bits/stl_uninitialized.h : /usr/local/include/c++/3.3.3/bits/stl_raw_storage_iter.h : /usr/local/include/c++/3.3.3/bits/stl_function.h : /usr/local/include/c++/3.3.3/bits/basic_string.h : /usr/local/include/c++/3.3.3/algorithm : /usr/local/include/c++/3.3.3/bits/stl_algo.h : /usr/local/include/c++/3.3.3/bits/stl_heap.h : /usr/local/include/c++/3.3.3/bits/stl_tempbuf.h : /usr/local/include/c++/3.3.3/bits/basic_string.tcc : /usr/local/include/c++/3.3.3/streambuf : /usr/local/include/c++/3.3.3/bits/streambuf.tcc : /usr/local/include/c++/3.3.3/bits/basic_ios.h : /usr/local/include/c++/3.3.3/bits/streambuf_iterator.h : /usr/local/include/c++/3.3.3/bits/locale_facets.h : /usr/local/include/c++/3.3.3/cwctype : /usr/include/wctype.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/ctype_base.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/ctype_inline.h : /usr/local/include/c++/3.3.3/bits/codecvt.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/codecvt_specializations.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/time_members.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/messages_members.h : /usr/local/include/c++/3.3.3/bits/basic_ios.tcc : /usr/local/include/c++/3.3.3/bits/ostream.tcc : /usr/local/include/c++/3.3.3/locale : /usr/local/include/c++/3.3.3/bits/locale_facets.tcc : /usr/local/include/c++/3.3.3/cerrno : /usr/include/errno.h : /usr/include/bits/errno.h : /usr/include/linux/errno.h : /usr/include/asm/errno.h : /usr/local/include/c++/3.3.3/cmath : /usr/include/math.h : /usr/include/bits/huge_val.h : /usr/include/bits/nan.h : /usr/include/bits/mathdef.h : /usr/include/bits/mathcalls.h : /usr/local/include/c++/3.3.3/bits/cmath.tcc : /usr/local/include/c++/3.3.3/limits : /usr/local/include/c++/3.3.3/typeinfo : /usr/local/include/c++/3.3.3/istream : /usr/local/include/c++/3.3.3/bits/istream.tcc : /home/tim/projects/multigig/OpenAccess/oa/include/oaDB.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBase.h : /usr/include/malloc.h : /usr/include/sys/times.h : /usr/include/dirent.h : /usr/include/bits/dirent.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBaseTypes.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBaseModTypes.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBaseMsgs.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaMemory.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaString.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaException.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPoint.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaVector.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSegment.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBox.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPointArray.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOrient.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTransform.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTimeStamp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPackedData.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDir.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaFile.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaMapFile.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaMapWindow.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTimer.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaType.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDomain.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaObject.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaIntProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaFloatProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaStringProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAppProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaHierProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDoubleProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBooleanProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTimeProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaIntRangeProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaFloatRangeProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDoubleRangeProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTimeRangeProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaEnumProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDataCallback.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaGroup.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCallback.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaThread.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaNameSpace.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaName.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAppObjectDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAppDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCdbaNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaNativeNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaLefDefNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSpiceNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSpefNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSpfNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaUnixNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaVerilogNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaVhdlNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaWinNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCollection.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBaseCollection.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDump.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaComplex.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaHashTbl.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaLookupTbl.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTesselator.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaMutex.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDD.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDDMsgs.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDDException.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDDObject.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaFileSys.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaFSDir.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaLib.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCell.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaView.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaFSFile.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaLibFile.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCellFile.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaViewFile.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDDObjectDB.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDDCallback.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDDCollection.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDDDump.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAntennaData.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTC.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTCModTypes.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTCMsgs.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTCObject.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTech.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTCException.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRule.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaLayer.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDerivedLayer.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPhysicalLayer.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPurpose.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSiteDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaViaDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaViaDefArray.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaViaSpec.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteLayerSpec.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteSpec.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOpPoint.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAnalysisLib.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCumulativeRatios.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTechDump.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTCCallback.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTCCollection.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDBModTypes.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDBMsgs.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDBException.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDBObject.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBlockObject.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDBCollection.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaHeaderCollection.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaNetCollection.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTermCollection.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAttrType.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSigType.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSource.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCellView.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBlock.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaScalarNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBusNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBusNetBit.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBusNetDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBundleNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaScalarTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBusTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBusTermBit.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBusTermDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBundleTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaFig.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaLPPHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaLayerHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTextAlign.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaFont.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaInstHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRowHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRow.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaScalarInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaArrayInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaVectorInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaVectorInstDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaShape.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRect.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPolygon.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPath.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDonut.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDot.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaEllipse.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaArc.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaLine.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaText.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTextDisplay.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaViaParam.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteElement.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRoute.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaInstTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaInstPin.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAssignmentDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAssignment.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaConnectDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaHierPath.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRegionQuery.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPin.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTrackPattern.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaMarker.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDBDataCallback.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaParam.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCluster.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBoundary.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBlockage.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaViaHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaScanChainSet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaScanChain.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaScanChainInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSteiner.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCMap.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaGCellPattern.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDBDump.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPinGroup.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAnalysisPoint.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAnalysisOpPoint.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOpPointHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteSpecHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaReducedModel.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPoleResidue.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaLumpedElmore.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPiElmore.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPiPoleResidue.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaElmore.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaNode.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaGroundedNode.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDevice.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaStdDevice.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaResistor.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCouplingCap.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaInductor.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDiode.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSeriesRL.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaMutualInductor.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaParasiticNetwork.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaGuide.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSubNetwork.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteOptimizer.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModObject.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModule.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModCellViewInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModScalarInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModVectorInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModVectorInstDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModInstHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModModuleInstHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModBundleNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusNetBit.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModScalarNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusNetDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModInstTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModBundleTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusTermBit.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModScalarTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusTermDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModConnectDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModAssignment.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModModuleInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModScalarModuleInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModVectorModuleInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccObject.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccurrence.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccCellViewInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccScalarInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccVectorInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccVectorInstDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccInstHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccModuleInstHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBundleNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusNetBit.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccScalarNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusNetDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccInstTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBundleTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusTermBit.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccScalarTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusTermDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccConnectDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccAssignment.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccArrayInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccModuleInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccScalarModuleInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccVectorModuleInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDBCallback.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModCallback.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccCallback.h : magicOA.h : /usr/local/include/tcl.h : /usr/local/include/tclDecls.h : magicInit.h : magic-8.0.210/oa/.deps/magicOA.P0000644000175000001440000013423710751423606014521 0ustar timusersmagicOA.o: magicOA.cpp /usr/local/include/c++/3.3.3/iostream \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/c++config.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/os_defines.h \ /usr/include/features.h /usr/include/sys/cdefs.h \ /usr/include/gnu/stubs.h /usr/local/include/c++/3.3.3/ostream \ /usr/local/include/c++/3.3.3/ios /usr/local/include/c++/3.3.3/iosfwd \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/c++locale.h \ /usr/local/include/c++/3.3.3/clocale /usr/include/locale.h \ /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/stddef.h \ /usr/include/bits/locale.h /usr/include/xlocale.h \ /usr/local/include/c++/3.3.3/cctype /usr/include/ctype.h \ /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \ /usr/include/bits/sched.h /usr/include/endian.h \ /usr/include/bits/endian.h \ /usr/local/include/c++/3.3.3/bits/stringfwd.h \ /usr/local/include/c++/3.3.3/bits/fpos.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/c++io.h \ /usr/local/include/c++/3.3.3/cstdio \ /usr/local/include/c++/3.3.3/cstddef /usr/include/stdio.h \ /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \ /usr/include/bits/wchar.h /usr/include/gconv.h \ /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/stdarg.h \ /usr/include/bits/stdio_lim.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/gthr.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/gthr-default.h \ /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/pthread.h \ /usr/include/sched.h /usr/include/time.h /usr/include/bits/time.h \ /usr/include/signal.h /usr/include/bits/sigset.h \ /usr/include/bits/initspin.h \ /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/bits/sigthread.h \ /usr/include/unistd.h /usr/include/bits/posix_opt.h \ /usr/include/bits/environments.h /usr/include/bits/wordsize.h \ /usr/include/bits/confname.h /usr/include/getopt.h \ /usr/local/include/c++/3.3.3/cwchar /usr/local/include/c++/3.3.3/ctime \ /usr/local/include/c++/3.3.3/bits/functexcept.h \ /usr/local/include/c++/3.3.3/exception_defines.h \ /usr/local/include/c++/3.3.3/exception \ /usr/local/include/c++/3.3.3/bits/char_traits.h \ /usr/local/include/c++/3.3.3/cstring /usr/include/string.h \ /usr/local/include/c++/3.3.3/bits/localefwd.h \ /usr/local/include/c++/3.3.3/bits/ios_base.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/atomicity.h \ /usr/local/include/c++/3.3.3/bits/locale_classes.h \ /usr/local/include/c++/3.3.3/string /usr/local/include/c++/3.3.3/memory \ /usr/local/include/c++/3.3.3/bits/stl_algobase.h \ /usr/local/include/c++/3.3.3/climits \ /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/limits.h \ /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/syslimits.h \ /usr/include/limits.h /usr/include/bits/posix1_lim.h \ /usr/include/bits/local_lim.h /usr/include/linux/limits.h \ /usr/include/bits/posix2_lim.h /usr/include/bits/xopen_lim.h \ /usr/local/include/c++/3.3.3/cstdlib /usr/include/stdlib.h \ /usr/include/bits/waitflags.h /usr/include/bits/waitstatus.h \ /usr/include/sys/types.h /usr/include/sys/select.h \ /usr/include/bits/select.h /usr/include/sys/sysmacros.h \ /usr/include/alloca.h /usr/local/include/c++/3.3.3/new \ /usr/local/include/c++/3.3.3/bits/stl_pair.h \ /usr/local/include/c++/3.3.3/bits/type_traits.h \ /usr/local/include/c++/3.3.3/bits/stl_iterator_base_types.h \ /usr/local/include/c++/3.3.3/bits/stl_iterator_base_funcs.h \ /usr/local/include/c++/3.3.3/bits/concept_check.h \ /usr/local/include/c++/3.3.3/bits/stl_iterator.h \ /usr/local/include/c++/3.3.3/bits/stl_alloc.h \ /usr/local/include/c++/3.3.3/bits/stl_threads.h \ /usr/local/include/c++/3.3.3/bits/stl_construct.h \ /usr/local/include/c++/3.3.3/bits/stl_uninitialized.h \ /usr/local/include/c++/3.3.3/bits/stl_raw_storage_iter.h \ /usr/local/include/c++/3.3.3/bits/stl_function.h \ /usr/local/include/c++/3.3.3/bits/basic_string.h \ /usr/local/include/c++/3.3.3/algorithm \ /usr/local/include/c++/3.3.3/bits/stl_algo.h \ /usr/local/include/c++/3.3.3/bits/stl_heap.h \ /usr/local/include/c++/3.3.3/bits/stl_tempbuf.h \ /usr/local/include/c++/3.3.3/bits/basic_string.tcc \ /usr/local/include/c++/3.3.3/streambuf \ /usr/local/include/c++/3.3.3/bits/streambuf.tcc \ /usr/local/include/c++/3.3.3/bits/basic_ios.h \ /usr/local/include/c++/3.3.3/bits/streambuf_iterator.h \ /usr/local/include/c++/3.3.3/bits/locale_facets.h \ /usr/local/include/c++/3.3.3/cwctype /usr/include/wctype.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/ctype_base.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/ctype_inline.h \ /usr/local/include/c++/3.3.3/bits/codecvt.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/codecvt_specializations.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/time_members.h \ /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/messages_members.h \ /usr/local/include/c++/3.3.3/bits/basic_ios.tcc \ /usr/local/include/c++/3.3.3/bits/ostream.tcc \ /usr/local/include/c++/3.3.3/locale \ /usr/local/include/c++/3.3.3/bits/locale_facets.tcc \ /usr/local/include/c++/3.3.3/cerrno /usr/include/errno.h \ /usr/include/bits/errno.h /usr/include/linux/errno.h \ /usr/include/asm/errno.h /usr/local/include/c++/3.3.3/cmath \ /usr/include/math.h /usr/include/bits/huge_val.h \ /usr/include/bits/nan.h /usr/include/bits/mathdef.h \ /usr/include/bits/mathcalls.h \ /usr/local/include/c++/3.3.3/bits/cmath.tcc \ /usr/local/include/c++/3.3.3/limits \ /usr/local/include/c++/3.3.3/typeinfo \ /usr/local/include/c++/3.3.3/istream \ /usr/local/include/c++/3.3.3/bits/istream.tcc magicOA.h \ /usr/local/include/tcl.h /usr/local/include/tclDecls.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDB.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBase.h \ /usr/include/malloc.h /usr/include/sys/times.h /usr/include/dirent.h \ /usr/include/bits/dirent.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBaseTypes.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBaseModTypes.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBaseMsgs.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaMemory.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaString.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaException.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPoint.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaVector.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSegment.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBox.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPointArray.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOrient.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTransform.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTimeStamp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPackedData.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDir.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaFile.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaMapFile.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaMapWindow.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTimer.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaType.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDomain.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaObject.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaIntProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaFloatProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaStringProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAppProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaHierProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDoubleProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBooleanProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTimeProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaIntRangeProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaFloatRangeProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDoubleRangeProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTimeRangeProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaEnumProp.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDataCallback.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaGroup.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCallback.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaThread.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaNameSpace.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaName.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAppObjectDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAppDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCdbaNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaNativeNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaLefDefNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSpiceNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSpefNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSpfNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaUnixNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaVerilogNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaVhdlNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaWinNS.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCollection.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBaseCollection.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDump.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaComplex.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaHashTbl.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaLookupTbl.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTesselator.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaMutex.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDD.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDDMsgs.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDDException.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDDObject.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaFileSys.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaFSDir.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaLib.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCell.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaView.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaFSFile.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaLibFile.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCellFile.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaViewFile.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDDObjectDB.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDDCallback.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDDCollection.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDDDump.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAntennaData.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTC.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTCModTypes.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTCMsgs.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTCObject.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTech.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTCException.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRule.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaLayer.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDerivedLayer.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPhysicalLayer.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPurpose.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSiteDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaViaDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaViaDefArray.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaViaSpec.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteLayerSpec.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteSpec.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOpPoint.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAnalysisLib.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCumulativeRatios.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTechDump.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTCCallback.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTCCollection.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDBModTypes.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDBMsgs.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDBException.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDBObject.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBlockObject.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDBCollection.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaHeaderCollection.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaNetCollection.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTermCollection.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAttrType.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSigType.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSource.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCellView.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBlock.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaScalarNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBusNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBusNetBit.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBusNetDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBundleNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaScalarTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBusTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBusTermBit.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBusTermDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBundleTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaFig.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaLPPHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaLayerHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTextAlign.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaFont.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaInstHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRowHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRow.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaScalarInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaArrayInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaVectorInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaVectorInstDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaShape.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRect.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPolygon.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPath.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDonut.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDot.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaEllipse.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaArc.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaLine.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaText.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTextDisplay.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaViaParam.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteElement.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRoute.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaInstTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaInstPin.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAssignmentDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAssignment.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaConnectDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaHierPath.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRegionQuery.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPin.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaTrackPattern.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaMarker.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDBDataCallback.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaParam.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCluster.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBoundary.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaBlockage.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaViaHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaScanChainSet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaScanChain.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaScanChainInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSteiner.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCMap.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaGCellPattern.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDBDump.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPinGroup.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAnalysisPoint.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaAnalysisOpPoint.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOpPointHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteSpecHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaReducedModel.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPoleResidue.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaLumpedElmore.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPiElmore.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaPiPoleResidue.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaElmore.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaNode.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaGroundedNode.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDevice.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaStdDevice.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaResistor.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaCouplingCap.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaInductor.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDiode.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSeriesRL.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaMutualInductor.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaParasiticNetwork.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaGuide.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaSubNetwork.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteOptimizer.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModObject.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModule.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModCellViewInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModScalarInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModVectorInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModVectorInstDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModInstHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModModuleInstHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModBundleNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusNetBit.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModScalarNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusNetDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModInstTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModBundleTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusTermBit.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModScalarTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusTermDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModConnectDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModAssignment.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModModuleInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModScalarModuleInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModVectorModuleInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccObject.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccurrence.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccCellViewInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccScalarInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccVectorInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccVectorInstDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccInstHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccModuleInstHeader.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBundleNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusNetBit.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccScalarNet.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusNetDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccInstTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBundleTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusTermBit.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccScalarTerm.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusTermDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccConnectDef.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccAssignment.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccArrayInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccModuleInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccScalarModuleInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccVectorModuleInst.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaDBCallback.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaModCallback.h \ /home/tim/projects/multigig/OpenAccess/oa/include/oaOccCallback.h magicOA.cpp : /usr/local/include/c++/3.3.3/iostream : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/c++config.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/os_defines.h : /usr/include/features.h : /usr/include/sys/cdefs.h : /usr/include/gnu/stubs.h : /usr/local/include/c++/3.3.3/ostream : /usr/local/include/c++/3.3.3/ios : /usr/local/include/c++/3.3.3/iosfwd : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/c++locale.h : /usr/local/include/c++/3.3.3/clocale : /usr/include/locale.h : /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/stddef.h : /usr/include/bits/locale.h : /usr/include/xlocale.h : /usr/local/include/c++/3.3.3/cctype : /usr/include/ctype.h : /usr/include/bits/types.h : /usr/include/bits/pthreadtypes.h : /usr/include/bits/sched.h : /usr/include/endian.h : /usr/include/bits/endian.h : /usr/local/include/c++/3.3.3/bits/stringfwd.h : /usr/local/include/c++/3.3.3/bits/fpos.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/c++io.h : /usr/local/include/c++/3.3.3/cstdio : /usr/local/include/c++/3.3.3/cstddef : /usr/include/stdio.h : /usr/include/libio.h : /usr/include/_G_config.h : /usr/include/wchar.h : /usr/include/bits/wchar.h : /usr/include/gconv.h : /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/stdarg.h : /usr/include/bits/stdio_lim.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/gthr.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/gthr-default.h : /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/pthread.h : /usr/include/sched.h : /usr/include/time.h : /usr/include/bits/time.h : /usr/include/signal.h : /usr/include/bits/sigset.h : /usr/include/bits/initspin.h : /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/bits/sigthread.h : /usr/include/unistd.h : /usr/include/bits/posix_opt.h : /usr/include/bits/environments.h : /usr/include/bits/wordsize.h : /usr/include/bits/confname.h : /usr/include/getopt.h : /usr/local/include/c++/3.3.3/cwchar : /usr/local/include/c++/3.3.3/ctime : /usr/local/include/c++/3.3.3/bits/functexcept.h : /usr/local/include/c++/3.3.3/exception_defines.h : /usr/local/include/c++/3.3.3/exception : /usr/local/include/c++/3.3.3/bits/char_traits.h : /usr/local/include/c++/3.3.3/cstring : /usr/include/string.h : /usr/local/include/c++/3.3.3/bits/localefwd.h : /usr/local/include/c++/3.3.3/bits/ios_base.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/atomicity.h : /usr/local/include/c++/3.3.3/bits/locale_classes.h : /usr/local/include/c++/3.3.3/string : /usr/local/include/c++/3.3.3/memory : /usr/local/include/c++/3.3.3/bits/stl_algobase.h : /usr/local/include/c++/3.3.3/climits : /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/limits.h : /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.3.3/include/syslimits.h : /usr/include/limits.h : /usr/include/bits/posix1_lim.h : /usr/include/bits/local_lim.h : /usr/include/linux/limits.h : /usr/include/bits/posix2_lim.h : /usr/include/bits/xopen_lim.h : /usr/local/include/c++/3.3.3/cstdlib : /usr/include/stdlib.h : /usr/include/bits/waitflags.h : /usr/include/bits/waitstatus.h : /usr/include/sys/types.h : /usr/include/sys/select.h : /usr/include/bits/select.h : /usr/include/sys/sysmacros.h : /usr/include/alloca.h : /usr/local/include/c++/3.3.3/new : /usr/local/include/c++/3.3.3/bits/stl_pair.h : /usr/local/include/c++/3.3.3/bits/type_traits.h : /usr/local/include/c++/3.3.3/bits/stl_iterator_base_types.h : /usr/local/include/c++/3.3.3/bits/stl_iterator_base_funcs.h : /usr/local/include/c++/3.3.3/bits/concept_check.h : /usr/local/include/c++/3.3.3/bits/stl_iterator.h : /usr/local/include/c++/3.3.3/bits/stl_alloc.h : /usr/local/include/c++/3.3.3/bits/stl_threads.h : /usr/local/include/c++/3.3.3/bits/stl_construct.h : /usr/local/include/c++/3.3.3/bits/stl_uninitialized.h : /usr/local/include/c++/3.3.3/bits/stl_raw_storage_iter.h : /usr/local/include/c++/3.3.3/bits/stl_function.h : /usr/local/include/c++/3.3.3/bits/basic_string.h : /usr/local/include/c++/3.3.3/algorithm : /usr/local/include/c++/3.3.3/bits/stl_algo.h : /usr/local/include/c++/3.3.3/bits/stl_heap.h : /usr/local/include/c++/3.3.3/bits/stl_tempbuf.h : /usr/local/include/c++/3.3.3/bits/basic_string.tcc : /usr/local/include/c++/3.3.3/streambuf : /usr/local/include/c++/3.3.3/bits/streambuf.tcc : /usr/local/include/c++/3.3.3/bits/basic_ios.h : /usr/local/include/c++/3.3.3/bits/streambuf_iterator.h : /usr/local/include/c++/3.3.3/bits/locale_facets.h : /usr/local/include/c++/3.3.3/cwctype : /usr/include/wctype.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/ctype_base.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/ctype_inline.h : /usr/local/include/c++/3.3.3/bits/codecvt.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/codecvt_specializations.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/time_members.h : /usr/local/include/c++/3.3.3/i686-pc-linux-gnu/bits/messages_members.h : /usr/local/include/c++/3.3.3/bits/basic_ios.tcc : /usr/local/include/c++/3.3.3/bits/ostream.tcc : /usr/local/include/c++/3.3.3/locale : /usr/local/include/c++/3.3.3/bits/locale_facets.tcc : /usr/local/include/c++/3.3.3/cerrno : /usr/include/errno.h : /usr/include/bits/errno.h : /usr/include/linux/errno.h : /usr/include/asm/errno.h : /usr/local/include/c++/3.3.3/cmath : /usr/include/math.h : /usr/include/bits/huge_val.h : /usr/include/bits/nan.h : /usr/include/bits/mathdef.h : /usr/include/bits/mathcalls.h : /usr/local/include/c++/3.3.3/bits/cmath.tcc : /usr/local/include/c++/3.3.3/limits : /usr/local/include/c++/3.3.3/typeinfo : /usr/local/include/c++/3.3.3/istream : /usr/local/include/c++/3.3.3/bits/istream.tcc : magicOA.h : /usr/local/include/tcl.h : /usr/local/include/tclDecls.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDB.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBase.h : /usr/include/malloc.h : /usr/include/sys/times.h : /usr/include/dirent.h : /usr/include/bits/dirent.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBaseTypes.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBaseModTypes.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBaseMsgs.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaMemory.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaString.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaException.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPoint.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaVector.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSegment.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBox.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPointArray.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOrient.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTransform.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTimeStamp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPackedData.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDir.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaFile.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaMapFile.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaMapWindow.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTimer.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaType.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDomain.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaObject.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaIntProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaFloatProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaStringProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAppProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaHierProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDoubleProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBooleanProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTimeProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaIntRangeProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaFloatRangeProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDoubleRangeProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTimeRangeProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaEnumProp.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDataCallback.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaGroup.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCallback.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaThread.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaNameSpace.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaName.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAppObjectDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAppDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCdbaNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaNativeNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaLefDefNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSpiceNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSpefNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSpfNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaUnixNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaVerilogNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaVhdlNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaWinNS.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCollection.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBaseCollection.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDump.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaComplex.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaHashTbl.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaLookupTbl.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTesselator.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaMutex.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDD.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDDMsgs.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDDException.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDDObject.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaFileSys.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaFSDir.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaLib.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCell.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaView.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaFSFile.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaLibFile.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCellFile.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaViewFile.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDDObjectDB.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDDCallback.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDDCollection.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDDDump.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAntennaData.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTC.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTCModTypes.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTCMsgs.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTCObject.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTech.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTCException.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRule.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaLayer.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDerivedLayer.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPhysicalLayer.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPurpose.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSiteDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaViaDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaViaDefArray.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaViaSpec.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteLayerSpec.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteSpec.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOpPoint.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAnalysisLib.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCumulativeRatios.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTechDump.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTCCallback.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTCCollection.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDBModTypes.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDBMsgs.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDBException.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDBObject.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBlockObject.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDBCollection.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaHeaderCollection.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaNetCollection.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTermCollection.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAttrType.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSigType.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSource.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCellView.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBlock.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaScalarNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBusNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBusNetBit.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBusNetDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBundleNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaScalarTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBusTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBusTermBit.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBusTermDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBundleTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaFig.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaLPPHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaLayerHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTextAlign.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaFont.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaInstHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRowHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRow.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaScalarInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaArrayInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaVectorInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaVectorInstDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaShape.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRect.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPolygon.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPath.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDonut.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDot.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaEllipse.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaArc.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaLine.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaText.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTextDisplay.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaViaParam.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteElement.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRoute.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaInstTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaInstPin.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAssignmentDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAssignment.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaConnectDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaHierPath.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRegionQuery.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPin.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaTrackPattern.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaMarker.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDBDataCallback.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaParam.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCluster.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBoundary.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaBlockage.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaViaHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaScanChainSet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaScanChain.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaScanChainInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSteiner.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCMap.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaGCellPattern.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDBDump.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPinGroup.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAnalysisPoint.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaAnalysisOpPoint.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOpPointHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteSpecHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaReducedModel.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPoleResidue.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaLumpedElmore.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPiElmore.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaPiPoleResidue.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaElmore.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaNode.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaGroundedNode.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDevice.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaStdDevice.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaResistor.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaCouplingCap.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaInductor.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDiode.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSeriesRL.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaMutualInductor.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaParasiticNetwork.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaGuide.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaSubNetwork.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaRouteOptimizer.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModObject.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModule.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModCellViewInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModScalarInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModVectorInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModVectorInstDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModInstHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModModuleInstHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModBundleNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusNetBit.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModScalarNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusNetDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModInstTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModBundleTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusTermBit.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModScalarTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModBusTermDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModConnectDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModAssignment.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModModuleInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModScalarModuleInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModVectorModuleInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccObject.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccurrence.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccCellViewInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccScalarInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccVectorInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccVectorInstDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccInstHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccModuleInstHeader.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBundleNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusNetBit.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccScalarNet.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusNetDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccInstTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBundleTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusTermBit.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccScalarTerm.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccBusTermDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccConnectDef.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccAssignment.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccArrayInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccModuleInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccScalarModuleInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccVectorModuleInst.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaDBCallback.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaModCallback.h : /home/tim/projects/multigig/OpenAccess/oa/include/oaOccCallback.h : magic-8.0.210/oa/magicInit.h0000644000175000001440000000441710751423606014140 0ustar timusers/*******************/ /* Defines */ /*******************/ #ifndef _magicinit_h_ #define _magicinit_h_ #include #if defined(__cplusplus) extern "C" { #endif #define CATCH \ catch (oaException &excp) {\ Tcl_SetObjResult(interp,Tcl_NewStringObj((const oaChar *)excp.getMsg(),-1));\ return TCL_ERROR;\ } #define getArgString(index) Tcl_GetStringFromObj(objv[index],NULL) #define getArgInt(index,Int) Tcl_GetIntFromObj(interp,objv[index],&Int) #define getArgDouble(index,Double) Tcl_GetDoubleFromObj(interp,objv[index],&Double) extern Tcl_Interp *REX_interp; extern FILE *REX_debug_file; #define USE_TCL_STUBS 1 #define TCL_ARGS _ANSI_ARGS_((ClientData clientData, \ Tcl_Interp *interp, int objc, struct Tcl_Obj * CONST * objv)) #define TCLENTRY() {REX_interp = interp;} #define TCLFUNC(name) int name TCL_ARGS #define TCLCMD(name, func) Tcl_CreateObjCommand(REX_interp, name, func, NULL, NULL); //#define TCLLINK(name, addr, type) Tcl_LinkVar(REX_interp, name, addr, type) /* Error Macros */ #define INFO(fmt, msg...) \ do {fprintf(stdout,"%s: ",__FUNCTION__); \ fprintf(stdout,fmt, ## msg); \ fputc('\n',stdout);} while (0) #define WARNING(fmt, msg...) \ do {fprintf(stderr,"Warning in %s at %s:%d: ",__FUNCTION__,__FILE__,__LINE__); \ fprintf(stderr,fmt, ## msg); \ fputc('\n',stderr);} while (0) #define ERROR(fmt, msg...) \ do { fprintf(stderr,"Error in %s at %s:%d:\n",__FUNCTION__,__FILE__,__LINE__); \ fprintf(stderr,fmt, ## msg); \ fputc('\n',stderr); \ abort(); } while(0) #define ASSERT(test) \ do {if(!(test)) ERROR("Assertion: %s", #test );} while (0) extern int __Tcl_Rtn_Error(const char *function,const char *file,unsigned int line, const char *fmt, ...); #define TCL_RTN_ERROR(fmt, msg...) \ do {\ __Tcl_Rtn_Error(__FUNCTION__,__FILE__,__LINE__,fmt, ## msg);\ return TCL_ERROR;\ } while(0) extern int REX_Tcl_Eval(char *fmt, ...); extern int REX_Tcl_Error(const char *fmt, ...); #define TCL_EVAL(fmt, msg...) \ do {\ if(REX_Tcl_Eval(fmt, ## msg) == TCL_ERROR)\ TCL_RTN_ERROR(fmt, ## msg);\ } while(0) #define CHECK_ERR(func) \ if((func) == TCL_ERROR) \ TCL_RTN_ERROR(#func) /* Return Codes */ #define rOK TCL_OK #define rERROR TCL_ERROR #ifndef offsetof #define offsetof(t,m) (int)(&((t*)0)->m) #endif #if defined(__cplusplus) } #endif #endif magic-8.0.210/oa/oa.h0000644000175000001440000000121610751423606012625 0ustar timusers/*--------------------------------------------------------------*/ /* oa.h -- */ /* OpenAccess database support for magic */ /* */ /* Written by R. Timothy Edwards 4/22/04 */ /* Open Circuit Design, Inc. for */ /* MultiGiG, Inc., Scotts Valley, CA */ /*--------------------------------------------------------------*/ #ifndef _OA_H #define _OA_H /* Header file is wrapped in ifdef so include statements don't */ /* need to be. */ #ifdef OPENACCESS /* Internally defined forward declarations */ extern int OACellSearch(); extern int oaTreeCellSrFunc(); /* see DBcellsrch.c */ #endif /* OPENACCESS */ #endif /* _OA_H */ magic-8.0.210/oa/magicOA.cpp0000644000175000001440000002151010751423606014060 0ustar timusers#include #include using namespace std; // current open cell view oaCellView *curCellView; int getTechInfo (const char *techName) { char *argArray[] = {"tclsh"}; int argCount = 1; // initialize OA DB oaDBInit( &argCount, argArray ); // open OA tech DB //oaDefNS ns; oaNativeNS ns; oaScalarName chipTechName(ns, (oaChar *) techName); oaTech *chipTech = oaTech::open(chipTechName); // get route specs from DB cout << "Get route spec info " << endl; oaIter routeSpecIter (chipTech->getRouteSpecs()); while (oaRouteSpec *routeSpec = routeSpecIter.getNext()) { oaString routeSpecName; routeSpec->getName(routeSpecName); cout << "Name: "<< routeSpecName << " width " << routeSpec->isWidthFixed() << " spacing " << routeSpec->isSpacingFixed() << endl; oaRouteLayerSpecArray routeLayerSpecArray; routeSpec->getLayerSpecs(routeLayerSpecArray); oaString routeLayerName; cout <<"Route layer specs" << endl; for (int i = 0; i < routeLayerSpecArray.getNumValues(); i++) { oaRouteLayerSpec routeLayerSpec = routeLayerSpecArray[i]; oaPhysicalLayer *routeLayer = routeLayerSpec.layer(); routeLayer->getName(routeLayerName); cout << "Route layer name: " << routeLayerName << endl; cout << " width - " << routeLayerSpec.width() << "\n" << " spacing - " << routeLayerSpec.spacing() << "\n" << " diag width - " << routeLayerSpec.diagWidth() << "\n" << " diag spacing - " << routeLayerSpec.diagSpacing() << "\n" << " wire ext - " << routeLayerSpec.wireExt() << endl; } } // get layer info from DB cout << "Get Layer info " << endl; oaIter layerIter (chipTech->getLayers()); cout << "Number of layers " << (chipTech->getLayers()).getCount() << endl; while (oaLayer *layer = layerIter.getNext()) { oaString layerName; oaString purposeName; layer->getName(layerName); cout << "Layer name: " << layerName << ", layer number: " << layer->getNumber() << endl; if (oaPhysicalLayer *phyLayer = oaPhysicalLayer::find(chipTech, layer->getNumber())) { cout << "Physical layer name:\n" << " routing grid pitch - " << phyLayer->getRouteGridPitch() << "\n" << " routing grid offset - " << phyLayer->getRouteGridOffset() << "\n" << " preferred routing dir - " << (phyLayer->getPrefRoutingDir()).getName() << "\n" << " manufacturing grid - " << phyLayer->getManufacturingGrid() << "\n" << endl; } } // get cell height - use site def info cout << "Get site def info" << endl; oaIter siteDefIter = chipTech->getSiteDefs(); cout << "Number of sites " << (chipTech->getSiteDefs()).getCount() << endl; while (oaSiteDef *siteDef = siteDefIter.getNext()) { oaSiteDefType siteDefType = siteDef->getSiteDefType(); cout << " Type - " << siteDefType.getName() << "\n" << " Cell height - " << siteDef->getHeight() << endl; } chipTech->close(); return 0; } int getUserUnit(const char *techName, char *userUnit, ClientData *cdarg, int (*magicFunc)(const char *techName, char *userUnit, ClientData *cdarg), oaCellViewType viewType) { // open OA tech DB oaNativeNS ns; //oaString userUnit; oaScalarName chipTechName(ns, (oaChar *) techName); oaTech *chipTech = oaTech::open(chipTechName); switch (chipTech->getUserUnits(viewType)) { case oacMicron: //userUnit = "micron"; strcpy(userUnit, "micron"); break; case oacMillimeter: //userUnit = "millimeter"; strcpy(userUnit, "millimeter"); break; case oacCentimeter: //userUnit = "centimeter"; strcpy(userUnit, "centimeter"); break; case oacMeter: //userUnit = "meter"; strcpy(userUnit, "meter"); break; case oacMil: //userUnit = "mil"; strcpy(userUnit, "mil"); break; case oacInch: //userUnit = "inch"; strcpy(userUnit, "inch"); break; case oacNanometer: //userUnit = "nanometer"; break; strcpy(userUnit, "nanometer"); default: //userUnit = "none"; strcpy(userUnit, "none"); } //cout << "getTechUserUnit " << userUnit << endl; if (magicFunc) magicFunc(techName, userUnit, cdarg); return 0; } int getDBUnitsPerUserUnit(const char *techName, int &dbUPerUU, ClientData *cdarg, int (*magicFunc) (const char *techName, int &dbUPerUU, ClientData *cdarg), oaCellViewType viewType) { // open OA tech DB oaNativeNS ns; oaScalarName chipTechName(ns, (oaChar *) techName); oaTech *chipTech = oaTech::open(chipTechName); dbUPerUU = chipTech->getDBUPerUU(viewType); //cout << "getTechDBUnitsPerUserUnit " << dbUPerUU < cellViewIter = oaCellView::getOpenCellViews(); while (oaCellView *cellView = cellViewIter.getNext()) { cv = cellView; } if (cv) { oaString cellName; cv->getCellName(ns, cellName); cout << "Current open cell set to " << cellName << endl; } else { cout << "No open cell view" << endl; } return cv; } int closeDesign(const char *lib, const char *cell, const char *view) { // init namespace oaNativeNS ns; oaScalarName libName(ns, lib); oaScalarName cellName(ns, cell); oaScalarName viewName(ns, view); oaCellView *cellView = oaCellView::find(libName, cellName, viewName); // valid open cell view found, so close if (cellView) { cout << "Close cell " << cell << " " << view << endl; cellView->close(); curCellView = getPrevCV(); } return 0; } int closeDesign() { oaNativeNS ns; oaString cellName; // check for valid cell if (curCellView) { curCellView->getCellName(ns, cellName); cout << "Close cell " << cellName << endl; curCellView->close(); curCellView = getPrevCV(); } else { cout << "No cell view currently open" << endl; } return 0; } int closeAll() { oaIter cellViewIter = oaCellView::getOpenCellViews(); while (oaCellView *cellView = cellViewIter.getNext()) { cellView->close(); } curCellView = NULL; return 0; } int getBoundingBox (oaInst *instPtr, const char *instanceName, const char *defName, int (*magicFunc)(const char *instName, const char *defName, int llx, int lly, int urx, int ury, const char *curName, ClientData *cdarg), ClientData *cdarg, int callBack) { oaNativeNS ns; oaCellView *cellView; oaString instMagicName(instanceName); oaBlock *topBlock; oaInst *inst = (oaInst *)instPtr; int loccallback = callBack; // on first call, use current open cell view if (inst == NULL) { oaBox bBox; //oaIter cellViewIter = oaCellView::getOpenCellViews(); if (curCellView) { cout << "Using open cell view" << endl; cellView = curCellView; } else { cout << "No cellview open" << endl; return 1; } topBlock = cellView->getTopBlock(); topBlock->getBBox(bBox); cout << "Layout size " << bBox.left() << "," << bBox.bottom() << " - " << bBox.right() << "," << bBox.top() << endl; } else { oaBox bBox; oaString instName; oaPoint instOrigin; inst->getName(ns, instName); cout << "instName " << instName << endl; if (instName == instMagicName) loccallback = TRUE; if (loccallback) { inst->getOrigin(instOrigin); try { cellView = inst->getMaster(); } catch (oaDBException dbErr) { cout << "error in getMaster" << endl; return 1; } try { topBlock = cellView->getTopBlock(); } catch (oaDBException dbErr) { cout << "error in getTopBlock" << endl; return 1; } topBlock->getBBox(bBox); //call magic function // magicFunc (instanceName, defName, // bBox.left() + instOrigin.x(), bBox.bottom() + instOrigin.y(), // bBox.right() + instOrigin.x(), bBox.top() + instOrigin.y(), // instName, cdarg); cout << "instName " << instName << ", bbox: (" << bBox.left() << ", " << bBox.bottom() << "), (" << bBox.right() << ", " << bBox.top() << ")" << endl; } } oaIter instIter = topBlock->getInsts(); while (oaInst *inst = instIter.getNext()) { getBoundingBox(inst, instanceName, defName, magicFunc, cdarg, loccallback); } return 0; } magic-8.0.210/oa/magicOA.h0000644000175000001440000000212110751423606013522 0ustar timusers#ifndef TECHINFO_H #define TECHINFO_H #include #include // Functions implemented for OA DB access and query int getTechInfo(const char *techName); int getUserUnit(const char *techName, char *userUnit, ClientData *cdarg, int (*magicFunc) (const char *techName, char *userUnit, ClientData *cdarg) = NULL, oaCellViewType viewType=oacMaskLayout); int getDBUnitsPerUserUnit(const char *techName, int &dbUPerUU, ClientData *cdarg, int (*magicFunc) (const char *techName, int &dbUPerUU, ClientData *cdarg) = NULL, oaCellViewType viewType=oacMaskLayout); int openDesign(const char *libName, const char *cellName, const char *viewName); int closeDesign(const char *libName, const char *cellName, const char *viewName); int closeDesign(); int closeAll(); int getBoundingBox (oaInst *instPtr, const char *instanceName, const char *defName, int (*magicFunc) (const char *instName, const char *defName, int llx, int lly, int urx, int ury, const char *curName, ClientData *cdarg), ClientData *cdarg, int callBack); #endif magic-8.0.210/oa/magicInit.cpp0000644000175000001440000001457110751423606014475 0ustar timusers#include #include #include #include using namespace std; Tcl_Interp *REX_interp; FILE *REX_debug_file; // get_user_unit callback int techUserUnit(const char *techName, char *userUnit, ClientData *cdarg) { cout << " callback func - techUserUnit : result - " << userUnit << endl; return 0; } // get_db_units_per_user_unit callback int techDBUPerUU(const char *techName, int &dbUPerUU, ClientData *cdarg) { cout << " callback func - techDBUPerUU : result - " << dbUPerUU << endl; return 0; } // get_boundin_box callback int boundingBoxInfo(const char *instName, const char *defName, int llx, int lly, int urx, int ury, const char *curName, ClientData *cdarg) { cout << " callback func boundingBoxInfo : result - " << curName << "\n bounding box " << llx << " " << lly << " " << urx << " " << ury << endl; return 0; } int __Tcl_Rtn_Error(const char *function,const char *file,unsigned int line, const char *fmt, ...) { char *buf; int chars1,chars2; va_list msg; va_start(msg,fmt); chars1 = snprintf(NULL,0,"Error in %s at %s:%d: ",function,file,line); chars2 = vsnprintf(NULL,0,fmt,msg); buf = (char *)malloc(chars1 + chars2 + 1); sprintf(buf,"Error in %s at %s:%d: ",function,file,line); vsprintf(buf+chars1,fmt,msg); fputs(buf,stderr); fputc('\n',stderr); Tcl_SetResult(REX_interp, buf,(Tcl_FreeProc *) free); return TCL_OK; } int REX_Tcl_Error(const char *fmt, ...) { char *buf; int chars; va_list msg; va_start(msg,fmt); chars = vsnprintf(NULL,0,fmt,msg); buf = (char *)malloc(chars+1); vsprintf(buf,fmt,msg); Tcl_SetResult(REX_interp, buf,(Tcl_FreeProc *) free); return TCL_OK; } int REX_Tcl_Eval(char *fmt, ...) { static char buf2[256]; char *ptr2=buf2; int nchars, rtn; va_list msg; va_start(msg,fmt); nchars = vsnprintf(ptr2,256,fmt,msg); if(nchars >= 256) { ptr2 = (char *)malloc(nchars+1); vsprintf(ptr2,fmt,msg); } if(REX_debug_file) { fputs(ptr2,REX_debug_file); fputc('\n',REX_debug_file); fflush(REX_debug_file); } rtn = Tcl_Eval(REX_interp, (char *)ptr2); if(nchars >= 256) free(ptr2); return rtn; } void helpPrint(); void helpInfo(const char *cmdStr); TCLFUNC(print_tech_info) { TCLENTRY(); if(objc != 2) TCL_RTN_ERROR("Usage: %s tech",getArgString(0)); try { getTechInfo(getArgString(1)); } CATCH return TCL_OK; } TCLFUNC(get_user_unit) { TCLENTRY(); char uUnit[32]; if(objc != 2) TCL_RTN_ERROR("Usage: %s tech",getArgString(0)); try { getUserUnit(getArgString(1), uUnit, NULL, techUserUnit); Tcl_Obj *strResult = Tcl_NewStringObj(uUnit, strlen(uUnit)); //Tcl_SetResult(REX_interp, uUnit, TCL_STATIC); Tcl_SetObjResult(REX_interp, strResult); } CATCH return TCL_OK; } TCLFUNC(get_db_units_per_user_unit) { TCLENTRY(); int dbUPerUU; if(objc != 2) TCL_RTN_ERROR("Usage: %s tech",getArgString(0)); try { getDBUnitsPerUserUnit(getArgString(1), dbUPerUU, NULL, techDBUPerUU); Tcl_Obj *intResult = Tcl_NewIntObj(dbUPerUU); Tcl_SetObjResult(REX_interp, intResult); } CATCH return TCL_OK; } TCLFUNC(open_cell) { TCLENTRY(); int cvIndex; if(objc != 4) TCL_RTN_ERROR("Usage: %s lib cell view",getArgString(0)); try { openDesign(getArgString(1), getArgString(2), getArgString(3)); //cvIndex = openDesign(getArgString(1), getArgString(2), getArgString(3)); //Tcl_Obj *intResult = Tcl_NewIntObj(cvIndex); //Tcl_SetObjResult(REX_interp, intResult); } CATCH return TCL_OK; } TCLFUNC(close_cell) { TCLENTRY(); int cellIndex; if((objc != 4)) TCL_RTN_ERROR("Usage: %s lib cell view", getArgString(0)); try { closeDesign(getArgString(1), getArgString(2), getArgString(3)); } CATCH return TCL_OK; } TCLFUNC(close_current_cell) { TCLENTRY(); if((objc != 1)) TCL_RTN_ERROR("Usage: %s",getArgString(0)); try { closeDesign(); } CATCH return TCL_OK; } TCLFUNC(close_all_cells) { TCLENTRY(); if((objc != 1)) TCL_RTN_ERROR("Usage: %s",getArgString(0)); try { closeAll(); } CATCH return TCL_OK; } TCLFUNC(get_bounding_box) { char *defstring; char *inststring; int callback = 0; TCLENTRY(); if (objc < 3) defstring = "dummy_def"; else defstring = getArgString(2); if (objc < 2) { inststring = "dummy_inst"; callback = 1; } else inststring = getArgString(1); try { getBoundingBox(NULL, inststring, defstring, boundingBoxInfo, NULL, callback); } CATCH return TCL_OK; } TCLFUNC(help) { TCLENTRY(); if (objc == 2) { helpInfo(getArgString(1)); return TCL_OK; } try { helpPrint(); } CATCH return TCL_OK; } struct tclCmd { Tcl_ObjCmdProc * cmd; char *name; char *help; }; static const struct tclCmd tclCmds[] = { // Help {help, "help", NULL}, // MAGIC API {print_tech_info, "print_tech_info", "tech"}, {get_user_unit, "get_user_unit", "tech"}, {get_db_units_per_user_unit, "get_db_units_per_user_unit", "tech"}, {open_cell, "open_cell", "lib cell view"}, {close_cell, "close_cell", "lib cell view"}, {close_current_cell, "close_current_cell", ""}, {close_all_cells, "close_all_cells", ""}, {get_bounding_box, "get_bounding_box", "inst def"} }; #define tclCmdsNum (sizeof(tclCmds) / sizeof(struct tclCmd)) void helpPrint() { printf ("help \n"); printf ("where cmd is one of \n"); for(unsigned int i = 1; i < tclCmdsNum ; i++) { printf(" %-24s", tclCmds[i].name); if (i%3 == 0) printf("\n"); } printf("\n"); } void helpInfo(const char *cmdStr) { for(unsigned int i = 1; i < tclCmdsNum ; i++) { if (!strcmp(cmdStr, tclCmds[i].name)) { if (tclCmds[i].help) { printf("Usage: %s %s\n", cmdStr, tclCmds[i].help); } else { printf("Help not implemented\n"); } } } } extern "C" { int Magicoa_Init(Tcl_Interp *interp) { if (interp == 0) return TCL_ERROR; TCLENTRY(); Tcl_PkgProvide(interp, "magicOA", "0.1"); #ifdef USE_TCL_STUBS if(Tcl_InitStubs(interp, (char *)"8.1",0) == NULL) return TCL_ERROR; #endif try { int args=1; char *argv[] = {"tclsh"}; oaDBInit(&args, argv); } CATCH for(unsigned int i = 0; i < tclCmdsNum ; i++) { TCLCMD(tclCmds[i].name,tclCmds[i].cmd); } //initLink(interp); return TCL_OK; } } /* extern "C" */ magic-8.0.210/calma/0000755000175000001440000000000012364011344012525 5ustar timusersmagic-8.0.210/calma/CalmaRdpt.c0000664000175000001440000006257012146764314014566 0ustar timusers/* * CalmaReadpaint.c -- * * Input of Calma GDS-II stream format. * Processing of paint (paths, boxes, and boundaries) and text. * * ********************************************************************* * * 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/calma/CalmaRdpt.c,v 1.7 2010/08/25 17:33:54 tim Exp $"; #endif /* not lint */ #include #include /* for abs() */ #include /* for strlen() */ #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/utils.h" #include "utils/hash.h" #include "database/database.h" #include "database/databaseInt.h" #include "utils/malloc.h" #include "utils/tech.h" #include "cif/cif.h" #include "cif/CIFint.h" #include "cif/CIFread.h" #include "utils/signals.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "utils/styles.h" #include "textio/textio.h" #include "calma/calmaInt.h" #include "calma/calma.h" extern int calmaNonManhattan; extern int CalmaPolygonCount; extern HashTable calmaDefInitHash; extern void calmaLayerError(); bool calmaReadPath(); /* * ---------------------------------------------------------------------------- * * calmaInputRescale --- * * This routine does the same thing as CIFInputRescale(). However, * the "gds flatten" option allows us to retain GDS layout * information in the cd_client record of a cell def. If we * change the GDS input scale factor, then all of these saved * layouts need to be rescaled. * * Results: * None. * * Side effects: * Reallocates memory for layout planes in each of the cells in * the database that have the CDFLATGDS flag set. * * ---------------------------------------------------------------------------- */ void calmaInputRescale(n, d) int n, d; { HashEntry *h; HashSearch hs; CellDef *def; HashStartSearch(&hs); while (TRUE) { h = HashNext(&CifCellTable, &hs); if (h == NULL) break; def = (CellDef *) HashGetValue(h); if (def == NULL) continue; /* shouldn't happen */ if (def->cd_flags & CDFLATGDS) { /* Scale the GDS planes in this cell's cd_client record */ Plane **gdsplanes = (Plane **)def->cd_client; CIFScalePlanes(n, d, gdsplanes); } } CIFInputRescale(n, d); } /* * ---------------------------------------------------------------------------- * * calmaReadPoint --- * * Read a point from the input. * We take care of scaling by calmaReadScale1/calmaReadScale2. * Also take care of noting when the scaling results in a sub-integer * value, and rescaling everything appropriately. "iscale" is an * integer scaling value used to return values at, for instance, double * the scale, as for a path centerline. * * Results: * None. * * Side effects: * The Point pointed to by parameter "p" is filled with the * coordinates of the point. If a fractional integer is * encountered, then everything in the GDS planes is rescaled * to match. * * ---------------------------------------------------------------------------- */ void calmaReadPoint(p, iscale) Point *p; int iscale; { int rescale; READI4((p)->p_x); p->p_x *= (calmaReadScale1 * iscale); if ((iscale != 0) && (p->p_x % calmaReadScale2 != 0)) { rescale = calmaReadScale2 / FindGCF(calmaReadScale2, abs(p->p_x)); if ((calmaReadScale1 * rescale) > CIFRescaleLimit) { calmaReadError("Warning: calma units at max scale; value rounded\n"); if (p->p_x < 0) p->p_x -= ((calmaReadScale2 - 1) >> 1); else p->p_x += (calmaReadScale2 >> 1); } else { calmaReadScale1 *= rescale; calmaInputRescale(rescale, 1); p->p_x *= rescale; } } p->p_x /= calmaReadScale2; READI4((p)->p_y); p->p_y *= (calmaReadScale1 * iscale); if ((iscale != 0) && (p->p_y % calmaReadScale2 != 0)) { rescale = calmaReadScale2 / FindGCF(calmaReadScale2, abs(p->p_y)); if ((calmaReadScale1 * rescale) > CIFRescaleLimit) { calmaReadError("Warning: calma units at max scale; value rounded\n"); if (p->p_y < 0) p->p_y -= ((calmaReadScale2 - 1) >> 1); else p->p_y += (calmaReadScale2 >> 1); } else { calmaReadScale1 *= rescale; calmaInputRescale(rescale, 1); p->p_x *= rescale; p->p_y *= rescale; } } p->p_y /= calmaReadScale2; } /* * ---------------------------------------------------------------------------- * * calmaElementBoundary -- * * Read a polygon. * * Results: * None. * * Side effects: * Paints one or more rectangles into one of the CIF planes. * * ---------------------------------------------------------------------------- */ void calmaElementBoundary() { int dt, layer, ciftype; CIFPath *pathheadp; LinkedRect *rp; Plane *plane; CellUse *use; CellDef *savedef, *newdef = NULL; /* Skip CALMA_ELFLAGS, CALMA_PLEX */ calmaSkipSet(calmaElementIgnore); /* Read layer and data type */ if (!calmaReadI2Record(CALMA_LAYER, &layer) || !calmaReadI2Record(CALMA_DATATYPE, &dt)) { calmaReadError("Missing layer or datatype in boundary/box.\n"); return; } /* Set current plane */ ciftype = CIFCalmaLayerToCifLayer(layer, dt, cifCurReadStyle); if (ciftype < 0) { plane = NULL; calmaLayerError("Unknown layer/datatype in boundary", layer, dt); } else plane = cifCurReadPlanes[ciftype]; /* Read the path itself, building up a path structure */ if (!calmaReadPath(&pathheadp, (plane == NULL) ? 0 : 1)) { if (plane != NULL) calmaReadError("Error while reading path for boundary/box; ignored.\n"); return; } /* Note that calmaReadPath() may reallocate planes of cifCurReadPlanes */ /* so we need to set it again. */ if (ciftype >= 0) plane = cifCurReadPlanes[ciftype]; /* Convert the polygon to rectangles. */ if (CalmaSubcellPolygons && (calmaNonManhattan > 0)) { /* Place the polygon in its own subcell */ char newname[] = "polygonXXXXX"; HashEntry *he; savedef = cifReadCellDef; /* Make up name for cell */ sprintf(newname + 7, "%05d", ++CalmaPolygonCount); he = HashFind(&calmaDefInitHash, newname); if (!HashGetValue(he)) { newdef = calmaFindCell(newname, NULL); cifReadCellDef = newdef; DBCellClearDef(cifReadCellDef); DBCellSetAvail(cifReadCellDef); /* cifEditCellPlanes is not used by the gds reader, so it's */ /* available to be used to store the polygon. */ cifCurReadPlanes = cifEditCellPlanes; if (plane != NULL) plane = cifCurReadPlanes[ciftype]; } } rp = CIFPolyToRects(pathheadp, plane, CIFPaintTable, (PaintUndoInfo *)NULL); CIFFreePath(pathheadp); /* Paint the rectangles (if any) */ for (; rp != NULL ; rp = rp->r_next) { if (plane) DBPaintPlane(plane, &rp->r_r, CIFPaintTable, (PaintUndoInfo *)NULL); freeMagic((char *) rp); } if (cifCurReadPlanes == cifEditCellPlanes) { CIFPaintCurrent(); DBReComputeBbox(cifReadCellDef); DRCCheckThis(cifReadCellDef, TT_CHECKPAINT, &cifReadCellDef->cd_bbox); DBWAreaChanged(cifReadCellDef, &cifReadCellDef->cd_bbox, DBW_ALLWINDOWS, &DBAllButSpaceBits); DBCellSetModified(cifReadCellDef, TRUE); DBGenerateUniqueIds(cifReadCellDef, FALSE); /* Is this necessary? */ cifCurReadPlanes = cifSubcellPlanes; cifReadCellDef = savedef; use = DBCellNewUse(newdef, (char *)NULL); DBSetTrans(use, &GeoIdentityTransform); DBPlaceCell(use, cifReadCellDef); } } /* * ---------------------------------------------------------------------------- * * calmaElementBox -- * * Read a box. * This is an optimized version of calmaElementBoundary * that handles rectangular polygons. These polygons each * have five vertex points, with the first and last point * being the same, and all sides parallel to one of the two * coordinate axes. * * Results: * None. * * Side effects: * Paints one rectangle into one of the CIF planes. * * ---------------------------------------------------------------------------- */ void calmaElementBox() { int nbytes, rtype, npoints, savescale; int dt, layer, ciftype; Plane *plane; Point p; Rect r; /* Skip CALMA_ELFLAGS, CALMA_PLEX */ calmaSkipSet(calmaElementIgnore); /* Read layer and data type */ if (!calmaReadI2Record(CALMA_LAYER, &layer) || !calmaReadI2Record(CALMA_BOXTYPE, &dt)) { calmaReadError("Missing layer or datatype in boundary/box.\n"); return; } /* Set current plane */ ciftype = CIFCalmaLayerToCifLayer(layer, dt, cifCurReadStyle); if (ciftype < 0) { calmaLayerError("Unknown layer/datatype in box", layer, dt); return; } else plane = cifCurReadPlanes[ciftype]; /* * Read the path itself. * Since it is Manhattan, we can build our rectangle directly. */ r.r_xbot = r.r_ybot = INFINITY; r.r_xtop = r.r_ytop = MINFINITY; /* Read the record header */ READRH(nbytes, rtype); if (nbytes < 0) { calmaReadError("EOF when reading box.\n"); return; } if (rtype != CALMA_XY) { calmaUnexpected(CALMA_XY, rtype); return; } /* Read this many points (pairs of four-byte integers) */ npoints = (nbytes - CALMAHEADERLENGTH) / 8; if (npoints != 5) { calmaReadError("Box doesn't have 5 points.\n"); (void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH); return; } while (npoints-- > 0) { savescale = calmaReadScale1; calmaReadPoint(&p, 1); if (savescale != calmaReadScale1) { int newscale = calmaReadScale1 / savescale; r.r_xbot *= newscale; r.r_xtop *= newscale; r.r_ybot *= newscale; r.r_ytop *= newscale; } if (p.p_x < r.r_xbot) r.r_xbot = p.p_x; if (p.p_y < r.r_ybot) r.r_ybot = p.p_y; if (p.p_x > r.r_xtop) r.r_xtop = p.p_x; if (p.p_y > r.r_ytop) r.r_ytop = p.p_y; } /* Paint the rectangle */ DBPaintPlane(plane, &r, CIFPaintTable, (PaintUndoInfo *)NULL); } /* * ---------------------------------------------------------------------------- * * calmaElementPath -- * * Read a centerline wire. * * Results: * None. * * Side effects: * May paint rectangles into CIF planes. * * ---------------------------------------------------------------------------- */ void calmaElementPath() { int nbytes, rtype, extend1, extend2; int layer, dt, width, pathtype, ciftype, savescale; int xmin, ymin, xmax, ymax, temp; CIFPath *pathheadp, *pathp, *previousp; Rect segment; Plane *plane; int first,last; CellUse *use; CellDef *savedef, *newdef = NULL; /* Skip CALMA_ELFLAGS, CALMA_PLEX */ calmaSkipSet(calmaElementIgnore); /* Grab layer and datatype */ if (!calmaReadI2Record(CALMA_LAYER, &layer)) return; if (!calmaReadI2Record(CALMA_DATATYPE, &dt)) return; /* Describes the shape of the ends of the path */ pathtype = CALMAPATH_SQUAREFLUSH; PEEKRH(nbytes, rtype); if (nbytes > 0 && rtype == CALMA_PATHTYPE) if (!calmaReadI2Record(CALMA_PATHTYPE, &pathtype)) return; if (pathtype != CALMAPATH_SQUAREFLUSH && pathtype != CALMAPATH_SQUAREPLUS) { calmaReadError("Warning: pathtype %d unsupported (ignored).\n", pathtype); pathtype = CALMAPATH_SQUAREFLUSH; } /* * Width of this path. * Allow zero-width paths; we will ignore them later. */ width = 0; PEEKRH(nbytes, rtype) if (nbytes > 0 && rtype == CALMA_WIDTH) { if (!calmaReadI4Record(CALMA_WIDTH, &width)) { calmaReadError("Error in reading WIDTH in calmaElementPath()\n") ; return; } } width *= calmaReadScale1; if (width % calmaReadScale2 != 0) calmaReadError("Wire width snapped to nearest integer boundary.\n"); width /= calmaReadScale2; /* Handle BGNEXTN, ENDEXTN */ extend1 = extend2 = 0; PEEKRH(nbytes, rtype); if (nbytes > 0 && rtype == CALMA_BGNEXTN) { if (!calmaReadI4Record(CALMA_BGNEXTN, &extend1)) calmaReadError("Error in reading BGNEXTN in path (ignored)\n") ; else { extend1 *= calmaReadScale1; if (extend1 % calmaReadScale2 != 0) calmaReadError("Wire extension snapped to nearest integer boundary.\n"); extend1 *= 2; extend1 /= calmaReadScale2; } } PEEKRH(nbytes, rtype); if (nbytes > 0 && rtype == CALMA_ENDEXTN) { if (!calmaReadI4Record(CALMA_ENDEXTN, &extend2)) calmaReadError("Error in reading ENDEXTN in path (ignored)\n") ; else { extend2 *= calmaReadScale1; if (extend2 % calmaReadScale2 != 0) calmaReadError("Wire extension snapped to nearest integer boundary.\n"); extend2 *= 2; extend2 /= calmaReadScale2; } } /* Read the points in the path */ savescale = calmaReadScale1; if (!calmaReadPath(&pathheadp, 2)) { calmaReadError("Improper path; ignored.\n"); return; } if (savescale != calmaReadScale1) { width *= (calmaReadScale1 / savescale); extend1 *= (calmaReadScale1 / savescale); extend2 *= (calmaReadScale1 / savescale); } /* Create path end extensions */ if (extend1 > 0) { if (pathheadp->cifp_x > pathheadp->cifp_next->cifp_x) pathheadp->cifp_x += extend1; else if (pathheadp->cifp_x < pathheadp->cifp_next->cifp_x) pathheadp->cifp_x -= extend1; if (pathheadp->cifp_y > pathheadp->cifp_next->cifp_y) pathheadp->cifp_y += extend1; else if (pathheadp->cifp_y < pathheadp->cifp_next->cifp_y) pathheadp->cifp_y -= extend1; } if (extend2 > 0) { pathp = pathheadp; while (pathp && pathp->cifp_next && pathp->cifp_next->cifp_next) pathp = pathp->cifp_next; if (pathp && pathp->cifp_next) { if (pathp->cifp_x > pathp->cifp_next->cifp_x) pathp->cifp_next->cifp_x -= extend2; else if (pathp->cifp_x < pathp->cifp_next->cifp_x) pathp->cifp_next->cifp_x += extend2; if (pathp->cifp_y > pathp->cifp_next->cifp_y) pathp->cifp_next->cifp_y -= extend2; else if (pathp->cifp_y < pathp->cifp_next->cifp_y) pathp->cifp_next->cifp_y += extend2; } } /* Don't process zero-width paths any further */ if (width <= 0) { CIFFreePath(pathheadp); return; } /* Make sure we know about this type */ ciftype = CIFCalmaLayerToCifLayer(layer, dt, cifCurReadStyle); if (ciftype < 0) { calmaLayerError("Unknown layer/datatype in path", layer, dt); CIFFreePath(pathheadp); } else { plane = cifCurReadPlanes[ciftype]; if (CalmaSubcellPolygons && (calmaNonManhattan > 0)) { /* Place the polygon in its own subcell */ char newname[] = "polygonXXXXX"; HashEntry *he; savedef = cifReadCellDef; /* Make up name for cell */ sprintf(newname + 7, "%05d", ++CalmaPolygonCount); he = HashFind(&calmaDefInitHash, newname); if (!HashGetValue(he)) { newdef = calmaFindCell(newname, NULL); cifReadCellDef = newdef; DBCellClearDef(cifReadCellDef); DBCellSetAvail(cifReadCellDef); /* cifEditCellPlanes is not used by the gds reader, so it's */ /* available to be used to store the polygon. */ cifCurReadPlanes = cifEditCellPlanes; if (plane != NULL) plane = cifCurReadPlanes[ciftype]; } } CIFPaintWirePath(pathheadp, width, (pathtype == CALMAPATH_SQUAREFLUSH) ? FALSE : TRUE, plane, CIFPaintTable, (PaintUndoInfo *)NULL); if (cifCurReadPlanes == cifEditCellPlanes) { CIFPaintCurrent(); DBReComputeBbox(cifReadCellDef); DRCCheckThis(cifReadCellDef, TT_CHECKPAINT, &cifReadCellDef->cd_bbox); DBWAreaChanged(cifReadCellDef, &cifReadCellDef->cd_bbox, DBW_ALLWINDOWS, &DBAllButSpaceBits); DBCellSetModified(cifReadCellDef, TRUE); DBGenerateUniqueIds(cifReadCellDef, FALSE); /* Is this necessary? */ cifCurReadPlanes = cifSubcellPlanes; cifReadCellDef = savedef; use = DBCellNewUse(newdef, (char *)NULL); DBSetTrans(use, &GeoIdentityTransform); DBPlaceCell(use, cifReadCellDef); } } } /* * ---------------------------------------------------------------------------- * * calmaElementText -- * * Read labels. * * Results: * None. * * Side effects: * Add labels to our label list. * * ---------------------------------------------------------------------------- */ void calmaElementText() { static int ignore[] = { CALMA_PATHTYPE, CALMA_WIDTH, -1 }; char *textbody = NULL; int nbytes, rtype; int layer, textt, cifnum; TileType type; Rect r; unsigned short textpres; double dval; int size, angle, font, pos; /* Skip CALMA_ELFLAGS, CALMA_PLEX */ calmaSkipSet(calmaElementIgnore); /* Grab layer and texttype */ if (!calmaReadI2Record(CALMA_LAYER, &layer)) return; if (!calmaReadI2Record(CALMA_TEXTTYPE, &textt)) return; cifnum = CIFCalmaLayerToCifLayer(layer, textt, cifCurReadStyle); if (cifnum < 0) { if(cifCurReadStyle->crs_flags & CRF_IGNORE_UNKNOWNLAYER_LABELS) type = -1; else { calmaLayerError("Label on unknown layer/datatype", layer, textt); type = TT_SPACE; } } else type = cifCurReadStyle->crs_labelLayer[cifnum]; font = -1; angle = 0; /* Default size is 1um */ size = (int)((800 * cifCurReadStyle->crs_multiplier) / cifCurReadStyle->crs_scaleFactor); /* Default position is bottom-right (but what the spec calls "top-left"!) */ pos = GEO_SOUTHEAST; /* Parse presentation and magnitude/angle part of transform */ /* Skip pathtype and width */ PEEKRH(nbytes, rtype); if (nbytes > 0 && rtype == CALMA_PRESENTATION) { calmaReadI2Record(CALMA_PRESENTATION, &textpres); font = (textpres >> 4) & 0x03; switch (textpres & 0x000f) { case 0x000a: pos = GEO_NORTHWEST; break; case 0x0006: pos = GEO_WEST; break; case 0x0002: pos = GEO_SOUTHWEST; break; case 0x0009: pos = GEO_NORTH; break; case 0x0005: pos = GEO_CENTER; break; case 0x0001: pos = GEO_SOUTH; break; case 0x0008: pos = GEO_NORTHEAST; break; case 0x0004: pos = GEO_EAST; break; case 0x0000: pos = GEO_SOUTHEAST; break; } } else if (nbytes > 0 && rtype != CALMA_STRANS) calmaSkipSet(ignore); READRH(nbytes, rtype); if (nbytes > 0 && rtype == CALMA_STRANS) { /* We don't handle the strans record for text */ calmaSkipBytes(nbytes - CALMAHEADERLENGTH); READRH(nbytes, rtype); if (nbytes > 0 && rtype == CALMA_MAG) { calmaReadR8(&dval); /* Assume that MAG is the label size in microns */ /* "size" is the label size in 8 * (database units) */ size = (int)((dval * 800 * cifCurReadStyle->crs_multiplier) / cifCurReadStyle->crs_scaleFactor); } else UNREADRH(nbytes, rtype); READRH(nbytes, rtype); if (nbytes > 0 && rtype == CALMA_ANGLE) { calmaReadR8(&dval); angle = (int)dval; } else UNREADRH(nbytes, rtype); } else UNREADRH(nbytes, rtype); /* Coordinates of text */ READRH(nbytes, rtype) if (nbytes < 0) return; if (rtype != CALMA_XY) { calmaUnexpected(CALMA_XY, rtype); return; } nbytes -= CALMAHEADERLENGTH; if (nbytes < 8) { calmaReadError("Not enough bytes in point record.\n"); } else { calmaReadPoint(&r.r_ll, 1); nbytes -= 8; } if (!calmaSkipBytes(nbytes)) return; r.r_ll.p_x /= cifCurReadStyle->crs_scaleFactor; r.r_ll.p_y /= cifCurReadStyle->crs_scaleFactor; r.r_ur = r.r_ll; /* String itself */ if (!calmaReadStringRecord(CALMA_STRING, &textbody)) return; /* Eliminate strange characters. */ { static bool algmsg = FALSE; bool changed = FALSE; char *cp; char *savstring; for (cp = textbody; *cp; cp++) { if (*cp <= ' ' | *cp > '~') { if (!changed) { savstring = StrDup(NULL, textbody); changed = TRUE; } if (*cp == '\r' && *(cp+1) == '\0') *cp = '\0'; else if (*cp == '\r') *cp = '_'; else if (*cp == ' ') *cp = '_'; else *cp = '?'; } } if (changed) { calmaReadError("Warning: improper characters fixed in label '%s'\n", savstring); if (!algmsg) { algmsg = TRUE; calmaReadError(" (algorithm used: trailing dropped, " " and ' ' changed to '_', \n" " other non-printables changed to '?')\n"); } calmaReadError(" modified label is '%s'\n", textbody); freeMagic(savstring); } } /* Place the label */ if (strlen(textbody) == 0) { calmaReadError("Warning: Ignoring empty string label at (%d, %d)\n", r.r_ll.p_x * cifCurReadStyle->crs_scaleFactor, r.r_ll.p_y * cifCurReadStyle->crs_scaleFactor); } else if (type < 0) { calmaReadError("Warning: label \"%s\" at (%d, %d) is on unhandled" " layer:purpose pair %d:%d and will be discarded.\n", textbody, r.r_ll.p_x * cifCurReadStyle->crs_scaleFactor, r.r_ll.p_y * cifCurReadStyle->crs_scaleFactor, layer, textt); } else { int flags; if (cifnum >= 0 && (cifCurReadStyle->crs_layers[cifnum]->crl_flags & CIFR_TEXTLABELS)) flags = LABEL_STICKY; else flags = 0; if (font < 0) DBPutLabel(cifReadCellDef, &r, pos, textbody, type, flags); else DBPutFontLabel(cifReadCellDef, &r, font, size, angle, &GeoOrigin, pos, textbody, type, flags); } /* done with textbody */ if (textbody != NULL) freeMagic(textbody); } /* * ---------------------------------------------------------------------------- * * calmaReadPath -- * * This procedure parses a Calma path, which is an XY record * containing one or more points. "iscale" is an internal * scaling, usually 1, but is 2 for paths specified on a * centerline, to avoid roundoff errors. * * Results: * TRUE is returned if the path was parsed successfully, * FALSE otherwise. * * Side effects: * Modifies the parameter pathheadpp to point to the path * that is constructed. * * ---------------------------------------------------------------------------- */ bool calmaReadPath(pathheadpp, iscale) CIFPath **pathheadpp; int iscale; { CIFPath path, *pathtailp, *newpathp; int nbytes, rtype, npoints, savescale; bool nonManhattan = FALSE; *pathheadpp = (CIFPath *) NULL; pathtailp = (CIFPath *) NULL; path.cifp_next = (CIFPath *) NULL; /* Read the record header */ READRH(nbytes, rtype); if (nbytes < 0) { calmaReadError("EOF when reading path.\n"); return (FALSE); } if (rtype != CALMA_XY) { calmaUnexpected(CALMA_XY, rtype); return (FALSE); } /* Read this many points (pairs of four-byte integers) */ npoints = (nbytes - CALMAHEADERLENGTH) / 8; while (npoints--) { savescale = calmaReadScale1; calmaReadPoint(&path.cifp_point, iscale); if (savescale != calmaReadScale1) { CIFPath *phead = *pathheadpp; int newscale = calmaReadScale1 / savescale; while (phead != NULL) { phead->cifp_x *= newscale; phead->cifp_y *= newscale; phead = phead->cifp_next; } } if (ABS(path.cifp_x) > 0x0fffffff || ABS(path.cifp_y) > 0x0fffffff) { calmaReadError("Warning: Very large point in path: (%d, %d)\n", path.cifp_x, path.cifp_y); } if (feof(calmaInputFile)) { CIFFreePath(*pathheadpp); return (FALSE); } if (iscale != 0) { newpathp = (CIFPath *) mallocMagic((unsigned) (sizeof (CIFPath))); *newpathp = path; if (*pathheadpp) { /* * Check that this segment is Manhattan. If not, remember the * fact and later introduce extra stair-steps to make the path * Manhattan. We don't do the stair-step introduction here for * two reasons: first, the same code is also used by the Calma * module, and second, it is important to know which side of * the polygon is the outside when generating the stair steps. */ if (pathtailp->cifp_x != newpathp->cifp_x && pathtailp->cifp_y != (newpathp->cifp_y)) { if (!nonManhattan) { calmaNonManhattan++; nonManhattan = TRUE; } } pathtailp->cifp_next = newpathp; } else *pathheadpp = newpathp; pathtailp = newpathp; } } return (*pathheadpp != NULL); } /* * ---------------------------------------------------------------------------- * * calmaLayerError -- * * This procedure is called when (layer, dt) doesn't map to a valid * Calma layer. The first time this procedure is called for a given * (layer, dt) pair, we print an error message; on subsequent times, * no error message is printed. * * Results: * None. * * Side effects: * An error message is printed if the first time for this (layer, dt). * Adds an entry to the HashTable calmaLayerHash if one is not * already present for this (layer, dt) pair. * * ---------------------------------------------------------------------------- */ void calmaLayerError(mesg, layer, dt) char *mesg; int layer; int dt; { CalmaLayerType clt; HashEntry *he; clt.clt_layer = layer; clt.clt_type = dt; he = HashFind(&calmaLayerHash, (char *) &clt); if (HashGetValue(he) == NULL) { HashSetValue(he, (ClientData) 1); calmaReadError("%s, layer=%d type=%d\n", mesg, layer, dt); } } magic-8.0.210/calma/calma.h0000664000175000001440000000315712361751705013774 0ustar timusers/* * calma.h -- * * This file defines things that are exported by the * calma module to the rest of the world. * * ********************************************************************* * * 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. * * ********************************************************************* * * rcsid $Header: /usr/cvsroot/magic-8.0/calma/calma.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ */ #ifndef _CALMA_H #define _CALMA_H #include "utils/magic.h" /* Externally visible variables */ extern bool CalmaSubcellPolygons; extern bool CalmaDoLabels; extern bool CalmaDoLower; extern bool CalmaMergeTiles; extern bool CalmaFlattenArrays; extern bool CalmaNoDRCCheck; extern bool CalmaFlattenUses; extern bool CalmaReadOnly; extern bool CalmaContactArrays; extern bool CalmaPostOrder; /* Externally-visible procedures: */ extern bool CalmaWrite(); extern void CalmaReadFile(); extern void CalmaTechInit(); extern bool CalmaGenerateArray(); #endif /* _CALMA_H */ magic-8.0.210/calma/Makefile0000644000175000001440000000041210751423606014170 0ustar timusers# # rcsid $Header: /usr/cvsroot/magic-8.0/calma/Makefile,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ # MODULE = calma MAGICDIR = .. SRCS = CalmaRead.c CalmaRdcl.c CalmaRdio.c CalmaRdpt.c CalmaWrite.c include ${MAGICDIR}/defs.mak include ${MAGICDIR}/rules.mak magic-8.0.210/calma/calmaInt.h0000644000175000001440000001472511410650573014443 0ustar timusers/* * calma.h -- * * This file defines constants used internally by the calma * module, but not exported to the rest of the world. * * ********************************************************************* * * 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. * * ********************************************************************* * * rcsid $Header: /usr/cvsroot/magic-8.0/calma/calmaInt.h,v 1.2 2010/06/24 12:37:15 tim Exp $ */ #ifndef _CALMAINT_H #define _CALMAINT_H #include "utils/magic.h" #include "database/database.h" /* Record data types */ #define CALMA_NODATA 0 /* No data present */ #define CALMA_BITARRAY 1 /* Bit array */ #define CALMA_I2 2 /* 2 byte integer */ #define CALMA_I4 3 /* 4 byte integer */ #define CALMA_R4 4 /* 4 byte real */ #define CALMA_R8 5 /* 8 byte real */ #define CALMA_ASCII 6 /* ASCII string */ /* Record types */ #define CALMA_HEADER 0 #define CALMA_BGNLIB 1 #define CALMA_LIBNAME 2 #define CALMA_UNITS 3 #define CALMA_ENDLIB 4 #define CALMA_BGNSTR 5 #define CALMA_STRNAME 6 #define CALMA_ENDSTR 7 #define CALMA_BOUNDARY 8 #define CALMA_PATH 9 #define CALMA_SREF 10 #define CALMA_AREF 11 #define CALMA_TEXT 12 #define CALMA_LAYER 13 #define CALMA_DATATYPE 14 #define CALMA_WIDTH 15 #define CALMA_XY 16 #define CALMA_ENDEL 17 #define CALMA_SNAME 18 #define CALMA_COLROW 19 #define CALMA_TEXTNODE 20 #define CALMA_NODE 21 #define CALMA_TEXTTYPE 22 #define CALMA_PRESENTATION 23 #define CALMA_SPACING 24 #define CALMA_STRING 25 #define CALMA_STRANS 26 #define CALMA_MAG 27 #define CALMA_ANGLE 28 #define CALMA_UINTEGER 29 #define CALMA_USTRING 30 #define CALMA_REFLIBS 31 #define CALMA_FONTS 32 #define CALMA_PATHTYPE 33 #define CALMA_GENERATIONS 34 #define CALMA_ATTRTABLE 35 #define CALMA_STYPTABLE 36 #define CALMA_STRTYPE 37 #define CALMA_ELFLAGS 38 #define CALMA_ELKEY 39 #define CALMA_LINKTYPE 40 #define CALMA_LINKKEYS 41 #define CALMA_NODETYPE 42 #define CALMA_PROPATTR 43 #define CALMA_PROPVALUE 44 #define CALMA_BOX 45 #define CALMA_BOXTYPE 46 #define CALMA_PLEX 47 #define CALMA_BGNEXTN 48 #define CALMA_ENDEXTN 49 #define CALMA_TAPENUM 50 #define CALMA_TAPECODE 51 #define CALMA_STRCLASS 52 #define CALMA_RESERVED 53 #define CALMA_FORMAT 54 #define CALMA_MASK 55 #define CALMA_ENDMASKS 56 #define CALMA_LIBDIRSIZE 57 #define CALMA_SRFNAME 58 #define CALMA_LIBSECUR 59 #define CALMA_NUMRECORDTYPES 60 /* Number of above types */ /* Property types defined for magic */ #define CALMA_PROP_USENAME 98 /* To record non-default cell use ids */ #define CALMA_PROP_ARRAY_LIMITS 99 /* To record non-default array limits */ /* Flags for transforms */ #define CALMA_STRANS_UPSIDEDOWN 0x8000 /* Mirror about X axis before rot */ #define CALMA_STRANS_ROTATE 0x0002 /* Rotate by absolute angle */ /* Path types */ #define CALMAPATH_SQUAREFLUSH 0 /* Square end flush with endpoint */ #define CALMAPATH_ROUND 1 /* Round end */ #define CALMAPATH_SQUAREPLUS 2 /* Square end plus half-width extent */ /* Largest calma layer or data type numbers */ #define CALMA_LAYER_MAX 255 #define CalmaIsValidLayer(n) ((n) >= 0 && (n) <= CALMA_LAYER_MAX) /* Used to index hash tables of (layer, datatype) pairs */ typedef struct { int clt_layer; int clt_type; } CalmaLayerType; /* Biggest calma string */ #define CALMANAMELENGTH 32 /* Length of record header */ #define CALMAHEADERLENGTH 4 /* ------------------------- Input macros ----------------------------- */ /* Globals for Calma reading */ extern FILE *calmaInputFile; extern char *calmaFilename; extern int calmaReadScale1; extern int calmaReadScale2; extern bool calmaLApresent; extern int calmaLAnbytes; extern int calmaLArtype; /* * Macros for number representation conversion. */ #ifdef ibm032 #include /* as macros in in.h and don't exist as routines */ #endif #ifndef ntohl # ifdef WORDS_BIGENDIAN # define ntohl(x) (x) # define ntohs(x) (x) # define htonl(x) (x) # define htons(x) (x) # endif #endif typedef union { char uc[2]; unsigned short us; } TwoByteInt; typedef union { char uc[4]; unsigned int ul; } FourByteInt; /* Macro to read a 2-byte integer */ #define READI2(z) \ { \ TwoByteInt u; \ u.uc[0] = getc(calmaInputFile); \ u.uc[1] = getc(calmaInputFile); \ (z) = (int) ntohs(u.us); \ } /* Macro to read a 4-byte integer */ #define READI4(z) \ { \ FourByteInt u; \ u.uc[0] = getc(calmaInputFile); \ u.uc[1] = getc(calmaInputFile); \ u.uc[2] = getc(calmaInputFile); \ u.uc[3] = getc(calmaInputFile); \ (z) = (int) ntohl(u.ul); \ } /* Macros for reading and unreading record headers */ #define READRH(nb, rt) \ { \ if (calmaLApresent) { \ (nb) = calmaLAnbytes; \ (rt) = calmaLArtype; \ calmaLApresent = FALSE; \ } else { \ READI2(nb); \ if (feof(calmaInputFile)) nb = -1; \ else { \ (rt) = getc(calmaInputFile); \ (void) getc(calmaInputFile); \ } \ } \ } #define UNREADRH(nb, rt) \ { \ ASSERT(!calmaLApresent, "UNREADRH"); \ calmaLApresent = TRUE; \ calmaLAnbytes = (nb); \ calmaLArtype = (rt); \ } #define PEEKRH(nb, rt) \ { \ READRH(nb, rt); \ UNREADRH(nb, rt); \ } /* Other commonly used globals */ extern HashTable calmaLayerHash; extern int calmaElementIgnore[]; extern CellDef *calmaFindCell(); /* (Added by Nishit, 8/18/2004--8/24/2004) */ extern CellDef *calmaLookCell(); extern void calmaWriteContact(); extern CellDef *calmaGetContactCell(); extern bool calmaIsContactCell; extern char *calmaRecordName(); extern void calmaSkipSet(); /* ------------------- Imports from CIF reading ----------------------- */ extern CellDef *cifReadCellDef; extern Plane *cifSubcellPlanes[]; extern Plane **cifCurReadPlanes; extern HashTable CifCellTable; extern Plane *cifEditCellPlanes[]; #endif /* _CALMAINT_H */ magic-8.0.210/calma/CalmaRdio.c0000644000175000001440000003033710751423606014540 0ustar timusers/* * CalmaReadio.c -- * * Input of Calma GDS-II stream format. * Low-level input. * * ********************************************************************* * * 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/calma/CalmaRdio.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/utils.h" #include "utils/hash.h" #include "database/database.h" #include "database/databaseInt.h" #include "utils/malloc.h" #include "utils/tech.h" #include "cif/cif.h" #include "cif/CIFint.h" #include "cif/CIFread.h" #include "utils/signals.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "utils/styles.h" #include "textio/textio.h" #include "calma/calmaInt.h" /* Forward declarations */ bool calmaReadR8(); bool calmaSkipBytes(); /* * ---------------------------------------------------------------------------- * * calmaReadTransform -- * * Read a CALMA_STRANS, CALMA_MAG, CALMA_ANGLE sequence and construct * the corresponding geometric transform. * * Results: * TRUE normally, FALSE on EOF or fatal syntax error. * * Side effects: * Consumes input. * Modifies the Transform pointed to by 'ptrans'. * * ---------------------------------------------------------------------------- */ bool calmaReadTransform(ptrans, name) Transform *ptrans; /* Fill in this transform */ char *name; /* Name of subcell (for errors) */ { int nbytes, rtype, flags, angle; double dangle; double dmag; Transform t; /* Default is the identity transform */ *ptrans = GeoIdentityTransform; /* Is there any transform at all? */ READRH(nbytes, rtype); if (nbytes < 0) return (FALSE); if (rtype != CALMA_STRANS) { UNREADRH(nbytes, rtype); return (TRUE); } if (nbytes != 6) { (void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH); return (FALSE); } READI2(flags); /* Look for magnification and angle */ READRH(nbytes, rtype); if (nbytes < 0) return (FALSE); if (rtype == CALMA_MAG) { if (nbytes != CALMAHEADERLENGTH + 8) { (void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH); return (FALSE); } if (!calmaReadR8(&dmag)) return (FALSE); if (dmag != (double)((int)(dmag + 0.5))) { calmaReadError("Non-integer magnification (%g) in transform\n", dmag); calmaReadError("Rounding to %d.\n", (int)(dmag + 0.5)); } GeoScaleTrans(ptrans, (int)(dmag + 0.5), &t); *ptrans = t; } else UNREADRH(nbytes, rtype); READRH(nbytes, rtype); if (nbytes < 0) return (FALSE); dangle = 0.0; if (rtype == CALMA_ANGLE) { if (nbytes != CALMAHEADERLENGTH + 8) { (void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH); return (FALSE); } if (!calmaReadR8(&dangle)) return (FALSE); } else UNREADRH(nbytes, rtype); /* Make sure the angle is Manhattan */ angle = (int) dangle; while (angle < 0) angle += 360; while (angle > 360) angle -= 360; switch (angle) { case 360: angle = 0; break; case 0: case 90: case 180: case 270: break; default: calmaReadError("Non-Manhattan angle (%d) in transform\n", angle); if (angle < 45) angle = 0; else if (angle < 135) angle = 90; else if (angle < 225) angle = 180; else if (angle < 315) angle = 270; else angle = 0; calmaReadError(" Rounding to %d degrees.\n", angle); } /* * Construct the transform. * Magic angles are clockwise; Calma angles are counterclockwise. */ if (flags & CALMA_STRANS_UPSIDEDOWN) { GeoTransTrans(ptrans, &GeoUpsideDownTransform, &t); *ptrans = t; } switch (angle) { case 90: GeoTransTrans(ptrans, &Geo270Transform, &t); *ptrans = t; break; case 180: GeoTransTrans(ptrans, &Geo180Transform, &t); *ptrans = t; break; case 270: GeoTransTrans(ptrans, &Geo90Transform, &t); *ptrans = t; break; } return (TRUE); } /* * ---------------------------------------------------------------------------- * * calmaReadI2Record -- * * Read a record that should contain a two-byte integer. * * Results: * TRUE on success, FALSE if the record type we read is not * what we're expecting, or if it is of the wrong size. * * Side effects: * Consumes input. * Stores the result value in *pvalue (note that this is a normal * int, even though we're reading only 16 bits from the input). * * ---------------------------------------------------------------------------- */ bool calmaReadI2Record(type, pvalue) int type; /* Type of record expected */ int *pvalue; /* Store value here */ { int nbytes, rtype, n; READRH(nbytes, rtype); if (nbytes < 0) goto eof; if (type != rtype) { calmaUnexpected(type, rtype); return (FALSE); } /* Read the value */ READI2(n); if (feof(calmaInputFile)) goto eof; *pvalue = n; return (TRUE); eof: calmaReadError("Unexpected EOF.\n"); return (FALSE); } /* * ---------------------------------------------------------------------------- * * calmaReadI4Record -- * * Read a record that should contain a four-byte integer. * * Results: * TRUE on success, FALSE if the record type we read is not * what we're expecting, or if it is of the wrong size. * * Side effects: * Consumes input. * Stores the result value in *pvalue. * * ---------------------------------------------------------------------------- */ bool calmaReadI4Record(type, pvalue) int type; /* Type of record expected */ int *pvalue; /* Store value here */ { int nbytes, rtype, n; READRH(nbytes, rtype); if (nbytes < 0) goto eof; if (type != rtype) { calmaUnexpected(type, rtype); return (FALSE); } /* Read the value */ READI4(n); if (feof(calmaInputFile)) goto eof; *pvalue = n; return (TRUE); eof: calmaReadError("Unexpected EOF.\n"); return (FALSE); } /* * ---------------------------------------------------------------------------- * * calmaReadStringRecord -- * * Read a record that should contain an ASCII string. * * Results: * TRUE on success, FALSE if the record type we read is not * what we're expecting. * * Side effects: * Consumes input. * Allocates memory for string str (must be freed by the caller) * Stores the result in the string pointed to by 'str'. * * ---------------------------------------------------------------------------- */ bool calmaReadStringRecord(type, str) int type; char **str; { int nbytes, rtype; READRH(nbytes, rtype); if (nbytes < 0) goto eof; if (type != rtype) { calmaUnexpected(type, rtype); return (FALSE); } nbytes -= CALMAHEADERLENGTH; *str = (char *) mallocMagic(nbytes + 1); if (fread(*str, sizeof (char), nbytes, calmaInputFile) != nbytes) goto eof; *(*str + nbytes) = '\0'; return (TRUE); eof: calmaReadError("Unexpected EOF.\n"); return (FALSE); } /* * ---------------------------------------------------------------------------- * * calmaReadR8 -- * * Read a single 8-byte real number in Calma stream format. * Convert to internal double-precision format and store in * the double pointed to by 'pd'. * * Results: * TRUE on success, FALSE if EOF is encountered. * * Side effects: * Consumes input. * Stores the result in the *pd. * * ---------------------------------------------------------------------------- */ bool calmaReadR8(pd) double *pd; /* Store result in *pd */ { int i, exponent; unsigned char dchars[8]; double mantissa, d; bool isneg; if (fread((char *) dchars, sizeof (char), sizeof dchars, calmaInputFile) != sizeof dchars) return (FALSE); /* Extract the sign and exponent */ exponent = dchars[0]; if (isneg = (exponent & 0x80)) exponent &= ~0x80; exponent -= 64; /* Construct the mantissa */ mantissa = 0.0; for (i = 7; i > 0; i--) { mantissa += dchars[i]; mantissa /= 256.0; } /* Now raise the mantissa to the exponent */ d = mantissa; if (exponent > 0) { while (exponent-- > 0) d *= 16.0; } else if (exponent < 0) { while (exponent++ < 0) d /= 16.0; } /* Make it negative if necessary */ if (isneg) d = -d; *pd = d; return (TRUE); } /* * ---------------------------------------------------------------------------- * * calmaSkipSet -- * * Skip all records falling in a specified set of types. * Leave the input stream positioned to the start of the first * record not in the specified set. * * The array pointed to by 'skipwhat' contains the record types * of all records to be skipped, terminated with -1. * * Results: * None. * * Side effects: * Consumes input. * * ---------------------------------------------------------------------------- */ void calmaSkipSet(skipwhat) int *skipwhat; { int *skipp; int nbytes, rtype; for (;;) { READRH(nbytes, rtype); if (nbytes < 0) return; for (skipp = skipwhat; *skipp >= 0; skipp++) if (*skipp == rtype) goto skipit; UNREADRH(nbytes, rtype); break; skipit: (void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH); } } /* * ---------------------------------------------------------------------------- * * calmaSkipExact -- * * Skip a single stream record, which must be of the type 'type'. * Leave the input positioned to the start of the record following * this one. Complain if the record is not the one expected. * * Results: * TRUE if successful, FALSE if we encountered an error and * the caller should abort. * * Side effects: * Consumes input. * * ---------------------------------------------------------------------------- */ bool calmaSkipExact(type) int type; { int nbytes, rtype; /* Eat up the record header */ READRH(nbytes, rtype); if (nbytes < 0) goto eof; /* Skip remainder of record */ if (!calmaSkipBytes(nbytes - CALMAHEADERLENGTH)) goto eof; if (rtype != type) { calmaUnexpected(type, rtype); return (FALSE); } return (TRUE); eof: calmaReadError("Unexpected EOF.\n"); return (FALSE); } /* * ---------------------------------------------------------------------------- * * calmaSkipTo -- * * Skip to a record of a particular type. Leaves the input stream * positioned AFTER the record whose type is given by 'what'. * * Results: * TRUE if we found this record, FALSE if EOF was encountered. * * Side effects: * Consumes input. * * ---------------------------------------------------------------------------- */ bool calmaSkipTo(what) int what; { int nbytes, rtype; do { READRH(nbytes, rtype); if (nbytes < 0) return (FALSE); calmaSkipBytes(nbytes - CALMAHEADERLENGTH); } while (rtype != what); return (TRUE); } /* * ---------------------------------------------------------------------------- * * calmaSkipBytes -- * * Skip 'nbytes' bytes from the input. * WARNING: this procedure doesn't know about input saved via UNREADRH(), * so if the caller wants this input to be discarded, it must call READRH() * itself. * * Results: * TRUE if successful, FALSE if EOF was encountered. * * Side effects: * Consumes nbytes of input. * * ---------------------------------------------------------------------------- */ bool calmaSkipBytes(nbytes) int nbytes; /* Skip this many bytes */ { while (nbytes-- > 0) if (getc(calmaInputFile) < 0) return (FALSE); return (TRUE); } magic-8.0.210/calma/CalmaWrite.c0000664000175000001440000020415612150000730014721 0ustar timusers/* * CalmaWrite.c -- * * Output of Calma GDS-II stream format. * * ********************************************************************* * * 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/calma/CalmaWrite.c,v 1.8 2010/12/22 16:29:06 tim Exp $"; #endif /* not lint */ #include #include #include #include #ifdef SYSV #include #else #include #endif #include "utils/magic.h" #include "utils/malloc.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/utils.h" #include "utils/hash.h" #include "database/database.h" #include "database/databaseInt.h" #include "utils/tech.h" #include "cif/cif.h" #include "cif/CIFint.h" #include "utils/signals.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "utils/styles.h" #include "textio/textio.h" #include "calma/calmaInt.h" #include "utils/main.h" /* for Path and CellLibPath */ #include "utils/stack.h" /* Exports */ bool CalmaDoLabels = TRUE; /* If FALSE, don't output labels with GDS-II */ bool CalmaDoLower = TRUE; /* If TRUE, allow lowercase labels. */ bool CalmaFlattenArrays = FALSE; /* If TRUE, output arrays as individual uses */ /* Experimental stuff---not thoroughly tested (as of Sept. 2007)! */ bool CalmaContactArrays = FALSE; /* If TRUE, output contacts as subcell arrays */ bool CalmaMergeTiles = FALSE; /* If TRUE, merge tiles into polygons in output. */ /* Forward declarations */ extern int calmaWriteInitFunc(); extern int calmaWriteMarkFunc(); extern int calmaWritePaintFunc(); extern int calmaMergePaintFunc(); extern int calmaWriteUseFunc(); extern void calmaWriteContacts(); extern void calmaDelContacts(); extern void calmaOutFunc(); extern void calmaOutStructName(); extern void calmaWriteLabelFunc(); extern void calmaOutHeader(); extern void calmaOutDate(); extern void calmaOutStringRecord(); extern void calmaOut8(); extern void calmaOutR8(); extern void calmaProcessBoundary(); extern void calmaMergeBoundaries(); extern void calmaRemoveColinear(); extern void calmaRemoveDegenerate(); /* Structure used by calmaWritePaintFunc() */ typedef struct { FILE *f; /* File stream for output */ Rect *area; /* Clipping area, in GDS coordinates */ } calmaOutputStruct; /*--------------------------------------------------------------*/ /* Structures used by the tile merging algorithm */ /*--------------------------------------------------------------*/ #define GDS_PENDING 0 #define GDS_UNPROCESSED CLIENTDEFAULT #define GDS_PROCESSED 1 #define PUSHTILE(tp) \ if ((tp)->ti_client == (ClientData) GDS_UNPROCESSED) { \ (tp)->ti_client = (ClientData) GDS_PENDING; \ STACKPUSH((ClientData) (tp), SegStack); \ } #define LB_EXTERNAL 0 /* Polygon external edge */ #define LB_INTERNAL 1 /* Polygon internal edge */ #define LB_INIT 2 /* Data not yet valid */ typedef struct LB1 { char lb_type; /* Boundary Type (external or internal) */ Point lb_start; /* Start point */ struct LB1 *lb_next; /* Next point record */ } LinkedBoundary; typedef struct BT1 { LinkedBoundary *bt_first; /* Polygon list */ int bt_points; /* Number of points in this list */ struct BT1 *bt_next; /* Next polygon record */ } BoundaryTop; /*--------------------------------------------------------------*/ /* Number assigned to each cell */ int calmaCellNum; /* Factor by which to scale Magic coordinates for cells and labels. */ int calmaWriteScale; /* Scale factor for outputting paint: */ int calmaPaintScale; /* * Current layer number and "type". * In GDS-II format, this is output with each rectangle. */ int calmaPaintLayerNumber; int calmaPaintLayerType; /* Imports */ extern time_t time(); /* -------------------------------------------------------------------- */ /* * Macros to output various pieces of Calma information. * These are macros for speed. */ /* -------------------------------------------------------------------- */ /* * calmaOutRH -- * * Output a Calma record header. * This consists of a two-byte count of the number of bytes in the * record (including the two count bytes), a one-byte record type, * and a one-byte data type. */ #define calmaOutRH(count, type, datatype, f) \ { calmaOutI2(count, f); (void) putc(type, f); (void) putc(datatype, f); } /* * calmaOutI2 -- * * Output a two-byte integer. * Calma byte order is the same as the network byte order used * by the various network library procedures. */ #define calmaOutI2(n, f) \ { \ union { short u_s; char u_c[2]; } u; \ u.u_s = htons(n); \ (void) putc(u.u_c[0], f); \ (void) putc(u.u_c[1], f); \ } /* * calmaOutI4 -- * * Output a four-byte integer. * Calma byte order is the same as the network byte order used * by the various network library procedures. */ #define calmaOutI4(n, f) \ { \ union { long u_i; char u_c[4]; } u; \ u.u_i = htonl(n); \ (void) putc(u.u_c[0], f); \ (void) putc(u.u_c[1], f); \ (void) putc(u.u_c[2], f); \ (void) putc(u.u_c[3], f); \ } static char calmaMapTableStrict[] = { 0, 0, 0, 0, 0, 0, 0, 0, /* NUL - BEL */ 0, 0, 0, 0, 0, 0, 0, 0, /* BS - SI */ 0, 0, 0, 0, 0, 0, 0, 0, /* DLE - ETB */ 0, 0, 0, 0, 0, 0, 0, 0, /* CAN - US */ '_', '_', '_', '_', '$', '_', '_', '_', /* SP - ' */ '_', '_', '_', '_', '_', '_', '_', '_', /* ( - / */ '0', '1', '2', '3', '4', '5', '6', '7', /* 0 - 7 */ '8', '9', '_', '_', '_', '_', '_', '_', /* 8 - ? */ '_', 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* @ - G */ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* H - O */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* P - W */ 'X', 'Y', 'Z', '_', '_', '_', '_', '_', /* X - _ */ '_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', /* ` - g */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', /* h - o */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', /* p - w */ 'x', 'y', 'z', '_', '_', '_', '_', 0, /* x - DEL */ }; static char calmaMapTablePermissive[] = { 0, 0, 0, 0, 0, 0, 0, 0, /* NUL - BEL */ 0, 0, 0, 0, 0, 0, 0, 0, /* BS - SI */ 0, 0, 0, 0, 0, 0, 0, 0, /* DLE - ETB */ 0, 0, 0, 0, 0, 0, 0, 0, /* CAN - US */ '_', '!', '"', '#', '$', '&', '%', '\'', /* SP - ' */ '(', ')', '*', '+', ',', '-', '.', '/', /* ( - / */ '0', '1', '2', '3', '4', '5', '6', '7', /* 0 - 7 */ '8', '9', ':', ';', '<', '=', '>', '?', /* 8 - ? */ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* @ - G */ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* H - O */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* P - W */ 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', /* X - _ */ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', /* ` - g */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', /* h - o */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', /* p - w */ 'x', 'y', 'z', '{', '|', '}', '~', 0, /* x - DEL */ }; /* * ---------------------------------------------------------------------------- * * CalmaWrite -- * * Write out the entire tree rooted at the supplied CellDef in Calma * GDS-II stream format, to the specified file. * * Results: * TRUE if the cell could be written successfully, FALSE otherwise. * * Side effects: * Writes a file to disk. * In the event of an error while writing out the cell, * the external integer errno is set to the UNIX error * encountered. * * Algorithm: * * Calma names can be strings of up to CALMANAMELENGTH characters. * Because general names won't map into Calma names, we use the * original cell name only if it is legal Calma, and otherwise * generate a unique numeric name for the cell. * * We make a depth-first traversal of the entire design tree, outputting * each cell to the Calma file. If a given cell has not been read in * when we visit it, we read it in ourselves. * * No hierarchical design rule checking or bounding box computation * occur during this traversal -- both are explicitly avoided. * * ---------------------------------------------------------------------------- */ bool CalmaWrite(rootDef, f) CellDef *rootDef; /* Pointer to CellDef to be written */ FILE *f; /* Open output file */ { int oldCount = DBWFeedbackCount, problems; bool good; CellUse dummy; /* * Do not attempt to write anything if a CIF/GDS output style * has not been specified in the technology file. */ if (!CIFCurStyle) { TxError("No CIF/GDS output style set!\n"); return FALSE; } /* * Make sure that the entire hierarchy rooted at rootDef is * read into memory and that timestamp mismatches are resolved * (this is needed so that we know that bounding boxes are OK). */ dummy.cu_def = rootDef; DBCellReadArea(&dummy, &rootDef->cd_bbox); DBFixMismatch(); /* * Go through all cells currently having CellDefs in the * def symbol table and mark them with negative numbers * to show that they should be output, but haven't yet * been. */ (void) DBCellSrDefs(0, calmaWriteInitFunc, (ClientData) NULL); rootDef->cd_client = (ClientData) -1; calmaCellNum = -2; /* Output the header, identifying this file */ calmaOutHeader(rootDef, f); /* * Write all contact cell definitions first */ if (CalmaContactArrays) calmaWriteContacts(f); /* * We perform a post-order traversal of the tree rooted at 'rootDef', * to insure that each child cell is output before it is used. The * root cell is output last. */ (void) calmaProcessDef(rootDef, f); /* Finish up by outputting the end-of-library marker */ calmaOutRH(4, CALMA_ENDLIB, CALMA_NODATA, f); fflush(f); good = !ferror(f); /* See if any problems occurred */ if (problems = (DBWFeedbackCount - oldCount)) TxPrintf("%d problems occurred. See feedback entries.\n", problems); /* * Destroy all contact cell definitions */ if (CalmaContactArrays) calmaDelContacts(); return (good); } /* * ---------------------------------------------------------------------------- * * calmaWriteInitFunc -- * * Filter function called on behalf of CalmaWrite() above. * Responsible for setting the cif number of each cell to zero. * * Results: * Returns 0 to indicate that the search should continue. * * Side effects: * Modify the calma numbers of the cells they are passed. * * ---------------------------------------------------------------------------- */ int calmaWriteInitFunc(def) CellDef *def; { def->cd_client = (ClientData) 0; return (0); } /* * ---------------------------------------------------------------------------- * * calmaProcessUse -- * calmaProcessDef -- * * Main loop of Calma generation. Performs a post-order, depth-first * traversal of the tree rooted at 'def'. Only cells that have not * already been output are processed. * * The procedure calmaProcessDef() is called initially; calmaProcessUse() * is called internally by DBCellEnum(). * * Results: * None. * * Side effects: * Causes Calma GDS-II stream-format to be output. * Returns when the stack is empty. * * ---------------------------------------------------------------------------- */ int calmaProcessUse(use, outf) CellUse *use; /* Process use->cu_def */ FILE *outf; /* Stream file */ { return (calmaProcessDef(use->cu_def, outf)); } int calmaProcessDef(def, outf) CellDef *def; /* Output this def's children, then the def itself */ FILE *outf; /* Stream file */ { char *filename; bool isReadOnly, oldStyle, hasContent; /* Skip if already output */ if ((int) def->cd_client > 0) return (0); /* Assign it a (negative) number if it doesn't have one yet */ if ((int) def->cd_client == 0) def->cd_client = (ClientData) calmaCellNum--; /* Mark this cell */ def->cd_client = (ClientData) (- (int) def->cd_client); /* Read the cell in if it is not already available. */ if ((def->cd_flags & CDAVAILABLE) == 0) if (!DBCellRead(def, (char *) NULL, TRUE)) return (0); /* * Output the definitions for any of our descendants that have * not already been output. Numbers are assigned to the subcells * as they are output. */ (void) DBCellEnum(def, calmaProcessUse, (ClientData) outf); /* * Check if this is a read-only file that is supposed to be copied * verbatim from input to output. If so, do the direct copy. If * not, or if there is any problem obtaining the original cell * definition, resort to writing out magic's version of the def, * and print a warning message. * * Treat the lack of a GDS_START property as an indication * that we should treat this cell like a reference-only * cell. That is, the instance will be called but no * definition will appear in the output. */ DBPropGet(def, "GDS_START", &hasContent); filename = (char *)DBPropGet(def, "GDS_FILE", &isReadOnly); if (isReadOnly && hasContent) { char *buffer, *offptr; size_t defsize, numbytes; off_t cellstart, cellend; dlong cval; FILE *fi; /* Use PaOpen() so the paths searched are the same as were */ /* searched to find the .mag file that indicated this GDS file. */ fi = PaOpen(filename, "r", "", Path, CellLibPath, (char **)NULL); if (fi == NULL) { /* This is a rare error, but if the subcell is inside */ /* another vendor GDS, it would not normally be output. */ DBPropGet(def->cd_parents->cu_parent, "GDS_FILE", &isReadOnly); if (!isReadOnly) TxError("Calma output error: Can't find GDS file for vendor cell." " Using magic's internal definition\n"); else def->cd_flags |= CDVENDORGDS; } else { offptr = (char *)DBPropGet(def, "GDS_END", NULL); sscanf(offptr, "%"DLONG_PREFIX"d", &cval); cellend = (off_t)cval; offptr = (char *)DBPropGet(def, "GDS_BEGIN", &oldStyle); if (!oldStyle) { offptr = (char *)DBPropGet(def, "GDS_START", NULL); /* Write our own header and string name, to ensure */ /* that the magic cell name and GDS name match. */ /* Output structure header */ calmaOutRH(28, CALMA_BGNSTR, CALMA_I2, outf); calmaOutDate(def->cd_timestamp, outf); calmaOutDate(time((time_t *) 0), outf); /* Name structure the same as the magic cellname */ calmaOutStructName(CALMA_STRNAME, def, outf); } sscanf(offptr, "%"DLONG_PREFIX"d", &cval); cellstart = (off_t)cval; fseek(fi, cellstart, SEEK_SET); if (cellend < cellstart) /* Sanity check */ { TxError("Calma output error: Bad vendor GDS file reference!\n"); isReadOnly = FALSE; } else { defsize = (size_t)(cellend - cellstart); buffer = (char *)mallocMagic(defsize); numbytes = fread(buffer, sizeof(char), (size_t)defsize, fi); if (numbytes == defsize) { numbytes = fwrite(buffer, sizeof(char), (size_t)defsize, outf); if (numbytes <= 0) { TxError("Calma output error: Can't write cell from vendor GDS." " Using magic's internal definition\n"); isReadOnly = FALSE; } } else { TxError("Calma output error: Can't read cell from vendor GDS." " Using magic's internal definition\n"); isReadOnly = FALSE; } freeMagic(buffer); } fclose(fi); /* Mark the definition as vendor GDS so that magic doesn't */ /* try to generate subcell interaction or array interaction */ /* paint for it. */ def->cd_flags |= CDVENDORGDS; } } /* Output this cell definition from the Magic database */ if (!isReadOnly) calmaOutFunc(def, outf, &TiPlaneRect); return (0); } /* * ---------------------------------------------------------------------------- * * calmaOutFunc -- * * Write out the definition for a single cell as a GDS-II stream format * structure. We try to preserve the original cell's name if it is legal * in GDS-II; otherwise, we generate a unique name. * * Results: * None. * * Side effects: * Appends to the open Calma output file. * * ---------------------------------------------------------------------------- */ void calmaOutFunc(def, f, cliprect) CellDef *def; /* Pointer to cell def to be written */ FILE *f; /* Open output file */ Rect *cliprect; /* Area to clip to (used for contact cells), * in CIF/GDS coordinates. */ { Label *lab; CIFLayer *layer; Rect bigArea; int type; int dbunits; calmaOutputStruct cos; cos.f = f; cos.area = (cliprect == &TiPlaneRect) ? NULL : cliprect; /* Output structure begin */ calmaOutRH(28, CALMA_BGNSTR, CALMA_I2, f); calmaOutDate(def->cd_timestamp, f); calmaOutDate(time((time_t *) 0), f); /* Output structure name */ calmaOutStructName(CALMA_STRNAME, def, f); /* Since Calma database units are nanometers, multiply all units by 10, * modified by the scale multiplier. */ dbunits = (CIFCurStyle->cs_flags & CWF_ANGSTROMS) ? 100 : 10; if ((dbunits % CIFCurStyle->cs_expander) == 0) { calmaWriteScale = CIFCurStyle->cs_scaleFactor * dbunits / CIFCurStyle->cs_expander; calmaPaintScale = dbunits / CIFCurStyle->cs_expander; } else { TxError("Calma output error: Output scale units are %2.1f nanometers.\n", (float)dbunits / (float)CIFCurStyle->cs_expander); TxError("Magic Calma output will be scaled incorrectly!\n"); if ((dbunits == 10) && ((100 % CIFCurStyle->cs_expander) == 0)) { TxError("Please add \"units angstroms\" to the cifoutput section" " of the techfile.\n"); } else { TxError("Magic GDS output is limited to a minimum dimension of" " 1 angstrom.\n"); } /* Set expander to 10 so output scales are not zero. */ calmaWriteScale = CIFCurStyle->cs_scaleFactor; calmaPaintScale = 1; } /* * Output the calls that the child makes to its children. For * arrays we output a single call, unlike CIF, since Calma * supports the notion of arrays. */ (void) DBCellEnum(def, calmaWriteUseFunc, (ClientData) f); /* Output all the tiles associated with this cell; skip temporary layers */ GEO_EXPAND(&def->cd_bbox, CIFCurStyle->cs_radius, &bigArea); CIFErrorDef = def; CIFGen(def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE, (ClientData) f); if (!CIFHierWriteDisable) CIFGenSubcells(def, &bigArea, CIFPlanes); if (!CIFArrayWriteDisable) CIFGenArrays(def, &bigArea, CIFPlanes); for (type = 0; type < CIFCurStyle->cs_nLayers; type++) { layer = CIFCurStyle->cs_layers[type]; if (layer->cl_flags & CIF_TEMP) continue; if (!CalmaIsValidLayer(layer->cl_calmanum)) continue; calmaPaintLayerNumber = layer->cl_calmanum; calmaPaintLayerType = layer->cl_calmatype; DBSrPaintArea((Tile *) NULL, CIFPlanes[type], cliprect, &CIFSolidBits, (CalmaMergeTiles) ? calmaMergePaintFunc : calmaWritePaintFunc, (ClientData) &cos); } /* Output labels */ if (CalmaDoLabels) for (lab = def->cd_labels; lab; lab = lab->lab_next) calmaWriteLabelFunc(lab, CIFCurStyle->cs_labelLayer[lab->lab_type], f); /* End of structure */ calmaOutRH(4, CALMA_ENDSTR, CALMA_NODATA, f); } /* * ---------------------------------------------------------------------------- * * calmaIsUseNameDefault -- * * Determine if this use name is not default; that is, it is not the name * of the cell def followed by an underscore and a use index number. If * it is not default, then we want to write out the use name as a property * in the GDS stream file so that we can recover the name when the file is * read back into magic. * * Results: * TRUE if the cell use ID is a default name; FALSE if not. * * Side Effects: * None. * * ---------------------------------------------------------------------------- */ bool calmaIsUseNameDefault(defName, useName) char *defName; char *useName; { int idx, slen; char *sptr; if (useName == NULL) return TRUE; slen = strlen(defName); if (!strncmp(defName, useName, slen)) { sptr = useName + slen; if (*sptr != '_') return FALSE; else sptr++; if (sscanf(sptr, "%d", &idx) != 1) return FALSE; else return TRUE; } return FALSE; } /* * ---------------------------------------------------------------------------- * * calmaWriteUseFunc -- * * Filter function, called by DBCellEnum on behalf of calmaOutFunc above, * to write out each CellUse called by the CellDef being output. If the * CellUse is an array, we output it as a single array instead of as * individual uses like CIF. * * Results: * None. * * Side effects: * Appends to the open Calma output file. * * ---------------------------------------------------------------------------- */ int calmaWriteUseFunc(use, f) CellUse *use; FILE *f; { /* * r90, r180, and r270 are Calma 8-byte real representations * of the angles 90, 180, and 270 degrees. Because there are * only 4 possible values, it is faster to have them pre-computed * than to format with calmaOutR8(). */ static unsigned char r90[] = { 0x42, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static unsigned char r180[] = { 0x42, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static unsigned char r270[] = { 0x43, 0x10, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00 }; unsigned char *whichangle; int x, y, topx, topy, rows, cols, xxlate, yxlate, hdrsize; int rectype, stransflags; Transform *t; bool isArray = FALSE; Point p, p2; topx = use->cu_xhi - use->cu_xlo; if (topx < 0) topx = -topx; topy = use->cu_yhi - use->cu_ylo; if (topy < 0) topy = -topy; /* * The following translates from the abcdef transforms that * we use internally to the rotation and mirroring specification * used in Calma stream files. It only works because orientations * are orthogonal in magic, and no scaling is allowed in cell use * transforms. Thus the elements a, b, d, and e always have one * of the following forms: * * a d * b e * * (counterclockwise rotations of 0, 90, 180, 270 degrees) * * 1 0 0 1 -1 0 0 -1 * 0 1 -1 0 0 -1 1 0 * * (mirrored across the x-axis before counterclockwise rotation * by 0, 90, 180, 270 degrees): * * 1 0 0 1 -1 0 0 -1 * 0 -1 1 0 0 1 -1 0 * * Note that mirroring must be done if either a != e, or * a == 0 and b == d. * */ t = &use->cu_transform; stransflags = 0; whichangle = (t->t_a == -1) ? r180 : (unsigned char *) NULL; if (t->t_a != t->t_e || (t->t_a == 0 && t->t_b == t->t_d)) { stransflags |= CALMA_STRANS_UPSIDEDOWN; if (t->t_a == 0) { if (t->t_b == 1) whichangle = r90; else whichangle = r270; } } else if (t->t_a == 0) { if (t->t_b == -1) whichangle = r90; else whichangle = r270; } if (CalmaFlattenArrays) { for (x = 0; x <= topx; x++) { for (y = 0; y <= topy; y++) { /* Structure reference */ calmaOutRH(4, CALMA_SREF, CALMA_NODATA, f); calmaOutStructName(CALMA_SNAME, use->cu_def, f); /* Transformation flags */ calmaOutRH(6, CALMA_STRANS, CALMA_BITARRAY, f); calmaOutI2(stransflags, f); /* Rotation if there is one */ if (whichangle) { calmaOutRH(12, CALMA_ANGLE, CALMA_R8, f); calmaOut8(whichangle, f); } /* Translation */ xxlate = t->t_c + t->t_a*(use->cu_xsep)*x + t->t_b*(use->cu_ysep)*y; yxlate = t->t_f + t->t_d*(use->cu_xsep)*x + t->t_e*(use->cu_ysep)*y; xxlate *= calmaWriteScale; yxlate *= calmaWriteScale; calmaOutRH(12, CALMA_XY, CALMA_I4, f); calmaOutI4(xxlate, f); calmaOutI4(yxlate, f); /* End of element */ calmaOutRH(4, CALMA_ENDEL, CALMA_NODATA, f); } } } else { /* Is it an array? */ isArray = (topx > 0 || topy > 0); rectype = isArray ? CALMA_AREF : CALMA_SREF; /* Structure reference */ calmaOutRH(4, rectype, CALMA_NODATA, f); calmaOutStructName(CALMA_SNAME, use->cu_def, f); /* Transformation flags */ calmaOutRH(6, CALMA_STRANS, CALMA_BITARRAY, f); calmaOutI2(stransflags, f); /* Rotation if there is one */ if (whichangle) { calmaOutRH(12, CALMA_ANGLE, CALMA_R8, f); calmaOut8(whichangle, f); } /* If array, number of columns and rows in the array */ if (isArray) { calmaOutRH(8, CALMA_COLROW, CALMA_I2, f); cols = topx + 1; rows = topy + 1; calmaOutI2(cols, f); calmaOutI2(rows, f); } /* Translation */ xxlate = t->t_c * calmaWriteScale; yxlate = t->t_f * calmaWriteScale; hdrsize = isArray ? 28 : 12; calmaOutRH(hdrsize, CALMA_XY, CALMA_I4, f); calmaOutI4(xxlate, f); calmaOutI4(yxlate, f); /* Array sizes if an array */ if (isArray) { /* Column reference point */ p.p_x = use->cu_xsep * cols; p.p_y = 0; GeoTransPoint(t, &p, &p2); p2.p_x *= calmaWriteScale; p2.p_y *= calmaWriteScale; calmaOutI4(p2.p_x, f); calmaOutI4(p2.p_y, f); /* Row reference point */ p.p_x = 0; p.p_y = use->cu_ysep * rows; GeoTransPoint(t, &p, &p2); p2.p_x *= calmaWriteScale; p2.p_y *= calmaWriteScale; calmaOutI4(p2.p_x, f); calmaOutI4(p2.p_y, f); } /* By NP */ /* Property attributes/value pairs. */ /* Add a CellUse ID property, if the CellUse has a non-default name */ if (!calmaIsUseNameDefault(use->cu_def->cd_name, use->cu_id)) { calmaOutRH(6, CALMA_PROPATTR, CALMA_I2, f); calmaOutI2(CALMA_PROP_USENAME, f); calmaOutStringRecord(CALMA_PROPVALUE, use->cu_id, f); } /* Add an array limits property, if the CellUse is an array and */ /* limits of the array (xlo, ylo) are not zero (the default). */ if ((use->cu_xlo != 0) || (use->cu_ylo != 0)) { char arraystr[128]; sprintf(arraystr, "%d_%d_%d_%d", use->cu_xlo, use->cu_xhi, use->cu_ylo, use->cu_yhi); calmaOutRH(6, CALMA_PROPATTR, CALMA_I2, f); calmaOutI2(CALMA_PROP_ARRAY_LIMITS, f); calmaOutStringRecord(CALMA_PROPVALUE, arraystr, f); } /* End of element */ calmaOutRH(4, CALMA_ENDEL, CALMA_NODATA, f); } return (0); } /* * ---------------------------------------------------------------------------- * * calmaOutStructName -- * * Output the name of a cell def. * If the name is legal GDS-II, use it; otherwise, generate one * that is legal and unique. * * Results: * None. * * Side effects: * Writes to the disk file. * * ---------------------------------------------------------------------------- */ void calmaOutStructName(type, def, f) int type; CellDef *def; FILE *f; { char defname[CALMANAMELENGTH+1]; unsigned char c; char *cp; int calmanum; char *table; if (CIFCurStyle->cs_flags & CWF_PERMISSIVE_LABELS) { table = calmaMapTablePermissive; } else { table = calmaMapTableStrict; } /* Is the def name a legal Calma name? */ for (cp = def->cd_name; c = (unsigned char) *cp; cp++) { if ((c > 127) || (table[c] == 0)) goto bad; else if ((unsigned char)table[c] != c) { TxError("Warning: character \'%c\' changed to \'%c\' in" " name %s\n", (char)c, table[c], def->cd_name); } /* We really should ensure that the new name is unique. . . */ } if (cp <= def->cd_name + CALMANAMELENGTH) { /* Yes, it's legal: use it */ (void) strcpy(defname, def->cd_name); } else { /* Bad name: use XXXXXcalmaNum */ bad: calmanum = (int) def->cd_client; if (calmanum < 0) calmanum = -calmanum; (void) sprintf(defname, "XXXXX%d", calmanum); TxError("Warning: string in output unprintable; changed to \'%s\'\n", defname); } calmaOutStringRecord(type, defname, f); } /* Added by NP 8/21/2004 */ /* * ---------------------------------------------------------------------------- * * calmaGetContactCell -- * * This routine creates [if it hasn't been created yet] a cell definition * containing the given TileType. Cellname is "$$" + layer1_name + "_" + * layer2_name... + "$$". Cellname contains the short name of all the * residues of the layer "type". * * Results: * Returns new celldef it doesn't exist else created one. * * Side effects: * New celldef created specially for contact type if it does not exist. * * ---------------------------------------------------------------------------- */ CellDef * calmaGetContactCell(type, lookOnly) TileType type; /* magic contact tile type */ bool lookOnly; /* if true, don't generate any new cells */ { TileType j; char contactCellName[100]; TileTypeBitMask *rMask = DBResidueMask(type); CellDef *def; bool first = TRUE; strcpy(contactCellName, "$$"); for (j = TT_SPACE + 1; j < DBNumUserLayers; j++) if (TTMaskHasType(rMask, j)) { /* Cellname starts with "$$" to make it diffrent from * other database cells, and to be compatible with a * number of other EDA tools. */ if (!first) strcat(contactCellName, "_"); else first = FALSE; strcat(contactCellName, DBTypeShortName(j)); } strcat(contactCellName, "$$"); def = DBCellLookDef(contactCellName); if ((def == (CellDef *) NULL) && (lookOnly == FALSE)) { def = DBCellNewDef(contactCellName, (char *) NULL); def->cd_flags &= ~(CDMODIFIED|CDGETNEWSTAMP); def->cd_flags |= CDAVAILABLE; } return def; } /* * ---------------------------------------------------------------------------- * * CalmaGenerateArray -- * * This routine * * Results: * TRUE on success, FALSE if no contact cell could be found. * * Side effects: * Writes an AREF record to the GDS stream output. * * ---------------------------------------------------------------------------- */ bool CalmaGenerateArray(f, type, llx, lly, pitch, cols, rows) FILE *f; /* GDS output file */ TileType type; /* Magic tile type of contact */ int llx, lly; /* Lower-left hand coordinate of the array * (centered on contact cut) */ int pitch; /* Pitch of the array elements */ int cols, rows; /* Number of array elements in X and Y */ { CellDef *child; /* Cell definition of the contact cell */ int xxlate, yxlate; child = calmaGetContactCell(type, TRUE); if (child == NULL) return FALSE; /* Structure reference */ calmaOutRH(4, CALMA_AREF, CALMA_NODATA, f); calmaOutStructName(CALMA_SNAME, child, f); /* Transformation flags */ calmaOutRH(6, CALMA_STRANS, CALMA_BITARRAY, f); calmaOutI2(0, f); /* Number of columns and rows in the array */ calmaOutRH(8, CALMA_COLROW, CALMA_I2, f); calmaOutI2(cols, f); calmaOutI2(rows, f); /* Translation */ xxlate = llx * calmaPaintScale; yxlate = lly * calmaPaintScale; calmaOutRH(28, CALMA_XY, CALMA_I4, f); calmaOutI4(xxlate, f); calmaOutI4(yxlate, f); /* Column reference point */ calmaOutI4(xxlate + pitch * cols * calmaPaintScale, f); calmaOutI4(yxlate, f); /* Row reference point */ calmaOutI4(xxlate, f); calmaOutI4(yxlate + pitch * rows * calmaPaintScale, f); /* End of AREF element */ calmaOutRH(4, CALMA_ENDEL, CALMA_NODATA, f); return TRUE; } /* Added by NP 8/22/2004 */ /* * ---------------------------------------------------------------------------- * * calmaWriteContacts -- * * This routine creates a new cellDef for each contact type and writes to * the GDS output stream file. It is called before processing all cell * definitions while writing GDS output. * * Results: * None. * * Side effects: * Writes contact cell definition to the open Calma output file. * * ---------------------------------------------------------------------------- */ void calmaWriteContacts(f) FILE *f; { TileType type; TileTypeBitMask tMask, *rMask; CellDef *def, *cellDef; Rect area, cliprect; int halfwidth, halfsize; CIFOp *op; HashSearch hs; HashEntry *entry; /* Turn off generation of contact arrays for the duration of this */ /* subroutine, so that the contact definitions themselves will get */ /* the proper contact cut drawn. It is turned on again at the end */ /* of the routine. Note that this routine is not called unless */ /* CalmaContactArrays is TRUE. */ CalmaContactArrays = FALSE; DBEnumerateTypes(&tMask); /* Decompose stacking types */ for (type = DBNumUserLayers; type < DBNumTypes; type++) if (TTMaskHasType(&tMask, type)) { rMask = DBResidueMask(type); TTMaskSetMask(&tMask, rMask); } for (type = TT_SPACE + 1; type < DBNumUserLayers; type++) { /* We need to create cell array only for contact types */ if (DBIsContact(type) && TTMaskHasType(&tMask, type)) { /* Write definition of cell to GDS stream. */ /* Get cell definition for Tiletype type */ def = calmaGetContactCell(type, FALSE); /* Get clip bounds, so that residue surround is */ /* minimum. Note that these values are in CIF/GDS */ /* units, and the clipping rectangle passed to */ /* calmaOutFunc is also in CIF/GDS units. */ halfsize = CIFGetContactSize(type, NULL, NULL, NULL) >> 1; /* Get minimum width for layer by rounding halfsize */ /* to the nearest lambda value. */ halfwidth = halfsize / CIFCurStyle->cs_scaleFactor; if ((halfsize % CIFCurStyle->cs_scaleFactor) != 0) halfwidth++; area.r_xbot = area.r_ybot = -halfwidth; area.r_xtop = area.r_ytop = halfwidth; UndoDisable(); DBPaint(def, &area, type); DBReComputeBbox(def); TTMaskSetType(&def->cd_types, type); /* Clip output to the bounds of "cliprect" */ cliprect.r_xbot = cliprect.r_ybot = -halfsize; cliprect.r_xtop = cliprect.r_ytop = halfsize; calmaOutFunc(def, f, &cliprect); UndoEnable(); } } CalmaContactArrays = TRUE; } /* * ---------------------------------------------------------------------------- * * calmaDelContacts -- * * This routine removes all cell definitions generated by * calmaWriteContacts(). * * Results: * None. * * Side effects: * Removes contact cell defs from the database. * * ---------------------------------------------------------------------------- */ void calmaDelContacts() { TileType type; CellDef *def; for (type = TT_SPACE + 1; type < DBNumUserLayers; type++) if (DBIsContact(type)) { def = calmaGetContactCell(type, TRUE); if (def != (CellDef *)NULL) DBCellDeleteDef(def); } } /* * ---------------------------------------------------------------------------- * calmaAddSegment --- * * Process a new polygon edge, inserting it into a polygon record as * required. If the edge is between a GDS layer and TT_SPACE, then * we insert a point record. If the edge is between two tiles of the * same layer, then we insert a tile record. * * Results: * Return 1 if an internal segment was generated, 0 if an external * segment was generate. On error, return -1 (failure to find a * connecting point; this shouldn't happen). * * Returns the current segment in the original pointer position (1st * argument). If segments are added in counterclockwise order, then * this should be most efficient. * * Side effects: * May allocate memory. * --------------------------------------------------------------------------- */ int calmaAddSegment(lbptr, poly_edge, p1x, p1y, p2x, p2y) LinkedBoundary **lbptr; bool poly_edge; int p1x, p1y, p2x, p2y; { LinkedBoundary *newseg, *curseg, *stopseg; bool startmatch = FALSE; bool endmatch = FALSE; stopseg = NULL; for (curseg = *lbptr; curseg != stopseg; curseg = curseg->lb_next) { stopseg = *lbptr; if (curseg->lb_type == LB_INIT) { if ((p1x == curseg->lb_start.p_x) && (p1y == curseg->lb_start.p_y)) startmatch = TRUE; if ((p2x == curseg->lb_next->lb_start.p_x) && (p2y == curseg->lb_next->lb_start.p_y)) endmatch = TRUE; if (startmatch && endmatch) { /* Segment completes this edge */ curseg->lb_type = (poly_edge) ? LB_EXTERNAL : LB_INTERNAL; *lbptr = curseg; return (int)curseg->lb_type; } else if (startmatch || endmatch) { /* Insert a new segment after curseg */ newseg = (LinkedBoundary *)mallocMagic(sizeof(LinkedBoundary)); newseg->lb_next = curseg->lb_next; curseg->lb_next = newseg; if (startmatch) { newseg->lb_type = curseg->lb_type; curseg->lb_type = (poly_edge) ? LB_EXTERNAL : LB_INTERNAL; newseg->lb_start.p_x = p2x; newseg->lb_start.p_y = p2y; } else { newseg->lb_type = (poly_edge) ? LB_EXTERNAL : LB_INTERNAL; newseg->lb_start.p_x = p1x; newseg->lb_start.p_y = p1y; } curseg = newseg; *lbptr = curseg; return (int)curseg->lb_type; } } } return -1; /* This shouldn't happen, but isn't fatal. */ } /* * ---------------------------------------------------------------------------- * calmaRemoveDegenerate --- * * This routine takes lists of polygons and removes any degenerate * segments (those that backtrack on themselves) from each one. * * Results: * None. * * Side Effects: * Deallocates memory for any segments that are removed. * * ---------------------------------------------------------------------------- */ void calmaRemoveDegenerate(blist) BoundaryTop *blist; { bool segfound; LinkedBoundary *stopseg, *curseg, *lastseg; BoundaryTop *bounds; for (bounds = blist; bounds != NULL; bounds = bounds->bt_next) { segfound = TRUE; while (segfound) { segfound = FALSE; stopseg = NULL; for (lastseg = bounds->bt_first; lastseg != stopseg;) { stopseg = bounds->bt_first; curseg = lastseg->lb_next; if (GEO_SAMEPOINT(curseg->lb_start, curseg->lb_next->lb_next->lb_start)) { segfound = TRUE; lastseg->lb_next = curseg->lb_next->lb_next; freeMagic(curseg->lb_next); freeMagic(curseg); /* Make sure record doesn't point to a free'd segment */ bounds->bt_first = lastseg; bounds->bt_points -= 2; break; } else lastseg = lastseg->lb_next; } } } } /* * ---------------------------------------------------------------------------- * calmaRemoveColinear --- * * This routine takes lists of polygons and removes any redundant * (colinear) points. * * Results: * None. * * Side Effects: * Deallocates memory for any segments that are removed. * * ---------------------------------------------------------------------------- */ void calmaRemoveColinear(blist) BoundaryTop *blist; { LinkedBoundary *stopseg, *curseg, *lastseg; BoundaryTop *bounds; for (bounds = blist; bounds != NULL; bounds = bounds->bt_next) { stopseg = NULL; for (lastseg = bounds->bt_first; lastseg != stopseg;) { stopseg = bounds->bt_first; curseg = lastseg->lb_next; if (((lastseg->lb_start.p_x == curseg->lb_start.p_x) && (lastseg->lb_start.p_x == curseg->lb_next->lb_start.p_x)) || ((lastseg->lb_start.p_y == curseg->lb_start.p_y) && (lastseg->lb_start.p_y == curseg->lb_next->lb_start.p_y))) { lastseg->lb_next = curseg->lb_next; /* Make sure record doesn't point to a free'd segment */ if (curseg == bounds->bt_first) bounds->bt_first = lastseg; freeMagic(curseg); bounds->bt_points--; } else if ((lastseg->lb_start.p_x != curseg->lb_start.p_x) && (lastseg->lb_start.p_y != curseg->lb_start.p_y) && (curseg->lb_start.p_x != curseg->lb_next->lb_start.p_x) && (curseg->lb_start.p_y != curseg->lb_next->lb_start.p_y)) { /* Check colinearity of non-Manhattan edges */ int delx1, dely1, delx2, dely2, gcf; delx1 = curseg->lb_start.p_x - lastseg->lb_start.p_x; dely1 = curseg->lb_start.p_y - lastseg->lb_start.p_y; delx2 = curseg->lb_next->lb_start.p_x - curseg->lb_start.p_x; dely2 = curseg->lb_next->lb_start.p_y - curseg->lb_start.p_y; if ((delx1 != delx2) || (dely1 != dely2)) { gcf = FindGCF(delx1, dely1); if (gcf > 1) { delx1 /= gcf; dely1 /= gcf; } } if ((delx1 != delx2) || (dely1 != dely2)) { gcf = FindGCF(delx2, dely2); if (gcf > 1) { delx2 /= gcf; dely2 /= gcf; } } if ((delx1 == delx2) && (dely1 == dely2)) { lastseg->lb_next = curseg->lb_next; if (curseg == bounds->bt_first) bounds->bt_first = lastseg; freeMagic(curseg); bounds->bt_points--; } else lastseg = lastseg->lb_next; } else lastseg = lastseg->lb_next; } } } /* * ---------------------------------------------------------------------------- * calmaMergeSegments --- * * Once a tile has been disassembled into segments, and it is not a simple * rectangle (which would have been handled already), then merge it into * the list of boundaries. * * Note that this algorithm is O(N^2) and has lots of room for improvement! * Still, each segment is never checked against more than 200 points, * because when a boundary reaches this number (the maximum for GDS * boundary records), the record will tend to be skipped (it should * probably be output here. . .) * * Results: * None. * * Side effects: * Output, memory allocation and deallocation * * ---------------------------------------------------------------------------- */ void calmaMergeSegments(edge, blist, num_points) LinkedBoundary *edge; BoundaryTop **blist; int num_points; { LinkedBoundary *stopseg, *curseg, *lastseg; LinkedBoundary *compstop, *compseg, *complast; BoundaryTop *bounds, *newbounds; if (*blist == NULL) goto make_new_bound; /* Check each internal edge for an antiparallel match with */ /* an internal edge in the boundary lists. */ stopseg = NULL; for (lastseg = edge; lastseg != stopseg; lastseg = lastseg->lb_next) { stopseg = edge; curseg = lastseg->lb_next; if (curseg->lb_type == LB_EXTERNAL) continue; for (bounds = *blist; bounds != NULL; bounds = bounds->bt_next) { /* Avoid overflow on GDS boundary point limit. Note */ /* that a merge will remove 2 points, but GDS requires */ /* that we add the 1st point to the end of the list. */ if (bounds->bt_points + num_points > 201) continue; compstop = NULL; for (complast = bounds->bt_first; complast != compstop; complast = complast->lb_next) { compstop = bounds->bt_first; compseg = complast->lb_next; if (compseg->lb_type == LB_EXTERNAL) continue; /* Edges match antiparallel only. Rect points are *not* */ /* canonical. r_ll and p1 are both 1st points traveling */ /* in a counterclockwise direction along the perimeter. */ if (GEO_SAMEPOINT(compseg->lb_start, curseg->lb_next->lb_start) && GEO_SAMEPOINT(compseg->lb_next->lb_start, curseg->lb_start)) { lastseg->lb_next = compseg->lb_next; complast->lb_next = curseg->lb_next; freeMagic(compseg); freeMagic(curseg); /* Make sure the record doesn't point to the free'd segment */ if (compseg == bounds->bt_first) bounds->bt_first = complast; bounds->bt_points += num_points - 2; return; } } } } /* If still no connecting edge was found, or if we overflowed the GDS max */ /* number of records for a boundary, then start a new entry. */ make_new_bound: newbounds = (BoundaryTop *)mallocMagic(sizeof(BoundaryTop)); newbounds->bt_first = edge; newbounds->bt_next = *blist; newbounds->bt_points = num_points; *blist = newbounds; } /* * ---------------------------------------------------------------------------- * Process a LinkedBoundary list into a polygon and generate GDS output. * Free the linked list when done. * * Results: * None. * * Side effects: * Output, memory deallocation. * * ---------------------------------------------------------------------------- */ void calmaProcessBoundary(blist, cos) BoundaryTop *blist; calmaOutputStruct *cos; { FILE *f = cos->f; LinkedBoundary *listtop, *lbref, *lbstop, *lbfree; BoundaryTop *bounds; int sval; int chkcount; /* diagnostic */ for (bounds = blist; bounds != NULL; bounds = bounds->bt_next) { /* Boundary */ calmaOutRH(4, CALMA_BOUNDARY, CALMA_NODATA, f); /* Layer */ calmaOutRH(6, CALMA_LAYER, CALMA_I2, f); calmaOutI2(calmaPaintLayerNumber, f); /* Data type */ calmaOutRH(6, CALMA_DATATYPE, CALMA_I2, f); calmaOutI2(calmaPaintLayerType, f); /* Record length = ((#points + 1) * 2 values * 4 bytes) + 4 bytes header */ calmaOutRH(4 + (bounds->bt_points + 1) * 8, CALMA_XY, CALMA_I4, f); /* Coordinates (repeat 1st point) */ listtop = bounds->bt_first; lbstop = NULL; chkcount = 0; for (lbref = listtop; lbref != lbstop; lbref = lbref->lb_next) { lbstop = listtop; calmaOutI4(lbref->lb_start.p_x * calmaPaintScale, f); calmaOutI4(lbref->lb_start.p_y * calmaPaintScale, f); chkcount++; } calmaOutI4(listtop->lb_start.p_x * calmaPaintScale, f); calmaOutI4(listtop->lb_start.p_y * calmaPaintScale, f); if (chkcount != bounds->bt_points) TxError("Points recorded=%d; Points written=%d\n", bounds->bt_points, chkcount); /* End of element */ calmaOutRH(4, CALMA_ENDEL, CALMA_NODATA, f); #ifdef DEBUG /* Diagnostic: report the contents of the list */ TxPrintf("Polygon path (%d points):\n", bounds->bt_points); listtop = bounds->bt_first; lbstop = NULL; for (lbref = listtop; lbref != lbstop; lbref = lbref->lb_next) { if (lbref != listtop) TxPrintf("->"); else lbstop = listtop; switch(lbref->lb_type) { case LB_EXTERNAL: TxPrintf("(%d %d)", lbref->lb_start.p_x, lbref->lb_start.p_y); break; case LB_INTERNAL: TxPrintf("[[%d %d]]", lbref->lb_start.p_x, lbref->lb_start.p_y); break; case LB_INIT: TxPrintf("XXXXX"); break; } } TxPrintf("\n\n"); #endif /* Free the LinkedBoundary list */ lbref = listtop; while (lbref->lb_next != listtop) { freeMagic(lbref); lbref = lbref->lb_next; } freeMagic(lbref); } /* Free the BoundaryTop list */ for (bounds = blist; bounds != NULL; bounds = bounds->bt_next) freeMagic(bounds); } /* * ---------------------------------------------------------------------------- * * calmaMergePaintFunc -- * * Results: * None. * * Side effects: * Writes to the disk file. * * ---------------------------------------------------------------------------- */ int calmaMergePaintFunc(tile, cos) Tile *tile; /* Tile to be written out. */ calmaOutputStruct *cos; /* Information needed by algorithm */ { FILE *f = cos->f; Rect *clipArea = cos->area; Tile *t, *tp; TileType ttype; int i, llx, lly, urx, ury, intedges, num_points, split_type; bool is_ext; static Stack *SegStack = (Stack *)NULL; static LinkedBoundary *edge; LinkedBoundary *lb; BoundaryTop *bounds = NULL; /* Quick check for tiles that have already been processed */ if (tile->ti_client == (ClientData)GDS_PROCESSED) return 0; if (SegStack == (Stack *)NULL) SegStack = StackNew(64); PUSHTILE(tile); while (!StackEmpty(SegStack)) { t = (Tile *) STACKPOP(SegStack); if (t->ti_client != (ClientData)GDS_PENDING) continue; t->ti_client = (ClientData)GDS_PROCESSED; split_type = -1; if (IsSplit(t)) { /* If we use SplitSide, then we need to set it when the */ /* tile is pushed. Since these are one-or-zero mask layers */ /* I assume it is okay to just check which side is TT_SPACE */ /* split_type = (SplitSide(t) << 1) | SplitDirection(t); */ split_type = SplitDirection(t); if (TiGetLeftType(t) == TT_SPACE) split_type |= 2; num_points = 2; if (edge != NULL) { /* Remove one point from the edge record for rectangles */ /* and relink the last entry back to the new head. */ lb = edge; while (lb->lb_next != edge) lb = lb->lb_next; lb->lb_next = edge->lb_next; freeMagic(edge); edge = edge->lb_next; } } else num_points = 3; /* Create a new linked boundary structure with 4 unknown edges. */ /* This structure is reused when we encounter isolated tiles, */ /* so we avoid unnecessary overhead in the case of, for */ /* example, large contact cut arrays. */ if (edge == NULL) { edge = (LinkedBoundary *)mallocMagic(sizeof(LinkedBoundary)); lb = edge; for (i = 0; i < num_points; i++) { lb->lb_type = LB_INIT; lb->lb_next = (LinkedBoundary *)mallocMagic(sizeof(LinkedBoundary)); lb = lb->lb_next; } lb->lb_type = LB_INIT; lb->lb_next = edge; } lb = edge; llx = LEFT(t); lly = BOTTOM(t); urx = RIGHT(t); ury = TOP(t); intedges = 0; /* Initialize the "edge" record with the corner points of the */ /* tile. */ if (IsSplit(t)) { switch (split_type) { case 0x0: lb->lb_start.p_x = urx; lb->lb_start.p_y = ury; lb->lb_type = LB_INIT; lb = lb->lb_next; lb->lb_start.p_x = llx; lb->lb_start.p_y = ury; lb->lb_type = LB_INIT; lb = lb->lb_next; lb->lb_start.p_x = llx; lb->lb_start.p_y = lly; lb->lb_type = LB_INIT; lb = lb->lb_next; break; case 0x1: lb->lb_start.p_x = llx; lb->lb_start.p_y = ury; lb->lb_type = LB_INIT; lb = lb->lb_next; lb->lb_start.p_x = llx; lb->lb_start.p_y = lly; lb->lb_type = LB_INIT; lb = lb->lb_next; lb->lb_start.p_x = urx; lb->lb_start.p_y = lly; lb->lb_type = LB_INIT; lb = lb->lb_next; break; case 0x2: lb->lb_start.p_x = urx; lb->lb_start.p_y = ury; lb->lb_type = LB_INIT; lb = lb->lb_next; lb->lb_start.p_x = llx; lb->lb_start.p_y = lly; lb->lb_type = LB_INIT; lb = lb->lb_next; lb->lb_start.p_x = urx; lb->lb_start.p_y = lly; lb->lb_type = LB_INIT; lb = lb->lb_next; break; case 0x3: lb->lb_start.p_x = urx; lb->lb_start.p_y = ury; lb->lb_type = LB_INIT; lb = lb->lb_next; lb->lb_start.p_x = llx; lb->lb_start.p_y = ury; lb->lb_type = LB_INIT; lb = lb->lb_next; lb->lb_start.p_x = urx; lb->lb_start.p_y = lly; lb->lb_type = LB_INIT; lb = lb->lb_next; break; } num_points = 1; } else { lb->lb_start.p_x = urx; lb->lb_start.p_y = ury; lb->lb_type = LB_INIT; lb = lb->lb_next; lb->lb_start.p_x = llx; lb->lb_start.p_y = ury; lb->lb_type = LB_INIT; lb = lb->lb_next; lb->lb_start.p_x = llx; lb->lb_start.p_y = lly; lb->lb_type = LB_INIT; lb = lb->lb_next; lb->lb_start.p_x = urx; lb->lb_start.p_y = lly; lb->lb_type = LB_INIT; lb = lb->lb_next; num_points = 0; } if (split_type == 0x1) goto left_search; /* Search the tile boundary for connected and unconnected tiles. */ /* Generate segments in a counterclockwise cycle. */ if (split_type == 0x2) { intedges += calmaAddSegment(&lb, TRUE, RIGHT(t), TOP(t), LEFT(t), BOTTOM(t)); goto bottom_search; } /* Search top */ ttype = TiGetTopType(t); for (tp = RT(t); RIGHT(tp) > LEFT(t); tp = BL(tp), num_points++) { is_ext = (TiGetBottomType(tp) != ttype) ? TRUE : FALSE; intedges += calmaAddSegment(&lb, is_ext, MIN(RIGHT(t), RIGHT(tp)), TOP(t), MAX(LEFT(t), LEFT(tp)), TOP(t)); if (!is_ext) PUSHTILE(tp); } if (split_type == 0x3) { intedges += calmaAddSegment(&lb, TRUE, LEFT(t), TOP(t), RIGHT(t), BOTTOM(t)); goto right_search; } /* Search left */ left_search: ttype = TiGetLeftType(t); for (tp = BL(t); BOTTOM(tp) < TOP(t); tp = RT(tp), num_points++) { is_ext = (TiGetRightType(tp) != ttype) ? TRUE : FALSE; intedges += calmaAddSegment(&lb, is_ext, LEFT(t), MIN(TOP(t), TOP(tp)), LEFT(t), MAX(BOTTOM(t), BOTTOM(tp))); if (!is_ext) PUSHTILE(tp); } if (split_type == 0x0) { intedges += calmaAddSegment(&lb, TRUE, LEFT(t), BOTTOM(t), RIGHT(t), TOP(t)); goto done_searches; } /* Search bottom */ bottom_search: ttype = TiGetBottomType(t); for (tp = LB(t); LEFT(tp) < RIGHT(t); tp = TR(tp), num_points++) { is_ext = (TiGetTopType(tp) != ttype) ? TRUE : FALSE; intedges += calmaAddSegment(&lb, is_ext, MAX(LEFT(t), LEFT(tp)), BOTTOM(t), MIN(RIGHT(t), RIGHT(tp)), BOTTOM(t)); if (!is_ext) PUSHTILE(tp); } if (split_type == 0x1) { intedges += calmaAddSegment(&lb, TRUE, RIGHT(t), BOTTOM(t), LEFT(t), TOP(t)); goto done_searches; } /* Search right */ right_search: ttype = TiGetRightType(t); for (tp = TR(t); TOP(tp) > BOTTOM(t); tp = LB(tp), num_points++) { is_ext = (TiGetLeftType(tp) != ttype) ? TRUE : FALSE; intedges += calmaAddSegment(&lb, is_ext, RIGHT(t), MAX(BOTTOM(t), BOTTOM(tp)), RIGHT(t), MIN(TOP(t), TOP(tp))); if (!is_ext) PUSHTILE(tp); } /* If tile is isolated, process it now and we're done */ done_searches: if (intedges == 0) { calmaWritePaintFunc(t, cos); /* Although calmaWritePaintFunc is called only on isolated */ /* tiles, we may have expanded it. This could use a LOT of */ /* optimizing. 1) remove colinear points in calmaAddSegment */ /* when both subsegments are external paths, and 2) here, */ /* take the shortest path to making "edge" exactly 4 points.*/ /* Note that in non-Manhattan mode, num_points may be 3. */ if (num_points != 4) { for (i = 0; i < num_points; i++) { freeMagic(edge); edge = edge->lb_next; } edge = NULL; } if (!StackEmpty(SegStack)) TxError("ERROR: Segment stack is supposed to be empty!\n"); else return 0; } else { /* Merge boundary into existing record */ calmaMergeSegments(edge, &bounds, num_points); edge = NULL; } } /* Remove any degenerate points */ calmaRemoveDegenerate(bounds); /* Remove any colinear points */ calmaRemoveColinear(bounds); /* Output the boundary records */ calmaProcessBoundary(bounds, cos); return 0; /* Keep the search alive. . . */ } /* * ---------------------------------------------------------------------------- * * calmaWritePaintFunc -- * * Filter function used to write out a single paint tile. * * **** NOTE **** * There are loads of Calma systems out in the world that * don't understand CALMA_BOX, so we output CALMA_BOUNDARY * even though CALMA_BOX is more appropriate. Bletch. * * Results: * None. * * Side effects: * Writes to the disk file. * * ---------------------------------------------------------------------------- */ int calmaWritePaintFunc(tile, cos) Tile *tile; /* Tile to be written out. */ calmaOutputStruct *cos; /* File for output and clipping area */ { FILE *f = cos->f; Rect *clipArea = cos->area; Rect r, r2; TiToRect(tile, &r); if (clipArea != NULL) GeoClip(&r, clipArea); r.r_xbot *= calmaPaintScale; r.r_ybot *= calmaPaintScale; r.r_xtop *= calmaPaintScale; r.r_ytop *= calmaPaintScale; /* Boundary */ calmaOutRH(4, CALMA_BOUNDARY, CALMA_NODATA, f); /* Layer */ calmaOutRH(6, CALMA_LAYER, CALMA_I2, f); calmaOutI2(calmaPaintLayerNumber, f); /* Data type */ calmaOutRH(6, CALMA_DATATYPE, CALMA_I2, f); calmaOutI2(calmaPaintLayerType, f); /* The inefficient use of CALMA_BOUNDARY for rectangles actually */ /* makes it easy to implement triangles, since they must be defined */ /* by CALMA_BOUNDARY. */ if (IsSplit(tile)) { /* Coordinates */ calmaOutRH(36, CALMA_XY, CALMA_I4, f); switch ((SplitSide(tile) << 1) | SplitDirection(tile)) { case 0x0: calmaOutI4(r.r_xbot, f); calmaOutI4(r.r_ybot, f); calmaOutI4(r.r_xbot, f); calmaOutI4(r.r_ytop, f); calmaOutI4(r.r_xtop, f); calmaOutI4(r.r_ytop, f); calmaOutI4(r.r_xbot, f); calmaOutI4(r.r_ybot, f); break; case 0x1: calmaOutI4(r.r_xbot, f); calmaOutI4(r.r_ytop, f); calmaOutI4(r.r_xbot, f); calmaOutI4(r.r_ybot, f); calmaOutI4(r.r_xtop, f); calmaOutI4(r.r_ybot, f); calmaOutI4(r.r_xbot, f); calmaOutI4(r.r_ytop, f); break; case 0x2: calmaOutI4(r.r_xbot, f); calmaOutI4(r.r_ybot, f); calmaOutI4(r.r_xtop, f); calmaOutI4(r.r_ybot, f); calmaOutI4(r.r_xtop, f); calmaOutI4(r.r_ytop, f); calmaOutI4(r.r_xbot, f); calmaOutI4(r.r_ybot, f); break; case 0x3: calmaOutI4(r.r_xbot, f); calmaOutI4(r.r_ytop, f); calmaOutI4(r.r_xtop, f); calmaOutI4(r.r_ytop, f); calmaOutI4(r.r_xtop, f); calmaOutI4(r.r_ybot, f); calmaOutI4(r.r_xbot, f); calmaOutI4(r.r_ytop, f); break; } } else { /* Coordinates */ calmaOutRH(44, CALMA_XY, CALMA_I4, f); calmaOutI4(r.r_xbot, f); calmaOutI4(r.r_ybot, f); calmaOutI4(r.r_xtop, f); calmaOutI4(r.r_ybot, f); calmaOutI4(r.r_xtop, f); calmaOutI4(r.r_ytop, f); calmaOutI4(r.r_xbot, f); calmaOutI4(r.r_ytop, f); calmaOutI4(r.r_xbot, f); calmaOutI4(r.r_ybot, f); } /* End of element */ calmaOutRH(4, CALMA_ENDEL, CALMA_NODATA, f); return 0; } /* * ---------------------------------------------------------------------------- * * calmaWriteLabelFunc -- * * Output a single label to the stream file 'f'. * * The CIF type to which this label is attached is 'type'; if this * is < 0 then the label is not output. * * Non-point labels are collapsed to point labels located at the center * of the original label. * * Results: * None. * * Side effects: * Writes to the FILE 'f'. * * ---------------------------------------------------------------------------- */ void calmaWriteLabelFunc(lab, type, f) Label *lab; /* Label to output */ int type; /* CIF layer number, or -1 if not attached to a layer */ FILE *f; /* Stream file */ { Point p; int calmanum; if (type < 0) return; calmanum = CIFCurStyle->cs_layers[type]->cl_calmanum; if (!CalmaIsValidLayer(calmanum)) return; calmaOutRH(4, CALMA_TEXT, CALMA_NODATA, f); calmaOutRH(6, CALMA_LAYER, CALMA_I2, f); calmaOutI2(calmanum, f); calmaOutRH(6, CALMA_TEXTTYPE, CALMA_I2, f); calmaOutI2(CIFCurStyle->cs_layers[type]->cl_calmatype, f); if (lab->lab_font >= 0) { unsigned short textpres = 0; /* A bit of a hack here. Magic can have any number of fonts, */ /* but GDS only allows four of them. So we just crop the font */ /* index to two bits. We provide no other font information, so */ /* this is highly implementation-dependent. But it allows us */ /* to retain font information when reading and writing our own */ /* GDS files. */ textpres = (lab->lab_font & 0x03) << 4; switch(lab->lab_just) { case GEO_SOUTH: textpres |= 0x0001; break; case GEO_SOUTHEAST: textpres |= 0x0000; break; case GEO_EAST: textpres |= 0x0004; break; case GEO_NORTHEAST: textpres |= 0x0008; break; case GEO_NORTH: textpres |= 0x0009; break; case GEO_NORTHWEST: textpres |= 0x000a; break; case GEO_WEST: textpres |= 0x0006; break; case GEO_SOUTHWEST: textpres |= 0x0002; break; case GEO_CENTER: textpres |= 0x0005; break; } calmaOutRH(6, CALMA_PRESENTATION, CALMA_BITARRAY, f); calmaOutI2(textpres, f); calmaOutRH(6, CALMA_STRANS, CALMA_BITARRAY, f); calmaOutI2(0, f); /* Any need for these bits? */ calmaOutRH(12, CALMA_MAG, CALMA_R8, f); calmaOutR8(((double)lab->lab_size / 800) * (double)CIFCurStyle->cs_scaleFactor / (double)CIFCurStyle->cs_expander, f); if (lab->lab_rotate != 0) { calmaOutRH(12, CALMA_ANGLE, CALMA_R8, f); calmaOutR8((double)lab->lab_rotate, f); } } p.p_x = (lab->lab_rect.r_xbot + lab->lab_rect.r_xtop) * calmaWriteScale / 2; p.p_y = (lab->lab_rect.r_ybot + lab->lab_rect.r_ytop) * calmaWriteScale / 2; calmaOutRH(12, CALMA_XY, CALMA_I4, f); calmaOutI4(p.p_x, f); calmaOutI4(p.p_y, f); /* Text of label */ calmaOutStringRecord(CALMA_STRING, lab->lab_text, f); /* End of element */ calmaOutRH(4, CALMA_ENDEL, CALMA_NODATA, f); } /* * ---------------------------------------------------------------------------- * * calmaOutHeader -- * * Output the header description for a Calma file. * * Results: * None. * * Side effects: * Writes to the FILE 'f'. * * ---------------------------------------------------------------------------- */ void calmaOutHeader(rootDef, f) CellDef *rootDef; FILE *f; { static double useru = 0.001; static double mum = 1.0e-9; /* GDS II version 3.0 */ calmaOutRH(6, CALMA_HEADER, CALMA_I2, f); calmaOutI2(3, f); /* Beginning of library */ calmaOutRH(28, CALMA_BGNLIB, CALMA_I2, f); calmaOutDate(rootDef->cd_timestamp, f); calmaOutDate(time((time_t *) 0), f); /* Library name (name of root cell) */ calmaOutStructName(CALMA_LIBNAME, rootDef, f); /* * Units. * User units are microns; this is really unimportant. * * Database units are nanometers, since there are * programs that don't understand anything else. If * the database units are *smaller* than nanometers, use * the actual database units. Otherwise, stick with * nanometers, because anything larger may not input * properly with other software. */ calmaOutRH(20, CALMA_UNITS, CALMA_R8, f); if (CIFCurStyle->cs_flags & CWF_ANGSTROMS) useru = 0.0001; calmaOutR8(useru, f); /* User units per database unit */ if (CIFCurStyle->cs_flags & CWF_ANGSTROMS) mum = 1e-10; calmaOutR8(mum, f); /* Meters per database unit */ } /* * ---------------------------------------------------------------------------- * * calmaOutDate -- * * Output a date/time specification to the FILE 'f'. * This consists of outputting 6 2-byte quantities, * or a total of 12 bytes. * * Results: * None. * * Side effects: * Writes to the FILE 'f'. * * ---------------------------------------------------------------------------- */ void calmaOutDate(t, f) time_t t; /* Time (UNIX format) to be output */ FILE *f; /* Stream file */ { struct tm *datep = localtime(&t); calmaOutI2(datep->tm_year, f); calmaOutI2(datep->tm_mon+1, f); calmaOutI2(datep->tm_mday, f); calmaOutI2(datep->tm_hour, f); calmaOutI2(datep->tm_min, f); calmaOutI2(datep->tm_sec, f); } /* * ---------------------------------------------------------------------------- * * calmaOutStringRecord -- * * Output a complete string-type record. The actual record * type is given by 'type'. Up to the first CALMANAMELENGTH characters * of the string 'str' are output. Any characters in 'str' * not in the legal Calma stream character set are output as * 'X' instead. * * Results: * None. * * Side effects: * Writes to the FILE 'f'. * * ---------------------------------------------------------------------------- */ void calmaOutStringRecord(type, str, f) int type; /* Type of this record (data type is ASCII string) */ char *str; /* String to be output (<= CALMANAMELENGTH chars) */ FILE *f; /* Stream file */ { int len; unsigned char c; char *table, *locstr, *origstr = NULL; char *locstrprv; /* Added by BSI */ if(CIFCurStyle->cs_flags & CWF_PERMISSIVE_LABELS) { table = calmaMapTablePermissive; } else { table = calmaMapTableStrict; } len = strlen(str); locstr = str; /* * Make sure length is even. * Output at most CALMANAMELENGTH characters. */ if (len & 01) len++; if (len > CALMANAMELENGTH) len = CALMANAMELENGTH; calmaOutI2(len+4, f); /* Record length */ (void) putc(type, f); /* Record type */ (void) putc(CALMA_ASCII, f); /* Data type */ /* Output the string itself */ while (len--) { locstrprv = locstr; c = (unsigned char) *locstr++; if (c == 0) putc('\0', f); else { if ((c > 127) || (c == 0)) { TxError("Warning: Unprintable character changed " "to \'X\' in label.\n"); c = 'X'; } else { if (((unsigned char)table[c] != c) && (origstr == NULL)) origstr = StrDup(NULL, str); c = table[c]; locstrprv[0] = c; } if (!CalmaDoLower && islower(c)) (void) putc(toupper(c), f); else (void) putc(c, f); } } if (origstr != NULL) { TxError("Warning: characters changed in string \'%s\'; " "modified string is \'%s\'\n", origstr, str); freeMagic(origstr); } } /* * ---------------------------------------------------------------------------- * * calmaOutR8 -- * * Write an 8-byte Real value in GDS-II format to the output stream * The value is passed as a double. * * Results: * None. * * Side effects: * 8-byte value written to output stream FILE 'f'. * * ---------------------------------------------------------------------------- */ void calmaOutR8(d, f) double d; /* Double value to write to output */ FILE *f; /* Stream file */ { int c, i, sign, expon; /* mantissa must be 64 bits for this routine to work correctly */ #if SIZEOF_UNSIGNED_LONG == 8 unsigned long mantissa; #else unsigned long long mantissa; #endif mantissa = 0; if (d == 0.0) { sign = 0; expon = 0; } else { if (d > 0.0) sign = 0; else { sign = 1; d = -d; } expon = 64; while (d >= 1.0) { d /= 16.0; expon++; } while (d < 0.0625) { d *= 16.0; expon--; } for (i = 0; i < 64; i++) { mantissa <<= 1; if (d >= 0.5) { mantissa |= 0x1; d -= 0.5; } d *= 2.0; } } c = (sign << 7) | expon; (void) putc(c, f); for (i = 1; i < 8; i++) { c = (int)(0xff & (mantissa >> (64 - (8 * i)))); (void) putc(c, f); } } /* * ---------------------------------------------------------------------------- * * calmaOut8 -- * * Output 8 bytes. * * Results: * None. * * Side effects: * Writes to the FILE 'f'. * * ---------------------------------------------------------------------------- */ void calmaOut8(str, f) char *str; /* 8-byte string to be output */ FILE *f; /* Stream file */ { int i; for (i = 0; i < 8; i++) (void) putc(*str++, f); } magic-8.0.210/calma/CalmaRdcl.c0000664000175000001440000006614012361751705014535 0ustar timusers/* * CalmaReadcell.c -- * * Input of Calma GDS-II stream format. * Processing for cells. * * ********************************************************************* * * 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/calma/CalmaRdcl.c,v 1.5 2010/06/25 13:59:24 tim Exp $"; #endif /* not lint */ #include #include #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/utils.h" #include "utils/hash.h" #include "database/database.h" #include "database/databaseInt.h" #include "utils/malloc.h" #include "utils/tech.h" #include "cif/cif.h" #include "cif/CIFint.h" #include "cif/CIFread.h" #include "utils/signals.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "utils/styles.h" #include "textio/textio.h" #include "calma/calmaInt.h" #include "calma/calma.h" int calmaNonManhattan; extern void CIFPaintCurrent(); extern HashTable calmaDefInitHash; /* forward declarations */ void calmaElementSref(); bool calmaParseElement(); /* Structure used when flattening the GDS hierarchy on read-in */ typedef struct { Plane *plane; Transform *trans; } GDSCopyRec; /* Added by NP 8/11/04 */ /* * ---------------------------------------------------------------------------- * * calmaSetPosition -- * * This routine sets the file pointer calmaInputFile to the start * of the CellDefinition "sname". It starts the search from the * current position and looks forward to find the Cell Definition * named "sname". * * Results: * Current position of file pointer before it jumps to the * definition of cell "sname" (if it exists, otherwise, returns * end-of-file). * * Side Effects: * The file position is set to the definition of cell "sname". If * "sname" does not exist in the GDS stream file, the pointer is * set to the end of the file. * * ---------------------------------------------------------------------------- */ off_t calmaSetPosition(sname) char *sname; { off_t originalPos = 0, currentPos = 0; int nbytes, rtype; char *strname = NULL; int strRecSize = 0; bool found = FALSE; originalPos = ftello(calmaInputFile); while (feof(calmaInputFile) == 0) { do { READRH(nbytes, rtype); /* Read header */ if (nbytes <= 0) break; /* Skip no of bytes in record header until * we reach to next structure record. */ fseek(calmaInputFile, nbytes - CALMAHEADERLENGTH, SEEK_CUR); } while (rtype != CALMA_BGNSTR); if (nbytes <= 0) break; calmaReadStringRecord(CALMA_STRNAME, &strname); if ((strcmp(sname, strname)) == 0) { /* If name if structure matches with given name, * we got that Cell Defination. Set position of * file to start of that structure. */ strRecSize = strlen(strname); if (strRecSize & 01) strRecSize++; fseek(calmaInputFile, -(nbytes + strRecSize + CALMAHEADERLENGTH), SEEK_CUR); freeMagic(strname); return originalPos; } freeMagic(strname); } // Ran out of file. It's possible that we were seeking ahead to a // definition that called something that was defined between it and // our previous position, so we will rewind the file and try again. // If that doesn't work, then the cell is not defined in the file. if (originalPos != 0) { rewind(calmaInputFile); calmaSetPosition(sname); return originalPos; } calmaReadError("Cell \"%s\" is used but not defined in this file.\n", sname); return originalPos; } /* Added by NP 8/11/04 */ /* * ---------------------------------------------------------------------------- * * calmaNextCell -- * * This routine sets the file pointer to next Cell Definition * in the GDS stream. It goes only in the forward direction * from the current position of the file pointer. * * Results: * None. * * Side Effects: * File pointer set to start of next Cell definition. * * ---------------------------------------------------------------------------- */ void calmaNextCell() { int nbytes, rtype; if (feof(calmaInputFile) == 0) { do { READRH(nbytes, rtype); /* Read header */ if (nbytes <= 0) { /* We have reached the end of the file. There are no * more cell definitions remaining to read. * Set file pointer to CALMA_ENDLIB record. */ fseek(calmaInputFile, -(CALMAHEADERLENGTH), SEEK_END); return; } /* Skip no. of bytes in record header to reach the next * structure record. */ fseek(calmaInputFile, nbytes - CALMAHEADERLENGTH, SEEK_CUR); } while(rtype != CALMA_BGNSTR); fseek(calmaInputFile, -nbytes, SEEK_CUR); } } /* * ---------------------------------------------------------------------------- * * calmaExact -- * * When dictated to flatten small cells (e.g., vias which have been placed * into their own cells to make use of GDS arrays), instead of calling * CIFPaintCurrent(), we just transfer the planes of cifCurReadPlanes to * the current cell, and swap the planes from the current cell into the * pointer array for cifCurReadPlanes, so we don't have to free and * reallocate any memory for the operation. Flag the cell as being a * CIF cell, so that it can be destroyed after read-in and flattening. * * Results: * Pointer to the plane structure created to hold the GDS data. * * Side Effects: * Swaps the planes of cifReadCellDef with cifCurReadPlanes. * * ---------------------------------------------------------------------------- */ Plane ** calmaExact() { int pNum; Plane *newplane; Plane **parray; int gdsCopyPaintFunc(); /* Forward reference */ parray = (Plane **)mallocMagic(MAXCIFRLAYERS * sizeof(Plane *)); for (pNum = 0; pNum < MAXCIFRLAYERS; pNum++) { if (cifCurReadPlanes[pNum] != NULL) { GDSCopyRec gdsCopyRec; newplane = DBNewPlane((ClientData) TT_SPACE); DBClearPaintPlane(newplane); gdsCopyRec.plane = newplane; gdsCopyRec.trans = NULL; DBSrPaintArea((Tile *)NULL, cifCurReadPlanes[pNum], &TiPlaneRect, &DBAllButSpaceBits, gdsCopyPaintFunc, &gdsCopyRec); parray[pNum] = newplane; } else parray[pNum] = NULL; } /* Clear out the current paint planes for the next cell */ for (pNum = 0; pNum < MAXCIFRLAYERS; pNum++) DBClearPaintPlane(cifCurReadPlanes[pNum]); return parray; } /* * ---------------------------------------------------------------------------- * * calmaParseStructure -- * * Process a complete GDS-II structure (cell) including its closing * CALMA_ENDSTR record. In the event of a syntax error, we skip * ahead to the closing CALMA_ENDSTR, output a warning, and keep going. * * Results: * TRUE if successful, FALSE if the next item in the input is * not a structure. * * Side effects: * Reads a new cell. * Consumes input. * * ---------------------------------------------------------------------------- */ bool calmaParseStructure(filename) char *filename; /* Name of the GDS file read */ { static int structs[] = { CALMA_STRCLASS, CALMA_STRTYPE, -1 }; int nbytes, rtype, nsrefs, osrefs, npaths; char *strname = NULL, newname[CALMANAMELENGTH*2]; HashEntry *he; int suffix; int mfactor; off_t filepos; bool was_called; CellDef *def; /* Make sure this is a structure; if not, let the caller know we're done */ PEEKRH(nbytes, rtype); if (nbytes <= 0 || rtype != CALMA_BGNSTR) return (FALSE); /* Read the structure name */ if (!calmaSkipExact(CALMA_BGNSTR)) goto syntaxerror;; if (!calmaReadStringRecord(CALMA_STRNAME, &strname)) goto syntaxerror; TxPrintf("Reading \"%s\".\n", strname); if (CalmaReadOnly) filepos = ftello(calmaInputFile); /* Set up the cell definition */ he = HashFind(&calmaDefInitHash, strname); if ((def = (CellDef *)HashGetValue(he)) != NULL) { if (def->cd_flags & CDPROCESSEDGDS) { /* If cell definition was marked as processed, then skip */ calmaNextCell(); return TRUE; } else { for (suffix = 1; HashGetValue(he) != NULL; suffix++) { (void) sprintf(newname, "%s_%d", strname, suffix); he = HashFind(&calmaDefInitHash, newname); } calmaReadError("Cell \"%s\" was already defined in this file.\n", strname); calmaReadError("Giving this cell a new name: %s\n", newname); strncpy(strname, newname, CALMANAMELENGTH*2); } } cifReadCellDef = calmaFindCell(strname, &was_called); DBCellClearDef(cifReadCellDef); DBCellSetAvail(cifReadCellDef); HashSetValue(he, cifReadCellDef); cifCurReadPlanes = cifSubcellPlanes; /* Done with strname */ if (strname != NULL) freeMagic(strname); /* For read-only cells, set flag in def */ if (CalmaReadOnly) cifReadCellDef->cd_flags |= CDVENDORGDS; /* Skip CALMA_STRCLASS or CALMA_STRTYPE */ calmaSkipSet(structs); /* Initialize the hash table for layer errors */ HashInit(&calmaLayerHash, 32, sizeof (CalmaLayerType) / sizeof (unsigned)); /* Body of structure: a sequence of elements */ osrefs = nsrefs = 0; npaths = 0; calmaNonManhattan = 0; while (calmaParseElement(&nsrefs, &npaths)) { if (SigInterruptPending) goto done; if (nsrefs > osrefs && (nsrefs % 100) == 0) TxPrintf(" %d uses\n", nsrefs); osrefs = nsrefs; calmaNonManhattan = 0; } /* Make sure it ends with an ENDSTR record */ if (!calmaSkipExact(CALMA_ENDSTR)) goto syntaxerror; if (CalmaReadOnly) { /* Writing the file position into a string is slow, but */ /* it prevents requiring special handling when printing */ /* out the properties. */ char *fpcopy = (char *)mallocMagic(20); char *fncopy = StrDup(NULL, filename); sprintf(fpcopy, "%"DLONG_PREFIX"d", (dlong) filepos); DBPropPut(cifReadCellDef, "GDS_START", (ClientData)fpcopy); fpcopy = (char *)mallocMagic(20); filepos = ftello(calmaInputFile); sprintf(fpcopy, "%"DLONG_PREFIX"d", (dlong) filepos); DBPropPut(cifReadCellDef, "GDS_END", (ClientData)fpcopy); DBPropPut(cifReadCellDef, "GDS_FILE", (ClientData)fncopy); /* Do not lock the cell, or else we can't save the */ /* magic cell with its GDS pointers to disk. . . */ /* cifReadCellDef->cd_flags |= CDNOEDIT; */ } /* * Don't paint now, just keep the CIF planes, and flatten the * cell by painting when instanced. But---if this cell was * instanced before it was defined, then it can't be flattened. */ if (CalmaFlattenUses && (!was_called) && (npaths < 10) && (nsrefs == 0)) { TxPrintf("Flattening cell %s\n", cifReadCellDef->cd_name); cifReadCellDef->cd_client = (ClientData) calmaExact(); cifReadCellDef->cd_flags |= CDFLATGDS; } else { /* * Do the geometrical processing and paint this material back into * the appropriate cell of the database. */ CIFPaintCurrent(); } DBAdjustLabelsNew(cifReadCellDef, &TiPlaneRect, (cifCurReadStyle->crs_flags & CRF_NO_RECONNECT_LABELS) ? 1 : 0); DBReComputeBbox(cifReadCellDef); /* Don't bother to register with DRC if we're going to delete the */ /* cell, or if the cell is read-only, or if "calma drcnocheck true" */ /* has been issued. */ if (!CalmaFlattenUses || (npaths >= 10) || (nsrefs != 0)) if (!CalmaReadOnly && !CalmaNoDRCCheck) DRCCheckThis(cifReadCellDef, TT_CHECKPAINT, &cifReadCellDef->cd_bbox); DBWAreaChanged(cifReadCellDef, &cifReadCellDef->cd_bbox, DBW_ALLWINDOWS, &DBAllButSpaceBits); DBCellSetModified(cifReadCellDef, TRUE); /* * Assign use-identifiers to all the cell uses. * These identifiers are generated so as to be * unique. */ DBGenerateUniqueIds(cifReadCellDef, FALSE); cifReadCellDef->cd_flags |= CDPROCESSEDGDS; done: HashKill(&calmaLayerHash); return (TRUE); /* Syntax error: skip to CALMA_ENDSTR */ syntaxerror: HashKill(&calmaLayerHash); return (calmaSkipTo(CALMA_ENDSTR)); } /* * ---------------------------------------------------------------------------- * * calmaParseElement -- * * Process one element from a GDS-II structure, including its * trailing CALMA_ENDEL record. In the event of a syntax error, we skip * ahead to the closing CALMA_ENDEL, output a warning, and keep going. * * Results: * TRUE if we processed an element, FALSE when we reach something that * is not an element. In the latter case, we leave the non-element * record unconsumed. * * Side effects: * Consumes input. * Depends on the kind of element encountered. * If we process a SREF or AREF, increment *pnsrefs. * * ---------------------------------------------------------------------------- */ bool calmaParseElement(pnsrefs, pnpaths) int *pnsrefs, *pnpaths; { static int node[] = { CALMA_ELFLAGS, CALMA_PLEX, CALMA_LAYER, CALMA_NODETYPE, CALMA_XY, -1 }; int nbytes, rtype; READRH(nbytes, rtype); if (nbytes < 0) { calmaReadError("Unexpected EOF.\n"); return (FALSE); } switch (rtype) { case CALMA_AREF: case CALMA_SREF: calmaElementSref(); (*pnsrefs)++; break; case CALMA_BOUNDARY: calmaElementBoundary(); (*pnpaths)++; break; case CALMA_BOX: calmaElementBox(); (*pnpaths)++; break; case CALMA_PATH: calmaElementPath(); (*pnpaths)++; break; case CALMA_TEXT: calmaElementText(); break; case CALMA_NODE: calmaReadError("NODE elements not supported: skipping.\n"); calmaSkipSet(node); break; default: UNREADRH(nbytes, rtype); return (FALSE); } return (calmaSkipTo(CALMA_ENDEL)); } /* * ---------------------------------------------------------------------------- * * calmaElementSref -- * * Process a structure reference (either CALMA_SREF or CALMA_AREF). * * Results: * None. * * Side effects: * Consumes input. * Adds a new cell use to the current def. * * ---------------------------------------------------------------------------- */ void calmaElementSref() { int nbytes, rtype, cols, rows, nref, n, i, savescale; int xlo, ylo, xhi, yhi, xsep, ysep; char *sname = NULL; bool isArray = FALSE; Transform trans, tinv; Point refarray[3], p; CellUse *use; CellDef *def; int gdsCopyPaintFunc(); /* Forward reference */ /* Added by NP */ char *useid = NULL, *arraystr = NULL; int propAttrType; /* Skip CALMA_ELFLAGS, CALMA_PLEX */ calmaSkipSet(calmaElementIgnore); /* Read subcell name */ if (!calmaReadStringRecord(CALMA_SNAME, &sname)) return; /* * Create a new cell use with this transform. If the * cell being referenced doesn't exist, create it. * Don't give it a use-id; we will do that only after * we've placed all cells. */ def = calmaLookCell(sname); if (!def && (CalmaPostOrder || CalmaFlattenUses)) { /* Force the GDS parser to read the cell definition in * post-order. If cellname "sname" is not defined before * it is used, then read the cell definition by jumping * to its position in the stream file, reading that * instance, and then returning to the current file * position. Note that this routine should be optimized * for the likely case where many cells are defined at * the end of the file; otherwise it will slow down the * read process excessively for large GDS files by * constantly moving from beginning to end of the file. * * Added by Nishit 8/16/2004 */ off_t originalFilePos = calmaSetPosition(sname); if (!feof(calmaInputFile)) { HashTable OrigCalmaLayerHash; int crsMultiplier = cifCurReadStyle->crs_multiplier; char *currentSname = cifReadCellDef->cd_name; OrigCalmaLayerHash = calmaLayerHash; cifReadCellDef->cd_client = (ClientData)calmaExact(); /* Read cell definition "sname". */ calmaParseStructure(); /* Put things back to the way they were. */ fseek(calmaInputFile, originalFilePos, SEEK_SET); cifReadCellDef = calmaLookCell(currentSname); def = calmaLookCell(sname); cifCurReadPlanes = (Plane **)cifReadCellDef->cd_client; cifReadCellDef->cd_client = (ClientData)NULL; calmaLayerHash = OrigCalmaLayerHash; if (crsMultiplier != cifCurReadStyle->crs_multiplier) { int scalen, scaled; if (crsMultiplier > cifCurReadStyle->crs_multiplier) { scalen = crsMultiplier / cifCurReadStyle->crs_multiplier; scaled = 1; } else { scalen = 1; scaled = cifCurReadStyle->crs_multiplier / crsMultiplier; } CIFScalePlanes(scalen, scaled, cifCurReadPlanes); } } else { TxPrintf("Cell definition %s does not exist!\n", sname); fseek(calmaInputFile, originalFilePos, SEEK_SET); def = calmaFindCell(sname, NULL); } } if (!def) def = calmaFindCell(sname, NULL); if (DBIsAncestor(def, cifReadCellDef)) { calmaReadError("Cell %s is an ancestor of %s", def->cd_name, cifReadCellDef->cd_name); calmaReadError(" and can't be used as a subcell.\n"); calmaReadError("(Use skipped)\n"); return; } /* Read subcell transform */ if (!calmaReadTransform(&trans, sname)) { printf("Couldn't read transform.\n"); return; } /* Get number of columns and rows if array */ cols = rows = 0; /* For half-smart compilers that complain otherwise. */ READRH(nbytes, rtype); if (nbytes < 0) return; if (rtype == CALMA_COLROW) { isArray = TRUE; READI2(cols); READI2(rows); xlo = 0; xhi = cols - 1; ylo = 0; yhi = rows - 1; if (feof(calmaInputFile)) return; (void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH - 4); } else { UNREADRH(nbytes, rtype); } /* * Read reference points. * For subcells, there will be a single reference point. * For arrays, there will be three; for their meanings, see below. */ READRH(nbytes, rtype) if (nbytes < 0) return; if (rtype != CALMA_XY) { calmaUnexpected(CALMA_XY, rtype); return; } /* Length of remainder of record */ nbytes -= CALMAHEADERLENGTH; /* * Read the reference points for the SREF/AREF. * Scale down by cifCurReadStyle->crs_scaleFactor, but complain * if they don't scale exactly. * Make sure we only read three points. */ nref = nbytes / 8; if (nref > 3) { calmaReadError("Too many points (%d) in SREF/AREF\n", nref); nref = 3; } else if (nref < 1) { calmaReadError("Missing reference points in SREF/AREF (using 0,0)\n"); refarray[0].p_x = refarray[0].p_y = 0; refarray[1].p_x = refarray[1].p_y = 0; refarray[2].p_x = refarray[2].p_y = 0; } /* If this is a cell reference, then we scale to magic coordinates * and place the cell in the magic database. However, if this is * a cell to be flattened a la "gds flatten", then we keep the GDS * coordinates, and don't scale to the magic database. */ if (def->cd_flags & CDFLATGDS) /* Don't scale to magic coords! */ { for (n = 0; n < nref; n++) { calmaReadPoint(&refarray[n], 1); if (feof(calmaInputFile)) return; } } else { for (n = 0; n < nref; n++) { savescale = cifCurReadStyle->crs_scaleFactor; calmaReadPoint(&refarray[n], 1); refarray[n].p_x = CIFScaleCoord(refarray[n].p_x, COORD_EXACT); if (savescale != cifCurReadStyle->crs_scaleFactor) { for (i = 0; i < n; i++) { refarray[i].p_x *= (savescale / cifCurReadStyle->crs_scaleFactor); refarray[i].p_y *= (savescale / cifCurReadStyle->crs_scaleFactor); } savescale = cifCurReadStyle->crs_scaleFactor; } refarray[n].p_y = CIFScaleCoord(refarray[n].p_y, COORD_EXACT); if (savescale != cifCurReadStyle->crs_scaleFactor) { for (i = 0; i < n; i++) { refarray[i].p_x *= (savescale / cifCurReadStyle->crs_scaleFactor); refarray[i].p_y *= (savescale / cifCurReadStyle->crs_scaleFactor); } refarray[n].p_x *= (savescale / cifCurReadStyle->crs_scaleFactor); } if (feof(calmaInputFile)) return; } } /* Skip remainder */ nbytes -= nref * 8; if (nbytes) (void) calmaSkipBytes(nbytes); /* * Figure out the inter-element spacing of array elements, * and also the translation part of the transform. * The first reference point for both SREFs and AREFs is the * translation of the use's or array's lower-left. */ trans.t_c = refarray[0].p_x; trans.t_f = refarray[0].p_y; GeoInvertTrans(&trans, &tinv); if (isArray) { /* * The remaining two points for an array are displaced from * the first reference point by: * - the inter-column spacing times the number of columns, * - the inter-row spacing times the number of rows. */ xsep = ysep = 0; if (cols) { GeoTransPoint(&tinv, &refarray[1], &p); if (p.p_x % cols) { n = (p.p_x + (cols+1)/2) / cols; calmaReadError("# cols doesn't divide displacement ref pt\n"); calmaReadError(" %d / %d -> %d\n", p.p_x, cols, n); xsep = n; } else xsep = p.p_x / cols; } if (rows) { GeoTransPoint(&tinv, &refarray[2], &p); if (p.p_y % rows) { n = (p.p_y + (rows+1)/2) / rows; calmaReadError("# rows doesn't divide displacement ref pt\n"); calmaReadError(" %d / %d -> %d\n", p.p_y, rows, n); ysep = n; } ysep = p.p_y / rows; } } /* Added by NP --- parse PROPATTR and PROPVALUE record types */ /* The PROPATTR types 98 and 99 are defined internally to */ /* magic and are used to retain information that cannot be */ /* saved to the GDS file in any other manner. */ while (1) { READRH(nbytes, rtype); if (nbytes < 0) return; if (rtype == CALMA_PROPATTR) { READI2(propAttrType); if (propAttrType == CALMA_PROP_USENAME) { if (!calmaReadStringRecord(CALMA_PROPVALUE, &useid)) return; } else if (propAttrType == CALMA_PROP_ARRAY_LIMITS) { if (!calmaReadStringRecord(CALMA_PROPVALUE, &arraystr)) return; else if (arraystr) { int xl, xh, yl, yh; if (sscanf(arraystr, "%d_%d_%d_%d", &xl, &xh, &yl, &yh) != 4) TxError("Malformed \"array\" property ignored: %s", arraystr); else { xlo = xl; ylo = yl; xhi = xh; yhi = yh; } } } } else { UNREADRH(nbytes, rtype); break; } } /* * Check for cells which have been marked for flattening */ if (def->cd_flags & CDFLATGDS) { Plane **gdsplanes = (Plane **)def->cd_client; GDSCopyRec gdsCopyRec; int pNum; /* To do: Deal with arrays by modifying trans and */ /* looping over X and Y */ for (pNum = 0; pNum < MAXCIFRLAYERS; pNum++) { if (gdsplanes[pNum] != NULL) { gdsCopyRec.plane = cifCurReadPlanes[pNum]; if (isArray) { Transform artrans; int x, y; gdsCopyRec.trans = &artrans; for (x = 0; x < cols; x++) for (y = 0; y < rows; y++) { GeoTransTranslate((x * xsep), (y * ysep), &trans, &artrans); DBSrPaintArea((Tile *)NULL, gdsplanes[pNum], &TiPlaneRect, &DBAllButSpaceBits, gdsCopyPaintFunc, &gdsCopyRec); } } else { gdsCopyRec.trans = &trans; DBSrPaintArea((Tile *)NULL, gdsplanes[pNum], &TiPlaneRect, &DBAllButSpaceBits, gdsCopyPaintFunc, &gdsCopyRec); } } } } else { use = DBCellNewUse(def, (useid) ? useid : (char *) NULL); if (isArray) DBMakeArray(use, &GeoIdentityTransform, xlo, ylo, xhi, yhi, xsep, ysep); DBSetTrans(use, &trans); DBPlaceCell(use, cifReadCellDef); } /* Done with allocated variables */ if (sname != NULL) freeMagic(sname); if (useid != NULL) freeMagic(useid); if (arraystr != NULL) freeMagic(arraystr); } /* Callback function for copying paint from one CIF cell into another */ int gdsCopyPaintFunc(tile, gdsCopyRec) Tile *tile; GDSCopyRec *gdsCopyRec; { int pNum; Rect sourceRect, targetRect; Transform *trans = gdsCopyRec->trans; Plane *plane = gdsCopyRec->plane; if (trans) { TiToRect(tile, &sourceRect); GeoTransRect(trans, &sourceRect, &targetRect); } else TiToRect(tile, &targetRect); DBNMPaintPlane(plane, TiGetTypeExact(tile), &targetRect, CIFPaintTable, (PaintUndoInfo *)NULL); return 0; } /* * ---------------------------------------------------------------------------- * * calmaFindCell -- * * This local procedure is used to find a cell in the subcell table, * and create a new subcell if there isn't already one there. * If a new subcell is created, its CDAVAILABLE is left FALSE. * * Results: * The return value is a pointer to the definition for the * cell whose name is 'name'. * * Side effects: * A new CellDef may be created. * * ---------------------------------------------------------------------------- */ CellDef * calmaFindCell(name, was_called) char *name; /* Name of desired cell */ bool *was_called; /* If this cell is in the hash table, then it * was instanced before it was defined. We * need to know this so as to avoid flattening * the cell if requested. */ { HashEntry *h; CellDef *def; h = HashFind(&CifCellTable, name); if (HashGetValue(h) == 0) { def = DBCellLookDef(name); if (def == NULL) { def = DBCellNewDef(name, (char *) NULL); /* * Tricky point: call DBReComputeBbox here to make SURE * that the cell has a valid bounding box. Otherwise, * if the cell is used in a parent before being defined * then it will cause a core dump. */ DBReComputeBbox(def); } HashSetValue(h, def); if (was_called) *was_called = FALSE; } else if (was_called) *was_called = TRUE; return (CellDef *) HashGetValue(h); } /* * ---------------------------------------------------------------------------- * * calmaLookCell -- * * This procedure is like calmaFindCell above, but it will not * create a new subcell if the named cell does not already exist. * * Results: * The return value is a pointer to the definition for the * cell whose name is 'name', or NULL if cell 'name' does * not exist. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ CellDef * calmaLookCell(name) char *name; /* Name of desired cell */ { HashEntry *h; h = HashLookOnly(&CifCellTable, name); if (h == NULL) return (CellDef *)NULL; else return (CellDef *)HashGetValue(h); } magic-8.0.210/calma/CalmaRead.c0000664000175000001440000003416012364011344014510 0ustar timusers/* * CalmaRead.c -- * * Input of Calma GDS-II stream format. * * ********************************************************************* * * 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/calma/CalmaRead.c,v 1.3 2010/06/24 12:37:15 tim Exp $"; #endif /* not lint */ #include #include #include #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/utils.h" #include "utils/hash.h" #include "database/database.h" #include "database/databaseInt.h" #include "utils/malloc.h" #include "utils/tech.h" #include "cif/cif.h" #include "cif/CIFint.h" #include "cif/CIFread.h" #include "utils/signals.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "utils/styles.h" #include "textio/textio.h" #include "calma/calmaInt.h" #include "commands/commands.h" /* for CmdGetRootPoint */ #include "utils/undo.h" /* Globals for Calma reading */ FILE *calmaInputFile = NULL; /* Read from this stream */ FILE *calmaErrorFile = NULL; /* Write error output here */ bool CalmaSubcellPolygons = FALSE; /* Put non-Manhattan polygons * in their own subcells. */ int CalmaPolygonCount; bool CalmaFlattenUses = FALSE; /* If TRUE, small cells in the input * stream are flattened when encountered * as uses. This improves magic's * performance when handling contacts * saved as subcell arrays. */ bool CalmaReadOnly = FALSE; /* Set files to read-only and * retain file position information * so cells can be written verbatim. */ bool CalmaNoDRCCheck = FALSE; /* If TRUE, don't mark cells as needing * a DRC check; they will be assumed * DRC clean. */ bool CalmaPostOrder = FALSE; /* If TRUE, forces the GDS parser to * read cells in post-order. It is * necessary, e.g., when we need to * flatten cells that are contact cuts. * Added by Nishit 8/16/2004 */ extern void calmaUnexpected(); bool calmaParseUnits(); /* * Scaling. * Multiply all coordinates by calmaReadScale1, then divide them * by calmaReadScale2 in order to get coordinates in centimicrons. */ int calmaReadScale1; int calmaReadScale2; int calmaTotalErrors; /* * Lookahead: calmaLApresent is TRUE when calmaLAnbytes and calmaLArtype * are set to the record header of a record we just ungot. */ bool calmaLApresent; /* TRUE if lookahead input waiting */ int calmaLAnbytes; /* # bytes in record (from header) */ int calmaLArtype; /* Record type */ /* * Hash table for errors, indexed by (layer, datatype). * The corresponding entry in this table is created whenever * a (layer, datatype) is seen that we don't recognize, so * we don't output an error message more than once. */ HashTable calmaLayerHash; /* * Hash table to keep track of all defs that have appeared * in this file. Indexed by cell def name. */ HashTable calmaDefInitHash; /* Common stuff to ignore */ int calmaElementIgnore[] = { CALMA_ELFLAGS, CALMA_PLEX, -1 }; /* * ---------------------------------------------------------------------------- * * CalmaReadFile -- * * Read an entire GDS-II stream format library from the open FILE 'file'. * * Results: * None. * * Side effects: * May modify the contents of cifReadCellDef by painting or adding * new uses or labels. May also create new CellDefs. * * ---------------------------------------------------------------------------- */ void CalmaReadFile(file, filename) FILE *file; /* File from which to read Calma */ char *filename; /* The real name of the file read */ { int k, version; char *libname = NULL; MagWindow *mw; static int hdrSkip[] = { CALMA_FORMAT, CALMA_MASK, CALMA_ENDMASKS, CALMA_REFLIBS, CALMA_FONTS, CALMA_ATTRTABLE, CALMA_STYPTABLE, CALMA_GENERATIONS, -1 }; static int skipBeforeLib[] = { CALMA_LIBDIRSIZE, CALMA_SRFNAME, CALMA_LIBSECUR, -1 }; /* We will use full cell names as keys in this hash table */ CIFReadCellInit(0); if (CIFWarningLevel == CIF_WARN_REDIRECT) { if (CIFErrorFilename == NULL) calmaErrorFile = NULL; else calmaErrorFile = PaOpen(CIFErrorFilename, "w", (char *)NULL, ".", (char *)NULL, (char **)NULL); } if (cifCurReadStyle == NULL) { TxError("Don't know how to read GDS-II:\n"); TxError("Nothing in \"cifinput\" section of tech file.\n"); return; } TxPrintf("Warning: Calma reading is not undoable! I hope that's OK.\n"); UndoDisable(); calmaTotalErrors = 0; CalmaPolygonCount = 0; HashInit(&calmaDefInitHash, 32, 0); calmaLApresent = FALSE; calmaInputFile = file; /* Read the GDS-II header */ if (!calmaReadI2Record(CALMA_HEADER, &version)) goto done; if (version < 600) TxPrintf("Library written using GDS-II Release %d.0\n", version); else TxPrintf("Library written using GDS-II Release %d.%d\n", version / 100, version % 100); if (!calmaSkipExact(CALMA_BGNLIB)) goto done; calmaSkipSet(skipBeforeLib); if (!calmaReadStringRecord(CALMA_LIBNAME, &libname)) goto done; if ((libname != NULL) && (libname[0] != '\0')) { /* Avoid generating a magic name with spaces in it. . . */ /* (added by Mike Godfrey, 7/17/05) */ for (k = 0; k < strlen(libname); k++) if (libname[k] == ' ') libname[k] = '_'; TxPrintf("Library name: %s\n", libname); } /* Skip the reflibs, fonts, etc. cruft */ calmaSkipSet(hdrSkip); /* Set the scale factors */ if (!calmaParseUnits()) goto done; /* Main body of GDS-II input */ while (calmaParseStructure(filename)) if (SigInterruptPending) goto done; (void) calmaSkipExact(CALMA_ENDLIB); done: /* Added by Nishit, Sept. 2004---Load cell read from GDS */ /* stream file to the magic layout window. If this fails */ /* then we do the original action and don't do a load into */ /* the window. Note that this follows the Magic GDS output */ /* convention of giving the library the name of the */ /* top-level cell, so magic-produced GDS can be read back */ /* with the expected cell appearing in the layout window. */ if (libname != NULL) { mw = CmdGetRootPoint((Point *)NULL, (Rect *)NULL); if (mw == NULL) windCheckOnlyWindow(&mw, DBWclientID); if (mw != NULL) { if (calmaLookCell(libname, NULL) != (CellDef *)NULL) DBWloadWindow(mw, libname, FALSE); } freeMagic(libname); } CIFReadCellCleanup(1); HashKill(&calmaDefInitHash); UndoEnable(); if (calmaErrorFile != NULL) fclose(calmaErrorFile); } /* * ---------------------------------------------------------------------------- * * calmaParseUnits -- * * Process the CALMA_UNITS record that sets the relationship between * user units (stored in the stream file) and centimicrons. * * Results: * TRUE if successful, FALSE if we encountered an error and * the caller should abort. * * Side effects: * Consumes input. * Sets calmaReadScale1 to the number of centimicrons per user * unit, and calmaReadScale2 to 1, unless calmaReadScale1 would be * less than 1, in which case we set calmaReadScale1 to 1 and * calmaReadScale2 to 1/calmaReadScale1. * * NOTE: * We don't care about user units, only database units. The * GDS-II stream specifies the number of meters per database * unit, which we use to compute the number of centimicrons * per database unit. Since database units are floating point, * there is a possibility of roundoff unless the number of * centimicrons per user unit is an integer value. * * ---------------------------------------------------------------------------- */ bool calmaParseUnits() { int nbytes, rtype; double metersPerDBUnit; double userUnitsPerDBUnit; double cuPerDBUnit; READRH(nbytes, rtype); #ifdef lint nbytes = nbytes; #endif /* lint */ if (rtype != CALMA_UNITS) { calmaUnexpected(CALMA_UNITS, rtype); return (FALSE); } /* Skip user units per database unit */ if (!calmaReadR8(&userUnitsPerDBUnit)) return (FALSE); /* Read meters per database unit */ if (!calmaReadR8(&metersPerDBUnit)) return (FALSE); #ifdef notdef TxPrintf("1 database unit equals %e user units\n", userUnitsPerDBUnit); TxPrintf("1 database unit equals %e meters\n", metersPerDBUnit); TxPrintf("1 user unit equals %e database units\n", 1.0/userUnitsPerDBUnit); TxPrintf("1 meter equals %e database units\n", 1.0/metersPerDBUnit); #endif /* notdef */ /* Meters per database unit (1.0e8 corresponds to traditional centimicrons) */ cuPerDBUnit = metersPerDBUnit * 1.0e8 * cifCurReadStyle->crs_multiplier; /* * Multiply database units by calmaReadScale1, then divide * by calmaReadScale2 to get CIF units. The current scheme * relies entirely on calmaReadScale1 being an integer. */ if (cuPerDBUnit >= 1.0) { calmaReadScale1 = (int)(cuPerDBUnit + 0.5); calmaReadScale2 = 1; } else { cuPerDBUnit = 1.0 / cuPerDBUnit; calmaReadScale1 = 1; calmaReadScale2 = (int)(cuPerDBUnit + 0.5); } #ifdef notdef TxPrintf("All units to be scaled by %d/%d\n", calmaReadScale1, calmaReadScale2); #endif /* notdef */ return (TRUE); } /* * ---------------------------------------------------------------------------- * * calmaReadError -- * * This procedure is called to print out error messages during * Calma file reading. * * Results: * None. * * Side effects: * An error message is printed. * * Note: * You can add more arguments if 10 turns out not to be enough. * * ---------------------------------------------------------------------------- */ void /*VARARGS1*/ calmaReadError(format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) char *format; char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9, *a10; { calmaTotalErrors++; if (CIFWarningLevel == CIF_WARN_NONE) return; if ((calmaTotalErrors < 100) || (CIFWarningLevel != CIF_WARN_LIMIT)) { if (CIFWarningLevel == CIF_WARN_REDIRECT) { if (calmaErrorFile != NULL) { fprintf(calmaErrorFile, "Error while reading cell \"%s\": ", cifReadCellDef->cd_name); fprintf(calmaErrorFile, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); } } else { TxError("Error while reading cell \"%s\": ", cifReadCellDef->cd_name); TxError(format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); } } else if ((calmaTotalErrors == 100) && (CIFWarningLevel == CIF_WARN_LIMIT)) { TxError("Error limit set: Remaining errors will not be reported.\n"); } } /* * ---------------------------------------------------------------------------- * * calmaUnexpected -- * * Complain about a record where we expected one kind but got another. * * Results: * None. * * Side effects: * Prints an error message. * * ---------------------------------------------------------------------------- */ void calmaUnexpected(wanted, got) int wanted; /* Type of record we wanted */ int got; /* Type of record we got */ { calmaReadError("Unexpected record type in input: \n"); if (CIFWarningLevel == CIF_WARN_NONE) return; if (calmaTotalErrors < 100 || (CIFWarningLevel != CIF_WARN_LIMIT)) { if (CIFWarningLevel == CIF_WARN_REDIRECT) { if (calmaErrorFile != NULL) { fprintf(calmaErrorFile," Expected %s record ", calmaRecordName(wanted)); fprintf(calmaErrorFile, "but got %s.\n", calmaRecordName(got)); } } else { TxError(" Expected %s record ", calmaRecordName(wanted)); TxError("but got %s.\n", calmaRecordName(got)); } } } /* * ---------------------------------------------------------------------------- * * calmaRecordName -- * * Return a pointer to the printable name of a CALMA record type. * * Results: * See above. * * Side effects: * May overwrite the string we returned on the previous call. * * ---------------------------------------------------------------------------- */ char * calmaRecordName(rtype) int rtype; { static char numeric[10]; static char *calmaRecordNames[] = { "HEADER", "BGNLIB", "LIBNAME", "UNITS", "ENDLIB", "BGNSTR", "STRNAME", "ENDSTR", "BOUNDARY", "PATH", "SREF", "AREF", "TEXT", "LAYER", "DATATYPE", "WIDTH", "XY", "ENDEL", "SNAME", "COLROW", "TEXTNODE", "NODE", "TEXTTYPE", "PRESENTATION", "SPACING", "STRING", "STRANS", "MAG", "ANGLE", "UINTEGER", "USTRING", "REFLIBS", "FONTS", "PATHTYPE", "GENERATIONS", "ATTRTABLE", "STYPTABLE", "STRTYPE", "ELFLAGS", "ELKEY", "LINKTYPE", "LINKKEYS", "NODETYPE", "PROPATTR", "PROPVALUE", "BOX", "BOXTYPE", "PLEX", "BGNEXTN", "ENDEXTN", "TAPENUM", "TAPECODE", "STRCLASS", "RESERVED", "FORMAT", "MASK", "ENDMASKS" }; if (rtype < 0 || rtype >= CALMA_NUMRECORDTYPES) { (void) sprintf(numeric, "%d", rtype); return (numeric); } return (calmaRecordNames[rtype]); } /* * ---------------------------------------------------------------------------- * * CalmaTechInit -- * * Prepare for a technology file. * * Results: * None. * * Side effects: * Error checking. * * ---------------------------------------------------------------------------- */ void CalmaTechInit() { ASSERT(sizeof(FourByteInt)==4, "definition in calmaInt.h"); ASSERT(sizeof(TwoByteInt)==2, "definition in calmaInt.h"); } magic-8.0.210/extflat/0000755000175000001440000000000012404142456013123 5ustar timusersmagic-8.0.210/extflat/EFread.c0000664000175000001440000004237112354346567014443 0ustar timusers/* * EFread.c - * * Procedures to read a .ext file and call the procedures * in EFbuild.c to build up a description of each def. * * ********************************************************************* * * 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/extflat/EFread.c,v 1.4 2009/01/30 03:51:02 tim Exp $"; #endif /* not lint */ #include #include #include #include #include "tcltk/tclmagic.h" #include "utils/magic.h" #include "utils/malloc.h" #include "utils/geometry.h" #include "utils/hash.h" #include "utils/utils.h" #include "tiles/tile.h" #include "commands/commands.h" #include "database/database.h" #include "extflat/extflat.h" #include "extflat/EFint.h" #include "extract/extract.h" #include "utils/paths.h" #ifndef MAGIC_WRAPPER /* This must match the definition for extDevTable in extract/ExtBasic.c */ char *extDevTable[] = {"fet", "mosfet", "asymmetric", "bjt", "devres", "devcap", "diode", "subckt", "rsubckt", "msubckt", NULL}; #endif /* * The following table describes the kinds of lines * that may be read in a .ext file. */ typedef enum { ADJUST, ATTR, CAP, DEVICE, DIST, EQUIV, FET, KILLNODE, MERGE, NODE, PARAMETERS, PORT, RESISTOR, RESISTCLASS, RNODE, SCALE, TECH, TIMESTAMP, USE, VERSION, EXT_STYLE } Key; static struct { char *k_name; /* Name of first token on line */ Key k_key; /* Internal name for token of this type */ int k_mintokens; /* Min total # of tokens on line of this type */ } keyTable[] = { "adjust", ADJUST, 4, "attr", ATTR, 8, "cap", CAP, 4, "device", DEVICE, 11, /* effectively replaces "fet" */ "distance", DIST, 4, "equiv", EQUIV, 3, "fet", FET, 12, /* for backwards compatibility */ "killnode", KILLNODE, 2, "merge", MERGE, 3, "node", NODE, 7, "parameters", PARAMETERS, 3, "port", PORT, 8, "resist", RESISTOR, 4, "resistclasses", RESISTCLASS, 1, "rnode", RNODE, 5, "scale", SCALE, 4, "tech", TECH, 2, "timestamp", TIMESTAMP, 2, "use", USE, 9, "version", VERSION, 2, "style", EXT_STYLE, 2, 0 }; /* Data shared with EFerror.c */ char *efReadFileName; /* Name of file currently being read */ int efReadLineNum; /* Current line number in above file */ /* Data local to this file */ static bool efReadDef(); /* atoCap - convert a string to a EFCapValue */ #define atoCap(s) ((EFCapValue)atof(s)) /* * ---------------------------------------------------------------------------- * * EFReadFile -- * * Main procedure to read a .ext file. If there is no Def by the * name of 'name', allocates a new one. Calls efReadDef to do the * work of reading the def itself. If 'dosubckt' is true, then port * mappings are kept. If 'resist' is true, read in the .res.ext file * (from extresist) if it exists, after reading the .ext file. * * Results: * Passes on the return value of efReadDef (see below) * * Side effects: * See above. * Leaves EFTech set to the technology specified with the -T flag * if there was one. Leaves EFScale set to 1 if it changed while * reading the .ext files. * * ---------------------------------------------------------------------------- */ bool EFReadFile(name, dosubckt, resist, noscale) char *name; /* Name of def to be read in */ bool dosubckt, resist; { Def *def; bool rc; def = efDefLook(name); if (def == NULL) def = efDefNew(name); rc = efReadDef(def, dosubckt, resist, noscale); if (EFArgTech) EFTech = StrDup((char **) NULL, EFArgTech); if (EFScale == 0.0) EFScale = 1.0; return rc; } /* * ---------------------------------------------------------------------------- * * efReadDef -- * * Procedure to read in a Def. Actually does the work of reading * the file 'def->def_name'.ext to build up the fields of the new * def, then recursively reads all uses of this def that haven't * yet been read. * * Results: * Returns TRUE if successful, FALSE if the file for 'name' * could not be found or we encountered errors. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ bool efReadDef(def, dosubckt, resist, noscale) Def *def; bool dosubckt, resist, noscale; { int argc, ac, n; EFCapValue cap; char line[1024], *argv[64], *name, *attrs; int rscale = 1; /* Multiply resistances by this */ int cscale = 1; /* Multiply capacitances by this */ float lscale = 1.0; /* Multiply lambda by this */ FILE *inf; Use *use; Rect r; bool rc = TRUE; bool DoResist = resist; bool DoSubCircuit = dosubckt; /* Mark def as available */ def->def_flags |= DEF_AVAILABLE; name = def->def_name; inf = PaOpen(name, "r", ".ext", EFSearchPath, EFLibPath, &efReadFileName); if (inf == NULL) { #ifdef MAGIC_WRAPPER char *tclres = Tcl_Alloc(128); sprintf(tclres, "Cannot read extract file %s.ext\n", name); Tcl_SetResult(magicinterp, tclres, TCL_DYNAMIC); #else perror(name); #endif return FALSE; } readfile: efReadLineNum = 0; while ((argc = efReadLine(line, sizeof line, inf, argv)) >= 0) { n = LookupStruct(argv[0], (LookupTable *) keyTable, sizeof keyTable[0]); if (n < 0) { efReadError("Unrecognized token \"%s\" (ignored)\n", argv[0]); continue; } if (argc < keyTable[n].k_mintokens) { efReadError("Not enough tokens for %s line\n", argv[0]); continue; } switch (keyTable[n].k_key) { /* scale rscale cscale lscale */ case SCALE: rscale = atoi(argv[1]); if (rscale == 0) { efReadError("Bad resistance scaling = 0; reset to 1.\n"); rscale = 1; } cscale = atoi(argv[2]); if (cscale == 0) { efReadError("Bad capacitance scaling = 0; reset to 1.\n"); cscale = 1; } lscale = (float)atof(argv[3]); if (lscale == 0.0) { efReadError("Bad linear scaling = 0; reset to 1.\n"); lscale = 1.0; } if (noscale == FALSE) { def->def_scale = lscale; if (EFScale != lscale) { if (EFScale != 0) efScaleChanged = TRUE, EFScale = 1.0; else EFScale = lscale; } } break; /* attr node xlo ylo xhi yhi type text */ case ATTR: r.r_xbot = atoi(argv[2]); r.r_ybot = atoi(argv[3]); r.r_xtop = atoi(argv[4]); r.r_ytop = atoi(argv[5]), efBuildAttr(def, argv[1], &r, argv[6], argv[7]); break; /* cap node1 node2 capacitance */ case CAP: cap = cscale*atoCap(argv[3]); efBuildCap(def, argv[1], argv[2], (double) cap); break; /* equiv node1 node2 */ case EQUIV: efBuildEquiv(def, argv[1], argv[2]); break; /* replaces "fet" (below) */ /* device mosfet|bjt|subckt type xlo ylo xhi yhi */ /* area perim [substrate] GATE T1 T2 ... */ /* device res|cap|rsubckt type xlo ylo xhi yhi value */ /* GATE T1 T2 ... */ case DEVICE: /* Parse device class */ for (n = 0; extDevTable[n] != NULL; n++) if (!strcmp(argv[1], extDevTable[n])) break; if (extDevTable[n] == NULL) { efReadError("Unknown device class\n"); continue; } switch (n) { case DEV_MOSFET: case DEV_ASYMMETRIC: case DEV_BJT: ac = 10; break; case DEV_DIODE: ac = 7; break; case DEV_CAP: case DEV_RES: if (!strcmp(argv[2], "None")) /* Has device value */ ac = 8; else ac = 9; /* Has device L and W */ break; case DEV_SUBCKT: case DEV_MSUBCKT: case DEV_RSUBCKT: ac = 7; /* Actually can have many arguments, which */ break; /* we will deal with in efBuildDevice(). */ } r.r_xbot = atoi(argv[3]); r.r_ybot = atoi(argv[4]); r.r_xtop = atoi(argv[5]); r.r_ytop = atoi(argv[6]); if (efBuildDevice(def, (char)n, argv[2], &r, argc - 7, &argv[7]) != 0) { efReadError("Incomplete terminal description for device\n"); continue; } break; /* for backwards compatibility */ /* fet type xlo ylo xhi yhi area perim substrate GATE T1 T2 ... */ case FET: r.r_xbot = atoi(argv[2]); r.r_ybot = atoi(argv[3]); r.r_xtop = atoi(argv[4]); r.r_ytop = atoi(argv[5]); if (efBuildDevice(def, DEV_FET, argv[1], &r, argc - 6, &argv[6]) != 0) { efReadError("Incomplete terminal description for fet\n"); continue; } break; /* merge node1 node2 C a1 p1 a2 p2 ... */ case MERGE: /* Redundant merge lines are purposely generated with */ /* no area and perimeter values; these should not be */ /* flagged as errors. */ /* if (argc > 4) && (argc - 4 < 2 * efNumResistClasses)) { efReadError("Too few area/perim values: " "assuming remainder are zero\n"); } */ cap = (argc > 3) ? atoCap(argv[3]) * cscale : 0; efBuildConnect(def, argv[1], argv[2], (double) cap, &argv[4], argc - 4); break; /* node name R C x y layer a1 p1 a2 p2 ... [ attrs ] */ case NODE: attrs = NULL; ac = argc - 7; if (ac & 01) attrs = argv[argc-1], ac--; if (ac < 2*efNumResistClasses) { efReadError( "Too few area/perim values: assuming remainder are zero\n"); } /* Note: resistance is ignored; we use perim/area instead */ cap = atoCap(argv[3])*cscale; efBuildNode(def, argv[1], (double) cap, atoi(argv[4]), atoi(argv[5]), argv[6], &argv[7], ac); break; /* parameters name */ case PARAMETERS: efBuildDeviceParams(argv[1], argc - 2, &argv[2]); break; /* port name num xl yl xh yh type */ case PORT: if (DoSubCircuit) { DoResist = FALSE; def->def_flags |= DEF_SUBCIRCUIT; efBuildPortNode(def, argv[1], atoi(argv[2]), atoi(argv[3]), atoi(argv[4]), argv[7]); } break; /* * rnode name C x y layer * These are nodes resulting from resistance extraction and * so have no "intrinsic" resistance per se. */ case RNODE: cap = atoCap(argv[3])*cscale; efBuildNode(def, argv[1], (double) cap, atoi(argv[4]), atoi(argv[5]), argv[6], (char **) NULL, 0); break; /* resist r1 r2 ... */ case RESISTCLASS: if (efNumResistClasses == 0) { efNumResistClasses = argc-1; for (n = 0; n < efNumResistClasses; n++) efResists[n] = atoi(argv[n + 1]); } else if (efNumResistClasses != argc-1) { efReadError("Number of resistance classes doesn't match:\n"); resistChanged: efReadError("Re-extract the entire tree with " "the same technology file\n"); efResistChanged = TRUE; break; } for (n = 0; n < efNumResistClasses; n++) if (efResists[n] != atoi(argv[n + 1])) { efReadError("Resistance class values don't match:\n"); goto resistChanged; } break; /* use def use-id T0 .. T5 */ case USE: efBuildUse(def, argv[1], argv[2], atoi(argv[3]), atoi(argv[4]), atoi(argv[5]), atoi(argv[6]), atoi(argv[7]), atoi(argv[8])); break; /* tech techname */ case TECH: #ifdef MAGIC_WRAPPER if (strcmp(argv[1], DBTechName)) { /* If we are running in batch mode and no layout is */ /* present, then load the new technology. */ if (CmdCheckForPaintFunc()) { TxError("Error: .ext file has different technology %s\n", argv[1]); TxError("Load this technology and repeat.\n"); rc = FALSE; break; } else { TxError("Loading technology %s\n", argv[1]); if (!TechLoad(argv[1], 0)) { TxError("Error in loading technology file\n"); rc = FALSE; break; } else EFTech = StrDup((char **) NULL, argv[1]); } } #else if (EFTech && EFTech[0]) { if (strcmp(EFTech, argv[1]) != 0) { efReadError("Technology %s doesn't match initial " "technology %s\n", EFTech, argv[1]); rc = FALSE; break; } } #endif else EFTech = StrDup((char **) NULL, argv[1]); if (!EFLibPath[0]) /* Put in a path if there wasn't one */ (void) sprintf(EFLibPath, EXT_PATH, EFTech); break; /* ext_style stylename */ case EXT_STYLE: #ifdef MAGIC_WRAPPER if (ExtCompareStyle(argv[1]) == FALSE) { TxError("Warning: .ext file style %s is not known " "in this technology!\n", argv[1]); if (EFStyle) { freeMagic(EFStyle); EFStyle = NULL; } } #else if (EFStyle) { if (strcmp(EFStyle, argv[1]) != 0) { efReadError("Extraction style doesn't match: %s\n", argv[1]); rc = FALSE; break; } } #endif else EFStyle = StrDup(&EFStyle, argv[1]); break; /* version version-number */ case VERSION: if (strcmp(argv[1], EFVersion) != 0) { efReadError( "Cell was extracted using version %s of the extractor.\n", argv[1]); efReadError(" It should be re-extracted.\n"); } break; /* distance driver receiver min max */ case DIST: efBuildDist(def, argv[1], argv[2], (int)(lscale*atoi(argv[3])), (int)(lscale*atoi(argv[4]))); break; /* killnode nodename */ case KILLNODE: efBuildKill(def, argv[1]); break; /* resistor node1 node2 resistance */ case RESISTOR: efBuildResistor(def, argv[1], argv[2], rscale*atoi(argv[3])); break; /* To-do: compare timestamp against the cell */ case TIMESTAMP: break; /* Ignore the rest for now */ case ADJUST: /* Unused */ default: break; } } (void) fclose(inf); /* Is there an "extresist" extract file? */ if (DoResist) { DoResist = FALSE; /* do this only once */ inf = PaOpen(name, "r", ".res.ext", EFSearchPath, EFLibPath, &efReadFileName); if (inf != NULL) goto readfile; } /* If we are considering standard cells, only the first level of */ /* subcircuits is meaningful. */ if (def->def_flags & DEF_SUBCIRCUIT) DoSubCircuit = FALSE; /* Read in each def that has not yet been read in */ for (use = def->def_uses; use; use = use->use_next) if ((use->use_def->def_flags & DEF_AVAILABLE) == 0) if(efReadDef(use->use_def, DoSubCircuit, resist, noscale) != TRUE) rc = FALSE; return rc; } /* * ---------------------------------------------------------------------------- * * efReadLine -- * * Read a line from a .ext file and split it up into tokens. * Blank lines are ignored. Lines ending in backslash are joined * to their successor lines. Lines beginning with '#' are considered * to be comments and are ignored. * * Results: * Returns the number of tokens into which the line was split, or * -1 on end of file. Never returns 0. * * Side effects: * Copies the line just read into 'line'. The trailing newline * is turned into a '\0'. The line is broken into tokens which * are then placed into argv. Updates *plinenum to point to the * current line number in 'file'. * * ---------------------------------------------------------------------------- */ int efReadLine(line, size, file, argv) char *line; /* Character array into which line is read */ int size; /* Size of character array */ FILE *file; /* Open .ext file */ char *argv[]; /* Vector of tokens built by efReadLine() */ { char *get, *put; bool inquote; int argc = 0; /* Read one line into the buffer, joining lines when they end in '\' */ start: get = line; while (size > 0) { efReadLineNum += 1; if (fgets(get, size, file) == NULL) return (-1); for (put = get; *put != '\n'; put++) size -= 1; if ((put != get) && (*(put-1) == '\\')) { get = put-1; continue; } *put= '\0'; break; } if (size == 0) efReadError("long line truncated\n"); get = put = line; if (*line == '#') goto start; /* Ignore comments */ while (*get != '\0') { /* Skip leading blanks */ while (isspace(*get)) get++; /* Beginning of the token is here */ argv[argc] = put = get; inquote = FALSE; /* * Grab up characters to the end of the token. Any character * preceded by a backslash is taken literally. */ while (*get != '\0') { if (inquote) { if (*get == '"') { get++; inquote = FALSE; continue; } } else { if (isspace(*get)) break; if (*get == '"') { get++; inquote = TRUE; continue; } } if (*get == '\\') /* Process quoted characters literally */ { get++; if (*get == '\0') break; } /* Copy into token receiving area */ *put++ = *get++; } /* * If we got no characters in the token, we must have been at * the end of the line. */ if (get == argv[argc]) break; /* Terminate the token and advance over the terminating character. */ if (*get != '\0') get++; /* Careful! could be at end of line! */ *put++ = '\0'; argc++; } if (argc == 0) goto start; return (argc); } magic-8.0.210/extflat/EFvisit.c0000664000175000001440000005146112400422506014642 0ustar timusers/* * EFvisit.c - * * Procedures to traverse and output flattened nodes, capacitors, * transistors, resistors, and Distances. * * ********************************************************************* * * 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/extflat/EFvisit.c,v 1.5 2010/08/10 00:18:45 tim Exp $"; #endif /* not lint */ #include #include #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/geofast.h" #include "utils/hash.h" #include "utils/malloc.h" #include "utils/utils.h" #include "extflat/extflat.h" #include "extflat/EFint.h" #include "extract/extract.h" /* Root of the tree being flattened */ extern Def *efFlatRootDef; extern Use efFlatRootUse; extern HierContext efFlatContext; extern void efDevFixLW(); extern void efHNOutPrefix(); bool efDevKilled(); /* * ---------------------------------------------------------------------------- * * EFVisitSubcircuits -- * * Visit all of the "defined" subcircuits in the circuit. * This is meant to provide a generic functionality similar to * the transistor/resistor/capacitor extraction. It assumes that the * end-user has an existing description of the extracted subcircuit, * such as a characterized standard cell, and that magic is not to * attempt an extraction itself, but only to call the predefined * subcircuit, matching nodes to the subcircuit's port list. * * For each def encountered which has the DEF_SUBCIRCUIT flag set, * call the user-supplied procedure (*subProc)(), which should be of * the following form: * * (*subProc)(use, hierName, is_top) * Use *use; * HierName *hierName; * Boolean is_top; * { * } * * is_top will be TRUE for the top-level cell, and FALSE for all * other cells. The procedure should return 0 normally, or 1 to abort * the search. * * Results: * Returns 0 if terminated normally, or 1 if the search * was aborted. * * Side effects: * Whatever (*subProc)() does. * * ---------------------------------------------------------------------------- */ int EFVisitSubcircuits(subProc, cdata) int (*subProc)(); ClientData cdata; { CallArg ca; HierContext *hc; int efVisitSubcircuits(); /* Forward declaration */ /* If the top-level def is defined as a subcircuit, call topProc */ hc = &efFlatContext; if (hc->hc_use->use_def->def_flags & DEF_SUBCIRCUIT) if ((*subProc)(hc->hc_use, hc->hc_hierName, TRUE)) return 1; /* For each subcell of the top-level def that is defined as */ /* a subcircuit, call subProc. */ ca.ca_proc = subProc; ca.ca_cdata = cdata; if (efHierSrUses(hc, efVisitSubcircuits, (ClientData) &ca)) return 1; return 0; } /* * Procedure to visit recursively all subcircuits in the design. * Does all the work of EFVisitSubcircuits() above. * * Results: * Returns 0 to keep efHierSrUses going. * * Side effects: * Calls the client procedure (*ca->ca_proc)(). */ int efVisitSubcircuits(hc, ca) HierContext *hc; CallArg *ca; { /* Look for children of this def which are defined */ /* as subcircuits via the DEF_SUBCIRCUIT flag. */ if (hc->hc_use->use_def->def_flags & DEF_SUBCIRCUIT) { if ((*ca->ca_proc)(hc->hc_use, hc->hc_hierName, NULL)) return 1; else return 0; } /* Recursively visit subcircuits in our children last. */ if (efHierSrUses(hc, efVisitSubcircuits, (ClientData) ca)) return 1; return 0; } /* * ---------------------------------------------------------------------------- * * EFGetLengthAndWidth -- * * Estimate length and width for a device from area and perimeter values. * Mostly this routine is meant to handle the older "fet" record. * Newer "device" types should have length and width properly determined * already, and we just return those values from the device structure. * * Results: * None * * Side Effects: * Values substituted for length and width. * * ---------------------------------------------------------------------------- */ void EFGetLengthAndWidth(dev, lptr, wptr) Dev *dev; int *lptr; int *wptr; { DevTerm *gate, *source, *drain; int area, perim, l, w; switch (dev->dev_class) { case DEV_MOSFET: case DEV_ASYMMETRIC: case DEV_BJT: case DEV_SUBCKT: case DEV_MSUBCKT: case DEV_RSUBCKT: case DEV_DIODE: case DEV_CAP: case DEV_RES: l = dev->dev_length; w = dev->dev_width; break; case DEV_FET: area = dev->dev_area; perim = dev->dev_perim; gate = &dev->dev_terms[0]; /* * L, W, and flat coordinates of a point inside the channel. * Handle FETs with two terminals (capacitors) separately. */ if (dev->dev_nterm == 2) { /* Convert area to type double to avoid overflow in */ /* extreme cases. */ l = perim - (int)sqrt((double)(perim * perim) - 16 * (double)area); l >>= 2; w = area / l; } else { source = drain = &dev->dev_terms[1]; if (dev->dev_nterm >= 3) drain = &dev->dev_terms[2]; l = gate->dterm_length / 2; w = (source->dterm_length + drain->dterm_length) / 2; } if (gate->dterm_attrs) efDevFixLW(gate->dterm_attrs, &l, &w); break; default: l = w = 0; break; } *lptr = l; *wptr = w; } /* * ---------------------------------------------------------------------------- * * EFVisitDevs -- * * Visit all the devs in the circuit. * Must be called after EFFlatBuild(). * For each dev in the circuit, call the user-supplied procedure * (*devProc)(), which should be of the following form: * * (*devProc)(dev, hierName, scale, cdata) * Dev *dev; * HierName *hierName; * float scale; * Transform *trans; * ClientData cdata; * { * } * * The procedure should return 0 normally, or 1 to abort the * search. * * We ensure that no devs connected to killed nodes are passed * to this procedure. * * Results: * Returns 0 if terminated normally, or 1 if the search * was aborted. * * Side effects: * Whatever (*devProc)() does. * * ---------------------------------------------------------------------------- */ int EFVisitDevs(devProc, cdata) int (*devProc)(); ClientData cdata; { CallArg ca; ca.ca_proc = devProc; ca.ca_cdata = cdata; return efVisitDevs(&efFlatContext, (ClientData) &ca); } /* * Procedure to visit recursively all devs in the design. * Does all the work of EFVisitDevs() above. * * Results: * Returns 0 to keep efHierSrUses going. * * Side effects: * Calls the client procedure (*ca->ca_proc)(). */ int efVisitDevs(hc, ca) HierContext *hc; CallArg *ca; { Def *def = hc->hc_use->use_def; Dev *dev; float scale; Transform t; if (def->def_flags & DEF_SUBCIRCUIT) return 0; /* Recursively visit devs in our children first */ if (efHierSrUses(hc, efVisitDevs, (ClientData) ca)) return 1; scale = (efScaleChanged && def->def_scale != 1.0) ? def->def_scale : 1.0; t = hc->hc_trans; /* Visit our own devices */ for (dev = def->def_devs; dev; dev = dev->dev_next) { if (efDevKilled(dev, hc->hc_hierName)) continue; if ((*ca->ca_proc)(dev, hc->hc_hierName, scale, &t, ca->ca_cdata)) return 1; } return 0; } /* * ---------------------------------------------------------------------------- * * efDevKilled -- * * Check all of the nodes to which the dev 'dev' is connected (its * hierarchical prefix is hc->hc_hierName). If any of these nodes * have been killed, then the dev is also killed. * * Results: * TRUE if the dev is connected to a killed node, FALSE if it's ok. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool efDevKilled(dev, prefix) Dev *dev; HierName *prefix; { HierName *suffix; HashEntry *he; EFNodeName *nn; int n; for (n = 0; n < dev->dev_nterm; n++) { suffix = dev->dev_terms[n].dterm_node->efnode_name->efnn_hier; he = EFHNConcatLook(prefix, suffix, "kill"); if (he && (nn = (EFNodeName *) HashGetValue(he)) && (nn->efnn_node->efnode_flags & EF_KILLED)) return TRUE; } return FALSE; } /* * ---------------------------------------------------------------------------- * * efDevFixLW -- * * Called for any devs that have gate attributes; these attributes may * specify the L and W of the dev explicitly. The attributes will be * of the form ext:l=value or ext:w=value, where value is either numerical * or symbolic; if symbolic the symbol must have been defined via efSymAdd(). * If the value is symbolic but wasn't defined by efSymAdd(), it's ignored. * The variables *pL and *pW are changed to reflect the new L and W as * appropriate. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void efDevFixLW(attrs, pL, pW) char *attrs; int *pL, *pW; { char *cp, *ep; char attrName, savec; int value; cp = attrs; while (cp && *cp) { if (*cp != 'e' || strncmp(cp, "ext:", 4) != 0) goto skip; cp += 4; if (*cp && cp[1] == '=') { switch (*cp) { case 'w': case 'W': attrName = 'w'; goto both; case 'l': case 'L': attrName = 'l'; both: cp += 2; for (ep = cp; *ep && *ep != ','; ep++) /* Nothing */; savec = *ep; *ep = '\0'; if (StrIsInt(cp)) value = atoi(cp); else if (!efSymLook(cp, &value)) goto done; if (attrName == 'w') *pW = value; else if (attrName == 'l') *pL = value; done: *ep = savec; } } skip: /* Skip to next attribute */ while (*cp && *cp++ != ',') /* Nothing */; } } /* * ---------------------------------------------------------------------------- * * EFVisitResists -- * * Visit all the resistors in the circuit. * Must be called after EFFlatBuild(). * For each resistor in the circuit, call the user-supplied procedure * (*resProc)(), which should be of the following form, where hn1 and * hn2 are the HierNames of the two nodes connected by the resistor. * * (*resProc)(hn1, hn2, resistance, cdata) * HierName *hn1, *hn2; * int resistance; * ClientData cdata; * { * } * * The procedure should return 0 normally, or 1 to abort the * search. * * We ensure that no resistors connected to killed nodes are passed * to this procedure. * * Results: * Returns 0 if terminated normally, or 1 if the search * was aborted. * * Side effects: * Whatever (*resProc)() does. * * ---------------------------------------------------------------------------- */ int EFVisitResists(resProc, cdata) int (*resProc)(); ClientData cdata; { CallArg ca; ca.ca_proc = resProc; ca.ca_cdata = cdata; return efVisitResists(&efFlatContext, (ClientData) &ca); } /* * Procedure to visit recursively all resistors in the design. * Does all the work of EFVisitResists() above. * * Results: * Returns 0 to keep efHierSrUses going. * * Side effects: * Calls the client procedure (*ca->ca_proc)(). */ extern int efVisitSingleResist(); int efVisitResists(hc, ca) HierContext *hc; CallArg *ca; { Def *def = hc->hc_use->use_def; Connection *res; /* Ignore subcircuits */ if (def->def_flags & DEF_SUBCIRCUIT) return 0; /* Recursively visit resistors in our children first */ if (efHierSrUses(hc, efVisitResists, (ClientData) ca)) return 1; /* Visit our own resistors */ for (res = def->def_resistors; res; res = res->conn_next) { /* Special case for speed if no arraying info */ if (res->conn_1.cn_nsubs == 0) { if (efVisitSingleResist(hc, res->conn_name1, res->conn_name2, res, ca)) return 1; } else if (efHierSrArray(hc, res, efVisitSingleResist, (ClientData) ca)) return 1; } return 0; } /* * ---------------------------------------------------------------------------- * * efVisitSingleResist -- * * Visit a resistor of res->conn_res milliohms between the nodes * 'name1' and 'name2' (text names, not hierarchical names). Don't * process the resistor if either terminal is a killed node. * * Results: * Whatever the user-supplied procedure (*ca->ca_proc)() returns * (type int). * * Side effects: * Calls the user-supplied procedure. * * ---------------------------------------------------------------------------- */ int efVisitSingleResist(hc, name1, name2, res, ca) HierContext *hc; /* Contains hierarchical pathname to cell */ char *name1, *name2; /* Names of nodes connecting to resistor */ Connection *res; /* Contains resistance to add */ CallArg *ca; { EFNode *n1, *n2; HashEntry *he; if ((he = EFHNLook(hc->hc_hierName, name1, "resist(1)")) == NULL) return 0; n1 = ((EFNodeName *) HashGetValue(he))->efnn_node; if (n1->efnode_flags & EF_KILLED) return 0; if ((he = EFHNLook(hc->hc_hierName, name2, "resist(2)")) == NULL) return 0; n2 = ((EFNodeName *) HashGetValue(he))->efnn_node; if (n2->efnode_flags & EF_KILLED) return 0; /* Do nothing if the nodes aren't different */ if (n1 == n2) return 0; return (*ca->ca_proc)(n1->efnode_name->efnn_hier, n2->efnode_name->efnn_hier, res->conn_res, ca->ca_cdata); } /* * ---------------------------------------------------------------------------- * * EFVisitCaps -- * * Visit all the capacitors built up by efFlatCaps. * Calls the user-provided procedure (*capProc)() * which should be of the following format: * * (*capProc)(hierName1, hierName2, cap, cdata) * HierName *hierName1, *hierName2; * EFCapValue cap; * ClientData cdata; * { * } * * Here cap is the capacitance in attofarads. * * Results: * Returns 1 if the client procedure returned 1; * otherwise returns 0. * * Side effects: * Calls the user-provided procedure (*capProc)(). * * ---------------------------------------------------------------------------- */ int EFVisitCaps(capProc, cdata) int (*capProc)(); ClientData cdata; { HashSearch hs; HashEntry *he; EFCoupleKey *ck; EFCapValue cap; HashStartSearch(&hs); while (he = HashNext(&efCapHashTable, &hs)) { cap = CapHashGetValue(he); ck = (EFCoupleKey *) he->h_key.h_words; if ((*capProc)(ck->ck_1->efnode_name->efnn_hier, ck->ck_2->efnode_name->efnn_hier, (double) cap, cdata)) return 1; } return 0; } /* * ---------------------------------------------------------------------------- * * EFVisitNodes -- * * Procedure to visit all flat nodes in the circuit. * For each node, calls the procedure (*nodeProc)(), * which should be of the following form: * * (*nodeProc)(node, r, c, cdata) * EFNode *node; * int r; * EFCapValue c; * ClientData cdata; * { * } * * Where 'r' and 'c' are the lumped resistance estimate * and capacitance to ground, in milliohms and attofarads * respectively. When either falls below the threshold * for output, they are passed as 0. * * Results: * Returns 1 if (*nodeProc)() returned 1 to abort the * search; otherwise, returns 0. * * Side effects: * Calls (*nodeProc)(). * * ---------------------------------------------------------------------------- */ int EFVisitNodes(nodeProc, cdata) int (*nodeProc)(); ClientData cdata; { EFNode *node; EFNodeName *nn; HierName *hierName; EFCapValue cap; int res; for (node = (EFNode *) efNodeList.efnode_next; node != &efNodeList; node = (EFNode *) node->efnode_next) { res = EFNodeResist(node); cap = node->efnode_cap; hierName = (HierName *) node->efnode_name->efnn_hier; if (EFHNIsGND(hierName)) cap = 0; if (efWatchNodes) { for (nn = node->efnode_name; nn; nn = nn->efnn_next) if (HashLookOnly(&efWatchTable, (char *) nn->efnn_hier)) { TxPrintf("Equivalent nodes:\n"); for (nn = node->efnode_name; nn; nn = nn->efnn_next) TxPrintf("\t%s\n", EFHNToStr(nn->efnn_hier)); break; } } if (node->efnode_flags & EF_KILLED) continue; if ((*nodeProc)(node, res, (double) cap, cdata)) return 1; } return 0; } /* * ---------------------------------------------------------------------------- * * EFNodeResist -- * * The input to this procedure is a pointer to a EFNode. * Its resistance is computed from the area and perimeter stored * in the array efnode_pa. * * We approximate the resistive region as a collection of rectangles * of width W and length L, one for each set of layers having a different * sheet resistivity. We do so by noting that for a rectangle, * * Area = L * W * Perimeter = 2 * (L + W) * * Solving the two simultaneous equations for L yields the following * quadratic: * * 2 * (L**2) - Perimeter * L + 2 * Area = 0 * * Solving this quadratic for L, the longer dimension, we get * * L = (Perimeter + S) / 4 * * where * * S = sqrt( (Perimeter**2) - 16 * Area ) * * The smaller dimension is W, ie, * * W = (Perimeter - S) / 4 * * The resistance is L / W squares: * * Perimeter + S * R = ------------- * Perimeter - S * * Results: * Returns the resistance. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ int EFNodeResist(node) EFNode *node; { int n, perim, area; float s, fperim; double v, dresist; int resist; resist = 0; for (n = 0; n < efNumResistClasses; n++) { area = node->efnode_pa[n].pa_area; perim = node->efnode_pa[n].pa_perim; if (area > 0 && perim > 0) { v = (double) perim * (double) perim - 16.0 * area; /* Approximate by one square if v < 0; shouldn't happen! */ if (v < 0.0) s = 0.0; else s = sqrt(v); fperim = (float) perim; dresist = (fperim + s)/(fperim - s) * efResists[n]; if (dresist + (double) resist > (double) MAXINT) resist = MAXINT; else resist += dresist; } } return (resist); } /* * ---------------------------------------------------------------------------- * * EFLookDist -- * * Look for the Distance between two points given by their HierNames. * * Results: * TRUE if a distance was found, FALSE if not. * * Side effects: * Sets *pMinDist and *pMaxDist to the min and max distances * if found. * * ---------------------------------------------------------------------------- */ bool EFLookDist(hn1, hn2, pMinDist, pMaxDist) HierName *hn1, *hn2; int *pMinDist, *pMaxDist; { Distance distKey, *dist; HashEntry *he; if (EFHNBest(hn1, hn2)) { distKey.dist_1 = hn1; distKey.dist_2 = hn2; } else { distKey.dist_1 = hn2; distKey.dist_2 = hn1; } he = HashLookOnly(&efDistHashTable, (char *) &distKey); if (he == NULL) return FALSE; dist = (Distance *) HashGetValue(he); *pMinDist = dist->dist_min; *pMaxDist = dist->dist_max; return TRUE; } /* * ---------------------------------------------------------------------------- * * EFHNOut -- * * Output a hierarchical node name. * The flags in EFTrimFlags control whether global (!) or local (#) * suffixes are to be trimmed. * * Results: * None. * * Side effects: * Writes to the files 'outf'. * * ---------------------------------------------------------------------------- */ void EFHNOut(hierName, outf) HierName *hierName; FILE *outf; { bool trimGlob, trimLocal, trimComma; char *cp, c; if (hierName->hn_parent) efHNOutPrefix(hierName->hn_parent, outf); if (EFTrimFlags) { cp = hierName->hn_name; trimGlob = (EFTrimFlags & EF_TRIMGLOB); trimLocal = (EFTrimFlags & EF_TRIMLOCAL); trimComma = (EFTrimFlags & EF_CONVERTCOMMAS); while (c = *cp++) { if (*cp) { if (trimComma && (c == ',')) putc(';', outf); else putc(c, outf); } else switch (c) { case '!': if (!trimGlob) (void) putc(c, outf); break; case '#': if (trimLocal) break; default: (void) putc(c, outf); break; } } } else (void) fputs(hierName->hn_name, outf); } void efHNOutPrefix(hierName, outf) HierName *hierName; FILE *outf; { char *cp, c; if (hierName->hn_parent) efHNOutPrefix(hierName->hn_parent, outf); cp = hierName->hn_name; while (c = *cp++) putc(c, outf); putc('/', outf); } magic-8.0.210/extflat/Makefile0000644000175000001440000000047310751423606014571 0ustar timusers# # rcsid "$Header: /usr/cvsroot/magic-8.0/extflat/Makefile,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $" # MODULE = extflat MAGICDIR = .. SRCS = EFargs.c EFbuild.c EFdef.c EFerr.c EFflat.c EFhier.c EFname.c \ EFread.c EFsym.c EFvisit.c include ${MAGICDIR}/defs.mak include ${MAGICDIR}/rules.mak magic-8.0.210/extflat/EFflat.c0000664000175000001440000010267612145167075014454 0ustar timusers/* * EFflat.c - * * Procedures to flatten the hierarchical description built * by efReadDef(). * * ********************************************************************* * * 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/extflat/EFflat.c,v 1.5 2010/12/16 18:59:03 tim Exp $"; #endif /* not lint */ #include #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/geofast.h" #include "utils/hash.h" #include "utils/malloc.h" #include "utils/utils.h" #include "extflat/extflat.h" #include "extflat/EFint.h" /* Initial size of the hash table of all flattened node names */ #define INITFLATSIZE 1024 /* Hash table containing all flattened capacitors */ HashTable efCapHashTable; /* Hash table containing all flattened distances */ HashTable efDistHashTable; /* Head of circular list of all flattened nodes */ EFNode efNodeList; /* Root of the tree being flattened */ Def *efFlatRootDef; Use efFlatRootUse; HierContext efFlatContext; /* Forward declarations */ int efFlatSingleCap(); void efFlatGlob(); int efFlatGlobHash(HierName *); bool efFlatGlobCmp(HierName *, HierName *); char *efFlatGlobCopy(HierName *); void efFlatGlobError(EFNodeName *, EFNodeName *); int efAddNodes(HierContext *, bool); int efAddOneConn(HierContext *, char *, char *, Connection *); /* * ---------------------------------------------------------------------------- * * EFFlatBuild -- * * First pass of flattening a circuit. * Builds up the flattened tables of nodes, capacitors, etc, depending * on the bits contained in flags: EF_FLATNODES causes the node table * to be built, EF_FLATCAPS the internodal capacitor table (implies * EF_FLATNODES), and EF_FLATDISTS the distance table. * * Callers who want various pieces of information should call * the relevant EFVisit procedures (e.g., EFVisitDevs(), EFVisitCaps(), * EFVisitNodes(), etc). * * Results: * None. * * Side effects: * Allocates lots of memory. * Be certain to call EFFlatDone() when this memory is * no longer needed. * * ---------------------------------------------------------------------------- */ void EFFlatBuild(name, flags) char *name; /* Name of root def being flattened */ int flags; /* Say what to flatten; see above */ { efFlatRootDef = efDefLook(name); if (efHNStats) efHNPrintSizes("before building flattened table"); /* Keyed by a full HierName */ HashInitClient(&efNodeHashTable, INITFLATSIZE, HT_CLIENTKEYS, efHNCompare, (char *(*)()) NULL, efHNHash, (int (*)()) NULL); /* Keyed by a pair of HierNames */ HashInitClient(&efDistHashTable, INITFLATSIZE, HT_CLIENTKEYS, efHNDistCompare, efHNDistCopy, efHNDistHash, efHNDistKill); /* Keyed by pairs of EFNode pointers (i.e., EFCoupleKeys) */ HashInit(&efCapHashTable, INITFLATSIZE, HashSize(sizeof (EFCoupleKey))); /* Keyed by a string and a HierName */ HashInitClient(&efHNUseHashTable, INITFLATSIZE, HT_CLIENTKEYS, efHNUseCompare, (char *(*)()) NULL, efHNUseHash, (int (*)()) NULL); /* Circular list of all nodes contains no elements initially */ efNodeList.efnode_next = (EFNodeHdr *) &efNodeList; efNodeList.efnode_prev = (EFNodeHdr *) &efNodeList; efFlatContext.hc_hierName = (HierName *) NULL; efFlatContext.hc_use = &efFlatRootUse; efFlatContext.hc_trans = GeoIdentityTransform; efFlatContext.hc_x = efFlatContext.hc_y = 0; efFlatRootUse.use_def = efFlatRootDef; if (flags & EF_FLATNODES) { if (flags & EF_NOFLATSUBCKT) efFlatNodesStdCell(&efFlatContext); else efFlatNodes(&efFlatContext); efFlatKills(&efFlatContext); efFlatGlob(); } /* Must happen after kill processing */ if (flags & EF_FLATCAPS) efFlatCaps(&efFlatContext); /* Distances are independent of kill processing */ if (flags & EF_FLATDISTS) efFlatDists(&efFlatContext); if (efHNStats) efHNPrintSizes("after building flattened table"); return; } /*----------------------------------------------------------------------*/ /* EFFlatBuildOneLevel -- */ /* */ /* EFFlatBuild for a single hierarchical level. Note, however that */ /* where subcircuits have no extracted components, the hierarchy of */ /* the subcircuit will be traversed and the subcircuit merged into */ /* the root being flattened. */ /* */ /* This routine used for hierarchical extraction. */ /*----------------------------------------------------------------------*/ HierContext * EFFlatBuildOneLevel(def) Def *def; /* root def being flattened */ { int usecount; Use *use; int efFlatNodesDeviceless(); /* Forward declaration */ efFlatRootDef = def; /* Keyed by a full HierName */ HashInitClient(&efNodeHashTable, INITFLATSIZE, HT_CLIENTKEYS, efHNCompare, (char *(*)()) NULL, efHNHash, (int (*)()) NULL); /* Keyed by a pair of HierNames */ HashInitClient(&efDistHashTable, INITFLATSIZE, HT_CLIENTKEYS, efHNDistCompare, efHNDistCopy, efHNDistHash, efHNDistKill); /* Keyed by pairs of EFNode pointers (i.e., EFCoupleKeys) */ HashInit(&efCapHashTable, INITFLATSIZE, HashSize(sizeof (EFCoupleKey))); /* Keyed by a string and a HierName */ HashInitClient(&efHNUseHashTable, INITFLATSIZE, HT_CLIENTKEYS, efHNUseCompare, (char *(*)()) NULL, efHNUseHash, (int (*)()) NULL); /* Circular list of all nodes contains no elements initially */ efNodeList.efnode_next = (EFNodeHdr *) &efNodeList; efNodeList.efnode_prev = (EFNodeHdr *) &efNodeList; efFlatContext.hc_hierName = (HierName *) NULL; efFlatContext.hc_use = &efFlatRootUse; efFlatContext.hc_trans = GeoIdentityTransform; efFlatContext.hc_x = efFlatContext.hc_y = 0; efFlatRootUse.use_def = efFlatRootDef; usecount = 0; /* Record all nodes of the next level in the hierarchy */ efHierSrUses(&efFlatContext, efAddNodes, (ClientData)FALSE); /* Expand all subcells that contain connectivity information but */ /* no active devices (including those in subcells). */ for (use = efFlatRootUse.use_def->def_uses; use; use = use->use_next) usecount++; /* Recursively flatten uses that have no active devices */ if (usecount > 0) efHierSrUses(&efFlatContext, efFlatNodesDeviceless, (ClientData)&usecount); if ((usecount == 0) && (efFlatRootUse.use_def->def_devs == NULL)) efFlatRootUse.use_def->def_flags |= DEF_NODEVICES; /* Record all local nodes */ efAddNodes(&efFlatContext, FALSE); efAddConns(&efFlatContext); efFlatGlob(); return &efFlatContext; } /* * ---------------------------------------------------------------------------- * * EFFlatDone -- * * Cleanup by removing all memory used by the flattened circuit * representation. * * Results: * None. * * Side effects: * Frees lots of memory. * * ---------------------------------------------------------------------------- */ void EFFlatDone() { #ifdef MALLOCTRACE /* Hash table statistics */ TxPrintf("\n\nStatistics for node hash table:\n"); HashStats(&efNodeHashTable); #endif /* MALLOCTRACE */ /* Free temporary storage */ efFreeNodeTable(&efNodeHashTable); efFreeNodeList(&efNodeList); HashFreeKill(&efCapHashTable); HashKill(&efNodeHashTable); HashKill(&efHNUseHashTable); return; } /* * ---------------------------------------------------------------------------- * * efFlatNodes -- * * Recursive procedure to flatten the nodes in hc->hc_use->use_def, * using a depth-first post-order traversal of the hierarchy. * * Algorithm: * We first recursivly call efFlatNodes for all of our children uses. * This adds their node names to the global node table. Next we add * our own nodes to the table. Some nodes will have to be merged * by connections made in this def, or at least will require adjustments * to their resistance or capacitance. We walk down the connection * list hc->hc_use->use_def->def_conns to do this merging. Whenever * two nodes merge, the EFNodeName list for the resulting node is * rearranged to begin with the highest precedence name from the lists * for the two nodes being combined. See efNodeMerge for a discussion * of precedence. * * Results: * Returns 0 to keep efHierSrUses going. * * Side effects: * Adds node names to the table of flattened node names efNodeHashTable. * May merge nodes from the list efNodeList as per the connection * list hc->hc_use->use_def->def_conns. * * ---------------------------------------------------------------------------- */ int efFlatNodes(hc) HierContext *hc; { (void) efHierSrUses(hc, efFlatNodes); /* Add all our own nodes to the table */ efAddNodes(hc, FALSE); /* Process our own connections and adjustments */ (void) efAddConns(hc); return (0); } /* * ---------------------------------------------------------------------------- * * efFlatNodesStdCell -- * * Recursive procedure to flatten the nodes in hc->hc_use->use_def, * using a depth-first post-order traversal of the hierarchy. We stop * whenever we reach a subcircuit definition, only enumerating its ports. * * Algorithm: * We first recursivly call efFlatNodes for all of our children uses. * This adds their node names to the global node table. Next we add * our own nodes to the table. Some nodes will have to be merged * by connections made in this def, or at least will require adjustments * to their resistance or capacitance. We walk down the connection * list hc->hc_use->use_def->def_conns to do this merging. Whenever * two nodes merge, the EFNodeName list for the resulting node is * rearranged to begin with the highest precedence name from the lists * for the two nodes being combined. See efNodeMerge for a discussion * of precedence. * * Results: * Returns 0 to keep efHierSrUses going. * * Side effects: * Adds node names to the table of flattened node names efNodeHashTable. * May merge nodes from the list efNodeList as per the connection * list hc->hc_use->use_def->def_conns. * * ---------------------------------------------------------------------------- */ int efFlatNodesStdCell(hc) HierContext *hc; { if (!(hc->hc_use->use_def->def_flags & DEF_SUBCIRCUIT)) { /* Recursively flatten each use, except in defined subcircuits */ (void) efHierSrUses(hc, efFlatNodesStdCell, (ClientData) NULL); } /* Add all our own nodes to the table */ efAddNodes(hc, TRUE); /* Process our own connections and adjustments */ if (!(hc->hc_use->use_def->def_flags & DEF_SUBCIRCUIT)) (void) efAddConns(hc); return (0); } int efFlatNodesDeviceless(hc, cdata) HierContext *hc; ClientData cdata; { int *usecount = (int *)cdata; int newcount = 0; Use *use; for (use = hc->hc_use->use_def->def_uses; use; use = use->use_next) newcount++; /* Recursively flatten uses that have no active devices */ if (newcount > 0) efHierSrUses(hc, efFlatNodesDeviceless, (ClientData)&newcount); if ((hc->hc_use->use_def->def_devs == NULL) && (newcount == 0)) { /* Add all our own nodes to the table */ efAddNodes(hc, TRUE); /* Process our own connections and adjustments */ efAddConns(hc); /* Mark this definition as having no devices, so it will not be visited */ hc->hc_use->use_def->def_flags |= DEF_NODEVICES; (*usecount)--; } return (0); } /* * ---------------------------------------------------------------------------- * * efAddNodes -- * * Add all the nodes defined by the def 'hc->hc_use->use_def' to the * global symbol table. Each global name is prefixed by the hierarchical * name component hc->hc_hierName. If "stdcell" is TRUE, we ONLY add nodes * that are defined ports. Otherwise, we add all nodes. * * Results: * None. * * Side effects: * Adds node names to the table of flattened node names efNodeHashTable. * * ---------------------------------------------------------------------------- */ int efAddNodes(hc, stdcell) HierContext *hc; bool stdcell; { Def *def = hc->hc_use->use_def; EFNodeName *nn, *newname, *oldname; EFNode *node, *newnode; EFAttr *ap, *newap; HierName *hierName; float scale; int size, asize; HashEntry *he; bool is_subcircuit = (def->def_flags & DEF_SUBCIRCUIT) ? TRUE : FALSE; scale = def->def_scale; size = sizeof (EFNode) + (efNumResistClasses-1) * sizeof (PerimArea); for (node = (EFNode *) def->def_firstn.efnode_next; node != &def->def_firstn; node = (EFNode *) node->efnode_next) { /* In subcircuits, only enumerate the ports */ if (stdcell && is_subcircuit && !(node->efnode_flags & EF_PORT)) continue; newnode = (EFNode *) mallocMagic((unsigned)(size)); newnode->efnode_attrs = (EFAttr *) NULL; for (ap = node->efnode_attrs; ap; ap = ap->efa_next) { asize = ATTRSIZE(strlen(ap->efa_text)); newap = (EFAttr *) mallocMagic((unsigned)(asize)); (void) strcpy(newap->efa_text, ap->efa_text); GeoTransRect(&hc->hc_trans, &ap->efa_loc, &newap->efa_loc); newap->efa_loc.r_xbot = (int)((float)(newap->efa_loc.r_xbot) * scale); newap->efa_loc.r_xtop = (int)((float)(newap->efa_loc.r_xtop) * scale); newap->efa_loc.r_ybot = (int)((float)(newap->efa_loc.r_ybot) * scale); newap->efa_loc.r_ytop = (int)((float)(newap->efa_loc.r_ytop) * scale); newap->efa_type = ap->efa_type; newap->efa_next = newnode->efnode_attrs; newnode->efnode_attrs = newap; } newnode->efnode_cap = node->efnode_cap; newnode->efnode_client = (ClientData) NULL; newnode->efnode_flags = node->efnode_flags; newnode->efnode_type = node->efnode_type; bcopy((char *) node->efnode_pa, (char *) newnode->efnode_pa, efNumResistClasses * sizeof (PerimArea)); GeoTransRect(&hc->hc_trans, &node->efnode_loc, &newnode->efnode_loc); /* Scale the result by "scale" --- hopefully we end up with an integer */ /* We don't scale the transform because the scale may be non-integer */ /* and the Transform type has integers only. */ newnode->efnode_loc.r_xbot = (int)((float)(newnode->efnode_loc.r_xbot) * scale); newnode->efnode_loc.r_xtop = (int)((float)(newnode->efnode_loc.r_xtop) * scale); newnode->efnode_loc.r_ybot = (int)((float)(newnode->efnode_loc.r_ybot) * scale); newnode->efnode_loc.r_ytop = (int)((float)(newnode->efnode_loc.r_ytop) * scale); /* Prepend to global node list */ newnode->efnode_next = efNodeList.efnode_next; newnode->efnode_prev = (EFNodeHdr *) &efNodeList; efNodeList.efnode_next->efnhdr_prev = (EFNodeHdr *) newnode; efNodeList.efnode_next = (EFNodeHdr *) newnode; /* Add each name for this node to the hash table */ newnode->efnode_name = (EFNodeName *) NULL; for (nn = node->efnode_name; nn; nn = nn->efnn_next) { /* * Construct the full hierarchical name of this node. * The path down to this point is given by hc->hc_hierName, * to which nn->efnn_hier is "appended". Exception: nodes * marked with EF_DEVTERM (fet substrate nodes used before * declared, so intended to refer to default global names) * are added as global nodes. */ if (node->efnode_flags & EF_DEVTERM) hierName = nn->efnn_hier; else hierName = EFHNConcat(hc->hc_hierName, nn->efnn_hier); he = HashFind(&efNodeHashTable, (char *) hierName); /* * The name should only have been in the hash table already * if the node was marked with EF_DEVTERM as described above. */ if (oldname = (EFNodeName *) HashGetValue(he)) { if (hierName != nn->efnn_hier) EFHNFree(hierName, hc->hc_hierName, HN_CONCAT); if (oldname->efnn_node != newnode) efNodeMerge(oldname->efnn_node, newnode); newnode = oldname->efnn_node; continue; } /* * We only guarantee that the first name for the node remains * first (since the first name is the "canonical" name for the * node). The order of the remaining names will be reversed. */ newname = (EFNodeName *) mallocMagic((unsigned)(sizeof (EFNodeName))); HashSetValue(he, (char *) newname); newname->efnn_node = newnode; newname->efnn_hier = hierName; if (newnode->efnode_name) { newname->efnn_next = newnode->efnode_name->efnn_next; newnode->efnode_name->efnn_next = newname; } else { newname->efnn_next = (EFNodeName *) NULL; newnode->efnode_name = newname; } } } return 0; } /* * ---------------------------------------------------------------------------- * * efAddConns -- * * Make all the connections for a given def. This may cause previously * distinct nodes in the flat table to merge. * * Results: * Returns 0 * * Side effects: * May merge nodes from the list efNodeList as per the connection * list hc->hc_use->use_def->def_conns. * * ---------------------------------------------------------------------------- */ int efAddConns(hc) HierContext *hc; { Connection *conn; if (efWatchNodes) TxPrintf("Processing %s (%s)\n", EFHNToStr(hc->hc_hierName), hc->hc_use->use_def->def_name); for (conn = hc->hc_use->use_def->def_conns; conn; conn = conn->conn_next) { /* Special case for speed when no array info is present */ if (conn->conn_1.cn_nsubs == 0) efAddOneConn(hc, conn->conn_name1, conn->conn_name2, conn); else efHierSrArray(hc, conn, efAddOneConn, (ClientData) NULL); } return (0); } /* * ---------------------------------------------------------------------------- * * efAddOneConn -- * * Do the work of adding a single connection. The names of the nodes * to be connected are 'name1' and 'name2' (note that these are regular * strings, not HierNames). The resistance of the merged node is to be * adjusted by 'deltaR' and its capacitance by 'deltaC'. If 'name2' is * NULL, we just adjust the R and C of the node 'name1'. * * Results: * Returns 0 * * Side effects: * May merge nodes from the list efNodeList. * * ---------------------------------------------------------------------------- */ int efAddOneConn(hc, name1, name2, conn) HierContext *hc; char *name1, *name2; /* These are strings, not HierNames */ Connection *conn; { HashEntry *he1, *he2; EFNode *node, *newnode; int n; he1 = EFHNLook(hc->hc_hierName, name1, "connect(1)"); if (he1 == NULL) return 0; /* Adjust the resistance and capacitance of its corresponding node */ node = ((EFNodeName *) HashGetValue(he1))->efnn_node; node->efnode_cap += conn->conn_cap; for (n = 0; n < efNumResistClasses; n++) { node->efnode_pa[n].pa_area += conn->conn_pa[n].pa_area; node->efnode_pa[n].pa_perim += conn->conn_pa[n].pa_perim; } /* Merge this node with conn_name2 if one was specified */ if (name2) { he2 = EFHNLook(hc->hc_hierName, name2, "connect(2)"); if (he2 == NULL) return 0; newnode = ((EFNodeName *) HashGetValue(he2))->efnn_node; if (node != newnode) efNodeMerge(node, newnode); } return 0; } /* * ---------------------------------------------------------------------------- * * efFlatGlob -- * * This procedure checks to ensure that all occurrences of the same global * name are connected. It also adds the reduced form of the global name * (i.e., the global name with no pathname prefix) to the hash table * efNodeHashTable, making this the preferred name of the global node. * * Algorithm: * Scan through the node table looking for globals. Add each * global to a global name table keyed by just the first component * of the HierName. The value of the entry in this table is set * initially to the EFNodeName for the first occurrence of the * global node. If another occurrence of the global name is * found whose EFNode differs from this one's, it's an error. * However, we still merge all the pieces of a global node * into a single one at the end. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void efFlatGlob() { EFNodeName *nameFlat, *nameGlob; EFNode *nodeFlat, *nodeGlob; HashEntry *heFlat, *heGlob; HierName *hnFlat, *hnGlob; HashTable globalTable; HashSearch hs; HashInitClient(&globalTable, INITFLATSIZE, HT_CLIENTKEYS, efFlatGlobCmp, efFlatGlobCopy, efFlatGlobHash, (int (*)()) NULL); /* * The following loop examines each global name (the last component of * each flat HierName that ends in the global symbol '!'), using the * hash table globalTable to keep track of how many times each global * name has been seen. Each global name should be seen exactly once. * The only exceptions are fet substrate nodes (nodes marked with the * flag EF_DEVTERM), which automatically merge with other global nodes * with the same name, since they're only implicitly connected anyway. */ for (nodeFlat = (EFNode *) efNodeList.efnode_next; nodeFlat != &efNodeList; nodeFlat = (EFNode *) nodeFlat->efnode_next) { /* * Ignore nodes whose names aren't global. NOTE: we rely on * the fact that EFHNBest() prefers global names to all others, * so if the first name in a node's list isn't global, none of * the rest are either. */ nameFlat = nodeFlat->efnode_name; hnFlat = nameFlat->efnn_hier; if (!EFHNIsGlob(hnFlat)) continue; /* * Look for an entry corresponding to the global part of hnFlat * (only the leaf component) in the global name table. If one * isn't found, an entry gets created. */ heGlob = HashFind(&globalTable, (char *) hnFlat); nameGlob = (EFNodeName *) HashGetValue(heGlob); if (nameGlob == NULL) { /* * Create a new EFNodeName that points to nodeFlat, but * don't link it in to nodeFlat->efnode_name yet. */ nameGlob = (EFNodeName *) mallocMagic((unsigned)(sizeof (EFNodeName))); HashSetValue(heGlob, (ClientData) nameGlob); nameGlob->efnn_node = nodeFlat; nameGlob->efnn_hier = (HierName *) heGlob->h_key.h_ptr; } else if (nameGlob->efnn_node != nodeFlat) { /* * If either node is a fet substrate node (marked with EF_DEVTERM) * it's OK to merge them; otherwise, it's an error, but we still * merge the nodes. When merging, we blow away nodeGlob and * absorb it into nodeFlat for simplicity in control of the main * loop. Note that since nameGlob isn't on the efnode_name list * for nodeGlob, we have to update its node backpointer explicitly. */ nodeGlob = nameGlob->efnn_node; if ((nodeGlob->efnode_flags & EF_DEVTERM) == 0 && (nodeFlat->efnode_flags & EF_DEVTERM) == 0) { efFlatGlobError(nameGlob, nameFlat); } efNodeMerge(nodeFlat, nodeGlob); nameGlob->efnn_node = nodeFlat; } } /* * Now make another pass through the global name table, * prepending the global name (the HierName consisting of * the trailing component only that was allocated when the * name was added to globalTable above) to its node, and * also adding it to the global hash table efNodeHashTable. */ HashStartSearch(&hs); while (heGlob = HashNext(&globalTable, &hs)) { /* * Add the name to the flat node name hash table, and * prepend the EFNodeName to the node's list, but only * if the node didn't already exist in efNodeHashTable. * Otherwise, free nameGlob. */ nameGlob = (EFNodeName *) HashGetValue(heGlob); hnGlob = nameGlob->efnn_hier; heFlat = HashFind(&efNodeHashTable, (char *) hnGlob); if (HashGetValue(heFlat) == NULL) { nodeFlat = nameGlob->efnn_node; HashSetValue(heFlat, (ClientData) nameGlob); nameGlob->efnn_next = nodeFlat->efnode_name; nodeFlat->efnode_name = nameGlob; } else { freeMagic((char *) nameGlob); EFHNFree(hnGlob, (HierName *) NULL, HN_GLOBAL); } } HashKill(&globalTable); return; } void efFlatGlobError(nameGlob, nameFlat) EFNodeName *nameGlob, *nameFlat; { EFNode *nodeGlob = nameGlob->efnn_node, *nodeFlat = nameFlat->efnn_node; EFNodeName *nn; int count; TxPrintf("*** Global name %s not fully connected:\n", nameGlob->efnn_hier->hn_name); TxPrintf("One portion contains the names:\n"); for (count = 0, nn = nodeGlob->efnode_name; count < 10 && nn; count++, nn = nn->efnn_next) { TxPrintf(" %s\n", EFHNToStr(nn->efnn_hier)); } if (nn) TxPrintf(" .... (no more names will be printed)\n"); TxPrintf("The other portion contains the names:\n"); for (count = 0, nn = nodeFlat->efnode_name; count < 10 && nn; count++, nn = nn->efnn_next) { TxPrintf(" %s\n", EFHNToStr(nn->efnn_hier)); } if (nn) TxPrintf(" .... (no more names will be printed)\n"); TxPrintf("I'm merging the two pieces into a single node, but you\n"); TxPrintf("should be sure eventually to connect them in the layout.\n\n"); return; } bool efFlatGlobCmp(hierName1, hierName2) HierName *hierName1, *hierName2; { if (hierName1 == hierName2) return FALSE; return ((bool)(hierName1 == NULL || hierName2 == NULL || hierName1->hn_hash != hierName2->hn_hash || strcmp(hierName1->hn_name, hierName2->hn_name) != 0 )); } char * efFlatGlobCopy(hierName) HierName *hierName; { HierName *hNew; int size; size = HIERNAMESIZE(strlen(hierName->hn_name)); hNew = (HierName *) mallocMagic((unsigned)(size)); (void) strcpy(hNew->hn_name, hierName->hn_name); hNew->hn_parent = (HierName *) NULL; hNew->hn_hash = hierName->hn_hash; if (efHNStats) efHNRecord(size, HN_GLOBAL); return (char *) hNew; } int efFlatGlobHash(hierName) HierName *hierName; { return hierName->hn_hash; } /* * ---------------------------------------------------------------------------- * * efFlatKills -- * * Recursively mark all killed nodes, using a depth-first post-order * traversal of the hierarchy. The algorithm is the same as for * efFlatNodes above. * * Results: * Returns 0 to keep efHierSrUses going. * * Side effects: * May mark node entries in the global name table as killed * by setting EF_KILLED in the efnode_flags field. * * ---------------------------------------------------------------------------- */ int efFlatKills(hc) HierContext *hc; { Def *def = hc->hc_use->use_def; HashEntry *he; EFNodeName *nn; Kill *k; /* Recursively visit each use */ (void) efHierSrUses(hc, efFlatKills, (ClientData) NULL); /* Process all of our kill information */ for (k = def->def_kills; k; k = k->kill_next) { if (he = EFHNConcatLook(hc->hc_hierName, k->kill_name, "kill")) { nn = (EFNodeName *) HashGetValue(he); nn->efnn_node->efnode_flags |= EF_KILLED; } } return (0); } /* * ---------------------------------------------------------------------------- * * efFlatCaps -- * * Recursive procedure to flatten all capacitors in the circuit. * Produces a single, global hash table (efCapHashTable) indexed * by pairs of EFNode pointers, where the value of each entry is the * capacitance between the two nodes. * * Algorithm: * Before this procedure is called, efFlatNodes() should have been * called to create a global table of all node names. We do a recursive * traversal of the design rooted at 'hc->hc_use->use_def', and construct * full hierarchical names from the terminals of each capacitor * encountered. * * These full names are used to find via a lookup in efNodeHashTable the * canonical name of the node for which this full name is an alias. The * canonical name is output as the node to which this terminal connects. * * Capacitance where one of the nodes is GND is treated specially; * instead of adding an entry to the global hash table, we update * the substrate capacitance of the other node appropriately (KLUDGE). * * Results: * Returns 0 to keep efHierSrUses going. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ int efFlatCaps(hc) HierContext *hc; { Connection *conn; /* Recursively flatten capacitors */ (void) efHierSrUses(hc, efFlatCaps, (ClientData) 0); /* Output our own capacitors */ for (conn = hc->hc_use->use_def->def_caps; conn; conn = conn->conn_next) { /* Special case for speed if no arraying info */ if (conn->conn_1.cn_nsubs == 0) efFlatSingleCap(hc, conn->conn_name1, conn->conn_name2, conn); else efHierSrArray(hc, conn, efFlatSingleCap, (ClientData) NULL); } return (0); } /* * ---------------------------------------------------------------------------- * * efFlatSingleCap -- * * Add a capacitor with value 'conn->conn_cap' between the nodes * 'name1' and 'name2' (text names, not hierarchical names). Don't * add the capacitor if either terminal is a killed node. * * Results: * Returns 0 * * Side effects: * Adds an entry to efCapHashTable indexed by the nodes of 'name1' * and 'name2' respectively. If the two nodes are the same, though, * nothing happens. If either node is ground (GND!), the capacitance * is added to the substrate capacitance of the other node instead of * creating a hash table entry. * * ---------------------------------------------------------------------------- */ int efFlatSingleCap(hc, name1, name2, conn) HierContext *hc; /* Contains hierarchical pathname to cell */ char *name1, *name2; /* Names of nodes connecting to capacitor */ Connection *conn; /* Contains capacitance to add */ { EFNode *n1, *n2; HashEntry *he; EFCoupleKey ck; if ((he = EFHNLook(hc->hc_hierName, name1, "cap(1)")) == NULL) return 0; n1 = ((EFNodeName *) HashGetValue(he))->efnn_node; if (n1->efnode_flags & EF_KILLED) return 0; if ((he = EFHNLook(hc->hc_hierName, name2, "cap(2)")) == NULL) return 0; n2 = ((EFNodeName *) HashGetValue(he))->efnn_node; if (n2->efnode_flags & EF_KILLED) return 0; /* Do nothing if the nodes aren't different */ if (n1 == n2) return 0; if (EFHNIsGND((HierName *) n1->efnode_name->efnn_hier)) n2->efnode_cap += conn->conn_cap; /* node 2 to substrate */ else if (EFHNIsGND((HierName *) n2->efnode_name->efnn_hier)) n1->efnode_cap += conn->conn_cap; /* node 1 to substrate */ else { /* node1 to node2 */ if (n1 < n2) ck.ck_1 = n1, ck.ck_2 = n2; else ck.ck_1 = n2, ck.ck_2 = n1; he = HashFind(&efCapHashTable, (char *) &ck); CapHashSetValue(he, (double) (conn->conn_cap + CapHashGetValue(he))); } return 0; } /* * ---------------------------------------------------------------------------- * * efFlatDists -- * * Recursive procedure to flatten all distance information in the circuit. * Produces a single, global hash table (efDistHashTable) indexed * by Distance structures, where the value of each entry is the same * as the key and gives the min and maximum distances between the two * points. * * Results: * Returns 0 to keep efHierSrUses going. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ int efFlatDists(hc) HierContext *hc; { Distance *dist, *distFlat, distKey; HashEntry *he, *heFlat; HashSearch hs; /* Recursively flatten distances */ (void) efHierSrUses(hc, efFlatDists, (ClientData) 0); /* Process our own distances */ HashStartSearch(&hs); while (he = HashNext(&hc->hc_use->use_def->def_dists, &hs)) { dist = (Distance *) HashGetValue(he); efHNBuildDistKey(hc->hc_hierName, dist, &distKey); heFlat = HashFind(&efDistHashTable, (char *) &distKey); if (distFlat = (Distance *) HashGetValue(heFlat)) { /* * This code differs from that in efBuildDist(), in that * we replace the min/max information in distFlat from * that in dist, rather than computing a new min/max. * The reason is that the information in dist (in the * parent) is assumed to override that already computed * in the child. */ distFlat->dist_min = dist->dist_min; distFlat->dist_max = dist->dist_max; EFHNFree(distKey.dist_1, hc->hc_hierName, HN_CONCAT); EFHNFree(distKey.dist_2, hc->hc_hierName, HN_CONCAT); } else { /* * If there was no entry in the table already with this * key, make the HashEntry point to its key (which is * the newly malloc'd Distance structure). */ HashSetValue(heFlat, (ClientData) he->h_key.h_ptr); } } return 0; } /* * CapHashGetValue() * do a HashGetValue, and if the pointer is null, return (EFCapValue)0.0 */ EFCapValue CapHashGetValue(he) HashEntry *he; { EFCapValue *capp = (EFCapValue *)HashGetValue(he); if(capp == NULL) return (EFCapValue)0; else return *capp; } /* * CapHashSetValue() * if the pointer is null, allocate a EFCapValue and point to it. * Then copy in the new value. * * need to pass doubles regardless of what CapValue is because of * argument promotion in ANSI C * */ void CapHashSetValue(he, c) HashEntry *he; double c; { EFCapValue *capp = (EFCapValue *)HashGetValue(he); if(capp == NULL) { capp = (EFCapValue *) mallocMagic((unsigned)(sizeof(EFCapValue))); HashSetValue(he, capp); } *capp = (EFCapValue) c; return; } magic-8.0.210/extflat/READ_ME0000644000175000001440000000031510751423606014143 0ustar timusersThis directory contains a library for reading hierarchical .ext files and flattening them. See ../ext2sim, ../ext2spice, or ../ext2dlys for examples of programs that use this library. Walter Scott magic-8.0.210/extflat/EFint.h0000664000175000001440000002623511735152025014312 0ustar timusers/* * EFint.h -- * * Internal definitions for the procedures to flatten hierarchical * (.ext) circuit extraction files. * * ********************************************************************* * * 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. * * ********************************************************************* * * rcsid $Header: /usr/cvsroot/magic-8.0/extflat/EFint.h,v 1.6 2010/12/16 18:59:03 tim Exp $ */ #ifndef _EFINT_H #define _EFINT_H #include "utils/magic.h" /* * Add in the next character value to a hash sum. * This function uses a 4-bit rotate to ensure that "ab" and "ba" * hash to different values; the 4 bits of rotation are provided * to allow even short strings to produce large hash values. * (Small hash values don't get randomized very well). * *************************************************************** * BE VERY CAREFUL ABOUT CHANGING THIS! IT CAN MAKE AN ENORMOUS * DIFFERENCE TO THE PERFORMANCE OF THE HASHING ALGORITHM! *************************************************************** */ #define HASHADDVAL(sum, val) \ (((((unsigned) (sum)) >> 28) | (((unsigned) (sum)) << 4)) + (val)) /* ------------------------ Distance information ---------------------- */ /* * The .ext file also allows explicit distance information to be * represented. This information is stored in a hash table in each * Def, keyed by this same structure. Distances are between named * signals, rather than nodes, so we use HierNames instead of EFNodes * for the two points between which distance is measured. */ typedef struct dist { int dist_min, dist_max; /* Min and max distance (lambda) */ HierName *dist_1, *dist_2; /* Two points */ } Distance; /* ------------------------- Kill information ------------------------- */ /* * In order for resistance and distance extraction to work correctly, * it's sometimes necessary to override the structure of the graph * extracted at a lower level of the hierarchy. The "killnode" line * in a .ext file specifies that a given node, and everything that * connects to it, have been re-extracted and are represented in * flat format later in the .ext file. * * The kill list bisects the .ext file. Fets, resistors, distance * info, etc that appear before the first killnode in a .ext file * are processed by the flattener before processing the kill list * for a given cell, followed by processing those fets, resistors, * etc that appear after the first killnode line. * * To allow the distinction to be made between before-kill and after-kill * processing, node structures have a flag field that can have the * EF_AFTERKILL bit set, indicating that the node appeared after * the killnode lines. This information isn't necessary for capacitors, * resistors, or fets, since they are implicitly killed whenever any * of their terminals is connected to a killed node. */ typedef struct kill { struct kill *kill_next; /* Next kill in def */ HierName *kill_name; /* Node to kill */ } Kill; /* --------------------------- Connections ---------------------------- */ /* * Connections are used for a multitude of purposes. They all * boil down to a need to represent hierarchical names with some * array range information present. * * Connections are used to represent that two nodes must be merged, * and the resultant node's resistance and capacitance adjusted * (conn_name2 non-NULL), or that the resistance and capacitance * of a single node be adjusted (conn_name2 NULL). * * They are also used to represent internodal capacitors when * they appear on the def_caps list of a Def, or explicit resistors * when appearing on the def_resistors list. In these latter cases, * both conn_name1 and conn_name2 are non-NULL. */ /* Max number of dimensions in an array */ #define MAXSUBS 2 /* Subscripts range from r_lo to r_hi inclusive; r_lo <= r_hi */ typedef struct { int r_lo, r_hi; } Range; /* * Each node in the connection may be accompanied by subscripts. * The range of values of the subscripts are stored here. * When cn_nsubs is 2, cn_subs[0] is x, cn_subs[1] is y. */ typedef struct { char *cn_name; int cn_nsubs; Range cn_subs[MAXSUBS]; } ConnName; /* Connection itself */ typedef struct conn { ConnName conn_1; /* First node in connection */ ConnName conn_2; /* Second (optional) node in connection */ union { int conn_val_res; /* Value of capacitance (attofarads) or */ EFCapValue conn_val_cap; /* resistance (milliohms). */ } conn_value; struct conn *conn_next; /* Next connection in list */ PerimArea conn_pa[1]; /* Dummy; each connection actually has * efNumResistClasses array elements * allocated to it. */ } Connection; /* Abbreviations */ #define conn_name1 conn_1.cn_name #define conn_name2 conn_2.cn_name #define conn_res conn_value.conn_val_res #define conn_cap conn_value.conn_val_cap /* -------------------------- Defs and uses --------------------------- */ /* A Def exists for each .ext file */ typedef struct def { char *def_name; /* Name of this def */ float def_scale; /* Multiply all dimensions by this */ int def_flags; /* Flags -- see below */ HashTable def_nodes; /* Map names into EFNodeNames */ HashTable def_dists; /* Map pairs of names into Distances */ EFNode def_firstn; /* Head of circular list of nodes */ /* The following are all NULL-terminated lists */ struct use *def_uses; /* Children of this def */ Connection *def_conns; /* Hierarchical connections/adjustments */ Connection *def_caps; /* Two-terminal capacitors */ Connection *def_resistors; /* Two-terminal resistors */ Dev *def_devs; /* Devices */ Kill *def_kills; /* Used to modify hierarchical structure * using information present only in the * parent, e.g, to kill an old node and * all its attached fets prior to replacing * the node with several smaller ones, * connected by explicit resistors. */ } Def; #define DEF_AVAILABLE 0x01 /* This def has been read in */ #define DEF_SUBCIRCUIT 0x02 /* This def defines subcircuit ports */ #define DEF_PROCESSED 0x04 /* This def processed in hierarchical output */ #define DEF_NODEVICES 0x08 /* This def contains no devices */ #define DEF_SUBSNODES 0x10 /* This def contains implicit substrate nodes */ /* * Every Def has a NULL-terminated list of uses that correspond * to the subcells of that Def. If the use is an array, the ArrayInfo * structure describes the indices and the separation between elements * (for computing transforms). */ #ifndef _DATABASE_H typedef struct { int ar_xlo, ar_xhi; int ar_ylo, ar_yhi; int ar_xsep, ar_ysep; } ArrayInfo; #endif /* _DATABASE_H */ typedef struct use { char *use_id; /* Use identifier (appears in hier paths) */ Def *use_def; /* Sub def being used */ // EFNodeName *use_ports; /* Port connections, for hierarchical output */ struct use *use_next; /* Next use in list (NULL-terminated) */ Transform use_trans; /* Transform up to parent coords (for fets) */ ArrayInfo use_array; /* Arraying information */ } Use; #define use_xlo use_array.ar_xlo #define use_xhi use_array.ar_xhi #define use_ylo use_array.ar_ylo #define use_yhi use_array.ar_yhi #define use_xsep use_array.ar_xsep #define use_ysep use_array.ar_ysep #define IsArray(u) ((u)->use_xlo!=(u)->use_xhi || (u)->use_ylo!=(u)->use_yhi) /* -------------------------------------------------------------------- */ /* Structure passed down during hierarchical searching */ typedef struct { Use *hc_use; /* Use being visited */ int hc_x, hc_y; /* X and Y indices if array */ Transform hc_trans; /* Transform to flat coordinates (for fets) */ HierName *hc_hierName; /* Ptr to trailing component of HierName list */ } HierContext; /* ------------------------------ Debugging --------------------------- */ extern bool efHNStats; /* TRUE if we keep statistics on HierNames */ /* -------------------------------------------------------------------- */ /* Structure for passing procedures and cdata to client functions */ typedef struct { int (*ca_proc)(); ClientData ca_cdata; } CallArg; /* -------------------------------------------------------------------- */ /* * Structure used as key in hash table of internodal capacitors. * Keys are EFNodes, since capacitors exist between a pair of electrical * nodes. The keys are ordered so that the lowest-address EFNode is * first. */ typedef struct { EFNode *ck_1, *ck_2; } EFCoupleKey; /* -------------------------------------------------------------------- */ /* Max filename length */ #define FNSIZE 1024 /* Resistance is in milliohms, capacitance in attofarads */ extern bool efWarn; /* If TRUE, warn about unusual occurrences */ extern bool efScaleChanged; /* If TRUE, multiply all dimensions by scale * factor on output; otherwise, leave them * alone and output a global scale factor * of efScale in the .sim file. */ extern int efResists[]; /* Resistance per square for each class */ extern bool efResistChanged; /* TRUE if some cells' resistclasses unequal */ extern HashTable efFreeHashTable; extern HashTable efNodeHashTable; extern HashTable efDevParamTable; extern HashTable efHNUseHashTable; extern HashTable efCapHashTable; extern HashTable efDistHashTable; extern HashTable efWatchTable; extern bool efWatchNodes; extern EFNode efNodeList; extern Def *efFlatRootDef; /* --------------------- Internally used procedures ------------------- */ /* Def table management */ extern Def *efDefLook(); extern Def *efDefNew(); extern Def *EFRootDef(); /* HierName manipulation */ extern HierName *efHNFromUse(); extern char *efHNToStrFunc(); /* Functions for hashing of HierNames */ extern int efHNCompare(); extern int efHNHash(); /* Functions for hashing of Distances */ extern bool efHNDistCompare(); extern char *efHNDistCopy(); extern int efHNDistHash(); extern void efHNDistKill(); /* Functions for hashing of use id HierNames */ extern bool efHNUseCompare(); extern int efHNUseHash(); extern EFCapValue CapHashGetValue(); extern void CapHashSetValue(); /* efBuild procedures */ /* Warning: The capacitance argument to these should be always double regardless of whether you set EFCapValue to float or double This should be done to avoid trouble with argument promotion that some ANSI C compilers introduce */ extern DevParam *efGetDeviceParams(); extern void efBuildNode(); extern void efBuildConnect(); extern void efBuildResistor(); extern void efBuildCap(); extern HierContext *EFFlatBuildOneLevel(); #endif /* _EFINT_H */ magic-8.0.210/extflat/EFerr.c0000644000175000001440000000512410751423606014276 0ustar timusers/* * EFerr.c - * * Contains only the routine efReadError(). This used to be in EFread.c, * but including Tcl/Tk stuff caused definition conflicts. So now it * gets its own file. Note that *printf routines have been changed to * the Tx* print routines for compatibility with the Tcl-based version. * Note also that the standalone executables ext2sim and ext2spice get * the Tx* functions from utils/LIBtextio.c, whereas the built-in * "extract" function gets them from textio/txOutput.c. In the Tcl * version, all these functions are built in, so utils/LIBtextio.c is * not compiled or linked. * * ********************************************************************* * * 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/extflat/EFerr.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "textio/textio.h" extern char *efReadFileName; extern int efReadLineNum; #ifdef MAGIC_WRAPPER extern int Tcl_printf(); #endif /* * ---------------------------------------------------------------------------- * * efReadError -- * * Complain about an error encountered while reading an .ext file. * Called with a variable number of arguments. * * Results: * None. * * Side effects: * Prints an error message to stderr, complete with offending * filename and line number. * * ---------------------------------------------------------------------------- */ void efReadError(char *fmt, ...) { va_list args; TxError("%s, line %d: ", efReadFileName, efReadLineNum); va_start(args, fmt); #ifdef MAGIC_WRAPPER Tcl_printf(stderr, fmt, args); #else vfprintf(stderr, fmt, args); #endif va_end(args); TxFlushErr(); } magic-8.0.210/extflat/EFargs.c0000664000175000001440000002660112151717104014442 0ustar timusers/* * EFargs.c - * * General command-line argument processing and overall initialization * for the .ext file flattener. * * ********************************************************************* * * 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/extflat/EFargs.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include #include #include "utils/magic.h" #include "utils/paths.h" #include "utils/geometry.h" #include "utils/hash.h" #include "utils/utils.h" #include "utils/malloc.h" #include "utils/pathvisit.h" #include "extflat/extflat.h" #include "extflat/EFint.h" #define atoCap(s) ((EFCapValue)atof(s)) /* --------------------- Visible outside extflat ---------------------- */ /* Command-line flags */ EFCapValue EFCapThreshold = 2; /* -c/-C: (fF) smallest interesting C */ int EFResistThreshold = 10; /* -r/-R: (Ohms) smallest interesting R */ int EFTrimFlags = 0; /* -t: output of nodename trailing #!'s */ char *EFSearchPath = NULL; /* -p: Search path for .ext files */ char *EFArgTech = NULL; /* -T: Tech specified on command line */ /* Misc globals */ float EFScale = 0.0; /* Uninitialized scale factor */ char *EFVersion = MAGIC_VERSION;/* Version number of .ext format we read */ char *EFLibPath = NULL; /* Library search path for .ext files */ char *EFTech = NULL; char *EFStyle = NULL; /* Start with no extraction style */ #ifdef MAGIC_WRAPPER extern char *Path; /* magic's search path---note this should */ /* be done with #include "utils/main.h" but */ /* this is easier. */ #endif /* -------------------- Visible only inside extflat ------------------- */ /* Command-line flags */ bool efWarn = FALSE; /* -v: Warn about duplicate node names */ bool efHNStats = FALSE; /* -z: TRUE if we gather mem usage stats */ bool efWatchNodes = FALSE; /* -n: TRUE if watching nodes in table below */ HashTable efWatchTable; /* -n: Names to watch, keyed by HierName */ /* Misc globals */ int efResists[128]; /* Sheet resistivity for each resist class */ int efNumResistClasses = 0; /* Number of resist classes */ bool efResistChanged = FALSE; /* TRUE if .ext resist classes mismatch */ bool efScaleChanged = FALSE; /* TRUE if .ext scales mismatch */ /* Forward declarations */ #ifndef MAGIC_WRAPPER extern int efLoadPathFunc(); extern void efLoadSearchPath(); #endif /* * ---------------------------------------------------------------------------- * * EFArgs -- * * Process command-line arguments that are relevant to the extractor * flattener. Arguments that are specific to the calling function * are processed by the procedure (*argsProc)(), which should * have the following form: * * (*argsProc)(pargc, pargv, cdata) * int *pargc; * char ***pargv; * ClientData cdata; * { * } * * If we don't recognize an argument, we call (*argsProc)() with * *pargc and *pargv pointing to the position in the argument * vector that we didn't recognize. If (*argsProc)() also doesn't * recognize the argument, it exits; otherwise, it updates *pargc * and *pargv to point past the argument it gobbled off and returns. * If argsProc is NULL, then any arguments we don't recognize are * considered errors. * * Arguments processed are: * * -T techname Specify the name of the technology, leaving * EFArgTech pointing to the technology name. * -p path Use the colon-separated search path 'path' * for finding .ext files. Overrides any paths * found in .magicrc files. * -s sym=value Set the name 'sym' in the symbol hash table to * have value 'value', where 'value' is an integer. * Certain attributes interpreted during circuit * flattening may have symbolic values; the -s flag * provides a means of associating a numeric value * with a symbol. * -S symfile Read the file 'symfile', which should consist of * lines of the form sym=value, processing each line * as though it were an argument to -s. * * The following flags are for debugging purposes only: * -n nodename For debugging: print all merges involving * the node named 'nodename'. * -N nodefile For debugging: print all merges involving * any of the nodes whose names appear in the * file 'nodefile' (one node name per line). * -v Warn about unusual occurrences while flattening * the circuit; mainly for debugging. * -z Print memory utilized for names. * * Results: * Returns a pointer to a string containing the base name * of the input .ext file. * * Side effects: * Can set global variables based on the values of command-line * arguments. * err_result, if non-null, is set to TRUE if an error occurred. * err_result is only used by the Tcl version of Magic. * * ---------------------------------------------------------------------------- */ char * EFArgs(argc, argv, err_result, argsProc, cdata) int argc; /* Number of command-line args */ char *argv[]; /* Vector of command-line args */ bool *err_result; /* Set to TRUE if error occurs */ bool (*argsProc)(); /* Called for args we don't recognize */ ClientData cdata; /* Passed to (*argsProc)() */ { static char libpath[FNSIZE]; char *realIn, line[1024], *inname = NULL, *name, *cp; HierName *hierName; FILE *f; if (err_result != NULL) *err_result = FALSE; /* Hash table of nodes we're going to watch if -N given */ HashInitClient(&efWatchTable, 32, HT_CLIENTKEYS, efHNCompare, (char *(*)()) NULL, efHNHash, (int (*)()) NULL); /* Process command line options */ for (argc--, argv++; argc-- > 0; argv++) { if (argv[0][0] != '-') { if (inname) { TxError("Warning: multiple input files specified; "); TxError("ignoring \"%s\"\n", inname); } inname = argv[0]; continue; } switch (argv[0][1]) { /*** NORMAL OPTIONS ***/ case 'c': if ((cp = ArgStr(&argc, &argv, "cap threshold")) == NULL) goto usage; EFCapThreshold = atoCap(cp); /* Femtofarads */ break; case 'p': EFSearchPath = ArgStr(&argc, &argv, "search path"); if (EFSearchPath == NULL) goto usage; break; case 'r': if ((cp = ArgStr(&argc, &argv, "resist threshold")) == NULL) goto usage; EFResistThreshold = atoi(cp); /* Ohms */ break; case 's': if ((cp = ArgStr(&argc, &argv, "symbolic name")) == NULL) goto usage; efSymAdd(cp); break; case 't': if ((cp = ArgStr(&argc, &argv, "trim characters")) == NULL) goto usage; if (index(cp, '!')) EFTrimFlags |= EF_TRIMGLOB; if (index(cp, '#')) EFTrimFlags |= EF_TRIMLOCAL; if (index(cp, ',')) EFTrimFlags |= EF_CONVERTCOMMAS; if (index(cp, '=')) EFTrimFlags |= EF_CONVERTEQUAL; break; case 'C': EFCapThreshold = INFINITE_THRESHOLD; break; case 'R': EFResistThreshold = INFINITE_THRESHOLD; break; case 'S': if ((cp = ArgStr(&argc, &argv, "symbol file")) == NULL) goto usage; efSymAddFile(cp); break; #ifndef MAGIC_WRAPPER case 'T': if ((EFArgTech = ArgStr(&argc, &argv, "tech name")) == NULL) goto usage; break; #endif /*** OPTIONS FOR DEBUGGING ***/ case 'n': if ((name = ArgStr(&argc, &argv, "nodename")) == NULL) goto usage; printf("Watching node '%s'\n", name); hierName = EFStrToHN((HierName *) NULL, name); (void) HashFind(&efWatchTable, (char *) hierName); efWatchNodes = TRUE; break; case 'N': if ((name = ArgStr(&argc, &argv, "filename")) == NULL) goto usage; /* Add everything in the file to the hash table */ f = fopen(name, "r"); if (f == NULL) { perror(name); break; } while (fgets(line, sizeof line, f)) { cp = index(line, '\n'); if (cp) *cp = '\0'; printf("Watching node '%s'\n", line); hierName = EFStrToHN((HierName *) NULL, line); (void) HashFind(&efWatchTable, (char *) hierName); } (void) fclose(f); efWatchNodes = TRUE; break; case 'v': efWarn = TRUE; break; case 'z': efHNStats = TRUE; break; /*** Try a caller-supplied argument processing function ***/ default: if (argsProc == NULL) goto usage; if ((*argsProc)(&argc, &argv, cdata)) { TxError("\n"); goto usage; } break; } } /* Find the search path if one was not specified */ if (EFSearchPath == NULL) #ifdef MAGIC_WRAPPER /* Set the search path to be the same as magic's search path */ EFSearchPath = StrDup(NULL, Path); #else efLoadSearchPath(&EFSearchPath); #endif EFLibPath = libpath; *EFLibPath = 0; /* start with no path */ if (EFArgTech) (void) sprintf(EFLibPath, EXT_PATH, EFArgTech); if (inname == NULL) #ifdef MAGIC_WRAPPER return NULL; #else goto usage; #endif /* Eliminate trailing .ext from input name */ if ((cp = rindex(inname, '.')) && strcmp(cp, ".ext") == 0) { realIn = (char *) mallocMagic((unsigned)(cp - inname + 1)); (void) strncpy(realIn, inname, cp - inname); realIn[cp - inname] = '\0'; inname = realIn; } return inname; usage: TxError("Standard arguments: [-R] [-C] [-r rthresh] [-c cthresh] [-v]\n" "[-p searchpath] [-s sym=value] [-S symfile] [-t trimchars]\n" #ifdef MAGIC_WRAPPER "[rootfile]\n"); if (err_result != NULL) *err_result = TRUE; return NULL; #else "[-T techname] rootfile\n"); exit (1); /*NOTREACHED*/ #endif } #ifndef MAGIC_WRAPPER /* * ---------------------------------------------------------------------------- * * efLoadSearchPath -- * * Load the search path string pointed to by 'path' * with whatever is specified in the .magicrc files * in $CAD_ROOT/magic/sys, ~, and ., searched in that * order with the last path taking precedence. See paths.h. * * Results: * None. * * Side effects: * Leaves *path pointing to the correct search path, * which may either be static or allocated via StrDup(). * * ---------------------------------------------------------------------------- */ void efLoadSearchPath(path) char **path; { PaVisit *pv; *path = NULL; pv = PaVisitInit(); PaVisitAddClient(pv, "path", efLoadPathFunc, (ClientData) path); PaVisitFiles(DOT_MAGIC_PATH, ".magicrc", pv); PaVisitFree(pv); if (*path == NULL) *path = "."; } int efLoadPathFunc(line, ppath) char *line; char **ppath; { char *cp, *dp, c; char path[BUFSIZ]; /* Skip leading blanks */ for (cp = &line[4]; *cp && isspace(*cp); cp++) /* Nothing */; /* Copy the path into 'path' */ for (dp = path; (c = *cp++) && !isspace(c) && c != '\n'; ) { if (c == '"') { while ((c = *cp++) && c != '"') *dp++ = c; if (c == '\0') break; } else *dp++ = c; } *dp = '\0'; (void) StrDup(ppath, path); return 0; /* continue search */ } #endif magic-8.0.210/extflat/COMPRESS0000644000175000001440000000632110751423606014305 0ustar timusersName compression: {prefix}/{suffix} -> {prefix} if {prefix} is unique {prefix}/{suffix} -> {suffix} if {suffix} is unique {prefix}/{middle}/{suffix} -> {prefix}/{suffix} if unique Consider array subscripts independently from name portions. Apply name compression only to the most-preferred name for each node. Algorithm (greedy): Input is a name of the form: Name * shorten(startName) Name *startName; /* nk/.../n1/n0 */ { Name *best, *prefix, *suffix; int bestLength, length, i; best = startName; bestLength = nameLength(startName); /* Find small suffixes */ for (suffix = NULL, i = 0; i <= bestLength + 1; i++) { newName = "ni/.../n0"; if (totallyUnique(newName) && suffixUnique(newName)) { suffix = newName; break; } } if (suffix && nameLength(suffix) < bestLength) { best = suffix; bestLength = nameLength(suffix); } /* Find small prefixes */ for (prefix = NULL, i = bestLength + 1; i >= 0; i--) { newName = "nk/.../ni"; if (totallyUnique(newName) && prefixUnique(newName)) { prefix = newName; break; } } if (prefix && nameLength(prefix) < bestLength) { best = prefix; bestLength = nameLength(prefix); } /* * Consider eliding inner parts of the name. * This loop starts with the smallest length and goes up * to names of length bestLength. */ for (length = 1; length < bestLength; length++) if (genAllSubNames(startName, length, elideFunc, &best)) break; return best; } /* * totallyUnique -- * * Determine whether 'name' is unique with respect to all the * names currently in nameTable. * * Results: * TRUE if 'name' is unique, FALSE if not. * * Side effects: * None. */ bool totallyUnique(name) Name *name; { } /* * prefixUnique -- * * Compare 'name' with all other names in nameTable, looking * only at the leading components of these names. If 'name' * isn't unique with respect to the set of names formed by * the leading components, return FALSE. * * Results: * TRUE if 'name' is unique as described above, FALSE if not. * * Side effects: * None. */ bool prefixUnique(name) Name *name; { } /* * suffixUnique -- * * Compare 'name' with all other names in nameTable, looking * only at the trailing components of these names. If 'name' * isn't unique with respect to the set of names formed by * the trailing components, return FALSE. * * Results: * TRUE if 'name' is unique as described above, FALSE if not. * * Side effects: * None. */ bool suffixUnique(name) Name *name; { } /* * genAllSubNames -- * * Generate all subnames of 'name' that are of length 'subLength'. * Call (*func)() on each name, where (*func)() is of the following * form: * * int * (*func)(name, cdata) * Name *name; * ClientData cdata; * { * } * * This function should return 0 if genAllSubNames() should continue * generating names, or 1 if we should stop. * * Results: * Returns 1 if (*func)() aborted the generation; otherwise * returns 0. * * Side effects: * None other than those caused by (*func)(). */ int genAllSubNames(name, subLength, func, cdata) Name *name; int subLength; int (*func)(); ClientData cdata; { } magic-8.0.210/extflat/EFname.c0000644000175000001440000006043111430115345014421 0ustar timusers/* * EFhier.c - * * Procedures for manipulating HierNames. * * ********************************************************************* * * 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/extflat/EFname.c,v 1.2 2010/08/10 00:18:45 tim Exp $"; #endif /* not lint */ #include #include #include #include "tcltk/tclmagic.h" #include "utils/magic.h" #include "utils/geometry.h" #include "utils/geofast.h" #include "utils/hash.h" #include "utils/malloc.h" #include "utils/utils.h" #include "extflat/extflat.h" #include "extflat/EFint.h" #ifdef MAGIC_WRAPPER #define PrintErr TxError #else #define PrintErr printf #endif /* * Hash table containing all flattened node names. * The keys in this table are HierNames, processed by the * procedures efHNCompare(), efHNHash(), efHierCopy(), * and efHierKill(). */ HashTable efNodeHashTable; /* * Hash table used by efHNFromUse to ensure that it always returns * a pointer to the SAME HierName structure each time it is called * with the same fields. */ HashTable efHNUseHashTable; extern void EFHNFree(); extern void efHNInit(); extern void efHNRecord(); /* * ---------------------------------------------------------------------------- * * EFHNIsGlob -- * * Determine whether a HierName is of the format of a global name, * i.e, it ends in a '!'. * * The Tcl version of magic further refines this to include names * which are defined in the global Tcl variable space. (7.3.94): * also check if the array variable "globals" contains the name as * a key entry. * * Results: * TRUE if the name is a global. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool EFHNIsGlob(hierName) HierName *hierName; { #ifdef MAGIC_WRAPPER char *retstr; retstr = (char *)Tcl_GetVar2(magicinterp, "globals", hierName->hn_name, TCL_GLOBAL_ONLY); if (retstr != NULL) return TRUE; retstr = (char *)Tcl_GetVar(magicinterp, hierName->hn_name, TCL_GLOBAL_ONLY); if (retstr != NULL) return TRUE; #endif return hierName->hn_name[strlen(hierName->hn_name) - 1] == '!'; } /* * ---------------------------------------------------------------------------- * * EFHNIsGND -- * * Determine whether a HierName is the same as the global signal GND. * * The Tcl version of magic expands this to include names which are * equal to the global Tcl variable $GND, if it is set. * * Results: * TRUE if the name is GND, false if not. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool EFHNIsGND(hierName) HierName *hierName; { #ifdef MAGIC_WRAPPER char *retstr; #endif if (hierName->hn_parent != (HierName *) NULL) return FALSE; #ifdef MAGIC_WRAPPER retstr = (char *)Tcl_GetVar(magicinterp, "GND", TCL_GLOBAL_ONLY); if (retstr != NULL) if (!strcmp(hierName->hn_name, retstr)) return TRUE; #endif return (strcmp(hierName->hn_name, "GND!") == 0); } /* * ---------------------------------------------------------------------------- * * EFHNConcat -- * * Given a HierName prefix and a HierName suffix, make a newly allocated * copy of the suffix that points to the prefix. * * Results: * Pointer to the new HierName as described above. * * Side effects: * May allocate memory. * * ---------------------------------------------------------------------------- */ HierName * EFHNConcat(prefix, suffix) HierName *prefix; /* Components of name on root side */ HierName *suffix; /* Components of name on leaf side */ { HierName *new, *prev; HierName *firstNew; unsigned size; for (firstNew = prev = (HierName *) NULL; suffix; prev = new, suffix = suffix->hn_parent) { size = HIERNAMESIZE(strlen(suffix->hn_name)); new = (HierName *) mallocMagic((unsigned)(size)); if (efHNStats) efHNRecord(size, HN_CONCAT); new->hn_hash = suffix->hn_hash; (void) strcpy(new->hn_name, suffix->hn_name); if (prev) prev->hn_parent = new; else firstNew = new; } prev->hn_parent = prefix; return firstNew; } /* * ---------------------------------------------------------------------------- * * EFStrToHN -- * * Given a hierarchical prefix (the HierName pointed to by prefix) * and a name relative to that prefix (the string 'suffixStr'), return a * pointer to the HierName we should use. Normally, this is just a newly * built HierName containing the path components of 'suffixStr' appended to * prefix. * * Results: * Pointer to a name determined as described above. * * Side effects: * May allocate new HierNames. * * ---------------------------------------------------------------------------- */ HierName * EFStrToHN(prefix, suffixStr) HierName *prefix; /* Components of name on side of root */ char *suffixStr; /* Leaf part of name (may have /'s) */ { char *cp; HashEntry *he; char *slashPtr; HierName *hierName; unsigned size; int len; /* Skip to the end of the relative name */ slashPtr = NULL; for (cp = suffixStr; *cp; cp++) if (*cp == '/') slashPtr = cp; /* * Convert the relative name into a HierName path, with one HierName * created for each slash-separated segment of suffixStr. */ cp = slashPtr = suffixStr; for (;;) { if (*cp == '/' || *cp == '\0') { size = HIERNAMESIZE(cp - slashPtr); hierName = (HierName *) mallocMagic((unsigned)(size)); if (efHNStats) efHNRecord(size, HN_ALLOC); efHNInit(hierName, slashPtr, cp); hierName->hn_parent = prefix; if (*cp++ == '\0') break; slashPtr = cp; prefix = hierName; } else cp++; } return hierName; } /* * ---------------------------------------------------------------------------- * * EFHNToStr -- * * Convert a HierName chain into a printable name. * Stores the result in a static buffer. * * Results: * Returns a pointer to the static buffer containing the * printable name. * * Side effects: * Overwrites the previous contents of the static buffer. * * ---------------------------------------------------------------------------- */ char * EFHNToStr(hierName) HierName *hierName; /* Name to be converted */ { static char namebuf[2048]; (void) efHNToStrFunc(hierName, namebuf); return namebuf; } /* * efHNToStrFunc -- * * Recursive part of name conversion. * Calls itself recursively on hierName->hn_parent and dstp, * adding the prefix of the pathname to the string pointed to * by dstp. Then stores hierName->hn_name at the end of the * just-stored prefix, and returns a pointer to the end. * * Results: * Returns a pointer to the null byte at the end of * all the pathname components stored so far in dstp. * * Side effects: * Stores characters in dstp. */ char * efHNToStrFunc(hierName, dstp) HierName *hierName; /* Name to be converted */ char *dstp; /* Store name here */ { char *srcp; if (hierName == NULL) { *dstp = '\0'; return dstp; } if (hierName->hn_parent) { dstp = efHNToStrFunc(hierName->hn_parent, dstp); *dstp++ = '/'; } srcp = hierName->hn_name; while (*dstp++ = *srcp++) /* Nothing */; return --dstp; } /* * ---------------------------------------------------------------------------- * * EFHNLook -- * * Look for the entry in the efNodeHashTable whose name is formed * by concatenating suffixStr to prefix. If there's not an * entry in efNodeHashTable, or the entry has a NULL value, complain * and return NULL; otherwise return the HashEntry. * * The string errorStr should say what we were processing, e.g, * "fet", "connect(1)", "connect(2)", etc., for use in printing * error messages. If errorStr is NULL, we don't print any error * messages. * * Results: * See above. * * Side effects: * Allocates memory temporarily to build the key for HashLookOnly(), * but then frees it before returning. * * ---------------------------------------------------------------------------- */ HashEntry * EFHNLook(prefix, suffixStr, errorStr) HierName *prefix; /* Components of name on root side */ char *suffixStr; /* Part of name on leaf side */ char *errorStr; /* Explanatory string for errors */ { HierName *hierName, *hn; bool dontFree = FALSE; HashEntry *he; if (suffixStr == NULL) { hierName = prefix; dontFree = TRUE; } else hierName = EFStrToHN(prefix, suffixStr); he = HashLookOnly(&efNodeHashTable, (char *) hierName); if (he == NULL || HashGetValue(he) == NULL) { if (errorStr) PrintErr("%s: no such node %s\n", errorStr, EFHNToStr(hierName)); he = NULL; } /* * Free the portion of the HierName we just allocated for * looking in the table, if we allocated one. */ if (!dontFree) EFHNFree(hierName, prefix, HN_ALLOC); return he; } /* * ---------------------------------------------------------------------------- * * EFHNConcatLook -- * * Like EFHNLook above, but the argument suffix is itself a HierName. * We construct the full name by concatenating the hierarchical prefix * and the node name 'suffix', then looking it up in the flat node * table for its real name. * * Results: * See EFHNLook()'s comments. * * Side effects: * See EFHNLook()'s comments. * * ---------------------------------------------------------------------------- */ HashEntry * EFHNConcatLook(prefix, suffix, errorStr) HierName *prefix; /* Components of name on root side */ HierName *suffix; /* Part of name on leaf side */ char *errorStr; /* Explanatory string for errors */ { HashEntry *he; HierName *hn; /* * Find the last component of the suffix, then temporarily * link the HierNames for use as a hash key. This is safe * because HashLookOnly() doesn't ever store anything in the * hash table, so we don't have to worry about this temporarily * built key somehow being saved without our knowledge. */ hn = suffix; while (hn->hn_parent) hn = hn->hn_parent; hn->hn_parent = prefix; he = HashLookOnly(&efNodeHashTable, (char *) suffix); if (he == NULL || HashGetValue(he) == NULL) { PrintErr("%s: no such node %s\n", errorStr, EFHNToStr(suffix)); he = (HashEntry *) NULL; } /* Undo the temp link */ hn->hn_parent = (HierName *) NULL; return he; } /* * ---------------------------------------------------------------------------- * * EFHNFree -- * * Free a list of HierNames, up to but not including the element pointed * to by 'prefix' (or the NULL indicating the end of the HierName list). * * Results: * None. * * Side effects: * Frees memory. * * ---------------------------------------------------------------------------- */ void EFHNFree(hierName, prefix, type) HierName *hierName, *prefix; int type; /* HN_ALLOC, HN_CONCAT, etc */ { HierName *hn; for (hn = hierName; hn; hn = hn->hn_parent) { if (hn == prefix) break; freeMagic((char *) hn); if (efHNStats) { int len = strlen(hn->hn_name); efHNRecord(-HIERNAMESIZE(len), type); } } } /* * ---------------------------------------------------------------------------- * * EFHNBest -- * * Determine which of two names is more preferred. The most preferred * name is a global name. Given two non-global names, the one with the * fewest pathname components is the most preferred. If the two names * have equally many pathname components, we choose the shortest. * If they both are of the same length, we choose the one that comes * later in the alphabet. * * Results: * TRUE if the first name is preferable to the second, FALSE if not. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool EFHNBest(hierName1, hierName2) HierName *hierName1, *hierName2; { int ncomponents1, ncomponents2, len1, len2; HierName *np1, *np2; char last1, last2; for (ncomponents1 = 0, np1 = hierName1; np1; np1 = np1->hn_parent) ncomponents1++; for (ncomponents2 = 0, np2 = hierName2; np2; np2 = np2->hn_parent) ncomponents2++; last1 = hierName1->hn_name[strlen(hierName1->hn_name) - 1]; last2 = hierName2->hn_name[strlen(hierName2->hn_name) - 1]; if (last1 != '!' || last2 != '!') { /* Prefer global over local names */ if (last1 == '!') return TRUE; if (last2 == '!') return FALSE; /* Neither name is global, so chose label over generated name */ if (last1 != '#' && last2 == '#') return TRUE; if (last1 == '#' && last2 != '#') return FALSE; } /* * Compare two names the hard way. Both are of the same class, * either both global or both non-global, so compare in order: * number of pathname components, length, and lexicographic * ordering. */ if (ncomponents1 < ncomponents2) return TRUE; if (ncomponents1 > ncomponents2) return FALSE; /* Same # of pathname components; check length */ for (len1 = 0, np1 = hierName1; np1; np1 = np1->hn_parent) len1 += strlen(np1->hn_name); for (len2 = 0, np2 = hierName2; np2; np2 = np2->hn_parent) len2 += strlen(np2->hn_name); if (len1 < len2) return TRUE; if (len1 > len2) return FALSE; return (efHNLexOrder(hierName1, hierName2) > 0); } /* * ---------------------------------------------------------------------------- * * efHNLexOrder -- * * Procedure to ensure that the canonical ordering used in determining * preferred names is the same as would have been used if we were comparing * the string version of two HierNames, instead of comparing them as pathnames * with the last component first. * * Results: * Same as strcmp(), i.e, * -1 if hierName1 should precede hierName2 lexicographically, * +1 if hierName1 should follow hierName2, and * 0 is they are identical. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ int efHNLexOrder(hierName1, hierName2) HierName *hierName1, *hierName2; { int i; if (hierName1 == hierName2) return 0; if (hierName1->hn_parent) if (i = efHNLexOrder(hierName1->hn_parent, hierName2->hn_parent)) return i; return strcmp(hierName1->hn_name, hierName2->hn_name); } /* * ---------------------------------------------------------------------------- * * efHNFromUse -- * * Construct a HierName for a cell use (for the array element identified * by (hc_x, hc_y) if the use is an array). The parent pointer of this * newly allocated HierName will be set to prefix. * * Results: * Returns a pointer to a newly allocated HierName. * * Side effects: * See above. * Note: we use a hash table to ensure that we always return * the SAME HierName whenever prefix, the (x, y) use * coordinates, and the use id are the same. * * ---------------------------------------------------------------------------- */ HierName * efHNFromUse(hc, prefix) HierContext *hc; /* Contains use and array information */ HierName *prefix; /* Root part of name */ { char *srcp, *dstp; char name[2048], *namePtr; Use *u = hc->hc_use; HierName *hierName; bool hasX, hasY; HashEntry *he; unsigned size; hasX = u->use_xlo != u->use_xhi; hasY = u->use_ylo != u->use_yhi; namePtr = u->use_id; if (hasX || hasY) { namePtr = name; srcp = u->use_id; dstp = name; while (*dstp++ = *srcp++) /* Nothing */; /* Array subscript */ dstp[-1] = '['; /* Y comes before X */ if (hasY) { (void) sprintf(dstp, "%d", hc->hc_y); while (*dstp++) /* Nothing */; dstp--; /* Leave pointing to NULL byte */ } if (hasX) { if (hasY) *dstp++ = ','; (void) sprintf(dstp, "%d", hc->hc_x); while (*dstp++) /* Nothing */; dstp--; /* Leave pointing to NULL byte */ } *dstp++ = ']'; *dstp = '\0'; } size = HIERNAMESIZE(strlen(namePtr)); hierName = (HierName *) mallocMagic ((unsigned)(size)); if (efHNStats) efHNRecord(size, HN_FROMUSE); efHNInit(hierName, namePtr, (char *) NULL); hierName->hn_parent = prefix; /* See if we already have an entry for this one */ he = HashFind(&efHNUseHashTable, (char *) hierName); if (HashGetValue(he)) { freeMagic((char *) hierName); return (HierName *) HashGetValue(he); } HashSetValue(he, (ClientData) hierName); (void) HashFind(&efFreeHashTable, (char *) hierName); return hierName; } /* * ---------------------------------------------------------------------------- * * efHNUseCompare -- * * Compare two HierNames for equality, but using a different sense * of comparison than efHNCompare: two names are considered equal * only if their hn_parent fields are equal and their hn_name strings * are identical. * * Results: Returns 0 if they are equal, 1 if not. * * efHNUseHash -- * * Convert a HierName to a single 32-bit value suitable for being * turned into a hash bucket by the hash module. Hashes based on * hierName->hn_hash and hierName->hn_parent, rather than summing * the hn_hash values. * * Results: Returns the 32-bit hash value. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool efHNUseCompare(hierName1, hierName2) HierName *hierName1, *hierName2; { return ((bool)(hierName1->hn_parent != hierName2->hn_parent || strcmp(hierName1->hn_name, hierName2->hn_name) )); } int efHNUseHash(hierName) HierName *hierName; { return hierName->hn_hash + (spointertype) hierName->hn_parent; } /* * ---------------------------------------------------------------------------- * * efHNInit -- * * Copy the string 'cp' into hierName->hn_name, also initializing * the hn_hash fields of hierName. If 'endp' is NULL, copy all * characters in 'cp' up to a trailing NULL byte; otherwise, copy * up to 'endp'. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void efHNInit(hierName, cp, endp) HierName *hierName; /* Fill in fields of this HierName */ char *cp; /* Start of name to be stored in hn_name */ char *endp; /* End of name if non-NULL; else, see above */ { unsigned hashsum; char *dstp; hashsum = 0; dstp = hierName->hn_name; if (endp) { while (cp < endp) { hashsum = HASHADDVAL(hashsum, *cp); *dstp++ = *cp++; } *dstp = '\0'; } else { while (*dstp++ = *cp) hashsum = HASHADDVAL(hashsum, *cp++); } hierName->hn_hash = hashsum; } /* * ---------------------------------------------------------------------------- * * efHNCompare -- * * Compare two HierNames for equality. Passed as a client procedure * to the hash module. The most likely place for a difference in the * two names is in the lowest-level component, which fortunately is * the first in a HierName list. * * Results: * Returns 0 if they are equal, 1 if not. * * efHNHash -- * * Convert a HierName to a single 32-bit value suitable for being * turned into a hash bucket by the hash module. Passed as a client * procedure to the hash module. * * Results: * Returns the 32-bit hash value. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ int efHNCompare(hierName1, hierName2) HierName *hierName1, *hierName2; { while (hierName1) { if (hierName1 == hierName2) return 0; if (hierName2 == NULL || hierName1->hn_hash != hierName2->hn_hash || strcmp(hierName1->hn_name, hierName2->hn_name) != 0) return 1; hierName1 = hierName1->hn_parent; hierName2 = hierName2->hn_parent; } return (hierName2 ? 1 : 0); } int efHNHash(hierName) HierName *hierName; { int n; for (n = 0; hierName; hierName = hierName->hn_parent) n += hierName->hn_hash; return n; } /* * ---------------------------------------------------------------------------- * * efHNDistCompare -- * efHNDistCopy -- * efHNDistHash -- * efHNDistKill -- * * Procedures for managing a HashTable whose keys are pointers * to malloc'd Distance structures. Distances point to a pair of * HierNames; the comparison and hashing functions rely directly * on those for processing HierNames (efHNCompare() and efHNHash()). * * Results: * efHNDistCompare returns 0 if the two keys are equal, 1 if not. * efHNDistCopy returns a pointer to a malloc'd copy of its Distance * argument. * efHNDistHash returns a single 32-bit hash value based on a Distance's * two HierNames. * efHNDistKill has no return value. * * Side effects: * efHNDistKill frees its Distance argument, and adds the HierNames * pointed to by it to the table of HierNames to free. * * ---------------------------------------------------------------------------- */ bool efHNDistCompare(dist1, dist2) Distance *dist1, *dist2; { return ((bool)(efHNCompare(dist1->dist_1, dist2->dist_1) || efHNCompare(dist1->dist_2, dist2->dist_2) )); } char * efHNDistCopy(dist) Distance *dist; { Distance *distNew; distNew = (Distance *) mallocMagic ((unsigned)(sizeof (Distance))); *distNew = *dist; return (char *) distNew; } int efHNDistHash(dist) Distance *dist; { return efHNHash(dist->dist_1) + efHNHash(dist->dist_2); } void efHNDistKill(dist) Distance *dist; { HierName *hn; for (hn = dist->dist_1; hn; hn = hn->hn_parent) (void) HashFind(&efFreeHashTable, (char *) hn); for (hn = dist->dist_2; hn; hn = hn->hn_parent) (void) HashFind(&efFreeHashTable, (char *) hn); freeMagic((char *) dist); } /* * ---------------------------------------------------------------------------- * * efHNBuildDistKey -- * * Build the key for looking in the Distance hash table for efFlatDists() * above. * * Results: * None. * * Side effects: * Sets up *distKey. * * ---------------------------------------------------------------------------- */ void efHNBuildDistKey(prefix, dist, distKey) HierName *prefix; Distance *dist; Distance *distKey; { HierName *hn1, *hn2; hn1 = EFHNConcat(prefix, dist->dist_1); hn2 = EFHNConcat(prefix, dist->dist_2); if (EFHNBest(hn1, hn2)) { distKey->dist_1 = hn1; distKey->dist_2 = hn2; } else { distKey->dist_1 = hn2; distKey->dist_2 = hn1; } distKey->dist_min = dist->dist_min; distKey->dist_max = dist->dist_max; } /* * ---------------------------------------------------------------------------- * * efHNDump -- * * Print all the names in the node hash table efNodeHashTable. * Used for debugging. * * Results: * None. * * Side effects: * Creates a file "hash.dump" and writes the node names to * it, one per line. * * ---------------------------------------------------------------------------- */ void efHNDump() { HashSearch hs; HashEntry *he; FILE *f; f = fopen("hash.dump", "w"); if (f == NULL) { perror("hash.dump"); return; } HashStartSearch(&hs); while (he = HashNext(&efNodeHashTable, &hs)) fprintf(f, "%s\n", EFHNToStr((HierName *) he->h_key.h_ptr)); (void) fclose(f); } int efHNSizes[4]; void efHNRecord(size, type) int size; int type; { efHNSizes[type] += size; } void efHNPrintSizes(when) char *when; { int total, i; total = 0; for (i = 0; i < 4; i++) total += efHNSizes[i]; printf("Memory used in HierNames %s:\n", when ? when : ""); printf("%8d bytes for global names\n", efHNSizes[HN_GLOBAL]); printf("%8d bytes for concatenated HierNames\n", efHNSizes[HN_CONCAT]); printf("%8d bytes for names from cell uses\n", efHNSizes[HN_FROMUSE]); printf("%8d bytes for names from strings\n", efHNSizes[HN_ALLOC]); printf("--------\n"); printf("%8d bytes total\n", total); } magic-8.0.210/extflat/extflat.h0000664000175000001440000002775612400422506014757 0ustar timusers/* * extflat.h -- * * Internal definitions for the procedures to flatten hierarchical * (.ext) circuit extraction files. * * ********************************************************************* * * 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. * * ********************************************************************* * * rcsid $Header: /usr/cvsroot/magic-8.0/extflat/extflat.h,v 1.2 2008/12/03 14:12:09 tim Exp $ */ #ifndef _EXTFLAT_H #define _EXTFLAT_H #include "utils/magic.h" typedef unsigned char U_char; /* * Arguments to EFFlatBuild(). */ #define EF_FLATNODES 0x01 /* Flatten nodes */ #define EF_FLATCAPS 0x02 /* Flatten capacitors */ #define EF_FLATRESISTS 0x04 /* Flatten resistors */ #define EF_FLATDISTS 0x08 /* Flatten distances */ #define EF_NOFLATSUBCKT 0x10 /* Don't flatten standard cells */ /* Flags to control output of node names. Stored in EFTrimFlags */ #define EF_TRIMGLOB 0x01 /* Delete trailing '!' from names */ #define EF_TRIMLOCAL 0x02 /* Delete trailing '#' from names */ #define EF_CONVERTCOMMAS 0x04 /* Change ',' to ';' in names */ #define EF_CONVERTEQUAL 0x08 /* Change '=' to ':' in names */ /* * capacitance type now set to float */ typedef float EFCapValue; /* ------------------------ Hierarchical names ------------------------ */ /* * One of the biggest consumers of memory space when flattening a circuit * are the full hierarchical names of all nodes. Most of this space is * wasted since it's redundant. Also, a lot of time is spent comparing * long names whose initial components are identical. * * The following structure allows hierarchical names to be represented * with sharing. Names are represented as a sequence of components, * from the lowest level of the hierarchy pointing back toward the root. * Hence, comparisons are likely to detect differences between names * early on. Second, many children can share the same parent, so * storage space should be comparable to that needed for an unflattened * hierarchy (with arrays flattened, however). */ typedef struct hiername { struct hiername *hn_parent; /* Back-pointer toward root */ int hn_hash; /* For speed in hashing */ char hn_name[4]; /* String is allocated here */ } HierName; /* * Size of a HierName big enough to hold a string containing * n bytes (not including the NULL byte). */ #define HIERNAMESIZE(n) ((n) + sizeof (HierName) - 3) /* Indicates where the HierName was allocated: passed to EFHNFree() */ #define HN_ALLOC 0 /* Normal name (FromStr) */ #define HN_CONCAT 1 /* Concatenation of two HierNames */ #define HN_GLOBAL 2 /* Global name */ #define HN_FROMUSE 3 /* From a cell use */ /* ----------------------- Node attribute lists ----------------------- */ typedef struct efattr { struct efattr *efa_next; /* Next in list */ Rect efa_loc; /* Location of attr label */ int efa_type; /* Tile type attr attached to */ char efa_text[4]; /* String is allocated here */ } EFAttr; /* * Size of an EFAttr big enough to hold a string containing * n bytes (not including the NULL byte). */ #define ATTRSIZE(n) ((n) + sizeof (EFAttr) - 3) /* ------------------- Hierarchical and flat nodes -------------------- */ /* * Each entry in the a nodename hash table points to a EFNodeName. * Several EFNodeNames may point to the same EFNode. Such EFNodeNames * are linked into a NULL-terminated list by the name_next pointers. * The first name in this list, pointed to by the efnode_name field of * the EFNode they all point to, is the canonical name for this node. * * The name_hier field points to the HierName for this node, which * will have only a single component for EFNodes within a Def, but * multiple components for hierarchical node names. */ typedef struct efnn { struct efnode *efnn_node; /* Corresponding node */ struct efnn *efnn_next; /* Next name for this node */ HierName *efnn_hier; /* HierName for this node */ int efnn_port; /* Port number for this node */ } EFNodeName; /* * Both hierarchical and flat nodes use the same structure. Hierarchical * nodes appear along with each cell def. Flat nodes are pointed to by * the global hash table. * * Hierarchical nodes are linked in a doubly-linked list with all * other nodes in the same cell, and flat nodes are similarly linked * with all other flat nodes in the circuit. The list is doubly * linked to allow nodes to be deleted easily when it is necessary * to merge two nodes into a single node. * * There is a third way in which a node can exist if only its name is * of interest, namely as an EFNodeHdr. The first part of an EFNode * is an EFNodeHdr. */ /* Represents perimeter and area for a resistance class */ typedef struct { int pa_area; int pa_perim; } PerimArea; typedef struct efnhdr { int efnhdr_flags; /* See below */ EFNodeName *efnhdr_name; /* Canonical name for this node, this is a ptr * to the first element in a null-terminated * list of all the EFNodeNames for this node. */ struct efnhdr *efnhdr_next; /* Next node in list */ struct efnhdr *efnhdr_prev; /* Previous node in list */ } EFNodeHdr; /* Node flags */ /* * If set, this node was killed and neither it nor anything connected * to it should be output. There should have been a new, identical * structure in the input that was connected to the new node. */ #define EF_KILLED 0x01 /* * If set, this node was allocated as a substrate terminal for a * dev, and so should be automatically merged with nodes of the * same name after all nodes have been flattened, rather than * complaining about it being unconnected. */ #define EF_DEVTERM 0x02 /* * This can be used as a general-purpose flag. It is used by * the LEF module to indicate that a node is a "special" net. */ #define EF_SPECIAL 0x04 /* * If set, this node is a subcircuit port and should be treated * accordingly when writing netlist output. The port number is * encoded in the efNodeName structure, since there may be * multiple ports per node (for example, a thru route). */ #define EF_PORT 0x08 /* * This is used when a node is a substrate node with a local * node name, making it an implicitly-defined port. It differs * from EF_DEVTERM in that EF_DEVTERM includes global substrate * nodes, which are not declared ports. */ #define EF_SUBS_PORT 0x10 extern int efNumResistClasses; /* Number of resistance classes in efResists */ typedef struct efnode { EFNodeHdr efnode_hdr; /* See above */ #define efnode_name efnode_hdr.efnhdr_name #define efnode_next efnode_hdr.efnhdr_next #define efnode_prev efnode_hdr.efnhdr_prev #define efnode_flags efnode_hdr.efnhdr_flags EFCapValue efnode_cap; /* Total capacitance to ground for this node */ int efnode_type; /* Index into type table for node */ Rect efnode_loc; /* Location of a 1x1 rect contained in this * node. This information is provided in the * .ext file so it will be easy to map between * node names and locations. */ EFAttr *efnode_attrs; /* Node attribute list */ ClientData efnode_client; /* For hire */ PerimArea efnode_pa[1]; /* Dummy; each node actually has * efNumResistClasses array elements * allocated to it. */ } EFNode; /* -------------------------- Devices ----------------------------- */ /* * Each device can contain several terminals. * Each terminal is described by the following structure. * We use a EFNode pointer for the terminal to which a device connects; * this assumes that devices appear after all the nodes for a cell. */ typedef struct devterm { EFNode *dterm_node; /* Node to which we're connected */ char *dterm_attrs; /* Attribute list */ int dterm_length; /* Length of terminal connection to gate */ int dterm_perim; /* Terminal perimeter if passed as a param */ int dterm_area; /* Terminal area if passed as a param */ } DevTerm; /* * Device itself. * The dev_substrate and dev_type pointers are actually pointer into shared * tables of names, rather than being individually allocated for each * transistor. */ typedef struct parm { char parm_type[2]; char *parm_name; double parm_scale; struct parm *parm_next; } DevParam; typedef struct dev { struct dev *dev_next; /* Next device in def */ U_char dev_class; /* Device class (see extract/extract.h) */ U_char dev_type; /* Index into device type table */ U_char dev_nterm; /* Number of terminals in device */ EFNode *dev_subsnode; /* Substrate node */ Rect dev_rect; /* 1x1 rectangle inside device */ /* Most device types use only one or two of these, but subcircuits */ /* may keep all values to pass along as parameters. */ float dev_cap; /* Capacitance for class "cap" or subckt */ float dev_res; /* Resistance for class "res" or subckt */ int dev_area; int dev_perim; int dev_length; int dev_width; DevParam *dev_params; /* List of subcircuit parameters to output */ DevTerm dev_terms[1]; /* Terminals. The actual number will depend * on dev_nterm above, so the size of this * structure will vary. */ } Dev; /* Size of a Dev structure for 'n' terminals (including the "gate") */ #define DevSize(n) (sizeof (Dev) + ((n)-1)*sizeof (DevTerm)) /* -------------------------------------------------------------------- */ /* * A big number, used for thresholds for capacitance and resistance * when no processing is desired. */ #define INFINITE_THRESHOLD (((unsigned int) (~0)) >> 1) /* Max filename length */ #define FNSIZE 1024 extern float EFScale; /* Scale factor to multiply all coords by */ extern char *EFTech; /* Technology of extracted circuit */ extern char *EFStyle; /* Extraction style of extracted circuit */ extern char *EFSearchPath; /* Path to search for .ext files */ extern char *EFLibPath; /* Library search path */ extern char *EFVersion; /* Version of extractor we work with */ extern char *EFArgTech; /* Tech file given as command line argument */ /* * Thresholds used by various extflat clients to filter out * unwanted resistors and capacitors. Resistance is in milliohms, * capacitance in attofarads. */ extern int EFResistThreshold; extern EFCapValue EFCapThreshold; /* Table of transistor types */ extern char *EFDevTypes[]; extern int EFDevNumTypes; /* Table of Magic layers */ extern char *EFLayerNames[]; extern int EFLayerNumNames; /* Output control flags */ extern int EFTrimFlags; /* -------------------------- Exported procedures --------------------- */ extern char *EFArgs(); /* HierName manipulation */ extern HashEntry *EFHNLook(); extern HashEntry *EFHNConcatLook(); extern HierName *EFHNConcat(); extern HierName *EFStrToHN(); extern char *EFHNToStr(); extern int EFGetPortMax(); /* ------------------------- constants used by clients -------------- */ /* This gives us a 32 or 64 dev types which should be ok */ #define BITSPERCHAR 8 #define MAXDEVTYPES (sizeof(long)*BITSPERCHAR) /* * ANSI C definitions of arguments to EFvisit procedures */ /* - left for documentation purposes typedef int (*capproc)(HierName *, HierName *, double, ClientData ); extern int EFVisitCaps(capproc, ClientData ); typedef int (*nodeproc)(EFNode *, int , double, ClientData ); extern int EFVisitNodes(nodeproc , ClientData ); extern int EFReadFile(char *); */ #endif /* _EXTFLAT_H */ magic-8.0.210/extflat/EFbuild.c0000664000175000001440000012775112404142456014620 0ustar timusers/* * EFbuild.c - * * Procedures for building up the hierarchical representation * of a circuit. These are all called from efReadDef() in EFread.c. * * ********************************************************************* * * 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/extflat/EFbuild.c,v 1.6 2010/06/24 12:37:17 tim Exp $"; #endif /* not lint */ #include #include /* for atof() */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/hash.h" #include "utils/utils.h" #include "utils/malloc.h" #include "extflat/extflat.h" #include "extflat/EFint.h" #include "extract/extract.h" /* for device class list */ /* * To avoid allocating ridiculously large amounts of memory to hold * transistor types and the names of node types, we maintain the following * string tables. Each string (transistor type or Magic layername) appears * exactly once in its respective table; each Dev structure's dev_type field * is an index into EFDevTypes[], and each node layer name an index into * EFLayerNames[]. */ /* The following are ridiculously high */ #define MAXTYPES 100 /* Table of transistor types */ char *EFDevTypes[MAXDEVTYPES]; int EFDevNumTypes; /* Table of Magic layers */ char *EFLayerNames[MAXTYPES] = { "space" }; int EFLayerNumNames; /* Forward declarations */ Connection *efAllocConn(); EFNode *efBuildDevNode(); void efNodeAddName(); void efNodeMerge(); bool efConnBuildName(); bool efConnInitSubs(); /* * ---------------------------------------------------------------------------- * * efBuildNode -- * * Process a "node" line from a .ext file. * Creates a new node with an initial name of 'nodeName' * and capacitance to substrate 'nodeCap'. If there is * already a node by the name of 'nodeName', adds 'nodeCap' * to its existing capacitance. * * In addition, the arguments 'av' and 'ac' are an (argv, argc) * vector of pairs of perimeters and areas for each of the * resist classes; these are either stored in the newly created * node, or added to the values already stored in an existing one. * * Results: * None. * * Side effects: * Updates the HashTable and node list of 'def'. * * EFNode tables: * Each hash table of nodes is organized in the following way. * This organization is true both for the node tables for each * Def, and for the global table of flattened nodes maintained * in EFflatten.c (although the flattened nodes use the HierName * struct for representing hierarchical names efficiently). * * Each HashEntry points to a EFNodeName struct. The EFNodeName * is a link back to the hash key (a HierName), as well as * a link to the actual EFNode for that name. The EFNode points * to the first EFNodeName in the NULL-terminated list of all * EFNodeNames pointing to that EFNode; the intent is that this * first EFNodeName is the "official" or highest-precedence * name for the node. * * The nodes themselves are linked into a circular, doubly * linked list, for ease in merging two nodes into a single * one as a result of a "connect" statement. * * HashEntries EFNodeNames EFNodes * * +---------------+ * | | * V | to from * +-------+ +-------+ | prev prev * | | ----> | |-+ | ^ | * +-------+ +-------+ | | | | * | | | | V * V | +---------------+ * +-------+ +-------+ +---> | | * | | ----> | | ----> | | * +-------+ +-------+ +---> | | * | | +---------------+ * V | ^ | * +-------+ +-------+ | | | * | | ----> | |-+ | V * +-------+ +-------+ from to * | next next * V * NIL * * ---------------------------------------------------------------------------- */ void efBuildNode(def, nodeName, nodeCap, x, y, layerName, av, ac) Def *def; /* Def to which this connection is to be added */ char *nodeName; /* One of the names for this node */ double nodeCap; /* Capacitance of this node to ground */ int x; int y; /* Location of a point inside this node */ char *layerName; /* Name of tile type */ char **av; /* Pairs of area, perimeter strings */ int ac; /* Number of strings in av */ { EFNodeName *newname; EFNode *newnode; HashEntry *he; unsigned size; int n; he = HashFind(&def->def_nodes, nodeName); if (newname = (EFNodeName *) HashGetValue(he)) { if (efWarn) efReadError("Warning: duplicate node name %s\n", nodeName); /* Just add to C, perim, area of existing node */ newnode = newname->efnn_node; newnode->efnode_cap += (EFCapValue) nodeCap; for (n = 0; n < efNumResistClasses && ac > 1; n++, ac -= 2) { newnode->efnode_pa[n].pa_area += atoi(*av++); newnode->efnode_pa[n].pa_perim += atoi(*av++); } return; } /* Allocate a new node with 'nodeName' as its single name */ newname = (EFNodeName *) mallocMagic((unsigned)(sizeof (EFNodeName))); newname->efnn_hier = EFStrToHN((HierName *) NULL, nodeName); newname->efnn_port = -1; /* No port assignment */ newname->efnn_next = NULL; HashSetValue(he, (char *) newname); /* New node itself */ size = sizeof (EFNode) + (efNumResistClasses - 1) * sizeof (PerimArea); newnode = (EFNode *) mallocMagic((unsigned)(size)); newnode->efnode_flags = 0; newnode->efnode_cap = nodeCap; newnode->efnode_attrs = (EFAttr *) NULL; newnode->efnode_loc.r_xbot = x; newnode->efnode_loc.r_ybot = y; newnode->efnode_loc.r_xtop = x + 1; newnode->efnode_loc.r_ytop = y + 1; newnode->efnode_client = (ClientData) NULL; if (layerName) newnode->efnode_type = efBuildAddStr(EFLayerNames, &EFLayerNumNames, MAXTYPES, layerName); else newnode->efnode_type = 0; for (n = 0; n < efNumResistClasses && ac > 1; n++, ac -= 2) { newnode->efnode_pa[n].pa_area = atoi(*av++); newnode->efnode_pa[n].pa_perim = atoi(*av++); } for ( ; n < efNumResistClasses; n++) newnode->efnode_pa[n].pa_area = newnode->efnode_pa[n].pa_perim = 0; /* Update back pointers */ newnode->efnode_name = newname; newname->efnn_node = newnode; /* Link the node into the list for this def */ newnode->efnode_next = def->def_firstn.efnode_next; newnode->efnode_prev = (EFNodeHdr *) &def->def_firstn; def->def_firstn.efnode_next->efnhdr_prev = (EFNodeHdr *) newnode; def->def_firstn.efnode_next = (EFNodeHdr *) newnode; } /* * ---------------------------------------------------------------------------- * * efBuildAttr -- * * Prepend another node attribute to the list for node 'nodeName'. * The attribute is located at the coordinates given by 'r' and * is on the layer 'layerName'. The text of the attribute is 'text'. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void efBuildAttr(def, nodeName, r, layerName, text) Def *def; char *nodeName; Rect *r; char *layerName; char *text; { HashEntry *he; EFNodeName *nn; EFAttr *ap; int size; he = HashFind(&def->def_nodes, nodeName); if (HashGetValue(he) == NULL) { efReadError("Attribute for nonexistent node %s ignored\n", nodeName); return; } nn = (EFNodeName *) HashGetValue(he); size = ATTRSIZE(strlen(text)); ap = (EFAttr *) mallocMagic((unsigned)(size)); (void) strcpy(ap->efa_text, text); ap->efa_type = efBuildAddStr(EFLayerNames, &EFLayerNumNames, MAXTYPES, layerName); ap->efa_loc = *r; ap->efa_next = nn->efnn_node->efnode_attrs; nn->efnn_node->efnode_attrs = ap; } /* * ---------------------------------------------------------------------------- * * efBuildDist -- * * Process a "dist" line from a .ext file. * Both of the names driver and receiver are pathnames with slashes. * Add a new Distance record to the hash table for Def, or update * an existing Distance record. * * This strategy allows the .ext file to contain several distance * lines for the same pair of points; we do the compression here * rather than requiring it be done during extraction. It's necessary * to do compression at some point before flattening; see the description * in efFlatDists(). * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void efBuildDist(def, driver, receiver, min, max) Def *def; /* Def for which we're adding a new Distance */ char *driver; /* Source terminal */ char *receiver; /* Destination terminal */ int min, max; /* Minimum and maximum acyclic distance from source * to destination. */ { Distance *dist, distKey; HierName *hn1, *hn2; HashEntry *he; hn1 = EFStrToHN((HierName *) NULL, driver); hn2 = EFStrToHN((HierName *) NULL, receiver); distKey.dist_min = min; distKey.dist_max = max; if (EFHNBest(hn1, hn2)) { distKey.dist_1 = hn1; distKey.dist_2 = hn2; } else { distKey.dist_1 = hn2; distKey.dist_2 = hn1; } #ifdef notdef TxError("ADD %s ", EFHNToStr(distKey.dist_1)); TxError("%s ", EFHNToStr(distKey.dist_2)); TxError("%d %d\n", min, max); #endif /* notdef */ he = HashFind(&def->def_dists, (char *) &distKey); if (dist = (Distance *) HashGetValue(he)) { /* * There was already an entry in the table; update it * to reflect new minimum and maximum distances. We * can free the keys since they were already in the * table. */ dist->dist_min = MIN(dist->dist_min, min); dist->dist_max = MAX(dist->dist_max, max); EFHNFree(hn1, (HierName *) NULL, HN_ALLOC); EFHNFree(hn2, (HierName *) NULL, HN_ALLOC); } else { /* * When the key was installed in the hash table, it was * a copy of the Distance 'distKey'. Leave this as the * value of the HashEntry. */ HashSetValue(he, (ClientData) he->h_key.h_ptr); } } /* * ---------------------------------------------------------------------------- * * efBuildKill -- * * Process a "killnode" line from a .ext file. * Prepends a Kill to the list for def. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void efBuildKill(def, name) Def *def; /* Def for which we're adding a new Kill */ char *name; /* Name of node to die */ { Kill *kill; kill = (Kill *) mallocMagic((unsigned)(sizeof (Kill))); kill->kill_name = EFStrToHN((HierName *) NULL, name); kill->kill_next = def->def_kills; def->def_kills = kill; } /* * ---------------------------------------------------------------------------- * * efBuildEquiv -- * * Process an "equiv" line from a .ext file. * One of the names 'nodeName1' or 'nodeName2' should be a name for * an existing node in the def 'def'. We simply prepend this name to * the list of names for that node. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void efBuildEquiv(def, nodeName1, nodeName2) Def *def; /* Def for which we're adding a new node name */ char *nodeName1; /* One of node names to be made equivalent */ char *nodeName2; /* Other name to be made equivalent. One of nodeName1 * or nodeName2 must already be known. */ { EFNodeName *nn1, *nn2; HashEntry *he1, *he2; /* Look up both names in the hash table for this def */ he1 = HashFind(&def->def_nodes, nodeName1); he2 = HashFind(&def->def_nodes, nodeName2); nn1 = (EFNodeName *) HashGetValue(he1); nn2 = (EFNodeName *) HashGetValue(he2); if (nn2 == (EFNodeName *) NULL) { /* Create nodeName1 if it doesn't exist */ if (nn1 == (EFNodeName *) NULL) { if (efWarn) efReadError("Creating new node %s\n", nodeName1); efBuildNode(def, nodeName1, (double)0, 0, 0, (char *) NULL, (char **) NULL, 0); nn1 = (EFNodeName *) HashGetValue(he1); } /* Make nodeName2 be another alias for node1 */ efNodeAddName(nn1->efnn_node, he2, EFStrToHN((HierName *) NULL, nodeName2)); return; } /* If both names exist and are for different nodes, merge them */ if (nn1) { if (nn1->efnn_node != nn2->efnn_node) { if (efWarn) efReadError("Merged nodes %s and %s\n", nodeName1, nodeName2); efNodeMerge(nn1->efnn_node, nn2->efnn_node); } return; } /* Make nodeName1 be another alias for node2 */ efNodeAddName(nn2->efnn_node, he1, EFStrToHN((HierName *) NULL, nodeName1)); } /* * ---------------------------------------------------------------------------- * * * ---------------------------------------------------------------------------- */ DevParam * efGetDeviceParams(name) char *name; { HashEntry *he; DevParam *plist = NULL; he = HashLookOnly(&efDevParamTable, (char *)name); if (he != NULL) plist = (DevParam *)HashGetValue(he); return plist; } /* * ---------------------------------------------------------------------------- * * efBuildDeviceParams -- * * Fill in a device parameter hash table entry from a "parameters" line in * the .ext file. * * ---------------------------------------------------------------------------- */ void efBuildDeviceParams(name, argc, argv) char *name; int argc; char *argv[]; { HashEntry *he; DevParam *plist = NULL, *newparm; char *pptr; int n; he = HashFind(&efDevParamTable, name); plist = (DevParam *)HashGetValue(he); if (plist != NULL) return; /* Already got one! */ /* Parse arguments for each parameter */ for (n = 0; n < argc; n++) { char *mult; pptr = strchr(argv[n], '='); if (pptr == NULL) { efReadError("Bad parameter assignment \"%s\" for device \"%s\"\n", argv[n], name); continue; } newparm = (DevParam *)mallocMagic(sizeof(DevParam)); newparm->parm_type[0] = *argv[n]; if ((pptr - argv[n]) == 1) newparm->parm_type[1] = '\0'; else newparm->parm_type[1] = *(argv[n] + 1); if ((mult = strchr(pptr + 1, '*')) != NULL) { *mult = '\0'; newparm->parm_scale = atof(mult + 1); } else newparm->parm_scale = 1.0; newparm->parm_name = StrDup((char **)NULL, pptr + 1); newparm->parm_next = plist; plist = newparm; } HashSetValue(he, (char *)plist); } /* * ---------------------------------------------------------------------------- * * efBuildDevice -- * * Process a device line from a .ext file. * The number of terminals in the dev is argc/3 (which must be integral). * Each block of 3 strings in argv describes a single terminal; see the * comments below for their interpretation. * * Results: * Returns 0 on success, 1 on failure to parse any terminal's values * * Side effects: * Prepends this dev to the list for the def 'def'. * * ---------------------------------------------------------------------------- */ int efBuildDevice(def, class, type, r, argc, argv) Def *def; /* Def to which this connection is to be added */ char class; /* Class (dev, bjt, etc.) of this device */ char *type; /* Type (name) of this device */ Rect *r; /* Coordinates of 1x1 rectangle entirely inside device */ int argc; /* Size of argv */ char *argv[]; /* Tokens for the rest of the dev line. * The first depend on the type of device. The rest * are taken in groups of 3, one for each terminal. * Each group of 3 consists of the node name to which * the terminal connects, the length of the terminal, * and an attribute list (or the token 0). */ { int n, nterminals, pn; DevTerm *term; Dev *newdev, devtmp; char ptype, *pptr, **av; int argstart = 1; /* start of terminal list in argv[] */ bool hasModel = strcmp(type, "None") ? TRUE : FALSE; int area, perim; /* Total area, perimeter of primary type (i.e., channel) */ char *substrate; /* Name of node to which substrate is connected */ devtmp.dev_subsnode = NULL; devtmp.dev_cap = 0.0; devtmp.dev_res = 0.0; devtmp.dev_area = 0; devtmp.dev_perim = 0; devtmp.dev_length = 0; devtmp.dev_width = 0; switch (class) { case DEV_FET: case DEV_MOSFET: case DEV_ASYMMETRIC: case DEV_BJT: argstart = 3; break; case DEV_DIODE: argstart = 0; break; case DEV_RES: case DEV_CAP: if (hasModel) argstart = 2; break; case DEV_SUBCKT: case DEV_MSUBCKT: case DEV_RSUBCKT: argstart = 0; /* Parse initial arguments for parameters */ while ((pptr = strchr(argv[argstart], '=')) != NULL) { pptr++; switch(*argv[argstart]) { case 'a': if ((pptr - argv[argstart]) == 2) devtmp.dev_area = atoi(pptr); else { pn = *(argv[argstart] + 1) - '0'; if (pn == 0) devtmp.dev_area = atoi(pptr); /* Otherwise, punt */ } break; case 'p': if ((pptr - argv[argstart]) == 2) devtmp.dev_perim = atoi(pptr); else { pn = *(argv[argstart] + 1) - '0'; if (pn == 0) devtmp.dev_perim = atoi(pptr); /* Otherwise, punt */ } break; case 'l': devtmp.dev_length = atoi(pptr); break; case 'w': devtmp.dev_width = atoi(pptr); break; case 'c': devtmp.dev_cap = (float)atof(pptr); break; case 'r': devtmp.dev_res = (float)atof(pptr); break; } argstart++; } break; } /* Check for optional substrate node */ switch (class) { case DEV_RES: case DEV_CAP: case DEV_RSUBCKT: case DEV_MSUBCKT: case DEV_SUBCKT: case DEV_DIODE: n = argc - argstart; if ((n % 3) == 1) { if (strncmp(argv[argstart], "None", 4) != 0) devtmp.dev_subsnode = efBuildDevNode(def, argv[argstart], TRUE); argstart++; } break; } /* Between argstart and argc, we should only have terminal triples */ if (((argc - argstart) % 3) != 0) return 1; nterminals = (argc - argstart) / 3; newdev = (Dev *) mallocMagic((unsigned) DevSize(nterminals)); newdev->dev_subsnode = devtmp.dev_subsnode; newdev->dev_cap = devtmp.dev_cap; newdev->dev_res = devtmp.dev_res; newdev->dev_area = devtmp.dev_area; newdev->dev_perim = devtmp.dev_perim; newdev->dev_length = devtmp.dev_length; newdev->dev_width = devtmp.dev_width; newdev->dev_params = NULL; newdev->dev_nterm = nterminals; newdev->dev_rect = *r; newdev->dev_type = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, type); newdev->dev_class = class; switch (class) { case DEV_FET: /* old-style "fet" record */ newdev->dev_area = atoi(argv[0]); newdev->dev_perim = atoi(argv[1]); newdev->dev_subsnode = efBuildDevNode(def, argv[2], TRUE); break; case DEV_MOSFET: /* new-style "device mosfet" record */ case DEV_ASYMMETRIC: case DEV_BJT: newdev->dev_length = atoi(argv[0]); newdev->dev_width = atoi(argv[1]); /* "None" in the place of the substrate name means substrate is ignored */ if ((argstart == 3) && (strncmp(argv[2], "None", 4) != 0)) newdev->dev_subsnode = efBuildDevNode(def, argv[2], TRUE); break; case DEV_RES: if (hasModel && StrIsInt(argv[0]) && StrIsInt(argv[1])) { newdev->dev_length = atoi(argv[0]); newdev->dev_width = atoi(argv[1]); } else if (StrIsNumeric(argv[0])) { newdev->dev_res = (float)atof(argv[0]); } else { if (hasModel) { efReadError("Error: expected L and W, got %s %s\n", argv[0], argv[1]); newdev->dev_length = 0; newdev->dev_width = 0; } else { efReadError("Error: expected resistance value, got %s\n", argv[0]); newdev->dev_res = 0.0; } } if ((argstart == 3) && (strncmp(argv[2], "None", 4) != 0)) newdev->dev_subsnode = efBuildDevNode(def, argv[2], TRUE); break; case DEV_CAP: if (hasModel && StrIsInt(argv[0]) && StrIsInt(argv[1])) { newdev->dev_length = atoi(argv[0]); newdev->dev_width = atoi(argv[1]); } else if (StrIsNumeric(argv[0])) { newdev->dev_cap = (float)atof(argv[0]); } else { if (hasModel) { efReadError("Error: expected L and W, got %s %s\n", argv[0], argv[1]); newdev->dev_length = 0; newdev->dev_width = 0; } else { efReadError("Error: expected capacitance value, got %s\n", argv[0]); newdev->dev_cap = 0.0; } } if ((argstart == 3) && (strncmp(argv[2], "None", 4) != 0)) newdev->dev_subsnode = efBuildDevNode(def, argv[2], TRUE); break; } #define TERM_NAME 0 #define TERM_PERIM 1 #define TERM_ATTRS 2 for (av = &argv[argstart], n = 0; n < nterminals; n++, av += 3) { term = &newdev->dev_terms[n]; term->dterm_node = efBuildDevNode(def, av[TERM_NAME], FALSE); term->dterm_length = atoi(av[TERM_PERIM]); term->dterm_area = 0; term->dterm_perim = 0; /* If the attr list is '0', this signifies no attributes */ if (av[TERM_ATTRS][0] == '0' && av[TERM_ATTRS][1] == '\0') term->dterm_attrs = (char *) NULL; else term->dterm_attrs = StrDup((char **) NULL, av[TERM_ATTRS]); } #undef TERM_NAME #undef TERM_PERIM #undef TERM_ATTRS /* Add this dev to the list for def */ newdev->dev_next = def->def_devs; def->def_devs = newdev; return 0; } /* * ---------------------------------------------------------------------------- * * efBuildPortNode -- * * Look for the node named 'name' in the local table for 'def', or in * the global node name table. If it doesn't already exist, create a * EFNode for it, and set capacitance and area/perimeter to zero. * Set the efnode_flags value to EF_PORT, with the port number encoded * in the efNodeName structure. * * ---------------------------------------------------------------------------- */ void efBuildPortNode(def, name, idx, x, y, layername) Def *def; /* Def to which this connection is to be added */ char *name; /* One of the names for this node */ int idx; /* Port number (order) */ int x; int y; /* Location of a point inside this node */ char *layername; /* Name of tile type */ { HashEntry *he; EFNodeName *nn; he = HashFind(&def->def_nodes, name); nn = (EFNodeName *) HashGetValue(he); if (nn == (EFNodeName *) NULL) { /* Create node if it doesn't already exist */ efBuildNode(def, name, (double)0, x, y, layername, (char **) NULL, 0); nn = (EFNodeName *) HashGetValue(he); } if (nn != (EFNodeName *) NULL) { nn->efnn_node->efnode_flags |= EF_PORT; nn->efnn_port = idx; } } /* * ---------------------------------------------------------------------------- * * EFGetPortMax -- * * Find the highest port number in the cell def and return the value. * * Results: * Value of highest port number in the cell def's node list * * Side effects: * Larger value including the implicit ports is placed in the * location of the pointer imp_max. * * ---------------------------------------------------------------------------- */ int EFGetPortMax(def, imp_max) Def *def; int *imp_max; { EFNode *snode; EFNodeName *nodeName; int portmax, portorder; portmax = -1; if (imp_max) *imp_max = -1; for (snode = (EFNode *) def->def_firstn.efnode_next; snode != &def->def_firstn; snode = (EFNode *) snode->efnode_next) { if (imp_max && (snode->efnode_flags & EF_SUBS_PORT)) { nodeName = snode->efnode_name; portorder = nodeName->efnn_port; if (portorder > (*imp_max)) (*imp_max) = portorder; } else if (snode->efnode_flags & EF_PORT) { for (nodeName = snode->efnode_name; nodeName != NULL; nodeName = nodeName->efnn_next) { portorder = nodeName->efnn_port; if (portorder > portmax) portmax = portorder; } } } return portmax; } /* * ---------------------------------------------------------------------------- * * efBuildDevNode -- * * Look for the node named 'name' in the local table for 'def', or * in the global node name table. If it doesn't already exist, * create a EFNode for it. If 'isSubsNode' is TRUE, this is node * is a substrate node and may not exist yet; otherwise, the node * must already exist. * * Results: * Returns a pointer to the EFNode for 'name'. * * Side effects: * May create a new node, as per above. * * ---------------------------------------------------------------------------- */ EFNode * efBuildDevNode(def, name, isSubsNode) Def *def; char *name; bool isSubsNode; { HashEntry *he; EFNodeName *nn; he = HashFind(&def->def_nodes, name); nn = (EFNodeName *) HashGetValue(he); if (nn == (EFNodeName *) NULL) { /* Create node if it doesn't already exist */ if (efWarn && !isSubsNode) efReadError("Node %s doesn't exist so creating it\n", name); efBuildNode(def, name, (double)0, 0, 0, (char *) NULL, (char **) NULL, 0); nn = (EFNodeName *) HashGetValue(he); if (isSubsNode) { if (!EFHNIsGlob(nn->efnn_hier)) { #ifdef MAGIC_WRAPPER if ((name[0] == '$') && (name[1] != '$')) efReadError("Substrate node is an undefined Tcl variable.\n"); // else #endif // efReadError("Default device substrate node" // " \"%s\" is not a global\n", name); /* This node is declared to be an implicit port */ nn->efnn_node->efnode_flags |= EF_SUBS_PORT; nn->efnn_port = -1; def->def_flags |= DEF_SUBSNODES; } nn->efnn_node->efnode_flags |= EF_DEVTERM; } } return nn->efnn_node; } /* * ---------------------------------------------------------------------------- * * efBuildAddStr -- * * Return the index of 'str' in 'table'. * Add the string 'str' to the table 'table' if it's not already there. * * Results: * See above. * * Side effects: * Increments *pMax if we add an entry to the table. * * ---------------------------------------------------------------------------- */ int efBuildAddStr(table, pMax, size, str) char *table[]; /* Table to search */ int *pMax; /* Increment this if we add an entry */ int size; /* Maximum size of table */ char *str; /* String to add */ { int n, max; max = *pMax; for (n = 0; n < max; n++) if (strcmp(table[n], str) == 0) return n; if (max >= size) { printf("Too many entries in table (max is %d) to add %s\n", size, str); printf("Recompile libextflat.a with a bigger table size\n"); exit (1); } table[n++] = StrDup((char **) NULL, str); *pMax = n; return max; } /* * ---------------------------------------------------------------------------- * * efBuildUse -- * * Process a "use" line from a .ext file. * Creates a new use by the name 'subUseId' of the def named 'subDefName'. * If 'subDefName' doesn't exist, it is created, but left marked as * unavailable so that readfile() will read it in after it is done * with this file. If 'subUseId' ends in an array subscript, e.g, * useid[xlo:xhi:xsep][ylo:yhi:ysep] * its ArrayInfo is filled in from this information; otherwise, its * ArrayInfo is marked as not being needed (xlo == xhi, ylo == yhi). * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void efBuildUse(def, subDefName, subUseId, ta, tb, tc, td, te, tf) Def *def; /* Def to which this connection is to be added */ char *subDefName; /* Def of which this a use */ char *subUseId; /* Use identifier for the def 'subDefName' */ int ta, tb, tc, td, te, tf; /* Elements of a transform from coordinates of * subDefName up to def. */ { Use *newuse; Def *newdef; char *cp; newdef = efDefLook(subDefName); if (newdef == NULL) newdef = efDefNew(subDefName); newuse = (Use *) mallocMagic((unsigned)(sizeof (Use))); newuse->use_def = newdef; newuse->use_trans.t_a = ta; newuse->use_trans.t_b = tb; newuse->use_trans.t_c = tc; newuse->use_trans.t_d = td; newuse->use_trans.t_e = te; newuse->use_trans.t_f = tf; newuse->use_next = def->def_uses; def->def_uses = newuse; /* Set the use identifier and array information */ if ((cp = index(subUseId, '[')) == NULL) { newuse->use_id = StrDup((char **) NULL, subUseId); newuse->use_xlo = newuse->use_xhi = 0; newuse->use_ylo = newuse->use_yhi = 0; newuse->use_xsep = newuse->use_ysep = 0; return; } *cp = '\0'; newuse->use_id = StrDup((char **) NULL, subUseId); *cp = '['; (void) sscanf(cp, "[%d:%d:%d][%d:%d:%d]", &newuse->use_xlo, &newuse->use_xhi, &newuse->use_xsep, &newuse->use_ylo, &newuse->use_yhi, &newuse->use_ysep); } /* * ---------------------------------------------------------------------------- * * efBuildConnect -- * * Process a "connect" line from a .ext file. * Creates a connection record for the names 'nodeName1' and * 'nodeName2'. * * Results: * None. * * Side effects: * Allocates a new connection record, and prepends it to the * list for def. * * ---------------------------------------------------------------------------- */ void efBuildConnect(def, nodeName1, nodeName2, deltaC, av, ac) Def *def; /* Def to which this connection is to be added */ char *nodeName1; /* Name of first node in connection */ char *nodeName2; /* Name of other node in connection */ double deltaC; /* Adjustment in capacitance */ char **av; /* Strings for area, perimeter adjustment */ int ac; /* Number of strings in av */ { int n; Connection *conn; unsigned size = sizeof (Connection) + (efNumResistClasses - 1) * sizeof (PerimArea); conn = (Connection *) mallocMagic((unsigned)(size)); if (efConnInitSubs(conn, nodeName1, nodeName2)) { conn->conn_cap = (EFCapValue) deltaC; conn->conn_next = def->def_conns; for (n = 0; n < efNumResistClasses && ac > 1; n++, ac -= 2) { conn->conn_pa[n].pa_area = atoi(*av++); conn->conn_pa[n].pa_perim = atoi(*av++); } for ( ; n < efNumResistClasses; n++) conn->conn_pa[n].pa_area = conn->conn_pa[n].pa_perim = 0; def->def_conns = conn; } } /* * ---------------------------------------------------------------------------- * * efBuildResistor -- * * Process a "resistor" line from a .ext file. * Creates a resistor record for the names 'nodeName1' and * 'nodeName2'. Both 'nodeName1' and 'nodeName2' must be non-NULL. * * Results: * None. * * Side effects: * Allocates a new connection record, and prepends it to the * def_resistors list for def. * * ---------------------------------------------------------------------------- */ void efBuildResistor(def, nodeName1, nodeName2, resistance) Def *def; /* Def to which this connection is to be added */ char *nodeName1; /* Name of first node in resistor */ char *nodeName2; /* Name of second node in resistor */ int resistance; /* Resistor value */ { Connection *conn; conn = (Connection *) mallocMagic((unsigned)(sizeof (Connection))); if (efConnInitSubs(conn, nodeName1, nodeName2)) { conn->conn_res = resistance; conn->conn_next = def->def_resistors; def->def_resistors = conn; } } /* * ---------------------------------------------------------------------------- * * efBuildCap -- * * Process a "cap" line from a .ext file. * Creates a capacitor record for the names 'nodeName1' and * 'nodeName2'. Both 'nodeName1' and 'nodeName2' must be non-NULL. * * Results: * None. * * Side effects: * Allocates a new connection record, and prepends it to the * def_caps list for def. * * ---------------------------------------------------------------------------- */ void efBuildCap(def, nodeName1, nodeName2, cap) Def *def; /* Def to which this connection is to be added */ char *nodeName1; /* Name of first node in capacitor */ char *nodeName2; /* Name of second node in capacitor */ double cap; /* Capacitor value */ { Connection *conn; conn = (Connection *) mallocMagic((unsigned)(sizeof (Connection))); if (efConnInitSubs(conn, nodeName1, nodeName2)) { conn->conn_cap = (EFCapValue) cap; conn->conn_next = def->def_caps; def->def_caps = conn; } } /* * ---------------------------------------------------------------------------- * * efConnInitSubs -- * * Fill in and check the subscript information for the newly allocated * Connection 'conn'. * * Results: * Returns TRUE if successful, FALSE on error. * * Side effects: * Fills in the two ConnNames conn->conn_1 and conn->conn_2. * Frees 'conn' in the event of an error. * * ---------------------------------------------------------------------------- */ bool efConnInitSubs(conn, nodeName1, nodeName2) Connection *conn; char *nodeName1, *nodeName2; { ConnName *c1, *c2; int n; c1 = &conn->conn_1; c2 = &conn->conn_2; if (!efConnBuildName(c1, nodeName1) || !efConnBuildName(c2, nodeName2)) goto bad; if (c1->cn_nsubs != c2->cn_nsubs) { efReadError("Number of subscripts doesn't match\n"); goto bad; } for (n = 0; n < c1->cn_nsubs; n++) { if (c1->cn_subs[n].r_hi - c1->cn_subs[n].r_lo != c2->cn_subs[n].r_hi - c2->cn_subs[n].r_lo) { efReadError("Subscript %d range mismatch\n", n); goto bad; } } return TRUE; bad: if (c1->cn_name) freeMagic((char *) c1->cn_name); if (c2->cn_name) freeMagic((char *) c2->cn_name); freeMagic((char *) conn); return FALSE; } /* * ---------------------------------------------------------------------------- * * efConnBuildName -- * * Fill in the fields of 'cnp' from the string 'name'. * If 'name' contains no trailing subscript ranges (which are * of the form [lo1:hi1] or [lo1:hi1,lo2:hi2], or [lo1:hi1][lo2:hi2] for * compatibility with older versions of Magic), we set cnp->cn_nsubs * to zero and cnp->cn_name to a copy of 'name'. Otherwise, we decode * the subscripts and fill in cnp->cn_subs and cnp->cn_nsubs appropriately. * * Results: * Returns TRUE if successful, FALSE on error. * * Side effects: * Fills in the fields of the ConnName 'cnp'. * * ---------------------------------------------------------------------------- */ bool efConnBuildName(cnp, name) ConnName *cnp; char *name; { char *srcp, *dstp, *cp, *dp; int nsubs; Range *rp; char newname[1024]; char c; cnp->cn_nsubs = 0; if (name == NULL) { cnp->cn_name = NULL; return TRUE; } cp = name; /* Make sure it's an array subscript range before treating it specially */ again: if ((cp = index(cp, '[')) == NULL) { cnp->cn_name = StrDup((char **) NULL, name); return TRUE; } for (dp = cp + 1; *dp && *dp != ':'; dp++) { if (*dp == ']') { cp = dp+1; goto again; } } /* Copy the initial part of the name */ for (srcp = name, dstp = newname; srcp < cp; *dstp++ = *srcp++) /* Nothing */; /* Replace each subscript range with %d */ for (nsubs = 0, rp = cnp->cn_subs; (c = *cp) == '[' || c == ','; nsubs++) { if (nsubs >= MAXSUBS) { efReadError("Too many array subscripts (maximum=2)\n"); return FALSE; } if (sscanf(++cp, "%d:%d", &rp[nsubs].r_lo, &rp[nsubs].r_hi) != 2) { efReadError("Subscript syntax error\n"); return FALSE; } if (rp[nsubs].r_lo > rp[nsubs].r_hi) { efReadError("Backwards subscript range [%d:%d]\n", rp[nsubs].r_lo, rp[nsubs].r_hi); return FALSE; } while (*cp && *cp != ']' && *cp != ',') cp++; if (*cp == ']') cp++; } /* Generate format for sprintf */ *dstp++ = '['; *dstp++ = '%'; *dstp++ = 'd'; if (nsubs == 2) { *dstp++ = ','; *dstp++ = '%'; *dstp++ = 'd'; } *dstp++ = ']'; /* Copy remainder of path */ while (*dstp++ = *cp++) /* Nothing */; cnp->cn_name = StrDup((char **) NULL, newname); cnp->cn_nsubs = nsubs; return TRUE; } /* * ---------------------------------------------------------------------------- * * efNodeAddName -- * * Add a name to the list for 'node'. * We already have a HashEntry for the new name. * The new name is added to the front of the list * for 'node' only if it is higher in precedence * than the name already at the front of the list. * Sets the value of 'he' to be the newly allocated * EFNodeName. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void efNodeAddName(node, he, hn) EFNode *node; HashEntry *he; HierName *hn; { EFNodeName *newnn; EFNodeName *oldnn; newnn = (EFNodeName *) mallocMagic((unsigned)(sizeof (EFNodeName))); newnn->efnn_node = node; newnn->efnn_hier = hn; newnn->efnn_port = -1; HashSetValue(he, (char *) newnn); /* Link in the new name */ oldnn = node->efnode_name; if (oldnn == NULL || EFHNBest(newnn->efnn_hier, oldnn->efnn_hier)) { /* New head of list */ newnn->efnn_next = oldnn; node->efnode_name = newnn; } else { /* Link it in behind the head of the list */ newnn->efnn_next = oldnn->efnn_next; oldnn->efnn_next = newnn; } } /* * ---------------------------------------------------------------------------- * * efNodeMerge -- * * Combine two nodes. The resistances and capacitances are summed. * The attribute lists are appended. The location chosen is the * lower-leftmost, with lowest being considered before leftmost. * The canonical name of the new node is taken to be the highest * precedence among the names for all nodes. * * One of the nodes will no longer be referenced, so we arbitrarily * make this node2 and free its memory. * * Results: * Return 0 if node1 has precedence, 1 if node2 has precedence * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void efNodeMerge(node1, node2) EFNode *node1, *node2; /* Hierarchical nodes */ { EFNodeName *nn, *nnlast; EFAttr *ap; int n; /* Sanity check: ignore if same node */ if (node1 == node2) return; if (efWatchNodes) { if (HashLookOnly(&efWatchTable, (char *) node1->efnode_name->efnn_hier) || (node2->efnode_name && HashLookOnly(&efWatchTable, (char *) node2->efnode_name->efnn_hier))) { printf("\ncombine: %s\n", EFHNToStr(node1->efnode_name->efnn_hier)); printf(" with %s\n\n", node2->efnode_name ? EFHNToStr(node2->efnode_name->efnn_hier) : "(unnamed)"); } } /* Sum capacitances, perimeters, areas */ node1->efnode_cap += node2->efnode_cap; for (n = 0; n < efNumResistClasses; n++) { node1->efnode_pa[n].pa_area += node2->efnode_pa[n].pa_area; node1->efnode_pa[n].pa_perim += node2->efnode_pa[n].pa_perim; } /* Make all EFNodeNames point to node1 */ if (node2->efnode_name) { for (nn = node2->efnode_name; nn; nn = nn->efnn_next) { nnlast = nn; nn->efnn_node = node1; } /* Concatenate list of EFNodeNames, taking into account precedence */ if (EFHNBest(node2->efnode_name->efnn_hier, node1->efnode_name->efnn_hier)) { /* * New official name is that of node2. * The new list of names is: * node2-names, node1-names */ nnlast->efnn_next = node1->efnode_name; node1->efnode_name = node2->efnode_name; /* * Choose the new location only if node2's location is a valid one, * i.e, node2 wasn't created before it was mentioned. This is mainly * to deal with new fets, resistors, and capacitors created by resistance * extraction, which appear with their full hierarchical names in the * .ext file for the root cell. * * This code has been moved up from below so that the original * location and type will be prefered when the original name * is preferred. * * I am purposefully subverting the original specification that * the node refer to the bottom corner of the network. Does * this have any effect on exttosim or exttospice? * * Tim, 6/14/04 */ if (node2->efnode_type > 0) { node1->efnode_loc = node2->efnode_loc; node1->efnode_type = node2->efnode_type; if (node2->efnode_loc.r_ybot < node1->efnode_loc.r_ybot || (node2->efnode_loc.r_ybot == node1->efnode_loc.r_ybot && node2->efnode_loc.r_xbot < node1->efnode_loc.r_xbot)) { // node1->efnode_loc = node2->efnode_loc; // node1->efnode_type = node2->efnode_type; } } } else { /* * Keep old official name. * The new list of names is: * node1-names[0], node2-names, node1-names[1-] */ nnlast->efnn_next = node1->efnode_name->efnn_next; node1->efnode_name->efnn_next = node2->efnode_name; } } /* Merge attribute lists */ if (ap = node2->efnode_attrs) { while (ap->efa_next) ap = ap->efa_next; ap->efa_next = node1->efnode_attrs; node1->efnode_attrs = ap; node2->efnode_attrs = (EFAttr *) NULL; /* Sanity */ } /* Unlink node2 from list for def */ node2->efnode_prev->efnhdr_next = node2->efnode_next; node2->efnode_next->efnhdr_prev = node2->efnode_prev; /* * Only if both nodes were EF_DEVTERM do we keep EF_DEVTERM set * in the resultant node. */ if ((node2->efnode_flags & EF_DEVTERM) == 0) node1->efnode_flags &= ~EF_DEVTERM; /* * If node2 has the EF_PORT flag set but node1 does not, * then copy the port record in the flags to node1. */ if ((node2->efnode_flags & EF_PORT) && !(node1->efnode_flags & EF_PORT)) node1->efnode_flags |= EF_PORT; /* Get rid of node2 */ freeMagic((char *) node2); } /* * ---------------------------------------------------------------------------- * * efFreeNodeTable -- * * Free the EFNodeNames (and the HierNames they point to) pointed to by * the entries in the HashTable 'table'. Each EFNodeName is assumed to * be pointed to by exactly one HashEntry, but each HierName can be * pointed to by many entries (some of which may be in other HashTables). * As a result, the HierNames aren't freed here; instead, an entry is * added to efFreeHashTable for each HierName encountered. Everything * is then freed at the end by EFDone(). * * Results: * None. * * Side effects: * Frees memory. * Adds an entry to hnTable for each HierName. * * ---------------------------------------------------------------------------- */ void efFreeNodeTable(table) HashTable *table; { HashSearch hs; HashEntry *he; HierName *hn; EFNodeName *nn; HashStartSearch(&hs); while (he = HashNext(table, &hs)) if (nn = (EFNodeName *) HashGetValue(he)) { for (hn = nn->efnn_hier; hn; hn = hn->hn_parent) (void) HashFind(&efFreeHashTable, (char *) hn); freeMagic((char *) nn); } } /* * ---------------------------------------------------------------------------- * * efFreeNodeList -- * * Free the circular list of nodes of which 'head' is the head. * Don't free 'head' itself, since it's statically allocated. * * Results: * None. * * Side effects: * Frees memory. * * ---------------------------------------------------------------------------- */ void efFreeNodeList(head) EFNode *head; { EFNode *node; EFAttr *ap; for (node = (EFNode *) head->efnode_next; node != head; node = (EFNode *) node->efnode_next) { for (ap = node->efnode_attrs; ap; ap = ap->efa_next) freeMagic((char *) ap); freeMagic((char *) node); } } /* * ---------------------------------------------------------------------------- * * efFreeConn -- * * Free the Connection *conn. * * Results: * None. * * Side effects: * Frees memory. * * ---------------------------------------------------------------------------- */ void efFreeConn(conn) Connection *conn; { if (conn->conn_name1) freeMagic(conn->conn_name1); if (conn->conn_name2) freeMagic(conn->conn_name2); freeMagic((char *) conn); } magic-8.0.210/extflat/EFhier.c0000664000175000001440000004523012145232231014430 0ustar timusers/* * EFhier.c - * * Procedures for traversing the hierarchical representation * of a circuit. * * ********************************************************************* * * 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/extflat/EFhier.c,v 1.5 2010/12/16 18:59:03 tim Exp $"; #endif /* not lint */ #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/geofast.h" #include "utils/hash.h" #include "utils/malloc.h" #include "utils/utils.h" #include "extflat/extflat.h" #include "extflat/EFint.h" /* * ---------------------------------------------------------------------------- * * efHierSrUses -- * * Visit all the children of hc->hc_use->use_def, keeping the transform * to flat coordinates and the hierarchical path from the root up to date. * For each child, calls the function 'func', which should be of the * following form: * * int * (*func)(hc, cdata) * HierContext *hc; * ClientData cdata; * { * } * * This procedure should return 0 normally, or 1 to abort the search. * * Hierarchical names: * The current hierarchical prefix down to this point is given by the * the HierName pointed to by hc->hc_hierName. To construct a full * hierarchical name from a name local to this def, we prepend a * newly allocated HierName component to hc->hc_hierName. * * Results: * Returns 0 if completed successfully, 1 if aborted. * * Side effects: * Whatever (*func)() does. * * ---------------------------------------------------------------------------- */ int efHierSrUses(hc, func, cdata) HierContext *hc; int (*func)(); ClientData cdata; { int xlo, xhi, ylo, yhi, xbase, ybase, xsep, ysep; HierContext newhc; Transform t; Use *u; for (u = hc->hc_use->use_def->def_uses; u; u = u->use_next) { newhc.hc_use = u; if (!IsArray(u)) { newhc.hc_hierName = efHNFromUse(&newhc, hc->hc_hierName); GeoTransTrans(&u->use_trans, &hc->hc_trans, &newhc.hc_trans); if ((*func)(&newhc, cdata)) return (1); continue; } /* Set up for iterating over all array elements */ if (u->use_xlo <= u->use_xhi) xlo = u->use_xlo, xhi = u->use_xhi, xsep = u->use_xsep; else xlo = u->use_xhi, xhi = u->use_xlo, xsep = -u->use_xsep; if (u->use_ylo <= u->use_yhi) ylo = u->use_ylo, yhi = u->use_yhi, ysep = u->use_ysep; else ylo = u->use_yhi, yhi = u->use_ylo, ysep = -u->use_ysep; GeoTransTrans(&u->use_trans, &hc->hc_trans, &t); for (newhc.hc_x = xlo; newhc.hc_x <= xhi; newhc.hc_x++) for (newhc.hc_y = ylo; newhc.hc_y <= yhi; newhc.hc_y++) { xbase = xsep * (newhc.hc_x - u->use_xlo); ybase = ysep * (newhc.hc_y - u->use_ylo); GeoTransTranslate(xbase, ybase, &t, &newhc.hc_trans); newhc.hc_hierName = efHNFromUse(&newhc, hc->hc_hierName); if ((*func)(&newhc, cdata)) return (1); } } return (0); } /* * ---------------------------------------------------------------------------- * * efHierSrArray -- * * Iterate over the subscripts in the Connection 'conn', deriving the * names conn_name1 and conn_name2 for each such subscript, calling * the supplied procedure for each. * * This procedure should be of the following form: * * (*proc)(hc, name1, name2, conn, cdata) * HierContext *hc; * char *name1; /# Fully-expanded first name #/ * char *name2; /# Fully-expanded 2nd name, or NULL #/ * Connection *conn; * ClientData cdata; * { * } * * The procedure should return 0 normally, or 1 if it wants us to abort. * * Results: * 0 normally, or 1 if we were aborted. * * Side effects: * Whatever those of 'proc' are. * * ---------------------------------------------------------------------------- */ int efHierSrArray(hc, conn, proc, cdata) HierContext *hc; Connection *conn; int (*proc)(); ClientData cdata; { char name1[1024], name2[1024]; int i, j, i1lo, i2lo, j1lo, j2lo; ConnName *c1, *c2; /* * Only handle three cases: * 0 subscripts * 1 subscript * 2 subscripts */ c1 = &conn->conn_1; c2 = &conn->conn_2; switch (c1->cn_nsubs) { case 0: return (*proc)(hc, c1->cn_name, c2->cn_name, conn, cdata); break; case 1: i1lo = c1->cn_subs[0].r_lo, i2lo = c2->cn_subs[0].r_lo; for (i = i1lo; i <= c1->cn_subs[0].r_hi; i++) { (void) sprintf(name1, c1->cn_name, i); if (c2->cn_name) (void) sprintf(name2, c2->cn_name, i - i1lo + i2lo); if ((*proc)(hc, name1, c2->cn_name ? name2 : (char *) NULL, conn, cdata)) return 1; } break; case 2: i1lo = c1->cn_subs[0].r_lo, i2lo = c2->cn_subs[0].r_lo; j1lo = c1->cn_subs[1].r_lo, j2lo = c2->cn_subs[1].r_lo; #ifdef notdef (void) printf("[%d:%d,%d:%d] [%d:%d,%d:%d]\n", i1lo, c1->cn_subs[0].r_hi, j1lo, c1->cn_subs[1].r_hi, i2lo, c2->cn_subs[0].r_hi, j2lo, c2->cn_subs[1].r_hi); #endif /* notdef */ for (i = i1lo; i <= c1->cn_subs[0].r_hi; i++) { for (j = j1lo; j <= c1->cn_subs[1].r_hi; j++) { (void) sprintf(name1, c1->cn_name, i, j); if (c2->cn_name) (void) sprintf(name2, c2->cn_name, i - i1lo + i2lo, j - j1lo + j2lo); if ((*proc)(hc,name1,c2->cn_name ? name2 : (char *) NULL, conn, cdata)) return 1; } } break; default: printf("Can't handle > 2 array subscripts\n"); break; } return 0; } /* * ---------------------------------------------------------------------------- * * EFHierSrDefs --- * * Traverse the cell definition hierarchy, processing each cell once. * For each definition, call func() with client data argument cdata. * If func() is NULL, then traverse the hierarchy and mark all cell * definitions as unprocessed. * * ---------------------------------------------------------------------------- */ int EFHierSrDefs(hc, func, cdata) HierContext *hc; int (*func)(); ClientData cdata; { HierContext newhc; Use *u; if (func == NULL) { if (!(hc->hc_use->use_def->def_flags & DEF_PROCESSED)) return 0; hc->hc_use->use_def->def_flags &= ~DEF_PROCESSED; } else { if (hc->hc_use->use_def->def_flags & DEF_PROCESSED) return 0; hc->hc_use->use_def->def_flags |= DEF_PROCESSED; } for (u = hc->hc_use->use_def->def_uses; u; u = u->use_next) { newhc.hc_use = u; newhc.hc_hierName = NULL; GeoTransTrans(&u->use_trans, &hc->hc_trans, &newhc.hc_trans); if (EFHierSrDefs(&newhc, func, cdata)) return 1; } if (func == NULL) return 0; else return ((*func)(hc, cdata)); } /*----------------------------------------------------------------------*/ /* All the routines below have been copied and modified from EFvisit.c. */ /* They are used for hierarchical output, such as a netlist for LVS. */ /*----------------------------------------------------------------------*/ /* * ---------------------------------------------------------------------------- * * EFHierVisitSubcircuits -- * * Visit all of the "defined" subcircuits in the circuit. * This is meant to provide a generic functionality similar to * the transistor/resistor/capacitor extraction. It assumes that the * end-user has an existing description of the extracted subcircuit, * such as a characterized standard cell, and that magic is not to * attempt an extraction itself, but only to call the predefined * subcircuit, matching nodes to the subcircuit's port list. * * For each def encountered, call the user-supplied procedure * (*subProc)(), which should be of the following form: * * (*subProc)(hc, use, hierName) * HierContext *hc; * bool is_top; * { * } * * The procedure should return 0 normally, or 1 to abort the search. * * Results: * Returns 0 if terminated normally, or 1 if the search * was aborted. * * Side effects: * Whatever (*subProc)() does. * * ---------------------------------------------------------------------------- */ int EFHierVisitSubcircuits(hc, subProc, cdata) HierContext *hc; int (*subProc)(); ClientData cdata; /* unused */ { CallArg ca; int efHierVisitSubcircuits(); /* Forward declaration */ /* For each subcell of the top-level def that is defined as */ /* a subcircuit, call subProc. */ ca.ca_proc = subProc; ca.ca_cdata = (ClientData)hc->hc_use->use_def; /* Save top-level def */ if (efHierSrUses(hc, efHierVisitSubcircuits, (ClientData) &ca)) return 1; return 0; } /* * Procedure to visit recursively all subcircuits in the design. * Does all the work of EFHierVisitSubcircuits() above. * * Results: * Returns 0 to keep efHierSrUses going. * * Side effects: * Calls the client procedure (*ca->ca_proc)(). */ int efHierVisitSubcircuits(hc, ca) HierContext *hc; CallArg *ca; { /* Visit all children of this def */ Def *def = (Def *)ca->ca_cdata; bool is_top = (def == hc->hc_use->use_def) ? TRUE : FALSE; if ((*ca->ca_proc)(hc->hc_use, hc->hc_hierName, is_top)) return 1; else return 0; } /* * ---------------------------------------------------------------------------- * * efHierDevKilled -- * * Check all of the nodes to which the dev 'dev' is connected. * If any of these nodes have been killed, then the dev is also killed. * * Results: * TRUE if the dev is connected to a killed node, FALSE if it's ok. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool efHierDevKilled(hc, dev, prefix) HierContext *hc; Dev *dev; HierName *prefix; { HierName *suffix; HashEntry *he; EFNodeName *nn; int n; Def *def = hc->hc_use->use_def; for (n = 0; n < dev->dev_nterm; n++) { suffix = dev->dev_terms[n].dterm_node->efnode_name->efnn_hier; he = HashFind(&def->def_nodes, EFHNToStr(suffix)); if (he && (nn = (EFNodeName *) HashGetValue(he)) && (nn->efnn_node->efnode_flags & EF_KILLED)) return TRUE; } return FALSE; } /* * ---------------------------------------------------------------------------- * * EFHierVisitDevs -- * * Visit all the devs in the circuit. * For each dev in the circuit, call the user-supplied procedure * (*devProc)(), which should be of the following form: * * (*devProc)(hc, dev, scale, cdata) * HierContext *hc; * Dev *dev; * float scale; * ClientData cdata; * { * } * * The procedure should return 0 normally, or 1 to abort the * search. * * We ensure that no devs connected to killed nodes are passed * to this procedure. * * Results: * Returns 0 if terminated normally, or 1 if the search * was aborted. * * Side effects: * Whatever (*devProc)() does. * * ---------------------------------------------------------------------------- */ int EFHierVisitDevs(hc, devProc, cdata) HierContext *hc; int (*devProc)(); ClientData cdata; { CallArg ca; ca.ca_proc = devProc; ca.ca_cdata = cdata; return efHierVisitDevs(hc, (ClientData) &ca); } /* * Procedure to visit recursively all devs in the design. * Does all the work of EFHierVisitDevs() above. * * Results: * Returns 0 to keep efHierSrUses going. * * Side effects: * Calls the client procedure (*ca->ca_proc)(). */ int efHierVisitDevs(hc, ca) HierContext *hc; CallArg *ca; { Def *def = hc->hc_use->use_def; Dev *dev; float scale; /* * Note that the transform passed does not transform * the scale; where def->def_scale != 1.0, the visited * procedure will have to multiply values by def->def_scale. */ scale = (efScaleChanged && def->def_scale != 1.0) ? def->def_scale : 1.0; /* Visit all devices */ for (dev = def->def_devs; dev; dev = dev->dev_next) { if (efHierDevKilled(hc, dev, hc->hc_hierName)) continue; if ((*ca->ca_proc)(hc, dev, scale, ca->ca_cdata)) return 1; } return 0; } /* * ---------------------------------------------------------------------------- * * efHierVisitSingleResist -- * * Visit a resistor of res->conn_res milliohms between the nodes * 'name1' and 'name2' (text names, not hierarchical names). Don't * process the resistor if either terminal is a killed node. * * Results: * Whatever the user-supplied procedure (*ca->ca_proc)() returns * (type int). * * Side effects: * Calls the user-supplied procedure. * * ---------------------------------------------------------------------------- */ int efHierVisitSingleResist(hc, name1, name2, res, ca) HierContext *hc; /* Contains hierarchical pathname to cell */ char *name1, *name2; /* Names of nodes connecting to resistor */ Connection *res; /* Contains resistance to add */ CallArg *ca; { EFNode *n1, *n2; HashEntry *he; Def *def = hc->hc_use->use_def; if ((he = HashFind(&def->def_nodes, name1)) == NULL) return 0; n1 = ((EFNodeName *) HashGetValue(he))->efnn_node; if (n1->efnode_flags & EF_KILLED) return 0; if ((he = HashFind(&def->def_nodes, name2)) == NULL) return 0; n2 = ((EFNodeName *) HashGetValue(he))->efnn_node; if (n2->efnode_flags & EF_KILLED) return 0; /* Do nothing if the nodes aren't different */ if (n1 == n2) return 0; return (*ca->ca_proc)(hc, n1->efnode_name->efnn_hier, n2->efnode_name->efnn_hier, res->conn_res, ca->ca_cdata); } /* * ---------------------------------------------------------------------------- * * EFHierVisitResists -- * * Visit all the resistors in the circuit. * For each resistor in the circuit, call the user-supplied procedure * (*resProc)(), which should be of the following form, where hn1 and * hn2 are the HierNames of the two nodes connected by the resistor. * * (*resProc)(hn1, hn2, resistance, cdata) * HierName *hn1, *hn2; * int resistance; * ClientData cdata; * { * } * * The procedure should return 0 normally, or 1 to abort the * search. * * We ensure that no resistors connected to killed nodes are passed * to this procedure. * * Results: * Returns 0 if terminated normally, or 1 if the search * was aborted. * * Side effects: * Whatever (*resProc)() does. * * ---------------------------------------------------------------------------- */ int EFHierVisitResists(hc, resProc, cdata) HierContext *hc; int (*resProc)(); ClientData cdata; { CallArg ca; int efHierVisitResists(); /* Forward reference */ ca.ca_proc = resProc; ca.ca_cdata = cdata; return efHierVisitResists(hc, (ClientData) &ca); } /* * Procedure to visit recursively all resistors in the design. * Does all the work of EFHierVisitResists() above. * * Results: * Returns 0 to keep efHierSrUses going. * * Side effects: * Calls the client procedure (*ca->ca_proc)(). */ int efHierVisitResists(hc, ca) HierContext *hc; CallArg *ca; { Def *def = hc->hc_use->use_def; Connection *res; Transform t; int scale; /* Visit all resistors */ for (res = def->def_resistors; res; res = res->conn_next) { /* Special case for speed if no arraying info */ if (res->conn_1.cn_nsubs == 0) { if (efHierVisitSingleResist(hc, res->conn_name1, res->conn_name2, res, ca)) return 1; } else if (efHierSrArray(hc, res, efHierVisitSingleResist, (ClientData) ca)) return 1; } return 0; } /* * ---------------------------------------------------------------------------- * * efHierVisitSingleCap -- * * Visit a capacitor of cap->conn_cap attoFarads between the nodes * 'name1' and 'name2' (text names, not hierarchical names). Don't * process the capacitor if either terminal is a killed node. * * Results: * Whatever the user-supplied procedure (*ca->ca_proc)() returns * (type int). * * Side effects: * Calls the user-supplied procedure. * * ---------------------------------------------------------------------------- */ int efHierVisitSingleCap(hc, name1, name2, cap, ca) HierContext *hc; /* Contains hierarchical pathname to cell */ char *name1, *name2; /* Names of nodes connecting to capacitor */ Connection *cap; /* Contains capacitance to add */ CallArg *ca; { EFNode *n1, *n2; EFNodeName *nn; HashEntry *he; Def *def = hc->hc_use->use_def; if ((he = HashFind(&def->def_nodes, name1)) == NULL) return 0; nn = (EFNodeName *)HashGetValue(he); if (nn == NULL) return 0; n1 = nn->efnn_node; if (n1->efnode_flags & EF_KILLED) return 0; if ((he = HashFind(&def->def_nodes, name2)) == NULL) return 0; nn = (EFNodeName *)HashGetValue(he); if (nn == NULL) return 0; n2 = nn->efnn_node; if (n2->efnode_flags & EF_KILLED) return 0; /* Do nothing if the nodes aren't different */ if (n1 == n2) return 0; return (*ca->ca_proc)(hc, n1->efnode_name->efnn_hier, n2->efnode_name->efnn_hier, cap->conn_cap, ca->ca_cdata); } /* * ---------------------------------------------------------------------------- * * EFHierVisitCaps -- * * Visit all the local capacitance records * Calls the user-provided procedure (*capProc)() * which should be of the following format: * * (*capProc)(hierName1, hierName2, cap, cdata) * HierName *hierName1, *hierName2; * EFCapValue cap; * ClientData cdata; * { * } * * Here cap is the capacitance in attofarads. * * Results: * Returns 1 if the client procedure returned 1; * otherwise returns 0. * * Side effects: * Calls the user-provided procedure (*capProc)(). * * ---------------------------------------------------------------------------- */ int EFHierVisitCaps(hc, capProc, cdata) HierContext *hc; int (*capProc)(); ClientData cdata; { CallArg ca; Def *def = hc->hc_use->use_def; Connection *cap; Transform t; int scale; ca.ca_proc = capProc; ca.ca_cdata = cdata; /* Visit all resistors */ for (cap = def->def_caps; cap; cap = cap->conn_next) { /* Special case for speed if no arraying info */ if (cap->conn_1.cn_nsubs == 0) { if (efHierVisitSingleCap(hc, cap->conn_name1, cap->conn_name2, cap, &ca)) return 1; } else if (efHierSrArray(hc, cap, efHierVisitSingleCap, (ClientData)&ca)) return 1; } return 0; } magic-8.0.210/extflat/EFdef.c0000644000175000001440000001547411115511671014250 0ustar timusers/* * EFdef.c - * * Procedures for managing the database of Defs. * There is a single Def for each .ext file in a hierarchically * extracted circuit. * * ********************************************************************* * * 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/extflat/EFdef.c,v 1.2 2008/12/03 14:12:09 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/hash.h" #include "utils/utils.h" #include "utils/malloc.h" #include "extflat/extflat.h" #include "extflat/EFint.h" /* Initial size of def hash table */ #define INITDEFSIZE 128 /* Initial size of node hash table in each def */ #define INITNODESIZE 32 /* Def hash table itself; maps from def names into pointers to Defs */ HashTable efDefHashTable; /* Hash table used for checking for malloc leaks */ HashTable efFreeHashTable; /* Hash table used for keeping subcircuit parameter names for a device */ HashTable efDevParamTable; /* * ---------------------------------------------------------------------------- * * EFInit -- * * Initialize the hash table of def names and global signal names. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void EFInit() { EFLayerNumNames = 1; EFDevNumTypes = 0; HashInit(&efFreeHashTable, 32, HT_WORDKEYS); HashInit(&efDefHashTable, INITDEFSIZE, 0); HashInit(&efDevParamTable, 8, HT_STRINGKEYS); efSymInit(); } /* * ---------------------------------------------------------------------------- * * EFDone -- * * Overall cleanup. * * Results: * None. * * Side effects: * Eliminates the def and global name hash tables. * If malloc tracing is enabled, also frees everything else we * allocated with malloc. * * ---------------------------------------------------------------------------- */ void EFDone() { Connection *conn; HashSearch hs; HashEntry *he; Kill *kill; Def *def; Use *use; Dev *dev; int n; HashStartSearch(&hs); while (he = HashNext(&efDefHashTable, &hs)) { def = (Def *) HashGetValue(he); freeMagic(def->def_name); efFreeNodeTable(&def->def_nodes); efFreeNodeList(&def->def_firstn); HashKill(&def->def_nodes); HashKill(&def->def_dists); for (use = def->def_uses; use; use = use->use_next) { freeMagic(use->use_id); freeMagic((char *) use); } for (conn = def->def_conns; conn; conn = conn->conn_next) efFreeConn(conn); for (conn = def->def_caps; conn; conn = conn->conn_next) efFreeConn(conn); for (conn = def->def_resistors; conn; conn = conn->conn_next) efFreeConn(conn); for (dev = def->def_devs; dev; dev = dev->dev_next) { for (n = 0; n < (int)dev->dev_nterm; n++) if (dev->dev_terms[n].dterm_attrs) freeMagic((char *) dev->dev_terms[n].dterm_attrs); freeMagic((char *) dev); } for (kill = def->def_kills; kill; kill = kill->kill_next) { freeMagic(kill->kill_name); freeMagic((char *) kill); } freeMagic((char *) def); } /* Misc cleanup */ for (n = 0; n < EFDevNumTypes; n++) freeMagic(EFDevTypes[n]); /* Changed from n = 0 to n = 1; First entry "space" is predefined, */ /* not malloc'd. ---Tim 9/3/02 */ for (n = 1; n < EFLayerNumNames; n++) freeMagic(EFLayerNames[n]); if (EFTech) { freeMagic(EFTech); EFTech = (char *)NULL; } /* Free up all HierNames that were stored in efFreeHashTable */ /* HashStartSearch(&hs); while (he = HashNext(&efFreeHashTable, &hs)) freeMagic(he->h_key.h_ptr); */ /* Free up the parameter name tables for each device */ HashStartSearch(&hs); while (he = HashNext(&efDevParamTable, &hs)) { DevParam *plist = (DevParam *)HashGetValue(he); while (plist != NULL) { freeMagic(plist->parm_name); freeMagic(plist); plist = plist->parm_next; } } HashKill(&efDevParamTable); HashKill(&efFreeHashTable); /* Final cleanup */ HashKill(&efDefHashTable); } /* * ---------------------------------------------------------------------------- * * efDefLook -- * * Look for a def by the given name in the hash table. * If the def doesn't exist, return NULL; otherwise, return * a pointer to the def. * * Results: * Returns a pointer to a def, or NULL if none by that * name exists. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ Def * efDefLook(name) char *name; { HashEntry *he; he = HashLookOnly(&efDefHashTable, name); if (he == (HashEntry*) NULL) return ((Def *) NULL); return ((Def *) HashGetValue(he)); } /* * ---------------------------------------------------------------------------- * * efDefNew -- * * Allocate a new def by the given name. * * Results: * Returns a pointer to a def. * * Side effects: * Allocates a new def and initializes it. * * ---------------------------------------------------------------------------- */ Def * efDefNew(name) char *name; { HashEntry *he; Def *newdef; he = HashFind(&efDefHashTable, name); newdef = (Def *) mallocMagic((unsigned) (sizeof (Def))); HashSetValue(he, (char *) newdef); newdef->def_name = StrDup((char **) NULL, name); newdef->def_flags = 0; newdef->def_scale = 1.0; newdef->def_conns = (Connection *) NULL; newdef->def_caps = (Connection *) NULL; newdef->def_resistors = (Connection *) NULL; newdef->def_devs = (Dev *) NULL; newdef->def_uses = (Use *) NULL; newdef->def_kills = (Kill *) NULL; /* Initialize circular list of nodes */ newdef->def_firstn.efnode_next = (EFNodeHdr *) &newdef->def_firstn; newdef->def_firstn.efnode_prev = (EFNodeHdr *) &newdef->def_firstn; /* Initialize hash table of node names */ HashInit(&newdef->def_nodes, INITNODESIZE, HT_STRINGKEYS); /* Initialize hash table of distances */ HashInitClient(&newdef->def_dists, INITNODESIZE, HT_CLIENTKEYS, efHNDistCompare, efHNDistCopy, efHNDistHash, efHNDistKill); return (newdef); } magic-8.0.210/extflat/EFsym.c0000664000175000001440000001172012276432152014317 0ustar timusers/* * EFsym.c - * * Procedures for managing symbolic names. * Such names are used to assign values to things like transistor dimensions. * When an attribute of the form "ext:what=value" is attached to a fet, the * corresponding quantity 'what' for that fet is set to 'value'. The 'value' * can be symbolic, allowing us to change it during flattening without having * to re-extract. The binding between symbolic names and numeric values is * set up by calls to efSymAdd(). Recognized values of 'what' are: * * w, l * * ********************************************************************* * * 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/extflat/EFsym.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/geofast.h" #include "utils/hash.h" #include "utils/malloc.h" #include "utils/utils.h" #include "extflat/extflat.h" #include "extflat/EFint.h" /* Forward declarations */ bool efSymAdd(); HashTable efSymHash; /* * ---------------------------------------------------------------------------- * * efSymInit -- * * Initialize the hash table 'efSymHash' used for symbolic name assignments. * Called by EFInit(). * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void efSymInit() { HashInit(&efSymHash, 16, HT_STRINGKEYS); } /* * ---------------------------------------------------------------------------- * * efSymAddFile -- * * Read the file 'name' for symbol assignments. Each line of the file * should be of the form name=value. We add each symbol 'name' to efSymHash * with value 'value'. * * Results: * TRUE on success, FALSE on an error in opening 'name'. * * Side effects: * Adds symbols to the hash table. * Complains if we can't open the file or if errors are encountered * while reading it. * * ---------------------------------------------------------------------------- */ bool efSymAddFile(name) char *name; { char line[1024], *cp; int lineNum; FILE *f; f = fopen(name, "r"); if (f == NULL) { perror(name); return FALSE; } for (lineNum = 1; fgets(line, sizeof line, f); lineNum++) { if (cp = index(line, '\n')) *cp = '\0'; if (!efSymAdd(line)) TxError("Error at line %d of %s\n", lineNum, name); } fclose(f); return TRUE; } /* * ---------------------------------------------------------------------------- * * efSymAdd -- * * Given a string of the form name=value, add the symbol 'name' to efSymHash * with value 'value'. * * Results: * TRUE normally, FALSE if the input was malformed or resulted in * assigning a new value to an existing name. * * Side effects: * Adds a symbol to the hash table. * Complains if we have to return FALSE. * * ---------------------------------------------------------------------------- */ bool efSymAdd(str) char *str; { HashEntry *he; char *value; value = index(str, '='); if (value == NULL) { TxError("Missing '=' in symbol assignment\n"); return FALSE; } value++; if (!StrIsInt(value)) { TxError("Symbol value must be numeric; ignoring \"%s\"\n", str); return FALSE; } value[-1] = '\0'; if (he = HashLookOnly(&efSymHash, str)) { TxError("Symbol \"%s\" already defined\n", str); value[-1] = '='; return FALSE; } he = HashFind(&efSymHash, str); value[-1] = '='; HashSetValue(he, (spointertype)atoi(value)); return TRUE; } /* * ---------------------------------------------------------------------------- * * efSymLook -- * * Look up the value of a symbol and store the value in *pValue. * * Results: * TRUE if the symbol was defined, FALSE if not. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ bool efSymLook(name, pValue) char *name; int *pValue; { HashEntry *he; he = HashLookOnly(&efSymHash, name); if (he == NULL) return FALSE; *pValue = (spointertype) HashGetValue(he); return TRUE; } magic-8.0.210/README0000644000175000001440000003627611140467722012354 0ustar timusers1. General Information: --------------------------------- Use your World Wide Web browser to read: http://opencircuitdesign.com/magic/ http://vlsi.csl.cornell.edu/magic/ http://www.research.digital.com/wrl/magic/magic.html Primary documentation is on the opencircuitdesign.com website under the "Documentation" link. The current development versions of magic are maintained by Tim Edwards and the current distribution version is maintained by Rajit Manohar . Please let us know of any problems/bugs you find. Development of versions 7.2 and newer is generously funded by MultiGiG, Inc. 2. Compilation and Installation: --------------------------------- See the file "INSTALL" in this directory. 3. Version 8.0 Release Notes: --------------------------------- As of the release of version 8.0, Version 7.5 is now the new stable distribution, and 8.0 is the development distribution. What's new in 8.0: ------------------ 1) Vector outline fonts with ability to control font, scale, rotation, and offset. Public-license outline fonts provided by the freefont project. 2) New cifoutput operators including "net" and "maxrect", specifically for using with the "cif paint" command. 4. Version 7.5 Release Notes: --------------------------------- Version 7.5 is the development branch. Version 7.5.0 is the same as 7.4.2, which is essentially the same as 7.3.123, plus some documentation updates. Intended development is as follows: What's new in 7.5: ------------------ 1) Use a finely spaced grid for the database, but keep the concept of "lambda" for layout. Keep backwards compatibility, and resolve issues with layout that does not work well on the lambda grid. Implemented in 7.5.1 by allowing a DRC "scalefactor" line, which declares that all DRC rules are in units of (lambda / scalefactor). Rules "in use" are scaled to lambda and rounded to the nearest integer. The original value is retained, however, so that any call to "scalegrid" will recompute the DRC distances based on the current internal grid. Thus, we can define DRC rules in fractional lambda and therefore match vendor DRC rule distances while still maintaining magic's concept of "lambda". This means that users working entirely within magic have scalable CMOS rules, but if a "vendor cell" (3rd party GDS or CIF) is loaded, the DRC rules will be correct with respect to it. 2) Multiple DRC styles allowed in the technology file. 3) Memory-mapped tile allocation using the mmap() function. 4) Layer and cell instance locking 5) Euclidean-distance measure on "cif grow" operator. 6) "cif paint" command to automatically manipulate the database paint using "cifoutput" rulesets. 7) New contact-cut generation algorithm. 8) Added the ability to define and extract MOS devices with asymmetric source and drain. 9) Added extraction devices "rsubcircuit" and "subcircuit" to produce subcircuit records in SPICE output, with a method to define parameters to be passed to the subcircuit. 10) Added resistor corner scaling (i.e., the resistance of a material at a corner can be set as a fraction of the resistance of the same material on a straight path). 11) Updated the interactive maze router, fixing many bugs, and adding many enhancements, including a maze router GUI that can be used to aid in interactively routing an entire netlist, or performing a verification of a netlist against the layout. 12) "gridlimit" keyword in the cifoutput section to prevent magic from generating geometry beyond a specific resolution. 13) Added the ability to specify all units in the extract section in microns, and added a simplified method for specifying standard parasitic capacitance extraction rules. 14) "gds merge true" option to generate polygons in the GDS output instead of tiles. This creates *much* smaller output files at the expense of processing time. 15) New "contact" function to automatically contact two layers at an intersection. See the online release notes for a more thorough list of features. 4. Version 7.4 Release Notes: --------------------------------- Version 7.4 is the new stable distribution version of magic. Apart from changes to the release notes, it is identical to the last revision (123) of development version 7.3. Revisions of 7.4 will be made as necessary to fix bugs in the code. All new additions and major changes will be done to the new development distribution, version 7.5. Therefore there will not be a "What's new in 7.4" section, as there is not supposed to be anything new in version 7.4. 5. Version 7.3 Release Notes: --------------------------------- Magic release 7.3 incorporates a stacked contact model which is, for the most part, backwardly compatible with Magic releases 7.2 and earlier. Information about this developmental release can be found at: http://opencircuitdesign.com/magic/magic7_3.html What's new in 7.3: ------------------ Provided by Tim Edwards (MultiGiG, Inc.): 1) Stacked contact model allowing arbitrary stacking of contact types. 2) A separate "undo/redo" method for network selection, to remove the memory overhead associated with selecting and unselecting large networks. Also removes some time overhead as well, especially when unselecting networks. 3) Much improved "plot pnm" function. 4) Improved transistor and resistor extraction. 5) LEF format reader; improved LEF/DEF input/output handling 6) New style and colormap file formats 7) Vendor GDS read/write capability 8) "wire segment" drawing function 9) Handling of path records in CIF and GDS input 10) Handling of cell scaling in GDS input 11) Pi-network device extraction for resistors 12) Option to write contacts as cell arrays in GDS output 13) New "widespacing" and "maxwidth" DRC algorithms. 14) "polygon" command 15) New cifoutput operator "bloat-all" 16) Backing-store for 24-bit and OpenGL graphics 17) New "pick" tool for interactive selection move and copy 18) New interactive "wire" tool 19) Crosshair 20) New cifoutput operator "slots" 21) New fcntl-based file locking mechanism 22) "angstroms" units supported in cifinput/cifoutput 23) Non-Manhattan device extraction support 24) New "feedback" mechanism 25) Proper support for > 32 planes (up to 64) 26) Fixed array interaction CIF/GDS generation 27) Added executable "magicdnull" for streamlined batch-mode use 28) New method for crash backups, including restore with "magic -r" 29) A number of other technology file additions and enhancements 6. Version 7.2 Release Notes: --------------------------------- Magic release 7.2 incorporates the capability to run magic from the Tcl interpreter with graphics handled by Tk. Instructions for compiling and installing this version are in README.Tcl. Information about this release can be found at: http://opencircuitdesign.com/magic/magic7_2.html What's new in 7.2: ------------------ Provided by Tim Edwards (MultiGiG, Inc., and JHU Applied Physics Lab): 1) Tcl interpreter extension option 2) Cygwin compile option 3) Memory resources cleaned up 4) GUI interface to Tcl version of Magic 5) Readline update to version 4.3 6) OpenGL fixes and refinements 7) Nonmanhattan geometry fixes and extensions 8) Threaded graphics in non-Tcl environments 9) Inductance extraction 10) CIF and GDS input/output support for deep submicron technologies 11) Different internal and lambda grids, including automatic or induced ("scalegrid" command) grid subdivision and expansion. "snap" and "grid" functions and extensions aid layout when lambda and internal units differ. 12) Removed commands "list", "listall", "parent", and "child", replacing them with the more general-purpose "cellname" and "instance" commands. 13) Added command "tech", and re-loadable technologies. 14) Revamped the "dstyle" files and updated the dstyle version 15) Added "element" types for layout annotation. 16) Extended extract section of techfile to include "device" keyword and devices "mosfet", "bjt", "capacitor", and "resistor". New model resistor and mosfet use width/length instead of area/ perimeter. 17) Added 3D rendering window invoked by command "specialopen wind3d", for the Tcl version compiled with OpenGL graphics. 18) Added "height" keyword to tech file for height/thickness values 19) Added "windowname" command for managing multiple wrapper windows under Tcl. 20) Added extraction extension for annular (ring) MOSFETs. 21) Added "widespacing" DRC rule. 22) Added GNU autoconf compile 23) New command "property" for setting key:value pair properties in cell definitions that can be interpreted by other routines (such as LEF/DEF). 24) General-purpose subcircuit method using the "port" command to declare a cell to be a subcircuit and to mark the position and orientation of connections into the subcell. This replaces a method previously built into version 7.2 using a "subcircuit" layer; that method is now considered obsolete. 25) LEF and DEF format readers, LEF format writer. 26) Improved techfile format with asterisk-notation and DRC "surround", "overhang", and "rect_only" statements. 7. Version 7.1 Release Notes: --------------------------------- Magic release 7.1 consolidates all known patches/features to magic version 6.5.x, and contains additional features that have been added since the consolidation. Information about this release is available at the magic web site: http://vlsi.cornell.edu/magic/ What's new in 7.1: ------------------ Provided by Rajit Manohar (Cornell University) (formerly version 7.0): 1) Implementation of "scheme" (a subset of lisp), a powerful method of generating complex functions. 2) Using CVS to facilitate source code development from multiple sites. 3) New commands using scheme: Too many to mention here; see the tutorials in doc/tutscm* for explanations. Functions themselves are defined in ${CAD_ROOT}/magic/scm/*.scm 4) Overhauled the readline interface. See doc/textfiles/readline.txt for details. 5) Changed tons of stuff about the build environment: - the include paths in all files is now canonical. - redid the make process and rewrote all Makefiles. - tons of other small things that hopefully make the build process nicer. 8. Releases prior to version 7: --------------------------------- What's new in 6.5.2: -------------------- Provided by R. Timothy Edwards (Johns Hopkins Applied Physics Laboratory): 1) Support for OpenGL Look at doc/open_gl.txt 2) Minor update to :config for selection of multiple graphics interfaces. 3) Updates to dstyle and cmap files 4) Always do a check to see if there is only one active layout window: There's no need to annoy the user with complaints of "Put the cursor in a layout window" when there is no possibility of confusion about the matter. Provided by Philippe Pouliquen (Johns Hopkins University): 5) "readline" command line editing capability 6) Macro extensions for X11 (see doc/macro_extension.txt) 7) Better handling of filenames on the UNIX command-line (multiple filenames allowed, ".mag" extension not required). 8) New commands: "child", "parent", "down", "xload", "list", "listall", "listtop", "shell", "imacro". 9) Command alterations: "box [+|-][dir]", "select visible", area of box included in "box" command. 10) Updated .magic macro file (source in magic/proto.magic, install in ${CAD_ROOT}/magic/sys/.magic) (see doc/default_macros.txt). What's new in 6.5.1: -------------------- 1) Support for true-color displays (courtesy of Michael Godfrey) Look into doc/hires-color.txt 2) Minor updates in ext2sim, ext2spice What's new in 6.5: ----------------- 1) Bug fixes in the extractor propagation of attributes (SU) 2) New version of ext2sim ext2spice with support for hspice, spice2, and spice3 (SU) 3) Integration of the port to SUN's Solaris OS (MIT) 4) Port to FreeBSD2.x. Thanks to John Wehle (john@jwlab.feith.com) 5) Integration of part of the DEC/WRL code fragments into the drc code. Since the code is not completely trustworthy the fragments are ifdef'd so if need be the drc will behave exactly as the old one. (you just need to change the #define DRC_EXTENSIONS in drc/drc.h to do that). For a description of the extensions look into doc/tutwrl1.ps (DEC/WRL) 6) Integration of some patches in to the CIF code that introduce: (i) A new cif operation squares-grid which generates contacts on grid. (ii) A new cif layer command min-width is added so that generated layers have the correct min drc width when magic expands layers in the hierarchy (like it does with wells). Magic-6.5 crashes if compiled with gcc in Solaris2.x/SunOS5.x (curiously enough it does not have that problem if compiled with Sun's cc compiler). To get around that you need to set the flag -DUSE_SYSTEM_MALLOC flag in misc/DFLAGS after you run make :config. The error has to do with allignment of doubles and an alternative way to get rid of it is to change extract/extractInt.h so that CapValue is float instead of double. Nevertheless the first method is recomended. What's new in 6.4: ------------------ This release, magic 6.4, contains the following modifications: 1) A number of bug fixes from the 6.3 notes. 2) A version numbering facility for tech files. Please add a new section to each tech file after the "tech" section, following this example: version version 2.0.3 description "MOSIS CMOS 0.13u Nano-nano technology." end Older versions of magic will complain about the new section, but no harm will be done. 4) Various comments describing dates and versions, including the above tech file information, are not written to the CIF file. 3) Support for patches and versioning: A new command called "version" lists out the version number and patches that are installed. A header file called patchlevel.h keeps track of a PATCHLEVEL integer and a string in patchlevel.c keeps track of the names of each installed patch. When posting patches to the net please be sure your patch updates variables. See the files for details. 4) Ports to Alpha AXP OSF/1, SGI/IRIX (courtesy of Stefanos Sidiropoulos) and Linux (courtesy of Harold Levy). 5) A change in the extractor algorithm to provide shielding for perimeter capacitances. Also a change in ext2sim to maintain information about the area and perimeter of diffusion and the bulk connection of the fets (written by Stefanos Sidiropoulos). magic-8.0.210/extract/0000755000175000001440000000000012522433012013116 5ustar timusersmagic-8.0.210/extract/ExtPerim.c0000644000175000001440000001333111443234341015025 0ustar timusers/* * ExtPerim.c -- * * Circuit extraction. * Functions for tracing the perimeter of a tile or of a * connected region. * * ********************************************************************* * * 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/extract/ExtPerim.c,v 1.5 2010/09/12 20:32:33 tim Exp $"; #endif /* not lint */ #include #include #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 "utils/stack.h" #include "debug/debug.h" #include "extract/extract.h" #include "extract/extractInt.h" #define POINTEQUAL(p, q) ((p)->p_x == (q)->p_x && (p)->p_y == (q)->p_y) /* * ---------------------------------------------------------------------------- * * extEnumTilePerim -- * * Visit all the tiles along the perimeter of 'tpIn' whose types are in * the mask 'mask'. For each such tile, call the supplied function 'func' * if it is non-null: * * (*func)(bp, cdata) * Boundary *bp; /# bp->b_inside is tpIn, bp->b_outside * # is the tile along the boundary of tpIn, * # and bp->b_segment is the segment of the * # boundary in common. * #/ * ClientData cdata; /# Supplied in call to extEnumTilePerim #/ * { * } * * The value returned by this function is ignored. * * Results: * Returns the total length of the portion of the perimeter of * 'tpIn' that borders tiles whose types are in 'mask'. * * Side effects: * None directly, but applies the client's filter function * to each qualifying segment of the boundary. * * Note: * The width/length calculation method is manhattan-only. So this * routine is pseudo-manhattan. It computes the true non-manhattan * perimeter, but calls the function on the perimeter tiles as if * the whole tile is the transistor type. * * Non-interruptible. * * ---------------------------------------------------------------------------- */ int extEnumTilePerim(tpIn, mask, pNum, func, cdata) Tile *tpIn; TileTypeBitMask mask; /* Note: this is not a pointer */ int pNum; /* Plane of perimeter */ int (*func)(); ClientData cdata; { TileType origType; Tile *tpOut; int perimCorrect; Boundary b; u_char sides = 0; b.b_inside = tpIn; b.b_plane = pNum; perimCorrect = 0; /* Diagonal */ if (IsSplit(tpIn)) { TileType otype = (SplitSide(tpIn)) ? SplitLeftType(tpIn): SplitRightType(tpIn); TileType itype = (SplitSide(tpIn)) ? SplitRightType(tpIn): SplitLeftType(tpIn); origType = TiGetTypeExact(tpIn); if (TTMaskHasType(&mask, otype)) { int width = RIGHT(tpIn) - LEFT(tpIn); int height = TOP(tpIn) - BOTTOM(tpIn); perimCorrect = width * width + height * height; perimCorrect = (int)sqrt((double)perimCorrect); } sides = (SplitSide(tpIn)) ? BD_LEFT : BD_RIGHT; sides |= (SplitSide(tpIn) == SplitDirection(tpIn)) ? BD_BOTTOM : BD_TOP; TiSetBody(tpIn, itype); } else sides = 0; /* Top */ b.b_segment.r_ybot = b.b_segment.r_ytop = TOP(tpIn); b.b_direction = BD_TOP; for (tpOut = RT(tpIn); RIGHT(tpOut) > LEFT(tpIn); tpOut = BL(tpOut)) { if (TTMaskHasType(&mask, TiGetBottomType(tpOut))) { b.b_segment.r_xbot = MAX(LEFT(tpIn), LEFT(tpOut)); b.b_segment.r_xtop = MIN(RIGHT(tpIn), RIGHT(tpOut)); b.b_outside = tpOut; if (sides & BD_TOP) perimCorrect -= BoundaryLength(&b); if (func) (*func)(&b, cdata); } } /* Bottom */ b.b_segment.r_ybot = b.b_segment.r_ytop = BOTTOM(tpIn); b.b_direction = BD_BOTTOM; for (tpOut = LB(tpIn); LEFT(tpOut) < RIGHT(tpIn); tpOut = TR(tpOut)) { if (TTMaskHasType(&mask, TiGetTopType(tpOut))) { b.b_segment.r_xbot = MAX(LEFT(tpIn), LEFT(tpOut)); b.b_segment.r_xtop = MIN(RIGHT(tpIn), RIGHT(tpOut)); b.b_outside = tpOut; if (sides & BD_BOTTOM) perimCorrect -= BoundaryLength(&b); if (func) (*func)(&b, cdata); } } /* Left */ b.b_segment.r_xbot = b.b_segment.r_xtop = LEFT(tpIn); b.b_direction = BD_LEFT; for (tpOut = BL(tpIn); BOTTOM(tpOut) < TOP(tpIn); tpOut = RT(tpOut)) { if (TTMaskHasType(&mask, TiGetRightType(tpOut))) { b.b_segment.r_ybot = MAX(BOTTOM(tpIn), BOTTOM(tpOut)); b.b_segment.r_ytop = MIN(TOP(tpIn), TOP(tpOut)); b.b_outside = tpOut; if (sides & BD_LEFT) perimCorrect -= BoundaryLength(&b); if (func) (*func)(&b, cdata); } } /* Right */ b.b_segment.r_xbot = b.b_segment.r_xtop = RIGHT(tpIn); b.b_direction = BD_RIGHT; for (tpOut = TR(tpIn); TOP(tpOut) > BOTTOM(tpIn); tpOut = LB(tpOut)) { if (TTMaskHasType(&mask, TiGetLeftType(tpOut))) { b.b_segment.r_ybot = MAX(BOTTOM(tpIn), BOTTOM(tpOut)); b.b_segment.r_ytop = MIN(TOP(tpIn), TOP(tpOut)); b.b_outside = tpOut; if (sides & BD_RIGHT) perimCorrect -= BoundaryLength(&b); if (func) (*func)(&b, cdata); } } if (sides != 0) TiSetBody(tpIn, origType); return (perimCorrect); } magic-8.0.210/extract/ExtBasic.c0000664000175000001440000026474712421575324015025 0ustar timusers/* * ExtBasic.c -- * * Circuit extraction. * Flat extraction of a single CellDef. * * ********************************************************************* * * 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 sccsid[] = "@(#)ExtBasic.c 4.13 MAGIC (Berkeley) 12/5/85"; #endif /* not lint */ #include #include #include #include #include "tcltk/tclmagic.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 "utils/malloc.h" #include "textio/textio.h" #include "debug/debug.h" #include "extract/extract.h" #include "extract/extractInt.h" #include "utils/signals.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "utils/styles.h" #include "utils/stack.h" /* These must be in the order of "known devices" in extract.h. */ /* Note: "fet" refers to the original fet type; "mosfet" refers to the */ /* new type. The main difference is that "fet" records area/perimeter */ /* while "mosfet" records length/width. */ /* Also: Note that this table is repeated in extflat/EFread.c when */ /* ext2spice/ext2sim are compiled as separate programs (i.e., non-Tcl) */ #ifdef MAGIC_WRAPPER char *extDevTable[] = {"fet", "mosfet", "asymmetric", "bjt", "devres", "devcap", "diode", "subckt", "rsubckt", "msubckt", NULL}; #endif /* --------------------- Data local to this file ---------------------- */ /* * The following are used to accumulate perimeter and area * on each layer when building up the node list. They are * used to compute the resistance of each node. Each is * indexed by sheet resistivity class. */ int extResistPerim[NT], extResistArea[NT]; /* * The following structure is used in extracting transistors. * * A "terminal" below refers to any port on the transistor that * is not the gate. In most cases, these are the "diffusion" * ports of the transistor. */ #define MAXSD 10 /* Maximum # of terminals per transistor */ typedef struct /* Position of each terminal (below) tile position */ { int pnum; Point pt; } TermTilePos; struct transRec { int tr_nterm; /* Number of terminals */ int tr_gatelen; /* Perimeter of connection to gate */ NodeRegion *tr_gatenode; /* Node region for gate terminal */ NodeRegion *tr_termnode[MAXSD]; /* Node region for each diff terminal */ NodeRegion *tr_subsnode; /* Substrate node */ int tr_termlen[MAXSD]; /* Length of each diff terminal edge, * used for computing L/W for the fet. */ Point tr_termvector[MAXSD]; /* Perimeter traversal vector, used to * find and calculate correct parameters * for annular (ring) devices and other * non-rectangular geometries. */ int tr_perim; /* Total perimeter */ TermTilePos tr_termpos[MAXSD]; /* lowest tile connecting to term */ } extTransRec; typedef struct LB1 { Rect r; /* Boundary segment */ int dir; /* Direction of travel */ struct LB1 *b_next; } LinkedBoundary; LinkedBoundary **extSpecialBounds; /* Linked Boundary List */ /* Structure used for finding substrate connections on implicitly-defined * substrates */ typedef struct TSD1 { bool found; /* Set to 1 if a substrate connection was found */ Rect rtrans; /* Rectangle of device */ Rect rhalo; /* Search halo around device */ NodeRegion *nreg; /* Closest substrate region within halo */ } TransSubsData; #define EDGENULL(r) ((r)->r_xbot > (r)->r_xtop || (r)->r_ybot > (r)->r_ytop) /* Forward declarations */ void extOutputNodes(); int extTransTileFunc(); int extTransPerimFunc(); NodeRegion *extTransFindSubsNode(); int extTransFindSubs(); int extAnnularTileFunc(); int extResistorTileFunc(); int extSpecialPerimFunc(); void extFindDuplicateLabels(); void extOutputTrans(); void extOutputParameters(); void extTransOutTerminal(); void extTransBad(); bool extLabType(); /* * ---------------------------------------------------------------------------- * * extBasic -- * * Extract a single CellDef, and output the result to the * file 'outFile'. * * Results: * Returns a list of Region structs that comprise all * the nodes in 'def'. It is the caller's responsibility * to call ExtResetTile() and ExtFreeLabRegions() to restore * the CellDef to its original state and to free the list * of regions we build up. * * Side effects: * Writes the result of extracting just the paint of * the CellDef 'def' to the output file 'outFile'. * The following kinds of records are output: * * node * equiv * fet * * Interruptible in a limited sense. We will still return a * Region list, but labels may not have been assigned, and * nodes and fets may not have been output. * * ---------------------------------------------------------------------------- */ NodeRegion * extBasic(def, outFile) CellDef *def; /* Cell being extracted */ FILE *outFile; /* Output file */ { NodeRegion *nodeList, *extFindNodes(); bool coupleInitialized = FALSE; TransRegion *transList; HashTable extCoupleHash; /* * Build up a list of the transistor regions for extOutputTrans() * below. We're only interested in pointers from each region to * a tile in that region, not the back pointers from the tiles to * the regions. */ transList = (TransRegion *) ExtFindRegions(def, &TiPlaneRect, &ExtCurStyle->exts_transMask, ExtCurStyle->exts_transConn, extUnInit, extTransFirst, extTransEach); ExtResetTiles(def, extUnInit); /* * Build up a list of the electrical nodes (equipotentials) * for extOutputNodes() below. For this, we definitely want * to leave each tile pointing to its associated Region struct. * Compute resistance and capacitance on the fly. * Use a special-purpose version of ExtFindRegions for speed. */ if (!SigInterruptPending) nodeList = extFindNodes(def, (Rect *) NULL); /* Assign the labels to their associated regions */ if (!SigInterruptPending) ExtLabelRegions(def, ExtCurStyle->exts_nodeConn, &nodeList, &TiPlaneRect); /* * Make sure all geometry with the same label is part of the * same electrical node. */ if (!SigInterruptPending && (ExtDoWarn & EXTWARN_DUP)) extFindDuplicateLabels(def, nodeList); /* * Build up table of coupling capacitances (overlap, sidewall). * This comes before extOutputNodes because we may have to adjust * node capacitances in this step. */ if (!SigInterruptPending && (ExtOptions&EXT_DOCOUPLING)) { coupleInitialized = TRUE; HashInit(&extCoupleHash, 256, HashSize(sizeof (CoupleKey))); extFindCoupling(def, &extCoupleHash, (Rect *) NULL); } /* Output device parameters for any subcircuit devices */ if (!SigInterruptPending) extOutputParameters(def, transList, outFile); /* Output each node, along with its resistance and capacitance to GND */ if (!SigInterruptPending) extOutputNodes(nodeList, outFile); /* Output coupling capacitances */ if (!SigInterruptPending && (ExtOptions&EXT_DOCOUPLING)) extOutputCoupling(&extCoupleHash, outFile); /* Output transistors and connectivity between nodes */ if (!SigInterruptPending) extOutputTrans(def, transList, outFile); /* Clean up */ if (coupleInitialized) extCapHashKill(&extCoupleHash); ExtFreeLabRegions((LabRegion *) transList); return (nodeList); } /* * ---------------------------------------------------------------------------- * * extSetResist -- * * The input to this procedure is a pointer to a NodeRegion. * Its resistance is computed from the area and perimeter stored * in the arrays extResistPerim[] and extResistArea[]. These arrays * are then reset to zero. * * We approximate the resistive region as a collection of rectangles * of width W and length L, one for each set of layers having a different * sheet resistivity. We do so by noting that for a rectangle, * * Area = L * W * Perimeter = 2 * (L + W) * * Solving the two simultaneous equations for L yields the following * quadratic: * * 2 * (L**2) - Perimeter * L + 2 * Area = 0 * * Solving this quadratic for L, the longer dimension, we get * * L = (Perimeter + S) / 4 * * where * * S = sqrt( (Perimeter**2) - 16 * Area ) * * The smaller dimension is W, ie, * * W = (Perimeter - S) / 4 * * The resistance is L / W squares: * * Perimeter + S * R = ------------- * Perimeter - S * * Results: * None. * * Side effects: * See the comments above. * * ---------------------------------------------------------------------------- */ void extSetResist(reg) NodeRegion *reg; { int n, perim, area; float s, fperim, v; for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) { reg->nreg_pa[n].pa_area = area = extResistArea[n]; reg->nreg_pa[n].pa_perim = perim = extResistPerim[n]; if (area > 0 && perim > 0) { v = (double) (perim*perim - 16*area); /* Approximate by one square if v < 0 */ if (v < 0) s = 0; else s = sqrt(v); fperim = (float) perim; reg->nreg_resist += (fperim + s) / (fperim - s) * ExtCurStyle->exts_resistByResistClass[n]; } /* Reset for the next pass */ extResistArea[n] = extResistPerim[n] = 0; } } /* * ---------------------------------------------------------------------------- * * extOutputNodes -- * * The resistance and capacitance of each node have already been * computed, so all we need do is output them. * * Results: * None. * * Side effects: * Writes a number of 'node' and 'equiv' records to the file 'outFile'. * * Interruptible. If SigInterruptPending is detected, we stop outputting * nodes and return. * * ---------------------------------------------------------------------------- */ void extOutputNodes(nodeList, outFile) NodeRegion *nodeList; /* Nodes */ FILE *outFile; /* Output file */ { ResValue rround = ExtCurStyle->exts_resistScale / 2; CapValue finC; int intR; NodeRegion *reg; LabelList *ll; char *cp; int n; Label *lab; char *text; /* If this node is a subcircuit port, it gets special treatment. */ /* There may be multiple ports per node. */ for (reg = nodeList; reg && !SigInterruptPending; reg = reg->nreg_next) for (ll = reg->nreg_labels; ll; ll = ll->ll_next) if (ll->ll_attr == LL_PORTATTR) { fprintf(outFile, "port \"%s\" %d %d %d %d %d %s\n", ll->ll_label->lab_text, ll->ll_label->lab_flags & PORT_NUM_MASK, ll->ll_label->lab_rect.r_xbot, ll->ll_label->lab_rect.r_ybot, ll->ll_label->lab_rect.r_xtop, ll->ll_label->lab_rect.r_ytop, DBTypeShortName(ll->ll_label->lab_type)); /* If the port name matches the node name to be written */ /* to the node record, then reassign the node position */ /* and type to be that of the port, so we don't have a */ /* conflict. */ if (!strcmp(extNodeName((LabRegion *) reg), ll->ll_label->lab_text)) { reg->nreg_ll.p_x = ll->ll_label->lab_rect.r_xbot; reg->nreg_ll.p_y = ll->ll_label->lab_rect.r_ybot; reg->nreg_type = ll->ll_label->lab_type; reg->nreg_pnum = DBPlane(reg->nreg_type); } } for (reg = nodeList; reg && !SigInterruptPending; reg = reg->nreg_next) { /* Output the node */ text = extNodeName((LabRegion *) reg); intR = (reg->nreg_resist + rround) / ExtCurStyle->exts_resistScale; finC = reg->nreg_cap/ExtCurStyle->exts_capScale; fprintf(outFile, "node \"%s\" %d %lg", text, intR, finC); /* Output its location (lower-leftmost point and type name) */ if (reg->nreg_type & TT_DIAGONAL) { /* Node may be recorded as a diagonal tile if no other */ /* non-diagonal tiles are adjoining it. */ TileType loctype = (reg->nreg_type & TT_SIDE) ? ((reg->nreg_type & TT_RIGHTMASK) >> 14) : (reg->nreg_type & TT_LEFTMASK); fprintf(outFile, " %d %d %s", reg->nreg_ll.p_x, reg->nreg_ll.p_y, DBTypeShortName(loctype)); } else { fprintf(outFile, " %d %d %s", reg->nreg_ll.p_x, reg->nreg_ll.p_y, DBTypeShortName(reg->nreg_type)); } /* Output its area and perimeter for each resistivity class */ for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) fprintf(outFile, " %d %d", reg->nreg_pa[n].pa_area, reg->nreg_pa[n].pa_perim); (void) putc('\n', outFile); /* Output its attribute list */ for (ll = reg->nreg_labels; ll; ll = ll->ll_next) if (extLabType(ll->ll_label->lab_text, LABTYPE_NODEATTR)) { /* Don't output the trailing character for node attributes */ lab = ll->ll_label; fprintf(outFile, "attr %s %d %d %d %d %s \"", text, lab->lab_rect.r_xbot, lab->lab_rect.r_ybot, lab->lab_rect.r_xtop, lab->lab_rect.r_ytop, DBTypeShortName(lab->lab_type)); cp = lab->lab_text; n = strlen(cp) - 1; while (n-- > 0) putc(*cp++, outFile); fprintf(outFile, "\"\n"); } /* Output the alternate names for the node */ for (ll = reg->nreg_labels; ll; ll = ll->ll_next) if (ll->ll_label->lab_text == text) { for (ll = ll->ll_next; ll; ll = ll->ll_next) if (extLabType(ll->ll_label->lab_text, LABTYPE_NAME)) fprintf(outFile, "equiv \"%s\" \"%s\"\n", text, ll->ll_label->lab_text); break; } } } /* * ---------------------------------------------------------------------------- * * extFindDuplicateLabels -- * * Verify that no node in the list 'nreg' has a label that appears in * any other node in the list. Leave a warning turd if one is. * * Results: * None. * * Side effects: * Leaves feedback attached to each node that contains a label * duplicated in another node. * * ---------------------------------------------------------------------------- */ void extFindDuplicateLabels(def, nreg) CellDef *def; NodeRegion *nreg; { static char *badmesg = "Label \"%s\" attached to more than one unconnected node: %s"; bool hashInitialized = FALSE; char message[512], name[512], *text; NodeRegion *np, *np2; LabelList *ll, *ll2; HashEntry *he; NodeRegion *lastreg; NodeRegion badLabel; HashTable labelHash; Rect r; for (np = nreg; np; np = np->nreg_next) { for (ll = np->nreg_labels; ll; ll = ll->ll_next) { text = ll->ll_label->lab_text; if (!extLabType(text, LABTYPE_NAME)) continue; if (!hashInitialized) HashInit(&labelHash, 32, 0), hashInitialized = TRUE; he = HashFind(&labelHash, text); lastreg = (NodeRegion *) HashGetValue(he); if (lastreg == (NodeRegion *) NULL) HashSetValue(he, (ClientData) np); else if (lastreg != np && lastreg != &badLabel) { /* * Make a pass through all labels for all nodes. * Leave a feedback turd over each instance of the * offending label. */ for (np2 = nreg; np2; np2 = np2->nreg_next) { for (ll2 = np2->nreg_labels; ll2; ll2 = ll2->ll_next) { if (strcmp(ll2->ll_label->lab_text, text) == 0) { extNumWarnings++; if (!DebugIsSet(extDebugID, extDebNoFeedback)) { r.r_ll = r.r_ur = ll2->ll_label->lab_rect.r_ll; r.r_xbot--, r.r_ybot--, r.r_xtop++, r.r_ytop++; extMakeNodeNumPrint(name, np2->nreg_pnum, np2->nreg_ll); (void) sprintf(message, badmesg, text, name); DBWFeedbackAdd(&r, message, def, 1, STYLE_PALEHIGHLIGHTS); } } } } /* Mark this label as already having generated an error */ HashSetValue(he, (ClientData) &badLabel); } } } if (hashInitialized) HashKill(&labelHash); } /* * ---------------------------------------------------------------------------- * * extNodeName -- * * Given a pointer to a LabRegion, return a pointer to a string * that can be printed as the name of the node. If the LabRegion * has a list of attached labels, use one of the labels; otherwise, * use its node number. * * Results: * Returns a pointer to a string. If the node had a label, this * is a pointer to the lab_text field of the first label on the * label list for the node; otherwise, it is a pointer to a static * buffer into which we have printed the node number. * * Side effects: * May overwrite the static buffer used to hold the printable * version of a node number. * * ---------------------------------------------------------------------------- */ char * extNodeName(node) LabRegion *node; { static char namebuf[100]; /* Big enough to hold a generated nodename */ LabelList *ll; if (node == (LabRegion *) NULL || SigInterruptPending) return ("(none)"); for (ll = node->lreg_labels; ll; ll = ll->ll_next) if (extLabType(ll->ll_label->lab_text, LABTYPE_NAME)) return (ll->ll_label->lab_text); extMakeNodeNumPrint(namebuf, node->lreg_pnum, node->lreg_ll); return (namebuf); } /* * --------------------------------------------------------------------- * * ExtSortTerminals -- * * Sort the terminals of a transistor so that the terminal with the * lowest leftmost coordinate on the plane with the lowest number is * output first. * * Results: * None * * Side effects: * The tr_termnode, tr_termlen, and tr_termpos entries may change. * * --------------------------------------------------------------------- */ void ExtSortTerminals(tran, ll) struct transRec *tran; LabelList *ll; { int nsd, changed; TermTilePos *p1, *p2; NodeRegion *tmp_node; TermTilePos tmp_pos; int tmp_len; LabelList *lp; do { changed = 0; for( nsd = 0; nsd < tran->tr_nterm-1; nsd++ ) { p1 = &(tran->tr_termpos[nsd]); p2 = &(tran->tr_termpos[nsd+1]); if( p2->pnum > p1->pnum ) continue; else if( p2->pnum == p1->pnum ) { if( p2->pt.p_x > p1->pt.p_x ) continue; else if( p2->pt.p_x == p1->pt.p_x && p2->pt.p_y > p1->pt.p_y ) continue; else if( p2->pt.p_x == p1->pt.p_x && p2->pt.p_y == p1->pt.p_y ) { TxPrintf("Extract error: Duplicate tile position, ignoring\n"); continue; } } changed = 1; tmp_node = tran->tr_termnode[nsd]; tmp_pos = tran->tr_termpos[nsd]; tmp_len = tran->tr_termlen[nsd]; tran->tr_termnode[nsd] = tran->tr_termnode[nsd+1]; tran->tr_termpos[nsd] = tran->tr_termpos[nsd+1]; tran->tr_termlen[nsd] = tran->tr_termlen[nsd+1]; tran->tr_termnode[nsd+1] = tmp_node; tran->tr_termpos[nsd+1] = tmp_pos; tran->tr_termlen[nsd+1] = tmp_len; /* Need to SWAP the indices in the labRegion too. * These for loops within the bubblesort in here are kinda slow * but S,D attributes are not that common so it should not matter * that much -- Stefanos 5/96 */ for ( lp = ll ; lp ; lp = lp->ll_next ) if ( lp->ll_attr == nsd ) lp->ll_attr = LL_SORTATTR ; else if ( lp->ll_attr == nsd+1 ) lp->ll_attr = nsd ; for ( lp = ll ; lp ; lp = lp->ll_next ) if ( lp->ll_attr == LL_SORTATTR ) lp->ll_attr = nsd+1; } } while( changed ); } /* *---------------------------------------------------------------------- * * extComputeCapLW -- * * Determine effective length and width of a rectangular capacitor, * based on the boundary vectors stored in extSpecialBounds. This * routine should only be called for capacitors that have exactly * one terminal. * * Results: * None * * Side Effects: * Puts effective length and width into the pointers * passed as arguments. *---------------------------------------------------------------------- */ void extComputeCapLW(rlengthptr, rwidthptr) int *rlengthptr, *rwidthptr; { LinkedBoundary *lb; Rect bbox; /* Quick algorithm---ignore tabs, compute max extents of */ /* the special bounds vector. */ lb = extSpecialBounds[0]; if (lb == NULL) { TxError("extract: Can't get capacitor L and W\n"); return; /* error condition */ } bbox = lb->r; for (lb = extSpecialBounds[0]; lb != NULL; lb = lb->b_next) GeoIncludeAll(&lb->r, &bbox); *rwidthptr = bbox.r_xtop - bbox.r_xbot; *rlengthptr = bbox.r_ytop - bbox.r_ybot; } /* *---------------------------------------------------------------------- * * extComputeEffectiveLW -- * * Determine effective length and width of an annular (or otherwise * non-rectangular) transistor structure, based on the boundary vectors * stored in extSpecialBounds. * * Note that "L" and "W" are reversed when this routine is called * to compute L and W for a resistor. The sense of "length" and * "width" as used in the routine are appropriate for a transistor. * * Also note that this algorithm will tend to over-estimate the width * of transistors with angled bends. This problem would be eliminated * if non-Manhattan geometry were evaluated directly rather than being * first converted to Manhattan geometry. * * Results: * None. * * Side Effects: * Puts effective length and width into the pointers * passed as arguments. *---------------------------------------------------------------------- */ void extComputeEffectiveLW(rlengthptr, rwidthptr, numregions, chop) int *rlengthptr, *rwidthptr; int numregions; float chop; { int i, j, p, jmax; LinkedBoundary *lb, *lb2; int oppdir, length, loclength, testlen, width; int locwidth, testwid, cornerw; int segp, segn, segc, sege; bool isComplex = FALSE; /* First, check for MOScap-connected transistors. In such * cases, one or more extSpecialBounds[] is NULL. Try to * separate the existing extSpecialBounds[] vectors into * independent (non-connecting) vectors. */ /* For each segment in the primary list, find the closest * segment in the other list which lies on the opposite * side of the gate area. Calculate the length, and check * for overlap, treating the length as a corner extension. * * The primary list is chosen as the one with the largest * number of elements. This helps prevent the algorithm from * producing a different result for devices at different * orientations. */ p = 0; jmax = 0; for (i = 0; i < numregions; i++) { j = 0; for (lb = extSpecialBounds[i]; lb != NULL; lb = lb->b_next) j++; if (j > jmax) { jmax = j; p = i; } } /* fprintf(stderr, "Annular transistor detailed L,W computaton:\n"); */ width = 0; length = 0; for (lb = extSpecialBounds[p]; lb != NULL; lb = lb->b_next) { loclength = INFINITY; switch (lb->dir) { case BD_LEFT: oppdir = BD_RIGHT; break; case BD_RIGHT: oppdir = BD_LEFT; break; case BD_TOP: oppdir = BD_BOTTOM; break; case BD_BOTTOM: oppdir = BD_TOP; break; } /* First pass: Find the distance of the closest segment within */ /* the range of its corner extension. We do two passes because */ /* there may be more than one segment at this distance. */ for (i = 0; i < numregions; i++) { if ((i == p) && (i > 1)) continue; for (lb2 = extSpecialBounds[i]; lb2 != NULL; lb2 = lb2->b_next) { if (lb2->dir == oppdir) { switch (lb->dir) { case BD_LEFT: if (lb2->r.r_xbot > lb->r.r_xbot) { testlen = lb2->r.r_xbot - lb->r.r_xbot; if (lb2->r.r_ybot < lb->r.r_ytop + testlen && lb2->r.r_ytop > lb->r.r_ybot - testlen) { /* Adjustments for offset segments */ if (lb2->r.r_ybot > lb->r.r_ytop) testlen += lb2->r.r_ybot - lb->r.r_ytop; else if (lb2->r.r_ytop < lb->r.r_ybot) testlen += lb->r.r_ybot - lb2->r.r_ytop; if (testlen < loclength) loclength = testlen; } } break; case BD_RIGHT: if (lb2->r.r_xtop < lb->r.r_xtop) { testlen = lb->r.r_xtop - lb2->r.r_xtop; if (lb2->r.r_ybot < lb->r.r_ytop + testlen && lb2->r.r_ytop > lb->r.r_ybot - testlen) { /* Adjustments for offset segments */ if (lb2->r.r_ybot > lb->r.r_ytop) testlen += lb2->r.r_ybot - lb->r.r_ytop; else if (lb2->r.r_ytop < lb->r.r_ybot) testlen += lb->r.r_ybot - lb2->r.r_ytop; if (testlen < loclength) loclength = testlen; } } break; case BD_TOP: if (lb2->r.r_ytop < lb->r.r_ytop) { testlen = lb->r.r_ytop - lb2->r.r_ytop; if (lb2->r.r_xbot < lb->r.r_xtop + testlen && lb2->r.r_xtop > lb->r.r_xbot - testlen) { /* Adjustments for offset segments */ if (lb2->r.r_xbot > lb->r.r_xtop) testlen += lb2->r.r_xbot - lb->r.r_xtop; else if (lb2->r.r_xtop < lb->r.r_xbot) testlen += lb->r.r_xbot - lb2->r.r_xtop; if (testlen < loclength) loclength = testlen; } } break; case BD_BOTTOM: if (lb2->r.r_ybot > lb->r.r_ybot) { testlen = lb2->r.r_ybot - lb->r.r_ybot; if (lb2->r.r_xbot < lb->r.r_xtop + testlen && lb2->r.r_xtop > lb->r.r_xbot - testlen) { /* Adjustments for offset segments */ if (lb2->r.r_xbot > lb->r.r_xtop) testlen += lb2->r.r_xbot - lb->r.r_xtop; else if (lb2->r.r_xtop < lb->r.r_xbot) testlen += lb->r.r_xbot - lb2->r.r_xtop; if (testlen < loclength) loclength = testlen; } } break; } } } } /* This segment should not be considered current-carrying; it */ /* only adds to the gate capacitance. Should we output the */ /* extra capacitance somewhere? */ if (loclength == INFINITY) continue; /* Note that the L/W calculation ignores the possibility that a */ /* transistor may have multiple lengths. Such cases should */ /* either 1) scale the width to one of the lengths, or 2) out- */ /* put a separate transistor record for each length. */ if (length == 0) length = loclength; /* Default length */ else if ((length != 0) && (length != loclength)) { /* If the newly computed length is less than the */ /* original, scale the original. Otherwise, scale */ /* the new length. */ if (loclength < length) { width *= loclength; width /= length; length = loclength; } isComplex = TRUE; } /* fprintf(stderr, " segment length = %d\n", loclength); */ /* Second pass: All segments at "length" distance add to the */ /* length and width calculation. Sides opposite and corner */ /* extensions are treated separately. Areas outside the corner */ /* extension are ignored. */ locwidth = 0; cornerw = 0; for (i = 0; i < numregions; i++) { if ((i == p) && (i > 1)) continue; for (lb2 = extSpecialBounds[i]; lb2 != NULL; lb2 = lb2->b_next) { if (lb2->dir == oppdir) { if (((lb->dir == BD_LEFT) && (lb2->r.r_xbot - lb->r.r_xbot == loclength)) || ((lb->dir == BD_RIGHT) && (lb->r.r_xtop - lb2->r.r_xtop == loclength))) { /* opposite */ segp = MIN(lb2->r.r_ytop, lb->r.r_ytop); segn = MAX(lb2->r.r_ybot, lb->r.r_ybot); testwid = segp - segn; if (testwid > 0) locwidth += testwid * 2; if (testwid <= -loclength) continue; /* corner extend top */ segc = MAX(lb2->r.r_ytop, lb->r.r_ytop); sege = MAX(segp, segn); testwid = segc - sege; if (testwid > loclength) testwid = loclength; if (testwid > 0) cornerw += testwid; /* corner extend bottom */ segc = MIN(lb2->r.r_ybot, lb->r.r_ybot); sege = MIN(segp, segn); testwid = sege - segc; if (testwid > loclength) testwid = loclength; if (testwid > 0) cornerw += testwid; } else if (((lb->dir == BD_TOP) && (lb->r.r_ytop - lb2->r.r_ytop == loclength)) || ((lb->dir == BD_BOTTOM) && (lb2->r.r_ybot - lb->r.r_ybot == loclength))) { /* opposite */ segp = MIN(lb2->r.r_xtop, lb->r.r_xtop); segn = MAX(lb2->r.r_xbot, lb->r.r_xbot); testwid = segp - segn; if (testwid > 0) locwidth += testwid * 2; if (testwid <= -loclength) continue; /* corner extend right */ segc = MAX(lb2->r.r_xtop, lb->r.r_xtop); sege = MAX(segp, segn); testwid = segc - sege; if (testwid > loclength) testwid = loclength; if (testwid > 0) cornerw += testwid; /* corner extend left */ segc = MIN(lb2->r.r_xbot, lb->r.r_xbot); sege = MIN(segp, segn); testwid = sege - segc; if (testwid > loclength) testwid = loclength; if (testwid > 0) cornerw += testwid; } } } } /* if (width > 0) fprintf(stderr, " segment width = %d\n", width); */ /* Width scaling for transistor sections with different lengths */ locwidth += (int)(0.5 + ((float)cornerw * chop)); if (loclength != length) { locwidth *= length; locwidth /= loclength; } width += locwidth; } if ((length > 0) && (width > 0)) { *rlengthptr = length; // If numregions == 1 then everything was put in one record, // and we have double-counted the width. if (numregions == 1) *rwidthptr = (width >> 2); else *rwidthptr = (width >> 1); /* fprintf(stderr, "total L = %d, W = %d\n", length, width); */ /* fflush(stderr); */ if (isComplex) TxError("Device has multiple lengths: scaling" " all widths to length %d\n", length); } } /* * ---------------------------------------------------------------------------- * * extSeparateBounds -- * * Because the non-source/drain perimeter is not a node, all the * boundary vectors end up in one record. So we have to pry them * apart. * * Results: * None. * * Side effects: * Messes with the extSpecialBounds[] linked lists. * * ---------------------------------------------------------------------------- */ void extSeparateBounds(nterm) int nterm; /* last terminal (# terminals - 1) */ { Rect lbrect; LinkedBoundary *lb, *lbstart, *lbend, *lblast, *lbnext; bool found; /* Avoid crash condition on a badly-defined extract definition */ if ((nterm < 0) || (extSpecialBounds[0] == NULL)) return; if (extSpecialBounds[nterm] == NULL) { /* Put first record into the unused terminal entry */ extSpecialBounds[nterm] = extSpecialBounds[0]; extSpecialBounds[0] = extSpecialBounds[nterm]->b_next; extSpecialBounds[nterm]->b_next = NULL; /* Add connected segments until no more are found */ lbstart = lbend = extSpecialBounds[nterm]; lbrect = lbstart->r; found = TRUE; while (found == TRUE) { lblast = NULL; found = FALSE; for (lb = extSpecialBounds[0]; lb != NULL; lb = lbnext) { /* perhaps we should cut down on these cases by */ /* checking the direction of the segment. . . */ lbnext = lb->b_next; if (((lb->r.r_xbot == lbrect.r_xbot) && (lb->r.r_ybot == lbrect.r_ybot))) { if (lblast == NULL) extSpecialBounds[0] = lb->b_next; else lblast->b_next = lb->b_next; // Insert lb after lbstart lb->b_next = lbstart->b_next; lbstart->b_next = lb; lbstart = lb; lbrect.r_xbot = lb->r.r_xtop; lbrect.r_ybot = lb->r.r_ytop; found = TRUE; } else if (((lb->r.r_xtop == lbrect.r_xbot) && (lb->r.r_ytop == lbrect.r_ybot))) { if (lblast == NULL) extSpecialBounds[0] = lb->b_next; else lblast->b_next = lb->b_next; lb->b_next = lbstart->b_next; lbstart->b_next = lb; lbstart = lb; lbrect.r_xbot = lb->r.r_xbot; lbrect.r_ybot = lb->r.r_ybot; found = TRUE; } else if (((lb->r.r_xtop == lbrect.r_xtop) && (lb->r.r_ytop == lbrect.r_ytop))) { if (lblast == NULL) extSpecialBounds[0] = lb->b_next; else lblast->b_next = lb->b_next; lb->b_next = lbend->b_next; lbend->b_next = lb; lbend = lb; lbrect.r_xtop = lb->r.r_xbot; lbrect.r_ytop = lb->r.r_ybot; found = TRUE; } else if (((lb->r.r_xbot == lbrect.r_xtop) && (lb->r.r_ybot == lbrect.r_ytop))) { if (lblast == NULL) extSpecialBounds[0] = lb->b_next; else lblast->b_next = lb->b_next; lb->b_next = lbend->b_next; lbend->b_next = lb; lbend = lb; lbrect.r_xtop = lb->r.r_xtop; lbrect.r_ytop = lb->r.r_ytop; found = TRUE; } else lblast = lb; } } } } /* * ---------------------------------------------------------------------------- * * extOutputParameters -- * * Scan through the TransRegion in the supplied list, and collect a mask of * all transistor types used in the layout. Then for each transistor type, * find if it belongs to a "subcircuit" (including "rsubcircuit" and * "msubcircuit") definition. If it does, output a record containing the * list of parameter names used by that subcircuit. * * Results: * None. * * Side effects: * Possibly writes to outFile. The purpose of this scan is not to have * to write out shared parameter information for every individual device. * ---------------------------------------------------------------------------- */ void extOutputParameters(def, transList, outFile) CellDef *def; /* Cell being extracted */ TransRegion *transList; /* Transistor regions built up in first pass */ FILE *outFile; /* Output file */ { ParamList *plist; TransRegion *reg; TileType t; TileTypeBitMask tmask; TTMaskZero(&tmask); for (reg = transList; reg && !SigInterruptPending; reg = reg->treg_next) TTMaskSetType(&tmask, reg->treg_type); for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) { if (TTMaskHasType(&tmask, t)) { plist = ExtCurStyle->exts_deviceParams[t]; if (plist != (ParamList *)NULL) { fprintf(outFile, "parameters %s", ExtCurStyle->exts_transName[t]); for (; plist != NULL; plist = plist->pl_next) { if (plist->pl_param[1] != '\0') { if (plist->pl_scale != 1.0) fprintf(outFile, " %c%c=%s*%g", plist->pl_param[0], plist->pl_param[1], plist->pl_name, plist->pl_scale); else fprintf(outFile, " %c%c=%s", plist->pl_param[0], plist->pl_param[1], plist->pl_name); } else { if (plist->pl_scale != 1.0) fprintf(outFile, " %c=%s*%g", plist->pl_param[0], plist->pl_name, plist->pl_scale); else fprintf(outFile, " %c=%s", plist->pl_param[0], plist->pl_name); } } fprintf(outFile, "\n"); } } } } /* * ---------------------------------------------------------------------------- * * extGetNativeResistClass() -- * * For the purpose of generating a node area and perimeter value to output * to a subcircuit call as a passed parameter. The value output is assumed * to refer only to the part of the whole eletrical node that is the * actual device node, not to include connected metal, contacts, etc. * Since area and perimeter information about a node is separated into * resist classes, we need to figure out which resist class belongs to * the device terminal type. * * "type" is the type identifier for the device (e.g., gate). "term" is * the index of the terminal for the device. Devices with symmetrical * terminals (e.g., MOSFETs), may have fewer type masks than terminals. * * ---------------------------------------------------------------------------- */ int extGetNativeResistClass(type, term) TileType type; int term; { TileTypeBitMask *tmask, *rmask; int i, n; tmask = NULL; for (i = 0;; i++) { rmask = &ExtCurStyle->exts_transSDTypes[type][i]; if (TTMaskHasType(rmask, TT_SPACE)) break; tmask = rmask; if (i == term) break; } if (tmask == NULL) return -1; /* Error */ for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) { rmask = &ExtCurStyle->exts_typesByResistClass[n]; if (TTMaskIntersect(rmask, tmask)) return n; } return -1; /* Error */ } /* * ---------------------------------------------------------------------------- * * extOutputTrans -- * * For each TransRegion in the supplied list, corresponding to a single * transistor in the layout, compute and output: * - Its type * - Its area and perimeter OR length and width OR capacitance OR resistance * - Its substrate node * - For each of the gate, and the various diff terminals (eg, * source, drain): * Node to which the terminal connects * Length of the terminal * Attributes (comma-separated), or 0 if none. * * The tiles in 'def' don't point back to the TransRegions in this list, * but rather to the NodeRegions corresponding to their electrical nodes. * * Results: * None. * * Side effects: * Writes a number of 'fet' records to the file 'outFile'. * * Interruptible. If SigInterruptPending is detected, we stop traversing * the transistor list and return. * * ---------------------------------------------------------------------------- */ void extOutputTrans(def, transList, outFile) CellDef *def; /* Cell being extracted */ TransRegion *transList; /* Transistor regions built up in first pass */ FILE *outFile; /* Output file */ { NodeRegion *node, *subsNode; TransRegion *reg; char *subsName; FindRegion arg; LabelList *ll; TileType t; int nsd, length, width, n, i, ntiles, corners, tn, rc; double dres, dcap; char mesg[256]; bool isAnnular, hasModel; ParamList *chkParam; for (reg = transList; reg && !SigInterruptPending; reg = reg->treg_next) { /* * Visit all of the tiles in the transistor region, updating * extTransRec.tr_termnode[] and extTransRec.tr_termlen[], * and the attribute lists for this transistor. * * Algorithm: first visit all tiles in the transistor, marking * them with 'reg', then visit them again re-marking them with * the gate node (extGetRegion(reg->treg_tile)). */ extTransRec.tr_nterm = 0; extTransRec.tr_gatelen = 0; extTransRec.tr_perim = 0; extTransRec.tr_subsnode = (NodeRegion *)NULL; arg.fra_def = def; arg.fra_connectsTo = ExtCurStyle->exts_transConn; extTransRec.tr_gatenode = (NodeRegion *) extGetRegion(reg->treg_tile); t = reg->treg_type; arg.fra_pNum = DBPlane(t); /* Set all terminals to NULL to guard against */ /* asymmetric devices missing a terminal. */ /* 5/30/09---but, reinitialize the array out to MAXSD, */ /* or devices declaring minterms < maxterms screw up! */ nsd = ExtCurStyle->exts_transSDCount[t]; for (i = 0; i < MAXSD; i++) extTransRec.tr_termnode[i] = NULL; /* Mark with reg and process each perimeter segment */ arg.fra_uninit = (ClientData) extTransRec.tr_gatenode; arg.fra_region = (Region *) reg; arg.fra_each = extTransTileFunc; ntiles = ExtFindNeighbors(reg->treg_tile, arg.fra_pNum, &arg); /* Re-mark with extTransRec.tr_gatenode */ arg.fra_uninit = (ClientData) reg; arg.fra_region = (Region *) extTransRec.tr_gatenode; arg.fra_each = (int (*)()) NULL; (void) ExtFindNeighbors(reg->treg_tile, arg.fra_pNum, &arg); /* * For types that require a minimum number of terminals, * check to make sure that they all exist. If they don't, * issue a warning message and make believe the missing * terminals are the same as the last terminal we do have. */ if (extTransRec.tr_nterm < nsd) { int missing = nsd - extTransRec.tr_nterm; (void) sprintf(mesg, "device missing %d terminal%s", missing, missing == 1 ? "" : "s"); if (extTransRec.tr_nterm > 0) { node = extTransRec.tr_termnode[extTransRec.tr_nterm - 1]; (void) strcat(mesg, ";\n connecting remainder to node "); (void) strcat(mesg, extNodeName((LabRegion *) node)); while (extTransRec.tr_nterm < nsd) { extTransRec.tr_termlen[extTransRec.tr_nterm] = 0; extTransRec.tr_termnode[extTransRec.tr_nterm++] = node; } } if (ExtDoWarn & EXTWARN_FETS) extTransBad(def, reg->treg_tile, mesg); } else if (extTransRec.tr_nterm > nsd) { /* It is not an error condition to have more terminals */ /* than the minimum. */ } /* * Output the transistor record. * The type is ExtCurStyle->exts_transName[t], which should have * some meaning to the simulator we are producing this file for. * Use the default substrate node unless the transistor overlaps * material whose type is in exts_transSubstrateTypes, in which * case we use the node of the overlapped material. */ subsName = ExtCurStyle->exts_transSubstrateName[t]; if (!TTMaskIsZero(&ExtCurStyle->exts_transSubstrateTypes[t]) && (subsNode = extTransRec.tr_subsnode)) { subsName = extNodeName(subsNode); } #ifdef MAGIC_WRAPPER /* If subsName is a Tcl variable (begins with "$"), make the */ /* variable substitution, if one exists. Ignore double-$. */ else if (subsName && subsName[0] == '$' && subsName[1] != '$') { char *varsub = (char *)Tcl_GetVar(magicinterp, &subsName[1], TCL_GLOBAL_ONLY); if (varsub != NULL) subsName = varsub; } #endif /* Original-style FET record backward compatibility */ if (ExtCurStyle->exts_deviceClass[t] != DEV_FET) fprintf(outFile, "device "); fprintf(outFile, "%s %s", extDevTable[ExtCurStyle->exts_deviceClass[t]], ExtCurStyle->exts_transName[t]); fprintf(outFile, " %d %d %d %d", reg->treg_ll.p_x, reg->treg_ll.p_y, reg->treg_ll.p_x + 1, reg->treg_ll.p_y + 1); /* NOTE: The following code makes unreasonable simplifying */ /* assumptions about how to calculate device length and width. */ /* However, it is the same as was always used by ext2sim and */ /* ext2spice. By putting it here, where all the tile */ /* information exists, it is at least theoretically possible to */ /* write better routines that can deal with bends in resistors */ /* and transistors, annular devices, multiple-drain devices, */ /* etc., etc. */ /* Tim, 2/20/03 */ switch (ExtCurStyle->exts_deviceClass[t]) { case DEV_FET: /* old style, perimeter & area */ fprintf(outFile, " %d %d \"%s\"", reg->treg_area, extTransRec.tr_perim, (subsName == NULL) ? "None" : subsName); break; /* "device " types, calculation of length & width */ case DEV_MOSFET: case DEV_BJT: case DEV_SUBCKT: case DEV_MSUBCKT: case DEV_ASYMMETRIC: length = extTransRec.tr_gatelen / 2; /* (default) */ width = 0; isAnnular = FALSE; /* Note that width is accumulated on one tr_termlen */ /* record when nodes are merged, so proper behavior */ /* for transistors w/connected S-D is to count over */ /* non-NULL termnodes, not non-zero termlens. */ for (n = 0; n < extTransRec.tr_nterm; n++) { if (extTransRec.tr_termnode[n] == NULL) continue; width += extTransRec.tr_termlen[n]; /* Mark annular transistors as requiring extra processing */ if (extTransRec.tr_termvector[n].p_x == 0 && extTransRec.tr_termvector[n].p_y == 0) isAnnular = TRUE; } if (n) width /= n; /*------------------------------------------------------*/ /* Note that the tr_termvector says a lot about the */ /* device geometry. If the sum of x and y for any */ /* vector is 0, then the terminal is enclosed (annular */ /* device). If the sum of x and y for all vectors is */ /* zero, then we have a normal rectangular device. But */ /* if the sum of all x and y is nonzero, then the */ /* device length changes along the device (including */ /* bends). This is a trigger to do a more extensive */ /* boundary search to find the exact dimensions of the */ /* device. */ /*------------------------------------------------------*/ if (n == 0) { /* Don't issue a warning on devices such as a */ /* vertical diode that may declare zero terminals */ /* because the substrate node (i.e., well) is the */ /* other terminal. */ if (ExtDoWarn && (ExtCurStyle->exts_transSDCount[t] > 0)) extTransBad(def, reg->treg_tile, "Could not determine device boundary"); length = width = 0; } else { LinkedBoundary *lb; extSpecialBounds = (LinkedBoundary **)mallocMagic(n * sizeof(LinkedBoundary *)); for (i = 0; i < n; i++) extSpecialBounds[i] = NULL; /* Mark with reg and process each perimeter segment */ arg.fra_uninit = (ClientData) extTransRec.tr_gatenode; arg.fra_region = (Region *) reg; arg.fra_each = extAnnularTileFunc; (void) ExtFindNeighbors(reg->treg_tile, arg.fra_pNum, &arg); extSeparateBounds(n - 1); /* Handle MOScaps (if necessary) */ extComputeEffectiveLW(&length, &width, n, ExtCurStyle->exts_cornerChop[t]); /* Free the lists */ for (i = 0; i < n; i++) for (lb = extSpecialBounds[i]; lb != NULL; lb = lb->b_next) freeMagic((char *)lb); freeMagic((char *)extSpecialBounds); /* Put the region list back the way we found it: */ /* Re-mark with extTransRec.tr_gatenode */ arg.fra_uninit = (ClientData) reg; arg.fra_region = (Region *) extTransRec.tr_gatenode; arg.fra_each = (int (*)()) NULL; (void) ExtFindNeighbors(reg->treg_tile, arg.fra_pNum, &arg); } if (ExtCurStyle->exts_deviceClass[t] == DEV_SUBCKT || ExtCurStyle->exts_deviceClass[t] == DEV_MSUBCKT) { for (chkParam = ExtCurStyle->exts_deviceParams[t]; chkParam != NULL; chkParam = chkParam->pl_next) { switch(tolower(chkParam->pl_param[0])) { case 'a': if (chkParam->pl_param[1] == '\0' || chkParam->pl_param[1] == '0') fprintf(outFile, " %c=%d", chkParam->pl_param[0], reg->treg_area); break; case 'p': if (chkParam->pl_param[1] == '\0' || chkParam->pl_param[1] == '0') fprintf(outFile, " %c=%d", chkParam->pl_param[0], extTransRec.tr_perim); break; case 'l': fprintf(outFile, " %c=%d", chkParam->pl_param[0], length); break; case 'w': fprintf(outFile, " %c=%d", chkParam->pl_param[0], width); break; case 'c': fprintf(outFile, " %c=%g", chkParam->pl_param[0], (ExtCurStyle->exts_transGateCap[t] * reg->treg_area) + (ExtCurStyle->exts_transSDCap[t] * extTransRec.tr_perim)); break; case 's': case 'x': case 'y': /* Do nothing; these values are standard output */ break; default: fprintf(outFile, " %c=", chkParam->pl_param[0]); break; } } } else /* DEV_MOSFET, DEV_ASYMMETRIC, DEV_BJT */ { fprintf(outFile, " %d %d", length, width); } fprintf(outFile, " \"%s\"", (subsName == NULL) ? "None" : subsName); break; case DEV_DIODE: /* Only handle the optional substrate node */ if (subsName != NULL) fprintf(outFile, " \"%s\"", subsName); break; case DEV_RES: case DEV_RSUBCKT: hasModel = strcmp(ExtCurStyle->exts_transName[t], "None"); length = extTransRec.tr_perim; isAnnular = FALSE; /* Boundary perimeter scan for resistors with more than */ /* one tile. */ for (n = 0; n < extTransRec.tr_nterm; n++) { if (extTransRec.tr_termnode[n] == NULL) continue; /* Mark annular resistors as requiring extra processing */ if (extTransRec.tr_termvector[n].p_x == 0 && extTransRec.tr_termvector[n].p_y == 0) isAnnular = TRUE; } if (n == 0) width = length = 0; else if (ntiles > 1) { LinkedBoundary *lb; extSpecialBounds = (LinkedBoundary **)mallocMagic(n * sizeof(LinkedBoundary *)); for (i = 0; i < n; i++) extSpecialBounds[i] = NULL; /* Mark with reg and process each perimeter segment */ arg.fra_uninit = (ClientData) extTransRec.tr_gatenode; arg.fra_region = (Region *) reg; if (isAnnular) arg.fra_each = extAnnularTileFunc; else arg.fra_each = extResistorTileFunc; (void) ExtFindNeighbors(reg->treg_tile, arg.fra_pNum, &arg); if (extSpecialBounds[0] != NULL) { extSeparateBounds(n - 1); if (isAnnular) extComputeEffectiveLW(&length, &width, n, ExtCurStyle->exts_cornerChop[t]); else extComputeEffectiveLW(&width, &length, n, ExtCurStyle->exts_cornerChop[t]); } else { if (ExtDoWarn) extTransBad(def, reg->treg_tile, "Could not determine resistor boundary"); length = width = 0; } /* Free the lists */ for (i = 0; i < n; i++) for (lb = extSpecialBounds[i]; lb != NULL; lb = lb->b_next) freeMagic((char *)lb); freeMagic((char *)extSpecialBounds); /* Put the region list back the way we found it: */ /* Re-mark with extTransRec.tr_gatenode */ arg.fra_uninit = (ClientData) reg; arg.fra_region = (Region *) extTransRec.tr_gatenode; arg.fra_each = (int (*)()) NULL; (void) ExtFindNeighbors(reg->treg_tile, arg.fra_pNum, &arg); } else { /* Single tile resistor means a simple L,W */ /* calculation from perimeter & area. */ width = 0; for (n = 0; extTransRec.tr_termlen[n] != 0; n++) { width += extTransRec.tr_termlen[n]; length -= extTransRec.tr_termlen[n]; } width >>= 1; length >>= 1; } if (width) { dres = ExtCurStyle->exts_sheetResist[t] * (double)length / (double)width; if (ExtDoWarn && (n > 2)) { if (hasModel) sprintf(mesg, "Resistor has %d terminals: " "extracted L/W will be wrong", n); else sprintf(mesg, "Resistor has %d terminals: " "extracted value will be wrong", n); extTransBad(def, reg->treg_tile, mesg); } } else { dres = 0.0; if (ExtDoWarn) extTransBad(def, reg->treg_tile, "Resistor has zero width"); } if (ExtCurStyle->exts_deviceClass[t] == DEV_RSUBCKT) { for (chkParam = ExtCurStyle->exts_deviceParams[t]; chkParam != NULL; chkParam = chkParam->pl_next) { switch(tolower(chkParam->pl_param[0])) { case 'a': if (chkParam->pl_param[1] == '\0' || chkParam->pl_param[1] == '0') fprintf(outFile, " %c=%d", chkParam->pl_param[0], reg->treg_area); break; case 'p': if (chkParam->pl_param[1] == '\0' || chkParam->pl_param[1] == '0') fprintf(outFile, " %c=%d", chkParam->pl_param[0], extTransRec.tr_perim); break; case 'l': fprintf(outFile, " %c=%d", chkParam->pl_param[0], length); break; case 'w': fprintf(outFile, " %c=%d", chkParam->pl_param[0], width); break; case 'r': fprintf(outFile, " %c=%g", chkParam->pl_param[0], dres / 1000.0); break; case 'c': fprintf(outFile, " %c=%g", chkParam->pl_param[0], (ExtCurStyle->exts_transGateCap[t] * reg->treg_area) + (ExtCurStyle->exts_transSDCap[t] * extTransRec.tr_perim)); break; case 's': case 'x': case 'y': /* Do nothing; these values are standard output */ break; default: fprintf(outFile, " %c=", chkParam->pl_param[0]); break; } } fprintf(outFile, " \"%s\"", (subsName == NULL) ? "None" : subsName); } else if (hasModel) /* SPICE semiconductor resistor */ { fprintf(outFile, " %d %d", length, width); if (subsName != NULL) fprintf(outFile, " \"%s\"", subsName); } else /* regular resistor */ fprintf(outFile, " %g", dres / 1000.0); /* mOhms -> Ohms */ break; case DEV_CAP: hasModel = strcmp(ExtCurStyle->exts_transName[t], "None"); if (hasModel) { for (n = 0; n < extTransRec.tr_nterm && extTransRec.tr_termnode[n] != NULL; n++); /* Don't know what to do (yet) with capacitors */ /* multiple terminals (see below); treat them in */ /* the original naive manner. */ if (n == 0) { width = 0; extTransBad(def, reg->treg_tile, "Capacitor has zero size"); fprintf(outFile, " 0 0"); } // else if ((ntiles == 1) || (n > 1)) // { // width = 0; // for (n = 0; extTransRec.tr_termlen[n] != 0; n++) // width += extTransRec.tr_termlen[n]; // // if (!width && ExtDoWarn) // extTransBad(def, reg->treg_tile, // "Capacitor has zero width"); // else width >>= 2; /* total perimeter / 4 */ // // fprintf(outFile, " %d %d", reg->treg_area / width, // width); // } else { /* Special handling of multiple-tile areas. */ /* This algorithm assumes that the capacitor */ /* has one terminal and that the area is a */ /* rectangle. It should be extended to output */ /* multiple capacitors for multiple rectangular */ /* areas, combining to form any arbitrary shape */ LinkedBoundary *lb; extSpecialBounds = (LinkedBoundary **)mallocMagic(n * sizeof(LinkedBoundary *)); for (i = 0; i < n; i++) extSpecialBounds[i] = NULL; /* Mark with reg and process each perimeter segment */ arg.fra_uninit = (ClientData) extTransRec.tr_gatenode; arg.fra_region = (Region *) reg; arg.fra_each = extAnnularTileFunc; (void) ExtFindNeighbors(reg->treg_tile, arg.fra_pNum, &arg); extComputeCapLW(&length, &width); if ((length * width) > reg->treg_area) { if (ExtDoWarn) extTransBad(def, reg->treg_tile, "L,W estimated " "for non-rectangular capacitor."); fprintf(outFile, " %d %d", width, reg->treg_area / width); } else fprintf(outFile, " %d %d", length, width); /* Free the lists */ for (i = 0; i < n; i++) for (lb = extSpecialBounds[i]; lb != NULL; lb = lb->b_next) freeMagic((char *)lb); freeMagic((char *)extSpecialBounds); /* Put the region list back the way we found it: */ /* Re-mark with extTransRec.tr_gatenode */ arg.fra_uninit = (ClientData) reg; arg.fra_region = (Region *) extTransRec.tr_gatenode; arg.fra_each = (int (*)()) NULL; (void) ExtFindNeighbors(reg->treg_tile, arg.fra_pNum, &arg); } if (subsName != NULL) fprintf(outFile, " \"%s\"", subsName); } else { dcap = (ExtCurStyle->exts_transGateCap[t] * reg->treg_area) + (ExtCurStyle->exts_transSDCap[t] * extTransRec.tr_perim); fprintf(outFile, " %g", dcap / 1000.0); /* aF -> fF */ } break; } /* gate */ node = (NodeRegion *) extGetRegion(reg->treg_tile); ll = node->nreg_labels; extTransOutTerminal((LabRegion *) node, ll, LL_GATEATTR, extTransRec.tr_gatelen, outFile); /* Sort source and drain terminals by position, unless the */ /* device is asymmetric, in which case source and drain do not */ /* permute, and the terminal order is fixed. */ if (TTMaskHasType(&ExtCurStyle->exts_transSDTypes[t][1], TT_SPACE)) ExtSortTerminals(&extTransRec, ll); /* each non-gate terminal */ for (nsd = 0; nsd < extTransRec.tr_nterm; nsd++) extTransOutTerminal((LabRegion *) extTransRec.tr_termnode[nsd], ll, nsd, extTransRec.tr_termlen[nsd], outFile); (void) fputs("\n", outFile); } } int extTransFindSubs(tile, def, sn) Tile *tile; CellDef *def; NodeRegion **sn; { TileType t; TileTypeBitMask *mask; Rect tileArea; int pNum; int extTransFindSubsFunc1(); /* Forward declaration */ TiToRect(tile, &tileArea); if (IsSplit(tile)) t = (SplitSide(tile)) ? SplitRightType(tile): SplitLeftType(tile); else t = TiGetTypeExact(tile); mask = &ExtCurStyle->exts_transSubstrateTypes[t]; for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) { if (TTMaskIntersect(&DBPlaneTypes[pNum], mask)) { if (DBSrPaintArea((Tile *) NULL, def->cd_planes[pNum], &tileArea, mask, extTransFindSubsFunc1, (ClientData)sn)) return 1; } } return 0; } int extTransFindSubsFunc1(tile, sn) Tile *tile; NodeRegion **sn; { /* Report split substrate region errors (two different substrate * regions under the same device) */ if (tile->ti_client != (ClientData) extUnInit) { if ((*sn != (NodeRegion *)NULL) && (*sn != tile->ti_client)) TxError("Warning: Split substrate under device at (%d %d)\n", tile->ti_ll.p_x, tile->ti_ll.p_y); *sn = (NodeRegion *) tile->ti_client; return 1; } return 0; } /* * ---------------------------------------------------------------------------- * * extTransTileFunc -- * * Filter function called by ExtFindNeighbors for each tile in a * transistor. Responsible for collecting the nodes, lengths, * and attributes of all the terminals on this transistor. * * Results: * Returns 0 always. * * Side effects: * Fills in the transRec structure extTransRec. * * ---------------------------------------------------------------------------- */ int extTransTileFunc(tile, pNum, arg) Tile *tile; int pNum; FindRegion *arg; { TileTypeBitMask mask; TileType loctype; int perim; LabelList *ll; Label *lab; Rect r; for (ll = extTransRec.tr_gatenode->nreg_labels; ll; ll = ll->ll_next) { /* Skip if already marked */ if (ll->ll_attr != LL_NOATTR) continue; lab = ll->ll_label; TITORECT(tile, &r); if (GEO_TOUCH(&r, &lab->lab_rect) && extLabType(lab->lab_text, LABTYPE_GATEATTR)) { ll->ll_attr = LL_GATEATTR; } } /* * Visit each segment of the perimeter of this tile that * that borders on something of a different type. */ if (IsSplit(tile)) { loctype = (SplitSide(tile)) ? SplitRightType(tile): SplitLeftType(tile); // return (0); /* Hack alert! We must properly handle diagonals! */ } else loctype = TiGetTypeExact(tile); mask = ExtCurStyle->exts_transConn[loctype]; TTMaskCom(&mask); /* NOTE: DO NOT USE extTransRec.tr_perim += extEnumTilePerim(...) */ /* The AMD target gcc compile works and the Intel target gcc */ /* compile doesn't! The following code works the same on both. */ perim = extEnumTilePerim(tile, mask, pNum, extTransPerimFunc, (ClientData)NULL); extTransRec.tr_perim += perim; if (extTransRec.tr_subsnode == (NodeRegion *)NULL) extTransFindSubs(tile, arg->fra_def, &extTransRec.tr_subsnode); return (0); } int extTransPerimFunc(bp) Boundary *bp; { TileType tinside, toutside; Tile *tile; NodeRegion *diffNode = (NodeRegion *) extGetRegion(bp->b_outside); int i, len = BoundaryLength(bp); int thisterm; LabelList *ll; Label *lab; Rect r; bool SDterm = FALSE; tile = bp->b_inside; if (IsSplit(tile)) tinside = (SplitSide(tile)) ? SplitRightType(tile): SplitLeftType(tile); else tinside = TiGetTypeExact(bp->b_inside); tile = bp->b_outside; if (IsSplit(tile)) toutside = (SplitSide(tile)) ? SplitRightType(tile): SplitLeftType(tile); else toutside = TiGetTypeExact(bp->b_outside); for (i = 0; !TTMaskHasType(&ExtCurStyle->exts_transSDTypes[tinside][i], TT_SPACE); i++) { if (TTMaskHasType(&ExtCurStyle->exts_transSDTypes[tinside][i], toutside)) { /* * It's a diffusion terminal (source or drain). See if the node is * already in our table; add it if it wasn't already there. * Asymmetric devices must have terminals in order. */ if (TTMaskHasType(&ExtCurStyle->exts_transSDTypes[tinside][1], TT_SPACE)) { for (thisterm = 0; thisterm < extTransRec.tr_nterm; thisterm++) if (extTransRec.tr_termnode[thisterm] == diffNode) break; } else thisterm = i; if (extTransRec.tr_termnode[thisterm] == NULL) { extTransRec.tr_nterm++; extTransRec.tr_termnode[thisterm] = diffNode; extTransRec.tr_termlen[thisterm] = 0; extTransRec.tr_termvector[thisterm].p_x = 0; extTransRec.tr_termvector[thisterm].p_y = 0; extTransRec.tr_termpos[thisterm].pnum = DBPlane(toutside); extTransRec.tr_termpos[thisterm].pt = bp->b_outside->ti_ll; /* Find the total area of this terminal */ } else if (extTransRec.tr_termnode[thisterm] == diffNode) { TermTilePos *pos = &(extTransRec.tr_termpos[thisterm]); Tile *otile = bp->b_outside; /* update the region tile position */ if( DBPlane(TiGetType(otile)) < pos->pnum ) { pos->pnum = DBPlane(TiGetType(otile)); pos->pt = otile->ti_ll; } else if( DBPlane(TiGetType(otile)) == pos->pnum ) { if( LEFT(otile) < pos->pt.p_x ) pos->pt = otile->ti_ll; else if( LEFT(otile) == pos->pt.p_x && BOTTOM(otile) < pos->pt.p_y ) pos->pt.p_y = BOTTOM(otile); } } else { TxError("Error: Asymmetric device with multiple terminals!\n"); } /* Add the length to this terminal's perimeter */ extTransRec.tr_termlen[thisterm] += len; /* Update the boundary traversal vector */ switch(bp->b_direction) { case BD_LEFT: extTransRec.tr_termvector[thisterm].p_y += len; break; case BD_TOP: extTransRec.tr_termvector[thisterm].p_x += len; break; case BD_RIGHT: extTransRec.tr_termvector[thisterm].p_y -= len; break; case BD_BOTTOM: extTransRec.tr_termvector[thisterm].p_x -= len; break; } /* * Mark this attribute as belonging to this transistor * if it is either: * (1) a terminal attribute whose LL corner touches bp->b_segment, * or (2) a gate attribute that lies inside bp->b_inside. */ for (ll = extTransRec.tr_gatenode->nreg_labels; ll; ll = ll->ll_next) { /* Skip if already marked */ if (ll->ll_attr != LL_NOATTR) continue; lab = ll->ll_label; if (GEO_ENCLOSE(&lab->lab_rect.r_ll, &bp->b_segment) && extLabType(lab->lab_text, LABTYPE_TERMATTR)) { ll->ll_attr = thisterm; } } SDterm = TRUE; break; } } if (!SDterm && extConnectsTo(tinside, toutside, ExtCurStyle->exts_nodeConn)) { /* Not in a terminal, but are in something that connects to gate */ extTransRec.tr_gatelen += len; } /* * Total perimeter (separate from terminals, for dcaps * that might not be surrounded by terminals on all sides). */ /* Don't double-count contact perimeters (added by Tim 1/9/07) */ if ((!DBIsContact(toutside) && !DBIsContact(tinside)) || (bp->b_plane == extTransRec.tr_gatenode->nreg_pnum)) extTransRec.tr_perim += len; return (0); } /* * ---------------------------------------------------------------------------- * * extAnnularTileFunc -- * * Filter function called by ExtFindNeighbors for each tile in a * transistor. Responsible for doing an extensive boundary * survey to determine the length of the transistor. * This is basically a subset of the code in extTransTileFunc() * but passes a different function to extEnumTilePerim(). * * Results: * Returns 0 always. * * Side effects: * * ---------------------------------------------------------------------------- */ int extAnnularTileFunc(tile, pNum) Tile *tile; int pNum; { TileTypeBitMask mask; TileType loctype; /* * Visit each segment of the perimeter of this tile that * that borders on something of a different type. */ if (IsSplit(tile)) { loctype = (SplitSide(tile)) ? SplitRightType(tile): SplitLeftType(tile); } else loctype = TiGetTypeExact(tile); mask = ExtCurStyle->exts_transConn[loctype]; TTMaskCom(&mask); extEnumTilePerim(tile, mask, pNum, extSpecialPerimFunc, (ClientData) TRUE); return (0); } /* * ---------------------------------------------------------------------------- * * extResistorTileFunc -- * * Filter function called by ExtFindNeighbors for each tile in a * resistor. This is very similar to the extAnnularTileFunc * above, but it looks a boundaries with non-source/drain types * rather than the source/drain boundaries themselves. This is * correct for tracing the detailed perimeter of a device where * L > W. * * Ideally, one wants to call both of these functions to check * both the case of L > W and the case W > L, assuming that both * are legal resistor layouts. * * Results: * Returns 0 always. * * Side effects: * * ---------------------------------------------------------------------------- */ int extResistorTileFunc(tile, pNum) Tile *tile; int pNum; { TileTypeBitMask mask; TileType loctype; /* * Visit each segment of the perimeter of this tile that * that borders on something of a different type. */ if (IsSplit(tile)) { loctype = (SplitSide(tile)) ? SplitRightType(tile): SplitLeftType(tile); } else loctype = TiGetTypeExact(tile); mask = ExtCurStyle->exts_transConn[loctype]; TTMaskSetMask(&mask, &ExtCurStyle->exts_transSDTypes[loctype][0]); TTMaskCom(&mask); extEnumTilePerim(tile, mask, pNum, extSpecialPerimFunc, (ClientData)FALSE); return (0); } /*----------------------------------------------------------------------*/ /* Detailed boundary survey for unusual transistor geometries (esp. */ /* annular). If "sense" is TRUE, look at boundaries with source/drain */ /* types. If "sense" is FALSE, looks at non-source/drain boundaries. */ /*----------------------------------------------------------------------*/ int extSpecialPerimFunc(bp, sense) Boundary *bp; bool sense; { TileType tinside, toutside; NodeRegion *diffNode = (NodeRegion *) extGetRegion(bp->b_outside); int thisterm, extended, i; LinkedBoundary *newBound, *lb, *lastlb; bool needSurvey; /* Note that extEnumTilePerim() assumes for the non-Manhattan case */ /* that non-Manhattan tiles should be incorporated into the device */ /* gate for purposes of computing effective length and width. In */ /* most cases this will be only a slight deviation from the true */ /* result. */ switch (bp->b_direction) { case BD_TOP: tinside = TiGetTopType(bp->b_inside); toutside = TiGetBottomType(bp->b_outside); break; case BD_BOTTOM: tinside = TiGetBottomType(bp->b_inside); toutside = TiGetTopType(bp->b_outside); break; case BD_RIGHT: tinside = TiGetRightType(bp->b_inside); toutside = TiGetLeftType(bp->b_outside); break; case BD_LEFT: tinside = TiGetLeftType(bp->b_inside); toutside = TiGetRightType(bp->b_outside); break; } /* Check all terminal classes for a matching type */ needSurvey = FALSE; for (i = 0; !TTMaskHasType(&ExtCurStyle->exts_transSDTypes[tinside][i], TT_SPACE); i++) { if (TTMaskHasType(&ExtCurStyle->exts_transSDTypes[tinside][i], toutside)) { needSurvey = TRUE; break; } } if (!sense || needSurvey) { /* * Since we're repeating the search, all terminals should be there. */ if (!sense) thisterm = 0; else { for (thisterm = 0; thisterm < extTransRec.tr_nterm; thisterm++) if (extTransRec.tr_termnode[thisterm] == diffNode) break; if (thisterm >= extTransRec.tr_nterm) { TxError("Internal Error in Transistor Perimeter Boundary Search!\n"); return 1; } } /* * Check the existing segment list to see if this segment * extends an existing segment. */ extended = 0; for (lb = extSpecialBounds[thisterm]; lb != NULL; lb = lb->b_next) { if (bp->b_direction == lb->dir) { switch(lb->dir) { case BD_LEFT: case BD_RIGHT: if (bp->b_segment.r_xbot == lb->r.r_xbot) { if (bp->b_segment.r_ybot == lb->r.r_ytop) { if (extended) lastlb->r.r_ybot = lb->r.r_ybot; else lb->r.r_ytop = bp->b_segment.r_ytop; extended++; lastlb = lb; } else if (bp->b_segment.r_ytop == lb->r.r_ybot) { if (extended) lastlb->r.r_ytop = lb->r.r_ytop; else lb->r.r_ybot = bp->b_segment.r_ybot; extended++; lastlb = lb; } } break; case BD_TOP: case BD_BOTTOM: if (bp->b_segment.r_ybot == lb->r.r_ybot) { if (bp->b_segment.r_xbot == lb->r.r_xtop) { if (extended) lastlb->r.r_xbot = lb->r.r_xbot; else lb->r.r_xtop = bp->b_segment.r_xtop; extended++; lastlb = lb; } else if (bp->b_segment.r_xtop == lb->r.r_xbot) { if (extended) lastlb->r.r_xtop = lb->r.r_xtop; else lb->r.r_xbot = bp->b_segment.r_xbot; extended++; lastlb = lb; } } break; } } if (extended == 2) { /* Connected two existing entries---need to remove lastlb, */ /* which is now a redundant segment. */ if (lastlb == extSpecialBounds[thisterm]) extSpecialBounds[thisterm] = lastlb->b_next; else { for (lb = extSpecialBounds[thisterm]; lb != NULL; lb = lb->b_next) { if (lastlb == lb->b_next) { lb->b_next = lastlb->b_next; break; } } } freeMagic((char *)lastlb); /* New segment cannot extend more than two existing segments */ break; } } if (!extended) { newBound = (LinkedBoundary *)mallocMagic(sizeof(LinkedBoundary)); newBound->r = bp->b_segment; newBound->dir = bp->b_direction; newBound->b_next = extSpecialBounds[thisterm]; extSpecialBounds[thisterm] = newBound; } } return (0); } /* * ---------------------------------------------------------------------------- * * extTransOutTerminal -- * * Output the information associated with one terminal of a * transistor. This consists of three things: * - the name of the node to which the terminal is connected * - the length of the terminal along the perimeter of the transistor * - a list of attributes pertinent to this terminal. * * If 'whichTerm' is LL_GATEATTR, this is the gate; otherwise, it is one * of the diffusion terminals. * * Results: * None. * * Side effects: * Writes the above information to 'outFile'. * Resets ll_attr for each attribute we output to LL_NOATTR. * * ---------------------------------------------------------------------------- */ void extTransOutTerminal(lreg, ll, whichTerm, len, outFile) LabRegion *lreg; /* Node connected to terminal */ LabelList *ll; /* Gate's label list */ int whichTerm; /* Which terminal we are processing. The gate * is indicated by LL_GATEATTR. */ int len; /* Length of perimeter along terminal */ FILE *outFile; /* Output file */ { char *cp; int n; char fmt; fprintf(outFile, " \"%s\" %d", extNodeName(lreg), len); for (fmt = ' '; ll; ll = ll->ll_next) if (ll->ll_attr == whichTerm) { fprintf(outFile, "%c\"", fmt); cp = ll->ll_label->lab_text; n = strlen(cp) - 1; while (n-- > 0) putc(*cp++, outFile); ll->ll_attr = LL_NOATTR; fprintf(outFile, "\""); fmt = ','; } if (fmt == ' ') fprintf(outFile, " 0"); } /* * ---------------------------------------------------------------------------- * * extTransBad -- * * For a transistor where an error was encountered, give feedback * as to the location of the error. * * Results: * None. * * Side effects: * Complains to the user. * * ---------------------------------------------------------------------------- */ void extTransBad(def, tp, mesg) CellDef *def; Tile *tp; char *mesg; { Rect r; if (!DebugIsSet(extDebugID, extDebNoFeedback)) { TiToRect(tp, &r); DBWFeedbackAdd(&r, mesg, def, 1, STYLE_PALEHIGHLIGHTS); } extNumWarnings++; } /* * ---------------------------------------------------------------------------- * * extLabType -- * * Check to see whether the text passed as an argument satisfies * any of the label types in 'typeMask'. * * Results: * TRUE if the text is of one of the label types in 'typeMask', * FALSE if not. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool extLabType(text, typeMask) char *text; int typeMask; { if (*text == '\0') return (FALSE); while (*text) text++; switch (*--text) { case '@': /* Node attribute */ return ((bool)(typeMask & LABTYPE_NODEATTR)); case '$': /* Terminal (source/drain) attribute */ return ((bool)(typeMask & LABTYPE_TERMATTR)); case '^': /* Gate attribute */ return ((bool)(typeMask & LABTYPE_GATEATTR)); default: return ((bool)(typeMask & LABTYPE_NAME)); } /*NOTREACHED*/ } /* * ---------------------------------------------------------------------------- * extNodeToTile -- * * Sets tp to be the tile containing the lower-leftmost point of the * NodeRegion *np, but in the tile planes of the ExtTree *et instead * of the tile planes originally containing *np. This routine used * to be defined as the macro NODETOTILE(). * * Results: * Returns a pointer to the tile * * Side effects: * None. * ---------------------------------------------------------------------------- */ Tile *extNodeToTile(np, et) NodeRegion *np; ExtTree *et; { Tile *tp; Plane *myplane; myplane = et->et_use->cu_def->cd_planes[np->nreg_pnum]; tp = myplane->pl_hint; GOTOPOINT(tp, &np->nreg_ll); myplane->pl_hint = tp; if (IsSplit(tp)) { TileType tpt = TiGetTypeExact(tp); if ((tpt & TT_LEFTMASK) == (np->nreg_type & TT_LEFTMASK)) TiSetBody(tp, tpt & ~TT_SIDE); else TiSetBody(tp, tpt | TT_SIDE); } return tp; } /* * ---------------------------------------------------------------------------- * * extSetNodeNum -- * * Update reg->lreg_ll and reg->lreg_pnum so that they are always the * lowest leftmost coordinate in a cell, on the plane with the lowest * number (formerly a macro in extractInt.h). * * (10/1/05: Changed from a macro to a subroutine and modified for * handling non-Manhattan geometry) * * Results: * None. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ void extSetNodeNum(reg, plane, tile) LabRegion *reg; int plane; Tile *tile; { TileType type; if (IsSplit(tile)) { /* Only consider split tiles if the lower-left-hand corner */ /* is only the type under consideration. */ if (!SplitSide(tile) && SplitDirection(tile)) type = SplitSide(tile) ? SplitRightType(tile) : SplitLeftType(tile); else if (reg->lreg_pnum == DBNumPlanes) type = TiGetTypeExact(tile); else return; } else type = TiGetType(tile); if ((plane < reg->lreg_pnum) || (reg->lreg_type & TT_DIAGONAL)) { reg->lreg_type = type; reg->lreg_pnum = plane; reg->lreg_ll = tile->ti_ll; } else if (plane == reg->lreg_pnum) { if (LEFT(tile) < reg->lreg_ll.p_x) { reg->lreg_ll = tile->ti_ll; reg->lreg_type = type; } else if (LEFT(tile) == reg->lreg_ll.p_x && BOTTOM(tile) < reg->lreg_ll.p_y) { reg->lreg_ll.p_y = BOTTOM(tile); reg->lreg_type = type; } } } /* * ---------------------------------------------------------------------------- * * extTransFirst -- * extTransEach -- * * Filter functions passed to ExtFindRegions when tracing out transistor * regions as part of flat circuit extraction. * * Results: * extTransFirst returns a pointer to a new TransRegion. * extTransEach returns NULL. * * Side effects: * Memory is allocated by extTransFirst. * We cons the newly allocated region onto the front of the existing * region list. * * The area of each transistor is updated by extTransEach. * * ---------------------------------------------------------------------------- */ Region * extTransFirst(tile, arg) Tile *tile; FindRegion *arg; { TransRegion *reg; reg = (TransRegion *) mallocMagic((unsigned) (sizeof (TransRegion))); reg->treg_next = (TransRegion *) NULL; reg->treg_labels = (LabelList *) NULL; reg->treg_area = 0; reg->treg_tile = tile; reg->treg_pnum = DBNumPlanes; if (IsSplit(tile)) reg->treg_type = SplitSide(tile) ? SplitRightType(tile) : SplitLeftType(tile); else reg->treg_type = TiGetTypeExact(tile); /* Prepend it to the region list */ reg->treg_next = (TransRegion *) arg->fra_region; arg->fra_region = (Region *) reg; return ((Region *) reg); } /*ARGSUSED*/ int extTransEach(tile, pNum, arg) Tile *tile; int pNum; FindRegion *arg; { TransRegion *reg = (TransRegion *) arg->fra_region; int area = TILEAREA(tile); if (IsSplit(tile)) area /= 2; /* Split tiles are 1/2 area! */ else if (IsSplit(reg->treg_tile)) { /* Avoid setting the region's tile pointer to a split tile */ reg->treg_tile = tile; reg->treg_type = TiGetTypeExact(tile); } /* The following is non-ideal. It assumes that the lowest plane of */ /* types connected to a device is the plane of the device itself. */ /* Otherwise, the area of the device will be miscalculated. */ if (pNum < reg->treg_pnum) reg->treg_area = 0; extSetNodeNum((LabRegion *) reg, pNum, tile); if (pNum == reg->treg_pnum) reg->treg_area += area; return (0); } /* * ---------------------------------------------------------------------------- * * extFindNodes -- * * Build up, in the manner of ExtFindRegions, a list of all the * node regions in the CellDef 'def'. This procedure is heavily * optimized for speed. * * Results: * Returns a pointer to a NULL-terminated list of NodeRegions * that correspond to the nodes in the circuit. The label lists * for each node region have not yet been filled in. * * Side effects: * Memory is allocated. * * ---------------------------------------------------------------------------- */ Stack *extNodeStack = NULL; Rect *extNodeClipArea = NULL; NodeRegion * extFindNodes(def, clipArea) CellDef *def; /* Def whose nodes are being found */ Rect *clipArea; /* If non-NULL, ignore perimeter and area that extend * outside this rectangle. */ { int extNodeAreaFunc(); FindRegion arg; int pNum, n; /* Reset perimeter and area prior to node extraction */ for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) extResistArea[n] = extResistPerim[n] = 0; extNodeClipArea = clipArea; if (extNodeStack == (Stack *) NULL) extNodeStack = StackNew(64); arg.fra_def = def; arg.fra_region = (Region *) NULL; SigDisableInterrupts(); for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) { arg.fra_pNum = pNum; (void) DBSrPaintClient((Tile *) NULL, def->cd_planes[pNum], &TiPlaneRect, &DBAllButSpaceBits, extUnInit, extNodeAreaFunc, (ClientData) &arg); } SigEnableInterrupts(); /* Compute resistance for last node */ if (arg.fra_region && (ExtOptions & EXT_DORESISTANCE)) extSetResist((NodeRegion *) arg.fra_region); return ((NodeRegion *) arg.fra_region); } int extNodeAreaFunc(tile, arg) Tile *tile; FindRegion *arg; { int tilePlaneNum, pNum, len, area, resistClass, n, nclasses; PlaneMask pMask; CapValue capval; TileTypeBitMask *mask, *resMask; NodeRegion *reg; Tile *tp; TileType type, t, residue, tres; NodeRegion *old; Rect r; PlaneAndArea pla; if (IsSplit(tile)) { type = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile); if (type == TT_SPACE) return 0; /* Should not happen */ } /* Compute the resistance for the previous region */ if (old = (NodeRegion *) arg->fra_region) if (ExtOptions & EXT_DORESISTANCE) extSetResist(old); /* Allocate a new node */ nclasses = ExtCurStyle->exts_numResistClasses; n = sizeof (NodeRegion) + (sizeof (PerimArea) * (nclasses - 1)); reg = (NodeRegion *) mallocMagic((unsigned) n); reg->nreg_labels = (LabelList *) NULL; reg->nreg_cap = (CapValue) 0; reg->nreg_resist = 0; reg->nreg_pnum = DBNumPlanes; reg->nreg_next = (NodeRegion *) NULL; for (n = 0; n < nclasses; n++) reg->nreg_pa[n].pa_perim = reg->nreg_pa[n].pa_area = 0; /* Prepend the new node to the region list */ reg->nreg_next = (NodeRegion *) arg->fra_region; arg->fra_region = (Region *) reg; /* Mark this tile as pending and push it */ PUSHTILE(tile, arg->fra_pNum); /* Continue processing tiles until there are none left */ while (!StackEmpty(extNodeStack)) { POPTILE(tile, tilePlaneNum); /* * Since tile was pushed on the stack, we know that it * belongs to this region. Check to see that it hasn't * been visited in the meantime. If it's still unvisited, * visit it and process its neighbors. */ if (tile->ti_client == (ClientData) reg) continue; tile->ti_client = (ClientData) reg; if (DebugIsSet(extDebugID, extDebNeighbor)) extShowTile(tile, "neighbor", 1); if (IsSplit(tile)) { type = (SplitSide(tile)) ? SplitRightType(tile): SplitLeftType(tile); } else type = TiGetTypeExact(tile); /* Contacts are replaced by their residues when calculating */ /* area/perimeter capacitance and resistance. */ residue = (DBIsContact(type)) ? DBPlaneToResidue(type, tilePlaneNum) : type; mask = &ExtCurStyle->exts_nodeConn[type]; resMask = &ExtCurStyle->exts_typesResistChanged[residue]; resistClass = ExtCurStyle->exts_typeToResistClass[residue]; /* * Make sure the lower-leftmost point in the node is * kept up to date, so we can generate an internal * node name that does not depend on any other nodes * in this cell. */ extSetNodeNum((LabRegion *) reg, tilePlaneNum, tile); /* * Keep track of the total area of this node, and the * contribution to parasitic ground capacitance resulting * from area. */ if (extNodeClipArea) { TITORECT(tile, &r); GEOCLIP(&r, extNodeClipArea); area = (r.r_xtop - r.r_xbot) * (r.r_ytop - r.r_ybot); } else area = TILEAREA(tile); if (IsSplit(tile)) area /= 2; /* Split tiles are 1/2 area! */ if (resistClass != -1) extResistArea[resistClass] += area; reg->nreg_cap += area * ExtCurStyle->exts_areaCap[residue]; /* Compute perimeter of nonManhattan edges */ if (IsSplit(tile)) { len = ((RIGHT(tile) - LEFT(tile)) * (RIGHT(tile) - LEFT(tile))) + ((TOP(tile) - BOTTOM(tile)) * (TOP(tile) - BOTTOM(tile))); len = (int)sqrt((double)len); if (extNodeClipArea) { /* To-do: Find perimeter length of clipped edge */ } /* Find the type on the other side of the tile */ t = (SplitSide(tile)) ? SplitLeftType(tile): SplitRightType(tile); tres = (DBIsContact(t)) ? DBPlaneToResidue(t, tilePlaneNum) : t; if ((capval = ExtCurStyle->exts_perimCap[residue][tres]) != (CapValue) 0) reg->nreg_cap += capval * len; if (TTMaskHasType(resMask, tres) && resistClass != -1) extResistPerim[resistClass] += len; } /* * Walk along all four sides of tile. * Sum perimeter capacitance as we go. * Keep track of the contribution to the total perimeter * of this node, for computing resistance. */ /* Top */ topside: if (IsSplit(tile) && (SplitSide(tile) ^ SplitDirection(tile))) goto leftside; for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp)) { if (extNodeClipArea) { r.r_ybot = r.r_ytop = TOP(tile); r.r_xtop = MIN(RIGHT(tile), RIGHT(tp)); r.r_xbot = MAX(LEFT(tile), LEFT(tp)); GEOCLIP(&r, extNodeClipArea); len = EDGENULL(&r) ? 0 : r.r_xtop - r.r_xbot; } else len = MIN(RIGHT(tile), RIGHT(tp)) - MAX(LEFT(tile), LEFT(tp)); if (IsSplit(tp)) { t = SplitBottomType(tp); if (tp->ti_client == extUnInit && TTMaskHasType(mask, t)) { PUSHTILEBOTTOM(tp, tilePlaneNum); } else if (tp->ti_client != (ClientData)reg && TTMaskHasType(mask, t)) { /* Count split tile twice, once for each node it belongs to. */ tp->ti_client = extUnInit; PUSHTILEBOTTOM(tp, tilePlaneNum); } } else { t = TiGetTypeExact(tp); if (tp->ti_client == extUnInit && TTMaskHasType(mask, t)) { PUSHTILE(tp, tilePlaneNum); } } tres = (DBIsContact(t)) ? DBPlaneToResidue(t, tilePlaneNum) : t; if ((capval = ExtCurStyle->exts_perimCap[residue][tres]) != (CapValue) 0) reg->nreg_cap += capval * len; if (TTMaskHasType(resMask, tres) && resistClass != -1) extResistPerim[resistClass] += len; } /* Left */ leftside: if (IsSplit(tile) && SplitSide(tile)) goto bottomside; for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp)) { if (extNodeClipArea) { r.r_xbot = r.r_xtop = LEFT(tile); r.r_ytop = MIN(TOP(tile), TOP(tp)); r.r_ybot = MAX(BOTTOM(tile), BOTTOM(tp)); GEOCLIP(&r, extNodeClipArea); len = EDGENULL(&r) ? 0 : r.r_ytop - r.r_ybot; } else len = MIN(TOP(tile), TOP(tp)) - MAX(BOTTOM(tile), BOTTOM(tp)); if (IsSplit(tp)) { t = SplitRightType(tp); if (tp->ti_client == extUnInit && TTMaskHasType(mask, t)) { PUSHTILERIGHT(tp, tilePlaneNum); } else if (tp->ti_client != (ClientData)reg && TTMaskHasType(mask, t)) { /* Count split tile twice, once for each node it belongs to. */ tp->ti_client = extUnInit; PUSHTILERIGHT(tp, tilePlaneNum); } } else { t = TiGetTypeExact(tp); if (tp->ti_client == extUnInit && TTMaskHasType(mask, t)) { PUSHTILE(tp, tilePlaneNum); } } tres = (DBIsContact(t)) ? DBPlaneToResidue(t, tilePlaneNum) : t; if ((capval = ExtCurStyle->exts_perimCap[residue][tres]) != (CapValue) 0) reg->nreg_cap += capval * len; if (TTMaskHasType(resMask, tres) && resistClass != -1) extResistPerim[resistClass] += len; } /* Bottom */ bottomside: if (IsSplit(tile) && (!(SplitSide(tile) ^ SplitDirection(tile)))) goto rightside; for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp)) { if (extNodeClipArea) { r.r_ybot = r.r_ytop = BOTTOM(tile); r.r_xtop = MIN(RIGHT(tile), RIGHT(tp)); r.r_xbot = MAX(LEFT(tile), LEFT(tp)); GEOCLIP(&r, extNodeClipArea); len = EDGENULL(&r) ? 0 : r.r_xtop - r.r_xbot; } else len = MIN(RIGHT(tile), RIGHT(tp)) - MAX(LEFT(tile), LEFT(tp)); if (IsSplit(tp)) { t = SplitTopType(tp); if (tp->ti_client == extUnInit && TTMaskHasType(mask, t)) { PUSHTILETOP(tp, tilePlaneNum); } else if (tp->ti_client != (ClientData)reg && TTMaskHasType(mask, t)) { /* Count split tile twice, once for each node it belongs to. */ tp->ti_client = extUnInit; PUSHTILETOP(tp, tilePlaneNum); } } else { t = TiGetTypeExact(tp); if (tp->ti_client == extUnInit && TTMaskHasType(mask, t)) { PUSHTILE(tp, tilePlaneNum); } } tres = (DBIsContact(t)) ? DBPlaneToResidue(t, tilePlaneNum) : t; if ((capval = ExtCurStyle->exts_perimCap[residue][tres]) != (CapValue) 0) reg->nreg_cap += capval * len; if (TTMaskHasType(resMask, tres) && resistClass != -1) extResistPerim[resistClass] += len; } /* Right */ rightside: if (IsSplit(tile) && !SplitSide(tile)) goto donesides; for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp)) { if (extNodeClipArea) { r.r_xbot = r.r_xtop = RIGHT(tile); r.r_ytop = MIN(TOP(tile), TOP(tp)); r.r_ybot = MAX(BOTTOM(tile), BOTTOM(tp)); GEOCLIP(&r, extNodeClipArea); len = EDGENULL(&r) ? 0 : r.r_ytop - r.r_ybot; } else len = MIN(TOP(tile), TOP(tp)) - MAX(BOTTOM(tile), BOTTOM(tp)); if (IsSplit(tp)) { t = SplitLeftType(tp); if (tp->ti_client == extUnInit && TTMaskHasType(mask, t)) { PUSHTILELEFT(tp, tilePlaneNum); } else if (tp->ti_client != (ClientData)reg && TTMaskHasType(mask, t)) { /* Count split tile twice, once for each node it belongs to */ tp->ti_client = extUnInit; PUSHTILELEFT(tp, tilePlaneNum); } } else { t = TiGetTypeExact(tp); if (tp->ti_client == extUnInit && TTMaskHasType(mask, t)) { PUSHTILE(tp, tilePlaneNum); } } tres = (DBIsContact(t)) ? DBPlaneToResidue(t, tilePlaneNum) : t; if ((capval = ExtCurStyle->exts_perimCap[residue][tres]) != (CapValue) 0) reg->nreg_cap += capval * len; if (TTMaskHasType(resMask, tres) && resistClass != -1) extResistPerim[resistClass] += len; } donesides: /* No capacitance */ if ((ExtOptions & EXT_DOCAPACITANCE) == 0) reg->nreg_cap = (CapValue) 0; /* If this is a contact, visit all the other planes */ if (DBIsContact(type)) { pMask = DBConnPlanes[type]; pMask &= ~(PlaneNumToMaskBit(tilePlaneNum)); for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) if (PlaneMaskHasPlane(pMask, pNum)) { Plane *plane = arg->fra_def->cd_planes[pNum]; tp = plane->pl_hint; GOTOPOINT(tp, &tile->ti_ll); plane->pl_hint = tp; if (tp->ti_client != extUnInit) continue; /* tp and tile should have the same geometry for a contact */ if (IsSplit(tile) && IsSplit(tp)) { if (SplitSide(tile)) { t = SplitRightType(tp); if (TTMaskHasType(mask, t)) { PUSHTILERIGHT(tp, pNum); } } else { t = SplitLeftType(tp); if (TTMaskHasType(mask, t)) { PUSHTILELEFT(tp, pNum); } } } else if (IsSplit(tp)) { /* Need to test both sides of the tile */ t = SplitRightType(tp); if (TTMaskHasType(mask, t)) { PUSHTILERIGHT(tp, pNum); } t = SplitLeftType(tp); if (TTMaskHasType(mask, t)) { PUSHTILELEFT(tp, pNum); } } else { t = TiGetTypeExact(tp); if (TTMaskHasType(mask, t)) { PUSHTILE(tp, pNum); } } } } /* * The hairiest case is when this type connects to stuff on * other planes, but isn't itself connected as a contact. * For example, a CMOS pwell connects to diffusion of the * same doping (p substrate diff). In a case like this, * we need to search the entire AREA of the tile plus a * 1-lambda halo to find everything it overlaps or touches * on the other plane. */ if (pMask = DBAllConnPlanes[type]) { Rect biggerArea; bool is_split = IsSplit(tile); extNbrUn = extUnInit; TITORECT(tile, &pla.area); GEO_EXPAND(&pla.area, 1, &biggerArea); for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) if ((pNum != tilePlaneNum) && PlaneMaskHasPlane(pMask, pNum)) { pla.plane = pNum; if (is_split) DBSrPaintNMArea((Tile *) NULL, arg->fra_def->cd_planes[pNum], TiGetTypeExact(tile) & (TT_DIAGONAL | TT_SIDE | TT_DIRECTION), &biggerArea, mask, extNbrPushFunc, (ClientData) &pla); else DBSrPaintArea((Tile *) NULL, arg->fra_def->cd_planes[pNum], &biggerArea, mask, extNbrPushFunc, (ClientData) &pla); } } } return (0); } /* * ---------------------------------------------------------------------------- * * extGetCapValue -- * extSetCapValue -- * * Procedures to get/set a value from our capacitance tables. * * ---------------------------------------------------------------------------- */ void extSetCapValue(he, value) HashEntry *he; CapValue value; { if (HashGetValue(he) == NULL) HashSetValue(he, (CapValue *) mallocMagic(sizeof(CapValue))); *( (CapValue *) HashGetValue(he)) = value; } CapValue extGetCapValue(he) HashEntry *he; { if (HashGetValue(he) == NULL) extSetCapValue(he, (CapValue) 0); return *( (CapValue *) HashGetValue(he)); } /* * ---------------------------------------------------------------------------- * * extCapHashKill -- * * Kill off a coupling capacitance hash table. * * Results: * None. * * Side effects: * Frees up storage in the table. * ---------------------------------------------------------------------------- */ void extCapHashKill(ht) HashTable *ht; { HashSearch hs; HashEntry *he; HashStartSearch(&hs); while (he = HashNext(ht, &hs)) { if (HashGetValue(he) != NULL) { freeMagic(HashGetValue(he)); /* Free a malloc'ed CapValue */ HashSetValue(he, (ClientData) NULL); } } HashKill(ht); } magic-8.0.210/extract/ExtCouple.c0000644000175000001440000010012111410650575015177 0ustar timusers/* * ExtCouple.c -- * * Circuit extraction. * Extraction of coupling capacitance. * * ********************************************************************* * * 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/extract/ExtCouple.c,v 1.2 2010/06/24 12:37:17 tim Exp $"; #endif /* not lint */ #include #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 "extract/extract.h" #include "extract/extractInt.h" /* --------------------- Data local to this file ---------------------- */ /* Pointer to hash table currently being updated with coupling capacitance */ HashTable *extCoupleHashPtr; /* Clipping area for coupling searches */ Rect *extCoupleSearchArea; /* Current list of sidewall capacitance rules */ EdgeCap *extCoupleList; EdgeCap *extOverlapList; /* Def being processed */ CellDef *extOverlapDef; /* Forward procedure declarations */ int extBasicOverlap(), extBasicCouple(); int extAddOverlap(), extAddCouple(); int extSideLeft(), extSideRight(), extSideBottom(), extSideTop(); int extSideOverlap(); void extSideCommon(); /* Structure to pass on to the coupling and sidewall capacitance */ /* routines to include the current cell definition and the current */ /* plane being searched. */ typedef struct _ecs { CellDef *def; int plane; } extCapStruct; /* Structure to pass on two planes to check for coupling and the tile */ /* which is doing the coupling. */ typedef struct _ecpls { Tile *tile; int plane_of_tile; int plane_checked; } extCoupleStruct; /* Structure to pass on two planes to check for coupling and the */ /* boundary which initiated the check. */ typedef struct _esws { Boundary *bp; int plane_of_boundary; int plane_checked; } extSidewallStruct; /* --------------------- Debugging stuff ---------------------- */ #define CAP_DEBUG FALSE void extNregAdjustCap(nr, c, str) NodeRegion *nr; CapValue c; char *str; { char *name; name = extNodeName((LabRegion *) nr); fprintf(stderr, "CapDebug: %s += %f (%s)\n", name, c, str); } void extAdjustCouple(he, c, str) HashEntry *he; CapValue c; char *str; { char *name1; char *name2; CoupleKey *ck; ck = (CoupleKey *) he->h_key.h_words; name1 = extNodeName((LabRegion *) ck->ck_1); name2 = extNodeName((LabRegion *) ck->ck_2); fprintf(stderr, "CapDebug: %s-%s += %f (%s)\n", name1, name2, c, str); } /* * ---------------------------------------------------------------------------- * * extFindCoupling -- * * Find the coupling capacitances in the cell def. Such capacitances * arise from three causes: * * Overlap. When two tiles on different planes overlap, they * may have a coupling capacitance proportional to * their areas. If this is so, we subtract the substrate * capacitance of the overlapped type, and add the overlap * capacitance to the coupling hash table. * * Sidewall. When tiles on the same plane are adjacent, they may * have a coupling capacitance proportional to the * length of their edges, divided by the distance between * them. In this case, we just add the sidewall coupling * capacitance to the hash table. * * Sidewall * overlap. When the edge of a tile on one plane overlaps a tile * on a different plane, the two tiles may have a coupling * capacitance proportional to the length of the overlapping * edge. In this case we add the coupling capacitance to the * hash table. (We may want to deduct the perimeter capacitance * to substrate?). * * Requires that ExtFindRegions has been run on 'def' to label all its * tiles with NodeRegions. Also requires that the HashTable 'table' * has been initialized by the caller. * * If 'clipArea' is non-NULL, search for overlap capacitance only inside * the area *clipArea. Search for sidewall capacitance only from tiles * inside *clipArea, although this capacitance may be to tiles outside * *clipArea. * * Results: * None. * * Side effects: * When done, the HashTable 'table' will have been filled * in with an entry for each pair of nodes having coupling * capacitance. Each entry will have a two-word key organized * as an CoupleKey struct, with ck_1 and ck_2 pointing to the * coupled nodes. The value of the hash entry will be the * coupling capacitance between that pair of nodes. * * ---------------------------------------------------------------------------- */ void extFindCoupling(def, table, clipArea) CellDef *def; HashTable *table; Rect *clipArea; { Rect *searchArea; int pNum; extCapStruct ecs; ecs.def = def; extCoupleHashPtr = table; extCoupleSearchArea = clipArea; searchArea = clipArea ? clipArea : &TiPlaneRect; for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) { ecs.plane = pNum; if (PlaneMaskHasPlane(ExtCurStyle->exts_overlapPlanes, pNum)) (void) DBSrPaintArea((Tile *) NULL, def->cd_planes[pNum], searchArea, &ExtCurStyle->exts_overlapTypes[pNum], extBasicOverlap, (ClientData) &ecs); if (PlaneMaskHasPlane(ExtCurStyle->exts_sidePlanes, pNum)) (void) DBSrPaintArea((Tile *) NULL, def->cd_planes[pNum], searchArea, &ExtCurStyle->exts_sideTypes[pNum], extBasicCouple, (ClientData) &ecs); } } /* * ---------------------------------------------------------------------------- * * extOutputCoupling -- * * Output the coupling capacitance table built up by extFindCoupling(). * Each entry in the hash table is a capacitance between the pair of * nodes identified by he->h_key, an CoupleKey struct. * * ExtFindRegions and ExtLabelRegions should have been called prior * to this procedure. * * Results: * None. * * Side effects: * See the comments above. * * ---------------------------------------------------------------------------- */ void extOutputCoupling(table, outFile) HashTable *table; /* Coupling capacitance hash table */ FILE *outFile; /* Output file */ { HashEntry *he; CoupleKey *ck; HashSearch hs; char *text; CapValue cap; /* value of capacitance. */ HashStartSearch(&hs); while (he = HashNext(table, &hs)) { cap = extGetCapValue(he) / ExtCurStyle->exts_capScale; if (cap == 0) continue; ck = (CoupleKey *) he->h_key.h_words; text = extNodeName((LabRegion *) ck->ck_1); fprintf(outFile, "cap \"%s\" ", text); text = extNodeName((LabRegion *) ck->ck_2); fprintf(outFile, "\"%s\" %lg\n", text, cap); } } /* * ---------------------------------------------------------------------------- * * extBasicOverlap -- * * Filter function for overlap capacitance. * Called for each tile that might have coupling capacitance * to another node because it overlaps a tile or tiles in that * node. Causes an area search over the area of 'tile' in all * planes to which 'tile' has overlap capacitance, for any tiles * to which 'tile' has overlap capacitance. * * Results: * Returns 0 to keep DBSrPaintArea() going. * * Side effects: * See extAddOverlap(). * * ---------------------------------------------------------------------------- */ int extBasicOverlap(tile, ecs) Tile *tile; extCapStruct *ecs; { int thisType; int pNum; PlaneMask pMask; TileTypeBitMask *tMask; Rect r; CellDef *def = ecs->def; int thisPlane = ecs->plane; extCoupleStruct ecpls; if (IsSplit(tile)) thisType = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile); else thisType = TiGetTypeExact(tile); if (DBIsContact(thisType)) thisType = DBPlaneToResidue(thisType, thisPlane); pMask = ExtCurStyle->exts_overlapOtherPlanes[thisType]; tMask = &ExtCurStyle->exts_overlapOtherTypes[thisType]; TITORECT(tile, &r); extOverlapDef = def; if (extCoupleSearchArea) { GEOCLIP(&r, extCoupleSearchArea); } ecpls.tile = tile; ecpls.plane_of_tile = thisPlane; for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) { /* Skip if nothing interesting on the other plane */ if (pNum == thisPlane || !PlaneMaskHasPlane(pMask, pNum)) continue; ecpls.plane_checked = pNum; (void) DBSrPaintArea((Tile *) NULL, def->cd_planes[pNum], &r, tMask, extAddOverlap, (ClientData) &ecpls); } return (0); } /* * ---------------------------------------------------------------------------- * * extAddOverlap -- * * We are called for each tile that is overlapped by the tile passed to * extBasicOverlap() above (our argument 'tabove'). The intent is that * 'tbelow' actually shields 'tabove' from the substrate, so we should * replace node(tabove)'s capacitance to substrate with a capacitance * to node(tbelow) whose size is proportional to the area of the overlap. * * We check to insure that tabove is not shielded from tbelow by any * intervening material; if it is, we deduct the capacitance between * node(tabove) and node(tbelow) for the area of the overlap. * * Results: * Returns 0 to keep DBSrPaintArea() going. * * Side effects: * Updates the HashEntry with key node(tbelow), node(tabove) * by adding the capacitance of the overlap if node(tbelow) * and node(tabove) are different, and if they are not totally * shielded by intervening material. Also subtracts the capacitance * to substrate from node(tabove) for the area of the overlap. * If node(tbelow) and node(tabove) are the same, we do nothing. * * ---------------------------------------------------------------------------- */ struct overlap { Rect o_clip; int o_area; PlaneMask o_pmask; TileTypeBitMask o_tmask; }; int extAddOverlap(tbelow, ecpls) Tile *tbelow; extCoupleStruct *ecpls; { int extSubtractOverlap(), extSubtractOverlap2(); NodeRegion *rabove, *rbelow; HashEntry *he; struct overlap ov; TileType ta, tb; CoupleKey ck; int pNum; CapValue c; Tile *tabove = ecpls->tile; /* Check if both tiles are connected. If they are, we don't need */ /* to check for shielding material, and we don't want to add any */ /* coupling capacitance between them. However, we *do* want to */ /* subtract off any substrate (area) capacitance previously added */ /* (Correction made 4/29/04 by Tim from a tip by Jeff Sondeen). */ rabove = (NodeRegion *) extGetRegion(tabove); rbelow = (NodeRegion *) extGetRegion(tbelow); /* Compute the area of overlap */ ov.o_clip.r_xbot = MAX(LEFT(tbelow), LEFT(tabove)); ov.o_clip.r_xtop = MIN(RIGHT(tbelow), RIGHT(tabove)); ov.o_clip.r_ybot = MAX(BOTTOM(tbelow), BOTTOM(tabove)); ov.o_clip.r_ytop = MIN(TOP(tbelow), TOP(tabove)); if (extCoupleSearchArea) { GEOCLIP(&ov.o_clip, extCoupleSearchArea); } ov.o_area = (ov.o_clip.r_ytop - ov.o_clip.r_ybot) * (ov.o_clip.r_xtop - ov.o_clip.r_xbot); ta = TiGetType(tabove); tb = TiGetType(tbelow); /* Revert any contacts to their residues */ if (DBIsContact(ta)) ta = DBPlaneToResidue(ta, ecpls->plane_of_tile); if (DBIsContact(tb)) tb = DBPlaneToResidue(tb, ecpls->plane_checked); /* * Find whether rabove and rbelow are shielded by intervening material. * Deduct the area shielded from the area of the overlap, so we adjust * the overlap capacitance correspondingly. */ if (ov.o_pmask = ExtCurStyle->exts_overlapShieldPlanes[ta][tb]) { ov.o_tmask = ExtCurStyle->exts_overlapShieldTypes[ta][tb]; for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) { if (!PlaneMaskHasPlane(ov.o_pmask, pNum)) continue; ov.o_pmask &= ~(PlaneNumToMaskBit(pNum)); if (ov.o_pmask == 0) { (void) DBSrPaintArea((Tile *) NULL, extOverlapDef->cd_planes[pNum], &ov.o_clip, &ov.o_tmask, extSubtractOverlap, (ClientData) &ov); } else { (void) DBSrPaintArea((Tile *) NULL, extOverlapDef->cd_planes[pNum], &ov.o_clip, &DBAllTypeBits, extSubtractOverlap2, (ClientData) &ov); } break; } } /* If any capacitance remains, add this record to the table */ if (ov.o_area > 0) { int oa = ExtCurStyle->exts_planeOrder[ecpls->plane_of_tile]; int ob = ExtCurStyle->exts_planeOrder[ecpls->plane_checked]; if (oa > ob) { /* * Subtract the substrate capacitance from tabove's region due to * the area of the overlap, minus any shielded area. The shielded * areas get handled later, when processing coupling between tabove * and the shielding tile. (Tabove was the overlapping tile, so it * is shielded from the substrate by tbelow if the Tabove plane is * above the Tbelow plane). */ rabove->nreg_cap -= ExtCurStyle->exts_areaCap[ta] * ov.o_area; if (CAP_DEBUG) extNregAdjustCap(rabove, -(ExtCurStyle->exts_areaCap[ta] * ov.o_area), "obsolete_overlap"); } else if (CAP_DEBUG) extNregAdjustCap(rabove, 0.0, "obsolete_overlap (skipped, wrong direction)"); /* If the regions are the same, skip this part */ if (rabove == rbelow) return (0); /* Find the coupling hash record */ if (rabove < rbelow) ck.ck_1 = rabove, ck.ck_2 = rbelow; else ck.ck_1 = rbelow, ck.ck_2 = rabove; he = HashFind(extCoupleHashPtr, (char *) &ck); /* Add the overlap capacitance to the table */ c = extGetCapValue(he); c += ExtCurStyle->exts_overlapCap[ta][tb] * ov.o_area; if (CAP_DEBUG) extAdjustCouple(he, ExtCurStyle->exts_overlapCap[ta][tb] * ov.o_area, "overlap"); extSetCapValue(he, c); } return (0); } int extSubtractOverlap(tile, ov) Tile *tile; struct overlap *ov; { Rect r; int area; TITORECT(tile, &r); GEOCLIP(&r, &ov->o_clip); area = (r.r_xtop - r.r_xbot) * (r.r_ytop - r.r_ybot); if (area > 0) ov->o_area -= area; return (0); } int extSubtractOverlap2(tile, ov) Tile *tile; struct overlap *ov; { struct overlap ovnew; int area, pNum; Rect r; TITORECT(tile, &r); GEOCLIP(&r, &ov->o_clip); area = (r.r_xtop - r.r_xbot) * (r.r_ytop - r.r_ybot); if (area <= 0) return (0); /* This tile shields everything below */ if (TTMaskHasType(&ov->o_tmask, TiGetType(tile))) { ov->o_area -= area; return (0); } /* Tile doesn't shield, so search next plane */ ovnew = *ov; ovnew.o_clip = r; for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) { if (!PlaneMaskHasPlane(ovnew.o_pmask, pNum)) continue; ovnew.o_pmask &= ~(PlaneNumToMaskBit(pNum)); if (ovnew.o_pmask == 0) { (void) DBSrPaintArea((Tile *) NULL, extOverlapDef->cd_planes[pNum], &ovnew.o_clip, &ovnew.o_tmask, extSubtractOverlap, (ClientData) &ovnew); } else { (void) DBSrPaintArea((Tile *) NULL, extOverlapDef->cd_planes[pNum], &ovnew.o_clip, &DBAllTypeBits, extSubtractOverlap2, (ClientData) &ovnew); } break; } ov->o_area = ovnew.o_area; return (0); } /* * ---------------------------------------------------------------------------- * * extBasicCouple -- * * Filter function for sidewall coupling capacitance. * Called for each tile that might have coupling capacitance * to another node because it is near tiles on the same plane, * or because its edge overlaps tiles on a different plane. * * Causes an area search over a halo surrounding each edge of * 'tile' for edges to which each edge has coupling capacitance * on this plane, and a search for tiles on different planes that * this edge overlaps. * * Results: * Returns 0 to keep DBSrPaintArea() going. * * Side effects: * See extAddCouple(). * * ---------------------------------------------------------------------------- */ int extBasicCouple(tile, ecs) Tile *tile; extCapStruct *ecs; { (void) extEnumTilePerim(tile, ExtCurStyle->exts_sideEdges[TiGetType(tile)], ecs->plane, extAddCouple, (ClientData) ecs); return (0); } /* * ---------------------------------------------------------------------------- * * extAddCouple -- * * Called for each segment along the boundary of the tile bp->b_inside * that might have coupling capacitance with its neighbors. * Causes an area search over a halo surrounding the boundary bp->b_segment * on the side outside bp->b_inside for edges to which this one has coupling * capacitance on this plane, and for tiles overlapping this edge on different * planes. * * Results: * Returns 0 to keep DBSrPaintArea() going. * * Side effects: * For each edge (tnear, tfar) we find that has coupling capacitance * to us, update the HashEntry with key node(bp->b_inside), node(tfar) * by adding the sidewall capacitance if node(bp->b_inside) and node(tfar) * are different. If node(bp->b_inside) and node(tfar) are the same, we * do nothing. * * For each tile tp we find on a different plane that overlaps this * edge, update the HashEntry with key node(bp->b_inside), node(tp) * by adding the sidewall overlap capacitance. If node(bp->b_inside) * and node(tp) are the same, do nothing. * * ---------------------------------------------------------------------------- */ Rect extSideOverlapSearchArea; int extAddCouple(bp, ecs) Boundary *bp; /* Boundary being considered */ extCapStruct *ecs; { TileType tin = TiGetType(bp->b_inside), tout = TiGetType(bp->b_outside); int pNum; PlaneMask pMask; int (*proc)(); Boundary bpCopy; Rect r, ovr; CellDef *def = ecs->def; extSidewallStruct esws; /* Revert any edge contacts to their residues */ if (DBIsContact(tin)) tin = DBPlaneToResidue(tin, ecs->plane); if (DBIsContact(tout)) tout = DBPlaneToResidue(tout, ecs->plane); extCoupleList = ExtCurStyle->exts_sideCoupleCap[tin][tout]; extOverlapList = ExtCurStyle->exts_sideOverlapCap[tin][tout]; if (extCoupleList == NULL && extOverlapList == NULL) return (0); /* * Clip the edge of interest to the area where we're searching * for coupling capacitance, if such an area has been specified. */ if (extCoupleSearchArea) { bpCopy = *bp; bp = &bpCopy; GEOCLIP(&bp->b_segment, extCoupleSearchArea); if (GEO_RECTNULL(&bp->b_segment)) return (0); } r = ovr = bp->b_segment; switch (bp->b_direction) { case BD_LEFT: /* Along left */ r.r_xbot -= ExtCurStyle->exts_sideCoupleHalo ; ovr.r_xbot -= 1; proc = extSideLeft; break; case BD_RIGHT: /* Along right */ r.r_xtop += ExtCurStyle->exts_sideCoupleHalo ; ovr.r_xtop += 1; proc = extSideRight; break; case BD_TOP: /* Along top */ r.r_ytop += ExtCurStyle->exts_sideCoupleHalo ; ovr.r_ytop += 1; proc = extSideTop; break; case BD_BOTTOM: /* Along bottom */ r.r_ybot -= ExtCurStyle->exts_sideCoupleHalo ; ovr.r_ybot -= 1; proc = extSideBottom; break; } if (extCoupleList) (void) DBSrPaintArea((Tile *) NULL, def->cd_planes[ecs->plane], &r, &ExtCurStyle->exts_sideCoupleOtherEdges[tin][tout], proc, (ClientData) bp); if (extOverlapList) { pMask = ExtCurStyle->exts_sideOverlapOtherPlanes[tin][tout]; extSideOverlapSearchArea = ovr; extOverlapDef = def; esws.bp = bp; esws.plane_of_boundary = ecs->plane; for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) if (PlaneMaskHasPlane(pMask, pNum)) { esws.plane_checked = pNum; (void) DBSrPaintArea((Tile *) NULL, def->cd_planes[pNum], &ovr, &ExtCurStyle->exts_sideOverlapOtherTypes[tin][tout], extSideOverlap, (ClientData) &esws); } } return (0); } /* * ---------------------------------------------------------------------------- * * extSideOverlap -- * * The boundary 'bp' has been found to overlap the tile 'tp', which it * has coupling capacitance to. * * Results: * Returns 0 to keep DBSrPaintArea() going. * * Side effects: * Update the coupling capacitance between node(bp->t_inside) and * node(tp) if the two nodes are different. Does so by updating * the value stored in the HashEntry keyed by the two nodes. * * ---------------------------------------------------------------------------- */ int extSideOverlap(tp, esws) Tile *tp; /* Overlapped tile */ extSidewallStruct *esws; /* Overlapping edge and plane information */ { Boundary *bp = esws->bp; /* Overlapping edge */ NodeRegion *rtp = (NodeRegion *) extGetRegion(tp); NodeRegion *rbp = (NodeRegion *) extGetRegion(bp->b_inside); TileType ta, tb; Rect tpr; struct overlap ov; HashEntry *he; EdgeCap *e; int length, areaAccountedFor; CapValue cap; CoupleKey ck; if (bp->b_segment.r_xtop == bp->b_segment.r_xbot) { length = MIN(bp->b_segment.r_ytop, TOP(tp)) - MAX(bp->b_segment.r_ybot, BOTTOM(tp)); } else { length = MIN(bp->b_segment.r_xtop, RIGHT(tp)) - MAX(bp->b_segment.r_xbot, LEFT(tp)); } TITORECT(tp, &ov.o_clip); GEOCLIP(&ov.o_clip, &extSideOverlapSearchArea); ov.o_area = length; areaAccountedFor = 0; ASSERT(length == GEO_WIDTH(&ov.o_clip) * GEO_HEIGHT(&ov.o_clip), "extSideOverlap"); ta = TiGetType(bp->b_inside); tb = TiGetType(tp); /* Avoid doing the code below if we're just going to return without */ /* changing anything. */ if ((tb == TT_SPACE) && (rtp == rbp)) return (0); /* Revert any contacts to their residues */ if (DBIsContact(ta)) ta = DBPlaneToResidue(ta, esws->plane_of_boundary); if (DBIsContact(tb)) tb = DBPlaneToResidue(tb, esws->plane_checked); /* Apply each rule, incorporating shielding into the edge length. */ cap = (CapValue) 0; for (e = extOverlapList; e; e = e->ec_next) { /* Only apply rules for the plane in which they are declared */ if (!PlaneMaskHasPlane(e->ec_pmask, esws->plane_checked)) continue; /* Does this rule "e" include the tile we found? */ if (TTMaskHasType(&e->ec_near, TiGetType(tp))) { /* We have a possible capacitor, but are the tiles shielded from * each other part of the way? */ int pNum; ov.o_area = length; ov.o_pmask = ExtCurStyle->exts_sideOverlapShieldPlanes[ta][tb]; if (ov.o_pmask) { ov.o_tmask = e->ec_far; /* Actually shieldtypes. */ for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) { /* Each call to DBSrPaintArea has an opportunity to * subtract from the area (really length 'cause width=1. */ if (!PlaneMaskHasPlane(ov.o_pmask, pNum)) continue; ov.o_pmask &= ~(PlaneNumToMaskBit(pNum)); if (ov.o_pmask == 0) { (void) DBSrPaintArea((Tile *) NULL, extOverlapDef->cd_planes[pNum], &ov.o_clip, &ov.o_tmask, extSubtractOverlap, (ClientData) &ov); } else { (void) DBSrPaintArea((Tile *) NULL, extOverlapDef->cd_planes[pNum], &ov.o_clip, &DBAllTypeBits, extSubtractOverlap2, (ClientData) &ov); } break; } } if (rtp != rbp) cap += e->ec_cap * ov.o_area; areaAccountedFor += ov.o_area; } } /* Add in the new capacitance. */ if (tb == TT_SPACE) { /* Is tp a space tile? If so, extGetRegion points to garbage; * make terminal 2 point to ground. */ rbp->nreg_cap += cap; if (CAP_DEBUG) extNregAdjustCap(rbp, cap, "sideoverlap_to_subs"); } else { int oa = ExtCurStyle->exts_planeOrder[esws->plane_of_boundary]; int ob = ExtCurStyle->exts_planeOrder[esws->plane_checked]; if (oa > ob) { /* If the overlapped tile is between the substrate and the boundary * tile, then we subtract the fringe substrate capacitance * from rbp's region due to the area of the sideoverlap, since * we now know it is shielded from the substrate. */ CapValue subcap; TileType outtype = TiGetType(bp->b_outside); /* Decompose contacts into their residues */ if (DBIsContact(ta)) ta = DBPlaneToResidue(ta, esws->plane_of_boundary); if (DBIsContact(outtype)) outtype = DBPlaneToResidue(outtype, esws->plane_of_boundary); subcap = (ExtCurStyle->exts_perimCap[ta][outtype] * MIN(areaAccountedFor, length)); rbp->nreg_cap -= subcap; if (CAP_DEBUG) extNregAdjustCap(rbp, -subcap, "obsolete_perimcap"); } else if (CAP_DEBUG) extNregAdjustCap(rbp, 0.0, "obsolete_perimcap (skipped, wrong direction)"); /* If the nodes are electrically connected, then we don't add */ /* any side overlap capacitance to the node. */ if (rtp == rbp) return (0); if (rtp < rbp) ck.ck_1 = rtp, ck.ck_2 = rbp; else ck.ck_1 = rbp, ck.ck_2 = rtp; he = HashFind(extCoupleHashPtr, (char *) &ck); if (CAP_DEBUG) extAdjustCouple(he, cap, "sideoverlap"); extSetCapValue(he, cap + extGetCapValue(he)); } return (0); } /* * ---------------------------------------------------------------------------- * * extSideLeft -- * * Searching to the left of the boundary 'bp', we found the tile * 'tpfar' which may lie on the far side of an edge to which the * edge bp->b_inside | bp->b_outside has sidewall coupling capacitance. * * Walk along the right-hand side of 'tpfar' searching for such * edges, and recording their capacitance in the hash table * *extCoupleHashPtr. * * Results: * Returns 0 always. * * Side effects: * If node(tpfar) exists, and node(bp->b_inside) != node(tpfar), * search along the inside edge of tpfar (the one closest to * the boundary bp) for edges having capacitance with bp. For * each such edge found, update the entry in *extCoupleHashPtr * identified by node(bp->b_inside) and node(tpfar) by adding * the capacitance due to the adjacency of the pair of edges. * * ---------------------------------------------------------------------------- */ int extSideLeft(tpfar, bp) Tile *tpfar; Boundary *bp; { NodeRegion *rinside = (NodeRegion *) extGetRegion(bp->b_inside); NodeRegion *rfar = (NodeRegion *) extGetRegion(tpfar); Tile *tpnear; if (rfar != (NodeRegion *) extUnInit && rfar != rinside) { int sep = bp->b_segment.r_xbot - RIGHT(tpfar); int limit = MAX(bp->b_segment.r_ybot, BOTTOM(tpfar)); int start = MIN(bp->b_segment.r_ytop, TOP(tpfar)); for (tpnear = TR(tpfar); TOP(tpnear) > limit; tpnear = LB(tpnear)) { int overlap = MIN(TOP(tpnear), start) - MAX(BOTTOM(tpnear), limit); if (overlap > 0) extSideCommon(rinside, rfar, tpnear, tpfar, overlap, sep); } } return (0); } /* * ---------------------------------------------------------------------------- * * extSideRight -- * * Searching to the right of the boundary 'bp', we found the tile * 'tpfar' which may lie on the far side of an edge to which the * edge bp->b_inside | bp->b_outside has sidewall coupling capacitance. * * Walk along the left-hand side of 'tpfar' searching for such * edges, and recording their capacitance in the hash table * *extCoupleHashPtr. * * Results: * Returns 0 always. * * Side effects: * See extSideLeft. * * ---------------------------------------------------------------------------- */ int extSideRight(tpfar, bp) Tile *tpfar; Boundary *bp; { NodeRegion *rinside = (NodeRegion *) extGetRegion(bp->b_inside); NodeRegion *rfar = (NodeRegion *) extGetRegion(tpfar); Tile *tpnear; if (rfar != (NodeRegion *) extUnInit && rfar != rinside) { int sep = LEFT(tpfar) - bp->b_segment.r_xtop; int limit = MIN(bp->b_segment.r_ytop, TOP(tpfar)); int start = MAX(bp->b_segment.r_ybot, BOTTOM(tpfar)); for (tpnear = BL(tpfar); BOTTOM(tpnear) < limit; tpnear = RT(tpnear)) { int overlap = MIN(TOP(tpnear), limit) - MAX(BOTTOM(tpnear), start); if (overlap > 0) extSideCommon(rinside, rfar, tpnear, tpfar, overlap, sep); } } return (0); } /* * ---------------------------------------------------------------------------- * * extSideTop -- * * Searching to the top of the boundary 'bp', we found the tile * 'tpfar' which may lie on the far side of an edge to which the * edge bp->b_inside | bp->b_outside has sidewall coupling capacitance. * * Walk along the bottom side of 'tpfar' searching for such * edges, and recording their capacitance in the hash table * *extCoupleHashPtr. * * Results: * Returns 0 always. * * Side effects: * See extSideLeft. * * ---------------------------------------------------------------------------- */ int extSideTop(tpfar, bp) Tile *tpfar; Boundary *bp; { NodeRegion *rinside = (NodeRegion *) extGetRegion(bp->b_inside); NodeRegion *rfar = (NodeRegion *) extGetRegion(tpfar); Tile *tpnear; if (rfar != (NodeRegion *) extUnInit && rfar != rinside) { int sep = BOTTOM(tpfar) - bp->b_segment.r_ytop; int limit = MIN(bp->b_segment.r_xtop, RIGHT(tpfar)); int start = MAX(bp->b_segment.r_xbot, LEFT(tpfar)); for (tpnear = LB(tpfar); LEFT(tpnear) < limit; tpnear = TR(tpnear)) { int overlap = MIN(RIGHT(tpnear), limit) - MAX(LEFT(tpnear), start); if (overlap > 0) extSideCommon(rinside, rfar, tpnear, tpfar, overlap, sep); } } return (0); } /* * ---------------------------------------------------------------------------- * * extSideBottom -- * * Searching to the bottom of the boundary 'bp', we found the tile * 'tpfar' which may lie on the far side of an edge to which the * edge bp->b_inside | bp->b_outside has sidewall coupling capacitance. * * Walk along the top side of 'tpfar' searching for such * edges, and recording their capacitance in the hash table * *extCoupleHashPtr. * * Results: * Returns 0 always. * * Side effects: * See extSideLeft. * * ---------------------------------------------------------------------------- */ int extSideBottom(tpfar, bp) Tile *tpfar; Boundary *bp; { NodeRegion *rinside = (NodeRegion *) extGetRegion(bp->b_inside); NodeRegion *rfar = (NodeRegion *) extGetRegion(tpfar); Tile *tpnear; if (rfar != (NodeRegion *) extUnInit && rfar != rinside) { int sep = bp->b_segment.r_ybot - TOP(tpfar); int limit = MAX(bp->b_segment.r_xbot, LEFT(tpfar)); int start = MIN(bp->b_segment.r_xtop, RIGHT(tpfar)); for (tpnear = RT(tpfar); RIGHT(tpnear) > limit; tpnear = BL(tpnear)) { int overlap = MIN(RIGHT(tpnear), start) - MAX(LEFT(tpnear), limit); if (overlap > 0) extSideCommon(rinside, rfar, tpnear, tpfar, overlap, sep); } } return (0); } /* * ---------------------------------------------------------------------------- * * extSideCommon -- * * Perform the actual update to the hash table entry for * the regions 'rinside' and 'rfar'. We assume that neither * 'rinside' nor 'rfar' are extUnInit, and further that they * are not equal. * * Walk along the rules in extCoupleList, applying the appropriate * amount of capacitance for an edge with tpnear on the close side * and tpfar on the remote side. * * Results: * Returns 0 always. * * Side effects: * See extSideLeft. * * ---------------------------------------------------------------------------- */ void extSideCommon(rinside, rfar, tpnear, tpfar, overlap, sep) NodeRegion *rinside, *rfar; /* Both must be valid */ Tile *tpnear, *tpfar; /* Tiles on near and far side of edge */ int overlap, sep; /* Overlap of this edge with original one, * and distance between the two. */ { TileType near = TiGetType(tpnear), far = TiGetType(tpfar); HashEntry *he; EdgeCap *e; CoupleKey ck; CapValue cap; if (rinside < rfar) ck.ck_1 = rinside, ck.ck_2 = rfar; else ck.ck_1 = rfar, ck.ck_2 = rinside; he = HashFind(extCoupleHashPtr, (char *) &ck); cap = extGetCapValue(he); for (e = extCoupleList; e; e = e->ec_next) if (TTMaskHasType(&e->ec_near, near) && TTMaskHasType(&e->ec_far, far)) { cap += (e->ec_cap * overlap) / sep; if (CAP_DEBUG) extAdjustCouple(he, (e->ec_cap * overlap) / sep, "sidewall"); } extSetCapValue(he, cap); } magic-8.0.210/extract/extractInt.h.new0000644000175000001440000010750411020566166016224 0ustar timusers/* * extractInt.h -- * * Defines things shared internally by the extract module of Magic, * but not generally needed outside the extract module. * * rcsid "$Header: /usr/cvsroot/magic-8.0/extract/extractInt.h.new,v 1.2 2008/06/01 18:37:42 tim Exp $" * * ********************************************************************* * * 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. * * ********************************************************************* * * This module has been modified at DEC/WRL and Stanford University. * The above disclaimers apply. * */ #ifndef _EXTRACTINT_H #define _EXTRACTINT_H #include "database/database.h" #undef NT #define NT TT_MAXTYPES #undef NP #define NP PL_MAXTYPES /* ------------------------ Capacitance Values ------------------------- */ typedef double CapValue; /* No longer allowed to define back to integer, * as this touches too many parts of the code. */ /* Procs to manipulate capacitance hash tables. */ extern CapValue extGetCapValue(); extern void extSetCapValue(); extern void extCapHashKill(); typedef int ResValue; /* Warning: in some places resistances are stored * as ints. This is here for documentation only. */ /* -------------------------- Label lists ----------------------------- */ /* * List of labels for a node. * We keep around pointers to the entire labels for * later figuring out which are attached to the gates, * sources, or drains of transistors. */ typedef struct ll { Label *ll_label; /* Actual Label in the source CellDef */ struct ll *ll_next; /* Next LabelList in this region */ int ll_attr; /* Which terminal of a transistor this is * an attribute of. */ } LabelList; #define LL_NOATTR -1 /* Value for ll_attr above if the label is * not a transistor attribute. */ #define LL_GATEATTR -2 /* Value for ll_attr if the label is a gate * attribute, rather than one of the diffusion * terminals' attributes. */ #define LL_SORTATTR -3 /* value for ll_attr used in * ExtBasic.c/ExtSortTerminals() to swap * the attributes as well as the regions * -- Stefanos 5/96 */ #define LL_PORTATTR -4 /* value for ll_attr used to declare * the label to be a subcircuit port * -- Tim 5/02 */ /* * Types of labels. * These can be or'd into a mask and passed to extLabType(). */ #define LABTYPE_NAME 0x01 /* Normal node name */ #define LABTYPE_NODEATTR 0x02 /* Node attribute */ #define LABTYPE_GATEATTR 0x04 /* Transistor gate attribute */ #define LABTYPE_TERMATTR 0x08 /* Transistor terminal (source/drain) * attribute. */ #define LABTYPE_PORTATTR 0x10 /* Subcircuit port */ /* ----------------------------- Regions ------------------------------ */ /* * The following are the structures built up by the various * clients of ExtFindRegions. The general rule for these * structures is that their initial fields must be identical * to those in a Region, but subsequent fields are up to * the individual client. * * Regions marked as GENERIC are the types accepted by * procedures in ExtRegion.c. */ /* * GENERIC Region struct. * All this provides is a pointer to the next Region. * This is the type passed to functions like ExtFreeRegions, * and is the type returned by ExtFindRegions. Clients should * cast pointers of this type to their own, client type. */ typedef struct reg { struct reg *reg_next; /* Next region in list */ } Region; /* * GENERIC region with labels. * Any other structure that wants to reference node names * must include the same fields as this one as its first part. */ typedef struct lreg { struct lreg *lreg_next; /* Next region in list */ int lreg_pnum; /* Lowest numbered plane in this region */ int lreg_type; /* Type of tile that contains lreg_ll */ Point lreg_ll; /* Lower-leftmost point in this region on * plane lreg_pnum. We take the min first * in X, then in Y. */ LabelList *lreg_labels; /* List of labels for this region. These are * any labels connected to the geometry making * up this region. If the list is empty, make * up a name from lreg_pnum and lreg_ll. */ } LabRegion; /* * Node region: labelled region with resistance and capacitance. * Used for each node in the flat extraction of a cell. */ typedef struct { int pa_perim; int pa_area; } PerimArea; typedef struct nreg { struct nreg *nreg_next; /* Next region in list */ int nreg_pnum; /* Lowest numbered plane in this region */ int nreg_type; /* Type of tile that contains nreg_ll */ Point nreg_ll; /* Lower-leftmost point in this region on * plane nreg_pnum. We take the min first * in X, then in Y. */ LabelList *nreg_labels; /* See LabRegion for description */ CapValue nreg_cap; /* Capacitance to ground */ ResValue nreg_resist; /* Resistance estimate */ PerimArea nreg_pa[1]; /* Dummy; each node actually has * ExtCurStyle->exts_numResistClasses * array elements allocated to it. */ } NodeRegion; /* * Transistor region: labelled region with perimeter and area. * Used for each transistor in the flat extraction of a cell. */ typedef struct treg { struct treg *treg_next; /* Next region in list */ int treg_pnum; /* UNUSED */ int treg_type; /* Type of tile that contains treg_ll */ Point treg_ll; /* UNUSED */ LabelList *treg_labels; /* Attribute list */ Tile *treg_tile; /* Some tile in the channel */ int treg_area; /* Area of channel */ } TransRegion; typedef struct { /* Maintain plane information when pushing */ Rect area; /* tiles on the node stack. For use with */ int plane; /* function extNbrPushFunc(). */ } PlaneAndArea; /* * The following constructs a node name from the plane number 'n' * and lower left Point l, and places it in the string 's' (which must * be large enough). */ #define extMakeNodeNumPrint(buf, plane, coord) \ (void) sprintf((buf), "%s_%s%d_%s%d#", DBPlaneShortName(plane), \ ((coord).p_x < 0) ? "n": "", abs((coord).p_x), \ ((coord).p_y < 0) ? "n": "", abs((coord).p_y)) /* Old way: cryptic numbers, but a bit shorter * * #define extMakeNodeNumPrint(s, n, l) \ * (void) sprintf((s), "%d_%d_%d#", (n), extCoord((l).p_x), extCoord((l).p_y)) * * The following is used to map the full coordinate space into * the positive integers, for constructing internally generated * node names. * * #define extCoord(x) (((x) < 0) ? (1 - ((x) << 1)) : ((x) << 1)) */ /* * Argument passed to filter functions for finding regions. */ typedef struct { TileTypeBitMask *fra_connectsTo; /* Array of TileTypeBitMasks. The * element fra_connectsTo[t] has a * bit set for each type that * connects to 't'. */ CellDef *fra_def; /* Def being searched */ int fra_pNum; /* Plane currently searching */ ClientData fra_uninit; /* This value appears in the ti_client * field of a tile if it's not yet * been visited. */ Region *(*fra_first)(); /* Function to init new region */ int (*fra_each)(); /* Function for each tile in region */ Region *fra_region; /* Ptr to Region struct for current * region. May be set by fra_first * and used by fra_each. */ } FindRegion; #define TILEAREA(tp) ((TOP(tp) - BOTTOM(tp)) * (RIGHT(tp) - LEFT(tp))) /* -------------------- Perimeter of a region ------------------------- */ /* * Segment of the boundary of a region whose perimeter * is being traced by ExtTracePerimeter() and extEnumTilePerim(). */ typedef struct { Tile *b_inside; /* Pointer to tile just inside segment */ Tile *b_outside; /* Pointer to tile just outside segment */ Rect b_segment; /* Actual coordinates of segment */ u_char b_direction; /* Direction following segment (see below) */ int b_plane; /* extract argument for extSideOverlap */ } Boundary; #define BoundaryLength(bp) \ ((bp)->b_segment.r_xtop - (bp)->b_segment.r_xbot \ + (bp)->b_segment.r_ytop - (bp)->b_segment.r_ybot) /* Directions in which we can be following the boundary of a perimeter */ #define BD_LEFT 0 /* Inside is to right */ #define BD_TOP 1 /* Inside is below */ #define BD_RIGHT 2 /* Inside is to left */ #define BD_BOTTOM 3 /* Inside is above */ /* -------- Yank buffers for hierarchical and array extraction -------- */ extern CellUse *extYuseCum; extern CellDef *extYdefCum; /* --------------- Argument passed to extHierYankFunc ----------------- */ typedef struct { Rect *hy_area; /* Area (in parent coordinates) to be yanked */ CellUse *hy_target; /* Yank into this use */ bool hy_prefix; /* If TRUE, prefix labels with use id */ } HierYank; /* ----- Arguments to filter functions in hierarchical extraction ---- */ /* * The following defines an extracted subtree. * The CellUse et_use will be either a cell we are extracting, * or a flattened subtree. If et_lookNames is non-NULL, it * points to a CellDef that we should look in for node names. */ typedef struct extTree { CellUse *et_use; /* Extracted cell, usually flattened */ CellUse *et_realuse; /* If et_use is flattened, et_realuse * points to the unflattened subtree's * root use; otherwise it is NULL. */ CellDef *et_lookNames; /* See above */ NodeRegion *et_nodes; /* List of nodes */ HashTable et_coupleHash; /* Table for coupling capacitance. * key is type CoupleKey * value is pointer to type CapValue */ struct extTree *et_next; /* Next one in list */ } ExtTree; /* * The following structure contains information passed down * through several levels of filter functions during hierarchical * extraction. * * The procedure ha_nodename is used to map from a tile into the * name of the node to which that tile belongs. It should be of * the following format: * * char * * proc(tp, et, ha) * Tile *tp; * ExtTree *et; * HierExtractArg *ha; * { * } * * It should always return a non-NULL string; if the name of a * node can't be determined, the string can be "(none)". */ typedef struct { FILE *ha_outf; /* The .ext file being written */ CellUse *ha_parentUse; /* Use pointing to the def being extracted */ char *(*ha_nodename)();/* Map (tp, et, ha) into nodename; see above */ ExtTree ha_cumFlat; /* Cumulative yank buffer */ HashTable ha_connHash; /* Connections made during hier processing */ /* All areas are in parent coordinates */ Rect ha_interArea; /* Area of whole interaction being considered */ Rect ha_clipArea; /* Only consider capacitance, perimeter, and * area that come from inside this area. This * rectangle is contained within ha_interArea. */ CellUse *ha_subUse; /* Root of the subtree being processed now */ Rect ha_subArea; /* Area of ha_subUse inside the interaction * area, i.e, contained within ha_interArea. */ Tile *hierOneTile; /* Used in ExtHier.c, tile from extHierOneFlat */ int hierPNum; /* Used in ExtHier.c, plane of tile above */ TileType hierType; /* Used in ExtHier.c, type of tile above */ int hierPNumBelow; /* Used in ExtHier.c, plane of tile below */ } HierExtractArg; /* * Normally, nodes in overlapping subcells are expected to have labels * in the area of overlap. When this is not the case, we have to use * a much more expensive algorithm for finding the labels attached to * the subcells' geometry in the overlap area. The following structure * is used to hold information about the search in progress for such * labels. */ typedef struct { HierExtractArg *hw_ha; /* Describes context of search */ Label *hw_label; /* We update hw_label with a ptr to a * newly allocated label if successful. */ Rect hw_area; /* Area in parent coordinates of the * area where we're searching. */ bool hw_autogen; /* If TRUE, we trace out all geometry * in the first node in the first cell * found to overlap the search area, * and use the internal name for that * node. */ TerminalPath hw_tpath; /* Hierarchical path down to label * we are searching for, rooted at * the parent being extracted. */ TileTypeBitMask hw_mask; /* Mask of tile types that connect to * the tile whose node is to be found, * and which are on the same plane. * Used when calling ExtFindRegions. */ bool hw_prefix; /* If FALSE, we skip the initial * use identifier when building * hierarchical labels (as when * extracting arrays; see hy_prefix * in the HierYank struct). */ int (*hw_proc)(); } HardWay; /* --------------------- Coupling capacitance ------------------------- */ /* * The following structure is the hash key used for computing * internodal coupling capacitance. Each word is a pointer to * one of the nodes being coupled. By convention, the first * word is the lesser of the two NodeRegion pointers. */ typedef struct { NodeRegion *ck_1, *ck_2; } CoupleKey; extern void extCoupleHashZero(); /* Clears out all pointers to data in table */ /* ------------------ Interface to debugging module ------------------- */ extern ClientData extDebugID; /* Identifier returned by the debug module */ /* ----------------- Technology-specific information ------------------ */ /* * Structure used to define sidewall coupling capacitances. */ typedef struct edgecap { struct edgecap *ec_next; /* Next edge capacitance rule in list */ CapValue ec_cap; /* Capacitance (attofarads) */ TileTypeBitMask ec_near; /* Types closest to causing edge, or in * the case of sideOverlaps, the * types we are overlapping. */ TileTypeBitMask ec_far; /* Types farthest from causing edge, or * in the case of sideOverlaps, the * types that shield the edge from * the overlaped tile. */ int ec_plane; /* if ec_near is TT_SPACE, ec_plane */ /* specifies which plane is to be */ /* used. -1 if ec_near isn't space */ } EdgeCap; /* A type used to determine if current style needs planeorder or not */ typedef enum { noPlaneOrder, needPlaneOrder, seenPlaneOrder } planeOrderStatus ; /* * Because a large TT_MAXTYPES value quickly generates huge extract section * structures, we want to keep around only the style names, and dynamically * load and destroy the extract section values as needed, when doing an * extraction command. */ typedef struct extkeep { struct extkeep *exts_next; char *exts_name; } ExtKeep; /* * Parameters for the process being extracted. * We try to use use integers here, rather than floats, to be nice to * machines like Sun workstations that don't have hardware * floating point. * * In the case of capacitances, though, we may have to use floats, depending * upon the type CapValue. In some newer processes the capacitance per * lambda^2 is less than 1 attofarad. */ /*---------------------------------------------------------------*/ /* Structure containing inter-layer information (NT x NT matrix) */ /*---------------------------------------------------------------*/ typedef struct extinterlayerstyle { /* * Capacitance per unit perimeter. Sidewall capacitance depends both * on the type inside the perimeter as well as the type outside it, * so the table is doubly indexed by TileType. * * The mask exts_perimCapMask[t] contains bits for all those TileTypes * 's' such that exts_perimCap[t][s] is nonzero. */ CapValue exts_perimCap; /* * Both exts_overlapShieldTypes[][] and exts_overlapShieldPlanes[][] * are indexed by the same pair of types used to index the table * exts_overlapCap[][]; they identify the types and planes that * shield capacitance between their index types. */ TileTypeBitMask exts_overlapShieldTypes; int exts_overlapShieldPlanes; /* * The table extOverlapCap[][] is indexed by two types to give the * overlap coupling capacitance between them, per unit area. Only * one of extOverlapCap[i][j] and extOverlapCap[j][i] should be * nonzero. The capacitance to substrate of the tile of type 'i' * is deducted when an overlap between i and j is detected, if * extOverlapCap[i][j] is nonzero. This is only done, however, if * tile i is below tile j in exts_planeOrder; */ CapValue exts_overlapCap; /* * Sidewall coupling capacitance. This capacitance is between edges * on the same plane, and is in units of attofarads. It is multiplied * by the value interpolated from a fringing-field table indexed by the * common length of the pair of edges divided by their separation: * * | | * E1 +----------------------------+ * ^ * +--- distance between edges * v * +-----------------------------------+ E2 * | | * * <-----------------------> length in common */ /* * The entry exts_sideCoupleCap[i][j] is a list of the coupling * capacitance info between edges with type 'i' on the inside * and 'j' on the outside, and other kinds of edges. */ EdgeCap *exts_sideCoupleCap; /* * exts_sideCoupleOtherEdges[i][j] is a mask of those types on the * far sides of edges to which an edge with 'i' on the inside and * 'j' on the outside has coupling capacitance. */ TileTypeBitMask exts_sideCoupleOtherEdges; /* * The entry exts_sideOverlapCap[i][j] is a list of the coupling * capacitance info between edges with type 'i' on the inside * and 'j' on the outside, and other kinds of tiles on other * planes. The ec_near mask in the EdgeCap record identifies the * types to which we have sidewall overlap capacitance, and the * ec_far mask identifies the types that shield the tiles preventing * a capacitance. */ EdgeCap *exts_sideOverlapCap; /* * extSideOverlapOtherTypes[i][j] is a mask of those types to which * an edge with 'i' on the inside and 'j' on the outside has coupling * capacitance. extSideOverlapOtherPlanes[i][j] is a mask of those * planes to which edge [i][j] has overlap coupling capacitance. * exts_sideOverlapShieldPlanes[s][t] is a list of the planes that * need to be examined for shielding material when we are considering * a sidewall overlap capacitor between types s and t. This may * be the "or" of the planes needed by several sideoverlap rules, * since there can be several types of edges in which type s is * the "intype" member and the "outtype" member varies. Note that * sideOverlapShieldPlanes is indexed like overlapShieldPlanes, not * like sideOverlapOtherPlanes. */ int exts_sideOverlapOtherPlanes; int exts_sideOverlapShieldPlanes; TileTypeBitMask exts_sideOverlapOtherTypes; } ExtInterLayerStyle; /*-----------------------------------------------------------*/ /* Structure containing per-layer information (1 x NT array) */ /*-----------------------------------------------------------*/ typedef struct extlayerstyle { /* * Connectivity tables. * Each table is an array of TileTypeBitMasks indexed by TileType. * The i-th element of each array is a mask of those TileTypes * to which type 'i' connects. */ /* Everything is connected to everything else in this table */ TileTypeBitMask exts_allConn; /* * Connectivity for determining electrical nodes. * This should be essentially the same as DBConnectTbl[]. */ TileTypeBitMask exts_nodeConn; /* * Connectivity for determining resistive regions. * Two types should be marked as connected here if * they are both connected in exts_nodeConnect[], and * if they both have the same resistance per square. */ TileTypeBitMask exts_resistConn; /* * Connectivity for determining transistors. * Each transistor type should connect only to itself. * Nothing else should connect to anything else. */ TileTypeBitMask exts_transConn; /* * Sheet resistivity for each tile type, in milli-ohms per square. * For types that are transistors or capacitors, this corresponds * to the sheet resistivity of the gate. */ /* Maps from a tile type to the index of its sheet resistance entry */ int exts_typeToResistClass; /* Gives a mask of neighbors of a type with different resistivity */ TileTypeBitMask exts_typesResistChanged; /* * Resistance information is also provided by the following tables: * exts_typesByResistClass[] is an array of masks of those types * having the same sheet resistivity, for each different value * of sheet resistivity; exts_resistByResistClass[] is a parallel array * giving the actual value of sheet resistivity. Both are indexed * from 0 up to (but not including) exts_numResistClasses. */ TileTypeBitMask exts_typesByResistClass; ResValue exts_resistByResistClass; /* Resistance per type */ ResValue exts_sheetResist; /* * Resistances for via holes. * These have four parts: the size, border, and spacing * of a minimum-size contact (it's assumed to be square), * and the resistance of its via hole. The resistance is * given in milliohms. */ int exts_viaSize; int exts_viaSpacing; int exts_viaBorder; ResValue exts_viaResist; /* Layer height and thickness used by the geometry extractor */ float exts_height; float exts_thick; /* * Capacitance to substrate for each tile type, in units of * attofarads per square lambda. */ /* * Capacitance per unit area. This is zero for explicit capacitor * types, which handle gate-channel capacitance specially. For * transistor types, this is at best an approximation that is * truly valid only when the transistor is switched off. */ CapValue exts_areaCap; TileTypeBitMask exts_perimCapMask; /* * Overlap coupling capacitance for each pair of tile types, in units * of attofarads per square lambda of overlap. * Internodal capacitance due to overlap only occurs between tile * types on different tile planes that are not shielded by intervening * tiles. */ /* * The mask exts_overlapOtherPlanes[t] is a mask of the planes that * must be searched for tiles having overlap capacitance with tiles * of type 't', and exts_overlapOtherTypes[t] is a mask of the types * with which our overlap capacitance is non-zero. */ TileTypeBitMask exts_overlapOtherTypes; int exts_overlapOtherPlanes; /* * Sidewall-overlap coupling capacitance. * This is between an edge on one plane and a type on another plane * that overlaps the edge (from the outside of the edge), and is in * units of attofarads per lambda. * * When an edge with sidewall capacitance to substrate is found to * overlap a type to which it has sidewall overlap capacitance, the * original capacitance to substrate is replaced with the overlap * capacitance to the tile overlapped, if the edge is above the tile * being overlapped (according to ext_planeOrder). If the tiles are * the other way around, then this replacement is not done. */ /* * The mask exts_sideEdges[i] is just a mask of those types j for * which either exts_sideCoupleCap[i][j] or exts_sideOverlapCap[i][j] * is non-empty. */ TileTypeBitMask exts_sideEdges; /* Transistors */ /* Name of each transistor type as output in .ext file */ char *exts_transName; /* Device class */ char exts_deviceClass; /* * Per-square resistances for each possible transistor type, * in the various regions that such a type might operate. * The only operating region currently used is "linear", * which the resistance extractor uses in its thresholding * operation. NOTE: resistances in this table are in OHMS * per square, not MILLIOHMS! */ HashTable exts_transResist; ResValue exts_linearResist; /* * Mask of the types of tiles that connect to the channel terminals * of a transistor type. The intent is that these will be the * diffusion terminals of a transistor, ie, its source and drain. * UPDATED May, 2008: Record is a list of type masks, allowing * multiple terminal types in the case of, e.g., high-voltage * or other asymmetric devices. The last entry in the list should * be equal to DBSpaceBits. */ TileTypeBitMask *exts_transSDTypes; /* * Maximum number of terminals (source/drains) per transistor type. * This table exists to allow the possibility of transistors with * more than two diffusion terminals at some point in the future. */ int exts_transSDCount; /* Currently unused: gate-source capacitance per unit perimeter */ CapValue exts_transSDCap; /* Currently unused: gate-channel capacitance per unit area */ CapValue exts_transGateCap; /* * Each type of transistor has a substrate node. By default, * it is the one given by exts_transSubstrateName[t]. However, * if the mask exts_transSubstrateTypes[t] is non-zero, and if * the transistor overlaps material of one of the types in the * mask, then the transistor substrate node is the node of the * material it overlaps. */ char *exts_transSubstrateName; TileTypeBitMask exts_transSubstrateTypes; TileTypeBitMask exts_subsTransistorTypes; ExtInterLayerStyle *eils[NT]; /* inter-layer information */ /* (dynamically allocated) */ } ExtLayerStyle; /*-----------------------------------------------------------*/ /* Structure containing per-plane information (1 x NP array) */ /*-----------------------------------------------------------*/ typedef struct extplanestyle { /* Specifies an ordering of the planes, so we can determine which * tile is above another one. This is used only when determining * if we should subtract capacitance to substrate for overlap and * sideoverlap rules. If no planeorder is specified and the style * does not contain a noplaneordering command a warning is issued * and the default planeorder is used for the style. */ int exts_planeOrder; /* * The mask exts_overlapPlanes is a mask of those planes that must * be searched for tiles having overlap capacitance, and the mask * exts_overlapTypes[p] is those types having overlap capacitance * on each plane p. The intent is that exts_overlapTypes[p] lists * only those types t for which some entry of exts_overlapCap[t][s] * is non-zero. */ TileTypeBitMask exts_overlapTypes; /* Common to both sidewall coupling and sidewall overlap */ /* * exts_sideTypes[p] is a mask of those types 't' having sidewall * coupling or sidewall overlap capacitance on plane p (i.e, for * which a bin in exts_sideCoupleCap[t][] or exts_sideOverlapCap[t][] * is non-empty), and exts_sidePlanes a mask of those planes containing * tiles in exts_sideTypes[]. */ TileTypeBitMask exts_sideTypes; } ExtPlaneStyle; /*--------------------------------------------------------------*/ /* Main extraction style information */ /*--------------------------------------------------------------*/ typedef struct extstyle { char exts_status; /* Loaded, not loaded, or pending */ char *exts_name; /* Name of this style */ int exts_sidePlanes; int exts_overlapPlanes; /* set/reset with planeorder commands to determine whether * we will warn if no planeorder is specified. This is done * because at Stanford we use a lot of diagnostic extraction * styles (for floating wells etc.) and we don't want to specify * the planeorder for each and every one of them. */ planeOrderStatus exts_planeOrderStatus; /* * We search out a distance exts_sideCoupleHalo from each edge * for other types with which we have coupling capacitance. * This value determines how much extra gets yanked when * computing hierarchical adjustments, so should be kept * small to insure reasonable performance. */ int exts_sideCoupleHalo; int exts_numResistClasses; /* Scaling */ /* * Step size used when breaking up a large cell for interaction * checks during hierarchical extraction. We check exts_stepSize * by exts_stepSize chunks for interactions one at a time. */ int exts_stepSize; /* * Number of linear units per lambda. All perimeter dimensions * that we output to the .ext file should be multiplied by * exts_unitsPerLambda; we produce a "scale" line in the .ext file * indicating this. All area dimensions should be multiplied * by exts_unitsPerLambda**2. * (changed to type float May 11, 2006 to accomodate, e.g., 90 * and 130 nm technologies) */ float exts_unitsPerLambda; /* * Scaling for resistance and capacitance. * All resistances in the .ext file should be multiplied by * exts_resistScale to get milliohms, and all capacitances by * exts_capScale to get attofarads. These numbers appear in * the "scale" line in the .ext file. */ int exts_capScale; int exts_resistScale; /* Contains one for each type of fet, zero for all other types */ TileTypeBitMask exts_transMask; ExtLayerStyle *els[NT]; /* Per-layer information (allocated) */ ExtPlaneStyle *eps[NP]; /* Per-plane information (allocated) */ } ExtStyle; #define EXT_PLUG_GND 1 #define EXT_PLUG_VDD 2 extern ExtStyle *ExtCurStyle; /* ------------------- Hierarchical node merging ---------------------- */ /* * Table used to hold all merged nodes during hierarchical extraction. * Used for duplicate suppression. */ extern HashTable extHierMergeTable; /* * Each hash entry in the above table points to a NodeName struct. * Each NodeName points to the Node corresponding to that name. * Each Node points back to a list of NodeNames that point to that * Node, and which are linked together along their nn_next fields. */ typedef struct nn { struct node *nn_node; /* Node for which this is a name */ char *nn_name; /* Text of name */ struct nn *nn_next; /* Other names of nn_node */ } NodeName; typedef struct node { NodeName *node_names; /* List of names for this node. The first name * in the list is the "official" node name. */ CapValue node_cap; /* Capacitance to substrate */ PerimArea node_pa[1]; /* Dummy; each node actually has * ExtCurStyle->exts_numResistClasses * array elements allocated to it. */ } Node; /* -------------------------------------------------------------------- */ /* * Value normally resident in the ti_client field of a tile, * indicating that the tile has not yet been visited in a * region search. */ extern ClientData extUnInit; #define extGetRegion(tp) ( (tp)->ti_client ) #define extHasRegion(tp,und) ( (tp)->ti_client != (und) ) /* For non-recursive flooding algorithm */ #define VISITPENDING ((ClientData) NULL) /* Marks tiles on stack */ #ifdef NONMANHATTAN /* Note that this macro depends on MAXPLANES being small */ /* compared to the bit position of TT_SIDE. Since tens of */ /* thousands of planes is inconceivable, this should not be a */ /* problem. It is necessary to push the tile's TT_SIDE bit */ /* because the search algorithm can overwrite it between the */ /* time the tile is pushed and the time that it is popped. */ #define PUSHTILE(tp, pl) \ (tp)->ti_client = VISITPENDING; \ STACKPUSH((ClientData)(pointertype)(pl | \ ((TileType)(spointertype)(tp)->ti_body & TT_SIDE)), extNodeStack); \ STACKPUSH((ClientData)(pointertype)tp, extNodeStack) #define POPTILE(tp, pl) \ tp = (Tile *) STACKPOP(extNodeStack); \ pl = (spointertype) STACKPOP(extNodeStack); \ if (pl & TT_SIDE) { \ TiSetBody((tp), TiGetTypeExact(tp) | TT_SIDE); \ pl &= (~TT_SIDE); \ } \ else \ TiSetBody((tp), TiGetTypeExact(tp) & (~TT_SIDE)) /* Variations of "pushtile" to force a specific value on TT_SIDE */ #define PUSHTILEBOTTOM(tp, pl) \ (tp)->ti_client = VISITPENDING; \ STACKPUSH((ClientData)(pointertype)(pl | \ ((SplitDirection(tp)) ? 0 : TT_SIDE)), extNodeStack) ;\ STACKPUSH((ClientData)(pointertype)tp, extNodeStack) #define PUSHTILETOP(tp, pl) \ (tp)->ti_client = VISITPENDING; \ STACKPUSH((ClientData)(pointertype)(pl | \ ((SplitDirection(tp)) ? TT_SIDE : 0)), extNodeStack) ;\ STACKPUSH((ClientData)(pointertype)tp, extNodeStack) #define PUSHTILELEFT(tp, pl) \ (tp)->ti_client = VISITPENDING; \ STACKPUSH((ClientData)(pointertype)(pl), extNodeStack); \ STACKPUSH((ClientData)(pointertype)tp, extNodeStack) #define PUSHTILERIGHT(tp, pl) \ (tp)->ti_client = VISITPENDING; \ STACKPUSH((ClientData)(pointertype)(pl | TT_SIDE), extNodeStack); \ STACKPUSH((ClientData)(pointertype)tp, extNodeStack) #else #define PUSHTILE(tp, pl) \ (tp)->ti_client = VISITPENDING; \ STACKPUSH((ClientData)pl, extNodeStack); \ STACKPUSH((ClientData)tp, extNodeStack) #define POPTILE(tp, pl) \ tp = (Tile *) STACKPOP(extNodeStack); \ pl = (int) STACKPOP(extNodeStack) #endif /* ------------------------- Region finding --------------------------- */ extern Region *ExtFindRegions(); /* Filter functions for ExtFindRegions() */ extern Region *extTransFirst(); extern int extTransEach(); extern Region *extResFirst(); extern int extResEach(); extern Region *extNodeFirst(); extern int extNodeEach(); extern Region *extHierLabFirst(); extern int extHierLabEach(); /* -------- Search for matching tile/node in another ExtTree ---------- */ /* * NODETOTILE(np, et, tp) * NodeRegion *np; * ExtTree *et; * Tile *tp; * * Sets tp to be the tile containing the lower-leftmost point of the * NodeRegion *np, but in the tile planes of the ExtTree *et instead * of the tile planes originally containing *np. */ #define NODETOTILE(np, et, tp) \ if (1) { \ Plane *myplane = (et)->et_use->cu_def->cd_planes[(np)->nreg_pnum]; \ \ (tp) = myplane->pl_hint; \ GOTOPOINT(tp, &(np)->nreg_ll); \ myplane->pl_hint = (tp); \ } /* * NODETONODE(nold, et, nnew) * NodeRegion *nold; * ExtTree *et; * NodeRegion *nnew; * * Like NODETOTILE above, but leaves nnew pointing to the node associated * with the tile we find. */ #define NODETONODE(nold, et, nnew) \ if (1) { \ Tile *tp; \ \ (nnew) = (NodeRegion *) NULL; \ NODETOTILE((nold), (et), tp); \ if (tp && extHasRegion(tp, extUnInit)) \ (nnew) = (NodeRegion *) extGetRegion(tp); \ } /* -------------------- Miscellaneous procedures ---------------------- */ extern char *extNodeName(); extern NodeRegion *extBasic(); extern NodeRegion *extFindNodes(); extern ExtTree *extHierNewOne(); extern int extNbrPushFunc(); /* --------------------- Miscellaneous globals ------------------------ */ extern int extNumFatal; /* Number fatal errors encountered so far */ extern int extNumWarnings; /* Number warning messages so far */ extern CellUse *extParentUse; /* Dummy use for def being extracted */ extern ClientData extNbrUn; /* Ditto */ /* * This is really a (Stack *), but we use the struct tag to avoid * having to include stack.h in every .c file. Used in the non-recursive * flooding algorithm. */ extern struct stack *extNodeStack; /* ------------------ Connectivity table management ------------------- */ /* * The following is true if tile types 'r' and 's' are connected * according to the connectivity table 'tbl' */ #define extConnectsTo(r, s, tbl) ( TTMaskHasType(&(tbl)[(r)], (s)) ) /* -------------------------------------------------------------------- */ #include "extDebugInt.h" #endif /* _EXTRACTINT_H */ magic-8.0.210/extract/ExtUnique.c0000664000175000001440000001777112421575324015243 0ustar timusers/* * ExtUnique.c -- * * Circuit extraction. * Generation of unique names. * * ********************************************************************* * * 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/extract/ExtUnique.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/styles.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/malloc.h" #include "textio/textio.h" #include "debug/debug.h" #include "extract/extract.h" #include "extract/extractInt.h" #include "utils/signals.h" #include "utils/stack.h" #include "utils/utils.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "utils/main.h" #include "utils/undo.h" /* * ---------------------------------------------------------------------------- * * extUniqueCell -- * * For the cell 'def', look for the same label appearing in two or more * distinct nodes. For each such label found: * * If allNames is TRUE, then generate unique names for all * but one of the nodes by appending a unique numeric * suffix to the offending labels. * If allNames is FALSE, then generate unique names only if * the label ends in '#'. Leave feedback for all other * names that don't end in '!'. * * Results: * Returns the number of warnings generated. * * Side effects: * May modify the label list of def, and mark def as CDMODIFIED. * May also leave feedback. * * ---------------------------------------------------------------------------- */ int extUniqueCell(def, allNames) CellDef *def; bool allNames; { LabRegion *lregList, *lastreg, processedLabel; LabRegion *lp; LabelList *ll; HashEntry *he; HashTable labelHash; Label *lab; char *text; int nwarn; nwarn = 0; HashInit(&labelHash, 32, HT_STRINGKEYS); TxPrintf("Processing %s\n", def->cd_name); TxFlush(); /* Build up a list of nodes and assign them to tiles */ lregList = (LabRegion *) ExtFindRegions(def, &TiPlaneRect, &DBAllButSpaceBits, ExtCurStyle->exts_nodeConn, extUnInit, extHierLabFirst, (int (*)()) NULL); /* Assign the labels to their associated regions */ ExtLabelRegions(def, ExtCurStyle->exts_nodeConn, &lregList, &TiPlaneRect); /* * First pass: * Place all node labels in the cell in the hash table. */ for (lab = def->cd_labels; lab; lab = lab->lab_next) if (extLabType(lab->lab_text, LABTYPE_NAME)) (void) HashFind(&labelHash, lab->lab_text); /* Fix up labels as necessary */ for (lp = lregList; lp; lp = lp->lreg_next) { for (ll = lp->lreg_labels; ll; ll = ll->ll_next) { /* * We might have set ll->ll_label to NULL if we changed it * to make it unique. Also ignore if the label is not a * node label type (e.g, it is an attribute). */ if (ll->ll_label == (Label *) NULL) continue; text = ll->ll_label->lab_text; if (!extLabType(text, LABTYPE_NAME)) continue; /* * See if this label has been seen before in this cell. * If not, remember the current LabRegion as the first * one seen with this label. If it has been seen, but * with this same region, or it has already been made * unique (lastreg == &processedLabel), skip it. */ he = HashFind(&labelHash, text); lastreg = (LabRegion *) HashGetValue(he); if (lastreg == (LabRegion *) NULL) { HashSetValue(he, (ClientData) lp); continue; } if (lastreg != lp && lastreg != &processedLabel) { nwarn += extMakeUnique(def, ll, lp, lregList, &labelHash, allNames); HashSetValue(he, (ClientData) &processedLabel); } } } HashKill(&labelHash); ExtFreeLabRegions((LabRegion *) lregList); ExtResetTiles(def, extUnInit); if (nwarn) TxError("%s: %d warnings\n", def->cd_name, nwarn); return (nwarn); } int extMakeUnique(def, ll, lreg, lregList, labelHash, allNames) CellDef *def; LabelList *ll; LabRegion *lreg, *lregList; HashTable *labelHash; bool allNames; { static char *badmesg = "Non-global label \"%s\" attached to more than one unconnected node: %s"; char *cpend, *text, name[1024], name2[1024], message[1024]; LabRegion *lp2; LabelList *ll2; int nsuffix, nwarn; Label saveLab, *lab; Rect r; /* * Make a pass through all labels for all nodes. * Replace labels as appropriate. This loop * sets ll_label pointers to NULL whenever it * changes a label to make it unique. */ text = ll->ll_label->lab_text; if (allNames) goto makeUnique; cpend = index(text, '\0'); if (cpend > text) cpend--; if (*cpend == '#') goto makeUnique; if (*cpend == '!') return 0; /* Generate a warning for each occurrence of this label */ nwarn = 0; for (lp2 = lregList; lp2; lp2 = lp2->lreg_next) { for (ll2 = lp2->lreg_labels; ll2; ll2 = ll2->ll_next) { if (ll2->ll_label && strcmp(ll2->ll_label->lab_text, text) == 0) { nwarn++; r.r_ll = r.r_ur = ll2->ll_label->lab_rect.r_ll; GEO_EXPAND(&r, 1, &r); extMakeNodeNumPrint(name, lp2->lreg_pnum, lp2->lreg_ll); (void) sprintf(message, badmesg, text, name); DBWFeedbackAdd(&r, message, def, 1, STYLE_MEDIUMHIGHLIGHTS); } } } return nwarn; /* * For each occurrence of this label in all nodes but lreg, * replace the label by one with a unique suffix. If the * label is replaced, we mark it in the label list of the * node by NULLing-out the ll_label field of the LabelList * pointing to it. */ makeUnique: nsuffix = 0; (void) strcpy(name, text); for (lp2 = lregList; lp2; lp2 = lp2->lreg_next) { /* Skip lreg -- its labels will be unchanged */ if (lp2 == lreg) continue; lab = (Label *) NULL; for (ll2 = lp2->lreg_labels; ll2; ll2 = ll2->ll_next) { if (ll2->ll_label == (Label *) NULL) continue; if (strcmp(ll2->ll_label->lab_text, name) != 0) continue; /* * Keep looking for a name not already in this cell. * This is a bit conservative, since names that might not have * been attached to nodes were also added to the table in * extUniqueCell() above, but we ensure that we don't generate * a name that might conflict with an existing one (e.g, turning * Phi into Phi1 when there's already a Phi1 in the cell). * It's not necessary to add the final name to labelHash * because nsuffix increases monotonically -- we can never * generate a label identical to one previously generated. */ for (;;) { (void) sprintf(name2, "%s_uq%d", name, nsuffix); if (HashLookOnly(labelHash, name2) == NULL) break; nsuffix++; } lab = ll2->ll_label; saveLab = *lab; DBEraseLabelsByContent(def, &lab->lab_rect, lab->lab_type, lab->lab_text); (void) DBPutFontLabel(def, &saveLab.lab_rect, saveLab.lab_font, saveLab.lab_size, saveLab.lab_rotate, &saveLab.lab_offset, saveLab.lab_just, name2, saveLab.lab_type, saveLab.lab_flags); ll2->ll_label = (Label *) NULL; } /* Bump the suffix if we replaced any labels */ if (lab) nsuffix++; } return 0; } magic-8.0.210/extract/ExtHier.c0000664000175000001440000005113512404142456014651 0ustar timusers/* * ExtHier.c -- * * Circuit extraction. * Lower-level procedures common both to ordinary subtree extraction, * and to array extraction. * The procedures in this file are not re-entrant. * * ********************************************************************* * * 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/extract/ExtHier.c,v 1.3 2010/06/24 12:37:17 tim Exp $"; #endif /* not lint */ #include #include #include #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 "utils/malloc.h" #include "textio/textio.h" #include "utils/styles.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "debug/debug.h" #include "extract/extract.h" #include "extract/extractInt.h" /* Local data */ /* Passed to search functions by extHierConnections */ ExtTree *extHierCumFlat; /* Cum buffer */ ExtTree *extHierOneFlat; /* Subtree being compared with extHierCumFlat */ /* List of free cells around for use in yanking subtrees */ ExtTree *extHierFreeOneList = (ExtTree *) NULL; /* Appended to the name of each new CellDef created by extHierNewOne() */ int extHierOneNameSuffix = 0; /* Forward declarations */ int extHierConnectFunc1(); int extHierConnectFunc2(); Node *extHierNewNode(); /* * ---------------------------------------------------------------------------- * * extHierConnections -- * * Process connections between the two ExtTrees 'oneFlat' and 'cumFlat'. * This consists of detecting overlaps or abutments between connecting * tiles (maybe on different planes), and recording the connection in the hash * table ha->ha_connHash. * * Results: * None. * * Side effects: * Adds connections to ha->ha_connHash. * Doesn't change resistance or capacitance of the connected * nodes; that is the job of extHierAdjustments(). * * ---------------------------------------------------------------------------- */ void extHierConnections(ha, cumFlat, oneFlat) HierExtractArg *ha; ExtTree *cumFlat, *oneFlat; { int pNum; CellDef *sourceDef = oneFlat->et_use->cu_def; extHierCumFlat = cumFlat; extHierOneFlat = oneFlat; for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) { ha->hierPNum = pNum; (void) DBSrPaintArea((Tile *) NULL, sourceDef->cd_planes[pNum], &ha->ha_subArea, &DBAllButSpaceBits, extHierConnectFunc1, (ClientData) ha); } } /* * extHierConnectFunc1 -- * * Called for each tile 'oneTile' in the ExtTree 'oneFlat' above * that lies in the area ha->ha_subArea. * * Results: * Returns 0 always. * * Side effects: * None here, but see extHierConnectFunc2(). */ int extHierConnectFunc1(oneTile, ha) Tile *oneTile; /* Comes from 'oneFlat' in extHierConnections */ HierExtractArg *ha; /* Extraction context */ { CellDef *cumDef = extHierCumFlat->et_use->cu_def; Rect r; TileTypeBitMask mask, *connected; TileType rtype; Label *lab, *newlab; int i; unsigned n; /* * Find all tiles that connect to 'srcTile', but in the * yank buffer cumDef. Adjust connectivity for each tile found. * Widen the rectangle to detect connectivity by abutment. */ ha->hierOneTile = oneTile; ha->hierType = TiGetTypeExact(oneTile); if (IsSplit(oneTile)) { rtype = ha->hierType; ha->hierType = (rtype & TT_SIDE) ? SplitRightType(oneTile) : SplitLeftType(oneTile); } connected = &(ExtCurStyle->exts_nodeConn[ha->hierType]); TITORECT(oneTile, &r); GEOCLIP(&r, &ha->ha_subArea); r.r_xbot--, r.r_ybot--, r.r_xtop++, r.r_ytop++; for (i = PL_TECHDEPBASE; i < DBNumPlanes; i++) { ha->hierPNumBelow = i; TTMaskAndMask3(&mask, connected, &DBPlaneTypes[i]); if (!TTMaskIsZero(&mask)) { if (IsSplit(oneTile)) DBSrPaintNMArea((Tile *) NULL, cumDef->cd_planes[i], rtype, &r, ((i == ha->hierPNum) ? &DBAllButSpaceBits : connected), extHierConnectFunc2, (ClientData) ha); else DBSrPaintArea((Tile *) NULL, cumDef->cd_planes[i], &r, ((i == ha->hierPNum) ? &DBAllButSpaceBits : connected), extHierConnectFunc2, (ClientData) ha); } } /* Where labels have been saved from the parent cell, look for any */ /* that are inside the cell boundary and would connect to the tile. */ /* This allows the extractor to catch "sticky" labels that are not */ /* attached to a physical layer in the parent cell. */ // NOTE by Tim, 9/10/2014: This generates phantom nodes when the // labels are created by the "hard" node search; I think this code // should be restricted to sticky labels only. But not certain. // Definitely this causes problems in arrays, because the array node // name may refer to a range of array elements, and the generated // node only describes a single point. for (lab = cumDef->cd_labels; lab; lab = lab->lab_next) if (GEO_TOUCH(&r, &lab->lab_rect) && (lab->lab_flags & LABEL_STICKY)) if (TTMaskHasType(connected, lab->lab_type)) { HashTable *table = &ha->ha_connHash; HashEntry *he; NodeName *nn; Node *node1, *node2; char *name; /* Register the name, like is done in extHierConnectFunc2 */ he = HashFind(table, lab->lab_text); nn = (NodeName *) HashGetValue(he); node1 = nn ? nn->nn_node : extHierNewNode(he); name = (*ha->ha_nodename)(ha->hierOneTile, ha->hierPNum, extHierOneFlat, ha, TRUE); he = HashFind(table, name); nn = (NodeName *) HashGetValue(he); node2 = nn ? nn->nn_node : extHierNewNode(he); if (node1 != node2) { /* * Both sets of names will now point to node1. * We don't need to update node_cap since it * hasn't been computed yet. */ for (nn = node2->node_names; nn->nn_next; nn = nn->nn_next) nn->nn_node = node1; nn->nn_node = node1; nn->nn_next = node1->node_names; node1->node_names = node2->node_names; freeMagic((char *) node2); } #if 0 /* Copy this label to the parent def with a */ /* special flag, so we can output it as a node */ /* and then delete it. Don't duplicate labels */ /* that are already in the parent. */ for (newlab = ha->ha_parentUse->cu_def->cd_labels; newlab; newlab = newlab->lab_next) if (!strcmp(newlab->lab_text, lab->lab_text)) break; if (newlab == NULL) { n = sizeof(Label) + strlen(lab->lab_text) - sizeof lab->lab_text + 1; newlab = (Label *)mallocMagic((unsigned)n); bcopy((char *)lab, (char *)newlab, (int)n); newlab->lab_next = ha->ha_parentUse->cu_def->cd_labels; ha->ha_parentUse->cu_def->cd_labels = newlab; } #endif } return (0); } /* * extHierConnectFunc2 -- * * Called once for each tile 'cum' in extHierCumFlat->et_use->cu_def * on the same plane as ha->hierOneTile that also overlaps or abuts * the intersection of ha->hierOneTile with ha->ha_subArea, and for tiles * in other planes that may connect. * * Results: * Returns 0 always. * * Side effects: * Makes a connection between the nodes of the two tiles * if the types of ha->hierOneTile and 'cum' connect. * Otherwise, if the tiles actually overlap (as opposed * to merely abut), mark it with feedback as an error. */ int extHierConnectFunc2(cum, ha) Tile *cum; /* Comes from extHierCumFlat->et_use->cu_def */ HierExtractArg *ha; /* Extraction context */ { HashTable *table = &ha->ha_connHash; Node *node1, *node2; TileType ttype; HashEntry *he; NodeName *nn; char *name; Rect r; /* Compute the overlap area */ r.r_xbot = MAX(LEFT(ha->hierOneTile), LEFT(cum)); r.r_xtop = MIN(RIGHT(ha->hierOneTile), RIGHT(cum)); r.r_ybot = MAX(BOTTOM(ha->hierOneTile), BOTTOM(cum)); r.r_ytop = MIN(TOP(ha->hierOneTile), TOP(cum)); /* If the tiles don't even touch, they don't connect */ if (r.r_xtop < r.r_xbot || r.r_ytop < r.r_ybot || (r.r_xtop == r.r_xbot && r.r_ytop == r.r_ybot)) return (0); /* * Only make a connection if the types of 'ha->hierOneTile' and 'cum' * connect. If they overlap and don't connect, it is an error. * If they do connect, mark their nodes as connected. */ ttype = TiGetTypeExact(cum); if (IsSplit(cum)) ttype = (ttype & TT_SIDE) ? SplitRightType(cum) : SplitLeftType(cum); if (extConnectsTo(ha->hierType, ttype, ExtCurStyle->exts_nodeConn)) { name = (*ha->ha_nodename)(cum, ha->hierPNumBelow, extHierCumFlat, ha, TRUE); he = HashFind(table, name); nn = (NodeName *) HashGetValue(he); node1 = nn ? nn->nn_node : extHierNewNode(he); name = (*ha->ha_nodename)(ha->hierOneTile, ha->hierPNum, extHierOneFlat, ha, TRUE); he = HashFind(table, name); nn = (NodeName *) HashGetValue(he); node2 = nn ? nn->nn_node : extHierNewNode(he); if (node1 != node2) { /* * Both sets of names will now point to node1. * We don't need to update node_cap since it * hasn't been computed yet. */ for (nn = node2->node_names; nn->nn_next; nn = nn->nn_next) nn->nn_node = node1; nn->nn_node = node1; nn->nn_next = node1->node_names; node1->node_names = node2->node_names; freeMagic((char *) node2); } } else if (r.r_xtop > r.r_xbot && r.r_ytop > r.r_ybot) { extNumFatal++; if (!DebugIsSet(extDebugID, extDebNoFeedback)) DBWFeedbackAdd(&r, "Illegal overlap (types do not connect)", ha->ha_parentUse->cu_def, 1, STYLE_MEDIUMHIGHLIGHTS); } return (0); } /* * ---------------------------------------------------------------------------- * * extHierAdjustments -- * * Process adjustments to substrate capacitance, coupling capacitance, * node perimeter, and node area between the subtree 'oneFlat' and the * cumulative yank buffer 'cumFlat'. The subtree 'lookFlat' is used * for looking up node names when handling capacitance/perimeter/area * adjustment. * * Results: * None. * * Side effects: * Updates capacitance in the table cumFlat->et_coupleHash. * Updates capacitance, perimeter, and area recorded in the * nodes of 'cumFlat'. * * Algorithm: * For each capacitor recorded in oneFlat->et_coupleHash, find * the corresponding nodes in 'cumFlat' and subtract the * capacitance from the entry indexed by these nodes in the * table cumFlat->et_coupleHash. * * For each node in oneFlat->et_nodes, find the corresponding * node in 'lookFlat'. Look for the Node with this name in * the table ha->ha_connHash, and subtract the oneFlat node's * capacitance, perimeter, and area from it. If no Node is * found in this table, don't do anything since the oneFlat * node must not participate in any connections. * * The node in 'cumFlat' corresponding to one in 'oneFlat' * is the one containing some point in 'oneFlat', since 'oneFlat' * is a strict subset of 'cumFlat'. * * ---------------------------------------------------------------------------- */ void extHierAdjustments(ha, cumFlat, oneFlat, lookFlat) HierExtractArg *ha; ExtTree *cumFlat, *oneFlat, *lookFlat; { HashEntry *he, *heCum; int n; CoupleKey *ckpOne, ckCum; NodeRegion *np; HashSearch hs; NodeName *nn; Tile *tp; char *name; /* Update all coupling capacitors */ if (ExtOptions & EXT_DOCOUPLING) { HashStartSearch(&hs); while (he = HashNext(&oneFlat->et_coupleHash, &hs)) { ckpOne = ((CoupleKey *) he->h_key.h_words); /* Find nodes in cumFlat->et_coupleHash */ NODETONODE(ckpOne->ck_1, cumFlat, ckCum.ck_1); NODETONODE(ckpOne->ck_2, cumFlat, ckCum.ck_2); if (ckCum.ck_1 == NULL || ckCum.ck_2 == NULL) continue; /* Skip if the same; reverse to make smaller node pointer first */ if (ckCum.ck_1 == ckCum.ck_2) continue; if (ckCum.ck_2 < ckCum.ck_1) np = ckCum.ck_1, ckCum.ck_1 = ckCum.ck_2, ckCum.ck_2 = np; /* Update the capacitor record in cumFlat->et_coupleHash */ heCum = HashFind(&cumFlat->et_coupleHash, (char *) &ckCum); extSetCapValue(heCum, extGetCapValue(heCum) - extGetCapValue(he)); } } /* * Update all node values. * Find the corresponding tile in the ExtTree lookFlat, then look * for its name. If this name appear in the connection hash table, * update the capacitance, perimeter, and area stored there; otherwise * ignore it. * * The FALSE argument to (*ha->ha_nodename)() means that we don't bother * looking for node names the hard way; if we didn't already have a valid * node name then it couldn't appear in the table ha->ha_connHash in the * first place. */ for (np = oneFlat->et_nodes; np; np = np->nreg_next) { /* Ignore orphaned nodes (non-Manhattan shards outside the clip box) */ if (np->nreg_pnum == DBNumPlanes) continue; tp = extNodeToTile(np, lookFlat); if (tp && (name = (*ha->ha_nodename)(tp, np->nreg_pnum, lookFlat, ha, FALSE)) && (he = HashLookOnly(&ha->ha_connHash, name)) && (nn = (NodeName *) HashGetValue(he))) { /* Adjust the capacitance and resistance */ nn->nn_node->node_cap -= np->nreg_cap; for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) { nn->nn_node->node_pa[n].pa_perim -= np->nreg_pa[n].pa_perim; nn->nn_node->node_pa[n].pa_area -= np->nreg_pa[n].pa_area; } } } } /* * ---------------------------------------------------------------------------- * * extOutputConns -- * * Dump the contents of the hash table 'table' of connectivity and * node R, C adjustments to the output file outf. * * Results: * None. * * Side effects: * Outputs a number of "merge" records to the file 'outf'. * * ---------------------------------------------------------------------------- */ void extOutputConns(table, outf) HashTable *table; FILE *outf; { CapValue c; /* cap value */ NodeName *nn, *nnext; Node *node; int n; NodeName *nfirst; HashSearch hs; HashEntry *he; HashStartSearch(&hs); while (he = HashNext(table, &hs)) { nfirst = (NodeName *) HashGetValue(he); /* * If nfirst->nn_node == NULL, the name for this hash entry * had been output previously as a member of the merge list * for a node appearing earlier in the table. If so, we need * only free the NodeName without any further processing. */ if (node = nfirst->nn_node) { /* * If there are N names for this node, output N-1 merge lines. * Only the first merge line will contain the C, perimeter, * and area updates. */ c = (node->node_cap) / ExtCurStyle->exts_capScale; nn = node->node_names; if (nnext = nn->nn_next) { /* First merge */ fprintf(outf, "merge \"%s\" \"%s\" %lg", nn->nn_name, nnext->nn_name, c); for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) fprintf(outf, " %d %d", node->node_pa[n].pa_area, node->node_pa[n].pa_perim); fprintf(outf, "\n"); nn->nn_node = (Node *) NULL; /* Processed */ /* Subsequent merges */ for (nn = nnext; nnext = nn->nn_next; nn = nnext) { fprintf(outf, "merge \"%s\" \"%s\"\n", nn->nn_name, nnext->nn_name); nn->nn_node = (Node *) NULL; /* Processed */ } } nn->nn_node = (Node *) NULL; freeMagic((char *) node); } freeMagic((char *) nfirst); } } /* * ---------------------------------------------------------------------------- * * extHierNewNode -- * * Create a new NodeName and Node to go with the HashEntry supplied. * The NodeName will point to the new Node, which will point back to the * NodeName. * * Results: * Returns a pointer to the newly created Node. * * Side effects: * Allocates memory. * Sets (via HashSetValue) the value of HashEntry 'he' to the * newly created NodeName. * * ---------------------------------------------------------------------------- */ Node * extHierNewNode(he) HashEntry *he; { int n, nclasses; NodeName *nn; Node *node; nclasses = ExtCurStyle->exts_numResistClasses; n = (nclasses - 1) * sizeof (PerimArea) + sizeof (Node); nn = (NodeName *) mallocMagic((unsigned) (sizeof (NodeName))); node = (Node *) mallocMagic((unsigned) n); nn->nn_node = node; nn->nn_next = (NodeName *) NULL; nn->nn_name = he->h_key.h_name; node->node_names = nn; node->node_cap = (CapValue) 0; for (n = 0; n < nclasses; n++) node->node_pa[n].pa_perim = node->node_pa[n].pa_area = 0; HashSetValue(he, (char *) nn); return (node); } /* * ---------------------------------------------------------------------------- * * extHierLabFirst -- * extHierLabEach -- * * Filter functions passed to ExtFindRegions when tracing out labelled * regions as part of a hierarchical circuit extraction. * * Results: * extHierLabFirst returns a pointer to a new LabRegion. * extHierLabEach returns 0 always. * * Side effects: * Memory is allocated by extHierLabFirst(); it conses the newly * allocated region onto the front of the existing region list. * The node-naming info (reg_ll, reg_pnum) is updated by * extHierLabEach(). * * ---------------------------------------------------------------------------- */ /*ARGSUSED*/ Region * extHierLabFirst(tile, arg) Tile *tile; FindRegion *arg; { LabRegion *new; new = (LabRegion *) mallocMagic((unsigned) (sizeof (LabRegion))); new->lreg_next = (LabRegion *) NULL; new->lreg_labels = (LabelList *) NULL; new->lreg_pnum = DBNumPlanes; /* Prepend it to the region list */ new->lreg_next = (LabRegion *) arg->fra_region; arg->fra_region = (Region *) new; return ((Region *) new); } /*ARGSUSED*/ int extHierLabEach(tile, pNum, arg) Tile *tile; int pNum; FindRegion *arg; { LabRegion *reg; reg = (LabRegion *) arg->fra_region; extSetNodeNum(reg, pNum, tile); return (0); } /* * ---------------------------------------------------------------------------- * * extHierNewOne -- * * Allocate a new ExtTree for use in hierarchical extraction. * This ExtTree will be used to hold an entire flattened subtree. * We try to return one from our free list if one exists; if none * are left, we create a new CellDef and CellUse and allocate a * new ExtTree. The new CellDef has a name of the form __EXTTREEn__, * where 'n' is a small integer. * * The HashTable et_coupleHash will be initialized but empty. * The node list et_nodes, the next pointer et_next, and the CellDef * pointer et_lookNames will all be set to NULL. * * Results: * Returns a pointer to a new ExtTree. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ ExtTree * extHierNewOne() { char defname[128]; CellDef *dummy; ExtTree *et; if (extHierFreeOneList) { et = extHierFreeOneList; extHierFreeOneList = et->et_next; } else { et = (ExtTree *) mallocMagic((unsigned)(sizeof (ExtTree))); (void) sprintf(defname, "__EXTTREE%d__", extHierOneNameSuffix++); DBNewYank(defname, &et->et_use, &dummy); } et->et_next = (ExtTree *) NULL; et->et_lookNames = (CellDef *) NULL; et->et_nodes = (NodeRegion *) NULL; if (ExtOptions & EXT_DOCOUPLING) HashInit(&et->et_coupleHash, 32, HashSize(sizeof (CoupleKey))); return (et); } /* * ---------------------------------------------------------------------------- * * extHierFreeOne -- * * Return an ExtTree allocated via extHierNewOne() above to the * free list. Frees the HashTable et->et_coupleHash, any NodeRegions * on the list et->et_nodes, any labels on the label list and any * paint in the cell et->et_use->cu_def. * * Results: * None. * * Side effects: * See above. * The caller should NOT use et->et_next after this procedure * has returned. * * ---------------------------------------------------------------------------- */ void extHierFreeOne(et) ExtTree *et; { if (ExtOptions & EXT_DOCOUPLING) extCapHashKill(&et->et_coupleHash); if (et->et_nodes) ExtFreeLabRegions((LabRegion *) et->et_nodes); extHierFreeLabels(et->et_use->cu_def); DBCellClearDef(et->et_use->cu_def); et->et_next = extHierFreeOneList; extHierFreeOneList = et; } magic-8.0.210/extract/ExtNghbors.c0000644000175000001440000002367611443234341015370 0ustar timusers/* * ExtNeighbors.c -- * * Circuit extraction. * This file contains the primitive function ExtFindNeighbors() * for visiting all neighbors of a tile that connect to it, and * applying a filter function at each tile. * * ********************************************************************* * * 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/extract/ExtNghbors.c,v 1.3 2010/09/12 20:32:33 tim Exp $"; #endif /* not lint */ #include #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 "utils/malloc.h" #include "debug/debug.h" #include "extract/extract.h" #include "extract/extractInt.h" #include "utils/signals.h" #include "utils/stack.h" /* * The algorithm used by ExtFindNeighbors is non-recursive. * It uses a stack (extNodeStack) to hold a list of tiles yet to * be processed. To mark a tile as being on the stack, we store * the value VISITPENDING in its ti_client field. */ /* Used for communicating with extNbrPushFunc */ ClientData extNbrUn; /* * ---------------------------------------------------------------------------- * * ExtFindNeighbors -- * * For each tile adjacent to 'tile' that connects to it (according to * arg->fra_connectsTo), and (if it is a contact) for tiles on other * planes that connect to it, we recursively visit the tile, call the * client's filter procedure (*arg->fra_each)(), if it is non-NULL. * The tile is marked as being visited by setting it's ti_client field * to arg->fra_region. * * Results: * Returns the number of tiles that are found to be connected. * This is used to find, for example, transistor gates made of * only one tile, for which a simple calculation suffices for * computing length and width. If an error occurred, returns * the value -1. * * Side effects: * See comments above. * * ---------------------------------------------------------------------------- */ int ExtFindNeighbors(tile, tilePlaneNum, arg) Tile *tile; int tilePlaneNum; FindRegion *arg; { TileTypeBitMask *connTo = arg->fra_connectsTo; Tile *tp; TileType type, t; TileTypeBitMask *mask; Rect biggerArea; int pNum, tilesfound; PlaneMask pMask; PlaneAndArea pla; tilesfound = 0; extNbrUn = arg->fra_uninit; if (extNodeStack == (Stack *) NULL) extNodeStack = StackNew(64); /* Mark this tile as pending and push it */ PUSHTILE(tile, tilePlaneNum); while (!StackEmpty(extNodeStack)) { POPTILE(tile, tilePlaneNum); if (IsSplit(tile)) { type = (SplitSide(tile)) ? SplitRightType(tile): SplitLeftType(tile); } else type = TiGetTypeExact(tile); mask = &connTo[type]; /* * Since tile was pushed on the stack, we know that it * belongs to this region. Check to see that it hasn't * been visited in the meantime. If it's still unvisited, * visit it and process its neighbors. */ if (tile->ti_client == (ClientData) arg->fra_region) continue; tile->ti_client = (ClientData) arg->fra_region; tilesfound++; if (DebugIsSet(extDebugID, extDebNeighbor)) extShowTile(tile, "neighbor", 1); /* Top */ topside: if (IsSplit(tile) && (SplitSide(tile) ^ SplitDirection(tile))) goto leftside; for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp)) { if (IsSplit(tp)) { t = SplitBottomType(tp); // if (tp->ti_client == extNbrUn && TTMaskHasType(mask, t)) if (tp->ti_client != (ClientData)arg->fra_region && TTMaskHasType(mask, t)) { PUSHTILEBOTTOM(tp, tilePlaneNum); } } else { t = TiGetTypeExact(tp); if (tp->ti_client == extNbrUn && TTMaskHasType(mask, t)) { PUSHTILE(tp, tilePlaneNum); } } } /* Left */ leftside: if (IsSplit(tile) && SplitSide(tile)) goto bottomside; for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp)) { if (IsSplit(tp)) { t = SplitRightType(tp); // if (tp->ti_client == extNbrUn && TTMaskHasType(mask, t)) if (tp->ti_client != (ClientData)arg->fra_region && TTMaskHasType(mask, t)) { PUSHTILERIGHT(tp, tilePlaneNum); } } else { t = TiGetTypeExact(tp); if (tp->ti_client == extNbrUn && TTMaskHasType(mask, t)) { PUSHTILE(tp, tilePlaneNum); } } } /* Bottom */ bottomside: if (IsSplit(tile) && (!(SplitSide(tile) ^ SplitDirection(tile)))) goto rightside; for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp)) { if (IsSplit(tp)) { t = SplitTopType(tp); // if (tp->ti_client == extNbrUn && TTMaskHasType(mask, t)) if (tp->ti_client != (ClientData)arg->fra_region && TTMaskHasType(mask, t)) { PUSHTILETOP(tp, tilePlaneNum); } } else { t = TiGetTypeExact(tp); if (tp->ti_client == extNbrUn && TTMaskHasType(mask, t)) { PUSHTILE(tp, tilePlaneNum); } } } /* Right */ rightside: if (IsSplit(tile) && !SplitSide(tile)) goto donesides; for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp)) { if (IsSplit(tp)) { t = SplitLeftType(tp); // if (tp->ti_client == extNbrUn && TTMaskHasType(mask, t)) if (tp->ti_client != (ClientData)arg->fra_region && TTMaskHasType(mask, t)) { PUSHTILELEFT(tp, tilePlaneNum); } } else { t = TiGetTypeExact(tp); if (tp->ti_client == extNbrUn && TTMaskHasType(mask, t)) { PUSHTILE(tp, tilePlaneNum); } } } donesides: /* Apply the client's filter procedure if one exists */ if (arg->fra_each) if ((*arg->fra_each)(tile, tilePlaneNum, arg)) goto fail; /* If this is a contact, visit all the other planes */ if (DBIsContact(type)) { pMask = DBConnPlanes[type]; pMask &= ~(PlaneNumToMaskBit(tilePlaneNum)); for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) if (PlaneMaskHasPlane(pMask, pNum)) { Plane *plane = arg->fra_def->cd_planes[pNum]; tp = plane->pl_hint; GOTOPOINT(tp, &tile->ti_ll); plane->pl_hint = tp; if (tp->ti_client != extNbrUn) continue; /* tp and tile should have the same geometry for a contact */ if (IsSplit(tile) && IsSplit(tp)) { if (SplitSide(tile)) { t = SplitRightType(tp); if (TTMaskHasType(mask, t)) { PUSHTILERIGHT(tp, pNum); } } else { t = SplitLeftType(tp); if (TTMaskHasType(mask, t)) { PUSHTILELEFT(tp, pNum); } } } else if (IsSplit(tp)) { t = SplitRightType(tp); if (TTMaskHasType(mask, t)) { PUSHTILERIGHT(tp, pNum); } t = SplitLeftType(tp); if (TTMaskHasType(mask, t)) { PUSHTILELEFT(tp, pNum); } } else { t = TiGetTypeExact(tp); if (TTMaskHasType(mask, t)) { PUSHTILE(tp, pNum); } } } } /* * The hairiest case is when this type connects to stuff on * other planes, but isn't itself connected as a contact. * For example, a CMOS pwell connects to diffusion of the * same doping (p substrate diff). In a case like this, * we need to search the entire AREA of the tile plus a * 1-lambda halo to find everything it overlaps or touches * on the other plane. */ if (pMask = DBAllConnPlanes[type]) { TITORECT(tile, &pla.area); GEO_EXPAND(&pla.area, 1, &biggerArea); for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) if ((pNum != tilePlaneNum) && PlaneMaskHasPlane(pMask, pNum)) { pla.plane = pNum; (void) DBSrPaintArea((Tile *) NULL, arg->fra_def->cd_planes[pNum], &biggerArea, mask, extNbrPushFunc, (ClientData) &pla); } } } return tilesfound; fail: /* Flush the stack */ while (!StackEmpty(extNodeStack)) { POPTILE(tile, tilePlaneNum); tile->ti_client = (ClientData) arg->fra_region; } return -1; } /* * ---------------------------------------------------------------------------- * * extNbrPushFunc -- * * Called for each tile overlapped by a 1-unit wide halo around the area * tileArea. If the tile overlaps or shares a non-null segment of border * with tileArea, and it hasn't already been visited, push it on the stack * extNodeStack. * * Uses the global parameter extNbrUn to determine whether or not a tile * has been visited; if the tile's client field is equal to extNbrUn, then * this is the first time the tile has been seen. * * Results: * Always returns 0. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ int extNbrPushFunc(tile, pla) Tile *tile; PlaneAndArea *pla; { Rect *tileArea; Rect r; tileArea = &pla->area; /* Ignore tile if it's already been visited */ if (tile->ti_client != extNbrUn) return 0; /* Only consider tile if it overlaps tileArea or shares part of a side */ TITORECT(tile, &r); if (!GEO_OVERLAP(&r, tileArea)) { GEOCLIP(&r, tileArea); if (r.r_xbot >= r.r_xtop && r.r_ybot >= r.r_ytop) return 0; } /* Push tile on the stack and mark as being visited */ PUSHTILE(tile, pla->plane); return 0; } magic-8.0.210/extract/ExtHard.c0000664000175000001440000003615312424560446014650 0ustar timusers/* * ExtHard.c -- * * Circuit extraction. * Procedures for finding the name of a node during hierarchical * extraction, when no label for that node could be found in the * interaction area. * * ********************************************************************* * * 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/extract/ExtHard.c,v 1.2 2010/06/24 12:37:17 tim Exp $"; #endif /* not lint */ #include #include #include #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 "textio/textio.h" #include "utils/styles.h" #include "debug/debug.h" #include "extract/extract.h" #include "extract/extractInt.h" #include "utils/geofast.h" /* Forward declarations */ void extHardFreeAll(); bool extHardGenerateLabel(); bool extHardSetLabel(); /* * ---------------------------------------------------------------------------- * * extLabFirst -- * extLabEach -- * * Filter functions passed to ExtFindRegions when tracing out extended * label regions as part of hierarchical circuit extraction. We use the * TransRegion record because it allows us to save a pointer to a tile * along with the usual LabRegion data. Since treg_area is not needed, * we use it to store the plane of the tile. * * Results: * extLabFirst returns a pointer to a new TransRegion. * extLabEach returns NULL. * * Side effects: * Memory is allocated by extLabFirst. * We cons the newly allocated region onto the front of the existing * region list. * * ---------------------------------------------------------------------------- */ Region * extLabFirst(tile, arg) Tile *tile; FindRegion *arg; { TransRegion *reg; reg = (TransRegion *) mallocMagic((unsigned) (sizeof (TransRegion))); reg->treg_next = (TransRegion *) NULL; reg->treg_labels = (LabelList *) NULL; reg->treg_pnum = DBNumPlanes; reg->treg_area = DBNumPlanes; reg->treg_tile = tile; /* Prepend it to the region list */ reg->treg_next = (TransRegion *) arg->fra_region; arg->fra_region = (Region *) reg; return ((Region *) reg); } /*ARGSUSED*/ int extLabEach(tile, pNum, arg) Tile *tile; int pNum; FindRegion *arg; { TransRegion *reg = (TransRegion *) arg->fra_region; /* Avoid setting the region's tile pointer to a split tile if we can */ if (IsSplit(reg->treg_tile) && !IsSplit(tile)) { reg->treg_tile = tile; reg->treg_area = pNum; } if (reg->treg_area == DBNumPlanes) reg->treg_area = pNum; extSetNodeNum((LabRegion *)reg, pNum, tile); return (0); } /* * ---------------------------------------------------------------------------- * * extHardProc -- * * Called for each cell use in a tree. We determine if there is any * geometry in this cell whose type is in the mask arg->hw_mask and * whose node name we can determine. * * If so, we set arg->hw_label to point to a newly allocated Label whose * name is the full hierarchical path of the node name we just found, and * whose location (lab_rect) lies within the geometry of the node, but has * been transformed to root coordinates by scx->scx_trans. * * Several fields in the HardWay struct pointed to by 'arg' control * the details of how we assign a label: * * arg->hw_prefix If this is FALSE, we are responsible for constructing * the full hierarchical pathname for the generated label * starting from the immediate children of the root cell * ha->ha_parentUse->cu_def. We do this by appending * the use-id of scx->scx_use to arg->hw_tpath before * appending the final component of the label name to * arg->hw_tpath. * * If TRUE, we are responsible only for appending segments * to arg->hw_tpath for grandchildren of the root cell and * their descendants; the caller is responsible for the * initial part of the pathname. * * arg->hw_autogen If FALSE, attempt to find an existing label for the * geometry in the node. * * If TRUE, generate a label from the canonical nodename * for the first piece of geometry we find. * * Results: * Returns 0 if the caller (DBCellSrArea) should keep going, * or 1 if we've succeeded and the caller may return. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ int extHardProc(scx, arg) SearchContext *scx; /* Context of the search to this cell */ HardWay *arg; /* See above; this structure provides both * options to govern how we generate labels * and a place to store the label we return. */ { HierExtractArg *ha = arg->hw_ha; bool isTopLevel = (scx->scx_use->cu_parent == ha->ha_parentUse->cu_def); CellDef *def = scx->scx_use->cu_def; TransRegion *reg; TransRegion *labRegList; char *savenext; int ret = 0; /* * Build up next component of label path. * If the caller has already taken care of generating a prefix * for immediate children of the root cell, arg->hw_prefix will * have been set to FALSE. */ savenext = arg->hw_tpath.tp_next; /* Will be restored before we return */ if (arg->hw_prefix || !isTopLevel) { arg->hw_tpath.tp_next = DBPrintUseId(scx, savenext, arg->hw_tpath.tp_last - savenext, FALSE); *arg->hw_tpath.tp_next++ = '/'; *arg->hw_tpath.tp_next = '\0'; } /* * We use a TransRegion because it holds both a LabelList * and a tile pointer, and call extLabEach to make sure * that treg_pnum and treg_ll are kept up-to-date (so we * can generate a node label if none is found). * * The call below may return several TransRegions, as when * geometry in a parent overlaps two different nodes in a * single child. */ labRegList = (TransRegion *) ExtFindRegions(def, &scx->scx_area, &arg->hw_mask, ExtCurStyle->exts_nodeConn, extUnInit, extLabFirst, extLabEach); if (labRegList) { /* * If labels are being generated automatically on this pass, * we don't bother to assign labels to geometry. Instead, we * construct a new label based on the lower-leftmost tile in * the Region labRegList. */ if (arg->hw_autogen) { (void) extHardGenerateLabel(scx, labRegList, arg); goto success; } /* * Assign labels to LabRegions. * Tiles in 'def' that belong to nodes other than those in labRegList * will have uninitialized region pointers, and so will not have labels * assigned to them. */ // ExtLabelRegions(def, ExtCurStyle->exts_nodeConn, &labRegList, // &scx->scx_area); ExtLabelRegions(def, ExtCurStyle->exts_nodeConn, NULL, NULL); /* Now try to find a region with a node label */ for (reg = labRegList; reg; reg = reg->treg_next) if (reg->treg_labels && extHardSetLabel(scx, reg, arg)) goto success; /* No luck; it's as though there was no geometry at all */ extHardFreeAll(def, labRegList); } /* No luck; check our subcells recursively */ ret = DBCellSrArea(scx, extHardProc, (ClientData) arg); arg->hw_tpath.tp_next = savenext; goto done; success: extHardFreeAll(def, labRegList); ret = 1; done: return (ret); } /* * ---------------------------------------------------------------------------- * * extHardSetLabel -- * * We found a LabRegion, 'reg', that has a label list. * Walk down its label list looking for a node label. * If we find one, append it to the TerminalPath we've * been constructing from the root, make a new label * whose text is this full pathname, and assign it to * arg->hw_label. * * The coordinates of the result label are those of * the node label we find, transformed by scx->scx_trans * to lie in the root. * * Results: * Returns TRUE if we found a node label, FALSE if not. * * Side effects: * If successful, allocates a new Label struct as described * above, and assigns it to arg->hw_label. * * ---------------------------------------------------------------------------- */ bool extHardSetLabel(scx, reg, arg) SearchContext *scx; /* We use scx->scx_trans to transform label * coordinates in the def scx->scx_use->cu_def * up to root coordinates. */ TransRegion *reg; /* Region with a label list */ HardWay *arg; /* We will set arg->hw_label if a node * label is found on the label list of 'reg'. */ { TerminalPath *tpath = &arg->hw_tpath; Label *oldlab, *newlab; char *srcp, *dstp; LabelList *ll; int prefixlen; char *text; int len; Rect r; int pNum; Tile *tp; for (ll = reg->treg_labels; ll; ll = ll->ll_next) if (extLabType(ll->ll_label->lab_text, LABTYPE_NAME)) break; if (ll == (LabelList *) NULL) return (FALSE); oldlab = ll->ll_label; /* Compute length of new label */ prefixlen = tpath->tp_next - tpath->tp_first; len = strlen(oldlab->lab_text) + prefixlen; /* Allocate a Label big enough to hold the complete path */ newlab = (Label *) mallocMagic((unsigned) (sizeof (Label) + len - 3)); r=oldlab->lab_rect; if (!GEO_SURROUND(&scx->scx_area,&r)) { GEOCLIP(&r,&scx->scx_area); pNum = DBPlane(oldlab->lab_type); tp = scx->scx_use->cu_def->cd_planes[pNum]->pl_hint; GOTOPOINT(tp, &r.r_ll); scx->scx_use->cu_def->cd_planes[pNum]->pl_hint = tp; if ((TransRegion *)extGetRegion(tp) == reg) { /* found an OK point */ r.r_ur.p_x =r.r_ll.p_x+1; r.r_ur.p_y =r.r_ll.p_y+1; } else { GOTOPOINT(tp, &r.r_ur); if ((TransRegion *)extGetRegion(tp) == reg) { r.r_ll = r.r_ur; } else { /* forget it; we're never going to find the damn thing */ r=oldlab->lab_rect; } } } GeoTransRect(&scx->scx_trans, &r, &newlab->lab_rect); newlab->lab_type = oldlab->lab_type; text = oldlab->lab_text; /* Don't care, really, which orientation the label has */ newlab->lab_just = GEO_NORTH; /* Construct the text of the new label */ dstp = newlab->lab_text; if (prefixlen) { srcp = tpath->tp_first; do { *dstp++ = *srcp++; } while (--prefixlen > 0); } srcp = text; while (*dstp++ = *srcp++) /* Nothing */; arg->hw_label = newlab; if (DebugIsSet(extDebugID, extDebHardWay)) TxPrintf("Hard way: found label = \"%s\"\n", newlab->lab_text); return (TRUE); } /* * ---------------------------------------------------------------------------- * * extHardGenerateLabel -- * * Generate a label automatically from reg->treg_pnum and * reg->treg_ll according to the conventions used for node * labels in ExtBasic.c. The label is prefixed with the * TerminalPath we've been constructing from the root in * arg->hw_tpath. * * The coordinates of the result label are those of reg->treg_tile->ti_ll, * transformed by scx->scx_trans to lie in the root. * * Results: * Always TRUE. * * Side effects: * Allocates a new Label struct as described above, * and assigns it to arg->hw_label. * * ---------------------------------------------------------------------------- */ bool extHardGenerateLabel(scx, reg, arg) SearchContext *scx; /* We use scx->scx_trans to transform the * generated label's coordinates up to * root coordinates. */ TransRegion *reg; /* Region whose treg_ll and treg_pnum we use * to generate a new label name. */ HardWay *arg; /* We set arg->hw_label to the new label */ { TerminalPath *tpath = &arg->hw_tpath; char *srcp, *dstp; Label *newlab; int prefixlen; char gen[100]; int len; Rect r; Point p; // Modification 9/9/2014 by Tim: // Convert the treg_ll value up to top-level coordinates. // Otherwise you end up with a node that is apparently in // "canonical coordinates", but if you try to find the // location of the node using the name, you'll end up in // a random place. It also allows the low-probability // but possible conflict between this node and another with // the same name in the parent cell. // // Reverted 10/30/2014, not the right solution, causes // worse problems. // // GeoTransPoint(&scx->scx_trans, ®->treg_ll, &r.r_ll); // extMakeNodeNumPrint(gen, reg->treg_pnum, r.r_ll); extMakeNodeNumPrint(gen, reg->treg_pnum, reg->treg_ll); prefixlen = tpath->tp_next - tpath->tp_first; len = strlen(gen) + prefixlen; newlab = (Label *) mallocMagic((unsigned) (sizeof (Label) + len - 3)); r.r_ll = reg->treg_tile->ti_ll; GEOCLIP(&r,&scx->scx_area); r.r_ur.p_x = r.r_ll.p_x+1; r.r_ur.p_y = r.r_ll.p_y+1; GeoTransRect(&scx->scx_trans, &r, &newlab->lab_rect); newlab->lab_type = TiGetType(reg->treg_tile); /* Don't care, really, which orientation the label has */ newlab->lab_just = GEO_NORTH; /* Mark this as a generated label; may or may not be useful */ newlab->lab_flags = LABEL_GENERATE; /* Construct the text of the new label */ dstp = newlab->lab_text; if (prefixlen) { srcp = tpath->tp_first; do { *dstp++ = *srcp++; } while (--prefixlen > 0); } srcp = gen; while (*dstp++ = *srcp++) /* Nothing */; arg->hw_label = newlab; if (DebugIsSet(extDebugID, extDebHardWay)) TxPrintf("Hard way: generated label = \"%s\"\n", newlab->lab_text); return (TRUE); } /* * ---------------------------------------------------------------------------- * * extHardFreeAll -- * * Reset all the ti_client fields that we set in 'def' that * were set to point to regions in the list 'tReg' of TransRegions. * Then free all the regions in 'tReg'. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void extHardFreeAll(def, tReg) CellDef *def; TransRegion *tReg; { TransRegion *reg; LabelList *ll; FindRegion arg; /* Don't need to initialize arg.fra_first below */ arg.fra_connectsTo = ExtCurStyle->exts_nodeConn; arg.fra_def = def; arg.fra_each = (int (*)()) NULL; arg.fra_region = (Region *) extUnInit; for (reg = tReg; reg; reg = reg->treg_next) { /* Reset all ti_client fields to extUnInit */ arg.fra_uninit = (ClientData) reg; if (reg->treg_tile) { arg.fra_pNum = reg->treg_area; ExtFindNeighbors(reg->treg_tile, arg.fra_pNum, &arg); } /* Free all LabelLists and then the region */ for (ll = reg->treg_labels; ll; ll = ll->ll_next) freeMagic((char *) ll); freeMagic((char *) reg); } } magic-8.0.210/extract/Makefile0000644000175000001440000000070510751423606014572 0ustar timusers# # rcsid "$Header: /usr/cvsroot/magic-8.0/extract/Makefile,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $" # MODULE = extract MAGICDIR = .. SRCS = ExtArray.c ExtBasic.c ExtCell.c ExtCouple.c ExtHard.c \ ExtHier.c ExtLength.c ExtMain.c ExtNghbors.c ExtPerim.c \ ExtRegion.c ExtSubtree.c ExtTech.c ExtTest.c ExtTimes.c ExtYank.c \ ExtInter.c ExtUnique.c include ${MAGICDIR}/defs.mak include ${MAGICDIR}/rules.mak magic-8.0.210/extract/extDebugInt.h0000644000175000001440000000311710751423606015525 0ustar timusers/* * extDebugInt.h -- * * Definitions of debugging flags for extraction. * This is a separate include file so that new debugging flags * can be added to it without forcing recompilation of the * entire extract module. * * rcsid "$Header: /usr/cvsroot/magic-8.0/extract/extDebugInt.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $" * * ********************************************************************* * * 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. * * ********************************************************************* * */ extern int extDebAreaEnum; extern int extDebArray; extern int extDebHardWay; extern int extDebHierCap; extern int extDebHierAreaCap; extern int extDebLabel; extern int extDebNeighbor; extern int extDebNoArray; extern int extDebNoFeedback; extern int extDebNoHard; extern int extDebNoSubcell; extern int extDebLength; extern int extDebPerim; extern int extDebResist; extern int extDebVisOnly; extern int extDebYank; magic-8.0.210/extract/ExtTimes.c0000644000175000001440000007227211202560464015044 0ustar timusers/* * ExtTimes.c -- * * Circuit extraction timing. * * ********************************************************************* * * 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/extract/ExtTimes.c,v 1.2 2009/05/13 15:03:16 tim Exp $"; #endif /* not lint */ #include #include #include #include #include #ifdef SYSV #include #include #endif #include /* for sqrt() function */ #include "utils/magic.h" #include "utils/utils.h" #include "utils/geometry.h" #include "utils/geofast.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/malloc.h" #include "textio/textio.h" #include "extract/extract.h" #include "extract/extractInt.h" /* * One of the following structures gets allocated for each cell. * It holds the statistics we accumulate while extracting that cell. */ struct cellStats { CellDef *cs_def; /* Which cell */ struct timeval cs_tpaint; /* Paint-only extraction time */ struct timeval cs_tcell; /* Extract just this cell */ struct timeval cs_thier; /* Extract complete tree */ struct timeval cs_tincr; /* Incremental extraction time */ int cs_fets; /* Transistor count in this cell */ int cs_rects; /* Non-space tile count in this cell */ int cs_hfets; /* Hierarchical transistor count */ int cs_hrects; /* Hierarchical tile count */ int cs_ffets; /* Total flat transistor count */ int cs_frects; /* Total flat tile count */ long cs_area; /* Total area of cell */ long cs_interarea; /* Interaction areas sum */ long cs_cliparea; /* Interaction area, counting each * overlap of interaction areas only * once instead of once for each * interaction area. */ }; /* Hash table of all the above structs, keyed by CellDef */ HashTable cellStatsTable; /* * Cumulative statistics */ struct cumStats { double cums_min; /* Smallest value */ double cums_max; /* Largest value */ double cums_sum; /* Sum of values */ double cums_sos; /* Sum of squares */ int cums_n; /* Number values */ }; struct cumStats cumFetsPerSecPaint; struct cumStats cumRectsPerSecPaint; struct cumStats cumFetsPerSecFlat; struct cumStats cumRectsPerSecFlat; struct cumStats cumFetsPerSecHier; struct cumStats cumRectsPerSecHier; struct cumStats cumIncrTime; struct cumStats cumPercentClipped; struct cumStats cumPercentInteraction; struct cumStats cumTotalArea, cumInteractArea, cumClippedArea; FILE *extDevNull = NULL; /* Forward declarations */ struct cellStats *extGetStats(); void extTimesCellFunc(); void extTimesIncrFunc(); void extTimesSummaryFunc(); void extTimesParentFunc(); void extTimeProc(); void extCumInit(); void extCumOutput(); void extCumAdd(); void extPaintOnly(CellDef *); void extHierCell(CellDef *); int extCountTiles(); extern int extDefInitFunc(); /* * ---------------------------------------------------------------------------- * * ExtTimes -- * * Time the extractor. * All cells in the tree rooted at 'rootUse' are extracted. * We report the following times for each cell (seconds of CPU * time, accurate to 10 milliseconds). * * Time to extract just its paint. * Time to extract it completely. * Time to perform incremental re-extraction if just this cell changed. * * In addition, we report: * * Fets/second paint extraction speed * Fets/second cell extraction speed * Fets/second hierarchical extraction speed * Rects/second paint extraction speed * Rects/second cell extraction speed * Rects/second hierarchical extraction speed * * Also for each cell, we report the number of transistors, number * of rectangles, and rectangles per transistor. * * In addition, we report the following cumulative information, as * means, standard deviation, min, and max: * * Fets/second flat extraction speed * Fets/second complete extraction speed * Rects/second flat extraction speed * Rects/second complete extraction speed * Incremental extraction time after changing one cell. * * Results: * None. * * Side effects: * Writes to the file 'f'. * * ---------------------------------------------------------------------------- */ void ExtTimes(rootUse, f) CellUse *rootUse; FILE *f; { double clip, inter; HashSearch hs; HashEntry *he; /* Make sure this cell is read in */ DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox); /* Initialize cumulative statistics */ extCumInit(&cumFetsPerSecPaint); extCumInit(&cumRectsPerSecPaint); extCumInit(&cumFetsPerSecFlat); extCumInit(&cumRectsPerSecFlat); extCumInit(&cumFetsPerSecHier); extCumInit(&cumRectsPerSecHier); extCumInit(&cumIncrTime); extCumInit(&cumPercentClipped); extCumInit(&cumPercentInteraction); extCumInit(&cumTotalArea); extCumInit(&cumInteractArea); extCumInit(&cumClippedArea); /* Open to /dev/null */ extDevNull = fopen("/dev/null", "w"); if (extDevNull == NULL) { perror("/dev/null"); return; } /* Mark all defs as unvisited */ (void) DBCellSrDefs(0, extDefInitFunc, (ClientData) 0); /* Recursively visit all defs in the tree and store in hash table */ HashInit(&cellStatsTable, 128, 1); (void) extTimesInitFunc(rootUse); /* * Now visit every cell in the hash table and compute * its individual statistics. */ TxPrintf("Computing individual cell statistics:\n"); TxFlush(); HashStartSearch(&hs); while (he = HashNext(&cellStatsTable, &hs)) extTimesCellFunc((struct cellStats *) HashGetValue(he)); /* * Now visit every cell in the hash table and compute * its incremental time (ancestors) and hierarchical * time (children). */ TxPrintf("Computing hierarchical and incremental statistics:\n"); TxFlush(); HashStartSearch(&hs); while (he = HashNext(&cellStatsTable, &hs)) extTimesIncrFunc((struct cellStats *) HashGetValue(he)); /* * Compute the summary statistics and output everything. * Free each entry in the table as we go. */ TxPrintf("Computing summary statistics:\n"); TxFlush(); HashStartSearch(&hs); while (he = HashNext(&cellStatsTable, &hs)) { extTimesSummaryFunc((struct cellStats *) HashGetValue(he), f); freeMagic((char *) HashGetValue(he)); } /* Output the summary statistics */ fprintf(f, "\n\nSummary statistics:\n\n"); fprintf(f, "%s %8s %8s %8s %8s\n", " ", "min", "max", "mean", "std.dev"); extCumOutput("fets/sec paint ", &cumFetsPerSecPaint, f); extCumOutput("fets/sec hier ", &cumFetsPerSecHier, f); extCumOutput("fets/sec flat ", &cumFetsPerSecFlat, f); extCumOutput("rects/sec paint", &cumRectsPerSecPaint, f); extCumOutput("rects/sec hier ", &cumRectsPerSecHier, f); extCumOutput("rects/sec flat ", &cumRectsPerSecFlat, f); extCumOutput("tot incr time ", &cumIncrTime, f); extCumOutput("% cell clipped ", &cumPercentClipped, f); extCumOutput("% cell interact", &cumPercentInteraction, f); /* Fix up average value to be weighted */ clip = inter = 0.0; if (cumTotalArea.cums_sum > 0) { clip = 100.0 * cumClippedArea.cums_sum / cumTotalArea.cums_sum; inter = 100.0 * cumInteractArea.cums_sum / cumTotalArea.cums_sum; } fprintf(f, "Mean %% clipped area = %.2f\n", clip); fprintf(f, "Mean %% interaction area = %.2f\n", inter); /* Free the hash table */ HashKill(&cellStatsTable); (void) fclose(extDevNull); } /* * ---------------------------------------------------------------------------- * * extTimesInitFunc -- * * Called to add the cellStats struct for use->cu_def to the hash table * cellStatsTable if it is not already present, and to initialize this * structure. * * Results: * Returns 0 always. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ int extTimesInitFunc(use) CellUse *use; { CellDef *def = use->cu_def; struct cellStats *cs; HashEntry *he; he = HashFind(&cellStatsTable, (char *) def); if (HashGetValue(he)) return (0); /* Not yet visited: add it to the hash table */ cs = (struct cellStats *) mallocMagic(sizeof (struct cellStats)); cs->cs_def = def; cs->cs_tpaint.tv_sec = cs->cs_tpaint.tv_usec = 0; cs->cs_tcell.tv_sec = cs->cs_tcell.tv_usec = 0; cs->cs_thier.tv_sec = cs->cs_thier.tv_usec = 0; cs->cs_tincr.tv_sec = cs->cs_tincr.tv_usec = 0; cs->cs_fets = cs->cs_rects = 0; cs->cs_ffets = cs->cs_frects = 0; cs->cs_hfets = cs->cs_hrects = 0; cs->cs_area = cs->cs_interarea = cs->cs_cliparea = 0; HashSetValue(he, (ClientData) cs); /* Visit our children */ (void) DBCellEnum(def, extTimesInitFunc, (ClientData) 0); return (0); } /* * ---------------------------------------------------------------------------- * * extTimesCellFunc -- * * Called for each cellStats structure in the hash table, we extract * the paint of cs->cs_def and then both the paint and subcells, timing * both. Also count the number of fets in this cell and the total number * of tiles. Store this information in: * * cs->cs_tpaint Time to extract paint only * cs->cs_tcell Time to extract paint and subcells * cs->cs_fets Number of fets * cs->cs_rects Number of non-space tiles * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void extTimesCellFunc(cs) struct cellStats *cs; { extern long extSubtreeTotalArea; extern long extSubtreeInteractionArea; extern long extSubtreeClippedArea; TransRegion *transList, *tl; CellDef *def = cs->cs_def; int pNum; TxPrintf("Processing %s\n", def->cd_name); TxFlush(); /* Count the number of transistors */ transList = (TransRegion *) ExtFindRegions(def, &TiPlaneRect, &ExtCurStyle->exts_transMask, ExtCurStyle->exts_transConn, extUnInit, extTransFirst, extTransEach); ExtResetTiles(def, extUnInit); for (tl = transList; tl; tl = tl->treg_next) cs->cs_fets++; ExtFreeLabRegions((LabRegion *) transList); /* Count the number of tiles */ for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) (void) DBSrPaintArea((Tile *) NULL, def->cd_planes[pNum], &TiPlaneRect, &DBAllButSpaceBits, extCountTiles, (ClientData) cs); /* Measure the flat extraction time */ extTimeProc(extPaintOnly, def, &cs->cs_tpaint); /* Measure the total extraction time */ extSubtreeTotalArea = 0; extSubtreeInteractionArea = 0; extSubtreeClippedArea = 0; extTimeProc(extHierCell, def, &cs->cs_tcell); cs->cs_area = extSubtreeTotalArea; cs->cs_interarea = extSubtreeInteractionArea; cs->cs_cliparea = extSubtreeClippedArea; } /* * extCountTiles -- * * Count the number of tiles in a cell. * Called via DBSrPaintArea by extTimesCellFunc() above. * * Results: * Returns 0 always. * * Side effects: * Increments cs->cs_rects. */ int extCountTiles(tile, cs) Tile *tile; /* UNUSED */ struct cellStats *cs; { cs->cs_rects++; return (0); } /* * ---------------------------------------------------------------------------- * * extTimesIncrFunc -- * * All cells have been visited by extTimesCellFunc above. This procedure * accumulates the hierarchical information from both above and below * in the tree. The cs_tcell times for all ancestors, plus this cell, * are summed into cs->cs_tincr. The cs_tcell times for all children, * counting each child once, are summed into cs->cs_thier. The cs_fets * and cs_rects for all children, also counting each child once, are * summed into cs_hfets and cs_hrects. Finally, the cs_fets and cs_rects * for all children, counting each child as many times as it appears, * are summed into cs_ffets and cs_frects. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void extTimesIncrFunc(cs) struct cellStats *cs; { /* * Visit all of our parents recursively. * This sums the incremental times. */ extTimesParentFunc(cs->cs_def, cs); /* Reset all defs */ (void) DBCellSrDefs(0, extDefInitFunc, (ClientData) 0); /* * Visit all of our children recursively, visiting * each child only once. This sums the number of fets * and rectangles for cs_hfets and cs_hrects. */ (void) extTimesHierFunc(cs->cs_def, cs); /* Reset all defs */ (void) DBCellSrDefs(0, extDefInitFunc, (ClientData) 0); /* * Visit all of our children recursively, visiting each * child as many times as it appears. This sums the * number of fets and rectangles as cs_ffets and cs_frects. */ (void) extTimesFlatFunc(cs->cs_def, cs); } /* * ---------------------------------------------------------------------------- * * extTimesSummaryFunc -- * * Write the statistics contained in the cellStats structure 'cs' * out to the FILE 'f'. Add them to the summary structures being * maintained (cumFetsPerSecPaint, etc). * * Results: * None. * * Side effects: * Writes to the FILE f. * * ---------------------------------------------------------------------------- */ void extTimesSummaryFunc(cs, f) struct cellStats *cs; FILE *f; { double tpaint, tcell, thier, tincr; double fetspaint, rectspaint; double fetshier, rectshier; double fetsflat, rectsflat; double pctinter, pctclip; pctinter = pctclip = 0.0; if (cs->cs_area > 0) { pctinter = ((double)cs->cs_interarea) / ((double)cs->cs_area) * 100.0; pctclip = ((double)cs->cs_cliparea) / ((double)cs->cs_area) * 100.0; } tpaint = cs->cs_tpaint.tv_usec; tpaint = (tpaint / 1000000.) + cs->cs_tpaint.tv_sec; tcell = cs->cs_tcell.tv_usec; tcell = (tcell / 1000000.) + cs->cs_tcell.tv_sec; thier = cs->cs_thier.tv_usec; thier = (thier / 1000000.) + cs->cs_thier.tv_sec; tincr = cs->cs_tincr.tv_usec; tincr = (tincr / 1000000.) + cs->cs_tincr.tv_sec; fetspaint = fetsflat = fetshier = 0.0; rectspaint = rectsflat = rectshier = 0.0; if (tpaint > 0.01) { fetspaint = cs->cs_fets / tpaint; rectspaint = cs->cs_rects / tpaint; } if (thier > 0.01) { fetshier = cs->cs_hfets / thier; rectshier = cs->cs_hrects / thier; fetsflat = cs->cs_ffets / thier; rectsflat = cs->cs_frects / thier; } /* Cell name */ fprintf(f, "\n%8s %8s %s\n", "", "", cs->cs_def->cd_name); /* Sizes */ fprintf(f, "%8d %8d (paint) fets rects\n", cs->cs_fets, cs->cs_rects); fprintf(f, "%8d %8d (hier) fets rects\n", cs->cs_hfets, cs->cs_hrects); fprintf(f, "%8d %8d (flat) fets rects\n", cs->cs_ffets, cs->cs_frects); /* Times */ fprintf(f, "%8.2f %8.2f Tpaint, Tcell\n", tpaint, tcell); fprintf(f, "%8.2f %8.2f Thier, Tincr\n", thier, tincr); /* Speeds */ fprintf(f, "%8.2f %8.2f (paint) fets/sec rects/sec\n", fetspaint, rectspaint); fprintf(f, "%8.2f %8.2f (hier) fets/sec rects/sec\n", fetshier, rectshier); fprintf(f, "%8.2f %8.2f (flat) fets/sec rects/sec\n", fetsflat, rectsflat); /* Fraction of area in subtree processing */ fprintf(f, "%8.2f %8.2f clip %% inter %%\n", pctclip, pctinter); /* Accumulate statistics */ if (cs->cs_fets > 0) extCumAdd(&cumFetsPerSecPaint, fetspaint); if (cs->cs_rects > 0) extCumAdd(&cumRectsPerSecPaint, rectspaint); if (cs->cs_hfets > 0) extCumAdd(&cumFetsPerSecHier, fetshier); if (cs->cs_hrects > 0) extCumAdd(&cumRectsPerSecHier, rectshier); if (cs->cs_ffets > 0) extCumAdd(&cumFetsPerSecFlat, fetsflat); if (cs->cs_frects > 0) extCumAdd(&cumRectsPerSecFlat, rectsflat); if (pctclip > 0.0) extCumAdd(&cumPercentClipped, pctclip); if (pctinter > 0.0) extCumAdd(&cumPercentInteraction, pctinter); extCumAdd(&cumTotalArea, (double) cs->cs_area); extCumAdd(&cumInteractArea, (double) cs->cs_interarea); extCumAdd(&cumClippedArea, (double) cs->cs_cliparea); extCumAdd(&cumIncrTime, tincr); } /* * ---------------------------------------------------------------------------- * * extTimesParentFunc -- * * Function to visit all the parents of 'def' and add their * times to that of 'cs'. We only add the times if the def * being visited is unmarked, ie, its cd_client field is 0. * After adding the times for a def, we mark it by setting * its cd_client field to 1. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void extTimesParentFunc(def, cs) CellDef *def; struct cellStats *cs; { struct cellStats *csForDef; CellUse *parent; if (def->cd_client) return; /* Mark this def as visited */ def->cd_client = (ClientData) 1; /* Find its statistics in the table */ if ((csForDef = extGetStats(def)) == NULL) return; /* Add the time */ cs->cs_tincr.tv_sec += csForDef->cs_tcell.tv_sec; cs->cs_tincr.tv_usec += csForDef->cs_tcell.tv_usec; if (cs->cs_tincr.tv_usec > 1000000) { cs->cs_tincr.tv_usec -= 1000000; cs->cs_tincr.tv_sec += 1; } /* Visit all our parents */ for (parent = def->cd_parents; parent; parent = parent->cu_nextuse) if (parent->cu_parent) extTimesParentFunc(parent->cu_parent, cs); } /* * ---------------------------------------------------------------------------- * * extTimesHierFunc -- * * Function to visit all the children of 'def' and add their * times to that of 'cs'. We only add the times if the def * being visited is unmarked, ie, its cd_client field is 0. * After adding the times for a def, we mark it by setting * its cd_client field to 1. * * Results: * Returns 0 always. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ int extTimesHierFunc(def, cs) CellDef *def; struct cellStats *cs; { int extTimesHierUse(); struct cellStats *csForDef; if (def->cd_client) return (0); /* Mark this def as visited */ def->cd_client = (ClientData) 1; /* Find its statistics in the table */ if ((csForDef = extGetStats(def)) == NULL) return (0); /* Add the time */ cs->cs_thier.tv_sec += csForDef->cs_tcell.tv_sec; cs->cs_thier.tv_usec += csForDef->cs_tcell.tv_usec; if (cs->cs_thier.tv_usec > 1000000) { cs->cs_thier.tv_usec -= 1000000; cs->cs_thier.tv_sec += 1; } /* Add the fets and rectangles */ cs->cs_hfets += csForDef->cs_fets; cs->cs_hrects += csForDef->cs_rects; /* Visit our children */ (void) DBCellEnum(def, extTimesHierUse, (ClientData) cs); return (0); } int extTimesHierUse(use, cs) CellUse *use; struct cellStats *cs; { return (extTimesHierFunc(use->cu_def, cs)); } /* * ---------------------------------------------------------------------------- * * extTimesFlatFunc -- * * Function to visit all the children of 'def' and add their * fet and rect counts to those of 'cs'. This is a fully * instantiated count, rather than a drawn count, so we count * each cell as many times as it appears in an array or as * a subcell. * * Results: * Returns 0 always. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ int extTimesFlatFunc(def, cs) CellDef *def; struct cellStats *cs; { struct cellStats *csForDef; int extTimesFlatUse(); /* Find this cell's statistics in the table */ if ((csForDef = extGetStats(def)) == NULL) return (0); /* Add the fets and rectangles */ cs->cs_ffets += csForDef->cs_fets; cs->cs_frects += csForDef->cs_rects; /* Visit our children */ (void) DBCellEnum(def, extTimesFlatUse, (ClientData) cs); return (0); } int extTimesFlatUse(use, cs) CellUse *use; struct cellStats *cs; { struct cellStats dummyCS; int nx, ny, nel; /* Compute statistics for this cell and its children */ bzero((char *) &dummyCS, sizeof dummyCS); (void) extTimesFlatFunc(use->cu_def, &dummyCS); /* Scale by number of elements in this array */ if (use->cu_xlo < use->cu_xhi) nx = use->cu_xhi - use->cu_xlo + 1; else nx = use->cu_xlo - use->cu_xhi + 1; if (use->cu_ylo < use->cu_yhi) ny = use->cu_yhi - use->cu_ylo + 1; else ny = use->cu_ylo - use->cu_yhi + 1; nel = nx * ny; /* Fets and rects */ cs->cs_ffets += dummyCS.cs_ffets * nel; cs->cs_frects += dummyCS.cs_frects * nel; return (0); } /* * ---------------------------------------------------------------------------- * * extTimeProc -- * * Time a procedure applied to the CellDef 'def', storing the time * in the timeval pointed to by 'tv'. The procedure should be of * the form: * * (*proc)(def) * CellDef *def; * { * } * * Results: * None. * * Side effects: * See above. * * Algorithm: * If (*proc)() takes less than a second to run, we run it ten * times to get a better time estimate, then divide by ten. * * ---------------------------------------------------------------------------- */ void extTimeProc(proc, def, tv) int (*proc)(); CellDef *def; struct timeval *tv; { int secs, usecs, i; #ifdef SYSV tv->tv_sec = 0; tv->tv_usec = 0; #else extern int getrusage(); struct rusage r1, r2; (void) getrusage(RUSAGE_SELF, &r1); (*proc)(def); (void) getrusage(RUSAGE_SELF, &r2); tv->tv_sec = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec; tv->tv_usec = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec; if (tv->tv_usec < 0) { tv->tv_usec += 1000000; tv->tv_sec -= 1; } if (tv->tv_sec < 1) { (void) getrusage(RUSAGE_SELF, &r1); for (i = 0; i < 10; i++) (*proc)(def); (void) getrusage(RUSAGE_SELF, &r2); secs = r2.ru_utime.tv_sec - r1.ru_utime.tv_sec; usecs = r2.ru_utime.tv_usec - r1.ru_utime.tv_usec; usecs = (usecs + (secs * 1000000)) / 10; tv->tv_sec = usecs / 1000000; tv->tv_usec = usecs % 1000000; } #endif } /* * ---------------------------------------------------------------------------- * * extPaintOnly -- * * Called via extTimeProc() above. Extract just the paint in a cell. * * Results: * None. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ void extPaintOnly(def) CellDef *def; { NodeRegion *reg; reg = extBasic(def, extDevNull); if (reg) ExtFreeLabRegions((LabRegion *) reg); ExtResetTiles(def, extUnInit); } /* * ---------------------------------------------------------------------------- * * extHierCell -- * * Called via extTimeProc() above. Extract a cell normally, but * send the extracted output to /dev/null. * * Results: * None. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ void extHierCell(def) CellDef *def; { extCellFile(def, extDevNull, FALSE); } /* * ---------------------------------------------------------------------------- * * extCumInit -- * * Initialize a cumulative statistics structure. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void extCumInit(cum) struct cumStats *cum; { cum->cums_min = (double) INFINITY; cum->cums_max = (double) MINFINITY; cum->cums_sum = 0.0; cum->cums_sos = 0.0; cum->cums_n = 0; } /* * ---------------------------------------------------------------------------- * * extCumOutput -- * * Output a cumulative statistics structure. * * Results: * None. * * Side effects: * Writes to the FILE 'f'. * * ---------------------------------------------------------------------------- */ void extCumOutput(str, cum, f) char *str; /* Prefix string */ struct cumStats *cum; FILE *f; { double mean, var; mean = var = 0.0; if (cum->cums_n != 0) { mean = cum->cums_sum / (double) cum->cums_n; var = (cum->cums_sos / (double) cum->cums_n) - (mean * mean); } fprintf(f, "%s", str); if (cum->cums_min < INFINITY) fprintf(f, " %8.2f", cum->cums_min); else fprintf(f, " "); if (cum->cums_max > MINFINITY) fprintf(f, " %8.2f", cum->cums_max); else fprintf(f, " "); fprintf(f, " %8.2f %8.2f\n", mean, sqrt(var)); } /* * ---------------------------------------------------------------------------- * * extCumAdd -- * * Add the value v to the cumulative statistics structure, * updating the statistics. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void extCumAdd(cum, v) struct cumStats *cum; double v; { if (v < cum->cums_min) cum->cums_min = v; if (v > cum->cums_max) cum->cums_max = v; cum->cums_sum += v; cum->cums_sos += v*v; cum->cums_n++; } /* * ---------------------------------------------------------------------------- * * extGetStats -- * * Return the cellStats record for the CellDef 'def'. * * Results: * See above. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ struct cellStats * extGetStats(def) CellDef *def; { HashEntry *he; he = HashLookOnly(&cellStatsTable, (char *) def); if (he == (HashEntry *) NULL) return ((struct cellStats *) NULL); return ((struct cellStats *) HashGetValue(he)); } /* * ---------------------------------------------------------------------------- * * ExtInterCount -- * * Find all interaction areas in an entire design, and count * the fraction of the total area that is really an interaction * area. Report this for each cell in the design, and as a * fraction of the total area. * * Results: * None. * * Side effects: * Writes to the FILE 'f'. * * ---------------------------------------------------------------------------- */ int extInterCountHalo; CellDef *extInterCountDef; void ExtInterCount(rootUse, halo, f) CellUse *rootUse; int halo; FILE *f; { double inter; /* Make sure this cell is read in */ DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox); /* Initialize cumulative statistics */ extCumInit(&cumPercentInteraction); extCumInit(&cumTotalArea); extCumInit(&cumInteractArea); /* Mark all defs as unvisited */ (void) DBCellSrDefs(0, extDefInitFunc, (ClientData) 0); /* * Recursively visit all defs in the tree and compute * their interaction area. */ extInterCountHalo = halo; (void) extInterAreaFunc(rootUse, f); /* Mark all defs as unvisited */ (void) DBCellSrDefs(0, extDefInitFunc, (ClientData) 0); /* Output the summary statistics */ fprintf(f, "\n\nSummary statistics:\n\n"); fprintf(f, "%s %8s %8s %8s %8s\n", " ", "min", "max", "mean", "std.dev"); extCumOutput("% cell interact", &cumPercentInteraction, f); /* Fix up average value to be weighted */ inter = 0.0; if (cumTotalArea.cums_sum > 0) inter = 100.0 * cumInteractArea.cums_sum / cumTotalArea.cums_sum; fprintf(f, "Mean %% interaction area = %.2f\n", inter); } int extInterAreaFunc(use, f) CellUse *use; FILE *f; { static Plane *interPlane = (Plane *) NULL; CellDef *def = use->cu_def; int extInterCountFunc(); int area, interarea; double pctinter; if (interPlane == NULL) interPlane = DBNewPlane((ClientData) TT_SPACE); /* Skip if already visited */ if (def->cd_client) return (0); /* Mark as visited */ def->cd_client = (ClientData) 1; /* Compute interaction area */ extInterCountDef = def; ExtFindInteractions(def, extInterCountHalo, 0, interPlane); interarea = 0; (void) DBSrPaintArea((Tile *) NULL, interPlane, &TiPlaneRect, &DBAllButSpaceBits, extInterCountFunc, (ClientData) &interarea); DBClearPaintPlane(interPlane); area = (def->cd_bbox.r_xtop - def->cd_bbox.r_xbot) * (def->cd_bbox.r_ytop - def->cd_bbox.r_ybot); pctinter = 0.0; if (area > 0) pctinter = ((double) interarea) / ((double) area) * 100.0; if (pctinter > 0.0) extCumAdd(&cumPercentInteraction, pctinter); extCumAdd(&cumTotalArea, (double) area); extCumAdd(&cumInteractArea, (double) interarea); fprintf(f, "%7.2f%% %s\n", pctinter, def->cd_name); /* Visit our children */ (void) DBCellEnum(def, extInterAreaFunc, (ClientData) f); return (0); } int extInterCountFunc(tile, pArea) Tile *tile; int *pArea; { Rect r; TITORECT(tile, &r); GEOCLIP(&r, &extInterCountDef->cd_bbox); *pArea += (r.r_xtop - r.r_xbot) * (r.r_ytop - r.r_ybot); return (0); } magic-8.0.210/extract/ExtArray.c0000664000175000001440000007710312421575324015046 0ustar timusers/* * ExtArray.c -- * * Circuit extraction. * Extract interactions between elements of an array. * The routines in this file are not re-entrant. * * ********************************************************************* * * 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/extract/ExtArray.c,v 1.2 2009/05/30 03:14:00 tim Exp $"; #endif /* not lint */ #include #include #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 "utils/malloc.h" #include "textio/textio.h" #include "debug/debug.h" #include "extract/extract.h" #include "extract/extractInt.h" #include "utils/signals.h" #include "utils/styles.h" #include "windows/windows.h" #include "dbwind/dbwind.h" /* Canonical interaction areas */ #define AREA_A 0 #define AREA_B 1 #define AREA_C 2 /* Imports from elsewhere in this module */ extern int extHardProc(); /* Local data passed to extArrayTileToNode() and its children */ Point extArrayPrimXY; /* X, Y indices of primary array element */ Point extArrayInterXY; /* X, Y indices of intersecting array element */ Transform extArrayPTrans; /* Transform from primary element to root */ Transform extArrayITrans; /* Transform from intersecting element ... */ int extArrayWhich; /* Which interaction area is being processed */ ExtTree *extArrayPrimary; /* Primary array element */ /* Forward declarations */ int extArrayFunc(); int extArrayPrimaryFunc(), extArrayInterFunc(); char *extArrayRange(); char *extArrayTileToNode(); LabRegion *extArrayHardNode(); char *extArrayNodeName(); void extArrayProcess(); void extArrayAdjust(); void extArrayHardSearch(); #if 0 /* * ---------------------------------------------------------------------------- * extOutputGeneratedLabels --- * * Write to the .ext file output "node" lines for labels generated in * the parent cell where paint in the subcell is not otherwise * represented by a node in the parent. These nodes have no material * in the parent, and therefore have no capacitance or resistance * associated with them. * * ---------------------------------------------------------------------------- */ void extOutputGeneratedLabels(parentUse, f) CellUse *parentUse; FILE *f; { CellDef *parentDef; Label *lab; int n; parentDef = parentUse->cu_def; while ((lab = parentDef->cd_labels) != NULL) { if ((lab->lab_flags & LABEL_GENERATE) == 0) return; fprintf(f, "node \"%s\" 0 0 %d %d %s", lab->lab_text, lab->lab_rect.r_xbot, lab->lab_rect.r_ybot, DBTypeShortName(lab->lab_type)); for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) fprintf(f, " 0 0"); putc('\n', f); freeMagic(lab); parentDef->cd_labels = lab->lab_next; } } #endif /* * ---------------------------------------------------------------------------- * * extArray -- * * Extract all connections resulting from interactions within each * array of subcells in the cell parentUse->cu_def. * * This procedure only finds arrays, and then calls extArrayFunc() to * do the real work. See the comments there for more details. * * Results: * None. * * Side effects: * Outputs connections and adjustments to the file 'f'. * There are two kinds of records; see extSubtree for a description. * However, when we output nodenames, they may contain implicit * subscripting information, e.g, * * cap a[1:3]/In a[2:4]/Phi1 deltaC * * which is like 3 separate "cap" records: * * cap a[1]/In a[2]/Phi1 deltaC * cap a[2]/In a[3]/Phi1 deltaC * cap a[3]/In a[4]/Phi1 deltaC * * ---------------------------------------------------------------------------- */ void extArray(parentUse, f) CellUse *parentUse; FILE *f; { SearchContext scx; HierExtractArg ha; /* * The connection hash table is initialized here but doesn't get * cleared until the end. It is responsible for changes to the * node structure over the entire cell 'parentUse->cu_def'. */ ha.ha_outf = f; ha.ha_parentUse = parentUse; ha.ha_nodename = extArrayTileToNode; ha.ha_cumFlat.et_use = extYuseCum; HashInit(&ha.ha_connHash, 32, 0); /* The real work of processing each array is done by extArrayFunc() */ scx.scx_use = parentUse; scx.scx_trans = GeoIdentityTransform; scx.scx_area = TiPlaneRect; (void) DBCellSrArea(&scx, extArrayFunc, (ClientData) &ha); #if 0 /* Output generated labels and remove them from the parent */ extOutputGeneratedLabels(parentUse, f); #endif /* Output connections and node adjustments */ extOutputConns(&ha.ha_connHash, f); HashKill(&ha.ha_connHash); } /* * ---------------------------------------------------------------------------- * * extArrayFunc -- * * Given a CellUse as argument, extract and output all the connections that * result from interactions between neighboring elements of the array. * * Results: * Returns 2 always so we stop after the first CellUse in the array. * * Side effects: * Writes to the file 'ha->ha_outf' * * Design: * To extract all the connections made between members of an array, we * only have to look for interactions in three canonical areas, shaded as * A, B, and C in the diagram below. Each interaction area consists only * of the portion of overlap between the canonical cell (1 for A, B, and * 2 for C) and its neighbors. Hence the exact size of the interaction * areas depends on how much overlap there is. In the extreme cases, * there may be no areas to check at all (instances widely separated), * or there may even be areas with more than four instances overlapping * (spacing less than half the size of the instance). * * ------------------------------------------------- * | | | | * | 2 | | | * | | | | * | CCC | | * --------------CCC-------------------------------- * | | | | * | | | | * | | | | * | | | | * AAAAAAAAAAAAAAaba-------------------------------| * AAAAAAAAAAAAAAbab | | * | BBB | | * | 1 BBB | | * | BBB | | * --------------BBB-------------------------------- * * In area A, we check for interactions with 1 and the elements directly * above, or above and to the right. In area B, we check for interactions * only with elements at the same level but to the right. In area C, we * check for interactions only with elements below and to the right. * * ---------------------------------------------------------------------------- */ int extArrayFunc(scx, ha) SearchContext *scx; /* Describes first element of array */ HierExtractArg *ha; /* Extraction context */ { int xsep, ysep; /* X, Y separation in parent coordinates */ int xsize, ysize; /* X, Y sizes in parent coordinates */ int halo = ExtCurStyle->exts_sideCoupleHalo + 1; CellUse *use = scx->scx_use; CellDef *def = use->cu_def; Rect tmp, tmp2, primary; /* Skip uses that aren't arrays */ if ((use->cu_xlo == use->cu_xhi) && (use->cu_ylo == use->cu_yhi)) return (2); if ((ExtOptions & (EXT_DOCOUPLING|EXT_DOADJUST)) != (EXT_DOCOUPLING|EXT_DOADJUST)) halo = 1; /* * Compute the sizes and separations of elements, in coordinates * of the parent. If the array is 1-dimensional, we set the * corresponding spacing to an impossibly large distance. */ tmp.r_xbot = tmp.r_ybot = 0; if (use->cu_xlo == use->cu_xhi) tmp.r_xtop = def->cd_bbox.r_xtop - def->cd_bbox.r_xbot + 2; else tmp.r_xtop = use->cu_xsep; if (use->cu_ylo == use->cu_yhi) tmp.r_ytop = def->cd_bbox.r_ytop - def->cd_bbox.r_ybot + 2; else tmp.r_ytop = use->cu_ysep; GeoTransRect(&use->cu_transform, &tmp, &tmp2); xsep = tmp2.r_xtop - tmp2.r_xbot; ysep = tmp2.r_ytop - tmp2.r_ybot; GeoTransRect(&use->cu_transform, &def->cd_bbox, &tmp2); xsize = tmp2.r_xtop - tmp2.r_xbot; ysize = tmp2.r_ytop - tmp2.r_ybot; /* * For areas A and B, we will be looking at the interactions * between the element in the lower-left corner of the array * (in parent coordinates) and its neighbors to the top, right, * and top-right. */ primary.r_xbot = use->cu_bbox.r_xbot; primary.r_xtop = use->cu_bbox.r_xbot + 1; primary.r_ybot = use->cu_bbox.r_ybot; primary.r_ytop = use->cu_bbox.r_ybot + 1; ha->ha_subUse = use; /* Area A */ if (ysep <= ysize) { ha->ha_clipArea.r_xbot = use->cu_bbox.r_xbot; ha->ha_clipArea.r_xtop = use->cu_bbox.r_xbot + xsize + halo; ha->ha_clipArea.r_ybot = use->cu_bbox.r_ybot + ysep - halo; ha->ha_clipArea.r_ytop = use->cu_bbox.r_ybot + ysize + halo; ha->ha_interArea = ha->ha_clipArea; extArrayWhich = AREA_A; extArrayProcess(ha, &primary); if (SigInterruptPending) return (1); } /* Area B */ if (xsep <= xsize) { ha->ha_clipArea.r_xbot = use->cu_bbox.r_xbot + xsep - halo; ha->ha_clipArea.r_xtop = use->cu_bbox.r_xbot + xsize + halo; ha->ha_clipArea.r_ybot = use->cu_bbox.r_ybot; ha->ha_clipArea.r_ytop = use->cu_bbox.r_ybot + ysize + halo; ha->ha_interArea = ha->ha_clipArea; extArrayWhich = AREA_B; extArrayProcess(ha, &primary); if (SigInterruptPending) return (1); } /* Area C */ if (ysep <= ysize && xsep <= xsize) { /* * For area C, we will be looking at the interactions between * the element in the upper-left corner of the array (in parent * coordinates) and its neighbors to the bottom-right only. */ primary.r_ybot = use->cu_bbox.r_ytop - 1; primary.r_ytop = use->cu_bbox.r_ytop; ha->ha_clipArea.r_xbot = use->cu_bbox.r_xbot + xsep - halo; ha->ha_clipArea.r_xtop = use->cu_bbox.r_xbot + xsize + halo; ha->ha_clipArea.r_ybot = use->cu_bbox.r_ytop - ysize - halo; ha->ha_clipArea.r_ytop = use->cu_bbox.r_ytop - ysep + halo; ha->ha_interArea = ha->ha_clipArea; extArrayWhich = AREA_C; extArrayProcess(ha, &primary); } return (2); } /* * ---------------------------------------------------------------------------- * * extArrayProcess -- * * Process a single canonical interaction area for the arrayed CellUse * 'ha->ha_subUse'. The area 'primary', in parent coordinates, should * be contained in only one element of the array. For each other element * in the array that appears in the area 'ha->ha_interArea', we determine * all connections and R/C adjustments and output them in the form of an * implicitly iterated "merge" or "adjust" line for the rest of the array. * * Expects extArrayWhich to be one of AREA_A, AREA_B, or AREA_C; this * is the interaction area being searched. * * Results: * None. * * Side effects: * See extArrayPrimaryFunc and extArrayInterFunc for details. * Trashes ha->ha_cumFlat.et_use. * * ---------------------------------------------------------------------------- */ void extArrayProcess(ha, primary) HierExtractArg *ha; Rect *primary; /* Area guaranteed to contain only the primary * element of the array, against which we will * extract all other elements that overlap the * area 'ha->ha_interArea'. */ { CellUse *use = ha->ha_subUse; /* * Yank the primary array element into a new yank buffer * that we leave extArrayPrimary pointing to. */ extArrayPrimary = (ExtTree *) NULL; if (DBArraySr(use, primary, extArrayPrimaryFunc, (ClientData) ha) == 0) { DBWFeedbackAdd(primary, "System error: expected array element but none found", ha->ha_parentUse->cu_def, 1, STYLE_MEDIUMHIGHLIGHTS); extNumFatal++; return; } if (SigInterruptPending) goto done; /* * Find and process all other elements that intersect ha->ha_interArea, * extracting connections against extArrayPrimary. */ (void) DBArraySr(use, &ha->ha_interArea, extArrayInterFunc, (ClientData)ha); done: if (extArrayPrimary) extHierFreeOne(extArrayPrimary); extArrayPrimary = (ExtTree *) NULL; } /* * ---------------------------------------------------------------------------- * * extArrayPrimaryFunc -- * * Called by DBArraySr, which should only find a single array element. * We record which element was found by setting extArrayPrimXY.p_x * and extArrayPrimXY.p_y, and also the transform in extArrayPTrans * for use by extArrayHardNode(). * * We yank the paint and labels of this array element into a new ExtTree, * which we leave extArrayPrimary pointing to. The area, perimeter, * capacitance, and coupling capacitance for this element are extracted. * * Results: * Returns 1 to cause DBArraySr to abort and return 1 itself. * This is so the caller of DBArraySr can tell whether or not * any elements were found (a sanity check). * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ int extArrayPrimaryFunc(use, trans, x, y, ha) CellUse *use; /* Use of which this is an array element */ Transform *trans; /* Transform from coordinates of use->cu_def to those * in use->cu_parent, for the array element (x, y). */ int x, y; /* X, Y indices of this array element */ HierExtractArg *ha; { CellDef *primDef; HierYank hy; /* * Remember the indices of this array element. * When we are looking for all other array elements intersecting * this area, we will ignore this element. We also remember the * transform in case we need to use it in extArrayHardNode(). */ extArrayPrimXY.p_x = x, extArrayPrimXY.p_y = y; extArrayPTrans = *trans; /* Restrict searching to interaction area for this element of array */ GeoTransRect(trans, &use->cu_def->cd_bbox, &ha->ha_subArea); GeoClip(&ha->ha_subArea, &ha->ha_interArea); /* Yank this element into the primary buffer */ extArrayPrimary = extHierNewOne(); hy.hy_area = &ha->ha_subArea; hy.hy_target = extArrayPrimary->et_use; hy.hy_prefix = FALSE; (void) extHierYankFunc(use, trans, x, y, &hy); /* * Extract extArrayPrimary, getting node capacitance, perimeter, * and area, and coupling capacitances between nodes. Assign * labels from primDef's label list. */ primDef = extArrayPrimary->et_use->cu_def; extArrayPrimary->et_nodes = extFindNodes(primDef, &ha->ha_clipArea); ExtLabelRegions(primDef, ExtCurStyle->exts_nodeConn, &extArrayPrimary->et_nodes, &ha->ha_clipArea); if ((ExtOptions & (EXT_DOADJUST|EXT_DOCOUPLING)) == (EXT_DOADJUST|EXT_DOCOUPLING)) extFindCoupling(primDef, &extArrayPrimary->et_coupleHash, &ha->ha_clipArea); return (1); } /* * ---------------------------------------------------------------------------- * * extArrayInterFunc -- * * Called by DBArraySr, which should find all array elements inside * 'ha->ha_interArea' (in parent coordinates). If the array element * (x, y) is the same as the primary element found by extArrayPrimaryFunc, * i.e, the element (extArrayPrimXY.p_x, extArrayPrimXY.p_y), we * skip it. Otherwise, we yank the overlap of this array element with * 'ha->ha_interArea' into its own subtree and extract the interactions * between it and extArrayPrimary. * * Results: * Returns 0 to cause DBArraySr to continue. * * Side effects: * Sets extArrayInterXY.p_x, extArrayInterXY.p_y to the element * (x, y) so that lower-level functions have access to this information. * * ---------------------------------------------------------------------------- */ int extArrayInterFunc(use, trans, x, y, ha) CellUse *use; /* Use of which this is an array element */ Transform *trans; /* Transform from use->cu_def to use->cu_parent * coordinates, for the array element (x, y). */ int x, y; /* X, Y of this array element in use->cu_def coords */ HierExtractArg *ha; { CellUse *cumUse = ha->ha_cumFlat.et_use; CellDef *cumDef = cumUse->cu_def; SearchContext scx; CellDef *oneDef; ExtTree *oneFlat; HierYank hy; /* Skip this element if it is the primary one */ if (x == extArrayPrimXY.p_x && y == extArrayPrimXY.p_y) return (0); switch (extArrayWhich) { /* * Area A is above, or above and to the right. * Given where we search, there are no elements below and * to the right of area A. */ case AREA_A: if (x == extArrayPrimXY.p_x || y == extArrayPrimXY.p_y) { /* * Exactly one of X or Y is the same as for * the primary element. */ if (trans->t_a) { /* * X, Y are still X, Y in parent. * If X is different, this element is only to the * right and so belongs to area B. */ if (x != extArrayPrimXY.p_x) return (0); } else { /* * X, Y are interchanged in parent. * If Y is different, this element is only to the * right and so belongs to area B. */ if (y != extArrayPrimXY.p_y) return (0); } } break; /* * Area B is only interactions to the right (not * above, or diagonally above or below), in parent * coordinates. */ case AREA_B: if (trans->t_a) { /* x, y are still x, y in parent */ if (y != extArrayPrimXY.p_y) return (0); } else { /* x, y are interchanged in parent */ if (x != extArrayPrimXY.p_x) return (0); } break; /* * Area C checks only diagonal interactions. * Given where we search, there are no interactions * above and to the right of area C; the only diagonal * interactions are below and to the right. */ case AREA_C: if (x == extArrayPrimXY.p_x || y == extArrayPrimXY.p_y) return (0); break; } /* Indicate which element this is to connection output routines */ extArrayInterXY.p_x = x, extArrayInterXY.p_y = y; extArrayITrans = *trans; /* Restrict searching to interaction area for this element of array */ GeoTransRect(trans, &use->cu_def->cd_bbox, &ha->ha_subArea); GeoClip(&ha->ha_subArea, &ha->ha_interArea); /* Yank this array element into a new ExtTree */ oneFlat = extHierNewOne(); hy.hy_area = &ha->ha_subArea; hy.hy_target = oneFlat->et_use; hy.hy_prefix = FALSE; (void) extHierYankFunc(use, trans, x, y, &hy); /* * Extract node capacitance, perimeter, area, and coupling capacitance * for this subtree. Labels come from the hierarchical labels yanked * above, but may have additional labels added when we find names the * hard way. */ oneDef = oneFlat->et_use->cu_def; oneFlat->et_nodes = extFindNodes(oneDef, &ha->ha_clipArea), ExtLabelRegions(oneDef, ExtCurStyle->exts_nodeConn, &oneFlat->et_nodes, &ha->ha_clipArea); if ((ExtOptions & (EXT_DOADJUST|EXT_DOCOUPLING)) == (EXT_DOADJUST|EXT_DOCOUPLING)) extFindCoupling(oneDef, &oneFlat->et_coupleHash, &ha->ha_clipArea); /* Process connections */ extHierConnections(ha, extArrayPrimary, oneFlat); ha->ha_cumFlat.et_nodes = (NodeRegion *) NULL; if (ExtOptions & EXT_DOADJUST) { /* Build cumulative buffer from both extArrayPrimary and oneFlat */ scx.scx_trans = GeoIdentityTransform; scx.scx_area = TiPlaneRect; scx.scx_use = oneFlat->et_use; DBCellCopyPaint(&scx, &DBAllButSpaceBits, 0, cumUse); scx.scx_use = extArrayPrimary->et_use; DBCellCopyPaint(&scx, &DBAllButSpaceBits, 0, cumUse); /* * Extract everything in the cumulative buffer. * Don't bother labelling the nodes, though, since we will never look * at the node labels (we only search extArrayPrimary or oneFlat for * the name of a node). Finally, compute and output adjustments for * nodes and coupling capacitance. */ HashInit(&ha->ha_cumFlat.et_coupleHash, 32, HashSize(sizeof (CoupleKey))); ha->ha_cumFlat.et_nodes = extFindNodes(cumDef, &ha->ha_clipArea); if (ExtOptions & EXT_DOCOUPLING) extFindCoupling(cumDef, &ha->ha_cumFlat.et_coupleHash, &ha->ha_clipArea); extArrayAdjust(ha, oneFlat, extArrayPrimary); if (ExtOptions & EXT_DOCOUPLING) extCapHashKill(&ha->ha_cumFlat.et_coupleHash); } /* Clean up */ if (oneFlat) extHierFreeOne(oneFlat); if (ha->ha_cumFlat.et_nodes) ExtFreeLabRegions((LabRegion *) ha->ha_cumFlat.et_nodes); ha->ha_cumFlat.et_nodes = (NodeRegion *) NULL; DBCellClearDef(cumDef); return (0); } void extArrayAdjust(ha, et1, et2) HierExtractArg *ha; ExtTree *et1, *et2; { CapValue cap; /* value of capacitance WAS: int */ NodeRegion *np; CoupleKey *ck; HashEntry *he; NodeName *nn; HashSearch hs; char *name; /* * Initialize the capacitance, perimeter, and area values * in the Nodes in the hash table ha->ha_connHash, taking * their values from the NodeRegions in ha->ha_cumFlat. */ for (np = ha->ha_cumFlat.et_nodes; np; np = np->nreg_next) { if ((name = extArrayNodeName(np, ha, et1, et2)) && (he = HashLookOnly(&ha->ha_connHash, name)) && (nn = (NodeName *) HashGetValue(he))) { nn->nn_node->node_cap = np->nreg_cap; bcopy((char *) np->nreg_pa, (char *) nn->nn_node->node_pa, ExtCurStyle->exts_numResistClasses * sizeof (PerimArea)); } } /* * Coupling capacitance from et1 and et2 gets subtracted from that * stored in ha->ha_cumFlat. Also, subtract the node capacitance, * perimeter, and area of each subtree from ha->ha_cumFlat's nodes. */ extHierAdjustments(ha, &ha->ha_cumFlat, et1, et1); extHierAdjustments(ha, &ha->ha_cumFlat, et2, et2); HashStartSearch(&hs); while (he = HashNext(&ha->ha_cumFlat.et_coupleHash, &hs)) { cap = extGetCapValue(he) / ExtCurStyle->exts_capScale; if (cap == 0) continue; ck = (CoupleKey *) he->h_key.h_words; name = extArrayNodeName(ck->ck_1, ha, et1, et2); fprintf(ha->ha_outf, "cap \"%s\" ", name); name = extArrayNodeName(ck->ck_2, ha, et1, et2); fprintf(ha->ha_outf, "\"%s\" %lg\n", name, cap); } } char * extArrayNodeName(np, ha, et1, et2) NodeRegion *np; HierExtractArg *ha; ExtTree *et1, *et2; { Tile *tp; tp = extNodeToTile(np, et1); if (tp && TiGetType(tp) != TT_SPACE && extHasRegion(tp, extUnInit)) return (extArrayTileToNode(tp, np->nreg_pnum, et1, ha, TRUE)); tp = extNodeToTile(np, et2); if (tp && TiGetType(tp) != TT_SPACE && extHasRegion(tp, extUnInit)) return (extArrayTileToNode(tp, np->nreg_pnum, et2, ha, TRUE)); return ("(none)"); } /* * ---------------------------------------------------------------------------- * * extArrayTileToNode -- * * Map from a Tile in a given ExtTree to the name of the node * containing that tile. * * The node associated with a tile can be determined in one of the * following ways: * * (1) Look for a label on the list of the Region pointed to by the * tile planes of 'et->et_use->cu_def'. If no label was found, * then try (2). * * (2) Call extArrayHardNode() to do a painful extraction of a label. * See the comments in extArrayHardNode() for a description of * the algorithm used. Only do this if doHard is TRUE. * * The actual name we use will be prefixed by the array use identifier * (from ha->ha_subUse), followed by the range of subscripts for that array * for which this is valid. The ExtTree 'et' tells us whether we are looking * at the primary element of an array (when it is extArrayPrimary), or at * one of the elements against which the primary is being extracted. * * Results: * Returns a pointer to the name of the node containing * the tile. If no node name was found, and doHard was * TRUE, return the string "(none)"; if doHard was FALSE, * return NULL. * * Side effects: * The string returned is allocated from a static buffer, so * subsequent calls to extArrayTileToNode() will overwrite * the results returned in previous calls. * * Records an error with the feedback package if no node name * could be found, and doHard was TRUE. * * ---------------------------------------------------------------------------- */ char * extArrayTileToNode(tp, pNum, et, ha, doHard) Tile *tp; int pNum; ExtTree *et; HierExtractArg *ha; bool doHard; /* If TRUE, we look up this node's name the hard way * if we can't find it any other way; otherwise, we * return NULL if we can't find the node's name. */ { static char name[2048]; static char errorStr[] = "Cannot find the name of this node (probable extractor error)"; CellDef *def = et->et_use->cu_def; CellUse *use = ha->ha_subUse; char *srcp, *dstp, *endp; bool hasX = (use->cu_xlo != use->cu_xhi); bool hasY = (use->cu_ylo != use->cu_yhi); int xdiff = extArrayInterXY.p_x - extArrayPrimXY.p_x; int ydiff = extArrayInterXY.p_y - extArrayPrimXY.p_y; LabRegion *reg; Rect r; if (extHasRegion(tp, extUnInit)) { reg = (LabRegion *) extGetRegion(tp); if (reg->lreg_labels) goto found; } if (!DebugIsSet(extDebugID, extDebNoHard)) if (reg = (LabRegion *) extArrayHardNode(tp, pNum, def, ha)) goto found; /* Blew it */ if (!doHard) return ((char *) NULL); extNumFatal++; TiToRect(tp, &r); if (!DebugIsSet(extDebugID, extDebNoFeedback)) DBWFeedbackAdd(&r, errorStr, ha->ha_parentUse->cu_def, 1, STYLE_MEDIUMHIGHLIGHTS); return ("(none)"); found: /* Copy in the use id, leaving room for [%d:%d,%d:%d] at the end */ srcp = use->cu_id; dstp = name; endp = &name[sizeof name - 40]; while (dstp < endp && (*dstp++ = *srcp++)) /* Nothing */; if (dstp >= endp) goto done; dstp--; #define Far(v, lo, hi) ((v) == (lo) ? (hi) : (lo)) #define FarX(u) Far(extArrayPrimXY.p_x, (u)->cu_xlo, (u)->cu_xhi) #define FarY(u) Far(extArrayPrimXY.p_y, (u)->cu_ylo, (u)->cu_yhi) /* * Append the array subscripts. * Remember that 2-d arrays are subscripted [y,x] and not [x,y]. */ if (def == extArrayPrimary->et_use->cu_def) { if (hasY) dstp = extArrayRange(dstp, extArrayPrimXY.p_y, FarY(use) - ydiff, FALSE, hasX); if (hasX) dstp = extArrayRange(dstp, extArrayPrimXY.p_x, FarX(use) - xdiff, hasY, FALSE); } else { if (hasY) dstp = extArrayRange(dstp, extArrayInterXY.p_y, FarY(use), FALSE, hasX); if (hasX) dstp = extArrayRange(dstp, extArrayInterXY.p_x, FarX(use), hasY, FALSE); } #undef Far #undef FarX #undef FarY done: *dstp++ = '/'; endp = &name[sizeof name - 1]; srcp = extNodeName(reg); while (dstp < endp && (*dstp++ = *srcp++)) /* Nothing */; *dstp = '\0'; return (name); } /* * ---------------------------------------------------------------------------- * * extArrayRange -- * * Called by extArrayTileToNode above, we print a range of the form [lo:hi] * into the string pointed to by 'dstp'. Guarantees that lo <= hi. * * Results: * Returns a pointer to the NULL byte at the end of the string * we print into (dstp). * * Side effects: * Writes characters into 'dstp', which should be large enough * to hold any possible string of the form [int:int]. * * ---------------------------------------------------------------------------- */ char * extArrayRange(dstp, lo, hi, prevRange, followRange) char *dstp; int lo, hi; bool prevRange; /* TRUE if preceded by a range */ bool followRange; /* TRUE if followed by a range */ { if (!prevRange) *dstp++ = '['; if (hi < lo) (void) sprintf(dstp, "%d:%d", hi, lo); else (void) sprintf(dstp, "%d:%d", lo, hi); while (*dstp++) /* Nothing */; dstp[-1] = followRange ? ',' : ']'; *dstp = '\0'; return (dstp); } /* * ---------------------------------------------------------------------------- * * extArrayHardNode -- * * Find a node name for the electrical node containing the tile 'tp' * the hard way. We assume tp->ti_client points to a LabRegion that * had no labels associated with it; if we succeed, we leave this * LabRegion pointing to a newly allocated LabelList and Label. * * Results: * Returns a pointer to LabRegion for the node to which the tile * 'tp' belongs. Returns NULL if no region could be found. * * Side effects: * None. * * Algorithm: * Search in the appropriate array element to the yank buffer * in question: if 'def' is the primary buffer, search the * element (extArrayPrimXY.p_x, extArrayPrimXY.p_y); otherwise, * search (extArrayInterXY.p_x, extArrayInterXY.p_y). * * For each cell we find in the course of a hierarchical search * of this array element in the area of the tile 'tp', trace out * the nodes lying in the area of the overlap, and then do a label * assignment for those nodes. As soon as we find a label, we're * done. Otherwise, we reset this def back the way we found it * and continue on to the next cell in our search. * * ---------------------------------------------------------------------------- */ LabRegion * extArrayHardNode(tp, pNum, def, ha) Tile *tp; int pNum; CellDef *def; HierExtractArg *ha; { TileType type = TiGetType(tp); char labelBuf[4096]; SearchContext scx; HardWay arg; arg.hw_ha = ha; arg.hw_label = (Label *) NULL; arg.hw_mask = DBPlaneTypes[pNum]; TTMaskAndMask(&arg.hw_mask, &DBConnectTbl[type]); arg.hw_tpath.tp_last = &labelBuf[sizeof labelBuf - 3]; arg.hw_tpath.tp_first = arg.hw_tpath.tp_next = labelBuf; arg.hw_prefix = FALSE; arg.hw_autogen = FALSE; TiToRect(tp, &arg.hw_area); scx.scx_use = ha->ha_subUse; /* Find a label in the interaction area */ labelBuf[0] = '\0'; extArrayHardSearch(def, &arg, &scx, extHardProc); if (arg.hw_label == NULL) { labelBuf[0] = '\0'; arg.hw_autogen = TRUE; extArrayHardSearch(def, &arg, &scx, extHardProc); } if (arg.hw_label) { LabRegion *lreg; LabelList *ll; lreg = (LabRegion *) extGetRegion(tp); ll = (LabelList *) mallocMagic((unsigned) (sizeof (LabelList))); lreg->lreg_labels = ll; ll->ll_next = (LabelList *) NULL; ll->ll_label = arg.hw_label; arg.hw_label->lab_next = def->cd_labels; def->cd_labels = arg.hw_label; return (lreg); } return ((LabRegion *) NULL); } /* * ---------------------------------------------------------------------------- * * extArrayHardSearch -- * * Do the actual work of calling (*proc)() either to find a label the hard * way, or to create a new label. Called from extArrayHardNode above. * * Results: * None. * * Side effects: * Those of (*proc)(). * * ---------------------------------------------------------------------------- */ void extArrayHardSearch(def, arg, scx, proc) CellDef *def; HardWay *arg; SearchContext *scx; int (*proc)(); { Transform tinv; if (def == extArrayPrimary->et_use->cu_def) { scx->scx_trans = extArrayPTrans; scx->scx_x = extArrayPrimXY.p_x; scx->scx_y = extArrayPrimXY.p_y; } else { scx->scx_trans = extArrayITrans; scx->scx_x = extArrayInterXY.p_x; scx->scx_y = extArrayInterXY.p_y; } GeoInvertTrans(&scx->scx_trans, &tinv); GeoTransRect(&tinv, &arg->hw_area, &scx->scx_area); (void) (*proc)(scx, arg); } magic-8.0.210/extract/ExtMain.c0000644000175000001440000004251610751423606014651 0ustar timusers/* * ExtMain.c -- * * Circuit extraction. * Command interface. * * ********************************************************************* * * 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/extract/ExtMain.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/styles.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/malloc.h" #include "textio/textio.h" #include "debug/debug.h" #include "extract/extract.h" #include "extract/extractInt.h" #include "utils/signals.h" #include "utils/stack.h" #include "utils/utils.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "utils/main.h" #include "utils/undo.h" /* Imports from elsewhere in this module */ extern FILE *extFileOpen(); /* ------------------------ Exported variables ------------------------ */ /* * See extract.h for the bit flags that may be set in the following. * If any are set, the corresponding warnings get generated, leaving * feedback messages. If this word is zero, only fatal errors are * reported. */ int ExtDoWarn = EXTWARN_DUP|EXTWARN_FETS; int ExtOptions = EXT_DOALL; /* --------------------------- Global data ---------------------------- */ /* Cumulative yank buffer for hierarchical circuit extraction */ CellUse *extYuseCum = NULL; CellDef *extYdefCum = NULL; /* Identifier returned by the debug module for circuit extraction */ ClientData extDebugID; /* Number of errors encountered during extraction */ int extNumFatal; int extNumWarnings; /* Dummy use pointing to def being extracted */ CellUse *extParentUse; /* ------------------------ Data local to this file ------------------- */ /* Stack of defs pending extraction */ Stack *extDefStack; /* Forward declarations */ int extDefInitFunc(), extDefPushFunc(); void extParents(); void extDefParentFunc(); void extDefParentAreaFunc(); void extExtractStack(); bool extContainsGeometry(); bool extContainsCellFunc(); bool extTimestampMisMatch(); /* * ---------------------------------------------------------------------------- * * ExtInit -- * * Initialize the technology-independent part of the extraction module. * This procedure should be called once, after the database module has * been initialized. * * Results: * None. * * Side effects: * Initializes the local variables of the extraction module. * Registers the extractor with the debugging module. * * ---------------------------------------------------------------------------- */ void ExtInit() { int n; static struct { char *di_name; int *di_id; } debugFlags[] = { "areaenum", &extDebAreaEnum, "array", &extDebArray, "hardway", &extDebHardWay, "hiercap", &extDebHierCap, "hierareacap", &extDebHierAreaCap, "label", &extDebLabel, "length", &extDebLength, "neighbor", &extDebNeighbor, "noarray", &extDebNoArray, "nofeedback", &extDebNoFeedback, "nohard", &extDebNoHard, "nosubcell", &extDebNoSubcell, "perimeter", &extDebPerim, "resist", &extDebResist, "visonly", &extDebVisOnly, "yank", &extDebYank, 0 }; /* Register ourselves with the debugging module */ extDebugID = DebugAddClient("extract", sizeof debugFlags/sizeof debugFlags[0]); for (n = 0; debugFlags[n].di_name; n++) *(debugFlags[n].di_id) = DebugAddFlag(extDebugID, debugFlags[n].di_name); /* Create the yank buffer used for hierarchical extraction */ DBNewYank("__ext_cumulative", &extYuseCum, &extYdefCum); /* Create the dummy use also used in hierarchical extraction */ extParentUse = DBCellNewUse(extYdefCum, (char *) NULL); DBSetTrans(extParentUse, &GeoIdentityTransform); /* Initialize the hash tables used in ExtLength.c */ extLengthInit(); } /* * ---------------------------------------------------------------------------- * * ExtAll -- * * Extract the subtree rooted at the CellDef 'rootUse->cu_def'. * Each cell is extracted to a file in the current directory * whose name consists of the last part of the cell's path, * with a .ext suffix. * * Results: * None. * * Side effects: * Creates a number of .ext files and writes to them. * Adds feedback information where errors have occurred. * * ---------------------------------------------------------------------------- */ void ExtAll(rootUse) CellUse *rootUse; { /* Make sure the entire subtree is read in */ DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox); /* Fix up bounding boxes if they've changed */ DBFixMismatch(); /* Mark all defs as being unvisited */ (void) DBCellSrDefs(0, extDefInitFunc, (ClientData) 0); /* Recursively visit all defs in the tree and push on stack */ extDefStack = StackNew(100); (void) extDefPushFunc(rootUse); /* Now extract all the cells we just found */ extExtractStack(extDefStack, TRUE, rootUse->cu_def); StackFree(extDefStack); } /* * Function to initialize the client data field of all * cell defs, in preparation for extracting a subtree * rooted at a particular def. */ int extDefInitFunc(def) CellDef *def; { def->cd_client = (ClientData) 0; return (0); } /* * Function to push each cell def on extDefStack * if it hasn't already been pushed, and then recurse * on all that def's children. */ int extDefPushFunc(use) CellUse *use; { CellDef *def = use->cu_def; if (def->cd_client || (def->cd_flags&CDINTERNAL)) return (0); def->cd_client = (ClientData) 1; StackPush((ClientData) def, extDefStack); (void) DBCellEnum(def, extDefPushFunc, (ClientData) 0); return (0); } /* * ---------------------------------------------------------------------------- * * ExtUnique -- * * For each cell in the subtree rooted at rootUse->cu_def, make * sure that there are not two different nodes with the same label. * If there are, and either the label ends in a '#' or allNames is * TRUE, we generate unique names by appending a numeric suffix to * all but one of the offending labels. Otherwise, if the label * doesn't end in a '!', we leave feedback. * * Results: * None. * * Side effects: * May modify the label lists of some of the cells rooted * at rootUse->cu_def, and mark the cells as CDMODIFIED. * May also leave feedback. * * ---------------------------------------------------------------------------- */ void ExtUnique(rootUse, allNames) CellUse *rootUse; bool allNames; { CellDef *def; int nwarn; /* Make sure the entire subtree is read in */ DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox); /* Fix up bounding boxes if they've changed */ DBFixMismatch(); /* Mark all defs as being unvisited */ (void) DBCellSrDefs(0, extDefInitFunc, (ClientData) 0); /* Recursively visit all defs in the tree and push on stack */ extDefStack = StackNew(100); (void) extDefPushFunc(rootUse); /* Now process all the cells we just found */ nwarn = 0; while (def = (CellDef *) StackPop(extDefStack)) { def->cd_client = (ClientData) 0; if (!SigInterruptPending) nwarn += extUniqueCell(def, allNames); } StackFree(extDefStack); if (nwarn) TxError("%d uncorrected errors (see the feedback info)\n", nwarn); } /* * ---------------------------------------------------------------------------- * * ExtParents -- * ExtShowParents -- * * ExtParents extracts the cell use->cu_def and all its parents. * ExtShowParents merely finds and prints all the parents without * extracting them. * * As in ExtAll, each cell is extracted to a file in the current * directory whose name consists of the last part of the cell's path, * with a .ext suffix. * * Results: * None. * * Side effects: * Creates a number of .ext files and writes to them. * Adds feedback information where errors have occurred. * * ---------------------------------------------------------------------------- */ void ExtParents(use) CellUse *use; { extParents(use, TRUE); } void ExtShowParents(use) CellUse *use; { extParents(use, FALSE); } void extParents(use, doExtract) CellUse *use; bool doExtract; /* If TRUE, we extract; if FALSE, we print */ { /* Mark all defs as being unvisited */ (void) DBCellSrDefs(0, extDefInitFunc, (ClientData) 0); /* Recursively visit all defs in the tree and push on stack */ extDefStack = StackNew(100); extDefParentFunc(use->cu_def); /* Now extract all the cells we just found */ extExtractStack(extDefStack, doExtract, (CellDef *) NULL); StackFree(extDefStack); } /* * Function to visit all the parents of 'def' and push them on * extDefStack. We only push a def if it is unmarked, ie, its * cd_client field is 0. After pushing a def, we mark it by * setting its cd_client field to 1. */ void extDefParentFunc(def) CellDef *def; { CellUse *parent; if (def->cd_client || (def->cd_flags&CDINTERNAL)) return; def->cd_client = (ClientData) 1; StackPush((ClientData) def, extDefStack); for (parent = def->cd_parents; parent; parent = parent->cu_nextuse) if (parent->cu_parent) extDefParentFunc(parent->cu_parent); } /* * ---------------------------------------------------------------------------- * * ExtParentArea -- * * ExtParentArea extracts the cell use->cu_def and each of its * parents that contain geometry touching or overlapping the area * of use->cu_def. * * Results: * None. * * Side effects: * Creates one or more .ext files and writes to them. * Adds feedback information where errors have occurred. * * ---------------------------------------------------------------------------- */ void ExtParentArea(use, changedArea, doExtract) CellUse *use; /* Use->cu_def changed; extract its affected parents */ Rect *changedArea; /* Area changed in use->cu_def coordinates */ bool doExtract; /* If TRUE, we extract; if FALSE, we just print names * of the cells we would extract. */ { Rect area; /* Mark all defs as being unvisited */ (void) DBCellSrDefs(0, extDefInitFunc, (ClientData) 0); /* * Recursively visit all defs in the tree * and push on stack if they contain any geometry * overlapping or touching the area 'changedArea'. */ area = *changedArea; area.r_xbot--, area.r_ybot--; area.r_xtop++, area.r_ytop++; extDefStack = StackNew(100); extDefParentAreaFunc(use->cu_def, use->cu_def, (CellUse *) NULL, &area); /* Now extract all the cells we just found */ extExtractStack(extDefStack, doExtract, (CellDef *) NULL); StackFree(extDefStack); } /* * Function to visit all the parents of 'def' and push them on * extDefStack. We only push a def if it is unmarked, ie, its * cd_client field is 0, and if it is either 'baseDef' or it * contains geometry or other subcells in the area 'area'. * We mark each def visited by setting cd_client to 1. */ void extDefParentAreaFunc(def, baseDef, allButUse, area) CellDef *def; CellDef *baseDef; CellUse *allButUse; Rect *area; { int x, y, xoff, yoff; CellUse *parent; Transform t, t2; Rect parArea; if (def->cd_client || (def->cd_flags&CDINTERNAL)) return; if (def == baseDef || extContainsGeometry(def, allButUse, area)) { def->cd_client = (ClientData) 1; StackPush((ClientData) def, extDefStack); } for (parent = def->cd_parents; parent; parent = parent->cu_nextuse) { if (parent->cu_parent) { for (x = parent->cu_xlo; x <= parent->cu_xhi; x++) { for (y = parent->cu_ylo; y <= parent->cu_yhi; y++) { xoff = (x - parent->cu_xlo) * parent->cu_xsep; yoff = (y - parent->cu_ylo) * parent->cu_ysep; GeoTranslateTrans(&GeoIdentityTransform, xoff, yoff, &t); GeoTransTrans(&t, &parent->cu_transform, &t2); GeoTransRect(&t2, area, &parArea); extDefParentAreaFunc(parent->cu_parent, baseDef, parent, &parArea); } } } } } bool extContainsGeometry(def, allButUse, area) CellDef *def; CellUse *allButUse; Rect *area; { int extContainsPaintFunc(); bool extContainsCellFunc(); int pNum; if (TiSrArea((Tile *) NULL, def->cd_planes[PL_CELL], area, extContainsCellFunc, (ClientData) allButUse)) return (TRUE); for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) if (DBSrPaintArea((Tile *) NULL, def->cd_planes[pNum], area, &DBAllButSpaceBits, extContainsPaintFunc, (ClientData) NULL)) return (TRUE); return (FALSE); } bool extContainsCellFunc(tile, allButUse) Tile *tile; CellUse *allButUse; { CellTileBody *ctb; for (ctb = (CellTileBody *) TiGetBody(tile); ctb; ctb = ctb->ctb_next) if (ctb->ctb_use != allButUse) return (TRUE); return (FALSE); } int extContainsPaintFunc() { return (1); } /* * ---------------------------------------------------------------------------- * * ExtIncremental -- * * Starting at 'rootUse', extract all cell defs that have changed. * Right now, we forcibly read in the entire tree before doing the * extraction. * * Results: * None. * * Side effects: * Creates a number of .ext files and writes to them. * Adds feedback information where errors have occurred. * * ---------------------------------------------------------------------------- */ void ExtIncremental(rootUse) CellUse *rootUse; { /* Make sure the entire subtree is read in */ DBCellReadArea(rootUse, &rootUse->cu_def->cd_bbox); /* Fix up bounding boxes if they've changed */ DBFixMismatch(); /* Update all timestamps */ DBUpdateStamps(); /* Mark all defs as being unvisited */ (void) DBCellSrDefs(0, extDefInitFunc, (ClientData) 0); /* * Recursively visit all defs in the tree * and push on stack if they need extraction. */ extDefStack = StackNew(100); (void) extDefIncrementalFunc(rootUse); /* Now extract all the cells we just found */ extExtractStack(extDefStack, TRUE, rootUse->cu_def); StackFree(extDefStack); } /* * Function to push each cell def on extDefStack if it hasn't * already been pushed and if it needs re-extraction, and then * recurse on all that def's children. */ int extDefIncrementalFunc(use) CellUse *use; { CellDef *def = use->cu_def; if (def->cd_client || (def->cd_flags&CDINTERNAL)) return (0); def->cd_client = (ClientData) 1; if (extTimestampMisMatch(def)) StackPush((ClientData) def, extDefStack); (void) DBCellEnum(def, extDefIncrementalFunc, (ClientData) 0); return (0); } /* * Function returning TRUE if 'def' needs re-extraction. * This will be the case if either the .ext file for 'def' * does not exist, or if its timestamp fails to match that * recorded in 'def'. */ bool extTimestampMisMatch(def) CellDef *def; { char line[256]; FILE *extFile; bool ret = TRUE; int stamp; extFile = extFileOpen(def, (char *) NULL, "r", (char **) NULL); if (extFile == NULL) return (TRUE); if (fgets(line, sizeof line, extFile) == NULL) goto closeit; if (sscanf(line, "timestamp %d", &stamp) != 1) goto closeit; if (def->cd_timestamp != stamp) goto closeit; ret = FALSE; closeit: (void) fclose(extFile); return (ret); } /* * ---------------------------------------------------------------------------- * * extExtractStack -- * * If 'doExtract' is TRUE, call ExtCell for each def on the stack 'stack'; * otherwise, print the name of each def on the stack 'stack'. * The root cell of the tree being processed is 'rootDef'; we only * extract pathlength information for this cell. * * Results: * None. * * Side effects: * Leaves 'stack' empty. * Calls ExtCell on each def on the stack if 'doExtract' is TRUE. * Resets cd_client to 0 for each def on the stack. * Prints the total number of errors and warnings. * * ---------------------------------------------------------------------------- */ void extExtractStack(stack, doExtract, rootDef) Stack *stack; bool doExtract; CellDef *rootDef; { int fatal = 0, warnings = 0; bool first = TRUE; CellDef *def; while (def = (CellDef *) StackPop(stack)) { def->cd_client = (ClientData) 0; if (!SigInterruptPending) { if (doExtract) { ExtCell(def, (char *) NULL, (def == rootDef)); fatal += extNumFatal; warnings += extNumWarnings; } else { if (!first) TxPrintf(", "); TxPrintf("%s", def->cd_name); TxFlush(); first = FALSE; } } } if (!doExtract) { TxPrintf("\n"); } else { if (fatal > 0) TxError("Total of %d fatal error%s.\n", fatal, fatal != 1 ? "s" : ""); if (warnings > 0) TxError("Total of %d warning%s.\n", warnings, warnings != 1 ? "s" : ""); } } magic-8.0.210/extract/ExtTest.c0000644000175000001440000004363311202560464014701 0ustar timusers/* * ExtTest.c -- * * Circuit extraction. * Interface for testing. * * ********************************************************************* * * 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/extract/ExtTest.c,v 1.3 2009/05/13 15:03:16 tim Exp $"; #endif /* not lint */ #include #include #include #include "utils/magic.h" #include "utils/utils.h" #include "utils/geometry.h" #include "utils/styles.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/malloc.h" #include "windows/windows.h" #include "graphics/graphics.h" #include "dbwind/dbwind.h" #include "utils/main.h" #include "commands/commands.h" #include "textio/textio.h" #include "textio/txcommands.h" #include "debug/debug.h" #include "extract/extract.h" #include "extract/extractInt.h" int extDebAreaEnum; int extDebArray; int extDebHardWay; int extDebHierCap; int extDebHierAreaCap; int extDebLabel; int extDebNeighbor; int extDebNoArray; int extDebNoFeedback; int extDebNoHard; int extDebNoSubcell; int extDebLength; int extDebPerim; int extDebResist; int extDebVisOnly; int extDebYank; /* * The following are used for selective redisplay while debugging * the circuit extractor. */ Rect extScreenClip; CellDef *extCellDef; MagWindow *extDebugWindow; /* The width of an edge in pixels when it is displayed */ int extEdgePixels = 4; /* Forward declarations */ int extShowInter(); void extShowTech(); void extDispInit(); bool extShowRect(); void extMore(); void extShowTrans(char *, TileTypeBitMask *, FILE *); void extShowMask(TileTypeBitMask *, FILE *); void extShowPlanes(PlaneMask, FILE *); void extShowConnect(char *, TileTypeBitMask *, FILE *); /* * ---------------------------------------------------------------------------- * * ExtractTest -- * * Command interface for testing circuit extraction. * Usage: * *extract * * Results: * None. * * Side effects: * Extracts the current cell, writing a file named * currentcellname.ext. * * ---------------------------------------------------------------------------- */ void ExtractTest(w, cmd) MagWindow *w; TxCommand *cmd; { extern long extSubtreeTotalArea; extern long extSubtreeInteractionArea; extern long extSubtreeClippedArea; static Plane *interPlane = (Plane *) NULL; static long areaTotal = 0, areaInteraction = 0, areaClipped = 0; long a1, a2; int n, halo, bloat; CellUse *selectedCell; Rect editArea; char *addr, *name; FILE *f; typedef enum { CLRDEBUG, CLRLENGTH, DRIVER, INTERACTIONS, INTERCOUNT, EXTPARENTS, RECEIVER, SETDEBUG, SHOWDEBUG, SHOWPARENTS, SHOWTECH, STATS, STEP, TIME } cmdType; static struct { char *cmd_name; cmdType cmd_val; } cmds[] = { "clrdebug", CLRDEBUG, "clrlength", CLRLENGTH, "driver", DRIVER, "interactions", INTERACTIONS, "intercount", INTERCOUNT, "parents", EXTPARENTS, "receiver", RECEIVER, "setdebug", SETDEBUG, "showdebug", SHOWDEBUG, "showparents", SHOWPARENTS, "showtech", SHOWTECH, "stats", STATS, "step", STEP, "times", TIME, 0 }; if (cmd->tx_argc == 1) { selectedCell = CmdGetSelectedCell((Transform *) NULL); if (selectedCell == NULL) { TxError("No cell selected\n"); return; } extDispInit(selectedCell->cu_def, w); ExtCell(selectedCell->cu_def, selectedCell->cu_def->cd_name, FALSE); return; } n = LookupStruct(cmd->tx_argv[1], (LookupTable *) cmds, sizeof cmds[0]); if (n < 0) { TxError("Unrecognized subcommand: %s\n", cmd->tx_argv[1]); TxError("Valid subcommands:"); for (n = 0; cmds[n].cmd_name; n++) TxError(" %s", cmds[n].cmd_name); TxError("\n"); return; } switch (cmds[n].cmd_val) { case STATS: areaTotal += extSubtreeTotalArea; areaInteraction += extSubtreeInteractionArea; areaClipped += extSubtreeClippedArea; TxPrintf("Extraction statistics (recent/total):\n"); TxPrintf("Total area of all cells = %ld / %ld\n", extSubtreeTotalArea, areaTotal); a1 = extSubtreeTotalArea; a2 = areaTotal; if (a1 == 0) a1 = 1; if (a2 == 0) a2 = 1; TxPrintf( "Total interaction area processed = %ld (%.2f%%) / %ld (%.2f%%)\n", extSubtreeInteractionArea, ((double) extSubtreeInteractionArea) / ((double) a1) * 100.0, ((double) areaInteraction) / ((double) a2) * 100.0); TxPrintf( "Clipped interaction area= %ld (%.2f%%) / %ld (%.2f%%)\n", extSubtreeClippedArea, ((double) extSubtreeClippedArea) / ((double) a1) * 100.0, ((double) areaClipped) / ((double) a2) * 100.0); extSubtreeTotalArea = 0; extSubtreeInteractionArea = 0; extSubtreeClippedArea = 0; break; case INTERACTIONS: if (interPlane == NULL) interPlane = DBNewPlane((ClientData) TT_SPACE); halo = 1, bloat = 0; if (cmd->tx_argc > 2) halo = atoi(cmd->tx_argv[2]) + 1; if (cmd->tx_argc > 3) bloat = atoi(cmd->tx_argv[3]); ExtFindInteractions(EditCellUse->cu_def, halo, bloat, interPlane); (void) DBSrPaintArea((Tile *) NULL, interPlane, &TiPlaneRect, &DBAllButSpaceBits, extShowInter, (ClientData) NULL); DBClearPaintPlane(interPlane); break; case INTERCOUNT: f = stdout; halo = 1; if (cmd->tx_argc > 2) halo = atoi(cmd->tx_argv[2]); if (cmd->tx_argc > 3) { f = fopen(cmd->tx_argv[3], "w"); if (f == NULL) { perror(cmd->tx_argv[3]); break; } } ExtInterCount((CellUse *) w->w_surfaceID, halo, f); if (f != stdout) (void) fclose(f); break; case TIME: f = stdout; if (cmd->tx_argc > 2) { f = fopen(cmd->tx_argv[2], "w"); if (f == NULL) { perror(cmd->tx_argv[2]); break; } } ExtTimes((CellUse *) w->w_surfaceID, f); if (f != stdout) (void) fclose(f); break; case EXTPARENTS: if (ToolGetEditBox(&editArea)) ExtParentArea(EditCellUse, &editArea, TRUE); break; case DRIVER: if (cmd->tx_argc != 3) { TxError("Usage: *extract driver terminalname\n"); break; } ExtSetDriver(cmd->tx_argv[2]); break; case RECEIVER: if (cmd->tx_argc != 3) { TxError("Usage: *extract receiver terminalname\n"); break; } ExtSetReceiver(cmd->tx_argv[2]); break; case CLRLENGTH: TxPrintf("Clearing driver/receiver length list\n"); ExtLengthClear(); break; case SHOWPARENTS: if (ToolGetEditBox(&editArea)) ExtParentArea(EditCellUse, &editArea, FALSE); break; case SETDEBUG: DebugSet(extDebugID, cmd->tx_argc - 2, &cmd->tx_argv[2], TRUE); break; case CLRDEBUG: DebugSet(extDebugID, cmd->tx_argc - 2, &cmd->tx_argv[2], FALSE); break; case SHOWDEBUG: DebugShow(extDebugID); break; case SHOWTECH: extShowTech(cmd->tx_argc > 2 ? cmd->tx_argv[2] : "-"); break; case STEP: TxPrintf("Current interaction step size is %d\n", ExtCurStyle->exts_stepSize); if (cmd->tx_argc > 2) { ExtCurStyle->exts_stepSize = atoi(cmd->tx_argv[2]); TxPrintf("New interaction step size is %d\n", ExtCurStyle->exts_stepSize); } break; } } int extShowInter(tile) Tile *tile; { Rect r; TiToRect(tile, &r); DBWFeedbackAdd(&r, "interaction", EditCellUse->cu_def, 1, STYLE_MEDIUMHIGHLIGHTS); return (0); } /* * ---------------------------------------------------------------------------- * * extShowTech -- * * Display the technology-specific tables maintained for circuit * extraction in a human-readable format. Intended mainly for * debugging technology files. If the argument 'name' is "-", * the output is to the standard output; otherwise, it is to * the file whose name is 'name'. * * Results: * None. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ void extShowTech(name) char *name; { FILE *out; TileType t, s; int p; EdgeCap *e; if (strcmp(name, "-") == 0) out = stdout; else { out = fopen(name, "w"); if (out == NULL) { perror(name); return; } } extShowTrans("Transistor", &ExtCurStyle->exts_transMask, out); fprintf(out, "\nNode resistance and capacitance:\n"); fprintf(out, "type R-ohm/sq AreaC-ff/l**2\n"); for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) fprintf(out, "%-8.8s %8d %9lf\n", DBTypeShortName(t), ExtCurStyle->exts_resistByResistClass[ ExtCurStyle->exts_typeToResistClass[t]], ExtCurStyle->exts_areaCap[t]); fprintf(out, "\nTypes contributing to resistive perimeter:\n"); fprintf(out, "type R-type boundary types\n"); for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) { fprintf(out, "%-8.8s ", DBTypeShortName(t)); fprintf(out, "%7d ", ExtCurStyle->exts_typeToResistClass[t]); extShowMask(&ExtCurStyle->exts_typesResistChanged[t], out); fprintf(out, "\n"); } fprintf(out, "\nSidewall capacitance:\n"); for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) for (s = 0; s < DBNumTypes; s++) if (ExtCurStyle->exts_perimCap[t][s] != (CapValue) 0) fprintf(out, " %-8.8s %-8.8s %8lf\n", DBTypeShortName(t), DBTypeShortName(s), ExtCurStyle->exts_perimCap[t][s]); fprintf(out, "\nInternodal overlap capacitance:\n"); fprintf(out, "\n (by plane)\n"); for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++) { if (PlaneMaskHasPlane(ExtCurStyle->exts_overlapPlanes , p)) { fprintf(out, " %-10.10s: types=", DBPlaneShortName(p)); extShowMask(&ExtCurStyle->exts_overlapTypes [p], out); fprintf(out, "\n"); } } fprintf(out, "\n (by type)\n"); for (t = 0; t < DBNumTypes; t++) if (!TTMaskIsZero(&ExtCurStyle->exts_overlapOtherTypes[t])) { fprintf(out, " %-10.10s: planes=", DBTypeShortName(t)); extShowPlanes(ExtCurStyle->exts_overlapOtherPlanes[t], out); fprintf(out, "\n overlapped types="); extShowMask(&ExtCurStyle->exts_overlapOtherTypes[t], out); fprintf(out, "\n"); for (s = 0; s < DBNumTypes; s++) if (ExtCurStyle->exts_overlapCap[t][s] != (CapValue) 0) fprintf(out, " %-10.10s: %8lf\n", DBTypeShortName(s), ExtCurStyle->exts_overlapCap[t][s]); } fprintf(out, "\nSidewall-coupling/sidewall-overlap capacitance:\n"); fprintf(out, "\n (by plane)\n"); for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++) { if (PlaneMaskHasPlane(ExtCurStyle->exts_sidePlanes, p)) { fprintf(out, " %-10.10s: ", DBPlaneShortName(p)); extShowMask(&ExtCurStyle->exts_sideTypes[p], out); fprintf(out, "\n"); } } fprintf(out, "\n (by type)\n"); for (s = 0; s < DBNumTypes; s++) if (!TTMaskIsZero(&ExtCurStyle->exts_sideEdges[s])) { fprintf(out, " %-10.10s: ", DBTypeShortName(s)); extShowMask(&ExtCurStyle->exts_sideEdges[s], out); fprintf(out, "\n"); for (t = 0; t < DBNumTypes; t++) { if (!TTMaskIsZero(&ExtCurStyle->exts_sideCoupleOtherEdges[s][t])) { fprintf(out, " edge mask="); extShowMask(&ExtCurStyle->exts_sideCoupleOtherEdges[s][t], out); fprintf(out, "\n"); } if (!TTMaskIsZero(&ExtCurStyle->exts_sideOverlapOtherTypes[s][t])) { fprintf(out, " overlap mask="); extShowMask(&ExtCurStyle->exts_sideOverlapOtherTypes[s][t], out); fprintf(out, "\n"); } if (e = ExtCurStyle->exts_sideCoupleCap[s][t]) for ( ; e; e = e->ec_next) { fprintf(out, " COUPLE: "); extShowMask(&e->ec_near, out); fprintf(out, " || "); extShowMask(&e->ec_far, out); fprintf(out, ": %lf\n", e->ec_cap); } if (e = ExtCurStyle->exts_sideOverlapCap[s][t]) for ( ; e; e = e->ec_next) { fprintf(out, " OVERLAP: "); extShowMask(&e->ec_near, out); fprintf(out, ": %lf\n", e->ec_cap); } } } fprintf(out, "\n\nSidewall coupling halo = %d\n", ExtCurStyle->exts_sideCoupleHalo ); extShowConnect("\nNode connectivity", ExtCurStyle->exts_nodeConn, out); extShowConnect("\nResistive region connectivity", ExtCurStyle->exts_resistConn, out); extShowConnect("\nTransistor connectivity", ExtCurStyle->exts_transConn, out); if (out != stdout) (void) fclose(out); } void extShowTrans(name, mask, out) char *name; TileTypeBitMask *mask; FILE *out; { TileType t; fprintf(out, "%s types: ", name); extShowMask(mask, out); fprintf(out, "\n"); for (t = 0; t < DBNumTypes; t++) if (TTMaskHasType(mask, t)) { fprintf(out, " %-8.8s %d terminals: ", DBTypeShortName(t), ExtCurStyle->exts_transSDCount[t]); extShowMask(&ExtCurStyle->exts_transSDTypes[t][0], out); fprintf(out, "\n\tcap (gate-sd/gate-ch) = %lf/%lf\n", ExtCurStyle->exts_transSDCap[t], ExtCurStyle->exts_transGateCap[t]); } } void extShowConnect(hdr, connectsTo, out) char *hdr; TileTypeBitMask *connectsTo; FILE *out; { TileType t; fprintf(out, "%s\n", hdr); for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) if (!TTMaskEqual(&connectsTo[t], &DBZeroTypeBits)) { fprintf(out, " %-8.8s: ", DBTypeShortName(t)); extShowMask(&connectsTo[t], out); fprintf(out, "\n"); } } void extShowMask(m, out) TileTypeBitMask *m; FILE *out; { TileType t; bool first = TRUE; for (t = 0; t < DBNumTypes; t++) if (TTMaskHasType(m, t)) { if (!first) fprintf(out, ","); first = FALSE; fprintf(out, "%s", DBTypeShortName(t)); } } void extShowPlanes(m, out) PlaneMask m; FILE *out; { int pNum; bool first = TRUE; for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) if (PlaneMaskHasPlane(m, pNum)) { if (!first) fprintf(out, ","); first = FALSE; fprintf(out, "%s", DBPlaneShortName(pNum)); } } /* * ---------------------------------------------------------------------------- * * extDispInit -- * * Initialize the screen information to be used during * extraction debugging. * * Results: * None. * * Side effects: * Initializes extDebugWindow, extScreenClip, and extCellDef. * * ---------------------------------------------------------------------------- */ void extDispInit(def, w) CellDef *def; MagWindow *w; { extDebugWindow = w; extCellDef = def; extScreenClip = w->w_screenArea; GeoClip(&extScreenClip, &GrScreenRect); } /* * ---------------------------------------------------------------------------- * * extShowEdge -- * * Display the edge described by the Boundary 'bp' on the display, * with text string 's' on the text terminal. Prompt with '--next--' * to allow a primitive sort of 'more' processing. * * Results: * None. * * Side effects: * Updates the display. * * ---------------------------------------------------------------------------- */ void extShowEdge(s, bp) char *s; Boundary *bp; { Rect extScreenRect, edgeRect; int style = STYLE_PURPLE1; edgeRect = bp->b_segment; WindSurfaceToScreen(extDebugWindow, &edgeRect, &extScreenRect); if (extScreenRect.r_ybot == extScreenRect.r_ytop) { extScreenRect.r_ybot -= extEdgePixels/2; extScreenRect.r_ytop += extEdgePixels - extEdgePixels/2; } else /* extScreenRect.r_xtop == extScreenRect.r_xbot */ { extScreenRect.r_xbot -= extEdgePixels/2; extScreenRect.r_xtop += extEdgePixels - extEdgePixels/2; } if (DebugIsSet(extDebugID, extDebVisOnly)) { Rect r; r = extScreenRect; GeoClip(&r, &extScreenClip); if (r.r_xtop <= r.r_xbot || r.r_ytop <= r.r_ybot) return; } TxPrintf("%s: ", s); GrLock(extDebugWindow, TRUE); GrClipBox(&extScreenRect, style); GrUnlock(extDebugWindow); (void) GrFlush(); extMore(); GrLock(extDebugWindow, TRUE); GrClipBox(&extScreenRect, STYLE_ORANGE1); GrUnlock(extDebugWindow); (void) GrFlush(); } /* * ---------------------------------------------------------------------------- * * extShowTile -- * * Display the tile 'tp' on the display by highlighting it. Also show * the text string 's' on the terminal. Prompt with '--next--' to allow * a primitive sort of more processing. * * Results: * None. * * Side effects: * Updates the display. * * ---------------------------------------------------------------------------- */ void extShowTile(tile, s, style_index) Tile *tile; char *s; int style_index; { Rect tileRect; static int styles[] = { STYLE_PALEHIGHLIGHTS, STYLE_DOTTEDHIGHLIGHTS }; TiToRect(tile, &tileRect); if (!extShowRect(&tileRect, styles[style_index])) return; TxPrintf("%s: ", s); extMore(); (void) extShowRect(&tileRect, STYLE_ERASEHIGHLIGHTS); } bool extShowRect(r, style) Rect *r; int style; { Rect extScreenRect; WindSurfaceToScreen(extDebugWindow, r, &extScreenRect); if (DebugIsSet(extDebugID, extDebVisOnly)) { Rect rclip; rclip = extScreenRect; GeoClip(&rclip, &extScreenClip); if (rclip.r_xtop <= rclip.r_xbot || rclip.r_ytop <= rclip.r_ybot) return (FALSE); } GrLock(extDebugWindow, TRUE); GrClipBox(&extScreenRect, style); GrUnlock(extDebugWindow); (void) GrFlush(); return (TRUE); } void extMore() { char line[100]; TxPrintf("--next--"); (void) fflush(stdout); (void) TxGetLine(line, sizeof line); } void extNewYank(name, puse, pdef) char *name; CellUse **puse; CellDef **pdef; { DBNewYank(name, puse, pdef); } magic-8.0.210/extract/extract.h0000664000175000001440000000577212354346567015003 0ustar timusers/* * extract.h -- * * Defines the exported interface to the circuit extractor. * * rcsid "$Header: /usr/cvsroot/magic-8.0/extract/extract.h,v 1.3 2009/01/30 03:51:02 tim Exp $" * * ********************************************************************* * * 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 _EXTRACT_H #define _EXTRACT_H #include "utils/magic.h" /* Extractor warnings */ #define EXTWARN_DUP 0x01 /* Warn if two nodes have the same name */ #define EXTWARN_LABELS 0x02 /* Warn if connecting to unlabelled subcell * node. */ #define EXTWARN_FETS 0x04 /* Warn about badly constructed fets */ #define EXTWARN_ALL (EXTWARN_DUP|EXTWARN_LABELS|EXTWARN_FETS) extern int ExtDoWarn; /* Bitmask of above */ /* Known devices (see ExtTech.c and ExtBasic.c) */ /* Make sure these match extDevTable in extract/ExtBasic.c and */ /* also extflat/EFread.c */ #define DEV_FET 0 /* FET w/area, perimeter declared */ #define DEV_MOSFET 1 /* FET w/length, width declared */ #define DEV_ASYMMETRIC 2 /* Like MOSFET but D,S not swappable */ #define DEV_BJT 3 /* Bipolar Junction Transistor */ #define DEV_RES 4 /* Resistor */ #define DEV_CAP 5 /* Capacitor */ #define DEV_DIODE 6 /* Diode */ #define DEV_SUBCKT 7 /* general-purpose subcircuit */ #define DEV_RSUBCKT 8 /* Resistor-like subcircuit. */ #define DEV_MSUBCKT 9 /* MOSFET-like subcircuit. */ /* Device names for .ext file output (new in version 7.2) */ /* (defined in extract/ExtBasic.c *and* extflat/EFread.c) */ extern char *extDevTable[]; /* Extractor options */ #define EXT_DOADJUST 0x01 /* Extract hierarchical adjustments */ #define EXT_DOCAPACITANCE 0x02 /* Extract capacitance */ #define EXT_DOCOUPLING 0x04 /* Extract coupling capacitance */ #define EXT_DORESISTANCE 0x08 /* Extract resistance */ #define EXT_DOLENGTH 0x10 /* Extract pathlengths */ #define EXT_DOALL 0x1f /* ALL OF THE ABOVE */ extern int ExtOptions; /* Bitmask of above */ extern bool ExtTechLine(); extern void ExtTechInit(); extern void ExtTechFinal(); extern void ExtSetStyle(); extern void ExtPrintStyle(); extern void ExtCell(); #ifdef MAGIC_WRAPPER extern bool ExtGetDevInfo(); extern bool ExtCompareStyle(); #endif #ifdef THREE_D extern void ExtGetZAxis(); #endif #endif /* _EXTRACT_H */ magic-8.0.210/extract/extractInt.h0000664000175000001440000010671312400422506015427 0ustar timusers/* * extractInt.h -- * * Defines things shared internally by the extract module of Magic, * but not generally needed outside the extract module. * * rcsid "$Header: /usr/cvsroot/magic-8.0/extract/extractInt.h,v 1.7 2010/08/10 00:18:46 tim Exp $" * * ********************************************************************* * * 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. * * ********************************************************************* * * This module has been modified at DEC/WRL and Stanford University. * The above disclaimers apply. * */ #ifndef _EXTRACTINT_H #define _EXTRACTINT_H #include "database/database.h" #undef NT #define NT TT_MAXTYPES #undef NP #define NP PL_MAXTYPES /* ------------------------ Capacitance Values ------------------------- */ typedef double CapValue; /* No longer allowed to define back to integer, * as this touches too many parts of the code. */ /* Procs to manipulate capacitance hash tables. */ extern CapValue extGetCapValue(); extern void extSetCapValue(); extern void extCapHashKill(); typedef int ResValue; /* Warning: in some places resistances are stored * as ints. This is here for documentation only. */ /* ------------------------ Parameter lists --------------------------- */ /* These lists keep track of what parameter names subcircuit definitions * use for parameters that magic knows how to generate. Valid pl_param * values are a (area), p (perimeter), w (width), l (length), s (substrate), * x (position), and y (position). Values "a" and "p" may be followed by * an additional integer indicating the terminal from which the value is * used (e.g., source area, drain perimeter, etc.). An integer "0" * indicates the device identifier region (e.g., gate) and is equivalent * to having no integer at all. Integers "1" and up indicate terminals, * in order. */ typedef struct pl { int pl_count; /* Share this list. . . */ char pl_param[2]; /* Default character for parameter */ char *pl_name; /* Full name for parameter */ double pl_scale; /* Scaling of parameter, if specified */ struct pl *pl_next; /* Next parameter in list */ } ParamList; /* -------------------------- Label lists ----------------------------- */ /* * List of labels for a node. * We keep around pointers to the entire labels for * later figuring out which are attached to the gates, * sources, or drains of transistors. */ typedef struct ll { Label *ll_label; /* Actual Label in the source CellDef */ struct ll *ll_next; /* Next LabelList in this region */ int ll_attr; /* Which terminal of a transistor this is * an attribute of. */ } LabelList; #define LL_NOATTR -1 /* Value for ll_attr above if the label is * not a transistor attribute. */ #define LL_GATEATTR -2 /* Value for ll_attr if the label is a gate * attribute, rather than one of the diffusion * terminals' attributes. */ #define LL_SORTATTR -3 /* value for ll_attr used in * ExtBasic.c/ExtSortTerminals() to swap * the attributes as well as the regions * -- Stefanos 5/96 */ #define LL_PORTATTR -4 /* value for ll_attr used to declare * the label to be a subcircuit port * -- Tim 5/02 */ /* * Types of labels. * These can be or'd into a mask and passed to extLabType(). */ #define LABTYPE_NAME 0x01 /* Normal node name */ #define LABTYPE_NODEATTR 0x02 /* Node attribute */ #define LABTYPE_GATEATTR 0x04 /* Transistor gate attribute */ #define LABTYPE_TERMATTR 0x08 /* Transistor terminal (source/drain) * attribute. */ #define LABTYPE_PORTATTR 0x10 /* Subcircuit port */ /* ----------------------------- Regions ------------------------------ */ /* * The following are the structures built up by the various * clients of ExtFindRegions. The general rule for these * structures is that their initial fields must be identical * to those in a Region, but subsequent fields are up to * the individual client. * * Regions marked as GENERIC are the types accepted by * procedures in ExtRegion.c. */ /* * GENERIC Region struct. * All this provides is a pointer to the next Region. * This is the type passed to functions like ExtFreeRegions, * and is the type returned by ExtFindRegions. Clients should * cast pointers of this type to their own, client type. */ typedef struct reg { struct reg *reg_next; /* Next region in list */ } Region; /* * GENERIC region with labels. * Any other structure that wants to reference node names * must include the same fields as this one as its first part. */ typedef struct lreg { struct lreg *lreg_next; /* Next region in list */ int lreg_pnum; /* Lowest numbered plane in this region */ int lreg_type; /* Type of tile that contains lreg_ll */ Point lreg_ll; /* Lower-leftmost point in this region on * plane lreg_pnum. We take the min first * in X, then in Y. */ LabelList *lreg_labels; /* List of labels for this region. These are * any labels connected to the geometry making * up this region. If the list is empty, make * up a name from lreg_pnum and lreg_ll. */ } LabRegion; /* * Node region: labelled region with resistance and capacitance. * Used for each node in the flat extraction of a cell. */ typedef struct { int pa_perim; int pa_area; } PerimArea; typedef struct nreg { struct nreg *nreg_next; /* Next region in list */ int nreg_pnum; /* Lowest numbered plane in this region */ int nreg_type; /* Type of tile that contains nreg_ll */ Point nreg_ll; /* Lower-leftmost point in this region on * plane nreg_pnum. We take the min first * in X, then in Y. */ LabelList *nreg_labels; /* See LabRegion for description */ CapValue nreg_cap; /* Capacitance to ground */ ResValue nreg_resist; /* Resistance estimate */ PerimArea nreg_pa[1]; /* Dummy; each node actually has * ExtCurStyle->exts_numResistClasses * array elements allocated to it. */ } NodeRegion; /* * Transistor region: labelled region with perimeter and area. * Used for each transistor in the flat extraction of a cell. */ typedef struct treg { struct treg *treg_next; /* Next region in list */ int treg_pnum; /* UNUSED */ int treg_type; /* Type of tile that contains treg_ll */ Point treg_ll; /* UNUSED */ LabelList *treg_labels; /* Attribute list */ Tile *treg_tile; /* Some tile in the channel */ int treg_area; /* Area of channel */ } TransRegion; typedef struct { /* Maintain plane information when pushing */ Rect area; /* tiles on the node stack. For use with */ int plane; /* function extNbrPushFunc(). */ } PlaneAndArea; /* * The following constructs a node name from the plane number 'n' * and lower left Point l, and places it in the string 's' (which must * be large enough). */ #define extMakeNodeNumPrint(buf, plane, coord) \ (void) sprintf((buf), "%s_%s%d_%s%d#", DBPlaneShortName(plane), \ ((coord).p_x < 0) ? "n": "", abs((coord).p_x), \ ((coord).p_y < 0) ? "n": "", abs((coord).p_y)) /* Old way: cryptic numbers, but a bit shorter * * #define extMakeNodeNumPrint(s, n, l) \ * (void) sprintf((s), "%d_%d_%d#", (n), extCoord((l).p_x), extCoord((l).p_y)) * * The following is used to map the full coordinate space into * the positive integers, for constructing internally generated * node names. * * #define extCoord(x) (((x) < 0) ? (1 - ((x) << 1)) : ((x) << 1)) */ /* * Argument passed to filter functions for finding regions. */ typedef struct { TileTypeBitMask *fra_connectsTo; /* Array of TileTypeBitMasks. The * element fra_connectsTo[t] has a * bit set for each type that * connects to 't'. */ CellDef *fra_def; /* Def being searched */ int fra_pNum; /* Plane currently searching */ ClientData fra_uninit; /* This value appears in the ti_client * field of a tile if it's not yet * been visited. */ Region *(*fra_first)(); /* Function to init new region */ int (*fra_each)(); /* Function for each tile in region */ Region *fra_region; /* Ptr to Region struct for current * region. May be set by fra_first * and used by fra_each. */ } FindRegion; #define TILEAREA(tp) ((TOP(tp) - BOTTOM(tp)) * (RIGHT(tp) - LEFT(tp))) /* -------------------- Perimeter of a region ------------------------- */ /* * Segment of the boundary of a region whose perimeter * is being traced by ExtTracePerimeter() and extEnumTilePerim(). */ typedef struct { Tile *b_inside; /* Pointer to tile just inside segment */ Tile *b_outside; /* Pointer to tile just outside segment */ Rect b_segment; /* Actual coordinates of segment */ u_char b_direction; /* Direction following segment (see below) */ int b_plane; /* extract argument for extSideOverlap */ } Boundary; #define BoundaryLength(bp) \ ((bp)->b_segment.r_xtop - (bp)->b_segment.r_xbot \ + (bp)->b_segment.r_ytop - (bp)->b_segment.r_ybot) /* Directions in which we can be following the boundary of a perimeter */ #define BD_LEFT 1 /* Inside is to right */ #define BD_TOP 2 /* Inside is below */ #define BD_RIGHT 4 /* Inside is to left */ #define BD_BOTTOM 8 /* Inside is above */ /* -------- Yank buffers for hierarchical and array extraction -------- */ extern CellUse *extYuseCum; extern CellDef *extYdefCum; /* --------------- Argument passed to extHierYankFunc ----------------- */ typedef struct { Rect *hy_area; /* Area (in parent coordinates) to be yanked */ CellUse *hy_target; /* Yank into this use */ bool hy_prefix; /* If TRUE, prefix labels with use id */ } HierYank; /* ----- Arguments to filter functions in hierarchical extraction ---- */ /* * The following defines an extracted subtree. * The CellUse et_use will be either a cell we are extracting, * or a flattened subtree. If et_lookNames is non-NULL, it * points to a CellDef that we should look in for node names. */ typedef struct extTree { CellUse *et_use; /* Extracted cell, usually flattened */ CellUse *et_realuse; /* If et_use is flattened, et_realuse * points to the unflattened subtree's * root use; otherwise it is NULL. */ CellDef *et_lookNames; /* See above */ NodeRegion *et_nodes; /* List of nodes */ HashTable et_coupleHash; /* Table for coupling capacitance. * key is type CoupleKey * value is pointer to type CapValue */ struct extTree *et_next; /* Next one in list */ } ExtTree; /* * The following structure contains information passed down * through several levels of filter functions during hierarchical * extraction. * * The procedure ha_nodename is used to map from a tile into the * name of the node to which that tile belongs. It should be of * the following format: * * char * * proc(tp, et, ha) * Tile *tp; * ExtTree *et; * HierExtractArg *ha; * { * } * * It should always return a non-NULL string; if the name of a * node can't be determined, the string can be "(none)". */ typedef struct { FILE *ha_outf; /* The .ext file being written */ CellUse *ha_parentUse; /* Use pointing to the def being extracted */ char *(*ha_nodename)();/* Map (tp, et, ha) into nodename; see above */ ExtTree ha_cumFlat; /* Cumulative yank buffer */ HashTable ha_connHash; /* Connections made during hier processing */ /* All areas are in parent coordinates */ Rect ha_interArea; /* Area of whole interaction being considered */ Rect ha_clipArea; /* Only consider capacitance, perimeter, and * area that come from inside this area. This * rectangle is contained within ha_interArea. */ CellUse *ha_subUse; /* Root of the subtree being processed now */ Rect ha_subArea; /* Area of ha_subUse inside the interaction * area, i.e, contained within ha_interArea. */ Tile *hierOneTile; /* Used in ExtHier.c, tile from extHierOneFlat */ int hierPNum; /* Used in ExtHier.c, plane of tile above */ TileType hierType; /* Used in ExtHier.c, type of tile above */ int hierPNumBelow; /* Used in ExtHier.c, plane of tile below */ } HierExtractArg; /* * Normally, nodes in overlapping subcells are expected to have labels * in the area of overlap. When this is not the case, we have to use * a much more expensive algorithm for finding the labels attached to * the subcells' geometry in the overlap area. The following structure * is used to hold information about the search in progress for such * labels. */ typedef struct { HierExtractArg *hw_ha; /* Describes context of search */ Label *hw_label; /* We update hw_label with a ptr to a * newly allocated label if successful. */ Rect hw_area; /* Area in parent coordinates of the * area where we're searching. */ bool hw_autogen; /* If TRUE, we trace out all geometry * in the first node in the first cell * found to overlap the search area, * and use the internal name for that * node. */ TerminalPath hw_tpath; /* Hierarchical path down to label * we are searching for, rooted at * the parent being extracted. */ TileTypeBitMask hw_mask; /* Mask of tile types that connect to * the tile whose node is to be found, * and which are on the same plane. * Used when calling ExtFindRegions. */ bool hw_prefix; /* If FALSE, we skip the initial * use identifier when building * hierarchical labels (as when * extracting arrays; see hy_prefix * in the HierYank struct). */ int (*hw_proc)(); } HardWay; /* --------------------- Coupling capacitance ------------------------- */ /* * The following structure is the hash key used for computing * internodal coupling capacitance. Each word is a pointer to * one of the nodes being coupled. By convention, the first * word is the lesser of the two NodeRegion pointers. */ typedef struct { NodeRegion *ck_1, *ck_2; } CoupleKey; extern void extCoupleHashZero(); /* Clears out all pointers to data in table */ /* ------------------ Interface to debugging module ------------------- */ extern ClientData extDebugID; /* Identifier returned by the debug module */ /* ----------------- Technology-specific information ------------------ */ /* * Structure used to define sidewall coupling capacitances. */ typedef struct edgecap { struct edgecap *ec_next; /* Next edge capacitance rule in list */ CapValue ec_cap; /* Capacitance (attofarads) */ TileTypeBitMask ec_near; /* Types closest to causing edge, or in * the case of sideOverlaps, the * types we are overlapping. */ TileTypeBitMask ec_far; /* Types farthest from causing edge, or * in the case of sideOverlaps, the * types that shield the edge from * the overlaped tile. */ int ec_pmask; /* specifies which planes are to be */ /* used. */ } EdgeCap; /* A type used to determine if current style needs planeorder or not */ typedef enum { noPlaneOrder, needPlaneOrder, seenPlaneOrder } planeOrderStatus ; /* * Because a large TT_MAXTYPES value quickly generates huge extract section * structures, we want to keep around only the style names, and dynamically * load and destroy the extract section values as needed, when doing an * extraction command. */ typedef struct extkeep { struct extkeep *exts_next; char *exts_name; } ExtKeep; /* * Parameters for the process being extracted. * We try to use use integers here, rather than floats, to be nice to * machines like Sun workstations that don't have hardware * floating point. * * In the case of capacitances, though, we may have to use floats, depending * upon the type CapValue. In some newer processes the capacitance per * lambda^2 is less than 1 attofarad. */ typedef struct extstyle { char exts_status; /* Loaded, not loaded, or pending */ char *exts_name; /* Name of this style */ /* * Connectivity tables. * Each table is an array of TileTypeBitMasks indexed by TileType. * The i-th element of each array is a mask of those TileTypes * to which type 'i' connects. */ /* Everything is connected to everything else in this table */ TileTypeBitMask exts_allConn[NT]; /* * Connectivity for determining electrical nodes. * This should be essentially the same as DBConnectTbl[]. */ TileTypeBitMask exts_nodeConn[NT]; /* * Connectivity for determining resistive regions. * Two types should be marked as connected here if * they are both connected in exts_nodeConnect[], and * if they both have the same resistance per square. */ TileTypeBitMask exts_resistConn[NT]; /* * Connectivity for determining transistors. * Each transistor type should connect only to itself. * Nothing else should connect to anything else. */ TileTypeBitMask exts_transConn[NT]; /* * Sheet resistivity for each tile type, in milli-ohms per square. * For types that are transistors or capacitors, this corresponds * to the sheet resistivity of the gate. */ /* Maps from a tile type to the index of its sheet resistance entry */ int exts_typeToResistClass[NT]; /* Gives a mask of neighbors of a type with different resistivity */ TileTypeBitMask exts_typesResistChanged[NT]; /* * Resistance information is also provided by the following tables: * exts_typesByResistClass[] is an array of masks of those types * having the same sheet resistivity, for each different value * of sheet resistivity; exts_resistByResistClass[] is a parallel array * giving the actual value of sheet resistivity. Both are indexed * from 0 up to (but not including) exts_numResistClasses. */ TileTypeBitMask exts_typesByResistClass[NT]; ResValue exts_resistByResistClass[NT]; int exts_numResistClasses; /* Resistance per type */ ResValue exts_sheetResist[NT]; /* * Resistances for via holes, given in milliohms. Number of * cuts is determined by the "cifoutput" style "squares" * parameters. */ ResValue exts_viaResist[NT]; /* * Amount to scale resistance of a material on a corner. * Defauts to 1.0. Often set to 0.5. */ float exts_cornerChop[NT]; /* Layer height and thickness used by the geometry extractor */ float exts_height[NT]; float exts_thick[NT]; /* * Capacitance to substrate for each tile type, in units of * attofarads per square lambda. */ /* * Capacitance per unit area. This is zero for explicit capacitor * types, which handle gate-channel capacitance specially. For * transistor types, this is at best an approximation that is * truly valid only when the transistor is switched off. */ CapValue exts_areaCap[NT]; /* * Capacitance per unit perimeter. Sidewall capacitance depends both * on the type inside the perimeter as well as the type outside it, * so the table is doubly indexed by TileType. * * The mask exts_perimCapMask[t] contains bits for all those TileTypes * 's' such that exts_perimCap[t][s] is nonzero. */ CapValue exts_perimCap[NT][NT]; TileTypeBitMask exts_perimCapMask[NT]; /* * Overlap coupling capacitance for each pair of tile types, in units * of attofarads per square lambda of overlap. * Internodal capacitance due to overlap only occurs between tile * types on different tile planes that are not shielded by intervening * tiles. */ /* * The mask exts_overlapPlanes is a mask of those planes that must * be searched for tiles having overlap capacitance, and the mask * exts_overlapTypes[p] is those types having overlap capacitance * on each plane p. The intent is that exts_overlapTypes[p] lists * only those types t for which some entry of exts_overlapCap[t][s] * is non-zero. */ PlaneMask exts_overlapPlanes; TileTypeBitMask exts_overlapTypes[NP]; /* * The mask exts_overlapOtherPlanes[t] is a mask of the planes that * must be searched for tiles having overlap capacitance with tiles * of type 't', and exts_overlapOtherTypes[t] is a mask of the types * with which our overlap capacitance is non-zero. */ TileTypeBitMask exts_overlapOtherTypes[NT]; PlaneMask exts_overlapOtherPlanes[NT]; /* * Both exts_overlapShieldTypes[][] and exts_overlapShieldPlanes[][] * are indexed by the same pair of types used to index the table * exts_overlapCap[][]; they identify the types and planes that * shield capacitance between their index types. */ TileTypeBitMask exts_overlapShieldTypes[NT][NT]; PlaneMask exts_overlapShieldPlanes[NT][NT]; /* * The table extOverlapCap[][] is indexed by two types to give the * overlap coupling capacitance between them, per unit area. Only * one of extOverlapCap[i][j] and extOverlapCap[j][i] should be * nonzero. The capacitance to substrate of the tile of type 'i' * is deducted when an overlap between i and j is detected, if * extOverlapCap[i][j] is nonzero. This is only done, however, if * tile i is below tile j in exts_planeOrder; */ CapValue exts_overlapCap[NT][NT]; /* Specifies an ordering of the planes, so we can determine which * tile is above another one. This is used only when determining * if we should subtract capacitance to substrate for overlap and * sideoverlap rules. If no planeorder is specified and the style * does not contain a noplaneordering command a warning is issued * and the default planeorder is used for the style. */ int exts_planeOrder[NP]; /* set/reset with planeorder commands to determine whether * we will warn if no planeorder is specified. This is done * because at Stanford we use a lot of diagnostic extraction * styles (for floating wells etc.) and we don't want to specify * the planeorder for each and every one of them. */ planeOrderStatus exts_planeOrderStatus; /* * Sidewall coupling capacitance. This capacitance is between edges * on the same plane, and is in units of attofarads. It is multiplied * by the value interpolated from a fringing-field table indexed by the * common length of the pair of edges divided by their separation: * * | | * E1 +----------------------------+ * ^ * +--- distance between edges * v * +-----------------------------------+ E2 * | | * * <-----------------------> length in common */ /* * The entry exts_sideCoupleCap[i][j] is a list of the coupling * capacitance info between edges with type 'i' on the inside * and 'j' on the outside, and other kinds of edges. */ EdgeCap *exts_sideCoupleCap[NT][NT]; /* * exts_sideCoupleOtherEdges[i][j] is a mask of those types on the * far sides of edges to which an edge with 'i' on the inside and * 'j' on the outside has coupling capacitance. */ TileTypeBitMask exts_sideCoupleOtherEdges[NT][NT]; /* * We search out a distance exts_sideCoupleHalo from each edge * for other types with which we have coupling capacitance. * This value determines how much extra gets yanked when * computing hierarchical adjustments, so should be kept * small to insure reasonable performance. */ int exts_sideCoupleHalo; /* * Sidewall-overlap coupling capacitance. * This is between an edge on one plane and a type on another plane * that overlaps the edge (from the outside of the edge), and is in * units of attofarads per lambda. * * When an edge with sidewall capacitance to substrate is found to * overlap a type to which it has sidewall overlap capacitance, the * original capacitance to substrate is replaced with the overlap * capacitance to the tile overlapped, if the edge is above the tile * being overlapped (according to ext_planeOrder). If the tiles are * the other way around, then this replacement is not done. */ /* * The entry exts_sideOverlapCap[i][j] is a list of the coupling * capacitance info between edges with type 'i' on the inside * and 'j' on the outside, and other kinds of tiles on other * planes. The ec_near mask in the EdgeCap record identifies the * types to which we have sidewall overlap capacitance, and the * ec_far mask identifies the types that shield the tiles preventing * a capacitance. */ EdgeCap *exts_sideOverlapCap[NT][NT]; /* * extSideOverlapOtherTypes[i][j] is a mask of those types to which * an edge with 'i' on the inside and 'j' on the outside has coupling * capacitance. extSideOverlapOtherPlanes[i][j] is a mask of those * planes to which edge [i][j] has overlap coupling capacitance. * exts_sideOverlapShieldPlanes[s][t] is a list of the planes that * need to be examined for shielding material when we are considering * a sidewall overlap capacitor between types s and t. This may * be the "or" of the planes needed by several sideoverlap rules, * since there can be several types of edges in which type s is * the "intype" member and the "outtype" member varies. Note that * sideOverlapShieldPlanes is indexed like overlapShieldPlanes, not * like sideOverlapOtherPlanes. */ PlaneMask exts_sideOverlapOtherPlanes[NT][NT]; TileTypeBitMask exts_sideOverlapOtherTypes[NT][NT]; PlaneMask exts_sideOverlapShieldPlanes[NT][NT]; /* * Both exts_overlapShieldTypes[][] and exts_overlapShieldPlanes[][] * are indexed by the same pair of types used to index the table * exts_overlapCap[][]; they identify the types and planes that * shield capacitance between their index types. */ /* Common to both sidewall coupling and sidewall overlap */ /* * exts_sideTypes[p] is a mask of those types 't' having sidewall * coupling or sidewall overlap capacitance on plane p (i.e, for * which a bin in exts_sideCoupleCap[t][] or exts_sideOverlapCap[t][] * is non-empty), and exts_sidePlanes a mask of those planes containing * tiles in exts_sideTypes[]. */ PlaneMask exts_sidePlanes; TileTypeBitMask exts_sideTypes[NP]; /* * The mask exts_sideEdges[i] is just a mask of those types j for * which either exts_sideCoupleCap[i][j] or exts_sideOverlapCap[i][j] * is non-empty. */ TileTypeBitMask exts_sideEdges[NT]; /* Transistors */ /* Name of each transistor type as output in .ext file */ char *exts_transName[NT]; /* List of parameter names for each subcircuit type */ ParamList *exts_deviceParams[NT]; /* Device class for each layer type */ char exts_deviceClass[NT]; /* Contains one for each type of fet, zero for all other types */ TileTypeBitMask exts_transMask; /* * Per-square resistances for each possible transistor type, * in the various regions that such a type might operate. * The only operating region currently used is "linear", * which the resistance extractor uses in its thresholding * operation. NOTE: resistances in this table are in OHMS * per square, not MILLIOHMS! */ HashTable exts_transResist[NT]; ResValue exts_linearResist[NT]; /* * Mask of the types of tiles that connect to the channel terminals * of a transistor type. The intent is that these will be the * diffusion terminals of a transistor, ie, its source and drain. * UPDATED May, 2008: Record is a list of type masks, allowing * multiple terminal types in the case of, e.g., high-voltage * or other asymmetric devices. The last entry in the list should * be equal to DBSpaceBits. */ TileTypeBitMask *exts_transSDTypes[NT]; /* * Maximum number of terminals (source/drains) per transistor type. * This table exists to allow the possibility of transistors with * more than two diffusion terminals at some point in the future. */ int exts_transSDCount[NT]; /* Currently unused: gate-source capacitance per unit perimeter */ CapValue exts_transSDCap[NT]; /* Currently unused: gate-channel capacitance per unit area */ CapValue exts_transGateCap[NT]; /* * Each type of transistor has a substrate node. By default, * it is the one given by exts_transSubstrateName[t]. However, * if the mask exts_transSubstrateTypes[t] is non-zero, and if * the transistor overlaps material of one of the types in the * mask, then the transistor substrate node is the node of the * material it overlaps. If exts_transSub */ char *exts_transSubstrateName[NT]; TileTypeBitMask exts_transSubstrateTypes[NT]; #ifdef ARIEL TileTypeBitMask exts_subsTransistorTypes[NT]; #endif /* ARIEL */ /* Scaling */ /* * Step size used when breaking up a large cell for interaction * checks during hierarchical extraction. We check exts_stepSize * by exts_stepSize chunks for interactions one at a time. */ int exts_stepSize; /* * Number of linear units per lambda. All perimeter dimensions * that we output to the .ext file should be multiplied by * exts_unitsPerLambda; we produce a "scale" line in the .ext file * indicating this. All area dimensions should be multiplied * by exts_unitsPerLambda**2. * (changed to type float May 11, 2006 to accomodate, e.g., 90 * and 130 nm technologies) */ float exts_unitsPerLambda; /* * Scaling for resistance and capacitance. * All resistances in the .ext file should be multiplied by * exts_resistScale to get milliohms, and all capacitances by * exts_capScale to get attofarads. These numbers appear in * the "scale" line in the .ext file. */ int exts_capScale; int exts_resistScale; } ExtStyle; #define EXT_PLUG_GND 1 #define EXT_PLUG_VDD 2 extern ExtStyle *ExtCurStyle; /* ------------------- Hierarchical node merging ---------------------- */ /* * Table used to hold all merged nodes during hierarchical extraction. * Used for duplicate suppression. */ extern HashTable extHierMergeTable; /* * Each hash entry in the above table points to a NodeName struct. * Each NodeName points to the Node corresponding to that name. * Each Node points back to a list of NodeNames that point to that * Node, and which are linked together along their nn_next fields. */ typedef struct nn { struct node *nn_node; /* Node for which this is a name */ char *nn_name; /* Text of name */ struct nn *nn_next; /* Other names of nn_node */ } NodeName; typedef struct node { NodeName *node_names; /* List of names for this node. The first name * in the list is the "official" node name. */ CapValue node_cap; /* Capacitance to substrate */ PerimArea node_pa[1]; /* Dummy; each node actually has * ExtCurStyle->exts_numResistClasses * array elements allocated to it. */ } Node; /* -------------------------------------------------------------------- */ /* * Value normally resident in the ti_client field of a tile, * indicating that the tile has not yet been visited in a * region search. */ extern ClientData extUnInit; #define extGetRegion(tp) ( (tp)->ti_client ) #define extHasRegion(tp,und) ( (tp)->ti_client != (und) ) /* For non-recursive flooding algorithm */ #define VISITPENDING ((ClientData) NULL) /* Marks tiles on stack */ /* Note that this macro depends on MAXPLANES being small */ /* compared to the bit position of TT_SIDE. Since tens of */ /* thousands of planes is inconceivable, this should not be a */ /* problem. It is necessary to push the tile's TT_SIDE bit */ /* because the search algorithm can overwrite it between the */ /* time the tile is pushed and the time that it is popped. */ #define PUSHTILE(tp, pl) \ (tp)->ti_client = VISITPENDING; \ STACKPUSH((ClientData)(pointertype)(pl | \ ((TileType)(spointertype)(tp)->ti_body & TT_SIDE)), extNodeStack); \ STACKPUSH((ClientData)(pointertype)tp, extNodeStack) #define POPTILE(tp, pl) \ tp = (Tile *) STACKPOP(extNodeStack); \ pl = (spointertype) STACKPOP(extNodeStack); \ if (pl & TT_SIDE) { \ TiSetBody((tp), TiGetTypeExact(tp) | TT_SIDE); \ pl &= (~TT_SIDE); \ } \ else \ TiSetBody((tp), TiGetTypeExact(tp) & (~TT_SIDE)) /* Variations of "pushtile" to force a specific value on TT_SIDE */ #define PUSHTILEBOTTOM(tp, pl) \ (tp)->ti_client = VISITPENDING; \ STACKPUSH((ClientData)(pointertype)(pl | \ ((SplitDirection(tp)) ? 0 : TT_SIDE)), extNodeStack) ;\ STACKPUSH((ClientData)(pointertype)tp, extNodeStack) #define PUSHTILETOP(tp, pl) \ (tp)->ti_client = VISITPENDING; \ STACKPUSH((ClientData)(pointertype)(pl | \ ((SplitDirection(tp)) ? TT_SIDE : 0)), extNodeStack) ;\ STACKPUSH((ClientData)(pointertype)tp, extNodeStack) #define PUSHTILELEFT(tp, pl) \ (tp)->ti_client = VISITPENDING; \ STACKPUSH((ClientData)(pointertype)(pl), extNodeStack); \ STACKPUSH((ClientData)(pointertype)tp, extNodeStack) #define PUSHTILERIGHT(tp, pl) \ (tp)->ti_client = VISITPENDING; \ STACKPUSH((ClientData)(pointertype)(pl | TT_SIDE), extNodeStack); \ STACKPUSH((ClientData)(pointertype)tp, extNodeStack) /* ------------------------- Region finding --------------------------- */ extern Region *ExtFindRegions(); /* Filter functions for ExtFindRegions() */ extern Region *extTransFirst(); extern int extTransEach(); extern Region *extResFirst(); extern int extResEach(); extern Region *extNodeFirst(); extern int extNodeEach(); extern Region *extHierLabFirst(); extern int extHierLabEach(); extern Tile *extNodeToTile(); /* -------- Search for matching node in another ExtTree ---------- */ /* * NODETONODE(nold, et, nnew) * NodeRegion *nold; * ExtTree *et; * NodeRegion *nnew; * * Like extNodeToTile(), but leaves nnew pointing to the node associated * with the tile we find. */ #define NODETONODE(nold, et, nnew) \ if (1) { \ Tile *tp; \ \ (nnew) = (NodeRegion *) NULL; \ tp = extNodeToTile((nold), (et)); \ if (tp && extHasRegion(tp, extUnInit)) \ (nnew) = (NodeRegion *) extGetRegion(tp); \ } /* -------------------- Miscellaneous procedures ---------------------- */ extern char *extNodeName(); extern NodeRegion *extBasic(); extern NodeRegion *extFindNodes(); extern ExtTree *extHierNewOne(); extern int extNbrPushFunc(); /* --------------------- Miscellaneous globals ------------------------ */ extern int extNumFatal; /* Number fatal errors encountered so far */ extern int extNumWarnings; /* Number warning messages so far */ extern CellUse *extParentUse; /* Dummy use for def being extracted */ extern ClientData extNbrUn; /* Ditto */ /* * This is really a (Stack *), but we use the struct tag to avoid * having to include stack.h in every .c file. Used in the non-recursive * flooding algorithm. */ extern struct stack *extNodeStack; /* ------------------ Connectivity table management ------------------- */ /* * The following is true if tile types 'r' and 's' are connected * according to the connectivity table 'tbl' */ #define extConnectsTo(r, s, tbl) ( TTMaskHasType(&(tbl)[(r)], (s)) ) /* -------------------------------------------------------------------- */ #include "extDebugInt.h" #endif /* _EXTRACTINT_H */ magic-8.0.210/extract/ExtCell.c0000644000175000001440000002504210751423606014637 0ustar timusers/* * ExtCell.c -- * * Circuit extraction. * Extract a single cell. * * ********************************************************************* * * 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/extract/ExtCell.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/styles.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/malloc.h" #include "textio/textio.h" #include "debug/debug.h" #include "extract/extract.h" #include "extract/extractInt.h" #include "utils/signals.h" #include "utils/stack.h" #include "utils/utils.h" #include "windows/windows.h" #include "utils/main.h" #include "utils/undo.h" /* --------------------------- Global data ---------------------------- */ /* * Value normally present in ti_client to indicate tiles that have not * been marked with their associated region. */ ClientData extUnInit = (ClientData) CLIENTDEFAULT; /* ------------------------ Data local to this file ------------------- */ /* Forward declarations */ int extOutputUsesFunc(); FILE *extFileOpen(); void extCellFile(); void extHeader(); /* * ---------------------------------------------------------------------------- * * ExtCell -- * * Extract the cell 'def', plus all its interactions with its subcells. * Place the result in the file named 'outName'. * * Results: * None. * * Side effects: * Creates the file 'outName'.ext and writes to it. * May leave feedback information where errors were encountered. * Upon return, extNumFatal contains the number of fatal errors * encountered while extracting 'def', and extNumWarnings contains * the number of warnings. * * ---------------------------------------------------------------------------- */ void ExtCell(def, outName, doLength) CellDef *def; /* Cell being extracted */ char *outName; /* Name of output file; if NULL, derive from def name */ bool doLength; /* If TRUE, extract pathlengths from drivers to * receivers (the names are stored in ExtLength.c). * Should only be TRUE for the root cell in a * hierarchy. */ { char *filename; FILE *f; f = extFileOpen(def, outName, "w", &filename); TxPrintf("Extracting %s into %s:\n", def->cd_name, filename); if (f == NULL) { #ifdef MAGIC_WRAPPER TxError("Cannot open output file.\n"); #else TxError("Cannot open output file: "); perror(filename); #endif return; } extNumFatal = extNumWarnings = 0; extCellFile(def, f, doLength); (void) fclose(f); if (extNumFatal > 0 || extNumWarnings > 0) { TxPrintf("%s:", def->cd_name); if (extNumFatal > 0) TxPrintf(" %d fatal error%s", extNumFatal, extNumFatal != 1 ? "s" : ""); if (extNumWarnings > 0) TxPrintf(" %d warning%s", extNumWarnings, extNumWarnings != 1 ? "s" : ""); TxPrintf("\n"); } } /* * ---------------------------------------------------------------------------- * * extFileOpen -- * * Open the .ext file corresponding to a .mag file. * If def->cd_file is non-NULL, the .ext file is just def->cd_file with * the trailing .mag replaced by .ext. Otherwise, the .ext file is just * def->cd_name followed by .ext. * * Results: * Return a pointer to an open FILE, or NULL if the .ext * file could not be opened in the specified mode. * * Side effects: * Opens a file. * * ---------------------------------------------------------------------------- */ FILE * extFileOpen(def, file, mode, prealfile) CellDef *def; /* Cell whose .ext file is to be written */ char *file; /* If non-NULL, open 'name'.ext; otherwise, * derive filename from 'def' as described * above. */ char *mode; /* Either "r" or "w", the mode in which the .ext * file is to be opened. */ char **prealfile; /* If this is non-NULL, it gets set to point to * a string holding the name of the .ext file. */ { char namebuf[512], *name, *endp; int len; FILE *rfile; if (file) name = file; else if (def->cd_file) { name = def->cd_file; if (endp = rindex(def->cd_file, '.')) { name = namebuf; len = endp - def->cd_file; if (len > sizeof namebuf - 1) len = sizeof namebuf - 1; (void) strncpy(namebuf, def->cd_file, len); namebuf[len] = '\0'; } } else name = def->cd_name; /* Try once as-is, and if this fails, try stripping any leading */ /* path information in case cell is in a read-only directory. */ if ((rfile = PaOpen(name, mode, ".ext", Path, CellLibPath, prealfile)) != NULL) return rfile; if (name == def->cd_name) return NULL; name = def->cd_name; return (PaOpen(name, mode, ".ext", Path, CellLibPath, prealfile)); } /* * ---------------------------------------------------------------------------- * * extCellFile -- * * Internal interface for extracting a single cell. * Extracts it to the open FILE 'f'. Doesn't print * any messages. * * Results: * None. * * Side effects: * May leave feedback information where errors were encountered. * Upon return, extNumFatal has been incremented by the number of * fatal errors encountered while extracting 'def', and extNumWarnings * by the number of warnings. * * ---------------------------------------------------------------------------- */ void extCellFile(def, f, doLength) CellDef *def; /* Def to be extracted */ FILE *f; /* Output to this file */ bool doLength; /* TRUE if we should extract driver-receiver path * length information for this cell (see ExtCell * for more details). */ { NodeRegion *reg; UndoDisable(); /* Output the header: timestamp, technology, calls on cell uses */ if (!SigInterruptPending) extHeader(def, f); /* Extract the mask information in this cell */ reg = (NodeRegion *) NULL; if (!SigInterruptPending) reg = extBasic(def, f); /* Do hierarchical extraction */ extParentUse->cu_def = def; if (!SigInterruptPending) extSubtree(extParentUse, f); if (!SigInterruptPending) extArray(extParentUse, f); /* Clean up from basic extraction */ if (reg) ExtFreeLabRegions((LabRegion *) reg); ExtResetTiles(def, extUnInit); /* Final pass: extract length information if desired */ if (!SigInterruptPending && doLength && (ExtOptions & EXT_DOLENGTH)) extLength(extParentUse, f); UndoEnable(); } /* * ---------------------------------------------------------------------------- * * extHeader -- * * Output header information to the .ext file for a cell. * This information consists of: * * timestamp * extractor version number * technology * scale factors for resistance, capacitance, and lambda * calls on all subcells used by this cell (see extOutputUsesFunc) * * Results: * None. * * Side effects: * Writes to (FILE *) 'f'. * * ---------------------------------------------------------------------------- */ void extHeader(def, f) CellDef *def; /* Cell being extracted */ FILE *f; /* Write to this file */ { int n; /* Output a timestamp (should be first) */ fprintf(f, "timestamp %d\n", def->cd_timestamp); /* Output our version number */ fprintf(f, "version %s\n", MagicVersion); /* Output the technology */ fprintf(f, "tech %s\n", DBTechName); /* Output the extract style name */ fprintf(f, "style %s\n", ExtCurStyle->exts_name); /* * Output scaling factors: R C D * R = amount to multiply all resistances in the file by * C = amount to multiply all capacitances by * D = amount to multiply all linear distances by (areas * should be multiplied by D**2). */ fprintf(f, "scale %d %d %g\n", ExtCurStyle->exts_resistScale, ExtCurStyle->exts_capScale, ExtCurStyle->exts_unitsPerLambda); /* Output the sheet resistivity classes */ fprintf(f, "resistclasses"); for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) fprintf(f, " %d", ExtCurStyle->exts_resistByResistClass[n]); fprintf(f, "\n"); /* Output all calls on subcells */ (void) DBCellEnum(def, extOutputUsesFunc, (ClientData) f); } /* * ---------------------------------------------------------------------------- * * extOutputUsesFunc -- * * Filter function, called via DBCellEnum, that outputs all the * cell uses contained in the parent's cell tile planes. * * Results: * Always returns 0, for DBCellEnum to keep going. * * Side effects: * Writes a line for each use encountered to 'outf'. * The line is of the following form: * * use defname useid Ta ... Tf * * where 'defname' is the name of the cell def referenced (cd_name), * 'useid' is its use identifier (cu_id), and Ta ... Tf are the six * components of the transform from coordinates of this use up to * its parent. If the cell is an array, the use id may be followed by: * * [xlo,xhi,xsep][ylo,yhi,ysep] * * The indices are xlo through xhi inclusive, or ylo through yhi * inclusive. The separation between adjacent elements is xsep * or ysep; this is used in computing the transform for a particular * array element. If arraying is not present in a given direction, * the low and high indices are equal and the separation is ignored. * * ---------------------------------------------------------------------------- */ int extOutputUsesFunc(cu, outf) CellUse *cu; FILE *outf; { Transform *t = &cu->cu_transform; fprintf(outf, "use %s %s", cu->cu_def->cd_name, cu->cu_id); if (cu->cu_xlo != cu->cu_xhi || cu->cu_ylo != cu->cu_yhi) { fprintf(outf, "[%d:%d:%d]", cu->cu_xlo, cu->cu_xhi, cu->cu_xsep); fprintf(outf, "[%d:%d:%d]", cu->cu_ylo, cu->cu_yhi, cu->cu_ysep); } /* Output transform to parent */ fprintf(outf, " %d %d %d %d %d %d\n", t->t_a, t->t_b, t->t_c, t->t_d, t->t_e, t->t_f); return (0); } magic-8.0.210/extract/ExtRegion.c0000664000175000001440000003216412421575324015211 0ustar timusers/* * ExtRegion.c -- * * Circuit extraction. * This file contains the code to trace out connected Regions * in a layout, and to build up or tear down lists of Regions. * * ********************************************************************* * * 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/extract/ExtRegion.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #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 "textio/textio.h" #include "debug/debug.h" #include "extract/extract.h" #include "extract/extractInt.h" #include "utils/signals.h" /* * ---------------------------------------------------------------------------- * * ExtFindRegions -- * * Find all the connected geometrical regions in a given area of a CellDef * that will correspond to nodes or devices in the extracted circuit. * Two procedures are supplied by the caller, 'first' and 'each'. * * The function 'first' must be non-NULL. It is called for each tile * tile found in the region. It must return a pointer to a Region * struct (or one of the client forms of a Region struct; see the * comments in extractInt.h). * * Region * * (*first)(tile, arg) * Tile *tile; /# Tile is on plane arg->fra_pNum #/ * FindRegion *arg; * { * } * * If the function 'each' is non-NULL, it is applied once to each tile found * in the region: * * (*each)(tile, planeNum, arg) * Tile *tile; * int planeNum; /# May be different than arg->fra_pNum #/ * FindRegion *arg; * { * } * * Results: * Returns a pointer to the first element in the linked list * of Region structures for this CellDef. The Region structs * may in fact contain more than the basic Region struct; this * will depend on what the function 'first' allocates. * * Side effects: * Each non-space tile has its ti_client field left pointing * to a Region structure that describes the region that tile * belongs to. * * Non-interruptible. It is the caller's responsibility to check * for interrupts. * * ---------------------------------------------------------------------------- */ Region * ExtFindRegions(def, area, mask, connectsTo, uninit, first, each) CellDef *def; /* Cell definition being searched */ Rect *area; /* Area to search initially for tiles */ TileTypeBitMask *mask; /* In the initial area search, only visit * tiles whose types are in this mask. */ TileTypeBitMask *connectsTo;/* Connectivity table for determining regions. * If t1 and t2 are the types of adjacent * tiles, then t1 and t2 belong to the same * region iff: * TTMaskHasType(&connectsTo[t1], t2) * * We assume that connectsTo[] is symmetric, * so this is the same as: * TTMaskHasType(&connectsTo[t2], t1) */ ClientData uninit; /* Contents of a ti_client field indicating * that the tile has not yet been visited. */ Region * (*first)(); /* Applied to first tile in region */ int (*each)(); /* Applied to each tile in region */ { FindRegion arg; int extRegionAreaFunc(); ASSERT(first != NULL, "ExtFindRegions"); arg.fra_connectsTo = connectsTo; arg.fra_def = def; arg.fra_uninit = uninit; arg.fra_first = first; arg.fra_each = each; arg.fra_region = (Region *) NULL; SigDisableInterrupts(); for (arg.fra_pNum=PL_TECHDEPBASE; arg.fra_pNumcd_planes[arg.fra_pNum], area, mask, uninit, extRegionAreaFunc, (ClientData) &arg); SigEnableInterrupts(); return (arg.fra_region); } /* * ---------------------------------------------------------------------------- * * extRegionAreaFunc -- * * Filter function called for each tile found during the area enumeration * in ExtFindRegions above. Only tiles whose ti_client is not already * equal to arg->fra_uninit are visited. * * We call 'fra_first' to allocate a new region struct for it, and then * prepend it to the Region list (Region *) arg->fra_clientData. We * then call ExtFindNeighbors to trace out recursively all the remaining * tiles in the region. * * Results: * Always returns 0, to cause DBSrPaintClient to continue its search. * * Side effects: * Allocates a new Region struct if the tile has not yet been visited. * See also the comments for ExtFindNeighbors. * * ---------------------------------------------------------------------------- */ int extRegionAreaFunc(tile, arg) Tile *tile; FindRegion *arg; { /* Allocate a new region */ if (arg->fra_first) (void) (*arg->fra_first)(tile, arg); if (DebugIsSet(extDebugID, extDebAreaEnum)) extShowTile(tile, "area enum", 0); /* Recursively visit all tiles surrounding this one that we connect to */ (void) ExtFindNeighbors(tile, arg->fra_pNum, arg); return (0); } /* * ---------------------------------------------------------------------------- * * ExtLabelRegions -- * * Given a CellDef whose tiles have been set to point to LabRegions * by ExtFindRegions, walk down the label list and assign labels * to regions. If the tile over which a label lies is still uninitialized * ie, points to extUnInit, we skip the label. * * A label is attached to the LabRegion for a tile if the label's * type and the tile's type are connected according to the table * 'connTo'. This disambiguates the case where a label lies * on the boundary between two tiles of different types. * * Results: * None. * * Side effects: * Each LabRegion has labels added to its label list. * * ---------------------------------------------------------------------------- */ void ExtLabelRegions(def, connTo, nodeList, clipArea) CellDef *def; /* Cell definition being labelled */ TileTypeBitMask *connTo; /* Connectivity table (see above) */ NodeRegion **nodeList; /* Node list to add to (or NULL) */ Rect *clipArea; /* Area to search for sticky labels */ { static Point offsets[] = { { 0, 0 }, { 0, -1 }, { -1, -1 }, { -1, 0 } }; LabelList *ll; Label *lab; Tile *tp; LabRegion *reg; int quad, pNum; Point p; bool found; for (lab = def->cd_labels; lab; lab = lab->lab_next) { found = FALSE; pNum = DBPlane(lab->lab_type); if (lab->lab_type == TT_SPACE || pNum < PL_TECHDEPBASE) continue; for (quad = 0; quad < 4; quad++) { /* * Visit each of the four quadrants surrounding * the lower-left corner of the label, searching * for a tile whose type matches that of the label * or connects to it. */ p.p_x = lab->lab_rect.r_xbot + offsets[quad].p_x; p.p_y = lab->lab_rect.r_ybot + offsets[quad].p_y; tp = def->cd_planes[pNum]->pl_hint; GOTOPOINT(tp, &p); def->cd_planes[pNum]->pl_hint = tp; if (extConnectsTo(TiGetType(tp), lab->lab_type, connTo) && extHasRegion(tp, extUnInit)) { found = TRUE; reg = (LabRegion *) extGetRegion(tp); ll = (LabelList *) mallocMagic((unsigned) (sizeof (LabelList))); ll->ll_label = lab; ll->ll_next = reg->lreg_labels; reg->lreg_labels = ll; if (lab->lab_flags & PORT_DIR_MASK) ll->ll_attr = LL_PORTATTR; else ll->ll_attr = LL_NOATTR; break; } } if ((found == FALSE) && (nodeList != NULL)) { // Unconnected node label. This may be a "sticky label". // If it is not connected to TT_SPACE, then create a new // node region for it. if (GEO_LABEL_IN_AREA(clipArea, &lab->lab_rect) && (lab->lab_type != TT_SPACE)) { NodeRegion *newNode; int n; int nclasses = ExtCurStyle->exts_numResistClasses; n = sizeof (NodeRegion) + (sizeof (PerimArea) * (nclasses - 1)); newNode = (NodeRegion *)mallocMagic((unsigned) n); ll = (LabelList *)mallocMagic(sizeof(LabelList)); ll->ll_label = lab; ll->ll_next = NULL; if (lab->lab_flags & PORT_DIR_MASK) ll->ll_attr = LL_PORTATTR; else ll->ll_attr = LL_NOATTR; newNode->nreg_next = *nodeList; newNode->nreg_pnum = pNum; newNode->nreg_type = lab->lab_type; newNode->nreg_ll = lab->lab_rect.r_ll; newNode->nreg_cap = (CapValue)0; newNode->nreg_resist = 0; for (n = 0; n < nclasses; n++) newNode->nreg_pa[n].pa_perim = newNode->nreg_pa[n].pa_area = 0; newNode->nreg_labels = ll; *nodeList = newNode; } } } } /* * ---------------------------------------------------------------------------- * * ExtLabelOneRegion -- * * Same as ExtLabelRegion, but it only assigns labels to one particular * region. * * Results: * None. * * Side effects: * The region has labels added to its label list. * * ---------------------------------------------------------------------------- */ void ExtLabelOneRegion(def, connTo, reg) CellDef *def; /* Cell definition being labelled */ TileTypeBitMask *connTo; /* Connectivity table (see above) */ NodeRegion *reg; /* The region whose labels we want */ { static Point offsets[] = { { 0, 0 }, { 0, -1 }, { -1, -1 }, { -1, 0 } }; LabelList *ll; Label *lab; Tile *tp; int quad, pNum; Point p; /* Generate segment list for subcircuit boundary, if any */ for (lab = def->cd_labels; lab; lab = lab->lab_next) { pNum = DBPlane(lab->lab_type); if (lab->lab_type == TT_SPACE || pNum < PL_TECHDEPBASE) continue; for (quad = 0; quad < 4; quad++) { /* * Visit each of the four quadrants surrounding * the lower-left corner of the label, searching * for a tile whose type matches that of the label * or connects to it. */ p.p_x = lab->lab_rect.r_xbot + offsets[quad].p_x; p.p_y = lab->lab_rect.r_ybot + offsets[quad].p_y; tp = def->cd_planes[pNum]->pl_hint; GOTOPOINT(tp, &p); def->cd_planes[pNum]->pl_hint = tp; if (extConnectsTo(TiGetType(tp), lab->lab_type, connTo) && (NodeRegion *) extGetRegion(tp) == reg) { ll = (LabelList *) mallocMagic((unsigned) (sizeof (LabelList))); ll->ll_label = lab; ll->ll_next = reg->nreg_labels; reg->nreg_labels = ll; if (lab->lab_flags & PORT_DIR_MASK) ll->ll_attr = LL_PORTATTR; else ll->ll_attr = LL_NOATTR; break; } } } } /* * ---------------------------------------------------------------------------- * * ExtResetTiles -- * * Given a CellDef whose tiles have been set to point to Regions * by ExtFindRegions, reset all the tiles to uninitialized. * * Results: * None. * * Side effects: * All the non-space tiles in the CellDef have their ti_client * fields set back to uninitialized. Does not free the Region * structs that these tiles point to; that must be done by * ExtFreeRegions, ExtFreeLabRegions, or ExtFreeHierLabRegions. * * Non-interruptible. * * ---------------------------------------------------------------------------- */ void ExtResetTiles(def, resetTo) CellDef *def; ClientData resetTo; /* New value for ti_client */ { int pNum; for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) DBResetTilePlane(def->cd_planes[pNum], resetTo); } /* * ---------------------------------------------------------------------------- * * ExtFreeRegions -- * ExtFreeLabRegions -- * ExtFreeHierLabRegions -- * * Free a list of Regions. * ExtFreeLabRegions also frees the LabelLists pointed to by lreg_labels. * ExtFreeHierLabRegions, in addition to freeing the LabelLists, frees * the labels they point to. * * Results: * None. * * Side effects: * Frees memory. * * Non-interruptible. * * ---------------------------------------------------------------------------- */ void ExtFreeRegions(regList) Region *regList; /* List of regions to be freed */ { Region *reg; for (reg = regList; reg; reg = reg->reg_next) freeMagic((char *) reg); } void ExtFreeLabRegions(regList) LabRegion *regList; /* List of regions to be freed */ { LabRegion *lreg; LabelList *ll; for (lreg = regList; lreg; lreg = lreg->lreg_next) { for (ll = lreg->lreg_labels; ll; ll = ll->ll_next) freeMagic((char *) ll); freeMagic((char *) lreg); } } void ExtFreeHierLabRegions(regList) Region *regList; /* List of regions to be freed */ { Region *reg; LabelList *ll; for (reg = regList; reg; reg = reg->reg_next) { for (ll = ((LabRegion *)reg)->lreg_labels; ll; ll = ll->ll_next) { freeMagic((char *) ll->ll_label); freeMagic((char *) ll); } freeMagic((char *) reg); } } magic-8.0.210/extract/ExtInter.c0000644000175000001440000004772210751423606015052 0ustar timusers/* * ExtInteraction.c -- * * Circuit extraction. * Finds interaction areas. * * ********************************************************************* * * 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/extract/ExtInter.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/geofast.h" #include "utils/undo.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/malloc.h" #include "textio/textio.h" #include "debug/debug.h" #include "extract/extract.h" #include "extract/extractInt.h" #include "utils/signals.h" #include "utils/styles.h" /* Local data */ CellUse *extInterUse = (CellUse *) NULL; /* Subtree being processed */ Plane *extInterPlane; /* Paint into this plane */ int extInterHalo; /* Elements closer than this * constitute an interaction. */ int extInterBloat; /* Bloat by this much when * painting into result plane. */ /* Forward declarations */ int extInterOverlapSubtree(); int extInterOverlapTile(); int extInterSubtree(); int extInterSubtreeClip(); int extInterSubtreeElement(); int extInterSubtreeTile(); int extInterSubtreePaint(); #define BLOATBY(r, h) ( (r)->r_xbot -= (h), (r)->r_ybot -= (h), \ (r)->r_xtop += (h), (r)->r_ytop += (h) ) /* * ---------------------------------------------------------------------------- * * ExtFindInteractions -- * * Paint into the supplied tile plane 'resultPlane' TT_ERROR_P tiles * for each area in the CellDef 'def' that must be processed for * interactions. * * Each interaction arises from paint in two different subtrees * being less than (but not equal to) 'halo' units away from * each other. In this definition, a subtree refers to a single * CellUse, which may be either a single cell or an entire array. * * If 'bloat' is non-zero, each interaction area is bloated by * this amount when being painted into the result plane. * * Results: * None. * * Side effects: * Paints into the plane 'resultPlane'. * * ---------------------------------------------------------------------------- */ void ExtFindInteractions(def, halo, bloatby, resultPlane) CellDef *def; /* Find interactions among children of def */ int halo; /* Interaction is elements closer than halo */ int bloatby; /* Bloat each interaction area by this amount when * painting into resultPlane. */ Plane *resultPlane; /* Paint interaction areas into this plane */ { SearchContext scx; UndoDisable(); extInterPlane = resultPlane; extInterHalo = halo; extInterBloat = bloatby; extParentUse->cu_def = def; scx.scx_use = extParentUse; scx.scx_trans = GeoIdentityTransform; scx.scx_area = def->cd_bbox; /* * Process each child subtree. * This involves comparing all the paint in the subtree * with all the paint in all other subtrees up to, but * not including, the subtree under consideration. */ extInterUse = (CellUse *) NULL; (void) extCellSrArea(&scx, extInterSubtree, (ClientData) NULL); /* * Process parent paint if there were any subcells. * We compare each paint rectangle with all the paint in * all the subtrees, to see if there is an overlap. */ if (extInterUse) { extInterUse = (CellUse *) NULL; (void) extCellSrArea(&scx, extInterSubtreePaint, (ClientData) def); } UndoEnable(); } int extInterSubtreePaint(scx, def) SearchContext *scx; CellDef *def; { Rect r; int pNum; r = scx->scx_use->cu_bbox; BLOATBY(&r, extInterHalo); for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) (void) DBSrPaintArea((Tile *) NULL, def->cd_planes[pNum], &r, &DBAllButSpaceAndDRCBits, extInterSubtreeTile, (ClientData) NULL); return (2); } /* * ---------------------------------------------------------------------------- * * extInterSubtree -- * * Called for each immediate child use of the cell being processed * for interactions. Our job is to process all the paint in this * use against all other subtrees overlapping this one. * * Results: * Returns 2 to abort after the first array element. * * Side effects: * Sets extInterUse to scx->scx_use. * Children may paint into extInterPlane. * * ---------------------------------------------------------------------------- */ int extInterSubtree(scx) SearchContext *scx; { CellUse *oldUse = extInterUse; SearchContext parentScx; extInterUse = scx->scx_use; if (oldUse) { /* Find all other subtrees overlapping this cell */ parentScx.scx_area = scx->scx_use->cu_bbox; BLOATBY(&parentScx.scx_area, extInterHalo); parentScx.scx_trans = GeoIdentityTransform; parentScx.scx_use = extParentUse; (void) extCellSrArea(&parentScx, extInterSubtreeClip, (ClientData) scx); } return (2); } int extInterSubtreeClip(overlapScx, scx) SearchContext *overlapScx, *scx; { Rect r, r2; /* Only search as far as extInterUse */ if (overlapScx->scx_use == extInterUse) return (2); /* * Only process the overlap between overlapScx and scx, * bloating both by extInterHalo. */ r = overlapScx->scx_use->cu_bbox; BLOATBY(&r, extInterHalo); r2 = scx->scx_use->cu_bbox; BLOATBY(&r2, extInterHalo); GEOCLIP(&r, &r2); (void) DBArraySr(scx->scx_use, &r, extInterSubtreeElement, (ClientData) &r); return (2); } /* * ---------------------------------------------------------------------------- * * extInterSubtreeElement -- * * Called for each element in the array forming the use passed to * extInterSubtree(). See extInterSubtree() for comments. * * Results: * Returns 0 always. * * Side effects: * See ExtFindInteractions. * * ---------------------------------------------------------------------------- */ int extInterSubtreeElement(use, trans, x, y, r) CellUse *use; Transform *trans; int x, y; Rect *r; { SearchContext scx; Transform tinv; scx.scx_use = use; scx.scx_trans = *trans; scx.scx_x = x; scx.scx_y = y; GEOINVERTTRANS(trans, &tinv); GEOTRANSRECT(&tinv, r, &scx.scx_area); (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, extInterSubtreeTile, (ClientData) NULL); return (0); } /* * ---------------------------------------------------------------------------- * * extInterSubtreeTile -- * * Called for each tile in the subtree being processed by * extInterSubtree(). Transform this tile to root coordinates, * bloating by extInterHalo, and then call extInterOverlapSubtree * to process all the other subtrees for paint overlapping * this bloated area. If the argument 'cxp' is non-NULL, we * use cxp->tc_scx->scx_trans to transform the area of tile to * root coordinates; otherwise, we don't transform it at all. * * Results: * Returns 0 always. * * Side effects: * See extInterOverlapTile. * * ---------------------------------------------------------------------------- */ int extInterSubtreeTile(tile, cxp) Tile *tile; TreeContext *cxp; { SearchContext newscx; Rect r; TITORECT(tile, &r); BLOATBY(&r, extInterHalo); if (cxp) { GEOTRANSRECT(&cxp->tc_scx->scx_trans, &r, &newscx.scx_area); } else newscx.scx_area = r; newscx.scx_trans = GeoIdentityTransform; newscx.scx_use = extParentUse; (void) extCellSrArea(&newscx, extInterOverlapSubtree, (ClientData) NULL); return (0); } /* * ---------------------------------------------------------------------------- * * extInterOverlapSubtree -- * * Called for each subcell of the root that overlaps the piece * of paint found by extInterSubtreeTile() above. We stop * as soon as we see extInterUse; otherwise, search all the * cells in the subtree rooted at scx->scx_use for paint * overlapping scx->scx_area. * * Results: * Returns 2 if we see extInterUse; otherwise, returns 0. * * Side effects: * Paints into the plane 'resultPlane'; see extInterOverlapTile. * * ---------------------------------------------------------------------------- */ int extInterOverlapSubtree(scx) SearchContext *scx; { if (extInterUse == scx->scx_use) return (2); (void) extTreeSrPaintArea(scx, extInterOverlapTile, (ClientData) NULL); return (0); } /* * ---------------------------------------------------------------------------- * * extInterOverlapTile -- * * Called for each piece of paint overlapping the piece found * by extInterSubtreeTile(). Bloat the found piece by extInterHalo, * then clip to the area of the overlapping piece of paint in root * coordinates. If the result is non-empty, paint it into the * plane extInterPlane. * * Results: * Returns 0 always. * * Side effects: * Paints into the plane 'resultPlane'. * * ---------------------------------------------------------------------------- */ int extInterOverlapTile(tile, cxp) Tile *tile; TreeContext *cxp; { SearchContext *scx = cxp->tc_scx; Rect r, rootr; TITORECT(tile, &r); BLOATBY(&r, extInterHalo); GEOCLIP(&r, &scx->scx_area); if (GEO_RECTNULL(&r)) return (0); GEOTRANSRECT(&scx->scx_trans, &r, &rootr); BLOATBY(&rootr, extInterBloat); DBPaintPlane(extInterPlane, &rootr, DBStdWriteTbl(TT_ERROR_P), (PaintUndoInfo *) NULL); return (0); } /* *----------------------------------------------------------------------------- * * extTreeSrPaintArea -- * * Recursively search downward from the supplied CellUse for * all paint tiles. * * The procedure should be of the following form: * * int * func(tile, scx, cdata) * Tile *tile; * SearchContext *scx; * ClientData cdata; * { * } * * The SearchContext is stored in cxp->tc_scx, and the user's arg is stored * in cxp->tc_filter->tf_arg. * * In the above, the scx transform is the net transform from the coordinates * of tile to "world" coordinates (or whatever coordinates the initial * transform supplied to extTreeSrTiles was a transform to). Func returns * 0 under normal conditions. If 1 is returned, it is a request to * abort the search. * * *** WARNING *** * * The client procedure should not modify any of the paint planes in * the cells visited by extTreeSrTiles, because we use DBSrPaintArea * instead of TiSrArea as our paint-tile enumeration function. * * Results: * 0 is returned if the search finished normally. 1 is returned * if the search was aborted. * * Side effects: * Whatever side effects are brought about by applying the * procedure supplied. * *----------------------------------------------------------------------------- */ int extTreeSrPaintArea(scx, func, cdarg) SearchContext *scx; /* Pointer to search context specifying * a cell use to search, an area in the * coordinates of the cell's def, and a * transform back to "root" coordinates. */ int (*func)(); /* Function to apply at each qualifying tile */ ClientData cdarg; /* Client data for above function */ { int extTreeSrFunc(); CellDef *def = scx->scx_use->cu_def; TreeContext context; TreeFilter filter; int pNum; if ((def->cd_flags & CDAVAILABLE) == 0) if (!DBCellRead(def, (char *) NULL, TRUE)) return 0; filter.tf_func = func; filter.tf_arg = cdarg; context.tc_scx = scx; context.tc_filter = &filter; /* * Apply the function first to any of the tiles in the planes * for this CellUse's CellDef that match the mask. */ for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) if (DBSrPaintArea((Tile *) NULL, def->cd_planes[pNum], &scx->scx_area, &DBAllButSpaceAndDRCBits, func, (ClientData) &context)) return (1); /* Visit our children recursively */ return (extCellSrArea(scx, extTreeSrFunc, (ClientData) &filter)); } /* * extTreeSrFunc -- * * Filter procedure applied to subcells by extTreeSrPaintArea(). */ int extTreeSrFunc(scx, fp) SearchContext *scx; TreeFilter *fp; { CellDef *def = scx->scx_use->cu_def; TreeContext context; int pNum; if ((def->cd_flags & CDAVAILABLE) == 0) if (!DBCellRead(def, (char *) NULL, TRUE)) return (0); context.tc_scx = scx; context.tc_filter = fp; /* * Apply the function first to any of the tiles in the planes * for this CellUse's CellDef that match the mask. */ for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) if (DBSrPaintArea((Tile *) NULL, def->cd_planes[pNum], &scx->scx_area, &DBAllButSpaceAndDRCBits, fp->tf_func, (ClientData) &context)) return (1); /* Visit our children recursively */ return (extCellSrArea(scx, extTreeSrFunc, (ClientData) fp)); } /* *----------------------------------------------------------------------------- * * extCellSrArea -- * * Apply the supplied procedure to each of the cellUses found in the * given area in the subcell plane of the child def of the supplied * search context. * * The procedure is applied to each array element in each cell use that * overlaps the clipping rectangle. The scx_x and scx_y parts of * the SearchContext passed to the filter function correspond to the * array element being visited. The same CellUse is, of course, passed * as scx_use for all elements of the array. * * The array elements are visited by varying the X coordinate fastest. * * The procedure should be of the following form: * int * func(scx, cdarg) * SearchContext *scx; * ClientData cdarg; * { * } * * Func normally returns 0. If it returns 1 then the search is * aborted. If it returns 2, then any remaining elements in the * current array are skipped. * * Results: * 0 is returned if the search terminated normally. 1 is * returned if it was aborted. * * Side effects: * Whatever side effects are brought about by applying the * procedure supplied. * *----------------------------------------------------------------------------- */ int extCellSrArea(scx, func, cdarg) SearchContext *scx; /* Pointer to search context specifying a cell use to * search, an area in the coordinates of the cell's * def, and a transform back to "root" coordinates. * The area may have zero size. */ int (*func)(); /* Function to apply at every tile found */ ClientData cdarg; /* Argument to pass to function */ { int xlo, xhi, ylo, yhi, xbase, ybase, xsep, ysep, clientResult; int srchBot, srchRight; Plane *plane = scx->scx_use->cu_def->cd_planes[PL_CELL]; Tile *tp, *tpnew; Rect *rect, *bbox; CellUse *use; SearchContext newScx; CellTileBody *body; Transform t, tinv; TreeFilter filter; Rect expanded; Point start; filter.tf_func = func; filter.tf_arg = cdarg; if ((scx->scx_use->cu_def->cd_flags & CDAVAILABLE) == 0) if (!DBCellRead(scx->scx_use->cu_def, (char *) NULL, TRUE)) return 0; /* * In order to make this work with zero-size areas, we first expand * the area by before searching the tile plane. extCellSrFunc will * check carefully to throw out things that don't overlap the original * area. The expansion is tricky because we mustn't expand infinities. */ expanded = scx->scx_area; if (expanded.r_xbot > TiPlaneRect.r_xbot) expanded.r_xbot -= 1; if (expanded.r_ybot > TiPlaneRect.r_ybot) expanded.r_ybot -= 1; if (expanded.r_xtop < TiPlaneRect.r_xtop) expanded.r_xtop += 1; if (expanded.r_ytop < TiPlaneRect.r_ytop) expanded.r_ytop += 1; rect = &expanded; /* Start along the top of the LHS of the search area */ start.p_x = rect->r_xbot; start.p_y = rect->r_ytop - 1; tp = plane->pl_hint; GOTOPOINT(tp, &start); /* Each iteration visits another tile on the LHS of the search area */ while (TOP(tp) > rect->r_ybot) { /* Each iteration enumerates another tile */ enumerate: plane->pl_hint = tp; if (SigInterruptPending) return (1); /* * Since subcells are allowed to overlap, a single tile body may * refer to many subcells and a single subcell may be referred to * by many tile bodies. To insure that each CellUse is enumerated * exactly once, the procedure given to DBCellSrArea is only applied * to a CellUse when its lower right corner is contained in the * tile to dbCellSrFunc (or otherwise at the last tile encountered * in the event the lower right corner of the CellUse is outside the * search rectangle). */ srchBot = scx->scx_area.r_ybot; srchRight = scx->scx_area.r_xtop; for (body = (CellTileBody *) TiGetBody(tp); body != NULL; body = body->ctb_next) { use = newScx.scx_use = body->ctb_use; ASSERT(use != (CellUse *) NULL, "dbCellSrFunc"); /* * The check below is to ensure that we only enumerate each * cell once, even though it appears in many different tiles * in the subcell plane. */ bbox = &use->cu_bbox; if ( (BOTTOM(tp) <= bbox->r_ybot || (BOTTOM(tp) <= srchBot && bbox->r_ybot < srchBot)) && (RIGHT(tp) >= bbox->r_xtop || (RIGHT(tp) >= srchRight && bbox->r_xtop >= srchRight))) { /* * Make sure that this cell really does overlap the * search area (it could be just touching because of * the expand-by-one in DBCellSrArea). */ if (!GEO_OVERLAP(&scx->scx_area, bbox)) continue; /* If not an array element, it's much simpler */ if (use->cu_xlo == use->cu_xhi && use->cu_ylo == use->cu_yhi) { newScx.scx_x = use->cu_xlo, newScx.scx_y = use->cu_yhi; if (SigInterruptPending) return 1; GEOINVERTTRANS(&use->cu_transform, &tinv); GEOTRANSTRANS(&use->cu_transform, &scx->scx_trans, &newScx.scx_trans); GEOTRANSRECT(&tinv, &scx->scx_area, &newScx.scx_area); if ((*func)(&newScx, filter.tf_arg) == 1) return 1; continue; } /* * More than a single array element; * check to see which ones overlap our search area. */ DBArrayOverlap(use, &scx->scx_area, &xlo, &xhi, &ylo, &yhi); xsep = (use->cu_xlo > use->cu_xhi) ? -use->cu_xsep : use->cu_xsep; ysep = (use->cu_ylo > use->cu_yhi) ? -use->cu_ysep : use->cu_ysep; for (newScx.scx_y = ylo; newScx.scx_y<=yhi; newScx.scx_y++) for (newScx.scx_x = xlo; newScx.scx_x<=xhi; newScx.scx_x++) { if (SigInterruptPending) return 1; xbase = xsep * (newScx.scx_x - use->cu_xlo); ybase = ysep * (newScx.scx_y - use->cu_ylo); GEOTRANSTRANSLATE(xbase, ybase, &use->cu_transform, &t); GEOINVERTTRANS(&t, &tinv); GEOTRANSTRANS(&t, &scx->scx_trans, &newScx.scx_trans); GEOTRANSRECT(&tinv, &scx->scx_area, &newScx.scx_area); clientResult = (*func)(&newScx, filter.tf_arg); if (clientResult == 2) goto skipArray; else if (clientResult == 1) return 1; } } skipArray: continue; } tpnew = TR(tp); if (LEFT(tpnew) < rect->r_xtop) { while (BOTTOM(tpnew) >= rect->r_ytop) tpnew = LB(tpnew); if (BOTTOM(tpnew) >= BOTTOM(tp) || BOTTOM(tp) <= rect->r_ybot) { tp = tpnew; goto enumerate; } } /* Each iteration returns one tile further to the left */ while (LEFT(tp) > rect->r_xbot) { if (BOTTOM(tp) <= rect->r_ybot) return (0); tpnew = LB(tp); tp = BL(tp); if (BOTTOM(tpnew) >= BOTTOM(tp) || BOTTOM(tp) <= rect->r_ybot) { tp = tpnew; goto enumerate; } } /* At left edge -- walk down to next tile along the left edge */ for (tp = LB(tp); RIGHT(tp) <= rect->r_xbot; tp = TR(tp)) /* Nothing */; } return (0); } magic-8.0.210/extract/ExtLength.c0000644000175000001440000007144311252261164015203 0ustar timusers/* * ExtLength.c -- * * Circuit extraction. * Computation of the length of the shortest path from a driver * to a receiver. This information is intended to be used in * computing delays of signals propagating in a transmission * line mode, where delay is proportional to the driver-to-receiver * distance. * * ********************************************************************* * * 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. * * ********************************************************************* * Lawrence Livermore National Laboratory */ #ifndef lint static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/extract/ExtLength.c,v 1.3 2009/09/10 20:32:52 tim Exp $"; #endif /* not lint */ #include #include #include #include #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 "utils/malloc.h" #include "textio/textio.h" #include "debug/debug.h" #include "extract/extract.h" #include "extract/extractInt.h" #include "utils/signals.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "utils/styles.h" #include "utils/stack.h" #include "utils/main.h" #include "utils/utils.h" /* Temporary cell for holding an entire flattened net */ CellDef *extPathDef = NULL; CellUse *extPathUse = NULL; /* * Tables that hold information describing each driver and receiver * in the circuit. * * Each entry in the driver table will be initially 0, and later * will be made to point to a list of hierarchical labels (i.e., * specially constructed labels whose text field contains a full * hierarchical pathname) where the driver label appears in the * design. * * Each entry in the receiver table is initially 0, and is set to 1 * when that receiver is processed as being connected to some driver. */ HashTable extDriverHash; HashTable extReceiverHash; /* Initial size of the hash tables used in this file */ #define INITHASHSIZE 32 /* Max length of a hierarchical name */ #define MAXNAMESIZE 2048 /* * List of labels being built up hierarchically by extLengthYank(). * This is used within this file to pass data down to filter * procedures of search functions. */ static Label *extLengthLabelList; /* * Used to hold information while tracing out paths. * Passed directly down to filter procedures of search functions. */ struct extPathArg { int epa_min, epa_max; int epa_pNum; Label *epa_lab1, *epa_lab2; }; /* * Additional information passed down to extPathFloodFunc() */ struct extPathFloodArg { int epfa_distance; Point *epfa_srcPoint; Tile *epfa_srcTile; Rect epfa_srcArea; struct extPathArg *epfa_epa; }; /* Used to mark tiles during path tracing */ #define MARKED ((ClientData) 1) /* Forward declarations */ Label *extPathLabel(); Label *extLengthYank(); int extLengthLabels(); int extLengthLabelsFunc(); int extPathPairFunc(); int extPathResetClient(); int extPathFloodFunc(); void extLengthInit(); void extPathPairDistance(); void extPathFlood(); void extPathFloodTile(); /* * ---------------------------------------------------------------------------- * * ExtSetDriver -- * ExtSetReceiver -- * * Add a terminal name to either the driver or the receiver table. * * Results: * None. * * Side effects: * Adds an entry to the hash tables extDriverHash or extReceiverHash * respectively. The initial value of the hash entry is 0. * * ---------------------------------------------------------------------------- */ void ExtSetDriver(name) char *name; { HashEntry *he; he = HashFind(&extDriverHash, name); HashSetValue(he, 0); } void ExtSetReceiver(name) char *name; { HashEntry *he; he = HashFind(&extReceiverHash, name); HashSetValue(he, 0); } /* * ---------------------------------------------------------------------------- * * ExtLengthClear -- * * Kill extDriverHash and extReceiverHash, and re-initialize them. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void ExtLengthClear() { HashKill(&extDriverHash); HashKill(&extReceiverHash); extLengthInit(); } /* * ---------------------------------------------------------------------------- * * extLengthInit -- * * Allocates and initializes the hash tables extDriverHash * and extReceiverHash. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void extLengthInit() { HashInit(&extDriverHash, INITHASHSIZE, 0); HashInit(&extReceiverHash, INITHASHSIZE, 0); } /* * ---------------------------------------------------------------------------- * * extLength -- * * Using the driver and receiver tables, compute the distances from * each driver to each receiver on its (flattened) net. Output to * the file 'f' lines of the following format: * * distance drivername receivername min max * * e.g, * * distance a/b/cOUT d/e/fIN 1234 2345 * * The units of distance are lambda. * * Results: * None. * * Side effects: * Outputs to the FILE 'f'. * * ---------------------------------------------------------------------------- */ void extLength(rootUse, f) CellUse *rootUse; /* The names stored in the driver and receiver tables * should all be relative to this root cell. It is * the responsibility of the caller to ensure this. */ FILE *f; /* Open output file */ { Label *dList, *rList, *dLab, *rLab; int min, max; HashSearch hs; HashEntry *he; /* Create the yank cell if it doesn't already exist */ if (extPathDef == (CellDef *) NULL) DBNewYank("__PATHYANK__", &extPathUse, &extPathDef); /* * Initialize the entries in the driver table to point to * a list of hierarchical labels describing the locations * where that driver appears. These labels should all * be from a single cell. */ HashStartSearch(&hs); while (he = HashNext(&extDriverHash, &hs)) { dList = extPathLabel(rootUse, he->h_key.h_name); HashSetValue(he, (ClientData) dList); } /* * Main loop. * For each driver, find all the receivers connected to it, and * then compute and output the distance to each. */ HashStartSearch(&hs); while (he = HashNext(&extDriverHash, &hs)) { /* Ignore drivers whose labels couldn't be found */ dList = (Label *) HashGetValue(he); if (dList == (Label *) NULL) continue; /* * Flatten this net into extPathDef. * Find all the labels that overlap material we yanked and * whose names appear in the receiver table. Build a hierarchical * list of these labels. */ rList = extLengthYank(rootUse, dList); /* * Now compute the distance from the driver label to * each of the receivers. Free each driver label * as it is processed. */ for (dLab = dList; dLab; dLab = dLab->lab_next) { for (rLab = rList; rLab; rLab = rLab->lab_next) { extPathPairDistance(dLab, rLab, &min, &max); fprintf(f, "distance %s %s %d %d\n", dLab->lab_text, rLab->lab_text, min, max); } /* Free the driver label */ freeMagic((char *) dLab); } /* Free all the receiver labels built up during this iteration */ for (rLab = rList; rLab; rLab = rLab->lab_next) freeMagic((char *) rLab); /* For sanity since we've freed the driver label list */ HashSetValue(he, (ClientData) NULL); } } /* * ---------------------------------------------------------------------------- * * extLengthYank -- * * Trace out all material connected to each location on the label * list 'labList', both in the root cell use->cu_def and hierarchically * in all of its children. Flatten this material into the cell * 'extPathDef'. * * Results: * Returns a list of the hierarchical labels whose names appear * in the receiver table (extReceiverHash) that are overlapped * by material we yanked. * * Side effects: * Adds material to extPathDef after erasing its previous contents. * * ---------------------------------------------------------------------------- */ Label * extLengthYank(use, labList) CellUse *use; /* Cell whose material is to be traced */ Label *labList; /* List of labels whose attached net is to be traced */ { SearchContext scx; char mesg[512]; Label *lab; int pNum; /* Eliminate previous contents of yank cell */ if (DebugIsSet(extDebugID, extDebLength)) { DBReComputeBbox(extPathDef); DBWAreaChanged(extPathDef, &extPathDef->cd_bbox, DBW_ALLWINDOWS, &DBAllButSpaceBits); } DBCellClearDef(extPathDef); /* * Search out all material connected to each label. * Bloat the label's rectangle to consider even material * that only touches the label. */ for (lab = labList; lab; lab = lab->lab_next) { if (lab->lab_type == TT_SPACE) continue; scx.scx_use = use; scx.scx_trans = GeoIdentityTransform; GEO_EXPAND(&lab->lab_rect, 1, &scx.scx_area); DBTreeCopyConnect(&scx, &DBConnectTbl[lab->lab_type], 0, DBConnectTbl, &TiPlaneRect, extPathUse); } if (DebugIsSet(extDebugID, extDebLength)) { DBReComputeBbox(extPathDef); DBWAreaChanged(extPathDef, &extPathDef->cd_bbox, DBW_ALLWINDOWS, &DBAllButSpaceBits); WindUpdate(); (void) sprintf(mesg, "Yanked %s", labList ? labList->lab_text : "(NONE)"); TxMore(mesg); } /* * Now find all the labels appearing in the receiver table that are * overlapped by any of the material we just yanked. This may not * be the most efficient way to do things: we're searching the label * list of at least the root cell every time we process a tile in * the yanked net. The hope is that this is still fast enough. * Possibly a better way would be to identify the CELLS that are * overlapped by tiles in the net, and then to process each label * list just once. */ extLengthLabelList = (Label *) NULL; for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) { (void) DBSrPaintArea((Tile *) NULL, extPathDef->cd_planes[pNum], &TiPlaneRect, &DBAllButSpaceBits, extLengthLabels, (ClientData) use); } return (extLengthLabelList); } /* * ---------------------------------------------------------------------------- * * extLengthLabels -- * * Called for each paint tile in extPathDef to find all the labels * in the original search tree that overlap the tile. We bloat each * tile to the top and right by one unit to be certain to catch * labels appearing on these edges. * * Results: * Always returns 0. * * Side effects: * May cons hierarchical labels (newly created labels whose text * is the full hierarchical path of a label in a subcell) to the * list extLengthLabelList. * * ---------------------------------------------------------------------------- */ int extLengthLabels(tile, rootUse) Tile *tile; /* Some tile in extPathDef */ CellUse *rootUse; /* The original root cell */ { char name[MAXNAMESIZE]; TileTypeBitMask mask; TerminalPath tpath; SearchContext scx; /* Grow the search area to include labels on the top and right */ TITORECT(tile, &scx.scx_area); scx.scx_area.r_xtop++; scx.scx_area.r_ytop++; scx.scx_use = rootUse; scx.scx_trans = GeoIdentityTransform; tpath.tp_first = tpath.tp_next = name; tpath.tp_last = &name[sizeof name - 2]; TTMaskSetOnlyType(&mask, TiGetType(tile)); (void) DBTreeSrLabels(&scx, &mask, 0, &tpath, TF_LABEL_ATTACH, extLengthLabelsFunc, (ClientData) NULL); return (0); } /* * ---------------------------------------------------------------------------- * * extLengthLabelsFunc -- * * Called for each label found while searching hierarchically the area * beneath one of the tiles in extPathDef. If the hierarchical label * name matches a name appearing in the receiver table (extReceiverHash) * we cons a newly created hierarchical label onto the front of * extLengthLabelList. * * Results: * Always returns 0. * * Side effects: * May cons hierarchical labels (newly created labels whose text * is the full hierarchical path of a label in a subcell) to the * list extLengthLabelList. Also, for each receiver label we * did find, leaves a value of 1 (via HashSetValue()) in the * receiver hash table, so we can know at the end which receiver * labels weren't driven by any driver. * * ---------------------------------------------------------------------------- */ int extLengthLabelsFunc(scx, label, tpath) SearchContext *scx; /* Where in the search tree we are */ Label *label; /* The label itself */ TerminalPath *tpath; /* Identifies hierarchical prefix for label. * The full hierarchical pathname will be the * concatenation of the string tpath->tp_first * and the string label->lab_text. */ { Label *newLab; HashEntry *he; int len; /* Concatenate the prefix and label to get the full hierarchical name */ (void) strcpy(tpath->tp_next, label->lab_text); /* Only bother with labels in the receiver table */ he = HashLookOnly(&extReceiverHash, tpath->tp_first); if (he == NULL) return (0); /* Mark this receiver as being seen */ HashSetValue(he, (ClientData) 1); /* Allocate and fill in a new hierarchical label */ len = strlen(tpath->tp_first) + sizeof (Label) - sizeof newLab->lab_text + 1; newLab = (Label *) mallocMagic((unsigned) len); newLab->lab_type = label->lab_type; newLab->lab_just = GeoTransPos(&scx->scx_trans, label->lab_just); GeoTransRect(&scx->scx_trans, &label->lab_rect, &newLab->lab_rect); newLab->lab_next = extLengthLabelList; extLengthLabelList = newLab; (void) strcpy(newLab->lab_text, tpath->tp_first); return (0); } /* * ---------------------------------------------------------------------------- * * extPathLabel -- * * Find all the locations of labels matching the hierarchical * name 'text' and return a linked list of newly allocated * labels with the full hierarchical name. * * Results: * Returns a pointer to the newly allocated Label list * * Side effects: * Allocates memory. * Complains if the label couldn't be found. * * ---------------------------------------------------------------------------- */ Label * extPathLabel(use, text) CellUse *use; char *text; { int extPathLabelFunc(); Label *lab; lab = (Label *) NULL; (void) DBSrLabelLoc(use, text, extPathLabelFunc, (ClientData) &lab); if (lab == NULL) TxError("Can't find terminal \"%s\"\n", text); return (lab); } /* * ---------------------------------------------------------------------------- * * extPathLabelFunc -- * * Called via DBSrLabelLoc() on behalf of extPathLabel() above. * Creates a Label whose text is the string pointed to by text, * whose lab_rect is *rect, and whose type is childLab->lab_type. * Cons it onto the front of the list *pLabList. * * Results: * Always returns 0. * * Side effects: * Allocates memory. * * ---------------------------------------------------------------------------- */ int extPathLabelFunc(rect, text, childLab, pLabList) Rect *rect; /* Transformed location of the label */ char *text; /* Full hierarchical name of the label */ Label *childLab; /* The label itself */ Label **pLabList; /* Cons the newly allocated label onto the front of * this list. */ { Label *lab; int len; len = strlen(text) + sizeof (Label) - sizeof lab->lab_text + 1; lab = (Label *) mallocMagic((unsigned) len); lab->lab_type = childLab->lab_type; lab->lab_rect = *rect; lab->lab_just = GEO_CENTER; /* Irrelevant */ lab->lab_next = *pLabList; /* Cons to front of list */ *pLabList = lab; (void) strcpy(lab->lab_text, text); return (0); } /* * ---------------------------------------------------------------------------- * * extPathPairDistance -- * * Compute the actual delay between two locations 'lab1' and 'lab2'. * The delay is computed using optimistic and pessimistic assumptions * to get a min and max delay respectively. * * Algorithm: * The algorithm we use here is simplistic, assuming that all * wires are of essentially uniform width. We use a tile-based * depth-first flooding algorithm that computes a delay on the * forward pass based on the wire's length. * * Results: * None. * * Side effects: * Stores the min and max delay in *pMin and *pMax respectively. * Uses the ti_client fields of the tiles in extPathDef, since * these are used while tracing out paths. * * ---------------------------------------------------------------------------- */ void extPathPairDistance(lab1, lab2, pMin, pMax) Label *lab1, *lab2; int *pMin, *pMax; { struct extPathArg epa; TileTypeBitMask mask; PlaneMask pMask; int pNum; Rect r; /* Skip if either type is space (sanity check) */ if (lab1->lab_type == TT_SPACE || lab2->lab_type == TT_SPACE) return; /* Include all tiles touching lab1 that are connected to it */ GEO_EXPAND(&lab1->lab_rect, 1, &r); mask = DBConnectTbl[lab1->lab_type]; /* * Find min and max delays, considering each plane that * lab1 is connected to. Don't reset the ti_client fields * until after we've found all paths. */ epa.epa_min = INFINITY; epa.epa_max = MINFINITY; epa.epa_lab1 = lab1; epa.epa_lab2 = lab2; pMask = DBTechTypesToPlanes(&mask); for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) if (PlaneMaskHasPlane(pMask, pNum)) { epa.epa_pNum = pNum; (void) DBSrPaintClient((Tile *) NULL, extPathDef->cd_planes[pNum], &r, &mask, (ClientData) CLIENTDEFAULT, extPathPairFunc, (ClientData) &epa); } /* Pass the min and max delay back to our caller */ *pMin = epa.epa_min; *pMax = epa.epa_max; /* Reset ti_client fields in tiles */ for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) (void) DBSrPaintClient((Tile *) NULL, extPathDef->cd_planes[pNum], &TiPlaneRect, &DBAllButSpaceBits, MARKED, extPathResetClient, (ClientData) NULL); } /* * ---------------------------------------------------------------------------- * extPathResetClient -- * * Called by DBSrPaintClient() on behalf of extPathPairDistance() * above to reset each tile's ti_client field to CLIENTDEFAULT. * * Results: * Always returns 0. * * Side effects: * Sets tile->ti_client to CLIENTDEFAULT. * ---------------------------------------------------------------------------- */ int extPathResetClient(tile) Tile *tile; { tile->ti_client = (ClientData) CLIENTDEFAULT; return (0); } /* * ---------------------------------------------------------------------------- * * extPathPairFunc -- * * Called by DBSrPaintClient() on behalf of extPathPairDistance() * above for each unprocessed tile (ti_client == CLIENTDEFAULT) * overlapped by epa->epa_lab1 that is connected to it. * Floods outward in depth-first search toward the destination * epa->epa_lab2. Remembers the min and max delay to the * destination in epa->epa_min and epa->epa_max. * * We use depth-first search instead of breadth-first because * it's easier, we need to consider both the longest and shortest * path, and we expect there to be only a few paths. * * Results: * Returns 0 always. * * Side effects: * See above. * Marks the ti_client fields of the tiles we visit as MARKED. * * ---------------------------------------------------------------------------- */ int extPathPairFunc(tile, epa) Tile *tile; struct extPathArg *epa; { Point startPoint; Rect r; /* * Visit all this tile's neighbors. * Our initial delay is zero, and our initial starting point * is in the center of the overlap of epa->epa_lab1 and tile. */ TITORECT(tile, &r); GEOCLIP(&r, &epa->epa_lab1->lab_rect); startPoint.p_x = (r.r_xtop + r.r_xbot) / 2; startPoint.p_y = (r.r_ytop + r.r_ybot) / 2; extPathFlood(tile, &startPoint, 0, epa); return (0); } /* * ---------------------------------------------------------------------------- * * extPathFlood -- * * Flood from a tile to all its connected and unprocessed neighbors. * As we flood to each neighbor, we estimate a delay for the increment * from the point 'p' (usually on the center of 'tile', and at distance * 'distance' from the starting point) to the central point of the new * tile. Contacts are processed in a similar way, except the point 'p' * doesn't change. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void extPathFlood(tile, p, distance, epa) Tile *tile; /* Tile whose neighbors we are to visit */ Point *p; /* Usually at center of 'tile' */ int distance; /* Distance to 'p' */ struct extPathArg *epa; /* Update epa_min and epa_max when we reach * the destination epa_lab2. */ { TileType type = TiGetType(tile); Label *lab2 = epa->epa_lab2; int pNum, newdistance; PlaneMask pMask; Tile *tp; char mesg[512]; Point p2; Rect r; /* Mark the tile as being visited */ tile->ti_client = MARKED; /* * Are we at the destination yet? * If so, compute final delay and just return. * Update the min and max delay if necessary. * Don't propagate to neighboring tiles since doing so * can only lengthen the path. */ TITORECT(tile, &r); if (DebugIsSet(extDebugID, extDebLength)) { ShowRect(extPathDef, &r, STYLE_SOLIDHIGHLIGHTS); TxMore("Visit tile"); ShowRect(extPathDef, &r, STYLE_ERASEHIGHLIGHTS); } if (GEO_TOUCH(&r, &lab2->lab_rect) && DBConnectsTo(type, lab2->lab_type)) { /* Find distance to closest point in 'lab2->lab_rect' to 'p' */ p2 = *p; GeoClipPoint(&p2, &lab2->lab_rect); newdistance = extPathTileDist(p, &p2, tile, distance); if (DebugIsSet(extDebugID, extDebLength)) { (void) sprintf(mesg, "Reached destination, dist = %d", newdistance); TxMore(mesg); } /* Update min and max distance */ if (newdistance < epa->epa_min) epa->epa_min = newdistance; if (newdistance > epa->epa_max) epa->epa_max = newdistance; return; } /* Walk around the perimeter to connected tiles */ /* TOP */ for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp)) if (tp->ti_client != MARKED && DBConnectsTo(TiGetType(tp), type)) extPathFloodTile(tile, p, distance, tp, epa); /* RIGHT */ for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp)) if (tp->ti_client != MARKED && DBConnectsTo(TiGetType(tp), type)) extPathFloodTile(tile, p, distance, tp, epa); /* BOTTOM */ for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp = TR(tp)) if (tp->ti_client != MARKED && DBConnectsTo(TiGetType(tp), type)) extPathFloodTile(tile, p, distance, tp, epa); /* LEFT */ for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp)) if (tp->ti_client != MARKED && DBConnectsTo(TiGetType(tp), type)) extPathFloodTile(tile, p, distance, tp, epa); /* Try connections to other planes */ if (DBIsContact(type)) { int saveplane = epa->epa_pNum; PlaneMask pMask = DBConnPlanes[type]; pMask &= ~(PlaneNumToMaskBit(epa->epa_pNum)); for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) if (PlaneMaskHasPlane(pMask, pNum)) { Plane *plane = extPathDef->cd_planes[pNum]; /* Find the point on the new plane */ tp = plane->pl_hint; GOTOPOINT(tp, &tile->ti_ll); plane->pl_hint = tp; /* If not yet visited, process tp */ if (tp->ti_client == (ClientData) CLIENTDEFAULT && DBConnectsTo(type, TiGetType(tp))) { epa->epa_pNum = pNum; extPathFlood(tp, p, distance, epa); } } epa->epa_pNum = saveplane; } /* * The hairiest case is when this type connects to stuff on * other planes, but isn't itself connected as a contact. * For example, a CMOS pwell connects to diffusion of the * same doping (p substrate diff). In a case like this, * we need to search the entire AREA of the tile plus a * 1-lambda halo to find everything it overlaps or touches * on the other plane. */ if (pMask = DBAllConnPlanes[type]) { int saveplane = epa->epa_pNum; struct extPathFloodArg epfa; Rect biggerArea; TITORECT(tile, &epfa.epfa_srcArea); GEO_EXPAND(&epfa.epfa_srcArea, 1, &biggerArea); epfa.epfa_distance = distance; epfa.epfa_epa = epa; epfa.epfa_srcPoint = p; epfa.epfa_srcTile = tile; for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) if (pNum != epa->epa_pNum && PlaneMaskHasPlane(pMask, pNum)) { epa->epa_pNum = pNum; (void) DBSrPaintClient((Tile *) NULL, extPathDef->cd_planes[pNum], &biggerArea, &DBConnectTbl[type], (ClientData) CLIENTDEFAULT, extPathFloodFunc, (ClientData) &epfa); } epa->epa_pNum = saveplane; } } int extPathFloodFunc(dstTile, epfa) Tile *dstTile; struct extPathFloodArg *epfa; { Rect srcRect, dstRect; Point dstPoint, *p; int dstDist; /* * If dstTile overlaps epfa->epfa_srcArea, use epfa->epfa_srcPoint; * otherwise, pick a point along the boundary of epfa->epfa_srcArea * that's in common with dstTile. */ dstDist = epfa->epfa_distance; srcRect = epfa->epfa_srcArea; TITORECT(dstTile, &dstRect); if (GEO_OVERLAP(&srcRect, &dstRect)) p = epfa->epfa_srcPoint; else { /* Pick a point along the boundary */ GEOCLIP(&srcRect, &dstRect); dstPoint.p_x = (srcRect.r_xbot + srcRect.r_xtop) / 2; dstPoint.p_y = (srcRect.r_ybot + srcRect.r_ytop) / 2; /* Compute the incremental delay */ dstDist = extPathTileDist(epfa->epfa_srcPoint, &dstPoint, epfa->epfa_srcTile, dstDist); p = &dstPoint; } /* Recurse */ extPathFlood(dstTile, p, dstDist, epfa->epfa_epa); return 0; } /* * ---------------------------------------------------------------------------- * * extPathFloodTile -- * * Propagate from a tile 'srcTile' to one of its neighbors 'dstTile'. * The delay 'srcDelay' has been computed to 'srcPoint' (which is * contained within 'srcTile' or is on its border). We pick the * midpoint of the overlap between 'srcTile' and 'dstTile' as the * point to which the next cost is computed, and then recursively * call extPathFlood() with dstTile and the new point. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void extPathFloodTile(srcTile, srcPoint, srcDist, dstTile, epa) Tile *srcTile; /* Tile through which we're propagating */ Point *srcPoint; /* Point inside or on srcTile */ int srcDist; /* Distance to srcPoint so far */ Tile *dstTile; /* Tile on border of srcTile */ struct extPathArg *epa; { Rect srcRect, dstRect; Point dstPoint; int dstDist; /* * Pick the central point along the boundary of srcTile and dstTile * for purposes of computing costs. */ TITORECT(srcTile, &srcRect); TITORECT(dstTile, &dstRect); GEOCLIP(&srcRect, &dstRect); dstPoint.p_x = (srcRect.r_xbot + srcRect.r_xtop) / 2; dstPoint.p_y = (srcRect.r_ybot + srcRect.r_ytop) / 2; /* Compute the incremental delay */ dstDist = extPathTileDist(srcPoint, &dstPoint, srcTile, srcDist); /* Recurse */ extPathFlood(dstTile, &dstPoint, dstDist, epa); } /* * ---------------------------------------------------------------------------- * * extPathTileDist -- * * Update delay information to include the costs of passing through * 'tile' from p1 to p2. The old distance is 'oldDist'. We account * for the distance from p1 to p2 through the tile 'tile'. * * Results: * Returns the distance described above. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ int extPathTileDist(p1, p2, tile, oldDist) Point *p1, *p2; Tile *tile; int oldDist; { int newDist; newDist = oldDist + ABSDIFF(p1->p_x, p2->p_x) + ABSDIFF(p1->p_y, p2->p_y); /* * If both points were on the same side, include a little extra * for passing through the middle of the tile (which wasn't counted). */ if (p1->p_x == p2->p_x) { if (p1->p_x == LEFT(tile) || p1->p_x == RIGHT(tile)) newDist += RIGHT(tile) - LEFT(tile); } if (p1->p_y == p2->p_y) { if (p1->p_y == BOTTOM(tile) || p1->p_y == TOP(tile)) newDist += TOP(tile) - BOTTOM(tile); } return (newDist); } magic-8.0.210/extract/ExtYank.c0000644000175000001440000001741511020566166014666 0ustar timusers/* * ExtYank.c -- * * Circuit extraction. * Hierarchical yanking of paint and labels. * * ********************************************************************* * * 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/extract/ExtYank.c,v 1.2 2008/06/01 18:37:42 tim Exp $"; #endif /* not lint */ #include #include #include #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 "utils/malloc.h" #include "textio/textio.h" #include "debug/debug.h" #include "utils/styles.h" #include "extract/extract.h" #include "extract/extractInt.h" Rect extSubcellArea; /* Area of currently processed subcell, clipped * to area of interaction, in parent coords. */ /* Forward declarations of filter functions */ int extHierYankFunc(); int extHierLabelFunc(); /* * ---------------------------------------------------------------------------- * * extHierCopyLabels -- * * Copy the label list from sourceDef to targetDef, prepending * it to any labels already in targetDef. Does not change * sourceDef's label list. * * Labels are copied in order, so the first label on sourceDef's * list becomes the first label on targetDef's list. THIS IS * CRITICAL TO INSURE THAT HIERARCHICAL ADJUSTMENTS CAN BE MADE * PROPERLY; SEE extSubtreeAdjustInit() FOR AN EXPLANATION. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void extHierCopyLabels(sourceDef, targetDef) CellDef *sourceDef, *targetDef; { Label *lab, *newlab, *firstLab, *lastLab; unsigned n; firstLab = lastLab = (Label *) NULL; for (lab = sourceDef->cd_labels; lab; lab = lab->lab_next) { n = sizeof (Label) + strlen(lab->lab_text) - sizeof lab->lab_text + 1; newlab = (Label *) mallocMagic((unsigned) n); bcopy((char *) lab, (char *) newlab, (int) n); if (lastLab == NULL) lastLab = firstLab = newlab; else lastLab->lab_next = newlab, lastLab = newlab; } if (lastLab) { lastLab->lab_next = targetDef->cd_labels; targetDef->cd_labels = firstLab; } } /* * ---------------------------------------------------------------------------- * * extHierFreeLabels -- * * Free all the labels from 'def'. * Leaves the label lis of 'def' pointing to NULL. * * This procedure exists mainly so we can trace the freeing * of labels for debugging. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void extHierFreeLabels(def) CellDef *def; { Label *lab; for (lab = def->cd_labels; lab; lab = lab->lab_next) freeMagic((char *) lab); def->cd_labels = (Label *) NULL; } /* * ---------------------------------------------------------------------------- * * extHierYankFunc -- * * Filter function normally called by DBArraySr to yank hierarchically the * paint and labels from 'use'. Called for each array element. Also called * during array extraction. * * Expects hy->hy_area to be the area, in use->cu_parent coordinates, * to be yanked. What we yank will be transformed to parent coordinates * and placed in the cell hy->hy_target. If hy->hy_prefix is TRUE, we * will prepend all the labels we yank with the use id of this array * element; otherwise, the labels have no prefix. * * WARNING: * Only node-name labels are yanked; attributes are not. * The hierarchical extraction code depends on this fact. * * Results: * Returns 0 to cause DBArraySr to keep going. * * Side effects: * Adds paint and new labels to 'hy->hy_target'. * * ---------------------------------------------------------------------------- */ int extHierYankFunc(use, trans, x, y, hy) CellUse *use; /* Use that is the root of the subtree being yanked */ Transform *trans; /* Transform from coordinates of use->cu_def to those * in use->cu_parent, for the array element (x, y). */ int x, y; /* Indices of this array element */ HierYank *hy; /* See comments in procedure header */ { char labelBuf[4096]; TerminalPath tpath; SearchContext scx; Transform tinv; /* * Want scx.scx_area to be the area in coordinates of use->cu_def * but hy->hy_area is in coordinates of use->cu_parent. */ GEOINVERTTRANS(trans, &tinv); GEOTRANSRECT(&tinv, hy->hy_area, &scx.scx_area); GEOCLIP(&scx.scx_area, &use->cu_def->cd_bbox); scx.scx_use = use; scx.scx_trans = *trans; scx.scx_x = x; scx.scx_y = y; /* Yank the paint */ // if (!DBIsSubcircuit(use->cu_def)) DBCellCopyAllPaint(&scx, &DBAllButSpaceBits, 0, hy->hy_target); /* Yank the labels */ tpath.tp_next = tpath.tp_first = labelBuf; tpath.tp_last = &labelBuf[sizeof labelBuf - 2]; if (hy->hy_prefix) { tpath.tp_next = DBPrintUseId(&scx, labelBuf, sizeof labelBuf - 3, FALSE); *tpath.tp_next++ = '/'; } *tpath.tp_next = '\0'; (void) DBTreeSrLabels(&scx, &DBAllButSpaceBits, 0, &tpath, TF_LABEL_ATTACH, extHierLabelFunc, (ClientData) hy->hy_target->cu_def); return (0); } int extHierLabelFunc(scx, label, tpath, targetDef) SearchContext *scx; Label *label; TerminalPath *tpath; CellDef *targetDef; { char *srcp, *dstp; Label *newlab; int len; /* Reject if the label falls over space */ if (label->lab_type == TT_SPACE) return (0); /* Reject if not a node label */ if (!extLabType(label->lab_text, LABTYPE_NAME)) return (0); /* Determine size of new label with hierarchical name */ for (srcp = label->lab_text; *srcp++; ) /* Nothing */; len = srcp - label->lab_text; for (srcp = tpath->tp_first; *srcp++; ) /* Nothing */; len += srcp - tpath->tp_first + 1; /* Allocate new label at correct location */ newlab = (Label *) mallocMagic((unsigned) (sizeof (Label) + len - 4)); GeoTransRect(&scx->scx_trans, &label->lab_rect, &newlab->lab_rect); newlab->lab_just = GeoTransPos(&scx->scx_trans, label->lab_just); newlab->lab_type = label->lab_type; newlab->lab_flags = label->lab_flags; dstp = newlab->lab_text; for (srcp = tpath->tp_first; *dstp++ = *srcp++; ) /* Nothing */; for (--dstp, srcp = label->lab_text; *dstp++ = *srcp++; ) /* Nothing */; newlab->lab_next = targetDef->cd_labels; targetDef->cd_labels = newlab; /* Add paint inside label if this is a subcircuit */ /* Caveat: If label has zero area, it will be extended by 1 unit */ // if (label->lab_flags & PORT_DIR_MASK) // { // int pNum; // // /* Is extending the label area valid in all cases? */ // if (newlab->lab_rect.r_xbot == newlab->lab_rect.r_xtop) // newlab->lab_rect.r_xtop++; // if (newlab->lab_rect.r_ybot == newlab->lab_rect.r_ytop) // newlab->lab_rect.r_ytop++; // // pNum = DBPlane(newlab->lab_type); // DBPaintPlane(targetDef->cd_planes[pNum], &newlab->lab_rect, // DBStdPaintTbl(newlab->lab_type, pNum), // (PaintUndoInfo *) NULL); // } return (0); } magic-8.0.210/extract/ExtTech.c0000664000175000001440000024127412522433012014642 0ustar timusers/* * ExtTech.c -- * * Circuit extraction. * Code to read and process the sections of a technology file * that are specific to circuit extraction. * * ********************************************************************* * * 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 sccsid[] = "@(#)ExtTech.c 4.8 MAGIC (Berkeley) 10/26/85"; #endif /* not lint */ #include #include /* for strtod() */ #include #include #include /* for isspace() */ #include "tcltk/tclmagic.h" #include "utils/magic.h" #include "utils/utils.h" #include "utils/geometry.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 "utils/tech.h" #include "debug/debug.h" #include "extract/extract.h" #include "extract/extractInt.h" #include "cif/CIFint.h" /* Whether we are converting units from microns to lambda */ bool doConvert; /* Current extraction style */ ExtStyle *ExtCurStyle = NULL; /* List of all styles */ ExtKeep *ExtAllStyles = NULL; /* Forward declarations */ void extTechFinalStyle(); void ExtLoadStyle(); void ExtTechScale(int, int); /* * Table used for parsing the extract section of a .tech file * Each line in the extract section is of a type determined by * its first keyword. There is one entry in the following table * for each such keyword. */ typedef enum { AREAC, CONTACT, CSCALE, DEFAULTAREACAP, DEFAULTOVERLAP, DEFAULTPERIMETER, DEFAULTSIDEOVERLAP, DEFAULTSIDEWALL, DEVICE, FET, FETRESIST, HEIGHT, LAMBDA, OVERC, PERIMC, PLANEORDER, NOPLANEORDER, RESIST, RSCALE, SIDEHALO, SIDEOVERLAP, SIDEWALL, STEP, STYLE, UNITS, VARIANT } Key; typedef struct { char *k_name; int k_key; int k_minargs; int k_maxargs; char *k_usage; } keydesc; static keydesc keyTable[] = { "areacap", AREAC, 3, 3, "types capacitance", "contact", CONTACT, 3, 6, "type resistance", "cscale", CSCALE, 2, 2, "capacitance-scalefactor", "defaultareacap", DEFAULTAREACAP, 4, 5, "types plane capacitance", "defaultoverlap", DEFAULTOVERLAP, 6, 6, "types plane otertypes otherplane capacitance", "defaultperimeter", DEFAULTPERIMETER, 4, 5, "types plane capacitance", "defaultsideoverlap", DEFAULTSIDEOVERLAP, 6, 6, "types plane othertypes otherplane capacitance", "defaultsidewall", DEFAULTSIDEWALL, 4, 4, "types plane capacitance", "device", DEVICE, 4, 10, "device dev-type types options...", "fet", FET, 8, 9, "types terminal-types min-#-terminals name [subs-types] subs-node gscap gate-chan-cap", "fetresist", FETRESIST, 4, 4, "type region ohms-per-square", "height", HEIGHT, 4, 4, "type height-above-subtrate thickness", "lambda", LAMBDA, 2, 2, "units-per-lambda", "overlap", OVERC, 4, 5, "toptypes bottomtypes capacitance [shieldtypes]", "perimc", PERIMC, 4, 4, "intypes outtypes capacitance", "planeorder", PLANEORDER, 3, 3, "plane index", "noplaneordering", NOPLANEORDER, 1, 1, "(no arguments needed)", "resist", RESIST, 3, 4, "types resistance", "rscale", RSCALE, 2, 2, "resistance-scalefactor", "sidehalo", SIDEHALO, 2, 2, "halo", "sideoverlap", SIDEOVERLAP, 5, 6, "intypes outtypes ovtypes capacitance [shieldtypes]", "sidewall", SIDEWALL, 6, 6, "intypes outtypes neartypes fartypes capacitance", "step", STEP, 2, 2, "size", "style", STYLE, 2, 4, "stylename", "units", UNITS, 2, 2, "lambda|microns", "variants", VARIANT, 2, 2, "style,...", 0 }; /* * Table used for parsing the "device" keyword types * * (Note: "10" for max types in subcircuit is arbitrary---the parser * ignores max types for DEV_SUBCKT and DEV_MSUBCKT). */ /* types are enumerated in extract.h */ static keydesc devTable[] = { "mosfet", DEV_MOSFET, 5, 10, "name gate-types src-types [drn-types] sub-types|None sub-node [gscap gccap]", "bjt", DEV_BJT, 5, 5, "name base-types emitter-types collector-types", "capacitor", DEV_CAP, 5, 8, "name top-types bottom-types [sub-types|None sub-node] [perimcap] areacap", "resistor", DEV_RES, 4, 6, "name|None res-types terminal-types [sub-types|None sub-node]", "diode", DEV_DIODE, 4, 6, "name pos-types neg-types [sub-types|None sub-node]", "subcircuit", DEV_SUBCKT, 3, 11, "name dev-types [N] [term1-types ... termN-types [sub-types|None sub-node]] [options]", "rsubcircuit", DEV_RSUBCKT, 4, 7, "name dev-types terminal-types [sub-types|None sub-node] [options]", "msubcircuit", DEV_MSUBCKT, 4, 11, "name dev-types [N] [term1-types ... termN-types [sub-types|None sub-node]] [options]", 0 }; #ifdef MAGIC_WRAPPER /* * ---------------------------------------------------------------------------- * * ExtCompareStyle -- * * This routine is designed to work with embedded exttosim and * exttospice. It determines whether the current extract style * matches the string (picked up from the .ext file). If so, it * returns TRUE. If not, it checks whether the style exists in * the list of known files for this technology. If so, it loads * the correct style and returns TRUE. If not, it returns FALSE. * * ---------------------------------------------------------------------------- */ bool ExtCompareStyle(stylename) char *stylename; { ExtKeep *style; if (!strcmp(stylename, ExtCurStyle->exts_name)) return TRUE; else { for (style = ExtAllStyles; style != NULL; style = style->exts_next) { if (!strcmp(stylename, style->exts_name)) { ExtLoadStyle(stylename); return TRUE; } } } return FALSE; } /* * ---------------------------------------------------------------------------- * * ExtGetDevInfo -- * * This routine is designed to work with the embedded exttosim and * exttospice commands under the Tcl-based magic, such that all * device information needed by these commands can be picked up * from the current extraction style (as it should!). This * really should be set up when the extract file is read, which is * why the routine is here, although this is not a very efficient * way to do it (but it needs to be this way to keep backward * compatibility with the non-Tcl, standalone programs ext2sim and * ext2spice). * * Note that finding the device by index ("idx") is horribly * inefficient, but keeps the netlist generator separated from * the extractor. Some of this code is seriously schizophrenic, * and should not be investigated too closely. * * Results: * Return FALSE if no device corresponds to index "idx". TRUE * otherwise. * * Side Effects: * Fills values in the argument list. * ---------------------------------------------------------------------------- */ bool ExtGetDevInfo(idx, devnameptr, sd_rclassptr, sub_rclassptr, subnameptr) int idx; char **devnameptr; short *sd_rclassptr; /* First SD type only---needs to be updated! */ short *sub_rclassptr; char **subnameptr; { TileType t; TileTypeBitMask *rmask, *tmask; int n, i = 0, j; bool repeat; char *locdname; char **uniquenamelist = (char **)mallocMagic(DBNumTypes * sizeof(char *)); for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) { locdname = ExtCurStyle->exts_transName[t]; if (locdname != NULL) { repeat = FALSE; for (j = 0; j < i; j++) if (!strcmp(uniquenamelist[j], locdname)) { repeat = TRUE; break; } if (repeat == FALSE) { if (i == idx) break; uniquenamelist[i] = locdname; i++; } } } if (t == DBNumTypes) return FALSE; *devnameptr = locdname; *subnameptr = ExtCurStyle->exts_transSubstrateName[t]; tmask = &ExtCurStyle->exts_transSDTypes[t][0]; *sd_rclassptr = (short)(-1); /* NO_RESCLASS */ for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) { rmask = &ExtCurStyle->exts_typesByResistClass[n]; if (TTMaskIntersect(rmask, tmask)) { *sd_rclassptr = (short)n; break; } } tmask = &ExtCurStyle->exts_transSubstrateTypes[t]; *sub_rclassptr = (short)(-1); /* NO_RESCLASS */ for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) { rmask = &ExtCurStyle->exts_typesByResistClass[n]; if (TTMaskIntersect(rmask, tmask)) { *sub_rclassptr = (short)(n); break; } } freeMagic(uniquenamelist); return TRUE; } #endif /* MAGIC_WRAPPER */ #ifdef THREE_D /* * ---------------------------------------------------------------------------- * * ExtGetZAxis -- * * Get the height and thickness parameters for a layer (used by the * graphics module which does not have access to internal variables * in the extract section). * * Results: * None * * Side Effects: * Fills values "height" and "thick" in argument list. * * ---------------------------------------------------------------------------- */ void ExtGetZAxis(tile, height, thick) Tile *tile; float *height, *thick; { TileType ttype; if (ExtCurStyle == NULL) return; ttype = TiGetLeftType(tile); /* Ignore non-Manhattan for now */ /* Note that w_scale is multiplied by SUBPIXEL to get fixed-point accuracy. */ /* However, we downshift by only 9 (divide by 512) so that heights are */ /* exaggerated in the layout by a factor of 8 (height exaggeration is */ /* standard practice for VLSI cross-sections). */ *height = ExtCurStyle->exts_height[ttype]; *thick = ExtCurStyle->exts_thick[ttype]; } #endif /* THREE_D */ /* * ---------------------------------------------------------------------------- * * ExtPrintStyle -- * * Print the available and/or current extraction styles. * * Results: * None. * * Side effects: * Output. * * ---------------------------------------------------------------------------- */ void ExtPrintStyle(dolist, doforall, docurrent) bool dolist; bool doforall; bool docurrent; { ExtKeep *style; if (docurrent) { if (ExtCurStyle == NULL) TxError("Error: No style is set\n"); else { if (!dolist) TxPrintf("The current style is \""); #ifdef MAGIC_WRAPPER if (dolist) Tcl_SetResult(magicinterp, ExtCurStyle->exts_name, NULL); else #endif TxPrintf("%s", ExtCurStyle->exts_name); if (!dolist) TxPrintf("\".\n"); } } if (doforall) { if (!dolist) TxPrintf("The extraction styles are: "); for (style = ExtAllStyles; style; style = style->exts_next) { if (dolist) { #ifdef MAGIC_WRAPPER Tcl_AppendElement(magicinterp, style->exts_name); #else if (style != ExtAllStyles) TxPrintf(" "); TxPrintf("%s", style->exts_name); #endif } else { if (style != ExtAllStyles) TxPrintf(", "); TxPrintf("%s", style->exts_name); } } if (!dolist) TxPrintf(".\n"); } } /* * ---------------------------------------------------------------------------- * * ExtSetStyle -- * * Set the current extraction style to 'name', or print * the available and current styles if 'name' is NULL. * * Results: * None. * * Side effects: * Just told you. * * ---------------------------------------------------------------------------- */ void ExtSetStyle(name) char *name; { ExtKeep *style, *match; int length; if (name == NULL) return; match = NULL; length = strlen(name); for (style = ExtAllStyles; style; style = style->exts_next) { if (strncmp(name, style->exts_name, length) == 0) { if (match != NULL) { TxError("Extraction style \"%s\" is ambiguous.\n", name); ExtPrintStyle(FALSE, TRUE, TRUE); return; } match = style; } } if (match != NULL) { ExtLoadStyle(match->exts_name); TxPrintf("Extraction style is now \"%s\"\n", name); return; } TxError("\"%s\" is not one of the extraction styles Magic knows.\n", name); ExtPrintStyle(FALSE, TRUE, TRUE); } /* * ---------------------------------------------------------------------------- * * extTechStyleAlloc -- * * Allocate memory for a new extract style structure. * * ---------------------------------------------------------------------------- */ ExtStyle * extTechStyleAlloc() { ExtStyle *style; TileType r; style = (ExtStyle *) mallocMagic(sizeof (ExtStyle)); /* Make sure that the memory for character strings is NULL, */ /* because we want the Init section to free memory if has */ /* been previously allocated. */ for (r = 0; r < NT; r++) { style->exts_transSubstrateName[r] = (char *) NULL; style->exts_transName[r] = (char *) NULL; style->exts_transSDTypes[r] = (TileTypeBitMask *) NULL; style->exts_deviceParams[r] = (ParamList *) NULL; style->exts_deviceClass[r] = (char) 0; style->exts_transResist[r].ht_table = (HashEntry **) NULL; } return style; } /* * ---------------------------------------------------------------------------- * * extTechStyleInit -- * * Fill in the extract style structure with initial values. * * ---------------------------------------------------------------------------- */ void extTechStyleInit(style) ExtStyle *style; { TileType r, s; style->exts_name = NULL; style->exts_status = TECH_NOT_LOADED; style->exts_sidePlanes = style->exts_overlapPlanes = 0; TTMaskZero(&style->exts_transMask); for (r = 0; r < NP; r++) { TTMaskZero(&style->exts_sideTypes[r]); TTMaskZero(&style->exts_overlapTypes[r]); style->exts_planeOrder[r] = -1; } for (r = 0; r < NT; r++) { TTMaskZero(&style->exts_nodeConn[r]); TTMaskZero(&style->exts_resistConn[r]); TTMaskZero(&style->exts_transConn[r]); style->exts_allConn[r] = DBAllTypeBits; style->exts_sheetResist[r] = 0; style->exts_cornerChop[r] = 1.0; style->exts_viaResist[r] = 0; style->exts_height[r] = 0.0; style->exts_thick[r] = 0.0; style->exts_areaCap[r] = (CapValue) 0; style->exts_overlapOtherPlanes[r] = 0; TTMaskZero(&style->exts_overlapOtherTypes[r]); TTMaskZero(&style->exts_sideEdges[r]); for (s = 0; s < NT; s++) { TTMaskZero(&style->exts_sideCoupleOtherEdges[r][s]); TTMaskZero(&style->exts_sideOverlapOtherTypes[r][s]); style->exts_sideOverlapOtherPlanes[r][s] = 0; style->exts_sideCoupleCap[r][s] = (EdgeCap *) NULL; style->exts_sideOverlapCap[r][s] = (EdgeCap *) NULL; style->exts_perimCap[r][s] = (CapValue) 0; style->exts_overlapCap[r][s] = (CapValue) 0; TTMaskZero(&style->exts_overlapShieldTypes[r][s]); style->exts_overlapShieldPlanes[r][s] = 0; style->exts_sideOverlapShieldPlanes[r][s] = 0; } TTMaskZero(&style->exts_perimCapMask[r]); #ifdef ARIEL TTMaskZero(&style->exts_subsTransistorTypes[r]); #endif if (style->exts_transSDTypes[r] != NULL) freeMagic(style->exts_transSDTypes[r]); style->exts_transSDTypes[r] = NULL; style->exts_transSDCount[r] = 0; style->exts_transGateCap[r] = (CapValue) 0; style->exts_transSDCap[r] = (CapValue) 0; if (style->exts_transSubstrateName[r] != (char *) NULL) { freeMagic(style->exts_transSubstrateName[r]); style->exts_transSubstrateName[r] = (char *) NULL; } if (style->exts_transName[r] != (char *) NULL) { freeMagic(style->exts_transName[r]); style->exts_transName[r] = (char *) NULL; } while (style->exts_deviceParams[r] != (ParamList *) NULL) { /* Parameter lists are shared. Only free the last one! */ if (style->exts_deviceParams[r]->pl_count > 1) { style->exts_deviceParams[r]->pl_count--; style->exts_deviceParams[r] = (ParamList *)NULL; } else { freeMagic(style->exts_deviceParams[r]->pl_name); freeMagic(style->exts_deviceParams[r]); style->exts_deviceParams[r] = style->exts_deviceParams[r]->pl_next; } } style->exts_deviceClass[r] = (char)0; if (style->exts_transResist[r].ht_table != (HashEntry **) NULL) HashKill(&style->exts_transResist[r]); HashInit(&style->exts_transResist[r], 8, HT_STRINGKEYS); style->exts_linearResist[r] = 0; } style->exts_sideCoupleHalo = 0; style->exts_stepSize = 100; style->exts_unitsPerLambda = 100.0; style->exts_resistScale = 1000; style->exts_capScale = 1000; style->exts_numResistClasses = 0; style->exts_planeOrderStatus = needPlaneOrder ; for (r = 0; r < DBNumTypes; r++) { style->exts_resistByResistClass[r] = 0; TTMaskZero(&style->exts_typesByResistClass[r]); style->exts_typesResistChanged[r] = DBAllButSpaceAndDRCBits; TTMaskSetType(&style->exts_typesResistChanged[r], TT_SPACE); style->exts_typeToResistClass[r] = -1; } doConvert = FALSE; } /* * ---------------------------------------------------------------------------- * * extTechStyleNew -- * * Allocate a new style with zeroed technology variables. * * Results: * Allocates a new ExtStyle, initializes it, and returns it. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ ExtStyle * extTechStyleNew() { ExtStyle *style; style = extTechStyleAlloc(); extTechStyleInit(style); return style; } /* * ---------------------------------------------------------------------------- * * aToCap -- * * Utility procedure for reading capacitance values. * * Returns: * A value of type CapValue. * * Side effects: * none. * ---------------------------------------------------------------------------- */ CapValue aToCap(str) char *str; { CapValue capVal; if (sscanf(str, "%lf", &capVal) != 1) { capVal = (CapValue) 0; TechError("Capacitance value %s must be a number\n", str); } return capVal; } /* * ---------------------------------------------------------------------------- * * ExtLoadStyle -- * * Re-read the technology file to load the specified technology extraction * style into structure ExtCurStyle. This is much more memory-efficient than * keeping a separate (and huge!) ExtStyle structure for each extraction style. * It incurs a complete reading of the tech file on startup and every time the * extraction style is changed, but we can assume that this does not happen * often. The first style in the technology file is assumed to be default, so * that re-reading the tech file is not necessary on startup unless the default * extraction style is changed by a call to "extract style". * * ---------------------------------------------------------------------------- */ void ExtLoadStyle(stylename) char *stylename; { SectionID invext; extTechStyleInit(ExtCurStyle); /* Reinitialize and mark as not */ ExtCurStyle->exts_name = stylename; /* loaded. */ /* Invalidate the extract section, and reload it. */ /* The second parameter to TechSectionGetMask is NULL because */ /* no other tech client sections depend on the extract section. */ invext = TechSectionGetMask("extract", NULL); TechLoad(NULL, invext); /* extTechFinalStyle(ExtCurStyle); */ /* Taken care of by TechLoad() */ ExtTechScale(DBLambda[0], DBLambda[1]); } /* * ---------------------------------------------------------------------------- * * ExtTechInit -- * * Ensure that all memory allocated to the extract database has * been freed up. Called before loading a new technology. * * ---------------------------------------------------------------------------- */ void ExtTechInit() { ExtKeep *style; int r; /* Delete everything in ExtCurStyle */ if (ExtCurStyle != NULL) { extTechStyleInit(ExtCurStyle); /* Everything has been freed except the hash tables, which */ /* were just reinitialized by extTechStyleInit(). */ for (r = 0; r < NT; r++) { if (ExtCurStyle->exts_transResist[r].ht_table != (HashEntry **) NULL) HashKill(&ExtCurStyle->exts_transResist[r]); } ExtCurStyle = NULL; } /* Forget all the extract style names */ for (style = ExtAllStyles; style != NULL; style = style->exts_next) { freeMagic(style->exts_name); freeMagic(style); } ExtAllStyles = NULL; } /* * ---------------------------------------------------------------------------- * * ExtTechSimpleAreaCap -- * * Parse the techfile line for the "defaultareacap" keyword. * This is equivalent to the "areacap" line but also applies * to "overlap" of types on the second plane (if specified) and * all planes below it, with appropriate intervening types. * * Results: * None. * * Side Effects: * Adds information into the ExtCurStyle records. * * ---------------------------------------------------------------------------- */ void ExtTechSimpleAreaCap(argc, argv) int argc; char *argv[]; { TileType s, t; TileTypeBitMask types, subtypes, shields; CapValue capVal; int plane1, plane2, plane3, pnum1, pnum2, pnum3; PlaneMask pshield; if (ExtCurStyle->exts_planeOrderStatus != seenPlaneOrder) { TechError("Cannot parse area cap line without plane ordering!\n"); return; } DBTechNoisyNameMask(argv[1], &types); plane1 = DBTechNoisyNamePlane(argv[2]); TTMaskAndMask(&types, &DBPlaneTypes[plane1]); capVal = aToCap(argv[argc - 1]); if (argc == 4) plane2 = -1; else plane2 = DBTechNoisyNamePlane(argv[3]); /* Part 1: Area cap */ for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) if (TTMaskHasType(&types, t)) ExtCurStyle->exts_areaCap[t] = capVal; if (plane2 == -1) return; /* No "virtual" overlaps */ else if (plane1 == plane2) return; /* shouldn't happen */ pnum1 = ExtCurStyle->exts_planeOrder[plane1]; pnum2 = ExtCurStyle->exts_planeOrder[plane2]; /* Part 2: Overlap cap on types equivalent to substrate */ /* Find all types in or below plane2 (i.e., ~(space)/plane2) */ /* Shield types are everything in the planes between plane1 and plane2 */ TTMaskZero(&subtypes); TTMaskZero(&shields); pshield = 0; for (plane3 = PL_TECHDEPBASE; plane3 < DBNumPlanes; plane3++) { pnum3 = ExtCurStyle->exts_planeOrder[plane3]; if (pnum3 > pnum2 && pnum3 < pnum1) { TTMaskSetMask(&shields, &DBPlaneTypes[plane3]); pshield |= PlaneNumToMaskBit(plane3); } else if (pnum3 <= pnum2) { TTMaskSetMask(&subtypes, &DBPlaneTypes[plane3]); TTMaskClearType(&subtypes, TT_SPACE); } TTMaskClearType(&shields, TT_SPACE); } /* Now record all of the overlap capacitances */ for (s = TT_TECHDEPBASE; s < DBNumTypes; s++) { if (TTMaskHasType(&types, s)) { /* Contact overlap caps are determined from residues */ if (DBIsContact(s)) continue; for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) { if (!TTMaskHasType(&subtypes, t)) continue; if (s == t) continue; /* shouldn't happen */ if (ExtCurStyle->exts_overlapCap[s][t] > (CapValue) 0) continue; /* redundant overlap */ ExtCurStyle->exts_overlapCap[s][t] = capVal; ExtCurStyle->exts_overlapPlanes |= PlaneNumToMaskBit(plane1); ExtCurStyle->exts_overlapOtherPlanes[s] |= PlaneNumToMaskBit(plane2); TTMaskSetType(&ExtCurStyle->exts_overlapTypes[plane1], s); TTMaskSetType(&ExtCurStyle->exts_overlapOtherTypes[s], t); ExtCurStyle->exts_overlapShieldPlanes[s][t] = pshield; ExtCurStyle->exts_overlapShieldTypes[s][t] = shields; } } } } /* * ---------------------------------------------------------------------------- * * ExtTechSimplePerimCap -- * * Parse the techfile line for the "defaultperimeter" keyword. * This comprises both the "perimc" statement and the "sideoverlap" * statement for overlaps to types that are effectively substrate * (e.g., well, implant, marker layers, etc.) * * Results: * None. * * Side Effects: * Adds information into the ExtCurStyle records. * * ---------------------------------------------------------------------------- */ void ExtTechSimplePerimCap(argc, argv) int argc; char *argv[]; { TileType r, s, t; TileTypeBitMask types, nottypes, subtypes, shields; CapValue capVal; int plane1, plane2, plane3, pnum1, pnum2, pnum3; PlaneMask pshield; EdgeCap *cnew; if (ExtCurStyle->exts_planeOrderStatus != seenPlaneOrder) { TechError("Cannot parse area cap line without plane ordering!\n"); return; } DBTechNoisyNameMask(argv[1], &types); TTMaskCom2(¬types, &types); plane1 = DBTechNoisyNamePlane(argv[2]); TTMaskAndMask(&types, &DBPlaneTypes[plane1]); TTMaskAndMask(¬types, &DBPlaneTypes[plane1]); capVal = aToCap(argv[argc - 1]); if (argc == 4) plane2 = -1; else plane2 = DBTechNoisyNamePlane(argv[3]); /* Part 1: Perimeter cap */ for (s = TT_TECHDEPBASE; s < DBNumTypes; s++) for (t = 0; t < DBNumTypes; t++) if (TTMaskHasType(&types, s) && TTMaskHasType(¬types, t)) { ExtCurStyle->exts_perimCap[s][t] = capVal; TTMaskSetType(&ExtCurStyle->exts_perimCapMask[s], t); } if (plane2 == -1) return; /* No "virtual" overlaps */ else if (plane1 == plane2) return; /* shouldn't happen */ pnum1 = ExtCurStyle->exts_planeOrder[plane1]; pnum2 = ExtCurStyle->exts_planeOrder[plane2]; /* Part 2: Sidewall overlap cap on types equivalent to substrate */ /* Find all types in or below plane2 (i.e., ~(space)/plane2) */ /* Shield types are everything in the planes between plane1 and plane2 */ TTMaskZero(&subtypes); TTMaskZero(&shields); pshield = 0; for (plane3 = PL_TECHDEPBASE; plane3 < DBNumPlanes; plane3++) { pnum3 = ExtCurStyle->exts_planeOrder[plane3]; if (pnum3 > pnum2 && pnum3 < pnum1) { TTMaskSetMask(&shields, &DBPlaneTypes[plane3]); pshield |= PlaneNumToMaskBit(plane3); } else if (pnum3 <= pnum2) { TTMaskSetMask(&subtypes, &DBPlaneTypes[plane3]); } } TTMaskClearType(&shields, TT_SPACE); TTMaskClearType(&subtypes, TT_SPACE); /* Record all of the sideoverlap capacitances */ for (s = TT_TECHDEPBASE; s < DBNumTypes; s++) { /* Side overlap computed from residues */ if (DBIsContact(s)) continue; if (!TTMaskHasType(&types, s)) { ExtCurStyle->exts_sidePlanes |= PlaneNumToMaskBit(plane1); TTMaskSetType(&ExtCurStyle->exts_sideTypes[plane1], s); TTMaskSetMask(&ExtCurStyle->exts_sideEdges[s], ¬types); for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) { if (!TTMaskHasType(¬types, t)) continue; if (DBIsContact(t)) continue; TTMaskSetMask(&ExtCurStyle->exts_sideOverlapOtherTypes[s][t], &subtypes); ExtCurStyle->exts_sideOverlapOtherPlanes[s][t] |= PlaneNumToMaskBit(plane2); cnew = (EdgeCap *) mallocMagic((unsigned) (sizeof (EdgeCap))); cnew->ec_cap = capVal; cnew->ec_far = shields; /* Types that shield */ cnew->ec_near = subtypes; /* Types we create cap with */ cnew->ec_pmask = PlaneNumToMaskBit(plane2); cnew->ec_next = ExtCurStyle->exts_sideOverlapCap[s][t]; ExtCurStyle->exts_sideOverlapCap[s][t] = cnew; for (r = TT_TECHDEPBASE; r < DBNumTypes; r++) if (TTMaskHasType(&subtypes, r)) ExtCurStyle->exts_sideOverlapShieldPlanes[s][r] |= pshield; } } /* Reverse case (swap "types" and "subtypes") */ if (TTMaskHasType(&subtypes, s)) { ExtCurStyle->exts_sidePlanes |= PlaneNumToMaskBit(plane2); TTMaskSetType(&ExtCurStyle->exts_sideTypes[plane2], s); for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) { if (DBIsContact(t)) continue; TTMaskSetMask(&ExtCurStyle->exts_sideOverlapOtherTypes[s][t], &types); ExtCurStyle->exts_sideOverlapOtherPlanes[s][t] |= PlaneNumToMaskBit(plane1); cnew = (EdgeCap *) mallocMagic((unsigned) (sizeof (EdgeCap))); cnew->ec_cap = capVal; cnew->ec_far = shields; /* Types that shield */ cnew->ec_near = types; /* Types we create cap with */ cnew->ec_pmask = PlaneNumToMaskBit(plane1); cnew->ec_next = ExtCurStyle->exts_sideOverlapCap[s][t]; ExtCurStyle->exts_sideOverlapCap[s][t] = cnew; for (r = TT_TECHDEPBASE; r < DBNumTypes; r++) if (TTMaskHasType(&types, r)) ExtCurStyle->exts_sideOverlapShieldPlanes[s][r] |= pshield; } } } } /* * ---------------------------------------------------------------------------- * * ExtTechSimpleSidewallCap -- * * Parse the techfile line for the "defaultsidewall" keyword. * * Results: * None. * * Side Effects: * Adds information into the ExtCurStyle records. * * ---------------------------------------------------------------------------- */ void ExtTechSimpleSidewallCap(argv) char *argv[]; { /* Like ExtTechLine, but with near = types2 and far = types1 */ TileType s, t; TileTypeBitMask types1, types2; CapValue capVal; EdgeCap *cnew; int plane; DBTechNoisyNameMask(argv[1], &types1); plane = DBTechNoisyNamePlane(argv[2]); capVal = aToCap(argv[3]); TTMaskCom2(&types2, &types1); TTMaskAndMask(&types1, &DBPlaneTypes[plane]); TTMaskAndMask(&types2, &DBPlaneTypes[plane]); if (TTMaskHasType(&types1, TT_SPACE)) TechError("Can't have space on inside of edge [ignored]\n"); for (s = TT_TECHDEPBASE; s < DBNumTypes; s++) { if (TTMaskHasType(&types1, s)) { ExtCurStyle->exts_sidePlanes |= PlaneNumToMaskBit(DBPlane(s)); TTMaskSetType(&ExtCurStyle->exts_sideTypes[DBPlane(s)], s); TTMaskSetMask(&ExtCurStyle->exts_sideEdges[s], &types2); for (t = 0; t < DBNumTypes; t++) { if (!TTMaskHasType(&types2, t)) continue; TTMaskSetMask(&ExtCurStyle->exts_sideCoupleOtherEdges[s][t], &types1); cnew = (EdgeCap *) mallocMagic((unsigned) (sizeof (EdgeCap))); cnew->ec_cap = capVal; cnew->ec_near = types2; cnew->ec_far = types1; cnew->ec_next = ExtCurStyle->exts_sideCoupleCap[s][t]; cnew->ec_pmask = 0; ExtCurStyle->exts_sideCoupleCap[s][t] = cnew; } } } } /* * ---------------------------------------------------------------------------- * * ExtTechSimpleOverlapCap -- * * Parse the techfile line for the "defaultoverlap" keyword. * This is the same as the "overlap" statement excet that shield * types are determined automatically from the planeorder. * * Results: * None. * * Side Effects: * Adds information into the ExtCurStyle records. * * ---------------------------------------------------------------------------- */ void ExtTechSimpleOverlapCap(argv) char *argv[]; { TileType s, t; TileTypeBitMask types1, types2, shields; CapValue capVal; int plane1, plane2, plane3, pnum1, pnum2, pnum3; PlaneMask pshield; if (ExtCurStyle->exts_planeOrderStatus != seenPlaneOrder) { TechError("Cannot parse area cap line without plane ordering!\n"); return; } DBTechNoisyNameMask(argv[1], &types1); plane1 = DBTechNoisyNamePlane(argv[2]); TTMaskAndMask(&types1, &DBPlaneTypes[plane1]); DBTechNoisyNameMask(argv[3], &types2); plane2 = DBTechNoisyNamePlane(argv[4]); TTMaskAndMask(&types2, &DBPlaneTypes[plane2]); capVal = aToCap(argv[5]); pnum1 = ExtCurStyle->exts_planeOrder[plane1]; pnum2 = ExtCurStyle->exts_planeOrder[plane2]; /* Find all types in or below plane2 (i.e., ~(space)/plane2) */ /* Shield types are everything in the planes between plane1 and plane2 */ TTMaskZero(&shields); pshield = 0; for (plane3 = PL_TECHDEPBASE; plane3 < DBNumPlanes; plane3++) { pnum3 = ExtCurStyle->exts_planeOrder[plane3]; if (pnum3 > pnum2 && pnum3 < pnum1) { TTMaskSetMask(&shields, &DBPlaneTypes[plane3]); pshield |= PlaneNumToMaskBit(plane3); } } TTMaskClearType(&shields, TT_SPACE); /* Now record all of the overlap capacitances */ for (s = TT_TECHDEPBASE; s < DBNumTypes; s++) { if (TTMaskHasType(&types1, s)) { /* Contact overlap caps are determined from residues */ if (DBIsContact(s)) continue; for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) { if (!TTMaskHasType(&types2, t)) continue; if (DBIsContact(t)) continue; if (s == t) continue; /* shouldn't happen */ if (plane1 == plane2) continue; /* shouldn't happen */ if (ExtCurStyle->exts_overlapCap[s][t] > (CapValue) 0) continue; /* redundant overlap */ ExtCurStyle->exts_overlapCap[s][t] = capVal; ExtCurStyle->exts_overlapPlanes |= PlaneNumToMaskBit(plane1); ExtCurStyle->exts_overlapOtherPlanes[s] |= PlaneNumToMaskBit(plane2); TTMaskSetType(&ExtCurStyle->exts_overlapTypes[plane1], s); TTMaskSetType(&ExtCurStyle->exts_overlapOtherTypes[s], t); ExtCurStyle->exts_overlapShieldPlanes[s][t] = pshield; ExtCurStyle->exts_overlapShieldTypes[s][t] = shields; } } } } /* * ---------------------------------------------------------------------------- * * ExtTechSimpleSideOverlapCap -- * * Parse the techfile line for the "defaultareacap" keyword. * * Results: * None. * * Side Effects: * Adds information into the ExtCurStyle records. * * ---------------------------------------------------------------------------- */ void ExtTechSimpleSideOverlapCap(argv) char *argv[]; { TileType r, s, t; TileTypeBitMask types, nottypes, ov, notov, shields; CapValue capVal; int plane1, plane2, plane3, pnum1, pnum2, pnum3; PlaneMask pshield; EdgeCap *cnew; if (ExtCurStyle->exts_planeOrderStatus != seenPlaneOrder) { TechError("Cannot parse area cap line without plane ordering!\n"); return; } DBTechNoisyNameMask(argv[1], &types); plane1 = DBTechNoisyNamePlane(argv[2]); TTMaskCom2(¬types, &types); TTMaskAndMask(&types, &DBPlaneTypes[plane1]); TTMaskAndMask(¬types, &DBPlaneTypes[plane1]); DBTechNoisyNameMask(argv[3], &ov); plane2 = DBTechNoisyNamePlane(argv[4]); TTMaskCom2(¬ov, &ov); TTMaskAndMask(&ov, &DBPlaneTypes[plane2]); TTMaskAndMask(¬ov, &DBPlaneTypes[plane2]); capVal = aToCap(argv[5]); pnum1 = ExtCurStyle->exts_planeOrder[plane1]; pnum2 = ExtCurStyle->exts_planeOrder[plane2]; /* Find all types in or below plane2 (i.e., ~(space)/plane2) */ /* Shield planes are the ones between plane1 and plane2 */ TTMaskZero(&shields); pshield = 0; for (plane3 = PL_TECHDEPBASE; plane3 < DBNumPlanes; plane3++) { pnum3 = ExtCurStyle->exts_planeOrder[plane3]; if (pnum3 > pnum2 && pnum3 < pnum1) { TTMaskSetMask(&shields, &DBPlaneTypes[plane3]); pshield |= PlaneNumToMaskBit(plane3); } } TTMaskClearType(&shields, TT_SPACE); /* Now record all of the sideoverlap capacitances */ if (TTMaskHasType(&types, TT_SPACE) || TTMaskHasType(&ov, TT_SPACE)) { TechError("Overlap types can't contain space [ignored]\n"); return; } /* Record all of the sideoverlap capacitances */ for (s = TT_TECHDEPBASE; s < DBNumTypes; s++) { /* Side overlap computed from residues */ if (DBIsContact(s)) continue; if (TTMaskHasType(&types, s)) { ExtCurStyle->exts_sidePlanes |= PlaneNumToMaskBit(plane1); TTMaskSetType(&ExtCurStyle->exts_sideTypes[plane1], s); TTMaskSetMask(&ExtCurStyle->exts_sideEdges[s], ¬types); for (t = TT_SPACE; t < DBNumTypes; t++) { if (!TTMaskHasType(¬types, t)) continue; if (DBIsContact(t)) continue; TTMaskSetMask(&ExtCurStyle->exts_sideOverlapOtherTypes[s][t], &ov); ExtCurStyle->exts_sideOverlapOtherPlanes[s][t] |= PlaneNumToMaskBit(plane2); cnew = (EdgeCap *) mallocMagic((unsigned) (sizeof (EdgeCap))); cnew->ec_cap = capVal; cnew->ec_far = shields; /* Types that shield */ cnew->ec_near = ov; /* Types we create cap with */ cnew->ec_pmask = PlaneNumToMaskBit(plane2); cnew->ec_next = ExtCurStyle->exts_sideOverlapCap[s][t]; ExtCurStyle->exts_sideOverlapCap[s][t] = cnew; for (r = TT_TECHDEPBASE; r < DBNumTypes; r++) if (TTMaskHasType(&ov, r)) ExtCurStyle->exts_sideOverlapShieldPlanes[s][r] |= pshield; } } /* Reverse case (swap "types" and "ov") */ if (TTMaskHasType(&ov, s)) { ExtCurStyle->exts_sidePlanes |= PlaneNumToMaskBit(plane2); TTMaskSetType(&ExtCurStyle->exts_sideTypes[plane2], s); TTMaskSetMask(&ExtCurStyle->exts_sideEdges[s], ¬ov); for (t = TT_SPACE; t < DBNumTypes; t++) { if (!TTMaskHasType(¬ov, t)) continue; if (DBIsContact(t)) continue; TTMaskSetMask(&ExtCurStyle->exts_sideOverlapOtherTypes[s][t], &types); ExtCurStyle->exts_sideOverlapOtherPlanes[s][t] |= PlaneNumToMaskBit(plane1); cnew = (EdgeCap *) mallocMagic((unsigned) (sizeof (EdgeCap))); cnew->ec_cap = capVal; cnew->ec_far = shields; /* Types that shield */ cnew->ec_near = types; /* Types we create cap with */ cnew->ec_pmask = PlaneNumToMaskBit(plane1); cnew->ec_next = ExtCurStyle->exts_sideOverlapCap[s][t]; ExtCurStyle->exts_sideOverlapCap[s][t] = cnew; for (r = TT_TECHDEPBASE; r < DBNumTypes; r++) if (TTMaskHasType(&types, r)) ExtCurStyle->exts_sideOverlapShieldPlanes[s][r] |= pshield; } } } } /* * ---------------------------------------------------------------------------- * * ExtTechLine -- * * Process a line from the "extract" section of a technology file. * * Each line in the extract section of a technology begins * with a keyword that identifies the format of the rest of * the line. * * The following three kinds of lines are used to define the resistance * and parasitic capacitance to substrate of each tile type: * * resist types resistance * areacap types capacitance * perimcap inside outside capacitance * * where 'types', 'inside', and 'outside' are comma-separated lists * of tile types, 'resistance' is an integer giving the resistance * per square in milli-ohms, and 'capacitance' is an integer giving * capacitance (per square lambda for areacap, or per lambda perimeter * for perimcap) in attofarads. * * The perimeter (sidewall) capacitance depends both on the types * inside and outside the perimeter. For a given 'perimcap' line, * any segment of perimeter with a type in 'inside' inside the * perimeter and a type in 'outside' ontside the perimeter will * have the indicated capacitance. * * Both area and perimeter capacitance computed from the information * above apply between a given node and the substrate beneath it, as * determined by extSubstrate[]. * * Contact resistances are specified by: * * contact type minsize resistance * * where type is the type of contact tile, minsize is chosen so that contacts * that are integer multiples of minsize get an additional contact cut for each * increment of minsize, and resistance is in milliohms. * * +++ FOR NOW, CONSIDER ALL SUBSTRATE TO BE AT GROUND +++ * * Overlap coupling capacitance is specified by: * * overlap toptypes bottomtypes capacitance [shieldtypes] * * where 'toptypes' and 'bottomtypes' are comma-separated lists of tile types, * and 'capacitance' is an integer giving capacitance in attofarads per * square lambda of overlap. The sets 'toptypes' and 'bottomtypes' should * be disjoint. Also, the union of the planes of 'toptypes' should be disjoint * from the union of the planes of 'bottomtypes'. If 'shieldtypes' are * present, they should also be a comma-separated list of types, on * planes disjoint from those of either 'toptypes' or 'bottomtypes'. * * Whenever a tile of a type in 'toptypes' overlaps one of a type in * 'bottomtypes', we deduct the capacitance to substrate of the 'toptypes' * tile for the area of the overlap, and create an overlap capacitance * between the two nodes based on 'capacitance'. When material in * 'shieldtypes' appears over any of this overlap area, however, we * only deduct the substrate capacitance; we don't create an overlap * capacitor. * * Sidewall coupling capacitance is specified by: * * sidewall intypes outtypes neartypes fartypes capacitance * * where 'intypes', 'outtypes', 'neartypes', and 'fartypes' are all comma- * separated lists of types, and 'capacitance' is an integer giving capacitance * in attofarads. All of the tiles in all four lists should be on the same * plane. * * Whenever an edge of the form i|j is seen, where 'i' is in intypes and * 'j' is in outtypes, we search on the 'j' side for a distance of * ExtCurStyle->exts_sideCoupleHalo for edges with 'neartypes' on the * close side and 'fartypes' on the far side. We create a capacitance * equal to the length of overlap, times capacitance, divided by the * separation between the edges (poor approximation, but better than * none). * * Sidewall overlap coupling capacitance is specified by: * * sideoverlap intypes outtypes ovtypes capacitance * * where 'intypes', 'outtypes', and 'ovtypes' are comma-separated lists * of types, and 'capacitance' is an integer giving capacitance in attofarads * per lambda. Both intypes and outtypes should be in the same plane, and * ovtypes should be in a different plane from intypes and outtypes. * * The next kind of line describes transistors: * * fet types terminals min-#terminals names substrate gscap gccap * * where 'types' and 'terminals' are comma-separated lists of tile types. * The meaning is that each type listed in 'types' is a transistor, whose * source and drain connect to any of the types listed in 'terminals'. * These transistors must have exactly min-#terminals terminals, in addition * to the gate (whose connectivity is specified in the system-wide connectivity * table in the "connect" section of the .tech file). Currently gscap and * gccap are unused, but refer to the gate-source (or gate-drain) capacitance * and the gate-channel capacitance in units of attofarads per lambda and * attofarads per square lambda respectively. * * The resistances of transistors is specified by: * * fetresist type region ohms * * where type is a type of tile that is a fet, region is a string ("linear" * is treated specially), and ohms is the resistance per square of the fet * type while operating in "region". The values of fets in the "linear" * region are stored in a separate table. * * Results: * Returns TRUE normally, or FALSE if the line from the * technology file is so malformed that Magic should abort. * Currently, we always return TRUE. * * Side effects: * Initializes the per-technology variables that appear at the * beginning of this file. * * ---------------------------------------------------------------------------- */ #define MAXSD 6 /*ARGSUSED*/ bool ExtTechLine(sectionName, argc, argv) char *sectionName; int argc; char *argv[]; { int n, l, i, j, size, val, p1, p2, p3, nterm, iterm, class; PlaneMask pshield, pov; CapValue capVal, gscap, gccap; TileTypeBitMask types1, types2, termtypes[MAXSD]; TileTypeBitMask near, far, ov, shield, subsTypes; char *subsName, *transName, *cp, *endptr, *paramName; TileType s, t, r, o; keydesc *kp, *dv; bool isLinear; HashEntry *he; EdgeCap *cnew; ExtKeep *es, *newStyle; ParamList *subcktParams, *newParam; int refcnt; double dhalo; bool bad; if (argc < 1) { TechError("Each line must begin with a keyword\n"); return (TRUE); } n = LookupStruct(argv[0], (LookupTable *) keyTable, sizeof keyTable[0]); if (n < 0) { TechError("Illegal keyword. Legal keywords are:\n\t"); for (n = 0; keyTable[n].k_name; n++) TxError(" %s", keyTable[n].k_name); TxError("\n"); return (TRUE); } kp = &keyTable[n]; if (argc < kp->k_minargs) goto usage; /* Handle maxargs for DEVICE type separately */ if ((argc > kp->k_maxargs) && (kp->k_key != DEVICE)) goto usage; else if (argc >= 2) l = strlen(argv[1]); /* If ExtCurStyle is NULL, this is a first pass, and we should */ /* immediately load this style as default. Otherwise, check if */ /* the style name is in the table of styles, and add it if it is */ /* not. */ if (kp->k_key == STYLE) { if (argc != 2) if ((argc != 4) || (strncmp(argv[2], "variant", 7))) goto usage; for (newStyle = ExtAllStyles; newStyle != NULL; newStyle = newStyle->exts_next) { if (!strncmp(newStyle->exts_name, argv[1], l)) break; } if (newStyle == NULL) { if (argc == 2) { newStyle = (ExtKeep *)mallocMagic(sizeof(ExtKeep)); newStyle->exts_next = NULL; newStyle->exts_name = StrDup((char **) NULL, argv[1]); if (ExtAllStyles == NULL) ExtAllStyles = newStyle; else { /* Append to end of style list */ for (es = ExtAllStyles; es->exts_next; es = es->exts_next); es->exts_next = newStyle; } } else /* Handle style variants */ { ExtKeep *saveStyle = NULL; char *tptr, *cptr; /* 4th argument is a comma-separated list of variants. */ /* In addition to the default name recorded above, */ /* record each of the variants. */ tptr = argv[3]; while (*tptr != '\0') { cptr = strchr(tptr, ','); if (cptr != NULL) *cptr = '\0'; newStyle = (ExtKeep *)mallocMagic(sizeof(ExtKeep)); newStyle->exts_next = NULL; newStyle->exts_name = (char *)mallocMagic(l + strlen(tptr) + 1); sprintf(newStyle->exts_name, "%s%s", argv[1], tptr); /* Remember the first variant as the default */ if (saveStyle == NULL) saveStyle= newStyle; /* Append to end of style list */ if (ExtAllStyles == NULL) ExtAllStyles = newStyle; else { for (es = ExtAllStyles; es->exts_next; es = es->exts_next); es->exts_next = newStyle; } if (cptr == NULL) break; else tptr = cptr + 1; } newStyle = saveStyle; } } /* Load style as default extraction style if this is the first */ /* style encountered. Otherwise, if we are changing styles, */ /* load this style only if the name matches that in ExtCurStyle.*/ if (ExtCurStyle == NULL) { ExtCurStyle = extTechStyleNew(); ExtCurStyle->exts_name = newStyle->exts_name; ExtCurStyle->exts_status = TECH_PENDING; } else if ((ExtCurStyle->exts_status == TECH_PENDING) || (ExtCurStyle->exts_status == TECH_SUSPENDED)) /* Finished loading; stop */ ExtCurStyle->exts_status = TECH_LOADED; else if (ExtCurStyle->exts_status == TECH_NOT_LOADED) { if (ExtCurStyle->exts_name == NULL) return (FALSE); /* Don't know what to load! */ else if (argc == 2) { if (!strcmp(argv[1], ExtCurStyle->exts_name)) ExtCurStyle->exts_status = TECH_PENDING; /* load pending */ } else if (argc == 4) { /* Verify that the style matches one variant */ char *tptr, *cptr; if (!strncmp(ExtCurStyle->exts_name, argv[1], l)) { tptr = argv[3]; while (*tptr != '\0') { cptr = strchr(tptr, ','); if (cptr != NULL) *cptr = '\0'; if (!strcmp(ExtCurStyle->exts_name + l, tptr)) { ExtCurStyle->exts_status = TECH_PENDING; return TRUE; } if (cptr == NULL) return TRUE; else tptr = cptr + 1; } } } } return (TRUE); } /* Only continue past this point if we are loading the extraction style */ if (ExtCurStyle == NULL) return FALSE; if ((ExtCurStyle->exts_status != TECH_PENDING) && (ExtCurStyle->exts_status != TECH_SUSPENDED)) return TRUE; /* Process "variant" lines next */ if (kp->k_key == VARIANT) { int l; char *cptr, *tptr; /* If our style variant is not one of the ones declared */ /* on the line, then we ignore all input until we */ /* either reach the end of the style, the end of the */ /* section, or another "variant" line. */ if (argc != 2) goto usage; tptr = argv[1]; while (*tptr != '\0') { cptr = strchr(tptr, ','); if (cptr != NULL) { *cptr = '\0'; for (j = 1; isspace(*(cptr - j)); j++) *(cptr - j) = '\0'; } if (*tptr == '*') /* Wildcard for "all variants" */ { ExtCurStyle->exts_status = TECH_PENDING; return TRUE; } else { l = strlen(ExtCurStyle->exts_name) - strlen(tptr); if (!strcmp(tptr, ExtCurStyle->exts_name + l)) { ExtCurStyle->exts_status = TECH_PENDING; return TRUE; } } if (cptr == NULL) break; else tptr = cptr + 1; } ExtCurStyle->exts_status = TECH_SUSPENDED; } /* Anything below this line is not parsed if we're in TECH_SUSPENDED mode */ if (ExtCurStyle->exts_status != TECH_PENDING) return TRUE; switch (kp->k_key) { case AREAC: case CONTACT: case FET: case FETRESIST: case HEIGHT: case OVERC: case PERIMC: case RESIST: case SIDEWALL: case SIDEOVERLAP: DBTechNoisyNameMask(argv[1], &types1); break; case DEVICE: DBTechNoisyNameMask(argv[3], &types1); break; case PLANEORDER: case NOPLANEORDER: default: break; } switch (kp->k_key) { case AREAC: capVal = aToCap(argv[2]); for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) if (TTMaskHasType(&types1, t)) ExtCurStyle->exts_areaCap[t] = capVal; break; case CONTACT: /* Contact size, border, spacing deprecated (now taken from */ /* cifoutput "squares" generation parameters). */ if (argc != 3) { if (argc == 4) TxPrintf("Contact size value ignored " "(using GDS generation rules).\n"); else TxPrintf("Contact size, spacing, and border values ignored " "(using GDS generation rules).\n"); } if (!StrIsInt(argv[argc - 1])) { TechError("Contact resistivity %s must be an integer value " "(in milliohms/square).\n", argv[argc - 1]); break; } val = atoi(argv[argc - 1]); for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) if (TTMaskHasType(&types1, t)) ExtCurStyle->exts_viaResist[t] = val; break; case CSCALE: ExtCurStyle->exts_capScale = strtol(argv[1], &endptr, 10); if (endptr == argv[1]) { TechError("Cannot parse cap scale value \"%s\"\n", argv[1]); ExtCurStyle->exts_capScale = 1; } break; case FET: /* Original FET format, kept for backwards compatibility */ DBTechNoisyNameMask(argv[2], &termtypes[0]); nterm = atoi(argv[3]); transName = argv[4]; subsName = argv[5]; cp = index(subsName, '!'); if (cp == NULL || cp[1] != '\0') { TechError("Fet substrate node %s is not a global name\n", subsName); } subsTypes = DBZeroTypeBits; if (sscanf(argv[6], "%lf", &capVal) != 1) { DBTechNoisyNameMask(argv[6], &subsTypes); gscap = aToCap(argv[7]); gccap = (argc > 8) ? aToCap(argv[8]) : (CapValue) 0; } else { gscap = aToCap(argv[6]); gccap = (argc > 7) ? aToCap(argv[7]) : (CapValue) 0; } TTMaskSetMask(&ExtCurStyle->exts_transMask, &types1); for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) if (TTMaskHasType(&types1, t)) { TTMaskSetMask(ExtCurStyle->exts_transConn+t,&types1); ExtCurStyle->exts_transSDTypes[t] = (TileTypeBitMask *) mallocMagic(2 * sizeof(TileTypeBitMask)); ExtCurStyle->exts_transSDTypes[t][0] = termtypes[0]; ExtCurStyle->exts_transSDTypes[t][1] = DBSpaceBits; ExtCurStyle->exts_transSDCount[t] = nterm; ExtCurStyle->exts_transSDCap[t] = gscap; ExtCurStyle->exts_transGateCap[t] = gccap; ExtCurStyle->exts_deviceClass[t] = DEV_FET; ExtCurStyle->exts_transName[t] = StrDup((char **) NULL, transName); ExtCurStyle->exts_transSubstrateName[t] = StrDup((char **) NULL, subsName); ExtCurStyle->exts_transSubstrateTypes[t] = subsTypes; #ifdef ARIEL { int z; for (z = TT_TECHDEPBASE; z < DBNumTypes; z++) { if (TTMaskHasType(&subsTypes, z)) TTMaskSetType(&ExtCurStyle->exts_subsTransistorTypes[z], t); } } #endif } break; case DEFAULTAREACAP: ExtTechSimpleAreaCap(argc, argv); break; case DEFAULTOVERLAP: ExtTechSimpleOverlapCap(argv); break; case DEFAULTPERIMETER: ExtTechSimplePerimCap(argc, argv); break; case DEFAULTSIDEOVERLAP: ExtTechSimpleSideOverlapCap(argv); break; case DEFAULTSIDEWALL: ExtTechSimpleSidewallCap(argv); break; case DEVICE: /* Parse second argument for device type */ n = LookupStruct(argv[1], (LookupTable *) devTable, sizeof devTable[0]); if (n < 0) { TechError("Illegal device. Legal devices are:\n\t"); for (n = 0; devTable[n].k_name; n++) TxError(" %s", devTable[n].k_name); TxError("\n"); return (TRUE); } dv = &devTable[n]; if ((argc - 1) < dv->k_minargs) goto usage; /* No limit on arguments in DEV_SUBCKT and DEV_MSUBCKT! */ /* And. . . check DEV_RSUBCKT later, after parsing parameter names */ class = dv->k_key; switch (class) { case DEV_SUBCKT: case DEV_RSUBCKT: case DEV_MSUBCKT: break; default: if ((argc - 1) > dv->k_maxargs) goto usage; break; } gscap = (CapValue) 0; gccap = (CapValue) 0; subsName = NULL; subcktParams = NULL; subsTypes = DBZeroTypeBits; transName = argv[2]; switch (dv->k_key) { case DEV_BJT: DBTechNoisyNameMask(argv[4], &termtypes[0]); /* emitter */ termtypes[1] = DBSpaceBits; DBTechNoisyNameMask(argv[5], &subsTypes); /* collector */ nterm = 1; /* emitter is the only "terminal type" expected */ break; case DEV_MOSFET: if ((argc > 7) && (!StrIsNumeric(argv[7]))) { /* Asymmetric device with different source and drain types */ DBTechNoisyNameMask(argv[4], &termtypes[0]); /* source */ DBTechNoisyNameMask(argv[5], &termtypes[1]); /* drain */ TTMaskAndMask3(&termtypes[2], &termtypes[0], &termtypes[1]); if (TTMaskEqual(&termtypes[0], &termtypes[1])) termtypes[1] = DBSpaceBits; /* Make it symmetric */ else if (!TTMaskIsZero(&termtypes[2])) { TechError("Device mosfet %s has overlapping drain" " and source types!\n", transName); /* Should this device be disabled? */ } termtypes[2] = DBSpaceBits; if (strcmp(argv[6], "None")) DBTechNoisyNameMask(argv[6], &subsTypes); /* substrate */ subsName = argv[7]; if (argc > 8) gscap = aToCap(argv[8]); if (argc > 9) gccap = aToCap(argv[9]); nterm = 2; class = DEV_ASYMMETRIC; } else { /* Normal symmetric device with swappable source/drain */ DBTechNoisyNameMask(argv[4], &termtypes[0]); /* source/drain */ termtypes[1] = DBSpaceBits; if (strcmp(argv[5], "None")) DBTechNoisyNameMask(argv[5], &subsTypes); /* substrate */ if (argc > 6) subsName = argv[6]; if (argc > 7) gscap = aToCap(argv[7]); if (argc > 8) gccap = aToCap(argv[8]); /* nterm = 1; */ /* Symmetric devices can be MOScaps */ nterm = 2; } break; case DEV_DIODE: DBTechNoisyNameMask(argv[4], &termtypes[0]); /* negative types */ termtypes[1] = DBSpaceBits; nterm = 1; if ((argc > 4) && strcmp(argv[4], "None")) DBTechNoisyNameMask(argv[4], &subsTypes); /* substrate */ else subsTypes = DBZeroTypeBits; if (argc > 5) subsName = argv[5]; break; case DEV_RES: DBTechNoisyNameMask(argv[4], &termtypes[0]); /* terminals */ termtypes[1] = DBSpaceBits; nterm = 2; if ((argc > 5) && strcmp(argv[5], "None")) DBTechNoisyNameMask(argv[5], &subsTypes); /* substrate */ else subsTypes = DBZeroTypeBits; if (argc > 6) subsName = argv[6]; break; case DEV_CAP: DBTechNoisyNameMask(argv[4], &termtypes[0]); /* bottom */ termtypes[1] = DBSpaceBits; gccap = aToCap(argv[argc - 1]); /* area cap */ if ((argc > 6) && StrIsNumeric(argv[argc - 2])) { gscap = aToCap(argv[argc - 2]); /* perimeter cap */ argc--; } nterm = 1; if ((argc > 6) && strcmp(argv[5], "None")) DBTechNoisyNameMask(argv[5], &subsTypes); /* substrate */ else subsTypes = DBZeroTypeBits; if (argc > 7) subsName = argv[6]; break; case DEV_SUBCKT: case DEV_MSUBCKT: /* Check final arguments for "x=y" statements showing what */ /* parameter names the subcircuit uses. */ while ((paramName = strchr(argv[argc - 1], '=')) != NULL) { char *mult; paramName++; newParam = (ParamList *)mallocMagic(sizeof(ParamList)); newParam->pl_count = 0; newParam->pl_param[0] = *argv[argc - 1]; newParam->pl_param[1] = '\0'; if (paramName - argv[argc - 1] == 3) newParam->pl_param[1] = *(argv[argc - 1] + 1); else if (paramName - argv[argc - 1] > 3) TechError("Parameter name %s can be no more than" "two characters.\n", argv[argc - 1]); // Parameter syntax "=*" indicates // that the subcircuit has internal scaling, and the // extractor should multiply the parameter by this value // before passing it to the subcircuit. if ((mult = strchr(paramName, '*')) != NULL) { *mult = '\0'; mult++; newParam->pl_scale = atof(mult); } else newParam->pl_scale = 1.0; newParam->pl_name = StrDup((char **)NULL, paramName); newParam->pl_next = subcktParams; subcktParams = newParam; argc--; } if (StrIsInt(argv[4])) { nterm = atoi(argv[4]); iterm = 4 + nterm; } else { nterm = 1; iterm = 4; } /* terminals */ for (i = iterm; i < iterm + nterm; i++) DBTechNoisyNameMask(argv[iterm], &termtypes[i - iterm]); termtypes[nterm] = DBSpaceBits; if (nterm == 0) i++; // Type MSUBCKT: Source and drain are symmetric. The // number of unique terminals in the definition is 1, // but nterm needs to be set to 2 for proper extraction. if ((dv->k_key == DEV_MSUBCKT) && (nterm == 1)) nterm = 2; if (argc > i) DBTechNoisyNameMask(argv[i], &subsTypes); /* substrate */ if (argc > (i + 1)) subsName = argv[i + 1]; break; case DEV_RSUBCKT: /* Check final arguments for "x=y" statements showing what */ /* parameter names the subcircuit uses. */ while ((paramName = strchr(argv[argc - 1], '=')) != NULL) { char *mult; paramName++; newParam = (ParamList *)mallocMagic(sizeof(ParamList)); newParam->pl_count = 0; newParam->pl_param[0] = *argv[argc - 1]; newParam->pl_param[1] = '\0'; if (paramName - argv[argc - 1] == 3) newParam->pl_param[1] = *(argv[argc - 1] + 1); else if (paramName - argv[argc - 1] > 3) TechError("Parameter name %s can be no more than" "two characters.\n", argv[argc - 1]); // See comments for DEV_SUBCKT/DEV_MSUBCKT above. if ((mult = strchr(paramName, '*')) != NULL) { *mult = '\0'; mult++; newParam->pl_scale = atof(mult); } else newParam->pl_scale = 1.0; newParam->pl_name = StrDup((char **)NULL, paramName); newParam->pl_next = subcktParams; subcktParams = newParam; argc--; } /* Now check number of parameters */ if ((argc - 1) > dv->k_maxargs) { while (subcktParams != NULL) { freeMagic(subcktParams->pl_name); freeMagic(subcktParams); subcktParams = subcktParams->pl_next; } goto usage; } nterm = 2; DBTechNoisyNameMask(argv[4], &termtypes[0]); /* terminals */ termtypes[1] = DBSpaceBits; if ((argc > 5) && strcmp(argv[5], "None")) DBTechNoisyNameMask(argv[5], &subsTypes); /* substrate */ else subsTypes = DBZeroTypeBits; if (argc > 6) subsName = argv[6]; break; } TTMaskSetMask(&ExtCurStyle->exts_transMask, &types1); for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) { if (TTMaskHasType(&types1, t)) { TTMaskSetMask(ExtCurStyle->exts_transConn + t, &types1); for (i = 0; !TTMaskHasType(&termtypes[i], TT_SPACE); i++); ExtCurStyle->exts_transSDTypes[t] = (TileTypeBitMask *) mallocMagic((i + 1) * sizeof(TileTypeBitMask)); for (i = 0; !TTMaskHasType(&termtypes[i], TT_SPACE); i++) ExtCurStyle->exts_transSDTypes[t][i] = termtypes[i]; ExtCurStyle->exts_transSDTypes[t][i] = DBSpaceBits; ExtCurStyle->exts_transSDCount[t] = nterm; ExtCurStyle->exts_transSDCap[t] = gscap; ExtCurStyle->exts_transGateCap[t] = gccap; ExtCurStyle->exts_deviceClass[t] = class; ExtCurStyle->exts_transName[t] = StrDup((char **) NULL, transName); if (subsName != NULL) ExtCurStyle->exts_transSubstrateName[t] = StrDup((char **) NULL, subsName); ExtCurStyle->exts_transSubstrateTypes[t] = subsTypes; #ifdef ARIEL { int z; for (z = TT_TECHDEPBASE; z < DBNumTypes; z++) { if (TTMaskHasType(&subsTypes, z)) TTMaskSetType(&ExtCurStyle-> exts_subsTransistorTypes[z], t); } } #endif if (subcktParams != NULL) { ExtCurStyle->exts_deviceParams[t] = subcktParams; subcktParams->pl_count++; } } } break; case FETRESIST: if (!StrIsInt(argv[3])) { TechError("Fet resistivity %s must be numeric\n", argv[3]); break; } val = atoi(argv[3]); isLinear = (strcmp(argv[2], "linear") == 0); for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) if (TTMaskHasType(&types1, t)) { he = HashFind(&ExtCurStyle->exts_transResist[t], argv[2]); HashSetValue(he, (spointertype)val); if (isLinear) ExtCurStyle->exts_linearResist[t] = val; } break; case HEIGHT: { float height, thick; if (!StrIsNumeric(argv[2])) { TechError("Layer height %s must be numeric\n", argv[2]); break; } if (!StrIsNumeric(argv[3])) { TechError("Layer thickness %s must be numeric\n", argv[3]); break; } height = (float)strtod(argv[2], NULL); thick = (float)strtod(argv[3], NULL); for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) if (TTMaskHasType(&types1, t)) { ExtCurStyle->exts_height[t] = height; ExtCurStyle->exts_thick[t] = thick; } } break; case UNITS: if (!strcmp(argv[1], "microns")) doConvert = TRUE; else if (!strcmp(argv[1], "um")) doConvert = TRUE; else if (strcmp(argv[1], "lambda")) TechError("Units must be microns or lambda. Using the " "default value (lambda).\n"); break; case LAMBDA: ExtCurStyle->exts_unitsPerLambda = (float)atof(argv[1]); break; case OVERC: DBTechNoisyNameMask(argv[2], &types2); capVal = aToCap(argv[3]); bad = FALSE; shield = DBZeroTypeBits; if (argc > 4) DBTechNoisyNameMask(argv[4], &shield); for (s = TT_TECHDEPBASE; s < DBNumTypes; s++) { if (!TTMaskHasType(&types1, s)) continue; /* Contact overlap caps are determined from residues */ if (DBIsContact(s)) continue; for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) { if (!TTMaskHasType(&types2, t)) continue; /* Contact overlap caps are determined from residues */ if (DBIsContact(t)) continue; if (s == t) { TechError("Can't have overlap capacitance between" " tiles of the same type (%s)\n", DBTypeLongName(s)); bad = TRUE; continue; } p1 = DBPlane(s), p2 = DBPlane(t); if (p1 == p2) { TechError("Can't have overlap capacitance between" " tiles on the same plane (%s, %s)\n", DBTypeLongName(s), DBTypeLongName(t)); bad = TRUE; continue; } if (ExtCurStyle->exts_overlapCap[s][t] > (CapValue) 0) { TechError("Only one of \"overlap %s %s\" or" " \"overlap %s %s\" allowed\n", DBTypeLongName(s), DBTypeLongName(t), DBTypeLongName(t), DBTypeLongName(s)); bad = TRUE; continue; } ExtCurStyle->exts_overlapCap[s][t] = capVal; ExtCurStyle->exts_overlapPlanes |= PlaneNumToMaskBit(p1); ExtCurStyle->exts_overlapOtherPlanes[s] |= PlaneNumToMaskBit(p2); TTMaskSetType(&ExtCurStyle->exts_overlapTypes[p1], s); TTMaskSetType(&ExtCurStyle->exts_overlapOtherTypes[s], t); if (argc == 4) continue; /* Shielding */ pshield = 0; for (r = TT_TECHDEPBASE; r < DBNumTypes; r++) { if (TTMaskHasType(&shield, r)) { /* Shielding types are determined from residues */ if (DBIsContact(r)) continue; p3 = DBPlane(r); if (p3 == p1 || p3 == p2) { TechError("Shielding type (%s) must be on a" " different plane from shielded types.\n", DBTypeLongName(r)); bad = TRUE; continue; } pshield |= PlaneNumToMaskBit(p3); } } ExtCurStyle->exts_overlapShieldPlanes[s][t] = pshield; ExtCurStyle->exts_overlapShieldTypes[s][t] = shield; } } if (bad) return (TRUE); break; case SIDEOVERLAP: bad = FALSE; DBTechNoisyNameMask(argv[2], &types2); pov = DBTechNoisyNameMask(argv[3], &ov); capVal = aToCap(argv[4]); shield = DBZeroTypeBits; if (argc == 6) DBTechNoisyNameMask(argv[5], &shield); if (TTMaskHasType(&types1, TT_SPACE)) TechError("Can't have space on inside of edge [ignored]\n"); /* It's ok to have the overlap be to space as long as a plane is */ /* specified. */ if (TTMaskHasType(&ov, TT_SPACE)) { if ((cp = index(argv[3],'/')) == NULL) { TechError("Must specify plane for sideoverlap to space\n"); } cp++; p3 = (spointertype) dbTechNameLookup(cp, &dbPlaneNameLists); if (p3 < 0) TechError("Unknown overlap plane %s\n",argv[3]); else pov = PlaneNumToMaskBit(p3); } for (s = TT_TECHDEPBASE; s < DBNumTypes; s++) { if (!TTMaskHasType(&types1, s)) continue; /* Side overlap computed from residues */ if (DBIsContact(s)) continue; p1 = DBPlane(s); if (PlaneMaskHasPlane(pov, p1)) goto diffplane; ExtCurStyle->exts_sidePlanes |= PlaneNumToMaskBit(p1); TTMaskSetType(&ExtCurStyle->exts_sideTypes[p1], s); TTMaskSetMask(&ExtCurStyle->exts_sideEdges[s], &types2); for (t = 0; t < DBNumTypes; t++) { if (!TTMaskHasType(&types2, t)) continue; /* Side overlap computed from residues */ if (DBIsContact(t)) continue; p2 = DBPlane(t); if (t != TT_SPACE && PlaneMaskHasPlane(pov, p2)) goto diffplane; TTMaskSetMask(&ExtCurStyle->exts_sideOverlapOtherTypes[s][t], &ov); ExtCurStyle->exts_sideOverlapOtherPlanes[s][t] |= pov; cnew = (EdgeCap *) mallocMagic((unsigned) (sizeof (EdgeCap))); cnew->ec_cap = capVal; cnew->ec_far = shield; /* Really types that shield */ cnew->ec_near = ov; /* Really types we create cap with */ cnew->ec_pmask = pov; cnew->ec_next = ExtCurStyle->exts_sideOverlapCap[s][t]; ExtCurStyle->exts_sideOverlapCap[s][t] = cnew; /* Shielding */ pshield = 0; for (r = TT_TECHDEPBASE; r < DBNumTypes; r++) { if (TTMaskHasType(&shield, r)) { /* Side overlap shielding computed from residues */ if (DBIsContact(r)) continue; p3 = DBPlane(r); if (p3 == p1 || p3 == p2) { TechError("Shielding type (%s) must be on" " a different plane from shielded types.\n", DBTypeLongName(r)); bad = TRUE; continue; } pshield |= PlaneNumToMaskBit(p3); } } for (o = TT_TECHDEPBASE; o < DBNumTypes; o++) { if (TTMaskHasType(&ov, o)) { ExtCurStyle->exts_sideOverlapShieldPlanes[s][o] |= pshield; } } } } if (bad) return (TRUE); break; case SIDEWALL: DBTechNoisyNameMask(argv[2], &types2); DBTechNoisyNameMask(argv[3], &near); DBTechNoisyNameMask(argv[4], &far); if (TTMaskHasType(&types1, TT_SPACE)) TechError("Can't have space on inside of edge [ignored]\n"); capVal = aToCap(argv[5]); for (s = TT_TECHDEPBASE; s < DBNumTypes; s++) { if (!TTMaskHasType(&types1, s)) continue; ExtCurStyle->exts_sidePlanes |= PlaneNumToMaskBit(DBPlane(s)); TTMaskSetType(&ExtCurStyle->exts_sideTypes[DBPlane(s)], s); TTMaskSetMask(&ExtCurStyle->exts_sideEdges[s], &types2); for (t = 0; t < DBNumTypes; t++) { if (!TTMaskHasType(&types2, t)) continue; TTMaskSetMask(&ExtCurStyle->exts_sideCoupleOtherEdges[s][t], &far); cnew = (EdgeCap *) mallocMagic((unsigned) (sizeof (EdgeCap))); cnew->ec_cap = capVal; cnew->ec_near = near; cnew->ec_far = far; cnew->ec_next = ExtCurStyle->exts_sideCoupleCap[s][t]; cnew->ec_pmask = 0; ExtCurStyle->exts_sideCoupleCap[s][t] = cnew; } } break; case SIDEHALO: /* Allow floating-point and increase by factor of 1000 */ /* to accomodate "units microns". */ /* Warning: Due to some gcc bug with an i686 FPU, using a */ /* result from atof() with a static value like 1000 */ /* produces a NaN result! sscanf() seems to be safe. . . */ sscanf(argv[1], "%lg", &dhalo); dhalo *= (double)1000.0; ExtCurStyle->exts_sideCoupleHalo = (int)dhalo; break; case PERIMC: DBTechNoisyNameMask(argv[2], &types2); capVal = aToCap(argv[3]); if (capVal == (CapValue) 0) break; for (s = TT_TECHDEPBASE; s < DBNumTypes; s++) for (t = 0; t < DBNumTypes; t++) if (TTMaskHasType(&types1, s) && TTMaskHasType(&types2, t)) { ExtCurStyle->exts_perimCap[s][t] = capVal; TTMaskSetType(&ExtCurStyle->exts_perimCapMask[s], t); } break; case RESIST: { float chop = 1.0; val = atoi(argv[2]); if (argc == 4) chop = atof(argv[3]); class = ExtCurStyle->exts_numResistClasses++; for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) if (TTMaskHasType(&types1, t)) { ExtCurStyle->exts_sheetResist[t] = val; ExtCurStyle->exts_cornerChop[t] = chop; ExtCurStyle->exts_typeToResistClass[t] = class; } ExtCurStyle->exts_resistByResistClass[class] = val; ExtCurStyle->exts_typesByResistClass[class] = types1; } break; case RSCALE: ExtCurStyle->exts_resistScale = atoi(argv[1]); break; case STEP: val = (int)atof(argv[1]); if (val <= 0) { TechError("Hierarchical interaction step size must be > 0\n"); return (FALSE); } ExtCurStyle->exts_stepSize = val; break; case NOPLANEORDER: { if ( ExtCurStyle->exts_planeOrderStatus == seenPlaneOrder ) TechError("\"noplaneordering\" specified after \"planeorder\".\n"); else ExtCurStyle->exts_planeOrderStatus = noPlaneOrder ; } break ; case PLANEORDER: { int pnum = (spointertype) dbTechNameLookup(argv[1], &dbPlaneNameLists); int pos = atoi(argv[2]); if ( ExtCurStyle->exts_planeOrderStatus == noPlaneOrder ) { TechError("\"planeorder\" specified after \"noplaneordering\".\n"); } ExtCurStyle->exts_planeOrderStatus = seenPlaneOrder ; if (pnum < 0) TechError("Unknown planeorder plane %s\n", argv[1]); else if (pos < 0 || pos >= DBNumPlanes-PL_TECHDEPBASE) TechError("Planeorder index must be [0..%d]\n", DBNumPlanes-PL_TECHDEPBASE-1); else ExtCurStyle->exts_planeOrder[pnum] = pos; } break; } return (TRUE); usage: TechError("Malformed line for keyword %s. Correct usage:\n\t%s %s\n", kp->k_name, kp->k_name, kp->k_usage); return (TRUE); diffplane: TechError("Overlapped types in \"sideoverlap\" rule must be on a\n" "\tdifferent plane from intypes and outtypes.\n"); return (TRUE); } /* * ---------------------------------------------------------------------------- * * ExtTechFinal -- * * Postprocess the technology specific information for extraction. * Builds the connectivity tables exts_nodeConn[], exts_resistConn[], * and exts_transConn[]. * * Results: * None. * * Side effects: * Initializes the tables mentioned above. * Leaves ExtCurStyle pointing to the first style in the list * ExtAllStyles. * * ---------------------------------------------------------------------------- */ void ExtTechFinal() { ExtStyle *es; /* Create a "default" style if there isn't one */ if (ExtAllStyles == NULL) { ExtAllStyles = (ExtKeep *)mallocMagic(sizeof(ExtKeep)); ExtAllStyles->exts_next = NULL; ExtAllStyles->exts_name = StrDup((char **) NULL, "default"); ExtCurStyle = extTechStyleNew(); ExtCurStyle->exts_name = ExtAllStyles->exts_name; ExtCurStyle->exts_status = TECH_LOADED; } extTechFinalStyle(ExtCurStyle); } void extTechFinalStyle(style) ExtStyle *style; { TileTypeBitMask maskBits; TileType r, s, t; int p1, missing, conflict; int indicis[NP]; for (r = TT_TECHDEPBASE; r < DBNumTypes; r++) { maskBits = style->exts_nodeConn[r] = DBConnectTbl[r]; if (!TTMaskHasType(&style->exts_transMask, r)) { TTMaskZero(&style->exts_transConn[r]); } for (s = TT_TECHDEPBASE; s < DBNumTypes; s++) { if (TTMaskHasType(&maskBits, s)) if (style->exts_typeToResistClass[s] != style->exts_typeToResistClass[r]) TTMaskClearType(&maskBits, s); } style->exts_resistConn[r] = maskBits; } /* r ranges over types, s over resistance entries */ for (r = TT_TECHDEPBASE; r < DBNumTypes; r++) { s = style->exts_typeToResistClass[r]; if (s >= 0) TTMaskClearMask(&style->exts_typesResistChanged[r], &style->exts_typesByResistClass[s]); } /* * Residue check: * We have ignored all contact types when parsing parasitic * capacitances. Now we need to add them. For each contact * type, add the contact type to the types lists accordingly. * Note that we don't have to record any cap values, since the * extraction routine dissolves contacts into their residue * types when computing the parasitics. But, the type must be * in the type lists or contact tiles will be passed over during * searches. */ for (s = TT_TECHDEPBASE; s < DBNumTypes; s++) { TileTypeBitMask rmask; PlaneMask pMask; int p; TileType q; if (!DBIsContact(s)) continue; pMask = DBTypePlaneMaskTbl[s]; for (p = 0; p < DBNumPlanes; p++) { if (PlaneMaskHasPlane(pMask, p)) { TTMaskSetType(&style->exts_overlapTypes[p], s); TTMaskSetType(&style->exts_sideTypes[p], s); } } DBFullResidueMask(s, &rmask); for (r = TT_TECHDEPBASE; r < DBNumUserLayers; r++) { if (!TTMaskHasType(&rmask, r)) continue; TTMaskSetMask(&style->exts_sideEdges[s], &style->exts_sideEdges[r]); for (q = TT_TECHDEPBASE; q < DBNumUserLayers; q++) { if (TTMaskHasType(&style->exts_overlapOtherTypes[q], r)) TTMaskSetType(&style->exts_overlapOtherTypes[q], s); for (t = TT_TECHDEPBASE; t < DBNumUserLayers; t++) if (TTMaskHasType(&style->exts_overlapShieldTypes[q][t], r) && !TTMaskHasType(&rmask, q) && !TTMaskHasType(&rmask, t)) TTMaskSetType(&style->exts_overlapShieldTypes[q][t], s); /* For sideOverlap, t is "outtypes" and includes space, so we */ /* must count from TT_SPACE, not TT_TECHDEPBASE. */ for (t = TT_SPACE; t < DBNumUserLayers; t++) if (TTMaskHasType(&style->exts_sideOverlapOtherTypes[q][t], r)) TTMaskSetType(&style->exts_sideOverlapOtherTypes[q][t], s); } } } /* * Consistency check: * If a type R shields S from T, make sure that R is listed as * being in the list of overlapped types for S, even if there * was no overlap capacitance explicitly specified for this * pair of types in an "overlap" line. This guarantees that * R will shield S from substrate even if there is no capacitance * associated with the overlap. */ for (s = TT_TECHDEPBASE; s < DBNumTypes; s++) for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) { if (style->exts_overlapShieldPlanes[s][t] == 0) continue; for (r = TT_TECHDEPBASE; r < DBNumTypes; r++) { if (!TTMaskHasType(&style->exts_overlapShieldTypes[s][t], r)) continue; p1 = DBPlane(s); style->exts_overlapPlanes |= PlaneNumToMaskBit(p1); style->exts_overlapOtherPlanes[s] |= PlaneNumToMaskBit(DBPlane(r)); TTMaskSetType(&style->exts_overlapTypes[p1], s); TTMaskSetType(&style->exts_overlapOtherTypes[s], r); } } if ( style->exts_planeOrderStatus == noPlaneOrder ) return /* no need to check */ ; /* Else Check to make sure the plane order is a permutation of the numbers 0..DBNumPlanes-DBNumPlanes-1 */ for (p1 = PL_TECHDEPBASE; p1 < DBNumPlanes; p1++) { indicis[p1] = 0; } for (p1 = PL_TECHDEPBASE; p1 < DBNumPlanes; p1++) { int pn = style->exts_planeOrder[p1]+PL_TECHDEPBASE; if (pn >= PL_TECHDEPBASE && pn < DBNumPlanes) indicis[pn]++; } conflict = FALSE; missing = FALSE; for (p1 = PL_TECHDEPBASE; p1 < DBNumPlanes; p1++) { if (indicis[p1] > 1) conflict = TRUE ; if (indicis[p1] < 1) missing = TRUE ; } if (!conflict && !missing) /* Everything was ok */ goto zinit; TxError ("\nWarning: Extraction Style %s\n", style -> exts_name); if (conflict) { TxError (" Conflicting planeorder for plane(s):\n "); for (p1 = PL_TECHDEPBASE; p1 < DBNumPlanes; p1++) { if (indicis[p1] > 1) TxError (" %s,", DBPlaneLongNameTbl[p1]); } TxError("\n"); } if (missing) { TxError (" Missing planeorder for plane(s):\n "); for (p1 = PL_TECHDEPBASE; p1 < DBNumPlanes; p1++) { if (indicis[p1] < 1) TxError (" %s,", DBPlaneLongNameTbl[p1]); } TxError("\n"); } TxError(" Magic will use the default planeorder for this style:\n "); for (p1 = PL_TECHDEPBASE; p1 < DBNumPlanes; p1++) { style->exts_planeOrder[p1] = p1 - PL_TECHDEPBASE ; TxError(" %s=%d,",DBPlaneLongNameTbl[p1], style->exts_planeOrder[p1]); } TxError("\n"); /* Now that we have a plane ordering, we can apply default height */ /* and thickness values for those layers. */ zinit: for (r = TT_TECHDEPBASE; r < DBNumTypes; r++) { if (style->exts_thick[r] == 0) style->exts_thick[r] = 0.05; if (style->exts_height[r] == 0) style->exts_height[r] = 0.1 * style->exts_planeOrder[DBPlane(r)]; } /* If global variable "doConvert" is TRUE, then we convert from */ /* microns to lambda and microns^2 to lambda^2. */ if (doConvert) { /* exts_unitsPerLambda is in centimicrons, so divide by */ /* 100 to get microns. */ CapValue scalefac = (CapValue)style->exts_unitsPerLambda / 100.0; CapValue sqfac = scalefac * scalefac; for (r = 0; r < DBNumTypes; r++) { style->exts_areaCap[r] *= sqfac; style->exts_transSDCap[r] *= sqfac; style->exts_transGateCap[r] *= sqfac; for (s = 0; s < DBNumTypes; s++) { EdgeCap *ec; style->exts_perimCap[r][s] *= scalefac; style->exts_overlapCap[r][s] *= sqfac; for (ec = style->exts_sideOverlapCap[r][s]; ec != NULL; ec = ec->ec_next) ec->ec_cap *= scalefac; // Sidewall capacitance is referred to distance, // so cap value does not scale. However, the lambda // reference for sidewall cap is 2 lambda, so if // the reference is to be interpreted as 1 micron, // the value needs to be divided by 2 (the factor of // 2 is made up by the fact that the sidewall is // independently accumulated on each plate of the // capacitor). for (ec = style->exts_sideCoupleCap[r][s]; ec != NULL; ec = ec->ec_next) ec->ec_cap *= 0.5; } } /* side halo and step size are also in microns */ style->exts_sideCoupleHalo = (int)(((CapValue)style->exts_sideCoupleHalo / scalefac) + 0.5); style->exts_stepSize = (int)(((CapValue)style->exts_stepSize / scalefac) + 0.5); } /* Avoid setting stepSize to zero, or extraction will hang! */ if (style->exts_stepSize <= 0) { TxError("Warning: zero step size! Resetting to default.\n"); style->exts_stepSize = 100; /* Revert to default */ } /* We had multiplied sideCoupleHalo by 1000 to accomodate a */ /* floating-point value in microns, whether or not doConvert was */ /* needed, so normalize it back to lambda units. */ style->exts_sideCoupleHalo /= 1000; } /* * ---------------------------------------------------------------------------- * ExtTechScale -- * * Scale all extraction values appropriately when rescaling the grid. * ---------------------------------------------------------------------------- */ void ExtTechScale(scalen, scaled) int scalen; /* Scale numerator */ int scaled; /* Scale denominator */ { ExtStyle *style = ExtCurStyle; EdgeCap *ec; int i, j; float sqn, sqd; if (style == NULL) return; sqn = (float)(scalen * scalen); sqd = (float)(scaled * scaled); style->exts_unitsPerLambda = style->exts_unitsPerLambda * (float)scalen / (float)scaled; DBScaleValue(&style->exts_sideCoupleHalo, scaled, scalen); DBScaleValue(&style->exts_stepSize, scaled, scalen); for (i = 0; i < DBNumTypes; i++) { style->exts_areaCap[i] *= sqn; style->exts_areaCap[i] /= sqd; style->exts_transSDCap[i] *= sqn; style->exts_transSDCap[i] /= sqd; style->exts_transGateCap[i] *= sqn; style->exts_transGateCap[i] /= sqd; style->exts_height[i] *= scaled; style->exts_height[i] /= scalen; style->exts_thick[i] *= scaled; style->exts_thick[i] /= scalen; for (j = 0; j < DBNumTypes; j++) { style->exts_perimCap[i][j] *= scalen; style->exts_perimCap[i][j] /= scaled; style->exts_overlapCap[i][j] *= sqn; style->exts_overlapCap[i][j] /= sqd; /* Typo fixed in 7.2.57 */ // Sidewall capacitance is referred to distance, // so cap value does not scale. // for (ec = style->exts_sideCoupleCap[i][j]; ec != NULL; // ec = ec->ec_next) // { // ec->ec_cap *= scalen; // ec->ec_cap /= scaled; // } for (ec = style->exts_sideOverlapCap[i][j]; ec != NULL; ec = ec->ec_next) { ec->ec_cap *= scalen; ec->ec_cap /= scaled; } } } return; } magic-8.0.210/extract/ExtSubtree.c0000664000175000001440000010024512421575324015373 0ustar timusers/* * ExtSubtree.c -- * * Circuit extraction. * Extracts interactions between subtrees of a parent and the * parent itself. Does not handle extraction of interactions * arising between elements of the same array; those are handled * by the procedures in ExtArray.c * * The procedures in this file are not re-entrant. * * ********************************************************************* * * 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/extract/ExtSubtree.c,v 1.3 2010/06/24 12:37:17 tim Exp $"; #endif /* not lint */ #include #include #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 "utils/malloc.h" #include "textio/textio.h" #include "debug/debug.h" #include "extract/extract.h" #include "extract/extractInt.h" #include "utils/signals.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "utils/styles.h" #ifdef exactinteractions /* * If "exactinteractions" is defined, we use an experimental algorithm * for finding exact interaction areas. Currently it doesn't work too * well, so we leave it turned off. */ int ExtInterBloat = 10; #endif /* exactinteractions */ /* Imports from elsewhere in this module */ extern int extHierYankFunc(); extern LabRegion *extSubtreeHardNode(); /* Global data incremented by extSubtree() */ int extSubtreeTotalArea; /* Total area of cell */ int extSubtreeInteractionArea; /* Total area of all interactions, counting the * entire area of the interaction each time. */ int extSubtreeClippedArea; /* Total area of all interactions, counting only * the area that lies inside each chunk, so no * area is counted more than once. */ /* Local data */ /* TRUE if processing the first subtree in an interaction area */ bool extFirstPass; /* Points to list of subtrees in an interaction area */ ExtTree *extSubList = (ExtTree *) NULL; /* Forward declarations of filter functions */ char *extSubtreeTileToNode(); int extSubtreeFunc(); int extConnFindFunc(); int extSubtreeHardUseFunc(); int extHardProc(); int extSubtreeCopyPlane(); int extSubtreeShrinkPlane(); void extSubtreeInteraction(); void extSubtreeAdjustInit(); void extSubtreeOutputCoupling(); void extSubtreeHardSearch(); /* * ---------------------------------------------------------------------------- * * extSubtree -- * * Do the hierarchical part of extracting the cell 'parentUse->cu_def'. * This consists of finding all connections either between geometry in the * parent and geometry in a subcell, or between geometry in two overlapping * or adjacent subcells. * * This procedure only finds interaction areas, where subcells are close * to each other or to mask information, and then calls extSubtreeInteraction() * to do the real work. See the comments there for more details. * * Results: * None. * * Side effects: * Outputs connections and adjustments to the file 'f'. * There are two kinds of records: * * merge node1 node2 deltaC deltaP1 deltaA1 deltaP2 deltaA2 ... * cap node1 node2 deltaC * * The first merges node1 and node2, adjusts the substrate capacitance * by adding deltaC (usually negative), and the node perimeter and area * for each resistive layer n by deltaPn deltaAn. * * The second adjusts the coupling capacitance between node1 and node2 * by deltaC, which may be positive or negative. * * ---------------------------------------------------------------------------- */ #define RECTAREA(r) (((r)->r_xtop-(r)->r_xbot) * ((r)->r_ytop-(r)->r_ybot)) void extSubtree(parentUse, f) CellUse *parentUse; FILE *f; { int extSubtreeInterFunc(); CellDef *def = parentUse->cu_def; int halo = ExtCurStyle->exts_sideCoupleHalo + 1; HierExtractArg ha; Rect r, rbloat, *b; Label *lab; bool result; if ((ExtOptions & (EXT_DOCOUPLING|EXT_DOADJUST)) != (EXT_DOCOUPLING|EXT_DOADJUST)) halo = 1; /* * The cumulative buffer is initially empty. It will be built up * for each interaction area, and then cleared before processing * the next one. * * The connection hash table is initialized here but doesn't get * cleared until the end. It is responsible for changes to the * node structure over the entire cell 'def'. */ extSubtreeTotalArea += RECTAREA(&def->cd_bbox); ha.ha_outf = f; ha.ha_parentUse = parentUse; ha.ha_nodename = extSubtreeTileToNode; ha.ha_cumFlat.et_use = extYuseCum; HashInit(&ha.ha_connHash, 32, 0); #ifndef exactinteractions /* * Cookie-cutter up def into pieces ExtCurStyle->exts_stepSize by * ExtCurStyle->exts_stepSize. * Find all interaction areas (within halo units distance, where * halo has been set above to reflect the maximum distance for * sidewall coupling capacitance). */ b = &def->cd_bbox; for (r.r_ybot = b->r_ybot; r.r_ybot < b->r_ytop; r.r_ybot = r.r_ytop) { r.r_ytop = r.r_ybot + ExtCurStyle->exts_stepSize; for (r.r_xbot = b->r_xbot; r.r_xbot < b->r_xtop; r.r_xbot = r.r_xtop) { r.r_xtop = r.r_xbot + ExtCurStyle->exts_stepSize; if (SigInterruptPending) goto done; rbloat = r; rbloat.r_xbot -= halo, rbloat.r_ybot -= halo; rbloat.r_xtop += halo, rbloat.r_ytop += halo; result = DRCFindInteractions(def, &rbloat, halo, &ha.ha_interArea); // Check area for labels. Expand interaction area to include // the labels. for (lab = def->cd_labels; lab; lab = lab->lab_next) if (GEO_OVERLAP(&lab->lab_rect, &r)) result |= GeoIncludeAll(&lab->lab_rect, &ha.ha_interArea); if (result) { ha.ha_clipArea = ha.ha_interArea; GEOCLIP(&ha.ha_clipArea, &r); extSubtreeInteractionArea += RECTAREA(&ha.ha_interArea); extSubtreeClippedArea += RECTAREA(&ha.ha_clipArea); extSubtreeInteraction(&ha); } } } #else /* exactinteractions */ { static Plane *interPlane = NULL, *bloatPlane = NULL; /* * Experimental code to find exact interaction areas. * Currently, this both takes longer to find interactions * and longer to process them than the cookie-cutter * approach above, but maybe it can be turned into a * scheme that is faster. */ if (interPlane == (Plane *) NULL) interPlane = DBNewPlane((ClientData) TT_SPACE); if (bloatPlane == (Plane *) NULL) bloatPlane = DBNewPlane((ClientData) TT_SPACE); ExtFindInteractions(def, halo, ExtInterBloat, interPlane); if (ExtInterBloat) { /* Shrink back down */ (void) DBSrPaintArea((Tile *) NULL, interPlane, &TiPlaneRect, &DBAllButSpaceBits, extSubtreeCopyPlane, (ClientData) bloatPlane); (void) DBSrPaintArea((Tile *) NULL, bloatPlane, &TiPlaneRect, &DBSpaceBits, extSubtreeShrinkPlane, (ClientData) interPlane); DBClearPaintPlane(bloatPlane); } (void) DBSrPaintArea((Tile *) NULL, interPlane, &TiPlaneRect, &DBAllButSpaceBits, extSubtreeInterFunc, (ClientData) &ha); DBClearPaintPlane(interPlane); } #endif /* exactinteractions */ done: /* Output connections and node adjustments */ extOutputConns(&ha.ha_connHash, f); HashKill(&ha.ha_connHash); } #ifdef exactinteractions int extSubtreeCopyPlane(tile, plane) Tile *tile; Plane *plane; { Rect r; TITORECT(tile, &r); (void) DBPaintPlane(plane, &r, DBStdWriteTbl(TT_ERROR_P), (PaintUndoInfo *) NULL); return (0); } int extSubtreeShrinkPlane(tile, plane) Tile *tile; Plane *plane; { Rect r; TITORECT(tile, &r); r.r_xbot -= ExtInterBloat; r.r_ybot -= ExtInterBloat; r.r_xtop += ExtInterBloat; r.r_ytop += ExtInterBloat; GEOCLIP(&r, &TiPlaneRect); (void) DBPaintPlane(plane, &r, DBStdWriteTbl(TT_SPACE), (PaintUndoInfo *) NULL); return (0); } int extSubtreeInterFunc(tile, ha) Tile *tile; HierExtractArg *ha; { TITORECT(tile, &ha->ha_interArea); ha->ha_clipArea = ha->ha_interArea; extSubtreeInteractionArea += RECTAREA(&ha->ha_interArea); extSubtreeClippedArea += RECTAREA(&ha->ha_clipArea); extSubtreeInteraction(ha); return (0); } #endif /* exactinteractions */ /* * ---------------------------------------------------------------------------- * * extSubtreeInteraction -- * * Having found an interaction area, we process it. * The def being extracted is ha->ha_parentUse->cu_def. * * Clipping: * The cookie-cutter piece we were looking at for the interaction is * ha->ha_clipArea, and the interaction area actually found is * ha->ha_interArea. It is possible that ha->ha_interArea extends * outside of ha->ha_clipArea; if this is the case, all area and * perimeter outside of ha->ha_clipArea are ignored when making * adjustments. When computing sidewall coupling capacitance, * we search for an initial tile only inside ha->ha_clipArea. * * Algorithm: * Extracting an interaction area consists of two passes. * * The first pass will build the connection table ha->ha_connHash, * but leave the adjustment for each connection as zero. At the * end of the first pass, extSubList is a list of ExtTrees containing * each flattened subtree in the area of the interaction (including * the parent geometry), and ha->ha_cumFlat contains everything * flattened. * * The second pass will make the adjustments in ha->ha_connHash, and * will build the table et_coupleHash in ha->ha_cumFlat. All of * the table ha->ha_connHash will be output, but only those entries * in et_coupleHash with non-zero capacitance adjustment (either * positive or negative) will get output. * * Results: * None. * * Side effects: * Adds more information to ha->ha_connHash and * ha->ha_cumFlat.et_coupleHash. * * ---------------------------------------------------------------------------- */ void extSubtreeInteraction(ha) HierExtractArg *ha; /* Context for hierarchical extraction */ { CellDef *oneDef, *cumDef = ha->ha_cumFlat.et_use->cu_def; ExtTree *oneFlat, *nextFlat; SearchContext scx; /* Copy parent paint into ha->ha_cumFlat (which was initially empty) */ scx.scx_trans = GeoIdentityTransform; scx.scx_area = ha->ha_interArea; scx.scx_use = ha->ha_parentUse; DBCellCopyPaint(&scx, &DBAllButSpaceBits, 0, ha->ha_cumFlat.et_use); #ifdef notdef extCopyPaint(ha->ha_parentUse->cu_def, &ha->ha_interArea, cumDef); #endif /* notdef */ /* * First element on the subtree list will be parent mask info. * Extract nodes and capacitors. Node names come from parent. */ oneFlat = extHierNewOne(); oneDef = oneFlat->et_use->cu_def; DBCellCopyPaint(&scx, &DBAllButSpaceBits, 0, oneFlat->et_use); #ifdef notdef extCopyPaint(ha->ha_parentUse->cu_def, &ha->ha_interArea, oneDef); #endif /* notdef */ oneFlat->et_nodes = extFindNodes(oneDef, &ha->ha_clipArea); if ((ExtOptions & (EXT_DOCOUPLING|EXT_DOADJUST)) == (EXT_DOCOUPLING|EXT_DOADJUST)) { HashInit(&oneFlat->et_coupleHash, 32, HashSize(sizeof (CoupleKey))); extFindCoupling(oneDef, &oneFlat->et_coupleHash, &ha->ha_clipArea); } oneFlat->et_lookNames = ha->ha_parentUse->cu_def; oneFlat->et_realuse = (CellUse *) NULL; extSubList = oneFlat; /* * Cumulative yank buffer names also come from parent. * Since we only mark nodes for use in naming on the first * pass, there's no need to extract nodes in ha_cumFlat * until we process the first subcell in extSubtreeFunc. */ ha->ha_cumFlat.et_nodes = (NodeRegion *) NULL; ha->ha_cumFlat.et_lookNames = ha->ha_parentUse->cu_def; extFirstPass = TRUE; /* * Process each subcell in the interaction area exactly once. * After processing each subcell, we reset ha->ha_cumFlat.et_nodes * to NULL. */ (void) DBCellSrArea(&scx, extSubtreeFunc, (ClientData) ha); if (ExtOptions & EXT_DOADJUST) { /* * Re-extract ha->ha_cumFlat, this time getting node capacitance, * perimeter, and area, and coupling capacitances between nodes. * Assign labels from cumDef's label list. * Don't reset ha_lookNames, since we still need to be able to * refer to nodes in the parent. */ ha->ha_cumFlat.et_nodes = extFindNodes(cumDef, &ha->ha_clipArea); ExtLabelRegions(cumDef, ExtCurStyle->exts_nodeConn, &(ha->ha_cumFlat.et_nodes), &ha->ha_clipArea); if (ExtOptions & EXT_DOCOUPLING) { HashInit(&ha->ha_cumFlat.et_coupleHash, 32, HashSize(sizeof(CoupleKey))); extFindCoupling(cumDef, &ha->ha_cumFlat.et_coupleHash, &ha->ha_clipArea); } /* Process all adjustments */ ha->ha_subUse = (CellUse *) NULL; extSubtreeAdjustInit(ha); for (oneFlat = extSubList; oneFlat; oneFlat = oneFlat->et_next) extHierAdjustments(ha, &ha->ha_cumFlat, oneFlat, &ha->ha_cumFlat); /* * Output adjustments to coupling capacitance. * The names output for coupling capacitors are those on the * label list for each node in the cumulative buffer. */ if (ExtOptions & EXT_DOCOUPLING) { extSubtreeOutputCoupling(ha); extCapHashKill(&ha->ha_cumFlat.et_coupleHash); } } /* Free the subtrees (this must happen after all adjustments are made) */ for (oneFlat = extSubList; oneFlat; oneFlat = nextFlat) nextFlat = oneFlat->et_next, extHierFreeOne(oneFlat); extSubList = (ExtTree *) NULL; /* * Done with the cumulative yank buffer for this interaction. * Free the list of nodes, the list of hierarchical labels * built when we yanked this def, and then erase all the paint * in the buffer. */ if (ha->ha_cumFlat.et_nodes) ExtFreeLabRegions((LabRegion *) ha->ha_cumFlat.et_nodes); ha->ha_cumFlat.et_nodes = (NodeRegion *) NULL; extHierFreeLabels(cumDef); DBCellClearDef(cumDef); } /* * ---------------------------------------------------------------------------- * * extSubtreeAdjustInit -- * * Initialize the node capacitance, perimeter, and area values in * all the Nodes in the HashTable ha->ha_connHash. The initial * values come from the NodeRegions in ha->ha_cumFlat.et_nodes, * which correspond to extracting the entire flattened interaction * area. We add these values to any already existing from a previous * interaction area in case there were any nodes that span the boundary * between two interaction areas. We will then call extHierAdjustments * to subtract away the extracted values in each of the individually * flattened subtrees. * * Results: * None. * * Side effects: * See above. * * Design notes: * We only need to update perimeter, area, or substrate capacitance * when nodes from different subtrees abut or overlap, i.e., connect. * These nodes have already been recorded in the table ha->ha_connHash * by extHierConnections(), so all we have to do is find the appropriate * entries in this table. * * Each NodeRegion in ha->ha_cumFlat contains a list of labels with * it. The first label in each list is guaranteed to correspond to * an entry in the table ha->ha_connHash if this node is a participant * in a connection, so we pass this label to HashFind to obtain the * appropriate Node. * * ---------------------------------------------------------------------------- */ void extSubtreeAdjustInit(ha) HierExtractArg *ha; { NodeRegion *np; NodeName *nn; int n; HashEntry *he; char *name; /* * Initialize the capacitance, perimeter, and area values * in the Nodes in the hash table ha->ha_connHash. */ for (np = ha->ha_cumFlat.et_nodes; np; np = np->nreg_next) { if ((name = extNodeName((LabRegion *) np)) && (he = HashLookOnly(&ha->ha_connHash, name)) && (nn = (NodeName *) HashGetValue(he))) { nn->nn_node->node_cap += np->nreg_cap; for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++) { nn->nn_node->node_pa[n].pa_perim += np->nreg_pa[n].pa_perim; nn->nn_node->node_pa[n].pa_area += np->nreg_pa[n].pa_area; } } } } /* * ---------------------------------------------------------------------------- * * extSubtreeOutputCoupling -- * * Output the coupling capacitance table built up by extFindCoupling(). * Each entry in the hash table is a capacitance between the pair of * nodes identified by he->h_key, an CoupleKey struct. Writes to the * FILE ha->ha_outf. * * Because it is possible that the coupled nodes aren't already named, * we have to call extSubtreeTileToNode() to find their actual names. * * Results: * None. * * Side effects: * See the comments above. * * ---------------------------------------------------------------------------- */ void extSubtreeOutputCoupling(ha) HierExtractArg *ha; { CapValue cap; CoupleKey *ck; HashEntry *he; Tile *tp; HashSearch hs; char *name; HashStartSearch(&hs); while (he = HashNext(&ha->ha_cumFlat.et_coupleHash, &hs)) { cap = extGetCapValue(he) / ExtCurStyle->exts_capScale; if (cap == 0) continue; ck = (CoupleKey *) he->h_key.h_words; tp = extNodeToTile(ck->ck_1, &ha->ha_cumFlat); name = extSubtreeTileToNode(tp, ck->ck_1->nreg_pnum, &ha->ha_cumFlat, ha, TRUE); fprintf(ha->ha_outf, "cap \"%s\" ", name); tp = extNodeToTile(ck->ck_2, &ha->ha_cumFlat); name = extSubtreeTileToNode(tp, ck->ck_2->nreg_pnum, &ha->ha_cumFlat, ha, TRUE); fprintf(ha->ha_outf, "\"%s\" %lg\n", name, cap); } } /* * ---------------------------------------------------------------------------- * * extSubtreeFunc -- * * Called once for each cell use that is a child of the parent def * being extracted. Yanks the subtree into a new ExtTree. Extract * connections between this subtree and ha->ha_cumFlat, then paint * the subtree into the cumulative buffer ha->ha_cumFlat and prepend * the subtree to extSubList. * * Results: * Always returns 2, to avoid further elements in arrays. * * Side effects: * Leaves ha->ha_cumFlat unextracted (all LabRegions free, * and ha->ha_cumFlat.et_nodes set to NULL). * See extHierConnections(). * * ---------------------------------------------------------------------------- */ int extSubtreeFunc(scx, ha) SearchContext *scx; HierExtractArg *ha; { CellUse *cumUse = ha->ha_cumFlat.et_use; CellUse *use = scx->scx_use; CellDef *oneDef; SearchContext newscx; ExtTree *oneFlat; HierYank hy; /* Allocate a new ExtTree to hold the flattened, extracted subtree */ oneFlat = extHierNewOne(); oneFlat->et_realuse = use; /* Record information for finding node names the hard way later */ ha->ha_subUse = use; /* * Yank all array elements of this subcell that lie in the interaction * area. Transform to parent coordinates. Prefix is true, meaning that * we should prefix each hierarchical name with the subcell use it * belongs to. */ ha->ha_subArea = use->cu_bbox; GEOCLIP(&ha->ha_subArea, &ha->ha_interArea); hy.hy_area = &ha->ha_subArea; hy.hy_target = oneFlat->et_use; hy.hy_prefix = TRUE; (void) DBArraySr(use, &ha->ha_subArea, extHierYankFunc, (ClientData) &hy); /* * Extract node capacitance, perimeter, area, and coupling capacitance * for this subtree. Labels come from the hierarchical labels yanked * above, but may have additional labels added when we find names the * hard way. */ oneDef = oneFlat->et_use->cu_def; oneFlat->et_nodes = extFindNodes(oneDef, &ha->ha_clipArea), ExtLabelRegions(oneDef, ExtCurStyle->exts_nodeConn, &(oneFlat->et_nodes), &ha->ha_clipArea); if ((ExtOptions & (EXT_DOCOUPLING|EXT_DOADJUST)) == (EXT_DOCOUPLING|EXT_DOADJUST)) extFindCoupling(oneDef, &oneFlat->et_coupleHash, &ha->ha_clipArea); /* * If this is not the first subcell we're processing, mark ha_cumFlat's * tiles with LabRegions. We don't mark it the first time through, * since then ha_cumFlat contains only the parent mask geometry and * node names will be found by looking in ha_lookNames. */ if (extFirstPass) { // On the first pass, run through et_lookName's label list. // Copy any sticky labels to cumUse->cu_def, so that the labels // can be found even when there is no geometry underneath in // the parent cell. CellDef *cumDef = ha->ha_cumFlat.et_lookNames; if (cumDef != NULL) { Label *lab, *newlab; unsigned int n; for (lab = cumDef->cd_labels; lab ; lab = lab->lab_next) { n = sizeof (Label) + strlen(lab->lab_text) - sizeof lab->lab_text + 1; newlab = (Label *)mallocMagic(n); newlab->lab_type = lab->lab_type; newlab->lab_rect = lab->lab_rect; newlab->lab_flags = lab->lab_flags; strcpy(newlab->lab_text, lab->lab_text); newlab->lab_next = cumUse->cu_def->cd_labels; cumUse->cu_def->cd_labels = newlab; } } extFirstPass = FALSE; } else { /* * We don't care about the lreg_ll or lreg_pNum for these * nodes (we're only interested in the label list associated * with each node), so we don't pass extHierLabEach() to * ExtFindRegions(). */ ha->ha_cumFlat.et_nodes = (NodeRegion *) ExtFindRegions(cumUse->cu_def, &TiPlaneRect, &DBAllButSpaceBits, ExtCurStyle->exts_nodeConn, extUnInit, extHierLabFirst, (int (*)()) NULL); ExtLabelRegions(cumUse->cu_def, ExtCurStyle->exts_nodeConn, &(ha->ha_cumFlat.et_nodes), &TiPlaneRect); } /* Process connections; this updates ha->ha_connHash */ extHierConnections(ha, &ha->ha_cumFlat, oneFlat); /* Free the cumulative node list we extracted above */ if (ha->ha_cumFlat.et_nodes) { ExtResetTiles(cumUse->cu_def, extUnInit); ExtFreeLabRegions((LabRegion *) ha->ha_cumFlat.et_nodes); ha->ha_cumFlat.et_nodes = (NodeRegion *) NULL; } /* * Paint the subtree buffer on top of the cumulative buffer. * Copy the labels that were yanked along with the subtree into * the cumulative buffer as well. */ newscx.scx_use = oneFlat->et_use; newscx.scx_area = ha->ha_subArea; newscx.scx_trans = GeoIdentityTransform; DBCellCopyPaint(&newscx, &DBAllButSpaceBits, 0, cumUse); #ifdef notdef extCopyPaint(oneFlat->et_use->cu_def, &ha->ha_subArea, cumUse->cu_def); #endif /* notdef */ extHierCopyLabels(oneFlat->et_use->cu_def, cumUse->cu_def); /* Prepend this tree to the list of trees we've processed so far */ oneFlat->et_next = extSubList; extSubList = oneFlat; return (2); } /* * ---------------------------------------------------------------------------- * * extSubtreeTileToNode -- * * Map from a Tile in a given yank buffer 'et' to the name of the node * containing that tile. * * The node associated with a tile can be determined in one of the * following ways: * * (1) Look for a label on the list of the Region pointed to by the * tile planes of the yank buffer. If no label was found, then * try (2). * * (2) If et->et_lookNames is non-NULL, see if the tile overlaps a * connected tile on the same plane of the def et->et_lookNames. * * (3) Call extSubtreeHardNode() to do a painful extraction of a label. * See the comments in extSubtreeHardNode() for a description of * the algorithm used. Only do this if doHard is TRUE. * * Results: * Returns a pointer to the name of the node containing * the tile. If no node name was found, and doHard was * TRUE, return the string "(none)"; if doHard was FALSE, * return NULL. * * Side effects: * The string returned is allocated from a static buffer, so * subsequent calls to extSubtreeTileToNode() will overwrite * the results returned in previous calls. * * Records an error with the feedback package if no node name * could be found and doHard was TRUE. * * ---------------------------------------------------------------------------- */ char * extSubtreeTileToNode(tp, pNum, et, ha, doHard) Tile *tp; /* Tile whose node name is to be found */ int pNum; /* Plane of the tile */ ExtTree *et; /* Yank buffer to search */ HierExtractArg *ha; /* Extraction context */ bool doHard; /* If TRUE, we look up this node's name the hard way * if we can't find it any other way; otherwise, we * return NULL if we can't find the node's name. */ { static char warningStr[] = "Warning: node labels should be inside overlap area"; static char errorStr[] = "Cannot find the name of this node (probable extractor error)"; CellDef *parentDef = ha->ha_parentUse->cu_def; LabRegion *reg; Label *lab; Rect r; TileType ttype; /* If there is a label list, use it */ if (extHasRegion(tp, extUnInit)) { reg = (LabRegion *) extGetRegion(tp); if (reg->lreg_labels) return (extNodeName(reg)); } /* * If there is any node at all in the cell et->et_lookNames, * use it. The node doesn't have to have a label list. */ TITORECT(tp, &r); if (et->et_lookNames) { /* * Make sure we've got a valid tile -- interactions with interrupts * can cause problems. */ if (IsSplit(tp)) { if (SplitSide(tp)) ttype = SplitRightType(tp); else ttype = SplitLeftType(tp); } else ttype = TiGetTypeExact(tp); if (pNum >= PL_PAINTBASE) { if (IsSplit(tp)) { if (DBSrPaintNMArea((Tile *) NULL, et->et_lookNames->cd_planes[pNum], TiGetTypeExact(tp), &r, &DBAllButSpaceBits, extConnFindFunc, (ClientData) ®)) { if (SigInterruptPending) return ("(none)"); return (extNodeName(reg)); } } else { if (DBSrPaintArea((Tile *) NULL, et->et_lookNames->cd_planes[pNum], &r, &DBAllButSpaceBits, extConnFindFunc, (ClientData) ®)) { if (SigInterruptPending) return ("(none)"); return (extNodeName(reg)); } } } } /* We have to do it the hard way */ if (!doHard) return ((char *) NULL); if (extHasRegion(tp, extUnInit) && (reg = extSubtreeHardNode(tp, pNum, et, ha))) { if (ExtDoWarn & EXTWARN_LABELS) { DBWFeedbackAdd(&r, warningStr, parentDef, 1, STYLE_PALEHIGHLIGHTS); extNumWarnings++; } return (extNodeName(reg)); } extNumFatal++; if (!DebugIsSet(extDebugID, extDebNoFeedback)) DBWFeedbackAdd(&r, errorStr, parentDef, 1, STYLE_MEDIUMHIGHLIGHTS); return ("(none)"); } /* * ---------------------------------------------------------------------------- * extConnFindFunc -- * * Called when searching the area of a tile in the def et->et_lookNames * by extSubtreeTileToNode() above. * * Results: * If we find a tile that has been marked with a node, * return 1; otherwise, return 0. * * Side effects: * Sets *preg to the node found if we returned 1; otherwise, * leaves *preg alone. * ---------------------------------------------------------------------------- */ int extConnFindFunc(tp, preg) Tile *tp; LabRegion **preg; { if (extHasRegion(tp, extUnInit)) { *preg = (LabRegion *) extGetRegion(tp); return (1); } return (0); } /* * ---------------------------------------------------------------------------- * * extSubtreeHardNode -- * * Find a node name for the electrical node containing the tile 'tp' * the hard way. We assume tp->ti_client points to a LabRegion that * had no labels associated with it; if we succeed, we leave this * LabRegion pointing to a newly allocated LabelList and Label. * * Results: * Returns a pointer to LabRegion for the node to which the tile * 'tp' belongs. Returns NULL if no region could be found. * * Side effects: * See above. * * Algorithm: * For each subcell of the parent that could have contributed * to the yank buffer in question, search the original tree * for geometry in the area of the tile 'tp'. For each cell * we find, we trace out just those nodes lying in the area * of the overlap, and then do a label assignment for those * nodes. As soon as we find a label, we're done. Otherwise, * we reset this def back the way we found it and continue on * to the next cell in our search. * * ---------------------------------------------------------------------------- */ LabRegion * extSubtreeHardNode(tp, pNum, et, ha) Tile *tp; int pNum; ExtTree *et; HierExtractArg *ha; { LabRegion *lreg = (LabRegion *) extGetRegion(tp); CellDef *def = et->et_use->cu_def; TileType ttype; char labelBuf[4096]; LabelList *ll; HardWay arg; ASSERT(lreg->lreg_labels == NULL, "extSubtreeHardNode"); if (IsSplit(tp)) { if (SplitSide(tp)) ttype = SplitRightType(tp); else ttype = SplitLeftType(tp); } else ttype = TiGetTypeExact(tp); arg.hw_ha = ha; arg.hw_label = (Label *) NULL; arg.hw_mask = DBPlaneTypes[pNum]; TTMaskAndMask(&arg.hw_mask, &DBConnectTbl[ttype]); arg.hw_tpath.tp_last = &labelBuf[sizeof labelBuf - 3]; arg.hw_tpath.tp_first = arg.hw_tpath.tp_next = labelBuf; arg.hw_prefix = TRUE; TITORECT(tp, &arg.hw_area); /* * Try to find a label in the area. * If we can't find a label, we make one up based on the * automatically generated node name in a child cell that * contains paint in this node. */ labelBuf[0] = '\0'; arg.hw_autogen = FALSE; extSubtreeHardSearch(et, &arg); if (arg.hw_label == NULL) { labelBuf[0] = '\0'; arg.hw_autogen = TRUE; extSubtreeHardSearch(et, &arg); } /* * If we succeeded (we always should), we now have a label. * Make the single LabelList for the region 'lreg' point to * this label, and prepend it to the list for 'def'. */ if (arg.hw_label) { ll = (LabelList *) mallocMagic((unsigned) (sizeof (LabelList))); lreg->lreg_labels = ll; ll->ll_next = (LabelList *) NULL; ll->ll_label = arg.hw_label; arg.hw_label->lab_next = def->cd_labels; def->cd_labels = arg.hw_label; return (lreg); } return ((LabRegion *) NULL); } /* * ---------------------------------------------------------------------------- * extSubtreeHardSearch -- * * Do the actual work of deciding which subtrees to search * for extSubtreeHardNode above. We apply the procedure * extHardProc() at each subcell. * ---------------------------------------------------------------------------- */ void extSubtreeHardSearch(et, arg) ExtTree *et; HardWay *arg; { HierExtractArg *ha = arg->hw_ha; ExtTree *oneFlat; arg->hw_proc = extHardProc; if (et == &ha->ha_cumFlat) { /* * Recursively search all children of parent up to, but not * including, ha->ha_subUse. Don't search parent paint. */ for (oneFlat = extSubList; oneFlat; oneFlat = oneFlat->et_next) { if (oneFlat->et_realuse) { if (DBArraySr(oneFlat->et_realuse, &arg->hw_area, extSubtreeHardUseFunc, (ClientData) arg)) { break; } } } } else { /* Recursively search only the elements of ha->ha_subUse */ (void) DBArraySr(ha->ha_subUse, &arg->hw_area, extSubtreeHardUseFunc, (ClientData) arg); } } /* * ---------------------------------------------------------------------------- * extSubtreeHardUseFunc -- * * When searching a subtree, this is called once for each element * in the array that is the root of the subtree. * * Results: * Returns 1 if we have successfully found a label, 0 if not * (return value of arg->hw_proc). * * Side effects: * Calls (*arg->hw_proc)(). * ---------------------------------------------------------------------------- */ int extSubtreeHardUseFunc(use, trans, x, y, arg) CellUse *use; /* Use that is the root of the subtree being searched */ Transform *trans; /* Transform from coordinates of use->cu_def to those * in use->cu_parent, for the array element (x, y). */ int x, y; /* Indices of this array element */ HardWay *arg; /* Context passed down to filter functions */ { SearchContext scx; Transform tinv; scx.scx_use = use; scx.scx_trans = *trans; scx.scx_x = x; scx.scx_y = y; GEOINVERTTRANS(trans, &tinv); GEOTRANSRECT(&tinv, &arg->hw_area, &scx.scx_area); return ((*arg->hw_proc)(&scx, arg)); } magic-8.0.210/Makefile0000664000175000001440000000721611640110341013111 0ustar timusers# # rcsid $Header: /usr/cvsroot/magic-8.0/Makefile,v 1.1.1.1 2008/02/03 20:43:49 tim Exp $ # MAGICDIR = . PROGRAMS = magic TECH = scmos LIBRARIES = database utils extflat MODULES = cmwind commands database dbwind debug drc extflat extract \ graphics netmenu plow resis select sim textio tiles utils \ windows wiring MAKEFLAGS = INSTALL_CAD_DIRS = windows doc ${TECH} include defs.mak all: $(ALL_TARGET) standard: @echo --- errors and warnings logged in file make.log @${MAKE} mains 2>&1 | tee -a make.log | egrep -i "(.c:|Stop.|---)" tcl: @echo --- errors and warnings logged in file make.log @${MAKE} tcllibrary 2>&1 | tee -a make.log | egrep -i "(.c:|Stop.|---)" force: clean all defs.mak: @echo No \"defs.mak\" file found. Run "configure" to make one. config: ${MAGICDIR}/configure tcllibrary: database/database.h modules @echo --- making Tcl shared libraries for dir in ${PROGRAMS}; do \ (cd $$dir && ${MAKE} tcl-main); done mains: database/database.h modules libs @echo --- making main programs for dir in ${PROGRAMS}; do \ (cd $$dir && ${MAKE} main); done database/database.h: database/database.h.in @echo --- making header file database/database.h ${SCRIPTS}/makedbh database/database.h.in database/database.h modules: @echo --- making modules for dir in ${MODULES} ${PROGRAMS}; do \ (cd $$dir && ${MAKE} module); done libs: @echo --- making libraries for dir in ${LIBRARIES}; do \ (cd $$dir && ${MAKE} lib); done depend: database/database.h ${RM} */Depend for dir in ${MODULES} ${UNUSED_MODULES} ${PROGRAMS}; do \ (cd $$dir && ${MAKE} depend); done install: $(INSTALL_TARGET) install-magic: @echo --- installing executable to $(DESTDIR)${BINDIR} @echo --- installing runtime files to $(DESTDIR)${LIBDIR} @${MAKE} install-real 2>&1 >> install.log install-real: install-dirs for dir in ${INSTALL_CAD_DIRS}; do \ (cd $$dir && ${MAKE} install); done for dir in ${PROGRAMS}; do \ (cd $$dir && ${MAKE} install); done install-tcl-dirs: ${MAGICDIR}/scripts/mkdirs $(DESTDIR)${BINDIR} $(DESTDIR)${MANDIR} \ $(DESTDIR)${SYSDIR} $(DESTDIR)${TCLDIR} $(DESTDIR)${TCLDIR}/bitmaps install-dirs: ${MAGICDIR}/scripts/mkdirs $(DESTDIR)${BINDIR} $(DESTDIR)${MANDIR} \ $(DESTDIR)${SYSDIR} $(DESTDIR)${SCMDIR} install-tcl: @echo --- installing executable to $(DESTDIR)${BINDIR} @echo --- installing runtime files to $(DESTDIR)${LIBDIR} @${MAKE} install-tcl-real 2>&1 >> install.log install-tcl-real: install-tcl-dirs for dir in ${INSTALL_CAD_DIRS} ${PROGRAMS}; do \ (cd $$dir && ${MAKE} install-tcl); done clean: for dir in ${MODULES} ${PROGRAMS} ${TECH} ${UNUSED_MODULES}; do \ (cd $$dir && ${MAKE} clean); done ${RM} *.tmp */*.tmp *.sav */*.sav *.log TAGS tags distclean: touch defs.mak @${MAKE} clean ${RM} defs.mak old.defs.mak ${MAGICDIR}/scripts/defs.mak ${RM} ${MAGICDIR}/scripts/default.conf ${RM} ${MAGICDIR}/scripts/config.log ${MAGICDIR}/scripts/config.status ${RM} scripts/magic.spec magic-`cat VERSION` magic-`cat VERSION`.tgz ${RM} *.log dist: ${RM} scripts/magic.spec magic-`cat VERSION` magic-`cat VERSION`.tgz sed -e /@VERSION@/s%@VERSION@%`cat VERSION`% \ scripts/magic.spec.in > scripts/magic.spec ln -nsf . magic-`cat VERSION` tar zchvf magic-`cat VERSION`.tgz --exclude CVS \ --exclude magic-`cat VERSION`/magic-`cat VERSION` \ --exclude magic-`cat VERSION`/magic-`cat VERSION`.tgz \ magic-`cat VERSION` clean-mains: for dir in ${PROGRAMS}; do \ (cd $$dir && ${RM} $$dir); done tags: ${RM} tags find . ${MODULES} ${PROGRAMS} -name "*.[ch]" -maxdepth 1 | xargs ctags -o tags TAGS: ${RM} TAGS find . ${MODULES} ${PROGRAMS} -name "*.[ch]" -maxdepth 1 | xargs etags -o TAGS magic-8.0.210/tiles/0000755000175000001440000000000012150000730012556 5ustar timusersmagic-8.0.210/tiles/tile.h0000644000175000001440000002406211410650645013706 0ustar timusers/* * tile.h -- * * Definitions of the basic tile structures * The definitions in this file are all that is visible to * the Ti (tile) modules. * * ********************************************************************* * * 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. * * ********************************************************************* * * rcsid "$Header: /usr/cvsroot/magic-8.0/tiles/tile.h,v 1.3 2010/06/24 12:37:57 tim Exp $" */ #ifndef _TILES_H #define _TILES_H #ifndef _MAGIC_H #include "utils/magic.h" #endif #ifndef _GEOMETRY_H #include "utils/geometry.h" #endif /* * A tile is the basic unit used for representing both space and * solid area in a plane. It has the following structure: * * RT * ^ * | * ------------------------- * | | ---> TR * | | * | | * | (lower left) | * BL <--- ------------------------- * | * v * LB * * The (x, y) coordinates of the lower left corner of the tile are stored, * along with four "corner stitches": RT, TR, BL, LB. * * Space tiles are distinguished at a higher level by having a distinguished * tile body. */ typedef struct tile { ClientData ti_body; /* Body of tile */ struct tile *ti_lb; /* Left bottom corner stitch */ struct tile *ti_bl; /* Bottom left corner stitch */ struct tile *ti_tr; /* Top right corner stitch */ struct tile *ti_rt; /* Right top corner stitch */ Point ti_ll; /* Lower left coordinate */ ClientData ti_client; /* This space for hire. Warning: the default * value for this field, to which all users * should return it when done, is CLNTDEFAULT * instead of NULL. */ } Tile; /* * The following macros make it appear as though both * the lower left and upper right coordinates of a tile * are stored inside it. */ #ifdef HAVE_SYS_MMAN_H #include #include /* This is an on-demand Free List management */ typedef Tile *TileStore; /* Page size is 4KB so we mmap a segment equal to 64 pages */ #define TILE_STORE_BLOCK_SIZE (4 * 1024 * 64) extern Tile *TileStoreFreeList; extern Tile *TileStoreFreeList_end; #endif /* HAVE_SYS_MMAN_H */ #define BOTTOM(tp) ((tp)->ti_ll.p_y) #define LEFT(tp) ((tp)->ti_ll.p_x) #define TOP(tp) (BOTTOM(RT(tp))) #define RIGHT(tp) (LEFT(TR(tp))) #define LB(tp) ((tp)->ti_lb) #define BL(tp) ((tp)->ti_bl) #define TR(tp) ((tp)->ti_tr) #define RT(tp) ((tp)->ti_rt) /* ----------------------- Tile planes -------------------------------- */ /* * A plane of tiles consists of the four special tiles needed to * surround all internal tiles on all sides. Logically, these * tiles appear as below, except for the fact that all are located * off at infinity. * * -------------------------------------- * |\ /| * | \ / | * | \ TOP / | * | \ / | * | \ / | * | -------------------------- | * | | | | * |LEFT | |RIGHT| * | | | | * | -------------------------- | * | / \ | * | / \ | * | / BOTTOM \ | * | / \ | * |/ \| * -------------------------------------- */ typedef struct { Tile *pl_left; /* Left pseudo-tile */ Tile *pl_top; /* Top pseudo-tile */ Tile *pl_right; /* Right pseudo-tile */ Tile *pl_bottom; /* Bottom pseudo-tile */ Tile *pl_hint; /* Pointer to a "hint" at which to * begin searching. */ } Plane; /* * The following coordinate, INFINITY, is used to represent a * tile location outside of the tile plane. * * It must be possible to represent INFINITY+1 as well as * INFINITY. * * Also, because locations involving INFINITY may be transformed, * it is desirable that additions and subtractions of small integers * from either INFINITY or MINFINITY not cause overflow. * * Consequently, we define INFINITY to be the largest integer * representable in wordsize - 2 bits. */ #undef INFINITY #define INFINITY ((1 << (8*sizeof (int) - 2)) - 4) #define MINFINITY (-INFINITY) /* CLIENTDEFAULT differs from MINFINITY on 64-bit systems, where it */ /* prevents problems arising from MINFINITY being two different values */ /* depending on whether it is cast into a 32 or a 64 bit word. */ #define CLIENTMAX (((pointertype)1 << (8 * sizeof(pointertype) - 2)) - 4) #define CLIENTDEFAULT (-CLIENTMAX) /* ------------------------ Flags, etc -------------------------------- */ #define BADTILE ((Tile *) -1) /* Invalid tile pointer */ /* ============== Function headers and external interface ============= */ /* * The following macros and procedures should be all that are * ever needed by modules other than the tile module. */ extern Plane *TiNewPlane(Tile *); extern void TiFreePlane(Plane *); extern void TiToRect(Tile *, Rect *); extern Tile *TiSplitX(Tile *, int); extern Tile *TiSplitY(Tile *, int); extern Tile *TiSplitX_Left(Tile *, int); extern Tile *TiSplitY_Bottom(Tile *, int); extern void TiJoinX(Tile *, Tile *, Plane *); extern void TiJoinY(Tile *, Tile *, Plane *); extern int TiSrArea(); extern Tile *TiSrPoint(Tile *, Plane *, Point *); #define TiBottom(tp) (BOTTOM(tp)) #define TiLeft(tp) (LEFT(tp)) #define TiTop(tp) (TOP(tp)) #define TiRight(tp) (RIGHT(tp)) /* * For the following to work, the caller must include database.h * (to get the definition of TileType). */ /* * Non-Manhattan split tiles are defined as follows: * d = SplitDirection, s = SplitSide * * d=1 d=0 * +---+ +---+ * |\XX| | /| * | \X| | /X| s=1 * | \| |/XX| * +---+ +---+ * 0x7 0x6 * * +---+ +---+ * |\ | |XX/| * |X\ | |X/ | s=0 * |XX\| |/ | * +---+ +---+ * 0x5 0x4 * */ #define TiGetType(tp) ((TileType)(spointertype)((tp)->ti_body) & TT_LEFTMASK) #define TiGetTypeExact(tp) ((TileType)(spointertype) (tp)->ti_body) #define SplitDirection(tp) ((TileType)(spointertype)((tp)->ti_body) & TT_DIRECTION ? 1 : 0) #define SplitSide(tp) ((TileType)(spointertype)((tp)->ti_body) & TT_SIDE ? 1 : 0) #define IsSplit(tp) ((TileType)(spointertype)((tp)->ti_body) & TT_DIAGONAL ? TRUE : FALSE) #define SplitLeftType(tp) ((TileType)(spointertype)((tp)->ti_body) & TT_LEFTMASK) #define SplitRightType(tp) (((TileType)(spointertype)((tp)->ti_body) & TT_RIGHTMASK) >> 14) #define SplitTopType(tp) (((TileType)(spointertype)((tp)->ti_body) & TT_DIRECTION) ? \ SplitRightType(tp) : SplitLeftType(tp)) #define SplitBottomType(tp) (((TileType)(spointertype)((tp)->ti_body) & TT_DIRECTION) ? \ SplitLeftType(tp) : SplitRightType(tp)) #define TiGetLeftType(tp) SplitLeftType(tp) #define TiGetRightType(tp) ((IsSplit(tp)) ? SplitRightType(tp) : TiGetType(tp)) #define TiGetTopType(tp) ((IsSplit(tp)) ? SplitTopType(tp) : TiGetType(tp)) #define TiGetBottomType(tp) ((IsSplit(tp)) ? SplitBottomType(tp) : TiGetType(tp)) #define TiGetBody(tp) ((tp)->ti_body) /* See diagnostic subroutine version in tile.c */ #define TiSetBody(tp, b) ((tp)->ti_body = (ClientData)(pointertype) (b)) #define TiGetClient(tp) ((tp)->ti_client) #define TiSetClient(tp,b) ((tp)->ti_client = (ClientData)(pointertype) (b)) Tile *TiAlloc(void); void TiFree(Tile *); #define EnclosePoint(tile,point) ((LEFT(tile) <= (point)->p_x ) && \ ((point)->p_x < RIGHT(tile)) && \ (BOTTOM(tile) <= (point)->p_y ) && \ ((point)->p_y < TOP(tile) )) #define EnclosePoint4Sides(tile,point) ((LEFT(tile) <= (point)->p_x ) && \ ((point)->p_x <= RIGHT(tile)) && \ (BOTTOM(tile) <= (point)->p_y ) && \ ((point)->p_y <= TOP(tile) )) /* The four macros below are for finding next tile RIGHT, UP, LEFT or DOWN * from current tile at a given coordinate value. * * For example, NEXT_TILE_RIGHT points tResult to tile to right of t * at y-coordinate y. */ #define NEXT_TILE_RIGHT(tResult, t, y) \ for ((tResult) = TR(t); BOTTOM(tResult) > (y); (tResult) = LB(tResult)) \ /* Nothing */; #define NEXT_TILE_UP(tResult, t, x) \ for ((tResult) = RT(t); LEFT(tResult) > (x); (tResult) = BL(tResult)) \ /* Nothing */; #define NEXT_TILE_LEFT(tResult, t, y) \ for ((tResult) = BL(t); TOP(tResult) <= (y); (tResult) = RT(tResult)) \ /* Nothing */; #define NEXT_TILE_DOWN(tResult, t, x) \ for ((tResult) = LB(t); RIGHT(tResult) <= (x); (tResult) = TR(tResult)) \ /* Nothing */; #define TiSrPointNoHint(plane, point) (TiSrPoint((Tile *) NULL, plane, point)) /* * GOTOPOINT is used whenever a macroized version of TiSrPoint is * needed. */ #define GOTOPOINT(tp, p) \ { \ if ((p)->p_y < BOTTOM(tp)) \ do tp = LB(tp); while ((p)->p_y < BOTTOM(tp)); \ else \ while ((p)->p_y >= TOP(tp)) tp = RT(tp); \ if ((p)->p_x < LEFT(tp)) \ do \ { \ do tp = BL(tp); while ((p)->p_x < LEFT(tp)); \ if ((p)->p_y < TOP(tp)) break; \ do tp = RT(tp); while ((p)->p_y >= TOP(tp)); \ } \ while ((p)->p_x < LEFT(tp)); \ else \ while ((p)->p_x >= RIGHT(tp)) \ { \ do tp = TR(tp); while ((p)->p_x >= RIGHT(tp)); \ if ((p)->p_y >= BOTTOM(tp)) break; \ do tp = LB(tp); while ((p)->p_y < BOTTOM(tp)); \ } \ } /* Fill in the bounding rectangle for a tile */ #define TITORECT(tp, rp) \ ((rp)->r_xbot = LEFT(tp), (rp)->r_ybot = BOTTOM(tp), \ (rp)->r_xtop = RIGHT(tp), (rp)->r_ytop = TOP(tp)) extern Rect TiPlaneRect; /* Rectangle large enough to force area * search to visit every tile in the * plane. This is the largest rectangle * that should ever be painted in a plane. */ #endif /* _TILES_H */ magic-8.0.210/tiles/tile.c0000664000175000001440000004765012150000730013675 0ustar timusers/* * tile.c -- * * Basic tile manipulation * * ********************************************************************* * * 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/tiles/tile.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include #include "utils/magic.h" #include "utils/malloc.h" #include "utils/geometry.h" #include "tiles/tile.h" /* * Debugging version of TiSetBody() macro in tile.h * Includes sanity check that a tile at "infinity" * is not being set to a type other than space. */ /* void TiSetBody(tp, b) Tile *tp; ClientData b; { if (b != (ClientData)0 && b != (ClientData)(-1)) if (RIGHT(tp) == INFINITY || TOP(tp) == INFINITY || LEFT(tp) == MINFINITY || BOTTOM(tp) == MINFINITY) TxError("Error: Tile at infinity set to non-space value %d\n", (int)b); tp->ti_body = b; } */ /* * Rectangle that defines the maximum extent of any plane. * No tile created by the user should ever extend outside of * this area. */ global Rect TiPlaneRect = { MINFINITY+2, MINFINITY+2, INFINITY-2, INFINITY-2 }; #ifdef HAVE_SYS_MMAN_H global Tile *TileStoreFreeList = NULL; global Tile *TileStoreFreeList_end = NULL; /* The new Tile Allocation scheme (Magic 8.0) */ static void *_block_begin = NULL; static void *_current_ptr = NULL; static void *_block_end = NULL; #endif /* HAVE_SYS_MMAN_H */ /* * -------------------------------------------------------------------- * * TiNewPlane -- * * Allocate and initialize a new tile plane. * * Results: * A newly allocated Plane with all corner stitches set * appropriately. * * Side effects: * Adjusts the corner stitches of the Tile supplied to * point to the appropriate bounding tile in the newly * created Plane. * * -------------------------------------------------------------------- */ Plane * TiNewPlane(tile) Tile *tile;/* Tile to become initial tile of plane. * May be NULL. */ { Plane *newplane; static Tile *infinityTile = (Tile *) NULL; newplane = (Plane *) mallocMagic((unsigned) (sizeof (Plane))); newplane->pl_top = TiAlloc(); newplane->pl_right = TiAlloc(); newplane->pl_bottom = TiAlloc(); newplane->pl_left = TiAlloc(); /* * Since the lower left coordinates of the TR and RT * stitches of a tile are used to determine its upper right, * we must give the boundary tiles a meaningful TR and RT. * To make certain that these tiles don't have zero width * or height, we use a dummy tile at (INFINITY+1,INFINITY+1). */ if (infinityTile == (Tile *) NULL) { infinityTile = TiAlloc(); LEFT(infinityTile) = INFINITY+1; BOTTOM(infinityTile) = INFINITY+1; } if (tile) { RT(tile) = newplane->pl_top; TR(tile) = newplane->pl_right; LB(tile) = newplane->pl_bottom; BL(tile) = newplane->pl_left; } LEFT(newplane->pl_bottom) = MINFINITY; BOTTOM(newplane->pl_bottom) = MINFINITY; RT(newplane->pl_bottom) = tile; TR(newplane->pl_bottom) = newplane->pl_right; LB(newplane->pl_bottom) = BADTILE; BL(newplane->pl_bottom) = newplane->pl_left; TiSetBody(newplane->pl_bottom, -1); LEFT(newplane->pl_top) = MINFINITY; BOTTOM(newplane->pl_top) = INFINITY; RT(newplane->pl_top) = infinityTile; TR(newplane->pl_top) = newplane->pl_right; LB(newplane->pl_top) = tile; BL(newplane->pl_top) = newplane->pl_left; TiSetBody(newplane->pl_top, -1); LEFT(newplane->pl_left) = MINFINITY; BOTTOM(newplane->pl_left) = MINFINITY; RT(newplane->pl_left) = newplane->pl_top; TR(newplane->pl_left) = tile; LB(newplane->pl_left) = newplane->pl_bottom; BL(newplane->pl_left) = BADTILE; TiSetBody(newplane->pl_left, -1); LEFT(newplane->pl_right) = INFINITY; BOTTOM(newplane->pl_right) = MINFINITY; RT(newplane->pl_right) = newplane->pl_top; TR(newplane->pl_right) = infinityTile; LB(newplane->pl_right) = newplane->pl_bottom; BL(newplane->pl_right) = tile; TiSetBody(newplane->pl_right, -1); newplane->pl_hint = tile; return (newplane); } /* * -------------------------------------------------------------------- * * TiFreePlane -- * * Free the storage associated with a tile plane. * Only the plane itself and its four border tiles are deallocated. * * Results: * None. * * Side effects: * Frees memory. * * -------------------------------------------------------------------- */ void TiFreePlane(plane) Plane *plane; /* Plane to be freed */ { TiFree(plane->pl_left); TiFree(plane->pl_right); TiFree(plane->pl_top); TiFree(plane->pl_bottom); freeMagic((char *) plane); } /* * -------------------------------------------------------------------- * * TiToRect -- * * Convert a tile to a rectangle. * * Results: * None. * * Side effects: * Sets *rect to the bounding box for the supplied tile. * * -------------------------------------------------------------------- */ void TiToRect(tile, rect) Tile *tile; /* Tile whose bounding box is to be stored in *rect */ Rect *rect; /* Pointer to rect to be set to bounding box */ { rect->r_xbot = LEFT(tile); rect->r_xtop = RIGHT(tile); rect->r_ybot = BOTTOM(tile); rect->r_ytop = TOP(tile); } /* * -------------------------------------------------------------------- * * TiSplitX -- * * Given a tile and an X coordinate, split the tile into two * along a line running vertically through the given coordinate. * * Results: * Returns the new tile resulting from the splitting, which * is the tile occupying the right-hand half of the original * tile. * * Side effects: * Modifies the corner stitches in the database to reflect * the presence of two tiles in place of the original one. * * -------------------------------------------------------------------- */ Tile * TiSplitX(tile, x) Tile *tile; /* Tile to be split */ int x; /* X coordinate of split */ { Tile *newtile; Tile *tp; ASSERT(x > LEFT(tile) && x < RIGHT(tile), "TiSplitX"); newtile = TiAlloc(); TiSetClient(newtile, CLIENTDEFAULT); TiSetBody(newtile, 0); LEFT(newtile) = x; BOTTOM(newtile) = BOTTOM(tile); BL(newtile) = tile; TR(newtile) = TR(tile); RT(newtile) = RT(tile); /* * Adjust corner stitches along the right edge */ for (tp = TR(tile); BL(tp) == tile; tp = LB(tp)) BL(tp) = newtile; TR(tile) = newtile; /* * Adjust corner stitches along the top edge */ for (tp = RT(tile); LEFT(tp) >= x; tp = BL(tp)) LB(tp) = newtile; RT(tile) = tp; /* * Adjust corner stitches along the bottom edge */ for (tp = LB(tile); RIGHT(tp) <= x; tp = TR(tp)) /* nothing */; LB(newtile) = tp; while (RT(tp) == tile) { RT(tp) = newtile; tp = TR(tp); } return (newtile); } /* * -------------------------------------------------------------------- * * TiSplitY -- * * Given a tile and a Y coordinate, split the tile into two * along a horizontal line running through the given coordinate. * * Results: * Returns the new tile resulting from the splitting, which * is the tile occupying the top half of the original * tile. * * Side effects: * Modifies the corner stitches in the database to reflect * the presence of two tiles in place of the original one. * * -------------------------------------------------------------------- */ Tile * TiSplitY(tile, y) Tile *tile; /* Tile to be split */ int y; /* Y coordinate of split */ { Tile *newtile; Tile *tp; ASSERT(y > BOTTOM(tile) && y < TOP(tile), "TiSplitY"); newtile = TiAlloc(); TiSetClient(newtile, CLIENTDEFAULT); TiSetBody(newtile, 0); LEFT(newtile) = LEFT(tile); BOTTOM(newtile) = y; LB(newtile) = tile; RT(newtile) = RT(tile); TR(newtile) = TR(tile); /* * Adjust corner stitches along top edge */ for (tp = RT(tile); LB(tp) == tile; tp = BL(tp)) LB(tp) = newtile; RT(tile) = newtile; /* * Adjust corner stitches along right edge */ for (tp = TR(tile); BOTTOM(tp) >= y; tp = LB(tp)) BL(tp) = newtile; TR(tile) = tp; /* * Adjust corner stitches along left edge */ for (tp = BL(tile); TOP(tp) <= y; tp = RT(tp)) /* nothing */; BL(newtile) = tp; while (TR(tp) == tile) { TR(tp) = newtile; tp = RT(tp); } return (newtile); } /* * -------------------------------------------------------------------- * * TiSplitX_Left -- * * Given a tile and an X coordinate, split the tile into two * along a line running vertically through the given coordinate. * Intended for use when plowing to the left. * * Results: * Returns the new tile resulting from the splitting, which * is the tile occupying the left-hand half of the original * tile. * * Side effects: * Modifies the corner stitches in the database to reflect * the presence of two tiles in place of the original one. * * -------------------------------------------------------------------- */ Tile * TiSplitX_Left(tile, x) Tile *tile; /* Tile to be split */ int x; /* X coordinate of split */ { Tile *newtile; Tile *tp; ASSERT(x > LEFT(tile) && x < RIGHT(tile), "TiSplitX"); newtile = TiAlloc(); TiSetClient(newtile, CLIENTDEFAULT); TiSetBody(newtile, 0); LEFT(newtile) = LEFT(tile); LEFT(tile) = x; BOTTOM(newtile) = BOTTOM(tile); BL(newtile) = BL(tile); LB(newtile) = LB(tile); TR(newtile) = tile; BL(tile) = newtile; /* Adjust corner stitches along the left edge */ for (tp = BL(newtile); TR(tp) == tile; tp = RT(tp)) TR(tp) = newtile; /* Adjust corner stitches along the top edge */ for (tp = RT(tile); LEFT(tp) >= x; tp = BL(tp)) /* nothing */; RT(newtile) = tp; for ( ; LB(tp) == tile; tp = BL(tp)) LB(tp) = newtile; /* Adjust corner stitches along the bottom edge */ for (tp = LB(tile); RIGHT(tp) <= x; tp = TR(tp)) RT(tp) = newtile; LB(tile) = tp; return (newtile); } /* * -------------------------------------------------------------------- * * TiSplitY_Bottom -- * * Given a tile and a Y coordinate, split the tile into two * along a horizontal line running through the given coordinate. * Used when plowing down. * * Results: * Returns the new tile resulting from the splitting, which * is the tile occupying the bottom half of the original * tile. * * Side effects: * Modifies the corner stitches in the database to reflect * the presence of two tiles in place of the original one. * * -------------------------------------------------------------------- */ Tile * TiSplitY_Bottom(tile, y) Tile *tile; /* Tile to be split */ int y; /* Y coordinate of split */ { Tile *newtile; Tile *tp; ASSERT(y > BOTTOM(tile) && y < TOP(tile), "TiSplitY"); newtile = TiAlloc(); TiSetClient(newtile, CLIENTDEFAULT); TiSetBody(newtile, 0); LEFT(newtile) = LEFT(tile); BOTTOM(newtile) = BOTTOM(tile); BOTTOM(tile) = y; RT(newtile) = tile; LB(newtile) = LB(tile); BL(newtile) = BL(tile); LB(tile) = newtile; /* Adjust corner stitches along bottom edge */ for (tp = LB(newtile); RT(tp) == tile; tp = TR(tp)) RT(tp) = newtile; /* Adjust corner stitches along right edge */ for (tp = TR(tile); BOTTOM(tp) >= y; tp = LB(tp)) /* nothing */; TR(newtile) = tp; for ( ; BL(tp) == tile; tp = LB(tp)) BL(tp) = newtile; /* Adjust corner stitches along left edge */ for (tp = BL(tile); TOP(tp) <= y; tp = RT(tp)) TR(tp) = newtile; BL(tile) = tp; return (newtile); } /* * -------------------------------------------------------------------- * * TiJoinX -- * * Given two tiles sharing an entire common vertical edge, replace * them with a single tile occupying the union of their areas. * * Results: * None. * * Side effects: * The first tile is simply relinked to reflect its new size. * The second tile is deallocated. Corner stitches in the * neighboring tiles are updated to reflect the new structure. * If the hint tile pointer in the supplied plane pointed to * the second tile, it is adjusted to point instead to the * first. * * -------------------------------------------------------------------- */ void TiJoinX(tile1, tile2, plane) Tile *tile1; /* First tile, remains allocated after call */ Tile *tile2; /* Second tile, deallocated by call */ Plane *plane; /* Plane in which hint tile is updated */ { Tile *tp; /* * Basic algorithm: * * Update all the corner stitches in the neighbors of tile2 * to point to tile1. * Update the corner stitches of tile1 along the shared edge * to be those of tile2. * Change the bottom or left coordinate of tile1 if appropriate. * Deallocate tile2. */ ASSERT(BOTTOM(tile1)==BOTTOM(tile2) && TOP(tile1)==TOP(tile2), "TiJoinX"); ASSERT(LEFT(tile1)==RIGHT(tile2) || RIGHT(tile1)==LEFT(tile2), "TiJoinX"); /* * Update stitches along top of tile */ for (tp = RT(tile2); LB(tp) == tile2; tp = BL(tp)) LB(tp) = tile1; /* * Update stitches along bottom of tile */ for (tp = LB(tile2); RT(tp) == tile2; tp = TR(tp)) RT(tp) = tile1; /* * Update stitches along either left or right, depending * on relative position of the two tiles. */ ASSERT(LEFT(tile1) != LEFT(tile2), "TiJoinX"); if (LEFT(tile1) < LEFT(tile2)) { for (tp = TR(tile2); BL(tp) == tile2; tp = LB(tp)) BL(tp) = tile1; TR(tile1) = TR(tile2); RT(tile1) = RT(tile2); } else { for (tp = BL(tile2); TR(tp) == tile2; tp = RT(tp)) TR(tp) = tile1; BL(tile1) = BL(tile2); LB(tile1) = LB(tile2); LEFT(tile1) = LEFT(tile2); } if (plane->pl_hint == tile2) plane->pl_hint = tile1; TiFree(tile2); } /* * -------------------------------------------------------------------- * * TiJoinY -- * * Given two tiles sharing an entire common horizontal edge, replace * them with a single tile occupying the union of their areas. * * Results: * None. * * Side effects: * The first tile is simply relinked to reflect its new size. * The second tile is deallocated. Corner stitches in the * neighboring tiles are updated to reflect the new structure. * If the hint tile pointer in the supplied plane pointed to * the second tile, it is adjusted to point instead to the * first. * * -------------------------------------------------------------------- */ void TiJoinY(tile1, tile2, plane) Tile *tile1; /* First tile, remains allocated after call */ Tile *tile2; /* Second tile, deallocated by call */ Plane *plane; /* Plane in which hint tile is updated */ { Tile *tp; /* * Basic algorithm: * * Update all the corner stitches in the neighbors of tile2 * to point to tile1. * Update the corner stitches of tile1 along the shared edge * to be those of tile2. * Change the bottom or left coordinate of tile1 if appropriate. * Deallocate tile2. */ ASSERT(LEFT(tile1)==LEFT(tile2) && RIGHT(tile1)==RIGHT(tile2), "TiJoinY"); ASSERT(TOP(tile1)==BOTTOM(tile2) || BOTTOM(tile1)==TOP(tile2), "TiJoinY"); /* * Update stitches along right of tile. */ for (tp = TR(tile2); BL(tp) == tile2; tp = LB(tp)) BL(tp) = tile1; /* * Update stitches along left of tile. */ for (tp = BL(tile2); TR(tp) == tile2; tp = RT(tp)) TR(tp) = tile1; /* * Update stitches along either top or bottom, depending * on relative position of the two tiles. */ ASSERT(BOTTOM(tile1) != BOTTOM(tile2), "TiJoinY"); if (BOTTOM(tile1) < BOTTOM(tile2)) { for (tp = RT(tile2); LB(tp) == tile2; tp = BL(tp)) LB(tp) = tile1; RT(tile1) = RT(tile2); TR(tile1) = TR(tile2); } else { for (tp = LB(tile2); RT(tp) == tile2; tp = TR(tp)) RT(tp) = tile1; LB(tile1) = LB(tile2); BL(tile1) = BL(tile2); BOTTOM(tile1) = BOTTOM(tile2); } if (plane->pl_hint == tile2) plane->pl_hint = tile1; TiFree(tile2); } #ifdef HAVE_SYS_MMAN_H /* MMAP the tile store */ static signed char mmapTileStore() { int prot = PROT_READ | PROT_WRITE; int flags = MAP_ANON | MAP_PRIVATE; unsigned long map_len = TILE_STORE_BLOCK_SIZE; _block_begin = mmap(NULL, map_len, prot, flags, -1, 0); if (_block_begin == MAP_FAILED) { TxError("TileStore: Unable to mmap ANON SEGMENT\n"); _exit(1); } _block_end = (void *) ((unsigned long) _block_begin + map_len); _current_ptr = _block_begin; return 0; } Tile * getTileFromTileStore() { Tile *_return_tile = NULL; if (!_block_begin && !_block_end) { mmapTileStore(); } /* Check if we can get the tile from the * Free list */ if (TileStoreFreeList) { _return_tile = TileStoreFreeList; TileStoreFreeList = (Tile *)TileStoreFreeList->ti_client; return _return_tile; } /* Get it from the mmap */ if (((unsigned long)_current_ptr + sizeof(Tile)) > (unsigned long)_block_end) { mmapTileStore(); } _current_ptr = (void *)((unsigned long)_current_ptr + sizeof(Tile)); if ((unsigned long)_current_ptr > (unsigned long) _block_end) { fprintf(stderr,"TileStore: internal assertion failure..."); _exit(1); } return (Tile *)((unsigned long)_current_ptr - sizeof(Tile)); } static void TileStoreFree(ptr) Tile *ptr; { if (!TileStoreFreeList_end || !TileStoreFreeList) { TileStoreFreeList_end = ptr; ptr->ti_client = (unsigned long)0; TileStoreFreeList = TileStoreFreeList_end; } else { TileStoreFreeList_end->ti_client = (unsigned long)ptr; TileStoreFreeList_end = ptr; TileStoreFreeList_end->ti_client = (unsigned long) 0; } } Tile * TiAlloc() { Tile *newtile; newtile = getTileFromTileStore(); TiSetClient(newtile, CLIENTDEFAULT); TiSetBody(newtile, 0); return (newtile); } void TiFree(tp) Tile *tp; { TileStoreFree(tp); } #else /* * -------------------------------------------------------------------- * * TiAlloc --- * * Memory allocation for tiles * * Results: * Pointer to an initialized memory location for a tile. * * -------------------------------------------------------------------- */ Tile * TiAlloc() { Tile *newtile; newtile = (Tile *) mallocMagic((unsigned) (sizeof (Tile))); TiSetClient(newtile, CLIENTDEFAULT); TiSetBody(newtile, 0); return (newtile); } /* * -------------------------------------------------------------------- * * TiFree --- * * Release memory allocation for tiles * * Results: * None. * * -------------------------------------------------------------------- */ void TiFree(tp) Tile *tp; { freeMagic((char *)tp); } #endif /* !HAVE_SYS_MMAN_H */ /* ==================================================================== */ /* */ /* DEBUGGING PROCEDURES */ /* */ /* ==================================================================== */ void tiPrint(tp) Tile *tp; { printf("tp=%p LL=(%d,%d) body=0x%"DLONG_PREFIX"x\n", tp, LEFT(tp), BOTTOM(tp), (dlong) tp->ti_body); printf("BL=%p LB=%p RT=%p TR=%p\n", BL(tp), LB(tp), RT(tp), TR(tp)); } void tiPrintAll(tp) Tile *tp; { tiPrint(tp); printf("UR=(%d,%d)\n", RIGHT(tp), TOP(tp)); /* The following is for plowing debugging */ printf("LEAD=%d\n", (int) tp->ti_client); } magic-8.0.210/tiles/Makefile0000644000175000001440000000035210751423606014236 0ustar timusers# # rcsid "$Header: /usr/cvsroot/magic-8.0/tiles/Makefile,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $" # MODULE = tiles MAGICDIR = .. SRCS = tile.c search.c search2.c include ${MAGICDIR}/defs.mak include ${MAGICDIR}/rules.mak magic-8.0.210/tiles/search.c0000644000175000001440000000404210751423606014207 0ustar timusers/* * search.c -- * * Point searching. * * ********************************************************************* * * 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/tiles/search.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" /* * -------------------------------------------------------------------- * * TiSrPoint -- * * Search for a point. * * Results: * A pointer to the tile containing the point. * The bottom and left edge of a tile are considered part of * the tile; the top and right edge are not. * * Side effects: * Updates the hint tile in the supplied plane to point * to the tile found. * * -------------------------------------------------------------------- */ Tile * TiSrPoint(hintTile, plane, point) Tile * hintTile; /* Pointer to tile at which to begin search. * If this is NULL, use the hint tile stored * with the plane instead. */ Plane * plane; /* Plane (containing hint tile pointer) */ Point * point; /* Point for which to search */ { Tile *tp = (hintTile) ? hintTile : plane->pl_hint; GOTOPOINT(tp, point); plane->pl_hint = tp; return(tp); } magic-8.0.210/tiles/search2.c0000644000175000001440000001646410751423606014304 0ustar timusers/* * search2.c -- * * Area searching. * * ********************************************************************* * * 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/tiles/search2.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/signals.h" /* -------------------- Local function headers ------------------------ */ int tiSrAreaEnum(); /* * -------------------------------------------------------------------- * * TiSrArea -- * * Find all tiles contained in or incident upon a given area. * Applies the given procedure to all tiles found. The procedure * should be of the following form: * * int * func(tile, cdata) * Tile *tile; * ClientData cdata; * { * } * * Func normally should return 0. If it returns 1 then the search * will be aborted. * * THIS PROCEDURE IS OBSOLETE EXCEPT FOR THE SUBCELL PLANE. USE * DBSrPaintArea() IF YOU WANT TO SEARCH FOR PAINT TILES. * * Results: * 0 is returned if the search completed normally. 1 is returned * if it aborted. * * Side effects: * Whatever side effects result from application of the * supplied procedure. * * NOTE: * The procedure called is free to do anything it wishes to tiles * which have already been visited in the area search, but it must * not affect anything about tiles not visited other than possibly * corner stitches to tiles already visited. * * ************************************************************************* * ************************************************************************* * **** **** * **** WARNING **** * **** **** * **** This code is INCREDIBLY sensitive to modification! **** * **** Change it only with the utmost caution, or you'll **** * **** be verrry sorry! **** * **** **** * ************************************************************************* * ************************************************************************* * * -------------------------------------------------------------------- */ int TiSrArea(hintTile, plane, rect, func, arg) Tile *hintTile; /* Tile at which to begin search, if not NULL. * If this is NULL, use the hint tile supplied * with plane. */ Plane *plane; /* Plane in which tiles lie. This is used to * provide a hint tile in case hintTile == NULL. * The hint tile in the plane is updated to be * the last tile visited in the area enumeration. */ Rect *rect;/* Area to search */ int (*func)(); /* Function to apply at each tile */ ClientData arg; /* Additional argument to pass to (*func)() */ { Point here; Tile *tp, *enumTR, *enumTile; int enumRight, enumBottom; /* * We will scan from top to bottom along the left hand edge * of the search area, searching for tiles. Each tile we * find in this search will be enumerated. */ here.p_x = rect->r_xbot; here.p_y = rect->r_ytop - 1; enumTile = hintTile ? hintTile : plane->pl_hint; GOTOPOINT(enumTile, &here); plane->pl_hint = enumTile; while (here.p_y >= rect->r_ybot) { if (SigInterruptPending) return 1; /* * Find the tile (tp) immediately below the one to be * enumerated (enumTile). This must be done before we enumerate * the tile, as the filter function applied to enumerate * it can result in its deallocation or modification in * some other way. */ here.p_y = BOTTOM(enumTile) - 1; tp = enumTile; GOTOPOINT(tp, &here); plane->pl_hint = tp; enumRight = RIGHT(enumTile); enumBottom = BOTTOM(enumTile); enumTR = TR(enumTile); if ((*func)(enumTile, arg)) return 1; /* * If the right boundary of the tile being enumerated is * inside of the search area, recursively enumerate * tiles to its right. */ if (enumRight < rect->r_xtop) if (tiSrAreaEnum(enumTR, enumBottom, rect, func, arg)) return 1; enumTile = tp; } return 0; } /* * -------------------------------------------------------------------- * * tiSrAreaEnum -- * * Perform the recursive edge search of the tile which has just been * enumerated in an area search. The arguments passed are the RT * corner stitch and bottom coordinate of the tile just enumerated. * * Results: * 0 is returned if the search completed normally, 1 if * it was aborted. * * Side effects: * Attempts to enumerate recursively each tile found in walking * along the right edge of the tile just enumerated. Whatever * side effects occur result from the application of the client's * filter function. * * -------------------------------------------------------------------- */ int tiSrAreaEnum(enumRT, enumBottom, rect, func, arg) Tile *enumRT; /* TR corner stitch of tile just enumerated */ int enumBottom; /* Bottom coordinate of tile just enumerated */ Rect *rect; /* Area to search */ int (*func)(); /* Function to apply at each tile */ ClientData arg; /* Additional argument to pass to (*func)() */ { Tile *tp, *tpLB, *tpTR; int tpRight, tpNextTop, tpBottom, srchBottom; int atBottom = (enumBottom <= rect->r_ybot); /* * Begin examination of tiles along right edge. * A tile to the right of the one being enumerated is enumerable if: * - its bottom lies at or above that of the tile being enumerated, or, * - the bottom of the tile being enumerated lies at or below the * bottom of the search rectangle. */ if ((srchBottom = enumBottom) < rect->r_ybot) srchBottom = rect->r_ybot; for (tp = enumRT, tpNextTop = TOP(tp); tpNextTop > srchBottom; tp = tpLB) { if (SigInterruptPending) return 1; /* * Since the client's filter function may result in this tile * being deallocated or otherwise modified, we must extract * all the information we will need from the tile before we * apply the filter function. */ tpLB = LB(tp); tpNextTop = TOP(tpLB); /* Since TOP(tpLB) comes from tp */ if (BOTTOM(tp) < rect->r_ytop && (atBottom || BOTTOM(tp) >= enumBottom)) { /* * We extract more information from the tile, which we will use * after applying the filter function. */ tpRight = RIGHT(tp); tpBottom = BOTTOM(tp); tpTR = TR(tp); if ((*func)(tp, arg)) return 1; /* * If the right boundary of the tile being enumerated is * inside of the search area, recursively enumerate * tiles to its right. */ if (tpRight < rect->r_xtop) if (tiSrAreaEnum(tpTR, tpBottom, rect, func, arg)) return 1; } } return 0; } magic-8.0.210/INSTALL0000644000175000001440000000505410751423605012512 0ustar timusersAutoconf Capsule Summary: ---------------------------------------- Compile and install: ./configure [options] make make install Autoconf options (use "./configure --help" for a complete list): --prefix=DIR Indicates the install directory. Determines the install directory of the executable. Determines the install directory of the libraries (${prefix}/lib) unless use of "--libdir=DIR" overrides it. Defaults to /usr/local/. --libdir=DIR By default, ${prefix}/lib/. Otherwise, run-time files used by magic are installed here, and ${CAD_ROOT} is set to DIR. In some distributions, this is set to /usr/share/. --with-interpreter=ARG Enable one of the two interpreters. ARG may be one of "tcl" or "scheme". --with-tcl Equivalent to "--with-interpreter=tcl". Normally enabled, if available. --with-opengl Enable OpenGL as a graphics option. Normally enabled, if available. --without-x Disable X11 as a graphics option. Normally enabled. --disable-nonmanhattan Disable non-Manhattan extensions. Normally enabled. --disable-readline Disable the GNU "readline" package. Normally enabled. --disable-threads Disable threaded X11 and OpenGL graphics. Normally enabled. Notes to Magic maintainers: -------------------------- This directory contains all the sources for the Magic system and related programs. The system runs on a number of machines. You should read the Magic Maintainer's manual as well as the introduction to Magic before compiling the system. These documents are in the "doc" subdirectory in PostScript, as well as the original LaTeX source. The "proper" way to profile the amount of CPU time spent in each procedure is to edit "defs.mak" and add flag "-pg" to CFLAGS. Then recompile, install, and run. Note that this doesn't work with the Tcl version; you have to compile the standalone version. After running, magic creates a file "gmon.out". To view the contents, run "gprof /usr/local/bin/magic > gprof.out" (the output can be very long). Memory tracing in Tcl requires that Tcl and Tk be compiled with the TCL_MEM_DEBUG option. Magic also must be compiled with TCL_MEM_DEBUG, which can be done by adding the definition -DTCL_MEM_DEBUG to DFLAGS in defs.mak, after running "configure". Magic is normally compiled without the optimization flag. This is handled by explicitly setting CFLAGS as an environment variable in the top-level "configure" script prior to calling scripts/configure. The top-level configure script needs to be modified to enable compile-time optimization. magic-8.0.210/wiring/0000755000175000001440000000000011504623600012746 5ustar timusersmagic-8.0.210/wiring/wireTech.c0000644000175000001440000001260111202560467014672 0ustar timusers/* * wireTech.c -- * * This file contains procedures that parse the wiring sections of * technology files. * * ********************************************************************* * * 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/wiring/wireTech.c,v 1.2 2009/05/13 15:03:19 tim Exp $"; #endif /* not lint */ #include #include #include #include "utils/magic.h" #include "utils/utils.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/tech.h" #include "wiring/wiring.h" #include "utils/malloc.h" /* Linked list to store contact information collected by this module: */ Contact *WireContacts; /* * ---------------------------------------------------------------------------- * WireTechInit -- * * Called once at beginning of technology file read-in to initialize * data structures. * * Results: * None. * * Side effects: * Clears out the contact table. * ---------------------------------------------------------------------------- */ void WireTechInit() { Contact *contact; int i; while (WireContacts != NULL) { freeMagic((char *) WireContacts); WireContacts = WireContacts->con_next; } } /* * ---------------------------------------------------------------------------- * WireTechLine -- * * This procedure is invoked by the technology module once for * each line in the "wiring" 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 contact table, prints error messages if necessary. * ---------------------------------------------------------------------------- */ /* ARGSUSED */ bool WireTechLine(sectionName, argc, argv) char *sectionName; /* Name of this section (unused). */ int argc; /* Number of arguments on line. */ char *argv[]; /* Pointers to fields of line. */ { Contact *new; if (strcmp(argv[0], "contact") != 0) { TechError("Unknown wiring keyword: %s. Line ignored.\n", argv[0]); return TRUE; } if (argc != 7) { TechError("\"contact\" lines must have exactly 7 arguments.\n"); return TRUE; } new = (Contact *) mallocMagic(sizeof(Contact)); new->con_type = DBTechNoisyNameType(argv[1]); new->con_layer1 = DBTechNoisyNameType(argv[3]); new->con_layer2 = DBTechNoisyNameType(argv[5]); if ((new->con_type < 0) || (new->con_layer1 < 0) || (new->con_layer2 < 0)) { errorReturn: freeMagic((char *) new); return TRUE; } if (!StrIsInt(argv[2])) { TechError("3rd field must be an integer.\n"); goto errorReturn; } else new->con_size = atoi(argv[2]); if (!StrIsInt(argv[4])) { TechError("5th field must be an integer.\n"); goto errorReturn; } else new->con_surround1 = atoi(argv[4]); if (!StrIsInt(argv[6])) { TechError("6th field must be an integer.\n"); goto errorReturn; } else new->con_surround2 = atoi(argv[6]); new->con_next = WireContacts; WireContacts = new; return TRUE; } /* * ---------------------------------------------------------------------------- * WireTechFinal -- * * This procedure is called by the technology module after all the * lines of the tech file have been read. It doesn't do anything * right now. * * Results: * None. * * Side effects: * None. * ---------------------------------------------------------------------------- */ void WireTechFinal() { /* Debugging code to print info about layers: */ /* Contact *con; for (con = WireContacts; con != NULL; con = con->con_next) { TxPrintf("Contact type \"%s\", size %d connects\n", DBTypeLongName(con->con_type), con->con_size); TxPrintf(" \"%s\" (overlap %d) and\n", DBTypeLongName(con->con_layer1), con->con_surround1); TxPrintf(" \"%s\" (overlap %d)\n", DBTypeLongName(con->con_layer2), con->con_surround2); } */ } /* *---------------------------------------------------------------------------- * WireTechScale -- * * Change parameters of the wiring section as required when * redefining magic's internal grid relative to the technology lambda. * *---------------------------------------------------------------------------- */ void WireTechScale(scalen, scaled) int scalen, scaled; { Contact *con; for (con = WireContacts; con != NULL; con = con->con_next) { con->con_size *= scaled; con->con_size /= scalen; con->con_surround1 *= scaled; con->con_surround1 /= scalen; con->con_surround2 *= scaled; con->con_surround2 /= scalen; } } magic-8.0.210/wiring/Makefile0000644000175000001440000000036010751423606014414 0ustar timusers# # rcsid $Header: /usr/cvsroot/magic-8.0/wiring/Makefile,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ # MODULE = wiring MAGICDIR = .. SRCS = wireOps.c wireTech.c wireUndo.c include ${MAGICDIR}/defs.mak include ${MAGICDIR}/rules.mak magic-8.0.210/wiring/wireInt.h0000644000175000001440000000261510751423606014553 0ustar timusers/* * wireInt.h -- * * Contains definitions for things that are used by more than * one file in the wiring module, but aren't exported. * * ********************************************************************* * * 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. * * ********************************************************************* * * rcsid $Header: /usr/cvsroot/magic-8.0/wiring/wireInt.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ */ #ifndef _WIREINT_H #define _WIREINT_H #include "utils/magic.h" #include "database/database.h" /* Undo-able wiring parameters: */ extern TileType WireType; extern int WireWidth; extern int WireLastDir; /* Undo procedure: */ extern void WireRememberForUndo(); extern void WireUndoInit(); #endif /* _WIREINT_H */ magic-8.0.210/wiring/wireUndo.c0000644000175000001440000001227610751423606014725 0ustar timusers/* * wireUndo.c -- * * This file contains procedures that implement undo for wiring procedures * such as setting the current wire width. * * ********************************************************************* * * 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/wiring/wireUndo.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/tech.h" #include "wiring/wiring.h" #include "wiring/wireInt.h" #include "textio/textio.h" #include "utils/undo.h" /* The following declaration is for records used to hold undo * information for wiring commands such as changing the current * layer. Only the wire-module-specific stuff needs to be undone * here: other stuff, such as selecting the current wire leg * and actually painting the wires, is undone in other modules. */ typedef struct { TileType wue_oldType; /* Previous type of wiring material. */ TileType wue_newType; /* New type of wiring material. */ int wue_oldWidth; /* Previous width of wiring material. */ int wue_newWidth; /* New width of wiring material. */ int wue_oldDir; /* Previous direction for wiring. */ int wue_newDir; /* New direction for wiring. */ } WireUndoEvent; /* Identifier for wiring undo records. */ UndoType WireUndoClientID; /* The following statics are used to remember the last values for the * wiring variables that were remembered by the undo package, so we * know what the values USED to be before the current round of changes. */ static TileType wireOldType = TT_SPACE; /* Last type that we remembered. */ static int wireOldWidth = 2; /* Last width that we remembered. */ static int wireOldDir = GEO_NORTH; /* Last direction */ /* * ---------------------------------------------------------------------------- * WireUndoInit -- * * Adds us as a client to the undo package. * * Results: * None. * * Side effects: * Adds a new client to the undo package, and sets WireUndoClientID. * ---------------------------------------------------------------------------- */ void WireUndoInit() { extern void WireUndoForw(), WireUndoBack(); WireUndoClientID = UndoAddClient((void (*)()) NULL, (void (*)()) NULL, (UndoEvent *(*)()) NULL, (int (*)()) NULL, WireUndoForw, WireUndoBack, "wiring parameters"); if (WireUndoClientID < (UndoType) 0) TxError("Couldn't add wiring as an undo client!\n"); } /* * ---------------------------------------------------------------------------- * WireRememberForUndo -- * * Whenever anybody in the wiring module changes the wiring parameters * (the static variables declared at the beginning of wireOps.c), * they're supposed to call this routine just after the changes so * that we can record information for undoing. * * Results: * None. * * Side effects: * Adds information to the undo list. The stuff that's remembered * is just exactly the stuff defined * ---------------------------------------------------------------------------- */ void WireRememberForUndo() { WireUndoEvent *wue; wue = (WireUndoEvent *) UndoNewEvent(WireUndoClientID, sizeof(WireUndoEvent)); if (wue == NULL) return; wue->wue_oldType = wireOldType; wue->wue_newType = wireOldType = WireType; wue->wue_oldWidth = wireOldWidth; wue->wue_newWidth = wireOldWidth = WireWidth; wue->wue_oldDir = wireOldDir; wue->wue_newDir = wireOldDir = WireLastDir; } /* * ---------------------------------------------------------------------------- * WireUndoForw -- * WireUndoBack -- * * These two routines are called by the undo package to process * undo events. WireUndoForw processes events during redo's and * WireUndoBack processes events during undo's * * Results: * None. * * Side effects: * Wiring parameters are modified. * ---------------------------------------------------------------------------- */ void WireUndoForw(wue) WireUndoEvent *wue; /* Event to be redone. */ { WireType = wireOldType = wue->wue_newType; WireWidth = wireOldWidth = wue->wue_newWidth; WireLastDir = wireOldDir = wue->wue_newDir; } void WireUndoBack(wue) WireUndoEvent *wue; /* Event to be undone. */ { WireType = wireOldType = wue->wue_oldType; WireWidth = wireOldWidth = wue->wue_oldWidth; WireLastDir = wireOldDir = wue->wue_oldDir; } magic-8.0.210/wiring/wiring.h0000644000175000001440000000572011060235211014414 0ustar timusers/* * wiring.h -- * * Contains definitions for things that are exported by the * wiring module. * * ********************************************************************* * * 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. * * ********************************************************************* * * rcsid $Header: /usr/cvsroot/magic-8.0/wiring/wiring.h,v 1.2 2008/09/05 13:56:25 tim Exp $ */ #ifndef _WIRING_H #define _WIRING_H #include "utils/magic.h" #include "database/database.h" /* Table that defines the shape of contacts and the layers that they * connect. This definition allows some layers to extend around the * contact, to support technologies where the contact pads are different * sizes for the different layers that the contact connects. */ typedef struct _Contact *ContactPtr; typedef struct _Contact { TileType con_type; /* Type of material that forms core of * contact. */ int con_size; /* Minimum size of this contact (size of * minimum con_type area). */ TileType con_layer1; /* First of two layers that the contact * really isn't a contact. */ int con_surround1; /* How much additional material of type * con_layer1 must be painted around the * edge of the contact. */ TileType con_layer2; /* Same information for second layer that * the contact connects. */ int con_surround2; ContactPtr con_next; /* Pointer to next contact record */ } Contact; extern Contact *WireContacts; /* Points to all the contacts that are * defined. */ /* Types defining the current state of the wiring tool */ extern TileType WireType; /* Type of material currently selected * for wiring. */ extern int WireWidth; /* Thickness of material to use for wiring. */ /* Procedures for placing wires: */ extern void WirePickType(); extern void WireAddLeg(); extern void WireAddContact(); extern void WireShowLeg(); extern int WireGetWidth(); extern TileType WireGetType(); /* Legal values for the "direction" parameter to WireAddLeg: */ #define WIRE_CHOOSE 0 #define WIRE_HORIZONTAL 1 #define WIRE_VERTICAL 2 /* Procedures for reading the technology file: */ extern void WireTechInit(); extern bool WireTechLine(); extern void WireTechFinal(); extern void WireTechScale(); /* Initialization: */ extern void WireInit(); #endif /* _WIRING_H */ magic-8.0.210/wiring/wireOps.c0000644000175000001440000006322611060235211014545 0ustar timusers/* * wireOps.c -- * * This file contains the basic procedures that provide a wiring-style * interface for Magic. The procedures do things like select a wiring * material and thickness, add a leg to a wire, etc. * * ********************************************************************* * * 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/wiring/wireOps.c,v 1.2 2008/09/05 13:56:25 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "select/select.h" #include "textio/textio.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "drc/drc.h" #include "utils/main.h" #include "wiring/wiring.h" #include "wiring/wireInt.h" #include "textio/txcommands.h" #include "utils/styles.h" /* The following variables define the state of the wiring interface. */ TileType WireType = TT_SELECTBASE-1; /* Type of material currently selected * for wiring. */ int WireWidth; /* Thickness of material to use for wiring. */ int WireLastDir; /* Last direction in which a wire was run. */ /* The following variable is used to communicate the desired root cellDef * between wireFindRootUse and wireFindRootFunc. */ static CellDef *wireDesiredDef; /* * ---------------------------------------------------------------------------- * wireFindRootUse -- * * This is a utility procedure to find a window containing a particular * definition as its root. * * Results: * The return value is the root use of a window, such that the * use is an instance of rootDef. If the definition isn't the * root of any window then NULL is returned. * * Side effects: * None. * ---------------------------------------------------------------------------- */ CellUse * wireFindRootUse(rootDef) CellDef *rootDef; /* Root definition for which a root use * is desired. */ { CellUse *result; extern int wireFindRootFunc(); result = NULL; wireDesiredDef = rootDef; (void) WindSearch(DBWclientID, (ClientData) NULL, (Rect *) NULL, wireFindRootFunc, (ClientData) &result); return result; } /* The following search function is called for each window. If the * window's root is wireDesiredDef, then cellUsePtr is filled in * with the window's root cellUse (and the search is aborted). */ int wireFindRootFunc(window, cellUsePtr) MagWindow *window; /* A layout window. */ CellUse **cellUsePtr; /* Pointer to cellUse pointer. */ { CellUse *use; use = (CellUse *) window->w_surfaceID; if (use->cu_def != wireDesiredDef) return 0; *cellUsePtr = use; return 1; } /* * ---------------------------------------------------------------------------- * WirePickType -- * * This procedure establishes a new material for future wiring, and * terminates any wires in progress. * * Results: * None. * * Side effects: * The current wire type and width are modified. If type is * less than zero, then a new type and width are picked based * on what's under the cursor, and this piece is also selected * as a chunk. Otherwise, the parameters determine the new * type and width. * ---------------------------------------------------------------------------- */ void WirePickType(type, width) TileType type; /* New type of material to use for wiring. * If less than zero, then pick a new type * based on what's underneath the cursor. */ int width; /* Width to use for future wiring. If type * is less than zero then this parameter is * ignored and the width of the material * underneath the cursor is used. */ { MagWindow *w; Point point; Rect chunk, box; SearchContext scx; DBWclientRec *crec; TileTypeBitMask mask; int height; if (type >= 0) { WireType = type; WireWidth = width; WireLastDir = -1; WireRememberForUndo(); return; } /* Find what layers are visible underneath the point. Pick one of * them as the material to select. If there are several, cycle * through them one at a time, starting from the last selected type * so each type gets a chance. */ w = ToolGetPoint(&point, &scx.scx_area); if (w == NULL) { TxError("Can't use cursor to select wiring material unless\n"); TxError(" cursor is in a layout window.\n"); return; } scx.scx_use = (CellUse *) w->w_surfaceID; scx.scx_trans = GeoIdentityTransform; crec = (DBWclientRec *) w->w_clientData; DBSeeTypesAll(scx.scx_use, &scx.scx_area, crec->dbw_bitmask, &mask); TTMaskAndMask(&mask, &crec->dbw_visibleLayers); TTMaskAndMask(&mask, &DBAllButSpaceAndDRCBits); if (TTMaskIsZero(&mask)) { TxError("There's no material visible underneath the cursor.\n"); return; } for (WireType += 1; ; WireType += 1) { if (WireType >= DBNumUserLayers) WireType = TT_SELECTBASE; if (TTMaskHasType(&mask, WireType)) break; } /* Now select a chunk underneath the cursor of the particular type. */ SelectClear(); SelectChunk(&scx, WireType, crec->dbw_bitmask, &chunk, FALSE); WireWidth = chunk.r_xtop - chunk.r_xbot; height = chunk.r_ytop - chunk.r_ybot; if (height < WireWidth) WireWidth = height; /* Set the box and the selection to a square chunk that indicates the * wire width. */ if (WireWidth & 1) { GEO_EXPAND(&scx.scx_area, WireWidth/2, &box); } else { box.r_xbot = point.p_x - WireWidth/2; box.r_ybot = point.p_y - WireWidth/2; box.r_xtop = box.r_xbot + WireWidth; box.r_ytop = box.r_ybot + WireWidth; } if (box.r_xbot < chunk.r_xbot) { box.r_xbot = chunk.r_xbot; box.r_xtop = box.r_xbot + WireWidth; } if (box.r_ybot < chunk.r_ybot) { box.r_ybot = chunk.r_ybot; box.r_ytop = box.r_ybot + WireWidth; } if (box.r_xtop > chunk.r_xtop) { box.r_xtop = chunk.r_xtop; box.r_xbot = box.r_xtop - WireWidth; } if (box.r_ytop > chunk.r_ytop) { box.r_ytop = chunk.r_ytop; box.r_ybot = box.r_ytop - WireWidth; } SelectClear(); scx.scx_area = box; TTMaskSetOnlyType(&mask, WireType); SelectArea(&scx, &mask, crec->dbw_bitmask); DBWSetBox(scx.scx_use->cu_def, &box); TxPrintf("Using %s wires %d units wide.\n", DBTypeLongName(WireType), WireWidth); WireLastDir = -1; WireRememberForUndo(); } /* * ---------------------------------------------------------------------------- * WireGetWidth, WireGetType -- * * Two routines used to query the internal values of the wiring * mechanism. * * ---------------------------------------------------------------------------- */ int WireGetWidth() { return WireWidth; } TileType WireGetType() { return WireType; } /* * ---------------------------------------------------------------------------- * WireAddLeg -- * * This procedure adds a new leg to the current wire in the current * wiring material (set by WirePickType). The new leg will abut rect * and extend to either point's x-coordinate or its y-coordinate, * whichever results in a longer wire. Direction can be used to * force the wire to run in a particular direction. * * Results: * None. * * Side effects: * The edit cell is modified to contain more material. * ---------------------------------------------------------------------------- */ void WireAddLeg(rect, point, direction) Rect *rect; /* Describes the current (last-painted) leg * of the wire, in root coordinates. If NULL, * then the box is used for this. */ Point *point; /* Describes where to paint the wire to, in * root coordinates. If NULL, then the cursor * location is used as the point. */ int direction; /* Which direction to run the wire, in root * coords. If WIRE_CHOOSE, then pick a * direction based on point. If WIRE_VERTICAL * or WIRE_HORIZONTAL, then run the wire in * the indicated direction. */ { Rect current, new, leg, editArea; CellDef *boxRootDef; SearchContext scx; Point cursorPos; TileTypeBitMask mask; if (WireType == 0) { TxError("Can't add a new wire leg: no wiring material selected.\n"); return; } /* If rect isn't supplied, use the box. */ if (rect == NULL) { rect = ¤t; if (!ToolGetBox(&boxRootDef, rect)) { TxError("No box! Before wiring a leg, you must set the box\n"); TxError(" to indicate where the leg starts.\n"); return; } if (boxRootDef != EditRootDef) { TxError("The box must be on the edit cell so it can be used\n"); TxError(" as the starting point for a wire leg.\n"); return; } } /* If no point is supplied, read it from the cursor location. */ if (point == NULL) { MagWindow *w; w = ToolGetPoint(&cursorPos, (Rect *) NULL); if ((w == NULL) || (((CellUse *) w->w_surfaceID)->cu_def != EditRootDef)) { TxError("Before wiring, must place cursor over edit cell to\n"); TxError(" indicate endpoint of new wire leg.\n"); return; } point = &cursorPos; } /* If the caller didn't provide a direction, then pick the opposite * direction (if this isn't the first leg of the wire), or pick * the direction that results in the largest amount of wiring (if * this is the first leg). */ if (direction == WIRE_CHOOSE) { int delx, dely; delx = point->p_x - rect->r_xtop; if (delx < 0) { delx = rect->r_xbot - point->p_x; if (delx < 0) delx = 0; } dely = point->p_y - rect->r_ytop; if (dely < 0) { dely = rect->r_ybot - point->p_y; if (dely < 0) dely = 0; } if (delx > dely) direction = WIRE_HORIZONTAL; else direction = WIRE_VERTICAL; } /* Now compute the area to paint. */ if (direction == WIRE_HORIZONTAL) { /* The new leg will be horizontal. First compute its span in * x, then its span in y. */ if (point->p_x > rect->r_xtop) { new.r_xbot = rect->r_xtop; new.r_xtop = point->p_x; WireLastDir = GEO_EAST; } else if (point->p_x < rect->r_xbot) { new.r_xtop = rect->r_xbot; new.r_xbot = point->p_x; WireLastDir = GEO_WEST; } else return; /* Nothing to paint! */ /* Hook the segment up to the nearest point along the box * to where we are. Usually the box is exactly as wide as * the wires so there's no real choice. */ new.r_ybot = point->p_y - WireWidth/2; if (new.r_ybot < rect->r_ybot) new.r_ybot = rect->r_ybot; else if (new.r_ybot > rect->r_ytop - WireWidth) new.r_ybot = rect->r_ytop - WireWidth; new.r_ytop = new.r_ybot + WireWidth; } else { /* The new wire segment is vertical. See comments above (this * code is just like what's up there). */ if (point->p_y > rect->r_ytop) { new.r_ybot = rect->r_ytop; new.r_ytop = point->p_y; WireLastDir = GEO_NORTH; } else if (point->p_y < rect->r_ybot) { new.r_ytop = rect->r_ybot; new.r_ybot = point->p_y; WireLastDir = GEO_SOUTH; } else return; /* Nothing to paint! */ new.r_xbot = point->p_x - WireWidth/2; if (new.r_xbot < rect->r_xbot) new.r_xbot = rect->r_xbot; if (new.r_xbot > rect->r_xtop - WireWidth) new.r_xbot = rect->r_xtop - WireWidth; new.r_xtop = new.r_xbot + WireWidth; } /* Paint the new leg and select it. */ GeoTransRect(&RootToEditTransform, &new, &editArea); TTMaskSetOnlyType(&mask, WireType); DBPaintValid(EditCellUse->cu_def, &editArea, &mask, 0); DBAdjustLabels(EditCellUse->cu_def, &editArea); DBWAreaChanged(EditCellUse->cu_def, &editArea, DBW_ALLWINDOWS, &mask); DRCCheckThis(EditCellUse->cu_def, TT_CHECKPAINT, &editArea); DBReComputeBbox(EditCellUse->cu_def); /* Select the new wire leg, if the edit cell is visible in any * windows. */ scx.scx_use = wireFindRootUse(EditRootDef); if (scx.scx_use != NULL) { SelectClear(); scx.scx_area = new; scx.scx_trans = GeoIdentityTransform; SelectChunk(&scx, WireType, 0, &leg, FALSE); } /* Make the box a square at the tip of the new are just painted. */ switch (WireLastDir) { case GEO_NORTH: if (leg.r_ybot < new.r_ybot) new.r_ybot = leg.r_ybot; if ((new.r_ytop - new.r_ybot) > WireWidth) new.r_ybot = new.r_ytop - WireWidth; break; case GEO_SOUTH: if (leg.r_ytop > new.r_ytop) new.r_ytop = leg.r_ytop; if ((new.r_ytop - new.r_ybot) > WireWidth) new.r_ytop = new.r_ybot + WireWidth; break; case GEO_EAST: if (leg.r_xbot < new.r_xbot) new.r_xbot = leg.r_xbot; if ((new.r_xtop - new.r_xbot) > WireWidth) new.r_xbot = new.r_xtop - WireWidth; break; case GEO_WEST: if (leg.r_xtop > new.r_xtop) new.r_xtop = leg.r_xtop; if ((new.r_xtop - new.r_xbot) > WireWidth) new.r_xtop = new.r_xbot + WireWidth; break; } DBWSetBox(EditRootDef, &new); WireRememberForUndo(); } /* * ---------------------------------------------------------------------------- * WireShowLeg -- * * This procedure adds a new leg to the current wire in the current * wiring material (set by WirePickType). Unlike WireAddLeg(), the * wire is painted into the selection def, not the edit def. This * allows the selection to be updated with cursor movement, showing * where magic is going to place the next wire leg. * Also, we do not print error messages, as this function may be * called several times per second. * * Results: * None. * * Side effects: * The selection cell is cleared and painted. * ---------------------------------------------------------------------------- */ void WireShowLeg() { Rect current, new, leg, editArea, *rect = ¤t; CellDef *boxRootDef; SearchContext scx; Point cursorPos, *point = &cursorPos; TileTypeBitMask mask; int direction = WIRE_CHOOSE; int delx, dely; MagWindow *w; if (WireType == 0) return; /* get the cursor box position. */ rect = ¤t; if (!ToolGetBox(&boxRootDef, rect)) return; if (boxRootDef != EditRootDef) return; /* get the cursor location. */ w = ToolGetPoint(&cursorPos, (Rect *) NULL); if ((w == NULL) || (((CellUse *) w->w_surfaceID)->cu_def != EditRootDef)) return; /* Pick the opposite direction (if this isn't the first leg of the * wire), or pick the direction that results in the largest amount * of wiring (if this is the first leg). */ delx = point->p_x - rect->r_xtop; if (delx < 0) { delx = rect->r_xbot - point->p_x; if (delx < 0) delx = 0; } dely = point->p_y - rect->r_ytop; if (dely < 0) { dely = rect->r_ybot - point->p_y; if (dely < 0) dely = 0; } if (delx > dely) direction = WIRE_HORIZONTAL; else direction = WIRE_VERTICAL; /* Now compute the area to paint. */ if (direction == WIRE_HORIZONTAL) { /* The new leg will be horizontal. First compute its span in * x, then its span in y. */ if (point->p_x > rect->r_xtop) { new.r_xbot = rect->r_xtop; new.r_xtop = point->p_x; WireLastDir = GEO_EAST; } else if (point->p_x < rect->r_xbot) { new.r_xtop = rect->r_xbot; new.r_xbot = point->p_x; WireLastDir = GEO_WEST; } else return; /* Nothing to paint! */ /* Hook the segment up to the nearest point along the box * to where we are. Usually the box is exactly as wide as * the wires so there's no real choice. */ new.r_ybot = point->p_y - WireWidth/2; if (new.r_ybot < rect->r_ybot) new.r_ybot = rect->r_ybot; else if (new.r_ybot > rect->r_ytop - WireWidth) new.r_ybot = rect->r_ytop - WireWidth; new.r_ytop = new.r_ybot + WireWidth; } else { /* The new wire segment is vertical. See comments above (this * code is just like what's up there). */ if (point->p_y > rect->r_ytop) { new.r_ybot = rect->r_ytop; new.r_ytop = point->p_y; WireLastDir = GEO_NORTH; } else if (point->p_y < rect->r_ybot) { new.r_ytop = rect->r_ybot; new.r_ybot = point->p_y; WireLastDir = GEO_SOUTH; } else return; /* Nothing to paint! */ new.r_xbot = point->p_x - WireWidth/2; if (new.r_xbot < rect->r_xbot) new.r_xbot = rect->r_xbot; if (new.r_xbot > rect->r_xtop - WireWidth) new.r_xbot = rect->r_xtop - WireWidth; new.r_xtop = new.r_xbot + WireWidth; } /* Clear any old selection. Ignore the Undo mechanism so */ /* we don't continuously record uncommitted routes. */ UndoDisable(); SelectClear(); /* Paint the new leg into the selection box. */ TTMaskSetOnlyType(&mask, WireType); DBPaintValid(SelectDef, &new, &mask, 0); DBAdjustLabels(SelectDef, &new); DBWAreaChanged(SelectDef, &new, DBW_ALLWINDOWS, &mask); DBReComputeBbox(SelectDef); DBWHLRedraw(SelectRootDef, &new, TRUE); DBWAreaChanged(SelectDef, &SelectDef->cd_bbox, DBW_ALLWINDOWS, &DBAllButSpaceBits); UndoEnable(); } /* * ---------------------------------------------------------------------------- * WireAddContact -- * * This procedure places a contact at the end of the current wire * leg in order to switch layers, and records a new routing layer * and width. * * Results: * None. * * Side effects: * A contact is placed, and the current wire type and width are * modified. The contact type is chosen based on information * from the technology file and the new and old routing layers. * ---------------------------------------------------------------------------- */ void WireAddContact(newType, newWidth) TileType newType; /* New type of material to use for wiring. * If less than zero, pick a new type based * on what's underneath the cursor. */ int newWidth; /* New width to use for future wiring. If * newType is less than zero, then this * parameter is ignored and the width of * the material underneath the cursor is * used. */ { Rect oldLeg, contactArea, tmp, tmp2, editArea; CellDef *boxRootDef; TileType oldType; TileTypeBitMask mask, allmask; int oldOverlap, newOverlap, i, totalSize, oldDir; Contact *contact; SearchContext scx; /* First of all, find out the location of the last wire leg, * which is marked by the box. */ if (!ToolGetBox(&boxRootDef, &oldLeg)) { TxError("No box! To place a contact, you must first use\n"); TxError(" the box to mark the previous leg of the wire,\n"); TxError(" at the end of which the contact will be placed.\n"); return; } if (boxRootDef != EditRootDef) { TxError("The box must be on the edit cell; it marks the wire\n"); TxError(" leg at the end of which a contact will be placed.\n"); return; } oldType = WireType; oldDir = WireLastDir; /* Now find a new type and width. If the type is the same, then * there's no need to add a contact. */ WirePickType(newType, newWidth); if (WireType == oldType) { TxError("The new wiring layer is the same as the old one, so\n"); TxError(" there's no need for a contact.\n"); return; } /* Choose a contact type. */ for (contact = WireContacts; contact != NULL; contact = contact->con_next) { if ((contact->con_layer1 == oldType) && (contact->con_layer2 == WireType)) { oldOverlap = contact->con_surround1; newOverlap = contact->con_surround2; goto gotContact; } if ((contact->con_layer2 == oldType) && (contact->con_layer1 == WireType)) { oldOverlap = contact->con_surround2; newOverlap = contact->con_surround1; goto gotContact; } } TxError("Sorry, but the technology file doesn't define a contact\n"); TxError(" between \"%s\" and \"%s\".\n", DBTypeLongName(oldType), DBTypeLongName(WireType)); return; /* Compute the contact's bounding box, including surrounds. The idea here * is to center the contact at the end of the leg. With the edge of * the surround corresponding to the old layer just lining up with * the end of the leg. The contact may have to be wider than the leg. * However, if the wire is very wide, make the contact so it won't * extend past the edge of the wire. */ gotContact: totalSize = contact->con_size + 2*oldOverlap; contactArea = oldLeg; if ((contactArea.r_xtop - contactArea.r_xbot) < totalSize) { contactArea.r_xbot -= (totalSize - (contactArea.r_xtop - contactArea.r_xbot))/2; contactArea.r_xtop = contactArea.r_xbot + totalSize; } if ((contactArea.r_ytop - contactArea.r_ybot) < totalSize) { contactArea.r_ybot -= (totalSize - (contactArea.r_ytop - contactArea.r_ybot))/2; contactArea.r_ytop = contactArea.r_ybot + totalSize; } switch (oldDir) { case GEO_NORTH: i = contactArea.r_ytop - totalSize; if (i > contactArea.r_ybot) contactArea.r_ybot = i; break; case GEO_SOUTH: i = contactArea.r_ybot + totalSize; if (i < contactArea.r_ytop) contactArea.r_ytop = i; break; case GEO_EAST: i = contactArea.r_xtop - totalSize; if (i > contactArea.r_xbot) contactArea.r_xbot = i; break; case GEO_WEST: i = contactArea.r_xbot + totalSize; if (i < contactArea.r_xtop) contactArea.r_xtop = i; break; } /* Paint the contact and its surrounding areas. */ GeoTransRect(&RootToEditTransform, &contactArea, &editArea); GEO_EXPAND(&editArea, -oldOverlap, &tmp); TTMaskSetOnlyType(&mask, contact->con_type); TTMaskSetOnlyType(&allmask, contact->con_type); DBPaintValid(EditCellUse->cu_def, &tmp, &mask, 0); if (contact->con_surround1 != 0) { TTMaskSetOnlyType(&mask, contact->con_layer1); TTMaskSetType(&allmask, contact->con_layer1); GEO_EXPAND(&tmp, contact->con_surround1, &tmp2); (void) GeoInclude(&tmp2, &editArea); DBPaintValid(EditCellUse->cu_def, &tmp2, &mask, 0); } if (contact->con_surround2 != 0) { TTMaskSetOnlyType(&mask, contact->con_layer2); TTMaskSetType(&allmask, contact->con_layer2); GEO_EXPAND(&tmp, contact->con_surround2, &tmp2); (void) GeoInclude(&tmp2, &editArea); DBPaintValid(EditCellUse->cu_def, &tmp2, &mask, 0); } DBAdjustLabels(EditCellUse->cu_def, &editArea); DBWAreaChanged(EditCellUse->cu_def, &editArea, DBW_ALLWINDOWS, &allmask); DRCCheckThis(EditCellUse->cu_def, TT_CHECKPAINT, &editArea); DBReComputeBbox(EditCellUse->cu_def); /* Select the contact and its surrounds, if the edit cell is * in a window. */ SelectClear(); scx.scx_use = wireFindRootUse(EditRootDef); if (scx.scx_use != NULL) { scx.scx_trans = GeoIdentityTransform; GEO_EXPAND(&contactArea, -oldOverlap, &tmp); scx.scx_area = tmp; TTMaskSetOnlyType(&mask, contact->con_type); SelectArea(&scx, &mask, 0); if (contact->con_surround1 != 0) { GEO_EXPAND(&tmp, contact->con_surround1, &scx.scx_area); TTMaskSetOnlyType(&mask, contact->con_layer1); SelectArea(&scx, &mask, 0); } if (contact->con_surround2 != 0) { GEO_EXPAND(&tmp, contact->con_surround2, &scx.scx_area); TTMaskSetOnlyType(&mask, contact->con_layer2); SelectArea(&scx, &mask, 0); } } /* Place the box over the overlap area of the new routing material. */ GEO_EXPAND(&tmp, newOverlap, &tmp2); DBWSetBox(EditRootDef, &tmp2); } /* * ---------------------------------------------------------------------------- * * WireButtonProc -- * * This procedure implements a button-based wiring interface. It * is registered as a client of the dbwind button manager and is * called automatically by dbwind when buttons are pushed and this * handler is the active one. * * Results: * None. * * Side effects: * Left button: same as ":wire type" (pick wiring layer and width) * Right button: same as ":wire leg" (add a new leg to the wire) * Middle button: same as ":wire switch" (place contact to new layer) * * ---------------------------------------------------------------------------- */ void WireButtonProc(w, cmd) MagWindow *w; /* Window in which button was pushed. */ TxCommand *cmd; /* Describes exactly what happened. */ { /* We do commands on the down-pushes and ignore the releases. */ if (cmd->tx_buttonAction != TX_BUTTON_DOWN) return; switch (cmd->tx_button) { case TX_LEFT_BUTTON: WirePickType(-1, 0); break; case TX_RIGHT_BUTTON: WireAddLeg((Rect *) NULL, (Point *) NULL, WIRE_CHOOSE); break; case TX_MIDDLE_BUTTON: WireAddContact(-1, 0); break; } } /* * ---------------------------------------------------------------------------- * * WireInit -- * * This procedure is called when Magic starts up to initialize * the wiring module. * * Results: * None. * * Side effects: * Registers various things with various managers. * * ---------------------------------------------------------------------------- */ void WireInit() { static char *doc = "You are currently using the \"wiring\" tool. The button actions are:\n\ left - pick a wiring layer and width (same as \":wire type\")\n\ right - add a leg to the wire (same as \":wire leg\")\n\ middle - place a contact to switch layers (same as \":wire switch\")\n"; WireUndoInit(); DBWAddButtonHandler("wiring", WireButtonProc, STYLE_CURS_ARROW, doc); } magic-8.0.210/wiring/wireTech.c.new0000644000175000001440000001250210751423606015463 0ustar timusers/* * wireTech.c -- * * This file contains procedures that parse the wiring sections of * technology files. * * ********************************************************************* * * 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[]="$Header: /usr/cvsroot/magic-8.0/wiring/wireTech.c.new,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "tech/tech.h" #include "wiring/wiring.h" #include "utils/malloc.h" /* Linked list to store contact information collected by this module: */ Contact *WireContacts; /* * ---------------------------------------------------------------------------- * WireTechInit -- * * Called once at beginning of technology file read-in to initialize * data structures. * * Results: * None. * * Side effects: * Clears out the contact table. * ---------------------------------------------------------------------------- */ void WireTechInit() { Contact *contact; int i; while (WireContacts != NULL) { freeMagic((char *) WireContacts); WireContacts = WireContacts->con_next; } } /* * ---------------------------------------------------------------------------- * WireTechLine -- * * This procedure is invoked by the technology module once for * each line in the "wiring" 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 contact table, prints error messages if necessary. * ---------------------------------------------------------------------------- */ /* ARGSUSED */ bool WireTechLine(sectionName, argc, argv) char *sectionName; /* Name of this section (unused). */ int argc; /* Number of arguments on line. */ char *argv[]; /* Pointers to fields of line. */ { Contact *new; if (strcmp(argv[0], "contact") != 0) { TechError("Unknown wiring keyword: %s. Line ignored.\n", argv[0]); return TRUE; } if (argc != 7) { TechError("\"contact\" lines must have exactly 7 arguments.\n"); return TRUE; } new = (Contact *) mallocMagic(sizeof(Contact)); new->con_type = DBTechNoisyNameType(argv[1]); new->con_layer1 = DBTechNoisyNameType(argv[3]); new->con_layer2 = DBTechNoisyNameType(argv[5]); if ((new->con_type < 0) || (new->con_layer1 < 0) || (new->con_layer2 < 0)) { errorReturn: freeMagic((char *) new); return TRUE; } if (!StrIsInt(argv[2])) { TechError("3rd field must be an integer.\n"); goto errorReturn; } else new->con_size = atoi(argv[2]); if (!StrIsInt(argv[4])) { TechError("5th field must be an integer.\n"); goto errorReturn; } else new->con_surround1 = atoi(argv[4]); if (!StrIsInt(argv[6])) { TechError("6th field must be an integer.\n"); goto errorReturn; } else new->con_surround2 = atoi(argv[6]); new->con_next = WireContacts; WireContacts = new; return TRUE; } /* * ---------------------------------------------------------------------------- * WireTechFinal -- * * This procedure is called by the technology module after all the * lines of the tech file have been read. It doesn't do anything * right now. * * Results: * None. * * Side effects: * None. * ---------------------------------------------------------------------------- */ void WireTechFinal() { /* Debugging code to print info about layers: */ /* Contact *con; for (con = WireContacts; con != NULL; con = con->con_next) { TxPrintf("Contact type \"%s\", size %d connects\n", DBTypeLongName(con->con_type), con->con_size); TxPrintf(" \"%s\" (overlap %d) and\n", DBTypeLongName(con->con_layer1), con->con_surround1); TxPrintf(" \"%s\" (overlap %d)\n", DBTypeLongName(con->con_layer2), con->con_surround2); } */ } /* *---------------------------------------------------------------------------- * WireTechScale -- * * Change parameters of the wiring section as required when * redefining magic's internal grid relative to the technology lambda. * *---------------------------------------------------------------------------- */ int WireTechScale(scalen, scaled) int scalen, scaled; { Contact *con; for (con = WireContacts; con != NULL; con = con->con_next) { con->con_size *= scalen; con->con_size /= scaled; con->con_surround1 *= scalen; con->con_surround1 /= scaled; con->con_surround2 *= scalen; con->con_surround2 /= scaled; } } magic-8.0.210/plot/0000755000175000001440000000000012150000730012414 5ustar timusersmagic-8.0.210/plot/plotInt.h0000664000175000001440000001572112046303407014241 0ustar timusers/* * plotInt.h -- * * Contains definitions for things that are used internally by the * plot module but not exported. * * ********************************************************************* * * 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. * * ********************************************************************* * * rcsid $Header: /usr/cvsroot/magic-8.0/plot/plotInt.h,v 1.2 2010/03/08 13:33:33 tim Exp $ */ #ifndef _PLOTINT_H #define _PLOTINT_H #include "utils/magic.h" #include "utils/geometry.h" #define VERSATEC /* Add this for HP plotter support */ /* system V machines lack vfont.h, so include the defs below. */ #if !defined(SYSV) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(CYGWIN) && !defined(__APPLE__) && !defined(__DragonFly__) && !defined(__OpenBSD__) #include #else struct header { short magic; unsigned short size; short maxx; short maxy; short xtend; }; struct dispatch { unsigned short addr; short nbytes; char up,down,left,right; short width; }; #endif /* SYSV */ /* The structure below is used for raster output, e.g. to a Versatec * printer. It defines a rectangular raster area in which to fill * bits for printing. */ typedef struct { int ras_width; /* How many bits across the raster * (x-dimension). */ int ras_bytesPerLine; /* How much to add to the byte address * of one pixel to find the byte containing * the pixel just below it. */ int ras_intsPerLine; /* How much to add to the address of an * integer containing a pixel to find the * address of the integer containing the * pixel just underneath it. */ int ras_height; /* Raster height (y-dimension). For proper * stippling, this should usually be a * multiple of the stipple height. */ int *ras_bits; /* Storage for raster. The raster is * organized as BYTES: the high-order bit * of the first byte corresponds to the * leftmost pixel of the highest raster line. * Successive bits fill out the first line. * The next raster line starts on the next * 4-byte boundary. */ } Raster; /* This structure is also used for raster output, but to "deep" * devices such as frame buffers and Dicomend cameras. It defines a * rectangular raster area in which to fill bits for printing. Each byte * of the pix_pixels array holds one pixel; for an RGB image, three * PixRasters will be needed. */ typedef struct { int pix_width; /* How many bytes across the raster * (x-dimension). */ int pix_height; /* Raster height (y-dimension). For proper * stippling, this should usually be a * multiple of the stipple height. */ char *pix_pixels; /* Storage for raster. The raster is * organized as BYTES: each byte is one pixel. */ } PixRaster; /* The structure below describes a stipple pattern. 16 32-bit words * are used to represent a 16-pixel high, 32-pixel wide texture pattern * for filling. Most of the actual stipple patterns are 16-bits wide, * in which case the two halves of each word are duplicates. */ typedef unsigned int Stipple[16]; /* * The versatec color codes are chosen to correspond to the codes used by the * color plotter, so no translation will be necessary. */ typedef short VersatecColor; /* the possible versatec colors */ #define BLACK 0 #define CYAN 1 #define MAGENTA 2 #define YELLOW 3 /* The structure below describes a font. It consists primarily of the * stuff read in from disk in Vfont format. See the vfont(5) man page * for details of what's in a font. All the fonts that have been * read in so far are linked by their fo_next fields. */ typedef struct font { char *fo_name; /* Name of font. */ struct header fo_hdr; /* Header structure. */ struct dispatch fo_chars[256]; /* Character descriptors. */ char *fo_bits; /* Character bitmaps. */ Rect fo_bbox; /* Bounding box of space occupied * by all characters, assuming * (0,0) origin. */ struct font *fo_next; /* Next in list, or NULL for * end of list. */ } RasterFont; /* Technology-file reading procedures: */ extern void PlotPSTechInit(); extern bool PlotPSTechLine(); extern void PlotGremlinTechInit(); extern bool PlotGremlinTechLine(); extern void PlotVersTechInit(); extern bool PlotVersTechLine(); extern void PlotColorVersTechInit(); extern bool PlotColorVersTechLine(); extern void PlotPNMTechInit(); extern bool PlotPNMTechLine(); extern void PlotPNMTechFinal(); extern void PlotPixTechInit(); extern bool PlotPixTechLine(); /* Raster utilities: */ extern void PlotRastInit(); extern Raster *PlotNewRaster(); extern void PlotFreeRaster(); extern void PlotClearRaster(); extern void PlotFillRaster(); extern void PlotPolyRaster(); extern int PlotDumpRaster(); extern Stipple PlotBlackStipple; extern RasterFont *PlotLoadFont(); extern void PlotTextSize(); extern void PlotRasterText(); extern int PlotSwapBytes(); extern short PlotSwapShort(); extern int PlotDumpColorPreamble(); extern PixRaster *PlotNewPixRaster(); extern void PlotFreePixRaster(); extern void PlotClearPixRaster(); extern void plotFillPixRaster(); extern void PlotPixRasterText(); extern int PlotDumpPixRaster(); /* User-settable plotting parameters: */ /* for PostScript (plotPS.c): */ extern char *PlotPSIdFont; extern char *PlotPSNameFont; extern char *PlotPSLabelFont; extern int PlotPSIdSize; extern int PlotPSNameSize; extern int PlotPSLabelSize; extern int PlotPSBoundary; extern int PlotPSWidth; extern int PlotPSHeight; extern int PlotPSMargin; /* for Versatec (plotVers.c): */ #ifdef VERSATEC extern int PlotVersWidth; extern int PlotVersDotsPerInch; extern int PlotVersSwathHeight; extern char *PlotVersPrinter; extern char *PlotVersCommand; extern char *PlotTempDirectory; extern char *PlotVersIdFont; extern char *PlotVersNameFont; extern char *PlotVersLabelFont; extern unsigned char PlotVersPlotType; #endif enum { VERSATEC_COLOR = 0, VERSATEC_BW, HPRTL, HPGL2 }; /* for plotPixels.c: */ #ifdef LLNL extern int PlotPixHeight; extern int PlotPixWidth; #endif /* for all: */ extern bool PlotShowCellNames; /* for plotPnm.c */ extern int PlotPNMmaxmem; extern int PlotPNMdownsample; extern unsigned char PlotPNMBG; #ifdef VERSATEC extern bool PlotPNMRTL; #endif #endif /* _PLOTINT_H */ magic-8.0.210/plot/Makefile0000644000175000001440000000220310751423606014071 0ustar timusers# # rscid $Header: # MODULE = plot MAGICDIR = .. SRCS = plotCmd.c plotGremln.c plotHP.c plotPS.c plotMain.c plotRutils.c \ plotVers.c plotPixels.c plotPNM.c include ${MAGICDIR}/defs.mak LIBS += ${LD_EXTRA_LIBS} ${SUB_EXTRA_LIBS} CLEANS += tclplot${SHDLIB_EXT} tclplot.o # Note: Add -DGREMLIN and/or -DVERSATEC to DFLAGS if you want # those output types to be added. Without them, only a minimal # amount of code is compiled to keep magic from complaining when # parameters are found in the technology file. tcl-main: tclplot.o tclplot${SHDLIB_EXT} tclplot.o: tclplot.c ${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS} tclplot.c -c -o tclplot.o tclplot${SHDLIB_EXT}: tclplot.o ${OBJS} @echo --- making Tcl auto-load module \(tclplot${SHDLIB_EXT}\) ${RM} tclplot${SHDLIB_EXT} ${CC} ${CFLAGS} ${CPPFLAGS} -o $@ ${LDDL_FLAGS} tclplot.o ${OBJS} \ ${EXTRA_LIBS} -lc ${LIBS} install-tcl: $(DESTDIR)${TCLDIR}/tclplot${SHDLIB_EXT} $(DESTDIR)${TCLDIR}/tclplot${SHDLIB_EXT}: tclplot${SHDLIB_EXT} ${RM} $(DESTDIR)${TCLDIR}/tclplot${SHDLIB_EXT} ${CP} tclplot${SHDLIB_EXT} $(DESTDIR)${TCLDIR}/tclplot${SHDLIB_EXT} include ${MAGICDIR}/rules.mak magic-8.0.210/plot/plotPS.c0000664000175000001440000010617312150000730014013 0ustar timusers/* * plotPS.c -- * * This file contains procedures that generate PS-format files * to describe a section of layout. * * ********************************************************************* * * 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/plot/plotPS.c,v 1.3 2010/06/24 12:37:25 tim Exp $"; #endif /* not lint */ #include #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/tech.h" #include "utils/malloc.h" #include "utils/utils.h" #include "windows/windows.h" #include "commands/commands.h" #include "dbwind/dbwind.h" #include "textio/textio.h" /* Records of the following type are used to describe how to generate * PS output for a particular set of mask layers. Each style * describes the PS figures to draw for a particular set of * layers. A single layer may participate in several ps styles. */ typedef struct psstyle { TileTypeBitMask grs_layers; /* Layers to plot in this style. */ int grs_stipple; /* Index of fill to use. */ int grs_color; /* Index of color to use. */ struct psstyle *grs_next; /* Next style in chain. */ } PSStyle; typedef struct pspattern { int index; unsigned long stipple[8]; struct pspattern *pat_next; } PSPattern; typedef struct pscolor { int index; unsigned char color[4]; struct pscolor *col_next; } PSColor; static PSStyle *plotPSStyles = NULL; static PSPattern *plotPSPatterns = NULL; static PSColor *plotPSColors = NULL; int delta, xnmargin, ynmargin, xpmargin, ypmargin; float fscale; /* Most of the grs_stipple values are PS stipple numbers. However, * if a grs_stipple value is less than zero, it means something special. * The definitions below give the possible alternatives: * * CROSS: Draw a thick outline around the tile with * a cross through it (used for contacts). * BORDER: Same as CROSS, except draw the outline with * no cross through it. * SOLID: This is the same as a solid stipple but renders * much faster. */ #define CROSS -1 #define BORDER -2 #define SOLID -3 /* The definitions below give the integers used for various PS * line drawing styles (brushes). */ #define PS_THIN 1 #define PS_MEDIUM 2 #define PS_THICK 3 /* The variables below are used to pass information from the top-level * procedure PlotPS down to the lower-level search functions * that are invoked for pieces of the layout. */ static FILE *file; /* File to use for output. */ static PSStyle *curStyle; /* Current style being output. */ static PSColor *curColor; /* Current color being output. */ static PSPattern *curPattern; /* Current pattern being output. */ static int curLineWidth; /* Current line width */ static int curFont; /* Current font */ static TileTypeBitMask curMask; /* Layers currently being searched: this * is the AND of the mask from curStyle and * the layers that the user specified. */ static Rect bbox; /* Bounding box, in root coordinates, of * area being plotted. */ /* Parameters passed to the plotting process */ static char *defaultBoldFont = "/HelveticaBold"; static char *defaultFont = "/Helvetica"; char *PlotPSIdFont = NULL; char *PlotPSNameFont = NULL; char *PlotPSLabelFont = NULL; int PlotPSIdSize = 8; int PlotPSNameSize = 12; int PlotPSLabelSize = 12; int PlotPSBoundary = 1; /* Print boundaries around all layers */ int PlotPSHeight = 792; /* 11 inches * 72 PS units/inch */ int PlotPSWidth = 612; /* 8.5 inches */ int PlotPSMargin = 72; /* 1 inch */ int curx1, curx2, cury1, cury2; /* Last encountered line */ int curxbot, curybot, curwidth, curheight; /* Last encountered rectangle */ /* * ---------------------------------------------------------------------------- * * PSReset() * * Plot optimization: Reset buffered line and rectangle to default values * * ---------------------------------------------------------------------------- */ void PSReset() { curxbot = curybot = curwidth = curheight = -2; curx1 = curx2 = cury1 = cury2 = -2; } /* * ---------------------------------------------------------------------------- * PlotPSTechInit -- * * Called once at beginning of technology file read-in to initialize * data structures. * * Results: * None. * * Side effects: * Clears out the list of things to plot. * ---------------------------------------------------------------------------- */ void PlotPSTechInit() { int i, j; PSStyle *style; PSColor *color; PSPattern *pattern; /* Clear out any old information */ for (style = plotPSStyles; style != NULL; style = style->grs_next) { freeMagic((char *) style); } plotPSStyles = NULL; for (pattern = plotPSPatterns; pattern != NULL; pattern = pattern->pat_next) { freeMagic((char *) pattern); } plotPSPatterns = NULL; for (color = plotPSColors; color != NULL; color = color->col_next) { freeMagic((char *) color); } plotPSColors = NULL; if (!PlotPSIdFont) StrDup(&PlotPSIdFont, defaultFont); if (!PlotPSNameFont) StrDup(&PlotPSNameFont, defaultBoldFont); if (!PlotPSLabelFont) StrDup(&PlotPSLabelFont, defaultFont); } /* * ---------------------------------------------------------------------------- * PlotPSTechLine -- * * This procedure is invoked by the technology module once for * each line in the "ps" subsection of the "plot" 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 table of PS styles. * ---------------------------------------------------------------------------- */ bool PlotPSTechLine(sectionName, argc, argv) char *sectionName; /* Name of this section (unused). */ int argc; /* Number of arguments on line. */ char *argv[]; /* Pointers to fields of line. */ { PSStyle *newstyle; PSColor *newcolor; PSPattern *newpattern; int i, color, stipple; if (argc != 9 && argc != 5 && argc != 3) { TechError("\"ps\" lines must have either 9, 5, or 3 arguments.\n"); return TRUE; } if (argc == 9) /* pattern definition */ { newpattern = (PSPattern *) mallocMagic(sizeof(PSPattern)); sscanf(argv[0], "%d", &(newpattern->index)); for(i = 0; i < 8; i++) { sscanf(argv[1 + i], "%08lx", &(newpattern->stipple[i])); } newpattern->pat_next = plotPSPatterns; plotPSPatterns = newpattern; } else if (argc == 5) /* color definition */ { int tmpint; newcolor = (PSColor *) mallocMagic(sizeof(PSColor)); sscanf(argv[0], "%d", &(newcolor->index)); for(i = 0; i < 4; i++) { sscanf(argv[1 + i], "%d", &tmpint); newcolor->color[i] = (unsigned char)(tmpint & 0xff); } newcolor->col_next = plotPSColors; plotPSColors = newcolor; } else { /* 3 args: layer definition */ if (!StrIsInt(argv[1])) { TechError("2nd field must be an integer\n"); return TRUE; } color = atoi(argv[1]); if (strcmp(argv[2], "X") == 0) stipple = CROSS; else if (strcmp(argv[2], "B") == 0) stipple = BORDER; else if (strcmp(argv[2], "S") == 0) stipple = SOLID; else { if (!StrIsInt(argv[2])) { TechError("3rd field must be an integer or \"S\", \"X\", or \"B\".\n"); return TRUE; } stipple = atoi(argv[2]); } newstyle = (PSStyle *) mallocMagic(sizeof(PSStyle)); DBTechNoisyNameMask(argv[0], &newstyle->grs_layers); /* Replace non-primary contact images with primary images. */ for (i = TT_TECHDEPBASE; i < DBNumTypes; i++) { if TTMaskHasType(&newstyle->grs_layers, i) TTMaskSetMask(&newstyle->grs_layers, &DBLayerTypeMaskTbl[i]); } TTMaskAndMask(&newstyle->grs_layers, &DBUserLayerBits); newstyle->grs_stipple = stipple; newstyle->grs_color = color; newstyle->grs_next = plotPSStyles; plotPSStyles = newstyle; } return TRUE; } /* * ---------------------------------------------------------------------------- * * plotPSFlushRect() * * Plot optimization: Draw last buffered rectangle. * * ---------------------------------------------------------------------------- */ void plotPSFlushRect(style) int style; { if (curwidth > 0) { if (style == SOLID) fprintf(file, "%d %d %d %d ms\n", curxbot, curybot, curwidth, curheight); else fprintf(file, "%d %d %d %d fb\n", curxbot, curybot, curxbot + curwidth, curybot + curheight); } } /* * ---------------------------------------------------------------------------- * * plotPSFlushLine() * * Plot optimization: Draw last buffered line. * * ---------------------------------------------------------------------------- */ void plotPSFlushLine() { if (cury1 == cury2) { if (curx1 != curx2) /* true only if nothing is buffered */ fprintf(file, "%d %d %d hl\n", curx2 - curx1, curx1, cury1); } else if (curx1 == curx2) fprintf(file, "%d %d %d vl\n", cury2 - cury1, curx1, cury1); else fprintf(file, "%d %d %d %d ml\n", curx1, cury1, curx2, cury2); } /* * ---------------------------------------------------------------------------- * * plotPSLine -- * * Outputs a line into the current PS file. * * Results: * None. * * Side effects: * I/O. * * ---------------------------------------------------------------------------- */ void plotPSLine(p1, p2) Point *p1, *p2; /* Endpoints of line, given in root * coordinates. */ { int x1, x2, y1, y2, limit, diff; bool tmptf; /* Clip the line to the rectangular area being output. First, * arrange for the first x-coordinate to be the smaller, then * clip against vertical lines at the x-boundaries. */ if (p1->p_x <= p2->p_x) { x1 = p1->p_x - bbox.r_xbot; x2 = p2->p_x - bbox.r_xbot; y1 = p1->p_y - bbox.r_ybot; y2 = p2->p_y - bbox.r_ybot; } else { x1 = p2->p_x - bbox.r_xbot; x2 = p1->p_x - bbox.r_xbot; y1 = p2->p_y - bbox.r_ybot; y2 = p1->p_y - bbox.r_ybot; } limit = bbox.r_xtop - bbox.r_xbot; if ((x1 > limit) || (x2 < 0)) return; /* Now clip against horizontal lines at the y-boundaries. */ if (y2 < y1) { float tmp; tmp = y2; y2 = y1; y1 = tmp; tmp = x2; x2 = x1; x1 = tmp; } limit = bbox.r_ytop - bbox.r_ybot; if ((y1 > limit) || (y2 < 0)) return; /* compare against last output line and merge if possible */ if (((x1 == x2) && (x1 == curx1) && (x2 == curx2) && ((tmptf = (y1 == cury2)) || (y2 == cury1)))) { if (tmptf) cury2 = y2; else cury1 = y1; } else if (((y1 == y2) && (y1 == cury1) && (y2 == cury2) && ((tmptf = (x1 == curx2)) || (x2 == curx1)))) { if (tmptf) curx2 = x2; else curx1 = x1; } else { plotPSFlushLine(); curx1 = x1; curx2 = x2; cury1 = y1; cury2 = y2; } } /* * ---------------------------------------------------------------------------- * * plotPSRect -- * * Outputs PS statements to draw a rectangular area as * an outline with a given line style. * * Results: * None. * * Side effects: * Adds information to the current PS file. * * ---------------------------------------------------------------------------- */ void plotPSRect(rect, style) Rect *rect; /* Rectangle to be drawn, in root coords. */ int style; { int x, y, w, h; /* Output all boxes with any part visible. Depend on PostScript to */ /* do the clipping of any boxes crossing the plot boundary. */ x = rect->r_xbot - bbox.r_xbot; if ((x < 0) || (rect->r_xbot > bbox.r_xtop)) return; w = rect->r_xtop - rect->r_xbot; y = rect->r_ybot - bbox.r_ybot; if ((y < 0) || (rect->r_ybot > bbox.r_ytop)) return; h = rect->r_ytop - rect->r_ybot; fprintf(file, "%d %d %d %d m%c\n", x, y, w, h, (style == CROSS) ? 'x' : (style == SOLID) ? 's' : 'r'); } /* * ---------------------------------------------------------------------------- * * plotPSPaint -- * * This procedure is invoked once for each paint rectangle in * the area being plotted. * * Results: * Always returns 0 to keep the search alive. * * Side effects: * Outputs information for the tile, including stipple for its * interior, and a solid line for any portion of the boundary * of the tile that is adjacent to a tile NOT in this style. * * ---------------------------------------------------------------------------- */ int plotPSPaint(tile, cxp) Tile *tile; /* Tile that's of type to be output. */ TreeContext *cxp; /* Describes search in progress. */ { Rect tileArea, edge, rootArea; int xbot, width, ybot, height; Tile *neighbor; SearchContext *scx = cxp->tc_scx; bool tmptf; TileType ntype; /* First transform tile coords to root coords */ TiToRect(tile, &tileArea); GeoTransRect(&scx->scx_trans, &tileArea, &rootArea); /* See if this tile gets special handling. */ if ((curStyle->grs_stipple == CROSS) || (curStyle->grs_stipple == BORDER)) { /* Draw tile as a thick outline with a cross from corner * to corner, and skip the rest of this procedure. */ Point ul, lr; if (curLineWidth != PS_MEDIUM) { fprintf(file, "l2\n"); curLineWidth = PS_MEDIUM; } plotPSRect(&rootArea, curStyle->grs_stipple); return 0; } /* If this is a triangle, output the last rect and deal with this one */ /* individually. */ if (IsSplit(tile)) { int np, i, j; TileType dinfo; Point polyp[5]; plotPSFlushRect(curStyle->grs_stipple); plotPSFlushLine(); PSReset(); /* Side and direction are altered by geometric transformations */ dinfo = DBTransformDiagonal(TiGetTypeExact(tile), &scx->scx_trans); /* Use GrClipTriangle() routine to get the n-sided polygon that */ /* results from clipping a triangle to the clip region. */ GrClipTriangle(&rootArea, &bbox, TRUE, dinfo, polyp, &np); for (i = 0; i < np; i++) { polyp[i].p_x -= bbox.r_xbot; polyp[i].p_y -= bbox.r_ybot; fprintf(file, "%d %d ", polyp[i].p_x, polyp[i].p_y); } fprintf(file, "%d tb\n", np); if (PlotPSBoundary) { if (curLineWidth != PS_THIN) { fprintf(file, "l1\n"); curLineWidth = PS_THIN; } /* Diagonal is always drawn */ for (i = 0; i < np; i++) { j = (i + 1) % np; if (polyp[i].p_x != polyp[j].p_x && polyp[i].p_y != polyp[j].p_y) { fprintf(file, "%d %d %d %d ml\n", polyp[i].p_x, polyp[i].p_y, polyp[j].p_x, polyp[j].p_y); break; } } } } else { /* This tile gets "normal" processing (i.e. stippling and outlining). * Clip it to the plotting area and output. */ GeoClip(&rootArea, &bbox); xbot = rootArea.r_xbot - bbox.r_xbot; width = rootArea.r_xtop - rootArea.r_xbot; ybot = rootArea.r_ybot - bbox.r_ybot; height = rootArea.r_ytop - rootArea.r_ybot; /* compare against last output rectangle and merge if possible */ if ((width == curwidth) && (xbot == curxbot) && ((tmptf = (ybot == curybot + curheight)) || (ybot + height == curybot))) { curheight += height; if (!tmptf) curybot = ybot; } else if ((height == curheight) && (ybot == curybot) && ((tmptf = (xbot == curxbot + curwidth)) || (xbot + width == curxbot))) { curwidth += width; if (!tmptf) curxbot = xbot; } else { plotPSFlushRect(curStyle->grs_stipple); curheight = height; curwidth = width; curxbot = xbot; curybot = ybot; } if (PlotPSBoundary && (curLineWidth != PS_THIN)) { fprintf(file, "l1\n"); curLineWidth = PS_THIN; } } if (!PlotPSBoundary) return 0; /* No borders */ /* Now output lines for any edges between material of the type * currently being drawn and material of other types. This is * done by searching along the tile's borders for neighbors that * have the wrong types. First, search the tile's bottom border * (unless it is at infinity). * * (This code is essentially a duplicate of selRedisplayFunc()) */ if (IsSplit(tile) && (!(SplitSide(tile) ^ SplitDirection(tile)))) goto searchleft; /* nothing on bottom of split */ if (tileArea.r_ybot > TiPlaneRect.r_ybot) { edge.r_ybot = edge.r_ytop = tileArea.r_ybot; for (neighbor = LB(tile); LEFT(neighbor) < tileArea.r_xtop; neighbor = TR(neighbor)) { ntype = TiGetTopType(neighbor); if (TTMaskHasType(&curMask, ntype)) continue; edge.r_xbot = LEFT(neighbor); edge.r_xtop = RIGHT(neighbor); if (edge.r_xbot < tileArea.r_xbot) edge.r_xbot = tileArea.r_xbot; if (edge.r_xtop > tileArea.r_xtop) edge.r_xtop = tileArea.r_xtop; GeoTransRect(&scx->scx_trans, &edge, &rootArea); plotPSLine(&rootArea.r_ll, &rootArea.r_ur); } } /* Now go along the tile's left border, doing the same thing. Ignore * edges that are at infinity. */ searchleft: if (IsSplit(tile) && SplitSide(tile)) goto searchtop; /* Nothing on left side of tile */ if (tileArea.r_xbot > TiPlaneRect.r_xbot) { edge.r_xbot = edge.r_xtop = tileArea.r_xbot; for (neighbor = BL(tile); BOTTOM(neighbor) < tileArea.r_ytop; neighbor = RT(neighbor)) { ntype = TiGetRightType(neighbor); if (TTMaskHasType(&curMask, ntype)) continue; edge.r_ybot = BOTTOM(neighbor); edge.r_ytop = TOP(neighbor); if (edge.r_ybot < tileArea.r_ybot) edge.r_ybot = tileArea.r_ybot; if (edge.r_ytop > tileArea.r_ytop) edge.r_ytop = tileArea.r_ytop; GeoTransRect(&scx->scx_trans, &edge, &rootArea); plotPSLine(&rootArea.r_ll, &rootArea.r_ur); } } /* Same thing for the tile's top border. */ searchtop: if (IsSplit(tile) && (SplitSide(tile) ^ SplitDirection(tile))) goto searchright; /* Nothing on top side of tile */ if (tileArea.r_ytop < TiPlaneRect.r_ytop) { edge.r_ybot = edge.r_ytop = tileArea.r_ytop; for (neighbor = RT(tile); RIGHT(neighbor) > tileArea.r_xbot; neighbor = BL(neighbor)) { ntype = TiGetBottomType(neighbor); if (TTMaskHasType(&curMask, ntype)) continue; edge.r_xbot = LEFT(neighbor); edge.r_xtop = RIGHT(neighbor); if (edge.r_xbot < tileArea.r_xbot) edge.r_xbot = tileArea.r_xbot; if (edge.r_xtop > tileArea.r_xtop) edge.r_xtop = tileArea.r_xtop; GeoTransRect(&scx->scx_trans, &edge, &rootArea); plotPSLine(&rootArea.r_ll, &rootArea.r_ur); } } /* Finally, the right border. */ searchright: if (IsSplit(tile) && !SplitSide(tile)) return 0; /* Nothing on right side of tile */ if (tileArea.r_xtop < TiPlaneRect.r_xtop) { edge.r_xbot = edge.r_xtop = tileArea.r_xtop; for (neighbor = TR(tile); TOP(neighbor) > tileArea.r_ybot; neighbor = LB(neighbor)) { ntype = TiGetLeftType(neighbor); if (TTMaskHasType(&curMask, ntype)) continue; edge.r_ybot = BOTTOM(neighbor); edge.r_ytop = TOP(neighbor); if (edge.r_ybot < tileArea.r_ybot) edge.r_ybot = tileArea.r_ybot; if (edge.r_ytop > tileArea.r_ytop) edge.r_ytop = tileArea.r_ytop; GeoTransRect(&scx->scx_trans, &edge, &rootArea); plotPSLine(&rootArea.r_ll, &rootArea.r_ur); } } return 0; } /* * ---------------------------------------------------------------------------- * * plotPSLabelPosition -- * * Determine the label position, orientation, and approximate bounding box * * ---------------------------------------------------------------------------- */ int plotPSLabelPosition(scx, label, x, y, p) SearchContext *scx; /* Describes state of search when label * was found. */ Label *label; /* Label that was found. */ int *x; /* returned x position */ int *y; /* returned y position */ int *p; /* returned orientation */ { Rect rootArea; int pos; /* Mapping from our GEO_xxx positions to PS object types: */ static int psPosition[] = { 5, /* CENTCENT */ 1, /* TOPCENT */ 0, /* TOPRIGHT */ 4, /* CENTRIGHT */ 12, /* BOTRIGHT */ 13, /* BOTCENT */ 15, /* BOTLEFT */ 7, /* CENTLEFT */ 3 /* TOPLEFT */ }; GeoTransRect(&scx->scx_trans, &label->lab_rect, &rootArea); pos = GeoTransPos(&scx->scx_trans, label->lab_just); switch (pos) { case GEO_NORTH: case GEO_NORTHEAST: case GEO_NORTHWEST: *y = (rootArea.r_ytop - bbox.r_ybot); *y += delta; break; case GEO_CENTER: case GEO_WEST: case GEO_EAST: *y = (rootArea.r_ytop + rootArea.r_ybot) / 2 - bbox.r_ybot; break; case GEO_SOUTH: case GEO_SOUTHEAST: case GEO_SOUTHWEST: *y = (rootArea.r_ybot - bbox.r_ybot); *y -= delta; break; } switch (pos) { case GEO_WEST: case GEO_NORTHWEST: case GEO_SOUTHWEST: *x = (rootArea.r_xbot - bbox.r_xbot); *x -= delta; break; case GEO_CENTER: case GEO_NORTH: case GEO_SOUTH: *x = (rootArea.r_xtop + rootArea.r_xbot) / 2 - bbox.r_xbot; break; case GEO_EAST: case GEO_NORTHEAST: case GEO_SOUTHEAST: *x = (rootArea.r_xtop - bbox.r_xbot); *x += delta; break; } *p = psPosition[pos]; return 0; } /* * ---------------------------------------------------------------------------- * * plotPSLabelBounds -- * * Estimate the bounding box extension based on label strings. * In reality, we need to know label sizes to compute the scale, * and we need to know the scale to compute label sizes. However, * in practice, we can only estimate the label size anyway, so we * allow for some slop and just wing it. * * ---------------------------------------------------------------------------- */ #define AVGCHARWIDTH 0.7 #define CHARHEIGHT 1.4 int plotPSLabelBounds(scx, label) SearchContext *scx; /* Describes state of search when label * was found. */ Label *label; /* Label that was found. */ { int pspos; int ls, psxsize, psysize; int llx, lly, urx, ury; int psdelta = (int)((float)delta / fscale); plotPSLabelPosition(scx, label, &llx, &lly, &pspos); urx = (int)((float)(llx - bbox.r_xtop) / fscale); ury = (int)((float)(lly - bbox.r_ytop) / fscale); llx = (int)((float)(bbox.r_xbot - llx) / fscale); lly = (int)((float)(bbox.r_ybot - lly) / fscale); ls = strlen(label->lab_text); psxsize = ls * (int)((float)PlotPSLabelSize * AVGCHARWIDTH); psysize = (int)((float)PlotPSLabelSize * CHARHEIGHT); switch (pspos) { case 0: ury += psysize + psdelta; urx += psxsize + psdelta; break; case 4: ury += psysize / 2; lly += psysize / 2; urx += psxsize + psdelta; break; case 12: lly += psysize + psdelta; urx += psxsize + psdelta; break; case 13: lly += psysize + psdelta; urx += psxsize / 2; llx += psxsize / 2; break; case 15: lly += psysize + psdelta; llx += psxsize + psdelta; break; case 7: ury += psysize / 2; lly += psysize / 2; llx += psxsize + psdelta; break; case 3: ury += psysize + psdelta; llx += psxsize + psdelta; break; case 1: ury += psysize + psdelta; urx += psxsize / 2; llx += psxsize / 2; break; case 5: ury += psysize / 2; lly += psysize / 2; urx += psxsize / 2; llx += psxsize / 2; break; } if (xpmargin < urx) xpmargin = urx; if (ypmargin < ury) ypmargin = ury; if (xnmargin < llx) xnmargin = llx; if (ynmargin < lly) ynmargin = lly; return 0; } /* * ---------------------------------------------------------------------------- * * plotPSLabelBox -- * * Output the box connected to a label * * ---------------------------------------------------------------------------- */ int plotPSLabelBox(scx, label) SearchContext *scx; /* Describes state of search when label * was found. */ Label *label; /* Label that was found. */ { Rect rootArea; int x, y; GeoTransRect(&scx->scx_trans, &label->lab_rect, &rootArea); /* Output lines marking the label's area. Different things are * done depending on whether the label is a point, a line, or an * area. */ if (curLineWidth != PS_MEDIUM) { fprintf(file, "l2\n"); curLineWidth = PS_MEDIUM; } if ((rootArea.r_xbot == rootArea.r_xtop) && (rootArea.r_ybot == rootArea.r_ytop)) { /* Point label. Output a cross. */ x = (rootArea.r_xbot - bbox.r_xbot); y = (rootArea.r_ybot - bbox.r_ybot); fprintf(file, "%d %d %d pl\n", delta, x, y); } else if ((rootArea.r_xbot == rootArea.r_xtop) || (rootArea.r_ybot == rootArea.r_ytop)) { /* Line label. Just draw a medium-thickness line. */ plotPSLine(&rootArea.r_ll, &rootArea.r_ur); } else { /* Rectangular. Draw lines around the boundary. */ plotPSRect(&rootArea, 0); } return 0; } /* * ---------------------------------------------------------------------------- * * plotPSLabel -- * * This procedure is invoked once for each label overlapping the * area being plotted. It generates PS output to describe * the label. * * Results: * Always returns 0 to keep the search from aborting. * * Side effects: * PS information is output. * * ---------------------------------------------------------------------------- */ int plotPSLabel(scx, label) SearchContext *scx; /* Describes state of search when label * was found. */ Label *label; /* Label that was found. */ { int x, y; int pspos; plotPSLabelPosition(scx, label, &x, &y, &pspos); /* Output the text for the label, if the label is within delta * of the area we're plotting (a large label could overlap a * bit of the area but stick out way off-screen too). */ if ((x >= -delta) && (y >= -delta) && (x <= (bbox.r_xtop - bbox.r_xbot) + delta) && (y <= (bbox.r_ytop - bbox.r_ybot) + delta)) { fprintf(file, "(%s) %d %d %d lb\n", label->lab_text, pspos, x, y); } return 0; } /* * ---------------------------------------------------------------------------- * * plotPSCell -- * * This procedure is invoked once for each unexpanded cell that * overlaps the area being plotted. * * Results: * Always returns 0 to keep the search from aborting. * * Side effects: * PS information is output to describe the cell. * * ---------------------------------------------------------------------------- */ int plotPSCell(scx) SearchContext *scx; /* Describes cell whose bbox is to * be plotted. */ { extern bool PlotShowCellNames; char idName[100]; Rect rootArea; CellDef *def; int x, y; /* Convert the cell's bounding box to root coordinates and then * draw as a thick outline. */ def = scx->scx_use->cu_def; GeoTransRect(&scx->scx_trans, &def->cd_bbox, &rootArea); if (curLineWidth != PS_THICK) { fprintf(file, "l3\n"); curLineWidth = PS_THICK; } plotPSRect(&rootArea, 0); if (!PlotShowCellNames) return 0; /* Output the cell definition's name in the top of the bounding box. * Use a bold font (#3), in a medium size (#2). Make sure that the * name's positioning point is within the area we're plotting. */ x = (rootArea.r_xtop + rootArea.r_xbot - 2*bbox.r_xbot)/2; y = (2*rootArea.r_ytop + rootArea.r_ybot - 3*bbox.r_ybot)/3; if ((x >= 0) && (y >= 0) && (x <= (bbox.r_xtop - bbox.r_xbot)) && (y <= (bbox.r_ytop - bbox.r_ybot))) { fprintf(file, "f2 (%s) 5 %d %d lb\n", def->cd_name, x, y); } /* Output the cell id in the bottom of the bounding box. * Use an italic font (#2) in a medium size (#2). */ x = (rootArea.r_xtop + rootArea.r_xbot - 2*bbox.r_xbot)/2; y = (rootArea.r_ytop + 2*rootArea.r_ybot - 3*bbox.r_ybot)/3; if ((x >= 0) && (y >= 0) && (x <= (bbox.r_xtop - bbox.r_xbot)) && (y <= (bbox.r_ytop - bbox.r_ybot))) { (void) DBPrintUseId(scx, idName, 100, TRUE); fprintf(file, "f3 (%s) 5 %d %d lb\n", idName, x, y); } return 0; } /* * ---------------------------------------------------------------------------- * * PlotPS -- * * This procedure generates a PS file to describe an area of * a layout. * * Results: * None. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ void PlotPS(fileName, scx, layers, xMask) char *fileName; /* Name of PS file to write. */ SearchContext *scx; /* The use and area and transformation * in this describe what to plot. */ TileTypeBitMask *layers; /* Tells what layers to plot. Only * paint layers in this mask, and also * expanded according to xMask, are * plotted. If L_LABELS is set, then * labels on the layers are also * plotted, if expanded according to * xMask. If L_CELL is set, then * subcells that are unexpanded * according to xMask are plotted as * bounding boxes. */ int xMask; /* An expansion mask, used to indicate * the window whose expansion status * will be used to determine * visibility. Zero means treat * everything as expanded. */ { int xsize, ysize; float yscale; FILE *infile; int i, j; int twidth, theight; char *fontptr, *fptr2, *fptr3; char line_in[100]; PSReset(); /* Compute a scale factor between our coordinates and PS * coordinates. */ GeoTransRect(&scx->scx_trans, &scx->scx_area, &bbox); xsize = bbox.r_xtop - bbox.r_xbot; ysize = bbox.r_ytop - bbox.r_ybot; fscale = (float)(PlotPSWidth - 2 * PlotPSMargin) / (float)xsize; yscale = (float)(PlotPSHeight - 2 * PlotPSMargin) / (float)ysize; if (yscale < fscale) fscale = yscale; /* Compute a distance equal to 1/8th the size of a typical wire * (max of thicknesses of routing layers). This is used to offset * text from labels and to compute cross size for point labels. */ if (RtrMetalWidth > RtrPolyWidth) delta = RtrMetalWidth / 8; else delta = RtrPolyWidth / 8; if (delta == 0) delta = 1; /* Go through labels once to estimate the bounding box, including labels */ xnmargin = ynmargin = xpmargin = ypmargin = 0; if (TTMaskHasType(layers, L_LABEL)) { curMask = *layers; TTMaskSetType(&curMask, TT_SPACE); (void) DBTreeSrLabels(scx, &curMask, xMask, (TerminalPath *) NULL, TF_LABEL_ATTACH, plotPSLabelBounds, (ClientData) NULL); fscale = (float)(PlotPSWidth - 2 * PlotPSMargin - xnmargin - xpmargin) / (float)(xsize); yscale = (float)(PlotPSHeight - 2 * PlotPSMargin - ynmargin - ypmargin) / (float)(ysize); if (yscale < fscale) fscale = yscale; } twidth = (xsize * fscale) + xnmargin + xpmargin; theight = (ysize * fscale) + ynmargin + ypmargin; /* Open the PS file and output header information. */ file = PaOpen(fileName, "w", (char *) NULL, ".", (char *) NULL, (char **) NULL); if (file == NULL) { TxError("Couldn't write PS file \"%s\".\n", fileName); return; } fprintf(file, "%%!PS-Adobe-3.0 EPSF-3.0\n"); fprintf(file, "%%%%BoundingBox: %d %d %d %d\n", PlotPSMargin, PlotPSMargin, twidth + PlotPSMargin, theight + PlotPSMargin); fontptr = PlotPSIdFont; fprintf(file, "%%%%DocumentNeededResources: font %s", fontptr); if (!Match(fptr2 = PlotPSNameFont, fontptr)); fprintf(file, " font %s", fptr2); if (!Match(fptr3 = PlotPSLabelFont, fontptr)) if (!Match(fptr3, fptr2)) fprintf(file, " font %s", fptr3); fprintf(file, "\n"); fprintf(file, "%%%%EndComments\n"); /* Insert the prolog here */ infile = PaOpen("magicps", "r", ".pro", ".", SysLibPath, NULL); if (infile != NULL) while(fgets(line_in, 99, infile) != NULL) fputs(line_in, file); else fprintf(file, "\npostscript_prolog_is_missing\n\n"); /* Insert the font definitions here. */ fprintf(file, "/f1 { %.3f %s sf } def\n", (float)PlotPSLabelSize / fscale, PlotPSLabelFont); fprintf(file, "/f2 { %.3f %s sf } def\n", (float)PlotPSNameSize / fscale, PlotPSNameFont); fprintf(file, "/f3 { %.3f %s sf } def\n", (float)PlotPSIdSize / fscale, PlotPSIdFont); /* Insert the color and stipple definitions here. */ for (curColor = plotPSColors; curColor != NULL; curColor = curColor->col_next) { fprintf(file, "/col%d {%.3f %.3f %.3f %.3f sc} bind def\n", curColor->index, (float)curColor->color[0] / 255.0, (float)curColor->color[1] / 255.0, (float)curColor->color[2] / 255.0, (float)curColor->color[3] / 255.0); } for (curPattern = plotPSPatterns; curPattern != NULL; curPattern = curPattern->pat_next) { fprintf(file, "{<"); for (j = 0; j < 8; j++) fprintf(file, "%08lx%08lx", curPattern->stipple[j], curPattern->stipple[j]); fprintf(file, ">} %d dp\n", curPattern->index); } fprintf(file, "%%%%EndResource\n%%%%EndProlog\n\n"); fprintf(file, "%%%%Page: 1 1\n"); fprintf(file, "/pgsave save def bop\n"); fprintf(file, "%% 0 0 offsets\nninit\n"); fprintf(file, "%d %d translate\n", PlotPSMargin + xnmargin, PlotPSMargin + ynmargin); fprintf(file, "%.3f %.3f scale\nminit\n", fscale, fscale); fprintf(file, "0 0 %d %d gsave rectclip\n", xsize, ysize); fprintf(file, "l2\nsp\n\n"); curLineWidth = PS_MEDIUM; /* For each PS style, find all the paint layers that belong * to that style and put plot information into the file. */ for (curStyle = plotPSStyles; curStyle != NULL; curStyle = curStyle->grs_next) { fprintf(file, "col%d\n", curStyle->grs_color); if (curStyle->grs_stipple >= 0) fprintf(file, "%d sl\n", curStyle->grs_stipple); TTMaskAndMask3(&curMask, layers, &curStyle->grs_layers); (void) DBTreeSrTiles(scx, &curMask, xMask, plotPSPaint, (ClientData) NULL); plotPSFlushRect(curStyle->grs_stipple); plotPSFlushLine(); PSReset(); } /* Output subcell bounding boxes, if they are wanted. */ if (TTMaskHasType(layers, L_CELL)) { (void) DBTreeSrCells(scx, xMask, plotPSCell, (ClientData) NULL); plotPSFlushRect(BORDER); plotPSFlushLine(); } /* Output label boxes followed by labels */ if (TTMaskHasType(layers, L_LABEL)) { curMask = *layers; TTMaskSetType(&curMask, TT_SPACE); (void) DBTreeSrLabels(scx, &curMask, xMask, (TerminalPath *) NULL, TF_LABEL_ATTACH, plotPSLabelBox, (ClientData) NULL); plotPSFlushRect(BORDER); plotPSFlushLine(); PSReset(); fprintf(file, "grestore\n"); /* end clipping rectangle */ fprintf(file, "f1 0 setgray\n"); /* set font, set color to black */ curMask = *layers; TTMaskSetType(&curMask, TT_SPACE); (void) DBTreeSrLabels(scx, &curMask, xMask, (TerminalPath *) NULL, TF_LABEL_ATTACH, plotPSLabel, (ClientData) NULL); } else { fprintf(file, "grestore\n"); /* end clipping rectangle */ } /* Output trailer information into the file, and close it. */ fprintf(file, "pgsave restore showpage\n\n"); fprintf(file, "%%%%Trailer\nMAGICsave restore\n%%%%EOF\n"); fclose(file); return; } magic-8.0.210/plot/plotVers.c0000644000175000001440000012256011410650605014416 0ustar timusers/* * plotVers.c -- * * This file contains the procedures that generate plots on * Versatec-style black-and-white printers. * * ********************************************************************* * * 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/plot/plotVers.c,v 1.3 2010/06/24 12:37:25 tim Exp $"; #endif /* not lint */ #include #include #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 "utils/malloc.h" #include "plot/plotInt.h" #include "windows/windows.h" #include "commands/commands.h" #include "textio/textio.h" #include "utils/utils.h" #include "utils/tech.h" #include "utils/signals.h" #include "dbwind/dbwind.h" #include "cif/cif.h" /* for CIFGetOutputScale() */ #ifdef VERSATEC /* Library imports: */ extern int rasFileByteCount; /* Records of the following type are used to describe how to generate * output for the mask layers. Each style describes a particular * stipple pattern. */ typedef struct versatecstyle { TileTypeBitMask vs_layers; /* Layers to plot in this style. */ Stipple vs_stipple; /* Stipple pattern to use. */ int vs_flags; /* Flag bits, see below. */ struct versatecstyle *vs_next; /* Pointer to next style in list. */ /* If the color flag is false, all stipples will be black */ VersatecColor vs_color; /* Stipple color */ } VersatecStyle; /* Flag values for VersatecStyles: * * VS_CROSS - if this bit is set, then generate an outline with an * X through the middle, like for contacts, instead of * stippling. The stipple pattern is ignored in this * case. * VS_BORDER - if this bit is set, generate an outline with no X * through the middle and no stipple. The stipple * pattern is ignored in this case. */ #define VS_CROSS 1 #define VS_BORDER 2 static VersatecStyle *plotVersStyles; static VersatecStyle *plotColorVersStyles; char *plotVersatecColorNames[] = { "Black", "Cyan", "Magenta", "Yellow" }; /* * ---------------------------------------------------------------------------- * The parameters below control various aspects of the plotting * process. The initial values are defaults for the versatec * printer. However, many of them can be modified by users * with the "plot option" command. * ---------------------------------------------------------------------------- */ /* Supported format. Default is "hprtl". */ unsigned char PlotVersPlotType = HPRTL; int PlotVersWidth = 2400; /* Number of dots across Versatec page. * Should be a multiple of 32. */ int PlotVersDotsPerInch = 300; /* Dots per inch. */ int PlotVersSwathHeight = 64; /* Width of swath to generate at one time, * in dots. */ /* Name of printer to use for output: */ static char *defaultPrinter = "versatec"; char *PlotVersPrinter = NULL; /* Command to use to actually print rasterized file. Contains two %s'es, * which are supplied with the printer name and the name of the raster file. */ static char *defaultCommand = "lp -d %s %s"; char *PlotVersCommand = NULL; /* Directory in which to create temporary file to hold raster: */ static char *defaultDirectory = "/tmp"; char *PlotTempDirectory = NULL; /* Name of fonts to use: */ static char *defaultIdFont = "vfont.I.12"; char *PlotVersIdFont = NULL; static char *defaultNameFont = "vfont.B.12"; char *PlotVersNameFont = NULL; static char *defaultLabelFont = "vfont.R.8"; char *PlotVersLabelFont = NULL; /* * ---------------------------------------------------------------------------- * The variables below are shared between the top-level Versatec * plotting procedure and the lower-level search functions. They * contain specific information about how to generate the current * plot. There area three coordinate systems of interest here: * * 1. Magic root coordinates. * 2. Raster coordinates: based on printer pixels, one unit per pixel, * where (0,0) corresponds to the lower-leftmost dot that will be * printed. * 3. Swath coordinates: the raster will be much too large to keep in * memory all at once, so it's generated in a series of horizontal * swaths. The stippling routines all work in swath-relative * coordinates, which are the same as raster coordinates except for * a y-displacement (swathY below). * ---------------------------------------------------------------------------- */ Point plotLL; /* Point in root Magic coords that corresponds * to (0,0) in raster coordinates. */ int swathY; /* The y-coordinate in raster coordinates that * corresponds to (0,0) in swath coords. It's * always >= 0. */ static int scale; /* How many (2**scaleShift)-ths of a pixel * correspond to one Magic unit. */ int scaleShift; /* The idea is that one Magic unit is equal * to scale/(2**scaleShift) pixels. */ static Rect rootClip; /* Total root area of the plot. Used for * clipping. */ static Rect swathClip; /* Rectangle used for clipping to the area of * the current swath. This is in swath * coordinates. */ static VersatecStyle *curStyle; /* Current style being processed. */ static TileTypeBitMask curMask; /* Mask of layers currently being stippled. * This is the AND of the mask from curStyle * and the layers that the user wants plotted. */ static int crossSize; /* Length of each arm of the crosses used * to draw labels, in pixel units. */ static RasterFont *labelFont; /* Font to use when rendering labels. */ static RasterFont *cellNameFont; /* Font to use when rendering cell names. */ static RasterFont *cellIdFont; /* Font to use when rendering cell ids. */ #endif /* VERSATEC */ /* * ---------------------------------------------------------------------------- * PlotVersTechInit -- * * Called once at beginning of technology file read-in to initialize * data structures. * * Results: * None. * * Side effects: * Clears out the list of things to plot. * ---------------------------------------------------------------------------- */ #ifdef VERSATEC void PlotVersTechInit() { VersatecStyle *style; for (style = plotVersStyles; style != NULL; style = style->vs_next) { freeMagic((char *) style); } plotVersStyles = NULL; if (PlotVersPrinter == NULL) StrDup(&PlotVersPrinter, defaultPrinter); if (PlotVersCommand == NULL) StrDup(&PlotVersCommand, defaultCommand); if (PlotTempDirectory == NULL) StrDup(&PlotTempDirectory, defaultDirectory); if (PlotVersIdFont == NULL) StrDup(&PlotVersIdFont, defaultIdFont); if (PlotVersNameFont == NULL) StrDup(&PlotVersNameFont, defaultNameFont); if (PlotVersLabelFont == NULL) StrDup(&PlotVersLabelFont, defaultLabelFont); } #else void PlotVersTechInit() {} #endif /* VERSATEC */ /* * ---------------------------------------------------------------------------- * PlotColorVersTechInit -- * * Called once at beginning of technology file read-in to initialize * data structures. * * Results: * None. * * Side effects: * Clears out the list of things to plot. * ---------------------------------------------------------------------------- */ #ifdef VERSATEC void PlotColorVersTechInit() { VersatecStyle *style; for (style = plotColorVersStyles; style != NULL; style = style->vs_next) { freeMagic((char *) style); } plotColorVersStyles = NULL; if (PlotVersPrinter == NULL) StrDup(&PlotVersPrinter, defaultPrinter); if (PlotVersCommand == NULL) StrDup(&PlotVersCommand, defaultCommand); if (PlotTempDirectory == NULL) StrDup(&PlotTempDirectory, defaultDirectory); if (PlotVersIdFont == NULL) StrDup(&PlotVersIdFont, defaultIdFont); if (PlotVersNameFont == NULL) StrDup(&PlotVersNameFont, defaultNameFont); if (PlotVersLabelFont == NULL) StrDup(&PlotVersLabelFont, defaultLabelFont); } #else void PlotColorVersTechInit() {} #endif /* VERSATEC */ /* * ---------------------------------------------------------------------------- * PlotVersTechLine -- * * This procedure is invoked by the technology module once for * each line in the "versatec" subsection of the "plot" 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 table of Versatec styles. * ---------------------------------------------------------------------------- */ #ifdef VERSATEC bool PlotVersTechLine(sectionName, argc, argv) char *sectionName; /* Name of this section (unused). */ int argc; /* Number of arguments on line. */ char *argv[]; /* Pointers to fields of line. */ { VersatecStyle *new; int i; new = (VersatecStyle *) mallocMagic(sizeof(VersatecStyle)); DBTechNoisyNameMask(argv[0], &new->vs_layers); if (argc == 2) { if (strcmp(argv[1], "X") == 0) new->vs_flags = VS_CROSS; else if (strcmp(argv[1], "B") == 0) new->vs_flags = VS_BORDER; else { TechError("Second field must be \"X\" or \"B\"\n"); freeMagic((char *) new); return TRUE; } } else { int i, value; if (argc != 17) { TechError("\"versatec\" lines must have either 2 or 17 fields.\n"); freeMagic((char *)new); return TRUE; } new->vs_color = 0; new->vs_flags = 0; for (i = 0; i < 16; i++) { (void) sscanf(argv[i+1], "%x", &value); new->vs_stipple[i] = (value<<16) | (value & 0xffff); #ifndef WORDS_BIGENDIAN new->vs_stipple[i] = PlotSwapBytes(new->vs_stipple[i]); #endif /* WORDS_BIGENDIAN */ } } new->vs_next = plotVersStyles; plotVersStyles = new; return TRUE; } #else bool PlotVersTechLine(sectionName, argc, argv) char *sectionName; /* Name of this section (unused). */ int argc; /* Number of arguments on line. */ char *argv[]; /* Pointers to fields of line. */ { return TRUE; } #endif /* VERSATEC */ /* * ---------------------------------------------------------------------------- * PlotColorVersTechLine -- * * This procedure is invoked by the technology module once for * each line in the "colorversatec" subsection of the "plot" 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 table of ColorVersatec styles. * ---------------------------------------------------------------------------- */ #ifdef VERSATEC bool PlotColorVersTechLine(sectionName, argc, argv) char *sectionName; /* Name of this section (unused). */ int argc; /* Number of arguments on line. */ char *argv[]; /* Pointers to fields of line. */ { VersatecStyle *new; static struct { char *l_str; int l_color; } colors[] = { "black", BLACK, "cyan", CYAN, "magenta", MAGENTA, "yellow", YELLOW, "K", BLACK, "C", CYAN, "M", MAGENTA, "Y", YELLOW, 0 }; int i; new = (VersatecStyle *)mallocMagic(sizeof(VersatecStyle)); DBTechNoisyNameMask(argv[0], &new->vs_layers); if (argc == 2) { new->vs_color = BLACK; if (strcmp(argv[1], "X") == 0) new->vs_flags = VS_CROSS; else if (strcmp(argv[1], "B") == 0) new->vs_flags = VS_BORDER; else { TechError("Second field must be \"X\" or \"B\"\n"); freeMagic((char *) new); return TRUE; } } else { int i, j, value; if (argc != 3 && argc != 4 && argc != 6 && argc != 10 && argc != 18) { TechError("\"colorversatec\" lines must have 2 fields + 1, 2, 4, 8," " or 16 stipple word values.\n"); freeMagic((char *)new); return TRUE; } i = LookupStruct(argv[1], (LookupTable *) colors, sizeof colors[0]); if (i < 0) { TechError("First field must be BLACK, CYAN, MAGENTA or YELLOW.\n"); freeMagic((char *)new); return TRUE; } new->vs_color = colors[i].l_color; new->vs_flags = 0; for (j = 0; j < 16; j += (argc - 2)) { for (i = 0; i < (argc - 2); i++) { sscanf(argv[i + 2], "%x", &value); new->vs_stipple[j + i] = (value << 16) | (value & 0xffff); #ifndef WORDS_BIGENDIAN new->vs_stipple[j + i] = PlotSwapBytes(new->vs_stipple[i]); #endif /* WORDS_BIGENDIAN */ } } } new->vs_next = plotColorVersStyles; plotColorVersStyles = new; return TRUE; } #else bool PlotColorVersTechLine(sectionName, argc, argv) char *sectionName; /* Name of this section (unused). */ int argc; /* Number of arguments on line. */ char *argv[]; /* Pointers to fields of line. */ { return TRUE; } #endif /* VERSATEC */ #ifdef VERSATEC /* * ---------------------------------------------------------------------------- * * plotTransToSwath -- * * Transforms a rectangle from Magic root coordinates to the * coordinates of the current swath. * * Results: * None. * * Side effects: * Dst is modified to hold a rectangle that has been transformed * to swath coordinates. * * ---------------------------------------------------------------------------- */ void plotTransToSwath(src, dst) Rect *src; /* Rectangle in Magic root coords. */ Rect *dst; /* Rectangle to be filled in with swath * corresponding to src. */ { dst->r_xbot = ((src->r_xbot - plotLL.p_x)*scale) >> scaleShift; dst->r_xtop = ((src->r_xtop - plotLL.p_x)*scale) >> scaleShift; dst->r_ybot = (((src->r_ybot - plotLL.p_y)*scale) >> scaleShift) - swathY; dst->r_ytop = (((src->r_ytop - plotLL.p_y)*scale) >> scaleShift) - swathY; } /* * ---------------------------------------------------------------------------- * * plotVersLine -- * * This procedure plots a line of a given thickness. * * Results: * None. * * Side effects: * The current raster is modified. * * ---------------------------------------------------------------------------- */ void plotVersLine(area, widen, raster) Rect *area; /* The "corner" points of this rectangle * give the endpoints of the line, in * Magic root coordinates. */ int widen; /* Amount by which to widen line. 0 means * line is drawn one pixel wide, 1 means 3 * pixels wide, etc. */ Raster *raster; /* Raster to write to */ { Rect swathArea; plotTransToSwath(area, &swathArea); /* Handle Manhattan lines using rectangle-drawing, since it's faster. */ if ((swathArea.r_xbot == swathArea.r_xtop) || (swathArea.r_ybot == swathArea.r_ytop)) { GEO_EXPAND(&swathArea, widen, &swathArea); GEOCLIP(&swathArea, &swathClip); if ((swathArea.r_xbot <= swathArea.r_xtop) && (swathArea.r_ybot <= swathArea.r_ytop)) PlotFillRaster(raster, &swathArea, PlotBlackStipple); } else PlotRastFatLine(raster, &swathArea.r_ll, &swathArea.r_ur, widen); } /* * ---------------------------------------------------------------------------- * * plotVersRect -- * * This procedure takes a rectangular area, given in Magic root * coordinates, translates it to swath coordinates, and draws * it as an outline of a given thickness. * * Results: * None. * * Side effects: * Modifies raster. * * ---------------------------------------------------------------------------- */ void plotVersRect(area, widen, raster) Rect *area; /* Rectangular area to draw, in root * coordinates. */ int widen; /* If zero, rectangular outline is drawn * one pixel wide. If non-zero, the outline * is widened by this many units on each * side. */ Raster *raster; /* Raster to plot to */ { Rect side; /* First, the bottom side. */ if (area->r_xbot != area->r_xtop) { side = *area; side.r_ytop = side.r_ybot; plotVersLine(&side, widen, raster); /* Now the top side, if it doesn't coincide with the bottom. */ if (area->r_ybot != area->r_ytop) { side = *area; side.r_ybot = side.r_ytop; plotVersLine(&side, widen, raster); } } /* Now do the left side. */ if (area->r_ybot != area->r_ytop) { side = *area; side.r_xtop = side.r_xbot; plotVersLine(&side, widen, raster); /* Now the right side, if it doesn't coincide with the left. */ if (area->r_xbot != area->r_xtop) { side = *area; side.r_xbot = side.r_xtop; plotVersLine(&side, widen, raster); } } } /* * ---------------------------------------------------------------------------- * * plotVersTile -- * * This procedure is called for paint tiles. It renders each tile * in the current style, in the current swath. * * Results: * Always returns 0 to keep the search alive. * * Side effects: * Modifies the raster area. * * ---------------------------------------------------------------------------- */ int plotVersTile(tile, cxp) Tile *tile; /* Tile that's of type to be output. */ TreeContext *cxp; /* Describes search in progress. */ { Rect tileArea, rootArea, swathArea, edge; TileType ntype; Tile *neighbor; Transform *trans = &cxp->tc_scx->scx_trans; Raster *raster = (Raster *)cxp->tc_filter->tf_arg; /* Transform tile coords to root coords and then to swath coords. */ TITORECT(tile, &tileArea); GEOTRANSRECT(trans, &tileArea, &rootArea); plotTransToSwath(&rootArea, &swathArea); /* Handle X'ed things specially. */ if (curStyle->vs_flags & VS_CROSS) { if (!IsSplit(tile)) if (((swathArea.r_xtop - swathArea.r_xbot) > 6) && ((swathArea.r_ytop - swathArea.r_ybot) > 6)) { Rect r2; plotVersLine(&rootArea, 0, raster); r2.r_xtop = rootArea.r_xbot; r2.r_ybot = rootArea.r_ybot; r2.r_xbot = rootArea.r_xtop; r2.r_ytop = rootArea.r_ytop; plotVersLine(&r2, 0, raster); } } if (IsSplit(tile)) { int i, j; TileType dinfo; Rect r; dinfo = DBTransformDiagonal(TiGetTypeExact(tile), &cxp->tc_scx->scx_trans); if (!(curStyle->vs_flags & VS_BORDER) && !(curStyle->vs_flags & VS_CROSS)) PlotPolyRaster(raster, &swathArea, &swathClip, dinfo, curStyle->vs_stipple); /* Diagonal is always drawn (clipping handled in plotVersLine) */ r = rootArea; if (dinfo & TT_DIRECTION) { /* swap X to make diagonal go the other way */ r.r_xbot = r.r_xtop; r.r_xtop = rootArea.r_xbot; } plotVersLine(&r, 0, raster); } else { /* Clip and then stipple. */ GEOCLIP(&swathArea, &swathClip); if (swathArea.r_xbot > swathArea.r_xtop) return 0; if (swathArea.r_ybot > swathArea.r_ytop) return 0; if (!(curStyle->vs_flags & VS_BORDER) && !(curStyle->vs_flags & VS_CROSS)) PlotFillRaster(raster, &swathArea, curStyle->vs_stipple); } /* Now output lines for any edges between material of the type * currently being drawn and material of other types. This is * done by searching along the tile's borders for neighbors that * have the wrong types. First, search the tile's bottom border * (unless it is at infinity). */ if (IsSplit(tile) && (!(SplitSide(tile) ^ SplitDirection(tile)))) goto searchleft; /* nothing on bottom of split */ if (tileArea.r_ybot > TiPlaneRect.r_ybot) { edge.r_ybot = edge.r_ytop = tileArea.r_ybot; for (neighbor = LB(tile); LEFT(neighbor) < tileArea.r_xtop; neighbor = TR(neighbor)) { ntype = TiGetTopType(neighbor); if (TTMaskHasType(&curMask, ntype)) continue; edge.r_xbot = LEFT(neighbor); edge.r_xtop = RIGHT(neighbor); if (edge.r_xbot < tileArea.r_xbot) edge.r_xbot = tileArea.r_xbot; if (edge.r_xtop > tileArea.r_xtop) edge.r_xtop = tileArea.r_xtop; GEOTRANSRECT(trans, &edge, &rootArea); plotVersLine(&rootArea, 0, raster); } } searchleft: if (IsSplit(tile) && (SplitSide(tile))) goto searchtop; /* Nothing on left side of split */ /* Now go along the tile's left border, doing the same thing. Ignore * edges that are at infinity. */ if (tileArea.r_xbot > TiPlaneRect.r_xbot) { edge.r_xbot = edge.r_xtop = tileArea.r_xbot; for (neighbor = BL(tile); BOTTOM(neighbor) < tileArea.r_ytop; neighbor = RT(neighbor)) { ntype = TiGetRightType(neighbor); if (TTMaskHasType(&curMask, ntype)) continue; edge.r_ybot = BOTTOM(neighbor); edge.r_ytop = TOP(neighbor); if (edge.r_ybot < tileArea.r_ybot) edge.r_ybot = tileArea.r_ybot; if (edge.r_ytop > tileArea.r_ytop) edge.r_ytop = tileArea.r_ytop; GEOTRANSRECT(trans, &edge, &rootArea); plotVersLine(&rootArea, 0, raster); } } /* Same thing for the tile's top border. */ searchtop: if (IsSplit(tile) && (SplitSide(tile) ^ SplitDirection(tile))) goto searchright; /* Nothing on top side of tile */ if (tileArea.r_ytop < TiPlaneRect.r_ytop) { edge.r_ybot = edge.r_ytop = tileArea.r_ytop; for (neighbor = RT(tile); RIGHT(neighbor) > tileArea.r_xbot; neighbor = BL(neighbor)) { ntype = TiGetBottomType(neighbor); if (TTMaskHasType(&curMask, ntype)) continue; edge.r_xbot = LEFT(neighbor); edge.r_xtop = RIGHT(neighbor); if (edge.r_xbot < tileArea.r_xbot) edge.r_xbot = tileArea.r_xbot; if (edge.r_xtop > tileArea.r_xtop) edge.r_xtop = tileArea.r_xtop; GEOTRANSRECT(trans, &edge, &rootArea); plotVersLine(&rootArea, 0, raster); } } /* Finally, the right border. */ searchright: if (IsSplit(tile) && !(SplitSide(tile))) return 0; /* Nothing on right side of tile */ if (tileArea.r_xtop < TiPlaneRect.r_xtop) { edge.r_xbot = edge.r_xtop = tileArea.r_xtop; for (neighbor = TR(tile); TOP(neighbor) > tileArea.r_ybot; neighbor = LB(neighbor)) { ntype = TiGetLeftType(neighbor); if (TTMaskHasType(&curMask, ntype)) continue; edge.r_ybot = BOTTOM(neighbor); edge.r_ytop = TOP(neighbor); if (edge.r_ybot < tileArea.r_ybot) edge.r_ybot = tileArea.r_ybot; if (edge.r_ytop > tileArea.r_ytop) edge.r_ytop = tileArea.r_ytop; GEOTRANSRECT(trans, &edge, &rootArea); plotVersLine(&rootArea, 0, raster); } } return 0; } /* * ---------------------------------------------------------------------------- * * plotVersLabel -- * * This procedure is invoked for labels. It generates bits to * display the label in the current raster swath. * * Results: * Always returns 0 to keep the search from aborting. * * Side effects: * Modifies the raster. * * ---------------------------------------------------------------------------- */ int plotVersLabel(scx, label, tpath, raster) SearchContext *scx; /* Describes state of search when label * was found. */ Label *label; /* Label that was found. */ TerminalPath *tpath; /* Ignored. */ Raster *raster; /* Raster to write to */ { Rect rootArea, swathArea, labelSize; Point point; int pos; /* Translate the label's area and relative position to root * coordinates and then to swath coordinates. Figure out * the point relative to which the label is to be positioned. */ GeoTransRect(&scx->scx_trans, &label->lab_rect, &rootArea); plotTransToSwath(&rootArea, &swathArea); pos = GeoTransPos(&scx->scx_trans, label->lab_just); PlotTextSize(labelFont, label->lab_text, &labelSize); switch (pos) { case GEO_NORTH: case GEO_NORTHEAST: case GEO_NORTHWEST: point.p_y = swathArea.r_ytop + crossSize + 2 - labelSize.r_ybot; break; case GEO_CENTER: case GEO_WEST: case GEO_EAST: point.p_y = (swathArea.r_ytop + swathArea.r_ybot)/2; point.p_y -= (labelSize.r_ytop + labelSize.r_ybot)/2; break; case GEO_SOUTH: case GEO_SOUTHEAST: case GEO_SOUTHWEST: point.p_y = swathArea.r_ybot - crossSize - 2 - labelSize.r_ytop; break; } switch (pos) { case GEO_WEST: case GEO_NORTHWEST: case GEO_SOUTHWEST: point.p_x = swathArea.r_xbot - crossSize - 2 - labelSize.r_xtop; break; case GEO_CENTER: case GEO_NORTH: case GEO_SOUTH: point.p_x = (swathArea.r_xtop + swathArea.r_xbot)/2; point.p_x -= (labelSize.r_xtop + labelSize.r_xbot)/2; break; case GEO_EAST: case GEO_NORTHEAST: case GEO_SOUTHEAST: point.p_x = swathArea.r_xtop + crossSize + 2 - labelSize.r_xbot; break; } /* Output lines marking the label's area. Different things are * done depending on whether the label is a point, a line, or an * area. */ if ((rootArea.r_xbot == rootArea.r_xtop) && (rootArea.r_ybot == rootArea.r_ytop)) { Rect tmp; /* Point label. Output a cross. */ tmp = swathArea; tmp.r_ytop += crossSize; tmp.r_ybot -= crossSize; GEO_EXPAND(&tmp, 1, &tmp); GEOCLIP(&tmp, &swathClip); if ((tmp.r_xbot <= tmp.r_xtop) && (tmp.r_ybot <= tmp.r_ytop)) PlotFillRaster(raster, &tmp, PlotBlackStipple); tmp = swathArea; tmp.r_xtop += crossSize; tmp.r_xbot -= crossSize; GEO_EXPAND(&tmp, 1, &tmp); GEOCLIP(&tmp, &swathClip); if ((tmp.r_xbot <= tmp.r_xtop) && (tmp.r_ybot <= tmp.r_ytop)) PlotFillRaster(raster, &tmp, PlotBlackStipple); } else { /* Line or rectangle. Draw outline. */ plotVersRect(&rootArea, 1, raster); } /* Output the text for the label. Before outputting the label, * erase the area where the label will appear in order to make * the label more visible. */ labelSize.r_xbot += point.p_x - 1; labelSize.r_xtop += point.p_x + 1; labelSize.r_ybot += point.p_y - 1; labelSize.r_ytop += point.p_y + 1; GEOCLIP(&labelSize, &swathClip); PlotClearRaster(raster, &labelSize); PlotRasterText(raster, &swathClip, labelFont, label->lab_text, &point); return 0; } /* * ---------------------------------------------------------------------------- * * plotVersCell -- * * This procedure is invoked for unexpanded cells. * * Results: * Always returns 0 to keep the search from aborting. * * Side effects: * The raster is modified to depict the cell's boundary, * name, and instance id. * * ---------------------------------------------------------------------------- */ int plotVersCell(scx, raster) SearchContext *scx; /* Describes cell whose bbox is to * be plotted. */ Raster *raster; /* Raster to write to */ { char idName[100]; Rect rootArea, swathArea, textSize; Point point; CellDef *def; /* Convert the cell's bounding box to root coordinates and then * draw as a thick outline. */ def = scx->scx_use->cu_def; GeoTransRect(&scx->scx_trans, &def->cd_bbox, &rootArea); plotVersRect(&rootArea, 2, raster); if (!PlotShowCellNames) return (0); /* Output the cell's name and id text. */ if (cellNameFont != NULL) { plotTransToSwath(&rootArea, &swathArea); PlotTextSize(cellNameFont, def->cd_name, &textSize); point.p_x = (swathArea.r_xtop + swathArea.r_xbot)/2; point.p_x -= (textSize.r_xtop + textSize.r_xbot)/2; point.p_y = (2*swathArea.r_ytop + swathArea.r_ybot)/3; point.p_y -= (textSize.r_ytop + textSize.r_ybot)/2; PlotRasterText(raster, &swathClip, cellNameFont, def->cd_name, &point); } if (cellIdFont != NULL) { DBPrintUseId(scx, idName, 100, TRUE); PlotTextSize(cellIdFont, idName, &textSize); point.p_x = (swathArea.r_xtop + swathArea.r_xbot)/2; point.p_x -= (textSize.r_xtop + textSize.r_xbot)/2; point.p_y = (swathArea.r_ytop + 2*swathArea.r_ybot)/3; point.p_y -= (textSize.r_ytop + textSize.r_ybot)/2; PlotRasterText(raster, &swathClip, cellIdFont, idName, &point); } return 0; } /* * ---------------------------------------------------------------------------- * * PlotVersatec -- * * This procedure generates a raster file suitable for driving * printers like the Versatec black-and-white family, and runs * a spooling program to print the file. * * If PlotVersPlotType is VERSATEC_COLOR, it will generate a * versatec color plot file in straight color raster format. * * If PlotVersPlotType is HPGL2 or HPRTL, it will generate * an HPRTL file for the supported HP plotters. * * Results: * None. * * Side effects: * Lots of disk space is chewed up by the file. * * ---------------------------------------------------------------------------- */ void PlotVersatec(scx, layers, xMask, user_scale) SearchContext *scx; /* The use and area and transformation * in this describe what to plot. */ TileTypeBitMask *layers; /* Tells what layers to plot. Only * paint layers in this mask, and also * expanded according to xMask, are * plotted. If L_LABELS is set, then * labels on the layers are also * plotted, if expanded according to * xMask. If L_CELL is set, then * subcells that are unexpanded * according to xMask are plotted as * bounding boxes. */ int xMask; /* An expansion mask, used to indicate * the window whose expansion status * will be used to determine * visibility. Zero means treat * everything as expanded. */ int user_scale; /* Scalefactor of output */ { static char *yesNo[] = {"no", "yes", NULL}; int dotsAcross, dotsDown, swathsDown, scaleDown; int mag_width; /* lambda */ float width; /* inches */ char fileName[200], command[300], answer[32]; float length, mBytes; Transform tinv; int action, result; FILE *file; VersatecColor color; bool haveColorMessage; int usedScale, maxScale; float oscale; Raster *raster = NULL; /* CMYK color separated raster buffers. */ Raster *kRaster, *cRaster, *mRaster, *yRaster; haveColorMessage = FALSE; GeoTransRect(&scx->scx_trans, &scx->scx_area, &rootClip); GEO_EXPAND(&rootClip, 1, &rootClip); /* Get conversion factor (internal units to inches) */ oscale = CIFGetOutputScale(1000); /* convert to microns */ oscale *= 3.937e-5; /* convert to inches */ /* Compute plot width from scalefactor */ mag_width = rootClip.r_xtop - rootClip.r_xbot; maxScale = ((float)PlotVersWidth / (float)PlotVersDotsPerInch) / (oscale * (float)mag_width); width = (float)user_scale * oscale * (float)mag_width; dotsAcross = (int)(width * (float)PlotVersDotsPerInch); if (dotsAcross <= 0 || dotsAcross > PlotVersWidth) { dotsAcross = PlotVersWidth; usedScale = maxScale; } else usedScale = user_scale; /* Recompute width based on the actual scale used */ width = (float)usedScale * oscale * (float)mag_width; /* * Compute the number of pixels per magic unit. * This number will be the fraction: scale / (1 << scaleShift). * In order to be reasonably sure that we have enough precision * in the numerator of the fraction, require that scale have at * least three bits (i.e., be greater than or equal to 4). */ for (scale = 0, scaleShift = 4; ; scaleShift++) { scaleDown = 1 << scaleShift; scale = (scaleDown * dotsAcross) / mag_width; if (scaleShift >= 8 * sizeof (int)) { TxError("The area selected is too many lambda wide to plot.\n"); TxError("(There are numerical problems with rasterizing it).\n"); TxError("Try selecting a smaller area, or else asking for "); TxError("a wider plot.\n"); return; } if (scale >= 8) break; } /* * Compute scaling information, and tell the user how big the * plot will be. */ dotsDown = ((rootClip.r_ytop - rootClip.r_ybot)*scale) >> scaleShift; swathsDown = (dotsDown + PlotVersSwathHeight - 1)/PlotVersSwathHeight; dotsDown = swathsDown * PlotVersSwathHeight; mBytes = ((PlotVersWidth/8)*dotsDown)/1000000.0; length = dotsDown; length /= PlotVersDotsPerInch; TxPrintf("Plot will be %.1f inches wide by %.1f inches long.\n", width, length); TxPrintf("It will take %.2f Megabytes in \"%s\".\n", (PlotVersPlotType == HPRTL || PlotVersPlotType == HPGL2) ? 4.0 * mBytes : mBytes, PlotTempDirectory); TxPrintf("Lambda: %.3f (um) Requested scale: %dX Actual scale: %dX " "[Full scale: %dX].\n", CIFGetOutputScale(1000), user_scale, usedScale, maxScale); do { TxPrintf("Do you still want the plot? [yes] "); if (TxGetLine(answer, sizeof answer) == NULL || answer[0] == '\0') { action = 1; break; } } while ((action = Lookup(answer, yesNo)) < 0); if (action == 0) return; /* The plot has been "approved". Now obtain a swath raster if * we don't already have one. If the swath size has changed, * recycle the raster for a new one. */ if ((raster != NULL) && ((raster->ras_width != PlotVersWidth) || (raster->ras_height != PlotVersSwathHeight))) { if (PlotVersPlotType == HPGL2 || PlotVersPlotType == HPRTL) { PlotFreeRaster(cRaster); PlotFreeRaster(mRaster); PlotFreeRaster(yRaster); } PlotFreeRaster(kRaster); raster = NULL; } if (raster == NULL) { if (PlotVersPlotType == HPGL2 || PlotVersPlotType == HPRTL) { cRaster = PlotNewRaster(PlotVersSwathHeight, PlotVersWidth); mRaster = PlotNewRaster(PlotVersSwathHeight, PlotVersWidth); yRaster = PlotNewRaster(PlotVersSwathHeight, PlotVersWidth); } kRaster = PlotNewRaster(PlotVersSwathHeight, PlotVersWidth); raster = kRaster; } /* Load font information for the plot, if it isn't already * loaded. */ labelFont = PlotLoadFont(PlotVersLabelFont); cellNameFont = PlotLoadFont(PlotVersNameFont); cellIdFont = PlotLoadFont(PlotVersIdFont); /* Compute the name of the file to use for output, and open it. */ sprintf(fileName, "%s/magicPlotXXXXXX", PlotTempDirectory); result = mkstemp(fileName); if (result == -1) { TxError("Failed to create temporary filename for %s\n", fileName); return; } file = PaOpen(fileName, "w", (char *) NULL, (char *) NULL, (char *) NULL, (char **) NULL); if (file == NULL) { TxError("Couldn't open file \"%s\" to write plot.\n", fileName); return; } /* Set up the rest of the transformation variables. * Arrange for the plot to be centered on the page. */ plotLL.p_y = rootClip.r_ybot; plotLL.p_x = (rootClip.r_xtop+rootClip.r_xbot)/2 - (PlotVersWidth*8)/scale; if (plotLL.p_x > rootClip.r_xbot) plotLL.p_x = rootClip.r_xbot; /* Compute a distance equal to 1/8th the size of a typical wire * (max of thicknesses of routing layers). This is used to offset * text from labels and to compute cross size for point labels. */ if (RtrMetalWidth > RtrPolyWidth) crossSize = (RtrMetalWidth*scale)/(scaleDown*8); else crossSize = (RtrPolyWidth*scale)/(scaleDown*8); if (crossSize < 2) crossSize = 2; /* Step down the page one swath at a time, rasterizing everything * that overlaps the current swath, then outputting the swath. */ GeoInvertTrans(&scx->scx_trans, &tinv); for (color = BLACK; color <= YELLOW; color++) { int swathsDownThisColor; swathsDownThisColor = swathsDown; rasFileByteCount = 0; /* issue preamble for this color's raster. if we are doing colors */ switch (PlotVersPlotType) { case HPRTL: PlotHPRTLHeader(PlotVersWidth, dotsDown, PlotVersDotsPerInch, file); break; case HPGL2: PlotHPGL2Header(PlotVersWidth, dotsDown, PlotVersDotsPerInch, usedScale, file); break; case VERSATEC_COLOR: if (PlotDumpColorPreamble(color, file, dotsDown, PlotVersWidth) != 0) goto error; if (SigInterruptPending) goto error; TxPrintf("\nDumping %s Raster:", plotVersatecColorNames[color]); TxFlush(); break; } for (swathsDownThisColor -= 1; swathsDownThisColor >= 0; swathsDownThisColor -= 1) { SearchContext scx2; Rect root, labelArea; int labelHeight; swathY = swathsDownThisColor * PlotVersSwathHeight; if (PlotVersPlotType == HPGL2 || PlotVersPlotType == HPRTL) { PlotClearRaster(cRaster, (Rect *) NULL); PlotClearRaster(mRaster, (Rect *) NULL); PlotClearRaster(yRaster, (Rect *) NULL); } PlotClearRaster(kRaster, (Rect *) NULL); /* Compute the area of the swath that overlaps the portion of * the layout we're plotting. */ plotTransToSwath(&rootClip, &swathClip); if (swathClip.r_xbot < 0) swathClip.r_xbot = 0; if (swathClip.r_ybot < 0) swathClip.r_ybot = 0; if (swathClip.r_xtop >= PlotVersWidth) swathClip.r_xtop = PlotVersWidth - 1; if (swathClip.r_ytop >= PlotVersSwathHeight) swathClip.r_ytop = PlotVersSwathHeight - 1; /* Compute the area of layout that overlaps this swath. This is * done twice, once for mask material and once for labels. The * separate computation for labels is because labels stick out * from their positioning points. We may have to search a larger * area than just the swath in order to find all the labels that * must be drawn in this swath. Only the y-direction needs to * be expanded this way, since we're only swathing in y. Even * non-label stuff has to be expanded slightly, because lines * are drawn more than 1 pixel thick. */ scx2 = *scx; root.r_xbot = (scaleDown*swathClip.r_xbot)/scale + plotLL.p_x; root.r_xtop = (scaleDown*swathClip.r_xtop)/scale + plotLL.p_x; root.r_ybot = (scaleDown*(swathY-4))/scale + plotLL.p_y; root.r_ytop = (scaleDown*(swathY+swathClip.r_ytop+4))/scale+plotLL.p_y; GEO_EXPAND(&root, 1, &root); GeoTransRect(&tinv, &root, &scx2.scx_area); labelArea.r_xbot = root.r_xbot; labelArea.r_xtop = root.r_xtop; if (labelFont != NULL) { labelHeight = (labelFont->fo_bbox.r_ytop - labelFont->fo_bbox.r_ybot) + 2; labelArea.r_ybot = (scaleDown * (swathY - crossSize - labelHeight)) / scale + plotLL.p_y; labelArea.r_ytop = (scaleDown * (swathY + swathClip.r_ytop + crossSize + labelHeight)) / scale + plotLL.p_y; GEO_EXPAND(&labelArea, 1, &labelArea); } /* For each Versatec style, output stippled areas for all * the tiles requested by the style. */ switch (PlotVersPlotType) { case VERSATEC_BW: curStyle = plotVersStyles; break; case HPGL2: case HPRTL: curStyle = plotColorVersStyles; if (curStyle == NULL) { TxError("Warning: No color versatec styles are defined" " in the technology file!\nPlotting aborted.\n"); return; } break; default: curStyle = plotColorVersStyles; if (!haveColorMessage) { TxError("Warning: No color versatec styles are defined" " in the technology file!\nPlot will be" " monochrome.\n"); haveColorMessage = TRUE; curStyle = plotVersStyles; } } if (curStyle == NULL) { TxError("Warning: No monochrome versatec styles are" " defined in the technology file!\nPlotting" " aborted.\n"); return; } for ( ; curStyle != NULL; curStyle = curStyle->vs_next) { /* if we are plotting in B&W, then visit all the tiles in this * swath, otherwise only visit them if they should be * plotted in the current style's color. */ if (PlotVersPlotType == HPGL2 || PlotVersPlotType == HPRTL) { switch (curStyle->vs_color) { case CYAN: raster = cRaster; break; case MAGENTA: raster = mRaster; break; case YELLOW: raster = yRaster; break; default: raster = kRaster; break; } } if ((PlotVersPlotType != VERSATEC_COLOR) || (curStyle->vs_color == color)) { TTMaskAndMask3(&curMask, layers, &curStyle->vs_layers); (void) DBTreeSrTiles(&scx2, &curMask, xMask, plotVersTile, (ClientData) raster); } } raster = kRaster; /* Output labels, if they are wanted. */ if (TTMaskHasType(layers, L_LABEL) && (color == BLACK) && (labelFont != NULL)) { curMask = *layers; TTMaskSetType(&curMask, TT_SPACE); GeoTransRect(&tinv, &labelArea, &scx2.scx_area); (void) DBTreeSrLabels(&scx2, &curMask, xMask, (TerminalPath *) NULL, TF_LABEL_ATTACH, plotVersLabel, (ClientData) raster); } /* Output subcell bounding boxes, if they are wanted. */ if (TTMaskHasType(layers, L_CELL) && color == BLACK) { (void) DBTreeSrCells(&scx2, xMask, plotVersCell, (ClientData) raster); } TxPrintf("#"); TxFlush(); switch (PlotVersPlotType) { case HPGL2: case HPRTL: PlotDumpHPRTL(file, kRaster, cRaster, mRaster, yRaster); break; case VERSATEC_COLOR: case VERSATEC_BW: if (PlotDumpRaster(raster, file) != 0) goto error; if (SigInterruptPending) goto error; break; } } /* Only the VERSATEC_COLOR type runs colors separately */ if (PlotVersPlotType != VERSATEC_COLOR) break; TxPrintf ("\nWrote %d bytes of data.\n", rasFileByteCount); } /* Write trailers */ switch (PlotVersPlotType) { case HPGL2: PlotHPGL2Trailer(file); break; case HPRTL: PlotHPRTLTrailer(file); break; } /* Close the file and issue the command to plot it. */ TxPrintf("\n"); fclose(file); sprintf(command, PlotVersCommand, PlotVersPrinter, fileName); if (system(command) != 0) { TxError("Couldn't execute spooler command to print \"%s\"\n", fileName); } return; error: TxError("\nVersatec plot aborted.\n"); fclose(file); unlink(fileName); } #endif /* VERSATEC */ magic-8.0.210/plot/plotPNM.c0000644000175000001440000010524311410650605014130 0ustar timusers/* * plotPNM.c -- * * This file contains procedures that generate PNM format files * to describe a section of layout. * * ********************************************************************* * * Copyright (C) 2000 Cornell University * * * 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. Cornell University * * * 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. * * ********************************************************************* * * R. Timothy Edwards * Copyright (C) 2004 * MultiGiG, Inc. * Scotts Valley, CA * * Cleaned up the code, including optimization for speed * Added: Non-Manhattan geometry handling, 24-bit color, * plot styles automatically generated from display styles, * downsampling for large plots, extended syntax for the * technology file description. */ #ifndef lint static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/plot/plotPNM.c,v 1.3 2010/06/24 12:37:25 tim Exp $"; #endif /* not lint */ #include #include #include #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 "utils/tech.h" #include "utils/malloc.h" #include "utils/utils.h" #include "utils/styles.h" #include "windows/windows.h" #include "graphics/graphics.h" #include "dbwind/dbwtech.h" #include "dbwind/dbwind.h" #include "utils/main.h" #include "commands/commands.h" #include "textio/textio.h" #include "utils/signals.h" #include "plot/plotInt.h" #define LANCZOS_KERNEL_SIZE 1024 #define PI 3.14159265 /* Structure for saving R, G, B components of colors */ /* from a non-default colormap. */ typedef struct _pnmcolor { unsigned char r, g, b; } pnmcolor; pnmcolor *PNMcolors = NULL; static int ncolors = 0; #define PIXELSZ sizeof(pnmcolor) int PlotPNMmaxmem = 64 * 1024; /* 64MB */ int PlotPNMdownsample = 0; /* No downsampling by default */ unsigned char PlotPNMBG = 0xff; /* White background by default */ #ifdef VERSATEC bool PlotPNMRTL = FALSE; /* If true, filter output through HP driver */ #endif /* * Local variables, modified/shared by callbacks. */ int Init_Error; float lk[2 * LANCZOS_KERNEL_SIZE + 1]; int *lkstep; /* lanczos kernel steps */ pnmcolor *rtile; int tile_xsize, tile_ysize; int ds_xsize, ds_ysize; Rect bb; unsigned long BBinit; int tile_yshift, tile_xshift; int im_x, im_y; int im_yoffset; int y_pixels; /* Structure for saving styles that are different from */ /* the styles loaded for this technology. */ typedef struct _dstyle { char *name; int init; unsigned int wmask; pnmcolor color; } dstyle; dstyle *Dstyles = NULL; static int ndstyles = 0; /* Structure which records how to paint a tile type. */ typedef struct _pstyle { unsigned int wmask; pnmcolor color; } pstyle; pstyle *PaintStyles = NULL; /* Forward declarations */ extern void PlotLoadStyles(); extern void PlotLoadColormap(); extern pnmcolor PNMColorBlend(); extern pnmcolor PNMColorIndexAndBlend(); /* * ---------------------------------------------------------------------------- * * Function for output of PNM line data to HPRTL format * * ---------------------------------------------------------------------------- */ #ifdef VERSATEC struct plotRTLdata { FILE *outfile; unsigned char *outbytes; }; int pnmRTLLineFunc(linebuffer, arg) unsigned char *linebuffer; struct plotRTLdata *arg; { int size; size = PlotRTLCompress(linebuffer, arg->outbytes, im_x * 3); fprintf(arg->outfile, "\033*b%dW", size); fwrite(arg->outbytes, size, 1, arg->outfile); return 0; } #endif /* * ---------------------------------------------------------------------------- * * Function for output of PNM line data to file fp * * ---------------------------------------------------------------------------- */ int pnmLineFunc(linebuffer, fp) unsigned char *linebuffer; FILE *fp; { fwrite(linebuffer, im_x * 3, 1, fp); return 0; } /* * ---------------------------------------------------------------------------- * * pnmRenderRegion -- * * Antialiased rendering. * * Results: * None. * * Side effects: * Writes output to file. * * ---------------------------------------------------------------------------- */ void pnmRenderRegion(scale, scale_over_2, normal, temp, func, arg) float scale; int scale_over_2; float normal; /* normalizing factor */ float *temp; /* passed so we don't have to allocate it * on every call. */ int (*func)(); /* Function to call per line of output */ ClientData arg; /* Arguments to function */ { int i, j; int jmax; int x, y; int dx, dy; int ds_over_2; pnmcolor *color; float r, g, b; unsigned char *linebuffer, *lineptr; jmax = MIN(y_pixels, im_yoffset + 1); ds_over_2 = scale_over_2 >> PlotPNMdownsample; linebuffer = mallocMagic(im_x * 3); /* x, y : pixel coords */ if (ds_over_2 == 0) { for (j = 0; j < jmax; j++) { lineptr = linebuffer; y = scale * (y_pixels - 1 - j); y >>= PlotPNMdownsample; for (i = 0; i < im_x; i++) { x = scale * i; x >>= PlotPNMdownsample; color = rtile + x + y * ds_xsize; *lineptr++ = color->r; *lineptr++ = color->g; *lineptr++ = color->b; } (*func)(linebuffer, arg); } } else { /* When the scale is small enough, we have to resort to antialiasing */ float lkval; int tidx; for (j = 0; j < jmax; j++) { y = scale_over_2 + scale * (y_pixels - 1 - j); y >>= PlotPNMdownsample; lineptr = linebuffer; for (i = 0; i < im_x; i++) { x = scale_over_2 + scale * i; x >>= PlotPNMdownsample; for (dx = -ds_over_2; dx < ds_over_2; dx++) { r = 0.0; g = 0.0; b = 0.0; for (dy = -ds_over_2; dy < ds_over_2; dy++) { if (dy + y >= ds_ysize) continue; /* grab rgb for (x + dx, y + dy) */ color = rtile + (x + dx) + (y + dy) * ds_xsize; lkval = lk[lkstep[dy + ds_over_2]]; r += (float)color->r * lkval; g += (float)color->g * lkval; b += (float)color->b * lkval; } tidx = 3 * (dx + ds_over_2); temp[tidx++] = r; temp[tidx++] = g; temp[tidx] = b; } r = 0.0; g = 0.0; b = 0.0; for (dx = 0; dx < 2 * ds_over_2; dx++) { tidx = 3 * dx; lkval = lk[lkstep[dx]]; r += temp[tidx++] * lkval; g += temp[tidx++] * lkval; b += temp[tidx] * lkval; } r /= normal; g /= normal; b /= normal; *lineptr++ = (unsigned char)r; *lineptr++ = (unsigned char)g; *lineptr++ = (unsigned char)b; } (*func)(linebuffer, arg); } } freeMagic(linebuffer); } /* * ---------------------------------------------------------------------------- * * pnmBBOX -- * * Callback for DBTreeSrTiles; compute bounding box of plot * * Results: * Always return 0 to keep search going. * * Side effects: * Modifies BBinit, updates bounding box "bb" * * ---------------------------------------------------------------------------- */ int pnmBBOX (tile,cxp) Tile *tile; TreeContext *cxp; { Rect targetRect, sourceRect; SearchContext *scx = cxp->tc_scx; Rect *arg; TileType type; if (!IsSplit(tile)) if ((type = TiGetType(tile)) == TT_SPACE) return 0; /* grab rectangle from tile */ TITORECT(tile, &targetRect); /* coordinate transform */ GEOTRANSRECT(&scx->scx_trans, &targetRect, &sourceRect); /* Clip */ arg = (Rect *)cxp->tc_filter->tf_arg; GEOCLIP(&sourceRect, arg); /* compute bbox */ if (!BBinit) bb = sourceRect; else { bb.r_xbot = MIN(bb.r_xbot, sourceRect.r_xbot); bb.r_ybot = MIN(bb.r_ybot, sourceRect.r_ybot); bb.r_xtop = MAX(bb.r_xtop, sourceRect.r_xtop); bb.r_ytop = MAX(bb.r_ytop, sourceRect.r_ytop); } BBinit = 1; return 0; } /* * ---------------------------------------------------------------------------- * * pnmTile -- * * Callback for DBTreeSrTiles; paints tiles in the current rtile buffer. * * Results: * Return 0 to keep search going unless an error condition was * encountered. * * Side effects: * Modifies rtile array. * * ---------------------------------------------------------------------------- */ int pnmTile (tile, cxp) Tile *tile; TreeContext *cxp; { SearchContext *scx = cxp->tc_scx; Rect targetRect, sourceRect, *clipRect; int type, j, x, y, dx, dy; pnmcolor *t; pnmcolor col; if ((type = (int)TiGetTypeExact(tile)) == TT_SPACE) return 0; /* undefined type; paint nothing */ if (!IsSplit(tile)) if (PaintStyles[type].wmask == 0) return 0; /* grab rectangle from tile */ TITORECT(tile, &targetRect); /* coordinate transform */ GEOTRANSRECT(&scx->scx_trans, &targetRect, &sourceRect); /* Clip */ clipRect = (Rect *)cxp->tc_filter->tf_arg; /* Handle non-Manhattan geometry */ if (IsSplit(tile)) { TileType dinfo; int w, h, llx, lly, urx, ury; Rect scaledClip; type = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile); if (type == TT_SPACE) return 0; else if (PaintStyles[type].wmask == 0) return 0; llx = sourceRect.r_xbot - tile_xshift; lly = sourceRect.r_ybot - tile_yshift; llx >>= PlotPNMdownsample; lly >>= PlotPNMdownsample; dx = sourceRect.r_xtop - sourceRect.r_xbot; dy = sourceRect.r_ytop - sourceRect.r_ybot; dx >>= PlotPNMdownsample; dy >>= PlotPNMdownsample; urx = llx + dx; ury = lly + dy; col = PaintStyles[type].color; scaledClip = *clipRect; scaledClip.r_xbot -= tile_xshift; scaledClip.r_xtop -= tile_xshift; scaledClip.r_ybot -= tile_yshift; scaledClip.r_ytop -= tile_yshift; scaledClip.r_xbot >>= PlotPNMdownsample; scaledClip.r_xtop >>= PlotPNMdownsample; scaledClip.r_ybot >>= PlotPNMdownsample; scaledClip.r_ytop >>= PlotPNMdownsample; /* The following structures could be much better */ /* written for considerable speedup. . . */ dinfo = DBTransformDiagonal(TiGetTypeExact(tile), &scx->scx_trans); if (((dinfo & TT_SIDE) >> 1) != (dinfo & TT_DIRECTION)) { /* work top to bottom */ for (y = ury - 1; y >= lly; y--) { if (y >= scaledClip.r_ytop) continue; else if (y < scaledClip.r_ybot) break; if (dinfo & TT_SIDE) /* work right to left */ { for (x = urx - 1; x >= llx; x--) { if (x >= scaledClip.r_xtop) continue; else if (x < scaledClip.r_xbot) break; if (((urx - x) * dy) > ((ury - y) * dx)) break; t = rtile + x + ds_xsize * y; *t = PNMColorBlend(t, &col); } } else /* work left to right */ { for (x = llx; x < urx; x++) { if (x < scaledClip.r_xbot) continue; else if (x >= scaledClip.r_xtop) break; if (((x - llx) * dy) > ((ury - y) * dx)) break; t = rtile + x + ds_xsize * y; *t = PNMColorBlend(t, &col); } } } } else /* work bottom to top */ { for (y = lly; y < ury; y++) { if (y < scaledClip.r_ybot) continue; else if (y >= scaledClip.r_ytop) break; if (dinfo & TT_SIDE) /* work right to left */ { for (x = urx; x >= llx; x--) { if (x >= scaledClip.r_xtop) continue; else if (x < scaledClip.r_xbot) break; if (((urx - x) * dy) > ((y - lly) * dx)) break; t = rtile + x + ds_xsize * y; *t = PNMColorBlend(t, &col); } } else /* work left to right */ { for (x = llx; x < urx; x++) { if (x < scaledClip.r_xbot) continue; else if (x >= scaledClip.r_xtop) break; if (((x - llx) * dy) > ((y - lly) * dx)) break; t = rtile + x + ds_xsize * y; *t = PNMColorBlend(t, &col); } } } } return 0; } GEOCLIP(&sourceRect, clipRect); /* paint rectangle */ x = sourceRect.r_xbot - tile_xshift; y = sourceRect.r_ybot - tile_yshift; /* stop the search on an error condition */ /* (this should not happen---is guaranteed by GEOCLIP */ if ((x < 0) || (y < 0) || (x >= tile_xsize) || (y >= tile_ysize)) return 1; x >>= PlotPNMdownsample; y >>= PlotPNMdownsample; dx = sourceRect.r_xtop - sourceRect.r_xbot; dy = sourceRect.r_ytop - sourceRect.r_ybot; dx >>= PlotPNMdownsample; dy >>= PlotPNMdownsample; col = PaintStyles[type].color; t = rtile + x + ds_xsize * y; for (dy; dy > 0; dy--) { for (j = 0; j < dx; j++) { *t = PNMColorBlend(t, &col); t++; } t = t - dx + ds_xsize; } /* Continue search function */ return 0; } /* * ---------------------------------------------------------------------------- * * PlotPNM -- * * This procedure generates a PNM file to describe an area of * a layout. * * Results: * None. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ void PlotPNM(fileName, scx, layers, xMask, width) char *fileName; /* Name of PNM file to write. */ SearchContext *scx; /* The use and area and transformation * in this describe what to plot. */ TileTypeBitMask *layers; /* Tells what layers to plot. Only * paint layers in this mask, and also * expanded according to xMask, are * plotted. If L_LABELS is set, then * labels on the layers are also * plotted, if expanded according to * xMask. If L_CELL is set, then * subcells that are unexpanded * according to xMask are plotted as * bounding boxes. */ int xMask; /* An expansion mask, used to indicate * the window whose expansion status * will be used to determine * visibility. Zero means treat * everything as expanded. */ int width; /* Indicates the width of the * plot, in pixels. */ { FILE *fp; Rect bbox; int bb_ysize, bb_xsize; int i, x, y, tile_ydelta; int save_ds, iter; int scale_over_2, ds_over_2; float *strip; float scale, invscale, scaledown, normal; #ifdef VERSATEC struct plotRTLdata rtl_args; char command[200], tempFile[200]; #endif if (width <= 0) { TxError ("PNM module given negative pixel width; cannot plot\n"); return; } if (Init_Error) { TxError ("PNM module initialization had failed; cannot plot\n"); return; } /* image: * ----- * | xxx | * | xxx | * | xxx | * ----- * * Use -scale/2 to scale/2 magic coordinates for each output pixel. * */ /* Rendering Tile: * * 0.. bbox size + 2 * scale_over_2. * * To sample, pixel (i,j) will be at: * (scale_over_2 + scale*i, scale_over_2 + scale*j) * * Given an initial pixel position at (i,j), we sample from * -scale_over_2 to scale_over_2 */ /* Compute bounding box size in lambda */ BBinit = 0; DBTreeSrTiles(scx, layers, xMask, pnmBBOX, (ClientData)&scx->scx_area); /* Initial bounding box size */ bb_ysize = bb.r_ytop - bb.r_ybot; bb_xsize = bb.r_xtop - bb.r_xbot; /* Determine value of "scale" from the total pixel width. */ scale = (float)bb_xsize / (float)width; invscale = 1.0 / scale; scale = 1.0 / invscale; if ((scale > 2) || (invscale != ceil(invscale))) scale_over_2 = (int) ceil(scale / 2.0); else scale_over_2 = 0; /* bump search context by scale_over_2 pixels on each side */ scx->scx_area.r_xbot = bb.r_xbot - scale_over_2; scx->scx_area.r_ybot = bb.r_ybot - scale_over_2; scx->scx_area.r_xtop = bb.r_xtop + scale_over_2; scx->scx_area.r_ytop = bb.r_ytop + scale_over_2; /* Recalculate bounding box with extended boundary */ bb_ysize = bb.r_ytop - bb.r_ybot; bb_xsize = bb.r_xtop - bb.r_xbot; tile_xsize = bb_xsize + 2 * scale_over_2; /* check for empty region */ if (BBinit == 0 || tile_xsize <= 0 || bb_ysize <= 0) { TxPrintf ("Empty region, no plot\n"); return; } /* * Compute memory requirements; a single pixel line needs a tile * that has size "xsize" by "scale." To keep inter-tile overlap low, * we insist that a single tile must have at least 3*scale pixels in * it. */ save_ds = PlotPNMdownsample; while ((PlotPNMmaxmem * 1024) < ((3 * scale + 2 * scale_over_2) * PIXELSZ * tile_xsize) / (1 << (PlotPNMdownsample * 2))) PlotPNMdownsample++; if (PlotPNMdownsample != save_ds) { TxPrintf ("%dX downsampling forced by memory size requirements.\n", PlotPNMdownsample); TxPrintf ("Current: %d KB; Required for non-downsampled image: %d KB\n", PlotPNMmaxmem, (int) (1023 + ((3 * scale + 2 * scale_over_2) * PIXELSZ * tile_xsize) / 1024) / (1 << (save_ds * 2))); TxPrintf ("Use \"plot parameter pnmmaxmem\" to increase allocation.\n"); } /* * Compute the maximum y size for a tile. */ tile_ysize = PlotPNMmaxmem * 1024 / (PIXELSZ * tile_xsize); tile_ydelta = (tile_ysize - scale_over_2 * 2); /* Determine the amount shifted in Y for each consecutively */ /* computed region. */ /* tile_ydelta is the amount of shift in magic units. */ /* y_pixels is the amount of shift in PNM pixels. */ /* tile_ydelta MUST EQUAL y_pixels * scale. If not, then */ /* we need to back-compute a better tile_ysize value. */ y_pixels = tile_ydelta / scale; if (y_pixels == 0) y_pixels = 1; if (y_pixels * scale != tile_ydelta) { tile_ydelta = scale * y_pixels; tile_ysize = tile_ydelta + (scale_over_2 * 2); } /* If there's enough memory allocation, tile_ysize bounds the whole plot */ if (tile_ysize > (bb_ysize + 2 * scale_over_2)) { tile_ysize = bb_ysize + 2 * scale_over_2; tile_ydelta = bb_ysize; y_pixels = tile_ydelta / scale; } ds_xsize = tile_xsize >> PlotPNMdownsample; ds_ysize = tile_ysize >> PlotPNMdownsample; ds_over_2 = scale_over_2 >> PlotPNMdownsample; rtile = (pnmcolor *) mallocMagic((ds_xsize * ds_ysize) * PIXELSZ); /* bump search context by scale_over_2 pixels on each side */ scx->scx_area.r_ybot = scx->scx_area.r_ytop - tile_ysize; tile_yshift = scx->scx_area.r_ybot; tile_xshift = scx->scx_area.r_xbot; im_x = (int)(bb_xsize / scale); im_y = (int)(bb_ysize / scale); #ifdef VERSATEC if (PlotPNMRTL) { if (fileName == NULL) { int result; sprintf(tempFile, "%s/magicPlotXXXXXX", PlotTempDirectory); result = mkstemp(tempFile); if (result == -1) { TxError("Failed to create temporary filename for %s\n", tempFile); return; } fileName = tempFile; } rtl_args.outfile = PaOpen(fileName, "w", (char *)NULL, ".", (char *)NULL, (char **)NULL); if (rtl_args.outfile == NULL) { TxError("Couldn't open file \"%s\" to write plot.\n", fileName); return; } switch (PlotVersPlotType) { case HPGL2: /* Write HPGL2 header */ /* Universal Command Language. */ fprintf(rtl_args.outfile, "\033%%-12345X"); /* Reset printer; set HPGL2 mode. */ fprintf(rtl_args.outfile, "@PJL ENTER LANGUAGE=HPGL2\r\n"); fprintf(rtl_args.outfile, "\033E\033%%0B"); /* Declare name; disable auto-rotate */ fprintf(rtl_args.outfile, "BP1,\"MAGIC\",5,1;"); /* Enter RTL mode. */ fprintf(rtl_args.outfile, "\033%%0A"); /* Source mode opaque */ fprintf(rtl_args.outfile, "\033*v1N"); /* Drop through */ case HPRTL: /* Write HPRTL header */ /* Direct pixel mode, 8 bits/component */ fwrite("\033*v6W\000\003\010\010\010\010", 11, 1, rtl_args.outfile); /* Image width in pixels. */ fprintf(rtl_args.outfile, "\033*r%dS", im_x); /* Image height in pixels.*/ fprintf(rtl_args.outfile, "\033*r%dT", im_y); /* No negative motion. */ fprintf(rtl_args.outfile, "\033&a1N"); /* Mode 2 row compression */ /* But, we REALLY ought to have delta row compression here. . . */ fprintf(rtl_args.outfile, "\033*b2M"); /* Printer resolution in DPI */ fprintf(rtl_args.outfile, "\033*t%dR", PlotVersDotsPerInch); /* Start raster data */ fprintf(rtl_args.outfile, "\033*r%cA", (PlotVersPlotType == HPGL2) ? '1' : '0'); break; } /* Reserve enough space for run-length encoding compression */ rtl_args.outbytes = mallocMagic((im_x * 3) + ((im_x * 3) / 127) + 1); } else #endif { /* open PNM file */ fp = PaOpen (fileName, "w", ".pnm", ".", NULL, NULL); if (fp == NULL) { TxError ("Could not open file `%s' for writing\n", fileName); goto done; } fprintf (fp, "P6\n"); fprintf (fp, "%d %d\n", im_x, im_y); fprintf (fp, "255\n"); } im_yoffset = im_y - 1; TxPrintf ("PNM image dimensions: %d x %d\n", im_x, im_y); #if 0 TxPrintf ("Region size: %d x %d\n", tile_xsize, tile_ysize); TxPrintf ("Pixels per region: %d\n", y_pixels); TxPrintf ("Scale: %g\n", scale); TxPrintf ("Antialiasing overlap: %d\n", scale_over_2); if (PlotPNMdownsample > 0) { TxPrintf ("Downsampling: %d\n", PlotPNMdownsample); TxPrintf ("Downsampled region size: %d x %d\n", ds_xsize, ds_ysize); } #endif strip = (float *) mallocMagic((unsigned) (ds_over_2 * 2 * 3 * sizeof(float))); lkstep = (int *) mallocMagic((unsigned) (ds_over_2 * 2 * sizeof(int))); scaledown = scale / (2 * (1 << PlotPNMdownsample)); for (x = -ds_over_2; x < ds_over_2; x++) { lkstep[ds_over_2 + x] = ((float)ABS(x)) / scaledown * LANCZOS_KERNEL_SIZE; if (lkstep[ds_over_2 + x] >= LANCZOS_KERNEL_SIZE) lkstep[ds_over_2 + x] = LANCZOS_KERNEL_SIZE - 1; } /* Compute the normalization factor (what to divide by after adding up the */ /* weighted values of all pixels in the kernel area). */ normal = 0.0; for (x = 0; x < 2 * ds_over_2; x++) for (y = 0; y < 2 * ds_over_2; y++) normal += lk[lkstep[x]] * lk[lkstep[y]]; iter = 0; while (im_yoffset >= 0) { /* If this is a slow rendering, then we'll announce */ /* the progress every 20 steps. */ if ((++iter) % 10 == 0) { TxPrintf("%g%% done\n", 100 * (float)(im_y - im_yoffset + 1) / (float)im_y); TxFlushOut(); } /* Clear tile memory with the background gray level */ memset((void *)rtile, PlotPNMBG, (size_t)(ds_xsize * ds_ysize * PIXELSZ)); if (SigInterruptPending) { TxPrintf (" *** interrupted ***\n"); goto done; } /* Use the "UniqueTiles" function to avoid painting contacts twice */ DBTreeSrUniqueTiles(scx, layers, xMask, pnmTile, (ClientData)&scx->scx_area); /* anti-aliased rendering */ #ifdef VERSATEC if (PlotPNMRTL) pnmRenderRegion(scale, scale_over_2, normal, strip, pnmRTLLineFunc, (ClientData)(&rtl_args)); else #endif pnmRenderRegion(scale, scale_over_2, normal, strip, pnmLineFunc, (ClientData)fp); /* advance to the next strip */ im_yoffset -= y_pixels; /* in output coords */ tile_yshift -= tile_ydelta; /* in magic coords */ scx->scx_area.r_ybot -= tile_ydelta; scx->scx_area.r_ytop -= tile_ydelta; } /* TxPrintf ("Save to file `%s', scale = %f\n", fileName, scale);*/ #ifdef VERSATEC if (PlotPNMRTL) { switch (PlotVersPlotType) { case HPRTL: PlotHPRTLTrailer(rtl_args.outfile); break; case HPGL2: PlotHPGL2Trailer(rtl_args.outfile); break; } fflush(rtl_args.outfile); fclose(rtl_args.outfile); freeMagic(rtl_args.outbytes); /* Run spooler */ sprintf(command, PlotVersCommand, PlotVersPrinter, fileName); if (system(command) != 0) { TxError("Couldn't execute spooler command to print \"%s\"\n", fileName); } } else #endif fclose (fp); done: PlotPNMdownsample = save_ds; freeMagic(rtile); freeMagic(strip); freeMagic(lkstep); return; } /* * ---------------------------------------------------------------------------- * * lanczos_kernel -- * * Compute the value of the lanczos kernel at the given position. * * * Results: * Returns kernel value at arg x. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ float lanczos_kernel(i, n) int i, n; { double x; /* position at which to evaluate the lanczos kernel */ if (i == 0) return (float)1.0; else x = (double)i / (double)n; return (float)(sin(PI * x) / (PI * x)) * (sin(PI * 0.5 * x) / (PI * 0.5 * x)); } /* * ---------------------------------------------------------------------------- * Color blending functions. * * PNMColorBlend blends two colors denoted by R, G, B components (0-255). * "c_have" is the color that is already present, and "c_put" is the * color being overlaid. * * PNMColorIndexAndBlend blends an R, G, B component color with a color * indexed into a colormap table. * * Both functions return an R, G, B component color. * ---------------------------------------------------------------------------- */ pnmcolor PNMColorBlend(c_have, c_put) pnmcolor *c_have, *c_put; { pnmcolor loccolor; short r, g, b; /* "127" is half the background color (which should be derived) */ r = (short)c_put->r - 127 + (short)c_have->r / 2; g = (short)c_put->g - 127 + (short)c_have->g / 2; b = (short)c_put->b - 127 + (short)c_have->b / 2; loccolor.r = (r < 0) ? 0 : (unsigned char)r; loccolor.g = (g < 0) ? 0 : (unsigned char)g; loccolor.b = (b < 0) ? 0 : (unsigned char)b; return loccolor; } pnmcolor PNMColorIndexAndBlend(c_have, cidx) pnmcolor *c_have; int cidx; { pnmcolor loccolor, *c_put; int ir, ig, ib; short r, g, b; if ((ncolors > 0) && (cidx < ncolors)) { c_put = &PNMcolors[cidx]; r = (short)c_put->r; g = (short)c_put->g; b = (short)c_put->b; } else { GrGetColor(cidx, &ir, &ig, &ib); r = (short)ir; g = (short)ig; b = (short)ib; } /* "127" is half the background color (which should be derived) */ r += (short)c_have->r / 2 - 127; g += (short)c_have->g / 2 - 127; b += (short)c_have->b / 2 - 127; loccolor.r = (r < 0) ? 0 : (unsigned char)r; loccolor.g = (g < 0) ? 0 : (unsigned char)g; loccolor.b = (b < 0) ? 0 : (unsigned char)b; return loccolor; } /* * ---------------------------------------------------------------------------- * * PlotPNMTechInit -- * * Called when magic starts up. * * * Results: * None. * * Side effects: * Initializes lk[...] array with the lanczos kernel. * * ---------------------------------------------------------------------------- */ void PlotPNMTechInit() { int i; /* Clear out any old information */ if (PaintStyles != NULL) freeMagic(PaintStyles); PaintStyles = (pstyle *)mallocMagic(DBNumUserLayers * sizeof(pstyle)); for (i = 0; i < DBNumUserLayers; i++) { PaintStyles[i].wmask = 0; PaintStyles[i].color.r = 0xff; PaintStyles[i].color.g = 0xff; PaintStyles[i].color.b = 0xff; } Init_Error = 0; /* Initialize Lanczos kernel */ for (i = 0; i <= 2 * LANCZOS_KERNEL_SIZE; i++) lk[i] = lanczos_kernel(i, LANCZOS_KERNEL_SIZE); } /* * ---------------------------------------------------------------------------- * * PlotPNMTechLine -- * * Parse a magic technology file line for the pnm plot style * * Results: * Return TRUE always (no errors flagged). * * Side effects: * Modifies paintstyles[] array. * * ---------------------------------------------------------------------------- */ /* ARGSUSED */ bool PlotPNMTechLine(sectionName, argc, argv) char *sectionName; /* Name of this section (unused). */ int argc; /* Number of arguments on line. */ char *argv[]; /* Pointers to fields of line. */ { int i, j, k, style; if (!strncmp(argv[0], "color", 5)) PlotLoadColormap((argc == 1) ? NULL : argv[1]); else if (!strncmp(argv[0], "dstyle", 6)) PlotLoadStyles((argc == 1) ? NULL : argv[1]); else if (!strncmp(argv[0], "draw", 4)) { if (argc == 2) { /* Use the default drawing style(s) for this type. */ i = (int)DBTechNameType(argv[1]); if (i >= 0 && i < DBNumUserLayers) { for (j = 0; j < DBWNumStyles; j++) { style = j + TECHBEGINSTYLES; if (TTMaskHasType(DBWStyleToTypes(j), i)) { PaintStyles[i].wmask |= GrStyleTable[style].mask; PaintStyles[i].color = PNMColorIndexAndBlend(&PaintStyles[i].color, GrStyleTable[style].color); } } } } else if (argc == 3) { /* Use the specified drawing style(s) instead of the */ /* display drawing styles (used to override crosses */ /* on contacts and such). */ k = (int)DBTechNameType(argv[1]); if (k >= 0 && k < DBNumUserLayers) { for (j = 2; j < argc; j++) { /* Use the specified display style, or the internal one */ if (ndstyles > 0) { for (i = 0; i < ndstyles; i++) { if (!strcmp(Dstyles[i].name, argv[j])) { PaintStyles[k].wmask |= Dstyles[i].wmask; PaintStyles[k].color = PNMColorBlend(&PaintStyles[k].color, &Dstyles[i].color); } } } else { i = (int)GrGetStyleFromName(argv[j]); if (i >= 0) { PaintStyles[k].wmask |= GrStyleTable[i].mask; PaintStyles[k].color = PNMColorIndexAndBlend(&PaintStyles[k].color, GrStyleTable[i].color); } } } } } } else if (!strncmp(argv[0], "map", 3)) { k = (int)DBTechNameType(argv[1]); if (k >= 0 && k < DBNumUserLayers) { for (j = 2; j < argc; j++) { i = (int)DBTechNameType(argv[j]); if (i >= 0) { PaintStyles[k].wmask |= PaintStyles[i].wmask; PaintStyles[k].color = PNMColorBlend(&PaintStyles[k].color, &PaintStyles[i].color); } } } } return TRUE; } /* * ---------------------------------------------------------------------------- * * PlotPNMTechFinal -- * * Routine to be run at the end of reading the "plot pnm" techfile * section. * * Results: * None. * * Side effects: * The "Dstyles" array is no longer needed and is free'd. * The "PNMTypeTable" is malloc'd and entries filled. * * ---------------------------------------------------------------------------- */ void PlotPNMTechFinal() { int i, j, style; for (i = 0; i < ndstyles; i++) freeMagic(Dstyles[i].name); if (Dstyles != NULL) { freeMagic(Dstyles); Dstyles = NULL; ndstyles = 0; } if (PNMcolors != NULL) { freeMagic(PNMcolors); PNMcolors = NULL; ncolors = 0; } /* If no "draw" or "map" lines were declared in the technology */ /* file, then we put together a default style where we use the */ /* display dstyles for each layer. We detect the condition as */ /* having all wmask values 0 in the PaintStyles array. */ for (i = TT_SPACE + 1; i < DBNumUserLayers; i++) if (PaintStyles[i].wmask != 0) break; if (i < DBNumUserLayers) return; for (i = TT_SPACE + 1; i < DBNumUserLayers; i++) { for (j = 0; j < DBWNumStyles; j++) { style = j + TECHBEGINSTYLES; if (TTMaskHasType(DBWStyleToTypes(j), i)) { PaintStyles[i].wmask |= GrStyleTable[style].mask; PaintStyles[i].color = PNMColorIndexAndBlend(&PaintStyles[i].color, GrStyleTable[style].color); } } } } /* * ---------------------------------------------------------------------------- * * PlotLoadStyles -- * * Read in the plotting styles for rendering. * * Results: * None. * * Side effects: * Initializes arrays for drawing/plotting. * * ---------------------------------------------------------------------------- */ void PlotLoadStyles(filename) char *filename; { FILE *inp; char fullName[256]; char *buf; int newsec; int ord, mask, color, outline, nfill, stipple; int ir, ig, ib; char shortname; char longname[128]; char fill[42]; if (filename == NULL) { (void) sprintf(fullName, "%.100s.7bit.mraster_dstyle", DBWStyleType); buf = fullName; } else { buf = filename; } inp = PaOpen(buf, "r", (char *)NULL, ".", SysLibPath, (char **) NULL); if (inp == NULL) { TxError ("PNM plot: Could not open display style file\n"); Init_Error = 1; return; } buf = fullName; /* reuse this space for input */ ndstyles = 0; Dstyles = (dstyle *)mallocMagic(DBWNumStyles * sizeof(dstyle)); /* Read in the dstyle file */ newsec = FALSE; while (fgets (buf, 256, inp)) { if (buf[0] == '#') continue; if (StrIsWhite (buf, FALSE)) { newsec = TRUE; continue; } else if (newsec) { if (strncmp (buf, "display_styles", 14) != 0) goto dstyle_err; newsec = FALSE; } else { if (sscanf (buf, "%d %d %d %d %40s %d %c %126s", &ord, &mask, &color, &outline, fill, &stipple, &shortname, longname) != 8) goto dstyle_err; if (ndstyles == DBWNumStyles) goto dstyle_err; Dstyles[ndstyles].wmask = mask; if ((ncolors > 0) && (color >=0) && (color < ncolors)) { Dstyles[ndstyles].color = PNMcolors[color]; } else { GrGetColor(color, &ir, &ig, &ib); Dstyles[ndstyles].color.r = (unsigned char)ir; Dstyles[ndstyles].color.g = (unsigned char)ig; Dstyles[ndstyles].color.b = (unsigned char)ib; } Dstyles[ndstyles].name = StrDup(NULL, longname); ndstyles++; if (ndstyles == DBWNumStyles) break; } } fclose (inp); return; dstyle_err: Init_Error = 1; TxError ("Format error in display style file\n"); fclose (inp); } /* * ---------------------------------------------------------------------------- * * PlotLoadColormap -- * * Read in the colormap for rendering. * * Results: * None. * * Side effects: * Initializes arrays for drawing/plotting. * * ---------------------------------------------------------------------------- */ void PlotLoadColormap(filename) char *filename; { FILE *inp; char fullName[256]; char *buf; int red, blue, green; /* read in color map */ if (filename == NULL) { (void) sprintf(fullName, "%.100s.7bit.mraster.cmap", DBWStyleType); buf = fullName; } else buf = filename; inp = PaOpen(buf, "r", (char *) NULL, ".", SysLibPath, (char **) NULL); if (inp == NULL) { TxError("Couldn't open colormap file \"%s\"\n", buf); Init_Error = 1; return; } buf = fullName; /* reuse this space for input */ ncolors = 0; PNMcolors = (pnmcolor *)mallocMagic(128 * PIXELSZ); while (fgets (buf, 256, inp)) { if (buf[0] == '#') continue; if (StrIsWhite (buf, FALSE)) continue; if (ncolors == 128) { goto color_err; } if (sscanf (buf, "%d %d %d", &red, &green, &blue) != 3) { goto color_err; } PNMcolors[ncolors].r = (unsigned char)red; PNMcolors[ncolors].g = (unsigned char)green; PNMcolors[ncolors].b = (unsigned char)blue; ncolors++; } fclose(inp); return; color_err: Init_Error = 1; TxError ("Format error in colormap file\n"); fclose (inp); } magic-8.0.210/plot/plotHP.c0000644000175000001440000002470511051047232014005 0ustar timusers/* *---------------------------------------------------------------------- * plotHP.c -- * * This file contains the procedures that generate plots in * HP Raster Transfer Language (HPRTL) and HPGL2. * *---------------------------------------------------------------------- */ #include #include #include #include "utils/malloc.h" #include "plot/plotInt.h" #ifdef VERSATEC extern int PlotRTLCompress(); extern void PlotHPRTLTrailer(); extern int rasFileByteCount; /* * ---------------------------------------------------------------------------- * * PlotHPRTLHeader -- * * Header for HP RTL format (standard for, e.g., HP color laser printers) * * ---------------------------------------------------------------------------- */ void PlotHPRTLHeader(width, height, density, hpfile) int width, height, density; FILE *hpfile; { fprintf(hpfile, "\033*r-3U\n"); /* Simple CMY color space */ fprintf(hpfile, "\033*r%dS", width); /* Image width in pixels. */ fprintf(hpfile, "\033*r%dT", height); /* Image height in pixels.*/ fprintf(hpfile, "\033&a1N"); /* No negative motion. */ fprintf(hpfile, "\033*b2M"); /* Mode 2 row compression */ fprintf(hpfile, "\033*t%dR", density); /* Plotting density in DPI. */ fprintf(hpfile, "\033*r0A"); /* Start raster data. */ } /* * ---------------------------------------------------------------------------- * * PlotHPGL2Header -- * * Header for HPGL2 (plotter) format * * ---------------------------------------------------------------------------- */ #define LABEL_SPACER 200 /* Height of the label area, in pixels */ #define IN_TO_HPGL 1016 /* HPGL2 coordinates are in 0.025mm units */ #define THIN_MARGIN 40 /* thin spacer (1mm) in HPGL2 coordinates */ void PlotHPGL2Header(width, height, density, scale, hpfile) int width, height, density, scale; FILE *hpfile; { fprintf(hpfile, "\033%%-12345X"); /* Universal Command Language. */ fprintf(hpfile, "@PJL ENTER LANGUAGE=HPGL2\r\n"); fprintf(hpfile, "\033E\033%%0B"); /* Reset printer; set HPGL2 mode. */ fprintf(hpfile, "BP1,\"MAGIC\",5,1;"); /* Declare name; disable auto-rotate */ fprintf(hpfile, "PS%d,%d;", ((height + LABEL_SPACER) * IN_TO_HPGL / density) + THIN_MARGIN, (width * IN_TO_HPGL / density) + THIN_MARGIN); /* Move the pen to the right edge of the paper. */ fprintf(hpfile, "SP1PA%d,0", (width * IN_TO_HPGL / density)); /* Plot upside down with a 10-point font. */ fprintf(hpfile, "DI-1,0SD3,10;"); /* Plot a label. */ fprintf(hpfile, "LB\r\nMagic Plot (%dX)\r\n\003SP0;", scale); fprintf(hpfile, "\033%%0A"); /* Enter RTL mode. */ fprintf(hpfile, "\033*v1N"); /* Source mode opaque */ /* Make room for the label string by moving vertically. */ fprintf(hpfile, "\033*b%dY", LABEL_SPACER); /* HPRTL Color reference guide: */ /* h20000.www2.hp.com/bc/docs/support/SupportManual/bpl13212/bpl13212.pdf */ /* Configure Image Data (CID) command */ /* Color space (1) = CMY */ /* Pixel encoding mode (0) = Index by plane */ /* Bits per index (3) = 8-index (2^3) colormap */ /* Color planes (1, 1, 1) = 1 bit each */ /* Bit planes are cyan / magenta / yellow and must */ /* be output in that order. */ /* fwrite("\033*v6W\1\0\3\1\1\1", 11, 1, hpfile); */ /* Apparently some plotters don't support plane-indexed CMY mode. */ /* Due to this oversight, it is necessary to build the CMY color */ /* table by hand by reversing the RGB color table. */ fwrite("\033*v6W\0\0\3\1\1\1", 11, 1, hpfile); fprintf(hpfile, "\033*v255a255b255c0I\n"); fprintf(hpfile, "\033*v0a255b255c1I\n"); fprintf(hpfile, "\033*v255a0b255c2I\n"); fprintf(hpfile, "\033*v0a0b255c3I\n"); fprintf(hpfile, "\033*v255a255b0c4I\n"); fprintf(hpfile, "\033*v0a255b0c5I\n"); fprintf(hpfile, "\033*v255a0b0c6I\n"); fprintf(hpfile, "\033*v0a0b0c7I\n"); fprintf(hpfile, "\033*r%dS", width); /* Set the image width in pixels. */ fprintf(hpfile, "\033*r%dT", height); /* Set the image height in pixels.*/ fprintf(hpfile, "\033&a1N"); /* No negative motion. */ fprintf(hpfile, "\033*b2M"); /* Mode 2 row compression */ fprintf(hpfile, "\033*t%dR", density); /* Plot density, in DPI. */ fprintf(hpfile, "\033*r1A"); /* Start sending raster data. */ } /* * ---------------------------------------------------------------------------- * * PlotHPRTLTrailer -- * * ---------------------------------------------------------------------------- */ void PlotHPRTLTrailer(hpfile) FILE *hpfile; { fprintf(hpfile, "\033*r0B\014\n"); /* End raster graphics. */ } /* * ---------------------------------------------------------------------------- * * PlotHPGL2Trailer -- * * ---------------------------------------------------------------------------- */ void PlotHPGL2Trailer(hpfile) FILE *hpfile; { fprintf(hpfile, "\033*rC"); /* End raster graphics. */ fprintf(hpfile, "\033%%0B"); /* HPGL2 mode. */ fprintf(hpfile, "PG;"); /* Terminate plot. */ fprintf(hpfile, "\033%%-12345X"); /* Universal command language reset. */ fprintf(hpfile, "@PJL\r\n"); } /* * ---------------------------------------------------------------------------- * HP Run-length compression algorithm #2 * This code has been taken from the "p3" PNM-to-HPRTL conversion tool. * Subroutine written by Noel Gorelick (ngorelic@speclab.cr.usgs.gov) * Author's comments below: * * The HP Paintjet 300-XL and DesignJet 650C both have the option of receiving * data using TIFF packbits encoding. This seemed like a good idea to me, so I * ran to the libtiff package to see if there was anything useful there to do * packbits for me. I was sorely disappointed to find a large (225 lines) * routine that will do this, but replys heavily on the internal data * structures used by the rest of the libtiff library. * * So, I wrote my own. Here is a much simpler pair of routines to do the same * thing. These were tested on both the PaintJet-300XL and DesignJet 650C, * having been compiled using an HP9000s800. If anyone is actually interested * in the driver program that converts a PPM image for use on these printers, I * could probably post that as well. * * Noel (ngorelic@speclab.cr.usgs.gov) *----------------------------------------------------------------------- */ /* *----------------------------------------------------------------------- * * PlotRTLCompress -- * * This routine encodes a string using the TIFF packbits encoding * scheme. This encoding method is used by several HP peripherals to * reduce the size of incoming raster images. Both routines convert s1 * into s2. The len parameter indicates the size of the incoming string. * The return value is the size of the output string (in s2). * * Results: * Returns the length of the compressed data. Note that compression * is not guaranteed, and the output may be larger than the input. * However, it is bounded by N + (N / 127) + 1. * * Side effects: * Output data placed in s2, which must be large enough to hold it. * *----------------------------------------------------------------------- */ int PlotRTLCompress(s1, s2, len) unsigned char *s1, *s2; int len; { /* * Pack s1 using TIFF packbits encoding into s2 */ int count = 0; int i; int base, newbase, size, outp; base = newbase = outp = 0; for (i = 1; i < len; i++) { if (s1[newbase] == s1[i]) count++; else { if (count < 2) { newbase = i; count = 0; } else { /* * Put any backed up literals first. */ while ((newbase - base) > 0) { size = MIN(127, newbase - base - 1); s2[outp++] = size; memcpy(s2 + outp, s1 + base, size + 1); outp += size + 1; base += size + 1; } /* * Now put -count and repeated string. */ count++; while (count > 0) { size = MIN(128, count); s2[outp++] = -(size - 1); s2[outp++] = s1[newbase]; count -= size; } base = newbase = i; } } } /* * Output any trailing literals. */ newbase = i; while ((newbase - base) > 0) { size = MIN(127, newbase - base - 1); s2[outp++] = size; memcpy(s2 + outp, s1 + base, size + 1); outp += size + 1; base += size + 1; } return (outp); } /* * ---------------------------------------------------------------------------- * * PlotDumpHPRTL -- * * Combines the four (CMYK) swath buffers by ORing the black image * into the primary color swaths. The swath is compressed using * HP run-length row compression mode 2 (TIFF compression). * * Results: * Returns 0 if all was well. Returns non-zero if there was * an I/O error. In this event, this procedure prints an * error message before returning. * * Side effects: * Information is added to the file. * * ---------------------------------------------------------------------------- */ int PlotDumpHPRTL(hpfile, kRaster, cRaster, mRaster, yRaster) FILE *hpfile; /* File in which to dump it. */ Raster *kRaster; /* Rasters to be dumped. */ Raster *cRaster; Raster *mRaster; Raster *yRaster; { int line, count, line_offset = 0; int ipl, bpl; register int *c, *m, *y, *k; unsigned char *obytes; /* bytes to output (compressed) */ int size; ipl = kRaster->ras_intsPerLine; bpl = kRaster->ras_bytesPerLine; c = cRaster->ras_bits; m = mRaster->ras_bits; y = yRaster->ras_bits; k = kRaster->ras_bits; /* Mode 2 row compression has a worst-case length of N + (N / 127) + 1 */ obytes = (unsigned char *)mallocMagic(bpl + (bpl / 127) + 1); for (line = 0; line < kRaster->ras_height; line++) { /* Merge the black plane into C, M, and Y */ for (count = 0; count < ipl; count++) { *c++ = (*c | *k); *m++ = (*m | *k); *y++ = (*y | *k); k++; } /* Compress each plane (C, M, and Y) and output */ size = PlotRTLCompress(c - ipl, obytes, bpl); fprintf(hpfile, "\033*b%dV", size); fwrite(obytes, size, 1, hpfile); size = PlotRTLCompress(m - ipl, obytes, bpl); fprintf(hpfile, "\033*b%dV", size); fwrite(obytes, size, 1, hpfile); size = PlotRTLCompress(y - ipl, obytes, bpl); fprintf(hpfile, "\033*b%dW", size); fwrite(obytes, size, 1, hpfile); } freeMagic(obytes); if (count < 0) { TxError("I/O error in writing HPRTL file: %s.\n", strerror(errno)); return 1; } rasFileByteCount += count; return 0; } #endif /* VERSATEC */ magic-8.0.210/plot/plotCmd.c0000644000175000001440000002031510751423606014203 0ustar timusers/* * PlotCmd.c -- * * Commands for the plot module only. * * ********************************************************************* * * 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/plot/plotCmd.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include #include #include "tcltk/tclmagic.h" #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "utils/utils.h" #include "database/database.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "utils/main.h" #include "textio/txcommands.h" #include "plow/plow.h" #include "select/select.h" #include "commands/commands.h" #include "plot/plotInt.h" /* * ---------------------------------------------------------------------------- * * CmdPlot -- * * Implement the "plot" command: generate plot output for what's * underneath the box. * * Usage: * plot type [options] * * Results: * None. * * Side effects: * Generates plot output on disk somewhere. * * ---------------------------------------------------------------------------- */ /* These definitions must correspond to the ordering in cmdPlotOption[] below */ typedef enum { POSTSCRIPT=0, PLOTPNM, #ifdef GREMLIN STYLE_GREMLIN, #endif #ifdef VERSATEC STYLE_VERSATEC, #endif #ifdef LLNL PIXELS, #endif PARAMETERS, HELP } PlotOptions; void CmdPlot(w, cmd) MagWindow *w; TxCommand *cmd; { int option; char **msg; MagWindow *window; DBWclientRec *crec; TileTypeBitMask mask; CellDef *boxRootDef; SearchContext scx; float width; int iwidth, scale; static char *cmdPlotOption[] = { "postscript file [layers] generate PostScript file for what's\n\ underneath the box", "pnm file [width [layers]] generate PNM file for what's\n\ underneath the box", #ifdef GREMLIN "gremlin file [layers] generate gremlin file for what's\n\ underneath the box", #endif #ifdef VERSATEC "versatec [scale [layers]] generate plot for selected printer;\n\ scale is multiplying factor for parameter\n\ lambda, for layers underneath the box", #endif #ifdef LLNL "pixels [width [layers]] generate plot in pix format, width pixels\n\ wide, for layers underneath box", #endif /* LLNL */ "parameters [name value] set or print out plotting parameters", "help print this help information", NULL }; if (cmd->tx_argc < 2) { option = HELP; cmd->tx_argc = 2; } else { option = Lookup(cmd->tx_argv[1], cmdPlotOption); if (option < 0) { TxError("\"%s\" isn't a valid plot option.\n", cmd->tx_argv[1]); option = HELP; cmd->tx_argc = 2; } } if ((option == PLOTPNM) || (option == POSTSCRIPT) #ifdef GREMLIN || (option == STYLE_GREMLIN) #endif #ifdef VERSATEC || (option == STYLE_VERSATEC) #endif #ifdef LLNL || (option == PIXELS) #endif ) { window = ToolGetPoint((Point *) NULL, (Rect *) NULL); if (window == NULL) { windCheckOnlyWindow(&window, DBWclientID); if ((window == (MagWindow *) NULL) || (window->w_client != DBWclientID)) { TxError("The cursor must be over a layout window to plot.\n"); return; } } crec = (DBWclientRec *) window->w_clientData; scx.scx_use = (CellUse *) window->w_surfaceID; if ((!ToolGetBox(&boxRootDef, &scx.scx_area)) || (scx.scx_use->cu_def != boxRootDef)) { TxError("The box and cursor must appear in the same window\n"); TxError(" for plotting. The box indicates the area to\n"); TxError(" plot, and the cursor's window tells which\n"); TxError(" cells are expanded and unexpanded).\n"); return; } scx.scx_trans = GeoIdentityTransform; mask = crec->dbw_visibleLayers; if ((crec->dbw_flags & DBW_SEELABELS) && (crec->dbw_labelSize >= 0)) TTMaskSetType(&mask, L_LABEL); else TTMaskClearType(&mask, L_LABEL); TTMaskSetType(&mask, L_CELL); } switch (option) { case POSTSCRIPT: if ((cmd->tx_argc != 3) && (cmd->tx_argc != 4)) { TxError("Wrong number of arguments:\n plot %s\n", cmdPlotOption[POSTSCRIPT]); return; } if (cmd->tx_argc == 4) { if (!CmdParseLayers(cmd->tx_argv[3], &mask)) return; } PlotPS(cmd->tx_argv[2], &scx, &mask, crec->dbw_bitmask); return; #ifdef GREMLIN case STYLE_GREMLIN: if ((cmd->tx_argc != 3) && (cmd->tx_argc != 4)) { TxError("Wrong number of arguments:\n plot %s\n", cmdPlotOption[STYLE_GREMLIN]); return; } if (cmd->tx_argc == 4) { if (!CmdParseLayers(cmd->tx_argv[3], &mask)) return; } PlotGremlin(cmd->tx_argv[2], &scx, &mask, crec->dbw_bitmask); return; #endif /* GREMLIN */ case HELP: TxPrintf("The \"plot\" commands are:\n"); for (msg = &(cmdPlotOption[0]); *msg != NULL; msg++) { TxPrintf(" plot %s\n", *msg); } return; case PARAMETERS: if (cmd->tx_argc == 2) PlotPrintParams(); else if (cmd->tx_argc == 4) PlotSetParam(cmd->tx_argv[2], cmd->tx_argv[3]); else { TxError("Wrong arguments:\n plot %s\n", cmdPlotOption[PARAMETERS]); } return; #ifdef VERSATEC case STYLE_VERSATEC: if (cmd->tx_argc > 4) { TxError("Too many arguments:\n plot %s\n", cmdPlotOption[STYLE_VERSATEC]); return; } if (cmd->tx_argc >= 3) scale = atoi(cmd->tx_argv[2]); else scale = 0.0; if (cmd->tx_argc == 4) { if (!CmdParseLayers(cmd->tx_argv[3], &mask)) return; } PlotVersatec( &scx, &mask, crec->dbw_bitmask, scale); return; #endif case PLOTPNM: if (cmd->tx_argc > 5) { TxError("Too many arguments:\n plot %s\n", cmdPlotOption[PLOTPNM]); return; } if (cmd->tx_argc < 3) { TxError("Too few arguments:\n plot %s\n", cmdPlotOption[PLOTPNM]); return; } if (cmd->tx_argc >= 4) { #ifdef VERSATEC if (PlotPNMRTL && StrIsNumeric(cmd->tx_argv[3])) iwidth = (int)(atof(cmd->tx_argv[3]) * (double)PlotVersDotsPerInch); else #endif if (!StrIsInt(cmd->tx_argv[3])) { { TxError("Width should be an integer number of pixels\n"); return; } } else iwidth = atoi(cmd->tx_argv[3]); } #ifdef VERSATEC /* RTL mode allows no filename. A temporary filename is created */ /* for the file being spooled to the printer. */ else if (PlotPNMRTL && StrIsNumeric(cmd->tx_argv[2])) { iwidth = (int)(atof(cmd->tx_argv[2]) * (double)PlotVersDotsPerInch); PlotPNM(NULL, &scx, &mask, crec->dbw_bitmask, iwidth); return; } #endif else iwidth = 1000; /* Default value */ if (cmd->tx_argc == 5) if (!CmdParseLayers(cmd->tx_argv[4], &mask)) return; PlotPNM(cmd->tx_argv[2], &scx, &mask, crec->dbw_bitmask, iwidth); return; #ifdef LLNL case PIXELS: if (cmd->tx_argc > 4) { TxError("Too many arguments:\n plot %s\n", cmdPlotOption[PIXELS]); return; } if (cmd->tx_argc >=3) iwidth = cmdParseCoord(w, cmd->tx_argv[2], TRUE, TRUE); else iwidth = 0; /* means get it from the plot parameters */ if (cmd->tx_argc == 4) { if (!CmdParseLayers(cmd->tx_argv[3], &mask)) return; } PlotPixels( &scx, &mask, crec->dbw_bitmask, iwidth); return; #endif /* LLNL */ } } magic-8.0.210/plot/plotGremln.c0000644000175000001440000005561711020566171014734 0ustar timusers/* * plotGremlin.c -- * * This file contains procedures that generate Gremlin-format files * to describe a section of layout. * * ********************************************************************* * * 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/plot/plotGremln.c,v 1.2 2008/06/01 18:37:45 tim Exp $"; #endif /* not lint */ #include #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/tech.h" #include "utils/malloc.h" #include "utils/utils.h" #include "windows/windows.h" #include "commands/commands.h" #include "dbwind/dbwind.h" #include "textio/textio.h" /* Records of the following type are used to describe how to generate * Gremlin output for a particular set of mask layers. Each style * describes the Gremlin figures to draw for a particular set of * layers. A single layer may participate in several gremlin styles. */ #ifdef GREMLIN typedef struct gremlinstyle { TileTypeBitMask grs_layers; /* Layers to plot in this style. */ int grs_stipple; /* Type of fill to use. See below. */ struct gremlinstyle *grs_next; /* Next style in chain. */ } GremlinStyle; static GremlinStyle *plotGremlinStyles; /* Most of the grs_stipple values are Gremlin stipple numbers. However, * if a grs_stipple value is less than zero, it means something special. * The definitions below give the possible alternatives: * * CROSS: Draw a thick outline around the tile with * a cross through it (used for contacts). * BORDER: Same as CROSS, except draw the outline with * no cross through it. */ #define CROSS -1 #define BORDER -2 /* The definitions below give the integers used for various Gremlin * line drawing styles (brushes). */ #define GREMLIN_DOTTED 1 #define GREMLIN_DASHED 4 #define GREMLIN_DOTDASH 2 #define GREMLIN_THIN 5 #define GREMLIN_MEDIUM 6 #define GREMLIN_THICK 3 /* The variables below are used to pass information from the top-level * procedure PlotGremlin down to the lower-level search functions * that are invoked for pieces of the layout. */ static FILE *file; /* File to use for output. */ static float scale; /* Multiply this by Magic units to get * Gremlin units. */ static GremlinStyle *curStyle; /* Current style being output. */ static TileTypeBitMask curMask; /* Layers currently being searched: this * is the AND of the mask from curStyle and * the layers that the user specified. */ static Rect bbox; /* Bounding box, in root coordinates, of * area being plotted. */ #endif /* GREMLIN */ /* * ---------------------------------------------------------------------------- * PlotGremlinTechInit -- * * Called once at beginning of technology file read-in to initialize * data structures. * * Results: * None. * * Side effects: * Clears out the list of things to plot. * ---------------------------------------------------------------------------- */ #ifdef GREMLIN void PlotGremlinTechInit() { GremlinStyle *style; for (style = plotGremlinStyles; style != NULL; style = style->grs_next) { freeMagic((char *) style); } plotGremlinStyles = NULL; } #else void PlotGremlinTechInit() {} #endif /* GREMLIN */ /* * ---------------------------------------------------------------------------- * PlotGremlinTechLine -- * * This procedure is invoked by the technology module once for * each line in the "gremlin" subsection of the "plot" 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 table of Gremlin styles. * ---------------------------------------------------------------------------- */ #ifdef GREMLIN bool PlotGremlinTechLine(sectionName, argc, argv) char *sectionName; /* Name of this section (unused). */ int argc; /* Number of arguments on line. */ char *argv[]; /* Pointers to fields of line. */ { GremlinStyle *new; int stipple, i; if (argc != 2) { TechError("\"gremlin\" lines must have exactly 2 arguments.\n"); return TRUE; } if (strcmp(argv[1], "X") == 0) stipple = CROSS; else if (strcmp(argv[1], "B") == 0) stipple = BORDER; else { if (!StrIsInt(argv[1])) { TechError("2nd field must be an integer or \"X\" or \"B\".\n"); return TRUE; } stipple = atoi(argv[1]); } new = (GremlinStyle *) mallocMagic(sizeof(GremlinStyle)); DBTechNoisyNameMask(argv[0], &new->grs_layers); /* Replace non-primary contact images with primary images. */ for (i = TT_TECHDEPBASE; i < DBNumTypes; i++) { if TTMaskHasType(&new->grs_layers, i) TTMaskSetMask(&new->grs_layers, &DBLayerTypeMaskTbl[i]); } TTMaskAndMask(&new->grs_layers, &DBUserLayerBits); new->grs_stipple = stipple; new->grs_next = plotGremlinStyles; plotGremlinStyles = new; return TRUE; } #else bool PlotGremlinTechLine(sectionName, argc, argv) char *sectionName; /* Name of this section (unused). */ int argc; /* Number of arguments on line (unused). */ char *argv[]; /* Pointers to fields of line (unused). */ { return TRUE; } #endif /* GREMLIN */ #ifdef GREMLIN /* * ---------------------------------------------------------------------------- * * plotGremlinLine -- * * Outputs a line into the current Gremlin file. * * Results: * None. * * Side effects: * I/O. * * ---------------------------------------------------------------------------- */ void plotGremlinLine(p1, p2, lineStyle) Point *p1, *p2; /* Endpoints of line, given in root * coordinates. */ int lineStyle; /* Gremlin line style to use for line. */ { float x1, x2, y1, y2, limit; /* Clip the line to the rectangular area being output. First, * arrange for the first x-coordinate to be the smaller, then * clip against vertical lines at the x-boundaries. */ if (p1->p_x <= p2->p_x) { x1 = p1->p_x - bbox.r_xbot; x2 = p2->p_x - bbox.r_xbot; y1 = p1->p_y - bbox.r_ybot; y2 = p2->p_y - bbox.r_ybot; } else { x1 = p2->p_x - bbox.r_xbot; x2 = p1->p_x - bbox.r_xbot; y1 = p2->p_y - bbox.r_ybot; y2 = p1->p_y - bbox.r_ybot; } limit = bbox.r_xtop - bbox.r_xbot; if ((x1 > limit) || (x2 < 0)) return; if (x1 < 0) { y1 += (-x1)*(y2-y1)/(x2-x1); x1 = 0; } if (x2 > limit) { y2 -= (x2-limit)*(y2-y1)/(x2-x1); x2 = limit; } /* Now clip against horizontal lines at the y-boundaries. */ if (y2 < y1) { float tmp; tmp = y2; y2 = y1; y1 = tmp; tmp = x2; x2 = x1; x1 = tmp; } limit = bbox.r_ytop - bbox.r_ybot; if ((y1 > limit) || (y2 < 0)) return; if (y1 < 0) { x1 += (-y1)*(x2-x1)/(y2-y1); y1 = 0; } if (y2 > limit) { x2 -= (y2-limit)*(x2-x1)/(y2-y1); y2 = limit; } /* Lastly, scale and generate Gremlin output. */ x1 *= scale; x2 *= scale; y1 *= scale; y2 *= scale; fprintf(file, "VECTOR\n"); fprintf(file, "%.3f %.3f\n%.3f %.3f\n", x1, y1, x2, y2); fprintf(file, "*\n%d 0\n0 \n", lineStyle); } /* * ---------------------------------------------------------------------------- * * plotGremlinRect -- * * Outputs Gremlin statements to draw a rectangular area as * an outline with a given line style. * * Results: * None. * * Side effects: * Adds information to the current Gremlin file. * * ---------------------------------------------------------------------------- */ void plotGremlinRect(rect, lineStyle) Rect *rect; /* Rectangle to be drawn, in root coords. */ int lineStyle; /* Gremlin line style to use for outline. */ { Point p; p.p_x = rect->r_xbot; p.p_y = rect->r_ytop; plotGremlinLine(&rect->r_ll, &p, lineStyle); plotGremlinLine(&p, &rect->r_ur, lineStyle); p.p_x = rect->r_xtop; p.p_y = rect->r_ybot; plotGremlinLine(&rect->r_ur, &p, lineStyle); plotGremlinLine(&p, &rect->r_ll, lineStyle); } /* * ---------------------------------------------------------------------------- * * plotGremlinPaint -- * * This procedure is invoked once for each paint rectangle in * the area being plotted. * * Results: * Always returns 0 to keep the search alive. * * Side effects: * Outputs information for the tile, including stipple for its * interior, and a solid line for any portion of the boundary * of the tile that is adjacent to a tile NOT in this style. * * ---------------------------------------------------------------------------- */ int plotGremlinPaint(tile, cxp) Tile *tile; /* Tile that's of type to be output. */ TreeContext *cxp; /* Describes search in progress. */ { Rect tileArea, edge, rootArea; float xbot, xtop, ybot, ytop; Tile *neighbor; /* First transform tile coords to root coords */ TiToRect(tile, &tileArea); GeoTransRect(&cxp->tc_scx->scx_trans, &tileArea, &rootArea); /* See if this tile gets special handling. */ if ((curStyle->grs_stipple == CROSS) || (curStyle->grs_stipple == BORDER)) { /* Draw tile as a thick outline with a cross from corner * to corner, and skip the rest of this procedure. */ Point ul, lr; plotGremlinRect(&rootArea, GREMLIN_MEDIUM); if (curStyle->grs_stipple == CROSS) { ul.p_x = rootArea.r_xbot; ul.p_y = rootArea.r_ytop; lr.p_x = rootArea.r_xtop; lr.p_y = rootArea.r_ybot; plotGremlinLine(&rootArea.r_ll, &rootArea.r_ur, GREMLIN_MEDIUM); plotGremlinLine(&ul, &lr, GREMLIN_MEDIUM); } return 0; } /* This tile gets "normal" processing (i.e. stippling and outlining). * Clip it to the plotting area and translate to Gremlin coords. * Then output Gremlin information for stippled interior. */ GeoClip(&rootArea, &bbox); xbot = (rootArea.r_xbot - bbox.r_xbot) * scale; xtop = (rootArea.r_xtop - bbox.r_xbot) * scale; ybot = (rootArea.r_ybot - bbox.r_ybot) * scale; ytop = (rootArea.r_ytop - bbox.r_ybot) * scale; fprintf(file, "POLYGON\n"); fprintf(file, "%.3f %.3f\n%.3f %.3f\n%.3f %.3f\n%.3f %.3f\n%.3f %.3f\n", xbot, ybot, xtop, ybot, xtop, ytop, xbot, ytop, xbot, ybot); fprintf(file, "*\n0 %d\n0 \n", curStyle->grs_stipple); /* Now output lines for any edges between material of the type * currently being drawn and material of other types. This is * done by searching along the tile's borders for neighbors that * have the wrong types. First, search the tile's bottom border * (unless it is at infinity). */ if (tileArea.r_ybot > TiPlaneRect.r_ybot) { edge.r_ybot = edge.r_ytop = tileArea.r_ybot; for (neighbor = LB(tile); LEFT(neighbor) < tileArea.r_xtop; neighbor = TR(neighbor)) { if (TTMaskHasType(&curMask, TiGetType(neighbor))) continue; edge.r_xbot = LEFT(neighbor); edge.r_xtop = RIGHT(neighbor); if (edge.r_xbot < tileArea.r_xbot) edge.r_xbot = tileArea.r_xbot; if (edge.r_xtop > tileArea.r_xtop) edge.r_xtop = tileArea.r_xtop; GeoTransRect(&cxp->tc_scx->scx_trans, &edge, &rootArea); plotGremlinLine(&rootArea.r_ll, &rootArea.r_ur, GREMLIN_THIN); } } /* Now go along the tile's left border, doing the same thing. Ignore * edges that are at infinity. */ if (tileArea.r_xbot > TiPlaneRect.r_xbot) { edge.r_xbot = edge.r_xtop = tileArea.r_xbot; for (neighbor = BL(tile); BOTTOM(neighbor) < tileArea.r_ytop; neighbor = RT(neighbor)) { if (TTMaskHasType(&curMask, TiGetType(neighbor))) continue; edge.r_ybot = BOTTOM(neighbor); edge.r_ytop = TOP(neighbor); if (edge.r_ybot < tileArea.r_ybot) edge.r_ybot = tileArea.r_ybot; if (edge.r_ytop < tileArea.r_ytop) edge.r_ytop = tileArea.r_ytop; GeoTransRect(&cxp->tc_scx->scx_trans, &edge, &rootArea); plotGremlinLine(&rootArea.r_ll, &rootArea.r_ur, GREMLIN_THIN); } } /* Same thing for the tile's top border. */ if (tileArea.r_ytop < TiPlaneRect.r_ytop) { edge.r_ybot = edge.r_ytop = tileArea.r_ytop; for (neighbor = RT(tile); RIGHT(neighbor) > tileArea.r_xbot; neighbor = BL(neighbor)) { if (TTMaskHasType(&curMask, TiGetType(neighbor))) continue; edge.r_xbot = LEFT(neighbor); edge.r_xtop = RIGHT(neighbor); if (edge.r_xbot < tileArea.r_xbot) edge.r_xbot = tileArea.r_xbot; if (edge.r_xtop > tileArea.r_xtop) edge.r_xtop = tileArea.r_xtop; GeoTransRect(&cxp->tc_scx->scx_trans, &edge, &rootArea); plotGremlinLine(&rootArea.r_ll, &rootArea.r_ur, GREMLIN_THIN); } } /* Finally, the right border. */ if (tileArea.r_xtop < TiPlaneRect.r_xtop) { edge.r_xbot = edge.r_xtop = tileArea.r_xtop; for (neighbor = TR(tile); TOP(neighbor) > tileArea.r_ybot; neighbor = LB(neighbor)) { if (TTMaskHasType(&curMask, TiGetType(neighbor))) continue; edge.r_ybot = BOTTOM(neighbor); edge.r_ytop = TOP(neighbor); if (edge.r_ybot < tileArea.r_ybot) edge.r_ybot = tileArea.r_ybot; if (edge.r_ytop < tileArea.r_ytop) edge.r_ytop = tileArea.r_ytop; GeoTransRect(&cxp->tc_scx->scx_trans, &edge, &rootArea); plotGremlinLine(&rootArea.r_ll, &rootArea.r_ur, GREMLIN_THIN); } } return 0; } /* * ---------------------------------------------------------------------------- * * plotGremlinLabel -- * * This procedure is invoked once for each label overlapping the * area being plotted. It generates Gremlin output to describe * the label. * * Results: * Always returns 0 to keep the search from aborting. * * Side effects: * Gremlin information is output. * * ---------------------------------------------------------------------------- */ int plotGremlinLabel(scx, label) SearchContext *scx; /* Describes state of search when label * was found. */ Label *label; /* Label that was found. */ { Rect rootArea; float x, y; float delta; int pos; /* Mapping from our GEO_xxx positions to Gremlin object types: */ static char *gremlinPosition[] = { "CENTCENT", "BOTCENT", "BOTLEFT", "CENTLEFT", "TOPLEFT", "TOPCENT", "TOPRIGHT", "CENTRIGHT", "BOTRIGHT" }; /* Compute a distance equal to 1/8th the size of a typical wire * (max of thicknesses of routing layers). This is used to offset * text from labels and to compute cross size for point labels. */ if (RtrMetalWidth > RtrPolyWidth) delta = RtrMetalWidth*scale/8; else delta = RtrPolyWidth*scale/8; /* Translate the label's area and relative position to root * coordinates, and figure out the point relative to which * the label is to be positioned. */ GeoTransRect(&scx->scx_trans, &label->lab_rect, &rootArea); pos = GeoTransPos(&scx->scx_trans, label->lab_just); switch (pos) { case GEO_NORTH: case GEO_NORTHEAST: case GEO_NORTHWEST: y = (rootArea.r_ytop - bbox.r_ybot) * scale; y += delta; break; case GEO_CENTER: case GEO_WEST: case GEO_EAST: y = (rootArea.r_ytop + rootArea.r_ybot - 2*bbox.r_ybot)*scale/2; break; case GEO_SOUTH: case GEO_SOUTHEAST: case GEO_SOUTHWEST: y = (rootArea.r_ybot - bbox.r_ybot) * scale; y -= delta; break; } switch (pos) { case GEO_WEST: case GEO_NORTHWEST: case GEO_SOUTHWEST: x = (rootArea.r_xbot - bbox.r_xbot) * scale; x -= delta; break; case GEO_CENTER: case GEO_NORTH: case GEO_SOUTH: x = (rootArea.r_xtop + rootArea.r_xbot - 2*bbox.r_xbot)*scale/2; break; case GEO_EAST: case GEO_NORTHEAST: case GEO_SOUTHEAST: x = (rootArea.r_xtop - bbox.r_xbot) * scale; x += delta; break; } /* Output the text for the label, if the label is within delta * of the area we're plotting (a large label could overlap a * bit of the area but stick out way off-screen too). */ if ((x >= -delta) && (y >= -delta) && (x <= ((bbox.r_xtop - bbox.r_xbot) * scale) + delta) && (y <= ((bbox.r_ytop - bbox.r_ybot) * scale) + delta)) { fprintf(file, "%s\n", gremlinPosition[pos]); fprintf(file, "%.3f %.3f\n*\n", x, y); fprintf(file, "1 1\n"); /* Roman font, small characters */ fprintf(file, "%d %s\n", strlen(label->lab_text), label->lab_text); } /* Output lines marking the label's area. Different things are * done depending on whether the label is a point, a line, or an * area. */ if ((rootArea.r_xbot == rootArea.r_xtop) && (rootArea.r_ybot == rootArea.r_ytop)) { /* Point label. Output a cross. */ float top, bot; x = (rootArea.r_xbot - bbox.r_xbot) * scale; y = (rootArea.r_ybot - bbox.r_ybot) * scale; top = y + delta; bot = y - delta; fprintf(file, "VECTOR\n%.3f %.3f\n%.3f %.3f\n*\n", x, bot, x, top); fprintf(file, "6 1\n0 \n"); /* Medium thickness */ top = x + delta; bot = x - delta; fprintf(file, "VECTOR\n%.3f %.3f\n%.3f %.3f\n*\n", bot, y, top, y); fprintf(file, "6 1\n0 \n"); /* Medium thickness */ } else if ((rootArea.r_xbot == rootArea.r_xtop) || (rootArea.r_ybot == rootArea.r_ytop)) { /* Line label. Just draw a medium-thickness line. */ plotGremlinLine(&rootArea.r_ll, &rootArea.r_ur, GREMLIN_MEDIUM); } else { /* Rectangular. Draw lines around the boundary. */ plotGremlinRect(&rootArea, GREMLIN_MEDIUM); } return 0; } /* * ---------------------------------------------------------------------------- * * plotGremlinCell -- * * This procedure is invoked once for each unexpanded cell that * overlaps the area being plotted. * * Results: * Always returns 0 to keep the search from aborting. * * Side effects: * Gremlin information is output to describe the cell. * * ---------------------------------------------------------------------------- */ int plotGremlinCell(scx) SearchContext *scx; /* Describes cell whose bbox is to * be plotted. */ { extern bool PlotShowCellNames; char idName[100]; Rect rootArea; CellDef *def; float x, y; /* Convert the cell's bounding box to root coordinates and then * draw as a thick outline. */ def = scx->scx_use->cu_def; GeoTransRect(&scx->scx_trans, &def->cd_bbox, &rootArea); plotGremlinRect(&rootArea, GREMLIN_THICK); if (!PlotShowCellNames) return 0; /* Output the cell definition's name in the top of the bounding box. * Use a bold font (#3), in a medium size (#2). Make sure that the * name's positioning point is within the area we're plotting. */ x = (rootArea.r_xtop + rootArea.r_xbot - 2*bbox.r_xbot)*scale/2; y = (2*rootArea.r_ytop + rootArea.r_ybot - 3*bbox.r_ybot)*scale/3; if ((x >= 0) && (y >= 0) && (x <= (bbox.r_xtop - bbox.r_xbot)*scale) && (y <= (bbox.r_ytop - bbox.r_ybot)*scale)) { fprintf(file, "CENTCENT\n%.3f %.3f\n*\n", x, y); fprintf(file, "3 2\n%d %s\n", strlen(def->cd_name), def->cd_name); } /* Output the cell id in the bottom of the bounding box. * Use an italic font (#2) in a medium size (#2). */ x = (rootArea.r_xtop + rootArea.r_xbot - 2*bbox.r_xbot)*scale/2; y = (rootArea.r_ytop + 2*rootArea.r_ybot - 3*bbox.r_ybot)*scale/3; if ((x >= 0) && (y >= 0) && (x <= (bbox.r_xtop - bbox.r_xbot)*scale) && (y <= (bbox.r_ytop - bbox.r_ybot)*scale)) { (void) DBPrintUseId(scx, idName, 100, TRUE); fprintf(file, "CENTCENT\n%.3f %.3f\n*\n", x, y); fprintf(file, "2 2\n%d %s\n", strlen(idName), idName); } return 0; } /* * ---------------------------------------------------------------------------- * * PlotGremlin -- * * This procedure generates a Gremlin file to describe an area of * a layout. * * Results: * None. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ void PlotGremlin(fileName, scx, layers, xMask) char *fileName; /* Name of Gremlin file to write. */ SearchContext *scx; /* The use and area and transformation * in this describe what to plot. */ TileTypeBitMask *layers; /* Tells what layers to plot. Only * paint layers in this mask, and also * expanded according to xMask, are * plotted. If L_LABELS is set, then * labels on the layers are also * plotted, if expanded according to * xMask. If L_CELL is set, then * subcells that are unexpanded * according to xMask are plotted as * bounding boxes. */ int xMask; /* An expansion mask, used to indicate * the window whose expansion status * will be used to determine * visibility. Zero means treat * everything as expanded. */ { int size, tmp; /* Compute a scale factor between our coordinates and Gremlin * coordinates. Pick an even power of two that will make all * the Gremlin units fall between 0 and 512. */ GeoTransRect(&scx->scx_trans, &scx->scx_area, &bbox); size = bbox.r_xtop - bbox.r_xbot; tmp = bbox.r_ytop - bbox.r_ybot; if (size < tmp) size = tmp; scale = 64.0; while (scale*size > 512) scale /= 2.0; /* Open the Gremlin file and output header information. */ file = PaOpen(fileName, "w", (char *) NULL, ".", (char *) NULL, (char **) NULL); if (file == NULL) { TxError("Couldn't write Gremlin file \"%s\".\n", fileName); return; } fprintf(file, "sungremlinfile\n"); fprintf(file, "1 0.00 0.00\n"); /* For each Gremlin style, find all the paint layers that belong * to that style and put plot information into the file. */ for (curStyle = plotGremlinStyles; curStyle != NULL; curStyle = curStyle->grs_next) { TTMaskAndMask3(&curMask, layers, &curStyle->grs_layers); (void) DBTreeSrTiles(scx, &curMask, xMask, plotGremlinPaint, (ClientData) NULL); } /* Output labels, if they are wanted. */ if (TTMaskHasType(layers, L_LABEL)) { curMask = *layers; TTMaskSetType(&curMask, TT_SPACE); (void) DBTreeSrLabels(scx, &curMask, xMask, (TerminalPath *) NULL, TF_LABEL_ATTACH, plotGremlinLabel, (ClientData) NULL); } /* Output subcell bounding boxes, if they are wanted. */ if (TTMaskHasType(layers, L_CELL)) { (void) DBTreeSrCells(scx, xMask, plotGremlinCell, (ClientData) NULL); } /* Output trailer information into the file, and close it. */ fprintf(file, "-1\n"); fclose(file); return; } #endif /* GREMLIN */ magic-8.0.210/plot/tclplot.c0000644000175000001440000000363610751423606014271 0ustar timusers/*--------------------------------------------------------------*/ /* tclplot.c */ /* */ /* Allows the "plot" feature to be loaded as a module */ /* under the Tcl/Tk version of magic. Loading is */ /* automatic upon invoking the "plot" command. */ /*--------------------------------------------------------------*/ #ifdef PLOT_AUTO #include #include #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 "plot/plot.h" #include "dbwind/dbwind.h" /* External routines */ extern void CmdPlot(); /* * ---------------------------------------------------------------------------- * * Tcl package initialization function * * ---------------------------------------------------------------------------- */ int Tclplot_Init(interp) Tcl_Interp *interp; { int n; SectionID invplot; /* 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 PLOT module\n"); TxFlushOut(); /* Replace the auto-load function with the ones defined in */ /* this package in the command functions list. */ if (WindReplaceCommand(DBWclientID, "plot", CmdPlot) < 0) return TCL_ERROR; /* Now we need to do TechAddClient and reload the tech file */ TechAddClient("plot", PlotTechInit, PlotTechLine, PlotTechFinal, (SectionID) 0, (SectionID *) 0, FALSE); /* No initialization function to go here */ invplot = TechSectionGetMask("plot", NULL); if (!TechLoad(NULL, invplot)) return TCL_ERROR; Tcl_PkgProvide(interp, "Plot", MAGIC_VERSION); return TCL_OK; } #endif /* PLOT_AUTO */ magic-8.0.210/plot/plot.h0000644000175000001440000000317410751423606013570 0ustar timusers/* * plot.h -- * * Contains definitions for things that are exported by the * plot module. * * ********************************************************************* * * 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. * * ********************************************************************* * * rcsid $Header: /usr/cvsroot/magic-8.0/plot/plot.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ */ #ifndef _PLOT_H #define _PLOT_H #include "utils/magic.h" /* Technology-file reading procedures: */ extern int PlotTechInit(); extern bool PlotTechLine(); extern void PlotTechFinal(); /* Top-level plot procedures: */ #ifdef GREMLIN extern void PlotGremlin(); #endif #ifdef VERSATEC extern void PlotVersatec(); extern void PlotHPRTLHeader(); extern void PlotHPGL2Header(); extern void PlotHPRTLTrailer(); extern void PlotHPGL2Trailer(); extern int PlotDumpHPRTL(); #endif extern void PlotPS(); extern void PlotPNM(); extern void PlotSetParam(); extern void PlotPrintParams(); #endif /* _PLOT_H */ magic-8.0.210/plot/plotMain.c0000644000175000001440000003700710751423606014372 0ustar timusers/* * plotMain.c -- * * This is the central file in the plot module. It contains tables * that define the various styles of plotting that are available, and * also contains central technology-file reading routines. * * ********************************************************************* * * 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/plot/plotMain.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/tech.h" #include "utils/malloc.h" #include "plot/plotInt.h" #include "textio/textio.h" #include "utils/utils.h" /* Magic can generate plots in several different ways, e.g. as a * Gremlin file or as a direct raster plot to a Versatec printer. * For each style of plot, there is a subsection of the plot section * of technology files. The tables below define the names of those * subsections, and the procedures to call to handle lines within * those subsections. To add a new style of plot, extend the tables * below and then modify the procedure CmdPlot to actually invoke * the top-level plotting routine. */ /* Note (10/8/04): All of the plot styles except PostScript and PNM */ /* have been removed in the default compilation. However, they should */ /* remain in the following lists so that magic doesn't complain when */ /* encountering these styles in the technology file. */ static char *plotStyles[] = /* Names of tech subsections. */ { "postscript", "pnm", "gremlin", "versatec", "colorversatec", "pixels", NULL }; /* These names need to match the plot types enumerated in plotInt.h */ static char *plotTypeNames[] = { "versatec_color", "versatec_bw", "hprtl", "hpgl2", NULL }; static void (*plotInitProcs[])() = /* Initialization procedures for * each style. */ { PlotPSTechInit, PlotPNMTechInit, PlotGremlinTechInit, PlotVersTechInit, PlotColorVersTechInit, PlotPixTechInit, NULL }; static bool (*plotLineProcs[])() = /* Proc to call for each line in * relevant subsection of tech file. */ { PlotPSTechLine, PlotPNMTechLine, PlotGremlinTechLine, PlotVersTechLine, PlotColorVersTechLine, PlotPixTechLine, NULL }; static void (*plotFinalProcs[])() = /* Proc to call at end of reading * tech files. */ { NULL, PlotPNMTechFinal, NULL, NULL, NULL, NULL, NULL }; static int plotCurStyle = -1; /* Current style being processed in * technology file. -1 means no * "style" line seen yet. -2 means * skipping to next "style" line. */ bool PlotShowCellNames = TRUE; /* TRUE if cell names and use-ids * should be printed inside cell * bounding boxes; if this is FALSE, * then only the bounding box is * drawn. */ /* * ---------------------------------------------------------------------------- * PlotTechInit -- * * Called once at beginning of technology file read-in to initialize * data structures. * * Results: * None. * * Side effects: * Calls the initialization procedures (if any) for each of the * various styles of plotting. * ---------------------------------------------------------------------------- */ void PlotTechInit() { int i; PlotRastInit(); plotCurStyle = -1; for (i = 0; plotStyles[i] != NULL; i++) { if (plotInitProcs[i] != NULL) (*(plotInitProcs[i]))(); } } /* * ---------------------------------------------------------------------------- * PlotTechLine -- * * This procedure is invoked by the technology module once for * each line in the "plot" section of the technology file. It * processes "style x" lines directly, to change the current style * of plot information. For other lines, it just passes the lines * onto the procedure for the current style. * * Results: * Returns whatever the handler for the current style returns when * we call it. * * Side effects: * Builds up plot technology information. * ---------------------------------------------------------------------------- */ bool PlotTechLine(sectionName, argc, argv) char *sectionName; /* Name of this section. */ int argc; /* Number of arguments on line. */ char *argv[]; /* Pointers to fields of line. */ { int i; if (strcmp(argv[0], "style") == 0) { if (argc != 2) { TechError("\"style\" lines must have exactly two arguments\n"); return TRUE; } /* Change the style of plot for which information is being read. */ plotCurStyle = -2; for (i = 0; plotStyles[i] != NULL; i++) { if (strcmp(argv[1], plotStyles[i]) == 0) { plotCurStyle = i; break; } } if (plotCurStyle == -2) { TechError("Plot style \"%s\" doesn't exist. Ignoring.\n", argv[1]); } return TRUE; } /* Not a new style. Just farm out this line to the handler for the * current style. */ if (plotCurStyle == -1) { TechError("Must declare a plot style before anything else.\n"); plotCurStyle = -2; return TRUE; } else if (plotCurStyle == -2) return TRUE; if (plotLineProcs[plotCurStyle] == NULL) return TRUE; return (*(plotLineProcs[plotCurStyle]))(sectionName, argc, argv); } /* * ---------------------------------------------------------------------------- * PlotTechFinal -- * * Called once at the end of technology file read-in. * * Results: * None. * * Side effects: * Calls the finalization procedures (if any) for each of the * various style of plotting. * ---------------------------------------------------------------------------- */ void PlotTechFinal() { int i; plotCurStyle = -1; for (i = 0; plotStyles[i] != NULL; i++) { if (plotFinalProcs[i] != NULL) (*(plotFinalProcs[i]))(); } } /* * ---------------------------------------------------------------------------- * * PlotPrintParams -- * * Print out a list of all the plotting parameters and their * current values. * * Results: * None. * * Side effects: * Stuff gets printed. * * ---------------------------------------------------------------------------- */ void PlotPrintParams() { TxPrintf("General plotting parameters are:\n"); TxPrintf(" showCellNames: %s\n", PlotShowCellNames ? "true" : "false"); TxPrintf(""); TxPrintf("Postscript plotting parameters are:\n"); TxPrintf(" PS_cellIdFont: \"%s\"\n", PlotPSIdFont); TxPrintf(" PS_cellNameFont:\"%s\"\n", PlotPSNameFont); TxPrintf(" PS_labelFont: \"%s\"\n", PlotPSLabelFont); TxPrintf(" PS_cellIdSize: %d\n", PlotPSIdSize); TxPrintf(" PS_cellNameSize:%d\n", PlotPSNameSize); TxPrintf(" PS_labelSize: %d\n", PlotPSLabelSize); TxPrintf(" PS_boundary: %s\n", PlotPSBoundary ? "true" : "false"); TxPrintf(" PS_width: %d (%.3f in)\n", PlotPSWidth, (float)PlotPSWidth / 72); TxPrintf(" PS_height: %d (%.3f in)\n", PlotPSHeight, (float)PlotPSHeight / 72); TxPrintf(" PS_margin: %d (%.3f in)\n", PlotPSMargin, (float)PlotPSMargin / 72); TxPrintf(""); TxPrintf("PNM plotting parameters are:\n"); TxPrintf(" pnmmaxmem: %d KB\n", PlotPNMmaxmem); TxPrintf(" pnmdownsample: %d\n", PlotPNMdownsample); TxPrintf(" pnmbackground: %d\n", PlotPNMBG); #ifdef VERSATEC TxPrintf(" pnmplotRTL: %s\n", PlotPNMRTL ? "true" : "false"); TxPrintf(""); TxPrintf("HP/Versatec plotting parameters are:\n"); TxPrintf(" cellIdFont: \"%s\"\n", PlotVersIdFont); TxPrintf(" cellNameFont: \"%s\"\n", PlotVersNameFont); TxPrintf(" directory: \"%s\"\n", PlotTempDirectory); TxPrintf(" dotsPerInch: %d\n", PlotVersDotsPerInch); TxPrintf(" labelFont: \"%s\"\n", PlotVersLabelFont); TxPrintf(" printer: \"%s\"\n", PlotVersPrinter); TxPrintf(" spoolCommand: \"%s\"\n", PlotVersCommand); TxPrintf(" swathHeight: %d\n", PlotVersSwathHeight); TxPrintf(" width: %d\n", PlotVersWidth); TxPrintf(" plotType: %s\n", plotTypeNames[PlotVersPlotType]); #endif #ifdef LLNL TxPrintf(""); TxPrintf("Pixel plotting parameters are:\n"); TxPrintf(" pixheight: %d\n", PlotPixHeight); TxPrintf(" pixwidth: %d\n", PlotPixWidth); #endif /* LLNL */ } /* * ---------------------------------------------------------------------------- * * PlotSetParam -- * * This procedure is called to change the value of one * of the plotting parameters. * * Results: * None. * * Side effects: * Whichever parameter is named by "name" is set to "value". * The interpretation of "value" depends on the parameter. * * ---------------------------------------------------------------------------- */ typedef enum { SHOWCELLNAMES=0, PSCELLIDFONT, PSNAMEFONT, PSLABELFONT, PSIDSIZE, PSNAMESIZE, PSLABELSIZE, PSBOUNDARY, PSWIDTH, PSHEIGHT, PSMARGIN, #ifdef VERSATEC CELLIDFONT, CELLNAMEFONT, LABELFONT, DIRECTORY, DOTSPERINCH, PRINTER, SPOOLCOMMAND, SWATHHEIGHT, WIDTH, PLOTTYPE, PNMRTL, #endif #ifdef LLNL PIXWIDTH, PIXHEIGHT, #endif PNMMAXMEM, PNMDOWNSAMPLE, PNMBACKGROUND } PlotParameterOptions; void PlotSetParam(name, value) char *name; /* Name of a parameter. */ char *value; /* New value for the parameter. */ { int indx, i; static char *tfNames[] = { "false", "true", 0 }; static char *paramNames[] = { "showcellnames", "ps_cellidfont", "ps_namefont", "ps_labelfont", "ps_cellidsize", "ps_namesize", "ps_labelsize", "ps_boundary", "ps_width", "ps_height", "ps_margin", #ifdef VERSATEC "cellidfont", "cellnamefont", "labelfont", "directory", "dotsperinch", "printer", "spoolcommand", "swathheight", "width", "plottype", "pnmplotRTL", /* PNM output piped through an HP plotter */ #endif #ifdef LLNL "pixwidth", "pixheight", #endif "pnmmaxmem", "pnmdownsample", "pnmbackground", NULL }; indx = Lookup(name, paramNames); if (indx < 0) { TxError("\"%s\" isn't a valid plot parameter.\n", name); PlotPrintParams(); return; } i = atoi(value); switch (indx) { case SHOWCELLNAMES: i = Lookup(value, tfNames); if (i < 0) { TxError("ShowCellNames can only be \"true\" or \"false\".\n"); return; } PlotShowCellNames = i; break; case PSCELLIDFONT: StrDup(&PlotPSIdFont, value); break; case PSNAMEFONT: StrDup(&PlotPSNameFont, value); break; case PSLABELFONT: StrDup(&PlotPSLabelFont, value); break; case PSIDSIZE: if (!StrIsInt(value) || (i <= 0)) { TxError("PS_cellIdSize must be an integer greater than zero.\n"); return; } else PlotPSIdSize = i; break; case PSNAMESIZE: if (!StrIsInt(value) || (i <= 0)) { TxError("PS_cellNameSize must be an integer greater than zero.\n"); return; } else PlotPSNameSize = i; break; case PSLABELSIZE: if (!StrIsInt(value) || (i <= 0)) { TxError("PS_labelSize must be an integer greater than zero.\n"); return; } else PlotPSLabelSize = i; break; case PSBOUNDARY: i = Lookup(value, tfNames); if (i < 0) { TxError("PS_boundary can only be \"true\" or \"false\".\n"); return; } PlotPSBoundary = i; break; case PSWIDTH: if (!StrIsInt(value) || (i <= 0)) { TxError("PS_Width must be an integer greater than zero.\n"); return; } else PlotPSWidth = i; break; case PSHEIGHT: if (!StrIsInt(value) || (i <= 0)) { TxError("PS_Height must be an integer greater than zero.\n"); return; } else PlotPSHeight = i; break; case PSMARGIN: if (!StrIsInt(value) || (i < 0)) { TxError("PS_Margin must be an integer greater than or equal to zero.\n"); return; } else PlotPSMargin = i; break; #ifdef VERSATEC case CELLIDFONT: StrDup(&PlotVersIdFont, value); break; case CELLNAMEFONT: StrDup(&PlotVersNameFont, value); break; case LABELFONT: StrDup(&PlotVersLabelFont, value); break; case DIRECTORY: StrDup(&PlotTempDirectory, value); break; case DOTSPERINCH: if (!StrIsInt(value) || (i <= 0)) { TxError("DotsPerInch must be an integer greater than zero.\n"); return; } else PlotVersDotsPerInch = i; break; case PRINTER: StrDup(&PlotVersPrinter, value); break; case PLOTTYPE: i = Lookup(value, plotTypeNames); if (i < 0) { int j; TxError("%s is not a supported plot type. Plot types are:\n"); for (j = 0 ; plotTypeNames[j] != NULL; j++) { TxError("\t%s\n", plotTypeNames[j]); } return; } PlotVersPlotType = i; switch(PlotVersPlotType) { case VERSATEC_COLOR: PlotVersDotsPerInch = 215; PlotVersWidth = 7904; break; case VERSATEC_BW: PlotVersDotsPerInch = 215; PlotVersWidth = 7904; break; case HPRTL: PlotVersDotsPerInch = 316; PlotVersWidth = 2400; break; case HPGL2: PlotVersDotsPerInch = 300; PlotVersWidth = 10650; break; } break; case SPOOLCOMMAND: StrDup(&PlotVersCommand, value); break; case SWATHHEIGHT: if (!StrIsInt(value) || (i <= 0)) { TxError("SwathHeight must be an integer greater than zero.\n"); return; } else PlotVersSwathHeight= i; break; case WIDTH: if (!StrIsInt(value) || (i <= 0)) { TxError("Width must be an integer greater than zero.\n"); return; } else PlotVersWidth = i; break; case PNMRTL: i = Lookup(value, tfNames); if (i < 0) { TxError("pnmplotRTL can only be \"true\" or \"false\".\n"); return; } PlotPNMRTL = i; break; #endif /* VERSATEC */ #ifdef LLNL case PIXWIDTH: if (!StrIsInt(value) || (i <= 0)) { TxError("PixWidth must be an integer greater than zero.\n"); return; } else PlotPixWidth = i; break; case PIXHEIGHT: if (!StrIsInt(value) || (i <= 0)) { TxError("PixHeight must be an integer greater than zero.\n"); return; } else PlotPixHeight = i; break; #endif /* LLNL */ case PNMMAXMEM: if (!StrIsInt(value) || (i <= 0)) { TxError("pnmmaxmem must be an integer greater than zero.\n"); return; } else PlotPNMmaxmem = i; break; case PNMDOWNSAMPLE: if (!StrIsInt(value) || (i < 0)) { TxError("pnmdownsample must be an integer zero or larger.\n"); return; } else PlotPNMdownsample = i; break; case PNMBACKGROUND: if (!StrIsInt(value) || (i < 0) || (i > 255)) { TxError("pnmbackground must be an integer 0-255.\n"); return; } else PlotPNMBG = (unsigned char)i; break; } } magic-8.0.210/plot/plotRutils.c0000644000175000001440000007337610751423606015001 0ustar timusers/* * plotRastUtils.c -- * * This file contains several procedures for manipulating rasters. * The procedures are used to create bitmaps to directly drive * printers such as the black-and-white Versatec. For example, * the procedures draw stippled areas and raster-ize text strings * using fonts. * * ********************************************************************* * * 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/plot/plotRutils.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include #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 "utils/malloc.h" #include "plot/plotInt.h" #include "textio/textio.h" #include "utils/utils.h" extern double sqrt(); int rasFileByteCount = 0; /* A solid black stipple: */ Stipple PlotBlackStipple = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, }; /* The following two arrays are used to select a range of bits within * a word. The first array selects all the bits at or to the left of * the given bit-position. "To the left" means in a lower-numbered * byte (according to byte order) or in a more significant bit of the * same byte. The second array selects the bits at or to the right of * the given bit-position. Bit position 0 is considered to be the * leftmost bit of the word; it's the highest-order bit in the 0th * byte. */ static unsigned int leftBits[32] = { 0x00000080, 0x000000c0, 0x000000e0, 0x000000f0, 0x000000f8, 0x000000fc, 0x000000fe, 0x000000ff, 0x000080ff, 0x0000c0ff, 0x0000e0ff, 0x0000f0ff, 0x0000f8ff, 0x0000fcff, 0x0000feff, 0x0000ffff, 0x0080ffff, 0x00c0ffff, 0x00e0ffff, 0x00f0ffff, 0x00f8ffff, 0x00fcffff, 0x00feffff, 0x00ffffff, 0x80ffffff, 0xc0ffffff, 0xe0ffffff, 0xf0ffffff, 0xf8ffffff, 0xfcffffff, 0xfeffffff, 0xffffffff }; static unsigned int rightBits[32] = { 0xffffffff, 0xffffff7f, 0xffffff3f, 0xffffff1f, 0xffffff0f, 0xffffff07, 0xffffff03, 0xffffff01, 0xffffff00, 0xffff7f00, 0xffff3f00, 0xffff1f00, 0xffff0f00, 0xffff0700, 0xffff0300, 0xffff0100, 0xffff0000, 0xff7f0000, 0xff3f0000, 0xff1f0000, 0xff0f0000, 0xff070000, 0xff030000, 0xff010000, 0xff000000, 0x7f000000, 0x3f000000, 0x1f000000, 0x0f000000, 0x07000000, 0x03000000, 0x01000000 }; /* The following arrray selects a single bit within a word. The * zeroth entry selects the bit that will be leftmost in the plot. */ static unsigned int singleBit[32] = { 0x00000080, 0x00000040, 0x00000020, 0x00000010, 0x00000008, 0x00000004, 0x00000002, 0x00000001, 0x00008000, 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, 0x00800000, 0x00400000, 0x00200000, 0x00100000, 0x00080000, 0x00040000, 0x00020000, 0x00010000, 0x80000000, 0x40000000, 0x20000000, 0x10000000, 0x08000000, 0x04000000, 0x02000000, 0x01000000 }; RasterFont *PlotFontList; /* Linked list of all fonts that have * been read in so far. */ /* * ---------------------------------------------------------------------------- * * PlotRastInit -- * * Initialize data structures related to rasters. * * Results: * None. * * Side effects: * All this procedure does is to swap bytes in the stipple * masks if we're running on a non-VAX. * * ---------------------------------------------------------------------------- */ void PlotRastInit() { #ifdef WORDS_BIGENDIAN int i; for (i = 0; i < 32; i++) { leftBits[i] = PlotSwapBytes(leftBits[i]); rightBits[i] = PlotSwapBytes(rightBits[i]); singleBit[i] = PlotSwapBytes(singleBit[i]); } #endif /* WORDS_BIGENDIAN */ } /* * ---------------------------------------------------------------------------- * * PlotNewRaster -- * * Allocate and initialize a new raster structure. * * Results: * The return value is a pointer to the new raster object. * * Side effects: * Memory is allocated. * * ---------------------------------------------------------------------------- */ Raster * PlotNewRaster(height, width) int height; /* Raster's height in pixels. Should generally * be a multiple of 16. */ int width; /* Raster's width in pixels. Should generally * be a multiple of 32 bits. */ { Raster *new; new = (Raster *) mallocMagic(sizeof(Raster)); new->ras_width = width; new->ras_intsPerLine = (width+31)/32; new->ras_bytesPerLine = new->ras_intsPerLine*4; new->ras_height = height; new->ras_bits = (int *) mallocMagic( (unsigned) (height * new->ras_intsPerLine * 4)); return new; } /* * ---------------------------------------------------------------------------- * * PlotFreeRaster -- * * Frees up the memory associated with an existing raster structure. * * Results: * None. * * Side effects: * The storage associated with raster is returned to the allocator. * * ---------------------------------------------------------------------------- */ void PlotFreeRaster(raster) Raster *raster; /* Raster whose memory is to be freed. Should * have been created with PlotNewRaster. */ { freeMagic((char *) raster->ras_bits); freeMagic((char *) raster); } /* * ---------------------------------------------------------------------------- * * PlotClearRaster -- * * This procedure clears out an area of the raster. * * Results: * None. * * Side effects: * The area of the raster indicated by "area" is set to all zeroes. * * ---------------------------------------------------------------------------- */ void PlotClearRaster(raster, area) Raster *raster; /* Raster that's to be cleared. */ Rect *area; /* Area to be cleared, in raster * coords. NULL means clear the * whole raster. */ { int *left, *right, *cur; int leftMask, rightMask, line; if (area == NULL) { bzero((char *) raster->ras_bits, raster->ras_bytesPerLine * raster->ras_height); return; } /* Compute the address of the leftmost word in the topmost line * to be cleared, and the rightmost word in the topmost line to * be cleared. */ left = raster->ras_bits + ((raster->ras_height-1) - area->r_ytop)*raster->ras_intsPerLine; right = left + area->r_xtop/32; left += area->r_xbot/32; /* Divide the x-span of the area into three parts: the leftmost * word, of which only the rightmost bits are cleared, the * rightmost word, of which only the leftmost bits are cleared, * and the middle section, in which all bits of each word are * cleared. Compute masks that determine which bits of the end * words will be cleared. There's a special case when the left * and right ends are in the same word. */ leftMask = rightBits[area->r_xbot&037]; rightMask = leftBits[area->r_xtop&037]; if (left == right) leftMask &= rightMask; /* Clear the area one raster line at a time, top to bottom. */ for (line = area->r_ytop; line >= area->r_ybot; line -= 1) { /* Clear the leftmost word on this line. */ *left &= ~leftMask; if (left != right) { /* Clear the center of the line. */ for (cur = left+1; cur < right; cur += 1) *cur = 0; /* Clear the rightmost word on this line. */ *cur &= ~rightMask; } left += raster->ras_intsPerLine; right += raster->ras_intsPerLine; } } /* * ---------------------------------------------------------------------------- * * PlotPolyRaster -- * * Fill a polygonal raster area, given the area of a triangular * tile (in pixel coordinates), information about what side and * direction are filled, and the area to clip to (also in raster * coordinates). This is *not* a general-purpose polygon-filling * routine. It can only handle clipped right triangles. * * Results: * None. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ void PlotPolyRaster(raster, tileArea, clipArea, dinfo, stipple) Raster *raster; /* Pointer to raster whose bits are * to be filled in. */ Rect *tileArea; /* Area of split tile, in pixel coordinates */ Rect *clipArea; /* Area to clip, in pixel coordinates */ TileType dinfo; /* Split tile side and direction information */ Stipple stipple; /* Stipple pattern to be used to fill * in the raster area. */ { int *cur, *rasleft, *tbase, *right, *left; int leftMask, rightMask, curStipple; int line, width, height, locleft, locright; Rect area; /* Compute the address of the leftmost word in the topmost line * to be filled, and the rightmost word in the topmost line to * be filled. */ area = *tileArea; GEOCLIP(&area, clipArea); /* Ensure that we have not been clipped out of existence */ if (area.r_xbot > area.r_xtop) return; if (area.r_ybot >= area.r_ytop) return; rasleft = raster->ras_bits + ((raster->ras_height-1) - area.r_ytop)*raster->ras_intsPerLine; width = tileArea->r_xtop - tileArea->r_xbot; height = tileArea->r_ytop - tileArea->r_ybot; /* Process the stippled area one raster line at a time, top to bottom. */ if (dinfo & TT_SIDE) { locright = area.r_xtop; tbase = rasleft + area.r_xtop / 32; /* base is on right */ } else { locleft = area.r_xbot; tbase = rasleft + area.r_xbot / 32; /* base is on left */ } for (line = area.r_ytop; line >= area.r_ybot; line -= 1) { if (dinfo & TT_SIDE) { if (dinfo & TT_DIRECTION) locleft = tileArea->r_xbot + (((tileArea->r_ytop - line) * width) / height); else locleft = tileArea->r_xbot + (((line - tileArea->r_ybot) * width) / height); right = tbase; left = rasleft + locleft / 32; } else { if (dinfo & TT_DIRECTION) locright = tileArea->r_xbot + (((tileArea->r_ytop - line) * width) / height); else locright = tileArea->r_xbot + (((line - tileArea->r_ybot) * width) / height); right = rasleft + locright / 32; left = tbase; } if (left > right) continue; leftMask = rightBits[locleft & 037]; rightMask = leftBits[locright & 037]; if (left == right) leftMask &= rightMask; curStipple = stipple[(-line)&017]; /* Fill the leftmost word on this line. */ *left |= curStipple & leftMask; if (left != right) { /* Fill the center of the line. */ for (cur = left+1; cur < right; cur += 1) *cur |= curStipple; /* Fill the rightmost word on this line. */ *cur |= curStipple & rightMask; } rasleft += raster->ras_intsPerLine; tbase += raster->ras_intsPerLine; } } /* * ---------------------------------------------------------------------------- * * PlotFillRaster -- * * Given a raster and an area, this procedure fills the given area * of the raster with a particular stipple pattern. * * Results: * None. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ void PlotFillRaster(raster, area, stipple) Raster *raster; /* Pointer to raster whose bits are * to be filled in. */ Rect *area; /* Area to be filled in pixel coords. * This is an inclusive area: it * includes the boundary pixels. The * caller must ensure that it is * clipped to the raster area. */ Stipple stipple; /* Stipple pattern to be used to fill * in the raster area. */ { int *left, *cur, line; int *right; int leftMask, rightMask, curStipple; /* Compute the address of the leftmost word in the topmost line * to be filled, and the rightmost word in the topmost line to * be filled. */ left = raster->ras_bits + ((raster->ras_height-1) - area->r_ytop)*raster->ras_intsPerLine; right = left + area->r_xtop/32; left += area->r_xbot/32; /* Divide the x-span of the area into three parts: the leftmost * word, of which only the rightmost bits are modified, the * rightmost word, of which only the leftmost bits are modified, * and the middle section, in which all bits of each word are * modified. Compute masks that determine which bits of the end * words will be modified. There's a special case when the left * and right ends are in the same word. */ leftMask = rightBits[area->r_xbot&037]; rightMask = leftBits[area->r_xtop&037]; if (left == right) leftMask &= rightMask; /* Process the stippled area one raster line at a time, top to bottom. */ for (line = area->r_ytop; line >= area->r_ybot; line -= 1) { curStipple = stipple[(-line)&017]; /* Fill the leftmost word on this line. */ *left |= curStipple & leftMask; if (left != right) { /* Fill the center of the line. */ for (cur = left+1; cur < right; cur += 1) *cur |= curStipple; /* Fill the rightmost word on this line. */ *cur |= curStipple & rightMask; } left += raster->ras_intsPerLine; right += raster->ras_intsPerLine; } } /* * ---------------------------------------------------------------------------- * * PlotDumpRaster -- * * Writes out the contents of the given raster to the given file, * in binary format. * * Results: * Returns 0 if all was well. Returns non-zero if there was * an I/O error. In this event, this procedure prints an * error message before returning. * * Side effects: * Information is added to file. * * ---------------------------------------------------------------------------- */ int PlotDumpRaster(raster, file) Raster *raster; /* Raster to be dumped. */ FILE *file; /* File in which to dump it. */ { int count; count = write(fileno(file), (char *) raster->ras_bits, raster->ras_bytesPerLine*raster->ras_height); if (count < 0) { TxError("I/O error in writing raster file: %s.\n", strerror(errno)); return 1; } rasFileByteCount += count; return 0; } /* * ---------------------------------------------------------------------------- * * PlotLoadFont -- * * Loads a font into memory, if it isn't already there. * ** Patched to accomodate both VAX format and Sun format vfont(5) files, ** regardless of the native byte order of the processor. J. Gealow 3/30/94 * * Results: * The return value is a pointer to the font. This must be used * when calling procedures like PlotTextSize. If the font file * couldn't be found, an error message is output and NULL is * returned. * * Side effects: * New memory gets allocated. * * ---------------------------------------------------------------------------- */ RasterFont * PlotLoadFont(name) char *name; /* Name of font file. */ { FILE *f; RasterFont *new; struct dispatch *d; /* See if we've already got the font. */ for (new = PlotFontList; new != NULL; new = new->fo_next) { if (strcmp(new->fo_name, name) == 0) return new; } f = PaOpen(name, "r", (char *) NULL, ".", SysLibPath, (char **) NULL); if (f == NULL) { TxError("Couldn't read font file \"%s\".\n", name); return NULL; } new = (RasterFont *) mallocMagic(sizeof(RasterFont)); new->fo_name = NULL; StrDup(&new->fo_name, name); /* Read in the font's header and check the magic number. */ if (read(fileno(f), (char *) &new->fo_hdr, sizeof(new->fo_hdr)) != sizeof(new->fo_hdr)) { fontError: TxError("Error in reading font file \"%s\".\n", name); fclose(f); return NULL; } if (PlotSwapShort(new->fo_hdr.magic) == 0436) { new->fo_hdr.size = (PlotSwapShort(new->fo_hdr.size)); new->fo_hdr.maxx = (PlotSwapShort(new->fo_hdr.maxx)); new->fo_hdr.maxy = (PlotSwapShort(new->fo_hdr.maxy)); new->fo_hdr.xtend = (PlotSwapShort(new->fo_hdr.xtend)); } else if (new->fo_hdr.magic != 0436) { TxError("Bad magic number in font file \"%s\".\n", name); fclose(f); return NULL; } /* Read the character descriptors and the bit map. */ if (read(fileno(f), (char *) new->fo_chars, sizeof(new->fo_chars)) != sizeof(new->fo_chars)) goto fontError; new->fo_bits = mallocMagic(new->fo_hdr.size); if (read(fileno(f), new->fo_bits, (unsigned) new->fo_hdr.size) != new->fo_hdr.size) goto fontError; fclose(f); /* Compute the bounding box of all characters in the font. */ new->fo_bbox.r_xbot = new->fo_bbox.r_xtop = 0; new->fo_bbox.r_ybot = new->fo_bbox.r_ytop = 0; for (d = &new->fo_chars[0]; d < &new->fo_chars[256]; d++) { if (PlotSwapShort(new->fo_hdr.magic) == 0436) { d->addr = PlotSwapShort(d->addr); d->nbytes = PlotSwapShort(d->nbytes); d->width = PlotSwapShort(d->width); } if (d->nbytes == 0) continue; if (d->up > new->fo_bbox.r_ytop) new->fo_bbox.r_ytop = d->up; if (d->down > new->fo_bbox.r_ybot) new->fo_bbox.r_ybot = d->down; if (d->right > new->fo_bbox.r_xtop) new->fo_bbox.r_xtop = d->right; if (d->left > new->fo_bbox.r_xbot) new->fo_bbox.r_xbot = d->left; #ifdef DEBUG_FONT if (d == &new->fo_chars['d']) { char *fontcp; int count; TxError("Character 'd' in font '%s' is at addr 0x%x, bytes %d, width %d\n", new->fo_name, d->addr, d->nbytes, d->width); count = 0; for (fontcp = new->fo_bits + d->addr; fontcp < new->fo_bits + d->addr + d->nbytes; fontcp++) { int i; char ch; ch = *fontcp; for (i = 0; i < 8; i++) { TxError("%c", ((ch & 0x80) ? 'X' : '.')); ch = (ch << 1); } count++; if (count >= (d->left + d->right + 7) >> 3) { TxError("\n"); count = 0; } } TxError("\n"); } #endif /* DEBUG_FONT */ } new->fo_bbox.r_xbot = - new->fo_bbox.r_xbot; new->fo_bbox.r_ybot = - new->fo_bbox.r_ybot; new->fo_next = PlotFontList; PlotFontList = new; return new; } /* * ---------------------------------------------------------------------------- * * PlotTextSize -- * * Compute the area that a string will occupy. * * Results: * None. * * Side effects: * The rectangle "area" is filled in with the bounding * box of the bits in "string", assuming that the origin * for the text is (0,0) and the text is rendered in font * "font". * * ---------------------------------------------------------------------------- */ void PlotTextSize(font, string, area) RasterFont *font; /* Font to use in computing text size. */ char *string; /* String to compute size of. */ Rect *area; /* Place to store bounding box. */ { int x; struct dispatch *d; area->r_xbot = area->r_xtop = 0; area->r_ybot = area->r_ytop = 0; x = 0; for ( ; *string != 0; string ++) { if ((*string == ' ') || (*string == '\t')) d = &font->fo_chars['t']; else d = &font->fo_chars[*string]; if (d->nbytes == 0) continue; if (d->up > area->r_ytop) area->r_ytop = d->up; if (d->down > area->r_ybot) area->r_ybot = d->down; if ((x+d->right) > area->r_xtop) area->r_xtop = x + d->right; if ((x-d->left) < area->r_ybot) area->r_ybot = x - d->left; x += d->width; } area->r_ybot = -area->r_ybot; } /* * ---------------------------------------------------------------------------- * * PlotRasterText -- * * Given a text string and a font, this procedure scan-converts * the string and sets bits in the current raster that correspond * to on-bits in the text. * * Results: * None. * * Side effects: * Bits are modified in the raster. * * ---------------------------------------------------------------------------- */ void PlotRasterText(raster, clip, font, string, point) Raster *raster; /* Raster whose bits are to be filled in. */ Rect *clip; /* Area to which to clip the text. Must be * entirely within the area of the raster. */ RasterFont *font; /* Font to use for rasterizing string. Must * have been obtained by calling PlotLoadFont. */ char *string; /* String of text to rasterize. */ Point *point; /* X-Y coordinates of origin of text. The * origin need not be inside the area of * the raster, but only raster points inside * the area will be modified. */ { int xOrig; /* X-origin for current character. */ /* Outer loop: process each character. */ xOrig = point->p_x; for ( ; *string != 0; string++) { int cBytesPerLine, i; struct dispatch *d; /* Descriptor for current character. */ /* Handle spaces and tabs specially by just spacing over. */ if ((*string == ' ') || (*string == '\t')) { xOrig += font->fo_chars['t'].width; continue; } /* Middle loop: render each character one raster line at a * time, from top to bottom. Skip rows that are outside the * area of the raster. */ d = &font->fo_chars[*string]; cBytesPerLine = (d->left + d->right + 7) >> 3; for (i = 0; i < d->up + d->down; i++) { int y, j; char *charBitPtr; y = point->p_y + d->up - 1 - i; if (y < clip->r_ybot) break; if (y > clip->r_ytop) continue; /* Inner loop: process a series of bytes in a row to * render one raster line of one character. Be sure * to skip areas that fall outside the raster to the * left or right. */ for (j = -d->left, charBitPtr = font->fo_bits + d->addr + i*cBytesPerLine; j < d->right; j += 8, charBitPtr++) { char *rPtr; int charBits, x; x = xOrig + j; if (x > clip->r_xtop) break; if (x < clip->r_xbot - 7) continue; rPtr = (char *) raster->ras_bits; rPtr += (raster->ras_height - 1 - y)*raster->ras_bytesPerLine + (x>>3); charBits = *charBitPtr & 0xff; /* One byte of the character's bit map may span two * bytes of the raster, so process each of the two * raster bytes separately. Either of the two bytes * may be off the edge of the raster, in which case * it must be skipped. */ if (x >= 0) *rPtr |= charBits >> (x & 0x7); rPtr += 1; if (x+8 <= clip->r_xtop) { charBits = charBits << (8 - (x & 0x7)); *rPtr |= charBits; } } } xOrig += d->width; } } /* * ---------------------------------------------------------------------------- * * PlotRastPoint -- * * Sets a particular pixel of a raster. * * Results: * None. * * Side effects: * If x and y lie inside the raster then the pixel that they select * is set to 1. If x or y is outside the raster area then nothing * happens. * * ---------------------------------------------------------------------------- */ void PlotRastPoint(raster, x, y) Raster *raster; /* Raster containing pixel to be * filled. */ int x, y; /* Coordinates of pixel. */ { if ((x < 0) || (x >= raster->ras_width)) return; y = (raster->ras_height - 1) - y; if ((y < 0) || (y >= raster->ras_height)) return; raster->ras_bits[((y*raster->ras_intsPerLine) + (x>>5))] |= singleBit[x&037]; } /* * ---------------------------------------------------------------------------- * * PlotRastLine -- * * Draws a one-pixel-wide line between two points. * * Results: * None. * * Side effects: * A line is drawn between pixels src and dst. Only the portion * of the line that lies inside the raster is drawn; the endpoints * may lie outside the raster (this feature is necessary to draw * straight lines that cross multiple swaths). * * ---------------------------------------------------------------------------- */ void PlotRastLine(raster, src, dst) Raster *raster; /* Where to render the line. */ Point *src; /* One endpoint of line, in raster coords. */ Point *dst; /* The other endpoint, in raster coords. */ { int x, y, dx, dy, xinc, incr1, incr2, d, done; /* Compute the total x- and y-motions, and arrange for the line to be * drawn in increasing order of y-coordinate. */ dx = dst->p_x - src->p_x; dy = dst->p_y - src->p_y; if (dy < 0) { dy = -dy; dx = -dx; x = dst->p_x; y = dst->p_y; dst = src; } else { x = src->p_x; y = src->p_y; } /* The code below is just the Bresenham algorithm from Foley and * Van Dam (pp. 435), modified slightly so that it can work in * all directions. */ if (dx < 0) { xinc = -1; dx = -dx; } else xinc = 1; if (dx >= dy) { d = 2*dy - dx; incr1 = 2*dy; incr2 = 2*(dy - dx); done = dst->p_x; for ( ; x != done ; x += xinc) { PlotRastPoint(raster, x, y); if (d < 0) d += incr1; else { d += incr2; y += 1; } } } else { d = 2*dx - dy; incr1 = 2*dx; incr2 = 2*(dx - dy); done = dst->p_y; for ( ; y != done ; y += 1) { PlotRastPoint(raster, x, y); if (d < 0) d += incr1; else { d += incr2; x += xinc; } } } PlotRastPoint(raster, x, y); } /* * ---------------------------------------------------------------------------- * * PlotRastFatLine -- * * Draws a line many pixels wide between two points. * * Results: * None. * * Side effects: * A line is drawn between pixels src and dst. Only the portion * of the line that lies inside the raster is drawn; the endpoints * may lie outside the raster (this feature is necessary to draw * straight lines that cross multiple swaths). The line is drawn * several pixels wide, as determined by the "widen" parameter. * The ends of the line are square, not rounded, which may cause * upleasant effects for some uses. If the line is Manhattan, * this procedure is very inefficient: it's better to use the * PlotFillRaster procedure. * * ---------------------------------------------------------------------------- */ void PlotRastFatLine(raster, src, dst, widen) Raster *raster; /* Where to render the line. */ Point *src; /* One endpoint of line, in raster coords. */ Point *dst; /* The other endpoint, in raster coords. */ int widen; /* How much to widen the line. 0 means the * line is one pixel wide, 1 means it's 3 * pixels wide, and so on. */ { double dx, dy, x, y; int nLines; /* Just draw (2*widen) + 1 lines spaced about one pixel apart. * The first lines here compute how far apart to space the lines. */ nLines = (2*widen) + 1; x = dst->p_x - src->p_x; y = dst->p_y - src->p_y; dy = sqrt(x*x + y*y); dx = y/dy; dy = -x/dy; x = -dy*(widen); y = dx*(widen); for (x = -dx*widen, y = -dy*widen; nLines > 0; nLines -= 1, x += dx, y += dy) { Point newSrc, newDst; if (x > 0) newSrc.p_x = (x + .5); else newSrc.p_x = (x - .5); if (y > 0) newSrc.p_y = (y + .5); else newSrc.p_y = (y - .5); newDst.p_x = dst->p_x + newSrc.p_x; newDst.p_y = dst->p_y + newSrc.p_y; newSrc.p_x += src->p_x; newSrc.p_y += src->p_y; PlotRastLine(raster, &newSrc, &newDst); } } /* * ---------------------------------------------------------------------------- * * PlotSwapBytes -- * PlotSwapShort -- * * These two procedures do byte swapping in the way that's * required when moving binary files between VAXes and Suns. * * Results: * Each procedure returns a value in which the order of bytes * has been reversed. PlotSwapBytes takes an integer and returns * an integer with the four bytes in reverse order; PlotSwapShort * takes a short and swaps the two bytes. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ int PlotSwapBytes(value) int value; /* 4-byte Value whose bytes are to * be reversed. */ { int result; #define src ((char *) &value) #define dst ((char *) &result) dst[0] = src[3]; dst[1] = src[2]; dst[2] = src[1]; dst[3] = src[0]; return result; } short PlotSwapShort(value) short value; /* Value whose bytes are to be swapped. */ { short result; #define src ((char *) &value) #define dst ((char *) &result) dst[0] = src[1]; dst[1] = src[0]; return result; } /* * ---------------------------------------------------------------------------- * * PlotDumpColorPreamble -- * * Dump a color preamble in vdmpc format for the color Versatec. See * the vdmpc(5) man page for details on the format. * * Format: * preamble is a 1K block * first word is 0xA5CF4DFB (a magic number) * second word gives the number of scan lines * third word gives width of the plot in pixels (must be multiple of 8) * rest of the words are zero * * ---------------------------------------------------------------------------- */ #define VERSATEC_BLOCK 1024 #define VERSATEC_MAGIC_WORD 0xA5CF4DFB unsigned int VersHeader[VERSATEC_BLOCK/sizeof(unsigned int)] = {VERSATEC_MAGIC_WORD}; int PlotDumpColorPreamble(color, file, lines, columns) VersatecColor color; /* The color that the following raster will * be printed in. */ FILE *file; /* file in which to place header */ int lines; /* number of scan lines */ int columns; /* Width in pixels. */ { int count; if (color == BLACK) { VersHeader[1] = lines; VersHeader[2] = columns; count = write(fileno(file), &VersHeader[0], sizeof(VersHeader)); TxPrintf("Wrote %d bytes of control.\n", count); } return 0; } magic-8.0.210/plot/plotPixels.c0000644000175000001440000012166211020566171014746 0ustar timusers/* * plotPixels.c -- * * This file contains the procedures that generate pix files. each file is * a sequence of unsigned chars, each triplet of chars representing a red, * green and blue value between 0 and 255 for a pixel. Pixels go across left * to right, and down the image. * * ********************************************************************* * * 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/plot/plotPixels.c,v 1.2 2008/06/01 18:37:45 tim Exp $"; #endif /* not lint */ #include #include #include #include #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 "dbwind/dbwtech.h" #include "utils/malloc.h" #include "plot/plotInt.h" #include "windows/windows.h" #include "commands/commands.h" #include "textio/textio.h" #include "utils/utils.h" #include "utils/tech.h" #include "utils/signals.h" #include "utils/styles.h" #include "graphics/graphics.h" #include "dbwind/dbwind.h" #ifdef LLNL /* forward declarations */ void PlotPixFatLine(); /* * ---------------------------------------------------------------------------- * The parameters below control various aspects of the plotting * process. The initial values are defaults for the pixels * printer. However, many of them can be modified by users * with the "plot option" command. * ---------------------------------------------------------------------------- */ int PlotPixWidth = 512; /* Number of dots across image. */ int PlotPixHeight = 512; /* Height of swath to generate at one time, * in dots. */ /* Directory in which to create temporary file to hold raster: */ static char *defaultDirectory = "/usr/tmp"; extern char *PlotTempDirectory; /* * ---------------------------------------------------------------------------- * The variables below are shared between the top-level pixels * plotting procedure and the lower-level search functions. They * contain specific information about how to generate the current * plot. There area three coordinate systems of interest here: * * 1. Magic root coordinates. * 2. Raster coordinates: based on printer pixels, one unit per pixel, * where (0,0) corresponds to the lower-leftmost dot that will be * printed. * 3. Swath coordinates: the raster will be much too large to keep in * memory all at once, so it's generated in a series of horizontal * swaths. The stippling routines all work in swath-relative * coordinates, which are the same as raster coordinates except for * a y-displacement (swathY below). * ---------------------------------------------------------------------------- */ static PixRaster *pixRasterSwath = NULL; /* Raster used to hold current swath. */ extern Point plotLL; /* Point in root Magic coords that corresponds * to (0,0) in raster coordinates. */ extern int swathY; /* The y-coordinate in raster coordinates that * corresponds to (0,0) in swath coords. It's * always >= 0. */ int scale; /* How many (2**scaleShift)-ths of a pixel * correspond to one Magic unit. */ extern int scaleShift; /* The idea is that one Magic unit is equal * to scale/(2**scaleShift) pixels. */ static Rect rootClip; /* Total root area of the plot. Used for * clipping. */ static Rect swathClip; /* Rectangle used for clipping to the area of * the current swath. This is in swath * coordinates. */ static int curStyle; /* Current style being processed. */ static TileTypeBitMask *curMask; /* Mask of layers currently being stippled. * This is the AND of the mask from curStyle * and the layers that the user wants plotted. */ static int crossSize; /* Length of each arm of the crosses used * to draw labels, in pixel units. */ static RasterFont *labelPixFont; /* Font to use when rendering labels. */ static RasterFont *cellNamePixFont; /* Font to use when rendering cell names. */ static RasterFont *cellIdPixFont; /* Font to use when rendering cell ids. */ #endif /* LLNL */ /* * ---------------------------------------------------------------------------- * PlotPixTechInit -- * * Called once at beginning of technology file read-in to initialize * data structures. * * Results: * None. * * Side effects: * Clears out the list of things to plot. * ---------------------------------------------------------------------------- */ void PlotPixTechInit() { /* most intersting stuff is done by PlotVersTechInit -- setting default * plot directory, default font names, etc. */ } /* * ---------------------------------------------------------------------------- * PlotPixTechLine -- * * This procedure is invoked by the technology module once for * each line in the "pixels" subsection of the "plot" 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 table of pixels styles. * ---------------------------------------------------------------------------- */ /* ARGSUSED */ bool PlotPixTechLine(sectionName, argc, argv) char *sectionName; /* Name of this section (unused). */ int argc; /* Number of arguments on line. */ char *argv[]; /* Pointers to fields of line. */ { return TRUE; } #ifdef LLNL /* * ---------------------------------------------------------------------------- * * PlotPixPoint -- * * Sets a particular pixel of a PixRaster. * * Results: * None. * * Side effects: * If x and y lie inside the raster then the pixel that they select * is set to 1. If x or y is outside the raster area then nothing * happens. * * ---------------------------------------------------------------------------- */ void PlotPixPoint(raster, x, y, style) PixRaster *raster; /* Raster containing pixel to be * filled. */ int x, y; /* Coordinates of pixel. */ int style; /* style to render the pixel with. */ { char *rp; /* ptr to pixel to change. */ if ((x < 0) || (x >= raster->pix_width)) return; y = (raster->pix_height - 1) - y; if ((y < 0) || (y >= raster->pix_height)) return; rp = raster->pix_pixels + x + y*raster->pix_width; *rp = (*rp & ~(GrStyleTable[style].mask)) | (GrStyleTable[style].color & GrStyleTable[style].mask); } /* * ---------------------------------------------------------------------------- * * PlotPixArbLine -- * * Draws a one-pixel-wide line between two points. * * Results: * None. * * Side effects: * A line is drawn between pixels src and dst. Only the portion * of the line that lies inside the raster is drawn; the endpoints * may lie outside the raster (this feature is necessary to draw * straight lines that cross multiple swaths). * * ---------------------------------------------------------------------------- */ void PlotPixArbLine(raster, src, dst, style) Raster *raster; /* Where to render the line. */ Point *src; /* One endpoint of line, in raster coords. */ Point *dst; /* The other endpoint, in raster coords. */ int style; /* Display style to render this line in */ { int x, y, dx, dy, xinc, incr1, incr2, d, done; /* Compute the total x- and y-motions, and arrange for the line to be * drawn in increasing order of y-coordinate. */ dx = dst->p_x - src->p_x; dy = dst->p_y - src->p_y; if (dy < 0) { dy = -dy; dx = -dx; x = dst->p_x; y = dst->p_y; dst = src; } else { x = src->p_x; y = src->p_y; } /* The code below is just the Bresenham algorithm from Foley and * Van Dam (pp. 435), modified slightly so that it can work in * all directions. */ if (dx < 0) { xinc = -1; dx = -dx; } else xinc = 1; if (dx >= dy) { d = 2*dy - dx; incr1 = 2*dy; incr2 = 2*(dy - dx); done = dst->p_x; for ( ; x != done ; x += xinc) { PlotPixPoint(raster, x, y, style); if (d < 0) d += incr1; else { d += incr2; y += 1; } } } else { d = 2*dx - dy; incr1 = 2*dx; incr2 = 2*(dx - dy); done = dst->p_y; for ( ; y != done ; y += 1) { PlotPixPoint(raster, x, y, style); if (d < 0) d += incr1; else { d += incr2; x += xinc; } } } PlotPixPoint(raster, x, y, style); } /* * ---------------------------------------------------------------------------- * * plotPixLine -- * * This procedure plots a line of a given thickness. * * Results: * None. * * Side effects: * The current raster is modified. * * ---------------------------------------------------------------------------- */ void plotPixLine(area, widen, style) Rect *area; /* The "corner" points of this rectangle * give the endpoints of the line, in * Magic root coordinates. */ int widen; /* Amount by which to widen line. 0 means * line is drawn one pixel wide, 1 means 3 * pixels wide, etc. */ int style; /* style in which to render the line */ { Rect swathArea; plotTransToSwath(area, &swathArea); /* Handle Manhattan lines using rectangle-drawing, since it's faster. */ if ((swathArea.r_xbot == swathArea.r_xtop) || (swathArea.r_ybot == swathArea.r_ytop)) { GEO_EXPAND(&swathArea, widen, &swathArea); GEOCLIP(&swathArea, &swathClip); if ((swathArea.r_xbot <= swathArea.r_xtop) && (swathArea.r_ybot <= swathArea.r_ytop)) plotFillPixRaster(pixRasterSwath, &swathArea,style, GR_STSOLID); } else PlotPixFatLine(pixRasterSwath, &swathArea.r_ll, &swathArea.r_ur, widen, curStyle); } /* * ---------------------------------------------------------------------------- * * PlotPixFatLine -- * * Draws a line many pixels wide between two points. * * Results: * None. * * Side effects: * A line is drawn between pixels src and dst. Only the portion * of the line that lies inside the raster is drawn; the endpoints * may lie outside the raster (this feature is necessary to draw * straight lines that cross multiple swaths). The line is drawn * several pixels wide, as determined by the "widen" parameter. * The ends of the line are square, not rounded, which may cause * upleasant effects for some uses. If the line is Manhattan, * this procedure is very inefficient: it's better to use the * PlotFillPixRaster procedure. * * ---------------------------------------------------------------------------- */ void PlotPixFatLine(raster, src, dst, widen, style) PixRaster *raster; /* Where to render the line. */ Point *src; /* One endpoint of line, in raster coords. */ Point *dst; /* The other endpoint, in raster coords. */ int widen; /* How much to widen the line. 0 means the * line is one pixel wide, 1 means it's 3 * pixels wide, and so on. */ int style; { double dx, dy, x, y; int nLines; /* Just draw (2*widen) + 1 lines spaced about one pixel apart. * The first lines here compute how far apart to space the lines. */ nLines = (2*widen) + 1; x = dst->p_x - src->p_x; y = dst->p_y - src->p_y; dy = sqrt(x*x + y*y); dx = y/dy; dy = -x/dy; x = -dy*(widen); y = dx*(widen); for (x = -dx*widen, y = -dy*widen; nLines > 0; nLines -= 1, x += dx, y += dy) { Point newSrc, newDst; if (x > 0) newSrc.p_x = (x + .5); else newSrc.p_x = (x - .5); if (y > 0) newSrc.p_y = (y + .5); else newSrc.p_y = (y - .5); newDst.p_x = dst->p_x + newSrc.p_x; newDst.p_y = dst->p_y + newSrc.p_y; newSrc.p_x += src->p_x; newSrc.p_y += src->p_y; PlotPixArbLine(raster, &newSrc, &newDst, style); } } /* * ---------------------------------------------------------------------------- * * plotPixRect -- * * This procedure takes a rectangular area, given in Magic root * coordinates, and draws it as an outline of a given thickness. * * Results: * None. * * Side effects: * Modifies raster. * * ---------------------------------------------------------------------------- */ void plotPixRect(area, widen, style) Rect *area; /* Rectangular area to draw, in root * coordinates. */ int widen; /* If zero, rectangular outline is drawn * one pixel wide. If non-zero, the outline * is widened by this many units on each * side. */ int style; /* style in which to render the rect */ { Rect side; /* First, the bottom side. */ if (area->r_xbot != area->r_xtop) { side = *area; side.r_ytop = side.r_ybot; plotPixLine(&side, widen,style); /* Now the top side, if it doesn't coincide with the bottom. */ if (area->r_ybot != area->r_ytop) { side = *area; side.r_ybot = side.r_ytop; plotPixLine(&side, widen, style); } } /* Now do the left side. */ if (area->r_ybot != area->r_ytop) { side = *area; side.r_xtop = side.r_xbot; plotPixLine(&side, widen, style); /* Now the right side, if it doesn't coincide with the left. */ if (area->r_xbot != area->r_xtop) { side = *area; side.r_xbot = side.r_xtop; plotPixLine(&side, widen, style); } } } /* * ---------------------------------------------------------------------------- * * plotPixTile -- * * This procedure is called for paint tiles. It renders each tile * in the current style, in the current swath. * * Results: * Always returns 0 to keep the search alive. * * Side effects: * Modifies the raster area. * * ---------------------------------------------------------------------------- */ int plotPixTile(tile, cxp) Tile *tile; /* Tile that's of type to be output. */ TreeContext *cxp; /* Describes search in progress. */ { Rect tileArea, rootArea, swathArea; Transform *trans = &cxp->tc_scx->scx_trans; /* Transform tile coords to root coords and then to swath coords. */ TITORECT(tile, &tileArea); #ifdef DEBUG TxPrintf("PlotPixTile: (%d,%d)(%d,%d) ", tileArea.r_xbot, tileArea.r_ybot, tileArea.r_xtop, tileArea.r_ytop); #endif GEOTRANSRECT(trans, &tileArea, &rootArea); plotTransToSwath(&rootArea, &swathArea); /* Clip and then fill with the color. */ GEOCLIP(&swathArea, &swathClip); if (swathArea.r_xbot > swathArea.r_xtop) return 0; if (swathArea.r_ybot > swathArea.r_ytop) return 0; #ifdef DEBUG TxPrintf(">> (%d,%d)(%d,%d)\n", swathArea.r_xbot, swathArea.r_ybot, swathArea.r_xtop, swathArea.r_ytop); #endif /* if the current style's fill-mode is GR_STOUTLINE or GR_STCROSS * we cannot let plotFillPixRaster render the tile, since we get * extra horizontal lines at swath boundaries. Too bad, it was a * neat idea, but we cannot force the user to render the entire * image at once (*sigh*) */ if((GrStyleTable[curStyle].fill == GR_STOUTLINE) || (GrStyleTable[curStyle].fill == GR_STCROSS)) { /* draw the outline */ plotPixRect(&tileArea, 1, curStyle); } if (GrStyleTable[curStyle].fill == GR_STCROSS) { /* draw the cross */ Point src, dst; src = swathArea.r_ll; dst = swathArea.r_ur; PlotPixFatLine(pixRasterSwath, &src, &dst, 1, curStyle); src.p_y = swathArea.r_ytop; dst.p_y = swathArea.r_ybot; PlotPixFatLine(pixRasterSwath, &src, &dst, 1, curStyle); } plotFillPixRaster(pixRasterSwath, &swathArea, curStyle, -1); return 0; } /* * ---------------------------------------------------------------------------- * * plotPixLabel -- * * This procedure is invoked for labels. It generates bits to * display the label in the current raster swath. * * Results: * Always returns 0 to keep the search from aborting. * * Side effects: * Modifies the raster. * * ---------------------------------------------------------------------------- */ int plotPixLabel(scx, label) SearchContext *scx; /* Describes state of search when label * was found. */ Label *label; /* Label that was found. */ { Rect rootArea, swathArea, labelSize; Point point; int pos; /* Translate the label's area and relative position to root * coordinates and then to swath coordinates. Figure out * the point relative to which the label is to be positioned. */ GeoTransRect(&scx->scx_trans, &label->lab_rect, &rootArea); plotTransToSwath(&rootArea, &swathArea); pos = GeoTransPos(&scx->scx_trans, label->lab_just); PlotTextSize(labelPixFont, label->lab_text, &labelSize); switch (pos) { case GEO_NORTH: case GEO_NORTHEAST: case GEO_NORTHWEST: point.p_y = swathArea.r_ytop + crossSize + 2 - labelSize.r_ybot; break; case GEO_CENTER: case GEO_WEST: case GEO_EAST: point.p_y = (swathArea.r_ytop + swathArea.r_ybot)/2; point.p_y -= (labelSize.r_ytop + labelSize.r_ybot)/2; break; case GEO_SOUTH: case GEO_SOUTHEAST: case GEO_SOUTHWEST: point.p_y = swathArea.r_ybot - crossSize - 2 - labelSize.r_ytop; break; } switch (pos) { case GEO_WEST: case GEO_NORTHWEST: case GEO_SOUTHWEST: point.p_x = swathArea.r_xbot - crossSize - 2 - labelSize.r_xtop; break; case GEO_CENTER: case GEO_NORTH: case GEO_SOUTH: point.p_x = (swathArea.r_xtop + swathArea.r_xbot)/2; point.p_x -= (labelSize.r_xtop + labelSize.r_xbot)/2; break; case GEO_EAST: case GEO_NORTHEAST: case GEO_SOUTHEAST: point.p_x = swathArea.r_xtop + crossSize + 2 - labelSize.r_xbot; break; } /* Output lines marking the label's area. Different things are * done depending on whether the label is a point, a line, or an * area. */ if ((rootArea.r_xbot == rootArea.r_xtop) && (rootArea.r_ybot == rootArea.r_ytop)) { Rect tmp; /* Point label. Output a cross. */ tmp = swathArea; tmp.r_ytop += crossSize; tmp.r_ybot -= crossSize; GEO_EXPAND(&tmp, 1, &tmp); GEOCLIP(&tmp, &swathClip); if ((tmp.r_xbot <= tmp.r_xtop) && (tmp.r_ybot <= tmp.r_ytop)) plotFillPixRaster(pixRasterSwath, &tmp, STYLE_LABEL, GR_STSOLID); tmp = swathArea; tmp.r_xtop += crossSize; tmp.r_xbot -= crossSize; GEO_EXPAND(&tmp, 1, &tmp); GEOCLIP(&tmp, &swathClip); if ((tmp.r_xbot <= tmp.r_xtop) && (tmp.r_ybot <= tmp.r_ytop)) plotFillPixRaster(pixRasterSwath, &tmp,STYLE_LABEL, GR_STSOLID); } else { /* Line or rectangle. Draw outline. * plotFillPixRaster will outline the area if STYLE_LABEL has * fill mode GR_STOUTLINE. * Cute, berry, but it loses when the rect crosses a swath boundary. */ GEOCLIP(&swathArea, &swathClip); plotPixRect(&rootArea, 1, STYLE_LABEL); /* plotFillPixRaster(pixRasterSwath, &swathArea, STYLE_LABEL, -1); */ } /* Output the text for the label. */ labelSize.r_xbot += point.p_x - 1; labelSize.r_xtop += point.p_x + 1; labelSize.r_ybot += point.p_y - 1; labelSize.r_ytop += point.p_y + 1; PlotPixRasterText(pixRasterSwath, &swathClip, labelPixFont, label->lab_text, &point, STYLE_LABEL); return 0; } /* * ---------------------------------------------------------------------------- * * plotPixCell -- * * This procedure is invoked for unexpanded cells. * * Results: * Always returns 0 to keep the search from aborting. * * Side effects: * The raster is modified to depict the cell's boundary, * name, and instance id. * * ---------------------------------------------------------------------------- */ int plotPixCell(scx) SearchContext *scx; /* Describes cell whose bbox is to * be plotted. */ { char idName[100]; Rect rootArea, swathArea, textSize; Point point; CellDef *def; /* Convert the cell's bounding box to root coordinates and then * draw the outline. */ def = scx->scx_use->cu_def; GeoTransRect(&scx->scx_trans, &def->cd_bbox, &rootArea); plotPixRect(&rootArea, 1, STYLE_BLACK); if (!PlotShowCellNames) return (0); /* Output the cell's name and id text. */ plotTransToSwath(&rootArea, &swathArea); PlotTextSize(cellNamePixFont, def->cd_name, &textSize); point.p_x = (swathArea.r_xtop + swathArea.r_xbot)/2; point.p_x -= (textSize.r_xtop + textSize.r_xbot)/2; point.p_y = (2*swathArea.r_ytop + swathArea.r_ybot)/3; point.p_y -= (textSize.r_ytop + textSize.r_ybot)/2; PlotPixRasterText(pixRasterSwath, &swathClip, cellNamePixFont, def->cd_name, &point, STYLE_BBOX); (void) DBPrintUseId(scx, idName, 100, TRUE); PlotTextSize(cellIdPixFont, idName, &textSize); point.p_x = (swathArea.r_xtop + swathArea.r_xbot)/2; point.p_x -= (textSize.r_xtop + textSize.r_xbot)/2; point.p_y = (swathArea.r_ytop + 2*swathArea.r_ybot)/3; point.p_y -= (textSize.r_ytop + textSize.r_ybot)/2; PlotPixRasterText(pixRasterSwath, &swathClip, cellIdPixFont, idName, &point, STYLE_BBOX); return 0; } /* * ---------------------------------------------------------------------------- * * Plotpixels -- * * This procedure generates a pix file usable by various programs * that produce images on Dicomed cameras and so on. * * Results: * None. * * Side effects: * Lots and lots of disk space is chewed up by the file. * * ---------------------------------------------------------------------------- */ void PlotPixels(scx, layers, xMask, width) SearchContext *scx; /* The use and area and transformation * in this describe what to plot. */ TileTypeBitMask *layers; /* Tells what layers to plot. Only * paint layers in this mask, and also * expanded according to xMask, are * plotted. If L_LABELS is set, then * labels on the layers are also * plotted, if expanded according to * xMask. If L_CELL is set, then * subcells that are unexpanded * according to xMask are plotted as * bounding boxes. */ int xMask; /* An expansion mask, used to indicate * the window whose expansion status * will be used to determine * visibility. Zero means treat * everything as expanded. */ int width; /* How many pixels across the plot * should be. */ { static char *yesNo[] = {"no", "yes", NULL}; int dotsAcross, dotsDown, swathsDown, scaleDown; char fileName[200], answer[32]; float mBytes; Transform tinv; int action, result; FILE *file; /* * check to make sure that the swath height is a multiple of 8 so that stipples * will look correct across swath boundaries. */ if (PlotPixHeight & 007) { TxPrintf("Warning: plot parameter \"pixheight\" is not a multiple of 8. It\n"); TxPrintf("will be rounded from %d to %d.\n", PlotPixHeight, (PlotPixHeight&(~007))+8); PlotPixHeight = (PlotPixHeight&(~007))+8; } /* did the user specify an explicit width? */ if (width != 0) PlotPixWidth = width; GeoTransRect(&scx->scx_trans, &scx->scx_area, &rootClip); GEO_EXPAND(&rootClip, 1, &rootClip); dotsAcross = width; if (dotsAcross <= 0) dotsAcross = PlotPixWidth; /* * Compute the number of pixels per magic unit. * This number will be the fraction: scale / (1 << scaleShift). * In order to be reasonably sure that we have enough precision * in the numerator of the fraction, require that scale have at * least three bits (i.e., be greater than or equal to 4). */ for (scale = 0, scaleShift = 4; ; scaleShift++) { scaleDown = 1 << scaleShift; scale = (scaleDown * dotsAcross) / (rootClip.r_xtop - rootClip.r_xbot); if (scaleShift >= 8 * sizeof (int)) { TxError("The area selected is too many lambda wide to plot.\n"); TxError("(There are numerical problems with rasterizing it).\n"); TxError("Try selecting a smaller area, or else asking for "); TxError("a wider plot.\n"); return; } if (scale >= 4) break; } /* * Compute scaling information, and tell the user how big the * plot will be. */ dotsDown = ((rootClip.r_ytop - rootClip.r_ybot)*scale) >> scaleShift; swathsDown = (dotsDown + PlotPixHeight - 1)/PlotPixHeight; dotsDown = swathsDown * PlotPixHeight; mBytes = (double)(PlotPixWidth*dotsDown)*3.0/1000000.0; TxPrintf("Plot will take %.2f Megabytes in \"%s\".\n", mBytes, PlotTempDirectory); do { TxPrintf("Do you still want the plot? [yes] "); if (TxGetLine(answer, sizeof answer) == NULL || answer[0] == '\0') { action = 1; break; } } while ((action = Lookup(answer, yesNo)) < 0); if (action == 0) return; /* The plot has been "approved". Now obtain swath rasters if * we don't already have them. If the swath size has changed, * recycle the rasters for new ones. */ if (pixRasterSwath == NULL) pixRasterSwath = PlotNewPixRaster(PlotPixHeight, PlotPixWidth); else { if ((pixRasterSwath->pix_width != PlotPixWidth) || (pixRasterSwath->pix_height != PlotPixHeight)) { PlotFreePixRaster(pixRasterSwath); pixRasterSwath = PlotNewPixRaster(PlotPixHeight, PlotPixWidth); } } /* Load font information for the plot, if it isn't already * loaded. We use the "versatec" fonts for convenience. */ labelPixFont = PlotLoadFont(PlotVersLabelFont); cellNamePixFont = PlotLoadFont(PlotVersNameFont); cellIdPixFont = PlotLoadFont(PlotVersIdFont); if ((labelPixFont == NULL) || (cellNamePixFont == NULL) || (cellIdPixFont == NULL)) { TxPrintf("PlotPixels: can't load fonts\n"); return; } /* Compute the name of the file to use for output, and open it. */ sprintf(fileName, "%s/magicPlot-%d-%d-XXXXXX", PlotTempDirectory, PlotPixWidth, PlotPixHeight*swathsDown); result = mkstemp(fileName); if (result == -1) { TxError("Couldn't create temporary filename for %s\n", fileName); return; } file = PaOpen(fileName, "w", (char *) NULL, (char *) NULL, (char *) NULL, (char **) NULL); if (file == NULL) { TxError("Couldn't open file \"%s\" to write plot.\n", fileName); return; } /* Set up the rest of the transformation variables. * Arrange for the plot to be centered on the page. */ plotLL.p_y = rootClip.r_ybot; plotLL.p_x = (rootClip.r_xtop+rootClip.r_xbot)/2 - (PlotPixWidth*8)/scale; if (plotLL.p_x > rootClip.r_xbot) plotLL.p_x = rootClip.r_xbot; /* Compute a distance equal to 1/8th the size of a typical wire * (max of thicknesses of routing layers). This is used to offset * text from labels and to compute cross size for point labels. */ if (RtrMetalWidth > RtrPolyWidth) crossSize = (RtrMetalWidth*scale)/(scaleDown*8); else crossSize = (RtrPolyWidth*scale)/(scaleDown*8); if (crossSize < 2) crossSize = 2; /* Step down the page one swath at a time, rasterizing everything * that overlaps the current swath, then outputting the swath. */ GeoInvertTrans(&scx->scx_trans, &tinv); for (swathsDown -= 1; swathsDown >= 0; swathsDown -= 1) { SearchContext scx2; Rect root, labelArea; int labelHeight; swathY = swathsDown * PlotPixHeight; PlotClearPixRaster(pixRasterSwath, (Rect *) NULL); /* Compute the area of the swath that overlaps the portion of * the layout we're plotting. */ plotTransToSwath(&rootClip, &swathClip); if (swathClip.r_xbot < 0) swathClip.r_xbot = 0; if (swathClip.r_ybot < 0) swathClip.r_ybot = 0; if (swathClip.r_xtop >= PlotPixWidth) swathClip.r_xtop = PlotPixWidth - 1; if (swathClip.r_ytop >= PlotPixHeight) swathClip.r_ytop = PlotPixHeight - 1; /* Compute the area of layout that overlaps this swath. This is * done twice, once for mask material and once for labels. The * separate computation for labels is because labels stick out * from their positioning points. We may have to search a larger * area than just the swath in order to find all the labels that * must be drawn in this swath. Only the y-direction needs to * be expanded this way, since we're only swathing in y. Even * non-label stuff has to be expanded slightly, because lines * are drawn more than 1 pixel thick. */ scx2 = *scx; root.r_xbot = (scaleDown*swathClip.r_xbot)/scale + plotLL.p_x; root.r_xtop = (scaleDown*swathClip.r_xtop)/scale + plotLL.p_x; root.r_ybot = (scaleDown*(swathY-4))/scale + plotLL.p_y; root.r_ytop = (scaleDown*(swathY+swathClip.r_ytop+4))/scale+plotLL.p_y; GEO_EXPAND(&root, 1, &root); GeoTransRect(&tinv, &root, &scx2.scx_area); labelArea.r_xbot = root.r_xbot; labelArea.r_xtop = root.r_xtop; labelHeight = (labelPixFont->fo_bbox.r_ytop - labelPixFont->fo_bbox.r_ybot) + 2; labelArea.r_ybot = (scaleDown*(swathY-crossSize-labelHeight))/scale + plotLL.p_y; labelArea.r_ytop = (scaleDown*(swathY+swathClip.r_ytop+crossSize+labelHeight))/scale + plotLL.p_y; GEO_EXPAND(&labelArea, 1, &labelArea); /* For each style, output areas for all the tiles * requested by the style. */ for (curStyle = 0; curStyle < DBWNumStyles; curStyle++) { /* visit all the tiles in this swath */ curMask = DBWStyleToTypes(curStyle); (void) DBTreeSrTiles(&scx2, curMask, xMask, plotPixTile, (ClientData) NULL); } /* Output labels, if they are wanted. */ if (TTMaskHasType(layers, L_LABEL)) { curMask = layers; TTMaskSetType(curMask, TT_SPACE); GeoTransRect(&tinv, &labelArea, &scx2.scx_area); (void)DBTreeSrLabels(&scx2, curMask, xMask, (TerminalPath *) NULL, TF_LABEL_ATTACH, plotPixLabel, (ClientData) NULL); } /* Output subcell bounding boxes, if they are wanted. */ if (TTMaskHasType(layers, L_CELL)) { (void) DBTreeSrCells(&scx2, xMask, plotPixCell, (ClientData) NULL); } TxPrintf("#"); TxFlush(); if (PlotDumpPixRaster(pixRasterSwath,file)!= 0) goto error; if (SigInterruptPending) goto error; } /* Close the file and tell the user where it is */ fclose(file); TxPrintf("\nPlot complete. pix file is \"%s\"\n", fileName); return; error: TxError("\npixel plot aborted.\n"); fclose(file); unlink(fileName); } /* * ---------------------------------------------------------------------------- * * PlotNewPixRaster -- * * Allocate and initialize a new raster structure. * * Results: * The return value is a pointer to the new PixRaster object. * * Side effects: * Memory is allocated. * * ---------------------------------------------------------------------------- */ PixRaster * PlotNewPixRaster(height, width) int height; /* PixRaster's height in pixels.*/ int width; /* PixRaster's width in pixels.*/ { PixRaster *new; new = (PixRaster *) mallocMagic(sizeof(PixRaster)); new->pix_width = width; new->pix_height = height; new->pix_pixels = (char *) mallocMagic((unsigned) (height * width)); return new; } /* * ---------------------------------------------------------------------------- * * PlotFreePixRaster -- * * Frees up the memory associated with an existing PixRaster structure. * * Results: * None. * * Side effects: * The storage associated with PixRaster is returned to the allocator. * * ---------------------------------------------------------------------------- */ void PlotFreePixRaster(pr) PixRaster *pr; /* PixRaster whose memory is to be freed. * Should have been created with * PlotNewPixRaster. */ { freeMagic((char *) pr->pix_pixels); freeMagic((char *) pr); } /* * ---------------------------------------------------------------------------- * * PlotClearPixRaster -- * * This procedure clears out an area of the PixRaster. * * Results: * None. * * Side effects: * The area of the PixRaster indicated by "area" is set to all zeroes. * * ---------------------------------------------------------------------------- */ void PlotClearPixRaster(pr, area) PixRaster *pr; /* PixRaster that's to be cleared. */ Rect *area; /* Area to be cleared, in PixRaster * coords. NULL means clear the * whole PixRaster. */ { char *left, *right, *cur; int line; if (area == NULL) { bzero((char *) pr->pix_pixels, pr->pix_height*pr->pix_width); return; } /* Compute the address of the leftmost word in the topmost line * to be cleared, and the rightmost word in the topmost line to * be cleared. */ left = pr->pix_pixels + ((pr->pix_height-1) - area->r_ytop)* pr->pix_width; right = left + area->r_xtop; left += area->r_xbot; /* Clear the area one PixRaster line at a time, top to bottom. */ for (line = area->r_ytop; line >= area->r_ybot; line -= 1) { /* Clear the line. */ for (cur = left; cur <= right; cur += 1) *cur = 0; left += pr->pix_width; right += pr->pix_width; } } /* * ---------------------------------------------------------------------------- * * plotFillPixRaster -- * * Given a PixRaster and an area, this procedure renders the given area * of the PixRaster with a particular stipple pattern or other * appropriate style. * * Results: * None. * * Side effects: * The current PixRaster is modified.. * * ---------------------------------------------------------------------------- */ void plotFillPixRaster(pr, area, style, fill) PixRaster *pr; /* Pointer to PixRaster whose bits are * to be filled in. */ Rect *area; /* Area to be filled in pixel coords. * This is an inclusive area: it * includes the boundary pixels. The * caller must ensure that it is * clipped to the PixRaster area. */ int style; /* index of style to be used */ int fill; /* if >0, override GrStyleTable fill mode */ { char *left, *cur; int line; char *right; int curStipple, curColor, curMask; /* local copies so we don't have to * continually indirect through * GrStyleTable */ Rect r; /* for passing to plotPixLine */ #ifdef DEBUG TxPrintf("plotFillPixRaster: raster buffer@0x%x : ", pr->pix_pixels); TxPrintf(" (%d,%d)(%d,%d)\n", area->r_xbot, area->r_ybot, area->r_xtop, area->r_ytop); #endif /* Compute the address of the leftmost word in the topmost line * to be filled, and the rightmost word in the topmost line to * be filled. */ /* find beginning of first swath line that is affected */ left = pr->pix_pixels + ((pr->pix_height-1) - area->r_ytop)*pr->pix_width; right = left + area->r_xtop; /* right edge */ left += area->r_xbot; /* left edge */ /* Process the area one PixRaster line at a time, top to bottom. */ curStipple = GrStyleTable[style].stipple; curColor = GrStyleTable[style].color; curMask = GrStyleTable[style].mask; /* * now select the appropriate rendering style * and render the area. If we were passed a non-negative fill argument, * let it override the fill mode from GrStyleTable. Otherwise, use the * mode from the table. This is so we can make solid areas in STYLE_LABEL, * for example, instead of getting the arms of the crosses hollow. */ if (fill < 0) fill = GrStyleTable[style].fill; switch (fill) { case GR_STSTIPPLE: #ifdef DEBUG TxPrintf ("Stipple: %d %d %d %d %d %d %d %d \n", GrStippleTable[curStipple][0], GrStippleTable[curStipple][1], GrStippleTable[curStipple][2], GrStippleTable[curStipple][3], GrStippleTable[curStipple][4], GrStippleTable[curStipple][5], GrStippleTable[curStipple][6], GrStippleTable[curStipple][7]); #endif for (line = area->r_ytop; line >= area->r_ybot; line -= 1) { for (cur = left; cur <= right; cur += 1) /* select "line" of stipple pattern and AND it with the bitmask * for the bit in the line * x&07 == x % 8 and is faster */ if(GrStippleTable[curStipple][line&07] & 1<<(int)((7-(cur-pr->pix_pixels)% pr->pix_width)&07)) *cur = (*cur & ~curMask) | (curColor & curMask); left += pr->pix_width; right += pr->pix_width; } break; case GR_STGRID: /* not implemented */ break; /* cross and outline are handled at a higher level */ case GR_STCROSS: /* can't do it here due to swath boundary problems. */ break; case GR_STOUTLINE: break; case GR_STSOLID: default: for (line = area->r_ytop; line >= area->r_ybot; line -= 1) { for (cur = left; cur <= right; cur += 1) *cur = (*cur & ~curMask) | (curColor & curMask); left += pr->pix_width; right += pr->pix_width; } break; } } /* * ---------------------------------------------------------------------------- * * PlotDumpPixRaster -- * * Writes out the contents of the given PixRaster to the given file, * in binary format. Goes trhough color map table to get the values for * each pixel. * * Results: * Returns 0 if all was well. Returns non-zero if there was * an I/O error. In this event, this procedure prints an * error message before returning. * * Side effects: * Information is added to file. * * ---------------------------------------------------------------------------- */ int PlotDumpPixRaster(pr, file) PixRaster *pr; /* PixRaster to be dumped. */ FILE *file; /* File stream on which to dump it. */ { int i; int r, g, b; for (i = 0; i < (pr->pix_width) * (pr->pix_height); i++) { GrGetColor(pr->pix_pixels[i], &r, &g, &b); if (putc(r, file) == EOF) /* red */ { TxError("I/O error in writing PixRaster file: %s.\n", strerror(errno)); return 1; } if (putc(g, file) == EOF) /* green */ { TxError("I/O error in writing PixRaster file: %s.\n", strerror(errno)); return 1; } if (putc(b, file) == EOF) /* blue */ { TxError("I/O error in writing PixRaster file: %s.\n", strerror(errno)); return 1; } } return 0; } /* * ---------------------------------------------------------------------------- * * PlotPixRasterText -- * * Given a text string and a font, this procedure scan-converts * the string and writespixels in the current raster that correspond * to on-bits in the text. * * Results: * None. * * Side effects: * Bits are modified in the raster. * * ---------------------------------------------------------------------------- */ void PlotPixRasterText(raster, clip, font, string, point, style) PixRaster *raster; /* Raster whose bits are to be filled in. */ Rect *clip; /* Area to which to clip the text. Must be * entirely within the area of the raster. */ RasterFont *font; /* Font to use for rasterizing string. Must * have been obtained by calling PlotLoadFont. */ char *string; /* String of text to rasterize. */ Point *point; /* X-Y coordinates of origin of text. The * origin need not be inside the area of * the raster, but only raster points inside * the area will be modified. */ int style; /* style for the text to be rendered in -- * used only for the correct color. */ { int xOrig; /* X-origin for current character. */ int color; color = GrStyleTable[style].color; /* Outer loop: process each character. */ xOrig = point->p_x; for (; *string != 0; string++) { int cBytesPerLine, i; struct dispatch *d; /* Descriptor for current character. */ /* Handle spaces and tabs specially by just spacing over. */ if ((*string == ' ') || (*string == '\t')) { xOrig += font->fo_chars['t'].width; continue; } /* Middle loop: render each character one raster line at a * time, from top to bottom. Skip rows that are outside the * area of the raster. */ d = &font->fo_chars[*string]; cBytesPerLine = (d->left + d->right + 7) >> 3; for (i = 0; i < d->up + d->down; i++) { int y, j; char *charBitPtr; y = point->p_y + d->up - 1 - i; if (y < clip->r_ybot) break; if (y > clip->r_ytop) continue; /* Inner loop: process a series of bytes in a row to * render one raster line of one character. Be sure * to skip areas that fall outside the raster to the * left or right. */ for (j = -d->left, charBitPtr = font->fo_bits + d->addr + i*cBytesPerLine; j < d->right; j += 8, charBitPtr++) { char *rPtr; int charBits, x, k; x = xOrig + j; if (x > clip->r_xtop) break; if (x < clip->r_xbot - 7) continue; rPtr = (char *) raster->pix_pixels; rPtr += (raster->pix_height - 1 - y)*raster->pix_width + x; charBits = *charBitPtr & 0xff; /* Inner inner loop: process the bytes worth of bits, setting * pixels in the raster to the current color */ for(k=7;k>=0;k--) { if(charBits&(1<width; } } #endif /* LLNL */ magic-8.0.210/net2ir/0000755000175000001440000000000011734162034012656 5ustar timusersmagic-8.0.210/net2ir/Makefile0000644000175000001440000000062410751423606014323 0ustar timusers# # rcsid = "$Header: /usr/cvsroot/magic-8.0/net2ir/Makefile,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $" # MODULE = net2ir MAGICDIR = .. SRCS = net2ir.c EXTRA_LIBS = ${MAGICDIR}/utils/libutils.a include ${MAGICDIR}/defs.mak tcl-main: echo "Nothing to do here" main: net2ir install: $(DESTDIR)${BINDIR}/${MODULE}${EXEEXT} install-tcl: echo "Nothing to do here" include ${MAGICDIR}/rules.mak magic-8.0.210/net2ir/net2ir.c0000644000175000001440000000650310751423606014234 0ustar timusers/* * net2ir -- * * Given a feedback file produced by the Magic :find command (from * the netlist menu) followed by :feed save, giving label locations and * layers, and a netlist * file, produce a set of irouter commands to route the two-point * nets in the order in which they appear in the netlist file. * * Usage: * net2ir feedfile netfile * * Produces the commands on its standard output. */ #include #include #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/hash.h" #include "utils/malloc.h" #include "utils/utils.h" #ifndef lint static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/net2ir/net2ir.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* lint */ #define INITHASHSIZE 128 #define LINESIZE 1024 /* * Hash table of all feedback information giving label locations. * Keyed by the label name; the contents are a structure giving * the label location and its layer. */ HashTable feedHash; typedef struct { char *li_layer; char *li_label; Rect li_area; } LabInfo; int main(argc, argv) char *argv[]; { char line1[LINESIZE], line2[LINESIZE], layer[LINESIZE], label[LINESIZE]; HashEntry *he; LabInfo *li; int nterms; FILE *fp; char *cp; Rect r; if (argc != 3) { fprintf(stderr, "Usage: net2ir feedfile netfile\n"); exit (1); } /* Process the feedback file, building the hash table of label locs */ HashInit(&feedHash, INITHASHSIZE, HT_STRINGKEYS); fp = fopen(argv[1], "r"); if (fp == NULL) { perror(argv[1]); exit (1); } while (fgets(line1, sizeof line1, fp)) { getfirst: if (sscanf(line1, "box %d %d %d %d", &r.r_xbot, &r.r_ybot, &r.r_xtop, &r.r_ytop) != 4) continue; if (fgets(line2, sizeof line2, fp) == NULL) break; if (sscanf(line2, "feedback add \"%[^;];%[^\"]", layer, label) != 2) { strcpy(line1, line2); goto getfirst; } he = HashFind(&feedHash, label); if (HashGetValue(he)) { fprintf(stderr, "Warning: multiple locs for label %s; 2nd loc ignored.\n", label); continue; } li = (LabInfo *) mallocMagic((unsigned) (sizeof (LabInfo))); GEO_EXPAND(&r, -1, &li->li_area); li->li_label = StrDup((char **) NULL, label); li->li_layer = StrDup((char **) NULL, layer); HashSetValue(he, (ClientData) li); } (void) fclose(fp); /* Process the net file */ fp = fopen(argv[2], "r"); if (fp == NULL) { perror(argv[2]); exit (1); } nterms = 0; while (fgets(line1, sizeof line1, fp)) { if (isspace(line1[0]) || line1[0] == '\0') { nterms = 0; continue; } if (cp = index(line1, '\n')) *cp = '\0'; if (nterms >= 2) { fprintf(stderr, "Net with >2 terms ignored: %s\n", line1); continue; } he = HashLookOnly(&feedHash, line1); if (he == NULL || (li = (LabInfo *) HashGetValue(he)) == NULL) { fprintf(stderr, "No location for terminal %s\n", line1); continue; } if(nterms == 0) { printf(":iroute route -slayers %s -sPoint %d %d ", li->li_layer, li->li_area.r_xbot, li->li_area.r_ybot); } else { printf("-dlayers %s -dRect %d %d %d %d\n", li->li_layer, li->li_area.r_xbot, li->li_area.r_ybot, li->li_area.r_xtop, li->li_area.r_ytop); } nterms++; } exit(0); } magic-8.0.210/doc/0000755000175000001440000000000011504623573012225 5ustar timusersmagic-8.0.210/doc/latexfiles/0000755000175000001440000000000011504623573014365 5ustar timusersmagic-8.0.210/doc/latexfiles/addendum6_5.tex0000644000175000001440000001573210751423606017210 0ustar timusers%---------------------------------------------------------------------------- % Magic Addendum: Version 6.5 differences %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Magic Addendum: Version 6.5 differences} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape Stefanos Sidiropoulos} \\ \vspace*{0.5in} Center for Integrated Systems \\ Stanford University \\ Stanford, CA 94305 \\ \vspace*{0.25in} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Affected Documents:} \starti \> Magic Tutorial \#6: Design-Rule Checking \\ \> Magic Tutorial \#9: Format Conversion for CIF and Calma \\ \> Magic Tutorial \#W-1: Design-Rule Extensions \\ \> Magic Maintainer's Manual \#2: The Technology File \\ \> Magic man pages: ext2sim(1), ext2spice(1), extflat(3), ext(5). \endi \vspace*{0.25in} \section{Introduction} Magic 6.5 has some significant modifications that make some of the original version 6 documents obsolete. The purpose of this addendum is to highlight these differences so that users can take advantage of the new features. \section{Extractor Extensions} The 6.5 extractor uses double precision floating point numbers to represent capacitances. Therefore all the capacitances in (aF/sq-lambda) associated with the {\itshape areacap, perimc, sidewall, sideoverlap} keywords in the extract section of the technology file can be {\itshape floating point numbers}. Additionally the extension of the capacitance to floating point numbers affects the manual pages of ext2sim(1), ext2spice(1), extflat(3), ext(5) which can be found in your local system under CAD{\_}HOME/man The 6.5 extractor shields the perimeter capacitance from layer to layer. To facilitate this two new commands {\itshape planeorder, noplaneordering} have been introduced and the {\itshape sideoverlap} command has been modified. The syntax for the new commands is: \starti \ii {\bfseries planeorder} {\itshape plane num } \endi Where {\itshape plane} is one of the defined planes and {\itshape num} is a positive integer indicating the ordering of this plane from lower to higher. So for example the metal1 plane has order 3 while metal2 has order 4. In case you dont want to specify the order of the planes the extractor will complain and assume a default one. If you want to suppress the warning you just have to issue the keyword: \starti \ii {\bfseries noplaneordering } \endi The {\itshape sideoverlap} keyword syntax has been altered to: \starti \ii {\bfseries sideoverlap} {\itshape intypes outtypes ovtypes cap shieldtypes} \endi where {\itshape intypes}, {\itshape outtypes}, and {\itshape ovtypes} are type-lists and {\itshape cap} is capacitance in attofarads per lambda. This is the capacitance associated with an edge with a type in {\itshape intypes} on its inside and a type in {\itshape outtypes} on its outside, that overlaps a tile whose type is in {\itshape ovtypes}. If the {\itshape shieldtypes} is present however this shields the capacitance. So for example to shield metal-2 to poly capacitance use: \starti \ii {\bfseries sideoverlap} M2Cap \~{}M2Cap PolyCap 19.41 M1Cap \endi \section{DRC Extensions} This version includes code fragments implemented in DEC-WRL by Don Stark which enable to implement more complicated DRC rules. For a description of these enhancements look in the magic tutorial \#W1 which can be found in the file doc/tutwrl1.ps under the magic source tree. \section{CIF extensions} Two new commands have been integrated in the cif output section courtesy of Steven Tell and Fred Heaton at UNC. The first new command is a command that enables the generation of DRC correct layers at the top level (such as the nwell in the SCMOS tech files). The syntax is: \starti \ii {\bfseries min-width} {\itshape width } \endi The width argument is in centimicrons. This command should be specified within a layer sub-section of the cifoutput section of the technology file. The second command is an extension to the squares cif output command. Its syntax is: \starti \ii {\bfseries squares-grid} {\itshape border size separation grid} \endi The added argument is {\itshape grid}. It is in units of centi-microns. In some technologies, all features must fall on a specified grid. In our case, this was a .05 micron grid. In the original implementation of magic, if lambda was not set to some integral multiple of the grid one could generate contacts that did not fall on grid boundaries. By specifying the grid spacing, the new enhancement to the contact generation code will allow contacts to be generated on grid. This does introduce some problems. In particular, some odd size contacts will not be able to generate a CIF contact structure that is centered on its corresponding magic contact. This is not a problem in most cases, except where an odd size contact is shared between two cells. In this case, the CIF contact strucuture might be shifted to the left during CIF generation to get it on grid and the other cell might be shifted to the right. The superposition of these two structures may create an illegal contact size or spacing. Use with extreme care or combine it with cifwidth and cifspacing rules to verify correct operation. \section{New commands} Three new commands have been introduced (based on the WRL code fragments by Bob Mayo): \starti \ii {\bfseries goto} {\itshape nodename} \endi Places the box/cross over the node named {\itshape nodename}. \starti \ii {\bfseries findlabel} {\itshape labelname} \endi Places the box/cross over the label {\itshape nodename}. \starti \ii {\bfseries flatten} {\itshape destname} \endi Flattens the cell in the current layout window and places it in the cell named {\itshape cellname}. The labels are changed to retain their hierarchical prefixes. \end{document} magic-8.0.210/doc/latexfiles/tutwrl1.tex0000644000175000001440000002026110751423606016530 0ustar timusers%---------------------------------------------------------------------------- % Magic tutorial number W-1 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Magic Tutorial \#W-1: Design-Rule Extensions} \def\q{\special{ps:(") show}\hspace*{0.6em}} \def\bk{\special{ps:/bksp 2 string def bksp 0 92 put bksp show}\hspace*{0.4em}} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape Don Stark} \\ \vspace*{0.5in} Western Research Laboratory \\ Digital Equipment Corporation \\ Palo Alto, CA 94301 \\ \vspace*{0.25in} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Tutorials to read first:} \starti \> Magic Tutorial \#6: Design-Rule Checking \\ \> Magic Tutorial \#9: Format Conversion for CIF and Calma \\ \> Magic Maintainer's Manual \#2: The Technology File \endi {\noindent\bfseries\large Commands introduced in this tutorial:} \starti \> {\itshape (None)} \endi {\noindent\bfseries\large Macros introduced in this tutorial:} \starti \> {\itshape (None)} \endi \vspace*{0.25in} \section{Introduction} Magic's original design rule checker has proved inadequate to implement all the rules found in advanced technologies. The rules described in this section allow more complicated configurations to be analyzed. Two new rules check a region's area and its maximum width. In addition, width, spacing, area, and maxwidth checks may now be performed on cif layers. \section{Area Rules} The {\bfseries area} rule is used to check the minimum area of a region. Its syntax is: \starti \ii {\bfseries area} {\itshape types minarea minedge why} \endi {\itshape Types} is a list of types that compose the region, all of which must be on the same plane. {\itshape Minarea} is the minimum area that a region must have, while {\itshape minedge} is the minimum length of an edge for the region. This second dimension is basically an optimization to make the design rule checker run faster; without it, the checker has to assume that a region 1 lambda wide and {\itshape minarea} long is legal, and it must examine a much larger area when checking the interaction between cells. Specifying {\itshape minedge} reduces this interaction distance. An example rule is: \starti \ii {\bfseries area (emitter,em1c)/npoly 6 2 {\q}emitter must be at least 2x3{\q}} \endi \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/tutw1.2.ps, width = 0.65\columnwidth} \caption{Example of the area rule.} \end{center} \end{figure} \section{Maxwidth Rules} Sometimes a technology requires that a region not be wider than a certain value. The {\bfseries maxwidth} rule can be used to check this. \starti \ii {\bfseries maxwidth} {\itshape layers mwidth bends why} \endi {\itshape Layers}, the types that compose the region, must all be in the same plane. The region must be less than {\itshape mwidth} wide in either the horizontal or vertical dimension. {\itshape Bends} takes one of two values, {\bfseries bend{\_}illegal} and {\bfseries bend{\_}ok}. For {\bfseries bend{\_}illegal} rules, the checker forms a bounding box around all contiguous tiles of the correct type, then checks this box's width. For example: \starti \ii {\bfseries maxwidth (emitter,em1c)/npoly 2 bend{\_}illegal\ {\bk}} \\ \ii \> {\bfseries {\q}emitter width cannot be over 2{\q}} \endi {\bfseries bend{\_}ok} rules are used to check structures where the region must be locally less than maxwidth, but may contain bends, T's, and X's. \starti \ii {\bfseries maxwidth trench 2 bend{\_}ok {\q}trench must be exactly 2 wide{\q}} \endi {\bfseries Warning:} the bend{\_}ok rule is basically a kludge, and may fail for regions composed of more than one type, or for intersections more complicated than T's or X's. Figure~\ref{maxwidth} shows some examples of both types of rules. \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/tutw1.1.ps, width=\columnwidth} \label{maxwidth} \caption{Examples of the maxwidth rule. The dogleg at the left would be ok in a {\bfseries bend{\_}ok} rule, but fails in a {\bfseries bend{\_}illegal} one, where the region's bounding box is checked. For {\bfseries bend{\_}ok} rules, each tile in the region is checked. The left shape fails in two places: the top horizontal part is too thick and the stub at the bottom intersects the region in a shape other than a T or X.} \end{center} \end{figure} \section{Rules on CIF layers} For technologies with complicated generated layers, it is often difficult to check design rules on the abstract types that are drawn in Magic. To ameliorate this problem, the extended checker allows simple checks to be performed on cif layers. The rules that can be checked are width, spacing, area, and maxarea. Since checking rules on the cif layers requires that these layers be generated, these checks are considerably slower than the normal ones, and should only be used when absolutely necessary. \subsection{Setting the CIF style} The {\bfseries cifstyle} rule is used to select which {\bfseries cifoutput} style is used. \starti \ii {\bfseries cifstyle} {\itshape cif{\_}style} \endi {\itshape Cif{\_}style} must be one of the cif styles included in the cifoutput section. In the current implementation, the cif checker generates all the layers in the style regardless of whether they are actually used in design-rule checks; for speed, defining a separate cif style for design rule checking it may be worthwhile when only a few layers are checked. Any layer in the cif style, defined by either a {\itshape layer} or a {\itshape templayer} rule, may be checked. \subsection{Width Checks} The syntax for {\bfseries cifwidth} is analogous to that of the regular width rule: \starti \ii {\bfseries cifwidth} {\itshape layer width why} \endi {\itshape Layer} is a single cif layer. (To do width checks with more than one cif layer, {\bfseries or} all the layers into a new {\itshape templayer}). {\itshape Width} is the minimum width of the region in centimicrons. \subsection{Spacing Checks} The {\bfseries cifspacing} rule is also very similar to the regular rule: \starti \ii {\bfseries cifspacing} {\itshape layer1 layer2 separation adjacency why} \endi {\itshape Layer1} and {\itshape layer2} are both cif layers. If {\itshape adjacency} is {\bfseries touching{\_}ok}, then layer1 must equal layer2. For {\bfseries touching{\_}illegal} rules, {\itshape layer1} and {\itshape layer2} may be any two cif layers. {\itshape Separation} is given in centimicrons. \subsection{Area Checks} The area rule is: \starti \ii {\bfseries cifarea} {\itshape layer minarea minedge why} \endi {\itshape Layer} is again a single cif layer. {\itshape minedge} is expressed in centimicrons, and {\itshape minarea} is given in square centimicrons. \subsection{Maxwidth Checks} The maxwidth rule is: \starti \ii {\bfseries cifmaxwidth} {\itshape layer mwidth bends why} \endi Again, {\itshape layer} is a single cif layer, and {\itshape mwidth} is given in centimicrons. \end{document} magic-8.0.210/doc/latexfiles/tuttcl1.tex0000644000175000001440000006500010751423606016506 0ustar timusers%---------------------------------------------------------------------------- % Magic Tcl tutorial number 1 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ig{\>} \def\ih{\>\>} \def\ii{\>\>\>} \def\mytitle{Magic Tcl Tutorial \#1: Introduction} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape R. Timothy Edwards} \\ \vspace*{0.5in} Space Department \\ Johns Hopkins University \\ Applied Physics Laboratory \\ Laurel, MD 20723 \\ \vspace*{0.25in} This tutorial corresponds to Tcl-based Magic version 7.2 \\ \end{center} \vspace*{0.5in} \section{What is Tcl-based Magic, and Why?} In Magic version 7.0, Rajit Manohar incorporated a SCHEME interpreter into the Magic source, noting the limitation of magic to handle definitions and variables, conditionals, and block structures. By embedding an interpreter into the code, the interpreter's functions are made available on the magic command line, making magic extensible. The SCHEME interpreter and various extensions incorporated into loadable scripts are outlined in the tutorials {\ttfamily tutscm1.ps} through {\ttfamily tutscm4.ps}. While making Magic considerably more flexible, the embedded SCHEME interpreter had some notable drawbacks. The primary one is that the SCHEME language is syntactically different from Magic's command-line syntax. Also, the interpreter is largely disconnected from the code, and does not affect or extend the graphics or handle results from magic commands. Beginning in Magic version 7.2, Magic has been recast into a framework called {\it ScriptEDA}, in which existing applications become {\bfseries extensions} of an interpreter rather than having an interpreter embedded in the application. The main advantage of extending over embedding is that the application becomes a module of the interpreter language, which does not preclude the use of additional, unrelated modules in the same interpretive environment. For example, in Tcl-based Magic, graphics are handled by Tk (the primary graphics package for use with Tcl), and applications such as IRSIM (the digital simulator) can be run as if they were an extension of magic itself. Commands for Tcl, Tk, IRSIM, BLT, and any other Tcl-based package can be mixed on the magic command line. While {\it ScriptEDA} suggests the use of the {\bfseries SWIG} package to give applications the ability to be compiled as extensions of any interpreter (Tcl, Python, SCHEME, Perl, etc.), there are specific advantages to targeting Tcl. Foremost, the syntax of Tcl is virtually 100\% compatible with that of Magic. This is not coincidentally because both Magic and Tcl were written by John Ousterhout! Many ideas from the development of Magic were incorporated into the overall concept and design of the Tcl interpreter language. Largely due to the syntactical compatibility, Tcl-based magic is completely backwardly-compatible with the non-interpreter version of magic. Either can be selected at compile-time, in addition to compiling with embedded SCHEME, which has been retained in full as an option. A few minor issues, such as the appearance of the cursor when magic is used without a Tk console window, are addressed below. Magic extensions under Tcl are considerable, and explanations of the features have been split into several tutorial files, as listed in Table~\ref{tutorials}. \begin{table}[ht] \begin{center} \begin{tabular}{|l|} \hline Magic Tcl Tutorial \#1: Introduction \\ Magic Tcl Tutorial \#2: The GUI Wrapper \\ Magic Tcl Tutorial \#3: Extraction and Netlisting \\ Magic Tcl Tutorial \#4: Simulation with IRSIM \\ Magic Tcl Tutorial \#5: Writing Tcl Scripts for Magic \\ \hline \end{tabular} \end{center} \caption{The Magic Tcl tutorials and other documentation.} \label{tutorials} \end{table} \section{Features of Tcl-based Magic} In summary, the features of Tcl-based Magic (corresponding to Magic version 7.2, revision 31) are as follows: \begin{enumerate} \item The command name {\bfseries magic} itself is a script, not a compiled executable. The script launches Tcl and gives it the name of a Tcl script to evaluate ({\ttfamily magic.tcl}). The Tcl script loads Magic as an extension of Tcl and performs all other operations necessary to start up the application. \item Command-line arguments passed to Magic have been changed. Some older, unused arguments have been removed. Several arguments have been added, as follows: \begin{enumerate} \item {\ttfamily -noconsole} Normally, under Tcl/Tk, Magic starts by launching a Tk-based console window ({\ttfamily tkcon.tcl}) which is the window that accepts magic commands. Previous versions of Magic accepted commands from the calling terminal. The former style of running commands from the calling terminal can be selected by choosing this argument at runtime. Note, however, that due to fundamental differences in the underlying input routines between Tcl and magic, the terminal-based command entry does not exactly match the original behavior of magic. In particular, the background DRC function does not change the prompt. In addition, ``Xterm'' consoles must select option ``Allow SendEvents'' for keystrokes to be echoed from the layout window into the terminal. For security reasons, the application cannot change this option on the terminal. \item {\ttfamily -wrapper} To enforce backward-compatibility, magic appears as it would without the Tcl interpreter (apart from the text entry console) when launched with the same arguments. However, most users will want to make use of the extensions and convenience functions provided by the ``wrapper'' GUI. These functions are detailed in a separate tutorial (see Tutorial~\#2). \end{enumerate} \item Magic-related programs ``ext2spice'' and ``ext2sim'' have been recast as magic commands instead of standalone executables. This makes a good deal of sense, as both programs make heavy use of the magic internal database. Most values required to produce netlists were passed through the intermediary file format {\ttfamily .ext}. However, not all necessary values were included in the {\ttfamily .ext} file format specification, and some of these missing values were hard-coded into the programs where they have since become mismatched to the magic database. This has been corrected so that all netlist output corresponds to the technology file used by a layout. Both commands ``ext2spice'' and ``ext2sim'' allow all of the command-line arguments previously accepted by the standalone programs. Some of the more common functions, however, have been duplicated as command options in the usual format of magic commands. For instance, one may use the magic command: \starti \ii {\bfseries ext2sim help} \endi to get more information on {\ttfamily ext2sim} command-line options. \item All Tcl interpreter procedures may be freely mixed with magic commands on the command line. For instance, a user can use Tcl to compute arithmetic expressions on the command line: \starti \ii {\bfseries copy e [expr\{276 * 5 + 4\}]} \endi \item A number of magic commands pass values back to the interpreter. For instance, the command \starti \ii {\bfseries box values} \endi returns the lower left- and upper right-hand coordinates of the cursor box in magic internal units. This return value can be incorporated into an expression, such as the one below which moves the box to the left by the value of its own width: \starti \ii {\bfseries set bbox [box values]} \\ \ii {\bfseries set bwidth \[expr \{[lindex \$bbox 2] - [lindex \$bbox 0]\}]} \\ \ii {\bfseries move e \$bwidth} \endi \item Magic prompts for text have been recast as Tk dialog boxes. For instance, the command {\bfseries writeall} will pop up a dialog box with five buttons, one for each of the available choices (write, flush, skip, abort, and auto). \item IRSIM is no longer available as a ``mode'' reached by switching tools by command or the space-bar macro. Instead, IRSIM (version 9.6) can be compiled as a Tcl extension in the same manner as Magic, at compile time. When this is done, IRSIM is invoked simply by typing \starti \ii {\bfseries irsim} \endi on the Magic command line. IRSIM is loaded as a Tcl package, and IRSIM and Magic commands may be freely mixed on the Magic command line: \starti \ii {\bfseries assert [getnode]} \endi IRSIM does not require the name of a file to start. Without arguments, it will assume the currently loaded cell is to be simulated, and it will generate the {\ttfamily .sim} file if it does not already exist. \item In addition to IRSIM, programs {\bf xcircuit} and {\bf netgen} can be compiled as Tcl extensions and provide cabability for schematic capture and layout-vs.-schematic, respectively. \item Tcl-based Magic makes use of the Tcl variable space. For instance, it keeps track of the installation directory through the variable {\ttfamily CAD\_HOME}, which mirrors the value of the shell environment variable of the same name. In addition, it makes use of variables {\ttfamily VDD} and {\tt GND} in the technology file to aid in the extraction of substrate- and well-connected nodes on transistors. \item Magic input files, such as the {\ttfamily .magic} startup file, are sourced as Tcl scripts, and so may themselves contain a mixture of Tcl and magic commands. \end{enumerate} \section{Compilation and Installation} Magic is selected for compilation as a Tcl extention when running the \starti \ii {\bfseries make config} \endi script. The first question asks whether magic should be compiled as a Tcl extension, with the SCHEME interpreter embedded, or as the original version with no interpreter. Subsequent to choosing Tcl as the interpreter and answering the remaining configuration questions, Tcl should be compiled and installed using the commands \starti \ii {\bfseries make tcl} \endi and \starti \ii {\bfseries make install-tcl} \endi Note that if magic is to be compiled under different interpreters, it is necessary to perform \starti \ii {\bfseries make clean} \endi between the compilations, so that all references to the last compiled version are deleted. \section{Dual-Source Input and Backward Compatibility} From its inception, Magic has used an unsual but very effective interface in which commands may be passed to the program from two different sources, the layout window, and the calling terminal. Keystrokes in the layout window are handled by the graphics package. These are interpreted as {\itshape macros}. The keystroke values are expanded into magic command-line commands and executed by the command-line command dispatcher routine. Two macros, `{\ttfamily .}' and `{\ttfamily :}' are reserved: The period expands to the last command executed from the command line ({\itshape not} from a macro expansion), and the colon initiates a redirection of keystrokes from the layout window into the calling terminal. Magic users quickly get used to the combination of keystrokes, mouse functions, and command-line commands. In the Tcl-based version of Magic, the command-line dispatching is given over entirely to Tcl, and the dispatching of keystroke events in the layout window is given over entirely to Tk. Unfortunately, in relinquishing these duties, Magic loses some of the effectiveness of its dual-source input model. One aspect of this is that Tcl is a line-based interpreter, and does not recognize anything on the command line until the return key has been pressed and the entire line is passed to the command dispatcher routine. Without any understanding of character-based input, it is difficult to impossible to directly edit the command line from outside the calling terminal, because it is the terminal, and not Tcl, which interprets keystrokes on a character-by-character basis. The way around this problem is to use a {\itshape console}, which is an application that runs in the manner usually expected by Tk, in that it is a GUI-driven application. The interpreter is split into {\itshape master} and {\itshape slave} interpreters (see the Tcl documentation on the {\bfseries interp} command), with the master interpreter running the console application and the slave interpreter running the application. The master interpreter then has character-based control over the command line, and the Magic dual-source input model can be implemented exactly as originally designed. The background DRC function can change the command line cursor from `{\itshape \%}' to `{\itshape ]}' to indicate that the DRC is in progress, and user input can be redirected from the layout window to the console with the `{\bfseries :}' keystroke. In addition to these functions, the console makes use of Tcl's ability to rename commands to recast the basic Tcl output function `{\bfseries puts}' in such a way that output to {\ttfamily stdout} and {\ttfamily stdin} can be handled differently. In the {\bfseries TkCon} console, output to {\ttfamily stdout} is printed in blue, while output to {\ttfamily stderr} is printed in red. Magic makes use of Tcl's output procedures so that returned values and information are printed in blue, while warnings and error messages are printed in red. The console also implements command-line history and cut-and-paste methods. The console command-line history replaces the embedded {\itshape readline} implementation in magic. The {\bfseries TkCon} console is a placeholder for what is intended to be a ``project manager'' console, with functions more appropriate to the Electronic Design Automation suite of Tcl-based tools. In general, the menu functions which are displayed on the TkCon console are not of particular interest to the Magic user, with the exception of the {\bfseries History} menu, which can be used to re-enter previously executed commands, and the {\bfseries Prefs} menu, which includes highlighting options and a very useful calculator mode. \section{Tk Graphics Methods} Because the graphics under Tcl are managed by the Tk package, the only graphics options which can be compiled are the X11 and the OpenGL options. There are numerous differences between these graphics interfaces as they exist under Tcl and under the non-Tcl-based version. The two primary differences are the way windows are generated and the way commands are sent to specific windows. In Tcl-based magic, a layout window does not have to be a top-level application window. by using the command syntax \starti \ii {\bfseries openwindow} {\itshape cellname tk\_pathname} \endi An unmapped window can be generated, corresponding to the Tk window hierarchy specified by {\itshape tk\_pathname} (see the Tk documentation for the specifics of Tk window path name syntax). This window is then mapped and managed by Tk commands. Using this method, a magic window can be embedded inside a ``wrapper'' application, an example of which has been done with the GUI wrapper invoked with the ``{\ttfamily -w}'' command-line argument. Extensions of magic window commands have been added so that the wrapper can control the window frame, including the scrollbars and title. Whenever a window is created, Magic creates a Tcl/Tk command with the same name as the window (this is conventional practice with Tk widgets). Magic and Tcl commands can be passed as arguments to the window command. Such commands are executed relative to the specific window. This applies to all of magic's window-based commands, including instructions such as {\bfseries move}, {\bfseries load}, and so forth. Commands which apply to all windows will automatically be sent to all windows. These commands are used primarly by the wrapper GUI, but are also called (transparently to the end user) whenever a command is executed from a layout window via any macro, including the `{\bfseries :}' command-line entry. In addition, however, they may be called from the command line to perform an action in a specific window. By default (in the absence of a wrapper GUI), magic's windows are named {\itshape .magic1}, {\itshape .magic2}, and so forth, in order of appearance, and these names are reflected in the title bar of the window. So it is equivalent to do \starti \ii {\bfseries :move s 10} \endi from layout window `{\itshape .magic2}' (where the colon indicates the key macro for command-line entry), and \starti \ii {\bfseries .magic2 move s 10} \endi typed in the console. \section{Tutorial Examples} Example sessions of running magic in various modes are presented below, along with examples of methods specific to each mode. In the examples below, prompts are shown to indicate the context of each command. The {\itshape \#} sign indicates the shell prompt, {\itshape (gdb)} indicates the GNU debugger prompt, and {\itshape \%} indicates the Tcl (i.e., Magic) prompt. \medskip \noindent {\bfseries \itshape Example 1: Standard Magic Execution} \\ Run Tcl-based magic in its most basic form by doing the following: \starti \ii {\itshape \#} {\bfseries magic -noconsole tut2a} \\ \endi Magic looks generally like its traditional form, except that the command-line prompt is the Tcl `{\itshape \%}' prompt. It should be possible to write commands from either the terminal or using the colon keystroke, and it is possible to partially type a command after the colon keystroke and finish the command inside the terminal, but not vice versa. Enabling the colon keystroke may require setting ``Allow SendEvents'' mode on the calling terminal. \medskip \noindent {\bfseries \itshape Example 2: Console-based Magic Execution} \\ Run the TkCon console-based magic by doing the following: \starti \ii {\itshape \#} {\bfseries magic tut2a} \\ \endi The layout window will still look like the usual, basic form. However, the calling terminal will be suspended (unless the application is backgrounded; however, if backgrounding the application, be aware that any output sent to the terminal will hang the application until it is foregrounded) and the Tcl prompt will appear in a new window, which is the {\bf console}. The console may have a slightly different appearance depending on the graphics mode used. For instance, magic has historically had difficulties running in 8-bit (PseudoColor) graphics mode, because it installs its own colormap. Because it does not share the colormap with the calling terminal, the calling terminal gets repainted in random colors from magic's colormap when the cursor is in the layout window. In unlucky setups, text and background may be unreadable. In the TkCon console setup, the console is mapped prior to determining the graphics mode required, so it also does not share the colormap. However, it is possible to query Magic's colormap to find the location of specific colors, and repaint the text and background of the console accordingly. Thus, the Magic console can be used when the display is in 8-bit PseudoColor mode, without extreme color remappings in the console which make it potentially impossible to read the console when the cursor is in a layout window. If compiled with both OpenGL and X11 graphics capability, magic will start in X11 mode by default. The OpenGL interface can only be enabled at startup by specifying: \starti \ii {\itshape \#} {\bfseries magic -d OGL tut4x} \\ \endi The OpenGL interface, in addition to having more solid, vibrant colors, has an additional feature which draws three-dimensional views of a layout. This is discussed in Tutorial~\#??. \medskip \noindent {\bfseries \itshape Example 4: The Magic Wrapper GUI} \\ The magic GUI interface is invoked by starting magic with the {\bfseries -w} option: \starti \ii {\itshape \#} {\bfseries magic -w tut2b} \\ \endi The immediately noticeable differences are the layer toolbar on the side, and the menu and redesigned title bar on the top. Experimenting with some mouse clicks, the user will note that the magic coordinates of the cursor box are displayed on the right-hand side of the titlebar. The toolbar contains one example of each layer defined in the magic technology file. Position a box on the screen, then put the cursor over a layer icon and press the middle mouse button. This paints the layer into the box. You will also notice that the name of the layer is printed in the title bar while the cursor is over the layer icon. The icons have other responses, too. The first and third mouse buttons respectively show and hide the layer in the layout. This works with labels, subcell boundaries, and error paint (the top three layer icons) as well as with regular paintable layers. In addition to mouse button responses, the buttons invoke various commands in reponse to keystrokes. Key `p' paints the layer; key `e' erases it. Key `s' selects the layer in the box while key `S' unselects it. The menubar has three items, {\bfseries File}, {\bfseries Cell}, and {\bfseries Tech}. Button {\bfseries File} pops up a menu with options to read and write layout, read and write CIF or GDS output, open a new layout window or close the existing one, or flush the current edit cell. Buttons {\bfseries Cell} and {\bfseries Tech} reveal transient windows showing information about the cell hierarchy and the technology file, respectively. The cell hierarchy view is only available if the Tcl/Tk package {\bfseries BLT} has been compiled and installed on the system. If so, it gives a tree view of the cell hierarchy and allows specific cells to be loaded, edited, and expanded, or viewed to fit the window. This can be expecially useful for querying the cell hierarchy of GDS files, which do not declare top-level cells like CIF files do. The technology manager window reports the current technology file, its version and description, and the current CIF input and output styles, the current extraction style, and the current value of lambda in microns. The technology file and the CIF input and output styles and extraction style are also buttons which can be used to select a new style or technology from those currently available. Clicking on the current extract style, for instance, gives a list of the styles which have been specified in the current technology file. Clicking on one of the entries in the list makes it the new current extract style. Cell hierarchy and technology manager windows should be closed by clicking on the ``Close'' button at the bottom, not by invoking any titlebar functions (which will probably cause the whole application to exit). \medskip \noindent {\bfseries \itshape Example 5: Batch-mode Magic} \\ Unlike previous versions of magic, it is not necessary to have a layout window present to run magic. Magic may be invoked in ``batch mode'' by the following command-line: \starti \ii {\itshape \#} {\bfseries magic -nowindow tut2b} \\ \endi Note however, that most magic commands expect a window to be present to execute the function. The main use for batch mode is for wrapper-type applications to delay opening a layout window until one is requested. For example: \starti \ii {\itshape \#} {\bfseries magic -nowindow tut2b} \\ \ii {\itshape \%} {\bfseries toplevel .myframe} \\ \ii {\itshape \%} {\bfseries openwindow tut2b .myframe.mylayout} \\ \ii {\itshape \%} {\bfseries pack .myframe.mylayout} \\ \ii {\itshape \%} {\bfseries .myframe.mylayout box 0 0 12 12} \\ \ii {\itshape \%} {\bfseries .myframe.mylayout select area poly} \\ \ii {\itshape \%} {\bfseries wm withdraw .myframe} \\ \ii {\itshape \%} {\bfseries wm deiconify .myframe} \\ \ii {\itshape \%} {\bfseries .myframe.mylayout closewindow} \\ \endi Note that this is the basic setup of the standard GUI wrapper, albeit with much greater sophistication. The standard GUI wrapper is generated entirely by script, which can be found in the library directory {\bfseries \$\{CAD\_HOME\}/lib/magic/tcl/wrapper.tcl}. \medskip \noindent {\bfseries \itshape Example 6: Tcl-Magic under the Debugger} \\ When running under Tcl, Magic cannot be debugged in the usual manner of executing, for instance, ``{\bfseries gdb magic}'', because the main executable is actually the program ``{\bfseries wish}''. To run Magic with debugging capability, it is necessary to do the steps below. In the following, it is assumed that Magic has been installed in the default location {\ttfamily CAD\_HOME=/usr/local/}, and that the GNU debugger {\ttfamily gdb} is the debugger of choice. \starti \ih {\itshape \#} {\bfseries gdb wish} \\ \ih {\itshape (gdb)} {\bfseries run} \\ \ih {\itshape \%} {\bfseries source /usr/local/lib/magic/tcl/magic.tcl} \\ \ii . \\ \ii . \\ \ii . \\ \ih {\itshape \%} {\itshape (type Control-C in the terminal window)} \\ \ih {\itshape (gdb)} {\bfseries break TxTclDispatch} \\ \ih {\itshape (gdb)} {\bfseries cont} \\ \ih {\itshape \%} {\bfseries paint m1} \\ \ih \\ \ih {\ttfamily Breakpoint 1, TxTclDispath (clientData=0x0, argc=2,}\\ \ii {\ttfamily argv=0xbffff400)}\\ \ih {\ttfamily \ \ \ \ \ at txCommands.c:1146} \\ \ih {\ttfamily 1146 \ \ \ \ \ \ \ \ DRCBreak();} \\ \ih {\itshape (gdb)} \\ \endi Command-line arguments can be passed to magic through the Tcl variables {\ttfamily argc} and {\ttfamily argv}. The integer value {\ttfamily argc} must match the number of entries passed in the {\ttfamily argv} list. For example, do the following: \starti \ii {\itshape \#} {\bfseries gdb wish} \\ \ii {\itshape (gdb)} {\bfseries run} \\ \ii {\itshape \%} {\bfseries set argc 4} \\ \ii {\itshape \%} {\bfseries set argv \{-w -d OGL tut1 \}} \\ \ii {\itshape \%} {\bfseries source /usr/local/lib/magic/tcl/magic.tcl} \\ \endi \end{document} magic-8.0.210/doc/latexfiles/tutscm4.tex0000644000175000001440000000410210751423606016505 0ustar timusers%---------------------------------------------------------------------------- % Magic tutorial number S-4 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Magic Tutorial \#S-4: The design rule file} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape Rajit Manohar} \\ \vspace*{0.5in} Deparment of Computer Science \\ California Institute of Technology \\ Pasadena, CA 91125 \\ \vspace*{0.25in} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Tutorials to read first:} \starti \> Magic Tutorial \#S-1: The scheme command-line interpreter \endi {\noindent\bfseries\large Commands introduced in this tutorial:} \starti \> :drc.\* \endi {\noindent\bfseries\large Macros introduced in this tutorial:} \starti \> {\itshape (None)} \endi \vspace*{0.25in} \section{Introduction} \end{document} magic-8.0.210/doc/latexfiles/maint1.tex0000644000175000001440000006275010751423606016310 0ustar timusers%---------------------------------------------------------------------------- % Magic Maintainer's Manual number 1: Installation and Development %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\= \hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Magic Maintainer's Manual \#1: Installation and Development} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape John Ousterhout} \\ {\itshape Walter Scott} \\ \vspace*{0.5in} Computer Science Division \\ Electrical Engineering and Computer Sciences \\ University of California \\ Berkeley, CA 94720 \\ \vspace*{0.25in} {\itshape Tim Edwards} \\ MultiGiG, Inc. \\ Scotts Valley, CA 95014 \\ \vspace*{0.25in} This manual corresponds to Magic version 7.4 \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Tutorials to read first:} \starti \> Preferably all of them. \endi {\noindent\bfseries\large Commands introduced in this manual:} \starti \> {\itshape (None)} \endi {\noindent\bfseries\large Macros introduced in this manual:} \starti \> {\itshape (None)} \endi \vspace*{0.75in} \section{Introduction} This document provides some information to help system administrators and would-be Magic maintainers learn about the system. Before doing anything to the internals of Magic, you should read at least the first, and perhaps all four, of the papers on Magic that appeared together in the {\itshape 1984 Design Automation Conference}. In addition, the following portions of magic have their own papers: \starti \> {\bfseries extractor} \ii {\itshape 1985 Design Automation Conference}, page 286. \\ \> {\bfseries channel router} \ii {\itshape 1985 Chapel Hill Conference on VLSI}, page 145. \\ \> {\bfseries irouter and mzrouter} \ii {\itshape 1988 Design Automation Conference}, page 672. \\ \> {\bfseries resistance extractor} \ii {\itshape 1987 Design Automation Conference}, page 570. \endi These documents are available from the Magic websites, which are another useful source of information regarding the program: \starti \> {\bfseries\ttfamily http://vlsi.cornell.edu/magic} \\ \> {\bfseries\ttfamily http://opencircuitdesign.com/magic} \endi The source for Magic can be downloaded from either website. Currently, the stable distribution release of Magic is version 7.4, and development version is 7.5. This documentation refers to features of the stable distribution version. For compilation instructions for the development version, please refer to the documentation in that distribution. This document corresponds specifically to version 7.4. \section{Compiling and Installing Magic} The download file comes in tarred, gzipped format. Normally, one will follow the standard procedure to uncompress and expand: \starti \ii tar xzf magic-7.4.0.tar.gz \\ \ii cd magic-7.4.0 \endi \section{Magic-7.4 Compile and Install} Magic 7.4 has a GNU ``autoconf'' method which automates most of the configuration process. The compile and install process is thereby simplified to the following: \starti \ii ./configure \\ \ii make \\ \ii make install \endi The autoconf process makes an effort to find the libraries and include files needed, including Tcl/Tk and OpenGL, and will compile Magic with support for these options unless they are specifically prohibited by an option to the {\ttfamily configure} script. Options may also be used to specify where libraries and include files may be found, if they are in a nonstandard location and the {\ttfamily configure} script is unable to find them. A full list of available options can be obtained by typing: \starti \ii ./configure --help \endi The Tcl interpreter makes Magic a {\itshape package extension} of the Tcl language, rather than being embedded. Tcl is largely compatible with Magic's existing command-line syntax, so Magic's command-line parser is simply given over to Tcl, and its graphics given over to Tk, the graphics interface for Tcl. The Tcl version makes a GUI available for Magic, and provides numerous extensions to the program. However, all critical functions are available with or without any compiled interpreter. The shell environment variable {\bfseries CAD{\_}HOME} exists as an override to the install path, so that Magic can be redirected to find its runtime files in a directory other than the location specified at compile time. Generally, unless you know what you're doing, having an environment variable {\bfseries CAD{\_}HOME} is probably a bad idea. In versions prior to 7.2, it was necessary to have this set before running the program, so on systems that have had an older version of magic installed, user's startup files may contain such variable declarations, which should be removed. \section{Source Directory Structure} \label{structure} There are many source subdirectories in Magic. Most of these consist of modules of source code for the system, for example {\bfseries database}, {\bfseries cif}, and {\bfseries utils}. See Section~\ref{modules} of this document for brief descriptions of what's in each source directory. Besides the source code, the other subdirectories are: \begin{itemize} \item {\bfseries doc} \\ Contains sources for all the documentation, including {\itshape man} pages, tutorials, and maintenance manuals. Subdirectories of {\bfseries doc}, e.g. {\bfseries doc/scmos}, contain some (outdated) technology manuals. The Makefile in each directory can be used to run off the documentation. The tutorials, maintenance manuals, and technology manuals all use LaTeX, which means that you will need the LaTeX package to recompile the manuals from source. Documentation is also available online in HTML format. \item {\bfseries magic} \\ In addition to the source main() routine used for the non-Tcl-based compile option, this directory is where the modules of Magic are linked to form the executable version of the system. \end{itemize} Magic is a relatively large system: there are around 575 source files, and 250,000 lines of C code. In order to make all of this manageable, we've organized the sources in a two-level structure. Each module has its own subdirectory, and you can make changes to the module and recompile it by working within that subdirectory. There are two mailing lists associated with Magic development: \begin{enumerate} \item {\ttfamily magic-hackers@csl.cornell.edu} is for general news and discussions about the development process. \item {\ttfamily magic-dev@csl.cornell.edu} is for developers only and provides feedback on any CVS changes made in the repository. \end{enumerate} \section{Compiling and Installing } The top-level Makefile (\~{}cad/src/magic/Makefile) provides many options. The most useful Makefile options are: \begin{itemize} \item {\bfseries make magic} \\ Make a version of Magic. All sub-modules are remade, if needed, and then the final magic binary is produced. \item {\bfseries make everything} \\ Same as ``make magic''. Both options make auxilary programs like {\bfseries ext2sim} and {\bfseries ext2spice}. \item {\bfseries make force} \\ Force recompilation. Like a ``make everything'', except that object files are first removed to force complete recompilation from scratch. \item {\bfseries make clean} \\ Delete files that can be remade, such as binaries, object, and library files. \item {\bfseries make veryclean} \\ A more complete cleanup, that removes the current configuration in addition to the files removed int the {\bfseries make clean} step. \item {\bfseries make install} \\ Install the Magic binaries and run-time library files. For Tcl, install the Magic shared-object files in the lib directory, and install a shell script as the ``magic'' executable. \end{itemize} Putting together a runnable Magic system proceeds in two steps after a source file has been modified. First, the source file is compiled, and all the files in its module are linked together into a single file {\itshape xyz}{\bfseries .o}, where {\itshape xyz} is the name of the module. Then all of the modules are linked together to form an executable version of Magic. The command {\bfseries make} in each source directory will compile and link the module locally; {\bfseries make install} will compile and link it. All Makefiles are set up to use the compiler flags found in the source top-level directory file {\bfseries defs.mak}. \section{Summary of Magic Modules} \label{modules} This section contains brief summaries of what is in each of the Magic source subdirectories. A number of files and directories were shifted around in the development of version 7.4, so this list has been updated accordingly. \begin{itemize} \item {\bfseries calma} \\ Contains code to read and write Calma (GDS-II) Stream-format files. It uses many of the procedures in the {\bfseries cif} module. \item {\bfseries cif} \\ Contains code to process the CIF sections of technology files, and to generate CIF files from Magic. \item {\bfseries cmwind} \\ Contains code to implement special windows for editing color maps. \item {\bfseries commands} \\ The procedures in this module contain the top-level command routines for layout commands (commands that are valid in all windows are handled in the {\bfseries windows} module). These routines generally just parse the commands, check for errors, and call other routines to carry out the actions. \item {\bfseries database} \\ This is the largest and most important Magic module. It implements the hierarchical corner-stitched database, and reads and writes Magic files. \item {\bfseries dbwind} \\ Provides display functions specific to layout windows, including managing the box, redisplaying layout, and displaying highlights and feedback. \item {\bfseries debug} \\ There's not much in this module, just a few routines used for debugging purposes. \item {\bfseries drc} \\ This module contains the incremental design-rule checker. It contains code to read the {\bfseries drc} sections of technology files, record areas to be rechecked, and recheck those areas in a hierarchical fashion. \item {\bfseries ext2sim} \\ This is another self-contained program. It's a self-contained program that flattens the hierarchical {\bfseries .ext} files generated by Magic's extractor into a single file in {\bfseries .sim} format. See the manual page {\bfseries ext2sim~(1)}. \item {\bfseries ext2spice} \\ This is another self-contained program. It converts {\bfseries .ext} files into single file in spice format. See the manual page {\bfseries ext2spice~(1)}. \item {\bfseries extcheck} \\ Yet another independent program. This one checks the {\bfseries .ext} files for global node connectivity and summarizes the number of FETs, nodes, etc. See the manual page {\bfseries extcheck~(1)}. \item {\bfseries extflat} \\ Contains code that is used by the {\bfseries extract} module and the {\bfseries ext2\dots} programs. The module produces a library that is linked in with the above programs. \item {\bfseries extract} \\ Contains code to read the {\bfseries extract} sections of technology files, and to generate hierarchical circuit descriptions ({\bfseries .ext} files) from Magic layouts. \item {\bfseries gcr} \\ Contains the channel router, which is an extension of Rivest's greedy router that can handle switchboxes and obstacles in the channels. \item {\bfseries graphics} \\ This is the lowest-level graphics module. It contains driver routines for X11 and OpenGL as well as the equivalent versions for use with Tk graphics under the Tcl-interpreter based version of Magic. If you want to make Magic run on a new kind of display, this is the only module that should have to change. \item {\bfseries grouter} \\ The files in this module implement the global router, which computes the sequence of channels that each net is to pass through. \item {\bfseries irouter} \\ Contains the interactive router written by Michael Arnold at Lawrence Livermore National Labs. This router allows the user to route nets interactively, using special hint layers to control the routing. \item {\bfseries lef} \\ This module contains the LEF and DEF file format handling routines. \item {\bfseries lisp} \\ This module contains code which, if the SCHEME option is chosen at compile time, implements the lisp-like ``scheme'' interpreter. Scheme enables magic commands to be executed in a programming language framework, so complex functions can be defined. \item {\bfseries magic} \\ Contains the C {\bfseries main()} routine, and, alternatively, the Tcl initialization functions which replace it in the Tcl shared-object extensions. Also contains all of the Tcl interpreter supporting code, such as the GUI wrapper, and the shell script which launches Magic. \item {\bfseries mzrouter} \\ Contains maze routing routines that are used by the irouter and garouter modules. \item {\bfseries net2ir} \\ Contains a program to convert a netlist into irouter commands. \item {\bfseries netmenu} \\ Implements netlists and the special netlist-editing windows. \item {\bfseries oa} \\ A very spare framework for an experimental interface to the OpenAccess database. This is barely functional and is not enabled by the default configuration. \item {\bfseries plot} \\ The internals of the {\bfseries plot} command. Code to write PostScript and rendered PNM output formats. Disabled legacy code exists for the raw pixel, versatec, and gremlin formats, which may be compiled in by adding the appropriate definitions to the {\bfseries defs.mak} file. \item {\bfseries plow} \\ This module contains the code to support the {\bfseries :plow} and {\bfseries :straighten} commands. \item {\bfseries readline} \\ ``readline'' is an independent library of routines implementing command-line history and editing. Version 7.4 of magic uses GNU readline-4.3. \item {\bfseries resis} \\ Resis is a module that does better resistance extraction via the :extresis command. Courtesy of Don Stark of Stanford. \item {\bfseries router} \\ Contains the top-level routing code, including procedures to read the router sections of technology files, chop free space up into channels, analyze obstacles, and paint back the results produced by the channel router. \item {\bfseries scripts} \\ This is not a module, but contains all of the shell scripts used by the make process. \item {\bfseries select} \\ This module contains files that manage the selection. The routines here provide facilities for making a selection, enumerating what's in the selection, and manipulating the selection in several ways, such as moving it or copying it. \item {\bfseries sim} \\ Provides an interactive interface to the simulator rsim. Courtesy of Mike Chow of Stanford. \item {\bfseries tcltk} \\ Contains the principle code used for the interface to the Tcl/Tk interpreter, the Tcl scripts that are used by the interface, and the startup scripts. Note that much of the Tcl/Tk calls are scattered throughout the code, especially in the {\bfseries graphics} and {\bfseries commands} subdirectories. \item {\bfseries textio} \\ The top-level command interpreter. This module grabs commands from the keyboard or mouse and sends them to the window module for processing. Also provides routines for message and error printout, and to manage the prompt on the screen. \item {\bfseries tiles} \\ Implements basic corner-stitched tile planes. This module was separated from {\bfseries database} in order to allow other clients to use tile planes without using the other database facilities too. \item {\bfseries utils} \\ This module implements a whole bunch of utility procedures, including a geometry package for dealing with rectangles and points and transformations, a heap package, a hash table package, a stack package, a revised memory allocator, the argument parser (formerly in module ``parser''), the initialization routines (formerly in module ``main''), the netlist handler (not associated with the ``netmenu'' module), the undo/redo handler, the technology reading code (formerly in module ``tech''), and lots of other stuff. \item {\bfseries windows} \\ This is the overall window manager. It keeps track of windows and calls clients (like {\bfseries dbwind} and {\bfseries cmwind}) to process window-specific operations such as redisplaying or processing commands. Commands that are valid in all windows, such as resizing or moving windows, are implemented here. \item {\bfseries wiring} \\ The files in this directory implement the {\bfseries :wire} command. There are routines to select wiring material, add wire legs, and place contacts. \end{itemize} \section{Portability Issues} \label{porting} Magic runs on a variety of machines. Running ``configure'' in the top-level source directory sets the compile-time options. If you are porting Magic, you will probably need to modify the file {\bfseries scripts/configure.in} to define the proper compile-time flags for your machine. No changes should be made that would hamper Magic's operation on other machines. Process the {\bfseries configure.in} file by doing {\bfseries cd scripts; autoconf}. Note that the {\bfseries automake} program is not used in this process. The {\bfseries configure} script is directed to produce not a Makefile, as usual, but to produce the {\bfseries defs.mak} file which is included by the Makefile. The top-level directory script {\bfseries configure} is a shell script wrapper for the actual autoconf-generated file {\bfseries scripts/configure}. The indirect call serves two purposes: All of the extra scripts required by autoconf can be kept in the {\bfseries scripts} subdirectory, and also the {\bfseries CFLAGS} environment variable can be set, allowing the compiler optimization flag to be disabled, resulting in an executable which is probably marginally slower, but much easier to debug. \section{Technology and Other Support Files} Besides the source code files, there are a number of other files that must be managed by Magic maintainers, including color maps, technology files, and other stuff. Below is a listing of those files and where they are located. \subsection{Technology Files} See ``Magic Maintainer's Manual\ \#2: The Technology File'' for information on the contents of technology files. The sources for technology files are contained in the subdirectory {\bfseries tech}, in files like {\bfseries scmos.tech} and {\bfseries nmos.tech}. The technology files that Magic actually uses at runtime are kept in the directory {\bfseries /usr/local/lib/magic/sys};%$ {\bfseries make install} in {\bfseries tech} will copy the sources to {\bfseries /usr/local/lib/magic/sys}.%$ The installed versions of technology files have the extension {\bfseries .tech}. Historically, the techfile format version was embedded in the filename. The last version number to use this (27), is still accepted as a valid techfile filename (for example, {\bfseries nmos.tech27}, where {\bfseries 27} is a version number). Now, the format number appears in the ``tech'' section of the tech file (the first section declared) as, e.g., ``format 28''. Future changes to the tech version are expected to be backwardly compatible to version 27, should query the format version from the file, and make adjustments as necessary to the read-in for backward compatibility. The technology files that are compiled and installed with the magic distribution are long outdated and useful mainly for demonstration purposes. A set of technology files corresponding to existing fabrication processes is available from Jeff Sondeen at ISI. Others are available from the Magic website, and from MOSIS. \subsection{Display Styles} The display style file sources are contained in the source directory {\bfseries graphics}. See ``Magic Maintainer's Manual\ \#3: The Display Style and Glyph Files'' and the manual page {\itshape dstyle}~(5) for a description of their contents. {\bfseries Make install} in {\bfseries graphics} will copy the files to {\bfseries /usr/local/lib/magic/sys}, which is where Magic looks for them when it executes. \subsection{Glyph Files} Glyph files are described in Maintainer's Manual\ \#3 and the manual page {\itshape glyphs}~(5); they define patterns that appear in the cursor. The sources for glyph files appear in two places: some of them are in {\bfseries graphics}, in files like {\bfseries color.glyphs}, and some others are defined in {\bfseries windows/window}{\itshape XX}{\bfseries .glyphs}. When you {\bfseries make install} in those directories, the glyphs are copied to {\bfseries /usr/local/lib/magic/sys},%$ which is where Magic looks for them when it executes. \subsection{Color Maps} The color map sources are also contained in the source directory {\bfseries graphics}. Color maps have names like {\bfseries mos.7bit.std.cmap}, where {\bfseries mos} is the name of the technology style to which the color map applies, {\bfseries 7bit} is the display style, and {\bfseries std} is a type of monitor. If monitors have radically different phosphors, they may require different color maps to achieve the same affects. Right now we only support the {\bfseries std} kind of monitor. When Magic executes, it looks for color maps in {\bfseries /usr/local/lib/magic/sys};%$ {\bfseries make install} in {\bfseries graphics} will copy them there. Although color map files are textual, editing by hand is undesirable; use Magic's color map editing window instead. \section{New Display Drivers} The most common kind of change that will be made to Magic is probably to adapt it for new kinds of color displays. Each display driver contains a standard collection of procedures to perform basic functions such as placing text, drawing filled rectangles, or changing the shape of the cursor. A table (defined in {\bfseries graphics/grMain.c}) holds the addresses of the routines for the current display driver. At initialization time this table is filled in with the addresses of the routines for the particular display being used. All graphics calls pass through the table. If you have a display other than the ones currently defined (X11 and OpenGL/GLX), and you want to build a new display driver, we recommend starting with the routines for the X11 (all the files in {\bfseries graphics} named {\bfseries grX11su}{\itshape n}{\bfseries .c}). Copy the files into a new set for your display, change the names of the routines, and modify them to perform the equivalent functions on your display. Write an initialization routine like {\bfseries x11suSetDisplay}, and add information to the display type tables in {\bfseries graphics/grMain.c}. At this point you should be all set. There shouldn't be any need to modify anything outside of the graphics module. \section{Debugging} Magic works fine under GNU {\bfseries gdb}. The Makefiles are set up to compile all files with the {\bfseries -g} switch, which creates debugging information. When Magic is compiled under the Tcl interpreter, however, one cannot run, e.g., ``{\bfseries gdb magic},'' because the magic executable is a script. The proper way to run Tcl-based magic under a debugger is the following: \starti \ii set pid=`ps --no-headers -o pid= -C wish` \\ \ii gdb program $pid \endi which is a simple invocation for Linux systems. If it is not possible to get {\bf ps} to return a single process ID, the process ID can be obtained visually from the {\bf ps} command and given to {\bf gdb} as the process ID to attach to: \starti \ii ps -C wish \ii gdb program {\itshape process_ID} \endi wher the first command returns {\itshape process_ID}, the process ID of the {\bfseries wish} process. If the version of {\bfseries ps} on your system does not support the {\bfseries -C} option, there are other options that will report the {\bfseries wish} process. Because this method attaches to an already running program, this method does not work for capturing errors that occur during program startup. Note, however, that errors occurring during technology loading can be captured by attaching to the running process, then giving the command ``{\bfseries tech load [tech filename]}'' to magic. Otherwise, the procedure to attach to the process prior to initialization is the following: \starti \ii gdb wish \ii run \ii set argc 3 \ii set argv \{-w -d OGL\} \ii source /usr/local/lib/magic/tcl/magic.tcl \endi Note the necessity of setting variables {\bfseries argc} and {\bfseries argv} within Tcl to get the startup script to process them as if they were command-line arguments passed from the shell. Any valid command-line arguments may be passed in this manner. The debugger prompt can be reached by typing Ctrl-C. Note that the Tk console window is not available when debugging, a minor inconvenience. \end{document} magic-8.0.210/doc/latexfiles/manual.tex0000644000175000001440000000424610751423606016370 0ustar timusers%---------------------------------------------------------------------------- % Magic User's Manual %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{book} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Magic Tutorial \#X: Title_goes_here} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \begin{frontmatter} \tableofcontents \listoffigures \listoftables \end{frontmatter} \chapter Overview \input{introduction.tex} \chapter Manual Pages---Section 1 (Programs) \chapter Manual Pages---Section 3 (Libraries) \chapter Manual Pages---Section 5 (File Formats) \chapter Manual Pages---Section 8 (System Maintenance) \chapter Tutorials \input{tut1.tex} \input{tut2.tex} \input{tut3.tex} \input{tut4.tex} \input{tut5.tex} \input{tut6.tex} \input{tut7.tex} \input{tut8.tex} \input{tut9.tex} \input{tut10.tex} \input{tut11.tex} \input{tutwrl1.tex} \input{tutscm1.tex} \input{tutscm2.tex} \input{tutscm3.tex} \input{tutscm4.tex} \chapter Maintainer's Manuals \input{maint1.tex} \input{maint2.tex} \input{maint3.tex} \input{maint4.tex} \chapter Technology Manuals \appendix \chapter Other Reports In This Series \end{document} magic-8.0.210/doc/latexfiles/tutscm3.tex0000644000175000001440000001333310751423606016512 0ustar timusers%---------------------------------------------------------------------------- % Magic tutorial number S-3 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Magic Tutorial \#S-3: Transistor stacks} \def\q{\special{ps:(") show}\hspace*{0.6em}} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape Rajit Manohar} \\ \vspace*{0.5in} Department of Computer Science \\ California Institute of Technology \\ Pasadena, CA 91125 \\ \vspace*{0.25in} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Tutorials to read first:} \starti \> Magic Tutorial \#S-1: The scheme command-line interpreter \endi {\noindent\bfseries\large Commands introduced in this tutorial:} \starti \> :stack.p, :stack.n, :stack.tallp, :stack.talln, :prs.draw, :prs.mgn, \\ \> :prs.talldraw, :prs.tallmgn \endi {\noindent\bfseries\large Macros introduced in this tutorial:} \starti \> {\itshape (None)} \endi \vspace*{0.75in} \section{Stacks} The first step in laying out a gate/operator using magic tends to involve drawing the transistor stacks without any wiring, labelling all the important nodes in the circuit. Since the extractor pretends that nodes that have the same label are electrically connected, the extracted circuit can be simulated using SPICE to obtain some indication of the power/speed of the circuit. {\bfseries stack.tallp} and {\bfseries stack.talln} can be used to draw such transistor stacks and place contacts where required. These two functions take a transistor width and a list of strings that represent the stack as their arguments, and draw the stack vertically (gates run horizontally) at the current box. For example, \starti \ii {\bfseries (stack.tallp 40 '(({\q}Vdd{\q}) {\q}a{\q} {\q}b{\q} ({\q}Inode{\q}) {\q}d{\q} ({\q}out{\q})))} \endi draws a vertical stack of p-transistors with the diffusion being 40 lambda wide. The stack begins with a contact labelled ``Vdd'', followed by two gates labelled ``a'' and ``b'', followed by a contact labelled ``Inode'', followed by a gate labelled ``d'', followed by a contact labelled ``out''. Contacts are indicated by placing the string for the label in parenthesis. Note the presence of the quote that prevents the interpreter from attempting to evaluate the list. The contact width and contact-gate spacing together amount to more than the spacing between adjacent gates. Often it is desired to eliminate this extra space by jogging the poly wires so that the amount of internal diffusion capacitance is minimized. The functions {\bfseries stack.p} and {\bfseries stack.n} can be used to do so. Typing \starti \ii {\bfseries (stack.tallp 40 '(({\q}Vdd{\q}) {\q}a{\q} {\q}b{\q} ({\q}Inode{\q}) {\q}d{\q} ({\q}out{\q})))} \endi will draw the same stack and jog the poly wires corresponding to the gate for ``d''. \section{Production rules} The functions {\bfseries prs.draw} and {\bfseries prs.mgn} can be used to draw the transistor stacks that implement a production rule. For instance, \starti \ii {\bfseries (prs.draw 40 {\q}x \& y $->$ z-{\q})} \endi will draw the stack required to implement the specified production rule with width 20. The function takes a gate width and a single production rule as its arguments. Note that the production rules must be in negation normal form, i.e., all negations must be on variables. Contacts can be shared between operators by providing a list of production rules as input to {\bfseries prs.mgn}, as follows: \starti \ii {\bfseries (prs.mgn 40 20 {\q}x \& y $->$ z-{\q} {\q}u \& v $->$ w-{\q} {\q}\~{}x \& \~{}y $->$ z+{\q})} \endi The contact to GND will be shared between the pull-down stacks for z and w. Both production-rule drawing function ensure that the variable order in the production rule (from left to right) corresponds to the gate order in the transistor stacks (from power supply to output). It is not always possible to directly draw a production rule in a single stack with no additional internal contacts. In this case, the function creates an internal node name of the form ``{\_}'' followed by a number. You can search for these using {\bfseries (label.search {\q}{\_}*{\q})}, followed by {\bfseries (label.find-next)}. To complete the implementation, you will have to wire up these internal contacts as well. Both {\bfseries prs.mgn} and {\bfseries prs.draw} draw the transistor stacks using {\bfseries stack.p} and {\bfseries stack.n}. The variants {\bfseries prs.tallmgn} and {\bfseries prs.talldraw} use {\bfseries stack.tallp} and {\bfseries stack.talln} instead. \end{document} magic-8.0.210/doc/latexfiles/maint2.tex0000644000175000001440000045541311226771523016315 0ustar timusers%---------------------------------------------------------------------------- % Magic Maintainer's Manual #2 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times,pifont} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\I{\hinch} \def\II{\I\I} \def\vns{\vspace*{-0.05in}} \def\mytitle{Magic Maintainer's Manual \#2: The Technology File} \def\q{\special{ps:(") show}\hspace*{0.6em}} \def\grt{\hspace*{0.3em}\special{ps:(>) show}\hspace*{0.3em}} \def\bk{\special{ps:/bksp 2 string def bksp 0 92 put bksp show}\hspace*{0.4em}} \def\vbar{$|$} \newcommand{\micro}{\Pifont{psy}m} \newcommand{\ohms}{\Pifont{psy}W} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape Walter Scott} \\ \vspace*{0.25in} Special Studies Program \\ Lawrence Livermore National Laboratory \\ P.O. Box 808, L-270 \\ Livermore, CA 94550 \\ \vspace*{0.25in} {\itshape John Ousterhout} \\ \vspace*{0.25in} Computer Science Division \\ Electrical Engineering and Computer Sciences \\ University of California \\ Berkeley, CA 94720 \\ \vspace*{0.25in} {\itshape (Updated by others, too.)} \\ \vspace*{0.25in} This manual corresponds to Magic version 7.4 and technology format 30 \end{center} \vspace*{0.25in} {\noindent\bfseries\large Tutorials to read first:} \starti \> Magic Tutorial \#1: Getting Started \\ \> Magic Tutorial \#2: Basic Painting and Selection \\ \> Magic Tutorial \#6: Design-Rule Checking \\ \> Magic Tutorial \#8: Circuit Extraction \\ \> Magic Tutorial \#9: Format Conversion for CIF and Calma \endi \noindent You should also read at least the first, and probably all four, of the papers on Magic that appeared in the {\itshape ACM IEEE 21st Design Automation Conference}, and the paper ``Magic's Circuit Extractor'', which appeared in the {\itshape ACM IEEE 22nd Design Automation Conference}. The overview paper from the DAC was also reprinted in {\itshape IEEE Design and Test} magazine in the February 1985 issue. The circuit extractor paper also appeared in the February 1986 issue of {\itshape IEEE Design and Test} magazine. {\noindent\bfseries\large Commands introduced in this manual:} \starti \> path \> tech \> *watch \endi {\noindent\bfseries\large Macros introduced in this manual:} \starti \> {\itshape (None)} \endi {\noindent\bfseries\large Changes since Magic version 7.2:} \begin{itemize} \item Support for stacked contacts. \item ``variants'' option for the cifinput, cifoutput, and extract sections, allowing an efficient description of different styles having minor variations. \item Supports names for layer drawing styles in addition to the usual numbers. \item Section name {\bfseries images} duplicates the {\bfseries contacts} section, allowing a less-restrictive definition of images that exist, like contacts, on multiple planes. \item Support for multi-line technology descriptions. \item ``include'' statement to divide technology files into parts. \item ``alias'' statements to replace the original cpp-style macros \item Support for {\itshape angstroms} in the scalefactor line of cifinput and cifoutput. \item Additional DRC types ``surround'', ``overhang'', and ``rect\_only''. \item Additional cifoutput operators ``slots'' and ``bloat-all''. \item Additional cifoutput statement ``render'' for 3-D information \item Asterisk syntax for layers that expands to the layer and all of the contacts containing that layer as a residue. \item The technology file syntax for the PNM format was changed in magic 7.3.56, and the {\bfseries plot pnm} command will use a default style derived from the layout styles if no section is present in the technology file. \end{itemize} {\noindent\bfseries\large Changes since Magic version 6.5:} \begin{itemize} \item Moved technology format from the filename to the ``tech'' section \item Added subdirectory searching to the path search for technology files. \item Support for technology file re-loading after Magic starts up, and support for re-loading of individual sections of the technology file. \item Scalefactors can now be any number whatsoever, for both CIF and GDS. For example, a scalefactor of 6.5 corresponds to a 0.13 micron process. \item A parameter {\itshape nanometers} has been added to the scalefactor specification for both cifinput and cifoutput sections. This parameter declares that all numbers in the style description are in nanometers instead of centimicrons. \item The {\itshape calmaonly} parameter to the scalefactor specification is deprecated (ignored if found). \item The scale reducer parameter is deprecated (generated automatically, and ignored if found in the techfile). \item The magic grid spacing is no longer assumed to be equal to the process lambda. It may be rescaled with the ``scalegrid'' command, and CIF and Calma reads may alter the value of magic units per lambda. \item Support for PNM and PostScript graphics in the ``plot'' section. \item Full support for bipolar junction transistors, capacitors, and resistors with the ``extract'' section keyword ``device'' \item Support for three-dimensional modeling and geometry extraction \item Support for the DRC widespacing rule \item Handling of contacts in the extraction section is capable of matching the CIF output section by specifying border, size, and spacing. \end{itemize} \vspace*{0.25in} \section{Introduction} Magic is a technology-independent layout editor. All technology-specific information comes from a {\itshape technology file}. This file includes such information as layer types used, electrical connectivity between types, design rules, rules for mask generation, and rules for extracting netlists for circuit simulation. This manual describes the use, contents, and syntax of Magic's technology file format, and gives hints for building a new one or (more typically) rewriting an existing one for a new fabrication process. References to specific files in the Magic distribution assume that your current working directory is the Magic source top-level directory. \section{Downloads and Installation} Typically, there is a different technology file for each fabrication process supported by Magic. Scalable technologies, which are (within limits) independent of feature size, will typically have one technology file for all processes supporting the same set of lambda-based (scalable) DRC rules. That said, modern technologies (post-1980's, more or less) tend to be more restrictive in their design rules, and consequently not scalable. This is particularly true of processes which push the envelope on feature sizes. The Magic source distribution is packaged with a ``standard'' set of scalable SCMOS rules, which is the technology loaded by default. Default settings are for 1\,{\micro}m technology, which is out of date. However, the variety and availability of processes means that the ``definitive'' set of technology files is prohibitively large to be included with the Magic source. In addition, process refinements generally require technology file updates on a regular basis. Because of this, the basic collection of technology files is handled by the MOSIS foundation, not by the Magic development team. This collection represents all processes which are available for fabriction through the MOSIS foundation. Most other vendors have proprietary process specifications, requiring tool maintainers to write their own technology files or modify an existing one to match the proprietary process. The standard technology file set can be downloaded from an FTP server at the MOSIS foundation. These files are regularly updated, but there is usually a symbolic link called ``current'' to the most recent stable revision. The download URL is the following: \starti \> {\ttfamily\bfseries ftp://ftp.mosis.edu/pub/sondeen/magic/new/beta/current.tar.gz} \endi Assuming that the install destination for magic is {\bfseries /usr/local}, this file should be put either in {\bfseries /usr/local/lib/magic/sys} or (preferably) in {\bfseries /usr/local/lib/magic/sys/current}. Other destinations may be used, if the system search path is appropriately specified on startup (see Section~\ref{commandline}, below). The technology file collection is in tarred, gzipped format, and should be installed with the following commands: \starti \ii {\ttfamily\bfseries cd /usr/local/lib/magic/sys/current} \\ \ii {\ttfamily\bfseries gunzip current.tar.gz} \\ \ii {\ttfamily\bfseries tar xf current.tar} \endi Once unpacked, these files are ready to be used in Magic. \section{Command-Line Invocation} \label{commandline} You can run Magic with a different technology by specifying the {\bfseries -T}{\itshape techfile} flag on the command line you use to start Magic, where {\itshape techfile} is the name of a file of the form {\itshape techname}{\bfseries .tech}, searched for in one of the following directories (listed by search order): \begin{enumerate} \item The current directory \item The library directory /usr/local/lib/magic/sys \item The library directory /usr/local/lib/magic/current \end{enumerate} This search order is not fixed and can be altered by the command {\bfseries path sys}, which may be redefined in the system or user {\bfseries .magic} startup script file. In addition, the startup script may load a new techfile, regardless of what was specified on the command line, or may load a new techfile provided that one has not been specified on the command line (the {\bfseries -nooverride} option. The {\bfseries -noprompt} switch causes the technology to be loaded without first prompting the user for confirmation. \starti \ii {\bfseries tech load} {\itshape filename} {\bfseries -noprompt} [{\bfseries -nooverride}] \endi \section{Technology File Format Overview} A technology file is organized into sections, each of which begins with a line containing a single keyword and ends with a line containing the single word {\bfseries end}. If you examine one of the Magic technology files in the installation directory {\bfseries \$}\{{\bfseries CAD\_HOME}\}{\bfseries /lib/magic/sys/}, {\itshape e.g.}, {\bfseries scmos.tech}, you can see that it contains the following sections: \starti \ii {\bfseries tech} \\ \ii {\bfseries planes} \\ \ii {\bfseries types} \\ \ii {\bfseries styles} \\ \ii {\bfseries contact} \\ \ii {\bfseries compose} \\ \ii {\bfseries connect} \\ \ii {\bfseries cifoutput} \\ \ii {\bfseries cifinput} \\ \ii {\bfseries mzrouter} \\ \ii {\bfseries drc} \\ \ii {\bfseries extract} \\ \ii {\bfseries wiring} \\ \ii {\bfseries router} \\ \ii {\bfseries plowing} \\ \ii {\bfseries plot} \endi These sections must appear in this order in all technology files. Every technology file must have all of the sections, although the sections need not have any lines between the section header and the {\bfseries end} line. Historically, technology files were written in a C-language context which was processed by the C preprocessor. This allows the use of C-language comments (``{\bfseries /*} \dots {\bfseries */}'') and the use of preprocessing definitions (``{\bfseries \#define} \dots'') and conditionals (``{\bfseries \#ifdef} \dots {\bfseries \#endif}''). The technology files were generated from a Makefile with the preprocessor constructs used to generate different sections of the technology file at different lambda scales. The decreasing use of scalable processes, however, has made this method largely obsolete, and the standard collection of technology files from MOSIS does not use them at all. Technology files are now written in their final form, not in preprocessed form. Information regarding preprocessor constructs is not included below, but can of course be obtained from the manual pages for the preprocessor itself ({\bfseries gcc} or {\bfseries cpp}). But also note that the use of C preprocessors for processing text files other than source code is now generally discouraged in favor of using a macro definition processor like {\bfseries m4} (see the manual page for {\bfseries m4} for details). On the other hand, macro definition processors are almost universally despised, so many preprocessor functions have been written into the technology file syntax. The default {\bfseries scmos} set of technology files included with the Magic distribution is still processed via the C preprocessor. Preprocessed files have the extension ``{\bfseries .tech.in}''. Technology files written specifically for Magic version 7.3 tend to make use of additional features of the technology file syntax that subsume most of the functions of the C preprocessor and M4 processor normally used to generate technology files. Each section in a technology file consists of a series of lines. Each line consists of a series of words, separated by spaces or tabs. If a line ends with the character ``{\bk}'', the ``{\bk}'' is ignored and the following newline is treated as an ordinary blank. For example, \starti \ii {\bfseries width allDiff 2 {\bk}} \\ \ii\> {\itshape {\q}Diffusion width must be at least 2{\q}} \endi is treated as though it had all appeared on a single line with no intervening ``{\bk}''. On the other hand, for the purposes of tracking errors in technology file input, the technology file parser treats these as separate lines, so that when magic reports an error on a specific line of the technology file, it will agree with the line numbering of the editor used to edit the file. Comments may be embedded in the technology file. Magic's technology file parser will ignore all text beginning with the character {\bfseries \#} through the end of the line. The rest of this part of the manual will describe each of the technology file sections in turn. \section{Tech section} Magic stores the technology of a cell in the cell's file on disk. When reading a cell back in to Magic from disk, the cell's technology must match the name of the current technology, which appears as a single word in the {\bfseries tech} section of the technology file. See Table~1 for an example. \begin{table}[ht] \begin{center} \begin{tabular}{|l|} \hline {\bfseries tech} \\ format 30 \\ scmos \\ {\bfseries end} \\ \hline \end{tabular} \caption {{\bfseries Tech} section} \end{center} \label{tech} \end{table} The name of the technology declared in the {\bfseries tech} section is meaningful to Magic, whereas the name of the file itself is not. Typically the name of the file will be the same as the name of the technology, to avoid confusion, but this need not be the case. Versions of magic prior to 7.2 embedded the format version of the technology in the file name, {\itshape e.g.}, {\bfseries scmos.tech27}. The last format version to use this syntax, 27, is still accepted as a valid filename extension. Many technology files still use this notation, including (at the time of writing) the collection from MOSIS. Now the format is declared inside the {\bfseries tech} section. \section{A short tutorial on ``corner stitching''} The {\bfseries planes}, {\bfseries types}, and {\bfseries contact} sections are used to define the layers used in the technology. Magic uses a data structure called {\itshape corner-stitching} to represent layouts. Corner-stitching represents mask information as a collection of non-overlapping rectangular {\itshape tiles}. Each tile has a type that corresponds to a single Magic layer. An individual corner-stitched data structure is referred to as a {\itshape plane}. Magic allows you to see the corner-stitched planes it uses to store a layout. We'll use this facility to see how several corner-stitched planes are used to store the layers of a layout. Enter Magic to edit the cell {\bfseries maint2a}. Type the command {\bfseries *watch active demo}. You are now looking at the {\bfseries active} plane. Each of the boxes outlined in black is a tile. (The arrows are {\itshape stitches}, but are unimportant to this discussion.) You can see that some tiles contain layers (polysilicon, ndiffusion, ndcontact, polycontact, and ntransistor), while others contain empty space. Corner-stitching is unusual in that it represents empty space explicitly. Each tile contains exactly one type of material, or space. You have probably noticed that metal1 does not seem to have a tile associated with it, but instead appears right in the middle of a space tile. This is because metal1 is stored on a different plane, the {\bfseries metal1} plane. Type the command {\bfseries :*watch metal1 demo}. Now you can see that there are metal1 tiles, but the polysilicon, diffusion, and transistor tiles have disappeared. The two contacts, polycontact and ndcontact, still appear to be tiles. The reason Magic uses several planes to store mask information is that corner-stitching can only represent non-overlapping rectangles. If a layout were to consist of only a single layer, such as polysilicon, then only two types of tiles would be necessary: polysilicon and space. As more layers are added, overlaps can be represented by creating a special tile type for each kind of overlap area. For example, when polysilicon overlaps ndiffusion, the overlap area is marked with the tile type ntransistor. Although some overlaps correspond to actual electrical constructs (e.g., transistors), other overlaps have little electrical significance. For example, metal1 can overlap polysilicon without changing the connectivity of the circuit or creating any new devices. The only consequence of the overlap is possibly a change in parasitic capacitance. To create new tile types for all possible overlapping combinations of metal1 with polysilicon, diffusion, transistors, etc. would be wasteful, since these new overlapping combinations would have no electrical significance. Instead, Magic partitions the layers into separate planes. Layers whose overlaps have electrical significance must be stored in a single plane. For example, polysilicon, diffusion, and their overlaps (transistors) are all stored in the {\bfseries active} plane. Metal1 does not interact with any of these tile types, so it is stored in its own plane, the {\bfseries metal1} plane. Similarly, in the scmos technology, metal2 doesn't interact with either metal1 or the active layers, so is stored in yet another plane, {\bfseries metal2}. Contacts between layers in one plane and layers in another are a special case and are represented on {\itshape both} planes. This explains why the pcontact and ndcontact tiles appeared on both the {\bfseries active} plane and on the {\bfseries metal1} plane. Later in this section, when the {\bfseries contacts} section of the technology file is introduced, we'll see how to define contacts and the layers they connect. \section{Planes, types, and contact sections} The {\bfseries planes} section of the technology file specifies how many planes will be used to store tiles in a given technology, and gives each plane a name. Each line in this section defines a plane by giving a comma-separated list of the names by which it is known. Any name may be used in referring to the plane in later sections, or in commands like the {\bfseries *watch} command indicated in the tutorial above. Table~\ref{planes} gives the {\bfseries planes} section from the scmos technology file. \begin{table}[ht] \begin{center} \begin{tabular}{|l|} \hline {\bfseries planes} \\ well,w \\ active,diffusion,polysilicon,a \\ metal1,m1 \\ metal2,m2 \\ oxide,ox \\ {\bfseries end} \\ \hline \end{tabular} \caption{{\bfseries Planes} section} \label{planes} \end{center} \end{table} Magic uses a number other planes internally. The {\bfseries subcell} plane is used for storing cell instances rather than storing mask layers. The {\bfseries designRuleCheck} and {\bfseries designRuleError} planes are used by the design rule checker to store areas to be re-verified, and areas containing design rule violations, respectively. Finally, the {\bfseries mhint}, {\bfseries fhint}, and {\bfseries rhint} planes are used for by the interactive router (the {\bfseries iroute} command) for designer-specified graphic hints. There is a limit on the maximum number of planes in a technology, including the internal planes. This limit is currently 64. To increase the limit, it is necessary to change {\bfseries MAXPLANES} in the file {\bfseries database/database.h.in} and then recompile all of Magic as described in ``Maintainer's Manual\ \#1''. Each additional plane involves additional storage space in every cell and some additional processing time for searches, so we recommend that you keep the number of planes as small as you can do cleanly. The {\bfseries types} section identifies the technology-specific tile types used by Magic. Table~\ref{types} gives this section for the scmos technology file. Each line in this section is of the following form: \starti \ii {\itshape plane names} \endi Each type defined in this section is allowed to appear on exactly one of the planes defined in the {\bfseries planes} section, namely that given by the {\itshape plane} field above. For contacts types such as {\bfseries pcontact}, the plane listed is considered to be the contact's {\itshape home} plane; in Magic 7.3 this is a largely irrelevant distinction. However, it is preferable to maintain a standard of listing the lowest plane connected to a contact as it's ``home plane'' (as they appear in the table). \begin{table}[ht] \begin{center} \begin{tabular}{|ll|} \hline {\bfseries types} & \\ active & polysilicon,red,poly,p \\ active & ndiffusion,green,ndiff \\ active & pdiffusion,brown,pdiff \\ metal1 & metal1,m1,blue \\ metal2 & metal2,m2,purple \\ well & pwell,pw \\ well & nwell,nw \\ active & polycontact,pcontact,pc \\ active & ndcontact,ndc \\ active & pdcontact,pdc \\ metal1 & m2contact,m2c,via,v \\ active & ntransistor,nfet \\ active & ptransistor,pfet \\ active & psubstratepcontact,ppcontact,ppcont,psc,ppc,pwc,pwcontact \\ active & nsubstratencontact,nncontact,nncont,nsc,nnc,nwc,nwcontact \\ active & psubstratepdiff,psd,ppdiff,ppd,pohmic \\ active & nsubstratendiff,nsd,nndiff,nnd,nohmic \\ metal2 & pad \\ oxide & glass \\ {\bfseries end} & \\ \hline \end{tabular} \caption{{\bfseries Types} section} \label{types} \end{center} \end{table} The {\itshape names} field is a comma-separated list of names. The first name in the list is the ``long'' name for the type; it appears in the {\bfseries .mag} file and whenever error messages involving that type are printed. Any unique abbreviation of any of a type's names is sufficient to refer to that type, both from within the technology file and in any commands such as {\bfseries paint} or {\bfseries erase}. Magic has certain built-in types as shown in Table~\ref{builtins}. Empty space ({\bfseries space}) is special in that it can appear on any plane. The types {\bfseries error{\_}p}, {\bfseries error{\_}s}, and {\bfseries error{\_}ps} record design rule violations. The types {\bfseries checkpaint} and {\bfseries checksubcell} record areas still to be design-rule checked. Types {\bfseries magnet}, {\bfseries fence}, and {\bfseries rotate} are the types used by designers to indicate hints for the irouter. \begin{table}[ht] \begin{center} \begin{tabular}{|l|l|} \hline Tile type & Plane \\ \hline\hline space & {\itshape all} \\ error{\_}p, EP & designRuleError \\ error{\_}s, ES & designRuleError \\ error{\_}ps, EPS & designRuleError \\ checkpaint, CP & designRuleCheck \\ checksubcell, CS & designRuleCheck \\ magnet, mag & mhint \\ fence, f & fhint \\ rotate, r & rhint \\ \hline \end{tabular} \caption{Built-in Magic types} \label{builtins} \end{center} \end{table} There is a limit on the maximum number of types in a technology, including all the built-in types. Currently, the limit is 256 tile types. To increase the limit, you'll have to change the value of {\bfseries TT{\_}MAXTYPES} in the file {\bfseries database/database.h.in} and then recompile all of Magic as described in ``Maintainer's Manual\ \#1''. Because there are a number of tables whose size is determined by the square of {\bfseries TT{\_}MAXTYPES}, it is very expensive to increase {\bfseries TT{\_}MAXTYPES}. Magic version 7.2 greatly reduced the number of these tables, so the problem is not as bad as it once was. Most internal tables depend on a {\itshape bitmask} of types, the consequence of which is that the internal memory usage greatly increases whenever {\bfseries TT{\_}MAXTYPES} exceeds a factor of 32 (the size of an integer, on 32-bit systems). Magic version 7.3 further alleviates the problem by reducing the number of ``derived'' tile types that magic generates internally, so that the total number of types is not much larger than the number declared in the {\bfseries types} section. Magic-7.4 only generates extra types for pairs of stackable contact types. For a typical process, the number of these derived stacked contact pairs is around 15 to 20. The declaration of tile types may be followed by a block of alias declarations. This is similar to the ``macro'' definitions used by preprocessors, except that the definitions are not only significant to the technology file parser, but extend to the user as well. Thus the statement ``{\bfseries alias metalstack m1,m2,m3}'' may be a convenient shorthand where metal layers 1, 2, and 3 appear simultaneously, but the end-user can type the command ``{\bfseries paint metalstack}'' and get the expected result of all three metal layers painted. The {\bfseries alias} statement has the additional function of allowing backward-compatibility for technology files making use of stackable contacts (see below) with older layouts, and cross-compatibility between similar technologies that may have slight differences in layer names. The {\bfseries contact} section lets Magic know which types are contacts, and the planes and component types to which they are connected. Each line in the {\bfseries contact} section begins with a tile type, {\itshape base}, which is thereby defined to be a contact. This type is also referred to as a contact's {\itshape base type}. The remainder of each line is a list of non-contact tile types that are connected by the contact. These tile types are referred to as the {\itshape residues} of the contact, and are the layers that would be present if there were no electrical connection ({\itshape i.e.}, no via hole). In Table~\ref{contacts}, for example, the type {\bfseries pcontact} is the base type of a contact connecting the residue layers {\bfseries polysilicon} on the active plane with {\bfseries metal1} on the metal1 plane. \begin{table}[ht] \begin{center} \begin{tabular}{|llll|} \hline {\bfseries contact} &&& \\ pcontact & poly & metal1 & \\ ndcontact & ndiff & metal1 & \\ pdcontact & pdiff & metal1 & \\ ppcontact & ppdiff & metal1 & \\ nncontact & nndiff & metal1 & \\ m2contact & metal2 & metal1 & \\ pad & metal1 & metal2 & glass \\ {\bfseries end} &&& \\ \hline \end{tabular} \caption{{\bfseries Contact} section} \label{contacts} \end{center} \end{table} In Magic-7.3 and above, any number of types can be connected, and those types may exist on any planes. It is the duty of the technology file developer to ensure that these connections make sense, especially if the planes are not contiguous. However, because Magic-7.3 handles stacked contacts explicitly, it is generally better to define contacts only between two adjacent planes, and use the {\bfseries stackable} keyword (see below) to allow types to be stacked upon one another. The multiple-plane representation exists for backward compatibility with technology files written for versions of Magic prior to 7.3. Stackable contacts in older technology files take the form: \starti \ii {\bfseries contact pc polysilicon metal1} \\ \ii {\bfseries contact m2c metal1 metal2} \\ \ii {\bfseries contact pm12c polysilicon metal1 metal2} \endi In Magic version 7.3, the above line would be represented as: \starti \ii {\bfseries contact pc polysilicon metal1} \\ \ii {\bfseries contact m2c metal1 metal2} \\ \ii {\bfseries stackable pc m2c pm12c} \endi where the third line declares that contact types m2c and pc may be stacked together, and that type name ``pm12c'' is a valid alias for the combination of ``pc'' and ``m2c''. Each contact has an {\itshape image} on all the planes it connects. Figure~\ref{contacttiles} depicts the situation graphically. In later sections of the technology file, it is sometimes useful to refer separately to the various images of contact. A special notation using a slash character (``/'') is used for this. If a tile type {\itshape aaa/bbb} is specified in the technology file, this refers to the image of contact {\itshape aaa} on plane {\itshape bbb}. For example, {\bfseries pcontact/metal1} refers to the image of the pcontact that lies on the metal1 plane, and {\bfseries pcontact/active} refers to the image on the active plane, which is the same as {\bfseries pcontact}. \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/maint2.1.ps, width=0.7\columnwidth} \caption{A different tile type is used to represent a contact on each plane that it connects. Here, a contact between poly on the {\bfseries active} plane and metal1 on the {\bfseries metal1} plane is stored as two tile types. One, {\bfseries pcontact}, is specified in the technology file as residing on the {\bfseries active} plane; the other is automatically-generated for the {\bfseries metal1} plane.} \label{contacttiles} \end{center} \end{figure} \section{Specifying Type-lists} \label{typelists} In several places in the technology file you'll need to specify groups of tile types. For example, in the {\bfseries connect} section you'll specify groups of tiles that are mutually connected. These are called {\itshape type-lists} and there are several ways to specify them. The simplest form for a type-list is a comma-separated list of tile types, for example \starti \ii poly,ndiff,pcontact,ndc \endi The null list (no tiles at all) is indicated by zero, i.e., \starti \ii 0 \endi There must not be any spaces in the type-list. Type-lists may also use tildes (``\~{}'') to select all tiles but a specified set, and parentheses for grouping. For example, \starti \ii \~{}(pcontact,ndc) \endi selects all tile types but pcontact and ndc. When a contact name appears in a type-list, it selects {\itshape all} images of the contact unless a ``/'' is used to indicate a particular one. The example above will not select any of the images of pcontact or ndc. Slashes can also be used in conjunction with parentheses and tildes. For example, \starti \ii \~{}(pcontact,ndc)/active,metal1 \endi selects all of the tile types on the active plane except for pcontact and ndc, and also selects metal1. Tildes have higher operator precedence than slashes, and commas have lowest precedence of all. A special notation using the asterisk (``*'') is a convenient way to abbreviate the common situation where a rule requires the inclusion of a tile type and also all contacts that define that tile type as one of their residue layers, a common occurrence. The notation \starti \ii *metal1 \endi expands to metal1 plus all of the contact types associated with metal1, such as ndc, pdc, nsc, m2c, and so forth. Note: in the CIF sections of the technology file, only simple comma-separated names are permitted; tildes and parentheses are not understood. However, everywhere else in the technology file the full generality can be used. The ``*'' notation for inclusion of contact residues may be present in any section. \section{Styles section} Magic can be run on several different types of graphical displays. Although it would have been possible to incorporate display-specific information into the technology file, a different technology file would have been required for each display type. Instead, the technology file gives one or more display-independent {\itshape styles} for each type that is to be displayed, and uses a per-display-type styles file to map to colors and stipplings specific to the display being used. The styles file is described in Magic Maintainer's Manual\ \#3: ``Styles and Colors'', so we will not describe it further here. Table~\ref{styles} shows part of the {\bfseries styles} section from the scmos technology file. The first line specifies the type of style file for use with this technology, which in this example is {\bfseries mos}. Each subsequent line consists of a tile type and a style number (an integer between 1 and 63). The style number is nothing more than a reference between the technology file and the styles file. Notice that a given tile type can have several styles (e.g., pcontact uses styles \#1, \#20, and \#32), and that a given style may be used to display several different tiles (e.g., style \#2 is used in ndiff and ndcontact). If a tile type should not be displayed, it has no entry in the {\bfseries styles} section. It is no longer necessary to have one style per line, a restriction of format 27 and earlier. Multiple styles for a tile type can be placed on the same line, separated by spaces. Styles may be specified by number, or by the ``long name'' in the style file. \begin{table}[ht] \begin{center} \begin{tabular}{|ll|} \hline {\bfseries styles} & \\ styles & \\ styletype mos & \\ poly & 1 \\ ndiff & 2 \\ pdiff & 4 \\ nfet & 6 \\ nfet & 7 \\ pfet & 8 \\ pfet & 9 \\ metal1 & 20 \\ metal2 & 21 \\ pcontact & 1 \\ pcontact & 20 \\ pcontact & 32 \\ ndcontact & 2 \\ ndcontact & 20 \\ ndcontact & 32 \\ pdcontact & 4 \\ pdcontact & 20 \\ pdcontact & 32 \\ m2contact & 20 \\ m2contact & 21 \\ m2contact & 33 \\ {\bfseries end} & \\ \hline \end{tabular} \caption{Part of the {\bfseries styles} section} \label{styles} \end{center} \end{table} \section{Compose section} The semantics of Magic's paint operation are defined by a collection of rules of the form, ``given material {\itshape HAVE} on plane {\itshape PLANE}, if we paint {\itshape PAINT}, then we get {\itshape Z}'', plus a similar set of rules for the erase operation. The default paint and erase rules are simple. Assume that we are given material {\itshape HAVE} on plane {\itshape PLANE}, and are painting or erasing material {\itshape PAINT}. \begin{enumerate} \item {\itshape You get what you paint.} \\ If the home plane of {\itshape PAINT} is {\itshape PLANE}, or {\itshape PAINT} is space, you get {\itshape PAINT}; otherwise, nothing changes and you get {\itshape HAVE}. \item {\itshape You can erase all or nothing.} \\ Erasing space or {\itshape PAINT} from {\itshape PAINT} will give space; erasing anything else has no effect. \end{enumerate} These rules apply for contacts as well. Painting the base type of a contact paints the base type on its home plane, and each image type on its home plane. Erasing the base type of a contact erases both the base type and the image types. It is sometimes desirable for certain tile types to behave as though they were ``composed'' of other, more fundamental ones. For example, painting poly over ndiffusion in scmos produces ntransistor, instead of ndiffusion. Also, painting either poly or ndiffusion over ntransistor leaves ntransistor, erasing poly from ntransistor leaves ndiffusion, and erasing ndiffusion leaves poly. The semantics for ntransistor are a result of the following rule in the {\bfseries compose} section of the scmos technology file: \starti \ii {\bfseries compose} ntransistor poly ndiff \endi Sometimes, not all of the ``component'' layers of a type are layers known to magic. As an example, in the {\bfseries nmos} technology, there are two types of transistors: {\bfseries enhancement-fet} and {\bfseries depletion-fet}. Although both contain polysilicon and diffusion, depletion-fet can be thought of as also containing implant, which is not a tile type. So while we can't construct depletion-fet by painting poly and then diffusion, we'd still like it to behave as though it contained both materials. Painting poly or diffusion over a depletion-fet should not change it, and erasing either poly or diffusion should give the other. These semantics are the result of the following rule: \starti \ii {\bfseries decompose} dfet poly diff \endi The general syntax of both types of composition rules, {\bfseries compose} and {\bfseries decompose}, is: \starti \ii {\bfseries compose} {\itshape\ \ \ type \ a1 b1 \ a2 b2 \ \dots} \\ \ii {\bfseries decompose} {\itshape type \ a1 b1 \ a2 b2 \ \dots} \endi The idea is that each of the pairs {\itshape a1 b1}, {\itshape a2 b2}, etc comprise {\itshape type}. In the case of a {\bfseries compose} rule, painting any {\itshape a} atop its corresponding {\itshape b} will give {\itshape type}, as well as vice-versa. In both {\bfseries compose} and {\bfseries decompose} rules, erasing {\itshape a} from {\itshape type} gives {\itshape b}, erasing {\itshape b} from {\itshape type} gives {\itshape a}, and painting either {\itshape a} or {\itshape b} over {\itshape type} leaves {\itshape type} unchanged. \begin{table}[ht] \begin{center} \begin{tabular}{|llll|} \hline {\bfseries compose} \\ compose & nfet & poly & ndiff \\ compose & pfet & poly & pdiff \\ paint & pwell & nwell & nwell \\ paint & nwell & pwell & pwell \\ paint & pdc/active & pwell & ndc/active \\ paint & pdc/m1 & pwell & ndc/m1 \\ paint & pfet & pwell & nfet \\ paint & pdiff & pwell & ndiff \\ paint & nsd & pwell & psd \\ paint & nsc/active & pwell & psc/active \\ paint & nsc/m1 & pwell & psc/m1 \\ paint & ndc/active & nwell & pdc/active \\ paint & ndc/m1 & nwell & pdc/m1 \\ paint & nfet & nwell & pfet \\ paint & ndiff & nwell & pdiff \\ paint & psd & nwell & nsd \\ paint & psc/active & nwell & nsc/active \\ paint & psc/m1 & nwell & nsc/m1 \\ {\bfseries end} &&& \\ \hline \end{tabular} \caption{{\bfseries Compose} section} \label{compose} \end{center} \end{table} Contacts are implicitly composed of their component types, so the result obtained when painting a type {\itshape PAINT} over a contact type {\itshape CONTACT} will by default depend only on the component types of {\itshape CONTACT}. If painting {\itshape PAINT} doesn't affect the component types of the contact, then it is considered not to affect the contact itself either. If painting {\itshape PAINT} does affect any of the component types, then the result is as though the contact had been replaced by its component types in the layout before type {\itshape PAINT} was painted. Similar rules hold for erasing. A pcontact has component types poly and metal1. Since painting poly doesn't affect either poly or metal1, it doesn't affect a pcontact either. Painting ndiffusion does affect poly: it turns it into an ntransistor. Hence, painting ndiffusion over a pcontact breaks up the contact, leaving ntransistor on the active plane and metal1 on the metal1 plane. The {\bfseries compose} and {\bfseries decompose} rules are normally sufficient to specify the desired semantics of painting or erasing. In unusual cases, however, it may be necessary to provide Magic with explicit {\bfseries paint} or {\bfseries erase} rules. For example, to specify that painting pwell over pdiffusion switches its type to ndiffusion, the technology file contains the rule: \starti \ii {\bfseries paint} pdiffusion pwell ndiffusion \endi This rule could not have been written as a {\bfseries decompose} rule; erasing ndiffusion from pwell does not yield pdiffusion, nor does erasing pdiffusion from ndiffusion yield pwell. The general syntax for these explicit rules is: \starti \ii {\bfseries paint} {\itshape have t result }[{\itshape p}] \\ \ii {\bfseries erase} {\itshape have t result }[{\itshape p}] \endi Here, {\itshape have} is the type already present, on plane {\itshape p} if it is specified; otherwise, on the home plane of {\itshape have}. Type {\itshape t} is being painted or erased, and the result is type {\itshape result}. Table~\ref{compose} gives the {\bfseries compose} section for scmos. It's easiest to think of the paint and erase rules as being built up in four passes. The first pass generates the default rules for all non-contact types, and the second pass replaces these as specified by the {\bfseries compose}, {\bfseries decompose}, etc. rules, also for non-contact types. At this point, the behavior of the component types of contacts has been completely determined, so the third pass can generate the default rules for all contact types, and the fourth pass can modify these as per any {\bfseries compose}, etc. rules for contacts. \section{Connect section} For circuit extraction, routing, and some of the net-list operations, Magic needs to know what types are electrically connected. Magic's model of electrical connectivity used is based on signal propagation. Two types should be marked as connected if a signal will {\itshape always} pass between the two types, in either direction. For the most part, this will mean that all non-space types within a plane should be marked as connected. The exceptions to this rule are devices (transistors). A transistor should be considered electrically connected to adjacent polysilicon, but not to adjacent diffusion. This models the fact that polysilicon connects to the gate of the transistor, but that the transistor acts as a switch between the diffusion areas on either side of the channel of the transistor. The lines in the {\bfseries connect} section of a technology file, as shown in Table~\ref{connect}, each contain a pair of type-lists in the format described in Section~\ref{typelists}. Each type in the first list connects to each type in the second list. This does not imply that the types in the first list are themselves connected to each other, or that the types in the second list are connected to each other. \begin{table}[ht] \begin{center} \begin{tabular}{|l@{\hspace*{1.5in}}l|} \hline {\bfseries connect} & \\ \multicolumn{2}{|l|}{\#define allMetal2 m2,m2c/m2,pad/m2} \\ \multicolumn{2}{|l|}{\#define allMetal1 m1,m2c/m1,pc/m1,ndc/m1,pdc/m1,ppcont/m1,nncont/m1,pad/m1} \\ \multicolumn{2}{|l|}{\#define allPoly poly,pc/a,nfet,pfet} \\ allMetal2 & allMetal2 \\ allMetal1 & allMetal1 \\ allPoly & allPoly \\ ndiff & ndc \\ pdiff & pdc \\ nwell,nnc,nsd & nwell,nnc,nsd \\ pwell,ppc,psd & pwell,ppc,psd \\ nnc & pdc \\ ppc & ndc \\ {\bfseries end} & \\ \hline \end{tabular} \caption{{\bfseries Connect} section} \label{connect} \end{center} \end{table} Because connectivity is a symmetric relationship, only one of the two possible orders of two tile types need be specified. Tiles of the same type are always considered to be connected. Contacts are treated specially; they should be specified as connecting to material in all planes spanned by the contact. For example, pcontact is shown as connecting to several types in the active plane, as well as several types in the metal1 plane. The connectivity of a contact should usually be that of its component types, so pcontact should connect to everything connected to poly, and to everything connected to metal1. \section{Cifoutput section} The layers stored by Magic do not always correspond to physical mask layers. For example, there is no physical layer corresponding to (the scmos technology file layer) ntransistor; instead, the actual circuit must be built up by overlapping poly and diffusion over pwell. When writing CIF (Caltech Intermediate Form) or Calma GDS-II files, Magic generates the actual geometries that will appear on the masks used to fabricate the circuit. The {\bfseries cifoutput} section of the technology file describes how to generate mask layers from Magic's abstract layers. \begin{table}[ht!] \begin{center} \begin{tabular}{|l|} \hline {\bfseries cifoutput} \\ style lambda=1.0(gen) \\ \I scalefactor 100 \\ \I layer CWN nwell \\ \II bloat-or pdiff,pdc,pfet * 600 \\ \II bloat-or nsc,nnd * 300 \\ \II grow 300 \\ \II shrink 300 \\ \II gds 42 1 \\ \I layer CWP pwell \\ \II bloat-or ndiff,ndc,nfet * 600 \\ \II bloat-or psc,ppd * 300 \\ \II grow 300 \\ \II shrink 300 \\ \II gds 41 1 \\ \I layer CMS allMetal2 \\ \II labels m2 \\ \II gds 51 1 \\ \I layer CAA allDiff \\ \II labels ndiff,pdiff \\ \II gds 43 1 \\ \I layer CCA ndc,pdc \\ \II squares 200 \\ \II gds 48 1 \\ \I layer CCA nncont,ppcont \\ \II squares 200 \\ \II gds 48 1 \\ \I layer CCP pc \\ \II squares 200 \\ \II gds 47 1 \\ {\bfseries end} \\ \hline \end{tabular} \caption{Part of the {\bfseries cifoutput} section for style lambda=1.0(gen) only.} \label{cifoutput} \end{center} \end{table} \subsection{CIF and GDS styles} From the 1990's, the CIF format has largely been replaced by the GDS format. However, they describe the same layout geometry, and the formats are similar enough that magic makes use of the CIF generation code as the basis for the GDS write routines. The technology file also uses CIF layer declarations as the basis for GDS output. So even a technology file that only expects to generate GDS output needs a ``{\bfseries cifoutput}'' section declaring CIF layer names. If only GDS output is required, these names may be longer and therefore more descriptive than allowed by CIF format syntax. The technology file can contain several different specifications of how to generate CIF. Each of these is called a CIF {\itshape style}. Different styles may be used for fabrication at different feature sizes, or for totally different purposes. For example, some of the Magic technology files contain a style ``plot'' that generates CIF pseudo-layers that have exactly the same shapes as the Magic layers. This style is used for generating plots that look just like what appears on the color display; it makes no sense for fabrication. Lines of the form \starti \ii {\bfseries style} {\itshape name} \endi are used to end the description of the previous style and start the description of a new style. The Magic command {\bfseries :cif ostyle} {\itshape name} is typed by users to change the current style used for output. The first style in the technology file is used by default for CIF output if the designer doesn't issue a {\bfseries :cif style} command. If the first line of the {\bfseries cifoutput} section isn't a {\bfseries style} line, then Magic uses an initial style name of {\bfseries default}. \subsection{Scaling} Each style must contain a line of the form \starti \ii {\bfseries scalefactor} {\itshape scale} [{\bfseries nanometers}\vbar {\bfseries angstroms}] \endi that tells how to scale Magic coordinates into CIF coordinates. The argument {\itshape scale} indicates how many hundredths of a micron correspond to one Magic unit. {\itshape scale} may be any number, including decimals. However, all units in the style description must be integer. Because deep submicron processes may require CIF operations in units of less than one centimicron, the optional parameter {\bfseries nanometers} declares that all units (including the {\itshape scale} parameter) are measured in units of nanometers. Likewise, the units may all be specified in {\bfseries angstroms}. However unlikely the dimensions may seem, the problem is that magic needs to place some objects, like contacts, on half-lambda positions to ensure correct overlap of contact cuts between subcells. A feature size such as, for example, 45 nanometers, has a half-lambda value of 22.5 nanometers. Since this is not an integer, magic will complain about this scalefactor. This is true even if the process doesn't {\itshape allow} sub-nanometer coordinates, and magic uses the {\itshape squares-grid} statement to enforce this restriction. In such a case, it is necessary to declare a scalefactor of 450 angstroms rather than 45 nanometers. Versions of {\itshape magic} prior to 7.1 allowed an optional second (integer) parameter, {\itshape reducer}, or the keyword {\bfseries calmaonly}. The use of {\itshape reducer} is integral to CIF output, which uses the value to ensure that output values are reduced to the smallest common denominator. For example, if all CIF values are divisible by 100, then the reducer is set to 100 and all output values are divided by the same factor, thus reducing the size of the CIF output file. Now the reducer is calculated automatically, avoiding any problems resulting from an incorrectly specified reducer value, and any value found after {\itshape scale} is ignored. The {\bfseries calmaonly} keyword specified that the {\itshape scale} was an odd integer. This limitation has been removed, so any such keyword is ignored, and correct output may be generated for either CIF or Calma at all output scales. In addition to specifying a scale factor, each style can specify the size in which chunks will be processed when generating CIF hierarchically. This is particularly important when the average design size is much larger than the maximum bloat or shrink (e.g, more than 3 orders of magnitude difference). The step size is specified by a line of the following form: \starti \ii {\bfseries stepsize} {\itshape stepsize} \endi where {\itshape stepsize} is in Magic units. For example, if you plan to generate CIF for designs that will typically be 100,000 Magic units on a side, it might make sense for {\itshape stepsize} to be 10000 or more. \subsection{Layer descriptions} The main body of information for each CIF style is a set of layer descriptions. Each layer description consists of one or more {\itshape operations} describing how to generate the CIF for a single layer. The first line of each description is one of \starti \ii {\bfseries layer} {\itshape name} [{\itshape layers}] \endi or \starti \ii {\bfseries templayer} {\itshape name} [{\itshape layers}] \endi These statements are identical, except that templayers are not output in the CIF file. They are used only to build up intermediate results used in generating the ``real'' layers. In each case, {\itshape name} is the CIF name to be used for the layer. If {\itshape layers} is specified, it consists of a comma-separated list of Magic layers and previously-defined CIF layers in this style; these layers form the initial contents of the new CIF layer (note: the layer lists in this section are less general than what was described in Section~\ref{typelists}; tildes and parentheses are not allowed). If {\itshape layers} is not specified, then the new CIF layer is initially empty. The following statements are used to modify the contents of a CIF layer before it is output. After the {\bfseries layer} or {\bfseries templayer} statement come several statements specifying geometrical operations to apply in building the CIF layer. Each statement takes the current contents of the layer, applies some operation to it, and produces the new contents of the layer. The last geometrical operation for the layer determines what is actually output in the CIF file. The most common geometrical operations are: \starti \ii {\bfseries or} {\itshape layers} \\ \ii {\bfseries and} {\itshape layers} \\ \ii {\bfseries and-not} {\itshape layers} \\ \ii {\bfseries grow} {\itshape amount} \\ \ii {\bfseries shrink} {\itshape amount} \\ \ii {\bfseries bloat-or} {\itshape layers layers2 amount layers2 amount \dots} \\ \ii {\bfseries squares} {\itshape size} \\ \ii {\bfseries squares} {\itshape border size separation} \\ \endi Some more obscure operations are: \starti \ii {\bfseries grow-grid} {\itshape amount} \\ \ii {\bfseries bloat-max} {\itshape layers layers2 amount layers2 amount \dots} \\ \ii {\bfseries bloat-min} {\itshape layers layers2 amount layers2 amount \dots} \\ \ii {\bfseries bloat-all} {\itshape layers layers2} \\ \ii {\bfseries squares-grid} {\itshape border size separation x y} \\ \ii {\bfseries slots} {\itshape border size separation} \\ \ii {\bfseries slots} {\itshape border size separation border\_long} \\ \ii {\bfseries slots} {\itshape border size separation border\_long size\_long sep\_long} [{\itshape offset}]] \\ \ii {\bfseries bbox} [{\bfseries top}] \endi The operation {\bfseries or} takes all the {\itshape layers} (which may be either Magic layers or previously-defined CIF layers), and or's them with the material already in the CIF layer. The operation {\bfseries and} is similar to {\bfseries or}, except that it and's the layers with the material in the CIF layer (in other words, any CIF material that doesn't lie under material in {\itshape layers} is removed from the CIF layer). {\bfseries And-not} finds all areas covered by {\itshape layers} and erases current CIF material from those areas. {\bfseries Grow} and {\bfseries shrink} will uniformly grow or shrink the current CIF layer by {\itshape amount} units, where {\itshape amount} is specified in CIF units, not Magic units. The {\bfseries grow-grid} operator grows layers non-uniformly to snap to the grid spacing indicated by {\itshape amount}. This can be used to ensure that features fall on a required minimum grid. The three ``bloat'' operations {\bfseries bloat-or}, {\bfseries bloat-min}, and {\bfseries bloat-max}, provide selective forms of growing. In these statements, all the layers must be Magic layers. Each operation examines all the tiles in {\itshape layers}, and grows the tiles by a different distance on each side, depending on the rest of the line. Each pair {\itshape layers2 amount} specifies some tile types and a distance (in CIF units). Where a tile of type {\itshape layers} abuts a tile of type {\itshape layers2}, the first tile is grown on that side by {\itshape amount}. The result is or'ed with the current contents of the CIF plane. The layer ``{\bfseries *}'' may be used as {\itshape layers2} to indicate all tile types. Where tiles only have a single type of neighbor on each side, all three forms of {\bfseries bloat} are identical. Where the neighbors are different, the three forms are slightly different, as illustrated in Figure~\ref{bloat}. Note: all the layers specified in any given {\bfseries bloat} operation must lie on a single Magic plane. For {\bfseries bloat-or} all distances must be positive. In {\bfseries bloat-max} and {\bfseries bloat-min} the distances may be negative to provide a selective form of shrinking. \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/maint2.2.ps, width=\columnwidth} \caption{The three different forms of {\bfseries bloat} behave slightly differently when two different bloat distances apply along the same side of a tile. In each of the above examples, the CIF that would be generated is shown in bold outline. If {\bfseries bloat-or} is specified, a jagged edge may be generated, as on the left. If {\bfseries bloat-max} is used, the largest bloat distance for each side is applied uniformly to the side, as in the center. If {\bfseries bloat-min} is used, the smallest bloat distance for each side is applied uniformly to the side, as on the right.} \end{center} \label{bloat} \end{figure} In retrospect, it's not clear that {\bfseries bloat-max} and {\bfseries bloat-min} are very useful operations. The problem is that they operate on tiles, not regions. This can cause unexpected behavior on concave regions. For example, if the region being bloated is in the shape of a ``T'', a single bloat factor will be applied to the underside of the horizontal bar. If you use {\bfseries bloat-max} or {\bfseries bloat-min}, you should probably specify design-rules that require the shapes being bloated to be convex. The fourth bloat operation {\bfseries bloat-all} takes all tiles of types {\itshape layers}, and grows to include all neighboring tiles of types {\itshape layers2}. This is very useful to generate marker layers or implant layers for specific devices, where the marker or implant must cover both the device and its contacts. Take the material of the device and use {\bfseries bloat-all} to expand into the contact areas. An important geometric operation for creating contact cuts is {\bfseries squares}. It examines each tile on the CIF plane, and replaces that tile with one or more squares of material. Each square is {\itshape size} CIF units across, and squares are separated by {\itshape separation} units. A border of at least {\itshape border} units is left around the edge of the original tile, if possible. This operation is used to generate contact vias, as in Figure~\ref{squares}. If only one argument is given in the {\bfseries squares} statement, then {\itshape separation} defaults to {\itshape size} and {\itshape border} defaults to {\itshape size}/2. If a tile doesn't hold an integral number of squares, extra space is left around the edges of the tile and the squares are centered in the tile. If the tile is so small that not even a single square can fit and still leave enough border, then the border is reduced. If a square won't fit in the tile, even with no border, then no material is generated. The {\bfseries squares} operation must be used with some care, in conjunction with the design rules. For example, if there are several adjacent skinny tiles, there may not be enough room in any of the tiles for a square, so no material will be generated at all. Whenever you use the {\bfseries squares} operator, you should use design rules to prohibit adjacent contact tiles, and you should always use the {\bfseries no{\_}overlap} rule to prevent unpleasant hierarchical interactions. The problems with hierarchy are discussed in Section~\ref{hierarchy} below, and design rules are discussed in Section~\ref{s_mzrouter}. \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/maint2.3.ps, width=0.33\columnwidth} \caption{The {\bfseries squares} operator chops each tile up into squares, as determined by the {\itshape border}, {\itshape size}, and {\itshape separation} parameters. In the example, the bold lines show the CIF that would be generated by a {\bfseries squares} operation. The squares of material are always centered so that the borders on opposite sides are the same.} \label{squares} \end{center} \end{figure} The {\bfseries squares-grid} operator is similar to {\bfseries squares} and takes the same arguments, except for the additional optional {\itshape x} and {\itshape y} offsets (which default to 1). Where the {\bfseries squares} operator places contacts on the half-lambda grid, the {\bfseries squares-grid} operator places contacts on an integer grid of {\itshape x} and {\itshape y}. This is helpful where manufacturing grid limitations do not allow half-lambda coordinates. However, it is necessary then to enforce a ``no-overlap'' rule for contacts in the DRC section to prevent incorrect contacts cuts from being generated in overlapping subcells. The {\bfseries squares-grid} operator can also be used with {\itshape x} and {\itshape y} values to generate fill geometry, or to generate offset contact cut arrays for pad vias. The {\bfseries slots} operator is similar to {\bfseries squares} operator, but as the name implies, the resulting shapes generated are rectangular, not (necessarily) square. Slots are generated inside individual tiles, like the squares operator, so each slots operation is separately oriented relative to the tile's long and short edges. Separate border, size, and separation values can be specified for the short and long dimensions of the tile. This operator can be used in a number of situations: \begin{enumerate} \item Generate square contact cuts with different border requirements on the short and long sides, as required for a number of deep submicron processes like 90 nanometer. \item Automatically generate slots in large metal areas, which most processes require. Note, however, that it is impossible to correctly generate all slots, so this cannot completely replace the widespacing DRC rule. \item Generate slot contacts. \item Generate fill geometry. \item Generate marker layers for resitors that abut the position of contacts, a generally-accepted way to define a resistor area boundary. \end{enumerate} Note that the {\bfseries slots} operator comes in three different forms with different numbers of arguments. With only three arguments (short side description only), the {\bfseries slots} operator creates stripes that extend to the edge of the tile. With four arguments (short side description plus long side border dimension only), the {\bfseries slots} operator create stripes that extend to the edge of the tile, with an appropriate border spacing at each end. In these two cases, the slots have variable length that is set by the size of the tile. In the final form, all short and long side dimensions are declared. The generated slots are of fixed size, and like the {\bfseries squares} operator, their positions will be adjusted to center them on the tile. The {\itshape offset} is intended to let each row of slots be offset from the previous one by a fixed amount, but is currently unimplemented and has no effect. \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/maint2.3b.ps, width=0.6\columnwidth} \caption{The {\bfseries slots} operator chops each tile up into rectangles.} \label{slots} \end{center} \end{figure} The {\bfseries bbox} operator generates a single rectangle that encompasses the bounding box of the cell. This is useful for the occasional process that requires marker or implant layers covering an entire design. The variant {\bfseries bbox top} will generate a rectangle encompassing the bounding box of the cell, but will only do so for the top-level cell of the design. \subsection{Labels} There is an additional statement permitted in the {\bfseries cifoutput} section as part of a layer description: \starti \ii {\bfseries labels} {\itshape Magiclayers} \endi This statement tells Magic that labels attached to Magic layers {\itshape Magiclayers} are to be associated with the current CIF layer. Each Magic layer should only appear in one such statement for any given CIF style. If a Magic layer doesn't appear in any {\bfseries labels} statement, then it is not attached to a specific layer when output in CIF. \subsection{Calma (GDS II Stream format) layers} Each layer description in the {\bfseries cifoutput} section may also contain one of the following statements: \starti \ii {\bfseries gds} {\itshape gdsNumber} {\itshape gdsType} \\ \ii {\bfseries calma} {\itshape gdsNumber} {\itshape gdsType} \endi Although the format is rarely referred to as ``Calma'' anymore, the keyword is retained for backwards compatibility with format 27 (and earlier) files. This statement tells Magic which layer number and data type to use when the {\bfseries gds} command outputs GDS II Stream format for this defined CIF layer. Both {\itshape gdsNumber} and {\itshape gdsType} should be positive integers, between 0 and 63. Each CIF layer should have a different {\itshape gdsNumber}. If there is no {\bfseries gds} line for a given CIF layer, then that layer will not be output by the ``{\bfseries gds write}'' command. The reverse is not true: every generated output layer must have a defined CIF layer type, even if the foundry only supports GDS format. In such case, the CIF layer name may violate the restrictive 4-character format required by the CIF syntax specification, and may be used to provide a reasonable, human-readable descriptive name of the GDS layer. \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/maint2.4.ps, width=0.85\columnwidth} \caption{If the operator {\bfseries grow 100} is applied to the shapes in (a), the merged shape in (b) results. If the operator {\bfseries shrink 100} is applied to (b), the result is (c). However, if the two original shapes in (a) belong to different cells, and if CIF is generated separately in each cell, the result will be the same as in (a). Magic handles this by outputting additional information in the parent of the subcells to fill in the gap between the shapes.} \label{growshrink} \end{center} \end{figure} \subsection{Hierarchy} \label{hierarchy} Hierarchical designs make life especially difficult for the CIF generator. The CIF corresponding to a collection of subcells may not necessarily be the same as the sum of the CIF's of the individual cells. For example, if a layer is generated by growing and then shrinking, nearby features from different cells may merge together so that they don't shrink back to their original shapes (see Figure~\ref{growshrink}). If Magic generates CIF separately for each cell, the interactions between cells will not be reflected properly. The CIF generator attempts to avoid these problems. Although it generates CIF in a hierarchical representation that matches the Magic cell structure, it tries to ensure that the resulting CIF patterns are exactly the same as if the entire Magic design had been flattened into a single cell and then CIF were generated from the flattened design. It does this by looking in each cell for places where subcells are close enough to interact with each other or with paint in the parent. Where this happens, Magic flattens the interaction area and generates CIF for it; then Magic flattens each of the subcells separately and generates CIF for them. Finally, it compares the CIF from the subcells with the CIF from the flattened parent. Where there is a difference, Magic outputs extra CIF in the parent to compensate. Magic's hierarchical approach only works if the overall CIF for the parent ends up covering at least as much area as the CIFs for the individual components, so all compensation can be done by adding extra CIF to the parent. In mathematical terms, this requires each geometric operation to obey the rule \starti \ii Op(A $\cup$ B) $\supseteq$ Op(A) $\cup$ Op(B) \endi The operations {\bfseries and}, {\bfseries or}, {\bfseries grow}, and {\bfseries shrink} all obey this rule. Unfortunately, the {\bfseries and-not}, {\bfseries bloat}, and {\bfseries squares} operations do not. For example, if there are two partially-overlapping tiles in different cells, the squares generated from one of the cells may fall in the separations between squares in the other cell, resulting in much larger areas of material than expected. There are two ways around this problem. One way is to use the design rules to prohibit problem situations from arising. This applies mainly to the {\bfseries squares} operator. Tiles from which squares are made should never be allowed to overlap other such tiles in different cells unless the overlap is exact, so each cell will generate squares in the same place. You can use the {\bfseries exact{\_}overlap} design rule for this. The second approach is to leave things up to the designer. When generating CIF, Magic issues warnings where there is less material in the children than the parent. The designer can locate these problems and eliminate the interactions that cause the trouble. Warning: Magic does not check the {\bfseries squares} operations for hierarchical consistency, so you absolutely must use {\bfseries exact{\_}overlap} design rule checks! Right now, the {\bfseries cifoutput} section of the technology is one of the trickiest things in the whole file, particularly since errors here may not show up until your chip comes back and doesn't work. Be extremely careful when writing this part! \begin{table}[ht!] \begin{center} \begin{tabular}{|l|} \hline {\bfseries cifinput} \\ style lambda=1.0(gen) \\ \I scalefactor 100 \\ \I layer m1 CMF \\ \II labels CMF \\ \I layer ndiff CSN \\ \II and CAA \\ \I layer nsd CWN \\ \II and CSN \\ \II and CAA \\ \I layer nfet CPG \\ \II and CAA \\ \II and CSN \\ \I layer ndc CCA \\ \II grow 100 \\ \II and CAA \\ \II and CWP \\ \II and CSN \\ \II and CMF \\ \I layer nncont CCA \\ \II grow 100 \\ \II and CAA \\ \II and CSN \\ \II and CWN \\ \II and CMF \\ \I calma CAA 1 * \\ \I calma CCA 2 * \\ \I calma CMF 4 * \\ \I calma CPG 7 * \\ \I calma CSN 8 * \\ \I calma CWN 11 * \\ \I calma CWP 12 * \\ {\bfseries end} \\ \hline \end{tabular} \caption{Part of the {\bfseries cifinput} section. The order of the layers is important, since each Magic layer overrides the previous ones just as if they were painted by hand.} \label{cifinput} \end{center} \end{table} Another problem with hierarchical generation is that it can be very slow, especially when there are a number of rules in the cifoutput section with very large grow or shrink distances, such that magic must always expand its area of interest by this amount to be sure of capturing all possible layer interactions. When this ``halo'' distance becomes larger than the average subcell, much of the design may end up being processed multiple times. Noticeably slow output generation is usually indicative of this problem. It can be alleviated by keeping output rules simple. Note that basic AND and OR operations do not interact between subcells, so that rules made from only these operators will not be processed during subcell interaction generation. Remember that typically, subcell interaction paint will only be generated for layers that have a ``grow'' operation followed by a ``shrink'' operation. This common ruleset lets layers that are too closely spaced to be merged together, thus eliminating the need for a spacing rule between the layers. But consider carefully before implementing such a rule. Implementing a DRC spacing rule instead may eliminate a huge amount of output processing. Usually this situation crops up for auto-generated layers such as implants and wells, to prevent magic from auto-generating DRC spacing violations. But again, consider carefully whether it might be better to require the layout engineer to draw the layers instead of attempting to auto-generate them. \subsection{Render statements} At the end of each style in the {\bfseries cifoutput} section, one may include {\bfseries render} statements, one per defined CIF/GDS layer. These {\bfseries render} statements are used by the 3-D drawing window in the OpenGL graphics version of magic, and are also used by the ``{\bfseries cif see}'' command to set the style painted. The syntax for the statement is as follows: \starti \ii {\bfseries render} {\itshape cif\_layer style\_name height thickness} \endi The {\itshape cif\_layer} is any valid layer name defined in the same {\bfseries cifoutput} section where the {\bfseries render} statement occurs. The {\itshape style\_name} is the name or number of a style in the styles file. The names are the same as used in the {\bfseries styles} section of the technology file. {\itshape height} and {\itshape thickness} are effectively dimensionless units and are used for relative placement and scaling of the three-dimensional layout view (such views generally have a greatly expanded z-axis scaling). By default, all layers are given the same style and a zero height and thickness, so effectively nothing useful can be seen in the 3-D view without a complete set of {\bfseries render} statements. \section{Cifinput section} In addition to writing CIF, Magic can also read in CIF files using the {\bfseries :cif read} {\itshape file} command. The {\bfseries cifinput} section of the technology file describes how to convert from CIF mask layers to Magic tile types. In addition, it provides information to the Calma reader to allow it to read in Calma GDS II Stream format files. The {\bfseries cifinput} section is very similar to the {\bfseries cifoutput} section. It can contain several styles, with a line of the form \starti \ii {\bfseries style} {\itshape name} \endi used to end the description of the previous style (if any), and start a new CIF input style called {\itshape name}. If no initial style name is given, the name {\bfseries default} is assigned. Each style must have a statement of the form \starti \ii {\bfseries scalefactor} {\itshape scale} {\bfseries [nanometers]} \endi to indicate the output scale relative to Magic units. Without the optional keyword {\bfseries nanometers}, {\itshape scale} describes how many hundredths of a micron correspond to one unit in Magic. With {\bfseries nanometers} declared, {\itshape scale} describes how many nanometers correspond to one unit in Magic. Like the {\bfseries cifoutput} section, each style consists of a number of layer descriptions. A layer description contains one or more lines describing a series of geometric operations to be performed on CIF layers. The result of all these operations is painted on a particular Magic layer just as if the user had painted that information by hand. A layer description begins with a statement of the form \starti \ii {\bfseries layer} {\itshape magicLayer }[{\itshape layers}] \endi In the {\bfseries layer} statement, {\itshape magicLayer} is the Magic layer that will be painted after performing the geometric operations, and {\itshape layers} is an optional list of CIF layers. If {\itshape layers} is specified, it is the initial value for the layer being built up. If {\itshape layers} isn't specified, the layer starts off empty. As in the {\bfseries cifoutput} section, each line after the {\itshape layer} statement gives a geometric operation that is applied to the previous contents of the layer being built in order to generate new contents for the layer. The result of the last geometric operation is painted into the Magic database. The geometric operations that are allowed in the {\bfseries cifinput} section are a subset of those permitted in the {\bfseries cifoutput} section: \starti \ii {\bfseries or} {\itshape layers} \\ \ii {\bfseries and} {\itshape layers} \\ \ii {\bfseries and-not} {\itshape layers} \\ \ii {\bfseries grow} {\itshape amount} \\ \ii {\bfseries shrink} {\itshape amount} \endi In these commands the {\itshape layers} must all be CIF layers, and the {\itshape amounts} are all CIF distances (centimicrons, unless the keyword {\bfseries nanometers} has been used in the {\bfseries scalefactor} specification). As with the {\bfseries cifoutput} section, layers can only be specified in simple comma-separated lists: tildes and slashes are not permitted. When CIF files are read, all the mask information is read for a cell before performing any of the geometric processing. After the cell has been completely read in, the Magic layers are produced and painted in the order they appear in the technology file. In general, the order that the layers are processed is important since each layer will usually override the previous ones. For example, in the scmos tech file shown in Table~\ref{cifinput} the commands for {\bfseries ndiff} will result in the {\bfseries ndiff} layer being generated not only where there is only ndiffusion but also where there are ntransistors and ndcontacts. The descriptions for {\bfseries ntransistor} and {\bfseries ndcontact} appear later in the section, so those layers will replace the {\bfseries ndiff} material that was originally painted. Labels are handled in the {\bfseries cifinput} section just like in the {\bfseries cifoutput} section. A line of the form \starti \ii {\bfseries labels} {\itshape layers} \endi means that the current Magic layer is to receive all CIF labels on {\itshape layers}. This is actually just an initial layer assignment for the labels. Once a CIF cell has been read in, Magic scans the label list and re-assigns labels if necessary. In the example of Table~\ref{cifinput}, if a label is attached to the CIF layer CPG then it will be assigned to the Magic layer {\bfseries poly}. However, the polysilicon may actually be part of a poly-metal contact, which is Magic layer {\bfseries pcontact}. After all the mask information has been processed, Magic checks the material underneath the layer, and adjusts the label's layer to match that material ({\bfseries pcontact} in this case). This is the same as what would happen if a designer painted {\bfseries poly} over an area, attached a label to the material, then painted {\bfseries pcontact} over the area. No hierarchical mask processing is done for CIF input. Each cell is read in and its layers are processed independently from all other cells; Magic assumes that there will not be any unpleasant interactions between cells as happens in CIF output (and so far, at least, this seems to be a valid assumption). If Magic encounters a CIF layer name that doesn't appear in any of the lines for the current CIF input style, it issues a warning message and ignores the information associated with the layer. If you would like Magic to ignore certain layers without issuing any warning messages, insert a line of the form \starti \ii {\bfseries ignore} {\itshape cifLayers} \endi where {\itshape cifLayers} is a comma-separated list of one or more CIF layer names. Calma layers are specified via {\bfseries calma} lines, which should appear at the end of the {\bfseries cifinput} section. They are of the form: \starti \ii {\bfseries calma} {\itshape cifLayer} {\itshape calmaLayers} {\itshape calmaTypes} \endi The {\itshape cifLayer} is one of the CIF types mentioned in the {\bfseries cifinput} section. Both {\itshape calmaLayers} and {\itshape calmaTypes} are one or more comma-separated integers between 0 and 63. The interpretation of a {\bfseries calma} line is that any Calma geometry whose layer is any of the layers in {\itshape calmaLayers}, and whose type is any of the types in {\itshape calmaTypes}, should be treated as the CIF layer {\itshape cifLayer}. Either or both of {\itshape calmaLayers} and {\itshape calmaTypes} may be the character {\bfseries *} instead of a comma-separated list of integers; this character means {\itshape all} layers or types respectively. It is commonly used for {\itshape calmaTypes} to indicate that the Calma type of a piece of geometry should be ignored. Just as for CIF, Magic also issues warnings if it encounters unknown Calma layers while reading Stream files. If there are layers that you'd like Magic to ignore without issuing warnings, assign them to a dummy CIF layer and ignore the CIF layer. \section{Lef section} This section defines a mapping between magic layers and layers that may be found in LEF and DEF format files. Without the section, magic cannot read a LEF or DEF file. The LEF and DEF layer declarations are usually simple and straightforward (as they typically define metal layers only), so often it will suffice to insert a plain vanilla {\bfseries lef} section into a technology file if one is missing. The {\bfseries lef} section was introduced in technology file format 28, and is therefore absent from all {\ttfamily .tech27} technology files. All of the statements in the {\bfseries lef} section have the same format: \starti \ii {\bfseries layer} {\itshape magic-type lefdef-type} \dots \\ \ii {\bfseries cut} {\itshape magic-type lefdef-type} \dots \\ \ii {\bfseries route}\vbar {\bfseries routing} {\itshape magic-type lefdef-type} \dots \\ \ii {\bfseries obstruction} {\itshape magic-type lefdef-type} \dots \\ \ii {\bfseries masterslice} {\itshape magic-type lefdef-type} \dots \\ \ii {\bfseries overlap} {\itshape magic-type lefdef-type} \dots \endi Each statement defines a mapping between a Magic layer type {\itshape magic-type} and one or more type names {\itshape lefdef-type} (space-separated) that might be encountered in a LEF or DEF file. The different command names all refer to different type classes defined by the LEF/DEF specification. For most purposes, it is only necessary to use the {\bfseries layer} statement. If the magic type is a contact type, then the {\bfseries layer} statement is equivalent to specifying {\bfseries cut}; otherwise, it is equivalent to {\bfseries route}. Table \ref{lefdef} is a typical {\bfseries lef} section for a 5-metal technology, which encompasses the most commonly used layer names found in LEF and DEF files. \begin{table}[ht] \begin{center} \begin{tabular}{|lllllll|} \hline {\bfseries lef} &&&&&& \\ & masterslice & ndiff & diffusion & active && \\ & masterslice & poly & poly & POLY1 & pl & \\ & routing & m1 & m1 & metal1 & METAL1 & METAL\_1 \\ & routing & m2 & m2 & metal2 & METAL2 & METAL\_2 \\ & routing & m3 & m3 & metal3 & METAL3 & METAL\_3 \\ & routing & m4 & m4 & metal4 & METAL4 & METAL\_4 \\ & routing & m5 & m5 & metal5 & METAL5 & METAL\_5 \\ &&&&&&\\ & cut & pc & cont1 & pl-m1 && \\ & cut & m2c & via1 & cont2 & VIA12 & m1-m2 \\ & cut & m3c & via2 & cont3 & VIA23 & m2-m3 \\ & cut & m4c & via3 & cont4 & VIA34 & m3-m4 \\ & cut & m5c & via4 & cont5 & VIA45 & m4-m5 \\ &&&&&& \\ & overlap & comment & overlap & OVERLAP && \\ {\bfseries end} &&&&&& \\ \hline \end{tabular} \caption{A plain vanilla lef section.} \label{lefdef} \end{center} \end{table} \section{Mzrouter section} \label{s_mzrouter} This section defines the layers and contacts available to the Magic maze router, {\itshape mzrouter}, and assigns default costs for each type. Default widths and spacings are derived from the {\bfseries drc} section of the technology file (described below) but can be overridden in this section. Other mzrouter parameters, for example, search rate and width, can also be specified in this section. The syntax and function of the lines in the {\bfseries mzrouter} section of the technology file are specified in the subsections below. Each set of specifications should be headed by a {\bfseries style} line. {\bfseries Routelayer} and {\bfseries routecontact} specifications should precede references to them. \begin{table}[ht] \begin{center} \begin{tabular}{|llllll|} \hline {\bfseries mzrouter} &&&&& \\ style & irouter &&&& \\ layer & m2 & 32 & 64 & 256 & 1 \\ layer & m1 & 64 & 32 & 256 & 1 \\ layer & poly & 128 & 128 & 512 & 1 \\ contact & m2contact & metal1 & metal2 & 1024 & \\ contact & pcontact & metal1 & poly & 2056 & \\ notactive & poly & pcontact &&& \\ style & garouter &&&& \\ layer & m2 & 32 & 64 & 256 & 1 \\ layer & m1 & 64 & 32 & 256 & 1 \\ contact & m2contact & metal1 & metal2 & 1024 & \\ {\bfseries end} &&&&& \\ \hline \end{tabular} \caption{Mzrouter section for the scmos technology.} \label{mzrouter} \end{center} \end{table} \subsection{Styles} The mzrouter is currently used in two contexts, interactively via the {\bfseries iroute} command, and as a subroutine to the garouter for stem generation. To permit distinct parameters for these two uses, the lines in the {\bfseries mzrouter} section are grouped into {\itshape styles}. The lines pertaining to the irouter should be preceded by \starti \ii {\bfseries style irouter} \endi and those pertaining to the garouter should be preceded by the specification \starti \ii {\bfseries style garouter} \endi Other styles can be specified, but are currently not used. Table~\ref{mzrouter} shows the mzrouter section from the scmos technology. \subsection{Layers} Layer lines define the route-layers available to the maze router in that style. They have the following form: \starti \ii {\bfseries layer} {\itshape type hCost vCost jogCost hintCost} \endi Here {\itshape type} is the name of the tiletype of the layer and {\itshape hCost}, {\itshape vCost}, {\itshape jogCost} and {\itshape hintCost}, are non-negative integers specifying the cost per unit horizontal distance, cost per unit vertical distance, cost per jog, and cost per unit area of deviation from magnets, respectively. Route layers for any given style must lie in distinct planes. \subsection{Contacts} Contact lines specify the route-contacts available to the mzrouter in the current style. They have the following form: \starti \ii {\bfseries contact} {\itshape type routeLayer1 routeLayer2 cost} \endi Here {\itshape type} is the tiletype of the contact, {\itshape routeLayer1} and {\itshape routeLayer2} are the two layers connected by the contact, and {\itshape cost} is a nonnegative integer specifying the cost per contact. \subsection{Notactive} It maybe desirable to have a layer or contact available to the maze router, but default to off, i.e., not be used by the mzrouter until explicitly made active. Route-types (route-layers or route-contacts) can be made to default to off with the following specification: \starti \ii {\bfseries notactive} {\itshape route-type} \dots [{\bfseries route-typen}] \endi \subsection{Search} The search {\bfseries rate}, {\bfseries width}, and {\bfseries penalty} parameters can be set with a specification of the form: \starti \ii {\bfseries search} {\itshape rate width penalty} \endi Here {\itshape rate} and {\itshape width} are positive integers. And {\itshape penalty} is a positive rational (it may include a decimal point). See the irouter tutorial for a discussion of these parameters. (Note that {\bfseries penalty} is a ``wizardly'' parameter, i.e., it is interactively set and examined via {\bfseries iroute wizard} not {\bfseries iroute search}). If no {\bfseries search} line is given for a style, the overall mzrouter defaults are used. \subsection{Width} Appropriate widths for route-types are normally derived from the {\bfseries drc} section of the technology file. These can be overridden with width specifications of the following form: \starti \ii {\bfseries width} {\itshape route-type width} \endi Here {\itshape width} is a positive integer. \subsection{Spacing} Minimum spacings between routing on a route-type and other types are derived from the design rules. These values can be overridden by explicit spacing specifications in the {\bfseries mzrouter} section. Spacing specifications have the following form: \starti \ii {\bfseries spacing} {\itshape routetype type1 spacing1 } \dots [{\itshape typen spacingn}] \endi Spacing values must be nonnegative integers or {\bfseries NIL}. The special type {\bfseries SUBCELL} can be used to specify minimum spacing to unexpanded subcells. \section{Drc section} The design rules used by Magic's design rule checker come entirely from the technology file. We'll look first at two simple kinds of rules, {\bfseries width} and and {\bfseries spacing}. Most of the rules in the {\bfseries drc} section are one or the other of these kinds of rules. \subsection{Width rules} The minimum width of a collection of types, taken together, is expressed by a {\bfseries width} rule. Such a rule has the form: \starti \ii {\bfseries width} {\itshape type-list width error} \endi where {\itshape type-list} is a set of tile types (see Section~\ref{typelists} for syntax), {\itshape width} is an integer, and {\itshape error} is a string, enclosed in double quotes, that can be printed by the command {\bfseries :drc why} if the rule is violated. A width rule requires that all regions containing any types in the set {\itshape types} must be wider than {\itshape w} in both dimensions. For example, in Table~\ref{drcwidth}, the rule \starti \ii {\bfseries width} nwell 6 {\itshape {\q}N-Well width must be at least 6 (MOSIS rule \#1.1){\q}} \endi means that nwells must be at least 6 units wide whenever they appear. The {\itshape type-list} field may contain more than a single type, as in the following rule: \starti \ii {\bfseries width} allDiff 2 {\itshape {\q}Diffusion width must be at least 2 (MOSIS rule \#2.1){\q}} \endi which means that all regions consisting of the types containing any kind of diffusion be at least 2 units wide. Because many of the rules in the {\bfseries drc} section refer to the same sets of layers, the {\bfseries \#define} facility of the C preprocessor is used to define a number of macros for these sets of layers. Table~\ref{drctiles} gives a complete list. \begin{table}[ht] \begin{center} \begin{tabular}{|lll|} \hline \#define & allDiff & ndiff,pdiff,ndc/a,pdc/a,ppcont/a,nncont/a,pfet,nfet,psd,nsd \\ \#define & extPoly & poly,pcontact \\ \#define & extM1 & metal1,pcontact/m1,ndc/m1,ppcont/m1,pdc/m1,nncont/m1 \\ \#define & extM2 & metal2,m2contact/m2 \\ \hline \end{tabular} \caption{Abbreviations for sets of tile types.} \label{drctiles} \end{center} \end{table} \begin{table}[ht] \begin{center} \begin{tabular}{|llll|} \hline width & pwell & 6 & {\q}P-Well width must be at least 6 (MOSIS rule \#1.1){\q} \\ width & nwell & 6 & {\q}N-Well width must be at least 6 (MOSIS rule \#1.1){\q} \\ width & allDiff & 2 & {\q}Diffusion width must be at least 2 (MOSIS rule \#2.1){\q} \\ width & allPoly & 2 & {\q}Polysilicon width must be at least 2 (MOSIS rule \#3.1){\q} \\ \hline \end{tabular} \caption{Some width rules in the {\bfseries drc} section.} \label{drcwidth} \end{center} \end{table} All of the layers named in any one width rule must lie on the same plane. However, if some of the layers are contacts, Magic will substitute a different contact image if the named image isn't on the same plane as the other layers. \subsection{Spacing rules} The second simple kind of design rule is a {\bfseries spacing} rule. It comes in two flavors: {\bfseries touching{\_}ok}, and {\bfseries touching{\_}illegal}, both with the following syntax: \starti \ii {\bfseries spacing} {\itshape types1 types2 distance flavor error} \endi The first flavor, {\bfseries touching{\_}ok}, does not prohibit {\itshape types1} and {\itshape types2} from being immediately adjacent. It merely requires that any type in the set {\itshape types1} must be separated by a ``Manhattan'' distance of at least {\itshape distance} units from any type in the set {\itshape types2} that is not immediately adjacent to the first type. See Figure~\ref{distance} for an illustration of Manhattan distance for design rules. As an example, consider the metal1 separation rule: \starti \ii {\bfseries spacing} allPoly allPoly 2 {\bfseries touching{\_}ok} {\bk} \\ \ii\> {\itshape {\q}Polysilicon spacing must be at least 2 (MOSIS rule \#3.2){\q}} \endi \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/maint2.5.ps, width=0.4\columnwidth} \caption{For design rule checking, the Manhattan distance between two horizontally or vertically aligned points is just the normal Euclidean distance. If they are not so aligned, then the Manhattan distance is the length of the longest side of the right triangle forming the diagonal line between the points.} \end{center} \label{distance} \end{figure} This rule is symmetric ({\itshape types1} is equal to {\itshape types2}), and requires, for example, that a pcontact be separated by at least 2 units from a piece of polysilicon. However, this rule does not prevent the pcontact from touching a piece of poly. In {\bfseries touching{\_}ok} rules, all of the layers in both {\itshape types1} and {\itshape types2} must be stored on the same plane (Magic will substitute different contact images if necessary). \begin{table}[ht] \begin{center} \begin{tabular}{|lllll|} \hline spacing & allPoly & allPoly & 2 & touching{\_}ok {\bk} \\ & \multicolumn{4}{l|}{{\itshape {\q}Polysilicon spacing must be at least 2 (MOSIS rule \#3.2){\q}}} \\ spacing & pfet & nncont,nnd & 3 & touching{\_}illegal {\bk} \\ & \multicolumn{4}{l|}{{\itshape {\q}Transistors must be separated from substrate contacts by 3 (MOSIS rule \#4.1){\q}}} \\ spacing & pc & allDiff & 1 & touching{\_}illegal {\bk} \\ & \multicolumn{4}{l|}{{\itshape {\q}Poly contact must be 1 unit from diffusion (MOSIS rule \#5B.6){\q}}} \\ \hline \end{tabular} \caption{Some spacing rules in the {\bfseries drc} section.} \label{drcspacing} \end{center} \end{table} {\bfseries TOUCHING{\_}OK SPACING} RULES DO NOT WORK FOR VERY LARGE SPACINGS (RELATIVE TO THE TYPES INVOLVED). SEE FIGURE 6 FOR AN EXPLANATION. If the spacing to be checked is greater than the width of one of the types involved plus either its self-spacing or spacing to a second involved type, {\bfseries touching{\_}ok spacing} may not work properly: a violation can be masked by an intervening touching type. In such cases the rule should be written using the {\bfseries edge4way} construct described below. \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/maint2.6.ps, width=0.5\columnwidth} \caption{The {\bfseries touching{\_}ok} rules cancels spacing checks if the material is touching. This means that even distant material won't be checked for spacing. If the rule applied at edge A is a touching{\_}ok rule between material t1 and t2, then no check will be made between the t1 material and the t2 material on the far right side of the diagram. If this check was desired, it could be accomplished in this case by a {\bfseries edge4way} check from edge B. This would not work in general, though, because that check could also be masked by material of type t2, causing the touching{\_}ok rule to be invoked.} \label{touchingok} \end{center} \end{figure} The second flavor of spacing rule, {\bfseries touching{\_}illegal}, disallows adjacency. It is used for rules where {\itshape types1} and {\itshape types2} can never touch, as in the following: \starti \ii {\bfseries spacing} pc allDiff 1 {\bfseries touching{\_}illegal} {\bk} \\ \ii\> {\itshape {\q}Poly contact must be 1 unit from diffusion (MOSIS rule \#5B.6){\q}} \endi Pcontacts and any type of diffusion must be at least 1 unit apart; they cannot touch. In {\bfseries touching{\_}illegal} rules {\itshape types1} and {\itshape types2} may not have any types in common: it would be rather strange not to permit a type to touch itself. In {\bfseries touching{\_}illegal} rules, {\itshape types1} and {\itshape types2} may be spread across multiple planes; Magic will find violations between material on different planes. \subsection{Wide material spacing rules} Many fabrications processes require a larger distance between layers when the width and length of one of those layers exceeds a certain minimum dimension. For instance, a process might declare that the normal spacing between metal1 lines is 3 microns. However, if a metal1 line exceeds a width of 100 microns, then the spacing to other unrelated metal1 lines must increase to 10 microns. This situation is covered by the {\bfseries widespacing} rule. The syntax for {\bfseries widespacing} is as follows: \starti \ii {\bfseries widespacing} {\itshape types1 wwidth types2 distance flavor error} \endi The {\bfseries widespacing} rule matches the syntax of {\bfseries spacing} in all respects except for the addition of the parameter {\itshape wwidth}, which declares the minimum width of layers of type(s) {\itshape types1} that triggers the rule. So for the example above, the correct {\bfseries widespacing} rule would be (assuming 1 magic unit = 1 micron): \starti \ii {\bfseries widespacing} allMetal1 100 allMetal1 10 {\bfseries touching{\_}ok} {\bk} \\ \ii\> {\itshape {\q}Space to wide Metal1 (length and width \grt 100) must be at least 10{\q}} \endi \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/maint2.6b.ps, width=0.8\columnwidth} \caption{The {\bfseries widespacing} rule covers situations like that shown above, in which material of type {\itshape t1} normally must be {\itshape dist} units away from type {\itshape t2} (situation A). However, if both dimensions of material type {\itshape t1} are larger than or equal to some width {\itshape wwidth} (situation B), then the spacing must be increased to {\itshape wdist}.} \label{widespacing} \end{center} \end{figure} \subsection{Surround rule} The {\bfseries surround} rule specifies what distance a layer must surround another, and whether the presence of the surrounding material is optional or mandatory. This rule is designed for materials which must {\itshape completely} surround another, such as metal around a contact cut or MiM capacitor layer. The syntax is: \starti \ii {\bfseries surround} {\itshape types1 types2 distance presence error} \endi and states that the layers in {\itshape types2} must surround the layers in {\itshape types1} by an amound {\itshape distance} lambda units. The value of {\itshape presence} must be one of the keywords {\bfseries absence\_ok} or {\bfseries absence\_illegal}. When {\itshape presence} is {\bfseries absence\_illegal}, then types {\itshape types2} must always be present when types {\itshape types1} are present. When {\itshape presence} is {\bfseries absence\_ok}, types {\itshape types1} may exist outside of types {\itshape types2} without error, but where they coincide, types {\itshape types2} must overlap {\itshape types1} by the amount {\itshape distance}. \subsection{Overhang rule} rule specifies what distance a layer must overhang another at an intersection. This is used, for example, to specify the length of polysilicon end-caps on transistors, which is the distance that the polysilicon gate must extend beyond the defined gate area of the transistor to ensure a correctly operating device. The syntax is: \starti \ii {\bfseries overhang} {\itshape types1 types2 distance error} \endi and states that layers in {\itshape types1} must overhang layers in {\itshape types2} by an amount {\itshape distance} lambda units. The rule flags the complete absence of types {\itshape types1}, but does not prohibit the use of {\itshape types1} as a bridge (that is, with types {\itshape types2} on either side of {\itshape types1}, which will generally be covered by a separate spacing rule, and which may have a different spacing requirement). \subsection{Rectangle-only rule} The {\bfseries rect\_only} rule is used to denote layers that must be rectangular; that is, they cannot bend, or have notches or tabs. Generally, this is used for contacts, so that the CIF output operator {\bfseries squares} will be guaranteed to generate a correct contact. This is due to magic's corner-stitching tile database, where bends, notches, tabs, and slots will break up an otherwise continuous patch of material into potentially many small tiles, each one of which might be too small to fit a contact cut. \starti \ii {\bfseries rect\_only} {\itshape types error} \endi \subsection{Edge rules} The width and spacing rules just described are actually translated by Magic into an underlying, edge-based rule format. This underlying format can handle rules more general than simple widths and spacings, and is accessible to the writer of a technology file via {\bfseries edge} rules. These rules are applied at boundaries between material of two different types, in any of four directions as shown in Figure~\ref{tileedge}. The design rule table contains a separate list of rules for each possible combination of materials on the two sides of an edge. \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/maint2.7.ps, width=0.4\columnwidth} \caption{Design rules are applied at the edges between tiles in the same plane. A rule is specified in terms of type {\itshape t1} and type {\itshape t2}, the materials on either side of the edge. Each rule may be applied in any of four directions, as shown by the arrows. The simplest rules require that only certain mask types can appear within distance {\itshape d} on {\itshape t2}'s side of the edge.} \label{tileedge} \end{center} \end{figure} In its simplest form, a rule specifies a distance and a set of mask types: only the given types are permitted within that distance on {\itshape type2}'s side of the edge. This area is referred to as the {\itshape constraint region}. Unfortunately, this simple scheme will miss errors in corner regions, such as the case shown in Figure~\ref{cornererror}. To eliminate these problems, the full rule format allows the constraint region to be extended past the ends of the edge under some circumstances. See Figure~\ref{cornerextend} for an illustration of the corner rules and how they work. Table~\ref{edgerules1} gives a complete description of the information in each design rule. \begin{figure}[hb!] \begin{center} \epsfig{file=../psfigures/maint2.8.ps, width=0.7\columnwidth} \caption{If only the simple rules from Figure~\ref{tileedge} are used, errors may go unnoticed in corner regions. For example, the polysilicon spacing rule in (a) will fail to detect the error in (b).} \label{cornererror} \end{center} \end{figure} \begin{figure}[ht!] \begin{center} \epsfig{file=../psfigures/maint2.9.ps, width=0.75\columnwidth} \caption{The complete design rule format is illustrated in (a). Whenever an edge has {\itshape type1} on its left side and {\itshape type2} on its right side, the area A is checked to be sure that only {\itshape OKTypes} are present. If the material just above and to the left of the edge is one of {\itshape cornerTypes}, then area B is also checked to be sure that it contains only {\itshape OKTypes}. A similar corner check is made at the bottom of the edge. Figure (b) shows a polysilicon spacing rule, (c) shows a situation where corner extension is performed on both ends of the edge, and (d) shows a situation where corner extension is made only at the bottom of the edge. If the rule described in (d) were to be written as an {\bfseries edge} rule, it would look like:} \starti \ii {\bfseries edge} poly space 2 \~{}poly \~{}poly 2 {\bk} \\ \ii\> {\itshape {\q}Poly-poly separation must be at least 2{\q}} \endi \label{cornerextend} \end{center} \end{figure} \begin{table}[ht] \begin{center} \begin{tabular}{|l|p{0.5\columnwidth}|} \hline Parameter & Meaning \\ \hline \hline type1 & Material on first side of edge. \\ \hline type2 & Material on second side of edge. \\ \hline d & Distance to check on second side of edge. \\ \hline OKTypes & List of layers that are permitted within {\itshape d} units on second side of edge. ({\itshape OKTypes}={\bfseries 0} means never OK) \\ \hline cornerTypes & List of layers that cause corner extension. ({\itshape cornerTypes}={\bfseries 0} means no corner extension) \\ \hline cornerDist & Amount to extend constraint area when {\itshape cornerTypes} matches. \\ \hline plane & Plane on which to check constraint region (defaults to same plane as {\itshape type1} and {\itshape type2} and {\itshape cornerTypes}). \\ \hline \end{tabular} \caption{The parts of an edge-based rule.} \label{edgerules1} \end{center} \end{table} Edge rules are specified in the technology file using the following syntax: \starti \ii {\bfseries edge} {\itshape types1 types2 d OKTypes cornerTypes cornerDist error} [{\itshape plane}] \endi Both {\itshape types1} and {\itshape types2} are type-lists. An edge rule is generated for each pair consisting of a type from {\itshape types1} and a type from {\itshape types2}. All the types in {\itshape types1}, {\itshape types2}, and {\itshape cornerTypes} must lie on a single plane. See Figure~\ref{cornerextend} for an example edge rule. It is sometimes useful to specify a null list, i.e., {\bfseries 0}, for {\itshape OKTypes} or {\itshape CornerTypes}. Null {\itshape OKTypes} means no edges between {\itshape types1} and {\itshape types2} are OK. Null {\itshape CornerTypes} means no corner extensions are to be checked (corner extensions are explained below). Some of the edge rules in Magic have the property that if a rule is violated between two pieces of geometry, the violation can be discovered looking from either piece of geometry toward the other. To capitalize on this, Magic normally applies an edge rule only in two of the four possible directions: bottom-to-top and left-to-right, reducing the work it has to do by a factor of two. Also, the corner extension is only performed to one side of the edge: to the top for a left-to-right rule, and to the left for a bottom-to-top rule. All of the width and spacing rules translate neatly into edge rules. However, you'll probably find it easiest when you're writing edge rules to insist that they be checked in all directions. To do this, write the rule the same way except use the keyword {\bfseries edge4way} instead of {\bfseries edge}: \starti \ii {\bfseries edge4way} nfet ndiff 2 ndiff,ndc ndiff 2 {\bk} \\ \ii\> {\itshape {\q}Diffusion must overhang transistor by at least 2{\q}} \endi Not only are {\bfseries edge4way} rules checked in all four directions, but the corner extension is performed on {\itshape both} sides of the edge. For example, when checking a rule from left-to-right, the corner extension is performed both to the top and to the bottom. {\bfseries Edge4way} rules take twice as much time to check as {\bfseries edge} rules, so it's to your advantage to use {\bfseries edge} rules wherever you can. \begin{table}[ht] \begin{center} \begin{tabular}{|lllllll|} \hline edge4way & ppcont,ppd & ndiff,ndc,nfet & 3 & ndiff,ndc,nfet & ndiff,ndc,nfet & 3 {\bk} \\ & \multicolumn{5}{l}{{\itshape {\q}Ndiff must be 3 wide if it abuts ppcont or ppd (MOSIS rule \#??){\q}}} & \\ edge4way & allPoly & \~{}(allPoly)/active & 3 & \~{}pc/active & \~{}(allPoly)/active & 3 {\bk} \\ & \multicolumn{5}{l}{{\itshape {\q}Poly contact must be at least 3 from other poly (MOSIS rule \#5B.4,5){\q}}} & \\ edge4way & allPoly & \~{}(allPoly)/active & 1 & \~{}m2c/metal2 & \~{}(allPoly)/active & 1 {\bk} \\ & \multicolumn{5}{l}{{\itshape {\q}Via must be on a flat surface (MOSIS rule \#8.4,5){\q}} metal2} & \\ \hline \end{tabular} \caption{Some edge rules in the {\bfseries drc} section.} \label{edgerules2} \end{center} \end{table} Normally, an edge rule is checked completely within a single plane: both the edge that triggers the rule and the constraint area to check fall in the same plane. However, the {\itshape plane} argument can be specified in an edge rule to force Magic to perform the constraint check on a plane different from the one containing the triggering edge. In this case, {\itshape OKTypes} must all be tile types in {\itshape plane}. This feature is used, for example, to ensure that polysilicon and diffusion edges don't lie underneath metal2 contacts: \starti \ii {\bfseries edge4way} allPoly \~{}(allPoly)/active 1 \~{}m2c/metal2 \~{}(allPoly)/active 1 {\bk} \\ \ii\> {\itshape {\q}Via must be on a flat surface (MOSIS rule \#8.4,5){\q}} metal2 \endi Magic versions using techfile formats more recent than 28 are generally more clever about determining the correct plane from {\itshape OKTypes} when they differ from the triggering types, and the situation is unambiguous (use of ``space'' in rules tends to introduce ambiguity, since space tiles appear on all planes). \subsection{Subcell Overlap Rules} In order for CIF generation and circuit extraction to work properly, certain kinds of overlaps between subcells must be prohibited. The design-rule checker provides two kinds of rules for restricting overlaps. They are \starti \ii {\bfseries exact{\_}overlap} {\itshape type-list} \\ \ii {\bfseries no{\_}overlap} {\itshape type-list1 type-list2} \endi In the {\bfseries exact{\_}overlap} rule, {\itshape type-list} indicates one or more tile types. If a cell contains a tile of one of these types and that tile is overlapped by another tile of the same type from a different cell, then the overlap must be exact: the tile in each cell must cover exactly the same area. Abutment between tiles from different cells is considered to be a partial overlap, so it is prohibited too. This rule is used to ensure that the CIF {\bfseries squares} operator will work correctly, as described in Section~\ref{hierarchy}. See Table~\ref{exactoverlap} for the {\bfseries exact{\_}overlap} rule from the standard scmos technology file. \begin{table}[ht] \begin{center} \begin{tabular}{|lll|} \hline exact{\_}overlap & \multicolumn{2}{l|}{m2c,ndc,pdc,pc,ppcont,nncont} \\ no{\_}overlap & pfet,nfet & pfet,nfet \\ \hline \end{tabular} \caption{Exact{\_}overlap rule in the {\bfseries drc} section.} \label{exactoverlap} \end{center} \end{table} The {\bfseries no{\_}overlap} rule makes illegal any overlap between a tile in {\itshape type-list1} and a tile in {\itshape type-list2}. You should rarely, if ever, need to specify {\bfseries no{\_}overlap} rules, since Magic automatically prohibits many kinds of overlaps between subcells. After reading the technology file, Magic examines the paint table and applies the following rule: if two tile types A and B are such that the result of painting A over B is neither A nor B, or the result of painting B over A isn't the same as the result of painting A over B, then A and B are not allowed to overlap. Such overlaps are prohibited because they change the structure of the circuit. Overlaps are supposed only to connect things without making structural changes. Thus, for example, poly can overlap pcontact without violating the above rules, but poly may not overlap diffusion because the result is efet, which is neither poly nor diffusion. The only {\bfseries no{\_}overlap} rules you should need to specify are rules to keep transistors from overlapping other transistors of the same type. \subsection{Background checker step size} Magic's background design-rule checker breaks large cells up into smaller pieces, checking each piece independently. For very large designs, the number of pieces can get to be enormous. If designs are large but sparse, the performance of the design-rule checker can be improved tremendously by telling it to use a larger step size for breaking up cells. This is done as follows: \starti \ii {\bfseries stepsize} {\itshape stepsize} \endi which causes each cell to be processed in square pieces of at most {\itshape stepsize} by {\itshape stepsize} units. It is generally a good idea to pick a large {\itshape stepsize}, but one that is small enough so each piece will contain no more than 100 to 1000 rectangles. Note that the distances declared in the DRC section are used to determine the ``halo'' of possible interactions around a tile edge. Magic must consider all paint in all cells simultaneously; thus for each edge in the design, magic must flatten the hierarchy around it to a distance equal to the interaction halo. Clearly this has a huge impact on processing time. Because the DRC is interactive, the performance hit can be noticeable to downright irritating. Often this performance hit can be greatly reduced by removing rules with large distance measures, such as rules involving distances to pads, and widespacing rules. If this is a problem, consider using one technology file for layout, and one which can be used ``offline'' to do a slow, non-interactive DRC check for pad and widespacing rules on an entire project layout. \section{Extract section} The {\bfseries extract} section of a technology file contains the parameters used by Magic's circuit extractor. Each line in this section begins with a keyword that determines the interpretation of the remainder of the line. Table~\ref{extract} gives an example {\bfseries extract} section. \begin{table}[ht!p] \begin{center} \begin{tabular}{|ll|} \hline {\bfseries extract} & \\ style & lambda=0.7 \\ lambda & 70 \\ step & 100 \\ sidehalo & 4 \\ \vns & \\ resist & poly,pfet,nfet 60000 \\ resist & pc/a 50000 \\ resist & pdiff,ppd 120000 \\ resist & ndiff,nnd 120000 \\ resist & m2contact/m1 1200 \\ resist & metal1 200 \\ resist & metal2,pad/m1 60 \\ resist & ppc/a,pdc/a 100000 \\ resist & nnc/a,ndc/a 100000 \\ resist & nwell,pwell 3000000 \\ \vns & \\ areacap & poly 33 \\ areacap & metal1 17 \\ areacap & metal2,pad/m1 11 \\ areacap & ndiff,nsd 350 \\ areacap & pdiff,psd 200 \\ areacap & ndc/a,nsc/a 367 \\ areacap & pdc/a,psc/a 217 \\ areacap & pcontact/a 50 \\ \vns & \\ perimc & allMetal1 space 56 \\ perimc & allMetal2 space 55 \\ \vns & \\ overlap & metal1 pdiff,ndiff,psd,nsd 33 \\ overlap & metal2 pdiff,ndiff,psd,nsd 17 metal1 \\ overlap & metal1 poly 33 \\ overlap & metal2 poly 17 metal1 \\ overlap & metal2 metal1 33 \\ \vns & \\ sideoverlap & allMetal1 space allDiff 64 \\ sideoverlap & allMetal2 space allDiff 60 \\ sideoverlap & allMetal1 space poly 64 \\ sideoverlap & allMetal2 space poly 60 \\ sideoverlap & allMetal2 space allMetal1 70 \\ \vns & \\ fet & pfet pdiff,pdc/a 2 pfet Vdd! nwell 0 0 \\ fet & nfet ndiff,ndc/a 2 nfet GND! pwell 0 0 \\ {\bfseries end} & \\ \hline \end{tabular} \caption{{\bfseries Extract} section.} \label{extract} \end{center} \end{table} This section is like the {\bfseries cifinput} and {\bfseries cifoutput} sections in that it supports multiple extraction styles. Each style is preceded by a line of the form \starti \ii {\bfseries style} {\itshape stylename} \endi All subsequent lines up to the next {\bfseries style} line or the end of the section are interpreted as belonging to extraction style {\itshape stylename}. If there is no initial {\bfseries style} line, the first style will be named ``default''. The keywords {\bfseries areacap}, {\bfseries perimcap}, and {\bfseries resist} define the capacitance to substrate and the sheet resistivity of each of the Magic layers in a layout. All capacitances that appear in the {\bfseries extract} section are specified as an integral number of attofarads (per unit area or perimeter), and all resistances as an integral number of milliohms per square. The {\bfseries areacap} keyword is followed by a list of types and a capacitance to substrate, as follows: \starti \ii {\bfseries areacap} {\itshape types} {\itshape C} \endi Each of the types listed in {\itshape types} has a capacitance to substrate of {\itshape C} attofarads per square lambda. Each type can appear in at most one {\bfseries areacap} line. If a type does not appear in any {\bfseries areacap} line, it is considered to have zero capacitance to substrate per unit area. Since most analysis tools compute transistor gate capacitance directly from the area of the transistor's gate, Magic should produce node capacitances that do not include gate capacitances. To ensure this, all transistors should have zero {\bfseries areacap} values. The {\bfseries perimcap} keyword is followed by two type-lists and a capacitance to substrate, as follows: \starti \ii {\bfseries perimcap} {\itshape intypes} {\itshape outtypes} {\itshape C} \endi Each edge that has one of the types in {\itshape intypes} on its inside, and one of the types in {\itshape outtypes} on its outside, has a capacitance to substrate of {\itshape C} attofarads per lambda. This can also be used as an approximation of the effects due to the sidewalls of diffused areas. As for {\bfseries areacap}, each unique combination of an {\itshape intype} and an {\itshape outtype} may appear at most once in a {\bfseries perimcap} line. Also as for {\bfseries areacap}, if a combination of {\itshape intype} and {\itshape outtype} does not appear in any {\bfseries perimcap} line, its perimeter capacitance per unit length is zero. The {\bfseries resist} keyword is followed by a type-list and a resistance as follows: \starti \ii {\bfseries resist} {\itshape types} {\itshape R} \endi The sheet resistivity of each of the types in {\itshape types} is {\itshape R} milliohms per square. Each {\bfseries resist} line in fact defines a ``resistance class''. When the extractor outputs the area and perimeter of nodes in the {\bfseries .ext} file, it does so for each resistance class. Normally, each resistance class consists of all types with the same resistance. However, if you wish to obtain the perimeter and area of each type separately in the {\bfseries .ext} file, you should make each into its own resistance class by using a separate {\bfseries resist} line for each type. In addition to sheet resistivities, there are two other ways of specifying resistances. Neither is used by the normal Magic extractor, but both are used by the resistance extractor. Contacts have a resistance that is inversely proportional to the number of via holes in the contact, which is proportional (albeit with quantization) to the area of the contact. The {\bfseries contact} keyword allows the resistance for a single via hole to be specified: \starti \ii {\bfseries contact} {\itshape types size R} \\ \ii {\bfseries contact} {\itshape types size border separation R} \endi where {\itshape types} is a comma-separated list of types, {\itshape size} is in lambda, and {\itshape R} is in milliohms. {\itshape Size} is interpreted as a hole-size quantum; the number of holes in a contact is equal to its width divided by {\itshape size} times its length divided by {\itshape size}, with both quotients rounded down to the nearest integer. The resistance of a contact is {\itshape R} divided by the number of holes. Note that the {\itshape size} alone may not compute the same number of contact cuts as would be generated by the {\itshape cifoutput} command, since it has no understaning of border and separation, and therefore may compute an incorrect contact resistance. To avoid this problem, the second form provides a way to give values for {\itshape border} and {\itshape separation}, again in units of lambda. There is no automatic check to guarantee that the extract and cifoutput sections agree on the number of contact cuts for a given contact area. Transistors also have resistance information associated with them. However, a transistor's resistance may vary depending on a number of variables, so a single parameter is generally insufficient to describe it. The {\bfseries fetresist} line allows sheet resistivities to be given for a variety of different configurations: \starti \ii {\bfseries fetresist} {\itshape fettypes region R} \endi where {\itshape fettypes} is a comma-separated list of transistor types (as defined in {\bfseries fet} lines below), {\itshape region} is a string used to distinguish between resistance values for a fet if more than one is provided (the special {\itshape region} value of ``{\bfseries linear}'' is required for the resistance extractor), and {\itshape R} is the on-resistance of the transistor in ohms per square ({\itshape not} milliohms; there would otherwise be too many zeroes). Magic also extracts internodal coupling capacitances, as illustrated in Figure~\ref{capextract}. The keywords {\bfseries overlap}, {\bfseries sidewall}, {\bfseries sideoverlap}, and {\bfseries sidehalo} provide the parameters needed to do this. Overlap capacitance is between pairs of tile types, and is described by the {\bfseries overlap} keyword as follows: \starti \ii {\bfseries overlap} {\itshape toptypes bottomtypes cap} [{\itshape shieldtypes}] \endi where {\itshape toptypes}, {\itshape bottomtypes}, and optionally {\itshape shieldtypes} are type-lists and {\itshape cap} is a capacitance in attofarads per square lambda. The extractor searches for tiles whose types are in {\itshape toptypes} that overlap tiles whose types are in {\itshape bottomtypes}, and that belong to different electrical nodes. (The planes of {\itshape toptypes} and {\itshape bottomtypes} must be disjoint). When such an overlap is found, the capacitance to substrate of the node of the tile in {\itshape toptypes} is deducted for the area of the overlap, and replaced by a capacitance to the node of the tile in {\itshape bottomtypes}. \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/tut8.4.ps, width=0.6\columnwidth} \caption{Magic extracts three kinds of internodal coupling capacitance. This figure is a side view of a set of masks that shows all three kinds of capacitance. {\itshape Overlap} capacitance is parallel-plate capacitance between two different kinds of material when they overlap. {\itshape Parallel wire} capacitance is fringing-field capacitance between the parallel vertical edges of two pieces of material. {\itshape Sidewall overlap} capacitance is fringing-field capacitance between the vertical edge of one piece of material and the horizontal surface of another piece of material that overlaps the vertical edge.} \label{capextract} \end{center} \end{figure} If {\itshape shieldtypes} are specified, overlaps between {\itshape toptypes} and {\itshape bottomtypes} that also overlap a type in {\itshape shieldtypes} are not counted. The types in {\itshape shieldtypes} must appear on a different plane (or planes) than any of the types in {\itshape toptypes} or {\itshape bottomtypes}. \begin{figure}[ht!] \begin{center} \epsfig{file=../psfigures/maint2.11.ps, width=0.33\columnwidth} \caption{Parallel wire capacitance is between pairs of edges. The capacitance applies between the tiles {\itshape tinside} and {\itshape tfar} above, where {\itshape tinside}'s type is one of {\itshape intypes}, and {\itshape tfar}'s type is one of {\itshape fartypes}.} \label{wirecap} \end{center} \end{figure} Parallel wire capacitance is between pairs of edges, and is described by the {\bfseries sidewall} keyword: \starti \ii {\bfseries sidewall} {\itshape intypes outtypes neartypes fartypes cap} \endi where {\itshape intypes}, {\itshape outtypes}, {\itshape neartypes}, and {\itshape fartypes} are all type-lists, described in Figure~\ref{wirecap}. {\itshape Cap} is half the capacitance in attofarads per lambda when the edges are 1 lambda apart. Parallel wire coupling capacitance is computed as being inversely proportional to the distance between two edges: at 2 lambda separation, it is equal to the value {\itshape cap}; at 4 lambda separation, it is half of {\itshape cap}. This approximation is not very good, in that it tends to overestimate the coupling capacitance between wires that are farther apart. To reduce the amount of searching done by Magic, there is a threshold distance beyond which the effects of parallel wire coupling capacitance are ignored. This is set as follows: \starti \ii {\bfseries sidehalo} {\itshape distance} \endi where {\itshape distance} is the maximum distance between two edges at which Magic considers them to have parallel wire coupling capacitance. {\bfseries If this number is not set explicitly in the technology file, it defaults to 0, with the result that no parallel wire coupling capacitance is computed.} Sidewall overlap capacitance is between material on the inside of an edge and overlapping material of a different type. It is described by the {\bfseries sideoverlap} keyword: \starti \ii {\bfseries sideoverlap} {\itshape intypes outtypes ovtypes cap} \endi where {\itshape intypes}, {\itshape outtypes}, and {\itshape ovtypes} are type-lists and {\itshape cap} is capacitance in attofarads per lambda. This is the capacitance associated with an edge with a type in {\itshape intypes} on its inside and a type in {\itshape outtypes} on its outside, that overlaps a tile whose type is in {\itshape ovtypes}. See Figure~\ref{capextract}. Devices are represented in Magic by explicit tile types. The extraction of a device is determined by the declared device type and the information about types which comprise the various independent {\itshape terminals} of the device. \starti \ii {\bfseries device mosfet} {\itshape model gate\_types sd\_types subs\_types subs\_node\_name} {\bk} \\ \ii\> [{\itshape perim\_cap} [{\itshape area\_cap}]] \\ \ii {\bfseries device capacitor} {\itshape model top\_types bottom\_types} [{\itshape perim\_cap}] {\itshape area\_cap} \\ \ii {\bfseries device resistor} {\itshape model resist\_types term\_types} \\ \ii {\bfseries device bjt} {\itshape model base\_types emitter\_types collector\_types} \\ \ii {\bfseries device diode} {\itshape model pos\_types neg\_types} \\ \ii {\bfseries device subcircuit} {\itshape model gate\_types} [{\itshape term\_types} [{\itshape subs\_types}]] \\ \ii {\bfseries device rsubcircuit} {\itshape model id\_types term\_types} \endi Arguments are as follows: \begin{itemize} \item {\itshape model} The SPICE model name of the device. In the case of a subcircuit, it is the subcircuit name. For resistor and capacitor devices for which a simple, unmodeled device type is needed, the {\itshape model} can be the keyword {\bfseries None}. \item {\itshape gate\_types} Layer types that form the gate region of a MOSFET transistor. \item {\itshape sd\_types} Layer types that form the source and drain regions of a MOSFET transistor. Currently there is no way to specify a device with asymmetric source and drain. \item {\itshape subs\_types} Layer types that form the bulk (well or substrate) region under the device. This can be the keyword {\itshape None} for a device such as an nFET that has no identifiable substrate layer type (``space'' cannot be used as a layer type here). \item {\itshape top\_types} Layer types that form the top plate of a capacitor. \item {\itshape bottom\_types} Layer types that form the bottom plate of a capacitor. \item {\itshape resist\_types} Layer types that represent the primary characterized resistive portion of a resistor device. \item {\itshape term\_types} Layer types that represent the ends of a resistor. Normally this is a contact type, but in the case of silicide block or high-resistance implants, it may be normal salicided polysilicon or diffusion. \item {\itshape base\_types} Layer types that represent the base region of a bipolar junction transistor. \item {\itshape emitter\_types} Layer types that represent the emitter region of a bipolar junction transistor. \item {\itshape collector\_types} Layer types that represent the collector region of a bipolar junction transistor. \item {\itshape pos\_types} Layer types that represent the positive (anode) terminal of a diode or P-N junction. \item {\itshape neg\_types} Layer types that represent the negative (cathode) terminal of a diode or P-N junction. \item {\itshape id\_types} Identifier layers that identify a specific resistor type. \item {\itshape subs\_node\_name} The default name of a substrate node in cases where a 4-terminal MOSFET device is missing an identifiable bulk terminal, or when the {\itshape subs\_type} is the keyword {\bfseries None}. \item {\itshape perim\_cap} A value for perimeter capacitance in units of attoFarads per lambda \item {\itshape area\_cap} A value for area capacitance in units of attoFarads per lambda squared. \end{itemize} The {\itshape subs\_node\_name} can be a Tcl variable name (beginning with ``\$'') in the Tcl-based version of magic. Thus, instead of hard-coding a global net name into the general-purpose, project-independent technology file, the technology file can contain a default global power and ground net variable, normally {\bfseries \$VDD} and {\bfseries \$VSS}. Each project should then set these variables (in the {\ttfamily .magicrc} file, for example) to the correct value for the project's default global power and ground networks. SPICE has two formats for resistors and capacitors: one uses a model, and the other does not. The model implies a semiconductor resistor or capacitor, and takes a length and width value. The resistivity or capacitance per unit area of the devices is assumed to be declared in the model, so these values are not generated as part of the SPICE netlist output. Magic technology file formats 27 and earlier only understood one device type, the FET transistor. The extraction of a fet (with gate, sources, and drains) from a collection of transistor tiles is governed by the information in a {\bfseries fet} line. This keyword and syntax is retained for backward compatibility. This line has the following format: \starti \ii {\bfseries fet} {\itshape types dtypes min-nterms name snode } [{\itshape stypes}]{\itshape gscap gccap} \endi {\itshape Types} is a list of those tiletypes that make up this type of transistor. Normally, there will be only one type in this list, since Magic usually represents each type of transistor with a different tiletype. {\itshape Dtypes} is a list of those tiletypes that connect to the diffusion terminals of the fet. Each transistor of this type must have at least {\itshape min-nterms} distinct diffusion terminals; otherwise, the extractor will generate an error message. For example, an {\bfseries efet} in the scmos technology must have a source and drain in addition to its gate; {\itshape min-nterms} for this type of fet is 2. The tiletypes connecting to the gate of the fet are the same as those specified in the {\bfseries connect} section as connecting to the fet tiletype itself. {\itshape Name} is a string used to identify this type of transistor to simulation programs. The substrate terminal of a transistor is determined in one of two ways. If {\itshape stypes} (a comma-separated list of tile types) is given, and a particular transistor overlaps one of those types, the substrate terminal will be connected to the node of the overlapped material. Otherwise, the substrate terminal will be connected to the node with the global name of {\itshape snode} (which {\itshape must} be a global name, i.e., end in an exclamation point). {\itshape Gscap} is the capacitance between the transistor's gate and its diffusion terminals, in attofarads per lambda. Finally, {\itshape gccap} is the capacitance between the gate and the channel, in attofarads per square lambda. Currently, {\itshape gscap} and {\itshape gccap} are unused by the extractor. In technology format 27 files, devices such as resistors, capacitors, and bipolar junction transistors could be extracted by treating them like FETs, using a ``{\bfseries fet}'' line in the extract file, and assigning the terminal classes (somewhat arbitrarily) to the FET terminal classes gate, source/drain, and bulk. Resistors are rather cumbersome using this method, because the ``gate'' terminal maps to nothing physical, and a dummy layer must be drawn. The ``ext2spice'' command generates an ``M'' spice record for all devices declared with a {\bfseries fet} line, so an output SPICE deck must be post-processed to produce the correct SPICE devices for simulation. One important other difference between the older form and the newer is the ability of the ``{\bfseries device}'' records to handle devices with bends or other irregular geometry, including annular (ring-shaped) FETs. Often the units in the extracted circuit for a cell will always be multiples of certain basic units larger than centimicrons for distance, attofarads for capacitance, or milliohms for resistance. To allow larger units to be used in the {\bfseries .ext} file for this technology, thereby reducing the file's size, the {\bfseries extract} section may specify a scale for any of the three units, as follows: \starti \ii {\bfseries cscale} {\itshape c} \\ \ii {\bfseries lambda} {\itshape l} \\ \ii {\bfseries rscale} {\itshape r} \endi In the above, {\itshape c} is the number of attofarads per unit capacitance appearing in the {\bfseries .ext} files, {\itshape l} is the number of centimicrons per unit length, and {\itshape r} is the number of milliohms per unit resistance. All three must be integers; {\itshape r} should divide evenly all the resistance-per-square values specified as part of {\bfseries resist} lines, and {\itshape c} should divide evenly all the capacitance-per-unit values. Magic's extractor breaks up large cells into chunks for hierarchical extraction, to avoid having to process too much of a cell all at once and possibly run out of memory. The size of these chunks is determined by the {\bfseries step} keyword: \starti \ii {\bfseries step} {\itshape step} \endi This specifies that chunks of {\itshape step} units by {\itshape step} units will be processed during hierarchical extraction. The default is {\bfseries 100} units. Be careful about changing {\itshape step}; if it is too small then the overhead of hierarchical processing will increase, and if it is too large then more area will be processed during hierarchical extraction than necessary. It should rarely be necessary to change {\itshape step} unless the minimum feature size changes dramatically; if so, a value of about 50 times the minimum feature size appears to work fairly well. Magic has the capability to generate a geometry-only extraction of a network, useful for 3-D simulations of electric fields necessary to rigorously determine inductance and capacitance. When this feature is used, it is necessary for the field-equation solver to know the vertical stackup of the layout. The extract section takes care of this by allowing each magic layer to be given a definition of height and thickness of the fabricated layer type: \starti \ii {\bfseries height} {\itshape layers height thickness} \endi where {\itshape layers} is a comma-separated list of magic layers sharing the same height and thickness, and {\itshape height} and {\itshape thickness} are floating-point numbers giving the height of the bottom of the layer above the substrate, and the thickness of the layer, respectively, in units of lambda. \section{Wiring section} The {\bfseries wiring} section provides information used by the {\bfseries :wire switch} command to generate contacts. See Table~\ref{wiring} for the {\bfseries wiring} section from the scmos technology file. Each line in the section has the syntax \starti \ii {\bfseries contact} {\itshape type minSize layer1 surround1 layer2 surround2} \\ \endi {\itshape Type} is the name of a contact layer, and {\itshape layer1} and {\itshape layer2} are the two wiring layers that it connects. {\itshape MinSize} is the minimum size of contacts of this type. If {\itshape Surround1} is non-zero, then additional material of type {\itshape layer1} will be painted for {\itshape surround1} units around contacts of {\itshape type}. If {\itshape surround2} is non-zero, it indicates an overlap distance for {\itshape layer2}. \begin{table}[ht] \begin{center} \begin{tabular}{|lllllll|} \hline {\bfseries wiring} &&&&&& \\ {\bfseries contact} & pdcontact & 4 & metal1 & 0 & pdiff & 0 \\ {\bfseries contact} & ndcontact & 4 & metal1 & 0 & ndiff & 0 \\ {\bfseries contact} & pcontact & 4 & metal1 & 0 & poly & 0 \\ {\bfseries contact} & m2contact & 4 & metal1 & 0 & metal2 & 0 \\ {\bfseries end} &&&&&& \\ \hline \end{tabular} \caption{{\bfseries Wiring} section} \label{wiring} \end{center} \end{table} During {\bfseries :wire switch} commands, Magic scans the wiring information to find a contact whose {\itshape layer1} and {\itshape layer2} correspond to the previous and desired new wiring materials (or vice versa). If a match is found, a contact is generated according to {\itshape type}, {\itshape minSize}, {\itshape surround1}, and {\itshape surround2}. \section{Router section} The {\bfseries router} section of a technology file provides information used to guide the automatic routing tools. The section contains four lines. See Table~\ref{router} for an example {\bfseries router} section. \begin{table}[ht] \begin{center} \begin{tabular}{|lllllll|} \hline {\bfseries router} &&&&&& \\ {\bfseries layer1} & metal1 & 3 & allMetal1 & 3 && \\ {\bfseries layer2} & metal2 & 3 & allMetal2 & 4 & allPoly,allDiff & 1 \\ {\bfseries contacts} & m2contact & 4 &&&& \\ {\bfseries gridspacing} & 8 &&&& \\ {\bfseries end} &&&&&& \\ \hline \end{tabular} \caption{{\bfseries Router} section} \label{router} \end{center} \end{table} The first two lines have the keywords {\bfseries layer1} and {\bfseries layer2} and the following format: \starti \ii {\bfseries layer1} {\itshape wireType wireWidth type-list distance type-list distance} \dots \endi They define the two layers used for routing. After the {\bfseries layer1} or {\bfseries layer2} keyword are two fields giving the name of the material to be used for routing that layer and the width to use for its wires. The remaining fields are used by Magic to avoid routing over existing material in the channels. Each pair of fields contains a list of types and a distance. The distance indicates how far away the given types must be from routing on that layer. Layer1 and layer2 are not symmetrical: wherever possible, Magic will try to route on layer1 in preference to layer2. Thus, in a single-metal process, metal should always be used for layer1. The third line provides information about contacts. It has the format \starti \ii {\bfseries contacts} {\itshape contactType size } [{\itshape surround1 surround2}] \endi The tile type {\itshape contactType} will be used to make contacts between layer1 and layer2. Contacts will be {\itshape size} units square. In order to avoid placing contacts too close to hand-routed material, Magic assumes that both the layer1 and layer2 rules will apply to contacts. If {\itshape surround1} and {\itshape surround2} are present, they specify overlap distances around contacts for layer1 and layer2: additional layer1 material will be painted for {\itshape surround1} units around each contact, and additional layer2 material will be painted for {\itshape surround2} units around contacts. The last line of the {\bfseries routing} section indicates the size of the grid on which to route. It has the format \starti \ii {\bfseries gridspacing} {\itshape distance} \endi The {\itshape distance} must be chosen large enough that contacts and/or wires on adjacent grid lines will not generate any design rule violations. \section{Plowing section} The {\bfseries plowing} section of a technology file identifies those types of tiles whose sizes and shapes should not be changed as a result of plowing. Typically, these types will be transistors and buried contacts. The section currently contains three kinds of lines: \starti \ii {\bfseries fixed} {\itshape types} \\ \ii {\bfseries covered} {\itshape types} \\ \ii {\bfseries drag} {\itshape types} \endi where {\itshape types} is a type-list. Table~\ref{plowing} gives this section for the scmos technology file. \begin{table}[ht] \begin{center} \begin{tabular}{|ll|} \hline {\bfseries plowing} & \\ {\bfseries fixed} & pfet,nfet,glass,pad \\ {\bfseries covered} & pfet,nfet \\ {\bfseries drag} & pfet,nfet \\ {\bfseries end} & \\ \hline \end{tabular} \caption{{\bfseries Plowing} section} \label{plowing} \end{center} \end{table} In a {\bfseries fixed} line, each of {\itshape types} is considered to be fixed-size; regions consisting of tiles of these types are not deformed by plowing. Contact types are always considered to be fixed-size, so need not be included in {\itshape types}. In a {\bfseries covered} line, each of {\itshape types} will remain ``covered'' by plowing. If a face of a covered type is covered with a given type before plowing, it will remain so afterwards. For example, if a face of a transistor is covered by diffusion, the diffusion won't be allowed to slide along the transistor and expose the channel to empty space. Usually, you should make all fixed-width types covered as well, except for contacts. In a {\bfseries drag} line, whenever material of a type in {\itshape types} moves, it will drag with it any minimum-width material on its trailing side. This can be used, for example, to insure that when a transistor moves, the poly-overlap forming its gate gets dragged along in its entirety, instead of becoming elongated. \section{Plot section} The {\bfseries plot} section of the technology file contains information used by Magic to generate hardcopy plots of layouts. Plots can be generated in different styles, which correspond to different printing mechanisms. For each style of printing, there is a separate subsection within the {\bfseries plot} section. Each subsection is preceded by a line of the form \starti \ii {\bfseries style} {\itshape styleName} \endi Magic version 6.5 and earlier supported {\bfseries gremlin}, {\bfseries versatec}, and {\bfseries colorversatec} styles. As these are thoroughly obsolete, versions 7 and above instead implement two formats {\bfseries postscript} and {\bfseries pnm}. Generally, the {\bfseries pnm} format is best for printouts of entire chips, and the {\bfseries postscript} format is best for small cells. The PostScript output includes labels, whereas the PNM output does not. The PostScript output is vector-drawn with stipple fills, whereas the PNM output is pixel-drawn, with antialiasing. Small areas of layout tend to look artificially pixellated in the PNM format, while large areas look almost photographic. The PostScript output is a perfect rendering of the Magic layout, but the files become very large and take long spans of time to render for large areas of layout. %-------------------------------------------------- \begin{table}[p] \renewcommand{\baselinestretch}{0.9} \normalsize \begin{center} \begin{tabular}{|llll|} \hline {\bfseries plot} &&& \\ {\bfseries style} & {\bfseries postscript} && \\ & 5 & \multicolumn{2}{l|}{FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF \dots} \\ & 7 & \multicolumn{2}{l|}{18181818 30303030 60606060 C0C0C0C0 \dots} \\ & 9 & \multicolumn{2}{l|}{18181818 3C3C3C3C 3C3C3C3C 18181818 \dots} \\ & 10 & \multicolumn{2}{l|}{F0F0F0F0 60606060 06060606 0F0F0F0F \dots} \\ & 13 & \multicolumn{2}{l|}{00000000 00000000 33333333 33333333 \dots} \\ &&& \\ & 1 & 47 95 111 0 & \\ & 9 & 223 47 223 0 & \\ & 10 & 0 255 255 0 & \\ & 12 & 191 127 0 0 & \\ & 13 & 95 223 63 0 & \\ & 14 & 0 0 0 255 & \\ & 16 & 111 151 244 0 & \\ & 17 & 23 175 183 0 & \\ &&& \\ & \multicolumn{2}{l}{pc,ndc,pdc,psc,nsc} & 14 X \\ & m2c && 14 B \\ & m2c && 14 13 \\ & m2,m2c && 13 10 \\ & \multicolumn{2}{l}{pdc,ndc,psc,nsc,pc,m1,m2c} & 12 9 \\ & poly,pc && 10 5 \\ & nfet && 9 7 \\ & nfet && 16 5 \\ & pfet && 1 7 \\ & pfet && 17 5 \\ & pdiff,pdc && 1 5 \\ & ndiff,ndc && 9 5 \\ &&& \\ {\bfseries style} & {\bfseries pnm} && \\ & draw & metal1 & \\ & draw & metal2 & \\ & draw & polysilicon & \\ & draw & ndiffusion & \\ & draw & pdiffusion & \\ & draw & ntransistor & \\ & draw & ptransistor & \\ & map & psubstratepdiff pdiffusion & \\ & map & nsubstratendiff ndiffusion & \\ & map & polycontact polysilicon metal1 & \\ & map & m2contact metal1 metal2 & \\ & map & ndcontact ndiffusion metal1 & \\ & map & pdcontact pdiffusion metal1 & \\ {\bfseries end} &&& \\ \hline \end{tabular} \caption{Sample {\bfseries plot} section (for an SCMOS process). PostScript stipple patterns have been truncated due to space limitations.} \end{center} \renewcommand{\baselinestretch}{1.0} \end{table} The {\bfseries postscript} style requires three separate sections. The first section defines the stipple patterns used: \starti \ii {\itshape index} {\itshape pattern-bytes}\dots \endi The {\itshape index} values are arbitrary but must be a positive integer and must be unique to each line. The indices will be referenced in the third section. The {\itshape pattern-bytes} are always exactly 8 sets of 8-digit hexidecimal numbers (4 bytes) representing a total of 16 bits by 16 lines of pattern data. If a solid color is intended, then it is necessary to declare a stipple pattern of all ones. The actual PostScript output will implement a solid color, not a stipple pattern, for considerably faster rendering. The second section defines the colors used in standard printer CMYK notation (Cyan, Magenta, Yellow, blacK): \starti \ii {\itshape index C M Y K} \endi Like the first section, each {\itshape index} must be a unique positive integer, and the color values each range from 0 to 255. The third section assigns colors and stipple patterns to each style: \starti \ii {\itshape type-list color-index stipple-index}\vbar {\bfseries X}\vbar {\bfseries B} \endi The {\itshape type-list} is a comma-separated list of magic layer types that collectively use the same color and style. The {\itshape color-index} refers to one of the colors defined in the second section, and the {\itshape stipple-index} refers to one of the stipple patterns defined in the first section. In addition to the stipple pattern indices, two characters are recognized: {\bfseries B} declares that a border will be drawn around the layer boundary, and {\bfseries X} declares that the layout boundary will be printed over with a cross in the same manner as contact areas are drawn in the Magic layout. To get a proper PostScript plot, it is necessary to have a properly defined {\bfseries plot postscript} section in the technology file. Without such a defined set, the {\bfseries plot postscript} command will generate blank output. The {\bfseries pnm} style declarations are as follows: \starti \ii {\bfseries draw} {\itshape magic-type} \\ \ii {\bfseries map} {\itshape magic-type} {\itshape draw-type}\dots \endi where both {\itshape magic-type} and {\itshape draw-type} represent a magic layer name. The {\bfseries draw} command states that a specific magic type will be output exactly as drawn on the layout. The {\bfseries map} statement declares that a specific magic type will be drawn as being composed of other layers declared as {\bfseries draw} types. The colors of the {\bfseries draw} types will be blended to generate the mapped layer color. Colors are defined by the style set used for layout and defined in the {\bfseries styles} section of the technology file. Stipple patterns, borders, and cross-hatches used by those styles are ignored. When multiple styles are used for a layer type, the PNM output blends the base color of each of those styles. Thus, contact areas by default tend to show up completely black, as the ``X'' pattern is usually defined as black, and black blended with other colors remains black. This is why the above example re-defines all of the contact types as mapped type blends. Contact cuts are not represented, which is generally desired if the plot being made represents a large area of layout. Unlike the PostScript section, the PNM plot section does {\itshape not} have to be declared. Magic will set up a default style for PNM plots that matches (more or less) the colors of the layout as specified by the {\bfseries styles} section of the technology file. The {\bfseries plot pnm} section can be used to tweak this default setup. Normally this is not necessary. The default setup is helpful in that it allows the {\bfseries plot pnm} command to be used with all technology files, including those written before the {\itshape plot pnm} command option was implemented. \section{Conditionals, File Inclusions, and Macro Definitions} The ``raw'' technology files in the {\bfseries scmos} subdirectory of the Magic distribution were written for a C preprocessor and cannot be read directly by Magic. The C preprocessor must first be used to eliminate comments and expand macros in a technology file before it gets installed, which is done during the ``{\bfseries make install}'' step when compiling and installing Magic from source. Macro definitions can be made with the preprocessor {\bfseries \#define} statement, and ``conditional compilation'' can be specified using {\bfseries \#ifdef}. Also, the technology file can be split into parts using the {\bfseries \#include} statement to read in different parts of the files. However, this has for the most part proven to be a poor method for maintaining technology files. End-users often end up making modifications to the technology files for one purpose or another. They should not need to be making changes to the source code distribution, they often do not have write access to the source distribution, and furthermore, the elimination of comments and macros from the file makes the actual technology file used difficult to read and understand. Technology file formats more recent that 27 include several built-in mechanisms that take the place of preprocessor statements, and allow the technology file source to be directly edited without the need to re-process. This includes the {\bfseries include} statement, which may be used anywhere in the technology file, the {\bfseries alias} statement in the {\bfseries types} section, and the {\bfseries variant} statement, which may be used in the {\bfseries cifoutput}, {\bfseries cifinput}, or {\bfseries extract} sections. The {\bfseries alias} statements appear in the {\bfseries types} section, covered above. The {\bfseries include} statement may appear anywhere in the file, and takes the form \starti \ii {\bfseries include} {\itshape filename} \endi Assuming that the included files exist in the search path Magic uses for finding system files (see command {\bfseries path sys}), then no absolute path needs to be speficied for {\itshape filename}. Note that the file contents will be included verbatim; section names and {\bfseries end} statements that appear in the included file should not exist in the file that includes it, and vice versa. %--------------------------------------------------------------------- The most common use of ``\#ifdef'' preprocessor statements in the default ``scmos'' technology is to selectively define different cifoutput, cifinput, and extract files for process variants. The result is that these sections become quite large and repeat many definitions that are common to all process variations. Technology file format 30 defines the {\bfseries variants} option to the {\bfseries style} statement for all three sections {\bfseries cifinput}, {\bfseries cifoutput}, and {\bfseries extract}. This statment option takes the form: \starti \ii {\bfseries style} {\itshape stylename} {\bfseries variants} {\itshape variantname,\dots} \endi where {\itshape stylename} is a base name used for all variants, and one of the comma-separated list of {\itshape variantname}s is a suffix appended to the {\itshape stylename} to get the actual name as it would be used in, for example, a {\bfseries cif ostyle} command. For example, the statement \starti \ii {\bfseries style scmos0.18 variants (p),(c),(pc),()} \endi defines four similar styles named {\bfseries scmos0.18(p)}, {\bfseries scmos0.18(c)}, {\bfseries scmos0.18(pc)}, and {\bfseries scmos0.18()}. All of the variants are assumed to be minor variations on the base style. Within each style description, statements may apply to a single variant, a group of variants, or all variants. After the {\bfseries style} statement has been processed, all following lines are assumed to refer to all variants of the base style until a {\bfseries variant} statment is encountered. This statment takes the form: \starti \ii {\bfseries variant} {\itshape variantname,\dots} \endi to refer to one or more variants in a comma-separated list. All lines following the {\bfseries variant} statment will apply only to the specific process variants in the list, until another {\bfseries variant} statement is encountered. The special character ``{\bfseries *}'' can be used as a shorthand notation for specifying all process variants: \starti \ii {\bfseries variant *} \endi \end{document} magic-8.0.210/doc/latexfiles/maint3.tex0000644000175000001440000003101610751423606016301 0ustar timusers%---------------------------------------------------------------------------- % Magic Maintainer's Manual #3 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Magic Maintainer's Manual \#3: Display Styles, Colormaps, and Glyphs} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape Robert N. Mayo} \\ {\itshape John Ousterhout} \\ \vspace*{0.5in} Computer Science Division \\ Electrical Engineering and Computer Sciences \\ University of California \\ Berkeley, CA 94720 \\ \vspace*{0.25in} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Tutorials to read first:} \starti \> All of them. \endi {\noindent\bfseries\large Commands introduced in this tutorial:} \starti \> {\itshape (None)} \endi {\noindent\bfseries\large Macros introduced in this tutorial:} \starti \> {\itshape (None)} \endi \vspace*{0.75in} \section{Introduction} This document gives overall information about the files that tell Magic how to display information on the screen. There are three types of files that contain display information: display styles files, color-map files, and glyph files. \section{Display Styles} Display styles files describe how to draw rectangular areas and text. A single file contains a large number of display styles. Each display style contains two kinds of information: a) how to modify pixels (which bits of the pixel should be changed and what their new value(s) should be); and b) which pixels to modify. Part b) consists of things like ``fill the entire area,'' or ``modify only those pixels in the area that are given by a particular stipple pattern,'' or ``draw a dashed-line around the area's outline.'' In the case of text, ``which pixels to modify'' is determined by the font for the text, which is not part of the display style, so the display style information for this is ignored. See the manual page {\bfseries dstyle~(5)} for details on the format of display styles files. Display styles are designed to take into account both the characteristics of certain technologies and the characteristics of certain displays. For example, a bipolar process may require information to be displayed very differently than a MOS process, and a black-and-white display will be used much differently than a color display. Thus there can be many different display styles files, each corresponding to a particular class of technologies and a class of displays. The names of styles files reflect these classes: each display styles file has a name of the form {\itshape x}{\bfseries .}{\itshape y}{\bfseries .dstyle}, where {\itshape x} is the technology class (given by the {\bfseries styletype} line in the {\bfseries styles} section of the technology file), and {\itshape y} is the class of display. Each display driver knows its display class; the driver initialization routine sets an internal Magic variable with the display class to use. Right now we have two display styles files: {\bfseries mos.7bit.dstyle} and {\bfseries mos.bw.dstyle}. Both files contain enough different styles to handle a variety of MOS processes, including both nMOS and CMOS (hence the {\bfseries mos} field). {\bfseries Mos.7bit.dstyle} is designed for color displays with at least seven bits of color per pixel, while {\bfseries mos.bw.dstyle} is for black-and-white displays (stipple patterns are used instead of colors). \section{Color Maps} The display styles file tells how to modify pixels, but this doesn't completely specify the color that will be displayed on the screen (unless the screen is black-and-white). For color displays, the pixel values are used to index into a {\itshape color map}, which contains the red, green, and blue intensity values to use for each pixel value. The values for color maps are stored in color-map files and can be edited using the color-map-editing window in Magic. See {\bfseries cmap~(5)} for details on the format of color-map files. Each display styles file uses a separate color map. Unfortunately, some monitors have slightly different phosphors than others; this will result in different colors if the same intensity values are used for them. To compensate for monitor differences, Magic supports multiple color maps for each display style, depending on the monitor being used. The monitor type can be specified with the {\bfseries -m} command line switch to Magic, with {\bfseries std} as the default. Color-map files have names of the form {\itshape x}{\bfseries .}{\itshape y}{\bfseries .}{\itshape z} {\bfseries .cmap}, where {\itshape x} and {\itshape y} have the same meaning as for display styles and {\itshape z} is the monitor type. Over the last few years monitor phosphors appear to have standardized quite a bit, so almost all monitors now work well with the {\bfseries std} monitor type. The color map {\bfseries mos.7bit.std.cmap} is the standard one used at Berkeley. \section{Transparent and Opaque Layers} One of the key decisions in defining a set of display styles for a color display is how to use the bits of a pixel (this section doesn't apply to black-and-white displays). One option is to use a separate bit of each pixel (called a {\itshape bit plane}) for each mask layer. The advantage of this is that each possible combination of layer overlaps results in a different pixel value, and hence a different color (if you wish). Thus, for example, if metal and poly are represented with different bit planes, poly-without-metal, metal-without-poly, poly-and-metal, and neither-poly-nor-metal will each cause a different value to be stored in the pixel. A different color can be used to display each of these combinations. Typically, the colors are chosen to present an illusion of transparency: the poly-and-metal color is chosen to make it appear as if metal were a transparent colored foil placed on top of poly. You can see this effect if you paint polysilicon, metal1, and metal2 on top of each other in our standard technologies. The problem with transparent layers is that they require many bits per pixel. Most color displays don't have enough planes to use a different one for each mask layer. Another option is to use a group of planes together. For example, three bits of a pixel can be used to store seven mask layers plus background, with each mask layer corresponding to one of the combinations of the three bits. The problem with this scheme is that there is no way to represent overlaps: where there is an overlap, one of the layers must be displayed at the expense of the others. We call this scheme an {\itshape opaque} one since when it is used it appears as if each layer is an opaque foil, with the foils lying on top of each other in some priority order. This makes it harder to see what's going on when there are several mask layers in an area. The display styles files we've designed for Magic use a combination of these techniques to get as much transparency as possible. For example, our {\bfseries mos.7bit.dstyle} file uses three bits of the pixel in an opaque scheme to represent polysilicon, diffusion, and various combinations of them such as transistors. Two additional bits are used, one each, for the two metal layers, so they are transparent with respect to each other and the poly-diff combinations. Thus, although only one poly-diff combination can appear at each point, it's possible to see the overlaps between each of these combinations and each combination of metal1 and metal2. Furthermore, all of these styles are overridden if the sixth bit of the pixel is set. In this case the low order five bits no longer correspond to mask layers; they are used for opaque layers for things like labels and cell bounding boxes, and override any mask information. Thus, for example, when metal1 is displayed it only affects one bit plane, but when labels are displayed, the entire low-order six bits of the pixel are modified. It's important that the opaque layers like labels are drawn after the transparent things that they blot out; this is guaranteed by giving them higher style numbers in the display styles files. Finally, the seventh bit of the pixel is used for highlights like the box and the selection. All 64 entries in the color map corresponding to pixel values with this bit set contain the same value, namely pure white. This makes the highlights appear opaque with respect to everything else. However, since they have their own bit plane which is completely independent of anything else, they can be drawn and erased without having to redraw any of the mask information underneath. This is why the box can be moved relatively quickly. On the other hand, if Magic erases a label it must redraw all the mask information in the area because the label shared pixel bits with the mask information. Thus, the scheme we've been using for Magic is a hierarchical combination of transparent and opaque layers. This scheme is defined almost entirely by the styles file, so you can try other schemes if you wish. However, you're likely to have problems if you try anything too radically different; we haven't tried any schemes but the one currently being used so there are probably some code dependencies on it. For more information on transparent and opaque layers, see the paper ``The User Interface and Implementation of an IC Layout Editor,'' which appeared in {\itshape IEEE Transactions on CAD} in July 1984. \section{Glyphs} Glyphs are small rectangular bit patterns that are used in two places in Magic. The primary use for glyphs is for programmable cursors, such as the shapes that show you which corner of the box you're moving and the various tools described in Tutorial \#3. Each programmable cursor is stored as a glyph describing the pattern to be displayed in the cursor. The second use of glyphs is by the window package: the little arrow icons appearing at the ends of scroll bars are stored as glyphs, as is the zoom box in the lower-left corner of the window. We may eventually use glyphs in a menu interface (but don't hold your breath). Glyphs are stored in ASCII glyph files, each of which can hold one or more glyph patterns. Each glyph is represented as a pattern of characters representing the pixels in the glyph. Each character selects a display style from the current display styles file; the display style indicates the color to use for that pixel. See the manual page {\bfseries glyphs~(5)} for details on the syntax of glyphs files. The window glyphs are stored in files of the form {\bfseries windows}{\itshape XX}{\bfseries .glyphs}. The {\itshape XX} indicates how wide the glyphs are, and is set by the graphics driver for a particular display. We started out with a {\bfseries windows7.glyphs} and a {\bfseries windows11.glyphs}. Since then, display resolution has increased greatly so we have also created a {\bfseries windows14.glyphs} and a {\bfseries windows22.glyphs}. The positions of the various glyphs in these files is important, and is defined in the {\bfseries window} module of Magic. Programmable cursors are stored in files named {\itshape x}{\bfseries .glyphs}, where {\itshape x} is determined by the device driver for the display. Displays capable of supporting full-color cursors use {\bfseries color.glyphs}; displays that can only support monochrome cursors used {\bfseries bw.glyphs}. The order of the various glyphs in these files is important. It is defined by the files {\bfseries styles.h} in the {\bfseries misc} module of Magic. \end{document} magic-8.0.210/doc/latexfiles/introduction.tex0000644000175000001440000002623710751423606017640 0ustar timusers%---------------------------------------------------------------------------- % Magic Overview %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Overview of the DECWRL/Livermore Magic Release (Version~6)} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} \section{Introduction} This version of Magic, version 6, gathers together work done by numerous people at several institutions since Magic version 4 was released from Berkeley on the 1986 VLSI tools tape. This is a release of Magic and IRSIM only. You'll probably want to obtain other tools by ordering the 1986 VLSI Tools Tape from Berkeley. This release has been prepared with the assistance of several groups. Much of the new software came from Walter Scott's group at the Lawrence Livermore National Labs (LLNL). LLNL also provided partial funding to help prepare the release. Digital Equipment Corporation's Western Research Lab (DECWRL) helped out by providing computer equipment, a place to work, and the services of one of us (Robert Mayo). Don Stark, Michael Arnold, and Gordon Hamachi also worked on the release at DECWRL. Stanford donated significant pieces of new code, including a simulation system called IRSIM. Other individuals and institutions have also contributed code and assistance in ways too numerous to detail here. New features in Magic Version 6 include: \begin{itemize} \item New and Improved Routing---{\itshape Michael Arnold and Walter Scott of LLNL} \\ Three major routing improvements have been made in this version of Magic. There is a new, improved, global router courtesy of Walter Scott (of LLNL). Walter Scott has also added a gate array router. See the ``garoute'' command in the manual page for details. Michael Arnold (of LLNL) has written an interactive maze router that allows the user to specify hints to control the routing. See the documentation for the ``iroute'' command. \item Extractor Enhancements---{\itshape Don Stark of Stanford and Walter Scott of LLNL} \\ The new ``extresis'' command, developed by Don Stark, provides substantially better resistance extraction. Magic's normal extraction (``extract'') lumps resistances on a node into a single value. In branching networks, this approximation is often not acceptable. Resis was written to solve this problem. Walter Scott added accurate path length extraction, an important feature when dealing with high speed circuits, such as ECL. \item New contact structure---{\itshape Walter Scott and Michael Arnold of LLNL and Don Stark of Stanford} \\ Multilayer contacts are handled better. In the previous version of Magic, there needed to be a separate contact type for each possible combination of contact layers over a given point. This caused a combinatorial explosion of tile types for multi-layer technologies with stacked contacts. Under the new scheme, there are only a couple of tile types for each layer: one that connects up, one that connects down, and one that connects in both directions. \item Simulator Interface to IRSIM---{\itshape Stanford} \\ A simulator interface is provided courtesy of Stanford. See the commands ``startrsim'', ``simcmd'', and ``rsim''. The irsim simulator, Stanford's much improved rewrite of esim, is included in this distribution. Credit goes to Mike Chow, Arturo Salz, and Mark Horowitz. \item New device/machine Support---{\itshape Various} \\ X11 is fully supported in this release, and is the preferred interface. Older drivers for graphics terminals and X10 are also included, but X11 is the preferred interface (meaning it is better supported and you'll have lots of company). Magic's X11 driver has a long history, starting with an X10 driver by Doug Pan at Stanford. Brown University, the University of Southern California, the University of Washington, and Lawrence Livermore National Labs all prepared improved versions, some of them for X11. Don Stark of Stanford took on the task of pulling these together and producing the X11 driver in this release. Magic runs on a number of workstations, such as the DECstation 3100 and Sun's SPARC processors. Partial Unix System V support is provided, via the compilation flags mentioned below. The system also runs on the MacII. Don Stark gets credit for the System V mods and support for HP machines, while Mike Chow helped get it running on the MacII. To assist people with small machines (such as the Mac II), Magic can now be compiled without some of its fancy features. Compilation flags are provided, as indicated below, to eliminate things like routing, plotting, or calma output. This is courtesy of Don Stark. \item Reorganization of Magic Source Directory \\ Magic, as previously distributed, was set up with the assumption that lots of people would be changing the code at the same time. As a result, the makefiles did all sorts of paranoid things like making extra copies of the source code whenever a module was re-installed. Since Magic is more stable now, this copying is no longer needed. Instead, each makefile invokes the script {\bfseries ../:instclean} after installing a module. This script, by default, doesn't copy the source code but does leave the .o files around. This cuts down on the disk space needed by a factor of two. You can change the script if you want the copying, or if you want to delete unused .o files to save even more disk space. \item Lots of bug fixes---{\itshape Various} \\ Lots of bugs have been fixed in this release. We'd like to thank everybody that has reported bugs in the past. If you find a new bug, please report it as mentioned below. \end{itemize} \section{Distribution Information} This version of Magic is available via FTP. Contact ``{\ttfamily magic@decwrl.dec.com}'' for information. For a handling fee, this version of Magic may be obtained on magnetic tape from: \starti \ii EECS/ERL Industrial Liaison Program \\ \ii 479 Cory Hall \\ \ii University of California at Berkeley \\ \ii Berkeley, CA 94720 \endi \section{Bug Reports} Maintenance of Magic is a volunteer effort. Please send descriptions of bugs via InterNet e-mail to ``{\ttfamily magic@decwrl.dec.com}'' or via Uucp e-mail to ``{\ttfamily decwrl!magic}''. If you develop a fix for the problem, please send that too! \section{Changes for Magic maintainers} Previous releases of Magic expected to find their system files in the home directory of the user {\bfseries cad}. The default behavior of version 6 is no different, but it is possible to put the files in another directory by setting the {\bfseries CAD{\_}HOME} shell environment variable. If this variable is set, magic will use that location instead of the \~{}cad it finds in the password file. \subsection{INSTALLING MAGIC} The distribution tape contains a version of Magic ready to run on Digital's line of Ultrix RISC workstations, such as the DECstation 3100. For other machines, read ahead. In any event, all users should set their shell environment variable CAD{\_}HOME to point to the place where the tape is loaded, unless that place is \~{}cad, in which case things will default correctly. Before installing Magic, you should set your shell environment variable CAD{\_}HOME to point to the place where you loaded the tape. If you ``cd'' to the magic source directory (\${CAD{\_}HOME}/src/magic) you will find a makefile. A ``{\bfseries make config}'' will run a configuration script that asks questions about your configuration and sets up magic to be compiled for your local environment. After running a ``make config'', you can run a ``{\bfseries make force}'' to force a complete recompilation of magic. A "{\bfseries make install}" will then copy the binaries to the \${CAD{\_}HOME}/bin area, as well as install things in \${CAD{\_}HOME}/lib and \${CAD{\_}HOME}/man. Included in this documentation is a set of Magic maintainer's manuals. These should be read by anybody interested in modifying Magic or by anybody that is having difficulty installing it on their system. \subsection{Technology file changes} Users of Magic 4 should have little trouble switching to Magic 6. A new section, the {\bfseries mzrouter} section needs to be added to your technology files. See the mzrouter section of the tutorial {\itshape Magic Maintainer's Manual \#2: The Technology File} for details. Display styles must be defined in the {\itshape .tech} file for the mzrouter hint layers magnet, fence and rotate. We suggest copying this information from the styles section of the scmos technology file on the distribution tape. You'll also need to include these display styles in your {\itshape .dstyle} file. \section{Beta-test Sites} We'd like to thank the beta-test sites that tried out this version of Magic, reported bugs and fixes in a timely manner, and ported the code to new machines: \starti \> Mike Chow, Apple Computer \\ \> Arun Rao, Arizona State University \\ \> Richard Hughey, Brown University \\ \> Rick Carley, Carnegie-Mellon University \\ \> Hank Walker, Carnegie-Mellon University \\ \> Christos Zoulas, Cornell University \\ \> Andreas Andreou, John Hopkins University \\ \> George Entenman, The Microelectronics Center of North Carolina \\ \> Shih-Lien Lu, The MOSIS Service \\ \> Jen-I Pi, The MOSIS Service \\ \> Guntram Wolski, Silicon Engineering, Inc. \\ \> Don Stark, Stanford University \\ \> Gregory Frazier, University of California at Los Angeles \\ \> Yuval Tamir, University of California at Los Angeles \\ \> Steven Parkes, University of Illinois \\ \> Larry McMurchie, University of Washington \\ \> Tim Heldt, Washington State University \\ \> David Lee, Xerox Palo Alto Research Center \\ \endi Martin Harriman of Silicon Engineering wrote a ``select less'' command for Magic during the beta-test phase. ``Select less'' has been a much-requested feature. In addition to the persons named above, there were many other beta-test users of Magic at these and other sites---too many to list here. We appreciate their help. We also acknowledge the help of the pre-release sites, who tested a version that included most of the fixes from the beta-test phase. \end{document} magic-8.0.210/doc/latexfiles/tuttcl3.tex0000644000175000001440000000354610751423606016517 0ustar timusers%---------------------------------------------------------------------------- % Magic Tcl tutorial number 3 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ig{\>} \def\ih{\>\>} \def\ii{\>\>\>} \def\mytitle{Magic Tcl Tutorial \#3: Extracting and Netlisting} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape R. Timothy Edwards} \\ \vspace*{0.5in} Space Department \\ Johns Hopkins University \\ Applied Physics Laboratory \\ Laurel, MD 20723 \\ \vspace*{0.25in} This tutorial corresponds to Tcl-based Magic version 7.2 \\ \end{center} \vspace*{0.5in} \section{Tech file extensions for extraction} \section{Commands exttospice and exttosim} \end{document} magic-8.0.210/doc/latexfiles/maint4.tex0000644000175000001440000001725210751423606016310 0ustar timusers%---------------------------------------------------------------------------- % Magic Maintainer's Manual number 4 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Magic Maintainer's Manual \#4: Using Magic Under X Windows} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape Don Stark} \\ \vspace*{0.5in} Computer Systems Laboratory \\ Stanford University \\ Stanford, CA 94305 \\ \vspace*{0.25in} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Tutorials to read first:} \starti \> Magic Tutorial \#1: Getting Started \endi {\noindent\bfseries\large Commands introduced in this tutorial:} \starti \> {\itshape (None)} \endi {\noindent\bfseries\large Macros introduced in this tutorial:} \starti \> {\itshape (None)} \endi \section{Introduction} This document provides information on Magic's X drivers that may be of help to system maintainers. \section{Compiling the Correct X Driver for your system.} Unfortunately, it is not possible to link with both the X10 and X11 libraries, so you will have to compile Magic differently depending on the version of X that you are running. \subsection{Compiling for X11} \begin{enumerate} \item Add the flag -DX11 to misc/DFLAGS \item Add -lX11 to magic/LIBS \item Change the SRCS line in graphics/Makefile to \${BASE{\_}SRCS} \${X11{\_}SRCS} \item Change the OBJS line to \${BASE{\_}OBJS} \${X11{\_}OBJS} \item Change the POBJS line to \${BASE{\_}POBJS} \${X11{\_}POBJS} \item Change the HELPER{\_}SRCS line \${X11HELPER{\_}SRCS} \item Change the HELPER{\_}SRCS line \${X11HELPER{\_}PROG} \item Compile the module graphics.o \item Relink magic \end{enumerate} \subsection{Compiling for X10} \begin{enumerate} \item Add the flag -DX10 to misc/DFLAGS \item Add -lX10 to magic/LIBS \item Change the SRCS line in graphics/Makefile to \${BASE{\_}SRCS} \${X10{\_}SRCS} \item Change the OBJS line to \${BASE{\_}SRCS} \${X10{\_}OBJS} \item Change the POBJS line to \${BASE{\_}SRCS} \${X10{\_}POBJS} \item Change the HELPER{\_}SRCS line \${X10HELPER{\_}SRCS} \item Change the HELPER{\_}SRCS line \${X10HELPER{\_}PROG} \item Compile the module graphics.o \item Relink magic \end{enumerate} \section{Troubleshooting the X Drivers} The following is a list of problems sometimes encountered in running Magic under X and some suggestions about how to get around the problem. \subsection{X11 Driver} \begin{itemize} \item Fonts \\ We have tried to pick a set of fonts that most machines running X11 Revision 3 will have, but there is nothing to guarantee that a given machine will have a font. If you're getting "unable to load font" messages, you will need to change the fonts that Magic uses. The simplest way to do this is to specify them in your .Xdefaults file as described in section 2.1. To change the default values that Magic uses, change the "fontnames" array in the file grX11su3.c of the graphics module. The program {\itshape xlsfonts} will tell you what fonts are available on your machine. \item Strange Color Effects \\ Magic often co-exists rather uneasily with other X applications because it is picky about which colors it is allocated. If possible, it tries to allocate the colors it requires out of the display's default colormap because this perturbs other applications the least. If this fails, however, Magic makes its own colormap. When this colormap gets installed is a function of the window manager; most window managers install it when the cursor is in the magic window. Unfortunately, there is no way to guarantee that the window manager installs the magic colormap correctly; if you get erratic colormap behavior, try using a lower number of planes or reducing the number of colors that other applications use. \item When magic's colormap is being used, other windows may change color, possibly to some unusable combination such as black on black or white on white. This problem can sometimes be ameliorated by changing the constants X{\_}COLORMAP{\_}BASE and X{\_}COLORMAP{\_}RESERVED in grX11su2.c; a more complete description of what these constants do is included in that file. Values for these constants that are incompatible with your machine will sometimes generate Xerrors in XQueryColors. \item Failure to prompt user for window position \\ Whether or not the designer is prompted for a window's location is dependent on the window manager. Certain window managers, notably {\itshape twm}, do not always do this. \end{itemize} \subsection{X10 Driver} In general, the Version 10 driver is less reliable than the X11 one. If you have the choice, you are better off running under X11. \begin{itemize} \item grX2.GrXSetCMap: Failed to get color cells \\ Magic gives this error when it can't get sufficient colors to run. This can be caused by running Magic on a machine with an insufficient number of planes (8 planes are generally required to run a 7 bit dstyles file), or by having too many colors already used by other applications. Try using only black and white xterms, xclocks, etc., and see if the problem goes away. \item Couldn\'t get 7 planes; allocating by color \\ Certain X10 servers, most notably the VaxstationII-GPX, allocate colors in such a way that Magic can never get the 7 color planes that it wants. When this happens, Magic instead allocates 128 colors. This is better than nothing, but not by much; strange colors often result when layers overlap. \end{itemize} \section{Acknowledgments} Many people share the credit (and the blame) for the Magic X drivers. The original X10 port was done by Mark Linton and Doug Pan at Stanford University. Walter Scott and Eric Lunow of Lawrence Livermore National Laboratories modified the driver and the windows module so that magic windows act like normal X windows. Meanwhile, Dave Durfee and Markus G. Wloka of Brown University improved the reliability of the Stanford X10 driver and added support for a variable number of planes. Marco Papa of USC converted the Brown X10 driver to X11. Concurrently, someone at the University of Washington converted the Stanford X10 driver to X11. The X11 driver in this distribution is predominantly a merge of the UW driver with the multiwindow features of the LLNL driver. Some of the ideas for supporting differing plane counts were borrowed from the USC/Brown work. Thanks to the Digital Equipment Corporation Western Research Laboratory (DECWRL) for use of their computer facilities, and to Mike Chow of Apple Computer for the Macintosh II-specific changes. \end{document} magic-8.0.210/doc/latexfiles/tut3.tex0000644000175000001440000005416210751423606016014 0ustar timusers%---------------------------------------------------------------------------- % Magic tutorial number 3 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Magic Tutorial \#3: Advanced Painting (Wiring and Plowing)} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape John Ousterhout} \\ {\itshape Walter Scott} \\ \vspace*{0.5in} Computer Science Division \\ Electrical Engineering and Computer Sciences \\ University of California \\ Berkeley, CA 94720 \\ \vspace*{0.25in} {\itshape (Updated by others, too.)} \\ \vspace*{0.25in} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Tutorials to read first:} \starti \> Magic Tutorial \#1: Getting Started \\ \> Magic Tutorial \#2: Basic Painting and Selection \endi {\noindent\bfseries\large Commands introduced in this tutorial:} \starti \> :array, :corner, :fill, :flush, :plow, :straighten, :tool, :wire \endi {\noindent\bfseries\large Macros introduced in this tutorial:} \starti \> $<$space$>$ \endi \vspace*{0.5in} \section{Introduction} Tutorial \#2 showed you the basic facilities for placing paint and labels, selecting, and manipulating the things that are selected. This tutorial describes two additional facilities for manipulating paint: wiring and plowing. These commands aren't absolutely necessary, since you can achieve the same effect with the simpler commands of Tutorial \#2; however, wiring and plowing allow you to perform certain kinds of manipulations much more quickly than you could otherwise. Wiring is described in Section 2; it allows you to place wires by pointing at the ends of legs rather than by positioning the box, and also provides for convenient contact placement. Plowing is the subject of Section 3. It allows you to re-arrange pieces of your circuit without having to worry about design-rule violations being created: plowing automatically moves things out of the way to avoid trouble. \section{Wiring} The box-and-painting paradigm described in Tutorial \#2 is sufficient to create any possible layout, but it's relatively inefficient since three keystrokes are required to paint each new area: two button clicks to position the box and one more to paint the material. This section describes a different painting mechanism based on {\itshape wires}. At any given time, there is a current wiring material and wire thickness. With the wiring interface you can create a new area of material with a single button click: this paints a straight-line segment of the current material and width between the end of the previous wire segment and the cursor location. Each additional button click adds an additional segment. The wiring interface also makes it easy for you to place contacts. \section{Tools} Before learning about wiring, you'll need to learn about tools. Until now, when you've pressed mouse buttons in layout windows the buttons have caused the box to change or material to be painted. The truth is that buttons can mean different things at different times. The meaning of the mouse buttons depends on the {\itshape current tool}. Each tool is identified by a particular cursor shape and a particular interpretation of the mouse buttons. Initially, the current tool is the box tool; when the box tool is active the cursor has the shape of a crosshair. To get information about the current tool, you can type the long command \starti \ii {\bfseries :tool info} \endi This command prints out the name of the current tool and the meaning of the buttons. Run Magic on the cell {\bfseries tut3a} and type {\bfseries :tool info}. The {\bfseries :tool} command can also be used to switch tools. Try this out by typing the command \starti \ii {\bfseries :tool} \endi Magic will print out a message telling you that you're using the wiring tool, and the cursor will change to an arrow shape. Use the {\bfseries :tool info} command to see what the buttons mean now. You'll be using the wiring tool for most of the rest of this section. The macro `` '' (space) corresponds to {\bfseries :tool}. Try typing the space key a few times: Magic will cycle circularly through all of the available tools. There are three tools in Magic right now: the box tool, which you already know about, the wiring tool, which you'll learn about in this tutorial, and the netlist tool, which has a square cursor shape and is used for netlist editing. ``Tutorial \#7: Netlists and Routing'' will show you how to use the netlist tool. The current tool affects only the meanings of the mouse buttons. It does not change the meanings of the long commands or macros. This means, for example, that you can still use all the selection commands while the wiring tool is active. Switch tools to the wiring tool, point at some paint in {\bfseries tut3a}, and type the {\bfseries s} macro. A chunk gets selected just as it does with the box tool. \section{Basic Wiring} There are three basic wiring commands: selecting the wiring material, adding a leg, and adding a contact. This section describes the first two commands. At this point you should be editing the cell {\bfseries tut3a} with the wiring tool active. The first step in wiring is to pick the material and width to use for wires. This can be done in two ways. The easiest way is to find a piece of material of the right type and width, point to it with the cursor, and click the left mouse button. Try this in {\bfseries tut3a} by pointing to the label {\bfseries 1} and left-clicking. Magic prints out the material and width that it chose, selects a square of that material and width around the cursor, and places the box around the square. Try pointing to various places in {\bfseries tut3a} and left-clicking. Once you've selected the wiring material, the right button paints legs of a wire. Left-click on label {\bfseries 1} to select the red material, then move the cursor over label {\bfseries 2} and right-click. This will paint a red wire between {\bfseries 1} and {\bfseries 2}. The new wire leg is selected so that you can modify it with selection commands, and the box is placed over the tip of the leg to show you the starting point for the next wire leg. Add more legs to the wire by right-clicking at {\bfseries 3} and then {\bfseries 4}. Use the mouse buttons to paint another wire in blue from {\bfseries 5} to {\bfseries 6} to {\bfseries 7}. Each leg of a wire must be either horizontal or vertical. If you move the cursor diagonally, Magic will still paint a horizontal or vertical line (whichever results in the longest new wire leg). To see how this works, left-click on {\bfseries 8} in {\bfseries tut3a}, then right-click on {\bfseries 9}. You'll get a horizontal leg. Now undo the new leg and right-click on {\bfseries 10}. This time you'll get a vertical leg. You can force Magic to paint the next leg in a particular direction with the commands \starti \ii {\bfseries :wire horizontal} \\ \ii {\bfseries :wire vertical} \endi Try out this feature by left-clicking on {\bfseries 8} in {\bfseries tut3a}, moving the cursor over {\bfseries 10}, and typing {\bfseries :wire ho} (abbreviations work for {\bfseries :wire} command options just as they do elsewhere in Magic). This command will generate a short horizontal leg instead of a longer vertical one. \section{Contacts} When the wiring tool is active, the middle mouse button places contacts. Undo all of your changes to {\bfseries tut3a} by typing the command {\bfseries :flush} and answering {\bfseries yes} to the question Magic asks. This throws away all of the changes made to the cell and re-loads it from disk. Draw a red wire leg from {\bfseries 1} to {\bfseries 2}. Now move the cursor over the blue area and click the middle mouse button. This has several effects. It places a contact at the end of the current wire leg, selects the contact, and moves the box over the selection. In addition, it changes the wiring material and thickness to match the material you middle-clicked. Move the cursor over {\bfseries 3} and right-click to paint a blue leg, then make a contact to purple by middle-clicking over the purple material. Continue by drawing a purple leg to {\bfseries 4}. Once you've drawn the purple leg to {\bfseries 4}, move the cursor over red material and middle-click. This time, Magic prints an error message and treats the click just like a left-click. Magic only knows how to make contacts between certain combinations of layers, which are specified in the technology file (see ``Magic Maintainer's Manual \#2: The Technology File''). For this technology, Magic doesn't know how to make contacts directly between purple and red. \section{Wiring and the Box} In the examples so far, each new wire leg appeared to be drawn from the end of the previous leg to the cursor position. In fact, however, the new material was drawn from the {\itshape box} to the cursor position. Magic automatically repositions the box on each button click to help set things up for the next leg. Using the box as the starting point for wire legs makes it easy to start wires in places that don't already have material of the right type and width. Suppose that you want to start a new wire in the middle of an empty area. You can't left-click to get the wire started there. Instead, you can left-click some other place where there's the right material for the wire, type the space bar twice to get back the box tool, move the box where you'd like the wire to start, hit the space bar once more to get back the wiring tool, and then right-click to paint the wire. Try this out on {\bfseries tut3a}. When you first start wiring, you may not be able to find the right kind of material anywhere on the screen. When this happens, you can select the wiring material and width with the command \starti \ii {\bfseries :wire type} {\itshape layer} {\itshape width} \endi Then move the box where you'd like the wire to start, switch to the wiring tool, and right-click to add legs. \section{Wiring and the Selection} Each time you paint a new wire leg or contact using the wiring commands, Magic selects the new material just as if you had placed the cursor over it and typed {\bfseries s}. This makes it easy for you to adjust its position if you didn't get it right initially. The {\bfseries :stretch} command is particularly useful for this. In {\bfseries tut3a}, paint a wire leg in blue from {\bfseries 5} to {\bfseries 6} (use {\bfseries :flush} to reset the cell if you've made a lot of changes). Now type {\bfseries R} two or three times to stretch the leg over to the right. Middle-click over purple material, then use {\bfseries W} to stretch the contact downward. It's often hard to position the cursor so that a wire leg comes out right the first time, but it's usually easy to tell whether the leg is right once it's painted. If it's wrong, then you can use the stretching commands to shift it over one unit at a time until it's correct. \section{Bundles of Wires} Magic provides two additional commands that are useful for running {\itshape bundles} of parallel wires. The commands are: \starti \ii {\bfseries fill} {\itshape direction }[{\itshape layers}] \\ \ii {\bfseries corner} {\itshape direction1 direction2 }[{\itshape layers}] \endi To see how they work, load the cell {\bfseries tut3b}. The {\bfseries :fill} comand extends a whole bunch of paint in a given direction. It finds all paint touching one side of the box and extends that paint to the opposite side of the box. For example, {\bfseries :fill left} will look underneath the right edge of the box for paint, and will extend that paint to the left side of the box. The effect is just as if all the colors visible underneath that edge of the box constituted a paint brush; Magic sweeps the brush across the box in the given direction. Place the box over the label ``Fill here'' in {\bfseries tut3b} and type {\bfseries :fill left}. The {\bfseries :corner} command is similar to {\bfseries :fill} except that it generates L-shaped wires that follow two sides of the box, travelling first in {\itshape direction1} and then in {\itshape direction2}. Place the box over the label ``Corner here'' in {\bfseries tut3b} and type {\bfseries :corner right up}. In both {\bfseries :fill} and {\bfseries :corner}, if {\itshape layers} isn't specified then all layers are filled. If {\itshape layers} is given then only those layers are painted. Experiment on {\bfseries tut3b} with the {\bfseries :fill} and {\bfseries :corner} commands. When you're painting bundles of wires, it would be nice if there were a convenient way to place contacts across the whole bundle in order to switch to a different layer. There's no single command to do this, but you can place one contact by hand and then use the {\bfseries :array} command to replicate a single contact across the whole bundle. Load the cell {\bfseries tut3c}. This contains a bundle of wires with a single contact already painted by hand on the bottom wire. Type {\bfseries s} with the cursor over the contact, and type {\bfseries S} with the cursor over the stub of purple wiring material next to it. Now place the box over the label ``Array'' and type the command {\bfseries :array 1 10}. This will copy the selected contact across the whole bundle. The syntax of the {\bfseries :array} command is \starti \ii {\bfseries :array} {\itshape xsize ysize} \endi This command makes the selection into an array of identical elements. {\itshape Xsize} specifies how many total instances there should be in the x-direction when the command is finished and {\itshape ysize} specifies how many total instances there should be in the y-direction. In the {\bfseries tut3c} example, {\bfseries xsize} was one, so no additional copies were created in that direction; {\bfseries ysize} was 10, so 9 additional copies were created. The box is used to determine how far apart the elements should be: the width of the box determines the x-spacing and the height determines the y-spacing. The new material always appears above and to the right of the original copy. In {\bfseries tut3c}, use {\bfseries :corner} to extend the purple wires and turn them up. Then paint a contact back to blue on the leftmost wire, add a stub of blue paint above it, and use {\bfseries :array} to copy them across the top of the bundle. Finally, use {\bfseries :fill} again to extend the blue bundle farther up. \section{Plowing} Magic contains a facility called {\itshape plowing} that you can use to stretch and compact cells. The basic plowing command has the syntax \starti \ii {\bfseries :plow} {\itshape direction }[{\itshape layers}] \endi where {\itshape direction} is a Manhattan direction like {\bfseries left} and {\itshape layers} is an optional, comma-separated list of mask layers. The plow command treats one side of the box as if it were a plow, and shoves the plow over to the other side of the box. For example, {\bfseries :plow up} treats the bottom side of the box as a plow, and moves the plow to the top of the box. As the plow moves, every edge in its path is pushed ahead of it (if {\itshape layers} is specified, then only edges on those layers are moved). Each edge that is pushed by the plow pushes other edges ahead of it in a way that preserves design rules, connectivity, and transistor and contact sizes. This means that material ahead of the plow gets compacted down to the minimum spacing permitted by the design rules, and material that crossed the plow's original position gets stretched behind the plow. You can compact a cell by placing a large plow off to one side of the cell and plowing across the whole cell. You can open up space in the middle of a cell by dragging a small plow across the area where you want more space. To try out plowing, edit the cell {\bfseries tut3d}, place the box over the rectangle that's labelled ``Plow here'', and try plowing in various directions. Also, try plowing only certain layers. For example, with the box over the ``Plow here'' label, try \starti \ii {\bfseries :plow right metal2} \endi Nothing happens. This is because there are no metal2 {\itshape edges} in the path of the plow. If instead you had typed \starti \ii {\bfseries :plow right metal1} \endi only the metal would have been plowed to the right. In addition to plowing with the box, you can plow the selection. The command to do this has the following syntax: \starti \ii {\bfseries :plow selection }[{\itshape direction }[{\itshape distance}]] \endi This is very similar to the {\bfseries :stretch} command: it picks up the selection and the box and moves both so that the lower-left corner of the box is at the cursor location. Unlike the {\bfseries :stretch} command, though, {\bfseries :plow selection} insures that design rule correctness and connectivity are preserved. Load the cell {\bfseries tut3e} and use {\bfseries a} to select the area underneath the label that says ``select me''. Then point with the cursor to the point labelled ``point here'' and type {\bfseries :plow selection}. Practice selecting things and plowing them. Like the {\bfseries :stretch} command, there is also a longer form of {\bfseries :plow selection}. For example, {\bfseries :plow selection down 5} will plow the selection and the box down 10 units. Selecting a cell and plowing it is a good way to move the cell. Load {\bfseries tut3f} and select the cell {\bfseries tut3e}. Point to the label ``point here'' and plow the selection with {\bfseries :plow selection}. Notice that all connections to the cell have remained attached. The cell you select must be in the edit cell, however. The plowing operation is implemented in a way that tries to keep your design as compact as possible. To do this, it inserts jogs in wires around the plow. In many cases, though, the additional jogs are more trouble than they're worth. To reduce the number of jogs inserted by plowing, type the command \starti \ii {\bfseries :plow nojogs} \endi From now on, Magic will insert as few jogs as possible when plowing, even if this means moving more material. You can re-enable jog insertion with the command \starti \ii {\bfseries :plow jogs} \endi Load the cell {\bfseries tut3d} again and try plowing it both with and without jog insertion. There is another way to reduce the number of jogs introduced by plowing. Instead of avoiding jogs in the first place, plowing can introduce them freely but clean them up as much as possible afterward. This results in more dense layouts, but possibly more jogs than if you had enabled {\bfseries :plow nojogs}. To take advantage of this second method for jog reduction, re-enable jog insertion ({\bfseries :plow jogs}) and enable jog cleanup with the command \starti \ii {\bfseries :plow straighten} \endi From now on, Magic will attempt to straighten out jogs after each plow operation. To disable straightening, use the command \starti \ii {\bfseries :plow nostraighten} \endi It might seem pointless to disable jog introduction with {\bfseries :plow nojogs} at the same time straightening is enabled with {\bfseries :plow straighten}. While it is true that {\bfseries :plow nojogs} won't introduce any new jogs for {\bfseries :plow straighten} to clean up, plowing will straighten out any existing jogs after each operation. In fact, there is a separate command that is sometimes useful for cleaning up layouts with many jogs, namely the command \starti \ii {\bfseries :straighten} {\itshape direction} \endi where {\itshape direction} is a Manhattan direction, e.g., {\bfseries up}, {\bfseries down}, {\bfseries right}, or {\bfseries left}. This command will start from one side of the box and pull jogs toward that side to straighten them. Load the cell {\bfseries tut3g}, place the box over the label ``put box here'', and type {\bfseries :straighten left}. Undo the last command and type {\bfseries :straighten right} instead. Play around with the {\bfseries :straighten} command. There is one more feature of plowing that is sometimes useful. If you are working on a large cell and want to make sure that plowing never affects any geometry outside of a certain area, you can place a {\itshape boundary} around the area you want to affect with the command \starti \ii {\bfseries :plow boundary} \endi The box is used to specify the area you want to affect. After this command, subsequent plows will only affect the area inside this boundary. Load the cell {\bfseries tut3h} place the box over the label ``put boundary here'', and type {\bfseries :plow boundary}. Now move the box away. You will see the boundary highlighted with dotted lines. Now place the box over the area labelled ``put plow here'' and plow up. This plow would cause geometry outside of the boundary to be affected, so Magic reduces the plow distance enough to prevent this and warns you of this fact. Now undo the last plow and remove the boundary with \starti \ii {\bfseries :plow noboundary} \endi Put the box over the ``put plow here'' label and plow up again. This time there was no boundary to stop the plow, so everything was moved as far as the height of the box. Experiment with placing the boundary around an area of this cell and plowing. \end{document} magic-8.0.210/doc/latexfiles/Makefile0000644000175000001440000000313110751423606016021 0ustar timusersMAGICDIR = ../.. include $(MAGICDIR)/defs.mak PS_SRCDIR=../psfiles PS_INSTDIR=$(LIBDIR)/magic/doc .SUFFIXES: .dvi .tex .ps GENDVI=tut1.dvi tut2.dvi tut3.dvi tut4.dvi tut5.dvi tut6.dvi \ tut7.dvi tut8.dvi tut9.dvi tut10.dvi tut11.dvi \ maint1.dvi maint2.dvi maint3.dvi maint4.dvi \ introduction.dvi copyright.dvi addendum6_5.dvi \ tutscm1.dvi tutscm2.dvi tutscm3.dvi tutscm4.dvi \ tuttcl1.dvi tuttcl2.dvi tuttcl3.dvi tuttcl4.dvi tuttcl5.dvi \ tutwrl1.dvi GENPS=tut1.ps tut2.ps tut3.ps tut4.ps tut5.ps tut6.ps \ tut7.ps tut8.ps tut9.ps tut10.ps tut11.ps \ maint1.ps maint2.ps maint3.ps maint4.ps \ introduction.ps copyright.ps addendum6_5.ps \ tutscm1.ps tutscm2.ps tutscm3.ps tutscm4.ps \ tuttcl1.ps tuttcl2.ps tuttcl3.ps tuttcl4.ps tuttcl5.ps \ tutwrl1.ps SRC_GENPS= $(GENPS:%=${PS_SRCDIR}/%) INST_GENPS= $(GENPS:%=$(DESTDIR)${PS_INSTDIR}/%) all: $(SRC_GENPS) @${RM} $(GENDVI) *.log *.aux install: $(DESTDIR)${PS_INSTDIR} ${INST_GENPS} $(DESTDIR)${PS_INSTDIR}: make-doc-dir make-doc-dir: ${SCRIPTS}/mkdirs $(DESTDIR)${PS_INSTDIR} $(DESTDIR)${PS_INSTDIR}/%: ${PS_SRCDIR}/% $(DESTDIR)${PS_INSTDIR} ${CP} ${PS_SRCDIR}/$* $(DESTDIR)${PS_INSTDIR}/$* .tex.ps: @echo "Converting $*.tex -> $*.dvi" @latex $*.tex < /dev/null > /dev/null @if grep 'LaTeX Warn' $*.log; \ then \ echo "Detected warnings, doing second pass for $*...";\ latex $*.tex < /dev/null > /dev/null; \ (grep 'LaTeX Warn' $*.log || (echo > /dev/null)); \ echo; \ fi @echo "Converting $*.dvi -> $(PS_SRCDIR)/$*.ps" @dvips -t letter $*.dvi -o $(PS_SRCDIR)/$*.ps > /dev/null clean: ${RM} $(GENDVI) $(SRC_GENPS) *.log *.aux magic-8.0.210/doc/latexfiles/tut9.tex0000644000175000001440000004115510751423606016020 0ustar timusers%---------------------------------------------------------------------------- % Magic tutorial number 9 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Magic Tutorial \#9: Format Conversion for CIF and Calma} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape John Ousterhout} \\ \vspace*{0.5in} Computer Science Division \\ Electrical Engineering and Computer Sciences \\ University of California \\ Berkeley, CA 94720 \\ \vspace*{0.25in} {\itshape (Updated by others, too.)} \\ \vspace*{0.25in} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Tutorials to read first:} \starti \> Magic Tutorial \#1: Getting Started \\ \> Magic Tutorial \#2: Basic Painting and Selection \\ \> Magic Tutorial \#4: Cell Hierarchies \endi {\noindent\bfseries\large Commands introduced in this tutorial:} \starti \> :calma, :cif \endi {\noindent\bfseries\large Macros introduced in this tutorial:} \starti \> {\itshape (None)} \endi \vspace*{0.75in} \section{Basics} CIF (Caltech Intermediate Form) and Calma Stream Format are standard layout description languages used to transfer mask-level layouts between organizations and design tools. This tutorial describes how Magic can be used to read and write files in CIF and Stream formats. The version of CIF that Magic supports is CIF 2.0; it is the most popular layout language in the university design community. The Calma format that Magic supports is GDS II Stream format, version 3.0, corresponding to GDS II Release 5.1. This is probably the most popular layout description language for the industrial design community. To write out a CIF file, place the cursor over a layout window and type the command \starti \ii {\bfseries :cif} \endi This will generate a CIF file called {\itshape name}{\bfseries .cif}, where {\itshape name} is the name of the root cell in the window. The CIF file will contain a description of the entire cell hierarchy in that window. If you wish to use a name different from the root cell, type the command \starti \ii {\bfseries :cif write} {\itshape file} \endi This will store the CIF in {\itshape file}{\bfseries .cif}. Start Magic up to edit {\bfseries tut9a} and generate CIF for that cell. The CIF file will be in ASCII format, so you can use Unix commands like {\bfseries more} and {\bfseries vi} to see what it contains. To read a CIF file into Magic, place the cursor over a layout window and type the command \starti \ii {\bfseries :cif read} {\itshape file} \endi This will read the file {\itshape file}{\bfseries .cif} (which must be in CIF format), generate Magic cells for the hierarchy described in the file, make the entire hierarchy a subcell of the edit cell, and run the design-rule checker to verify everything read from the file. Information in the top-level cell (usually just a call on the ``main'' cell of the layout) will be placed into the edit cell. Start Magic up afresh and read in {\bfseries tut9a.cif}, which you created above. It will be easier if you always read CIF when Magic has just been started up: if some of the cells already exist, the CIF reader will not overwrite them, but will instead use numbers for cell names. To read and write Stream-format files, use the commands {\bfseries :calma read} and {\bfseries :calma}, respectively. These commands have the same effect as the CIF commands, except that they operate on files with {\bfseries .strm} extensions. Stream is a binary format, so you can't examine {\bfseries .strm} files with a text editor. Stream files do not identify a top-level cell, so you won't see anything on the screen after you've used the {\bfseries :calma read} command. You'll have to use the {\bfseries :load} command to look at the cells you read. However, if Magic was used to write the Calma file being read, the library name reported by the {\bfseries :calma read} command is the same as the name of the root cell for that library. Also, Calma format places some limitations on the names of cells: they can only contain alphanumeric characters, ``\$'', and ``{\_}'', and can be at most 32 characters long. If the name of a cell does not meet these limitations, {\bfseries :calma write} converts it to a unique name of the form \rule{0.25in}{0.5pt}{\itshape n}, where {\itshape n} is a small integer. To avoid any possible conflicts, you should avoid using names like these for your own cells. You shouldn't need to know much more than what's above in order to read and write CIF and Stream. The sections below describe the different styles of CIF/Calma that Magic can generate and the limitations of the CIF/Calma facilities (you may have noticed that when you wrote and read CIF above you didn't quite get back what you started with; Section 3 describes the differences that can occur). Although the discussion mentions only CIF, the same features and problems apply to Calma. \section{Styles} Magic usually knows several different ways to generate CIF/Calma from a given layout. Each of these ways is called a {\itshape style}. Different styles can be used to handle different fabrication facilities, which may differ in the names they use for layers or in the exact mask set required for fabrication. Different styles can be also used to write out CIF/Calma with slightly different feature sizes or design rules. CIF/Calma styles are described in the technology file that Magic reads when it starts up; the exact number and nature of the styles is determined by whoever wrote your technology file. There are separate styles for reading and writing CIF/Calma; at any given time, there is one current input style and one current output style. The standard SCMOS technology file provides an example of how different styles can be used. Start up Magic with the SCMOS technology ({\bfseries magic -Tscmos}). Then type the commands \starti \ii {\bfseries :cif ostyle} \\ \ii {\bfseries :cif istyle} \endi The first command will print out a list of all the styles in which Magic can write CIF/Calma (in this technology) and the second command prints out the styles in which Magic can read CIF/Calma. You use the {\bfseries :cif} command to change the current styles, but the styles are used for both CIF and Calma format conversion. The SCMOS technology file provides several output styles. The initial (default) style for writing CIF is {\bfseries lambda=1.0(gen)}. This style generates mask layers for the MOSIS scalable CMOS process, where each Magic unit corresponds to 1 micron and both well polarities are generated. See the technology manual for more information on the various styles that are available. You can change the output style with the command \starti \ii {\bfseries :cif ostyle} {\itshape newStyle} \endi where {\itshape newStyle} is the new style you'd like to use for output. After this command, any future CIF or Calma files will be generated with the new style. The {\bfseries :cif istyle} command can be used in the same way to see the available styles for reading CIF and to change the current style. Each style has a specific scalefactor; you can't use a particular style with a different scalefactor. To change the scalefactor, you'll have to edit the appropriate style in the {\bfseries cifinput} or {\bfseries cifoutput} section of the technology file. This process is described in ``Magic Maintainer's Manual \#2: The Technology File.'' \section{Rounding} The units used for coordinates in Magic are generally different from those in CIF files. In Magic, most technology files use lambda-based units, where one unit is typically half the minimum feature size. In CIF files, the units are centimicrons (hundredths of a micron). When reading CIF and Calma files, an integer scalefactor is used to convert from centimicrons to Magic units. If the CIF file contains coordinates that don't scale exactly to integer Magic units, Magic rounds the coordinates up or down to the closest integer Magic units. A CIF coordinate exactly halfway between two Magic units is rounded down. The final authority on rounding is the procedure CIFScaleCoord in the file cif/CIFreadutils.c When rounding occurs, the resulting Magic file will not match the CIF file exactly. Technology files usually specify geometrical operations such as bloating, shrinking, and-ing, and or-ing to be performed on CIF geometries when they are read into Magic. These geometrical operations are all performed in the CIF coordinate system (centimicrons) so there is no rounding or loss of accuracy in the operations. Rounding occurs only AFTER the geometrical operations, at the last possible instant before entering paint into the Magic database. \section{Non-Manhattan Geometries} Magic only supports Manhattan features. When CIF or Calma files contain non-Manhattan features, they are approximated with Manhattan ones. The approximations occur for wires (if the centerline contains non-Manhattan segments) and polygons (if the outline contains non-Manhattan segments). In these cases, the non-Manhattan segments are replaced with one or more horizontal and vertical segments before the figure is processed. Conversion is done by inserting a one-unit stairstep on a 45-degree angle until a point is reached where a horizontal or vertical line can reach the segment's endpoint. Some examples are illustrated in the figure below: in each case, the figure on the left is the one specified in the CIF file, and the figure on the right is what results in Magic. \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/tut9.1.ps, width=0.55\columnwidth} \end{center} \end{figure} The shape of the Magic stairstep depends on the order in which vertices appear in the CIF or Calma file. The stairstep is made by first incrementing or decrementing the x-coordinate, then incrementing or decrementing the y-coordinate, then x, then y, and so on. For example, in the figure above, the polygon was specified in counter-clockwise order; if it had been specified in clockwise order the result would have been slightly different. An additional approximation occurs for wires. The CIF wire figure assumes that round caps will be generated at each end of the wire. In Magic, square caps are generated instead. The top example of the figure above illustrates this approximation. \section{Other Problems with Reading and Writing CIF} You may have noticed that when you wrote out CIF for {\bfseries tut9a} and read it back in again, you didn't get back quite what you started with. Although the differences shouldn't cause any serious problems, this section describes what they are so you'll know what to expect. There are three areas where there may be discrepancies: labels, arrays, and contacts. These are illustrated in {\bfseries tut9b}. Load this cell, then generate CIF, then read the CIF back in again. When the CIF is read in, you'll get a couple of warning messages because Magic won't allow the CIF to overwrite existing cells: it uses new numbered cells instead (this is why you should normally read CIF with a ``clean slate''; in this case it's convenient to have both the original and reconstructed infromation present at the same time; just ignore the warnings). The information from the CIF cell appears as a subcell named {\bfseries 1} right on top of the old contents of {\bfseries tut9b}; select {\bfseries 1}, move it below {\bfseries tut9b}, and expand it so you can compare its contents to {\bfseries tut9b}. The first problem area is that CIF normally allows only point labels. By default, where you have line or box labels in Magic, CIF labels are generated at the center of the Magic labels. The label {\bfseries in} in {\bfseries tut9y} is an example of a line label that gets smashed in the CIF processing. The command \starti \ii {\bfseries :cif arealabels yes} \endi sets a switch telling Magic to use an extension to cif to output area-labels. This is not the default since many programs that take CIF as input do not understand this extension. If you are reading a CIF file created by a tool other than Magic, there is an additional problems with labels. The CIF label construct (``{\bfseries 94} {\itshape label x y layer}'') has an optional {\itshape layer} field that indicates the layer to which a label is attached. If reading a CIF file generated by Magic, this field is always present and so a label's layer is unambiguous. However, if the field is absent, Magic must decide which layer to use. It does this by looking to see what Magic layers lie beneath the label after the CIF has been read in. When there are several layers, it chooses the one appearing LATEST in the {\bfseries types} section of the technology file. Usually, it's possible to ensure that the right layer is used by placing signal layers (such as metal, diffusion, and poly) later in the types section than layers such as pwell or nplus. However, sometimes Magic will still pick the wrong layer, and it will be up to you to move the label to the right layer yourself. The second problem is with arrays. CIF has no standard array construct, so when Magic outputs arrays it does it as a collection of cell instances. When the CIF file is read back in, each array element comes back as a separate subcell. The array of {\bfseries tut9y} cells is an example of this. Most designs only have a few arrays that are large enough to matter; where this is the case, you should go back after reading the CIF and replace the multiple instances with a single array. Calma format does have an array construct, so it doesn't have this problem. The third discrepancy is that where there are large contact areas, when CIF is read and written the area of the contact may be reduced slightly. This happened to the large poly contact in {\bfseries tut9b}. The shrink doesn't reduce the effective area of the contact; it just reduces the area drawn in Magic. To see what's happening here, place the box around {\bfseries tut9b} and {\bfseries 1}, expand everything, then type \starti \ii {\bfseries :cif see CCP} \endi This causes feedback to be displayed showing CIF layer ``CCP'' (contact cut to poly). You may have to zoom in a bit to distinguish the individual via holes. Magic generates lots of small contact vias over the area of the contact, and if contacts aren't exact multiples of the hole size and spacing then extra space is left around the edges. When the CIF is read back in, this extra space isn't turned back into contact. The circuit that is read in is functionally identical to the original circuit, even though the Magic contact appears slightly smaller. There is an additional problem with generating CIF having to do with the cell hierarchy. When Magic generates CIF, it performs geometric operations such as ``grow'' and ``shrink''on the mask layers. Some of these operations are not guaranteed to work perfectly on hierarchical designs. Magic detects when there are problems and creates feedback areas to mark the trouble spots. When you write CIF, Magic will warn you that there were troubles. These should almost never happen if you generate CIF from designs that don't have any design-rule errors. If they do occur, you can get around them by writing cif with the following command \starti \ii {\bfseries :cif flat} {\itshape fileName} \endi This command creates an internal version of the design with hierarchy removed, before outputing CIF as in {\bfseries cif write}. An alternative approach that does not require flattening is to modify the technology file in use. Read ``Magic Maintainers Manual \#2: The Technology File'', if you want to try this approach. \end{document} magic-8.0.210/doc/latexfiles/tut11.tex0000644000175000001440000004410710751423606016071 0ustar timusers%---------------------------------------------------------------------------- % Magic tutorial number 11 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Magic Tutorial \#11: Using IRSIM and RSIM with Magic} \def\_{\rule{0.6em}{0.5pt}} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape Michael Chow} \\ {\itshape Mark Horowitz} \\ \vspace*{0.5in} Computer Systems Laboratory \\ Center for Integrated Systems \\ Stanford University \\ Stanford, CA 94305 \\ \vspace*{0.25in} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Tutorials to read first:} \starti \> Magic Tutorial \#1: Getting Started \\ \> Magic Tutorial \#2: Basic Painting and Selection \\ \> Magic Tutorial \#4: Cell Hierarchies \\ \> Magic Tutorial \#8: Circuit Extraction \endi {\noindent\bfseries\large Commands introduced in this tutorial:} \starti \> :getnode, :rsim, :simcmd, :startrsim \endi {\noindent\bfseries\large Macros introduced in this tutorial:} \starti \> {\itshape (None)} \endi \vspace*{0.25in} \section{Introduction} This tutorial explains how to use Magic's interface to the switch-level circuit simulators, RSIM and IRSIM. The interface is the same for both these simulators and, except where noted, RSIM refers to IRSIM as well. This interface eliminates the tedium of mapping node names to objects in the layout and typing node names as RSIM input. It allows the user to select nodes using the mouse and apply RSIM commands to them or to display the node values determined by RSIM in the layout itself. You should already be familiar with using both RSIM and Magic's circuit extractor. Section 2 describes how to prepare the files necessary to simulate a circuit. Section 3 describes how to run RSIM interactively under Magic. Section 4 explains how to determine the node names that RSIM uses. Lastly, section 5 explains how to use the RSIM tool in Magic to simulate a circuit. \section{Preparations for Simulation} Magic uses the RSIM input file when it simulates the circuit. Before proceeding any further, make sure you have the correct versions of the programs {\bfseries ext2sim} and {\bfseries rsim} installed on your system. Important changes have been made to these programs to support simulation within Magic. To try out this tool on an example, copy all the {\bfseries tut11{\itshape x}} cells to your current directory with the following command: \starti \ii {\bfseries cp \~{}cad/lib/magic/tutorial/tut11* .} \endi The {\bfseries tut11a} cell is a simple 4-bit counter using the Magic scmos technology file. Start Magic on the cell {\bfseries tut11a}, and extract the entire cell using the command: \starti \ii {\bfseries :extract all} \endi When this command completes, several {\bfseries .ext} files will be created in your current directory by the extractor. The next step is to flatten the hierarchy into a single representation. Return to the Unix c-shell by quitting Magic. The program {\bfseries ext2sim} is used to flatten the hierarchy. Run this program from the C-shell by typing: \starti \ii {\bfseries ext2sim -L -R -c 20 tut11a} \endi This program will create the file {\bfseries tut11a.sim} in your current directory. If you are running IRSIM, the {\bfseries tut11a.sim} can be used directly as input to the simulator and you should skip the next step. Instead, if you will be using RSIM, the last step is to create the binary representation of the flattened hierarchy by using the program {\bfseries presim}. To do this, type: \starti \ii {\bfseries presim tut11a.sim tut11a.rsm \~{}cad/lib/scmos100.prm -nostack -nodrops} \endi The third file is the parameter file used by presim for this circuit. The convention at Stanford is to use the suffix {\itshape .rsm} when naming the RSIM input file. The file {\bfseries tut11a.rsm} can also be used as input for running RSIM alone. \section{Using RSIM} Re-run Magic again to edit the cell {\bfseries tut11a}. We'll first learn how to run RSIM in interactive mode under Magic. To simulate the circuit of tut11a, using IRSIM type the command: \starti \ii {\bfseries :rsim scmos100.prm tut11a.sim} \endi To simulate the circuit of tut11a, using RSIM type the command: \starti \ii {\bfseries :rsim tut11a.rsm} \endi You should see the RSIM header displayed, followed by the standard RSIM prompt ({\bfseries rsim$>$} or {\bfseries irsim$>$}, depending on the simulator) in place of the usual Magic prompt; this means keyboard input is now directed to RSIM. This mode is very similar to running RSIM alone; one difference is that the user can escape RSIM and then return to Magic. Also, the mouse has no effect when RSIM is run interactively under Magic. Only one instance of RSIM may be running at any time under Magic. The simulation running need not correspond to the Magic layout; however, as we shall see later, they must correspond for the RSIM tool to work. All commands typed to the RSIM prompt should be RSIM commands. We'll first run RSIM, then escape to Magic, and then return back to RSIM. Type the RSIM command \starti \ii {\bfseries @ tut11a.cmd} \endi to initialize the simulation. (Note there is a `` '' after the @.) Now type {\bfseries c} to clock the circuit. You should see some information about some nodes displayed, followed by the time. Set two of the nodes to a logic ``1'' by typing {\bfseries h RESET{\_}B hold}. Step the clock again by typing {\bfseries c}, and RSIM should show that these two nodes now have the value ``1''. You can return to Magic without quitting RSIM and then later return to RSIM in the same state in which it was left. Escape to Magic by typing: \starti \ii {\bfseries . } \endi (a single period) to the RSIM prompt. Next, type a few Magic commands to show you're really back in Magic (signified by the Magic prompt). You can return to RSIM by typing the Magic command {\bfseries rsim} without any arguments. Type: \starti \ii {\bfseries :rsim} \endi The RSIM prompt will be displayed again, and you are now back in RSIM in the state you left it in. Experiment with RSIM by typing some commands. To quit RSIM and return to Magic, type: \starti \ii {\bfseries q} \endi in response to the RSIM prompt. You'll know you're back in Magic when the Magic prompt is redisplayed. If you should interrupt RSIM (typing a control-C), you'll probably kill it and then have to restart it. RSIM running standalone will also be killed if you interrupt it. If you interrupt IRSIM (typing a control-C), the simulator will abort whatever it's doing (a long simulation run, for example) and return to the command interpreter by prompting again with {\bfseries irsim$>$}. \section{Node Names} It's easy to determine node names under Magic. First, locate the red square region in the middle right side of the circuit. Move the cursor over this region and select it by typing {\bfseries s}. To find out the name for this node, type: \starti \ii {\bfseries :getnode} \endi Magic should print that the node name is {\itshape RESET{\_}B}. The command {\bfseries getnode} prints the names of all nodes in the current selection. Move the cursor over the square blue region in the upper right corner and add this node to the current selection by typing {\bfseries S}. Type {\bfseries :getnode} again, and Magic should print the names of two nodes; the blue node is named {\itshape hold}. You can also print aliases for the selected nodes. Turn on name-aliasing by typing: \starti \ii {\bfseries :getnode alias on} \endi Select the red node again, and type {\bfseries :getnode}. Several names will be printed; the last name printed is the one RSIM uses, so you should use this name for RSIM. Note that {\bfseries getnode} is not guaranteed to print all aliases for a node. Only those alises generated when the RSIM node name is computed are printed. However, most of the alaiases will usually be printed. Printing aliases is also useful to monitor the name search, since {\bfseries getnode} can take several seconds on large nodes. Turn off aliasing by typing: \starti \ii {\bfseries :getnode alias off} \endi {\bfseries getnode} works by extracting a single node. Consequently, it can take a long time to compute the name for large nodes, such as {\itshape Vdd} or {\itshape GND}. Select the horizontal blue strip on top of the circuit and run {\bfseries :getnode} on this. You'll find that this will take about six seconds for {\bfseries getnode} to figure out that this is {\itshape Vdd}. You can interrupt {\bfseries getnode} by typing {\bfseries \^{}C} (control-C), and {\bfseries getnode} will return the ``best'' name found so far. There is no way to tell if this is an alias or the name RSIM expects unless {\bfseries getnode} is allowed to complete. To prevent these long name searches, you can tell {\bfseries getnode} to quit its search when certain names are encountered. Type: \starti \ii {\bfseries :getnode abort Vdd} \endi Select the blue strip on top of the circuit and type {\bfseries :getnode}. You'll notice that the name was found very quickly this time, and {\bfseries getnode} tells you it aborted the search of {\itshape Vdd}. The name returned may be an alias instead of the the one RSIM expects. In this example, the abort option to {\bfseries getnode} will abort the name search on any name found where the last component of the node name is {\itshape Vdd}. That is, {\bfseries getnode} will stop if a name such as ``miasma/crock/{\itshape Vdd}'' or ``hooha/{\itshape Vdd}'' is found. You can abort the search on more than one name; now type {\bfseries :getnode abort GND}. Select the bottom horizontal blue strip in the layout, and type {\bfseries :getnode}. The search will end almost immediately, since this node is {\itshape GND}. {\bfseries getnode} will now abort any node name search when either {\itshape Vdd} or {\itshape GND} is found. The search can be aborted on any name; just supply the name as an argument to {\bfseries getnode abort}. Remember that only the last part of the name counts when aborting the name search. To cancel all name aborts and resume normal name searches, type: \starti \ii {\bfseries :getnode abort} \endi {\bfseries getnode} will no longer abort the search on any names, and it will churn away unless interrupted by the user. \section{RSIM Tool} You can also use the mouse to help you run RSIM under Magic. Instead of typing node names, you can just select nodes with the mouse, tell RSIM what to do with these nodes, and let Magic do the rest. Change tools by typing: \starti \ii {\bfseries :tool rsim} \endi or hit the space bar until the cursor changes to a pointing hand. The RSIM tool is active when the cursor is this hand. The left and right mouse buttons have the same have the same function as the box tool. You use these buttons along with the select command to select the nodes. The middle button is different from the box tool. Clicking the middle button will cause all nodes in the selection to have their logical values displayed in the layout and printed in the text window. We need to have RSIM running in order to use this tool. Start RSIM by typing: \starti \ii {\bfseries :startrsim tut11a.rsm} \endi The {\bfseries .rsm} file you simulate must correspond to the root cell of the layout. If not, Magic will generate node names that RSIM will not understand and things won't work properly. If any paint is changed in the circuit, the circuit must be re-extracted and a new {\bfseries .rsm} file must be created to reflect the changes in the circuit. Magic will print the RSIM header, but you return to Magic instead of remaining in RSIM. This is an alternate way of starting up RSIM, and it is equivalent to the command {\bfseries rsim tut11a.rsm} and typing a period ({\bfseries .}) to the RSIM prompt, escaping to Magic. We need to initialize RSIM, so get to RSIM by typing {\bfseries :rsim} and you'll see the RSIM prompt again. As before, type {\bfseries @ tut11a.cmd} to the RSIM prompt to initialize everything. Type a period ({\bfseries .}) to return to Magic. We are now ready to use the RSIM tool. As mentioned earlier, {\bfseries tut11a} is a 4-bit counter. We'll reset the counter and then step it using the RSIM tool. Locate the square blue area on the top right corner of the circuit. Place the cursor over this region and select it. Now click the middle button, and the RSIM value for this node will be printed in both the text window and in the layout. Magic/RSIM will report that the node is named {\itshape hold} and that its current value is {\itshape X}. You may not be able to see the node value in the layout if you are zoomed out too far. Zoom in closer about this node if necessary. Try selecting other nodes, singly or in groups and click the middle button to display their values. This is an easy way to probe nodes when debugging a circuit. Select {\itshape hold} again (the blue square). This node must be a ``1'' before resetting the circuit. Make sure this is the only node in the current selection. Type: \starti \ii {\bfseries :simcmd h} \endi to set it to a ``1''. Step the clock by typing: \starti \ii {\bfseries :simcmd c} \endi Click the middle button and you will see that the node has been set to a ``1.'' The Magic command {\bfseries simcmd} will take the selected nodes and use them as RSIM input. These uses of {\bfseries simcmd} are like typing the RSIM commands {\itshape h hold} followed by {\itshape c}. The arguments given to {\bfseries simcmd} are normal RSIM commands, and {\bfseries simcmd} will apply the specified RSIM command to each node in the current selection. Try RSIM commands on this node (such as {\itshape ?} or {\itshape d}) by using the command as an argument to {\bfseries simcmd}. You can enter RSIM interactively at any time by simply typing {\bfseries :rsim}. To continue using the RSIM tool, escape to Magic by typing a period ({\bfseries .}) to the RSIM prompt. The node {\itshape RESET{\_}B} must be set to a ``0''. This node is the red square area at the middle right of the circuit. Place the cursor over this node and select it. Type the Magic commands {\bfseries :simcmd l} followed by {\bfseries :simcmd c} to set the selected node to a ``0''. Click the middle mouse button to check that this node is now ``0''. Step the clock once more to ensure the counter is reset. Do this using the {\bfseries :simcmd c} command. The outputs of this counter are the four vertical purple strips at the bottom of the circuit. Zoom in if necessary, select each of these nodes, and click the middle button to check that all are ``0''. Each of these four nodes is labeled {\itshape bit{\_}x}. If they are all not ``0'', check the circuit to make sure {\itshape hold=1} and {\itshape RESET{\_}B=0}. Assuming these nodes are at their correct value, you can now simulate the counter. Set {\itshape RESET{\_}B} to a ``1'' by selecting it (the red square) and then typing {\bfseries :simcmd h}. Step the clock by typing {\bfseries :simcmd c}. Using the same procedure, set the node {\itshape hold} (the blue square) to a ``0''. We'll watch the output bits of this counter as it runs. Place the box around all four outputs (purple strips at the bottom) and zoom in so their labels are visible. Select one of the outputs by placing the cursor over it and typing {\bfseries s}. Add the other three outputs to the selection by placing the cursor over each and typing {\bfseries S}. These four nodes should be the only ones in the selection. Click the middle mouse button to display the node values. Step the clock by typing {\bfseries :simcmd c}. Click the middle button again to check the nodes. Repeat stepping the clock and displaying the outputs several times, and you'll see the outputs sequence as a counter. If you also follow the text on the screen, you'll also see that the outputs are also being watched. You may have noticed that the results are printed very quickly if the middle button is clicked a second time without changing the selection. This is because the node names do not have to be recomputed if the selection remains unchanged. Thus, you can increase the performance of this tool by minimizing selection changes. This can be accomplished by adding other nodes to the current selection that you are intending to check. To erase all the RSIM value labels from the layout, clear the selection by typing: \starti \ii {\bfseries :select clear} \endi and then click the middle mouse button. The RSIM labels do not affect the cell modified flag, nor will they be written in the {\bfseries .mag} file. When you're finished using RSIM, resume RSIM by typing {\bfseries :rsim} and then quit it by typing a {\bfseries q} to the RSIM prompt. Quitting Magic before quitting RSIM will also quit RSIM. We've used a few macros to lessen the typing necessary for the RSIM tool. The ones commonly used are: \starti \ii {\bfseries :macro h ``simcmd h''} \\ \ii {\bfseries :macro l ``simcmd l''} \\ \ii {\bfseries :macro k ``simcmd c''} \endi \end{document} magic-8.0.210/doc/latexfiles/tut7.tex0000644000175000001440000012140510751423606016013 0ustar timusers%---------------------------------------------------------------------------- % Magic tutorial number 7 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Magic Tutorial \#7: Netlists and Routing} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape John Ousterhout} \\ \vspace*{0.5in} Computer Science Division \\ Electrical Engineering and Computer Sciences \\ University of California \\ Berkeley, CA 94720 \\ \vspace*{0.25in} {\itshape (Updated by others, too.)} \\ \vspace*{0.25in} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Tutorials to read first:} \starti \> Magic Tutorial \#1: Getting Started \\ \> Magic Tutorial \#2: Basic Painting and Selection \\ \> Magic Tutorial \#3: Advanced Painting (Wiring and Plowing) \\ \> Magic Tutorial \#4: Cell Hierarchies \\ \> Magic Tutorial \#5: Multiple Windows \\ \endi {\noindent\bfseries\large Netlist Commands introduced in this tutorial:} \starti \> :extract, :flush, :ripup, :savenetlist, :trace, :writeall \endi {\noindent\bfseries\large Layout Commands introduced in this tutorial:} \starti \> :channel, :route \endi {\noindent\bfseries\large Macros introduced in this tutorial:} \starti \> {\itshape (none)} \endi \vspace*{0.75in} \section{Introduction} This tutorial describes how to use Magic's automatic routing tools to make interconnections between subcells in a design. In addition to the standard Magic router, which is invoked by the {\bfseries route} command and covered in this tutorial, two other routing tools are available. A gate-array router {\itshape Garouter} permits user specified channel definitions, terminals in the interior of cells, and route-throughs across cells. To learn about the gate-array router read this first then ``Magic Tutorial \#12: Routing Gate Arrays''. Finally Magic provides an interactive maze-router that takes graphic hints, the {\itshape Irouter}, that permits the user to control the overall path of routes while leaving the tedious details to Magic. The {\itshape Irouter} is documented in ``Magic Tutorial \#10: The Interactive Router''. The standard Magic router provides an {\itshape obstacle-avoidance} capability: if there is mask material in the routing areas, the router can work under, over, or around that material to complete the connections. This means that you can pre-route key signals by hand and have Magic route the less important signals automatically. In addition, you can route power and ground by hand (right now we don't have any power-ground routing tools, so you {\itshape have} to route them by hand). The router {\itshape only} makes connections between subcells; to make point-to-point connections between pieces of layout within a single cell you should use the wiring command described in ``Magic Tutorial \#3: Advanced Painting (Wiring and Plowing) '' or the maze router described in ``Magic Tutorial \#10: The Interactive Router''. If you only need to make a few connections you are probably better off doing them manually. The first step in routing is to tell Magic what should be connected to what. This information is contained in a file called a {\itshape netlist}. Sections 2, 3, 4, and 5 describe how to create and modify netlists using Magic's interactive netlist editing tools. Once you've created a netlist, the next step is to invoke the router. Section 6 shows how to do this, and gives a brief summary of what goes on inside the routing tools. Unless your design is very simple and has lots of free space, the routing probably won't succeed the first time. Section 7 describes the feedback provided by the routing tools. Sections 8 and 9 discuss how you can modify your design in light of this feedback to improve its routability. You'll probably need to iterate a few times until the routing is successful. \section{Terminals and Netlists} A netlist is a file that describes a set of desired connections. It contains one or more {\itshape nets}. Each net names a set of {\itshape terminals} that should all be wired together. A terminal is simply a label attached to a piece of mask material within a subcell; it is distinguishable from ordinary labels within a subcell by its presence within a netlist file and by certain characteristics common to terminals, as described below. The first step in building a netlist is to label the terminals in your design. Figure 1 shows an example. Each label should be a line or rectangle running along the edge of the cell (point terminals are not allowed). The router will make a connection to the cell somewhere along a terminal's length. If the label isn't at the edge of the cell, Magic will route recklessly across the cell to reach the terminal, taking the shortest path between the terminal and a routing channel. It's almost always a good idea to arrange for terminal labels to be at cell edges. The label must be at least as wide as the minimum width of the routing material; the wider you make the label, the more flexibility you give the router to choose a good point to connect to the terminal. \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/tut7.1.ps, width=0.5\columnwidth} \caption{An example of terminal labels. Each terminal should be labeled with a line or rectangle along the edge of the cell.} \end{center} \end{figure} Terminal labels must be attached to mask material that connects directly to one of Magic's two routing layers (Routing layers are defined in Magic's technology file). For example, in the SCMOS process where the routing layers are metal1 and metal2, diffusion may not be used as a terminal since neither of the routing layers will connect directly to it. On the other hand, a terminal may be attached to diffusion-metal1 contact, since the metal1 routing layer will connect properly to it. Terminals can have arbitrary names, except that they should not contain slashes (``/'') or the substring ``feedthrough'', and should not end in ``@'', ``\$'', or ``\^{}''. See Tutorial \#2 for a complete description of labeling conventions. For an example of good and bad terminals, edit the cell {\bfseries tut7a}. The cell doesn't make any electrical sense, but contains several good and bad terminals. All the terminals with names like {\bfseries bad1} are incorrect or undesirable for one of the reasons given above, and those with names like {\bfseries good4} are acceptable. \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/tut7.2.ps, width=0.7\columnwidth} \caption{The netlist menu.} \end{center} \end{figure} \begin{table}[ht] \begin{center} \begin{tabular}{|l|l|} \hline Button & Action \\ \hline Current Text & Left-click: prompt for more labels \\ & Right-click: advance to next label \\ \hline Placer & Left-click: place label \\ & Right-click: change label text position \\ \hline Pumps & Left-click: decrement number \\ & Right-click: increment number \\ \hline Find & Search under box, highlight labels \\ & matching current text \\ \hline Current Netlist & Left-click: prompt for new netlist name \\ & Right-click: use edit cell name as netlist name \\ \hline Verify & Check that wiring matches netlist (same as \\ & typing {\bfseries :verify} command) \\ \hline Print & Print names of all terminals in selected net \\ & (same as typing {\bfseries :print} command) \\ \hline Terms & Place feedback areas on screen to identify all terminals \\ & in current netlist (same as {\bfseries :showterms} command) \\ \hline Cleanup & Check current netlist for missing labels and nets \\ & with less than two terminals (same as typing \\ \hline & {\bfseries :cleanup} command) \\ No Net & Delete selected net (same as {\bfseries :dnet} command) \\ \hline Show & Highlight paint connected to material under box \\ & (same as typing {\bfseries :shownet} command) \\ \hline \end{tabular} \caption{A summary of all the netlist menu button actions.} \end{center} \end{table} If you create two or more terminal labels with the same name in the same cell the router will assume that they are electrically equivalent (connected together within the cell). Because of this, when routing the net it will feel free to connect to whichever one of the terminals is most convenient, and ignore the others. In some cases the router may take advantage of electrically equivalent terminals by using {\itshape feed throughs}: entering a cell at one terminal to make one connection, and exiting through an equivalent terminal on the way to make another connection for the same net. \section{Menu for Label Editing} Magic provides a special menu facility to assist you in placing terminal labels and editing netlists. To make the menu appear, invoke the Magic command \starti \ii {\bfseries :specialopen netlist} \endi A new window will appear in the lower-left corner of the screen, containing several rectangular areas on a purple background. Each of the rectangular areas is called a {\itshape button}. Clicking mouse buttons inside the menu buttons will invoke various commands to edit labels and netlists. Figure 2 shows a diagram of the netlist menu and Table I summarizes the meaning of button clicks in various menu items. The netlist menu can be grown, shrunk, and moved just like any other window; see ``Magic Tutorial \#5: Multiple Windows'' for details. It also has its own private set of commands. To see what commands you can type in the netlist menu, move the cursor over the menu and type \starti \ii {\bfseries :help} \endi You shouldn't need to type commands in the netlist menu very often, since almost everything you'll need to do can be done using the menu. See Section 9 for a description of a few of the commands you can type; the complete set is described in the manual page {\itshape magic(1)}. One of the best uses for the commands is so that you can define macros for them and avoid having to go back and forth to the menu; look up the {\bfseries :send} command in the man page to see how to do this. The top half of the menu is for placing labels and the bottom half is for editing netlists. This section describes the label facilities, and Section 4 describes the netlist facilities. The label menu makes it easy for you to enter lots of labels, particularly when there are many labels that are the same except for a number, e.g. {\bfseries bus1}, {\bfseries bus2}, {\bfseries bus3}, etc. There are four sections to the label menu: the current text, the placer, two pumps, and the {\bfseries Find} button. To place labels, first click the left mouse button over the current text rectangle. Then type one or more labels on the keyboard, one per line. You can use this mechanism to enter several labels at once. Type return twice to signal the end of the list. At this point, the first of the labels you typed will appear in the current text rectangle. To place a label, position the box over the area you want to label, then click the left mouse button inside one of the squares of the placer area. A label will be created with the current text. Where you click in the placer determines where the label text will appear relative to the label box: for example, clicking the left-center square causes the text to be centered just to the left of the box. You can place many copies of the same label by moving the box and clicking the placer area again. You can re-orient the text of a label by clicking the right mouse button inside the placer area. For example, if you would like to move a label's text so that it appears centered above the label, place the box over the label and right-click the top-center placer square. If you entered several labels at once, only the first appears in the current text area. However, you can advance to the next label by right-clicking inside the current text area. In this way you can place a long series of labels entirely with the mouse. Try using this mechanism to add labels to {\bfseries tut7a}. The two small buttons underneath the right side of the current text area are called pumps. To see how these work, enter a label name containing a number into the current text area, for example, {\bfseries bus1}. When you do this, the ``1'' appears in the left pump. Right-clicking the pump causes the number to increment, and left-clicking the pump causes the number to decrement. This makes it easy for you to enter a series of numbered signal names. If a name has two numbers in it, the second number will appear in the second pump, and it can be incremented or decremented too. Try using the pumps to place a series of numbered names. The last entry in the label portion of the menu is the {\bfseries Find} button. This can be used to locate a label by searching for a given pattern. If you click the {\bfseries Find} button, Magic will use the current text as a pattern and search the area underneath the box for a label whose name contains the pattern. Pattern-matching is done in the same way as in {\itshape csh}, using the special characters ``*'', ``?'', ``\\'', ``['', and ``]''. Try this on {\bfseries tut7a}: enter ``good*'' into the current text area, place the box around the whole cell, then click on the ``Find'' button. For each of the good labels, a feedback area will be created with white stripes to highlight the area. The {\bfseries :feedback find} command can be used to step through the areas, and {\bfseries :feedback clear} will erase the feedback information from the screen. The {\bfseries :feedback} command has many of the same options as {\bfseries :drc} for getting information about feedback areas; see the Magic manual page for details, or type {\bfseries :feedback help} for a synopsis of the options. \section{Netlist Editing} After placing terminal labels, the next step is to specify the connections between them; this is called netlist editing. The bottom half of the netlist menu is used for editing netlists. The first thing you must do is to specify the netlist you want to edit. Do this by clicking in the current netlist box. If you left-click, Magic will prompt you for the netlist name and you can type it at the keyboard. If you right-click, Magic will use the name of the edit cell as the current netlist name. In either case, Magic will read the netlist from disk if it exists and will create a new netlist if there isn't currently a netlist file with the given name. Netlist files are stored on disk with a ``.net'' extension, which is added by Magic when it reads and writes files. You can change the current netlist by clicking the current netlist button again. Startup Magic on the cell {\bfseries tut7b}, open the netlist menu, and set the current netlist to {\bfseries tut7b}. Then expand the subcells in {\bfseries tut7b} so that you can see their terminals. \begin{table}[ht] \begin{center} \begin{tabular}{|l|l|} \hline Button & Action \\ \hline Left & Select net, using nearest terminal to cursor. \\ \hline Right & Toggle nearest terminal into or out of \\ & current net. \\ \hline Middle & Find nearest terminal, join its net with the \\ & current net. \\ \hline \end{tabular} \caption{The actions of the mouse buttons when the terminal tool is in use.} \end{center} \end{table} Netlist editing is done with the netlist tool. If you haven't already read ``Tutorial \#3: Advanced Painting (Wiring and Plowing)'', you should read it now, up through Section 2.1. Tutorial \#3 explained how to change the current tool by using the space macro or by typing {\bfseries :tool}. Switch tools to the netlist tool (the cursor will appear as a thick square). When the netlist tool is in use the left, right, and middle buttons invoke select, toggle, and join operations respectively (see Table II). To see how they work, move the cursor over the terminal {\bfseries right4} in the top subcell of {\bfseries tut7b} and click the left mouse button (you may have to zoom in a bit to see the labels; terminals are numbered in clockwise order: {\bfseries right4} is the fourth terminal from the top on the right side). This causes the net containing that terminal to be selected. Three hollow white squares will appear over the layout, marking the terminals that are supposed to be wired together into {\bfseries right4}'s net. Left-click over the {\bfseries left3} terminal in the same subcell to select its net, then select the {\bfseries right4} net again. The right button is used to toggle terminals into or out of the current net. If you right-click over a terminal that is in the current net, then it is removed from the current net. If you right-click over a terminal that isn't in the current net, it is added to the current net. A single terminal can only be in one net at a time, so if a terminal is already in a net when you toggle it into another net then Magic will remove it from the old net. Toggle the terminal {\bfseries top4} in the bottom cell out of, then back into, the net containing {\bfseries right4}. Now toggle {\bfseries left3} in the bottom cell into this net. Magic warns you because it had to remove {\bfseries left3} from another net in order to add it to {\bfseries right4}'s net. Type {\bfseries u} to undo this change, then left-click on {\bfseries left3} to make sure it got restored to its old net by the undo. All of the netlist-editing operations are undo-able. The middle button is used to merge two nets together. If you middle-click over a terminal, all the terminals in its net are added to the current net. Play around with the three buttons to edit the netlist {\bfseries tut7b}. Note: the router does not make connections to terminals in the top level cell. It only works with terminals in subcells, or sub-subcells, etc. Because of this, the netlist editor does not permit you to select terminals in the top level cell. If you click over such a terminal Magic prints an error message and refuses to make the selection. If you left-click over a terminal that is not currently in a net, Magic creates a new net automatically. If you didn't really want to make a new net, you have several choices. Either you can toggle the terminal out of its own net, you can undo the select operation, or you can click the {\bfseries No Net} button in the netlist menu (you can do this even while the cursor is in the square shape). The {\bfseries No Net} button removes all terminals from the current net and destroys the net. It's a bad idea to leave single-net terminals in the netlist: the router will treat them as errors. There are two ways to save netlists on disk; these are similar to the ways you can save layout cells. If you type \starti \ii {\bfseries :savenetlist }[{\itshape name}] \endi with the cursor over the netlist menu, the current netlist will be saved on disk in the file {\itshape name}.{\bfseries net}. If no {\itshape name} is typed, the name of the current netlist is used. If you type the command \starti \ii {\bfseries :writeall} \endi then Magic will step through all the netlists that have been modified since they were last written, asking you if you'd like them to be written out. If you try to leave Magic without saving all the modified netlists, Magic will warn you and give you a chance to write them out. If you make changes to a netlist and then decide you don't want them, you can use the {\bfseries :flush} netlist command to throw away all of the changes and re-read the netlist from its disk file. If you create netlists using a text editor or some other program, you can use {\bfseries :flush} after you've modified the netlist file in order to make sure that Magic is using the most up-to-date version. The {\bfseries Print} button in the netlist menu will print out on the text screen the names of all the terminals in the current net. Try this for some of the nets in {\bfseries tut7b}. The official name of a terminal looks a lot like a Unix file name, consisting of a bunch of fields separated by slashes. Each field except the last is the id of a subcell, and the last field is the name of the terminal. These hierarchical names provide unique names for each terminal, even if the same terminal name is re-used in different cells or if there are multiple copies of the same cell. The {\bfseries Verify} button will check the paint of the edit cell to be sure it implements the connections specified in the current netlist. Feedback areas are created to show nets that are incomplete or nets that are shorted together. The {\bfseries Terms} button will cause Magic to generate a feedback area over each of the terminals in the current netlist, so that you can see which terminals are included in the netlist. If you type the command {\bfseries :feedback clear} in a layout window then the feedback will be erased. The {\bfseries Cleanup} button is there as a convenience to help you cleanup your netlists. If you click on it, Magic will scan through the current netlist to make sure it is reasonable. {\bfseries Cleanup} looks for two error conditions: terminal names that don't correspond to any labels in the design, and nets that don't have at least two terminals. When it finds either of these conditions it prints a message and gives you the chance to either delete the offending terminal (if you type {\bfseries dterm}), delete the offending net ({\bfseries dnet}), skip the current problem without modifying the netlist and continue looking for other problems ({\bfseries skip}), or abort the {\bfseries Cleanup} command without making any more changes ({\bfseries abort}). The {\bfseries Show} button provides an additional mechanism for displaying the paint in the net. If you place the box over a piece of paint and click on {\bfseries Show}, Magic will highlight all of the paint in the net under the box. This is similar to pointing at the net and typing {\bfseries s} three times to select the net, except that {\bfseries Show} doesn't select the net (it uses a different mechanism to highlight it), and {\bfseries Show} will trace through all cells, expanded or not (the selection mechanism only considers paint in expanded cells). Once you've used {\bfseries Show} to highlight a net, the only way to make the highlighting go away is to place the box over empty space and invoke {\bfseries Show} again. {\bfseries Show} is an old command that pre-dates the selection interface, but we've left it in Magic because some people find it useful. \section{Netlist Files} Netlists are stored on disk in ordinary text files. You are welcome to edit those files by hand or to write programs that generate the netlists automatically. For example, a netlist might be generated by a schematic editor or by a high-level simulator. See the manual page {\itshape net(5)} for a description of netlist file format. \section{Running the Router} Once you've created a netlist, it is relatively easy to invoke the router. First, place the box around the area you'd like Magic to consider for routing. No terminals outside this area will be considered, and Magic will not generate any paint more than a few units outside this area (Magic may use the next routing grid line outside the area). Load {\bfseries tut7d}, {\bfseries :flush} the netlist if you made any changes to it, set the box to the bounding box of the cell, and then invoke the router using the command: \starti \ii {\bfseries :route} \endi When the command completes, the netlist should be routed. Click the {\bfseries Verify} netlist button to make sure the connections were made correctly. Try deleting a piece from one of the wires and verify again. Feedback areas should appear to indicate where the routing was incorrect. Use the {\bfseries :feedback} command to step through the areas and, eventually, to delete the feedback ({\bfseries :feedback help} gives a synopsis of the command options). If the router is unable to complete the connections, it will report errors to you. Errors may be reported in several ways. For some errors, such as non-existent terminal names, messages will be printed. For other errors, cross-hatched feedback areas will be created. Most of the feedback areas have messages similar to ``Net shifter/bit[0]/phi1: Can't make bottom connection.'' To see the message associated with a feedback area, place the box over the feedback area and type {\bfseries :feedback why}. In this case the message means that for some reason the router was unable to connect the specified net (named by one of its terminals) within one of the routing channel. The terms ``bottom'', ``top'', etc. may be misnomers because Magic sometimes rotates channels before routing: the names refer to the direction at the time the channel was routed, not the direction in the circuit. However, the location of the feedback area indicates where the connection was supposed to have been made. You've probably noticed by now that the router sometimes generates unnecessary wiring, such as inserting extra jogs and U-shapes in wires (look next to {\bfseries right3} in the top cell). These jogs are particularly noticeable in small examples. However, the router actually does {\itshape better} on larger examples: there will still be a bit of extra wire, but it's negligible in comparison to the total wire length on a large chip. Some of this wire is necessary and important: it helps the router to avoid several problem situations that would cause it to fail on more difficult examples. However, you can use the {\bfseries straighten} command described in ``Magic Tutorial \#3: Advanced Painting (Wiring and Plowing)'' to remove unnecessary jogs. Please don't judge the router by its behavior on small examples. On the other hand, if it does awful things on big examples, we'd like to know about it. All of the wires placed by the router are of the same width, so the router won't be very useful for power and ground wiring. When using the Magic router, you can wire power and ground by hand before running the router. The router will be able to work around your hand-placed connections to make the connections in the netlist. If there are certain key signals that you want to wire carefully by hand, you can do this too; the router will work around them. Signals that you route by hand should not be in the netlist. {\bfseries Tutorial7b} has an example of ``hand routing'' in the form of a piece of metal in the middle of the circuit. Undo the routing, and try modifying the metal and/or adding more hand routing of your own to see how it affects the routing. The Magic router has a number of options useful for getting information about the routing and setting routing parameters. You need to invoke the {\bfseries route} command once for each option you want to specify; then type {\bfseries :route} with no options to start up the router with whatever parameters you've set. The {\bfseries viamin}, option which invokes a routing post-pass is, of course, invoked AFTER routing. Type {\bfseries :route netlist} {\itshape file} to specify a netlist for the routing without having to open up the netlist menu. The {\bfseries metal} option lets you toggle metal maximization on and off; if metal maximization is turned on, the router converts routing from the alternate routing layer (``poly'') to the preferred routing layer (``metal'') wherever possible. The {\bfseries vias} option controls metal maximization by specifying how many grid units of ``metal'' conversion make it worthwhile to place vias; setting this to 5 means that metal maximization will add extra vias only if 5 or more grid units of ``poly'' can be converted to ``metal''. View the current technology's router parameters with the {\bfseries tech} option. The {\bfseries jog}, {\bfseries obstacle}, and {\bfseries steady} options let you view and change parameters to control the channel router (this feature is for advanced users). The {\bfseries viamin} option invokes a via minimization algorithm which reduces the number of vias in a routed layout. This can be used as a post-processing step to improve the quality of the routing. This may be useful even when using another router to do the actual routing. Finally, show all parameter values with the {\bfseries settings} option. The options and their actions are summarized in Table III. \begin{table}[ht] \begin{center} \begin{tabular}{|l|l|} \hline Option & Action \\ \hline {\bfseries end} & Print the channel router end constant \\ {\bfseries end}{\itshape real} & Set the channel router end constant \\ \hline {\bfseries help} & Print a summary of the router options \\ \hline {\bfseries jog} & Print the channel router minimum jog length \\ {\bfseries jog} {\itshape int} & Set the minimum jog length, measured in grid units \\ \hline {\bfseries metal} & Toggle metal maximization on or off \\ \hline {\bfseries netlist} & Print the name of the current net list \\ {\bfseries netlist} {\itshape file} & Set the current net list \\ \hline {\bfseries obstacle} & Print the channel router obstacle constant \\ {\bfseries obstacle} {\itshape real} & Set the obstacle constant \\ \hline {\bfseries settings} & Print a list of all router parameters \\ \hline {\bfseries steady} & Print the channel router steady net constant \\ {\bfseries steady} {\itshape int} & Set the steady net constant, measured in grid units \\ \hline {\bfseries tech} & Print router technology information \\ \hline {\bfseries vias} & Print the metal maximization via limit \\ {\bfseries vias} {\itshape int} & Set the via limit \\ \hline {\bfseries viamin} & Minimize vias in a routed layout. \\ \hline \end{tabular} \end{center} \caption{A summary of all of Magic router options.} \end{table} \section{How the Router Works} In order to make the router produce the best possible results, it helps to know a little bit about how it works. The router runs in three stages, called {\itshape channel definition}, {\itshape global routing}, and {\itshape channel routing}. In the channel definition phase, Magic divides the area of the edit cell into rectangular routing areas called channels. The channels cover all the space under the box except the areas occupied by subcells. All of Magic's routing goes in the channel areas, except that stems (Section 8.2) may extend over subcells. To see the channel structure that Magic chose, place the box in {\bfseries tut7d} as if you were going to route, then type the command \starti \ii {\bfseries :channel} \endi in the layout window. Magic will compute the channel structure and display it on the screen as a collection of feedback areas. The channel structure is displayed as white rectangles. Type {\bfseries :feedback clear} when you're through looking at them. The second phase of routing is global routing. In the global routing phase, Magic considers each net in turn and chooses the sequence of channels the net must pass through in order to connect its terminals. The {\itshape crossing points} (places where the net crosses from one channel to another) are chosen at this point, but not the exact path through each channel. In the third phase, each channel is considered separately. All the nets passing through that channel are examined at once, and the exact path of each net is decided. Once the routing paths have been determined, paint is added to the edit cell to implement the routing. The router is grid-based: all wires are placed on a uniform grid. For the standard nMOS process the grid spacing is 7 units, and for the standard SCMOS process it is 8 units. If you type {\bfseries :grid 8} after routing {\bfseries tut7b}, you'll see that all of the routing lines up with its lower and left sides on grid lines. Fortunately, you don't have to make your cell terminals line up on even grid boundaries. During the routing Magic generates {\itshape stems} that connect your terminals up to grid lines at the edges of channels. Notice that there's space left by Magic between the subcells and the channels; this space is used by the stem generator. \section{What to do When the Router Fails} Don't be surprised if the router is unable to make all the connections the first time you try it on a large circuit. Unless you have extra routing space in your chip, you may have to make slight re-arrangements to help the router out. The paragraphs below describe things you can do to make life easier for the router. This section is not very well developed, so we'd like to hear about techniques you use to improve routability. If you discover new techniques, send us mail and we'll add them to this section. \subsection{Channel Structure} One of the first things to check when the router fails is the channel structure. If using the Magic router, type {\bfseries :channel} to look at the channels. One common mistake is to have some of the desired routing area covered by subcells; Magic only runs wires where there are no subcells. Check to be sure that there are channels everywhere that you're expecting wires to run. If you place cells too close together, there may not be enough room to have a channel between the cells; when this happens Magic will route willy-nilly across the tops of cells to bring terminals out to channels, and will probably generate shorts or design-rule violations. To solve the problem, move the cells farther apart. If there are many skinny channels, it will be difficult for the router to produce good routing. Try to re-arrange the cell structure to line up edges of nearby cells so that there are as few channels as possible and they are as large as possible (before doing this you'll probably want to get rid of the existing routing by undo-ing or by flushing the edit cell). \subsection{Stems} Another problem has to do with the stem generator. Stems are the pieces of wiring that connect terminals up to grid points on the edges of channels. The current stem generation code doesn't know about connectivity or design rules. It simply finds the nearest routing grid point and wires out to that point, without considering any other terminals. If a terminal is not on the edge of the cell, the stem runs straight across the cell to the nearest channel, without any consideration for other material in the cell. If two terminals are too close together, Magic may decide to route them both to the same grid point. When this happens, you have two choices. Either you can move the cell so that the terminals have different nearest grid points (for example, you can line its terminals up with the grid lines), or if this doesn't work you'll have to modify the cell to make the terminals farther apart. The place where stems cause the most trouble is in PLAs, many of which have been optimized to space the outputs as closely together as possible. In some cases the outputs are closer together than the routing grid, which is an impossible situation for the stem generator. In this case, we think the best approach is to change the PLA templates to space the outputs farther apart. Either space them exactly the same as the router grid (in which case you can line the PLAs up before routing so the terminals are already on the grid), or space the outputs at least 1.5 grid units apart so the stem generator won't have troubles. Having tightly-spaced PLA outputs is false economy: it makes it more difficult to design the PLAs and results in awful routing problems. Even if Magic could river-route out from tightly-spaced terminals to grid lines (which it can't), it would require $N^2$ space to route out $N$ lines; it takes less area to stretch the PLA. \subsection{Obstacles} The router tends to have special difficulties with obstacles running along the edges of channels. When you've placed a power wire or other hand-routing along the edge of a channel, the channel router will often run material under your wiring in the other routing layer, thereby blocking both routing layers and making it impossible to complete the routing. Where this occurs, you can increase the chances of successful routing by moving the hand-routing away from the channel edges. It's especially important to keep hand-routing away from terminals. The stem generator will not pay any attention to hand-routing when it generates stems (it just makes a bee-line for the nearest grid point), so it may accidentally short a terminal to nearby hand-routing. \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/tut7.3.ps, width=0.4\columnwidth} \caption{When placing hand routing, it is best to place wires with their left and bottom edges along grid lines, and contacts centered on the wires. In this fashion, the hand routing will block as few routing grid lines as possible.} \end{center} \end{figure} When placing hand-routing, you can get better routing results by following the advice illustrated in Figure 3. First, display the routing grid. For example, if the router is using a 8-unit grid (which is true for the standard SCMOS technology), type {\bfseries :grid 8}. Then place all your hand routing with its left and bottom edges along the grid lines. Because of the way the routing tools work, this approach results in the least possible amount of lost routing space. \section{More Netlist Commands} In addition to the netlist menu buttons and commands described in Section 4, there are a number of other netlist commands you can invoke by typing in the netlist window. Many of these commands are textual equivalents of the menu buttons. However, they allow you to deal with terminals by typing the hierarchical name of the terminal rather than by pointing to it. If you don't know where a terminal is, or if you have deleted a label from your design so that there's nothing to point to, you'll have to use the textual commands. Commands that don't just duplicate menu buttons are described below; see the {\itshape magic(1)} manual page for details on the others. The netlist command \starti \ii {\bfseries :extract} \endi will generate a net from existing wiring. It looks under the box for paint, then traces out all the material in the edit cell that is connected electrically to that paint. Wherever the material touches subcells it looks for terminals in the subcells, and all the terminals it finds are placed into a new net. Warning: there is also an {\bfseries extract} command for layout windows, and it is totally different from the {\bfseries extract} command in netlist windows. Make sure you've got the cursor over the netlist window when you invoke this command! The netlist editor provides two commands for ripping up existing routing (or other material). They are \starti \ii {\bfseries :ripup} \\ \ii {\bfseries :ripup netlist} \endi The first command starts by finding any paint in the edit cell that lies underneath the box. It then works outward from that paint to find all paint in the edit cell that is electrically connected to the starting paint. All of this paint is erased. ({\bfseries :ripup} isn't really necessary, since the same effect can be achieved by selecting all the paint in the net and deleting the selection; it's a hangover from olden days when there was no selection). The second form of the command, {\bfseries :ripup netlist}, is similar to the first except that it starts from each of the terminals in the current netlist instead of the box. Any paint in the edit cell that is electrically connected to a terminal is erased. The {\bfseries :ripup netlist} command may be useful to ripup existing routing before rerouting. The command \starti \ii {\bfseries :trace} [{\itshape name}] \endi provides an additional facility for examining router feedback. It highlights all paint connected to each terminal in the net containing {\itshape name}, much as the {\bfseries Show} menu button does for paint connected to anything under the box. The net to be highlighted may be specified by naming one of its terminals, for example, {\bfseries :trace shifter/bit[0]/phi1}. Use the trace command in conjunction with the nets specified in router feedback to see the partially completed wiring for a net. Where no net is specified, the {\bfseries :trace} command highlights the currently selected net. \end{document} magic-8.0.210/doc/latexfiles/tuttcl5.tex0000644000175000001440000000345510751423606016520 0ustar timusers%---------------------------------------------------------------------------- % Magic Tcl tutorial number 5 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ig{\>} \def\ih{\>\>} \def\ii{\>\>\>} \def\mytitle{Magic Tcl Tutorial \#5: Writing Tcl Scripts for Magic} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape R. Timothy Edwards} \\ \vspace*{0.5in} Space Department \\ Johns Hopkins University \\ Applied Physics Laboratory \\ Laurel, MD 20723 \\ \vspace*{0.25in} This tutorial corresponds to Tcl-based Magic version 7.2 \\ \end{center} \vspace*{0.5in} \section{Scripting in Magic} \end{document} magic-8.0.210/doc/latexfiles/tut5.tex0000644000175000001440000004605510751423606016020 0ustar timusers%---------------------------------------------------------------------------- % Magic tutorial number 5 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Magic Tutorial \#5: Multiple Windows} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape Robert N. Mayo} \\ \vspace*{0.5in} Computer Science Division \\ Electrical Engineering and Computer Sciences \\ University of California \\ Berkeley, CA 94720 \\ \vspace*{0.25in} {\itshape (Updated by others, too.)} \\ \vspace*{0.25in} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Tutorials to read first:} \starti \> Magic Tutorial \#1: Getting Started \\ \> Magic Tutorial \#2: Basic Painting and Selection \endi {\noindent\bfseries\large Commands introduced in this tutorial:} \starti \> :center :closewindow, :openwindow, :over, :specialopen, :under, :windowpositions \endi {\noindent\bfseries\large Macros introduced in this tutorial:} \starti \> o, O, ``,'' \endi \vspace*{0.75in} \section{Introduction} A window is a rectangular viewport. You can think of it as a magnifying glass that may be moved around on your chip. Magic initially displays a single window on the screen. This tutorial will show you how to create new windows and how to move old ones around. Multiple windows allow you to view several portions of a circuit at the same time, or even portions of different circuits. Some operations are easier with multiple windows. For example, let's say that you want to paint a very long line, say 3 units by 800 units. With a single window it is hard to align the box accurately since the magnification is not great enough. With multiple windows, one window can show the big picture while other windows show magnified views of the areas where the box needs to be aligned. The box can then be positioned accurately in these magnified windows. \section{Manipulating Windows} \subsection{Opening and Closing Windows} Initially Magic displays one large window. The \starti \ii {\bfseries :openwindow }[{\itshape cellname}] \endi command opens another window and loads the given cell. To give this a try, start up Magic with the command {\bfseries magic tut5a}. Then point anywhere in a Magic window and type the command {\bfseries :openwindow tut5b} (make sure you're pointing to a Magic window). A new window will appear and it will contain the cell {\bfseries tut5b}. If you don't give a {\itshape cellname} argument to {\bfseries :openwindow}, it will open a new window on the cell containing the box, and will zoom in on the box. The macro {\bfseries o} is predefined to {\bfseries :openwindow}. Try this out by placing the box around an area of {\bfseries tut5b} and then typing {\bfseries o}. Another window will appear. You now have three windows, all of which display pieces of layout. There are other kinds of windows in Magic besides layout windows: you'll learn about them later. Magic doesn't care how many windows you have (within reason) nor how they overlap. To get rid of a window, point to it and type \starti \ii {\bfseries :closewindow} \endi or use the macro {\bfseries O}. Point to a portion of the original window and close it. \subsection{Resizing and Moving Windows} If you have been experimenting with Magic while reading this you will have noticed that windows opened by {\bfseries :openwindow} are all the same size. If you'd prefer a different arrangement you can resize your windows or move them around on the screen. The techniques used for this are different, however, depending on what kind of display you're using. If you are using a workstation, then you are also running a window system such as X11 or SunView. In this case Magic's windows are moved and resized just like the other windows you have displayed, and you can skip the rest of this section. For displays like the AED family, which don't have a built-in window package, Magic implements its own window manager. To re-arrange windows on the screen you can use techniques similar to those you learned for moving the box for painting operations. Point somewhere in the border area of a window, except for the lower left corner, and press and hold the right button. The cursor will change to a shape like this: \begin{center} \begin{tabular}{c|c|}\hline \hspace*{0.1in} & \hspace*{0.1in} \\ \hline \hspace*{0.1in} & \hspace*{0.1in} \\ \end{tabular} \end{center} This indicates that you have hold of the upper right corner of the window. Point to a new location for this corner and release the button. The window will change shape so that the corner moves. Now point to the border area and press and hold the left button. The cursor will now look like: \begin{center} \begin{tabular}{|c|c|}\hline \hspace*{0.1in} & \hspace*{0.1in} \\ \hline \hspace*{0.1in} & \hspace*{0.1in} \\ \hline \end{tabular} \end{center} This indicates that you have hold of the entire window by its lower left window. Move the cursor and release the button. The window will move so that its lower left corner is where you pointed. The other button commands for positioning the box by any of its corners also work for windows. Just remember to point to the border of a window before pushing the buttons. The middle button can be used to grow a window up to full-screen size. To try this, click the middle button over the caption of the window. The window will now fill the entire screen. Click in the caption again and the window will shrink back to its former size. \subsection{Shuffling Windows} By now you know how to open, close, and resize windows. This is sufficient for most purposes, but sometimes you want to look at a window that is covered up by another window. The {\bfseries :underneath} and {\bfseries :over} commands help with this. The {\bfseries :underneath} command moves the window that you are pointing at underneath all of the other windows. The {\bfseries :over} command moves the window on top of the rest. Create a few windows that overlap and then use these commands to move them around. You'll see that overlapping windows behave just like sheets of paper: the ones on top obscure portions of the ones underneath. \subsection{Scrolling Windows} Some of the windows have thick bars on the left and bottom borders. These are called {\itshape scroll bars}, and the slugs within them are called {\itshape elevators}. The size and position of an elevator indicates how much of the layout (or whatever is in the window) is currently visible. If an elevator fills its scroll bar, then all of the layout is visible in that window. If an elevator fills only a portion of the scroll bar, then only that portion of the layout is visible. The position of the elevator indicates which part is visible---if it is near the bottom, you are viewing the bottom part of the layout; if it is near the top, you are viewing the top part of the layout. There are scroll bars for both the vertical direction (the left scroll bar) and the horizontal direction (the bottom scroll bar). Besides indicating how much is visible, the scroll bars can be used to change the view of the window. Clicking the middle mouse button in a scroll bar moves the elevator to that position. For example, if you are viewing the lower half of a chip (elevator near the bottom) and you click the middle button near the top of the scroll bar, the elevator will move up to that position and you will be viewing the top part of your chip. The little squares with arrows in them at the ends of the scroll bars will scroll the view by one screenful when the middle button is clicked on them. They are useful when you want to move exactly one screenful. The {\bfseries :scroll} command can also be used to scroll the view (though we don't think it's as easy to use as the scroll bars). See the man page for information on it. If you only want to make a small adjustment in a window's view, you can use the command \starti \ii {\bfseries :center} \endi It will move the view in the window so that the point that used to be underneath the cursor is now in the middle of the window. The macro {\bfseries ,} is predefined to {\bfseries :center}. The bull's-eye in the lower left corner of a window is used to zoom the view in and out. Clicking the left mouse button zooms the view out by a factor of 2, and clicking the right mouse button zooms in by a factor of 2. Clicking the middle button here makes everything in the window visible and is equivalent to the {\bfseries :view} command. \subsection{Saving Window Configurations} After setting up a bunch of windows you may want to save the configuration (for example, you may be partial to a set of 3 non-overlapping windows). To do this, type: \starti \ii {\bfseries :windowpositions} {\itshape filename} \endi A set of commands will be written to the file. This file can be used with the {\bfseries :source} command to recreate the window configuration later. (However, this only works well if you stay on the same kind of display; if you create a file under X11 and then {\bfseries :source} it under SunView, you might not get the same positions since the coordinate systems may vary.) \section{How Commands Work Inside of Windows} Each window has a caption at the top. Here is an example: \starti \ii {\bfseries mychip EDITING shiftcell} \endi This indicates that the window contains the root cell {\bfseries mychip}, and that a subcell of it called {\bfseries shiftcell} is being edited. You may remember from the Tutorial \#4 that at any given time Magic is editing exactly one cell. If the edit cell is in another window then the caption on this window will read: \starti \ii {\bfseries mychip [NOT BEING EDITED]} \endi Let's do an example to see how commands are executed within windows. Close any layout windows that you may have on the screen and open two new windows, each containing the cell {\bfseries tut5a}. (Use the {\bfseries :closewindow} and {\bfseries :openwindow tut5a} commands to do this.) Try moving the box around in one of the windows. Notice that the box also moves in the other window. Windows containing the same root cell are equivalent as far as the box is concerned: if it appears in one it will appear in all, and it can be manipulated from them interchangeably. If you change {\bfseries tut5a} by painting or erasing portions of it you will see the changes in both windows. This is because both windows are looking at the same thing: the cell {\bfseries tut5a}. Go ahead and try some painting and erasing until you feel comfortable with it. Try positioning one corner of the box in one window and another corner in another window. You'll find it doesn't matter which window you point to, all Magic knows is that you are pointing to {\bfseries tut5a}. These windows are independent in some respects, however. For example, you may scroll one window around without affecting the other window. Use the scrollbars to give this a try. You can also expand and unexpand cells independently in different windows. We have seen how Magic behaves when both windows view a single cell. What happens when windows view different cells? To try this out load {\bfseries tut5b} into one of the windows (point to a window and type {\bfseries :load tut5b}). You will see the captions on the windows change---only one window contains the cell currently being edited. The box cannot be positioned by placing one corner in one window and another corner in the other window because that doesn't really make sense (try it). However, the selection commands work between windows: you can select information in one window and then copy it into another (this only works if the window you're copying into contains the edit cell; if not, you'll have to use the {\bfseries :edit} command first). The operation of many Magic commands is dependent upon which window you are pointing at. If you are used to using Magic with only one window you may, at first, forget to point to the window that you want the operation performed upon. For instance, if there are several windows on the screen you will have to point to one before executing a command like {\bfseries :grid}---otherwise you may not affect the window that you intended! \section{Special Windows} In addition to providing multiple windows on different areas of a layout, Magic provides several special types of windows that display things other than layouts. For example, there are special window types to edit netlists and to adjust the colors displayed on the screen. One of the special window types is described in the section below; others are described in the other tutorials. The \starti \ii {\bfseries :specialopen} {\itshape type }[{\itshape args}] \endi command is used to create these sorts of windows. The {\itshape type} argument tells what sort of window you want, and {\itshape args} describe what you want loaded into that window. The {\bfseries :openwindow} {\itshape cellname} command is really just short for the command {\bfseries :specialopen layout} {\itshape cellname}. Each different type of window (layout, color, etc.) has its own command set. If you type {\bfseries :help} in different window types, you'll see that the commands are different. Some of the commands, such as those to manipulate windows, are valid in all windows, but for other commands you must make sure you're pointing to the right kind of window or the command may be misinterpreted. For example, the {\bfseries :extract} command means one thing in a layout window and something totally different in a netlist window. \section{Color Editing} Special windows of type {\bfseries color} are used to edit the red, green, and blue intensities of the colors displayed on the screen. To create a color editing window, invoke the command \starti \ii {\bfseries :specialopen color }[{\itshape number}] \endi {\itshape Number} is optional; if present, it gives the octal value of the color number whose intensities are to be edited. If {\itshape number} isn't given, 0 is used. Try opening a color window on color 0. A color editing window contains 6 ``color bars'', 12 ``color pumps'' (one on each side of each bar), plus a large rectangle at the top of the window that displays a swatch of the color being edited (called the ``current color'' from now on). The color bars display the components of the current color in two different ways. The three bars on the left display the current color in terms of its red, green, and blue intensities (these intensities are the values actually sent to the display). The three bars on the right display the current color in terms of hue, saturation, and value. Hue selects a color of the spectrum. Saturation indicates how diluted the color is (high saturation corresponds to a pure color, low saturation corresponds to a color that is diluted with gray, and a saturation of 0 results in gray regardless of hue). Value indicates the overall brightness (a value of 0 corresponds to black, regardless of hue or saturation). There are several ways to modify the current color. First, try pressing any mouse button while the cursor is over one of the color bars. The length of the bar, and the current color, will be modified to reflect the mouse position. The color map in the display is also changed, so the colors will change everywhere on the screen that the current color is displayed. Color 0, which you should currently be editing, is the background color. You can also modify the current color by pressing a button while the cursor is over one of the ``color pumps'' next to the bars. If you button a pump with ``+'' in it, the value of the bar next to it will be incremented slightly, and if you button the ``-'' pump, the bar will be decremented slightly. The left button causes a change of about 1\% in the value of the bar, and the right button will pump the bar up or down by about 5\%. Try adjusting the bars by buttoning the bars and the pumps. If you press a button while the cursor is over the current color box at the top of the window, one of two things will happen. In either case, nothing happens until you release the button. Before releasing the button, move the cursor so it is over a different color somewhere on the screen. If you pressed the left button, then when the button is released the color underneath the cursor becomes the new current color, and all future editing operations will affect this color. Try using this feature to modify the color used for window borders. If you pressed the right button, then when the button is released the value of the current color is copied from whatever color is present underneath the cursor. There are only a few commands you can type in color windows, aside from those that are valid in all windows. The command \starti \ii {\bfseries :color }[{\itshape number}] \endi will change the current color to {\itshape number}. If no {\itshape number} is given, this command will print out the current color and its red, green, and blue intensities. The command \starti \ii {\bfseries :save }[{\itshape techStyle displayStyle monitorType}] \endi will save the current color map in a file named {\itshape techStyle}.{\itshape displayStyle}.{\itshape monitorType}{\bfseries .cmap}, where {\itshape techStyle} is the type of technology (e.g., {\bfseries mos}), {\itshape displayStyle} is the kind of display specified by a {\bfseries styletype} in the {\bfseries style} section of a technology file (e.g., {\bfseries 7bit}), and {\itshape monitorType} is the type of the current monitor (e.g., {\bfseries std}). If no arguments are given, the current technology style, display style, and monitor type are used. The command \starti \ii {\bfseries :load }[{\itshape techStyle displayStyle monitorType}] \endi will load the color map from the file named {\itshape techStyle}.{\itshape displayStyle}.{\itshape monitorType}{\bfseries .cmap} as above. If no arguments are given, the current technology style, display style, and monitor type are used. When loading color maps, Magic looks first in the current directory, then in the system library. \end{document} magic-8.0.210/doc/latexfiles/tut1.tex0000644000175000001440000005160110751423606016005 0ustar timusers%---------------------------------------------------------------------------- % Magic tutorial number 1 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Magic Tutorial \#1: Getting Started} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape John Ousterhout} \\ \vspace*{0.5in} Computer Science Division \\ Electrical Engineering and Computer Sciences \\ University of California \\ Berkeley, CA 94720 \\ \vspace*{0.25in} {\itshape (Updated by others, too.)} \\ \vspace*{0.25in} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} \section{What is Magic?} Magic is an interactive system for creating and modifying VLSI circuit layouts. With Magic, you use a color graphics display and a mouse or graphics tablet to design basic cells and to combine them hierarchically into large structures. Magic is different from other layout editors you may have used. The most important difference is that Magic is more than just a color painting tool: it understands quite a bit about the nature of circuits and uses this information to provide you with additional operations. For example, Magic has built-in knowledge of layout rules; as you are editing, it continuously checks for rule violations. Magic also knows about connectivity and transistors, and contains a built-in hierarchical circuit extractor. Magic also has a {\itshape plow} operation that you can use to stretch or compact cells. Lastly, Magic has routing tools that you can use to make the global interconnections in your circuits. Magic is based on the Mead-Conway style of design. This means that it uses simplified design rules and circuit structures. The simplifications make it easier for you to design circuits and permit Magic to provide powerful assistance that would not be possible otherwise. However, they result in slightly less dense circuits than you could get with more complex rules and structures. For example, Magic permits only {\itshape Manhattan} designs (those whose edges are vertical or horizontal). Circuit designers tell us that our conservative design rules cost 5-10\% in density. We think that the density sacrifice is compensated for by reduced design time. \begin{table}[ht] \begin{center} \begin{tabular}{|l|} \hline Magic Tutorial \#1: Getting Started \\ Magic Tutorial \#2: Basic Painting and Selection \\ Magic Tutorial \#3: Advanced Painting (Wiring and Plowing) \\ Magic Tutorial \#4: Cell Hierarchies \\ Magic Tutorial \#5: Multiple Windows \\ Magic Tutorial \#6: Design-Rule Checking \\ Magic Tutorial \#7: Netlists and Routing \\ Magic Tutorial \#8: Circuit Extraction \\ Magic Tutorial \#9: Format Conversion for CIF and Calma \\ Magic Tutorial \#10: The Interactive Route \\ Magic Tutorial \#11: Using RSIM with Magic \\ \hline Magic Maintainer's Manual \#1: Hints for System Maintainers \\ Magic Maintainer's Manual \#2: The Technology File \\ Magic Maintainer's Manual \#3: Display Styles, Color Maps, and Glyphs \\ Magic Maintainer's Manual \#4: Using Magic Under X Windows \\ \hline Magic Technology Manual \#1: NMOS \\ Magic Technology Manual \#2: SCMOS \\ \hline \end{tabular} \end{center} \caption{The Magic tutorials, maintenance manuals, and technology manuals.} \label{tutorials} \end{table} \section{How to Get Help and Report Problems} There are several ways you can get help about Magic. If you are trying to learn about the system, you should start off with the Magic tutorials, of which this is the first. Each tutorial introduces a particular set of facilities in Magic. There is also a set of manuals intended for system maintainers. These describe things like how to create new technologies. Finally, there is a set of technology manuals. Each one of the technology manuals describes the features peculiar to a particular technology, such as layer names and design rules. Table~\ref{tutorials} lists all of the Magic manuals. The tutorials are designed to be read while you are running Magic, so that you can try out the new commands as they are explained. You needn't read all the tutorials at once; each tutorial lists the other tutorials that you should read first. The tutorials are not necessarily complete. Each one is designed to introduce a set of facilities, but it doesn't necessarily cover every possibility. The ultimate authority on how Magic works is the reference manual, which is a standard Unix {\itshape man} page. The {\itshape man} page gives concise and complete descriptions of all the Magic commands. Once you have a general idea how a command works, the {\itshape man} page is probably easier to consult than the tutorial. However, the {\itshape man} page may not make much sense until after you've read the tutorial. A third way of getting help is available on-line through Magic itself. The {\bfseries :help} command will print out one line for each Magic command, giving the command's syntax and an extremely brief description of the command. This facility is useful if you've forgotten the name or exact syntax of a command. After each screenful of help information, {\bfseries :help} stops and prints ``--More--''. If you type a space, the next screenful of data will be output, and if you type {\bfseries q} the rest of the output will be skipped. If you're interested in information about a particular subject, you can type \starti \ii {\bfseries :help} {\itshape subject} \endi This command will print out each command description that contains the {\itshape subject} string. If you have a question or problem that can't be answered with any of the above approaches, you may contact the Magic authors by sending mail to {\ttfamily magic@ucbarpa.Berkeley.EDU}. This will log your message in a file (so we can't forget about it) and forward the message to the Magic maintainers. Magic maintenance is a mostly volunteer effort, so when you report a bug or ask a question, {\itshape please} be specific. Obviously, the more specific you are, the more likely we can answer your question or reproduce the bug you found. We'll tend to answer the specific bug reports first, since they involve less time on our part. Try to describe the exact sequence of events that led to the problem, what you expected to happen, and what actually happened. If possible, find a small example that reproduces the problem and send us the relevant (small!) files so we can make it happen here. Or best of all, send us a bug fix along with a small example of the problem. \section{Graphics Configuration} Magic can be run with different graphics hardware. The most common configuration is to run Magic under X11 on a workstation. Another way to run Magic is under SunView on a Sun workstation, or under OpenGL (in an X11 environment) on an SGI workstation or Linux box with accelerated 3D video hardware and drivers. Legacy code exists supporting AED graphics terminals and X10 (the forerunner of X11). The rest of this section concerns X11. Before starting up magic, make sure that your {\ttfamily DISPLAY} variable is set correctly. If you are running magic and your X server on the same machine, set it to {\ttfamily unix:0}: \starti \ii {\bfseries setenv} {\ttfamily DISPLAY unix:0} \endi The Magic window is an ordinary X window, and can be moved and resized using the window manager. For now, you can skip to the next major section: "Running Magic". \section{Advanced X Use} The X11 driver can read in window sizing and font preferences from your {\itshape .Xdefaults} file. The following specifications are recognized: \starti \> {\bfseries magic.window:} \ii 1000x600+10+10 \\ \> {\bfseries magic.newwindow:} \ii 300x300+400+100 \\ \> {\bfseries magic.small:} \ii helvetica8 \\ \> {\bfseries magic.medium:} \ii helvetica12 \\ \> {\bfseries magic.large:} \ii helvetica18 \\ \> {\bfseries magic.xlarge:} \ii helvetica24 \endi {\bfseries magic.window} is the size and position of the initial window, while {\bfseries magic.newwindow} is the size and position of subsequent windows. If these are left blank, you will be prompted to give the window's position and size. {\bfseries small}, {\bfseries medium}, {\bfseries large}, and {\bfseries xlarge} are various fonts magic uses for labels. Some X11 servers read the {\ttfamily .Xdefaults} file only when you initially log in; you may have to run {\ttfamily xrdb -load \~{}/.Xdefaults} for the changes to take effect. Under X11, Magic can run on a display of any depth for which there are colormap and dstyle files. Monochrome, 4 bit, 6 bit, 7 bit, and 24 bit files for MOS are distributed in this release. You can explicitly specify how many planes Magic is to use by adding a suffix numeral between 1 and 7 to ``XWIND'' when used with Magic's ``-d'' option. For example, ``magic -d XWIND1'' runs magic on a monochrome display and ``magic -d XWIND7'' runs magic on a 7 plane display. If this number is not specified, magic checks the depth of the display and picks the largest number in the set \{1, 4, 6, 7, 16, 24\} that the display will support. Another way to force the display type is to set an environment variable called {\ttfamily MAGIC\_COLOR} to one of the strings ``8bit'', ``16bit'', or ``24bit''. \medskip \noindent {\bfseries \itshape Linux note:} \\ Magic's ``native'' display (except when using the OpenGL interface) is the 8-bit PseudoColor visual type. 24-bit TrueColor visuals prevent Magic from allocating colors for bit-plane logical operations, so the 24-bit interface is visually somewhat sub-par, requiring stipple patterns on all metal layers, for instance. Under Linux, a few (commercial) X drivers will support 8-bit overlays on top of 24-bit TrueColor when using 32-bit color. This is the ideal way to use magic, because the colormap for the rest of the display is preserved when the cursor is inside the Magic window. Otherwise, the X session may have to be started using ``{\ttfamily startx --bpp 8}'' to force it to use the 8-bit PseudoColor visual. \medskip \noindent {\bfseries \itshape X11 remote usage note:} \\ When running Magic remotely on an X terminal, the colormap allocation may differ for the local machine compared to the remote machine. In some cases, this can cause the background of magic to appear black, usually with a black-on-black cursor. This is known to be true of X11 drivers for Windows (such as PC-XWare), due to the way the Windows 8-bit PseudoColor colormap is set up. This behavior can be corrected by setting two environment variables on the remote machine as follows: \starti \ii {\bfseries setenv} {\ttfamily X\_COLORMAP\_BASE 128} \\ \ii {\bfseries setenv} {\ttfamily X\_COLORMAP\_DEFAULT 0} \\ \endi This causes Magic to avoid trying to allocate the first color in the colormap, which under Windows is fixed as black. \section{Running Magic} From this point on, you should be sitting at a Magic workstation so you can experiment with the program as you read the manuals. Starting up Magic is usually pretty simple. Just log in and, if needed, start up your favorite window system. Then type the shell command \starti \ii {\bfseries magic tut1} \endi {\bfseries Tut1} is the name of a library cell that you will play with in this tutorial. At this point, several colored rectangles should appear on the color display along with a white box and a cursor. A message will be printed on the text display to tell you that {\bfseries tut1} isn't writable (it's in a read-only library), and a ``$>$'' prompt should appear. If this has happened, then you can skip the rest of this section (except for the note below) and go directly to Section 5. Note: in the tutorials, when you see things printed in boldface, for example, {\bfseries magic tut1} from above, they refer to things you type exactly, such as command names and file names. These are usually case sensitive ({\bfseries A} is different from {\bfseries a}). When you see things printed in italics, they refer to classes of things you might type. Arguments in square brackets are optional. For example, a more complete description of the shell command for Magic is \starti \ii {\bfseries magic} [{\itshape file}] \endi You could type any file name for {\itshape file}, and Magic would start editing that file. It turns out that {\bfseries tut1} is just a file in Magic's cell library. If you didn't type a file name, Magic would load a new blank cell. If things didn't happen as they should have when you tried to run Magic, any of several things could be wrong. If a message of the form ``magic: Command not found'' appears on your screen it is because the shell couldn't find the Magic program. The most stable version of Magic is the directory {\ttfamily \~{}cad/bin}, and the newest public version is in {\ttfamily \~{}cad/new}. You should make sure that both these directories are in your shell path. Normally, {\ttfamily \~{}cad/new} should appear before {\ttfamily \~{}cad/bin}. If this sounds like gibberish, find a Unix hacker and have him or her explain to you about paths. If worst comes to worst, you can invoke Magic by typing its full name: \starti \ii {\bfseries \~{}cad/bin/magic tut1} \endi Another possible problem is that Magic might not know what kind of display you are using. To solve this, use magic's {\bfseries -d} flag: \starti \ii {\bfseries magic -d} {\itshape display} {\bfseries tut1} \endi {\itshape Display} is usually the model number of the workstation you are using or the name of your window system. Look in the manual page for a list of valid names, or just guess something. Magic will print out the list of valid names if you guess wrong. If you are using a graphics terminal (not a workstation), it is possible that Magic doesn't know which serial line to use. To learn how to fix this, read about the {\bfseries -g} switch in the magic(1) manual page. Also read the displays(5) manual page. \section{The Box and the Cursor} Two things, called the {\itshape box} and the {\itshape cursor}, are used to select things on the color display. As you move the mouse, the cursor moves on the screen. The cursor starts out with a crosshair shape, but you'll see later that its shape changes as you work to provide feedback about what you're doing. The left and right mouse buttons are used to position the box. If you press the left mouse button and then release it, the box will move so that its lower left corner is at the cursor position. If you press and release the right mouse button, the upper right corner of the box will move to the cursor position, but the lower left corner will not change. These two buttons are enough to position the box anywhere on the screen. Try using the buttons to place the box around each of the colored rectangles on the screen. Sometimes it is convenient to move the box by a corner other than the lower left. To do this, press the left mouse button and {\itshape hold it down}. The cursor shape changes to show you that you are moving the box by its lower left corner: \begin{center} \begin{tabular}{|c|} \hline \hspace*{0.1in} \\ \hline \end{tabular} \end{center} While holding the button down, move the cursor near the lower right corner of the box, and now click the right mouse button (i.e. press and release it, while still holding down the left button). The cursor's shape will change to indicate that you are now moving the box by its lower right corner. Move the cursor to a different place on the screen and release the left button. The box should move so that its lower right corner is at the cursor position. Try using this feature to move the box so that it is almost entirely off-screen to the left. Try moving the box by each of its corners. You can also reshape the box by corners other than the upper right. To do this, press the right mouse button and hold it down. The cursor shape shows you that you are reshaping the box by its upper right corner: \begin{center} \begin{tabular}{c|} \hline \hspace*{0.1in} \\ \end{tabular} \end{center} Now move the cursor near some other corner of the box and click the left button, all the while holding the right button down. The cursor shape will change to show you that now you are reshaping the box by a different corner. When you release the right button, the box will reshape so that the selected corner is at the cursor position but the diagonally opposite corner is unchanged. Try reshaping the box by each of its corners. \section{Invoking Commands} Commands can be invoked in Magic in three ways: by pressing buttons on the mouse; by typing single keystrokes on the text keyboard (these are called {\itshape macros}); or by typing longer commands on the text keyboard (these are called {\itshape long commands}). Many of the commands use the box and cursor to help guide the command. To see how commands can be invoked from the buttons, first position the box over a small blank area in the middle of the screen. Then move the cursor over the red rectangle and press the middle mouse button. At this point, the area of the box should get painted red. Now move the cursor over empty space and press the middle button again. The red paint should go away. Note how this command uses both the cursor and box locations to control what happens. As an example of a macro, type the {\bfseries g} key on the text keyboard. A grid will appear on the color display, along with a small black box marking the origin of the cell. If you type {\bfseries g} again, the grid will go away. You may have noticed earlier that the box corners didn't move to the exact cursor position: you can see now that the box is forced to fall on grid points. Long commands are invoked by typing a colon (``:'') or semi-colon (``;''). After you type the colon or semi-colon, the ``$>$'' prompt on the text screen will be replaced by a ``:'' prompt. This indicates that Magic is waiting for a long command. At this point you should type a line of text, followed by a return. When the long command has been processed, the ``$>$'' prompt reappears on the text display. Try typing semi-colon followed by return to see how this works. Occasionally a ``]'' (right bracket) prompt will appear. This means that the design-rule checker is reverifying part of your design. For now you can just ignore this and treat ``]'' like ``$>$''. Each long command consists of the name of the command followed by arguments, if any are needed by that command. The command name can be abbreviated, just as long as you type enough characters to distinguish it from all other long commands. For example, {\bfseries :h} and {\bfseries :he} may be used as abbreviations for {\bfseries :help}. On the other hand, {\bfseries :u} may not be used as an abbreviation for {\bfseries :undo} because there is another command, {\bfseries :upsidedown}, that has the same abbreviation. Try typing {\bfseries :u}. As an example of a long command, put the box over empty space on the color display, then invoke the long command \starti \ii {\bfseries :paint red} \endi The box should fill with the red color, just as if you had used the middle mouse button to paint it. Everything you can do in Magic can be invoked with a long command. It turns out that the macros are just conveniences that are expanded into long commands and executed. For example, the long command equivalent to the {\bfseries g} macro is \starti \ii {\bfseries :grid} \endi Magic permits you to define new macros if you wish. Once you've become familiar with Magic you'll almost certainly want to add your own macros so that you can invoke quickly the commands you use most frequently. See the {\itshape magic(1)} man page under the command {\bfseries :macro}. One more long command is of immediate use to you. It is \starti \ii {\bfseries :quit} \endi Invoke this command. Note that before exiting, Magic will give you one last chance to save the information that you've modified. Type {\bfseries y} to exit without saving anything. \end{document} magic-8.0.210/doc/latexfiles/tut6.tex0000644000175000001440000003515110751423606016014 0ustar timusers%---------------------------------------------------------------------------- % Magic tutorial number 6 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Magic Tutorial \#6: Design-Rule Checking} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape John Ousterhout} \\ \vspace*{0.5in} Computer Science Division \\ Electrical Engineering and Computer Sciences \\ University of California \\ Berkeley, CA 94720 \\ \vspace*{0.25in} {\itshape (Updated by others, too.)} \\ \vspace*{0.25in} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Tutorials to read first:} \starti \> Magic Tutorial \#1: Getting Started \\ \> Magic Tutorial \#2: Basic Painting and Selection \\ \> Magic Tutorial \#4: Cell Hierarchies \endi {\noindent\bfseries\large Commands introduced in this tutorial:} \starti \> :drc \endi {\noindent\bfseries\large Macros introduced in this tutorial:} \starti \> y \endi \vspace*{0.75in} \section{Continuous Design-Rule Checking} When you are editing a layout with Magic, the system automatically checks design rules on your behalf. Every time you paint or erase, and every time you move a cell or change an array structure, Magic rechecks the area you changed to be sure you haven't violated any of the layout rules. If you do violate rules, Magic will display little white dots in the vicinity of the violation. This error paint will stay around until you fix the problem; when the violation is corrected, the error paint will go away automatically. Error paint is written to disk with your cells and will re-appear the next time the cell is read in. There is no way to get rid of it except to fix the violation. Continuous design-rule checking means that you always have an up-to-date picture of design-rule errors in your layout. There is never any need to run a massive check over the whole design unless you change your design rules. When you make small changes to an existing layout, you will find out immediately if you've introduced errors, without having to completely recheck the entire layout. To see how the checker works, run Magic on the cell {\bfseries tut6a}. This cell contains several areas of metal (blue), some of which are too close to each other or too narrow. Try painting and erasing metal to make the error paint go away and re-appear again. \section{Getting Information about Errors} In many cases, the reason for a design-rule violation will be obvious to you as soon as you see the error paint. However, Magic provides several commands for you to use to find violations and figure what's wrong in case it isn't obvious. All of the design-rule checking commands have the form \starti \ii {\bfseries :drc} {\itshape option} \endi where {\itshape option} selects one of several commands understood by the design-rule checker. If you're not sure why error paint has suddenly appeared, place the box around the error paint and invoke the command \starti \ii {\bfseries :drc why} \endi This command will recheck the area underneath the box, and print out the reasons for any violations that were found. You can also use the macro {\bfseries y} to do the same thing. Try this on some of the errors in {\bfseries tut6a}. It's a good idea to place the box right around the area of the error paint: {\bfseries :drc why} rechecks the entire area under the box, so it may take a long time if the box is very large. If you're working in a large cell, it may be hard to see the error paint. To help locate the errors, select a cell and then use the command \starti \ii {\bfseries :drc find} [{\itshape nth}] \endi If you don't provide the {\itshape nth} argument, the command will place the box around one of the errors in the selected cell, and print out the reason for the error, just as if you had typed {\bfseries :drc why}. If you invoke the command repeatedly, it will step through all of the errors in the selected cell. (remember, the ``.'' macro can be used to repeat the last long command; this will save you from having to retype {\bfseries :drc find} over and over again). Try this out on the errors in {\bfseries tut6a}. If you type a number for {\itshape nth}, the command will go to the {\itshape nth} error in the selected cell, instead of the next one. If you invoke this command with no cell selected, it searches the edit cell. A third drc command is provided to give you summary information about errors in hierarchical designs. The command is \starti \ii {\bfseries :drc count} \endi This command will search every cell (visible or not) that lies underneath the box to see if any have errors in them. For each cell with errors, {\bfseries :drc count} will print out a count of the number of error areas. \section{Errors in Hierarchical Layouts} The design-rule checker works on hierarchical layouts as well as single cells. There are three overall rules that describe the way that Magic checks hierarchical designs: \begin{enumerate} \item The paint in each cell must obey all the design rules by itself, without considering the paint in any other cells, including its children. \item The combined paint of each cell and all of its descendants (subcells, sub-subcells, etc.) must be consistent. If a subcell interacts with paint or with other subcells in a way that introduces a design-rule violation, an error will appear in the parent. In designs with many levels of hierarchy, this rule is applied separately to each cell and its descendants. \item Each array must be consistent by itself, without considering any other subcells or paint in its parent. If the neighboring elements of an array interact to produce a design-rule violation, the violation will appear in the parent. \end{enumerate} To see some examples of interaction errors, edit the cell {\bfseries tut6b}. This cell doesn't make sense electrically, but illustrates the features of the hierarchical checker. On the left are two subcells that are too close together. In addition, the subcells are too close to the red paint in the top-level cell. Move the subcells and/or modify the paint to make the errors go away and reappear. On the right side of {\bfseries tut6b} is an array whose elements interact to produce a design-rule violation. Edit an element of the array to make the violation go away. When there are interaction errors between the elements of an array, the errors always appear near one of the four corner elements of the array (since the array spacing is uniform, Magic only checks interactions near the corners; if these elements are correct, all the ones in the middle must be correct too). It's important to remember that each of the three overall rules must be satisfied independently. This may sometimes result in errors where it doesn't seem like there should be any. Edit the cell {\bfseries tut6c} for some examples of this. On the left side of the cell there is a sliver of paint in the parent that extends paint in a subcell. Although the overall design is correct, the sliver of paint in the parent is not correct by itself, as required by the first overall rule above. On the right side of {\bfseries tut6c} is an array with spacing violations between the array elements. Even though the paint in the parent masks some of the problems, the array is not consistent by itself so errors are flagged. The three overall rules are more conservative than strictly necessary, but they reduce the amount of rechecking Magic must do. For example, the array rule allows Magic to deduce the correctness of an array by looking only at the corner elements; if paint from the parent had to be considered in checking arrays, it would be necessary to check the entire array since there might be parent paint masking some errors but not all (as, for example, in {\bfseries tut6c}). Error paint appears in different cells in the hierarchy, depending on what kind of error was found. Errors resulting from paint in a single cell cause error paint to appear in that cell. Errors resulting from interactions and arrays appear in the parent of the interacting cells or array. Because of the way Magic makes interaction checks, errors can sometimes ``bubble up'' through the hierarchy and appear in multiple cells. When two cells overlap, Magic checks this area by copying all the paint in that area from both cells (and their descendants) into a buffer and then checking the buffer. Magic is unable to tell the difference between an error from one of the subcells and an error that comes about because the two subcells overlap incorrectly. This means that errors in an interaction area of a cell may also appear in the cell's parent. Fixing the error in the subcell will cause the error in the parent to go away also. \section{Turning the Checker Off} We hope that in most cases the checker will run so quickly and quietly that you hardly know it's there. However, there will probably be some situations where the checker is irksome. This section describes several ways to keep the checker out of your hair. If you're working on a cell with lots of design-rule violations the constant redisplay caused by design-rule checking may get in your way more than it helps. This is particularly true if you're in the middle of a large series of changes and don't care about design-rule violations until the changes are finished. You can stop the redisplay using the command \starti \ii {\bfseries :see no errors} \endi After this command is typed, design-rule errors will no longer be displayed on the screen. The design-rule checker will continue to run and will store error information internally, but it won't bother you by displaying it on the screen. When you're ready to see errors again, type \starti \ii {\bfseries :see errors} \endi There can also be times when it's not the redisplay that's bothersome, but the amount of CPU time the checker takes to recheck what you've changed. For example, if a large subcell is moved to overlap another large subcell, the entire overlap area will have to be rechecked, and this could take several minutes. If the prompt on the text screen is a ``]'' character, it means that the command has completed but the checker hasn't caught up yet. You can invoke new commands while the checker is running, and the checker will suspend itself long enough to process the new commands. If the checker takes too long to interrupt itself and respond to your commands, you have several options. First, you can hit the interrupt key (often \^{}C) on the keyboard. This will stop the checker immediately and wait for your next command. As soon as you issue a command or push a mouse button, the checker will start up again. To turn the checker off altogether, type the command \starti \ii {\bfseries :drc off} \endi From this point on, the checker will not run. Magic will record the areas that need rechecking but won't do the rechecks. If you save your file and quit Magic, the information about areas to recheck will be saved on disk. The next time you read in the cell, Magic will recheck those areas, unless you've still got the checker turned off. There is nothing you can do to make Magic forget about areas to recheck; {\bfseries :drc off} merely postpones the recheck operation to a later time. Once you've turned the checker off, you have two ways to make sure everything has been rechecked. The first is to type the command \starti \ii {\bfseries :drc catchup} \endi This command will run the checker and wait until everything has been rechecked and errors are completely up to date. When the command completes, the checker will still be enabled or disabled just as it was before the command. If you get tired of waiting for {\bfseries :drc catchup}, you can always hit the interrupt key to abort the command; the recheck areas will be remembered for later. To turn the checker back on permanently, invoke the command \starti \ii {\bfseries :drc on} \endi \section{Porting Layouts from Other Systems} You should not need to read this section if you've created your layout from scratch using Magic or have read it from CIF using Magic's CIF or Calma reader. However, if you are bringing into Magic a layout that was created using a different editor or an old version of Magic that didn't have continuous checking, read on. You may also need to read this section if you've changed the design rules in the technology file. In order to find out about errors in a design that wasn't created with Magic, you must force Magic to recheck everything in the design. Once this global recheck has been done, Magic will use its continuous checker to deal with any changes you make to the design; you should only need to do the global recheck once. To make the global recheck, load your design, place the box around the entire design, and type \starti \ii {\bfseries :drc check} \endi This will cause Magic to act as if the entire area under the box had just been modified: it will recheck that entire area. Furthermore, it will work its way down through the hierarchy; for every subcell found underneath the box, it will recheck that subcell over the area of the box. If you get nervous that a design-rule violation might somehow have been missed, you can use {\bfseries :drc check} to force any area to be rechecked at any time, even for cells that were created with Magic. However, this should never be necessary unless you've changed the design rules. If the number of errors in the layout ever changes because of a {\bfseries :drc check}, it is a bug in Magic and you should notify us immediately. \end{document} magic-8.0.210/doc/latexfiles/tutscm2.tex0000644000175000001440000001775510751423606016525 0ustar timusers%---------------------------------------------------------------------------- % Magic tutorial number S-2 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\=\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\q{\special{ps:(") show}\hspace*{0.6em}} \def\mytitle{Magic Tutorial \#S-2: Boxes and labels} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape Rajit Manohar} \\ \vspace*{0.5in} Department of Computer Science \\ California Institute of Technology \\ Pasadena, CA 91125 \\ \vspace*{0.25in} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Tutorials to read first:} \starti \> Magic Tutorial \#S-1: The scheme command-line interpreter \endi {\noindent\bfseries\large Commands introduced in this tutorial:} \starti \> :getbox, :box.push, :box.pop, :box.move, :label.vert, :label.horiz, \\ \> :label.rename, :label.search, :label.find-next \endi {\noindent\bfseries\large Macros introduced in this tutorial:} \starti \> {\itshape (None)} \endi \vspace*{0.25in} \section{The current box} The fundamental way scheme programs interact with magic layout is by using magic's {\bfseries box} command. For instance, \starti \ii {\bfseries (box 1 1 2 2)} \endi changes the current box to the rectangle defined by the coordinates (1,1) and (2,2) in the current edit cell. This is the standard magic {\bfseries :box} command. After moving the box to a particular position in the layout, the area can be painted, erased, selected, etc. The scheme function {\bfseries getbox} returns the current box as a list of four integers. For instance, \starti \ii {\bfseries (box 1 1 2 2)} \\ \ii {\bfseries (define x (getbox))} \endi will bind the list {\bfseries (1 1 2 2)} to variable {\bfseries x}. \section{Saving and restoring the box} If a scheme function moves the current box around, it is good practice to restore the box back to its original position. This is especially useful when writing a function that the user is likely to type on the command line. {\bfseries box.push} can be used to push a box onto the current stack of boxes. {\bfseries box.pop} restores the box to the one on the top of the box stack. The sequence \starti \ii {\bfseries (box.push (getbox))} \\ \ii {\bfseries (box 1 1 5 4)} \\ \ii {\bfseries (paint poly)} \\ \ii {\bfseries (box.pop)} \endi will paint a rectangle of polysilicon from (1,1) to (5,4), restoring the original position of the box. \section{Moving the box} Magic's built-in {\bfseries move} command is not entirely reliable. Sometimes move commands are ignored, with disastrous effects. (Think about what might happen if a move command was ignored in the middle of drawing a stack of twenty transistors . . .) The scheme function {\bfseries box.move} moves the box relative to the current position. \starti \ii {\bfseries (box.move 5 3)} \endi will move the box right 5 lambda and up 3 lambda. \section{Labelling vertical and horizontal wires} Datapaths are usually designed by designing cells for a single bit of the datapath, and then arraying those cells to obtain the complete datapath. When simulating such designs, it is usually desirable to label wires in the datapath with names like ``name0'', ``name1'', up to ``nameN.'' There are two functions that can be used to perform such a task. The function {\bfseries label.vert} returns a function that can be used as a labeller for vertically arrayed nodes. {\bfseries label.horiz} returns a function that can be used as a labeller for horizontally arrayed nodes. \starti \ii {\bfseries (define lbl (label.vert {\q}name{\q} 6)} \endi The command above defines a new function {\bfseries lbl} that can be used to generate labels beginning with {\q}name0{\q} for nodes that are vertically spaced by 6 lambda. The simplest way to use this function is to bind it to a macro as follows: \starti \ii {\bfseries (macro 1 {\q}lbl{\q})} \endi Place the box over the lowest node. Every time key ``1'' is pressed, a new label ``nameM'' is created and the box is moved up by 6 lambda. {\bfseries label.horiz} can be used in a similar fashion for labelling nodes that are horizontally arrayed. \section{Finding and renaming existing labels} The label macros provide functionality to search for all labels that match a particular string. Place the box over the region of interest. Type: \starti \ii {\bfseries (label.search {\q}label{\q})} \endi To place the box over the first occurrence of the label you searched for, type: \starti \ii {\bfseries (label.find-next)} \endi Repeatedly executing this function causes the box to move to all the labels that match the search pattern. Typically, one would bind {\bfseries label.find-next} to a macro. The command {\bfseries label.rename} can be used to rename all labels with a particular name. To use this command, place the box over the region of interest. Then type \starti \ii {\bfseries (label.rename {\q}label1{\q} {\q}label2{\q})} \endi All occurrences of label ``label1'' in the current box will be renamed to ``label2''. \section{Writing these functions} The functions discussed in this tutorial are not built-in. They are user-defined functions in the default scheme file loaded in when magic starts. As you begin to use magic with the scheme command-line interpreter, you will observe that commands for drawing paint on the screen are extremely slow. This time interval is not normally noticeable because editing is interactive. However, when one can write a scheme program to draw twenty transistors on the screen, this delay becomes noticeable. It is worthwhile to minimize the number of magic commands executed, even if this involves writing more scheme code. The {\bfseries box-pop} command has been tuned a little to not execute the {\bfseries box} command if the box would not move as a result. \bfseries \starti \> (define box.list ()) \\ \\ \> (define box.move \\ \>\> (lambda (dx dy) \\ \ii (let* ((x (getbox)) \\ \ii\> (nllx (+ dx (car x))) \\ \ii\> (nlly (+ dy (cadr x))) \\ \ii\> (nurx (+ dx (caddr x))) \\ \ii\> (nury (+ dy (cadddr x)))) \\ \ii (box nllx nlly nurx nury) \\ \ii ) \\ \>\> ) \\ \> ) \\ \\ \> (define box.=? \\ \>\> (lambda (b1 b2) \\ \ii (and (and (=? (car b1) (car b2)) (=? (cadr b1) (cadr b2))) \\ \ii\> (and (=? (caddr b1) (caddr b2)) (=? (caddr b1) (caddr b2))) \\ \ii ) \\ \>\> ) \\ \> ) \\ \\ \> (define box.push \\ \>\> (lambda (pos) \\ \ii (set! box.list (cons pos box.list)) \\ \>\> ) \\ \> ) \endi \starti \> (define box.pop \\ \>\> (lambda () \\ \ii (if (null? box.list) \\ \ii\> (echo {\q}Box list is empty{\q}) \\ \ii\> (let ((x (car box.list))) \\ \ii\>\> (begin \\ \ii\>\> (set! box.list (cdr box.list)) \\ \ii\>\> (if (box.=? x (getbox)) \#t (eval (cons 'box x))) \\ \ii\>\> ) \\ \ii\> ) \\ \ii ) \\ \>\> ) \\ \> ) \endi \end{document} magic-8.0.210/doc/latexfiles/tut8.tex0000644000175000001440000012231010751423606016010 0ustar timusers%---------------------------------------------------------------------------- % Magic tutorial number 8 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Magic Tutorial \#8: Circuit Extraction} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape Walter Scott} \\ \vspace*{0.5in} Special Studies Program \\ Lawrence Livermore National Laboratory \\ P.O. Box 808, L-270 \\ Livermore, CA 94550 \\ \vspace*{0.25in} {\itshape (Updated by others, too.)} \\ \vspace*{0.25in} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Tutorials to read first:} \starti \> Magic Tutorial \#1: Getting Started \\ \> Magic Tutorial \#2: Basic Painting and Selection \\ \> Magic Tutorial \#4: Cell Hierarchies \endi {\noindent\bfseries\large Commands introduced in this tutorial:} \starti \> :extract \endi {\noindent\bfseries\large Macros introduced in this tutorial:} \starti {\itshape (none)} \endi {\bfseries Changes since Magic version 4:} \starti \> New form of {\bfseries :extract unique} \\ \> Path length extraction with {\bfseries :extract length} \\ \> Accurate resistance extraction with {\bfseries :extresis} \\ \> Extraction of well connectivity and substrate nodes \\ \> Checking for global net connectedness in {\itshape ext2sim}~(1) \\ \> New programs: {\itshape ext2spice}~(1) and {\itshape extcheck}~(1) \\ \endi \section{Introduction} This tutorial covers the use of Magic's circuit extractor. The extractor computes from the layout the information needed to run simulation tools such as {\itshape crystal}~(1) and {\itshape esim}~(1). This information includes the sizes and shapes of transistors, and the connectivity, resistance, and parasitic capacitance of nodes. Both capacitance to substrate and several kinds of internodal coupling capacitances are extracted. Magic's extractor is both incremental and hierarchical: only part of the entire layout must be re-extracted after each change, and the structure of the extracted circuit parallels the structure of the layout being extracted. The extractor produces a separate {\bfseries .ext} file for each {\bfseries .mag} file in a hierarchical design. This is in contrast to previous extractors, such as Mextra, which produces a single {\bfseries .sim} file that represents the flattened (fully-instantiated) layout. Sections 2 through 4 introduce Magic's {\bfseries :extract} command and some of its more advanced features. Section 5 describes what information actually gets extracted, and discusses limitations and inaccuracies. Section 6 talks about extraction styles. Although the hierarchical {\itshape ext}~(5) format fully describes the circuit implemented by a layout, very few tools currently accept it. It is normally necessary to flatten the extracted circuit using one of the programs discussed in Section 7, such as {\itshape ext2sim}~(1), {\itshape ext2spice}~(1), or {\itshape extcheck}~(1). \section{Basic Extraction} You can use Magic's extractor in one of several ways. Normally it is not necessary to extract all cells in a layout. To extract only those cells that have changed since they were extracted, use: \starti \ii {\bfseries :load} {\itshape root} \\ \ii {\bfseries :extract} \endi The extractor looks for a {\bfseries .ext} file for every cell in the tree that descends from the cell {\itshape root}. The {\bfseries .ext} file is searched for in the same directory that contains the cell's {\bfseries .mag} file. Any cells that have been modified since they were last extracted, and all of their parents, are re-extracted. Cells having no {\bfseries .ext} files are also re-extracted. To try out the extractor on an example, copy all the {\bfseries tut8}{\itshape x} cells to your current directory with the following shell commands: \starti \ii {\bfseries cp \~{}cad/lib/magic/tutorial/tut8*.mag\ \ .} \endi Start magic on the cell {\bfseries tut8a} and type {\bfseries :extract}. Magic will print the name of each cell ({\bfseries tut8a}, {\bfseries tut8b}, {\bfseries tut8c}, and {\bfseries tut8d}) as it is extracted. Now type {\bfseries :extract} a second time. This time nothing gets printed, since Magic didn't have to re-extract any cells. Now delete the piece of poly labelled ``{\bfseries delete me}'' and type {\bfseries :extract} again. This time, only the cell {\bfseries tut8a} is extracted as it is the only one that changed. If you make a change to cell {\bfseries tut8b} (do it) and then extract again, both {\bfseries tut8b} and {\bfseries tut8a} will be re-extracted, since {\bfseries tut8a} is the parent of {\bfseries tut8b}. To force all cells in the subtree rooted at cell {\itshape root} to be re-extracted, use {\bfseries :extract\ all}: \starti \ii {\bfseries :load}{\itshape root} \\ \ii {\bfseries :extract all} \endi Try this also on {\bfseries tut8a}. You can also use the {\bfseries :extract} command to extract a single cell as follows: \starti \ii {\bfseries :extract cell} {\itshape name} \endi will extract just the selected (current) cell, and place the output in the file {\itshape name}. Select the cell {\bfseries tut8b} ({\bfseries tut8b{\_}0}) and type {\bfseries :extract cell differentFile} to try this out. After this command, the file {\bfseries differentFile.ext} will contain the extracted circuit for the cell {\bfseries tut8b}. The children of {\bfseries tut8b} (in this case, the single cell {\bfseries tut8d}) will not be re-extracted by this command. If more than one cell is selected, the upper-leftmost one is extracted. You should be careful about using {\bfseries :extract cell}, since even though you may only make a change to a child cell, all of its parents may have to be re-extracted. To re-extract all of the parents of the selected cell, you may use \starti \ii {\bfseries :extract parents} \endi Try this out with {\bfseries tut8b} still selected. Magic will extract only the cell {\bfseries tut8a}, since it is the only one that uses the cell {\bfseries tut8b}. To see what cells would be extracted by {\bfseries :extract parents} without actually extracting them, use \starti \ii {\bfseries :extract showparents} \endi Try this command as well. \section{Feedback: Errors and Warnings} When the extractor encounters problems, it leaves feedback in the form of stippled white rectangular areas on the screen. Each area covers the portion of the layout that caused the error. Each area also has an error message associated with it, which you can see by using the {\bfseries :feedback} command. Type {\bfseries :feedback help} while in Magic for assistance in using the {\bfseries :feedback} command. The extractor will always report extraction {\itshape errors}. These are problems in the layout that may cause the output of the extractor to be incorrect. The layout should be fixed to eliminate extraction errors before attempting to simulate the circuit; otherwise, the results of the simulation may not reflect reality. Extraction errors can come from violations of transistor rules. There are two rules about the formation of transistors: no transistor can be formed, and none can be destroyed, as a result of cell overlaps. For example, it is illegal to have poly in one cell overlap diffusion in another cell, as that would form a transistor in the parent where none was present in either child. It is also illegal to have a buried contact in one cell overlap a transistor in another, as this would destroy the transistor. Violating these transistor rules will cause design-rule violations as well as extraction errors. These errors only relate to circuit extraction: the fabricated circuit may still work; it just won't be extracted correctly. In general, it is an error for material of two types on the same plane to overlap or abut if they don't connect to each other. For example, in CMOS it is illegal for p-diffusion and n-diffusion to overlap or abut. In addition to errors, the extractor can give {\itshape warnings}. If only warnings are present, the extracted circuit can still be simulated. By default, only some types of warnings are reported and displayed as feedback. To cause all warnings to be displayed, use \starti \ii {\bfseries :extract warn all} \endi The command \starti \ii {\bfseries :extract warn} {\itshape warning} \endi may be used to enable specific warnings selectively; see below. To cause no warnings to be displayed, or to disable display of a particular {\itshape warning}, use respectively \starti \ii {\bfseries :extract warn no all} or \\ \ii {\bfseries :extract warn no} {\itshape warning} \endi Three different kinds of warnings are generated. The {\bfseries dup} warning checks to see whether you have two electrically unconnected nodes in the same cell labelled with the same name. If so, you are warned because the two unconnected nodes will appear to be connected in the resulting {\bfseries .ext} file, which means that the extracted circuit would not represent the actual layout. This is bad if you're simulating the circuit to see if it will work correctly: the simulator will think the two nodes are connected, but since there's no physical wire between them, the electrons won't! When two unconnected nodes share the same label (name), the extractor leaves feedback squares over each instance of the shared name. It's an excellent idea to avoid labelling two unconnected nodes with the same name within a cell. Instead, use the "correct" name for one of the nodes, and some mnemonic but textually distinct name for the other nodes. For example, in a cell with multiple power rails, you might use {\bfseries Vdd!} for one of the rails, and names like {\bfseries Vdd\#1} for the others. As an example, load the cell {\bfseries tut8e}. If the two nodes are connected in a higher-level cell they will eventually be merged when the extracted circuit is flattened. If you want to simulate a cell out of context, but still want the higher-level nodes to be hooked up, you can always create a dummy parent cell that hooks them together, either with wire or by using the same name for pieces of paint that lie over the terminals to be connected; see the cell {\bfseries tut8f} for an example of this latter technique. You can use the command \starti \ii {\bfseries :extract unique} \endi as an automatic means of labelling nodes in the manner described above. Run this command on the cell {\bfseries tut8g}. A second version of this command is provided for compatibility with previous versions of Magic. Running \starti \ii {\bfseries :extract unique \#} \endi will only append a unique numeric suffix to labels that end with a ``{\bfseries \#}''. Any other duplicate nodenames that also don't end in a ``{\bfseries !}'' (the global nodename suffix as described in Section 5) are flagged by feedback. A second type of warning, {\bfseries fets}, checks to see whether any transistors have fewer diffusion terminals than the minimum for their types. For example, the transistor type ``{\bfseries dfet}'' is defined in the {\bfseries nmos} technology file as requiring two diffusion terminals: a source and a drain. If a capacitor with only one diffusion terminal is desired in this technology, the type {\bfseries dcap} should be used instead. The {\bfseries fets} warning is a consistency check for transistors whose diffusion terminals have been accidentally shorted together, or for transistors with insufficiently many diffusion terminals. The third warning, {\bfseries labels}, is generated if you violate the following guideline for placement of labels: Whenever geometry from two subcells abuts or overlaps, it's a good idea to make sure that there is a label attached to the geometry in each subcell {\itshape in the area of the overlap or along the line of abutment}. Following this guideline isn't necessary for the extractor to work, but it will result in noticeably faster extraction. By default, the {\bfseries dup} and {\bfseries fets} warnings are enabled, and the {\bfseries labels} warning is disabled. Load the cell {\bfseries tut8h}, expand all its children ({\bfseries tut8i} and {\bfseries tut8j}), and enable all extractor warnings with {\bfseries :extract warn all}. Now extract {\bfseries tut8h} and all of its children with {\bfseries :extract}, and examine the feedback for examples of fatal errors and warnings. \section{Advanced Circuit Extraction} \subsection{Lengths} The Magic extractor has a rudimentary ability to compute wire lengths between specific named points in a circuit. This feature is intended for use with technologies where the wire length between two points is more important than the total capacitance on the net; this may occur, for example, when extracting circuits with very long wires being driven at high speeds ({\itshape e.g.}, bipolar circuits). Currently, you must indicate to Magic which pairs of points are to have distances computed. You do this by providing two lists: one of {\itshape drivers} and one of {\itshape receivers}. The extractor computes the distance between each driver and each receiver that it is connected to. Load the cell {\bfseries tut8k}. There are five labels: two are drivers ({\bfseries driver1} and {\bfseries driver2}) and three are receivers ({\bfseries receiverA}, {\bfseries receiverB}, and {\bfseries receiverC}). Type the commands: \starti \ii {\bfseries :extract length driver driver1 driver2} \\ \ii {\bfseries :extract length receiver receiverA receiverB receiverC} \endi Now enable extraction of lengths with {\bfseries :extract do length} and then extract the cell ({\bfseries :extract}). If you examine {\bfseries tut8k.ext}, you will see several {\bfseries distance} lines, corresponding to the driver-receiver distances described above. These distances are through the centerlines of wires connecting the two labels; where multiple paths exist, the shortest is used. Normally the driver and receiver tables will be built by using {\bfseries :source} to read a file of {\bfseries :extract length driver} and {\bfseries :extract length receiver} commands. Once these tables are created in Magic, they remain until you leave Magic or type the command \starti \ii {\bfseries :extract length clear} \endi which wipes out both tables. Because extraction of wire lengths is {\itshape not} performed hierarchically, it should only be done in the root cell of a design. Also, because it's not hierarchical, it can take a long time for long, complex wires such as power and ground nets. This feature is still experimental and subject to change. \subsection{Resistance} Magic provides for more accurate resistance extraction using the {\bfseries :extresis }command. {\bfseries :extresis} provides a detailed resistance/capacitance description for nets where parasitic resistance is likely to significantly affect circuit timing. \subsubsection{Tutorial Introduction} To try out the resistance extractor, load in the cell {\bfseries tut8r}. Extract it using {\bfseries :extract}, pause magic, and run ext2sim on the cell with the command \starti \ii {\bfseries ext2sim tut8r} \endi This should produce {\bfseries tut8r.sim}, {\bfseries tut8r.nodes}, and {\bfseries tut8r.al}. Restart magic and type \starti \ii {\bfseries :extresis tolerance 10} \\ \ii {\bfseries :extresis} \endi This will extract interconnect resistances for any net where the interconnect delay is at least one-tenth of the transistor delay. Magic should give the messages: \starti \ii {\bfseries :extresis tolerance 10} \\ \ii {\bfseries :extresis} \\ \ii {\bfseries Adding net2; Tnew = 0.428038ns,Told = 0.3798ns} \\ \ii {\bfseries Adding net1; Tnew = 0.529005ns,Told = 0.4122ns} \\ \ii {\bfseries Total Nets: 7} \\ \ii {\bfseries Nets extracted: 2 (0.285714)} \\ \ii {\bfseries Nets output: 2 (0.285714)} \endi These may vary slightly depending on your technology parameters. The {\bfseries Adding [net]} lines describe which networks for which magic produced resistor networks. {\bfseries Tnew} is the estimated delay on the net including the resistor parasitics, while {\bfseries Told} is the delay without parasitics. The next line describes where magic thinks the slowest node in the net is. The final 3 lines give a brief summary of the total number of nets, the nets requiring extraction, and the number for which resistors were added to the output. Running the resistance extractor also produced the file {\bfseries cell.res.ext}. To produce a {\bfseries .sim} file containing resistors, quit magic and type: \starti \ii {\bfseries cat tut8r.ext tut8r.res.ext $>$tut8r.2.ext} \\ \ii {\bfseries ext2sim -R -t! -t\# tut8r.2} \endi Comparing the two files, {\bfseries tut8r.sim} and {\bfseries tut8r.2.sim}, shows that the latter has the nodes net1 and net2 split into several parts, with resistors added to connect the new nodes together. \subsubsection{General Notes on using the resistance extractor} To use {\bfseries :extresis}, the circuit must first be extracted using {\bfseries :extract} and flattened using ext2sim. When ext2sim is run, do not use the {\bfseries -t\#} and {\bfseries -t!} flags (i.e. don't trim the trailing "\#" and "!" characters) or the {\bfseries -R} flag because {\bfseries :extresis} needs the {\bfseries .sim} and {\bfseries .ext} names to correspond exactly, and it needs the lumped resistance values that the extractor produces. Also, do not delete or rename the {\bfseries .nodes} file; {\bfseries :extresis} needs this to run. Once the {\bfseries .sim} and {\bfseries .nodes} files have been produced, type the command {\bfseries :extresis} while running magic on the root cell. As the resistance extractor runs, it will identify which nets (if any) for which it is producing RC networks, and will identify what it thinks is the "slowest" point in the network. When it completes, it will print a brief summary of how many nets it extracted and how many required supplemental networks. The resistance networks are placed in the file {\bfseries root.res.ext}. To produce a {\bfseries .sim} file with the supplemental resistors, type {\bfseries cat root.ext root.res.ext $>$newname.ext}, and then rerun {\bfseries ext2sim} on the new file. During this second {\bfseries ext2sim} run, the {\bfseries -t} flag may be used. Like extraction of wire lengths, resistance extraction is {\itshape not} performed hierarchically; it should only be done in the root cell of a design and can take a long time for complex wires. \subsubsection{Options, Features, Caveats and Bugs} The following is a list of command line options and the arguments that they take. \begin{itemize} \item {\bfseries tolerance [value]} \\ This controls how large the resistance in a network must be before it is added to the output description. {\bfseries value} is defined as the minimum ratio of transistor resistance to interconnect resistance that requires a resistance network. The default value is 1; values less than 1 will cause fewer resistors to be output and will make the program run faster, while values greater than 1 will produce more a larger, more accurate description but will run slower. \item {\bfseries all} \\ Causes all nets in the circuit to be extracted; no comparison between transistor size and lumped resistance is performed. This option is not recommended for large designs. \item {\bfseries simplify [on/off]} \\ Turns on/off the resistance network simplification routines. Magic normally simplifies the resistance network it extracts by removing small resistors; specifying this flag turns this feature off. \item {\bfseries extout [on/off]} \\ Turns on and off the writing of the {\ttfamily root.res.ext} file. The default value is on. \item {\bfseries lumped [on/off]} \\ Turns on the writing of {\ttfamily root.res.lump}. This file contains an updated value of the lumped resistance for each net that {\bfseries :extresis} extracts. \item {\bfseries silent [on/off]} \\ This option suppresses printing of the name and location of nets for which resistors are produced. \item {\bfseries skip mask} \\ Specifies a list of layers that the resistance extractor is to ignore. \item {\bfseries help} \\ Print brief list of options. \end{itemize} Attribute labels may also be used to specify certain extractor options. For a description of attributes and how they work, see tutorial 2. Following is a description of {\bfseries :extresis} attributes. \begin{itemize} \item {\bfseries res:skip@} \\ Causes this net to be skipped. This is useful for avoiding extraction of power supplies or other DC signals that are not labeled Vdd or GND. \item {\bfseries res:force@} \\ Forces extraction of this net regardless of its lumped resistance value. Nets with both skip and force labels attached will cause the extractor to complain. \item {\bfseries res:min=[value]@} \\ Sets the smallest resistor size for this net. The default value is the resistance of the largest driving transistor divided by the tolerance described above. \item {\bfseries res:drive@} - Nets with no driving transistors will normally not be extracted. This option allows the designer to specify from where in the net the signal is driven. This is primarily useful when extracting subcells, where the transistors driving a given signal may be located in a different cell. \end{itemize} \subsubsection{Technology File Changes} Certain changes must be made in the extract section of the technology file to support resistance extraction. These include the {\bfseries fetresist} and {\bfseries contact} lines, plus a small change to the fet line. Full details can be found in Magic Maintainer's Manual \#2. The only thing to note is that, contrary to the documentation, the {\bfseries gccap} and {\bfseries gscap} parts of the fet line MUST be set; the resistance extractor uses them to calculate RC time constants for the circuit. \section{Extraction Details and Limitations} This section explores in greater depth what gets extracted by Magic, as well as the limitations of the circuit extractor. A detailed explanation of the format of the {\bfseries .ext} files output by Magic may be found in the manual page {\itshape ext}~(5). ``Magic Maintainer's Manual\ \#2: The Technology File'' describes how extraction parameters are specified for the extractor. \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/tut8.1.ps, width=0.33\columnwidth} \caption{Each node extracted by Magic has a lumped resistance {\itshape R} and a lumped capacitance {\itshape C} to the substrate. These lumped values can be interpreted as in the diagram above, in which each device connected to the node is attached to one of the points {\itshape 1}, {\itshape 2}, \dots, {\itshape N}.} \end{center} \end{figure} \subsection{Nodes} Magic approximates the pieces of interconnect between transistors as ``nodes''. A node is like an equipotential region, but also includes a lumped resistance and capacitance to substrate. Figure 1 shows how these lumped values are intended to be interpreted by the analysis programs that use the extracted circuit. Each node in an extracted circuit has a name, which is either one of the labels attached to the geometry in the node if any exist, or automatically generated by the extractor. These latter names are always of the form {\itshape p{\_}x{\_}y\#}, where {\itshape p}, {\itshape x}, and {\itshape y} are integers, {\itshape e.g.}, {\bfseries 3{\_}104{\_}17\#}. If a label ending in the character ``{\bfseries !}'' is attached to a node, the node is considered to be a ``global''. Post-processing programs such as {\itshape ext2sim}~(1) will check to ensure that nodes in different cells that are labelled with the same global name are electrically connected. Nodes may have attributes attached to them as well as names. Node attributes are labels ending in the special character ``{\bfseries @}'', and provide a mechanism for passing information to analysis programs such as {\itshape crystal}~(1). The man page {\itshape ext}~(5) provides additional information about node attributes. \subsection{Resistance} Magic extracts a lumped resistance for each node, rather than a point-to-point resistance between each pair of devices connected to that node. The result is that all such point-to-point resistances are approximated by the worst-case resistance between any two points in that node. By default, node resistances are approximated rather than computed exactly. For a node comprised entirely of a single type of material, Magic will compute the node's total perimeter and area. It then solves a quadratic equation to find the width and height of a simple rectangle with this same perimeter and area, and approximates the resistance of the node as the resistance of this ``equivalent'' rectangle. The resistance is always taken in the longer dimension of the rectangle. When a node contains more than a single type of material, Magic computes an equivalent rectangle for each type, and then sums the resistances as though the rectangles were laid end-to-end. This approximation for resistance does not take into account any branching, so it can be significantly in error for nodes that have side branches. Figure 2 gives an example. For global signal trees such as clocks or power, Magic's estimate of resistance will likely be several times higher than the actual resistance between two points. \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/tut8.2.ps, width=0.8\columnwidth} \caption{Magic approximates the resistance of a node by assuming that it is a simple wire. The length and width of the wire are estimated from the node's perimeter and area. (a) For non-branching nodes, this approximation is a good one. (b) The computed resistance for this node is the same as for (a) because the side branches are counted, yet the actual resistance between points 1 and 2 is significantly less than in (a).} \end{center} \end{figure} The approximated resistance also does not lend itself well to hierarchical adjustments, as does capacitance. To allow programs like {\bfseries ext2sim} to incorporate hierarchical adjustments into a resistance approximation, each node in the {\bfseries .ext} file also contains a perimeter and area for each ``resistance class'' that was defined in the technology file (see ``Maintainer's Manual \#2: The Technology File,'' and {\itshape ext}~(5)). When flattening a circuit, {\bfseries ext2sim} uses this information along with adjustments to perimeter and area to produce the value it actually uses for node resistance. If you wish to disable the extraction of resistances and node perimeters and areas, use the command \starti \ii {\bfseries :extract no resistance} \endi which will cause all node resistances, perimeters, and areas in the {\bfseries .ext} file to be zero. To re-enable extraction of resistance, use the command \starti \ii {\bfseries :extract do resistance}. \endi Sometimes it's important that resistances be computed more accurately than is possible using the lumped approximation above. Magic's {\bfseries :extresist} command does this by computing explicit two-terminal resistors and modifying the circuit network to include them so it reflects more exactly the topology of the layout. See the section on {\bfseries Advanced Extraction} for more details on explicit resistance extraction with {\bfseries :extresist}. \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/tut8.3.ps, width=0.5\columnwidth} \caption{Each type of edge has capacitance to substrate per unit length. Here, the diffusion-space perimeter of 13 units has one value per unit length, and the diffusion-buried perimeter of 3 units another. In addition, each type of material has capacitance per unit area.} \end{center} \end{figure} \subsection{Capacitance} Capacitance to substrate comes from two different sources. Each type of material has a capacitance to substrate per unit area. Each type of edge (i.e, each pair of types) has a capacitance to substrate per unit length. See Figure 3. The computation of capacitance may be disabled with \starti \ii {\bfseries :extract no capacitance} \endi which causes all substrate capacitance values in the {\bfseries .ext} file to be zero. It may be re-enabled with \starti \ii {\bfseries :extract do capacitance}. \endi Internodal capacitance comes from three sources, as shown in Figure 4. When materials of two different types overlap, the capacitance to substrate of the one on top (as determined by the technology) is replaced by an internodal capacitance to the one on the bottom. Its computation may be disabled with \starti \ii {\bfseries :extract no coupling} \endi which will also cause the extractor to run 30\% to 50\% faster. Extraction of coupling capacitances can be re-enabled with \starti \ii {\bfseries :extract do coupling}. \endi \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/tut8.4.ps, width=0.75\columnwidth} \caption{Magic extracts three kinds of internodal coupling capacitance. This figure is a cross-section (side view, not a top view) of a set of masks that shows all three kinds of capacitance. {\itshape Overlap} capacitance is parallel-plate capacitance between two different kinds of material when they overlap. {\itshape Sidewall} capacitance is parallel-plate capacitance between the vertical edges of two pieces of the same kind of material. {\itshape Sidewall overlap} capacitance is orthogonal-plate capacitance between the vertical edge of one piece of material and the horizontal surface of another piece of material that overlaps the first edge.} \end{center} \end{figure} \begin{figure}[ht] \begin{center} \epsfig{file=../psfigures/tut8.5.ps, width=0.75\columnwidth} \caption{ (a) When transistors are rectangular, it is possible to compute $L / W$ exactly. Here {\itshape gateperim}$=4$, {\itshape srcperim}$=6$, {\itshape drainperim}$=6$, and $L/W = 2/6$. (b) The $L/W$ of non-branching transistors can be approximated. Here {\itshape gateperim}$=4$, {\itshape srcperim}$=6$, {\itshape drainperim}$=10$. By averaging {\itshape srcperim} and {\itshape drainperim} we get $L/W = 2/8$. (c) The $L/W$ of branching transistors is not well approximated. Here {\itshape gateperim}$=16$, {\itshape srcperim}$=2$, {\itshape drainperim}$=2$. Magic's estimate of $L/W$ is $8/2$, whereas in fact because of current spreading, $W$ is effectively larger than $2$ and $L$ effectively smaller than $8$, so $L/W$ is overestimated.} \end{center} \end{figure} Whenever material from two subcells overlaps or abuts, the extractor computes adjustments to substrate capacitance, coupling capacitance, and node perimeter and area. Often, these adjustments make little difference to the type of analysis you are performing, as when you wish only to compare netlists. Even when running Crystal for timing analysis, the adjustments can make less than a 5\% difference in the timing of critical paths in designs with only a small amount of inter-cell overlap. To disable the computation of these adjustments, use \starti \ii {\bfseries :extract no adjustment} \endi which will result in approximately 50\% faster extraction. This speedup is not entirely additive with the speedup resulting from {\bfseries :extract no coupling}. To re-enable computation of adjustments, use {\bfseries :extract do adjustment}. \subsection{Transistors} Like the resistances of nodes, the lengths and widths of transistors are approximated. Magic computes the contribution to the total perimeter by each of the terminals of the transistor. See Figure 5. For rectangular transistors, this yields an exact \$L / W\$. For non-branching, non-rectangular transistors, it is still possible to approximate \$L / W\$ fairly well, but substantial inaccuracies can be introduced if the channel of a transistor contains branches. Since most transistors are rectangular, however, Magic's approximation works well in practice. \begin{table}[ht] \begin{center} \begin{tabular}{|ccccccc|} \hline Type & Loc & A P & Subs & Gate & Source & Drain \\ \hline fet nfet & 59 1 60 2 & 8 12 & GND! & Mid2 4 {\bfseries N3} & Out 4 0 & Vss\#0 4 0 \\ fet nfet & 36 1 37 2 & 8 12 & Float & Mid1 4 {\bfseries N2} & Mid2 4 0 & Vss\#0 4 0 \\ fet nfet & 4 1 5 2 & 8 12 & Vss\#0 & In 4 {\bfseries N1} & Mid1 4 0 & Vss\#0 4 0 \\ fet pfet & 59 25 60 26 & 8 12 & Vdd! & Mid2 4 {\bfseries P3} & Vdd\#0 4 0 & Out 4 0 \\ fet pfet & 36 25 37 26 & 8 12 & VBias & Mid1 4 {\bfseries P2} & Vdd\#0 4 0 & Mid2 4 0 \\ fet pfet & 4 25 5 26 & 8 12 & Vdd\#0 & In 4 {\bfseries P1} & Vdd\#0 4 0 & Mid1 4 0 \\ \hline \end{tabular} \caption{The transistor section of {\bfseries tut8l.ext}.} \end{center} \end{table} In addition to having gate, source, and drain terminals, MOSFET transistors also have a substrate terminal. By default, this terminal is connected to a global node that depends on the transistor's type. For example, p-channel transistors might have a substrate terminal of {\bfseries Vdd!}, while n-channel transistors would have one of {\bfseries GND!}. However, when a transistor is surrounded by explicit ``well'' material (as defined in the technology file), Magic will override the default substrate terminal with the node to which the well material is connected. This has several advantages: it allows simulation of analog circuits in which wells are biased to different potentials, and it provides a form of checking to ensure that wells in a CMOS process are explicitly tied to the appropriate DC voltage. Transistor substrate nodes are discovered by the extractor only if the transistor and the overlapping well layer are in the same cell. If they appear in different cells, the transistor's substrate terminal will be set to the default for the type of transistor. Load the cell {\bfseries tut8l}, extract it, and look at the file {\bfseries tut8l.ext}. Table 1 shows the lines for the six transistors in the file. You'll notice that the substrate terminals (the {\itshape Subs} column) for all transistors are different. Since each transistor in this design has a different gate attribute attached to it (shown in bold in the table, {\itshape e.g.}, {\bfseries N1}, {\bfseries P2}, etc), we'll use them in the following discussion. The simplest two transistors are {\bfseries N3} and {\bfseries P3}, which don't appear in any explicitly drawn wells. The substrate terminals for these are {\bfseries GND!} and {\bfseries Vdd!} respectively, since that's what the technology file says is the default for the two types of transistors. {\bfseries N1} and {\bfseries P1} are standard transistors that lie in wells tied to the ground and power rails, labelled in this cell as {\bfseries Vss\#0} and {\bfseries Vdd\#0} respectively. (They're not labelled {\bfseries GND!} and {\bfseries Vdd!} so you'll see the difference between {\bfseries N1} and {\bfseries N3}). {\bfseries P2} lies in a well that is tied to a different bias voltage, {\bfseries VBias}, such as might occur in an analog design. Finally, {\bfseries N2} is in a well that isn't tied to any wire. The substrate node appears as {\bfseries Float} because that's the label that was attached to the well surrounding {\bfseries N2}. The ability to extract transistor substrate nodes allows you to perform a simple check for whether or not transistors are in properly connected ({\itshape e.g.}, grounded) wells. In a p-well CMOS process, for example, you might set the default substrate node for n-channel transistors to be some distinguished global node other than ground, {\itshape e.g.}, {\bfseries NSubstrateNode!}. You could then extract the circuit, flatten it using {\itshape ext2spice}~(1) (which preserves substrate nodes, unlike {\itshape ext2sim}~(1) which ignores them), and look at the substrate node fields of all the n-channel transistors: if there were any whose substrate nodes weren't connected to {\bfseries GND!}, then these transistors appear either outside of any explicit well (their substrate nodes will be the default of {\bfseries NSubstrateNode}), or in a well that isn't tied to {\bfseries GND!} with a substrate contact. \section{Extraction styles} Magic usually knows several different ways to extract a circuit from a given layout. Each of these ways is called a {\itshape style}. Different styles can be used to handle different fabrication facilities, which may differ in the parameters they have for parasitic capacitance and resistance. For a scalable technology, such as the default {\bfseries scmos}, there can be a different extraction style for each scale factor. The exact number and nature of the extraction styles is described in the technology file that Magic reads when it starts. At any given time, there is one current extraction style. To print a list of the extraction styles available, type the command \starti \ii {\bfseries :extract style}. \endi The {\bfseries scmos} technology currently has the styles {\bfseries lambda=1.5}, {\bfseries lambda=1.0}, and {\bfseries lambda=0.6}, though this changes over time as technology evolves. To change the extraction style to {\itshape style}, use the command \starti \ii {\bfseries :extract style}{\itshape style} \endi Each style has a specific scale factor between Magic units and physical units ({\itshape e.g.}, microns); you can't use a particular style with a different scale factor. To change the scalefactor, you'll have to edit the appropriate style in the {\bfseries extract} section of the technology file. This process is described in ``Magic Maintainer's Manual \#2: The Technology File.'' \section{Flattening Extracted Circuits} Unfortunately, very few tools exist to take advantage of the {\itshape ext}~(5) format files produced by Magic's extractor. To use these files for simulation or timing analysis, you will most likely need to convert them to a flattened format, such as {\itshape sim}~(5) or {\itshape spice}~(5). There are several programs for flattening {\itshape ext}~(5) files. {\itshape Ext2sim}~(1) produces {\itshape sim}~(5) files suitable for use with {\itshape crystal}~(1), {\itshape esim}~(1), or {\itshape rsim}~(1). {\itshape Ext2spice}~(1) is used to produce {\itshape spice}~(5) files for use with the circuit-level simulator {\itshape spice}~(1). Finally, {\itshape extcheck}~(1) can be used to perform connectivity checking and will summarize the number of flattened nodes, transistors, capacitors, and resistors in a circuit. All of these programs make use of a library known as {\itshape extflat}~(3), so the conventions for each and the checks they perform are virtually identical. The documentation for {\itshape extcheck} covers the options common to all of these programs. To see how {\itshape ext2sim} works, load the cell {\bfseries tut8n} and expand all the {\bfseries tutm} subcells. Notice how the {\bfseries GND!} bus is completely wired, but the {\bfseries Vdd!} bus is in three disconnected pieces. Now extract everything with {\bfseries :extract}, then exit Magic and run {\bfseries ext2sim tut8n}. You'll see the following sort of output: \ttfamily \starti \> *** Global name Vdd! not fully connected: \\ \> One portion contains the names: \\ \> \> left/Vdd! \\ \> The other portion contains the names: \\ \> \> center/Vdd! \\ \> I'm merging the two pieces into a single node, but you \\ \> should be sure eventually to connect them in the layout. \\ \\ \> *** Global name Vdd! not fully connected: \\ \> One portion contains the names: \\ \> \> left/Vdd! \\ \> \> center/Vdd! \\ \> The other portion contains the names: \\ \> \> right/Vdd! \\ \> I'm merging the two pieces into a single node, but you \\ \> should be sure eventually to connect them in the layout. \\ \\ \> Memory used: 56k \endi \rmfamily The warning messages are telling you that the global name {\bfseries Vdd!} isn't completely wired in the layout. The flattener warns you, but goes ahead and connects the pieces together anyway to allow you to simulate the circuit as though it had been completely wired. The output of {\itshape ext2sim} will be three files: {\bfseries tut8n.sim}, {\bfseries tut8n.al}, and {\bfseries tut8n.nodes}; see {\itshape ext2sim}~(1) or {\itshape sim}~(5) for more information on the contents of these files. ``{\bfseries Magic Tutorial \#11: Using RSIM with Magic}'' explains how to use the output of {\itshape ext2sim} with the switch-level simulator, {\itshape rsim}~(1). \end{document} magic-8.0.210/doc/latexfiles/tuttcl2.tex0000644000175000001440000000343410751423606016512 0ustar timusers%---------------------------------------------------------------------------- % Magic Tcl tutorial number 2 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ig{\>} \def\ih{\>\>} \def\ii{\>\>\>} \def\mytitle{Magic Tcl Tutorial \#2: The Wrapper GUI} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape R. Timothy Edwards} \\ \vspace*{0.5in} Space Department \\ Johns Hopkins University \\ Applied Physics Laboratory \\ Laurel, MD 20723 \\ \vspace*{0.25in} This tutorial corresponds to Tcl-based Magic version 7.2 \\ \end{center} \vspace*{0.5in} \section{The Wrapper GUI} \end{document} magic-8.0.210/doc/latexfiles/tut2.tex0000644000175000001440000011271510751423606016012 0ustar timusers%---------------------------------------------------------------------------- % Magic tutorial number 2 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Magic Tutorial \#2: Basic Painting and Selection} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape John Ousterhout} \\ \vspace*{0.5in} Computer Science Division \\ Electrical Engineering and Computer Sciences \\ University of California \\ Berkeley, CA 94720 \\ \vspace*{0.25in} {\itshape (Updated by others, too.)} \\ \vspace*{0.25in} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Tutorials to read first:} \starti \> Magic Tutorial \#1: Getting Started \endi {\noindent\bfseries\large Commands introduced in this tutorial:} \starti \> :box, :clockwise, :copy, :erase, :findbox :grid, :label, \\ \> :layers, :macro, :move, :paint, :redo, :save, :select, \\ \>:sideways, :undo, :upsidedown, :view, :what, :writeall, :zoom \endi {\noindent\bfseries\large Macros introduced in this tutorial:} \starti \> a, A, c, d, \^{}D, e, E, g, G, q, Q, r, R, s, S, t, T, u, U, v, w, W, z, Z, 4 \endi \vspace*{0.75in} \section{Cells and Paint} In Magic, a circuit layout is a hierarchical collection of {\itshape cells}. Each cell contains three things: colored shapes, called {\itshape paint}, that define the circuit's structure; textual {\itshape labels} attached to the paint; and {\itshape subcells}, which are instances of other cells. The paint is what determines the eventual function of the VLSI circuit. Labels and subcells are a convenience for you in managing the layout and provide a way of communicating information between various synthesis and analysis tools. This tutorial explains how to create and edit paint and labels in simple single-cell designs, using the basic painting commands. ``Magic Tutorial \#3: Advanced Painting (Wiring and Plowing)'' describes some more advanced features for manipulating paint. For information on how to build up cell hierarchies, see ``Magic Tutorial \#4: Cell Hierarchies''. \section{Painting and Erasing} Enter Magic to edit the cell {\bfseries tut2a} (type {\bfseries magic tut2a} to the Unix shell; follow the directions in ``Tutorial \#1: Getting Started'' if you have any problems with this). The {\bfseries tut2a} cell is a sort of palette: it shows a splotch of each of several paint layers and gives the names that Magic uses for the layers. The two basic layout operations are painting and erasing. They can be invoked using the {\bfseries :paint} and {\bfseries :erase} long commands, or using the buttons. The easiest way to paint and erase is with the mouse buttons. To paint, position the box over the area you'd like to paint, then move the cursor over a color and click the middle mouse button. To erase everything in an area, place the box over the area, move the cursor over a blank spot, and click the middle mouse button. Try painting and erasing various colors. If the screen gets totally messed up, you can always exit Magic and restart it. While you're painting, white dots may occasionally appear and disappear. These are design rule violations detected by Magic, and will be explained in ``Magic Tutorial \#6: Design Rule Checking''. You can ignore them for now. It's completely legal to paint one layer on top of another. When this happens, one of three things may occur. In some cases, the layers are independent, so what you'll see is a combination of the two, as if each were a transparent colored foil. This happens, for example, if you paint metal1 (blue) on top of polysilicon (red). In other cases, when you paint one layer on top of another you'll get something different from either of the two original layers. For example, painting poly on top of ndiff produces ntransistor (try this). In still other cases the new layer replaces the old one: this happens, for example, if you paint a pcontact on top of ntransistor. Try painting different layers on top of each other to see what happens. The meaning of the various layers is discussed in more detail in Section 11 below. There is a second way of erasing paint that allows you to erase some layers without affecting others. This is the macro {\bfseries \^{}D} (control-D, for ``{\bfseries D}elete paint''). To use it, position the box over the area to be erased, then move the crosshair over a splotch of paint containing the layer(s) you'd like to erase. Type {\bfseries \^{}D} key on the text keyboard: the colors underneath the cursor will be erased from the area underneath the box, but no other layers will be affected. Experiment around with the {\bfseries \^{}D} macro to try different combinations of paints and erases. If the cursor is over empty space then the {\bfseries \^{}D} macro is equivalent to the middle mouse button: it erases everything. You can also paint and erase using the long commands \starti \ii {\bfseries :paint} {\itshape layers} \\ \ii {\bfseries :erase} {\itshape layers} \endi In each of these commands {\itshape layers} is one or more layer names separated by commas (you can also use spaces for separators, but only if you enclose the entire list in double-quotes). Any layer can be abbreviated as long as the abbreviation is unambiguous. For example, {\bfseries :paint poly,metal1} will paint the polysilicon and metal1 layers. The macro {\bfseries \^{}D} is predefined by Magic to be {\bfseries :erase \$} ({\bfseries \$} is a pseudo-layer that means ``all layers underneath the cursor''). \section{Undo} There are probably going to be times when you'll do things that you'll later wish you hadn't. Fortunately, Magic has an undo facility that you can use to restore things after you've made mistakes. The command \starti \ii {\bfseries :undo} \endi (or, alternatively, the macro {\bfseries u}) will undo the effects of the last command you invoked. If you made a mistake several commands back, you can type {\bfseries :undo} several times to undo successive commands. However, there is a limit to all this: Magic only remembers how to undo the last ten or so commands. If you undo something and then decide you wanted it after all, you can undo the undo with the command \starti \ii {\bfseries :redo} \endi ({\bfseries U} is a macro for this command). Try making a few paints and erases, then use {\bfseries :undo} and {\bfseries :redo} to work backwards and forwards through the changes you made. \section{The Selection} Once you have painted a piece of layout, there are several commands you can invoke to modify the layout. Many of them are based on the {\itshape selection}: you select one or more pieces of the design, and then perform operations such as copying, deletion, and rotation on the selected things. To see how the selection works, load cell {\bfseries tut2b}. You can do this by typing {\bfseries :load tut2b} if you're still in Magic, or by starting up Magic with the shell command {\bfseries magic tut2b}. The first thing to do is to learn how to select. Move the cursor over the upper portion of the L-shaped blue area in {\bfseries tut2b}, and type {\bfseries s}, which is a macro for {\bfseries :select}. The box will jump over to cover the vertical part of the ``L''. This operation selected a chunk of material. Move the box away from the chunk, and you'll see that a thin white outline is left around the chunk to show that it's selected. Now move the cursor over the vertical red bar on the right of the cell and type {\bfseries s}. The box will move over that bar, and the selection highlighting will disappear from the blue area. If you type {\bfseries s} several times without moving the cursor, each command selects a slightly larger piece of material. Move the cursor back over the top of the blue ``L'', and type {\bfseries s} three times without moving the cursor. The first {\bfseries s} selects a chunk (a rectangular region all of the same type of material). The second {\bfseries s} selects a {\itshape region} (all of the blue material in the region underneath the cursor, rectangular or not). The third {\bfseries s} selects a {\itshape net} (all of the material that is electrically connected to the original chunk; this includes the blue metal, the red polysilicon, and the contact that connects them). The macro {\bfseries S} (short for {\bfseries :select more}) is just like {\bfseries s} except that it adds on to the selection, rather than replacing it. Move the cursor over the vertical red bar on the right and type {\bfseries S} to see how this works. You can also type {\bfseries S} multiple times to add regions and nets to the selection. If you accidentally type {\bfseries s} or {\bfseries S} when the cursor is over space, you'll select a cell ({\bfseries tut2b} in this case). You can just undo this for now. Cell selection will be discussed in ``Magic Tutorial \#4: Cell Hierarchies''. You can also select material by area: place the box around the material you'd like to select and type {\bfseries a} (short for {\bfseries :select area}). This will select all of the material underneath the box. You can use the macro {\bfseries A} to add material to the selection by area, and you can use the long command \starti \ii {\bfseries :select }[{\bfseries more}]{\bfseries area} {\itshape layers} \endi to select only material on certain layers. Place the box around everything in {\bfseries tut2b} and type {\bfseries :select area metal1} followed by {\bfseries :select more area poly}. If you'd like to clear out the selection without modifying any of the selected material, you can use the command \starti \ii {\bfseries :select clear} \endi or type the macro {\bfseries C}. You can clear out just a portion of the selection by typing {\bfseries :select less} or {\bfseries :select less area} {\itshape layers}; the former deselects paint in the order that {\bfseries :select} selects paint, while the latter deselects paint under the box (just as {\bfseries :select area} selects paint under the box). For a synopsis of all the options to the {\bfseries :select} command, type \starti \ii {\bfseries :select help} \endi \section{Operations on the Selection} Once you've made a selection, there are a number of operations you can perform on it: \starti \ii {\bfseries :delete} \\ \ii {\bfseries :move }[{\itshape direction} [{\itshape distance}]] \\ \ii {\bfseries :stretch }[{\itshape direction} [{\itshape distance}]] \\ \ii {\bfseries :copy} \\ \ii {\bfseries :upsidedown} \\ \ii {\bfseries :sideways} \\ \ii {\bfseries :clockwise }[{\itshape degrees}] \\ \endi The {\bfseries :delete} command deletes everything that's selected. Watch out: {\bfseries :delete} is different from {\bfseries :erase}, which erases paint from the area underneath the box. Select the red bar on the right in {\bfseries tut2b} and type {\bfseries d}, which is a macro for {\bfseries :delete}. Undo the deletion with the {\bfseries u} macro. The {\bfseries :move} command picks up both the box and the selection and moves them so that the lower-left corner of the box is at the cursor location. Select the red bar on the right and move it so that it falls on top of the vertical part of the blue ``L''. You can use {\bfseries t} (``{\bfseries t}ranslate'') as a macro for {\bfseries :move}. Practice moving various things around the screen. The command {\bfseries :copy} and its macro {\bfseries c} are just like {\bfseries :move} except that a copy of the selection is left behind at the original position. There is also a longer form of the {\bfseries :move} command that you can use to move the selection a precise amount. For example, {\bfseries :move up 10} will move the selection (and the box) up 10 units. The {\itshape direction} argument can be any direction like {\bfseries left}, {\bfseries south}, {\bfseries down}, etc. See the Magic manual page for a complete list of the legal directions. The macros {\bfseries q}, {\bfseries w}, {\bfseries e}, and {\bfseries r} are defined to move the selection left, down, up, and right (respectively) by one unit. The {\bfseries :stretch} command is similar to {\bfseries :move} except that it stretches and erases as it moves. {\bfseries :stretch} does not operate diagonally, so if you use the cursor to indicate where to stretch to, Magic will either stretch up, down, left, or right, whichever is closest. The {\bfseries :stretch} command moves the selection and also does two additional things. First, for each piece of paint that moves, {\bfseries :stretch} will erase that layer from the region that the paint passes through as it moves, in order to clear material out of its way. Second, if the back edge of a piece of selected paint touches non-selected material, one of the two pieces of paint is stretched to maintain the connection. The macros {\bfseries Q}, {\bfseries W}, {\bfseries E}, and {\bfseries R} just like the macros {\bfseries q}, etc. described above for {\bfseries :move}. The macro {\bfseries T} is predefined to {\bfseries :stretch}. To see how stretching works, select the horizontal piece of the green wire in {\bfseries tut2b} and type {\bfseries W}, then {\bfseries E}. Stretching only worries about material in front of and behind the selection; it ignores material to the sides (try the {\bfseries Q} and {\bfseries R} macros to see). You can use plowing (described in Tutorial \#3) if this is a problem. The command {\bfseries :upsidedown} will flip the selection upside down, and {\bfseries :sideways} flips the selection sideways. Both commands leave the selection so it occupies the same total area as before, but with the contents flipped. The command {\bfseries :clockwise} will rotate the selection clockwise, leaving the lower-left corner of the new selection at the same place as the lower-left corner of the old selection. {\itshape Degrees} must be a multiple of 90, and defaults to 90. At this point you know enough to do quite a bit of damage to the {\bfseries tut2b} cell. Experiment with the selection commands. Remember that you can use {\bfseries :undo} to back out of trouble. \section{Labels} Labels are pieces of text attached to the paint of a cell. They are used to provide information to other tools that will process the circuit. Most labels are node names: they provide an easy way of referring to nodes in tools such as routers, simulators, and timing analyzers. Labels may also be used for other purposes: for example, some labels are treated as {\itshape attributes} that give Crystal, the timing analyzer, information about the direction of signal flow through transistors. Load the cell {\bfseries tut2c} and place a cross in the middle of the red chunk (to make a cross, position the lower-left corner of the box with the left button and then click the right button to place the upper-right corner on top of the lower-left corner). Then type type the command {\bfseries :label test}. A new label will appear at the position of the box. The complete syntax of the {\bfseries :label} command is \starti \ii {\bfseries :label }[{\itshape text }[{\itshape position }[{\itshape layer}]]] \endi {\itshape Text} must be supplied, but the other arguments can be defaulted. If {\itshape text} has any spaces in it, then it must be enclosed in double quotes. {\itshape Position} tells where the text should be displayed, relative to the point of the label. It may be any of {\bfseries north}, {\bfseries south}, {\bfseries east}, {\bfseries west}, {\bfseries top}, {\bfseries bottom}, {\bfseries left}, {\bfseries right}, {\bfseries up}, {\bfseries down}, {\bfseries center}, {\bfseries northeast}, {\bfseries ne}, {\bfseries southeast}, {\bfseries se}, {\bfseries southwest}, {\bfseries sw}, {\bfseries northwest}, {\bfseries nw}. For example, if {\bfseries ne} is given, the text will be displayed above and to the right of the label point. If no {\itshape position} is given, Magic will pick a position for you. {\itshape Layer} tells which paint layer to attach the label to. If {\itshape layer} covers the entire area of the label, then the label will be associated with the particular layer. If {\itshape layer} is omitted, or if it doesn't cover the label's area, Magic initially associates the label with the ``space'' layer, then checks to see if there's a layer that covers the whole area. If there is, Magic moves the label to that layer. It is generally a bad idea to place labels at points where there are several paint layers, since it will be hard to tell which layer the label is attached to. As you edit, Magic will ensure that labels are only attached to layers that exist everywhere under the label. To see how this works, paint the layer pdiff (brown) over the label you just created: the label will switch layers. Finally, erase poly over the area, and the label will move again. Although many labels are point labels, this need not be the case. You can label any rectangular area by setting the box to that area before invoking the label command. This feature is used for labelling terminals for the router (see below), and for labelling tiles used by Mpack, the tile packing program. {\bfseries Tut2c} has examples of point, line, and rectangular labels. All of the selection commands apply to labels as well as paint. Whenever you select paint, the labels attached to that paint will also be selected. Selected labels are highlighted in white. Select some of the chunks of paint in {\bfseries tut2c} to see how the labels are selected too. When you use area selection, labels will only be selected if they are completely contained in the area being selected. If you'd like to select {\itshape just} a label without any paint, make the box into a cross and put the cross on the label: {\bfseries s} and {\bfseries S} will select just the label. There are several ways to erase a label. One way is to select and then delete it. Another way is to erase the paint that the label is attached to. If the paint is erased all around the label, then Magic will delete the label too. Try attaching a label to a red area, then paint blue over the red. If you erase blue the label stays (since it's attached to red), but if you erase the red then the label is deleted. You can also erase labels using the {\bfseries :erase} command and the pseudo-layer {\bfseries labels}. The command \starti \ii {\bfseries :erase labels} \endi will erase all labels that lie completely within the area of the box. Finally, you can erase a label by making the box into a cross on top of the label, then clicking the middle button with the cursor over empty space. Technically, this will erase all paint layers and labels too. However, since the box has zero area, erasing paint has no effect: only the labels are erased. \section{Labelling Conventions} When creating labels, Magic will permit you to use absolutely any text whatsoever. However, many other tools, and even parts of Magic, expect label names to observe certain conventions. Except for the special cases described below, labels shouldn't contain any of the characters ``/\$@!\^{}''. Spaces, control characters, or parentheses within labels are probably a bad idea too. Many of the programs that process Magic output have their own restrictions on label names, so you should find out about the restrictions that apply at your site. Most labels are node names: each one gives a unique identification to a set of things that are electrically connected. There are two kinds of node names, local and global. Any label that ends in ``!'' is treated as a global node name; it will be assumed that all nodes by this name, anywere in any cell in a layout, are electrically connected. The most common global names are {\bfseries Vdd!} and {\bfseries GND!}, the power rails. You should always use these names exactly, since many other tools require them. Nobody knows why ``GND!'' is all in capital letters and ``Vdd!'' isn't. Any label that does not end in ``!'' or any of the other special characters discussed below is a local node name. It refers to a node within that particular cell. Local node names should be unique within the cell: there shouldn't be two electrically distinct nodes with the same name. On the other hand, it is perfectly legal, and sometimes advantageous, to give more than one name to the same node. It is also legal to use the same local node name in different cells: the tools will be able to distinguish between them and will not assume that they are electrically connected. The only other labels currently understood by the tools are {\itshape attributes}. Attributes are pieces of text associated with a particular piece of the circuit: they are not node names, and need not be unique. For example, an attribute might identify a node as a chip input, or it might identify a transistor terminal as the source of information for that transistor. Any label whose last character is ``@'', ``\$'', or ``\^{}'' is an attribute. There are three different kinds of attributes. Node attributes are those ending with ``@''; they are associated with particular nodes. Transistor source/drain attributes are those ending in ``\$''; they are associated with particular terminals of a transistor. A source or drain attribute must be attached to the channel region of the transistor and must fall exactly on the source or drain edge of the transistor. The third kind of attribute is a transistor gate attribute. It ends in ``\^{}'' and is attached to the channel region of the transistor. To see examples of attributes and node names, edit the cell {\bfseries tut2d} in Magic. Special conventions apply to labels for routing terminals. The standard Magic router (invoked by {\bfseries :route}) ignores all labels except for those on the edges of cells. (This restriction does not apply to the gate-array router, Garoute, or to the interactive router, Iroute). If you expect to use the standard router to connect to a particular node, you should place the label for that node on its outermost edge. The label should not be a point label, but should instead be a horizontal or vertical line covering the entire edge of the wire. The router will choose a connection point somewhere along the label. A good rule of thumb is to label all nodes that enter or leave the cell in this way. For more details on how labels are used by the standard router, see ``Magic Tutorial \#7: Netlists and Routing''. Other labeling conventions are used by the Garouter and Irouter, consult their respective tutorials for details. \section{Files and Formats} Magic provides a variety of ways to save your cells on disk. Normally, things are saved in a special Magic format. Each cell is a separate file, and the name of the file is just the name of the cell with {\bfseries .mag} appended. For example, the cell {\bfseries tut2a} is saved in file {\bfseries tut2a.mag}. To save cells on disk, invoke the command \starti \ii {\bfseries :writeall} \endi This command will run through each of the cells that you have modified in this editing session, and ask you what to do with the cell. Normally, you'll type {\bfseries write}, or just hit the return key, in which case the cell will be written back to the disk file from which it was read (if this is a new cell, then you'll be asked for a name for the cell). If you type {\bfseries autowrite}, then Magic will write out all the cells that have changed without asking you what to do on a cell-by-cell basis. {\bfseries Flush} will cause Magic to delete its internal copy of the cell and reload the cell from the disk copy, thereby expunging all edits that you've made. {\bfseries Skip} will pass on to the next cell without writing this cell (but Magic still remembers that it has changed, so the next time you invoke {\bfseries :writeall} Magic will ask about this cell again). {\bfseries Abort} will stop the command immediately without writing or checking any more cells. {\bfseries IMPORTANT NOTE:} Unlike vi and other text editors, Magic doesn't keep checkpoint files. This means that if the system should crash in the middle of a session, you'll lose all changes since the last time you wrote out cells. It's a good idea to save your cells frequently during long editing sessions. You can also save the cell you're currently editing with the command \starti \ii {\bfseries :save} {\itshape name} \endi This command will append ``.mag'' to {\itshape name} and save the cell you are editing in that location. If you don't provide a name, Magic will use the cell's name (plus the ``.mag'' extension) as the file name, and it will prompt you for a name if the cell hasn't yet been named. Once a cell has been saved on disk you can edit it by invoking Magic with the command \starti \ii {\bfseries magic} {\itshape name} \endi where {\itshape name} is the same name you used to save the cell (no ``.mag'' extension). Magic can also read and write files in CIF and Calma Stream formats. See ``Magic Tutorial \#9: Format Conversion for CIF and Calma'' for details. \section{Plotting} Magic can generate hardcopy plots of layouts in four ways: postscript (color), versatec (black-and-white or color), gremlin, and pixels (a generalized pixel-file that can be massaged in many ways). To plot part of your design in PostScript, place the box around the part you'd like to plot and type \starti \ii {\bfseries :plot postscript} \endi This will generate a plot of the area of the box. Everything visible underneath the box will appear in more-or-less the same way in the plot. {\itshape Width} specifies how wide the plot will be, in inches. Magic will scale the plot so that the area of the box comes out this wide. The default for {\itshape width} is the width of the plotter (if {\itshape width} is larger than the plotter width, it's reduced to the plotter width). If {\itshape layers} is given, it specifies exactly what information is to be plotted. Only those layers will appear in the plot. The special ``layer'' {\bfseries labels} will enable label plotting. The second form is for driving printers like color Versatecs. It is enabled by setting the {\itshape color} plot parameter to {\itshape true}. A table of stipples for the primary colors (black, cyan, magenta abd yellow) is given in the technology file. When the {\itshape plot} command is given, four rasters (one for each of the colors) are generated, separated with the proper control sequences for the printer. Otherwise, operation is exactly as for the black-and-white case. The third form of plotting is for generating Gremlin-format files, which can then be edited with the Gremlin drawing system or included in documents processed by Grn and Ditroff. The command to get Gremlin files is \starti \ii {\bfseries :plot gremlin} {\itshape file }[{\itshape layers}] \endi It will generate a Gremlin-format file in {\itshape file} that describes everything underneath the box. If {\itshape layers} is specified, it indicates which layers are to appear in the file; otherwise everything visible on the screen is output. The Gremlin file is output without any particular scale; use the {\bfseries width} or {\bfseries height} commands in Grn to scale the plot when it's printed. You should use the {\bfseries mg} stipples when printing Magic Gremlin plots; these will produce the same stipple patterns as {\bfseries :plot versatec}. Finally, the ``pixels'' style of plotting generates a file of pixel values for the region to be plotted. This can be useful for input to other image tools, or for generation of slides and viewgraphs for presentations. The file consists of a sequence of bytes, three for each pixel, written from left to right and top to bottom. Each three bytes represent the red, green and blue values used to display the pixel. Thus, if the upper-left-most pixel were to be red, the first three bytes of the file would have values of 255, 0 and 0. The resolution of the generated file is normally 512, but can be controlled by setting the plot parameter {\itshape pixWidth}. It must be a multiple of 8; Magic will round up if an inappropriate value is entered. The height of the file is determined by the shape of the box. In any case, the actual resolution of the file is appended to the file name. For example, plotting a square region, 2048 pixels across, will result in a file named something like ``magicPlot1234a-2048-2048''. There are several plotting parameters used internally to Magic, such as the width of the Versatec printer and the number of dots per inch on the Versatec printer. You can modify most of these to work with different printers. For details, read about the various {\bfseries :plot} command options in the {\itshape man} page. \section{Utility Commands} There are several additional commands that you will probably find useful once you start working on real cells. The command \starti \ii {\bfseries :grid }[{\itshape spacing}] \\ \ii {\bfseries :grid }{\itshape xSpacing ySpacing} \\ \ii {\bfseries :grid }{\itshape xSpacing ySpacing xOrigin yOrigin} \\ \ii {\bfseries :grid off} \endi will display a grid over your layout. Initially, the grid has a one-unit spacing. Typing {\bfseries :grid} with no arguments will toggle the grid on and off. If a single numerical argument is given, the grid will be turned on, and the grid lines will be {\itshape spacing} units apart. The macro {\bfseries g} provides a short form for {\bfseries :grid} and {\bfseries G} is short for {\bfseries :grid 2}. If you provide two arguments to {\bfseries :grid}, they are the x- and y-spacings, which may be different. If you provide four arguments, the last two specify a reference point through which horizontal and vertical grid lines pass; the default is to use (0,0) as the grid origin. The command {\bfseries :grid off} always turns the grid off, regardless of whether or not is was previously on. When the grid is on, a small black box is displayed to mark the (0,0) coordinate of the cell you're editing. If you want to create a cell that doesn't fit on the screen, you'll need to know how to change the screen view. This can be done with three commands: \starti \ii {\bfseries :zoom }{\itshape factor} \\ \ii {\bfseries :findbox }[{\bfseries zoom}] \\ \ii {\bfseries :view} \endi If {\itshape factor} is given to the zoom command, it is a zoom-out factor. For example, the command {\bfseries :zoom 2} will change the view so that there are twice as many units across the screen as there used to be ({\bfseries Z} is a macro for this). The new view will have the same center as the old one. The command {\bfseries :zoom .5} will increase the magnification so that only half as much of the circuit is visible. The {\bfseries :findbox} command is used to change the view according to the box. The command alone just moves the view (without changing the scale factor) so that the box is in the center of the screen. If the {\bfseries zoom} argument is given then the magnification is changed too, so that the area of the box nearly fills the screen. {\bfseries z} is a macro for {\bfseries :findbox zoom} and {\bfseries B} is a macro for {\bfseries :findbox}. The command {\bfseries :view} resets the view so that the entire cell is visible in the window. It comes in handy if you get lost in a big layout. The macro {\bfseries v} is equivalent to {\bfseries :view}. The command {\bfseries :box} prints out the size and location of the box in case you'd like to measure something in your layout. The macro {\bfseries b} is predefined to {\bfseries :box}. The {\bfseries :box} command can also be used to set the box to a particular location, height, or width. See the man page for details. The command \starti \ii {\bfseries :what} \endi will print out information about what's selected. This may be helpful if you're not sure what layer a particular piece of material is, or what layer a particular label is attached to. If you forget what a macro means, you can invoke the command \starti \ii {\bfseries :macro }[{\itshape char}] \endi This command will print out the long command that's associated with the macro {\itshape char}. If you omit {\itshape char}, Magic will print out all of the macro associations. The command \starti \ii {\bfseries :macro} {\itshape char command} \endi We set up {\itshape char} to be a macro for {\itshape command}, replacing the old {\itshape char} macro if there was one. If {\itshape command} contains any spaces then it must be enclosed in double-quotes. To see how this works, type the command {\bfseries :macro} {\ttfamily 1 "echo You just typed the 1 key."}, then type the 1 key. One of the macros, ``{\bfseries .}'', has special meaning in Magic. This macro is always defined by the system to be the last long command you typed. Whenever you'd like to repeat a long command, all you have to do is use the dot macro. \section{What the Layers Mean} The paint layers available in Magic are different from those that you may be used to in Caesar and other systems because they don't correspond exactly to the masks used in fabrication. We call them {\itshape abstract layers} because they correspond to constructs such as wires and contacts, rather than mask layers. We also call them {\itshape logs} because they look like sticks except that the geometry is drawn fully fleshed instead of as lines. In Magic there is one paint layer for each kind of conducting material (polysilicon, ndiffusion, metal1, etc.), plus one additional paint layer for each kind of transistor (ntransistor, ptransistor, etc.), and, finally, one further paint layer for each kind of contact (pcontact, ndcontact, m2contact, etc.) Each layer has one or more names that are used to refer to that layer in commands. To find out the layers available in the current technology, type the command \starti \ii {\bfseries :layers} \endi In addition to the mask layers, there are a few pseudo-layers that are valid in all technologies; these are listed in Table~\ref{pseudolayers}. Each Magic technology also has a technology manual describing the features of that technology, such as design rules, routing layers, CIF styles, etc. If you haven't seen any of the technology manuals yet, this is a good time to take a look at the one for your process. \begin{table}[hb] \begin{center} \begin{tabular}{|l|} \hline {\bfseries errors} (design-rule violations) \\ {\bfseries labels} \\ {\bfseries subcells} \\ {\bfseries \*} (all mask layers) \\ {\bfseries \$} (all mask layers visible under cursor) \\ \hline \end{tabular} \end{center} \caption{Pseudo-layers available in all technologies.} \label{pseudolayers} \end{table} If you're used to designing with mask layers (e.g. you've been reading the Mead-Conway book), Magic's log style will take some getting used to. One of the reasons for logs is to save you work. In Magic you don't draw implants, wells, buried windows, or contact via holes. Instead, you draw the primary conducting layers and paint some of their overlaps with special types such as n-transistor or polysilicon contact. For transistors, you draw only the actual area of the transistor channel. Magic will generate the polysilicon and diffusion, plus any necessary implants, when it creates a CIF file. For contacts, you paint the contact layer in the area of overlap between the conducting layers. Magic will generate each of the constituent mask layers plus vias and buried windows when it writes the CIF file. Figure~\ref{layers1} shows a simple cell drawn with both mask layers (as in Caesar) and with logs (as in Magic). If you're curious about what the masks will look like for a particular layout, you can use the {\bfseries :cif see} command to view the mask information. \begin{figure}[ht] \begin{center} \begin{minipage}{0.3\columnwidth} \epsfig{file=../psfigures/tut2.2.ps, height=5in} \end{minipage} \hspace*{0.5in} \begin{minipage}{0.5\columnwidth} \epsfig{file=../psfigures/tut2.1.ps, height=4.0in} \end{minipage} \caption {An example of how the logs are used. The figure on the left shows actual mask layers for an CMOS inverter cell, and the figure on the right shows the layers used to represent the cell in Magic.} \label{layers1} \end{center} \end{figure} An advantage of the logs used in Magic is that they simplify the design rules. Most of the formation rules (e.g. contact structure) go away, since Magic automatically generates correctly-formed structures when it writes CIF. All that are left are minimum size and spacing rules, and Magic's abstract layers result in fewer of these than there would be otherwise. This helps to make Magic's built-in design rule checker very fast (see ``Magic Tutorial \#6: Design Rule Checking''), and is one of the reasons plowing is possible. \end{document} magic-8.0.210/doc/latexfiles/tut4.tex0000644000175000001440000006546210751423606016022 0ustar timusers%---------------------------------------------------------------------------- % Magic tutorial number 4 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Magic Tutorial \#4: Cell Hierarchies} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape John Ousterhout} \\ \vspace*{0.5in} Computer Science Division \\ Electrical Engineering and Computer Sciences \\ University of California \\ Berkeley, CA 94720 \\ \vspace*{0.25in} {\itshape (Updated by others, too.)} \\ \vspace*{0.25in} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Tutorials to read first:} \starti \> Magic Tutorial \#1: Getting Started \\ \> Magic Tutorial \#2: Basic Painting and Selection \endi {\noindent\bfseries\large Commands introduced in this tutorial:} \starti \> :array, :edit, :expand, :flush, :getcell, :identify, :load, :path, :see, :unexpand \endi {\noindent\bfseries\large Macros introduced in this tutorial:} \starti \> x, X, \^{}X \endi \vspace*{0.75in} \section{Introduction} In Magic, a layout is a hierarchical collection of cells. Each cell contains three things: paint, labels, and subcells. Tutorial \#2 showed you how to create and edit paint and labels. This tutorial describes Magic's facilities for building up cell hierarchies. Strictly speaking, hierarchical structure isn't necessary: any design that can be represented hierarchically can also be represented ``flat'' (with all the paint and labels in a single cell). However, many things are greatly improved if you use a hierarchical structure, including the efficiency of the design tools, the speed with which you can enter the design, and the ease with which you can modify it later. \section{Selecting and Viewing Hierarchical Designs} ``Hierarchical structure'' means that each cell can contain other cells as components. To look at an example of a hierarchical layout, enter Magic with the shell command {\bfseries magic tut4a}. The cell {\bfseries tut4a} contains four subcells plus some blue paint. Two of the subcells are instances of cell {\bfseries tut4x} and two are instances of {\bfseries tut4y}. Initially, each subcell is displayed in {\itshape unexpanded} form. This means that no details of the subcell are displayed; all you see is the cell's bounding box, plus two names inside the bounding box. The top name is the name of the subcell (the name you would type when invoking Magic to edit the cell). The cell's contents are stored in a file with this name plus a {\bfseries .mag} extension. The bottom name inside each bounding box is called an {\itshape instance identifier}, and is used to distinguish different instances of the same subcell. Instance id's are used for routing and circuit extraction, and are discussed in Section 6. Subcells can be manipulated using the same selection mechanism that you learned in Tutorial \#2. To select a subcell, place the cursor over the subcell and type {\bfseries f} (``{\bfseries f}ind cell''), which is a macro for {\bfseries :select cell}. You can also select a cell by typing {\bfseries s} when the cursor is over a location where there's no paint; {\bfseries f} is probably more convenient, particularly for cells that are completely covered with paint. When you select a cell the box will be set to the cell's bounding box, the cell's name will be highlighted, and a message will be printed on the text display. All the selection operations ({\bfseries :move}, {\bfseries :copy}, {\bfseries :delete}, etc.) apply to subcells. Try selecting and moving the top subcell in {\bfseries tut4a}. You can also select subcells using area selection (the {\bfseries a} and {\bfseries A} macros): any unexpanded subcells that intersect the area of the box will be selected. To see what's inside a cell instance, you must {\itshape expand} it. Select one of the instances of {\bfseries tut4y}, then type the command \starti \ii {\bfseries :expand toggle} \endi or invoke the macro {\bfseries \^{}X} which is equivalent. This causes the internals of that instance of {\bfseries tut4y} to be displayed. If you type {\bfseries \^{}X} again, the instance is unexpanded so you only see a bounding box again. The {\bfseries :expand toggle} command expands all of the selected cells that are unexpanded, and unexpands all those that are expanded. Type {\bfseries \^{}X} a third time so that {\bfseries tut4y} is expanded. As you can see now, {\bfseries tut4y} contains an array of {\bfseries tut4x} cells plus some additional paint. In Magic, an array is a special kind of instance containing multiple copies of the same subcell spaced at fixed intervals. Arrays can be one-dimensional or two-dimensional. The whole array is always treated as a single instance: any command that operates on one element of the array also operates on all the other elements simultaneously. The instance identifiers for the elements of the array are the same except for an index. Now select one of the elements of the array and expand it. Notice that the entire array is expanded at the same time. When you have expanded the array, you'll see that the paint in the top-level cell {\bfseries tut4a} is displayed more brightly than the paint in the {\bfseries tut4x} instances. {\bfseries Tut4a} is called the {\itshape edit cell}, because its contents are currently editable. The paint in the edit cell is normally displayed more brightly than other paint to make it clear that you can change it. As long as {\bfseries tut4a} is the edit cell, you cannot modify the paint in {\bfseries tut4x}. Try erasing paint from the area of one of the {\bfseries tut4x} instances: nothing will be changed. Section 4 tells how to switch the edit cell. Place the cursor over one of the {\bfseries tut4x} array elements again. At this point, the cursor is actually over three different cells: {\bfseries tut4x} (an element of an array instance within {\bfseries tut4y}), {\bfseries tut4y} (an instance within {\bfseries tut4a}), and {\bfseries tut4}. Even the topmost cell in the hierarchy is treated as an instance by Magic. When you press the {\bfseries s} key to select a cell, Magic initially chooses the smallest instance visible underneath the cursor, {\bfseries tut4x} in this case. However, if you invoke the {\bfseries s} macro again (or type {\bfseries :select}) without moving the cursor, Magic will step through all of the instances under the cursor in order. Try this out. The same is true of the {\bfseries f} macro and {\bfseries :select cell}. When there are many different expanded cells on the screen, you can use the selection commands to select paint from any of them. You can select anything that's visible, regardless of which cell it's in. However, as mentioned above, you can only modify paint in the edit cell. If you use {\bfseries :move} or {\bfseries :upsidedown} or similar commands when you've selected information outside the edit cell, the information outside the edit cell is removed from the selection before performing the operation. There are two additional commands you can use for expanding and unexpanding cells: \starti \ii {\bfseries :expand} \\ \ii {\bfseries :unexpand} \endi Both of these commands operate on the area underneath the box. The {\bfseries :expand} command will recursively expand every cell that intersects the box until there are no unexpanded cells left under the box. The {\bfseries :unexpand} command will unexpand every cell whose area intersects the box but doesn't completely contain it. The macro {\bfseries x} is equivalent to {\bfseries :expand}, and {\bfseries X} is equivalent to {\bfseries :unexpand}. Try out the various expansion and unexpansion facilities on {\bfseries tut4a}. \section{Manipulating Subcells} There are a few other commands, in addition to the selection commands already described, that you'll need in order to manipulate subcells. The command \starti \ii {\bfseries :getcell} {\itshape name} \endi will find the file {\itshape name}{\bfseries .mag} on disk, read the cell it contains, and create an instance of that cell with its lower-left corner aligned with the lower-left corner of the box. Use the {\bfseries getcell} command to get an instance of the cell {\bfseries tut4z}. After the {\bfseries getcell} command, the new instance is selected so you can move it or copy it or delete it. The {\bfseries getcell} command recognizes additional arguments that permit the cell to be positioned using labels and/or explicit coordinates. See the {\itshape man} page for details. To turn a normal instance into an array, select the instance and then invoke the {\bfseries :array} command. It has two forms: \starti \ii {\bfseries :array} {\itshape xsize ysize} \\ \ii {\bfseries :array} {\itshape xlo xhi ylo yhi} \endi In the first form, {\itshape xsize} indicates how many elements the array should have in the x-direction, and {\itshape ysize} indicates how many elements it should have in the y-direction. The spacing between elements is controlled by the box's width (for the x-direction) and height (for the y-direction). By changing the box size, you can space elements so that they overlap, abut, or have gaps between them. The elements are given indices from 0 to {\itshape xsize}-1 in the x-direction and from 0 to {\itshape ysize}-1 in the y-direction. The second form of the command is identical to the first except that the elements are given indices from {\itshape xlo} to {\itshape xhi} in the x-direction and from {\itshape ylo} to {\itshape yhi} in the y-direction. Try making a 4x4 array out of the {\bfseries tut4z} cell with gaps between the cells. You can also invoke the {\bfseries :array} command on an existing array to change the number of elements or spacing. Use a size of 1 for {\itshape xsize} or {\itshape ysize} in order to get a one-dimensional array. If there are several cells selected, the {\bfseries :array} command will make each of them into an array of the same size and spacing. It also works on paint and labels: if paint and labels are selected when you invoke {\bfseries :array}, they will be copied many times over to create the array. Try using the array command to replicate a small strip of paint. \section{Switching the Edit Cell} At any given time, you are editing the definition of a single cell. This definition is called the {\itshape edit cell}. You can modify paint and labels in the edit cell, and you can re-arrange its subcells. You may not re-arrange or delete the subcells of any cells other than the edit cell, nor may you modify the paint or labels of any cells except the edit cell. You may, however, copy information from other cells into the edit cell, using the selection commands. To help clarify what is and isn't modifiable, Magic displays the paint of the edit cell in brighter colors than other paint. When you rearrange subcells of the edit cell, you aren't changing the subcells themselves. All you can do is change the way they are used in the edit cell (location, orientation, etc.). When you delete a subcell, nothing happens to the file containing the subcell; the command merely deletes the instance from the edit cell. Besides the edit cell, there is one other special cell in Magic. It's called the {\itshape root cell} and is the topmost cell in the hierarchy, the one you named when you ran Magic ({\bfseries tut4a} in this case). As you will see in Tutorial \#5, there can actually be several root cells at any given time, one in each window. For now, there is only a single window on the screen, and thus only a single root cell. The window caption at the top of the color display contains the name of the window's root cell and also the name of the edit cell. Up until now, the root cell and the edit cell have been the same. However, this need not always be the case. You can switch the edit cell to any cell in the hierarchy by selecting an instance of the definition you'd like to edit, and then typing the command \starti \ii {\bfseries :edit} \endi Use this command to switch the edit cell to one of the {\bfseries tut4x} instances in {\bfseries tut4a}. Its paint brightens, while the paint in {\bfseries tut4a} becomes dim. If you want to edit an element of an array, select the array, place the cursor over the element you'd like to edit, then type {\bfseries :edit}. The particular element underneath the cursor becomes the edit cell. When you edit a cell, you are editing the master definition of that cell. This means that if the cell is used in several places in your design, the edits will be reflected in all those places. Try painting and erasing in the {\bfseries tut4x} cell that you just made the edit cell: the modifications will appear in all of its instances. There is a second way to change the edit cell. This is the command \starti \ii {\bfseries :load} {\itshape name} \endi The {\bfseries :load} command loads a new hierarchy into the window underneath the cursor. {\itshape Name} is the name of the root cell in the hierarchy. If no {\itshape name} is given, a new unnamed cell is loaded and you start editing from scratch. The {\bfseries :load} command only changes the edit cell if there is not already an edit cell in another window. \section{Subcell Usage Conventions} Overlaps between cells are occasionally useful to share busses and control lines running along the edges. However, overlaps cause the analysis tools to work much harder than they would if there were no overlaps: wherever cells overlap, the tools have to combine the information from the two separate cells. Thus, you shouldn't use overlaps any more than absolutely necessary. For example, suppose you want to create a one-dimensional array of cells that alternates between two cell types, A and B: ``ABABABABABAB''. One way to do this is first to make an array of A instances with large gaps between them (``A A A A A A''), then make an array of B instances with large gaps between them (``B B B B B B''), and finally place one array on top of the other so that the B's nestle in between the A's. The problem with this approach is that the two arrays overlap almost completely, so Magic will have to go to a lot of extra work to handle the overlaps (in this case, there isn't much overlap of actual paint, but Magic won't know this and will spend a lot of time worrying about it). A better solution is to create a new cell that contains one instance of A and one instance of B, side by side. Then make an array of the new cell. This approach makes it clear to Magic that there isn't any real overlap between the A's and B's. If you do create overlaps, you should use the overlaps only to connect the two cells together, and not to change their structure. This means that the overlap should not cause transistors to appear, disappear, or change size. The result of overlapping the two subcells should be the same electrically as if you placed the two cells apart and then ran wires to hook parts of one cell to parts of the other. The convention is necessary in order to be able to do hierarchical circuit extraction easily (it makes it possible for each subcell to be circuit-extracted independently). Three kinds of overlaps are flagged as errors by the design-rule checker. First, you may not overlap polysilicon in one subcell with diffusion in another cell in order to create transistors. Second, you may not overlap transistors or contacts in one cell with different kinds of transistors or contacts in another cell (there are a few exceptions to this rule in some technologies). Third, if contacts from different cells overlap, they must be the same type of contact and must coincide exactly: you may not have partial overlaps. This rule is necessary in order to guarantee that Magic can generate CIF for fabrication. You will make life a lot easier on yourself (and on Magic) if you spend a bit of time to choose a clean hierarchical structure. In general, the less cell overlap the better. If you use extensive overlaps you'll find that the tools run very slowly and that it's hard to make modifications to the circuit. \section{Instance Identifiers} Instance identifiers are used to distinguish the different subcells within a single parent. The cell definition names cannot be used for this purpose because there could be many instances of a single definition. Magic will create default instance id's for you when you create new instances with the {\bfseries :get} or {\bfseries :copy} commands. The default id for an instance will be the name of the definition with a unique integer added on. You can change an id by selecting an instance (which must be a child of the edit cell) and invoking the command \starti \ii {\bfseries :identify} {\itshape newid} \endi where {\itshape newid} is the identifier you would like the instance to have. {\itshape Newid} must not already be used as an instance identifier of any subcell within the edit cell. Any node or instance can be described uniquely by listing a path of instance identifiers, starting from the root cell. The standard form of such names is similar to Unix file names. For example, if {\bfseries id1} is the name of an instance within the root cell, {\bfseries id2} is an instance within {\bfseries id1}, and {\bfseries node} is a node name within {\bfseries id2}, then {\bfseries id1/id2/node} can be used unambiguously to refer to the node. When you select a cell, Magic prints out the complete path name of the instance. Arrays are treated specially. When you use {\bfseries :identify} to give an array an instance identifier, each element of the array is given the instance identifier you specified, followed by one or two array subscripts enclosed in square brackets, e.g, {\bfseries id3[2]} or {\bfseries id4[3][7]}. When the array is one-dimensional, there is a single subscript; when it is two-dimensional, the first subscript is for the y-dimension and the second for the x-dimension. \section{Writing and Flushing Cells} When you make changes to your circuit in Magic, there is no immediate effect on the disk files that hold the cells. You must explicitly save each cell that has changed, using either the {\bfseries :save} command or the {\bfseries :writeall} command. Magic keeps track of the cells that have changed since the last time they were saved on disk. If you try to leave Magic without saving all the cells that have changed, the system will warn you and give you a chance to return to Magic to save them. Magic never flushes cells behind your back, and never throws away definitions that it has read in. Thus, if you edit a cell and then use {\bfseries :load} to edit another cell, the first cell is still saved in Magic even though it doesn't appear anywhere on the screen. If you then invoke {\bfseries :load} a second time to go back to the first cell, you'll get the edited copy. If you decide that you'd really like to discard the edits you've made to a cell and recover the old version, there are two ways you can do it. The first way is using the {\bfseries flush} option in {\bfseries :writeall}. The second way is to use the command \starti \ii {\bfseries :flush }[{\itshape cellname}] \endi If no {\itshape cellname} is given, then the edit cell is flushed. Otherwise, the cell named {\itshape cellname} is flushed. The {\bfseries :flush} command will expunge Magic's internal copy of the cell and replace it with the disk copy. When you are editing large chips, Magic may claim that cells have changed even though you haven't modified them. Whenever you modify a cell, Magic makes changes in the parents of the cell, and their parents, and so on up to the root of the hierarchy. These changes record new design-rule violations, as well as timestamp and bounding box information used by Magic to keep track of design changes and enable fast cell read-in. Thus, whenever you change one cell you'll generally need to write out new copies of its parents and grandparents. If you don't write out the parents, or if you edit a child ``out of context'' (by itself, without the parents loaded), then you'll incur extra overhead the next time you try to edit the parents. ``Timestamp mismatch'' warnings are printed when you've edited cells out of context and then later go back and read in the cell as part of its parent. These aren't serious problems; they just mean that Magic is doing extra work to update information in the parent to reflect the child's new state. \section{Search Paths} When many people are working on a large design, the design will probably be more manageable if different pieces of it can be located in different directories of the file system. Magic provides a simple mechanism for managing designs spread over several directories. The system maintains a {\itshape search path} that tells which directories to search when trying to read in cells. By default, the search path is ``.'', which means that Magic looks only in the working directory. You can change the path using the command \starti \ii {\bfseries :path }[{\itshape searchpath}] \endi where {\itshape searchpath} is the new path that Magic should use. {\itshape Searchpath} consists of a list of directories separated by colons. For example, the path ``.:\~{}ouster/x:a/b'' means that if Magic is trying to read in a cell named ``foo'', it will first look for a file named ``foo.mag'' in the current directory. If it doesn't find the file there, it will look for a file named ``\~{}ouster/x/foo.mag'', and if that doesn't exist, then it will try ``a/b/foo.mag'' last. To find out what the current path is, type {\bfseries :path} with no arguments. In addition to your path, this command will print out the system cell library path (where Magic looks for cells if it can't find them anywhere in your path), and the system search path (where Magic looks for files like colormaps and technology files if it can't find them in your current directory). If you're working on a large design, you should use the search path mechanism to spread your layout over several directories. A typical large chip will contain a few hundred cells; if you try to place all of them in the same directory there will just be too many things to manage. For example, place the datapath in one directory, the control unit in another, the instruction buffer in a third, and so on. Try to keep the size of each directory down to a few dozen files. You can place the {\bfseries :path} command in a {\bfseries .magic} file in your home directory or the directory you normally run Magic from; this will save you from having to retype it each time you start up (see the Magic man page to find out about {\bfseries .magic} files). If all you want to do is add another directory onto the end of the search path, you can use the {\bfseries :addpath }[{\itshape directory}] command. Because there is only a single search path that is used everywhere in Magic, you must be careful not to re-use the same cell name in different portions of the chip. A common problem with large designs is that different designers use the same name for different cells. This works fine as long as the designers are working separately, but when the two pieces of the design are put together using a search path, a single copy of the cell (the one that is found first in the search path) gets used everywhere. There's another caveat in the use of search paths. Magic looks for system files in \~{}cad, but sometimes it is helpful to put Magic's system files elsewhere. If the {\bfseries CAD{\_}HOME} shell environment variable is set, then Magic uses that as the location of \~{}cad instead of the location in the password file. This overrides all uses of \~{}cad within magic, including the \~{}cad seen in the search paths printed out by {\bfseries :path}. \section{Additional Commands} This section describes a few additional cell-related commands that you may find useful. One of them is the command \starti \ii {\bfseries :select save} {\itshape file} \endi This command takes the selection and writes it to disk as a new Magic cell in the file {\itshape file}{\bfseries .mag}. You can use this command to break up a big file into smaller ones, or to extract pieces from an existing cell. The command \starti \ii {\bfseries :dump} {\itshape cellName} [{\itshape labelName}] \endi does the opposite of {\bfseries select save}: it copies the contents of cell {\itshape cellName} into the edit cell, such that the lower-left corner of label {\itshape labelName} is at the lower-left corner of the box. The new material will also be selected. This command is similar in form to the {\bfseries getcell} command except that it copies the contents of the cell instead of using the cell as a subcell. There are several forms of {\bfseries dump}; see the {\itshape man} page for details. The main purpose of {\bfseries dump} is to allow you to create a library of cells representing commonly-used structures such as standard transistor shapes or special contact arrangements. You can then define macros that invoke the {\bfseries dump} command to place the cells. The result is that a single keystroke is all you need to copy one of them into the edit cell. As mentioned earlier, Magic normally displays the edit cell in brighter colors than non-edit cells. This helps to distinguish what is editable from what is not, but may make it hard for you to view non-edit paint since it appears paler. If you type the command \starti \ii {\bfseries :see allSame} \endi you'll turn off this feature: all paint everywhere will be displayed in the bright colors. The word {\bfseries allSame} must be typed just that way, with one capital letter. If you'd like to restore the different display styles, type the command \starti \ii {\bfseries :see no allSame} \endi You can also use the {\bfseries :see} command to selectively disable display of various mask layers in order to make the other ones easier to see. For details, read about {\bfseries :see} in the Magic man page. \end{document} magic-8.0.210/doc/latexfiles/tuttcl4.tex0000644000175000001440000005147210751423606016521 0ustar timusers%---------------------------------------------------------------------------- % Magic Tcl tutorial number 4 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ig{\>} \def\ih{\>\>} \def\ii{\>\>\>} \def\ij{\>\>\>\>} \def\tf{\ttfamily} \def\bstf{\bfseries\ttfamily} \def\mytitle{Magic Tcl Tutorial \#4: Simulation with IRSIM} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape R. Timothy Edwards} \\ \vspace*{0.5in} Space Department \\ Johns Hopkins University \\ Applied Physics Laboratory \\ Laurel, MD 20723 \\ \vspace*{0.25in} This tutorial corresponds to Tcl-based Magic version 7.2 \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Tutorials to read first:} \starti \> Magic Tutorial \#1: Getting Started \\ \> Magic Tutorial \#2: Basic Painting and Selection \\ \> Magic Tutorial \#4: Cell Hierarchies \\ \> Magic Tutorial \#8: Circuit Extraction \\ \> Magic Tutorial \#11: Using IRSIM and RSIM with Magic \endi {\noindent\bfseries\large Commands introduced in this tutorial:} \starti \> irsim , getnode, goto \\ \> graphnode, watchnode, unwatchnode \\ \> movenode, watchtime, unwatchtime, movetime \\ \> {\itshape (plus the standard IRSIM command set)} \endi {\noindent\bfseries\large Macros introduced in this tutorial:} \starti \> {\itshape (None)} \endi \vspace*{0.25in} \section{IRSIM Version 9.6} In version 9.6, IRSIM has been redesigned to work under the Tcl interpreter, in the same manner as Magic version 7.2 does. Like Magic version 7.2, section of Tcl as an interpreter is specified at compile-time, along with various use options. The ``{\bfseries make}'' method has been rewritten to match the one which Magic uses, so IRSIM can be compiled and installed in a similar manner: \starti \ii {\bstf make config} \\ \ii {\bstf make tcl} \\ \ii {\bstf make install-tcl} \endi Tcl-based IRSIM, like its non-interpreter version, can be run as a standalone product, and will simulate a circuit from a {\ttfamily .sim} format file. However, it is specifically designed to be operated in conjunction with magic, with methods for providing feedback directly into the layout from the simulation, and vice versa. There are a number of {\itshape cross-application commands}, detailed below, which belong to neither Magic or IRSIM, but are applicable when both are running in the Tcl interpreter at the same time. The cross-application commands highlight the usefulness of the method of compiling each application as a loadable Tcl object module. In addition to cross-application commands, Tcl-based IRSIM allows the use of interpreter variables, conditionals, and control structures to set up detailed simulation environments. A random number generator has been added to the Tcl-based version, allowing generation of random bit vectors for statistically-based coverage of input pattern spaces. \section{Invoking IRSIM from Magic} Within the Tcl/Tk environment, IRSIM is easier than ever to invoke. For tutorial purposes, we will use the same cell used for the original Tutorial \#11. Unlike the original version, Magic 7.2 requires no preparation for simulation and can operate directly off of the tutorial directory input. Start magic with the command-line \starti \ii {\itshape \# }{\bstf magic -w -d OGL tut11a} \endi Note that the OpenGL interface and Wrapper environment specified above are optional, and do not affect the descriptions in this tutorial. It is not necessary to extract! The scripts which invoke IRSIM are capable of looking for a netlist file to simulate for the currently-loaded cell. Because these exist for the tutorial cells, they will be used. IRSIM is therefore simply invoked by: \starti \ii {\itshape \% }{\bstf irsim} \endi You will see a slew of output that looks like the following: \starti \> \tf Warning: irsim command 'time' use fully-qualified name '::irsim::time' \\ \> \tf Warning: irsim command 'start' use fully-qualified name '::irsim::start' \\ \> \tf Warning: irsim command 'help' use fully-qualified name '::irsim::help' \\ \> \tf Warning: irsim command 'path' use fully-qualified name '::irsim::path' \\ \> \tf Warning: irsim command 'clear' use fully-qualified name '::irsim::clear' \\ \> \tf Warning: irsim command 'alias' use fully-qualified name '::irsim::alias' \\ \> \tf Warning: irsim command 'set' use fully-qualified name '::irsim::set' \\ \> \tf Warning: irsim command 'exit' use fully-qualified name '::irsim::exit' \\ \> \tf Starting irsim under Tcl interpreter \\ \> \tf IRSIM 9.6 compiled on Thu Mar 20 17:19:00 EST 2003 \\ \> \tf Warning: Aliasing nodes 'GND' and 'Gnd' \\ \> \tf /usr/local/lib/magic/tutorial/tut11a.sim: Ignoring lumped-resistance \\ \>\> \tf ('R' construct) \\ \\ \> \tf Read /usr/local/lib/magic/tutorial/tut11a.sim lambda:1.00u format:MIT \\ \> \tf 68 nodes; transistors: n-channel=56 p-channel=52 \\ \> \tf parallel txtors:none \\ \> {\itshape \% } \endi These comments require some explanation. The warning messages all have to do with the fact that certain command names are used both by IRSIM and Magic, or by IRSIM and Tcl or one of its loaded packages (such as Tk). There are several ways to work around the unfortunate consequences of multiply defining command names, but the easiest is to make use of the Tcl concept of {\itshape namespaces}. A complete description of Tcl namespaces is beyond the scope of this tutorial; however, a simple description suffices. By prefixing a ``scope'' to the command, the command can only be executed when the complete name (scope plus the double colon `::' plus the command name) is entered. In general, the EDA tools make an attempt to allow commands to be entered without the scope prefix at the command line. As long as command names are unique, this is done without comment. However, when commands overlap, the easiest solution is to require the scope prefix. Therefore, the command `{\bfseries set}' would refer to the Tcl {\bfseries set} command (i.e., to set a variable), while `{\bfseries irsim::set}' would refer to the IRSIM command. Some attempt is made to overload commands which conflict but which have unique syntax, so that it is possible to determine which use is intended when the command is dispatched by the interpreter. In addition to the warnings, there are a few standard warnings about global name aliases and lumped resistance, and some information about the {\ttfamily .sim} file which was read. \section{IRSIM Command Set} In addition to the exceptions noted above for fully-qualified namespace commands, there are several IRSIM commands which are not compatible with Tcl syntax, and these have been renamed. The old and new commands are as follows (see the IRSIM documentation for the full set of commands): \begin{center} \begin{tabular}{|lll|} \hline > & savestate & save network state \\ < & restorestate & restore network state \\ << & restoreall & restore network and input state \\ ? & querysource & get info regarding source/drain connections \\ ! & querygate & get info regarding gate connections \\ \@ & source \itshape{(Tcl command)} & source a command file \\ \hline \end{tabular} \end{center} Note that the `{\bfseries \@}' command is simply superceded by the Tcl `{\bfseries source}' command, which is more general in that it allows a mixture of Tcl and IRSIM commands (and commands for any other loaded package, such as Magic) to be combined in the command file. Once loaded into Tcl alongside Magic via the {\bfseries irsim} command, the IRSIM commands are typed directly into the Magic command line, and will execute the appropriate IRSIM function. By repeating the contents of Tutorial \#11 in the Tcl environment, this method should become clear, as will the benefits of using the interpreter environment for simulation. To setup the simulation, the equivalent instruction to that of Tutorial \#11 is the following: \starti \ii {\itshape \% } {\bstf source \$}\{{\bstf CAD\_HOME}\}{\bstf /lib/magic/tutorial/tut11a.cmd} \endi Note that because the {\bfseries source} command is a Tcl command, not a Magic or IRSIM command, it it necessary to specify the complete path to the file, as Tcl does not understand the search path for Magic cells, which includes the tutorial directory. As most common commands are not among the set that cause conflicts with Magic and Tcl commands, the tutorial command file loads and executes without comment. Following the example of Tutorial~\#11, type {\bfseries c} (IRSIM clock command) on the magic command line to clock the circuit. Values for the watched nodes, which were declared in the tutorial command file, are displayed in the console window. Likewise, \starti \ii {\bstf h RESET\_B hold} \endi will set the nodes {\bstf RESET\_B} and {\bstf hold} to value 1. \section{Feedback to Magic} The cross-application commands reveal the usefulness of having both applications as extensions of the same Tcl interpreter. While Magic and IRSIM are active and file {\ttfamily tut11a} is loaded, execute the following commands from the command line: \starti \ii {\bstf stepsize 100} \\ \ii {\bstf watchnode RESET\_B} \\ \ii {\bstf watchnode hold} \endi Note that the nodes and values are immediately printed in the magic window, making use of the magic ``{\bfseries element}'' command. These values are persisent in the sense that they will remain through various transformations, openings, and closings of the layout window, but they are temporary in the sense that they will not be saved along with the layout if the file is written (however, this behavior can be modified). The {\bfseries watchnode} command requires no special action for placing the label elements in the layout because magic uses the labels or other node information to pinpoint a position in the layout belonging to that node, and places the label element there. It is possible to use {\bfseries watchnode} with vectors. However, as no location can be pinpointed for a vector, the magic cursor box position will be used to place the label element. Move the magic cursor box to a empty space in the layout window, and type \starti \ii {\bstf watchnode bits} \endi Now move the cursor box to another empty space and type \starti \ii {\bstf watchtime} \endi Now all of the simulation values of interest are displayed directly on the Magic layout. The display of any node can be removed with the command {\bstf unwatchnode}, with the same syntax as {\bstf watchnode}, and similarly, the display of simulation time can be removed with the command {\bstf unwatchtime}. If the position of a label is not in a good position to read, or the relative position of two labels places them on top of one another, making them difficult to read, the labels can be moved using the {\bfseries movenode} command. For instance, the node {\ttfamily RESET\_B} is not exactly on the polysilicon pad. To center it exactly on the pad, select the square pad, so that the box cursor is on it, then do \starti \ii {\bstf movenode RESET\_B} \endi The label will be moved so that it is centered on the center of the cursor box. The equivalent method can be applied to the time value using the {\bstf movetime} command. It is not necessary to know the name of a node in order to query or display its simulation value. For instance, unexpand the layout of {\ttfamily tut11a.mag}, select an unlabeled node, and use a mixture of IRSIM and magic commands to watch its value: \starti \ii {\bstf box 93 -104 94 -102} \\ \ii {\bstf select area} \\ \ii {\bstf watchnode [getnode]} \\ \endi In this example, both the node ({\ttfamily bit\_1/tut11d\_0/a\_39\_n23\#}) and its value are displayed. Likewise, the {\bfseries getnode} command can be combined with other IRSIM commands to setup clocks and vectors from unlabeled nodes. This can be particularly useful in situations where it may not be obvious which nodes in a design need to be examined prior to running the simulation. \section{Analyzer Display} Tcl-based IRSIM has a graphical node display which is derived from functions available in the ``{\bfseries BLT}'' graphics package. These functions are not particularly well-suited for display of logic values, and so this will probably be replaced in the future with a more appropriate interface. However, it accomplishes most of the functions of the former X11-based analyzer display. In the Tcl-based IRSIM, no special command is needed to initialize the analyzer display. One command sets up signals to be displayed in the analyzer window. This is: \starti \ii {\bstf graphnode} {\itshape name} [{\itshape row}] [{\itshape offset}] \endi For display of multiple signals in the window, the optional arguments {\itshape row} and {\itshape offset} are provided. Each signal which declares a new {\itshape row} (default zero) will appear in a separate graph in the display. Signals which appear in the same graph, however, may declare a non-zero {\itshape offset} which will set them at a different vertical placement on the graph, for cases in which this provides better viewing than having the signals directly overlapping. The analyzer display updates at the end of each simulation cycle. Logic values are displayed as 0 or 1, with undefined (value 'X') values displayed as 1/2. Note that the BLT-based interface prohibits the display of multi-bit values, and only nodes, not vectors, can be passed to the {\bstf graphnode} command. \section{Wildcards} The original IRSIM used ``wildcard'' characters in the form of standard UNIX ``regular expressions'' to perform operations on multiple nodes with one command. Unfortunately, there was a syntactical collision between IRSIM and Magic over the use of brackets (`{\bstf [}' and `{\bstf ]}'). Brackets represent groupings in regular expression syntax. However, Magic uses brackets to represent arrays of subcells. Because Tcl itself implements regular expressions in the form of the Tcl ``{\bstf regexp}'' command, there is a way around this problem in the Tcl version of IRSIM. IRSIM's parsing of regular expressions has been disabled. In place of it, Tcl lists may be passed as arguments to any command which previously would accept wildcard characters. In addition, Tcl-IRSIM defines a command \starti \ii {\bstf listnodes} \endi which returns a Tcl list of all the nodes defined in the netlist input file. This list can be searched by Tcl regular expression commands, and the resulting sub-lists passed as node arguments to IRSIM commands. For example, the following script sets all nodes in the circuit (except for {\ttfamily Vdd}, which is fixed) to zero, then releases them: \starti \ii {\bstf set nl [listnodes]} \\ \ii {\bstf l \$nl} \\ \ii {\bstf s} \\ \ii {\bstf x \$nl} \endi Brackets in individual node names are treated as-is by IRSIM, as are other Magic-generated characters such as the slash, underscore, and hash mark. Note, however, that because Tcl itself defines brackets as representing command groupings which return an immediate result, the following is illegal: \starti \ii {\itshape \%} {\bstf l multcell5\_0[1,0]/a\_13\_n21\#} \\ \ii {\ttfamily invalid command name "1,0"} \endi Instead, node names containing brackets should be surrounded by braces (`\{' and `\}'), which effectively turns a node name into a list of node names which happens to contain exactly one entry: \starti \ii {\itshape \%} {\bstf l }\{{\bstf multcell5\_0[1,0]/a\_13\_n21\#}\} \\ \endi The Tcl versions of Magic and IRSIM are set up in such a way that when they return results containing node names, these names are automatically treated as lists. Therefore, the command \starti \ii {\itshape \%} {\bstf select area [goto }\{{\bstf multcell5\_0[1,0]/a\_13\_n21\#}\} {\bstf ]} \\ \ii {\itshape \%} {\bstf l [getnode]} \endi does not produce any error when the arrayed node name is passed to the IRSIM ``{\bstf l}'' command, and sets the value of the node to zero as expected. It is only when node names are entered in a script or from the command line that precautions must be taken to list-enclose names which contain brackets. \section{Scripting IRSIM Command Sequences} A consequence of placing IRSIM in an interpreter environment is the ability to use interpreter features such as variables, conditionals, and loops to set up complicated simulation environments. \section{Deterministic Bit Vector Generation} A convenience function has been added to Tcl-IRSIM to aid in generating deterministic sequences of inputs. This is the command \starti \ii {\bstf bconvert} {\itshape value} {\itshape bits} [{\itshape dir}] \endi where {\itshape value} is an integer decimal value, {\itshape bits} is the length of the bit vector to hold the conversion, and {\itshape dir} is an optional direction flag. If {\itshape dir} is 1, then the bit vector is defined with the most significant bit (MSB) on the right. The {\bstf bconvert} command returns the string value of the bit vector containing {\ttfamily 0} and {\ttfamily 1} characters. For example: \starti \ii {\itshape \%} {\bstf bconvert 20 5} \\ \ii {\ttfamily 10100} \\ \ii {\itshape \%} {\bstf bconvert 20 5 1} \\ \ii {\ttfamily 00101} \endi \section{Random Bit Vector Generation} The tutorial examples are small by design, but real systems (such as a microprocessor) are often so complex that generating and simulating an exhaustive set of all possible states of the circuit is impossible, and instead simulations rely on the generation of a set of randomly-generated inputs to test a representative set of states. Random number generation is not a built-in feature of the Tcl language, but several open-source packages exist, one of which has been incorporated into the IRSIM 9.6 source. The pseudorandom number generator is compiled as a separate Tcl package, but is loaded by the IRSIM startup script. It contains one command, {\bstf random}, with the following arguments: \starti \ii {\bstf random} {\itshape option} \endi where {\itshape option} may be one of: \begin{itemize} \item [] {\bstf -reset} will cause the generator to be reseeded using current pid and current time. \item [] {\bstf -seed} {\itshape n} will reseed the generator with the integer value {\itshape n}. \item [] {\bstf -integer} {\itshape ...} will cause the number returned to be rounded down to the largest integer less than or equal to the number which would otherwise be returned. \item [] {\bstf -normal} {\itshape m s} will cause the number returned to be taken from a gaussian with mean {\itshape m} and standard deviation {\itshape s}. \item [] {\bstf -exponential} {\itshape m} will cause the number returned to be taken from an exponential distribution with mean {\itshape m}. \item [] {\bstf -uniform} {\itshape low high} will cause the number returned to be taken from uniform distribution on {\itshape [a,b)}. \item [] {\bstf -chi2} {\itshape n} will cause the number returned to be taken from the chi2 distribution with {\itshape n} degrees of freedom. \item [] {\bstf -select} {\itshape n list} will cause {\itshape n} elements to be selected at random from the list {\itshape list} with replacement. \item [] {\bstf -choose} {\itshape n list} will cause {\itshape n} elements to be selected at random from the list {\itshape list} without replacement. \item [] {\bstf -permutation} {\itshape n} will return a permutation of $0\dots n-1$ if {\itshape n} is a number and will return a permutation of its elements if {\itshape n} is a list. \end{itemize} The following script clocks a random serial bit vector into a state machine, assuming that {\bstf bit\_in} is the node to set, and that the proper clock vectors have already been set up: \starti \ih for \{set i 0\} \{\$i < 100\} \{incr i\} \{ \\ \ii if \{[random] < 0.5\} \{ \\ \ij l bit\_in \\ \ii \} else \{ \\ \ij h bit\_in \\ \ii \} \\ \ii c \\ \ih \} \endi \end{document} magic-8.0.210/doc/latexfiles/tutscm1.tex0000644000175000001440000006037710751423606016522 0ustar timusers%---------------------------------------------------------------------------- % Magic tutorial number S-1 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\q{\special{ps:(") show}\hspace*{0.6em}} \def\mytitle{Magic Tutorial \#S-1: The scheme command-line interpreter} \def\bk{\special{ps:/bksp 2 string def bksp 0 92 put bksp show}\hspace*{0.4em}} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape Rajit Manohar} \\ \vspace*{0.5in} Department of Computer Science \\ California Institute of Technology \\ Pasadena, CA 91125 \\ \vspace*{0.25in} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Tutorials to read first:} \starti \> Read reference \cite{sussman} \endi {\noindent\bfseries\large Commands introduced in this tutorial:} \starti \> :scm-echo-result, :eval, lots of scheme functions \endi {\noindent\bfseries\large Macros introduced in this tutorial:} \starti \> {\itshape (None)} \endi \vspace*{0.75in} \section{Introduction} Magic's original command-line interpreter has some limitations. Some of these include the absence of definitions with arguments, block structure, the ability to define complex functions. We describe an extension which is almost completely backward compatible with the existing magic command-line syntax, but permits the use of Scheme on the command-line. \section{Backward compatibility} To permit existing magic source files to work within the scheme interpreter, we have had to sacrifice one feature of the magic command-line syntax. Single quotes can only be used to quote a single character. The reason for this limitation is that {\itshape unmatched} quotes are used by scheme to stop evaluation of the next input symbol. Parentheses are used by the scheme interpreter. If you use parentheses outside single or double quotes in your magic source files, you might find that the source files don't work properly. To circumvent this problem, simply put your parentheses in double quotes. You can also use backslashes to quote parentheses as in: \starti \ii {\bfseries :macro {\bk}( {\q}echo hello{\q}} \endi Another thing you may notice is that floating-point numbers are parsed as such, and therefore a command such as \starti \ii {\bfseries :echo 5.3} \endi would display the string {\bfseries 5.300000}. If you really want the string {\bfseries 5.3}, use: \starti \ii {\bfseries :echo {\q}5.3{\q}} \endi If this difference is undesirable, the scheme interpreter can be turned off at compile-time. Talk to your local magic maintainer if you want this done. We feel that the minor trouble taken in modifying existing magic source files will be outweighed by the advantage of using a more powerful layout language. \section{The scheme interpreter} The interpreter supports a subset of the scheme language. The features of scheme that are missing include character types, vector types, file input/output, complex numbers, the distinction between exact and inexact arithmetic, quasi-quotations, and continuations. \subsection{Command-line interaction} When interacting with the command-line of magic, the interpreter implicitly parenthesizes its input. For example, the command \starti \ii {\bfseries :paint poly} \endi would be interpreted as the scheme expression \starti \ii {\bfseries (paint poly)} \endi This has exactly the same effect as the original expression, because all existing magic command-line functions are also scheme functions. Since the valid magic commands vary from window to window, the return value of the function is a boolean that indicates whether the command was valid for the current window. The boolean {\bfseries scm-echo-result} controls whether or not the result of the evaluation is displayed. If the variable does not exist, or the variable is not boolean-valued, the result of evaluation is not echoed. Since the input is implicitly parenthesized, typing in \starti \ii {\bfseries :scm-echo-result} \endi would not display the value of the variable, since it would be evaluated as: \starti \ii {\bfseries (scm-echo-result)} \endi To display the value of a variable, use the built-in procedure {\bfseries eval} as follows: \starti \ii {\bfseries :eval scm-echo-result} \endi This would result in the expression: \starti \ii {\bfseries (eval scm-echo-result)} \endi which would have the desired effect (note that for this to actually display anything, the value of {\bfseries scm-echo-result} must be {\bfseries \#t}, and so examining its value is really a futile exercise---which is why it is an example, of course!). \subsection{Types of arguments} Since scheme expressions are typed, we may need to examine the type of a particular expression. The following functions return booleans, and can be used to determine the type of an object. {\bfseries \#t} and {\bfseries \#f} are constants representing the booleans true and false. A standard scheme convention is to name functions that return booleans with a name ending with ``?''. The built-in functions conform to this convention. The expression {\itshape expr} is evaluated, and the type of the result of evaluation is checked. \begin{center} \begin{tabular}{|l|l|} \hline {\bfseries (boolean?} {\itshape expr}{\bfseries )} & {\bfseries \#t} if {\itshape expr} is a boolean \\ \hline {\bfseries (symbol?} {\itshape expr}{\bfseries )} & {\bfseries \#t} if {\itshape expr} is a symbol \\ \hline {\bfseries (list?} {\itshape expr}{\bfseries )} & {\bfseries \#t} if {\itshape expr} is a list \\ \hline {\bfseries (pair?} {\itshape expr}{\bfseries )} & {\bfseries \#t} if {\itshape expr} is a pair \\ \hline {\bfseries (number?} {\itshape expr}{\bfseries )} & {\bfseries \#t} if {\itshape expr} is a number \\ \hline {\bfseries (string?} {\itshape expr}{\bfseries )} & {\bfseries \#t} if {\itshape expr} is a string \\ \hline {\bfseries (procedure?} {\itshape expr}{\bfseries )} & {\bfseries \#t} if {\itshape expr} is a procedure \\ \hline \end{tabular} \end{center} For example, \starti \ii {\bfseries (boolean? \#t)}{\itshape $=>$ \#t} \\ \ii {\bfseries (number? \#t)}{\itshape $=>$ \#f} \endi \subsection{Lists and pairs} A pair is a record structure with two fields, called the car and cdr fields (for historical reasons). Pairs are used primarily to represent lists. A list can be defined recursively as either the empty list, or a pair whose cdr field is a list. The following functions are used to extract these fields and to construct new pairs and lists. \begin{center} \begin{tabular}{|l|l|} \hline {\bfseries (car} {\itshape pair}{\bfseries )} & the car field of {\itshape pair} \\ \hline {\bfseries (cdr} {\itshape pair}{\bfseries )}& the cdr field {\itshape pair} \\ \hline {\bfseries (cons} {\itshape obj1 obj2}{\bfseries )} & a new pair whose car field is {\itshape obj1} and cdr field is {\itshape obj2} \\ \hline {\bfseries (list} {\itshape arg1 \dots}{\bfseries )} & a new list consisting of its arguments \\ \hline {\bfseries (null?} {\itshape list}{\bfseries )} & {\bfseries \#t} if {\itshape list} is the empty list \\ \hline {\bfseries (length} {\itshape list}{\bfseries )} & the number of elements in {\itshape list} \\ \hline \end{tabular} \end{center} For example, \starti \ii {\bfseries (car '(a b c))}{\itshape =$>$ a} \\ \ii {\bfseries (cdr '(a b c))}{\itshape =$>$ (b c)} \\ \ii {\bfseries (cons 'a '(b c))}{\itshape =$>$ (a b c)} \\ \ii {\bfseries (list 'a 'b 'c)}{\itshape =$>$ (a b c)} \\ \ii {\bfseries (null? '(a b))}{\itshape =$>$ \#f} \\ \ii {\bfseries (null? ())}{\itshape =$>$ \#t} \endi The car field and cdr field of a pair can be set using the following two functions. \begin{center} \begin{tabular}{|l|l|} \hline {\bfseries (set-car!} {\itshape pair obj}{\bfseries )} & sets the car field of {\itshape pair} to {\itshape obj}. It returns the new pair \\ \hline {\bfseries (set-cdr!} {\itshape pair obj}{\bfseries )} & sets the cdr field of {\itshape pair} to {\itshape obj}. It returns the new pair \\ \hline \end{tabular} \end{center} These two functions have {\itshape side-effects}, another feature that distinguishes scheme from pure lisp. Another naming convention followed is that functions that have side-effects end in ``!''. Try the following sequence in magic: \starti \ii {\bfseries (define x '(a b))}{\itshape =$>$ (a b)} \\ \ii {\bfseries (set-car! x 'c)}{\itshape =$>$ (c b)} \\ \ii {\bfseries (set-cdr! x '(q))}{\itshape =$>$ (c q)} \\ \ii {\bfseries (set-cdr! x 'q)}{\itshape =$>$ (c . q)} \\ \endi After the last statement, the value of x is no longer a list but a pair. \subsection{Arithmetic} The interpreter supports both floating-point and integer arithmetic. The basic arithmetic functions are supported. \begin{center} \begin{tabular}{|l|l|} \hline {\bfseries (+ }{\itshape num1 num2}{\bfseries )} & the sum {\itshape num1}+{\itshape num2} \\ \hline {\bfseries (- }{\itshape num1 num2}{\bfseries )} & the difference {\itshape num1}-{\itshape num2} \\ \hline {\bfseries (* }{\itshape num1 num2}{\bfseries )} & the product {\itshape num1}*{\itshape num2} \\ \hline {\bfseries (/ }{\itshape num1 num2}{\bfseries )} & the quotient {\itshape num1}/{\itshape num2} \\ \hline {\bfseries (truncate }{\itshape num}{\bfseries )} & the integer part of {\itshape num} \\ \hline \end{tabular} \end{center} The division operator checks for division by zero, and promotes integers to floating-point if deemed necessary. Floating-point numbers can be converted into integers by truncation. The range of a number can be checked using the following predicates: \begin{center} \begin{tabular}{|l|l|} \hline {\bfseries (zero? }{\itshape num}{\bfseries )} & {\bfseries \#t} if {\itshape num} is zero \\ \hline {\bfseries (positive? }{\itshape num}{\bfseries )} & {\bfseries \#t} if {\itshape num} is positive \\ \hline {\bfseries (negative? }{\itshape num}{\bfseries )} & {\bfseries \#t} if {\itshape num} is negative \\ \hline \end{tabular} \end{center} \subsection{Strings} The interpreter supports string manipulation. String manipulation can be useful for interaction with the user as well as constructing names for labels. \begin{center} \begin{tabular}{|l|p{0.6\columnwidth}|} \hline {\bfseries (string-append }{\itshape str1 str2}{\bfseries )} & the string formed by concatenating {\itshape str1} and {\itshape str2} \\ \hline {\bfseries (string-length }{\itshape str}{\bfseries )} & the length of string {\itshape str} \\ \hline {\bfseries (string-compare }{\itshape str1 str2}{\bfseries )} & a positive, zero, or negative number depending on whether {\itshape str1} is lexicographically greater, equal to, or less than {\itshape str2} \\ \hline {\bfseries (string-ref }{\itshape str int}{\bfseries )} & the numerical value of the character stored at position {\itshape int} in {\itshape str} (The first character is at position 0.) \\ \hline {\bfseries (string-set! }{\itshape str int1 int2}{\bfseries )} & sets character in string {\itshape str} at position {\itshape int1} to {\itshape int2} \\ \hline {\bfseries (substring }{\itshape str int1 int2}{\bfseries )} & returns substring of {\itshape str} from position {\itshape int1} (inclusive) to {\itshape int2} (exclusive) \\ \hline \end{tabular} \end{center} Strings can be used to convert to and from various types. \begin{center} \begin{tabular}{|l|l|} \hline {\bfseries (number-$>$string }{\itshape num}{\bfseries )} & the string corresponding to the representation of {\itshape num} \\ \hline {\bfseries (string-$>$number }{\itshape str}{\bfseries )} & the number corresponding to {\itshape str} \\ \hline {\bfseries (string-$>$symbol }{\itshape str}{\bfseries )} & a symbol named {\itshape str} \\ \hline {\bfseries (symbol$->$string }{\itshape sym}{\bfseries )} & the string corresponding to the name of {\itshape sym} \\ \hline \end{tabular} \end{center} \subsection{Bindings and functions} An object (more accurately, the {\itshape location} where the object is stored) can be bound to a symbol using the following two functions: \begin{center} \begin{tabular}{|l|l|} \hline {\bfseries (define }{\itshape sym expr}{\bfseries )} & bind {\itshape expr} to {\itshape sym}, creating a new symbol if necessary and return {\itshape expr} \\ \hline {\bfseries (set! }{\itshape sym expr}{\bfseries )} & bind {\itshape expr} to an existing symbol {\itshape sym} and return {\itshape expr} \\ \hline \end{tabular} \\ (Note: these functions do not evaluate their first argument.) \end{center} The difference between the two is that {\bfseries define} introduces a new binding, whereas {\bfseries set!} modifies an existing binding. In both cases, {\itshape expr} is evaluated, and the result is bound to the symbol {\itshape sym}. The result of the evaluation is also returned. \starti \ii {\bfseries (define x 4)}{\itshape $=>$ 4} \endi Functions can be defined using lambda expressions. Typically a function is bound to a variable. If required, a lambda expression or built-in function can be applied to a list. \begin{center} \begin{tabular}{|l|l|} \hline {\bfseries (lambda }{\itshape list obj}{\bfseries )} & a new function \\ \hline \end{tabular} \\ (Note: a lambda does not evaluate its arguments.) \end{center} {\itshape list} is a list of symbol names, and {\itshape obj} is the expression that corresponds to the body of the function. For example, \starti \ii {\bfseries (lambda (x y z) (+ (+ x y) z))}{\itshape $=>$ \#proc} \endi is a function that takes three arguments and returns their sum. It can be bound to a symbol using {\bfseries define}. \starti \ii {\bfseries (define sum3 (lambda (x y z) (+ (+ x y) z)))}{\itshape $=>$ \#proc} \endi Now, we can use {\bfseries sum3} like any other function. \starti \ii {\bfseries (sum3 5 3 8)}{\itshape $=>$ 16} \endi A function can be applied to a list using {\bfseries apply}. \begin{center} \begin{tabular}{|l|l|} \hline {\bfseries (apply }{\itshape proc list}{\bfseries )} & apply {\itshape proc} to {\itshape list} \\ \hline \end{tabular} \\ (Note: both {\itshape proc} and {\itshape list} are evaluated before application.) \end{center} {\itshape list} is used as the list of arguments for the function. For instance, an alternative way to sum the three numbers in the example above is: \starti \ii {\bfseries (apply sum3 '(3 5 8))}{\itshape $=>$ 16} \endi An alternative method for creating bindings is provided by the {\bfseries let} mechanism. \begin{center} \begin{tabular}{|l|l|} \hline {\bfseries (let }{\itshape binding-list expr}{\bfseries )} & evaluate {\itshape expr} after the bindings have been performed \\ \hline {\bfseries (let* }{\itshape binding-list expr}{\bfseries )} & evaluate {\itshape expr} after the bindings have been performed \\ \hline {\bfseries (letrec }{\itshape binding-list expr}{\bfseries )} & evaluate {\itshape expr} after the bindings have been performed \\ \hline \end{tabular} \end{center} The {\itshape binding-list} is a list of bindings. Each binding is a list containing a symbol and an expression. The expression is evaluated and bound to the symbol. In the case of {\bfseries let}, all the expressions are evaluated before binding them to any symbol; {\bfseries let*}, on the other hand, evaluates an expression and binds it to the symbol before evaluating the next expression. {\bfseries letrec} permits bindings to refer to each other, permitting mutually recursive function definitions. The evaluation order is defined to be from left to right in all cases. After performing the bindings, {\itshape expr} is evaluated with the new bindings in effect and the result is returned. {\bfseries let} bindings can be used in interesting ways. An example of their use is provided later. Scheme is an eager language, and only a few functions do not evaluate all their arguments (definitions and conditionals). Evaluation can be controlled to some degree using the following two functions: \begin{center} \begin{tabular}{|l|l|} \hline {\bfseries (quote }{\itshape obj}{\bfseries )} & the unevaluated object {\itshape obj} \\ \hline {\bfseries (eval }{\itshape obj}{\bfseries )} & evaluates object {\itshape obj} \\ \hline \end{tabular} \end{center} \subsection{Control structures} Since scheme is a functional programming language, functions that are usually written using loops are written using recursion. Conditional constructs are used to terminate the recursion. These constructs are slightly different in that they do not evaluate all their arguments (otherwise recursive functions would not terminate!). \begin{center} \begin{tabular}{|l|l|} \hline {\bfseries (if }{\itshape expr arg1 arg2}{\bfseries )} & evaluate {\itshape expr} and evaluate one of {\itshape arg1} or {\itshape arg2} \\ \hline \end{tabular} \end{center} The {\bfseries if} construct evaluates its first argument (which must result in a boolean), and if the result is {\bfseries \#t} evaluates {\itshape arg1} and returns the result; otherwise {\itshape arg2} is evaluated and returned. For instance, the standard factorial function might be written as: \starti \ii {\bfseries (define fact (lambda (x) (if (positive? x) (* x (fact (- x 1))) 1)))} \endi A more complicated form of conditional behavior is provided by {\bfseries cond}. \begin{center} \begin{tabular}{|l|l|} \hline {\bfseries (cond }{\itshape arg1 arg2 ...}{\bfseries )} & generalized conditional \\ \hline \end{tabular} \end{center} Each argument consists of a list which contains two expressions. The first expression is evaluated (and must evaluate to a boolean), and if it is true the second expression is evaluated and returned as the result of the entire expression. If the result was false, the next argument is examined and the above procedure is repeated. If all arguments evaluate to false, the result is undefined. For instance if {\bfseries x} was a list, the expression \starti \ii {\bfseries (cond ((null? x) x) ((list? x) (car x)) (\#t (echo {\q}error{\q})))} \endi would return the empty list if {\bfseries x} was the empty list and the first element from the list otherwise. When {\bfseries x} is not a list, an error message is displayed. Note that {\bfseries echo} is a standard magic command. Often one needs to evaluate a number of expressions in sequence (since the language has side-effects). The {\bfseries begin} construct can be used for this purpose. \begin{center} \begin{tabular}{|l|l|} \hline {\bfseries (begin }{\itshape arg1 arg2 \dots}{\bfseries )} & sequencing construct \\ \hline \end{tabular} \end{center} {\bfseries begin} evaluates each of its arguments in sequence, and returns the result of evaluating its last argument. \subsection{Interaction with layout} All standard magic commands are also scheme functions. This permits one to write scheme functions that interact with the layout directly. Apart from the standard magic commands, the following scheme functions are provided so as to enable the user to edit layout. \begin{center} \begin{tabular}{|l|p{0.6\columnwidth}|} \hline {\bfseries (getbox)} & a list containing four members (llx lly urx ury) \\ \hline {\bfseries (getpaint }{\itshape str}{\bfseries )} & a list containing the boxes from layer {\itshape str} under the current box that have paint in them \\ \hline {\bfseries (getlabel }{\itshape str}{\bfseries )} & a list containing the labels under the current box that match {\itshape str} \\ \hline {\bfseries (magic }{\itshape sym}{\bfseries )} & forces {\itshape sym} to be interpreted as a magic command \\ \hline \end{tabular} \end{center} The pairs (llx,lly) and (urx,ury) correspond to magic coordinates for the lower left and upper right corner of the current box. {\bfseries getpaint} returns a list of boxes (llx lly urx ury), and {\bfseries getlabel} returns a list of tagged boxes (label llx lly urx ury) which contain the label string. {\bfseries magic} can be used to force the scheme interpreter to interpret a symbol as a magic procedure. The evaluation returns the specified magic command. \subsection{Miscellaneous} Some additional functions are provided to enable the user to debug functions. \begin{center} \begin{tabular}{|l|l|} \hline {\bfseries (showframe)} & display the current list of bindings \\ \hline {\bfseries (display-object }{\itshape obj}{\bfseries )} & display the type and value of {\itshape obj} \\ \hline {\bfseries (error }{\itshape str}{\bfseries )} & display error message and abort evaluation \\ \hline {\bfseries (eqv? }{\itshape obj1 obj2}{\bfseries )} & checks if two objects are equal \\ \hline {\bfseries (collect-garbage)} & force garbage collection \\ \hline \end{tabular} \end{center} The following is a complete list of the built-in scheme variables that can be used to control the interpreter. \begin{center} \begin{tabular}{|l|p{0.6\columnwidth}|} \hline {\bfseries scm-library-path} & a colon-separated path string \\ \hline {\bfseries scm-echo-result} & a boolean used to determine if the result of evaluation should be displayed \\ \hline {\bfseries scm-trace-magic} & controls display of actual magic commands \\ \hline {\bfseries scm-echo-parser-input} & controls display of the string sent to the scheme parser \\ \hline {\bfseries scm-echo-parser-output} & controls display of the result of parsing \\ \hline {\bfseries scm-stack-display-depth} & controls the number of frames displayed in the stack trace output when an error occurs during evaluation \\ \hline {\bfseries scm-gc-frequency} & controls the frequency of garbage collection \\ \hline \end{tabular} \end{center} \subsection{Libraries} The following function loads in a file and evaluates its contents in order. \begin{center} \begin{tabular}{|l|l|} \hline {\bfseries (load-scm }{\itshape str}{\bfseries )} & reads scheme commands in from the named file \\ \hline {\bfseries (save-scm }{\itshape str obj}{\bfseries )} & appends {\itshape obj} to the file {\itshape str}, creating a new file if necessary \\ \hline \end{tabular} \end{center} The file can be in the current directory, or in any of the locations specified by a string containing a colon-separated list of directory names stored in {\bfseries scm-library-path}. The format of these files differs from standard magic source files because the contents of a line are not implicitly parenthesized. In addition, semicolons are used as a comment character; everything following a semicolon to the end of the current line is treated as a comment. For instance, \starti \ii {\bfseries define f (lambda (x) x)} \endi would define {\bfseries f} to be the identity function when placed in a magic source file (so as to provide backward compatibility). The same definition would result in an error if placed in a scheme source file. \starti \ii {\bfseries (define f (lambda (x) x))} \endi The above expression should be used in the scheme file to achieve the same effect. \begin{thebibliography}{2} \bibitem{sussman} H. Abelson and G.J. Sussman, \newblock {\itshape Structure and Interpretation of Computer Programs}. \bibitem{abelson} H. Abelson {\itshape et al.}, \newblock {\itshape Revised Report on the Algorithmic Language Scheme}. \end{thebibliography} \end{document} magic-8.0.210/doc/latexfiles/tut10.tex0000644000175000001440000005334010751423606016067 0ustar timusers%---------------------------------------------------------------------------- % Magic tutorial number 10 %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} \def\hinch{\hspace*{0.5in}} \def\starti{\begin{center}\begin{tabbing}\hinch\=\hinch\=\hinch\=hinch\hinch\=\kill} \def\endi{\end{tabbing}\end{center}} \def\ii{\>\>\>} \def\mytitle{Magic Tutorial \#10: The Interactive Router} %---------------------------------------------------------------------------- \begin{document} \makeatletter \newcommand{\ps@magic}{% \renewcommand{\@oddhead}{\mytitle\hfil\today}% \renewcommand{\@evenhead}{\today\hfil\mytitle}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \newcommand{\ps@mplain}{% \renewcommand{\@oddhead}{}% \renewcommand{\@evenhead}{}% \renewcommand{\@evenfoot}{\hfil\textrm{--{\thepage}--}\hfil}% \renewcommand{\@oddfoot}{\@evenfoot}} \makeatother \pagestyle{magic} \thispagestyle{mplain} \begin{center} {\bfseries \Large \mytitle} \\ \vspace*{0.5in} {\itshape Michael Arnold} \\ \vspace*{0.5in} O Division \\ Lawrence Livermore National Laboratory \\ Livermore, CA 94550 \\ \vspace*{0.25in} This tutorial corresponds to Magic version 7. \\ \end{center} \vspace*{0.5in} {\noindent\bfseries\large Tutorials to read first:} \starti \> Magic Tutorial \#1: Getting Started \\ \> Magic Tutorial \#2: Basic Painting and Selection \\ \> Magic Tutorial \#4: Cell Hierarchies \endi {\noindent\bfseries\large Commands introduced in this tutorial:} \starti \> :iroute \endi {\noindent\bfseries\large Macros introduced in this tutorial:} \starti \> \^{}R, \^{}N \endi \vspace*{0.25in} \section{Introduction} The Magic interactive router, {\itshape Irouter}, provides an interactive interface to Magic's internal maze router. It is intended as an aid to manual routing. Routing is done one connection at a time, the user specifying a starting point and destination areas prior to each connection. The user determines the order in which signals are routed and how multi-point nets are decomposed into point-to-area connections. In addition parameters and special Magic {\itshape hint} layers permit the user to control the nature of the routes. Typically the user determines the overall path of a connection, and leaves the details of satisfying the design-rules, and detouring around or over minor obstacles, to the router. The interactive router is not designed for fully automatic routing: interactions between nets are not considered, and net decomposition is not automatic. Thus netlists are generally not suitable input for the Irouter. However it can be convenient to obtain endpoint information from netlists. The {\itshape Net2ir} program uses netlist information to generate commands to the Irouter with appropriate endpoints for specified signals. Typically a user might setup parameters and hints to river-route a set of connections, and then generate Irouter commands with the appropriate endpoints via Net2ir. For details on Net2ir see the manual page {\itshape net2ir(1)}. This tutorial provides detailed information on the use of the Irouter. On-line help, Irouter subcommands, Irouter parameters, and hint-layers are explained. \section{Getting Started---`Cntl-R', `Cntl-N', `:iroute' and `:iroute help'} To make a connection with the Irouter, place the cursor over one end of the desired connection (the {\itshape start-point}) and the box at the other end (the {\itshape destination-area}). Then type \starti \ii {\bfseries Cntl-R} \endi Note that the box must be big enough to allow the route to terminate entirely within it. A design-rule correct connection between the cursor and the box should appear. The macro \starti \ii {\bfseries Cntl-R} \endi and the long commands \starti \ii {\bfseries :iroute} \\ \ii {\bfseries :iroute route} \endi are all equivalent. They invoke the Irouter to connect the cursor with the interior of the box. Note that the last connection is always left selected. This allows further terminals to be connected to the route with the second Irouter macro, {\bfseries Cntl-N}. Try typing \starti \ii {\bfseries Cntl-N} \endi A connection between the cursor and the previous route should appear. In general {\bfseries Cntl-N} routes from the cursor to the selection. There are a number of commands to set parameters and otherwise interact with the Irouter. These commands have the general form \starti \ii {\bfseries :iroute}{\itshape subcommand }[{\itshape arguments}] \endi For a list of subcommands and a short description of each, type \starti \ii {\bfseries :iroute help} \endi Usage information on a subcommand can be obtained by typing \starti \ii {\bfseries :iroute help }[{\itshape subcommand}] \endi As with Magic in general, unique abbreviations of subcommands and most of their arguments are permitted. Case is generally ignored. \section{:Undo and Cntl-C} As with other Magic commands, the results of {\bfseries :iroute} can be undone with {\bfseries :undo}, and if the Irouter is taking too long it can be interrupted with {\bfseries Cntl-C}. This makes it easy to refine the results of the Irouter by trial and error. If you don't like the results of a route, undo it, tweak the Irouter parameters or hints you are using and try again. If the Irouter is taking too long, you can very likely speed things up by interrupting it, resetting performance related parameters, and trying again. The details of parameters and hints are described later in this document. \section{More about Making Connections---`:iroute route'} Start points for routes can be specified via the cursor, labels, or coordinates. Destination areas can be specified via the box, labels, coordinates or the selection. In addition start and destination layers can be specified explicitly. For the syntax of all these options type \starti \ii {\bfseries :iroute help route} \endi When a start point lies on top of existing geometry it is assumed that a connection to that material is desired. If this is not the case, the desired starting layer must be explicitly specified. When routing to the selection it is assumed that connection to the selected material is desired. By default, routes to the box may terminate on any active route layer. If you are having trouble connecting to a large region, it may be because the connection point or area is too far in the interior of the region. Try moving it toward the edge. (Alternately see the discussion of the {\itshape penetration} parameter in the wizard section below.) \section{Hints} Magic has three built-in layers for graphical control of the Irouter, {\bfseries fence} ({\bfseries f}), {\bfseries magnet} ({\bfseries mag}), and {\bfseries rotate} ({\bfseries r}). These layers can be painted and erased just like other Magic layers. The effect each has on the Irouter is described below. \subsection{The Fence Layer} The Irouter won't cross fence boundaries. Thus the fence layer is useful both for carving out routing-regions and for blocking routing in given areas. It is frequently useful to indicate the broad path of one or a series of routes with fence. In addition to guiding the route, the use of fences can greatly speed up the router by limiting the search. \subsection{The Magnet Layer} Magnets attract the route. They can be used to pull routes in a given direction, e.g., towards one edge of a channel. Over use of magnets can make routing slow. In particular magnets that are long and far away from the actual route can cause performance problems. (If you are having problems with magnets and performance, see also the discussion of the {\itshape penalty} parameter in the wizard section below.) \subsection{The Rotate Layer} The Irouter associates different weights with horizontal and vertical routes (see the layer-parameter section below). This is so that a preferred routing direction can be established for each layer. When two good route-layers are available (as in a two-layer-metal process) interference between routes can be minimized by assigning opposite preferred directions to the layers. The rotate layer locally inverts the preferred directions. An example use of the rotate layer might involve an {\bfseries L}-shaped bus. The natural preferred directions on one leg of the {\bfseries L} are the opposite from the other, and thus one leg needs to be marked with the rotate layer. \section{Subcells} As with painting and other operations in Magic, the Irouter's output is written to the cell being edited. What the router sees, that is which features act as obstacles, is determined by the window the route is issued to (or other designated reference window - see the wizard section.) The contents of subcells expanded in the route window are visible to the Irouter, but it only sees the bounding boxes of unexpanded subcells. These bounding boxes appear on a special {\bfseries SUBCELL} pseudo-layer. The spacing parameters to the {\bfseries SUBCELL} layer determine exactly how the Irouter treats unexpanded subcells. (See the section on spacing parameters below.) By default, the spacings to the {\bfseries SUBCELL} layer are large enough to guarantee that no design-rules will be violated, regardless of the contents of unexpanded subcells. Routes can be terminated at unexpanded subcells in the same fashion that connections to other pre-existing features are made. \section{Layer Parameters---`:iroute layers'} {\itshape Route-layers}, specified in the {\bfseries mzrouter} section of the technology file, are the layers potentially available to the Irouter for routing. The {\bfseries layer} subcommand gives access to parameters associated with these route-layers. Many of the parameters are weights for factors in the Irouter cost-function. The Irouter strives for the cheapest possible route. Thus the balance between the factors in the cost-function determines the character of the routes: which layers are used in which directions, and the number of contacts and jogs can be controlled in this way. But be careful! Changes in these parameters can also profoundly influence performance. Other parameters determine which of the route-layers are actually available for routing and the width of routes on each layer. It is a good idea to inactivate route-layers not being used anyway, as this speeds up routing. The layers subcommand takes a variable number of arguments. \starti \ii {\bfseries :iroute layers} \endi prints a table with one row for each route-layer giving all parameter values. \starti \ii {\bfseries :iroute layers}{\itshape type} \endi prints all parameters associated with route-layer {\itshape type}. \starti \ii {\bfseries :iroute layers}{\itshape type parameter} \endi prints the value of {\itshape parameter} for layer {\itshape type}. If {\itshape type} is `{\bfseries *}', the value of {\itshape parameter} is printed for all layers. \starti \ii {\bfseries :iroute layers} {\itshape type parameter value} \endi sets {\itshape parameter} to {\itshape value} on layer {\itshape type}. If {\itshape type} is `{\bfseries *}', {\itshape parameter} is set to {\itshape value} on all layers. \starti \ii {\bfseries :iroute layers} {\itshape type} {\bfseries *} {\itshape value1 value2 }\dots{\itshape valuen} \endi sets a row in the parameter table. \starti \ii {\bfseries :iroute layers *}{\itshape parameter value1 \dots valuen} \endi sets a column in the table. There are six layer parameters. \begin{itemize} \item {\bfseries active} \\ Takes the value of {\bfseries YES} (the default) or {\bfseries NO}. Only active layers are used by the Irouter. \item {\bfseries width} \\ Width of routing created by the Irouter on the given layer. The default is the minimum width permitted by the design rules. \item {\bfseries hcost} \\ Cost per unit-length for horizontal segments on this layer. \item {\bfseries vcost} \\ Cost per unit-length for vertical segments. \item {\bfseries jogcost} \\ Cost per jog (transition from horizontal to vertical segment). \item {\bfseries hintcost} \\ Cost per unit-area between actual route and magnet segment. \end{itemize} \section{Contact Parameters---`:iroute contacts'} The {\bfseries contacts} subcommand gives access to a table of parameters for contact-types used in routing, one row of parameters per type. The syntax is identical to that of the {\bfseries layers} subcommand described above, and parameters are printed and set in the same way. There are three contact-parameters. \begin{itemize} \item {\bfseries active} \\ Takes the value of {\bfseries YES} (the default) or {\bfseries NO}. Only active contact types are used by the Irouter. \item {\bfseries width} \\ Diameter of contacts of this type created by the Irouter. The default is the minimum width permitted by the design-rules. \item {\bfseries cost} \\ Cost per contact charged by the Irouter cost-function. \end{itemize} \section{Spacing Parameters---`:iroute spacing'} The spacing parameters specify minimum spacings between the route-types (route-layers and route-contacts) and arbitrary Magic types. These spacings are the design-rules used internally by the Irouter during routing. Default values are derived from the {\bfseries drc} section of the technology file. These values can be overridden in the {\bfseries mzrouter} section of the technology file. (See the {\itshape Magic Maintainers Manual on Technology Files} for details.) Spacings can be examined and changed at any time with the {\bfseries spacing} subcommand. Spacing values can be {\bfseries nil}, {\bfseries 0}, or positive integers. A value of {\bfseries nil} means there is no spacing constraint between the route-layer and the given type. A value of {\bfseries 0} means the route-layer may not overlap the given type. If a positive value is specified, the Irouter will maintain the given spacing between new routing on the specified route-layer and pre-existing features of the specified type (except when connecting to the type at an end-point of the new route). The {\bfseries spacing} subcommand takes several forms. \starti \ii {\bfseries :iroute spacing} \endi prints spacings for all route-types. (Nil spacings are omitted.) \starti \ii {\bfseries :iroute spacing} {\itshape route-type} \endi prints spacings for {\itshape route-type}. (Nil spacings are omitted.) \starti \ii {\bfseries :iroute spacing} {\itshape route-type type} \endi prints the spacing between {\itshape route-type} and {\itshape type}. \starti \ii {\bfseries :iroute spacing} {\itshape route-type type value} \endi sets the spacing between {\itshape route-type} and {\itshape type} to {\itshape value}. The spacings associated with each route-type are the ones that are observed when the Irouter places that route-type. To change the spacing between two route-types, two spacing parameters must be changed: the spacing to the first type when routing on the second, and the spacing to the second type when routing on the first. Spacings to the {\bfseries SUBCELL} pseudo-type give the minimum spacing between a route-type and unexpanded subcells. The {\bfseries SUBCELL} spacing for a given route-layer defaults to the maximum spacing to the route-layer required by the design-rules (in the {\bfseries drc} section of the technology file). This ensures that no design-rules will be violated regardless of the contents of the subcell. If subcell designs are constrained in a fashion that permits closer spacings to some layers, the {\bfseries SUBCELL} spacings can be changed to take advantage of this. \section{Search Parameters---`:search'} The Mzrouter search is windowed. Early in the search only partial paths near the start point are considered; as the search progresses the window is moved towards the goal. This prevents combinatorial explosion during the search, but still permits the exploration of alternatives at all stages. The {\bfseries search} subcommand permits access to two parameters controlling the windowed search, {\bfseries rate}, and {\bfseries width}. The {\bfseries rate} parameter determines how fast the window is shifted towards the goal, and the {\bfseries width} parameter gives the width of the window. The units are comparable with those used in the cost parameters. If the router is taking too long to complete, try increasing {\bfseries rate}. If the router is choosing poor routes, try decreasing {\bfseries rate}. The window width should probably be at least twice the rate. The subcommand has this form: \starti \ii {\bfseries :iroute search} [{\itshape parameter}] [{\itshape value}] \endi If {\itshape value} is omitted, the current value is printed, if {\itshape parameter} is omitted as well, both parameter values are printed. \section{Messages---`:iroute verbosity'} The number of messages printed by the Irouter is controlled by \starti \ii {\bfseries :iroute verbosity}{\itshape value} \endi If verbosity is set to {\bfseries 0}, only errors and warnings are printed. A value of {\bfseries 1} (the default) results in short messages. A value of {\bfseries 2} causes statistics to be printed. \section{Version---`:iroute version'} The subcommand \starti \ii {\bfseries :iroute version} \endi prints the Irouter version in use. \section{Saving and Restoring Parameters---`:iroute save'} The command \starti \ii {\bfseries :iroute save} {\itshape file}{\bfseries .ir} \endi saves away the current settings of all the Irouter parameters in file {\itshape file}{\bfseries .ir}. Parameters can be reset to these values at any time with the command \starti \ii {\bfseries :source} {\itshape file}{\bfseries .ir} \endi This feature can be used to setup parameter-sets appropriate to different routing contexts. Note that the extension {\bfseries .ir} is recommended for Irouter parameter-files. \section{Wizard Parameters---`:iroute wizard'} Miscellaneous parameters that are probably not of interest to the casual user are accessed via the {\bfseries wizard} subcommand. The parameters are as follows: \begin{itemize} \item {\bfseries bloom} Takes on a non-negative integer value. This controls the amount of compulsory searching from a focus, before the next focus is picked based on the cost-function and window position. In practice {\bfseries 1} (the default value) seems to be the best value. This parameter may be removed in the future. \item {\bfseries boundsIncrement} Takes on the value {\bfseries AUTOMATIC} or a positive integer. Determines in what size chunks the layout is preprocessed for routing. This preprocessing (blockage generation) takes a significant fraction of the routing time, thus performance may well be improved by experimenting with this parameter. \item {\bfseries estimate} Takes on a boolean value. If {\bfseries ON} (the default) an estimation plane is generated prior to each route that permits cost-to-completion estimates to factor in subcells and fence regions. This can be very important to efficient routing. Its rarely useful to turn estimation off. \item {\bfseries expandDests} Takes on a boolean value. If {\bfseries ON} (not the default) destination areas are expanded to include all of any nodes they overlap. This is particularly useful if the Irouter is being invoked from a script, since it is difficult to determine optimal destination areas automatically. \item {\bfseries penalty} Takes on a rational value (default is 1024.0). It is not strictly true that the router searches only within its window. Paths behind the window are also considered, but with cost penalized by the product of their distance to the window and the penalty factor. It was originally thought that small penalties might be desirable, but experience, so far, has shown that large penalties work better. In particular it is important that the ratio between the actual cost of a route and the initial estimate is less than the value of {\bfseries penalty}, otherwise the search can explode (take practically forever). If you suspect this is happening, you can set {\bfseries verbosity} to {\bfseries 2} to check, or just increase the value of {\bfseries penalty}. In summary it appears that the value of penalty doesn't matter much as long as it is large (but not so large as to cause overflows). It will probably be removed in the future. \item {\bfseries penetration} This parameter takes the value {\bfseries AUTOMATIC} or a positive integer. It determines how far into a blocked area the router will penetrate to make a connection. Note however the router will in no case violate spacing constraints to nodes not involved in the route. \item {\bfseries window} This parameter takes the value {\bfseries COMMAND} (the default) or a window id (small integers). It determines the reference window for routes. The router sees the world as it appears in the reference window, e.g., it sees the contents of subcells expanded in the reference window. If {\bfseries window} is set to {\bfseries COMMAND} the reference window is the one that contained the cursor when the route was invoked. To set the reference window to a fixed window, place the cursor in that window and type: \starti \ii {\bfseries :iroute wizard window .} \endi \end{itemize} \begin{thebibliography}{1} \bibitem{arnold} M.H. Arnold and W.S. Scott, \newblock ``An Interactive Maze Router with Hints'', \newblock {\itshape Proceedings of the 25th Design Automation Conference}, \newblock June 1988, pp. 672--676. \end{thebibliography} \end{document} magic-8.0.210/doc/latexfiles/copyright.tex0000644000175000001440000000263010751423606017116 0ustar timusers%---------------------------------------------------------------------------- % Magic copyright %---------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1994/12/01] \documentclass[letterpaper,twoside,12pt]{article} \usepackage{epsfig,times} \setlength{\textwidth}{8.5in} \addtolength{\textwidth}{-2.0in} \setlength{\textheight}{11.0in} \addtolength{\textheight}{-2.0in} \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0pt} \setlength{\topmargin}{-0.5in} \setlength{\headheight}{0.2in} \setlength{\headsep}{0.3in} \setlength{\topskip}{0pt} %---------------------------------------------------------------------------- \begin{document} \pagestyle{empty} \begin{center} \vspace*{6.0in} Copyright \copyright 1985, 1989, 1990 Regents of the University of California, \\ Lawrence Livermore National Labs, Stanford University, and Digital \\ Equipment Corporation. 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 appears in all \\ copies. The copyright holders make 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. \end{center} \end{document} magic-8.0.210/doc/psfigures/0000755000175000001440000000000011504623573014234 5ustar timusersmagic-8.0.210/doc/psfigures/maint2.4.ps0000644000175000001440000001673610751423606016147 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.4.ps %%Creator: Xcircuit v2.0 %%CreationDate: Tue Apr 18 11:22:46 2000 %%Pages: 1 %%BoundingBox: 68 68 712 297 %%DocumentNeededResources: font Helvetica %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 1056 334 offsets 1.0000 inchscale 2.6000 setlinewidth 0.490 0.651 0.980 scb 240 1.00 800 270 800 718 1312 718 1312 270 4 polygon 240 1.00 1504 334 1504 654 1888 654 1888 334 4 polygon 240 1.00 192 334 192 654 320 654 320 334 4 polygon 240 1.00 448 334 448 654 576 654 576 334 4 polygon sce 0 1.00 192 334 192 654 320 654 320 334 4 polygon 0 1.00 448 334 448 654 576 654 576 334 4 polygon 0 1.00 1504 334 1504 654 1888 654 1888 334 4 polygon 0 1.00 800 270 800 718 1312 718 1312 270 4 polygon 2 1.00 864 334 864 654 992 654 992 334 4 polygon 2 1.00 1120 334 1120 654 1248 654 1248 334 4 polygon 2 1.00 1504 334 1504 654 1632 654 1632 334 4 polygon 2 1.00 1760 334 1760 654 1888 654 1888 334 4 polygon 1 1.00 784 654 704 654 2 polygon 1 1.00 784 718 704 718 2 polygon 1 1.00 736 638 736 590 2 polygon 1 1.00 736 734 736 782 2 polygon 1.00 0 736 654 arrowhead 1.00 -181 736 718 arrowhead (100) {/Helvetica 1.000 cf} 2 21 0 736 686 label (\(a\)) {/Helvetica 1.000 cf} 2 21 0 352 206 label (\(b\)) {/Helvetica 1.000 cf} 2 21 0 1056 206 label (\(c\)) {/Helvetica 1.000 cf} 2 21 0 1696 206 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/tut9.1.ps0000644000175000001440000002043510751423606015646 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: tut9.1.ps %%Creator: Xcircuit v2.0 %%CreationDate: Fri Apr 14 15:43:22 2000 %%Pages: 1 %%BoundingBox: 68 68 403 447 %%DocumentNeededResources: font Helvetica %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /dot { % -10 -10 20 20 bbox begingate 248 1.00 0 0 6 0.00 360.00 xcarc endgate } def /cifwire { % -272 -32 400 64 bbox begingate 0.490 0.651 0.980 scb 96 -32 beginpath 96 0 32 -90.00 90.00 arc -240 32 1 polyc -240 0 32 90.00 270.00 arc 96 -32 1 polyc 241 1.00 endpath sce 1 1.00 -240 0 96 0 2 polygon 1.00 0 96 0 dot 1.00 0 -240 0 dot 96 -32 beginpath 96 0 32 -90.00 90.00 arc -240 32 1 polyc -240 0 32 90.00 270.00 arc 96 -32 1 polyc 1 1.00 endpath endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 800 1038 offsets % 32.00 8.00 gridspace 1.0000 inchscale 2.6000 setlinewidth 0.800 0.800 0.800 scb 241 1.00 672 302 800 302 1056 430 1056 558 928 686 736 654 672 590 672 302 8 polygon sce 0.490 0.651 0.980 scb 241 1.00 192 302 320 302 576 430 576 558 448 686 256 654 192 590 192 302 8 polygon sce 0.616 0.624 0.925 scb 241 1.00 672 302 864 302 864 366 928 366 928 430 1056 430 1056 558 992 558 992 622 928 622 928 686 864 686 864 622 672 622 672 302 15 polygon sce 0.490 0.651 0.980 scb 240 1.00 688 862 800 862 800 926 864 926 864 990 928 990 928 1054 992 1054 992 1182 928 1182 928 1118 864 1118 864 1054 800 1054 800 990 736 990 736 926 688 926 18 polygon sce 1.00 45 464 1070 cifwire 0 1.00 688 862 800 862 800 926 864 926 864 990 928 990 928 1054 992 1054 992 1182 928 1182 928 1118 864 1118 864 1054 800 1054 800 990 736 990 736 926 688 926 18 polygon 1 1.00 720 894 768 894 768 958 832 958 832 1022 896 1022 896 1086 960 1086 960 1150 9 polygon 1.00 0 960 1150 dot 1.00 0 720 894 dot 1 1.00 192 302 320 302 576 430 576 558 448 686 256 654 192 590 192 302 8 polygon 0.490 0.651 0.980 scb 241 1.00 800 302 864 302 864 334 800 302 4 polygon 240 1.00 672 590 704 622 672 622 3 polygon 240 1.00 864 678 928 686 864 686 3 polygon sce 1 1.00 672 302 864 302 864 366 928 366 928 430 1056 430 1056 558 992 558 992 622 928 622 928 686 864 686 864 622 672 622 672 302 15 polygon (CIF Wire) {/Helvetica 1.000 cf} 2 21 0 320 782 label (Resulting Magic Shape) {/Helvetica 1.000 cf} 2 21 0 864 782 label (CIF Polygon) {/Helvetica 1.000 cf} 2 21 0 352 206 label (Resulting Magic Shape) {/Helvetica 1.000 cf} 2 21 0 864 206 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/maint2.8.ps0000644000175000001440000001675610751423606016155 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.8.ps %%Creator: Xcircuit v2.0 %%CreationDate: Tue Apr 18 11:46:16 2000 %%Pages: 1 %%BoundingBox: 68 68 604 369 %%DocumentNeededResources: font Helvetica font Helvetica-Bold %%+ font Helvetica-Oblique %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 928 590 offsets 1.0000 inchscale 2.6000 setlinewidth 1.000 0.000 0.000 scb 240 1.00 832 270 832 590 1184 590 1184 270 4 polygon 240 1.00 1248 654 1248 974 1600 974 1600 654 4 polygon 240 1.00 192 270 192 590 320 590 320 270 4 polygon sce 0 1.00 320 270 320 590 512 590 512 270 4 polygon (space) {/Helvetica-Bold 1.000 cf} 2 21 0 416 430 label (poly) {/Helvetica-Bold 1.000 cf} 2 21 0 256 430 label (poly) {/Helvetica-Bold 1.000 cf} (= not ) {/Helvetica 1.000 cf} (OKTypes ) {/Helvetica-Oblique 1.000 cf} 6 25 0 416 686 label 1 1.00 416 670 416 558 2 polygon 1.00 -181 416 542 arrowhead (\(a\)) {/Helvetica 1.000 cf} 2 21 0 416 206 label 0 1.00 832 270 832 590 1184 590 1184 270 4 polygon 0 1.00 1248 654 1248 974 1600 974 1600 654 4 polygon 1 1.00 832 590 832 782 1184 782 1184 590 1376 590 1376 270 1184 270 7 polygon 1 1.00 1600 654 1600 462 1248 462 1248 654 1056 654 1056 974 1248 974 7 polygon (poly) {/Helvetica-Bold 1.000 cf} 2 21 0 1424 830 label (poly) {/Helvetica-Bold 1.000 cf} 2 21 0 992 430 label (\(b\)) {/Helvetica 1.000 cf} 2 21 0 1216 206 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/tut2.2.ps0000644000175000001440000001417110751423606015640 0ustar timusers%!PS-Adobe-2.0 EPSF-1.2 %%Title: tut2.2.ps %%CreationDate: %%DocumentFonts: Helvetica %%Pages: 1 %%BoundingBox: 190 28 420 764 %%EndComments /INIT { 72 exch div dup dup scale div exch findfont exch scalefont /TxFont exch def /BoxOutline exch def /#copies exch def TxFont dup /FontBBox get exch /FontMatrix get exch aload pop 4 index transform /bbhi exch def pop 3 -1 roll transform /bblow exch def /bbx exch def /bbhi bbhi bblow sub def /nChars matrix defaultmatrix 0 get abs 72 8.5 mul mul 64 div ceiling cvi def 1 1 dtransform abs dup 1 exch div /onePix exch def dup /resY exch def 1 exch div /iresY exch def abs dup /resX exch def 1 exch div /iresX exch def /bX 64 iresX mul def /bY 64 iresY mul def /pattFont StipplePattern definefont pop /patterns /pattFont findfont [iresX 64 mul 0 0 iresY 64 mul 0 0] makefont def /CA nChars 1 add string def } def /StipplePattern 45 dict def StipplePattern begin /FontType 3 def /FontMatrix [1 0 0 1 0 0] def /FontBBox [0 0 1 1] def /Encoding 256 array def /PattName (P0) def /tmpStr 1 string def /NoPatt {<00>} def 0 1 255 { Encoding exch /NoPatt put } for /BuildChar { 1 0 0 0 1 1 setcachedevice exch begin Encoding exch get load 64 64 true [64 0 0 64 0 0] 5 -1 roll imagemask end } def end /DefPatt { StipplePattern begin dup 30 tmpStr cvrs PattName exch 1 exch putinterval PattName cvn dup Encoding exch 4 -1 roll exch put exch store end } def /HEADER { 4 onePix mul add moveto show } def /SL { 0 1 nChars { exch dup 3 1 roll CA 3 1 roll put } for pop } def /SC { 0 1 nChars { exch dup 3 1 roll CA 3 1 roll put } for 4 mul colors exch 4 getinterval aload pop setcmykcolor } def /SP { patterns setfont 2 setlinewidth } def /ST { TxFont setfont onePix 2 mul setlinewidth } def /V { newpath moveto 0 exch rlineto stroke } def /H { newpath moveto 0 rlineto stroke } def /B { /h exch def /w exch def /y exch def /x exch def gsave newpath x y moveto w y lineto w h lineto x h lineto closepath clip x resX mul cvi 63 not and dup iresX mul exch w resX mul sub abs 63 add cvi 64 idiv /w exch def y resY mul cvi 63 not and dup iresY mul exch h resY mul sub abs 63 add cvi 64 idiv /h exch def /CH CA 0 w getinterval def moveto h { CH gsave show grestore 0 bY rmoveto } repeat grestore } def /L { gsave newpath dup bblow add 2 index bbx add exch moveto 0 bbhi rlineto 2 index stringwidth pop bbx abs 2 mul add 0 rlineto 0 bbhi neg rlineto closepath 1.0 setgray fill grestore moveto show } def /BB { /h exch def /w exch def /y exch def /x exch def grestore gsave newpath x y moveto w y lineto w h lineto x h lineto closepath BoxOutline 1 eq { gsave stroke grestore } if clip } def /BS { 4 copy BB exch pop exch pop exch bbhi add exch bbhi sub onePix sub L } def /MSAV { /Mstat save def } def /MRES { Mstat restore } def %%EndProlog %%Page: 1 1 {<000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c00000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0>} 0 DefPatt {<000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c00000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0>} 1 DefPatt {<00000000000000000c0c0c0c0c0c0c0c000000000000000000000000000000000000000000000000c0c0c0c0c0c0c0c000000000000000000000000000000000>} 5 DefPatt {<00000000000000000c0c0c0c0c0c0c0c000000000000000000000000000000000000000000000000c0c0c0c0c0c0c0c000000000000000000000000000000000>} 6 DefPatt {} 8 DefPatt {<8383838383838383c1c1c1c1c1c1c1c1e0e0e0e0e0e0e0e0707070707070707038383838383838381c1c1c1c1c1c1c1c0e0e0e0e0e0e0e0e0707070707070707>} 9 DefPatt {<8181818181818181c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3818181818181818118181818181818183c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c1818181818181818>} 11 DefPatt {} 16 DefPatt /colors [0.18 0.37 0.43 0.00 0.87 0.12 0.87 0.00 0.00 0.00 0.00 0.75 0.12 0.43 0.12 0.00 0.12 0.43 1.00 0.00 0.25 0.37 0.75 0.00 1.00 0.25 1.00 0.00 0.00 0.00 0.00 0.50 0.87 0.18 0.87 0.00 0.00 1.00 1.00 0.00 0.00 0.00 1.00 0.00 0.75 0.50 0.00 0.00 0.37 0.87 0.25 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.75 0.75 0.50 0.25 0.00 ] def 1 1 /Helvetica 10.0 300.000000 INIT % ST (tutcell.cif Scale: 0.212766 \(5404X\) Size: 14 x 47 microns ) 828 3150 HEADER SP 828 150 translate 0 SC 1532 0 0 V 894 0 0 H 1532 894 0 V 894 0 1532 H 0 0 894 1532 B 1 SC 1404 0 1596 V 894 0 1596 H 1404 894 1596 V 894 0 3000 H 0 1596 894 3000 B 5 SC 1022 191 1787 V 511 191 1787 H 1022 702 1787 V 511 191 2809 H 191 1787 702 2809 B 6 SC 1149 191 191 V 511 191 191 H 1149 702 191 V 511 191 1340 H 191 191 702 1340 B 8 SC 894 319 319 V 766 319 1915 V 383 511 574 V 319 319 511 1213 B 256 511 2170 V 319 1915 511 2681 B 255 319 319 H 255 574 319 V 63 511 574 H 511 319 574 574 B 63 511 957 H 256 574 957 V 255 319 1213 H 511 957 574 1213 B 255 319 1915 H 255 574 1915 V 63 511 2170 H 511 1915 574 2170 B 63 511 2426 H 255 574 2426 V 255 319 2681 H 511 2426 574 2681 B 9 SC 128 0 702 V 128 0 2234 V 702 0 702 H 128 702 702 V 702 0 830 H 0 702 702 830 B 766 0 2234 H 128 766 2234 V 766 0 2362 H 0 2234 766 2362 B 11 SC 192 0 319 V 192 0 2489 V 319 0 511 H 0 319 319 511 B 63 319 511 V 1213 319 957 V 63 319 2426 V 319 0 2489 H 0 2489 319 2681 B 63 574 511 V 255 319 574 H 319 319 574 574 B 255 319 957 H 511 574 957 V 447 574 1723 V 255 319 2170 H 319 957 574 2170 B 255 319 2426 H 63 574 2426 V 319 2426 574 2681 B 894 0 319 H 192 894 319 V 320 574 511 H 574 319 894 511 B 320 574 1468 H 255 894 1468 V 320 574 1723 H 574 1468 894 1723 B 320 574 2489 H 192 894 2489 V 894 0 2681 H 574 2489 894 2681 B 16 SC 128 383 383 V 128 383 1021 V 127 383 1979 V 128 383 2489 V 128 383 383 H 128 511 383 V 128 383 511 H 383 383 511 511 B 128 383 1021 H 128 511 1021 V 128 383 1149 H 383 1021 511 1149 B 128 383 1979 H 127 511 1979 V 128 383 2106 H 383 1979 511 2106 B 128 383 2489 H 128 511 2489 V 128 383 2617 H 383 2489 511 2617 B ST gsave % (tutcell1) 0 0 894 3000 BS % 0 0 894 3000 BB grestore showpage %%Trailer magic-8.0.210/doc/psfigures/maint2.2.ps0000644000175000001440000001721410751423606016135 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.2.ps %%Creator: Xcircuit v2.0 %%CreationDate: Tue Apr 18 11:16:25 2000 %%Pages: 1 %%BoundingBox: 68 68 856 261 %%DocumentNeededResources: font Helvetica %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /tiles { % -304 -188 608 380 bbox begingate 1 1.00 176 64 176 -96 2 polygon 1 1.00 -176 64 -176 -96 2 polygon 1 1.00 -16 64 -16 192 2 polygon (A) {/Helvetica 1.000 cf} 2 21 0 -16 -16 label (C) {/Helvetica 1.000 cf} 2 21 0 224 -16 label (B) {/Helvetica 1.000 cf} 2 23 0 -240 -16 label (D) {/Helvetica 1.000 cf} 2 29 0 -16 -160 label 1 1.00 -304 -96 304 -96 2 polygon 1 1.00 -304 64 304 64 2 polygon endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 992 398 offsets 1.0000 inchscale 2.6000 setlinewidth 0.745 0.600 0.871 scb 241 1.00 1744 606 1744 350 2240 350 2240 606 1744 606 5 polygon 241 1.00 1008 654 1008 350 1504 350 1504 654 1008 654 5 polygon 240 1.00 480 654 272 654 272 350 768 350 768 606 480 606 6 polygon sce 1 1.00 480 654 272 654 272 350 768 350 768 606 480 606 6 polygon 1.00 0 496 494 tiles 1.00 0 1232 494 tiles 1.00 0 1968 494 tiles 1 1.00 1008 654 1008 350 1504 350 1504 654 1008 654 5 polygon 1 1.00 1744 606 1744 350 2240 350 2240 606 1744 606 5 polygon (E) {/Helvetica 1.000 cf} 2 21 0 368 622 label (B) {/Helvetica 1.000 cf} 2 25 0 624 622 label (E) {/Helvetica 1.000 cf} 2 29 0 1104 638 label (B) {/Helvetica 1.000 cf} 2 29 0 1376 638 label (E) {/Helvetica 1.000 cf} 2 25 0 1840 622 label (B) {/Helvetica 1.000 cf} 2 25 0 2080 622 label (bloat-or A * 100 C,E 200) {/Helvetica 1.000 cf} 2 21 0 512 206 label (bloat-max A * 100 C,E 200) {/Helvetica 1.000 cf} 2 21 0 1248 206 label (bloat-min A * 100 C,E 200) {/Helvetica 1.000 cf} 2 21 0 2000 206 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/maint2.11.ps0000644000175000001440000001561510751423606016220 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.11.ps %%Creator: Xcircuit v2.0 %%CreationDate: Tue Apr 18 12:05:00 2000 %%Pages: 1 %%BoundingBox: 68 68 292 268 %%DocumentNeededResources: font Helvetica-Oblique %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 672 288 offsets 1.0000 inchscale 2.6000 setlinewidth 0.490 0.651 0.980 scb 240 1.00 320 480 320 704 608 704 608 480 4 polygon sce 0.745 0.600 0.871 scb 240 1.00 192 192 192 320 768 320 768 192 4 polygon sce 1 1.00 320 704 320 480 608 480 608 704 4 polygon 1 1.00 192 192 192 320 768 320 768 192 4 polygon (tfar) {/Helvetica-Oblique 1.000 cf} 2 21 0 464 592 label (fartypes) {/Helvetica-Oblique 1.000 cf} 2 24 0 336 496 label (neartypes) {/Helvetica-Oblique 1.000 cf} 2 28 0 336 464 label (outtypes) {/Helvetica-Oblique 1.000 cf} 2 24 0 240 336 label (intypes) {/Helvetica-Oblique 1.000 cf} 2 28 0 240 304 label (tinside) {/Helvetica-Oblique 1.000 cf} 2 21 0 448 224 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/maint2.7.ps0000644000175000001440000002104510751423606016137 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.7.ps %%Creator: Xcircuit v2.0 %%CreationDate: Tue Apr 18 11:32:42 2000 %%Pages: 1 %%BoundingBox: 68 68 412 400 %%DocumentNeededResources: font Helvetica-Oblique %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 704 544 offsets 1.0000 inchscale 2.6000 setlinewidth 0.745 0.600 0.871 scb 240 1.00 832 736 832 1056 1024 1056 1024 736 4 polygon 240 1.00 256 256 256 448 576 448 576 256 4 polygon 240 1.00 256 736 256 1056 448 1056 448 736 4 polygon 240 1.00 704 256 704 448 1024 448 1024 256 4 polygon sce 0 1.00 256 736 256 1056 448 1056 448 736 4 polygon 0 1.00 832 736 832 1056 1024 1056 1024 736 4 polygon 0 1.00 256 256 256 448 576 448 576 256 4 polygon 0 1.00 704 256 704 448 1024 448 1024 256 4 polygon 1 1.00 192 896 320 896 2 polygon 1 1.00 1088 896 960 896 2 polygon 1 1.00 416 192 416 320 2 polygon 1 1.00 864 512 864 384 2 polygon 1.00 0 416 336 arrowhead 1.00 -181 864 368 arrowhead 1.00 -271 944 896 arrowhead 1.00 270 336 896 arrowhead (t1) {/Helvetica-Oblique 1.000 cf} 2 25 0 224 928 label (t2) {/Helvetica-Oblique 1.000 cf} 2 25 0 288 928 label (t1) {/Helvetica-Oblique 1.000 cf} 2 25 0 1056 928 label (t2) {/Helvetica-Oblique 1.000 cf} 2 25 0 976 928 label (t1) {/Helvetica-Oblique 1.000 cf} 2 25 0 896 480 label (t2) {/Helvetica-Oblique 1.000 cf} 2 25 0 896 400 label (t1) {/Helvetica-Oblique 1.000 cf} 2 25 0 368 208 label (t2) {/Helvetica-Oblique 1.000 cf} 2 25 0 368 288 label (d) {/Helvetica-Oblique 1.000 cf} 2 21 0 352 688 label 1 1.00 256 720 256 672 2 polygon 1 1.00 448 720 448 672 2 polygon (d) {/Helvetica-Oblique 1.000 cf} 2 21 0 928 688 label 1 1.00 832 720 832 672 2 polygon 1 1.00 1024 720 1024 672 2 polygon (d) {/Helvetica-Oblique 1.000 cf} 2 21 0 208 352 label 1 1.00 240 448 192 448 2 polygon 1 1.00 240 256 192 256 2 polygon (d) {/Helvetica-Oblique 1.000 cf} 2 21 0 1072 352 label 1 1.00 1088 448 1040 448 2 polygon 1 1.00 1088 256 1040 256 2 polygon 1 1.00 1072 384 1072 432 2 polygon 1 1.00 1072 320 1072 272 2 polygon 1 1.00 208 384 208 432 2 polygon 1 1.00 208 320 208 272 2 polygon 1 1.00 272 688 320 688 2 polygon 1 1.00 384 688 432 688 2 polygon 1 1.00 848 688 896 688 2 polygon 1 1.00 960 688 1008 688 2 polygon 1.00 0 208 448 arrowhead 1.00 0 1072 448 arrowhead 1.00 -181 1072 256 arrowhead 1.00 -181 208 256 arrowhead 1.00 -271 256 688 arrowhead 1.00 -271 832 688 arrowhead 1.00 -91 1024 688 arrowhead 1.00 -91 448 688 arrowhead pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/tutw1.2.ps0000644000175000001440000001555610751423606016036 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: tutw1.2.ps %%Creator: Xcircuit v2.0 %%CreationDate: Fri Apr 14 16:35:19 2000 %%Pages: 1 %%BoundingBox: 68 68 331 211 %%DocumentNeededResources: font Times-Roman %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 576 260 offsets 1.0000 inchscale 2.6000 setlinewidth 0.439 1.000 0.314 scb 240 1.00 192 196 192 548 704 548 704 196 4 polygon sce (minarea) {/Times-Roman 1.000 cf} 2 21 0 448 372 label 0 1.00 192 196 192 548 704 548 704 196 4 polygon (minedge) {/Times-Roman 1.000 cf} 2 20 0 736 372 label 1 1.00 720 548 800 548 2 polygon 1 1.00 720 196 800 196 2 polygon 1 1.00 768 532 768 404 2 polygon 1 1.00 768 340 768 212 2 polygon 1.00 0 768 548 arrowhead 1.00 -181 768 196 arrowhead pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/tutcell.cif0000644000175000001440000000172010751423606016371 0ustar timusers( @@user : tim ); ( @@machine : stravinsky.jhuapl.edu ); ( @@source : tutcell1.mag ); ( @@tool : Magic 7.1 ); ( @@patch : 0 ); ( @@patchnames : release-6.5b1, linux1, solaris1, SU-WRL-extract, WRL-DRC-X, UNC-CIF-X ); ( @@compiled : Tue Apr 11 16:16:29 EDT 2000 ); ( @@technology : scmos ); ( @@version : 8.2.8 ); ( @@techdesc : MOSIS Scalable CMOS Technology for Standard Rules ); ( @@style : lambda=1.0(gen) ); ( @@date : Wed Apr 12 16:25:21 2000 ); DS 1 50 2; 9 tutcell1; L CWN; B 56 88 32 124; L CWP; B 56 96 32 28; L CMF; B 56 12 32 142; B 16 4 32 134; B 16 28 32 102; B 36 16 42 80; B 16 32 32 56; B 16 4 32 14; B 56 12 32 6; L CPG; B 48 8 28 124; B 44 8 26 28; L CAA; B 16 16 32 140; B 12 16 30 124; B 16 16 32 108; B 16 16 32 48; B 12 24 30 28; B 16 16 32 8; L CCA; B 8 8 32 140; B 8 8 32 108; B 8 8 32 48; B 8 8 32 8; L CSN; B 32 72 32 28; L CSP; B 32 64 32 124; DF; C 1; End magic-8.0.210/doc/psfigures/maint2.3.ps0000644000175000001440000001731510751423606016140 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.3.ps %%Creator: Xcircuit v2.0 %%CreationDate: Tue Apr 18 11:18:51 2000 %%Pages: 1 %%BoundingBox: 68 68 304 253 %%DocumentNeededResources: font Helvetica-Oblique %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrowhead90 { % -20 -12 36 24 bbox begingate 1.00 90 -16 0 arrowhead endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 800 460 offsets 1.0000 inchscale 2.6000 setlinewidth 0.753 0.333 0.502 scb 240 1.00 224 300 224 556 608 556 608 300 4 polygon sce 0 1.00 224 300 224 556 608 556 608 300 4 polygon 240 1.00 256 332 256 396 320 396 320 332 4 polygon 240 1.00 256 460 256 524 320 524 320 460 4 polygon 240 1.00 384 332 384 396 448 396 448 332 4 polygon 240 1.00 384 460 384 524 448 524 448 460 4 polygon 240 1.00 512 332 512 396 576 396 576 332 4 polygon 240 1.00 512 460 512 524 576 524 576 460 4 polygon 1 1.00 320 572 320 620 2 polygon 1 1.00 384 572 384 620 2 polygon 1 1.00 624 332 672 332 2 polygon 1 1.00 624 300 672 300 2 polygon 1 1.00 256 316 256 236 2 polygon 1 1.00 320 316 320 236 2 polygon 1 1.00 256 604 304 604 2 polygon 1 1.00 400 604 448 604 2 polygon 1 1.00 656 348 656 396 2 polygon 1 1.00 656 284 656 220 2 polygon 1 1.00 336 252 384 252 2 polygon 1 1.00 240 252 192 252 2 polygon 1.00 0 336 252 arrowhead90 1.00 0 400 604 arrowhead90 1.00 -1 304 604 arrowhead90 1.00 -1 240 252 arrowhead90 1.00 -91 656 348 arrowhead90 1.00 270 656 284 arrowhead90 (separation) {/Helvetica-Oblique 1.000 cf} 2 25 0 352 636 label (size) {/Helvetica-Oblique 1.000 cf} 2 29 0 288 220 label (border) {/Helvetica-Oblique 1.000 cf} 2 20 0 688 316 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/tut8.1.ps0000644000175000001440000002152310751423606015644 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: tut8.1 %%Creator: Xcircuit v2.0 %%CreationDate: Fri Apr 14 14:46:45 2000 %%Pages: 1 %%BoundingBox: 68 68 246 247 %%DocumentNeededResources: font Times-Roman font Times-Bold font Times-Italic %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /resistor { % -14 -64 28 128 bbox begingate % fundamental 1 1.00 0 64 0 36 2 polygon 1 1.00 0 -64 0 -36 2 polygon 1 1.00 0 -36 14 -30 -14 -18 14 -6 -14 6 14 18 -14 30 0 36 8 polygon 1.000 0.000 0.000 scb (r.1) {/Times-Roman 1.000 cf} 2 9 0 0 64 pinlabel (r.2) {/Times-Roman 1.000 cf} 2 13 0 0 -64 pinlabel sce (spice:R%i %pr.1 %pr.2 1.0K) {/Times-Roman 1.000 cf} 2 0 0 -208 -160 infolabel (sim:r %pr.1 %pr.2) {/Times-Roman 1.000 cf} 2 0 0 -208 -208 infolabel endgate } def /capacitor { % -32 -64 64 128 bbox begingate % fundamental 1 1.00 0 -64 0 -6 2 polygon 1 1.00 0 64 0 6 2 polygon 1 1.00 -32 6 32 6 2 polygon 1 1.00 -32 -6 32 -6 2 polygon 1.000 0.000 0.000 scb (c.1) {/Times-Roman 1.000 cf} 2 9 0 0 64 pinlabel (c.2) {/Times-Roman 1.000 cf} 2 13 0 0 -64 pinlabel sce (spice:C%i %pc.1 %pc.2 1.0P) {/Times-Roman 1.000 cf} 2 0 0 -208 -160 infolabel (sim:c %pc.1 %pc.2) {/Times-Roman 1.000 cf} 2 0 0 -208 -208 infolabel endgate } def /circle { % -6 -12 28 24 bbox begingate 1 1.00 16 0 6 0.00 360.00 xcarc 1 1.00 0 0 10 0 2 polygon 1.000 0.000 0.000 scb (out) {/Times-Roman 1.000 cf} 2 4 0 16 0 pinlabel (out) {/Times-Roman 1.000 cf} 2 7 0 0 0 pinlabel sce endgate } def /gnd { % -32 -60 64 68 bbox begingate 1 1.00 0 0 0 -32 2 polygon 1 1.00 -32 -32 32 -32 2 polygon 1 1.00 -18 -46 18 -46 2 polygon 1 1.00 -4 -60 4 -60 2 polygon 1.000 0.000 0.000 scb (GND) {/Times-Roman 1.000 cf} 2 1 0 0 0 pinglobal sce endgate } def /dot { % -10 -10 20 20 bbox begingate 248 1.00 0 0 6 0.00 360.00 xcarc endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 430 412 offsets 1.0000 inchscale 2.6000 setlinewidth 1.00 0 430 508 resistor 1.00 315 504 486 resistor 1.00 270 526 412 resistor 1.00 270 334 412 resistor 1.00 0 430 316 capacitor 1 1.00 430 380 430 444 2 polygon 1 1.00 398 412 462 412 2 polygon 1 1.00 430 412 462 444 2 polygon 1.00 0 590 412 circle 1.00 45 550 532 circle 1.00 90 430 572 circle 1.00 180 270 412 circle (C) {/Times-Italic 1.000 cf} 2 20 0 478 316 label (/2) {/Times-Roman 1.000 cf} (R) {/Times-Italic 1.000 cf} 4 29 0 526 388 label (1) {/Times-Roman 1.000 cf} 2 20 0 630 412 label (2) {/Times-Roman 1.000 cf} 2 24 0 574 556 label (3) {/Times-Roman 1.000 cf} 2 25 0 430 620 label (N) {/Times-Italic 1.000 cf} 2 23 0 222 412 label (/2) {/Times-Roman 1.000 cf} (R) {/Times-Italic 1.000 cf} 4 29 0 334 388 label (/2) {/Times-Roman 1.000 cf} (R) {/Times-Italic 1.000 cf} 4 28 0 526 484 label (/2) {/Times-Roman 1.000 cf} (R) {/Times-Italic 1.000 cf} 4 23 0 398 540 label 1.00 0 430 252 gnd 1.00 0 430 412 dot (.) {/Times-Bold 1.000 cf} 2 21 0 364 486 label (.) {/Times-Bold 1.000 cf} 2 21 0 387 506 label (.) {/Times-Bold 1.000 cf} 2 21 0 350 460 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/tut2.1.ps0000644000175000001440000002023610751423606015636 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%BoundingBox: 72 72 540 560 %%DocumentNeededResources: font /Helveticafont /HelveticaBold %%EndComments %%BeginProlog % % PostScript prolog for output from magic plot % Version: 1.0 % written by Tim Edwards 4/05/00 JHU Applied Physics Laboratory % %%BeginResource: procset MAGICproc 1.0 1 % supporting definitions /MAGICsave save def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /minit { /nChars matrix defaultmatrix 0 get abs 72 8.5 mul mul 64 div ceiling cvi def 1 1 dtransform abs dup 1 exch div /onePix exch def dup /resY exch def 1 exch div /iresY exch def abs dup /resX exch def 1 exch div /iresX exch def /bX 64 iresX mul def /bY 64 iresY mul def /pattFont StipplePattern definefont pop /patterns /pattFont findfont [iresX 64 mul 0 0 iresY 64 mul 0 0] makefont def /ca nChars 1 add string def } def /StipplePattern 45 dict def StipplePattern begin /FontType 3 def /FontMatrix [1 0 0 1 0 0] def /FontBBox [0 0 1 1] def /Encoding 256 array def /PattName (P0) def /tmpStr 1 string def /NoPatt {<00>} def 0 1 255 { Encoding exch /NoPatt put } for /BuildChar { 1 0 0 0 1 1 setcachedevice exch begin Encoding exch get load 64 64 true [64 0 0 64 0 0] 5 -1 roll imagemask end } def end /dp { StipplePattern begin dup 30 tmpStr cvrs PattName exch 1 exch putinterval PattName cvn dup Encoding exch 4 -1 roll exch put exch store end } def /sf { findfont exch scalefont setfont } bind def /sp { patterns setfont 2 setlinewidth } def /lb { gsave translate 0 0 moveto /just exch def gsave dup true charpath flattenpath pathbbox grestore exch 4 -1 roll exch sub 3 1 roll sub just 4 and 0 gt {just 8 and 0 eq {0.5 mul} if}{pop 0} ifelse exch just 1 and 0 gt {just 2 and 0 eq {0.5 mul} if}{pop 0} ifelse exch rmoveto show grestore } def /sl { 0 1 nChars { exch dup 3 1 roll ca 3 1 roll put } for pop } def /sc { setcmykcolor } bind def /l1 { onePix setlinewidth } def /l2 { onePix 2 mul setlinewidth } def /l3 { onePix 3 mul setlinewidth } def /ml { moveto lineto stroke } bind def /vl { moveto 0 exch rlineto stroke } bind def /hl { moveto 0 rlineto stroke } bind def /mr { rectstroke } bind def /mx { 4 copy rectstroke 4 -1 roll 4 -1 roll 4 copy moveto rlineto stroke 3 -1 roll dup neg 4 1 roll add moveto rlineto stroke } bind def /pl { gsave translate /d exch def 0 d neg moveto 0 d lineto stroke d neg 0 moveto d 0 lineto stroke grestore } bind def /fb {/h exch def /w exch def /y exch def /x exch def gsave newpath x y moveto w y lineto w h lineto x h lineto closepath clip x resX mul cvi 63 not and dup iresX mul exch w resX mul sub abs 63 add cvi 64 idiv /w exch def y resY mul cvi 63 not and dup iresY mul exch h resY mul sub abs 63 add cvi 64 idiv /h exch def /ch ca 0 w getinterval def moveto h { ch gsave show grestore 0 bY rmoveto } repeat grestore } def /f1 { 1.440 /Helvetica sf } def /f2 { 0.960 /HelveticaBold sf } def /f3 { 0.640 /Helvetica sf } def /col17 {0.090 0.686 0.718 0.000 sc} bind def /col16 {0.435 0.592 0.957 0.000 sc} bind def /col15 {0.749 0.498 0.247 0.000 sc} bind def /col14 {0.000 0.000 0.000 255.000 sc} bind def /col13 {0.373 0.875 0.247 0.000 sc} bind def /col12 {0.749 0.498 0.000 0.000 sc} bind def /col11 {0.000 0.000 1.000 0.000 sc} bind def /col10 {0.000 1.000 1.000 0.000 sc} bind def /col9 {0.875 0.184 0.875 0.000 sc} bind def /col8 {0.000 0.000 0.000 127.000 sc} bind def /col7 {1.000 0.247 1.000 0.000 sc} bind def /col6 {0.247 0.373 0.749 0.000 sc} bind def /col5 {0.122 0.435 1.000 0.000 sc} bind def /col4 {0.122 0.435 0.122 0.000 sc} bind def /col3 {0.000 0.000 0.000 192.000 sc} bind def /col2 {0.875 0.122 0.875 0.000 sc} bind def /col1 {0.184 0.373 0.435 0.000 sc} bind def {<000000000000000000000000000000003333333333333333333333333333333300000000000000000000000000000000cccccccccccccccccccccccccccccccc>} 13 dp {<00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000>} 12 dp {<010000800100008002000040020000400c0000300c000030f000000ff000000f000ff000000ff00000300c0000300c0000400200004002000080010000800100>} 11 dp {} 10 dp {<18181818181818183c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c18181818181818188181818181818181c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c38181818181818181>} 9 dp {<18181818181818180c0c0c0c0c0c0c0c060606060606060603030303030303038181818181818181c0c0c0c0c0c0c0c060606060606060603030303030303030>} 8 dp {<181818181818181830303030303030306060606060606060c0c0c0c0c0c0c0c08181818181818181030303030303030306060606060606060c0c0c0c0c0c0c0c>} 7 dp {<07070707070707070e0e0e0e0e0e0e0e1c1c1c1c1c1c1c1c38383838383838387070707070707070e0e0e0e0e0e0e0e0c1c1c1c1c1c1c1c18383838383838383>} 6 dp {} 5 dp {<00000000000000000000000000000000c0c0c0c0c0c0c0c00000000000000000000000000000000000000000000000000c0c0c0c0c0c0c0c0000000000000000>} 4 dp {<0003000300030003000c000c000c000c003000300030003000c000c000c000c003000300030003000c000c000c000c003000300030003000c000c000c000c000>} 3 dp {} 2 dp {} 1 dp %%EndResource %%EndProlog %%Page: 1 1 /pgsave save def bop % 0 0 offsets 72 85 translate 12.500 12.500 scale minit 0 0 26 37 gsave rectclip l2 sp col2 4 sl col1 4 sl col9 5 sl l1 4 21 16 hl 4 21 16 vl 4 21 20 hl 21 16 25 20 fb 4 25 16 vl 1 8 10 hl 4 5 10 vl 4 5 14 hl 3 9 11 vl 5 10 9 14 fb 4 9 10 vl 4 21 11 hl 4 21 11 vl 1 21 14 vl 4 21 15 hl % 21 11 25 15 fb 4 25 11 vl 3 5 8 hl 6 5 8 vl 5 8 8 10 fb 2 8 8 vl 2 5 4 vl 3 5 6 hl 1 8 5 vl 5 4 8 6 fb 2 8 4 vl 4 5 0 hl 6 5 0 vl 1 8 4 hl 3 9 1 vl 5 0 9 4 fb 4 9 0 vl col1 5 sl 1 8 33 hl 4 5 33 vl 4 5 37 hl 5 33 9 37 fb 4 9 33 vl 3 5 32 hl 5 5 32 vl 5 32 8 33 fb 1 8 32 vl 1 5 29 vl 3 5 30 hl 5 29 8 30 fb 1 8 29 vl 4 5 25 hl 5 5 25 vl 1 8 29 hl 3 9 26 vl 5 25 9 29 fb 4 9 25 vl 4 21 21 hl 4 21 21 vl 4 21 25 hl 21 21 25 25 fb 4 25 21 vl col17 5 sl 3 5 30 hl 2 5 30 vl 3 5 32 hl 5 30 8 32 fb 2 8 30 vl 4 21 6 hl 4 21 6 vl 2 21 8 vl 4 21 10 hl 21 6 25 10 fb 4 25 6 vl col16 5 sl 3 5 6 hl 2 5 6 vl 3 5 8 hl 5 6 8 8 fb 2 8 6 vl 4 21 1 hl 4 21 1 vl 1 21 4 vl 4 21 5 hl 21 1 25 5 fb 4 25 1 vl col10 5 sl 5 0 30 hl 2 0 30 vl 5 0 32 hl 0 30 5 32 fb 2 5 30 vl 4 8 30 hl 2 8 30 vl 4 8 32 hl 8 30 12 32 fb 2 12 30 vl 4 21 26 hl 4 21 26 vl 1 21 29 vl 4 21 30 hl 21 26 25 30 fb 4 25 26 vl 5 0 6 hl 2 0 6 vl 5 0 8 hl 0 6 5 8 fb 2 5 6 vl 3 8 6 hl 2 8 6 vl 3 8 8 hl 8 6 11 8 fb 2 11 6 vl col1 7 sl 3 5 30 hl 2 5 30 vl 3 5 32 hl 5 30 8 32 fb 2 8 30 vl 4 21 6 hl 4 21 6 vl 2 21 8 vl 4 21 10 hl 21 6 25 10 fb 4 25 6 vl col9 8 sl 3 5 6 hl 2 5 6 vl 3 5 8 hl 5 6 8 8 fb 2 8 6 vl 4 21 1 hl 4 21 1 vl 1 21 4 vl 4 21 5 hl 21 1 25 5 fb 4 25 1 vl col6 1 sl col7 1 sl col11 7 sl col12 9 sl 4 5 33 hl 4 5 33 vl 4 5 37 hl 5 33 9 37 fb 4 9 33 vl 4 5 25 hl 5 5 25 vl 4 5 29 hl 3 9 26 vl 5 25 9 29 fb 4 9 25 vl 4 5 10 hl 4 5 10 vl 4 5 14 hl 3 9 11 vl 5 10 9 14 fb 4 9 10 vl 4 21 11 hl 4 21 11 vl 1 21 14 vl 4 21 15 hl % 21 11 25 15 fb 4 25 11 vl 4 5 0 hl 6 5 0 vl 4 5 4 hl 3 9 1 vl 5 0 9 4 fb 4 9 0 vl 5 0 34 hl 3 0 34 vl 5 0 37 hl 0 34 5 37 fb 3 5 34 vl 5 9 34 hl 3 9 34 vl 5 9 37 hl 2 14 35 vl 9 34 14 37 fb 3 14 34 vl 4 21 31 hl 4 21 31 vl 2 21 33 vl 1 21 34 vl 4 21 35 hl 21 31 25 35 fb 4 25 31 vl 7 5 22 vl 4 5 25 hl 5 22 9 25 fb 7 9 22 vl 5 9 18 hl 11 5 18 vl 5 9 22 hl 5 18 14 22 fb 4 14 18 vl 4 5 14 hl 15 5 14 vl 3 9 15 vl 5 14 9 18 fb 4 9 14 vl 5 0 0 hl 3 0 0 vl 5 0 3 hl 0 0 5 3 fb 4 5 0 vl 5 9 0 hl 4 9 0 vl 5 9 3 hl 9 0 14 3 fb 3 14 0 vl col13 10 sl col14 13 sl col14 11 sl col14 col14 l2 5 33 4 4 mx 5 25 4 4 mx 5 10 4 4 mx 21 11 4 4 mx 5 0 4 4 mx 21 31 4 4 mr 21 26 4 4 mr 21 21 4 4 mr 21 16 4 4 mr 21 11 4 4 mr 21 6 4 4 mr 21 1 4 4 mr grestore f1 0 setgray (Metal) 4 26 33 lb (Polysilicon) 4 26 28 lb (P-Diffusion) 4 26 23 lb (N-Diffusion) 4 26 18 lb (Contact) 4 26 13 lb (P-Fet) 4 26 8 lb (N-Fet) 4 26 3 lb pgsave restore showpage %%Trailer MAGICsave restore %%EOF magic-8.0.210/doc/psfigures/tut8.5.ps0000644000175000001440000002357610751423606015662 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: tut8.5.ps %%Creator: Xcircuit v2.0 %%CreationDate: Fri Apr 14 15:16:43 2000 %%Pages: 1 %%BoundingBox: 68 68 467 364 %%DocumentNeededResources: font Times-Roman %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrowhead90 { % -20 -12 36 24 bbox begingate 1.00 90 -16 0 arrowhead endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 916 480 offsets 1.0000 inchscale 2.6000 setlinewidth 1.000 0.000 0.000 scb 240 1.00 260 736 260 800 324 800 324 736 4 polygon 240 1.00 516 736 516 800 580 800 580 736 4 polygon sce 0.439 1.000 0.314 scb 240 1.00 324 800 324 896 516 896 516 800 4 polygon 240 1.00 324 640 324 736 516 736 516 640 4 polygon sce 0.133 0.545 0.133 scb 240 1.00 324 736 324 800 516 800 516 736 4 polygon sce 1.000 0.000 0.000 scb 240 1.00 260 320 260 384 324 384 324 320 4 polygon 240 1.00 516 320 516 384 580 384 580 320 4 polygon sce 0.439 1.000 0.314 scb 240 1.00 324 384 324 512 516 512 516 384 4 polygon 240 1.00 324 192 324 320 516 320 516 192 4 polygon sce 0.133 0.545 0.133 scb 240 1.00 324 320 324 384 516 384 516 320 4 polygon sce 1.000 0.000 0.000 scb 240 1.00 852 736 852 800 916 800 916 736 4 polygon 240 1.00 1012 544 1012 608 1076 608 1076 544 4 polygon sce 0.439 1.000 0.314 scb 240 1.00 916 800 916 896 1172 896 1172 800 4 polygon sce 0.133 0.545 0.133 scb 240 1.00 916 736 916 800 1076 800 1076 736 4 polygon sce 0.439 1.000 0.314 scb 240 1.00 916 608 916 736 1012 736 1012 608 4 polygon sce 0.133 0.545 0.133 scb 240 1.00 1012 608 1012 736 1076 736 1076 608 4 polygon 240 1.00 388 288 388 416 452 416 452 288 4 polygon sce 0.439 1.000 0.314 scb 240 1.00 1076 608 1076 800 1172 800 1172 608 4 polygon sce (6) {/Times-Roman 1.000 cf} 2 21 0 420 928 label (6) {/Times-Roman 1.000 cf} 2 21 0 420 544 label (6) {/Times-Roman 1.000 cf} 2 21 0 1204 704 label (2) {/Times-Roman 1.000 cf} 2 21 0 1044 512 label (2) {/Times-Roman 1.000 cf} 2 21 0 820 768 label (2) {/Times-Roman 1.000 cf} 2 21 0 612 768 label (2) {/Times-Roman 1.000 cf} 2 21 0 612 352 label (1) {/Times-Roman 1.000 cf} 2 25 0 612 464 label (4) {/Times-Roman 1.000 cf} 2 21 0 884 672 label (\(a\)) {/Times-Roman 1.000 cf} 2 21 0 212 768 label (\(c\)) {/Times-Roman 1.000 cf} 2 21 0 212 352 label (\(b\)) {/Times-Roman 1.000 cf} 2 21 0 756 768 label 1 1.00 836 800 804 800 2 polygon 1 1.00 836 736 804 736 2 polygon 1.00 0 820 736 arrowhead 1.00 -181 820 800 arrowhead 1 1.00 1012 528 1012 480 2 polygon 1 1.00 1076 528 1076 480 2 polygon 1 1.00 1188 608 1236 608 2 polygon 1 1.00 1188 800 1236 800 2 polygon 1 1.00 852 608 900 608 2 polygon 1 1.00 596 384 644 384 2 polygon 1 1.00 596 320 644 320 2 polygon 1 1.00 532 416 644 416 2 polygon 1 1.00 596 736 644 736 2 polygon 1 1.00 596 800 644 800 2 polygon 1 1.00 324 912 324 960 2 polygon 1 1.00 516 912 516 960 2 polygon 1 1.00 324 528 324 576 2 polygon 1 1.00 516 528 516 576 2 polygon 1 1.00 452 544 500 544 2 polygon 1 1.00 388 544 340 544 2 polygon 1 1.00 388 928 340 928 2 polygon 1 1.00 452 928 500 928 2 polygon 1 1.00 612 816 612 848 2 polygon 1 1.00 612 720 612 688 2 polygon 1 1.00 820 816 820 864 2 polygon 1 1.00 820 720 820 672 2 polygon 1 1.00 612 400 612 448 2 polygon 1 1.00 612 304 612 256 2 polygon 1 1.00 996 512 948 512 2 polygon 1 1.00 1092 512 1140 512 2 polygon 1 1.00 1204 624 1204 672 2 polygon 1 1.00 1204 736 1204 784 2 polygon 1 1.00 884 640 884 624 2 polygon 1 1.00 884 704 884 720 2 polygon 1.00 0 612 736 arrowhead 1.00 0 612 320 arrowhead 1.00 0 1204 800 arrowhead 1.00 0 884 736 arrowhead 1.00 -181 884 608 arrowhead 1.00 -181 1204 608 arrowhead 1.00 -181 612 800 arrowhead 1.00 -181 612 384 arrowhead 1.00 -181 612 416 arrowhead 1.00 0 340 928 arrowhead90 1.00 0 340 544 arrowhead90 1.00 0 1092 512 arrowhead90 1.00 -1 996 512 arrowhead90 1.00 -1 500 544 arrowhead90 1.00 -1 500 928 arrowhead90 pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/tut8.3.ps0000644000175000001440000001743010751423606015650 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: tut8.3 %%Creator: Xcircuit v2.0 %%CreationDate: Fri Apr 14 15:01:57 2000 %%Pages: 1 %%BoundingBox: 68 68 498 352 %%DocumentNeededResources: font Times-Roman %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /mgrid { % -304 -368 736 736 bbox begingate 1 1.00 -256 368 -256 -368 2 polygon 1 1.00 -128 368 -128 -368 2 polygon 1 1.00 -304 192 432 192 2 polygon 1 1.00 -304 64 432 64 2 polygon 1 1.00 0 368 0 -368 2 polygon 1 1.00 256 368 256 -368 2 polygon 1 1.00 128 368 128 -368 2 polygon 1 1.00 -304 -192 432 -192 2 polygon 1 1.00 -304 -64 432 -64 2 polygon 1 1.00 -304 -320 432 -320 2 polygon 1 1.00 -304 320 432 320 2 polygon 1 1.00 384 368 384 -368 2 polygon endgate } def /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrow { % -12 -40 24 80 bbox begingate 1 0.80 0 -40 0 20 2 polygon 1.00 0 0 40 arrowhead endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 720 464 offsets 1.0000 inchscale 2.6000 setlinewidth 0.133 0.545 0.133 scb 240 1.00 368 624 368 880 752 880 752 624 4 polygon sce 0.439 1.000 0.314 scb 241 1.00 240 240 880 240 880 496 752 496 752 624 368 624 368 496 240 496 8 polygon 1 1.00 752 864 752 880 2 polygon sce 0.800 0.800 0.800 scb 1.00 0 496 560 mgrid sce 0 1.00 368 624 368 880 752 880 752 624 4 polygon 1.000 1.000 1.000 scb (buried) {/Times-Roman 1.000 cf} 2 21 0 560 752 label sce (diffusion) {/Times-Roman 1.000 cf} 2 21 0 544 400 label (diff-space perimeter) {/Times-Roman 1.000 cf} 2 28 0 976 224 label (diff-buried perimeter) {/Times-Roman 1.000 cf} 2 21 0 944 704 label 3 1.00 368 624 368 496 240 496 240 240 880 240 880 496 752 496 752 624 8 polygon 1.00 60 928 256 arrow 1.000 1.000 1.000 scb 3 1.00 368 624 752 624 2 polygon 1.00 135 720 656 arrow sce pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/tut8.4.ps0000644000175000001440000001773310751423606015657 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: tut8.4 %%Creator: Xcircuit v2.0 %%CreationDate: Fri Apr 14 15:06:26 2000 %%Pages: 1 %%BoundingBox: 68 68 484 244 %%DocumentNeededResources: font Times-Roman font Times-Italic %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrowhead90 { % -20 -12 36 24 bbox begingate 1.00 90 -16 0 arrowhead endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 928 256 offsets 1.0000 inchscale 2.6000 setlinewidth 0.490 0.651 0.980 scb 192 480 beginpath 544 608 544 480 2 polyc 512 608 32 0.00 90.00 arc 192 640 1 polyc 240 1.00 endpath 1280 480 beginpath 928 608 928 480 2 polyc 960 608 32 180.00 90.00 arcn 1280 640 1 polyc 240 1.00 endpath sce 1.000 0.000 0.000 scb 192 192 beginpath 1120 320 1120 192 2 polyc 1088 320 32 0.00 90.00 arc 192 352 1 polyc 240 1.00 endpath sce 192 480 beginpath 544 608 544 480 2 polyc 512 608 32 0.00 90.00 arc 192 640 1 polyc 1 1.00 endpath 1280 480 beginpath 928 608 928 480 2 polyc 960 608 32 180.00 90.00 arcn 1280 640 1 polyc 1 1.00 endpath 192 192 beginpath 1120 320 1120 192 2 polyc 1088 320 32 0.00 90.00 arc 192 352 1 polyc 1 1.00 endpath (\(metal\)) {/Times-Roman 1.000 cf} 2 21 0 352 560 label (\(metal\)) {/Times-Roman 1.000 cf} 2 21 0 1120 560 label (\(poly\)) {/Times-Roman 1.000 cf} 2 21 0 656 272 label (sidewall overlap) {/Times-Italic 1.000 cf} 2 21 0 688 448 label (sidewall) {/Times-Italic 1.000 cf} 2 21 0 720 576 label (overlap) {/Times-Roman 1.000 cf} 2 21 0 352 424 label (\(oxide\)) {/Times-Roman 1.000 cf} 2 21 0 1024 416 label 1.00 0 560 576 arrowhead90 1.00 -1 912 576 arrowhead90 1.00 0 560 512 arrowhead90 1.00 -91 688 368 arrowhead90 1 1.00 560 576 640 576 2 polygon 1 1.00 912 576 800 576 2 polygon 1 1.00 560 512 688 512 688 480 3 polygon 1 1.00 688 416 688 368 2 polygon 1.00 -91 352 368 arrowhead90 1.00 270 352 464 arrowhead90 1 1.00 352 432 352 464 2 polygon 1 1.00 352 368 352 400 2 polygon pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/maint2.6.ps0000644000175000001440000001563610751423606016147 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.6.ps %%Creator: Xcircuit v2.0 %%CreationDate: Tue Apr 18 11:27:49 2000 %%Pages: 1 %%BoundingBox: 68 68 436 289 %%DocumentNeededResources: font Helvetica font Helvetica-Oblique %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 832 124 offsets 1.0000 inchscale 2.6000 setlinewidth 0.133 0.545 0.133 scb 240 1.00 192 252 192 700 384 700 384 252 4 polygon sce 0.439 1.000 0.314 scb 240 1.00 960 252 960 700 1152 700 1152 252 4 polygon 240 1.00 384 252 384 700 576 700 576 252 4 polygon sce 0 1.00 192 252 192 700 384 700 384 252 4 polygon 0 1.00 384 252 384 700 576 700 576 252 4 polygon 0 1.00 960 252 960 700 1152 700 1152 252 4 polygon (t1) {/Helvetica-Oblique 1.000 cf} 2 29 0 288 220 label (t2) {/Helvetica-Oblique 1.000 cf} 2 29 0 480 220 label (t2) {/Helvetica-Oblique 1.000 cf} 2 29 0 1056 220 label (A) {/Helvetica 1.000 cf} 2 25 0 384 732 label (B) {/Helvetica 1.000 cf} 2 25 0 1056 732 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/maint2.3b.ps0000644000175000001440000002345410751423606016303 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.3b %%Creator: XCircuit v3.6 rev4 %%CreationDate: Mon Feb 13 12:33:32 2006 %%Pages: 1 %%BoundingBox: 68 68 523 247 %%DocumentNeededResources: font Helvetica font Helvetica-Oblique %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 3.3 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--7/13/05 (tim.edwards@multigig.com) % The Johns Hopkins University (1993-2004) % MultiGiG, Inc. (2004-present) % %%BeginResource: procset XCIRCproc 3.3 0 % % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /ul { dup type /stringtype eq showflag 1 eq and { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { dup type /stringtype eq showflag 1 eq and { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave currentpoint newpath moveto true charpath flattenpath pathbbox pop exch pop sub grestore } def /Ts {mark Tabs aload pop counttomark 1 add array astore /Tabs exch def Tabs 0 currentpoint pop put} def /Tbn {mark Tabs aload pop counttomark dup 2 add 1 roll cleartomark 1 sub} def /Tb { 0 1 Tbn {Tabs exch get dup currentpoint pop lt {currentpoint exch pop moveto exit} {pop} ifelse } for } def /Tf { Tbn -1 0 {Tabs exch get dup currentpoint pop gt {currentpoint exch pop moveto exit} {pop} ifelse } for } def /qS { (aa) stW (a a) stW sub 4 div 0 Kn } def /hS { qS qS } def /pspc 0 def /cf0 { scalefont setfont } bind def /Kn { dup kY add /kY exch def rmoveto } bind def /ss { /fscale fscale 0.67 mul def currentfont 0.67 cf0 0 fscale0 fscale mul 0.33 mul neg Kn} def /Ss { /fscale fscale 0.67 mul def currentfont 0.67 cf0 0 fscale0 fscale mul 0.67 mul Kn } def /ns { 0 kY neg Kn /kY 0 def /fscale 1.0 def xfont0 1.0 cf0 } def /CR { ns 0 /Bline Bline fscale0 neg add def Bline moveto } def /cf { dup type /realtype ne {1.0} if exch findfont exch kY 0 eq { 40 mul dup /fscale0 exch def cf0 /xfont0 currentfont def} {fscale0 mul fscale mul cf0} ifelse } def /ctmk { counttomark dup 2 add -1 roll pop } bind def /label { gsave translate 0 0 moveto dup scale neg /rotval exch def /just exch def just 384 and 0 gt {/mshow {pop} def} {/mshow {show} def} ifelse just 16 and 0 gt {gsave rotval rotate 0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup abs 1e-9 lt {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse grestore {-1 /rotval rotval neg def /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch -1e-9 lt {-1 /rotval rotval neg def /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /showflag 0 def /fspc pspc def /Bline 0 def /Tabs 0 array def /fscale 1.0 def /kY 0 def gsave dup 1 add copy 0 exch 1 0 dtransform exch atan rotate {exch dup type /stringtype eq {true charpath flattenpath} {dup type /arraytype eq {exec} {12 string cvs true charpath flattenpath} ifelse} ifelse} repeat pop pathbbox grestore 3 -1 roll pop 3 1 roll just 1 and 0 gt {just 2 and 0 gt {exch pop neg fspc sub} {exch sub 0.5 mul neg} ifelse} {pop neg fspc add} ifelse exch Bline exch just 4 and 0 gt {just 8 and 0 gt {exch pop neg fspc sub} {add 0.5 mul neg} ifelse} {pop neg fspc add} ifelse rotval rotate Kn currentpoint translate /showflag 1 def /Bline 0 def /Tabs 0 array def /fscale 1.0 def /kY 0 def {dup type /stringtype eq {mshow} {dup type /arraytype eq {exec} {12 string cvs mshow} ifelse} ifelse} repeat grestore } def /pinlabel { 4 index 32 and 0 ne hlevel 0 eq or { /pspc 10 def label /pspc 0 def } { pop pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /graphic { gsave 4 index cvx exec /DataSource get resetfile translate 0 0 moveto neg rotate dup scale cvx exec image grestore } def /scb { setrgbcolor } bind def /sce { defColor aload pop scb } bind def /cRedef {/defColor currentcolor 3 array astore def} def /begingate {dup type /dicttype ne {1 dict} if begin % default params dup type /dicttype ne {1 dict} if begin % instanced params /hlevel hlevel 1 add def /defColor currentcolor sce 3 array astore def gsave sce translate 0 0 moveto neg rotate dup abs scale } bind def /endgate { /hlevel hlevel 1 sub def grestore defColor aload pop cRedef scb end end} bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if gsave style 16 and 0 gt { style 224 and -5 bitshift style 256 and 0 gt { 7 exch sub 8 div dup 1 exch sub currentrgbcolor 3 array astore {3 copy mul add 4 1 roll pop} forall pop pop setrgbcolor eofill} {dup 7 lt {gar exch get ppaint} {pop eofill} ifelse} ifelse} {style 256 and 0 gt {1 setgray eofill} if} ifelse grestore style 8 and 0 gt style 512 eq or {newpath} {stroke} ifelse grestore} def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 0 0 scb cRedef } def /psinsertion {/PSobj save def /showpage {} def /setpagedevice {pop} def bop rotate translate dup scale} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. %%BeginSetup /arrowhead { % trivial begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrowhead90 { begingate 1.00 270 -16 0 arrowhead endgate } def /arrow { % trivial begingate 1 0.80 0 -40 0 20 2 polygon 1.00 0 0 40 arrowhead endgate } def %%EndSetup %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop 1.0000 inchscale 2.6000 setlinewidth 1058 -16 translate 0.753 0.333 0.502 scb 240 1.00 -576 272 -576 528 48 528 48 272 4 polygon sce 1 1.00 -288 512 -288 592 2 polygon 1 1.00 -240 512 -240 592 2 polygon 1 1.00 -352 576 -304 576 2 polygon 1 1.00 -224 576 -176 576 2 polygon -1.00 0 -304 576 arrowhead90 (sep_long) {/Helvetica-Oblique cf} 2 25 0 1.00 -256 608 label 0 1.00 -576 272 -576 528 48 528 48 272 4 polygon 240 1.00 -496 432 -496 496 -288 496 -288 432 4 polygon 240 1.00 -496 304 -496 368 -32 368 -32 304 4 polygon 240 1.00 -240 432 -240 496 -32 496 -32 432 4 polygon (given) {CR} (separation) {CR} (no size or) {/Helvetica cf} 6 20 0 1.00 144 272 label 1.00 0 -224 576 arrowhead90 1 1.00 -496 544 -496 624 2 polygon 1 1.00 -576 544 -576 624 2 polygon 1 1.00 -480 608 -432 608 2 polygon 1.00 0 -480 608 arrowhead90 1 1.00 -592 528 -736 528 2 polygon 1 1.00 -592 496 -736 496 2 polygon 1 1.00 -16 496 96 496 2 polygon 1 1.00 -16 432 96 432 2 polygon 1 1.00 -32 416 -32 224 2 polygon 1 1.00 -240 416 -240 224 2 polygon 1 1.00 -16 240 32 240 2 polygon 1.00 0 -16 240 arrowhead90 1 1.00 -256 240 -304 240 2 polygon -1.00 0 -256 240 arrowhead90 (size_long) {/Helvetica-Oblique cf} 2 29 0 1.00 -144 240 label 1 1.00 -640 608 -592 608 2 polygon -1.00 0 -592 608 arrowhead90 (border_long) {/Helvetica-Oblique cf} 2 25 0 1.00 -544 640 label (border) {/Helvetica-Oblique cf} 2 23 0 1.00 -752 512 label 1 1.00 -704 544 -704 592 2 polygon -1.00 90 -704 544 arrowhead90 1 1.00 -704 480 -704 432 2 polygon 1.00 90 -704 480 arrowhead90 1 1.00 80 512 80 560 2 polygon -1.00 90 80 512 arrowhead90 1 1.00 80 416 80 352 2 polygon 1.00 90 80 416 arrowhead90 -1.00 300 96 288 arrow (size) {/Helvetica-Oblique cf} 2 20 0 1.00 96 464 label 1 1.00 -592 432 -640 432 2 polygon 1 1.00 -592 368 -640 368 2 polygon 1 1.00 -624 448 -624 480 2 polygon -1.00 90 -624 448 arrowhead90 1 1.00 -624 352 -624 320 2 polygon 1.00 90 -624 352 arrowhead90 (sep) {/Helvetica-Oblique cf} 2 23 0 1.00 -608 400 label 1.000 1.000 1.000 scb 1 1.00 -240 304 -240 368 2 polygon pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/maint2.1.ps0000644000175000001440000001761510751423606016141 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.1.ps %%Creator: Xcircuit v2.0 %%CreationDate: Tue Apr 18 11:08:34 2000 %%Pages: 1 %%BoundingBox: 68 68 523 220 %%DocumentNeededResources: font Helvetica font Helvetica-Bold %%+ font Helvetica-Oblique %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrow { % -12 -40 24 80 bbox begingate 1 0.80 0 -40 0 20 2 polygon 1.00 0 0 40 arrowhead endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 544 352 offsets 1.0000 inchscale 2.6000 setlinewidth 0.753 0.333 0.502 scb 240 1.00 192 224 192 192 512 192 672 320 672 352 384 352 6 polygon sce 0.490 0.651 0.980 scb 240 1.00 192 448 192 416 512 416 672 544 672 576 384 576 6 polygon sce 0 1.00 192 416 192 448 512 448 512 416 4 polygon 1 1.00 192 448 384 576 2 polygon 1 1.00 512 448 672 576 2 polygon 1 1.00 384 576 672 576 2 polygon 1 1.00 512 416 672 544 2 polygon 1 1.00 672 576 672 544 2 polygon 1 1.00 192 448 672 576 2 polygon 1 1.00 384 576 512 448 2 polygon 0 1.00 192 192 192 224 512 224 512 192 4 polygon 1 1.00 192 224 384 352 2 polygon 1 1.00 512 224 672 352 2 polygon 1 1.00 384 352 672 352 2 polygon 1 1.00 512 192 672 320 2 polygon 1 1.00 672 352 672 320 2 polygon 1 1.00 192 224 672 352 2 polygon 1 1.00 384 352 512 224 2 polygon 1 1.00 672 528 672 368 2 polygon 1 1.00 512 400 512 240 2 polygon 1 1.00 192 400 192 240 2 polygon 1 1.00 384 368 384 416 2 polygon (plane) {/Helvetica 1.000 cf} (metal1 ) {/Helvetica-Bold 1.000 cf} 4 20 0 704 560 label (plane) {/Helvetica 1.000 cf} (active ) {/Helvetica-Bold 1.000 cf} 4 20 0 704 336 label 1.00 75 640 240 arrow 1.00 75 656 480 arrow (: pcontact) {/Helvetica 1.000 cf} (drawn) {/Helvetica-Oblique 1.000 cf} 4 20 0 704 224 label (: pcontact/m1) {/Helvetica 1.000 cf} (automatically generated) {/Helvetica-Oblique 1.000 cf} 4 20 0 720 464 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/maint2.5.ps0000644000175000001440000001605510751423606016142 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.5.ps %%Creator: Xcircuit v2.0 %%CreationDate: Tue Apr 18 11:25:42 2000 %%Pages: 1 %%BoundingBox: 68 68 346 316 %%DocumentNeededResources: font Helvetica %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 691 480 offsets 1.0000 inchscale 2.6000 setlinewidth 0.745 0.600 0.871 scb 240 1.00 211 192 211 448 403 448 403 192 4 polygon 240 1.00 563 608 563 832 755 832 755 608 4 polygon sce 1 1.00 211 448 403 448 403 192 3 polygon 1 1.00 563 832 563 608 755 608 3 polygon 1 1.00 419 464 451 496 2 polygon 1 1.00 419 448 627 448 2 polygon 1 1.00 595 496 595 464 2 polygon 1.00 0 595 608 arrowhead 1.00 -181 595 448 arrowhead 1.00 135 403 448 arrowhead 1.00 -46 563 608 arrowhead 1 1.00 595 560 595 592 2 polygon 1 1.00 499 544 547 592 2 polygon (Manhattan distance) {/Helvetica 1.000 cf} 2 21 0 739 528 label (Euclidean distance) {/Helvetica 1.000 cf} 2 21 0 355 528 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/tut7.3.ps0000644000175000001440000001623010751423606015644 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: ../psfiles/tut7.3.ps %%Creator: Xcircuit v2.0 %%CreationDate: Fri Apr 14 13:21:10 2000 %%Pages: 1 %%BoundingBox: 68 68 304 304 %%DocumentNeededResources: %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /mgrid { % -304 -304 608 608 bbox begingate 1 1.00 -256 304 -256 -304 2 polygon 1 1.00 -128 304 -128 -304 2 polygon 1 1.00 -304 224 304 224 2 polygon 1 1.00 -304 64 304 64 2 polygon 1 1.00 0 304 0 -304 2 polygon 1 1.00 256 304 256 -304 2 polygon 1 1.00 128 304 128 -304 2 polygon 1 1.00 -304 -256 304 -256 2 polygon 1 1.00 -304 -96 304 -96 2 polygon endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 848 560 offsets 1.0000 inchscale 2.6000 setlinewidth 0.490 0.651 0.980 scb 240 1.00 240 400 688 400 688 768 624 768 624 464 240 464 6 polygon sce 0.745 0.600 0.871 scb 240 1.00 496 224 496 384 560 384 560 224 4 polygon sce 0 1.00 496 224 496 384 560 384 560 224 4 polygon 0 1.00 240 400 688 400 688 768 624 768 624 464 240 464 6 polygon 0.616 0.624 0.925 scb 240 1.00 480 384 480 480 576 480 576 384 4 polygon sce 0 1.00 480 384 480 480 576 480 576 384 4 polygon 1 1.00 480 480 576 384 2 polygon 1 1.00 576 480 480 384 2 polygon 0.800 0.800 0.800 scb 1.00 0 496 496 mgrid sce pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/tut7.2.ps0000644000175000001440000002315310751423606015645 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: tut7.2.ps %%Creator: Xcircuit v2.0 %%CreationDate: Fri Apr 14 13:50:28 2000 %%Pages: 1 %%BoundingBox: 68 68 535 385 %%DocumentNeededResources: font Helvetica font Times-Italic %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrowhead90 { % -20 -12 36 24 bbox begingate 1.00 90 -16 0 arrowhead endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 1117 536 offsets % 32.00 8.00 gridspace 1.0000 inchscale 2.6000 setlinewidth 0.545 0.137 0.137 scb 240 1.00 317 192 317 1016 1149 1016 1149 192 4 polygon sce 0.804 0.000 0.804 scb 240 1.00 333 208 333 968 1133 968 1133 208 4 polygon sce 1.000 0.647 0.000 scb 240 1.00 749 640 749 704 973 704 973 640 4 polygon sce 0.898 0.898 0.898 scb 240 1.00 493 648 493 792 637 792 637 648 4 polygon sce 0.824 0.706 0.549 scb 240 1.00 493 808 493 872 973 872 973 808 4 polygon 240 1.00 749 728 749 792 845 792 845 728 4 polygon 240 1.00 877 728 877 792 973 792 973 728 4 polygon sce 0.753 1.000 0.753 scb 240 1.00 493 480 493 544 973 544 973 480 4 polygon sce 0.490 0.651 0.980 scb 240 1.00 749 400 749 464 973 464 973 400 4 polygon sce 1.000 0.502 0.502 scb 240 1.00 749 320 749 384 973 384 973 320 4 polygon sce 1.000 1.000 0.753 scb 240 1.00 749 240 749 304 973 304 973 240 4 polygon sce 0.800 0.800 0.800 scb 240 1.00 493 240 493 304 717 304 717 240 4 polygon sce 1.000 0.753 0.753 scb 240 1.00 493 320 493 384 717 384 717 320 4 polygon sce 0.753 1.000 1.000 scb 240 1.00 493 400 493 464 717 464 717 400 4 polygon sce 1.000 1.000 1.000 scb (NETLIST MENU) {/Helvetica 0.800 cf} 2 25 0 733 984 label (Label) {/Helvetica 1.000 cf} 2 25 0 733 904 label sce (BusBit13) {/Helvetica 1.000 cf} 2 21 0 733 840 label 0 1.00 317 192 317 1016 1149 1016 1149 192 4 polygon 0 1.00 333 208 333 968 1133 968 1133 208 4 polygon 0 1.00 493 808 493 872 973 872 973 808 4 polygon 0 1.00 877 728 877 792 973 792 973 728 4 polygon 0 1.00 749 728 749 792 845 792 845 728 4 polygon 0 1.00 749 640 749 704 973 704 973 640 4 polygon 0 1.00 493 480 493 544 973 544 973 480 4 polygon 1.000 1.000 1.000 scb (Netlist) {/Helvetica 1.000 cf} 2 25 0 733 584 label sce (Find) {/Helvetica 1.000 cf} 2 21 0 853 672 label (13) {/Helvetica 1.000 cf} 2 21 0 797 760 label 0 1.00 493 648 493 792 637 792 637 648 4 polygon 1 1.00 541 648 541 792 2 polygon 1 1.00 589 792 589 648 2 polygon 1 1.00 493 744 637 744 2 polygon 1 1.00 493 696 637 696 2 polygon 1 1.00 557 720 573 720 2 polygon 1 1.00 565 728 565 712 2 polygon (Placer) {/Times-Italic 1.000 cf} 2 23 0 293 728 label (Current Netlist) {/Times-Italic 1.000 cf} 2 20 0 1165 512 label (Pumps) {/Times-Italic 1.000 cf} 2 20 0 1165 760 label (Current Text) {/Times-Italic 1.000 cf} 2 20 0 1165 840 label 0 1.00 493 400 493 464 717 464 717 400 4 polygon 0 1.00 749 400 749 464 973 464 973 400 4 polygon 0 1.00 493 320 493 384 717 384 717 320 4 polygon 0 1.00 749 320 749 384 973 384 973 320 4 polygon 0 1.00 493 240 493 304 717 304 717 240 4 polygon 0 1.00 749 240 749 304 973 304 973 240 4 polygon (Print) {/Helvetica 1.000 cf} 2 21 0 861 432 label (Cleanup) {/Helvetica 1.000 cf} 2 21 0 861 352 label (Show) {/Helvetica 1.000 cf} 2 21 0 861 272 label (No Net) {/Helvetica 1.000 cf} 2 21 0 605 272 label (Terms) {/Helvetica 1.000 cf} 2 21 0 605 352 label (Verify) {/Helvetica 1.000 cf} 2 21 0 605 432 label 1.00 0 989 840 arrowhead90 1.00 0 989 760 arrowhead90 1.00 0 989 512 arrowhead90 1.00 -1 477 720 arrowhead90 1 1.00 989 840 1165 840 2 polygon 1 1.00 989 760 1165 760 2 polygon 1 1.00 989 512 1165 512 2 polygon 1 1.00 469 720 301 720 2 polygon pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/tutw1.1.ps0000644000175000001440000002117410751423606016026 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: tutw1.1.ps %%Creator: Xcircuit v2.0 %%CreationDate: Fri Apr 14 16:43:40 2000 %%Pages: 1 %%BoundingBox: 68 68 862 365 %%DocumentNeededResources: font Times-Roman %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 1200 357 offsets 1.0000 inchscale 2.6000 setlinewidth 0.800 0.800 0.800 scb 240 1.00 192 261 192 965 1072 965 1072 261 4 polygon 240 1.00 1136 261 1136 965 2288 965 2288 261 4 polygon sce 0.745 0.600 0.871 scb 240 1.00 720 549 720 645 912 645 912 549 4 polygon 241 1.00 496 581 368 581 368 677 592 677 592 485 496 485 496 581 7 polygon sce 0 1.00 720 549 720 645 912 645 912 549 4 polygon 0.490 0.651 0.980 scb 241 1.00 1232 389 1616 389 1616 901 1232 901 1232 485 1168 485 1168 421 1232 421 1232 389 1296 453 1296 805 1552 805 1552 453 1296 453 14 polygon 241 1.00 1840 389 1840 613 1744 613 1744 677 1840 677 1840 901 2192 901 2192 581 2256 581 2256 517 2192 517 2192 389 1840 389 1904 453 2128 453 2128 517 2064 517 2064 581 2128 581 2128 837 1904 837 1904 453 22 polygon sce 0 1.00 1296 453 1296 805 1552 805 1552 453 4 polygon 1 1.00 1904 453 1904 837 2128 837 2128 581 2064 581 2064 517 2128 517 2128 453 1904 453 9 polygon 1 1.00 2192 389 1840 389 1840 613 1744 613 1744 677 1840 677 1840 901 2192 901 2192 581 2256 581 2256 517 2192 517 2192 389 13 polygon 1 1.00 1232 485 1232 901 1616 901 1616 389 1232 389 1232 421 1168 421 1168 485 1232 485 9 polygon 1 1.00 496 581 368 581 368 677 592 677 592 485 496 485 496 581 7 polygon (mwidth) {/Times-Roman 1.000 cf} 2 23 0 336 629 label (mwidth) {/Times-Roman 1.000 cf} 2 23 0 416 437 label (mwidth) {/Times-Roman 1.000 cf} 2 20 0 928 597 label 1 1.00 928 645 1008 645 2 polygon 1 1.00 928 549 1008 549 2 polygon 1 1.00 960 661 960 709 2 polygon 1 1.00 960 533 960 485 2 polygon 1 1.00 352 581 272 581 2 polygon 1 1.00 320 565 320 517 2 polygon 1 1.00 352 677 272 677 2 polygon 1 1.00 320 693 320 741 2 polygon 1 1.00 496 469 496 405 2 polygon 1 1.00 592 469 592 405 2 polygon 1 1.00 576 437 432 437 2 polygon 1.00 0 960 549 arrowhead 1.00 0 320 581 arrowhead 1.00 -181 320 677 arrowhead 1.00 -181 960 645 arrowhead 1.00 -91 592 437 arrowhead 1.00 -91 496 437 arrowhead (invalid) {/Times-Roman 1.250 cf} 2 21 0 464 325 label (valid) {/Times-Roman 1.250 cf} 2 21 0 816 325 label (invalid) {/Times-Roman 1.250 cf} 2 21 0 1424 325 label (valid) {/Times-Roman 1.250 cf} 2 21 0 2016 325 label (bend_ok) {/Times-Roman 1.500 cf} 2 21 0 1728 213 label (bend_illegal) {/Times-Roman 1.500 cf} 2 21 0 608 213 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/tutcell1.mag0000644000175000001440000000206510751423606016460 0ustar timusersmagic tech scmos timestamp 955571370 << error_p >> rect 22 21 26 25 rect 22 16 26 18 rect 22 12 26 15 rect 22 10 26 11 rect 21 6 22 10 rect 26 6 27 10 rect 22 5 26 6 rect 21 1 22 5 rect 26 1 27 5 rect 22 0 26 1 << polysilicon >> rect 1 30 6 32 rect 9 30 13 32 rect 22 26 26 30 rect 1 6 6 8 rect 9 6 12 8 << ndiffusion >> rect 22 16 26 20 rect 6 8 9 10 rect 6 4 9 6 << pdiffusion >> rect 6 32 9 33 rect 6 29 9 30 rect 22 21 26 25 << metal1 >> rect 1 34 6 37 rect 10 34 15 37 rect 22 31 26 35 rect 6 22 10 25 rect 6 18 15 22 rect 6 14 10 18 rect 1 0 6 3 rect 10 0 15 3 << ntransistor >> rect 6 6 9 8 rect 22 1 26 5 << ptransistor >> rect 6 30 9 32 rect 22 6 26 10 << ndcontact >> rect 6 10 10 14 rect 22 11 26 15 rect 6 0 10 4 << pdcontact >> rect 6 33 10 37 rect 6 25 10 29 << labels >> rlabel metal1 22 31 26 35 3 Metal rlabel polysilicon 22 26 26 30 3 Polysilicon rlabel pdiffusion 22 21 26 25 3 P-Diffusion rlabel ndiffusion 22 16 26 20 3 N-Diffusion rlabel ndcontact 22 11 26 15 3 Contact rlabel ptransistor 22 6 26 10 3 P-Fet rlabel ntransistor 22 1 26 5 3 N-Fet << end >> magic-8.0.210/doc/psfigures/tut8.2.ps0000644000175000001440000001744610751423606015656 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: tut8.2 %%Creator: Xcircuit v2.0 %%CreationDate: Fri Apr 14 14:51:18 2000 %%Pages: 1 %%BoundingBox: 68 68 652 303 %%DocumentNeededResources: font Helvetica font Times-Roman %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /dot { % -10 -10 20 20 bbox begingate 248 1.00 0 0 6 0.00 360.00 xcarc endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 992 510 offsets 1.0000 inchscale 2.6000 setlinewidth 0.800 0.800 0.800 scb 240 1.00 192 254 192 798 1728 798 1728 254 4 polygon sce 0.490 0.651 0.980 scb 240 1.00 1152 510 1408 510 1408 382 1248 382 1248 350 1568 350 1568 382 1440 382 1440 510 1568 510 1568 542 1344 542 1344 638 1664 638 1664 766 1632 766 1632 670 1312 670 1312 542 1152 542 20 polygon 240 1.00 256 510 448 510 448 318 672 318 672 638 800 638 800 510 960 510 960 542 832 542 832 670 640 670 640 350 480 350 480 542 256 542 16 polygon sce 0 1.00 256 510 448 510 448 318 672 318 672 638 800 638 800 510 960 510 960 542 832 542 832 670 640 670 640 350 480 350 480 542 256 542 16 polygon 0 1.00 1152 510 1408 510 1408 382 1248 382 1248 350 1568 350 1568 382 1440 382 1440 510 1568 510 1568 542 1344 542 1344 638 1664 638 1664 766 1632 766 1632 670 1312 670 1312 542 1152 542 20 polygon 1.000 1.000 0.000 scb 1 1.00 256 526 464 526 464 334 656 334 656 654 816 654 816 526 960 526 8 polygon 1 1.00 1152 526 1568 526 2 polygon 1 1.00 1248 366 1568 366 2 polygon 1 1.00 1424 366 1424 526 2 polygon 1 1.00 1328 526 1328 654 1648 654 1648 766 4 polygon 1.00 0 256 526 dot 1.00 0 960 526 dot 1.00 0 1152 526 dot 1.00 0 1568 526 dot sce (1) {/Helvetica 1.000 cf} 2 23 0 224 526 label (2) {/Helvetica 1.000 cf} 2 20 0 976 526 label (1) {/Helvetica 1.000 cf} 2 23 0 1120 526 label (2) {/Helvetica 1.000 cf} 2 20 0 1600 526 label (\(a\)) {/Times-Roman 1.000 cf} 2 21 0 560 206 label (\(b\)) {/Times-Roman 1.000 cf} 2 21 0 1424 206 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/maint2.9.ps0000644000175000001440000002523110751423606016142 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.9.ps %%Creator: Xcircuit v2.0 %%CreationDate: Tue Apr 18 12:02:16 2000 %%Pages: 1 %%BoundingBox: 68 68 583 490 %%DocumentNeededResources: font Helvetica font Helvetica-Bold %%+ font Helvetica-Oblique %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrowhead90 { % -20 -12 36 24 bbox begingate 1.00 90 -16 0 arrowhead endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 1150 782 offsets 1.0000 inchscale 2.6000 setlinewidth 0.800 0.800 0.800 scb 240 1.00 478 1166 478 1230 542 1230 542 1166 4 polygon sce 0.898 0.898 0.898 scb 240 1.00 542 1166 542 1294 670 1294 670 1166 4 polygon sce 0.800 0.800 0.800 scb 240 1.00 542 910 542 1166 670 1166 670 910 4 polygon 240 1.00 1182 1166 1182 1230 1246 1230 1246 1166 4 polygon sce 1.000 0.000 0.000 scb 240 1.00 1118 910 1118 1166 1246 1166 1246 910 4 polygon sce 0.898 0.898 0.898 scb 240 1.00 1246 1166 1246 1294 1374 1294 1374 1166 4 polygon sce 0 1.00 542 910 542 1166 670 1166 670 910 4 polygon 0 1.00 542 1166 542 1294 670 1294 670 1166 4 polygon 0 1.00 478 1166 478 1230 542 1230 542 1166 4 polygon 0 1.00 1246 910 1246 1166 1374 1166 1374 910 4 polygon 0 1.00 1246 1166 1246 1294 1374 1294 1374 1166 4 polygon 0 1.00 1182 1166 1182 1230 1246 1230 1246 1166 4 polygon (B) {/Helvetica 1.000 cf} 2 21 0 606 1230 label (A) {/Helvetica 1.000 cf} 2 25 0 606 942 label (cornerTypes) {/Helvetica-Oblique 1.000 cf} 2 23 0 414 1198 label (cornerDist) {/Helvetica-Oblique 1.000 cf} 2 20 0 702 1238 label (OKTypes) {/Helvetica-Oblique 1.000 cf} 2 20 0 702 1102 label (t1) {/Helvetica-Oblique 1.000 cf} 2 21 0 510 1006 label (t2) {/Helvetica-Oblique 1.000 cf} 2 21 0 574 1006 label 1 1.00 478 1038 606 1038 2 polygon 1 1.00 638 1102 686 1102 2 polygon 1 1.00 702 1118 638 1182 2 polygon 1 1.00 718 1278 718 1254 2 polygon 1 1.00 718 1214 718 1182 2 polygon 1 1.00 430 1198 510 1198 2 polygon 1 1.00 558 878 590 878 2 polygon 1 1.00 622 878 654 878 2 polygon 1 1.00 542 894 542 846 2 polygon 1 1.00 670 894 670 846 2 polygon 1.00 0 718 1294 arrowhead 1.00 -181 718 1166 arrowhead 1.00 -91 526 1198 arrowhead 1.00 -91 622 1038 arrowhead 1.00 -91 670 878 arrowhead 1.00 90 542 878 arrowhead 1.00 90 622 1102 arrowhead 1.00 45 622 1198 arrowhead (d) {/Helvetica-Oblique 1.000 cf} 2 21 0 602 878 label (\(a\)) {/Helvetica 1.000 cf} 2 21 0 606 798 label 1 1.00 1422 1210 1422 1182 2 polygon 1.00 -181 1422 1166 arrowhead 1 1.00 1422 1278 1422 1254 2 polygon 1.00 0 1422 1294 arrowhead 1 1.00 1406 1118 1342 1182 2 polygon 1.00 45 1326 1198 arrowhead 1 1.00 1342 1102 1390 1102 2 polygon 1.00 90 1326 1102 arrowhead 1 1.00 1182 1038 1310 1038 2 polygon 1.00 -91 1326 1038 arrowhead 1 1.00 1326 878 1358 878 2 polygon 1 1.00 1374 894 1374 846 2 polygon 1.00 -91 1374 878 arrowhead 1 1.00 1262 878 1294 878 2 polygon 1 1.00 1246 894 1246 846 2 polygon 1.00 90 1246 878 arrowhead (\(b\)) {/Helvetica 1.000 cf} 2 21 0 1310 798 label 1 1.00 1134 1198 1214 1198 2 polygon 1.00 -91 1230 1198 arrowhead 1 1.00 686 1294 734 1294 2 polygon 1 1.00 686 1166 734 1166 2 polygon 1 1.00 1390 1294 1438 1294 2 polygon 1 1.00 1390 1166 1438 1166 2 polygon (poly) {/Helvetica-Bold 1.000 cf} (not) {/Helvetica 1.000 cf} 4 23 0 1118 1198 label (poly) {/Helvetica-Bold 1.000 cf} (not) {/Helvetica 1.000 cf} 4 20 0 1422 1102 label (2) {/Helvetica 1.000 cf} 2 21 0 1310 878 label (2) {/Helvetica 1.000 cf} 2 21 0 1422 1234 label (poly) {/Helvetica-Bold 1.000 cf} 2 31 0 1214 1022 label (space) {/Helvetica-Bold 1.000 cf} 2 28 0 1262 1022 label 1.000 0.000 0.000 scb 240 1.00 414 398 414 590 542 590 542 398 4 polygon sce 0.800 0.800 0.800 scb 240 1.00 542 270 542 718 670 718 670 270 4 polygon sce 0 1.00 542 270 542 718 670 718 670 270 4 polygon (poly) {/Helvetica-Bold 1.000 cf} 2 25 0 494 510 label (poly) {/Helvetica-Bold 1.000 cf} (not) {/Helvetica 1.000 cf} 4 20 0 734 462 label 1 1.00 718 462 638 462 2 polygon 1 1.00 494 494 574 494 2 polygon 1.00 0 638 462 arrowhead90 1.00 -1 574 494 arrowhead90 1.000 0.000 0.000 scb 240 1.00 1022 398 1022 590 1150 590 1150 398 4 polygon 240 1.00 1022 590 1022 718 1374 718 1374 590 4 polygon sce 0.800 0.800 0.800 scb 240 1.00 1150 270 1150 590 1278 590 1278 270 4 polygon sce 0 1.00 1150 270 1150 590 1278 590 1278 270 4 polygon (poly) {/Helvetica-Bold 1.000 cf} (not) {/Helvetica 1.000 cf} 4 20 0 1342 462 label 1 1.00 1326 462 1246 462 2 polygon 1.00 0 1246 462 arrowhead90 (poly) {/Helvetica-Bold 1.000 cf} 2 25 0 1182 638 label 1 1.00 1102 510 1182 510 2 polygon 1.00 -1 1182 510 arrowhead90 (\(c\)) {/Helvetica 1.000 cf} 2 21 0 542 206 label (\(d\)) {/Helvetica 1.000 cf} 2 21 0 1198 206 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/maint2.6b.ps0000644000175000001440000002267010751423606016305 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.6b.ps %%Creator: Xcircuit v2.5 %%CreationDate: Tue Jan 8 13:16:19 2002 %%Pages: 1 %%BoundingBox: 68 68 637 323 %%DocumentNeededResources: font Helvetica font Helvetica-Oblique %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.4 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--5/16/01 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.4 1 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /ul { dup type /stringtype eq showflag 1 eq and { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { dup type /stringtype eq showflag 1 eq and { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave currentpoint newpath moveto true charpath flattenpath pathbbox pop exch pop sub grestore } def /Ts {mark Tabs aload pop counttomark 1 add array astore /Tabs exch def Tabs 0 currentpoint pop put} def /Tbn {mark Tabs aload pop counttomark dup 2 add 1 roll cleartomark 1 sub} def /Tb { 0 1 Tbn {Tabs exch get dup currentpoint pop lt {currentpoint exch pop moveto exit} {pop} ifelse } for } def /Tf { Tbn -1 0 {Tabs exch get dup currentpoint pop gt {currentpoint exch pop moveto exit} {pop} ifelse } for } def /qS { (aa) stW (a a) stW sub 4 div 0 Kn } def /hS { qS qS } def /pspc 0 def /cf0 { scalefont setfont } bind def /Kn { dup kY add /kY exch def rmoveto } bind def /ss { /fscale fscale 0.67 mul def currentfont 0.67 cf0 0 fscale0 fscale mul 0.33 mul neg Kn} def /Ss { /fscale fscale 0.67 mul def currentfont 0.67 cf0 0 fscale0 fscale mul 0.67 mul Kn } def /ns { 0 kY neg Kn /kY 0 def /fscale 1.0 def xfont0 1.0 cf0 } def /CR { ns 0 /Bline Bline fscale0 neg add def Bline moveto } def /cf { dup type /realtype ne {1.0} if exch findfont exch kY 0 eq { 40 mul dup /fscale0 exch def cf0 /xfont0 currentfont def} {fscale0 mul fscale mul cf0} ifelse } def /ctmk { counttomark dup 2 add -1 roll pop } bind def /label { gsave translate 0 0 moveto dup scale neg /rotval exch def /just exch def just 16 and 0 gt {gsave rotval rotate 0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup abs 1e-9 lt {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse grestore {-1 /rotval rotval neg def /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch -1e-9 lt {-1 /rotval rotval neg def /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /showflag 0 def /fspc pspc def /Bline 0 def /Tabs 0 array def /fscale 1.0 def /kY 0 def gsave dup 1 add copy 0 exch 1 0 dtransform exch atan rotate {exch dup type /stringtype eq {true charpath flattenpath} {exec} ifelse } repeat pop pathbbox grestore 3 -1 roll pop 3 1 roll just 1 and 0 gt {just 2 and 0 gt {exch pop neg fspc sub} {exch sub 0.5 mul neg} ifelse} {pop neg fspc add} ifelse exch Bline exch just 4 and 0 gt {just 8 and 0 gt {exch pop neg fspc sub} {add 0.5 mul neg} ifelse} {pop neg fspc add} ifelse rotval rotate Kn currentpoint translate /showflag 1 def /Bline 0 def /Tabs 0 array def /fscale 1.0 def /kY 0 def {dup type /stringtype eq {show}{exec} ifelse} repeat grestore } def /pinlabel { 4 index 32 and 0 ne hlevel 0 eq or { /pspc 20 def label /pspc 0 def } { pop pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /scb { setrgbcolor } bind def /sce { defColor aload pop scb } bind def /cRedef {/defColor currentcolor 3 array astore def} def /begingate { /hlevel hlevel 1 add def /defColor currentcolor sce 3 array astore def gsave sce translate 0 0 moveto neg rotate dup abs scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore defColor aload pop cRedef scb} bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt style 512 eq or { newpath } { stroke } ifelse grestore } def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 0 0 scb cRedef } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox % trivial begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrowhead90 { % -20 -12 36 24 bbox % trivial begingate 1.00 270 -16 0 arrowhead endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 1024 186 offsets 1.0000 inchscale 2.6000 setlinewidth 0.494 0.753 0.933 scb 240 1.00 880 298 880 746 1264 746 1264 298 4 polygon 240 1.00 480 298 480 746 672 746 672 298 4 polygon 240 1.00 1360 298 1360 746 1552 746 1552 298 4 polygon sce 0 1.00 880 298 880 746 1264 746 1264 298 4 polygon 0 1.00 1360 298 1360 746 1552 746 1552 298 4 polygon 0 1.00 480 298 480 746 672 746 672 298 4 polygon (t1) {/Helvetica-Oblique cf} 2 29 0 1.00 1072 266 label (t2) {/Helvetica-Oblique cf} 2 29 0 1.00 1456 266 label (t2) {/Helvetica-Oblique cf} 2 29 0 1.00 576 266 label (A) {/Helvetica cf} 2 29 0 1.00 432 218 label (B) {/Helvetica cf} 2 29 0 1.00 1232 218 label 0.494 0.753 0.933 scb 240 1.00 192 298 192 746 384 746 384 298 4 polygon sce 0 1.00 192 298 192 746 384 746 384 298 4 polygon (t1) {/Helvetica-Oblique cf} 2 29 0 1.00 272 266 label 1 1.00 1264 826 1264 762 2 polygon 1 1.00 1424 762 1424 826 2 polygon 1 1.00 880 762 880 826 2 polygon 1 1.00 880 810 1424 810 2 polygon 1.00 0 896 810 arrowhead90 -1.00 0 1248 810 arrowhead90 -1.00 0 1408 810 arrowhead90 1.00 0 1280 810 arrowhead90 (wwidth) {/Helvetica-Oblique cf} 2 17 0 1.00 1056 826 label (wdist) {/Helvetica-Oblique cf} 2 17 0 1.00 1344 826 label 1.000 1.000 1.000 scb 1 1.00 1360 746 1424 682 2 polygon 1 1.00 1360 714 1424 650 2 polygon 1 1.00 1360 682 1424 618 2 polygon 1 1.00 1360 650 1424 586 2 polygon 1 1.00 1360 618 1424 554 2 polygon 1 1.00 1360 586 1424 522 2 polygon 1 1.00 1360 554 1424 490 2 polygon 1 1.00 1360 522 1424 458 2 polygon 1 1.00 1360 490 1424 426 2 polygon 1 1.00 1360 458 1424 394 2 polygon 1 1.00 1360 426 1424 362 2 polygon 1 1.00 1360 394 1424 330 2 polygon 1 1.00 1360 362 1424 298 2 polygon 1 1.00 1360 330 1392 298 2 polygon 1 1.00 1392 746 1424 714 2 polygon sce 1 1.00 1360 794 1360 762 2 polygon 1 1.00 1360 778 1488 778 2 polygon 1.00 0 1440 778 arrowhead90 1.00 0 1376 778 arrowhead90 (error area) {/Helvetica cf} 2 20 0 1.00 1504 778 label 1 1.00 480 762 480 826 2 polygon 1 1.00 384 810 480 810 2 polygon -1.00 0 464 810 arrowhead90 1.00 0 400 810 arrowhead90 (dist) {/Helvetica-Oblique cf} 2 17 0 1.00 432 826 label 1 1.00 384 826 384 762 2 polygon pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/psfigures/tut7.1.ps0000644000175000001440000001645510751423606015653 0ustar timusers%!PS-Adobe-3.0 EPSF-3.0 %%Title: ../psfiles/tut7.1.ps %%Creator: Xcircuit v2.0 %%CreationDate: Fri Apr 14 13:29:20 2000 %%Pages: 1 %%BoundingBox: 68 68 364 190 %%DocumentNeededResources: font Helvetica font Times-Roman %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrow { % -12 -40 24 80 bbox begingate 1 0.80 0 -40 0 20 2 polygon 1.00 0 0 40 arrowhead endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 480 256 offsets 1.0000 inchscale 2.6000 setlinewidth 0.800 0.800 0.800 scb 240 1.00 192 192 192 496 960 496 960 192 4 polygon sce 0.490 0.651 0.980 scb 240 1.00 672 224 672 320 800 320 800 224 4 polygon 240 1.00 384 192 384 384 512 384 512 192 4 polygon sce 1 1.00 256 192 256 384 800 384 800 192 4 polygon 1.000 1.000 0.000 scb (Input) {/Helvetica 1.000 cf} 2 29 0 448 376 label sce (Cell Boundary) {/Times-Roman 1.000 cf} 2 27 0 848 444 label 1.000 1.000 0.000 scb (Output) {/Helvetica 1.000 cf} 2 20 0 808 272 label sce 1 1.00 672 224 800 224 2 polygon 1 1.00 672 320 800 320 2 polygon 1 1.00 512 384 512 192 2 polygon 1 1.00 384 384 384 192 2 polygon 1.000 1.000 0.000 scb 1 1.00 800 224 800 320 2 polygon 0 1.00 384 320 384 384 512 384 512 320 4 polygon sce 1.00 135 580 412 arrow pgsave restore showpage %%Trailer XCIRCsave restore %%EOF magic-8.0.210/doc/Makefile0000644000175000001440000000255410751423606013671 0ustar timusers# # makefile for Magic documentation # MAGICDIR = .. PSDIR = psfiles include ${MAGICDIR}/defs.mak PRINTER=verlag TROFF=ditroff -P${PRINTER} TTROFF=ditroff -Ppsc -t PSDIT=psdit GRN=grn -Ppsc TBL=tbl -Ppsc EQN=eqn -Ppsc install-tcl: cd latexfiles && ${MAKE} install cd man && ${MAKE} install cd tutcells && ${MAKE} install cd html && ${MAKE} install install: cd latexfiles && ${MAKE} install cd man && ${MAKE} install cd tutcells && ${MAKE} install cd html && ${MAKE} install print_only: force lpr -h ${PSDIR}/copyright.ps lpr -h ${PSDIR}/tofc.ps lpr -h ${PSDIR}/introduction.ps lpr -h ${PSDIR}/tut1.ps lpr -h ${PSDIR}/tut2.ps lpr -h ${PSDIR}/tut3.ps lpr -h ${PSDIR}/tut4.ps lpr -h ${PSDIR}/tut5.ps lpr -h ${PSDIR}/tut6.ps lpr -h ${PSDIR}/tut7.ps lpr -h ${PSDIR}/tut8.ps lpr -h ${PSDIR}/tut9.ps lpr -h ${PSDIR}/tut10.ps lpr -h ${PSDIR}/tut11.ps lpr -h ${PSDIR}/maint1.ps lpr -h ${PSDIR}/maint2.ps lpr -h ${PSDIR}/maint3.ps lpr -h ${PSDIR}/maint4.ps lpr -h ${PSDIR}/otherreports.ps lpr -h ${PSDIR}/Addendum6.5.ps print: postscript print_only postscript: copyright.ps introduction.ps tofc.ps tut1.ps tut2.ps tut3.ps \ tut4.ps tut5.ps tut6.ps tut7.ps tut8.ps tut9.ps tut10.ps tut11.ps \ maint1.ps maint2.ps maint3.ps maint4.ps Addendum6.5.ps cd nmos; make postscript PRINTER=psc "PSDIT=${PSDIT}" cd scmos; make postscript PRINTER=psc "PSDIT=${PSDIT}" magic-8.0.210/doc/textfiles/0000755000175000001440000000000011504623573014234 5ustar timusersmagic-8.0.210/doc/textfiles/LEF.txt0000644000175000001440000001123110751423606015377 0ustar timusersLEF extensions to Magic-7.2 ------------------------------------- 1) Ports A new method exists for declaring a cell to be a subcircuit. This involves the creation of ports, which are a special kind of label. The existance of any port in a cell marks that cell as a subcircuit, which causes it to be treated differently during the process of extraction and netlist generation: a) Subcircuits are extracted as usual, except for the presence of the "port" keyword for each port in the .ext file. b) Exttosim (ext2sim) operates as usual, because the netlist is not hierarchical. c) Exttospice (ext2spice) will generate an "X" record for each instance of the subcircuit cell, rather than flattening the cell. To simulate in SPICE, a ".subckt" record for the cell must be added to the SPICE deck. This behavior can be subverted in the Tcl-based magic by using "exttospice subcircuits off", in which case all subcircuits will be flattened. d) The "extresis" command will ignore the contents of subcircuits. On the other hand, after doing "extresis geometry", subsequent use of "extresis" will generate a ".fh" file containing the detailed three-dimensional geometry of the cell in the format of nodes and segments used by the FastHenry field equation solver. This is unrelated to the LEF module. A new command "port" turns labels into ports. The syntax of the command is: port [option], where [option] is one of: class [type] get [set] port class type use [type] get [set] port use type index [number] get [set] port number connections [dir...] get [set] port connection directions make [index] [dir...] turn a label into a port remove turn a port back into a label help print this help information [] To use the port command, a label must first exist, and the cursor box must overlap the label, and only that label. The index indicates the order of the port in the argument list of the subcircuit definition and calls. The ordering of ports must match the order of arguments to any .subckt record used in a SPICE simulation of the cell. The directions given to "connections" must be one or more of "n", "s", "e", and "w" (with no spaces in between; e.g., "port connections nsew"). They indicate the edge of the port to which connections may be made to the cell. This is unused by LEF, which uses more detailed information about metal routing and obstructions inside the cell to determine how to attach to a pin. In the abbreviated command usage "port ", a default direction will be determined by the position of the text on the label. Class and use types correspond to LEF classes and uses for pins. Valid class types are: default input output tristate bidirectional, inout feedthrough, feedthru Valid use types are: default analog signal, digital power ground clock 2) Properties While the "port" command and method specifies information about pins, LEF also supports information about the cell itself. The "property" command is a general-purpose interface for attaching key-value pairs to a cell, which are saved in the output and may be parsed by any function. Keys relevant to the LEF module begin with the text "LEF". LEF-related keys are: LEFclass corresponding to LEF "CLASS" LEFsource corresponding to LEF "SOURCE" LEFsymmetry corresponding to LEF "SYMMETRY" The string value attached to each key is written to the LEF output verbatim, thus any value may be used that is acceptable LEF syntax. The property command has the following syntax: property [ []] With no arguments, "property" returns all the key-value pairs defined for the current edit cell. Given the key argument only, it returns the value attached to the indicated key. Given both arguments, it assigns the string value to the indicated key. A value which is an empty string ("") will cause the key to become undefined. Values which consist of more than one word must be enclosed in quotes. Example: property LEFsymmetry "X Y" 3) LEF file generation A LEF-definition file with extension ".lef" may be written for each cell. This file contains detailed information required for placing and routing the cell, including all information regarding pins, ports, and obstructions on the metallization layers. The syntax of the LEF command is: lef write [] to write a .lef file for a single cell. If is not specified, then the output will be for the current edit cell. All cells in a design my be written using the syntax: lef writeall magic-8.0.210/doc/textfiles/hires-color.txt0000644000175000001440000000410110751423606017215 0ustar timusers 3 February 1997 A More Colorful Magic Michael D. Godfrey This file describes the implementation of color visuals > 8bits. The purposes of these changes are: 1. Try to select the "best" visual on systems which offer choices. The current Magic just takes the default, and crashes if the color depth is greater than 8. 2. Support operation using TrueColor at 16 or 24 bits (and maybe 15 bits, thanks to Linux over-zealous implementation). The changes require X11R5 or above. I do not know what will happen if older X11's are used, but it is not likely to be useful. All changes are in the files graphics/grX11su1.c, grX11su2.c, and grX11su5.c. Most of the changes are in grX11su2.c. The changes are: 1. Call XGetVisualInfo() to find out what visuals the X-server has to offer. 2. Look at the optional environment variable MAGIC_COLOR. If it is present try to use the requested visual. Valid requests are: setenv MAGIC_COLOR <8bit | 16bit | 24bit>. If the requested visual is not offered Magic terminates. If there was no MAGIC_COLOR variable try: 8bit PseudoColor, 24bit TrueColor, 16bit TrueColor in that order. 3. If 8bit PseudoColor was selected, the code is unchanged and the file mos.7bit.dstyle5 is read from CAD_ROOT. If TrueColor is selected, the generation of pixel values and masks is fundamentally changed since TrueColor does not allow writable colormaps. The intent is to produce the same RGB color values, but no "transparent" colors are possible. Therefore, a new file: mos.24bit.dstlye5 is read. This file has M1 and M2 stippled, and the selection box made non-transparent. Further change in version 7.1: 4. Because some X servers, like PC-XWare for Windows, reserve spots at the bottom of the colormap rather than the top, it is necessary to let these values be set at runtime. We allow two environment variables, X_COLORMAP_RESERVED and X_COLORMAP_BASE, for the purpose of overriding the default values set in graphics/grX11su2.c. magic-8.0.210/doc/textfiles/locking.txt0000644000175000001440000000721010751423606016421 0ustar timusers August 1999 Files modified to implement file locking. file comment ------------------------------------------------------------------ flock/locking documentation misc/magic.h added #define FILE_LOCKS database/database.h define CDNOEDIT cd_flag and flock_list database/DBio.c definition of locking functions, and I/O calls. fixed :save command error database/DBcellname.c diagnostics dbwind/DBWprocs.c apply CDNOEDIT tests commands/cmde.c checks on :edit command commands/cmdlq.c lock on :open command windows/windclient.c defn: flock_close_wlist() windows/windcmdam.c call to flock_close_wlist on window close windows/windcmdnr.c Diagnostic code in windOpenCmd main/main.c call to flock_close_wlist on Magic exit. utils/path.c control of fopens The logic of the file locking implementation is as follows: First, Magic checks if there is a directory named flock in the directory given by CAD_ROOT. If directory flock is not present Magic turns off flie locking. If file locking is on: 1. When a file is opened due to being named on the call line, or used in a :load or :open command its status is checked. If it is not locked, lock is set and file is opened r/w (if permissions allow). If it is locked, the file is opened read-only and NOT editing cell. An attempt to use :edit to make it the editing cell will be rejected. 2. A list of locked files is maintained in each magic execution. Magic does (more or less) open/close sequences when reading/writing files. In addition, Magic just exits when it is :quit. The conditions that can cause the locking to release a lock are :close and :quit. In principle some cell's locks could be released on :close. However, if a window contains a root cell which contains references to other cells down the hierarchy, only the cells which are the root or have been expanded will have been read from the filesystem and locked. Cells that are unexpanded are not written back nor unlocked. The same cell may appear in multiple windows in a locked or unlocked state. This all leads to the choice that :close does not unlock any files. On :quit all locks are released. 3. When Magic starts, a lock directory (flock_list) is created in the current directory. A file is written in this directory for each local *.mag file read by Magic. The file name is the lock record. This record is removed on normal (:quit) termination. When Magic starts it checks for any "leftover" locks and tries to clear any "stale" ones. Files that are read from other directories (by being found through library paths or directly) are unconditionally marked as read-only. Normally such files should not be updated. If they are to be updated Magic must be executed from the directory containing the file. The following may be implemented to reduce problems due to "stale locks" leftover from cases such as magic crashes: During execution Magic updates the timestamp of its lock once every 10s. locks older than 10s are stale. Ideally, a simple thread would do this, but... UPDATE HISTORY ------------------------------------------------------------------- 5 January 2000: It was discovered that the use of :addpath and, generally, reading files from other directories had not been considered properly. In fact, use of :addpath led to a magic crash since it tried to create an invalid filename. This has now been corrected as described above. All non-local files are are marked read-only. magic-8.0.210/doc/textfiles/readline.txt0000644000175000001440000000514710751423606016565 0ustar timusers 11 January 2001 Magic now with GNU Readline Jeff Solomon This file describes the implementation of the GNU Readline interface in to magic. 1. Introduction GNU Readline helps you type. As you may know from using a modern shell, like bash, tcsh, or zsh, quickly returning to an old command or typing only an abbreviation of the command desired can save a tremendous amount of time. Now magic has those same capabilities with the addition of GNU Readline. 2. Building First, you have to compile the readline interface in. Do this by selecting "yes" when asked from scripts/config program. The magic distribution comes with the source for readline and I'd suggest using it because it will always be a version that works. 3. Usage The short answer is "Press ". In Readline, the TAB key cause completion to occur. First press ":" to get the command prompt, then hit TAB twice. You should see a list of all magic commands. Next, hit the letter "c" and hit TAB again. You should see a list of all the commands that begin with the letter "c". But wait, there's more! This implementation of readline has context sensitive completion. Type ":see " and hit TAB. It gives a list of possible layer names in the current technology. Pretty cool, huh? Next, try ":getcell " and then TAB, it will list all possible cell names. Very neat I think. Here are the possible things that are completed depending on the command and the placement of the cursor in a command: commands command arguments macros interative macros layer names file names/usernames cell names istyle names ostyle names directions (eg. bottom, down, east) When in doubt, just hit TAB! 4. Programming Mostly all the code for the readline interface lives in textio/txInput.c. There is also some in textio/txMain.c, but only in one place of initialization. See these two files and the docs for readline itself for instructions on changing the interface. 5. GNU License vs. Magic License The GNU license under with Readline is released is fairly restrictive. There is some concern that by integrating readline into magic, the magic code itself will be "infected" with the GNU license. My belief (which clearly could be wrong) is that as long as compiling without the code is an option and the code is clearly #ifdef'ed then it should not be a problem because a clear deliniation between magic and readline code has been maintained. Any GNU experts feel free to enlighten the rest of us if we're wrong. magic-8.0.210/doc/textfiles/open_gl.txt0000644000175000001440000002004110751423606016413 0ustar timusers 16 March 2000 Magic Freed From 8 Bit Planes! R. Timothy Edwards This file describes the implementation of an OpenGL interface for magic. The purpose of these changes is: Avoid the limit of 8 bit planes imposed by the pseudocolor colormap without compromising the quality of the display by using stipples in place of solid color fills. Details: Magic is losing ground to 1) new VLSI fabrication processes, and 2) new video cards. The first is not necessarily a problem: magic is well thought out and surprisingly versatile. However, the second was giving me fits a while back when I found that magic only runs in 8-bit colormap (pseudocolor) mode, while many of my other X11 applications wouldn't run at all and were only happy in 24-bit (TrueColor) mode. This is particularly true of Linux and the new breed of window managers and GUIs such as KDE which normally expect the desktop visual to be 24-bit TrueColor. I was forced to close my X session and restart in 8-bit mode to get magic to work. Then, I would often get the problem that by installing its own 8-bit colormap, magic would cause the colors of the xterm which it uses for text I/O to become unreadable. Later, I bought the Xi Graphics X11 server which supports 8-bit overlays on top of a 24-bit color, and that works well, but I regard it as a temporary solution. Magic makes good use of its color bit planes to represent layers in the VLSI layout. The result is a display that looks better than any of the multi-thousand-dollar professional layout tools (Cadence or Mentor Graphics, which use stipple patterns on a harsh black background, or Tanner's L-Edit, which is still backwardly-compatible to the original 4-plane color and uses a harsh white background). The problem with magic is that the 8-bit colormap mode is increasingly considered "archaic" and is less well supported as applications move toward 24-bit color. Also, fabrication processes have moved toward multiple metal and poly layers, which exceeds the capacity of 8 bit planes to represent separate fabrication layers. I have a solution: write a new graphics interface to magic for OpenGL. Why? OpenGL is supported by many high-performance video cards. It can do color blending in hardware, which gives similar results to what magic does with careful allocation of colors in the colormap. And: it's not limited to eight bit planes. And: it works in 24-bit color. And: say goodbye to stipple patterns. All layers can be represented by solid colors, and non-edit cell layers can have that "washed out" look without compromising graphics resolution. The results are stunning. Ideally, the interface would be based on "glut", the generic graphics API for OpenGL, which would avoid making explicit calls to X11 functions and make magic easier to port to non-UNIX operating systems (namely, Windows). Unfortunately, this approach got bogged down in a problem with threads and Xlib. The final answer on that is: Don't ever multithread an OpenGL program unless you're sure you have 100% control over the relative timing of the execution of all X11 and OpenGL calls. Instead of glut, this implementation is based on glX, the more specific API detailing the use of OpenGL within an X11 environment. This method keeps the original X11Handler as the event manager for magic, and uses X11 cursors and a few other routines. Everything else is rendered using OpenGL commands. Usage notes: Especially for Intel x86 and compatible platforms: Don't attempt to using magic/OpenGL with the Mesa OpenGL library unless you have video hardware support (as far as I know, this is only true for the Voodoo cards). More specifically, the hardware has to support color blends (GL_BLEND function); otherwise you will be waiting all day long for magic to draw your chip layout. There is one (commercial) driver available as of this writing (Xi graphics 3D Accelerated X server, see www.xig.com, works with several dozen video cards), and promises for the near future from SuSe, RedHat, MetroX, and Precision Insight. I am assuming that this is the wave of the future; otherwise, I wouldn't bother with the implementation. OpenGL rendering under the Xi Graphics server is a bit slower than with the X11 interface, but benchmarks are a complex combination of driver, card, revision numbers of each, processor type and speed, and magic implementation. If magic is compiled only for OpenGL, this will come up as the default. Otherwise, if it is compiled along with X11, X11 will be the default and it will require typing > magic -d OGL on the command line to get the OpenGL graphics. Implementation notes: OpenGL is normally considered a 3D rendering engine; here, I make use of 3D hardware acceleration, but all transformation matrices are aligned perpendicular to the depth (z) axis. There is no colormap; although OpenGL can work in color index mode, there is no point in doing so because the X11 version would be faster. For reasons of simplicity, the OpenGL version takes its color input from mos.7bit.std.cmap1, although instead of plugging them into a colormap, it sets the color according to their RGB values. The mos.7bit.std.cmap1 has been extended to include a set of solid colors which implement the "washed out" look of magic's non-edit cells without reverting to the checkerboard stipple pattern. Existence of the gray background made the color blending tricky, because anything blended with gray becomes grayer. However, OpenGL allows color specs to run outside of the normal color boundaries; it only cares whether the color values map to real video values after all transformations (like blending) have been performed on the color values. So we compute "super-colors" which can be whiter than white and blacker than black, but which arithmetically resolve to the usual magic colors when blended with the background gray. This achieves the desired effect. The only real difference between the OpenGL and X11 displays is the blend colors, which are always "computationally perfect" blends of multiple solids in OpenGL but have been tweaked for aesthetic effect in the X11 colormap version. This effect has been reproduced in the OpenGL version by tweaking the color, style, and tech files. In addition, new styles have been added for poly2 and capacitors. OpenGL has several emergent features unavailable in the X11 version: one is an unlimited number of solid colors (and their mixtures); this made all the difference on my layouts in 3-metal layer technologies, where the 3rd metal layer covers large areas and makes parts of the circuit uninterpretable when viewed through the nasty cross-hatched magenta stipple. Under OpenGL, the magenta color is perhaps still a bit severe, but the whole circuit is easily viewed underneath. The second emergent benefit is that layers of the same material which overlap in separate cells are drawn darker at the overlap (due to the blending function), so it is much easier to see where one cell ends and another begins. Bugs: Bugs of the source and of the glX driver are difficult to separate. My Xi Graphics 3D Accelerated-X server previously had problems drawing over X11 windows overlapping the magic window; this behavior has disappeared in the current distribution of the X server (May 2000). A good test of server bugs is to run magic/OpenGL on an SGI machine, which has a stable implementation of OpenGL. Files changed are: 1. scripts/configure.in (altered) 2. graphics/Makefile (altered) 3. graphics/grOGL*.c (new) graphics/grTOGL*.c (new) 4. scmos/mos.7bit.std.cmap (altered) scmos/mos.OpenGL.dstyle (new) scmos/mos.7bit.dstyle (altered) scmos/*.tech (altered) magic-8.0.210/doc/textfiles/default_macros.txt0000644000175000001440000000417410751423606017771 0ustar timusers---------------------------------------------------------------- Explanation of the default keyboard macros (installed in ${CAD_ROOT}/magic/sys/.magic) ---------------------------------------------------------------- Note: ellipses (...) indicate an interactive macro asterisk (*) indicates a macro available only under X11 ---------------------------------------------------------------- macro key command ---------------------------------------------------------------- a select visible A select more visible ctrl-A select less visible b box c copy d delete ctrl-D erase $ e edit f sideways (flip horizontal) F upside (flip vertical) g grid (toggle) i select cell I select more cell ctrl-I select less cell * l label... L shell ls ctrl-L redraw m move M stretch o openwindow O closewindow p paint... ctrl-shift-Q quit * r clockwise [90] R clockwise 270 ctrl-R clockwise 180 s select S select more ctrl-S select less ctrl-shift-S undo; select * u undo U redo v view V xview w writeall W writeall force x expand X unexpand ctrl-X expand toggle z zoom 0.5 Z zoom 2 ctrl-Z findbox zoom ctrl-shift-Z center * ? drc why / select area; what; select clear , select clear ! shell... space tool shift-space tool box * ctrl-shft-space tool wiring * (below: [dir] may be one of right, left, up, or down) [dir]_arrow scroll [dir] .1 * shift-[dir]_arrow scroll [dir] 1 * ctrl-[dir]_arrow box +[dir] 1 * ctrl-shift-[dir]_arrow box -[~dir] 1 * keypad_period box w 0; box h 0 * keypad_0 box w 4; box h 4 * shift-keypad_0 box w 7; box h 2 * ctrl-keypad_0 box w 2; box h 7 * (below: [num] may be 1 through 9; the resulting direction [dir] corresponds to the position of the number on the keypad. Diagonal directions are implemented as two commands) keypad_[num] move [dir] 1 * shift-keypad_[num] stretch [dir] 1 * F1 paint ndiff * F2 paint pdiff * F3 paint poly * F4 paint poly2 * F5 paint m1 * F6 paint m2 * F7 paint m3 * F8 paint m4 * F9 paint ndc * F10 paint pdc * F11 paint pc * F12 paint via * magic-8.0.210/doc/textfiles/non-manhattan.txt0000644000175000001440000001113710751423606017541 0ustar timusers---------------------------------------------- non-Manhattan extensions in Magic ---------------------------------------------- written by R. Timothy Edwards version dated 12/10/01 updated 2/21/06 ---------------------------------------------- 1. INTRODUCTION With the non-Manhattan extensions compiled in (this is the default configuration), Magic includes the ability to handle a large subset of non-Manhattan geometry. The implementation was chosen to fit into the "corner-stitched" data structures which form the basis of all operations in Magic, so as to require as little possible overhead. In fact, when non-Manhattan extensions are compiled in, Magic will not be measurably slower when acting on standard Manhattan geometry than it is without the extensions compiled in. 2. IMPLEMENTATION The chosen implementation does not include every possible type of non-Manhattan geometry (for instance, it does not include any kind of circular geometry). It implements what I would call "corner-split geometry". Every rectangular tile in Magic may be split across the diagonal, with one layer type on one side and another layer type on the other side, thus: +-----+ |XXXX/| |XXX/ | |XX/ | |X/ | |/ | +-----+ The corner-split geometry allows angles of any value, as long as the endpoints of each tile lie on the integer layout grid. [For those interested in implementation issues: There are only a maximum of 256 or so "types", which means TileType could easily be type short int, or 2 bytes long, with plenty room to spare. Instead, the TileType is defined as int, 4 bytes long, partly to let the data structure share the space as a pointer for subcell definitions. This allows the 32 bits to be sliced up into bit fields. I define 14 bits for the left-side type, 14 bits for the right-side type, one bit to define the direction ("/" or "\") of the split, and one bit to declare the tile as being split. Each Magic function requiring a check for non-Manhattan geometry makes a single test for the non-Manhattan declaration bit and branches to the non-Manhattan handling code, thus limiting the overhead on Manhattan geometry to two machine instructions (AND + BZ).] 3. COMMANDS Two simple commands allow basic generation and manipulation of non-Manhattan geometry: splitpaint [] spliterase These commands are analogous to the "paint" and "erase" commands. Instead of filling (or erasing the contents of) the box cursor, the non-Manhattan command paints (or erases) a triangle inside the cursor select box, with the corner of the triangle facing the direction indicated by , which can be one of the list: (nw, sw, ne, se). names the layer type to paint, and the optional names a layer to fill the rest of the box not covered by . For instance, in the example tile shown above, if the X's represent metal1, the tile would be generated by the command "split nw m1". 4. SUPPORTED FEATURES Non-Manhattan geometry extensions are complete in magic versio 7.4, apart from possible minor bug fixes. Supported features are listed below. Full support for: X11 and OpenGL rendering Painting/erasing (including move, copy, flip, rotate, and subcell geometry) Loading/saving Selection Connectivity searches CIF read/write (see below)* GDS read/write Plotting Extraction/Extresis (unlikely to extract non-Manhattan transistors) DRC (see below)** ---------------------------------------------- * Non-Manhattan CIF and GDS writes: The "bloat-max" and "bloat-min" functions are not defined for non-Manhattan geometry. However, I am not aware of any technology file which uses either function. "bloat-or" may produce incorrect output in pathological situations, but is expected to work properly for the usual uses of bloat-or such as auto-generated wells and selects. The CIF/GDS output "squares" function will not produce contact cuts inside nonmanhattan tiles. Technologies allowing/requiring nonmanhattan contact cuts should define the Magic layer to exactly correspond to the cut, instead of using the "squares" command. Otherwise, nonmanhattan regions should not be created from Magic contact layers. ** Non-Manhattan DRC: Currently, non-Manhattan DRC operates in the following manner: DRC checks occur for each orthogonal edge of a split tile. So the tile must obey DRC rules separately for each of the two types which make up the tile. This covers about 90% of the required DRC rules. Additional rules are required but have not yet been implemented. magic-8.0.210/doc/textfiles/macro_extension.txt0000644000175000001440000001675710751423606020210 0ustar timusersExtend keyboard macros for magic Provided by Philippe Pouliquen Johns Hopkins University department of Electrical and Computer Engineering Added to magic-6.5.2 distribution 3/28/00 -------------------------------------------------------------------------- Use of extended keyboard macros: To distinguish between normal key macros and extended keyboard macros, the extended keyboard macros key names all start with 'XK_'. For instance, the 'i' key has: macro i "select cell" macro XK_i "select cell" Although these two macros are the same, the extended keyboard macros are only available when the mouse cursor is in the drawing window, and X11 graphics is being used. If the mouse cursor is in the terminal window, or if magic is started with "-d NULL" then only the normal macros are available. Note that with the "-d NULL" option, magic will warn about 'Unrecognized macro name XK_xxx' on startup. For the uppercase version of the 'i' key, which you get when the 'shift' key and the 'i' key are depressed simultaneously, you would use: macro I "select more cell" macro Shift_XK_i "select more cell" Note that for some keys, such as the numbers, the shifted version is a symbol rather than a number. So the the number '3' and american keyboards, you would see: macro 3 "see allSame" macro XK_3 "see allSame" macro # "see no allSame" macro XK_3 "see no allSame" Finally, extended macros allow you to use any keyboard key as a distinct macro, along with its 'Meta', 'Control', 'Capslock', and 'Shift' variants. For instance, the up-arrow key is heavily loaded: macro XK_Up "scroll u .1" macro Shift_XK_Up "scroll u 1" macro Control_XK_Up "box +u 1" macro Control_Shift_XK_Up "box -d 1" There is one exception to the usual rule, involving the keypad. Keypads are usually set up such that Shift + a keypad number produces the ASCII number. To make it possible to distinguish between the number key and the keypad equivalent, magic parses the number key as ASCII and the keypad key as XK_KP_(number). For example: "XK_8" and "8" both refer to the "8" key. "XK_KP_Up" refers to the unshifted keypad "8" key. "XK_KP_8" refers to the shifted keypad "8" key, or the keypad "8" key by itself with "Num Lock" ON. This exception was introduced in revision 42 of magic 7.2; prior revisions did not distinguish the keypad from the number. Note that control characters should be specified with the carat ("^") notation. Embedding actual control characters in the macro definition is not compatible with the Tcl-interpreter-based version of magic, for which it is a syntax error. However, the printable carat notation is not backwardly-compatible to magic 6.X. -------------------------------------------------------------------------- The easiest way to add a macro is to type the key combination you want to use and see what magic reports (if the key combination is not already in use). For instance, typing 'a' with all the modifiers results in the message: Unknown macro or short command: 'Meta_Control_Capslock_Shift_XK_a' Finally, along with the 'macro' command, there is also an 'imacro' command. This version is an 'interactive' version of the normal macro. The assigned string is printed as if you had typed it in, allowing you to add more to the end of the command. For instance: imacro l "label " imacro XK_l "label " Now typing the 'l' key is equivalent to typing ":label ". Another example is the '!' to enter shell commands: imacro ! "shell " imacor XK_Shift_1 "shell " Now typing "!ls" followed by the return key is equivalent to typing ":shell ls" to get a directory listing. ############################################################################## # Example .magic macro file ############################################################################## macro '^L' "redraw" # A key macro a "" macro XK_a "select visible" macro A "" macro Shift_XK_a "select more visible" macro Control_XK_a "select less visible" # B key macro b "box" macro XK_b "box" macro B "" # C key macro c "" macro XK_c "copy" macro C "" # D key macro d "delete" macro XK_d "delete" macro '^D' "erase $" macro Control_XK_d "erase $" # E key macro e "edit" macro XK_e "edit" macro E "" # F key macro f "sideways" macro XK_f "sideways" macro F "upsidedown" macro Shift_XK_f "upsidedown" # G key macro g "grid" macro XK_g "grid" macro G "" # H key macro h "" macro H "" # I key macro i "select cell" macro XK_i "select cell" macro I "select more cell" macro Shift_XK_i "select more cell" macro Control_XK_i "select less cell" # J key macro j "" macro J "" # K key macro k "" macro K "" # L key imacro l "label " macro L "shell ls" # M key macro XK_m "move" macro Shift_XK_m "stretch" # N key macro n "" macro N "" # O key macro o "openwindow" macro XK_o "openwindow" macro O "closewindow" macro Shift_XK_o "closewindow" # P key imacro p "paint " imacro XK_p "paint " # Q key macro q "" macro Q "" # R key macro r "clockwise" macro XK_r "clockwise" macro R "clockwise 270" macro Shift_XK_r "clockwise 270" macro '^R' "clockwise 180" macro Control_XK_r "clockwise 180" # S key macro s "" macro XK_s "select" macro S "" macro Shift_XK_s "select more" macro Control_XK_s "select less" macro Control_Shift_XK_s "undo ; select" # T key macro t "" macro T "" # U key macro u "undo" macro XK_u "undo" macro U "redo" macro Shift_XK_u "redo" # V key macro v "" macro XK_v "xview" macro V "" macro Shift_XK_v "view" # W key macro w "writeall" macro XK_w "writeall" macro W "writeall force" macro Shift_XK_w "writeall force" # X key macro x "expand" macro XK_x "expand" macro X "unexpand" macro Shift_XK_x "unexpand" macro '^X' "expand toggle" macro Control_XK_x "expand toggle" # Y key macro y "" macro Y "" # Z key macro z "" macro XK_z "zoom .5" macro Z "" macro Shift_XK_z "zoom 2" macro Control_XK_z "center" # ? key macro ? "drc why" macro Shift_XK_question "drc why" macro / "select area; what ; select clear" macro XK_slash "select area; what ; select clear" # , key macro , "" macro XK_comma "select clear" # Quote key imacro '"' "shell " imacro XK_quotedbl "shell " imacro Shift_XK_quotedbl "shell " imacro "'" "shell " imacro XK_apostrophe "shell " imacro Shift_XK_apostrophe "shell " # Space key macro ' ' "tool" macro XK_space "tool" macro Shift_XK_space "tool box" macro Control_XK_space "tool wiring" # Arrow keys macro XK_Left "scroll l .1" macro Shift_XK_Left "scroll l 1" macro Control_XK_Left "box +l 1" macro Control_Shift_XK_Left "box -r 1" macro XK_Right "scroll r .1" macro Shift_XK_Right "scroll r 1" macro Control_XK_Right "box +r 1" macro Control_Shift_XK_Right "box -l 1" macro XK_Up "scroll u .1" macro Shift_XK_Up "scroll u 1" macro Control_XK_Up "box +u 1" macro Control_Shift_XK_Up "box -d 1" macro XK_Down "scroll d .1" macro Shift_XK_Down "scroll d 1" macro Control_XK_Down "box +d 1" macro Control_Shift_XK_Down "box -u 1" # Keypad keys macro XK_KP_0 "box w 4; box h 4" macro Shift_XK_KP_0 "box w 7; box h 2" macro Control_XK_KP_0 "box w 2; box h 7" macro XK_KP_1 "move l 1; move d 1" macro Shift_XK_KP_1 "stretch l 1; stretch d 1" macro XK_KP_2 "move d 1" macro Shift_XK_KP_2 "stretch d 1" macro XK_KP_3 "move r 1; move d 1" macro Shift_XK_KP_3 "stretch r 1; stretch d 1" macro XK_KP_4 "move l 1" macro Shift_XK_KP_4 "stretch l 1" macro XK_KP_5 "findbox zoom" macro Shift_XK_KP_5 "findbox" macro XK_KP_6 "move r 1" macro Shift_XK_KP_6 "stretch r 1" macro XK_KP_7 "move l 1; move u 1" macro Shift_XK_KP_7 "stretch l 1; stretch u 1" macro XK_KP_8 "move u 1" macro Shift_XK_KP_8 "stretch u 1" macro XK_KP_9 "move r 1; move u 1" macro Shift_XK_KP_9 "stretch r 1; stretch u 1" magic-8.0.210/doc/tutcells/0000755000175000001440000000000011504623573014064 5ustar timusersmagic-8.0.210/doc/tutcells/tut9a.mag0000644000175000001440000000162310751423606015620 0ustar timusersmagic tech scmos timestamp 502161799 << polysilicon >> rect -1 15 1 20 rect -1 9 1 11 rect -1 -1 1 1 rect -1 -10 1 -5 << ndiffusion >> rect -2 -5 -1 -1 rect 1 -5 2 -1 << pdiffusion >> rect -2 11 -1 15 rect 1 11 2 15 << metal1 >> rect -5 7 -2 11 rect -9 4 -2 7 rect -5 -1 -2 4 rect 2 7 5 11 rect 2 4 6 7 rect 2 -1 5 4 << metal2 >> rect -10 15 6 20 rect -10 -10 6 -5 << ndcontact >> rect -6 -5 -2 -1 rect 2 -5 6 -1 << pdcontact >> rect -6 11 -2 15 rect 2 11 6 15 << ntransistor >> rect -1 -5 1 -1 << ptransistor >> rect -1 11 1 15 use tut9x tut9x_0 timestamp 502161799 transform 1 0 -25 0 1 6 box -1 -16 16 14 << labels >> rlabel metal2 -9 -7 -9 -7 1 GND! rlabel metal2 -9 17 -9 17 5 Vdd! rlabel metal1 -9 5 -9 5 1 in rlabel metal2 6 -10 6 -5 7 GND! rlabel metal1 6 4 6 7 7 out rlabel metal2 6 15 6 20 7 Vdd! rlabel metal2 6 15 6 20 3 Vdd! rlabel metal2 -1 20 1 20 5 phibar rlabel metal2 -1 -10 1 -10 1 phi << end >> magic-8.0.210/doc/tutcells/tut11a.mag0000644000175000001440000000436310751423606015675 0ustar timusersmagic tech scmos timestamp 552706284 << polysilicon >> rect 190 -24 201 -22 rect 199 -42 201 -24 rect 190 -44 192 -42 rect 190 -113 199 -111 rect 203 -113 207 -111 rect 190 -129 207 -127 rect 197 -149 207 -143 rect 190 -151 207 -149 rect 197 -154 207 -151 rect 190 -159 207 -157 rect 190 -175 193 -173 rect 197 -175 207 -173 rect 8 -226 19 -224 rect 8 -233 10 -226 rect 17 -233 19 -226 rect 8 -235 19 -233 rect 8 -244 10 -235 rect 15 -237 17 -235 rect 15 -239 19 -237 rect 17 -240 19 -239 rect 17 -242 21 -240 rect 19 -244 21 -242 rect 24 -242 26 -224 rect 36 -226 47 -224 rect 36 -233 38 -226 rect 45 -233 47 -226 rect 36 -235 47 -233 rect 24 -244 33 -242 rect 36 -244 38 -235 rect 45 -244 47 -235 << metal1 >> rect -26 -19 76 -13 rect 82 -19 184 -13 rect 214 -28 224 -24 rect 190 -32 224 -28 rect 214 -35 224 -32 rect 193 -171 196 -46 rect 199 -109 202 -46 rect -34 -222 22 -216 rect 28 -222 130 -216 rect 136 -222 191 -216 << metal2 >> rect -32 -22 -26 -19 rect 76 -22 82 -19 rect 184 -22 190 -19 rect -4 -245 0 -197 rect 22 -216 28 -199 rect 50 -245 54 -197 rect 104 -245 108 -197 rect 130 -216 136 -199 rect 158 -245 162 -197 << polycontact >> rect 192 -46 196 -42 rect 199 -46 203 -42 rect 199 -113 203 -109 rect 193 -175 197 -171 << m2contact >> rect -32 -19 -26 -13 rect 76 -19 82 -13 rect 184 -19 190 -13 rect -4 -197 0 -193 rect 50 -197 54 -193 rect 104 -197 108 -193 rect 158 -197 162 -193 rect 22 -222 28 -216 rect 130 -222 136 -216 use tut11c bit_3 timestamp 552706284 transform 0 1 28 -1 0 -62 box -40 -60 137 0 use tut11b bit_2 timestamp 552706284 transform 0 1 82 -1 0 -62 box -40 -60 137 0 use tut11c bit_1 timestamp 552706284 transform 0 1 136 -1 0 -62 box -40 -60 137 0 use tut11b bit_0 timestamp 552706284 transform 0 1 190 -1 0 -62 box -40 -60 137 0 << labels >> rlabel metal1 224 -35 224 -24 7 hold rlabel polysilicon 207 -113 207 -111 7 phi1 rlabel metal1 191 -222 191 -216 1 GND rlabel m2contact 190 -19 190 -13 5 Vdd rlabel polysilicon 207 -129 207 -127 7 phi1_b rlabel polysilicon 207 -159 207 -157 7 phi2 rlabel polysilicon 207 -175 207 -173 7 phi2_b rlabel metal2 160 -245 160 -245 5 bit_0 rlabel metal2 106 -245 106 -245 5 bit_1 rlabel metal2 52 -245 52 -245 5 bit_2 rlabel metal2 -2 -245 -2 -245 5 bit_3 rlabel polysilicon 202 -143 202 -143 1 RESET_B << end >> magic-8.0.210/doc/tutcells/tut2.f1a.cif0000644000175000001440000000112710751423606016112 0ustar timusersDS 1 200 4; 9 shiftcell; L NP; B 40 8 20 24; B 16 8 76 24; B 8 100 52 50; B 24 36 20 62; B 20 16 150 196; B 20 16 -82 -84; L ND; B 16 12 20 6; B 24 20 20 22; B 68 8 42 36; B 8 12 72 26; B 16 16 20 92; B 8 44 20 62; L NM; B 84 16 42 8; B 84 16 42 92; L NI; B 16 52 20 62; L NB; B 16 20 20 46; B 16 20 72 26; L NC; B 8 8 20 8; B 8 8 20 92; 2A "In" T 4 24; 0V 4 24 4 24 4 24 4 24 4 24; 2A "Vdd" T 4 92; 0V 4 92 4 92 4 92 4 92 4 92; 2A "GND" T 4 8; 0V 4 8 4 8 4 8 4 8 4 8; 2A "Phi" T 52 68; 0V 52 68 52 68 52 68 52 68 52 68; 2A "Out" T 80 24; 0V 80 24 80 24 80 24 80 24 80 24; DF; C 1; End magic-8.0.210/doc/tutcells/tuttcl1.cmd0000644000175000001440000000020410751423606016143 0ustar timusers# Simulation script tuttcl1.cmd # For use with Tcl-based magic and Tcl-based IRSIM # This script corresponds to layout tut11a.mag # magic-8.0.210/doc/tutcells/tut11a.al0000644000175000001440000000344610751423606015526 0ustar timusers= bit_3 bit_3/tut11d_0/B = bit_3 bit_3/5_73_39# = bit_3 bit_3/tut11d_0/Q_out = bit_3/5_69_27# bit_3/tut11d_0/5_23_109# = bit_3/5_69_27# bit_2/5_69_105# = bit_2 bit_2/tut11d_0/B = bit_2 bit_2/5_73_87# = bit_2 bit_2/tut11d_0/Q_out = bit_2/5_69_83# bit_2/tut11d_0/5_23_109# = bit_2/5_69_83# bit_1/5_69_49# = bit_1 bit_1/tut11d_0/B = bit_1 bit_1/5_73_39# = bit_1 bit_1/tut11d_0/Q_out = bit_1/5_69_27# bit_1/tut11d_0/5_23_109# = bit_1/5_69_27# bit_0/5_69_105# = phi2_b bit_3/tut11d_0/phi2_b = phi2_b bit_2/tut11d_0/phi2_b = phi2_b bit_1/tut11d_0/phi2_b = phi2_b bit_0/tut11d_0/phi2_b = phi2_b bit_3/5_41_121# = phi2_b bit_2/5_41_121# = phi2_b bit_1/5_41_121# = phi2_b bit_0/5_41_121# = phi1 bit_3/tut11d_0/phi1 = phi1 bit_2/tut11d_0/phi1 = phi1 bit_1/tut11d_0/phi1 = phi1 bit_0/tut11d_0/phi1 = phi1 bit_3/5_81_121# = phi1 bit_2/5_81_121# = phi1 bit_1/5_81_121# = phi1 bit_0/5_81_121# = phi2 bit_3/tut11d_0/phi2 = phi2 bit_2/tut11d_0/phi2 = phi2 bit_1/tut11d_0/phi2 = phi2 bit_0/tut11d_0/phi2 = RESET_B bit_3/tut11d_0/reset_b = RESET_B bit_2/tut11d_0/reset_b = RESET_B bit_1/tut11d_0/reset_b = RESET_B bit_0/tut11d_0/reset_b = phi1_b bit_3/tut11d_0/phi1_b = phi1_b bit_2/tut11d_0/phi1_b = phi1_b bit_1/tut11d_0/phi1_b = phi1_b bit_0/tut11d_0/phi1_b = hold bit_0/5_69_83# = hold bit_0/tut11d_0/5_23_109# = bit_0 bit_0/tut11d_0/B = bit_0 bit_0/5_73_87# = bit_0 bit_0/tut11d_0/Q_out = Vdd bit_3/tut11d_0/Vdd = Vdd bit_3/5_37_89# = Vdd bit_2/tut11d_0/Vdd = Vdd bit_2/5_37_45# = Vdd bit_1/tut11d_0/Vdd = Vdd bit_1/5_37_89# = Vdd bit_0/tut11d_0/Vdd = Vdd bit_0/5_37_45# = GND bit_3/tut11d_0/GND = GND bit_1/tut11d_0/GND = GND bit_1/7_81_13# = GND bit_1/4_81_57# = GND bit_3/7_81_13# = GND bit_3/4_81_57# = GND bit_2/tut11d_0/GND = GND bit_2/7_81_121# = GND bit_2/4_81_121# = GND bit_0/tut11d_0/GND = GND bit_0/7_81_121# = GND bit_0/4_81_121# magic-8.0.210/doc/tutcells/tut8b.mag0000644000175000001440000000072110751423606015616 0ustar timusersmagic tech scmos timestamp 500619087 << polysilicon >> rect -6 5 0 7 rect 3 5 10 7 << ndiffusion >> rect 0 7 3 8 rect 0 4 3 5 << metal1 >> rect -6 8 0 12 rect 4 8 10 12 rect -6 0 0 4 rect 4 0 10 4 << ndcontact >> rect 0 8 4 12 rect 0 0 4 4 << ntransistor >> rect 0 5 3 7 use tut8d tut8d_0 timestamp 500619087 transform 1 0 0 0 1 3 box 10 -3 18 9 << labels >> rlabel metal1 -6 0 -6 4 3 Out rlabel metal1 -6 8 -6 12 3 In rlabel polysilicon -6 5 -6 7 3 Gate << end >> magic-8.0.210/doc/tutcells/maint2a.mag0000644000175000001440000000056210751423606016106 0ustar timusersmagic tech scmos timestamp 617322824 << polysilicon >> rect -13 8 -9 10 rect -6 8 10 10 rect -13 1 -9 5 rect -6 1 -3 5 << ndiffusion >> rect -9 10 -6 13 rect -9 5 -6 8 rect -9 -1 -6 1 rect -9 -9 -6 -5 << metal1 >> rect 1 1 10 4 rect -6 -5 10 -2 << polycontact >> rect -3 1 1 5 << ndcontact >> rect -10 -5 -6 -1 << ntransistor >> rect -9 8 -6 10 rect -9 1 -6 5 << end >> magic-8.0.210/doc/tutcells/tut11a.sim0000644000175000001440000003424010751423606015716 0ustar timusers| units: 100 tech: scmos format: SU p hold Vdd bit_0/tut11d_0/A_b 2 6 175 -52 g=S_Vdd! s=A_1108,P_688 d=A_30,P_22 p bit_0/tut11d_0/A_b bit_0/tut11d_0/A Vdd 2 5 172 -63 g=S_Vdd! s=A_25,P_20 d=A_0,P_0 p bit_0 bit_0/tut11d_0/B_b Vdd 2 6 167 -79 g=S_Vdd! s=A_30,P_22 d=A_0,P_0 p bit_0/tut11d_0/A_b Vdd bit_0/tut11d_0/a_26_n23# 2 6 167 -87 g=S_Vdd! s=A_0,P_0 d=A_18,P_18 p bit_0/tut11d_0/B_b bit_0/tut11d_0/a_26_n23# bit_0/tut11d_0/a_31_n39# 2 6 167 -92 g=S_Vdd! s=A_0,P_0 d=A_66,P_46 p bit_0 bit_0/tut11d_0/a_31_n39# bit_0/tut11d_0/a_39_n23# 2 6 167 -100 g=S_Vdd! s=A_0,P_0 d=A_12,P_16 p bit_0/tut11d_0/A bit_0/tut11d_0/a_39_n23# Vdd 2 6 167 -104 g=S_Vdd! s=A_0,P_0 d=A_0,P_0 n bit_0 bit_0/tut11d_0/B_b GND 2 6 151 -79 g=S_GND s=A_30,P_34 d=A_792,P_896 n bit_0/tut11d_0/A_b GND bit_0/tut11d_0/a_26_n39# 2 6 151 -87 g=S_GND s=A_0,P_0 d=A_18,P_18 n bit_0 bit_0/tut11d_0/a_26_n39# bit_0/tut11d_0/a_31_n39# 2 6 151 -92 g=S_GND s=A_0,P_0 d=A_66,P_82 n bit_0/tut11d_0/B_b bit_0/tut11d_0/a_31_n39# bit_0/tut11d_0/a_39_n39# 2 6 151 -100 g=S_GND s=A_0,P_0 d=A_12,P_16 n bit_0/tut11d_0/A bit_0/tut11d_0/a_39_n39# GND 2 6 151 -104 g=S_GND s=A_0,P_0 d=A_0,P_0 n hold bit_0/tut11d_0/A_b GND 2 6 138 -52 g=S_GND s=A_30,P_34 d=A_0,P_0 n bit_0/tut11d_0/A_b GND bit_0/tut11d_0/A 2 6 138 -61 g=S_GND s=A_0,P_0 d=A_30,P_34 p phi1_b bit_0/tut11d_0/a_31_n39# bit_0/tut11d_0/a_55_n47# 2 6 172 -118 g=S_Vdd! s=A_0,P_0 d=A_30,P_22 p RESET_B Vdd bit_0/tut11d_0/a_77_n40# 2 5 173 -150 g=S_Vdd! s=A_0,P_0 d=A_117,P_80 n phi1 bit_0/tut11d_0/a_55_n47# bit_0/tut11d_0/a_31_n39# 2 6 148 -118 g=S_GND s=A_30,P_34 d=A_0,P_0 p bit_0/tut11d_0/a_55_n47# bit_0/tut11d_0/a_77_n40# Vdd 2 6 170 -140 g=S_Vdd! s=A_0,P_0 d=A_0,P_0 n bit_0/tut11d_0/a_55_n47# bit_0/tut11d_0/a_77_n44# bit_0/tut11d_0/a_77_n40# 2 6 148 -140 g=S_GND s=A_12,P_16 d=A_60,P_68 n RESET_B GND bit_0/tut11d_0/a_77_n44# 2 6 144 -140 g=S_GND s=A_0,P_0 d=A_0,P_0 p phi2_b bit_0/tut11d_0/a_77_n40# bit_0/tut11d_0/a_101_n47# 2 6 170 -164 g=S_Vdd! s=A_0,P_0 d=A_30,P_22 n phi2 bit_0/tut11d_0/a_101_n47# bit_0/tut11d_0/a_77_n40# 2 6 148 -164 g=S_GND s=A_30,P_34 d=A_0,P_0 p bit_0/tut11d_0/a_101_n47# bit_0 Vdd 2 12 170 -186 g=S_Vdd! s=A_60,P_34 d=A_0,P_0 n bit_0/tut11d_0/a_101_n47# GND bit_0 2 12 148 -186 g=S_GND s=A_0,P_0 d=A_60,P_58 p phi2_b bit_1/a_n34_n13# Vdd 2 6 168 -43 g=S_Vdd! s=A_24,P_22 d=A_0,P_0 n bit_0 bit_0/a_n34_n45# hold 2 6 147 -29 g=S_GND s=A_12,P_16 d=A_24,P_36 n phi1 bit_1/a_n34_n13# bit_0/a_n34_n45# 2 6 143 -29 g=S_GND s=A_48,P_72 d=A_0,P_0 p bit_1/a_n34_n13# Vdd bit_1/tut11d_0/A_b 2 6 90 -52 g=S_Vdd! s=A_0,P_0 d=A_30,P_22 p bit_1/tut11d_0/A_b bit_1/tut11d_0/A Vdd 2 5 93 -63 g=S_Vdd! s=A_25,P_20 d=A_0,P_0 p bit_1 bit_1/tut11d_0/B_b Vdd 2 6 98 -79 g=S_Vdd! s=A_30,P_22 d=A_0,P_0 p bit_1/tut11d_0/A_b Vdd bit_1/tut11d_0/a_26_n23# 2 6 98 -87 g=S_Vdd! s=A_0,P_0 d=A_18,P_18 p bit_1/tut11d_0/B_b bit_1/tut11d_0/a_26_n23# bit_1/tut11d_0/a_31_n39# 2 6 98 -92 g=S_Vdd! s=A_0,P_0 d=A_66,P_46 p bit_1 bit_1/tut11d_0/a_31_n39# bit_1/tut11d_0/a_39_n23# 2 6 98 -100 g=S_Vdd! s=A_0,P_0 d=A_12,P_16 p bit_1/tut11d_0/A bit_1/tut11d_0/a_39_n23# Vdd 2 6 98 -104 g=S_Vdd! s=A_0,P_0 d=A_0,P_0 n bit_1 bit_1/tut11d_0/B_b GND 2 6 114 -79 g=S_GND s=A_30,P_34 d=A_0,P_0 n bit_1/tut11d_0/A_b GND bit_1/tut11d_0/a_26_n39# 2 6 114 -87 g=S_GND s=A_0,P_0 d=A_18,P_18 n bit_1 bit_1/tut11d_0/a_26_n39# bit_1/tut11d_0/a_31_n39# 2 6 114 -92 g=S_GND s=A_0,P_0 d=A_66,P_82 n bit_1/tut11d_0/B_b bit_1/tut11d_0/a_31_n39# bit_1/tut11d_0/a_39_n39# 2 6 114 -100 g=S_GND s=A_0,P_0 d=A_12,P_16 n bit_1/tut11d_0/A bit_1/tut11d_0/a_39_n39# GND 2 6 114 -104 g=S_GND s=A_0,P_0 d=A_0,P_0 n bit_1/a_n34_n13# bit_1/tut11d_0/A_b GND 2 6 127 -52 g=S_GND s=A_30,P_34 d=A_0,P_0 n bit_1/tut11d_0/A_b GND bit_1/tut11d_0/A 2 6 127 -61 g=S_GND s=A_0,P_0 d=A_30,P_34 p phi1_b bit_1/tut11d_0/a_31_n39# bit_1/tut11d_0/a_55_n47# 2 6 93 -118 g=S_Vdd! s=A_0,P_0 d=A_30,P_22 p RESET_B Vdd bit_1/tut11d_0/a_77_n40# 2 5 92 -150 g=S_Vdd! s=A_0,P_0 d=A_117,P_80 n phi1 bit_1/tut11d_0/a_55_n47# bit_1/tut11d_0/a_31_n39# 2 6 117 -118 g=S_GND s=A_30,P_34 d=A_0,P_0 p bit_1/tut11d_0/a_55_n47# bit_1/tut11d_0/a_77_n40# Vdd 2 6 95 -140 g=S_Vdd! s=A_0,P_0 d=A_0,P_0 n bit_1/tut11d_0/a_55_n47# bit_1/tut11d_0/a_77_n44# bit_1/tut11d_0/a_77_n40# 2 6 117 -140 g=S_GND s=A_12,P_16 d=A_60,P_68 n RESET_B GND bit_1/tut11d_0/a_77_n44# 2 6 121 -140 g=S_GND s=A_0,P_0 d=A_0,P_0 p phi2_b bit_1/tut11d_0/a_77_n40# bit_1/tut11d_0/a_101_n47# 2 6 95 -164 g=S_Vdd! s=A_0,P_0 d=A_30,P_22 n phi2 bit_1/tut11d_0/a_101_n47# bit_1/tut11d_0/a_77_n40# 2 6 117 -164 g=S_GND s=A_30,P_34 d=A_0,P_0 p bit_1/tut11d_0/a_101_n47# bit_1 Vdd 2 12 95 -186 g=S_Vdd! s=A_60,P_34 d=A_0,P_0 n bit_1/tut11d_0/a_101_n47# GND bit_1 2 12 117 -186 g=S_GND s=A_0,P_0 d=A_60,P_58 n phi1 bit_1/a_n34_n17# bit_1/a_n34_n13# 2 6 121 -29 g=S_GND s=A_12,P_16 d=A_0,P_0 n bit_1 bit_2/a_n34_n41# bit_1/a_n34_n17# 2 6 117 -29 g=S_GND s=A_48,P_72 d=A_0,P_0 p phi2_b bit_2/a_n34_n41# Vdd 2 6 92 -43 g=S_Vdd! s=A_24,P_22 d=A_0,P_0 p bit_2/a_n34_n41# Vdd bit_2/tut11d_0/A_b 2 6 67 -52 g=S_Vdd! s=A_0,P_0 d=A_30,P_22 p bit_2/tut11d_0/A_b bit_2/tut11d_0/A Vdd 2 5 64 -63 g=S_Vdd! s=A_25,P_20 d=A_0,P_0 p bit_2 bit_2/tut11d_0/B_b Vdd 2 6 59 -79 g=S_Vdd! s=A_30,P_22 d=A_0,P_0 p bit_2/tut11d_0/A_b Vdd bit_2/tut11d_0/a_26_n23# 2 6 59 -87 g=S_Vdd! s=A_0,P_0 d=A_18,P_18 p bit_2/tut11d_0/B_b bit_2/tut11d_0/a_26_n23# bit_2/tut11d_0/a_31_n39# 2 6 59 -92 g=S_Vdd! s=A_0,P_0 d=A_66,P_46 p bit_2 bit_2/tut11d_0/a_31_n39# bit_2/tut11d_0/a_39_n23# 2 6 59 -100 g=S_Vdd! s=A_0,P_0 d=A_12,P_16 p bit_2/tut11d_0/A bit_2/tut11d_0/a_39_n23# Vdd 2 6 59 -104 g=S_Vdd! s=A_0,P_0 d=A_0,P_0 n bit_2 bit_2/tut11d_0/B_b GND 2 6 43 -79 g=S_GND s=A_30,P_34 d=A_0,P_0 n bit_2/tut11d_0/A_b GND bit_2/tut11d_0/a_26_n39# 2 6 43 -87 g=S_GND s=A_0,P_0 d=A_18,P_18 n bit_2 bit_2/tut11d_0/a_26_n39# bit_2/tut11d_0/a_31_n39# 2 6 43 -92 g=S_GND s=A_0,P_0 d=A_66,P_82 n bit_2/tut11d_0/B_b bit_2/tut11d_0/a_31_n39# bit_2/tut11d_0/a_39_n39# 2 6 43 -100 g=S_GND s=A_0,P_0 d=A_12,P_16 n bit_2/tut11d_0/A bit_2/tut11d_0/a_39_n39# GND 2 6 43 -104 g=S_GND s=A_0,P_0 d=A_0,P_0 n bit_2/a_n34_n41# bit_2/tut11d_0/A_b GND 2 6 30 -52 g=S_GND s=A_30,P_34 d=A_0,P_0 n bit_2/tut11d_0/A_b GND bit_2/tut11d_0/A 2 6 30 -61 g=S_GND s=A_0,P_0 d=A_30,P_34 p phi1_b bit_2/tut11d_0/a_31_n39# bit_2/tut11d_0/a_55_n47# 2 6 64 -118 g=S_Vdd! s=A_0,P_0 d=A_30,P_22 p RESET_B Vdd bit_2/tut11d_0/a_77_n40# 2 5 65 -150 g=S_Vdd! s=A_0,P_0 d=A_117,P_80 n phi1 bit_2/tut11d_0/a_55_n47# bit_2/tut11d_0/a_31_n39# 2 6 40 -118 g=S_GND s=A_30,P_34 d=A_0,P_0 p bit_2/tut11d_0/a_55_n47# bit_2/tut11d_0/a_77_n40# Vdd 2 6 62 -140 g=S_Vdd! s=A_0,P_0 d=A_0,P_0 n bit_2/tut11d_0/a_55_n47# bit_2/tut11d_0/a_77_n44# bit_2/tut11d_0/a_77_n40# 2 6 40 -140 g=S_GND s=A_12,P_16 d=A_60,P_68 n RESET_B GND bit_2/tut11d_0/a_77_n44# 2 6 36 -140 g=S_GND s=A_0,P_0 d=A_0,P_0 p phi2_b bit_2/tut11d_0/a_77_n40# bit_2/tut11d_0/a_101_n47# 2 6 62 -164 g=S_Vdd! s=A_0,P_0 d=A_30,P_22 n phi2 bit_2/tut11d_0/a_101_n47# bit_2/tut11d_0/a_77_n40# 2 6 40 -164 g=S_GND s=A_30,P_34 d=A_0,P_0 p bit_2/tut11d_0/a_101_n47# bit_2 Vdd 2 12 62 -186 g=S_Vdd! s=A_60,P_34 d=A_0,P_0 n bit_2/tut11d_0/a_101_n47# GND bit_2 2 12 40 -186 g=S_GND s=A_0,P_0 d=A_60,P_58 p phi2_b bit_3/a_n34_n13# Vdd 2 6 60 -43 g=S_Vdd! s=A_24,P_22 d=A_0,P_0 n bit_2 bit_2/a_n34_n45# bit_2/a_n34_n41# 2 6 39 -29 g=S_GND s=A_12,P_16 d=A_0,P_0 n phi1 bit_3/a_n34_n13# bit_2/a_n34_n45# 2 6 35 -29 g=S_GND s=A_48,P_72 d=A_0,P_0 p bit_3/a_n34_n13# Vdd bit_3/tut11d_0/A_b 2 6 -18 -52 g=S_Vdd! s=A_0,P_0 d=A_30,P_22 p bit_3/tut11d_0/A_b bit_3/tut11d_0/A Vdd 2 5 -15 -63 g=S_Vdd! s=A_25,P_20 d=A_0,P_0 p bit_3 bit_3/tut11d_0/B_b Vdd 2 6 -10 -79 g=S_Vdd! s=A_30,P_22 d=A_0,P_0 p bit_3/tut11d_0/A_b Vdd bit_3/tut11d_0/a_26_n23# 2 6 -10 -87 g=S_Vdd! s=A_0,P_0 d=A_18,P_18 p bit_3/tut11d_0/B_b bit_3/tut11d_0/a_26_n23# bit_3/tut11d_0/a_31_n39# 2 6 -10 -92 g=S_Vdd! s=A_0,P_0 d=A_66,P_46 p bit_3 bit_3/tut11d_0/a_31_n39# bit_3/tut11d_0/a_39_n23# 2 6 -10 -100 g=S_Vdd! s=A_0,P_0 d=A_12,P_16 p bit_3/tut11d_0/A bit_3/tut11d_0/a_39_n23# Vdd 2 6 -10 -104 g=S_Vdd! s=A_0,P_0 d=A_0,P_0 n bit_3 bit_3/tut11d_0/B_b GND 2 6 6 -79 g=S_GND s=A_30,P_34 d=A_0,P_0 n bit_3/tut11d_0/A_b GND bit_3/tut11d_0/a_26_n39# 2 6 6 -87 g=S_GND s=A_0,P_0 d=A_18,P_18 n bit_3 bit_3/tut11d_0/a_26_n39# bit_3/tut11d_0/a_31_n39# 2 6 6 -92 g=S_GND s=A_0,P_0 d=A_66,P_82 n bit_3/tut11d_0/B_b bit_3/tut11d_0/a_31_n39# bit_3/tut11d_0/a_39_n39# 2 6 6 -100 g=S_GND s=A_0,P_0 d=A_12,P_16 n bit_3/tut11d_0/A bit_3/tut11d_0/a_39_n39# GND 2 6 6 -104 g=S_GND s=A_0,P_0 d=A_0,P_0 n bit_3/a_n34_n13# bit_3/tut11d_0/A_b GND 2 6 19 -52 g=S_GND s=A_30,P_34 d=A_0,P_0 n bit_3/tut11d_0/A_b GND bit_3/tut11d_0/A 2 6 19 -61 g=S_GND s=A_0,P_0 d=A_30,P_34 p phi1_b bit_3/tut11d_0/a_31_n39# bit_3/tut11d_0/a_55_n47# 2 6 -15 -118 g=S_Vdd! s=A_0,P_0 d=A_30,P_22 p RESET_B Vdd bit_3/tut11d_0/a_77_n40# 2 5 -16 -150 g=S_Vdd! s=A_0,P_0 d=A_117,P_80 n phi1 bit_3/tut11d_0/a_55_n47# bit_3/tut11d_0/a_31_n39# 2 6 9 -118 g=S_GND s=A_30,P_34 d=A_0,P_0 p bit_3/tut11d_0/a_55_n47# bit_3/tut11d_0/a_77_n40# Vdd 2 6 -13 -140 g=S_Vdd! s=A_0,P_0 d=A_0,P_0 n bit_3/tut11d_0/a_55_n47# bit_3/tut11d_0/a_77_n44# bit_3/tut11d_0/a_77_n40# 2 6 9 -140 g=S_GND s=A_12,P_16 d=A_60,P_68 n RESET_B GND bit_3/tut11d_0/a_77_n44# 2 6 13 -140 g=S_GND s=A_0,P_0 d=A_0,P_0 p phi2_b bit_3/tut11d_0/a_77_n40# bit_3/tut11d_0/a_101_n47# 2 6 -13 -164 g=S_Vdd! s=A_0,P_0 d=A_30,P_22 n phi2 bit_3/tut11d_0/a_101_n47# bit_3/tut11d_0/a_77_n40# 2 6 9 -164 g=S_GND s=A_30,P_34 d=A_0,P_0 p bit_3/tut11d_0/a_101_n47# bit_3 Vdd 2 12 -13 -186 g=S_Vdd! s=A_60,P_34 d=A_0,P_0 n bit_3/tut11d_0/a_101_n47# GND bit_3 2 12 9 -186 g=S_GND s=A_0,P_0 d=A_60,P_58 n phi1 bit_3/a_n34_n17# bit_3/a_n34_n13# 2 6 13 -29 g=S_GND s=A_12,P_16 d=A_0,P_0 n bit_3 bit_3/a_n34_n24# bit_3/a_n34_n17# 2 6 9 -29 g=S_GND s=A_24,P_36 d=A_0,P_0 p phi2_b bit_3/a_n34_n24# Vdd 2 6 -16 -43 g=S_Vdd! s=A_24,P_22 d=A_0,P_0 C bit_3/tut11d_0/B_b GND 5.8 C bit_3 bit_3/tut11d_0/a_55_n47# 3.2 C bit_0/tut11d_0/A GND 15.2 C bit_2 Vdd 2.5 C bit_1/tut11d_0/a_55_n47# GND 5.9 C bit_1/tut11d_0/a_55_n47# bit_1 3.2 C bit_3 Vdd 2.5 C phi1_b GND 26.4 C bit_0/tut11d_0/a_55_n47# GND 5.9 C bit_2/tut11d_0/a_101_n47# GND 6.6 C bit_0 GND 10.0 C phi2 GND 33.3 C bit_3/tut11d_0/a_55_n47# GND 5.9 C bit_0/tut11d_0/B_b GND 5.8 C bit_1 Vdd 2.5 C bit_0/tut11d_0/a_31_n39# bit_0 2.5 C bit_0/tut11d_0/a_101_n47# GND 6.6 C bit_2 GND 10.0 C bit_0/tut11d_0/a_77_n40# bit_0 2.2 C bit_3 GND 10.5 C bit_3 bit_3/tut11d_0/a_77_n40# 2.2 C bit_0/tut11d_0/A_b GND 15.8 C bit_2/a_n34_n41# GND 7.5 C bit_2 bit_2/tut11d_0/a_31_n39# 2.5 C bit_1 bit_1/tut11d_0/a_77_n40# 2.2 C bit_1 GND 10.5 C bit_3/tut11d_0/A_b GND 15.8 C bit_1/tut11d_0/B_b GND 5.8 C bit_2/tut11d_0/a_55_n47# phi1_b 2.2 C RESET_B GND 33.3 C bit_2/tut11d_0/A GND 15.2 C phi1 GND 58.5 C bit_2/tut11d_0/B_b GND 5.8 C bit_1/tut11d_0/a_55_n47# phi1_b 2.2 C bit_2/tut11d_0/a_55_n47# bit_2 3.2 C GND bit_1/tut11d_0/a_101_n47# 6.6 C bit_0/tut11d_0/a_55_n47# phi1_b 2.2 C bit_3 bit_3/tut11d_0/a_31_n39# 2.5 C bit_0/tut11d_0/a_55_n47# bit_0 3.2 C bit_1/tut11d_0/A_b GND 15.8 C hold GND 6.7 C bit_3/tut11d_0/a_101_n47# GND 6.6 C bit_3/tut11d_0/a_55_n47# phi1_b 2.2 C bit_2/tut11d_0/A_b GND 15.8 C bit_2/tut11d_0/a_55_n47# GND 5.9 C Vdd bit_0 2.5 C phi2_b GND 52.5 C bit_3/tut11d_0/A GND 15.2 C bit_1/tut11d_0/a_31_n39# bit_1 2.5 C bit_1/tut11d_0/A GND 15.2 C bit_3/a_n34_n13# GND 16.9 C bit_1/a_n34_n13# GND 16.9 C bit_2/tut11d_0/a_77_n40# bit_2 2.2 C a_36_n244# GND 12.9 R a_36_n244# 596 C a_24_n244# GND 6.7 R a_24_n244# 322 C a_8_n244# GND 13.8 R a_8_n244# 643 C bit_3/a_n34_n24# GND 8.1 R bit_3/a_n34_n24# 464 R bit_3/a_n34_n17# 80 C bit_3/tut11d_0/a_101_n47# GND 11.5 R bit_3/tut11d_0/a_101_n47# 820 R bit_3/tut11d_0/a_77_n44# 80 C bit_3/tut11d_0/a_77_n40# GND 11.1 R bit_3/tut11d_0/a_77_n40# 1150 C bit_3/tut11d_0/a_55_n47# GND 11.3 R bit_3/tut11d_0/a_55_n47# 773 R bit_3/tut11d_0/a_39_n39# 80 R bit_3/tut11d_0/a_26_n39# 53 R bit_3/tut11d_0/a_39_n23# 179 C bit_3/tut11d_0/a_31_n39# GND 9.6 R bit_3/tut11d_0/a_31_n39# 973 R bit_3/tut11d_0/a_26_n23# 119 C bit_3/tut11d_0/A GND 7.0 R bit_3/tut11d_0/A 1107 C bit_3/tut11d_0/B_b GND 12.3 R bit_3/tut11d_0/B_b 713 C bit_3/tut11d_0/A_b GND 14.6 R bit_3/tut11d_0/A_b 1537 C bit_3 GND 46.3 R bit_3 2324 R bit_2/a_n34_n45# 80 C bit_3/a_n34_n13# GND 12.2 R bit_3/a_n34_n13# 1386 C bit_2/tut11d_0/a_101_n47# GND 11.5 R bit_2/tut11d_0/a_101_n47# 820 R bit_2/tut11d_0/a_77_n44# 80 C bit_2/tut11d_0/a_77_n40# GND 11.1 R bit_2/tut11d_0/a_77_n40# 1150 C bit_2/tut11d_0/a_55_n47# GND 11.3 R bit_2/tut11d_0/a_55_n47# 773 R bit_2/tut11d_0/a_39_n39# 80 R bit_2/tut11d_0/a_26_n39# 53 R bit_2/tut11d_0/a_39_n23# 179 C bit_2/tut11d_0/a_31_n39# GND 9.6 R bit_2/tut11d_0/a_31_n39# 973 R bit_2/tut11d_0/a_26_n23# 119 C bit_2/tut11d_0/A GND 7.0 R bit_2/tut11d_0/A 1107 C bit_2/tut11d_0/B_b GND 12.3 R bit_2/tut11d_0/B_b 713 C bit_2/tut11d_0/A_b GND 14.6 R bit_2/tut11d_0/A_b 1537 C bit_2 GND 46.9 R bit_2 2324 C bit_2/a_n34_n41# GND 21.0 R bit_2/a_n34_n41# 1386 R bit_1/a_n34_n17# 80 C bit_1/tut11d_0/a_101_n47# GND 11.5 R bit_1/tut11d_0/a_101_n47# 820 R bit_1/tut11d_0/a_77_n44# 80 C bit_1/tut11d_0/a_77_n40# GND 11.1 R bit_1/tut11d_0/a_77_n40# 1150 C bit_1/tut11d_0/a_55_n47# GND 11.3 R bit_1/tut11d_0/a_55_n47# 773 R bit_1/tut11d_0/a_39_n39# 80 R bit_1/tut11d_0/a_26_n39# 53 R bit_1/tut11d_0/a_39_n23# 179 C bit_1/tut11d_0/a_31_n39# GND 9.6 R bit_1/tut11d_0/a_31_n39# 973 R bit_1/tut11d_0/a_26_n23# 119 C bit_1/tut11d_0/A GND 7.0 R bit_1/tut11d_0/A 1107 C bit_1/tut11d_0/B_b GND 12.3 R bit_1/tut11d_0/B_b 713 C bit_1/tut11d_0/A_b GND 14.6 R bit_1/tut11d_0/A_b 1537 C bit_1 GND 46.3 R bit_1 2324 R bit_0/a_n34_n45# 80 C bit_1/a_n34_n13# GND 12.2 R bit_1/a_n34_n13# 1386 C phi2_b GND 86.3 R phi2_b 6913 C phi1 GND 90.6 R phi1 7806 C bit_0/tut11d_0/a_101_n47# GND 11.5 R bit_0/tut11d_0/a_101_n47# 820 C phi2 GND 34.8 R phi2 3784 R bit_0/tut11d_0/a_77_n44# 80 C bit_0/tut11d_0/a_77_n40# GND 11.1 R bit_0/tut11d_0/a_77_n40# 1150 C RESET_B GND 36.3 R RESET_B 3486 C phi1_b GND 41.8 R phi1_b 3784 C bit_0/tut11d_0/a_55_n47# GND 11.3 R bit_0/tut11d_0/a_55_n47# 773 R bit_0/tut11d_0/a_39_n39# 80 R bit_0/tut11d_0/a_26_n39# 53 R bit_0/tut11d_0/a_39_n23# 179 C bit_0/tut11d_0/a_31_n39# GND 9.6 R bit_0/tut11d_0/a_31_n39# 973 R bit_0/tut11d_0/a_26_n23# 119 C bit_0/tut11d_0/A GND 7.0 R bit_0/tut11d_0/A 1107 C bit_0/tut11d_0/B_b GND 12.3 R bit_0/tut11d_0/B_b 713 C bit_0/tut11d_0/A_b GND 14.6 R bit_0/tut11d_0/A_b 1537 C hold GND 23.4 R hold 866 C bit_0 GND 46.9 R bit_0 2324 C Vdd GND 302.9 R Vdd 9192 C GND GND 297.9 R GND 13271 magic-8.0.210/doc/tutcells/tut11d.mag0000644000175000001440000001454710751423606015705 0ustar timusersmagic tech scmos timestamp 552706284 << polysilicon >> rect 24 -7 38 -5 rect -11 -9 -9 -7 rect 24 -8 26 -7 rect 16 -10 26 -8 rect 17 -14 18 -10 rect -11 -46 -9 -15 rect -4 -18 0 -16 rect 5 -18 8 -16 rect 16 -17 18 -14 rect 24 -17 26 -13 rect 36 -13 38 -7 rect 29 -17 31 -14 rect 36 -15 39 -13 rect 37 -17 39 -15 rect 41 -17 43 -15 rect -4 -26 -2 -18 rect -4 -43 -2 -30 rect 16 -33 18 -23 rect 24 -33 26 -23 rect 29 -26 31 -23 rect 37 -24 39 -23 rect 33 -26 39 -24 rect 33 -29 35 -26 rect 29 -31 35 -29 rect 29 -33 31 -31 rect 37 -33 39 -29 rect 41 -33 43 -23 rect 16 -41 18 -39 rect 24 -43 26 -39 rect 29 -42 31 -39 rect 37 -42 39 -39 rect -4 -45 26 -43 rect -2 -46 0 -45 rect 38 -46 39 -42 rect 41 -50 43 -39 rect 49 -40 51 0 rect 65 -16 67 0 rect 87 -12 89 0 rect 53 -18 55 -16 rect 61 -18 67 -16 rect 49 -42 55 -40 rect 61 -42 63 -40 rect 11 -52 43 -50 rect -11 -54 -9 -52 rect -2 -54 0 -52 rect 52 -60 54 -42 rect 65 -60 67 -18 rect 74 -20 77 -18 rect 83 -20 85 -18 rect 74 -40 76 -20 rect 74 -42 77 -40 rect 83 -42 85 -40 rect 87 -44 89 -17 rect 75 -46 77 -44 rect 83 -46 89 -44 rect 87 -60 89 -46 rect 95 -40 97 0 rect 111 -18 113 0 rect 99 -20 101 -18 rect 107 -20 113 -18 rect 95 -42 101 -40 rect 107 -42 109 -40 rect 95 -60 97 -42 rect 111 -60 113 -20 rect 120 -20 123 -18 rect 135 -20 137 -18 rect 120 -42 123 -40 rect 135 -42 137 -40 << ndiffusion >> rect 15 -39 16 -33 rect 18 -39 19 -33 rect 23 -39 24 -33 rect 26 -39 29 -33 rect 31 -39 32 -33 rect 36 -39 37 -33 rect 39 -39 41 -33 rect 43 -39 44 -33 rect -12 -52 -11 -46 rect -9 -52 -8 -46 rect -4 -52 -2 -46 rect 0 -52 1 -46 rect 55 -40 61 -39 rect 55 -43 61 -42 rect 77 -40 83 -39 rect 77 -44 83 -42 rect 77 -47 83 -46 rect 101 -40 107 -39 rect 101 -43 107 -42 rect 123 -40 135 -39 rect 123 -43 135 -42 << pdiffusion >> rect -13 -15 -11 -9 rect -9 -15 -8 -9 rect 0 -16 5 -15 rect 0 -19 5 -18 rect 15 -23 16 -17 rect 18 -23 19 -17 rect 23 -23 24 -17 rect 26 -23 29 -17 rect 31 -23 32 -17 rect 36 -23 37 -17 rect 39 -23 41 -17 rect 43 -23 44 -17 rect 55 -16 61 -15 rect 84 -17 87 -12 rect 89 -17 94 -12 rect 77 -18 83 -17 rect 55 -19 61 -18 rect 77 -21 83 -20 rect 90 -21 94 -17 rect 101 -18 107 -17 rect 101 -21 107 -20 rect 123 -18 135 -17 rect 123 -21 135 -20 << metal1 >> rect -17 -9 -13 -5 rect 2 -5 3 -1 rect 7 -5 8 -1 rect -9 -15 -8 -9 rect 2 -11 5 -5 rect 12 -14 13 -10 rect -8 -26 -5 -15 rect 20 -17 23 -1 rect 44 -5 55 -1 rect 61 -5 72 -1 rect 76 -5 77 -1 rect -1 -23 0 -19 rect -8 -30 -6 -26 rect -8 -40 -5 -30 rect -15 -43 -5 -40 rect -15 -46 -12 -43 rect 1 -46 4 -23 rect 12 -26 15 -23 rect 26 -26 29 -10 rect 44 -17 48 -5 rect 83 -5 90 -1 rect 94 -5 102 -1 rect 106 -5 114 -1 rect 118 -5 123 -1 rect 61 -15 68 -11 rect 12 -29 29 -26 rect 12 -33 15 -29 rect -9 -52 -8 -46 rect 5 -52 7 -48 rect -8 -55 -4 -52 rect 20 -55 23 -39 rect 26 -43 29 -29 rect 32 -27 36 -23 rect 55 -27 61 -23 rect 32 -30 61 -27 rect 32 -33 36 -30 rect 55 -35 61 -30 rect 64 -28 68 -15 rect 77 -12 83 -6 rect 135 -5 137 -1 rect 123 -13 135 -6 rect 107 -17 119 -13 rect 135 -17 137 -13 rect 115 -21 116 -17 rect 83 -25 90 -21 rect 94 -25 101 -21 rect 64 -32 70 -28 rect 26 -46 34 -43 rect 45 -55 48 -39 rect 64 -43 68 -32 rect 77 -35 83 -25 rect 101 -35 107 -25 rect 115 -39 119 -21 rect 123 -28 135 -25 rect 127 -32 135 -28 rect 123 -35 135 -32 rect 115 -43 116 -39 rect 61 -47 68 -43 rect 107 -47 119 -43 rect 135 -47 137 -43 rect 77 -55 83 -51 rect 123 -54 135 -47 rect 20 -59 21 -55 rect 25 -59 27 -55 rect 38 -59 40 -55 rect 44 -59 56 -55 rect 60 -59 78 -55 rect 82 -59 90 -55 rect 94 -59 102 -55 rect 106 -59 114 -55 rect 118 -59 123 -55 rect 135 -59 137 -55 << metal2 >> rect -17 -1 77 0 rect -13 -5 8 -1 rect 20 -5 77 -1 rect -17 -6 77 -5 rect 83 -6 123 0 rect 135 -6 137 0 rect 8 -19 12 -14 rect -17 -23 69 -19 rect 65 -28 69 -23 rect 65 -32 123 -28 rect -17 -55 90 -54 rect -17 -59 -8 -55 rect -4 -59 27 -55 rect 38 -59 90 -55 rect -17 -60 90 -59 rect 94 -60 123 -54 rect 135 -60 137 -54 << pwell >> rect -17 -31 -9 -30 rect -17 -32 57 -31 rect -17 -60 137 -32 << polycontact >> rect 13 -14 17 -10 rect 29 -14 33 -10 rect -6 -30 -2 -26 rect 34 -46 38 -42 rect 7 -52 11 -48 rect 70 -32 74 -28 rect 116 -21 120 -17 rect 116 -43 120 -39 << ndcontact >> rect 11 -39 15 -33 rect 19 -39 23 -33 rect 32 -39 36 -33 rect 44 -39 48 -33 rect -16 -52 -12 -46 rect -8 -52 -4 -46 rect 1 -52 5 -46 rect 55 -39 61 -35 rect 55 -47 61 -43 rect 77 -39 83 -35 rect 77 -51 83 -47 rect 101 -39 107 -35 rect 101 -47 107 -43 rect 123 -39 135 -35 rect 123 -47 135 -43 << pdcontact >> rect -17 -18 -13 -9 rect -8 -15 -4 -9 rect 0 -15 5 -11 rect 0 -23 5 -19 rect 11 -23 15 -17 rect 19 -23 23 -17 rect 32 -23 36 -17 rect 44 -23 48 -17 rect 55 -15 61 -11 rect 77 -17 84 -12 rect 55 -23 61 -19 rect 77 -25 83 -21 rect 90 -25 94 -21 rect 101 -17 107 -13 rect 123 -17 135 -13 rect 101 -25 107 -21 rect 123 -25 135 -21 << m2contact >> rect -17 -5 -13 -1 rect 8 -5 20 -1 rect 8 -14 12 -10 rect 77 -6 83 0 rect 123 -6 135 0 rect 123 -32 127 -28 rect -8 -59 -4 -55 rect 27 -59 38 -55 rect 90 -60 94 -54 rect 123 -60 135 -54 << ntransistor >> rect 16 -39 18 -33 rect 24 -39 26 -33 rect 29 -39 31 -33 rect 37 -39 39 -33 rect 41 -39 43 -33 rect -11 -52 -9 -46 rect -2 -52 0 -46 rect 55 -42 61 -40 rect 77 -42 83 -40 rect 77 -46 83 -44 rect 101 -42 107 -40 rect 123 -42 135 -40 << ptransistor >> rect -11 -15 -9 -9 rect 0 -18 5 -16 rect 16 -23 18 -17 rect 24 -23 26 -17 rect 29 -23 31 -17 rect 37 -23 39 -17 rect 41 -23 43 -17 rect 55 -18 61 -16 rect 87 -17 89 -12 rect 77 -20 83 -18 rect 101 -20 107 -18 rect 123 -20 135 -18 << psubstratepcontact >> rect 10 -59 14 -55 rect 21 -59 25 -55 rect 40 -59 44 -55 rect 56 -59 60 -55 rect 78 -59 82 -55 rect 102 -59 106 -55 rect 114 -59 118 -55 << nsubstratencontact >> rect 3 -5 7 -1 rect 40 -5 44 -1 rect 55 -5 61 -1 rect 72 -5 76 -1 rect 90 -5 94 -1 rect 102 -5 106 -1 rect 114 -5 118 -1 << labels >> rlabel metal1 129 -30 129 -30 1 Q_out rlabel polysilicon 112 -53 112 -53 1 phi2_b rlabel polysilicon 96 -52 96 -52 3 phi2 rlabel polysilicon 88 -52 88 -52 7 reset_b rlabel polysilicon 66 -53 66 -53 1 phi1_b rlabel polysilicon 50 -9 50 -9 1 phi1 rlabel polysilicon 66 -9 66 -9 1 phi1_b rlabel polysilicon 88 -10 88 -10 1 reset_b rlabel polysilicon 96 -10 96 -10 1 phi2 rlabel polysilicon 112 -10 112 -10 1 phi2_b rlabel metal2 1 -57 1 -57 3 GND rlabel metal2 1 -3 1 -3 3 Vdd rlabel polysilicon 38 -41 38 -41 1 B_b rlabel polysilicon 42 -41 42 -41 1 A rlabel polysilicon 30 -41 30 -41 1 B rlabel polysilicon 25 -41 25 -41 1 A_b << end >> magic-8.0.210/doc/tutcells/tut11d.ext0000644000175000001440000001147310751423606015734 0ustar timuserstimestamp 552706284 version 7.2 tech scmos style lambda=1.0(scna20_orb) scale 1000 1 100 resistclasses 26670 59550 23860 19690 27260 2000000 49 26 2505830 node "phi2_b" 859 9684 99 -20 p 0 0 0 0 144 148 0 0 0 0 0 0 0 0 0 0 0 0 equiv "phi2_b" "phi2_b" node "a_101_n47#" 820 11470 101 -47 ndc 30 34 30 22 100 100 0 0 0 0 0 0 176 120 0 0 0 0 node "phi2" 859 7936 95 -60 p 0 0 0 0 144 148 0 0 0 0 0 0 0 0 0 0 0 0 equiv "phi2" "phi2" node "a_77_n44#" 80 0 77 -44 ndiff 12 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 node "a_77_n40#" 1150 11092 77 -40 ndiff 60 68 117 80 0 0 0 0 0 0 0 0 176 108 0 0 0 0 node "reset_b" 859 7066 75 -46 p 0 0 0 0 144 148 0 0 0 0 0 0 0 0 0 0 0 0 equiv "reset_b" "reset_b" node "phi1_b" 859 9684 53 -18 p 0 0 0 0 144 148 0 0 0 0 0 0 0 0 0 0 0 0 equiv "phi1_b" "phi1_b" node "a_55_n47#" 773 11298 55 -47 ndc 30 34 30 22 100 96 0 0 0 0 0 0 176 96 0 0 0 0 node "phi1" 859 7698 49 -42 p 0 0 0 0 144 148 0 0 0 0 0 0 0 0 0 0 0 0 node "a_39_n39#" 80 0 39 -39 ndiff 12 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 node "a_26_n39#" 53 0 26 -39 ndiff 18 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 node "a_39_n23#" 179 0 39 -23 pdiff 0 0 12 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 node "a_31_n39#" 973 9635 31 -39 ndiff 66 82 66 46 0 0 0 0 0 0 0 0 169 96 0 0 0 0 node "a_26_n23#" 119 0 26 -23 pdiff 0 0 18 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 node "A" 1107 6996 0 -52 ndiff 30 34 25 20 150 150 0 0 0 0 0 0 81 74 0 0 0 0 node "B_b" 713 12278 11 -39 ndc 30 34 30 22 86 84 0 0 0 0 0 0 186 130 0 0 0 0 node "A_b" 1537 14566 -16 -52 ndc 30 34 30 22 220 220 0 0 0 0 0 0 116 98 0 0 0 0 node "a_n11_n54#" 561 4606 -11 -54 p 0 0 0 0 94 98 0 0 0 0 0 0 0 0 0 0 0 0 node "B" 1655 32895 13 -14 pc 60 58 60 34 212 210 0 0 0 0 0 0 140 62 648 332 0 0 equiv "B" "Q_out" node "Vdd" 2107 59727 -17 -18 pdc 120 116 255 162 0 0 0 0 0 0 0 0 650 374 924 320 0 0 node "GND" 3185 57314 -17 -60 pw 198 224 112 112 0 0 0 0 0 0 0 0 650 396 924 320 0 0 cap "B_b" "a_26_n23#" 846 cap "phi2_b" "B" 152 cap "phi1" "Vdd" 316 cap "a_55_n47#" "GND" 5868 cap "A_b" "B_b" 180 cap "a_31_n39#" "phi1" 180 cap "a_31_n39#" "B_b" 60 cap "B" "a_n11_n54#" 152 cap "phi2_b" "a_101_n47#" 480 cap "phi2_b" "GND" 6980 cap "a_26_n39#" "B_b" 846 cap "phi2" "B" 152 cap "A" "B" 1080 cap "reset_b" "B" 152 cap "phi2_b" "Vdd" 316 cap "a_101_n47#" "B" 720 cap "GND" "B" 5114 cap "a_77_n40#" "B" 2160 cap "Vdd" "B" 2150 cap "GND" "a_n11_n54#" 4684 cap "A_b" "B" 692 cap "phi1_b" "GND" 6980 cap "a_31_n39#" "B" 2516 cap "phi2" "GND" 8728 cap "GND" "A" 15163 cap "phi1" "B" 152 cap "B_b" "B" 1618 cap "A_b" "a_n11_n54#" 180 cap "phi2" "a_77_n40#" 240 cap "phi1_b" "Vdd" 316 cap "reset_b" "GND" 8728 cap "a_39_n23#" "B" 176 cap "phi2" "Vdd" 316 cap "a_101_n47#" "GND" 6638 cap "reset_b" "a_77_n40#" 240 cap "a_55_n47#" "B" 3167 cap "a_77_n40#" "GND" 1692 cap "reset_b" "Vdd" 316 cap "A_b" "A" 180 cap "a_31_n39#" "A" 180 cap "A_b" "GND" 15778 cap "a_31_n39#" "GND" 1316 cap "a_55_n47#" "phi1_b" 2220 cap "phi1" "GND" 8966 cap "B_b" "GND" 5826 device mosfet nfet 123 -42 124 -41 2 12 "GND" "a_101_n47#" 4 0 "GND" 12 0 "B" 12 0 device mosfet pfet 123 -20 124 -19 2 12 "Vdd!" "a_101_n47#" 4 0 "B" 12 0 "Vdd" 12 0 device mosfet nfet 101 -42 102 -41 2 6 "GND" "phi2" 4 0 "a_101_n47#" 6 0 "a_77_n40#" 6 0 device mosfet pfet 101 -20 102 -19 2 6 "Vdd!" "phi2_b" 4 0 "a_77_n40#" 6 0 "a_101_n47#" 6 0 device mosfet nfet 77 -46 78 -45 2 6 "GND" "reset_b" 4 0 "GND" 6 0 "a_77_n44#" 6 0 device mosfet nfet 77 -42 78 -41 2 6 "GND" "a_55_n47#" 4 0 "a_77_n44#" 6 0 "a_77_n40#" 6 0 device mosfet pfet 77 -20 78 -19 2 6 "Vdd!" "a_55_n47#" 4 0 "a_77_n40#" 6 0 "Vdd" 6 0 device mosfet nfet 55 -42 56 -41 2 6 "GND" "phi1" 4 0 "a_55_n47#" 6 0 "a_31_n39#" 6 0 device mosfet pfet 87 -17 88 -16 2 5 "Vdd!" "reset_b" 4 0 "Vdd" 5 0 "a_77_n40#" 5 0 device mosfet pfet 55 -18 56 -17 2 6 "Vdd!" "phi1_b" 4 0 "a_31_n39#" 6 0 "a_55_n47#" 6 0 device mosfet nfet -2 -52 -1 -51 2 6 "GND" "A_b" 4 0 "GND" 6 0 "A" 6 0 device mosfet nfet -11 -52 -10 -51 2 6 "GND" "a_n11_n54#" 4 0 "A_b" 6 0 "GND" 6 0 device mosfet nfet 41 -39 42 -38 2 6 "GND" "A" 4 0 "a_39_n39#" 6 0 "GND" 6 0 device mosfet nfet 37 -39 38 -38 2 6 "GND" "B_b" 4 0 "a_31_n39#" 6 0 "a_39_n39#" 6 0 device mosfet nfet 29 -39 30 -38 2 6 "GND" "B" 4 0 "a_26_n39#" 6 0 "a_31_n39#" 6 0 device mosfet nfet 24 -39 25 -38 2 6 "GND" "A_b" 4 0 "GND" 6 0 "a_26_n39#" 6 0 device mosfet nfet 16 -39 17 -38 2 6 "GND" "B" 4 0 "B_b" 6 0 "GND" 6 0 device mosfet pfet 41 -23 42 -22 2 6 "Vdd!" "A" 4 0 "a_39_n23#" 6 0 "Vdd" 6 0 device mosfet pfet 37 -23 38 -22 2 6 "Vdd!" "B" 4 0 "a_31_n39#" 6 0 "a_39_n23#" 6 0 device mosfet pfet 29 -23 30 -22 2 6 "Vdd!" "B_b" 4 0 "a_26_n23#" 6 0 "a_31_n39#" 6 0 device mosfet pfet 24 -23 25 -22 2 6 "Vdd!" "A_b" 4 0 "Vdd" 6 0 "a_26_n23#" 6 0 device mosfet pfet 16 -23 17 -22 2 6 "Vdd!" "B" 4 0 "B_b" 6 0 "Vdd" 6 0 device mosfet pfet 0 -18 1 -17 2 5 "Vdd!" "A_b" 4 0 "A" 5 0 "Vdd" 5 0 device mosfet pfet -11 -15 -10 -14 2 6 "Vdd!" "a_n11_n54#" 4 0 "Vdd" 6 0 "A_b" 6 0 magic-8.0.210/doc/tutcells/tut8f.mag0000644000175000001440000000037410751423606015626 0ustar timusersmagic tech scmos timestamp 617925832 << metal2 >> rect 39 89 49 93 rect 38 1 49 5 use tut8e tut8e_0 timestamp 617925319 transform 1 0 103 0 1 55 box -103 -55 -54 39 << labels >> rlabel metal2 47 3 47 3 8 Vdd! rlabel metal2 47 91 47 91 6 Vdd! << end >> magic-8.0.210/doc/tutcells/tut11c.ext0000644000175000001440000000431510751423606015730 0ustar timuserstimestamp 552706284 version 7.2 tech scmos style lambda=1.0(scna20_orb) scale 1000 1 100 resistclasses 26670 59550 23860 19690 27260 2000000 49 26 2505830 use tut11d tut11d_0 1 0 0 0 -1 -60 node "m2_n40_n6#" 0 0 -40 -6 m2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 162 66 0 0 node "a_n18_n44#" 196 5362 -18 -44 pdiff 0 0 58 36 0 0 0 0 0 0 0 0 32 24 162 66 0 0 node "a_n20_n60#" 716 6828 -20 -60 p 0 0 0 0 120 124 0 0 0 0 0 0 0 0 0 0 0 0 node "a_n34_n24#" 464 8084 -34 -24 ndc 24 36 24 22 0 0 0 0 0 0 0 0 164 90 0 0 0 0 node "a_n36_n19#" 620 10422 -36 -19 p 0 0 0 0 112 112 0 0 0 0 0 0 20 18 72 44 0 0 node "a_n34_n17#" 80 0 -34 -17 ndiff 12 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 node "a_n34_n13#" 329 5079 -34 -13 ndiff 24 36 0 0 16 16 0 0 0 0 0 0 156 108 56 36 0 0 node "a_n40_n60#" 859 10176 -40 -60 p 0 0 0 0 144 148 0 0 0 0 0 0 0 0 0 0 0 0 node "w_n40_n28#" 0 0 -40 -28 pw 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 cap "w_n40_n28#" "a_n40_n60#" 6172 cap "a_n40_n60#" "m2_n40_n6#" 228 cap "a_n36_n19#" "a_n34_n13#" 210 cap "w_n40_n28#" "a_n34_n13#" 6244 cap "a_n34_n13#" "m2_n40_n6#" 1080 cap "a_n36_n19#" "a_n18_n44#" 66 cap "w_n40_n28#" "a_n36_n19#" 4288 cap "w_n40_n28#" "m2_n40_n6#" 2166 cap "a_n18_n44#" "a_n34_n24#" 1080 cap "a_n34_n13#" "a_n20_n60#" 152 cap "a_n36_n19#" "a_n34_n24#" 1296 cap "w_n40_n28#" "a_n34_n24#" 752 cap "a_n18_n44#" "a_n20_n60#" 228 cap "a_n36_n19#" "a_n20_n60#" 38 cap "w_n40_n28#" "a_n20_n60#" 6664 cap "m2_n40_n6#" "a_n20_n60#" 228 cap "a_n40_n60#" "a_n18_n44#" 228 device mosfet pfet -20 -44 -19 -43 2 6 "Vdd!" "a_n20_n60#" 4 0 "a_n34_n24#" 6 0 "a_n18_n44#" 6 0 device mosfet nfet -34 -19 -33 -18 2 6 "w_n40_n28#" "a_n36_n19#" 4 0 "a_n34_n24#" 6 0 "a_n34_n17#" 6 0 device mosfet nfet -34 -15 -33 -14 2 6 "w_n40_n28#" "a_n40_n60#" 4 0 "a_n34_n17#" 6 0 "a_n34_n13#" 6 0 cap "a_n18_n44#" "a_n36_n19#" 264 cap "tut11d_0/a_n11_n54#" "w_n40_n28#" 536 cap "m2_n40_n6#" "w_n40_n28#" -456 merge "tut11d_0/Vdd" "a_n18_n44#" -3652 0 0 -36 -26 0 0 0 0 0 0 0 0 -32 -24 -24 -20 0 0 merge "tut11d_0/B" "a_n36_n19#" -475 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -32 -32 0 0 merge "tut11d_0/GND" "w_n40_n28#" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -72 -48 0 0 merge "w_n40_n28#" "m2_n40_n6#" 0 merge "tut11d_0/a_n11_n54#" "a_n34_n13#" -1176 0 0 0 0 0 -8 0 0 0 0 0 0 0 0 0 0 0 0 magic-8.0.210/doc/tutcells/tut11a.cmd0000644000175000001440000000023010751423606015661 0ustar timusersvector clk phi1 phi2 vector clkb phi1_b phi2_b clock clk 10 00 01 00 clock clkb 01 11 10 11 vector bits bit_3 bit_2 bit_1 bit_0 w clk hold RESET_B bits magic-8.0.210/doc/tutcells/tut7c.mag0000644000175000001440000000224210751423606015616 0ustar timusersmagic tech scmos timestamp 616462327 << polysilicon >> rect 9 25 11 30 << ndiffusion >> rect 38 10 41 13 << pdiffusion >> rect -10 -5 -5 -2 << metal1 >> rect 1 30 4 35 rect 30 32 35 35 rect 30 30 33 32 rect 38 -5 45 -2 rect -14 -18 -7 -15 rect 6 -29 9 -22 rect 37 -29 45 -25 << metal2 >> rect -12 22 -9 35 rect 38 23 41 26 rect -14 19 -9 22 rect -14 10 -5 13 rect 38 -17 45 -14 rect -6 -26 -3 -19 rect -12 -29 -3 -26 rect 25 -29 28 -22 << polycontact >> rect 9 30 13 35 << ndcontact >> rect 41 10 45 14 << pdcontact >> rect -14 -5 -10 -1 << m2contact >> rect 41 23 45 27 rect -7 -19 -3 -15 << labels >> rlabel metal2 -12 -29 -3 -29 1 bot3 rlabel metal1 6 -29 9 -29 1 bot2 rlabel pdcontact -14 -5 -14 -1 3 left2 rlabel ndcontact 45 10 45 14 7 right2 rlabel polycontact 9 35 13 35 5 top3 rlabel m2contact 45 23 45 27 7 right1 rlabel metal1 30 35 35 35 5 top4 rlabel metal2 -14 10 -14 13 3 left3 rlabel metal1 -14 -18 -14 -15 3 left1 rlabel metal2 25 -29 28 -29 1 bot1 rlabel metal1 45 -29 45 -25 7 right5 rlabel metal2 45 -17 45 -14 7 right4 rlabel metal1 45 -5 45 -2 7 right3 rlabel metal2 -14 19 -14 22 3 left4 rlabel metal2 -12 35 -9 35 5 top1 rlabel metal1 1 35 4 35 5 top2 << end >> magic-8.0.210/doc/tutcells/tut7b.net0000644000175000001440000000025310751423606015637 0ustar timusers Net List File tut7c_0/top1 tut7c_1/top1 tut7c_1/left3 tut7c_0/left3 tut7c_1/left4 tut7c_1/left1 tut7c_1/bot1 tut7c_0/right3 tut7c_0/right4 tut7c_1/top4 tut7c_1/bot3 magic-8.0.210/doc/tutcells/tut2c.mag0000644000175000001440000000051710751423606015614 0ustar timusersmagic tech scmos timestamp 500615676 << polysilicon >> rect -17 7 0 13 << pdiffusion >> rect 5 -15 13 -4 << metal1 >> rect -18 -18 -5 -10 << labels >> rlabel polysilicon -15 10 -15 10 3 Label1 rlabel metal1 -17 -14 -17 -14 3 Metal1 label rlabel pdiffusion 13 -13 13 -7 7 Line label rlabel space 4 2 25 22 1 Rectangular label << end >> magic-8.0.210/doc/tutcells/tut8m.mag0000644000175000001440000000125410751423606015633 0ustar timusersmagic tech scmos timestamp 539557994 << polysilicon >> rect 3 35 8 37 rect 14 35 16 37 rect 3 24 5 35 rect 0 22 5 24 rect 3 9 5 22 rect 3 7 8 9 rect 14 7 16 9 << ndiffusion >> rect 8 9 14 10 rect 8 6 14 7 << pdiffusion >> rect 8 37 14 38 rect 8 34 14 35 << metal1 >> rect 0 40 8 44 rect 14 40 16 44 rect 8 25 14 28 rect 8 21 16 25 rect 8 16 14 21 rect 0 0 8 4 rect 14 0 16 4 << ndcontact >> rect 8 10 14 16 rect 8 0 14 6 << pdcontact >> rect 8 38 14 44 rect 8 28 14 34 << ntransistor >> rect 8 7 14 9 << ptransistor >> rect 8 35 14 37 << labels >> rlabel metal1 0 40 0 44 7 Vdd! rlabel metal1 0 0 0 4 7 GND! rlabel polysilicon 0 22 0 24 7 In rlabel metal1 16 21 16 25 3 Out << end >> magic-8.0.210/doc/tutcells/tut2a.mag0000644000175000001440000000064210751423606015611 0ustar timusersmagic tech scmos timestamp 500615676 << polysilicon >> rect -33 3 -29 7 << ndiffusion >> rect -40 3 -36 7 << pdiffusion >> rect -12 3 -8 7 << metal2 >> rect -19 3 -15 7 << polycontact >> rect -26 3 -22 7 << labels >> rlabel ndiffusion -38 3 -38 3 5 ndiff rlabel polysilicon -31 3 -31 3 5 poly rlabel polycontact -24 3 -24 3 5 pcontact rlabel metal2 -17 3 -17 3 5 metal2 rlabel pdiffusion -10 3 -10 3 5 pdiff << end >> magic-8.0.210/doc/tutcells/tut9y.mag0000644000175000001440000000206310751423606015647 0ustar timusersmagic tech scmos timestamp 502162889 << polysilicon >> rect 8 9 10 14 rect 8 1 10 5 rect 8 -7 10 -3 rect 8 -16 10 -11 << ndiffusion >> rect 7 -11 8 -7 rect 10 -11 11 -7 << pdiffusion >> rect 7 5 8 9 rect 10 5 11 9 << metal1 >> rect 2 9 6 10 rect 15 5 16 8 rect 13 1 16 5 rect -1 -2 5 1 rect 13 -2 26 1 rect 13 -7 16 -2 rect 15 -10 16 -7 rect 2 -12 6 -11 << metal2 >> rect -1 10 2 14 rect 6 10 21 14 rect -1 9 21 10 rect -1 -12 21 -11 rect -1 -16 2 -12 rect 6 -16 21 -12 << polycontact >> rect 5 -3 10 1 << ndcontact >> rect 3 -11 7 -7 rect 11 -11 15 -7 << pdcontact >> rect 3 5 7 9 rect 11 5 15 9 << m2contact >> rect 2 10 6 14 rect 2 -16 6 -12 << ntransistor >> rect 8 -11 10 -7 << ptransistor >> rect 8 5 10 9 << psubstratepcontact >> rect -1 -11 3 -7 << nsubstratencontact >> rect -1 5 3 9 << labels >> rlabel metal1 15 -1 15 -1 7 out rlabel metal2 15 11 15 11 6 Vdd! rlabel metal2 15 -13 15 -13 8 GND! rlabel metal1 -1 -2 -1 1 3 in rlabel metal2 -1 -16 -1 -11 3 GND! rlabel metal2 -1 9 -1 14 3 Vdd! rlabel metal2 8 14 10 14 5 in rlabel metal2 8 -16 10 -16 1 in << end >> magic-8.0.210/doc/tutcells/tut8k.mag0000644000175000001440000000066110751423606015632 0ustar timusersmagic tech scmos timestamp 539497029 << metal1 >> rect -6 24 4 28 rect -40 -3 -36 4 rect -6 -22 -2 24 rect 1 -3 5 4 rect 5 -7 24 -3 rect -6 -26 4 -22 << metal2 >> rect -36 -7 1 -4 << m2contact >> rect -40 -7 -36 -3 rect 1 -7 5 -3 << labels >> rlabel metal1 24 -5 24 -5 3 ReceiverC rlabel metal1 3 4 3 4 1 Driver2 rlabel metal1 -38 4 -38 4 1 ReceiverB rlabel metal1 4 -24 4 -24 3 Driver1 rlabel metal1 4 27 4 27 3 ReceiverA << end >> magic-8.0.210/doc/tutcells/tut8j.mag0000644000175000001440000000017110751423606015625 0ustar timusersmagic tech scmos timestamp 617922547 << ndiffusion >> rect 0 0 10 3 << labels >> rlabel ndiffusion 0 0 0 2 3 B << end >> magic-8.0.210/doc/tutcells/tut11a.nodes0000644000175000001440000000540510751423606016237 0ustar timusers94 5_72_489# 5400 -36600 p; 94 5_48_489# 3600 -36600 p; 94 5_16_489# 1200 -36600 p; 94 bit_3/5_69_49# 600 -4350 ndc; 94 bit_3/5_69_35# 1650 -4350 green; 94 bit_3/tut11d_0/5_202_95# 2100 -24600 ndc; 94 bit_3/tut11d_0/5_154_89# 1650 -21000 green; 94 bit_3/tut11d_0/5_154_81# 1050 -21000 green; 94 bit_3/tut11d_0/5_110_95# 2100 -17700 ndc; 94 bit_3/tut11d_0/5_78_79# 900 -15300 green; 94 bit_3/tut11d_0/5_52_79# 900 -13350 green; 94 bit_3/tut11d_0/5_78_47# -1500 -15300 brown; 94 bit_3/tut11d_0/5_62_79# 900 -14100 green; 94 bit_3/tut11d_0/5_52_47# -1500 -13350 brown; 94 bit_3/tut11d_0/A 2850 -9450 green; 94 bit_3/tut11d_0/B_b 900 -11100 ndc; 94 bit_3/tut11d_0/A_b 2850 -7050 ndc; 94 bit_3 -600 -29550 v; 94 bit_2/5_69_91# 5550 -4350 green; 94 bit_3/5_69_27# 3150 -7800 p; 94 bit_2/tut11d_0/5_202_95# 5250 -24600 ndc; 94 bit_2/tut11d_0/5_154_89# 5700 -21000 green; 94 bit_2/tut11d_0/5_154_81# 6300 -21000 green; 94 bit_2/tut11d_0/5_110_95# 5250 -17700 ndc; 94 bit_2/tut11d_0/5_78_79# 6450 -15300 green; 94 bit_2/tut11d_0/5_52_79# 6450 -13350 green; 94 bit_2/tut11d_0/5_78_47# 8850 -15300 brown; 94 bit_2/tut11d_0/5_62_79# 6450 -14100 green; 94 bit_2/tut11d_0/5_52_47# 8850 -13350 brown; 94 bit_2/tut11d_0/A 4500 -9450 green; 94 bit_2/tut11d_0/B_b 6450 -11100 ndc; 94 bit_2/tut11d_0/A_b 4500 -7050 ndc; 94 bit_2 7500 -29550 v; 94 bit_2/5_69_83# 4200 -7800 p; 94 bit_1/5_69_35# 17850 -4350 green; 94 bit_1/tut11d_0/5_202_95# 18300 -24600 ndc; 94 bit_1/tut11d_0/5_154_89# 17850 -21000 green; 94 bit_1/tut11d_0/5_154_81# 17250 -21000 green; 94 bit_1/tut11d_0/5_110_95# 18300 -17700 ndc; 94 bit_1/tut11d_0/5_78_79# 17100 -15300 green; 94 bit_1/tut11d_0/5_52_79# 17100 -13350 green; 94 bit_1/tut11d_0/5_78_47# 14700 -15300 brown; 94 bit_1/tut11d_0/5_62_79# 17100 -14100 green; 94 bit_1/tut11d_0/5_52_47# 14700 -13350 brown; 94 bit_1/tut11d_0/A 19050 -9450 green; 94 bit_1/tut11d_0/B_b 17100 -11100 ndc; 94 bit_1/tut11d_0/A_b 19050 -7050 ndc; 94 bit_1 15600 -29550 v; 94 bit_0/5_69_91# 21750 -4350 green; 94 bit_1/5_69_27# 19350 -7800 p; 94 phi2_b 28500 -26250 p; 94 phi1 28500 -16950 p; 94 bit_0/tut11d_0/5_202_95# 21450 -24600 ndc; 94 phi2 28500 -23850 p; 94 bit_0/tut11d_0/5_154_89# 21900 -21000 green; 94 bit_0/tut11d_0/5_154_81# 22500 -21000 green; 94 RESET_B 28500 -22650 p; 94 phi1_b 28500 -19350 p; 94 bit_0/tut11d_0/5_110_95# 21450 -17700 ndc; 94 bit_0/tut11d_0/5_78_79# 22650 -15300 green; 94 bit_0/tut11d_0/5_52_79# 22650 -13350 green; 94 bit_0/tut11d_0/5_78_47# 25050 -15300 brown; 94 bit_0/tut11d_0/5_62_79# 22650 -14100 green; 94 bit_0/tut11d_0/5_52_47# 25050 -13350 brown; 94 bit_0/tut11d_0/A 20700 -9450 green; 94 bit_0/tut11d_0/B_b 22650 -11100 ndc; 94 bit_0/tut11d_0/A_b 20700 -7050 ndc; 94 hold 20400 -7800 p; 94 bit_0 23700 -29550 v; 94 Vdd -2250 -6900 pdc; 94 GND -5100 -33300 m1; 94 Vdd! 28500 -9450 space; magic-8.0.210/doc/tutcells/tut8a.mag0000644000175000001440000000064510751423606015622 0ustar timusersmagic tech scmos timestamp 539486845 << polysilicon >> rect -3 -14 -1 7 << metal1 >> rect -14 8 -1 12 rect -18 0 -1 4 rect -18 -8 -14 0 << metal2 >> rect -18 -18 -14 8 << m2contact >> rect -18 8 -14 12 use tut8b tut8b_0 timestamp 500619087 transform 1 0 5 0 1 0 box -6 0 18 12 use tut8c tut8c_0 timestamp 500619087 transform 1 0 4 0 1 -14 box -22 -8 11 6 << labels >> rlabel polysilicon -3 -14 -1 7 3 delete_me << end >> magic-8.0.210/doc/tutcells/tut8e.mag0000644000175000001440000000347710751423606015634 0ustar timusersmagic tech scmos timestamp 617925319 << polysilicon >> rect -95 26 -92 28 rect -72 26 -70 28 rect -95 2 -93 26 rect -72 15 -54 17 rect -95 0 -92 2 rect -72 0 -70 2 rect -95 -18 -92 -16 rect -72 -18 -70 -16 rect -95 -42 -93 -18 rect -72 -33 -54 -31 rect -95 -44 -92 -42 rect -72 -44 -70 -42 << ndiffusion >> rect -92 2 -72 3 rect -92 -1 -72 0 rect -92 -16 -72 -15 rect -92 -19 -72 -18 << pdiffusion >> rect -92 28 -72 29 rect -92 25 -72 26 rect -92 -42 -72 -41 rect -92 -45 -72 -44 << metal1 >> rect -88 34 -87 38 rect -92 33 -87 34 rect -76 18 -72 21 rect -102 14 -99 18 rect -76 7 -72 14 rect -92 -6 -87 -5 rect -88 -10 -87 -6 rect -92 -11 -87 -10 rect -76 -30 -72 -23 rect -103 -34 -99 -30 rect -76 -37 -72 -34 rect -92 -50 -87 -49 rect -88 -54 -87 -50 << metal2 >> rect -103 34 -92 38 rect -88 34 -54 38 rect -103 -10 -92 -6 rect -88 -10 -54 -6 rect -103 -54 -92 -50 rect -88 -54 -54 -50 << nwell >> rect -101 16 -70 39 rect -101 -55 -70 -32 << polycontact >> rect -99 14 -95 18 rect -76 14 -72 18 rect -99 -34 -95 -30 rect -76 -34 -72 -30 << ndcontact >> rect -92 3 -72 7 rect -92 -5 -72 -1 rect -92 -15 -72 -11 rect -92 -23 -72 -19 << pdcontact >> rect -92 29 -72 33 rect -92 21 -72 25 rect -92 -41 -72 -37 rect -92 -49 -72 -45 << m2contact >> rect -92 34 -88 38 rect -92 -10 -88 -6 rect -92 -54 -88 -50 << ntransistor >> rect -92 0 -72 2 rect -92 -18 -72 -16 << ptransistor >> rect -92 26 -72 28 rect -92 -44 -72 -42 << psubstratepcontact >> rect -87 -11 -83 -5 << nsubstratencontact >> rect -87 33 -82 38 rect -87 -54 -82 -49 << labels >> rlabel metal1 -101 -32 -101 -32 3 in2 rlabel metal1 -101 16 -101 16 3 in1 rlabel polysilicon -57 16 -57 16 1 net1 rlabel polysilicon -58 -32 -58 -32 1 net2 rlabel metal2 -64 -8 -64 -8 5 GND! rlabel metal2 -62 36 -62 36 5 Vdd! rlabel metal2 -64 -8 -64 -8 1 GND! rlabel metal2 -62 -52 -62 -52 1 Vdd#1 << end >> magic-8.0.210/doc/tutcells/tut3e.mag0000644000175000001440000000160010751423606015611 0ustar timusersmagic tech scmos timestamp 616380512 << polysilicon >> rect 8 17 10 19 rect 16 16 18 21 rect 25 20 27 21 rect 22 18 27 20 rect 16 14 20 16 rect 8 11 10 14 rect 18 0 20 14 rect 22 0 24 18 rect 30 16 32 21 rect 38 14 40 21 rect 30 0 32 13 rect 38 12 42 14 rect 45 12 47 14 rect 38 0 40 12 << ndiffusion >> rect 12 17 15 21 rect 1 14 8 17 rect 10 14 15 17 rect 1 0 4 14 rect 12 11 15 14 rect 12 7 13 11 rect 29 13 30 16 rect 32 13 33 16 rect 42 14 45 15 rect 42 11 45 12 << metal1 >> rect 33 17 41 19 rect 37 16 41 17 rect 45 16 47 19 rect 0 7 5 10 rect 17 7 41 10 rect 0 0 4 4 rect 8 0 47 4 << polycontact >> rect 5 7 10 11 << ndcontact >> rect 13 7 17 11 rect 4 0 8 4 rect 25 13 29 17 rect 33 13 37 17 rect 41 15 45 19 rect 41 7 45 11 << ntransistor >> rect 8 14 10 17 rect 30 13 32 16 rect 42 12 45 14 << labels >> rlabel space 5 6 21 21 0 select me rlabel space 27 6 27 6 1 point here << end >> magic-8.0.210/doc/tutcells/Makefile0000644000175000001440000000215110751423606015521 0ustar timusers# # makefile for Magic documentation # MAGICDIR = ../.. include ${MAGICDIR}/defs.mak TUTDIR = ${LIBDIR}/magic/tutorial TUTFILES= m3a.mag maint2a.mag tut1.mag \ tut2a.mag tut2b.mag tut2c.mag tut2d.mag \ tut3a.mag tut3b.mag tut3c.mag tut3d.mag tut3e.mag \ tut3f.mag tut3g.mag tut3h.mag \ tut4a.mag tut4x.mag tut4y.mag tut4z.mag \ tut5a.mag tut5b.mag \ tut6a.mag tut6b.mag tut6c.mag tut6x.mag tut6y.mag \ tut7a.mag tut7b.mag tut7b.net tut7c.mag tut7d.mag tut7d.net \ tut8a.mag tut8b.mag tut8c.mag tut8d.mag tut8e.mag tut8f.mag \ tut8g.mag tut8h.mag tut8i.mag tut8j.mag tut8k.mag tut8l.mag \ tut8m.mag tut8n.mag tut8r.mag \ tut9a.mag tut9b.mag tut9x.mag tut9y.mag \ tut11a.mag tut11b.mag tut11c.mag tut11d.mag \ tut11a.al tut11a.cmd tut11a.ext tut11a.nodes tut11a.sim \ tut11b.ext tut11c.ext tut11d.ext INST_TUTFILES= $(TUTFILES:%=$(DESTDIR)${TUTDIR}/%) install: $(DESTDIR)${TUTDIR} ${INST_TUTFILES} $(DESTDIR)${TUTDIR}: make-tut-dirs make-tut-dirs: ${SCRIPTS}/mkdirs $(DESTDIR)${TUTDIR} $(DESTDIR)${TUTDIR}/%: % $(DESTDIR)${TUTDIR} ${CP} $* $(DESTDIR)${TUTDIR}/$* magic-8.0.210/doc/tutcells/tut8r.mag0000644000175000001440000000602710751423606015643 0ustar timusersmagic tech scmos timestamp 617565736 << polysilicon >> rect -95 26 -92 28 rect -72 26 -70 28 rect -3 26 0 28 rect 4 26 6 28 rect -95 2 -93 26 rect -3 17 -1 26 rect -72 15 -1 17 rect -3 2 -1 15 rect -95 0 -92 2 rect -72 0 -70 2 rect -3 0 0 2 rect 4 0 8 2 rect 6 -16 8 0 rect -95 -18 -92 -16 rect -72 -18 -70 -16 rect -2 -18 0 -16 rect 4 -18 18 -16 rect -95 -42 -93 -18 rect -3 -22 0 -20 rect 4 -22 6 -20 rect -3 -31 -1 -22 rect -72 -33 -1 -31 rect -3 -42 -1 -33 rect 16 -42 18 -18 rect -95 -44 -92 -42 rect -72 -44 -70 -42 rect -3 -44 0 -42 rect 4 -44 6 -42 rect 8 -44 10 -42 rect 14 -44 18 -42 << ndiffusion >> rect -92 2 -72 3 rect 0 2 4 3 rect -92 -1 -72 0 rect 0 -1 4 0 rect -92 -16 -72 -15 rect 0 -16 4 -15 rect -92 -19 -72 -18 rect 0 -20 4 -18 rect 0 -23 4 -22 << pdiffusion >> rect -92 28 -72 29 rect 0 28 4 29 rect -92 25 -72 26 rect 0 25 4 26 rect -92 -42 -72 -41 rect 0 -42 4 -41 rect 10 -42 14 -41 rect -92 -45 -72 -44 rect 0 -45 4 -44 rect 10 -45 14 -44 << metal1 >> rect -88 34 -87 38 rect -92 33 -87 34 rect -1 34 0 38 rect -5 33 0 34 rect -76 18 -72 21 rect -102 14 -99 18 rect -76 7 -72 14 rect 0 7 4 21 rect -92 -6 -87 -5 rect -88 -10 -87 -6 rect -92 -11 -87 -10 rect -5 -6 0 -5 rect -1 -10 0 -6 rect -5 -11 0 -10 rect -76 -30 -72 -23 rect -103 -34 -99 -30 rect -76 -37 -72 -34 rect 0 -37 4 -27 rect 4 -41 10 -37 rect 4 -49 10 -45 rect -92 -50 -87 -49 rect -88 -54 -87 -50 rect -5 -50 0 -49 rect -1 -54 0 -50 << metal2 >> rect -104 34 -92 38 rect -88 34 -5 38 rect -1 34 24 38 rect 20 -6 24 34 rect -110 -10 -92 -6 rect -88 -10 -5 -6 rect -1 -10 13 -6 rect 20 -10 28 -6 rect 20 -50 24 -10 rect -104 -54 -92 -50 rect -88 -54 -5 -50 rect -1 -54 24 -50 << nwell >> rect -101 16 -70 39 rect -14 16 17 39 rect -101 -55 -70 -32 rect -14 -55 17 -32 << polycontact >> rect -99 14 -95 18 rect -76 14 -72 18 rect -99 -34 -95 -30 rect -76 -34 -72 -30 << ndcontact >> rect -92 3 -72 7 rect 0 3 4 7 rect -92 -5 -72 -1 rect 0 -5 4 -1 rect -92 -15 -72 -11 rect 0 -15 4 -11 rect -92 -23 -72 -19 rect 0 -27 4 -23 << pdcontact >> rect -92 29 -72 33 rect 0 29 4 33 rect -92 21 -72 25 rect 0 21 4 25 rect -92 -41 -72 -37 rect 0 -41 4 -37 rect 10 -41 14 -37 rect -92 -49 -72 -45 rect 0 -49 4 -45 rect 10 -49 14 -45 << m2contact >> rect -92 34 -88 38 rect -5 34 -1 38 rect -92 -10 -88 -6 rect -5 -10 -1 -6 rect -92 -54 -88 -50 rect -5 -54 -1 -50 << ntransistor >> rect -92 0 -72 2 rect 0 0 4 2 rect -92 -18 -72 -16 rect 0 -18 4 -16 rect 0 -22 4 -20 << ptransistor >> rect -92 26 -72 28 rect 0 26 4 28 rect -92 -44 -72 -42 rect 0 -44 4 -42 rect 10 -44 14 -42 << psubstratepcontact >> rect -87 -11 -83 -5 rect 0 -11 4 -5 << nsubstratencontact >> rect -87 33 -82 38 rect 0 33 5 38 rect -87 -54 -82 -49 rect 0 -54 5 -49 << labels >> rlabel metal2 -43 -8 -43 -8 1 GND! rlabel metal2 -41 36 -41 36 5 Vdd! rlabel metal2 -43 -8 -43 -8 5 GND! rlabel metal2 -41 -52 -41 -52 1 Vdd! rlabel polysilicon -37 -32 -37 -32 1 net2 rlabel polysilicon -36 16 -36 16 1 net1 rlabel metal1 -101 -32 -101 -32 3 in2 rlabel metal1 -101 16 -101 16 3 in1 rlabel metal1 2 12 2 12 1 out1 rlabel metal1 2 -30 2 -30 1 out2 << end >> magic-8.0.210/doc/tutcells/tut3g.mag0000644000175000001440000000103110751423606015611 0ustar timusersmagic tech scmos timestamp 616380642 << polysilicon >> rect -5 23 -3 27 rect -19 21 -3 23 rect -19 7 -17 21 rect -1 19 1 27 rect -15 17 1 19 rect -15 11 -13 17 rect -15 9 -5 11 rect -19 5 -9 7 rect -11 2 -9 5 rect -19 0 -9 2 rect -19 -17 -17 0 rect -7 -2 -5 9 rect -15 -4 -5 -2 rect -15 -13 -13 -4 rect -15 -15 1 -13 rect -19 -19 -3 -17 rect -5 -20 -3 -19 rect -1 -20 1 -15 << ndiffusion >> rect 2 16 5 27 rect -2 13 5 16 rect -2 -8 1 13 rect -2 -11 6 -8 rect 3 -20 6 -11 << labels >> rlabel space -23 -23 10 28 0 put box here << end >> magic-8.0.210/doc/tutcells/tut3a.mag0000644000175000001440000000070510751423606015612 0ustar timusersmagic tech scmos timestamp 500617727 << polysilicon >> rect -12 6 12 8 << metal1 >> rect -12 0 29 3 << metal2 >> rect -12 -6 -2 -3 << labels >> rlabel polysilicon 11 7 11 7 7 1 rlabel space 11 21 11 21 1 2 rlabel metal1 28 1 28 1 7 5 rlabel space 28 -13 28 -13 5 6 rlabel metal2 -3 -5 -3 -5 7 8 rlabel space 15 -9 15 -9 5 9 rlabel space 5 -21 5 -21 5 10 rlabel space 35 20 35 20 3 3 rlabel space 34 35 34 35 1 4 rlabel space 47 -12 47 -12 3 7 << end >> magic-8.0.210/doc/tutcells/tut11b.ext0000644000175000001440000000447110751423606015732 0ustar timuserstimestamp 552706284 version 7.2 tech scmos style lambda=1.0(scna20_orb) scale 1000 1 100 resistclasses 26670 59550 23860 19690 27260 2000000 49 26 2505830 use tut11d tut11d_0 1 0 0 0 1 0 node "m2_n40_n60#" 0 0 -40 -60 m2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 162 66 0 0 node "a_n34_n45#" 80 0 -34 -45 ndiff 12 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 node "a_n34_n41#" 329 10522 -34 -41 ndiff 24 36 0 0 16 16 0 0 0 0 0 0 164 98 88 52 0 0 node "a_n18_n22#" 196 5362 -18 -22 pdiff 0 0 58 36 0 0 0 0 0 0 0 0 32 24 162 66 0 0 node "a_n34_n52#" 464 3666 -34 -52 ndc 24 36 24 22 0 0 0 0 0 0 0 0 172 102 0 0 0 0 node "a_n20_n60#" 716 6828 -20 -60 p 0 0 0 0 120 124 0 0 0 0 0 0 0 0 0 0 0 0 node "a_n36_n43#" 620 10974 -36 -43 p 0 0 0 0 112 112 0 0 0 0 0 0 20 18 72 44 0 0 node "a_n40_n60#" 859 10176 -40 -60 p 0 0 0 0 144 148 0 0 0 0 0 0 0 0 0 0 0 0 node "w_n40_n60#" 0 0 -40 -60 pw 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 cap "w_n40_n60#" "a_n34_n52#" 5452 cap "a_n34_n45#" "a_n34_n52#" 282 cap "a_n40_n60#" "a_n34_n52#" 120 cap "w_n40_n60#" "a_n40_n60#" 6172 cap "m2_n40_n60#" "a_n34_n52#" 1080 cap "m2_n40_n60#" "w_n40_n60#" 2166 cap "a_n34_n52#" "a_n34_n41#" 720 cap "a_n40_n60#" "a_n18_n22#" 228 cap "w_n40_n60#" "a_n34_n41#" 1658 cap "m2_n40_n60#" "a_n40_n60#" 228 cap "a_n36_n43#" "a_n20_n60#" 38 cap "a_n18_n22#" "a_n34_n41#" 1080 cap "a_n34_n52#" "a_n36_n43#" 876 cap "w_n40_n60#" "a_n36_n43#" 3812 cap "a_n18_n22#" "a_n36_n43#" 66 cap "w_n40_n60#" "a_n20_n60#" 6664 cap "a_n34_n41#" "a_n36_n43#" 152 cap "a_n18_n22#" "a_n20_n60#" 228 cap "m2_n40_n60#" "a_n20_n60#" 228 cap "a_n34_n41#" "a_n20_n60#" 152 device mosfet nfet -34 -47 -33 -46 2 6 "w_n40_n60#" "a_n40_n60#" 4 0 "a_n34_n52#" 6 0 "a_n34_n45#" 6 0 device mosfet nfet -34 -43 -33 -42 2 6 "w_n40_n60#" "a_n36_n43#" 4 0 "a_n34_n45#" 6 0 "a_n34_n41#" 6 0 device mosfet pfet -20 -22 -19 -21 2 6 "Vdd!" "a_n20_n60#" 4 0 "a_n34_n52#" 6 0 "a_n18_n22#" 6 0 cap "m2_n40_n60#" "w_n40_n60#" -456 cap "w_n40_n60#" "tut11d_0/a_n11_n54#" 395 cap "a_n36_n43#" "a_n18_n22#" 264 merge "tut11d_0/Vdd" "a_n18_n22#" -3652 0 0 -36 -26 0 0 0 0 0 0 0 0 -32 -24 -24 -20 0 0 merge "tut11d_0/GND" "w_n40_n60#" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -72 -48 0 0 merge "w_n40_n60#" "m2_n40_n60#" 0 merge "tut11d_0/a_n11_n54#" "a_n34_n41#" -1035 0 0 0 0 0 -8 0 0 0 0 0 0 0 0 0 0 0 0 merge "tut11d_0/B" "a_n36_n43#" -475 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -32 -32 0 0 magic-8.0.210/doc/tutcells/tut6a.mag0000644000175000001440000000036510751423606015617 0ustar timusersmagic tech scmos timestamp 500618582 << error_p >> rect -4 15 -2 17 rect -1 12 1 15 rect 9 12 12 14 rect 9 8 15 11 rect -5 2 8 4 << metal1 >> rect -7 12 -2 17 rect -1 11 2 15 rect 9 12 12 16 rect 9 8 12 11 rect 12 5 15 8 rect -5 1 8 2 << end >> magic-8.0.210/doc/tutcells/tut4x.mag0000644000175000001440000000432510751423606015644 0ustar timusersmagic tech scmos timestamp 616443648 << polysilicon >> rect -3 104 -1 106 rect 38 104 40 106 rect -3 96 -1 101 rect -3 94 7 96 rect -9 88 -7 90 rect 9 88 11 94 rect 25 94 26 96 rect 38 96 40 101 rect 30 94 40 96 rect 25 88 27 94 rect 44 88 46 90 rect -3 81 -1 83 rect -9 79 -7 80 rect 38 81 40 83 rect 44 79 46 80 << ndiffusion >> rect -12 86 -9 88 rect -11 82 -9 86 rect -12 80 -9 82 rect -7 84 -1 88 rect 3 84 9 88 rect -7 80 -4 84 rect -1 83 9 84 rect 11 83 25 88 rect 27 84 34 88 rect 38 84 44 88 rect 27 83 38 84 rect 11 81 14 83 rect -1 79 14 81 rect 24 81 25 83 rect 24 79 38 81 rect 41 80 44 84 rect 46 80 49 88 rect -1 78 18 79 rect 23 78 38 79 << pdiffusion >> rect -8 108 1 112 rect 36 108 45 112 rect -8 104 -4 108 rect 41 104 45 108 rect -8 101 -3 104 rect -1 101 0 104 rect 37 101 38 104 rect 40 101 45 104 << metal1 >> rect -12 99 -9 112 rect -6 105 -3 112 rect -6 104 3 105 rect -6 102 0 104 rect -12 96 -5 99 rect -12 89 -11 92 rect -16 86 -11 89 rect -8 79 -5 96 rect 0 88 3 100 rect 8 99 11 112 rect 14 91 17 112 rect 7 88 17 91 rect 20 91 23 112 rect 26 99 29 112 rect 40 104 43 112 rect 37 101 43 104 rect 20 88 30 91 rect -6 74 -5 79 rect -8 72 -5 74 rect 7 72 10 88 rect 14 78 24 79 rect 18 77 23 78 rect 18 74 19 77 rect 27 72 30 88 rect 34 88 37 100 rect 46 98 49 112 rect 42 95 49 98 rect 42 79 45 95 rect 42 74 43 79 rect 42 72 45 74 << metal2 >> rect -16 93 55 97 rect -12 89 -11 93 rect -16 86 -11 89 rect -16 77 55 79 rect -16 74 19 77 rect 23 74 55 77 << polycontact >> rect 7 94 11 99 rect 26 94 30 99 rect -11 74 -6 79 rect 43 74 48 79 << ndcontact >> rect -16 82 -11 86 rect -1 84 3 88 rect 34 84 38 88 rect 14 79 24 83 << pdcontact >> rect 0 100 4 104 rect 33 100 37 104 << m2contact >> rect -16 89 -12 93 rect 19 73 23 77 << ntransistor >> rect -9 80 -7 88 rect 9 83 11 88 rect 25 83 27 88 rect -1 81 11 83 rect 25 81 38 83 rect 44 80 46 88 << ptransistor >> rect -3 101 -1 104 rect 38 101 40 104 << psubstratepcontact >> rect 13 74 18 78 << nsubstratencontact >> rect 1 108 5 112 rect 32 108 36 112 << labels >> rlabel metal1 -8 72 -5 72 1 accA0 rlabel metal1 7 72 10 72 1 accB0 rlabel metal1 27 72 30 72 1 accB1 rlabel metal1 42 72 45 72 1 accA1 rlabel metal2 55 74 55 79 7 GND! rlabel metal2 55 93 55 97 7 busA0 << end >> magic-8.0.210/doc/tutcells/tut11c.mag0000644000175000001440000000264210751423606015675 0ustar timusersmagic tech scmos timestamp 552706284 << polysilicon >> rect -40 -13 -38 0 rect -40 -15 -34 -13 rect -28 -15 -26 -13 rect -40 -60 -38 -15 rect -36 -19 -34 -17 rect -28 -19 -25 -17 rect -27 -22 -25 -19 rect -29 -24 -25 -22 rect -29 -30 -27 -24 rect -30 -32 -27 -30 rect -30 -50 -28 -32 rect -20 -38 -18 0 rect -30 -52 -27 -50 rect -20 -60 -18 -44 << ndiffusion >> rect -30 -12 -28 -11 rect -34 -13 -28 -12 rect -34 -17 -28 -15 rect -34 -20 -28 -19 rect -30 -21 -28 -20 << pdiffusion >> rect -21 -42 -20 -38 rect -22 -44 -20 -42 rect -18 -42 -13 -38 rect -18 -44 -17 -42 << metal1 >> rect -34 -8 -30 0 rect -30 -12 -22 -8 rect -34 -38 -30 -24 rect -26 -25 -22 -12 rect -16 -30 -12 -29 rect -16 -34 -15 -30 rect -34 -42 -25 -38 rect -34 -60 -30 -42 rect -27 -50 -23 -49 rect -17 -55 -13 -51 << metal2 >> rect -40 -6 -13 0 rect -22 -29 -16 -25 rect -27 -41 -17 -37 rect -27 -45 -23 -41 rect -40 -55 -13 -54 rect -40 -59 -17 -55 rect -40 -60 -13 -59 << pwell >> rect -40 -28 -13 0 << polycontact >> rect -15 -34 -11 -30 rect -27 -54 -23 -50 << ndcontact >> rect -34 -12 -30 -8 rect -34 -24 -30 -20 << pdcontact >> rect -25 -42 -21 -38 rect -17 -51 -13 -42 << m2contact >> rect -26 -29 -22 -25 rect -16 -29 -12 -25 rect -27 -49 -23 -45 rect -17 -59 -13 -55 << ntransistor >> rect -34 -15 -28 -13 rect -34 -19 -28 -17 << ptransistor >> rect -20 -44 -18 -38 use tut11d tut11d_0 timestamp 552706284 transform 1 0 0 0 -1 -60 box -17 -60 137 0 << end >> magic-8.0.210/doc/tutcells/tut2.f1b.cif0000644000175000001440000000255410751423606016120 0ustar timusersDS 1 200 4; 9 f4b; L NP; B 40 8 20 24; B 8 100 52 50; B 8 12 28 50; B 8 12 12 50; B 24 24 20 68; B 8 8 80 24; B 8 8 100 98; B 8 8 100 50; B 8 8 100 34; L ND; B 68 8 42 36; B 4 4 30 14; B 4 4 10 14; B 24 16 20 24; B 8 4 20 42; B 8 4 72 30; B 8 28 20 70; B 8 8 100 66; B 8 8 100 50; B 8 8 100 34; L NM; B 56 16 56 8; B 12 16 6 8; B 56 16 56 92; B 12 16 6 92; B 8 8 -56 148; B 8 8 252 -56; B 8 8 100 82; L NI; B 8 24 20 68; B 8 8 100 34; L NB; B 8 12 20 50; B 8 8 72 24; B 8 8 100 18; 0V 12 0 12 16 28 16 28 0 12 0 28 16; 0V 28 0 12 16; 0V 12 84 12 100 28 100 28 84 12 84 28 100; 0V 28 84 12 100; 0V 96 -2 96 6 104 6 104 -2 96 -2 104 6; 0V 96 6 104 -2; 2A "In" T 4 24; 0V 4 24 4 24 4 24 4 24 4 24; 2A "Vdd" T 4 92; 0V 4 92 4 92 4 92 4 92 4 92; 2A "GND" T 4 8; 0V 4 8 4 8 4 8 4 8 4 8; 2A "Phi" T 52 68; 0V 52 68 52 68 52 68 52 68 52 68; 2A "Out" T 80 24; 0V 80 24 80 24 80 24 80 24 80 24; 2L "Depletion-FET" T 108 32; 0V 108 32 108 32 108 32 108 32 108 32; 2L "Enhancement-FET" T 108 48; 0V 108 48 108 48 108 48 108 48 108 48; 2L "Diffusion" T 108 64; 0V 108 64 108 64 108 64 108 64 108 64; 2L "Metal" T 108 80; 0V 108 80 108 80 108 80 108 80 108 80; 2L "Polysilicon" T 108 96; 0V 108 96 108 96 108 96 108 96 108 96; 2L "Diff-Metal-Contact" T 108 0; 0V 108 0 108 0 108 0 108 0 108 0; 2L "Buried-Contact" T 108 16; 0V 108 16 108 16 108 16 108 16 108 16; DF; C 1; End magic-8.0.210/doc/tutcells/tut4y.mag0000644000175000001440000000060310751423606015640 0ustar timusersmagic tech scmos timestamp 500618087 << metal1 >> rect 5 -10 8 -3 rect 20 -10 23 -3 rect 40 -10 43 -3 rect 55 -10 58 -3 rect 76 -10 79 -3 rect 91 -10 94 -3 rect 111 -10 114 -3 rect 126 -10 129 -3 rect 147 -10 150 -3 rect 162 -10 165 -3 rect 182 -10 185 -3 rect 197 -10 200 -3 use tut4x tut4x_0 array 0 2 71 0 0 39 timestamp 500618087 transform 1 0 13 0 1 -75 box -16 72 55 112 << end >> magic-8.0.210/doc/tutcells/tut8g.mag0000644000175000001440000000310610751423606015623 0ustar timusersmagic tech scmos timestamp 617925690 << polysilicon >> rect 8 81 11 83 rect 31 81 33 83 rect 8 57 10 81 rect 31 70 49 72 rect 8 55 11 57 rect 31 55 33 57 rect 8 37 11 39 rect 31 37 33 39 rect 8 13 10 37 rect 31 22 49 24 rect 8 11 11 13 rect 31 11 33 13 << ndiffusion >> rect 11 57 31 58 rect 11 54 31 55 rect 11 39 31 40 rect 11 36 31 37 << pdiffusion >> rect 11 83 31 84 rect 11 80 31 81 rect 11 13 31 14 rect 11 10 31 11 << metal1 >> rect 15 89 16 93 rect 11 88 16 89 rect 27 73 31 76 rect 1 69 4 73 rect 27 62 31 69 rect 11 49 16 50 rect 15 45 16 49 rect 11 44 16 45 rect 27 25 31 32 rect 0 21 4 25 rect 27 18 31 21 rect 11 5 16 6 rect 15 1 16 5 << metal2 >> rect 0 89 11 93 rect 15 89 49 93 rect 0 45 11 49 rect 15 45 49 49 rect 0 1 11 5 rect 15 1 49 5 << nwell >> rect 2 71 33 94 rect 2 0 33 23 << polycontact >> rect 4 69 8 73 rect 27 69 31 73 rect 4 21 8 25 rect 27 21 31 25 << ndcontact >> rect 11 58 31 62 rect 11 50 31 54 rect 11 40 31 44 rect 11 32 31 36 << pdcontact >> rect 11 84 31 88 rect 11 76 31 80 rect 11 14 31 18 rect 11 6 31 10 << m2contact >> rect 11 89 15 93 rect 11 45 15 49 rect 11 1 15 5 << ntransistor >> rect 11 55 31 57 rect 11 37 31 39 << ptransistor >> rect 11 81 31 83 rect 11 11 31 13 << psubstratepcontact >> rect 16 44 20 50 << nsubstratencontact >> rect 16 88 21 93 rect 16 1 21 6 << labels >> rlabel metal1 2 23 2 23 3 in2 rlabel metal1 2 71 2 71 3 in1 rlabel polysilicon 46 71 46 71 1 net1 rlabel polysilicon 45 23 45 23 1 net2 rlabel metal2 39 47 39 47 5 GND! rlabel metal2 41 91 41 91 5 Vdd! rlabel metal2 39 47 39 47 1 GND! rlabel metal2 40 3 40 3 1 Vdd! << end >> magic-8.0.210/doc/tutcells/tut3f.mag0000644000175000001440000000066210751423606015621 0ustar timusersmagic tech scmos timestamp 500618087 << error_s >> rect 49 6 50 8 << polysilicon >> rect 19 15 21 46 rect 28 15 30 46 rect 33 15 35 46 rect 21 -37 23 -6 rect 25 -37 27 -6 rect 33 -37 35 -6 << ndiffusion >> rect 15 15 17 46 << metal1 >> rect 50 10 64 13 rect -6 1 3 4 rect -6 -6 3 -2 rect 50 -6 65 -2 use tut3e tut3e_0 timestamp 500618087 transform 1 0 3 0 1 -6 box 0 0 47 21 << labels >> rlabel space 72 4 72 4 7 Point here << end >> magic-8.0.210/doc/tutcells/tut3b.mag0000644000175000001440000000042410751423606015611 0ustar timusersmagic tech scmos timestamp 616379430 << polysilicon >> rect -16 19 16 21 << ndiffusion >> rect -16 28 16 31 rect -16 22 16 25 << metal1 >> rect -16 32 16 35 rect -16 13 16 16 << labels >> rlabel space -32 12 -14 36 1 Fill here rlabel space 14 12 52 36 1 Corner here << end >> magic-8.0.210/doc/tutcells/tut8c.mag0000644000175000001440000000102510751423606015615 0ustar timusersmagic tech scmos timestamp 500619087 << polysilicon >> rect -7 -2 3 0 rect 6 -2 8 0 rect -7 -4 -3 -2 << ndiffusion >> rect 3 0 6 2 rect 3 -4 6 -2 << metal1 >> rect -22 2 2 6 rect 7 2 11 6 rect -10 -8 -9 -4 rect 7 -8 11 -4 << metal2 >> rect -22 -8 -14 -4 rect -10 -8 11 -4 << polycontact >> rect -9 -8 -3 -4 << ndcontact >> rect 2 2 7 6 rect 2 -8 7 -4 << m2contact >> rect -14 -8 -10 -4 << ntransistor >> rect 3 -2 6 0 << labels >> rlabel metal2 -22 -8 -22 -4 3 A rlabel metal1 -22 2 -22 6 3 B rlabel metal1 11 -8 11 -4 7 C << end >> magic-8.0.210/doc/tutcells/tut4a.mag0000644000175000001440000000101110751423606015602 0ustar timusersmagic tech scmos timestamp 500618121 << metal1 >> rect 1 36 4 44 rect 7 36 10 44 rect 21 36 24 44 rect 27 36 30 44 rect 33 36 36 44 rect 39 36 42 44 rect 53 36 56 44 rect 59 36 62 44 use tut4x tut4x_1 timestamp 500618087 transform 1 0 13 0 -1 156 box -16 72 55 112 use tut4x tut4x_0 timestamp 500618087 transform 1 0 13 0 1 -76 box -16 72 55 112 use tut4y tut4y_0 timestamp 500618087 transform 1 0 -68 0 1 -59 box -3 -10 210 37 use tut4y tut4y_1 timestamp 500618087 transform 1 0 -68 0 -1 -79 box -3 -10 210 37 << end >> magic-8.0.210/doc/tutcells/tut5b.mag0000644000175000001440000000267010751423606015620 0ustar timusersmagic tech scmos timestamp 616454154 << polysilicon >> rect 114 76 116 78 rect 114 68 116 73 rect 114 66 124 68 rect 108 60 110 62 rect 126 60 128 66 rect 114 53 116 55 rect 108 51 110 52 << ndiffusion >> rect 105 59 108 60 rect 106 55 108 59 rect 105 52 108 55 rect 110 56 116 60 rect 120 56 126 60 rect 110 52 113 56 rect 116 55 126 56 rect 128 55 141 60 rect 128 53 131 55 rect 116 50 131 53 << pdiffusion >> rect 109 80 118 84 rect 109 76 113 80 rect 109 73 114 76 rect 116 73 117 76 << metal1 >> rect 105 71 108 84 rect 111 77 114 84 rect 111 76 120 77 rect 111 74 117 76 rect 105 68 112 71 rect 101 60 105 61 rect 101 59 106 60 rect 109 51 112 68 rect 117 60 120 72 rect 125 71 128 84 rect 131 63 134 84 rect 124 60 134 63 rect 137 60 141 84 rect 111 46 112 51 rect 109 44 112 46 rect 124 44 127 60 rect 136 50 141 51 rect 136 46 137 50 << metal2 >> rect 101 65 141 69 rect 105 61 106 65 rect 101 59 106 61 rect 101 50 141 51 rect 101 46 137 50 << polycontact >> rect 124 66 128 71 rect 106 46 111 51 << ndcontact >> rect 101 55 106 59 rect 116 56 120 60 rect 131 51 141 55 << pdcontact >> rect 117 72 121 76 << m2contact >> rect 101 61 105 65 rect 137 46 141 50 << ntransistor >> rect 108 52 110 60 rect 126 55 128 60 rect 116 53 128 55 << ptransistor >> rect 114 73 116 76 << psubstratepcontact >> rect 131 46 136 51 << nsubstratencontact >> rect 118 80 122 84 << labels >> rlabel metal1 124 44 127 44 1 accB0 rlabel metal1 109 44 112 44 1 accA0 << end >> magic-8.0.210/doc/tutcells/tut3h.mag0000644000175000001440000000040510751423606015616 0ustar timusersmagic tech scmos timestamp 500618087 << polysilicon >> rect -6 -16 34 -14 rect -6 -20 34 -18 rect -6 -24 34 -22 rect -6 -28 34 -26 rect -6 -32 34 -30 << labels >> rlabel space 9 -32 19 -12 0 put plow here rlabel space -8 -37 36 -9 3 put boundary here << end >> magic-8.0.210/doc/tutcells/tut3d.mag0000644000175000001440000002017010751423606015613 0ustar timusersmagic tech scmos timestamp 616380303 << polysilicon >> rect 338 168 340 171 rect 344 165 346 167 rect 391 168 393 171 rect 385 165 387 167 rect 338 158 340 160 rect 357 156 359 160 rect 372 156 374 160 rect 391 158 393 160 rect 357 154 374 156 rect 357 153 359 154 rect 344 151 354 153 rect 344 146 346 151 rect 358 151 359 153 rect 344 140 346 143 rect 343 121 346 123 rect 349 121 351 123 rect 343 116 345 121 rect 365 114 367 154 rect 372 153 374 154 rect 372 151 373 153 rect 377 151 387 153 rect 385 146 387 151 rect 385 140 387 143 rect 380 121 382 123 rect 385 121 388 123 rect 386 116 388 121 rect 345 112 386 114 rect 340 103 342 111 rect 358 102 360 105 rect 371 102 373 105 rect 389 103 391 111 rect 351 96 353 98 rect 377 96 379 98 rect 358 92 360 93 rect 371 92 373 93 rect 358 86 360 87 rect 371 86 373 87 rect 351 83 353 85 rect 377 83 379 85 rect 339 69 341 78 rect 358 73 360 78 rect 371 73 373 78 rect 389 69 391 78 rect 342 59 344 64 rect 387 59 389 64 rect 342 57 346 59 rect 349 57 351 59 rect 380 57 382 59 rect 385 57 389 59 rect 344 37 346 39 rect 385 37 387 39 rect 344 29 346 34 rect 344 27 354 29 rect 338 20 340 22 rect 356 21 358 27 rect 372 27 373 29 rect 385 29 387 34 rect 377 27 387 29 rect 372 21 374 27 rect 391 21 393 23 rect 344 14 346 16 rect 338 11 340 13 rect 385 14 387 16 rect 391 11 393 13 << ndiffusion >> rect 335 165 338 168 rect 336 161 338 165 rect 335 160 338 161 rect 340 164 343 168 rect 346 167 361 170 rect 359 165 361 167 rect 371 167 385 170 rect 371 165 372 167 rect 346 164 357 165 rect 340 160 346 164 rect 350 160 357 164 rect 359 160 372 165 rect 374 164 385 165 rect 388 164 391 168 rect 374 160 381 164 rect 385 160 391 164 rect 393 160 396 168 rect 331 96 340 103 rect 342 99 349 103 rect 353 99 358 102 rect 342 98 351 99 rect 331 92 351 96 rect 355 93 358 99 rect 360 98 363 102 rect 368 98 371 102 rect 360 93 371 98 rect 373 99 377 102 rect 381 99 389 103 rect 373 93 376 99 rect 379 98 389 99 rect 391 99 397 103 rect 391 96 392 99 rect 379 95 392 96 rect 336 87 351 92 rect 331 85 351 87 rect 379 86 394 95 rect 331 78 339 85 rect 341 82 351 83 rect 355 82 358 86 rect 341 78 350 82 rect 354 78 358 82 rect 360 82 371 86 rect 360 78 363 82 rect 368 78 371 82 rect 373 82 376 86 rect 379 85 392 86 rect 379 82 389 83 rect 373 78 379 82 rect 383 78 389 82 rect 391 82 392 85 rect 391 78 397 82 rect 343 20 346 21 rect 335 13 338 20 rect 340 17 346 20 rect 350 17 356 21 rect 340 13 343 17 rect 346 16 356 17 rect 358 16 372 21 rect 374 17 381 21 rect 385 17 391 21 rect 374 16 385 17 rect 358 14 361 16 rect 346 12 361 14 rect 371 14 372 16 rect 371 12 385 14 rect 388 13 391 17 rect 393 13 396 21 rect 346 11 385 12 << pdiffusion >> rect 339 143 344 146 rect 346 143 347 146 rect 339 139 343 143 rect 339 135 346 139 rect 339 128 347 135 rect 339 124 346 128 rect 346 123 349 124 rect 346 120 349 121 rect 346 117 354 120 rect 384 143 385 146 rect 387 143 392 146 rect 388 139 392 143 rect 385 135 392 139 rect 384 128 392 135 rect 385 124 392 128 rect 382 123 385 124 rect 382 120 385 121 rect 377 117 385 120 rect 346 60 354 63 rect 346 59 349 60 rect 377 60 385 63 rect 382 59 385 60 rect 346 56 349 57 rect 382 56 385 57 rect 339 52 346 56 rect 385 52 392 56 rect 339 45 347 52 rect 384 45 392 52 rect 339 41 346 45 rect 385 41 392 45 rect 339 37 343 41 rect 388 37 392 41 rect 339 34 344 37 rect 346 34 347 37 rect 384 34 385 37 rect 387 34 392 37 << metal1 >> rect 339 176 342 178 rect 341 171 342 176 rect 331 159 336 161 rect 339 152 342 171 rect 334 149 342 152 rect 334 106 337 149 rect 347 147 350 160 rect 354 160 357 178 rect 366 171 367 176 rect 366 170 371 171 rect 374 160 377 178 rect 389 176 392 178 rect 389 171 390 176 rect 354 156 364 160 rect 340 143 347 146 rect 340 116 343 143 rect 346 134 350 135 rect 346 129 348 134 rect 346 128 350 129 rect 355 121 358 148 rect 350 117 354 120 rect 334 103 346 106 rect 350 103 353 117 rect 361 114 364 156 rect 343 75 346 103 rect 357 111 364 114 rect 367 156 377 160 rect 367 114 370 156 rect 373 121 376 148 rect 381 147 384 160 rect 389 152 392 171 rect 389 149 397 152 rect 384 143 391 146 rect 381 134 385 135 rect 383 129 385 134 rect 381 128 385 129 rect 367 111 374 114 rect 357 92 360 111 rect 363 102 368 104 rect 371 92 374 111 rect 377 103 380 120 rect 388 116 391 143 rect 394 106 397 149 rect 386 103 397 106 rect 357 87 358 92 rect 373 87 374 92 rect 333 72 346 75 rect 333 31 336 72 rect 339 37 343 64 rect 351 60 354 78 rect 357 69 360 87 rect 363 76 368 78 rect 371 69 374 87 rect 357 66 364 69 rect 346 51 350 52 rect 346 46 348 51 rect 346 45 350 46 rect 339 34 347 37 rect 333 28 342 31 rect 331 19 335 21 rect 339 11 342 28 rect 347 21 350 33 rect 355 32 358 59 rect 361 24 364 66 rect 354 21 364 24 rect 367 66 374 69 rect 367 24 370 66 rect 379 63 382 78 rect 386 75 389 103 rect 392 92 399 95 rect 392 87 395 92 rect 392 86 399 87 rect 386 72 398 75 rect 377 60 382 63 rect 373 32 376 59 rect 381 51 385 52 rect 383 46 385 51 rect 381 45 385 46 rect 388 37 392 64 rect 384 34 392 37 rect 367 21 377 24 rect 341 6 342 11 rect 339 4 342 6 rect 354 4 357 21 rect 361 11 371 12 rect 365 10 371 11 rect 365 6 366 10 rect 374 4 377 21 rect 381 21 384 33 rect 395 31 398 72 rect 389 28 398 31 rect 389 11 392 28 rect 389 6 390 11 rect 389 4 392 6 << metal2 >> rect 331 171 367 176 rect 371 171 402 176 rect 331 154 336 155 rect 331 150 402 154 rect 331 129 348 134 rect 352 129 379 134 rect 383 129 402 134 rect 331 119 402 123 rect 331 110 402 114 rect 363 108 368 110 rect 331 87 395 92 rect 399 87 402 92 rect 363 70 368 72 rect 331 66 402 70 rect 331 57 402 61 rect 331 46 348 51 rect 352 46 379 51 rect 383 46 402 51 rect 331 26 402 30 rect 331 25 336 26 rect 331 10 402 11 rect 331 6 366 10 rect 371 6 402 10 << polycontact >> rect 336 171 341 176 rect 390 171 395 176 rect 354 148 358 153 rect 340 111 345 116 rect 373 148 377 153 rect 386 111 391 116 rect 358 87 363 92 rect 368 87 373 92 rect 339 64 344 69 rect 387 64 392 69 rect 354 27 358 32 rect 373 27 377 32 rect 336 6 341 11 rect 390 6 395 11 << ndcontact >> rect 331 161 336 165 rect 361 165 371 170 rect 346 160 350 164 rect 381 160 385 164 rect 349 99 353 103 rect 363 98 368 102 rect 377 99 381 103 rect 392 95 402 99 rect 350 78 354 82 rect 363 78 368 82 rect 379 78 383 82 rect 392 82 402 86 rect 331 15 335 19 rect 346 17 350 21 rect 381 17 385 21 rect 361 12 371 16 << pdcontact >> rect 347 143 351 147 rect 346 124 350 128 rect 354 117 358 121 rect 380 143 384 147 rect 381 124 385 128 rect 373 117 377 121 rect 354 59 358 63 rect 373 59 377 63 rect 346 52 350 56 rect 381 52 385 56 rect 347 33 351 37 rect 380 33 384 37 << m2contact >> rect 331 155 336 159 rect 367 171 371 176 rect 348 129 352 134 rect 379 129 383 134 rect 363 104 368 108 rect 363 72 368 76 rect 348 46 352 51 rect 331 21 335 25 rect 395 87 399 92 rect 379 46 383 51 rect 366 6 371 10 << ntransistor >> rect 338 160 340 168 rect 346 165 359 167 rect 372 165 385 167 rect 357 160 359 165 rect 372 160 374 165 rect 391 160 393 168 rect 340 98 342 103 rect 340 96 351 98 rect 358 93 360 102 rect 371 93 373 102 rect 389 98 391 103 rect 379 96 391 98 rect 339 83 351 85 rect 339 78 341 83 rect 358 78 360 86 rect 371 78 373 86 rect 379 83 391 85 rect 389 78 391 83 rect 338 13 340 20 rect 356 16 358 21 rect 372 16 374 21 rect 346 14 358 16 rect 372 14 385 16 rect 391 13 393 21 << ptransistor >> rect 344 143 346 146 rect 346 121 349 123 rect 385 143 387 146 rect 382 121 385 123 rect 346 57 349 59 rect 382 57 385 59 rect 344 34 346 37 rect 385 34 387 37 << psubstratepcontact >> rect 361 170 366 176 rect 331 87 336 92 rect 361 6 365 11 << nsubstratencontact >> rect 346 135 350 139 rect 381 135 385 139 rect 346 41 350 45 rect 381 41 385 45 << labels >> rlabel metal2 402 89 402 89 7 GND! rlabel metal1 391 178 391 178 5 accA1# rlabel metal1 355 178 355 178 5 accB0# rlabel metal1 376 178 376 178 5 accB1# rlabel metal1 340 178 340 178 5 accA0# rlabel space 359 125 378 143 5 Plow here rlabel metal2 402 112 402 112 7 busB1# rlabel metal2 402 68 402 68 7 busB0# rlabel metal2 402 49 402 49 7 Vdd! rlabel metal2 402 28 402 28 7 busA0# rlabel metal1 391 4 391 4 1 accA1# rlabel metal1 340 4 340 4 1 accA0# rlabel metal2 402 9 402 9 8 GND! rlabel metal1 355 4 355 4 1 accB0# rlabel metal1 376 4 376 4 1 accB1# << end >> magic-8.0.210/doc/tutcells/tut7d.mag0000644000175000001440000000315010751423606015616 0ustar timusersmagic tech scmos timestamp 616465268 << metal1 >> rect -24 80 3 83 rect -24 43 -21 80 rect 0 75 3 80 rect 84 72 94 81 rect -32 32 -17 35 rect -32 -13 -29 32 rect -40 -16 -29 -13 rect -40 -53 -37 -16 rect -24 -45 -21 23 rect 56 21 67 24 rect 64 19 67 21 rect 64 16 71 19 rect 67 8 83 11 rect 72 -45 75 -1 rect 80 -13 83 8 rect 80 -16 91 -13 rect -24 -48 -5 -45 rect 72 -48 79 -45 rect -8 -53 -5 -48 rect 88 -53 91 -16 rect -40 -56 -13 -53 rect -8 -56 11 -53 rect -16 -77 -13 -56 rect 8 -61 11 -56 rect 48 -56 91 -53 rect 48 -71 51 -56 rect -24 -80 -13 -77 rect -24 -93 -21 -80 rect -13 -88 -9 -85 rect -24 -96 -9 -93 rect -16 -125 -13 -105 rect -8 -124 4 -121 rect -8 -125 -5 -124 rect -16 -128 -5 -125 rect -41 -160 -31 -151 rect 8 -157 11 -145 rect 40 -149 43 -145 rect 80 -149 83 -65 rect 40 -152 83 -149 rect 88 -157 91 -56 rect 8 -160 91 -157 << metal2 >> rect -1 61 2 71 rect -24 27 -21 39 rect -17 36 -3 39 rect -17 35 -13 36 rect 56 11 67 12 rect 56 9 63 11 rect 72 3 75 15 rect 80 -61 83 -49 rect 6 -65 7 -61 rect 6 -71 9 -65 rect -9 -85 4 -84 rect -5 -87 4 -85 rect -16 -101 -13 -89 rect -5 -96 4 -93 rect 8 -141 11 -135 rect 43 -145 46 -135 << m2contact >> rect -1 71 3 75 rect -25 39 -21 43 rect -17 31 -13 35 rect -25 23 -21 27 rect 71 15 75 19 rect 63 7 67 11 rect 71 -1 75 3 rect 79 -49 83 -45 rect 7 -65 11 -61 rect 79 -65 83 -61 rect -17 -89 -13 -85 rect -9 -89 -5 -85 rect -9 -97 -5 -93 rect -17 -105 -13 -101 rect 7 -145 11 -141 rect 39 -145 43 -141 use tut7c tut7c_0 timestamp 616462327 transform 1 0 11 0 1 26 box -14 -29 45 35 use tut7c tut7c_1 timestamp 616462327 transform 1 0 18 0 1 -106 box -14 -29 45 35 << end >> magic-8.0.210/doc/tutcells/tut9x.mag0000644000175000001440000000202310751423606015642 0ustar timusersmagic tech scmos timestamp 502161799 << polysilicon >> rect 8 9 10 14 rect 8 1 10 5 rect 8 -7 10 -3 rect 8 -16 10 -11 << ndiffusion >> rect 7 -11 8 -7 rect 10 -11 11 -7 << pdiffusion >> rect 7 5 8 9 rect 10 5 11 9 << metal1 >> rect 2 9 6 10 rect 15 5 16 8 rect -1 -2 5 1 rect 13 -7 16 5 rect 15 -10 16 -7 rect 2 -12 6 -11 << metal2 >> rect -1 10 2 14 rect 6 10 15 14 rect -1 9 15 10 rect -1 -12 15 -11 rect -1 -16 2 -12 rect 6 -16 15 -12 << polycontact >> rect 5 -3 10 1 << ndcontact >> rect 3 -11 7 -7 rect 11 -11 15 -7 << pdcontact >> rect 3 5 7 9 rect 11 5 15 9 << m2contact >> rect 2 10 6 14 rect 2 -16 6 -12 << ntransistor >> rect 8 -11 10 -7 << ptransistor >> rect 8 5 10 9 << psubstratepcontact >> rect -1 -11 3 -7 << nsubstratencontact >> rect -1 5 3 9 << labels >> rlabel metal1 15 -1 15 -1 7 out rlabel metal2 15 11 15 11 6 Vdd! rlabel metal2 15 -13 15 -13 8 GND! rlabel metal1 -1 -2 -1 1 3 in rlabel metal2 -1 9 -1 14 3 Vdd! rlabel metal2 -1 -16 -1 -11 3 GND! rlabel metal2 8 -16 10 -16 1 in rlabel metal2 8 14 10 14 5 in << end >> magic-8.0.210/doc/tutcells/tut1.mag0000644000175000001440000000022310751423606015442 0ustar timusersmagic tech scmos timestamp 500615676 << polysilicon >> rect -17 -15 -10 -5 << ndiffusion >> rect -12 11 2 14 << metal1 >> rect 7 -3 13 6 << end >> magic-8.0.210/doc/tutcells/tut6x.mag0000644000175000001440000000017210751423606015642 0ustar timusersmagic tech scmos timestamp 500618582 << polysilicon >> rect 1 8 7 11 rect 5 5 7 8 rect -9 -6 -6 1 rect 2 -5 6 0 << end >> magic-8.0.210/doc/tutcells/tut7d.net0000644000175000001440000000025310751423606015641 0ustar timusers Net List File tut7c_0/top1 tut7c_1/top1 tut7c_1/left3 tut7c_0/left3 tut7c_1/left4 tut7c_1/left1 tut7c_1/bot1 tut7c_0/right3 tut7c_0/right4 tut7c_1/top4 tut7c_1/bot3 magic-8.0.210/doc/tutcells/tut8h.mag0000644000175000001440000000112410751423606015622 0ustar timusersmagic tech scmos timestamp 617922660 << error_s >> rect -3 -7 0 -5 << polysilicon >> rect -1 6 5 8 rect -7 -7 4 -5 << ndiffusion >> rect -9 15 -1 20 rect -10 8 -1 11 rect -10 6 -7 8 rect -10 3 -1 6 << ntransistor >> rect -7 6 -1 8 use tut8j tut8j timestamp 617922547 transform 0 1 -3 -1 0 -1 box 0 0 10 3 use tut8i tut8i_0 timestamp 617922660 transform 1 0 -13 0 1 -17 box -15 0 11 2 use tut8i tut8i_1 timestamp 617922660 transform 1 0 13 0 1 -17 box -15 0 11 2 << labels >> rlabel polysilicon 5 6 5 8 7 Gate rlabel ndiffusion -9 15 -9 20 3 Drain rlabel ndiffusion -10 3 -10 11 3 Drain << end >> magic-8.0.210/doc/tutcells/tut11a.ext0000644000175000001440000001400310751423606015721 0ustar timuserstimestamp 552706284 version 7.2 tech scmos style lambda=1.0(scna20_orb) scale 1000 1 100 resistclasses 26670 59550 23860 19690 27260 2000000 49 26 2505830 use tut11c bit_3 0 1 28 -1 0 -62 use tut11b bit_2 0 1 82 -1 0 -62 use tut11c bit_1 0 1 136 -1 0 -62 use tut11b bit_0 0 1 190 -1 0 -62 node "GND" 2 68694 -34 -222 m1 0 0 0 0 0 0 0 0 0 0 0 0 1350 462 276 116 0 0 node "bit_0" 0 4248 158 -197 v 0 0 0 0 0 0 0 0 0 0 0 0 16 16 208 112 0 0 node "bit_1" 0 4248 104 -197 v 0 0 0 0 0 0 0 0 0 0 0 0 16 16 208 112 0 0 node "bit_2" 0 4248 50 -197 v 0 0 0 0 0 0 0 0 0 0 0 0 16 16 208 112 0 0 node "bit_3" 0 4248 -4 -197 v 0 0 0 0 0 0 0 0 0 0 0 0 16 16 208 112 0 0 node "hold" 0 9306 190 -32 m1 0 0 0 0 0 0 0 0 0 0 0 0 206 90 0 0 0 0 node "Vdd" 2 65682 -32 -19 v 0 0 0 0 0 0 0 0 0 0 0 0 1332 456 162 90 0 0 node "a_36_n244#" 596 12852 36 -244 p 0 0 0 0 108 108 0 0 0 0 0 0 0 0 0 0 0 0 node "a_24_n244#" 322 6746 24 -244 p 0 0 0 0 54 58 0 0 0 0 0 0 0 0 0 0 0 0 node "a_8_n244#" 643 13804 8 -244 p 0 0 0 0 116 116 0 0 0 0 0 0 0 0 0 0 0 0 node "phi2" 203 4366 190 -159 p 0 0 0 0 34 38 0 0 0 0 0 0 0 0 0 0 0 0 node "RESET_B" 97 9316 190 -151 p 0 0 0 0 124 56 0 0 0 0 0 0 0 0 0 0 0 0 node "phi1_b" 203 4366 190 -129 p 0 0 0 0 34 38 0 0 0 0 0 0 0 0 0 0 0 0 node "phi2_b" 322 25379 190 -175 p 0 0 0 0 62 62 0 0 0 0 0 0 375 256 0 0 0 0 node "phi1" 644 24191 190 -113 p 0 0 0 0 116 116 0 0 0 0 0 0 189 132 0 0 0 0 cap "phi1" "phi2_b" 180 cap "phi1" "hold" 240 cap "GND" "bit_3" 1080 cap "phi1_b" "phi2_b" 180 cap "GND" "bit_2" 1080 cap "phi2_b" "RESET_B" 180 cap "phi2_b" "phi2" 180 cap "GND" "bit_1" 1080 cap "bit_0" "GND" 1080 cap "bit_3/tut11d_0/phi2" "bit_3/tut11d_0/GND" -784 cap "bit_3/tut11d_0/phi2_b" "bit_3/tut11d_0/GND" -784 cap "bit_3/tut11d_0/reset_b" "bit_3/tut11d_0/GND" -784 cap "bit_2/tut11d_0/Vdd" "bit_2/tut11d_0/reset_b" -316 cap "bit_2/tut11d_0/phi2" "bit_2/tut11d_0/Vdd" -316 cap "bit_2/tut11d_0/phi2_b" "bit_2/tut11d_0/Vdd" -316 cap "bit_1/tut11d_0/GND" "bit_2/tut11d_0/reset_b" -784 cap "bit_1/tut11d_0/GND" "bit_2/tut11d_0/phi2" -784 cap "bit_1/tut11d_0/GND" "bit_2/tut11d_0/phi2_b" -784 cap "bit_2/tut11d_0/phi1" "bit_3/tut11d_0/GND" -784 cap "bit_3/tut11d_0/phi1_b" "bit_3/tut11d_0/GND" -784 cap "bit_1/tut11d_0/GND" "bit_2/tut11d_0/phi1" -784 cap "bit_2/tut11d_0/Vdd" "bit_2/tut11d_0/phi1" -316 cap "bit_1/tut11d_0/GND" "bit_2/tut11d_0/phi1_b" -784 cap "bit_2/tut11d_0/Vdd" "bit_2/tut11d_0/phi1_b" -316 cap "bit_3/a_n40_n60#" "bit_2/tut11d_0/GND" -228 cap "bit_3/w_n40_n28#" "bit_3/a_n34_n13#" -1128 cap "bit_3/w_n40_n28#" "bit_3/a_n20_n60#" -468 cap "bit_3/w_n40_n28#" "bit_3/a_n40_n60#" -468 cap "bit_2/tut11d_0/GND" "bit_3/a_n34_n13#" -1080 cap "bit_2/tut11d_0/GND" "bit_3/a_n20_n60#" -228 cap "bit_3/w_n40_n28#" "bit_2/tut11d_0/GND" -1710 cap "bit_1/w_n40_n28#" "bit_2/a_n20_n60#" -468 cap "bit_1/w_n40_n28#" "bit_0/tut11d_0/GND" -1710 cap "bit_2/a_n40_n60#" "bit_2/a_n18_n22#" -228 cap "bit_2/a_n40_n60#" "bit_0/tut11d_0/GND" -228 cap "bit_2/a_n18_n22#" "bit_2/a_n34_n41#" -1080 cap "bit_0/tut11d_0/GND" "bit_1/a_n34_n13#" -1080 cap "bit_1/w_n40_n28#" "bit_2/a_n40_n60#" -468 cap "bit_2/a_n18_n22#" "bit_2/a_n20_n60#" -228 cap "bit_0/tut11d_0/GND" "bit_2/a_n20_n60#" -228 cap "bit_1/w_n40_n28#" "bit_1/a_n34_n13#" -1128 merge "bit_0/a_n18_n22#" "bit_1/tut11d_0/Vdd" -1710 0 0 0 0 0 0 0 0 0 0 0 0 0 -4 -138 -88 0 0 merge "bit_1/tut11d_0/Vdd" "bit_2/tut11d_0/Vdd" -1710 merge "bit_2/tut11d_0/Vdd" "bit_2/a_n18_n22#" -1710 merge "bit_2/a_n18_n22#" "bit_3/a_n18_n44#" -1710 merge "bit_3/a_n18_n44#" "Vdd" -1710 merge "bit_0/tut11d_0/GND" "bit_1/tut11d_0/GND" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 merge "bit_1/tut11d_0/GND" "bit_2/tut11d_0/GND" 0 merge "bit_2/tut11d_0/GND" "bit_3/tut11d_0/GND" 0 merge "bit_3/tut11d_0/GND" "GND" 0 merge "GND" "bit_3/w_n40_n28#" 0 merge "bit_3/w_n40_n28#" "bit_1/w_n40_n28#" 0 merge "bit_0/tut11d_0/phi1_b" "bit_1/tut11d_0/phi1_b" -320 0 0 0 0 0 -4 0 0 0 0 0 0 0 0 0 0 0 0 merge "bit_1/tut11d_0/phi1_b" "bit_2/tut11d_0/phi1_b" -320 merge "bit_2/tut11d_0/phi1_b" "bit_3/tut11d_0/phi1_b" -320 merge "bit_3/tut11d_0/phi1_b" "phi1_b" -320 merge "bit_2/tut11d_0/Q_out" "bit_2" -752 0 0 0 0 0 0 0 0 0 0 0 0 -16 -16 0 0 0 0 merge "bit_0/a_n34_n41#" "hold" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -8 0 0 0 0 merge "bit_0/a_n20_n60#" "bit_1/a_n20_n60#" -640 0 0 0 0 0 -8 0 0 0 0 0 0 0 0 0 0 0 0 merge "bit_1/a_n20_n60#" "bit_2/a_n20_n60#" -640 merge "bit_2/a_n20_n60#" "bit_3/a_n20_n60#" -640 merge "bit_3/a_n20_n60#" "bit_0/tut11d_0/phi2_b" -640 merge "bit_0/tut11d_0/phi2_b" "bit_1/tut11d_0/phi2_b" -640 merge "bit_1/tut11d_0/phi2_b" "bit_2/tut11d_0/phi2_b" -640 merge "bit_2/tut11d_0/phi2_b" "bit_3/tut11d_0/phi2_b" -640 merge "bit_3/tut11d_0/phi2_b" "phi2_b" -640 merge "bit_0/tut11d_0/reset_b" "bit_1/tut11d_0/reset_b" -320 0 0 0 0 0 -4 0 0 0 0 0 0 0 0 0 0 0 0 merge "bit_1/tut11d_0/reset_b" "bit_2/tut11d_0/reset_b" -320 merge "bit_2/tut11d_0/reset_b" "bit_3/tut11d_0/reset_b" -320 merge "bit_3/tut11d_0/reset_b" "RESET_B" -320 merge "bit_0/a_n34_n52#" "bit_1/a_n34_n13#" 0 0 0 0 0 0 0 0 0 0 0 0 0 -24 -20 0 0 0 0 merge "bit_1/a_n34_n24#" "bit_2/a_n34_n41#" -1128 0 0 0 0 0 0 0 0 0 0 0 0 -24 -20 0 0 0 0 merge "bit_2/a_n34_n52#" "bit_3/a_n34_n13#" 0 0 0 0 0 0 0 0 0 0 0 0 0 -24 -20 0 0 0 0 merge "bit_0/tut11d_0/Q_out" "bit_0" -752 0 0 0 0 0 0 0 0 0 0 0 0 -16 -16 0 0 0 0 merge "bit_0/a_n40_n60#" "bit_1/a_n40_n60#" -640 0 0 0 0 0 -8 0 0 0 0 0 0 0 0 0 0 0 0 merge "bit_1/a_n40_n60#" "bit_2/a_n40_n60#" -640 merge "bit_2/a_n40_n60#" "bit_3/a_n40_n60#" -640 merge "bit_3/a_n40_n60#" "bit_0/tut11d_0/phi1" -640 merge "bit_0/tut11d_0/phi1" "bit_1/tut11d_0/phi1" -640 merge "bit_1/tut11d_0/phi1" "bit_2/tut11d_0/phi1" -640 merge "bit_2/tut11d_0/phi1" "bit_3/tut11d_0/phi1" -640 merge "bit_3/tut11d_0/phi1" "phi1" -640 merge "bit_1/tut11d_0/Q_out" "bit_1" -752 0 0 0 0 0 0 0 0 0 0 0 0 -16 -16 0 0 0 0 merge "bit_0/tut11d_0/phi2" "bit_1/tut11d_0/phi2" -320 0 0 0 0 0 -4 0 0 0 0 0 0 0 0 0 0 0 0 merge "bit_1/tut11d_0/phi2" "bit_2/tut11d_0/phi2" -320 merge "bit_2/tut11d_0/phi2" "bit_3/tut11d_0/phi2" -320 merge "bit_3/tut11d_0/phi2" "phi2" -320 merge "bit_3/tut11d_0/Q_out" "bit_3" -752 0 0 0 0 0 0 0 0 0 0 0 0 -16 -16 0 0 0 0 magic-8.0.210/doc/tutcells/tut2d.mag0000644000175000001440000000113610751423606015613 0ustar timusersmagic tech scmos timestamp 500615676 << polysilicon >> rect 4 2 6 10 rect 4 -5 6 -1 rect 4 -15 6 -8 << ndiffusion >> rect -5 -1 4 2 rect 6 -1 8 2 rect -5 -8 4 -5 rect 6 -8 8 -5 << metal1 >> rect -7 11 2 14 rect 7 11 30 14 << polycontact >> rect 2 10 7 14 << ntransistor >> rect 4 -1 6 2 rect 4 -8 6 -5 << labels >> rlabel metal1 24 12 24 12 1 Local node name rlabel ndiffusion -3 -6 -3 -6 1 Global name! rlabel ndiffusion -3 1 -3 1 1 Node Attribute@ rlabel ntransistor 6 1 6 1 3 Source/Drain Attribute$ rlabel ntransistor 5 -6 5 -6 3 Gate Attribute^ rlabel metal1 -7 11 -7 14 7 Label for routing << end >> magic-8.0.210/doc/tutcells/tut6b.mag0000644000175000001440000000101410751423606015610 0ustar timusersmagic tech scmos timestamp 500618582 << error_p >> rect 59 39 60 41 rect 59 19 60 24 rect 54 18 61 19 rect 70 18 71 19 rect 86 18 90 19 rect 57 17 61 18 rect 59 1 60 7 << error_s >> rect -12 18 -9 19 rect 8 18 11 19 rect 0 0 1 7 << polysilicon >> rect -12 18 11 22 use tut6x tut6x_1 timestamp 500618582 transform -1 0 -10 0 1 6 box -9 -6 7 11 use tut6x tut6x_0 timestamp 500618582 transform 1 0 9 0 1 6 box -9 -6 7 11 use tut6x tut6x_2 array 0 2 16 0 2 17 timestamp 500618582 transform 1 0 52 0 1 6 box -9 -6 7 11 << end >> magic-8.0.210/doc/tutcells/m3a.mag0000644000175000001440000000062710751423606015235 0ustar timusersmagic tech nmos timestamp 478544012 << polysilicon >> rect -10 8 -8 10 rect -6 8 10 10 rect -10 1 -8 5 rect -6 1 -3 5 << diffusion >> rect -8 10 -6 12 rect -8 5 -6 8 rect -8 -1 -6 1 rect -8 -9 -6 -5 << metal >> rect 1 1 10 4 rect -6 -5 10 -2 << poly-metal-contact >> rect -3 1 1 5 << diff-metal-contact >> rect -10 -5 -6 -1 << enhancement-fet >> rect -8 8 -6 10 << depletion-fet >> rect -8 1 -6 5 << end >> magic-8.0.210/doc/tutcells/tut7b.mag0000644000175000001440000000051510751423606015616 0ustar timusersmagic tech scmos timestamp 500618984 << metal1 >> rect 94 93 100 102 rect -66 -45 94 -29 rect -61 -181 -55 -173 use tut7c tut7c_0 timestamp 500618984 transform 1 0 11 0 1 26 box -14 -29 45 35 use tut7c tut7c_1 timestamp 500618984 transform 1 0 18 0 1 -106 box -14 -29 45 35 << labels >> rlabel metal1 -66 -45 -66 -29 3 foo << end >> magic-8.0.210/doc/tutcells/tut2b.mag0000644000175000001440000000041610751423606015611 0ustar timusersmagic tech scmos timestamp 500615676 << polysilicon >> rect -7 3 1 5 rect -1 -5 1 3 rect 10 -5 12 14 << ndiffusion >> rect -3 -21 -1 -13 rect -19 -23 -1 -21 rect -19 -33 -17 -23 << metal1 >> rect -18 7 -15 14 rect -18 4 -12 7 << polycontact >> rect -12 3 -7 7 << end >> magic-8.0.210/doc/tutcells/tut9b.mag0000644000175000001440000000026610751423606015623 0ustar timusersmagic tech scmos timestamp 502162889 << polycontact >> rect 24 36 47 51 use tut9y tut9y_0 array 0 3 27 0 0 30 timestamp 502162889 transform 1 0 -17 0 1 13 box -1 -16 26 14 << end >> magic-8.0.210/doc/tutcells/tut11b.mag0000644000175000001440000000250510751423606015672 0ustar timusersmagic tech scmos timestamp 552706284 << polysilicon >> rect -40 -45 -38 0 rect -30 -10 -27 -8 rect -30 -28 -28 -10 rect -20 -16 -18 0 rect -30 -30 -25 -28 rect -27 -41 -25 -30 rect -36 -43 -34 -41 rect -28 -43 -25 -41 rect -40 -47 -34 -45 rect -28 -47 -26 -45 rect -40 -60 -38 -47 rect -20 -60 -18 -22 << ndiffusion >> rect -30 -40 -28 -39 rect -34 -41 -28 -40 rect -34 -45 -28 -43 rect -34 -48 -28 -47 rect -30 -49 -28 -48 << pdiffusion >> rect -22 -18 -20 -16 rect -21 -22 -20 -18 rect -18 -18 -17 -16 rect -18 -22 -13 -18 << metal1 >> rect -34 -31 -30 0 rect -27 -11 -23 -10 rect -17 -9 -13 -5 rect -34 -36 -30 -35 rect -25 -44 -21 -22 rect -16 -31 -12 -30 rect -34 -48 -21 -44 rect -34 -60 -30 -52 << metal2 >> rect -40 -1 -13 0 rect -40 -5 -17 -1 rect -40 -6 -13 -5 rect -27 -19 -23 -15 rect -27 -23 -17 -19 rect -30 -35 -16 -31 rect -40 -60 -13 -54 << pwell >> rect -40 -60 -12 -32 << polycontact >> rect -27 -10 -23 -6 rect -15 -30 -11 -26 << ndcontact >> rect -34 -40 -30 -36 rect -34 -52 -30 -48 << pdcontact >> rect -25 -22 -21 -18 rect -17 -18 -13 -9 << m2contact >> rect -17 -5 -13 -1 rect -27 -15 -23 -11 rect -34 -35 -30 -31 rect -16 -35 -12 -31 << ntransistor >> rect -34 -43 -28 -41 rect -34 -47 -28 -45 << ptransistor >> rect -20 -22 -18 -16 use tut11d tut11d_0 timestamp 552706284 transform 1 0 0 0 1 0 box -17 -60 137 0 << end >> magic-8.0.210/doc/tutcells/tut7a.mag0000644000175000001440000000201210751423606015607 0ustar timusersmagic tech scmos timestamp 616462131 << polysilicon >> rect -23 -8 -15 -6 << ndiffusion >> rect -27 14 -20 17 rect -23 2 -20 5 << metal1 >> rect 14 26 17 32 rect 18 15 21 19 rect 13 12 21 15 rect -2 -8 1 -1 rect 16 -8 19 0 << metal2 >> rect -21 29 -16 32 rect -21 26 -18 29 rect -4 26 -1 32 rect 6 0 15 3 rect 19 0 21 3 rect 6 -3 9 0 << ndcontact >> rect -27 1 -23 5 << m2contact >> rect 15 0 19 4 << labels >> rlabel metal1 17 -8 17 -8 1 bad1 rlabel metal1 17 -8 17 -8 5 (use line label) rlabel ndcontact -27 1 -27 5 3 good5 rlabel metal2 -4 32 -3 32 5 bad4 rlabel metal2 -4 32 -3 32 1 (not wide enough to route to) rlabel polysilicon -20 -8 -15 -8 1 bad5 rlabel polysilicon -20 -8 -15 -8 5 (will work, but why not make wider?) rlabel metal1 21 12 21 19 7 good2 rlabel metal2 6 -3 9 0 1 (works, but better to place on cell edge) rlabel metal2 6 -3 9 0 5 bad3 rlabel metal2 -21 29 -16 32 5 good4 rlabel metal1 14 32 17 32 5 good3 rlabel metal1 -2 -8 1 -5 1 good1 rlabel ndiffusion -27 14 -27 17 3 bad2 (can't route to diff) << end >> magic-8.0.210/doc/tutcells/tut8n.mag0000644000175000001440000000051710751423606015635 0ustar timusersmagic tech scmos timestamp 539560185 << checkpaint >> rect -28 -19 58 9 << metal1 >> rect -16 -7 46 -3 use tut8m left timestamp 539557994 transform 1 0 -16 0 1 -7 box 0 0 16 44 use tut8m center timestamp 539557994 transform 1 0 7 0 1 -7 box 0 0 16 44 use tut8m right timestamp 539557994 transform 1 0 30 0 1 -7 box 0 0 16 44 << end >> magic-8.0.210/doc/tutcells/tut8l.mag0000644000175000001440000000367210751423606015640 0ustar timusersmagic tech scmos timestamp 539905536 << polysilicon >> rect -1 25 4 27 rect 8 25 10 27 rect 31 25 36 27 rect 40 25 42 27 rect 54 25 59 27 rect 63 25 65 27 rect -1 3 1 25 rect 31 12 33 25 rect 8 10 33 12 rect 54 12 56 25 rect 40 10 56 12 rect 31 3 33 10 rect 54 3 56 10 rect -6 1 4 3 rect 8 1 10 3 rect 31 1 36 3 rect 40 1 42 3 rect 54 1 59 3 rect 63 1 65 3 << ndiffusion >> rect 4 3 8 4 rect 36 3 40 4 rect 59 3 63 4 rect 4 -2 8 1 rect 36 -2 40 1 rect 59 -2 63 1 << pdiffusion >> rect 4 27 8 35 rect 36 27 40 35 rect 59 27 63 35 rect 4 24 8 25 rect 36 24 40 25 rect 59 24 63 25 << metal1 >> rect -5 35 4 39 rect 12 35 36 39 rect 40 35 59 39 rect 63 35 67 39 rect -5 28 26 32 rect 30 28 67 32 rect 4 14 8 20 rect 4 8 8 10 rect 36 14 40 20 rect 36 8 40 10 rect 59 14 63 20 rect 59 10 67 14 rect 59 8 63 10 rect -6 -6 4 -2 rect 12 -6 36 -2 rect 40 -6 59 -2 rect 63 -6 67 -2 << pwell >> rect -2 -12 15 14 rect 30 -12 46 14 << nwell >> rect -2 14 15 43 rect 26 14 46 43 << polycontact >> rect 4 10 8 14 rect 36 10 40 14 << ndcontact >> rect 4 4 8 8 rect 36 4 40 8 rect 59 4 63 8 rect 4 -6 8 -2 rect 36 -6 40 -2 rect 59 -6 63 -2 << pdcontact >> rect 4 35 8 39 rect 36 35 40 39 rect 59 35 63 39 rect 4 20 8 24 rect 36 20 40 24 rect 59 20 63 24 << ntransistor >> rect 4 1 8 3 rect 36 1 40 3 rect 59 1 63 3 << ptransistor >> rect 4 25 8 27 rect 36 25 40 27 rect 59 25 63 27 << psubstratepcontact >> rect 8 -6 12 -2 << nsubstratencontact >> rect 8 35 12 39 rect 26 28 30 32 << labels >> rlabel polysilicon -6 1 -6 3 7 In rlabel pwell 38 -10 38 -10 1 Float rlabel metal1 -5 28 -5 32 7 VBias rlabel metal1 67 10 67 14 3 Out rlabel polysilicon 19 11 19 11 1 Mid1 rlabel polysilicon 50 11 50 11 1 Mid2 rlabel metal1 -5 35 -5 39 7 Vdd#0 rlabel metal1 -6 -6 -6 -2 7 Vss#0 rlabel ntransistor 6 2 6 2 7 N1^ rlabel ntransistor 38 2 38 2 7 N2^ rlabel ntransistor 61 2 61 2 7 N3^ rlabel ptransistor 6 26 6 26 7 P1^ rlabel ptransistor 38 26 38 26 7 P2^ rlabel ptransistor 61 26 61 26 7 P3^ << end >> magic-8.0.210/doc/tutcells/tut5a.mag0000644000175000001440000001100310751423606015605 0ustar timusersmagic tech scmos timestamp 616454097 << polysilicon >> rect 97 -18 98 -16 rect 106 -18 108 -16 rect 99 -24 101 -22 rect 112 -24 119 -22 rect 122 -24 124 -22 rect 142 -22 149 -20 rect 154 -19 163 -17 rect 142 -24 144 -22 rect 112 -32 114 -24 rect 142 -29 144 -27 rect 106 -36 112 -34 rect 168 -32 170 -30 rect 161 -38 163 -36 rect 171 -38 172 -36 rect 106 -51 114 -50 rect 161 -51 163 -49 rect 171 -51 172 -49 rect 106 -52 112 -51 rect 99 -65 101 -63 rect 112 -63 114 -55 rect 142 -60 144 -58 rect 168 -57 170 -55 rect 112 -65 119 -63 rect 122 -65 124 -63 rect 97 -71 98 -69 rect 106 -71 108 -69 rect 142 -65 144 -63 rect 142 -67 149 -65 rect 154 -70 163 -68 << ndiffusion >> rect 98 -14 101 -13 rect 105 -14 106 -13 rect 98 -16 106 -14 rect 163 -14 172 -9 rect 163 -17 173 -14 rect 98 -21 106 -18 rect 102 -24 106 -21 rect 96 -36 99 -24 rect 101 -28 102 -24 rect 101 -34 106 -28 rect 163 -28 168 -19 rect 167 -30 168 -28 rect 170 -30 173 -17 rect 163 -33 167 -32 rect 163 -36 171 -33 rect 96 -39 106 -36 rect 96 -49 97 -39 rect 101 -49 106 -39 rect 163 -41 171 -38 rect 163 -49 171 -46 rect 96 -50 106 -49 rect 96 -63 99 -50 rect 101 -59 106 -52 rect 101 -63 102 -59 rect 102 -66 106 -63 rect 163 -54 171 -51 rect 163 -57 167 -54 rect 167 -61 168 -57 rect 98 -69 106 -66 rect 163 -68 168 -61 rect 170 -70 173 -57 rect 98 -74 106 -71 rect 163 -73 173 -70 rect 163 -75 167 -73 << pdiffusion >> rect 119 -21 141 -17 rect 119 -22 122 -21 rect 126 -24 141 -21 rect 119 -25 122 -24 rect 130 -25 137 -24 rect 141 -27 142 -24 rect 144 -27 148 -24 rect 145 -32 148 -27 rect 119 -63 122 -62 rect 130 -63 137 -62 rect 145 -60 148 -55 rect 141 -63 142 -60 rect 144 -63 148 -60 rect 119 -66 122 -65 rect 126 -66 141 -63 rect 119 -70 141 -66 << metal1 >> rect 105 -13 107 -9 rect 114 -14 163 -11 rect 90 -19 92 -17 rect 114 -17 117 -14 rect 97 -19 117 -17 rect 90 -20 117 -19 rect 120 -21 149 -17 rect 120 -25 123 -21 rect 160 -21 163 -14 rect 160 -24 177 -21 rect 106 -28 118 -25 rect 122 -29 123 -25 rect 130 -26 137 -24 rect 130 -28 131 -26 rect 136 -28 137 -26 rect 145 -32 163 -29 rect 90 -35 109 -32 rect 106 -39 109 -35 rect 117 -36 144 -33 rect 151 -36 177 -35 rect 151 -38 172 -36 rect 151 -39 154 -38 rect 96 -43 97 -39 rect 92 -44 97 -43 rect 95 -49 97 -44 rect 106 -42 154 -39 rect 106 -48 154 -45 rect 162 -46 165 -41 rect 106 -52 109 -48 rect 151 -49 154 -48 rect 151 -51 172 -49 rect 90 -55 109 -52 rect 117 -54 144 -51 rect 151 -52 177 -51 rect 145 -57 148 -55 rect 106 -62 118 -59 rect 119 -66 122 -62 rect 130 -61 131 -59 rect 136 -61 137 -59 rect 130 -63 137 -61 rect 145 -60 163 -57 rect 90 -68 116 -67 rect 90 -70 92 -68 rect 97 -70 116 -68 rect 119 -70 149 -66 rect 160 -67 177 -64 rect 113 -73 116 -70 rect 160 -73 163 -67 rect 113 -76 163 -73 rect 171 -74 177 -70 rect 171 -78 172 -74 << metal2 >> rect 92 -44 97 -9 rect 111 -13 115 -9 rect 110 -14 115 -13 rect 95 -49 97 -44 rect 92 -80 97 -49 rect 111 -80 115 -14 rect 131 -26 136 -9 rect 131 -57 136 -30 rect 131 -80 136 -61 rect 142 -80 146 -9 rect 151 -41 155 -9 rect 151 -46 157 -41 rect 151 -80 155 -46 rect 172 -74 177 -9 rect 172 -80 177 -78 << polycontact >> rect 92 -19 97 -14 rect 149 -22 154 -17 rect 112 -36 117 -32 rect 172 -41 177 -36 rect 172 -51 177 -46 rect 112 -55 117 -51 rect 92 -73 97 -68 rect 149 -70 154 -65 << ndcontact >> rect 101 -14 105 -9 rect 102 -28 106 -24 rect 163 -32 167 -28 rect 97 -49 101 -39 rect 165 -46 169 -41 rect 102 -63 106 -59 rect 163 -61 167 -57 rect 167 -80 171 -73 << pdcontact >> rect 118 -29 122 -25 rect 137 -28 141 -24 rect 144 -36 148 -32 rect 144 -55 148 -51 rect 118 -62 122 -58 rect 137 -63 141 -59 << m2contact >> rect 107 -13 111 -9 rect 131 -30 136 -26 rect 91 -49 95 -44 rect 157 -46 162 -41 rect 131 -61 136 -57 rect 172 -78 177 -74 << ntransistor >> rect 98 -18 106 -16 rect 99 -34 101 -24 rect 163 -19 170 -17 rect 99 -36 106 -34 rect 168 -30 170 -19 rect 163 -38 171 -36 rect 99 -52 106 -50 rect 163 -51 171 -49 rect 99 -63 101 -52 rect 98 -71 106 -69 rect 168 -68 170 -57 rect 163 -70 170 -68 << ptransistor >> rect 119 -24 122 -22 rect 142 -27 144 -24 rect 142 -63 144 -60 rect 119 -65 122 -63 << psubstratepcontact >> rect 172 -14 177 -9 rect 92 -43 96 -39 << nsubstratencontact >> rect 126 -28 130 -24 rect 126 -63 130 -59 << labels >> rlabel metal2 153 -80 153 -80 1 busB0# rlabel metal2 134 -80 134 -80 1 Vdd! rlabel metal1 90 -54 90 -54 3 accB1# rlabel metal1 90 -33 90 -33 3 accB0# rlabel metal2 113 -80 113 -80 1 busA0# rlabel metal2 95 -80 95 -80 2 GND! rlabel metal1 90 -18 90 -18 3 accA0# rlabel metal1 90 -69 90 -69 3 accA1# rlabel metal2 174 -80 174 -80 1 GND! << end >> magic-8.0.210/doc/tutcells/tut6y.mag0000644000175000001440000000130310751423606015640 0ustar timusersmagic tech scmos timestamp 616458412 << polysilicon >> rect 20 60 25 62 rect 29 60 31 62 rect 20 49 22 60 rect 13 47 22 49 rect 29 47 32 49 rect 20 40 22 47 rect 20 37 25 40 rect 29 37 31 40 << ndiffusion >> rect 25 40 29 41 rect 25 33 29 37 << pdiffusion >> rect 25 62 29 66 rect 25 59 29 60 << metal1 >> rect 13 66 20 70 rect 28 66 32 70 rect 25 52 29 55 rect 25 45 29 47 rect 13 29 20 33 rect 28 29 32 33 << polycontact >> rect 25 47 29 52 << ndcontact >> rect 25 41 29 45 rect 24 29 28 33 << pdcontact >> rect 24 66 28 70 rect 25 55 29 59 << ntransistor >> rect 25 37 29 40 << ptransistor >> rect 25 60 29 62 << psubstratepcontact >> rect 20 29 24 33 << nsubstratencontact >> rect 20 66 24 70 << end >> magic-8.0.210/doc/tutcells/tut4z.mag0000644000175000001440000000266710751423606015655 0ustar timusersmagic tech scmos timestamp 616443771 << polysilicon >> rect 104 107 106 109 rect 104 99 106 104 rect 104 97 114 99 rect 98 91 100 93 rect 116 91 118 97 rect 104 84 106 86 rect 98 82 100 83 << ndiffusion >> rect 95 90 98 91 rect 96 86 98 90 rect 95 83 98 86 rect 100 87 106 91 rect 110 87 116 91 rect 100 83 103 87 rect 106 86 116 87 rect 118 86 131 91 rect 118 84 121 86 rect 106 81 121 84 << pdiffusion >> rect 99 111 108 115 rect 99 107 103 111 rect 99 104 104 107 rect 106 104 107 107 << metal1 >> rect 95 102 98 115 rect 101 108 104 115 rect 101 107 110 108 rect 101 105 107 107 rect 95 99 102 102 rect 91 91 95 92 rect 91 90 96 91 rect 99 82 102 99 rect 107 91 110 103 rect 115 102 118 115 rect 121 94 124 115 rect 114 91 124 94 rect 127 91 131 115 rect 101 77 102 82 rect 99 75 102 77 rect 114 75 117 91 rect 126 81 131 82 rect 126 77 127 81 << metal2 >> rect 91 96 131 100 rect 95 92 96 96 rect 91 90 96 92 rect 91 81 131 82 rect 91 77 127 81 << polycontact >> rect 114 97 118 102 rect 96 77 101 82 << ndcontact >> rect 91 86 96 90 rect 106 87 110 91 rect 121 82 131 86 << pdcontact >> rect 107 103 111 107 << m2contact >> rect 91 92 95 96 rect 127 77 131 81 << ntransistor >> rect 98 83 100 91 rect 116 86 118 91 rect 106 84 118 86 << ptransistor >> rect 104 104 106 107 << psubstratepcontact >> rect 121 77 126 82 << nsubstratencontact >> rect 108 111 112 115 << labels >> rlabel metal1 114 75 117 75 1 accB0 rlabel metal1 99 75 102 75 1 accA0 << end >> magic-8.0.210/doc/tutcells/tut3c.mag0000644000175000001440000000053010751423606015610 0ustar timusersmagic tech scmos timestamp 500617727 << metal1 >> rect -20 64 18 67 rect -20 56 18 59 rect -20 48 18 51 rect -20 40 18 43 rect -20 32 18 35 rect -20 24 18 27 rect -20 16 18 19 rect -20 8 18 11 rect -20 0 18 3 rect -20 -8 18 -5 << metal2 >> rect 22 -8 24 -5 << m2contact >> rect 18 -8 22 -4 << labels >> rlabel space 18 0 20 8 5 Array << end >> magic-8.0.210/doc/tutcells/tut8i.mag0000644000175000001440000000020110751423606015616 0ustar timusersmagic tech scmos timestamp 617922660 << polysilicon >> rect -15 0 11 2 << labels >> rlabel polysilicon -15 0 -15 2 3 A << end >> magic-8.0.210/doc/tutcells/tut6c.mag0000644000175000001440000000077710751423606015630 0ustar timusersmagic tech scmos timestamp 616458517 << error_p >> rect 55 47 57 51 rect 10 33 12 37 rect 10 -4 12 0 rect 55 -4 57 0 rect 55 -23 56 -21 rect 55 -41 57 -37 << polysilicon >> rect 53 28 55 30 rect 54 -23 56 -21 << metal1 >> rect 52 47 55 51 rect 9 33 10 37 rect 52 10 55 14 rect 9 -4 10 0 rect 52 -4 55 0 rect 52 -41 55 -37 use tut6y tut6y_0 timestamp 616458517 transform 1 0 -23 0 1 -33 box 13 29 32 70 use tut6y tut6y_1 array 0 3 20 0 1 51 timestamp 616458517 transform 1 0 22 0 1 -70 box 13 29 32 70 << end >> magic-8.0.210/doc/tutcells/tut8d.mag0000644000175000001440000000017410751423606015622 0ustar timusersmagic tech scmos timestamp 500619087 << polysilicon >> rect 10 2 18 4 << metal1 >> rect 10 5 18 9 rect 10 -3 18 1 << end >> magic-8.0.210/doc/man/0000755000175000001440000000000011504623573013000 5ustar timusersmagic-8.0.210/doc/man/extcheck.10000644000175000001440000000754210751423606014666 0ustar timusers.TH EXTCHECK 1 .SH NAME extcheck \- check hierarchical \fIext\fR\|(5) files for global node connectivity and summarize number of fets, nodes, etc. .SH SYNOPSIS .B extcheck [ .B \-c .I cthresh ] [ .B \-p .I path ] [ .B \-r .I rthresh ] [ .B \-s \fIsym\fB=\fIvalue\fR ] [ .B \-C ] [ .B \-R ] [ .B \-S .I symfile ] [ .B \-T .I tech ] .I root .SH DESCRIPTION \fIExtcheck\fR will read an extracted circuit in the hierarchical \fIext\fR\|(5) representation produced by Magic, check to ensure that all global nodes (those to which a label ending in an exclamantion point is attached) are fully connected in the layout, and then print a count of the number of various items (nodes, fets, etc) encountered while flattening the circuit. The root of the tree to be processed is the file \fIroot\fB.ext\fR; it and all the files it references are recursively flattened. .PP The following options are recognized: .TP .B \-c\ \fIcthresh\fP Set the capacitance threshold to \fIcthresh\fP femtofarads. \fIExtcheck\fR will count the number of explicit internodal capacitors greater than \fIcthresh\fR, the number of nodes whose capacitance is greater than \fIcthresh\fR, as well as the total number of nodes. (Other programs such as \fIext2sim\fR\|(1) use this option as a threshold value below which a capacitor will not be output). The default value for \fIcthresh\fP is 10 femtofarads. .TP .B \-p\ \fIpath\fP Normally, the path to search for \fB.ext\fP files is determined by looking for \fBpath\fP commands in first ~cad/lib/magic/sys/.magic, then ~/.magic, then .magic in the current directory. If \fB\-p\fP is specified, the colon-separated list of directories specified by \fIpath\fP is used instead. Each of these directories is searched in turn for the \fB.ext\fP files in a design. .TP .B \-r\ \fIrthresh\fP Set the resistance threshold to \fIrthresh\fP ohms. Similar in function to \fB\-c\fR, but for resistances. The default value for \fIrthresh\fP is 10 ohms. .TP .B \-s\ \fIsym\fB=\fIvalue\fP It's possible to use special attributes attached to transistor gates to control the length and width of transistors explicitly, rather than allowing them to be determined by the extractor. These attributes are of the form \fBext:w=\fIwidth\fB^\fR or \fBext:l=\fIlength\fB^\fR, where \fIwidth\fR or \fIlength\fR can either be numeric, or textual. (The trailing ``\fB^\fR'' indicates that these are transistor gate attributes). If textual, they are treated as symbols which can be assigned a numeric value at the time \fIext2sim\fR is run. The \fB\-s\fR flag is used to assign numeric values to symbols. If a textual symbol appears in one of the above attributes, but isn't given a numeric value via \fB\-s\fR (or \fB\-S\fR below), then it is ignored; otherwise, the transistor's length or width is set to the numeric value defined for that symbol. \fI(This option is not currently used by extcheck, but it is common to ext2sim\|(1) and other tools that are written using the extflat\|(3) library)\fR .TP .B \-C Set the capacitance threshold to infinity. Because this avoids any internodal capacitance processing, all tools will run faster when this flag is given. .TP .B \-R Set the resistance threshold to infinity. .TP .B \-S\ \fIsymfile\fP Each line in the file \fIsymfile\fR is of the form \fIsym\fB=\fIvalue\fR, just like the argument to the \fB\-s\fR flag above; the lines are interpreted in the same fashion. \fI(This option is not currently used by extcheck, but it is common to ext2sim et. al.)\fR .TP .B \-T\ \fItech\fP Set the technology in the output \fB.sim\fR file to \fItech\fP. This overrides any technology specified in the root \fB.ext\fR file. .SH "SEE ALSO" ext2dlys\|(1), ext2sim\|(1), ext2spice\|(1), magic\|(1), rsim\|(1), sim2spice\|(1), ext\|(5), sim\|(5) .SH AUTHOR Walter Scott .SH BUGS The \fB\-s\fR mechanism is incomplete; it should allow quantities other than transistor lengths and widths to be specified. magic-8.0.210/doc/man/mag.50000644000175000001440000001763610751423606013645 0ustar timusers.\" sccsid @(#)magic.5 4.1 MAGIC (Berkeley) 11/29/85 .\" .\" CONVENTIONS: .\" italics: things that are substituted for .\" boldface: characters that are typed as-is .\" .\" EXAMPLE: \fIfilename\fB.mag\fR .\" or: \fBcif \fR[\fIfile\fR] .\" .de (X .sp .nf .in +1i .. .de )X .in -1i .sp .fi .. .TH MAGIC 5 .UC 4 .SH NAME magic \- format of \fB.mag\fR files read/written by Magic .SH DESCRIPTION Magic uses its own internal ASCII format for storing cells in disk files. Each cell \fIname\fP is stored in its own file, named \fIname\fB.mag\fR. .LP The first line in a \fB.mag\fP file is the string .(X \fBmagic\fP .)X to identify this as a Magic file. .LP The next line is optional and is used to identify the technology in which a cell was designed. If present, it should be of the form .(X \fBtech\fP \fItechname\fP .)X If absent, the technology defaults to a system-wide standard, currently \fBnmos\fP. .LP The next line is also optional and gives a timestamp for the cell. The line is of the format .(X \fBtimestamp\fP \fIstamp\fP .)X where \fIstamp\fP is a number of seconds since 00:00 GMT January 1, 1970 (i.e, the Unix time returned by the library function \fItime()\fP). It should be the last time this cell or any of its children changed. The timestamp is used to detect when a child is edited outside the context of its parent (the parent stores the last timestamp it saw for each of its children; see below). When this occurs, the design-rule checker must recheck the entire area of the child for subcell interaction errors. If this field is omitted in a cell, Magic supplies a default value that forces the rechecks. .LP Next come lines describing the contents of the cell. There are three kinds of groups of lines, describing mask rectangles, subcell uses, and labels. Each group must appear contiguously in the file, but the order between groups is arbitrary. .LP Each group of mask rectangles is headed with a line of the format .(X \fB<<\ \fIlayer\fB\ >>\fR .)X where \fIlayer\fP is a layername known in the current technology (see the \fBtech\fP line above). Each line after this header has the format .(X \fBrect\fI xbot ybot xtop ytop\fR .)X where \fI(xbot,\ ybot)\fR is the lower-left corner of the rectangle in Magic (lambda) coordinates, and \fI(xtop,\ ytop)\fR is the upper-right corner. Degenerate rectangles are not allowed; \fIxbot\fP must be strictly less than \fIxtop\fP, and \fIybot\fP strictly less than \fIytop\fP. The smallest legal value of \fIxbot\fP or \fIybot\fP is \fB\(mi67108858\fP, and the largest legal value for \fIxtop\fP or \fIytop\fP is \fB67108858\fP. Values that approach these limits (within a factor of 100 or 1000) may cause numerical overflows in Magic even though they are not strictly illegal. We recommend using coordinates around zero as much as possible. .PP Rectangles should be non-overlapping, although this is not essential. They should also already have been merged into maximal horizontal strips (the neighbor to the right or left of a rectangle should not be of the same type), but this is also not essential. .PP The second kind of line group describes a single cell use. Each cell use group is of the following form: .(X \fBuse\fI filename use-id\fR \fBarray\fI xlo xhi xsep ylo yhi ysep\fR \fBtimestamp\fI stamp\fR \fBtransform\fI a b c d e f\fR \fBbox\fI xbot ybot xtop ytop\fR .)X A group specifies a single instance of the cell named \fIfilename\fP, with instance-identifier \fIuse-id\fP. The instance-identifier \fIuse-id\fP must be unique among all cells used by this \fB.mag\fP file. If \fIuse-id\fP is not specified, a unique one is generated automatically. .LP The \fBarray\fP line need only be present if the cell is an array. If so, the X indices run from \fIxlo\fP to \fIxhi\fP inclusive, with elements being separated from each other in the X dimension by \fIxsep\fP lambda. The Y indices run from \fIylo\fP to \fIyhi\fP inclusive, with elements being separated from each other in the Y dimension by \fIysep\fP lambda. If \fIxlo\fP and \fIxhi\fP are equal, \fIxsep\fP is ignored; similarly if \fIylo\fP and \fIyhi\fP are equal, \fIysep\fP is ignored. .LP The \fBtimestamp\fP line is optional; if present, it gives the last time this cell was aware that the child \fIfilename\fP changed. If there is no \fBtimestamp\fP line, a timestamp of 0 is assumed. When the subcell is read in, this value is compared to the actual value at the beginning of the child cell. If there is a difference, the ``timestamp mismatch'' message is printed, and Magic rechecks design-rules around the child. .LP The \fBtransform\fP line gives the geometric transform from coordinates of the child \fIfilename\fP into coordinates of the cell being read. The six integers \fIa\fP, \fIb\fP, \fIc\fP, \fId\fP, \fIe\fP, and \fIf\fP are part of the following transformation matrix, which is used to postmultiply all coordinates in the child \fIfilename\fP whenever their coordinates in the parent are required: .sp .in +2i .nf .ta +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i \fIa\fR \fId\fR 0 \fIb\fR \fIe\fR 0 \fIc\fR \fIf\fR 1 .fi .in -2i .LP Finally, \fBbox\fP gives an estimate of the bounding box of cell \fIfilename\fP (covering all the elements of the array if an \fBarray\fP line was present), in coordinates of the cell being read. .LP The third kind of line group in a \fB.mag\fP file is a list of labels. It begins with the line .(X \fB<<\ labels\ >>\fR .)X and is followed by zero or more lines of the following form: .(X \fBrlabel\fI layer xbot ybot xtop ytop position text\fR .)X Here \fIlayer\fP is the name of one of the layers specified in the technology file for this cell. The label is attached to material of this type. \fILayer\fP may be \fBspace\fP, in which case the label is not considered to be attached to any layer. .LP Labels are rectangular. The lower-left corner of the label (the part attached to any geometry if \fIlayer\fP is non-\fBspace\fR) is at \fI(xbot,\ ybot)\fR, and the upper-right corner at \fI(xtop,\ ytop)\fR. The width of the rectangle or its height may be zero. In fact, most labels in Magic have a lower-left equal to their upper right. .LP The text of the label, \fItext\fP, may be any sequence of characters not including a newline. This text is located at one of nine possible orientations relative to the center of the label's rectangle. \fIPosition\fP is an integer between 0 and 8, each of which corresponds to a different orientation: .(X .ta +0.5i +0.5i \fB0\fR center \fB1\fR north \fB2\fR northeast \fB3\fR east \fB4\fR southeast \fB5\fR south \fB6\fR southwest \fB7\fR west \fB8\fR northwest .)X .LP A \fB.mag\fP file is terminated by the line .(X \fB<<\ end\ >>\fR .)X Everything following this line is ignored. .LP Any line beginning with a pound sigh (``\fB#\fR'') is considered to be a comment and ignored. Beware, however, that these comments are discarded by Magic when it reads a cell, so if that cell is written again by Magic, the comments will be lost. .SH "NOTE FOR PROGRAMS THAT GENERATE MAGIC FILES" Magic's incremental design rule checker expects that every cell is either completely checked, or contains information to tell the checker which areas of the cell have yet to be examined for design-rule violations. To make sure that the design-rule checker verifies all the material that has been generated for a cell, programs that generate \fB.mag\fP files should place the following rectangle in each file: .(X \fB<< checkpaint >>\fR \fBrect \fIxbot ybot xtop ytop\fR .)X This rectangle may appear anywhere a list of rectangles is allowed; immediately following the \fBtimestamp\fP line at the beginning of a \fB.mag\fP file is a good place. The coordinates \fIxbot\fR etc. should be large enough to completely cover anything in the cell, and must surround all this material by at least one lambda. Be careful, however, not to make this area too ridiculously large. For example, if you use the maximum and minimum legal tile coordinates, it will take the design-rule checker an extremely long time to recheck the area. .SH "SEE ALSO" magic\|(1) magic-8.0.210/doc/man/Makefile0000644000175000001440000000232610751423606014441 0ustar timusers# # makefile for Magic documentation # MAGICDIR = ../.. MANMACS= tmac.anc TROFF=ditroff -h TTROFF=ditroff -Ppsc -t PSDIT=psdit GRN=grn -Ppsc TBL=tbl -Ppsc EQN=eqn -Ppsc include ${MAGICDIR}/defs.mak MANFILES = \ $(DESTDIR)${MANDIR}/man1/ext2spice.1 \ $(DESTDIR)${MANDIR}/man1/extcheck.1 \ $(DESTDIR)${MANDIR}/man1/ext2sim.1 \ $(DESTDIR)${MANDIR}/man1/magic.1 \ $(DESTDIR)${MANDIR}/man5/cmap.5 \ $(DESTDIR)${MANDIR}/man5/displays.5 \ $(DESTDIR)${MANDIR}/man5/dlys.5 \ $(DESTDIR)${MANDIR}/man5/dstyle.5 \ $(DESTDIR)${MANDIR}/man5/ext.5 \ $(DESTDIR)${MANDIR}/man5/glyphs.5 \ $(DESTDIR)${MANDIR}/man5/mag.5 \ $(DESTDIR)${MANDIR}/man5/net.5 \ $(DESTDIR)${MANDIR}/man5/sim.5 install: ${MANFILES} $(DESTDIR)${MANDIR}: ${SCRIPTS}/mkdirs $(DESTDIR)${MANDIR} $(DESTDIR)${MANDIR}/man1: $(DESTDIR)${MANDIR} ${SCRIPTS}/mkdirs $(DESTDIR)${MANDIR}/man1 $(DESTDIR)${MANDIR}/man1/%: % $(DESTDIR)${MANDIR}/man1 ${CP} $* $(DESTDIR)${MANDIR}/man1/$* $(DESTDIR)${MANDIR}/man5: $(DESTDIR)${MANDIR} ${SCRIPTS}/mkdirs $(DESTDIR)${MANDIR}/man5 $(DESTDIR)${MANDIR}/man5/%: % $(DESTDIR)${MANDIR}/man5 ${CP} $* $(DESTDIR)${MANDIR}/man5/$* mans: ${SCRIPTS}/printmans "${TROFF} ${MANMACS} -" *.1 *.5 magic-8.0.210/doc/man/magic.10000644000175000001440000026316610751423606014156 0ustar timusers.\" rcsid "$Header" .\" .\" CONVENTIONS: .\" italics: things that are substituted for .\" boldface: characters that are typed as-is .\" .\" EXAMPLE: \fIfilename\fB.mag\fR .\" or: \fBcif write \fR[\fIfile\fR] .\" .TH MAGIC 1 .UC 4 .SH NAME magic \- VLSI layout editor .SH SYNOPSIS .B magic [ .B \-T\ .I technology ] [ .B \-d\ .I device_type ] [ .B \-g\ .I graphics_port ] [ .B \-m\ .I monitor_type ] [ .B \-D ] [ \fIfile\fP ] .br .SH DESCRIPTION Magic is an interactive editor for VLSI layouts that runs under all variants of UNIX, including Mac OS-X and Cygwin. This man page is a reference manual; if you are a first-time user, you should use the Magic tutorials to get acquainted with the system (see the online resources links below). .PP Magic uses two windows: one for text and a separate window for displaying layouts. Magic runs under the window system X11 (use under Cygwin requires the presence of an X11 server in Windows; the server that comes packaged with Cygwin works well). The command line switch "-d" can be used to tell Magic which kind of display you are running. Specifically, this is useful to tell magic to use OpenGL graphics instead of plain X11 ("-d OGL"), or to use 24 bit plane graphics instead of 8 bit planes ("-d 24BITS") if both are available on a video card with overlay support. .PP Here are the options accepted by Magic: .TP .B \-T The next argument is the name of a technology. The tile types, display information, and design rules for this technology are read by Magic from a technology file when it starts up. The technology defaults to ``scmos''. .TP .B \-d The next argument is the type of workstation or graphics display being used. Magic supports these types: .RS .TP .B NULL A null device for running Magic without using a graphics display, such as a batch job. Note that the special case "-dnull" (lowercase, no space) has a more streamlined startup specifically for batch processing. .TP .B X11 X-windows, version 11. The is the preferred interface. Magic acts as a client to the X window server and interfaces to all graphics terminals supported by the X server. .TP .B OGL OpenGL graphics running under X11. This is the preferred interface on systems having hardware-accelerated 3D graphics video cards and drivers. .IP Addition information on Magic's X11 driver, including options for .Xdefaults files, may be found in ``Magic Maintainer's Manual #4: Using Magic Under X Windows''. .TP .B XWIND Simply another name for the X11 driver. .RE If no device is specified, Magic tries to guess which driver is appropriate (by checking the environment variables and by poking around in /dev). .LP When Magic starts up it looks for a command file in ${CAD_ROOT}/magic/sys/.magicrc and processes it if it exists. Then Magic looks for a file with the name ``.magicrc'' in the home directory and processes it if it exists. Finally, Magic looks for a .magicrc file in the current directory and reads it as a command file if it exists. The .magicrc file format is described under the \fBsource\fR command. If magic is compiled with Tcl/Tk support, then any magic or Tcl/Tk commands may be used inside the startup file. The startup file name was changed to ".magicrc" to avoid conflicts with a common system file named ".magic". However, the name ".magic" will be searched after ".magicrc" for backward compatibility. .SH "COMMANDS -- GENERAL INFORMATION" .PP Magics uses types of commands: Key macros and long commands. The first form consists of single-key (or button) abbreviations called ``macros''; macros are invoked by pressing a single key or mouse button. Certain macros are predefined in the systemwide ${CAD_ROOT}/magic/sys/.magicrc file, but you can override them and add your own macros using the \fBmacro\fR command (described below under COMMANDS FOR ALL WINDOWS). The special macro "." is reserved to mean "execute the last typed long command". You can enter long commands in the terminal console at the console prompt, or from the layout window by typing a \fB:\fR or \fB;\fR key, which are the two other reserved macros meaning "switch keyboard focus to the console window". After typing the \fB:\fR or \fB;\fR key, type the text of the command, which will be written to the terminal window. Multiple commands may be specified on one line by separating them with semicolons. .PP Most commands deal with the window underneath the cursor, so if a command doesn't do what you expect make sure that you are pointing to the correct place on the screen. There are several different kinds of windows in Magic (layout, color, and netlist); each window has a different command set, described in a separate section below. .SH "MOUSE BUTTONS FOR LAYOUT WINDOWS" .PP Magic uses a three button mouse. The buttons are interpreted in a way that depends on the current tool, as indicated by the shape of the cursor (see the \fBtool\fR command). The various tools are described below. The initial tool is \fBbox\fR. These interpretations apply only when mouse buttons are pressed in the interior of a layout window. .TP .B "Box Tool" This is the default tool, and is indicated by a crosshair cursor. It is used to position the box and to paint and erase: .RS .TP \fBleft\fR This button is used to move the box by one of its corners. Normally, this button picks up the box by its lower-left corner. To pick the box up by a different corner, click the right button while the left button is down. This switches the pick-up point to the corner nearest the cursor. When the button is released, the box is moved to position the corner at the cursor location. If the box has been set to snap to the window's grid (see the \fB:snap\fR command), then the box corner is left aligned with the grid that the user has chosen for the window with the \fB:grid\fR command, even if that grid is not visible. .TP \fBright\fR Change the size of the box by moving one corner. Normally this button moves the upper-right corner of the box. To move a different corner, click the left button while the right button is down. This switches the corner to the one nearest the cursor. When you release the button, three corners of the box move in order to place the selected corner at the cursor location (the corner opposite the one you picked up remains fixed). Snapping to the window's grid is handled as for the left button. .TP \fBmiddle (bottom)\fR Used to paint or erase. If the crosshair is over paint, then the area of the box is painted with the layer(s) underneath the crosshair. If the crosshair is over white space, then the area of the box is erased. .RE .TP .B "Wiring Tool" The wiring tool, indicated by an arrow cursor, is used to provide an efficient interface to the wiring commands: .RS .TP \fBleft\fR Same as the long command \fBwire type\fR. .TP \fBright\fR Same as the long command \fBwire leg\fR. .TP \fBmiddle (bottom) \fR Same as the long command \fBwire switch\fR. .RE .TP .B "Netlist Tool" This tool is used to edit netlists interactively. It is indicated by a thick box cursor. .RS .TP \fBleft\fR Select the net associated with the terminal nearest the cursor. .TP \fBright\fR Find the terminal nearest the cursor, and toggle it into the current net (if it wasn't already in the current net) or out of the current net (if it was previously in the net). .TP \fBmiddle (bottom) \fR Find the terminal nearest the cursor, and join its net with the current net. .RE .TP .B "Rsim Tool" Used when running the IRSIM simulator under Magic. A pointing hand is used as the cursor. .RS .TP \fBleft\fR Moves the box just like the box tool. .TP \fBright\fR Moves the box just like the box tool. .TP \fBmiddle (bottom) \fR Displays the Rsim node values of the selected paint. .RE .SH "LONG COMMANDS FOR LAYOUT WINDOWS" .PP These commands work if you are pointing to the interior of a layout window. Commands are invoked by typing a colon (``:'') or semi-colon (``;''), followed by a line containing a command name and zero or more parameters. In addition, macros may be used to invoke commands with single keystrokes. Useful default macros are set in the global \fB.magicrc\fR file (in \fB${CAD_ROOT}/magic/sys\fR, normally \fB/usr/local/lib/magic/sys\fR). You can list all current macros with the \fBmacro\fR command, described under ``LONG COMMANDS FOR ALL WINDOWS''. Unique abbreviations are acceptable for all keywords in commands. The commands are: .TP .B "addpath \fIsearchpath\fR" Add more directories to the end of Magic's cell search path. See the documentation for the \fBpath\fR command for an explanation of the search path. .TP .B "array \fIxsize ysize\fP" Make many copies of the selection. There will be \fIxsize\fR instances in the x-direction and \fIysize\fR instances in the y-direction. Paint and labels are arrayed by copying them. Subcells are not copied, but instead each instance is turned into an array instance with elements numbered from 0 to \fIxsize\fR-1 in the x-direction, and from 0 to \fIysize\fR-1 in the y-direction. The spacing between elements of the array is determined by the box x- and y-dimensions. .TP .B "array \fIxlo ylo xhi yhi\fP" Identical to the form of \fBarray\fR above, except that the elements of arrayed cells are numbered left-to-right from \fIxlo\fR to \fIxhi\fR and bottom-to-top from \fIylo\fR to \fIyhi\fR. It is legal for \fIxlo\fR to be greater than \fIxhi\fR, and also for \fIylo\fR to be greater than \fIyhi\fR. .TP .B "box \fR[\fIargs\fR]" Used to change the size of the box or to find out its size. There are several sorts of arguments that may be given to this command: .RS .TP .I (No arguments.) Show the box size and its location in the edit cell, or root cell of its window if the edit cell isn't in that window. .TP \fIdirection\fR [\fIdistance\fR] Move the box .I distance units in \fIdirection\fR, which may be one of \fBleft\fR, \fBright\fR, \fBup\fR, or \fBdown\fR. \fIDistance\fR defaults to the width of the box if \fIdirection\fP is \fBright\fP or \fBleft\fP, and to the height of the box if \fIdirection\fP is \fBup\fP or \fBdown\fP. .TP \fBwidth [\fIsize\fR] .TP \fBheight [\fIsize\fR] Set the box to the width or height indicated. If \fIsize\fR is not specified the width or height is reported. .TP \fIx1 y1 x2 y2\fR Move the box to the coordinates specified (these are in edit cell coordinates if the edit cell is in the window under the cursor; otherwise these are in the root coordinates of the window). \fIx1\fR and \fIy1\fR are the coordinates of the lower left corner of the box, while \fIx2\fR and \fIy2\fR are the upper right corner. The coordinates must all be integers. .RE .TP \fBcalma \fR[\fIoption\fR] [\fIargs\fR] This command is used to read and write files in Calma GDS II Stream format (version 3.0, corresponding to GDS II Release 5.1). This format is like CIF, in that it describes physical mask layers instead of Magic layers. In fact, the technology file specifies a correspondence between CIF and Calma layers. The current CIF output style (see \fBcif\ ostyle\fR) controls how Calma stream layers are generated from Magic layers. If no arguments are given, the \fBcalma\fR command generates a Calma stream file for the layout in the window beneath the cursor in \fIfile\fB.strm\fR, where \fIfile\fR is the name of the root cell. This stream file describes the entire cell hierarchy in the window. The name of the library is the same as the name of the root cell. \fIOption\fR and \fIargs\fR may be used to invoke one of several additional operations: .RS .TP \fBcalma flatten\fR Ordinarily, Magic arrays are output using the Calma ARRAY construct. After a \fBcalma flatten\fR command, though, arrays will be output instead as a collection of individual cell uses, as occurs when writing CIF. .TP \fBcalma help\fR Print a short synopsis of all of the \fBcalma\fR command options. .TP \fBcalma labels\fR Output labels whenever writing a Calma output file. .TP \fBcalma lower\fR Allow both upper and lower case to be output for label text. This is the default behavior; \fBcalma nolower\fR causes lower case to be converted to upper case on output. .TP \fBcalma noflatten\fR Undoes the effect of a prior \fB:calma flatten\fR command, re-enabling the output of Magic arrays using the Calma ARRAY construct. .TP \fBcalma nolabels\fR Don't output labels when writing a Calma output file. .TP \fBcalma nolower\fR Convert lower to upper case when outputting labels. .TP \fBcalma read \fIfile\fR The file \fIfile\fR.\fBstrm\fR is read in Calma format and converted to a collection of Magic cells. The current CIF input style determines how the Calma layers are converted to Magic layers. The new cells are marked for design-rule checking. Calma format doesn't identify the root of the collection of cells read in, so none of the cells read will appear on the display; use \fBload\fR to make them visible. If the Calma file had been produced by Magic, then the name of the root cell is the same as the library name printed by the \fB:calma read\fR command. .TP \fBcalma write \fIfileName\fR Writes a stream file just as if no arguments had been entered, except that the output is written into \fIfileName\fB.strm\fR instead of using the root cell name for the file name. .RE .TP \fBchannels\fR This command will run just the channel decomposition part of the Magic router, deriving channels for the area under the box. The channels will be displayed as outlined feedback areas over the edit cell. .TP \fBcif \fR[\fIoption\fR] [\fIargs\fR] Read or write files in Caltech Intermediate Form (CIF). If no arguments are given, this command generates a CIF file for the window beneath the cursor in \fIfile\fB.cif\fR, where \fIfile\fR is the name of the root cell. The CIF file describes the entire cell hierarchy in the window. \fIOption\fR and \fIargs\fR may be used to invoke one of several additional CIF operations: .RS .TP \fBcif arealabels \fR[\fByes \fR|\fB no]\fR Enables/disables the cif area-label extension. If enabled, area labels are written via the \fB95\fR cif extension. If disabled, labels are collapsed to points when writing cif and the \fB94\fR cif construct is used. Area-labels are disabled by default (many programs don't understand cif area-labels). .TP \fBcif help\fR Print a short synopsis of all of the cif command options. .TP \fBcif istyle \fR[\fIstyle\fR] Select the style to be used for CIF input. If no \fIstyle\fR argument is provided, then Magic prints the names of all CIF input styles defined in the technology file and identifies the current style. If \fIstyle\fR is provided, it is made the current style. .TP \fBcif ostyle \fR[\fIstyle\fR] Select the style to be used for CIF output. If no \fIstyle\fR argument is provided, then Magic prints the names of all CIF output styles defined in the technology file and identifies the current style. If \fIstyle\fR is provided, it is made the current style. .TP \fBcif read \fIfile\fR The file \fIfile\fR.\fBcif\fR is read in CIF format and converted to a collection of Magic cells. The current input style determines how the CIF layers are converted to Magic layers. The new cells are marked for design-rule checking. Any information in the top-level CIF cell is copied into the edit cell. Note: this command is not undo-able (it would waste too much space and time to save information for undoing). .TP \fBcif see \fIlayer\fR In this command \fIlayer\fR must be the CIF name for a layer in the current output style. Magic will display on the screen all the CIF for that layer that falls under the box, using stippled feedback areas. It's a bad idea to look at CIF over a large area, since this command requires the area under the box to be flattened and therefore is slow. .TP \fBcif statistics\fR Prints out statistics gathered by the CIF generator as it operates. This is probably not useful to anyone except system maintainers. .TP \fBcif write \fIfileName\fR Writes out CIF just as if no arguments had been entered, except that the CIF is written into \fIfileName\fB.cif\fR instead of using the root cell name for the file name. The current output style controls how CIF layers are generated from Magic layers. .TP \fBcif flat \fIfileName\fR Writes out CIF as in the \fBcif write\fR command, but flattens the design first (e.g. creates an internal version with the cell hierarchy removed). This is useful if one wishes to use the \fBand-not\fR feature of the CIF output styles, but is having problems with interactions of overlapping cells. .RE .TP \fBclockwise \fR[\fIdegrees\fR] Rotate the selection by \fB90\fR, \fB180\fR or \fB270\fR degrees. After the rotation, the lower-left corner of the selection's bounding box will be in the same place as the lower-left corner of the bounding box before the rotation. \fIDegrees\fR defaults to \fB90\fR. If the box is in the same window as the selection, it is rotated too. Only material in the edit cell is affected. .TP .B "copy \fR[\fIdirection \fR[\fIamount\fR]]" .TP .B "copy to \fIx y\fR" If no arguments are given, a copy of the selection is picking up at the point lying underneath the box lower-left corner, and placed so that this point lies at the cursor position. If \fIdirection\fR is given, it must be a Manhattan direction (e.g. \fBnorth\fR, see the ``DIRECTIONS'' section below). The copy of the selection is moved in that direction by \fIamount\fR. If the box is in the same window as the selection, it is moved too. \fIAmount\fR defaults to \fB1\fR. The second form of the command behaves as though the cursor were pointing to (\fIx,\ y\fR) in the edit cell; a copy of the selection is picked up by the point beneath the lower-left corner of the box and placed so that this point lies at (\fIx\fR,\fI\ y\fR). .TP .B "corner \fIdirection1 direction2 \fR[layers\fR]" This command is similar to \fBfill\fR, except that it generates L-shaped wires that travel across the box first in \fIdirection1\fR and then in \fIdirection2\fR. For example, \fBcorner north east\fR finds all paint under the bottom edge of the box and extends it up to the top of the box and then across to the right side of the box, generating neat corners at the top of the box. The box should be at least as tall as it is wide for this command to work correctly. \fIDirection1\fR and \fIdirection2\fR must be Manhattan directions (see the section DIRECTIONS below) and must be orthogonal to each other. If \fIlayers\fR is specified then only those layers are used; otherwise all layers are considered. .TP .B "delete" Delete all the information in the current selection that is in the edit cell. When cells are deleted, only the selected use(s) of the cell is (are) deleted: other uses of the cell remain intact, as does the disk file containing the cell. Selected material outside the edit cell is not deleted. .TP \fBdrc option \fR[\fIargs\fR] This command is used to interact with the design rule checker. \fIOption\fR and \fIargs\fR (if needed) are used to invoke a \fBdrc\fR command in one of the following ways: .RS .TP \fBdrc catchup\fR Let the checker process all the areas that need rechecking. This command will not return until design-rule checking is complete or an interrupt is typed. The checker will run even if the background checker has been disabled with \fBdrc off\fR. .TP \fBdrc check\fR Mark the area under the box for rechecking in all cells that intersect the box. The recheck will occur in background after the command completes. This command is not normally necessary, since Magic automatically remembers which areas need to be rechecked. It should only be needed if the design rules are changed. .TP \fBdrc count\fR Print the number of errors in each cell under the box. Cells with no errors are skipped. .TP \fBdrc find\fR [\fInth\fR] Place the box over the \fInth\fR error area in the selected cell or edit cell, and print out information about the error just as if \fBdrc why\fR had been typed. If \fInth\fR isn't given (or is less than 1), the command moves to the next error area. Successive invocations of \fBdrc find\fR cycle through all the error tiles in the cell. If multiple cells are selected, this command uses the upper-leftmost one. If no cells are selected, this command uses the edit cell. .TP \fBdrc help\fR Print a short synopsis of all the drc command options. .TP \fBdrc off\fR Turn off the background checker. From now on, Magic will not recheck design rules immediately after each command (but it will record the areas that need to be rechecked; the command \fBdrc on\fR can be used to restart the checker). .TP \fBdrc on\fR Turn on the background checker. The checker will check whatever modifications have not already been checked. From now on, the checker will reverify modified areas as they result from commands. The checker is run in the background, not synchronously with commands, so it may get temporarily behind if massive changes are made. .TP \fBdrc printrules \fR[\fIfile\fR] Print out the compiled rule set in \fIfile\fR, or on the text terminal if \fIfile\fR isn't given. For system maintenance only. .TP \fBdrc rulestats\fR Print out summary statistics about the compiled rule set. This is primarily for use in writing technology files. .TP \fBdrc statistics\fR Print out statistics kept by the design-rule checker. For each statistic, two values are printed: the count since the last time \fBdrc statistics\fR was invoked, and the total count in this editing session. This command is intended primarily for system maintenance purposes. .TP \fBdrc why\fR Recheck the area underneath the box and print out the reason for each violation found. Since this command causes a recheck, the box should normally be placed around a small area (such as an error area). .RE .TP .B "dump \fIcellName \fR[\fBchild\fI refPointC\fR] [\fBparent\fI refPointP\fR]" Copy the contents of cell \fIcellName\fR into the edit cell so that \fIrefPointC\fR in the child is positioned at point \fIrefPointP\fR in the edit cell. The reference points can either be the name of a label, in which case the lower-left corner of the label's box is used as the reference point, or as a pair of numbers giving the (\fIx\fR,\ \fIy\fR) coordinates of a point explicitly. If \fIrefPointC\fR is not specified, the lower-left corner of \fIcellName\fR cell is used. If \fIrefPointP\fR is not specified, the lower-left corner of the box tool is used (the box must be in a window on the edit cell). After this command completes, the new information is selected. .TP .B "edit" Make the selected cell the edit cell, and edit it in context. The edit cell is normally displayed in brighter colors than other cells (see the \fBsee\fR command to change this). If more than one cell is selected, or if the selected cell is an array, the cursor position is used to select one of those cells as the new edit cell. Generally, Magic commands modify only the current edit cell. .TP .B "erase \fR[\fIlayers\fR]" For the area enclosed by the box, erase all paint in \fIlayers\fR. (See the ``LAYERS'' section for the syntax of layer lists). If \fIlayers\fR is omitted it defaults to \fB*,labels\fR. See your technology manual, or use the \fBlayers\fR command, to find out about the available layer names. .TP .B "expand \fR[\fBtoggle\fR]" If the keyword \fBtoggle\fR is supplied, all of the selected cells that are unexpanded are expanded, and all of the selected cells that are expanded are unexpanded. If \fBtoggle\fR isn't specified, then all of the cells underneath the box are expanded recursively until there is nothing but paint under the box. .TP \fBextract \fIoption\fR [\fIargs\fR] Extract a layout, producing one or more hierarchical \fB.ext\fP files that describe the electrical circuit implemented by the layout. The current extraction style (see \fBextract style\fR below) determines the parameters for parasitic resistance, capacitance, etc. that will be used. The \fBextract\fP command with no parameters checks timestamps and re-extracts as needed to bring all \fB.ext\fR files up-to-date for the cell in the window beneath the crosshair, and all cells beneath it. Magic displays any errors encountered during circuit extraction using stippled feedback areas over the area of the error, along with a message describing the type of error. Option\fR and \fIargs\fR are used in the following ways: .RS .TP \fBextract all\fR All cells in the window beneath the cursor are re-extracted regardless of whether they have changed since last being extracted. .TP \fBextract cell \fIname\fR Extract only the currently selected cell, placing the output in the file \fIname\fP. If more than one cell is selected, this command uses the upper-leftmost one. .TP \fBextract do \fR[ \fIoption\fR ] .TP \fBextract no \fIoption\fR Enable or disable various options governing how the extractor will work. Use \fB:extract do\fR with no arguments to print a list of available options and their current settings. When the \fBadjust\fR option is enabled, the extractor will compute compensating capacitance and resistance whenever cells overlap or abut; if disabled, the extractor will not compute these adjustments but will run faster. If \fBcapacitance\fR is enabled, node capacitances to substrate (perimeter and area) are computed; otherwise, all node capacitances are set to zero. Similarly, \fBresistance\fR governs whether or not node resistances are computed. The \fBcoupling\fR option controls whether coupling capacitances are computed or not; if disabled, flat extraction is significantly faster than if coupling capacitance computation is enabled. Finally, the \fBlength\fR option determines whether or not pathlengths in the root cell are computed (see \fBextract length\fR below). .TP \fBextract help\fR Prints a short synopsis of all the \fBextract\fR command options. .TP \fBextract length\fR [ \fIoption args\fR ] Provides several options for controlling which point-to-point path lengths are extracted explicitly. The extractor maintains two internal tables, one of \fIdrivers\fR, or places where a signal is generated, and one of \fIreceivers\fR, or places where a signal is sent. The components of each table are hierarchical label names, defined by means of the two commands \fBextract length driver \fIname1 \fR[\fIname2 ...\fR] and \fBextract length receiver \fIname1 \fR[\fIname2 ...\fR]. If extraction of pathlengths is enabled (``\fB:extract do length\fR''), then when the root cell in an extract command is being extracted, the extractor will compute the shortest and longest path between each driver and each receiver on the same electrical net, and output it to the \fB.ext\fR file for the root cell. Normally, one should create a file of these Magic commands for the circuit drivers and receivers of interest, and use \fBsource\fR to read it in prior to circuit extraction. \fBExtract length clear\fR removes all the entries from both the driver and receiver tables. .TP \fBextract parents\fR Extract the currently selected cell and all of its parents. All of its parents must be loaded in order for this to work correctly. If more than one cell is selected, this command uses the upper-leftmost one. .TP \fBextract showparents\fR Like \fBextract parents\fP, but only print the cells that would be extracted; don't actually extract them. .TP \fBextract style \fR[\fIstyle\fR] Select the style to be used for extraction parameters. If no \fIstyle\fR argument is provided, then Magic prints the names of all extraction parameter styles defined in the technology file and identifies the current style. If \fIstyle\fR is provided, it is made the current style. .TP \fBextract unique \fR[\fB#\fR] For each cell in the window beneath the cursor, check to insure that no label is attached to more than one node. If the \fB#\fR keyword was not specified, whenever a label is attached to more than one node, the labels in all but one of the nodes are changed by appending a numeric suffix to make them unique. If the \fB#\fR keyword is specified, only names that end in a ``\fB#\fR'' are made unique; any other duplicate nodenames that don't end in a ``\fB!\fR'' are reported by leaving a warning feedback area. This command is provided for converting old designs that were intended for extraction with Mextra, which would automatically append unique suffixes to node names when they appeared more than once. .TP \fBextract warn\fR [ [\fBno\fR] \fIoption\fR | [\fBno\fR] \fBall\fR ] The extractor always reports fatal errors. This command controls the types of warnings that are reported. \fIOption\fR may be one of the following: \fBdup\fR, to warn about two or more unconnected nodes in the same cell that have the same name, \fBfets\fR, to warn about transistors with fewer than the minimum number of terminals, and \fBlabels\fR, to warn when nodes are not labeled in the area of cell overlap. In addition, \fBall\fR may be used to refer to all warnings. If a warning is preceded by \fBno\fR, it is disabled. To disable all warnings, use ``\fBextract warn no all\fR''. To see which warning options are in effect, use ``\fBextract warn\fR''. .RE .TP \fBextresist [\fIcell\fR [\fIthreshold\fR] ] Postprocessor for improving on the resistance calculation performed by the circuit extractor. To use this command, you first have to extract the design rooted at \fIcell\fR with \fB:extract\ \fIcell\fR, and then flatten the design using \fIext2sim\fR\|(1), producing the files \fIcell\fB.sim\fR and \fIcell\fB.nodes\fR. Then run \fB:extresist\fI\ cell\fR to produce a file, \fIcell\fB.res.ext\fR, containing differences between the network described by the \fB.ext\fR files produced the first time around, and a new network that incorporates explicit two-point resistors where appropriate (see below). This file may be appended to \fIcell\fB.ext\fR, and then \fIext2sim\fR\ run for a second time, to produce a new network with explicit resistors. The \fIthreshold\fR parameter is used to control which nodes are turned into resistor networks: any node whose total resistance exceeds \fIthreshold\fR times the smallest on-resistance of any transistor connected to that node will be approximated as a resistor network. .TP \fBfeedback \fIoption\fR [\fIargs\fR] Examine feedback information that is created by several of the Magic commands to report problems or highlight certain things for users. \fIOption\fR and \fIargs\fR are used in the following ways: .RS .TP \fBfeedback add \fItext\fR [\fIstyle\fR] Used to create a feedback area manually at the location of the box. This is intended as a way for other programs like Crystal to highlight things on a layout. They can generate a command file consisting of a \fBfeedback clear\fR command, and a sequence of \fBbox\fR and \fBfeedback add\fR commands. \fIText\fR is associated with the feedback (it will be printed by \fBfeedback why\fR and \fBfeedback find\fR). \fIStyle\fR tells how to display the feedback, and is one of \fBdotted\fR, \fBmedium\fR, \fBoutline\fR, \fBpale\fR, and \fBsolid\fR (if unspecified, \fIstyle\fR defaults to \fBpale\fR). .TP \fBfeedback clear\fR Clears all existing feedback information from the screen. .TP \fBfeedback count\fR Prints out a count of the current number of feedback areas. .TP \fBfeedback find \fR[\fInth\fR] Used to locate a particular feedback area. If \fInth\fR is specified, the box is moved to the location of the \fInth\fR feedback area. If \fInth\fR isn't specified, then the box is moved to the next sequential feedback area after the last one located with \fBfeedback find\fR. In either event, the explanation associated with the feedback area is printed. .TP \fBfeedback help\fR Prints a short synopsis of all the \fBfeedback\fR command options. .TP \fBfeedback save \fIfile\fR This option will save information about all existing feedback areas in \fIfile\fR. The information is stored as a collection of Magic commands, so that it can be recovered with the command \fBsource \fIfile\fR. .TP \fBfeedback why\fR Prints out the explanations associated with all feedback areas underneath the box. .RE .TP .B "fill \fIdirection\fR [\fIlayers\fR]" \fIDirection\fR is a Manhattan direction (see the section DIRECTIONS below). The paint visible under one edge of the box is sampled. Everywhere that the edge touches paint, the paint is extended in the given direction to the opposite side of the box. For example, if \fIdirection\fR is \fBnorth\fR, then paint is sampled under the bottom edge of the box and extended to the top edge. If \fIlayers\fR is specified, then only the given layers are considered; if \fIlayers\fR isn't specified, then all layers are considered. .TP .B "findbox \fR[\fBzoom\fR]" Center the view on the box. If the optional \fBzoom\fR argument is present, zoom into the area specified by the box. This command will complain if the box is not in the window you are pointing to. .TP .B "flush \fR[\fIcellname\fR]" Cell \fIcellname\fR is reloaded from disk. All changes made to the cell since it was last saved are discarded. If \fIcellname\fR is not given, the edit cell is flushed. .TP \fBgaroute \fIoption\fR [\fIargs\fR] This command, with no \fIoption\fR or \fIarg\fR, is like the \fBroute\fR command: it generates routing in the edit cell to make connections specified in the current netlist. (See the \fBroute\fR command for further information). Unlike the \fBroute\fR command, this command is intended to be used for routing types of circuits, such as gate-arrays, whose routing channels can be determined in advance, and which require the ability to river-route across the tops of cells. The channels must have been predefined using \fBgaroute\ channel\fR commands prior to this command being invoked. Unlike the \fBroute\fR command, where the box indicates the routing area, this command ignores the box entirely. The new wires are placed in the edit cell. The netlist used is that selected by the \fBroute netlist\fR command, or the current netlist being edited in a \fBnetlist\fR window if no \fBroute netlist\fR command has been given. \fIOptions\fR and \fIargs\fR have the following effects: .RS .TP \fBgaroute channel \fR[\fItype\fR] .TP \fBgaroute channel \fIxlo ylo xhi yhi \fR[\fItype]\fR Define a channel. If \fIxlo\fR, \fIylo\fR, \fIxhi\fR, and \fIyhi\fR are provided, they are interpreted as the coordinates of the lower-left and upper-right of the bounding box for the channel respectively. Otherwise, the coordinates of the box are used. The boundary of each channel is adjusted inward to lie halfway between routing grid lines if it does not lie there already; if the channel is adjusted, a warning message is printed. The channel defined is an ordinary routing channel if \fItype\fR is not specified; such channels are identical to those used by the router of the \fBroute\fR command. If \fItype\fR is given, it must be either \fBh\fR or \fBv\fR. The channel thereby created will be a \fIriver-routing\fR channel inside which only left-to-right routes are possible (``\fBh\fR'') or top-to-bottom (``\fBv\fR''). Unlike a normal channel, a river-routing channel may contain terminals in its interior. .TP \fBgaroute generate\fI type \fR[\fIfile\fR] Provides a primitive form of channel decomposition for regular structures such as gate-array or standard-cell layouts. Generates a collection of \fBgaroute channel\fR commands, either to the standard output, or to \fIfile\fR if the latter is specified. The \fItype\fR parameter must be either \fBh\fR or \fBv\fR. The entire area contained within the box is turned into routing channels. Each cell inside this area has its bounding box computed for purposes of routing by looking only at those layers considered to be ``obstacles'' to routing (see ``Tutorial #7: Netlists and Routing'' for details). The bounding box just computed is then extended all the way to the sides of the area of the box tool, vertically if \fItype\fR is \fBh\fR or horizontally if \fItype\fR is \fBv\fR. This extended area is then marked as belonging to a river-routing channel of type \fItype\fR; adjacent channels of this type are merged into a single channel. After all cells are processed, the areas not marked as being river-routing channels are output as normal channels. .TP \fBgaroute help\fR Print a short synopsis of all the \fBgaroute\fR command options. .TP \fBgaroute nowarn\fR If a given terminal appears in more than one place inside a cell, the router can leave feedback if it is not possible to route to all of the places where the terminal appears. The \fBgaroute nowarn\fR command instructs the router to leave feedback only if it is not possible to route to \fIany\fR of the locations of a terminal. (This is the default behavior of \fBgaroute\fR router). .TP \fBgaroute route\fR [\fInetlist\fR] Route the edit cell. If \fInetlist\fR is not specified, the netlist used is the same as when \fBgaroute\fR is given with no options. If \fInetlist\fR is given, then it is used instead. .TP \fBgaroute reset\fR Clear all channels defined by \fBgaroute channel\fR in preparation for redefining a new set of channels. .TP \fBgaroute warn\fR The opposite of \fBgaroute nowarn\fR, this command instructs the router to leave feedback if it is not possible to route to all of the places where a terminal appears when a terminal has more than one location, even if not all of those locations are actually selected for routing by the global router. .RE .TP .B "getcell \fIcellName \fR[\fBchild\fI refPointC\fR] [\fBparent\fI refPointP\fR]" This command adds a child cell instance to the edit cell. The instance refers to the cell \fIcellName\fR; it is positioned so that \fIrefPointC\fR in the child is at point \fIrefPointP\fR in the edit cell. The reference points can either be the name of a label, in which case the lower-left corner of the label's box is used as the reference point, or as a pair of numbers giving the (\fIx\fR,\ \fIy\fR) coordinates of a point explicitly. If \fIrefPointC\fR is not specified, the lower-left corner of \fIcellName\fR cell is used. If \fIrefPointP\fR is not specified, the lower-left corner of the box tool is used (the box must be in a window on the edit cell). The new subcell is selected. The difference between this command and \fBdump\fR is that \fBdump\fR copies the contents of the cell, while \fBgetcell\fR simply makes a reference to the original cell. \fICellname\fR must not be the edit cell or one of its ancestors. .TP .B "getnode \fR[\fBalias on\fR | \fBalias off\fR] .TP .B "getnode \fR[\fBabort \fR[\fIstr\fR]] Getnode prints out the node names (used by the extractor) for all selected paint. If aliasing turned on, getnode prints all the names it finds for a given node. It may not print every name that exists, however. When turned off, it just prints one name. The abort option allows the user to tell getnode that it is not important to completely search nodes that have certain names. For example, \fBgetnode abort Vdd\fR will tell getnode not to continue searching the node if it determines that one of its names is Vdd. A \fBgetnode abort\fR, without a string argument, will erase the list of names previously created by calling \fBgetnode abort\fR with string arguments. Getnode can be safely aborted at any time by typing the interrupt character, usually ^C. See \fITutorial #11: Using IRSIM and RSIM with Magic\fR for more information on this command. .TP .B "grid \fR[\fIxSpacing\fR [\fIySpacing \fR[\fIxOrigin yOrigin\fR]]]" .TP .B "grid off" If no arguments are given, a one-unit grid is toggled on or off in the window underneath the cursor. \fBGrid off\fR always turns the grid off, regardless of whether it was on or off previously. If numerical arguments are given, the arguments determine the grid spacing and origin for the window under the cursor. In its most general form, \fBgrid\fR takes four integer arguments. \fBXOrigin\fR and \fByOrigin\fR specify an origin for the grid: horizontal and vertical grid lines will pass through this point. \fBXSpacing\fR and \fBySpacing\fR determine the number of units between adjacent grid lines. If \fBxOrigin\fR and \fByOrigin\fR are omitted, they default to 0. If \fBySpacing\fR is also omitted, the xSpacing value is used for both spacings. Grid parameters will be retained for a window until explicitly changed by another \fIgrid\fR command. When the grid is displayed, a solid box is drawn to show the origin of the edit cell. .TP .B "identify \fIinstance_id" Set the instance identifier of the selected cell use to \fIinstance_id\fR. \fIInstance_id\fR must be unique among all instance identifiers in the parent of the selected cell. Initially, Magic guarantees uniqueness of identifiers by giving each cell an initial identifier consisting of the cell definition name followed by an underscore and a small integer. .TP .B "iroute \fIsubcommand\fR [\fIargs\fR]" This command provides an interactive interface to the Magic maze-router. Routing is done one connection at a time. Three internal \fIhint\fR layers, \fBmagnet\fR, \fBfence\fR, and \fBrotate\fR, allow the user to guide routing graphically. Routes are chosen close to magnets (if possible), routing does not cross fence boundaries, and rotate areas reverse the preferred routing directions for each layer. The maze-router seeks to find a lowest-cost path. Parameters specifying costs for horizontal and vertical routing on each layer, cost for jogs and contacts, and cost (per unit area) for distance between a path and magnets, help determine the nature of the routes. Several \fIsearch\fR parameters permit tuning to achieve acceptable routes in as short a time as possible. Routing can always be interrupted with \fB^C\fR. The iroute subcommands are as follows: .RS .TP \fBiroute\fR Routes from cursor to inside box. .TP \fBiroute contact \fR[\fItype\fR] [\fIparameter\fR] [\fIvalue1\fR] ... [\fIvaluen\fR] An asterisk, \fB*\fR, can be used for \fItype\fR and \fIparameter\fR. This command is for setting and examining parameters related to contacts. .TP \fBiroute help \fR[\fIsubcommand\fR] Summarizes irouter commands. If a \fIsubcommand\fR is given, usage information for that subcommand is printed. .TP \fBiroute layers \fR[\fItype\fR] [\fIparameter\fR] [\fIvalue1\fR] ... [\fIvaluen\fR] An asterisk, \fB*\fR, can be used for \fItype\fR and \fIparameter\fR. This command is for setting and examining parameters related to route layers. .TP \fBiroute route \fR[\fIoptions\fR] Invokes the router. Options are as follows: .in +5 .nf \fB-sLayers\fI layers\fR = layers route may start on \fB-sCursor\fR = start route at cursor (DEFAULT) \fB-sLabel \fIname\fR = start route at label of given name \fB-sPoint \fIx y\fR = start route at given coordinates \fB-dLayers\fI layers\fR = layers route may end on \fB-dBox\fR = route to box (DEFAULT) \fB-dLabel\fI name\fR = route to label of given name \fB-dRect\fI xbot ybot xtop ytop\fR = route to rectangle of given coordinates \fB-dSelection\fI = route to selection .in -5 .fi .TP \fBiroute saveParameters \fR<\fIfilename\fR> Saves all current irouter parameter settings. The parameters can be restored to these values with the command ``\fBsource \fIfilename\fR''. .TP \fBiroute search \fR[\fIsearchParameter\fR] [\fIvalue\fR] Allows parameters controlling the search to be modified. If routing is too slow try increasing \fBrate\fR. If the router is producing bad results, try reducing \fBrate\fR. Its a good idea to make \fBwidth\fR at least twice as big as \fBrate\fR. .TP \fBiroute spacings \fR[\fIroute-type\fR] [\fItype\fR] [\fIspacing\fR] ... [\fItypen spacingn\fR] Default minimum spacings between a route-type placed by the router and other types are derived from the \fBdrc\fR section of the technology file. The defaults can be overridden by this command. The special type \fBSUBCELL\fR is used to specify minimum spacing to unexpanded subcells. .TP \fBiroute verbosity \fR[\fIlevel\fR] Controls the number of messages printed during routing: .in +5 .nf \fB0\fR = errors and warnings only, \fB1\fR = brief, \fB2\fR = lots of statistics. .in -5 .fi .TP \fBiroute version\fR Prints irouter version information. .TP \fBiroute wizard \fR[\fIwizardparameter\fR] [\fIvalue\fR] Used to examine and set miscellaneous parameters. Most of these are best left alone by the unadventurous user. .RE .TP .B "label \fIstring \fR[\fIpos \fR[\fIlayer\fR]]" A label with text \fIstring\fR is positioned at the box location. Labels may cover points, lines, or areas, and are associated with specific layers. Normally the box is collapsed to either a point or to a line (when labeling terminals on the edges of cells). Normally also, the area under the box is occupied by a single layer. If no \fIlayer\fR argument is specified, then the label is attached to the layer under the box, or space if no layer covers the entire area of the box. If \fIlayer\fR is specified but \fIlayer\fR doesn't cover the entire area of the box, the label will be moved to another layer or space. Labels attached to space will be considered by CIF processing programs to be attached to all layers overlapping the area of the label. \fIPos\fR is optional, and specifies where the label text is to be displayed relative to the box (e.g. ``north''). If \fIpos\fR isn't given, Magic will pick a position to ensure that the label text doesn't stick out past the edge of the cell. .TP .B "layers" Prints out the names of all the layers defined for the current technology. .TP .B "load \fR[\fIfile\fR]" Load the cell hierarchy rooted at \fIfile\fB.mag\fR into the window underneath the cursor. If no \fIfile\fR is supplied, a new unnamed cell is created. The root cell of the hierarchy is made the edit cell unless there is already an edit cell in a different window. .TP .B "move \fR[\fIdirection \fR[\fIamount\fR]]" .TP .B "move to \fIx y\fR" If no arguments are given, the selection is picked up by the point underneath the lower-left corner of the box and moved so that this point lies at the cursor location. If \fIdirection\fR is given, it must be a Manhattan direction (e.g. \fBnorth\fR). The selection is moved in that direction by \fIamount\fR. If the box is in the same window as the selection, it is moved too. \fIAmount\fR defaults to 1. Selected material that is not in the edit cell, is not affected. The second form of the command is as though the cursor were pointing to (\fIx,\ y\fR) in the edit cell; the selection is picked up by the point beneath the lower-left corner of the box and moved so that this point lies at (\fIx\fR,\fI\ y\fR). .TP .B "paint \fIlayers" The area underneath the box is painted in \fIlayers\fR. .TP .B "path \fR[\fIsearchpath\fR]" This command tells Magic where to look for cells. \fISearchpath\fR contains a list of directories separated by colons or spaces (if spaces are used, then \fIsearchpath\fR must be surrounded by quotes). When looking for a cell, Magic will check each directory in the path in order, until the cell is found. If the cell is not found anywhere in the path, Magic will look in the system library for it. If the \fIpath\fR command is invoked with no arguments, the current search path is printed. .TP .B "plot \fIoption\fR [\fIargs\fR]" Used to generate hardcopy plots direct from Magic. \fIOptions\fR and \fIargs\fR are used in the following ways: .RS .TP \fBplot gremlin \fIfile\fR [\fIlayers\fR] Generate a Gremlin-format description of everything under the box, and write the description in \fIfile\fR. If \fIlayers\fR isn't specified, paint, labels, and unexpanded subcells are all included in the Gremlin file just as they appear on the screen. If \fIlayers\fR is specified, then just the indicated layers are output in the Gremlin file. \fILayers\fR may include the special layers \fBlabels\fR and \fBsubcell\fR. The Gremlin file is scaled to have a total size between 256 and 512 units; you should use the \fBwidth\fR and/or \fBheight\fR Grn commands to ensure that the printed version is the size you want. Use the \fBmg\fR stipples in Grn. No plot parameters are used in Gremlin plotting. .TP \fBplot help\fR Print a short synopsis of all the \fBplot\fR command options. .TP \fBplot parameters [\fIname value\fR] If \fBplot parameters\fR is invoked with no additional arguments, the values for all of the plot parameters are printed. If \fIname\fR and \fIvalue\fR are provided, then \fIname\fR is the name of a plot parameter and \fIvalue\fR is a new value for it. Plot parameters are used to control various aspects of plotting; all of them have ``reasonable'' initial values. Most of the parameters available now are used to control Versatec-style plotting. They are: .RS .TP \fBcellIdFont\fR The name of the font to use for cell instance ids in Versatec plots. This must be a file in Vfont format. .TP \fBcellNameFont\fR The name of the font to use for cell names in Versatec plots. This must be a file in Vfont format. .TP \fBcolor\fR If this is set to \fBtrue\fR, the \fB:plot versatec\fR command will generate output suitable for a four-color Versatec plotter, using the styles defined in the \fBcolorversatec\fR style of the \fBplot\fR section of the technology file. If \fBcolor\fR is \fBfalse\fR (the default), then \fB:plot versatec\fR generates normal black-and-white plots. .TP \fBdirectory\fR The name of the directory in which to create raster files for the Versatec. The raster files have names of the form \fBmagicPlotXXXXXX\fR, where \fBXXXXXX\fR is a process-specific identifier. .TP \fBdotsPerInch\fR Indicates how many dots per inch there are on the Versatec printer. This parameter is used only for computing the scale factor for plotting. Must be an integer greater than zero. .TP \fBlabelFont\fR The name of the font to use for labels in Versatec plots. This must be a file in Vfont format. .TP \fBprinter\fR The name of the printer to which to spool Versatec raster files. .TP \fBshowcellnames\fR If ``true'' (the default) then the name and instance-identifier of each unexpanded subcell is displayed inside its bounding box. If this parameter is ``false'' then only the bounding box of the cell is displayed. .TP \fBspoolCommand\fR The command used to spool Versatec raster files. This must be a text string containing two ``%s'' formatting fields. The first ``%s'' will be replaced with the printer name, and the second one will be replaced with the name of the raster file. .TP \fBswathHeight\fR How many raster lines of Versatec output to generate in memory at one time. The raster file is generated in swaths in order to keep the memory requirements reasonable. This parameter determines the size of the swaths. It must be an integer greater than zero, and should be a multiple of 16 in order to avoid misalignment of stipple patterns. .TP \fBwidth\fR The number of pixels across the Versatec printer. Must be an integer greater than 0, and must be an even multiple of 32. .RE .TP \fBplot versatec \fR[\fIsize\fR [\fIlayers\fR]] Generate a raster file describing all the the information underneath the box in a format suitable for printing on Versatec black-and-white or color printers, and spool the file for printing. See the plot parameters above for information about the parameters that are used to control Versatec plotting. \fISize\fR is used to scale the plot: a scalefactor is chosen so that the area of the box is \fIsize\fR inches across on the printed page. \fISize\fR defaults to the width of the printer. \fILayers\fR selects which layers (including labels and subcells) to plot; it defaults to everything visible on the screen. .RE .TP .B "plow \fIdirection\fR [\fIlayers\fR]" .TP .B "plow \fIoption\fR [\fIargs\fR]" The first form of this command invokes the plowing operation to stretch and/or compact a cell. \fIDirection\fR is a Manhattan direction. \fILayers\fR is an optional collection of mask layers, which defaults to \fB*\fR. One of the edges of the box is treated as a plow and dragged to the opposite edge of the box (e.g. the left edge is used as the plow when \fBplow right\fR is invoked). All edges on \fIlayers\fR that lie in the plow's path are pushed ahead of it, and they push other edges ahead of them to maintain design rules, connectivity, and transistor and contact sizes. Subcells are moved in their entirety without being modified internally. Any mask information overlapping a subcell moved by plowing is also moved by the same amount. \fIOption\fR and \fIargs\fR are used in the following ways: .RS .TP \fBplow boundary\fR The box specifies the area that may be modified by plowing. This area is highlighted with a pale stipple outline. Subsequent plows are not allowed to modify any area outside that specified by the box; if they do, the distance the plow moves is reduced by an amount sufficient to insure that no geometry outside the boundary gets affected. .TP \fBplow help\fR Prints a short synopsis of all the \fBplow\fR command options. .TP \fBplow horizon\fI\ n\fR .TP \fBplow horizon\fR The first form sets the plowing jog horizon to \fIn\fR units. The second form simply prints the value of the jog horizon. Every time plowing considers introducing a jog in a piece of material, it looks up and down that piece of material for a distance equal to the jog horizon. If it finds an existing jog within this distance, it uses it. Only if no jog is found within the jog horizon does plowing introduce one of its own. A jog horizon of zero means that plowing will always introduce new jogs where needed. A jog horizon of infinity (\fBplow nojogs\fR) means that plowing will not introduce any new jogs of its own. .TP \fBplow jogs\fR Re-enable jog insertion with a horizon of 0. This command is equivalent to \fBplow horizon 0\fR. .TP \fBplow noboundary\fR Remove any boundary specified with a previous \fBplow boundary\fR command. .TP \fBplow nojogs\fR Sets the jog horizon to infinity. This means that plowing will not introduce any jogs of its own; it will only use existing ones. .TP \fBplow nostraighten\fR Don't straighten jogs automatically after each plow operation. .TP \fBplow selection \fR[\fIdirection \fR[\fIdistance\fR]] Like the \fBmove\fR or \fBstretch\fR commands, this moves all the material in the selection that belongs to the edit cell. However, any material not in the selection is pushed out of its way, just as though each piece of the selection were plowed individually. If no arguments are given, the selection is picked up by the point underneath the lower-left corner of the box and plowed so that this point lies at the cursor location. The box is moved along with the selection. If \fIdirection\fR is given, it must be a Manhattan direction (e.g. \fBnorth\fR). The selection is moved in that direction by \fIamount\fR. If the box is in the same window as the selection, it is moved too. \fIAmount\fR defaults to 1. If there is selected material that isn't in the edit cell, it is ignored (note that this is different from \fBselect\fR and \fBmove\fR). If \fIdirection\fR isn't given and the cursor isn't exactly left, right, up, or down from the box corner, then Magic first rounds the cursor position off to a position that is one of those (whichever is closest). .TP \fBplow straighten\fR Straighten jogs automatically after each plow operation. The effect will be as though the \fBstraighten\fR command were invoked after each plow operation, with the same direction, and over the area changed by plowing. .RE .TP \fBresist \fIcell\fR [\fItolerance\fR] This command is similar to \fBextresist\fR above, but used for extracting resistance networks for individual nodes. Only the node underneath the box is processed. The network for this node is output to the file \fIcell\fB.res.ext\fR. See the description for \fBextresist\fR for an explanation of \fItolerance\fR. .TP \fBroute \fIoption\fR [\fIargs\fR] This command, with no \fIoption\fR or \fIarg\fR, is used to generate routing using the Magic router in the edit cell to make connections specified in the current netlist. The box is used to indicate the routing area: no routing will be placed outside the area of the box. The new wires are placed in the edit cell. \fIOptions\fR and \fIargs\fR have the following effects: .RS .TP \fBroute end \fR[\fIreal\fR] Print the value of the channel end constant used by the channel router. If a value is supplied, the channel end constant is set to that value. The channel end constant is a dimensionless multiplier used to compute how far from the end of a channel to begin preparations to make end connections. .TP \fBroute help\fR Print a short synopsis of all the \fBroute\fR command options. .TP \fBroute jog \fR[\fIint\fR] Print the value of the minimum jog length used by the channel router. If a value is supplied, the minimum jog length is set to that value. The channel router makes no vertical jogs shorter than the minimum jog length, measured in router grid units. Higher values for this constant may improve the quality of the routing by removing unnecessary jogs; however, prohibiting short jogs may make some channels unroutable. .TP \fBroute metal\fR Toggle metal maximization on or off. The route command routes the preferred routing layer (termed ``metal'') horizontally and the alternate routing layer vertically. By default wires on the alternate routing layer are then converted, as much as possible, to the preferred layer before being painted into the layout. Enabling metal maximization improves the quality of the resulting routing, since the preferred routing layer generally has better electrical characteristics; however, designers wishing to do hand routing after automatic routing may find it easier to disable metal maximization and deal with a layer-per-direction layout. .TP \fBroute netlist \fR[\fIfile\fR] Print the name of the current netlist. If a file name is specified, it is opened if possible, and the new netlist is loaded. This option is provided primarily as a convenience so you need not open the netlist menu before routing. .TP \fBroute obstacle \fR[\fIreal\fR] Print the obstacle constant used by the channel router. If a value is supplied, set the channel router obstacle constant to that value. The obstacle constant is a dimensionless multiplier used in deciding how far in front of an obstacle the channel router should begin jogging nets out of the way. Larger values mean that nets will jog out of the way earlier; however, if nets jog out of the way too early routing area is wasted. .TP \fBroute origin \fR[\fIx y\fR] Print the x- and y-coordinates of the origin of the routing grid. By default, the routing grid starts from (0,0). However, by supplying an \fIx\fR and \fIy\fR coordinate to the \fBroute origin\fR command, the origin can be set to any other value. This command is primarily useful when routing a chip that has been designed with routing on the same pitch as the router will use, but where the left and bottom edges of the pre-existing routing don't line up with the routing grid lines (for example, the pre-existing routing might have been centered on routing grid lines). The alternative to specifying a different origin for the routing grid would be to translate all the material in the cell to be routed so that the prewiring lined up properly with routing grid lines. .TP \fBroute settings\fR Print the values of all router parameters. .TP \fBroute steady \fR[\fIint\fR] Print the value of the channel router's steady net constant. If a value is supplied, set the steady net constant to the value. The steady net constant, measured in router grid units, specifies how far beyond the next terminal the channel router should look for a conflicting terminal before deciding that a net is rising or falling. Larger values mean that the net rises and falls less often. .TP \fBroute tech\fR Print the router technology information. This includes information such as the names of the preferred and alternate routing layers, their wire widths, the router grid spacing, and the contact size. .TP \fBroute viamin\fR Minimize vias in (previously) routed netlist. This subcommand removes unnecessary layer changes in all nets in the current netlist to minimize via count. The preferred routing layer, \fBlayer1\fR in the \fBrouter\fR section of the technology file, is favored by the algorithm. Note that ``\fBroute viamin\fR'' is an independent routing postpass that can be applied even if the routing was not generated by the \fBroute\fR command, provided the layers and widths agree with the \fBrouter\fR section of the technology file. .TP \fBroute vias \fR[\fIint\fR] Print the value of the metal maximization via constant. If a value is supplied, set the via constant to the value. The via constant, measured in router grid units, represents the tradeoff between metal maximization and the via count. In many cases it is possible to convert wiring on the alternate routing layer into routing on the preferred routing layer (``metal'') at the expense of introducing one or two vias. The via constant specifies the amount of converted wiring that makes it worthwhile to add vias to the routing. .RE .TP .B \fBrsim \fR[\fIoptions\fR]\fR [\fIfilename\fR] Runs rsim under Magic. See \fITutorial #11: Using IRSIM and RSIM with Magic\fR for more information on what options and files are required by rsim. Normally, IRSIM requires a parameter file for the technology and a \fB.sim\fR file describing the circuit. .IP The \fBrsim\fR command without any options can be used to interact with a previously-started rsim. Type \fBrsim\fR and you will see the rsim prompt. To get back to magic, type \fBq\fR. .TP .B "save \fR[\fIname\fR]" Save the edit cell on disk. If the edit cell is currently the ``(UNNAMED)'' cell, \fIname\fR must be specified; in this case the edit cell is renamed to \fIname\fR as well as being saved in the file \fIname\fR.\fBmag\fR. Otherwise, \fIname\fR is optional. If specified, the edit cell is saved in the file \fIname\fR.\fBmag\fR; otherwise, it is saved in the file from which it was originally read. .TP .B "see \fIoption\fR" This command is used to control which layers are to be displayed in the window under the cursor. It has several forms: .RS .TP \fBsee no \fIlayers\fR Do not display the given layers in the window under the cursor. If \fBlabels\fR is given as a layer name, don't display labels in that window either. If \fBerrors\fR is given as a layer, no design-rule violations will be displayed (the checker will continue to run, though). If \fIlayers\fR is given as "*", all mask layers will be disabled, but errors and labels will still be shown. See the "LAYERS" section at the end of this manual page for an explanation of layer naming in Magic. .TP \fBsee \fIlayers\fR Reenable display of the given \fIlayers\fR. Note that "*" expands to all mask layers, but does not include the label or error layers. See the "LAYERS" section at the end of this manual page for details. .TP \fBsee no\fR Don't display any mask layers or labels. Only subcell bounding boxes will be displayed. .TP \fBsee\fR Reenable display of all mask layers, labels, and errors. .TP \fBsee allSame\fR Display all cells the same way. This disables the facility where the edit cell is displayed in bright colors and non-edit cells are in paler colors. After \fBsee allSame\fR, all mask information will be displayed in bright colors. .TP \fBsee no allSame\fR Reenable the facility where non-edit cells are drawn in paler colors. .RE .TP .B "select \fIoption\fR" This command is used to select paint, labels, and subcells before operating on them with commands like \fBmove\fR and \fBcopy\fR and \fBdelete\fR. It has several forms: .RS .TP .B "select" If the cursor is over empty space, then this command is identical to \fBselect cell\fR. Otherwise, paint is selected. The first time the command is invoked, a chunk of paint is selected: the largest rectangular area of material of the same type visible underneath the cursor. If the command is invoked again without moving the cursor, the selection is extended to include all material of the same type, regardless of shape. If the command is invoked a third time, the selection is extended again to include all material that is visible and electrically connected to the point underneath the cursor. .TP .B "select more" This command is identical to \fBselect\fR except that the selection is not first cleared. The result is to add the newly-selected material to what is already in the selection. .TP .B "select less" This chooses material just as \fBselect\fR does, but the material is removed from the selection, rather than added to it. The result is to deselect the chosen material. .TP .B "select \fR[\fBmore\fR | \fBless\fR] \fBarea\fI layers\fR" Select material by area. If \fIlayers\fR are not specified, then all paint, labels, and unexpanded subcells visible underneath the box are selected. If \fIlayers\fR is specified, then only those layers are selected. If \fBmore\fR is specified, the new material is added to the current selection rather than replacing it. If \fBless\fR is specified, the new material is removed from the selection (deselected). .TP .B "select \fR[\fBmore\fR | \fBless\fR] \fBcell\fI name\fR" Select a subcell. If \fIname\fR isn't given, this command finds a subcell that is visible underneath the cursor and selects it. If the command is repeated without moving the cursor then it will step through all the subcells under the cursor. If \fIname\fR is given, it is treated as a hierarchical instance identifier starting from the root of the window underneath the cursor. The named cell is selected. If \fBmore\fR is specified, the new subcell is added to the current selection instead of replacing it. If \fBless\fR is specified, the new subcell is removed from the selection (deselected). .TP .B "select clear" Clear out the selection. This does not affect the layout; it merely deselects everything. .TP .B "select help" Print a short synopsis of the selection commands. .TP .B "select save \fIcell\fR" Save all the information in the selection as a Magic cell on disk. The selection will be saved in file \fIcell\fB.mag\fR. .TP .I "select and the see command" Select interacts with the \fBsee\fR command. When selecting individual pieces of material, only visible layers are candidates for selection. When selecting an entire area, however, both visible and non-visible material is selected. This behavior allows entire regions of material to be moved, even if \fBsee\fR has been used to turn off the display of some of the layers. .RE .TP .B "sideways\fR" Flip the selection left-to-right about a vertical axis running through the center of the selection's area. If the box is in the same window as the selection, it is flipped too. Selected material not in the edit cell is not affected. .TP .B "simcmd \fIcmd\fR" Sends the command \fIcmd\fR to rsim for execution. See \fITutorial #11: Using IRSIM and RSIM with Magic\fR for more information. .TP .B "snap \fR[\fBon\fR]" .TP .B "snap \fR[\fBoff\fR]" Control whether the box and point are snapped to the grid selected for the windows in which they appear (the grid was set by the \fBgrid\fR command), or to the standard 1x1 grid. The default is for snapping to be \fBoff\fR, i.e., snapping to a 1x1 grid. With no arguments, \fBsnap\fR prints whether snapping is enabled or not. .TP .B \fBstartrsim \fR[\fIoptions\fR]\fR [\fIfilename\fR] Similar to the \fBrsim\fR command, except it returns to Magic as soon as rsim is started. See \fITutorial #11: Using IRSIM and RSIM with Magic\fR for more information. .TP .B "straighten \fIdirection\fR" Straighten jogs in wires underneath the box by pulling them in \fIdirection\fR. Jogs are only straightened if doing so will cause no additional geometry to move. .TP .B "stretch \fR[\fIdirection \fR[\fIamount\fR]]" This command is identical to \fBmove\fR except that simple stretching occurs as the selection is moved. Each piece of paint in the selection causes the area through which it's moved to be erased in that layer. Also, each piece of paint in the selection that touches unselected material along its back side causes extra material to be painted to fill in the gap left by the move. If \fIdirection\fR isn't given and the cursor isn't exactly left, right, up, or down from the box corner, then Magic first rounds the cursor position off to a position that is one of those (whichever is closest). .TP .B "tool \fR[\fIname\fR | \fBinfo\fR]" Change the current tool. The result is that the cursor shape is different and the mouse buttons mean different things. The command \fBtool info\fR prints out the meanings of the buttons for the current tool. \fBTool \fIname\fR changes the current tool to \fIname\fR, where \fIname\fR is one of \fBbox\fR, \fBwiring\fR, or \fBnetlist\fR. If \fBtool\fR is invoked with no arguments, it picks a new tool in circular sequence: multiple invocations will cycle through all of the available tools. .TP .B "unexpand" Unexpand all cells that touch the box but don't completely contain it. .TP .B "upsidedown\fR" Flip the selection upside down about a horizontal axis running through the center of the selection's area. If the box is in the same window as the selection then it is flipped too. Selected material that is not in the edit cell is not changed. .TP .B "what" Print out information about all the things that are selected. .TP .B "wire \fIoption \fR[\fIargs\fR]" This command provides a centerline-wiring style user interface. \fIOption\fR and \fIargs\fR specify a particular wiring option, as described below. Some of the options can be invoked via mouse buttons when the \fBwiring\fR tool is active. .RS .TP .B "wire help" Print out a synopsis of the various wiring commands. .TP .B "wire horizontal" Just like \fBwire leg\fR except that the new segment is forced to be horizontal. .TP .B "wire leg" Paint a horizontal or vertical segment of wire from one side of the box over to the cursor's x- or y-location (respectively). The direction (horizontal or vertical) is chosen so as to produce the longest possible segment. The segment is painted in the current wiring material and thickness. The new segment is selected, and the box is placed at its tip. .TP .B "wire switch \fB[\fIlayer width\fR]" Switch routing layers and place a contact at the box location. The contact type is chosen to connect the old and new routing materials. The box is placed at the position of the contact, and the contact is selected. If \fIlayer\fR and \fIwidth\fR are specified, they are used as the new routing material and width, respectively. If they are not specified, the new material and width are chosen to correspond to the material underneath the cursor. .TP .B "wire type \fB[\fIlayer width\fR]" Pick a material and width for wiring. If \fIlayer\fR and \fIwidth\fR are not given, then they are chosen from the material underneath the cursor, a square chunk of material is selected to indicate the layer and width that were chosen, and the box is placed over this chunk. If \fIlayer\fR and \fIwidth\fR are given, then this command does not modify the box position. .TP .B "wire vertical" Just like \fBwire leg\fR except that the new segment is forced to be vertical. .RE .TP .B "writeall \fR[\fBforce\fR]" This command steps through all the cells that have been modified in this edit session and gives you a chance to write them out. If the \fBforce\fR option is specified, then ``autowrite'' mode is used: all modified cells are automatically written without asking for permission. .SH "COMMANDS FOR ALL WINDOWS" These commands are not used for layout, but are instead used for overall, housekeeping functions. They are valid in all windows. .TP .B "closewindow" The window under the cursor is closed. That area of the screen will now show other windows or the background. .TP \fBecho \fR[\fB-n\fR] \fIstr1 str2 ... strN\fR Prints \fIstr1 str2 ... strN\fR in the text window, separated by spaces and followed by a newline. If the \fB-n\fR switch is given, no newline is output after the command. .TP \fBhelp\fR [\fIpattern\fR] Displays a synopsis of commands that apply to the window you are pointing to. If \fIpattern\fR is given then only command descriptions containing the pattern are printed. \fIPattern\fR may contain '*' and '?' characters, which match a string of non-blank characters or a single non-blank character (respectively). .TP .B "logcommands \fR[\fIfile \fR[\fBupdate\fR]]]" If \fIfile\fR is given, all further commands are logged to that file. If no arguments are given, command logging is terminated. If the keyword \fBupdate\fR is present, commands are output to the file to cause the screen to be updated after each command when the command file is read back in. .TP .B "macro \fR[\fIchar \fR[\fIcommand\fR]]" \fICommand\fR is associated with \fIchar\fR such that typing \fIchar\fR on the keyboard is equivalent to typing ``:'' followed by \fIcommand\fR. If \fIcommand\fR is omitted, the current macro for \fIchar\fR is printed. If \fIchar\fR is also omitted, then all current macros are printed. If \fIcommand\fR contains spaces, tabs, or semicolons then it must be placed in quotes. The semicolon acts as a command separator allowing multiple commands to be combined in a single macro. .TP .B "openwindow \fR[\fIcell\fR]" Open a new, empty window at the cursor position. Placement, sizing, and methods of manipulation are determined by the conventions of the window system in use. If \fIcell\fR is specified, then that cell is displayed in the new window. Otherwise the area of the box will be displayed in the new window. .TP .B "pushbutton \fIbutton action\fR" Simulates a button push. Button should be \fBleft\fR, \fBmiddle\fR, or \fBright\fR. Action is one of \fBup\fR, or \fBdown\fR. This command is normally invoked only from command scripts produced by the \fBlogcommands\fR command. .TP .B "quit" Exit Magic and return to the shell. If any cells, colormaps, or netlists have changed since they were last saved on disk, you are given a chance to abort the command and continue in Magic. .TP .B "redo \fR[\fIn\fR]" Redo the last \fIn\fR commands that were undone using \fBundo\fR (see below). The number of commands to redo defaults to 1 if \fIn\fR is not specified. .TP .B "redraw" Redraw the graphics screen. .TP .B "scroll \fIdirection \fR[\fIamount\fR]" The window under the cursor is moved by \fIamount\fR screenfulls in \fIdirection\fR relative to the circuit. If \fIamount\fR is omitted, it defaults to 0.5. .TP .B "send \fItype command\fR" Send a \fIcommand\fR to the window client named by \fItype\fR. The result is just as if \fIcommand\fR had been typed in a window of type \fItype\fR. See \fBspecialopen\fR, below, for the allowable types of windows. .TP .B "setpoint [\fIx y\fR [\fIwindowID\fR]]" Fakes the location of the cursor up until after the next interactive command. Without arguments, just prints out the current point location. This command is normally invoked only from command scripts. .IP If \fIwindowID\fR is given, then the point is assumed to be in that window's screen coordinate system rather than absolute screen coordinates. .TP .B "sleep \fIn" Causes Magic to go to sleep for \fIn\fR seconds. .TP .B "source \fIfilename" Each line of \fIfilename\fR is read and processed as one command. Any line whose last character is backslash is joined to the following line. The commands \fBsetpoint\fR, \fBpushbutton\fR, \fBecho\fR, \fBsleep\fR, and \fBupdatedisplay\fR are useful in command files, and seldom used elsewhere. .TP .B "specialopen \fR[\fIx1 y1 x2 y2\fR] \fItype\fR [\fIargs\fR]" Open a window of type \fItype\fR. If the optional \fIx1 y1 x2 y2\fR coordinates are given, then the new window will have its lower left corner at screen coordinates (\fIx1\fR, \fIy1\fR) and its upper right corner at screen coordinates (\fIx2\fR, \fIy2\fR). The \fIargs\fR arguments are interpreted differently depending upon the type of the window. These types are known: .RS .TP .B layout This type of window is used to edit a VLSI cell. The command takes a single argument which is used as the name of a cell to be loaded. The command .ce \fBopen \fIfilename\fR is a shorthand for the command .ce \fBspecialopen layout \fIfilename\fR. .TP .B color This type of window allows the color map to be edited. See the section COMMANDS FOR COLORMAP EDITING below. .TP .B netlist This type of window presents a menu that can be used to place labels, and to generate and edit net-lists. See the section COMMANDS FOR NETLIST EDITING below. .RE .TP .B "underneath" Move the window pointed at so that it lies underneath the rest of the windows. .TP .B "undo \fR[\fIcount\fR]" Undoes the last \fIcount\fR commands. Almost all commands in Magic are now undo-able. The only holdouts left are cell expansion/unexpansion, and window modifications (change of size, zooming, etc.). If \fIcount\fR is unspecified, it defaults to 1. .TP .B "updatedisplay" Update the display. This command is normally invoked only from command scripts. Scripts that do not contain this command update the screen only at the end of the script. .TP .B "view" Choose a view for the window underneath the cursor so that everything in the window is visible. .TP .B "windscrollbars \fR[\fIon\fR|\fIoff\fR]" Set the flag that determines if new windows will have scroll bars. .TP .B "windowpositions \fR[\fIfile\fR]" Write out the positions of the windows in a format suitable for the \fBsource\fR command. If \fIfile\fR is specified, then write it out to that file instead of to the terminal. .TP .B "zoom \fR[\fIfactor\fR]" Zoom the view in the window underneath the cursor by \fIfactor\fR. If \fIfactor\fR is less than 1, we zoom in; if it is greater than one, we zoom out. .SH "MOUSE BUTTONS FOR NETLIST WINDOWS" .PP When the netlist menu is opened using the command \fBspecial netlist\fR, a menu appears on the screen. The colored areas on the menu can be clicked with various mouse buttons to perform various actions, such as placing labels and editing netlists. For details on how to use the menu, see ``Magic Tutorial #7: Netlists and Routing''. The menu buttons all correspond to commands that could be typed in netlist or layout windows. .SH "COMMANDS FOR NETLIST WINDOWS" .PP The commands described below work if you are pointing to the interior of the netlist menu. They may also be invoked when you are pointing at another window by using the \fBsend netlist\fR command. Terminal names in all of the commands below are hierarchical names consisting of zero or more cell use ids separated by slashes, followed by the label name, e.g. \fBtoplatch/shiftcell_1/in\fR. When processing the terminal paths, the search always starts in the edit cell. .TP \fBadd \fIterm1 term2\fR Add the terminal named \fIterm1\fR to the net containing terminal \fIterm2\fR. If \fIterm2\fR isn't in a net yet, make a new net containing just \fIterm1\fR and \fIterm2\fR. .TP \fBcleanup\fR Check the netlist to make sure that for every terminal named in the list there is at least one label in the design. Also check to make sure that every net contains at least two distinct terminals, or one terminal with several labels by the same name. When errors are found, give the user an opportunity to delete offending terminals and nets. This command can also be invoked by clicking the ``Cleanup'' menu button. .TP \fBcull\fR Examine the current netlist and the routing in the edit cell, and remove those nets from the netlist that are already routed. This command is often used after pre-routing nets by hand, so the router won't try to implement them again. .TP \fBdnet \fIname name\fR ... For each \fIname\fR given, delete the net containing that terminal. If no \fIname\fR is given, delete the currently-selected net, just as happens when the ``No Net'' menu button is clicked. .TP \fBdterm \fIname name\fR ... For each \fIname\fR given, delete that terminal from its net. .TP \fBextract\fR Pick a piece of paint in the edit cell that lies under the box. Starting from this, trace out all the electrically-connected material in the edit cell. Where this material touches subcells, find any terminals in the subcells and make a new net containing those terminals. Note: this is a different command from the \fBextract\fR command in layout windows. .TP \fBfind \fIpattern \fR[\fIlayers\fR] Search the area beneath the box for labels matching \fIpattern\fR, which may contain the regular-expression characters ``\fB*\fR'' ``\fB?\fR'', ``\fB[\fR'', ``\fB]\fR'', and ``\fB\e\fR'' (as matched by \fIcsh\fR\|(1); see the description of the \fBfind\fR button in ``Magic Tutorial #7: Netlists and Routing''). For each label found, leave feedback whose text is the layer on which the label appears, followed by a semicolon, followed by the full hierarchical pathname of the label. The feedback surrounds the area of the label by one unit on all sides. (The reason for the one-unit extension is that feedback rectangles must have positive area, while labels may have zero width or height). If \fIlayers\fR are given, only labels attached to those layers are considered. .TP \fBflush \fR[\fInetlist\fR] The netlist named \fInetlist\fR is reloaded from the disk file \fInetlist\fB.net\fR. Any changes made to the netlist since the last time it was written are discarded. If \fInetlist\fR isn't given, the current netlist is flushed. .TP \fBjoin \fIterm1 term2\fR Join together the nets containing terminals \fIterm1\fR and \fIterm2\fR. The result is a single net containing all the terminals from both the old nets. .TP \fBnetlist \fR[\fIname\fR] Select a netlist to work on. If \fIname\fR is provided, read \fIname\fR.\fBnet\fR (if it hasn't already been read before) and make it the current netlist. If \fIname\fR isn't provided, use the name of the edit cell instead. .TP \fBprint \fR[\fIname\fR] Print the names of all the terminals in the net containing \fIname\fR. If \fIname\fR isn't provided, print the terminals in the current net. This command has the same effect as clicking on the ``Print'' menu button. .TP \fBripup \fR[\fBnetlist\fR] This command has two forms. If \fBnetlist\fR isn't typed as an argument, then find a piece of paint in the edit cell under the box. Trace out all paint in the edit cell that is electrically connected to the starting piece, and delete all of this paint. If \fBnetlist\fR is typed, find all paint in the edit cell that is electrically connected to any of the terminals in the current netlist, and delete all of this paint. .TP \fBsavenetlist \fR[\fIfile\fR] Save the current netlist on disk. If \fIfile\fR is given, write the netlist in \fIfile\fR.\fBnet\fR. Otherwise, write the netlist back to the place from which it was read. .TP \fBshownet\fR Find a piece of paint in any cell underneath the box. Starting from this paint, trace out all paint in all cells that is electrically connected to the starting piece and highlight this paint on the screen. To make the highlights go away, invoke the command with the box over empty space. This command has the same effect as clicking on the ``Show'' menu button. .TP \fBshowterms\fR Find the labels corresponding to each of the terminals in the current netlist, and generate a feedback area over each. This command has the same effect as clicking on the ``Terms'' menu button. .TP \fBtrace\fR [\fIname\fR] This command is similar to \fBshownet\fR except that instead of starting from a piece of paint under the box, it starts from each of the terminals in the net containing \fIname\fR (or the current net if no \fIname\fR is given). All connected paint in all cells is highlighted. .TP \fBverify\fR Compare the current netlist against the wiring in the edit cell to make sure that the nets are implemented exactly as specified in the netlist. If there are discrepancies, feedback areas are created to describe them. This command can also be invoked by clicking the ``Verify'' menu button. .TP \fBwriteall\fR Scan through all the netlists that have been read during this editing session. If any have been modified, ask the user whether or not to write them out. .SH "MOUSE BUTTONS FOR COLORMAP WINDOWS" .PP Color windows display two sets of colored bars and a swatch of the color being edited. The left set of color bars is labeled Red, Green, and Blue; these correspond to the proportion of red, green, and blue in the color being edited. The right set of bars is labeled Hue, Saturation, and Value; these correspond to the same color but in a space whose axes are hue (spectral color), saturation (spectral purity vs. dilution with white), and value (light vs. dark). .PP The value of a color is changed by pointing inside the region spanned by one of the color bars and clicking any mouse button. The color bar will change so that it extends to the point selected by the crosshair when the button was pressed. The color can also be changed by clicking a button over one of the ``pumps'' next to a color bar. A left-button click makes a 1% increment or decrement, and a right-button click makes a 5% change. .PP The color being edited can be changed by pressing the left button over the current color box in the editing window, then moving the mouse and releasing the button over a point on the screen that contains the color to be edited. A color value can be copied from an existing color to the current color by pressing the right mouse button over the current color box, then releasing the button when the cursor is over the color whose value is to be copied into the current color. .SH "COMMANDS FOR COLORMAP WINDOWS" .PP These commands work if you are pointing to the interior of a colormap window. The commands are: .TP .B "color \fR[\fInumber\fR]" Load \fInumber\fR as the color being edited in the window. \fINumber\fR must be an octal number between 0 and 377; it corresponds to the entry in the color map that is to be edited. If no \fInumber\fR is given, this command prints out the value of the color currently being edited. .TP .B "load \fR[\fItechStyle displayStyle monitorType\fR]" Load a new color map. If no arguments are specified, the color map for the current technology style (e.g, \fBmos\fR), display style (e.g, \fB7bit\fR), and monitor type (e.g, \fBstd\fR) is re-loaded. Otherwise, the color map is read from the file \fItechStyle\fR.\fIdisplayStyle\fR.\fImonitorType\fB.cmap\fR in the current directory or in the system library directory. .TP .B "save \fR[\fItechStyle displayStyle monitorType\fR]" Save the current color map. If no arguments are specified, save the color map in a file determined by the current technology style, display style, and monitor type as above. Otherwise, save it in the file \fItechStyle\fR.\fIdisplayStyle\fR.\fImonitorType\fB.cmap\fR in the current directory or in the system library directory. .SH "DIRECTIONS" .PP Many of the commands take a direction as an argument. The valid direction names are \fBnorth\fR, \fBsouth\fR, \fBeast\fR, \fBwest\fR, \fBtop\fR, \fBbottom\fR, \fBup\fR, \fBdown\fR, \fBleft\fR, \fBright\fR, \fBnortheast\fR, \fBne\fR, \fBsoutheast\fR, \fBse\fR, \fBnorthwest\fR, \fBnw\fR, \fBsouthwest\fR, \fBsw\fR, and \fBcenter\fR. In some cases, only Manhattan directions are permitted, which means only \fBnorth\fR, \fBsouth\fR, \fBeast\fR, \fBwest\fR, and their synonyms, are allowed. .SH "LAYERS" .PP The mask layers are different for each technology, and are described in the technology manuals. The layers below are defined in all technologies: .TP .B "*" All mask layers. Does not include special layers like the label layer and the error layer (see below). .TP .B "$" All layers underneath the cursor. .TP .B "errors" Design-rule violations (useful primarily in the \fBsee\fR command). .TP .B "labels" Label layer. .TP .B "subcell" Subcell layer. .PP Layer masks may be formed by constructing comma-separated lists of individual layer names. The individual layer names may be abbreviated, as long as the abbreviations are unique. For example, to indicate polysilicon and n-diffusion, use \fBpoly,ndiff\fR or \fBndiff,poly\fR. The special character \fB\-\fR causes all subsequent layers to be subtracted from the layer mask. For example, \fB*\-p\fR means ``all layers but polysilicon''. The special character \fB\+\fR reverses the effect of a previous \fB\-\fR; all subsequent layers are once again added to the layer mask. .SH "SEE ALSO" .PP ext2sim(1), ext2spice(1), cmap(5), dstyle(5), ext(5), sim(5), glyphs(5), magic(5), displays(5), net(5) .sp Online documentation can be found at the following URLs: .br http://opencircuitdesign.com/magic/ .br http://vlsi.cornell.edu/magic/ .br The OpenCircuitDesign website contains HTML versions of all the documentation found in the Magic "doc" subdirectory, including tutorials, technology file manual; download, compile and install instructions, and command reference. .SH "FILES" .PP .ta 5c .nf ${CAD_ROOT}/magic/sys/.magic startup file to create default macros .br ~/.magic user-specific startup command file .br ${CAD_ROOT}/magic/nmos/* some standard nmos cells .br ${CAD_ROOT}/magic/scmos/* some standard scmos cells .br ${CAD_ROOT}/magic/sys/*.cmap colormap files, see CMAP(5) man page .br ${CAD_ROOT}/magic/sys/*.dstyle display style files, see DSTYLE(5) man page .br ${CAD_ROOT}/magic/sys/*.glyphs cursor and window bitmap files, see GLYPH(5) man page .br ${CAD_ROOT}/magic/sys/*.tech technology files, see ``Maintainer's Manual #2: The Technology File'' .br ${CAD_ROOT}/displays configuration file for Magic serial-line displays .fi .PP \fICAD_ROOT variable.\fR If the shell environment variable \fBCAD_ROOT\fR is set, Magic uses that location instead of the installed location (/usr/local/lib, by default). Normally one would change the search path (see below) rather than redirect the entire \fBCAD_ROOT\fR location. .PP \fISearch path.\fR Magic's system and library files, such as technology files and display-style files, normally are placed in the ${CAD_ROOT}/magic area. However, Magic first tries to find them in the user's current directory. This makes it easier for an individual user to override installed system files. The search path is defined by the Magic command \fBpath\fR, .SH AUTHORS \fBOriginal\fR: Gordon Hamachi, Robert Mayo, John Ousterhout, Walter Scott, George Taylor .sp \fBContributors\fR: Michael Arnold (Magic maze-router and Irouter command), Don Stark (new contact scheme, X11 interface, various other things), Mike Chow (Rsim interface). The X11 driver is the work of several people, including Don Stark, Walter Scott, and Doug Pan. .sp \fBDevelopers\fR: Ongoing development (magic version 6.5 and higher) made possible by Stefanos Sidiropolous, Tim Edwards, Rajit Manohar, Philippe Pouliquen, Michael Godfrey, and others. .sp Many other people have contributed to Magic, but it is impossible to list them all here. We appreciate their help! .SH BUGS .PP If Magic gets stuck for some reason, first try typing Control-C into the terminal window (in the Tcl/Tk version, this is the \fIoriginal\fR terminal, not the Tk console window). Most of Magic's lengthy database searches are interruptible. If this doesn't work, kill the process. The Tcl/Tk version automatically creates periodic backups that may be recovered with "magic -r". .PP Report bugs to \fBmagic-dev@csl.cornell.edu\fR. Please be specific: tell us exactly what you did to cause the problem, what you expected to happen, and what happened instead. If possible send along small files that we can use to reproduce the bug. A list of known bugs and fixes is also available from the above address. Tell us which version of magic you are running. magic-8.0.210/doc/man/sim.50000644000175000001440000001172210751423606013657 0ustar timusers.\" sccsid @(#)sim.5 4.1 MAGIC (Berkeley) 11/29/85 .\" .\" CONVENTIONS: .\" italics: things that are substituted for .\" boldface: characters that are typed as-is .\" .\" EXAMPLE: \fIfilename\fB.mag\fR .\" or: \fBcif \fR[\fIfile\fR] .\" .TH SIM 5 .UC 4 .SH NAME sim \- format of .sim files read by esim, crystal, etc. .SH DESCRIPTION The simulation tools \fIcrystal\fP\|(1) and \fIesim\fP\|(1) accept a circuit description in \fB.sim\fP format. There is a single \fB.sim\fP file for the entire circuit, unlike Magic's \fIext\fP\|(5) format in which there is a \fB.ext\fP file for every cell in a hierarchical design. .LP A \fB.sim\fP file consists of a series of lines, each of which begins with a key letter. The key letter beginning a line determines how the remainder of the line is interpreted. The following are the list of key letters understood. .TP .B "|\ units: \fIs\fB tech: \fItech\fR format: \fIMIT|LBL|SU\fR" If present, this must be the first line in the \fB.sim\fP file. It identifies the technology of this circuit as \fItech\fP and gives a scale factor for units of linear dimension as \fIs\fP. All linear dimensions appearing in the \fB.sim\fP file are multiplied by \fIs\fP to give centimicrons. The format field signifies the sim variant. MIT and SU are compatible and understood by all tools. LBL is understood only by gemini(1). .TP .I "type g s d l w x y \fBg=\fIgattrs \fBs=\fIsattrs \fBd=\fIdattrs" Defines a transistor of type \fItype\fP. Currently, \fItype\fP may be \fBe\fP or \fBd\fP for NMOS, or \fBp\fP or \fBn\fP for CMOS. The name of the node to which the gate, source, and drain of the transistor are connected are given by \fIg\fP, \fIs\fP, and \fId\fP respectively. The length and width of the transistor are \fIl\fP and \fIw\fP. The next two tokens, \fIx\fP and \fIy\fP, are optional. If present, they give the location of a point inside the gate region of the transistor. The last three tokens are the attribute lists for the transistor gate, source, and drain. If no attributes are present for a particular terminal, the corresponding attribute list may be absent (i.e, there may be no \fBg=\fP field at all). The attribute lists \fIgattrs\fP, etc. are comma-separated lists of labels. The label names should not include any spaces, although some tools can accept label names with spaces if they are enclosed in double quotes. .B "In version 6.4.5 and later" the default format produced by ext2sim is SU. In this format the attribute of the gate starting with S_ is the substrate node of the fet. The attributes of the gate, and source and substrate starting with A_, P_ are the area and perimeter (summed for that node only once) of the source and drain respectively. This addition to the format is backwards compatible. .TP .B "C \fIn1 n2 cap\fR" Defines a capacitor between nodes \fIn1\fP and \fIn2\fP. The value of the capacitor is \fIcap\fP femtofarads. \fBNOTE:\fR since many analysis tools compute transistor gate capacitance themselves from the transistor's area and perimeter, the capacitance between a node and substrate (GND!) normally does not include the capacitance from transistor gates connected to that node. If the \fB.sim\fR file was produced by \fIext2sim\fR\|(1), check the technology file that was used to produce the original \fB.ext\fR files to see whether transistor gate capacitance is included or excluded; see ``Magic Maintainer's Manual #2: The Technology File'' for details. .TP .B "R \fInode res\fR" Defines the lumped resistance of node \fInode\fP to be \fIres\fP ohms. This construct is only interpreted by a few programs. .TP .B "r \fInode1 node2 res\fR" Defines an explicit resistor between nodes \fInode1\fP and \fInode2\fR of resistance \fIres\fP ohms. This construct is only interpreted by a few programs. .TP .B "N \fInode darea dperim parea pperim marea mperim" As an alternative to computed capacitances, some tools expect the total perimeter and area of the polysilicon, diffusion, and metal in each node to be reported in the \fB.sim\fP file. The \fBN\fP construct associates diffusion area \fIdarea\fP (in square centimicrons) and diffusion perimeter \fIdperim\fP (in centimicrons) with node \fInode\fP, polysilicon area \fIparea\fP and perimeter \fIpperim\fP, and metal area \fImarea\fP and perimeter \fImperim\fP. .I "This construct is technology dependent and obsolete." .TP .B "A \fInode attr\fR" Associates attribute \fIattr\fP for node \fInode\fP. The string \fIattr\fP should contain no blanks. .TP .B "= \fInode1 node2\fR" Each node in a \fB.sim\fP file is named implicitly by having it appear in a transistor definition. All node names appearing in a \fB.sim\fP file are assumed to be distinct. Some tools, such as \fIesim\fP\|(1), recognize aliases for node names. The \fB=\fR construct allows the name \fInode2\fP to be defined as an alias for the name \fInode1\fP. Aliases defined by means of this construct may not appear anywhere else in the \fB.sim\fP file. .SH "SEE ALSO" crystal\|(1), esim\|(1), ext2sim\|(1), sim2spice\|(1), ext\|(5) magic-8.0.210/doc/man/cmap.50000644000175000001440000000440310751423606014005 0ustar timusers.\" sccsid @(#)cmap.5 4.2 (Berkeley) 10/17/85 .\" .\" CONVENTIONS: .\" italics: things that are substituted for .\" boldface: characters that are typed as-is .\" .\" EXAMPLE: \fIfilename\fB.mag\fR .\" or: \fBcif \fR[\fIfile\fR] .\" .TH CMAP 5 .UC 4 .SH NAME cmap \- format of .cmap files (color maps) .SH DESCRIPTION .PP Color-map files define the mapping between eight-bit color numbers and red, green and blue intensities used for those numbers. They are read by Magic as part of system startup, and also by the \fB:load\fR and \fB:save\fR commands in color-map windows. Color-map file names usually have the form \fIx\fB.\fIy\fB.\fIz\fB.cmap\fIn\fR, where \fIx\fR is a class of technology files, \fIy\fR is a class of displays, \fIz\fR is a class of monitors, and \fIn\fR is a version number (currently \fB1\fR). The version number will change in the future if the formap of color-map files ever changes. Normally, \fIx\fR and \fIy\fR correspond to the corresponding parts of a display styles file. For example, the color map file \fBmos.7bit.std.cmap1\fR is used today for most nMOS and CMOS technology files using displays that support at least seven bits of color per pixel and standard-phosphor monitors. It corresponds to the display styles file \fBmos.7bit.dstyle5\fR. .PP Color-map files are stored in ASCII form, with each line containing four decimal integers separated by white space. The first three integers are red, green, and blue intensities, and the fourth field is a color number. For current displays the intensities must be integers between 0 and 255. The color numbers must increase from line to line, and the last line must have a color number of 255. The red, green, and blue intensities on the first line are used for all colors from 0 up to and including the color number on that line. For other lines, the intensities on that line are used for all colors starting one color above the color number on the previous line and continuing up and through the color number on the current line. For example, consider the color map below: .nf .ta 2c 4c 6c 8c 255 0 0 2 0 0 255 3 255 255 255 256 .fi .LP This color map indicates that colors 0, 1, and 2 are to be red, color 3 is to be blue, and all other colors are to be white. .SH "SEE ALSO" magic\|(1), dstyle\|(5) magic-8.0.210/doc/man/NOTUSED/0000755000175000001440000000000011504623573014121 5ustar timusersmagic-8.0.210/doc/man/NOTUSED/path.30000644000175000001440000001065110751423606015142 0ustar timusers.TH PATH 3 .UC 4 .SH NAME path \- procedures for managing search paths in libmagicutils.a .SH SYNOPSIS .nf .B #include .B #include "utils.h" .PP .B "int PaConvertTilde(psource, pdest, size)" .B char **psource, **pdest; .B int size; .PP .B "FILE *PaOpen(file, mode, ext, path, libpath, prealname)" .B "char *file, *mode, *ext;" .B char *path, *libpath; .B char **prealname; .PP .B "char *PaSubsWD(path, newWD)" .B char *path, *newWD; .PP .B "int PaEnum(path, file, func, cdata)" .B char *path, *file; .B "int (*func)(name, cdata);" .B ClientData cdata; .fi .SH DESCRIPTION These procedures implement a path mechanism, whereby several places may be searched for files. .PP .I PaConvertTilde is used to convert \fIcsh\fR\|(1)-style tilde notation for users' home directories (e.g., ``~wss'', ``~/mydir/file.o'') to standard directory names as understood by \fIopen\fR\|(2), etc. If \fI**psource\fR is a tilde (``\fB~\fR''), then the name following the tilde up to the first slash or end of string is converted to a home directory and stored in the string pointed to by \fI*pdest\fR. Then remaining characters in the file name at \fI*psource\fR are copied to \fI*pdest\fR (the file name is terminated by white space, a NULL character, or a colon) and \fI*psource\fR is updated. Upon return, \fI*psource\fR points to the terminating character in the source file name, and \fI*pdest\fR points to the null character terminating the expanded name. If a tilde cannot be converted because the user name cannot be found, \fI*psource\fR is still advanced past the current entry, but nothing is stored at the destination. At most \fIsize\fR characters (including the terminating null character) will be stored at \fI*pdest\fR. The name consisting of a single tilde, i.e, ``\fB~\fR'' with no user name, expands to the current user's home directory. .I PaConvertTilde returns the number of bytes of space left in the destination area if successful, or -1 if the user name couldn't be found in the password file. .PP .I PaOpen opens a file, looking it up in the current path and supplying a default extension. It either returns a pointer to a \fIFILE\fR, as does \fIfopen\fR\|(3s), or NULL if no file could be opened. The mode of the file opened is determined by \fImode\fR, also as in \fIfopen\fR. If \fIext\fR is specified, then it is tacked onto the end of \fIname\fR to construct the name of the file \fIPaOpen\fR will attempt to find. (\fIExt\fR must begin with a dot if that is the extension separator; none is inserted automatically.) If the first character of \fIname\fR is a tilde or slash, \fIPaOpen\fR tries to look up the file with the original name (and extension), doing tilde expansion if necessary and returning the result. Otherwise, it goes through the search path \fIpath\fR (a colon-separated list of directories much as in \fIcsh\fR\|(1)) one entry at a time, trying to look up the file once for each path entry by prepending the path entry to the original file name. This concatenated name is stored in a static string and made available to the caller by setting \fI*prealName\fR to point to it if \fIprealName\fR is non-NULL and if the open succeeds. If the entire \fIpath\fR is tried, and still nothing works, then we try each entry in the library path \fIlibpath\fR next. The static string will be trashed on the next call to this routine. Also, no individual file name is allowed to be more than 200 characters long; excess characters are lost. .PP .I PaSubsWD replaces all uses of the working directory in a path by some fixed directory. It returns a pointer to a path that is just like \fIpath\fR, except that every implicit or explicit use of the working directory (``.'') is replaced by the \fInewWD\fR argument. The result is a static array, which will be trashed on the next call to this procedure. .PP .I PaEnum is used to call a client procedure with each directory in \fIpath\fR prepended to the string \fIfile\fR. The client procedure is of the form \fI(*func)(name, cdata)\fR, where \fIname\fR is a directory in the path prepended to \fIfile\fR, and \fIcdata\fR is the same as \fIcdata\fR passed to \fIPaEnum\fR. This client procedure should return 0 normally, or 1 to abort the path enumeration. If a directory in the search path refers to a non-existent user name (using the ``~user'' syntax), we skip that component. .I PaEnum returns 0 if all clients returned 0, or 1 if some client returned 1. If some client returns 1, the enumeration is aborted. .SH SEE ALSO magicutils\|(3) magic-8.0.210/doc/man/NOTUSED/extflat.30000644000175000001440000002613610751423606015662 0ustar timusers.TH EXTFLAT 3 .UC 4 .SH NAME extflat \- procedures in libextflat.a for flattening extractor \fB.ext\fR files .SH SYNOPSIS .nf \fB #include "hash.h" #include "extflat.h" .sp typedef struct hiername { ... } HierName; typedef struct efnn { ... } EFNodeName; typedef struct efnhdr { ... } EFNodeHdr; typedef struct efnode { ... } EFNode; typedef struct fet { ... } Fet; EFInit() EFDone() char * EFArgs(argc, argv, argsProc, cdata) int argc; char *argv[]; Void (*argsProc)(pargc, pargv, cdata); ClientData cdata; EFReadFile(name) char *name; EFFlatBuild(rootName, flags) char *rootName; int flags; EFFlatDone() EFVisitCaps(capProc, cdata) int (*capProc)(hn1, hn2, double cap, cdata); ClientData cdata; EFVisitFets(fetProc, cdata) int (*fetProc)(fet, prefix, trans, cdata) ClientData cdata; EFVisitNodes(nodeProc, cdata) int (*nodeProc)(node, int r, double c, cdata); ClientData cdata; int EFNodeResist(node) EFNode *node; EFVisitResists(resProc, cdata) int (*resProc)(hn1, hn2, res, cdata); ClientData cdata; bool EFLookDist(hn1, hn2, pMinDist, pMaxDist) HierName *hn1, *hn2; int *pMinDist, *pMaxDist; char * EFHNToStr(hn) HierName *hn; HierName * EFStrToHN(prefix, suffixStr) HierName *prefix; char *suffixStr; HierName * EFHNConcat(prefix, suffix) HierName *prefix, *suffix; HashEntry * EFHNLook(prefix, suffixStr, errorStr) HierName *prefix; char *suffixStr; char *errorStr; HashEntry * EFHNConcatLook(prefix, suffix, errorStr) HierName *prefix, *suffix; char *errorStr; EFHNOut(hn, outf) HierName *hn; FILE *outf; EFHNFree(hn, prefix, type) HierName *hn, *prefix; int type; bool EFHNBest(hn1, hn2) HierName *hn1, *hn2; bool EFHNIsGND(hn) HierName *hn; bool EFHNIsGlob(hn) HierName *hn; typedef struct hiername { ... } HierName; typedef struct efnn { ... } EFNodeName; typedef struct efnhdr { ... } EFNodeHdr; typedef struct efnode { ... } EFNode; typedef struct fet { ... } Fet; \fR .fi .SH DESCRIPTION This module provides procedures for reading, flattening, and traversing the hierarchical extracted circuits (in \fIext\fR\|(5) format) produced by the Magic circuit extractor. .PP To use the procedures in this library, a client should first call .I EFInit to initialize various hash tables. When a client is finally finished with this library, and wishes to free up any remaining memory used by it, .I EFDone should be called. .SH "COMMAND-LINE ARGUMENT PROCESSING" The procedure .I EFArgs is provided for parsing of command-line flags; it should be passed the arguments to \fImain\fR. It will scan through them, recognizing those specific to \fIextflat\fR (see \fIextcheck\fR\|(1) for a list of these arguments) and passing unrecognized arguments to the user-supplied procedure \fIargsProc\fR, which should update \fI*pargc\fR and \fI*pargv\fR to point after each argument it recognizes, or else print an error message if the argument is unrecognized. If it is necessary to pass any additional information to \fIargsProc\fR, the \fIcdata\fR argument of .I EFArgs is automatically passed as the third argument to \fIargsProc\fR. If \fIargsProc\fR is NULL, any arguments not recognized by .I EFArgs are considered to be errors. .I EFArgs considers any argument not beginning with a dash (``\fB\-\fR'') to be a filename, of which there can be at most one. The argument containing this filename is returned to the caller. .SH "FLATTENING A CIRCUIT" Once command-line argument processing is complete, the caller can cause \fIext\fR\|(5) files to be read by calling \fIEFReadFile\fR. This procedure will read \fIname\fB.ext\fR and all of the \fB.ext\fR files it refers to, recursively until the entire tree rooted at \fIname\fR has been read and converted into an internal, hierarchical representation. .I EFReadFile may be called several times with different values of \fIname\fR; any portions of the tree rooted at \fIname\fR that aren't already read in will be. .PP To build up the flat representation of a circuit read using .I EFReadFile one should call \fIEFFlatBuild\fR. The argument \fIrootName\fR gives the name of the cell, which should have been read with .I EFReadFile above, that is the root of the hierarchical circuit to be flattened. After all subsequent processing of the flat design is complete, the caller may call .I EFFlatDone to free the memory associated with the flattened circuit, possibly in preparation for calling .I EFFlatBuild with a different \fIrootName\fR. .PP A different procedure is provided for visiting all of the structures of each type in the flattened circuit: \fIEFVisitCaps\fR, \fIEFVisitFets\fR, \fIEFVisitNodes\fR, and \fIEFVisitResists\fR. Each takes two arguments: a search procedure to apply to all structures visited, and a ClientData field used to pass additional information to this search procedure. .PP .I EFVisitCaps visits each of the internodal capacitors in the flat circuit, applying \fIcapProc\fR to each. The arguments to \fIcapProc\fR are the HierNames \fIhn1\fR and \fIhn2\fR of the two nodes between which the capacitor sits, the capacitance \fIcap\fR in attofarads (type double from 6.5 and later), and the client data \fIcdata\fR with which \fIEFVisitCaps\fR was called. If it's necessary to obtain a pointer to the flat EFNode structures to which \fIhn1\fR or \fIhn2\fR refer, they can be passed to \fIEFHNLook\fR (see below). .PP .I EFVisitFets visits each of the transistors in the circuit, applying \fIfetProc\fR to each. The arguments to \fIfetProc\fR are the transistor structure itself, \fIfet\fR, the hierarchical path \fIprefix\fR that should be prepended to the node names of all the fet's terminals, a geometric transform that must be applied to all coordinates in the fet to convert them to root coordinates, the computed length \fIl\fR and width \fIw\fR of the transistor channel (taking into account substitution of symbolic values with the \fB\-s\fR flag), and the client data \fIcdata\fR with which \fIEFVisitFets\fR was called. .PP .I EFVisitNodes visits each of the flat nodes in the circuit, applying \fInodeProc\fR to each. The arguments to \fInodeProc\fR are the flat EFNode \fInode\fR, its lumped resistance \fIr\fR and capacitance to substrate \fIc\fR (r type is integer and c type is double from 6.5 and later), and the client data \fIcdata\fR with which \fIEFVisitNodes\fR was called. An auxiliary procedure, \fIEFNodeResist\fR, is provided to compute the lumped resistance of a node from the perimeter and area information stored in it; it returns the resistance estimate in milliohms. .PP .I EFVisitResists visits each of the explicit resistors in the circuit, applying \fIresProc\fR to each. The arguments to \fIresProc\fR are similar to those of \fIcapProc\fR: the HierNames \fIhn1\fR and \fIhn2\fR of the two terminals of the resistor, its resistance \fIres\fR, and the client data \fIcdata\fR with which \fIEFVisitResists\fR was called. .PP A final procedure is provided for looking up distance information. .I EFLookDist searches to find if there was a distance measured between the points with the HierNames \fIhn1\fR and \fIhn2\fR. If there was a distance found, it returns TRUE and leaves \fI*pMinDist\fR and \fI*pMaxDist\fR set respectively to the minimum and maximum measured distance between the two points; otherwise, it returns FALSE. .SH "NODE ORGANIZATION" Each electrical node in the circuit is represented by an \fIEFNode\fR structure, which points to a NULL-terminated list of \fIEFNodeName\fRs, each of which in turn points to the \fIHierName\fR list representing the hierarchical name. \fIEFNode\fRs contain capacitance, perimeter, and area information for a node. If this information is not required, an application may use \fIEFNodeHdr\fR structures in place of \fIEFNode\fRs in many cases; an \fIEFNodeHdr\fR consists of just the first few fields of an \fIEFNode\fR. Each \fIEFNodeName\fR is pointed to by a \fIHashEntry\fR in a hash table of all flattened node names. .SH "HIERARCHICAL NAME MANIPULATION" Hierarchical node names are represented as lists of \fIHierName\fR structures. These structures store a hierarchical pathname such as \fBfoo/bar[1][3]/bletch\fR in reverse order, with the last component (\fIe.g.\fR, \fBbletch\fR) first. Pathnames sharing a common prefix can therefore be shared. .PP .I EFStrToHN is the fundamental procedure for creating HierNames; it builds a path of HierNames from the string \fIsuffixStr\fR, and then leaves this path pointing to the prefix path \fIprefix\fR. For example, if \fIprefix\fR were the path of HierNames representing \fBfoo/bar[1][3]\fR, and \fIsuffix\fR were the string \fBshift/Vb1\fR, the resulting HierName would be \fBfoo/bar[1][3]/shift/Vb1\fR, but only the \fBshift/Vb1\fR part would be newly allocated. .I EFHNFree frees the memory allocated for the portions of the HierName path pointed to by \fIhn\fR between \fIhn\fR and \fIprefix\fR, which should be the same as the \fIprefix\fR passed to \fIEFStrToHN\fR. The \fItype\fR parameter is used only for measuring memory usage and should be zero. .I EFHNToStr converts a HierName back into a string; it returns a pointer to a statically-allocated copy of the string representation of the HierName \fIhn\fR. .PP .I EFHNConcat is like .I EFStrToHN in that it concatenates a prefix and a suffix, but the suffix passed to \fIEFHNConcat\fR has already been converted to a HierName. .I EFHNConcat creates a copy of the HierName path \fIsuffix\fR whose final element points to the prefix \fIprefix\fR, in effect producing the concatenation of the two HierNames. .PP .I EFHNLook finds the HashEntry in the flat node hash table corresponding to the HierName that is the concatenation of the HierName \fIprefix\fR and the HierName formed from the suffix string \fIsuffixStr\fR. The value field of this HashEntry (obtained through \fIHashGetValue\fR) is a pointer to an EFNodeName, which in turn points to the EFNode for this name. .I EFHNLook returns NULL if there wasn't an entry in the node hash table by this name, and also prints an error message of the form ``\fIerrorStr\fR: node \fIprefix/suffixStr\fR not found''. .I EFHNConcatLook performs a similar function, but its second argument is a HierName instead of a string. .PP .I EFHNOut writes the HierName \fIhn\fR to the output FILE \fI*outf\fR. The \fB-t\fR flag can be passed to \fIEFArgs\fR to request suppression of trailing ``\fB!\fR'' or ``\fB#\fR'' characters in node names when they are output by \fIEFHNOut\fR. .PP Three predicates are defined for HierNames. .I EFHNBest returns TRUE if \fIhn1\fR is ``preferred'' to \fIhn2\fR, or FALSE if the opposite is true. Global names (ending in ``\fB!\fR'') are preferred to ordinary names, which are preferred to automatically-generated names (ending in ``\fB#\fR''). Among two names of the same type, the one with the least number of pathname components is preferred. If two names have the same number of components, the one lexicographically earliest is preferable. .I EFHNIsGND returns TRUE if its argument is the ground node ``\fBGND!\fR''. .I EFHNIsGlob returns TRUE if its argument is a global node name, i.e., ends in an exclamation point. .SH SEE ALSO extcheck\|(1), ext2dlys\|(1), ext2sim\|(1), ext2spice\|(1), magic\|(1) magicutils\|(3), ext\|(5) magic-8.0.210/doc/man/NOTUSED/stack.30000644000175000001440000000557110751423606015320 0ustar timusers.TH STACK 3 .UC 4 .SH NAME stack \- procedures for managing stacks in libmagicutils.a .SH SYNOPSIS .nf .B #include "magic.h" .B #include "stack.h" .PP .B Stack *StackNew(sincr) .B int sincr; .PP .B StackFree(stack) .B Stack *stack; .PP .B ClientData StackPop(stack) .B Stack *stack; .PP .B ClientData StackLook(stack) .B Stack *stack; .PP .B StackPush(arg, stack) .B ClientData arg; .B Stack *stack; .PP .B StackEnum(stack, func, cdata) .B Stack *stack; .B int (*func)(item, i, cdata) .B ClientData item, cdata; .B int i; .PP .B StackCopy(src, dest, copystr) .B Stack *src, **dest; .B bool copystr; .PP .B bool StackEmpty(stack) .B Stack *stack; .PP .B ClientData STACKPOP(stack) .B Stack *stack; .PP .B ClientData STACKLOOK(stack) .B Stack *stack; .PP .B STACKPUSH(arg, stack) .B ClientData arg; .B Stack *stack; .fi .SH DESCRIPTION These procedures implement a simple stack mechanism, allowing stacks containing an arbitrary number of one-word elements to be created, manipulated, and destroyed. .PP .I StackNew creates and returns a new \fIStack\fR. This stack grows automatically as new items are pushed on it. The number of new elements for which space is added each time the stack grows is specified by \fIsincr\fR. When the stack is through being used, \fIStackFree\fR frees it. .PP Elements can be pushed on the stack using \fIStackPush\fR. The top of the stack can be viewed without removing it by using \fIStackLook\fR, or removed by \fIStackPop\fR. Both return the top element from the stack, or NULL if the stack is empty. Fast macro versions exist for each of these functions: \fISTACKPUSH\fR, \fISTACKLOOK\fR, and \fISTACKPOP\fR. To test whether \fIstack\fR is empty, one can call \fIStackEmpty\fR, which returns \fBTRUE\fR if the stack is empty, or \fBFALSE\fR if it contains any entries. .PP \fIStackEnum\fR visits all the elements in \fIstack\fR without popping them. It applies \fI(*func)()\fR to each element. The arguments to \fI(*func)()\fR are \fIitem\fR, the stack element being visited, \fIi\fR, its index on the stack (1 for the top of the stack, increasing as one moves down the stack), and the same \fIcdata\fR as was passed to \fIStackEnum\fR. If \fI(*func)()\fR returns a non-zero value, the enumeration of the stack aborts and \fIStackEnum\fR returns 1; otherwise, \fIStackEnum\fR returns 0 after visiting all elements in the stack. .PP .I StackCopy is used to make a copy of a stack \fIsrc\fR. It leaves \fI*dest\fR pointing to the copy. If the parameter \fIcopystr\fR is \fBTRUE\fR, then the elements of \fIsrc\fR are interpreted as pointers to NULL-terminated ASCII strings, which are copied into newly allocated memory before the address of the new string is stored in \fI*dest\fR; otherwise, the elements of \fIsrc\fR are just copied to \fI*dest\fR. .SH BUGS There should be a way of declaring a \fIStack\fR that pushes or pops more than a single word at a time. .SH SEE ALSO magicutils\|(3) magic-8.0.210/doc/man/NOTUSED/libmalloc.30000644000175000001440000000750710751423606016152 0ustar timusers.TH MALLOC 3 BRL/CAD .SH NAME malloc, free, realloc \- memory allocator .SH SYNOPSIS .nf .B char *malloc(size) .B Size size; .PP .B void free(ptr) .B char *ptr; .PP .B char *realloc(ptr, size) .B char *ptr; .B Size size; .PP .B extern char endfree .PP .B extern void (*mlabort)() .fi .PP Where .I Size is an integer large enough to hold a char pointer. .SH DESCRIPTION .I Malloc and .I free provide a simple general-purpose memory allocation package. .I Malloc returns a pointer to a block of at least .I size bytes beginning on the boundary of the most stringent alignment required by the architecture. .PP The argument to .I free is a pointer to a block previously allocated by .IR malloc ; this space is made available for further allocation, but its contents are left undisturbed. .PP Needless to say, grave disorder will result if the space assigned by .I malloc is overrun or if some random number is handed to .IR free . .PP .I Malloc maintains multiple lists of free blocks according to size, allocating space from the appropriate list. It calls .I brk (see .IR brk (2)) to get more memory from the system when there is no suitable space already free. .PP .I Free makes an attempt to merge newly freed memory with adjacent free areas. If the result of this merging is an area that touches the system break (the current location of the highest valid address of the data segment of the process) and if .I endfree has a non-zero value, then break is moved back, contracting the process size and releasing the memory back to the system. .PP By default .I endfree has a value of 0, which disables the release of memory back to the system. .PP It is valid to also allocate memory by the use of .I sbrk(3) or by moving up the break with .I brk(3). This memory may be reclaimed and returned to the \fImalloc\fP/\fIfree\fP arena by the use of .I forget (see \fIforget\fP(3)). .PP .I Realloc changes the size of the block pointed to by .I ptr to .I size bytes and returns a pointer to the (possibly moved) block. The contents will be unchanged up to the lesser of the new and old sizes. .PP In order to be compatible with older versions, if .I endfree is 0, then .I realloc also works if .I ptr points to a block freed since the last call of .I malloc or .I realloc. Sequences of .I free, malloc and .I realloc were previously used to attempt storage compaction. This procedure is no longer recommended. In this implementation .I Realloc, .I malloc and .I free do a fair amount of their own storage compaction anyway. .SH DIAGNOSTICS .I Malloc, realloc return a null pointer (0) if there is no available memory or if the arena has been detectably corrupted by storing outside the bounds of a block. .I Realloc makes an attempt to detect and return a null pointer when the break has been moved so that the requested address is no longer valid. .I Malloc may be recompiled to check the arena very stringently on every transaction; those sites with a source code license may do this by recompiling the source with -Ddebug . .PP On detection of corruption of the malloc arena the normal response is an abort with a core dump. This response can be changed by placing a pointer to a function with the desired response into the extern pointer .I mlabort. .SH ALGORITHM .I Malloc returns a block of size equal to the size requested plus an overhead (24 bytes for a 32 bit machine). Freed memory is linked into a chain selected by the size of the freed area (currently, memory size of items in a chain is between two adjacent powers of 2). The search for memory starts with the chain whose length index is at least equal to the size of the request and proceeds if unsuccessful to larger memory size chains. If there is any surplus memory left after the filling of a request it is returned to the appropriate free list chain. .SH BUGS When .I realloc returns 0, the block pointed to by .I ptr may have been destroyed. magic-8.0.210/doc/man/NOTUSED/geometry.30000644000175000001440000003506710751423606016051 0ustar timusers.TH GEOMETRY 3 .UC 4 .SH NAME geometry \- primitive geometric structures and procedures in libmagicutils.a .SH SYNOPSIS .nf .B #include "geometry.h" .PP .B typedef struct { int p_x, p_y; } Point; .PP .B typedef struct { Point r_ll, r_ur; } Rect; .B #define r_xbot r_ll.p_x .B #define r_ybot r_ll.p_y .B #define r_xtop r_ur.p_x .B #define r_ytop r_ur.p_y .PP .B typedef struct G1 { Rect r_r; struct G1 *r_next; } LinkedRect; .PP .B typedef struct { int t_a, t_b, t_c, t_d, t_e, t_f; } Transform; .PP .ta 1.5i .B #define GEO_CENTER 0 .B #define GEO_NORTH 1 .B #define GEO_NORTHEAST 2 .B #define GEO_EAST 3 .B #define GEO_SOUTHEAST 4 .B #define GEO_SOUTH 5 .B #define GEO_SOUTHWEST 6 .B #define GEO_WEST 7 .B #define GEO_NORTHWEST 8 .PP .B bool GEO_OVERLAP(r1, r2) .B Rect *r1; .B Rect *r2; .PP .B bool GEO_TOUCH(r1, r2) .B Rect *r1; .B Rect *r2; .PP .B bool GEO_SURROUND(r1, r2) .B Rect *r1; .B Rect *r2; .PP .B bool GEO_SURROUND_STRONG(r1, r2) .B Rect *r1; .B Rect *r2; .PP .B bool GEO_ENCLOSE(p, r) .B Point *p; .B Rect *r; .PP .B bool GEO_RECTNULL(r) .B Rect *r; .PP .B GEO_EXPAND(src, amount, dst) .B Rect *src, *dst; .B int amount; .PP .B Transform GeoIdentityTransform; .B Transform GeoUpsideDownTransform; .B Transform GeoSidewaysTransform; .B Transform Geo90Transform; .B Transform Geo180Transform; .B Transform Geo270Transform; .PP .B Rect GeoNullRect; .PP .B GeoTransPoint(t, psrc, pdst) .B Transform *t; .B Point *psrc, *pdst; .PP .B GeoTransRect(t, rsrc, rdst) .B Transform *t; .B Rect *rsrc, *rdst; .PP .B GeoTranslateTrans(tsrc, x, y, tdst) .B Transform *tsrc, *tdst; .B int x, y; .PP .B GeoTransTranslate(x, y, tsrc, tdst) .B Transform *tsrc, *tdst; .B int x, y; .PP .B GeoTransTrans(t1, t2, tdst) .B Transform *t1, *t2, *tdst; .PP .B GeoInvertTrans(tsrc, tinv) .B Transform *tsrc, *tinv; .PP .B int GeoScale(t) .B Transform *t; .PP .B GeoDecomposeTransform(t, upsidedown, angle) .B Transform *t; .B bool *upsidedown; .B int *angle; .PP .B int GeoNameToPos(name, manhattan, printerrors) .B char *name; .B bool manhattan, printerrors; .PP .B char *GeoPosToName(pos) .B int pos; .PP .B int GeoTransPos(t, pos); .B Transform *t; .B int pos; .PP .B bool GeoInclude(src, dst); .B Rect *src, *dst; .PP .B bool GeoIncludeAll(src, dst); .B Rect *src, *dst; .PP .B bool GeoIncludePoint(src, dst); .B Point *src; .B Rect *dst; .PP .B GeoClip(r, cliparea) .B Rect *r, *cliparea; .PP .B GeoClipPoint(p, cliparea) .B Point *p; .B Rect *cliparea; .PP .B bool GeoDisjoint(area, cliparea, func, cdata) .B Rect *area, *cliparea; .B bool (*func)(rect, cdata); .B ClientData cdata; .PP .B bool GeoDummyFunc(rect, cdata) .B Rect *rect; .B ClientData cdata; .PP .B GeoCanonicalRect(rsrc, rdst) .B Rect *rsrc, *rdst; .PP .B int GeoRectPointSide(r, p) .B Rect *r; .B Point *p; .PP .B int GeoRectRectSide(r1, r2) .B Rect *r1, *r2; .PP .B bool GetRect(f, nskip, r) .B FILE *f; .B int nskip; .B Rect *r; .SH DESCRIPTION These procedures implement a number of useful geometric primitives: a \fIPoint\fR, which consists of an integer \fIx\fR and \fIy\fR coordinate, and a \fIRect\fR, which describes a rectangle by its lower-left and upper-right \fIPoint\fRs. An important predefined \fIRect\fR is \fIGeoNullRect\fR, the rectangle with both its lower-left and upper-right at the origin (0, 0). If linked lists of \fIRect\fRs are needed, the \fILinkedRect\fR primitive can be used. .PP Another primitive is a position relative to a point (\fIGEO_NORTH\fR, \fIGEO_EAST\fR, etc). There are a total of nine positions, corresponding to the eight points around a single point in a grid plus the point itself (\fIGEO_CENTER\fR). .PP The final primitive is a \fITransform\fR, which represents some combination of rotation by a multiple of 90 degrees, mirroring across the \fIx\fR or \fIy\fR axis, scaling by an integer scale factor, and translation by an integer \fIx\fR and \fIy\fR displacement. A \fITransform\fR can be thought of as representing a simple linear transformation on two-dimensional points, or as a matrix of the form: .sp .in +2i .nf .ta +0.3i +0.3i +0.3i +0.3i +0.3i +0.3i +0.3i +0.3i +0.3i \fIa\fR \fId\fR 0 \fIb\fR \fIe\fR 0 \fIc\fR \fIf\fR 1 .fi .in -2i .sp Multiplying a point vector of the form \fI(x,\ y, 0)\fR by this transform gives a transformed point \fI(x',\ y',\ 0)\fR. Although the transform matrix has nine elements, the three on the right-hand are always constant, so only six numbers are needed to describe a transform: four for the rotation (\fIa\fR, \fIb\fR, \fId\fR, \fIe\fR) and two for the translation (\fIc\fR, \fIf\fR). Because the only rotations are multiples of 90 degrees, transforms will always be of one of the following even more specific forms (only the four rotation numbers are shown), where \fIS\fR is the integer scale factor: .sp .in +1i .nf .ta +0.3i +0.6i +0.3i +0.6i +0.3i +0.6i +0.3i \fIS 0 0 -S -S 0 0 S\fR \fI0 S S 0 0 -S -S 0\fR .sp \fIS 0 0 S -S 0 0 -S\fR \fI0 -S S 0 0 S -S 0\fR .fi .in -1i .sp The first four forms correspond to clockwise rotations of 0, 90, 180, and 270 degrees, and the second four correspond to the same four orientations flipped upside down (mirror across the \fIx\fR-axis after rotating). .PP The above rotations or mirrorings with a scale factor of 1 exist as predefined transforms. \fIGeoIdentityTransform\fR is the identity transformation, i.e, no transformation at all, or the first transform listed above. \fIGeo90Transform\fR, \fIGeo180Transform\fR, and \fIGeo270Transform\fR correspond to the next three transformations, or clockwise rotations of 90, 180, and 270 degrees respectively. \fIGeoUpsideDownTransform\fR is the next transform, mirroring across the \fIx\fR-axis. \fIGeoSidewaysTransform\fR is the seventh transform, corresponding to mirroring across the \fIy\fR-axis. The remaining two transforms above (the sixth and eighth) don't have any predefined transforms, but can be built by composing predefined transforms using \fIGeoTransTrans\fR (see below). .PP A number of macros exist for determining relationships between \fIPoint\fRs and \fIRect\fRs. \fIGEO_OVERLAP\fR is TRUE if two rectangles share some area in common. \fIGEO_TOUCH\fR is TRUE if two rectangles share some area or any part of their perimeters (including touching only at a corner). \fIGEO_SURROUND\fR is TRUE if \fIr1\fR completely surrounds \fIr2\fR, where the boundaries of \fIr1\fR and \fIr2\fR are allowed to touch. \fIGEO_SURROUND_STRONG\fR is like \fIGEO_SURROUND\fR, but is only TRUE if \fIr1\fR completely surrounds \fIr2\fR without their borders touching. \fIGEO_ENCLOSE\fR is TRUE if a point \fIp\fR lies inside or on the border of the rectangle \fIr\fR. \fIGEO_RECTNULL\fR is TRUE if \fIr\fR has zero area, which can result if the \fIx\fR-coordinate of its upper-right is less than or equal to the \fIx\fR-coordinate of its lower-left, or similarly for the \fIy\fR-coordinates. Finally, \fIGEO_EXPAND\fR is used to grow (or shrink) a rectangle \fIsrc\fR by an integer distance \fIamount\fR, leaving the new rectangle in \fIdst\fR (which may be the same as \fIsrc\fR). .PP Many procedures exist to manipulate transformations. In general, when they accept more than one Point or Rect as arguments, the Points or Rects must be distinct from each other (i.e, no aliasing is allowed). \fIGeoTransPoint\fR applies the Transform \fI*t\fR to the Point \fI*psrc\fR and leaves its result in the Point \fI*pdst\fR. \fIGeoTransRect\fR is identical, but for Rects; it applies \fIt\fR to \fI*rsrc\fR and leaves its result in \fI*rdst\fR. \fIGeoTransRect\fR guarantees that \fIrdst->r_ur\fR is really above and to the right of \fIrdst->r_ll\fR, by interchanging upper and lower coordinates if necessary after the transform. Note that this is NOT the same as transforming the upper-right and lower-left Points separately, since separate transformations can result in a rectangle whose upper right is below its lower left (e.g, \fIGeoUpsideDownTransform\fR). .PP Three procedures compose transforms, producing the transform that is equivalent to applying first one, then the second of the two transforms. There are two special-case procedures. \fIGeoTranslateTrans\fR composes first the Transform \fI*tsrc\fR and then a simple translation by \fIx\fR and \fIy\fR, storing its result in \fI*tdst\fR. \fIGeoTransTranslate\fR composes first a simple translation by \fIx\fR and \fIy\fR, followed by the Transform \fI*tsrc\fR, also storing its result in \fI*tdst\fR. Finally, \fIGeoTransTrans\fR composes two arbitrary transforms \fI*t1\fR and \fI*t2\fR, leaving its result in \fI*tdst\fR. .PP Transforms that adhere to one of the eight rotation formats described above are always invertible. The inverse of such a transform can be computed by \fIGeoInvertTrans\fR, which leaves the inverse of \fI*tsrc\fR in \fI*tinv\fR. .PP Two procedures extract useful information from Transforms. .I GeoScale returns the scale factor associated with the Transform \fI*t\fR. .I GeoDecomposeTransform breaks up a transform into an optional mirror about the x-axis (i.e., flipping upside down), followed by an optional counterclockwise rotation. It sets \fI*upsidedown\fR to \fBTRUE\fR if the transform requires flipping upside down before rotation, and sets \fI*angle\fR to the degrees of rotation: 0, 90, 180, or 270. .PP Three procedures manipulate positions such as \fIGEO_NORTH\fR. .I GeoNameToPos maps the ASCII \fIname\fR for a position (e.g, ``north'', ``top'', or ``left'', ``west'', etc) into the internal position number. If \fIname\fR is ambiguous, -1 is returned; if \fIname\fR is unrecognized, -2 is returned. If \fImanhattan\fR is TRUE, only the directions corresponding to \fIGEO_NORTH\fR, \fIGEO_SOUTH\fR, \fIGEO_WEST\fR, or \fIGEO_EAST\fR are accepted. If \fIprinterrors\fR is TRUE, \fIGeoNameToPos\fR will print an error message on the standard output in addition to returning -1 or -2. The inverse of \fIGeoNameToPos\fR is \fIGeoPosToName\fR, which returns the ASCII string for a given position \fIpos\fR. .I GeoTransPos applies the Transfor \fI*t\fR to the position \fIpos\fR and returns the new position. Only the rotational part of \fI*t\fR is relevant; the translation is ignored. .PP The next collection of procedures manipulate Points and Rects. .I GeoInclude and .I GeoIncludeAll extend whichever sides of the Rect \fI*dst\fR that are necessary to include the area of the Rect \fI*src\fR. Both return TRUE if \fI*dst\fR was enlarged. If \fI*src\fR is considered to be zero-size (see below), \fI*dst\fR is unchanged. If \fI*dst\fR is zero-size, it is set to \fI*src\fR if \fI*src\fR is not also zero-size. The two procedures differ in that \fIGeoInclude\fR considers zero-area rectangles to be zero-size, while \fIGeoIncludeAll\fR only considers rectangles whose bottom is actually above their top or whose LHS is to the right of their RHS to be zero-size. .I GeoIncludePoint is like .I GeoInclude except \fI*src\fR is a Point instead of a Rect. .PP Three procedures are provided for clipping. .I GeoClip determines the portion of the Rect \fI*r\fR that overlaps the Rect \fI*cliparea\fR and replaces \fI*r\fR with the new Rect. If \fI*r\fR and \fI*cliparea\fR don't overlap at all, \fI*r\fR is turned inside out (\fIr_xbot\fR\ >\ \fIr_xtop\fR or \fIr_ybot\fR\ >\ \fIr_ytop\fR). .I GeoClipPoint moves the Point \fI*p\fR to the closest point on the boundary of the Rect \fI*cliparea\fR if it isn't already contained in \fI*cliparea\fR or on its border. Finally, .I GeoDisjoint is used to clip a Rect against another, but to apply a procedure to each region in \fI*area\fR that lies outside \fI*cliparea\fR, instead of modifying \fI*area\fR. The procedure \fI(*proc)()\fR it applies should be like the library procedure \fIGeoDummyFunc\fR, which accepts a Rect and the \fIcdata\fR argument passed to \fIGeoDisjoint\fR and returns TRUE always. If \fI(*proc)()\fR returns FALSE, \fIGeoDisjoint\fR aborts and returns FALSE itself; otherwise, it returns TRUE. .I GeoDisjoint works in ``tile'' space, so each rectangle is considered to contain its lower \fIx\fR- and \fIy\fR-coordinates, but not its upper coordinates. .PP The discussion earlier on transformation mentioned that transforming the two corner points of a Rect independently could result in a Rect whose lower left was above or to the right of its upper right. .I GeoCanonicalRect can remedy this situation; it flips the top and bottom or left and right (or both) of the Rect \fI*rsrc\fR as necessary to ensure that the upper right is above and to the right of the lower left, leaving the canonical Rect in \fI*rdst\fR. .PP Two procedures compute the relative positions of Points and Rects. .I GeoRectPointSide gives the side (\fIGEO_NORTH\fR, etc) of the Rect \fI*r\fR on which the Point \fI*p\fR lies (\fI*p\fR must lie on the boundary of \fI*r\fR; otherwise, \fIGEO_CENTER\fR is returned). Similarly, .I GeoRectRectSide gives the side of \fI*r1\fR on which \fI*r2\fR lies, or \fIGEO_CENTER\fR if they don't share any side. Unfortunately this procedure doesn't detect the case where the Rects share a coordinate without sharing a side (e.g, the LHS of one is equal to the RHS of the other, but they don't come even close in the vertical dimension). .PP A final procedure is provided for high-speed reading of ascii files containing descriptions of rectangles, \fIGetRect\fR. This procedure reads from a stdio-opened FILE \fI*f\fR, which should be positioned so that after skipping \fInskip\fR characters, it will be at the start of a line containing four ascii numbers that will be stored in \fIr->r_xbot\fR, \fIr->r_ybot\fR, \fIr->r_xtop\fR, and \fIr->r_ytop\fR. It returns TRUE if it successfully recognized a rectangle, FALSE on error or end-of-file. \fIGetRect\fR is considerably faster than either \fIfscanf\fR\|(3s) or even \fIfgets\fR\|(3s) followed by manual decoding of the line, because it reads data directly from the stdio buffer in its input file. As such, it depends on the structure of a FILE, and may fail to work properly on machines with wildly different implementations of the stdio library from the standard Berkeley distribution (those in which certain fields are nonexistent or renamed). .SH "MACROS FOR SPEED" If speed is essential, macros are defined in \fBgeofast.h\fR to take the place of the several procedures for special cases. .I GEOCLIP is identical to the procedure \fIGeoClip\fR, but it returns no value. Four macros for manipulating Transforms, \fIGEOTRANSRECT\fR, \fIGEOTRANSTRANS\fR, \fIGEOINVERTTRANS\fR, and \fIGEOTRANSTRANSLATE\fR, are similar to their procedural counterparts \fIGeoTransRect\fR, \fIGeoTransTrans\fR, \fIGeoInvertTrans\fR, and \fIGeoTransTranslate\fR, but only work with Transforms whose scale factor is unity (1). These macros are several times faster than their procedural counterparts; on a Sun-2 the speed difference is close to a factor of 10, but on other machines the difference is less extreme. .SH SEE ALSO magicutils\|(3) magic-8.0.210/doc/man/NOTUSED/ext2dlys.10000644000175000001440000001250710751423606015764 0ustar timusers.TH EXT2DLYS 1 .SH NAME ext2dlys \- create a SCALD wire-delays file from a tree of .ext files .SH SYNOPSIS .B ext2dlys [ .B \-d\ \fIpsPerPf\fR ] [ .B \-l\ \fIpsPerCentimicron\fR ] [ .B \-m\ \fIminmult\fR \fImaxmult\fR ] [ .B \-o\ \fIoutfile\fR ] [ .B \-t\ \fIcapscale\fR ] [ .B \-D\ \fIdrivefile\fR ] [ .B \-I\ \fIiload\fR ] [ .B \-L\ \fInetfile\fR ] [ .B \-M\ \fIscaldmapfile\fR ] [ .B \-O\ \fIoload\fR ] [ .I "extcheck-options" ] .I file .SH DESCRIPTION .I Ext2dlys is used to produce a SCALD wire-delays file (in \fIdlys\fR\|(5) format) on standard output, to be used in simulation and timing verification. It computes the wire delay information from capacitance in the circuit extracted from a layout by \fImagic\fR\|(1). .PP The filename \fIfile\fR given to \fIext2dlys\fR is the name of the root \fB.ext\fR file of the extracted circuit, and also of the \fB.net\fR file. The \fB.ext\fR files, in \fIext\fR\|(5) format, contain the capacitance to substrate for each electrical node, specify the connectivity of the circuit, and also give distance information. The \fB.net\fR file, in \fInet\fR\|(5) format, lists the nets and terminals in the circuit that will be present in the \fB.dlys\fR file. All terminals in the \fB.net\fR file are by default considered to be inputs (receivers) unless explicitly identified as drivers in the \fIdrivefile\fR given with the \fB\-D\fR option; see the description below. In addition to identifying the terminals of interest, the \fB.net\fR file gives the signal name associated with each net as a comment line immediately prior to the list of terminals in the net. .PP The remaining arguments to \fIext2dlys\fR tell how this capacitance and distance information is to be converted into delay, as well as specifying the use of alternate files: .TP \fB\-d\fI\ psPerPf\fR Used to turn capacitance into delay; one picofarad is equal to \fIpsPerPf\fR picoseconds of delay. The default value is \fB100.0\fR, or roughly what one would expect if using 100 ohm drivers. The value of \fIpsPerPf\fR is used only for drivers whose effective on resistance hasn't been given explicitly in the \fIdrivefile\fR specified with the \fB\-D\fR flag (see below). .TP \fB\-l\fI\ psPerCentimicron\fR Used to turn distance into delay; one centimicron of distance is equal to \fIpsPerCentimicron\fR picoseconds of delay. .TP \fB\-m\fI\ minmult\ maxmult\fR Multipliers to convert estimated delays into best-case (\fIminmult\fR) and worst-case (\fImaxmult\fR). Both are \fB1.0\fR by default. .TP \fB\-o\fI\ outfile\fR Write the output to \fIoutfile\fR (note that no suffix is implied) instead of to the standard output. .TP \fB\-t\fI\ capscale\fR Gives a scale factor by which units of capacitance in the \fB.sim\fR file will be multiplied in order to give femtofarads. \fICapscale\fR may be a real number; its default value is \fB1.0\fR. .TP \fB\-D\fI\ drivefile\fR Also used to turn capacitance into delay, but on a per-net basis. Each line of the file \fIdrivefile\fR consists of a hierarchical pin name (of an output driver) and its associated ``drive factor'' (equivalent to \fIdelay\fR in the \fB\-d\fR flag above), namely the number of picoseconds per picofarad for the net driven by that output pin. Nets driven by a pin listed not in this file use the default delay specified by \fB\-d\fR above. If this file isn't given, we don't know for certain which pins are the drivers in each net, so we arbitrarily pick one pin per net and assume it is the driver. .TP \fB\-I\fI\ iload\fR In addition to the capacitance reported in the \fB.sim\fR file for each net, add an additional \fIiload\fR attofarads of capacitance for each input on a given net to the total capacitance for that net. (Inputs are counted only if they appear in the \fB.net\fR file.) The default value of \fIiload\fR is \fB0.0\fR, since it varies so much from one technology to the next. This option is provided to account for extra transistor capacitance not computed by the extractor, such as when the technology of the circuit being extracted is non-MOS (e.g, bipolar). .TP \fB\-L\fI\ netfile\fR Instead of using \fIfile\fB.net\fR as the netlist file, use \fInetfile\fB.net\fR instead. .TP \fB\-M\fI scaldmap\fR If specified, then \fIscaldmap\fR is read (note no suffix implied) to obtain a translation between Magic terminal names and SCALD pin names. Each line in \fIscaldmap\fR contains a Magic name followed by a SCALD name. The Magic name is terminated by the first blank; the SCALD name continues from the next non-blank character to the end of the line, possibly including embedded blanks. When writing the output file, the corresponding SCALD name is used instead of the Magic name for each pin in a net. See \fIdlys\fR\|(5) for more details of the output file format. .TP \fB\-O\fI\ oload\fR In addition to the capacitance reported in the \fB.sim\fR file for each net, add an additional \fIoload\fR attofarads of capacitance for each output on a given net to the total capacitance for that net. The default value of \fIoload\fR is \fB0.0\fR. If only \fB\-I\fR and not \fB\-O\fR is specified, \fIext2dlys\fR treats this as though both \fB\-I\fR and \fB\-O\fR had been specified with the same values; inputs and outputs are not distinguished. .PP In addition, all of the options of \fIextcheck\fR\|(1) are accepted. .SH "SEE ALSO" extcheck\|(1), ext2sim\|(1), ext2spice\|(1), magic\|(1), dlys\|(5), ext\|(5) .SH AUTHOR Walter Scott magic-8.0.210/doc/man/NOTUSED/net2ir.10000644000175000001440000000163310751423606015407 0ustar timusers.TH NET2IR 1 .SH NAME net2ir \- produce :iroute commands to route a netlist composed of two-point nets .SH SYNOPSIS .B net2ir .I feedfile .I netfile .SH DESCRIPTION \fINet2ir\fR is used to produce commands for the Magic interactive hint router to route the collection of two-point nets specified in the \fInet\fR\|(5) file \fInetfile\fR, in the order in which they appear in the file. The label locations come from \fIfeedfile\fR, which should consist of a series of \fBbox\fR and \fBfeedback add\fR Magic commands, such as produced by the \fBfind\fR command (in a Magic netlist window). The text associated with each feedback command must be of the form \fIlayer\fB;\fIlabel\fR, where \fIlayer\fR is the Magic layer on which \fIlabel\fR lies. .PP The output of \fInet2ir\fR is a sequence of \fB:iroute route\fR commands, one for each net in the netlist file. .SH "SEE ALSO" magic\|(1), net\|(5) .SH AUTHOR Walter Scott magic-8.0.210/doc/man/NOTUSED/dqueue.30000644000175000001440000000603610751423606015500 0ustar timusers.TH DQUEUE 3 .UC 4 .SH NAME dqueue \- procedures for managing double-ended queues in libmagicutils.a .SH SYNOPSIS .nf .B #include "magic.h" .B #include "malloc.h" .B #include "dqueue.h" .PP .B DQInit(q, capacity) .B DQueue *q; .B int capacity; .PP .B DQFree(q) .B DQueue *q; .PP .B DQPushFront(q, elem) .B DQueue *q; .B ClientData elem; .PP .B DQPushRear(q, elem) .B DQueue *q; .B ClientData elem; .PP .B ClientData DQPopFront(q) .B DQueue *q; .PP .B ClientData DQPopRear(q) .B DQueue *q; .PP .B DQChangeSize(q, newSize) .B DQueue *q; .B int newSize .PP .B DQCopy(dst, src) .B DQueue *dst; .B DQueue *src; .PP .B bool DQIsEmpty(q) .B DQueue *q; .fi .SH DESCRIPTION These procedures manipulate double-ended queues. A double-ended queue (\fIDQueue\fR) is a structure to which single word elements of type \fIClientData\fR (actually type \fI(char *)\fR, but intended to mean ``any one-word type at all'') may be added to either end or removed from either end. Callers should not reference fields of a \fIDQueue\fR directly, but rather should use the following procedures: .PP .I DQInit initializes the DQueue \fIq\fR to have sufficient capacity to hold \fIcapacity\fR entries at first. If more than this many entries are pushed on the queue, it automatically doubles its size (at the cost of copying, however), so \fIcapacity\fR should be treated as the expected number of entries on the queue rather than the maximum number. .I DQFree frees the storage allocated by \fIDQinit\fR for the DQueue \fIq\fR. .PP .I DQPushFront and .I DQPushRear each place a new entry \fIelem\fR on the queue \fIq\fR; .I DQPushFront places it on the front of the queue, while .I DQPushRear places it on the rear. If the current maximum size of the queue would be exceeded by either operation, twice as much space is allocated automatically and the existing queue contents are copied to the bigger area. .I DQPopFront and .I DQPopRear remove an element from respectively the front or rear of the DQueue \fIq\fR and return it. If no elements are left, they return \fINULL\fR (zero). .PP Although \fIDQPushFront\fR and \fIDQPushRear\fR take care of increasing the space for a queue automatically, sometimes it is desirable to change the size of a queue explicitly. This can be done with \fIDQChangeSize\fR, which changes the size of the DQueue \fIq\fR to \fInewSize\fR, as long as \fInewSize\fR is at least as great as the number of entries already in the queue. If there are more than \fInewSize\fR entries in the queue, nothing happens. .PP One DQueue may be copied to another by \fIDQCopy\fR, which copies the DQueue \fIsrc\fR to the DQueue \fIdst\fR. .PP Finally, to check whether a queue \fIq\fR is empty, one may call \fIDQIsEmpty\fR, which returns \fBTRUE\fR (non-zero) if the queue is empty, or \fBFALSE\fR (zero) if it contains any elements. .SH BUGS Using \fBNULL\fR to indicate end-of-queue in \fIDQPopFront\fR and \fIDQPopRear\fR is of marginal usefulness. Callers should stick to using \fIDQIsEmpty\fR unless they are certain not to have pushed any zero elements on the queue. .SH SEE ALSO magicutils\|(3) magic-8.0.210/doc/man/NOTUSED/runstats.30000644000175000001440000000457210751423606016076 0ustar timusers.TH RUNSTATS 3 .UC 4 .SH NAME runstats \- keep track of process time and memory utilization (in libmagicutils.a) .SH SYNOPSIS .nf .B #include .B #include .B #include .B #include "runstats.h" .PP .B "char *RunStats(flags, lastt, deltat)" .B int flags; .B struct tms *lastt, *deltat; .PP .B "char *RunStatsRealTime()" .fi .SH DESCRIPTION .I RunStats collects information about a process's utilization of memory and CPU time. Depending on the flags provided, the following information is returned: .TP .B RS_TCUM cumulative user and system time .TP .B RS_TINCR the difference between the current cumulative user and system time and the values stored in the \fItms\fR struct pointed to by \fIlastt\fR. This struct is usually the one last passed to \fIRunStats\fR when it was last called with \fBRS_TINCR\fR as a flag. .TP .B RS_MEM the number of bytes by which the data segment has grown past its initial size. .PP \fIRunStats\fR returns a pointer to a statically allocated character string of the form ``\fB[\fR\...\ \fIstuff\fR\ ...\fB]\fR'', where \fIstuff\fR contains the information specified by the flags. Times are of the form \fImins\fR:\fIsecsu\ mins\fR:\fIsecss\fR, where the first time is the amount of user CPU time this process has used, and the second time is the amount of system time used. Memory is specified by a string of the form \fIN\fBk\fR, where \fIN\fR is the number of kilobytes by which the data segment has grown past its initial size. .PP If \fBRS_TINCR\fR is specified, the parameters \fIlastt\fR and \fIdeltat\fR are set if they are non-NULL. Both point to \fItms\fR structs; the one pointed to by \fIdeltat\fR is set to the difference between the current user/system time and the time given in the \fItms\fR struct pointed to by \fIlastt\fR; the one pointed to by \fIlastt\fR is then set to the current user/system time. .PP .I RunStatsRealTime reports the real time, both since the first invocation and incremental since the last invocation. It returns a statically allocated string of the form \fIx\fB:\fIxx\fB.\fIx\fR \fIx\fB:\fIxx\fB.\fIx\fR, where the first number is the amount of elapsed real time since the first call to \fIRunStatsRealTime\fR, and the second is the amount of elapsed real time since the latest call. .SH BUGS The interfaces to \fIRunStats\fR and \fIRunStatsRealTime\fR should really be consistent. .SH SEE ALSO magicutils\|(3) magic-8.0.210/doc/man/NOTUSED/list.30000644000175000001440000000305610751423606015162 0ustar timusers.TH List 3 .UC 4 .SH NAME list \- procedures for managing lisp style lists in libmagicutils.a .SH SYNOPSIS .nf .B #include "magic.h" .B #include "list.h" .PP .B "LIST_ADD(item,list)" .PP .B "LIST_FIRST(list)" .PP .B "LIST_TAIL(list)" .PP .B "bool ListContainsP(element, list)" .B "ClientData element;" .B "List *list;" .PP .B "Void ListDealloc(list)" .B "List *list;" .PP .B "Void ListDeallocC(list)" .B "List *list;" .PP .B "int ListLength(list)" .B "List *list;" .PP .B "ClientData ListPop(listPP)" .B "List **listPP;" .PP .B "List *ListReverse(list)" .B "List *list" .PP .SH DESCRIPTION These macros and procedures permit the implementation of linked lists of arbitrary things. The lists are lisp like, i.e., list pointers are in separate structures rather than in the strucs being linked. Macros are distinguished from procedues by names that are all upper-case. .PP .I LIST_ADD(i,l) adds an item to the front of a list. .PP .I LIST_COPY(l,lnew) creates a copy of a list .PP .I LIST_FIRST references the first item on the list. .PP .I LIST_TAIL(l) references the sublist consisting of all but the first item of the list. .PP .I ListContainsP returns \fBTRUE\fR in the specified item is contained in the list. .PP .I int ListLength returns the length of the list. .PP .I Void ListDealloc reclaims a list (but not its contents). .PP .I Void ListDeallocC reclaims a list /fIand/fR its contents. .PP .I ListPop deletes the first item from the list, and returns it (the item). .PP .I List *ListReverse creates and returns a reversed copy of a list. .SH SEE ALSO magicutils\|(3) magic-8.0.210/doc/man/NOTUSED/malloc.30000644000175000001440000001336210751423606015457 0ustar timusers.TH MALLOC 3 .UC 4 .SH NAME mallocMagic, freeMagic \- a new memory allocator in libmagicutils.a .SH SYNOPSIS .nf .B #include "magic.h" .B #include "malloc.h" .PP .B "char *mallocMagic(size)" .B unsigned size; .PP .B "char *callocMagic(size)" .B unsigned size; .PP \fBMALLOC(\fItype_decl\fB, var, size)\fR .B \fItype_decl\fB var; .B unsigned size; .PP \fBCALLOC(\fItype_decl\fB, var, size)\fR .B \fItype_decl\fB var; .B unsigned size; .PP .B "freeMagic(var)" .B char *var; .PP .B "FREE(var)" .B char *var; .PP .B "cc -DMALLOCTRACE ... ~cad/src/magic/lib/libmagictrace.a" .PP .B mallocTraceInit(filename) .B char *filename; .PP .B mallocTraceEnable() .PP .B mallocTraceDisable() .PP .B mallocTraceDone() .PP .B mallocTraceOnlyWatched(only) .B bool only; .PP .B bool mallocTraceWatch(addr) .B char *addr; .PP .B bool mallocTraceUnWatch(addr) .B char *addr; .SH DESCRIPTION These procedures implement a new memory allocator. They provide fast allocation and freeing for programs that allocate thousands or millions of objects of similar sizes. Speed results from maintaining separate free-lists for objects of each size, providing fast macros \fIMALLOC\fR and \fIFREE\fR for doing allocation and freeing, and clustering objects of the same size on the same page in an attempt to improve locality of reference. In addition, these procedures provide features to aid in the debugging of programs that do a lot of memory allocation and freeing; used in conjunction with \fIprleak\fR\|(8) they can detect storage leaks and also duplicate attempts to free the same storage location. .PP Memory is allocated using either the procedure \fImallocMagic\fR or the macro \fIMALLOC\fR. The former has an interface identical to that of the standard UNIX library procedure \fImalloc\fR\|(3), namely, it returns a pointer to a region of memory sufficiently large to hold \fIsize\fR bytes. The macro \fIMALLOC\fR is noticeably faster, particularly on machines with brain-dead procedure calls (such as a certain popular machine made by the second largest U.S. computer manufacturer). Its usage is a bit unusual, in that its first argument is a type specification and its second is modified in place. For example, to allocate an object of type \fIHashEntry *\fR that is 20 bytes long, and to assign this to the pointer \fIhe\fR, one could write: .sp .ti +1i \fBMALLOC(HashEntry *, he, 20);\fR .sp Note that there are no parentheses around the \fBHashEntry *\fR above. After executing this macro, \fIhe\fR would point to a \fIHashEntry\fR that was 20 bytes long. .PP The macro \fICALLOC\fR and the procedure \fIcallocMagic\fR perform function analagous to \fIMALLOC\fR and \fImallocMagic\fR except that the malloc'd memory is zeroed. .PP Memory can be freed using either the procedure \fIfreeMagic\fR, which frees its argument \fIvar\fR exactly as does the UNIX \fIfree\fR\|(3), or using the \fIFREE\fR macro, which does the same thing to \fIvar\fR but is faster. .PP Users of \fIMALLOC\fR and \fIFREE\fR should beware that they are macros that include C statements enclosed in a pair of braces (\fB{\ ...\ }\fR), and should be treated accordingly. For example, it is not legal to type: .sp .in +1i .nf .ta +1i \fBif (i != j) MALLOC(HashEntry *, he, i); else return (NULL);\fR .fi .in -1i One should instead use: .sp .in +1i .nf .ta +1i \fBif (i != j) { MALLOC(HashEntry *, he, i); } else return (NULL);\fR .fi .in -1i .PP If you wish to take advantage of the debugging features of this memory allocator, you must do two things. First, compile all of your \fB.c\fR files that #include ``malloc.h'' with the \fB-DMALLOCTRACE\fR flag. Second, when you link your program to build an \fIa.out\fR file, use the library \fB~cad/src/magic/lib/libmagictrace.a\fR instead of the normal \fBlibmagicutils.a\fR. The \fBlibmagictrace.a\fR library contains additional code to maintain the information needed by the debugging procedures below. If you link your program with the standard library, it will link successfully, but the debugging procedures won't do anything. .PP The debugging procedures produce a trace file for subsequent analysis by \fIprleak\fR\|(8). Before any memory is allocated, you should call \fImallocTraceInit\fR to create the trace file \fIname\fR. Tracing won't actually begin, however, until you call \fImallocTraceEnable\fR. From that point until \fImallocTraceDisable\fR, all calls to \fImallocMagic\fR or \fIfreeMagic\fR (or their corresponding macro versions \fIMALLOC\fR and \fIFREE\fR) will be logged to the trace file. Calls to \fImallocTraceDisable\fR and \fImallocTraceEnable\fR may be nested; only the outermost \fImallocTraceEnable\fR has any effect. .PP If more selective tracing is desired, you can specify that trace information is to be output only for certain addresses. Calling \fImallocTraceOnlyWatched\fR with \fIonly\fR equal to \fBTRUE\fR causes this to happen. An address \fIaddr\fR is added to the list of addresses to trace by calling \fImallocTraceWatch\fR, or removed from this list by calling \fImallocTraceUnWatch\fR. When \fImallocTraceOnlyWatched\fR is called with \fIonly\fR equal to \fBFALSE\fR, operation reverts to the normal mode of tracing all addresses. .PP When you are finished with all memory allocation tracing and want to flush all results out to the trace file, call \fImallocTraceDone\fR. Subsequent calls to the memory allocator will not be traced. .SH BUGS The \fIMALLOC\fR and \fIFREE\fR macros are syntactically clumsy, but unfortunately some C optimizers have trouble with syntactically cleaner forms. .sp The ability to trace specific addresses is only useful if you know which ones to watch. A more generally useful facility would probably be to watch certain sizes of objects, or to allow the user to supply a procedure that could determine whether or not an address was to be traced. .SH SEE ALSO magicutils\|(3) magic-8.0.210/doc/man/NOTUSED/sim2spice.10000644000175000001440000000405610751423606016104 0ustar timusers.TH SIM2SPICE 1 11/17/82 .UC .SH NAME sim2spice \- convert from .sim format to spice format .SH SYNOPSIS .B sim2spice [\-d defs] file.sim .SH DESCRIPTION .I Sim2spice reads a file in \fB.sim\fR format and creates a new file in spice format. The file contains just a list of transistors and capacitors, the user must add the transistor models and simulation information. The new file is appended with the tag \fB.spice\fR. One other file is created, which is a list of \fB.sim\fR node names and their corresponding spice node numbers. This file is tagged \fB.names\fR. .PP .I Defs is a file of definitions. A definition can be used to set up equivelences between \fB.sim\fR node names and spice node numbers. The form of this type of definition is: .RS \fBset \fIsim_name spice_number \fR[\fItech\fR] .RE The \fItech\fR field is optional. In NMOS, a special node, `BULK', is used to represent the substrate node. For CMOS, two special nodes, 'NMOS' and 'PMOS', represent the substrate nodes for the 'n' and 'p' transistors, repectively. For example, for NMOS the \fB.sim\fR node `GND' corresponds to spice node 0, `Vdd' corresponds to spice node 1, and `BULK' corresponds to spice node 2. The \fIdefs\fR file for this set up would look like this: .RS .nf set GND 0 nmos set Vdd 2 nmos set BULK 3 nmos .fi .RE A definition also allows you to set a correspondence between \fB.sim\fR transistor types and and spice transistor types. The form of this definition is: .RS \fBdef \fIsim_trans spice_trans \fR[\fItech\fR] .RE Again, the \fItech\fR field is optional. For NMOS these definitions would look as follows: .RS .nf def e ENMOS nmos def d DNMOS nmos .fi .RE Definitions may also be placed in the `.cadrc' file, but the definitions in the \fIdefs\fR file overrides those in the `.cadrc' file. .SH "SEE ALSO" ext2sim(1), magic(1), spice(1), cadrc(5), ext(5), sim(5) .SH AUTHOR Dan Fitzpatrick CMOS fixes by Neil Soiffer .SH BUGS The only pre-defined technologies are \fBnmos\fR, \fBcmos-pw\fR, and \fBcmos\fR (the same as \fBcmos-pw\fR). Only one definition file is allowed. magic-8.0.210/doc/man/NOTUSED/magicutils.30000644000175000001440000000437710751423606016357 0ustar timusers.TH MAGICUTILS 3 .UC 4 .SH NAME magicutils \- collection of utility procedures in -lmagicutils .SH SYNOPSIS .B cc .B -I\fI~cad\fB/src/magic/include ... .B \fI~cad\fB/src/magic/lib/libmagicutils.a .br .B cc .B -I\fI~cad\fB/src/magic/include ... .B \fI~cad\fB/src/magic/lib/libmagictrace.a .br .B cc .B -I\fI~cad\fB/src/magic/include .B -pg ... .B \fI~cad\fB/src/magic/lib/libmagicutils_p.a .br .B cc .B -I\fI~cad\fB/src/magic/include .B -pg ... .B \fI~cad\fB/src/magic/lib/libmagictrace_p.a .br \fR(replace \fI~cad\fR with the home directory of the user \fBcad\fR). .PP .B MainExit(code) .B int code; .PP .B TxError(fmt, va_alist) .B char *fmt; .B va_dcl; .PP .B char *TxGetLine(buf, len) .B char *buf; .B int len; .SH DESCRIPTION The two libraries \fIlibmagicutils.a\fR and \fIlibmagictrace.a\fR include all of the procedures from the \fIutils\fR module used internally by the Magic layout system. The first library is for normal use; the second library is for use with the tracing option of the new memory allocator. See the documentation on the individual pieces of the library for details of the procedures they contain. .PP To use these libraries, you should compile your programs with the flag \fB-I\fI~cad\fB/src/magic/include\fR (to search the Magic include directory for needed \fB.h\fR files). The documentation for the various pieces of the libraries lists which \fB.h\fR files are needed for which procedures. .PP Three default procedures are defined for the library but can be replaced by your own procedures if you so wish. The procedures are \fIMainExit\fR, which has the same semantics as \fIexit\fR\|(3) but can be replaced by your own procedure by that name to do additional cleanup, \fITxError\fR, which is like \fIfprintf(stderr,\ fmt,\ args)\fR, where \fIargs\fR can be zero or more arguments, just as in \fIfprintf\fR\|(3), and finally \fITxGetLine\fR, which is like \fIfgets(buf,\ len,\ stdin\fR). The library versions of these procedures only get pulled in if you haven't defined them yourself. .PP Versions exist of both libraries with profiling (\fB-pg\fR) enabled; these are \fIlibmagicutils_p.a\fR and \fIlibmagictrace_p.a\fR. .SH "SEE ALSO" magic(1), dqueue(3), geometry(3), hash(3), heap(3), list(3), malloc(3), path(3), runstats(3), set(3) show(3) stack(3), string(3) magic-8.0.210/doc/man/NOTUSED/prleak.80000644000175000001440000000475210751423606015476 0ustar timusers.\" sccsid @(#)prleak.8 4.1 MAGIC (Berkeley) 11/29/85 .\" .\" CONVENTIONS: .\" italics: things that are substituted for .\" boldface: characters that are typed as-is .\" .\" EXAMPLE: \fIfilename\fB.mag\fR .\" or: \fBcif \fR[\fIfile\fR] .\" .TH PRLEAK 8 .SH NAME prleak \- aid for debugging programs using malloc/free .SH SYNOPSIS prleak [ .B \-a ] [ .B \-d ] [ .B \-l ] [ .I objfile [ .I tracefile ] ] .SH DESCRIPTION .I Prleak is a tool for use in debugging programs that make use of Magic's versions of \fImalloc\fR and \fIfree\fR. It examines the trace file produced by special versions of .I malloc and .I free produced when they are compiled with the \fB\-DMALLOCTRACE\fR flag. The output of prleak is the average allocation size, a list of `leaky' allocations (blocks still allocated at program exit) if \fB\-l\fR is specified, a list of duplicate frees (blocks that the program attempted to free after they had already been deallocated) if \fB\-d\fR is specified, and a list of all calls to malloc and free if \fB\-a\fR is specified. If no switches are given, the default action is as though \fB\-l\fR and \fB\-d\fR were in effect. .PP For each entry output, both the address of the allocated block and a stack backtrace at the time of the call to .I malloc or .I free are printed. .I Prleak attempts to use the namelist from .I objfile (\fBa.out\fR if no file is given) to produce a symbolic backtrace. If no namelist can be found, the backtrace is printed in hex. If .I tracefile is specified, the malloc trace is read from it; otherwise, it is read from the file \fBmalloc.out\fR in the current directory. .PP An example output might be as follows: .DS L .sp .nf \fBAverage allocation size = 12 bytes\fR \fB------\fR \fBLeaks:\fR \fB------\fR \fB0x11540 [11 bytes]\fR \fBat _foo+0x14\fR \fBcalled from ~main+026\fR \fB0x11556 [14 bytes]\fR \fBat _bar+0x50\fR \fBcalled from _foo+0x36\fR \fBcalled from ~main+0x26\fR \fB--------- ------\fR \fBDuplicate frees:\fR \fB--------- ------\fR \fB0x11556 \fR \fBat _bar+0x40\fR \fBcalled from _foo+0x36\fR \fBcalled from ~main+0x26\fR .fi .DE .SH FILES malloc.out .SH "SEE ALSO" \fIACM SIGPLAN Notices\fR, Vol 17, No 5 (May 1982), the article by Barach and Taenzer. .SH AUTHOR Walter Scott .SH BUGS Local symbols (beginning with ``~'') in the backtrace output should be tagged with the source file to which they refer. magic-8.0.210/doc/man/NOTUSED/heap.30000644000175000001440000000644710751423606015133 0ustar timusers.TH HEAP 3 .UC 4 .SH NAME heap \- procedures for managing sorted heaps in libmagicutils.a .SH SYNOPSIS .nf .B #include "magic.h" .B #include "heap.h" .PP .B "typedef struct { int he_key, char *he_id; } HeapEntry;" .PP .B bool HEAP_EMPTY(h) .B Heap *h; .PP .B "HeapInit(h, initsize, descending, stringids)" .B Heap *h; .B int initsize; .B bool descending, stringids; .PP .B "HeapKill(h, func)" .B Heap *h; .B int (*func)(h, index); .PP .B "HeapFreeIdFunc(h, index)" .B Heap *h; .B int index; .PP .B "HeapEntry *HeapRemoveTop(h, entry);" .B Heap *h; .B HeapEntry *entry; .PP .B "HeapAdd(h, key, id)" .B Heap *h; .B int key; .B char *id; .fi .SH DESCRIPTION These procedures create, manipulate, and destroy heaps. A heap is essentially an array that automatically sorts itself when items are added to it. The items added to the heap consist of an integer key and a one-word datum which can either be the address of a NULL-terminated string (treated specially), or any other one-word data item. Heaps can be sorted in either ascending or descending order. The data storage for a heap automatically grows as more elements are added to the heap. .PP The \fIHeapEntry\fR structure identifies the integer key value (\fIhe_key\fR) on which the element is sorted, and a one-word datum (\fIhe_id\fR). Heaps are created by \fIHeapInit\fR, which initializes the data storage for \fIh\fR. Enough space is left initially for \fIinitsize\fR elements, although the heap will grow automatically as more elements are added. If \fIdescending\fR is \fBTRUE\fR, the largest element in the heap will be removed first; otherwise, the smallest element will be the first to be removed by \fIHeapRemoveTop\fR. Each heap entry has an associated datum or \fIid\fR; if \fIstringids\fR is TRUE, these are considered to be ASCII strings and handled specially by \fIHeapAdd\fR and \fIHeapKill\fR. .PP .I HeapKill deallocates the storage associated with a heap. If \fIfunc\fR is non-NULL, it is applied to each element in the heap. A common use of \fIfunc\fR is to free the storage associated with string ids in the heap, such as is necessary when the heap was created with \fIstringids\fR set to \fBTRUE\fR in the call to \fIHeapInit\fR above. A library function, \fIHeapFreeIdFunc\fR, is provided for this purpose. .PP .I HeapRemoveTop places the top element from \fIh\fR in the \fIHeapEntry\fR pointed to by \fIentry\fR and returns \fIentry\fR. However, if the heap was empty, \fIHeapRemoveTop\fR returns NULL. .I HeapRemoveTop always removes the smallest (if keys are ascending) or largest (if keys are descending) element from the heap. .PP .I HeapAdd is used to add a new entry to \fIh\fR. The new entry has an integer key of \fIkey\fR, and a value of \fIid\fR. If the heap was created with \fIstringids\fR to be \fBTRUE\fR in \fIHeapInit\fR, then \fIid\fR is interpreted as a NULL-terminated ASCII string; sufficient additional memory to hold this string is allocated, the string is copied into this new memory, and a pointer to this new memory is stored with the heap entry. Otherwise, the value of \fIid\fR is just stored directly in the heap entry. .SH BUGS The management of the \fIhe_id\fR field should be consistent with the management of keys for hash tables, i.e, multi-word structures should be supported along with strings and single-word values. .SH SEE ALSO magicutils\|(3) magic-8.0.210/doc/man/NOTUSED/magicusage.10000644000175000001440000000335210751423606016311 0ustar timusers.\" sccsid @(#)magicusage.1 4.1 MAGIC (Berkeley) 11/29/85 .\" .\" CONVENTIONS: .\" italics: things that are substituted for .\" boldface: characters that are typed as-is .\" .\" EXAMPLE: \fIfilename\fB.mag\fR .\" or: \fBcif \fR[\fIfile\fR] .\" .TH MAGICUSAGE 1 .UC 4 .SH NAME magicusage \- print the names of all cells and files used in a Magic design .SH SYNOPSIS .B magicusage [ .B \-T .I technology ] [ .B \-p .I path ] .I rootcell .SH DESCRIPTION Magicusage will print the names of all cells and files used in the design whose root cell is .IR rootcell . Each line of the output is of the form .sp .ti +8 \fIcellname\fR \fB:::\fR \fIfilename\fR .sp where .I cellname is the name of the cell as it is used, and .I filename is the \fB.mag\fP file containing the cell. If a cell is not found, a line of the form .sp .ti +8 \fIcellname\fR \fB:::\fR \fB<< not found >>\fR .sp is output instead. .PP If \fB\-p\fI\ path\fR is specified, the search path used to find \fB.mag\fR files will be \fIpath\fR. Otherwise, the search path is initialized by first reading the system-wide .magic file in ~cad/lib/magic/sys, then the .magic file in the user's home directory, and finally the .magic file in the current directory. The most recent .B path command read from the three files determines the search path used to find cells. .PP In addition, a library path of ~cad/lib/magic/\fItechname\fP is used when searching for cells. By default, \fItechname\fP is the technology of the first cell read, but it may be overridden by specifying an explicit technology with the \fB\-T\fI\ techname\fR flag. .SH "FILES" .PP .ta 5c ~cad/lib/magic/\fItech\fR .br ~cad/lib/magic/sys/.magic .br ~/.magic .br \.magic .SH "SEE ALSO" magic\|(1), magic\|(5) .SH AUTHOR Walter Scott magic-8.0.210/doc/man/NOTUSED/show.30000644000175000001440000000061710751423606015167 0ustar timusers.TH SHOW 3 .UC 4 .SH NAME show \- procedure for displaying rects as feedback, for debugging. printing their values. .SH SYNOPSIS .nf .PP .B "Void ShowRect(def, r, style)" .B "CellDef *def;" .B "Rect *r;" .B "int style;" .SH DESCRIPTION Highlights the specified area in the specified cell and the specified style. See the Magic \fIgarouter\fR module for example uses. .SH SEE ALSO magicutils\|(3) magic-8.0.210/doc/man/NOTUSED/set.30000644000175000001440000000156010751423606015000 0ustar timusers.TH SET 3 .UC 4 .SH NAME set \- procedures for setting parameters (from strings) and for printing their values. .SH SYNOPSIS .nf .PP .B "Void SetNoisyInt(parm,valueS,file)" .B "int *parm;" .B "char *valueS;" .B "FILE *file;" .PP .B "Void SetNoisyBool(parm,valueS,file)" .B "bool *parm;" .B "char *valueS;" .B "FILE *file;" .PP .B "Void SetNoisyDI(parm,valueS,file)" .B "DoubleInt *parm;" .B "char *valueS;" .B "FILE *file;" .SH DESCRIPTION These procedures interpet a string and set a parameter accordingly. Error messages are printed if the string doesn't make sense, and in any event the final parameter value is printed. If \fIvalueS\fR is \fBNULL\fR, the parameter value is not changed. If \fIfile\fR is \fBNULL\fR the result is printed with \fITxPrintf\fR, Magic's standard print function, otherwise it is printed on the specified file. .SH SEE ALSO magicutils\|(3) magic-8.0.210/doc/man/NOTUSED/string.30000644000175000001440000001075010751423606015514 0ustar timusers.TH STRING 3 .UC 4 .SH NAME string \- procedures for manipulating strings in libmagicutils.a .SH SYNOPSIS .nf .B #include "magic.h" .B #include "utils.h" .PP .B "typedef struct { char *d_str; } LookupTable;" .PP .B "int Lookup(str, table)" .B char *str; .B char *table[]; .PP .B "int LookupStruct(str, table, size)" .B char *str; .B LookupTable *table; .B int size; .PP .B "int LookupAny(c, table)" .B char c; .B char *table[]; .PP .B "int LookupFull(name, table)" .B char *name; .B char *table[]; .PP .B "char *StrDup(oldstr, str)" .B char **oldstr, *str; .PP .B bool StrIsWhite(str, commentok) .B char *str; .B bool commentok; .PP .B bool StrIsInt(str) .B char *str; .PP .B bool Match(pattern, string) .B char *pattern, *string; .PP .B "char *ArgStr(pargc, pargv, argType)" .B int *pargc; .B char ***pargv; .B char *argType; .SH DESCRIPTION This collection of procedures provide a number of useful functions for dealing with strings. .I Lookup searches a table of strings to find one that matches a given string. It's useful mostly for command lookup. The table of strings should be terminated with a NULL string pointer, and the entries should be alphabetical and all lower-case. Any characters following the first white space in an entry are ignored. If \fIstr\fR is an unambiguous abbreviation for one of the entries in \fItable\fR, then the index of the matching entry is returned. If \fIstr\fR is an abbreviation for more than one entry in table, then -1 is returned. If \fIstr\fR doesn't match any entry, then -2 is returned. Case differences are ignored. .PP .I LookupStruct is a more general version of \fILookup\fR for dealing with tables of structures whose first word is a string pointer. The \fItable\fR argument should be a pointer to an array of such structures, cast as type \fI(LookupTable *)\fR. The table should be terminated with an entry whose string pointer is NULL. As in \fILookup\fR, all entries should contain lower-case strings and should be sorted alphabetically. The \fIsize\fR parameter gives the size in bytes of each structure in the table. .PP .I LookupAny looks up a single character in a table of pointers to strings. The last entry in the string table must be a NULL pointer. The index of the first string in the table containing the indicated character is returned, or -1 if no matching string is found. .PP .I LookupFull is like \fILookup\fR, but does not allow abbreviations. It either returns the index of the entry of \fItable\fR matching \fIstr\fR, or -1 if no match is found. Case is significant, and entries are considered to extend all the way to their trailing NULL byte, instead of being terminated by the first white space as in \fILookup\fR. .PP .I StrDup can be used to replace an old string with a new one, freeing the storage for the old one and allocating sufficient storage for the new one. It returns a pointer to a newly allocated character array just large enough to hold \fIstr\fR and its trailing NULL byte. This newly allocated array contains a copy of \fIstr\fR. However, if \fIstr\fR is NULL, no memory is allocated and we return NULL. If \fIoldstr\fR is non-NULL, then if \fI*oldstr\fR is non-NULL, \fIStrDup\fR frees the storage pointed to by \fI*oldstr\fR. \fIStrDup\fR then sets \fI*oldstr\fR to point to the new array of memory just allocated, or NULL if \fIstr\fR was NULL. .PP .I StrIsWhite returns TRUE if \fIstr\fR is all white space, or FALSE otherwise. If \fIcommentok\fR is TRUE, then if the first non-white character in \fIstr\fR is a pound-sign (``\fB#\fR''), \fIstr\fR is considered to be all white space. .PP .I StrIsInt returns TRUE if \fIstr\fR is a well-formed decimal integer, or FALSE if it isn't. .PP .I Match provides a \fIcsh\fR\|(1)-like wild-card matching facility. The string \fIpattern\fR may contain any of the \fIcsh\fR wildcard characters: \fB*\fR, \fB?\fR, \fB\\\fR, \fB[\fR, and \fB]\fR. If \fIpattern\fR matches \fIstring\fR, \fIMatch\fR returns TRUE; otherwise, it returns FALSE. .PP .I ArgStr is provided to allow standard processing of command-line arguments that take parameters. It recognizes flag-value pairs of either the form ``\fB\-\fIXvalue\fR'' (a single argument string) or ``\fB\-\fIX\ value\fR'' (two successive argument strings) in the argument list (\fI*pargc,\ *pargv\fR), incrementing \fI*pargc\fR and \fI*pargv\fR by an amount sufficient to step over the flag-value pair. If there are no more arguments remaining in the list, .I ArgStr prints an error message complaining that \fIargType\fR is required for the flag \fI*pargv[0]\fR. .SH SEE ALSO magicutils\|(3) magic-8.0.210/doc/man/NOTUSED/mpack.30000644000175000001440000003452610751423606015310 0ustar timusers. . sccsid "@(#)mpack.3 4.1 MAGIC (Berkeley) 11/29/85"; . .TH MPACK 3 2/20/85 .UC .SH NAME mpack \- routines for generating semi-regular modules .SH DESCRIPTION \fBMpack\fR is a library of `C' routines that aid the process of generating semi-regular modules. Decoder planes, barrel shifters, and PLAs are common examples of semi-regular modules. .PP Using Magic, an mpack user will draw an example of a finished module and then break it into tiles. These tiles represent the building blocks for more complicated instances of the module. The mpack library provides routines to aid in assembling tiles into a finished module. .SH MAKING AN EXAMPLE MODULE .PP The first step in using mpack is to create an example instance of the module, called a \fItemplate\fR. The basic building blocks of the structure, or \fItiles\fR, are then chosen. Each tile should be given a name by means of a rectangular label which defines its contents. If the tiles in the module do not abut (e.g. they overlap) it is useful to define another tile whose size indicates how far apart the tiles should be placed. .PP Templates should be in Magic format and, by convention, end with a \fB.mag\fR suffix. With some programs, it is possible to generate the same structure in a different technology or style by changing just the template. If this is the case, each template should have a filename of the .br form \fRbasename\fB-\fIstyle\fB.mag\fR. The \fIstyle\fR part of the filename interacts with the \fB-s\fR option (see later part of this manual). .SH WRITING AN MPACK PROGRAM .PP An mpack program is the `C' code which assembles tiles into the desired module. Typically this program reads a file (such as a truth table) and then calls the tile placement routines in the mpack library. .PP The mpack program must first include the file \fB~cad/lib/mpack.h\fR which defines the interface to the mpack system. Next the \fBTPinitialize\fR procedure is called. This procedure processes command line arguments, opens an input file as the standard input (\fBstdin\fR), and loads in a template. .PP The program should now read from the standard input and compute where to place the next tile. Tiles may be aligned with previously placed tiles or placed at absolute coordinates. If a tile is to overlap an existing tile the program must space over the distance of the overlap before placing the tile. .PP When all tiles are placed the program should call the routine \fBTPwrite_tile\fR to create the output file that was specified on the command line. .PP To use the mpack library be sure to include it with your compile or load command (e.g. \fBcc \fIyour_file\fB ~cad/lib/mpack.lib\fR). .SH ROUTINES .sp .LP Initialization and Output Routines .RS .sp \fBTPinitialize(\fIargc, argv, base_name\fB)\fR .RS The mpack system is initialized, command line arguments are processed, and a template is loaded. The file descriptor \fBstdin\fR is attached to the input file specified on the command line. The template's filename is formed by taking the \fIbase_name\fR, adding any extension indicated by the \fB-s\fR option, and then adding the \fB.mag\fR suffix. The \fB-t\fR option allows the user to override \fIbase_name\fR from the command line. .PP \fIArgc\fR and \fIargv\fR should contain the command line arguments. \fIArgc\fR is a count of the number of arguments, while \fIargv\fR is an array of pointers to strings. Strings of length zero are ignored (as is the flag consisting of a single space), in order to make it easy for the calling program to intercept its own arguments. \fIArgc\fR and \fIargv\fR are of the same structure as the two parameters passed to the main program. A later section of this manual summarizes the command line options. .RE .sp \fBTPload_tiles(\fIfile_name\fB)\fR .RS The given \fIfile_name\fR is read, and each rectangular label found in the file becomes a tile accessible via TPname_to_tile. No extensions are added to \fIfile_name\fR. .RE .sp \fBTILE TPread_tile(\fIfile_name\fB)\fR .RS A tile is created and \fIfile_name\fR is read into it. The tile is returned as the value of the function. .RE .sp \fBTPwrite_tile(\fItile, filename\fB)\fR .RS The tile \fItile\fR is written to the file specified by \fIfilename\fR, with \fB.ca\fR or \fB.cif\fR extensions added. See the description of the \fB-o\fR option for information on what file name is chosen if \fIfilename\fR is the null string. The choice between Magic or CIF format is chosen with the \fB-a\fR or \fB-c\fR command line options. .RE .sp .RE .LP Tile creation, deletion, and access .sp .RS \fBTPdelete_tile(\fItile\fB)\fI .RS The tile \fItile\fR is deleted from the database and the space occupied by it is reused. .RE .sp \fBTILE TPcreate_tile(\fIname\fB)\fI .RS A new, empty tile is created and given the name \fIname\fR. This name is used by the routine \fBTPname_to_tile\fR and in error messages. The type \fBTILE\fR returned is a unique ID for the tile, not the tile itself. Currently this is implemented by defining the type TILE to be a pointer to the internal database representation of the tile. .RE .sp \fBint TPtile_exists(\fIname\fB)\fR .RS TRUE (1) is returned if a tile with the given \fIname\fR exists (such as in the template or from a call to TPcreate_tile). .RE .sp \fBTILE TPname_to_tile(\fIname\fB)\fR .RS A value of type \fBTILE\fR is returned. This value is a unique ID for the tile that has the name \fIname\fR. This name comes from a call to TPcreate_tile(), or from the rectangular label that defined it in a template that was read in by TPread_tiles() or TPinitialize(). If the tile does not exist then a value of NULL is returned and an error message is printed. .RE .sp \fBRECTANGLE TPsize_of_tile(\fItile\fB)\fR .RS A rectangle is returned that is the same size as the tile \fItile\fR. The rectangle's lower left corner is located at the coordinate (0, 0). All coordinates in mpack are specified in half-lambda. .RE .sp .RE .LP Painting and Placement Routines .sp .RS \fBRECTANGLE TPpaint_tile(\fIfrom_tile, to_tile, ll_corner\fB)\fR .RS The tile \fIfrom_tile\fR is painted into the tile \fIto_tile\fR such that its lower left corner is placed at the point \fIll_corner\fR in the tile \fIto_tile\fR . The location of the newly painted area in the output tile is returned as a value of type RECTANGLE. The tile \fIto_tile\fR is often an empty tile made by \fBTPcreate_tile()\fR. The point \fIll_corner\fR is almost never provided directly, it is usually generated by routines such as \fBalign()\fR. .RE .sp \fBTPdisp_tile(\fIfrom_tile, ll_corner\fB)\fR .RS A rectangle the size of \fIfrom_tile\fR with the lower left corner located at \fIll_corner\fR is returned. Note that this routine behaves exactly like the routine TPpaint_tile except that no output tile is modified. This routine, in conjunction with the \fBalign\fR routine, is useful for controlling the overlap of tiles. .RE .sp \fBRECTANGLE TPpaint_cell(\fIfrom_tile, to_tile, ll_corner\fB)\fR .RS This routine behaves like \fBTPpaint_tile()\fR except that the \fIfrom_tile\fR is placed as a subcell rather than painted into place. The tile \fIfrom_tile\fR must exist in the file system (i.e. it must have been read in from disk or have been written out to disk). .RE .sp .RE .LP Label Manipulation Routines .sp .RS \fBTPplace_label(\fItile, rect, label_name\fB)\fR .RS A label named \fIlabel_name\fR is place in the tile \fItile\fR. The size and location of the label is the given by the RECTANGLE \fIrect\fR. .RE .sp \fBint TPfind_label(\fItile, &rect1, str, &rect2\fB)\fR .RS The tile \fItile\fR is searched for a label of name \fIstr\fR. The location of the first such label found is returned in the rectangle \fIrect2\fR. The function returns 1 if such a label was found, and 0 otherwise. The rectangle pointer \fI&rect1\fR, if non-NULL, restricts the search to an area of the tile. .RE .sp \fBTPstrip_labels(\fItile, ch\fB)\fR .RS All labels in the tile \fItile\fR that begin with the character \fIch\fR are deleted. .RE .sp \fBTPremove_labels(\fItile, name, r\fB)\fR .RS All labels in the tile \fItile\fR that are completely within the area \fIr\fR are deleted. If \fIname\fR is non-NULL, then only labels with that name will be affected. .RE .sp \fBTPstretch_tile(\fItile, str, num\fB)\fR .RS The string \fIstr\fR is the name of one or more labels within the tile \fItile\fR. Each of these labels must be of zero width or zero height, i.e. they must be lines. Each of these lines define a line across which the tile will be stretched. The amount of the stretch is specified by \fInum\fR in units of \fBhalf\fR-lambda. Stretching such a line turns it into a rectangle. Note that if the tile contains 2 lines that are co-linear, the stretching of one of them will turn both into rectangles. .RE .sp .RE .LP Point-Valued Routines .RS .sp \fBPOINT tLL(\fItile\fB)\fR .br \fBPOINT tLR(\fItile\fB)\fR .br \fBPOINT tUL(\fItile\fB)\fR .br \fBPOINT tUR(\fItile\fB)\fR .RS The location of the specified corner of tile \fItile\fR, relative to the tile's lower left corner, is returned as a point. LL stands for lower-left, LR for lower-right, UL for upper-left, and UR for upper-right. Note that \fBtLL()\fR returns (0, 0). .RE .sp \fBPOINT rLL(\fIrect\fB)\fR .br \fBPOINT rLR(\fIrect\fB)\fR .br \fBPOINT rUL(\fIrect\fB)\fR .br \fBPOINT rUR(\fIrect\fB)\fR .RS The location of the specified corner of the rectangle \fIrect\fR is returned as a point. LL stands for lower-left, LR for lower-right, UL for upper-left, and UR for upper-right. .RE .sp \fBPOINT align(\fIp1, p2\fB)\fR .RS A point is computed such that when added to the point \fIp2\fR gives the point \fIp1\fR. \fIp1\fR is normally a corner of a rectangle within a tile and \fIp2\fR is normally a corner of a tile. In this case the point computed can be treated as the location for the placement of the tile. .PP For example, TPpaint_tile(outtile, fromtile, align(rUL(rect), tLL(fromtile))) will paint the tile \fIfromtile\fR into \fIouttile\fR such that the lower left corner of \fIfromtile\fR is aligned with the upper-left corner of \fIrect\fR. In this example \fIrect\fR would probably be something returned from a previous TPpaint_tile() call. .RE .sp .RE .LP Point and Rectangle Addition Routines .RS .sp \fBPOINT TPadd_pp(\fIp1, p2\fB)\fR .br \fBPOINT TPsub_pp(\fIp1, p2\fB)\fR .RS The points \fIp1\fR and \fIp2\fR are added or subtracted, and the result is returned as a point. In the subtract case \fIp2\fR is subtracted from \fIp1\fR. .RE .sp \fBRECTANGLE TPadd_rp(\fIr1, p1\fB)\fR .br \fBRECTANGLE TPsub_rp(\fIr1, p1\fB)\fR .RS The rectangle \fIr1\fR has the point \fIp1\fR added or subtracted from it. This has the effect of displacing the rectangle in the X and/or Y dimensions. .RE .sp .RE .LP Miscellaneous Functions .RS .sp \fBint TPget_lambda()\fR .RS This function returns the current value of lambda in centi-microns. .RE .sp .RE .SH INTERFACE DATA STRUCTURES .PP In those cases where tiles must be placed using absolute, (half-lambda) coordinates, it is useful to know that \fBRECTANGLE\fRs and \fBPOINT\fRs are defined as: .RS .nf typedef struct { int x_left, x_right, y_top, y_bot; } RECTANGLE; typedef struct { int x, y; } POINT; .fi .RE The variable \fBorigin_point\fR is predefined to be (0, 0). \fBorigin_rect\fR is defined to be a zero-sized rectangle located at the origin. .SH OPTIONS ACCEPTED BY \fBTPinitialize()\fI .LP Typical command line: \fIprogram_name\fR [-t \fItemplate\fR] [-s \fIstyle\fR] [-o \fIoutput_file\fR] \fIinput_file\fR .IP \fB-a\fR produce Magic format (this is the default) .IP \fB-c\fR produce CIF format .IP \fB-v\fR be verbose (sequentially label the tiles in the output for debugging purposes; also print out information about the number of rectangles processed by mpack) .IP \fB-s\fI\ style\fR generate output using the template for this style (see TPinitialize for details) .IP \fB-o\fR The next argument is taken to be the base name of the output file. The default is the input file name with any extensions removed. If there is not input file specified and no -o option specified, the output will go to \fBstdout\fR. .IP \fB-p\fR (pipe mode) Send the output to \fBstdout\fR. .IP \fB-t\fR The next argument specifies the template base name to use. This overrides the default supplied by the program. A \fB.mag\fR extension is automatically added. (see TPinitialize) .IP \fB-l\fI\ name\fR Set the cif output style to \fIname\fR. \fIname\fR is the name of a cif output style as defined in Magic's technology file. If this option is not specified then the first output style in the technology file is used. (Note: In the old tpack system this option set the size of lambda.) .IP \fIinput_file\fR The name of the file that the program should read from (such as a truth table file). If this filename is omitted then the input is taken from the standard input (such as a pipe). .IP \fB-M\fI\ num\fR This option is accepted by mpack, but ignored. It is a leftover from the tpack system. .IP \fB-D\fI\ num1\ num2\fR The \fIDemo\fR or \fIDebug\fR option. This option will cause \fBmpack\fR to place only the first \fInum1\fR tiles, and the last \fInum2\fR of those will be outlined with rectangular labels. In addition, if a tile called "blotch" is defined then a copy of it will be placed in the output tile upon each call to the \fIalign\fR function during the placing of the last \fInum2\fR tiles. The blotch tile will be centered on the first point passed to \fIalign\fR, and usually consists of a small blotch of brightly colored paint. This has the effect of marking the alignment points of tiles. The last tile painted into is assumed to be the output tile. .SH EXAMPLE It is highly recommended that the example in \fB~cad/src/mquilt\fR be examined. Look at both the template and the `C' code. A more complex example is in \fB~cad/src/mpla\fR. .SH FILES .nf \~cad/lib/mpack.h (definition of the mpack interface) \~cad/lib/mpack.lib (linkable mpack library) \~cad/lib/mpack.ln (lint-library for lint) \~cad/src/mquilt/* (an example of an mpack program) \~cad/lib/magic/sys/*.tech* (technology description files) .fi .SH ALSO SEE magic(CAD), mquilt(CAD), mpla(CAD) .br Robert N. Mayo .I Pictures with Parentheses: Combining Graphics and Procedures in a VLSI Layout Tool, .R Proceedings of the 20th Design Automation Conference, June, 1983. .br \`C' Manual .SH HISTORY This is a port of the tpack(1) system which generated Caesar files. .SH AUTHOR Robert N. Mayo .SH BUGS When a tile contains part of a subcell, or touches a subcell, then the whole subcell is considered to be part of the tile. The same goes for arrays of subcells. magic-8.0.210/doc/man/NOTUSED/grsunprog.10000644000175000001440000000512010751423606016225 0ustar timusers.\" sccsid @(#)grsunprog.1 4.1 MAGIC (Berkeley) 11/29/85 .\" .\" CONVENTIONS: .\" italics: things that are substituted for .\" boldface: characters that are typed as-is .\" .\" EXAMPLE: \fIfilename\fB.mag\fR .\" or: \fBcif \fR[\fIfile\fR] .\" .TH GRSUNPROG 1 .UC 4 .SH NAME grSunProg \- internal process for Magic's Sun 120 display driver .SH SYNOPSIS \fBgrSunProg \fIcolorWindowName textWindowName notifyPID requestFD pointFD buttonFD\fR .SH DESCRIPTION .PP GrSunProg is an internal program used by Magic when using the Sun 120 workstation's display. This manual page is intended only for Magic maintainers. .PP GrSunProg collects button pushes from the color window and sends them over a pipe to Magic. The program also responds to requests from Magic for the mouse position. In addition, this program tells Suntools to forward characters typed in the color window directly to Magic's text window. .SH ARGUMENTS .PP All six arguments are required: .RS .TP .I colorWindowName This is the name of the color window that magic is running under (such as \fB/dev/win3\fR). Magic normally opens up the color monitor with a single, large, window on it. .TP .I textWindowName This is the name of the text window that contains Magic's command log. Keyboard events are forwarded to this window. .TP .I notifyPID If this processID is not 0, then SIGIO signals are sent to this process when there is data for it. .TP .I requestFD pointFD buttonFD These are the file descriptors that grSunProg should use in its interface (see below). They are small integers printed as strings. .RE .SH INTERFACE .PP Button pushes are sent out over file descriptor \fIbuttonFD\fR. A button push is encoded as two characters followed by two integers giving the location of the button push. The first character is either 'L', 'M', or 'R' depending on the button pushed: Left, Middle, or Right. The next character is either 'D' or 'U' depending on the action: Up or Down. The two numbers are the X and Y coordinates of the button push. This string is followed by a newline. Example: \fBLD 123 342\fR means that the left button was pushed down at location (123, 342). .PP GrSunProg sometimes receives a character from Magic over file descriptor \fIrequestFD\fR. If this character is an EOF, then the program terminates. If this character is an 'A', then grSunProg responds with a 'P' and the current mouse coordinates over file descriptor \fIpointFD\fR. This string is followed by a newline. Example: \fBP 101 23\fR means that the mouse is currently at location (101, 23). .SH "SEE ALSO" magic(1) grsunprog2(1) .SH AUTHOR Robert N. Mayo magic-8.0.210/doc/man/NOTUSED/hash.30000644000175000001440000001311010751423606015122 0ustar timusers.TH HASH 3 .UC 4 .SH NAME hash \- procedures for managing hash tables in libmagicutils.a .SH SYNOPSIS .nf .B #include "hash.h" .PP .B "HashInit(table, initsize, keysize)" .B HashTable *table; .B int initsize, keysize; .PP .B "HashInitClient(table, initsize, keysize, compareFn, copyFn, hashFn, killFn)" .B HashTable *table; .B int initsize, keysize; .B int (*compareFn)(key1, key2); .B char *(*copyFn)(key); .B int (*hashFn)(key); .B Void (*killFn)(key); .PP .B "int HashSize(keybytes)" .B int keybytes; .PP .B "HashKill(table)" .B HashTable *table; .PP .B "HashEntry *HashLookOnly(table, key)" .B HashTable *table; .B ClientData key; .PP .B "HashEntry *HashFind(table, key)" .B HashTable *table; .B ClientData key; .PP .B "ClientData HashGetValue(he)" .B HashEntry *he; .PP .B "HashSetValue(he, value)" .B HashEntry *he; .B ClientData value; .PP .B "HashStartSearch(hs)" .B HashSearch *hs; .PP .B "HashEntry *HashNext(table, hs)" .B HashTable *table; .B HashSearch *hs; .fi .SH DESCRIPTION This module provides procedures for creating, accessing, and destroying hash tables. These tables grow automatically as more elements are added to them to avoid overloading. They may be indexed by strings, single words, or multi-word structures. Single-word can be interpreted (e.g., compared or hashed) by user-supplied procedures. Each entry stores a single word value, which may be set or read by the macros \fIHashSetValue\fR or \fIHashGetValue\fR but should not be manipulated directly. .PP .I HashInit is used to allocate space for the initially empty hash table \fItable\fR. Enough space is allocated for \fIinitsize\fR buckets (which should be a power of two), although subsequent additions to the hash table can cause the number of buckets to increase. Tables can be organized in one of three different ways, depending on the value of \fIkeysize\fR. .PP If \fIkeysize\fR is \fBHT_STRINGKEYS\fR, then keys passed to \fIHashFind\fR (or \fIHashLookOnly\fR) are treated as the addresses of NULL-terminated strings. The \fIHashEntry\fR structures for this type of key are variable-sized; sufficient space is allocated at the end of each structure to hold the key string and its trailing NULL byte. If \fIkeysize\fR is \fBHT_WORDKEYS\fR, then keys are single words of data passed directly to \fIHashFind\fR, and are compared using \fIstrcmp\fR\|(1). If \fIkeysize\fR is \fBHT_STRUCTKEYS\fR or greater, keys are multiple words of data, but their address is passed to \fIHashFind\fR (instead of the actual value as when \fIkeysize\fR was \fBHT_WORDKEYS\fR). The value of \fIkeysize\fR in this case should be the number of words in a key. The macro \fIHashSize\fR should be used to produce this number; \fIHashSize\fR(\fBsizeof \fR(\fBstruct \fIfoo\fR)) gives the number of words needed if keys are to be of type (\fIstruct foo\fR). In general, single-word keys (\fIkeysize\fR equal to \fBHT_WORDKEYS\fR) are the fastest, but the most restrictive. .PP A second procedure, \fIHashInitClient\fR, may be used to initialize a hash table instead of \fIHashInit\fR. This second procedure is a more general one, in that it allows a fourth value of \fIkeysize\fR to be provided, \fBHT_CLIENTKEYS\fR, along with four client procedures. The keys in such a case are single-word values, passed to \fIHashFind\fR just like keys when \fIkeysize\fR is \fBHT_WORDKEYS\fR. However, they are interpreted using the client procedures passed in the call to \fIHashInitClient\fR. These procedures perform four functions; if any are NULL, then those functions are performed exactly as in the case of \fBHT_WORDKEYS\fR. The first, \fI(*compareFn)(key1, key2)\fR, takes two single-word key values and returns either 0 if they are equal, or 1 if they are not. The next procedure, \fI(*copyFn)(key)\fR, is called when a new entry is being created for a key; it performs whatever processing is needed to ensure that the key can be kept around permanently (e.g., making a copy of it), and returns the value that will actually be stored as the key in the hash table (e.g., the copy). The third procedure, \fI(*hashFn)(key)\fR, is used to produce a single 32-bit value from \fIkey\fR. It is primarily useful when \fIkey\fR is in fact a pointer to a structure, and the contents of the structure, rather than its address, determine the hash value. Finally, \fI(*killFn)(key)\fR is called when the hash table is being freed by \fIHashKill\fR to perform any final cleanup of a key, such as freeing a key that had been copied by \fI(*copyFn)()\fR when it was installed in the hash table. .PP .I HashKill can be used to free all the storage associated with \fItable\fR. .PP Both \fIHashLookOnly\fR and \fIHashFind\fR are used for retrieving the entry from \fItable\fR that matchs \fIkey\fR. They differ in their behavior when \fIkey\fR is not in the table. .I HashLookOnly will return NULL if the key is not found, while .I HashFind will create a new HashEntry whose value (as returned by \fIHashGetValue\fR) is zero. .PP It is possible to scan sequentially through a hash table to visit all its entries. .I HashStartSearch initializes the \fIHashSearch\fR structure \fIhs\fR, which is then passed to \fIHashNext\fR, which keeps returning subsequent entries in the table until all have been returned, when it returns NULL. .SH BUGS If it is possible for initialized entries in the hash table to have NULL values, then \fIHashLookOnly\fR must be called before \fIHashFind\fR if you are to be certain that an entry was not already in the table, since there is no distinction between a NULL value that was already in the table and a NULL value that signifies that the entry was newly created by \fIHashFind\fR. .SH SEE ALSO magicutils\|(3) magic-8.0.210/doc/man/ext2spice.10000644000175000001440000001456510751423606015001 0ustar timusers.TH EXT2SPICE 1 .UC 4 .SH NAME ext2spice \- convert hierarchical \fIext\fR\|(5) extracted-circuit files to flat \fIspice\fR\| files .SH SYNOPSIS .B ext2spice [ .B \-B ] [ .I "extcheck-options" ] [ .I -M|m ] [ .I -y num ] [ .I -f hspice|spice3|spice2 ] [ .I -J hier|flat ] [ .I -j device:sdRclass[/subRclass]/defaultSubstrate ] .I root .SH DESCRIPTION Ext2spice will convert an extracted circuit from the hierarchical \fIext\fR\|(5) representation produced by Magic to a flat spice file which can be accepted by spice2, spice3, hspice and other simulation tools. The root of the tree to be extracted is the file \fIroot\fB.ext\fR; it and all the files it references are recursively flattened. The result is a single, flat representation of the circuit that is written to the file \fIroot\fB.spice\fR . .LP The following options are recognized: .TP 1.0i .B \-o\ \fIoutfile\fP Instead of leaving output in the file \fIroot\fB.spice\fR, leave it in \fIoutfile\fP. .TP 1.0i .B \-B Don't output transistor or node attributes in the spice file. Usually the attributes of a node or a device are output as special comments **fetattr and **nodeatrr which can be processed further to create things such a initial conditions etc. .TP 1.0i .B \-F Don't output nodes that aren't connected to fets (floating nodes). Normally capacitance from these nodes is output with the comment **FLOATING attached on the same line. .TP 1.0i .B \-t\fIchar\fR Trim characters from node names when writing the output file. \fIChar\fR should be either "#" or "!". The option may be used twice if both characters are desired. Trimming "#" and "!" is enabled by default when the format is hspice. .TP 1.0i .B -\fIM|m\fR Merge parallel fets. \fI-m\fR means conservative merging of fets that have equal widths only (usefull with hspice format multiplier if delta W effects need to be taken care of). -M means aggresive merging: the fets are merged if they have the same terminals and the same length. .TP 1.0i .B \-y \fInum\fR Select the precision for outputing capacitors. The default is 1 which means that the capacitors will be printed to a precision of .1 fF. .TP 1.0i .B \-f \fIhspice|spice2|spice3\fR Select the output format. Spice3 is the the format understood by the latest version of berkeley spice. Node names have the same names as they would in a \fIsim\fR(5) file and no special constructs are used. Spice2 is the format understood by the older version of spice (which usually has better convergence). Node names are numbers and a dictionary of number and corresponding node is output in the end. HSPICE is a format understood by meta-software's hspice and other commercial tools. In this format node names cannot be longer than 15 characters long (blame the fortran code): so if a hierarchical node name is longer it is truncated to something like x1234/name where x1234 is an alias of the normal node hierarchical prefix and name its hierarchical postfix (a dictionary mapping prefixes to real hierarchical paths is output at the end of the spice file). If the node name is still longer than 15 characters long (again blame the fortran code) it is translated to something like z@1234 and the equivalent name is output as a comment. In addition since hspice supports scaling and multipliers so the output dimensions are in lambdas and if parallel fets are merged the hspice construct \fIM\fR is used. .TP 1.0i .B \-J \fIhier|flat\fR Select the source/drain area and perimeter extraction algorithm. If \fIhier\fR is selected then the areas and perimeters are extracted \fIonly within each subcell\fR. For each fet in a subcell the area and perimeter of its source and drain within this subcell are output. If two or more fets share a source/drain node then the total area and perimeter will be output in only one of them and the other will have 0. If \fIflat\fR is selected the same rules apply only that the scope of search for area and perimeter is the whole netlist. In general \fIflat\fR (which is the default) will give accurate results (it will take into account shared sources/drains) but hier is provided for backwards compatibility with version 6.4.5. On top of this selection you can individually control how a terminal of a specific fet will be extracted if you put a source/drain attribute. \fIext:aph\fR makes the extraction for that specific terminal hierarchical and \fIext:apf\fR makes the extraction flat (see the magic tutorial about attaching attribute labels). Additionaly to ease extraction of bipolar transistors the gate attribute \fIext:aps\fR forces the output of the substrate area and perimeter for a specific fet (in flat mode only). .TP 1.0i .B \-j \fIdevice:sdRclass[/subRclass]/defaultSubstrate\fR Gives ext2sim information about the source/drain resistance class of the fet type \fIdevice\fR. Makes \fIdevice\fR to have \fIsdRclass\fR source drain resistance class, \fIsubRclass\fR substrate (well) resistance class and the node named \fIdefaultSubstrate\fR as its default substrate. The defaults are nfet:0/Gnd\! and pfet:1/6/Vdd\! which correspond to the MOSIS technology file but things might vary in your site. Ask your local cad administrator. .PP The way the extraction of node area and perimeter works in magic the total area and perimeter of the source/drain junction is summed up on a single node. That is why all the junction areas and perimeters are summed up on a single node (this should not affect simulation results however). .PP \fISpecial care must be taken when the substrate of a fet is tied to a node other than the default substrate\fR (eg in a bootstraping charge pump). To get the correct substrate info in these cases the fet(s) with separate wells should be in their own separate subcell with ext:aph attributes attached to their sensitive terminals (also all the transistors which share sensistive terminals with these should be in another subcell with the same attributes). .PP In addition, all of the options of \fIextcheck\fR\|(1) are accepted. .PP The awk filter spice2sim is provided with the current distribution for debugging purposes. .SH "SEE ALSO" extcheck\|(1), ext2spice\|(1), magic\|(1), rsim\|(1), ext\|(5), sim\|(5) .SH AUTHOR Stefanos Sidiropoulos. .SH BUGS The areas and perimeters of fet sources and drains work only with the simple extraction algorith and not with the extresis flow. So you have to model them as linear capacitors (create a special extraction style) if you want to extract parasitic resistances with extresis. magic-8.0.210/doc/man/dstyle.50000644000175000001440000001446510751423606014402 0ustar timusers.\" sccsid @(#)dstyle.5 4.6 (Berkeley) 10/20/85 .\" .\" CONVENTIONS: .\" italics: things that are substituted for .\" boldface: characters that are typed as-is .\" .\" EXAMPLE: \fIfilename\fB.mag\fR .\" or: \fBcif \fR[\fIfile\fR] .\" .TH DSTYLE 5 .UC 4 .SH NAME dstyle \- format of .dstyle files (display styles) .SH DESCRIPTION .PP Display styles indicate how to render information on a screen. Each style describes one way of rendering information, for example as a solid area in red or as a dotted outline in purple. Different styles correspond to mask layers, highlights, labels, menus, window borders, and so on. See ``Magic Maintainer's Manual #3: Display Styles, Color Maps, and Glyphs'' for more information on how the styles are used. .PP Dstyle files usually have names of the form \fIx\fB.\fIy\fB.dstyle\fIn\fR, where \fIx\fR is a class of technologies, \fIy\fR is a class of displays, and \fIn\fR is a version number (currently \fB5\fR). The version number may increase in the future if the format of dstyle files changes. For example, the display style file \fBmos.7bit.dstyle5\fR provides all the rendering information for our nMOS and CMOS technologies for color displays with at least 7 bits of color. .PP Dstyle files are stored in ASCII as a series of lines. Lines beginning with ``#'' are considered to be comments and are ignored. The rest of the lines of the file are divided up into two sections separated by blank lines. There should not be any blank lines within a section. .SH "DISPLAY_STYLES SECTION" The first section begins with a line .DS L \fBdisplay_styles\fR \fIplanes\fR .DE where \fIplanes\fR is the number of bits of color information per pixel on the screen (between 1 and 8). Each line after that describes one display style and contains eight fields separated by white space: .DS L \fIstyle writeMask color outline fill stipple shortName longName\fR .DE The meanings of the fields are: .TP \fIstyle\fR The number of this style, in decimal. Styles 1 through 64 are used to display mask layers in the edit cell. The style number(s) to use for each mask layer is (are) specified in the technology file. Styles 65-128 are used for displaying mask layers in non-edit cells. If style \fIx\fR is used for a mask layer in the edit cell, style \fIx\fR+64 is used for the same mask layer in non-edit cells. Styles above 128 are used by the Magic code for various things like menus and highlights. See the file \fIstyles.h\fR in Magic for how styles above 128 are used. When redisplaying, the styles are drawn in order starting at 1, so the order of styles may affect what appears on the screen. .TP \fIwriteMask\fR This is an octal number specifying which bit-planes are to be modified when this style is rendered. For example, 1 means only information in bit-plane 0 will be affected, and 377 means all eight bit-planes are affected. .TP \fIcolor\fR An octal number specifying the new values to be written into the bit-planes that are modified. This is used along with \fIwriteMask\fR to determine the new value of each pixel that's being modified: .DS C newPixel = (oldPixel & \(apwriteMask) | (color & writeMask) .DE The red, green, and blue intensities displayed for each pixel are not deterimined directly by the value of the pixel; they come from a color map that maps the eight-bit pixel values into red, green, and blue intensities. Color maps are stored in separate files. .TP \fIoutline\fR If this field is zero, then no outline is drawn. If the field is non-zero, it specifies that outlines are to be drawn around the rectangular areas rendered in this style, and the octal value gives an eight-bit pattern telling how to draw the outline. For example, 377 means to draw a solid line, 252 means to draw a dotted line, 360 specifies long dashes, etc. This field only indicates \fIwhich\fR pixels will be modified: the \fIwriteMask\fR and \fIcolor\fR fields indicate how the pixels are modified. .TP \fIfill\fR This is a text string specifying how the areas drawn in this style should be filled. It must have one of the values \fBsolid\fR, \fBstipple\fR, \fBcross\fR, \fBoutline\fR, \fBgrid\fR. \fBSolid\fR means that every pixel in the area is to modified according to \fIwriteMask\fR and \fIcolor\fR. \fBStipple\fR means that the area should be stippled: the stipple pattern given by \fIstipple\fR is used to determine which pixels in the area are to be modified. \fBCross\fR means that an X is drawn in a solid line between the diagonally-opposite corners of the area being rendered. \fBOutline\fR means that the area should not be filled at all; only an outline is drawn (if specified by \fIoutline\fR). \fBGrid\fR is a special style used to draw a grid in the line style given by \fIoutline\fR. The styles \fBcross\fR and \fBstipple\fR may be supplemented with an outline by giving a non-zero \fIoutline\fR field. The \fBoutline\fR and \fBgrid\fR styles don't make sense without an an outline, and \fBsolid\fR doesn't make sense with an outline (since all the pixels are modified anyway). .TP \fIstipple\fR Used when \fIfill\fR is \fBstipple\fR to specify (in decimal) the stipple number to use. .TP \fIshortName\fR This is a one-character name for this style. These names are used in the specification of glyphs and also in a few places in the Magic source code. Most styles have no short name; use a ``-'' in this field for them. .TP \fIlongName\fR A more human-readable name for the style. It's not used at all by Magic. .SH "STIPPLES SECTION" .PP The second section of a dstyle file is separated from the first by a blank line. The first line of the second section must be .DS L \fBstipples\fR .DE and each additional line specifies one stipple pattern with the syntax .DS L \fInumber pattern name\fR .DE \fINumber\fR is a decimal number used to name the stipple in the \fIstipple\fR fields of style lines. \fINumber\fR must be no less than 1 and must be no greater than a device-dependent upper limit. Most devices support at least 15 stipple patterns. \fIPattern\fR consists of eight octal numbers, each from 0-377 and separated by white space. The numbers form an 8-by-8 array of bits indicating which pixels are to be modified when the stipple is used. The \fIname\fR field is just a human-readable description of the stipple; it isn't used by Magic. .SH "FILES" \(apcad/lib/magic/sys/mos.7bit.dstyle5 .SH "SEE ALSO" magic\|(1), cmap\|(5), glyphs\|(5) magic-8.0.210/doc/man/dlys.50000644000175000001440000000652210751423606014044 0ustar timusers.TH DLYS 5 .SH NAME dlys \- format of .dlys files read by the SCALD simulator and timing verifier .SH DESCRIPTION The SCALD simulator and timing verifier can accept information about the actual delays of wires in a circuit. This delay information is described in a \fB.dlys\fR file, which consists of a sequence of records, one for each electrical net. Each record begins with the signal name for the net (note that this is the SCALD signal name, i.e, the name given by the user to the entire net, and not usually the name of one of the pins in the net), followed by an \fB=\fR, then a comma-separated list of the terminals in the net and their associated delay, with the list terminated by a semicolon. The end of the file is marked with a second semicolon. .PP The elements of the comma-separated list for each net take the form .sp .ti +8 \fIlocation\fB [\fImin\fB:\fImax\fB]\fR .sp where \fIlocation\fR is the full hierarchical SCALD name of the physical pin to which the delay is computed, and \fImin\fR and \fImax\fR are the best-case and worst-case wire delay in nanoseconds (both are floating-point numbers). The assumption is that only a single driver exists per net, so all delays are computed from this driver. If a net has multiple drivers, then the interpretation of delays is up to the program reading this file (e.g, \fImin\fR delays are taken from the fastest driver, \fImax\fR from the slowest). .PP Here is an example \fB.dlys\fR file: .sp .na .nf .ta +0.3i +2.0i \fC (APS )ALU STATUS BITS I1<0> = (APS MR 3V6 R1 1P )IN#63 [ 0.3 : 0.4 ], (APS APS 4RI RFC RF )OUT [ 0.5 : 0.7 ]; (APS )ALU STATUS BITS I1<1> = (APS APS 4ALUD DCD )AN#12 [ 1.4 : 1.6 ], (APS APS 4ALUD DCD )AN#8 [ 1.1 : 1.3 ], (APS APS 4ALUD DCD )AN#9 [ 1.1 : 1.3 ], (APS APS 4ALUD DCD )AN#10 [ 1.1 : 1.3 ], (APS APS 4ALUD DCD )AN#11 [ 1.1 : 1.3 ], (APS MR 3V2 R1 1P )#23 [ 0.6 : 0.8 ], (APS MR 3V6 R1 1P )#62 [ 0.3 : 0.4 ], (APS APS 4ALUD DCD ) [ 0.4 : 0.6 ], (APS APS 4ALUD DCD )#1 [ 0.4 : 0.6 ], (APS APS 4ALUD DCD )#2 [ 0.4 : 0.6 ], (APS APS 4ALUD DCD )#3 [ 0.4 : 0.6 ], (APS APS 4ALUD DCD )#4 [ 0.7 : 0.8 ], (APS APS 4ALUD DCD )#5 [ 0.7 : 0.8 ]; ; \fR .fi .ad .PP Although it is not good practice, it is possible to omit the actual pin names from the \fIlocation\fR names and only give the path to the part; the example above shows several cases where the final pin name is missing. Since the timing verifier and simulator have the original SCALD netlist available, they are usually able to use the signal name to determine the net, and then use the part's path to identify which pin of the net is meant. This is accurate when a net connects to at most one pin per part; if it connects to more than one pin per part then there is ambiguity over which pin is meant. Usually, though, this ambiguity results in only a small inaccuracy, since the delay to different pins on the same part is usually similar. Also, if delay is capacitive, the delay to all pins in a net will be the same anyway, so there is no inaccuracy. .SH "SEE ALSO" ext2dlys\|(1), ext\|(5), sim\|(5) .SH BUGS There should be some way to specify which pins are drivers and which are receivers in a net. .PP The ability to omit pin names is dangerous; although it usually works it can introduce large inaccuracies when the parts are large compared to the sizes of the wires used to connect them, as might be the case on a silicon PCB. magic-8.0.210/doc/man/tmac.anc0000644000175000001440000000766710751423606014425 0ustar timusers ' # month name .if t .tr ~\(ap .if "\nd"0" .nr m \n(mo-1 .if "\nm"0" .ds ]m January .if "\nm"1" .ds ]m February .if "\nm"2" .ds ]m March .if "\nm"3" .ds ]m April .if "\nm"4" .ds ]m May .if "\nm"5" .ds ]m June .if "\nm"6" .ds ]m July .if "\nm"7" .ds ]m August .if "\nm"8" .ds ]m September .if "\nm"9" .ds ]m October .if "\nm"10" .ds ]m November .if "\nm"11" .ds ]m December ' # set the date .if n \{.nr m \nm+1 . ie \nd .ds ]W Modified \nm/\nd/\ny . el .ds ]W Printed \n(mo/\n(dy/\n(yr\} .if t \{.ie \nd .ds ]W \*(]m \nd, 19\ny . el .ds ]W \*(]m \n(dy, 19\n(yr\} .de UC .if t .ds ]W 1990 DECWRL/Livermore Magic .. ' # reset the basic page layout .de }E .}f .in \\n()Ru+\\n(INu .ll \\n(LLu .. ' # default tabs .de DT 'ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i .. ' # set type font and size .de }f .ps 10 .ft 1 .. ' # handle the head of the page .de }H .ev 1 .}C 'sp .5i .ft 1 .ps 10 .tl @\\*(]H@\\*(]D@\\*(]H@ 'sp .5i .ev .ns .. ' # handle the foot of the page .de }F .ev 1 .ft 1 .ps 10 'sp .5i .tl @\\*(]W@\\*(]L@%@ 'bp .ev .. ' # the cut mark .if n .ig .de }C .po .1i .tl '-' .po .. ' # the final cut mark .de }M .}N .wh -1p }C .ll \\n(LLu .. ' # no runout unless there was a .TH .de }K .}N .pl 1 .ll \\n(LLu .. .em }K ' # set title and heading .de TH .if t .ds ]W 1990 DECWRL/Livermore Magic .PD .if n .nr IN .5i .if t .nr IN .5i .nr LL \\n(.l .ds ]H \\$1\|(\|\\$2\|) .ds ]D CAD Tool User's Manual .wh 0 }H .if t .wh -1i }F .if n .wh -1.167i }F .em }M .if \\n(nl .bp 1 .ds ]L \\$3 .}E .DT .nr )I .5i .nr )R 0 .if n .na .. ' # section heading .de SH .}X 0 .nr )E 2 \&\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6 .. ' # sub section heading .de SS .}X \\n()Ru+\\n(INu \&\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6 .br .. ' # subroutine for section heading .de }X .}E .ti \\$1 .sp \\n()Pu .ne 2 .nr )R 0 .fi .it 1 }N .SM .B .. ' # end of SH (cf }X above and }N below) .de }2 .nr )E 0 .}E .nr )I .5i .ns .. ' # italic .de I .ft 2 .it 1 }N .if !"\\$1"" \&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 .. ' # bold .de B .ft 3 .it 1 }N .if !"\\$1"" \&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 .. ' # small .de SM .ps 9 .it 1 }N .if !"\\$1"" \&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 .. ' # combinations of Roman, italic, bold .de RI .}S 1 2 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" .. .de RB .}S 1 3 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" .. .de IR .}S 2 1 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" .. .de IB .}S 2 3 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" .. .de BR .}S 3 1 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" .. .de BI .}S 3 2 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" .. ' # make special case of shift out of italic .de }S .ds ]F .if "\\$1"2" .if !"\\$5"" .ds ]F\^ .ie !"\\$4"" .}S \\$2 \\$1 "\\$3\f\\$1\\$4\\*(]F" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9" .el \\$3 .}f .. ' # paragraph .de LP .PP .. .de PP .sp \\n()Pu .ne 2 .}E .nr )I .5i .ns .. ' # paragraph distance .de PD .if t .nr )P .4v .if n .nr )P 1v .if !"\\$1"" .nr )P \\$1v .. ' # hanging indent .de HP .sp \\n()Pu .ne 2 .if !"\\$1"" .nr )I \\$1n .ll \\n(LLu .in \\n()Ru+\\n(INu+\\n()Iu .ti \\n()Ru+\\n(INu .}f .. ' # indented paragraph .de IP .TP \\$2 \&\\$1 .. ' # hanging label .de TP .if !"\\$1"" .nr )I \\$1n .sp \\n()Pu .in \\n()Ru .nr )E 1 .ns .it 1 }N .di ]B .. ' # end of TP (cf }N below) .de }1 .ds ]X \&\\*(]B\\ .nr )E 0 .if !"\\$1"" .nr )I \\$1n .}f .ll \\n(LLu .in \\n()Ru+\\n(INu+\\n()Iu .ti \\n(INu .ie !\\n()Iu+\\n()Ru-\w@\\*(]X@u-3p \{\\*(]X .br\} .el \\*(]X\h@|\\n()Iu+\\n()Ru@\c .}f .. ' # handle end of 1-line features .de }N .if \\n()E .br .di .if "\\n()E"0" .}f .if "\\n()E"1" .}1 .if "\\n()E"2" .}2 .nr )E 0 .. ' # increase relative indent .de RS .nr ]\\n+()p \\n()I .nr )\\n()p \\n()R .ie !"\\$1"" .nr )R +\\$1n .el .nr )R +\\n()I .nr )I .5i .}E .. ' # decrease relative indent .de RE .if !"\\$1"" \{.ie "\\$1"0" .nr )p 1 1 . el .nr )p \\$1 1\} .ds ]i \\*(]I\\n()p .ds ]r \\*(]R\\n()p .nr )I \\*(]i .nr )R \\*(]r .if \\n()p .nr )p -1 .}E .. .nr )p 0 1 .ds ]I \\\\n(] .ds ]R \\\\n() .bd S 3 3 .if t .ds R \(rg .if n .ds R (Reg.) .ds S \s10 .hy 14 magic-8.0.210/doc/man/displays.50000644000175000001440000000404610751423606014720 0ustar timusers.\" sccsid @(#)displays.5 4.1 MAGIC (Berkeley) 11/29/85 .\" .\" CONVENTIONS: .\" italics: things that are substituted for .\" boldface: characters that are typed as-is .\" .\" EXAMPLE: \fIfilename\fB.mag\fR .\" or: \fBcif \fR[\fIfile\fR] .\" .TH DISPLAYS 5 2/19/85 .UC .SH NAME displays \- Display Configuration File .SH DESCRIPTION The interactive graphics programs Caesar, Magic, and Gremlin use two separate terminals: a text terminal from which commands are issued, and a color graphics terminal on which graphical output is displayed. These programs use a .B displays file to associate their text terminal with its corresponding display device. .PP The .B displays file is an ASCII text file with one line for each text terminal/graphics terminal pair. Each line contains 4 items separated by spaces: the name of the port attached to a text terminal, the name of the port attached to the associated graphics terminal, the phosphor type of the graphics terminal's monitor, and the type of graphics terminal. .PP An applications program may use the phosphor type to select a color map tuned to the monitor's characteristics. Only the \fBstd\fR phosphor type is supported at UC Berkeley. .PP The graphics terminal type specifies the device driver a program should use when communicating with its graphics terminal. Magic supports types \fBUCB512\fR, \fBAED1024\fR, and \fBSUN120\fR. Other programs may recognize different display types. See the manual entry for your specific application for more information. .PP A sample displays file is: .sp .in +0.5i .B .br /dev/ttyi1 /dev/ttyi0 std UCB512 .br /dev/ttyj0 /dev/ttyj1 std UCB512 .br /dev/ttyjf /dev/ttyhf std UCB512 .br /dev/ttyhb /dev/ttyhc std UCB512 .br /dev/ttyhc /dev/ttyhb std UCB512 .R .in -0.5i .br .PP In this example, \fB/dev/ttyi1\fR connects to a text terminal. An associated \fBUCB512\fR graphics terminal with standard phosphor is connected to \fB/dev/ttyi0\fR. .SH "FILES" Magic uses the displays file ~cad/lib/displays. Gremlin looks in /usr/local/displays. .SH "SEE ALSO" magic(1) magic-8.0.210/doc/man/ext.50000644000175000001440000003136210751423606013671 0ustar timusers.\" sccsid @(#)ext.5 4.2 MAGIC (Berkeley) 11/30/85 .\" .\" CONVENTIONS: .\" italics: things that are substituted for .\" boldface: characters that are typed as-is .\" .\" EXAMPLE: \fIfilename\fB.mag\fR .\" or: \fBcif \fR[\fIfile\fR] .\" .TH EXT 5 .UC 4 .SH NAME ext \- format of .ext files produced by Magic's hierarchical extractor .SH DESCRIPTION Magic's extractor produces a \fB.ext\fP file for each cell in a hierarchical design. The \fB.ext\fP file for cell \fIname\fP is \fIname\fB.ext\fR. This file contains three kinds of information: environmental information (scaling, timestamps, etc), the extracted circuit corresponding to the mask geometry of cell \fIname\fP, and the connections between this mask geometry and the subcells of \fIname\fP. .LP A \fB.ext\fP file consists of a series of lines, each of which begins with a keyword. The keyword beginning a line determines how the remainder of the line is interpreted. The following set of keywords define the environmental information: .TP .B "tech\ \fItechname\fR" Identifies the technology of cell \fIname\fP as \fItechname\fP, e.g, \fBnmos\fP, \fBcmos\fP. .TP .B "timestamp\ \fItime\fR" Identifies the time when cell \fIname\fP was last modified. The value \fItime\fP is the time stored by Unix, i.e, seconds since 00:00 GMT January 1, 1970. Note that this is \fInot\fP the time \fIname\fR was extracted, but rather the timestamp value stored in the \fB.mag\fP file. The incremental extractor compares the timestamp in each \fB.ext\fP file with the timestamp in each \fB.mag\fP file in a design; if they differ, that cell is re-extracted. .TP .B "version\ \fIversion\fR" Identifies the version of \fB.ext\fR format used to write \fIname\fB.ext\fR. The current version is \fB5.1\fR. .TP .B "style\ \fIstyle\fR" Identifies the style that the cell has been extracted with. .TP .B "scale\ \fIrscale\ cscale\ lscale\fR" Sets the scale to be used in interpreting resistance, capacitance, and linear dimension values in the remainder of the \fB.ext\fP file. Each resistance value must be multiplied by \fIrscale\fP to give the real resistance in milliohms. Each capacitance value must be multiplied by \fIcscale\fP to give the real capacitance in attofarads. Each linear dimension (e.g, width, height, transform coordinates) must be multiplied by \fIlscale\fP to give the real linear dimension in centimicrons. Also, each area dimension (e.g, transistor channel area) must be multiplied by \fIscale*scale\fP to give the real area in square centimicrons. At most one \fBscale\fP line may appear in a \fB.ext\fP file. If none appears, all of \fIrscale\fP, \fIcscale\fP, and \fIlscale\fP default to 1. .TP .B "resistclasses\ \fIr1 r2 ...\fR" Sets the resistance per square for the various resistance classes appearing in the technology file. The values \fIr1\fR, \fIr2\fR, etc. are in milliohms; they are not scaled by the value of \fIrscale\fR specified in the \fBscale\fR line above. Each node in a \fB.ext\fR file has a perimeter and area for each resistance class; the values \fIr1\fR, \fIr2\fR, etc. are used to convert these perimeters and areas into actual node resistances. See ``Magic Tutorial #8: Circuit Extraction'' for a description of how resistances are computed from perimeters and areas by the program \fBext2sim\fR. .PP The following keywords define the circuit formed by the mask information in cell \fIname\fP. This circuit is extracted independently of any subcells; its connections to subcells are handled by the keywords in the section after this one. .TP .B "node \fIname R C x y type a1 p1 a2 p2 ... aN pN\fR" Defines an electrical node in \fIname\fP. This node is referred to by the name \fIname\fP in subsequent \fBequiv\fP lines, connections to the terminals of transistors in \fBfet\fP lines, and hierarchical connections or adjustments using \fBmerge\fP or \fBadjust\fP. The node has a total capacitance to ground of \fIC\fP attofarads, and a lumped resistance of \fIR\fP milliohms. For purposes of going back from the node name to the geometry defining the node, \fI(x,\|y)\fP is the coordinate of a point inside the node, and \fItype\fR is the layer on which this point appears. The values \fIa1\fR, \fIp1\fR, ... \fIaN\fR, \fIpN\fR are the area and perimeter for the material in each of the resistance classes described by the \fBresistclasses\fR line at the beginning of the \fB.ext\fR file; these values are used to compute adjusted hierarchical resistances more accurately. \fBNOTE:\fR since many analysis tools compute transistor gate capacitance themselves from the transistor's area and perimeter, the capacitance between a node and substrate (GND!) normally does not include the capacitance from transistor gates connected to that node. If the \fB.sim\fR file was produced by \fIext2sim\fR\|(1), check the technology file that was used to produce the original \fB.ext\fR files to see whether transistor gate capacitance is included or excluded; see ``Magic Maintainer's Manual #2: The Technology File'' for details. .TP .B "attr \fIname xl yl xh yh type text\fR" One of these lines appears for each label ending in the character ``\fB@\fR'' that was attached to geometry in the node \fIname\fR. The location of each attribute label (\fIxl yl xh yh\fR) and the type of material to which it was attached (\fItype\fR) are given along with the text of the label minus the trailing ``\fB@\fR'' character (\fItext\fR). .TP .B "equiv\ \fInode1\ node2\fR" Defines two node names in cell \fIname\fP as being equivalent: \fInode1\fP and \fInode2\fP. In a collection of node names related by \fBequiv\fP lines, exactly one must be defined by a \fBnode\fP line described above. .TP .B "fet\ \fItype\ xl\ yl\ xh\ yh\ area\ perim\ sub\ GATE\ T1\ T2\ ...\fR" Defines a transistor in \fIname\fP. The kind of transistor is \fItype\fP, a string that comes from the technology file and is intended to have meaning to simulation programs. The coordinates of a square entirely contained in the gate region of the transistor are \fI(xl,\ yl)\fP for its lower-left and \fI(xh,\ yh)\fP for its upper-right. All four coordinates are in the \fIname\fP's coordinate space, and are subject to scaling as described in \fBscale\fP above. The gate region of the transistor has area \fIarea\fP square centimicrons and perimeter \fIperim\fP centimicrons. The substrate of the transistor is connected to node \fIsub\fP. .sp The remainder of a \fBfet\fP line consists of a series of triples: \fIGATE\fP, \fIT1\fP, .... Each describes one of the terminals of the transistor; the first describes the gate, and the remainder describe the transistor's non-gate terminals (e.g, source and drain). Each triple consists of the name of a node connecting to that terminal, a terminal length, and an attribute list. The terminal length is in centimicrons; it is the length of that segment of the channel perimeter connecting to adjacent material, such as polysilicon for the gate or diffusion for a source or drain. .sp The attribute list is either the single token ``0'', meaning no attributes, or a comma-separated list of strings. The strings in the attribute list come from labels attached to the transistor. Any label ending in the character ``\fB^\fR'' is considered a gate attribute and appears on the gate's attribute list, minus the trailing ``\fB^\fR''. Gate attributes may lie either along the border of a channel or in its interior. Any label ending in the character ``\fB$\fR'' is considered a non-gate attribute. It appears on the list of the terminal along which it lies, also minus the trailing ``\fB$\fR''. Non-gate attributes may only lie on the border of the channel. .PP The keywords in this section describe information that is not processed hierarchically: path lengths and accurate resistances that are computed by flattening an entire node and then producing a value for the flattened node. .TP .B "killnode\ \fInode\fR" During resistance extraction, it is sometimes necessary to break a node up into several smaller nodes. The appearance of a \fBkillnode\fR line during the processing of a \fB.ext\fR file means that all information currently accumulated about \fInode\fR, along with all fets that have a terminal connected to \fInode\fR, should be thrown out; it will be replaced by information later in the \fB.ext\fR file. The order of processing \fB.ext\fR files is important in order for this to work properly: children are processed before their parents, so a \fBkillnode\fR in a parent overrides one in a child. .TP .B "resist\ \fInode1\ node2\ R\fR" Defines a resistor of \fIR\fR milliohms between the two nodes \fInode1\fR and \fInode2\fR. Both names are hierarchical. .TP .B "distance\ \fIname1\ name2\ dmin\ dmax\fR" Gives the distance between two electrical terminals \fIname1\fR (a driver) and \fIname2\fR (a receiver). Note that these are terminals and not nodes: the names (which are hierarchical label names) are used to specify two different locations on the same electrical node. The two distances, \fIdmin\fR and \fIdmax\fR, are the lengths (in lambda) of the shortest and longest acyclic paths between the driver and receiver. .PP The keywords in this last section describe the subcells used by \fIname\fP, and how connections are made to and between them. .TP .B "use\ \fIdef\ use-id\ TRANSFORM\fR" Specifies that cell \fIdef\fP with instance identifier \fIuse-id\fP is a subcell of cell \fIname\fP. If cell \fIdef\fP is arrayed, then \fIuse-id\fP will be followed by two bracketed subscript ranges of the form: \fB[\fIlo\fB,\fIhi\fB,\fIsep\fB]\fR. The first range is for x, and the second for y. The subscripts for a given dimension are \fIlo\fP through \fIhi\fP inclusive, and the separation between adjacent array elements is \fIsep\fP centimicrons. .sp \fITRANSFORM\fP is a set of six integers that describe how coordinates in \fIdef\fP are to be transformed to coordinates in the parent \fIname\fP. It is used by \fIext2sim\fP\|(1) in transforming transistor locations to coordinates in the root of a design. The six integers of \fITRANSFORM\fP (\fIta,\ tb,\ tc,\ td,\ te,\ tf\fR) are interpreted as components in the following transformation matrix, by which all coordinates in \fIdef\fP are post-multiplied to get coordinates in \fIname\fP: .sp .in +2i .nf .ta +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i \fIta\fR \fItd\fR 0 \fItb\fR \fIte\fR 0 \fItc\fR \fItf\fR 1 .fi .in -2i .TP .B "merge\ \fIpath1\ path2\ C\ a1\ p1\ a2\ p2 \ ...\ aN\ pN\fR" Used to specify a connection between two subcells, or between a subcell and mask information of \fIname\fP. Both \fIpath1\fP and \fIpath2\fP are hierarchical node names. To refer to a node in cell \fIname\fP itself, its pathname is just its node name. To refer to a node in a subcell of \fIname\fP, its pathname consists of the \fIuse-id\fP of the subcell (as it appeared in a \fBuse\fP line above), followed by a slash\ (\fI/\fR), followed by the node name in the subcell. For example, if \fIname\fP contains subcell \fIsub\fP with use identifier \fIsub-id\fP, and \fIsub\fP contains node \fIn\fP, the full pathname of node \fIn\fP relative to \fIname\fP will be \fIsub-id/n\fP. .PP Connections between adjacent elements of an array are represented using a special syntax that takes advantage of the regularity of arrays. A use-id in a path may optionally be followed by a range of the form \fB[\fIlo\fB:\fIhi\fB]\fR (before the following slash). Such a use-id is interpreted as the elements \fIlo\fP through \fIhi\fP inclusive of a one-dimensional array. An element of a two-dimensional array may be subscripted with two such ranges: first the y range, then the x range. .PP Whenever one \fIpath\fP in a \fBmerge\fP line contains such a subscript range, the other must contain one of comparable size. For example, .sp .ti +1i \fBmerge\fP\ \ sub-id[1:4,2:8]/a\ \ sub-id[2:5,1:7]/b .sp is acceptable because the range 1:4 is the same size as 2:5, and the range 2:8 is the same size as 1:7. .sp When a connection occurs between nodes in different cells, it may be that some resistance and capacitance has been recorded redundantly. For example, polysilicon in one cell may overlap polysilicon in another, so the capacitance to substrate will have been recorded twice. The values \fIC\fP, \fIa1\fR, \fIp1\fR, etc. in a \fBmerge\fP line provide a way of compensating for such overlap. Each of \fIa1\fR, \fIp1\fR, etc. (usually negative) are added to the area and perimeter for material of each resistance class to give an adjusted area and perimeter for the aggregate node. The value \fIC\fP attofarads (also usually negative) is added to the sum of the capacitances (to substrate) of nodes \fIpath1\fP and \fIpath2\fP to give the capacitance of the aggregate node. .TP .B "cap\ \fInode1\ node2\ C\fR" Defines a capacitor between the nodes \fInode1\fP and \fInode2\fP, with capacitance \fIC\fP. This construct is used to specify both internodal capacitance within a single cell and between cells. .SH AUTHOR Walter Scott .SH "SEE ALSO" ext2sim\|(1), magic\|(1) magic-8.0.210/doc/man/ext2sim.10000644000175000001440000001526410751423606014463 0ustar timusers.TH EXT2SIM 1 .UC 4 .SH NAME ext2sim \- convert hierarchical \fIext\fR\|(5) extracted-circuit files to flat \fIsim\fR\|(5) files .SH SYNOPSIS .B ext2sim [ .B \-a .I aliasfile ] [ .B \-l .I labelsfile ] [ .B \-o .I simfile ] [ .B \-A ] [ .B \-B ] [ .B \-F ] [ .B \-L ] [ .B \-t ] [ .I "extcheck-options" ] [ .I -y num ] [ .I -f mit|lbl|su ] [ .I -J hier|flat ] [ .I -j device:sdRclass[/subRclass]/defaultSubstrate ] .I root .SH DESCRIPTION Ext2sim will convert an extracted circuit from the hierarchical \fIext\fR\|(5) representation produced by Magic to the flat \fIsim\fR\|(5) representation required by many simulation tools. The root of the tree to be extracted is the file \fIroot\fB.ext\fR; it and all the files it references are recursively flattened. The result is a single, flat representation of the circuit that is written to the file \fIroot\fB.sim\fR, a list of node aliases written to the file \fIroot\fB.al\fR, and a list of the locations of all nodenames in CIF format, suitable for plotting, to the file \fIroot\fB.nodes\fR. The file \fIroot\fB.sim\fR is suitable for use with programs such as \fIcrystal\fP\|(1), \fIesim\fP\|(1), or \fIsim2spice\fP\|(1). .LP The following options are recognized: .TP 1.0i .B \-a\ \fIaliasfile\fP Instead of leaving node aliases in the file \fIroot\fB.al\fR, leave it in \fIaliasfile\fP. .TP 1.0i .B \-l\ \fIlabelfile\fP Instead of leaving a CIF file with the locations of all node names in the file \fIroot\fB.nodes\fR, leave it in \fIlabelfile\fP. .TP 1.0i .B \-o\ \fIoutfile\fP Instead of leaving output in the file \fIroot\fB.sim\fR, leave it in \fIoutfile\fP. .TP 1.0i .B \-A Don't produce the aliases file. .TP 1.0i .B \-B Don't output transistor or node attributes in the \fB.sim\fR file. This option will also disable the output of information such as the area and perimeter of source and drain diffusion and the fet substrate. For compatibitlity reasons the latest version of ext2sim outputs this information as node attibutes. This option is necessary when preparing input for programs that don't know about attributes, such as \fIsim2spice\fR\|(1) (which is actually made obsolete by \fIext2spice\fR\|(1), anyway), or \fIrsim\fR\|(1). .TP 1.0i .B \-F Don't output nodes that aren't connected to fets (floating nodes). .TP 1.0i .B \-L Don't produce the label file. .TP 1.0i .B \-t\fIchar\fR Trim characters from node names when writing the output file. \fIChar\fR should be either "#" or "!". The option may be used twice if both characters are desired. .TP 1.0i .B \-f \fIMIT|LBL|SU\fR Select the output format. MIT is the traditional \fIsim\fR(5) format. LBL is a variant of it understood by \fIgemini\fR(1) which includes the substrate connection as a fourth terminal before length and width. SU is the internal Stanford format which is described also in \fIsim\fR(5) and includes areas and perimeters of fet sources, drains and substrates. .TP 1.0i .B \-y \fInum\fR Select the precision for outputing capacitors. The default is 1 which means that the capacitors will be printed to a precision of .1 fF. .TP 1.0i .B \-J \fIhier|flat\fR Select the source/drain area and perimeter extraction algorithm. If \fIhier\fR is selected then the areas and perimeters are extracted \fIonly within each subcell\fR. For each fet in a subcell the area and perimeter of its source and drain within this subcell are output. If two or more fets share a source/drain node then the total area and perimeter will be output in only one of them and the other will have 0. If \fIflat\fR is selected the same rules apply only that the scope of search for area and perimeter is the whole netlist. In general \fIflat\fR (which is the default) will give accurate results (it will take into account shared sources/drains) but hier is provided for backwards compatibility with version 6.4.5. On top of this selection you can individually control how a terminal of a specific fet will be extracted if you put a source/drain attribute. \fIext:aph\fR makes the extraction for that specific terminal hierarchical and \fIext:apf\fR makes the extraction flat (see the magic tutorial about attaching attribute labels). Additionaly to ease extraction of bipolar transistors the gate attribute \fIext:aps\fR forces the output of the substrate area and perimeter for a specific fet (in flat mode only). .TP 1.0i .B \-j \fIdevice:sdRclass[/subRclass]/defaultSubstrate\fR Gives ext2sim information about the source/drain resistance class of the fet type \fIdevice\fR. Makes \fIdevice\fR to have \fIsdRclass\fR source drain resistance class, \fIsubRclass\fR substrate (well) resistance class and the node named \fIdefaultSubstrate\fR as its default substrate. The defaults are nfet:0/Gnd\! and pfet:1/6/Vdd\! which correspond to the MOSIS technology file but things might vary in your site. Ask your local cad administrator. .PP The way the extraction of node area and perimeter works in magic the total area and perimeter of the source/drain junction is summed up on a single node. That is why all the junction areas and perimeters are summed up on a single node (this should not affect simulation results however). .PP \fISpecial care must be taken when the substrate of a fet is tied to a node other than the default substrate\fR (eg in a bootstraping charge pump). To get the correct substrate info in these cases the fet(s) with separate wells should be in their own separate subcell with ext:aph attributes attached to their sensitive terminals (also all the transistors which share sensistive terminals with these should be in another subcell with the same attributes). .PP In addition, all of the options of \fIextcheck\fR\|(1) are accepted. .SH "SCALING AND UNITS" If all of the \fB.ext\fR files in the tree read by \fIext2sim\fP have the same geometrical scale (specified in the \fBscale\fP line in each \fB.ext\fR file), this scale is reflected through to the output, resulting in substantially smaller \fB.sim\fR files. Otherwise, the geometrical unit in the output \fB.sim\fR file is a centimicron. .PP Resistance and capacitance are always output in ohms and femptofarads, respectively. .SH "SEE ALSO" extcheck\|(1), ext2dlys\|(1), ext2spice\|(1), magic\|(1), rsim\|(1), ext\|(5), sim\|(5) .SH AUTHOR Walter Scott additions/fixes by Stefanos Sidiropoulos. .SH BUGS Transistor gate capacitance is typically not included in node capacitances, as most analysis tools compute the gate capacitance directly from the gate area. The \fB-c\fR flag therefore provides a limit only on non-gate capacitance. The areas and perimeters of fet sources and drains work only with the simple extraction algorith and not with the extresis flow. So you have to model them as linear capacitors (create a special extraction style) if you want to extract parasitic resistances with extresis. magic-8.0.210/doc/man/glyphs.50000644000175000001440000000507710751423606014403 0ustar timusers.\" sccsid @(#)glyphs.5 4.2 (Berkeley) 10/17/85 .\" .\" CONVENTIONS: .\" italics: things that are substituted for .\" boldface: characters that are typed as-is .\" .\" EXAMPLE: \fIfilename\fB.mag\fR .\" or: \fBcif \fR[\fIfile\fR] .\" .TH GLYPHS 5 .UC 4 .SH NAME glyphs \- format of .glyphs files .SH DESCRIPTION .PP Glyph files (``.glyph'' extension) are used to store commonly-used bit patterns (glyphs) for Magic. Right now, the bit patterns are used for two purposes in Magic. First, they specify patterns for programmable cursors: each cursor shape (e.g. the arrow used for the wiring tool) is read in as a glyph from a glyph file. Second, glyphs are used by the window manager to represent the icons displayed at the ends of scroll bars. Glyph file names normally have the extension \fB.glyph\fR. .PP Glyph files are stored in ASCII format. Lines beginning with ``#'' are considered to be comments and are ignored. Blank lines are also ignored. The first non-comment line in a glyph file must have the syntax .DS L \fBsize \fInGlyphs width height\fR .DE The \fInGlyphs\fR field must be a number giving the total number of glyphs stored in the file. The \fIwidth\fR and \fIheight\fR fields give the dimensions of each glyph in pixels. All glyphs in the same file must have the same size. .PP The \fBsize\fR line is followed by a description for each of the glyphs. Each glyph consists of \fIheight\fR lines each containing 2\(mu\fIwidth\fR characters. Each pair of characters corresponds to a bit position in the glyph, with the leftmost pair on the topmost line corresponding to the upper-left pixel in the glyph. .PP The first character of each pair specifies the color to appear in that pixel. The color is represented as as a single character, which must be the short name of a display style in the current display style file. Some commonly-used characters are \fBK\fR for black, \fBW\fR for white, and \fB.\fR for the background color (when \fB.\fR is used in a cursor, it means that that pixel position is transparent: the underlying picture appears through the cursor). See ``Magic Maintainer's Manual #3: Display Styles, Color Maps, and Glyphs'' for more information. .PP The second character of each pair is normally blank, except for one pixel per glyph which may contain a ``*'' in the second character. The ``*'' is used for programmable cursors to indicate the hot-spot: the pixel corresponding to the ``*'' is the one that the cursor is considered to point to. .PP For an example of a glyph file, see \(apcad/lib/magic/sys/color.glyphs. .SH "SEE ALSO" magic\|(1), dstyle\|(5) magic-8.0.210/doc/man/net.50000644000175000001440000000422410751423606013654 0ustar timusers.\" sccsid @(#)net.5 4.1 MAGIC (Berkeley) 11/29/85 .\" .\" CONVENTIONS: .\" italics: things that are substituted for .\" boldface: characters that are typed as-is .\" .\" EXAMPLE: \fIfilename\fB.mag\fR .\" or: \fBcif \fR[\fIfile\fR] .\" .TH NET 5 .UC 4 .SH NAME net \- format of .net files read/written by Magic's netlist editor .SH DESCRIPTION .PP Netlist files are read and written by Magic's netlist editor in a very simple ASCII format. The first line contains the characters ``\ \ Netlist File'' (the leading blank is important). After that comes a blank line and then the descriptions of one or more nets. Each net contains one or more lines, where each line contains a single terminal name. The nets are separated by blank lines. Any line that is blank or whose first character is blank is considered to be a separator line and the rest of its contents are ignored. .PP Each terminal name is a path, much like a file path name in Unix. It consists of one or more fields separated by slashes. The last field in the path is the name of a label in a cell. The other fields (if any), are cell instance identifiers that form a path from the edit cell down to the label. The first instance identifier must name a subcell of the edit cell, the second must be a subcell of the first, and so on. .PP Instance identifiers are unique within their parent cells, so a terminal path selects a unique cell to contain the label. However, the same label may appear multiple times within its cell. When this occurs, Magic assumes that the identical labels identify electrically equivalent terminals; it will choose the closest of them when routing to that terminal. Further, after connecting to one of these terminals Magic may take advantage of the internal wiring connecting them together and route through a cell to complete the net's wiring. .PP An example netlist file follows below. It contains three distinct nets. .nf .cs R 22 \l'10c\&\(em' .RS Netlist File alu/bit_1/cout alu/bit_2/cin regcell[21,2]/output latch[2]/input This line starts with a blank, so it's a separator. opcode_pla/out6 shifter/drivers/shift2 .RE \l'10c\&\(em' .cs R .fi .SH "SEE ALSO" magic\|(1) magic-8.0.210/doc/html/0000755000175000001440000000000011504623573013171 5ustar timusersmagic-8.0.210/doc/html/port.html0000644000175000001440000001316010751423606015042 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

port


Declare a label to be a subcircuit port, or manipulate port parameters.

Usage:

port option

where option may be one of the following:
index directions
Declare a label to be a port with order number index and with allowed connection directions specified by the list directions. This is equivalent to the make option, except that the index and direction must be specified.
class [type]
Get [set] port class type (see Summary, below).
use [type]
Get [set] port use type (see Summary, below).
index [number]
Get [set] port number
equivalent [number]
Make the port equivalent to the (other) port numbered number.
connections [directions]
Get [set] port connection directions
make [index] [directions]
Declare a label to be a port with order number index and with allowed connection directions specified by the list directions. If not specified, the index is set to the first unused number, starting with 1, and the direction defaults to the direction of the label text. That is, if the label text is drawn to the right of the port, then connections are allowed to the right side of the port.
remove
Turn a port back into an ordinary label, removing all of its port properties.
help
Print help information

Summary:

The port command turns labels into ports and manipulates the properties of those ports. The port command gives magic some understanding of "standard cells". A cell definition that contains declared ports is treated specially by the extract, ext2spice, lef, and def commands. All other commands interpret ports as ordinary labels. ext2spice only interprets ports specially if the option ext2spice subcircuits on is enabled. Cells that contain port labels are assumed in these cases to be standard cells, that is, cells which are pre-characterized, and for which the layout is not to be interpreted as a physical circuit. When writing SPICE output, a cell containing port labels that is a descendent cell of the top-level layout is written as a subcircuit call, that is, an "X" record. If the top-level cell in the layout contains ports, then the SPICE output is written as a subcircuit definition, that is, wrapped in a ".subckt . . . .ends" pair. For LEF files, a cell that contains ports is written as a macro cell, and the ports are the declared PINs of the macro. For DEF files, a cell that contains ports is written as a COMPONENT.

The "index" property of the port is used only when the cell is written into a SPICE deck as a subcircuit entry, when the ext2spice subcircuit on option is enabled (which it is by default). In that case, the subcircuit call parameters (nodes) are written in the order of the port indices, which are then assumed to match the definition for the subcircuit. Likewise, if the circuit is written as a subcircuit to a SPICE file, the order of parameters in the subcircuit definition will match the order of the port indices. Note that the actual port numbers are ignored; the port values will be written in ascending order starting with the lowest numbered port and ending with the highest numbered port.

The "direction" property of the port has no particular meaning to magic but may be used by other programs to control the allowed direction of routes into a standard cell.

The "class" and "use" properties of the port have no internal meaning to magic but are used by the LEF and DEF format read and write routines, and match the LEF/DEF CLASS and USE properties for macro cell pins. Valid classes are: default, input, output, tristate, bidirectional, inout, feedthrough, and feedthru. Valid uses are: default, analog, signal, digital, power, ground, and clock.

Implementation Notes:

port is implemented as a built-in command in magic.

See Also:

label
lef

Return to command index

Last updated: October 16, 2004 at 2:10pm

magic-8.0.210/doc/html/tech.html0000644000175000001440000001136710751423606015010 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

tech


Query properties of the current technology, or change the current technology.

Usage:

tech option

where option may be one of the following:
load filename [-noprompt][-nooverride]
Load a new technology from the file filename[.tech].
help
Display help information
name
Show current technology name
filename
Show current technology filename
version
Show current technology version and description strings
lambda
Show internal units per lambda
planes
Show defined planes
layers [layer]
Show defined layers
drc option
Query the DRC ruleset, where option is one of the following:
width layer
Return the minimum allowed width for the indicated layer type.
spacing layer1 [layer2]
Return the minimum allowed spacing between layer1 and layer2, if layer2 is specified, or between layer1 and itself, if not.

Summary:

The tech command queries aspects of the current technology, and can also be used to change the current technology. The tech load command completely replaces the technology. Normally a call to tech load generates a dialog window asking the user for confirmation, since the tech load command is potentially destructive and can cause loss of an existing layout. The -noprompt option forces a technology load without presenting a dialog. This is particularly useful to put a "tech load name -noprompt" command in a .magic startup file in the directory of a project, so that it is not necessary to specify the technology on the command line when invoking magic. However, occasionally one may want to run magic from the same project directory with a different technology. The -nooverride option prevents the tech load command from overriding a technology name entered on the UNIX command line when starting magic.

Technology file reloading is especially useful when developing a technology file, to immediately see the results of a change made to the file. The current technology can be reloaded with the simple Tcl command "tech load [tech filename]".

Note that there is a slightly different meaning between the command "tech layers" and "tech layers "*"". The former prints a formatted list of layers, including all aliases for each layer, to the console. The second returns a Tcl list of all layers, with only the primary name for each layer.

A few aspects of the technology must be queried from other commands. The CIF/GDS input and output styles are given by the cif istyle and cif ostyle commands, while the extraction style is given by the extract style command.

The drc option is intended for use by Tcl scripted procedures that wish to place layout while satisfying the DRC rules. The two accepted rule options are spacing and width.

Implementation Notes:

tech is implemented as a built-in command in magic. The command replaces the original techinfo command, which no longer exists.

Bugs:

tech drc may not return the correct value in all cases.

Return to command index

Last updated: October 16, 2004 at 1:59pm

magic-8.0.210/doc/html/load.html0000644000175000001440000000700610751423606014777 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

load


Load a cell into the layout window

Usage:

load [cellname [scaled n [d]]] [-force]

where cellname is the name of a cell that presumably exists either in the database memory or on disk as a .mag file. n and d are the numerator and denominator, respectively, of a magnification factor, if it is desired to load the cell at a different scale than it was written. d defaults to 1 if not specified.

Summary:

The load command loads a cell into the database and displays it in the current layout window (if available). If the cell is not already in the database memory, it is loaded from disk. If it cannot be found on disk, then a new cell definition of name cellname is created and loaded into the window.

By default, magic loads a cell from disk only if the technology name matches the current technology. Historically, this has led to most technologies being named "scmos" which undermines the purpose of having a technology name in the first place. In magic-7.2 and 7.3, this behavior can be overridden with the -force option. magic will read the cell to the extent that layer names match between the current technology and the technology of the file.

The -force option and scaled option can be used together to port layouts from one technology to another. The scaled option implements a scale conversion during input by redefining the ratio of lambda to internal units during the load. This is useful if a cell was written in a lambda-based technology but needs to be read into a vendor-rules-based technology with a fine internal scale such as 0.1 micron per internal unit. The scaled option may also be used simply to resize cell geometry, although this is generally only useful to do for layout such as logos and text lettering drawn in routing layers.

Note that if it is not desired to have cellname created if not found on disk (e.g., because the path for the cell was missing from the search path), the database can be updated with the flush command or the cellname delete command.

Implementation Notes:

load is implemented as a built-in command in magic.

See Also:

xload

Return to command index

Last updated: October 7, 2004 at 2:02am

magic-8.0.210/doc/html/label.html0000644000175000001440000000522110751423606015134 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

command_name


Place a label in the layout

Usage:

label string [position [layer]]

where string is the text of the label, position may be any valid direction in magic, and layer may be any valid layer in the technology.

Summary:

The label command places a label on the layout. The label is marked by a point, line, or rectangle, depending on the size of the cursor box. If the area under the cursor box contains exactly one type, the label will be "attached" to that type; that is, the label will name the network of the node containing that type. If the area under the cursor box contains multiple layers, one will be chosen for attachment to the label. If there are multiple network nodes under the cursor box, the result may not be what the user intended; in such cases, the user should specify which layer the label should be attached to, so that the appropriate network node will be labeled.

The label text is placed to one side of the marker in the direction indicated by the position argument. For example, "label text north" will draw the label string "text" to the north (above) the marker.

Labels cannot be directly modified; modifications should be handled by first erasing the label with "erase label" and then redrawing.

Implementation Notes:

label is implemented as a built-in command in magic.

See Also:

port

Return to command index

Last updated: October 7, 2004 at 1:11am

magic-8.0.210/doc/html/imacro.html0000644000175000001440000000527510751423606015340 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

imacro


Define or print an interactive macro.

Usage:

imacro [window_type] key value

where key is a valid name for a keyboard key and value is the command to be printed to the console, pending completion. If present, window_type must be one of the window types recognized by the specialopen command: layout, color, netlist, or wind3d. If omitted, the layout window type is assumed, unless the command was called from inside a window using the colon or semicolon escape to the command-line, in which case the type of the calling window is assumed.

Summary:

The imacro command allows a variant of the macro command in which the bound command, rather than being immediately executed, is instead printed to the console as the beginning portion of a command, awaiting completion. It can be used to simplify typing of commands by pre-formatting the command line with the command and possibly some options. For example,
imacro p "paint "
will allow the single keystroke "p" to automatically format the command "paint " on the command line, waiting for the user to enter the type to paint and execute the command.

Unlike the macro command, commands entered by imacro are ultimately evaluated by the Tcl interpreter, and so may contain Tcl commands as well as magic commands.

Implementation Notes:

imacro is implemented as a built-in window command in magic.

See Also:

macro

Return to command index

Last updated: November 9, 2004 at 10:13am

magic-8.0.210/doc/html/closewrapper.html0000644000175000001440000000406610751423606016571 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

closewrapper


Close a GUI layout window and all of its associated frames.

Shortcuts:

Menu option File->Close implements the command closewrapper tk_path_name in the GUI layout window.

Usage:

closewrapper frame_name

where frame_name is the Tk path name of the top-level layout GUI window frame. By default, this name is .layout1, .layout2, etc., for successive windows created with the openwrapper command.

Summary:

The closewrapper command removes a layout window in the Tcl version of magic. It is only applicable when magic is invoked with the GUI wrapper, using magic -w, and supercedes the built-in command closewindow.

Implementation Notes:

closewrapper is implemented as a Tcl procedure in the GUI wrapper script.

See Also:

closewindow
openwrapper

Return to command index

Last updated: October 6, 2004 at 12:45am

magic-8.0.210/doc/html/windowborder.html0000644000175000001440000000311610751423606016563 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

windowborder


Toggle border drawing for new windows

Usage:

windowborder [on|off]

Summary:

The windowborder command turns the drawing of the window border on or off. Normally, this will be on in the non-GUI version of magic, and off in the GUI version, where the border area is handled by the Tk frame window. Note that the command does not affect the current layout windows, but takes effect for all windows created after the command has been called.

Implementation Notes:

windowborder is implemented as a built-in window command in magic.

Return to command index

Last updated: October 9, 2004 at 2:20am

magic-8.0.210/doc/html/promptsave.html0000644000175000001440000000443410751423606016262 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

promptsave


Invoke the load-file widget in the GUI version of magic, prompting for a file to load.

Shortcuts:

Menu item File->Save layout implements the command promptsave magic.
Menu item File->Write CIF implements the command promptsave cif.
Menu item File->Write GDS implements the command promptsave gds.

Usage:

promptsave magic|cif|gds

Summary:

The promptsave command handles output of various file formats for the GUI layout window in the Tcl-based version of magic when invoked with the magic -w option. The handling of CIF and GDS formats merely makes calls to the cif and gds write routines. The handling of magic (.mag) format appends the destination path to the search path. If the destination filename is changed in the Tk file window, the save command is invoked to rename the top-level layout appropriately before writing the output.

Implementation Notes:

promptsave is implemented as a Tcl procedure in the "wrapper" script. It calls the tk_getSaveFile widget in Tk.

See Also:

promptload

Return to command index

Last updated: October 16, 2004 at 2:09pm

magic-8.0.210/doc/html/deletecommandentry.html0000644000175000001440000000400710751423606017741 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

deletecommandentry


Remove the GUI window frame for additional command-line entry.

Usage:

deletecommandentry framename

where framename is the Tk pathname of a frame.

Summary:

The deletecommandentry command is used with the GUI wrapper in magic version 7.3. It removes the text entry frame at the bottom of the window that duplicates the output of the Tk console. The framename is the Tk path name of the frame holding the layout window. By default these are named .layout1, .layout2, etc., for each call to openwrapper.

Implementation Notes:

deletecommandentry is implemented as a Tcl procedure defined in the GUI wrapper script. It is only available when the wrapper is used, that is, when magic is invoked with argument -w.

See Also:

addcommandentry
openwrapper

Return to command index

Last updated: October 5, 2004 at 3:17am

magic-8.0.210/doc/html/cif.html0000644000175000001440000002007210751423606014617 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

cif


Read CIF input or generate CIF output.

Usage:

cif [option]

where option is one of the following:
help
Print usage information
arealabels [yes|no]
Enable/diable use of the CIF area label extension. The default is "yes". Normally there is no reason not to do this.
coverage layer
Report the coverage of the indicated CIF layer within the bounds of the current edit cell. This is useful for fabrication processes that require a minimum amount of coverage for specific layers (usually the metal routing layers).
idcell [yes|no]
Enable/diable use of the CIF cell ID extension. The default is "yes". Normally there is no reason not to do this.
lambda in|out
Report the number of microns per lambda for the current style. If "in" is specified, the value is reported for the current CIF/GDS input style. If "out" is specified, the value is reported for the current CIF/GDS output style.
limit [value]
Limit the amount of internal grid subdivision to the indicated value (which is dimensionless, the ratio of the maximum subdivision to the current lambda value). If no value is given, the current limit is reported. By default, the value is set to 100, as grid subdivision smaller than this amount can result in integer overflow on subsequent CIF or GDS output.
rescale [yes|no]
Allow or disallow internal grid subdivision while reading CIF input. Default is "yes". Normally, one wants to allow rescaling to ensure that the CIF is displayed exactly as it is in the input file. Occasionally, however, the CIF input is on a very fine scale, such as nanometers, and it is preferable to snap the input to lambda boundaries rather than to subsplit the internal grid to such a fine value. The limit option may also be used to limit grid subdivision to a minimum value (see above).
warning [option]
Set warning information level. "option" may be one of the following:
default
The default setting is equivalent to all the other options (align, limit, redirect, and none) being disabled.
align
Generate warnings during a "cif see" command if the alignment of geometry is on fractional lambda. Normally, magic allows contacts to be drawn at half-lambda positions. If this violates DRC requirements for the minimum output grid, this warning setting can be used to detect such violations.
limit
Limit warnings to the first 100 warnings or errors only.
redirect [file]
Redirect all warnings to an output file named file. If file is not given, then redirection is disabled.
none
Do not produce any warning messages on CIF input.
polygon subcells [yes|no]
Put non-Manhattan polygons into subcells. Default is "no". Normally this option is not needed. However, input layout that defines a number of angled wires, particularly those that are closely spaced, can cause magic to generate literally millions of internal tiles. This tends to be true in particular for corner cells in padframes for deep submicron feature sizes, where the angled corners are required to meet the DRC specification. When set to "yes", each polygon encountered in the CIF input is placed in its own uniquely-named subcell. This prevents interations with other polygons on the same plane and so reduces tile splitting.
see layers
View the CIF/GDS output layers in the comma-separated list layers as feedback entries on the layout. This is useful for determining what the actual foundry layer types are doing as a result of the boolean operations in the CIF/GDS output style. Most useful for debugging technology file CIF/GDS output style sections, or tracing DRC error reports from sources other than magic. CIF output is computed and feedback is shown only inside the cursor box area.

Figure 1. Command cif see CSP shows the P+ implant layer surrounding the P diffusion regions within the cursor box area.
statistics
Print statistics from the CIF generator, including tile operations, rectangles output, and interactions between cells. Not especially useful to the typical end-user.
prefix [path]
Prepend the path name path to cell names in the CIF output. If no path is specified, reports the existing path name.
[list|listall] istyle [style]
Set the current input style to style. If no style is specified, returns the current input style. To get a list of all available input styles in the current technology, use the listall istyle option. The list istyle option returns the current style name as a Tcl result.
[list|listall] ostyle [style]
Set the current output style to style. If no style is specified, returns the current output style. To get a list of all available output styles in the current technology, use the listall ostyle option. The list ostyle option returns the current style name as a Tcl result.
flat file
Output CIF format to "file" for the window's root cell, flattening the hierarchy prior to output.
read file
Read CIF format from file file into the edit cell. If file does not have a file extension, then magic searches for a file named file or file.cif.
write file
Output CIF format to "file" for the window's root cell.

Summary:

The cif command reads CIF input or produces CIF input/output ("Caltech Intermediate Format", as described in Mead & Conway), or sets various parameters affecting the CIF (and GDS) input and output. Certain cif command options also affect GDS input and output.

If no option is given, a CIF file is produced for the root cell, with the default name of the root cell definition and the filename extension ".cif".

Implementation Notes:

cif is implemented as a built-in function in magic. Options list and listall cause output to be returned as a Tcl result, rather than printed to stdout (the console).

See Also:

gds (calma)

Return to command index

Last updated: October 4, 2004 at 8:03am

magic-8.0.210/doc/html/center.html0000644000175000001440000000403710751423606015341 0ustar timusers center [x y] Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

center


Center the layout window view on the cursor lower-left coordinate, or the indicated coordinate if present.

Usage:

center [x y]

where x y is a coordinate in default magic units

Summary:

Without arguments, the center command centers the layout window on the lower-left corner of the cursor box. When values x and y are given, the view is centered on that coordinate. Coordinate values must be in (integer) units of the magic internal grid. This command is similar to the "view llx lly urx ury" command, which centers on a box instead of a point.

Implementation Notes:

center is implemented as a magic built-in command.

Bugs:

Coordinate values should be any acceptable value, including lambda, grid, and metric values, as they are for the box command.

See Also:

view

Return to command index

Last updated: October 4, 2004 at 3:59am

magic-8.0.210/doc/html/caption.html0000644000175000001440000000343210751423606015514 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

caption


Configures the titlebar of the GUI wrapper on a layout window

Usage:

caption layoutwindow

where layoutwindow is the Tk pathname of the layout window (not the top-level frame).

Summary:

The caption command is used by the GUI wrapper script and is normally not a user command. It configures the titlebar of the wrapper frame in a way that is similar to the titlebar in the original (non-Tcl, non-GUI) versions of magic. The style and contents of the titlebar may be changed by redefining this procedure in Tcl.

Implementation Notes:

caption is implemented as a Tcl script in the GUI wrapper.

See Also:

windowcaption

Return to command index

Last updated: October 3, 2004 at 8:01am

magic-8.0.210/doc/html/cellsearch.html0000644000175000001440000001004410751423606016161 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

cellsearch


Execute a TCL procedure on each cell definition or instance in the hierarchy

Usage:

cellsearch [instances] procedure

where procedure is the name of a predefined Tcl procedure (see Summary, below).

Summary:

The cellsearch command is a method for user access to the magic database search routines. It searches the hierarchical database for all cell definitions and applies the callback procedure to each. If the instances keyword is present, it searches the database for all cell instances and applies the callback procedure to each. The callback procedure must be defined as described below. Note that the callback method into Tcl is inherently slow and should only be used for non-compute-intensive tasks.

The Tcl callback procedure for the instances version of the cellsearch command is passed six values, the bounding box coordinates of the instance, the instance use name (id), and the name of the parent cell definition. The procedure must be defined to accept these six arguments, as in the following example:

	proc inst_callback {llx lly urx ury usename defname} {
	   puts stdout "Instance $usename of $defname bbox $llx $lly $urx $ury"
        }
     
The Tcl callback procedure for the cell definition search is passed one value, the name of the cell definition. The procedure must be defined to accept this single argument, as in the following example:
	proc def_callback {defname} {
	   puts stdout "Cell $defname"
        }
     

Implementation Notes:

cellsearch is implemented as an internal magic command that links to an external Tcl procedure as a callback function. This routine is experimental and subject to change without notice.

Bugs:

As currently implemented, there is no protection against calling a magic command from the callback procedure that will alter the internal cell hash table while it is being traversed, causing a crash. The implementation should be changed to a 2-step procedure that traverses the cell hash table first, creating an internal list of function arguments to pass for each cell, and then executes the callback function on each.

There are more efficient ways of executing the callback function than Tcl_EvalEx(). In particular, the procedure should be cast as a Tcl object and Tcl_EvalObjEx() used.

The callback function should allow in-line Tcl procedures and use the standard Tcl/Tk method of "%" escape sequences used as arguments to the callback function that allow the user to specify what arguments are passed to the callback function (as is done for the tag command).

See Also:

search

Return to command index

Last updated: October 4, 2004 at 5:05am

magic-8.0.210/doc/html/move.html0000644000175000001440000000531710751423606015031 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

move


Move the cursor box and the selection.

Shortcuts:

Key macro m implements the command move (no arguments).
Key macro Keypad-8 implements the command move n 1
Key macro Keypad-6 implements the command move e 1
(and so forth for all 8 compass rose directions).

Usage:

move [option]

where option is one of the following:
direction [distance]
Move the selection relative to the original position in the direction direction by an amount distance.
to x y
Move the selection to the coordinate location specified by the coordinate pair x y.

Summary:

The move command erases the current selection from its current position and moves it according to the command arguments. Without arguments, the lower-left hand corner of the selection is moved to the current cursor position (the X11 cursor, not the magic "cursor box"). With arguments direction and distance, the selection is moved relative to the original in the indicated direction by the indicated amount. The default distance is 1 unit (usually lambda; see distance for further explication).

Implementation Notes:

move is implemented as a built-in magic command.

See Also:

direction
distance

Return to command index

Last updated: October 7, 2004 at 3:19am

magic-8.0.210/doc/html/scalegrid.html0000644000175000001440000000445010751423606016015 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

scalegrid


Set the ratio of magic internal units to lambda units

Usage:

scalegrid a b

where a and b are integers.

Summary:

The scalegrid command sets the ratio of magic internal units to lambda units by rescaling the internal database and appropriate technology parameters. The values a and b are interpreted to mean that all positions in the database should be multiplied by the factor b / a. An equivalent meaning is that there should be b internal units per a lambda units in the database. For example,
scalegrid 1 2
means 2 internal units per lambda, or an internal grid that is twice as finely spaced as the default. The grid scaling can be queried using the tech lambda command. Grid scaling is interpreted relative to the current scale, so
scalegrid 1 2
scalegrid 1 2
results in 4 internal units per lambda.

Implementation Notes:

scalegrid is implemented as a built-in command in magic.

See Also:

snap
tech

Return to command index

Last updated: October 8, 2004 at 2:14am

magic-8.0.210/doc/html/get.html0000644000175000001440000000666510751423606014651 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

get, getcell


Import a cell as a subcell of the current edit cell.

Usage:

getcell cellname [orientation]

getcell cellname [child child_refpoint] [parent parent_refpoint]

where orientation may be one of the following:
90
Load rotated by 90 degrees clockwise
180
Load rotated by 180 degrees
270
Load rotated by 90 degrees counterclockwise
v
Load flipped top to bottom
h
Load flipped left to right
90v
Load rotated 90 degrees clockwise and flipped top to bottom
90h
Load rotated 90 degrees clockwise and flipped left to right
180v
Load rotated 180 degrees and flipped top to bottom
180h
Load rotated 180 degrees and flipped left to right
270v
Load rotated 90 degrees counterclockwise and flipped top to bottom
270h
Load rotated 90 degrees counterclockwise and flipped left to right
and child_refpoint and parent_refpoint may be x y coordinate pairs, or one of the four keywords ll, lr, ul, or ur, indicating one of the four box corners. For the child, coordinate pairs are in the coordinate system of the child, and corners indicate cell bounding box corners. For the parent, coordinate pairs are in the coordinate system of the parent, and corners indicate corners of the cursor box.

Summary:

The getcell command creates subcell instances within the current edit cell. By default, with only the cellname given, an orientation of zero is assumed, and the cell is placed such that the lower-left corner of the cell's bounding box is placed at the lower-left corner of the cursor box in the parent cell.

Implementation Notes:

getcell is implemented as a built-in command in magic.

get is an alias for the command getcell (allowed abbreviation where otherwise use would be ambiguous).

Scripts will find it more convenient to place cells according to the cell origin, with the usage "getcell cellname child 0 0".

See Also:

dump

Return to command index

Last updated: October 6, 2004 at 3:32am

magic-8.0.210/doc/html/exttosim.html0000644000175000001440000001417710751423606015743 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

ext2sim, exttosim


Convert extracted file(s) to a ".sim" format file.

Usage:

ext2sim [option]

where option is one of the following:
[run] [runtime_options]
Run exttosim on current cell, with command-line options (see Summary, below).
alias on|off
Enable/disable alias (.al) file
labels on|off
Enable/disable labels (.nodes) file
default
Reset to default values
format MIT|SU|LBL
Set output format
rthresh [value]
Set resistance threshold value. Lumped resistances below this value will not be written to the output. The value is in ohms, or may be the keyword infinite to prohibit writing any lumped resistances to the output.
cthresh [value]
Set capacitance threshold value. The value is in femtofarads, or may be the keyword infinite to prohibit writing any parasitic capacitances to the output.
merge [merge_option]
Merge parallel devices/transistors. The valid merge options are:
conservative
Merge transistors and capacitors having the same device type and node connections and having the same width and length. Widths are summed in the final output for transistors. Capacitor values are summed in the final output.
aggressive
Merge transistors having the same node connections and having the same length. Widths are summed in the final output. Merge any capacitors having the same device type and node connections. Capacitance is summed in the final output.
none
Do not merge any devices.
extresist on|off
Incorporate output from the command extresist into the final .sim file.
help
Print help information

Summary:

Without options, or with the option run, the ext2sim command converts the hierarchical extracted netlist information produced by the extract command in a series of .ext files into a flattened representation in the .sim format, used for switch-level simulation.

runtime_options may be passed on the command line, and represent the original command-line options passed to the standalone version of ext2sim. A number of the original command-line options have been deprecated in the Tcl-based version, and some are duplicated by other ext2sim options. Valid runtime_options are:

-B
Don't output transistor or node attributes in the .sim file. This option will also disable the output of information such as the area and perimeter of source and drain diffusion and the FET substrate.
-F
Don't output nodes that aren't connected to devices (floating nodes).
-tchar
Trim characters from node names when writing the output file. char should be either "#" or "!". The option may be used twice if both characters require trimming.
-y num
Select the precision for outputting capacitors. The default is 1 which means that the capacitors will be printed to a precision of 0.1 fF.
-J hier|flat
Select the source/drain area and perimeter extraction algorithm. If hier is selected then the areas and perimeters are extracted only within each subcell. For each device in a subcell the area and perimeter of its source and drain within this subcell are output. If two or more devices share a source/drain node then the total area and perimeter will be output in only one of them and the other will have 0. If flat is selected the same rules apply, only the scope of search for area and perimeter is the whole netlist. In general, flat (which is the default) will give accurate results (it will take into account shared sources/drains).
With options, the command sets various parameters affecting the output format and content.

Implementation Notes:

ext2sim is implemented as a separate loadable Tcl package, but one which depends on the presence of the standard "tclmagic" package. magic is set up with a placeholder command for ext2sim, and will automatically load the Tcl package when this command is invoked.

exttosim is an alias for ext2sim, to satisfy the grammatically anal retentive.

See Also:

extract
extresist
ext2spice
irsim

Return to command index

Last updated: October 12, 2005 at 9:40pm

magic-8.0.210/doc/html/netlist.html0000644000175000001440000000477610751423606015555 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

netlist


Netlist operations for use with the "netlist tool" in a layout window.

Usage:

netlist option

wher option may be one of the following:
help
Print usage information
select
Select the network nearest the cursor
join
Join the current network and the network containing the terminal nearest the cursor.
terminal
Toggle the terminal nearest the cursor into or out of the current network.

Summary:

The netlist command works with the "netlist tool" and is the interface between the layout window and the netlist window as generated by the "specialopen netlist" command. The command options, outlined above, allow interactive creation of netlists from a layout. Note that this is only interface code; most manipulation of the netlist is handled by the netlist window commands (see the section in the table of contents on the netlist window command set).

Implementation Notes:

netlist is implemented as a built-in command in magic. Prior to magic-7.3 revision 61, these functions were only available as built-in button callbacks. They have been changed to command-line commands with the switch to handling buttons like keys, with macro bindings.

See Also:

specialopen netlist

Return to command index

Last updated: November 10, 2004 at 10:44am

magic-8.0.210/doc/html/sleep.html0000644000175000001440000000302210751423606015162 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

sleep


Sleep for a number of seconds

Usage:

sleep seconds

where seconds is the number of seconds to sleep.

Summary:

The sleep command implements the UNIX system sleep() call to suspend the process for a number of seconds. This function is only particularly useful for demonstration purposes. In the Tcl version of magic, it is effectively superceded by the Tcl after command.

Implementation Notes:

sleep is implemented as a built-in command in magic.

Return to command index

Last updated: October 8, 2004 at 6:28am

magic-8.0.210/doc/html/changetool.html0000644000175000001440000001254210751423606016204 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

tool


Change the layout "tool" (button bindings). This page describes the version of the command used by the Tcl version of magic.

Shortcuts:

Key macro space implements the command tool.
Key macro shift-space implements the command tool box.

Usage:

tool [name|info]

where name may be one of box, wiring, netlist, or pick.

Summary:

The tool command selects or queries the mode of operation of the mouse buttons in the layout window. Each tool type has a unique set of button bindings.

Without arguments, the tool command selects the next tool type in round-robin fashion. With a tool type as argument, the button bindings switch to those for the indicated tool. With the info option, a summary of the commands bound to each mouse button is given for the current tool.

The default mouse bindings for each of the three tools is as follows:

  • Box Tool
    left
    Move the box so its lower-left corner is at cursor position
    right
    Resize box by moving upper-right corner to cursor position
    middle
    Paint box area with material underneath cursor
    In addition, you can move or resize the box by different corners by pressing left or right, holding it down, moving the cursor near a different corner and clicking the other (left or right) button down then up without releasing the initial button.
  • Wiring Tool
    left
    Pick wire material and size from under the cursor and begin interactive wire placement.
    right
    Cancel interactive wire placement.
    middle
    Place a wire at the position shown by the interactive wire tool highlight box, and continue interactive wire placement.
    shift-left
    Change the type of wire to the next plane (e.g., metal1 to metal2)
    shift-right
    Change the type of wire to the previous plane (e.g., metal2 to metal1)
    shift-middle
    Place a contact at the current location and switch to the wire type on the next plane.
    scrollwheel up
    Increase the wire size by one unit
    scrollwheel down
    Decrease the wire size by one unit
    Note that the methods for the wire tool differ significantly between Tcl-based magic, with its interactive capabilities, and non-Tcl-based magic.
  • Netlist Tool
    left
    Select the net containing the terminal nearest the cursor
    right
    Toggle the terminal nearest the cursor into/out of current net
    middle
    Join current net and net containing terminal nearest the cursor
  • Pick Tool
    left
    Remove the current selection from the layout, place it in the pick buffer, and follow the cursor.
    right
    Cancel the current pick buffer and stop following the cursor.
    middle
    Place a copy of the pick buffer at the current location, and continue following the cursor.
    shift-middle
    Make a copy of the current selection from the layout, place it in the pick buffer, and follow the cursor.
    The pick tool is an interactive feature only available in the Tcl-based version of magic.

Implementation Notes:

tool is implemented as a Tcl script in the Tcl-based version of magic. The command duplicates the function of the original tool command, which remains for the non-Tcl based version of magic, and which performs the function of changing the cursor style in the window.

Button functions for each "tool" may be added to or modified in the startup scripts. The Tcl variable Opts(tool) contains the current tool name, and may be used by a user tool procedure overriding the default one in "tools.tcl".

See Also:

tool (non-Tcl version)

Return to command index

Last updated: December 4, 2005 at 5:25pm

magic-8.0.210/doc/html/logcommands.html0000644000175000001440000000277010751423606016366 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

logcommands


Log all commands into a file

Usage:

logcommands [file [update]]

where file is the name of the log file to write to.

Summary:

The logcommands command tells magic to write all command-line commands and button pushes to the log file named file. If update is specified, a screen update is generated after each command executes.

Implementation Notes:

logcommands is implemented as a built-in command in magic.

Return to command index

Last updated: October 7, 2004 at 2:06am

magic-8.0.210/doc/html/direction.html0000644000175000001440000000412610751423606016040 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

direction


Valid direction options in magic

Summary:

Directions may be any valid known direction known to magic, including the following standard directions:
  • north, up, top
  • south, down, bottom
  • east, right
  • west, left
  • center
Directions may also be one of the combinations:
  • northeast
  • northwest
  • southeast
  • southwest
Directions may also be abbreviated. The following abbreviations are explicitly defined in magic, and all other abbreviations are accepted as long as the abbreviation can be uniquely identified (such as r for right and l for left).
  • n, u
  • s, d
  • e
  • w
  • ne, ur, tr
  • se, dr, br
  • sw, dl, bl
  • nw, ul, tl

See Also:

distance

Return to command index

Last updated: October 4, 2004 at 7:30am

magic-8.0.210/doc/html/upsidedown.html0000644000175000001440000000305310751423606016237 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

upsidedown


Flip selection and box upside down

Shortcuts:

Key macro F implements the command upsidedown.

Usage:

upsidedown

Summary:

The upsidedown command flips the selection from top to bottom. Flipping is done such that the lower left-hand corner of the selection remains in the same place through the flip.

Implementation Notes:

upsidedown is implemented as a built-in command in magic.

See Also:

sideways

Return to command index

Last updated: October 8, 2004 at 6:17am

magic-8.0.210/doc/html/distance.html0000644000175000001440000000357710751423606015663 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

distance


Valid distance specifications in magic.

Summary:

Distances are normally interpreted as lambda values. However, this depends on the last use of the snap command; snap internal changes the interpretation of units to the internal grid, while snap user changes the interpretation of units to the user grid. Distances may always be explicitly called out by appending one of the following to the distance value (with no intervening whitespace):
i
internal units
l
lambda units
um
microns
mm
millimeters
cu
centimicrons
In any case where the internal grid is finer than the declared distance measure, fractional distances may be specified; e.g.,
box move e 1.25um

See Also:

direction snap

Return to command index

Last updated: October 4, 2004 at 7:21am

magic-8.0.210/doc/html/crosshair.html0000644000175000001440000000336510751423606016061 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

crosshair


Implements a crosshair highlight on top of the layout.

Usage:

crosshair x y

crosshair off

Summary:

The crosshair command generates, moves, or removes a crosshair highlight in the layout window. Option off removes the crosshair, while coordinates x y place the crosshair at a specific layout location, creating the crosshair if it has been previously disabled. The crosshair is disabled by default upon startup.

Implementation Notes:

crosshair is implemented as a built-in window command in magic. The crosshair is available as an interactive feature in the Tcl/Tk version of magic from the "Options" menu. The commands above are executed in response to pointer motion events.

Return to command index

Last updated: December 4, 2005 at 5:05pm

magic-8.0.210/doc/html/pushstack.html0000644000175000001440000000340210751423606016061 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

pushstack


Load the selected cell and remember the action for later recall using popstack.

Shortcuts:

Key macro > implements the command pushstack.

Usage:

pushstack

Summary:

The pushstack command loads the selected cell into the layout window. However, unlike the load command, the pushstack command remembers the action by saving the currently loaded cell on a stack, so it can be recalled with the popstack command. Due to the stack implemention, calls may be nested.

Implementation Notes:

pushstack is implemented as a Tcl procedure in the "tools" script.

See Also:

popstack

Return to command index

Last updated: October 16, 2004 at 2:08pm

magic-8.0.210/doc/html/xview.html0000644000175000001440000000307610751423606015225 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

xview


Change the view in the current layout window so that everything is visible but unexpanded.

Usage:

xview

Summary:

The xview command changes the view so that the layout fits the window, as in the view command, but ensures that all cells are unexpanded. This is useful for large layouts where the full view can take a long time to refresh.

Implementation Notes:

xview is implemented as a built-in command in magic.

See Also:

view
xload

Return to command index

Last updated: October 9, 2004 at 7:17am

magic-8.0.210/doc/html/contact.html0000644000175000001440000000326310751423606015514 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

contact


Paint a contact at the intersection of two layers.

Usage:

contact type

Summary:

The contact command computes the intersection area (inside the cursor box) of the two (or more) residue types that make up the contact type type, and paints the contact type type on top of the area of intersection.

Implementation Notes:

contact is implemented as a built-in layout command in magic. As of magic version 7.3.115 this command does not correctly translate the cursor box for edit cells and may paint outside of the cursor box, with random results.

See Also:

paint

Return to command index

Last updated: December 4, 2005 at 8:18pm

magic-8.0.210/doc/html/render3d.html0000644000175000001440000000315010751423606015562 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

render3d


Create a top-level GUI frame for handling the 3D display window.

Usage:

render3d

Summary:

The render3d command creates a Tk top-level window for handling the 3D display window. Currently, the window is rudimentary and does essentially nothing more than the specialopen wind3d command does.

Implementation Notes:

render3d is implemented as a Tcl procedure in the "wrapper" script. This is basically a placeholder for a more complete GUI frame for manipulating the 3D view.

See Also:

specialopen

Return to command index

Last updated: November 10, 2004 at 1:09pm

magic-8.0.210/doc/html/updatedisplay.html0000644000175000001440000000401010751423606016720 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

updatedisplay


Force display update, or suspend/resume updates

Usage:

updatedisplay [suspend|resume]

Summary:

The updatedisplay command allows the display redraw to be suspended and resumed. The main situation where this is useful is inside a script or series of commands, where it is not desired to have the display refresh at each step. Areas needing to be redrawn will accumulate and be processed all at once when updatedisplay resume is called.

Calls to updatedisplay suspend can be nested, so that the display will not update until the same number of calls to updatedisplay resume have been encountered.

Without arguments, updatedisplay forces an immediate display redraw.

Implementation Notes:

updatedisplay is implemented as a built-in window command in magic.

See Also:

suspendall
resumeall

Return to command index

Last updated: October 9, 2004 at 1:45am

magic-8.0.210/doc/html/dump.html0000644000175000001440000000440710751423606015027 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

dump


Copy contents of the indicated cell into the current edit cell.

Usage:

dump cell [child child_refpoint] [parent parent_refpoint]

where cell is the name of the cell whose contents are to be copied, and optional child_refpoint and parent_refpoint are coordinate pairs of x y values, or keywords ll, lr, ul, or ur. The syntax and use of the reference points is the same as for the getcell command.

Summary:

The dump command copies contents of the indicated cell cell into the current edit cell. Without arguments, the contents are placed such that the lower left coordinate of cell is at the cursor box lower left corner. With the child argument, the indicated coordinate position child_refpoint is used instead of the lower-left corner. With the parent argument, the indicated coordinate position parent_refpoint is used instead of the lower-left corner of the cursor box.

Implementation Notes:

dump is implemented as a built-in command in magic.

See Also:

getcell

Return to command index

Last updated: October 6, 2004 at 2:53am

magic-8.0.210/doc/html/cursor.html0000644000175000001440000000361210751423606015374 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

cursor


Return magic internal coordinates of the cursor (X11 pointer)

Usage:

cursor

Summary:

The cursor command returns the current position of the cursor (the X11 pointer, not the magic cursor box) in internal layout coordinates.

Implementation Notes:

cursor is implemented as a built-in window command in magic. In the Tcl version of magic, it returns a Tcl result (list of two elements, x and y coordinates).

Like all window commands, it reports relative to the existing window if only one window is present, or the active window if called with the ":" macro. Otherwise, it must be called using the tk_path_name command to specify relative to which layout window the cursor coordinates will be given.

See Also:

tk_path_name

Return to command index

Last updated: October 5, 2004 at 2:47am

magic-8.0.210/doc/html/Makefile0000644000175000001440000000040410751423606014625 0ustar timusersMAGICDIR = ../.. include $(MAGICDIR)/defs.mak HTML_INSTDIR=$(LIBDIR)/magic/doc/html install: $(DESTDIR)${HTML_INSTDIR} tar cf - . | (cd $(DESTDIR)${HTML_INSTDIR}; tar xf - ) $(DESTDIR)${HTML_INSTDIR}: ${SCRIPTS}/mkdirs $(DESTDIR)${HTML_INSTDIR} clean: magic-8.0.210/doc/html/specialopen.html0000644000175000001440000000466310751423606016370 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

specialopen


Open a window of a specific type.

Usage:

specialopen type [arguments]

where type may be one of the following:
layout
Open a layout window. Equivalent to the openwindow command.
wind3d tk_path_name
Generate the 3D window. Only available when using OpenGL graphics ("magic -d OGL"). The tk_path_name argument allows the window to be inserted into a Tk frame instead of generated directly on the desktop.
color
Open a window allowing layout colors to be edited.
netlist
Open a window allowing interactive definition of netlists.

Summary:

The specialopen command opens one of several special-purpose windows known to magic, as well as the default layout window. Each window has a set of commands associated with it. The layout window commands are listed in this reference guide along with the general-purpose commands, because the layout window is the most common type. For the command sets of the other special-purpose windows, see the sections on the colormap, netlist, and 3D rendering.

Implementation Notes:

specialopen is implemented as a built-in window command in magic.

See Also:

openwindow

Return to command index

Last updated: October 8, 2004 at 7:29am

magic-8.0.210/doc/html/calma.html0000644000175000001440000002037510751423606015141 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

gds, calma


Read GDSII input or generate GDSII output.

Usage:

gds [option]

calma [option]

where option is one of the following:
help
Print usage information
arrays [yes|no]
Output arrays as individual subuses (like in CIF). Default is "no". Normally there is no reason to do this.
contacts [yes|no]
Causes contacts to be written to the GDS file as subcell arrays (experimental, introduced in version 7.3.55). This method can produce very efficient output compared to writing each contact cut square separately.
flatten [yes|no]
Flatten simple cells (e.g., contacts) on input. This helps magic to use its contact-area representation of contacts, and can also avoid situations where contacts are lost or translated to "generic" types because the arrayed part of the contacts is missing one or more residue layers.
ordering [yes|no]
Forces post-ordering of subcells read from a GDS file; that is, if a cell use is encountered before it is defined, magic will read through the remainder of the file until it finds the definition, read it, and then return to the original file position to continue reading. This option is always enabled when using gds flatten. Otherwise, the default behavior is ordering no to avoid lengthy searches through the GDS stream file.
labels [yes|no]
Cause labels to be output when writing GDSII. Default is "yes". Normally there is no reason not to do this.
lower [yes|no]
Allow both upper and lower case in labels. Default is "yes".
read file
Read GDSII format from file file into the edit cell. If file does not have a file extension, then magic searches for a file named file, file.gds, file.gds2, or file.strm.
readonly [yes|no]
Set cell as "read-only". This has the effect of marking each cell definition (using the property method) with the start and end positions of the cell definition in the input file. In subsequent output, the cell definition will be transferred verbatim from the input to the output file. This is useful for 3rd-party standard cells or pad cells where the original GDS is trusted and it is desirable to bypass the boolean operators of magic's GDS reader and writer to prevent the layout from being altered. Note that "read-only" layout can be written to a .mag file, but the contents of this file are representational only. It can be useful to keep a simplified respresentation in the case of pad cells or digital standard cells, for example, by reading them using a GDS input style that defines only metal layers.
rescale [yes|no]
Allow or disallow internal grid subdivision while reading GDS input. Default is "yes". Normally, one wants to allow rescaling to ensure that the GDS is displayed exactly as it is in the input file. Occasionally, however, the GDS input is on a very fine scale, such as nanometers, and it is preferable to snap the input to lambda boundaries rather than to subsplit the internal grid to such a fine value. The "cif limit" function may also be used to limit grid subdivision to a minimum value.
warning [option]
Set warning information level. "option" may be one of the following:
default
The default setting is equivalent to all the other options (align, limit, redirect, and none) being disabled.
align
Generate warnings during a "cif see" command if the alignment of geometry is on fractional lambda. Normally, magic allows contacts to be drawn at half-lambda positions. If this violates DRC requirements for the minimum output grid, this warning setting can be used to detect such violations.
limit
Limit warnings to the first 100 warnings or errors only.
redirect [file]
Redirect all warnings to an output file named file. If file is not given, then redirection is disabled.
none
Do not produce any warning messages on GDS input.
write file
Output GDSII format to "file" for the window's root cell.
polygon subcells [yes|no]
Put non-Manhattan polygons into subcells. Default is "no". Normally this option is not needed. However, input layout that defines a number of angled wires, particularly those that are closely spaced, can cause magic to generate literally millions of internal tiles. This tends to be true in particular for corner cells in padframes for deep submicron feature sizes, where the angled corners are required to meet the DRC specification. When set to "yes", each polygon encountered in the GDS input is placed in its own uniquely-named subcell. This prevents interations with other polygons on the same plane and so reduces tile splitting.

Summary:

The gds command reads or produces GDSII output (also known as "stream" output, or "calma" output after the name of the company that invented the format), or sets various parameters affecting the GDS input and output. In magic, the GDS read and write routines are a subset of the CIF read and write routines, and so it is important to note that certain cif command options (q.v.) also affect GDS input and output. In particular, cif istyle and cif ostyle set the input and output styles from the technology file, respectively.

If no option is given, a CALMA GDS-II stream file is produced for the root cell, with the default name of the root cell definition and the filename extension ".gds".

Implementation Notes:

gds is implemented as a built-in function in magic. The calma command is an alias for gds and is exactly equivalent.

Bugs:

  • The cif command options that affect GDS input and output should really be duplicates as options of the GDS command.
  • GDS input is "interpreted" through boolean operations in the technology file definition, and so it is not guaranteed that all input will be read correctly.
  • Not all non-Manhattan geometry is read correctly.
  • The input can be fouled up if the magic grid is rescaled during input. This error can be avoided by scaling the grid prior to GDS read-in.
  • "polygon subcells" in GDS creates a duplicate image of the layout read into the subcells; this needs to be fixed.

See Also:

cif

Return to command index

Last updated: December 4, 2005 at 3:17pm

magic-8.0.210/doc/html/def.html0000644000175000001440000000542510751423606014621 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

def


Read or write DEF format files.

Usage:

def option

where option is one of the following:
read [filename]
Read a DEF file filename[.def]
write [cell]
Write DEF for current or indicated cell named cell
help
Print help information (command summary)

Summary:

The def command reads and writes DEF format files. These files are generally assumed to be digital standard-cell based layouts. The DEF format has no real concept of hierarchy. To generate a valid DEF file that may be recognized by other software, it is necessary to have a layout with standard cells using the port method to declare input and output ports. In particular, the port class and port use are designed to work with the DEF read and write routines.

The technology file should have a lef section describing how LEF and DEF files should be written. However, if an appropriate LEF file exists and is read prior to writing a DEF format file, the technology will be initialized from the file if it is not declared in the technology file.

Implementation Notes:

def is implemented as a built-in magic command. Only the critical part of the DEF definition has been implemented. Some uncommon forms of syntax such as wire extensions are not implemented. This is largely due to the incomplete nature of the LEF/DEF spec. It is unlikely that such forms will be encountered in third-party input.

See Also:

lef
port

Return to command index

Last updated: October 7, 2004 at 1:45am

magic-8.0.210/doc/html/startup.html0000644000175000001440000000327410751423606015565 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

startup


Start magic from inside the Tcl interpreter.

Usage:

startup

Summary:

The startup command is not a user command. It is called by Tcl packages that wish to use magic from the interpreter. The procedure for starting magic is as follows:
  • Load the tclmagic.so object file.
  • Call initialize with arguments passed to magic on the command line.
  • Call startup

Implementation Notes:

startup is implemented as a built-in command in magic, but only defined by the Tcl version.

See Also:

initialize

Return to command index

Last updated: October 8, 2004 at 8:00am

magic-8.0.210/doc/html/gds.html0000644000175000001440000002037510751423606014641 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

gds, calma


Read GDSII input or generate GDSII output.

Usage:

gds [option]

calma [option]

where option is one of the following:
help
Print usage information
arrays [yes|no]
Output arrays as individual subuses (like in CIF). Default is "no". Normally there is no reason to do this.
contacts [yes|no]
Causes contacts to be written to the GDS file as subcell arrays (experimental, introduced in version 7.3.55). This method can produce very efficient output compared to writing each contact cut square separately.
flatten [yes|no]
Flatten simple cells (e.g., contacts) on input. This helps magic to use its contact-area representation of contacts, and can also avoid situations where contacts are lost or translated to "generic" types because the arrayed part of the contacts is missing one or more residue layers.
ordering [yes|no]
Forces post-ordering of subcells read from a GDS file; that is, if a cell use is encountered before it is defined, magic will read through the remainder of the file until it finds the definition, read it, and then return to the original file position to continue reading. This option is always enabled when using gds flatten. Otherwise, the default behavior is ordering no to avoid lengthy searches through the GDS stream file.
labels [yes|no]
Cause labels to be output when writing GDSII. Default is "yes". Normally there is no reason not to do this.
lower [yes|no]
Allow both upper and lower case in labels. Default is "yes".
read file
Read GDSII format from file file into the edit cell. If file does not have a file extension, then magic searches for a file named file, file.gds, file.gds2, or file.strm.
readonly [yes|no]
Set cell as "read-only". This has the effect of marking each cell definition (using the property method) with the start and end positions of the cell definition in the input file. In subsequent output, the cell definition will be transferred verbatim from the input to the output file. This is useful for 3rd-party standard cells or pad cells where the original GDS is trusted and it is desirable to bypass the boolean operators of magic's GDS reader and writer to prevent the layout from being altered. Note that "read-only" layout can be written to a .mag file, but the contents of this file are representational only. It can be useful to keep a simplified respresentation in the case of pad cells or digital standard cells, for example, by reading them using a GDS input style that defines only metal layers.
rescale [yes|no]
Allow or disallow internal grid subdivision while reading GDS input. Default is "yes". Normally, one wants to allow rescaling to ensure that the GDS is displayed exactly as it is in the input file. Occasionally, however, the GDS input is on a very fine scale, such as nanometers, and it is preferable to snap the input to lambda boundaries rather than to subsplit the internal grid to such a fine value. The "cif limit" function may also be used to limit grid subdivision to a minimum value.
warning [option]
Set warning information level. "option" may be one of the following:
default
The default setting is equivalent to all the other options (align, limit, redirect, and none) being disabled.
align
Generate warnings during a "cif see" command if the alignment of geometry is on fractional lambda. Normally, magic allows contacts to be drawn at half-lambda positions. If this violates DRC requirements for the minimum output grid, this warning setting can be used to detect such violations.
limit
Limit warnings to the first 100 warnings or errors only.
redirect [file]
Redirect all warnings to an output file named file. If file is not given, then redirection is disabled.
none
Do not produce any warning messages on GDS input.
write file
Output GDSII format to "file" for the window's root cell.
polygon subcells [yes|no]
Put non-Manhattan polygons into subcells. Default is "no". Normally this option is not needed. However, input layout that defines a number of angled wires, particularly those that are closely spaced, can cause magic to generate literally millions of internal tiles. This tends to be true in particular for corner cells in padframes for deep submicron feature sizes, where the angled corners are required to meet the DRC specification. When set to "yes", each polygon encountered in the GDS input is placed in its own uniquely-named subcell. This prevents interations with other polygons on the same plane and so reduces tile splitting.

Summary:

The gds command reads or produces GDSII output (also known as "stream" output, or "calma" output after the name of the company that invented the format), or sets various parameters affecting the GDS input and output. In magic, the GDS read and write routines are a subset of the CIF read and write routines, and so it is important to note that certain cif command options (q.v.) also affect GDS input and output. In particular, cif istyle and cif ostyle set the input and output styles from the technology file, respectively.

If no option is given, a CALMA GDS-II stream file is produced for the root cell, with the default name of the root cell definition and the filename extension ".gds".

Implementation Notes:

gds is implemented as a built-in function in magic. The calma command is an alias for gds and is exactly equivalent.

Bugs:

  • The cif command options that affect GDS input and output should really be duplicates as options of the GDS command.
  • GDS input is "interpreted" through boolean operations in the technology file definition, and so it is not guaranteed that all input will be read correctly.
  • Not all non-Manhattan geometry is read correctly.
  • The input can be fouled up if the magic grid is rescaled during input. This error can be avoided by scaling the grid prior to GDS read-in.
  • "polygon subcells" in GDS creates a duplicate image of the layout read into the subcells; this needs to be fixed.

See Also:

cif

Return to command index

Last updated: December 4, 2005 at 3:17pm

magic-8.0.210/doc/html/openwindow.html0000644000175000001440000000515710751423606016256 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

openwindow


Open a new (non-GUI) layout window with indicated name, bound to indicated cell

Shortcuts:

Key macro o implements the command openwindow. This macro is disabled when using the GUI wrapper.

Usage:

openwindow [cell] [name]

where cell is the name of a cell to be loaded into the new window, and name is the Tk path name of a top-level window (see below). An empty string or Tcl NULL list "{}" for cell will cause the default cell "(UNNAMED)" to be loaded.

Summary:

The openwindow command opens a new layout window. Without arguments, a new layout window named "magicn" is created, where n is the index of the nth window to be created. Without a named cell, the new window is loaded with a copy of the cell that was present in the last generated layout window.

The use of parameter name is used in conjunction with a wrapper script to attach the layout window to an existing Tk frame window.

Implementation Notes:

openwindow is implemented as a built-in magic window command. It should not be used with the GUI wrapper (invoked with magic -w); instead, the openwrapper function should be used. Note that it is possible to use this command in batch mode, although there is no useful reason to do so.

See Also:

closewindow
openwrapper

Return to command index

Last updated: December 4, 2005 at 9:03pm

magic-8.0.210/doc/html/array.html0000644000175000001440000001114010751423606015170 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

array


Array everything in the current selection

Usage:

array option

where option is one of the following:
xsize ysize
Array the selection with xsize copies in the x (horizontal) direction and ysize copies in the y (vertical) direction. Array pitch is determined by the current cursor box.
xlo xhi ylo yhi
Array the selection with indices xlo, xhi, ylo, and yhi inclusive. Thus, (xhi - xlo + 1) copies will be created in the x direction and (yhi - ylo + 1) copies will be created in the y direction. Arrayed cell uses will be numbered according to the indices. Array pitch is determined by the current cursor box.
count [[xlo] xhi [ylo] yhi]
With no arguments, returns the array indices of the currently selected cell. With arguments, is equivalent to the first two options (see above).
width [value]
With no arguments, returns the array spacing in x of the currently selected cell. With arguments, redefines the spacing in x between cells in the array.
height [value]
With no arguments, returns the array spacing in y of the currently selected cell. With arguments, redefines the spacing in y between cells in the array.
pitch [x y]
With no arguments, returns the array spacing in x and y of the currently selected cell. With arguments, redefines the spacing in x and y between cells in the array.
position [x y]
With no arguments, returns the position of the array origin. With arguments, redefines the array origin.
help
Print help information

Summary:

The array command creates multiple copies of the current paint selection. In the case of selected paint, only the first two options are available, and the function makes multiple copies of the selected paint in the x and/or y direction(s). In the case of selected cells, the cell is copied multiple times but is maintained in the database as an array type, rather than multiple individual uses. As an array type, certain functions such as move or copy operate on the array as a single unit, and subsequent calles to the array command may resize the array.

The cursor box defines the pitch between cells or paint copies in the array. The height of the box is the pitch in y, and the width of the box is the pitch in x.

The Tcl version allows useful constructs on the command line such as:

array width [expr {1 + [array width]}]
move s [array height]
The first example expands the pitch of the array by 1 unit in the x direction without requiring explicitly sizing the cursor box to match the array pitch. The second example moves the array down by the y

Implementation Notes:

array is implemented as a magic built-in command. Command options which return values from a selected array generate Tcl results in the Tcl version of magic.

Return to command index

Last updated: October 16, 2004 at 2:20pm

magic-8.0.210/doc/html/invoke.html0000644000175000001440000001115210751423606015350 0ustar timusers

Magic version 7.3 Usage

Basic usage:

magic [-noc[onsole]] [-w[rapper]] [-d devType] [-T technology] [file]

where:

-noconsole
(Tcl version only) Uses the calling terminal for terminal-based command-line input. Otherwise, a Tk console window is used.
-wrapper
(Tcl version only) Magic layout windows use the GUI wrapper, including cell and technology manager windows, layer toolbar, and file menu.
-d devType

(all versions) Select the graphics interface at runtime. Specifying an invalid devType will result in a list of known types. The possible values of devType are determined at compile time, but the usual ones are NULL (no graphics), X11, and OpenGL. X11 is the usual default.
-T technology
(all versions) Select the appropriate technology (.tech27) file. At present (this is on the to-do list), magic cannot change technology after startup. So the technology file corresponding to the layout to be loaded must be supplied to the command line at startup. The default technology is scmos, which is included with the magic source distribution. The complete list of available technology files depends on what has been installed on the system (see the technology file page for details).
file
(all versions) Load the layout (.mag) file file into the layout window on startup.
Complete usage information:

magic [-noc[onsole]] [-w[rapper]] [-nowindow] [-d devType] [-T technology] [-m monType] [-D] [file]
where the additional options not covered above are:

-nowindow
(Tcl version only) Run without displaying an initial layout window. This is used mainly for GUI wrapper scripts which like to generate and handle their own windows.
-m monType
(obscure) monType names a monitor type. This is used in the search for the colomap file name, which is designated <tech>.<planes>.<mon>.cmap1. The default is "std" (corresponding to colormap file "mos.7bit.std.cmap1". The only other monitor type for which colormaps exist in the distribution is "mraster". This provides a way for users to override the system color assignments.
-D
(all versions) Run in Debug mode.
Obsolete usage information:

magic [-g gPort] [-i tabletPort] [-F objFile saveFile] ...
where the additional options not covered above are:

-g gPort
(largely obsolete) gPort names a device to use for the display. This was generally used in the past with dual-monitor systems, especially Sun systems in which the layout display might go to /dev/fb.
-i tabletPort
(largely obsolete) tabletPort names a device to use for graphics input. This has not been tested with modern graphics tablet devices. It is ignored by the X11 and OpenGL display interfaces.
-F objFile saveFile
(largely obsolete) Create an executable file of the current magic process, a core image snapshot taken after all initialization. objFile is the name of the original executable, and the image will be saved in saveFile. This only works on VAXen and SUNs running an old SunOS (using a.out executables).
magic-8.0.210/doc/html/peekbox.html0000644000175000001440000000310610751423606015512 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

peekbox


Query the last saved cursor box position

Usage:

peekbox

Summary:

The peekbox command sets the cursor box to the position of the box last saved with the pushbox command. This is like the popbox command except that the box is left on the stack.

Implementation Notes:

peekbox is implemented as a Tcl procedure in the "tools" script. It is useful when writing automated layout-generating Tcl scripts.

See Also:

pushbox
popbox

Return to command index

Last updated: October 7, 2004 at 5:59am

magic-8.0.210/doc/html/property.html0000644000175000001440000000420510751423606015742 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

property


Attach a "property" (string key and value pair) to the edit cell

Usage:

property [key [value]]

where key and value are any text strings.

Summary:

The property command implements a general-purpose method of attaching information to a cell definition. Except for a few properties known to the lef and gds commands (q.v.), properties have no inherent meaning to magic but may be used with other programs or scripts to add additional information about a cell definition.

With no arguments, all properties of the current edit cell are listed. With only the key argument, the value associated with the key is returned. With both arguments, the string value is associated with the string key as a property of the cell. If key is an existing key, then its original value will be overwritten.

Implementation Notes:

property is implemented as a built-in command in magic. The property structure itself is implemented as a hash table in the cell definition structure.

Return to command index

Last updated: December 4, 2005 at 8:05pm

magic-8.0.210/doc/html/popbox.html0000644000175000001440000000303410751423606015364 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

popbox


Retrieve the last saved cursor box position

Usage:

popbox

Summary:

The popbox command sets the cursor box to the position of the box last saved with the pushbox command, removing the saved position from the stack.

Implementation Notes:

popbox is implemented as a Tcl procedure in the "tools" script. It is useful when writing automated layout-generating Tcl scripts.

See Also:

pushbox
peekbox

Return to command index

Last updated: October 7, 2004 at 6:07am

magic-8.0.210/doc/html/box.html0000644000175000001440000001317110751423606014650 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

box


Move box dist units in direction or (with no arguments) show box size.

Shortcuts:

Key macro b implements the command box (with no arguments), which prints information about the box to the console (terminal stdout).

Usage:

box [option]

where option is one of the following:
[direction [distance]]
Move the box in the indicated direction by the indicated distance.
width [width]
Set or return box width
height [height]
Set or return box height
size [width height]
Set or return box size
position [llx lly] [-edit]
Set or return box position
values [llx lly urx ury] [-edit]
Set or return box coordinates.
move direction distance|cursor
Move box position
grow direction distance
Expand box size
shrink direction distance
Shrink box size
corner direction distance|cursor
Reposition a box corner
exists
Is the cursor box present?
help
Print help information

Summary:

The box command, with no arguments, prints information about the current position and size of the cursor box to the console (terminal stdout). The output shows the lower-left and upper-right coordinates of the box, plus the box width, height, and area. These coordinates and dimensions are shown both in microns and in lambda units. If the internal grid has been subdivided to a finer grid than lambda, then internal units will also be reported.

With arguments, the box command adjusts the position and dimensions of the cursor box as outlined in the Usage section (see above). The -edit switch causes coordinate values to be reported relative to the origin of the current edit cell, if the edit cell is not the topmost cell in the layout window.

For a discussion of valid distances, see the page distance. This includes dimensional values such as width and height, e.g.,

box width 1.2um
Note that because metric dimensions do not always match lambda dimensions, the dimension may be rounded down to the nearest lambda. This is important in case this use of box is intended to meet some DRC requirement. For the options move and corner, the distance may be the keyword "cursor", indicating that the box should be moved or the corner repositioned to the position of the cursor. These versions of the command implement the standard mouse button bindings for the "box tool" in layout windows.

For a discussion of valid directions, see the page direction. Note that special cases box grow center and box shrink center will cause the box to expand or shrink on all sides, whereas box move center is nonfunctional. Also, the box corner command expects the direction to be a nonmanhattan direction (ur, bl, etc.), indicating the corner to be repositioned.

Implementation Notes:

box is implemented as a magic built-in command. Command options with keywords and no arguments return Tcl results in the Tcl version of magic. However, to be backwardly compatible with versions of magic prior to 7.3, the box command with no arguments prints information directly to stdout (the command-line console). The separate option box values is provided to return the two box coordinates (lower-left and upper-right) as a Tcl list.

The use of returned Tcl values allows various useful constructs on the command-line, such as:

box move e [box width] box height [box width]
The first example moves the box to the right by the width of the box, while the second example makes the box square by adjusting the height to match the width.

See Also:

snap scalegrid

Return to command index

Last updated: November 8, 2004 at 2:53pm

magic-8.0.210/doc/html/commands.list0000644000175000001440000000176710751423606015700 0ustar timusersaddcommandentry addpath array box calma caption cellmanager cellname cellsearch center channels cif clockwise closewindow closewrapper copy corner cursor def delete deletecommandentry down drc dump edit element erase expand ext ext2sim ext2spice extract extresist exttosim exttospice feedback fill findbox findlabel flatten flush garoute gds get getcell getnode gmacro goto grid grow help identify imacro initialize instance iroute label lef load logcommands macro maketoolbar move openwindow openwrapper paint path peekbox plot plow popbox popstack port promptload promptsave property pushbox pushbutton pushstack quit redo redraw render reset resumeall rotate route save scalegrid scroll search see select setpoint shell sideways sleep snap specialopen spliterase splitpaint startup straighten stretch suspendall tag tech techmanager tool undo unexpand updatedisplay upsidedown version view what windowborder windowcaption windownames windowpositions windowscrollbars wire writeall xload xview zoom tk_path_name magic-8.0.210/doc/html/maketoolbar.html0000644000175000001440000000611410751423606016357 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

maketoolbar


Generate the GUI layout window toolbar.

Shortcuts:

Menu item Options->Toolbar implements the command maketoolbar.

Usage:

maketoolbar frame_name

where frame_name is the Tk path name of a GUI layout window frame (e.g., ".layout1", ".layout2").

Summary:

The maketoolbar command generates the toolbar for the GUI layout window. The toolbar contains a set of buttons representing each layer type in the technology file. Each toolbar button has bindings for mouse buttons and keys to implement shortcut commands in magic. While the mouse pointer is inside the boundary of the toolbar button, the name of the layer represented by the toolbar is printed in the title bar of the window.


Figure 1. The GUI toolbar for the default scmos technology.
The default bindings for the toolbar buttons and the magic commands they invoke are as follows:
Button-1
see layername
Button-3
see no layername
Button-2
paint layername
Shift-Button-2
erase layername
Key-p
paint layername
Key-e
erase layername
Key-s
select more area layername
Key-S
select less area layername
The toolbar is not present on window startup due to timing problems with several window managers that prevents the correct measurement of window height.

Implementation Notes:

maketoolbar is implemented as a Tcl procedure in the GUI wrapper script.

Return to command index

Last updated: October 7, 2004 at 3:12am

magic-8.0.210/doc/html/tool.html0000644000175000001440000000722710751423606015042 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

tool


Change layout tool or print information about what the button bindings are for the current tool. This page describes the tool command as implemented in the non-Tcl version of magic.

Shortcuts:

Key macro space implements the command tool.
Key macro shift-space implements the command tool box.

Usage:

tool [name|info]

where name may be one of box, wiring, netlist, or rsim.

Summary:

The tool command selects or queries the mode of operation of the mouse buttons in the layout window. Each tool type has a unique set of button bindings.

Without arguments, the tool command selects the next tool type in round-robin fashion. With a tool type as argument, the button bindings switch to those for the indicated tool. With the info option, a summary of the mouse buttons is given for the current tool.

The mouse bindings for each of the three tools is as follows:

  • Box Tool
    left
    Move the box so its lower-left corner is at cursor position
    right
    Resize box by moving upper-right corner to cursor position
    middle
    Paint box area with material underneath cursor
    In addition, you can move or resize the box by different corners by pressing left or right, holding it down, moving the cursor near a different corner and clicking the other (left or right) button down then up without releasing the initial button.
  • Wiring Tool
    left
    Pick a wiring layer and width (same as "wire type")
    right
    Add a leg to the wire (same as "wire leg")
    middle
    Place a contact to switch layers (same as "wire switch")
  • Netlist Tool
    left
    Select the net containing the terminal nearest the cursor
    right
    Toggle the terminal nearest the cursor into/out of current net
    middle
    Join current net and net containing terminal nearest the cursor
  • Rsim Tool
    left
    right
    middle

Implementation Notes:

tool is implemented as a built-in command in the non-Tcl version of magic.

See Also:

tool (Tcl version)

Return to command index

Last updated: December 4, 2005 at 5:11pm

magic-8.0.210/doc/html/closewindow.html0000644000175000001440000000426510751423606016421 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

closewindow


Close a (non-GUI) window

Shortcuts:

Key macro O implements the command closewindow. This macro is disabled when using the GUI wrapper.

Usage:

closewindow [name]

where name is the name of a window.

Summary:

The closewindow command closes a window. Without arguments, if only one window is present, that window will be closed. Otherwise, if multiple windows are present, the window to be closed must be specified by name.

closewindow closes both layout windows created with the openwindow command or windows created with the specialopen command.

Implementation Notes:

closewindow is implemented as a built-in magic window command. It should not be used with the GUI wrapper (invoked with magic -w); instead, the closewrapper function should be used.

See Also:

openwindow
specialopen
closewrapper

Return to command index

Last updated: November 10, 2004 at 6:08pm

magic-8.0.210/doc/html/garoute.html0000644000175000001440000000431710751423606015530 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

garoute


Gate-array router

Usage:

garoute option

where option may be one of the following:
channel xl yl xh yh [type]
Define a channel, with indicated coordinates.
channel [type]
Define a channel
generate h|h [file]
Generate channel definition for a horizontal (h) or vertical (v) routing channel.
help
Print help information
nowarn
Only warn if all locations of a terminal are unreachable.
route [netlist]
Route the current cell
reset
Clear all channel definitions
warn
Leave feedback for each location of a terminal that is unreachable.

Summary:

The garoute command controls the gate-array router. There is currently practically no documentation for the gate-array router. This section shall be expanded.

Implementation Notes:

garoute is implemented as a built-in command in magic.

See Also:

channel

Return to command index

Last updated: October 6, 2004 at 2:35am

magic-8.0.210/doc/html/ext2sim.html0000644000175000001440000001417710751423606015462 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

ext2sim, exttosim


Convert extracted file(s) to a ".sim" format file.

Usage:

ext2sim [option]

where option is one of the following:
[run] [runtime_options]
Run exttosim on current cell, with command-line options (see Summary, below).
alias on|off
Enable/disable alias (.al) file
labels on|off
Enable/disable labels (.nodes) file
default
Reset to default values
format MIT|SU|LBL
Set output format
rthresh [value]
Set resistance threshold value. Lumped resistances below this value will not be written to the output. The value is in ohms, or may be the keyword infinite to prohibit writing any lumped resistances to the output.
cthresh [value]
Set capacitance threshold value. The value is in femtofarads, or may be the keyword infinite to prohibit writing any parasitic capacitances to the output.
merge [merge_option]
Merge parallel devices/transistors. The valid merge options are:
conservative
Merge transistors and capacitors having the same device type and node connections and having the same width and length. Widths are summed in the final output for transistors. Capacitor values are summed in the final output.
aggressive
Merge transistors having the same node connections and having the same length. Widths are summed in the final output. Merge any capacitors having the same device type and node connections. Capacitance is summed in the final output.
none
Do not merge any devices.
extresist on|off
Incorporate output from the command extresist into the final .sim file.
help
Print help information

Summary:

Without options, or with the option run, the ext2sim command converts the hierarchical extracted netlist information produced by the extract command in a series of .ext files into a flattened representation in the .sim format, used for switch-level simulation.

runtime_options may be passed on the command line, and represent the original command-line options passed to the standalone version of ext2sim. A number of the original command-line options have been deprecated in the Tcl-based version, and some are duplicated by other ext2sim options. Valid runtime_options are:

-B
Don't output transistor or node attributes in the .sim file. This option will also disable the output of information such as the area and perimeter of source and drain diffusion and the FET substrate.
-F
Don't output nodes that aren't connected to devices (floating nodes).
-tchar
Trim characters from node names when writing the output file. char should be either "#" or "!". The option may be used twice if both characters require trimming.
-y num
Select the precision for outputting capacitors. The default is 1 which means that the capacitors will be printed to a precision of 0.1 fF.
-J hier|flat
Select the source/drain area and perimeter extraction algorithm. If hier is selected then the areas and perimeters are extracted only within each subcell. For each device in a subcell the area and perimeter of its source and drain within this subcell are output. If two or more devices share a source/drain node then the total area and perimeter will be output in only one of them and the other will have 0. If flat is selected the same rules apply, only the scope of search for area and perimeter is the whole netlist. In general, flat (which is the default) will give accurate results (it will take into account shared sources/drains).
With options, the command sets various parameters affecting the output format and content.

Implementation Notes:

ext2sim is implemented as a separate loadable Tcl package, but one which depends on the presence of the standard "tclmagic" package. magic is set up with a placeholder command for ext2sim, and will automatically load the Tcl package when this command is invoked.

exttosim is an alias for ext2sim, to satisfy the grammatically anal retentive.

See Also:

extract
extresist
ext2spice
irsim

Return to command index

Last updated: October 12, 2005 at 9:40pm

magic-8.0.210/doc/html/iroute.html0000644000175000001440000000627210751423606015373 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

iroute


Do interactive point-to-point routing from the pointer cursor to the cursor box

Usage:

iroute option

where option may be one of the following:
contacts [type] [parameter] [value...]
Set route-contact parameters. parameter may be one of the following keywords:
active
width
cost
help [option_name]
Summarize iroute subcommands
layers [type] [parameter] [value...]
Set route-layer parameters. parameter may be one of the following keywords:
active
width
hCost
vCost
jogCost
hintCost
route node_name...
Connect point to named node(s)
saveParameters
Write out all irouter parameters. These are written out as command calls so they can be read back with the Tcl source command.
search rate|width
Set parameters controlling the internal search for routes
spacings type
Set minimum spacing between route-type and arbitrary type
verbosity level
Control the amount of messages printed
version
Identify irouter version
wizard parameter
Set miscellaneous parameters. parameter may be one of the following keywords:
bloom
boundsIncrement
estimate
expandDests
penalty
penetration
window

Summary:

The iroute command is. . .

Implementation Notes:

iroute is implemented as a built-in command in magic.

See Also:

route
garoute

Return to command index

Last updated: October 6, 2004 at 11:11pm

magic-8.0.210/doc/html/getnode.html0000644000175000001440000000440410751423606015504 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

getnode


Get node names of all selected paint

Usage:

getnode [option]

where option may be one of the following:
abort [string]
Stop the getnode search when the node name string is encountered.
alias [on|off]
If on, reports all names found for the node. If off, only the canonical name is returned.
globals [on|off]
If on, any global node name (names ending with "!") will terminate the search, returning the global name. If off, global names are treated like local node names.
fast
Return the first name encountered, rather than finding the canonical node name.

Summary:

The getnode command queries areas of selected paint for netlist node names. The converse of this command is goto.

Implementation Notes:

getnode is implemented as a built-in command in magic. The node name search uses the same algorithm as the netlist connectivity selection function, and for very large networks, can be quite slow.

See Also:

goto

Return to command index

Last updated: October 6, 2004 at 6:01am

magic-8.0.210/doc/html/unmeasure.html0000644000175000001440000000272110751423606016063 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

unmeasure


Remove a ruler generated with the measure script.

Usage:

unmeasure

Summary:

The unmeasure command is a script that removes a ruler that was created with the corresponding measure command. Any ruler that is found within the cursor box will be removed.

Implementation Notes:

unmeasure is implemented as a Tcl procedure in the "tools" script.

See Also:

measure

Return to command index

Last updated: December 4, 2005 at 9:20pm

magic-8.0.210/doc/html/paint.html0000644000175000001440000000442610751423606015176 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

paint


Paint mask information into the current edit cell

Shortcuts:

Key interactive macro p implements the command paint and waits for input of the layer type.
Mouse button 2 implements the command paint cursor when using the "box tool" in a layout window.

Usage:

paint layers|cursor

where layers is a comma-separated list of types to paint.

Summary:

The paint command paints layer types in the current edit cell inside the area of the cursor box.

Note that some layers, such as DRC layers, cannot be painted. Elements are painted with the element command and feedback areas are painted using the feedback command.

The "paint cursor" option picks the layers underneath the position of the (X11) cursor and fills the cursor box with these types. However, when no material (e.g., "space") is present under the cursor, then all material and labels are erased from the area of the cursor box.

Implementation Notes:

paint is implemented as a built-in command in magic.

See Also:

erase

Return to command index

Last updated: November 8, 2004 at 3:02pm

magic-8.0.210/doc/html/ext.html0000644000175000001440000000764410751423606014670 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

ext, extract


Circuit netlist extractor

Usage:

extract option

where option may be one of the following:
all
Extract the root cell and all its children. This bypasses the incremental extraction and ensures that a new .ext file is written for every cell definition.
cell name
Extract the indicated cell into file name
do|no [option]
Enable or disable an extractor option, where option may be one of the following:
capacitance
resistance
coupling
length
adjust
all
length [option]
Control pathlength extraction information, where option may be one of the following:
driver termname
receiver termname
clear
help
Print help information
parents
Extract the selected cell and all its parents
showparents
List the cell and all parents of selected cell. Note that this is not really an extract option and is superceded by the cellname command.
[list|listall] style [stylename]
Set the current extraction style to stylename. Without arguments, print the current extraction style. With keyword list, return the current extraction style as a Tcl result. With keyword listall, return all valid extraction styles for the technology as a Tcl list.
unique [#]
Generate unique names when different nodes have the same name
warn [[no] option]
Enable/disable reporting of non-fatal errors, where option may be one of the following:
fets
labels
dup
all

Summary:

With no options given, the extract command incrementally extracts the root cell and all its children into separate .ext files. With options, the effect is as described in the Usage section above.

Implementation Notes:

extract is implemented as a built-in magic command.

ext is an alias for command extract (allowed abbreviation where the usage would otherwise be ambiguous).

See Also:

extresist
ext2spice
ext2sim

Return to command index

Last updated: October 6, 2004 at 3:16am

magic-8.0.210/doc/html/setpoint.html0000644000175000001440000000627410751423606015733 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

setpoint


Set the value of the cursor reference point in a specific window.

Usage:

setpoint [x y [window_id]

where x and y are screen coordinates and window_id is the identifying number for a layout window.

Summary:

The setpoint command forces the reference point for a specific window. Each command that executes relative to a window must be able to translate from the pointer position to a layout coordinate. Commands that are executed from a script or from the command-line may not have access to the pointer, but can set the reference point with this command so that the effect of the command is predictable.

Normally, in interactive this command is not used. However, scripts that open more than one window need to specify which one is to take the action of the command. In the Tcl/Tk version, this can be done by using the tk_path_name command to pass a command to a specific window. The non-Tcl/Tk version, and the Tcl/Tk version using the "-dnull" option on the command line (i.e., no graphics package initialized) must use the setpoint command to track windows. Although possible, it is generally a bad idea for a script running in batch mode ("-dnull") to create and access multiple windows, since the window structures have no useful function outside of a graphics environment. Nevertheless, it is important to realize that the openwindow command will generate multiple virtual windows in a batch-mode environment, and these can only be separately accessed using the setpoint command.

Implementation Notes:

setpoint is implemented as a built-in window command in magic.

Bugs:

The use of the window ID number is unique to this command and should be a window name like every other window-related command. Likewise, scripts would best make use of this command if the position were in layout coordinates, and magic translated them back to screen coordinates in the indicated window to set the reference point.

Return to command index

Last updated: December 4, 2005 at 9:02pm

magic-8.0.210/doc/html/sideways.html0000644000175000001440000000304210751423606015704 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

sideways


Flip selection and box sideways

Shortcuts:

Key macro f implements the command sideways.

Usage:

sideways

Summary:

The sideways command flips the selection from left to right. Flipping is done such that the lower left-hand corner of the selection remains in the same place through the flip.

Implementation Notes:

sideways is implemented as a built-in command in magic.

See Also:

upsidedown

Return to command index

Last updated: October 8, 2004 at 6:02am

magic-8.0.210/doc/html/netlist/0000755000175000001440000000000011504623573014653 5ustar timusersmagic-8.0.210/doc/html/netlist/netlist.html0000644000175000001440000000341410751423606017223 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

netlist


Switch current netlist to the netlist with the given filename, or if unspecified, the edit cell name with the file suffix .net.

Usage:

netlist [name]

where name is the filename of a netlist, with or without the file suffix .net.

Summary:

The netlist command sets the indicated name to be the current netlist. It searches for a file of the name name.net and loads the contents of this file. If no name is specified, then the name of the current edit cell is used.

Implementation Notes:

netlist is implemented as a built-in netlist window command in magic. It can only be invoked from a window created with the specialopen netlist command.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/netlist/joinnets.html0000644000175000001440000000405310751423606017372 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

joinnets


Join the nets containing the two indicated terminals.

Usage:

joinnets term1 term2

where term1 and term2 are names of netlist terminals.

Summary:

The joinnets command joins two networks together into a single network. The two networks are specified by naming a terminal on each network. If either terminal is not connected to a network, no action is taken (use the add command to add an unconnected terminal to a network).

Implementation Notes:

joinnets is implemented as a built-in netlist window command in magic. It can only be invoked from a window created with the specialopen netlist command. This command was previously called join, and may be used as that abbreviation in the non-Tcl version of magic. However, the command name join conflicts with the Tcl command of the same name, and its syntax is not distinct. Therefore, in Tcl-based magic, the command name join is interpreted as the Tcl command.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/netlist/cull.html0000644000175000001440000000257610751423606016510 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

cull


Remove fully-wired nets from the current netlist

Usage:

cull

Summary:

The cull command checks the current netlist against routing in the edit cell and removes nets that are already wired correctly.

Implementation Notes:

cull is implemented as a built-in netlist window command in magic. It can only be invoked from a window created with the specialopen netlist command.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/netlist/find.html0000644000175000001440000000331410751423606016460 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

find


Find all occurrences of any labels matching the indicated pattern beneath the box (on layers, if specified) and leave as feedback.

Usage:

find pattern [layers]

where pattern is a text pattern to match to labels, and layers is an optional list of layers on which to restrict the search for connected labels.

Summary:

The find command creates feedback areas for all instances of labels containing the indicated pattern that lie beneath the box.

Implementation Notes:

find is implemented as a built-in netlist window command in magic. It can only be invoked from a window created with the specialopen netlist command.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/netlist/showterms.html0000644000175000001440000000342310751423606017574 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

showterms


Generate feedback for all terminals in netlist

Usage:

showterms

Summary:

The showterms command highlights (using feedback highlights) all terminals in the current netlist. These feedback entries may be cleared with the "feedback clear" command. Note, however, that while the showterms command must be executed from the netlist window, the feedback command must be executed from the layout window.

Implementation Notes:

showterms is implemented as a built-in netlist window command in magic. It can only be invoked from a window created with the specialopen netlist command.

See Also:

shownet
feedback

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/netlist/verify.html0000644000175000001440000000304110751423606017041 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

verify


Make sure the current netlist is correctly wired

Usage:

verify

Summary:

The verify command checks the current netlist against routing in the edit cell to ensure that all the nets are implemented exactly as specified by the netlist. If correctly verified, no action is taken. If problems are found, these are highlighted with feedback entries.

Implementation Notes:

verify is implemented as a built-in netlist window command in magic. It can only be invoked from a window created with the specialopen netlist command.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/netlist/writeall.html0000644000175000001440000000340010751423606017357 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

writeall


Write out all modified netlists.

Usage:

writeall

Summary:

The writeall command scans through all the netlists that are loaded, finds any that have been modified, and queries the user for an action. The actions are:
write
Write the netlist file.
skip
Ignore the network and do not update its netlist file.
abort
Terminate the writeall command with no further files modified.

Implementation Notes:

writeall is implemented as a built-in netlist window command in magic. It can only be invoked from a window created with the specialopen netlist command.

See Also:

savenetlist

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/netlist/add.html0000644000175000001440000000326610751423606016276 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

add


Add the indicated terminal to the net of the other indicated terminal.

Usage:

add term1 term2

where term1 and term2 are the names of netlist terminals.

Summary:

The add command adds an additional terminal term1 to a network. The network is specified by identifying a second terminal term2 belonging to the network. If term1 previously belonged to another network, it is removed from that network.

Implementation Notes:

add is implemented as a built-in netlist window command in magic. It can only be invoked from a window created with the specialopen netlist command.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/netlist/trace.html0000644000175000001440000000330610751423606016637 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

trace


Highlight material connected to the terminals of the indicated network, or of the current network if no network name is specified.

Usage:

trace [name]

where name is the name of a network.

Summary:

The trace command highlights (using feedback highlights) the network connected to the terminals of the indicated network, where the network is indicated by name. If no network name is specified, then the current network is highlighted.

Implementation Notes:

trace is implemented as a built-in netlist window command in magic. It can only be invoked from a window created with the specialopen netlist command.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/netlist/flush.html0000644000175000001440000000315410751423606016663 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

flush


Short summary. Flush changes to the indicated netlist, or the current netlist if unspecified.

Usage:

flush [netlist]

where netlist is the name of a netlist.

Summary:

The flush command flushes changes to the indicated netlist, reverting the netlist to the last form read from the netlist file. If the netlist is unspecified, the current netlist is flushed.

Implementation Notes:

flush is implemented as a built-in netlist window command in magic. It can only be invoked from a window created with the specialopen netlist command.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/netlist/extract.html0000644000175000001440000000276510751423606017223 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

extract


Generate a net for terminals connected to box

Usage:

extract

Summary:

Starting from paint underneath the box, the extract command finds all electrically-connected material in the edit cell, locates terminals touched by the material, and puts the terminals into a new network in the current netlist.

Implementation Notes:

extract is implemented as a built-in netlist window command in magic. It can only be invoked from a window created with the specialopen netlist command.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/netlist/dnet.html0000644000175000001440000000324110751423606016471 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

dnet


Delete the net(s) containing the indicated name(s), or the current net if no name is given.

Usage:

dnet name1 name2 ...

where name1, name2, etc., are net names.

Summary:

The dnet command removes networks from the current netlist. The networks are specified by names of terminals that are part of the network.

Implementation Notes:

dnet is implemented as a built-in netlist window command in magic. It can only be invoked from a window created with the specialopen netlist command.

See Also:

dterm

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/netlist/ripup.html0000644000175000001440000000314710751423606016703 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

ripup


Rip up edit cell paint connected to paint under box, or rip up the current netlist if invokes as "ripup netlist"

Usage:

ripup [netlist]

Summary:

The ripup command performs one of two functions. Invoked as ripup netlist, it removes the painted material routing all nets in the current netlist. Invoked as ripup, it removes the painted material connected to any paint found under the box.

Implementation Notes:

ripup is implemented as a built-in netlist window command in magic. It can only be invoked from a window created with the specialopen netlist command.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/netlist/dterm.html0000644000175000001440000000313410751423606016653 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

dterm


Delete terminals from nets

Usage:

dterm name1 name2 ...

where name1, name2, etc., are the names of netlist terminals.

Summary:

The dterm command removes terminals from a network in the current netlist. The terminals are specified by name.

Implementation Notes:

dterm is implemented as a built-in netlist window command in magic. It can only be invoked from a window created with the specialopen netlist command.

See Also:

dnet

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/netlist/shownet.html0000644000175000001440000000334410751423606017232 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

shownet


Highlight edit cell paint connected to paint under the box.

Usage:

shownet [erase]

Summary:

The shownet command highlights (using highlights) the network connected to any painted material under the box. Although the highlights look like feedback entries, they are actually separate, and cannot be removed by the "feedback clear". The command option "shownet erase" will remove the highlighted entries.

Implementation Notes:

shownet is implemented as a built-in netlist window command in magic. It can only be invoked from a window created with the specialopen netlist command.

See Also:

showterms

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/netlist/cleanup.html0000644000175000001440000000346310751423606017174 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

cleanup


Interactively clean up the netlist

Usage:

cleanup

Summary:

The cleanup command performs an interactive netlist cleanup. It checks the current netlist for terminals that aren't present in the design and for nets with only one terminal. When found, the user is informed and an action requested.

Requested actions are as follows:

dterm
Delete the terminal
dnet
Delete the net
skip
Take no action on this problem
abort
End the cleanup command immediately with no further checks, requests, or actions.

Implementation Notes:

cleanup is implemented as a built-in netlist window command in magic. It can only be invoked from a window created with the specialopen netlist command.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/netlist/savenetlist.html0000644000175000001440000000332710751423606020105 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

savenetlist


Write out the current netlist to a .net file.

Usage:

savenetlist [file]

where file is the optional filename to write output to.

Summary:

The savenetlist command writes the current netlist to the indicated .net file file. If unspecified, and the netlist was read from a file, then the netlist is saved back to that file.

Implementation Notes:

savenetlist is implemented as a built-in netlist window command in magic. It can only be invoked from a window created with the specialopen netlist command.

See Also:

writeall

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/netlist/pushbutton.html0000644000175000001440000000354710751423606017763 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

pushbutton


Execute the default function associated with a mouse button event.

Usage:

pushbutton button

where button is one of left, middle, or right.

Summary:

The pushbutton command invokes the function "traditionally" associated with the indicated mouse button. However, in Magic-7.3, button actions are treated as macros, and so the button macros are defined, by default, to call the pushbutton command for the indicated button. The button actions no longer recognize button-up events. The action taken by the command depends on where in the netlist window the button was pressed.

Implementation Notes:

pushbutton is implemented as a built-in netlist window command in magic. It overrides the default window client pushbutton command.

Return to command index

Last updated: November, 2004

magic-8.0.210/doc/html/netlist/print.html0000644000175000001440000000312310751423606016672 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

print


Print all terminals in the indicated net, or in the current net if the name is unspecified.

Usage:

print [name]

where name is the name of a network.

Summary:

The print command reports all terminals connected to the indicated network. If no network name is specified, then all terminals connected to the current network are listed.

Implementation Notes:

print is implemented as a built-in netlist window command in magic. It can only be invoked from a window created with the specialopen netlist command.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/snap.html0000644000175000001440000000714710751423606015027 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

snap


Cause box to snap to the selected grid when moved by the cursor. Also, cause distance measurements to be interpreted by default as measurments in the selected grid.

Usage:

snap [internal|lambda|user]

Summary:

The snap command causes the cursor box to snap to the selected grid when moved by pointer button events. The selected grids are internal, the size of the internal database, lambda, the lambda grid based on the technology minimum feature size, and user, based on the value given by the user to the grid command.

In addition to changing the behavior of the box to mouse button events, the snap command also changes the way that distance measurements are interpreted in commands that take distance arguments, such as move, copy, and stretch. An integer number with no other identifying units is interpreted as a measurement in the current snap grid. All other measurements must have an identifying unit: i for internal units, l for lambda units, and g for user grid units (as well as the usual metric units). Even when snap is set to the larger lambda or user grids, it is possible to move the cursor box to finer grid positions from the command line. See the reference page on distance measures for a complete description of distance values.

snap with no arguments returns the current snap grid type.

By default, the internal and lambda grids are the same. However, CIF, GDS, or LEF/DEF input on a finer scale can cause the internal grid to be set finer than the lambda grid. Also, the scalegrid command can be used to separate the internal and lambda grids. Note that the use of "lambda" is merely a convention. Traditionally, scalable CMOS rules were based on units of "lambda", equal to one-half the minimum feature size of the technology. Many technology files are still based on lambda rules, which are usually more conservative than vendor rules. However, some technology files may be based on exactly implementing vendor rules, and may set the internal grid spacing to a finer resolution, such as 0.1 micron or smaller. In such cases, the use of the term "lambda" is a misnomer.

Implementation Notes:

snap is implemented as a built-in command in magic.

See Also:

grid

Return to command index

Last updated: October 8, 2004 at 7:16am

magic-8.0.210/doc/html/measure.html0000644000175000001440000000410210751423606015513 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

measure


Create a ruler to measure the distance between two points on a layout.

Usage:

measure [orient]

Summary:

The measure command is a script that creates a ruler to measure the distance between two points on a layout. The ruler is positioned within the bounds of the cursor box. The option orient may be "horizontal", "vertical", or "auto", and determines whether the ruler measures a width or a height. Without any option, orientation auto is assumed. Automatic orientation chooses the longer dimension of the cursor box as the dimension to measure. Dimensions are printed in microns.

Implementation Notes:

measure is implemented as a Tcl procedure in the "tools" script. The ruler itself is implemented as elements (see the element command), including line elements for the ruler and a text element for the printed dimension.

See Also:

unmeasure
element

Return to command index

Last updated: December 4, 2005 at 9:12pm

magic-8.0.210/doc/html/undo.html0000644000175000001440000000407410751423606015027 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

undo


Undo commands

Shortcuts:

Key macro U implements the command undo.

Usage:

undo [print [count]]

where count indicates a number of events to be undone (default 1 event), and must be a nonzero positive integer.

Summary:

The undo command reverses the effect of the last executed command (command-line, script, or macro-invoked), returning the layout to the state it was in prior to execution of that command.

Certain commands in magic disable the undo mechanism, thus preventing the command from being undone. These include layout reads and writes, CIF, GDS, and LEF/DEF reads and writes. The print option generates a stack trace of the top count events in the undo stack, in excruciating detail.

Implementation Notes:

undo is implemented as a built-in window command in magic.

See Also:

redo

Return to command index

Last updated: October 15, 2004 at 5:55am

magic-8.0.210/doc/html/grid.html0000644000175000001440000001012510751423606015001 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

grid


Toggle the grid lines on or off, and set grid parameters

Shortcuts:

Key macro g implements the command grid (with no arguments). Key macro G implements the command grid 2.

Usage:

grid [option]

where option may be one of the following:
x_spacing [y_spacing [x_origin y_origin]]
set the grid to the indicated spacing, where all spacing and origin values are any valid magic distance value.
on|off
Set the visibility of the grid on or off, as indicated.
state
Report the state (on or off) of the grid. In the Tcl version, this is returned as a boolean value (0 or 1).
box
Report the box (rectangle) of the unit grid, in magic internal coordinates.
help
Print usage information on the grid command.

Summary:

The grid command has two purposes: to draw a reference grid on the screen as an aid to layout placement, and to define a snap grid of arbitrary (and not necessarily square) units. This second use works in conjunction with the snap command; with the invocation of snap grid (or, equivalently, snap user), standard magic dimensions for commands such as move, copy, box, stretch, and mouse-button movement of the cursor box are parsed as integer divisions of the user grid. The grid does not have to be visible ("grid on") for the snap function to be enabled.

Note that the grid has both spacing values and an offset; unlike the lambda grid, which is always aligned to the internal coordinate system, the user grid may be any value; for grid spacings that are not a multiple of internal or lambda values, the grid may need to be offset from the origin to get the desired alignment. To do this, specify the x_origin and y_origin values, which describe the offset of the grid origin from the internal coordinate system origin.

Usually there is no reason to have different x_spacing and y_spacing values (only one spacing value is required for both). However, occasionally it may be useful to define something like the following:

grid 150um 3l; snap grid
This example makes it easy to draw a number of horizontal routing lines aligned to a pad cell spacing of 150 microns.

Note that even when the grid is set to visible, at a large enough zoom factor, where the grid lines become dense, the grid will not be drawn.

grid with no arguments toggles the visibility of the grid lines on the screen.

Implementation Notes:

grid is implemented as a built-in window command in magic.

See Also:

snap

Return to command index

Last updated: November 7, 2004 at 3:24pm

magic-8.0.210/doc/html/openwrapper.html0000644000175000001440000000425510751423606016425 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

openwrapper


Open a GUI layout window and all of its associated frames.

Shortcuts:

Menu option File->New window implements the command openwrapper in the GUI layout window.

Usage:

openwrapper [cellname] frame_name]]

where frame_name is the Tk path name of the top-level layout GUI window frame. By default, this name is .layout1, .layout2, etc., for successive layout windows. cellname is the name of a cell to be loaded into the window. Options behave the same was as they do for the non-GUI openwindow command.

Summary:

The openwrapper command creates a new layout window in the Tcl version of magic. It is only applicable when magic is invoked with the GUI wrapper, using magic -w, and supercedes the built-in command openwindow.

Implementation Notes:

openwrapper is implemented as a Tcl procedure in the GUI wrapper script.

See Also:

openwindow
closewrapper

Return to command index

Last updated: October 7, 2004 at 5:40am

magic-8.0.210/doc/html/expand.html0000644000175000001440000000375010751423606015341 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

expand


Expand everything inside or touching the cursor box, or toggle expanded/unexpanded cells in the current selection.

Usage:

expand [toggle]

Shortcuts:

Key macro x implements the command expand.
Key macro Control-X implements the command expand toggle.

Summary:

The expand command expands the view of subcells to display the contents of the subcells. Without arguments, the expand command expands all unexpanded subcells that touch or intersect the cursor box in the layout window.

Option expand toggle operates on the current selection, not relative to the cursor box, and will expand a selected cell that is unexpanded, or unexpand a cell that is already expanded.

Implementation Notes:

expand is implemented as a built-in magic command.

See Also:

unexpand

Return to command index

Last updated: October 16, 2004 at 2:17pm

magic-8.0.210/doc/html/version.html0000644000175000001440000000240010751423606015536 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

version


Print version and revision info

Usage:

version

Summary:

The version command prints the version number and revision number of magic, and the compilation date and time.

Implementation Notes:

version is implemented as a built-in command in magic.

Return to command index

Last updated: December 4, 2005 at 3:19pm

magic-8.0.210/doc/html/macro.html0000644000175000001440000000741210751423606015162 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

macro


Define or print a macro called char

Usage:

macro [window_type] [key [value]]

where key is the name of a valid key (see below), and value is a magic command-line command. If present, window_type must be one of the four window types accepted by the specialopen command: layout, color, netlist, and wind3d. If omitted, the layout window is assumed by default, unless the command has been called from inside a window (using the colon or semicolon escape to the command-line), in which case that window type is assumed.

Summary:

The macro command translates keystrokes typed into a layout window into magic command-line commands. When the key key is pressed in a layout window, the command stored in value is executed relative to that layout window. The default bindings are specified in the system .magic file, read at startup. These macros may be arbitrarily rebound using the macro command.

A key macro may be unbound from a command by passing an empty string ("") for the value.

key is any valid name for a keyboard keypress event. In its simplest form, this may just be the name of the key, such as "g" or "X". The space bar key must be quoted in double-quotes; most other characters may be unquoted. Control characters may be specified by the two-character combination of the carat ("^") key followed by a capital letter, such as "^Z". The use of embedded control characters is deprecated, as it is incompatible with Tcl syntax.

key may also be specified as any valid X11 name for a key as defined in the include file keysymdef.h on UNIX systems. This allows specification of function keys such as "XK_F8" or keypad keys such as "XK_KP_Right".

Buttons are treated just like keys for the purpose of defining macros. While the official names for buttons in keysymdef.h are "XK_Pointer_Button_1", etc., the macro command accepts the abbreviated forms Button1, and so forth.

Finally, key modifiers may be prepended to the key name. Valid key modifiers are Shift_, Control_, Alt_, and Meta_, and may be coupled in any combination. Mouse buttons may also be combined with key modifiers, so, for example, Shift_Button1 is a legal, unique binding.

Implementation Notes:

macro is implemented as a built-in window command in magic.

See Also:

imacro

Return to command index

Last updated: November 10, 2004 at 10:34am

magic-8.0.210/doc/html/popstack.html0000644000175000001440000000323410751423606015703 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

popstack


Return from editing a cell that was loaded using pushstack.

Shortcuts:

Key macro < implements the command popstack.

Usage:

popstack

Summary:

The popstack command returns from editing a cell that was loaded using the pushstack command, reverting the layout window to the cell that was loaded prior to the pushstack call. This is implemented as a stack, and calls may be nested.

Implementation Notes:

popstack is implemented as a Tcl procedure in the "tools" script.

See Also:

pushstack

Return to command index

Last updated: October 7, 2004 at 11:47pm

magic-8.0.210/doc/html/cellmanager.html0000644000175000001440000001515310751423606016334 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

cellmanager


Invoke the cell manager GUI window

Shortcuts:

Menu option Options->Cell Manager implements the command cellmanager create in the GUI layout window. This menu item has a checkbox and is used both to open and to close the Cell Manager window.

Usage:

cellmanager [option]

where option is optional and may be one of the following:
update
The default option if no option is given. Update the cell manager to reflect the current state of the layout.
create
Create the cell manager window. This option is normally called only from the "Cell Manager" button in the magic GUI layout window.

Summary:

The cellmanager command is normally invoked automatically from inside the GUI wrapper procedures and tag callbacks, and normally should not be called directly from the command line.

Figure 1. The Cell Manager Window
The Cell Manager window (see above) is a separate top-level window with Tk pathname ".cellmgr". It consists of a tree widget (defined in the Tcl package "BLT") display in the center, a message window and button on the bottom, and a row of menu buttons at the top.

The Cell Manager displays cells for everything stored in the layout database. As such, it is only necessary to have a single cell manager for all layout windows. However, commands such as "Load", "Edit", etc., apply to a specific window. When a new layout window is created, rather than generate a new Cell Manager window, the new window is added to the list of "target windows". The currently selected target window is displayed at the bottom of the Cell Manager. This is also a button that can be used to select a new target window. If only one layout window is present, the target is declared "default" and may be left alone.

The hierarchical tree view shows all of the instances (cell uses) in a layout. When first invoked, the top-level cell only is shown, with a "folder" icon showing that this cell contains uses. By clicking on the "+" symbol next to the folder icon, the tree view is expanded to show the cell instances used by the top-level layout cell. This expansion may continue until a cell instance is found that does not contain any descendents. Note that the name displayed is the name of the cell definition, with the instance number given in parentheses after the name. If the instance name is non-default (e.g., because it came from a 3rd party vendor database or was altered with the identify command), the full name of the instance is shown in the parentheses. If the instance is arrayed, the array indices are shown in brackets ("[]") after the instance number or name.

The use of tag callbacks on commands allows the cell manager to be updated in response to certain commands entered on the command line. The cell manager will be updated in response to a "load" or "getcell" command.

The menu buttons perform certain functions based on the selection made in the tree window. These functions are as follows:

Load
load the selected cell into the window. The load command is invoked and passed the cell definition name of the selected cell instance. Note that this menu function operates on the cell definition of the selected cell instance.
Edit
edit the selected cell instance. The cell instance selected becomes the current edit cell.
Expand
expand (or unexpand, if already expanded) the selected cell instance.
Zoom
change the current view of the layout so that it is centered on the selected cell instance, and scaled so that the cell instance fills the screen.

Implementation Notes:

cellmanager is implemented as a Tcl procedure in the GUI wrapper script. Because layouts with complicated hierarchy can cause magic to run very slowly due to processing in the cell manager window, this window does not exist on startup and is deleted entirely when turned off in the "Options" menu of the GUI wrapper layout window.

cellmanager uses the tree display widget from the tcl package "BLT". Therefore, in order to see the Cell Manager window, it is necessary to have BLT installed on the system. If BLT is not installed, no option for "Cell Manager" will appear in the "Options" menu of the GUI wrapper window.

cellmanager depends on the GUI wrapper window, as it is defined in the wrapper script. Therefore, to use the cell manager, it is necessary to invoke magic with the option "-w".

Bugs:

The "Expand" function should expand everything above the selected cell. Otherwise, if something higher up in the hierarchy is unexpanded, the selected cell will not be expanded.

See Also:

load
edit
expand
zoom

Return to command index

Last updated: October 6, 2004 at 12:47am

magic-8.0.210/doc/html/writeall.html0000644000175000001440000000535110751423606015704 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

writeall


Write out all modified cells to disk

Shortcuts:

Key macro w implements the command writeall.
Key macro W implements the command writeall force.

Usage:

writeall [force cell1 cell2...]

Summary:

The writeall command generates a popup dialog prompting for action on writing each cell definition in the layout hierarchy to disk. As shown in the figure below, the popup dialog presents five choices:
write
Writes the single cell and continues the prompting for the next cell.
flush
Reverts the cell to what was originally on the disk, like the flush command. Continues prompting for the next cell.
skip
No action for the indicated cell definition; continue prompting for the next cell.
abort
Stop all writing and terminate the command with no further prompting or processing.
autowrite
Write all the cells, with no further prompting.

Figure 1. The popup dialog of the writeall command.
With the option write force, the command writes all cells in the hierarchy with no prompting. If one or more cell names follows write force, the cells listed will be written (action "write") and all other cells will be ignored (action "skip").

Implementation Notes:

writeall is implemented as a built-in command in magic.

See Also:

save

Return to command index

Last updated: December 4, 2005 at 8:09pm

magic-8.0.210/doc/html/identify.html0000644000175000001440000000332210751423606015670 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

identify


Set the use identifier of the selected cell

Usage:

identify use_id

where use_id is a unique name to identify the cell use.

Summary:

The identify command renames cell uses in magic. By default, magic names cell uses with the name of the cell definition followed by an underscore, followed by a unique index number for the cell use in the parent cell. This is merely a convention, and any unique identifier suffices to name the cell use.

Implementation Notes:

identify is implemented as a built-in command in magic.

See Also:

instance

Return to command index

Last updated: October 6, 2004 at 9:32pm

magic-8.0.210/doc/html/erase.html0000644000175000001440000000512310751423606015155 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

erase


Erase paint from the layout inside the bounds of the cursor box.

Shortcuts:

Key macro Control-D implements the command "erase $", which indicates to erase all paint and labels in the cursor box.
Key e typed while the cursor is in a layer box in the GUI toolbar implements the command "erase layer", passing the layer type in the toolbar.
Key Shift plus Mouse button 2 implements the command erase cursor when using the "box tool" in a layout window.

Usage:

erase [layers|cursor]

where layers is a comma-separated list of layer types to be erased, or * to indicate all paint but not labels, or $ to indicate both paint and labels.

Summary:

The erase command erases paint inside the cursor box in the current edit cell. Without arguments, everything inside the box is erased. With argument layers, only the indicated layers are erased.

Note that some layer types, such as DRC paint, cannot be erased. Feedback areas are not considered paint and should be erased using the feedback clear command.

The option "erase cursor" picks the layers at the position of the (X11) cursor and erases these from the area of the cursor box.

Implementation Notes:

erase is implemented as a built-in magic command.

See Also:

paint

Return to command index

Last updated: November 8, 2004 at 3:02pm

magic-8.0.210/doc/html/windowcaption.html0000644000175000001440000000320010751423606016735 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

windowcaption


Toggle title caption for new windows

Usage:

windowcaption [on|off]

Summary:

The windocaption command turns the drawing of the window title area (caption) on or off. Normally, this will be on in the non-GUI version of magic, and off in the GUI version, where the title area is handled by the Tk frame window and the caption procedure.

Note that the command does not affect the current layout windows, but takes effect for all windows created after the command has been called.

Implementation Notes:

windocaption is implemented as a built-in command in magic.

Return to command index

Last updated: October 9, 2004 at 2:21am

magic-8.0.210/doc/html/flatten.html0000644000175000001440000000525410751423606015520 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

flatten


Flatten edit cell into the indicated destination cell.

Usage:

flatten cellname [option]

where cellname is the name of a cell definition to be created, and into which the flattened geometry will be placed. option may be one of -nolabels, -nosubcircuit, or -novendor.

Summary:

The flatten command creates a new cell with the indicated name, then flattens the hierarchy of the current edit cell and copies the result into the new cell.

The options allow selective flattening, as follows:

-nolabels
Prevents magic from copying labels into the flattened cell. Otherwise, magic flattens labels by prepending the cell hierarchy to each label as it copies it into the flat cell.
-nosubcircuit
Prevents magic from flattening cells declared to be subcircuits (by the presence of ports in the cell). These cells are retained as subcells in the flattened version.
-novendor
Prevents magic from flattening cells that are vendor cells, that is, cells that are generated by reading GDS using the gds readonly option, or which have the appropriate property values set.
Note that cellname is a top-level cell but is not displayed or saved subsequent to the flatten command. The usual procedure is to follow the command "flatten cellname" with "load cellname", to view the new flattened layout.

Implementation Notes:

flatten is implemented as a built-in command in magic.

Return to command index

Last updated: December 4, 2005 at 8:04pm

magic-8.0.210/doc/html/ruler.html0000644000175000001440000000430310751423606015206 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

ruler


Create ruler markings inside the box with indicated text.

Usage:

ruler [text [orient]]

where orient is either vertical, horizontal, or auto (the default), and where text is any string. If the string contains whitespace, it must be quoted.

Summary:

The ruler command generates a "ruler", a set of lines indicating a dimension. It is used to annotate layouts with the indicated text. If no orientation is given, then automatic orientation it used, in which the presented dimension (the line or lines with arrowheads) is whichever box dimension (width or height) is longer. The ruler may be removed with the unmeasure command. The measure command is a specific type of ruler where the text is set to the presented box dimension.

Implementation Notes:

ruler is implemented as a Tcl procedure defined in the "tools" script. It generates a set of elements (lines and text) with the element add command.

See Also:

measure
unmeasure

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/plot.html0000644000175000001440000001607510751423606015044 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

plot


Hardcopy plotting

Usage:

plot option

where option may be one of the following:
postscript file [layers]
Generate a PostScript file of layout underneath the box.
pnm file [scale [layers]]
Generate a .pnm ("portable anymap") file of layout underneath the box. The output size is propotional to scale, where a scale of 1 is one output pixel per magic internal unit. The default scale value, if unspecified, is 0.5.
parameters [name value]
Set or print out plotting parameters (see Summary below).
help
Print help information

Summary:

The plot command generates hardcopy plots of a layout. The use of plot for any particular output format requires that the parameters of the format be defined in the plot section of the technology file. However, from magic-7.3.56, the PNM handler will create a default set of output styles from the existing layout styles for the technology. This makes plot pnm compatible with all technology files, regardless of whether or not a section exists for "style pnm".

Each plot format has its own set of parameters, but all parameters are controlled with the plot parameters option. Valid parameters and their defaults are as follows:

General parameters:
parameter name default value
showCellNames true
PostScript parameters:
parameter name default value explanation
PS_cellIdFont /Helvetica Font used for writing cell use IDs
PS_cellNameFont /HelveticaBold Font used for writing cell definition names
PS_labelFont /Helvetica Font used for writing label text
PS_cellIdSize 8 Font size for writing cell use IDs (in points)
PS_cellNameSize 12 Font size for writing cell definition names (in points)
PS_labelSize 12 Font size for writing label text (in points)
PS_boundary true Whether to draw boundaries around layers in addition to fill patterns
PS_width 612 (8.5in) Page width of the target output
PS_height 792 (11in) Page height of the target output
PS_margin 72 (1in) Minimum margin to allow on all sides of the output page
PNM parameters:
parameter name default value explanation
pnmmaxmem 65536 Maximum memory (in KB) to use to generate output. Larger values allow larger chunks of the layout to be processed at a time. Normally, anything larger than the default will just take a long time to render, so it's better to leave it alone and let the plot pnm routine downsample the image to fit in memory if the size of the layout requires it.
pnmbackground 255 Value of the background, where 0=black and 255=white. White is default to match the printed page, which is where the plots usually end up. A value of 200 is approximately the default background color in magic.
pnmdownsample 0 Number of bits to downsample the original layout. In the first pass, one pixel is generated for each n magic internal units in each of x and y, where n is the downsampling value. Each downsampling bit therefore represents a factor of 4 in decreased computation time. Generally speaking, downsampling causes information to be lost in the translation from layout to the PNM file. However, if the grid has been scaled from the original lambda, then downsampling up to the scale factor will have no impact on the output other than speeding up the rendering (because the minimum feature size is still in lambda, so no feature will be overstepped by the downsampling). For example, for a grid scaling of 1:10 the proper downsampling would be 3 bits. Note that layouts that are too large for the allocated memory blocksize pnmmaxmem will force downsampling regardless of the value of pnmdownsample.
PostScript plotting is best suited for drawing small layouts with relatively few components. PNM plotting is best suited for drawing large layouts. For chip-size layouts, the PNM plots are virtually identical to chip photographs. From magic version 7.3.56, plotting PNM files requires no special entries in the technology file. Although such entries can fine-tune the output, this is usually not necessary. Also, since version 7.3.56, magic makes intelligent decisions about memory usage, so it's generally not necessary to change the PNM plot parameters.

Implementation Notes:

plot is implemented as a built-in command in magic.

Original plot styles versatec and gremlin have been removed, but shells of the code are retained so that magic doesn't complain when encountering styles for these types in a technology file.

Return to command index

Last updated: December 4, 2005 at 3:24pm

magic-8.0.210/doc/html/getcell.html0000644000175000001440000000666510751423606015511 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

get, getcell


Import a cell as a subcell of the current edit cell.

Usage:

getcell cellname [orientation]

getcell cellname [child child_refpoint] [parent parent_refpoint]

where orientation may be one of the following:
90
Load rotated by 90 degrees clockwise
180
Load rotated by 180 degrees
270
Load rotated by 90 degrees counterclockwise
v
Load flipped top to bottom
h
Load flipped left to right
90v
Load rotated 90 degrees clockwise and flipped top to bottom
90h
Load rotated 90 degrees clockwise and flipped left to right
180v
Load rotated 180 degrees and flipped top to bottom
180h
Load rotated 180 degrees and flipped left to right
270v
Load rotated 90 degrees counterclockwise and flipped top to bottom
270h
Load rotated 90 degrees counterclockwise and flipped left to right
and child_refpoint and parent_refpoint may be x y coordinate pairs, or one of the four keywords ll, lr, ul, or ur, indicating one of the four box corners. For the child, coordinate pairs are in the coordinate system of the child, and corners indicate cell bounding box corners. For the parent, coordinate pairs are in the coordinate system of the parent, and corners indicate corners of the cursor box.

Summary:

The getcell command creates subcell instances within the current edit cell. By default, with only the cellname given, an orientation of zero is assumed, and the cell is placed such that the lower-left corner of the cell's bounding box is placed at the lower-left corner of the cursor box in the parent cell.

Implementation Notes:

getcell is implemented as a built-in command in magic.

get is an alias for the command getcell (allowed abbreviation where otherwise use would be ambiguous).

Scripts will find it more convenient to place cells according to the cell origin, with the usage "getcell cellname child 0 0".

See Also:

dump

Return to command index

Last updated: October 6, 2004 at 3:32am

magic-8.0.210/doc/html/channels.html0000644000175000001440000000344710751423606015660 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

channels


See channels (as feedback) without doing routing.

Usage:

channels [netlist_file]

where netlist_file is the name of a .net file containing a routing netlist.

Summary:

The channels command is part of the routing module in magic. It shows available routing channels in the current layout using the feedback layer mechanism.

Implementation Notes:

channesl is implemented as a built-in command in magic when the router modules are compiled in (which currently they are, in the default compilation configuration).

See Also:

route
iroute
garoute

Return to command index

Last updated: October 4, 2004 at 5:13am

magic-8.0.210/doc/html/tk_path_name.html0000644000175000001440000000646610751423606016523 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

tk_path_name


Execute a window command in the indicated window.

Shortcuts:

Key macro : (colon) implements the command tk_path_name by prepending the window name to the command typed on the command line when the command is executed. This action is, however, transparent to the end user.

Usage:

tk_path_name command_name

where command_name is any valid window command for the type of window indicated by tk_path_name.

Summary:

The tk_path_name command is unique for each window that is created in magic. The name of the window is registered as a command name with the Tcl interpreter. When the window name is used as a command, the arguments of the command are passed to the magic command interpreter to be executed in the context of that specific window. Effectively, it is the same as typing the macro ":" (colon) in a layout window, and then typing the command on the command line.

For example, the default first window that is created in the Tcl GUI version of magic is .layout1.magic. Upon creation, the command name .layout1.magic is registered with the Tcl interpreter. Subsequently, any command on the command-line will be executed in relation to that window if it is specified as an option to the .layout1.magic command:

.layout1.magic box 0 0 10 10
which is exactly the same as putting the X11 pointer cursor in the layout window, typing the ":" (colon) macro, then typing the command box 0 0 10 10 into the command line and hitting the return key.

Similarly to layout windows, windows created with the specialopen command have their Tk path names registered as commands with the Tcl interpreter, and can be passed commands recognized by the specific window type (e.g., netlist commands in the netlist special window).

Implementation Notes:

tk_path_name is implemented as a built-in command in magic which is registered with the Tcl interpreter when the window is created and unregistered when the window is destroyed.

Return to command index

Last updated: October 16, 2004 at 1:54pm

magic-8.0.210/doc/html/lef.html0000644000175000001440000001300110751423606014616 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

lef


LEF-format input and output

Usage:

lef option

where option may be one of the following:
read [filename]
Read a LEF file named filename[.lef]
[filename] -import
Read a LEF file. Import standard cells from .mag files
write [cell]
Write LEF for the current or indicated cell.
writeall
Write all cells including the top-level cell. This might be appropriate if the top-level cell is a compendium of standard cells.
writeall -notop
write all subcells of the top-level cell, but not the top-level cell itself. This is appropriate for generating a LEF library from a layout, for which the layout itself would be written to a DEF file.
help
Print help information

Summary:

The lef command writes LEF-format files, which are files containing technology information and information about the content of standard cells. It is used in conjunction with the def command to read databases of routed digital standard-cell layouts. The .lef file shares some information with the technology file in magic. At a minimum, to read .lef files from third-party sources, the technology file should have a lef section that maps magic layers to layer names that are found in the .lef and .def files. Without this information, magic will attempt to make an educated guess about the routing layers, which normally will be named in an obvious manner such as "metal1", "metal2", etc. The technology file section may be necessary to handle more complicated input such as obstruction layers. Most other aspects of a technology will be contained within the .lef file. When writing .lef files, magic will use internal layer names for the routing layers if no other information is present in the lef section of the technology file.

Because the lef format allows standard cells to be minimally defined (for purposes of protecting intellectual property), often the .lef file contains no actual layout information for the standard cells. magic provides a command option "-import". When specified, for each macro cell in the input .lef file, magic will look for a .mag file of the same name. If found, it will be loaded and used in preference to the definition in the lef file.

Magic uses the port mechanism for labels to determine what are the standard cells in a design. All cells containing port labels will be considered standard cells when writing a .lef file. Ports retain various bits of information used by the LEF/DEF definition, including the port use and direction. See the port documentation for more information.

Macro cell properties common to the LEF/DEF definition but that have no corresponding database interpretation in magic are retained using the cell property method in magic. There are specific property names associated with the LEF format. These are as follows:

LEFclass
Corresponds to the value of CLASS for a macro cell in the LEF format.
LEFsource
Corresponds to the value of SOURCE for a macro cell in the LEF format.
LEFsymmetry
Corresponds to the vlaue of SYMMETRY for a macro cell in the LEF format.
Normally, when importing a LEF/DEF layout into magic, one will first execute a lef read command followed by a def read command. Likewise, when writing a layout, one will first execute a lef writeall -notop command followed by a def write command.

Implementation Notes:

lef is implemented as a built-in command in magic. Only the critical portion of the LEF syntax has been implemented. In particular, simulation-specific properties of the technology and of macro cells are not implemented.

See Also:

def
port
property

Return to command index

Last updated: October 7, 2004 at 1:43am

magic-8.0.210/doc/html/promptload.html0000644000175000001440000000462010751423606016240 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

promptload


Invoke the load-file widget in the GUI version of magic, prompting for a file to load.

Shortcuts:

Menu item File->Load layout implements the command promptload magic.
Menu item File->Read CIF implements the command promptload cif.
Menu item File->Read GDS implements the command promptload gds.

Usage:

promptload magic|cif|gds

Summary:

The promptload command handles input of various file formats for the GUI layout window in the Tcl-based version of magic when invoked with the magic -w option. The handling is more sophisticated than the underlying magic calls. The gds read function will attempt to find the top-level GDS cell and load it into the current window. Likewise, the cif read function will name the top-level cell with the root name of the file being read. The magic load will append the path of the indicated file to the search path, so that if the file makes calls to additional cells in the same directory, they will be found and loaded.

Implementation Notes:

promptload is implemented as a Tcl procedure in the "wrapper" script. It calls the tk_getOpenFile widget in Tk.

See Also:

promptsave

Return to command index

Last updated: October 8, 2004 at 12:30am

magic-8.0.210/doc/html/route.html0000644000175000001440000000511610751423606015216 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

route


Route the current cell

Usage:

route option

where option may be one of the following:
end value
Set channel router end constant. value type is real, and defaults to 1.0.
help
Print help information
jog length
Set minimum jog length (integer grid units)
metal
Toggle metal maximization (default is "on").
netlist file
Set current netlist (default NULL)
obstacle value
Set obstacle constant. value type is real, and defaults to 0.7.
origin [x y]
Print or set routing grid origin
stats
Print and clear previous route statistics
settings
Show router parameters
steady value
Set steady net constant. value type is integer, and defaults to 1.
tech
Show router parameters read from the technology file.
vias value
Set metal maximization via limit (grid units). value type is integer, and defaults to 2.
viamin
Via minimization

Summary:

The route command performs standard routing of networks in a netlist.

Implementation Notes:

route is implemented as a built-in command in magic.

See Also:

iroute
garoute

Return to command index

Last updated: October 8, 2004 at 1:47am

magic-8.0.210/doc/html/addcommandentry.html0000644000175000001440000000452610751423606017235 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

addcommandentry


Generate a new frame for command-line entry.

Usage:

addcommandentry framename

where framename is the Tk pathname of a frame.

Summary:

The addcommandentry command is used with the GUI wrapper in magic version 7.3. It adds a narrow text entry frame to the bottom of the window. This frame duplicates the output of the Tk console, and can be used as an alternative console from which to enter command-line commands. The framename is the Tk path name of the frame holding the layout window. By default these are named .layout1, .layout2, etc., for each call to openwrapper.

The command entry window has a prompt with the name of the Tk frame, e.g., "layout1>", and all window commands entered into this area will be relative to the associated layout window.

Implementation Notes:

addcommandentry is implemented as a Tcl procedure defined in the GUI wrapper script. It is only available when the wrapper is used, that is, when magic is invoked with argument -w.

See Also:

deletecommandentry
openwrapper

Return to command index

Last updated: October 5, 2004 at 3:19am

magic-8.0.210/doc/html/view.html0000644000175000001440000000431510751423606015032 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

view


Zoom window out so everything is visible, or zoom window to the specified area bounds.

Shortcuts:

Key macro v implements the command view.
view [get|bbox|llx lly urx ury]

Usage:

view [get|bbox|llx lly urx ury

where llx lly urx ury are layout dimensions to become the screen view limits.

Summary:

The view command is most often used without arguments to center and scale the screen view of the layout window to fit the layout.

view bbox returns the bounding box dimensions of the layout, in the coordinate system of the layout.

view get returns the coordinates of the screen limits in the coordinate system of the layout (internal database units).

view llx lly urx ury sets the view so that the corners of the screen are at the indicated positions in the coordinate system of the layout. Where the dimensions do not match exactly to the screen aspect ratio, the view will be centered on the indicated coordinates.

Implementation Notes:

view is implemented as a built-in command in magic.

Return to command index

Last updated: October 9, 2004 at 1:59am

magic-8.0.210/doc/html/clockwise.html0000644000175000001440000000460210751423606016042 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

clockwise


Rotate the selection and box clockwise

Shortcuts:

Key macro r implements the command clockwise (or rotate 90).
Key macro R implements the command clockwise 270 (or rotate -90).
Key macro Control-R implements the command clockwise 180

Usage:

clockwise [degrees] [-origin]

where degrees is the number of degrees to rotate, and must be a manhattan amount (90, 180, 270).

Summary:

The clockwise command rotates the current selection by the specified amount, in degrees. The default rotation is by 90 degrees. The amount of rotation must be one of 90, 180, or 270.

If -origin is specified, the rotation is around the origin of the selection, not around the lower left-hand corner.

Implementation Notes:

clockwise is implemented as a built-in magic command. Because a "standard abbreviation" is clock and conflicts with the Tcl command clock, this case is handled specially. The command clock is deprecated in favor of the more general command rotate, but is maintained for backward compatibility.

See Also:

rotate

Return to command index

Last updated: October 15, 2004 at 10:09am

magic-8.0.210/doc/html/graphics/0000755000175000001440000000000011504623573014771 5ustar timusersmagic-8.0.210/doc/html/graphics/techmgr.gif0000644000175000001440000001122510751423606017110 0ustar timusersGIF87aiÃ÷ÿl¦Í‡Îë‹G&™™™ÍÙÙÙæææÿÿÿÿ¿¿!5fêk@@@ðÜNUÀW²xx`VV'Lø  ç‚ëiB@@à4€¥YÐÀòñÿÿ¿¿èò¿!òšêøð`U'xx VVLøððH™™@@f€­û``E BBñ¿DçpÍëw@@(t(PWPuð†ñÿà¿ó¢ÿ¿!H™ê(PFxóñÿÿDºoéǬ#›†m[9ÁÙwkG§ºéêÒmü]¼;÷ï½þ‡îëåèŸ_Ïš¾õõ÷—­[Ï-ÿòAâäÅãÏ¿ý§^{èÉEàsÓ½ßtºÕŸs÷˜ß„ýIX!…ÿÁ$`rt­w„ïé[j Î'݃ aha†¶Èâ‹âm˜žs‡^Ô¡H_‰ îxn ©(¤‹+9$Œ7™gàªUbˆ6~È#”SÚá‘F‰å–ZV(cj*ô$JV&„d—g¦™¥šù}9à›xm…`ˆqÉ&škæigZn²Æœ\ÚÉicxîih¡ˆÞI”’€–)'_z&©¢“V Ô£˜fªé¦œvêé§ †*ꨤ–JP¨¦ªêª¬¶êê«þ°Æ*무Öjë­¸æªë®¼öêë¯À+ì°Äkì±È&«ì²¹àì³ÐF+í´ÔVkíµØf«í¶Üvëí·à†+î¸ä–kî¹è¦«îºì¶ëî»ðÆ+ï¼ôÖkï½øæ«ï¾üöëï¿,ðÀlðÁ'¬ð 7ìðÃG,ñÄWlñÅg¬ñÆc ¨¶V}rÇÛº&ƒkrÊÒ®|rË+?Ë2ɼ­ÍÜâLsµ3ïËrÏüü²Ì/Ï ôÎýâŒÕ³KòÈOÀôUÎBMuÕRG=5ÖÞàµÏ~ ö`M¶×a›í¬ØÜ M´³.Ã}rÊq]tÌvç­þÛÔÍ·ÞHÿk³ÕNK]xáY'žøá‡kݸâŒ3®3¶hŸm¹å•g^öØhk®­ÑCÓ}·Ý..ºÜ¤NôÑoÃì÷Ðó;¸áŽoý8ׄ;®;틇«öÚc§ üðžÿþ9ì§ë-úÝÈÏmúèÐþ=ì­÷Ìzì÷ξ´Î¹ó.ùâÝs}û¸jW.üås¼ñ×Zï¼Üq¿þ<êÒ+O½êÓ£Þ:öûÎ-÷Þ ßí¨=s™Í|ÃCßæ¼àµzxÃßÑb–¼ Bzûƒ™þ6È¿|ùo|»ûžC5Ã!Z“»VñÔ§@â±ÐsÙ’_õÞ§¿Ó¹­~|K^þ¤w½ÎKiþWCœ÷@È; qk@D¡ ·Å¶²°…g3_cx¿ òoBËa#¸<,2ï‚> #µ”–±RÌŒbDš#g14JÌi¤YÓØx18:ÌŽqÌ£÷ÈÇ>úñ€ ¤ IÈBòˆL¤"ÉÈF:ò‘Œ¤$'IÉJZò’˜Ì¤&7ÉÉNzr\ @´B ­P’²”¦¥³Ny€TªRZ®ä+GùÊUÖòZ©´%-Q9ËVæ’–®¼eµz©-b‚Ò˜¸ü¥/Á…Ìa 3˜ÎôW/YyJj¾²šª´&,¯)ÌhNkšÝüf6E ÎgaӜܤV3ÕÎd¢kÞ\¦<½ÏmÚS—âþ”¦5ljJ|ÊóœþD§@}¹O~”ŸUf?‰NƒâS›ùl(7ÏIщT™¤Ìh:y9ΊîR—¿ )9Ó‰MjôžËôèA%/S64 ûü(A­åÒž4¥#éIoJÌžÆtžó¬ió«¶<ªRêÓ³"¶­@,;%zÓ¹&6­\ýl7Š×²f²[«d=ûQÒâ£õ,þ`1ÛV×®•¤¬_S»Ù]®¨µ '_Ý:ÙÔî´¸?½§JQj[»†¶³˜=­h3KÖvUSºAÝhp™K×îw©[n`¯›]ìR»ÎýîtÓ:ÑÞ.W¦…Uïl‹ûZîÖ7½±=æ*aŠÕXžö­‘-èKEºTï®´¬å¯X›V¡V½.)n ׋ª%0r‹ZËÎt½µè'ÿÖ›xcÛ=±Š/Û»øÅ0ޱŒgLãÛøÆ8αŽwÌãûøÇ@FéH°zl‰ÿC²µ€hĸ™Š}‹`E†d#YÉÙ²²•“¬DÜ ±Ë%“ò § ® RÍjákZþíæˆDª¹wâSó ¯¶æÞ±ÌD^£íž¬Á>ã‘ÌJt³Öº—/ƒïËX;´¡“HÀrzŸ¤m—ÂHGyZõt–ÏÌi:ÒÙц#¨§ä!7ÙΨ沪'g6oÓ÷³Ÿ¦»õ4§ °Ê‚ö²¤ƒHiÅuZZh!E(ÄR/qr–æ3ÏbéY/ÒŠÆs£­êÚ±Z×Ãö´WgDïùx°æ ³¯5] p„£`´­ÝflúÖ©æ6º¯Mìîƒã&7íÜýé@1ØÀ†ó›§…æ#ÎÛr’OMpo_z†η찬°WYâq´xÁ4þlŒ§‘ãWÈþ=Nò’›üä(O¹ÊWÎr‚àå0¹Ìg>spÑüæ8‡yË ™óžË6÷¹Ð¾sA¾ü" º·Žn‘¤Ýè@ºÒ»ÅôŠ8ý逬:E®¾ô¨7}ê–Ô2ÅË<öŽ+û\#ÿ¶¼·¥uH„ë §VÛßöJŠ]i8¼ò®l¾€é_£»Ù¥x¯ >“Nt]çH§™ñ‹×»öFÝêrsšò»ûà´æ¸»Zœ‡ˆçííV/z{©Vx ³íøÄ“šÑéf<¼‰måÐ?dôj‡–í‚ûI ›áýö4œM¿m^ƒ™„ÈÆ5íSïmï¾!½WöóýHþ~ñu®<»§þ­gã£õq/öòçý=ïoÞëq{çëÎ4kM!Õ‡äõYýAäW›ùôWýðŸlò÷ßùè§ê'zìW5î€x{(Ió×oõ‡]ökÈ×|®Çnü6~¶z 'wxxzz¸~š$lå÷e§æk’%˜‚S“l |®GDÑv~‘€¼W€[ö~ Xw3e×0Z7<ÈR׃åâw„Hu(„ h„>x1J(‚ß2……}d… tEˆ…{ôrI†b8†d8†AW†h˜†Oè…ØSjø†fX…p8‡kȆvx‡x˜‡z¸‡|؇~ø‡€ˆ‚8ˆ„Xˆ†øcþWlÇöƒ·iƒW.'nùÓ6±F:`$.‘˜gg.w2c‡„ -S”3±×.·e ØgÝÒCxT7{ƒA™¨Š¤¸v¦h~~ß2Šçƒ@Žx¢¦mÿ†‚ yyôf-YT4©ãE€cAhÄ::ösCÍCe‚†jwn®¶‚¶vyØ&ƒŒ(Š´‹ãx‹½ö‹X·Å8~”(kZ´ŒïCAø&‹cÖŒÎCCË£:‘hfꨈ²×€ønoÚ‹ „úö…¥¸Ô&mŽ÷6ñHâÖEÒèg°8?ysEÞ‚z1˜hÄ'{ÉeÀWŠÙ‰ç#Ž¡Ø‹ÇGþqÿoFæíözH˜Œúè‘?fг‘¹““8‹Ysk«¶m'd€%H“©xù’ YŽ é‹qÇ}ÁX-ÁG’߈‰Dy‘<ù•¥“A÷(”4t’xqé(|çØ}åŒ%y„f‹—ã’u…ÙÆ‚¤6{“¸Ã•¬•ô–ƒ9ù(kËvo5:‡‰‘üX‰fjÚø”y{Yõ–-”>R¹i‰’’™kš×‚‹(‘Š—{ö&`‰Óˆ?E9Œ©˜–¸˜¯é‰L™yˆ–ˆ·|Âøx7ùkšé@š£Ù#˜eH™ …©hŽ|ïè…Íùˆ~”Œ«¨œ‡˜Úþ¹ÜÙÞùàžâ9žäYžæyžè™žê¹žìÙžîùžðŸy¨› IkÆyŠe7d nË e°ö:㋦fœÖH }g ÐBœºè‹É6‹Ꜵ.™ÈŠØ9=@¹A±øŠT¡ëÂ’ŠšÉ>Sù‹VÙp)ù¯p׎·‰ù3ª9˜ùE©©¡¬)£³ù‘Õ’´›‰y¼†ûæãŽÝ¢0ô~~ó7gNÉYinQfð”i˜D™˜‰¡WZ˜É£×Œ ©O:“¡†™ J-HúDJÚkÆW|Yù™€¹kO©2`´š:š‘ùÈEÌf¥cæ˜î¦(¸}þ)j'y¨X©‰N¦¦T™¤k× p—™‘‘3t‰-:‰˜=©Ebf£6Ï?øÖG©h çaz›Ø‡*YŸÁ9-ŽŠgçȤOŠªÇ¸”Lv“*–´ ¨b銊˜Uú©;j”‰wªJ‰«r§•‰“c·¦)©5šÇ—µ6«×j“rŠ©¼Z¥†)i™A=Éšôˆ£jŸª —Òú”‘º–(˜›¹@w©¢SJ¯ºƒÙ7Œ²ú€£éŸô¸šÒ˜E®)®4ÊAÎè§ûÙˆ±ç–ìƒEdp¾Éoûg-ñêDþ¢ŸK†œ[tlˆ±$ZK¥Ò‰ ¶HÖò™²*»²,Ûþ².û²0³2;³4[³6{³8›³:»³<Û³>û³ì²¨¸¸¡09´ä2¡q×ãŠáê• “¡Éi}áŠøI»ú-fÁº‘(C˜XÛ§ò§|)ú£¤yšúzD,:Giw²Wê‘yš£ZJ¬û¬Ìø´Ûl>Y˜g9°‰¤Úç€õjzõ†¢kÛ­Ôø­åÊ·i ê£ßú¥Â*·¥“¸MkH‹ª¶ šm:§•Z§_«¡x:®3J·á&¬R ›´Yºû¹ªG•VšlThÉ'j¹¶¬ꯢګ^;–q;‰8¼‹ÉŒh)¹ª{®”|ؖƦ• ««^Ù¸¾*½{ʵÀ‰[àz½[¼Úk–µ©H~»—ëú—Øz”K˜;½Ž›§‰û“ÕȸÓ¿—¸´nK¹Šk¹´k‚׎It¶“Ư·+²ÿê§:䌊{®¤»:Œ \7Lë:™º-G²$óºþbÁˆHÁƒÁüÂÁ<æ±eT¡ë2¹"\º@{Â(œÂ*¼Â,ÜÂ.üÂÜ;magic-8.0.210/doc/html/graphics/magic_title2.gif0000644000175000001440000002477010751423606020033 0ustar timusersGIF89að‡÷.‹W1~i4qz4‰l6d‹6ˆv9“y:~Œ;’b>…•>–Š@x¦Cn’F‚´IšmM¡¼PxšP ŒRйWгW¢x\¬î^ƒ¢^’¾c]:eTFe©ƒf±ïhC]h‘²j¬ãk©k›ÃoPoq·ðsWxs±w£Èy—±y˜²|¼ñ~¹±~ºësŸ¹šƒ«Í„¬Í†¢¹‡ÂòÁ¥´Ò’Çó“¬Á“Èô˜/š"/œ¼×ȰÍô ,<¡¶È§:P¨ÄܨÒõ«Ð»«Ó߬ËîÁвØ÷µÍá¶³£¹CR¹ØÇºth»kt¼ËØ½Ýø¾n~ÁÕæÆ€ŠÇàÒȆÈãùÉÕàÉäúÍÍÝëÐÓ""ÓèúÕ£­ÕçÝÖàçÖâä×33ÚDDÚæðÝUUÞîûáffãÇÂãïèäwwäêïåÆËæîõ爈éóü뙙ñ»»ñãàñô÷ñ÷óòöúôùýõÌÌøÝÝøðñûîîÿÿÿòñúÿÿa¿¿ œÀÅl%À+b€öðaÿ¿œÅlÀ0öÀÿ¿ø˜òñÿÿbúaÉP!^QøœòÅÿl¿OÀverwritÈeñ ÿe¿xôLi¿s t¤`nÈg fsiµlVe œ'Å/lhod0m°ee/im/d`eÈvlL/magdi+6cQ/W e°bœaÅglicTè_ïñtÛÿiB¿tól²ee.ŽàiîÅfÛ'B?`È´VŽLàîðÛÿB¿À!þ+CREATOR: The GIMP's PNM Filter Version 1.0 ,ð‡þkH° Áƒ*\Ȱa„ 9±¢Å‹3jÜȱ£Ç CŠI²¤É“(Sª\¹‘J…—0cÊœI³¦Í›8sÞ| €OtÎìQ¥hB“*]Ê´©Ó§P£JJµªÕ«X³jÝʵ«×¯Mk€k“§Ï³>ƒ&%Z´m¤dãÊK·®Ý»xóêÝË7«Ø¾X{¢ @N¶nÝÂ̸±ãÇ#KžLYîßÊIÍÞlØ&âĉ{`Mº´éÓ¨S«¦yyõKÍ›cw–ù4hÑ®sëÞÍ»·ïÞ­U ŽMü¬Ú µmÛÆý»¹óçУK¿Ü4ìâØhâŒ4Öh#u‘e¸"ZìÕ¡‹nÁ£[ßÝhä‘H&YŠw鸣OVdB5åŠ)©å–\È$]*>9‡UZi[™X&`—l¶é¦s_’夘QJYæ•V¢™f[!¾é矀’çWsŠùc•>R‰èžDêè£26(WaŠIØ‹˜þ˜)£Uôé§ †ªÕ¤Xúdf2x檜޶¦¨þ°Æ*«P¤VeêŽ-Þ©ë¦máÙjQ¯Î*ì°²Ö*U¥–žÕ#ž‰öÊ쳈êc°ÄVkm Æ:u+®Îòš§·v‚›¦§×–k.—Ù.µíŠd²Ú¡»AÂû«QçÖk¯’é …l²PR ®¯ïú.§äÞkðÁæ‹Óü.¨è¡?,±³ÑJë`‘ËÃÆ0dì1y ß´/¿ÿ 쯦(Ÿü+µ/qì2 (ˆ:YàaóÍ6‹!Å"|ì3œ[= ÎD㜃zì™QôÒ_¨êôÀPÇ;¯š6Á°4D8&BÑYGµ5ÑRÈ$Ño%s\½te'µÑ1S56Îmÿü”jç­7þÑY¨¦Ñ=çòMAìÇÑë¹X‡á&w›²ã*÷ú+¹?\=ÃcE÷ESÑ[m@„áKK±P€^•êvC•6é°Ý5j£ß<lj\á½7â›- À†oQqÄŸçð­zª{ѧ;6÷ÍbDeµì}V(¼»õÍã4ßUM}ëP¡°ýùxÔmÚóx„­×à6i¯7ïØ)Ð4Ô{ŸÙHG?´«-^ Ý$÷4©E†7L£0–ºÒAæ‚þ7;¡RÄw3Ì„€xáUH@"Àà„"ÐÁ‹fDœLÑf—£ •h¯ÞŒ‹Oá\ Iw=Ô1}¸ÓÊ÷ e©Œ ¤ó俨¿ÈÕ‘Žáj\ΈAÈ0ÑfêS ñPƘ 2nUAÁën¶†*Þ‹ddN"‰ÏIå[ãÍé1~Q:´™ë?š1omD`W¼‰ÏxvB^+õXSÞ,}ác™òG4ÊÄ‹´Êi:ÔQ²’71«L›ì”d$.}CÀB⥔3¹âÍ⢵qSj Úý–æ<lvÌ£ÿhÂvF¦™XkÊ(ÙA™hÒfšþ«Ê)ë)>:’&tßT|ÚëŠí <§@~^s+Çĺ‰³râ°-Wˆѹ45 é£òÒ¡ GzÑ=,2”Ì`RN9KÂä”*õÑÖ0JœP0¦1©>Sx/žzåŒ mN3ÁøPì]-½™EïXàá¬-ZÎÉ?uš³qLWi´ÔœÌÓ§1Ñæ?¥rʱ E§6Ñæ4›"Vƒ)óf»ô Z¡sƵΛ1é¥ÍR@qβ(e ÚÚp5@ –Íz¥+c K“²¬1žÌS"‹šÖ„’.J$Ø”3âôsD«iS0k°PâA´XA¢YM¾àõ¥W»þÂ8•JÇ0íW¸ÃÒî@Õ¢\! H¥ÑÊ5„á W}ÌÐáÚ¬ m˜á¼káƒÌ8y[.åk8[mÀk³Û…¬IñlÕfZòâÁ¼ZÍØ§3ž1F¾Yß²`ß½D–³`¡$w¡‚_ýò7³L)0#œ„öåµ/¡ ÍêP…ÙÚÌ µðáV¹´6äð H Ý€€ÜJ©(_ ¬Úê@‚¶,®hj°†ƒéU" riÌ —‚Ä®¾ä>vJYBPñVÀ´… ³r¶ˆòÍ®;V ×*ºó Á4‰ägg2Ô˜ðñjðe2ÑÂü”*ë- XƉþ™#˜æ˜hùÁZ¹š‡5Œá;Q h ÁÕb¬2/ÌxoqhZ:€8ŽU¸ÂÕÂ`ÝÍš4“¯–Ô6å­·LoÑÖ:ש¨Õ)"x™h)KT¨tš*¶ÔÛ–1í̤Ô&?˜ô˜ ÷Ò:&ådª+¸‚9)±&Ýn=“`nØ8±5œ±òe<ÄXéüˆ†äàj‚Vì>9*¶WÐ(é /Ä41\šp’=ô%ð*›n0Ñ’V¢ÅU*Ú,5V¦\mÞ;*°á¶\´Çp‘Ö¦ánë³M&HTÛ–§rê¥l@á{#öK.~>Z7ܵY1íÍþší;9 hÀŸñPâþ9uŒtÀ# Îdž¨>Õ6/lÁt k½A:*ƒœ8®ÇŒZæYE›ÖÊBWZf œtÓä·NþˆÓv£Ïà°Å™¼o–P+/íßG·÷S¬~>¬Ç„ìÛ3;É,8¬ôÀÐE+ mhsÇN¨EDóx:¡…Tq…„difˆ5d^µY4¡Mb€Zx3¨~b§•f%ø@ôÇVÜssh3up(‡4ˆþ¬Æ€v2µanKC~,x3w—GÏg3|†x6Ó4SÂaECWà+µ4ˆÖ!צ6t0X %`áw5¶áˆ0v…6£oö—i›Ç:6ñ~9!uVA‹E³^hv:!`Uá‹QÁD-¥W”T9qJtJq˜Q64…/±vëE7cÁÑø‡8q2A˜GŽ0aZúù˜ˆÞ6c x7“ŠU0„KcÓV4äæ4ï˜m‰xbnq>}¶¡4KÃh Ñj#^ðd€R±t6!ƈFwxl;CŒ4á^lWf)ì³…/1{3á^íWkšîeY:þŒø^WP»øpcñiß5Së(“ãÅ“Bá“ÿ%)NÁrçŠGI4™”7³‚x·4ßTâöƒ»òŽþrƒÖgUU ±*V4-畈3úFˆWc’Iñ€5AY¥çeÖ£t»¶79&¾v^8³’;‰3ë@‡“6AY™¥“†o¨|i‰3[VMd1’5éKƒ^Ùä™bƒ3ƒXTJa”mÑŠÖòèØ7rE14K„ná9j°š«™†1cÙ™ÇÕ8‰‰%%û¸4Ò•±iw8Gix––‡‹ItáØ@\·h8k`W3O¨6oeè2i‡ÞXÚtîþ•dgÔ–4AP8µ‡2‘ˆÇAcqFxYÝ©àY=È™í)âIJJ±ýA›–è™qçX}UW3Šƒ¦+Xð•Õ-ïèŸ3sWãmf’‚Ecx‰±rÎ)EíBÕ©dˆDS–ס^±3ótyClþV[dH$ZH´VWôn*…C„^u%TSølÈc§iˆ£7£¿V5 *™ýA8³›ŸY''X‚•‰WR"Õð«¹r63UÒ›x0Uî‹·%RJJƒ Ÿ„¤àÈy´'™`!¢4;Îɘšå¦q±xÒ¨žèµK¡^2¡ŽB1”þ5ñq_Ajyiž3ú£,ùž>*‘µä—}á P©–z©˜Z©ýñŽÚ¤UPŠ7ƒ~.rx€~Wõf n@ªjƒSš7GUbÚ‚êô‡w58©ºº«¼Ú«½ÚDc»jDS¾Z©P4Ǻ¬Ìª«%àÄš7iЫ @4ÓÚ¬¾š¬Dƒ­ÜŠ© P8àE`i°4EЫ2@4¹ª«Ñj3׊©8@4-À­%@4>©E€3ïz¬`€3NÀ«>°­Ý:°•Ú¯8c¬Ø¯83¯ØZ¯8s¯–ª°7ðÍê°7±–ê8Û±ÍêÜ:îñg¦Ê”7ƒQ­èQ>¡ÓÇþXnÁ!VB¼5%免È3«7cͲråw5à±@‹©k3š©éŠ3E{¬ÀŠ´AÛ´ {5 À«G{3ÿÚ´ °´7“´Xk©ÏêV °³®»:´x€±—ªµ6C±—j°6#Ýj¶dk©n‹W»¬öÊ«íŠ\Ûµ»*ÊÊ­u ·ôª®m‹3„Û°†{©åz3çê·] ²Üºí„nѤ3èª ‚³ùyGa॰Sg—‹m½¥ReUœ‰þÙhº¯;°‹©{3?»¬û°¯ë±µy»«ùŠ»X{» ¹àb‹>û·Dó¸²Ë´™ ¸8üÍ*¼6“¼•þ ½73·½j¶Ö‹©Çk3h›»—j¶‹­Øk3ÒˬԋÉ{¾x¾¶[¬—ª­7#â´’Ë­Ý«9;ºJYcé”UðŽ`šW›}Çg½¢65ÔŒ3aYwÖQ ñW¿÷»¬³k3™º¾áÛ«{‹ö›Á»¾|Ë«u˾]Â#¼±“!|¬Áj´D3µ™ª¶"Ü­¿{3 ´ò»¬ËÁ»Z­ K—êÁÜŠÃ-ܬ;l3=\©J¬ÃDóÄP\ÃFL°ù‹­”›‹æ¿8Seªna |% ;tzÆ4‰1ÁE³àŠÃU& Z4»Y;0& ¾Wܬ!l½þð½x T,ÃVÜÇØšÂ}{©±Û´EcÃA+)¼4r`> S»·‹œ©{[¾Œ½»º¾Ý«ÁÛÁ»¬MìÉ4Œ3µ{żk3K¿Û­¬Ê¢LË¥|ħŒÈK°[œRj3öh²6CÌÂ#–KS‰EÆXs_ð‰Övn½BšE°äÆÔ†( J4Þ–Ç•Â73ʼlʳl©ë«½ÔJ4‰´>ÐÎíËݺ¾›ÜäÛµD|3ëì±’¼4`P>Pâ,ÈŒ¯»ÜÔKÈ»úÊxЭôËǘúʪ쫌Á•zм¼ÁxÉ̪Рݻ•ÊÑÜÚÐg‹©š<ÎØšÅØ*þ² Aª“HÌx°•vìhÚWbºÕÌìÌì›A²Í´ŠG>}31À øH41ˆÇ—*ÈålÒ»Äx@¶"ѾZµDÛµDs·‹ÄºêÔ=°T}ÂMÂrà­¼«" Ïä|3—ÈÀË® Ä?üɎˬ"Ît믈,Ò Í­1Ì­Nm½}°q]©ÍÔÌŠÒZ r6¡q‡•%+%eÚ¹m©‹w¼”Uº†#ïhQ Å}Em„-RŒ|5Çz½Ú«]È]k¶ÛÄ*ÌÄ ´° ´çœÐDƒÖ+ÛÝ­N eÍ«8¬Ñ»ŠÃÉK½®KÒo}¬¼ÜuͬNþmܧ=¼}ŒÃó ÂÍ-ÑúÊÜ8ƒË7ãº÷¼¶†½¬ˆ­‰Á¹ÎÆØDò’-%A‰‰ßx0Ô(ƒ¦¶é! šU>ñŽ/Ý-êmh‘•ª6üz5®µ"}µãm·‚+¯X{Û«ÐÔ]©]á›ÂlÛ±‚œ ʈ»¬Ü{½‚¼áÞ­ÖØúÕ\Ü̚¼:â}¬ÕØØÌªâ'.ÄÍjã—úÕÃ]ÞºzÞͪÒEa«^¬TE3Ì>‘TÿÛ+rŒ3e€<¶š(þ ÍÑ‚ÍùJ63$0®6âìµ|¿3Ü!Üã¾Z4f>°\ ´®¼ÛM°h´_mâ(켆œ½•ÚÄÙýÍþo¾«ŒÐ˜º¾Ìj¶ÙíÔ.¾!Lç¾J㤌ϮÍèθ®mÑ>î«@Þ¬¿¼Ó,ÇÞy#À>‘º«[OZ49) ý¿S’å8£² B•½Þý£é@ 6¼Ýû¼4_Þ´ƒKϵ-âÖÚµ8,Õ)þ떊ݯìA ÒÀÞÖ¾ZØ"á–úÇÍêÔÝÉ-nì›Ë}¬Ôi®ÝK}¬ÖÎɃí«ãŽ©u‹Õ•þãAëbKꑨ6Fx}W³‚2ƒ’]%g¼4p Ô\4wà ù¯nÙeÒ›O¾j“ݲmµÌÑ~è¼êÔêî±f;ÛÝÊÖŽâδߴ‚¼çkÑŠNþîßÄ¿­ËÏ« îáºò²Œ3·>шÜàù¬¾Ú®«-Ÿà2î«;Ÿ©9¿î•z阞hõZj3ðŽïxß¼g³ï¥y'ysjàmÀIo3^`ÆWSm›¡ä»ý¼ ÿ¶ßÞ´<öܪÐ)ŸñE#ò›Â)Ÿè]Ëö‘<澚ë8#ñ˜ªçC 迪ìy¯Ô_.øT»4iî¾v-¾_]ñËŠÃË­«κ ùË:ùÕ›©0.ôì´;ÙMôzsÙO¿4rä#ï¨w@ò¹yÃѳDXª‰•Wó}›AßèkÀ-ó$üÕDCì‘îA;É]=Ä),ü„M4gÏ­þ½ëkøe«Ôxùï®{»ø˜ê¾#M­òq~øEsóÇ^îÜóÍÊýmß ðýn¾òÞêþ™j蜿«DäD^äEÓÒú™yäßáÆ ^ÌÐÁ“Pᄪ<„Hð CŠ-&tCb9,j 2$…‹%)iRåJ–-]¾,Q²ÄKš $P”PS§K­\ØÙàBŠr@мÀPNP¦7ædŠ”"š%œX´5¦E0Q‰2¤ú‡†YiR4ÛRÂW´4}0lUîK+ gÎMÉVaX—cËÖÔ›oK¿ Ó²Ô›ïbÆ)]4f‰ÆâFˆnJª¡üÐ"”ÌcL~þf¸eË ¶±ˆ¢ ‚P,Š„ Àµi‹(!G½h{n Ú }¸¬[щ  ,%”ð¦¢Ñš=:¹½’wo“¿S’eXä®PäÊbOxX'ˆ‹Ûw&EK<åqi(‚úÒ=C02 ^hQ|ï ­»|k!0âŠ.(œC¯,õlBn>ãs)AÃdÏA…à“o!Ý ä¥Ç o!:2«¢4‹®ÈÌ ‹rm#,¨ÃƒÔ*­Å‡®¸£7 b°(Œ‡lÀ ¤8*Ú"6‘H‚Q¡ ;|)D…ä(n®“¬H†¤( +¬èÏ¢4ŽªiJÿ:“Ê…¬Ì F9Z.!(‡2P8)©Äþ0ꌲ@/RŒI–È[¨OÆÊ¤­Î0é„p%§öò³Ño”"ÕH»ˆ ͰˆÀ#Ú ¸B ‹°àT£(ØÂ´@âD \ÑH‘X r°F[js¡ÿæÊÕL…¢üK‹H8»:ìÕW<¢”40€Jèv²ÐM`™ Ì· .Ö"£M¨X•UòV•pÈî¶l?ÛU§u««i+…Ì3÷¶G!sŽ¢1H4‘"/HdÃ"2„>‹#†‡®ˆM 5r¼H ‚ꨨÖ`£µ"duHÚ¬³Þ–MCÜ ºMr)š@è’:+è=ë©YV“¥|M’ã¿«¦þ *Ùv½¢- šiÚ¹$+rš.!A#¼ÈV?“¯w+2z®«³¼JH]¡4,Óô=+ú¼Ñ˜_Šö’l_Ìø‹×)WñÀfLìèvX»z믧 ⇰Èa6<WCS‚7-u|ó³o1 ‹Vm¼ýÆ`ïñà ìƒ>ý[Á+ºƒ|¼ý°%2p‚ƒþ´äƒ® ó‘Sеâ¥þOq@@¹ä§?õóžc²¤¡ 2 ‡.ø¿ 9aƒÑYa]ÈÁšKzÓÃ^uX*ò…}=Ô^|X# qas_“8€ÔЉÄ3‰2¹KØlò”¿æÅþ”²`Ó˜ÇlI*!ÆU6³ŒF$âÑ9‹˜a6ŠÂEXÄKnÒ™ßg½"•†ÓœçÄ£2!CHg’Œït%úòf6„á 1È.’KnîÒ—èh@çÒ¥ç Ô ÍŸ:!ÓÎ0.R‘ÝDÔ§¬…€¤Ÿ˜ô&B5ŠP½@i£)*MÆN†^ž¯<#ú6‚1Šâácã?C:Ób^À ºÀÏESžö4( ]gIsÍkJ3š™E_ Ó$fÔ§Oí¤ÛUªR¨a¦PÏ4ª”2£R,ÊÔöÉ´ªgÅ#Ùð@L´¶5¤Wm IµzHˆN2¢v­B(Öþ›8ä@—dmŸSÝ:X,F‹~4$lbÃ ×ÆÌ{'õjW%*–~f 1ø+`AfVÅv6…\á£gEkLÆ2&«ŽU$QyhÔ¢ŠFÝ+C …°Àšãhu[@˜]è„».iõ'WÔŽ‘«k|åÆpÛOÎ׹υnUKÛØâŽ±®p»+—ÛOÁF×»ßïA§ËâV¹‘=¯d9¤ír³¹á…o|åÌñ’×¼ãSí3úªövs¾ÿp€=YßÅœö¾œB)d•ÛßL¾WÀ†p„ HàÅ”÷À‰ÌnD6²`cTÂqˆMFáÅ\8µ  ;ŒI‹ØÅ/†±N&°þרÆ7ÆqŽuŒã˜ø¨­½&{WŒÉìØÈGFr’•¼d&7ÙÉO†r”¥÷ÙÏt =hBÚЇFt¢½èEŸ€Ñifs†Ìa8'QÆt¦5½iNwÚÓŸu¨E=êQ;ÚÓkŽ´›yXé8ʙԯ†u¬e=kZ×ÚÖ·Æ5L}êTëw5¬Æä¥s=lbÛØÇFv²•Ýç]wš½Ö¥ 2W/ÛÚׯv¶µ½mnë¹ÙFu¯92í8 »ÛçFwºÕ½nvþgúÛ·ŠÉݸj·ÛÞ÷Æw¾õîwsúÙl¾Aæmé}ÜàGxÂK=êpøbÀÀ©­pŠWÜâÇøû o‡“Y7’¹Ñ̼@Ó$7y¨Qžñ2¯œå/‡y·7èð` ™L€æ†;ö0óÇANzY!FÇÃ4¥#›fzÌ u©WÝêÇžyŸ?p†’œÁjFíÏÓqÜ*¤Üh>º˜©Îç´ÛyíSOˆ¢Û÷¦Ãüí¦MŸy÷«÷½ÝYßóÞ20@ÌxÁÍ’r2ÿ[«§3Ùkv÷½ÌmŸBÎý!îù™Wßçáß¹ø>~ë_m8à{f~ò•?}c¿þÎH Ÿæ% þÌ ;ž{ÏTÊËÊòÂç» ¥?çõ?ýÔ—5¸¾„=3€ þ—m};s_Ÿ3¨½3s¼BR ;³;ßà ¾4k?·{¿4S@3‹À=»Àt«Àlë¾3ؾ<çË@ý#Á… 4ÕÃú«³`AЋ»žSˆÀˆ*Œù¼¨c€!àºÏ#³Xÿ;!«H(@‘) ¸­¥ò#º3ûLˆ3þ‚€»§S» „›Sˆ3X,3Ác¤SºÜÁ,tA<`P<8XÆs:ôÓB CüSC3K¼æÃ.àÛ»¼¤#äC+Ä4¼!@³ûû¿üÁ*¼Bô;C*äÁ.T<<C1\Ã3ÛÃìûC DB„ÄCL½„ÐD<£AÁdEOã?: A<Ã3a´`4C_þôÆh´lœC2[ÇŠpÇ@ŒG„$EC–LˆˆdÊ‚DJ 4H>üDx>œÅ…àäG< È4cÄ ÌÆÅ;¼”\IF|¾¤KFKÄz̳‡Ä´HŒ4LE{Eö›@ZL¿pÉ*Xˆ0\èBî¤Pü”B¼JæLP3[ÐSl; Ë3< U}Ï:»¹é¼³½ã‚]ÏÝ´öD»•@pDµ[|¸5džŒEŽ,³æCÎLþfüÏ›LÓ³”Ѷk; |†´Ð% S§sÒÃQ õÑßL?£4Ký|;%õÑ33J'E1lR4ƒÈ5$E/ÓªdÓD lÈ$O=S=8pÒôÒEå3!=3>ìÓ:ã¼ÄƒðëÍ÷ô¿4»¹.¨R+P‘¾áCÁ:l»Q…Ä/Ò ½Tp>.}Oß„ÐôãÃ×D:8ˆÓõCAl>ñ$€LE³›ëQª3SÅÄ!@Õ1%€YR[ESa½3Å£Õl>JFµÖDsT3S¼ÊD³õÎ |65½Ðf¥N“ ;(ìTP%Rg=NWÇF¯¤×ä¼UÓr´×ÙDP"þW:¼³]ÖÍK“ˆSx­.˜×ª,>wõW‰ÜP;ËL©$×k¥XBËV=J:cD@ ½èWdL‚8t•ÒO9 ÕENR]L  %Ç>$Çz}ÕXW ÍWÛdØT½Õu%³;%€XüVи×`|Ù˜Õ¾}½Yœ­Ù¥M³XlÓ9[ÙÏàÖŠµÚF4äÕ4ËÇ­ÍÙjÛõû8’}Éß#a“¾T–uZ£½D©¤Ù›ýØ2ËÇ` ÛÅœ[ÿÓ®íÙ¶5È_$Á„[ŸÕ×ztC…ˆÈ.Mˆ½=Ó»õÛèØ<›Z“¨Ú«µ\4ÿ{Ç2‹Å¹lÙ¹SÅ+Ó}dPþ [³«7éƒZNÜY`ÁÑDÐuÜ5¤U$ÈгG¼µÙ1‹ÅÍ…ÑÁ•[³ì„Ñ ÝnePr}]ÖeMÞEÑ MAvÛ4ƒÑüÜ<á½ÜìE³‹UÍÚƒ]1Ë]Uˆ×$þ=³å<3 Ô,4…>é³Ý3»Ä}­»Âʯ­Q3[] $_XeÕôCÁú3è”ÞœF èÀîÍØÜ|SÝ`¥ Øõ%3ž]<ûÓASTíµZî-³7„]_œE®ÌÍn4_3LDÕ_=]Ý}Ü^5Å2ƒÑæ³9½Ï¨lPü­BrÌÝ­á1LÖÎç%­µ_éE³|ì\ÈýËÑí]¥þá2CÎÄ}¿í$3".`ìå_:c¬Ü¢Õà/63ÎÍa$¼í³€X”ÅþK„JÙØØýËObų[öõT ýÞ¿ýË„õI¥dÛvÇÛƒh>&Ӧί³»ÜÍŸ­=6ŽW<Öºœ½6äÃÊüÚ:3ÊÅÕÃÚ“c ã"âÚ;ÖA.dޤK¬¬dB~á+na7ÕG:[YIÅb0Ö^1n¹˜]ˆ3¨Zù;XFDd=Ôå*ôÃhg:ëáôíè¤ãZ>Kçe˜–éY#–S!^[Z~å}ÎÞ~^·P¦–ꩦêAsêªÆê¬Öꌻê­öê¯k{ëê°&ë²6keë³VëµfkXK붆븖ëF›ëº¶ë»&µ·Æë½æë¾Ö5¿ìÀlo ;magic-8.0.210/doc/html/graphics/writeall.gif0000644000175000001440000000753610751423606017314 0ustar timusersGIF87aø•÷l¦Í‚‚‚‡ÎëÙÙÙÿÿÿÿ@¿¸Øòðÿÿ¿¿!5fêk@@@ðÜNUÀW²xx`VV'Lø  ç‚ëiB@@à4€¥YÐÀòñÿÿ¿¿èò¿!òšêøð`U'xxVVLøððE™™@@f€­û``B BBñÿ¿DçpÍëw@@(t(PWPuð†ñÿà¿ó¢ÿ¿!E™ê(PCxóñD¼{pîß½þž¼x»Ç™#_ï:uõ“£3–n}¾}Ö÷ß»=Ï?¼óÿ•'`8 R‡]ÇÞrõAßbòe×\vÓI8ÛAx v˜á‡‚¸¡QéµÇÞj‰XeôáÇV‹Ö·ˆ†hãˆ5âHãŽ7Vbr º¨àsøac‹V¨Ž=òÈä“9F餔þ¸àbî±H[‘1yd~å”d6iæ˜gR‰&z%¦åŠÍ½FduïMgŸ†YP™kªé'Ÿ¦ (ˆVÂihl)éIР‚6Ú'£:(q…šh)l$)™P¤œNê)¤ŸJ *‚m6¡›ú‰¤à’¡v:ª¨þ°º«§ ¢ªh[½*ë®­öª«¯ãá*ì°Äkì±È&«ì²Ì6ëì³ÐF+íETkíµØf«í¶Üvëí·à†+î¸ä–kî¹è¦«îºì¶ëî»ðÆ+ï¼ôÖkï½øæ«ï¾üöëï¿åN+ðÀlðÁ ð 7ìðÃG,ñÄWlñÅg¬ñÆwìñÇ ‡,òÈ$—lòÉ `Ê,·ìòË0Ç,óÌ4×lóÍ«ŒóÎ<÷ìóÏ@-ôÐëLôÑH'­ôÒL7ͲÑNG-õÔTWmuÌP_­õÖ\wíuÔY-öØd—möÈaŸ­öÚl·-vÚnÇ-÷Üt wÝxç­÷þÞ!ßÍ÷߀¸ß‚nøájŽøâŒ7>µâŽG.ùä>CNùå˜g޲åšwîùçsúè¤.z騧>ù骷îzᬿ.ûìuÇNûÏh™ûÈi°»Æ¿wüÂÃnûí=ïµòç®Öƽ{}ÃÌk~<òA@³ö2sß<ÃÕO¾Åã“~=ö>—O²ú"³ÿpðîSï½ðó¿~¾ÕÏ?½ïÚï±óúûÝî†@…åÏaÊ‹žØ?î1pz”ØèÀ Bðd ÿ2˜Á Žo-ä_çW@ V¬„# áý±:¯~l»ÕL8À6†Ô ¡{7AVð}þ8Ü …ÈÃê|?” ‘xDÑ{&|bEØDŠ„PÌ"ñ¬ÁZр정èÃ)ÊM†RK`‡øÁ%Â/Œlt# 3&@'îO€ZÜ"ãXE<2‘v„_‡è»+þ‘:„cùjHÄCúñX„ãÜеð]°Š-Ä#IE1²b/ ¤üúˆò=’“‚±£`|©@%¨Ç{j²4dè&YzS3Ï£%e=s Deޱ‘ hÙL„Zô¤ts¡J»èEA>0…8¥g?XS1Ú›"ìçG1*IªÚó¬^Mk'Ã:ÑüYpŒ>¥ IãºM·J5“š æÙ J6‚æM¯ZlË›O/FޝcókÝË4Æ>”°¦,êaQz¸ŸºIoŽUZf×Y2Ë®Ž²…ë"ªÐ×9³~–´¨Mm A«ÚÖºVkˆ}þ­lg ³ØVm³e³*di‹:ÛNí“{ƒàDy;;ßþv·†[C‰‹=㦹3UnqË\É9÷hw•e*_\©&Ó¢ñlçwÅ‹ÐêÒîºCcd¸T“tªë…h ŸgÁ˜òô‘ž5ïíÐ+´ðªò› ê<ù¹F¹"ò¦2Õ%uõÛ8þí’m"73Ý4 kÅo:¡ËàÌ98{MÕâx|Ï‹¸›(fâHŸÊácîø;ñßKâ¶ø•ñXméâó²vmþðGIªàÃôÈ+keãôí4È,. -œâ#‡õÂ&]ð’ ×d''Òo/^µúUúÊ—­õ]¡þ¯¬Ï-§®ËnŽ3iá,ç:ûØÎxÎsÑ~¬ç>»™Î~tç-èBSŽÐ†Ntƒù¬èF»ÑŽŽ4à -éJçÒ–Î4T5Íéý2ºÓ 6ݧCMjëºÔ¨>mªW=èS³úÕ\v5¬gý7LÓúÖG³5®wm7Yóú׫€°‡MìbûØÈN¶²—Íìf;ûÙÐŽ¶´§Míj[ûÚØÎ¶¶·Íín{ûÛÇF˜¸ÇMîr›»XÀN·Þt­îvcÍ×îŽ÷ÖØ-ïz—Œp¶Ê·¾÷Íï~kÙÞÆ÷òlw­ÅÏ´ÁÁÍpcÛ7á·^¸ÕĉpˆKZâU£¸Åqqi)Lã!ƒÊþ–5òh•üÜ ÁXÇ¡%€?ÜcÏjùÉ”%s“E«æ%C¹BpN±•3MØ.G+Ìám3 ÏœèµåùÈòs¥‹Œém3ºÅ|¾4£ƒdPGšÔsŽô—mdYOÚ×—Þõª]bTWšÕ_Þ±°íì!/{ËàŽu¹ÏŒîsû^±´‹]æWϻݓ^ò¡á}èM/|Ôùž³OsðƒÇàÙÎ1½ íðm¼É0_yÍ{ñ‚wçæw­O^è™W;èùÕ§¾ê®ï¼ècOzÇ+ ò‰'@àYozÅmô³¼ái|Ïç~ê¶'îaôŠ3Løv#~Æ 3àOßøs—>ƨþÿ6é—¾}ÆäØÚQ/{Œí´šâ×þŸÏQ"‡Nýcÿ+ «røWLþttþÓ¯òä/Ÿe›5~ú÷qðæ^ÄGÇY÷fƒ–c}Û‡}îwL c}ßw€/Å]74BÈ%€Oçkf&SvRhÇ€ã€lµSN¸~È^yµP¦•3((1*X‚jvU_Jfƃõ×4¥|H;äJDõ~Í‚æ÷CGHƒ&hƒ¾‡~jÆ‚ÍT1/"è„>È…ê4u71ø„$È…"µII†B¨PD¨{1X…”„ñ‚qׄÆ]S¦† hJdv‡»•…÷×u¿4ˆGå‚a1þ*8ce(RRÔƒá71èEXX„(a8‡§7€nh‡pˆ`Øw‡ø0‰HA"öˆ'8…ÕtN•`XŠ“ƒ#¸ˆ,Hee\R:’¸‰”W–X§¨{”·1°è‡Å”`­ˆŠÌÔ‚f…E㊠3†Ë¸ŠmvŒ{ÈLÄ(‹]xMŸØsÞ—‹£¨cVè‹ C‡ulj]È‹ÛØŒÈ¨ÒÈSAXTˆ‡í¨JJuŽPx`U†‡Ì˜2Ý8„ÿY9¦Vz¸{¯'d¨ƒ˜¸Ž´tbÙøŽ6ƒGYö‡Îø|Y…6bHf‹·ˆ|9‰ª·„uøw ùX‘ÇÇu³·††½þŒä'Œ¸y¹0‰Hˆ X“'Ó)蓹öl“CI’åh’öÈ;-”8(” x’c‰!©‹#)“š˜“4ã”b•Õˆè•hs“"¹6TY”e“Y~1©’­'•Ñ—E”/™–G‰•L¨”nù{di•zÉ’‹ç’ïs{vùv™˜—m ˜|)—•Ó—Zivt9˜mø˜[y˜%™˜`'––¢¨™}㘞ù3gY—~©–ÁX|W¹—q¹”†É˜]3š’ y ×mH)x³©m%w›Ô–›º™m¼Ù›À©l‚R“œØV›0gœÕ6rÊùlÌÙœ»9sÐ9‘Iœ} 3k¹q©O†qT“ÚYj W0§ù¡fp\£‰äégæ¹5虞z†oþŸò9Ÿ+垨Foö™Ÿø™Ÿî¹ŸüIžþùŸÚ©2ÔY z š  º  º ;magic-8.0.210/doc/html/graphics/corner1.gif0000644000175000001440000000315510751423606017033 0ustar timusersGIF87a“sñg›ëÈÈÈÿÿÿ,“sþŒ©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þ ‡Ä¢ñˆL*—̦ó J§ÔªõŠÍj·Ü®÷ ‹Çä²ùŒN«×ì¶û ËçôºýŽÏë÷ü¾ÿ(8HXh!¨¸ÈØèø)9IYiy‰™©¹ÉÙéù¹x:JZjzŠšªº )*p›’è[[2k†k»û¡KæËœ,F,|^{N¥Ž~È.õÞNE/hï”ï·ÏäÏo@%â)ˆ¡Á: 4\(ç!‰ßPr±"›þŒ@8jLãÑGȹ^•$)l$•(‹™,ò岗¿hÊ„3GΛ×lºä™Îg˜@³µq´¨9¡3•ºcú%©Ó)RgTZj4­Xõ\ñµë?®=Å û­Ù„d·¨]ë°-7¹pã¼eq·.Fºáøêm“WEà¿"ý.%,Ðp•Áˆw0>ñ¸1ŽÈ·K†i™jæË?Orf¸9 åÏ2F0M:m謩ç ñºõŠØ½VË6j[_îÛ‡=ó¼{ìo7´=~:ø’ãÈa+'ø¼yæ¨Kï`}XôëÐiq÷Žù;øšâ}“/><ú1Ù1´_Ÿlû‘÷ðÉ[èý"ôþó;èO€þ-  ˆÀ(ˆ` þ·_ƒ:E8ăZȆùi¨‡ðy˜ …"%b ¢w¢)Š·âŠßµXâˆVÅøƒ‹ÜÁ(#nã帅ñxŽ@.æc6^'äší¨äI6ÉšyPêÆä”˹–V’ðä–WVéå|Zêp¤t]†É˜hN4æ„k~)å›üµ9rj§æ5ÚI¢žbæég–€J&Ÿ5”ÙÜ™„þç¢FJ¢È)ê¨cÎX©‰—–¶i¦v ƒ¤ÃQêé ¤–z(¨ª¡úè ¬†ªª ¢þvê«`ÅÚ¬¼ÕjëªöÊ©«ÀΆ+^ÅfÊþë°Ä «, É6ë챂Iëè³Ðš`íµ\R­¶Áþê­,ÜB6n Ù† ¹èWneëÊÚî¶ïæoróË콨«¯{õŠ ëmüökÁÀø¯s“›ïÂ'œ.Ähìð‚³[±¼àf¬Ågx1v!oéñÇŸ6lò%§\ÍÈÕ¹<åÊ,;3ž3ï[³¿7ãŒòÎ ÈÌ2Ð) m2ÑÍ1Ò+]1Ó;½0ÔKM0ÕýZ­/Ö÷j=/×ïz½.ØèŠ.ÙÞš­-Úת -Ûͺ­,ÜÃÊ ,ݽÚm+Þ¯êÍ*ߨú]*àž ŽlÎ,á•*^­áûܱã þÞã‹ZN(ææJŽ0ä6«çùã‡þ çñ‘.:è¨h:ë«w>úë!öºæ~Ú®'îwê.'ïoú¾&ð·nŸì®Çn<Í´{.|˜Í{ù<ÉÄ[œ<õȽ•ÙÇ<½ÊÝ#¸=”á79¾’åy>éó¸~ŽíËøþˆñK8ƒõƒÿ}éÕ{¿<ä÷_˜?íBýóÙÿüsÀ @ ¬OØÀŸEp=üÐ[6@ý]Ov¤àUôA…r©é ŠF¡0ƒÜàëLXа€;“¡ ix3Þh…,<™ Q€ qˆD,¢G`Ä$*ш(‘ÛŸxD@qŠEl"þm@Å%"1‹Y´"?ÀÅ$n1ŒPôâO@Æ*J1O4£êhÀÆ!Ž1ŽL$‰é€9âQŽv¼b ö¨Ç=Ñéù#)HB²R€\£ ùø‘;Ò‘Œ¤áxHG>r}ü¢* ‚MBR#’Œ#%3iIW°b•¬l¥+_ ËUª2–´¬¥-o‰KU”`%'{˜^~Ò—yf0QJbó˜“Ôä&—‰av€˜Å„f¤ÉjZÓØÜ€6·Injà›à”€8™)ÊrNàœÑT¦:#ÀÎ óˆ'7ÝIÏz"³—¾ÌçìyM|ús §@š€‚®ó m¨CL шJt¢­¨E/ŠÑŒjt£í¨G? ÒŠt¤$-©IOŠÒ”ªt¥,m©K_ Ó˜Êt¦4­©MoŠÓœêt§<í©O Ô  u¨û+;magic-8.0.210/doc/html/graphics/cif_see.gif0000644000175000001440000014013410751423606017056 0ustar timusersGIF87a2¯÷ T†|tZ€$FLÄÆÌLTš©\Pmtn„¤€´ tb‡ÔÎÔ$&+|z”li$!+Œ ÄL=TŒz¤ìîò<6H¬¦ÜÌÎÔDjd|u’$85TVedªž|ޝlY{Lzt,6DDN_\^rŒt Ä†¬|iŽÜÚäüþül`!Ä–´œ²\’Œ4`h,QYÄ~l¼~¤ÄÂÄÄš„<^\F<ôâÜLˆ–ôÚÜÔz| „n˜œž¼œ®Õ4ft,V\L,"\ž”l~œ„š¼lº¬Tž¬|n”)$D2,df||Šª4&+THbDGU¤†¸424üøú2.´’ÌD2D<`\ln„4RLœªÔTPc”‘¯4)7¤Á41=DÝóÐ@-tÑH­´ÑL'ðµ*—ÈòËTWÝÐÔÒEÖVwíõÈyø:]ÔbƒýõÙh#D2Î6×À€#ZŒqú´›@çO…Trõ¨ÓœÂ4© (!)ÂP1PÎà 0©VAºÒ”J Ý$(EÇ*Ö²^Ó¬%ëYךV´ªU¤ûkQ›iM£Úu¨w«^… X´ŸH(Â&”@„Ìa q˜Ã=ˆV$CšédkdÿJYJ6¬½¬f++ÑÍZ–³™mA=ÛYÑNö³¨-­G“á†ö°F˜þC {ƒ" Á¬T`èðÊ۽橽n+Š1Úâ¦ðâánLÕ Â,nðjæV›§U­X±«ÍA…v²àåîwÅk\ò†w¼è-oh=JÉZò½ð "~1P¦ó¾9Lç@o‹U´‘Ö˜B'&POt¨â¶öM°~\ßã×Á®/ƒ%œ` CxÂf0†#œaW¸ÃÖð‡9Lâ ›xÄ^Æþ;wÂõô\áëw·ñͱŽß‹cë—ÂHhXÜ ]pãQD=–b9Áƒ1~§Üà*ÿøÊùͲµle.cù¦r‡ÓÙà ïøÌ?¼/þ~±á&‡Ù¾ïk{1iÄá  €ªKâ÷ÙÌmôˆýè-ÿYË…t›ÝeF_~ ¬3œo[Ó+mò–{½h÷¹£ns·Ý›Ín?—*ÀÔVèd â¡?$Ç-±•:î‚'Ûà?¸ÂK»[r›w®Û¥ÞᇠÁ¿@*JàŒ „Âo”þ1kp’/Ú'/¸ºINn…ûáé·Ìa®^õÞ`¥y¼M.ÑuR‚tH*;Ûl"§%ùÊw.ÔœCÜáL§Ó›uÊ&ý¬ÉØDÙ`‹8! ‹EаQ~^TйÕÍ»†˜Ó\íp»ÜÓëépóÜíè¥üð‚xLÚ VD/|Qz¼£Ìx¯yÜ¿xvG]ÌM9¿ÜèÊSþòˆÖ4=æ`ëY ÚÍS>õ~÷‡48£qˆÂ tÄúóotì=Ïi)úͰ²ìuÿåwÐ#pè XÍ g¡ßïÈpèßìe'SÌS=æ;ß|ê[ßòÕOçn'þÏü1ï>Äc^Ú™† tbPsH˜¬hMçº×οû- æçc î-µüq}bøW¹ËPïgfþçgÿ·`Ò× mð{‡4|äŒrFúÇh›æ‰v˜N6z~DHS z¬çz²¦{•w€Möy:dbk°küƒû7€3Ø÷µ¦Ö~‡¶h³æ~ƒBíSPðj¯×‚Hx{ŽÆ>ôk¸Ö„vWMypTˆrUˆpýÁ€…\˜rÄæn€… biñÀÜÆvpPßpê6u\ø†-…ŽQËpU@î € ÜAÐoEpvo5÷…þVuÍT rØ…Wè…èVÃeZ`¨rJgnEõUU~AÀ ¿9ð½ó ²öx—8‡u¸nÅöYWWW7‹s§xåäW´Èxµ(oŠ'QŽÀ Ù¬f œ Hww­‡W'pÎøtçZwl  æñ>À ŽðŒÈ‹°¸‹4gY=õn¶¨‹ê˜Žì˜NÄÅ‹Ï8ކŽäå]£•[¾ØTË…mSà ÜÑðmÌè(u8s,ˆ_’'ƒ Gƒ iƒElö»vÈʧkSiJtwæ­·dÉkõç©`æZîЍ0yþ™Æ_+è`³×¾64¨aH€ƒ™‡(”%ƒHÈ{Õ·“¸‡y „÷Ee¾Œ½°jTŠzv‚'Ùƒ¹æ}Y‰‘L)ø“<¨ƒ¥¶yby–1x{ci’L(fþ|s „D˜Ak¢'”?I–õ%~~÷0CçIQ䯕·†“z–ÿ7ƒ`‰CÛ·„‰©˜’É„9ô˜h™yC™e ‰CùטazàTåW#˜~p° G¸ƒƒ¶CNXcV–ˆÏä]gðXŽª%^7·Š‡ÈŒ©¥ŠÁV‰(WT r)Ši(’§náœnøL°ñÐ `¨œþ@E°›TWróœ•xpâèVW›¬¨v´©›ôÈVu·v°éŠWHfSh›ëÅsú”OEð{Ap«–Ô° YE‡)ÇRxîVÀx/÷¨5ÒØ›ÑFM7w›t¨žpˆM舞R§‹ùÙ Ô¦\àBè XÐmùxôfo÷àÆ oüæÉv˜è›ì¡žÅžöÙŽmWY ¡j‰BžÎ}÷‰£í™£­à^H•OM¥ÆYq`ÁÀzl˜Šð9Z—œ€QàÙÐz:µ•õUk±‡¦=¸¦¹'ffÙ•©“i¶W{ bh•D0•QÀ Ü`•~ kþHÀ‘iÐ\qpL–€îç}ËÏg{'ö„nê•ÚG”ß—©rʦyi{–y“yÚ©J¹9‰”–ÚkúÕã×€Q OÆW—Y…|½À ¬†gÇwÉ×ø•Ù–í—ƒ}Öô€sù„® ¬l©š@锑ù”ûu[ ð'Ð ÈÐ { `½ôð”ošf\fªçÚ¦¦ª®‹É¬.˜ªÀJ¬ÆJ¬xÚ“‚––è¬uÚ™Ðʘ¹waÒ‡P|C  ÚÀ­{p±ƒº_Û~F*‹ºi«](‡]}uˆ눉G¡:ž™n0 `z%À Fð ðˆ þ E°Ÿžø—FÀ ¶J@ C ‰†Hžâi¤Íˆ£‹X±>ë¡*´]8‰âx£?Û¥àØ]y ˆ&Ç£Cû7°z8(û ÷  PÀ  >ñð ÐÎ/° ±ÖtëYuE¡™¤”ÈxPpNò¹Žq;·í(:o70‡ô¨ ˆþvv„x^c¸\)à\Và½ó \š‹L«´: ¤@¤FÉ·û¹¤%·ë9^Äe´D‹¹!ëLö˜·³9ôöR½ Sòä² > ß(^øˆv ʼnTzœSEŠD Ô…®ôI‘rºªë:§éœ§®—º”tÊ÷—¼Íþ'~äg~#X„­k6¯õ7÷åªÀW«&«W$i‰—ó§¼9½îf=†”¥ ¿šŠ§††_£*½•Ê¿(x§Ç¿Ç}‰®5iSÅ«èਔڬÍw[P \Ûà %0jŒVkØï­€Œ™ÁÁ:¬«y”ðŠ€ËЉÓŠ•–g~Ð|˜šÙ„F“¨iD0i‰ú ¬‡š|Ö¿@I¯9¹hËêšÚ7™Cü¬*ˆÄøš_>©„ÆËšˆ™üÊ}DpÀ¡’pp•æ“>Ìõ êæ3ÓOÙ†½]¶K ÃÝ;“pÞå2~Ævj×Y¿çvÄ­ƒù5Ű½SÝ®¹¬ Ú0LôãÑ%J¡ôùaúWDK¤/ú¦ú¨ÏEª¿ú¬ßú®ÿú°û²?û´_û¶Oû¥ŸûZ4úaTúa!ÀûDpH°jS »Q°诈þž}Šn˜ZÙ`ÈÀj'  Ú0FP¿ðÃïù£ïù§¯û½¿û©ÏúDðJ·¿þìßþ²O·ÿòËö8ÿöÿøŸÿú¿ÿsàûñ"ÈÀ $˜P ƒAúzñ0"D_)Vô•QãFŽ=~RäH’%Mžüïň 6¬¸2áÌ—4Œ—Â6ž=}þTèP¢Eþ âÀ]<›c6…zÓåĈA2ZÅ1Ož¬(½~ûqàQž[ÉžE›Ö'•žl×¾ê–([·Tèò¤[ÛÝ»{ñþõX¯`Àƒ FLXñáʼn?öÛW/_¹‘-<´ò[¾Õ~þ3\À¢-w¾ìÖìiÇ­¿† Û5c´«MßF{¸ódÖ¨w—VœzöpÙÅc'ŽÜxrļÿú.œué͸­_oÞ¶÷基ƒ:¿kúròÊÍ·Î\½;6ÛØÝ?‡ïüMµ<D±ÄWTÑ@EÜðÅýÔN;Õ›1ºGû..{L8õ<ûqÂàtÎÅú²S±IŸt2ʉüPÆ#á›ÑÄàê»±ÈìÖë±:È*ë FÁ4„2M)dÎÆ§„“¶!]þ’D,ÍÔÏ;ó sO?çts¼,ïüÒÊ?ÕDtÍ4Û‘I!}ó44íÓ?0õÓ×ò»°­*¤/Ô%GQT>ÅÑ>üÆäÑRQ‹B#EkLXA5³F2¥#uÇR{5ÕWaƒÍ3ÉRO• ?öò8VÏ£n%òÙ´~Í”/4QýÉHµMr®8 }p³2£ålº>E7QsƒLw\g#¶ÓKœrÕø¸Íö^}»¥Ó2ç ÷-ñÔb³ÕC¡•2¿í½|ë}¸Jïf…«KruvahÙ5VÜ&´¨ñx4XÒ.tØPlUÞv_+›…µQ[ËÝLÛÒÕQÓšEžc7¹þ¼V_ˆY¶·¸‹ËuwÞbÏ]÷ÍTõÌ Ãwk’jî*>8²]2ÞqC¦_¢#n9ÙK—Þ5f—ߥ¢á}®5T«^Ѿ½ l`±÷zå‘[÷¿£‘&T0lÒAit:ë\‘5æ¸s3Pµç{èÌ«´;r»ƒ¤uÙÑVþ—'͉×7·NJÑ Ö‚÷¶Fáía»Ïþ´Óž¿ÉŽm‰K^ò–溹­k¤Á Ìr6¹ºÅ.@Z\€ÝU#Œ Àê¹Bµ.Xý“[Êš¶Á jLËÖ·µvi|”£NgÀóЦ€„ù¡¥ ·>¥OhKÚ]¿!æ 9%daê·Â6­‰T|ÜÚf§;2~‘yet¢ãTx?QqŠ5 âr‚ø-dqïnŒŒ fçÍKÞû ‡åÁ)¶lBäßò|g6MO˜³b$½øD<Þp4<î0f/NjSx_y8E"oŽi+ܲ<É¡÷¥P3dó öÈxQiSx;$¾r©=)ÊÑ”‘¤#"¹þWJ:Ò•9Ì$ }·F\ê Žõóe''ÙIÔµN…,f%#€PÌ:S7ûòÍÎÓ3Ü´QÄù—o^¦|Aç9»ùuÆœr‰§Oòésêœu©çOòÙ“vž{¹'(çY—~œ}¨BåóNˆnó üü§Dõ’нp´mëd¥1Eú  u¨dê9Έ²…¢~y©KÚ“­dôk$%m§@×ÀíjIÜØ"qK˜žÈSë,ê`ʓⅢtY);ŠÑ2½´£ÝK@óˆÔ«ž&ž'õ*W?êÕ‹^Õ¢*EiVÅÚT»D•Ÿ(•édÜÊ“’‚”®XëFñÚþTµ óWD,=÷ŠÔ¸ zUêTûŠXzÚõ£ÏDf+yª®’ñò@zƒàHÙØ;vU¯î´)6ê*­RÕ°Š¥GE+VÕöÓ´øœi_Sл¸ö®UŪhQÕ¤Z&¦ºM,hÑZ£¥êv¢-5.c¥jÏ™ª0›ÚlLZÇ:Ûæ× g §p³ËÙÊx¯4Òw?³H"¹»¼"Ñx»Xñ­5­ì!,p9k-évW¶ …ëtº[é&´­Ž«|#ãѯ:U±†j}íŠàÛÎVÁ’‚+ƒÛÆ_ín•¹Boʶ˜š¹æu¹ð|pv7ÄWcôzŽcŸw«×ÃìÈyrÑã ±þÒÞ¦&puŸ*ÛŠn¬ŸÕ oeªÝÚ"×¶60ncôÛÑŠøÃma«|÷Ë\"§ÔÇE%-Ž|déÞ²Û»ì<{·qÁeBë½ìz~8§±·¥_<á ¶¯À%¯è§¯àœUóãˇCKªEâ|?Suœw÷þÜï-‡¹¢\¾bÊ2à:\sã^ü³Ï±†¶i;Ó'ßéi[üÔcÇýa¡Þûžß5˾F(±}ã@û¶ñ©Íú™ÏítOÿìe6µŸ öª×±ˆÙe=7ªßìròÝ·|¥åæëüµRebÝàT¬42JYó~?þ•­oòjø… ­ã8ä»6žû½E;>–@o4®Ë<¼?(ë8 ½§c»˜ë< ©#ã+û»¾[·¼¼C½ÕS½ík½› µé û‚¹LÁ©Ki-b3?ü3áÃ2ê*7ÐK¾ +À’ó/àã1Ý37Ãs°¬8ãã7‹[­®%°ë¶ì´~Ë8û+ALAÖc1ןð9±è;ñ‘f»C|j¼ÜÓC:4DTÔ¹ó³¿(ôÀXÜ=ò»²(<@ <:Ó+5 |/-TEZÌÂè㶸±BD!7žÂZd¬þ[Æ¥J¿º 2ÔÀ¸CÌb3Hä†j¾"«7`…pdnb…~Çq”~0Gqä&u þbõäß(.ÕâÕO2…`Þ½}âPEÏ™õÝ 6ÑZ]Y­Ñ,PWo:È‚PÀPšW»íÔ8.'Ì<úM i´• Ü‹)øÕqÍÙS%Ðhp‚ˆVoˆ[[Yà&K½âþT6^¼õ`µäù¬ÜUØM®äýOνžÜE$ á¿s*áâ?âLåÓêuÑ*xZíd* ð…/ ÝàÅÝY+ÎUÈýbáåeSMYåc÷åÛxÕYÜ5ZV.Ñb¦ÙI6Ñ_ø|^õ‡'`eÀØ øæ&ò\Ú»½ÛÀfaíÏø¬|DÂñVé°8hÏ<Àfkþ…fVÆ^ÅØ€hý+èÎpRP@QŽ\ÂíÕW5\¼mh†~à2\`È\t挖ÜcÆÛn„ƒÍ#ÎF=Ž’¶yÂ­šƒ¢­×e΄þ%æD æ_e‡Pðòõ†ªµ,ÕRPZOÎ]X¦Ù½=ÖX]iþTf¢Õ¤}bÕÛj½Y&jžuâß…åÅQ6ð×Ucðt&(篆j•~ifP"­¾`Äc¶ÓãtНÒÊß]5êj)†éªvuÔ¸Uã­p‚€bËQ"6SÁ¦h öàÌíèýà UÇ}YrxÜÍ­™?¥©›gY2§ë‡êÔ]{Þ`WþÏþbêÅg*FTP¨5€ÚÙôfu×h€×îµâW•fdîU`vé&YíýÝ÷”æLø¦•æ^Ó¶ímõäi¨Ø€îÎmvøØ®UsF^[mfYÁµ[l•Âó¤´Žç&'®ŠíÝžO|ÎfÒ†áöv_HÖ­¨ŒõNöaƒvÞ‚Õ\‚¥dþÖmUÕoá¥aÿ^èW~ì–ÅÜ•æo>ÛB![î«•Af¹CUUÞb–6m–%j±Þg†PÈ‚˜Re[,ÕìÄUó„k¸fàÛ=Zðã ·VõT§¿æð|Vb@V·•f}]e`ƒX' Ö7¦ëé.þgøÌT¥nfUåðX¹D<ÒG\k6ÔÖ )†r’UЦîТvïdVÐáÍ4µÏ2–6hÝb0†5–]¯ŽñÁ.êô®Üì.jÊ­ÖÀõäWåØ œQ†·s½y2T8¾ífæFWUÐvf2k¢îg5¨X*ÍØ$àwÕc>îóŽíÚÍ[é­ViÞÚÞmâ>nÝ•ÿ `í¬ZïlW]–ã÷LrO'uÉíôéÍuàîmþ•qÅV½ÛVR>#Õ£A$JåÁ6ï¦]^]Wf_7Öõ¦n&.b¿ýsûÜæ/:èb0ƒ+•…vøaöLècŽl!>l Þà‚%âsOÞŒðÿþi¨r¶B—ƄٶûzX`'ѰŽU›…t€×ñÒ®ñöÔYa˜}…ªÕêE6d_îòí¥ñ¯kîEâg7x/ešþÑ2wE÷Z·Ou¢á1ŸdHçâwÕî5y]mâ_ê(BÇr"n½òÄø-uJ['æòßÕdèb¦½Ý*¾øŠ¯OI.s:GÑ=WZ.†ðQ_…hP`jÆsË¥\;ŸöqsæÐ@wÁÏÕ÷… ºd‹Ò%õçu_Tgt^åíÿt{ãûsŽtŠvñúô‡àöæÑpƒþ뢟û1îõ]ïR_í2EíÀÑp]+¸enb‚«¯æIÏg‚Åí­Ýñþ=n•tëžaá¥Íà±ù…pMDœ\¤zŽÞI†Ùa]ñË_ÕØ~tFGuEèÁåSNVOèø,°é¸Õ®j á>a¦è–­àïýT¯4¯»´E¬ fy.õmíðK½|(îÚŒgÚêÐÎû2÷RR(ãC~xhä½ü»ßóàNyUOØ–:Àá¸ýNeˆvU„5"×HF®‚ å’að!C‡“eŠ‘9„1lxÑb2Žb´xQãEVv,C¶—Ødä‘ù’J1aòì óæN >w-jôeN¢/iÆœbÐ"˂Ʌ,™+aÉŽ«j}þh5×Ó§WIæÉ31,UŒ'Vüèua#U€aóÁJ“è€ Í[’Û®mÔ6-©d+ §ÅèO˜}ÿ‚ •ÉÓrÙË> ꙳ѢThÚ„ÉÔòÌ2$¥b=뱪aš‚É5$r¬WÚ2VënÜ5+Ȭ(I»Û ?v_d(»{ÂÌNÊdTñõõÖƒeÈh'‹-fÅ”)£“%±z-^PåàdØKo‹2$kÛ½{|x{«Z½)”‰|ÚQuÕ š‘¦TR¥†šhžýô…Τӄ3ÕSïøJ%ô¸ §ÝJµ„bY"ùlUÉHJX­FJ#þê1Š>²ãM1ÌxÃÆ? ¤Þb"¦µU™`Jí€Á‰-xY±_h6¡ƒ™YxThZ†65TN¬ßF!*”oÜ]´^œ"ˆ­)ÔßuvîégW«qGdÌgÆÆ$1](ŸØØrS&‘Ce|Àí ›¹GçŠø‰Åžq%3lë-‰ÑUøý9§›¬æ"jŠ(Ò–Ðf–ùÓ™5f„a {š6jŸyè•b¸–Œû=Ë[YQ‰”Xn6fµ-­ÌnU# ð…,œÜÕÄ•œdY’Žíè‹Áä¤-ÁÈ¢Ï@U¶Oe•ÖÓ—R(¬þf¥Ë« ýØ|U×U´¨Èf‰¾§g  [œ‰œ¢¨ß|¬‡lŽLpGÇ"„Æ8•ŽcFÿá„2¶~z³vÿ‰TñGØíIj~;ËÉ€†d³C%U<`H(5!Ó‚ºn l˜ q)°…Ü)¥¡Pqt|âYg¥â´.6LÇE—Øâ’1¹4ÖmcÉÈ oáÙ²|Á8,F1¶èÐ;êÌÛ–ã”G†ýJpÁXGÎ5—þöóU jÙc³·|›˜gœ(zÎ$U²™ (É¿W_€A^èF÷yÿØÅÌ Æç‹_€Žz€ž‹êiΫ¯øþ6è?ÓÚHN5Æ~tê¶y®,è â´kLIÅ䫘óKùPZ—&¾Me­jªx.»¦ŸAÛˆg³¹T+ÒY+¹í$WàÖ¤FÐ(>¦RËÿHâI°ÂÌ` "ýCårNl¡.X‡7 ÙÀú¹ U®3À’œ°„5„½„ Ð`°çŸèi¥N«ÒÍj8–3ÎMËá×Ò2±5B¡`N0l$oc:N ÈSn&ƒ,Ä HÌè‘ ø0“Äða<ä™Çœ…<ÿ¨?ikŒÈ˜†® yyš¿¤Ôœ0…²Ü˜Œu“3í$ª©Qé‚&ª êLTgLÕ{Ó¢FØþ-7®B #GfºÅÐEEŒÒwÂS EéÀNHœ¶x÷É|@<ÞHB'MÁ…4n_˜ÐWGË,eCbJLn ¦Ò5 v­z0…“´…TO0îq^Ù6rªÑ1O[ àÎsgòd‰8èŠñ旬Ť¨;`HÁU†òd)8žb¤È,çq„‡²ëX˜´LÖÉÇN¦³gÆÒâž&ð±–¢Õ·¾†oWH‘AÞâ³|þ¦=¤jY\$?î@ÉãÈZÈ­¬Æ’þE46 ”AÐ ”…ª …yÐ-ÖÊQ4¾à N

%Qä¸5ÒtHŸï»ò`³PdNd³ÎZä·ÜV®TÒ- 0EôÀo˜¡pÁ ƒ'ÅVýÌ0†F»­KßòÈ´RB¯ÜùxêXËÅdAßøúá>zÆJ†Ùž2‘ù”bz%dwUËY»é-„@I ÿ ’2Ê (Ø~<Þ;ƒ3;ˆà n9À¦T‹ „7:ñøÂpP:†ÆYþÓfžº%1ú\ZûPÓÊpµ×XUƒ¥@Ùïmé4S ݬV„Fø¶°$9ÝY÷÷Ò¾ .8Ø„íÌÁ›ªk›ÊmÞfóÜ%±1!éV·rJÂ8F¶§þé@W¸”9^†9î]ãWfÓFì8só¯T`W5"¡ƒÂ¤Ku‹><ž ­’4¥1»`¦ÜÂ7ÕzcœLÌÆy˜2¨$‹VmÔ™Ò>Æ¿ÀæS›iÈ PcÜ=Ö²¡±ÚO]ËÏ ·²C#c¡7œõöPt.hWå^r0¡ úèª7Li¯™ IioR¥ê9qK-¤F¹%·Þvi±æþ›PñˆZb¹{”ç…Ï'ií²sæ©Ðo·s!&ápg•¶t§èlYß@…˜c¦´A¨ n4÷)9¶s`xYœ© DÀ¾á”9›^ÏbÛ!S¸¥-eÂG€ÞºqþõÖØG…„~ŠÏÊd†…½Îlÿ’,ycüQ5\ÐJIP×þ"˜Ù.Î-‡¸2c­<¿ÅFFs‘Ž#»ÓCØÐüV!‘õ°…õPuý9 ³G;*;ˆòG4NVSèGS„ò²wxÔ‰úµÌ‡·dtîÇÃB”ÈÓ[™A'Lmþ»ib÷ ym‡rRã·ZéîœdkË"Cyõc}¢WÓÒúOTlmdi9’@Á0þ)î¥5ƒFøÏX ²û:˜Ú7gº„ç Þf‰‰ôÚ3Ò·N}KbÆY$|h±ÞÜÙéYwé ‰ˆºj¡‰‹ú+¿õ¸ÛÝ¡ôHrBá :g ä„,ÚÑne‰Û ¸_ª¢‚ìáx}ûIp}ÇJø'ZËè©€XXÅ»bÜ@É;ä)‹1°”qÅÁ"‡É($ÝÜ(ÛŒ K±¬ 9¤fä¿(qåZP9È‚¸«|[‰0“ž™õa…fÉ;¨Á”þÜyDG–lŠJhŸí“ÒõRÁF ®ÊÝ…ÅX4[³ÙYÞq¸]šZ Ã\ÜŽ2´–¼–/ JS1 ”Õ ™!åJI͹\½¡ÉÝ…\D²Ý™;áÿ¹ÎJXy$7D9h)žÿùÏK-OÍa(å†ÿ¥Ê‹xÔ“=™ˆ(DH`šØ¢áÚp5ÖN™†ü„.9×èVý€™E^øy¸]‘ KxY nSuYšïýÿ|"‡ýIöÓ6Ü)’ÕIÄÉy½ˆw@‘²5Ü™ ðmK§ðøPØ ¾Ë W®ÅÁTBõÞ † €… þ4ÊxÃðOЈ˜·Øn¡Ý̈bÀáBhcXàˆ “8 ù[ËM ,©‚UQ}€áÒaHI îœ@º€wà€`ˆÑ¼Y ¨L•ÚÌàfÕ×!$ NÙéYÙLÐ<ݫӳءF„¸¨Á f€>Öó‰à5uÖ^ÁÓK} bEޝ™†ç¹]¶]—Ù!ÖDeõ™CZÔ£Ušò9P€U@_JÙÕ ºh-Œ´SQ†MHXTÈq[;Hª=„hùáhIÒŒ@晉æ] ç=˜¡†AõšƒQÁ Ô 3²ßFÂŽ0‡XÑ9‘]YÖK-YpÀ¥DØŸ1þ“ õÞ°}nåU¸ù’=õRÏ€Ýuù‡ëˆÄ ª_ÂE¶]¤A…šk‘GY‰Ù`n—‚IÌ•ß/ ã¿åd-–ShܘH-ÊßdRx1‘y4 î)Óñdš«%BOÉiK¶`‹9‚œhÝP¶0 [ :ÂAHÀbÙZLJˆ tažíœ@•0C¢ Oy!É ª^³¥DÞVg]¶ä Ò nØðÒ@rDßY—2Ê \<Ý]Ú)lŸÍÔgTà@ÐÉ€Š5A|Àt|»|§#¾L¯ÀݶäJY…ÙRe±gB˜Û”„× ôg èômâ«,O§,RozT€þD¥R:ÒÝPÅFÍfme¹E#E’= „b!bÍ®¡<”š°W.(Ÿ$,Ž`¨XG{)T >Ë#ååŸ=â‘*ÜÛÐçñ©bíW^¶I¤„“ý^UdÔô)ÓbrâJsøˆdJ£2d0Áّýõ‘îÛg’OøQ±ÜO8EˆÃ<,s¤é\ÍâšØg0ØEìŒÀn#µET$ˆ«m ‰àæ¤úSbTtÄpöÚ±Üq²#0ê)PäD?CWUÉ8Ã)A_†:¬Î*wÌê¬:‘T)ÌCમòª¯îª)Ôª¬êªk®æjþ°ÎðÊ@±þjC<ë®Fk²N«³æ*´^k®Zë¬fk·:A³ë¶"k(«¶zë¶ò*BH«Pk²öê¹r«­z]¼z].«°’«¬"+­j«¬†y¨X1ŒÃx”‘ŒÔÈÝhÀã‚F ‚¶úà›P´ °AáOÈñܪ¿î빂+±þj¸Š+¼vë´–Å·‚«®VA¹‚+¯&ë·îj¹–+¯ «ÌûÊ쮦ë¯þjºšB„‚ϲ¬Ðºì»‚«­Ú*ÀÒ¢Ó2-Ó6-”Ô>­ÔZ­ÕV-Ö6íÕV­×r­×–E×R­'„-$@,‡!¬-Ûª-Û®­Û¾mܶþ­2¼-ÜÖ­Ýέ!XÂÜZ‚!Ä­ßþ-ÞÊíàî­à¾­ßöíáæmá&ná®í8!®!D.ãJ®Þ.îÚú-å®Ýb.Ývîå†îãzîÝ‚®2ÄBÐ!ÀÔæÁ×RíÕnmÔr-ØÆnÔjíìæ®ÓÒ.MŒmtí8 C,@àŠ®évîæ~nå2nYt®á®óf®ÝBoôV¯õ^oôú-õ¾-ë.-ëBí÷zoYxøvï÷–/øzïù®oùª¯û†/ÓR-ë’/äÄüþ^þî/!è/ÿöo.ü/ °ÿòoïïçoÿo0/°C0K°0;p[°?ðþg0+COpW0—°Ÿ0þz‚ý’/ýÒÄüù²¯ ›/ «/ ß𠟯ëÂ0ýʯçÁc0ƒ° ‹pWpY°/17±?1?1 Oñûư ï0›¯ {¯ §¯×ÞðûÎo »ð“¯ ³0 £pïoÍq¿ññÇ1ϱÿo±¯1ï±˱²÷o°ð˯!Óï×.r Ã/£/#Km"Ã0óðÔæ‚'rkò'q2(‡²(+ñ$—2ùŽoOq*—2ÓòÒNò+§r,2"²ëòoò ²ï².÷20÷1/ ó/óþûò1s.'³¿ð)Ë€%Ÿò*Oó$«²÷Zñ÷z ³26k³-‹1 “-2ó/ ó2›°'<ñ:²;;q;‡28›r8r4S3>ss>O3Ùª2*o³9t1Ÿó8´2 43ôAt@±Aç¯C/´{s ÷³-ë3F—1=ï3+·î ³nN ±1s2I£p:¿3J§ô(w3>ÿ3G¿tF³rH§rä‚3B—´Dëô:çôC qO3´P‡pP'ôõþ"5 +µ:+tQ'rMk´GÃô>SuL¯ð6“í d²B´A35!œ´J5Y3ñ=ss?Ç´UÃô)OrZ‡þsG´W÷r;p]5O5A×µ\wµ_¿q_ûtS ö\¶Óò-ûó«5c¯µ['öëÏVóð_6^²X—µfkö<·´=76h¿ôM×´[cr3µRßµQ_öNÿ4`¯vRv.Xvlÿ5kÏ5Xc0 G5TCó6;6pgô [ò[{ÂQë5/çökǶþñf?·f3vq7uk³!ëOik³kÇ5l37«¶N§1_w0xã¯r³vjË6m—ôxòz£0ùêÏ*ÓEW·}ÿ¶KŸrb³0a÷ï{··/g6tø(Su~ß7p¿p-Ÿ²MÃpkqwo7Qÿñ{?¸x_¸mþGø`Kðy“7D»q…‚qïw=g3‚‡¶L¶M'²þp…+÷8 8×xK7‰£ø}{sq“­vS¸QǸ¹†Ë6C‡xeù‡÷^Ë8ÿ’6McòYŸ¸}Gyv3¹]ùÓ¸w¹Yÿv"#¶Žù4ƒ4&O6ƒk´S/ùR#÷/w¸w»øÿ–ó›gx^/÷W'yœß9‡Ûvi´ Sù˜—2o—1opDù„£³s{¹£;1Ž ºcïvŽË7 oõq÷·¦s· —·…ëù¢‡úA#ù¦¯ö*[º˜K:™Ç÷gGö-sµ‹úsù£×º"Üz (B®ë:¯ßº"”…¯ïzþ®;¯»±;²»²óúlûº¯_…³ßúl‚T{µ“µ[»`»¶o»2d»µs»¶‹{¸{·“ûµ›û¸«{¹ƒ{º»»·Ã;ºÇû¹³û»×»¼Û;½¯{¾÷;¾ÿ;¿|» ü½<¿G;´#|.;®7|¯3üÃ;<ÄO|Ãﺳ'üÅ炳üÀ|Ç<LJ|Y(€"t{µ—¼É£|·«¼¶³¼µ»üÉ›<ÉË<ÌÏ|ʧ|´ç¼¯»Î÷¼Ïÿ<ÐK{Îcü³ëû¼½2¸<ÒË»Æü¶7½Ç§»Ò'}½O}¾+=Ô—;Ö[}Õwýºsý¸g½Ô;=yL=؃üÓsýÅ'þ=³}п=Ü¿=ÑK»Æo|ÍœýØG½·›½Ó—¼ÇüÍþÊÓ<á ~ËþàãüÛó|Ü7¾ã¯ýÐS½Þ/=Ù½åûûä_~åc>ÚS~æs~Èï{çkþço¾é“¼´»ý³×ýã·~Ü7{Ûç¼ç>Þ‹~Þ‡ûÈ›üß+Àî÷¾Ìû¾îÿ¾ð¿îÇ=ã»>òûüÝÇ>Ë—½×Óþó‡¾óg~íÏþíK?éCéSÿék}÷_ÿÞW¾ÊßúòC~òŸÏϽ"”Ñ_ý÷Û>ü#}îk;ðw{ýÓÿðÛþã?ñë¿ñç@(8`Aƒ&<˜+—Á\Ê*èBY ‰)Z¼¨þ€¢¢+~Ì("IKn©2%J,_¢<9±%͘6IÞ9¤ÎŽ9M…thQ™D]"U HYÂF•:5¡S‚ †dÉó§Qœ^{šÌ“çcY³gѦU»–­YªŠÆ¾•;w Ô‚M JlÊS™Ö‹{?ö囋¯_½„V 80â€;þ«òäÁ…/7Îyó_ɇ;ƒÖ<šsâЋ­ÄK—u뫟ÖD}º²èÒ·={Ì“k#O‰‚Ì/+ü#ñÆ/"ÿœyÙ“o㺖ž•zÞ•I· = öúWìÛÁÓä*»{ØìÜ—WŸžýx÷JwÂ_ï“2ì«©ÚŸ¾?vþõóáãûO<ù´«­LPÁ³ Ëƒ¿ýìzÍ ÆpÓ‹²Ï»3Ò<Ûð±úhÓÐ4-ôв?4±DOL‘Å+̰°êZíÁm¬Ë¾y„±Ãe L†“v[nAµ|;RIä¼ÑµUéö´½÷ ð;+œ@,»$Jôè¾2«4/L÷î’J'¥{“©Ô¼«SK.ñ¼óNTNÉãôóÀ&á¤KÊóÿ†2Dƒtñ±Fc¬-RF!]ÔÇMg#±ÓIiS”Ò+Õ¶/MÂ6 …P?Þü”ÔY9µÔVS+IA›+®×µxnPª¢kõÉWþêËe³\ÌYå™Ë‘Ùæ˜i®YçrÚ¹æžKÎ'ŸzúâAè¡ó)C.ÉGŠ¡‹núi¢—&Æi¨—ni¥™ºž¤—>úk®¥Æºë©‹¶íª¯¦úl³Ëv;ûm¹ë&»í´÷f{í»éþ[m¸ûÜoÂÿž;ì¼³f|­óá9Ÿþ%§üæ›aÎ\óÍ9Ç™gÊÞ™¡]„N¼ðÁñþ[A´`Ý…\X½usú²cuÖ©},ÜÍ„Þé÷Ùƒ÷}øâ'¾÷ä?~yà…o]yã¥/zÙÙ…í¹ßÞ{íËËeÊ!ûòIÞžûõÕoü÷Ág~õ†¹gî­nŠib¬¾Dÿ¦­–ÿå#€ `.d`4«YMÊÈ!øò€š˜ M¼ øÁ®„´ ÿJHÂæ…ûã =˜Á Š0„2\ cˆAýÝP†9L¡yØA ã„ÿ[ 1˜²óÕ/sßs"øÌW>)F‘ŠÝ³þ¢÷¦Ŗ킉%ëY5Æʰ†;¼]î`wÆÜ)#vgìKìvsÆ6ªqŽg´qG5êQŽxôãêêx;>Þ.«Ó£¥?õ‰Ï|ãCúȧȒE’’“´$÷YIí!Љ<à$&ó!6íÄ¥ KyÊR²‰ ¼Ä+ ¨Êž’…¤%)C Âþµ•¦!/¡J`Ò’ää*S©KV€Âì3cùKú’iÔf1e¹Ì_6óšÁTf2«ÉÍjЛ½¦8aÙ´l2PšMKâ÷vqÊî•#é›bŸ˜Ï+Þ³ŠOœ§'ëÉïÉs•¼|%:­©@c&…·«þêFeÜqw¤E1šQ‹RÕ¨Eáé>Jî‚eìC¡ˆÉ|N2¥#õ'@ß·½$º }ª$g ki5†”8] Nq¹S`æã˜ …à+;ØÓ’“¨®¼é•:JútªB¬jkYÎb’Ó€M[êVÉTN攨R-æWÝÉÐî4§-üiSyA³–uƒØ”ê+mº@žL}òüž(å?Lö|„UâËÔgX–¶o¦ŒÕàãH™T®bµ˜nª W×”A6%œ½]E9Z?Ф¥ãhQ[Z56¤ëcdLåç¾ÀÊ–¶ó{_Ñç2À:Q¨ýË%*ƒéÊ 5¨”-åCþÂɼ¦uœ¥4¢-ïúÛ–“¬ë”.)‰ØN$Žr•·¬%[}ë]uþ°œÈ .*éšUéöï¼ÈL/.³‰WáB—¾½r JWöÞwiìÛ)b¹øØØÚ¶¶&ðo+ƒùýW{xeÿØ ß¹z—hìl.)Ê:îδ¸ë¨[7ÇÖ]ôŒ!.1‰O{»ÒĪõ° ¾—ÛÖŽE¶pk_zEØ*Ø}§¼çX{JÌ«Öwªp… NÙô¨BÖitÁ»P…"5…Ž«;a8Ü*û¡áý¥^¸U»*”€cÝ*u U)¿Ìq=kaiЂy²D†%ßܵ;«µÎ—ˆä}þlÅw˜Ð"E°¡ ½É@;öϤ[nSK™P`–÷©it£¥ga5Ž¥Ž#ÎtŠAÝG‡ÚÓ© µì8ú8U¯Z}—p™øTíjC·v¶¶­õlKXÿ*8¿Âde„»ÛNê“ÀÅ/{}meb—Ù•Ø}îxÉ\ÞŸÊ ÙS2´zÜ,O¿E&.+ŸÄ¬ù6Âäì6„Çý]³òw…ìv/°‹í^ëÆ÷ºÜe"]½[ØÂ6±þÔ1¿ŒÒóØž¢”õø¢¬Ü$?½ôÖ°~ƈßNõˆ?Œ=c7ù©Q,jÌgüž¼æG>s»Ìðâã+¡ýoDÏá2`©n'·=[:õ™ÚÝ©}ã+nÆ›œÛº´ÉIa¢¦»ØÕån¼‘=ám*·„ÁNûzki]¡69ÝØ^ë|uZýëFûç¶yêüüÞ¾÷¶ZS(W’$íþ«’®ºóöÌSϘ«SCRÌM5›/F r!…M ßóè¢î”z0W2 Aòù†22VSÕ;)-My ±ë MÛ1gî@‘ÕXejÑH¯±T­O•²¤0ìË› ÏB‹òÂpC£òCŸÒ[G-OÍÄBtQcÖ uÕ«@Ùu+õXßgþ^Ò3½ça‘ÍN÷`‰ÚvøˆÏóIu/«ärürTV{OS}Q-óu`Rü˜t÷J媹"2”‚K#¬´4aá ÝVý*SÁ´@óÑ]´X 4^cÍî ”MŸu=×’_ÁïëtÏÿ(/Ã`‡ ÉQKPþIhk³Cu37;®OÝÇ]ÝQ@@×u]!u3”_6Ðp®c«õùdÑT­Š$'"£ :«Ôí8éÌ~l?õÌt´ÏBQ½Ü”Sj©ölël5y´®äVÊx5<;Ê¢P#+Kßî3[Öiå5±®3Nq]Î8Ép,Û4ËÓ#ƒÎ·¶Â(N[5Í áè/\‘66Á‘´øt6QìQ‡“^ËDÝ5EÍ4Y5^{Ìp_ô31÷nTH«I³w«)/ó¶>ùÏ-ñ,b‹OËÜÌ$Ávª|ï§ÐÒùà®ùø5û“}ã’a‹d‹ô¸h¯ÌV1AÕ‘dÊŸ7vUþjU4Yó1·$õjo޾°KG#LKlUL³V§¢ˆöâòhOW ØCK¬ÃžÜQe]®}Û·LÑU°ÒÔp ï%ñ®°³oJ#—’N ñó{réoÙráê­ÎVìjÕû@øÙX‘•:Û$t‚êÌêÐpSS1FêAµ‡* …®•wn n¦žv^ÃôQa—eSVðš1~Áj=e>ÓnƒÛP5e B/,)A—CkS\5NŒysŒ=O‚_ÆaíLMt+—V^e—?[Ô‚Í*a¯¾æÌ{‘{ÊféòbÕkÿЋ¸î7ù(v—°­³_izµ6{w4…þ³{#svIE¶»vgT÷ü« ›uŽvLU·]Q™ŽL',0Ò¹k¨sg_óÖŒû4Å =,iogYËÔPYvŽx‚]·”aR¶Æ‹Ä–ÏTU?Õl³CuΠÙÏöÈJ•n™T Rp—ð­­“5øÚ\‘éÚÊ95økgø è¶ywÝ é=gÖÇ0'‹‚OÙKô‚ƒµK—ÖM'1T§“f9—Ú¼xÓ046?NhÁ5§rtÏ8¢!×qˇDÕ›˜]sΔß8@õ­Žƒ×q¶,OyÙ+o–†ÑYI=µÍÙ{÷ H†§T‘;ÑbSš~þÍ’ß5Ù¹ârìÄWÏ’÷Ù)Zm÷Kÿ™Ðyª÷ j˜9g6e9©9-ù²5ÃZSâºõà :‡–)q'—ÑøÅ&:t!0Ä„ù£_­åi‰iw‰©–ªéÚùQ×ÈmT•¬®Ü A;ë³q¶ GS!á¶Út°¸ òxËͳêŠm)Œª¢Ù¹o Ñ0mGò„a8 ã“;Ê"ÃÆjF¹‡uŸ!—ŸgWY™øþ”³îÜUúòs‡k[‘ò·%®ò@÷—I×—K·¸½õ¬ûh£ã¸i»£gÛq¡˜‚Mö+1ó×Zµ¥óz’Á7‘i:¡w«±þø¯ç ¹ŒO0{ ¥¥Nx—:¨Û¤•WÇw½Q2{%¬¹üz?‘y 4Šé8v7MKÖḇs)¿Ü--¹ ®‹÷—ƒû|¹uY£LWÅ:Üäl ÄE|ÄI|,HüÄQ<ÅU|ÅON\”FœŒhœÆË°Æmp|ø@ÇwÜÇk|Æe<ÇsaÇ{\p\Æ|È—\É‘üÇŸÜÆ<ÉoÊ©œ!Œ¼É«<ȵ¼Ë£<Ç¿ÜɯüËyÜ˯¼È‡\̃|Ê­¼Í¥ÜÅIÎY|Îé¼ÎW\ÎEÜÅ3aÏ÷\”øœÏýüÏ3!Ðÿ<ÐqœÚj<hËÆþ"Éy€Æ'}ÒËÒù ÒùàÒ1ÓiœÓ=ýÒ9}Ò;ýÓKÝÓM=ÉSÕ3½ÆíÜÄYü ì<Äe}ÖCÆI×E¼ÇÑÇ]ÑÍ×UÑùؽÆÔ‰=É“}Ñ£Ù{]Ù{]Ú½Ù™ý×©Æ‡ÝØ­ÛƒýÚ½=ܽÚÉ=Û§Ü}ÍѽØÍÍ»ýÝÇÝÑsáÅë=×m=ßG¼Öé\×E×ÿœ!=^Ð >àsÏ[]”Týѽ×#}ØU}â%]Õ™â1>ã1žÔ/ÓUýÕó@ßE~Å©íÅeÀäq\ѾÆWžÆW^åÜ×;¾åÙÜi¾ÉkþØþ=æqçiþçy>è‹=æžÔa~èþ˾Ñ>é‘>Éo>èM~êG¾êI>äKüäCœÏ%ˆÏwàÈàÃáÿÚÞÙ¿<Ò5~í AÕÛ~íá>îùàíqœîqä­>ïm â^ëGœá¡>Ýw¾áðýË€Þk<ñ?ðqœÿð ÿì%ñêc>ˆ~ó)Ÿå ¿ð£œñ5¿áó`òiœñ Ÿ?õ]ô;ßå‘<×ýþßg_ïõ¾äs]ëCœ2¡)þ࿾÷Þë…_Ð/¿òiœ¡åÕž2Áù¡ÿù¥?ú©_ç“Ø•úµŸú·ûIò aÒÿþñǿƳŸÆñÅùÄk½ýi}äu_Ä5¿ï-Ò‰¾ô-¿â^?ò•苜ñ‚2280B>e(Dذ Ä„ù䑸0F„ "$¸°áC†A.¸±$ƃ|4žDùÒ¤G™,;žtøÒåDœ7G’+9’$ODm\,Zô(R¢g˜:µÑêÓ¨T§.]ZՆë[‘fÊ•+“Ø]bs)‹ökØLdË®M+“Ïϸ*CZ|Èã¥Þ½|eò ˜¯`Á»\4kÔ¤y_µí±d¢‘­J½<™ ׯ7%²$g’%L’ru~–‘Ëc]ÒS‡ÓóGÙMÏŽ­ºµjþrÊRRìóái×Ãq“MücòÚ¾C+¯ˆ:·s¹Ó MÍ ¨æ¥ÛŸNþivïÜep5Ïý-ZekÛfbŸV,|±<ܪ¶N[7ë\y‚Þ›ÉÈš\~-DÎ …ÇØU•9È`„Ž•wQ?­–‘kmÄ!:!äas"æ4âI"tbI˶]-ù‡!ªEÇA2‚˜bˆ}ýÔI:gb‰- ‰¢o°¹á‚Z¡‡Tw> eRLj7%Q¡ÕXñ©µ¥–X~E$†Êõ—‡]ˆ¦@Ê…PšlšyãBqòÞxF5ežàUÖeZáiƒ@øIW‚0š"v·æ¢þI€¹ãm}å5š‚4¹ãú×_ ()¦ òÁÑ•ªá¢<¢*(¨ ZÝu¯þ•×¥’Bé¬Ï§àŸHEÖçRê å°Zýê+wyl9Ÿ{ÍŽeV—2Œºšh8ä}ç!9ã•ï­øå6®‘ã‹?î¹æšËzé™;ÞøéªNúá™Îºç2ä=öEx—‡ÜsïÎ;Û´ón;íM)Å£æOñä4BŽFËÏöùk£M»úç«þíïÏÿ¾Ùoã}?ûï³/ÿç©þ¿¾Ðr¨»Ü=dÀpœS`@F‚~Ë øÀ NPƒ”`/þ¢ù€·ëÏýN(ÂâO~êc¡üVø6–0+¬ ñÖˆ^ïyÖ“™‡æ%£z;lâ@Àî•o‰Ll¢½Ç¦P"|a ­ˆÅ^±…ëËÝ û3ˆù½ŽƒÜ ?HF"уeDãÛG5¦ñ€¤Üï8G6Êñ{ü ÁØB0b1‹„T!ý‰E@ʯnk#rª÷¼ òð‘Žtd'ÙÇ8P‰Oì¤'? 8ºÍ…$4d! Y?BŽ0~]|á-˜G<ò‘Žz¤¥,݈KMÖr—·Ôe/3 L[fp7$fM‰ÌSjQ„Œœá ‘“ GFó’Ì#G4%™ÃþåíКÍã¥ë` Êpг|¬%1¹¨ÌtjQ•'|¥Üö7»XÊs–Þ¤ç/…iÏyæ2˜õÜ'>÷iG}–ñ|¶û¢“‰PuRŒ¹k§ ßç|+G¯ŠXO*“ C­«cÙS‡þU¥m]«[ÙzÓÌ¢õ­œÅìf=ë8Ê13íªiéúJfŠ•›…¤T«Iº6¢ %Äa‹[&zu«è ƒ+á WÆÂ‡3\á—8ÄNpŠ_üáÇxÁ-ÞqŽÜã '¹Æ3ò‘‹¼á+xËMó–§¼ä/¯ùÄc~s›<¶õ ¬ïcèŠfÀœà„*8Á,HWºÒ Òt¤/]R—:Ô«òŠË<ïOÁ§!ˆ„ƒ]ìaÄØÍ^ö³«=íl'»ÛÑþöµÇ½íp¯û46ŒÌ­–»«vnåù°(# ç(F1Œá2”áŒo¼âïxe@žñeüäyËCó›_üå=ßùÉ ò¢ç¼ãAúÒ£žòšO}æKßzʯ~ô³7=ëUûÏç>ôþºÿ|1††0X@.˜3¿¿¸w1[oȆ†º!‡0TÞ 9°Å¬Ozëk_ž·þí{¿ùØ^óýaüla œ?ýëW?úÝŸ~ôÇÿýò‡¿ýÛÿ÷çŸýô׿ÿçÏü—Nïe|AgHýVhç3 Ð8Pj œðÜgÀ ` Qîö`õ`Ƴ•DQ èC~%X&‚Ž”‚”Ä<$(Q*X‚°µ‚+Øh'È{Å‚Ê3ƒ1XI4ø6¨ƒ<ƒ/„Ch‚¨ñ€øfPyIÀ ¾ðì€2  QvNÉçX¶¶]"@þÀÁ I` '`¶àp PÂ@Dþ²ÅCØ´†DXƒ×Ã<ýñcÕ”MËc‡yhIzˆ‡{è‡}ˆw(ˆ|8ˆ(ˆÉ3l–oX˜PMFhý£ ¸æ]Âà ðÁ x"à Áð¾à &^á%[H%^@ƆÕã]®•ŠmX{Šrˆ‡ &‹FX“dŠñV‹ªH‹¢h‹«ˆŠ§èh´dÂ8‹kVŒL ¾@˜¨ "` lð ð‰†Š¹pekéfcŒÈUŽ˜h\è`®% ¡„ÌP VàpPÈÉŽ%Œ¥è‹äжH¸fõˆ÷¨ùÈö8€qe€\åsµ|"%0[§˜CAä…_œàp'(þ j€Q‚5[J厶K%UIÚ¤‘´MÑŒÆZ"‰k¥hQ<Ä’Àˆ‘.I‹»æ‘9I,9“8É<ÂP gŽV :á°•ƒ¯u)Jü×¥…wv;ÀfIå‡þ@¾ Ià ÅÀ •' h¨†Ðt“'i“D‡ý¨–ûÈ–ké–mRÅv`@ePØÈ|yÀék+I^¿¸“•ø“Ê`ŽÞ:à Ñc'è’­¸—^G¥cðV^!yIÓUEi’Ö]OµTÞ¥c2ŒùZñö˜‰‰ßÅ‹ŸÙk£¹™’ø`’éÑ —V0e‘2†2™‡Uþ)oËÓÇwcOÉw‹ö^Ûè "ð’?Ön¾Ö`ÀSàpt_ GYiÒ¤˜D4릖‘IÆMäÙ–çù]ਗ਼ ©žU=•wÈ¡6·Ã øIX¢èš?ôH›_à 7†¸Y”20–BT’I©f•ÔZîèš°5D§XE4š7XIÖd^oh‡1YMÒSMCÔ’Ú‡*’I“Ï# ñl` ƒ™ŽN $º†+ɆBÆfkV8Ÿ å”?7Y·Ó)9a¤(i“¹f – ¶P •Dz»y‘¨ñM¤`™9UÊã‡|(d¤9d–ÉZcº<þf*a‚èžQ¥¦~…£ä—òIœ¿%b†7 ` ¿éžõ™ÛÙ˜‹ù< Ð“÷A tÀLÐcÍ šñØC‰YDà•f-y¦¾(©'dž•ÙšgzM0©Ì)š¡™’¼hI—êahMÀ}Ø Ã¡zQŒŒtäV=jWÉ&Fe¡š“Y}nâP<áž«CT½èÿ[À/)þµ®Á»[±“ NpÙ!ÛÀ…ùÕL`^J…bH†s›Ù ¨#žk':XM¬¢§½ÉÎs¥2.“k¼kÍò=øTt貘¬>M€R$hÉyu` ;} @/ô6ôD?ôâÀW°ÈïT)Mœ»¿úì `µZþç,^ëÙÚ¼ì)aÏ›½m9Iì “+V0 ÷޹‰¡¤€ŒÊ Æ`xÏxÍ&;ê<„çú®BÝr“—h\¶~M¢:Ö¶o(ž{ÝÇK›¶PiQmèž ƒ®•Xa0^^À g cÙÏÄÊ̯iÀ&ŠÁ)o‡’ÚÉŸ,Ò—,Úgö¡lˆÚÑ*Ú·þ˜úePÛ¹.n»-h¸ÍJ"på0Ï€ÜÁÜÃOÜBM à ÔK¯L²‹6ਂtí§’i¾®/¯úêÞMÎõª‡Õº¼áº¥ô}Õ@‰ÿ,ã@ùæ¯ Å`PÖZ¯Ï“ïyN³òù½žÀePíiÌ×~±ŸïínäÈÉÈE.¹F &بQ®\ &$h!Å\ >”Ð#ÇeÈø†Ó‡ MÊ(ãôO–,:œVž°’„˜/#C‚L˜0Y®Ž=BÜèqaH‚EæÊ“ÇcSˆM…6µØ4PrT b RjB­V2ÍsjOžšP›‡À ¶mצmêIÄ.þüjáÅ[ŽGß¿<.ñŒwð_{\ðÒòÄÖqcÈ®Fn<™@†ž@»ìØPaA‰¹~íp`Æ‹‰>ušŒ¡ÐЙ|Ê6(»í '¦®”R„ÑB¡“ÄX1fØüsùS’ '2|à¦Ýaw>æNYrïá»_žûÜÇW»ËP¦£ûÓ=3E(û¨OrX%¾GŠºa¦£ŠÂʳøªO'‰Tëh?e&”d Æ›•l F–œf!Ý dÇ 0þQFä,ÄAò[P dH9ª¾Ÿèó "ÏÊ*3² !±DZ`S‘Ç?ú1¬«š€«.²pô"¹œþ¼Ë¯ú¬°ÃvÙK-ÿ*§¯>~(LIóÔ£ÌLDPгƒ*Ú¯@ÏôûÅ„D­§ Ë©†|"EÏv*ê#øRlä PœPCB[˜)Æ›`èÈ"”O6ÛI'|aÔQcÐaR&<2ïL·F%ïTSÓâ.ï,‹ "`+Mµˆ m¢¤R„Ó¨;yUª‘<è30WÓxò(ò€o!hŒfª©ºœzåï"cçC”1%c’¨n$¼Õ5ˆ6ãJ(²Ê‘¡ÝݳIeO³ˆ!9Ý¥J(}ùÜ“œØ‚ <'™‚ÌI¸DàáŠ+Ò9†a¼ ¾Ⅿؒb†ßxƒaþ†1ÏàUÁs 39ñõO[ùv5(Ù‘­U£dwÛÓÒc¥9ÅÐzò'š’ž3F:åôØÀPRKy3¤=󇞃±¢ +lAõ<‘SÚj«Õ£š[RL×¢5ÿ‹ñÞ¡NÎä§;Q†ñëcK^ª3ÒVôèëF˜Å—½™‚•‘¡èîã5åÙµ¶ðõaÏä •Åïì¼–AÈs‡ìî¹{%ÒÀaý;îÌw0n„NðdÉ\ØJ+-¦yluÇ*©8Ÿ&$¹b0†q¿}—Üyßý IŠÑ"÷aNEï`·aô'$é´1mZ_«Ðd¯æ?o Ü.²aL‰0˜þFõ4'*µ¹Fø“–?$L±>þjü±>äWó„EXüñI°'#‘hÎXÁÜô¬—Ÿ— Î@¨ÂHØ` 3L!\~û;Êu=Ãm†X¾êÇ¡Fà  _ðÛžfêøí\Hì•3teVÙ—C!8‡k"ó1áÑFs±Ê1 @²ÆÇÜå9F:¸ô—,eQ0xù¶ôÇUŽaJwÊ¡ÜêZ,zC€X8 n_œKPn eDC Ðrá¦Ã0¨áþà×ûŽF(ÜØ&ùÞüò÷ýEò‘‘¹_[ØÂµ5½é³B[k iæ“þ'„[Bü1_è V@ΈþqȽQ–',ÈGìd½N"¥^!¬‘(‚)ö°ÁfxT0üŠÈ‰f€ô¤µ7”©H‚kjöSÓA¤;ubyîÒ¥0FKYÚÒ8µTNp`âK[*^xJ•ÿ© †²—W”k6„š–[›µ¤¬}¯{€jă^‘ 9ÊBÿX2Ë%ŸbÒ"á#[‚ŠÕ!í0ò7±ß;%ùÑ©±2¬‚ &ÛH+àl2‚±¡9ÓRr¤ º 3V ø"LðÇ}ÓÑ$C6ëbãJù)Ôl¡Ôh;Ì!BvÆ:ôÑ Ñª€m©«þÑVæø"iâÈM)+¯Èv2R¦u©Å&vÜAbsu+]¡ Œ kJ¤d.0ã™Y. 4zš?¸R`9¯‡ÇEu’Š 'Ñ(ZDi6?­ö©Pwì "1Ð?qެË$M«¿Jj­1eØúI¹Rž-_Õ4!ت¹´’dƒªeø£uÀ!²Ò²™ÉWÕu²­(pŸÌ“­ÜXÚ•¦þr$ÿ¨é£üæ‹öõä¤dW½D#Ѫñ–Øó\BÊàÑ$n“ôáWö2|Úñ!h9ÏŠ“ÖîH±œ<#ĉEÂà™ à0 _.`*8L‰]2¡|jTæASW?ìºdð,6| )ᢖCBH‰"õ^°ÁiŒöa3d£›^4­'Ò¶¤«ÞoêΔºÇ "ó,2¿Œ9EkÒ?þpìH\Ø„épÂoW5œè€*·•Lѯoþ ÌÉÒ4×PyÒ5¿ ·¶R® ºååÌÀifLaD7ÁOáø6Ñ©—ÈI/e°¾2‘’èŒìøò½˜ó/|)g—vaoœ“_j¨Ð8÷—¹¹ Í”3 XkÅnÄ †1”Qå¼Ò s$” [ÄaÛ°ô<Ô}(bT˜@®Y!1ü‘ަX檢¤wÒÚW„Ù¨'å§vË»!ücBŰ®22áÀêpç5~QCÄì2&ÑÑÈXÈ–X WO…¶rµ ÜíI`ÜJ¼ßÐ4P/aÛ‹…•?ï—Þ"åŽÂèšNº^¬®WèC1èz ÆÏÍ´šþbìR‡/ð=¤éÅ5˜„œ†Bp>ò.m´3j¹†Eð¹¼k`³HzÞ¸O£¯ºè5¾bÑ&Õ¬f½ñ♞\pNÏvîKñ£ÇÎ!ƒ+©4 ‰J@ b[OÒ®ö¦•m@áYl¾œ›ó[û}¶¶ÝmktϵͮÎα²à„îW"Ù/D£§µ¤>lÁ–Ü„À[2ƒ?øxd'ß7^±›,@(+‘à ¡þ›$.à[Šd³*>®"´0uã¥4‹:7ë³>Å«§®Sѱ ¹8 ¡}€°Âj:Bˆ¸[AU…á·)ʇa¸…;›3¼@Ã[¸„+é‹vêþa1îh¢ÉÙ6ÁJ‘p‚¹ ¢ó1ö@¦®ëÁÓà¸R‹Ÿ÷iMã z!!5R3%Ø(k ‰ÕCÁÖ‹7R¹¤ÀíQ‘Fh¬‘ e8p¹ Éëˆ @c{ž;ª1û?çy»eº Û¤Z¬°ÖÅ‹ ­{¯kº'û`º|z8‹X®{Ò6ˆãAÎ൞ù€2(¢–*8>æk‚õ“7¹ÃŸ (§ÂÀ þx}3§râ‚c(ŒÀÀ‹9<“n˜¹›§šQ6,3‰_Ë€ ¤ø²c{EYÑ‘gê´h‘‰z¹ô4Ëú@ÛŒ…\9Úø—ã<ñŒ˜ÛDM\?›+•ÿéšûø„/Àe`¥©âY Pà—Àj;ˆ#›'ì[9lŒ 3ŽÑѼÕx>a&C"!d ˜*+ׂ2j:fÜ®Š#¤D·“6X fpì¢4xÌŸ¶Š˜ºB1É»·Úp „½Û…r¸üÂ1[“'°Â²S†`øöÉdF*ãºÌ™™ Ÿü4]ñ8ʼH<Ô¼ LÈíñ¼ÈD‹L•þòh?K‚ À¿±…臧Yh''ðÃ\èL'¨‚Î Ð M?TËÐ4…y0ÒìLѬ¿Í*PÍ\P×TMØDÍ*˜Íy ×äMß”MÖDÍÔt‚àLÍÞÔMÐlM×<ÍÛœ‡ÜlNÚ´ÍÒŒÎÒ4NÝÄMeøLÙtæÍá|ÎðtÍP°NÑt‚ñDÎà|Mï$ÎåtOÎŒÍ/б“X‰q(ZŽóR±Ó©92œ?ß±¹P†Ñ ù²48X›7H¦t¡iÄOê€ËãÍØ¼ÎÖäMó4…ݼPõ¤Î˃âDÏyÑêÄMS@ÎÝDÑÕDO EÎ ÑUMåþÍ…NñìNåPQ­È‹d51Œ5O˜Æ`† °…@€ ù%uRü'•Ò•R%UÒ•0-ÝÒÙRC°CèR/ SeS2õR0S-MÓ2Ó,uÓ6õR5åÒ8¥Ó-Ó3½Ó<•Ó:ÕÒ9õÓ>ÝÓ-}S>5Ó?5BµÓ1=TF T1µÀ…8£w´¤Y/sÊ¢÷Ê¢<~Ø"6äÀû˜¹+•#H…LG]UCeU=mT/mŠ55S<5S4µÕ1­Õ/ÅU^íU_åUÅ Rӯʠ·Dc´fBÃ!fmVˆhVgÍheÖgÖj…ÖkÖi%„l¥ViþµÖoÅÖpÕVpÝÖnåÖqõVsMWnU†u}×rWqÝÖí„×y•WmU+W›·þŒ3~۷ƒ:`ÃrÂ>ó·~»„v#cu5¶PW|…Ø{Xr¥XBhŠmÍXÝXŽíXýXí¨Å”¹1C©.º\“ˆEW{­X—•Ø—eÙ•­×•=W›e×›mY˜ÝY™µØžÙœ­ÙoePR©TåËùº˜I¨…®ìJ,x„°ìʸ1¤ŒŸåYšõÙ õYŒY¯ýZ° ÛŒ ÖÅd=ÇlŠA°•~¬5Ò!­ÅY¸ÕÙ«Û­Ú¸Z¹­[žÕÛvÍÛ»}[{UÇÔ&ó¸‹õþ30ùê»Ã%žü+ÚUù[»õÛ¼íZ±½\Ì[>ØV ÙòðŽñ¨Ã‘b )[Û%dÆÉÅ[ÕÜÕM]Ö}]×ݽ•ÜÙ¥Üf=º;1ʸ PÝ¢+q6¼áT<Uñ]ÂkXۅݽuWpµÜÌ^éýZ²Vª$8k>Û’ïQF°©ÝÖÝ\¾_Ú¥Ûò­[ñ=_õ…Öô]^—mßÖ%„'™;‡5{ã7ü¥5Ç4,G6,81Ò¿J½Š–…_æýY&„ö…Þém`æ\;AÏ%­Á ´kJsA u«óe_îàøafM`˜M`þ`ôaÙáÍíÛð¥[çÅþÖ’<ñ¸Ê¦Í‰q+‚.„¨åÞ£¥9;|5O°ÖŽÝ&_feà~â®Þ Þ+ŽŒÓ§cDÖ‰"´qßæõbþÛfâ®M{ãõEâåEcsMâ6ß~Ýó¨á+h¯¤åJøß¹„¯$кJPTAÛW{X uc߉ub(^dÌí\ë5-äÍÝ[T ¶Ñ<•ò`2Và7ÎVcCßONãNaNîY6.ãPcÂ…':”à ¸>‹Ã)Ú…Z¸ƒ-a„½¸"pÔ.“ .•#FdOVeÉUdF>fêÍš1œâ2Vÿ9~,>ÝPFUNå2ÆÙ$&á0þncnVãfÕf3¾fb>cfÍZgµæyÕ×*&Cü]G€Å„1 O§àÝZ©ú…ÇnÚdÉçl>dcFfîXGfæQùåŒ4¹]éAŠL×açÕ=åQåÎä‹Fç‹._šíŸŒD• ¸a‹ñ‹±†pÀiËŠÑŽ #ªýe¶€‹#ÆhD.äm èÎém•âG6¦PÛ«+™ü¯ ÀV_þb‰f^>(e¨>ßOþg›]j¶êªÆä¿íO´êÂÝã=~+ÜYZ{؆:ëÜ©˜r 1Ê綨Ôp®èi}ê~¦[œÖi¼–ßîi¼¹nô% ¾ÃÒ þGãàšfj¤goÖZ¬–jÅfl÷g‹†YÖ)Õ«‘³â5ÇÁ(†a€Ãq³+ré6ûh}ýfjÅjÔöÛ»ÎëœæiƒnævX *ŠÉkIa9l^bªžlº–[sÆí¨îf‹ímÓî¦Vâ«ßØÆ{‹ÃÌ. pÐãv6ÃqZX„Ó¿mšì¹ýíÜfÙÕfm.h¾† %mÒµ1§C¬èR*‹8d÷¦é÷WÉîs~ìú>îšžïkæOüa/´Ë|¨xC®b²Ü+þ|aøÚïïcvíñ~\xzǨ—f\¾Á"®lƒ ûnùÞæÅ~Yâ¦Ø%Öîsåî7ql^×ìæþÆÊJ8ë¿ÛãvrlÜßäÆ\ÐV#d~ÖÙ·iymp_dñ~íãCªô\dÆÁ&& rva¹Æïøîp*ßè5>mú–؈®èV¡_ñ`†-*s3ü‹t Цî3Þ©YòÉH -·òl%ò"b;Ès;x€=ïs>×ó¦Ðó<çsBtC?ô>÷ó='ô`ôBt;€ˆDÏsˆøs=‡Á€C8$ˆLÈM¿LÿôK ˆL×t °AHuTT„VßÎVWuVWõTŸuW¯uehõWÏ…XÇõ^[õ\§u`ö[v^OueöZOöcgvdïu;€vX'vjþ7va×õf—v[_vlßvewõn÷ukÏuKt^‡tI‡t=O€r(‡|x÷x‡wxK~‡wGo¨wzϱœw4œtv¯tuçõ?÷oöp/vmWøp¿ö†÷¦puT¯xŠox=¿u]·øŠÏócïxZyŽ÷x§xbÏø'ùgw–t–y˜y™§ôOwAubÈbõ\àÿy ŒœßyR¿„¡çyXøjxg_ö¦w¦ÿõí|¥z‡wz©·ú©¯ú¬§ú¨çz°gz¯Çú°'û¯?{³O{¨W{d?wt¯ù˜¯`˜x§{¤wk˜xkðwÛywþàw†)Zˆùu¿y›÷ø¥wú±_ûfoü«wüÈ„@_xb_ø_¿üpÏücÇ|ËïüÍÿ|Îý™Ïs—/}ÔO}ÃO|Jçu8ôô|ú×ßôžÿùKˆ} O¿ý¢xcgûqŸüÅ—üÚüõâ/{É~A8~´O~­ÿ}çÏzéGþÉg~à‡~áwöKgý·yw·ûÀϺo”®{“¾{ñ¿Á¿‚€ùÃßþÇ~å·~â—­·z²}ý·üÑßÏç€$p  ;*i¤“;y˜€I&ÜSn'i¥\áÖWä“Ï—o9ãL˜_Êõ gv)&˜bž@ZŠþ1厅ùä•C%(P9 ý©P ±¨¡ *è¡ JР¥‰Vš¤“ÚaÞ~]‘M.Íh[¬Í4R‹!¹6 ;Ê CgXÄê@®žº§¬Á*H­·2+­¨ªºë¬­¢약ûë«Ä¾*ì®—JtÑ0`–3f´oÖ€ˆ\WHâ–$5°m¶n¾uþ…‰(*:Ôj®¶¢ºî­Ê+PŸGiáÙ@õ ”™ øV†™¿ñ«oÀ÷Ú{Öh‘RšpFsžË‘m¤ÎX#‹&I¬RL2Yl¬®ñrœl³ r­Rn<¥¯'w\å({̲îÂÛ²º†5\3¹¥7W˜;—#À1êÝwÌëÁß0 1ìÐQ#Ãü±Ë![9P‚ú´¾L°Õ~þ«u×U´ b“=¶ÙdOt¶Úe³½¶ÛmÃ}6GrÉK9lkJêL ¢Ä÷Lš¢4±È2ˆÌë°«Æ\²„ÓŠ¬â¶:ù°ƒo¦…u2c¾¸Õx¦,yã"e.³%ß}ðÓB˜§»þåÞêñ­—_E"ZªåC§ŠøáOßê¸cTg öcçûuÖŸü¾ñ°Ë.Í;½ô»LÔ<ôÓcŸ½öÛg_ŽÝÎ[ÏÑ.w[_S¨!µX›«ÿ-½h­MÏ%ý?¦j¿Ó)úý'ÎVÿ³“þê÷4’ °p ã al†‘R¸ÉKКÄ$È&·pcÜàÑ0’4ˆ,‰J X«‰<¥^[ëÀ‚‡/¹°xÊka Y6èY/‡ÏkÞD¢§Cü0ˆ;"‰(Ä"þp¯y3•‹ÖÐäb.¹ lZCEýbóŸ Ø*Æm±]üâà&çÅÌy.Œ ³Ÿîþθ/Þ5窈RŠ]HKZK˜Äµ %­gX#\oSGÔÀŠÐ5¦J#ó÷97ްU}B¿l(¼É´0xš”a%ÒÉLr²j<¸Û%vQÊrŒÒ”ã£^šWÊS¦–¤_,i9KTÞ²–¸dâõvQð=OS¦LIúR#Y,F-qŸHŽ%BGÎ,H\„ä4‹$FHöo€fŒæÊ¸ù*mJœÖ£G‡‘¶të-él8ŠæÎÕ!<ÛË_,òÁŽñ›ù¤ŠاM²ð“3(ðdˆÉ‰ Å!/{Ì…>”¡¨D+z·&: ˜å(É+Uã¾Ö817Ë[køþ¦8˹k‘SAé3MgJÓp¼ã7§c5R‰¥L™Nµ*š¾l3èhЗ» à@[Ï]f€¢ñ¥jAdͺÈÓ×l¦Åú§% šIþK ø+B»jPáé²–§d¥+m©Ê]Êò­iÍ%]UÙD_>|¨\b#*)cS ,2GÕÌj6I¦ãÜ©>©)N­6v‹ågÔÈÈXÊâo²!ÄæXGU£MÒBD .®æ#”°`´¼ '›Q¨‘4™7_VÀÒË«%+A´@µöö¬ËË­Ayi\ˆ:ÔzU.C™ LçW¹ÏÛeIîªDÐÒ”‚ßÐGþ›O±$p—;ÕO[Z¹lÚ”wYÑz]Æ^^ö½lœ_z}zY¨Ù÷^+e¥c;Â\„K^ÊV9Tð‡> ’µk¯‹›Y$‘ý ŒdÛ¨. 72)óêÚÀ*iCä4ÄÂë%KœÊ×µ‡puë\§+WòÁX•(ž.3ZÊ`Ê€|Ñ;æ_™9RØTŒ5cÚ>g«²ÄfÕ¶œ}溘Í~·¶›•2bŒY$géÿÈ0â" ƒ><ËG:uV0khR ³–¦Ù*IÉTfÒÔ@iÖ;ÿö¬À%^A 6~)ôÆÎåa–k]ç Ú¸7.%ô ÑRòµÑKl4^s£>þ¿ÍÆÒ}cßKn“+ùö–¿™u~!{eÜ«¼¼[äKQaÍ1†ÔõIˆ8UÏŒ¨Z¶HΊöŸÙ§>ö9†`‡‹ÐnŽçÁlßeÕÌýÎ_†Œo9¬[_»Äq£í*è»Uo–v¥ô¸¹mîGGÔÛÑËÔ+i)>GÖ5@ænx=J±ÖÀ(O×ü‹ g8÷{ÉŽeò3e«'}ïË_4ç„#R.¢ILqP]Ä¥% Ñv Sðc—ּ冃s‘¹œInä“£ÐxñòðL¼ÇÐ’{Æö¶­n&&÷æÝvt¢unn›·»¢xíyuG*Üx*‹±ñ”ù\”·Rþ“W½•/~3 ºWWýq8Uo’xëeÝ·$Sgõz±Š²rêú"FýR·&Èi…‹Ày„V™B–k¨»Vä³QÝw[MR“¼Õöʳ]0~Ä¢L÷ÎW=uK7Ñ m÷¡mnr£˜¯ŒÞh.ž'1½Ä£@¾t½C‚›fj}ß´UÒ¿SZä'<œþ¾Ÿ’œåÕŸúäŒÞÑΖ½äCá˜K™íãÎr„c E+‡ÇA¾÷ Ï>ú± Wý|<à 7û./ëeäznG;t¢ÝVwÏ)Oéò—»ÛÕMô_¹·ï¾_Ó¶\§3í)¿÷v¼ì%ûßv—*–Õ­Z’ÉÚI‘Lþf×]ÊôžóÕ‘ñ;™ÎÖG|ÄÑ”‚~|œŠô*WõÙ Ì…ö™Uµµœ “ù=TµÏ­àCIÞÏÉ`¹É·eT[µŸó(úD Ä(Ãèœ\7™\뽞ê•\ÆYºÂÉ^eÕÞ›5[“y²=ijx 7|jU´\ÜÍÀˆVœ˜lÍ™ô­aÔà–e†@ÑÜ Š`p‘àö ‚ ¶U»åœuY¥µÕ¹â Ú`¦`íÕ!ªR¦qJü%ÝúÈßm„Wm´W—ÆT×ùß5&ö—©±Ëª°šJyGöÔ¬ U!R€µ i5˜ÜÉÝþt˘¤%„˸|ÈEHØPá' à…ÉKLžõiŸ')^â™àR[ÏAO¸©R¢QúÝ 3ÞÜ â•‹5Ou’+1émŠéÍJ §¬OK%œ•A!ÁM_¾Y¶¡”¡ÂáÞž=_âÌ]¼A±\t‹ñŸÏÀEó•Ë=±<ºãE! Îa … µc&¥ù±ÒC]#FZžuI£ ªÒBOI ’Bu—$ŠÔ}TmtŠÓ¹ MÕË¿EŽÿ`Mþ_–×é¤1VLºÙ}¥]yœËCU˜ ƒ0T™ÎQ©SRÊ…ì`Ä.&þñäUšZ´ñþY –`Er%2.#EBä@Äà:^8Z bãäYÐu$å)bópžuÖ` V2U ŒœO2Ia/2d;:á=.$`®#aF‰Bæž 1áfåcŠ@D5ˆÉ#C±ÀÜ] aÃtÜÂd¡AìÞ`Æ£’¤÷… ©¶XzeØÀÒÍ©’CÝØ bmš%äÕ`7:GGyÊĤ¤kÀ#–TL|"³m)./ÂVZå/B§¦Ô«¡Tr8Î)âvøÞCìâÃáÑPœ,zË€5˜xމ94˜4Q2îdt&`«ž0>äDš&(±æöÉájJ[>c+yd Únþ~äEÚ Iv^ þ§àe£é±ƤOÞ^î fî)!afèh:ᆚœí-gˆ \Cè£c’ ñƒ^d:¥™%U9d „Ýßi(b&°üYí§½LÛWÝ¡}F¤¿d—ÍQšC•äùUÞøÁàå hãÁe^ÉXFíÂѱ§øÍ’ãw=gsŽšÙ]ími|2§˜âd€ §{)fM•>î"¯íÂS&ói`hTÕ{†é&z ~ÍÌãeôh¦àXÆÜOèÍõ楛m*é[väõâ÷ÙØ.¸ÄJ°¤8ÒÈKèeJØÈ8ÞDhvèØ¨¨Þ¨h¢j‡Ú¨‡r©þª¦ãâÊ«ÎhF Ã3´ÓÜ%vIeb\9ŒA$<˜!y¦ê©ºªÒgkjÛà)£p1«²jÖdmvÈf ÂàZæfmº%ä ½†ŽåFÞü¦Ñ©t×jðŸ{ÙÚªÕd»Ô|òéžþä»ÞTâ`g|årHÞ• (Ua¦š',ZÐ pC°jURëé¼*  lØAŒe´*+öy˜Wê¶±å][¡)52ª[Ö 5b”†$vQšû´pJ̧¾„Þ1-&À½ä_r¨=Öìªò,&¤ˆòÏb>I{šh5ðÂÎ$Ty™@Íêü@=yæèülâ¬ÄÒþgÎО•~êËa­×D4®Hª’Rë÷1i¢b#,}+¤aWIBZ`é $ž§Åˆ§hÊ_9Ñ|e–(ªi™'™ê©à:g¾Â Òá6R'>ÀPVJQ:„@@U‹VîRöŒ8\†Ì(½nV c~Žàè2Cjá]lê*Âê²nëºîD¸nìÊîìÒní²n.ÄîJän.‚ø®ï*ƒ2ôîï*@ðïï/ñ¯ð*ïJ¯ïúÏó/ï6¯ Hoò/ö"/óf/÷nïõz/ð†ïò‚où6ïøj¯øšo÷Joôž¯ôEûŽoü*¯û²¯òÒoërDìî/í.‚þ”B ðpð×nÿê/î¶®ÐïýBð÷¾ïG°ïN„ôú.+€s°òf°ƒð{p0ÛnëÂî «ð ¯pQð¯2(oo W0ù*oP/ñ–Áøâ°ôöð çðïþ°±úʰï±ñú*±±$±×púBñSñ31ó0?1ûîí2ð³ð“ñ óo³._±£oû°OkpÏq˱ãqÛq °p —ñ·0 »® Ó°7±!#² O±±"²#'²3ò"g1$[²$W2&7²³ñõñê²ò(Ÿ°ƒñgòþ$?²&go.ıo0,‹°ò’0-ßq ã²-÷qr/Ën(ß® ² <11û0 +¯1ßðs3/³3ë03?ó4G34 ±4W35_³5kq!#q#3ñ*s6‹s1có6¯"èî ³/»óíš1;Kï8£39×ó=kq3¿2ñNƒ,ûó?t@+À.¿³;¯³þ¶s$«²B§rCoòB_2D³ò*KtE;4%o²õ>´'ŸqA{´ìt0{sD_4E›oÈñ ¯´·´ò¾´J³ôL»4MôMôG20ƒr;Ç0»Àøõ<³F‹³P uQÏsR/uS'³9;õQGþõïu2#õTûnUKµUϳQSõUsuXou÷Ƴþê´;›rO¯îX5V+€V·µXǵì³Ï€@ãu^tNŸõ‡ôêþµ:£¯{5CW¯'—4ðö%v&7öa7ïcgïb!bCöd_/e£/ek¶ecöù–õ)÷õ(ó´:‡1òrvf{6j¯6ð1JÏ2ñÖ±^ÿs-ë±ôòõh—²O+Bi5X³uV÷\·p»5\·\'wp¿õp/wq7÷q;wt+÷[/6rS7sc÷v /;‡¶nqiós“wvC7wcuÏöM×t{³7m»wç6xÓ.¶}›vbojþoôe³vFëwe÷7F¸Iø€xvëv`Ó÷n7I#¸a×ðß2|ÃrLÿ®†û.‡Û±‡Ï÷ƒ—2~ïou£·‰O÷‰kwг¸t»8Š¿øŠwuŒŸw‹±Z2~‹xóvƒÛ¸ŒÃø ×µïÞ5†ù‘߸ ûñŽÛ®x ²‚KøgCùDSx‚[y•cy”_¹–g9•kù}7“Ónƒã·—›¹EŸ/l+ïHw¸MËt|¹‡Óñ@¯ð’‹ù/óv(×8—·Šïyy ÿ¹ ÷ùú¡:Ÿ›v˜ßù/‡¹ó:¢›wŸóîÛ5’¿÷›çµœ'ù Ûy£‹´w³n—wöþ„sù©Ÿy€£ù”Kt©Kù–«±«S4£ƒz“çy8Ãúª¸šãñzcº› ôK‡8¨'B"Än±»®Œ‚(Ho0»ò:{³?;ñF;´OûïV;µ_»ïf;¶o»t;·{¸ƒû¸›»´£»µ§»¶¯»··»¸¿{¹Ç;¹Óû·‚±».²ç{­×®¾#ôZKºŸ'ºXï3§Ãy›<†<ûû;ë>üꊂ½S¼ô.»ÅW¼ò^¼Æg<ñn¼Çwüï~¼È‡¼ï޼ɗ¼²§üÉ«<Æ»<Ç¿<ÈÇ<ÉÏ<ÊKïÄ;¾·n"¿ÏnÄ÷¶0¯2O±¬+öñšG¯ÿºxøÂëþ±ÓÓ¹’ó²Ï}ÕŸ;´'¼_=»«{×S{Ö{½»c½Ö7;Øý¼›=¶§=·¯½¼}س=Ú—ýÜÃ=¸·}´ç»ÎC¼ÞûüÞ‡öÀú¤ >r«÷¥/ý?C=sxÃ39ß+‚Õß|ÊO|äS¾òN¾åûåË<æWþæ¯æÿ.èÛ<Ìs>é{>Í—þéû®è·|ꣾê·þçKþ³ï¼ã}ß=O£úfg²ÑÓuh0›3ý…Ë6ñ»ñã±' ‚òó+ÿó7ÿD<ÿòSÿô[õ/ócÿõsÿöcðn?ø!<ù?ÁŒ??!pÀ!‚ú—ÿœú¯?œýþ—¿ýã?ûßÿû×ÿBq8Eˆ@‚%8ðÉ„ t¸°!Å'>4ØãEˆ E~,™ñáF’ŠÜ(ñ¤KŽ15Îd‰’ JqB„yS&LBžˆ*S6ˆ(ÒAF‘uúÔ“Ò¨ƒ¨RZkV«RuÕS°Hså[4‹2Ò‚d«Vá[·m×Ê€;P®CBÊòäA˜óáß”jÜiØ¥ZÀ„ n\Xq`Ç=¨|ÙræË}5wÆüÙshУ5_.zje– "IøÔkµ® #Œ]›ÐíÚºa˶í;7pÚ»óž]9îá½qG¸\­sBÐ+Oþ^›zpëÍ…_o-©j©§›ŽÚ,Tô_Ù›/Ÿ4,ê§ÊÌB-‹û~íü„÷«íð?B,«/Ü <Á\ÁE ­/Ò$|p 5[ª ¢° æfsa;ìº ñ;3ñ¹EDq:[qÅ_d1»]ÀüÚËÚô­íšoÅ9붦”cþ!Wfšâ§í&â»éÆXï¼ñ®;FM7ö¬d«;uÊí­ÍºTÀ¹]~Ük–%çÏq„ÎNóZmØœóÎ=ïËs\9ã WF/ýtÓIWõÕSôØeŸý \ Ýö ±@ ÎAj˜a~~˜.ùâ'~xã“o~ùäg^ùç«§~zé£'>{î·‡ÞúîÁ§ž¨àµÿûaÊÇ>}ñ¯?Ÿ}ôå'ßó½Ÿþᇩ†€Aä@«“ÀíX状„]G:>ÐsepAèØâ9h(ÃÃ9ª< Ï~¡]0Bá‰0„%áðP¨?¾äzÖKžýdHCâþŇ5Ôayh½a@0t óíˆXD#‘ˆ¶ÃÝí¢1†OP1è‚1†a†Zƒ £à@>2‘ tñ§ØÅ»˜‰0z±‹_ ãw‘Æ3’Q§`£OF4®1`#õhÇ8ÂQc,£嘉6zñƒ<ã!õ8GDÖ‘„4¤" iÇ0 ²Œ—Ì#!1ÈM^2’‰ÌdIH@r’ùàÀ(ÒM Ï]ˆÁÈЇaΧ Ý5t‰D_Ê@fçl:ä!tÊôñ{ãFÁ^Ñbì‚>ƒ4dY´‰Í\t3›ƒôf7 ”‡.¶“Lç!שNC¶þsðt§<é9O{Ö3Ãäœ;÷ËØe⟾èZPÒeB‰=hB?ñ>v±¦xÅ>b  f c XxÃ(FQR”q¼ì¦HµyŠkŒ´Ž%=©8I Ò–žó¥†ŒiHSêÒšfr¥ç4ãÄiƜⴧ§à)H}ŠR£²ô¦2M*MªS¡õ§2}5ô!ZP‘hÀ‚V`Í¢–± g8ÅíJº±´¬²3hYP}s‚žsA(Xmf"ÊèÁ `€…˜Á(µx ê`¼~³”ead¹©Óï2ÈD_îZYË^³™Õìf5ûVð“sg¸‚+:ÚÒ’Vþ´WXjQwZ×–‰JlkínÐhhâ«”ä)zÕb˜AÇØÇ(LÁÅIÆ4/m#r•›Ü›.7©Îíis™]’2R¤¥¬®c¥«ÝçJW›Û ¯uÉ{×ìò×È^ÑJMXÆöÐ-ë!Þ2ÒBpAóKºÑîW´ª¨+XKàթ¿öì‚%HÁ\àB›dYêA†;è!c(C4±ÕW!.#7‹Ø s²æÔl)9Ûbo–Åwõ,h7GúwÿmŽO§Ú|®¡dýgBI׃Z”‡4é]ÏXFbô18Æ_‹aŒ`Ä`Ô0wÑäIæöœþ^VrTÁlÈ%«”ÉQí²š½ Ô’ÖTÉÑ=³n;ç0³ÏÝ´³™Wšd0ž”O„¼Ò+|@\XÁÈÜÒ1s—`í] i‹•u:Ît9í_Î1àÓ¡Þ¨õy ºzNÈ„ðˆ%áVŸøÉøô6l DÃ`}`Ë]E¼ÍVìtl)…ýåb{ØÉ6¶²‘ýeÈ›s؈ö´7GcøÛþÌ%Ze»hx¢¼H5oRM€‡Q¼!Æ(Æ4ƒ¨¡¸e¤.™]pRaÛ÷Ñ÷·NÓÛT7+RÍÈÝ3xÑ»oy¼‹õž¤$*ÅW#£zê1Þq_¼¤ƒþ8hì\pÚ5­¥Ý‚Emiw®Á¨–Áæ ÌXeô4¯¼~õˆ¿YáWè 2(ÃŒáaL„s».#e_\t£=Æ•12MÚ³uã@~:¯M» oüÚ —ºY1ÿªwòð  üuÆp7 ¨Ñ‡Q¦™Ép;šßìõ•2òëtszHGÏýËy?3;ÿþUÂÃùÉQÖ@-¬öZ`™^íbáÞæ6¶Ù̧¸¥ì@^P"[ýé (É!(í2\£s N5çNÐEŸØÙ™:«ež RZF©¢8½‚\üº‹D‡ì²_¼Øžr×ÙÄ~ì]¼ôÐxÒ©»þµ5-ýK—޵» öÍúñ^rþ ¸¸ØN~ÀËúÀ¹º€4èá˜tánq¢ ¼Ñr&3æ»;þRòÿºþ­üì¯àÌ‹Ô ØÏbþL¡â’+ÿÈïòöï§–ë¤6o´ÆÊÀPÇv6ð &­Àz,úVë H‚ŠésVŽsН^.Â\ö" ÅbpÂZánÎ(~€ç‚Aî /Š-³š »É²’Žùo…0ŸÞÊÚ: t pÓ°-Œ>΢¡œªï*ðäN’ˆªòì ½8Š8¡Ì`Р 4€í>ár+μ.¥Ïä°þo ¿püè® ï0ÅþIáøn¯¸ ÎÐ2jAØÎH¡ò–*—ìïî0“ê0ÂJ´(Ó0Ñ £0Á®Ou6çäš©M#õPéXOÄk')œØIè¾ìi®ölÏ è…~«8AÑ$ù\̃±al³R¯äHÍÚB.Û–±ˆª0v´¯ ?AüÀ ï(PÁNßâμž€½Þ Æ f*ñ²¦òí" ½p΄ò÷0DRb Ì Ê‚!ñà "‰à®ré±²ÒÎnIëz’'gç&e'/AÏ!=çG"9Gç6’0í÷ #cލS²„ï®nñä!ÝÖíŽA¡Œ«ÙˆÏøbo3‡ðø„&ûÉ]AûFKûJó4£o5W‰œ'qéûŠ©ì»æ° ðßün©àq¼"êæ¾‘(¬ì èK¼ns (‹Ê»¸ËÎnqbàþªªè°`ð ÞØrÛr;…r‰’ßÞ7+ô+µH§<¬´ ¯±ÇZ³túˆssd@VmÄ`0?yM?]¯?‹Å¤Âé[ìɨÁì4¡ñŒõ¡>%W²²”¯GÑB?'C‹w À6ÔC¨.ÍêûÎ@‘¬’ Ý ï´²ÏØÒ;—sàÒ‹>Á­*­È2ŸRàX¹F“*Ì$ Êܾ´óGí±ÎôO›ô®"mOÁÒ8ôA-³õÙ0 ÙLÀÂ`2•‘XŸñ5O¡ê¸Qµï º.'²®¹óòœÔ‹ºòE Iò¤xà_AIJŠ:Œš"Â'¯_GÉæH¾<Œ êkb“Ô(­R_7ucõp7SFþó0Œ,Ñ.­P/á56ôŠU>Qî/S"W #Í´MÉiæ\/”"]oæäÔ3ïj%%T›Ô58¡‰"Ž–¤ èŠ-ÐÁ쨌Aå‚d²Ú2tsD°=?Ïó :IGlW¶'Cn!{2üÄÍ6¿37}´6Á¨‹VÍo-çîÉFRŠÐ°ja-Iáÿêè@» <ÁÐjVKÕ(}3WuÓívÏâv;k)÷âª!Á45À ˆ=ÁÖÀb–˜âªsì³sXP@Ñ g1Ò"iq1©UŠÍ1%t3ƒð²¶¬ ªq¹`\¯iøx ¨!2'“Ýx±šdµŒJîšðþú°´3a Ï@X /‰¨.µÏv°ß(qEŸt(OÕ`ÒWRdIv|»H]ïÀÝ”ÖÆàÜýöQ‹œöV'— Vðju¦Âð®ÊWÎ1Pt z9T7”K·tÔüòÔxõ:çb®Ä¸ è)1©õåJiu34‰‘øl·²Ö+8_‰Þ÷>`  iå– +³BÇKc2k‡èziçPm2^…õQÅÓ÷~QÕqûÏrÙ¶qýuVÇs-ÍÜ Ñ šàÌ€(Èòp5`â 9uóò†êVõwßxsØÎËmƒ²dï!‡5mßUvD×À4‚$’sÊ€#3r@ëþ¸ZÛhuñ˜‰Îh®3ÿw—r˜á¬¬àš¸4@¨Á”wG3´j²esX‡—‘^…l“Iç'Ï×V½ó_ëö|ÉD]ôŒ¡TœÈ.2ŸiÝЀ_!’±Q}M!:¿Ñ3 Ë26.Û²+G¶ÌÖl #×å’I»(¬UDg§­v˜e/™tbVÚHwŽ­¹>íÊÙöƒMÌuÙÉ‚AJ1añ›f÷•éÊÈ„½…Ç€ï€ð®B28?€Ht°R²”JCxsÜ ËlÚk5E‹eó’™ÅJÈ¢ˆÍ÷8PSÑ+™Å—q»Ó–3é z@ ñ•²ªAþµŒ8õüœxЬ(ö¡«dUSå–þšÓ±&uˆï6¹¼7ˆÉ˜ˆO›š =Áö§ zUs ÇV´BG&eòX…‰>m€-ð“g“ 3èêØ#£:ÅHxŘ­Œ.!)[5¥oíwµÚ²Ôµ™|kOõ ´„)§·z¯ï­ÁöC(DZv¤qà¦2˜9¤Þ’*ùPÉBv+ÑwÉž(2ñ‘€kšžRqkÚò„¸‹¤`•†´HgÉ—ùº`Í×”Ûqüz¯Ó—"­Ó¨tJXÇTÁúŽÚŸû’Ô’µéÄtÂþ3ƒÕ´›ÉÉMíXƒ_Í—Ï%“¯²lN¾ñ–ÖèÁ~9ëOQþ›òV­õ†q˜²^kÇQ?!R ’R§‹Wù y:»Åí»¿’ ˆÔß@8€Ä.˜?¶¦IšÈ.wÑZ–¹3ë˜{ÿ,Õ¼*z¢ƒø€uvz¡’µèô‚ˆYiñ‚5ÒÁuêªíø›³ú²’{WÄo· %™hÉš·9ËsjXYµöÚ,9Q39‡Õ®œ“Iç Р˜÷»˜ûõ³ó•sŠú€¢óªѰÌA[|[oá’‹ê™H†ãÙŒ¿PnÏo¹pÚ<›¯oü6/e]<šwš ʯ™‚$ò\®§pviÛŽ$œ±v6²´Éœ‘þ°ŒÌÚ™”6âhù¸QÙˆÐ\p®¶ŸK‘5wì4Mtš ;€®YvÅ €¸q¿w¦+PïV9‰só¤@H]I½ÁÝPRž#šˆ¿øqmWýíÔßûj4ÝÔ r´–IÝVs¿ €Ç¸Ž0ð êͯ`¬„ús…ý=Ï“†IQ©G|sšz‚7u§z1¡=¶ïÊ#Ñܱv{¹M[ýjÃOr\ËU„ÿØÂý²(ykŸ7KÑtâZÇ~‰À]à“ »¢ <Áxùê쌡 Œè⮈×Neº¸1SF†3MŒ¸ëcG†&#ŽÄ¨‘âʆ9^42%Ì–2m¢lÉ2S=2wô`Aã©Ø˜ƒwÈ‘ñÊÊ(CêQzÜqEI«XC™‘”Ú”Vb©£·UêØÙIO6Wksµöš\iç®™·ž!æ¼³Öº¦½Äq€†~LÉäÂ5¦¬ Ô?àI-oÜAÍB†ž‡Ÿy÷ÅÇ_N÷µ‡Rsý…&¡zË ª_Å—’gqœ‹r~%××#50ÄÐ…1ÃX¡‰\Œþò *%zÊ0¾±yï˜b’tV«¡ë%¯t­¨ŒoÀдAML+4« 8Ml'22ô€ó_)‰lÔc_”m¹år«­¸ßN®ÚÞnknºt­—Zº­••Þg¤5YmñÍ7obž«á=?!Žh׸@Œ Ôè$˜ñ}ö`èæ’œóÉ;yZÚ¤(Þ”F§9léé‚‘:ã{Þ¨ÆQ ú¡â5$Ec1Ä™Qµ „‡ ´gÂ3X´ò½Uòl©u!àΛÅ\gèj½ ,Ê•°p k,C&pýF-c¤I³¯˜²Ð_c7tYg‰1ÄHÓ†”í•iÇ-wÛPJù6·þ±\ìÝt7 ms+²G8òÊ ­¢ñ)(K1•Q‚qªT‰®t Y}L¦±ôìâ_ü:§D³ÙAh„¡„JGÃ:c¦Ëa GF«Û½äÔE j‘§`a£èŽw çCfqâ§xÀ*êF€Eƒ‹ÒXóp.'h–ÀŽñp £YòÐ5L¨ï]„F¢ùÞ_ƒ£öýå~ãú̸ޖ?*u+n}ŒIÈB23†$°ÁÈF:ò‘Ø8$#9É3xâ’—ì 4yIt¡Yž d<JO £rØÃ ‹bˆ€f`†ÁD`ZÒr–¶Œþe(sùÊ]ÖÒ Å0Ã,ÙËÊÙ’Ÿd.™!_Ú2ƒÌ-™)LO𲚼dF(k™XjÓÌ´eÁ¬ùË`sšÍ4æ/µI€l†RšåTæ2ùËsÆ2¹¬å6y¹ObÚ³˜×´§9ɉÎwŠ@šÅ8±‡n C˜h–Á&Qe„²“˜Ì$&GéÉŒvÁ`¥h"GJRÉr(CD:ˆf¥2 8A1ÊPbÂR2"x&3”QÓƒR“§µÌ¥d¸IËb•—ÍÊŒº™Ë`^÷$¦T©IK©Võ©ëĪVc Kq®ÓŸhXÅŠÈPNt‘‹|dZ¹ÖIºõ¢ƒðDþ\/9W(#®sm© Ì:Qž^ô¢& «'+VÂ^Ô¯bh«Ø¿^Ò°qElX%ׯ&V²}]¬Á*ËSf–±˜ eh-;YÍ–Ö³¢5íg/« ±Æ5°¥•ëd[+ØÑÚVµr½í_ &$Á’r¯®5«\J\Ù¢t¸Æõ-IGºÛÁ‚¶ ‰õÄö¢›‹<ø¶º¨%vk#êæ‚º+åîw3ÓÜèF·¼Œ izÍ«Üõº—½ìuoXÉ»[l¬­je$~¹ßýâ•®r­«E3JÊÅ¥í!;ػµÁÁ ì‚\Ù–.ö¿¤Å«n]ë×Êæ·õp†?,ÛÍR–Ä›Eq‰þCká·ØÃ-¾ì…áÊâÓØ´Æ1‰E¼áÙF×®ÁðœÑ¼b2¾NrsÓkXƒ½èÁÚ])Œó ÆRÊÕŲu{åGÙ`e=®—× _(›yÌeNó{‹á5ò¢ˆL¬~íË_:Û¿ý½³}‰2dº‚ò¸(Eì„ÇÜd ¶Ð’is¢MÛÂ:ØÑŠn4`%m0DSÚÐŽ&ô¥--âG:Å þ4£5] OºÓ‹†ô¨WíáTŸúÁˆV²l…ŒI#{x¬Ë}s|+}é8Ï÷»!õ5^©]bs9b%±»l7»f¾u›ÙÛéj—øÚm†±›¯Ü2ÏwËa¥ó}ëþ¬g=§Õ¿IŽ,ˆmüêL¯ÚÝðžt©7MïyÛûÝòÆ7¯ïï}ëÓùî7Àý-pKó;à'x»ekêP'w®Âó¶e­^öúEÙÝ®®»Ö,s¹Ê·2È;^0—\ÍÝ6ÊUÎò•¿ÙÍÏ·¹í\n<³uÎöuqjnã7üß?/x½>t¡\áH¸Òƒžð¥½éLOzÔ~tO¯wÚpE3cIºíBûz¢1ûw]ì±ÿ¼Å.¹²­ÛòŠ·Ýåo{™Ë*VqÛýî6Ÿù¹±Ý×r;´T'zÕ§Nø§KÝð7ºà¯øÆCñ…¼¤ÿ;×ày׎%°š/®þv“wz»¿f¬ÇI.zp‹=ío‡»êåžz7;Ûô¡¼¹ÞqžçšŸùï Ž<ã/ùÞïþð¾w<ðŸxÞ_÷Âgóš; _Cºy´t¿hw™ ìWÎÈ&;³³vî’—ù¬_½øÃÏò¯Ç¾æ²o+íçŒ_”Ûòð¾ñ“üùÛøôÿñõŸÿªån7x#7Q£G€jJ¨l¨€"Wz¥}ÿG~8ïvçgwy·wêIiµyüwŇ X"X‚!x‚$ˆ‚h‚)HbÅzëb™‘l¯×i3è}4Òev`×yÒ…lè‚8„¨ƒ4Gs{Çx„iÖcþ«[2ö\R…T…Vø„X¸sU˜…¤Å…N¨…W†^ƒS†](†hx†jø…B؆f¨qp¶€Î&‡ 8‡¥—]wz?è†|H„r„7—ìw„“„V”³^l˜ˆd¸…i¨ˆe8†Øˆ‹h†ŽÈˆk8‰h‰•H‰˜(Z}è‚Ð{sXvº¶v¥øz¤H}©øƒ臟Èzå烄èVJhs{_›˜‰œ‰—È‹¹(‰¾Ø‰½¨‰Âø‹Ã¸‹ÄŒ¼èŠr}r˜‡ rÒz‰U‡p„ÌøŠÿçr€¸„¶¸„8LjXŒä¨ŒÉxŽÈ˜Žº¸ŽÀˆŽìxŒïhŒòbÙøvÎxþŠÍ‡øx}&‡vdwl"†ÚX¯h„ûE‹I˜gT°_gŽêØŽ åèŽy‘™‘óèïH-Šàå€Õ(ŠÐewè}i~¹’DØŽ ‰~9ç~‘i‘Y“É‘y“6©“=I,Ù„2øŒü¸‡ÚGV<¸v6ˆlªè}¢è‘C釀ø’ëg•1ÙH4É“9É•>¹“8ù•Aé•@Ù•a)”Cƒ›&ŠuX’n¹€ƒð–')VÕ¥ƒSy—{žP{1‰•xÇH§H–‚y–ƒù“… –†I˜Š™˜)•,'Œ:hlßFŠG™ßfƒãÅvx¹™í¥fUy•wþ‡~ãÖŽÉ™¦Yš¨yšª™šŽÙv*Ùv*gr¬¹š)‡rÏVw09ˆ|¹~39›¾I›¿œÀ9œÂYœj¶vÆ™œs§—»™•‚˜„ÄÊ9ÒYÔyÍ÷ƒ¯iwé’¢Ž8ˆtqØYžÜižè¹™çəȹžÅ©ƒÎ9{m••­èžö™žøyŸú‰ý˜ŸÂy›„„à¹áø’TàŸû™ º  zšÈÉ i¹r9‹G˜wåfg ¡º¡Ú¡(›*~Ü(Š 9n…X‹9Gž!ê¡,º¢. ¡íÙ¢o‡E6@@_’T€£:š£gÀ£À £= ¤áNá~ážá®á Îá ¾á Þá!þá"^â$~â^á*Žá#žâ,nâ.îá1®ßèe^çEq8žã:¾ã‡yp×Ûƒäþ¼Ù—BNã/zä2ŠäJžŸøÝä·^®›ÿ=ä ù—â™äX¾äZžåÊã^þå8Þßå¥zb¥º)ž»Ù›[¾æ\ÎænžšNç\gäžV^{à˜m¾çoÞç|œ`è^¾z&>qcæVž›²ççŒþçÎæá'çrnœJäY¹~Žžé®éœÞ‡‚þéJö¡äwæß¹©ç›žê¾êª.éøM„È^óyæêg¡ƒØê¬žë¸îç ÞëB8ê*{âYgy·ëº~ìÆ®å®þä.xâ,g¢§^ëh~sÈ^íÉníÞë_ài¢zWŸØ~íä>îü¹ìsîŠ;magic-8.0.210/doc/html/graphics/corner2.gif0000644000175000001440000000507010751423606017032 0ustar timusersGIF87a—}ñg›ëÈÈÈÿÿÿ,—}þŒ©Ëí£œ´Ú‹³Þ¼û†âH–扦êʶî ÇòL×öçúÎ÷þ ‡Ä¢ñˆL*—̦ó J§ÔªõŠÍj·Ü®÷ ‹Çä²ùŒN«×ì¶û ËçôºýŽÏë÷ü¾ÿ(8HXhxˆ˜¨¸ÈØèø)9IYiy‰™©¹ÉÙéù *:JZjzŠšªºÊÚêú +;K[k{‹›«»ËÛëû ,<Ü!`|Œœ¬¼ÌÜìü -=M]m}­½Í¼Ö .>N^n~ŽÞü-@ g¼Þþö®6ÏV†oŸ¦oÖ¿ï=ùÌw°`@x 2l¸p Ä3ÿÈTœèå¢þ·pó±#–Š,ùðä’]Xª”âңɗZbÖœIs$Î16s2é©Ógˉ …idÒ£O€^qÊ´Ô*S£ ©:«ÕZ£tÝÊãkÓ¥`“ˆur¶ì´?ɪ5ÂvIÜ·2æšuKwˆ]${ó¶è ¯_ €¥ ì£0ňM0¾z¸ñŽÇA(Ka™käË82'ÞÌÙ†ç£Ck(=´é¨u´^]áugÕ°aÈ^K»¶‹Û¢sëfÁ»Fðß †³öM<…ñºÈ“ŸXºóÒ_TO~ýoóé$²ßÎ]„÷²˜?>½úõìÛ»?¾üùôëÛ¿?ýñ*þÊëÿ`€H`ÆÇŸràmp`ƒ>a„º— þMˆa†nÈáy>· ŽHb‰&Ú÷¡c!fpb‹.¾HbŠ%\c6Þ8 ŒÝ­ˆŽ>þ¤|:Ž@cFéãâñx’N> £’˜1i”V^Ù¡” ‰e—^¨å\~If™ø…éÁ˜f®É&…Tòõ&mÎI'{hçuî¹ç¨Ég ]ú¹ ‚ú$¡§å)¢ŽÊèb‘Bðh¥P*š¡–nå¤áÀi¨?bЦ¢žš¥§•©Úª®ºHê¦ÂçW¬Ìú^­¬j꺦D€¿Jtƒ°yÙþÛ® K²àêÞ°õªŸ´ëë±Ê’¶m̾åìжg-EÝ"ð­ZáJ0.{åFdCºe­A»ë½[†½êákѹÈ ½è›¿<ùkÀ[ üÁè\µùA†ÃçQ¬”Äøa¼Â(lÃXlÇ(a[­¶ÀÎrT"7@2&¥ñ}3sóÍ2ÕlŸÎ7ñ\߯núrq·ÌâЕ½@Î"(½´Ç¸MŸÐP;Ê´N‡p5ÖR÷Fõ|Vw-hÖ l Ù‡šÚ¨]ö×Â-×póÉön{p7ÞrÓ°w}÷ù÷qaË7öàmæm@à(N'ãÔÑþ²Ý³)¹ã ^ŽyáÌ_✓™9å?=º™¥ƒN+ê©“îyt¦oìúë^®Žòé–ÛéÊ2 Ý#ï·ÇnÛì6×.¼•¸Ç[wÚÉc¹| À7ùü•ÑÛüÛÕ+O¼uÆ÷ŒüöG^Ïrö|‹Ÿh÷»}tøèIþïæ þ>’ñÇ0}•õ¯¾v¬çê¾üaâ~0 œ d ¾À€zB`)è6ʤ€` $%°ßù_´8¿OX¤G1”ð| Éþª°r(|ab(¶ꮆ¾Ã_7W  ö°€?Ñ E‘B¬Ð-¬  äArévNâþ‹˜´ ºÐŠÄbð´XEb1†Ú#Å(=/RÏŒH|¢…pˆ¸)/ŒÓÊÇÆP$1KlÕõèFEÑ]r¯5Æ–‘@BD#öÈx¾<‚b(è#šxÆ:&òŽ‹P#5™FHÒO’" ¤Šy¯B¶ïæBå¾T)CVÂ+”ŠŒ$#·èÈò‰òqœ¤)gÇÐÁ2‡²ÌW0[·;O┬å(oYÌ~¹²`ÃŒc46͇US˜×Œ˜çˆGhf‘´ä¤-•ÙÍŠ€ÉÐ'ÉÙLs>ãlå7 Nz¶‘‹T£þHé JžÀ’Ëêe)ùIBV“ûÌ¥üþv Dq6”™ºt&/Ú š€  `( ªB…£œÐh 8ê-ƒô—;ÊæÅ¶‰ÌzÎ2žàì¤;— ÏŠÊó¢ý¨C}Q#’t&%JÑ¥ÒŒ²”Hëü`;ôN{n²¦ç¼i:3vÏUæÓª25¦KKSvvUšYåV¡ŠS©–“ªóäêDsúP‹FTŸ>¥h\w:W·Ö®@•«P{êK*Q¤ ª&Š*:¶ò”®ý)ƒšEÀÔ±W„ì%»RÁò‘°4l&Ö—>õ¨ŠíhÍjS´^µc_•Yh¥¸Ú“MŸ©%m"L{V­Ö–³”Àín‰™[ÞN·U¥mqmþ‹â¶Õ¸ËEî!”»XÅæUµcÅfYû[¿–t©Kjmb©ûVµÒ”¹Ñï^Å«Séþ•±“µk_ñº^½6Ö½ÕîeÙ›YÊvѲkĬR5[Iá²0©Ûð@ÌD•»Sòîk [š]ךÁåïg¼¥¦Â¶Âö=,†Å¤as¾Öo?-¼P{ØÀE°=;À§)Ä©<-Š/Ýéêö¸.~DŽãK^÷Ø?Ž,‰ï+ßöòµ¾Gî/~ÿkâ„Þ¸°þ-1}+ÛáVyÁ,>é;ªâ wÙ¨_N)Œq,c<9ØÆYŽñ˜¿»ãæ–yEFrì\CÔÙÉê5r’ó{þåý¶y¤[^q”C:åÎŻl¢3f77z³6á™-±g-7YÓ†r OÁýàÙËCôQI| áÂLOÐz¸T8Ie¸ZHLåôDMÊvñ#"†ŠF$Ƙv&˜ÂKéK b²¤\Òׂ \W;œ„€3L|x·çW *Q!a"ÐGA|-LЈDÈÀCª2’B6ˆk¼ù —o¦à¤}„Õ$•TA¢n”ç©Pˆ5á,²Œ/²EvïøòE‰:î•Ó¡þ4¶H¨O-”uƒjÀ¡5ä:,|†R&7AðˆçQgˆ0ˆ¬"K“]aE ¼yS™ý,ˆl’À\»(4í6BNª(€LŸ[r5âC@áÕ ]C%ñZ×Ío>V*Zƒ|pBcL\f&æa„8(åJ_-£Ì$1H˜½*ž™Ç`á$T ]úˆ)AQ t.#Ûs œQqdZ_É)oUÕ žG£VƒžŠhlz—T0u€ F¯Ôâs?=En®°y0L>É 5ɹ‰pUM~Ø TÄP(E Œf+S—)ˆA%ÁñTH¸}rÅ ÇÁ‘ÄþŸ³N¯ƒVQ¡{0–TR$@(. k€Vƒ&ëheLRð®K݆s—„´t5 ÕIŸ àfÁ²)¹FÂØ™t&³Id€®+"0õ›O¿~­ˆ Áh0“×fmÅ#JøˆbÞxÐi6OŸ Ý+p8‰ˆp©€q-ZIU ò¡*$2"&ü6ò @šúBåk0o'ÎËÅ êÅ+´d8ÈEn N !1ÛÅÚP¼‡7j€Ý;‚Sž  â9á…³ƒÝ$CÑÌeÐ|ØgOžðƒkd¦™[Í‹nÀÙÓž¸Ð0íL¢!© Óþ­ u4Ü\&j ‡zQ:>´ ~[‚26—+âˆÑlôa˜0úñŒ•‹.©†;U íÄÂoä¨AÝòeÐ+F¡ˆT§Zø‘!$pW€ }J˜ !a̙˰|ÈGÅ@ùqFcÆa:úN„¾à7“|ã2_IYOþôŒ¸#|×8…ÜD1‰9•¢a’âÁÀà‹ƒ# d2M,æT†ðBì…Øœ`‰+™— 4Uˆ ð…Y›[S¾a@·È9s¡A\  */ÖˆþvЕœlaA8,…z@ / %Z4 kª!.Áåï/€ÀŒnFaŠ˜c‚…rŽÂ…ô]ò€W€ŒeÍ  †`’Ñm‚7v4“¸ÇEPYªFúµˆÒ¹(“ñÙE§=T.PL•â–dg¥ÁÑ‹R‰ v²'¼,¨tËØ:z… pÕk\ÈÐmJô=¾=†A¹)†ì5g(ÓW‚hÄ]–HP|«Rƺ Ï>à¹b8ö$§ùÛ@ö è&¯:! õ1›Y1'±k]®ê¥S!`/bœ L ñ?¡}/ᓽ¼±‰hã6X˜ÔúÚd7ñµ02þGŠøsˆJ"®À0EÇ4ïÀÃ*H°fêЫ!ø rÚ/ G€gY\ù̽’ÃK¹,I–ÌÃAzÄ@ŒJ¡h%)ºÊSD‘…v2-­‹„¦VcŠÀ!–±à2|Æ‹Ž0(‰ÚJE1ÄàÌõtòè앆Ȁ#Îánœ0ÚÎòŽÄà—(·tiN£ÕªT !P€ OAÉ&‚5/ðŽ*¡ í° ¿º7(vñVlXñ H®4gÔU—œ¨bÁÄÄ&RqK#Rvdáy¶ZP²Õ˜àQ80@bLZ³x;>¶À¥EÙ´4“‹²¥›”¥8þ®#tø%aδ•hX €‰!r4Œ! £2I¬U¯ó`,b €K€=NeØäZÎtFe/@E¼Õëd>*ì ¨y w6ù¢ ö¹žµ“4½ÃÆÇHÈÖf˜À¯i¸Zsj.ŒR=8¬K¥h‚Á nŽ ì‘ÏâB âd¨Ê,XB ¦¶O æEn\§ÿX';k&טÕÏÌAn¯ãKx B K†)yv¤ŸR¬ü–ð›Ð[…qe©¤ð±ÇÉÌTj%—8Äò8µµ¹ÆmåáèM=îV9\±®åJœ9^°™cÞ*ê’0F Ðq—JµÁE±†i Ú¿,ƒ!tbT²¹–T"Ç—I”2h õQ(¡Òedrâ¥ð«¨ø’˜zźþ­O’oFíè‚£wPcˆÄd; b ï$ýÃs·Â)±° 61(‚âAÓ4…Ðr—„èÀ€RÌÐ$“Ó"R älÖ ãsb4BAqS.†D›‘€:•^¡%¤a"#/H/ùósPq‚PÔ }FuÓu"t-\0:ú “ñ›° 8!}s€C'¶V)È6;¥â½°=Ör+WupwU16|± \apëàÀ+­…ÖqSQ€ «"C÷£"0s–Hã#ùÂ*S:•q2†a+ñXS"nð4%2Ðm¥þRøbwñµ €l<ÇMM qm†±d:D>Áá‚q “àÀ-ðàÐV¶ó9 –WQP NÀQÎç:qÅhæ nó bBÓ1JÑ`dt p¼%1I"3/Ÿa.”ž±Aq=T‡2¢ŽZ€2Ì·7A \0ªà%.¦dwö÷1ð¨ %'JA’' µp¼1'wã1sQ%@Ć;[â:s×8޲IàR좬âMÐr„N“‡Ev;0t|EO!e®"¦!(8Cõñ½£%'ðÄ 9qÅÒ >(þ|02†`Æ‘d"C—8$£Ž©7±o a6–“šbsÂÂsVÊ`8C ÖAÀs+̰^‘Ñ@¶‚5—‹(n  ¡b©ðf›r"—çS é´e,´µHZáZ!D0l¬²I2Fâh…úƒC70”WW¨—æP7ˆmr¨ aÖQ Φ ñ¢.†+13Dˆ`sÑBëöðƒ¸V :UIò„]—ÜÒÏq\BAb ðfrSEfò[!æ“2nL2Ñ'êt5ŽóÈa ND §9%9‘B6â#†@Ïþµp¢7G¡ ^É.œi zT éÃI  , ¬°(Z@œÇðEÄsQæ³`ÃAÿ B'c‰„ÁŽ”Á{ÉfEÄq„àÕ£|âànVä0` Bõ}-²P:Ë¢K%tO5×N4‚6ðž¨`Š˜P±bÁ@9Ž0,¡›‚el‘+µñDEr€‹Ò"Ä¥"°“kBŠ‘¤5)é#ûÓ‹q)^èt&$¥ñ±ùÁKV³,€¢-Ÿæ •-?‚Õp<àç¹Á8?€Ñ „Q=Êi07oñÁ„öÀ¢¤@ÜE«`)þ­ÄŸòù1fÚ´°Õj°D>ž@ÐEp)±„^!j° ð-ÞЖi˜Ò7‹E2À< SS"¥ "p«¶”†9)ø°Q3ô€‚6á¬/0F»Ñ&À5‚ÑæU*¼‚2Ôs0DÄðr*7|…T$®+0€Y7Ô3‡r#2év·”¨ñ†àqÂsRÄ6$œkòßøªtglp–S-GÂí¨gæPz fÇJ§_ð£|á¦?l‘U÷x§ Œ*°Tb¸XÆ ðA”ED…bNC½Á-úò Þ1‹Ÿp ÐTA‘ ÿcþVø7ë<;P4²‰øpú7œ[’&90ˆ×r(òsgÁŒ§@'¡ŠéÒ'w…‹„ „öÇ ƒ /¦“J¶nk ”+†CØpT.*Ñ¢ž7k7ìUÅ86 ÷¦ÐpáÃp‚=H ƒF2´"b‰@CQp–”V߇w‘DT:IЇX¶*‚}Å@¬DqÙ…‹s!tP¦BËYhp3ØaÆ ¦O7}’3Ò>b9†Ø0Úes[1mVW¾°£}d¡xK,eU|Gælú±'¸b…2à(“+!!#„# V’M"ßjN“\0B€þXÔÕ'Ã冉 œg˜gJ> pfâ DJ7ãð&òà?¤_»qw†u*¢qÃ6…‘O¦è!7am`9ñ?ÈÁ.ßw?9E»})Ø'ƒ0n}q&G¹Y*ë÷Vå@NsÒ“Û0© Õ`-¢ð§Ÿ7‡%Ög?pu^º\àR'Tµ!t4oÅóØÃé!Ыéð!êP ^Ûj1DΣ“~tçD:r' ÐŒÄÂ0U¸WQ­¸Ó¬2ÐñtO¶S%f°bOLx’”%aŸxQ¡CiRU×&Ü ‰?»èó1ê6 êeS¡2ðmÃB±$DGˆ °ñEþ#5‰ðãÀ^c@ENäRÃñ:$^¢- ˆµÙp]á R6ƒi0 oÐL;0f“<ÒI±oÆà’ù:ùÂe(ja&žP<:JýàPAÑpá⨭ëT*Q–Œ"ÄôÁ—û!7ɤё#–c>ÛŠ‰b}P³Ì! Å#ÆÈè1åS8WÓóawL ø€Æú$lP"e\âZÁ¢` „ ¶, " ´â Ã3ºqL‰!×\ êl÷ÏCVbÀ#aA.VS6,H4щ+leg3O@í1ëdfQÈì42bHŒ!Ÿþ­f)F0OÂi>PE­Ø<z)²JI ½é¨Ñ!HKSÄŠ8”‘ôqu`M¾ª'd6†Ê'’ÂÏ0–ÀÄ¿°7g™Òº*H‚cDUä"a€?3ᨖCOž…è¥ÃTp«à BpGS«r@ÑYbLÁJ0Õ¿ ¾KO€ Pa)~P—f®w Cð¶ÎD—ÓgÓ.r˜Lc°#gPñœEH<€ZG×9í˜:ö^1ÁÁ§%<ˆÃ>i=ß¡ ‚ÉΆd£0Ç¡—–8J°£¬÷1µ(ÊDDóþŒ¢1ÄÄ1 EùÂ>ó…¹s Å,8,’C'QF5' \â„ð· l6…<á~ð @u^[мÔu;ÆV‰»"2F"±TÜà ’Øã /©sK{²2¶¥Öqà¢4Îb³2€9{¸H[Aµ„äT5£^L00Ë眂å`H„©×!!׆Æâ(×Q³p†\™{)¿åàEâ ÐÛß ?ÅÔ’ìâQþ ¾``NÃà! © c´Î#"À ±ô@ý±Á –P” b)û2Ùëf[ðiagAivË<ŽÊ ô“­èC”?« þe¾sÞ —\'¦‘üÄTh7,ŒY”3âÙ"[ˇ¤³$g¿Íñûض„1=Ý×j/ŽÓOj) A¬|Q¸`IöœàŸï‡ZZàqWÀ%H1Kä0/¹ö‘¸Õn_‘$6÷NË ¶›Çb U§]PÚ,a+› ëAËòf\–îhKþ܇êi°®æ0,Õ›H6gãŽÆš²°Á2Q31¥œÄ£ÖL–Z±$ãÐ\. 8›1qÆàK‰SÄ0V0ß’8•žv~N –Àƒ B'oáÍoÌg4¿FìdD’~  [Iþ3 „d ˜š “‘Ÿòã#æó,­_”b(h/§’â`yg®X¹Žà@_$^ã ˜$|sÖ}“x»©gI€u&ú'N^~Cc i/ç ò îtÃ_+«%]Ä(’®Þ§$܈ðWn¼%Õì`ç§Q¤°%1ˆÜe ãä©,!‡rt„#)÷MÀñ~ÐLùpu\ÀN“‚÷!P )Ã'¹¡ÎH+ì4®þ—÷IáÂíY 5Ã5Ûav_¢L ¶K µÑŽ G!¢gf-$#Ësྠð VÙß(ZûQµ=ÑžáS/7lÿ‚Z´\zDN7‹:·gJ-W> þz"šAéóÞéš$ñË]!eÑ£Ñdê28¡JëãUW ŠSà`È •B”2j¥Pˆ"I cÏh¸%ˆ%FLŒ@ŒÄ0ªít ^ßî€ò-.Ÿž1&cj8L¯âÚà 0Æ¡´,¥¼xÜ;qw¡AEËï«… ®²„‘…Œ$ƒ‚„‹•3«F"Æ’J“(¸„%®#5Ê‚&’˜žÁ3ÆT…®‚œ¥7$& Ÿ¾ã‚/¢¥ 5),Ô#«ŒÕ;ÄXF±™„;BTª(D ì‚wI¤^®Hþ«Qbð¼Á¬€+-Hð#BiÆ"ÉÄ$¬‹ 37B!dóa@`$HQ™0‘kû¸d@Aé+JK$½KƒáGLÞ¤Hryäe—|˜@À"s©†Â&ˆÊ AÌÄo}D.éäCØÕ3ï¢ÐJ¦‚„L ¦x Óá㈉77L°"ó(¬n²Ù£G& ² á8"Ž Ê¢"à( øÖ‹ ˜0Ââ^5+Ê‘°„°ébËãZ^(d²+ T‡…Rº,ȳŽ >4 Šµ¿o(9 ÔeÜ{x…õ­€&%tëù*ÀKÛ d- ·!'›'Æ-@{€»þUV+18RƒÕ [G"1Š6ƒþÌ‚pð^i¾¬”Æ+š´bXàº]Fé§ŽÀ(…ÿú»ÃŒÐÌiÊ=J¼*/5*˜`Ö Cü–à`þ¤Øa@%êiJ”A´ø¨°‚»¤@AQÒ’g @Ø#J@d¯ ¦@Ô"á¡dz€èe’eò@±HkÀ¹È¦`Ɇ_hàî„0 Y‡¯Bþ‘MbÀ›±˜b¸)$ ­ø³"XŽp¢ Ȥ)AŃÀ„Í:JÆ'ízèò$ $Qúxä1O¬"a„MyC»@]R…Q„Ñž:þ€¥¦*J@«VúªˆÍU˜¸ÆŒ˜\¸¢Æ“b ³Qå8ï´aÌÈAW$ŽAK‡ š“oA2†t†¯Q+± ív â€L0`àä.¸ HòPL 2IÙU‚Fò‰Ö‚¼bL•ŒU5Ä` „X*ˆB}2¥cSÀà ¢ åaY›R'FúÌ2ƒòJÕm.j%: Z°åcpI”`À6óyç¢QaѸd;^jVa[߸AB øW‘±Øl ÒJ¨ŸÞ83Xá†a€T”*A%Ÿc¨ÃØO‚€ À` &“œ,Éc5(Ë&3–ƈ^{vÒ†-_¬Zçˆ#ͦQEþ0sé™7öðù†OœarN°ì"ê›VÒ0¤i òáB úKIœZ£»Dë'ït4e3Ó10•KœÈƶPÈ$ ˜jk„Q1htÉ•B1‰=Òe˜LÍág§¥ìÍ'ÊC† ‰&Ù€vîÝ"¬ z´æ±4Ña'®•tøÓ` YZö›• Bá› WåÛ’kg©`&6¨·Ùd¢<]€Íüü')  #œà‹uŒ€ˆžå-¿1@nv;9„t+ FYuà˜2TÀtd @ ¼ÆI¼óË0IòLŲÀMc;ìþ„¢0À8€¢W.Ó„mÐ iPÅYº AÆlÏ;ÈàV$x!äè¬%ß »N  wPíD¯‚Í Î•<êPÂ.œÌ }àLHA Â" p}%\ hÀ=¨BÄpI8xží|€–VèªHS»¿~À¯OÔ†àèa•q_xL/H@…6mèNš)„?D ±ÿ4á }Â…ë€ ü ‰íAçnCèB&ò#]PpYÓ ´p5ñ\y†D¤)ZN ˜Dsâ§pÁQºaN"TDçhaqF‡vC’èQ’_ÐxN ùBþAzˆ¡ÞT%§à9a Ø;SµŒàk|óÏLN¯’³¥5§¡(èuT‡:ðIFaÉØRÚ 0\T‘vúd ?28i@dû@7—-ମ+ã½I¼èV|Zo"+öW:hd0B`™§\HNòE8v@¥¥”RVNÒ(¡3(Ù£C}”™#:z"6lŸeZ@›æ¤µ—Ù\Ê4FŠº¶¡q¸BhÙeMhcÄáÂ*¾šO`M¡¸ òPžÄ¶xæjsRXÃA •®(L+6„¢ÿA¢ëkß”á~+>/¾ÄpŠŒp«ßJ þ‹dêÀ:«ƒh¬‡?b€.”¥͈ à™;å 8è9¬KŠü€  pǃŽÁ¥«ÐÎ\6ùÞKj Y!pÎVH¨9‘ 1Dç¸pX¡Z‚åñ“TÙ!жfae)ÎD($OKdùà \¬1plG·.©b׸úyšËË›s†èr=¶wœÇ9”“]oØp[W¤"q£z>í:åº-5FZƒWp±É61MAÄ7/]@BcPN¿Ðb—YÀD°ÔÀ)^p`HH¬«2PK'©[£à¤…oÏ(f)H©KFcpy'lBh‘ü] $þÂ…ÀøÀó±Øç¦ÆÆùtc! ¨” U$Ág‘F$d<‹jNÎ÷02Y“¤ó§¾;Rƒ~Ñ "'e7sšÃ‹Ý)ÚÆbx€³ºµ_iM|˜2¤#ÍtÏ‹ Œ›¼(!v ÉÔâ¶ûà¡IB»™`‹£h£"ð„ë20.v€B? “qYIËJêÇÐÁÑ1© •z\,Æð!° Ã*ÃÌà/‡‘‹ÆÊNòý±ƒÅ³"Õ~mÅ12Ò¯Vx`8²œ®pÆ;-oaQÂ\Ö )ßà¨9aÿ^&Ìu-TJX›¥%’ÔÇà 4àp°”þ£Î…ðÐ'S€L~;ñ/]0n3  } £âjÀ:bL}wÏÕF‡4*•@QGW1Ž  D¨{H¾è=×a¹‘3ŸQ£S‚ˉò#©p2´5Ày |zœ™©”9” ÁGˆ)ܸ²ú¨º5ÈM¹»A  ¸‚¸‚Aù9/©„‡±ÒJ† 0#)š¼ B¯72pÈ*ó ƒ(“¨ªoQBK3˜Äòƒ@ŠÆ±£’ˆ’U饴8‚hˆ¡Chºl©òøÂÓø¦ú’X”Êy>êŸ~ÐH ¿…˜ðšˆ$*L*ü F(/{ÃŒà/"‘µs‹þ½˜ Rº"apéÀ¨B…*0ÙÀ”86ï8&.e¸­ç0zÉ,]ù/ò•Å2Ã5ó 5J…G‰dàXµDqµQ˜ ¸w“ùx°UÃ7¿ Š^K:¤©6XK™‚ì# ³9iXˆ A„´†ïh î°„B oè `›Ù…q¤5ˆœ+d`I2T*ˆ‡x`]–¡i4Ex;s°)~@…¬$†º» ˆªÉ†¬âwKX ` rQ—»ª1'¸…l†ÿ‹QàŽ…EŒá“tÔ<™„ 7«´ŒJQ à“ Y—ðˆ%ñ¿¿ÂþI8ºH¥è½Vò1¼9s•ÏêM Ÿ9é׹ĉ;Åú¯V²%`$9Kž’ ¼"Y ÕˆœÆá‹f¹ ³)i –ó€1'æp‡bƒ:´k`%h‰IK> ˜›IËR€Ñе“7E¡ªc Á  ³J°2;¹“s ‹Â:C¶•¨5z¨8_ð‚vã)鹤ãÒ¦1ÛQGh`à 9Ú¡›:X¿Ø#¢™Ì‘5aé >à–pÒ4Q –¨¥iLª:<¬´à® hˆ/ @øËƸ“XýxªXŠ^ ¹H$˜fâÚYÜÊG8‰œSHž¡H$ºÑ #h6tñ„)ˆ¶"0º˜Ð™œ² !ùp$¸oJš 9€ò² y»¨Çì2„ÆÄÒˆ¤`ƒ@ !‚ËÚ2/©-W„wh•40Ìq™¤¨Åò‡µð$øŠBÐ)Ûº0àp ¸x>ß“p©˜©´Gå9¶Pø¤3žê~±Éº ¸"ŒRCИȆ€0(ïòè¡âA€"Û …w\£>±‡;magic-8.0.210/doc/html/graphics/toolbar.gif0000644000175000001440000002404110751423606017121 0ustar timusersGIF87a1÷Ü###$*+Õ -- -.  #' Ý */,2$-"-%&))"3%/.$7 #!#!7%'€‚!-(="/"0$4+A ('*,/!)-!/2!¢¥$0&3&³')"B1¡µ3Ø37777Ø78„£=2a=z£AACBj…HŒJHPLGZQb‰Qc‰Qh”Qz¹RRRSRTT†©Wo[r§[Æ]…____v€`vÆeÓeg`€g{¬g}®g„¼g›ëm+‘n+‘qÑquuuv©µxQy–¢‚‚‚………‰ ÇŠB ‹7¸‹CŽŽŽ”‘•zî#ÏŸ=P =P¦ §Z§‚eª4Õ¶ee¹Šá¿WÁ_ÆnÇrÇsÈcÈy$ȉFÈ‹JÈžrÈ£|ÈÈÈÈææÉcÔ!WÖb× eÙÙÙããeå€íééRê ë—äìììðð7ù¼ÿÿÿPP'"k¢'à7ü8Xñàÿ¿^~Ùîq@@CPOÍ<°öÿ¿x5ZpjUªE}b½:2çS ?­‚•úlÖ£X¡EJVêØ·fÃz5*v#Ù¦sñê5—*T[Õnå›õîݾy*Þ«ñðb¾ló2~¸vðÙ¤3C¦+ùqeŽŽçŠ•ûU.Z®#£žÚ™óæ×cÿž~­š¶_ËQ5§üÙ°ë¾z}Oƶbצ#~Þ-T³pÛ‰EÃnü»mZ΢oϾܼ;f¼Ù÷þ.6Ý–°MêeŸ_8=nöðÛkO¿¾ýûøóëßÏ¿¿ÿÿ(à€Åaà&¨à‚ 6èàƒ.xÇ„Vhá…f¨á†^ᇠ†(¢ƒwbâ‰(¦¨" ®èâŠ-¾(£‰wŒhã8J8£ŒTĸãŠ=–ø#5æhä‘ Ùá…TIã’6#”Qöˆä•XêÈ¢‰r‡—^Þ!¥’!Šé$‹eJ™åšY* & ]Âù¥œfN©‡xæ©§žzÔ©d/*è ƒöP'›ˆIf’cÒèLJ~øIã ¾ph¢˜Ú¸è‡’²øh„‘6Ê"¥Zªf¦¨&Iã›q¶G§þw| a¨gÞA*„¦Z™ê®º)'«s«¬Ò:å­æZ$¯Ì*¸i„ÃB +²*Ûìµ> a´ N[饨^ë««Àr;«·¥‚.³ãën˜¢Æ*m¼Ô6híºÍjÛk¼Ä:h¬’õ2x/¾¼êK"¿óÖð‚œj»ÀÂ[k¿ þ;é·§:üðª¿v쪹Ţ‹«ºcjpƒ û+r²$—ŒèÉ ¦\ñÊÕ¶ìòšJR9a¼:ÃÚsÆ7¿lb“DmôÑ1­´ÒI/í4ÐAã ÈÓT·HõÓV_½ô²QãÜó×`÷ÜõËa—mv†c³)ä*úÈ6Šn¿McÚRË}â™vO÷þÛºÒ}eÎ:óx­?÷í·¢s3Zkš‹+ˆÇ‚xØ|¸¦4ÂñÆå˜gž9°>qÄç ‡ú°>PO~£’oÄq¹¯»ÞºëmÀzDŸ˜;î·ãî¬q˜ž ðJ®z™4¶ûò³¿Q{¼·ï.}ïGü¯Ä˜½ñÇsšü‡oØþáÀcy¶©w<‹³C>ôã—oþ馯¾÷,¶Ñüþ°+« Ô  î¢'¿ù ¯~†»ßúî ¿þ9Pv®ûŸy7@ÜЀz÷ˆ²ïEè}µê„Èw=ú oƒÔÒÚ÷ NI„"a­²‡ÁâÙ/…dw¸¼ç…‚þ@”žõGÃà9ë†8T¡òøÇC¾0ˆ¬^ùЏ=$&1A¬Ÿø"$Ã)iï|6Làs¸B-‹¤b¹6F26‡üs¡’XA(Z°„_¤ Û¨¤72Ïr¤íHÁ.êK{#à¨$8Fnpll£–´Æ4!Qi–¼dÑ")I,NM“›,(CùÉQб“Ù:›*U‰J”­ò•akeÌòv¢½½Í–lã¤,×f7¼õ—?:å.ŸÉEB©‘Çf+Ÿ%†5^44Í5*iØÌ¦6·¹‡D^Q[ÏLÐ3ËWÍ•š×ä¦:±éÍ$ê+œj&ðÎy z¾*^ëþ\g;q3Ô5ŽSøÌ'7÷™Â~ñŸÐ ¨@µIP‹xLh­ºÍ†*pQð6ª¥mj];Œ×ÌNµ³Ÿ kbgÙœæ1‹¾êms{Øñ"7¸+-î;¨»ÚÀ>÷«½Mnk Ûê6·¼é]lUãÚÞøÂw½ã-ïVÓ›Ú¦>6À×%ðoëûÜÞFx¿áî(ûÝç6±%Ní…‡«áÙÎø³þ£mìf'û¢ËÎ7Á ÎïŸ<ª)x­ ŽîZ½û×'õÅU>sšË:ÝyVcîð•ïè´.9ÎÙmqw½ç4?¸Ò—îha½¶Îp5Ëtã9“5lb«þ*Ç.VÐaÿ3ÙÍö®;ôlˆ»ÜçN÷ºË•U'­ÜîÑ@ï·\;jùZ-ü}ð‚-$ûˆ>8þñüãµ`ø¬‹:çÊfÑ«ÃlÎ\JŒïFOúÒ›ž } üáYT†Ö»þõ°/ƒÇ±¥$X{ÞöŸïQèOÏ{Ò§¾ò4нð]?{qÑ(Ö·ßüÏuo"Ñ÷ž÷¿_ý†?üâçëø>¯ÓîŸþúè+‰ú·>»°uÐ7ŸûÝWý÷Á{ñŒü,7ãÑozïŸý¯wÿ®jφä»ÚÿÚw~ôç{êwø×zú·1š×jþÇ€ó&Î7€¨W€¬w€(ta Ø5Gxó'|h ˆ*ü÷—{h#x€%˜)'ˆ‚È·|+‚!(}x˜‡r X~Ì÷è‚Ó·ƒ1h2ðwtAÈ‚ôG„;({˜VIqˆƒNh„QÈ\Ø·X… x…$˜…ÜE~\ø€Kh…X„a؃0§xƒz’‡—†…ãv>ˆgŒGyz¸‡|؇«‡g‚÷g}ׇ„Xˆ‡§vþywv·ˆ‹ˆwŽÖvŒ–x´4i3B‰2b‡m˜7šL–è"l8tnˆuWÇu–—!b˜^4ª¸Š¬ØŠ|+P׋×+`p‹¸ˆh€‹¹ˆG˜(JâŠÂ¸ŠÂE‹ÈeŒ[6%¼º¸ŒÌ¸‹¿(4,2ŒÃØ_ÈH\×h‹½èŒÍѨ6©H®ˆ`×8\ȨÏÈ»x‹ßX7w ŽãÈdæ(‹ÇHÚØ¼ˆÞxŠöŽðHŒò8³(‹¶¨·híØ&þø¯Y°b鸌 ‰%ÁȪ‹9‹©ŽÜX‘³ÿ‹ôX\å¨]ñâ‘˨‹ ‰$‰‘ÅXþ’Ø(“(Y++¹Žùü(`" ÖH“W)¹7ÉŽ;Ù`=)Žä”ç8”™“¸Ø’ˆ3ÙXö&iC)‘ú(•Fò’ Éa'I‹‰“D•GyaII&6–‘fyq¹Ÿ˜T “ñ”LÙ‘E¹’^™#¥ˆ!¡fŠ[G[˜Š_'vg§˜zˆ‰ùgh·Xk‰‡6™”ÉY’˜7è"› #™©Z™"›¸#u)…¡HŠ£h˜É$¥©…,B\*]±™ŒJ‹fàŒ`p›FY+´8›é›5y˜vyܰ©c6i›¸©›Å³èœÅõ—8¢$W`œÅY‹N‰‹ºþ¹Œ·)\*PŽß)“Ò¹:4’]朵‰›ê¹”YaibåyžØ™œêéŒæ–îÙšcøšò‰œÊXŸöéø9ž”ßÇy]³©Û©œ¼Èaá‰\áI #B ¡´I#Ú¹œ š—ŠŒ³ù–ï©bñY²Ù¹ º›SÒ›YI¢É˜xÄé¢j¢ôy‹(j£*J&É£ù)œ¦IœÖ)£Ê"Îx£¹I—SRà)”ú‰ŠÚŸ?šžº¡W‰Ÿ? £RJ£ÿY¥hy•A©—Yšw#º¥èè¥JJ¡3¹‘*"jz:¥š¤GJ‘ù Å¡!:ce:¤¾‰ŽHº  §þjŽmº@u¸š2˜‚ù¤ýhv|v‹ ©”¤Z™”Z©‘Ù˜‰x™›e™žjYŸ¹w€—K¥:$–ºŸšš(2š3â¨â;ÎÝ-îâ°òJ ã4®áH~ã9.ä+.áÝ>£Ý*¾ÝEnäñÒäJÎäáãñråP®åSNåí]vAŽåC¾å\ãáýåJ`ãaþäXþálžÝè]åþ}dÎæàæo>%MÞJNçu>æç­âE¾Þ|îÙk.á0ÝíãJRè†@Þb^+d¾Þ0éz®Ý>º4òçXßQ>è—>Þ9páãÝéSrå"ê.âƒnåf^æ¤~ä`.çà-ëJbµ>å€ç½nâïé[žåhÞåáèÀ.ì§.åR¾â¥NhÞçfâ–N#MŽè†>ãÁnç‚îìÙîYÛ.è€Îêà>ç˜çäNíAÎîežî™5ìöèßÎ"3ïâ­äôîçÎâŽïÃÔàgáB.ðã-ãÐágŽë‹~¯ìû·É³ Û;3»‹ëǘkÛNSþ¹Zóã‰KȘ‹ˆÀMÜf“È.YÌ]ZÎ"•Œ&3ÏZ5ߺ;ÿº— [¿¨ Ý}.ÞAáGÞ°2LßôNÿôS+Q0õT_õVi®$úÝßðßü]+#p%Pöföe#+$ &ðöp÷o¯$õ4ëàôÞõ°BöEõN_e+n?W_õCðövïïÀîêH>ð% øø‚?%+&ø†ø‰&°øw€äÞtùS ùP_ù–ùQ ùWßùžú^NîÑ^è¦ú‘ø%Ðô—/&0õ®Oõ°û¯€¡¯G/ç9Pâ}û¸þ?ùªÏô½_+¿ü™oýUÿùÅo‚ïŽüI>ã6®÷ÎÿüÑ/ý¬/ü™?üS¯ýÑ äÇŸ÷I®éáôãúpP?ýSRý¯põaâ*wâD˜PáB† >„‘á@€î|P’QI>äÐDɇ)Z,1E¥Ê"JY©²DÉ;'’3ç &†èÌ) A‰EEêÐ&F9*(Ññ1$É¡6S®,’2+Ì•3«V¼ tα?u -˜TíZ¶Á2U’nT©š{uJV¬/»Ò´‰s§à(eÏÒl›XñÑ¥åjÌH×.à¼,õZæê¯EÁcþöñbÒ¥6~ 9²Ô»5+ó‰yŠfלAü-QÓ½I/uª:£Hº­­ÂŽ™v`ϸsïö]±M…[ ²E—Écg½°ýNOçbMh-]}R›5Ý¿‡ïþ«ÅøõßÏ·Ÿ?ýzþO0@¬m@ ,ð@‡ê¯Áˆ(Z0B×"\pB äÍA Ò¯C?Ñà GL(DOD1>W<©"_„1ÆÚb¤‘ÆkĬIl1Ç7óñǃ„1­7lÏDüN\RI#tЦ¦¤²J+O¯…˜àRK/¹dÂKñ– ³L3Ï\b?(ù³‰€€3N9áþ€ñH =à“O=C` Äë`‚?Et‚Ô\S=›8€&¦ä’ÒI7ÐS¼4L/·är>Å3´S0Oe‚‡Ll´?› À”K-Ýà&BBôSPy` Äã•WTÁTõVF[õíÕjÝàÊZ§4 ×TåÁ×TCÐrXü@Xbv@S\2AX–YÓœ}ö€h©œ–Zk·]áÓd»%–KlOM–K\YUW:›B˜ôU£Mõ€*­¿`õÕUË]»6_}ÝöÔŸ ¸Y°¦”wUµáÍîx8T]E_üF–×~ÁÜ8ÃŽ×Ë+7`€+Mþ® ePÃ\!†vùdpÍÜA‚ÐDà›q¶Hç*yv×J mJ™èMWh¹â—Qå¡TTkžÚ㪾”àZ%¥´f®‡µQ;M:h˜/ÞÖTe¥N{1g¹¬µÒXãž7Õ`%66ïcŽÙT´/ÝxáÍú„­ÁzXU_±u¬¥ÍezÜsÓ¥\-g/¿:ëÍ- öÞOéûd‚gæ×ØÉSŸîc‘ÙžÕà6xå‰=ýRqQ‰ÅìbQç1° ¾Ò…E@SÂNž Q uïc/žúè‹J2Ä&Õ?™IŽÏW½¢ üo~´@›áG Âü´Ðÿ¾"@ýñ-)B`þEd@Õ)Ь ãG¤ ‰‚.²à-"Aöh°H¤ <ˆ÷qðA`q_ÐR˜>΄‘Ò¨$Ã)Ñð4t¸Cö âÉCºÄ!QˆD ¢ù^X"°àq¢¡X'ñÈ€WÄb³(ñŒ¡ VèÂÃF0Šq J\âAE¸ý RnœT Vu2páŠ:¼£ëhGˆgˆc,"Ç(D4¦ñUr”oH8 üŽzÄãóÈ‚>âŒFâ øÅB.ñU?€– eX+o>ô! üÈ#¶R|á'ÛUƒN«”â9%*y¨Jü„“EdeaþiÂ-aJ<Âv 0&³xd4#iGñ\r“š$¢†ÉÁbRj™@&¥œ)hN’äåÉþˆÍLú² Û” ,kȳˆRs¸Ôe*ýØÊ`"ñ.L£[ª&J¬Ñ²†÷ÄO.óIÍ^òó—þ„'?Y)92alœ”å–:NRš|Ü' 9È–0 §É/JQ^-r£éèG'YÉ“YS¾Ü¤6zR&´]u×-ºÐ]®ò¡®ÌdD øI[Îp–}$QñhÔM"ñšJåßÀ–¹0crõ˜É|¦L¥™Î Ù´ÁÔ©IyŠ›Lâ„ë–™=ü”óœe¨:Ï:þRwb~,üÐúZØ>'ío­l•ñ÷¿ÅæÏ°‡ƒÿ+Y°²5‹@Ìžf³Ÿ5Qg94‚¦%ÒcÛ#аµ¨õ‘ZW‹ÂÂÖC‚ ¬l×j“ëôV â¹Rp©$6׸ÇE.üz>›pÀ#€nt¥ûp@n§;†¸@F2mfæ¢ujTWÕ’ñœÞ]Ë8ra3 ]°ƒÑšFö­ÕÕÖü·×xF²vðC={RÞt•}RÛv··%,ûTkgN6±•­ßeE‹Xþ°Ý–eìºÙ Zz/PÞõÆw~ä­FÒbµ„­Æ½è~“0à8r­uKpúÔ–¶âî¶~¶P›(ÀâÇxÆ $á:×p©ƒà’|JÊfVÅ5¾r‹‹Ç¹˜.taÝê^÷Mpj€vÀÝ…s,?Ðã t¡‹èóy“çõ>jÐS°ŸeÝ­[åAWÖµYü|ÒÎnô ³ÃU»pU­ÊY®qñ`d©°xt-i) ª÷¹EÖ¾ò¶¯fÍq)±Ü§DwÌQ hûެކžõÅo½åc“qh¬k&a$ù"ùÁ®×à~ß6q<㉾qÈ+þÁHÎ’MŸ^&O*N&Ùë'åù{ÿ|ïï»@®e.ëžÍ‚ŸÉé9ò8#^í·üÉ0ò¸¨™ù—ÇÏ—O¬e˜ä´·ºíC¿õ¶/=½zf‚Î뱯Íp°èÓO ´wöê‡Ñ»¾kGCÅ¿~ü}ißöÈO¾ a Pó»Éˆ¾Á³;Y+¾Ïû?ì; 5€µlYC¹V½ø½ d³¼gãÉc2à<ëá’ÌìK;ŽРŸŒ0òãµÓ£®ð™>t½„¡«ž£¸‡,r¸†7ÿ+7t;7ÆJ·xcÀvà &„7Ç2¾|“Â÷ˆÂ)œþB"ì·ƒÃ-¬ ,¡„» 0 !¼ëA!üÁˆËoó64$°0.5ð.8/üÀ8X9; @›ø‚/P€=ìÃ=äC?Üà lCc9D.D´5:¬Ã;ÌC°8ƒ5ð‚5DJ¤ÄI¬Ä3 Ä5145@4Oä4FÄ:1Ð@R9àËÄT´¸/˜ƒM„C<¶ Ô@5Â@DŒ[Å>„Å#1ÄZ«E|D‹˜ƒ?D]ôÃWœ¸6´ˆZ[Ä“!Æb¼ƒcìÅd\Æ_Ü‘ ¤/284oT.ü8;Ü:r\<ñPFVDÆ@ÔFQ¼â"*cƒxŒÆ  :p<| H2tÆù:Ä8¤3ilDÃC‡ŒÈk ĉ$ÂùEü*ÉÅÅ#ÅÑ3E~TÇ^Èv䂜ÅPÔÈíƒ?t„HUÜÅ/É FTFbI|FhJäG£LGHÊÚÛ !G G)3G¡ÛJÒ;™¨äIAüI$yÇy”Gz Ç“¹Ç|Ä: Ë—œÊì3ÃÜBˆóAº$ÂwKBÇÚKû¡ÈtBÊBÂ"T·{³Â+ü¼Ã”B/!.´‘Ó ¿Œ¥‚C"©Ì ÈÉœKp«Ë3¼KÎI: 6MÒÍÑ,MþÑ`ÍÖtÍ×|‘®+K ±‰:°:°ƒÜÜÍÝÔMÞ¬ƒÕ„ÍádMÙœÍ*©Í(‹Ü<®ÓMãÒMá$NØ4Îã<¹fH‹@ÍÓlNî¤éœN׬NëLα ;0ÍÔÜÎÒ´ð ÏâÄë´’òt•åLÏí¼O6hOüxÏ×Ïã¤O6‹õ|ÎârNÒtÏ÷üÏÙ Ðõ8ÏÍOèÜÏ“éOñŒOù.ìÔÌ;`NõTOҜР©ÐÖ\PájPGYNü<ÐÔ Q›Qø< ÍÐÌ$¦íÎÒ”Ð Ï ®˜PõNN¥M ­Q‹@Ï%Pý$Râ4ÒùDþRn²O&ÍÏ‹Í •Q›hRèRþ|Ñ(EÎ)'S5P,µ-5Ó•Ì$E5”¸pûÁ¼47ÂäË#„Â%ÔK>íS'¬BŬ·B5TÐbL€ƒÌ rLYÔ0|Ô¹ÌØšS*ÝÌ5ìLºDCû@S‰ 0ÕQ%ÕRñ@‚TUÕUeU$(€ÕX•ÕY…/U›;0Õ\UñÀðÕ_V`Åñ¨Z5V(¨[í ›ÐU]¸+™¢W-ŠZýÔ¥ Õf5ÕgVsbiÅ(¨Ve¥\ÕÖRhÕuE"8VZ%r­œl=×]Åh•*.þ¸j•k¥QL5×{Uñ ±š¦~ ×q½Ö¬²W‚5X„…$…=qýWzý‡½×te×VuWü€×x•ÕymØ¿ÒØsåÖ}¥Ø ±ØˆØKMS‹ X|=hÅ«»׊e؀مØ|íVœõW—ÅXÁ9YmåØŽ]Õ=™YX%YžU™ÙSZ•ZˆxÙ‘¬Z«=™ƒõViZY›hY­-ÚޡڙذMج}ˆ­UÊ:ÅSNýLMÕS#Ôùi,¿ô¿ÀÌ[½Ì?5ÌD¥7D%\ÍŠTGmÔÓZÜÔJ\ËœT©Ô‘ZlÍÔ;ÝTÎìÔú(YæR<ôG£2Э\þ‡­JÒµGÑ ]ÔIÆX]ÿxÝé\ñú\ØUKÕ½]Ö[×Í]ÛM]Ý¥JÉ]ßÍ@à•Ká]JÞ‡8ÛÄ(^â­]Ùí]é…Ù©EÞéU^ìeÞÙݯèÍÞß…ÞÓõÝÖÅ]ð¥Þç¥^òE]ôý^öÝÞÒ5Yñ=_ï}_óý^õ ßëµßúÅßù•ßö¥_¥àÞ à†^ÿÕß‘\¡ºÅÜÍ1?õ˾\ ÖÛ¾ T¿%ÔÄ<ÜÏ2Üv ááN‘6áAá‘fáqáî–a}ãàFÆa¹ánáöaâ žá!&bÜ#¶7«Sb!N+â&Fb&†býÐá#®b"¾â ÎbÞâîbþâcã.c>ã;magic-8.0.210/doc/html/graphics/cellmgr.gif0000644000175000001440000002223710751423606017111 0ustar timusersGIF87aá÷l¦Í‚‚‚‡Îë™™™¿¿¿ÃÃÃÙÙÙæææÿÿ¿ÿÿÿÿÿr@a@ðpNUhWicxs`V/'ceLllmg r‚.igBi@àf€¥'?àÐòñ¿¿øò¿!òšêø@@@ð`U'x"VàLøðð™™@@a€­û`` BBñÿ¿DçpÍëw@@(t(PWPm†òÿà¿ó¢ÿ¿!™ê(P(Pˆ8(óòñD£>•J”*Ô©X«f½ªâÒ¯H X8¶bذ!¹ªµÊvk[­p׺KÔëÀ² ðâ½KÖâÙ½åÆ}+¸0áÃt oµ+P/ß‚{™>>¨ô®ä¿yóþÕ;3Z„‰Mz´iÅ£gnXµoÑ¿{oëµ2ëã±EðíÚ¸•K.YaðÓÃ…kǾ½¦êäÌþƒ o¹yeÏe©§ÎðºûìÜã¿ïýݵXå¯W‹uκtÿ.Ô|óÉGàXÕ‡`úå§_sÓ­çßsÎ& fˆá†ªTÜxäE¶ƒ–}fzÿ©G[{rØb‡/¨ d÷)DbS»±¨!Œ;ÆØcN3‚'$B7~D¡C?º˜$J$lše\Sø Z“Lfé#–8}(eŽT†©å’[ŽÉa˜h¦©æšl¶éæ›pÆ)çœ Ôiçxæ©çž|öé矀*è „j衈&ªè¢Œ6êè£F*é¤"`饘fªé¦œvêé§ †*ꨤ–jꩨ¦ªª©s2di«þ½ +F²ÎºP­¶4®°îŠ@®ù lBÂ6°ê±ŸP,²ÌZª¬¬ÍFk곿+íµÎ.‹-³Ô ´mªÝZûí¸˜†Kn³æž ®¶êŠšn»ß¾ /ªòÎë.»övZo¾ÜâËï¨ûþËiÀ#@pÁ§Œ°¦ /Üp¾/jÄSü¯Åíb,ñÀþn¼©Æö‚L®È_J2Ä{Š”ª+œr§_eºrË-» í¨1o[óÄ/o Ö¼ïlªÐÉöì30#)ÑEß,*Ó×BͱӥJmÐJ_ª”ÖIq€Õ ­)Ñ3#]6Ø™b-³ÒeõÖnÇmiÛ6W{*Í]Ï·þÙg—ª¶×qã8Ú劽öá] Nê߀÷M·ã|»5ÏT?Íöår?ŽyÝÞâ<¹â^ƒN¹Ýžo-¸è£wn9ܬo:æ¨7MºçG>¸Þ¸s.n¨;+¾T擃ÊxîšûmøÒÁç¼Þ‰Ãîzê»óþ¶ó¸ûž¼§ÃŸN½Ü÷Vþ©ÐÚ+ßýìÒ½÷öÅÇŽýñ€o{ñÜCOjïèGž÷øª—¼äË_?5ù ŸóìW¿Áùïùû^ðÂw»åén~¿ƒÿÚF8“±yçk`ü„wAÉ5¯z¶›`5(¿Õ™î~­sßâ:ˆ2ï!ìdI  ÃsÕðZ74Ÿ ]X2 òpcþ9ŒV÷´^̈ðb¿~ØCÙ%°‰>`•ˆ,*‘‰%³¢‘/.fÑ‹EÄâ ÁˆC2VÌŒêÒ"ºÐ¸F1B1lnúñ€ ¤ IH@ʪˆL¤"ÿxÈE:ò‘d##IÉJvË’˜tä«2ÉÉ@n²“ ´ä'CIJCâñ”¨L¥*WÉÊVºò•°Œeɵ/Ùò–¸Ì¥.wÉË^úò—À ¦0‡y?HŠ H¦2—ÉÌf:ó™ÐŒ¦4§IÍjZóšØÌ¦6·ÉÍiŠKY§80€qŠSuÈ–:×É΃$à›å4gâ)Ïc øþÌg®ÞiAs`žô<§=õIЂ¾‰ŸÙª'8멵{ô¡m B Ðk¡m¨FÀQŽFô£(F-šÐq¢Ó¡€°R¤0Õ§Hªº‘žt? :ˆJYÊS—vÔ£1 ê¬fšÑ~õk(…Òƒ òÒ…ÀJ¹SU;UuªV…ˆT©J©v•ª^ýj¦ZÕ± U"D g1zSÕH§ è©\WúT‡pU fÅkW¯:»2įy%k_ùª×Áö°{=+DÒúD¶Ô­5ÈK[:W–Öõ¯ñkT7ËYÌ&V°ŸmaG;ZÍŠV± alôJÚÖä¼f,/þmd[YÊ^v!¦-kV Zܯzê­fw{Ø<¡Ö!D}"k;$¥ d²µµ,TI›ÙÎR÷´ ln…‹í—"É]m?[«Ô"½4ºt.v¹ÛÛõd¸¼í®uá{Ýï6d¦A$Iç–Tò,• Ð¥¬€o‹Û¯Æ÷·Þµ+b¼`‡°Ûµï@ð«HòVÉA’«€åJ`ßþ«cÝ-X‰‹Ù°w¸y1ˆMkb #$­þŒ±…'òÓ×X½‰°‹AŠ_ˆh#ºlŠŽwÑ3d3†è‰üÐ-ÉijšZ¼âà2YN^”¯Ìe`eY_Hf.G¤Üå2gäËÛ²þ™× '4,Ì?î™ÙLçÅÂS¹…Ss÷&7‡MÏ™3ŸíÎ;‹7Ïbþî”2&}’¨:Í刟Ógþ~DÐ ©1Ž:‚ã\=º¼ ™4¢ã̦¶Óé´CT=+9ç­µý/ezÃ>ý)§wmÐOGú¿g6ô“íÊdš!¶S|ÓG/<‹fÈyD”£Í°Ú¿¯†õFd-Z¯ÚØ9/®yšl"ņÙCÊö¥Bε¸AínSÔÛ A7S0îS«×Õó†’c"›žv¿à°¹¶¾õ­{+ ßÒŽÒYfKqÙŠ;ºåÖvB.$¨BúÛ•Rsþp`_û¾ÂÖ2±ÍRr󽬼eÞ ¾{æ·y¼7^r†{Ö‡:©/âóçjãÿy¤Îsÿ6=ç8wzÔÞòŸw;èWz±5>×6æ÷ydÂþîZŸ;ÝcÿµÎCnîz§Ì'‹ÈÃ}ôqƒÝ<®^ιm}\Ùß;8CrÊ4úæqx¥‘ê&;þîA=ùÖ þÅÇÝ!¨n¶-‰,ùÉ+ÝíBW¹Ö ¦ÎÇÔò+r czË ×õ£'½ì+ÿö4§>¥«Ÿ½‹aoiÝûžö¡‡ûí-’y§þÞ¾¼güñ—oõ{cÝù±Ç=™Úä§“úroµá‹þN%ë÷w£¹oˆ¦ådz0›û#ñ¾AMmYòÊã!j“ú=R|…Ôÿ¹¸¶1›ÊŸêžW]¢µ÷f—'÷y%ÒÑ&qKux! ˜oþÇu|¶}Ä~öWw•e€Ò­án˜vá1"±pÿ—~øgÃ,^—IGplƒj·€øt#w‚"1r¶zWq>ˆ^ `€s7‚·sWm5Øv2‡~!¡ƒùÔ‚s%„kWs2E8#ê6ƒ9˜‚”6€È†Ç„R8uLg6Hƒ47…D˜„MÈ…£Ö{ú…†c ¸†ÌA‚åq‡(ugh†ljn|×·ƒÓ÷…bØiþ}çwÔÆUÒlQÂÛ§„jâ„øôx6Æn¢‰'§‰a‰àWˆÒ–K剬扟ˆY‡Ø·i\ŠqtGg‘x\°ØŠ¸˜·(}!‹¹ØN»ø‹ÂØÁX¾˜aÃXdª}¬˜ŒÎXŒ`øÇ茶Ô(yÇw^¶Œ·‚шyÒ¨k¡w8%C&ðÇ„òÇ‹7ˆq8`,—‡vˆ†¥qi'ÖØ‹^‚aL•ã'‰ƒZh~9l’Øx‚H‡'FØ€…7u¹& ÓÈtæ¥ÆWp5‘+ò$7‘•ÈŽ^ØìFwý&]Ÿ· #Y‹gþ’”hi’Þ(ŠøZ>؃‡Ø’TèkxxÙ‡ˆç& yl+éR Y…˜o8”|¸Ž(€7©f—’pÕ“C)‚88…29“Sy6iè¨/×oyv;×yxˆ…j‡ŠÛV–ÍŠ«vŽûÆ•r—ˆ|7’“©€_I•«(|f™+˜xc.•ÕH—ÊGˆX9Џ´c§¸U©‚‡yËw”àˆ“¥¸y³Ç™šIz¢ù…ž9šìTš¨¹gª™§¹šÃÒš°¹f²9‹‘9›Xæ˜îˆ› I$ð+µ W¯nâ8äxaÕ—®hlêH–—Ù…W9+ìçRñ¸nôxTR$þ1˜ÎY˜X—±¸µ8–õöeG’¡N'— §›ß·&Ü·>Y†x¾x"Ùžùœoø˜c¦öérz©†”%È–A2 cY“þ)ˆñ©&I©’0×”÷’~I† :o7âžÍ×Ö™·ù— ؃´µ’kƒZ‚Byžé‰ŸF Ÿq2¡pµ”) ubiœŒ‰w/ÙŸÞi•"é‡V Ú–ÕÙ 0ÊŸC%£p2Ÿiùu’Eé–^é“è¡‰ç¤ •9U¤(úoüø€€ine𣏤„ÉŒ† žë”˜?¥¥Ú·¡Mú …¹›v)¤w9™‹Iy>Ê¦ß  ¼¹™þ\ ÃIP­š…:¨ÇœÈ8¢Œ œ‹©ºç¨ûv¨”zP“𩤹©ª‡©œÚ€ ¤nª™*•ø” ¢¢WªªVœ,JxæÁ£` ¨Ê rº…vʦxÚNÓ9K¨ oy‡jÚrY¨¤’Ú«¬*¨y*™ÇÙQhžç™¬WJ…êIoÚŠO–š¤ñFŸJw­Øoa‰Ê:'ÝÚuú­Éaª¶¿fŸìI§7¨ª­’®ÆI¤ûf£•™†„—¡’g‚öŠ®žÊ‹9Y¢;IqFÚɪ•óš¯ÚÖœËú£˜éªg©•ƯYyŸ ¹­ôJu+'øJq‹« ¦%;¬èù¢XÚþ°E¹O[5(‡=u£z(×é²jˆ±49±£Z±Îžµ¦œêº°“ˆµ*xgG´.ºwhš›ÌÚŽªNpÚQ»š&;šO#+¬êꥉ RýJP#ª§³Æød»¦Í¨¿š¶¯g¶hkšnÛfp;·¯X·Ú™v£Q{’{«X[·; Az|·Ú¢M‹´!K°})¸L%«o¢nË¡ÜY§…ûŸmû¦ð8£õê§ Û³>»¶¤´Ÿº§Ñ `þH¹;-ë¯b‹·½‰Ÿàêµøw H”;ë²W |› ¡——tg´·‡kÇÊu¾;»{¸H‰–û±–›¥ãþh…¤ë¸Á{§Sûªß¦“&z²H§ºHˆ£K¼ç»Nc‹¾[¡]©²ÿõ›¢;ºÙ+²´¹;ƒgw/H¿ã:åÚ¼2u¿Ñ;³Qê‚Y¾+K¥:˜ÿ›­öû¼+¹¶š¡û»t¸l·A«¸"L»³©Ú¸øHÀrRµõ»¯û$±IÂâGÁÈùÁˆ:¿Üʃ ¸4l|°j›5œŠŒº;Ìd›ÃÂùÃhuÃDÌcF|lBü¨GüëÛÄP»½¾Ú½g»Ä— ÅÈ•ÄËw¦w¹}§šŸžW"àÄyÛ˜çº ±ûar“w¹K#Ol+ÁZ»˼ޚµ°›=–H~«Äe,·þö׺…’jœ£n¹¼ñê¯ÆÇûQ·«l‚YŽÕ¦»«ËÆ_±ul®yc1ÆPlÅ.—ü‘¼t”ȄΖ­ L”¾ËÉ|T«X4ëoõ)»4çq¨:“¬ÈðôÊþÔÇ:Œ¿ú¾<‰²Ré»_:•ýÛ´»¯®ìËÀü„…SšÇ/«Ì¹Œ½±ë̽ìË&ÕÈz«§¢Ü®¶UÍš¼Ì܉ˆˆì±ö̯Í—8ÍsØÅWk·jÊðv®œË¸ îÜÉð|ÅâüÇjÌ$:Éc °–Ì\œ´…ì´ÆöÏ2ÎeÂ6ËgQ)Ñ¿LÑ€,̽—_ ´HyíÉ>Œ¸¨YþÒß ½áìÑ.#—L~ 9ÂFåÍjÅÑXRÝlÓûuÒULЮ™Ó ¡Ò°LÅB-TD}Ó,mÆ@íÇG­‹;mÓýÔQLQ<­ÔŸÜÔÁ,T­IÝÓ±| =Š^¬¸G{½k<ÆQíÍSݵZ=ÄȆƼ–ɵ‘¹JèÆKËs_ÝÖž[³t,öüÐx<ƒc±×8ÔýÒ:%È@µžÞjÇh ÁUj#†½Ôõȧ܀›mÇ1ºù›„þ¼ÖÐ|ØN­ØLÆ›Öñw¼_™ÊçºÊO[¥•Õ05Ë,yÌ]ϳ­ž²ƒV2Ú5-Õ¦½Õ-ÍÕÄüƒm þšÌ/‹ÎGªÂÁþ]Û>-T¸Í”µœÈ‹{¬ê\¿“½qÔÖ. ר—Ë-‘,Ò ÚÝ’Ü”MÚï\ÜÒ<½dÍÛhgÏW¬9ØZ(Ü%ÅÓ|M²oÍÄaxÞ<Ç—žÙ#­c-Æ‘-ÉÞFTmÎu–Ñð ÐòMà\-ÄA–ÍlÖ¯.Œ(|e#NãÍáGñÙO:Ót;Ül½á]½Â0^Ú–Ã.Ð3N'¾ãÕ—á}ãˆ]Þ8îãä-äFNãÿMÜJnÜ©MäTÝã¸Ùà¬y gÖ٣Ĉä&-Þ ìÖ‰mrMÈ€]×"¬¯¡Í³¬Aå.6Ç!qÈ[~Çm®…íå+mÛR~ÚþîTŒÍµ âlüà× Ùååæö…Ù¾É/ÌÙ‚Çå4ÂâÖ¬Þ‡ŽçE=¼ant†hà‹nß l„°]èþ+è7çßV}Õ΂ò\³æœÞžÎÝ¡]®„èB›ã.—Ü':¾º¯ÎËÛ­Ët͇¦>R1þäóí¾»ž¾lÝ1ìGë©;æÇ½•œŽ¬»Í»ÉÞú\êÜ\ãñmìñLßÙ÷꘎ù-®8Çß­léX]Ý™.àÒ¦º~Ѓ—àù¹ˆgå!L½½ÞåÞ®áà¬&lá# Ðn°{åXÃÞM™$Íî`=á³Wâ@ ñèðžð©&é›èâšúïA®çK>à Ÿþä"?íQÞç#ð#ßd/ã¡lëb¾ä,ßòUó)®ã*Oó/ðº§ï ?´@orÚ8Ô=ò)òMæƒ|„>êØŽ¾êˆóÖý¹\ç½Ýðù}ËF_ò_.ññ¾ôJϺÓZæX¥vÍ»¤TSŠnxŒ~„µø®ûξƒÕ^Ÿçî.óš®Õ£ì®ôÜÚøý”ïj²s®ÝzßäÅŽô—½ê´ü¾×¿¤è¬<ùÑöa_ä‘‹ëâË¿-)¿rÏ¿Žö‰¯ìG¾÷—Nd×}Ñ¢Ïìël×ìü•š¯ñ*žôòú’¯ø–¿í±Ÿ÷Ø–ZGß÷· ù¹ÍÌÖ‹³Æ:°úöýþ,üªßî`î÷¿óÅ[íœ ®Ð‡—åZަ~9]µïÈÿ{üùÃ?ý›?äÖï/{aëÕéö6ŸšóéÔñ‘÷þ0ý_ÿÑ@à@‚ D˜PáB„  €8`ÀŠ-^€ =ð¤È‚!IžD™RåJ–-:Ô(ñâL‹!rt™SçNž=}þ\ 3âDš4mnìèÓ$Ê¥'›…UjO¡dyçT®]½~›°êU¬5ÞLÚó©ÈµÛ†…÷çX¢e+jM+W/W}äôXdà¾+ÿ,|ððBºvÍjܪVå[†”A ÀlYçⓜ zþö¬0tÊÐ…G 9ýºÐ¶“.Zk¥³iŸÞ¯–Õf™m"mvi¯y{SnºXï{wnÔV'GûoË\kÂ1e8< =|qÕ?òq¾GºÜòÌÝ\tC_GüÓÐ]ÈäkW2{ÉÊ_Í ·øÄe¯’ä›ÃÎÙôÓ™õ›÷À}¿[t?‘6^@¸»Nºz¼™.©EÃ]ÔùÞ;]R]©¾:ø…Ð'žó¬¯=ïîí[êUþèë.’ôD÷¾OÏ6#­÷éïh±;Þ|þþ§<6P]¶îè@ 0^ )¸ÁleÿEÈ8ù-Ð{#Dá°¥öbaKeÚ’†0^3}ZMqÊK}¶®B:œ µ±$n ŸMdß«pyJ¸ÕNk Ü-UÎìŧu”‹SoúÎúŒD-å0·ˆÕžìÑšqÑêOÌê¬Ê@Oi³œ¥B#9G@qŸ½#"UZþQfºÎ™Î çþþh¼s’sxã”*_Ú¯½v¥—ùùfêK7%F쇚«¦Ü´žm•ãi%Æh$Oþ ÖC°b(]ƒ·Yt¶¬oõå3ƒYʯÒ0Å^:ѺXƒå¤}½æ_9Y-Š•¬ƒË¬×X›×Í”ž|&q§WKÝΩ|2îu×ÅÛ“5–¥ô%iåÊФ&uk—U®Ã–Ë\îÞnW]ÕzQ…[T5W! ]ßBSË7‡R«½ÛÜi€I¸N<ÆT•Bm¨Ej_›”Áµiƒø_ïJ¸Áî[„-<. o8¢æ#‚=lP û¶ÁûÕ‹e×J®øŒA­ X÷"_þ(ó¸siq;ª:^ÙisWhŽoø[çG²mü “[Õ¥Ä^‰Ú`Œ:µ}‚6}K$/•Q¼>ÚVÇyÕf…‹°Êìn¸n]â4 2&еÍK£’Á¦Àë˜XЧç|$Ç8š2®^®ä5å¼=ä9ÎÅîl”+EkfÀMö¨L¦ä$!fÔ&×Ѷ,ó?M<,ð„ôài­]¦^¼ÛŠÏ–ß±ˆf7ÃQØŒô¹á •ÝdãþUéªö:_5Î<¸7¬žY§v›«,ž'=½(F|âÍ S;sÜ™É}o¨Soxãœ:W½Ó ¤ßà_ø*Ç æ!N|²}«)´=Â>ýÓYŸÌÜ×¥ôÁï`ñ7½íãÇæîKrôÓÐûžm¿bÕßÛÔÇŸf¯/|ñ¹>òú#Ü›n‘¹ž›²KÙ6¾\Ó º8 1C“Ë¢ª+®Éã&È=ý›÷b¼¡ƒ'‰¹æ¨›Î›;¯Ø#ËÛ­-9 @A{\‹2Úš$|§Ò˻ѓ?œIA” \½8™µÆ,·R“à ¬Ì¢¸Õ²Áˆ›“ÄAô!²ë°óµ²›–ì£þ@þ‰À»‹¾¼a«àA僫 -Êi=»1-A-˜)ABS ›€Ä@ü¾uë*Ösü¾Ò…€s’[ÀAg´»¤ç ´ÖLoÚ)W ¹v’Ö U*’©P¨ÜÛ´T @ïÚù‘ÇûWÿ:vǼîÄ;¯ì®a¯¥f ôÖâ´YmK ¹¯GwoúœS»YÌonvüÞ(ÐRûaœ0/ÆE „¤@J$”@†Hɨ‰¼mB4„lhH)¨``WhdddeH:gŒÔgšïhIIkF oL7pHrNrY2z­¯z¹i{¤ä~·¼ƒÌƒ„r²Œ‘šŒ“™™«ê”“˜•‰Ï•¬–˜—ŽÖ˜¢Å™™™™™¹šlÑœ¥Ëžd½ž°®Ÿ­¯ ¥È ³ ¡œ¬¡µß¤„Ú¥šÄ§™¯¨…ܨ稩²¨­·¬aÌ­¤Ü²z³„³Æê³Í÷¶£”¼—ܽ r½Ö׽ܴ¿ÛÞÀ|ÁÁ®ÑÁ²†ÁæÁÂ¹ÙÆÕõÈÈÈÊuʧjÌÑâϲÞÐ’’Д?ÐÒäÐÚïÒÍâ׌AÙ½áÛÑÊÞ™nÞйà×èàÙÃá=ä8ä²däääåȺåÓµèÉÉèÊŸëÆ ðìáòòòôåÏÿÿÿ]óñ ÿÿ¿¿5Zss@¬„|ôMuÿ¿ð óÿ¿èÇÔ ôXòÿ ÿ¿@¿nXaêFg@¨X0ôFs¬„Xô÷ÿÿ¿¿ð õÿ¿X›F|;pm„ðÄNÔXX÷ ÿ@¿úX÷ÿR|ôÿ¿)qHOpÿ¿#hXó÷ÿÿ¿¿|oüÂ@@>äÐèOóNÿ¿ pÔÐXóÿ¿ÀËtóùWXqvF@@,ÂÒþc¼H° Á7ŒÞYÈáÁ‡[xi!q¢D3ªÙÈ‘cFˆ;~I²ä›"MšÄh2a×* J¤èÅ¢–*QzŒ©SMÌŸ&{úú'I—/­X³éM Bö$JäÔªX"MJ„(Œ¯`ÁÊSgÖ³dÏRÝštìU©oƒšU[5-Ý‚ŠéÝËW/£An Ü·°áA~+V|¸±ÞņÌX²åËŽ)WÆÌWÉAGrí 5nNÓ$Qß•;(葯?²…YºuYÛ%U¯N­û³ï‘³ºÅÍ%\ã»#wý[¶h®DÉHŸ>}øòâ)“Ÿ&n2vFïƒþ+ýI½¼õʳkÏÝ6Ä*ð«Ü‰O¿>£*£‰ÔßÏ¿Š–ÿØß€ð9e üØ‚ 6ˆ ‚ :Xß|RHà}ùIH_€j„5y¢‡$2¢%ÊÇ …b8Z‰Xâ‰"B˜âûÑX"‹ýñÈŸ‹\Áã3ލ¡‘8&©#‰>îפ}ø½HâD’¸¤ƒH&yã•>IŸ—ñ™”Ciã‘gj¹e–]®È ˜/‘£™ ÖX§šk¦é!˜ðñYœ ÉÙ¡•lš¨'žvÞɤ›Ê 2z¨¡Š"šè;öWx%´ZyÔ§{×­7’]1qzªyz¨þÕÕV*o³šjw%±ºihŸÂJ†¨;m‡ž­´Öšks¹J—¯¿Ê:¬°£ûª*éJµZíÆlA?tëí·àB!î¸ãv[R·ä’ îºßþÄî»éªûî¼Ý²ñî®Àië+·ô~o¹?œûÿPôÛnL{KpÁ ¯k/»ø:×+¬ü.ðÁŰ€ûPÂÇ ƒl.I݆rÇ[œñÅ#«ä­Ê+£lòÉܱÅpq7ÀqÄÉêK1AÝ^Œ²>ûÌq N4ítÓ LòL?Ý´ÒݱÏQ»[4ÖH‡½´ÕNc­õÖbû€3h+ tx»Q©}Y§­4ÖTýqþÓ%t=5Ó{;ñ1ØI×vƒüþP¸Øxó­w fÛm¸ÚH³ÍøÏ×òz—Üt_9Çy;ηß#•,øã„g9âD­:Ú ‹~úç‹§½±QHîÃÛÆMeçXß>yÕd“þ‘éd§N9Ú¬ä­Ò§M¼ÕŸ/?ùíhDïvæù®Æy|†×ŽõôOŸòÔ£|÷ê &¾>ì“}5ìâ×ÌqîŸó~²j}_Ý´ëàçóA¤[¡;ÝüÚ>4ï Ï»œô¸È0e•kàî¸'±»\€ ! .<°…m| T ‚@:p©óY}0à‚Úî‹¡)X5³™°vþkc X‚-„ì„]HbYЀÏzêC¡üVxô= lÑ{]}jø….~Á_`ÉËŽ†4)&Ï~d<Û8f¹× ‘ƒA[ ™¸Ä$Šñ ÷¸Goå‘|”ZéðÈ>v ,¤ F0~±‹wDd!õèÇIR²[‰ä·þ8Mv‹ˆš£ C¨Ä;6Œ^;å½ âH.B²uªŒå¼¶®Ðá–†¸¥.w©KFÐ!#¼ ¦0é0J$&Ñ–·ƒ2•Ƀe:³™Îd¦3wY^Fs ÐŒf6Ÿ©L^¶Ò‘_@&¸yÍm.ÓœÒ,ç5Çp†uò@œ¹f/ yÚsŽJþ¤£8ÕÉOm.“š±f?ÉéOo>ò û$¨BÏéΆFsè<íyK_“¢Â4f>»P”¡cè@xÑ’ºÓ›à|dGAêÑ–.4ËÜ6¯9QŠZ´ž æ”ÈSˆÓ¤•¦Hß`M ºôŸ»Ä€½è‚•²ô¥3 jT•)Ó©*³¦ö¼éCrÌ ¼à«`ýê> U U d}j7wɸõ­nÕeZaZV‡Ž¡ªVÝe<³JÏ­ru—i¬`»KºªÕ°k½e5 ‹X«ªõ¯Éœ«c T¼NU¯ÕêA «ËÁz–±“ -:Ï ZÑÚ5¤¥ìikZËF³6íþëf9K϶´’5'iuyTÕ&–«¬Ííj™éÚ™ò.˜š5ˆ›™x8/—ØÇDZ‘“m7bûĶóYŒÅ¦ëùòš½¾65°QÅwûÃ"î¶°ÅÍjCÑÛd,ñ·ÕÈÆ(r¬Úï-5¶­í9=‘À;0‚ËݤáÛl6cD¾e­±}ë›Ϙ¾/&ð0e*ƒp¾ß‰zÞ޳½îŽ{ÜÜïøÃþ;&ë£ áC¹ÇG>ò£µñhRˆ¹ì s)´y×ò¦°¯k^ó,øüç?ç¹Ð‡Nô¢ýèCgÒ—Žt¥×ÜéDw:ÔkNó£W=æ7·vÎi¼ó¡ýëL»ØÇ.…©?áSG;Ô•Žð²—½í17;ÏÕ.s©ýêüÍ?}î;±þUØ~ùÏŸ~ôßëü÷ÔçtðÑ~RGy‚~æ§t¾×zÔ—÷‘'ð÷q|›xU@sø€è's[søwq:·h Øèçsà÷sà7}&È‚%È‚0(sÓç‚1ø‚2X‚6ˆƒ4H{:¨v¶7{hw3Xv0hw4‚>(uÓǃ1Çz'Pu5ØOX‚‚×^×6‚…§ƒÓ‡‚@~èw„7ø…aØ‚&X†1†dˆ†(†H†ètkH„m8‡ph†uØJ(s¬'ˆ†U`zv°Uha['e]÷|þ>ç}ÇxRðyÈ~¡'‰‚ˆzñ·yý—ˆê·‰—·¨ths¼WyõG ðA{ðñz˜øhyš¨t£Èx€XgzRp¸(ˆø„•(‚\G‚ÈwU°ˆZЈYð~‘HŠ¢ˆÎ(Š hyý—~íljÃh~˸€Ê(ŠÂ÷'ØàHèÒøƒ¼'‹mwŽÈg‹“(\Ì1÷8ˆWŒY(… È…*˜5è‚úH†9(IC¨ƒ2˜„x„,ˆvo(‡KX„/è%¨v ‘zˆ~PˆƒT7„öXˆƒè^Ü·w5~)ˆ‚*Ps ‚¹’$©’fþù’7Hƒ-Y†l899“2é’=Y†‡7s5‰uч~ÕŒ†Ho–È}Z°àçx07ì×X~Òè~¡hó·‹û‡¬Ç}˜‰`)Ü—•WY~\së׎`‰€Ki•ú'x–Ô7z~—~‰}ó(z‰·xOù}×yÓˆy¿7z ‡˜Í‡x·˜˜ÍWy€ ™x†‰‰Œ©zטkù‡Iz’é™nézËטÜ'sx·—Š–B÷u@Gv²9›´Y›¶)txWs(ór¬Ùk‹ÖqIœÂ)œ&WœÆyœÈ™œÊ¹œÆùrǛ֧u|)’¨FFÃyÌ™Úþ¹ÜÙΙb;Sp'†”!©a†1#0×ù# `‡`ï©_ &Ÿñ¹2ó3õ©pù9qçy3û¹_ žFFh lä…·b꩞™žCCšbÐölÚbâ£b+V;ÌF¡&l>D³†;’† V’$Ú—¨dÁÉ +šH¦bLV?´Æi›6£Jk¯dªVk2jgNÖcIódãy}­™})ú:-Ú I@i‚fiœVf¶öhªÆ¤d¦gï3¥2*¥·&¢`¶1BÚ›g¤Æ1IÚ¢P¤<€¶¥Sz¦„&h{æ¦oj¥y¶¦ijgm cuŠkEv ¤lHš, ¨Kê¤þUŠ¥i«v¨Vi`v¥‰ ¥Yšf‰z?#ʧ¾vde*¨/Z¡1:©¶fA4Š£i#ª0º£¡Ú£öó£7ÊFJ¤¾™ Ç¶ Ãé $&l:¡Z¡Ç¶dº¡î֡Ζ«¢ÈÖnF¦X(¦ç¨úKú«s*¬ëf§ F­ÐJn—FX¤­tv­éÆn0ö«|ÔIQ#5È%[Ê5LÎ#I|DîÊðJ@“ä-ìªH˜dIåJH–TIýú÷êI›ItHkHüZ¯ùª° K®û-ص]»Ô]¥®Ä.ðš±{^Û±û±û.Ù„Wf%L+±Ã4Y`p`Ðþ². Â%U1Û[¦%³ÃU³4ËÅMÐdYÃt²DeO†Õ²,û²`€³ue³J›³7;³IMíÄOÍä³&‹®Þ•²tå²E벾ŴKû´`\M;¶QçDµçzQòDP/»µGÛµa ·bûµsëµvKU¡µLQû[kµ»¶äd´[·H[·„ë´†›¸tUUf{WÙô³~‹²Â¤NF»²-{·Š[¸r»¹šÛ¹FE²ëtW¯Uµj‹µÚT¹–K·œ‹¸«K¶˜ë[–QŒ‹Zi‹SòQn«µ®{¸»›¹¬ë¹ åZвÓÕ;Tñ.›¼ »¼ÌÛ¼ý’^ì±ÆKÈ›¼þë¼Ø›½Ì ½s0ûSÕk½L ½ä[¾ÕŽ?°›(ÓX"ÀyÄÙò;¿ô;¿ßI ëû#7ò¾ðû¬õû¿Àw¿.—¿ûѾ$¿ð+À ÜÀLÀêKrú›" Œ|Áœ¬¬rÀÁ; óU6Ä74_4dC5„ôÂÜÁF`2<ÃV`/ÜÁ.|Ã9üÂ;ŒÃ7 Â?¬= Ä?<ÄBÄFœÄH¼ÄE¼ÄÌÃDìÁ8<_®Ä]F)à^®tÅ_ÅîuÄ7\Ã4<ÃJÜÄf¬ÃLŒÆg ÅkìÃmÅl¬ÆrÌÃOÌÆ.\Ç"¬ÅdÅŽäÅWÐHþ\ÜÅóÇJ Ã1<Æ`<Çn¬È„ÜȉǼȑìÈeÌÈÜÁfÀÄ!ŒÇT|Å&ìE~üM <Èp<Ç<ԜƓ|É©üƬüÊ•¼Ê±,É,F|¶Ó¤K­ôÉ]ÊW Nâ4N,Õ¶/뻽ۺª ¼ÉlN2Õ¸ì”Ë·È|ÜËzÜJ]Ì%¸\kÌË|ÌÊüºß,ºyë¸HÍŽdÅÊ)FØìO•[´àü»òìÍóÜO »NÍü[JÕEèüE~¼ÏKÕT¥uN¨Ë²Ý|ÐñLÏ ÍO±»LÄÛ2oŒ0ÑM`Ñ8à"¾ðj¾ Òƒ¾½HÁ?ƒþ±-Ò,ÝÒÞBÒ/í½­¾*-¾.}Ó!¾Ã3 @E(í2?Ð_#à¬ÃÉžö9`ô¹pþ©ÔþõŸóŸYD`QÔýÙÔL  9# Xír\cÒñÓ&ñ5(#« :ºê«Úl¸šÖŠl¶:ªoÝÖ¼ºÖj#mB„5¹ã>MÓ**¨Jº©wmª@ꩨ:k¥ ×DÖ¡‚­d£ª1z1–³×Ç«8¨êI¥_¦ie©„fœ-§˜iXÚÙëƒf÷CÚÍ1’M½”ýa™zÙ-Ú«FÚªÃÙŸ£‹Ú¤¶­Ùüi§ªy½Ú@á:wóÚ.Úc¤ªØ6ªd…ÜØ€ý©Êþí£B:ª¬ª×^-“-ld½¢f]«ê¡·ª«â­Öà}Öq-¬ÃF×Ī¡Æ*Ü^“EÌZÔþ»bØ­Òú­ÖšßÕš­ýÝ­èÆ­øÝak®¹:®—7“M°îJ;¯ ›°{°Ká—$áþ¯ ‹¯žánᛤG{á%­à¬½.=¾8½âÚ‹¾ú3Ó*Ò2ã4ÎîÑ=¯^5¾ã<þETD`]Ì2äD^äF~äHžäÍu?Jj¡äPåR>åG¾MŽãËBåZ¾å\^å«qå”å]>ædÞåVŽ,&.æe¾ælžäg~ãaþäm>çt¾ätæq”ãu¾çþ{þæäBÃç‚Îæ~þN~ƒžèk^èè=þè®ãwŽæÓ é–Nã’®¬‚œŽHÀé~|À40ê¤^ê£Þ¨žê=¬ðê°ë`´^ë¶~븞뺾ë¼Þë¼.ëÀÞêÂÎêMPìÆ^ìÃÎêÀþê¾NëX ëK¥ÔœcabêÖNªžêÂnOÐíÞþí½þíâ>îä^îæ~îâîçÉNìÇnìíÎíãîëÝ>åíÓ¾uŒpí¦ží¨¾íè~îêðŸî¼^ðåÎîíþîðžìòŽðÝîìÐîEÒ.ÈÔžŠü^êþ¾ê­þðOðOî!ÿñ¯þðÉÎðÈîð$ïíöNîønñúžñ¤¾ñ¿ò6ïíËë7¿óO`òÃŽòMï7ßòãþò¡n2êþ^óë¸^ð‚ïí)ù)PP(zø_O÷¬Þ!Pú¦ú¨Ÿúª¿ú¬ßú®ÿú°¯úíù(ßî¤û©O«?_xPx /ó‰?ûÂ?üÄ_üÆüÈŸü’ŸüÃß³þÏû¾_í¡ŸíÌ_ýÖýدüµŸýÉîüíýFúûüÜ_þæþ¿üæïýÉþóõ½@þò?ÿè¯þåÏþÃîþîÿ?AÿþÿÿDà@‚6A˜¡A† ¶i¸Fâš?kâ\ÁxåÍFŽŒ8~ò Á2%KÖ©cÒ$J•'S¶d ó¥Ê˜4g®¼é²e™š8wöÔiœ•œ¹Ëc§êÙ±‚ö°²….w¸ºN¯¢Ö"]Ó­X¿4ØÄ‘m´¡.MÔÊO¶Jqž]®\¹Âʂ׽6Ñk,ù*Åð$âÀC~ñ0þö—ƒBÄ †0„A BÃú»àA´ÁÁm8Ä!ú0a G˜Â–ð…û`a søÂư†7œá“8Ä6ñ„A¬â¸„€1ŒB XÄ+v±†ÑH©(×#Ú=ÒzµHÉð÷¹aÙ¨p7Ûc¿È‘u®‘ÛÛ±TÉìê1ÿlÃ[ø¶®T³”oBÛïfYË'âí‘lúÚ)‹Y«Ä ¯TÂÓYÉ^õ»a¾òtÃlüÐù³é¼³›Ï:^<ïi"U/RÛ|e¼Æ÷Ê›:tvkj¸¹N6ÐŒ­b;magic-8.0.210/doc/html/graphics/line1.gif0000644000175000001440000000045610751423606016473 0ustar timusersGIF87aR¡à¬`d`øü,Rþ„™‡ ÜcVêlÆJw¾€Óq‘›ù¡¡:6©»ÂmtÊ^L¿9^Úâ=ë킵!ðøK²K¥¯ }JNjÔ:j‹[]—Ç {Ÿ,™8NƒÕèµ» gšÙr¬½+È |¾>ßç÷8ð·hH˜ˆ8Ȩ§ØØ·()øèˆyHyÉ™é¹iù)ZXiÚI ™Š:ÚZ:©ª¹êûJ {j»«ÛËÊûë[+œl<|\Œ¼¬ÜŒû< =-- ÊL}½}kÝ] Î œí=î\N¬¬ý-žŽ¾OÞ^oÎ~/NŸÏÿîà…ø",øð`?†š$:œqaƆ1z¼è°;magic-8.0.210/doc/html/stretch.html0000644000175000001440000000642510751423606015540 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

stretch


Stretch the cursor box and the selection.

Shortcuts:

Key macro M implements the command move (no arguments).
Key macro Shift-Keypad-8 implements the command stretch n 1
Key macro Shift-Keypad-6 implements the command stretch e 1
(and so forth for all 8 compass rose directions).

Usage:

stretch [direction [distance]]

where direction is any valid direction specification in magic, and distance is any valid distance specification.

Summary:

The stretch command moves the current selection from its current position according to the command arguments, and fills in behind with material such that electrical connections are maintained across the area in between the original and final positions.

Without arguments, the lower-left hand corner of the selection is moved to the current cursor position (the X11 cursor, not the magic "cursor box"). With arguments direction and distance, the selection is moved relative to the original in the indicated direction by the indicated amount. The default distance is 1 unit (usually lambda; see distance for further explication).

The stretching algorithm fills in with the material that crosses or touches the cursor box in the opposite direction to the direction being stretched. If two different materials are on opposite sides of this boundary, the effect depends on the material types. Contact types will not be stretched unless the contact material is on both sides of the cursor box boundary. If two different contact types are on opposite sides of the boundary, then the material that electrically connects those two contacts (if any) will be filled in the stretch area.

Implementation Notes:

stretch is implemented as a built-in magic command.

See Also:

direction
distance

Return to command index

Last updated: October 16, 2004 at 2:00pm

magic-8.0.210/doc/html/windowscrollbars.html0000644000175000001440000000320610751423606017454 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

windowscrollbars


Toggle scroll bars for new windows

Usage:

windowscrollbars [on|off]

Summary:

The windowscrollbars command turns the drawing of the window scrollbars on or off. Normally, this will be on in the non-GUI version of magic, and off in the GUI version, where the scrollbars are handled by the Tk frame window and the GUI "wrapper" script.

Note that the command does not affect the current layout windows, but takes effect for all windows created after the command has been called.

Implementation Notes:

windowscrollbars is implemented as a built-in window command in magic.

Return to command index

Last updated: October 9, 2004 at 2:22am

magic-8.0.210/doc/html/initialize.html0000644000175000001440000000361210751423606016220 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

initialize


Initialization of magic from the Tcl interpreter.

Usage:

initialize [arguments]

where arguments is the list of arguments passed to magic on the UNIX command-line.

Summary:

The initialize command is part of the procedure for starting magic from inside the Tcl interpreter. It is not a user command. Other Tcl-based packages that wish to use magic directly should follow this procedure:
  • Load the tclmagic.so object file.
  • Call initialize with arguments passed to magic on the command line.
  • Call startup

Implementation Notes:

initialize is implemented as a built-in command in magic, but only in the Tcl version.

See Also:

startup

Return to command index

Last updated: October 8, 2004 at 7:59am

magic-8.0.210/doc/html/extresist.html0000644000175000001440000001064010751423606016110 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

extresist


Patch the extraction .ext files with detailed route resistance information.

Usage:

extresist option

where option may be one of the following:
tolerance value
Set the ratio between resistor and transistor tolerance for determining when to insert resistance into a network route.
all
Extract all the nets.
simplify [on|off]
Turn on/off simplification of resistor nets.
extout [on|off]
Turn on/off writing of the .res.ext file.
lumped [on|off]
Turn on/off writing of updated lumped resistances.
silent [on|off]
Turn off/on printing of net statistics.
skip mask
Don't extract types indicated in the comma-separated list mask
box type
Extract the signal under the cursor box on layer type
cell cellname
Extract the network for the cell named cellname
geometry
Extract network geometry and present as a collection of line elements on the layout.
fasthenry [freq]
Extract subcircuit network geometry into a fasthenry-format .fh file. If freq is specified, the file will be customized for fasthenry analysis at the indicated frequency (in Hz).
help
Print help information

Summary:

The normal flow through layout extraction into a simulation file treats routes as nonphysical entities, that is, with infinitesimal impedence through the wires. Extraction for digital simulation using irsim generates "lumped resistances", a single resistance per network node that, along with the node capacitance to substrate, provides an RC time constant to approximately model the delay from point to point in the network node. The lumped resistance model is inappropriate for analog (i.e., SPICE) simulation, and for digital simulation, is a poor approximation for branching networks, where the delay between endpoints is different for each pair of endpoints in the network node.

The extresist command provides a method for generating a more detailed model of resistance, in which long network routes and branching routes are replaced with resistor devices and device networks.

Using extresist is a multi-step process. It is first necessary to run both extract and ext2sim to get the initial netlist (with lumped, not detailed, resistances). After a .sim file has been generated, the extresist all command may be run. The output is a file .res.ext for each cell in the hierarchy. Finally, with the option extresist on set, ext2sim or ext2spice will generate the final, detailed simulation file.

More details on using extresist can be found in magic Tutorial number 8.

Implementation Notes:

extresist is implemented as a built-in command in magic.

See Also:

extract
ext2sim

Return to command index

Last updated: October 21, 2004 at 10:48am

magic-8.0.210/doc/html/save.html0000644000175000001440000000345110751423606015016 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

save


Save edit cell on disk

Usage:

save [filename]

where filename is a new name for the cell as well as the root name of the .mag file to be saved.

Summary:

The save command saves the current edit cell to disk. If filename is specified, then the layout will be saved to "filename.mag", and the current edit cell will be renamed to filename.

The save command differs from writeall in several ways: save does not descend the hierarchy, and does not prompt the user for an action.

Implementation Notes:

save is implemented as a built-in command in magic.

See Also:

writeall

Return to command index

Last updated: October 8, 2004 at 2:05am

magic-8.0.210/doc/html/fill.html0000644000175000001440000000402610751423606015005 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

fill


Fill layers from one side of box to other.

Usage:

fill direction [layers]

where direction is any valid Manhattan direction in magic, and layers is an optional comma-separated list of layers to restrict the operation of the fill command.

Summary:

The fill command extends paint from one side of the cursor box to the other. It is most often used to fill gaps in wire routes or fill paint between subcells. The algorithm is to select all paint that touches or crosses the cursor box on the side opposite the indicated direction, and extend this paint in the indicated direction to the other side of the cursor box. Paint that is in the cursor box but does not touch the side of entry is not changed.

Implementation Notes:

fill is implemented as a built-in command in magic.

See Also:

corner

Return to command index

Last updated: October 6, 2004 at 1:42am

magic-8.0.210/doc/html/plow.html0000644000175000001440000000550510751423606015043 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

plow


Layout stretching and compaction

Usage:

plow option

where option may be one of the following:
direction
Where direction may be any valid Manhattan direction, and causes the plow to be moved in that direction.
boundary
Set boundary around area plowing may affect
help
Print help information
horizon n
Set the horizon for jog introduction to n lambda units.
jogs
Reenable jog insertion (set horizon to 0)
selection [direction [distance]]
Plow the selection in the indicated direction for the indicated distance.
straighten
Automatically straighten jogs after each plow
noboundary
Remove boundary around area plowing may affect
nojogs
Disable jog insertion (infinite jog horizon)
nostraighten
Don't automatically straighten jogs after each plow

Summary:

The plow command implements a sophisticated method of stretching and compacting layout. The cursor box can be used to shove layout in one direction or another, preserving net connectivity through the modifications.

Results of plow are usually messier than most VLSI designers care to cope with. The best cell compaction is realized with careful floorplanning considerations, not brute force pushing and shoving.

Implementation Notes:

plow is implemented as a built-in command in magic.

See Also:

straighten

Return to command index

Last updated: October 8, 2004 at 8:32pm

magic-8.0.210/doc/html/template.html0000644000175000001440000000306410751423606015673 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

command_name


Short summary.

Shortcuts:

Key macro k implements the command command_name option.

Usage:

command_name option

where option may be one of the following:
option_1

Summary:

The command_name command is. . .

Implementation Notes:

command_name is implemented as a built-in command in magic.

See Also:

other_command

Return to command index

Last updated: October 6, 2004 at 12:21am

magic-8.0.210/doc/html/flush.html0000644000175000001440000000350510751423606015201 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

flush


Forget changes to the edit cell (or to the indicated cell) since the last saved version.

Usage:

flush [cellname]

where cellname is the name of a cell definition to be flushed.

Summary:

The flush command reverts a cell definition to the last version saved to disk, forgetting all changes made in the interim. Without arguments, the current edit cell is flushed. Otherwise, the named cell is flushed.

The effects of the flush command are irrevocable; the command cannot be undone with an undo command.

Implementation Notes:

flush is implemented as a built-in command in magic. However, it conflicts with the Tcl flush command that flushes an output pipe. Special processing determines which use is intended.

Return to command index

Last updated: October 6, 2004 at 2:06am

magic-8.0.210/doc/html/splitpaint.html0000644000175000001440000000466610751423606016260 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

splitpaint


Paint into the cursor box, splitting the box diagonally with one layer forming a right triangle in one corner and space or another layer in the other.

Usage:

splitpaint dir layer [layer2]

where dir is a valid non-Manhattan direction indicating the direction of the right angle corner of the right triangle to be painted. This triangle is painted with layer type layer. If specified, the opposite triangle is painted with layer type layer2; otherwise, it is unpainted.

Summary:

The splitpaint command implements a form of non-Manhattan geometry that conforms to the corner-stitched tile database format used by magic for painting and searching operations in a plane. It lets a rectangular area, as defined by the position of the cursor box, be split diagonally, with one half containing one layer type, and the other half containing another.

Note that splitpaint is somewhat cumbersome to use; to generate diagonal wires, use the wire segment command, which is also able to compute mitred joints between segments at different angles.

Implementation Notes:

splitpaint is implemented as a built-in command in magic.

See Also:

spliterase
wire

Return to command index

Last updated: October 8, 2004 at 7:38am

magic-8.0.210/doc/html/wind3d/0000755000175000001440000000000011504623573014361 5ustar timusersmagic-8.0.210/doc/html/wind3d/defaults.html0000644000175000001440000000436510751423606017064 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

defaults


Revert to default view scale and position.

Shortcuts:

Key macro space implements the command defaults.

Usage:

defaults

Summary:

The defaults command reverts the scale and angle settings of the view to the default values. The default scale fits the layout to the size of the 3D viewing window. The default rotation is a view from directly above the layout, which matches the view in the layout window.

Implementation Notes:

defaults is implemented as a built-in wind3d window command in magic. It can only be invoked from a window created with the specialopen wind3d command, or the render procedure. Note that the wind3d window is only available when magic is compiled with the OpenGL graphics option and invoked with magic -d OGL.

Note that macros of the wind3d window are hard-coded, and cannot be changed with the macro, gmacro, or imacro commands. There is no ":" macro for entering commands; to enter commands from the command-line, use the tk_path_name command. The default Tk path name of the wind3d window is ".magic3d".

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wind3d/cutbox.html0000644000175000001440000000507310751423606016556 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

cutbox


Set a clipping rectangle for the 3D view.

Usage:

cutbox [none|box|llx lly urx ury]

where llx lly urx ury are points of a rectangle in the coordinate system of magic.

Summary:

The cutbox command generates a clipping rectangle on the layout. This is used for two purposes: Limiting the amount of output to generate for a large layout, and to create vertical or orthogonal cross-sections of a layout.

cutbox none removes any existing cutbox. cutbox box creates a cutbox equal to the cursor box boundary. Otherwise, cutbox is followed by two coordinate pairs representing the cutbox lower-left and upper-right corners, in magic (not CIF/GDS) units.

Implementation Notes:

cutbox is implemented as a built-in wind3d window command in magic. It can only be invoked from a window created with the specialopen wind3d command, or the render procedure. Note that the wind3d window is only available when magic is compiled with the OpenGL graphics option and invoked with magic -d OGL.

Note that macros of the wind3d window are hard-coded, and cannot be changed with the macro, gmacro, or imacro commands. There is no ":" macro for entering commands; to enter commands from the command-line, use the tk_path_name command. The default Tk path name of the wind3d window is ".magic3d".

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wind3d/cif.html0000644000175000001440000000574610751423606016022 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

cif


Switch to/from CIF layers display

Shortcuts:

Key macro C implements the command cif.

Usage:

cif

Summary:

The cif command toggles between the view of the layout as CIF (equivalently, GDS) layers, and the magic database layers. The view of CIF/GDS layers is default, because the representation of contacts is much clearer in the CIF/GDS view.

To view CIF/GDS layers in the 3D rendering window, it is necessary to have rendering information in the technology file for each CIF/GDS layer, presented in the cifoutput section with the render keyword. This information includes the style with which to render the layer, and height and thickness information for each layer. Note that this height and thickness is currently used only for rendering purposes, and so values are effectively arbitrary. Height and thickness values corresponding to the magic database layers can be provided in the extract section of the technology file, and is used for three-dimensional geometry extraction as well as the 3D window viewing of the magic database layers.

Implementation Notes:

cif is implemented as a built-in wind3d window command in magic. It can only be invoked from a window created with the specialopen wind3d command, or the render procedure. Note that the wind3d window is only available when magic is compiled with the OpenGL graphics option and invoked with magic -d OGL.

Note that macros of the wind3d window are hard-coded, and cannot be changed with the macro, gmacro, or imacro commands. There is no ":" macro for entering commands; to enter commands from the command-line, use the tk_path_name command. The default Tk path name of the wind3d window is ".magic3d".

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wind3d/closewindow.html0000644000175000001440000000432610751423606017607 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

closewindow


Close the 3D display

Usage:

closewindow

Summary:

The closewindow command closes the 3D display window. Note that the syntax of closewindow is different for the 3D display window than for other windows, which use the default window client closewindow command.

Implementation Notes:

closewindow is implemented as a built-in wind3d window command in magic. It overrides the default window client closewindow command. Note that the wind3d window is only available when magic is compiled with the OpenGL graphics option and invoked with magic -d OGL.

Note that macros of the wind3d window are hard-coded, and cannot be changed with the macro, gmacro, or imacro commands. There is no ":" macro for entering commands; to enter commands from the command-line, use the tk_path_name command. The default Tk path name of the wind3d window is ".magic3d". When invoked with the Tcl procedure render, the default window name is ".render.magic".

See Also:

closewindow

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wind3d/render.html0000644000175000001440000000561510751423606016533 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

render


Specify properties of CIF layer rendering
render name [height thick [style]]

Usage:

render name [height thick [style]]

where name is the CIF name of a CIF or GDS layer, height and thick are values for the height above substrate of the layer bottom, and the total layer thickness, and style is a known display style from the .dstyle file.

Summary:

The render command can be used to replace or complement the render lines in the cifoutput section of a magic technology file. These lines specify, for each CIF/GDS layer to be drawn, a height and thickness value, and a style to use when drawing the layer.

Note that normally, magic styles are used to draw internal tile types, not CIF/GDS layers. Thus, each of these layers must be mapped to a style before magic can draw them. Without specification, the style defaults to zero (actual output dependent on the contents of the .dstyle file), and height and thickness also default to zero.

Implementation Notes:

render is implemented as a built-in wind3d window command in magic. It can only be invoked from a window created with the specialopen wind3d command, or the render procedure. Note that the wind3d window is only available when magic is compiled with the OpenGL graphics option and invoked with magic -d OGL.

Note that macros of the wind3d window are hard-coded, and cannot be changed with the macro, gmacro, or imacro commands. There is no ":" macro for entering commands; to enter commands from the command-line, use the tk_path_name command. The default Tk path name of the wind3d window is ".magic3d".

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wind3d/view.html0000644000175000001440000000516710751423606016230 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

view


Specify the 3D viewpoint angle

Shortcuts:

Keys 1,2 [7,8] implement x-axis coarse [fine] rotation.
Keys 3,4 [9,0] implement y-axis coarse [fine] rotation.
Keys 5,6 [-,=] implement z-axis coarse [fine] rotation.

Usage:

view [x y z]

where x, y, and z are rotations (in degrees) about each of the indicated axes.

Summary:

The view command sets the viewing angle of the 3D rendering window with respect to each of the primary axes.

Implementation Notes:

view is implemented as a built-in wind3d window command in magic. It overrides the default window client view command. Note that the wind3d window is only available when magic is compiled with the OpenGL graphics option and invoked with magic -d OGL.

Note that macros of the wind3d window are hard-coded, and cannot be changed with the macro, gmacro, or imacro commands. There is no ":" macro for entering commands; to enter commands from the command-line, use the tk_path_name command. The default Tk path name of the wind3d window is ".magic3d".

Without arguments, the view command returns the current viewing angle in degrees for each of the three axes.

See Also:

scroll
zoom

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wind3d/scroll.html0000644000175000001440000000512410751423606016545 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

scroll


Specify the 3D viewpoint position
scroll [x y z]

Shortcuts:

The arrow keys implement different aspects of the scroll command, panning in the x and y directions relative to the normal layout view.

Usage:

scroll [x y z]

where x, y, and z represent the viewpoint position in each of the axes.

Summary:

The scroll command sets the 3D viewpoint position on each of the axes, where the x and y origins are equal to the layout origin, and the z origin is on the substrate. Without arguments, returns the current viewpoint position in the three axes.

Implementation Notes:

scroll is implemented as a built-in wind3d window command in magic. It overrides the default window client scroll command. Note that the wind3d window is only available when magic is compiled with the OpenGL graphics option and invoked with magic -d OGL.

Note that macros of the wind3d window are hard-coded, and cannot be changed with the macro, gmacro, or imacro commands. There is no ":" macro for entering commands; to enter commands from the command-line, use the tk_path_name command. The default Tk path name of the wind3d window is ".magic3d".

See Also:

view
zoom

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wind3d/help.html0000644000175000001440000000446310751423606016204 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

help


Print the command list and usage for all of the 3D viewing window commands.

Shortcuts:

Key macros ? and h implement the command help.

Usage:

help

Summary:

The help command prints the command list for commands known to the wind3d window, along with a line of text summarizing the command usage. It is separate from the help procedure for magic as invoked from the console (terminal). It does not, for instance, accept a "pattern" argument.

Implementation Notes:

help is implemented as a built-in wind3d window command in magic. It can only be invoked from a window created with the specialopen wind3d command, or the render procedure. Note that the wind3d window is only available when magic is compiled with the OpenGL graphics option and invoked with magic -d OGL.

Note that macros of the wind3d window are hard-coded, and cannot be changed with the macro, gmacro, or imacro commands. There is no ":" macro for entering commands; to enter commands from the command-line, use the tk_path_name command. The default Tk path name of the wind3d window is ".magic3d".

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wind3d/see.html0000644000175000001440000000473610751423606016033 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

see


View or hide layers from the 3D view

Usage:

see [no] layer

where layer is a magic layer type if the current view is of magic layers, and is a CIF layer name if the view is of CIF/GDS layers.

Summary:

The see command is similar to the see command in the layout window. It adds or subtracts layers from what is viewed in the 3D window. By default, all layers are displayed. The "see layer" command causes layers to be displayed, while "see no layer" causes them to be hidden.

Implementation Notes:

see is implemented as a built-in wind3d window command in magic. It can only be invoked from a window created with the specialopen wind3d command, or the render procedure. Note that the wind3d window is only available when magic is compiled with the OpenGL graphics option and invoked with magic -d OGL.

Note that macros of the wind3d window are hard-coded, and cannot be changed with the macro, gmacro, or imacro commands. There is no ":" macro for entering commands; to enter commands from the command-line, use the tk_path_name command. The default Tk path name of the wind3d window is ".magic3d".

See Also:

cif

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wind3d/refresh.html0000644000175000001440000000431210751423606016703 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

refresh


Refresh the 3D display

Usage:

refresh

Summary:

The refresh command clears and redraws the 3D window display. The 3D display does not maintain areas requiring updates like the layout window (this is very difficult to do in 3 dimensions), so updating the view to reflect changes made to the layout often requires a manual refresh. However, all commands that change any aspect of the 3D display will also cause a refresh.

Implementation Notes:

refresh is implemented as a built-in wind3d window command in magic. It can only be invoked from a window created with the specialopen wind3d command, or the render procedure. Note that the wind3d window is only available when magic is compiled with the OpenGL graphics option and invoked with magic -d OGL.

Note that macros of the wind3d window are hard-coded, and cannot be changed with the macro, gmacro, or imacro commands. There is no ":" macro for entering commands; to enter commands from the command-line, use the tk_path_name command. The default Tk path name of the wind3d window is ".magic3d".

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wind3d/level.html0000644000175000001440000000513510751423606016360 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

level


Set the rendering level

Shortcuts:

Key macro L raises the rendering level by 1.
Key macro l lowers the rendering level by 1.

Usage:

level [n]

where n is a non-zero, positive integer.

Summary:

The level command sets the rendering level to n, if given, or else returns the current rendering level. There are two rendering levels in this implementation. Rendering level 1 (one) uses OpenGL line and polygon antialiasing. Rendering level 0 (zero) does not use antialiasing, so yields a coarser but faster rendering. The wish-list for the future includes higher rendering levels to represent rounded edges on wells and diffusion, and a more accurate vertical profile.

Implementation Notes:

level is implemented as a built-in wind3d window command in magic. It can only be invoked from a window created with the specialopen wind3d command, or the render procedure. Note that the wind3d window is only available when magic is compiled with the OpenGL graphics option and invoked with magic -d OGL.

Note that macros of the wind3d window are hard-coded, and cannot be changed with the macro, gmacro, or imacro commands. There is no ":" macro for entering commands; to enter commands from the command-line, use the tk_path_name command. The default Tk path name of the wind3d window is ".magic3d".

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wind3d/zoom.html0000644000175000001440000000676010751423606016242 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

zoom


Specify rendering scale.

Shortcuts:

Key macro Z implements a zoom-out function.
Key macro z implements a zoom-in function.
Key macro < decreases the vertical scale.
Key macro > increases the vertical scale.

Usage:

zoom [xy z]

where xy is the scale in both x and y dimensions (which cannot be set differently from each other), and z is the scale in the z (vertical) direction.

Summary:

The zoom command changes the scale of the 3D rendering, effectively moving the viewpoint closer to or farther away from the vertical axis origin.

Three-dimensional rendered views of layout usually exaggerate the vertical axis (like topographical maps of the Earth) to allow the vertical structure to be more readily viewed and understood. The vertical axis scaling is therefore arbritrary, and may be set independently of the other axes.

Note that the z-axis value is represented such that it is independent of changes in the xy zooming. Key macros implementing zoom-in and zoom-out functions effectively change the scaling factor of all three viewing axes simultaneously, so that the vertical scale remains proportional to the horizontal scales. This does not change the zoom value of z reported by the zoom command.

Without arguments, zoom returns the current scalefactors in both the xy axes (combined) and z axis.

Implementation Notes:

zoom is implemented as a built-in wind3d window command in magic. It overrides the default window client zoom command. Note that the wind3d window is only available when magic is compiled with the OpenGL graphics option and invoked with magic -d OGL.

Note that macros of the wind3d window are hard-coded, and cannot be changed with the macro, gmacro, or imacro commands. There is no ":" macro for entering commands; to enter commands from the command-line, use the tk_path_name command. The default Tk path name of the wind3d window is ".magic3d".

See Also:

scroll
view

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/extract.html0000644000175000001440000000764410751423606015542 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

ext, extract


Circuit netlist extractor

Usage:

extract option

where option may be one of the following:
all
Extract the root cell and all its children. This bypasses the incremental extraction and ensures that a new .ext file is written for every cell definition.
cell name
Extract the indicated cell into file name
do|no [option]
Enable or disable an extractor option, where option may be one of the following:
capacitance
resistance
coupling
length
adjust
all
length [option]
Control pathlength extraction information, where option may be one of the following:
driver termname
receiver termname
clear
help
Print help information
parents
Extract the selected cell and all its parents
showparents
List the cell and all parents of selected cell. Note that this is not really an extract option and is superceded by the cellname command.
[list|listall] style [stylename]
Set the current extraction style to stylename. Without arguments, print the current extraction style. With keyword list, return the current extraction style as a Tcl result. With keyword listall, return all valid extraction styles for the technology as a Tcl list.
unique [#]
Generate unique names when different nodes have the same name
warn [[no] option]
Enable/disable reporting of non-fatal errors, where option may be one of the following:
fets
labels
dup
all

Summary:

With no options given, the extract command incrementally extracts the root cell and all its children into separate .ext files. With options, the effect is as described in the Usage section above.

Implementation Notes:

extract is implemented as a built-in magic command.

ext is an alias for command extract (allowed abbreviation where the usage would otherwise be ambiguous).

See Also:

extresist
ext2spice
ext2sim

Return to command index

Last updated: October 6, 2004 at 3:16am

magic-8.0.210/doc/html/scroll.html0000644000175000001440000000461710751423606015363 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

scroll


Scroll the window

Shortcuts:

The keyboard arrow keys implement the command. Without modifiers, the window scrolls by 1/10 width in the indicated direction. With Shift, the window scrolls by one width in the indicated direction.

Usage:

scroll direction [amount [units]]

where direction is a valid Manhattan direction, and amount by default is an absolute distance in any acceptable units. If units is w, then the amount is interpreted as a fraction of the screen width. If units ls l, then the amount is interpreted as a fraction of the layout width. Note that units of distance for amount, such as "um" for microns or "i" for internal units, are attached to the value with no intervening space, whereas the two units keywords accepted by the scroll command are a separate argument and separated from amount by whitespace.

Summary:

The scroll command implements a pan of the layout in the window in the indicated direction by the indicated amount. The interpretation of amount is described above in the Usage section.

Implementation Notes:

scroll is implemented as a built-in window command in magic.

Return to command index

Last updated: October 8, 2004 at 2:45am

magic-8.0.210/doc/html/copy.html0000644000175000001440000000520010751423606015024 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

copy


Make a copy of the selection.

Shortcuts:

Key macro c implements the command copy.

Usage:

copy [option]

where option is one of the following:
direction [distance]
Copy the selection relative to the original in the direction direction by an amount distance.
to x y
Copy the selection to the coordinate location specified by the coordinate pair x y.

Summary:

The copy command creates a copy of the current selection. Without arguments, the lower-left hand corner of the copied selection is placed at the current cursor position (the X11 cursor, not the magic "cursor box"). With arguments direction and distance, the new copy is placed relative to the original in the indicated direction by the indicated amount. The default distance is 1 unit (usually lambda; see distance for further explication).

Note that usage copy center is useful to make a copy in the current edit cell of a selection of paint and/or subcells in a non-edit cell. With this use, the copy will be generated directly on top of the original.

Implementation Notes:

copy is implemented as a built-in magic command.

See Also:

direction
distance

Return to command index

Last updated: October 6, 2004 at 12:41am

magic-8.0.210/doc/html/feedback.html0000644000175000001440000001104710751423606015604 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

feedback


Query or manipulate feedback entry areas.

Usage:

feedback option

where option may be one of the following:
add text [style] [x1 y1 ...]
Create a new feedback area. If positions x1 y1 ... are not specified, then the feedback area created corresponds to the area of the cursor box. The feedback entry will be associated with the text text, which will be reported on execution of a feedback why query. The feedback area will be drawn in style style, which may be one of the following:
  • dotted
  • medium
  • outline
  • pale
  • solid
From magic version 7.3.110, any style from the ".dstyle" file may be specified (e.g., "yellow1"). If points x1 y1 ... are specified, then they represent a polygonal area for the feedback entry. This area may be a point, line, or polygon, and may be specified in internal units or metric units. If the feedback area is a point, line, or degenerate polygon (polygon with zero internal area), then the style must be an outlined style; otherwise, the style is changed to style outline so that the feedback area is ensured to be visible.
clear [substring]
Without the argument substring, clears all feedback info. When substring is specified, only feedback entries containing the text substring will be removed. For example, if "cif see CMF" is followed by "cif see CCC", the contact cuts will not be seen due to being overlapped by the feedback for metal1. However, if this is followed by "feedback clear CMF", the feedback area for metal1 will be removed, leaving the contact cuts visible.
count
Count the number of feedback entries
find [nth]
Put the cursor box over next (or nth) entry
help
Print help information
save file
Save feedback area information into file file
why
Print text associated with all feedback areas under the cursor box.

Summary:

The feedback command queries or manipulates feedback areas, which are areas drawn on top of the layout and may be used for annotations and markers. Internally, magic uses feedback areas to report CIF/GDS layers (cif see command), and errors generated by the extract command. CIF/GDS feedback is placed on the output (usually centimicron) grid, which cannot be done with the feedback add command directly from the command-line.

Feedback information and areas are not saved in the layout file.

Implementation Notes:

feedback is implemented as a built-in magic command.

Bugs:

Small feedback areas were previously drawn solid to prevent them from disappearing entirely; however, this created bizarre results in CIF/GDS feedback when several narrow feedback areas are tiled together, so it was removed. This leaves the possibility that feedback areas smaller than the spacing between feedback crosshatch lines might not be drawn; an inconvenience, but not a serious problem.

There should be a mechanism for removing only the feedback entries under the cursor box, or the current feedback entry.

Return to command index

Last updated: December 4, 2005 at 8:32pm

magic-8.0.210/doc/html/goto.html0000644000175000001440000000442010751423606015025 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

goto


Goto the named node

Usage:

goto nodename [-nocomplain]

where nodename is any valid name for a network node.

Summary:

The goto command moves the cursor box to some position representing the network node named nodename, if it exists in the layout. Because any given area of the layout may contain more than one unconnected network node, a layer type is returned. The area of the cursor box plus the layer type always uniquely identifies the node.

The -nocomplain switch supresses the warning message if the node does not exist. In the Tcl version, an empty list is returned for nodes that cannot be found, and no error condition is reported.

Implementation Notes:

goto is implemented as a built-in command in magic. The Tcl version of magic returns the layer of the node as a Tcl result.

A script may make use of the return value in the following manner:

select box [goto nodename]; select more net
which selects the entire network named nodename.

See Also:

getnode

Return to command index

Last updated: October 16, 2004 at 2:15pm

magic-8.0.210/doc/html/help.html0000644000175000001440000000545710751423606015020 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

help


Print out synopses for all commands valid in the current window (or restrict output to those containing the indicated pattern)

Usage:

help [pattern]

where pattern is any keyword or text string.

Summary:

The help command invokes the built-in help function in magic, which lists the summary usage information that has been compiled into magic for each command. The summary help information is usually only a single line of text. Commands that have complicated sets of options have their own help option, which is not part of the help command.

Without arguments, help reports a summary usage for every command in magic. With arguments, magic filters the output to report only those commands matching the indicated text pattern.

The output is divided into general-purpose and window-specific sections. The window-specfic section depends on the active window. For instance, with a single layout window present, help cleanup returns no information. However, the command specialopen netlist followed by help cleanup will report the usage of the command cleanup, which is a command that can only be invoked from the netlist window.

Implementation Notes:

help is implemented as a built-in command in magic. Note that there is no general-purpose command-line-based help method for Tcl commands, so the help command will not provide any information about magic commands written as Tcl procedures, such as openwrapper or pushstack. The general convention is for each Tcl procedure to allow the option help and provide its own usage information.

Return to command index

Last updated: October 6, 2004 at 7:02pm

magic-8.0.210/doc/html/crashbackups.html0000644000175000001440000000422010751423606016524 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

crashbackups


Handle periodic backups during a layout editing session.

Usage:

crashbackups [start|stop]

Summary:

The crashbackups procedure enables or disables the periodic saving of crash recovery backup files. crashbackups or crashbackups start sets the timer for the first periodic save. After the timer times out, backup file is generated and written in the system temporary directory, and the timer is reset. By default, the backup interval is 10 minutes (600000 msec). The interval can be changed by setting the value of Tcl variable $Opts(backupinterval) to the interval value in msec.

crashbackups stop removes the timer callback and thus prevents further writing of backup files. Note that if crash recovery is stopped or started multiple times during a session, the same filename is used to save the data.

Implementation Notes:

crashbackups is implemented as a Tcl procedure in the "tools.tcl" script file. It calls the magic command "crash save".

See Also:

crash

Return to command index

Last updated: December 7, 2005 at 3:15pm

magic-8.0.210/doc/html/quit.html0000644000175000001440000000340410751423606015040 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

quit


Exit magic

Shortcuts:

Key macro Control-Shift-q implements the command quit.

Usage:

quit

Summary:

The quit command implements a resonably gentle exit from magic, first prompting the user if layouts with changes have not yet been committed to disk.

Note that in the Tcl version, if the magic package is unable to load for some reason, the quit command will not be present, and the Tcl exit command is required to quit the program. The Tcl exit command will always exit magic immediately, without prompting or cleanup or any other niceties.

Implementation Notes:

quit is implemented as a built-in window command in magic.

Return to command index

Last updated: October 8, 2004 at 1:00am

magic-8.0.210/doc/html/commands.html0000644000175000001440000005317710751423606015673 0ustar timusers Magic-7.4 Command Reference

Magic VLSI Layout Tool Version 7.4 *

Magic User's Guide

Table of Contents

Command-line invocation (usage)
Script Invocation
Magic command summary

Obligatory Screenshot

Screenshot of Magic
This screenshot, from Magic version 7.2, shows off a number of features of the Tcl version, including the cell manager window, the tech manager window, the toolbar, the console command-line entry window, and popup dialog boxes. Also shows off the version 7.1+ features of the OpenGL display and the non-Manhattan geometry extension.

Magic version 7.4 Usage (command-line invocation)

Basic usage:

magic [-noc[onsole]] [-now[rapper]] [-d devType] [-T technology] [file]

where:
-noconsole
(Tcl version only) Uses the calling terminal for terminal-based command-line input. Otherwise, a Tk console window is used.
-nowrapper
(Tcl version only) Magic layout windows use the GUI wrapper, including cell and technology manager windows, layer toolbar, and file menu.
-d devType
(all versions) Select the graphics interface at runtime. Specifying an invalid devType will result in a list of known types. The possible values of devType are determined at compile time, but the usual ones are NULL (no graphics), X11, and OpenGL. X11 is the usual default.
-T technology
(all versions) Select the appropriate technology (.tech) file. At present (this is on the to-do list), magic cannot change technology after startup. So the technology file corresponding to the layout to be loaded must be supplied to the command line at startup. The default technology is scmos, which is included with the magic source distribution. The complete list of available technology files depends on what has been installed on the system (see the technology file page for details).
file
(all versions) Load the layout (.mag) file file into the layout window on startup.
Other standard usage:

magic [-dnull] [file]

magic [-r[ecover]]

where options are as follows:
-recover
This option recovers a layout after a crash. Note that crash recovery files are only automatically created and updated by the Tcl/Tk version of magic. A single file containing multiple layouts is placed in the /tmp directory. Upon normal program exit, it is removed. However, if magic terminates abnormally due to a program bug, reception of a termination signal from the operating system, or a system crash or shutdown, the file will remain and can be recovered. It is very important that you recover the file from the same directory where it was initially created; otherwise, if startup conditions are different (such as a different technology specified), layout may be lost.
-dnull file
This option starts magic without graphics. It is appropriate for running magic in batch mode from a script. Note that there is a subtle difference between options "-d null" and "-dnull". The former starts magic without the ability to create a layout window, but still invokes the graphics initialization routines (in the Tcl/Tk version, a Tk window may briefly appear). The latter form specifically ignores all graphics and therefore runs with less overhead on startup.
Complete usage information:

magic [-noc[onsole]] [-now[rapper]] [-nowindow] [-d devType] [-T technology] [-m monType] [-D] [file]

where the additional options not covered above are:

-nowindow
(Tcl version only) Run without displaying an initial layout window. This is used mainly for GUI wrapper scripts which like to generate and handle their own windows.
-m monType
(obscure) monType names a monitor type. This is used in the search for the colomap file name, which is designated <tech>.<planes>.<mon>.cmap1. The default is "std" (corresponding to colormap file "mos.7bit.std.cmap1". The only other monitor type for which colormaps exist in the distribution is "mraster". This provides a way for users to override the system color assignments.
-D
(all versions) Run in Debug mode.
Obsolete usage information:

magic [-g gPort] [-i tabletPort] [-F objFile saveFile] ...

where the additional options not covered above are:

-g gPort
(largely obsolete) gPort names a device to use for the display. This was generally used in the past with dual-monitor systems, especially Sun systems in which the layout display might go to /dev/fb.
-i tabletPort
(largely obsolete) tabletPort names a device to use for graphics input. This has not been tested with modern graphics tablet devices. It is ignored by the X11 and OpenGL display interfaces.
-F objFile saveFile
(largely obsolete) Create an executable file of the current magic process, a core image snapshot taken after all initialization. objFile is the name of the original executable, and the image will be saved in saveFile. This only works on VAXen and SUNs running an old SunOS (using a.out executables).

Script invocation

Often it is helpful to have a shell script invoke magic with specific options to perform tasks such as generating a GDS file for tapeout. The following example code clip imports GDS into magic as a "vendor cell":
magic -dnull -noconsole << EOF
drc off
box 0 0 0 0
load vtop.mag -force
drc off
gds readonly true
gds rescale false
gds read ${cellname}.gds
cellname rename ${cellname} vtmp
load vtmp
select top cell
set pname [lindex [cellname list children] 0]
cellname rename \\\$pname ${cellname}
select cell \\\${pname}_0
identify ${cellname}_0
writeall force ${cellname}
quit -noprompt
EOF

General window commands (for all windows)

center closewindow cursor
help imacro logcommands
macro openwindow redo
redraw scroll setpoint
sleep specialopen quit
undo updatedisplay version
view windowborder windowcaption
windownames windowscrollbars xview
zoom tk_path_name

Layout window commands and window-less commands

addcommandentry addpath array
box calma caption
cellmanager cellname cellsearch
channels cif clockwise
closewrapper contact copy
corner crash crashbackups
crosshair def delete
deletecommandentry down drc
dump edit element
erase expand ext
ext2sim ext2spice extract
extresist exttosim exttospice
feedback fill findbox
findlabel flatten flush
garoute gds get
getcell getnode goto
grid help identify
initialize instance iroute
irsim label lef
load maketoolbar measure
move openwrapper paint
path peekbox plot
plow polygon popbox
popstack port promptload
promptsave property pushbox
pushstack render3d resumeall
rotate route save
scalegrid search see
select shell sideways
snap spliterase splitpaint
startup straighten stretch
suspendall tag tech
techmanager tool (non-Tcl version) tool (Tcl version)
unexpand unmeasure upsidedown
what wire writeall
xload

Netlist window commands

add cleanup cull
dnet dterm extract
find flush join
netlist pushbutton print
ripup savenetlist shownet
showterms trace verify
writeall

3D window commands

cif closewindow cutbox
defaults help level
refresh render scroll
see view zoom

Color window commands

pushbutton color load
save

"Wizard" (developer) layout commands

*bypass *coord *extract
*plow *psearch *showtech
*tilestats *tsearch *watch

"Wizard" (developer) window commands

*crash *files *grstats
*pause *winddebug *winddump

User's Guide Development

To be done:
  • Add some general topics, not command-specific.
  • Incorporate a lot of the currently text-only material into HTML format.
  • Run latex2html on all of the LaTeX distribution documentation.
  • More information on the routers and netlists
  • Subject index.

email:

Last updated: December 15, 2005 at 6:59am

magic-8.0.210/doc/html/path.html0000644000175000001440000000403210751423606015010 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

path


Modify or query magic's search paths
path [search|cell|sys] [[+]path]

Usage:

path [search|cell|sys] [[+]path]

Summary:

The path command queries and manipulates the various search paths used by magic. Without arguments, path search is assumed. The three search paths are:
search
The search path for layout files.
cell
Search path for tutorial cells.
sys
Search path for technology files.
The + option allows the path component path to be appended to the indicated search path. Otherwise, the indicated search path is replaced by the contents of path.

Implementation Notes:

path is implemented as a built-in command in magic. The use path search +path supercedes the addpath command, as the path command is more general.

See Also:

addpath

Return to command index

Last updated: October 7, 2004 at 5:54am

magic-8.0.210/doc/html/suspendall.html0000644000175000001440000000412510751423606016231 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

suspendall


Suspend normal display refresh on all windows until the invocation of a corresponding resumeall command.

Usage:

suspendall

Summary:

The suspendall command is a script that invokes the command update suspend on all layout windows. It is used in conjunction with the resumeall command and is intended for use in Tcl scripts that perform multiple manipulations on layout in a window, where it is desired to have the entire display refresh at one time at the end of the script rather than for each command within the script.

Because the update command can be nested, calls to suspendall and resumeall are likewise nested. resumeall does not resume the window refresh until it has been called the same number of times as suspendall was called.

Implementation Notes:

suspendall is implemented as a Tcl procedure in the "tools" script.

See Also:

resumeall
update

Return to command index

Last updated: October 8, 2004 at 1:24am

magic-8.0.210/doc/html/corner.html0000644000175000001440000000614110751423606015347 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

corner


Make L-shaped wires inside the cursor box.

Usage:

corner d1 d2 [layers]

where d1 and d2 are valid manhattan directions, and layers is an optional comma-separated list of valid paint layers.

Summary:

The corner command makes L-shaped wires inside the cursor box, filling first in direction d1, then in direction d2. If no layers are specified, then the cornering algorithm is applied to all layers crossing the cursor box boundary opposite to direction d1. If layers is specified, the cornering algorithm is applied only to those layers specified. The usage of corner is similar to that for the command fill (q.v.).
Below is an example showing how the cornering algorithm responds to the command corner n e. First it finds layers crossing the cursor box boundary to the south (opposite to the first specified direction, north), and then extends these layers as wires first to the north, then to the east. The position of the layers leaving the box to the east is such that the same distance is maintained from each layer to the north side of the box at the exit point as it was from each layer to the east side of the box at the entrance point.

Figure 1: The cornering operation in response to the layout shown, given magic command corner n e.

Implementation Notes:

corner is implemented as a built-in magic command.

Bugs:

If the area in the box is not large enough for the cornering algorithm to produce the cornered wires, unpredictable results often result.

See Also:

direction
fill

Return to command index

Last updated: October 4, 2004 at 7:56am

magic-8.0.210/doc/html/drc.html0000644000175000001440000001255010751423606014630 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

drc


Background design rule checker control and status.

Usage:

drc option

where option is one of the following:
catchup
Run checker and wait for it to complete
check
Recheck area under box in all cells
count [total]
Count error tiles in each cell under box. Option total returns the total number of DRC error tiles in the cell.
euclidean on|off
Enable/disable Euclidean geometry checking
find [nth]
Locate next (or nth) error in current cell
help
Print help information
off
Turn off background checker
on
Reenable background checker
status
Report whether the background checker is on or off.
printrules [file]
Print out design rules in file or to stdout
rulestats
Print out statistics about design rule database
statistics
Print out statistics gathered by checker
why
Print out reasons for errors under box
*halo [value]
Without option value, prints out the DRC halo distance, which is the largest distance at which a DRC interaction can occur outside of any area to be checked. Becuase large DRC haloes can cause very long delays in the interactive DRC checks, it can be helpful to use value to force a smaller halo. This causes certain DRC errors to be missed, but allows all the basic short-distance design rules to be checked without undue processing delays.
*stepsize [value]
The step size is the length of a side of the area into which the DRC checker routine breaks up larger areas for more efficient processing. Changing this value can greatly effect the speed of the DRC checker, although it is difficult to predict what step size is "optimal". Without option value, returns the current value of the step size.

Summary:

The drc command controls the behavior of magic's "background" design rule checker. Normally the design rule checker is invoked whenever the design is changed and checks all parts of the design close to the changed area that might have been affected by the change. The design rule checker flags areas that have been checked as it runs. It starts whenever a layout change has been made or after any command has been executed if areas of the layout still need to be checked. Any macro keystroke in the layout window or command executed on the command line will interrupt the design rule checker pending completion of the action, at which time the design rule checker will be reactivated.

The drc on and drc off options are the main controls for starting and stopping the design rule checker. drc status returns the status of the background checker, either "on" or "off". The Tcl version of magic returns a boolean value (0 or 1).

The drc check option marks all areas of the layout under the box as requiring a check and restarts the design rule checker.

The drc why and drc find commands can be used to query errors in the layout discovered by the design rule checker. drc why reports the reason for all error regions found inside the magic cursor box. The drc find command can be used to find errors that may not be visible inside the current window view, or that may be difficult to find on a large layout.

The drc euclidean on command can be useful in cases where vendor design rules intend a Euclidean distance metric (minimum linear distance) rather than a Manhattan distance metric (minimum distance in either the x or y direction, evaluated separately). The default option is "off", as most vendor rules and design rule checkers assume Manhattan distances when checking rules.

The remaining options are relativly obscure and unlikely to be useful to the typical end-user.

Implementation Notes:

drc is implemented as a built-in magic command.

Return to command index

Last updated: December 4, 2005 at 5:39pm

magic-8.0.210/doc/html/see.html0000644000175000001440000000534010751423606014633 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

see


Change what layers are displayed in the window

Shortcuts:

Mouse buttons 1 and 3 pressed in the GUI window toolbar implement the see and see no commands for the layer represented by the toolbar button.

Usage:

see [no] layers|allSame

where layers is a comma-separated list of layers in the technology, and may also be the character * indicating all layers but not labels, $ indicating all layers including labels, labels indicating only labels, error indicating DRC error paint, and subcell indicating subcells.

Summary:

The see command allows various layers in the layout to be made visible, including labels and error paint. With the keyword no, the command causes these layers to be made invisible on the display.

The keyword allSame is a special use and indicates that non-edit cells should be drawn in the same manner as the edit cell, rather than being drawn in the "pale" styles.

Undisplayed layers generally do not respond to commands such as erase or select. However, network selection will select across invisible layers, and copying or moving such a network selection will alter the invisible layers as well as the visible.

Implementation Notes:

see is implemented as a built-in command in magic.

Bugs:

It should be enforced everywhere in the code that invisible layers cannot be altered. This may require removing invisible layers from a selection after doing a network connectivity search.

Return to command index

Last updated: October 16, 2004 at 2:02pm

magic-8.0.210/doc/html/rotate.html0000644000175000001440000000414610751423606015360 0ustar timusers rotate [+/-][deg] rotate selection and box (counter)clockwise only manhattan rotations (90, 180, 270) are supported Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

rotate


Rotate the selection and box clockwise by the indicated amount.

Usage:

rotate [+|-][degrees] [-origin]

where degrees is the number of degrees to rotate, and must be a manhattan amount (90, 180, 270).

Summary:

The rotate command rotates the current selection by the specified amount, in degrees. The default rotation is by 90 degrees. The amount of rotation can be positive or negative, but must be one of the Manhattan rotations 90, 180, or 270.

If -origin is specified, the rotation is around the origin of the selection, not around the lower left-hand corner.

Implementation Notes:

rotate is implemented as a built-in magic command. It is equivalent to the clockwise command but allows negative values to represent counterclockwise rotation.

See Also:

clockwise

Return to command index

Last updated: October 15, 2004 at 10:10am

magic-8.0.210/doc/html/windownames.html0000644000175000001440000000435110751423606016413 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

windownames


Get name of current or all windows

Usage:

windownames [all|type]

where type is one of the window types known to the specialopen command, which are: layout, wind3d, color, and netlist.

Summary:

The windownames command returns a list of magic windows as specified by the command options. No options is equivalent to option all, and prints the names of all existing windows. Otherwise, windows can be listed by type, where type is the type of window as understood by the specialopen command.

The Tcl/Tk version of magic returns the full Tk path name of each window, including any parent frames. The non-Tcl/Tk version of magic returns window IDs (the ID is an integer number used by the setpoint command.

See Also:

setpoint

Implementation Notes:

windownames is implemented as a built-in command in magic. The Tcl version returns a Tcl list of Tk path names for each window. The non-Tcl version of magic writes the window list to standard output.

Return to command index

Last updated: December 4, 2005 at 8:40pm

magic-8.0.210/doc/html/crash.html0000644000175000001440000000727610751423606015171 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

crash


Handle crash backup files

Usage:

crash save | recover [filename]

Summary:

The crash command handles crash backup files. The exact operation depends on the options, and are outlined below:
crash save
creates and writes to a single file a copy of the contents of all modified cells. If crash save has been called previously, then the filename specified or generated will be used again. If this is the first call to crash save, or if the previous call was crash save "", then a new, unique filename of a file in the system temporary directory (normally "/tmp") is created and remembered for subsequent calls to crash save.
crash save filename
creates and writes to the file filename a copy of the contents of all modified cells. filename is retained as the crash filename, so subsequent uses of crash save without a filename specified will also write to this file.
crash save ""
causes magic to forget the name of the crash file. The next use of crash save without a filename will revert to the behavior of generating a unique filename in the system temporary directory.
crash recover
searches the system temporary directory for magic crash recovery files. If one or more such files is found, then the user is prompted for the action of either recovering or ignoring the most recent file found. If the chosen action is to recover the file, then the contents of the saved crash file are loaded into the database, and the file is removed.
crash recover filename
recovers the database from the contents of the saved crash file filename upon successful read-in, the file filename is removed.
If a crash file has been generated during a layout editing session, and magic is exited normally with the "quit" command, then the crash backup file is removed.

For backward-compatibility, crash backup files are always generated when magic receives a SIGTERM signal. In the non-Tcl version of magic, periodic backups are not made.

Implementation Notes:

crash is implemented as a built-in command in magic. The Tcl/Tk version defines various scripts in "tools.tcl" that implement a periodic backup using the crash command. Invoking magic on the command-line using "magic -r" is equivalent to starting magic followed by the command "crash recover".

See Also:

crashbackups

Return to command index

Last updated: December 7, 2005 at 3:06pm

magic-8.0.210/doc/html/ext2spice.html0000644000175000001440000001617310751423606015773 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

ext2spice, exttospice


Convert extracted file(s) to a SPICE format file.

Usage:

ext2spice [option]

where option is one of the following:
[run] [runtime_options]
Run ext2spice on current cell, with command-line options (see Summary, below).
default
Reset to default values
format hspice|spice2|spice3
Set output format. spice3 is the default, for compatibility with tclspice. This is a change from previous versions of magic, where the default was hspice.
rthresh [value]
Set resistance threshold value. Lumped resistances below this value will not be written to the output. The value is in ohms, or may be the keyword infinite to prohibit writing any lumped resistances to the output.
cthresh [value]
Set capacitance threshold value. The value is in femtofarads, or may be the keyword infinite to prohibit writing any parasitic capacitances to the output.
merge [merge_option]
Merge parallel devices/transistors. The valid merge options are:
conservative
Merge transistors and capacitors having the same device type and node connections and having the same width and length. Widths are summed in the final output for transistors. Capacitor values are summed in the final output.
aggressive
Merge transistors having the same node connections and having the same length. Widths are summed in the final output. Merge any capacitors having the same device type and node connections. Capacitance is summed in the final output.
none
Do not merge any devices.
extresist on|off
Incorporate output from the command extresist into the final SPICE file.
resistor tee [on|off]
Model resistor capacitance as a T-network. Each resistor device is split into two, with all substrate and overlap capacitance placed on the node between the two half-length devices. Without this option, resistor devices lose all parasitic capacitance information, and ext2spice may produce warnings about unknown nodes. However, use of this option may conflict with LVS (layout-vs.-schematic), when only one resistor is expected per drawn device.
subcircuits [on|off]
When set to on (the default), standard cells become subcircuit calls ("X") in the SPICE output. The contents of the standard cells are not output, and it is assumed that a pre-characterized SPICE deck exists modeling the behavior of each standard cell definition. Standard cells are defined by the use of the port method for labeling input and output ports. When set to off, ports are ignored, and the entire circuit hierarchy is flattened down to the device level.
help
Print help information.

Summary:

Without options, or with the option run, the ext2spice command converts the hierarchical extracted netlist information produced by the extract command in a series of .ext files into a flattened representation in SPICE format, used for detailed analog simulation.

runtime_options may be passed on the command line, and represent the original command-line options passed to the standalone version of ext2spice. A number of the original command-line options have been deprecated in the Tcl-based version, and some are duplicated by other ext2spice options. Valid runtime_options are:

-B
Don't output transistor or node attributes in the SPICE file. This option will also disable the output of information such as the area and perimeter of source and drain diffusion and the FET substrate.
-F
Don't output nodes that aren't connected to devices (floating nodes).
-tchar
Trim characters from node names when writing the output file. char should be either "#" or "!". The option may be used twice if both characters require trimming.
-y num
Select the precision for outputting capacitors. The default is 1 which means that the capacitors will be printed to a precision of 0.1 fF.
-J hier|flat
Select the source/drain area and perimeter extraction algorithm. If hier is selected then the areas and perimeters are extracted only within each subcell. For each device in a subcell the area and perimeter of its source and drain within this subcell are output. If two or more devices share a source/drain node then the total area and perimeter will be output in only one of them and the other will have 0. If flat is selected the same rules apply, only the scope of search for area and perimeter is the whole netlist. In general, flat (which is the default) will give accurate results (it will take into account shared sources/drains).
With options, the command sets various parameters affecting the output format and content.

Implementation Notes:

ext2spice is implemented as a separate loadable Tcl package, but one which depends on the presence of the standard "tclmagic" package. magic is set up with a placeholder command for ext2spice, and will automatically load the Tcl package when this command is invoked.

exttospice is an alias for ext2spice, to satisfy the grammatically anal retentive.

See Also:

extract
ext2sim

Return to command index

Last updated: October 12, 2005 at 9:40pm

magic-8.0.210/doc/html/wire.html0000644000175000001440000000750210751423606015027 0ustar timusers

See Also:

wire
Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

wire


Generate wires from the command line.

Shortcuts:

Mouse buttons in conjunction with the wire tool implement various wire commands (see the tool command reference).

Usage:

wire option

where option may be one of the following:
help
Print help information
horizontal
Add a new horizontal wire leg
leg
Add a new horizontal or vertical leg
switch [layer width]
Place contact and switch layers
type [layer width]
Select the type and size of wires
vertical
add a new vertical wire leg
segment layer width x1 y1 x2 y2... [-noendcap]
Paint one or more wire segments
show
Determine where the next wire leg will be according to the rules for wire leg, but place the result in the selection buffer rather than directly on the layout.
increment layer
Change the layer type used for wires to the wire type on the plane above the plane of the current wire type.
decrement layer
Change the layer type used for wires to the wire type on the plane below the plane of the current wire type.
increment width
Increment the width of the current wire by 1 internal unit.
decrement width
Decrement the width of the current wire by 1 internal unit.

Summary:

The wire command allows quick generation of wires on the layout. Some of these commands are bound to mouse button events in the wire tool, making a convenient interface for fast wiring where full netlist routing is not required. Due to the presence of the wire tool, most of these commands are not typically called from the command line.

The wire segment command can generate non-Manhattan segments. All other wiring commands generate only Manhattan routes. This command places wire segments in relation to the centerline coordinates specified by x1 y1, x2 y2, and so forth. By default, wires are drawn with an endcap extension of one-half the wire width. The -noendcap option causes the wire to end at the coordinate, with no extension. The wire segment command is intended to be used from Tcl scripts for automatic layout generation.

Implementation Notes:

wire is implemented as a built-in command in magic.

See Also:

polygon

Return to command index

Last updated: December 4, 2005 at 8:38pm

magic-8.0.210/doc/html/shell.html0000644000175000001440000000377310751423606015176 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

shell


Execute a command in a UNIX subshell

Usage:

shell [command]

where command is a valid UNIX command-line command.

Summary:

The shell command allows UNIX commands to be executed from the magic command line. This use is superceded by the Tcl interpreter, which executes shell commands directly from the interpreter prompt. Differences between the two uses is noted below.

Implementation Notes:

shell is implemented as a built-in command in magic. This is similar to the Tcl interpreter execution of shell commands directly from the Tcl command-line. The primary difference is that results from the shell interpreter are printed to the calling terminal with shell, and are printed to the console when invoked directly from Tcl. For example, note the difference in the output target for:
ls -l
           
vs.
shell ls -l

Return to command index

Last updated: October 8, 2004 at 3:55am

magic-8.0.210/doc/html/wizard/0000755000175000001440000000000011504623573014471 5ustar timusersmagic-8.0.210/doc/html/wizard/grstats.html0000644000175000001440000000262410751423606017050 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

*grstats


Print out statistics on graphics.

Usage:

*grstats count [style]

where count and style are integers.

Summary:

The *grstats command does a screen update and reports on the number of rectangles drawn, and gives an estimate of the rendering speed for rectangle drawing.

Implementation Notes:

*grstats is implemented as a built-in window "wizard" command in magic.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wizard/showtech.html0000644000175000001440000000333010751423606017200 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

*showtech


Print internal technology tables.

Usage:

*showtech [-v] [file]

where file is the name of a file to which to direct output.

Summary:

The *showtech command prints information from the current technology, including information from the layers, planes, connect, compose, and contact sections. The "-v" flag, if specified, prints detailed information about the paint and erase tables (which can be very large).

Implementation Notes:

*showtech is implemented as a built-in "wizard" command in magic.

See Also:

tech

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wizard/pause.html0000644000175000001440000000252210751423606016473 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

*pause


Print arguments and wait for the return key to be pressed.

Usage:

*pause [args]

Summary:

The *pause command prints out the arguments passed to the command and waits for the carriage-return to be pressed, effectively suspending the program.

Implementation Notes:

*pause is implemented as a built-in window "wizard" command in magic.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wizard/watch.html0000644000175000001440000000454210751423606016470 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

*watch


Enable (disable) annotated tile plane display

Usage:

*watch [plane] [demo] [types]

where plane is a valid plane name in the current technology.

Summary:

The *watch command generates an annotated layout display which shows the structure of the tile plane in the corner-stitched database representation.

The demo option produces arrows at the stitch corners illustrating which tiles are directly referenced by pointers in the database tile structure.

The types option shows the name of the tile type for each tile, instead of the default display, which is the memory address (in hexidecimal) of the tile, in large print, and the memory address of the four stitched tiles, in small print.

*watch without arguments clears the display of annotations and returns to the normal layout view. Note that *watch only allows one plane at a time to be annotated. Also note that some commands such as edit will cause the annotation not to be synchronized with the current display or current edit cell, and may require the *watch to be executed again to display the correct tiles.

Implementation Notes:

*watch is implemented as a built-in "wizard" command in magic.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wizard/tsearch.html0000644000175000001440000000335610751423606017015 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

*tsearch


Invoke an area search over box area

Usage:

*tsearch plane count [mask [mayo|new]]

where plane is a valid plane name in the current technology, and count is the number of searches to be performed. mask is a layer list to restrict the scope of the search, and the remaining optional arguments implement different search algorithms.

Summary:

The *tsearch command calls the internal hierarchical tile search routine a specified number of times over an area the size and shape specified by the box, each time over a different area in the edit cell.

Implementation Notes:

*tsearch is implemented as a built-in "wizard" command in magic.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wizard/winddump.html0000644000175000001440000000266610751423606017216 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

*winddump


Printe out debugging information.

Usage:

*winddump

Summary:

The *winddump command prints the list of window clients and the pointers to their create, delete, and redisplay routines, and the pointer to the client's command array. It also prints a list of the windows open and reports the surface area, origin, and scale of each.

Implementation Notes:

*winddump is implemented as a built-in window "wizard" command in magic.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wizard/plow.html0000644000175000001440000000442410751423606016342 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

*plow


Debug the plowing mechanism

Usage:

*plow option

where option may be one of the following:
clrdebug flags
help
jogreduce
lwidth layers
lshadow layers
mergedown
mergeup
move
outline direction layers
plow direction [layers]
print
random
setdebug flags
shadow layers
showdebug
split
techshow [file]
trail [value]
whenbot [xbot ybot]
whentop [xtop ytop]
width layers

Summary:

The *plow command reports assorted information about the plow mechanism.

Implementation Notes:

*plow is implemented as a built-in "wizard" command in magic.

See Also:

plow

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wizard/psearch.html0000644000175000001440000000277210751423606017012 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

*psearch


Invoke point search over box area

Usage:

*psearch plane count

where plane is a valid plane name for the current technology, and count is the number of searches to perform.

Summary:

The *psearch command runs a point search a specified number of times from the point at the lower-left corner of the box tool to each point in the edit cell.

Implementation Notes:

*psearch is implemented as a built-in "wizard" command in magic.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wizard/extract.html0000644000175000001440000000470310751423606017033 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

*extract


Debug the circuit extractor

Usage:

*extract option

where option may be one of the following:
clrdebug [flags]
clrlength
driver terminalname
interactions [halo [bloat]]
intercount [halo [filename]]
parents
reciever terminalname
setdebug [flags]
showdebug
showparents
showtech [filename | -]
Display the technology-specific tables maintained for circuit extraction in a human-readable format. Intended mainly for debugging technology files. If the argument filename is "-", the output is to the standard output; otherwise, it is to the file whose name is filename.
stats
step [stepsize]
Set or report interaction step size.
times [filename]

Summary:

The *extract command gives assorted detailed information about the operation of the circuit extractor.

Implementation Notes:

*extract is implemented as a built-in "wizard" command in magic.

See Also:

extract

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wizard/tilestats.html0000644000175000001440000000306410751423606017374 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

*tilestats


Print statistics on tile utilization

Usage:

*tilestats [-a] [file]

where file is the name of a file to which to redirect output.

Summary:

The *tilestats command reports various statistics on tile plane utilization. The "-a" switch, if specified, causes output to be generated for all cells in the database. Otherwise, output is generated for only the currently selected cell.

Implementation Notes:

*tilestats is implemented as a built-in "wizard" command in magic.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wizard/coord.html0000644000175000001440000000324210751423606016464 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

*coord


Show coordinates of setpoint, cursor box, root cell, and edit cell.

Usage:

*coord

Summary:

The *coord command shows coordinates of the current set point (point tool), cursor box (box tool), root cell, and edit cell. Coordinate values are prefixed as follows:
e
Edit cell coordinate system
r
Root cell coordinate system
If the cursor is not in the window in which the command has been executed, then the point is not reported. If the box does not exist in the window, then the box is not reported.

Implementation Notes:

*coord is implemented as a built-in "wizard" command in magic.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wizard/crash.html0000644000175000001440000000243310751423606016457 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

*crash


Cause a core dump.

Usage:

*crash

Summary:

The *crash command calls the niceabort() routine, thereby causing an immediate program crash. If no limits are set by the shell, the core is dumped.

Implementation Notes:

*crash is implemented as a built-in window "wizard" command in magic.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wizard/winddebug.html0000644000175000001440000000254610751423606017334 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

*winddebug


Set debugging mode.

Usage:

*winddebug

Summary:

The *winddebug command sets the debugging mode, which reports on each command generated through the WindSend() routine. This does not include Tcl commands or commands generated on the command-line.

Implementation Notes:

*winddebug is implemented as a built-in window "wizard" command in magic.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/wizard/files.html0000644000175000001440000000241610751423606016462 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

*files


Printe out currently open files.

Usage:

*files

Summary:

The *files command reports on all files that magic is currently holding open, reporting the file type and file descriptor.

Implementation Notes:

*files is implemented as a built-in window "wizard" command in magic.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/element.html0000644000175000001440000001726610751423606015522 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

element


Handle generic drawing elements (line, box, text) in the layout.

Usage:

element option

where option is one of the following:
add type name parameters
Create a new element. The name is a unique name to be assigned to the new element. The parameters depend on the type, and are as follows:
line name style x1 y1 x2 y2
Create a new line element, with position starting at coordinate x1 y1 and ending at x2 y2. The line does not need to be on a Manhattan grid. Initial coordinates must be on internal magic grid points (that is, must be integer). However, half-grid units can be generated with the configure option (see below).
rectangle name style llx lly urx ury
Create a new box element, with lower left corner at coordinate llx lly and upper right corner at coordinate urx ury.
text name style cx cy label_text
Create a new text label at coordinate position cx cy with text string "label_text".
For an explanation of the style parameter, see the configure option, below.
delete name
Delete an existing element by name.
configure name config_option
Configure or query an existing element named name. config_option may be one of the following:
text [new_label_text]
style [add|remove [style_type]]
With no arguments, return the list of styles used to draw the element. With option add or remove, add or remove, respectively, a style from the list of styles for an element. Styles are the same as styles for tile types in magic, and are defined in the "dstyle" file in the magic install directory. The "dstyle" file declares a "long name" for each style type. This "long name" is what is expected for parameter style_type. The most useful values are the colors defined in the "dstyle" file, such as black, white, red, etc.

Like tile types, elements may be drawn in multiple styles. So, styles are maintained as a list and the element configure style option takes the keyword add or remove to add or remove specific styles from the list. Removing the last remaining style for an element is prohibited. Changing styles requires first adding the new style type, then removing the original.

position [x y [x2 y2]]
With no arguments, returns the position of the element. For text elements, this is the label position (a single coordinate). For lines, both endpoint coordinates are returned, and for rectangles, the lower-left and upper-right coordinates are returned. With one or two coordinate specified, the position of the element is changed. For text, a single coordinate indicates the new position of the text. For lines and rectangles, the two coordinates completely describe the line or box.
flags flag_type
Add or change flags of an element. The specific flag indicated is set. Valid flags are as follows. All elements have these flags:
temporary
Indicates an element that is not saved to the database with a save or writeall command (the default flag).
persistant
Indicates an element that is saved to the database with a save or writeall command, and can be recovered with a load command.
Text elements have the following additional flags:
small, medium, large, xlarge
One of four text sizes.
direction
Any valid direction specification in magic will be translated to a text justification; that is, the text will be printed relative to its position in the indicated direction.
Line elements have the following additional flags:
halfx, halfy
Adjust the position of the line endpoints by one-half unit (postive, that is, right or up). This allows lines to be drawn on, for example, wire centerlines. There is no allowance for having only one endpoint on the half-integer grid.
exactx, exacty
Set line endpoints on the exact coordinates of the line position (the default flag).
arrowleft, arrowbottom arrowtop, arrowright
Add arrows to the line endpoints at the indicated end. Note that four possible positions are allowed, although only two will be relevant for any given line. Arrowheads are of fixed size and may not be visible at large zoom factors.
plainleft, plainbottom plaintop, plaintright
Draw plain lines, with no arrowheads (the default flags).
Rectangle elements have no additional flags.
names
Print names of all elements
inbox
Print name of element in (or nearest) the box
help
Print help information

Summary:

The element command creates and manipulates general-purpose "elements", which are lines, rectangles, and text that have no inherent meaning to the database. They are positioned in units of the layout and so scale and move with zooms and pans. They are intended to be used for layout annotation, measurement rulers, user-defined feedback, flylines, wire paths, and so forth.

Implementation Notes:

element is implemented as a built-in magic command. The syntax is complicated and is expected to be driven by Tcl scripts with simpler syntax for specific purposes such as annotation or measurement rulers.

Return to command index

Last updated: October 5, 2004 at 6:32am

magic-8.0.210/doc/html/straighten.html0000644000175000001440000000314510751423606016230 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

straighten


Straighten jogs by pulling in direction

Usage:

straighten direction

where direction is any valid Manhattan direction in magic.

Summary:

The straighten command attempts to straighten jogs in wire paths. It is part of the plow method, and helps to clean up areas that have been altered using the plow command.

Implementation Notes:

straighten is implemented as a built-in command in magic.

See Also:

plow

Return to command index

Last updated: October 8, 2004 at 8:34pm

magic-8.0.210/doc/html/cellname.html0000644000175000001440000001415310751423606015641 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

cellname


Operations on cell definitions.

Usage:

cellname option

where option is one of the following:
[list] children [name]
List all of the children definitions of cell name, or the children of the currently selected cell instance.
[list] parent [name]
List the parent cell definition of cell name, or the parent of the currently selected cell instance.
[list] exists|self [name]
Returns the name of the cell if the cell exists, or false (0) if the cell does not exist (is not loaded into the database; the cell may still exist on disk). If name is not present, returns the name of the currently selected cell.
[list] allcells
List all of the cells in the database. Note that expansion is not automatic, so cells that are not expanded are not searched.
[list] topcells
List the name of the top-level cell or cells. Note that the cells are searched in the whole database, so multiple cells may be returned, regardless of what cell is the topmost cell in the layout window. For that, use cellname window (see below).
[list] window
List the name of the topmost cell in the window. If only one window exists, it is implicit. If more than one window exists, the command operates on the window from which the command was called if the ":" macro was used to invoke the command. Otherwise, the window can be specified as the command (q.v. tk_path_name).
create name
Create a new cell definition with name name. This is most often used with scripts, where it is not necessary or desirable to load the cell into the window. Note that this command does not search the layout search path for a cell named name.mag, so it can be used to replace a cell which exists on disk but is not currently loaded.
rename name newname
Change the name of the cell definition name to newname.
delete name
Delete the cell definition with name name. If cell name is a descendent of another cell, the command will be prohibited. If the cell name is currently the topmost cell in the window, the window will be loaded with default cell "(UNNAMED)".
flags
Reports flag settings for the cell. Flags which are reported are "available", "modified", and "readonly". Flag "available" is true if the cell has been loaded into the database. Flag "modified" is true if layout changes have been made to the cell. Flag "readonly" is true if the cell has been locked to prevent edits.
writeable [true|false]
Option writeable false makes the current cell read-only and therefore prevents any edits from being written to disk. If magic is compiled with file-locking, then any advisory lock on the file is released. Option writeable true makes the current cell read-write. If magic is compiled with file-locking, then magic attempts to grab an advisory lock on the file. If a lock is already held on the file, then the command cannot be executed, and the cell remains read-only. Option writeable with no other arguments returns the state of the cell (roughly equivalent to cellname flags readonly).

Summary:

The cellname command performs various operations on cell definitions. For the first four options listed above, cellname lists cells by their relationship to cell name, or to the current selection if no name is given. The optional argument list returns the result as a list. In particular, in the Tcl version of magic, this list is a Tcl result that may be operated on by Tcl procedures.

Implementation Notes:

cellname is implemented as a built-in function in magic The Tcl version of magic returns Tcl results when the "list" option is present. instance is essentially an alias for the cellname command, and takes the same options, but references are to cell instances rather that cell definitions (q.v.).

The command option cellname list exists is nonsensical from the standpoint of the end-user (if the cell is selected, of course it exists). However, it is a very useful function for Tcl scripts to determine the name of the cell that is currently selected.

The cellname command replaces a number of commands that briefly appeared in version 7.1, such as parent, child, and top. These commands are now options of the cellname and instance commands.

See Also:

instance
load
tk_path_name

Return to command index

Last updated: December 4, 2005 at 5:38pm

magic-8.0.210/doc/html/pushbox.html0000644000175000001440000000310210751423606015541 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

pushbox


Save the cursor box position on a stack for later restoring.

Usage:

pushbox

Summary:

The pushbox command saves the position of the cursor box onto a stack, where it may be retrieved or queried using the popbox and peekbox commands, respectively.

Implementation Notes:

pushbox is implemented as a Tcl procedure in the "tools" script. It is useful when writing automated layout-generating Tcl scripts.

See Also:

popbox
peekbox

Return to command index

Last updated: October 7, 2004 at 6:00am

magic-8.0.210/doc/html/irsim.html0000644000175000001440000000511610751423606015203 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

irsim


Invoke the irsim switch-level digital simulator.

Usage:

irsim [args]

where args are any arguments to be passed to the irsim program as they would from the command line. See the irsim documentation for an explanation of its valid command-line arguments.

Summary:

The irsim command starts the irsim simulator. While previous versions of magic did this by forking the irsim process, Tcl-based magic can load the Tcl-based irsim as a package directly into the interpreter. Commands for irsim are added to the Tcl namespace and are available directly from the the magic command line.

As a Tcl script, the irsim command attempts to set up the simulation arguments to ensure proper startup. It also checks for a valid .sim file matching the layout, and generates one if it does not already exist.

A number of commands are available for viewing signal values directly on the layout. For a complete description of these commands and the Tcl-based irsim simulation environment, see the documentation on irsim.

Implementation Notes:

irsim is implemented as a Tcl procedure that loads the Tcl-package based version of irsim, then executes its startup procedure. The irsim Tcl package itself is compiled and installed separately from magic.

See Also:

ext2sim

Return to command index

Last updated: October 7, 2004 at 1:01am

magic-8.0.210/doc/html/redraw.html0000644000175000001440000000267710751423606015355 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

redraw


Redraw the display.

Usage:

redraw

Summary:

The redraw command completely redraws the layout window. Normally, magic records regions that require updating and redraws those portions of the layout. However, key and button events are allowed to interrupt the redraw, so on occasion it may be necessary to force a refresh of the display.

Implementation Notes:

redraw is implemented as a built-in window command in magic.

Return to command index

Last updated: October 8, 2004 at 1:07am

magic-8.0.210/doc/html/pushbutton.html0000644000175000001440000000362110751423606016272 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

pushbutton


Emulate a mouse button event.

Usage:

pushbutton button action

where button is one of left, middle, or right, and action is is one of up or down.

Summary:

The pushbutton command is a way of invoking the actions associated with mouse buttons from the command-line, or from a Tcl script.

Implementation Notes:

pushbutton is implemented as a built-in window command in magic. However, it is functionally equivalent to calling the Tk function event generate.

Bugs:

This is all backwards! There should be commands implemented to generate the actions that are caused by button pushes in each tool, and these commands should be bound to the button events. Presumably the existing setup is a holdover from pre-X11 days.

Return to command index

Last updated: October 8, 2004 at 12:44am

magic-8.0.210/doc/html/color/0000755000175000001440000000000011504623573014307 5ustar timusersmagic-8.0.210/doc/html/color/load.html0000644000175000001440000000463310751423606016120 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

load


Load an alternate layer colormap.
load [techStyle displayStyle monitorType]

Usage:

load [techStyle displayStyle monitorType]

where techStyle is declared by the technology (normally "mos"), displayStyle is determined by the display visual (normally "7bit", "24bit", or "OpenGL"), and monitorType is normally "std".

Summary:

The load command loads an alternative colormap file that can be used to change the colors used by magic for drawing layout.

By default, without arguments, the filename searched for varies according to the display visual type, but is normally

mos.24bit.std.cmap for 24- and 32-bit visuals, mos.7bit.std.cmap for 8-bit visuals, and mos.OpenGL.std.cmap for OpenGL visuals.
The current directory is searched first for local files overriding the system colormap defaults, followed by a search of the sys path as declared by the path command.

Implementation Notes:

load is implemented as a built-in color window command in magic. It can only be invoked from a window created with the specialopen color command.

See Also:

save
path

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/color/save.html0000644000175000001440000000477010751423606016141 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

save


Save the layer colormap to a file.

Usage:

save [techStyle displayStyle monitorType]

where techStyle is the type of "dstyle" file requested by the technology (normally "mos"), displayStyle is the type of display (normally NULL, but when specified should be "24bit", "8bit", or "OpenGL" to match the type of display), and monitorType is typically "std".

Summary:

The save command saves the contents of the color map in a file that can be retrieved with the color window load command. This file is saved in the current working directory and has the format
techStyle.displayStyle.monType.cmap
Without arguments, the default colormap filename varies according to the display type, but is normally one of:
mos.24bit.std.cmap for 24- and 32-bit display visuals
mos.7bit.std.cmap for 8-bit display visuals
mos.OpenGL.std.cmap for OpenGL displays
Note that for the colormap to be read by magic on startup, the filename format above must be adhered to.

Implementation Notes:

save is implemented as a built-in color window command in magic. It can only be invoked from a window created with the specialopen color command.

See Also:

load

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/color/color.html0000644000175000001440000000572610751423606016323 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

color


Specify color to edit, or print intensities of the currently edited color

Usage:

color [number|next|last|get|rgb]

where number is the number of a color in the colormap list. Historically, this number was given in octal. This has been changed to the variable format of C syntax, in which numbers are treated as decimal unless beginning with "0" (zero), in which case they are treated as octal, or "0x" (zero-x), in which case they are treated as hexidecimal.

Summary:

The color command specifies the color number to edit in the colormap window. With no arguments, prints the color index and RGB values for the color being edited.

In the Tcl-based version of magic, the "color picking" and "color copying" functions are no longer functional. For this reason, options color next and color last have been added to allow scrolling through the colors in the colormap. These commands are bound to the key macros "+" (plus) and "-" (minus), respectively.

Options color get and color rgb return subsets of the information reported by color with no arguments. color get returns the color index of the color, and color rgb returns the individual red, green, and blue intensities of the color. In the Tcl-based version of magic, these values are returned as Tcl results.

Note that color changes made in the color window do not immediately take effect on the layout. It is necessary to pass a refresh command to the layout window, or to type the Control-L macro in the layout window to update the colors.

Implementation Notes:

color is implemented as a built-in color window command in magic. It can only be invoked from a window created with the specialopen color command.

Return to command index

Last updated: October, 2004

magic-8.0.210/doc/html/color/pushbutton.html0000644000175000001440000000407210751423606017411 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

pushbutton


Execute the default function associated with a mouse button event.

Usage:

pushbutton button

where button is one of left, middle, or right.

Summary:

The pushbutton command invokes the function "traditionally" associated with the indicated mouse button. However, in Magic-7.3, button actions are treated as macros, and so the button macros are defined, by default, to call the pushbutton command for the indicated button. The button actions no longer recognize button-up events. The action taken depends on where in the color window the button was pressed. Actions are defined for pressing the button in one of the six color bars or the "plus" and "minus" buttons on each side of each color bar, and changes the color components of the current edit color accordingly.

Implementation Notes:

pushbutton is implemented as a built-in color window command in magic. It overrides the default window client pushbutton command.

Return to command index

Last updated: November, 2004

magic-8.0.210/doc/html/tag.html0000644000175000001440000001055410751423606014635 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

tag


Register a tag callback command.

Usage:

tag command_name [procedure]

where command_name is the name of any magic command, and procedure is any valid Tcl procedure.

Summary:

The tag command is registers callback procedures to be executed after the indicated magic command has been executed. The primary use of the tag command is to register procedures that update the GUI window in response to commands that are typed on the command line or generated from macro calls.

In keeping with standard methods for Tcl callback functions, certain "escape sequences" beginning with the percent ("%") character are allowed to be embedded in the callback function procedure, and are substituted prior to execution, with the substitutions defined as follows:

%W
Substitute the Tk path of the layout window from which or in reference to which command_name was invoked.
%r
Substitute the previous Tcl result string, but do not reset the Tcl result of the execution of procedure.
%R
Substitute the previous Tcl result string and reset the Tcl result from the execution of procedure such that the the result of command_name becomes the result of procedure.
%[0-5]
Substitute the zeroth to fifth argument to the original command.
%%
Substitute a single percent character.
%char
where char is any character not defined above: No action, print exactly as written.
When a tag callback is used, the return value seen by the interpreter is the return value of the function procedure, not the return value of the tagged command command_name. The escape sequence %R can be used to force the result of command_name to become the result of procedure (unless procedure produces an error condition, in which case the error is returned). The escape sequence %r passes the result of command_name as an argument to the procedure, which may choose to return it as a result, or not.

If no procedure is present, then the tag command returns whatever procedure string is attached to the indicated command_name, if any. This can be used as a way to prevent infinite recursion inside a tag callback; for example,

set savetag [tag callback command]
(procedure calls, which may include a call to command)
tag command $savetag
Another way to avoid infinite recursion is to check the procedure depth from within the tag callback procedure using the Tcl command "info level", to avoid executing the callback procedure if the level is not zero.

Only one tag callback is allowed per command name. However, only one is needed as that procedure may call as many other procedures as it wants to.

Implementation Notes:

tag is implemented as a built-in command in magic, but only in the Tcl version.

Return to command index

Last updated: October 8, 2004 at 10:15pm

magic-8.0.210/doc/html/instance.html0000644000175000001440000000716210751423606015667 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

instance


Operations on cell instances (uses).

Usage:

instance option

where option is one of the following:
[list] children [name]
List all of the children definitions of cell use name, or the children of the currently selected cell instance.
[list] parent [name]
List the parent cell definition of cell use name, or the parent of the currently selected cell instance.
[list] exists|self [name]
Returns the name of the instance if the cell exists, or false (0) if the instance does not exist (is not loaded into the database; the cell may still exist on disk). If name is not present, returns the name of the currently selected instance.
[list] allcells
List all of the cell instances in the database. Note that expansion is not automatic, so cells that are not expanded are not searched.

Summary:

The instance command performs various operations on cell uses, or instances. For the first four options listed above, instance lists cells by their relationship to cell use name, or to the current selection if no name is given. The optional argument list returns the result as a list. In particular, in the Tcl version of magic, this list is a Tcl result that may be operated on by Tcl procedures.

Implementation Notes:

instance is implemented as a built-in function in magic The Tcl version of magic returns Tcl results when the "list" option is present. instance is essentially an alias for the cellname command, and takes many of the same options, but references are to cell instances rather that cell definitions (q.v.). A number of options to cellname are meaningless for instances.

The command option instance list exists is nonsensical from the standpoint of the end-user (if the cell is selected, of course it exists). However, it is a very useful function for Tcl scripts to determine the name of the cell instance that is currently selected.

Bugs:

Technically, instance rename should be implemented as a replacement for the command identify.

See Also:

cellname
load
tk_path_name

Return to command index

Last updated: October 8, 2004 at 8:06am

magic-8.0.210/doc/html/techmanager.html0000644000175000001440000000417510751423606016342 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

techmanager


Generate the technology manager GUI window.

Shortcuts:

Menu item Options->Technology manager implements the command techmanager.

Usage:

techmanager

Summary:

The techmanager command generates the "technology manager" GUI window (see Figure 1 below). This window shows the current technology along with its version and description strings shows the internal grid scaling, the current and available CIF/GDS input and output styles, and the current and available extraction styles. It also shows the known technology files by searching the system search path (see the command path for more information). It allows a new technology to be loaded, or the CIF/GDS and extraction styles to be changed, as well as allowing internal grid rescaling by specifying the internal units per lambda.


Figure 1. The technology manager GUI window.

Implementation Notes:

techmanager is implemented as a Tcl procedure in the "wrapper" script.

Return to command index

Last updated: October 8, 2004 at 11:09pm

magic-8.0.210/doc/html/xload.html0000644000175000001440000000322210751423606015163 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

command_name


Load a cell into a window unexpanded

Usage:

xload cellname

where cellname is the name of a layout cell in the database memory or on disk.

Summary:

The xload command works exactly like the load command, but keeps the top-level cell cellname unexpanded. This can be useful for large layouts where the expanded view takes a long time to redraw.

Implementation Notes:

xload is implemented as a built-in command in magic.

See Also:

load
xview

Return to command index

Last updated: October 9, 2004 at 7:17am

magic-8.0.210/doc/html/select.html0000644000175000001440000001427210751423606015342 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

select


Select or unselect portions of the layout according to the options, or create a new cell definition from a selection.

Shortcuts:

Key macro , (comma) implements the command select clear.
Key macro s implements the command select.
Key macro S implements the command select more.
Key macro Control-S implements the command select less.
Key macro a implements the command select visible.
Key macro A implements the command select more visible.
Key macro Control-A implements the command select less visible.
Key macro i implements the command select cell.
Key macro I implements the command select more cell.
Key macro Control-I implements the command select less cell.

Usage:

select option

where option may be one of the following:
[more | less] [layers]
[De]select material under cursor, or [de]select a subcell if the cursor is over space.
nocycle [layers]
Select material without cycling through different tile types when "select" is called from the same cursor position more than once.
[more | less] area [layers]
[De]select all material under box in layers layers
[more | less] visible [layers]
[De]select all visible material under box in layers layers.
[more | less] box [layers]
[De]select material specified by the boundary of the cursor box
[more | less] chunk [layers]
[De]select a network chunk (largest rectangle) specified by the lower left corner of the cursor box
[more | less] region [layers]
[De]select a network region specified by the lower left corner of the cursor box
[more | less] net [layers]
[De]select an entire electrical network specified by the lower left corner of the cursor box
[more | less] cell [name]
[De]select the cell under cursor, or the cell use (instance) named name.
top cell
Select the topmost cell in the window, which does not have an instance name and therefore cannot be selected with the select cell command.
save cell
Save selection as cell named cell, which is also saved to disk as cell.mag.
clear
Clear selection
pick
Remove the selection from the layout, but retain the selection buffer for interactive processing.
keep
Copy the selection from the layout into the selection buffer, and keep the selection buffer for interactive processing.
move x y
Move the selection buffer to position x y, relative to the cell definition origin.
help
Print help information

Summary:

The select command changes what material is in the current selection. magic maintains a separate cell definition that represents the current selection. Without the options more or less, the selection is cleared prior to executing the new selection command. Otherwise, more adds to the existing selection and less subtracts from it.

Network selection differs from other types of selection in that magic uses a sophisticated algorithm to determine what is electrically connected together throughout the layout. A chunk is the largest rectangle containing a single layer type. A region is the largest network area containing a single layer type. The region stops where the net connects to a different layer type. The net is the entire electrical network.

The select save options differs from the rest in that it does not alter the current selection, but creates a new cell definition from the current selection. Note that this cell is created as a top-level cell, and does not replace the current selection as a use in the edit cell. To do that requires "select save cell" followed by "delete" and "getcell child 0 0 parent 0 0". The last command syntax is used because the bounds of the selection may differ from the cursor box.

Implementation Notes:

select is implemented as a built-in command in magic. The select keep, select move, and select pick are interactive functions used by the "pick" tool.

Bugs:

To be consistent, select save should be a separate command, since like other commands it operates on the selection rather than alter what is in the selection.

Return to command index

Last updated: December 4, 2005 at 5:06pm

magic-8.0.210/doc/html/delete.html0000644000175000001440000000247410751423606015326 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

delete


Delete everything in selection

Shortcuts:

Key macro d implements the command delete.

Usage:

delete

Summary:

The delete command deletes whatever cells and paint are in the current selection.

Implementation Notes:

delete is implemented as a built-in magic command.

Return to command index

Last updated: October 6, 2004 at 12:48am

magic-8.0.210/doc/html/findbox.html0000644000175000001440000000340210751423606015505 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

findbox


Center the window on the box and optionally zoom in.

Shortcuts:

Key macro B implements the command findbox.
Key macro Control-Z implements the command findbox zoom.

Usage:

findbox [zoom]

Summary:

The findbox command centers the window on the cursor box. This is particularly useful in conjunction with other commands such as drc find or feedback find that may move the box to an unknown off-screen location. With the option zoom, the window view will be centered on the cursor box and additionally scaled so that the cursor box fills the window.

Implementation Notes:

findbox is implemented as a built-in command in magic.

Return to command index

Last updated: October 6, 2004 at 1:46am

magic-8.0.210/doc/html/addpath.html0000644000175000001440000000442210751423606015464 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

addpath


Append to current search path

Usage:

addpath [path]

where path is the path of a directory to add to the list of directories searched for layout cells, relative to the current working directory.

Summary:

The addpath command is used to control which directories magic searches when attempting to read an undefined cell. It can only be used to append new directories to the existing search path (see below). This command is most often used when groups of subcells such as a standard-cell library or padframe library is kept in a separate place from the rest of the layout. In such cases it is convenient to put this command in the .magic file in the layout directory to ensure that all cells required by the layout are accessible at runtime.

Implementation Notes:

addpath is a magic built-in command. It is retained for backwards compatibility, but is superceded by the path command, which allows complete control over the layout search path contents, as well as other search paths used by magic.

See Also:

path
getcell

Return to command index

Last updated: October 3, 2004 at 6:53am

magic-8.0.210/doc/html/polygon.html0000644000175000001440000000461210751423606015547 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

polygon


Generate polygons from the command line.

Shortcuts:

None.

Usage:

polygon type x1 y1 x2 y2 ... xn yn

where type is a tile type to draw, and x1 y1 ... xn yn are n vertices of a polygon.

Summary:

The polygon command allows generation of polygons on the layout from the command line, similarly to the wire segment command. The polygon command automatically generates the proper tile geometry for the polygon as specified by vertices. Vertex points are pairs of X Y coordinates, and may take any dimensional value (default lambda, but may be internal units or metric units). Note that polygons should be convex; the tile generation algorithm is not guaranteed to work with non-convex geometries.

While simple non-Manhattan structures (triangles) can be generated with the "splitpaint" and "spliterase" commands using macros, there is no convenient interactive method for generating complex polygon geometry. The polygon command is best used in scripts to create specific patterns based on known geometry.

Implementation Notes:

polygon is implemented as a built-in command in magic.

See Also:

wire

Return to command index

Last updated: December 4, 2005 at 8:39pm

magic-8.0.210/doc/html/exttospice.html0000644000175000001440000001617310751423606016254 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

ext2spice, exttospice


Convert extracted file(s) to a SPICE format file.

Usage:

ext2spice [option]

where option is one of the following:
[run] [runtime_options]
Run ext2spice on current cell, with command-line options (see Summary, below).
default
Reset to default values
format hspice|spice2|spice3
Set output format. spice3 is the default, for compatibility with tclspice. This is a change from previous versions of magic, where the default was hspice.
rthresh [value]
Set resistance threshold value. Lumped resistances below this value will not be written to the output. The value is in ohms, or may be the keyword infinite to prohibit writing any lumped resistances to the output.
cthresh [value]
Set capacitance threshold value. The value is in femtofarads, or may be the keyword infinite to prohibit writing any parasitic capacitances to the output.
merge [merge_option]
Merge parallel devices/transistors. The valid merge options are:
conservative
Merge transistors and capacitors having the same device type and node connections and having the same width and length. Widths are summed in the final output for transistors. Capacitor values are summed in the final output.
aggressive
Merge transistors having the same node connections and having the same length. Widths are summed in the final output. Merge any capacitors having the same device type and node connections. Capacitance is summed in the final output.
none
Do not merge any devices.
extresist on|off
Incorporate output from the command extresist into the final SPICE file.
resistor tee [on|off]
Model resistor capacitance as a T-network. Each resistor device is split into two, with all substrate and overlap capacitance placed on the node between the two half-length devices. Without this option, resistor devices lose all parasitic capacitance information, and ext2spice may produce warnings about unknown nodes. However, use of this option may conflict with LVS (layout-vs.-schematic), when only one resistor is expected per drawn device.
subcircuits [on|off]
When set to on (the default), standard cells become subcircuit calls ("X") in the SPICE output. The contents of the standard cells are not output, and it is assumed that a pre-characterized SPICE deck exists modeling the behavior of each standard cell definition. Standard cells are defined by the use of the port method for labeling input and output ports. When set to off, ports are ignored, and the entire circuit hierarchy is flattened down to the device level.
help
Print help information.

Summary:

Without options, or with the option run, the ext2spice command converts the hierarchical extracted netlist information produced by the extract command in a series of .ext files into a flattened representation in SPICE format, used for detailed analog simulation.

runtime_options may be passed on the command line, and represent the original command-line options passed to the standalone version of ext2spice. A number of the original command-line options have been deprecated in the Tcl-based version, and some are duplicated by other ext2spice options. Valid runtime_options are:

-B
Don't output transistor or node attributes in the SPICE file. This option will also disable the output of information such as the area and perimeter of source and drain diffusion and the FET substrate.
-F
Don't output nodes that aren't connected to devices (floating nodes).
-tchar
Trim characters from node names when writing the output file. char should be either "#" or "!". The option may be used twice if both characters require trimming.
-y num
Select the precision for outputting capacitors. The default is 1 which means that the capacitors will be printed to a precision of 0.1 fF.
-J hier|flat
Select the source/drain area and perimeter extraction algorithm. If hier is selected then the areas and perimeters are extracted only within each subcell. For each device in a subcell the area and perimeter of its source and drain within this subcell are output. If two or more devices share a source/drain node then the total area and perimeter will be output in only one of them and the other will have 0. If flat is selected the same rules apply, only the scope of search for area and perimeter is the whole netlist. In general, flat (which is the default) will give accurate results (it will take into account shared sources/drains).
With options, the command sets various parameters affecting the output format and content.

Implementation Notes:

ext2spice is implemented as a separate loadable Tcl package, but one which depends on the presence of the standard "tclmagic" package. magic is set up with a placeholder command for ext2spice, and will automatically load the Tcl package when this command is invoked.

exttospice is an alias for ext2spice, to satisfy the grammatically anal retentive.

See Also:

extract
ext2sim

Return to command index

Last updated: October 12, 2005 at 9:40pm

magic-8.0.210/doc/html/down.html0000644000175000001440000000335610751423606015033 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

down


Load selected cell into a window

Usage:

down

Summary:

The down command loads the currently selected cell into the window. If more than one cell is selected, the one closest to the cursor (pointer) position will be used, or at worst, one will be selected arbitrarily.

Implementation Notes:

down is implemented as a built-in window command in magic. In the Tcl version of magic, it is generally deprecated in favor of the scripted Tcl procedure pushstack, and the "tools" script implementation of the ">" macro to invoke pushstack on a selected cell.

See Also:

load
pushstack

Return to command index

Last updated: October 5, 2004 at 3:27am

magic-8.0.210/doc/html/what.html0000644000175000001440000000405310751423606015022 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

what


Print out information about what material is in the current selection. Short summary.

Shortcuts:

Key macro / (slash) implements the command what.

Usage:

what [-list]

Summary:

The what command queries what material is in the current selection. This includes a report on layers, labels, and subcell instances that are selected.

In the Tcl version of magic, the -list option returns the result as a Tcl list containing three sub-lists. The first sub-list contains the types found, the second contains the labels found, and the third contains the subcells found. Each label in the second sub-list is itself a list of three items: The label text, the layer the label is attached to, and the cell def containing the label. Each subcell in the third sub-list is itself a list of two items: The subcell instance ID name, and the cell definition name.

Implementation Notes:

what is implemented as a built-in command in magic.

Return to command index

Last updated: October 15, 2004 at 6:25am

magic-8.0.210/doc/html/edit.html0000644000175000001440000000244510751423606015007 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

edit


Use selected cell as new edit cell

Shortcuts:

Key macro e implements the command edit.

Usage:

edit

Summary:

The edit command makes the selected cell the new edit cell.

Implementation Notes:

edit is implemented as a built-in magic command.

Return to command index

Last updated: October 6, 2004 at 12:55am

magic-8.0.210/doc/html/search.html0000644000175000001440000001015010751423606015317 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

search


Execute a TCL procedure on each tile in the current edit cell definition.

Usage:

search [layers] procedure

where layers is a comma-separated list of layer types to generate a mask to limit the tile search, and procedure is the name of a predefined Tcl procedure (see Summary, below).

Summary:

The search command is a method for user access to the magic database search routines. It searches the tile database of the current edit cell definition and its hierarchy of descendents and applies the callback procedure to each. The callback procedure must be defined as described below.

Note that the callback method into Tcl is inherently slow and should only be used for non-compute-intensive tasks. In particular, unless it is known that the cell definition being traversed has relatively few structures, the layers argument should be used to severely limit the scope of the search. This function can be useful in certain situations, such as parsing a layout for layer "pad" to enumerate the number of pads in a design.

The Tcl callback procedure is passed five values, the four coordinates of the tile, and the layer type of the tile. The procedure must be defined to accept these five arguments, as in the following example:

	proc tile_callback {llx lly urx ury ttype} {
	   puts stdout "Tile type $ttype at $llx $lly $urx $ury"
        }
     
When non-manhattan tiles are parsed, the type $ttype is passed as a list of two string elements, the type on the left side of the diagonal split, and the type on the right side of the diagonal split.

Implementation Notes:

search is implemented as an internal magic command that links to an external Tcl procedure as a callback function. This routine is experimental and subject to change without notice.

Bugs:

As currently implemented, there is no protection against calling a magic command from the callback procedure that will alter the internal tile structures while the tile plane is being traversed, causing a crash. The implementation should be changed to a 2-step procedure that traverses the tile plane first, creating an internal list of function arguments to pass for each tile, and then executes the callback function on each.

There are more efficient ways of executing the callback function than Tcl_EvalEx(). In particular, the procedure should be cast as a Tcl object and Tcl_EvalObjEx() used.

The callback function should allow in-line Tcl procedures and use the standard Tcl/Tk method of "%" escape sequences used as arguments to the callback function that allow the user to specify what arguments are passed to the callback function (as is done for the tag command).

See Also:

cellsearch

Return to command index

Last updated: October 4, 2004 at 5:05am

magic-8.0.210/doc/html/unexpand.html0000644000175000001440000000320010751423606015672 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

unexpand


Unexpand everything inside or touching the cursor box.

Usage:

unexpand

Shortcuts:

Key macro X implements the command unexpand.

Summary:

The unexpand command unexpands the view of subcells to hide the contents of the subcells and show the bounding box outline only. The unexpand command unexpands all subcells that touch or intersect the cursor box in the layout window.

Implementation Notes:

unexpand is implemented as a built-in magic command.

See Also:

expand

Return to command index

Last updated: October 16, 2004 at 1:58pm

magic-8.0.210/doc/html/spliterase.html0000644000175000001440000000510210751423606016226 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

spliterase


Paint into the cursor box, splitting the box diagonally with one layer forming a right triangle in one corner and space or another layer in the other.

Usage:

spliterase dir layer

where dir is a valid non-Manhattan direction indicating the direction of the right angle corner of the right triangle to be erased. Any paint of layer type layer is erased from this triangular area.

Summary:

The spliterase command implements a form of non-Manhattan geometry that conforms to the corner-stitched tile database format used by magic for painting and searching operations in a plane. It lets a rectangular area, as defined by the position of the cursor box, be split diagonally, with one half containing one layer type, and the other half containing another. While the splitpaint command generates non-Manhattan areas by adding paint in a triangular area, spliterase creates non-Manhattan areas by subtracting paint from a triangular area.

Note that spliterase, like splitpaint, is somewhat cumbersome to use; to generate diagonal wires, use the wire segment command instead, which is also able to compute mitred joints between segments at different angles.

Implementation Notes:

spliterase is implemented as a built-in command in magic.

See Also:

splitpaint
wire

Return to command index

Last updated: October 8, 2004 at 7:41am

magic-8.0.210/doc/html/findlabel.html0000644000175000001440000000320010751423606015770 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

findlabel


Set the cursor box to the location of the indicated label

Usage:

findlabel label [-glob]

where label is the name of an existing label in magic.

Summary:

The findlabel command can be used to center the cursor box on a specific named label in the layout.

The -glob option causes findlabel to find all labels containing the text pattern of label. This is the way the findlabel command worked in versions of magic prior to 7.2.

Implementation Notes:

findlabel is implemented as a built-in command in magic.

Return to command index

Last updated: November 7, 2004 at 3:32pm

magic-8.0.210/doc/html/redo.html0000644000175000001440000000356510751423606015017 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

redo


Redo commands

Shortcuts:

Key macro U implements the command redo.

Usage:

redo [print [count]]

where count indicates a number of events to be redone (default 1 event), and must be a nonzero positive integer.

Summary:

The redo command reverses the effect of an undo command, returning the layout in a specific window to the state it was in prior to execution of the undo command.

The print option allows stack tracing for the redo command, printing the top count events on the event stack in excruciating detail.

Implementation Notes:

redo is implemented as a built-in window command in magic.

See Also:

undo

Return to command index

Last updated: October 15, 2004 at 5:54am

magic-8.0.210/doc/html/zoom.html0000644000175000001440000000405310751423606015043 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

zoom


Zoom window by specified magnification factor.

Shortcuts:

Key macro z implements the command zoom 0.5 (zoom out by a factor of 2).
Key macro Z implements the command zoom 2 (zoom in by a factor of 2).

Usage:

zoom factor

where factor is any real value. Values larger than 1 indicate a zoom in, while values smaller than 1 indicate a zoom out.

Summary:

The zoom command implements view scaling in the layout window in and out by the indicated magnification factor.

Note that several other commands effect a change in the view scale factor, including findbox zoom and view with coordinate arguments.

Implementation Notes:

zoom is implemented as a built-in window command in magic.

See Also:

center
view
findbox

Return to command index

Last updated: October 9, 2004 at 7:23am

magic-8.0.210/doc/html/resumeall.html0000644000175000001440000000405510751423606016052 0ustar timusers Magic-7.3 Command Reference

Magic VLSI Layout Tool Version 7.3 *

resumeall


Resume normal display refresh on all windows.

Usage:

resumeall

Summary:

The resumeall command is a script that invokes the command update resume on all layout windows. It is used in conjunction with the suspendall command and is intended for use in Tcl scripts that perform multiple manipulations on layout in a window, where it is desired to have the entire display refresh at one time at the end of the script rather than for each command within the script.

Because calls to update can be nested, calls to suspendall and resumeall are likewise nested. The resumeall command will have no effect until the same number of resumeall calls has been encountered as the number of suspendall calls made.

Implementation Notes:

resumeall is implemented as a Tcl procedure in the "tools" script.

See Also:

update
suspendall

Return to command index

Last updated: October 8, 2004 at 1:25am

magic-8.0.210/doc/psfiles/0000755000175000001440000000000011504623573013672 5ustar timusersmagic-8.0.210/doc/psfiles/tuttcl1.ps0000644000175000001440000014157010751423606015644 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software %%Title: tuttcl1.dvi %%Pages: 9 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman Courier %%+ Times-BoldItalic %%EndComments %DVIPSWebPage: (www.radicaleye.com) %DVIPSCommandLine: dvips -t letter tuttcl1.dvi -o ../psfiles/tuttcl1.ps %DVIPSParameters: dpi=600, compressed %DVIPSSource: TeX output 2006.04.12:1204 %%BeginProcSet: texc.pro %! /TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin /FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array /BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get }B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr 1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx 0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B /chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ /cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 {2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ 1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put }if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X 1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N /p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ /Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) (LaserWriter 16/600)]{A length product length le{A length product exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end %%EndProcSet %%BeginProcSet: 8r.enc % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndProcSet %%BeginProcSet: texps.pro %! TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type/integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics/Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{ dup sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[exch{dup CharStrings exch known not{pop/.notdef/Encoding true def} if}forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def} def end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tuttcl1.dvi) @start /Fa 135[50 2[55 28 39 39 1[50 50 55 78 28 2[28 55 50 1[44 50 44 50 50 9[89 1[72 61 55 5[89 3[39 1[72 1[66 72 66 66 7[33 3[50 50 50 1[50 50 3[33 45[{ TeXBase1Encoding ReEncodeFont}36 99.6264 /Times-BoldItalic rf %DVIPSBitmapFont: Fb cmsy10 12 2 /Fb 2 104 df102 D<12FEEAFFE0EA07F8EA00FEEB7F806D7E6D7E130F6D7EA26D7EB3AD6D7EA26D7E 806E7E6E7EEC0FE0EC03FC913800FFE0A2913803FC00EC0FE0EC3FC04A5A4AC7FC5C495A A2495AB3AD495AA2495A131F495A495A01FEC8FCEA07F8EAFFE048C9FC236479CA32>I E %EndDVIPSBitmapFont /Fc 134[50 50 72 50 55 33 39 44 1[55 50 55 83 28 55 1[28 55 50 33 44 55 44 55 50 3[33 1[33 3[100 2[66 55 2[61 78 1[94 66 2[39 78 78 61 66 72 72 66 72 6[33 2[50 50 50 50 1[50 50 50 28 25 33 1[57 50 5[50 33[55 2[{ TeXBase1Encoding ReEncodeFont}56 99.6264 /Times-Bold rf /Fd 135[60 60 60 60 60 60 60 1[60 60 60 60 60 60 1[60 60 60 60 60 60 60 60 60 10[60 1[60 1[60 2[60 60 60 4[60 60 1[60 60 60 60 60 3[60 1[60 60 3[60 1[60 1[60 60 60 60 60 60 60 2[60 60 40[{TeXBase1Encoding ReEncodeFont}49 99.6264 /Courier rf /Fe 105[50 1[44 44 24[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 33 6[72 72 94 1[72 61 55 66 1[55 72 72 89 61 72 39 33 72 72 55 61 72 66 66 72 1[44 3[28 28 50 50 50 50 50 50 50 50 50 50 28 25 33 25 2[33 33 33 1[83 1[50 1[33 29[55 55 2[{TeXBase1Encoding ReEncodeFont}78 99.6264 /Times-Roman rf /Ff 134[44 1[66 44 1[28 39 39 1[50 50 50 72 28 44 1[28 50 50 1[44 50 44 50 50 3[39 8[55 50 61 12[61 72 66 1[61 14[50 50 2[25 33 3[33 33 2[83 1[50 35[{TeXBase1Encoding ReEncodeFont}36 99.6264 /Times-Italic rf /Fg 134[72 72 104 1[80 48 56 64 1[80 72 80 120 40 80 1[40 80 72 48 64 80 64 80 72 9[143 2[96 80 5[135 3[56 1[112 88 96 104 104 96 2[72 4[48 3[72 72 72 72 72 72 3[48 36 8[72 35[{TeXBase1Encoding ReEncodeFont}44 143.462 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%BeginPaperSize: Letter letter %%EndPaperSize %%EndSetup %%Page: 1 1 1 0 bop 850 101 a Fg(Magic)35 b(Tcl)g(T)-13 b(utorial)34 b(#1:)44 b(Intr)m(oduction)1546 521 y Ff(R.)25 b(T)-5 b(imothy)24 b(Edwar)l(ds)1583 941 y Fe(Space)i(Department)1434 1062 y(Johns)e(Hopkins)g(Uni)n(v)o(ersity)1391 1182 y(Applied)g (Physics)g(Laboratory)1578 1303 y(Laurel,)h(MD)f(20723)819 1573 y(This)g(tutorial)g(corresponds)g(to)h(Tcl-based)f(Magic)h(v)o (ersion)e(7.2)0 2287 y Fg(1)143 b(What)36 b(is)f(Tcl-based)f(Magic,)h (and)g(Wh)n(y?)0 2511 y Fe(In)30 b(Magic)f(v)o(ersion)f(7.0,)i(Rajit)f (Manohar)g(incorporated)g(a)h(SCHEME)g(interpreter)f(into)g(the)g (Magic)g(source,)0 2631 y(noting)h(the)i(limitation)d(of)j(magic)f(to)g (handle)h(de\002nitions)e(and)i(v)n(ariables,)g(conditionals,)f(and)h (block)f(struc-)0 2752 y(tures.)56 b(By)33 b(embedding)f(an)h (interpreter)h(into)e(the)h(code,)i(the)e(interpreter')-5 b(s)33 b(functions)f(are)i(made)f(a)n(v)n(ailable)0 2872 y(on)k(the)h(magic)f(command)g(line,)k(making)36 b(magic)i(e)o (xtensible.)68 b(The)38 b(SCHEME)g(interpreter)f(and)h(v)n(arious)0 2992 y(e)o(xtensions)29 b(incorporated)i(into)f(loadable)h(scripts)f (are)i(outlined)e(in)g(the)h(tutorials)f Fd(tutscm1.ps)f Fe(through)0 3113 y Fd(tutscm4.ps)p Fe(.)146 3233 y(While)19 b(making)g(Magic)g(considerably)g(more)g(\003e)o(xible,)h(the)f (embedded)g(SCHEME)h(interpreter)f(had)h(some)0 3354 y(notable)25 b(dra)o(wbacks.)32 b(The)25 b(primary)g(one)g(is)g(that)g (the)g(SCHEME)g(language)g(is)g(syntactically)f(dif)n(ferent)h(from)0 3474 y(Magic')-5 b(s)33 b(command-line)f(syntax.)57 b(Also,)35 b(the)f(interpreter)g(is)f(lar)n(gely)h(disconnected)f(from)g(the)h (code,)i(and)0 3594 y(does)25 b(not)f(af)n(fect)h(or)g(e)o(xtend)f(the) g(graphics)h(or)g(handle)f(results)g(from)h(magic)f(commands.)146 3715 y(Be)o(ginning)h(in)g(Magic)g(v)o(ersion)f(7.2,)h(Magic)g(has)h (been)f(recast)h(into)f(a)g(frame)n(w)o(ork)g(called)h Ff(ScriptED)m(A)p Fe(,)d(in)0 3835 y(which)28 b(e)o(xisting)e (applications)h(become)h Fc(extensions)h Fe(of)f(an)g(interpreter)h (rather)f(than)g(ha)n(ving)g(an)g(interpreter)0 3955 y(embedded)22 b(in)f(the)h(application.)29 b(The)22 b(main)f(adv)n (antage)h(of)g(e)o(xtending)f(o)o(v)o(er)g(embedding)g(is)h(that)f(the) h(applica-)0 4076 y(tion)j(becomes)h(a)g(module)f(of)h(the)g (interpreter)g(language,)g(which)g(does)f(not)h(preclude)g(the)g(use)g (of)g(additional,)0 4196 y(unrelated)e(modules)f(in)h(the)h(same)f (interpreti)n(v)o(e)f(en)l(vironment.)29 b(F)o(or)24 b(e)o(xample,)g(in)g(Tcl-based)g(Magic,)g(graph-)0 4317 y(ics)31 b(are)h(handled)e(by)h(Tk)g(\(the)g(primary)f(graphics)h (package)h(for)f(use)g(with)f(Tcl\),)j(and)e(applications)e(such)i(as)0 4437 y(IRSIM)d(\(the)g(digital)e(simulator\))g(can)i(be)g(run)f(as)h (if)f(the)o(y)g(were)h(an)f(e)o(xtension)f(of)i(magic)f(itself.)38 b(Commands)0 4557 y(for)28 b(Tcl,)g(Tk,)g(IRSIM,)g(BL)-9 b(T)i(,)28 b(and)f(an)o(y)g(other)h(Tcl-based)f(package)h(can)g(be)g (mix)o(ed)e(on)h(the)h(magic)f(command)0 4678 y(line.)146 4798 y(While)g Ff(ScriptED)m(A)f Fe(suggests)g(the)h(use)h(of)f(the)h Fc(SWIG)e Fe(package)i(to)f(gi)n(v)o(e)f(applications)g(the)i(ability)e (to)h(be)0 4918 y(compiled)33 b(as)h(e)o(xtensions)e(of)i(an)o(y)f (interpreter)h(\(Tcl,)i(Python,)f(SCHEME,)f(Perl,)j(etc.\),)f(there)e (are)h(speci\002c)0 5039 y(adv)n(antages)24 b(to)h(tar)n(geting)g(Tcl.) 32 b(F)o(oremost,)24 b(the)h(syntax)f(of)h(Tcl)h(is)e(virtually)g (100\045)h(compatible)f(with)g(that)h(of)0 5159 y(Magic.)43 b(This)28 b(is)h(not)f(coincidentally)g(because)h(both)f(Magic)h(and)g (Tcl)g(were)h(written)e(by)h(John)f(Ousterhout!)0 5280 y(Man)o(y)23 b(ideas)h(from)g(the)g(de)n(v)o(elopment)e(of)i(Magic)g (were)h(incorporated)f(into)f(the)h(o)o(v)o(erall)f(concept)h(and)g (design)0 5400 y(of)h(the)g(Tcl)f(interpreter)h(language.)1875 5649 y(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Fe(April)24 b(12,)h(2006)1886 b(Magic)24 b(Tcl)h(T)l(utorial)e(#1:)30 b(Introduction)146 68 y(Lar)n(gely)19 b(due)g(to)g(the)f(syntactical)g(compatibility)-6 b(,)17 b(Tcl-based)i(magic)f(is)h(completely)e(backw)o(ardly-compatible)0 188 y(with)30 b(the)h(non-interpreter)f(v)o(ersion)g(of)h(magic.)49 b(Either)30 b(can)i(be)f(selected)g(at)g(compile-time,)f(in)h(addition) e(to)0 309 y(compiling)f(with)h(embedded)h(SCHEME,)g(which)f(has)h (been)g(retained)g(in)f(full)h(as)g(an)g(option.)44 b(A)30 b(fe)n(w)g(minor)0 429 y(issues,)24 b(such)g(as)g(the)h(appearance)g (of)g(the)f(cursor)g(when)h(magic)f(is)g(used)g(without)f(a)i(Tk)f (console)g(windo)n(w)-6 b(,)22 b(are)0 549 y(addressed)j(belo)n(w)-6 b(.)146 670 y(Magic)28 b(e)o(xtensions)d(under)j(Tcl)f(are)h (considerable,)g(and)g(e)o(xplanations)d(of)j(the)f(features)h(ha)n(v)o (e)g(been)f(split)0 790 y(into)d(se)n(v)o(eral)g(tutorial)g(\002les,)h (as)f(listed)g(in)h(T)-8 b(able)24 b(1.)p 837 916 2227 4 v 835 1036 4 121 v 887 1000 a(Magic)g(Tcl)h(T)l(utorial)e(#1:)30 b(Introduction)p 3061 1036 V 835 1156 V 887 1120 a(Magic)24 b(Tcl)h(T)l(utorial)e(#2:)30 b(The)25 b(GUI)g(Wrapper)p 3061 1156 V 835 1277 V 887 1241 a(Magic)f(Tcl)h(T)l(utorial)e(#3:)30 b(Extraction)24 b(and)h(Netlisting)p 3061 1277 V 835 1397 V 887 1361 a(Magic)f(Tcl)h(T)l(utorial)e(#4:)30 b(Simulation)24 b(with)g(IRSIM)p 3061 1397 V 835 1518 V 887 1481 a(Magic)g(Tcl)h(T)l(utorial)e(#5:)30 b(Writing)24 b(Tcl)h(Scripts)g(for)g(Magic)p 3061 1518 V 837 1521 2227 4 v 782 1788 a(T)-8 b(able)25 b(1:)30 b(The)25 b(Magic)f(Tcl)h (tutorials)f(and)g(other)h(documentation.)0 2241 y Fg(2)143 b(F)l(eatur)m(es)35 b(of)g(Tcl-based)f(Magic)0 2465 y Fe(In)22 b(summary)-6 b(,)21 b(the)h(features)g(of)g(Tcl-based)g(Magic) g(\(corresponding)f(to)h(Magic)g(v)o(ersion)f(7.2,)h(re)n(vision)e (31\))i(are)0 2585 y(as)j(follo)n(ws:)120 2797 y(1.)49 b(The)25 b(command)g(name)g Fc(magic)h Fe(itself)e(is)i(a)f(script,)h (not)f(a)g(compiled)g(e)o(x)o(ecutable.)32 b(The)25 b(script)g (launches)244 2917 y(Tcl)32 b(and)h(gi)n(v)o(es)e(it)h(the)h(name)f(of) h(a)g(Tcl)g(script)f(to)g(e)n(v)n(aluate)g(\()p Fd(magic.tcl)p Fe(\).)52 b(The)33 b(Tcl)g(script)f(loads)244 3038 y(Magic)k(as)g(an)h (e)o(xtension)e(of)h(Tcl)h(and)f(performs)g(all)g(other)h(operations)e (necessary)i(to)f(start)g(up)g(the)244 3158 y(application.)120 3357 y(2.)49 b(Command-line)31 b(ar)n(guments)g(passed)h(to)f(Magic)h (ha)n(v)o(e)f(been)i(changed.)52 b(Some)32 b(older)l(,)h(unused)f(ar)n (gu-)244 3478 y(ments)24 b(ha)n(v)o(e)g(been)h(remo)o(v)o(ed.)30 b(Se)n(v)o(eral)24 b(ar)n(guments)h(ha)n(v)o(e)f(been)h(added,)g(as)g (follo)n(ws:)299 3677 y(\(a\))49 b Fd(-noconsole)23 b Fe(Normally)-6 b(,)22 b(under)j(Tcl/Tk,)e(Magic)h(starts)g(by)g (launching)f(a)i(Tk-based)f(console)458 3798 y(windo)n(w)i(\()p Fd(tkcon.tcl)p Fe(\))f(which)i(is)f(the)h(windo)n(w)e(that)i(accepts)g (magic)f(commands.)36 b(Pre)n(vious)458 3918 y(v)o(ersions)27 b(of)i(Magic)f(accepted)g(commands)f(from)h(the)g(calling)g(terminal.) 40 b(The)28 b(former)h(style)e(of)458 4038 y(running)20 b(commands)g(from)g(the)h(calling)f(terminal)g(can)h(be)g(selected)g (by)f(choosing)g(this)g(ar)n(gument)458 4159 y(at)26 b(runtime.)32 b(Note,)25 b(ho)n(we)n(v)o(er)l(,)f(that)h(due)g(to)g (fundamental)g(dif)n(ferences)h(in)f(the)g(underlying)f(input)458 4279 y(routines)30 b(between)g(Tcl)g(and)h(magic,)g(the)f (terminal-based)g(command)f(entry)h(does)g(not)g(e)o(xactly)458 4400 y(match)38 b(the)g(original)f(beha)n(vior)g(of)h(magic.)70 b(In)38 b(particular)l(,)j(the)d(background)f(DRC)i(function)458 4520 y(does)27 b(not)g(change)g(the)g(prompt.)36 b(In)27 b(addition,)f(\223Xterm\224)h(consoles)g(must)e(select)i(option)f(\223) -8 b(Allo)n(w)458 4640 y(SendEv)o(ents\224)21 b(for)g(k)o(e)o(ystrok)o (es)f(to)g(be)h(echoed)g(from)g(the)g(layout)f(windo)n(w)g(into)g(the)h (terminal.)28 b(F)o(or)458 4761 y(security)d(reasons,)f(the)h (application)f(cannot)g(change)h(this)f(option)g(on)g(the)h(terminal.) 294 4918 y(\(b\))48 b Fd(-wrapper)22 b Fe(T)-8 b(o)23 b(enforce)h(backw)o(ard-compatibility)-6 b(,)20 b(magic)j(appears)h(as) f(it)f(w)o(ould)h(without)e(the)458 5039 y(Tcl)29 b(interpreter)f (\(apart)h(from)f(the)g(te)o(xt)f(entry)h(console\))g(when)g(launched)g (with)f(the)i(same)f(ar)n(gu-)458 5159 y(ments.)38 b(Ho)n(we)n(v)o(er)l (,)26 b(most)g(users)i(will)e(w)o(ant)h(to)g(mak)o(e)g(use)g(of)h(the)f (e)o(xtensions)e(and)j(con)l(v)o(enience)458 5280 y(functions)j(pro)o (vided)g(by)h(the)g(\223wrapper\224)h(GUI.)f(These)g(functions)f(are)i (detailed)f(in)f(a)i(separate)458 5400 y(tutorial)24 b(\(see)i(T)l(utorial)d(#2\).)1875 5649 y(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Fe(Magic)24 b(Tcl)h(T)l(utorial)f(#1:)30 b(Introduction)1885 b(April)24 b(12,)h(2006)120 68 y(3.)49 b(Magic-related)34 b(programs)h(\223e)o(xt2spice\224)f(and)g(\223e)o (xt2sim\224)g(ha)n(v)o(e)g(been)h(recast)g(as)g(magic)f(commands)244 188 y(instead)25 b(of)g(standalone)f(e)o(x)o(ecutables.)32 b(This)24 b(mak)o(es)h(a)h(good)e(deal)i(of)f(sense,)h(as)f(both)f (programs)h(mak)o(e)244 309 y(hea)n(vy)36 b(use)h(of)f(the)g(magic)g (internal)g(database.)66 b(Most)35 b(v)n(alues)h(required)g(to)g (produce)h(netlists)d(were)244 429 y(passed)28 b(through)f(the)h (intermediary)g(\002le)g(format)g Fd(.ext)p Fe(.)40 b(Ho)n(we)n(v)o(er) l(,)28 b(not)g(all)g(necessary)g(v)n(alues)f(were)244 549 y(included)d(in)g(the)g Fd(.ext)g Fe(\002le)h(format)f (speci\002cation,)h(and)f(some)g(of)h(these)f(missing)f(v)n(alues)h (were)h(hard-)244 670 y(coded)j(into)e(the)i(programs)f(where)h(the)o (y)f(ha)n(v)o(e)g(since)g(become)h(mismatched)e(to)h(the)h(magic)f (database.)244 790 y(This)g(has)h(been)g(corrected)g(so)g(that)f(all)h (netlist)e(output)h(corresponds)g(to)g(the)h(technology)f(\002le)h (used)f(by)244 911 y(a)e(layout.)244 1071 y(Both)g(commands)e(\223e)o (xt2spice\224)h(and)h(\223e)o(xt2sim\224)e(allo)n(w)h(all)h(of)f(the)h (command-line)e(ar)n(guments)i(pre)n(vi-)244 1192 y(ously)f(accepted)h (by)g(the)f(standalone)g(programs.)30 b(Some)25 b(of)g(the)g(more)f (common)g(functions,)g(ho)n(we)n(v)o(er)l(,)244 1312 y(ha)n(v)o(e)36 b(been)h(duplicated)e(as)i(command)e(options)g(in)h (the)g(usual)g(format)g(of)h(magic)f(commands.)64 b(F)o(or)244 1432 y(instance,)24 b(one)h(may)f(use)h(the)g(magic)f(command:)1144 1668 y Fc(ext2sim)g(help)244 1904 y Fe(to)g(get)h(more)g(information)e (on)h Fd(ext2sim)g Fe(command-line)f(options.)120 2105 y(4.)49 b(All)25 b(Tcl)g(interpreter)h(procedures)f(may)g(be)h(freely)g (mix)o(ed)e(with)g(magic)h(commands)g(on)g(the)g(command)244 2225 y(line.)53 b(F)o(or)32 b(instance,)i(a)e(user)h(can)g(use)f(Tcl)g (to)g(compute)g(arithmetic)f(e)o(xpressions)g(on)h(the)g(command)244 2345 y(line:)1144 2581 y Fc(copy)25 b(e)g([expr)p Fb(f)p Fc(276)g(*)g(5)g(+)f(4)p Fb(g)p Fc(])120 2817 y Fe(5.)49 b(A)31 b(number)g(of)h(magic)f(commands)f(pass)h(v)n(alues)f(back)i(to) f(the)g(interpreter)-5 b(.)50 b(F)o(or)32 b(instance,)g(the)f(com-)244 2937 y(mand)1144 3173 y Fc(box)25 b(v)o(alues)244 3409 y Fe(returns)j(the)g(lo)n(wer)f(left-)h(and)g(upper)g(right-hand)f (coordinates)h(of)g(the)g(cursor)g(box)f(in)h(magic)g(internal)244 3529 y(units.)h(This)23 b(return)g(v)n(alue)g(can)g(be)h(incorporated)f (into)f(an)i(e)o(xpression,)e(such)h(as)h(the)f(one)g(belo)n(w)g(which) 244 3649 y(mo)o(v)o(es)g(the)i(box)f(to)g(the)h(left)g(by)f(the)h(v)n (alue)f(of)h(its)f(o)n(wn)g(width:)1144 3885 y Fc(set)h(b)o(box)g([box) g(v)o(alues])1144 4005 y(set)g(bwidth)h(expr)f Fb(f)p Fc([lindex)h($b)o(box)f(2])g(-)g([lindex)g($b)o(box)g(0])p Fb(g)p Fc(])1144 4126 y(mo)o(v)o(e)g(e)g($bwidth)120 4362 y Fe(6.)49 b(Magic)34 b(prompts)e(for)j(te)o(xt)e(ha)n(v)o(e)g (been)i(recast)f(as)g(Tk)g(dialog)f(box)o(es.)57 b(F)o(or)34 b(instance,)i(the)e(command)244 4482 y Fc(writeall)f Fe(will)g(pop)g(up)h(a)g(dialog)e(box)i(with)f(\002)n(v)o(e)g(b)n (uttons,)h(one)g(for)g(each)g(of)g(the)f(a)n(v)n(ailable)g(choices)244 4602 y(\(write,)25 b(\003ush,)f(skip,)g(abort,)h(and)f(auto\).)120 4803 y(7.)49 b(IRSIM)33 b(is)e(no)g(longer)h(a)n(v)n(ailable)f(as)h(a)g (\223mode\224)g(reached)g(by)g(switching)e(tools)h(by)h(command)e(or)i (the)244 4924 y(space-bar)i(macro.)54 b(Instead,)35 b(IRSIM)f(\(v)o (ersion)e(9.6\))g(can)i(be)f(compiled)e(as)i(a)h(Tcl)e(e)o(xtension)g (in)g(the)244 5044 y(same)f(manner)h(as)g(Magic,)h(at)e(compile)g (time.)51 b(When)32 b(this)e(is)i(done,)h(IRSIM)f(is)f(in)l(v)n(ok)o (ed)g(simply)f(by)244 5164 y(typing)1144 5400 y Fc(irsim)1875 5649 y Fe(\2263\226)p eop %%Page: 4 4 4 3 bop 0 -180 a Fe(April)24 b(12,)h(2006)1886 b(Magic)24 b(Tcl)h(T)l(utorial)e(#1:)30 b(Introduction)244 68 y(on)36 b(the)g(Magic)f(command)g(line.)64 b(IRSIM)37 b(is)f(loaded)g(as)g(a)g (Tcl)g(package,)j(and)e(IRSIM)f(and)g(Magic)244 188 y(commands)23 b(may)i(be)g(freely)g(mix)o(ed)f(on)g(the)h(Magic)f(command)g(line:) 1144 481 y Fc(assert)h([getnode])244 775 y Fe(IRSIM)33 b(does)e(not)h(require)g(the)g(name)g(of)g(a)g(\002le)g(to)g(start.)52 b(W)l(ithout)30 b(ar)n(guments,)j(it)f(will)f(assume)g(the)244 895 y(currently)36 b(loaded)h(cell)g(is)f(to)h(be)f(simulated,)j(and)e (it)f(will)g(generate)h(the)g Fd(.sim)f Fe(\002le)h(if)g(it)f(does)h (not)244 1015 y(already)25 b(e)o(xist.)120 1256 y(8.)49 b(In)25 b(addition)g(to)g(IRSIM,)h(programs)f Fc(xcir)n(cuit)h Fe(and)g Fc(netgen)g Fe(can)g(be)g(compiled)e(as)i(Tcl)f(e)o(xtensions) f(and)244 1376 y(pro)o(vide)g(cabability)f(for)j(schematic)e(capture)h (and)g(layout-vs.-schematic,)e(respecti)n(v)o(ely)-6 b(.)120 1617 y(9.)49 b(Tcl-based)34 b(Magic)g(mak)o(es)h(use)f(of)h (the)f(Tcl)g(v)n(ariable)g(space.)61 b(F)o(or)34 b(instance,)i(it)e(k)o (eeps)h(track)g(of)f(the)244 1737 y(installation)28 b(directory)h (through)g(the)h(v)n(ariable)f Fd(CAD)p 2132 1737 30 4 v 35 w(HOME)p Fe(,)g(which)h(mirrors)f(the)h(v)n(alue)f(of)h(the)g (shell)244 1858 y(en)l(vironment)35 b(v)n(ariable)i(of)f(the)h(same)g (name.)66 b(In)37 b(addition,)h(it)e(mak)o(es)h(use)f(of)h(v)n (ariables)f Fd(VDD)g Fe(and)244 1978 y Fd(GND)23 b Fe(in)g(the)h (technology)e(\002le)j(to)e(aid)g(in)h(the)f(e)o(xtraction)g(of)h (substrate-)f(and)h(well-connected)f(nodes)g(on)244 2098 y(transistors.)71 2339 y(10.)48 b(Magic)30 b(input)g(\002les,)j(such)d (as)h(the)g Fd(.magic)f Fe(startup)g(\002le,)i(are)g(sourced)f(as)g (Tcl)g(scripts,)g(and)g(so)f(may)244 2459 y(themselv)o(es)23 b(contain)h(a)h(mixture)f(of)h(Tcl)g(and)g(magic)f(commands.)0 2846 y Fg(3)143 b(Compilation)33 b(and)i(Installation)0 3085 y Fe(Magic)24 b(is)h(selected)g(for)g(compilation)e(as)h(a)i(Tcl)e (e)o(xtention)g(when)g(running)g(the)900 3333 y Fc(mak)o(e)h(con\002g)0 3574 y Fe(script.)64 b(The)36 b(\002rst)h(question)e(asks)g(whether)i (magic)e(should)g(be)i(compiled)e(as)h(a)g(Tcl)g(e)o(xtension,)i(with)d (the)0 3694 y(SCHEME)k(interpreter)g(embedded,)k(or)c(as)g(the)g (original)f(v)o(ersion)g(with)h(no)g(interpreter)-5 b(.)73 b(Subsequent)38 b(to)0 3814 y(choosing)30 b(Tcl)h(as)h(the)f (interpreter)g(and)g(answering)g(the)g(remaining)f(con\002guration)h (questions,)g(Tcl)g(should)0 3935 y(be)25 b(compiled)f(and)g(installed) g(using)g(the)g(commands)900 4183 y Fc(mak)o(e)h(tcl)0 4423 y Fe(and)900 4671 y Fc(mak)o(e)g(install-tcl)0 4912 y Fe(Note)g(that)f(if)h(magic)f(is)g(to)h(be)g(compiled)f(under)g(dif)n (ferent)h(interpreters,)f(it)h(is)f(necessary)h(to)f(perform)900 5159 y Fc(mak)o(e)h(clean)0 5400 y Fe(between)g(the)g(compilations,)d (so)j(that)f(all)g(references)j(to)d(the)h(last)f(compiled)g(v)o (ersion)f(are)j(deleted.)1875 5649 y(\2264\226)p eop %%Page: 5 5 5 4 bop 0 -180 a Fe(Magic)24 b(Tcl)h(T)l(utorial)f(#1:)30 b(Introduction)1885 b(April)24 b(12,)h(2006)0 99 y Fg(4)143 b(Dual-Sour)m(ce)34 b(Input)g(and)h(Backward)f(Compatibility)0 494 y Fe(From)24 b(its)e(inception,)h(Magic)g(has)h(used)f(an)h(unsual) f(b)n(ut)g(v)o(ery)g(ef)n(fecti)n(v)o(e)g(interf)o(ace)h(in)f(which)g (commands)f(may)0 615 y(be)k(passed)g(to)g(the)g(program)g(from)g(tw)o (o)g(dif)n(ferent)g(sources,)g(the)g(layout)g(windo)n(w)-6 b(,)24 b(and)i(the)h(calling)e(terminal.)0 735 y(K)n(e)o(ystrok)o(es)30 b(in)i(the)g(layout)f(windo)n(w)f(are)j(handled)e(by)h(the)g(graphics)f (package.)53 b(These)32 b(are)g(interpreted)g(as)0 856 y Ff(macr)l(os)p Fe(.)d(The)24 b(k)o(e)o(ystrok)o(e)f(v)n(alues)g(are)h (e)o(xpanded)f(into)g(magic)h(command-line)e(commands)h(and)g(e)o(x)o (ecuted)g(by)0 976 y(the)f(command-line)e(command)h(dispatcher)g (routine.)29 b(T)-8 b(w)o(o)22 b(macros,)g(`)p Fd(.)p Fe(')30 b(and)22 b(`)p Fd(:)p Fe(')29 b(are)23 b(reserv)o(ed:)29 b(The)21 b(period)0 1096 y(e)o(xpands)k(to)g(the)g(last)g(command)f(e)o (x)o(ecuted)h(from)g(the)h(command)e(line)h(\()p Ff(not)g Fe(from)g(a)h(macro)g(e)o(xpansion\),)e(and)0 1217 y(the)33 b(colon)h(initiates)e(a)i(redirection)f(of)h(k)o(e)o(ystrok)o(es)e (from)h(the)h(layout)f(windo)n(w)f(into)h(the)g(calling)g(terminal.)0 1337 y(Magic)c(users)g(quickly)f(get)h(used)g(to)g(the)g(combination)f (of)h(k)o(e)o(ystrok)o(es,)g(mouse)g(functions,)g(and)g(command-)0 1458 y(line)24 b(commands.)146 1661 y(In)39 b(the)f(Tcl-based)h(v)o (ersion)e(of)i(Magic,)i(the)e(command-line)e(dispatching)g(is)h(gi)n(v) o(en)f(o)o(v)o(er)h(entirely)f(to)0 1781 y(Tcl,)g(and)d(the)h (dispatching)e(of)i(k)o(e)o(ystrok)o(e)e(e)n(v)o(ents)g(in)i(the)f (layout)g(windo)n(w)f(is)h(gi)n(v)o(en)f(o)o(v)o(er)h(entirely)g(to)g (Tk.)0 1901 y(Unfortunately)-6 b(,)38 b(in)f(relinquishing)e(these)i (duties,)i(Magic)d(loses)g(some)h(of)g(the)f(ef)n(fecti)n(v)o(eness)g (of)h(its)f(dual-)0 2022 y(source)21 b(input)g(model.)28 b(One)22 b(aspect)f(of)h(this)e(is)h(that)g(Tcl)g(is)g(a)h(line-based)f (interpreter)l(,)h(and)f(does)g(not)g(recognize)0 2142 y(an)o(ything)h(on)i(the)g(command)f(line)h(until)e(the)i(return)g(k)o (e)o(y)g(has)g(been)g(pressed)g(and)g(the)g(entire)g(line)f(is)h (passed)f(to)0 2263 y(the)e(command)g(dispatcher)g(routine.)29 b(W)l(ithout)20 b(an)o(y)h(understanding)f(of)i(character)n(-based)h (input,)e(it)g(is)g(dif)n(\002cult)0 2383 y(to)k(impossible)e(to)i (directly)f(edit)h(the)g(command)f(line)h(from)g(outside)f(the)h (calling)g(terminal,)f(because)i(it)e(is)h(the)0 2503 y(terminal,)f(and)h(not)f(Tcl,)g(which)h(interprets)f(k)o(e)o(ystrok)o (es)g(on)g(a)h(character)n(-by-character)i(basis.)146 2706 y(The)39 b(w)o(ay)g(around)f(this)g(problem)g(is)g(to)h(use)f(a)i Ff(console)p Fe(,)h(which)d(is)h(an)g(application)e(that)h(runs)h(in)f (the)0 2827 y(manner)f(usually)g(e)o(xpected)g(by)g(Tk,)j(in)d(that)g (it)g(is)g(a)g(GUI-dri)n(v)o(en)f(application.)68 b(The)37 b(interpreter)g(is)g(split)0 2947 y(into)30 b Ff(master)g Fe(and)h Ff(slave)f Fe(interpreters)h(\(see)g(the)g(Tcl)g (documentation)e(on)h(the)h Fc(inter)o(p)h Fe(command\),)f(with)f(the)0 3068 y(master)21 b(interpreter)h(running)e(the)i(console)f(application) f(and)i(the)f(sla)n(v)o(e)g(interpreter)g(running)g(the)g(application.) 0 3188 y(The)36 b(master)g(interpreter)g(then)f(has)h(character)n (-based)h(control)f(o)o(v)o(er)f(the)h(command)f(line,)j(and)e(the)f (Magic)0 3308 y(dual-source)k(input)f(model)h(can)g(be)h(implemented)d (e)o(xactly)i(as)g(originally)f(designed.)73 b(The)40 b(background)0 3429 y(DRC)34 b(function)f(can)h(change)f(the)g(command) g(line)g(cursor)g(from)g(`)p Ff(\045)p Fe(')h(to)f(`)p Ff(])p Fe(')g(to)g(indicate)g(that)g(the)g(DRC)i(is)0 3549 y(in)c(progress,)h(and)f(user)g(input)f(can)h(be)g(redirected)g (from)g(the)g(layout)f(windo)n(w)g(to)g(the)h(console)f(with)h(the)f(`) p Fc(:)p Fe(')0 3670 y(k)o(e)o(ystrok)o(e.)146 3873 y(In)f(addition)f (to)h(these)f(functions,)h(the)g(console)f(mak)o(es)h(use)g(of)g(Tcl') -5 b(s)28 b(ability)g(to)g(rename)i(commands)d(to)0 3993 y(recast)22 b(the)f(basic)g(Tcl)h(output)e(function)h(`)p Fc(puts)p Fe(')h(in)f(such)g(a)h(w)o(ay)g(that)f(output)f(to)h Fd(stdout)f Fe(and)i Fd(stdin)e Fe(can)i(be)0 4113 y(handled)28 b(dif)n(ferently)-6 b(.)41 b(In)29 b(the)g Fc(TkCon)h Fe(console,)f(output)e(to)h Fd(stdout)g Fe(is)g(printed)g(in)h(blue,)g (while)f(output)f(to)0 4234 y Fd(stderr)22 b Fe(is)h(printed)g(in)g (red.)30 b(Magic)23 b(mak)o(es)g(use)h(of)f(Tcl')-5 b(s)23 b(output)f(procedures)h(so)g(that)g(returned)h(v)n(alues)e(and)0 4354 y(information)g(are)i(printed)f(in)g(blue,)g(while)g(w)o(arnings)g (and)g(error)h(messages)f(are)h(printed)f(in)g(red.)30 b(The)24 b(console)0 4475 y(also)35 b(implements)e(command-line)h (history)g(and)h(cut-and-paste)g(methods.)61 b(The)35 b(console)f(command-line)0 4595 y(history)24 b(replaces)h(the)g (embedded)f Ff(r)l(eadline)g Fe(implementation)f(in)h(magic.)146 4798 y(The)30 b Fc(TkCon)h Fe(console)e(is)g(a)h(placeholder)g(for)g (what)f(is)h(intended)f(to)g(be)h(a)g(\223project)g(manager\224)g (console,)0 4918 y(with)36 b(functions)g(more)h(appropriate)f(to)h(the) g(Electronic)f(Design)g(Automation)f(suite)i(of)g(Tcl-based)f(tools.)0 5039 y(In)f(general,)i(the)d(menu)g(functions)g(which)g(are)h (displayed)e(on)i(the)f(TkCon)g(console)g(are)i(not)e(of)g(particular)0 5159 y(interest)26 b(to)h(the)g(Magic)g(user)l(,)h(with)e(the)h(e)o (xception)f(of)h(the)g Fc(History)f Fe(menu,)h(which)g(can)g(be)h(used) f(to)f(re-enter)0 5280 y(pre)n(viously)31 b(e)o(x)o(ecuted)h(commands,) h(and)g(the)g Fc(Pr)n(efs)g Fe(menu,)h(which)f(includes)f(highlighting) e(options)h(and)i(a)0 5400 y(v)o(ery)24 b(useful)h(calculator)g(mode.) 1875 5649 y(\2265\226)p eop %%Page: 6 6 6 5 bop 0 -180 a Fe(April)24 b(12,)h(2006)1886 b(Magic)24 b(Tcl)h(T)l(utorial)e(#1:)30 b(Introduction)0 99 y Fg(5)143 b(Tk)36 b(Graphics)d(Methods)0 322 y Fe(Because)28 b(the)f(graphics)g (under)h(Tcl)f(are)h(managed)f(by)g(the)g(Tk)g(package,)h(the)f(only)g (graphics)g(options)f(which)0 443 y(can)k(be)g(compiled)e(are)i(the)g (X11)f(and)g(the)h(OpenGL)f(options.)44 b(There)29 b(are)i(numerous)d (dif)n(ferences)i(between)0 563 y(these)j(graphics)f(interf)o(aces)i (as)e(the)o(y)h(e)o(xist)e(under)i(Tcl)g(and)g(under)g(the)f (non-Tcl-based)h(v)o(ersion.)54 b(The)33 b(tw)o(o)0 683 y(primary)22 b(dif)n(ferences)h(are)h(the)f(w)o(ay)f(windo)n(ws)g(are)h (generated)g(and)g(the)g(w)o(ay)g(commands)e(are)j(sent)e(to)h (speci\002c)0 804 y(windo)n(ws.)28 b(In)20 b(Tcl-based)h(magic,)g(a)g (layout)f(windo)n(w)f(does)i(not)f(ha)n(v)o(e)g(to)h(be)f(a)i(top-le)n (v)o(el)d(application)g(windo)n(w)-6 b(.)0 924 y(by)25 b(using)e(the)i(command)f(syntax)900 1090 y Fc(openwindo)o(w)i Ff(cellname)e(tk)p 1923 1090 30 4 v 36 w(pathname)146 1255 y Fe(An)j(unmapped)f(windo)n(w)g(can)h(be)g(generated,)h (corresponding)e(to)h(the)g(Tk)f(windo)n(w)g(hierarchy)h(speci\002ed)0 1376 y(by)22 b Ff(tk)p 200 1376 V 35 w(pathname)f Fe(\(see)i(the)f(Tk)f (documentation)g(for)h(the)g(speci\002cs)g(of)g(Tk)g(windo)n(w)e(path)i (name)g(syntax\).)29 b(This)0 1496 y(windo)n(w)c(is)h(then)g(mapped)g (and)g(managed)h(by)f(Tk)g(commands.)34 b(Using)26 b(this)f(method,)h (a)h(magic)f(windo)n(w)f(can)0 1616 y(be)32 b(embedded)g(inside)f(a)i (\223wrapper\224)g(application,)f(an)g(e)o(xample)g(of)g(which)g(has)g (been)g(done)g(with)f(the)h(GUI)0 1737 y(wrapper)24 b(in)l(v)n(ok)o(ed) e(with)h(the)g(\223)p Fd(-w)p Fe(\224)g(command-line)f(ar)n(gument.)30 b(Extensions)21 b(of)j(magic)e(windo)n(w)g(commands)0 1857 y(ha)n(v)o(e)30 b(been)g(added)h(so)e(that)h(the)g(wrapper)h(can)f (control)g(the)g(windo)n(w)f(frame,)j(including)c(the)i(scrollbars)g (and)0 1978 y(title.)146 2098 y(Whene)n(v)o(er)f(a)h(windo)n(w)e(is)h (created,)i(Magic)e(creates)h(a)g(Tcl/Tk)e(command)h(with)f(the)h(same) h(name)f(as)g(the)0 2218 y(windo)n(w)19 b(\(this)g(is)h(con)l(v)o (entional)f(practice)h(with)g(Tk)g(widgets\).)28 b(Magic)20 b(and)g(Tcl)g(commands)f(can)i(be)f(passed)g(as)0 2339 y(ar)n(guments)j(to)g(the)g(windo)n(w)f(command.)29 b(Such)24 b(commands)e(are)i(e)o(x)o(ecuted)f(relati)n(v)o(e)f(to)h(the)g (speci\002c)h(windo)n(w)-6 b(.)0 2459 y(This)20 b(applies)g(to)g(all)g (of)h(magic')-5 b(s)20 b(windo)n(w-based)f(commands,)h(including)f (instructions)g(such)h(as)h Fc(mo)o(v)o(e)p Fe(,)g Fc(load)p Fe(,)0 2580 y(and)31 b(so)g(forth.)49 b(Commands)30 b(which)g(apply)h (to)f(all)h(windo)n(ws)e(will)h(automatically)g(be)h(sent)g(to)f(all)h (windo)n(ws.)0 2700 y(These)e(commands)f(are)h(used)g(primarly)f(by)h (the)g(wrapper)g(GUI,)g(b)n(ut)f(are)i(also)e(called)h(\(transparently) g(to)f(the)0 2820 y(end)23 b(user\))h(whene)n(v)o(er)f(a)h(command)e (is)i(e)o(x)o(ecuted)e(from)h(a)h(layout)f(windo)n(w)f(via)h(an)o(y)g (macro,)h(including)e(the)h(`)p Fc(:)p Fe(')0 2941 y(command-line)i (entry)-6 b(.)35 b(In)26 b(addition,)f(ho)n(we)n(v)o(er)l(,)g(the)o(y)h (may)g(be)g(called)h(from)f(the)g(command)f(line)h(to)g(perform)0 3061 y(an)k(action)g(in)g(a)h(speci\002c)g(windo)n(w)-6 b(.)45 b(By)31 b(def)o(ault)f(\(in)g(the)g(absence)h(of)f(a)h(wrapper)g (GUI\),)f(magic')-5 b(s)30 b(windo)n(ws)0 3181 y(are)25 b(named)f Ff(.ma)o(gic1)p Fe(,)f Ff(.ma)o(gic2)p Fe(,)h(and)g(so)g (forth,)g(in)f(order)i(of)f(appearance,)h(and)g(these)f(names)f(are)i (re\003ected)g(in)0 3302 y(the)g(title)f(bar)h(of)g(the)f(windo)n(w)-6 b(.)29 b(So)c(it)f(is)h(equi)n(v)n(alent)e(to)h(do)900 3467 y Fc(:mo)o(v)o(e)h(s)g(10)0 3633 y Fe(from)f(layout)f(windo)n(w)g (`)p Ff(.ma)o(gic2)p Fe(')h(\(where)g(the)g(colon)g(indicates)f(the)h (k)o(e)o(y)g(macro)g(for)g(command-line)f(entry\),)0 3753 y(and)900 3919 y Fc(.magic2)h(mo)o(v)o(e)h(s)g(10)0 4084 y Fe(typed)f(in)h(the)f(console.)0 4417 y Fg(6)143 b(T)-13 b(utorial)34 b(Examples)0 4641 y Fe(Example)23 b(sessions)g(of)h(running)e(magic)i(in)f(v)n(arious)g(modes)g(are)i (presented)e(belo)n(w)-6 b(,)23 b(along)g(with)g(e)o(xamples)g(of)0 4761 y(methods)18 b(speci\002c)h(to)g(each)h(mode.)28 b(In)19 b(the)g(e)o(xamples)f(belo)n(w)-6 b(,)19 b(prompts)e(are)j(sho) n(wn)e(to)h(indicate)f(the)h(conte)o(xt)f(of)0 4881 y(each)26 b(command.)31 b(The)26 b Ff(#)f Fe(sign)f(indicates)h(the)g(shell)g (prompt,)f Ff(\(gdb\))h Fe(indicates)g(the)g(GNU)g(deb)n(ugger)g (prompt,)0 5002 y(and)g Ff(\045)g Fe(indicates)f(the)g(Tcl)h(\(i.e.,)g (Magic\))f(prompt.)0 5159 y Fa(Example)g(1:)31 b(Standard)24 b(Magic)h(Ex)o(ecution)146 5400 y Fe(Run)g(Tcl-based)g(magic)f(in)h (its)f(most)g(basic)g(form)h(by)f(doing)g(the)h(follo)n(wing:)1875 5649 y(\2266\226)p eop %%Page: 7 7 7 6 bop 0 -180 a Fe(Magic)24 b(Tcl)h(T)l(utorial)f(#1:)30 b(Introduction)1885 b(April)24 b(12,)h(2006)900 84 y Ff(#)g Fc(magic)f(-noconsole)h(tut2a)146 439 y Fe(Magic)e(looks)g (generally)g(lik)o(e)f(its)h(traditional)f(form,)h(e)o(xcept)g(that)g (the)g(command-line)f(prompt)g(is)h(the)g(Tcl)0 559 y(`)p Ff(\045)p Fe(')28 b(prompt.)39 b(It)28 b(should)f(be)h(possible)f(to)g (write)h(commands)f(from)g(either)h(the)g(terminal)f(or)h(using)f(the)h (colon)0 679 y(k)o(e)o(ystrok)o(e,)i(and)g(it)g(is)f(possible)g(to)h (partially)f(type)h(a)g(command)f(after)i(the)f(colon)g(k)o(e)o(ystrok) o(e)f(and)h(\002nish)f(the)0 800 y(command)22 b(inside)g(the)h (terminal,)g(b)n(ut)f(not)h(vice)g(v)o(ersa.)30 b(Enabling)22 b(the)h(colon)f(k)o(e)o(ystrok)o(e)g(may)h(require)g(setting)0 920 y(\223)-8 b(Allo)n(w)24 b(SendEv)o(ents\224)g(mode)g(on)h(the)f (calling)g(terminal.)0 1109 y Fa(Example)g(2:)31 b(Console-based)25 b(Magic)f(Ex)o(ecution)146 1356 y Fe(Run)h(the)g(TkCon)g(console-based) f(magic)g(by)h(doing)f(the)g(follo)n(wing:)900 1596 y Ff(#)h Fc(magic)f(tut2a)146 1950 y Fe(The)g(layout)e(windo)n(w)h(will)f (still)g(look)h(lik)o(e)g(the)g(usual,)g(basic)h(form.)30 b(Ho)n(we)n(v)o(er)l(,)22 b(the)i(calling)e(terminal)h(will)0 2071 y(be)i(suspended)g(\(unless)g(the)g(application)f(is)h (backgrounded;)g(ho)n(we)n(v)o(er)l(,)f(if)h(backgrounding)f(the)h (application,)0 2191 y(be)f(a)o(w)o(are)g(that)f(an)o(y)g(output)f (sent)h(to)h(the)f(terminal)g(will)f(hang)i(the)f(application)g(until)f (it)h(is)g(fore)o(grounded\))g(and)0 2312 y(the)e(Tcl)g(prompt)f(will)g (appear)i(in)e(a)i(ne)n(w)e(windo)n(w)-6 b(,)20 b(which)h(is)f(the)h Fc(console)p Fe(.)30 b(The)21 b(console)f(may)h(ha)n(v)o(e)g(a)g (slightly)0 2432 y(dif)n(ferent)31 b(appearance)h(depending)e(on)h(the) g(graphics)g(mode)g(used.)49 b(F)o(or)32 b(instance,)g(magic)f(has)g (historically)0 2552 y(had)21 b(dif)n(\002culties)f(running)g(in)g (8-bit)g(\(PseudoColor\))i(graphics)e(mode,)h(because)h(it)e(installs)f (its)i(o)n(wn)f(colormap.)0 2673 y(Because)i(it)e(does)g(not)g(share)h (the)f(colormap)g(with)g(the)h(calling)f(terminal,)g(the)g(calling)g (terminal)g(gets)g(repainted)0 2793 y(in)35 b(random)f(colors)h(from)g (magic')-5 b(s)34 b(colormap)g(when)h(the)g(cursor)g(is)g(in)g(the)f (layout)h(windo)n(w)-6 b(.)59 b(In)35 b(unluck)o(y)0 2914 y(setups,)24 b(te)o(xt)g(and)g(background)h(may)f(be)h (unreadable.)146 3040 y(In)35 b(the)g(TkCon)g(console)f(setup,)i(the)f (console)f(is)h(mapped)f(prior)h(to)f(determining)g(the)g(graphics)h (mode)0 3160 y(required,)i(so)d(it)h(also)f(does)g(not)g(share)h(the)g (colormap.)60 b(Ho)n(we)n(v)o(er)l(,)36 b(it)e(is)g(possible)f(to)i (query)f(Magic')-5 b(s)34 b(col-)0 3281 y(ormap)d(to)f(\002nd)i(the)f (location)f(of)h(speci\002c)h(colors,)g(and)f(repaint)g(the)g(te)o(xt)f (and)h(background)f(of)i(the)f(console)0 3401 y(accordingly)-6 b(.)29 b(Thus,)24 b(the)g(Magic)g(console)g(can)h(be)f(used)g(when)h (the)f(display)f(is)h(in)g(8-bit)g(PseudoColor)g(mode,)0 3522 y(without)g(e)o(xtreme)h(color)h(remappings)e(in)i(the)f(console)g (which)h(mak)o(e)f(it)g(potentially)f(impossible)g(to)h(read)h(the)0 3642 y(console)e(when)h(the)g(cursor)f(is)h(in)f(a)h(layout)f(windo)n (w)-6 b(.)146 3768 y(If)28 b(compiled)e(with)g(both)h(OpenGL)g(and)g (X11)f(graphics)h(capability)-6 b(,)26 b(magic)h(will)f(start)h(in)g (X11)g(mode)f(by)0 3889 y(def)o(ault.)k(The)25 b(OpenGL)g(interf)o(ace) g(can)g(only)f(be)h(enabled)g(at)g(startup)f(by)h(specifying:)900 4129 y Ff(#)g Fc(magic)f(-d)i(OGL)e(tut4x)0 4484 y Fe(The)k(OpenGL)g (interf)o(ace,)h(in)f(addition)f(to)h(ha)n(ving)f(more)h(solid,)g (vibrant)f(colors,)h(has)g(an)h(additional)d(feature)0 4604 y(which)e(dra)o(ws)h(three-dimensional)e(vie)n(ws)h(of)h(a)g (layout.)30 b(This)24 b(is)g(discussed)g(in)g(T)l(utorial)g(#??.)0 4792 y Fa(Example)g(4:)31 b(The)26 b(Magic)e(Wrapper)f(GUI)146 5039 y Fe(The)i(magic)g(GUI)f(interf)o(ace)i(is)e(in)l(v)n(ok)o(ed)g (by)h(starting)e(magic)i(with)f(the)h Fc(-w)g Fe(option:)900 5280 y Ff(#)g Fc(magic)f(-w)h(tut2b)1875 5649 y Fe(\2267\226)p eop %%Page: 8 8 8 7 bop 0 -180 a Fe(April)24 b(12,)h(2006)1886 b(Magic)24 b(Tcl)h(T)l(utorial)e(#1:)30 b(Introduction)146 68 y(The)35 b(immediately)e(noticeable)h(dif)n(ferences)h(are)g(the)g(layer)g (toolbar)f(on)g(the)g(side,)j(and)e(the)f(menu)g(and)0 188 y(redesigned)26 b(title)f(bar)i(on)f(the)g(top.)34 b(Experimenting)25 b(with)g(some)h(mouse)f(clicks,)h(the)g(user)g(will) g(note)g(that)f(the)0 309 y(magic)f(coordinates)h(of)f(the)h(cursor)g (box)f(are)i(displayed)e(on)g(the)h(right-hand)f(side)g(of)h(the)g (titlebar)-5 b(.)146 429 y(The)27 b(toolbar)f(contains)f(one)i(e)o (xample)f(of)g(each)h(layer)g(de\002ned)g(in)f(the)h(magic)f (technology)f(\002le.)36 b(Position)0 549 y(a)25 b(box)g(on)g(the)g (screen,)g(then)g(put)g(the)g(cursor)g(o)o(v)o(er)f(a)h(layer)h(icon)e (and)h(press)g(the)g(middle)f(mouse)h(b)n(utton.)30 b(This)0 670 y(paints)d(the)h(layer)h(into)e(the)h(box.)40 b(Y)-11 b(ou)28 b(will)f(also)g(notice)h(that)g(the)g(name)g(of)g(the)g(layer)g (is)g(printed)f(in)h(the)g(title)0 790 y(bar)d(while)f(the)h(cursor)g (is)f(o)o(v)o(er)g(the)h(layer)g(icon.)146 911 y(The)k(icons)e(ha)n(v)o (e)h(other)h(responses,)f(too.)41 b(The)28 b(\002rst)h(and)f(third)g (mouse)f(b)n(uttons)g(respecti)n(v)o(ely)g(sho)n(w)g(and)0 1031 y(hide)k(the)f(layer)h(in)g(the)g(layout.)48 b(This)30 b(w)o(orks)g(with)g(labels,)i(subcell)f(boundaries,)g(and)g(error)h (paint)e(\(the)h(top)0 1151 y(three)d(layer)f(icons\))g(as)h(well)f(as) g(with)g(re)o(gular)g(paintable)f(layers.)39 b(In)27 b(addition)f(to)h(mouse)g(b)n(utton)f(responses,)0 1272 y(the)k(b)n(uttons)e(in)l(v)n(ok)o(e)i(v)n(arious)f(commands)g(in)g (reponse)h(to)g(k)o(e)o(ystrok)o(es.)45 b(K)n(e)o(y)29 b(`p')h(paints)f(the)h(layer;)j(k)o(e)o(y)c(`e')0 1392 y(erases)c(it.)30 b(K)n(e)o(y)24 b(`s')h(selects)g(the)g(layer)g(in)f (the)h(box)f(while)g(k)o(e)o(y)h(`S')g(unselects)f(it.)146 1513 y(The)f(menubar)f(has)g(three)h(items,)f Fc(File)p Fe(,)g Fc(Cell)p Fe(,)h(and)f Fc(T)-9 b(ech)p Fe(.)31 b(Button)22 b Fc(File)g Fe(pops)g(up)g(a)h(menu)f(with)g(options)e(to)0 1633 y(read)28 b(and)f(write)g(layout,)f(read)i(and)f(write)g(CIF)h(or) f(GDS)h(output,)e(open)h(a)g(ne)n(w)g(layout)f(windo)n(w)g(or)h(close)g (the)0 1753 y(e)o(xisting)18 b(one,)k(or)e(\003ush)g(the)h(current)f (edit)g(cell.)29 b(Buttons)20 b Fc(Cell)g Fe(and)g Fc(T)-9 b(ech)22 b Fe(re)n(v)o(eal)e(transient)f(windo)n(ws)g(sho)n(wing)0 1874 y(information)24 b(about)i(the)f(cell)h(hierarchy)g(and)f(the)h (technology)f(\002le,)h(respecti)n(v)o(ely)-6 b(.)32 b(The)25 b(cell)h(hierarchy)g(vie)n(w)0 1994 y(is)21 b(only)g(a)n(v)n(ailable)g(if)g(the)h(Tcl/Tk)f(package)h Fc(BL)-9 b(T)23 b Fe(has)e(been)h(compiled)f(and)g(installed)f(on)i (the)f(system.)29 b(If)22 b(so,)g(it)0 2114 y(gi)n(v)o(es)h(a)i(tree)f (vie)n(w)g(of)h(the)f(cell)g(hierarchy)g(and)h(allo)n(ws)e(speci\002c)i (cells)f(to)g(be)g(loaded,)g(edited,)g(and)h(e)o(xpanded,)0 2235 y(or)h(vie)n(wed)g(to)g(\002t)g(the)h(windo)n(w)-6 b(.)33 b(This)25 b(can)i(be)f(e)o(xpecially)g(useful)g(for)g(querying)g (the)g(cell)g(hierarchy)g(of)h(GDS)0 2355 y(\002les,)e(which)f(do)h (not)f(declare)i(top-le)n(v)o(el)d(cells)h(lik)o(e)h(CIF)g(\002les)g (do.)146 2476 y(The)31 b(technology)e(manager)i(windo)n(w)e(reports)h (the)g(current)h(technology)e(\002le,)k(its)c(v)o(ersion)h(and)g (descrip-)0 2596 y(tion,)23 b(and)h(the)g(current)h(CIF)g(input)e(and)h (output)f(styles,)g(the)h(current)g(e)o(xtraction)f(style,)g(and)h(the) g(current)h(v)n(alue)0 2716 y(of)f(lambda)g(in)g(microns.)29 b(The)c(technology)e(\002le)h(and)g(the)h(CIF)g(input)e(and)h(output)f (styles)g(and)i(e)o(xtraction)e(style)0 2837 y(are)k(also)g(b)n(uttons) e(which)h(can)h(be)g(used)g(to)f(select)h(a)g(ne)n(w)f(style)g(or)h (technology)f(from)g(those)g(currently)h(a)n(v)n(ail-)0 2957 y(able.)40 b(Clicking)28 b(on)f(the)h(current)h(e)o(xtract)e (style,)h(for)h(instance,)f(gi)n(v)o(es)e(a)j(list)e(of)h(the)g(styles) f(which)g(ha)n(v)o(e)h(been)0 3077 y(speci\002ed)f(in)g(the)g(current)g (technology)f(\002le.)37 b(Clicking)26 b(on)h(one)g(of)g(the)g(entries) f(in)h(the)g(list)f(mak)o(es)g(it)h(the)g(ne)n(w)0 3198 y(current)e(e)o(xtract)g(style.)146 3318 y(Cell)j(hierarchy)e(and)h (technology)f(manager)i(windo)n(ws)d(should)h(be)h(closed)g(by)g (clicking)f(on)h(the)g(\223Close\224)0 3439 y(b)n(utton)f(at)g(the)h (bottom,)f(not)g(by)g(in)l(v)n(oking)f(an)o(y)i(titlebar)f(functions)f (\(which)i(will)f(probably)g(cause)h(the)g(whole)0 3559 y(application)d(to)g(e)o(xit\).)0 3727 y Fa(Example)g(5:)31 b(Batc)o(h-mode)25 b(Magic)146 3968 y Fe(Unlik)o(e)j(pre)n(vious)f(v)o (ersions)f(of)j(magic,)f(it)g(is)f(not)h(necessary)g(to)g(ha)n(v)o(e)g (a)g(layout)g(windo)n(w)f(present)g(to)h(run)0 4088 y(magic.)i(Magic)25 b(may)f(be)h(in)l(v)n(ok)o(ed)f(in)g(\223batch)h(mode\224)g(by)f(the)h (follo)n(wing)e(command-line:)900 4285 y Ff(#)i Fc(magic)f(-no)o(windo) o(w)i(tut2b)146 4602 y Fe(Note)g(ho)n(we)n(v)o(er)l(,)f(that)h(most)f (magic)g(commands)g(e)o(xpect)h(a)g(windo)n(w)f(to)h(be)g(present)g(to) f(e)o(x)o(ecute)h(the)g(func-)0 4722 y(tion.)65 b(The)37 b(main)e(use)i(for)g(batch)f(mode)g(is)g(for)h(wrapper)n(-type)g (applications)e(to)h(delay)g(opening)g(a)h(layout)0 4842 y(windo)n(w)23 b(until)h(one)h(is)f(requested.)31 b(F)o(or)24 b(e)o(xample:)900 5039 y Ff(#)h Fc(magic)f(-no)o(windo)o(w)i(tut2b)900 5159 y Ff(\045)f Fc(tople)o(v)o(el)f(.myframe)900 5280 y Ff(\045)h Fc(openwindo)o(w)h(tut2b)g(.myframe.mylay)n(out)900 5400 y Ff(\045)f Fc(pack)h(.myframe.mylay)n(out)1875 5649 y Fe(\2268\226)p eop %%Page: 9 9 9 8 bop 0 -180 a Fe(Magic)24 b(Tcl)h(T)l(utorial)f(#1:)30 b(Introduction)1885 b(April)24 b(12,)h(2006)900 84 y Ff(\045)g Fc(.myframe.mylay)n(out)f(box)h(0)g(0)f(12)h(12)900 205 y Ff(\045)g Fc(.myframe.mylay)n(out)f(select)h(ar)n(ea)g(poly)900 325 y Ff(\045)g Fc(wm)g(withdraw)g(.myframe)900 445 y Ff(\045)g Fc(wm)g(deiconify)g(.myframe)900 566 y Ff(\045)g Fc(.myframe.mylay)n(out)f(closewindo)o(w)146 867 y Fe(Note)e(that)g (this)f(is)h(the)g(basic)g(setup)g(of)g(the)g(standard)g(GUI)g(wrapper) l(,)h(albeit)f(with)f(much)h(greater)h(sophisti-)0 987 y(cation.)29 b(The)22 b(standard)f(GUI)h(wrapper)h(is)e(generated)h (entirely)f(by)h(script,)g(which)f(can)h(be)g(found)f(in)h(the)f (library)0 1108 y(directory)k Fc($)p Fb(f)p Fc(CAD)p 707 1108 30 4 v 35 w(HOME)p Fb(g)p Fc(/lib/magic/tcl/wrapper)-10 b(.tcl)p Fe(.)0 1270 y Fa(Example)24 b(6:)31 b(Tcl-Magic)24 b(under)i(the)f(De)o(b)n(ugger)146 1511 y Fe(When)36 b(running)f(under)g(Tcl,)j(Magic)d(cannot)h(be)f(deb)n(ugged)g(in)h (the)f(usual)g(manner)h(of)f(e)o(x)o(ecuting,)i(for)0 1631 y(instance,)22 b(\223)p Fc(gdb)i(magic)p Fe(\224,)e(because)h(the) f(main)g(e)o(x)o(ecutable)f(is)h(actually)g(the)g(program)g(\223)p Fc(wish)p Fe(\224.)30 b(T)-8 b(o)22 b(run)g(Magic)0 1752 y(with)g(deb)n(ugging)g(capability)-6 b(,)21 b(it)h(is)h(necessary)g (to)f(do)h(the)f(steps)h(belo)n(w)-6 b(.)28 b(In)23 b(the)g(follo)n (wing,)e(it)h(is)h(assumed)f(that)0 1872 y(Magic)30 b(has)g(been)g (installed)f(in)h(the)f(def)o(ault)h(location)g Fd(CAD)p 2137 1872 V 35 w(HOME=/usr/local/)p Fe(,)e(and)i(that)f(the)h(GNU)0 1993 y(deb)n(ugger)25 b Fd(gdb)f Fe(is)g(the)h(deb)n(ugger)f(of)h (choice.)600 2173 y Ff(#)g Fc(gdb)g(wish)600 2294 y Ff(\(gdb\))g Fc(run)600 2414 y Ff(\045)g Fc(sour)n(ce)h (/usr/local/lib/magic/tcl/magic.tcl)900 2534 y Fe(.)900 2655 y(.)900 2775 y(.)600 2896 y Ff(\045)f(\(type)g(Contr)l(ol-C)f(in)g (the)h(terminal)f(window\))600 3016 y(\(gdb\))h Fc(br)n(eak)h (TxTclDispatch)600 3136 y Ff(\(gdb\))f Fc(cont)600 3257 y Ff(\045)g Fc(paint)g(m1)600 3498 y Fd(Breakpoint)58 b(1,)h(TxTclDispath)e(\(clientData=0x0,)f(argc=2,)900 3618 y(argv=0xbffff400\))899 3738 y(at)j(txCommands.c:1146)600 3859 y(1146)537 b(DRCBreak\(\);)600 3979 y Ff(\(gdb\))146 4280 y Fe(Command-line)26 b(ar)n(guments)h(can)h(be)f(passed)g(to)g (magic)f(through)h(the)g(Tcl)g(v)n(ariables)f Fd(argc)h Fe(and)g Fd(argv)p Fe(.)0 4401 y(The)h(inte)o(ger)f(v)n(alue)g Fd(argc)g Fe(must)f(match)i(the)f(number)g(of)h(entries)g(passed)f(in)g (the)h Fd(argv)f Fe(list.)38 b(F)o(or)28 b(e)o(xample,)0 4521 y(do)d(the)f(follo)n(wing:)900 4702 y Ff(#)h Fc(gdb)g(wish)900 4822 y Ff(\(gdb\))g Fc(run)900 4942 y Ff(\045)g Fc(set)g(ar)o(gc)g(4) 900 5063 y Ff(\045)g Fc(set)g(ar)o(gv)g Fb(f)p Fc(-w)f(-d)i(OGL)e(tut1) i Fb(g)900 5183 y Ff(\045)f Fc(sour)n(ce)h (/usr/local/lib/magic/tcl/magic.tcl)1875 5649 y Fe(\2269\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tutscm1.ps0000644000175000001440000014127110751423606015642 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: tutscm1.dvi %%Pages: 9 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips tutscm1.dvi -o tutscm1.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Bold % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet %%BeginProcSet: special.pro TeXDict begin /SDict 200 dict N SDict begin /@SpecialDefaults{/hs 612 N /vs 792 N /ho 0 N /vo 0 N /hsc 1 N /vsc 1 N /ang 0 N /CLIP 0 N /rwiSeen false N /rhiSeen false N /letter{}N /note{}N /a4{}N /legal{}N}B /@scaleunit 100 N /@hscale{@scaleunit div /hsc X}B /@vscale{@scaleunit div /vsc X}B /@hsize{/hs X /CLIP 1 N}B /@vsize{/vs X /CLIP 1 N}B /@clip{ /CLIP 2 N}B /@hoffset{/ho X}B /@voffset{/vo X}B /@angle{/ang X}B /@rwi{ 10 div /rwi X /rwiSeen true N}B /@rhi{10 div /rhi X /rhiSeen true N}B /@llx{/llx X}B /@lly{/lly X}B /@urx{/urx X}B /@ury{/ury X}B /magscale true def end /@MacSetUp{userdict /md known{userdict /md get type /dicttype eq{userdict begin md length 10 add md maxlength ge{/md md dup length 20 add dict copy def}if end md begin /letter{}N /note{}N /legal{} N /od{txpose 1 0 mtx defaultmatrix dtransform S atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{itransform lineto} }{6 -2 roll transform 6 -2 roll transform 6 -2 roll transform{ itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll curveto}}{{ closepath}}pathforall newpath counttomark array astore /gc xdf pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack}if}N /txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 -1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop 90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr 2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 -1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S TR}if}N /cp {pop pop showpage pm restore}N end}if}if}N /normalscale{Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale}if 0 setgray} N /psfts{S 65781.76 div N}N /startTexFig{/psf$SavedState save N userdict maxlength dict begin /magscale true def normalscale currentpoint TR /psf$ury psfts /psf$urx psfts /psf$lly psfts /psf$llx psfts /psf$y psfts /psf$x psfts currentpoint /psf$cy X /psf$cx X /psf$sx psf$x psf$urx psf$llx sub div N /psf$sy psf$y psf$ury psf$lly sub div N psf$sx psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub TR /showpage{}N /erasepage{}N /copypage{}N /p 3 def @MacSetUp}N /doclip{ psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath moveto}N /endTexFig{end psf$SavedState restore}N /@beginspecial{SDict begin /SpecialSave save N gsave normalscale currentpoint TR @SpecialDefaults count /ocount X /dcount countdictstack N}N /@setspecial {CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR }{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury lineto closepath clip}if /showpage{}N /erasepage{}N /copypage{}N newpath }N /@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{ end}repeat grestore SpecialSave restore end}N /@defspecial{SDict begin} N /@fedspecial{end}B /li{lineto}B /rl{rlineto}B /rc{rcurveto}B /np{ /SaveX currentpoint /SaveY X N 1 setlinecap newpath}N /st{stroke SaveX SaveY moveto}N /fil{fill SaveX SaveY moveto}N /ellipse{/endangle X /startangle X /yrad X /xrad X /savematrix matrix currentmatrix N TR xrad yrad scale 0 0 1 startangle endangle arc savematrix setmatrix}N end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tutscm1.dvi) @start /Fa 1 1 df<7FFFFFFFFFFFFFE0FFFFFFFFFFFFFFF0FFFFFFFFFFFFFFF07FFFFF FFFFFFFFE03C04789A4D>0 D E /Fb 1 63 df<7000000000000000FC00000000000000 FF000000000000007FC00000000000001FF000000000000007FC00000000000001FF0000 00000000007FC00000000000001FF000000000000007FE00000000000001FF8000000000 00007FE00000000000001FF800000000000003FE00000000000000FF800000000000003F E00000000000000FF800000000000003FF00000000000000FFC00000000000003FF00000 000000000FFC00000000000001FF000000000000007FC00000000000001FF00000000000 0007FC00000000000001FF000000000000007FC00000000000001FE00000000000001FE0 0000000000007FC0000000000001FF00000000000007FC0000000000001FF00000000000 007FC0000000000001FF0000000000000FFC0000000000003FF0000000000000FFC00000 00000003FF0000000000000FF80000000000003FE0000000000000FF80000000000003FE 0000000000001FF80000000000007FE0000000000001FF80000000000007FE0000000000 001FF00000000000007FC0000000000001FF00000000000007FC0000000000001FF00000 000000007FC0000000000000FF00000000000000FC000000000000007000000000000000 3B3878B44C>62 D E /Fc 1 62 df<7FFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF80FFFFFF FFFFFFFFFF807FFFFFFFFFFFFFFF00000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000007FFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFF80FFFFFF FFFFFFFFFF807FFFFFFFFFFFFFFF0041187BA44C>61 D E /Fd 133[44 50 50 72 50 55 33 39 44 55 55 50 55 83 28 55 33 28 55 50 33 44 55 44 55 50 33[50 4[33 1[50 2[50 50 50 1[50 50 28 25 33 1[57 50 33 33 33 3[50 1[33 30[55 2[{ TeXBase1Encoding ReEncodeFont }45 100.000003 /Times-Bold rf /Fe 134[60 1[86 1[66 40 47 53 1[66 60 66 100 33 2[33 66 60 40 53 66 53 66 60 12[80 66 5[113 80 2[47 5[86 80 86 6[40 60 60 60 60 60 60 60 60 60 60 1[30 40 42[66 2[{ TeXBase1Encoding ReEncodeFont }42 119.999948 /Times-Bold rf /Ff 104[100 50 1[44 44 24[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 3[33 1[33 1[72 1[94 2[61 55 66 1[55 72 72 89 2[39 33 72 72 55 61 72 66 1[72 1[44 3[28 28 50 50 50 50 50 50 50 50 50 50 28 25 33 25 56 50 33 33 33 3[50 1[33 29[55 55 2[{ TeXBase1Encoding ReEncodeFont }76 100.000003 /Times-Roman rf /Fg 134[44 44 1[44 50 28 39 39 50 50 50 50 72 28 1[28 28 50 50 28 44 50 44 50 50 13[50 61 1[61 1[66 83 55 2[33 5[66 1[61 3[67 6[50 1[50 1[50 50 2[25 33 3[33 33 4[50 35[{ TeXBase1Encoding ReEncodeFont }42 100.000003 /Times-Italic rf /Fh 134[72 1[104 1[80 48 56 64 1[80 72 80 120 40 80 1[40 80 72 48 64 80 64 80 72 12[96 80 104 4[135 3[56 6[96 7[48 6[72 72 72 3[48 9[72 35[{ TeXBase1Encoding ReEncodeFont }33 143.999997 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 121 101 a Fh(Magic)36 b(T)-13 b(utorial)34 b(#S-1:)43 b(The)35 b(scheme)f(command-line)e(inter)o(pr)m(eter)1655 521 y Fg(Rajit)24 b(Manohar)1282 941 y Ff(Department)g(of)h(Computer)f (Science)1271 1062 y(California)h(Institute)f(of)h(T)-7 b(echnology)1534 1182 y(P)o(asadena,)25 b(CA)h(91125)1053 1453 y(This)e(tutorial)g(corresponds)g(to)g(Magic)h(v)o(ersion)e(7.)0 1976 y Fe(T)-11 b(utorials)30 b(to)f(r)n(ead)h(\002rst:)300 2176 y Ff(Read)c(reference)g([1])0 2376 y Fe(Commands)j(intr)n(oduced)j (in)f(this)f(tutorial:)300 2576 y Ff(:scm-echo-result,)24 b(:e)n(v)n(al,)f(lots)h(of)h(scheme)g(functions)0 2776 y Fe(Macr)n(os)k(intr)n(oduced)i(in)g(this)f(tutorial:)300 3000 y Fg(\(None\))0 3892 y Fh(1)143 b(Intr)m(oduction)0 4115 y Ff(Magic')-5 b(s)18 b(original)g(command-line)g(interpreter)h (has)g(some)f(limitations.)26 b(Some)19 b(of)h(these)e(include)h(the)g (absence)0 4236 y(of)i(de\002nitions)g(with)f(ar)n(guments,)i(block)f (structure,)g(the)g(ability)g(to)g(de\002ne)h(comple)o(x)e(functions.) 28 b(W)-8 b(e)22 b(describe)0 4356 y(an)j(e)o(xtension)e(which)h(is)g (almost)f(completely)h(backw)o(ard)h(compatible)e(with)h(the)g(e)o (xisting)f(magic)h(command-)0 4476 y(line)g(syntax,)g(b)n(ut)h(permits) e(the)i(use)g(of)g(Scheme)g(on)f(the)h(command-line.)0 4815 y Fh(2)143 b(Backward)34 b(compatibility)0 5039 y Ff(T)-8 b(o)19 b(permit)f(e)o(xisting)f(magic)i(source)g(\002les)g (to)g(w)o(ork)g(within)e(the)i(scheme)g(interpreter)l(,)h(we)g(ha)n(v)o (e)e(had)h(to)g(sacri\002ce)0 5159 y(one)29 b(feature)h(of)f(the)g (magic)g(command-line)f(syntax.)43 b(Single)29 b(quotes)f(can)i(only)e (be)h(used)g(to)g(quote)g(a)g(single)0 5280 y(character)-5 b(.)69 b(The)38 b(reason)f(for)h(this)f(limitation)e(is)i(that)g Fg(unmatc)o(hed)f Ff(quotes)h(are)h(used)f(by)g(scheme)h(to)f(stop)0 5400 y(e)n(v)n(aluation)23 b(of)i(the)g(ne)o(xt)e(input)h(symbol.)1875 5649 y(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Ff(September)25 b(26,)f(2001)713 b(Magic)25 b(T)l(utorial)e(#S-1:)31 b(The)25 b(scheme)g(command-line)e (interpreter)146 68 y(P)o(arentheses)g(are)h(used)f(by)g(the)g(scheme)g (interpreter)-5 b(.)30 b(If)23 b(you)g(use)g(parentheses)g(outside)f (single)h(or)g(double)0 188 y(quotes)i(in)g(your)g(magic)g(source)h (\002les,)g(you)f(might)f(\002nd)i(that)f(the)g(source)h(\002les)g (don')n(t)f(w)o(ork)g(properly)-6 b(.)32 b(T)-8 b(o)26 b(cir)n(-)0 309 y(cumv)o(ent)21 b(this)f(problem,)i(simply)e(put)h (your)h(parentheses)f(in)h(double)f(quotes.)29 b(Y)-11 b(ou)21 b(can)i(also)e(use)h(backslashes)0 429 y(to)i(quote)h (parentheses)f(as)h(in:)900 664 y Fd(:macr)n(o)1227 664 y /bksp 2 string def bksp 0 92 put bksp show 1227 664 a 40 w Fd(\()1325 664 y (") show 1325 664 a 60 w Fd(echo)h(hello)1809 664 y (") show 1809 664 a 146 898 a Ff(Another)h(thing)f(you)h(may)f(notice)h (is)g(that)f(\003oating-point)g(numbers)g(are)i(parsed)f(as)g(such,)g (and)g(therefore)0 1019 y(a)e(command)f(such)g(as)900 1253 y Fd(:echo)i(5.3)146 1488 y Ff(w)o(ould)e(display)g(the)h(string)f Fd(5.300000)p Ff(.)29 b(If)c(you)g(really)f(w)o(ant)h(the)f(string)g Fd(5.3)p Ff(,)h(use:)900 1723 y Fd(:echo)1152 1723 y (") show 1152 1723 a 60 w Fd(5.3)1337 1723 y (") show 1337 1723 a 146 1957 a Ff(If)g(this)f(dif)n(ference)h(is)f(undesirable,)g(the)h(scheme)f (interpreter)h(can)g(be)g(turned)f(of)n(f)h(at)f(compile-time.)29 b(T)-8 b(alk)0 2077 y(to)23 b(your)h(local)g(magic)f(maintainer)g(if)h (you)f(w)o(ant)h(this)f(done.)30 b(W)-8 b(e)24 b(feel)g(that)g(the)f (minor)g(trouble)h(tak)o(en)f(in)h(mod-)0 2197 y(ifying)k(e)o(xisting)f (magic)i(source)g(\002les)g(will)f(be)h(outweighed)f(by)h(the)g(adv)n (antage)g(of)g(using)f(a)h(more)g(po)n(werful)0 2318 y(layout)24 b(language.)0 2663 y Fh(3)143 b(The)35 b(scheme)f(inter)o (pr)m(eter)0 2888 y Ff(The)25 b(interpreter)f(supports)g(a)h(subset)f (of)h(the)f(scheme)h(language.)30 b(The)25 b(features)g(of)g(scheme)f (that)h(are)g(missing)0 3008 y(include)h(character)j(types,)d(v)o (ector)h(types,)g(\002le)g(input/output,)e(comple)o(x)h(numbers,)g(the) h(distinction)e(between)0 3129 y(e)o(xact)g(and)f(ine)o(xact)h (arithmetic,)e(quasi-quotations,)g(and)i(continuations.)0 3429 y Fe(3.1)119 b(Command-line)31 b(interaction)0 3618 y Ff(When)e(interacting)e(with)h(the)g(command-line)g(of)g(magic,)h (the)f(interpreter)h(implicitly)d(parenthesizes)j(its)e(in-)0 3739 y(put.)j(F)o(or)25 b(e)o(xample,)f(the)g(command)900 3974 y Fd(:paint)i(poly)146 4208 y Ff(w)o(ould)e(be)h(interpreted)g(as) g(the)f(scheme)h(e)o(xpression)900 4443 y Fd(\(paint)h(poly\))146 4677 y Ff(This)18 b(has)h(e)o(xactly)f(the)h(same)g(ef)n(fect)g(as)g (the)f(original)g(e)o(xpression,)h(because)g(all)g(e)o(xisting)e(magic) h(command-)0 4797 y(line)29 b(functions)f(are)i(also)e(scheme)h (functions.)43 b(Since)29 b(the)g(v)n(alid)f(magic)h(commands)f(v)n (ary)h(from)g(windo)n(w)e(to)0 4918 y(windo)n(w)-6 b(,)20 b(the)h(return)f(v)n(alue)h(of)g(the)g(function)f(is)g(a)h(boolean)g (that)f(indicates)h(whether)g(the)f(command)g(w)o(as)h(v)n(alid)0 5038 y(for)k(the)g(current)g(windo)n(w)-6 b(.)146 5159 y(The)26 b(boolean)f Fd(scm-echo-r)n(esult)i Ff(controls)e(whether)g (or)h(not)e(the)i(result)f(of)g(the)h(e)n(v)n(aluation)d(is)i (displayed.)0 5280 y(If)k(the)f(v)n(ariable)g(does)h(not)f(e)o(xist,)g (or)g(the)h(v)n(ariable)f(is)g(not)g(boolean-v)n(alued,)g(the)g(result) g(of)h(e)n(v)n(aluation)e(is)h(not)0 5400 y(echoed.)j(Since)25 b(the)g(input)f(is)g(implicitly)e(parenthesized,)j(typing)e(in)1875 5649 y(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Ff(Magic)24 b(T)l(utorial)g(#S-1:)31 b(The)24 b(scheme)h(command-line)f(interpreter)713 b(September)25 b(26,)g(2001)900 84 y Fd(:scm-echo-r)n(esult)146 379 y Ff(w)o(ould)f(not)h(display)e(the)i(v)n(alue)f(of)h(the)g(v)n (ariable,)f(since)g(it)h(w)o(ould)f(be)h(e)n(v)n(aluated)e(as:)900 684 y Fd(\(scm-echo-r)n(esult\))146 979 y Ff(T)-8 b(o)25 b(display)f(the)g(v)n(alue)h(of)f(a)i(v)n(ariable,)e(use)g(the)h(b)n (uilt-in)e(procedure)j Fd(e)o(v)o(al)e Ff(as)h(follo)n(ws:)900 1284 y Fd(:e)o(v)o(al)f(scm-echo-r)n(esult)146 1579 y Ff(This)g(w)o(ould)g(result)h(in)f(the)h(e)o(xpression:)900 1884 y Fd(\(e)o(v)o(al)f(scm-echo-r)n(esult\))146 2179 y Ff(which)e(w)o(ould)g(ha)n(v)o(e)g(the)g(desired)g(ef)n(fect)h (\(note)f(that)f(for)i(this)e(to)h(actually)g(display)f(an)o(ything,)g (the)h(v)n(alue)g(of)0 2299 y Fd(scm-echo-r)n(esult)30 b Ff(must)d(be)h Fd(#t)p Ff(,)i(and)e(so)g(e)o(xamining)e(its)i(v)n (alue)f(is)h(really)g(a)h(futile)e(e)o(x)o(ercise\227which)g(is)h(why)0 2420 y(it)c(is)h(an)g(e)o(xample,)e(of)i(course!\).)0 2776 y Fe(3.2)119 b(T)-9 b(ypes)30 b(of)f(ar)o(guments)0 2983 y Ff(Since)e(scheme)g(e)o(xpressions)f(are)i(typed,)f(we)g(may)g (need)g(to)f(e)o(xamine)h(the)f(type)h(of)g(a)h(particular)e(e)o (xpression.)0 3104 y(The)f(follo)n(wing)e(functions)g(return)i (booleans,)f(and)h(can)g(be)g(used)g(to)f(determine)g(the)h(type)f(of)h (an)g(object.)146 3234 y Fd(#t)e Ff(and)g Fd(#f)g Ff(are)g(constants)f (representing)g(the)g(booleans)g(true)h(and)g(f)o(alse.)30 b(A)23 b(standard)f(scheme)h(con)l(v)o(ention)0 3354 y(is)35 b(to)h(name)g(functions)e(that)i(return)g(booleans)f(with)g(a)h (name)g(ending)f(with)g(\223?\224.)65 b(The)36 b(b)n(uilt-in)e (functions)0 3474 y(conform)24 b(to)h(this)f(con)l(v)o(ention.)146 3604 y(The)h(e)o(xpression)f Fg(e)n(xpr)h Ff(is)f(e)n(v)n(aluated,)g (and)g(the)h(type)f(of)h(the)g(result)f(of)h(e)n(v)n(aluation)e(is)h (check)o(ed.)p 996 3822 1908 4 v 994 3942 4 121 v 1046 3906 a Fd(\(boolean?)31 b Fg(e)n(xpr)p Fd(\))p 1850 3942 V 201 w(#t)25 b Ff(if)g Fg(e)n(xpr)g Ff(is)f(a)i(boolean)p 2902 3942 V 996 3946 1908 4 v 994 4066 4 121 v 1046 4030 a Fd(\(symbol?)k Fg(e)n(xpr)p Fd(\))p 1850 4066 V 229 w(#t)25 b Ff(if)g Fg(e)n(xpr)g Ff(is)f(a)i(symbol)p 2902 4066 V 996 4069 1908 4 v 994 4190 4 121 v 1046 4154 a Fd(\(list?)k Fg(e)n(xpr)p Fd(\))p 1850 4190 V 406 w(#t)25 b Ff(if)g Fg(e)n(xpr)g Ff(is)f(a)i(list)p 2902 4190 V 996 4193 1908 4 v 994 4313 4 121 v 1046 4277 a Fd(\(pair?)31 b Fg(e)n(xpr)p Fd(\))p 1850 4313 V 356 w(#t)25 b Ff(if)g Fg(e)n(xpr)g Ff(is)f(a)i(pair)p 2902 4313 V 996 4317 1908 4 v 994 4437 4 121 v 1046 4401 a Fd(\(number?)33 b Fg(e)n(xpr)p Fd(\))p 1850 4437 V 195 w(#t)25 b Ff(if)g Fg(e)n(xpr)g Ff(is)f(a)i(number)p 2902 4437 V 996 4440 1908 4 v 994 4561 4 121 v 1046 4525 a Fd(\(string?)31 b Fg(e)n(xpr)p Fd(\))p 1850 4561 V 284 w(#t)25 b Ff(if)g Fg(e)n(xpr)g Ff(is)f(a)i(string)p 2902 4561 V 996 4564 1908 4 v 994 4684 4 121 v 1046 4648 a Fd(\(pr)n(ocedur)n(e?)34 b Fg(e)n(xpr)p Fd(\))p 1850 4684 V 99 w(#t)25 b Ff(if)g Fg(e)n(xpr)g Ff(is)f(a)i(procedure)p 2902 4684 V 996 4688 1908 4 v 146 4939 a(F)o(or)f(e)o(xample,)900 5244 y Fd(\(boolean?)31 b(#t\))p Fc(=)p Fb(>)25 b Fg(#t)900 5364 y Fd(\(number?)33 b(#t\))p Fc(=)p Fb(>)24 b Fg(#f)1875 5649 y Ff(\2263\226)p eop %%Page: 4 4 4 3 bop 0 -180 a Ff(September)25 b(26,)f(2001)713 b(Magic)25 b(T)l(utorial)e(#S-1:)31 b(The)25 b(scheme)g(command-line)e (interpreter)0 82 y Fe(3.3)119 b(Lists)29 b(and)h(pairs)0 278 y Ff(A)i(pair)g(is)g(a)g(record)h(structure)e(with)h(tw)o(o)f (\002elds,)j(called)e(the)g(car)g(and)g(cdr)h(\002elds)f(\(for)g (historical)f(reasons\).)0 399 y(P)o(airs)24 b(are)g(used)g(primarily)f (to)g(represent)h(lists.)29 b(A)24 b(list)f(can)h(be)g(de\002ned)g (recursi)n(v)o(ely)f(as)h(either)g(the)f(empty)g(list,)0 519 y(or)31 b(a)f(pair)h(whose)f(cdr)h(\002eld)f(is)g(a)h(list.)47 b(The)30 b(follo)n(wing)f(functions)g(are)i(used)f(to)g(e)o(xtract)g (these)h(\002elds)f(and)g(to)0 640 y(construct)24 b(ne)n(w)h(pairs)f (and)h(lists.)p 446 813 3009 4 v 444 933 4 121 v 496 897 a Fd(\(car)g Fg(pair)p Fd(\))p 1203 933 V 362 w Ff(the)g(car)g (\002eld)g(of)g Fg(pair)p 3452 933 V 446 937 3009 4 v 444 1057 4 121 v 496 1021 a Fd(\(cdr)h Fg(pair)p Fd(\))p 1203 1057 V 356 w Ff(the)f(cdr)g(\002eld)g Fg(pair)p 3452 1057 V 446 1060 3009 4 v 444 1181 4 121 v 496 1144 a Fd(\(cons)g Fg(obj1)f(obj2)p Fd(\))p 1203 1181 V 99 w Ff(a)h(ne)n(w)g(pair)f(whose)h(car)g(\002eld)g(is)g Fg(obj1)f Ff(and)h(cdr)g(\002eld)g(is)f Fg(obj2)p 3452 1181 V 446 1184 3009 4 v 444 1304 4 121 v 496 1268 a Fd(\(list)g Fg(ar)l(g1)h(.)15 b(.)g(.)g Fd(\))p 1203 1304 V 210 w Ff(a)25 b(ne)n(w)g(list)e(consisting)g(of)i(its)f(ar)n (guments)p 3452 1304 V 446 1308 3009 4 v 444 1428 4 121 v 496 1392 a Fd(\(null?)31 b Fg(list)p Fd(\))p 1203 1428 V 322 w(#t)25 b Ff(if)g Fg(list)e Ff(is)i(the)f(empty)g(list)p 3452 1428 V 446 1431 3009 4 v 444 1552 4 121 v 496 1516 a Fd(\(length)i Fg(list)p Fd(\))p 1203 1552 V 278 w Ff(the)f(number)f (of)h(elements)f(in)g Fg(list)p 3452 1552 V 446 1555 3009 4 v 146 1767 a Ff(F)o(or)h(e)o(xample,)900 2028 y Fd(\(car)g('\(a)g(b)h(c\)\))p Fg(=)p Fb(>)f Fg(a)900 2148 y Fd(\(cdr)h('\(a)f(b)g(c\)\))p Fg(=)p Fb(>)h Fg(\(b)f(c\))900 2269 y Fd(\(cons)g('a)g('\(b)h(c\)\))p Fg(=)p Fb(>)f Fg(\(a)g(b)g(c\))900 2389 y Fd(\(list)f('a)h('b)h('c\))p Fg(=)p Fb(>)f Fg(\(a)g(b)g(c\))900 2509 y Fd(\(null?)31 b('\(a)25 b(b\)\))p Fg(=)p Fb(>)h Fg(#f)900 2630 y Fd(\(null?)31 b(\(\)\))p Fg(=)p Fb(>)26 b Fg(#t)146 2886 y Ff(The)f(car)h(\002eld)f (and)g(cdr)g(\002eld)g(of)g(a)g(pair)g(can)g(be)g(set)f(using)g(the)h (follo)n(wing)e(tw)o(o)h(functions.)p 411 3059 3079 4 v 409 3180 4 121 v 461 3144 a Fd(\(set-car!)32 b Fg(pair)24 b(obj)p Fd(\))p 1251 3180 V 104 w Ff(sets)h(the)f(car)i(\002eld)f(of)g Fg(pair)f Ff(to)g Fg(obj)p Ff(.)30 b(It)25 b(returns)g(the)f(ne)n(w)h (pair)p 3487 3180 V 411 3183 3079 4 v 409 3304 4 121 v 461 3267 a Fd(\(set-cdr!)32 b Fg(pair)24 b(obj)p Fd(\))p 1251 3304 V 99 w Ff(sets)h(the)f(cdr)h(\002eld)g(of)g Fg(pair)f Ff(to)h Fg(obj)p Ff(.)30 b(It)25 b(returns)f(the)h(ne)n(w)f (pair)p 3487 3304 V 411 3307 3079 4 v 146 3519 a(These)e(tw)o(o)e (functions)h(ha)n(v)o(e)g Fg(side-ef)n(fects)p Ff(,)g(another)g (feature)h(that)f(distinguishes)e(scheme)i(from)g(pure)g(lisp.)0 3640 y(Another)j(naming)g(con)l(v)o(ention)f(follo)n(wed)h(is)g(that)h (functions)e(that)i(ha)n(v)o(e)f(side-ef)n(fects)h(end)g(in)f (\223!\224.)146 3764 y(T)m(ry)h(the)f(follo)n(wing)f(sequence)i(in)g (magic:)900 4025 y Fd(\(de\002ne)i(x)d('\(a)i(b\)\))p Fg(=)p Fb(>)f Fg(\(a)g(b\))900 4145 y Fd(\(set-car!)32 b(x)25 b('c\))p Fg(=)p Fb(>)g Fg(\(c)g(b\))900 4266 y Fd(\(set-cdr!)32 b(x)25 b('\(q\)\))p Fg(=)p Fb(>)h Fg(\(c)g(q\))900 4386 y Fd(\(set-cdr!)32 b(x)25 b('q\))p Fg(=)p Fb(>)h Fg(\(c)f(.)31 b(q\))146 4763 y Ff(After)25 b(the)g(last)f(statement,)g (the)h(v)n(alue)f(of)h(x)g(is)f(no)g(longer)h(a)g(list)f(b)n(ut)g(a)h (pair)-5 b(.)0 5084 y Fe(3.4)119 b(Arithmetic)0 5280 y Ff(The)26 b(interpreter)f(supports)g(both)g(\003oating-point)f(and)h (inte)o(ger)g(arithmetic.)32 b(The)26 b(basic)f(arithmetic)g(functions) 0 5400 y(are)h(supported.)1875 5649 y(\2264\226)p eop %%Page: 5 5 5 4 bop 0 -180 a Ff(Magic)24 b(T)l(utorial)g(#S-1:)31 b(The)24 b(scheme)h(command-line)f(interpreter)713 b(September)25 b(26,)g(2001)p 1015 3 1871 4 v 1013 124 4 121 v 1065 88 a Fd(\(+)f Fg(num1)h(num2)p Fd(\))p 1735 124 V 106 w Ff(the)f(sum)g Fg(num1)p Ff(+)p Fg(num2)p 2884 124 V 1015 127 1871 4 v 1013 247 4 121 v 1065 211 a Fd(\(-)h Fg(num1)f(num2)p Fd(\))p 1735 247 V 130 w Ff(the)g(dif)n(ference)i Fg(num1)p Ff(-)p Fg(num2)p 2884 247 V 1015 251 1871 4 v 1013 371 4 121 v 1065 335 a Fd(\(*)e Fg(num1)h(num2)p Fd(\))p 1735 371 V 113 w Ff(the)f(product)h Fg(num1)p Ff(*)p Fg(num2)p 2884 371 V 1015 374 1871 4 v 1013 495 4 121 v 1065 459 a Fd(\(/)f Fg(num1)h(num2)p Fd(\))p 1735 495 V 135 w Ff(the)f(quotient)g Fg(num1)p Ff(/)p Fg(num2)p 2884 495 V 1015 498 1871 4 v 1013 619 4 121 v 1065 582 a Fd(\(truncate)i Fg(num)p Fd(\))p 1735 619 V 100 w Ff(the)e(inte)o(ger)g(part)h(of)g Fg(num)p 2884 619 V 1015 622 1871 4 v 146 831 a Ff(The)34 b(di)n(vision)d(operator)i (checks)h(for)f(di)n(vision)e(by)i(zero,)j(and)e(promotes)e(inte)o (gers)g(to)h(\003oating-point)f(if)0 951 y(deemed)39 b(necessary)-6 b(.)73 b(Floating-point)37 b(numbers)i(can)g(be)g(con)l (v)o(erted)g(into)f(inte)o(gers)g(by)h(truncation.)72 b(The)0 1072 y(range)25 b(of)g(a)g(number)f(can)i(be)f(check)o(ed)g (using)f(the)g(follo)n(wing)f(predicates:)p 1108 1241 1684 4 v 1106 1361 4 121 v 1158 1325 a Fd(\(zer)n(o?)32 b Fg(num)p Fd(\))p 1877 1361 V 271 w(#t)25 b Ff(if)f Fg(num)h Ff(is)f(zero)p 2790 1361 V 1108 1365 1684 4 v 1106 1485 4 121 v 1158 1449 a Fd(\(positi)o(v)o(e?)31 b Fg(num)p Fd(\))p 1877 1485 V 127 w(#t)25 b Ff(if)f Fg(num)h Ff(is)f(positi)n(v)o(e)p 2790 1485 V 1108 1488 1684 4 v 1106 1609 4 121 v 1158 1573 a Fd(\(negati)o(v)o(e?)31 b Fg(num)p Fd(\))p 1877 1609 V 100 w(#t)25 b Ff(if)f Fg(num)h Ff(is)f(ne)o(gati)n(v)o(e)p 2790 1609 V 1108 1612 1684 4 v 0 1871 a Fe(3.5)119 b(Strings)0 2066 y Ff(The)36 b(interpreter)g(supports)f(string)g(manipulation.)63 b(String)36 b(manipulation)e(can)i(be)h(useful)e(for)i(interaction)0 2187 y(with)24 b(the)h(user)g(as)f(well)h(as)g(constructing)e(names)i (for)g(labels.)p 142 2356 3617 4 v 140 2476 4 121 v 192 2440 a Fd(\(string-append)h Fg(str1)e(str2)p Fd(\))p 1317 2476 V 152 w Ff(the)h(string)f(formed)h(by)f(concatenating)g Fg(str1)g Ff(and)h Fg(str2)p 3757 2476 V 142 2480 3617 4 v 140 2600 4 121 v 192 2564 a Fd(\(string-length)h Fg(str)p Fd(\))p 1317 2600 V 431 w Ff(the)f(length)f(of)h(string)f Fg(str)p 3757 2600 V 142 2603 3617 4 v 140 2844 4 241 v 192 2688 a Fd(\(string-compar)n(e)i Fg(str1)e(str2)p Fd(\))p 1317 2844 V 98 w Ff(a)j(positi)n(v)o(e,)c(zero,)k(or)f(ne)o (gati)n(v)o(e)e(number)h(depending)g(on)h(whether)1368 2808 y Fg(str1)e Ff(is)h(le)o(xicographically)e(greater)l(,)i(equal)g (to,)f(or)h(less)g(than)f Fg(str2)p 3757 2844 V 142 2847 3617 4 v 140 3088 4 241 v 192 2932 a Fd(\(string-r)n(ef)i Fg(str)e(int)p Fd(\))p 1317 3088 V 447 w Ff(the)e(numerical)f(v)n(alue) g(of)h(the)f(character)i(stored)e(at)h(position)e Fg(int)h Ff(in)1368 3052 y Fg(str)k Ff(\(The)g(\002rst)g(character)g(is)g(at)g (position)e(0.\))p 3757 3088 V 142 3092 3617 4 v 140 3212 4 121 v 192 3176 a Fd(\(string-set!)31 b Fg(str)24 b(int1)g(int2)p Fd(\))p 1317 3212 V 182 w Ff(sets)h(character)h(in)e (string)g Fg(str)g Ff(at)h(position)e Fg(int1)h Ff(to)g Fg(int2)p 3757 3212 V 142 3215 3617 4 v 140 3456 4 241 v 192 3299 a Fd(\(substring)h Fg(str)f(int1)g(int2)p Fd(\))p 1317 3456 V 221 w Ff(returns)d(substring)e(of)h Fg(str)g Ff(from)g(position)f Fg(int1)h Ff(\(inclusi)n(v)o(e\))e(to)i Fg(int2)1368 3420 y Ff(\(e)o(xclusi)n(v)o(e\))p 3757 3456 V 142 3459 3617 4 v 146 3668 a(Strings)25 b(can)g(be)g(used)f(to)h (con)l(v)o(ert)f(to)g(and)h(from)g(v)n(arious)e(types.)p 304 3838 3292 4 v 302 3958 4 121 v 354 3922 a Fd(\(number)l(-)p Fb(>)p Fd(string)k Fg(num)p Fd(\))p 1383 3958 V 126 w Ff(the)d(string)g(corresponding)g(to)g(the)h(representation)f(of)h Fg(num)p 3594 3958 V 304 3961 3292 4 v 302 4082 4 121 v 354 4046 a Fd(\(string-)p Fb(>)p Fd(number)i Fg(str)p Fd(\))p 1383 4082 V 188 w Ff(the)d(number)h(corresponding)e(to)i Fg(str)p 3594 4082 V 304 4085 3292 4 v 302 4205 4 121 v 354 4169 a Fd(\(string-)p Fb(>)p Fd(symbol)g Fg(str)p Fd(\))p 1383 4205 V 221 w Ff(a)g(symbol)e(named)i Fg(str)p 3594 4205 V 304 4209 3292 4 v 302 4329 4 121 v 354 4293 a Fd(\(symbol)p Fa(\000)j Fb(>)p Fd(string)d Fg(sym)p Fd(\))p 1383 4329 V 100 w Ff(the)f(string)g(corresponding)g(to)g(the)h (name)g(of)g Fg(sym)p 3594 4329 V 304 4333 3292 4 v 0 4592 a Fe(3.6)119 b(Bindings)31 b(and)f(functions)0 4787 y Ff(An)21 b(object)f(\(more)h(accurately)-6 b(,)21 b(the)g Fg(location)f Ff(where)h(the)g(object)f(is)g(stored\))h(can)g(be)g (bound)f(to)h(a)g(symbol)e(using)0 4907 y(the)25 b(follo)n(wing)e(tw)o (o)h(functions:)p 132 5076 3636 4 v 130 5197 4 121 v 182 5161 a Fd(\(de\002ne)j Fg(sym)e(e)n(xpr)p Fd(\))p 931 5197 V 100 w Ff(bind)f Fg(e)n(xpr)h Ff(to)f Fg(sym)p Ff(,)h(creating)f(a)i(ne)n(w)e(symbol)f(if)i(necessary)g(and)g(return)g Fg(e)n(xpr)p 3766 5197 V 132 5200 3636 4 v 130 5320 4 121 v 182 5284 a Fd(\(set!)32 b Fg(sym)24 b(e)n(xpr)p Fd(\))p 931 5320 V 200 w Ff(bind)g Fg(e)n(xpr)h Ff(to)f(an)h(e)o (xisting)e(symbol)g Fg(sym)i Ff(and)g(return)g Fg(e)n(xpr)p 3766 5320 V 132 5324 3636 4 v 770 5400 a Ff(\(Note:)31 b(these)24 b(functions)g(do)h(not)f(e)n(v)n(aluate)g(their)g(\002rst)h (ar)n(gument.\))1875 5649 y(\2265\226)p eop %%Page: 6 6 6 5 bop 0 -180 a Ff(September)25 b(26,)f(2001)713 b(Magic)25 b(T)l(utorial)e(#S-1:)31 b(The)25 b(scheme)g(command-line)e (interpreter)146 69 y(The)i(dif)n(ference)g(between)g(the)g(tw)o(o)f (is)g(that)g Fd(de\002ne)j Ff(introduces)d(a)h(ne)n(w)f(binding,)f (whereas)j Fd(set!)31 b Ff(modi\002es)0 189 y(an)g(e)o(xisting)e (binding.)48 b(In)31 b(both)f(cases,)j Fg(e)n(xpr)e Ff(is)f(e)n(v)n (aluated,)i(and)f(the)f(result)h(is)f(bound)g(to)h(the)g(symbol)e Fg(sym)p Ff(.)0 309 y(The)c(result)f(of)h(the)g(e)n(v)n(aluation)e(is)h (also)g(returned.)900 473 y Fd(\(de\002ne)j(x)d(4\))p Fc(=)p Fb(>)h Fg(4)146 637 y Ff(Functions)c(can)g(be)h(de\002ned)f (using)f(lambda)h(e)o(xpressions.)28 b(T)-8 b(ypically)20 b(a)i(function)e(is)h(bound)f(to)h(a)h(v)n(ariable.)0 757 y(If)j(required,)g(a)g(lambda)f(e)o(xpression)g(or)h(b)n(uilt-in)e (function)h(can)h(be)g(applied)f(to)h(a)g(list.)p 1212 836 1476 4 v 1210 956 4 121 v 1262 920 a Fd(\(lambda)g Fg(list)f(obj)p Fd(\))p 1997 956 V 99 w Ff(a)h(ne)n(w)g(function)p 2686 956 V 1212 960 1476 4 v 963 1042 a(\(Note:)30 b(a)25 b(lambda)f(does)h(not)f(e)n(v)n(aluate)g(its)g(ar)n(guments.\))146 1205 y Fg(list)34 b Ff(is)g(a)h(list)e(of)i(symbol)e(names,)j(and)f Fg(obj)f Ff(is)g(the)g(e)o(xpression)f(that)h(corresponds)g(to)g(the)h (body)f(of)g(the)0 1326 y(function.)c(F)o(or)25 b(e)o(xample,)900 1490 y Fd(\(lambda)g(\(x)g(y)g(z\))g(\(+)g(\(+)g(x)g(y\))f(z\)\))p Fc(=)p Fb(>)i Fg(#pr)l(oc)146 1653 y Ff(is)33 b(a)h(function)f(that)g (tak)o(es)g(three)h(ar)n(guments)f(and)g(returns)g(their)g(sum.)56 b(It)34 b(can)f(be)h(bound)f(to)g(a)h(symbol)0 1774 y(using)24 b Fd(de\002ne)p Ff(.)900 1938 y Fd(\(de\002ne)j(sum3)e(\(lambda)g(\(x)g (y)f(z\))i(\(+)f(\(+)f(x)h(y\))g(z\)\)\))p Fc(=)p Fb(>)g Fg(#pr)l(oc)146 2101 y Ff(No)n(w)-6 b(,)24 b(we)h(can)g(use)g Fd(sum3)g Ff(lik)o(e)f(an)o(y)g(other)h(function.)900 2265 y Fd(\(sum3)g(5)g(3)f(8\))p Fc(=)p Fb(>)h Fg(16)146 2429 y Ff(A)g(function)f(can)h(be)g(applied)f(to)h(a)g(list)f(using)g Fd(apply)p Ff(.)p 1186 2508 1528 4 v 1184 2628 4 121 v 1236 2592 a Fd(\(apply)h Fg(pr)l(oc)g(list)p Fd(\))p 1939 2628 V 98 w Ff(apply)f Fg(pr)l(oc)g Ff(to)h Fg(list)p 2712 2628 V 1186 2631 1528 4 v 783 2713 a Ff(\(Note:)30 b(both)24 b Fg(pr)l(oc)g Ff(and)h Fg(list)f Ff(are)h(e)n(v)n(aluated)f (before)h(application.\))146 2877 y Fg(list)e Ff(is)g(used)h(as)g(the)f (list)g(of)h(ar)n(guments)f(for)h(the)f(function.)30 b(F)o(or)24 b(instance,)f(an)h(alternati)n(v)o(e)e(w)o(ay)i(to)f(sum)g (the)0 2997 y(three)i(numbers)f(in)g(the)h(e)o(xample)f(abo)o(v)o(e)g (is:)900 3161 y Fd(\(apply)h(sum3)g('\(3)g(5)g(8\)\))p Fc(=)p Fb(>)g Fg(16)146 3325 y Ff(An)g(alternati)n(v)o(e)e(method)h (for)h(creating)g(bindings)e(is)i(pro)o(vided)e(by)i(the)f Fd(let)h Ff(mechanism.)p 301 3402 3298 4 v 299 3522 4 121 v 351 3486 a Fd(\(let)g Fg(binding-list)e(e)n(xpr)p Fd(\))p 1386 3522 V 230 w Ff(e)n(v)n(aluate)h Fg(e)n(xpr)h Ff(after)h(the)e(bindings)f(ha)n(v)o(e)i(been)g(performed)p 3597 3522 V 301 3525 3298 4 v 299 3646 4 121 v 351 3609 a Fd(\(let*)g Fg(binding-list)d(e)n(xpr)p Fd(\))p 1386 3646 V 181 w Ff(e)n(v)n(aluate)i Fg(e)n(xpr)h Ff(after)h(the)e (bindings)f(ha)n(v)o(e)i(been)g(performed)p 3597 3646 V 301 3649 3298 4 v 299 3769 4 121 v 351 3733 a Fd(\(letr)n(ec)h Fg(binding-list)d(e)n(xpr)p Fd(\))p 1386 3769 V 99 w Ff(e)n(v)n(aluate)h Fg(e)n(xpr)h Ff(after)h(the)e(bindings)f(ha)n(v)o (e)i(been)g(performed)p 3597 3769 V 301 3773 3298 4 v 146 3893 a(The)g Fg(binding-list)e Ff(is)h(a)i(list)d(of)i(bindings.)30 b(Each)25 b(binding)e(is)i(a)g(list)f(containing)g(a)h(symbol)e(and)i (an)g(e)o(xpres-)0 4013 y(sion.)39 b(The)28 b(e)o(xpression)f(is)g(e)n (v)n(aluated)g(and)h(bound)f(to)h(the)f(symbol.)39 b(In)28 b(the)g(case)g(of)g Fd(let)p Ff(,)h(all)f(the)g(e)o(xpressions)0 4133 y(are)f(e)n(v)n(aluated)e(before)h(binding)f(them)g(to)h(an)o(y)g (symbol;)e Fd(let*)p Ff(,)j(on)e(the)h(other)g(hand,)g(e)n(v)n(aluates) f(an)h(e)o(xpression)0 4254 y(and)i(binds)g(it)g(to)g(the)h(symbol)e (before)i(e)n(v)n(aluating)d(the)j(ne)o(xt)e(e)o(xpression.)41 b Fd(letr)n(ec)30 b Ff(permits)d(bindings)g(to)h(refer)0 4374 y(to)h(each)h(other)l(,)h(permitting)c(mutually)h(recursi)n(v)o(e) h(function)f(de\002nitions.)44 b(The)29 b(e)n(v)n(aluation)f(order)i (is)f(de\002ned)0 4494 y(to)d(be)h(from)g(left)g(to)f(right)g(in)h(all) f(cases.)37 b(After)27 b(performing)g(the)f(bindings,)g Fg(e)n(xpr)h Ff(is)f(e)n(v)n(aluated)g(with)g(the)h(ne)n(w)0 4615 y(bindings)c(in)i(ef)n(fect)g(and)f(the)h(result)f(is)h(returned.) 146 4735 y Fd(let)g Ff(bindings)e(can)j(be)f(used)f(in)h(interesting)e (w)o(ays.)31 b(An)24 b(e)o(xample)g(of)h(their)g(use)f(is)h(pro)o (vided)e(later)-5 b(.)146 4856 y(Scheme)37 b(is)f(an)g(eager)h (language,)h(and)e(only)f(a)i(fe)n(w)f(functions)f(do)h(not)f(e)n(v)n (aluate)g(all)h(their)g(ar)n(guments)0 4976 y(\(de\002nitions)c(and)h (conditionals\).)53 b(Ev)n(aluation)31 b(can)i(be)g(controlled)f(to)g (some)h(de)o(gree)g(using)e(the)i(follo)n(wing)0 5096 y(tw)o(o)24 b(functions:)p 1100 5153 1700 4 v 1098 5273 4 121 v 1150 5237 a Fd(\(quote)i Fg(obj)p Fd(\))p 1655 5273 V 99 w Ff(the)f(une)n(v)n(aluated)e(object)i Fg(obj)p 2798 5273 V 1100 5276 1700 4 v 1098 5397 4 121 v 1150 5361 a Fd(\(e)o(v)o(al)f Fg(obj)p Fd(\))p 1655 5397 V 168 w Ff(e)n(v)n(aluates)g(object)g Fg(obj)p 2798 5397 V 1100 5400 1700 4 v 1875 5649 a Ff(\2266\226)p eop %%Page: 7 7 7 6 bop 0 -180 a Ff(Magic)24 b(T)l(utorial)g(#S-1:)31 b(The)24 b(scheme)h(command-line)f(interpreter)713 b(September)25 b(26,)g(2001)0 82 y Fe(3.7)119 b(Contr)n(ol)30 b(structur)n(es)0 270 y Ff(Since)23 b(scheme)f(is)g(a)h(functional)f(programming)f (language,)i(functions)e(that)h(are)h(usually)f(written)g(using)f (loops)0 390 y(are)37 b(written)f(using)f(recursion.)66 b(Conditional)35 b(constructs)g(are)i(used)g(to)f(terminate)f(the)i (recursion.)65 b(These)0 511 y(constructs)21 b(are)h(slightly)e(dif)n (ferent)i(in)f(that)h(the)o(y)f(do)g(not)g(e)n(v)n(aluate)g(all)h (their)f(ar)n(guments)g(\(otherwise)h(recursi)n(v)o(e)0 631 y(functions)i(w)o(ould)g(not)g(terminate!\).)p 552 750 2797 4 v 550 871 4 121 v 602 835 a Fd(\(if)h Fg(e)n(xpr)g(ar)l(g1)f (ar)l(g2)p Fd(\))p 1396 871 V 99 w Ff(e)n(v)n(aluate)g Fg(e)n(xpr)h Ff(and)g(e)n(v)n(aluate)f(one)h(of)f Fg(ar)l(g1)h Ff(or)g Fg(ar)l(g2)p 3346 871 V 552 874 2797 4 v 146 1040 a Ff(The)j Fd(if)g Ff(construct)f(e)n(v)n(aluates)g(its)g(\002rst) h(ar)n(gument)g(\(which)f(must)g(result)g(in)h(a)g(boolean\),)g(and)g (if)g(the)g(result)0 1160 y(is)c Fd(#t)h Ff(e)n(v)n(aluates)f Fg(ar)l(g1)g Ff(and)h(returns)g(the)f(result;)g(otherwise)g Fg(ar)l(g2)h Ff(is)f(e)n(v)n(aluated)g(and)h(returned.)146 1280 y(F)o(or)g(instance,)f(the)h(standard)f(f)o(actorial)h(function)f (might)g(be)h(written)f(as:)900 1485 y Fd(\(de\002ne)j(fact)e(\(lambda) g(\(x\))g(\(if)g(\(positi)o(v)o(e?)31 b(x\))25 b(\(*)f(x)h(\(fact)h (\(-)f(x)g(1\)\)\))g(1\)\)\))146 1689 y Ff(A)g(more)g(complicated)f (form)g(of)h(conditional)e(beha)n(vior)i(is)f(pro)o(vided)g(by)g Fd(cond)p Ff(.)p 989 1808 1922 4 v 987 1928 4 121 v 1039 1892 a Fd(\(cond)i Fg(ar)l(g1)e(ar)l(g2)h(...)p Fd(\))p 1877 1928 V 99 w Ff(generalized)h(conditional)p 2909 1928 V 989 1932 1922 4 v 146 2097 a(Each)j(ar)n(gument)e(consists)g(of) h(a)h(list)e(which)h(contains)f(tw)o(o)h(e)o(xpressions.)39 b(The)28 b(\002rst)g(e)o(xpression)f(is)h(e)n(v)n(al-)0 2217 y(uated)35 b(\(and)g(must)f(e)n(v)n(aluate)g(to)h(a)g(boolean\),)i (and)e(if)g(it)g(is)f(true)h(the)g(second)g(e)o(xpression)f(is)g(e)n(v) n(aluated)g(and)0 2338 y(returned)29 b(as)g(the)f(result)g(of)h(the)g (entire)g(e)o(xpression.)41 b(If)29 b(the)g(result)f(w)o(as)h(f)o (alse,)g(the)g(ne)o(xt)f(ar)n(gument)g(is)h(e)o(xam-)0 2458 y(ined)23 b(and)g(the)g(abo)o(v)o(e)f(procedure)h(is)g(repeated.) 30 b(If)24 b(all)f(ar)n(guments)f(e)n(v)n(aluate)g(to)h(f)o(alse,)g (the)g(result)g(is)f(unde\002ned.)146 2579 y(F)o(or)j(instance)f(if)h Fd(x)g Ff(w)o(as)g(a)g(list,)f(the)g(e)o(xpression)900 2783 y Fd(\(cond)i(\(\(null?)31 b(x\))25 b(x\))g(\(\(list?)30 b(x\))25 b(\(car)h(x\)\))f(\(#t)g(\(echo)2804 2783 y (") show 2804 2783 a 60 w Fd(err)n(or)3088 2783 y (") show 3088 2783 a 61 w Fd(\)\)\))146 2987 y Ff(w)o(ould)e(return)h(the)g(empty)f(list)g (if)h Fd(x)g Ff(w)o(as)g(the)f(empty)h(list)e(and)i(the)g(\002rst)g (element)f(from)h(the)g(list)f(otherwise.)0 3107 y(When)i Fd(x)g Ff(is)f(not)g(a)h(list,)f(an)h(error)g(message)g(is)f (displayed.)30 b(Note)24 b(that)h Fd(echo)g Ff(is)g(a)g(standard)f (magic)h(command.)146 3228 y(Often)g(one)f(needs)h(to)f(e)n(v)n(aluate) f(a)i(number)f(of)g(e)o(xpressions)f(in)h(sequence)h(\(since)f(the)h (language)f(has)g(side-)0 3348 y(ef)n(fects\).)31 b(The)25 b Fd(begin)g Ff(construct)f(can)i(be)f(used)f(for)h(this)f(purpose.)p 1000 3467 1900 4 v 998 3588 4 121 v 1050 3552 a Fd(\(begin)i Fg(ar)l(g1)e(ar)l(g2)g(.)15 b(.)g(.)g Fd(\))p 1960 3588 V 100 w Ff(sequencing)24 b(construct)p 2898 3588 V 1000 3591 1900 4 v 146 3757 a Fd(begin)29 b Ff(e)n(v)n(aluates)e(each)i(of)f (its)g(ar)n(guments)f(in)h(sequence,)h(and)g(returns)f(the)g(result)f (of)i(e)n(v)n(aluating)d(its)i(last)0 3877 y(ar)n(gument.)0 4169 y Fe(3.8)119 b(Interaction)30 b(with)h(lay)m(out)0 4356 y Ff(All)25 b(standard)h(magic)f(commands)g(are)i(also)e(scheme)h (functions.)33 b(This)25 b(permits)g(one)h(to)f(write)h(scheme)g(func-) 0 4477 y(tions)20 b(that)g(interact)g(with)g(the)h(layout)f(directly)-6 b(.)28 b(Apart)21 b(from)f(the)h(standard)f(magic)g(commands,)h(the)f (follo)n(wing)0 4597 y(scheme)25 b(functions)e(are)j(pro)o(vided)e(so)g (as)h(to)f(enable)h(the)g(user)g(to)f(edit)h(layout.)p 408 4714 3085 4 v 406 4835 4 121 v 458 4799 a Fd(\(getbox\))p 1051 4835 V 296 w Ff(a)h(list)d(containing)h(four)h(members)f(\(llx)g (lly)g(urx)h(ury\))p 3491 4835 V 408 4838 3085 4 v 406 5079 4 241 v 458 4922 a Fd(\(getpaint)g Fg(str)p Fd(\))p 1051 5079 V 99 w Ff(a)j(list)e(containing)g(the)h(box)o(es)f(from)h (layer)g Fg(str)f Ff(under)h(the)g(current)1102 5043 y(box)e(that)f(ha)n(v)o(e)h(paint)f(in)g(them)p 3491 5079 V 408 5082 3085 4 v 406 5323 4 241 v 458 5166 a Fd(\(getlabel)h Fg(str)p Fd(\))p 1051 5323 V 115 w Ff(a)e(list)f (containing)f(the)h(labels)g(under)h(the)f(current)h(box)f(that)g (match)1102 5287 y Fg(str)p 3491 5323 V 408 5326 3085 4 v 406 5446 4 121 v 458 5410 a Fd(\(magic)i Fg(sym)p Fd(\))p 1051 5446 V 144 w Ff(forces)i Fg(sym)e Ff(to)h(be)g (interpreted)f(as)h(a)g(magic)g(command)p 3491 5446 V 408 5450 3085 4 v 1875 5649 a(\2267\226)p eop %%Page: 8 8 8 7 bop 0 -180 a Ff(September)25 b(26,)f(2001)713 b(Magic)25 b(T)l(utorial)e(#S-1:)31 b(The)25 b(scheme)g(command-line)e (interpreter)146 68 y(The)30 b(pairs)f(\(llx,lly\))f(and)i(\(urx,ury\)) f(correspond)g(to)g(magic)h(coordinates)e(for)i(the)f(lo)n(wer)g(left)h (and)f(upper)0 188 y(right)35 b(corner)i(of)f(the)g(current)h(box.)64 b Fd(getpaint)37 b Ff(returns)f(a)g(list)f(of)i(box)o(es)e(\(llx)g(lly) h(urx)g(ury\),)j(and)d Fd(getlabel)0 309 y Ff(returns)29 b(a)h(list)f(of)h(tagged)f(box)o(es)g(\(label)g(llx)g(lly)g(urx)h (ury\))f(which)h(contain)f(the)g(label)g(string.)45 b Fd(magic)29 b Ff(can)h(be)0 429 y(used)h(to)g(force)h(the)f(scheme)g (interpreter)g(to)g(interpret)g(a)g(symbol)f(as)h(a)h(magic)e (procedure.)51 b(The)31 b(e)n(v)n(aluation)0 549 y(returns)25 b(the)f(speci\002ed)h(magic)g(command.)0 867 y Fe(3.9)119 b(Miscellaneous)0 1062 y Ff(Some)25 b(additional)e(functions)h(are)i (pro)o(vided)d(to)i(enable)f(the)h(user)g(to)f(deb)n(ug)h(functions.)p 591 1231 2718 4 v 589 1352 4 121 v 641 1316 a Fd(\(sho)o(wframe\))p 1505 1352 V 381 w Ff(display)f(the)g(current)h(list)f(of)h(bindings)p 3307 1352 V 591 1355 2718 4 v 589 1476 4 121 v 641 1439 a Fd(\(display-object)h Fg(obj)p Fd(\))p 1505 1476 V 99 w Ff(display)e(the)g(type)h(and)g(v)n(alue)f(of)h Fg(obj)p 3307 1476 V 591 1479 2718 4 v 589 1599 4 121 v 641 1563 a Fd(\(err)n(or)h Fg(str)p Fd(\))p 1505 1599 V 494 w Ff(display)e(error)h(message)g(and)f(abort)h(e)n(v)n(aluation)p 3307 1599 V 591 1603 2718 4 v 589 1723 4 121 v 641 1687 a Fd(\(eqv?)31 b Fg(obj1)24 b(obj2)p Fd(\))p 1505 1723 V 240 w Ff(checks)h(if)g(tw)o(o)f(objects)g(are)i(equal)p 3307 1723 V 591 1726 2718 4 v 589 1847 4 121 v 641 1810 a Fd(\(collect-garbage\))p 1505 1847 V 203 w Ff(force)f(garbage)g (collection)p 3307 1847 V 591 1850 2718 4 v 146 2059 a(The)g(follo)n(wing)d(is)i(a)h(complete)f(list)g(of)g(the)g(b)n (uilt-in)f(scheme)i(v)n(ariables)f(that)g(can)g(be)h(used)f(to)g (control)g(the)0 2179 y(interpreter)-5 b(.)p 163 2348 3575 4 v 161 2469 4 121 v 213 2433 a Fd(scm-library-path)p 1296 2469 V 410 w Ff(a)25 b(colon-separated)g(path)g(string)p 3735 2469 V 163 2472 3575 4 v 161 2713 4 241 v 213 2556 a Fd(scm-echo-r)n(esult)p 1296 2713 V 468 w Ff(a)48 b(boolean)e(used)h (to)g(determine)f(if)i(the)f(result)f(of)h(e)n(v)n(aluation)1347 2677 y(should)24 b(be)h(displayed)p 3735 2713 V 163 2716 3575 4 v 161 2837 4 121 v 213 2801 a Fd(scm-trace-magic)p 1296 2837 V 432 w Ff(controls)f(display)g(of)h(actual)g(magic)f (commands)p 3735 2837 V 163 2840 3575 4 v 161 2960 4 121 v 213 2924 a Fd(scm-echo-parser)l(-input)p 1296 2960 V 178 w Ff(controls)g(display)g(of)h(the)f(string)g(sent)h(to)f(the)h (scheme)f(parser)p 3735 2960 V 163 2964 3575 4 v 161 3084 4 121 v 213 3048 a Fd(scm-echo-parser)l(-output)p 1296 3084 V 123 w Ff(controls)g(display)g(of)h(the)f(result)h(of)g (parsing)p 3735 3084 V 163 3087 3575 4 v 161 3328 4 241 v 213 3172 a Fd(scm-stack-display-depth)p 1296 3328 V 101 w Ff(controls)j(the)h(number)f(of)h(frames)g(displayed)e(in)i(the)f (stack)h(trace)1347 3292 y(output)24 b(when)h(an)g(error)g(occurs)g (during)f(e)n(v)n(aluation)p 3735 3328 V 163 3331 3575 4 v 161 3452 4 121 v 213 3416 a Fd(scm-gc-fr)n(equency)p 1296 3452 V 386 w Ff(controls)g(the)h(frequenc)o(y)g(of)f(garbage)h (collection)p 3735 3452 V 163 3455 3575 4 v 0 3714 a Fe(3.10)119 b(Libraries)0 3909 y Ff(The)25 b(follo)n(wing)e(function)h (loads)g(in)g(a)h(\002le)h(and)e(e)n(v)n(aluates)g(its)g(contents)g(in) g(order)-5 b(.)p 343 4078 3215 4 v 341 4199 4 121 v 392 4163 a Fd(\(load-scm)25 b Fg(str)p Fd(\))p 1168 4199 V 248 w Ff(reads)g(scheme)g(commands)e(in)i(from)f(the)h(named)g (\002le)p 3556 4199 V 343 4202 3215 4 v 341 4322 4 121 v 392 4286 a Fd(\(sa)n(v)o(e-scm)g Fg(str)f(obj)p Fd(\))p 1168 4322 V 99 w Ff(appends)g Fg(obj)h Ff(to)f(the)h(\002le)g Fg(str)p Ff(,)f(creating)h(a)g(ne)n(w)f(\002le)i(if)e(necessary)p 3556 4322 V 343 4326 3215 4 v 146 4535 a(The)d(\002le)f(can)h(be)f(in)g (the)g(current)h(directory)-6 b(,)20 b(or)g(in)g(an)o(y)g(of)g(the)g (locations)f(speci\002ed)i(by)f(a)g(string)f(containing)0 4655 y(a)25 b(colon-separated)g(list)f(of)g(directory)h(names)f(stored) h(in)f Fd(scm-library-path)p Ff(.)146 4779 y(The)35 b(format)g(of)g (these)f(\002les)i(dif)n(fers)e(from)h(standard)f(magic)h(source)g (\002les)g(because)g(the)g(contents)f(of)h(a)0 4899 y(line)e(are)h(not) f(implicitly)f(parenthesized.)57 b(In)33 b(addition,)i(semicolons)d (are)i(used)f(as)h(a)g(comment)e(character;)0 5020 y(e)n(v)o(erything) 23 b(follo)n(wing)g(a)i(semicolon)e(to)i(the)g(end)f(of)h(the)g (current)g(line)f(is)h(treated)g(as)f(a)i(comment.)146 5144 y(F)o(or)f(instance,)900 5400 y Fd(de\002ne)i(f)e(\(lambda)g (\(x\))g(x\))1875 5649 y Ff(\2268\226)p eop %%Page: 9 9 9 8 bop 0 -180 a Ff(Magic)24 b(T)l(utorial)g(#S-1:)31 b(The)24 b(scheme)h(command-line)f(interpreter)713 b(September)25 b(26,)g(2001)146 69 y(w)o(ould)h(de\002ne)i Fd(f)f Ff(to)f(be)i(the)e (identity)g(function)g(when)g(placed)h(in)g(a)g(magic)g(source)g (\002le)g(\(so)g(as)g(to)f(pro)o(vide)0 189 y(backw)o(ard)d (compatibility\).)k(The)c(same)f(de\002nition)g(w)o(ould)g(result)g(in) g(an)g(error)i(if)e(placed)h(in)f(a)h(scheme)f(source)0 309 y(\002le.)900 538 y Fd(\(de\002ne)27 b(f)e(\(lambda)g(\(x\))g (x\)\))146 766 y Ff(The)g(abo)o(v)o(e)f(e)o(xpression)f(should)h(be)h (used)g(in)f(the)h(scheme)f(\002le)i(to)e(achie)n(v)o(e)g(the)h(same)f (ef)n(fect.)0 1106 y Fh(Refer)m(ences)0 1329 y Ff([1])49 b(H.)25 b(Abelson)f(and)g(G.J.)h(Sussman,)35 b Fg(Structur)l(e)24 b(and)g(Interpr)l(etation)f(of)i(Computer)f(Pr)l(o)o(gr)o(ams)p Ff(.)0 1532 y([2])49 b(H.)25 b(Abelson)f Fg(et)g(al.)p Ff(,)36 b Fg(Re)o(vised)24 b(Report)g(on)h(the)f(Algorithmic)f(Langua)o (g)o(e)i(Sc)o(heme)p Ff(.)1875 5649 y(\2269\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tutscm2.ps0000644000175000001440000005734610751423606015654 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: tutscm2.dvi %%Pages: 4 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips tutscm2.dvi -o tutscm2.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Bold % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet %%BeginProcSet: special.pro TeXDict begin /SDict 200 dict N SDict begin /@SpecialDefaults{/hs 612 N /vs 792 N /ho 0 N /vo 0 N /hsc 1 N /vsc 1 N /ang 0 N /CLIP 0 N /rwiSeen false N /rhiSeen false N /letter{}N /note{}N /a4{}N /legal{}N}B /@scaleunit 100 N /@hscale{@scaleunit div /hsc X}B /@vscale{@scaleunit div /vsc X}B /@hsize{/hs X /CLIP 1 N}B /@vsize{/vs X /CLIP 1 N}B /@clip{ /CLIP 2 N}B /@hoffset{/ho X}B /@voffset{/vo X}B /@angle{/ang X}B /@rwi{ 10 div /rwi X /rwiSeen true N}B /@rhi{10 div /rhi X /rhiSeen true N}B /@llx{/llx X}B /@lly{/lly X}B /@urx{/urx X}B /@ury{/ury X}B /magscale true def end /@MacSetUp{userdict /md known{userdict /md get type /dicttype eq{userdict begin md length 10 add md maxlength ge{/md md dup length 20 add dict copy def}if end md begin /letter{}N /note{}N /legal{} N /od{txpose 1 0 mtx defaultmatrix dtransform S atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{itransform lineto} }{6 -2 roll transform 6 -2 roll transform 6 -2 roll transform{ itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll curveto}}{{ closepath}}pathforall newpath counttomark array astore /gc xdf pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack}if}N /txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 -1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop 90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr 2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 -1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S TR}if}N /cp {pop pop showpage pm restore}N end}if}if}N /normalscale{Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale}if 0 setgray} N /psfts{S 65781.76 div N}N /startTexFig{/psf$SavedState save N userdict maxlength dict begin /magscale true def normalscale currentpoint TR /psf$ury psfts /psf$urx psfts /psf$lly psfts /psf$llx psfts /psf$y psfts /psf$x psfts currentpoint /psf$cy X /psf$cx X /psf$sx psf$x psf$urx psf$llx sub div N /psf$sy psf$y psf$ury psf$lly sub div N psf$sx psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub TR /showpage{}N /erasepage{}N /copypage{}N /p 3 def @MacSetUp}N /doclip{ psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath moveto}N /endTexFig{end psf$SavedState restore}N /@beginspecial{SDict begin /SpecialSave save N gsave normalscale currentpoint TR @SpecialDefaults count /ocount X /dcount countdictstack N}N /@setspecial {CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR }{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury lineto closepath clip}if /showpage{}N /erasepage{}N /copypage{}N newpath }N /@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{ end}repeat grestore SpecialSave restore end}N /@defspecial{SDict begin} N /@fedspecial{end}B /li{lineto}B /rl{rlineto}B /rc{rcurveto}B /np{ /SaveX currentpoint /SaveY X N 1 setlinecap newpath}N /st{stroke SaveX SaveY moveto}N /fil{fill SaveX SaveY moveto}N /ellipse{/endangle X /startangle X /yrad X /xrad X /savematrix matrix currentmatrix N TR xrad yrad scale 0 0 1 startangle endangle arc savematrix setmatrix}N end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tutscm2.dvi) @start /Fa 133[44 50 50 1[50 55 33 39 44 1[55 50 55 83 28 2[28 55 50 33 44 55 44 55 50 30[66 2[50 1[57 2[33 3[50 50 50 50 50 50 2[25 33 1[57 50 33 33 33 3[50 1[33 30[55 2[{ TeXBase1Encoding ReEncodeFont }42 100.000003 /Times-Bold rf /Fb 138[66 40 47 53 2[60 66 100 33 2[33 66 2[53 66 53 1[60 12[80 6[113 9[86 8[40 55[66 2[{ TeXBase1Encoding ReEncodeFont }19 119.999948 /Times-Bold rf /Fc 105[50 1[44 44 24[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 1[28 50 50 33 44 50 44 50 44 9[94 2[61 55 66 1[55 1[72 89 3[33 72 1[55 61 72 66 66 72 6[28 50 1[50 50 50 50 50 50 50 50 1[25 33 25 2[33 33 33 3[50 32[55 2[{ TeXBase1Encoding ReEncodeFont }61 100.000003 /Times-Roman rf /Fd 139[28 1[39 2[50 50 3[28 28 50 2[44 3[50 14[61 3[66 83 35[33 33 40[{ TeXBase1Encoding ReEncodeFont }14 100.000003 /Times-Italic rf /Fe 133[64 1[72 104 72 80 48 56 64 2[72 80 120 40 2[40 80 72 48 64 80 64 80 72 9[143 2[96 80 5[135 96 5[88 3[96 7[48 3[72 72 72 72 72 72 3[48 9[72 35[{ TeXBase1Encoding ReEncodeFont }37 143.999997 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 787 101 a Fe(Magic)35 b(T)-13 b(utorial)34 b(#S-2:)43 b(Boxes)35 b(and)g(labels)1655 521 y Fd(Rajit)24 b(Manohar)1282 941 y Fc(Department)g(of)h(Computer)f(Science)1271 1062 y(California)h(Institute)f(of)h(T)-7 b(echnology)1534 1182 y(P)o(asadena,)25 b(CA)h(91125)1053 1453 y(This)e(tutorial)g (corresponds)g(to)g(Magic)h(v)o(ersion)e(7.)0 1973 y Fb(T)-11 b(utorials)30 b(to)f(r)n(ead)h(\002rst:)300 2171 y Fc(Magic)24 b(T)l(utorial)g(#S-1:)31 b(The)24 b(scheme)h(command-line)f(interpreter)0 2368 y Fb(Commands)29 b(intr)n(oduced)j(in)f(this)f(tutorial:)300 2566 y Fc(:getbox,)24 b(:box.push,)f(:box.pop,)g(:box.mo)o(v)o(e,)f(:label.v)o(ert,)i (:label.horiz,)300 2686 y(:label.rename,)g(:label.search,)h (:label.\002nd-ne)o(xt)0 2884 y Fb(Macr)n(os)k(intr)n(oduced)i(in)g (this)f(tutorial:)300 3104 y Fd(\(None\))0 3693 y Fe(1)143 b(The)35 b(curr)m(ent)g(box)0 3916 y Fc(The)28 b(fundamental)e(w)o(ay)i (scheme)f(programs)g(interact)h(with)e(magic)h(layout)g(is)g(by)h (using)e(magic')-5 b(s)27 b Fa(box)g Fc(com-)0 4037 y(mand.)j(F)o(or)25 b(instance,)900 4257 y Fa(\(box)g(1)g(1)g(2)f(2\))146 4478 y Fc(changes)d(the)g(current)g(box)f(to)g(the)h(rectangle)g (de\002ned)g(by)g(the)f(coordinates)h(\(1,1\))f(and)h(\(2,2\))g(in)f (the)h(current)0 4598 y(edit)k(cell.)32 b(This)25 b(is)f(the)i (standard)e(magic)h Fa(:box)h Fc(command.)31 b(After)26 b(mo)o(ving)d(the)i(box)g(to)g(a)h(particular)f(position)0 4718 y(in)f(the)h(layout,)f(the)h(area)g(can)h(be)f(painted,)f(erased,) h(selected,)g(etc.)146 4839 y(The)g(scheme)g(function)f Fa(getbox)h Fc(returns)g(the)f(current)h(box)g(as)f(a)i(list)d(of)i (four)g(inte)o(gers.)30 b(F)o(or)25 b(instance,)900 5059 y Fa(\(box)g(1)g(1)g(2)f(2\))900 5180 y(\(de\002ne)j(x)d(\(getbox\)\)) 146 5400 y Fc(will)g(bind)g(the)h(list)f Fa(\(1)h(1)f(2)h(2\))g Fc(to)f(v)n(ariable)h Fa(x)p Fc(.)1875 5649 y(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Fc(September)25 b(26,)f(2001)1559 b(Magic)24 b(T)l(utorial)g(#S-2:)30 b(Box)o(es)25 b(and)g(labels)0 99 y Fe(2)143 b(Sa)l(ving)35 b(and)g(r)m(estoring)f(the)h(box)0 322 y Fc(If)29 b(a)h(scheme)f(function)f(mo)o(v)o(es)f(the)i(current)g (box)g(around,)g(it)g(is)f(good)h(practice)g(to)g(restore)g(the)g(box)f (back)h(to)0 443 y(its)23 b(original)f(position.)28 b(This)23 b(is)g(especially)g(useful)g(when)g(writing)f(a)i(function)f(that)f (the)i(user)f(is)g(lik)o(ely)f(to)h(type)0 563 y(on)i(the)f(command)g (line.)146 683 y Fa(box.push)j Fc(can)f(be)g(used)g(to)f(push)g(a)h (box)g(onto)f(the)g(current)h(stack)g(of)g(box)o(es.)33 b Fa(box.pop)26 b Fc(restores)g(the)g(box)0 804 y(to)e(the)h(one)g(on)f (the)h(top)f(of)h(the)g(box)f(stack.)31 b(The)24 b(sequence)900 998 y Fa(\(box.push)i(\(getbox\)\))900 1118 y(\(box)f(1)g(1)g(5)f(4\)) 900 1239 y(\(paint)i(poly\))900 1359 y(\(box.pop\))146 1553 y Fc(will)31 b(paint)g(a)g(rectangle)h(of)g(polysilicon)d(from)i (\(1,1\))h(to)f(\(5,4\),)i(restoring)d(the)i(original)e(position)g(of)h (the)0 1674 y(box.)0 2009 y Fe(3)143 b(Mo)o(ving)35 b(the)g(box)0 2232 y Fc(Magic')-5 b(s)24 b(b)n(uilt-in)f Fa(mo)o(v)o(e)i Fc(command)f(is)g(not)g(entirely)g(reliable.)31 b(Sometimes)23 b(mo)o(v)o(e)h(commands)f(are)j(ignored,)0 2353 y(with)j(disastrous)e (ef)n(fects.)45 b(\(Think)28 b(about)h(what)g(might)f(happen)h(if)h(a)f (mo)o(v)o(e)f(command)g(w)o(as)i(ignored)e(in)h(the)0 2473 y(middle)g(of)g(dra)o(wing)g(a)h(stack)g(of)g(twenty)f (transistors)f(.)46 b(.)g(.\))f(The)30 b(scheme)g(function)f Fa(box.mo)o(v)o(e)g Fc(mo)o(v)o(es)f(the)0 2593 y(box)c(relati)n(v)o(e) g(to)g(the)h(current)g(position.)900 2787 y Fa(\(box.mo)o(v)o(e)g(5)g (3\))146 2982 y Fc(will)f(mo)o(v)o(e)g(the)g(box)h(right)f(5)g(lambda)h (and)f(up)h(3)g(lambda.)0 3316 y Fe(4)143 b(Labelling)34 b(v)o(ertical)g(and)h(horizontal)e(wir)m(es)0 3540 y Fc(Datapaths)21 b(are)i(usually)d(designed)h(by)h(designing)e(cells)i (for)g(a)g(single)f(bit)g(of)g(the)h(datapath,)g(and)g(then)f(arraying) 0 3660 y(those)27 b(cells)g(to)g(obtain)f(the)i(complete)e(datapath.)39 b(When)27 b(simulating)e(such)i(designs,)g(it)g(is)g(usually)f (desirable)0 3781 y(to)e(label)h(wires)g(in)f(the)h(datapath)f(with)g (names)h(lik)o(e)f(\223name0\224,)h(\223name1\224,)g(up)f(to)h (\223nameN.)-7 b(\224)146 3901 y(There)21 b(are)h(tw)o(o)e(functions)g (that)g(can)h(be)g(used)f(to)h(perform)f(such)h(a)g(task.)29 b(The)20 b(function)g Fa(label.v)o(ert)h Fc(returns)0 4022 y(a)j(function)e(that)h(can)h(be)f(used)g(as)h(a)g(labeller)f(for) g(v)o(ertically)g(arrayed)h(nodes.)30 b Fa(label.horiz)23 b Fc(returns)g(a)h(function)0 4142 y(that)g(can)i(be)e(used)h(as)g(a)g (labeller)g(for)g(horizontally)e(arrayed)j(nodes.)900 4336 y Fa(\(de\002ne)h(lbl)d(\(label.v)o(ert)1807 4336 y (") show 1807 4336 a 59 w Fa(name)2098 4336 y (") show 2098 4336 a 86 w Fa(6\))146 4530 y Fc(The)29 b(command)e(abo)o(v)o(e)h(de\002nes)h(a)g (ne)n(w)f(function)f Fa(lbl)i Fc(that)f(can)h(be)g(used)f(to)g (generate)h(labels)f(be)o(ginning)0 4651 y(with)213 4651 y (") show 213 4651 a 60 w Fc(name0)539 4651 y (") show 539 4651 a 95 w Fc(for)35 b(nodes)h(that)f(are)h(v)o(ertically)e(spaced)i(by)f(6)h (lambda.)62 b(The)36 b(simplest)e(w)o(ay)h(to)h(use)f(this)0 4771 y(function)24 b(is)g(to)h(bind)f(it)g(to)g(a)i(macro)e(as)h(follo) n(ws:)900 4965 y Fa(\(macr)n(o)g(1)1302 4965 y (") show 1302 4965 a 60 w Fa(lbl)1473 4965 y (") show 1473 4965 a 59 w Fa(\))146 5159 y Fc(Place)32 b(the)f(box)g(o)o(v)o(er)f(the)h(lo)n(west)f(node.) 49 b(Ev)o(ery)31 b(time)f(k)o(e)o(y)h(\2231\224)g(is)g(pressed,)i(a)e (ne)n(w)g(label)g(\223nameM\224)g(is)0 5280 y(created)j(and)f(the)g (box)g(is)g(mo)o(v)o(ed)e(up)i(by)g(6)g(lambda.)55 b Fa(label.horiz)34 b Fc(can)f(be)h(used)f(in)g(a)g(similar)f(f)o(ashion) h(for)0 5400 y(labelling)24 b(nodes)g(that)g(are)i(horizontally)d (arrayed.)1875 5649 y(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Fc(Magic)24 b(T)l(utorial)g(#S-2:)31 b(Box)o(es)24 b(and)h(labels)1558 b(September)25 b(26,)g(2001)0 99 y Fe(5)143 b(Finding)34 b(and)i(r)m(enaming)e(existing)g(labels)0 323 y Fc(The)25 b(label)g(macros)g(pro)o(vide)f(functionality)f(to)i (search)h(for)f(all)g(labels)g(that)f(match)h(a)h(particular)f(string.) 30 b(Place)0 444 y(the)25 b(box)f(o)o(v)o(er)g(the)h(re)o(gion)f(of)g (interest.)31 b(T)-8 b(ype:)900 675 y Fa(\(label.sear)n(ch)1463 675 y (") show 1463 675 a 59 w Fa(label)1727 675 y (") show 1727 675 a 60 w Fa(\))146 906 y Fc(T)g(o)25 b(place)g(the)g(box)f(o)o(v)o(er)g (the)h(\002rst)g(occurrence)g(of)g(the)g(label)g(you)f(searched)h(for)l (,)g(type:)900 1138 y Fa(\(label.\002nd-next\))146 1369 y Fc(Repeatedly)20 b(e)o(x)o(ecuting)f(this)f(function)h(causes)h(the)g (box)f(to)g(mo)o(v)o(e)g(to)g(all)g(the)h(labels)f(that)h(match)f(the)h (search)0 1490 y(pattern.)30 b(T)-8 b(ypically)i(,)24 b(one)g(w)o(ould)g(bind)g Fa(label.\002nd-next)j Fc(to)d(a)i(macro.)146 1610 y(The)k(command)e Fa(label.r)n(ename)j Fc(can)f(be)g(used)f(to)g (rename)h(all)f(labels)g(with)g(a)h(particular)f(name.)45 b(T)-8 b(o)29 b(use)0 1731 y(this)24 b(command,)g(place)h(the)f(box)h (o)o(v)o(er)f(the)g(re)o(gion)g(of)h(interest.)30 b(Then)25 b(type)900 1963 y Fa(\(label.r)n(ename)1507 1963 y (") show 1507 1963 a 60 w Fa(label1)1822 1963 y (") show 1822 1963 a 1906 1963 a (") show 1906 1963 a 60 w Fa(label2)2221 1963 y (") show 2221 1963 a 59 w Fa(\))146 2194 y Fc(All)g(occurrences)g(of)g(label)g (\223label1\224)f(in)h(the)g(current)g(box)f(will)g(be)h(renamed)g(to)f (\223label2\224.)0 2536 y Fe(6)143 b(Writing)35 b(these)g(functions)0 2760 y Fc(The)h(functions)f(discussed)g(in)g(this)g(tutorial)g(are)i (not)e(b)n(uilt-in.)63 b(The)o(y)35 b(are)h(user)n(-de\002ned)h (functions)e(in)g(the)0 2881 y(def)o(ault)25 b(scheme)f(\002le)h (loaded)g(in)f(when)h(magic)f(starts.)146 3001 y(As)32 b(you)f(be)o(gin)g(to)h(use)f(magic)h(with)f(the)g(scheme)h (command-line)e(interpreter)l(,)k(you)d(will)g(observ)o(e)h(that)0 3122 y(commands)26 b(for)h(dra)o(wing)g(paint)f(on)h(the)g(screen)h (are)g(e)o(xtremely)e(slo)n(w)-6 b(.)36 b(This)26 b(time)h(interv)n(al) f(is)h(not)f(normally)0 3242 y(noticeable)e(because)h(editing)f(is)g (interacti)n(v)o(e.)29 b(Ho)n(we)n(v)o(er)l(,)24 b(when)g(one)h(can)g (write)f(a)h(scheme)g(program)f(to)g(dra)o(w)0 3363 y(twenty)k (transistors)g(on)g(the)h(screen,)h(this)e(delay)h(becomes)f (noticeable.)43 b(It)28 b(is)h(w)o(orthwhile)f(to)g(minimize)f(the)0 3483 y(number)g(of)g(magic)g(commands)f(e)o(x)o(ecuted,)h(e)n(v)o(en)g (if)g(this)f(in)l(v)n(olv)o(es)g(writing)g(more)h(scheme)g(code.)39 b(The)27 b Fa(box-)0 3603 y(pop)g Fc(command)e(has)i(been)f(tuned)g(a)h (little)e(to)h(not)f(e)o(x)o(ecute)h(the)g Fa(box)h Fc(command)e(if)h (the)h(box)e(w)o(ould)h(not)g(mo)o(v)o(e)0 3724 y(as)f(a)g(result.)300 3955 y Fa(\(de\002ne)i(box.list)d(\(\)\))300 4196 y(\(de\002ne)j (box.mo)o(v)o(e)600 4317 y(\(lambda)e(\(dx)g(dy\))900 4437 y(\(let*)g(\(\(x)g(\(getbox\)\))1138 4557 y(\(nllx)g(\(+)g(dx)g (\(car)g(x\)\)\))1138 4678 y(\(nlly)g(\(+)g(dy)g(\(cadr)h(x\)\)\))1138 4798 y(\(nurx)g(\(+)f(dx)g(\(caddr)h(x\)\)\))1138 4918 y(\(nury)g(\(+)f(dy)g(\(cadddr)i(x\)\)\)\))900 5039 y(\(box)e(nllx)g (nlly)f(nurx)i(nury\))900 5159 y(\))600 5280 y(\))300 5400 y(\))1875 5649 y Fc(\2263\226)p eop %%Page: 4 4 4 3 bop 0 -180 a Fc(September)25 b(26,)f(2001)1559 b(Magic)24 b(T)l(utorial)g(#S-2:)30 b(Box)o(es)25 b(and)g(labels)300 205 y Fa(\(de\002ne)i(box.=?)600 325 y(\(lambda)e(\(b1)g(b2\))900 445 y(\(and)h(\(and)f(\(=?)31 b(\(car)25 b(b1\))h(\(car)f(b2\)\))g (\(=?)31 b(\(cadr)26 b(b1\))f(\(cadr)h(b2\)\)\))1138 566 y(\(and)g(\(=?)k(\(caddr)d(b1\))e(\(caddr)h(b2\)\))f(\(=?)31 b(\(caddr)26 b(b1\))g(\(caddr)g(b2\)\)\))900 686 y(\))600 807 y(\))300 927 y(\))300 1168 y(\(de\002ne)h(box.push)600 1288 y(\(lambda)e(\(pos\))900 1408 y(\(set!)31 b(box.list)25 b(\(cons)g(pos)g(box.list\)\))600 1529 y(\))300 1649 y(\))300 1878 y(\(de\002ne)i(box.pop)600 1998 y(\(lambda)e(\(\))900 2118 y(\(if)g(\(null?)31 b(box.list\))1138 2239 y(\(echo)1390 2239 y (") show 1390 2239 a 60 w Fa(Box)25 b(list)f(is)g(empty)2149 2239 y (") show 2149 2239 a 61 w Fa(\))1138 2359 y(\(let)h(\(\(x)g(\(car)h (box.list\)\)\))1438 2479 y(\(begin)1438 2600 y(\(set!)32 b(box.list)24 b(\(cdr)i(box.list\)\))1438 2720 y(\(if)f(\(box.=?)31 b(x)24 b(\(getbox\)\))i(#t)f(\(e)o(v)o(al)f(\(cons)h('box)g(x\)\)\)) 1438 2841 y(\))1138 2961 y(\))900 3081 y(\))600 3202 y(\))300 3322 y(\))1875 5649 y Fc(\2264\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tut5.ps0000644000175000001440000011370110751423606015140 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: tut5.dvi %%Pages: 6 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips tut5.dvi -o tut5.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Bold % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tut5.dvi) @start /Fa 134[50 50 72 50 55 33 39 44 1[55 50 55 83 28 2[28 55 50 33 44 55 44 55 50 3[33 1[33 6[66 4[78 72 4[39 1[78 1[66 72 1[66 7[33 2[50 1[50 6[25 1[25 44[{ TeXBase1Encoding ReEncodeFont }37 100.000003 /Times-Bold rf /Fb 133[53 2[86 60 66 40 47 53 1[66 60 66 100 33 2[33 66 60 40 53 66 53 1[60 9[120 2[80 66 86 2[93 1[113 9[86 8[40 4[60 60 60 60 60 2[30 42[66 66 2[{ TeXBase1Encoding ReEncodeFont } 36 119.999948 /Times-Bold rf /Fc 104[100 50 1[44 44 24[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 3[33 1[33 1[72 72 94 72 72 61 55 2[55 72 72 89 61 1[39 33 72 72 55 61 72 66 66 72 1[44 3[28 28 50 50 50 50 50 50 50 50 50 50 1[25 33 25 56 1[33 33 33 1[83 1[50 1[33 29[55 55 2[{ TeXBase1Encoding ReEncodeFont }79 100.000003 /Times-Roman rf /Fd 134[44 2[44 50 28 39 39 1[50 50 50 72 28 2[28 50 50 1[44 50 44 50 50 11[72 55 50 61 3[66 83 30[25 1[25 2[33 33 37[50 2[{ TeXBase1Encoding ReEncodeFont }30 100.000003 /Times-Italic rf /Fe 136[104 1[80 48 56 64 1[80 72 80 120 40 80 1[40 1[72 48 64 80 64 1[72 9[143 2[96 80 5[135 3[56 112 2[96 1[104 8[48 4[72 72 72 72 72 13[72 35[{ TeXBase1Encoding ReEncodeFont } 33 143.999997 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 791 101 a Fe(Magic)35 b(T)-13 b(utorial)34 b(#5:)43 b(Multiple)35 b(W)m(indo)o(ws)1630 521 y Fd(Robert)24 b(N.)i(Mayo)1401 941 y Fc(Computer)e(Science)i(Di)n(vision)1020 1062 y(Electrical)f(Engineering)f(and)h(Computer)f(Sciences)1473 1182 y(Uni)n(v)o(ersity)f(of)i(California)1544 1303 y(Berk)o(ele)o(y)-6 b(,)24 b(CA)h(94720)1448 1573 y Fd(\(Updated)f(by)h(other)o(s,)f (too.\))1053 1843 y Fc(This)g(tutorial)g(corresponds)g(to)g(Magic)h(v)o (ersion)e(7.)0 2336 y Fb(T)-11 b(utorials)30 b(to)f(r)n(ead)h(\002rst:) 300 2513 y Fc(Magic)24 b(T)l(utorial)g(#1:)30 b(Getting)24 b(Started)300 2633 y(Magic)g(T)l(utorial)g(#2:)30 b(Basic)25 b(P)o(ainting)f(and)h(Selection)0 2810 y Fb(Commands)k(intr)n(oduced)j (in)f(this)f(tutorial:)300 2987 y Fc(:center)25 b(:close)n(windo)n(w)-6 b(,)22 b(:openwindo)n(w)-6 b(,)22 b(:o)o(v)o(er)l(,)i(:specialopen,)f (:under)l(,)i(:windo)n(wpositions)0 3164 y Fb(Macr)n(os)k(intr)n (oduced)i(in)g(this)f(tutorial:)300 3356 y Fc(o,)25 b(O,)f(\223,)-7 b(\224)0 4213 y Fe(1)143 b(Intr)m(oduction)0 4437 y Fc(A)25 b(windo)n(w)f(is)h(a)g(rectangular)h(vie)n(wport.)31 b(Y)-11 b(ou)25 b(can)g(think)f(of)i(it)f(as)g(a)g(magnifying)f(glass)h (that)g(may)f(be)i(mo)o(v)o(ed)0 4557 y(around)32 b(on)h(your)f(chip.) 53 b(Magic)32 b(initially)f(displays)g(a)i(single)f(windo)n(w)f(on)h (the)g(screen.)55 b(This)32 b(tutorial)f(will)0 4678 y(sho)n(w)23 b(you)h(ho)n(w)g(to)g(create)h(ne)n(w)f(windo)n(ws)f(and)h (ho)n(w)g(to)g(mo)o(v)o(e)e(old)i(ones)g(around.)31 b(Multiple)22 b(windo)n(ws)h(allo)n(w)0 4798 y(you)h(to)h(vie)n(w)f(se)n(v)o(eral)g (portions)f(of)i(a)g(circuit)g(at)g(the)f(same)h(time,)f(or)h(e)n(v)o (en)f(portions)f(of)i(dif)n(ferent)g(circuits.)146 4918 y(Some)34 b(operations)f(are)i(easier)f(with)f(multiple)f(windo)n(ws.) 56 b(F)o(or)34 b(e)o(xample,)h(let')-5 b(s)33 b(say)g(that)h(you)f(w)o (ant)g(to)0 5039 y(paint)c(a)h(v)o(ery)f(long)g(line,)i(say)e(3)h (units)e(by)i(800)f(units.)44 b(W)l(ith)29 b(a)h(single)f(windo)n(w)f (it)i(is)f(hard)h(to)f(align)g(the)h(box)0 5159 y(accurately)g(since)e (the)h(magni\002cation)f(is)h(not)g(great)g(enough.)43 b(W)l(ith)28 b(multiple)g(windo)n(ws,)g(one)h(windo)n(w)f(can)0 5280 y(sho)n(w)c(the)g(big)g(picture)h(while)f(other)g(windo)n(ws)f (sho)n(w)h(magni\002ed)g(vie)n(ws)g(of)g(the)h(areas)g(where)g(the)g (box)f(needs)0 5400 y(to)g(be)h(aligned.)30 b(The)25 b(box)g(can)g(then)f(be)h(positioned)e(accurately)j(in)e(these)h (magni\002ed)f(windo)n(ws.)1875 5649 y(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Fc(September)25 b(26,)f(2001)1577 b(Magic)25 b(T)l(utorial)e(#5:)30 b(Multiple)24 b(W)l(indo)n(ws)0 99 y Fe(2)143 b(Manipulating)34 b(W)m(indo)o(ws)0 356 y Fb(2.1)119 b(Opening)31 b(and)g(Closing)f(W)n(indo)o(ws)0 548 y Fc(Initially)23 b(Magic)i(displays)e(one)i(lar)n(ge)g(windo)n(w) -6 b(.)29 b(The)900 793 y Fa(:openwindo)o(w)d Fc([)p Fd(cellname)p Fc(])146 1036 y(command)31 b(opens)h(another)g(windo)n(w) e(and)i(loads)g(the)g(gi)n(v)o(en)e(cell.)52 b(T)-8 b(o)32 b(gi)n(v)o(e)f(this)g(a)h(try)-6 b(,)33 b(start)f(up)f(Magic)0 1157 y(with)24 b(the)i(command)e Fa(magic)h(tut5a)p Fc(.)32 b(Then)25 b(point)g(an)o(ywhere)g(in)g(a)g(Magic)g(windo)n(w)f(and)h (type)g(the)g(command)0 1277 y Fa(:openwindo)o(w)i(tut5b)h Fc(\(mak)o(e)e(sure)g(you')-5 b(re)26 b(pointing)e(to)i(a)h(Magic)e (windo)n(w\).)34 b(A)26 b(ne)n(w)g(windo)n(w)e(will)h(appear)0 1398 y(and)j(it)f(will)f(contain)h(the)h(cell)f Fa(tut5b)p Fc(.)40 b(If)28 b(you)f(don')n(t)h(gi)n(v)o(e)e(a)i Fd(cellname)f Fc(ar)n(gument)g(to)g Fa(:openwindo)o(w)p Fc(,)j(it)d(will)0 1518 y(open)33 b(a)g(ne)n(w)f(windo)n(w)g(on)g(the)h(cell)g(containing) f(the)g(box,)j(and)e(will)f(zoom)g(in)g(on)h(the)g(box.)54 b(The)33 b(macro)g Fa(o)0 1638 y Fc(is)28 b(prede\002ned)i(to)e Fa(:openwindo)o(w)p Fc(.)44 b(T)m(ry)28 b(this)g(out)g(by)g(placing)g (the)h(box)f(around)h(an)f(area)i(of)f Fa(tut5b)h Fc(and)e(then)0 1759 y(typing)e Fa(o)p Fc(.)37 b(Another)26 b(windo)n(w)g(will)g (appear)-5 b(.)37 b(Y)-11 b(ou)27 b(no)n(w)f(ha)n(v)o(e)h(three)g (windo)n(ws,)f(all)h(of)g(which)f(display)g(pieces)0 1879 y(of)g(layout.)34 b(There)27 b(are)g(other)f(kinds)f(of)i(windo)n (ws)d(in)i(Magic)g(besides)g(layout)f(windo)n(ws:)32 b(you')o(ll)25 b(learn)i(about)0 1999 y(them)21 b(later)-5 b(.)30 b(Magic)21 b(doesn')n(t)h(care)h(ho)n(w)e(man)o(y)g(windo)n(ws)f (you)i(ha)n(v)o(e)f(\(within)g(reason\))h(nor)g(ho)n(w)f(the)o(y)g(o)o (v)o(erlap.)146 2122 y(T)-8 b(o)25 b(get)g(rid)f(of)h(a)g(windo)n(w)-6 b(,)23 b(point)h(to)g(it)h(and)f(type)900 2367 y Fa(:closewindo)o(w)146 2610 y Fc(or)h(use)g(the)g(macro)f Fa(O)p Fc(.)h(Point)f(to)g(a)i (portion)d(of)i(the)g(original)f(windo)n(w)f(and)i(close)g(it.)0 2919 y Fb(2.2)119 b(Resizing)31 b(and)f(Mo)o(ving)g(W)n(indo)o(ws)0 3111 y Fc(If)24 b(you)f(ha)n(v)o(e)g(been)h(e)o(xperimenting)d(with)i (Magic)g(while)g(reading)g(this)f(you)h(will)g(ha)n(v)o(e)g(noticed)g (that)g(windo)n(ws)0 3232 y(opened)33 b(by)f Fa(:openwindo)o(w)i Fc(are)f(all)g(the)f(same)h(size.)54 b(If)33 b(you')-5 b(d)33 b(prefer)g(a)g(dif)n(ferent)g(arrangement)f(you)h(can)0 3352 y(resize)21 b(your)f(windo)n(ws)f(or)i(mo)o(v)o(e)e(them)h(around) g(on)g(the)h(screen.)29 b(The)21 b(techniques)f(used)g(for)h(this)e (are)j(dif)n(ferent,)0 3472 y(ho)n(we)n(v)o(er)l(,)g(depending)g(on)h (what)g(kind)f(of)h(display)f(you')-5 b(re)23 b(using.)29 b(If)23 b(you)g(are)h(using)e(a)h(w)o(orkstation,)f(then)h(you)0 3593 y(are)35 b(also)e(running)g(a)i(windo)n(w)d(system)h(such)h(as)g (X11)f(or)h(SunV)-6 b(ie)n(w)g(.)57 b(In)34 b(this)f(case)i(Magic')-5 b(s)33 b(windo)n(ws)f(are)0 3713 y(mo)o(v)o(ed)20 b(and)i(resized)h (just)e(lik)o(e)g(the)h(other)g(windo)n(ws)e(you)i(ha)n(v)o(e)g (displayed,)f(and)h(you)g(can)g(skip)f(the)h(rest)g(of)g(this)0 3834 y(section.)146 3956 y(F)o(or)36 b(displays)e(lik)o(e)h(the)g(AED)g (f)o(amily)-6 b(,)37 b(which)e(don')n(t)g(ha)n(v)o(e)g(a)h(b)n(uilt-in) e(windo)n(w)g(package,)39 b(Magic)c(im-)0 4076 y(plements)27 b(its)g(o)n(wn)g(windo)n(w)g(manager)-5 b(.)39 b(T)-8 b(o)28 b(re-arrange)h(windo)n(ws)d(on)i(the)g(screen)g(you)g(can)g(use) g(techniques)0 4197 y(similar)g(to)h(those)g(you)g(learned)h(for)g(mo)o (ving)d(the)j(box)f(for)g(painting)g(operations.)43 b(Point)29 b(some)n(where)g(in)g(the)0 4317 y(border)d(area)g(of)g(a)g(windo)n(w) -6 b(,)23 b(e)o(xcept)j(for)f(the)h(lo)n(wer)f(left)g(corner)l(,)h(and) g(press)f(and)h(hold)e(the)i(right)e(b)n(utton.)32 b(The)0 4438 y(cursor)25 b(will)f(change)h(to)f(a)h(shape)g(lik)o(e)f(this:)p 1790 4596 320 4 v 1948 4716 4 121 v 2108 4716 V 1790 4719 320 4 v 1948 4840 4 121 v 2108 4840 V 146 5039 a(This)36 b(indicates)g(that)g(you)g(ha)n(v)o(e)g(hold)f(of)i(the)f(upper)h (right)e(corner)i(of)g(the)f(windo)n(w)-6 b(.)64 b(Point)36 b(to)g(a)h(ne)n(w)0 5159 y(location)29 b(for)h(this)f(corner)h(and)g (release)g(the)g(b)n(utton.)44 b(The)29 b(windo)n(w)g(will)g(change)h (shape)f(so)h(that)f(the)h(corner)0 5280 y(mo)o(v)o(es.)j(No)n(w)25 b(point)h(to)f(the)h(border)h(area)g(and)f(press)g(and)g(hold)f(the)h (left)g(b)n(utton.)34 b(The)26 b(cursor)g(will)g(no)n(w)f(look)0 5400 y(lik)o(e:)1875 5649 y(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Fc(Magic)24 b(T)l(utorial)g(#5:)30 b(Multiple)23 b(W)l(indo)n(ws)1576 b(September)25 b(26,)g(2001)p 1790 3 320 4 v 1788 124 4 121 v 1948 124 V 2108 124 V 1790 127 320 4 v 1788 247 4 121 v 1948 247 V 2108 247 V 1790 251 320 4 v 146 465 a(This)34 b(indicates)f(that)h(you)f(ha)n(v)o(e)h (hold)g(of)g(the)g(entire)g(windo)n(w)f(by)h(its)f(lo)n(wer)h(left)g (windo)n(w)-6 b(.)57 b(Mo)o(v)o(e)32 b(the)0 586 y(cursor)h(and)g (release)g(the)g(b)n(utton.)53 b(The)33 b(windo)n(w)e(will)h(mo)o(v)o (e)g(so)g(that)h(its)f(lo)n(wer)g(left)h(corner)g(is)f(where)i(you)0 706 y(pointed.)146 831 y(The)d(other)g(b)n(utton)f(commands)g(for)h (positioning)e(the)i(box)f(by)h(an)o(y)g(of)g(its)f(corners)i(also)e(w) o(ork)h(for)g(win-)0 951 y(do)n(ws.)f(Just)24 b(remember)g(to)h(point)e (to)i(the)g(border)f(of)h(a)g(windo)n(w)f(before)h(pushing)f(the)g(b)n (uttons.)146 1076 y(The)29 b(middle)e(b)n(utton)h(can)h(be)g(used)f(to) g(gro)n(w)g(a)h(windo)n(w)e(up)i(to)f(full-screen)g(size.)43 b(T)-8 b(o)28 b(try)g(this,)h(click)f(the)0 1196 y(middle)22 b(b)n(utton)g(o)o(v)o(er)g(the)h(caption)g(of)g(the)g(windo)n(w)-6 b(.)29 b(The)23 b(windo)n(w)f(will)g(no)n(w)g(\002ll)h(the)g(entire)h (screen.)30 b(Click)23 b(in)0 1316 y(the)i(caption)f(again)g(and)h(the) f(windo)n(w)g(will)g(shrink)g(back)h(to)f(its)g(former)h(size.)0 1639 y Fb(2.3)119 b(Shuf\003ing)32 b(W)n(indo)o(ws)0 1836 y Fc(By)21 b(no)n(w)f(you)h(kno)n(w)e(ho)n(w)h(to)h(open,)g (close,)h(and)e(resize)i(windo)n(ws.)27 b(This)20 b(is)h(suf)n (\002cient)f(for)h(most)f(purposes,)h(b)n(ut)0 1956 y(sometimes)i(you)h (w)o(ant)g(to)g(look)g(at)h(a)f(windo)n(w)g(that)g(is)g(co)o(v)o(ered)g (up)g(by)g(another)g(windo)n(w)-6 b(.)29 b(The)c Fa(:under)o(neath)0 2077 y Fc(and)g Fa(:o)o(v)o(er)g Fc(commands)f(help)g(with)g(this.)146 2201 y(The)30 b Fa(:under)o(neath)i Fc(command)c(mo)o(v)o(es)f(the)j (windo)n(w)e(that)h(you)f(are)j(pointing)c(at)j(underneath)f(all)g(of)g (the)0 2322 y(other)d(windo)n(ws.)34 b(The)26 b Fa(:o)o(v)o(er)g Fc(command)g(mo)o(v)o(es)e(the)i(windo)n(w)f(on)h(top)g(of)g(the)g (rest.)36 b(Create)27 b(a)g(fe)n(w)f(windo)n(ws)0 2442 y(that)38 b(o)o(v)o(erlap)g(and)g(then)h(use)f(these)g(commands)g(to)g (mo)o(v)o(e)f(them)h(around.)72 b(Y)-11 b(ou')o(ll)38 b(see)h(that)f(o)o(v)o(erlapping)0 2563 y(windo)n(ws)21 b(beha)n(v)o(e)i(just)f(lik)o(e)g(sheets)g(of)h(paper:)30 b(the)23 b(ones)f(on)h(top)f(obscure)h(portions)e(of)i(the)g(ones)f (underneath.)0 2885 y Fb(2.4)119 b(Scr)n(olling)31 b(W)n(indo)o(ws)0 3082 y Fc(Some)25 b(of)g(the)g(windo)n(ws)f(ha)n(v)o(e)h(thick)f(bars)i (on)f(the)g(left)g(and)g(bottom)e(borders.)32 b(These)25 b(are)h(called)f Fd(scr)l(oll)f(bar)o(s)p Fc(,)0 3202 y(and)j(the)f(slugs)g(within)f(them)h(are)h(called)g Fd(ele)o(vator)o(s)p Fc(.)35 b(The)27 b(size)f(and)h(position)e(of)i (an)f(ele)n(v)n(ator)g(indicates)g(ho)n(w)0 3323 y(much)f(of)h(the)f (layout)g(\(or)h(whate)n(v)o(er)f(is)g(in)h(the)f(windo)n(w\))g(is)g (currently)h(visible.)32 b(If)26 b(an)g(ele)n(v)n(ator)e(\002lls)i(its) f(scroll)0 3443 y(bar)l(,)k(then)e(all)h(of)f(the)h(layout)f(is)g (visible)g(in)g(that)h(windo)n(w)-6 b(.)37 b(If)28 b(an)g(ele)n(v)n (ator)f(\002lls)g(only)g(a)i(portion)d(of)i(the)g(scroll)0 3563 y(bar)l(,)c(then)f(only)f(that)h(portion)g(of)g(the)g(layout)g(is) g(visible.)29 b(The)23 b(position)f(of)h(the)g(ele)n(v)n(ator)g (indicates)f(which)h(part)0 3684 y(is)28 b(visible\227if)f(it)h(is)h (near)g(the)g(bottom,)f(you)g(are)h(vie)n(wing)f(the)g(bottom)f(part)i (of)g(the)f(layout;)i(if)f(it)f(is)g(near)h(the)0 3804 y(top,)c(you)g(are)h(vie)n(wing)e(the)i(top)e(part)i(of)f(the)h (layout.)32 b(There)26 b(are)g(scroll)f(bars)g(for)h(both)f(the)g(v)o (ertical)g(direction)0 3925 y(\(the)g(left)g(scroll)f(bar\))h(and)g (the)g(horizontal)e(direction)h(\(the)h(bottom)f(scroll)g(bar\).)146 4049 y(Besides)29 b(indicating)f(ho)n(w)g(much)h(is)f(visible,)h(the)g (scroll)g(bars)g(can)g(be)g(used)g(to)g(change)g(the)g(vie)n(w)f(of)h (the)0 4170 y(windo)n(w)-6 b(.)32 b(Clicking)26 b(the)f(middle)g(mouse) g(b)n(utton)g(in)h(a)g(scroll)f(bar)i(mo)o(v)o(es)d(the)i(ele)n(v)n (ator)f(to)g(that)h(position.)32 b(F)o(or)0 4290 y(e)o(xample,)d(if)g (you)f(are)i(vie)n(wing)d(the)i(lo)n(wer)f(half)h(of)g(a)g(chip)g (\(ele)n(v)n(ator)f(near)h(the)g(bottom\))e(and)i(you)g(click)f(the)0 4410 y(middle)23 b(b)n(utton)h(near)h(the)f(top)g(of)h(the)f(scroll)g (bar)l(,)h(the)g(ele)n(v)n(ator)e(will)h(mo)o(v)o(e)f(up)h(to)g(that)h (position)d(and)j(you)f(will)0 4531 y(be)f(vie)n(wing)e(the)h(top)g (part)h(of)f(your)h(chip.)29 b(The)23 b(little)e(squares)h(with)g(arro) n(ws)g(in)h(them)e(at)i(the)f(ends)h(of)f(the)h(scroll)0 4651 y(bars)32 b(will)f(scroll)h(the)g(vie)n(w)f(by)h(one)g(screenful)g (when)g(the)g(middle)f(b)n(utton)g(is)g(click)o(ed)h(on)g(them.)52 b(The)o(y)31 b(are)0 4772 y(useful)g(when)g(you)f(w)o(ant)h(to)g(mo)o (v)o(e)f(e)o(xactly)g(one)h(screenful.)50 b(The)31 b Fa(:scr)n(oll)g Fc(command)f(can)i(also)e(be)i(used)e(to)0 4892 y(scroll)c(the)g(vie)n(w)g(\(though)g(we)h(don')n(t)f(think)f(it') -5 b(s)26 b(as)g(easy)h(to)f(use)h(as)f(the)h(scroll)f(bars\).)36 b(See)27 b(the)g(man)f(page)h(for)0 5012 y(information)c(on)i(it.)146 5137 y(If)h(you)e(only)g(w)o(ant)h(to)f(mak)o(e)h(a)g(small)f (adjustment)f(in)h(a)h(windo)n(w')-5 b(s)23 b(vie)n(w)-6 b(,)24 b(you)g(can)h(use)g(the)g(command)900 5400 y Fa(:center)1875 5649 y Fc(\2263\226)p eop %%Page: 4 4 4 3 bop 0 -180 a Fc(September)25 b(26,)f(2001)1577 b(Magic)25 b(T)l(utorial)e(#5:)30 b(Multiple)24 b(W)l(indo)n(ws)146 68 y(It)29 b(will)e(mo)o(v)o(e)g(the)h(vie)n(w)g(in)g(the)g(windo)n(w)f (so)h(that)g(the)g(point)f(that)h(used)g(to)g(be)h(underneath)f(the)g (cursor)h(is)0 188 y(no)n(w)24 b(in)g(the)h(middle)f(of)h(the)f(windo)n (w)-6 b(.)29 b(The)c(macro)g Fa(,)g Fc(is)f(prede\002ned)h(to)g Fa(:center)p Fc(.)146 309 y(The)19 b(b)n(ull')-5 b(s-e)o(ye)18 b(in)h(the)g(lo)n(wer)f(left)h(corner)h(of)f(a)h(windo)n(w)e(is)g(used) h(to)g(zoom)f(the)h(vie)n(w)g(in)f(and)i(out.)28 b(Clicking)0 429 y(the)34 b(left)f(mouse)g(b)n(utton)g(zooms)g(the)g(vie)n(w)g(out)h (by)f(a)h(f)o(actor)g(of)g(2,)i(and)e(clicking)f(the)g(right)g(mouse)g (b)n(utton)0 549 y(zooms)23 b(in)f(by)h(a)h(f)o(actor)g(of)f(2.)30 b(Clicking)23 b(the)g(middle)f(b)n(utton)g(here)i(mak)o(es)f(e)n(v)o (erything)e(in)i(the)g(windo)n(w)f(visible)0 670 y(and)j(is)f(equi)n(v) n(alent)f(to)i(the)f Fa(:view)h Fc(command.)0 963 y Fb(2.5)119 b(Sa)m(ving)30 b(W)n(indo)o(w)h(Con\002gurations)0 1151 y Fc(After)i(setting)e(up)h(a)h(b)n(unch)e(of)i(windo)n(ws)e(you)h(may) g(w)o(ant)g(to)g(sa)n(v)o(e)g(the)g(con\002guration)g(\(for)g(e)o (xample,)i(you)0 1271 y(may)24 b(be)h(partial)g(to)f(a)h(set)g(of)g(3)g (non-o)o(v)o(erlapping)d(windo)n(ws\).)29 b(T)-8 b(o)25 b(do)f(this,)g(type:)900 1484 y Fa(:windo)o(wpositions)h Fd(\002lename)146 1698 y Fc(A)g(set)g(of)g(commands)e(will)h(be)h (written)f(to)h(the)f(\002le.)31 b(This)25 b(\002le)g(can)g(be)g(used)f (with)g(the)h Fa(:sour)n(ce)h Fc(command)0 1818 y(to)e(recreate)h(the)f (windo)n(w)f(con\002guration)g(later)-5 b(.)31 b(\(Ho)n(we)n(v)o(er)l (,)23 b(this)g(only)g(w)o(orks)h(well)g(if)g(you)g(stay)f(on)h(the)g (same)0 1939 y(kind)j(of)i(display;)f(if)g(you)g(create)h(a)f(\002le)h (under)f(X11)g(and)g(then)f Fa(:sour)n(ce)j Fc(it)d(under)h(SunV)-6 b(ie)n(w)g(,)28 b(you)g(might)f(not)0 2059 y(get)e(the)f(same)h (positions)e(since)h(the)h(coordinate)f(systems)g(may)g(v)n(ary)-6 b(.\))0 2397 y Fe(3)143 b(Ho)o(w)35 b(Commands)e(W)-11 b(ork)36 b(Inside)e(of)i(W)m(indo)o(ws)0 2620 y Fc(Each)25 b(windo)n(w)e(has)i(a)g(caption)g(at)f(the)h(top.)30 b(Here)c(is)e(an)h(e)o(xample:)900 2834 y Fa(mychip)g(EDITING)g (shiftcell)146 3047 y Fc(This)33 b(indicates)g(that)g(the)g(windo)n(w)f (contains)g(the)i(root)f(cell)g Fa(mychip)p Fc(,)j(and)d(that)g(a)h (subcell)f(of)g(it)g(called)0 3167 y Fa(shiftcell)27 b Fc(is)f(being)g(edited.)36 b(Y)-11 b(ou)26 b(may)h(remember)f(from)h (the)f(T)l(utorial)g(#4)g(that)g(at)h(an)o(y)f(gi)n(v)o(en)f(time)h (Magic)h(is)0 3288 y(editing)e(e)o(xactly)g(one)h(cell.)34 b(If)27 b(the)f(edit)f(cell)h(is)g(in)f(another)h(windo)n(w)f(then)g (the)h(caption)g(on)f(this)g(windo)n(w)g(will)0 3408 y(read:)900 3622 y Fa(mychip)g([NO)l(T)g(BEING)g(EDITED])146 3835 y Fc(Let')-5 b(s)33 b(do)g(an)h(e)o(xample)e(to)h(see)h(ho)n(w)e (commands)g(are)i(e)o(x)o(ecuted)f(within)f(windo)n(ws.)55 b(Close)33 b(an)o(y)g(layout)0 3955 y(windo)n(ws)d(that)h(you)h(may)f (ha)n(v)o(e)h(on)f(the)h(screen)g(and)g(open)f(tw)o(o)h(ne)n(w)f(windo) n(ws,)h(each)g(containing)f(the)g(cell)0 4076 y Fa(tut5a)p Fc(.)54 b(\(Use)32 b(the)h Fa(:closewindo)o(w)f Fc(and)h Fa(:openwindo)o(w)g(tut5a)g Fc(commands)e(to)h(do)g(this.\))53 b(T)m(ry)32 b(mo)o(ving)e(the)0 4196 y(box)25 b(around)g(in)g(one)g(of) g(the)h(windo)n(ws.)k(Notice)25 b(that)g(the)g(box)g(also)g(mo)o(v)o (es)e(in)i(the)g(other)g(windo)n(w)-6 b(.)31 b(W)l(indo)n(ws)0 4317 y(containing)h(the)i(same)g(root)f(cell)h(are)g(equi)n(v)n(alent)e (as)i(f)o(ar)h(as)e(the)h(box)f(is)h(concerned:)49 b(if)33 b(it)h(appears)g(in)f(one)0 4437 y(it)e(will)g(appear)h(in)g(all,)h (and)f(it)f(can)h(be)g(manipulated)e(from)i(them)f(interchangeably)-6 b(.)50 b(If)32 b(you)g(change)g Fa(tut5a)0 4557 y Fc(by)g(painting)f (or)h(erasing)g(portions)f(of)h(it)f(you)h(will)f(see)i(the)f(changes)g (in)f(both)h(windo)n(ws.)51 b(This)31 b(is)h(because)0 4678 y(both)c(windo)n(ws)e(are)k(looking)d(at)h(the)g(same)g(thing:)37 b(the)28 b(cell)h Fa(tut5a)p Fc(.)42 b(Go)28 b(ahead)h(and)f(try)g (some)g(painting)f(and)0 4798 y(erasing)k(until)e(you)h(feel)h (comfortable)g(with)f(it.)48 b(T)m(ry)30 b(positioning)e(one)j(corner)g (of)g(the)f(box)g(in)h(one)f(windo)n(w)0 4918 y(and)g(another)g(corner) g(in)g(another)f(windo)n(w)-6 b(.)45 b(Y)-11 b(ou')o(ll)29 b(\002nd)h(it)f(doesn')n(t)h(matter)f(which)h(windo)n(w)e(you)i(point)f (to,)0 5039 y(all)c(Magic)f(kno)n(ws)g(is)g(that)g(you)h(are)g (pointing)e(to)i Fa(tut5a)p Fc(.)146 5159 y(These)j(windo)n(ws)e(are)j (independent)e(in)g(some)g(respects,)i(ho)n(we)n(v)o(er)-5 b(.)38 b(F)o(or)27 b(e)o(xample,)h(you)f(may)h(scroll)f(one)0 5280 y(windo)n(w)f(around)h(without)f(af)n(fecting)h(the)g(other)g (windo)n(w)-6 b(.)36 b(Use)28 b(the)f(scrollbars)f(to)h(gi)n(v)o(e)f (this)h(a)g(try)-6 b(.)38 b(Y)-11 b(ou)27 b(can)0 5400 y(also)d(e)o(xpand)h(and)f(une)o(xpand)g(cells)h(independently)e(in)h (dif)n(ferent)h(windo)n(ws.)1875 5649 y(\2264\226)p eop %%Page: 5 5 5 4 bop 0 -180 a Fc(Magic)24 b(T)l(utorial)g(#5:)30 b(Multiple)23 b(W)l(indo)n(ws)1576 b(September)25 b(26,)g(2001)146 68 y(W)-8 b(e)40 b(ha)n(v)o(e)f(seen)g(ho)n(w)g(Magic)g(beha)n(v)o(es)g (when)g(both)f(windo)n(ws)g(vie)n(w)g(a)i(single)e(cell.)74 b(What)40 b(happens)0 188 y(when)35 b(windo)n(ws)e(vie)n(w)h(dif)n (ferent)h(cells?)61 b(T)-8 b(o)35 b(try)f(this)g(out)h(load)f Fa(tut5b)i Fc(into)e(one)h(of)g(the)g(windo)n(ws)e(\(point)0 309 y(to)38 b(a)h(windo)n(w)d(and)j(type)f Fa(:load)g(tut5b)p Fc(\).)73 b(Y)-11 b(ou)38 b(will)f(see)i(the)f(captions)f(on)h(the)g (windo)n(ws)f(change\227only)0 429 y(one)e(windo)n(w)f(contains)g(the)h (cell)g(currently)g(being)f(edited.)61 b(The)35 b(box)g(cannot)f(be)i (positioned)d(by)i(placing)0 549 y(one)i(corner)h(in)f(one)g(windo)n(w) f(and)h(another)g(corner)g(in)g(the)g(other)g(windo)n(w)f(because)i (that)e(doesn')n(t)h(really)0 670 y(mak)o(e)d(sense)g(\(try)h(it\).)58 b(Ho)n(we)n(v)o(er)l(,)36 b(the)e(selection)f(commands)g(w)o(ork)i (between)f(windo)n(ws:)48 b(you)33 b(can)i(select)0 790 y(information)c(in)h(one)g(windo)n(w)f(and)i(then)f(cop)o(y)g(it)g (into)f(another)h(\(this)g(only)f(w)o(orks)h(if)h(the)f(windo)n(w)f (you')-5 b(re)0 911 y(cop)o(ying)24 b(into)g(contains)g(the)g(edit)h (cell;)f(if)h(not,)f(you')o(ll)g(ha)n(v)o(e)h(to)f(use)h(the)f Fa(:edit)i Fc(command)e(\002rst\).)146 1032 y(The)30 b(operation)g(of)g(man)o(y)f(Magic)h(commands)f(is)h(dependent)f(upon)h (which)g(windo)n(w)e(you)i(are)h(pointing)0 1152 y(at.)45 b(If)30 b(you)f(are)h(used)f(to)g(using)g(Magic)g(with)g(only)f(one)i (windo)n(w)e(you)h(may)-6 b(,)30 b(at)f(\002rst,)i(for)n(get)f(to)f (point)f(to)h(the)0 1273 y(windo)n(w)21 b(that)h(you)g(w)o(ant)h(the)f (operation)g(performed)h(upon.)29 b(F)o(or)23 b(instance,)f(if)h(there) f(are)i(se)n(v)o(eral)d(windo)n(ws)g(on)0 1393 y(the)30 b(screen)i(you)e(will)f(ha)n(v)o(e)i(to)f(point)f(to)h(one)h(before)g (e)o(x)o(ecuting)e(a)i(command)f(lik)o(e)g Fa(:grid)p Fc(\227otherwise)g(you)0 1513 y(may)24 b(not)h(af)n(fect)g(the)g(windo) n(w)e(that)h(you)h(intended!)0 1858 y Fe(4)143 b(Special)34 b(W)m(indo)o(ws)0 2084 y Fc(In)c(addition)e(to)h(pro)o(viding)f (multiple)g(windo)n(ws)g(on)h(dif)n(ferent)g(areas)i(of)e(a)h(layout,)g (Magic)g(pro)o(vides)e(se)n(v)o(eral)0 2204 y(special)34 b(types)g(of)g(windo)n(ws)e(that)i(display)f(things)g(other)h(than)g (layouts.)58 b(F)o(or)34 b(e)o(xample,)i(there)e(are)h(special)0 2324 y(windo)n(w)28 b(types)g(to)g(edit)h(netlists)e(and)i(to)g(adjust) f(the)g(colors)h(displayed)f(on)g(the)h(screen.)44 b(One)29 b(of)g(the)f(special)0 2445 y(windo)n(w)23 b(types)i(is)f(described)h (in)f(the)h(section)f(belo)n(w;)f(others)i(are)g(described)g(in)f(the)h (other)g(tutorials.)k(The)900 2680 y Fa(:specialopen)d Fd(type)f Fc([)p Fd(ar)l(gs)p Fc(])146 2914 y(command)19 b(is)h(used)g(to)g(create)h(these)f(sorts)f(of)h(windo)n(ws.)28 b(The)20 b Fd(type)g Fc(ar)n(gument)g(tells)f(what)h(sort)f(of)h(windo) n(w)0 3035 y(you)25 b(w)o(ant,)f(and)h Fd(ar)l(gs)g Fc(describe)g(what) f(you)h(w)o(ant)g(loaded)f(into)g(that)h(windo)n(w)-6 b(.)29 b(The)c Fa(:openwindo)o(w)h Fd(cellname)0 3155 y Fc(command)e(is)g(really)h(just)f(short)g(for)h(the)g(command)f Fa(:specialopen)h(lay)n(out)f Fd(cellname)p Fc(.)146 3276 y(Each)h(dif)n(ferent)f(type)g(of)h(windo)n(w)e(\(layout,)h(color) l(,)g(etc.\))31 b(has)25 b(its)e(o)n(wn)h(command)g(set.)30 b(If)25 b(you)f(type)g Fa(:help)0 3396 y Fc(in)32 b(dif)n(ferent)h (windo)n(w)e(types,)k(you')o(ll)d(see)h(that)f(the)h(commands)f(are)h (dif)n(ferent.)55 b(Some)33 b(of)g(the)f(commands,)0 3517 y(such)26 b(as)g(those)g(to)g(manipulate)f(windo)n(ws,)g(are)i(v)n (alid)e(in)h(all)g(windo)n(ws,)f(b)n(ut)h(for)g(other)g(commands)f(you) h(must)0 3637 y(mak)o(e)33 b(sure)h(you')-5 b(re)33 b(pointing)f(to)h (the)g(right)g(kind)f(of)i(windo)n(w)e(or)h(the)h(command)e(may)h(be)h (misinterpreted.)0 3758 y(F)o(or)e(e)o(xample,)h(the)e Fa(:extract)i Fc(command)e(means)h(one)f(thing)g(in)h(a)g(layout)f (windo)n(w)f(and)i(something)e(totally)0 3878 y(dif)n(ferent)24 b(in)h(a)g(netlist)e(windo)n(w)-6 b(.)0 4223 y Fe(5)143 b(Color)35 b(Editing)0 4448 y Fc(Special)e(windo)n(ws)e(of)i(type)f Fa(color)g Fc(are)i(used)e(to)g(edit)h(the)f(red,)j(green,)g(and)d (blue)h(intensities)d(of)j(the)g(colors)0 4569 y(displayed)24 b(on)g(the)h(screen.)31 b(T)-8 b(o)25 b(create)h(a)f(color)f(editing)g (windo)n(w)-6 b(,)23 b(in)l(v)n(ok)o(e)h(the)h(command)900 4804 y Fa(:specialopen)h(color)e Fc([)p Fd(number)p Fc(])146 5038 y Fd(Number)32 b Fc(is)f(optional;)h(if)g(present,)g(it)f(gi)n(v)o (es)f(the)h(octal)g(v)n(alue)g(of)g(the)g(color)g(number)g(whose)g (intensities)0 5158 y(are)26 b(to)e(be)h(edited.)30 b(If)25 b Fd(number)g Fc(isn')n(t)f(gi)n(v)o(en,)f(0)i(is)f(used.)31 b(T)m(ry)24 b(opening)g(a)h(color)g(windo)n(w)e(on)i(color)f(0.)146 5280 y(A)30 b(color)f(editing)f(windo)n(w)g(contains)g(6)i(\223color)f (bars\224,)i(12)e(\223color)g(pumps\224)g(\(one)g(on)g(each)h(side)f (of)g(each)0 5400 y(bar\),)23 b(plus)f(a)h(lar)n(ge)f(rectangle)h(at)f (the)h(top)e(of)i(the)f(windo)n(w)f(that)h(displays)f(a)i(sw)o(atch)f (of)g(the)g(color)h(being)f(edited)1875 5649 y(\2265\226)p eop %%Page: 6 6 6 5 bop 0 -180 a Fc(September)25 b(26,)f(2001)1577 b(Magic)25 b(T)l(utorial)e(#5:)30 b(Multiple)24 b(W)l(indo)n(ws)0 68 y(\(called)33 b(the)f(\223current)h(color\224)f(from)g(no)n(w)g (on\).)53 b(The)32 b(color)g(bars)h(display)e(the)h(components)f(of)i (the)f(current)0 188 y(color)26 b(in)f(tw)o(o)h(dif)n(ferent)f(w)o (ays.)34 b(The)26 b(three)g(bars)g(on)f(the)h(left)g(display)f(the)g (current)h(color)g(in)f(terms)h(of)g(its)f(red,)0 309 y(green,)j(and)f(blue)g(intensities)f(\(these)h(intensities)e(are)j (the)f(v)n(alues)g(actually)g(sent)f(to)h(the)g(display\).)38 b(The)27 b(three)0 429 y(bars)34 b(on)f(the)h(right)f(display)f(the)i (current)f(color)h(in)f(terms)g(of)h(hue,)i(saturation,)f(and)e(v)n (alue.)57 b(Hue)33 b(selects)h(a)0 549 y(color)23 b(of)h(the)f (spectrum.)29 b(Saturation)24 b(indicates)e(ho)n(w)h(diluted)f(the)h (color)g(is)g(\(high)g(saturation)g(corresponds)f(to)0 670 y(a)29 b(pure)h(color)l(,)f(lo)n(w)f(saturation)g(corresponds)h(to) g(a)g(color)g(that)f(is)h(diluted)f(with)g(gray)-6 b(,)30 b(and)f(a)g(saturation)f(of)h(0)0 790 y(results)d(in)g(gray)g(re)o (gardless)g(of)g(hue\).)36 b(V)-11 b(alue)27 b(indicates)e(the)i(o)o(v) o(erall)e(brightness)g(\(a)i(v)n(alue)f(of)g(0)h(corresponds)0 911 y(to)d(black,)h(re)o(gardless)f(of)h(hue)f(or)h(saturation\).)146 1031 y(There)i(are)f(se)n(v)o(eral)f(w)o(ays)h(to)f(modify)g(the)h (current)g(color)-5 b(.)33 b(First,)26 b(try)g(pressing)f(an)o(y)g (mouse)g(b)n(utton)g(while)0 1151 y(the)38 b(cursor)g(is)g(o)o(v)o(er)f (one)h(of)g(the)g(color)g(bars.)71 b(The)38 b(length)f(of)i(the)e(bar)l (,)42 b(and)c(the)g(current)h(color)l(,)i(will)c(be)0 1272 y(modi\002ed)24 b(to)h(re\003ect)h(the)f(mouse)g(position.)30 b(The)25 b(color)g(map)f(in)h(the)g(display)f(is)h(also)g(changed,)g (so)g(the)g(colors)0 1392 y(will)19 b(change)i(e)n(v)o(erywhere)f(on)g (the)g(screen)g(that)g(the)g(current)h(color)f(is)f(displayed.)29 b(Color)20 b(0,)h(which)f(you)f(should)0 1513 y(currently)30 b(be)h(editing,)f(is)g(the)g(background)g(color)-5 b(.)46 b(Y)-11 b(ou)30 b(can)h(also)f(modify)f(the)h(current)h(color)f(by)g (pressing)0 1633 y(a)e(b)n(utton)e(while)h(the)g(cursor)h(is)f(o)o(v)o (er)g(one)g(of)h(the)f(\223color)h(pumps\224)e(ne)o(xt)h(to)g(the)g (bars.)39 b(If)28 b(you)f(b)n(utton)f(a)i(pump)0 1753 y(with)d(\223+\224)h(in)g(it,)f(the)g(v)n(alue)g(of)h(the)g(bar)g(ne)o (xt)e(to)i(it)f(will)g(be)g(incremented)h(slightly)-6 b(,)23 b(and)j(if)f(you)g(b)n(utton)g(the)g(\223-\224)0 1874 y(pump,)32 b(the)g(bar)g(will)e(be)i(decremented)g(slightly)-6 b(.)49 b(The)31 b(left)h(b)n(utton)e(causes)i(a)g(change)g(of)f(about)h (1\045)f(in)g(the)0 1994 y(v)n(alue)23 b(of)i(the)e(bar)l(,)i(and)f (the)g(right)f(b)n(utton)g(will)g(pump)g(the)h(bar)g(up)g(or)g(do)n(wn) f(by)h(about)f(5\045.)30 b(T)m(ry)24 b(adjusting)e(the)0 2114 y(bars)j(by)f(b)n(uttoning)f(the)i(bars)g(and)g(the)f(pumps.)146 2235 y(If)31 b(you)f(press)h(a)g(b)n(utton)e(while)h(the)h(cursor)f(is) g(o)o(v)o(er)g(the)h(current)f(color)h(box)f(at)h(the)f(top)g(of)h(the) f(windo)n(w)-6 b(,)0 2355 y(one)24 b(of)g(tw)o(o)f(things)g(will)g (happen.)30 b(In)24 b(either)g(case,)g(nothing)f(happens)g(until)g(you) g(release)i(the)f(b)n(utton.)29 b(Before)0 2476 y(releasing)22 b(the)g(b)n(utton,)f(mo)o(v)o(e)g(the)h(cursor)h(so)e(it)h(is)g(o)o(v)o (er)f(a)i(dif)n(ferent)f(color)g(some)n(where)f(on)h(the)g(screen.)31 b(If)23 b(you)0 2596 y(pressed)28 b(the)g(left)g(b)n(utton,)g(then)g (when)g(the)g(b)n(utton)f(is)h(released)h(the)f(color)g(underneath)g (the)g(cursor)g(becomes)0 2716 y(the)d(ne)n(w)g(current)g(color)l(,)g (and)g(all)g(future)g(editing)f(operations)g(will)g(af)n(fect)i(this)e (color)-5 b(.)31 b(T)m(ry)24 b(using)g(this)g(feature)0 2837 y(to)f(modify)f(the)h(color)g(used)g(for)g(windo)n(w)f(borders.)30 b(If)24 b(you)f(pressed)g(the)g(right)f(b)n(utton,)g(then)h(when)g(the) g(b)n(utton)0 2957 y(is)29 b(released)h(the)f(v)n(alue)f(of)i(the)f (current)h(color)f(is)g(copied)g(from)g(whate)n(v)o(er)f(color)h(is)g (present)g(underneath)g(the)0 3077 y(cursor)-5 b(.)146 3198 y(There)24 b(are)g(only)f(a)h(fe)n(w)f(commands)f(you)h(can)h (type)f(in)g(color)g(windo)n(ws,)f(aside)h(from)g(those)g(that)g(are)h (v)n(alid)0 3318 y(in)g(all)h(windo)n(ws.)k(The)c(command)900 3521 y Fa(:color)g Fc([)p Fd(number)p Fc(])146 3724 y(will)d(change)h (the)f(current)h(color)f(to)g Fd(number)p Fc(.)30 b(If)23 b(no)f Fd(number)g Fc(is)g(gi)n(v)o(en,)g(this)f(command)h(will)f (print)h(out)g(the)0 3844 y(current)j(color)g(and)f(its)g(red,)i (green,)f(and)f(blue)h(intensities.)k(The)c(command)900 4047 y Fa(:sa)n(v)o(e)f Fc([)p Fd(tec)o(hStyle)g(displayStyle)g (monitorT)-7 b(ype)p Fc(])146 4250 y(will)19 b(sa)n(v)o(e)f(the)i (current)f(color)g(map)g(in)g(a)g(\002le)h(named)f Fd(tec)o(hStyle)p Fc(.)p Fd(displayStyle)p Fc(.)p Fd(monitorT)-7 b(ype)p Fa(.cmap)p Fc(,)17 b(where)0 4371 y Fd(tec)o(hStyle)31 b Fc(is)g(the)g(type)g(of)h(technology)e(\(e.g.,)k Fa(mos)p Fc(\),)e Fd(displayStyle)f Fc(is)g(the)g(kind)g(of)g(display)g (speci\002ed)h(by)f(a)0 4491 y Fa(styletype)f Fc(in)g(the)g Fa(style)g Fc(section)f(of)h(a)h(technology)e(\002le)h(\(e.g.,)h Fa(7bit)p Fc(\),)h(and)e Fd(monitorT)-7 b(ype)29 b Fc(is)h(the)f(type)h (of)g(the)0 4611 y(current)e(monitor)f(\(e.g.,)i Fa(std)p Fc(\).)42 b(If)28 b(no)g(ar)n(guments)g(are)h(gi)n(v)o(en,)e(the)h (current)h(technology)e(style,)h(display)f(style,)0 4732 y(and)e(monitor)e(type)i(are)g(used.)31 b(The)24 b(command)900 4935 y Fa(:load)h Fc([)p Fd(tec)o(hStyle)f(displayStyle)f(monitorT)-7 b(ype)p Fc(])146 5138 y(will)20 b(load)h(the)f(color)h(map)f(from)h (the)f(\002le)h(named)g Fd(tec)o(hStyle)p Fc(.)p Fd(displayStyle)p Fc(.)p Fd(monitorT)-7 b(ype)p Fa(.cmap)17 b Fc(as)k(abo)o(v)o(e.)0 5258 y(If)29 b(no)g(ar)n(guments)f(are)h(gi)n(v)o(en,)g(the)f(current)h (technology)f(style,)h(display)e(style,)i(and)g(monitor)f(type)g(are)h (used.)0 5378 y(When)c(loading)f(color)g(maps,)g(Magic)h(looks)f (\002rst)h(in)f(the)h(current)g(directory)-6 b(,)24 b(then)g(in)g(the)h (system)f(library)-6 b(.)1875 5649 y(\2266\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tut11.ps0000644000175000001440000011061110751423606015212 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: tut11.dvi %%Pages: 7 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman Times-BoldItalic %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips tut11.dvi -o tut11.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Bold % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tut11.dvi) @start /Fa 1 63 df<7000000000000000FC00000000000000FF000000000000007FC0 0000000000001FF000000000000007FC00000000000001FF000000000000007FC0000000 0000001FF000000000000007FE00000000000001FF800000000000007FE0000000000000 1FF800000000000003FE00000000000000FF800000000000003FE00000000000000FF800 000000000003FF00000000000000FFC00000000000003FF00000000000000FFC00000000 000001FF000000000000007FC00000000000001FF000000000000007FC00000000000001 FF000000000000007FC00000000000001FE00000000000001FE00000000000007FC00000 00000001FF00000000000007FC0000000000001FF00000000000007FC0000000000001FF 0000000000000FFC0000000000003FF0000000000000FFC0000000000003FF0000000000 000FF80000000000003FE0000000000000FF80000000000003FE0000000000001FF80000 000000007FE0000000000001FF80000000000007FE0000000000001FF00000000000007F C0000000000001FF00000000000007FC0000000000001FF00000000000007FC000000000 0000FF00000000000000FC0000000000000070000000000000003B3878B44C>62 D E /Fb 135[50 120[{ TeXBase1Encoding ReEncodeFont }1 100.000003 /Times-BoldItalic rf /Fc 103[33 3[50 50 10[33 15[50 2[55 33 39 44 55 55 50 55 83 28 55 1[28 55 50 33 44 55 44 55 50 10[72 1[66 55 72 3[72 1[66 4[78 1[66 72 72 66 1[93 5[33 7[50 50 50 28 25 33 2[50 42[{ TeXBase1Encoding ReEncodeFont }45 100.000003 /Times-Bold rf /Fd 138[66 40 47 53 2[60 66 100 33 2[33 66 2[53 66 53 1[60 12[80 6[113 9[86 8[40 55[66 2[{ TeXBase1Encoding ReEncodeFont } 19 119.999948 /Times-Bold rf /Fe 105[50 1[44 44 24[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 6[61 72 1[94 1[72 61 55 66 72 55 72 72 89 61 2[33 72 72 55 61 72 66 66 72 92 4[28 28 50 50 50 50 50 50 50 50 50 50 28 25 33 25 2[33 33 33 3[50 31[55 55 2[{ TeXBase1Encoding ReEncodeFont }74 100.000003 /Times-Roman rf /Ff 133[39 1[44 66 2[28 39 39 2[50 50 72 28 44 1[28 50 2[44 50 44 50 50 8[61 1[61 1[55 50 61 3[66 83 4[72 72 1[61 72 66 61 2[50 1[67 11[50 50 1[25 4[33 33 40[{ TeXBase1Encoding ReEncodeFont }38 100.000003 /Times-Italic rf /Fg 136[104 1[80 48 56 64 1[80 72 80 120 40 2[40 80 72 48 64 80 64 1[72 11[104 96 80 104 1[88 1[104 135 3[56 14[48 4[72 72 72 72 72 13[72 35[{ TeXBase1Encoding ReEncodeFont }33 143.999997 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 211 101 a Fg(Magic)35 b(T)-13 b(utorial)34 b(#11:)43 b(Using)35 b(IRSIM)g(and)g(RSIM)h(with)f(Magic)1659 521 y Ff(Mic)o(hael)24 b(Chow)1646 641 y(Mark)h(Hor)l(owitz)1338 1062 y Fe(Computer)g(Systems)f(Laboratory)1354 1182 y(Center)i(for)f (Inte)o(grated)f(Systems)1558 1303 y(Stanford)h(Uni)n(v)o(ersity)1547 1423 y(Stanford,)g(CA)h(94305)1053 1693 y(This)e(tutorial)g (corresponds)g(to)g(Magic)h(v)o(ersion)e(7.)0 2220 y Fd(T)-11 b(utorials)30 b(to)f(r)n(ead)h(\002rst:)300 2423 y Fe(Magic)24 b(T)l(utorial)g(#1:)30 b(Getting)24 b(Started)300 2543 y(Magic)g(T)l(utorial)g(#2:)30 b(Basic)25 b(P)o(ainting)f(and)h(Selection)300 2663 y(Magic)f(T)l(utorial)g(#4:)30 b(Cell)25 b(Hierarchies)300 2784 y(Magic)f(T)l(utorial)g(#8:)30 b(Circuit)25 b(Extraction)0 2986 y Fd(Commands)k(intr)n(oduced)j(in)f (this)f(tutorial:)300 3188 y Fe(:getnode,)24 b(:rsim,)g(:simcmd,)f (:startrsim)0 3391 y Fd(Macr)n(os)29 b(intr)n(oduced)i(in)g(this)f (tutorial:)300 3618 y Ff(\(None\))0 4213 y Fg(1)143 b(Intr)m(oduction)0 4437 y Fe(This)20 b(tutorial)g(e)o(xplains)f(ho)n(w)h(to)g(use)h (Magic')-5 b(s)20 b(interf)o(ace)h(to)f(the)h(switch-le)n(v)o(el)e (circuit)h(simulators,)g(RSIM)h(and)0 4557 y(IRSIM.)27 b(The)g(interf)o(ace)g(is)g(the)f(same)h(for)g(both)e(these)i (simulators)e(and,)i(e)o(xcept)f(where)h(noted,)g(RSIM)g(refers)0 4678 y(to)i(IRSIM)i(as)f(well.)45 b(This)29 b(interf)o(ace)i (eliminates)d(the)i(tedium)f(of)h(mapping)e(node)i(names)f(to)h (objects)f(in)g(the)0 4798 y(layout)f(and)h(typing)f(node)g(names)h(as) g(RSIM)g(input.)42 b(It)29 b(allo)n(ws)f(the)g(user)h(to)g(select)g (nodes)f(using)g(the)h(mouse)0 4918 y(and)36 b(apply)f(RSIM)i(commands) e(to)g(them)g(or)h(to)g(display)f(the)g(node)h(v)n(alues)f(determined)g (by)h(RSIM)h(in)e(the)0 5039 y(layout)26 b(itself.)38 b(Y)-11 b(ou)27 b(should)f(already)h(be)h(f)o(amiliar)e(with)h(using)f (both)h(RSIM)h(and)f(Magic')-5 b(s)26 b(circuit)h(e)o(xtractor)-5 b(.)0 5159 y(Section)32 b(2)g(describes)g(ho)n(w)f(to)h(prepare)g(the)g (\002les)g(necessary)h(to)e(simulate)g(a)h(circuit.)52 b(Section)32 b(3)g(describes)0 5280 y(ho)n(w)24 b(to)h(run)g(RSIM)g (interacti)n(v)o(ely)e(under)i(Magic.)31 b(Section)25 b(4)g(e)o(xplains)f(ho)n(w)g(to)g(determine)h(the)g(node)f(names)0 5400 y(that)e(RSIM)h(uses.)29 b(Lastly)-6 b(,)21 b(section)h(5)g(e)o (xplains)f(ho)n(w)g(to)h(use)g(the)g(RSIM)h(tool)f(in)f(Magic)h(to)g (simulate)f(a)i(circuit.)1875 5649 y(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Fe(September)25 b(26,)f(2001)813 b(Magic)24 b(T)l(utorial)g(#11:)30 b(Using)23 b(IRSIM)j(and)f(RSIM)g(with)f(Magic) 0 99 y Fg(2)143 b(Pr)m(eparations)33 b(f)l(or)j(Simulation)0 327 y Fe(Magic)23 b(uses)h(the)f(RSIM)i(input)e(\002le)h(when)f(it)h (simulates)e(the)h(circuit.)30 b(Before)25 b(proceeding)f(an)o(y)f (further)l(,)h(mak)o(e)0 447 y(sure)34 b(you)f(ha)n(v)o(e)g(the)g (correct)i(v)o(ersions)d(of)h(the)h(programs)f Fc(ext2sim)g Fe(and)g Fc(rsim)h Fe(installed)e(on)h(your)g(system.)0 567 y(Important)26 b(changes)i(ha)n(v)o(e)f(been)g(made)g(to)g(these)g (programs)g(to)g(support)f(simulation)f(within)h(Magic.)38 b(T)-8 b(o)27 b(try)0 688 y(out)g(this)f(tool)g(on)h(an)h(e)o(xample,)f (cop)o(y)g(all)g(the)g Fc(tut11)p Fb(x)g Fe(cells)g(to)g(your)g (current)g(directory)g(with)g(the)g(follo)n(wing)0 808 y(command:)900 1053 y Fc(cp)f(\230cad/lib/magic/tutorial/tut11*)d(.)146 1296 y Fe(The)29 b Fc(tut11a)g Fe(cell)f(is)g(a)h(simple)e(4-bit)h (counter)g(using)f(the)i(Magic)f(scmos)f(technology)h(\002le.)42 b(Start)28 b(Magic)0 1416 y(on)d(the)f(cell)h Fc(tut11a)p Fe(,)g(and)g(e)o(xtract)f(the)h(entire)g(cell)f(using)g(the)h(command:) 900 1661 y Fc(:extract)h(all)146 1904 y Fe(When)k(this)e(command)h (completes,)h(se)n(v)o(eral)e Fc(.ext)i Fe(\002les)g(will)e(be)i (created)g(in)f(your)g(current)h(directory)f(by)0 2024 y(the)i(e)o(xtractor)-5 b(.)48 b(The)31 b(ne)o(xt)f(step)h(is)f(to)h (\003atten)g(the)g(hierarchy)f(into)h(a)g(single)f(representation.)48 b(Return)32 b(to)e(the)0 2145 y(Unix)24 b(c-shell)h(by)f(quitting)f (Magic.)146 2267 y(The)32 b(program)f Fc(ext2sim)g Fe(is)g(used)g(to)g (\003atten)h(the)f(hierarchy)-6 b(.)50 b(Run)32 b(this)e(program)h (from)h(the)f(C-shell)g(by)0 2387 y(typing:)900 2632 y Fc(ext2sim)24 b(-L)i(-R)f(-c)g(20)g(tut11a)146 2875 y Fe(This)f(program)h(will)f(create)h(the)g(\002le)g Fc(tut11a.sim)g Fe(in)f(your)h(current)g(directory)-6 b(.)146 2997 y(If)22 b(you)f(are)h(running)e(IRSIM,)i(the)f Fc(tut11a.sim)f Fe(can)i(be)f(used)g(directly)g(as)g(input)f(to)h(the)g (simulator)e(and)j(you)0 3118 y(should)27 b(skip)h(the)g(ne)o(xt)g (step.)41 b(Instead,)29 b(if)f(you)g(will)g(be)g(using)g(RSIM,)h(the)f (last)g(step)g(is)g(to)g(create)h(the)f(binary)0 3238 y(representation)c(of)h(the)g(\003attened)g(hierarchy)f(by)h(using)f (the)g(program)h Fc(pr)n(esim)p Fe(.)31 b(T)-8 b(o)25 b(do)f(this,)g(type:)900 3483 y Fc(pr)n(esim)h(tut11a.sim)g(tut11a.rsm) g(\230cad/lib/scmos100.prm)f(-nostack)i(-nodr)n(ops)146 3726 y Fe(The)j(third)e(\002le)i(is)f(the)g(parameter)h(\002le)g(used)f (by)g(presim)g(for)h(this)e(circuit.)41 b(The)29 b(con)l(v)o(ention)d (at)j(Stanford)0 3846 y(is)24 b(to)f(use)h(the)g(suf)n(\002x)f Ff(.r)o(sm)h Fe(when)g(naming)f(the)g(RSIM)i(input)e(\002le.)31 b(The)24 b(\002le)g Fc(tut11a.rsm)g Fe(can)h(also)e(be)h(used)g(as)0 3967 y(input)g(for)h(running)f(RSIM)h(alone.)0 4319 y Fg(3)143 b(Using)35 b(RSIM)0 4547 y Fe(Re-run)27 b(Magic)f(again)f(to)h (edit)g(the)g(cell)g Fc(tut11a)p Fe(.)35 b(W)-8 b(e')o(ll)26 b(\002rst)g(learn)g(ho)n(w)g(to)f(run)h(RSIM)h(in)f(interacti)n(v)o(e)f (mode)0 4668 y(under)g(Magic.)30 b(T)-8 b(o)25 b(simulate)e(the)i (circuit)f(of)h(tut11a,)f(using)g(IRSIM)i(type)e(the)h(command:)900 4912 y Fc(:rsim)g(scmos100.prm)f(tut11a.sim)146 5155 y Fe(T)-8 b(o)25 b(simulate)e(the)i(circuit)g(of)f(tut11a,)g(using)g (RSIM)i(type)e(the)h(command:)900 5400 y Fc(:rsim)g(tut11a.rsm)1875 5649 y Fe(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Fe(Magic)24 b(T)l(utorial)g(#11:)30 b(Using)24 b(IRSIM)h(and)g(RSIM)h(with)e(Magic)812 b(September)25 b(26,)g(2001)146 69 y(Y)-11 b(ou)32 b(should)f(see)h(the)g(RSIM)g (header)h(displayed,)f(follo)n(wed)f(by)h(the)f(standard)h(RSIM)g (prompt)f(\()p Fc(rsim)p Fa(>)0 189 y Fe(or)c Fc(irsim)p Fa(>)p Fe(,)g(depending)f(on)h(the)g(simulator\))f(in)g(place)i(of)f (the)g(usual)f(Magic)h(prompt;)g(this)f(means)h(k)o(e)o(yboard)0 309 y(input)g(is)h(no)n(w)f(directed)i(to)f(RSIM.)h(This)e(mode)h(is)g (v)o(ery)g(similar)f(to)h(running)f(RSIM)i(alone;)g(one)g(dif)n (ference)0 430 y(is)h(that)g(the)h(user)f(can)h(escape)g(RSIM)h(and)e (then)h(return)f(to)g(Magic.)48 b(Also,)31 b(the)g(mouse)e(has)i(no)f (ef)n(fect)h(when)0 550 y(RSIM)25 b(is)g(run)g(interacti)n(v)o(ely)e (under)h(Magic.)146 671 y(Only)i(one)f(instance)h(of)g(RSIM)h(may)e(be) h(running)f(at)h(an)o(y)g(time)f(under)h(Magic.)33 b(The)26 b(simulation)e(running)0 791 y(need)i(not)g(correspond)f(to)h(the)g (Magic)f(layout;)h(ho)n(we)n(v)o(er)l(,)f(as)h(we)g(shall)f(see)i (later)l(,)f(the)o(y)f(must)g(correspond)h(for)0 911 y(the)32 b(RSIM)h(tool)e(to)g(w)o(ork.)53 b(All)31 b(commands)g(typed)g (to)h(the)g(RSIM)h(prompt)e(should)g(be)h(RSIM)g(commands.)0 1032 y(W)-8 b(e')o(ll)28 b(\002rst)g(run)g(RSIM,)g(then)g(escape)h(to)e (Magic,)h(and)g(then)g(return)g(back)g(to)g(RSIM.)g(T)-8 b(ype)28 b(the)g(RSIM)g(com-)0 1152 y(mand)900 1374 y Fc(@)d(tut11a.cmd)146 1597 y Fe(to)k(initialize)f(the)g(simulation.)41 b(\(Note)29 b(there)g(is)g(a)g(\223)g(\224)g(after)h(the)f(@.\))43 b(No)n(w)28 b(type)g Fc(c)i Fe(to)e(clock)h(the)g(circuit.)0 1717 y(Y)-11 b(ou)29 b(should)g(see)g(some)g(information)f(about)h (some)g(nodes)g(displayed,)h(follo)n(wed)e(by)i(the)f(time.)44 b(Set)30 b(tw)o(o)f(of)0 1837 y(the)24 b(nodes)g(to)g(a)h(logic)e (\2231\224)i(by)f(typing)f Fc(h)i(RESET)p 1768 1837 60 5 v 61 w(B)g(hold)p Fe(.)31 b(Step)24 b(the)h(clock)f(again)f(by)h (typing)g Fc(c)p Fe(,)g(and)g(RSIM)0 1958 y(should)g(sho)n(w)f(that)i (these)f(tw)o(o)h(nodes)f(no)n(w)g(ha)n(v)o(e)g(the)h(v)n(alue)f (\2231\224.)146 2078 y(Y)-11 b(ou)23 b(can)g(return)g(to)f(Magic)g (without)g(quitting)f(RSIM)i(and)g(then)f(later)h(return)g(to)f(RSIM)i (in)e(the)h(same)f(state)0 2199 y(in)i(which)h(it)f(w)o(as)h(left.)31 b(Escape)25 b(to)f(Magic)g(by)h(typing:)900 2421 y Fc(.)146 2643 y Fe(\(a)e(single)e(period\))h(to)f(the)h(RSIM)h(prompt.)28 b(Ne)o(xt,)22 b(type)g(a)g(fe)n(w)g(Magic)g(commands)f(to)g(sho)n(w)g (you')-5 b(re)22 b(really)0 2763 y(back)j(in)f(Magic)h(\(signi\002ed)f (by)h(the)f(Magic)h(prompt\).)146 2884 y(Y)-11 b(ou)25 b(can)g(return)g(to)f(RSIM)i(by)e(typing)g(the)g(Magic)h(command)f Fc(rsim)g Fe(without)g(an)o(y)g(ar)n(guments.)30 b(T)-8 b(ype:)900 3106 y Fc(:rsim)146 3328 y Fe(The)25 b(RSIM)g(prompt)e(will) g(be)i(displayed)e(again,)h(and)g(you)g(are)h(no)n(w)e(back)i(in)e (RSIM)i(in)f(the)g(state)g(you)g(left)0 3449 y(it)f(in.)30 b(Experiment)23 b(with)g(RSIM)i(by)e(typing)g(some)g(commands.)29 b(T)-8 b(o)24 b(quit)f(RSIM)h(and)g(return)g(to)f(Magic,)h(type:)900 3671 y Fc(q)146 3893 y Fe(in)29 b(response)g(to)f(the)h(RSIM)g(prompt.) 42 b(Y)-11 b(ou')o(ll)29 b(kno)n(w)f(you')-5 b(re)29 b(back)g(in)f(Magic)h(when)g(the)g(Magic)f(prompt)0 4014 y(is)e(redisplayed.)37 b(If)27 b(you)f(should)g(interrupt)g(RSIM)i (\(typing)d(a)i(control-C\),)g(you')o(ll)f(probably)g(kill)g(it)h(and)f (then)0 4134 y(ha)n(v)o(e)i(to)f(restart)h(it.)39 b(RSIM)29 b(running)e(standalone)g(will)g(also)g(be)h(killed)f(if)h(you)g (interrupt)f(it.)39 b(If)28 b(you)g(interrupt)0 4254 y(IRSIM)23 b(\(typing)e(a)i(control-C\),)f(the)g(simulator)e(will)i (abort)g(whate)n(v)o(er)f(it')-5 b(s)21 b(doing)g(\(a)i(long)e (simulation)f(run,)j(for)0 4375 y(e)o(xample\))h(and)h(return)g(to)f (the)h(command)f(interpreter)g(by)h(prompting)e(again)h(with)g Fc(irsim)p Fa(>)p Fe(.)0 4713 y Fg(4)143 b(Node)35 b(Names)0 4937 y Fe(It')-5 b(s)28 b(easy)i(to)e(determine)h(node)g(names)f(under) h(Magic.)43 b(First,)30 b(locate)f(the)g(red)g(square)h(re)o(gion)e(in) g(the)h(middle)0 5057 y(right)d(side)f(of)i(the)f(circuit.)35 b(Mo)o(v)o(e)24 b(the)j(cursor)f(o)o(v)o(er)f(this)h(re)o(gion)f(and)h (select)g(it)g(by)g(typing)f Fc(s)p Fe(.)35 b(T)-8 b(o)26 b(\002nd)h(out)e(the)0 5178 y(name)g(for)g(this)f(node,)g(type:)900 5400 y Fc(:getnode)1875 5649 y Fe(\2263\226)p eop %%Page: 4 4 4 3 bop 0 -180 a Fe(September)25 b(26,)f(2001)813 b(Magic)24 b(T)l(utorial)g(#11:)30 b(Using)23 b(IRSIM)j(and)f(RSIM)g(with)f(Magic) 146 68 y(Magic)j(should)f(print)h(that)f(the)h(node)g(name)g(is)g Ff(RESET)p 2108 68 60 5 v 60 w(B)p Fe(.)g(The)g(command)f Fc(getnode)i Fe(prints)e(the)h(names)0 188 y(of)c(all)h(nodes)e(in)h (the)h(current)f(selection.)30 b(Mo)o(v)o(e)22 b(the)h(cursor)g(o)o(v)o (er)g(the)g(square)h(blue)f(re)o(gion)f(in)h(the)g(upper)h(right)0 309 y(corner)35 b(and)f(add)g(this)f(node)h(to)f(the)h(current)h (selection)e(by)h(typing)f Fc(S)p Fe(.)h(T)-8 b(ype)34 b Fc(:getnode)i Fe(again,)f(and)f(Magic)0 429 y(should)27 b(print)h(the)g(names)g(of)h(tw)o(o)f(nodes;)h(the)f(blue)g(node)g(is)g (named)g Ff(hold)p Fe(.)41 b(Y)-11 b(ou)28 b(can)h(also)f(print)g (aliases)g(for)0 549 y(the)d(selected)f(nodes.)31 b(T)l(urn)24 b(on)g(name-aliasing)g(by)h(typing:)900 827 y Fc(:getnode)h(alias)e(on) 146 1098 y Fe(Select)35 b(the)e(red)h(node)g(again,)h(and)f(type)f Fc(:getnode)p Fe(.)59 b(Se)n(v)o(eral)33 b(names)h(will)e(be)i (printed;)j(the)d(last)f(name)0 1219 y(printed)f(is)h(the)f(one)h(RSIM) h(uses,)g(so)f(you)f(should)g(use)h(this)f(name)g(for)i(RSIM.)f(Note)g (that)f Fc(getnode)i Fe(is)f(not)0 1339 y(guaranteed)27 b(to)g(print)f(all)h(aliases)g(for)g(a)g(node.)37 b(Only)27 b(those)f(alises)h(generated)g(when)g(the)g(RSIM)g(node)g(name)0 1460 y(is)32 b(computed)f(are)i(printed.)51 b(Ho)n(we)n(v)o(er)l(,)33 b(most)e(of)h(the)g(alaiases)g(will)f(usually)g(be)h(printed.)52 b(Printing)31 b(aliases)0 1580 y(is)26 b(also)h(useful)f(to)h(monitor)e (the)i(name)g(search,)g(since)g Fc(getnode)h Fe(can)f(tak)o(e)g(se)n(v) o(eral)f(seconds)h(on)f(lar)n(ge)i(nodes.)0 1700 y(T)l(urn)c(of)n(f)h (aliasing)f(by)g(typing:)900 1978 y Fc(:getnode)i(alias)e(off)146 2249 y(getnode)30 b Fe(w)o(orks)d(by)h(e)o(xtracting)f(a)i(single)e (node.)41 b(Consequently)-6 b(,)27 b(it)h(can)h(tak)o(e)f(a)g(long)g (time)f(to)h(compute)0 2370 y(the)23 b(name)g(for)h(lar)n(ge)f(nodes,)g (such)g(as)g Ff(Vdd)g Fe(or)h Ff(GND)p Fe(.)f(Select)h(the)f (horizontal)f(blue)h(strip)g(on)f(top)h(of)g(the)g(circuit)0 2490 y(and)32 b(run)f Fc(:getnode)j Fe(on)d(this.)51 b(Y)-11 b(ou')o(ll)31 b(\002nd)h(that)f(this)g(will)g(tak)o(e)h(about)f (six)g(seconds)g(for)h Fc(getnode)h Fe(to)f(\002gure)0 2611 y(out)27 b(that)g(this)f(is)h Ff(Vdd)p Fe(.)39 b(Y)-11 b(ou)27 b(can)h(interrupt)e Fc(getnode)j Fe(by)e(typing)f Fc(\210C)i Fe(\(control-C\),)g(and)f Fc(getnode)i Fe(will)d(return)0 2731 y(the)h(\223best\224)g(name)h(found)e(so)h(f)o(ar)-5 b(.)39 b(There)27 b(is)g(no)g(w)o(ay)h(to)f(tell)f(if)h(this)g(is)g(an) g(alias)g(or)g(the)h(name)f(RSIM)h(e)o(xpects)0 2851 y(unless)23 b Fc(getnode)i Fe(is)f(allo)n(wed)f(to)g(complete.)30 b(T)-8 b(o)24 b(pre)n(v)o(ent)e(these)i(long)f(name)h(searches,)h(you)e (can)i(tell)e Fc(getnode)0 2972 y Fe(to)h(quit)g(its)g(search)i(when)e (certain)h(names)g(are)g(encountered.)31 b(T)-8 b(ype:)900 3249 y Fc(:getnode)26 b(abort)f(Vdd)146 3521 y Fe(Select)30 b(the)f(blue)g(strip)g(on)g(top)g(of)g(the)g(circuit)g(and)h(type)f Fc(:getnode)p Fe(.)45 b(Y)-11 b(ou')o(ll)29 b(notice)g(that)g(the)g (name)g(w)o(as)0 3641 y(found)20 b(v)o(ery)f(quickly)h(this)f(time,)h (and)g Fc(getnode)h Fe(tells)f(you)f(it)h(aborted)g(the)g(search)h(of)f Ff(Vdd)p Fe(.)29 b(The)20 b(name)g(returned)0 3761 y(may)25 b(be)g(an)g(alias)g(instead)g(of)g(the)g(the)g(one)g(RSIM)h(e)o (xpects.)31 b(In)25 b(this)f(e)o(xample,)g(the)h(abort)g(option)f(to)h Fc(getnode)0 3882 y Fe(will)f(abort)g(the)h(name)f(search)i(on)e(an)o (y)g(name)h(found)f(where)h(the)f(last)h(component)e(of)i(the)f(node)h (name)f(is)h Ff(Vdd)p Fe(.)0 4002 y(That)g(is,)f Fc(getnode)i Fe(will)e(stop)g(if)g(a)i(name)e(such)h(as)g(\223miasma/crock/)p Ff(Vdd)p Fe(\224)e(or)i(\223hooha/)p Ff(Vdd)p Fe(\224)f(is)g(found.)146 4129 y(Y)-11 b(ou)38 b(can)h(abort)f(the)g(search)h(on)f(more)g(than)g (one)g(name;)45 b(no)n(w)37 b(type)h Fc(:getnode)i(abort)f(GND)p Fe(.)f(Select)0 4249 y(the)f(bottom)e(horizontal)h(blue)h(strip)f(in)h (the)g(layout,)i(and)e(type)g Fc(:getnode)p Fe(.)69 b(The)37 b(search)g(will)f(end)h(almost)0 4369 y(immediately)-6 b(,)27 b(since)h(this)g(node)g(is)g Ff(GND)p Fe(.)h Fc(getnode)h Fe(will)d(no)n(w)h(abort)g(an)o(y)g(node)g(name)h(search)g(when)f (either)0 4490 y Ff(Vdd)20 b Fe(or)g Ff(GND)h Fe(is)f(found.)28 b(The)21 b(search)g(can)f(be)h(aborted)f(on)g(an)o(y)g(name;)h(just)e (supply)g(the)i(name)f(as)g(an)h(ar)n(gument)0 4610 y(to)29 b Fc(getnode)i(abort)p Fe(.)45 b(Remember)30 b(that)f(only)f(the)i (last)f(part)g(of)h(the)f(name)g(counts)g(when)g(aborting)g(the)g(name) 0 4731 y(search.)i(T)-8 b(o)25 b(cancel)g(all)g(name)f(aborts)h(and)g (resume)f(normal)g(name)h(searches,)g(type:)900 5008 y Fc(:getnode)h(abort)146 5280 y(getnode)c Fe(will)e(no)h(longer)f (abort)h(the)f(search)i(on)e(an)o(y)g(names,)i(and)e(it)h(will)f(churn) g(a)o(w)o(ay)h(unless)f(interrupted)0 5400 y(by)25 b(the)f(user)-5 b(.)1875 5649 y(\2264\226)p eop %%Page: 5 5 5 4 bop 0 -180 a Fe(Magic)24 b(T)l(utorial)g(#11:)30 b(Using)24 b(IRSIM)h(and)g(RSIM)h(with)e(Magic)812 b(September)25 b(26,)g(2001)0 99 y Fg(5)143 b(RSIM)36 b(T)-13 b(ool)0 335 y Fe(Y)i(ou)31 b(can)g(also)g(use)f(the)h(mouse)f(to)h(help)g(you)f (run)h(RSIM)h(under)e(Magic.)49 b(Instead)31 b(of)g(typing)f(node)h (names,)0 455 y(you)23 b(can)h(just)e(select)h(nodes)g(with)g(the)g (mouse,)g(tell)g(RSIM)h(what)f(to)g(do)g(with)g(these)g(nodes,)g(and)g (let)g(Magic)g(do)0 576 y(the)i(rest.)30 b(Change)c(tools)d(by)i (typing:)900 852 y Fc(:tool)g(rsim)146 1123 y Fe(or)h(hit)g(the)g (space)g(bar)g(until)f(the)h(cursor)g(changes)g(to)g(a)g(pointing)f (hand.)34 b(The)26 b(RSIM)g(tool)g(is)f(acti)n(v)o(e)g(when)0 1243 y(the)32 b(cursor)h(is)f(this)f(hand.)54 b(The)32 b(left)h(and)f(right)g(mouse)f(b)n(uttons)g(ha)n(v)o(e)i(the)f(same)g (ha)n(v)o(e)g(the)h(same)f(function)0 1363 y(as)h(the)f(box)g(tool.)53 b(Y)-11 b(ou)32 b(use)h(these)f(b)n(uttons)f(along)h(with)g(the)h (select)f(command)g(to)g(select)g(the)h(nodes.)53 b(The)0 1484 y(middle)23 b(b)n(utton)g(is)g(dif)n(ferent)h(from)g(the)g(box)f (tool.)30 b(Clicking)23 b(the)h(middle)f(b)n(utton)g(will)g(cause)h (all)g(nodes)g(in)f(the)0 1604 y(selection)30 b(to)g(ha)n(v)o(e)g (their)g(logical)g(v)n(alues)g(displayed)f(in)h(the)h(layout)e(and)i (printed)f(in)g(the)g(te)o(xt)g(windo)n(w)-6 b(.)46 b(W)-8 b(e)0 1724 y(need)25 b(to)f(ha)n(v)o(e)h(RSIM)g(running)f(in)h(order)g (to)f(use)h(this)f(tool.)30 b(Start)25 b(RSIM)g(by)g(typing:)900 2001 y Fc(:startrsim)g(tut11a.rsm)146 2271 y Fe(The)31 b Fc(.rsm)g Fe(\002le)g(you)g(simulate)f(must)f(correspond)i(to)f(the)h (root)g(cell)f(of)h(the)g(layout.)48 b(If)32 b(not,)f(Magic)g(will)0 2392 y(generate)d(node)e(names)h(that)g(RSIM)g(will)f(not)h(understand) f(and)h(things)f(w)o(on')n(t)g(w)o(ork)h(properly)-6 b(.)37 b(If)27 b(an)o(y)g(paint)0 2512 y(is)k(changed)g(in)f(the)h (circuit,)h(the)f(circuit)g(must)f(be)h(re-e)o(xtracted)g(and)g(a)h(ne) n(w)e Fc(.rsm)h Fe(\002le)h(must)e(be)h(created)g(to)0 2632 y(re\003ect)26 b(the)f(changes)f(in)h(the)f(circuit.)146 2759 y(Magic)f(will)f(print)g(the)g(RSIM)i(header)l(,)g(b)n(ut)e(you)g (return)h(to)g(Magic)f(instead)g(of)h(remaining)f(in)g(RSIM.)i(This)0 2879 y(is)g(an)g(alternate)h(w)o(ay)f(of)g(starting)f(up)h(RSIM,)h(and) g(it)e(is)h(equi)n(v)n(alent)e(to)i(the)g(command)g Fc(rsim)g (tut11a.rsm)g Fe(and)0 3000 y(typing)h(a)i(period)f(\()p Fc(.)p Fe(\))35 b(to)26 b(the)g(RSIM)h(prompt,)f(escaping)g(to)g (Magic.)34 b(W)-8 b(e)27 b(need)g(to)e(initialize)h(RSIM,)g(so)g(get)g (to)0 3120 y(RSIM)j(by)e(typing)g Fc(:rsim)h Fe(and)g(you')o(ll)f(see)i (the)f(RSIM)g(prompt)f(again.)40 b(As)28 b(before,)h(type)f Fc(@)g(tut11a.cmd)g Fe(to)0 3240 y(the)e(RSIM)h(prompt)e(to)h (initialize)f(e)n(v)o(erything.)33 b(T)-8 b(ype)26 b(a)g(period)g(\()p Fc(.)p Fe(\))35 b(to)26 b(return)g(to)g(Magic.)34 b(W)-8 b(e)27 b(are)f(no)n(w)g(ready)0 3361 y(to)e(use)h(the)g(RSIM)g(tool.) 146 3487 y(As)k(mentioned)f(earlier)l(,)j Fc(tut11a)f Fe(is)e(a)i(4-bit)e(counter)-5 b(.)44 b(W)-8 b(e')o(ll)29 b(reset)g(the)g(counter)h(and)f(then)g(step)f(it)h(using)0 3608 y(the)e(RSIM)g(tool.)36 b(Locate)26 b(the)h(square)g(blue)f(area)i (on)e(the)h(top)f(right)g(corner)h(of)g(the)g(circuit.)36 b(Place)27 b(the)g(cursor)0 3728 y(o)o(v)o(er)f(this)f(re)o(gion)g(and) i(select)f(it.)35 b(No)n(w)26 b(click)g(the)g(middle)f(b)n(utton,)g (and)i(the)f(RSIM)h(v)n(alue)f(for)g(this)g(node)g(will)0 3848 y(be)35 b(printed)f(in)g(both)f(the)i(te)o(xt)e(windo)n(w)g(and)i (in)f(the)g(layout.)59 b(Magic/RSIM)35 b(will)e(report)i(that)f(the)g (node)h(is)0 3969 y(named)24 b Ff(hold)g Fe(and)h(that)f(its)g(current) h(v)n(alue)f(is)h Ff(X)p Fe(.)f(Y)-11 b(ou)24 b(may)h(not)f(be)h(able)g (to)f(see)h(the)f(node)h(v)n(alue)f(in)g(the)h(layout)0 4089 y(if)32 b(you)g(are)h(zoomed)f(out)f(too)h(f)o(ar)-5 b(.)53 b(Zoom)31 b(in)h(closer)g(about)g(this)f(node)h(if)g(necessary) -6 b(.)53 b(T)m(ry)32 b(selecting)f(other)0 4209 y(nodes,)25 b(singly)g(or)h(in)f(groups)g(and)h(click)g(the)f(middle)g(b)n(utton)f (to)i(display)f(their)g(v)n(alues.)33 b(This)25 b(is)g(an)h(easy)g(w)o (ay)0 4330 y(to)e(probe)h(nodes)g(when)f(deb)n(ugging)g(a)h(circuit.) 146 4456 y(Select)h Ff(hold)d Fe(again)h(\(the)h(blue)f(square\).)31 b(This)24 b(node)g(must)g(be)h(a)g(\2231\224)f(before)i(resetting)d (the)i(circuit.)30 b(Mak)o(e)0 4577 y(sure)25 b(this)f(is)g(the)h(only) f(node)g(in)h(the)f(current)h(selection.)30 b(T)-8 b(ype:)900 4853 y Fc(:simcmd)25 b(h)146 5124 y Fe(to)g(set)f(it)h(to)f(a)h (\2231\224.)31 b(Step)25 b(the)g(clock)g(by)f(typing:)900 5400 y Fc(:simcmd)h(c)1875 5649 y Fe(\2265\226)p eop %%Page: 6 6 6 5 bop 0 -180 a Fe(September)25 b(26,)f(2001)813 b(Magic)24 b(T)l(utorial)g(#11:)30 b(Using)23 b(IRSIM)j(and)f(RSIM)g(with)f(Magic) 146 68 y(Click)39 b(the)f(middle)f(b)n(utton)h(and)g(you)g(will)g(see)g (that)g(the)h(node)f(has)g(been)h(set)f(to)g(a)h(\2231.)-7 b(\224)72 b(The)38 b(Magic)0 188 y(command)19 b Fc(simcmd)g Fe(will)g(tak)o(e)g(the)h(selected)f(nodes)g(and)h(use)f(them)g(as)h (RSIM)g(input.)28 b(These)19 b(uses)g(of)h Fc(simcmd)0 309 y Fe(are)32 b(lik)o(e)e(typing)g(the)g(RSIM)i(commands)e Ff(h)h(hold)f Fe(follo)n(wed)f(by)i Ff(c)p Fe(.)49 b(The)31 b(ar)n(guments)f(gi)n(v)o(en)g(to)g Fc(simcmd)h Fe(are)0 429 y(normal)e(RSIM)i(commands,)f(and)g Fc(simcmd)g Fe(will)f(apply)g (the)h(speci\002ed)g(RSIM)h(command)e(to)g(each)i(node)e(in)0 549 y(the)23 b(current)h(selection.)29 b(T)m(ry)23 b(RSIM)h(commands)e (on)h(this)g(node)g(\(such)g(as)h Ff(?)30 b Fe(or)23 b Ff(d)p Fe(\))h(by)f(using)f(the)i(command)e(as)0 670 y(an)j(ar)n(gument)f(to)h Fc(simcmd)p Fe(.)146 790 y(Y)-11 b(ou)30 b(can)g(enter)g(RSIM)h(interacti)n(v)o(ely)d(at)i(an)o(y)f (time)g(by)h(simply)e(typing)h Fc(:rsim)p Fe(.)46 b(T)-8 b(o)29 b(continue)g(using)g(the)0 911 y(RSIM)c(tool,)f(escape)i(to)e (Magic)h(by)f(typing)g(a)h(period)f(\()p Fc(.)p Fe(\))31 b(to)25 b(the)f(RSIM)i(prompt.)146 1031 y(The)i(node)g Ff(RESET)p 839 1031 60 5 v 59 w(B)g Fe(must)f(be)h(set)f(to)h(a)g (\2230\224.)40 b(This)27 b(node)h(is)f(the)h(red)g(square)g(area)h(at)e (the)h(middle)f(right)0 1151 y(of)f(the)h(circuit.)35 b(Place)27 b(the)f(cursor)h(o)o(v)o(er)e(this)h(node)g(and)g(select)h (it.)35 b(T)-8 b(ype)26 b(the)g(Magic)g(commands)g Fc(:simcmd)g(l)0 1272 y Fe(follo)n(wed)g(by)g Fc(:simcmd)h(c)g Fe(to)f(set)h(the)g (selected)f(node)h(to)f(a)h(\2230\224.)37 b(Click)27 b(the)f(middle)g(mouse)g(b)n(utton)f(to)i(check)0 1392 y(that)i(this)f(node)h(is)g(no)n(w)f(\2230\224.)45 b(Step)29 b(the)g(clock)h(once)f(more)g(to)g(ensure)g(the)g(counter)h(is)e (reset.)45 b(Do)29 b(this)f(using)0 1513 y(the)d Fc(:simcmd)g(c)g Fe(command.)146 1633 y(The)f(outputs)d(of)j(this)e(counter)h(are)h(the) f(four)h(v)o(ertical)e(purple)h(strips)g(at)g(the)g(bottom)f(of)h(the)g (circuit.)30 b(Zoom)0 1753 y(in)h(if)g(necessary)-6 b(,)33 b(select)e(each)h(of)g(these)f(nodes,)h(and)g(click)f(the)g(middle)f(b) n(utton)g(to)h(check)h(that)f(all)g(are)h(\2230\224.)0 1874 y(Each)f(of)g(these)g(four)g(nodes)g(is)f(labeled)h Ff(bit)p 1563 1874 V 59 w(x)p Fe(.)50 b(If)31 b(the)o(y)g(are)g(all)g (not)g(\2230\224,)h(check)g(the)f(circuit)f(to)h(mak)o(e)g(sure)0 1994 y Ff(hold=1)26 b Fe(and)h Ff(RESET)p 780 1994 V 59 w(B=0)p Fe(.)36 b(Assuming)25 b(these)i(nodes)f(are)h(at)g(their)g (correct)g(v)n(alue,)f(you)g(can)i(no)n(w)d(simulate)0 2114 y(the)32 b(counter)-5 b(.)51 b(Set)32 b Ff(RESET)p 971 2114 V 60 w(B)g Fe(to)f(a)i(\2231\224)f(by)g(selecting)f(it)g (\(the)h(red)g(square\))g(and)g(then)g(typing)e Fc(:simcmd)j(h)p Fe(.)0 2235 y(Step)22 b(the)g(clock)g(by)g(typing)f Fc(:simcmd)i(c)p Fe(.)30 b(Using)21 b(the)h(same)g(procedure,)h(set)f(the)g(node)g Ff(hold)f Fe(\(the)h(blue)g(square\))0 2355 y(to)i(a)i(\2230\224.)146 2476 y(W)-8 b(e')o(ll)34 b(w)o(atch)f(the)h(output)e(bits)h(of)g(this)g (counter)g(as)h(it)f(runs.)57 b(Place)34 b(the)f(box)g(around)h(all)f (four)h(outputs)0 2596 y(\(purple)29 b(strips)f(at)i(the)f(bottom\))f (and)h(zoom)g(in)f(so)h(their)g(labels)g(are)h(visible.)43 b(Select)30 b(one)f(of)g(the)h(outputs)d(by)0 2716 y(placing)f(the)g (cursor)g(o)o(v)o(er)g(it)g(and)g(typing)f Fc(s)p Fe(.)36 b(Add)26 b(the)g(other)g(three)h(outputs)e(to)h(the)g(selection)f(by)h (placing)g(the)0 2837 y(cursor)31 b(o)o(v)o(er)f(each)h(and)g(typing)f Fc(S)p Fe(.)h(These)g(four)g(nodes)f(should)g(be)h(the)f(only)g(ones)h (in)f(the)h(selection.)48 b(Click)0 2957 y(the)30 b(middle)e(mouse)i(b) n(utton)e(to)i(display)e(the)i(node)g(v)n(alues.)45 b(Step)30 b(the)g(clock)f(by)h(typing)f Fc(:simcmd)h(c)p Fe(.)46 b(Click)0 3077 y(the)27 b(middle)f(b)n(utton)g(again)g(to)h(check)h (the)e(nodes.)38 b(Repeat)27 b(stepping)f(the)h(clock)g(and)g (displaying)f(the)h(outputs)0 3198 y(se)n(v)o(eral)g(times,)h(and)g (you')o(ll)g(see)g(the)g(outputs)f(sequence)h(as)h(a)f(counter)-5 b(.)40 b(If)29 b(you)e(also)h(follo)n(w)f(the)h(te)o(xt)f(on)h(the)0 3318 y(screen,)d(you')o(ll)f(also)h(see)g(that)f(the)h(outputs)e(are)j (also)e(being)g(w)o(atched.)146 3439 y(Y)-11 b(ou)29 b(may)g(ha)n(v)o(e)g(noticed)g(that)f(the)h(results)g(are)h(printed)e (v)o(ery)h(quickly)f(if)h(the)h(middle)e(b)n(utton)g(is)g(click)o(ed)0 3559 y(a)i(second)f(time)g(without)f(changing)h(the)g(selection.)45 b(This)28 b(is)h(because)h(the)g(node)f(names)g(do)h(not)f(ha)n(v)o(e)g (to)g(be)0 3679 y(recomputed)i(if)g(the)h(selection)e(remains)h (unchanged.)50 b(Thus,)33 b(you)e(can)g(increase)h(the)g(performance)g (of)f(this)0 3800 y(tool)j(by)h(minimizing)e(selection)i(changes.)62 b(This)34 b(can)i(be)f(accomplished)f(by)h(adding)g(other)g(nodes)f(to) h(the)0 3920 y(current)25 b(selection)f(that)g(you)h(are)g(intending)f (to)g(check.)146 4041 y(T)-8 b(o)25 b(erase)g(all)g(the)g(RSIM)g(v)n (alue)f(labels)h(from)f(the)h(layout,)f(clear)h(the)g(selection)f(by)h (typing:)900 4253 y Fc(:select)g(clear)146 4465 y Fe(and)i(then)f (click)g(the)g(middle)f(mouse)h(b)n(utton.)34 b(The)26 b(RSIM)h(labels)f(do)g(not)g(af)n(fect)g(the)h(cell)f(modi\002ed)g (\003ag,)0 4586 y(nor)35 b(will)e(the)o(y)h(be)h(written)f(in)h(the)f Fc(.mag)h Fe(\002le.)60 b(When)35 b(you')-5 b(re)35 b(\002nished)f (using)g(RSIM,)h(resume)g(RSIM)g(by)0 4706 y(typing)29 b Fc(:rsim)h Fe(and)g(then)g(quit)f(it)h(by)g(typing)f(a)i Fc(q)f Fe(to)g(the)g(RSIM)h(prompt.)46 b(Quitting)28 b(Magic)i(before)h(quitting)0 4826 y(RSIM)25 b(will)f(also)h(quit)f (RSIM.)146 4947 y(W)-8 b(e')j(v)o(e)21 b(used)e(a)i(fe)n(w)f(macros)g (to)f(lessen)h(the)g(typing)e(necessary)j(for)f(the)g(RSIM)h(tool.)28 b(The)20 b(ones)g(commonly)0 5067 y(used)25 b(are:)900 5280 y Fc(:macr)n(o)g(h)h(\223simcmd)e(h\224)900 5400 y(:macr)n(o)h(l)g(\223simcmd)g(l\224)1875 5649 y Fe(\2266\226)p eop %%Page: 7 7 7 6 bop 0 -180 a Fe(Magic)24 b(T)l(utorial)g(#11:)30 b(Using)24 b(IRSIM)h(and)g(RSIM)h(with)e(Magic)812 b(September)25 b(26,)g(2001)900 84 y Fc(:macr)n(o)g(k)h(\223simcmd)e(c\224)1875 5649 y Fe(\2267\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/copyright.ps0000644000175000001440000003050310751423606016245 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: copyright.dvi %%Pages: 1 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Roman %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips copyright.dvi -o copyright.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Roman % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (copyright.dvi) @start /Fa 1 14 df<0000000003FFE00000000000000000007FFFFF00000000000000 0003FFFFFFE0000000000000000FFFFFFFF8000000000000007FFE003FFF000000000000 00FFC00001FF80000000000003FE0000003FE000000000000FF80000000FF80000000000 1FC000000001FC00000000003F8000000000FE0000000000FE00000000003F8000000001 FC00000000001FC000000003F0000000000007E000000007E0000000000003F00000000F C0000000000001F80000001F80000000000000FC0000003F000000000000007E0000007E 000000000000003F0000007C000000000000001F000000F8000000000000000F800001F8 000000000000000FC00001F00000000000000007C00003E00000000000000003E00003E0 0000000000000003E00007C00000000000000001F0000FC00000000000000001F8000F80 0000000000000000F8000F00000000000000000078001F0000000000000000007C001F00 00000000000000007C003E0000000000000000003E003E0000000000000000003E003C00 00000000000000001E003C0000000000000000001E007C0000000000000000001F007C00 00000000000000001F00780000000000000000000F00780000000000000000000F00F800 00000000000000000F80F80000000000000000000F80F00000000000000000000780F000 00000000000000000780F00000000000000000000780F00000000000000000000780F000 00000000000000000780F00000000000000000000780F00000000000000000000780F000 00000000000000000780F00000000000000000000780F00000000000000000000780F000 00000000000000000780F00000000000000000000780F80000000000000000000F80F800 00000000000000000F80780000000000000000000F00780000000000000000000F007C00 00000000000000001F007C0000000000000000001F003C0000000000000000001E003C00 00000000000000001E003E0000000000000000003E003E0000000000000000003E001F00 00000000000000007C001F0000000000000000007C000F00000000000000000078000F80 0000000000000000F8000FC00000000000000001F80007C00000000000000001F00003E0 0000000000000003E00003E00000000000000003E00001F00000000000000007C00001F8 000000000000000FC00000F8000000000000000F8000007C000000000000001F0000007E 000000000000003F0000003F000000000000007E0000001F80000000000000FC0000000F C0000000000001F800000007E0000000000003F000000003F0000000000007E000000001 FC00000000001FC000000000FE00000000003F80000000003F8000000000FE0000000000 1FC000000001FC00000000000FF80000000FF8000000000003FE0000003FE00000000000 00FFC00001FF800000000000007FFE003FFF000000000000000FFFFFFFF8000000000000 0003FFFFFFE000000000000000007FFFFF00000000000000000003FFE00000000000595C 7BC664>13 D E /Fb 107[44 44 25[50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 1[28 50 50 33 44 50 44 50 44 11[72 61 55 66 1[55 1[72 1[61 2[33 3[61 72 66 1[72 7[50 50 2[50 3[50 50 1[25 1[25 44[{ TeXBase1Encoding ReEncodeFont }45 100.000003 /Times-Roman rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 536 3720 a Fb(Cop)o(yright)992 3717 y(c)964 3720 y Fa(\015)p Fb(1985,)24 b(1989,)g(1990)g(Re)o(gents)h(of)g(the)f(Uni)n (v)o(ersity)f(of)i(California,)579 3841 y(La)o(wrence)g(Li)n(v)o (ermore)e(National)h(Labs,)h(Stanford)g(Uni)n(v)o(ersity)-6 b(,)22 b(and)j(Digital)519 3961 y(Equipment)e(Corporation.)30 b(Permission)24 b(to)g(use,)h(cop)o(y)-6 b(,)24 b(modify)-6 b(,)23 b(and)i(distrib)n(ute)550 4082 y(this)f(softw)o(are)h(and)f(its) g(documentation)f(for)j(an)o(y)e(purpose)g(and)h(without)e(fee)j(is)546 4202 y(hereby)f(granted,)f(pro)o(vided)g(that)g(the)h(abo)o(v)o(e)f (cop)o(yright)g(notice)g(appears)h(in)g(all)663 4322 y(copies.)30 b(The)25 b(cop)o(yright)f(holders)g(mak)o(e)h(no)f (representations)g(about)g(the)668 4443 y(suitability)e(of)j(this)f (softw)o(are)h(for)g(an)o(y)f(purpose.)31 b(It)24 b(is)h(pro)o(vided)e (\223as)i(is\224)591 4563 y(without)e(e)o(xpress)h(or)h(implied)e(w)o (arranty)-6 b(.)31 b(Export)24 b(of)h(this)f(softw)o(are)h(outside)704 4683 y(of)g(the)g(United)f(States)h(of)g(America)g(may)f(require)h(an)g (e)o(xport)f(license.)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/introduction.ps0000644000175000001440000006515210751423606016766 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: introduction.dvi %%Pages: 4 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Roman Times-Bold Times-Italic Courier %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips introduction.dvi -o introduction.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Roman % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (introduction.dvi) @start /Fa 134[60 5[47 3[60 66 1[33 3[66 60 1[53 1[53 1[60 12[80 66 4[86 113 80 2[47 1[93 3[86 1[86 12[60 1[60 60 2[30 43[66 2[{ TeXBase1Encoding ReEncodeFont }24 119.999948 /Times-Bold rf /Fb 136[60 4[60 2[60 1[60 60 2[60 1[60 1[60 60 60 1[60 32[60 17[60 12[60 33[{ TeXBase1Encoding ReEncodeFont } 14 100.000003 /Courier rf /Fc 133[44 4[55 33 39 44 2[50 55 83 28 55 1[28 1[50 33 44 55 44 1[50 17[78 1[94 4[78 2[66 72 72 1[72 6[33 10[28 25 43[55 2[{ TeXBase1Encoding ReEncodeFont } 28 100.000003 /Times-Bold rf /Fd 134[44 3[50 28 39 39 2[50 50 1[28 44 1[28 50 50 28 44 50 44 1[50 9[83 61 1[55 50 4[66 83 55 5[61 1[72 2[61 6[33 7[50 3[25 6[33 3[50 35[{ TeXBase1Encoding ReEncodeFont }32 100.000003 /Times-Italic rf /Fe 1 16 df<0001FF0000000FFFE000003FFFF800007FFFFC0001FFFFFF0003FFFF FF8007FFFFFFC00FFFFFFFE01FFFFFFFF01FFFFFFFF03FFFFFFFF87FFFFFFFFC7FFFFFFF FC7FFFFFFFFCFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFE FFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFE7FFFFFFFFC7FFFFFFFFC7FFFFFFFFC3F FFFFFFF81FFFFFFFF01FFFFFFFF00FFFFFFFE007FFFFFFC003FFFFFF8001FFFFFF00007F FFFC00003FFFF800000FFFE0000001FF000027267BAB32>15 D E /Ff 138[80 48 56 64 1[80 72 80 120 3[40 80 72 48 64 80 64 80 72 13[80 104 4[135 3[56 4[104 104 96 12[72 72 72 72 72 3[48 45[{ TeXBase1Encoding ReEncodeFont }30 143.999997 /Times-Bold rf /Fg 103[33 100 50 1[44 44 24[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 6[61 72 72 94 72 72 61 55 66 1[55 72 72 89 61 1[39 33 72 72 55 61 72 66 66 72 6[28 50 50 50 50 1[50 50 50 50 50 28 25 33 25 2[33 33 33 2[50 2[33 29[55 55 2[{ TeXBase1Encoding ReEncodeFont }76 100.000003 /Times-Roman rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 1053 68 a Fg(This)24 b(tutorial)g(corresponds)g(to)g(Magic)h(v) o(ersion)e(7.)0 780 y Ff(1)143 b(Intr)m(oduction)0 1004 y Fg(This)24 b(v)o(ersion)g(of)h(Magic,)g(v)o(ersion)f(6,)h(gathers)g (together)f(w)o(ork)h(done)g(by)g(numerous)f(people)h(at)g(se)n(v)o (eral)f(insti-)0 1124 y(tutions)i(since)h(Magic)h(v)o(ersion)e(4)i(w)o (as)f(released)h(from)g(Berk)o(ele)o(y)f(on)h(the)f(1986)g(VLSI)h (tools)f(tape.)39 b(This)27 b(is)g(a)0 1245 y(release)e(of)f(Magic)f (and)h(IRSIM)h(only)-6 b(.)29 b(Y)-11 b(ou')o(ll)23 b(probably)h(w)o (ant)f(to)h(obtain)f(other)h(tools)f(by)g(ordering)h(the)g(1986)0 1365 y(VLSI)h(T)-8 b(ools)24 b(T)-8 b(ape)25 b(from)g(Berk)o(ele)o(y)-6 b(.)146 1485 y(This)21 b(release)h(has)g(been)g(prepared)g(with)f(the)g (assistance)g(of)h(se)n(v)o(eral)f(groups.)29 b(Much)21 b(of)g(the)h(ne)n(w)f(softw)o(are)0 1606 y(came)33 b(from)g(W)-8 b(alter)33 b(Scott')-5 b(s)33 b(group)f(at)h(the)g(La)o(wrence)g(Li)n (v)o(ermore)f(National)g(Labs)h(\(LLNL\).)g(LLNL)g(also)0 1726 y(pro)o(vided)i(partial)g(funding)h(to)f(help)h(prepare)h(the)f (release.)65 b(Digital)35 b(Equipment)f(Corporation')-5 b(s)35 b(W)-8 b(estern)0 1847 y(Research)38 b(Lab)f(\(DECWRL\))h (helped)f(out)f(by)h(pro)o(viding)e(computer)h(equipment,)j(a)e(place)h (to)e(w)o(ork,)k(and)0 1967 y(the)29 b(services)g(of)g(one)g(of)h(us)e (\(Robert)i(Mayo\).)43 b(Don)29 b(Stark,)i(Michael)d(Arnold,)i(and)f (Gordon)g(Hamachi)g(also)0 2087 y(w)o(ork)o(ed)e(on)g(the)h(release)g (at)f(DECWRL.)h(Stanford)g(donated)e(signi\002cant)h(pieces)g(of)h(ne)n (w)f(code,)h(including)e(a)0 2208 y(simulation)21 b(system)h(called)h (IRSIM.)h(Other)g(indi)n(viduals)c(and)j(institutions)e(ha)n(v)o(e)i (also)g(contrib)n(uted)f(code)h(and)0 2328 y(assistance)h(in)h(w)o(ays) f(too)h(numerous)e(to)i(detail)f(here.)146 2449 y(Ne)n(w)h(features)g (in)f(Magic)h(V)-11 b(ersion)24 b(6)h(include:)145 2646 y Fe(\017)49 b Fg(Ne)n(w)24 b(and)h(Impro)o(v)o(ed)e(Routing\227)p Fd(Mic)o(hael)g(Arnold)h(and)g(W)-9 b(alter)24 b(Scott)g(of)h(LLNL)244 2766 y Fg(Three)e(major)f(routing)f(impro)o(v)o(ements)f(ha)n(v)o(e)i (been)h(made)g(in)f(this)f(v)o(ersion)h(of)h(Magic.)29 b(There)23 b(is)f(a)h(ne)n(w)-6 b(,)244 2887 y(impro)o(v)o(ed,)34 b(global)g(router)g(courtesy)g(of)g(W)-8 b(alter)35 b(Scott)f(\(of)g (LLNL\).)g(W)-8 b(alter)35 b(Scott)f(has)g(also)g(added)244 3007 y(a)g(gate)g(array)h(router)-5 b(.)59 b(See)35 b(the)f (\223garoute\224)g(command)g(in)f(the)i(manual)e(page)i(for)f(details.) 59 b(Michael)244 3128 y(Arnold)22 b(\(of)h(LLNL\))f(has)h(written)f(an) h(interacti)n(v)o(e)e(maze)i(router)g(that)f(allo)n(ws)g(the)h(user)f (to)h(specify)f(hints)244 3248 y(to)i(control)g(the)h(routing.)30 b(See)25 b(the)g(documentation)e(for)i(the)g(\223iroute\224)g(command.) 145 3444 y Fe(\017)49 b Fg(Extractor)24 b(Enhancements\227)p Fd(Don)g(Stark)g(of)g(Stanfor)l(d)g(and)g(W)-9 b(alter)24 b(Scott)g(of)g(LLNL)244 3564 y Fg(The)29 b(ne)n(w)h(\223e)o (xtresis\224)f(command,)g(de)n(v)o(eloped)f(by)i(Don)f(Stark,)i(pro)o (vides)d(substantially)g(better)h(resis-)244 3684 y(tance)37 b(e)o(xtraction.)64 b(Magic')-5 b(s)36 b(normal)g(e)o(xtraction)f (\(\223e)o(xtract\224\))i(lumps)f(resistances)g(on)g(a)h(node)f(into) 244 3805 y(a)f(single)g(v)n(alue.)61 b(In)36 b(branching)e(netw)o (orks,)j(this)e(approximation)e(is)i(often)g(not)g(acceptable.)62 b(Resis)244 3925 y(w)o(as)33 b(written)g(to)g(solv)o(e)f(this)g (problem.)55 b(W)-8 b(alter)34 b(Scott)f(added)g(accurate)h(path)f (length)g(e)o(xtraction,)h(an)244 4046 y(important)23 b(feature)j(when)e(dealing)h(with)f(high)g(speed)g(circuits,)h(such)f (as)h(ECL.)145 4241 y Fe(\017)49 b Fg(Ne)n(w)20 b(contact)g (structure\227)p Fd(W)-9 b(alter)18 b(Scott)i(and)g(Mic)o(hael)f (Arnold)g(of)h(LLNL)i(and)d(Don)h(Stark)g(of)f(Stanfor)l(d)244 4362 y Fg(Multilayer)25 b(contacts)g(are)i(handled)e(better)-5 b(.)34 b(In)26 b(the)g(pre)n(vious)e(v)o(ersion)h(of)h(Magic,)g(there)g (needed)g(to)g(be)244 4482 y(a)31 b(separate)g(contact)f(type)g(for)h (each)g(possible)e(combination)g(of)i(contact)f(layers)h(o)o(v)o(er)e (a)i(gi)n(v)o(en)e(point.)244 4602 y(This)21 b(caused)h(a)h (combinatorial)d(e)o(xplosion)h(of)h(tile)f(types)h(for)g(multi-layer)f (technologies)g(with)g(stack)o(ed)244 4723 y(contacts.)29 b(Under)23 b(the)f(ne)n(w)g(scheme,)h(there)g(are)g(only)f(a)h(couple)f (of)h(tile)f(types)g(for)g(each)h(layer:)30 b(one)23 b(that)244 4843 y(connects)h(up,)h(one)g(that)f(connects)g(do)n(wn,)g (and)h(one)g(that)f(connects)g(in)h(both)f(directions.)145 5039 y Fe(\017)49 b Fg(Simulator)24 b(Interf)o(ace)i(to)e(IRSIM\227)p Fd(Stanfor)l(d)244 5159 y Fg(A)e(simulator)e(interf)o(ace)j(is)e(pro)o (vided)g(courtesy)g(of)h(Stanford.)30 b(See)23 b(the)e(commands)g (\223startrsim\224,)h(\223sim-)244 5280 y(cmd\224,)35 b(and)e(\223rsim\224.)55 b(The)34 b(irsim)e(simulator)l(,)h(Stanford') -5 b(s)33 b(much)g(impro)o(v)o(ed)e(re)n(write)i(of)g(esim,)i(is)d(in-) 244 5400 y(cluded)24 b(in)h(this)f(distrib)n(ution.)k(Credit)d(goes)f (to)h(Mik)o(e)f(Cho)n(w)-6 b(,)24 b(Arturo)g(Salz,)i(and)f(Mark)f(Horo) n(witz.)1875 5649 y(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Fg(September)25 b(26,)f(2001)482 b(Ov)o(ervie)n(w)24 b(of)h(the)g(DECWRL/Li)n(v)o(ermore)e(Magic)i(Release)h(\(V)-11 b(ersion)24 b(6\))145 68 y Fe(\017)49 b Fg(Ne)n(w)24 b(de)n(vice/machine)g(Support\227)p Fd(V)-11 b(arious)244 188 y Fg(X11)24 b(is)f(fully)h(supported)f(in)g(this)g(release,)i(and)f (is)g(the)g(preferred)h(interf)o(ace.)31 b(Older)24 b(dri)n(v)o(ers)f (for)h(graph-)244 309 y(ics)34 b(terminals)f(and)g(X10)h(are)h(also)e (included,)j(b)n(ut)d(X11)h(is)f(the)h(preferred)h(interf)o(ace)g (\(meaning)e(it)h(is)244 429 y(better)c(supported)g(and)g(you')o(ll)g (ha)n(v)o(e)g(lots)g(of)g(compan)o(y\).)47 b(Magic')-5 b(s)30 b(X11)g(dri)n(v)o(er)g(has)g(a)h(long)f(history)-6 b(,)244 549 y(starting)29 b(with)h(an)h(X10)f(dri)n(v)o(er)f(by)h(Doug) g(P)o(an)h(at)f(Stanford.)48 b(Bro)n(wn)30 b(Uni)n(v)o(ersity)-6 b(,)30 b(the)g(Uni)n(v)o(ersity)e(of)244 670 y(Southern)e(California,)g (the)f(Uni)n(v)o(ersity)f(of)i(W)-8 b(ashington,)24 b(and)i(La)o (wrence)g(Li)n(v)o(ermore)e(National)h(Labs)244 790 y(all)k(prepared)h (impro)o(v)o(ed)e(v)o(ersions,)h(some)g(of)h(them)f(for)h(X11.)44 b(Don)30 b(Stark)g(of)f(Stanford)h(took)f(on)g(the)244 911 y(task)24 b(of)h(pulling)e(these)i(together)f(and)h(producing)f (the)h(X11)f(dri)n(v)o(er)g(in)g(this)g(release.)244 1107 y(Magic)31 b(runs)g(on)g(a)h(number)f(of)g(w)o(orkstations,)g (such)g(as)h(the)f(DECstation)g(3100)f(and)i(Sun')-5 b(s)31 b(SP)-9 b(ARC)244 1227 y(processors.)33 b(P)o(artial)25 b(Unix)g(System)g(V)h(support)e(is)h(pro)o(vided,)g(via)g(the)h (compilation)d(\003ags)j(mentioned)244 1348 y(belo)n(w)-6 b(.)29 b(The)24 b(system)e(also)h(runs)h(on)f(the)h(MacII.)g(Don)f (Stark)h(gets)f(credit)h(for)g(the)g(System)f(V)g(mods)g(and)244 1468 y(support)h(for)h(HP)g(machines,)f(while)g(Mik)o(e)h(Cho)n(w)f (helped)g(get)h(it)f(running)g(on)h(the)f(MacII.)244 1664 y(T)-8 b(o)37 b(assist)e(people)i(with)f(small)g(machines)g (\(such)h(as)g(the)f(Mac)h(II\),)h(Magic)e(can)h(no)n(w)f(be)h (compiled)244 1785 y(without)30 b(some)h(of)h(its)e(f)o(anc)o(y)i (features.)51 b(Compilation)30 b(\003ags)i(are)g(pro)o(vided,)g(as)g (indicated)f(belo)n(w)-6 b(,)31 b(to)244 1905 y(eliminate)24 b(things)f(lik)o(e)h(routing,)g(plotting,)f(or)i(calma)g(output.)k (This)24 b(is)g(courtesy)h(of)g(Don)f(Stark.)145 2178 y Fe(\017)49 b Fg(Reor)n(ganization)24 b(of)h(Magic)g(Source)g (Directory)244 2298 y(Magic,)30 b(as)g(pre)n(viously)e(distrib)n(uted,) h(w)o(as)h(set)f(up)h(with)f(the)g(assumption)f(that)h(lots)g(of)h (people)f(w)o(ould)244 2418 y(be)h(changing)g(the)g(code)h(at)f(the)g (same)h(time.)46 b(As)30 b(a)h(result,)g(the)f(mak)o(e\002les)g(did)g (all)g(sorts)g(of)g(paranoid)244 2539 y(things)23 b(lik)o(e)i(making)e (e)o(xtra)i(copies)g(of)f(the)h(source)g(code)g(whene)n(v)o(er)f(a)h (module)f(w)o(as)h(re-installed.)244 2735 y(Since)32 b(Magic)e(is)h(more)g(stable)g(no)n(w)-6 b(,)31 b(this)g(cop)o(ying)f (is)h(no)g(longer)f(needed.)51 b(Instead,)32 b(each)g(mak)o(e\002le)244 2855 y(in)l(v)n(ok)o(es)21 b(the)g(script)h Fc(../:instclean)g Fg(after)g(installing)e(a)i(module.)29 b(This)21 b(script,)g(by)h(def)o (ault,)g(doesn')n(t)f(cop)o(y)244 2976 y(the)26 b(source)h(code)f(b)n (ut)g(does)g(lea)n(v)o(e)h(the)f(.o)g(\002les)h(around.)35 b(This)26 b(cuts)g(do)n(wn)f(on)h(the)g(disk)g(space)h(needed)244 3096 y(by)33 b(a)h(f)o(actor)g(of)g(tw)o(o.)57 b(Y)-11 b(ou)33 b(can)h(change)g(the)g(script)f(if)g(you)h(w)o(ant)f(the)h(cop) o(ying,)g(or)g(if)g(you)f(w)o(ant)g(to)244 3217 y(delete)25 b(unused)f(.o)g(\002les)h(to)g(sa)n(v)o(e)f(e)n(v)o(en)g(more)h(disk)f (space.)145 3489 y Fe(\017)49 b Fg(Lots)24 b(of)h(b)n(ug)f(\002x)o (es\227)p Fd(V)-11 b(arious)244 3609 y Fg(Lots)25 b(of)i(b)n(ugs)e(ha)n (v)o(e)h(been)h(\002x)o(ed)f(in)f(this)h(release.)35 b(W)-8 b(e')j(d)27 b(lik)o(e)f(to)g(thank)f(e)n(v)o(erybody)g(that)h (has)g(reported)244 3730 y(b)n(ugs)e(in)g(the)h(past.)30 b(If)c(you)e(\002nd)h(a)g(ne)n(w)f(b)n(ug,)h(please)g(report)f(it)h(as) g(mentioned)e(belo)n(w)-6 b(.)0 4157 y Ff(2)143 b(Distrib)m(ution)33 b(Inf)l(ormation)0 4410 y Fg(This)27 b(v)o(ersion)g(of)g(Magic)h(is)f (a)n(v)n(ailable)g(via)h(FTP)-11 b(.)28 b(Contact)g(\223)p Fb(magic@decwrl.dec.com)p Fg(\224)23 b(for)28 b(informa-)0 4530 y(tion.)146 4664 y(F)o(or)d(a)g(handling)f(fee,)h(this)f(v)o (ersion)g(of)h(Magic)f(may)h(be)g(obtained)f(on)g(magnetic)g(tape)h (from:)900 5003 y(EECS/ERL)g(Industrial)f(Liaison)g(Program)900 5123 y(479)g(Cory)i(Hall)900 5244 y(Uni)n(v)o(ersity)d(of)h(California) h(at)g(Berk)o(ele)o(y)900 5364 y(Berk)o(ele)o(y)-6 b(,)24 b(CA)i(94720)1875 5649 y(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Fg(Ov)o(ervie)n(w)24 b(of)h(the)f(DECWRL/Li)n(v)o (ermore)g(Magic)g(Release)i(\(V)-11 b(ersion)25 b(6\))482 b(September)25 b(26,)g(2001)0 99 y Ff(3)143 b(Bug)35 b(Reports)0 327 y Fg(Maintenance)29 b(of)g(Magic)g(is)f(a)i(v)n (olunteer)e(ef)n(fort.)44 b(Please)29 b(send)g(descriptions)f(of)h(b)n (ugs)f(via)h(InterNet)g(e-mail)0 448 y(to)22 b(\223)p Fb(magic@decwrl.dec.com)p Fg(\224)d(or)j(via)h(Uucp)f(e-mail)g(to)g (\223)p Fb(decwrl!magic)p Fg(\224.)28 b(If)23 b(you)f(de)n(v)o(elop)f (a)i(\002x)0 568 y(for)i(the)g(problem,)f(please)g(send)h(that)f(too!)0 923 y Ff(4)143 b(Changes)34 b(f)l(or)i(Magic)f(maintainers)0 1151 y Fg(Pre)n(vious)e(releases)h(of)g(Magic)f(e)o(xpected)g(to)g (\002nd)h(their)f(system)g(\002les)h(in)f(the)g(home)h(directory)f(of)h (the)f(user)0 1271 y Fc(cad)p Fg(.)41 b(The)28 b(def)o(ault)g(beha)n (vior)g(of)g(v)o(ersion)f(6)h(is)g(no)g(dif)n(ferent,)g(b)n(ut)g(it)f (is)h(possible)f(to)h(put)f(the)h(\002les)g(in)g(another)0 1392 y(directory)22 b(by)h(setting)e(the)i Fc(CAD)p 1160 1392 30 4 v 35 w(HOME)f Fg(shell)g(en)l(vironment)g(v)n(ariable.)29 b(If)23 b(this)f(v)n(ariable)g(is)g(set,)h(magic)f(will)0 1512 y(use)j(that)f(location)g(instead)g(of)h(the)g(\230cad)g(it)f (\002nds)h(in)f(the)h(passw)o(ord)f(\002le.)0 1823 y Fa(4.1)119 b(INST)-11 b(ALLING)30 b(MA)-7 b(GIC)0 2015 y Fg(The)34 b(distrib)n(ution)e(tape)i(contains)g(a)g(v)o(ersion)g(of)g (Magic)g(ready)g(to)g(run)g(on)g(Digital')-5 b(s)33 b(line)h(of)g (Ultrix)g(RISC)0 2135 y(w)o(orkstations,)21 b(such)h(as)g(the)g (DECstation)g(3100.)29 b(F)o(or)22 b(other)g(machines,)g(read)h(ahead.) 31 b(In)22 b(an)o(y)g(e)n(v)o(ent,)f(all)h(users)0 2256 y(should)32 b(set)i(their)f(shell)g(en)l(vironment)f(v)n(ariable)i(CAD) p 1984 2256 V 36 w(HOME)f(to)g(point)g(to)g(the)g(place)h(where)g(the)g (tape)g(is)0 2376 y(loaded,)24 b(unless)g(that)h(place)g(is)f(\230cad,) h(in)g(which)f(case)i(things)d(will)h(def)o(ault)h(correctly)-6 b(.)146 2499 y(Before)26 b(installing)d(Magic,)h(you)g(should)f(set)h (your)h(shell)f(en)l(vironment)f(v)n(ariable)h(CAD)p 3245 2499 V 36 w(HOME)g(to)g(point)0 2619 y(to)18 b(the)h(place)g (where)h(you)e(loaded)g(the)h(tape.)29 b(If)19 b(you)g(\223cd\224)g(to) f(the)h(magic)g(source)f(directory)h(\($CAD)p 3453 2619 V 36 w(HOME/src/magic\))0 2740 y(you)k(will)f(\002nd)h(a)h(mak)o (e\002le.)30 b(A)23 b(\223)p Fc(mak)o(e)h(con\002g)p Fg(\224)g(will)f(run)g(a)g(con\002guration)g(script)f(that)h(asks)g (questions)f(about)0 2860 y(your)j(con\002guration)f(and)g(sets)h(up)f (magic)h(to)f(be)h(compiled)f(for)h(your)f(local)h(en)l(vironment.)146 2983 y(After)g(running)f(a)h(\223mak)o(e)g(con\002g\224,)g(you)f(can)h (run)f(a)h(\223)p Fc(mak)o(e)h(f)n(or)n(ce)p Fg(\224)f(to)f(force)i(a)f (complete)f(recompilation)0 3103 y(of)k(magic.)41 b(A)28 b(\224)p Fc(mak)o(e)i(install)p Fg(\224)d(will)h(then)g(cop)o(y)g(the)g (binaries)g(to)g(the)g($CAD)p 2779 3103 V 36 w(HOME/bin)f(area,)j(as)e (well)g(as)0 3224 y(install)23 b(things)h(in)g($CAD)p 905 3224 V 36 w(HOME/lib)f(and)i($CAD)p 1821 3224 V 36 w(HOME/man.)146 3346 y(Included)k(in)f(this)f(documentation)g(is)h(a)h (set)f(of)h(Magic)f(maintainer')-5 b(s)27 b(manuals.)41 b(These)29 b(should)e(be)i(read)0 3467 y(by)f(an)o(ybody)f(interested)h (in)g(modifying)e(Magic)i(or)h(by)f(an)o(ybody)f(that)h(is)f(ha)n(ving) h(dif)n(\002culty)f(installing)g(it)g(on)0 3587 y(their)e(system.)0 3897 y Fa(4.2)119 b(T)-11 b(echnology)30 b(\002le)h(changes)0 4090 y Fg(Users)25 b(of)g(Magic)f(4)h(should)e(ha)n(v)o(e)i(little)f (trouble)g(switching)f(to)h(Magic)h(6.)146 4213 y(A)39 b(ne)n(w)f(section,)j(the)d Fc(mzr)n(outer)i Fg(section)e(needs)g(to)h (be)f(added)h(to)f(your)g(technology)f(\002les.)72 b(See)39 b(the)0 4333 y(mzrouter)25 b(section)f(of)h(the)f(tutorial)g Fd(Ma)o(gic)g(Maintainer')l(s)g(Manual)f(#2:)31 b(The)25 b(T)-9 b(ec)o(hnolo)o(gy)25 b(F)l(ile)e Fg(for)j(details.)146 4456 y(Display)h(styles)h(must)e(be)j(de\002ned)f(in)g(the)g Fd(.tec)o(h)f Fg(\002le)i(for)f(the)g(mzrouter)g(hint)f(layers)h (magnet,)g(fence)h(and)0 4576 y(rotate.)46 b(W)-8 b(e)30 b(suggest)f(cop)o(ying)g(this)g(information)g(from)g(the)h(styles)f (section)g(of)h(the)g(scmos)f(technology)g(\002le)0 4697 y(on)c(the)f(distrib)n(ution)f(tape.)30 b(Y)-11 b(ou')o(ll)24 b(also)h(need)g(to)f(include)g(these)h(display)f(styles)g(in)g(your)h Fd(.dstyle)f Fg(\002le.)0 5051 y Ff(5)143 b(Beta-test)34 b(Sites)0 5280 y Fg(W)-8 b(e')j(d)24 b(lik)o(e)f(to)g(thank)g(the)g (beta-test)g(sites)g(that)g(tried)g(out)g(this)f(v)o(ersion)h(of)g (Magic,)h(reported)f(b)n(ugs)g(and)g(\002x)o(es)g(in)0 5400 y(a)i(timely)f(manner)l(,)g(and)h(ported)g(the)f(code)h(to)g(ne)n (w)f(machines:)1875 5649 y(\2263\226)p eop %%Page: 4 4 4 3 bop 0 -180 a Fg(September)25 b(26,)f(2001)482 b(Ov)o(ervie)n(w)24 b(of)h(the)g(DECWRL/Li)n(v)o(ermore)e(Magic)i(Release)h(\(V)-11 b(ersion)24 b(6\))300 84 y(Mik)o(e)g(Cho)n(w)-6 b(,)24 b(Apple)g(Computer)300 205 y(Arun)h(Rao,)g(Arizona)g(State)g(Uni)n(v)o (ersity)300 325 y(Richard)g(Hughe)o(y)-6 b(,)24 b(Bro)n(wn)g(Uni)n(v)o (ersity)300 445 y(Rick)h(Carle)o(y)-6 b(,)25 b(Carne)o(gie-Mellon)f (Uni)n(v)o(ersity)300 566 y(Hank)h(W)-8 b(alk)o(er)l(,)25 b(Carne)o(gie-Mellon)f(Uni)n(v)o(ersity)300 686 y(Christos)g(Zoulas,)g (Cornell)h(Uni)n(v)o(ersity)300 807 y(Andreas)g(Andreou,)f(John)g (Hopkins)g(Uni)n(v)o(ersity)300 927 y(Geor)n(ge)h(Entenman,)f(The)h (Microelectronics)f(Center)h(of)g(North)g(Carolina)300 1047 y(Shih-Lien)f(Lu,)h(The)g(MOSIS)g(Service)300 1168 y(Jen-I)g(Pi,)g(The)g(MOSIS)g(Service)300 1288 y(Guntram)f(W)-8 b(olski,)24 b(Silicon)g(Engineering,)g(Inc.)300 1408 y(Don)g(Stark,)i(Stanford)f(Uni)n(v)o(ersity)300 1529 y(Gre)o(gory)f(Frazier)l(,)i(Uni)n(v)o(ersity)d(of)i(California)g(at)f (Los)h(Angeles)300 1649 y(Y)-11 b(uv)n(al)24 b(T)-8 b(amir)l(,)24 b(Uni)n(v)o(ersity)f(of)i(California)g(at)f(Los)h(Angeles)300 1770 y(Ste)n(v)o(en)f(P)o(ark)o(es,)h(Uni)n(v)o(ersity)e(of)h(Illinois) 300 1890 y(Larry)h(McMurchie,)f(Uni)n(v)o(ersity)f(of)i(W)-8 b(ashington)300 2010 y(T)m(im)23 b(Heldt,)i(W)-8 b(ashington)23 b(State)i(Uni)n(v)o(ersity)300 2131 y(Da)n(vid)f(Lee,)i(Xerox)e(P)o (alo)h(Alto)f(Research)i(Center)146 2479 y(Martin)i(Harriman)g(of)g (Silicon)g(Engineering)f(wrote)h(a)g(\223select)h(less\224)f(command)f (for)h(Magic)g(during)f(the)0 2600 y(beta-test)d(phase.)31 b(\223Select)26 b(less\224)e(has)h(been)g(a)g(much-requested)f (feature.)146 2720 y(In)e(addition)d(to)i(the)g(persons)g(named)g(abo)o (v)o(e,)g(there)g(were)h(man)o(y)e(other)h(beta-test)g(users)g(of)g (Magic)g(at)g(these)0 2841 y(and)k(other)h(sites\227too)d(man)o(y)i(to) g(list)f(here.)33 b(W)-8 b(e)26 b(appreciate)g(their)f(help.)32 b(W)-8 b(e)26 b(also)f(ackno)n(wledge)g(the)g(help)g(of)0 2961 y(the)g(pre-release)h(sites,)d(who)i(tested)f(a)h(v)o(ersion)f (that)g(included)g(most)g(of)h(the)g(\002x)o(es)f(from)h(the)g (beta-test)f(phase.)1875 5649 y(\2264\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/maint2.ps0000644000175000001440000132637210751423606015444 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvips(k) 5.92b Copyright 2002 Radical Eye Software %%Title: maint2.dvi %%Pages: 53 %%PageOrder: Ascend %%BoundingBox: 0 0 596 842 %%DocumentFonts: Times-Bold Times-Italic Times-Roman CMSY10 Symbol %%+ Courier-Bold Helvetica font Helvetica-Bold Helvetica-Oblique Courier %%EndComments %DVIPSWebPage: (www.radicaleye.com) %DVIPSCommandLine: dvips maint2 -o %DVIPSParameters: dpi=600, compressed %DVIPSSource: TeX output 2006.02.13:1406 %%BeginProcSet: texc.pro %! /TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin /FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array /BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get }B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr 1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx 0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B /chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ /cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 {2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ 1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put }if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X 1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N /p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ /Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) (LaserWriter 16/600)]{A length product length le{A length product exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end %%EndProcSet %%BeginProcSet: 8r.enc % File 8r.enc as of 2002-03-12 for PSNFSS 9 % % This is the encoding vector for Type1 and TrueType fonts to be used % with TeX. This file is part of the PSNFSS bundle, version 9 % % Authors: S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry, W. Schmidt % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida + Euro. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % % (6) /Euro is assigned to 128, as in Windows ANSI % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /Euro /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndProcSet %%BeginProcSet: bbad153f.enc % Thomas Esser, Dec 2002. public domain % % Encoding for: % cmsy10 cmsy5 cmsy6 cmsy7 cmsy8 cmsy9 % /TeXbbad153fEncoding [ /minus /periodcentered /multiply /asteriskmath /divide /diamondmath /plusminus /minusplus /circleplus /circleminus /circlemultiply /circledivide /circledot /circlecopyrt /openbullet /bullet /equivasymptotic /equivalence /reflexsubset /reflexsuperset /lessequal /greaterequal /precedesequal /followsequal /similar /approxequal /propersubset /propersuperset /lessmuch /greatermuch /precedes /follows /arrowleft /arrowright /arrowup /arrowdown /arrowboth /arrownortheast /arrowsoutheast /similarequal /arrowdblleft /arrowdblright /arrowdblup /arrowdbldown /arrowdblboth /arrownorthwest /arrowsouthwest /proportional /prime /infinity /element /owner /triangle /triangleinv /negationslash /mapsto /universal /existential /logicalnot /emptyset /Rfractur /Ifractur /latticetop /perpendicular /aleph /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O /P /Q /R /S /T /U /V /W /X /Y /Z /union /intersection /unionmulti /logicaland /logicalor /turnstileleft /turnstileright /floorleft /floorright /ceilingleft /ceilingright /braceleft /braceright /angbracketleft /angbracketright /bar /bardbl /arrowbothv /arrowdblbothv /backslash /wreathproduct /radical /coproduct /nabla /integral /unionsq /intersectionsq /subsetsqequal /supersetsqequal /section /dagger /daggerdbl /paragraph /club /diamond /heart /spade /arrowleft /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /minus /periodcentered /multiply /asteriskmath /divide /diamondmath /plusminus /minusplus /circleplus /circleminus /.notdef /.notdef /circlemultiply /circledivide /circledot /circlecopyrt /openbullet /bullet /equivasymptotic /equivalence /reflexsubset /reflexsuperset /lessequal /greaterequal /precedesequal /followsequal /similar /approxequal /propersubset /propersuperset /lessmuch /greatermuch /precedes /follows /arrowleft /spade /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef ] def %%EndProcSet %%BeginProcSet: texnansi.enc % @psencodingfile{ % author = "Y&Y, Inc.", % version = "1.1", % date = "1 December 1996", % filename = "texnansi.enc", % email = "help@YandY.com", % address = "45 Walden Street // Concord, MA 01742, USA", % codetable = "ISO/ASCII", % checksum = "xx", % docstring = "Encoding for fonts in Adobe Type 1 format for use with TeX." % } % % The idea is to have all 228 characters normally included in Type 1 text % fonts (plus a few more) available for typesetting. This is effectively % the character set in Adobe Standard Encoding, ISO Latin 1, plus a few more. % % Character code assignments were made as follows: % % (1) The character layout largely matches `ASCII' in the 32 -- 126 range, % except for `circumflex' in 94 and `tilde' in 126, to match `TeX text' % (`asciicircumflex' and `asciitilde' appear in 158 and 142 instead). % % (2) The character layout matches `Windows ANSI' in almost all places, % except for `quoteright' in 39 and `quoteleft' in 96 to match ASCII % (`quotesingle' and `grave' appear in 129 and 18 instead). % % (3) The character layout matches `TeX typewriter' used by CM text fonts % in most places (except for discordant positions such as hungarumlaut % (instead of braceright), dotaccent (instead of underscore) etc. % % (4) Remaining characters are assigned arbitrarily to the `control character' % range (0 -- 31), avoiding 0, 9, 10 and 13 in case we meet dumb software % - similarly one should really avoid 127 and 128 if possible. % In addition, the 8 open slots in Windows ANSI between 128 and 159 are used. % % (5) Y&Y Lucida Bright includes some extra ligatures and such; ff, ffi, ffl, % and `dotlessj,' these are included 11 -- 15, and 17. % % (6) Hyphen appears both at 45 and 173 for compatibility with both ASCII % and Windows ANSI. % % (7) It doesn't really matter where ligatures appear (both real, such as ffi, % and pseudo such as ---) since these should not be accessed directly, only % via ligature information in the TFM file. % % SAMPLE USAGE (in `psfonts.map' file for DVIPS): % % lbr LucidaBright "TeXnANSIEncoding ReEncodeFont" } imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrow { % -12 -40 24 80 bbox begingate 1 0.80 0 -40 0 20 2 polygon 1.00 0 0 40 arrowhead endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 544 352 offsets 1.0000 inchscale 2.6000 setlinewidth 0.753 0.333 0.502 scb 240 1.00 192 224 192 192 512 192 672 320 672 352 384 352 6 polygon sce 0.490 0.651 0.980 scb 240 1.00 192 448 192 416 512 416 672 544 672 576 384 576 6 polygon sce 0 1.00 192 416 192 448 512 448 512 416 4 polygon 1 1.00 192 448 384 576 2 polygon 1 1.00 512 448 672 576 2 polygon 1 1.00 384 576 672 576 2 polygon 1 1.00 512 416 672 544 2 polygon 1 1.00 672 576 672 544 2 polygon 1 1.00 192 448 672 576 2 polygon 1 1.00 384 576 512 448 2 polygon 0 1.00 192 192 192 224 512 224 512 192 4 polygon 1 1.00 192 224 384 352 2 polygon 1 1.00 512 224 672 352 2 polygon 1 1.00 384 352 672 352 2 polygon 1 1.00 512 192 672 320 2 polygon 1 1.00 672 352 672 320 2 polygon 1 1.00 192 224 672 352 2 polygon 1 1.00 384 352 512 224 2 polygon 1 1.00 672 528 672 368 2 polygon 1 1.00 512 400 512 240 2 polygon 1 1.00 192 400 192 240 2 polygon 1 1.00 384 368 384 416 2 polygon (plane) {/Helvetica 1.000 cf} (metal1 ) {/Helvetica-Bold 1.000 cf} 4 20 0 704 560 label (plane) {/Helvetica 1.000 cf} (active ) {/Helvetica-Bold 1.000 cf} 4 20 0 704 336 label 1.00 75 640 240 arrow 1.00 75 656 480 arrow (: pcontact) {/Helvetica 1.000 cf} (drawn) {/Helvetica-Oblique 1.000 cf} 4 20 0 704 224 label (: pcontact/m1) {/Helvetica 1.000 cf} (automatically generated) {/Helvetica-Oblique 1.000 cf} 4 20 0 720 464 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF %%EndDocument @endspecial 0 1115 a(Figure)j(1:)38 b(A)28 b(dif)n(ferent)g(tile)g (type)f(is)h(used)g(to)g(represent)h(a)f(contact)g(on)g(each)h(plane)f (that)g(it)g(connects.)41 b(Here,)0 1236 y(a)32 b(contact)f(between)g (poly)g(on)g(the)g Fd(acti)o(v)o(e)h Fg(plane)f(and)g(metal1)g(on)g (the)g Fd(metal1)g Fg(plane)g(is)g(stored)g(as)h(tw)o(o)f(tile)0 1356 y(types.)38 b(One,)27 b Fd(pcontact)p Fg(,)j(is)c(speci\002ed)i (in)f(the)g(technology)f(\002le)i(as)f(residing)g(on)g(the)g Fd(acti)o(v)o(e)g Fg(plane;)h(the)f(other)0 1477 y(is)d (automatically-generated)g(for)h(the)g Fd(metal1)f Fg(plane.)0 1872 y Fi(8)143 b(Specifying)34 b(T)-11 b(ype-lists)0 2097 y Fg(In)31 b(se)n(v)o(eral)f(places)h(in)g(the)g(technology)f (\002le)h(you')o(ll)f(need)h(to)g(specify)g(groups)f(of)h(tile)f (types.)49 b(F)o(or)31 b(e)o(xample,)0 2217 y(in)25 b(the)h Fd(connect)h Fg(section)e(you')o(ll)g(specify)h(groups)f(of)h(tiles)f (that)g(are)h(mutually)e(connected.)34 b(These)26 b(are)g(called)0 2337 y Fh(type-lists)c Fg(and)h(there)g(are)h(se)n(v)o(eral)e(w)o(ays)h (to)f(specify)h(them.)30 b(The)23 b(simplest)e(form)i(for)g(a)g (type-list)f(is)g(a)i(comma-)0 2458 y(separated)h(list)f(of)h(tile)f (types,)g(for)h(e)o(xample)900 2690 y(poly)-6 b(,ndif)n(f,pcontact,ndc) 146 2922 y(The)25 b(null)f(list)g(\(no)h(tiles)f(at)g(all\))h(is)f (indicated)h(by)f(zero,)h(i.e.,)900 3155 y(0)146 3387 y(There)k(must)e(not)g(be)h(an)o(y)g(spaces)g(in)f(the)h(type-list.)39 b(T)-8 b(ype-lists)27 b(may)g(also)h(use)g(tildes)f(\(\223\230\224\))i (to)e(select)h(all)0 3507 y(tiles)c(b)n(ut)g(a)h(speci\002ed)g(set,)g (and)g(parentheses)f(for)h(grouping.)30 b(F)o(or)25 b(e)o(xample,)900 3740 y(\230\(pcontact,ndc\))146 3972 y(selects)d(all)h(tile)e(types)h (b)n(ut)g(pcontact)g(and)h(ndc.)30 b(When)22 b(a)h(contact)f(name)g (appears)h(in)f(a)h(type-list,)e(it)h(selects)0 4092 y Fh(all)k Fg(images)g(of)h(the)g(contact)f(unless)g(a)h(\223/\224)g (is)f(used)h(to)f(indicate)g(a)i(particular)e(one.)37 b(The)26 b(e)o(xample)g(abo)o(v)o(e)g(will)0 4213 y(not)36 b(select)g(an)o(y)f(of)i(the)e(images)h(of)g(pcontact)g(or)g(ndc.)65 b(Slashes)36 b(can)h(also)e(be)i(used)e(in)h(conjunction)f(with)0 4333 y(parentheses)25 b(and)f(tildes.)30 b(F)o(or)25 b(e)o(xample,)900 4566 y(\230\(pcontact,ndc\)/acti)n(v)o(e,metal1)146 4798 y(selects)34 b(all)g(of)g(the)f(tile)h(types)f(on)h(the)f(acti)n (v)o(e)g(plane)h(e)o(xcept)f(for)i(pcontact)e(and)h(ndc,)i(and)e(also)f (selects)0 4918 y(metal1.)d(T)m(ildes)22 b(ha)n(v)o(e)i(higher)f (operator)h(precedence)h(than)f(slashes,)f(and)h(commas)f(ha)n(v)o(e)g (lo)n(west)g(precedence)0 5038 y(of)i(all.)146 5159 y(A)h(special)g (notation)e(using)h(the)g(asterisk)g(\(\223*\224\))i(is)e(a)h(con)l(v)o (enient)e(w)o(ay)i(to)g(abbre)n(viate)f(the)g(common)g(situ-)0 5280 y(ation)e(where)h(a)g(rule)g(requires)g(the)f(inclusion)f(of)i(a)g (tile)f(type)h(and)f(also)h(all)f(contacts)h(that)f(de\002ne)h(that)f (tile)g(type)0 5400 y(as)i(one)g(of)g(their)f(residue)h(layers,)f(a)i (common)d(occurrence.)32 b(The)25 b(notation)1850 5649 y(\22611\226)p eop end %%Page: 12 12 TeXDict begin 12 11 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)900 84 y(*metal1)146 293 y(e)o(xpands)k(to)h(metal1)f(plus)g(all)h(of)g(the)g(contact)g (types)f(associated)g(with)h(metal1,)g(such)g(as)g(ndc,)g(pdc,)h(nsc,)0 413 y(m2c,)24 b(and)h(so)g(forth.)146 534 y(Note:)59 b(in)39 b(the)g(CIF)i(sections)d(of)i(the)f(technology)f(\002le,)43 b(only)38 b(simple)g(comma-separated)h(names)g(are)0 654 y(permitted;)24 b(tildes)g(and)i(parentheses)f(are)h(not)f (understood.)31 b(Ho)n(we)n(v)o(er)l(,)24 b(e)n(v)o(erywhere)h(else)g (in)g(the)g(technology)0 774 y(\002le)37 b(the)f(full)f(generality)h (can)h(be)f(used.)65 b(The)36 b(\223*\224)h(notation)e(for)h(inclusion) f(of)h(contact)g(residues)g(may)g(be)0 895 y(present)25 b(in)f(an)o(y)g(section.)0 1232 y Fi(9)143 b(Styles)35 b(section)0 1455 y Fg(Magic)c(can)h(be)g(run)f(on)g(se)n(v)o(eral)g (dif)n(ferent)g(types)g(of)h(graphical)f(displays.)50 b(Although)30 b(it)h(w)o(ould)g(ha)n(v)o(e)g(been)0 1576 y(possible)21 b(to)h(incorporate)g(display-speci\002c)g(information)f (into)g(the)h(technology)f(\002le,)j(a)e(dif)n(ferent)g(technology)0 1696 y(\002le)j(w)o(ould)e(ha)n(v)o(e)h(been)g(required)g(for)h(each)g (display)e(type.)30 b(Instead,)24 b(the)g(technology)f(\002le)h(gi)n(v) o(es)f(one)h(or)g(more)0 1816 y(display-independent)g Fh(styles)i Fg(for)g(each)h(type)f(that)g(is)g(to)f(be)i(displayed,)e (and)h(uses)g(a)h(per)n(-display-type)e(styles)0 1937 y(\002le)k(to)e(map)h(to)g(colors)g(and)g(stipplings)e(speci\002c)i(to) g(the)g(display)f(being)h(used.)40 b(The)29 b(styles)e(\002le)i(is)e (described)0 2057 y(in)d(Magic)h(Maintainer')-5 b(s)23 b(Manual)i(#3:)30 b(\223Styles)25 b(and)f(Colors\224,)h(so)g(we)g(will) f(not)g(describe)h(it)f(further)h(here.)146 2177 y(T)-8 b(able)25 b(6)g(sho)n(ws)e(part)i(of)f(the)h Fd(styles)f Fg(section)g(from)g(the)h(scmos)f(technology)f(\002le.)31 b(The)25 b(\002rst)g(line)f(speci\002es)0 2298 y(the)j(type)f(of)i (style)e(\002le)h(for)g(use)g(with)g(this)f(technology)-6 b(,)25 b(which)i(in)f(this)h(e)o(xample)f(is)g Fd(mos)p Fg(.)37 b(Each)27 b(subsequent)0 2418 y(line)g(consists)e(of)j(a)f (tile)g(type)g(and)g(a)g(style)g(number)f(\(an)i(inte)o(ger)e(between)h (1)h(and)f(63\).)37 b(The)27 b(style)g(number)g(is)0 2539 y(nothing)f(more)i(than)g(a)g(reference)h(between)f(the)g (technology)f(\002le)h(and)g(the)f(styles)g(\002le.)40 b(Notice)28 b(that)f(a)i(gi)n(v)o(en)0 2659 y(tile)24 b(type)g(can)h(ha)n(v)o(e)f(se)n(v)o(eral)g(styles)f(\(e.g.,)i (pcontact)f(uses)g(styles)f(#1,)h(#20,)g(and)h(#32\),)f(and)g(that)g(a) h(gi)n(v)o(en)e(style)0 2779 y(may)h(be)g(used)g(to)g(display)f(se)n(v) o(eral)g(dif)n(ferent)h(tiles)f(\(e.g.,)h(style)g(#2)g(is)f(used)h(in)g (ndif)n(f)f(and)i(ndcontact\).)30 b(If)24 b(a)h(tile)0 2900 y(type)f(should)g(not)g(be)h(displayed,)f(it)g(has)h(no)f(entry)h (in)g(the)f Fd(styles)g Fg(section.)146 3020 y(It)40 b(is)f(no)g(longer)g(necessary)h(to)f(ha)n(v)o(e)g(one)g(style)g(per)g (line,)k(a)d(restriction)e(of)i(format)f(27)g(and)g(earlier)-5 b(.)0 3141 y(Multiple)26 b(styles)g(for)i(a)g(tile)f(type)g(can)h(be)f (placed)h(on)f(the)g(same)g(line,)h(separated)g(by)f(spaces.)39 b(Styles)27 b(may)g(be)0 3261 y(speci\002ed)e(by)g(number)l(,)f(or)h (by)f(the)h(\223long)f(name\224)h(in)f(the)h(style)f(\002le.)0 3598 y Fi(10)143 b(Compose)34 b(section)0 3821 y Fg(The)29 b(semantics)e(of)i(Magic')-5 b(s)27 b(paint)h(operation)g(are)i (de\002ned)e(by)h(a)g(collection)e(of)i(rules)f(of)h(the)f(form,)h (\223gi)n(v)o(en)0 3942 y(material)k Fh(HA)-10 b(VE)33 b Fg(on)g(plane)h Fh(PLANE)p Fg(,)g(if)g(we)g(paint)f Fh(P)-9 b(AINT)p Fg(,)34 b(then)f(we)h(get)g Fh(Z)p Fg(\224,)g(plus)f (a)h(similar)e(set)i(of)f(rules)0 4062 y(for)f(the)f(erase)i (operation.)50 b(The)32 b(def)o(ault)f(paint)g(and)h(erase)g(rules)f (are)i(simple.)50 b(Assume)30 b(that)h(we)h(are)h(gi)n(v)o(en)0 4182 y(material)24 b Fh(HA)-10 b(VE)24 b Fg(on)h(plane)g Fh(PLANE)p Fg(,)g(and)g(are)g(painting)f(or)h(erasing)f(material)h Fh(P)-9 b(AINT)p Fg(.)120 4391 y(1.)49 b Fh(Y)-9 b(ou)25 b(g)o(et)f(what)h(you)g(paint.)244 4511 y Fg(If)c(the)g(home)f(plane)h (of)g Fh(P)-9 b(AINT)22 b Fg(is)e Fh(PLANE)p Fg(,)i(or)f Fh(P)-9 b(AINT)21 b Fg(is)g(space,)h(you)e(get)h Fh(P)-9 b(AINT)p Fg(;)22 b(otherwise,)f(nothing)244 4632 y(changes)k(and)f(you) h(get)f Fh(HA)-10 b(VE)p Fg(.)120 4830 y(2.)49 b Fh(Y)-9 b(ou)25 b(can)f(er)o(ase)h(all)f(or)g(nothing)o(.)244 4951 y Fg(Erasing)g(space)h(or)g Fh(P)-9 b(AINT)26 b Fg(from)e Fh(P)-9 b(AINT)26 b Fg(will)e(gi)n(v)o(e)g(space;)g(erasing)h (an)o(ything)e(else)i(has)g(no)f(ef)n(fect.)146 5159 y(These)i(rules)g(apply)g(for)g(contacts)g(as)g(well.)35 b(P)o(ainting)24 b(the)i(base)h(type)e(of)i(a)f(contact)g(paints)f(the) h(base)g(type)0 5280 y(on)21 b(its)f(home)h(plane,)h(and)f(each)h (image)f(type)f(on)h(its)g(home)f(plane.)30 b(Erasing)21 b(the)g(base)g(type)g(of)g(a)h(contact)f(erases)0 5400 y(both)j(the)h(base)g(type)f(and)h(the)g(image)f(types.)1850 5649 y(\22612\226)p eop end %%Page: 13 13 TeXDict begin 13 12 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)p 1525 3 850 4 v 1523 124 4 121 v 1575 88 a Fd(styles)p 2373 124 V 1523 244 V 1575 208 a Fg(styles)p 2373 244 V 1523 364 V 1575 328 a(styletype)f(mos)p 2373 364 V 1523 485 V 1575 449 a(poly)472 b(1)p 2373 485 V 1523 605 V 1575 569 a(ndif)n(f)458 b(2)p 2373 605 V 1523 726 V 1575 689 a(pdif)n(f)g(4)p 2373 726 V 1523 846 V 1575 810 a(nfet)495 b(6)p 2373 846 V 1523 966 V 1575 930 a(nfet)g(7)p 2373 966 V 1523 1087 V 1575 1051 a(pfet)g(8)p 2373 1087 V 1523 1207 V 1575 1171 a(pfet)g(9)p 2373 1207 V 1523 1328 V 1575 1291 a(metal1)378 b(20)p 2373 1328 V 1523 1448 V 1575 1412 a(metal2)g(21)p 2373 1448 V 1523 1568 V 1575 1532 a(pcontact)312 b(1)p 2373 1568 V 1523 1689 V 1575 1653 a(pcontact)g(20)p 2373 1689 V 1523 1809 V 1575 1773 a(pcontact)g(32)p 2373 1809 V 1523 1929 V 1575 1893 a(ndcontact)262 b(2)p 2373 1929 V 1523 2050 V 1575 2014 a(ndcontact)g(20)p 2373 2050 V 1523 2170 V 1575 2134 a(ndcontact)g(32)p 2373 2170 V 1523 2291 V 1575 2254 a(pdcontact)g(4)p 2373 2291 V 1523 2411 V 1575 2375 a(pdcontact)g(20)p 2373 2411 V 1523 2531 V 1575 2495 a(pdcontact)g(32)p 2373 2531 V 1523 2652 V 1575 2616 a(m2contact)234 b(20)p 2373 2652 V 1523 2772 V 1575 2736 a(m2contact)g(21)p 2373 2772 V 1523 2892 V 1575 2856 a(m2contact)g(33)p 2373 2892 V 1523 3013 V 1575 2977 a Fd(end)p 2373 3013 V 1525 3016 850 4 v 1285 3175 a Fg(T)-8 b(able)25 b(6:)30 b(P)o(art)25 b(of)g(the)g Fd(styles)f Fg(section)146 3547 y(It)31 b(is)f(sometimes)f(desirable)h(for)h(certain)g(tile)f(types)g(to)g (beha)n(v)o(e)h(as)f(though)g(the)o(y)g(were)h(\223composed\224)f(of)0 3668 y(other)l(,)41 b(more)d(fundamental)f(ones.)70 b(F)o(or)37 b(e)o(xample,)k(painting)36 b(poly)i(o)o(v)o(er)f(ndif)n(fusion)f(in)h (scmos)g(produces)0 3788 y(ntransistor)l(,)31 b(instead)e(of)i(ndif)n (fusion.)46 b(Also,)31 b(painting)e(either)i(poly)e(or)i(ndif)n(fusion) e(o)o(v)o(er)g(ntransistor)h(lea)n(v)o(es)0 3908 y(ntransistor)l(,)40 b(erasing)d(poly)g(from)g(ntransistor)g(lea)n(v)o(es)g(ndif)n(fusion,)i (and)f(erasing)f(ndif)n(fusion)f(lea)n(v)o(es)h(poly)-6 b(.)0 4029 y(The)22 b(semantics)g(for)h(ntransistor)e(are)i(a)g(result) f(of)g(the)g(follo)n(wing)f(rule)h(in)g(the)h Fd(compose)f Fg(section)g(of)h(the)f(scmos)0 4149 y(technology)i(\002le:)900 4416 y Fd(compose)h Fg(ntransistor)f(poly)g(ndif)n(f)146 4678 y(Sometimes,)d(not)e(all)i(of)f(the)h(\223component\224)e(layers)i (of)g(a)f(type)h(are)g(layers)f(kno)n(wn)g(to)g(magic.)29 b(As)20 b(an)h(e)o(xam-)0 4798 y(ple,)30 b(in)e(the)h Fd(nmos)g Fg(technology)-6 b(,)28 b(there)h(are)g(tw)o(o)g(types)f(of)h (transistors:)37 b Fd(enhancement-fet)32 b Fg(and)d Fd(depletion-)0 4918 y(fet)p Fg(.)40 b(Although)26 b(both)g(contain)h(polysilicon)f (and)h(dif)n(fusion,)g(depletion-fet)g(can)h(be)f(thought)g(of)g(as)h (also)f(con-)0 5039 y(taining)21 b(implant,)h(which)g(is)g(not)g(a)h (tile)f(type.)30 b(So)23 b(while)f(we)h(can')n(t)g(construct)f (depletion-fet)f(by)i(painting)e(poly)0 5159 y(and)26 b(then)f(dif)n(fusion,)f(we')-5 b(d)26 b(still)f(lik)o(e)g(it)g(to)g (beha)n(v)o(e)h(as)g(though)e(it)i(contained)f(both)g(materials.)32 b(P)o(ainting)25 b(poly)0 5280 y(or)k(dif)n(fusion)e(o)o(v)o(er)h(a)h (depletion-fet)f(should)g(not)g(change)h(it,)h(and)f(erasing)f(either)h (poly)f(or)h(dif)n(fusion)e(should)0 5400 y(gi)n(v)o(e)c(the)i(other)-5 b(.)30 b(These)25 b(semantics)f(are)h(the)g(result)f(of)h(the)g(follo)n (wing)e(rule:)1850 5649 y(\22613\226)p eop end %%Page: 14 14 TeXDict begin 14 13 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)900 84 y Fd(decompose)i Fg(dfet)f(poly)f(dif)n(f)146 315 y(The)h(general)g(syntax)f(of)h(both)f (types)g(of)h(composition)e(rules,)h Fd(compose)h Fg(and)g Fd(decompose)p Fg(,)h(is:)900 546 y Fd(compose)100 b Fh(type)50 b(a1)24 b(b1)50 b(a2)24 b(b2)50 b(.)15 b(.)g(.)900 666 y Fd(decompose)26 b Fh(type)50 b(a1)24 b(b1)50 b(a2)24 b(b2)49 b(.)15 b(.)g(.)146 897 y Fg(The)31 b(idea)h(is)e(that)h(each)h (of)f(the)g(pairs)g Fh(a1)g(b1)p Fg(,)h Fh(a2)f(b2)p Fg(,)h(etc)g(comprise)e Fh(type)p Fg(.)50 b(In)31 b(the)g(case)h(of)f (a)h Fd(compose)0 1017 y Fg(rule,)24 b(painting)e(an)o(y)h Fh(a)g Fg(atop)g(its)g(corresponding)f Fh(b)h Fg(will)g(gi)n(v)o(e)f Fh(type)p Fg(,)h(as)h(well)f(as)g(vice-v)o(ersa.)31 b(In)23 b(both)g Fd(compose)0 1138 y Fg(and)h Fd(decompose)i Fg(rules,)e(erasing)h Fh(a)f Fg(from)g Fh(type)h Fg(gi)n(v)o(es)e Fh(b)p Fg(,)h(erasing)h Fh(b)f Fg(from)g Fh(type)h Fg(gi)n(v)o(es)e Fh(a)p Fg(,)h(and)h(painting)e(either)0 1258 y Fh(a)i Fg(or)g Fh(b)f Fg(o)o(v)o(er)g Fh(type)h Fg(lea)n(v)o(es)g Fh(type)f Fg(unchanged.)p 1052 1401 1797 4 v 1050 1521 4 121 v 1102 1485 a Fd(compose)p 1050 1641 V 1102 1605 a Fg(compose)110 b(nfet)350 b(poly)143 b(ndif)n(f)p 2846 1641 V 1050 1762 V 1102 1726 a(compose)110 b(pfet)350 b(poly)143 b(pdif)n(f)p 2846 1762 V 1050 1882 V 1102 1846 a(paint)265 b(pwell)283 b(nwell)99 b(nwell)p 2846 1882 V 1050 2003 V 1102 1966 a(paint)265 b(nwell)283 b(pwell)99 b(pwell)p 2846 2003 V 1050 2123 V 1102 2087 a(paint)265 b(pdc/acti)n(v)o(e)98 b(pwell)h(ndc/acti)n(v)o(e)p 2846 2123 V 1050 2243 V 1102 2207 a(paint)265 b(pdc/m1)205 b(pwell)99 b(ndc/m1)p 2846 2243 V 1050 2364 V 1102 2328 a(paint)265 b(pfet)350 b(pwell)99 b(nfet)p 2846 2364 V 1050 2484 V 1102 2448 a(paint)265 b(pdif)n(f)313 b(pwell)99 b(ndif)n(f)p 2846 2484 V 1050 2605 V 1102 2568 a(paint)265 b(nsd)366 b(pwell)99 b(psd)p 2846 2605 V 1050 2725 V 1102 2689 a(paint)265 b(nsc/acti)n(v)o(e)109 b(pwell)99 b(psc/acti)n(v)o(e)p 2846 2725 V 1050 2845 V 1102 2809 a(paint)265 b(nsc/m1)216 b(pwell)99 b(psc/m1)p 2846 2845 V 1050 2966 V 1102 2930 a(paint)265 b(ndc/acti)n(v)o(e)98 b(nwell)h(pdc/acti)n(v)o(e)p 2846 2966 V 1050 3086 V 1102 3050 a(paint)265 b(ndc/m1)205 b(nwell)99 b(pdc/m1)p 2846 3086 V 1050 3206 V 1102 3170 a(paint)265 b(nfet)350 b(nwell)99 b(pfet)p 2846 3206 V 1050 3327 V 1102 3291 a(paint)265 b(ndif)n(f)313 b(nwell)99 b(pdif)n(f)p 2846 3327 V 1050 3447 V 1102 3411 a(paint)265 b(psd)366 b(nwell)99 b(nsd)p 2846 3447 V 1050 3568 V 1102 3531 a(paint)265 b(psc/acti)n(v)o(e)109 b(nwell)99 b(nsc/acti)n(v)o(e)p 2846 3568 V 1050 3688 V 1102 3652 a(paint)265 b(psc/m1)216 b(nwell)99 b(nsc/m1)p 2846 3688 V 1050 3808 V 1102 3772 a Fd(end)p 2846 3808 V 1052 3812 1797 4 v 1424 3972 a Fg(T)-8 b(able)25 b(7:)30 b Fd(Compose)25 b Fg(section)146 4316 y(Contacts)g(are)h(implicitly)c(composed)i(of)h(their)g(component) f(types,)g(so)g(the)h(result)g(obtained)f(when)h(paint-)0 4437 y(ing)32 b(a)g(type)g Fh(P)-9 b(AINT)33 b Fg(o)o(v)o(er)f(a)g (contact)g(type)g Fh(CONT)-5 b(A)m(CT)34 b Fg(will)e(by)g(def)o(ault)g (depend)g(only)f(on)h(the)g(component)0 4557 y(types)23 b(of)h Fh(CONT)-5 b(A)m(CT)p Fg(.)26 b(If)f(painting)d Fh(P)-9 b(AINT)25 b Fg(doesn')n(t)f(af)n(fect)g(the)g(component)f (types)g(of)h(the)g(contact,)g(then)f(it)h(is)0 4677 y(considered)k(not)f(to)h(af)n(fect)h(the)f(contact)g(itself)f(either) -5 b(.)41 b(If)28 b(painting)f Fh(P)-9 b(AINT)29 b Fg(does)f(af)n(fect) h(an)o(y)e(of)i(the)f(compo-)0 4798 y(nent)23 b(types,)g(then)h(the)f (result)g(is)h(as)f(though)g(the)g(contact)h(had)f(been)h(replaced)g (by)g(its)e(component)h(types)g(in)g(the)0 4918 y(layout)h(before)h (type)g Fh(P)-9 b(AINT)25 b Fg(w)o(as)g(painted.)30 b(Similar)25 b(rules)f(hold)g(for)h(erasing.)146 5039 y(A)c(pcontact)f(has)g (component)f(types)h(poly)g(and)g(metal1.)29 b(Since)21 b(painting)e(poly)h(doesn')n(t)g(af)n(fect)g(either)h(poly)0 5159 y(or)i(metal1,)g(it)g(doesn')n(t)g(af)n(fect)h(a)g(pcontact)f (either)-5 b(.)29 b(P)o(ainting)23 b(ndif)n(fusion)e(does)i(af)n(fect)h (poly:)29 b(it)23 b(turns)g(it)f(into)h(an)0 5280 y(ntransistor)-5 b(.)46 b(Hence,)32 b(painting)d(ndif)n(fusion)f(o)o(v)o(er)i(a)g (pcontact)g(breaks)h(up)f(the)g(contact,)i(lea)n(ving)d(ntransistor)0 5400 y(on)c(the)f(acti)n(v)o(e)g(plane)h(and)f(metal1)h(on)f(the)h (metal1)f(plane.)1850 5649 y(\22614\226)p eop end %%Page: 15 15 TeXDict begin 15 14 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)146 68 y(The)h Fd(compose)f Fg(and)h Fd(decompose)g Fg(rules)f(are)h(normally)e(suf)n (\002cient)h(to)g(specify)g(the)g(desired)h(semantics)e(of)0 188 y(painting)f(or)i(erasing.)30 b(In)25 b(unusual)e(cases,)i(ho)n(we) n(v)o(er)l(,)e(it)h(may)g(be)h(necessary)f(to)g(pro)o(vide)g(Magic)g (with)g(e)o(xplicit)0 309 y Fd(paint)j Fg(or)f Fd(erase)h Fg(rules.)35 b(F)o(or)26 b(e)o(xample,)g(to)g(specify)g(that)g (painting)f(pwell)g(o)o(v)o(er)h(pdif)n(fusion)e(switches)i(its)f(type) 0 429 y(to)f(ndif)n(fusion,)f(the)i(technology)f(\002le)h(contains)f (the)g(rule:)900 658 y Fd(paint)h Fg(pdif)n(fusion)e(pwell)i(ndif)n (fusion)146 887 y(This)e(rule)g(could)g(not)f(ha)n(v)o(e)h(been)h (written)f(as)g(a)g Fd(decompose)i Fg(rule;)e(erasing)g(ndif)n(fusion)f (from)h(pwell)f(does)0 1007 y(not)27 b(yield)h(pdif)n(fusion,)e(nor)i (does)g(erasing)f(pdif)n(fusion)f(from)i(ndif)n(fusion)e(yield)h (pwell.)40 b(The)28 b(general)g(syntax)0 1128 y(for)d(these)g(e)o (xplicit)e(rules)i(is:)900 1357 y Fd(paint)g Fh(have)g(t)g(r)l(esult)f Fg([)p Fh(p)p Fg(])900 1477 y Fd(erase)h Fh(have)g(t)g(r)l(esult)f Fg([)p Fh(p)p Fg(])146 1706 y(Here,)f Fh(have)e Fg(is)f(the)h(type)f (already)h(present,)h(on)e(plane)h Fh(p)g Fg(if)g(it)f(is)g (speci\002ed;)j(otherwise,)e(on)f(the)h(home)f(plane)0 1826 y(of)26 b Fh(have)p Fg(.)32 b(T)-8 b(ype)26 b Fh(t)f Fg(is)g(being)g(painted)g(or)h(erased,)g(and)f(the)g(result)g(is)g (type)h Fh(r)l(esult)p Fg(.)32 b(T)-8 b(able)25 b(7)h(gi)n(v)o(es)d (the)j Fd(compose)0 1947 y Fg(section)e(for)h(scmos.)146 2067 y(It')-5 b(s)28 b(easiest)f(to)h(think)e(of)i(the)g(paint)f(and)h (erase)h(rules)e(as)h(being)g(b)n(uilt)e(up)i(in)f(four)h(passes.)40 b(The)27 b(\002rst)h(pass)0 2188 y(generates)22 b(the)g(def)o(ault)f (rules)h(for)g(all)g(non-contact)f(types,)h(and)f(the)h(second)g(pass)f (replaces)h(these)g(as)g(speci\002ed)0 2308 y(by)27 b(the)g Fd(compose)p Fg(,)h Fd(decompose)p Fg(,)g(etc.)38 b(rules,)28 b(also)e(for)i(non-contact)e(types.)38 b(At)26 b(this)h(point,)f(the)h (beha)n(vior)g(of)0 2428 y(the)k(component)e(types)h(of)h(contacts)f (has)h(been)g(completely)f(determined,)h(so)f(the)h(third)f(pass)g(can) i(generate)0 2549 y(the)e(def)o(ault)g(rules)g(for)g(all)g(contact)g (types,)h(and)f(the)g(fourth)g(pass)g(can)g(modify)f(these)h(as)h(per)f (an)o(y)g Fd(compose)p Fg(,)0 2669 y(etc.)h(rules)25 b(for)g(contacts.)0 3009 y Fi(11)143 b(Connect)34 b(section)0 3233 y Fg(F)o(or)j(circuit)f(e)o(xtraction,)j(routing,)g(and)e(some)f (of)h(the)g(net-list)f(operations,)j(Magic)d(needs)h(to)f(kno)n(w)g (what)0 3353 y(types)27 b(are)i(electrically)e(connected.)40 b(Magic')-5 b(s)27 b(model)g(of)h(electrical)g(connecti)n(vity)e(used)h (is)h(based)f(on)h(signal)0 3474 y(propagation.)45 b(T)-8 b(w)o(o)30 b(types)g(should)f(be)h(mark)o(ed)g(as)h(connected)f(if)g(a) g(signal)g(will)f Fh(always)h Fg(pass)g(between)g(the)0 3594 y(tw)o(o)j(types,)i(in)f(either)f(direction.)57 b(F)o(or)33 b(the)h(most)e(part,)k(this)d(will)g(mean)g(that)g(all)h (non-space)f(types)g(within)0 3714 y(a)f(plane)g(should)f(be)i(mark)o (ed)f(as)g(connected.)52 b(The)32 b(e)o(xceptions)f(to)h(this)f(rule)h (are)h(de)n(vices)e(\(transistors\).)52 b(A)0 3835 y(transistor)28 b(should)g(be)h(considered)g(electrically)g(connected)g(to)g(adjacent)g (polysilicon,)f(b)n(ut)h(not)f(to)h(adjacent)0 3955 y(dif)n(fusion.)42 b(This)29 b(models)f(the)h(f)o(act)g(that)g(polysilicon)e(connects)i (to)g(the)g(gate)g(of)g(the)g(transistor)l(,)g(b)n(ut)g(that)f(the)0 4076 y(transistor)21 b(acts)h(as)g(a)g(switch)f(between)h(the)g(dif)n (fusion)e(areas)j(on)f(either)g(side)f(of)h(the)g(channel)g(of)g(the)g (transistor)-5 b(.)146 4196 y(The)28 b(lines)e(in)h(the)g Fd(connect)i Fg(section)e(of)g(a)h(technology)e(\002le,)i(as)f(sho)n (wn)f(in)h(T)-8 b(able)27 b(8,)h(each)g(contain)e(a)i(pair)0 4316 y(of)23 b(type-lists)f(in)h(the)g(format)g(described)g(in)f (Section)i(8.)30 b(Each)23 b(type)g(in)g(the)g(\002rst)g(list)f (connects)h(to)g(each)h(type)e(in)0 4437 y(the)i(second)h(list.)k(This) 24 b(does)h(not)f(imply)f(that)h(the)g(types)g(in)h(the)f(\002rst)h (list)e(are)j(themselv)o(es)d(connected)h(to)g(each)0 4557 y(other)l(,)h(or)f(that)h(the)f(types)h(in)f(the)h(second)f(list)g (are)i(connected)e(to)h(each)g(other)-5 b(.)146 4678 y(Because)31 b(connecti)n(vity)e(is)g(a)i(symmetric)e(relationship,)g (only)h(one)g(of)g(the)g(tw)o(o)f(possible)g(orders)h(of)h(tw)o(o)0 4798 y(tile)20 b(types)g(need)h(be)f(speci\002ed.)30 b(T)m(iles)19 b(of)i(the)f(same)g(type)h(are)g(al)o(w)o(ays)f (considered)g(to)g(be)h(connected.)29 b(Contacts)0 4918 y(are)i(treated)g(specially;)h(the)o(y)d(should)g(be)i(speci\002ed)f (as)h(connecting)f(to)f(material)h(in)g(all)g(planes)g(spanned)g(by)0 5039 y(the)e(contact.)40 b(F)o(or)28 b(e)o(xample,)g(pcontact)f(is)h (sho)n(wn)f(as)h(connecting)f(to)g(se)n(v)o(eral)h(types)f(in)h(the)f (acti)n(v)o(e)g(plane,)i(as)0 5159 y(well)22 b(as)g(se)n(v)o(eral)g (types)g(in)g(the)g(metal1)g(plane.)29 b(The)23 b(connecti)n(vity)d(of) j(a)f(contact)h(should)e(usually)g(be)i(that)e(of)i(its)0 5280 y(component)29 b(types,)j(so)e(pcontact)g(should)f(connect)h(to)h (e)n(v)o(erything)d(connected)j(to)f(poly)-6 b(,)30 b(and)h(to)f(e)n(v) o(erything)0 5400 y(connected)25 b(to)f(metal1.)1850 5649 y(\22615\226)p eop end %%Page: 16 16 TeXDict begin 16 15 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)p 225 3 3451 4 v 223 124 4 121 v 274 88 a Fd(connect)p 3674 124 V 223 244 V 274 208 a Fg(#de\002ne)i(allMetal2)d(m2,m2c/m2,pad/m2)p 3674 244 V 223 364 V 274 328 a(#de\002ne)j(allMetal1)d (m1,m2c/m1,pc/m1,ndc/m1,pdc/m1,ppcont/)o(m1,n)o(ncont/m)o(1,pad/)o(m1)p 3674 364 V 223 485 V 274 449 a(#de\002ne)j(allPoly)e(poly)-6 b(,pc/a,nfet,pfet)p 3674 485 V 223 605 V 274 569 a(allMetal2)1071 b(allMetal2)p 3674 605 V 223 726 V 274 689 a(allMetal1)g(allMetal1)p 3674 726 V 223 846 V 274 810 a(allPoly)1171 b(allPoly)p 3674 846 V 223 966 V 274 930 a(ndif)n(f)1262 b(ndc)p 3674 966 V 223 1087 V 274 1051 a(pdif)n(f)g(pdc)p 3674 1087 V 223 1207 V 274 1171 a(nwell,nnc,nsd)899 b(nwell,nnc,nsd)p 3674 1207 V 223 1328 V 274 1291 a(pwell,ppc,psd)g(pwell,ppc,psd)p 3674 1328 V 223 1448 V 274 1412 a(nnc)1310 b(pdc)p 3674 1448 V 223 1568 V 274 1532 a(ppc)g(ndc)p 3674 1568 V 223 1689 V 274 1653 a Fd(end)p 3674 1689 V 225 1692 3451 4 v 1443 1852 a Fg(T)-8 b(able)25 b(8:)30 b Fd(Connect)d Fg(section)0 2244 y Fi(12)143 b(Cif)l(output)34 b(section)0 2487 y Fg(The)25 b(layers)g(stored)g(by)g(Magic)g(do)g(not)f(al)o(w)o (ays)h(correspond)g(to)g(physical)f(mask)h(layers.)31 b(F)o(or)26 b(e)o(xample,)e(there)0 2607 y(is)35 b(no)g(physical)g (layer)h(corresponding)e(to)h(\(the)h(scmos)f(technology)f(\002le)i (layer\))g(ntransistor;)k(instead,)d(the)0 2727 y(actual)31 b(circuit)g(must)f(be)h(b)n(uilt)f(up)h(by)g(o)o(v)o(erlapping)e(poly)i (and)g(dif)n(fusion)e(o)o(v)o(er)i(pwell.)49 b(When)31 b(writing)f(CIF)0 2848 y(\(Caltech)k(Intermediate)f(F)o(orm\))f(or)i (Calma)f(GDS-II)h(\002les,)i(Magic)c(generates)i(the)f(actual)g (geometries)g(that)0 2968 y(will)24 b(appear)h(on)g(the)f(masks)g(used) h(to)f(f)o(abricate)h(the)g(circuit.)30 b(The)25 b Fd(cif)n(output)h Fg(section)e(of)h(the)f(technology)g(\002le)0 3088 y(describes)h(ho)n (w)f(to)g(generate)h(mask)g(layers)f(from)h(Magic')-5 b(s)24 b(abstract)h(layers.)0 3441 y Ff(12.1)119 b(CIF)30 b(and)g(GDS)h(styles)0 3647 y Fg(From)j(the)f(1990')-5 b(s,)35 b(the)e(CIF)i(format)f(has)f(lar)n(gely)h(been)g(replaced)g(by) g(the)f(GDS)h(format.)57 b(Ho)n(we)n(v)o(er)l(,)35 b(the)o(y)0 3767 y(describe)c(the)h(same)f(layout)f(geometry)-6 b(,)32 b(and)g(the)f(formats)g(are)h(similar)e(enough)h(that)g(magic)g(mak)o (es)g(use)g(of)0 3888 y(the)j(CIF)g(generation)g(code)g(as)g(the)f (basis)g(for)h(the)g(GDS)g(write)g(routines.)56 b(The)34 b(technology)f(\002le)h(also)f(uses)0 4008 y(CIF)28 b(layer)e (declarations)g(as)h(the)f(basis)g(for)h(GDS)f(output.)35 b(So)26 b(e)n(v)o(en)g(a)h(technology)e(\002le)i(that)f(only)g(e)o (xpects)f(to)0 4128 y(generate)i(GDS)g(output)e(needs)h(a)h(\223)p Fd(cif)n(output)p Fg(\224)h(section)e(declaring)g(CIF)h(layer)g(names.) 35 b(If)27 b(only)f(GDS)g(output)0 4249 y(is)d(required,)g(these)h (names)e(may)h(be)h(longer)f(and)g(therefore)h(more)f(descripti)n(v)o (e)f(than)h(allo)n(wed)f(by)h(CIF)h(format)0 4369 y(syntax.)146 4498 y(The)31 b(technology)e(\002le)i(can)g(contain)f(se)n(v)o(eral)g (dif)n(ferent)g(speci\002cations)g(of)g(ho)n(w)g(to)g(generate)h(CIF)-8 b(.)32 b(Each)0 4619 y(of)24 b(these)f(is)g(called)h(a)g(CIF)g Fh(style)p Fg(.)30 b(Dif)n(ferent)24 b(styles)e(may)h(be)h(used)f(for)h (f)o(abrication)f(at)h(dif)n(ferent)f(feature)h(sizes,)0 4739 y(or)k(for)f(totally)f(dif)n(ferent)h(purposes.)38 b(F)o(or)28 b(e)o(xample,)f(some)g(of)g(the)g(Magic)g(technology)g (\002les)g(contain)g(a)h(style)0 4860 y(\223plot\224)20 b(that)f(generates)h(CIF)i(pseudo-layers)d(that)h(ha)n(v)o(e)f(e)o (xactly)h(the)g(same)f(shapes)h(as)g(the)g(Magic)g(layers.)29 b(This)0 4980 y(style)c(is)g(used)h(for)g(generating)f(plots)g(that)g (look)g(just)g(lik)o(e)g(what)g(appears)h(on)g(the)f(color)h(display;)f (it)g(mak)o(es)g(no)0 5100 y(sense)g(for)g(f)o(abrication.)30 b(Lines)24 b(of)h(the)g(form)900 5400 y Fd(style)g Fh(name)1850 5649 y Fg(\22616\226)p eop end %%Page: 17 17 TeXDict begin 17 16 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)p 1036 3 1829 4 v 1034 124 4 121 v 1085 88 a Fd(cif)n(output)p 2863 124 V 1034 244 V 1085 208 a Fg(style)g(lambda=1.0\(gen\))p 2863 244 V 1034 364 V 1385 328 a(scalef)o(actor)h(100)p 2863 364 V 1034 485 V 1385 449 a(layer)f(CWN)h(nwell)p 2863 485 V 1034 605 V 1685 569 a(bloat-or)f(pdif)n(f,pdc,pfet)e(*)i (600)p 2863 605 V 1034 726 V 1685 689 a(bloat-or)g(nsc,nnd)f(*)h(300)p 2863 726 V 1034 846 V 1685 810 a(gro)n(w)g(300)p 2863 846 V 1034 966 V 1685 930 a(shrink)f(300)p 2863 966 V 1034 1087 V 1685 1051 a(gds)h(42)f(1)p 2863 1087 V 1034 1207 V 1385 1171 a(layer)h(CWP)h(pwell)p 2863 1207 V 1034 1328 V 1685 1291 a(bloat-or)f(ndif)n(f,ndc,nfet)e(*)i(600)p 2863 1328 V 1034 1448 V 1685 1412 a(bloat-or)g(psc,ppd)f(*)h(300)p 2863 1448 V 1034 1568 V 1685 1532 a(gro)n(w)g(300)p 2863 1568 V 1034 1689 V 1685 1653 a(shrink)f(300)p 2863 1689 V 1034 1809 V 1685 1773 a(gds)h(41)f(1)p 2863 1809 V 1034 1929 V 1385 1893 a(layer)h(CMS)h(allMetal2)p 2863 1929 V 1034 2050 V 1685 2014 a(labels)f(m2)p 2863 2050 V 1034 2170 V 1685 2134 a(gds)g(51)f(1)p 2863 2170 V 1034 2291 V 1385 2254 a(layer)h(CAA)h(allDif)n(f)p 2863 2291 V 1034 2411 V 1685 2375 a(labels)f(ndif)n(f,pdif)n(f)p 2863 2411 V 1034 2531 V 1685 2495 a(gds)g(43)f(1)p 2863 2531 V 1034 2652 V 1385 2616 a(layer)h(CCA)h(ndc,pdc)p 2863 2652 V 1034 2772 V 1685 2736 a(squares)f(200)p 2863 2772 V 1034 2892 V 1685 2856 a(gds)g(48)f(1)p 2863 2892 V 1034 3013 V 1385 2977 a(layer)h(CCA)h(nncont,ppcont)p 2863 3013 V 1034 3133 V 1685 3097 a(squares)f(200)p 2863 3133 V 1034 3254 V 1685 3218 a(gds)g(48)f(1)p 2863 3254 V 1034 3374 V 1385 3338 a(layer)h(CCP)i(pc)p 2863 3374 V 1034 3494 V 1685 3458 a(squares)e(200)p 2863 3494 V 1034 3615 V 1685 3579 a(gds)g(47)f(1)p 2863 3615 V 1034 3735 V 1085 3699 a Fd(end)p 2863 3735 V 1036 3738 1829 4 v 567 3898 a Fg(T)-8 b(able)25 b(9:)30 b(P)o(art)25 b(of)g(the)f Fd(cif)n(output)i Fg(section)e(for)h(style)g (lambda=1.0\(gen\))f(only)-6 b(.)146 4245 y(are)33 b(used)f(to)g(end)f (the)h(description)f(of)h(the)g(pre)n(vious)f(style)g(and)h(start)g (the)g(description)f(of)h(a)g(ne)n(w)g(style.)0 4366 y(The)22 b(Magic)g(command)f Fd(:cif)i(ostyle)e Fh(name)h Fg(is)g(typed)g(by)f(users)h(to)g(change)g(the)g(current)h(style)e (used)h(for)g(output.)0 4486 y(The)k(\002rst)g(style)g(in)f(the)h (technology)f(\002le)i(is)e(used)h(by)g(def)o(ault)g(for)g(CIF)h (output)e(if)h(the)g(designer)g(doesn')n(t)g(issue)0 4606 y(a)e Fd(:cif)g(style)g Fg(command.)29 b(If)c(the)f(\002rst)g (line)f(of)h(the)g Fd(cif)n(output)h Fg(section)e(isn')n(t)g(a)h Fd(style)g Fg(line,)f(then)h(Magic)f(uses)h(an)0 4727 y(initial)f(style)i(name)f(of)h Fd(default)p Fg(.)0 5017 y Ff(12.2)119 b(Scaling)0 5205 y Fg(Each)25 b(style)f(must)g(contain)g (a)h(line)g(of)f(the)h(form)900 5400 y Fd(scalefactor)g Fh(scale)g Fg([)p Fd(nanometers)p Fe(j)p Fd(angstr)n(oms)p Fg(])1850 5649 y(\22617\226)p eop end %%Page: 18 18 TeXDict begin 18 17 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)146 68 y(that)29 b(tells)f(ho)n(w)h(to)g(scale)g(Magic)g(coordinates)g(into)f(CIF)i (coordinates.)44 b(The)29 b(ar)n(gument)g Fh(scale)g Fg(indicates)0 189 y(ho)n(w)38 b(man)o(y)g(hundredths)g(of)h(a)h (micron)e(correspond)h(to)g(one)g(Magic)g(unit.)72 b Fh(scale)39 b Fg(may)g(be)g(an)o(y)g(number)l(,)0 309 y(including)c(decimals.)65 b(Ho)n(we)n(v)o(er)l(,)39 b(all)d(units)f(in)i(the)f(style)g(description)f(must)h(be)g(inte)o (ger)-5 b(.)65 b(Because)38 b(deep)0 429 y(submicron)20 b(processes)i(may)f(require)h(CIF)h(operations)e(in)g(units)g(of)g (less)h(than)f(one)h(centimicron,)f(the)g(optional)0 550 y(parameter)i Fd(nanometers)g Fg(declares)g(that)f(all)g(units)f (\(including)g(the)i Fh(scale)f Fg(parameter\))h(are)g(measured)f(in)g (units)0 670 y(of)38 b(nanometers.)69 b(Lik)o(e)n(wise,)40 b(the)e(units)f(may)g(all)h(be)g(speci\002ed)g(in)g Fd(angstr)n(oms)p Fg(.)70 b(Ho)n(we)n(v)o(er)37 b(unlik)o(ely)f(the)0 790 y(dimensions)31 b(may)h(seem,)j(the)e(problem)f(is)g(that)g(magic)h (needs)g(to)f(place)h(some)g(objects,)h(lik)o(e)e(contacts,)i(on)0 911 y(half-lambda)d(positions)f(to)i(ensure)g(correct)g(o)o(v)o(erlap)f (of)h(contact)g(cuts)f(between)h(subcells.)52 b(A)32 b(feature)g(size)0 1031 y(such)23 b(as,)g(for)g(e)o(xample,)f(45)h (nanometers,)g(has)f(a)i(half-lambda)e(v)n(alue)g(of)h(22.5)g (nanometers.)29 b(Since)23 b(this)f(is)h(not)0 1152 y(an)e(inte)o(ger)l (,)g(magic)g(will)f(complain)g(about)h(this)f(scalef)o(actor)-5 b(.)29 b(This)21 b(is)f(true)i(e)n(v)o(en)e(if)h(the)g(process)g (doesn')n(t)g Fh(allow)0 1272 y Fg(sub-nanometer)27 b(coordinates,)h (and)f(magic)h(uses)f(the)h Fh(squar)l(es-grid)e Fg(statement)h(to)g (enforce)h(this)f(restriction.)0 1392 y(In)d(such)g(a)h(case,)g(it)f (is)g(necessary)g(to)g(declare)h(a)g(scalef)o(actor)g(of)f(450)g (angstroms)f(rather)i(than)f(45)g(nanometers.)146 1514 y(V)-11 b(ersions)27 b(of)g Fh(ma)o(gic)g Fg(prior)g(to)f(7.1)h(allo)n (wed)f(an)i(optional)d(second)i(\(inte)o(ger\))g(parameter)l(,)h Fh(r)l(educer)p Fg(,)g(or)f(the)0 1634 y(k)o(e)o(yw)o(ord)f Fd(calmaonly)p Fg(.)37 b(The)28 b(use)f(of)g Fh(r)l(educer)g Fg(is)g(inte)o(gral)f(to)h(CIF)h(output,)e(which)h(uses)g(the)g(v)n (alue)f(to)h(ensure)0 1754 y(that)22 b(output)f(v)n(alues)g(are)i (reduced)g(to)f(the)g(smallest)f(common)g(denominator)-5 b(.)28 b(F)o(or)22 b(e)o(xample,)g(if)h(all)f(CIF)h(v)n(alues)0 1875 y(are)31 b(di)n(visible)d(by)h(100,)i(then)f(the)g(reducer)g(is)g (set)g(to)f(100)h(and)g(all)g(output)e(v)n(alues)h(are)i(di)n(vided)e (by)g(the)h(same)0 1995 y(f)o(actor)l(,)g(thus)e(reducing)g(the)h(size) g(of)f(the)h(CIF)h(output)d(\002le.)43 b(No)n(w)28 b(the)h(reducer)g (is)g(calculated)f(automatically)-6 b(,)0 2115 y(a)n(v)n(oiding)26 b(an)o(y)g(problems)g(resulting)f(from)i(an)g(incorrectly)g (speci\002ed)g(reducer)g(v)n(alue,)g(and)g(an)o(y)f(v)n(alue)h(found)0 2236 y(after)j Fh(scale)g Fg(is)f(ignored.)46 b(The)29 b Fd(calmaonly)h Fg(k)o(e)o(yw)o(ord)f(speci\002ed)h(that)f(the)h Fh(scale)f Fg(w)o(as)h(an)g(odd)f(inte)o(ger)-5 b(.)45 b(This)0 2356 y(limitation)20 b(has)i(been)h(remo)o(v)o(ed,)f(so)g(an)o (y)f(such)i(k)o(e)o(yw)o(ord)e(is)h(ignored,)g(and)h(correct)g(output)e (may)h(be)h(generated)0 2477 y(for)i(either)g(CIF)h(or)f(Calma)g(at)g (all)f(output)g(scales.)146 2598 y(In)33 b(addition)e(to)h(specifying)g (a)h(scale)g(f)o(actor)l(,)i(each)e(style)f(can)g(specify)h(the)f(size) h(in)f(which)g(chunks)g(will)0 2718 y(be)26 b(processed)g(when)g (generating)g(CIF)h(hierarchically)-6 b(.)33 b(This)26 b(is)f(particularly)g(important)g(when)h(the)g(a)n(v)o(erage)0 2838 y(design)c(size)g(is)g(much)g(lar)n(ger)h(than)f(the)g(maximum)e (bloat)i(or)h(shrink)e(\(e.g,)i(more)f(than)g(3)h(orders)f(of)g (magnitude)0 2959 y(dif)n(ference\).)31 b(The)25 b(step)f(size)h(is)g (speci\002ed)g(by)f(a)h(line)g(of)g(the)f(follo)n(wing)f(form:)900 3193 y Fd(stepsize)i Fh(stepsize)146 3426 y Fg(where)g Fh(stepsize)e Fg(is)g(in)g(Magic)h(units.)29 b(F)o(or)24 b(e)o(xample,)f(if)h(you)f(plan)h(to)f(generate)i(CIF)g(for)f(designs)f (that)g(will)0 3547 y(typically)h(be)h(100,000)e(Magic)i(units)e(on)i (a)g(side,)f(it)h(might)e(mak)o(e)i(sense)f(for)i Fh(stepsize)d Fg(to)i(be)g(10000)f(or)h(more.)0 3847 y Ff(12.3)119 b(Lay)o(er)29 b(descriptions)0 4036 y Fg(The)24 b(main)g(body)g(of)g (information)f(for)i(each)g(CIF)g(style)f(is)g(a)h(set)f(of)g(layer)h (descriptions.)k(Each)24 b(layer)h(descrip-)0 4156 y(tion)g(consists)f (of)h(one)h(or)f(more)h Fh(oper)o(ations)d Fg(describing)i(ho)n(w)f(to) h(generate)h(the)g(CIF)g(for)g(a)g(single)f(layer)-5 b(.)32 b(The)0 4277 y(\002rst)25 b(line)f(of)h(each)h(description)d(is) i(one)f(of)900 4511 y Fd(lay)o(er)h Fh(name)f Fg([)p Fh(layer)o(s)p Fg(])0 4744 y(or)900 4952 y Fd(templay)o(er)h Fh(name)g Fg([)p Fh(layer)o(s)p Fg(])146 5159 y(These)j(statements)e (are)i(identical,)f(e)o(xcept)h(that)f(templayers)f(are)i(not)f(output) g(in)g(the)g(CIF)h(\002le.)40 b(The)o(y)26 b(are)0 5280 y(used)f(only)g(to)h(b)n(uild)e(up)i(intermediate)f(results)g(used)g (in)h(generating)f(the)g(\223real\224)i(layers.)34 b(In)25 b(each)i(case,)f Fh(name)0 5400 y Fg(is)k(the)h(CIF)h(name)f(to)f(be)h (used)f(for)h(the)g(layer)-5 b(.)48 b(If)32 b Fh(layer)o(s)e Fg(is)g(speci\002ed,)j(it)d(consists)f(of)i(a)g(comma-separated)1850 5649 y(\22618\226)p eop end %%Page: 19 19 TeXDict begin 19 18 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)0 68 y(list)31 b(of)i(Magic)f(layers)h(and)f(pre)n(viously-de\002ned)g(CIF)h(layers)g (in)f(this)f(style;)36 b(these)c(layers)h(form)f(the)g(initial)0 188 y(contents)d(of)g(the)h(ne)n(w)f(CIF)i(layer)e(\(note:)40 b(the)30 b(layer)f(lists)g(in)g(this)f(section)h(are)i(less)e(general)h (than)f(what)g(w)o(as)0 309 y(described)e(in)f(Section)h(8;)h(tildes)e (and)h(parentheses)g(are)g(not)g(allo)n(wed\).)36 b(If)28 b Fh(layer)o(s)e Fg(is)h(not)f(speci\002ed,)i(then)e(the)0 429 y(ne)n(w)31 b(CIF)i(layer)f(is)f(initially)f(empty)-6 b(.)50 b(The)31 b(follo)n(wing)f(statements)g(are)j(used)e(to)g(modify) g(the)g(contents)g(of)h(a)0 549 y(CIF)26 b(layer)f(before)g(it)g(is)f (output.)146 670 y(After)k(the)f Fd(lay)o(er)h Fg(or)f Fd(templay)o(er)i Fg(statement)d(come)h(se)n(v)o(eral)g(statements)f (specifying)h(geometrical)g(oper)n(-)0 790 y(ations)j(to)h(apply)f(in)g (b)n(uilding)g(the)g(CIF)i(layer)-5 b(.)49 b(Each)31 b(statement)f(tak)o(es)h(the)g(current)g(contents)f(of)h(the)g(layer)l (,)0 911 y(applies)21 b(some)g(operation)g(to)h(it,)f(and)h(produces)f (the)h(ne)n(w)f(contents)g(of)h(the)f(layer)-5 b(.)30 b(The)21 b(last)h(geometrical)f(oper)n(-)0 1031 y(ation)e(for)g(the)h (layer)f(determines)g(what)g(is)g(actually)g(output)f(in)i(the)f(CIF)h (\002le.)30 b(The)19 b(most)f(common)h(geometrical)0 1151 y(operations)24 b(are:)900 1371 y Fd(or)h Fh(layer)o(s)900 1491 y Fd(and)h Fh(layer)o(s)900 1612 y Fd(and-not)g Fh(layer)o(s)900 1732 y Fd(gr)n(o)o(w)f Fh(amount)900 1852 y Fd(shrink)h Fh(amount)900 1973 y Fd(bloat-or)f Fh(layer)o(s)f(layer)o(s2)h(amount)e(layer)o(s2)i(amount)e(.)15 b(.)g(.)900 2093 y Fd(squar)n(es)26 b Fh(size)900 2214 y Fd(squar)n(es)g Fh(bor)l(der)e(size)g(separ)o(ation)146 2553 y Fg(Some)h(more)g(obscure)g(operations)f(are:)900 2773 y Fd(gr)n(o)o(w-grid)h Fh(amount)900 2893 y Fd(bloat-max)g Fh(layer)o(s)f(layer)o(s2)g(amount)g(layer)o(s2)g(amount)g(.)15 b(.)g(.)900 3014 y Fd(bloat-min)25 b Fh(layer)o(s)f(layer)o(s2)h (amount)e(layer)o(s2)i(amount)e(.)15 b(.)g(.)900 3134 y Fd(bloat-all)24 b Fh(layer)o(s)h(layer)o(s2)900 3254 y Fd(squar)n(es-grid)h Fh(bor)l(der)e(size)h(separ)o(ation)d(x)j(y)900 3375 y Fd(slots)f Fh(bor)l(der)g(size)h(separ)o(ation)900 3495 y Fd(slots)f Fh(bor)l(der)g(size)h(separ)o(ation)d(bor)l(der)p 2303 3495 30 4 v 36 w(long)900 3616 y Fd(slots)i Fh(bor)l(der)g(size)h (separ)o(ation)d(bor)l(der)p 2303 3616 V 36 w(long)i(size)p 2691 3616 V 35 w(long)g(sep)p 3061 3616 V 36 w(long)g Fg([)p Fh(of)n(fset)p Fg(]])900 3736 y Fd(b)o(box)h Fg([)p Fd(top)p Fg(])146 3955 y(The)i(operation)f Fd(or)g Fg(tak)o(es)h(all)f (the)g Fh(layer)o(s)g Fg(\(which)g(may)g(be)h(either)f(Magic)g(layers)h (or)f(pre)n(viously-de\002ned)0 4076 y(CIF)g(layers\),)f(and)g(or')-5 b(s)24 b(them)g(with)g(the)h(material)f(already)i(in)e(the)h(CIF)h (layer)-5 b(.)30 b(The)25 b(operation)f Fd(and)i Fg(is)e(similar)0 4196 y(to)31 b Fd(or)p Fg(,)j(e)o(xcept)e(that)f(it)h(and')-5 b(s)31 b(the)h(layers)f(with)h(the)f(material)h(in)f(the)h(CIF)h(layer) f(\(in)g(other)f(w)o(ords,)j(an)o(y)d(CIF)0 4317 y(material)22 b(that)h(doesn')n(t)f(lie)g(under)h(material)f(in)h Fh(layer)o(s)f Fg(is)g(remo)o(v)o(ed)f(from)i(the)f(CIF)i(layer\).)31 b Fd(And-not)24 b Fg(\002nds)e(all)0 4437 y(areas)29 b(co)o(v)o(ered)f(by)g Fh(layer)o(s)g Fg(and)g(erases)h(current)g(CIF)g (material)f(from)g(those)g(areas.)42 b Fd(Gr)n(o)o(w)28 b Fg(and)h Fd(shrink)g Fg(will)0 4557 y(uniformly)23 b(gro)n(w)h(or)h(shrink)f(the)g(current)h(CIF)h(layer)f(by)g Fh(amount)e Fg(units,)h(where)h Fh(amount)f Fg(is)g(speci\002ed)h(in)f (CIF)0 4678 y(units,)h(not)h(Magic)g(units.)34 b(The)26 b Fd(squar)n(es-grid)i Fg(operator)e(gro)n(ws)g(layers)g(non-uniformly) f(to)g(snap)h(to)g(the)h(grid)0 4798 y(spacing)e(indicated)g(by)g Fh(amount)p Fg(.)32 b(This)25 b(can)h(be)f(used)h(to)f(ensure)g(that)g (features)h(f)o(all)g(on)f(a)h(required)f(minimum)0 4918 y(grid.)146 5039 y(The)30 b(three)f(\223bloat\224)g(operations)f Fd(bloat-or)p Fg(,)j Fd(bloat-min)p Fg(,)f(and)f Fd(bloat-max)p Fg(,)h(pro)o(vide)e(selecti)n(v)o(e)g(forms)h(of)0 5159 y(gro)n(wing.)g(In)24 b(these)g(statements,)f(all)h(the)g(layers)g (must)f(be)h(Magic)g(layers.)31 b(Each)24 b(operation)f(e)o(xamines)g (all)h(the)0 5280 y(tiles)31 b(in)g Fh(layer)o(s)p Fg(,)i(and)e(gro)n (ws)g(the)h(tiles)f(by)g(a)h(dif)n(ferent)f(distance)g(on)h(each)g (side,)h(depending)e(on)g(the)g(rest)h(of)0 5400 y(the)c(line.)39 b(Each)28 b(pair)g Fh(layer)o(s2)f(amount)g Fg(speci\002es)h(some)f (tile)g(types)g(and)h(a)g(distance)f(\(in)h(CIF)h(units\).)38 b(Where)1850 5649 y(\22619\226)p eop end %%Page: 20 20 TeXDict begin 20 19 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)0 68 y(a)j(tile)f(of)g(type)h Fh(layer)o(s)f Fg(ab)n(uts)g(a)h(tile)f(of)g(type)g Fh(layer)o(s2)p Fg(,)h(the)f(\002rst)h(tile)f(is)g(gro)n(wn)f(on)i(that)f(side)g(by)g Fh(amount)p Fg(.)35 b(The)0 189 y(result)25 b(is)g(or'ed)h(with)f(the)g (current)h(contents)f(of)g(the)h(CIF)g(plane.)33 b(The)26 b(layer)g(\223)p Fd(*)p Fg(\224)g(may)f(be)h(used)f(as)h Fh(layer)o(s2)e Fg(to)0 309 y(indicate)f(all)h(tile)f(types.)30 b(Where)25 b(tiles)e(only)g(ha)n(v)o(e)h(a)g(single)f(type)h(of)g (neighbor)f(on)h(each)g(side,)g(all)f(three)i(forms)0 429 y(of)i Fd(bloat)h Fg(are)f(identical.)38 b(Where)27 b(the)h(neighbors)e(are)i(dif)n(ferent,)f(the)g(three)h(forms)e(are)i (slightly)e(dif)n(ferent,)h(as)0 550 y(illustrated)e(in)h(Figure)g (12.3.)34 b(Note:)f(all)26 b(the)g(layers)g(speci\002ed)h(in)f(an)o(y)f (gi)n(v)o(en)g Fd(bloat)h Fg(operation)g(must)f(lie)h(on)g(a)0 670 y(single)g(Magic)h(plane.)37 b(F)o(or)28 b Fd(bloat-or)f Fg(all)g(distances)f(must)g(be)h(positi)n(v)o(e.)36 b(In)27 b Fd(bloat-max)g Fg(and)g Fd(bloat-min)g Fg(the)0 790 y(distances)d(may)h(be)g(ne)o(gati)n(v)o(e)d(to)i(pro)o(vide)g(a)h (selecti)n(v)o(e)f(form)g(of)h(shrinking.)0 1863 y @beginspecial 68 @llx 68 @lly 856 @urx 261 @ury 4680 @rwi @setspecial %%BeginDocument: ../psfigures/maint2.2.ps %!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.2.ps %%Creator: Xcircuit v2.0 %%CreationDate: Tue Apr 18 11:16:25 2000 %%Pages: 1 %%BoundingBox: 68 68 856 261 %%DocumentNeededResources: font Helvetica %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /tiles { % -304 -188 608 380 bbox begingate 1 1.00 176 64 176 -96 2 polygon 1 1.00 -176 64 -176 -96 2 polygon 1 1.00 -16 64 -16 192 2 polygon (A) {/Helvetica 1.000 cf} 2 21 0 -16 -16 label (C) {/Helvetica 1.000 cf} 2 21 0 224 -16 label (B) {/Helvetica 1.000 cf} 2 23 0 -240 -16 label (D) {/Helvetica 1.000 cf} 2 29 0 -16 -160 label 1 1.00 -304 -96 304 -96 2 polygon 1 1.00 -304 64 304 64 2 polygon endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 992 398 offsets 1.0000 inchscale 2.6000 setlinewidth 0.745 0.600 0.871 scb 241 1.00 1744 606 1744 350 2240 350 2240 606 1744 606 5 polygon 241 1.00 1008 654 1008 350 1504 350 1504 654 1008 654 5 polygon 240 1.00 480 654 272 654 272 350 768 350 768 606 480 606 6 polygon sce 1 1.00 480 654 272 654 272 350 768 350 768 606 480 606 6 polygon 1.00 0 496 494 tiles 1.00 0 1232 494 tiles 1.00 0 1968 494 tiles 1 1.00 1008 654 1008 350 1504 350 1504 654 1008 654 5 polygon 1 1.00 1744 606 1744 350 2240 350 2240 606 1744 606 5 polygon (E) {/Helvetica 1.000 cf} 2 21 0 368 622 label (B) {/Helvetica 1.000 cf} 2 25 0 624 622 label (E) {/Helvetica 1.000 cf} 2 29 0 1104 638 label (B) {/Helvetica 1.000 cf} 2 29 0 1376 638 label (E) {/Helvetica 1.000 cf} 2 25 0 1840 622 label (B) {/Helvetica 1.000 cf} 2 25 0 2080 622 label (bloat-or A * 100 C,E 200) {/Helvetica 1.000 cf} 2 21 0 512 206 label (bloat-max A * 100 C,E 200) {/Helvetica 1.000 cf} 2 21 0 1248 206 label (bloat-min A * 100 C,E 200) {/Helvetica 1.000 cf} 2 21 0 2000 206 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF %%EndDocument @endspecial 203 x(Figure)31 b(2:)41 b(The)30 b(three)h(dif)n(ferent)f (forms)f(of)i Fd(bloat)f Fg(beha)n(v)o(e)g(slightly)e(dif)n(ferently)i (when)g(tw)o(o)g(dif)n(ferent)g(bloat)0 2187 y(distances)f(apply)g (along)f(the)i(same)f(side)g(of)g(a)h(tile.)44 b(In)29 b(each)h(of)f(the)h(abo)o(v)o(e)e(e)o(xamples,)h(the)h(CIF)g(that)f(w)o (ould)0 2307 y(be)i(generated)f(is)g(sho)n(wn)g(in)g(bold)f(outline.)47 b(If)31 b Fd(bloat-or)f Fg(is)g(speci\002ed,)j(a)d(jagged)g(edge)h(may) f(be)h(generated,)0 2428 y(as)25 b(on)g(the)g(left.)31 b(If)26 b Fd(bloat-max)f Fg(is)f(used,)h(the)g(lar)n(gest)g(bloat)f (distance)h(for)g(each)h(side)f(is)f(applied)h(uniformly)e(to)0 2548 y(the)k(side,)g(as)g(in)g(the)f(center)-5 b(.)38 b(If)27 b Fd(bloat-min)g Fg(is)g(used,)g(the)g(smallest)f(bloat)g (distance)h(for)g(each)h(side)e(is)h(applied)0 2668 y(uniformly)c(to)i (the)f(side,)h(as)g(on)f(the)h(right.)146 2992 y(In)39 b(retrospect,)i(it')-5 b(s)37 b(not)h(clear)h(that)f Fd(bloat-max)g Fg(and)g Fd(bloat-min)g Fg(are)h(v)o(ery)f(useful)g (operations.)70 b(The)0 3113 y(problem)25 b(is)g(that)h(the)o(y)e (operate)j(on)e(tiles,)g(not)g(re)o(gions.)33 b(This)25 b(can)h(cause)g(une)o(xpected)f(beha)n(vior)h(on)f(conca)n(v)o(e)0 3233 y(re)o(gions.)k(F)o(or)c(e)o(xample,)f(if)g(the)g(re)o(gion)g (being)g(bloated)g(is)g(in)g(the)g(shape)h(of)f(a)h(\223T\224,)g(a)g (single)e(bloat)h(f)o(actor)h(will)0 3354 y(be)j(applied)e(to)h(the)h (underside)f(of)g(the)g(horizontal)g(bar)-5 b(.)38 b(If)28 b(you)f(use)g Fd(bloat-max)h Fg(or)f Fd(bloat-min)p Fg(,)h(you)f (should)0 3474 y(probably)d(specify)h(design-rules)f(that)g(require)h (the)g(shapes)f(being)g(bloated)h(to)f(be)h(con)l(v)o(e)o(x.)146 3594 y(The)36 b(fourth)f(bloat)g(operation)h Fd(bloat-all)f Fg(tak)o(es)g(all)h(tiles)f(of)g(types)g Fh(layer)o(s)p Fg(,)j(and)e(gro)n(ws)f(to)g(include)g(all)0 3715 y(neighboring)26 b(tiles)g(of)h(types)g Fh(layer)o(s2)p Fg(.)37 b(This)27 b(is)f(v)o(ery)h(useful)g(to)g(generate)g(mark)o(er)h(layers)f(or)g (implant)f(layers)0 3835 y(for)d(speci\002c)h(de)n(vices,)e(where)i (the)f(mark)o(er)g(or)g(implant)e(must)h(co)o(v)o(er)g(both)h(the)f(de) n(vice)h(and)g(its)f(contacts.)30 b(T)-8 b(ak)o(e)0 3955 y(the)25 b(material)f(of)h(the)g(de)n(vice)f(and)h(use)f Fd(bloat-all)h Fg(to)f(e)o(xpand)g(into)g(the)h(contact)f(areas.)146 4076 y(An)31 b(important)f(geometric)g(operation)h(for)g(creating)g (contact)g(cuts)f(is)h Fd(squar)n(es)p Fg(.)50 b(It)31 b(e)o(xamines)f(each)i(tile)0 4196 y(on)c(the)g(CIF)h(plane,)f(and)g (replaces)h(that)e(tile)h(with)f(one)h(or)g(more)g(squares)g(of)g (material.)40 b(Each)28 b(square)g(is)g Fh(size)0 4317 y Fg(CIF)c(units)e(across,)h(and)f(squares)h(are)h(separated)f(by)f Fh(separ)o(ation)f Fg(units.)29 b(A)22 b(border)h(of)g(at)g(least)g Fh(bor)l(der)f Fg(units)g(is)0 4437 y(left)i(around)f(the)g(edge)h(of)g (the)g(original)e(tile,)i(if)f(possible.)29 b(This)23 b(operation)g(is)g(used)h(to)f(generate)h(contact)g(vias,)0 4557 y(as)31 b(in)g(Figure)g(3.)49 b(If)32 b(only)e(one)h(ar)n(gument)f (is)h(gi)n(v)o(en)e(in)i(the)g Fd(squar)n(es)h Fg(statement,)f(then)g Fh(separ)o(ation)e Fg(def)o(aults)0 4678 y(to)34 b Fh(size)f Fg(and)h Fh(bor)l(der)g Fg(def)o(aults)f(to)h Fh(size)p Fg(/2.)57 b(If)34 b(a)h(tile)e(doesn')n(t)h(hold)f(an)h(inte)o(gral)f (number)g(of)h(squares,)i(e)o(xtra)0 4798 y(space)c(is)e(left)i(around) f(the)g(edges)g(of)g(the)g(tile)g(and)g(the)g(squares)g(are)h(centered) g(in)f(the)g(tile.)49 b(If)32 b(the)f(tile)g(is)f(so)0 4918 y(small)22 b(that)i(not)e(e)n(v)o(en)h(a)h(single)f(square)g(can)h (\002t)g(and)f(still)g(lea)n(v)o(e)g(enough)g(border)l(,)h(then)f(the)g (border)h(is)f(reduced.)0 5039 y(If)31 b(a)f(square)h(w)o(on')n(t)f (\002t)g(in)g(the)h(tile,)g(e)n(v)o(en)e(with)h(no)g(border)l(,)h(then) f(no)h(material)e(is)h(generated.)48 b(The)30 b Fd(squar)n(es)0 5159 y Fg(operation)23 b(must)g(be)h(used)g(with)f(some)g(care,)i(in)f (conjunction)f(with)g(the)g(design)h(rules.)30 b(F)o(or)24 b(e)o(xample,)f(if)h(there)0 5280 y(are)j(se)n(v)o(eral)e(adjacent)g (skinn)o(y)g(tiles,)g(there)h(may)f(not)h(be)f(enough)h(room)f(in)g(an) o(y)h(of)f(the)h(tiles)f(for)h(a)g(square,)g(so)0 5400 y(no)21 b(material)f(will)g(be)h(generated)h(at)f(all.)29 b(Whene)n(v)o(er)20 b(you)h(use)f(the)h Fd(squar)n(es)h Fg(operator)l(,)g(you)e(should)g(use)h(design)1850 5649 y(\22620\226)p eop end %%Page: 21 21 TeXDict begin 21 20 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)0 68 y(rules)j(to)g(prohibit)f (adjacent)h(contact)g(tiles,)h(and)f(you)g(should)f(al)o(w)o(ays)h(use) g(the)g Fd(no)p 2938 68 30 4 v 37 w(o)o(v)o(erlap)g Fg(rule)g(to)g(pre) n(v)o(ent)0 188 y(unpleasant)k(hierarchical)h(interactions.)53 b(The)32 b(problems)g(with)g(hierarchy)g(are)h(discussed)f(in)g (Section)h(12.6)0 309 y(belo)n(w)-6 b(,)23 b(and)i(design)f(rules)h (are)g(discussed)f(in)g(Section)h(15.)1306 1465 y @beginspecial 68 @llx 68 @lly 304 @urx 253 @ury 1544 @rwi @setspecial %%BeginDocument: ../psfigures/maint2.3.ps %!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.3.ps %%Creator: Xcircuit v2.0 %%CreationDate: Tue Apr 18 11:18:51 2000 %%Pages: 1 %%BoundingBox: 68 68 304 253 %%DocumentNeededResources: font Helvetica-Oblique %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrowhead90 { % -20 -12 36 24 bbox begingate 1.00 90 -16 0 arrowhead endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 800 460 offsets 1.0000 inchscale 2.6000 setlinewidth 0.753 0.333 0.502 scb 240 1.00 224 300 224 556 608 556 608 300 4 polygon sce 0 1.00 224 300 224 556 608 556 608 300 4 polygon 240 1.00 256 332 256 396 320 396 320 332 4 polygon 240 1.00 256 460 256 524 320 524 320 460 4 polygon 240 1.00 384 332 384 396 448 396 448 332 4 polygon 240 1.00 384 460 384 524 448 524 448 460 4 polygon 240 1.00 512 332 512 396 576 396 576 332 4 polygon 240 1.00 512 460 512 524 576 524 576 460 4 polygon 1 1.00 320 572 320 620 2 polygon 1 1.00 384 572 384 620 2 polygon 1 1.00 624 332 672 332 2 polygon 1 1.00 624 300 672 300 2 polygon 1 1.00 256 316 256 236 2 polygon 1 1.00 320 316 320 236 2 polygon 1 1.00 256 604 304 604 2 polygon 1 1.00 400 604 448 604 2 polygon 1 1.00 656 348 656 396 2 polygon 1 1.00 656 284 656 220 2 polygon 1 1.00 336 252 384 252 2 polygon 1 1.00 240 252 192 252 2 polygon 1.00 0 336 252 arrowhead90 1.00 0 400 604 arrowhead90 1.00 -1 304 604 arrowhead90 1.00 -1 240 252 arrowhead90 1.00 -91 656 348 arrowhead90 1.00 270 656 284 arrowhead90 (separation) {/Helvetica-Oblique 1.000 cf} 2 25 0 352 636 label (size) {/Helvetica-Oblique 1.000 cf} 2 29 0 288 220 label (border) {/Helvetica-Oblique 1.000 cf} 2 20 0 688 316 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF %%EndDocument @endspecial 0 1669 a(Figure)g(3:)32 b(The)25 b Fd(squar)n(es)h Fg(operator)f(chops)g(each)g(tile)g(up)g(into)f(squares,)h(as)h (determined)e(by)h(the)g Fh(bor)l(der)p Fg(,)g Fh(size)p Fg(,)0 1789 y(and)c Fh(separ)o(ation)f Fg(parameters.)29 b(In)22 b(the)f(e)o(xample,)g(the)h(bold)e(lines)h(sho)n(w)g(the)g(CIF) h(that)f(w)o(ould)g(be)h(generated)f(by)0 1909 y(a)29 b Fd(squar)n(es)g Fg(operation.)40 b(The)28 b(squares)g(of)g(material)g (are)h(al)o(w)o(ays)f(centered)h(so)f(that)f(the)h(borders)g(on)g (opposite)0 2030 y(sides)c(are)i(the)e(same.)146 2364 y(The)38 b Fd(squar)n(es-grid)i Fg(operator)e(is)f(similar)g(to)h Fd(squar)n(es)h Fg(and)f(tak)o(es)g(the)g(same)g(ar)n(guments,)i(e)o (xcept)e(for)0 2484 y(the)33 b(additional)f(optional)h Fh(x)g Fg(and)h Fh(y)g Fg(of)n(fsets)e(\(which)i(def)o(ault)f(to)g (1\).)57 b(Where)34 b(the)f Fd(squar)n(es)i Fg(operator)e(places)0 2604 y(contacts)24 b(on)g(the)g(half-lambda)f(grid,)h(the)g Fd(squar)n(es-grid)i Fg(operator)e(places)g(contacts)g(on)g(an)g(inte)o (ger)g(grid)f(of)i Fh(x)0 2725 y Fg(and)g Fh(y)p Fg(.)33 b(This)25 b(is)g(helpful)g(where)h(manuf)o(acturing)e(grid)i (limitations)c(do)k(not)e(allo)n(w)h(half-lambda)g(coordinates.)0 2845 y(Ho)n(we)n(v)o(er)l(,)34 b(it)g(is)f(necessary)h(then)f(to)g (enforce)h(a)g(\223no-o)o(v)o(erlap\224)f(rule)h(for)f(contacts)g(in)h (the)f(DRC)i(section)d(to)0 2966 y(pre)n(v)o(ent)f(incorrect)h (contacts)g(cuts)g(from)g(being)f(generated)i(in)f(o)o(v)o(erlapping)e (subcells.)52 b(The)32 b Fd(squar)n(es-grid)0 3086 y Fg(operator)22 b(can)h(also)e(be)i(used)f(with)f Fh(x)h Fg(and)g Fh(y)h Fg(v)n(alues)e(to)h(generate)h(\002ll)f(geometry)-6 b(,)21 b(or)h(to)g(generate)h(of)n(fset)e(contact)0 3206 y(cut)k(arrays)g(for)g(pad)g(vias.)146 3329 y(The)h Fd(slots)e Fg(operator)h(is)g(similar)f(to)h Fd(squar)n(es)h Fg(operator)l(,)f(b)n (ut)g(as)g(the)g(name)h(implies,)d(the)i(resulting)f(shapes)0 3449 y(generated)i(are)g(rectangular)l(,)g(not)e(\(necessarily\))i (square.)33 b(Slots)24 b(are)j(generated)e(inside)g(indi)n(vidual)e (tiles,)i(lik)o(e)0 3570 y(the)32 b(squares)h(operator)l(,)h(so)e(each) h(slots)f(operation)g(is)g(separately)g(oriented)g(relati)n(v)o(e)g(to) g(the)g(tile')-5 b(s)31 b(long)h(and)0 3690 y(short)f(edges.)50 b(Separate)33 b(border)l(,)g(size,)g(and)e(separation)g(v)n(alues)g (can)h(be)f(speci\002ed)h(for)f(the)h(short)e(and)i(long)0 3811 y(dimensions)23 b(of)i(the)f(tile.)30 b(This)24 b(operator)h(can)h(be)e(used)h(in)f(a)i(number)e(of)h(situations:)120 4056 y(1.)49 b(Generate)25 b(square)g(contact)g(cuts)g(with)f(dif)n (ferent)g(border)h(requirements)f(on)h(the)g(short)f(and)h(long)f (sides,)244 4176 y(as)h(required)g(for)g(a)g(number)f(of)h(deep)g (submicron)f(processes)g(lik)o(e)h(90)f(nanometer)-5 b(.)120 4392 y(2.)49 b(Automatically)22 b(generate)i(slots)f(in)g(lar)n (ge)h(metal)f(areas,)i(which)e(most)g(processes)h(require.)30 b(Note,)24 b(ho)n(w-)244 4512 y(e)n(v)o(er)l(,)e(that)g(it)g(is)g (impossible)e(to)i(correctly)h(generate)g(all)f(slots,)f(so)h(this)g (cannot)g(completely)f(replace)i(the)244 4633 y(widespacing)h(DRC)i (rule.)120 4848 y(3.)49 b(Generate)25 b(slot)f(contacts.)120 5064 y(4.)49 b(Generate)25 b(\002ll)g(geometry)-6 b(.)120 5280 y(5.)49 b(Generate)32 b(mark)o(er)f(layers)g(for)g(resitors)g (that)f(ab)n(ut)h(the)g(position)e(of)i(contacts,)h(a)g (generally-accepted)244 5400 y(w)o(ay)25 b(to)f(de\002ne)i(a)f (resistor)f(area)i(boundary)-6 b(.)1850 5649 y(\22621\226)p eop end %%Page: 22 22 TeXDict begin 22 21 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)146 68 y(Note)37 b(that)f(the)g Fd(slots)g Fg(operator)g(comes)g(in)h(three)f(dif)n (ferent)g(forms)g(with)g(dif)n(ferent)g(numbers)g(of)h(ar)n(gu-)0 188 y(ments.)44 b(W)l(ith)29 b(only)g(three)h(ar)n(guments)f(\(short)g (side)g(description)g(only\),)h(the)f Fd(slots)g Fg(operator)h(creates) g(stripes)0 309 y(that)c(e)o(xtend)g(to)g(the)h(edge)g(of)f(the)h (tile.)35 b(W)l(ith)26 b(four)h(ar)n(guments)f(\(short)g(side)h (description)e(plus)h(long)g(side)g(bor)n(-)0 429 y(der)33 b(dimension)d(only\),)j(the)g Fd(slots)e Fg(operator)h(create)i (stripes)d(that)h(e)o(xtend)f(to)h(the)g(edge)h(of)f(the)g(tile,)h (with)f(an)0 549 y(appropriate)f(border)g(spacing)f(at)h(each)g(end.)49 b(In)31 b(these)g(tw)o(o)f(cases,)j(the)e(slots)e(ha)n(v)o(e)i(v)n (ariable)f(length)g(that)h(is)0 670 y(set)e(by)f(the)h(size)g(of)g(the) g(tile.)43 b(In)29 b(the)g(\002nal)g(form,)h(all)e(short)h(and)g(long)f (side)h(dimensions)e(are)i(declared.)44 b(The)0 790 y(generated)29 b(slots)e(are)i(of)f(\002x)o(ed)g(size,)h(and)f(lik)o(e)g(the)g Fd(squar)n(es)h Fg(operator)l(,)g(their)f(positions)e(will)i(be)g (adjusted)f(to)0 911 y(center)i(them)e(on)i(the)f(tile.)40 b(The)29 b Fh(of)n(fset)e Fg(is)h(intended)g(to)g(let)g(each)g(ro)n(w)g (of)h(slots)e(be)h(of)n(fset)g(from)g(the)g(pre)n(vious)0 1031 y(one)d(by)f(a)h(\002x)o(ed)g(amount,)f(b)n(ut)g(is)g(currently)h (unimplemented)e(and)h(has)h(no)g(ef)n(fect.)780 2112 y @beginspecial 68 @llx 68 @lly 523 @urx 247 @ury 2808 @rwi @setspecial %%BeginDocument: ../psfigures/maint2.3b.ps %!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.3b %%Creator: XCircuit v3.6 rev4 %%CreationDate: Mon Feb 13 12:33:32 2006 %%Pages: 1 %%BoundingBox: 68 68 523 247 %%DocumentNeededResources: font Helvetica font Helvetica-Oblique %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 3.3 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--7/13/05 (tim.edwards@multigig.com) % The Johns Hopkins University (1993-2004) % MultiGiG, Inc. (2004-present) % %%BeginResource: procset XCIRCproc 3.3 0 % % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /ul { dup type /stringtype eq showflag 1 eq and { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { dup type /stringtype eq showflag 1 eq and { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave currentpoint newpath moveto true charpath flattenpath pathbbox pop exch pop sub grestore } def /Ts {mark Tabs aload pop counttomark 1 add array astore /Tabs exch def Tabs 0 currentpoint pop put} def /Tbn {mark Tabs aload pop counttomark dup 2 add 1 roll cleartomark 1 sub} def /Tb { 0 1 Tbn {Tabs exch get dup currentpoint pop lt {currentpoint exch pop moveto exit} {pop} ifelse } for } def /Tf { Tbn -1 0 {Tabs exch get dup currentpoint pop gt {currentpoint exch pop moveto exit} {pop} ifelse } for } def /qS { (aa) stW (a a) stW sub 4 div 0 Kn } def /hS { qS qS } def /pspc 0 def /cf0 { scalefont setfont } bind def /Kn { dup kY add /kY exch def rmoveto } bind def /ss { /fscale fscale 0.67 mul def currentfont 0.67 cf0 0 fscale0 fscale mul 0.33 mul neg Kn} def /Ss { /fscale fscale 0.67 mul def currentfont 0.67 cf0 0 fscale0 fscale mul 0.67 mul Kn } def /ns { 0 kY neg Kn /kY 0 def /fscale 1.0 def xfont0 1.0 cf0 } def /CR { ns 0 /Bline Bline fscale0 neg add def Bline moveto } def /cf { dup type /realtype ne {1.0} if exch findfont exch kY 0 eq { 40 mul dup /fscale0 exch def cf0 /xfont0 currentfont def} {fscale0 mul fscale mul cf0} ifelse } def /ctmk { counttomark dup 2 add -1 roll pop } bind def /label { gsave translate 0 0 moveto dup scale neg /rotval exch def /just exch def just 384 and 0 gt {/mshow {pop} def} {/mshow {show} def} ifelse just 16 and 0 gt {gsave rotval rotate 0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup abs 1e-9 lt {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse grestore {-1 /rotval rotval neg def /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch -1e-9 lt {-1 /rotval rotval neg def /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /showflag 0 def /fspc pspc def /Bline 0 def /Tabs 0 array def /fscale 1.0 def /kY 0 def gsave dup 1 add copy 0 exch 1 0 dtransform exch atan rotate {exch dup type /stringtype eq {true charpath flattenpath} {dup type /arraytype eq {exec} {12 string cvs true charpath flattenpath} ifelse} ifelse} repeat pop pathbbox grestore 3 -1 roll pop 3 1 roll just 1 and 0 gt {just 2 and 0 gt {exch pop neg fspc sub} {exch sub 0.5 mul neg} ifelse} {pop neg fspc add} ifelse exch Bline exch just 4 and 0 gt {just 8 and 0 gt {exch pop neg fspc sub} {add 0.5 mul neg} ifelse} {pop neg fspc add} ifelse rotval rotate Kn currentpoint translate /showflag 1 def /Bline 0 def /Tabs 0 array def /fscale 1.0 def /kY 0 def {dup type /stringtype eq {mshow} {dup type /arraytype eq {exec} {12 string cvs mshow} ifelse} ifelse} repeat grestore } def /pinlabel { 4 index 32 and 0 ne hlevel 0 eq or { /pspc 10 def label /pspc 0 def } { pop pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /graphic { gsave 4 index cvx exec /DataSource get resetfile translate 0 0 moveto neg rotate dup scale cvx exec image grestore } def /scb { setrgbcolor } bind def /sce { defColor aload pop scb } bind def /cRedef {/defColor currentcolor 3 array astore def} def /begingate {dup type /dicttype ne {1 dict} if begin % default params dup type /dicttype ne {1 dict} if begin % instanced params /hlevel hlevel 1 add def /defColor currentcolor sce 3 array astore def gsave sce translate 0 0 moveto neg rotate dup abs scale } bind def /endgate { /hlevel hlevel 1 sub def grestore defColor aload pop cRedef scb end end} bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if gsave style 16 and 0 gt { style 224 and -5 bitshift style 256 and 0 gt { 7 exch sub 8 div dup 1 exch sub currentrgbcolor 3 array astore {3 copy mul add 4 1 roll pop} forall pop pop setrgbcolor eofill} {dup 7 lt {gar exch get ppaint} {pop eofill} ifelse} ifelse} {style 256 and 0 gt {1 setgray eofill} if} ifelse grestore style 8 and 0 gt style 512 eq or {newpath} {stroke} ifelse grestore} def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 0 0 scb cRedef } def /psinsertion {/PSobj save def /showpage {} def /setpagedevice {pop} def bop rotate translate dup scale} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. %%BeginSetup /arrowhead { % trivial begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrowhead90 { begingate 1.00 270 -16 0 arrowhead endgate } def /arrow { % trivial begingate 1 0.80 0 -40 0 20 2 polygon 1.00 0 0 40 arrowhead endgate } def %%EndSetup %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop 1.0000 inchscale 2.6000 setlinewidth 1058 -16 translate 0.753 0.333 0.502 scb 240 1.00 -576 272 -576 528 48 528 48 272 4 polygon sce 1 1.00 -288 512 -288 592 2 polygon 1 1.00 -240 512 -240 592 2 polygon 1 1.00 -352 576 -304 576 2 polygon 1 1.00 -224 576 -176 576 2 polygon -1.00 0 -304 576 arrowhead90 (sep_long) {/Helvetica-Oblique cf} 2 25 0 1.00 -256 608 label 0 1.00 -576 272 -576 528 48 528 48 272 4 polygon 240 1.00 -496 432 -496 496 -288 496 -288 432 4 polygon 240 1.00 -496 304 -496 368 -32 368 -32 304 4 polygon 240 1.00 -240 432 -240 496 -32 496 -32 432 4 polygon (given) {CR} (separation) {CR} (no size or) {/Helvetica cf} 6 20 0 1.00 144 272 label 1.00 0 -224 576 arrowhead90 1 1.00 -496 544 -496 624 2 polygon 1 1.00 -576 544 -576 624 2 polygon 1 1.00 -480 608 -432 608 2 polygon 1.00 0 -480 608 arrowhead90 1 1.00 -592 528 -736 528 2 polygon 1 1.00 -592 496 -736 496 2 polygon 1 1.00 -16 496 96 496 2 polygon 1 1.00 -16 432 96 432 2 polygon 1 1.00 -32 416 -32 224 2 polygon 1 1.00 -240 416 -240 224 2 polygon 1 1.00 -16 240 32 240 2 polygon 1.00 0 -16 240 arrowhead90 1 1.00 -256 240 -304 240 2 polygon -1.00 0 -256 240 arrowhead90 (size_long) {/Helvetica-Oblique cf} 2 29 0 1.00 -144 240 label 1 1.00 -640 608 -592 608 2 polygon -1.00 0 -592 608 arrowhead90 (border_long) {/Helvetica-Oblique cf} 2 25 0 1.00 -544 640 label (border) {/Helvetica-Oblique cf} 2 23 0 1.00 -752 512 label 1 1.00 -704 544 -704 592 2 polygon -1.00 90 -704 544 arrowhead90 1 1.00 -704 480 -704 432 2 polygon 1.00 90 -704 480 arrowhead90 1 1.00 80 512 80 560 2 polygon -1.00 90 80 512 arrowhead90 1 1.00 80 416 80 352 2 polygon 1.00 90 80 416 arrowhead90 -1.00 300 96 288 arrow (size) {/Helvetica-Oblique cf} 2 20 0 1.00 96 464 label 1 1.00 -592 432 -640 432 2 polygon 1 1.00 -592 368 -640 368 2 polygon 1 1.00 -624 448 -624 480 2 polygon -1.00 90 -624 448 arrowhead90 1 1.00 -624 352 -624 320 2 polygon 1.00 90 -624 352 arrowhead90 (sep) {/Helvetica-Oblique cf} 2 23 0 1.00 -608 400 label 1.000 1.000 1.000 scb 1 1.00 -240 304 -240 368 2 polygon pgsave restore showpage %%Trailer XCIRCsave restore %%EOF %%EndDocument @endspecial 703 2315 a(Figure)g(4:)31 b(The)25 b Fd(slots)f Fg(operator)g(chops)h(each)g(tile)f(up)h(into)f(rectangles.)146 2682 y(The)h Fd(b)o(box)g Fg(operator)f(generates)h(a)g(single)e (rectangle)i(that)f(encompasses)f(the)i(bounding)e(box)g(of)i(the)f (cell.)0 2803 y(This)j(is)g(useful)g(for)g(the)g(occasional)g(process)h (that)f(requires)g(mark)o(er)h(or)f(implant)f(layers)i(co)o(v)o(ering)e (an)h(entire)0 2923 y(design.)i(The)23 b(v)n(ariant)f Fd(b)o(box)h(top)h Fg(will)e(generate)h(a)g(rectangle)g(encompassing)e (the)i(bounding)e(box)i(of)g(the)f(cell,)0 3043 y(b)n(ut)i(will)g(only) g(do)h(so)f(for)h(the)g(top-le)n(v)o(el)e(cell)i(of)g(the)f(design.)0 3375 y Ff(12.4)119 b(Labels)0 3574 y Fg(There)25 b(is)g(an)g (additional)e(statement)h(permitted)f(in)i(the)g Fd(cif)n(output)g Fg(section)g(as)f(part)h(of)g(a)g(layer)g(description:)900 3847 y Fd(labels)f Fh(Ma)o(giclayer)o(s)146 4115 y Fg(This)c(statement) g(tells)g(Magic)g(that)h(labels)f(attached)h(to)f(Magic)g(layers)h Fh(Ma)o(giclayer)o(s)f Fg(are)h(to)g(be)g(associated)0 4235 y(with)32 b(the)g(current)g(CIF)i(layer)-5 b(.)53 b(Each)32 b(Magic)g(layer)h(should)e(only)h(appear)g(in)g(one)h(such)f (statement)f(for)i(an)o(y)0 4356 y(gi)n(v)o(en)25 b(CIF)j(style.)36 b(If)27 b(a)g(Magic)f(layer)h(doesn')n(t)g(appear)g(in)f(an)o(y)g Fd(labels)h Fg(statement,)f(then)g(it)g(is)h(not)f(attached)g(to)0 4476 y(a)f(speci\002c)g(layer)g(when)g(output)f(in)g(CIF)-8 b(.)0 4807 y Ff(12.5)119 b(Calma)29 b(\(GDS)i(II)e(Str)n(eam)g(f)m (ormat\))g(lay)o(ers)0 5006 y Fg(Each)c(layer)g(description)f(in)g(the) h Fd(cif)n(output)h Fg(section)e(may)g(also)h(contain)f(one)h(of)g(the) f(follo)n(wing)f(statements:)900 5280 y Fd(gds)i Fh(gdsNumber)f(gdsT)-7 b(ype)900 5400 y Fd(calma)24 b Fh(gdsNumber)h(gdsT)-7 b(ype)1850 5649 y Fg(\22622\226)p eop end %%Page: 23 23 TeXDict begin 23 22 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)146 68 y(Although)36 b(the)h(format)g(is)f(rarely)i(referred)h(to)d(as)i(\223Calma\224)f(an) o(ymore,)j(the)d(k)o(e)o(yw)o(ord)f(is)h(retained)g(for)0 188 y(backw)o(ards)25 b(compatibility)d(with)i(format)h(27)f(\(and)h (earlier\))h(\002les.)146 309 y(This)k(statement)g(tells)g(Magic)g (which)g(layer)h(number)f(and)h(data)f(type)h(to)f(use)g(when)h(the)f Fd(gds)h Fg(command)0 429 y(outputs)g(GDS)i(II)g(Stream)g(format)f(for) h(this)f(de\002ned)h(CIF)g(layer)-5 b(.)54 b(Both)32 b Fh(gdsNumber)g Fg(and)h Fh(gdsT)-7 b(ype)32 b Fg(should)0 549 y(be)i(positi)n(v)o(e)e(inte)o(gers,)k(between)e(0)g(and)g(63.)59 b(Each)34 b(CIF)i(layer)e(should)f(ha)n(v)o(e)h(a)g(dif)n(ferent)g Fh(gdsNumber)p Fg(.)59 b(If)0 670 y(there)33 b(is)g(no)f Fd(gds)h Fg(line)g(for)g(a)g(gi)n(v)o(en)f(CIF)i(layer)l(,)h(then)d (that)h(layer)g(will)f(not)g(be)h(output)f(by)h(the)f(\223)p Fd(gds)h(write)p Fg(\224)0 790 y(command.)55 b(The)34 b(re)n(v)o(erse)f(is)g(not)f(true:)48 b(e)n(v)o(ery)33 b(generated)g(output)f(layer)i(must)e(ha)n(v)o(e)h(a)h(de\002ned)f(CIF) i(layer)0 911 y(type,)24 b(e)n(v)o(en)f(if)i(the)f(foundry)f(only)h (supports)f(GDS)i(format.)30 b(In)24 b(such)g(case,)h(the)f(CIF)h (layer)g(name)f(may)g(violate)0 1031 y(the)36 b(restricti)n(v)o(e)e (4-character)j(format)e(required)h(by)f(the)h(CIF)g(syntax)f (speci\002cation,)j(and)e(may)f(be)h(used)f(to)0 1151 y(pro)o(vide)24 b(a)h(reasonable,)g(human-readable)f(descripti)n(v)o(e) f(name)i(of)g(the)g(GDS)g(layer)-5 b(.)292 2457 y @beginspecial 68 @llx 68 @lly 712 @urx 297 @ury 3978 @rwi @setspecial %%BeginDocument: ../psfigures/maint2.4.ps %!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.4.ps %%Creator: Xcircuit v2.0 %%CreationDate: Tue Apr 18 11:22:46 2000 %%Pages: 1 %%BoundingBox: 68 68 712 297 %%DocumentNeededResources: font Helvetica %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 1056 334 offsets 1.0000 inchscale 2.6000 setlinewidth 0.490 0.651 0.980 scb 240 1.00 800 270 800 718 1312 718 1312 270 4 polygon 240 1.00 1504 334 1504 654 1888 654 1888 334 4 polygon 240 1.00 192 334 192 654 320 654 320 334 4 polygon 240 1.00 448 334 448 654 576 654 576 334 4 polygon sce 0 1.00 192 334 192 654 320 654 320 334 4 polygon 0 1.00 448 334 448 654 576 654 576 334 4 polygon 0 1.00 1504 334 1504 654 1888 654 1888 334 4 polygon 0 1.00 800 270 800 718 1312 718 1312 270 4 polygon 2 1.00 864 334 864 654 992 654 992 334 4 polygon 2 1.00 1120 334 1120 654 1248 654 1248 334 4 polygon 2 1.00 1504 334 1504 654 1632 654 1632 334 4 polygon 2 1.00 1760 334 1760 654 1888 654 1888 334 4 polygon 1 1.00 784 654 704 654 2 polygon 1 1.00 784 718 704 718 2 polygon 1 1.00 736 638 736 590 2 polygon 1 1.00 736 734 736 782 2 polygon 1.00 0 736 654 arrowhead 1.00 -181 736 718 arrowhead (100) {/Helvetica 1.000 cf} 2 21 0 736 686 label (\(a\)) {/Helvetica 1.000 cf} 2 21 0 352 206 label (\(b\)) {/Helvetica 1.000 cf} 2 21 0 1056 206 label (\(c\)) {/Helvetica 1.000 cf} 2 21 0 1696 206 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF %%EndDocument @endspecial 0 2660 a(Figure)27 b(5:)34 b(If)27 b(the)g(operator)g Fd(gr)n(o)o(w)g(100)f Fg(is)g(applied)g(to)g(the)h(shapes)f(in)h (\(a\),)h(the)e(mer)n(ged)h(shape)g(in)f(\(b\))h(results.)0 2781 y(If)j(the)f(operator)g Fd(shrink)h(100)f Fg(is)g(applied)f(to)h (\(b\),)h(the)f(result)g(is)g(\(c\).)44 b(Ho)n(we)n(v)o(er)l(,)29 b(if)g(the)g(tw)o(o)g(original)f(shapes)0 2901 y(in)j(\(a\))i(belong)e (to)g(dif)n(ferent)h(cells,)h(and)e(if)h(CIF)h(is)e(generated)h (separately)g(in)g(each)g(cell,)h(the)f(result)f(will)g(be)0 3022 y(the)h(same)h(as)f(in)g(\(a\).)55 b(Magic)32 b(handles)g(this)g (by)g(outputting)e(additional)h(information)h(in)g(the)g(parent)h(of)f (the)0 3142 y(subcells)24 b(to)g(\002ll)h(in)f(the)h(gap)f(between)h (the)g(shapes.)0 3647 y Ff(12.6)119 b(Hierar)n(ch)n(y)0 3835 y Fg(Hierarchical)23 b(designs)f(mak)o(e)g(life)h(especially)f (dif)n(\002cult)g(for)h(the)g(CIF)g(generator)-5 b(.)30 b(The)23 b(CIF)h(corresponding)d(to)0 3955 y(a)28 b(collection)e(of)h (subcells)g(may)g(not)g(necessarily)g(be)g(the)g(same)g(as)h(the)f(sum) f(of)i(the)f(CIF')-5 b(s)28 b(of)f(the)g(indi)n(vidual)0 4076 y(cells.)53 b(F)o(or)32 b(e)o(xample,)h(if)g(a)f(layer)h(is)f (generated)g(by)g(gro)n(wing)f(and)i(then)f(shrinking,)g(nearby)h (features)f(from)0 4196 y(dif)n(ferent)38 b(cells)h(may)f(mer)n(ge)h (together)f(so)h(that)f(the)o(y)g(don')n(t)g(shrink)g(back)h(to)f (their)g(original)g(shapes)h(\(see)0 4317 y(Figure)28 b(5\).)38 b(If)28 b(Magic)f(generates)h(CIF)h(separately)e(for)h(each)g (cell,)g(the)f(interactions)f(between)i(cells)f(will)g(not)0 4437 y(be)h(re\003ected)g(properly)-6 b(.)38 b(The)27 b(CIF)i(generator)e(attempts)f(to)i(a)n(v)n(oid)e(these)i(problems.)37 b(Although)26 b(it)h(generates)0 4557 y(CIF)35 b(in)e(a)g(hierarchical) h(representation)f(that)g(matches)g(the)g(Magic)g(cell)h(structure,)h (it)e(tries)g(to)g(ensure)h(that)0 4678 y(the)g(resulting)e(CIF)j (patterns)f(are)g(e)o(xactly)f(the)h(same)g(as)f(if)h(the)g(entire)g (Magic)f(design)g(had)h(been)g(\003attened)0 4798 y(into)29 b(a)i(single)e(cell)h(and)h(then)f(CIF)h(were)g(generated)f(from)g(the) g(\003attened)h(design.)46 b(It)30 b(does)g(this)g(by)g(looking)0 4918 y(in)c(each)g(cell)g(for)g(places)g(where)h(subcells)e(are)i (close)e(enough)h(to)f(interact)h(with)f(each)i(other)f(or)g(with)f (paint)g(in)0 5039 y(the)j(parent.)41 b(Where)29 b(this)f(happens,)g (Magic)g(\003attens)g(the)h(interaction)e(area)i(and)g(generates)f(CIF) i(for)e(it;)h(then)0 5159 y(Magic)24 b(\003attens)g(each)h(of)f(the)g (subcells)f(separately)h(and)g(generates)h(CIF)g(for)g(them.)k(Finally) -6 b(,)24 b(it)f(compares)h(the)0 5280 y(CIF)29 b(from)f(the)g (subcells)g(with)f(the)h(CIF)h(from)f(the)g(\003attened)h(parent.)41 b(Where)28 b(there)h(is)f(a)g(dif)n(ference,)h(Magic)0 5400 y(outputs)23 b(e)o(xtra)i(CIF)h(in)e(the)h(parent)g(to)f (compensate.)1850 5649 y(\22623\226)p eop end %%Page: 24 24 TeXDict begin 24 23 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)146 68 y(Magic')-5 b(s)25 b(hierarchical)g(approach)h(only)e(w)o(orks)h(if)g(the)g(o)o(v)o (erall)f(CIF)i(for)g(the)f(parent)g(ends)g(up)g(co)o(v)o(ering)f(at)0 188 y(least)h(as)h(much)f(area)h(as)g(the)f(CIFs)i(for)e(the)h(indi)n (vidual)d(components,)h(so)h(all)h(compensation)e(can)h(be)h(done)f(by) 0 309 y(adding)k(e)o(xtra)h(CIF)h(to)e(the)h(parent.)46 b(In)30 b(mathematical)f(terms,)h(this)f(requires)h(each)h(geometric)e (operation)g(to)0 429 y(obe)o(y)24 b(the)h(rule)900 676 y(Op\(A)g Fe([)g Fg(B\))h Fe(\023)f Fg(Op\(A\))g Fe([)g Fg(Op\(B\))146 920 y(The)c(operations)g Fd(and)p Fg(,)h Fd(or)p Fg(,)g Fd(gr)n(o)o(w)p Fg(,)g(and)f Fd(shrink)h Fg(all)e(obe)o(y)h(this)f(rule.)29 b(Unfortunately)-6 b(,)20 b(the)h Fd(and-not)p Fg(,)i Fd(bloat)p Fg(,)0 1041 y(and)f Fd(squar)n(es)g Fg(operations)f(do)h(not.)29 b(F)o(or)21 b(e)o(xample,)h(if)g(there)g(are)g(tw)o(o)f(partially-o)o (v)o(erlapping)e(tiles)i(in)g(dif)n(ferent)0 1161 y(cells,)32 b(the)f(squares)g(generated)h(from)f(one)g(of)g(the)g(cells)g(may)f(f)o (all)h(in)g(the)g(separations)f(between)i(squares)e(in)0 1282 y(the)23 b(other)g(cell,)h(resulting)e(in)g(much)h(lar)n(ger)h (areas)g(of)f(material)g(than)g(e)o(xpected.)30 b(There)24 b(are)f(tw)o(o)g(w)o(ays)g(around)0 1402 y(this)i(problem.)35 b(One)26 b(w)o(ay)h(is)f(to)g(use)g(the)g(design)g(rules)g(to)g (prohibit)f(problem)h(situations)e(from)i(arising.)35 b(This)0 1522 y(applies)19 b(mainly)g(to)g(the)g Fd(squar)n(es)i Fg(operator)-5 b(.)29 b(T)m(iles)18 b(from)i(which)f(squares)h(are)g (made)g(should)e(ne)n(v)o(er)h(be)h(allo)n(wed)0 1643 y(to)29 b(o)o(v)o(erlap)f(other)h(such)g(tiles)f(in)h(dif)n(ferent)g (cells)f(unless)h(the)g(o)o(v)o(erlap)f(is)h(e)o(xact,)h(so)e(each)i (cell)f(will)g(generate)0 1763 y(squares)c(in)f(the)h(same)f(place.)31 b(Y)-11 b(ou)25 b(can)g(use)g(the)f Fd(exact)p 1948 1763 30 4 v 37 w(o)o(v)o(erlap)g Fg(design)g(rule)h(for)g(this.)146 1886 y(The)g(second)g(approach)h(is)e(to)h(lea)n(v)o(e)g(things)e(up)i (to)g(the)g(designer)-5 b(.)30 b(When)25 b(generating)g(CIF)-8 b(,)26 b(Magic)f(issues)0 2006 y(w)o(arnings)e(where)h(there)g(is)f (less)g(material)g(in)g(the)g(children)g(than)h(the)f(parent.)30 b(The)24 b(designer)f(can)h(locate)f(these)0 2127 y(problems)f(and)h (eliminate)g(the)g(interactions)f(that)h(cause)h(the)f(trouble.)29 b(W)-8 b(arning:)30 b(Magic)23 b(does)g(not)g(check)g(the)0 2247 y Fd(squar)n(es)j Fg(operations)f(for)h(hierarchical)g(consistenc) o(y)-6 b(,)23 b(so)i(you)g(absolutely)f(must)h(use)g Fd(exact)p 3265 2247 V 36 w(o)o(v)o(erlap)h Fg(design)0 2367 y(rule)e(checks!)31 b(Right)23 b(no)n(w)-6 b(,)23 b(the)h Fd(cif)n(output)h Fg(section)f(of)g(the)f(technology)g(is)h (one)g(of)g(the)g(trickiest)f(things)g(in)g(the)0 2488 y(whole)i(\002le,)i(particularly)e(since)h(errors)g(here)g(may)g(not)f (sho)n(w)g(up)g(until)g(your)h(chip)f(comes)h(back)g(and)f(doesn')n(t)0 2608 y(w)o(ork.)31 b(Be)25 b(e)o(xtremely)f(careful)h(when)g(writing)f (this)g(part!)146 2731 y(Another)f(problem)g(with)g(hierarchical)h (generation)f(is)g(that)g(it)g(can)h(be)f(v)o(ery)g(slo)n(w)-6 b(,)22 b(especially)h(when)h(there)0 2851 y(are)30 b(a)g(number)f(of)h (rules)f(in)g(the)h(cifoutput)e(section)h(with)g(v)o(ery)g(lar)n(ge)h (gro)n(w)f(or)h(shrink)e(distances,)i(such)g(that)0 2972 y(magic)f(must)f(al)o(w)o(ays)h(e)o(xpand)g(its)f(area)j(of)e(interest) g(by)g(this)f(amount)g(to)h(be)h(sure)f(of)h(capturing)e(all)h (possible)0 3092 y(layer)23 b(interactions.)29 b(When)23 b(this)f(\223halo\224)h(distance)g(becomes)g(lar)n(ger)g(than)g(the)g (a)n(v)o(erage)g(subcell,)g(much)f(of)h(the)0 3212 y(design)28 b(may)g(end)g(up)h(being)f(processed)g(multiple)f(times.)41 b(Noticeably)27 b(slo)n(w)h(output)f(generation)h(is)g(usually)0 3333 y(indicati)n(v)o(e)j(of)j(this)e(problem.)56 b(It)33 b(can)h(be)f(alle)n(viated)g(by)g(k)o(eeping)g(output)f(rules)h (simple.)55 b(Note)33 b(that)g(basic)0 3453 y(AND)k(and)g(OR)g (operations)g(do)f(not)h(interact)g(between)g(subcells,)i(so)e(that)f (rules)h(made)g(from)g(only)f(these)0 3573 y(operators)d(will)g(not)g (be)g(processed)h(during)e(subcell)h(interaction)g(generation.)56 b(Remember)34 b(that)f(typically)-6 b(,)0 3694 y(subcell)30 b(interaction)f(paint)h(will)g(only)g(be)g(generated)h(for)g(layers)f (that)g(ha)n(v)o(e)g(a)h(\223gro)n(w\224)f(operation)g(follo)n(wed)0 3814 y(by)c(a)g(\223shrink\224)g(operation.)35 b(This)25 b(common)g(ruleset)h(lets)f(layers)i(that)e(are)i(too)f(closely)f (spaced)i(to)f(be)g(mer)n(ged)0 3935 y(together)l(,)32 b(thus)e(eliminating)e(the)j(need)g(for)g(a)g(spacing)f(rule)h(between) g(the)f(layers.)49 b(But)31 b(consider)f(carefully)0 4055 y(before)25 b(implementing)e(such)h(a)i(rule.)31 b(Implementing)22 b(a)k(DRC)f(spacing)g(rule)g(instead)f(may)g (eliminate)g(a)h(huge)0 4175 y(amount)34 b(of)i(output)e(processing.)62 b(Usually)34 b(this)g(situation)g(crops)h(up)g(for)h(auto-generated)g (layers)f(such)g(as)0 4296 y(implants)d(and)i(wells,)h(to)e(pre)n(v)o (ent)g(magic)g(from)h(auto-generating)f(DRC)h(spacing)g(violations.)55 b(But)34 b(again,)0 4416 y(consider)k(carefully)g(whether)g(it)f(might) g(be)h(better)f(to)h(require)g(the)g(layout)f(engineer)h(to)g(dra)o(w)f (the)h(layers)0 4536 y(instead)24 b(of)h(attempting)e(to)i (auto-generate)g(them.)0 4846 y Ff(12.7)119 b(Render)31 b(statements)0 5039 y Fg(At)k(the)h(end)g(of)f(each)i(style)e(in)g(the) h Fd(cif)n(output)g Fg(section,)i(one)e(may)f(include)g Fd(r)n(ender)j Fg(statements,)f(one)f(per)0 5159 y(de\002ned)h(CIF/GDS) g(layer)-5 b(.)65 b(These)36 b Fd(r)n(ender)j Fg(statements)c(are)i (used)f(by)g(the)g(3-D)g(dra)o(wing)f(windo)n(w)g(in)h(the)0 5280 y(OpenGL)31 b(graphics)f(v)o(ersion)g(of)h(magic,)h(and)f(are)g (also)g(used)g(by)f(the)h(\223)p Fd(cif)g(see)p Fg(\224)h(command)e(to) g(set)h(the)g(style)0 5400 y(painted.)f(The)25 b(syntax)f(for)h(the)g (statement)e(is)i(as)g(follo)n(ws:)1850 5649 y(\22624\226)p eop end %%Page: 25 25 TeXDict begin 25 24 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)p 1366 3 1168 4 v 1364 124 4 121 v 1416 88 a Fd(ci\002nput)p 2532 124 V 1364 244 V 1416 208 a Fg(style)f(lambda=1.0\(gen\))p 2532 244 V 1364 364 V 1716 328 a(scalef)o(actor)i(100)p 2532 364 V 1364 485 V 1716 449 a(layer)f(m1)f(CMF)p 2532 485 V 1364 605 V 2016 569 a(labels)g(CMF)p 2532 605 V 1364 726 V 1716 689 a(layer)h(ndif)n(f)f(CSN)p 2532 726 V 1364 846 V 2016 810 a(and)h(CAA)p 2532 846 V 1364 966 V 1716 930 a(layer)g(nsd)f(CWN)p 2532 966 V 1364 1087 V 2016 1051 a(and)h(CSN)p 2532 1087 V 1364 1207 V 2016 1171 a(and)g(CAA)p 2532 1207 V 1364 1328 V 1716 1291 a(layer)g(nfet)g(CPG)p 2532 1328 V 1364 1448 V 2016 1412 a(and)g(CAA)p 2532 1448 V 1364 1568 V 2016 1532 a(and)g(CSN)p 2532 1568 V 1364 1689 V 1716 1653 a(layer)g(ndc)g(CCA)p 2532 1689 V 1364 1809 V 2016 1773 a(gro)n(w)f(100)p 2532 1809 V 1364 1929 V 2016 1893 a(and)h(CAA)p 2532 1929 V 1364 2050 V 2016 2014 a(and)g(CWP)p 2532 2050 V 1364 2170 V 2016 2134 a(and)g(CSN)p 2532 2170 V 1364 2291 V 2016 2254 a(and)g(CMF)p 2532 2291 V 1364 2411 V 1716 2375 a(layer)g(nncont)f(CCA)p 2532 2411 V 1364 2531 V 2016 2495 a(gro)n(w)g(100)p 2532 2531 V 1364 2652 V 2016 2616 a(and)h(CAA)p 2532 2652 V 1364 2772 V 2016 2736 a(and)g(CSN)p 2532 2772 V 1364 2892 V 2016 2856 a(and)g(CWN)p 2532 2892 V 1364 3013 V 2016 2977 a(and)g(CMF)p 2532 3013 V 1364 3133 V 1716 3097 a(calma)g(CAA)g(1)g(*)p 2532 3133 V 1364 3254 V 1716 3218 a(calma)g(CCA)h(2)e(*)p 2532 3254 V 1364 3374 V 1716 3338 a(calma)h(CMF)g(4)g(*)p 2532 3374 V 1364 3494 V 1716 3458 a(calma)g(CPG)h(7)e(*)p 2532 3494 V 1364 3615 V 1716 3579 a(calma)h(CSN)h(8)e(*)p 2532 3615 V 1364 3735 V 1716 3699 a(calma)h(CWN)g(11)g(*)p 2532 3735 V 1364 3856 V 1716 3819 a(calma)g(CWP)h(12)e(*)p 2532 3856 V 1364 3976 V 1416 3940 a Fd(end)p 2532 3976 V 1366 3979 1168 4 v 0 4139 a Fg(T)-8 b(able)24 b(10:)30 b(P)o(art)25 b(of)f(the)h Fd(ci\002nput)h Fg(section.)k(The)24 b(order)h(of)f(the)g(layers)h(is)f(important,)f(since)h(each)h(Magic)f (layer)0 4260 y(o)o(v)o(errides)g(the)g(pre)n(vious)g(ones)g(just)g(as) h(if)g(the)o(y)f(were)h(painted)g(by)f(hand.)900 4651 y Fd(r)n(ender)j Fh(cif)p 1317 4651 30 4 v 35 w(layer)e(style)p 1765 4651 V 35 w(name)g(height)f(thic)n(kness)146 4918 y Fg(The)k Fh(cif)p 435 4918 V 36 w(layer)g Fg(is)f(an)o(y)h(v)n(alid)f (layer)h(name)g(de\002ned)h(in)e(the)h(same)g Fd(cif)n(output)h Fg(section)f(where)g(the)g Fd(r)n(ender)0 5039 y Fg(statement)22 b(occurs.)30 b(The)23 b Fh(style)p 1087 5039 V 35 w(name)g Fg(is)f(the)h(name)g(or)g(number)f(of)h(a)g(style)f(in)h(the)g(styles)f (\002le.)30 b(The)23 b(names)f(are)0 5159 y(the)30 b(same)g(as)g(used)f (in)h(the)g Fd(styles)f Fg(section)g(of)h(the)g(technology)f(\002le.)46 b Fh(height)30 b Fg(and)g Fh(thic)n(kness)f Fg(are)h(ef)n(fecti)n(v)o (ely)0 5280 y(dimensionless)19 b(units)g(and)i(are)h(used)f(for)g (relati)n(v)o(e)f(placement)g(and)h(scaling)g(of)g(the)f (three-dimensional)g(layout)0 5400 y(vie)n(w)h(\(such)g(vie)n(ws)g (generally)h(ha)n(v)o(e)f(a)h(greatly)f(e)o(xpanded)g(z-axis)h (scaling\).)29 b(By)22 b(def)o(ault,)g(all)g(layers)f(are)i(gi)n(v)o (en)1850 5649 y(\22625\226)p eop end %%Page: 26 26 TeXDict begin 26 25 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)0 68 y(the)f(same)g(style)f(and)h (a)h(zero)f(height)g(and)g(thickness,)f(so)h(ef)n(fecti)n(v)o(ely)e (nothing)h(useful)h(can)g(be)g(seen)g(in)g(the)g(3-D)0 188 y(vie)n(w)h(without)f(a)j(complete)e(set)g(of)h Fd(r)n(ender)i Fg(statements.)0 556 y Fi(13)143 b(Ci\002nput)34 b(section)0 789 y Fg(In)26 b(addition)e(to)h(writing)f(CIF)-8 b(,)27 b(Magic)e(can)h(also)f(read)h(in)f(CIF)h(\002les)g(using)e(the)i Fd(:cif)g(r)n(ead)g Fh(\002le)f Fg(command.)32 b(The)0 909 y Fd(ci\002nput)24 b Fg(section)d(of)g(the)h(technology)f(\002le)h (describes)f(ho)n(w)g(to)h(con)l(v)o(ert)f(from)g(CIF)i(mask)e(layers)h (to)f(Magic)h(tile)0 1030 y(types.)44 b(In)29 b(addition,)g(it)g(pro)o (vides)f(information)g(to)h(the)g(Calma)h(reader)g(to)f(allo)n(w)f(it)h (to)g(read)h(in)f(Calma)h(GDS)0 1150 y(II)c(Stream)g(format)g(\002les.) 33 b(The)26 b Fd(ci\002nput)h Fg(section)e(is)h(v)o(ery)f(similar)g(to) g(the)g Fd(cif)n(output)i Fg(section.)33 b(It)26 b(can)g(contain)0 1271 y(se)n(v)o(eral)e(styles,)g(with)g(a)h(line)f(of)h(the)g(form)900 1534 y Fd(style)g Fh(name)146 1794 y Fg(used)g(to)f(end)h(the)g (description)e(of)i(the)g(pre)n(vious)e(style)h(\(if)h(an)o(y\),)g(and) f(start)h(a)g(ne)n(w)f(CIF)i(input)e(style)g(called)0 1914 y Fh(name)p Fg(.)63 b(If)36 b(no)g(initial)e(style)h(name)h(is)f (gi)n(v)o(en,)i(the)f(name)f Fd(default)i Fg(is)e(assigned.)63 b(Each)36 b(style)f(must)f(ha)n(v)o(e)i(a)0 2034 y(statement)24 b(of)h(the)f(form)900 2298 y Fd(scalefactor)h Fh(scale)g Fd([nanometers])146 2558 y Fg(to)33 b(indicate)f(the)h(output)f(scale)h (relati)n(v)o(e)f(to)h(Magic)g(units.)54 b(W)l(ithout)31 b(the)i(optional)f(k)o(e)o(yw)o(ord)g Fd(nanome-)0 2678 y(ters)p Fg(,)k Fh(scale)d Fg(describes)g(ho)n(w)g(man)o(y)f (hundredths)g(of)i(a)f(micron)g(correspond)g(to)g(one)g(unit)g(in)g (Magic.)56 b(W)l(ith)0 2798 y Fd(nanometers)26 b Fg(declared,)f Fh(scale)g Fg(describes)f(ho)n(w)g(man)o(y)g(nanometers)g(correspond)h (to)f(one)h(unit)f(in)g(Magic.)146 2923 y(Lik)o(e)39 b(the)f Fd(cif)n(output)i Fg(section,)i(each)d(style)f(consists)f(of)i (a)g(number)f(of)h(layer)g(descriptions.)71 b(A)39 b(layer)0 3044 y(description)23 b(contains)g(one)h(or)g(more)g(lines)f (describing)g(a)h(series)g(of)g(geometric)f(operations)g(to)h(be)g (performed)0 3164 y(on)f(CIF)i(layers.)30 b(The)24 b(result)f(of)g(all) g(these)h(operations)e(is)h(painted)g(on)h(a)f(particular)h(Magic)f (layer)h(just)e(as)i(if)f(the)0 3284 y(user)h(had)f(painted)g(that)g (information)f(by)h(hand.)30 b(A)24 b(layer)g(description)e(be)o(gins)g (with)h(a)h(statement)e(of)i(the)f(form)900 3548 y Fd(lay)o(er)i Fh(ma)o(gicLayer)g Fg([)p Fh(layer)o(s)p Fg(])146 3808 y(In)g(the)f Fd(lay)o(er)g Fg(statement,)f Fh(ma)o(gicLayer)i Fg(is)f(the)g(Magic)g(layer)g(that)g(will)g(be)g(painted)g(after)h (performing)e(the)0 3928 y(geometric)31 b(operations,)i(and)f Fh(layer)o(s)f Fg(is)h(an)g(optional)f(list)f(of)i(CIF)h(layers.)52 b(If)33 b Fh(layer)o(s)e Fg(is)h(speci\002ed,)h(it)f(is)f(the)0 4048 y(initial)26 b(v)n(alue)i(for)g(the)f(layer)h(being)g(b)n(uilt)e (up.)40 b(If)28 b Fh(layer)o(s)f Fg(isn')n(t)g(speci\002ed,)i(the)f (layer)g(starts)f(of)n(f)h(empty)-6 b(.)38 b(As)27 b(in)0 4169 y(the)22 b Fd(cif)n(output)g Fg(section,)g(each)h(line)e(after)h (the)g Fh(layer)f Fg(statement)g(gi)n(v)o(es)f(a)j(geometric)e (operation)g(that)g(is)h(applied)0 4289 y(to)g(the)g(pre)n(vious)f (contents)h(of)g(the)h(layer)f(being)g(b)n(uilt)f(in)h(order)h(to)f (generate)h(ne)n(w)f(contents)g(for)g(the)g(layer)-5 b(.)30 b(The)0 4409 y(result)24 b(of)h(the)g(last)f(geometric)g (operation)h(is)f(painted)g(into)g(the)h(Magic)f(database.)146 4534 y(The)c(geometric)g(operations)f(that)h(are)h(allo)n(wed)e(in)h (the)g Fd(ci\002nput)h Fg(section)f(are)h(a)f(subset)f(of)i(those)e (permitted)0 4655 y(in)24 b(the)h Fd(cif)n(output)h Fg(section:)900 4918 y Fd(or)f Fh(layer)o(s)900 5039 y Fd(and)h Fh(layer)o(s)900 5159 y Fd(and-not)g Fh(layer)o(s)900 5280 y Fd(gr)n(o)o(w)f Fh(amount)900 5400 y Fd(shrink)h Fh(amount)1850 5649 y Fg(\22626\226)p eop end %%Page: 27 27 TeXDict begin 27 26 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)146 68 y(In)33 b(these)f(commands)f(the)h Fh(layer)o(s)g Fg(must)f(all)h(be)g(CIF)i (layers,)g(and)e(the)g Fh(amounts)f Fg(are)i(all)f(CIF)i(distances)0 189 y(\(centimicrons,)22 b(unless)f(the)i(k)o(e)o(yw)o(ord)e Fd(nanometers)j Fg(has)e(been)h(used)f(in)g(the)h Fd(scalefactor)g Fg(speci\002cation\).)29 b(As)0 309 y(with)21 b(the)h Fd(cif)n(output)g Fg(section,)g(layers)g(can)g(only)f(be)h(speci\002ed) f(in)h(simple)e(comma-separated)i(lists:)27 b(tildes)21 b(and)0 429 y(slashes)j(are)i(not)e(permitted.)146 550 y(When)d(CIF)i(\002les)e(are)h(read,)g(all)f(the)g(mask)f(information)g (is)h(read)g(for)h(a)f(cell)g(before)h(performing)e(an)o(y)h(of)g(the)0 670 y(geometric)29 b(processing.)44 b(After)30 b(the)f(cell)g(has)h (been)g(completely)e(read)i(in,)g(the)f(Magic)h(layers)f(are)h (produced)0 790 y(and)j(painted)f(in)g(the)h(order)g(the)o(y)f(appear)h (in)f(the)h(technology)e(\002le.)55 b(In)33 b(general,)i(the)d(order)h (that)g(the)f(layers)0 911 y(are)d(processed)f(is)f(important)g(since)h (each)g(layer)g(will)g(usually)e(o)o(v)o(erride)i(the)f(pre)n(vious)g (ones.)40 b(F)o(or)28 b(e)o(xample,)0 1031 y(in)36 b(the)g(scmos)f (tech)h(\002le)g(sho)n(wn)f(in)h(T)-8 b(able)36 b(10)g(the)g(commands)e (for)j Fd(ndiff)g Fg(will)e(result)g(in)h(the)g Fd(ndiff)h Fg(layer)0 1152 y(being)29 b(generated)g(not)g(only)g(where)g(there)h (is)f(only)f(ndif)n(fusion)g(b)n(ut)g(also)h(where)h(there)f(are)h (ntransistors)e(and)0 1272 y(ndcontacts.)46 b(The)31 b(descriptions)e(for)h Fd(ntransistor)h Fg(and)f Fd(ndcontact)i Fg(appear)f(later)g(in)f(the)g(section,)h(so)f(those)0 1392 y(layers)25 b(will)f(replace)h(the)g Fd(ndiff)h Fg(material)e(that)g(w)o(as)h(originally)f(painted.)146 1513 y(Labels)h(are)g(handled)g(in)f(the)h Fd(ci\002nput)h Fg(section)e(just)g(lik)o(e)h(in)f(the)h Fd(cif)n(output)h Fg(section.)k(A)24 b(line)h(of)g(the)f(form)900 1739 y Fd(labels)g Fh(layer)o(s)146 1966 y Fg(means)29 b(that)f(the)h (current)g(Magic)g(layer)g(is)f(to)h(recei)n(v)o(e)g(all)f(CIF)i (labels)f(on)f Fh(layer)o(s)p Fg(.)43 b(This)28 b(is)h(actually)f(just) 0 2086 y(an)f(initial)f(layer)h(assignment)e(for)i(the)g(labels.)37 b(Once)27 b(a)g(CIF)h(cell)f(has)g(been)g(read)g(in,)g(Magic)g(scans)g (the)f(label)0 2207 y(list)g(and)g(re-assigns)g(labels)h(if)f (necessary)-6 b(.)36 b(In)27 b(the)f(e)o(xample)g(of)h(T)-8 b(able)27 b(10,)f(if)h(a)g(label)f(is)h(attached)f(to)g(the)h(CIF)0 2327 y(layer)e(CPG)g(then)f(it)f(will)h(be)g(assigned)g(to)f(the)i (Magic)e(layer)i Fd(poly)p Fg(.)30 b(Ho)n(we)n(v)o(er)l(,)23 b(the)h(polysilicon)f(may)h(actually)0 2447 y(be)f(part)h(of)f(a)h (poly-metal)e(contact,)h(which)g(is)f(Magic)h(layer)h Fd(pcontact)p Fg(.)31 b(After)24 b(all)f(the)g(mask)f(information)g (has)0 2568 y(been)32 b(processed,)i(Magic)e(checks)h(the)f(material)g (underneath)g(the)g(layer)l(,)i(and)e(adjusts)f(the)i(label')-5 b(s)31 b(layer)h(to)0 2688 y(match)c(that)h(material)f(\()p Fd(pcontact)j Fg(in)d(this)g(case\).)43 b(This)29 b(is)f(the)h(same)f (as)h(what)g(w)o(ould)f(happen)g(if)h(a)g(designer)0 2809 y(painted)24 b Fd(poly)h Fg(o)o(v)o(er)f(an)h(area,)g(attached)g (a)g(label)g(to)f(the)h(material,)f(then)h(painted)f Fd(pcontact)i Fg(o)o(v)o(er)e(the)h(area.)146 2929 y(No)k(hierarchical) g(mask)g(processing)f(is)g(done)h(for)g(CIF)h(input.)43 b(Each)29 b(cell)g(is)f(read)i(in)e(and)h(its)f(layers)h(are)0 3049 y(processed)c(independently)f(from)h(all)g(other)g(cells;)g(Magic) f(assumes)h(that)g(there)g(will)f(not)h(be)g(an)o(y)g(unpleasant)0 3170 y(interactions)k(between)h(cells)g(as)h(happens)e(in)h(CIF)i (output)d(\(and)h(so)g(f)o(ar)l(,)i(at)e(least,)h(this)f(seems)g(to)f (be)i(a)f(v)n(alid)0 3290 y(assumption\).)146 3410 y(If)22 b(Magic)g(encounters)f(a)h(CIF)h(layer)f(name)g(that)f(doesn')n(t)g (appear)i(in)e(an)o(y)g(of)h(the)f(lines)g(for)h(the)g(current)g(CIF)0 3531 y(input)28 b(style,)i(it)f(issues)f(a)i(w)o(arning)f(message)g (and)h(ignores)e(the)i(information)e(associated)h(with)f(the)h(layer)-5 b(.)45 b(If)0 3651 y(you)25 b(w)o(ould)g(lik)o(e)g(Magic)h(to)f(ignore) g(certain)h(layers)g(without)e(issuing)h(an)o(y)g(w)o(arning)g (messages,)g(insert)h(a)g(line)0 3772 y(of)f(the)g(form)900 3998 y Fd(ignor)n(e)g Fh(cifLayer)o(s)146 4225 y Fg(where)h Fh(cifLayer)o(s)e Fg(is)h(a)g(comma-separated)f(list)g(of)h(one)g(or)g (more)f(CIF)i(layer)f(names.)146 4345 y(Calma)37 b(layers)f(are)h (speci\002ed)f(via)g Fd(calma)g Fg(lines,)i(which)e(should)f(appear)i (at)f(the)g(end)g(of)g(the)g Fd(ci\002nput)0 4465 y Fg(section.)30 b(The)o(y)24 b(are)i(of)f(the)f(form:)900 4692 y Fd(calma)g Fh(cifLayer)h(calmaLayer)o(s)g(calmaT)-7 b(ypes)146 4918 y Fg(The)25 b Fh(cifLayer)g Fg(is)g(one)g(of)g(the)f(CIF)i(types)f (mentioned)e(in)i(the)g Fd(ci\002nput)h Fg(section.)31 b(Both)24 b Fh(calmaLayer)o(s)h Fg(and)0 5039 y Fh(calmaT)-7 b(ypes)32 b Fg(are)g(one)g(or)g(more)g(comma-separated)g(inte)o(gers)f (between)h(0)f(and)h(63.)52 b(The)32 b(interpretation)f(of)0 5159 y(a)k Fd(calma)f Fg(line)g(is)g(that)h(an)o(y)f(Calma)g(geometry)g (whose)h(layer)f(is)h(an)o(y)f(of)g(the)h(layers)f(in)g Fh(calmaLayer)o(s)p Fg(,)j(and)0 5280 y(whose)22 b(type)f(is)h(an)o(y)f (of)h(the)g(types)g(in)f Fh(calmaT)-7 b(ypes)p Fg(,)22 b(should)f(be)h(treated)g(as)g(the)g(CIF)h(layer)g Fh(cifLayer)p Fg(.)29 b(Either)22 b(or)0 5400 y(both)j(of)i Fh(calmaLayer)o(s)f Fg(and)g Fh(calmaT)-7 b(ypes)26 b Fg(may)g(be)g(the)g(character)h Fd(*)f Fg(instead)g(of)g(a)h(comma-separated)f(list)f(of)1850 5649 y(\22627\226)p eop end %%Page: 28 28 TeXDict begin 28 27 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)0 68 y(inte)o(gers;)f(this)g (character)i(means)e Fh(all)g Fg(layers)h(or)g(types)f(respecti)n(v)o (ely)-6 b(.)29 b(It)23 b(is)h(commonly)e(used)h(for)h Fh(calmaT)-7 b(ypes)0 189 y Fg(to)24 b(indicate)h(that)f(the)h(Calma)g (type)f(of)h(a)g(piece)g(of)g(geometry)f(should)g(be)h(ignored.)146 309 y(Just)f(as)h(for)g(CIF)-8 b(,)25 b(Magic)f(also)h(issues)e(w)o (arnings)h(if)h(it)f(encounters)g(unkno)n(wn)f(Calma)i(layers)f(while)g (read-)0 430 y(ing)c(Stream)h(\002les.)29 b(If)21 b(there)f(are)h (layers)g(that)f(you')-5 b(d)20 b(lik)o(e)g(Magic)g(to)g(ignore)g (without)f(issuing)f(w)o(arnings,)j(assign)0 550 y(them)j(to)h(a)g (dummy)e(CIF)j(layer)f(and)g(ignore)f(the)h(CIF)h(layer)-5 b(.)0 892 y Fi(14)143 b(Lef)35 b(section)0 1116 y Fg(This)19 b(section)g(de\002nes)h(a)g(mapping)e(between)i(magic)f(layers)h(and)g (layers)f(that)h(may)f(be)h(found)f(in)g(LEF)h(and)g(DEF)0 1237 y(format)28 b(\002les.)40 b(W)l(ithout)27 b(the)h(section,)g (magic)f(cannot)h(read)h(a)f(LEF)g(or)g(DEF)h(\002le.)40 b(The)28 b(LEF)h(and)f(DEF)g(layer)0 1357 y(declarations)c(are)i (usually)e(simple)g(and)g(straightforw)o(ard)h(\(as)g(the)o(y)f (typically)f(de\002ne)j(metal)e(layers)h(only\),)f(so)0 1477 y(often)h(it)g(will)g(suf)n(\002ce)h(to)f(insert)g(a)g(plain)g(v)n (anilla)f Fd(lef)i Fg(section)f(into)f(a)i(technology)f(\002le)g(if)h (one)f(is)g(missing.)31 b(The)0 1598 y Fd(lef)24 b Fg(section)f(w)o(as) h(introduced)f(in)g(technology)g(\002le)h(format)g(28,)f(and)h(is)g (therefore)g(absent)f(from)h(all)g Fa(.tech27)0 1718 y Fg(technology)g(\002les.)31 b(All)24 b(of)h(the)f(statements)g(in)g (the)h Fd(lef)g Fg(section)f(ha)n(v)o(e)h(the)f(same)h(format:)900 1950 y Fd(lay)o(er)g Fh(ma)o(gic-type)f(lefdef-type)h Fg(.)15 b(.)g(.)900 2070 y Fd(cut)26 b Fh(ma)o(gic-type)e(lefdef-type)h Fg(.)15 b(.)g(.)900 2190 y Fd(r)n(oute)p Fe(j)p Fd(r)n(outing)26 b Fh(ma)o(gic-type)f(lefdef-type)f Fg(.)15 b(.)g(.)900 2311 y Fd(obstruction)26 b Fh(ma)o(gic-type)f(lefdef-type)f Fg(.)15 b(.)g(.)900 2431 y Fd(masterslice)25 b Fh(ma)o(gic-type)f (lefdef-type)h Fg(.)15 b(.)g(.)900 2551 y Fd(o)o(v)o(erlap)25 b Fh(ma)o(gic-type)f(lefdef-type)h Fg(.)15 b(.)g(.)146 2782 y(Each)21 b(statement)e(de\002nes)i(a)g(mapping)e(between)h(a)h (Magic)f(layer)h(type)f Fh(ma)o(gic-type)g Fg(and)g(one)h(or)f(more)g (type)0 2903 y(names)k Fh(lefdef-type)g Fg(\(space-separated\))h(that)f (might)f(be)h(encountered)g(in)g(a)h(LEF)f(or)h(DEF)f(\002le.)31 b(The)24 b(dif)n(ferent)0 3023 y(command)e(names)h(all)g(refer)h(to)f (dif)n(ferent)f(type)h(classes)g(de\002ned)g(by)g(the)g(LEF/DEF)g (speci\002cation.)30 b(F)o(or)23 b(most)0 3144 y(purposes,)k(it)h(is)f (only)g(necessary)g(to)h(use)f(the)h Fd(lay)o(er)f Fg(statement.)38 b(If)28 b(the)g(magic)f(type)g(is)g(a)h(contact)g(type,)f(then)0 3264 y(the)e Fd(lay)o(er)f Fg(statement)g(is)g(equi)n(v)n(alent)f(to)i (specifying)f Fd(cut)p Fg(;)h(otherwise,)f(it)h(is)f(equi)n(v)n(alent)f (to)h Fd(r)n(oute)p Fg(.)146 3385 y(T)-8 b(able)31 b(11)e(is)h(a)h (typical)e Fd(lef)i Fg(section)e(for)i(a)f(5-metal)g(technology)-6 b(,)30 b(which)g(encompasses)f(the)h(most)f(com-)0 3505 y(monly)24 b(used)g(layer)h(names)g(found)f(in)g(LEF)h(and)g(DEF)g (\002les.)0 3847 y Fi(15)143 b(Mzr)m(outer)35 b(section)0 4071 y Fg(This)h(section)h(de\002nes)g(the)g(layers)g(and)g(contacts)g (a)n(v)n(ailable)f(to)h(the)g(Magic)f(maze)i(router)l(,)i Fh(mzr)l(outer)p Fg(,)e(and)0 4192 y(assigns)27 b(def)o(ault)h(costs)f (for)i(each)f(type.)41 b(Def)o(ault)28 b(widths)e(and)j(spacings)e(are) i(deri)n(v)o(ed)e(from)h(the)f Fd(dr)n(c)j Fg(section)0 4312 y(of)36 b(the)g(technology)f(\002le)h(\(described)h(belo)n(w\))e (b)n(ut)g(can)i(be)f(o)o(v)o(erridden)f(in)g(this)h(section.)63 b(Other)36 b(mzrouter)0 4433 y(parameters,)21 b(for)e(e)o(xample,)h (search)g(rate)g(and)g(width,)f(can)h(also)f(be)h(speci\002ed)g(in)f (this)g(section.)28 b(The)19 b(syntax)g(and)0 4553 y(function)k(of)i (the)e(lines)h(in)g(the)g Fd(mzr)n(outer)h Fg(section)f(of)g(the)g (technology)f(\002le)i(are)f(speci\002ed)h(in)f(the)g(subsections)0 4673 y(belo)n(w)-6 b(.)36 b(Each)28 b(set)f(of)g(speci\002cations)g (should)f(be)h(headed)h(by)e(a)i Fd(style)f Fg(line.)37 b Fd(Routelay)o(er)28 b Fg(and)f Fd(r)n(outecontact)0 4794 y Fg(speci\002cations)d(should)g(precede)i(references)g(to)e (them.)0 5091 y Ff(15.1)119 b(Styles)0 5280 y Fg(The)34 b(mzrouter)g(is)f(currently)h(used)g(in)f(tw)o(o)h(conte)o(xts,)h (interacti)n(v)o(ely)d(via)i(the)g Fd(ir)n(oute)g Fg(command,)i(and)e (as)g(a)0 5400 y(subroutine)29 b(to)h(the)g(garouter)f(for)i(stem)e (generation.)46 b(T)-8 b(o)30 b(permit)g(distinct)e(parameters)j(for)f (these)g(tw)o(o)g(uses,)1850 5649 y(\22628\226)p eop end %%Page: 29 29 TeXDict begin 29 28 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)p 307 3 3287 4 v 305 124 4 121 v 357 88 a Fd(lef)p 3591 124 V 305 244 V 611 208 a Fg(masterslice)99 b(ndif)n(f)279 b(dif)n(fusion)97 b(acti)n(v)o(e)p 3591 244 V 305 364 V 611 328 a(masterslice)i(poly)293 b(poly)278 b(POL)-10 b(Y1)255 b(pl)p 3591 364 V 305 485 V 611 449 a(routing)k(m1)343 b(m1)328 b(metal1)283 b(MET)-9 b(AL1)98 b(MET)-9 b(AL)p 3465 449 30 4 v 35 w(1)p 3591 485 4 121 v 305 605 V 611 569 a(routing)259 b(m2)343 b(m2)328 b(metal2)283 b(MET)-9 b(AL2)98 b(MET)-9 b(AL)p 3465 569 30 4 v 35 w(2)p 3591 605 4 121 v 305 726 V 611 689 a(routing)259 b(m3)343 b(m3)328 b(metal3)283 b(MET)-9 b(AL3)98 b(MET)-9 b(AL)p 3465 689 30 4 v 35 w(3)p 3591 726 4 121 v 305 846 V 611 810 a(routing)259 b(m4)343 b(m4)328 b(metal4)283 b(MET)-9 b(AL4)98 b(MET)-9 b(AL)p 3465 810 30 4 v 35 w(4)p 3591 846 4 121 v 305 966 V 611 930 a(routing)259 b(m5)343 b(m5)328 b(metal5)283 b(MET)-9 b(AL5)98 b(MET)-9 b(AL)p 3465 930 30 4 v 35 w(5)p 3591 966 4 121 v 305 1087 V 3591 1087 V 305 1207 V 611 1171 a(cut)426 b(pc)377 b(cont1)234 b(pl-m1)p 3591 1207 V 305 1328 V 611 1291 a(cut)426 b(m2c)299 b(via1)284 b(cont2)333 b(VIA12)206 b(m1-m2)p 3591 1328 V 305 1448 V 611 1412 a(cut)426 b(m3c)299 b(via2)284 b(cont3)333 b(VIA23)206 b(m2-m3)p 3591 1448 V 305 1568 V 611 1532 a(cut)426 b(m4c)299 b(via3)284 b(cont4)333 b(VIA34)206 b(m3-m4)p 3591 1568 V 305 1689 V 611 1653 a(cut)426 b(m5c)299 b(via4)284 b(cont5)333 b(VIA45)206 b(m4-m5)p 3591 1689 V 305 1809 V 3591 1809 V 305 1929 V 611 1893 a(o)o(v)o(erlap)251 b(comment)99 b(o)o(v)o(erlap)159 b(O)-5 b(VERLAP)p 3591 1929 V 305 2050 V 357 2014 a Fd(end)p 3591 2050 V 307 2053 3287 4 v 1223 2212 a Fg(T)d(able)25 b(11:)30 b(A)25 b(plain)f(v)n(anilla)g(lef)h(section.)0 2585 y(the)e(lines)g(in)g(the)h Fd(mzr)n(outer)h Fg(section)e(are)h(grouped)f(into)g Fh(styles)p Fg(.)30 b(The)23 b(lines)g(pertaining)g(to)g(the)g(irouter) g(should)0 2705 y(be)i(preceded)g(by)900 2970 y Fd(style)g(ir)n(outer) 146 3229 y Fg(and)g(those)f(pertaining)g(to)h(the)f(garouter)h(should)e (be)i(preceded)h(by)e(the)h(speci\002cation)900 3494 y Fd(style)g(gar)n(outer)146 3753 y Fg(Other)i(styles)f(can)i(be)f (speci\002ed,)h(b)n(ut)e(are)i(currently)f(not)f(used.)38 b(T)-8 b(able)27 b(12)f(sho)n(ws)g(the)h(mzrouter)g(section)0 3874 y(from)e(the)f(scmos)g(technology)-6 b(.)0 4198 y Ff(15.2)119 b(Lay)o(ers)0 4395 y Fg(Layer)25 b(lines)e(de\002ne)i (the)f(route-layers)g(a)n(v)n(ailable)g(to)f(the)i(maze)f(router)g(in)g (that)g(style.)30 b(The)o(y)23 b(ha)n(v)o(e)h(the)g(follo)n(w-)0 4515 y(ing)g(form:)900 4779 y Fd(lay)o(er)h Fh(type)g(hCost)f(vCost)h (jo)o(gCost)f(hintCost)146 5039 y Fg(Here)39 b Fh(type)f Fg(is)f(the)h(name)g(of)g(the)f(tiletype)g(of)h(the)g(layer)g(and)g Fh(hCost)p Fg(,)i Fh(vCost)p Fg(,)i Fh(jo)o(gCost)37 b Fg(and)g Fh(hintCost)p Fg(,)0 5159 y(are)g(non-ne)o(gati)n(v)o(e)d (inte)o(gers)h(specifying)g(the)h(cost)g(per)h(unit)e(horizontal)g (distance,)k(cost)d(per)g(unit)g(v)o(ertical)0 5280 y(distance,)24 b(cost)h(per)g(jog,)g(and)g(cost)f(per)h(unit)g(area)h(of)f(de)n (viation)e(from)i(magnets,)f(respecti)n(v)o(ely)-6 b(.)29 b(Route)c(layers)0 5400 y(for)g(an)o(y)f(gi)n(v)o(en)g(style)g(must)f (lie)i(in)f(distinct)g(planes.)1850 5649 y(\22629\226)p eop end %%Page: 30 30 TeXDict begin 30 29 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)p 816 3 2268 4 v 814 124 4 121 v 866 88 a Fd(mzr)n(outer)p 3082 124 V 814 244 V 866 208 a Fg(style)307 b(irouter)p 3082 244 V 814 364 V 866 328 a(layer)297 b(m2)387 b(32)337 b(64)271 b(256)149 b(1)p 3082 364 V 814 485 V 866 449 a(layer)297 b(m1)387 b(64)337 b(32)271 b(256)149 b(1)p 3082 485 V 814 605 V 866 569 a(layer)297 b(poly)337 b(128)287 b(128)221 b(512)149 b(1)p 3082 605 V 814 726 V 866 689 a(contact)208 b(m2contact)99 b(metal1)165 b(metal2)99 b(1024)p 3082 726 V 814 846 V 866 810 a(contact)208 b(pcontact)177 b(metal1)165 b(poly)193 b(2056)p 3082 846 V 814 966 V 866 930 a(notacti)n(v)o(e)133 b(poly)337 b(pcontact)p 3082 966 V 814 1087 V 866 1051 a(style)307 b(garouter)p 3082 1087 V 814 1207 V 866 1171 a(layer)297 b(m2)387 b(32)337 b(64)271 b(256)149 b(1)p 3082 1207 V 814 1328 V 866 1291 a(layer)297 b(m1)387 b(64)337 b(32)271 b(256)149 b(1)p 3082 1328 V 814 1448 V 866 1412 a(contact)208 b(m2contact)99 b(metal1)165 b(metal2)99 b(1024)p 3082 1448 V 814 1568 V 866 1532 a Fd(end)p 3082 1568 V 816 1572 2268 4 v 886 1731 a Fg(T)-8 b(able)25 b(12:)30 b(Mzrouter)25 b(section)f(for)h(the)g (scmos)f(technology)-6 b(.)0 2114 y Ff(15.3)119 b(Contacts)0 2307 y Fg(Contact)30 b(lines)f(specify)g(the)g(route-contacts)h(a)n(v)n (ailable)e(to)i(the)f(mzrouter)g(in)h(the)f(current)h(style.)44 b(The)o(y)29 b(ha)n(v)o(e)0 2427 y(the)c(follo)n(wing)e(form:)900 2677 y Fd(contact)j Fh(type)f(r)l(outeLayer1)f(r)l(outeLayer2)g(cost) 146 2923 y Fg(Here)32 b Fh(type)e Fg(is)h(the)f(tiletype)g(of)h(the)f (contact,)i Fh(r)l(outeLayer1)e Fg(and)g Fh(r)l(outeLayer2)g Fg(are)i(the)e(tw)o(o)g(layers)h(con-)0 3044 y(nected)25 b(by)f(the)h(contact,)g(and)f Fh(cost)h Fg(is)f(a)h(nonne)o(gati)n(v)o (e)d(inte)o(ger)i(specifying)g(the)h(cost)f(per)h(contact.)0 3355 y Ff(15.4)119 b(Notacti)o(v)o(e)0 3548 y Fg(It)22 b(maybe)g(desirable)g(to)f(ha)n(v)o(e)h(a)h(layer)f(or)g(contact)g(a)n (v)n(ailable)f(to)h(the)g(maze)g(router)l(,)h(b)n(ut)e(def)o(ault)h(to) g(of)n(f,)g(i.e.,)h(not)0 3669 y(be)k(used)g(by)g(the)g(mzrouter)g (until)g(e)o(xplicitly)e(made)i(acti)n(v)o(e.)37 b(Route-types)27 b(\(route-layers)g(or)g(route-contacts\))0 3789 y(can)e(be)g(made)g(to) f(def)o(ault)h(to)f(of)n(f)h(with)f(the)h(follo)n(wing)d (speci\002cation:)900 4038 y Fd(notacti)o(v)o(e)j Fh(r)l(oute-type)f Fg(.)15 b(.)g(.)g([)p Fd(r)n(oute-typen)p Fg(])0 4350 y Ff(15.5)119 b(Sear)n(ch)0 4543 y Fg(The)25 b(search)g Fd(rate)p Fg(,)g Fd(width)p Fg(,)h(and)f Fd(penalty)g Fg(parameters)g(can)g(be)g(set)g(with)f(a)h(speci\002cation)f(of)h(the) g(form:)900 4792 y Fd(sear)n(ch)h Fh(r)o(ate)e(width)g(penalty)146 5039 y Fg(Here)30 b Fh(r)o(ate)e Fg(and)g Fh(width)g Fg(are)i(positi)n(v)o(e)c(inte)o(gers.)42 b(And)28 b Fh(penalty)g Fg(is)g(a)h(positi)n(v)o(e)e(rational)h(\(it)g(may)h (include)f(a)0 5159 y(decimal)j(point\).)51 b(See)33 b(the)e(irouter)h(tutorial)e(for)i(a)g(discussion)e(of)i(these)g (parameters.)52 b(\(Note)31 b(that)g Fd(penalty)0 5280 y Fg(is)g(a)i(\223wizardly\224)e(parameter)l(,)j(i.e.,)g(it)d(is)g (interacti)n(v)o(ely)f(set)i(and)g(e)o(xamined)e(via)i Fd(ir)n(oute)h(wizard)f Fg(not)f Fd(ir)n(oute)0 5400 y(sear)n(ch)p Fg(\).)h(If)25 b(no)g Fd(sear)n(ch)g Fg(line)g(is)f(gi)n (v)o(en)f(for)i(a)h(style,)e(the)g(o)o(v)o(erall)g(mzrouter)g(def)o (aults)h(are)g(used.)1850 5649 y(\22630\226)p eop end %%Page: 31 31 TeXDict begin 31 30 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)0 82 y Ff(15.6)119 b(W)n(idth)0 275 y Fg(Appropriate)32 b(widths)g(for)g(route-types)g (are)i(normally)d(deri)n(v)o(ed)h(from)g(the)g Fd(dr)n(c)i Fg(section)e(of)h(the)f(technology)0 395 y(\002le.)f(These)25 b(can)g(be)g(o)o(v)o(erridden)f(with)g(width)f(speci\002cations)i(of)g (the)f(follo)n(wing)f(form:)900 642 y Fd(width)i Fh(r)l(oute-type)f (width)146 887 y Fg(Here)i Fh(width)e Fg(is)h(a)g(positi)n(v)o(e)d (inte)o(ger)-5 b(.)0 1197 y Ff(15.7)119 b(Spacing)0 1389 y Fg(Minimum)29 b(spacings)h(between)h(routing)f(on)g(a)h(route-type)g (and)g(other)g(types)f(are)i(deri)n(v)o(ed)d(from)i(the)g(design)0 1510 y(rules.)41 b(These)29 b(v)n(alues)e(can)i(be)g(o)o(v)o(erridden)e (by)h(e)o(xplicit)f(spacing)h(speci\002cations)g(in)g(the)g Fd(mzr)n(outer)i Fg(section.)0 1630 y(Spacing)25 b(speci\002cations)f (ha)n(v)o(e)h(the)f(follo)n(wing)f(form:)900 1877 y Fd(spacing)i Fh(r)l(outetype)f(type1)g(spacing1)49 b Fg(.)15 b(.)g(.)g([)p Fh(typen)24 b(spacingn)p Fg(])146 2122 y(Spacing)g(v)n(alues)e(must)h (be)g(nonne)o(gati)n(v)o(e)e(inte)o(gers)h(or)i Fd(NIL)p Fg(.)g(The)f(special)g(type)g Fd(SUBCELL)j Fg(can)e(be)f(used)0 2242 y(to)h(specify)h(minimum)d(spacing)j(to)f(une)o(xpanded)g (subcells.)0 2596 y Fi(16)143 b(Dr)m(c)35 b(section)0 2825 y Fg(The)20 b(design)g(rules)g(used)g(by)g(Magic')-5 b(s)20 b(design)f(rule)i(check)o(er)g(come)f(entirely)g(from)g(the)g (technology)f(\002le.)30 b(W)-8 b(e')o(ll)0 2945 y(look)23 b(\002rst)h(at)g(tw)o(o)f(simple)g(kinds)f(of)i(rules,)g Fd(width)g Fg(and)g(and)g Fd(spacing)p Fg(.)30 b(Most)23 b(of)h(the)f(rules)h(in)f(the)h Fd(dr)n(c)h Fg(section)0 3066 y(are)h(one)e(or)h(the)g(other)f(of)h(these)g(kinds)f(of)h(rules.) 0 3376 y Ff(16.1)119 b(W)n(idth)30 b(rules)0 3568 y Fg(The)c(minimum)f (width)g(of)i(a)f(collection)g(of)g(types,)h(tak)o(en)f(together)l(,)g (is)g(e)o(xpressed)g(by)g(a)h Fd(width)g Fg(rule.)36 b(Such)27 b(a)0 3688 y(rule)e(has)g(the)f(form:)900 3935 y Fd(width)h Fh(type-list)f(width)h(err)l(or)146 4180 y Fg(where)33 b Fh(type-list)d Fg(is)i(a)g(set)f(of)h(tile)f(types)g (\(see)h(Section)g(8)g(for)g(syntax\),)g Fh(width)g Fg(is)f(an)h(inte)o (ger)l(,)g(and)g Fh(err)l(or)0 4300 y Fg(is)27 b(a)g(string,)g (enclosed)g(in)g(double)g(quotes,)g(that)g(can)g(be)h(printed)f(by)g (the)g(command)f Fd(:dr)n(c)j(wh)o(y)e Fg(if)g(the)g(rule)h(is)0 4421 y(violated.)j(A)25 b(width)f(rule)h(requires)h(that)e(all)h(re)o (gions)f(containing)g(an)o(y)h(types)f(in)h(the)g(set)g Fh(types)g Fg(must)f(be)h(wider)0 4541 y(than)f Fh(w)i Fg(in)e(both)g(dimensions.)29 b(F)o(or)c(e)o(xample,)f(in)g(T)-8 b(able)25 b(14,)f(the)h(rule)900 4788 y Fd(width)g Fg(nwell)g(6)1489 4788 y (") show 1489 4788 a 60 w Fh(N-W)-9 b(ell)25 b(width)g(must)f(be)h(at)f (least)g(6)h(\(MOSIS)g(rule)f(#1.1\))3555 4788 y (") show 3555 4788 a 146 5033 a Fg(means)j(that)g(nwells)f(must)g(be)i(at)f(least)g (6)g(units)f(wide)h(whene)n(v)o(er)f(the)o(y)h(appear)-5 b(.)38 b(The)27 b Fh(type-list)f Fg(\002eld)h(may)0 5153 y(contain)d(more)h(than)f(a)h(single)f(type,)h(as)g(in)f(the)h(follo)n (wing)e(rule:)900 5400 y Fd(width)i Fg(allDif)n(f)g(2)1531 5400 y (") show 1531 5400 a 60 w Fh(Dif)n(fusion)e(width)h(must)g(be)h(at)g (least)f(2)h(\(MOSIS)f(rule)h(#2.1\))3693 5400 y (") show 3693 5400 a 1850 5649 a Fg(\22631\226)p eop end %%Page: 32 32 TeXDict begin 32 31 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)p 333 3 3234 4 v 331 124 4 121 v 383 88 a(#de\002ne)100 b(allDif)n(f)139 b(ndif)n(f,pdif)n(f,ndc/a,pdc/a,ppcont/a,nncont/a,pfet,nfet,psd,nsd)p 3565 124 V 331 244 V 383 208 a(#de\002ne)100 b(e)o(xtPoly)f(poly)-6 b(,pcontact)p 3565 244 V 331 364 V 383 328 a(#de\002ne)100 b(e)o(xtM1)143 b(metal1,pcontact/m1,ndc/m1,ppcont/m1,pdc/m)o(1,nn)o (cont/m)o(1)p 3565 364 V 331 485 V 383 449 a(#de\002ne)100 b(e)o(xtM2)143 b(metal2,m2contact/m2)p 3565 485 V 333 488 3234 4 v 1050 647 a(T)-8 b(able)25 b(13:)30 b(Abbre)n(viations)23 b(for)i(sets)f(of)h(tile)g(types.)p 316 877 3269 4 v 314 997 4 121 v 365 961 a(width)99 b(pwell)160 b(6)1223 961 y (") show 1223 961 a 60 w Fg(P-W)-8 b(ell)25 b(width)f(must)g(be)h(at)g (least)f(6)h(\(MOSIS)g(rule)g(#1.1\))3301 961 y (") show 3301 961 a 3583 997 4 121 v 314 1118 V 365 1082 a Fg(width)99 b(nwell)160 b(6)1223 1082 y (") show 1223 1082 a 60 w Fg(N-W)-8 b(ell)25 b(width)f(must)f(be)i(at)g(least)g(6)f(\(MOSIS)i(rule)f (#1.1\))3318 1082 y (") show 3318 1082 a 3583 1118 4 121 v 314 1238 V 365 1202 a Fg(width)99 b(allDif)n(f)118 b(2)1223 1202 y (") show 1223 1202 a 60 w Fg(Dif)n(fusion)23 b(width)h(must)g(be)h(at)g (least)f(2)h(\(MOSIS)g(rule)g(#2.1\))3406 1202 y (") show 3406 1202 a 3583 1238 4 121 v 314 1358 V 365 1322 a Fg(width)99 b(allPoly)g(2)1223 1322 y (") show 1223 1322 a 60 w Fg(Polysilicon)23 b(width)h(must)g(be)h(at)g(least)f(2)h(\(MOSIS)h(rule)e(#3.1\))3475 1322 y (") show 3475 1322 a 3583 1358 4 121 v 316 1362 3269 4 v 1026 1521 a Fg(T)-8 b(able)25 b(14:)30 b(Some)25 b(width)f(rules)h (in)f(the)h Fd(dr)n(c)h Fg(section.)146 1861 y(which)d(means)f(that)h (all)f(re)o(gions)g(consisting)f(of)i(the)f(types)h(containing)e(an)o (y)h(kind)g(of)h(dif)n(fusion)f(be)h(at)f(least)0 1982 y(2)33 b(units)f(wide.)55 b(Because)34 b(man)o(y)e(of)i(the)f(rules)f (in)h(the)g Fd(dr)n(c)h Fg(section)f(refer)h(to)f(the)f(same)h(sets)g (of)g(layers,)i(the)0 2102 y Fd(#de\002ne)25 b Fg(f)o(acility)e(of)h (the)g(C)g(preprocessor)g(is)f(used)g(to)h(de\002ne)g(a)g(number)f(of)h (macros)g(for)g(these)f(sets)g(of)h(layers.)0 2223 y(T)-8 b(able)25 b(13)f(gi)n(v)o(es)g(a)h(complete)f(list.)146 2343 y(All)h(of)f(the)h(layers)g(named)f(in)h(an)o(y)f(one)h(width)e (rule)i(must)f(lie)g(on)h(the)f(same)h(plane.)31 b(Ho)n(we)n(v)o(er)l (,)23 b(if)i(some)f(of)0 2463 y(the)g(layers)h(are)g(contacts,)f(Magic) g(will)g(substitute)e(a)j(dif)n(ferent)f(contact)g(image)g(if)h(the)f (named)g(image)g(isn')n(t)g(on)0 2584 y(the)h(same)f(plane)h(as)g(the)g (other)f(layers.)0 2878 y Ff(16.2)119 b(Spacing)31 b(rules)0 3066 y Fg(The)22 b(second)h(simple)e(kind)h(of)g(design)g(rule)g(is)h (a)f Fd(spacing)h Fg(rule.)30 b(It)22 b(comes)g(in)h(tw)o(o)f(\003a)n (v)n(ors:)29 b Fd(touching)p 3572 3066 30 4 v 37 w(ok)p Fg(,)23 b(and)0 3186 y Fd(touching)p 376 3186 V 37 w(illegal)p Fg(,)g(both)h(with)g(the)h(follo)n(wing)e(syntax:)900 3409 y Fd(spacing)i Fh(types1)f(types2)h(distance)f(\003avor)g(err)l (or)146 3631 y Fg(The)39 b(\002rst)f(\003a)n(v)n(or)l(,)k Fd(touching)p 1200 3631 V 37 w(ok)p Fg(,)f(does)d(not)g(prohibit)f Fh(types1)g Fg(and)h Fh(types2)g Fg(from)g(being)g(immediately)0 3751 y(adjacent.)52 b(It)32 b(merely)g(requires)g(that)g(an)o(y)f(type) h(in)g(the)f(set)h Fh(types1)g Fg(must)f(be)h(separated)g(by)g(a)g (\223Manhattan\224)0 3872 y(distance)27 b(of)g(at)g(least)g Fh(distance)g Fg(units)f(from)h(an)o(y)g(type)f(in)h(the)g(set)g Fh(types2)g Fg(that)g(is)g(not)g(immediately)e(adjacent)0 3992 y(to)i(the)h(\002rst)f(type.)39 b(See)29 b(Figure)e(16.2)g(for)h (an)g(illustration)d(of)j(Manhattan)f(distance)g(for)h(design)f(rules.) 39 b(As)27 b(an)0 4112 y(e)o(xample,)d(consider)g(the)h(metal1)f (separation)g(rule:)900 4335 y Fd(spacing)h Fg(allPoly)f(allPoly)g(2)h Fd(touching)p 2311 4335 V 37 w(ok)2472 4335 y /bksp 2 string def bksp 0 92 put bksp show 2472 4335 a 1200 4455 a (") show 1200 4455 a 60 w Fh(P)-8 b(olysilicon)23 b(spacing)h(must)g(be)h(at)f(least)g(2)h(\(MOSIS)g(rule)f(#3.2\))3521 4455 y (") show 3521 4455 a 146 4678 a Fg(This)31 b(rule)g(is)g(symmetric)f(\()p Fh(types1)h Fg(is)g(equal)g(to)g Fh(types2)p Fg(\),)i(and)e(requires,)i (for)f(e)o(xample,)g(that)f(a)g(pcontact)0 4798 y(be)g(separated)h(by)e (at)h(least)g(2)g(units)f(from)h(a)g(piece)h(of)f(polysilicon.)47 b(Ho)n(we)n(v)o(er)l(,)32 b(this)e(rule)h(does)g(not)f(pre)n(v)o(ent)0 4918 y(the)e(pcontact)g(from)h(touching)e(a)i(piece)g(of)f(poly)-6 b(.)41 b(In)28 b Fd(touching)p 2264 4918 30 4 v 37 w(ok)h Fg(rules,)g(all)f(of)h(the)f(layers)h(in)f(both)f Fh(types1)0 5039 y Fg(and)35 b Fh(types2)g Fg(must)g(be)g(stored)g(on)g(the)h(same) f(plane)g(\(Magic)g(will)g(substitute)e(dif)n(ferent)i(contact)g (images)g(if)0 5159 y(necessary\).)146 5280 y Fd(T)n(OUCHING)p 705 5280 V 35 w(OK)k(SP)-7 b(A)i(CING)38 b Fg(R)l(ULES)i(DO)g(NO)l(T)f (W)o(ORK)h(FOR)g(VER)-6 b(Y)40 b(LARGE)g(SP)-9 b(A)l(CINGS)0 5400 y(\(RELA)e(TIVE)32 b(T)n(O)f(THE)g(TYPES)h(INV)l(OL)-10 b(VED\).)31 b(SEE)h(FIGURE)g(6)f(FOR)i(AN)e(EXPLAN)m(A)-11 b(TION.)30 b(If)i(the)1850 5649 y(\22632\226)p eop end %%Page: 33 33 TeXDict begin 33 32 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)1170 1392 y @beginspecial 68 @llx 68 @lly 346 @urx 316 @ury 1872 @rwi @setspecial %%BeginDocument: ../psfigures/maint2.5.ps %!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.5.ps %%Creator: Xcircuit v2.0 %%CreationDate: Tue Apr 18 11:25:42 2000 %%Pages: 1 %%BoundingBox: 68 68 346 316 %%DocumentNeededResources: font Helvetica %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 691 480 offsets 1.0000 inchscale 2.6000 setlinewidth 0.745 0.600 0.871 scb 240 1.00 211 192 211 448 403 448 403 192 4 polygon 240 1.00 563 608 563 832 755 832 755 608 4 polygon sce 1 1.00 211 448 403 448 403 192 3 polygon 1 1.00 563 832 563 608 755 608 3 polygon 1 1.00 419 464 451 496 2 polygon 1 1.00 419 448 627 448 2 polygon 1 1.00 595 496 595 464 2 polygon 1.00 0 595 608 arrowhead 1.00 -181 595 448 arrowhead 1.00 135 403 448 arrowhead 1.00 -46 563 608 arrowhead 1 1.00 595 560 595 592 2 polygon 1 1.00 499 544 547 592 2 polygon (Manhattan distance) {/Helvetica 1.000 cf} 2 21 0 739 528 label (Euclidean distance) {/Helvetica 1.000 cf} 2 21 0 355 528 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF %%EndDocument @endspecial 0 1595 a(Figure)g(6:)31 b(F)o(or)25 b(design)f(rule)h (checking,)g(the)f(Manhattan)h(distance)f(between)h(tw)o(o)g (horizontally)e(or)i(v)o(ertically)0 1715 y(aligned)e(points)f(is)i (just)e(the)i(normal)f(Euclidean)g(distance.)30 b(If)24 b(the)o(y)f(are)h(not)f(so)h(aligned,)f(then)g(the)h(Manhattan)0 1836 y(distance)f(is)g(the)g(length)f(of)h(the)h(longest)e(side)h(of)g (the)g(right)g(triangle)f(forming)h(the)g(diagonal)f(line)h(between)g (the)0 1956 y(points.)p 85 2231 3730 4 v 83 2351 4 121 v 135 2315 a(spacing)99 b(allPoly)g(allPoly)262 b(2)100 b(touching)p 1972 2315 30 4 v 34 w(ok)2125 2315 y /bksp 2 string def bksp 0 92 put bksp show 2125 2315 a 3813 2351 4 121 v 83 2472 V 539 2436 a (") show 539 2436 a 60 w Fh(P)-8 b(olysilicon)23 b(spacing)h(must)g(be)h(at)g(least)f(2)g (\(MOSIS)h(rule)g(#3.2\))2861 2436 y (") show 2861 2436 a 3813 2472 4 121 v 83 2592 V 135 2556 a Fg(spacing)99 b(pfet)227 b(nncont,nnd)98 b(3)i(touching)p 1972 2556 30 4 v 34 w(ille)o(gal)2272 2556 y /bksp 2 string def bksp 0 92 put bksp show 2272 2556 a 3813 2592 4 121 v 83 2712 V 539 2676 a (") show 539 2676 a 60 w Fh(T)-5 b(r)o(ansistor)o(s)22 b(must)i(be)h(separ)o(ated)e(fr)l(om)h(substr)o(ate)f(contacts)h(by)h (3)f(\(MOSIS)h(rule)f(#4.1\))3705 2676 y (") show 3705 2676 a 3813 2712 4 121 v 83 2833 V 135 2797 a Fg(spacing)99 b(pc)288 b(allDif)n(f)281 b(1)100 b(touching)p 1972 2797 30 4 v 34 w(ille)o(gal)2272 2797 y /bksp 2 string def bksp 0 92 put bksp show 2272 2797 a 3813 2833 4 121 v 83 2953 V 539 2917 a (") show 539 2917 a 60 w Fh(P)-8 b(oly)25 b(contact)f(must)g(be)h(1)g(unit)e(fr)l(om)h(dif)n(fusion)f (\(MOSIS)i(rule)f(#5B.6\))3084 2917 y (") show 3084 2917 a 3813 2953 4 121 v 85 2957 3730 4 v 988 3116 a Fg(T)-8 b(able)24 b(15:)31 b(Some)24 b(spacing)h(rules)f(in)h(the)f Fd(dr)n(c)i Fg(section.)0 3522 y(spacing)32 b(to)g(be)h(check)o(ed)g(is)f(greater)h (than)g(the)f(width)g(of)g(one)h(of)g(the)f(types)g(in)l(v)n(olv)o(ed)f (plus)h(either)g(its)g(self-)0 3642 y(spacing)k(or)g(spacing)f(to)h(a)h (second)e(in)l(v)n(olv)o(ed)g(type,)j Fd(touching)p 2296 3642 30 4 v 37 w(ok)e(spacing)h Fg(may)f(not)f(w)o(ork)h(properly:)53 b(a)0 3762 y(violation)24 b(can)j(be)f(mask)o(ed)f(by)h(an)g(interv)o (ening)e(touching)h(type.)33 b(In)26 b(such)g(cases)g(the)g(rule)g (should)f(be)h(written)0 3883 y(using)e(the)g Fd(edge4way)h Fg(construct)g(described)f(belo)n(w)-6 b(.)146 4024 y(The)32 b(second)f(\003a)n(v)n(or)h(of)f(spacing)g(rule,)i Fd(touching)p 1940 4024 V 37 w(illegal)p Fg(,)e(disallo)n(ws)f(adjacenc)o(y)-6 b(.)49 b(It)32 b(is)f(used)g(for)g(rules)0 4145 y(where)25 b Fh(types1)g Fg(and)g Fh(types2)f Fg(can)h(ne)n(v)o(er)f(touch,)h(as)f (in)h(the)f(follo)n(wing:)900 4542 y Fd(spacing)h Fg(pc)g(allDif)n(f)f (1)h Fd(touching)p 2104 4542 V 36 w(illegal)2414 4542 y /bksp 2 string def bksp 0 92 put bksp show 2414 4542 a 1200 4663 a (") show 1200 4663 a 60 w Fh(P)-8 b(oly)24 b(contact)h(must)f(be)h(1)f(unit)g(fr)l(om)g(dif)n(fusion)f(\(MOSIS)i (rule)f(#5B.6\))3745 4663 y (") show 3745 4663 a 146 5039 a Fg(Pcontacts)j(and)f (an)o(y)g(type)h(of)f(dif)n(fusion)f(must)h(be)g(at)h(least)f(1)h(unit) e(apart;)j(the)o(y)d(cannot)i(touch.)35 b(In)27 b Fd(touch-)0 5159 y(ing)p 139 5159 30 4 v 36 w(illegal)d Fg(rules)i Fh(types1)f Fg(and)h Fh(types2)g Fg(may)f(not)h(ha)n(v)o(e)f(an)o(y)h (types)f(in)g(common:)32 b(it)25 b(w)o(ould)g(be)h(rather)g(strange)0 5280 y(not)32 b(to)h(permit)f(a)i(type)e(to)h(touch)g(itself.)54 b(In)33 b Fd(touching)p 1983 5280 V 37 w(illegal)f Fg(rules,)j Fh(types1)d Fg(and)h Fh(types2)g Fg(may)g(be)g(spread)0 5400 y(across)25 b(multiple)e(planes;)h(Magic)h(will)e(\002nd)i (violations)e(between)i(material)g(on)f(dif)n(ferent)g(planes.)1850 5649 y(\22633\226)p eop end %%Page: 34 34 TeXDict begin 34 33 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)975 1171 y @beginspecial 68 @llx 68 @lly 436 @urx 289 @ury 2340 @rwi @setspecial %%BeginDocument: ../psfigures/maint2.6.ps %!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.6.ps %%Creator: Xcircuit v2.0 %%CreationDate: Tue Apr 18 11:27:49 2000 %%Pages: 1 %%BoundingBox: 68 68 436 289 %%DocumentNeededResources: font Helvetica font Helvetica-Oblique %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 832 124 offsets 1.0000 inchscale 2.6000 setlinewidth 0.133 0.545 0.133 scb 240 1.00 192 252 192 700 384 700 384 252 4 polygon sce 0.439 1.000 0.314 scb 240 1.00 960 252 960 700 1152 700 1152 252 4 polygon 240 1.00 384 252 384 700 576 700 576 252 4 polygon sce 0 1.00 192 252 192 700 384 700 384 252 4 polygon 0 1.00 384 252 384 700 576 700 576 252 4 polygon 0 1.00 960 252 960 700 1152 700 1152 252 4 polygon (t1) {/Helvetica-Oblique 1.000 cf} 2 29 0 288 220 label (t2) {/Helvetica-Oblique 1.000 cf} 2 29 0 480 220 label (t2) {/Helvetica-Oblique 1.000 cf} 2 29 0 1056 220 label (A) {/Helvetica 1.000 cf} 2 25 0 384 732 label (B) {/Helvetica 1.000 cf} 2 25 0 1056 732 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF %%EndDocument @endspecial 0 1374 a(Figure)19 b(7:)27 b(The)19 b Fd(touching)p 934 1374 30 4 v 37 w(ok)g Fg(rules)g(cancels)g(spacing)f(checks)h(if)g (the)g(material)f(is)h(touching.)27 b(This)18 b(means)h(that)0 1495 y(e)n(v)o(en)26 b(distant)f(material)i(w)o(on')n(t)f(be)h(check)o (ed)g(for)g(spacing.)36 b(If)28 b(the)e(rule)h(applied)f(at)h(edge)g(A) f(is)h(a)g(touching)p 3772 1495 V 34 w(ok)0 1615 y(rule)33 b(between)g(material)f(t1)g(and)h(t2,)h(then)f(no)f(check)h(will)f(be)h (made)g(between)g(the)f(t1)h(material)f(and)h(the)f(t2)0 1736 y(material)23 b(on)g(the)h(f)o(ar)g(right)f(side)g(of)h(the)f (diagram.)30 b(If)24 b(this)e(check)i(w)o(as)g(desired,)f(it)g(could)g (be)h(accomplished)e(in)0 1856 y(this)h(case)h(by)f(a)h Fd(edge4way)f Fg(check)h(from)g(edge)f(B.)h(This)f(w)o(ould)g(not)g(w)o (ork)g(in)g(general,)h(though,)f(because)h(that)0 1976 y(check)h(could)g(also)f(be)h(mask)o(ed)f(by)h(material)f(of)h(type)f (t2,)h(causing)f(the)h(touching)p 2876 1976 V 34 w(ok)g(rule)g(to)f(be) h(in)l(v)n(ok)o(ed.)0 2355 y Ff(16.3)119 b(W)n(ide)30 b(material)f(spacing)i(rules)0 2544 y Fg(Man)o(y)22 b(f)o(abrications)h (processes)g(require)g(a)g(lar)n(ger)h(distance)f(between)g(layers)g (when)g(the)g(width)f(and)h(length)f(of)0 2665 y(one)29 b(of)f(those)g(layers)h(e)o(xceeds)g(a)f(certain)h(minimum)e (dimension.)40 b(F)o(or)29 b(instance,)g(a)g(process)f(might)f(declare) 0 2785 y(that)k(the)g(normal)g(spacing)g(between)g(metal1)g(lines)g(is) g(3)g(microns.)50 b(Ho)n(we)n(v)o(er)l(,)32 b(if)f(a)h(metal1)e(line)h (e)o(xceeds)h(a)0 2906 y(width)20 b(of)i(100)e(microns,)h(then)g(the)g (spacing)g(to)g(other)g(unrelated)g(metal1)f(lines)h(must)f(increase)h (to)g(10)g(microns.)0 3026 y(This)j(situation)f(is)i(co)o(v)o(ered)f (by)g(the)h Fd(widespacing)g Fg(rule.)31 b(The)25 b(syntax)f(for)h Fd(widespacing)g Fg(is)f(as)h(follo)n(ws:)900 3259 y Fd(widespacing)g Fh(types1)g(wwidth)g(types2)f(distance)g(\003avor)g (err)l(or)146 3492 y Fg(The)j Fd(widespacing)h Fg(rule)f(matches)g(the) f(syntax)h(of)g Fd(spacing)g Fg(in)g(all)f(respects)h(e)o(xcept)g(for)g (the)g(addition)f(of)0 3612 y(the)g(parameter)h Fh(wwidth)p Fg(,)g(which)f(declares)h(the)f(minimum)e(width)i(of)g(layers)h(of)f (type\(s\))h Fh(types1)f Fg(that)g(triggers)0 3732 y(the)d(rule.)31 b(So)24 b(for)f(the)h(e)o(xample)f(abo)o(v)o(e,)f(the)i(correct)g Fd(widespacing)g Fg(rule)g(w)o(ould)e(be)i(\(assuming)e(1)i(magic)f (unit)0 3853 y(=)i(1)g(micron\):)900 4086 y Fd(widespacing)g Fg(allMetal1)f(100)g(allMetal1)g(10)h Fd(touching)p 2934 4086 V 36 w(ok)3095 4086 y /bksp 2 string def bksp 0 92 put bksp show 3095 4086 a 1200 4206 a (") show 1200 4206 a 60 w Fh(Space)g(to)f(wide)h(Metal1)f(\(length)g(and)h(width)2903 4206 y (>) show 2903 4206 a 30 w Fh(100\))f(must)h(be)f(at)h(least)f(10)3888 4206 y (") show 3888 4206 a 0 4617 a Ff(16.4)119 b(Surr)n(ound)32 b(rule)0 4806 y Fg(The)20 b Fd(surr)n(ound)i Fg(rule)e(speci\002es)h (what)f(distance)f(a)i(layer)f(must)f(surround)g(another)l(,)i(and)f (whether)h(the)f(presence)0 4926 y(of)33 b(the)g(surrounding)f (material)h(is)g(optional)f(or)h(mandatory)-6 b(.)55 b(This)32 b(rule)h(is)g(designed)f(for)i(materials)f(which)0 5046 y(must)22 b Fh(completely)h Fg(surround)f(another)l(,)i(such)f(as) g(metal)g(around)g(a)g(contact)g(cut)g(or)h(MiM)e(capacitor)h(layer)-5 b(.)30 b(The)0 5167 y(syntax)24 b(is:)900 5400 y Fd(surr)n(ound)j Fh(types1)d(types2)h(distance)f(pr)l(esence)h(err)l(or)1850 5649 y Fg(\22634\226)p eop end %%Page: 35 35 TeXDict begin 35 34 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)390 1398 y @beginspecial 68 @llx 68 @lly 637 @urx 323 @ury 3744 @rwi @setspecial %%BeginDocument: ../psfigures/maint2.6b.ps %!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.6b.ps %%Creator: Xcircuit v2.5 %%CreationDate: Tue Jan 8 13:16:19 2002 %%Pages: 1 %%BoundingBox: 68 68 637 323 %%DocumentNeededResources: font Helvetica font Helvetica-Oblique %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.4 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--5/16/01 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.4 1 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /ul { dup type /stringtype eq showflag 1 eq and { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { dup type /stringtype eq showflag 1 eq and { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave currentpoint newpath moveto true charpath flattenpath pathbbox pop exch pop sub grestore } def /Ts {mark Tabs aload pop counttomark 1 add array astore /Tabs exch def Tabs 0 currentpoint pop put} def /Tbn {mark Tabs aload pop counttomark dup 2 add 1 roll cleartomark 1 sub} def /Tb { 0 1 Tbn {Tabs exch get dup currentpoint pop lt {currentpoint exch pop moveto exit} {pop} ifelse } for } def /Tf { Tbn -1 0 {Tabs exch get dup currentpoint pop gt {currentpoint exch pop moveto exit} {pop} ifelse } for } def /qS { (aa) stW (a a) stW sub 4 div 0 Kn } def /hS { qS qS } def /pspc 0 def /cf0 { scalefont setfont } bind def /Kn { dup kY add /kY exch def rmoveto } bind def /ss { /fscale fscale 0.67 mul def currentfont 0.67 cf0 0 fscale0 fscale mul 0.33 mul neg Kn} def /Ss { /fscale fscale 0.67 mul def currentfont 0.67 cf0 0 fscale0 fscale mul 0.67 mul Kn } def /ns { 0 kY neg Kn /kY 0 def /fscale 1.0 def xfont0 1.0 cf0 } def /CR { ns 0 /Bline Bline fscale0 neg add def Bline moveto } def /cf { dup type /realtype ne {1.0} if exch findfont exch kY 0 eq { 40 mul dup /fscale0 exch def cf0 /xfont0 currentfont def} {fscale0 mul fscale mul cf0} ifelse } def /ctmk { counttomark dup 2 add -1 roll pop } bind def /label { gsave translate 0 0 moveto dup scale neg /rotval exch def /just exch def just 16 and 0 gt {gsave rotval rotate 0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup abs 1e-9 lt {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse grestore {-1 /rotval rotval neg def /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch -1e-9 lt {-1 /rotval rotval neg def /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /showflag 0 def /fspc pspc def /Bline 0 def /Tabs 0 array def /fscale 1.0 def /kY 0 def gsave dup 1 add copy 0 exch 1 0 dtransform exch atan rotate {exch dup type /stringtype eq {true charpath flattenpath} {exec} ifelse } repeat pop pathbbox grestore 3 -1 roll pop 3 1 roll just 1 and 0 gt {just 2 and 0 gt {exch pop neg fspc sub} {exch sub 0.5 mul neg} ifelse} {pop neg fspc add} ifelse exch Bline exch just 4 and 0 gt {just 8 and 0 gt {exch pop neg fspc sub} {add 0.5 mul neg} ifelse} {pop neg fspc add} ifelse rotval rotate Kn currentpoint translate /showflag 1 def /Bline 0 def /Tabs 0 array def /fscale 1.0 def /kY 0 def {dup type /stringtype eq {show}{exec} ifelse} repeat grestore } def /pinlabel { 4 index 32 and 0 ne hlevel 0 eq or { /pspc 20 def label /pspc 0 def } { pop pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /scb { setrgbcolor } bind def /sce { defColor aload pop scb } bind def /cRedef {/defColor currentcolor 3 array astore def} def /begingate { /hlevel hlevel 1 add def /defColor currentcolor sce 3 array astore def gsave sce translate 0 0 moveto neg rotate dup abs scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore defColor aload pop cRedef scb} bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt style 512 eq or { newpath } { stroke } ifelse grestore } def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 0 0 scb cRedef } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox % trivial begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrowhead90 { % -20 -12 36 24 bbox % trivial begingate 1.00 270 -16 0 arrowhead endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 1024 186 offsets 1.0000 inchscale 2.6000 setlinewidth 0.494 0.753 0.933 scb 240 1.00 880 298 880 746 1264 746 1264 298 4 polygon 240 1.00 480 298 480 746 672 746 672 298 4 polygon 240 1.00 1360 298 1360 746 1552 746 1552 298 4 polygon sce 0 1.00 880 298 880 746 1264 746 1264 298 4 polygon 0 1.00 1360 298 1360 746 1552 746 1552 298 4 polygon 0 1.00 480 298 480 746 672 746 672 298 4 polygon (t1) {/Helvetica-Oblique cf} 2 29 0 1.00 1072 266 label (t2) {/Helvetica-Oblique cf} 2 29 0 1.00 1456 266 label (t2) {/Helvetica-Oblique cf} 2 29 0 1.00 576 266 label (A) {/Helvetica cf} 2 29 0 1.00 432 218 label (B) {/Helvetica cf} 2 29 0 1.00 1232 218 label 0.494 0.753 0.933 scb 240 1.00 192 298 192 746 384 746 384 298 4 polygon sce 0 1.00 192 298 192 746 384 746 384 298 4 polygon (t1) {/Helvetica-Oblique cf} 2 29 0 1.00 272 266 label 1 1.00 1264 826 1264 762 2 polygon 1 1.00 1424 762 1424 826 2 polygon 1 1.00 880 762 880 826 2 polygon 1 1.00 880 810 1424 810 2 polygon 1.00 0 896 810 arrowhead90 -1.00 0 1248 810 arrowhead90 -1.00 0 1408 810 arrowhead90 1.00 0 1280 810 arrowhead90 (wwidth) {/Helvetica-Oblique cf} 2 17 0 1.00 1056 826 label (wdist) {/Helvetica-Oblique cf} 2 17 0 1.00 1344 826 label 1.000 1.000 1.000 scb 1 1.00 1360 746 1424 682 2 polygon 1 1.00 1360 714 1424 650 2 polygon 1 1.00 1360 682 1424 618 2 polygon 1 1.00 1360 650 1424 586 2 polygon 1 1.00 1360 618 1424 554 2 polygon 1 1.00 1360 586 1424 522 2 polygon 1 1.00 1360 554 1424 490 2 polygon 1 1.00 1360 522 1424 458 2 polygon 1 1.00 1360 490 1424 426 2 polygon 1 1.00 1360 458 1424 394 2 polygon 1 1.00 1360 426 1424 362 2 polygon 1 1.00 1360 394 1424 330 2 polygon 1 1.00 1360 362 1424 298 2 polygon 1 1.00 1360 330 1392 298 2 polygon 1 1.00 1392 746 1424 714 2 polygon sce 1 1.00 1360 794 1360 762 2 polygon 1 1.00 1360 778 1488 778 2 polygon 1.00 0 1440 778 arrowhead90 1.00 0 1376 778 arrowhead90 (error area) {/Helvetica cf} 2 20 0 1.00 1504 778 label 1 1.00 480 762 480 826 2 polygon 1 1.00 384 810 480 810 2 polygon -1.00 0 464 810 arrowhead90 1.00 0 400 810 arrowhead90 (dist) {/Helvetica-Oblique cf} 2 17 0 1.00 432 826 label 1 1.00 384 826 384 762 2 polygon pgsave restore showpage %%Trailer XCIRCsave restore %%EOF %%EndDocument @endspecial 0 1602 a(Figure)g(8:)30 b(The)25 b Fd(widespacing)g Fg(rule)f(co)o(v)o(ers)g(situations)e(lik)o(e)j(that)f(sho)n(wn)f(abo)o (v)o(e,)g(in)i(which)f(material)g(of)g(type)0 1722 y Fh(t1)32 b Fg(normally)g(must)f(be)i Fh(dist)f Fg(units)f(a)o(w)o(ay)i (from)f(type)g Fh(t2)h Fg(\(situation)e(A\).)i(Ho)n(we)n(v)o(er)l(,)g (if)f(both)g(dimensions)f(of)0 1842 y(material)23 b(type)h Fh(t1)f Fg(are)i(lar)n(ger)f(than)g(or)g(equal)g(to)f(some)g(width)g Fh(wwidth)h Fg(\(situation)e(B\),)j(then)e(the)h(spacing)f(must)0 1963 y(be)i(increased)g(to)f Fh(wdist)p Fg(.)146 2304 y(and)29 b(states)f(that)g(the)h(layers)g(in)f Fh(types2)g Fg(must)g(surround)g(the)g(layers)h(in)f Fh(types1)h Fg(by)f(an)h(amound)f Fh(distance)0 2425 y Fg(lambda)d(units.)31 b(The)25 b(v)n(alue)g(of)g Fh(pr)l(esence)h Fg(must)e(be)i(one)f(of)g (the)g(k)o(e)o(yw)o(ords)g Fd(absence)p 2983 2425 30 4 v 37 w(ok)g Fg(or)h Fd(absence)p 3590 2425 V 36 w(illegal)p Fg(.)0 2545 y(When)33 b Fh(pr)l(esence)g Fg(is)g Fd(absence)p 1091 2545 V 37 w(illegal)p Fg(,)g(then)g(types)f Fh(types2)g Fg(must)g(al)o(w)o(ays)h(be)g(present)f(when)h(types)f Fh(types1)0 2665 y Fg(are)25 b(present.)31 b(When)24 b Fh(pr)l(esence)h Fg(is)f Fd(absence)p 1555 2665 V 37 w(ok)p Fg(,)h(types)e Fh(types1)h Fg(may)h(e)o(xist)e(outside)g(of)i (types)e Fh(types2)i Fg(without)0 2786 y(error)l(,)g(b)n(ut)g(where)g (the)o(y)f(coincide,)g(types)g Fh(types2)h Fg(must)f(o)o(v)o(erlap)f Fh(types1)i Fg(by)f(the)h(amount)f Fh(distance)p Fg(.)0 3080 y Ff(16.5)119 b(Ov)o(erhang)30 b(rule)0 3268 y Fg(rule)35 b(speci\002es)g(what)g(distance)g(a)g(layer)g(must)f(o)o(v)o(erhang)g (another)h(at)g(an)g(intersection.)60 b(This)34 b(is)h(used,)i(for)0 3388 y(e)o(xample,)23 b(to)h(specify)f(the)h(length)f(of)h(polysilicon) e(end-caps)i(on)f(transistors,)g(which)g(is)h(the)f(distance)h(that)f (the)0 3509 y(polysilicon)30 b(gate)i(must)f(e)o(xtend)g(be)o(yond)g (the)h(de\002ned)h(gate)f(area)h(of)f(the)g(transistor)f(to)h(ensure)g (a)h(correctly)0 3629 y(operating)24 b(de)n(vice.)31 b(The)24 b(syntax)g(is:)900 3852 y Fd(o)o(v)o(erhang)h Fh(types1)g(types2)f(distance)g(err)l(or)146 4075 y Fg(and)k(states)g (that)f(layers)h(in)f Fh(types1)h Fg(must)f(o)o(v)o(erhang)f(layers)i (in)g Fh(types2)f Fg(by)h(an)g(amount)f Fh(distance)g Fg(lambda)0 4196 y(units.)35 b(The)27 b(rule)g(\003ags)g(the)f (complete)g(absence)h(of)g(types)f Fh(types1)p Fg(,)h(b)n(ut)f(does)g (not)g(prohibit)g(the)g(use)h(of)f Fh(types1)0 4316 y Fg(as)g(a)h(bridge)f(\(that)g(is,)h(with)e(types)h Fh(types2)g Fg(on)g(either)h(side)f(of)g Fh(types1)p Fg(,)g(which)g(will)g (generally)g(be)h(co)o(v)o(ered)e(by)0 4436 y(a)g(separate)g(spacing)g (rule,)f(and)h(which)g(may)f(ha)n(v)o(e)h(a)g(dif)n(ferent)f(spacing)g (requirement\).)0 4731 y Ff(16.6)119 b(Rectangle-only)30 b(rule)0 4918 y Fg(The)35 b Fd(r)n(ect)p 359 4918 V 37 w(only)g Fg(rule)g(is)f(used)h(to)g(denote)f(layers)h(that)g(must)f(be) h(rectangular;)40 b(that)35 b(is,)i(the)o(y)d(cannot)g(bend,)0 5039 y(or)40 b(ha)n(v)o(e)g(notches)f(or)i(tabs.)76 b(Generally)-6 b(,)43 b(this)c(is)g(used)h(for)h(contacts,)i(so)d(that)f(the)h(CIF)h (output)e(operator)0 5159 y Fd(squar)n(es)31 b Fg(will)e(be)h (guaranteed)g(to)g(generate)g(a)g(correct)h(contact.)46 b(This)29 b(is)h(due)g(to)f(magic')-5 b(s)29 b(corner)n(-stitching)0 5280 y(tile)24 b(database,)h(where)g(bends,)f(notches,)f(tabs,)i(and)f (slots)f(will)h(break)h(up)f(an)h(otherwise)f(continuous)f(patch)h(of)0 5400 y(material)e(into)f(potentially)g(man)o(y)g(small)g(tiles,)h(each) h(one)g(of)f(which)g(might)f(be)h(too)g(small)f(to)h(\002t)h(a)f (contact)g(cut.)1850 5649 y(\22635\226)p eop end %%Page: 36 36 TeXDict begin 36 35 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)900 84 y Fd(r)n(ect)p 1069 84 30 4 v 37 w(only)h Fh(types)f(err)l(or)0 383 y Ff(16.7)119 b(Edge)30 b(rules)0 572 y Fg(The)j(width)f(and)i(spacing) e(rules)h(just)g(described)g(are)h(actually)e(translated)h(by)g(Magic)g (into)f(an)h(underlying,)0 692 y(edge-based)25 b(rule)g(format.)32 b(This)24 b(underlying)g(format)g(can)i(handle)f(rules)f(more)h (general)h(than)e(simple)g(widths)0 813 y(and)31 b(spacings,)h(and)f (is)g(accessible)g(to)g(the)g(writer)g(of)g(a)h(technology)e(\002le)i (via)f Fd(edge)h Fg(rules.)49 b(These)31 b(rules)g(are)0 933 y(applied)d(at)g(boundaries)g(between)h(material)f(of)g(tw)o(o)g (dif)n(ferent)g(types,)h(in)f(an)o(y)g(of)h(four)f(directions)g(as)g (sho)n(wn)0 1053 y(in)c(Figure)g(9.)30 b(The)24 b(design)f(rule)i (table)e(contains)g(a)i(separate)f(list)f(of)h(rules)g(for)g(each)h (possible)e(combination)f(of)0 1174 y(materials)i(on)h(the)f(tw)o(o)h (sides)f(of)h(an)g(edge.)1170 2819 y @beginspecial 68 @llx 68 @lly 412 @urx 400 @ury 1872 @rwi @setspecial %%BeginDocument: ../psfigures/maint2.7.ps %!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.7.ps %%Creator: Xcircuit v2.0 %%CreationDate: Tue Apr 18 11:32:42 2000 %%Pages: 1 %%BoundingBox: 68 68 412 400 %%DocumentNeededResources: font Helvetica-Oblique %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 704 544 offsets 1.0000 inchscale 2.6000 setlinewidth 0.745 0.600 0.871 scb 240 1.00 832 736 832 1056 1024 1056 1024 736 4 polygon 240 1.00 256 256 256 448 576 448 576 256 4 polygon 240 1.00 256 736 256 1056 448 1056 448 736 4 polygon 240 1.00 704 256 704 448 1024 448 1024 256 4 polygon sce 0 1.00 256 736 256 1056 448 1056 448 736 4 polygon 0 1.00 832 736 832 1056 1024 1056 1024 736 4 polygon 0 1.00 256 256 256 448 576 448 576 256 4 polygon 0 1.00 704 256 704 448 1024 448 1024 256 4 polygon 1 1.00 192 896 320 896 2 polygon 1 1.00 1088 896 960 896 2 polygon 1 1.00 416 192 416 320 2 polygon 1 1.00 864 512 864 384 2 polygon 1.00 0 416 336 arrowhead 1.00 -181 864 368 arrowhead 1.00 -271 944 896 arrowhead 1.00 270 336 896 arrowhead (t1) {/Helvetica-Oblique 1.000 cf} 2 25 0 224 928 label (t2) {/Helvetica-Oblique 1.000 cf} 2 25 0 288 928 label (t1) {/Helvetica-Oblique 1.000 cf} 2 25 0 1056 928 label (t2) {/Helvetica-Oblique 1.000 cf} 2 25 0 976 928 label (t1) {/Helvetica-Oblique 1.000 cf} 2 25 0 896 480 label (t2) {/Helvetica-Oblique 1.000 cf} 2 25 0 896 400 label (t1) {/Helvetica-Oblique 1.000 cf} 2 25 0 368 208 label (t2) {/Helvetica-Oblique 1.000 cf} 2 25 0 368 288 label (d) {/Helvetica-Oblique 1.000 cf} 2 21 0 352 688 label 1 1.00 256 720 256 672 2 polygon 1 1.00 448 720 448 672 2 polygon (d) {/Helvetica-Oblique 1.000 cf} 2 21 0 928 688 label 1 1.00 832 720 832 672 2 polygon 1 1.00 1024 720 1024 672 2 polygon (d) {/Helvetica-Oblique 1.000 cf} 2 21 0 208 352 label 1 1.00 240 448 192 448 2 polygon 1 1.00 240 256 192 256 2 polygon (d) {/Helvetica-Oblique 1.000 cf} 2 21 0 1072 352 label 1 1.00 1088 448 1040 448 2 polygon 1 1.00 1088 256 1040 256 2 polygon 1 1.00 1072 384 1072 432 2 polygon 1 1.00 1072 320 1072 272 2 polygon 1 1.00 208 384 208 432 2 polygon 1 1.00 208 320 208 272 2 polygon 1 1.00 272 688 320 688 2 polygon 1 1.00 384 688 432 688 2 polygon 1 1.00 848 688 896 688 2 polygon 1 1.00 960 688 1008 688 2 polygon 1.00 0 208 448 arrowhead 1.00 0 1072 448 arrowhead 1.00 -181 1072 256 arrowhead 1.00 -181 208 256 arrowhead 1.00 -271 256 688 arrowhead 1.00 -271 832 688 arrowhead 1.00 -91 1024 688 arrowhead 1.00 -91 448 688 arrowhead pgsave restore showpage %%Trailer XCIRCsave restore %%EOF %%EndDocument @endspecial 0 3023 a(Figure)g(9:)31 b(Design)24 b(rules)g(are)i (applied)e(at)h(the)g(edges)f(between)h(tiles)f(in)h(the)f(same)h (plane.)31 b(A)25 b(rule)f(is)h(speci\002ed)0 3143 y(in)h(terms)h(of)f (type)h Fh(t1)f Fg(and)h(type)f Fh(t2)p Fg(,)h(the)f(materials)g(on)h (either)f(side)h(of)g(the)f(edge.)37 b(Each)27 b(rule)f(may)h(be)g (applied)0 3263 y(in)22 b(an)o(y)f(of)i(four)f(directions,)g(as)g(sho)n (wn)f(by)h(the)g(arro)n(ws.)29 b(The)22 b(simplest)f(rules)h(require)g (that)g(only)f(certain)i(mask)0 3384 y(types)h(can)h(appear)h(within)d (distance)i Fh(d)f Fg(on)h Fh(t2)p Fg(')-5 b(s)24 b(side)g(of)h(the)g (edge.)146 3731 y(In)e(its)e(simplest)g(form,)i(a)f(rule)h(speci\002es) f(a)h(distance)f(and)g(a)h(set)f(of)g(mask)g(types:)29 b(only)22 b(the)g(gi)n(v)o(en)f(types)g(are)0 3851 y(permitted)i (within)g(that)h(distance)f(on)h Fh(type2)p Fg(')-5 b(s)24 b(side)f(of)h(the)g(edge.)31 b(This)23 b(area)i(is)f(referred)i(to)d (as)h(the)g Fh(constr)o(aint)0 3971 y(r)l(e)l(gion)p Fg(.)k(Unfortunately)-6 b(,)19 b(this)f(simple)g(scheme)i(will)e(miss)g (errors)i(in)e(corner)i(re)o(gions,)f(such)g(as)h(the)f(case)g(sho)n (wn)0 4092 y(in)29 b(Figure)g(10.)44 b(T)-8 b(o)29 b(eliminate)g(these) g(problems,)g(the)g(full)g(rule)g(format)g(allo)n(ws)f(the)h (constraint)g(re)o(gion)f(to)h(be)0 4212 y(e)o(xtended)c(past)h(the)g (ends)g(of)g(the)g(edge)h(under)f(some)f(circumstances.)35 b(See)27 b(Figure)f(11)g(for)h(an)f(illustration)e(of)0 4333 y(the)29 b(corner)h(rules)g(and)f(ho)n(w)g(the)o(y)f(w)o(ork.)45 b(T)-8 b(able)29 b(16)h(gi)n(v)o(es)e(a)h(complete)g(description)g(of)g (the)g(information)f(in)0 4453 y(each)d(design)f(rule.)146 4574 y(Edge)h(rules)g(are)g(speci\002ed)g(in)g(the)f(technology)g (\002le)h(using)f(the)h(follo)n(wing)d(syntax:)900 4807 y Fd(edge)k Fh(types1)e(types2)g(d)h(OKT)-7 b(ypes)26 b(cornerT)-7 b(ypes)24 b(cornerDist)g(err)l(or)f Fg([)p Fh(plane)p Fg(])146 5039 y(Both)30 b Fh(types1)f Fg(and)h Fh(types2)f Fg(are)h(type-lists.)44 b(An)30 b(edge)f(rule)h(is)f (generated)h(for)g(each)h(pair)e(consisting)f(of)i(a)0 5159 y(type)h(from)g Fh(types1)g Fg(and)g(a)h(type)e(from)h Fh(types2)p Fg(.)50 b(All)31 b(the)g(types)f(in)h Fh(types1)p Fg(,)i Fh(types2)p Fg(,)f(and)f Fh(cornerT)-7 b(ypes)31 b Fg(must)0 5280 y(lie)d(on)f(a)h(single)f(plane.)40 b(See)28 b(Figure)g(11)g(for)g(an)g(e)o(xample)f(edge)h(rule.)39 b(It)28 b(is)f(sometimes)f(useful)i(to)f(specify)h(a)0 5400 y(null)e(list,)h(i.e.,)h Fd(0)p Fg(,)g(for)f Fh(OKT)-7 b(ypes)28 b Fg(or)g Fh(CornerT)-7 b(ypes)p Fg(.)38 b(Null)27 b Fh(OKT)-7 b(ypes)27 b Fg(means)g(no)g(edges)h(between)f Fh(types1)g Fg(and)1850 5649 y(\22636\226)p eop end %%Page: 37 37 TeXDict begin 37 36 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)0 68 y Fh(types2)d Fg(are)h(OK.)f(Null)f Fh(CornerT)-7 b(ypes)22 b Fg(means)g(no)g(corner) h(e)o(xtensions)d(are)j(to)f(be)g(check)o(ed)h(\(corner)g(e)o (xtensions)0 188 y(are)j(e)o(xplained)d(belo)n(w\).)146 309 y(Some)i(of)f(the)g(edge)g(rules)g(in)g(Magic)g(ha)n(v)o(e)g(the)g (property)g(that)g(if)g(a)h(rule)f(is)g(violated)f(between)h(tw)o(o)g (pieces)0 429 y(of)35 b(geometry)-6 b(,)37 b(the)e(violation)e(can)j (be)f(disco)o(v)o(ered)f(looking)g(from)h(either)g(piece)g(of)g (geometry)g(to)n(w)o(ard)f(the)0 549 y(other)-5 b(.)39 b(T)-8 b(o)28 b(capitalize)g(on)f(this,)h(Magic)g(normally)e(applies)i (an)g(edge)g(rule)g(only)f(in)g(tw)o(o)h(of)g(the)f(four)h(possible)0 670 y(directions:)h(bottom-to-top)23 b(and)h(left-to-right,)g(reducing) g(the)h(w)o(ork)f(it)g(has)h(to)f(do)h(by)f(a)h(f)o(actor)g(of)g(tw)o (o.)30 b(Also,)0 790 y(the)g(corner)g(e)o(xtension)f(is)g(only)g (performed)h(to)g(one)f(side)h(of)g(the)g(edge:)40 b(to)30 b(the)g(top)f(for)h(a)g(left-to-right)f(rule,)0 911 y(and)22 b(to)g(the)f(left)h(for)g(a)h(bottom-to-top)c(rule.)30 b(All)22 b(of)g(the)f(width)g(and)h(spacing)g(rules)g(translate)f (neatly)h(into)f(edge)0 1031 y(rules.)146 1151 y(Ho)n(we)n(v)o(er)l(,) 31 b(you')o(ll)f(probably)g(\002nd)h(it)g(easiest)f(when)h(you')-5 b(re)31 b(writing)e(edge)i(rules)g(to)f(insist)g(that)g(the)o(y)g(be)0 1272 y(check)o(ed)21 b(in)f(all)h(directions.)28 b(T)-8 b(o)21 b(do)f(this,)g(write)h(the)f(rule)h(the)g(same)f(w)o(ay)h(e)o (xcept)f(use)h(the)f(k)o(e)o(yw)o(ord)g Fd(edge4way)0 1392 y Fg(instead)k(of)h Fd(edge)p Fg(:)900 1601 y Fd(edge4way)g Fg(nfet)g(ndif)n(f)f(2)h(ndif)n(f,ndc)e(ndif)n(f)i(2)2486 1601 y /bksp 2 string def bksp 0 92 put bksp show 2486 1601 a 1200 1721 a (") show 1200 1721 a 60 w Fh(Dif)n(fusion)e(must) h(o)o(verhang)g(tr)o(ansistor)e(by)j(at)f(least)h(2)3163 1721 y (") show 3163 1721 a 146 1929 a Fg(Not)33 b(only)g(are)h Fd(edge4way)f Fg(rules)g(check)o(ed)h(in)f(all)g(four)h(directions,)g (b)n(ut)f(the)g(corner)h(e)o(xtension)e(is)h(per)n(-)0 2050 y(formed)23 b(on)h Fh(both)f Fg(sides)g(of)g(the)h(edge.)30 b(F)o(or)24 b(e)o(xample,)f(when)g(checking)g(a)h(rule)g(from)f (left-to-right,)g(the)h(corner)0 2170 y(e)o(xtension)d(is)h(performed)g (both)g(to)g(the)g(top)g(and)h(to)f(the)g(bottom.)28 b Fd(Edge4way)23 b Fg(rules)g(tak)o(e)f(twice)g(as)h(much)f(time)0 2291 y(to)i(check)i(as)f Fd(edge)g Fg(rules,)g(so)f(it')-5 b(s)24 b(to)g(your)h(adv)n(antage)f(to)g(use)h Fd(edge)h Fg(rules)e(where)n(v)o(er)h(you)f(can.)146 2411 y(Normally)-6 b(,)22 b(an)i(edge)g(rule)f(is)g(check)o(ed)h(completely)f(within)f(a)i (single)e(plane:)30 b(both)23 b(the)g(edge)h(that)f(triggers)0 2531 y(the)d(rule)h(and)g(the)f(constraint)g(area)i(to)e(check)h(f)o (all)f(in)h(the)f(same)h(plane.)29 b(Ho)n(we)n(v)o(er)l(,)20 b(the)h Fh(plane)f Fg(ar)n(gument)g(can)h(be)0 2652 y(speci\002ed)27 b(in)f(an)h(edge)g(rule)g(to)f(force)h(Magic)g(to)f(perform)h(the)f (constraint)g(check)h(on)f(a)h(plane)g(dif)n(ferent)f(from)0 2772 y(the)g(one)h(containing)e(the)i(triggering)e(edge.)37 b(In)26 b(this)g(case,)h Fh(OKT)-7 b(ypes)28 b Fg(must)d(all)h(be)h (tile)f(types)g(in)g Fh(plane)p Fg(.)36 b(This)0 2893 y(feature)d(is)g(used,)h(for)f(e)o(xample,)h(to)e(ensure)h(that)f (polysilicon)f(and)i(dif)n(fusion)e(edges)i(don')n(t)f(lie)g (underneath)0 3013 y(metal2)24 b(contacts:)900 3221 y Fd(edge4way)h Fg(allPoly)f(\230\(allPoly\)/acti)n(v)o(e)g(1)g (\230m2c/metal2)g(\230\(allPoly\)/acti)n(v)o(e)f(1)3662 3221 y /bksp 2 string def bksp 0 92 put bksp show 3662 3221 a 585 4947 a @beginspecial 68 @llx 68 @lly 604 @urx 369 @ury 3276 @rwi @setspecial %%BeginDocument: ../psfigures/maint2.8.ps %!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.8.ps %%Creator: Xcircuit v2.0 %%CreationDate: Tue Apr 18 11:46:16 2000 %%Pages: 1 %%BoundingBox: 68 68 604 369 %%DocumentNeededResources: font Helvetica font Helvetica-Bold %%+ font Helvetica-Oblique %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 928 590 offsets 1.0000 inchscale 2.6000 setlinewidth 1.000 0.000 0.000 scb 240 1.00 832 270 832 590 1184 590 1184 270 4 polygon 240 1.00 1248 654 1248 974 1600 974 1600 654 4 polygon 240 1.00 192 270 192 590 320 590 320 270 4 polygon sce 0 1.00 320 270 320 590 512 590 512 270 4 polygon (space) {/Helvetica-Bold 1.000 cf} 2 21 0 416 430 label (poly) {/Helvetica-Bold 1.000 cf} 2 21 0 256 430 label (poly) {/Helvetica-Bold 1.000 cf} (= not ) {/Helvetica 1.000 cf} (OKTypes ) {/Helvetica-Oblique 1.000 cf} 6 25 0 416 686 label 1 1.00 416 670 416 558 2 polygon 1.00 -181 416 542 arrowhead (\(a\)) {/Helvetica 1.000 cf} 2 21 0 416 206 label 0 1.00 832 270 832 590 1184 590 1184 270 4 polygon 0 1.00 1248 654 1248 974 1600 974 1600 654 4 polygon 1 1.00 832 590 832 782 1184 782 1184 590 1376 590 1376 270 1184 270 7 polygon 1 1.00 1600 654 1600 462 1248 462 1248 654 1056 654 1056 974 1248 974 7 polygon (poly) {/Helvetica-Bold 1.000 cf} 2 21 0 1424 830 label (poly) {/Helvetica-Bold 1.000 cf} 2 21 0 992 430 label (\(b\)) {/Helvetica 1.000 cf} 2 21 0 1216 206 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF %%EndDocument @endspecial 0 5150 a Fg(Figure)36 b(10:)52 b(If)36 b(only)f(the)g (simple)g(rules)g(from)g(Figure)h(9)g(are)g(used,)i(errors)e(may)f(go)h (unnoticed)e(in)i(corner)0 5271 y(re)o(gions.)30 b(F)o(or)24 b(e)o(xample,)g(the)h(polysilicon)e(spacing)h(rule)h(in)f(\(a\))i(will) e(f)o(ail)g(to)h(detect)f(the)h(error)h(in)e(\(b\).)1850 5649 y(\22637\226)p eop end %%Page: 38 38 TeXDict begin 38 37 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)488 2397 y @beginspecial 68 @llx 68 @lly 583 @urx 490 @ury 3510 @rwi @setspecial %%BeginDocument: ../psfigures/maint2.9.ps %!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.9.ps %%Creator: Xcircuit v2.0 %%CreationDate: Tue Apr 18 12:02:16 2000 %%Pages: 1 %%BoundingBox: 68 68 583 490 %%DocumentNeededResources: font Helvetica font Helvetica-Bold %%+ font Helvetica-Oblique %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrowhead90 { % -20 -12 36 24 bbox begingate 1.00 90 -16 0 arrowhead endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 1150 782 offsets 1.0000 inchscale 2.6000 setlinewidth 0.800 0.800 0.800 scb 240 1.00 478 1166 478 1230 542 1230 542 1166 4 polygon sce 0.898 0.898 0.898 scb 240 1.00 542 1166 542 1294 670 1294 670 1166 4 polygon sce 0.800 0.800 0.800 scb 240 1.00 542 910 542 1166 670 1166 670 910 4 polygon 240 1.00 1182 1166 1182 1230 1246 1230 1246 1166 4 polygon sce 1.000 0.000 0.000 scb 240 1.00 1118 910 1118 1166 1246 1166 1246 910 4 polygon sce 0.898 0.898 0.898 scb 240 1.00 1246 1166 1246 1294 1374 1294 1374 1166 4 polygon sce 0 1.00 542 910 542 1166 670 1166 670 910 4 polygon 0 1.00 542 1166 542 1294 670 1294 670 1166 4 polygon 0 1.00 478 1166 478 1230 542 1230 542 1166 4 polygon 0 1.00 1246 910 1246 1166 1374 1166 1374 910 4 polygon 0 1.00 1246 1166 1246 1294 1374 1294 1374 1166 4 polygon 0 1.00 1182 1166 1182 1230 1246 1230 1246 1166 4 polygon (B) {/Helvetica 1.000 cf} 2 21 0 606 1230 label (A) {/Helvetica 1.000 cf} 2 25 0 606 942 label (cornerTypes) {/Helvetica-Oblique 1.000 cf} 2 23 0 414 1198 label (cornerDist) {/Helvetica-Oblique 1.000 cf} 2 20 0 702 1238 label (OKTypes) {/Helvetica-Oblique 1.000 cf} 2 20 0 702 1102 label (t1) {/Helvetica-Oblique 1.000 cf} 2 21 0 510 1006 label (t2) {/Helvetica-Oblique 1.000 cf} 2 21 0 574 1006 label 1 1.00 478 1038 606 1038 2 polygon 1 1.00 638 1102 686 1102 2 polygon 1 1.00 702 1118 638 1182 2 polygon 1 1.00 718 1278 718 1254 2 polygon 1 1.00 718 1214 718 1182 2 polygon 1 1.00 430 1198 510 1198 2 polygon 1 1.00 558 878 590 878 2 polygon 1 1.00 622 878 654 878 2 polygon 1 1.00 542 894 542 846 2 polygon 1 1.00 670 894 670 846 2 polygon 1.00 0 718 1294 arrowhead 1.00 -181 718 1166 arrowhead 1.00 -91 526 1198 arrowhead 1.00 -91 622 1038 arrowhead 1.00 -91 670 878 arrowhead 1.00 90 542 878 arrowhead 1.00 90 622 1102 arrowhead 1.00 45 622 1198 arrowhead (d) {/Helvetica-Oblique 1.000 cf} 2 21 0 602 878 label (\(a\)) {/Helvetica 1.000 cf} 2 21 0 606 798 label 1 1.00 1422 1210 1422 1182 2 polygon 1.00 -181 1422 1166 arrowhead 1 1.00 1422 1278 1422 1254 2 polygon 1.00 0 1422 1294 arrowhead 1 1.00 1406 1118 1342 1182 2 polygon 1.00 45 1326 1198 arrowhead 1 1.00 1342 1102 1390 1102 2 polygon 1.00 90 1326 1102 arrowhead 1 1.00 1182 1038 1310 1038 2 polygon 1.00 -91 1326 1038 arrowhead 1 1.00 1326 878 1358 878 2 polygon 1 1.00 1374 894 1374 846 2 polygon 1.00 -91 1374 878 arrowhead 1 1.00 1262 878 1294 878 2 polygon 1 1.00 1246 894 1246 846 2 polygon 1.00 90 1246 878 arrowhead (\(b\)) {/Helvetica 1.000 cf} 2 21 0 1310 798 label 1 1.00 1134 1198 1214 1198 2 polygon 1.00 -91 1230 1198 arrowhead 1 1.00 686 1294 734 1294 2 polygon 1 1.00 686 1166 734 1166 2 polygon 1 1.00 1390 1294 1438 1294 2 polygon 1 1.00 1390 1166 1438 1166 2 polygon (poly) {/Helvetica-Bold 1.000 cf} (not) {/Helvetica 1.000 cf} 4 23 0 1118 1198 label (poly) {/Helvetica-Bold 1.000 cf} (not) {/Helvetica 1.000 cf} 4 20 0 1422 1102 label (2) {/Helvetica 1.000 cf} 2 21 0 1310 878 label (2) {/Helvetica 1.000 cf} 2 21 0 1422 1234 label (poly) {/Helvetica-Bold 1.000 cf} 2 31 0 1214 1022 label (space) {/Helvetica-Bold 1.000 cf} 2 28 0 1262 1022 label 1.000 0.000 0.000 scb 240 1.00 414 398 414 590 542 590 542 398 4 polygon sce 0.800 0.800 0.800 scb 240 1.00 542 270 542 718 670 718 670 270 4 polygon sce 0 1.00 542 270 542 718 670 718 670 270 4 polygon (poly) {/Helvetica-Bold 1.000 cf} 2 25 0 494 510 label (poly) {/Helvetica-Bold 1.000 cf} (not) {/Helvetica 1.000 cf} 4 20 0 734 462 label 1 1.00 718 462 638 462 2 polygon 1 1.00 494 494 574 494 2 polygon 1.00 0 638 462 arrowhead90 1.00 -1 574 494 arrowhead90 1.000 0.000 0.000 scb 240 1.00 1022 398 1022 590 1150 590 1150 398 4 polygon 240 1.00 1022 590 1022 718 1374 718 1374 590 4 polygon sce 0.800 0.800 0.800 scb 240 1.00 1150 270 1150 590 1278 590 1278 270 4 polygon sce 0 1.00 1150 270 1150 590 1278 590 1278 270 4 polygon (poly) {/Helvetica-Bold 1.000 cf} (not) {/Helvetica 1.000 cf} 4 20 0 1342 462 label 1 1.00 1326 462 1246 462 2 polygon 1.00 0 1246 462 arrowhead90 (poly) {/Helvetica-Bold 1.000 cf} 2 25 0 1182 638 label 1 1.00 1102 510 1182 510 2 polygon 1.00 -1 1182 510 arrowhead90 (\(c\)) {/Helvetica 1.000 cf} 2 21 0 542 206 label (\(d\)) {/Helvetica 1.000 cf} 2 21 0 1198 206 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF %%EndDocument @endspecial 0 2600 a(Figure)f(11:)29 b(The)23 b(complete)f(design)g (rule)h(format)g(is)f(illustrated)f(in)i(\(a\).)31 b(Whene)n(v)o(er)22 b(an)h(edge)g(has)g Fh(type1)f Fg(on)h(its)0 2721 y(left)g(side)g(and)g Fh(type2)g Fg(on)g(its)g(right)f(side,)h(the)g(area)h(A)g(is)e(check)o (ed)i(to)f(be)g(sure)g(that)g(only)g Fh(OKT)-7 b(ypes)23 b Fg(are)h(present.)0 2841 y(If)35 b(the)g(material)f(just)g(abo)o(v)o (e)f(and)i(to)f(the)h(left)f(of)h(the)g(edge)g(is)f(one)g(of)h Fh(cornerT)-7 b(ypes)p Fg(,)37 b(then)d(area)i(B)f(is)g(also)0 2961 y(check)o(ed)25 b(to)g(be)g(sure)g(that)g(it)f(contains)g(only)h Fh(OKT)-7 b(ypes)p Fg(.)31 b(A)25 b(similar)f(corner)i(check)f(is)g (made)g(at)g(the)g(bottom)e(of)0 3082 y(the)f(edge.)31 b(Figure)22 b(\(b\))h(sho)n(ws)f(a)g(polysilicon)f(spacing)h(rule,)h (\(c\))g(sho)n(ws)f(a)h(situation)d(where)j(corner)h(e)o(xtension)0 3202 y(is)k(performed)h(on)f(both)g(ends)g(of)g(the)h(edge,)g(and)g (\(d\))f(sho)n(ws)g(a)g(situation)f(where)i(corner)g(e)o(xtension)e(is) h(made)0 3323 y(only)i(at)g(the)g(bottom)f(of)h(the)g(edge.)48 b(If)31 b(the)f(rule)g(described)g(in)g(\(d\))h(were)g(to)f(be)g (written)g(as)g(an)h Fd(edge)g Fg(rule,)h(it)0 3443 y(w)o(ould)24 b(look)g(lik)o(e:)900 3671 y Fd(edge)i Fg(poly)e(space)h(2)g(\230poly)f (\230poly)g(2)2187 3671 y /bksp 2 string def bksp 0 92 put bksp show 2187 3671 a 1200 3792 a (") show 1200 3792 a 60 w Fh(P)-8 b(oly-poly)24 b(separ)o(ation)f(must)h(be)h(at)f (least)g(2)2811 3792 y (") show 2811 3792 a 1200 4409 a (") show 1200 4409 a 60 w Fh(V)-7 b(ia)24 b(must)g(be)h(on)f(a)h(\003at)f(surface)g (\(MOSIS)h(rule)g(#8.4,5\))3232 4409 y (") show 3232 4409 a 84 w Fg(metal2)146 5039 y(Magic)37 b(v)o(ersions)e(using)h(tech\002le)h (formats)f(more)g(recent)h(than)g(28)f(are)i(generally)e(more)g(cle)n (v)o(er)h(about)0 5159 y(determining)29 b(the)i(correct)g(plane)g(from) g Fh(OKT)-7 b(ypes)31 b Fg(when)f(the)o(y)g(dif)n(fer)h(from)g(the)f (triggering)g(types,)i(and)e(the)0 5280 y(situation)g(is)h(unambiguous) f(\(use)h(of)h(\223space\224)g(in)f(rules)h(tends)f(to)g(introduce)g (ambiguity)-6 b(,)31 b(since)g(space)h(tiles)0 5400 y(appear)25 b(on)g(all)f(planes\).)1850 5649 y(\22638\226)p eop end %%Page: 39 39 TeXDict begin 39 38 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)p 630 3 2640 4 v 628 124 4 121 v 680 88 a(P)o(arameter)p 1218 124 V 188 w(Meaning)p 3268 124 V 630 127 2640 4 v 630 144 V 628 264 4 121 v 680 228 a(type1)p 1218 264 V 368 w(Material)f(on)h (\002rst)g(side)f(of)h(edge.)p 3268 264 V 630 267 2640 4 v 628 388 4 121 v 680 352 a(type2)p 1218 388 V 368 w(Material)f(on)h(second)f(side)h(of)g(edge.)p 3268 388 V 630 391 2640 4 v 628 511 4 121 v 680 475 a(d)p 1218 511 V 540 w(Distance)f(to)h(check)g(on)f(second)h(side)f(of)h(edge.)p 3268 511 V 630 515 2640 4 v 628 876 4 362 v 680 599 a(OKT)-8 b(ypes)p 1218 876 V 210 w(List)24 b(of)g(layers)h(that)f(are)i (permitted)e(within)f Fh(d)i Fg(units)e(on)1270 719 y(second)35 b(side)h(of)f(edge.)64 b(\()p Fh(OKT)-7 b(ypes)p Fg(=)p Fd(0)36 b Fg(means)g(ne)n(v)o(er)1270 840 y(OK\))p 3268 876 V 630 879 2640 4 v 628 1120 4 241 v 680 963 a(cornerT)-8 b(ypes)p 1218 1120 V 100 w(List)31 b(of)h(layers)g(that)g(cause)h (corner)f(e)o(xtension.)52 b(\()p Fh(cor)n(-)1270 1084 y(nerT)-7 b(ypes)p Fg(=)p Fd(0)25 b Fg(means)f(no)h(corner)g(e)o (xtension\))p 3268 1120 V 630 1123 2640 4 v 628 1364 4 241 v 680 1208 a(cornerDist)p 1218 1364 V 169 w(Amount)33 b(to)i(e)o(xtend)f(constraint)g(area)i(when)f Fh(corner)n(-)1270 1328 y(T)-7 b(ypes)25 b Fg(matches.)p 3268 1364 V 630 1367 2640 4 v 628 1729 4 362 v 680 1452 a(plane)p 1218 1729 V 374 w(Plane)39 b(on)f(which)g(to)g(check)g(constraint)g(re)o (gion)f(\(de-)1270 1572 y(f)o(aults)29 b(to)g(same)g(plane)g(as)h Fh(type1)f Fg(and)g Fh(type2)g Fg(and)h Fh(cor)n(-)1270 1692 y(nerT)-7 b(ypes)p Fg(\).)p 3268 1729 V 630 1732 2640 4 v 1110 1891 a(T)f(able)25 b(16:)30 b(The)25 b(parts)f(of)h(an)g (edge-based)g(rule.)p 105 2128 3691 4 v 103 2248 4 121 v 155 2212 a(edge4w)o(ay)99 b(ppcont,ppd)f(ndif)n(f,ndc,nfet)202 b(3)100 b(ndif)n(f,ndc,nfet)e(ndif)n(f,ndc,nfet)356 b(3)3706 2212 y /bksp 2 string def bksp 0 92 put bksp show 3706 2212 a 3794 2248 4 121 v 103 2368 V 657 2332 a (") show 657 2332 a 60 w Fh(Ndif)n(f)24 b(must)g(be)h(3)g(wide)g(if)f(it)h(ab) n(uts)f(ppcont)g(or)g(ppd)g(\(MOSIS)h(rule)g(#??\))3257 2332 y (") show 3257 2332 a 3794 2368 4 121 v 103 2489 V 155 2453 a Fg(edge4w)o(ay)99 b(allPoly)262 b(\230\(allPoly\)/acti)n(v)o(e)98 b(3)i(\230pc/acti)n(v)o(e)249 b(\230\(allPoly\)/acti)n(v)o(e)j(3)3706 2453 y /bksp 2 string def bksp 0 92 put bksp show 3706 2453 a 3794 2489 4 121 v 103 2609 V 657 2573 a (") show 657 2573 a 60 w Fh(P)-8 b(oly)24 b(contact)h(must)f(be)h(at)f(least)g (3)h(fr)l(om)e(other)i(poly)f(\(MOSIS)h(rule)f(#5B.4,5\))3472 2573 y (") show 3472 2573 a 3794 2609 4 121 v 103 2730 V 155 2693 a Fg(edge4w)o(ay)99 b(allPoly)262 b(\230\(allPoly\)/acti)n(v)o(e)98 b(1)i(\230m2c/metal2)134 b(\230\(allPoly\)/acti)n(v)o(e)252 b(1)3706 2693 y /bksp 2 string def bksp 0 92 put bksp show 3706 2693 a 3794 2730 4 121 v 103 2850 V 657 2814 a (") show 657 2814 a 60 w Fh(V)-7 b(ia)24 b(must)g(be)h(on)f(a)h (\003at)f(surface)g(\(MOSIS)h(rule)g(#8.4,5\))2689 2814 y (") show 2689 2814 a 84 w Fg(metal2)p 3794 2850 4 121 v 105 2853 3691 4 v 1046 3013 a(T)-8 b(able)24 b(17:)31 b(Some)25 b(edge)g(rules)f(in)h(the)f Fd(dr)n(c)i Fg(section.)0 3395 y Ff(16.8)119 b(Subcell)32 b(Ov)o(erlap)e(Rules)0 3586 y Fg(In)g(order)g(for)g(CIF)h(generation)f(and)g(circuit)f(e)o (xtraction)g(to)g(w)o(ork)h(properly)-6 b(,)30 b(certain)g(kinds)f(of)h (o)o(v)o(erlaps)f(be-)0 3707 y(tween)34 b(subcells)f(must)f(be)i (prohibited.)56 b(The)34 b(design-rule)f(check)o(er)i(pro)o(vides)d(tw) o(o)h(kinds)g(of)h(rules)f(for)h(re-)0 3827 y(stricting)23 b(o)o(v)o(erlaps.)30 b(The)o(y)24 b(are)900 4072 y Fd(exact)p 1127 4072 30 4 v 36 w(o)o(v)o(erlap)h Fh(type-list)900 4192 y Fd(no)p 1011 4192 V 36 w(o)o(v)o(erlap)g Fh(type-list1)f (type-list2)146 4435 y Fg(In)k(the)f Fd(exact)p 633 4435 V 37 w(o)o(v)o(erlap)g Fg(rule,)h Fh(type-list)f Fg(indicates)g(one)g (or)h(more)g(tile)f(types.)38 b(If)28 b(a)g(cell)f(contains)g(a)h(tile) f(of)0 4555 y(one)e(of)g(these)g(types)f(and)h(that)g(tile)f(is)h(o)o (v)o(erlapped)f(by)h(another)f(tile)h(of)g(the)g(same)g(type)f(from)h (a)h(dif)n(ferent)e(cell,)0 4676 y(then)29 b(the)g(o)o(v)o(erlap)f (must)g(be)h(e)o(xact:)39 b(the)29 b(tile)f(in)h(each)h(cell)f(must)f (co)o(v)o(er)h(e)o(xactly)f(the)h(same)g(area.)44 b(Ab)n(utment)0 4796 y(between)39 b(tiles)f(from)g(dif)n(ferent)g(cells)h(is)f (considered)g(to)h(be)f(a)h(partial)g(o)o(v)o(erlap,)i(so)d(it)g(is)g (prohibited)g(too.)0 4916 y(This)g(rule)h(is)f(used)g(to)h(ensure)g (that)f(the)h(CIF)g Fd(squar)n(es)h Fg(operator)f(will)f(w)o(ork)g (correctly)-6 b(,)42 b(as)d(described)f(in)0 5037 y(Section)25 b(12.6.)30 b(See)c(T)-8 b(able)24 b(18)h(for)g(the)g Fd(exact)p 1606 5037 V 36 w(o)o(v)o(erlap)g Fg(rule)g(from)f(the)h (standard)f(scmos)g(technology)g(\002le.)146 5159 y(The)19 b Fd(no)p 431 5159 V 36 w(o)o(v)o(erlap)g Fg(rule)g(mak)o(es)g(ille)o (gal)e(an)o(y)h(o)o(v)o(erlap)g(between)h(a)g(tile)g(in)f Fh(type-list1)g Fg(and)h(a)g(tile)g(in)f Fh(type-list2)p Fg(.)0 5280 y(Y)-11 b(ou)29 b(should)f(rarely)-6 b(,)30 b(if)g(e)n(v)o(er)l(,)g(need)f(to)g(specify)g Fd(no)p 1828 5280 V 36 w(o)o(v)o(erlap)h Fg(rules,)g(since)f(Magic)g (automatically)f(prohibits)0 5400 y(man)o(y)g(kinds)g(of)h(o)o(v)o (erlaps)e(between)i(subcells.)42 b(After)29 b(reading)g(the)g (technology)f(\002le,)i(Magic)e(e)o(xamines)g(the)1850 5649 y(\22639\226)p eop end %%Page: 40 40 TeXDict begin 40 39 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)p 970 3 1960 4 v 968 124 4 121 v 1020 88 a(e)o(xact)p 1235 88 30 4 v 35 w(o)o(v)o(erlap)99 b(m2c,ndc,pdc,pc,ppcont,nncont)p 2928 124 4 121 v 968 244 V 1020 208 a(no)p 1126 208 30 4 v 35 w(o)o(v)o(erlap)208 b(pfet,nfet)99 b(pfet,nfet)p 2928 244 4 121 v 970 247 1960 4 v 1006 407 a(T)-8 b(able)25 b(18:)30 b(Exact)p 1641 407 30 4 v 36 w(o)o(v)o(erlap)23 b(rule)i(in)f(the)h Fd(dr)n(c)h Fg(section.)0 777 y(paint)34 b(table)h(and)g(applies)f(the)h(follo)n(wing)e(rule:)51 b(if)35 b(tw)o(o)g(tile)f(types)g(A)h(and)g(B)h(are)g(such)e(that)h (the)g(result)f(of)0 897 y(painting)h(A)i(o)o(v)o(er)e(B)i(is)f (neither)g(A)h(nor)f(B,)h(or)g(the)f(result)g(of)g(painting)f(B)i(o)o (v)o(er)f(A)g(isn')n(t)g(the)g(same)h(as)f(the)0 1017 y(result)24 b(of)h(painting)e(A)i(o)o(v)o(er)f(B,)h(then)g(A)f(and)h(B) g(are)h(not)e(allo)n(wed)g(to)g(o)o(v)o(erlap.)30 b(Such)25 b(o)o(v)o(erlaps)e(are)i(prohibited)0 1138 y(because)36 b(the)o(y)e(change)h(the)g(structure)g(of)g(the)g(circuit.)61 b(Ov)o(erlaps)35 b(are)g(supposed)f(only)h(to)f(connect)h(things)0 1258 y(without)20 b(making)g(structural)h(changes.)29 b(Thus,)21 b(for)h(e)o(xample,)f(poly)f(can)i(o)o(v)o(erlap)e(pcontact) h(without)f(violating)0 1379 y(the)k(abo)o(v)o(e)f(rules,)g(b)n(ut)h (poly)f(may)g(not)g(o)o(v)o(erlap)g(dif)n(fusion)f(because)j(the)e (result)h(is)f(efet,)h(which)g(is)f(neither)h(poly)0 1499 y(nor)k(dif)n(fusion.)40 b(The)29 b(only)e Fd(no)p 1085 1499 V 36 w(o)o(v)o(erlap)i Fg(rules)f(you)g(should)f(need)i(to)f (specify)g(are)i(rules)e(to)g(k)o(eep)g(transistors)0 1619 y(from)d(o)o(v)o(erlapping)d(other)j(transistors)f(of)g(the)h (same)g(type.)0 1936 y Ff(16.9)119 b(Backgr)n(ound)31 b(check)o(er)g(step)e(size)0 2130 y Fg(Magic')-5 b(s)28 b(background)g(design-rule)g(check)o(er)i(breaks)f(lar)n(ge)g(cells)g (up)f(into)g(smaller)g(pieces,)i(checking)e(each)0 2250 y(piece)36 b(independently)-6 b(.)62 b(F)o(or)36 b(v)o(ery)g(lar)n(ge)g (designs,)i(the)e(number)f(of)h(pieces)g(can)g(get)g(to)g(be)g (enormous.)63 b(If)0 2371 y(designs)26 b(are)h(lar)n(ge)g(b)n(ut)f (sparse,)h(the)g(performance)g(of)g(the)f(design-rule)g(check)o(er)i (can)f(be)g(impro)o(v)o(ed)d(tremen-)0 2491 y(dously)g(by)g(telling)g (it)g(to)g(use)h(a)g(lar)n(ger)h(step)e(size)h(for)g(breaking)f(up)h (cells.)30 b(This)24 b(is)h(done)f(as)h(follo)n(ws:)900 2746 y Fd(stepsize)g Fh(stepsize)146 2997 y Fg(which)30 b(causes)h(each)f(cell)h(to)f(be)g(processed)g(in)g(square)h(pieces)f (of)g(at)h(most)e Fh(stepsize)g Fg(by)h Fh(stepsize)f Fg(units.)0 3117 y(It)e(is)f(generally)g(a)h(good)g(idea)f(to)h(pick)f (a)h(lar)n(ge)g Fh(stepsize)p Fg(,)f(b)n(ut)g(one)h(that)f(is)h(small)e (enough)h(so)h(each)g(piece)g(will)0 3238 y(contain)d(no)h(more)f(than) h(100)f(to)h(1000)f(rectangles.)146 3361 y(Note)d(that)e(the)i (distances)e(declared)i(in)f(the)h(DRC)g(section)f(are)h(used)f(to)g (determine)g(the)g(\223halo\224)h(of)f(possible)0 3482 y(interactions)35 b(around)g(a)h(tile)f(edge.)63 b(Magic)35 b(must)g(consider)g(all)g(paint)g(in)g(all)h(cells)f(simultaneously;)j (thus)0 3602 y(for)h(each)h(edge)g(in)e(the)i(design,)h(magic)e(must)f (\003atten)i(the)f(hierarchy)g(around)g(it)f(to)h(a)h(distance)e(equal) h(to)0 3722 y(the)e(interaction)g(halo.)68 b(Clearly)37 b(this)g(has)g(a)h(huge)f(impact)g(on)g(processing)f(time.)68 b(Because)38 b(the)f(DRC)i(is)0 3843 y(interacti)n(v)o(e,)28 b(the)g(performance)h(hit)e(can)i(be)f(noticeable)g(to)g(do)n(wnright)e (irritating.)40 b(Often)28 b(this)g(performance)0 3963 y(hit)c(can)g(be)h(greatly)e(reduced)i(by)f(remo)o(ving)f(rules)h(with) f(lar)n(ge)i(distance)f(measures,)g(such)g(as)g(rules)g(in)l(v)n (olving)0 4084 y(distances)k(to)g(pads,)h(and)f(widespacing)g(rules.)42 b(If)28 b(this)g(is)g(a)h(problem,)f(consider)g(using)g(one)g (technology)g(\002le)0 4204 y(for)h(layout,)g(and)g(one)g(which)g(can)g (be)g(used)g(\223of)n(\003ine\224)g(to)f(do)h(a)g(slo)n(w)-6 b(,)29 b(non-interacti)n(v)o(e)e(DRC)j(check)f(for)g(pad)0 4324 y(and)c(widespacing)f(rules)g(on)h(an)g(entire)g(project)f (layout.)0 4685 y Fi(17)143 b(Extract)34 b(section)0 4915 y Fg(The)25 b Fd(extract)g Fg(section)f(of)h(a)g(technology)e (\002le)i(contains)f(the)h(parameters)f(used)h(by)f(Magic')-5 b(s)24 b(circuit)g(e)o(xtractor)-5 b(.)0 5036 y(Each)25 b(line)f(in)g(this)f(section)h(be)o(gins)f(with)h(a)h(k)o(e)o(yw)o(ord) f(that)g(determines)f(the)i(interpretation)e(of)i(the)f(remainder)0 5156 y(of)h(the)g(line.)30 b(T)-8 b(able)25 b(19)f(gi)n(v)o(es)f(an)i (e)o(xample)f Fd(extract)i Fg(section.)146 5280 y(This)k(section)g(is)h (lik)o(e)f(the)h Fd(ci\002nput)h Fg(and)f Fd(cif)n(output)h Fg(sections)e(in)g(that)g(it)h(supports)e(multiple)g(e)o(xtraction)0 5400 y(styles.)h(Each)25 b(style)f(is)g(preceded)i(by)e(a)h(line)g(of)g (the)f(form)1850 5649 y(\22640\226)p eop end %%Page: 41 41 TeXDict begin 41 40 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)p 854 7 2192 4 v 852 127 4 121 v 904 91 a Fd(extract)p 3044 127 V 852 248 V 904 212 a Fg(style)367 b(lambda=0.7)p 3044 248 V 852 368 V 904 332 a(lambda)262 b(70)p 3044 368 V 852 488 V 904 452 a(step)395 b(100)p 3044 488 V 852 609 V 904 573 a(sidehalo)223 b(4)p 3044 609 V 852 729 V 3044 729 V 852 820 V 904 783 a(resist)345 b(poly)-6 b(,pfet,nfet)23 b(60000)p 3044 820 V 852 940 V 904 904 a(resist)345 b(pc/a)25 b(50000)p 3044 940 V 852 1060 V 904 1024 a(resist)345 b(pdif)n(f,ppd)23 b(120000)p 3044 1060 V 852 1181 V 904 1145 a(resist)345 b(ndif)n(f,nnd)23 b(120000)p 3044 1181 V 852 1301 V 904 1265 a(resist)345 b(m2contact/m1)23 b(1200)p 3044 1301 V 852 1421 V 904 1385 a(resist)345 b(metal1)24 b(200)p 3044 1421 V 852 1542 V 904 1506 a(resist)345 b(metal2,pad/m1)23 b(60)p 3044 1542 V 852 1662 V 904 1626 a(resist)345 b(ppc/a,pdc/a)24 b(100000)p 3044 1662 V 852 1783 V 904 1747 a(resist)345 b(nnc/a,ndc/a)24 b(100000)p 3044 1783 V 852 1903 V 904 1867 a(resist)345 b(nwell,pwell)24 b(3000000)p 3044 1903 V 852 2023 V 3044 2023 V 852 2114 V 904 2078 a(areacap)253 b(poly)24 b(33)p 3044 2114 V 852 2234 V 904 2198 a(areacap)253 b(metal1)24 b(17)p 3044 2234 V 852 2355 V 904 2318 a(areacap)253 b(metal2,pad/m1)23 b(11)p 3044 2355 V 852 2475 V 904 2439 a(areacap)253 b(ndif)n(f,nsd)23 b(350)p 3044 2475 V 852 2595 V 904 2559 a(areacap)253 b(pdif)n(f,psd)23 b(200)p 3044 2595 V 852 2716 V 904 2680 a(areacap)253 b(ndc/a,nsc/a)24 b(367)p 3044 2716 V 852 2836 V 904 2800 a(areacap)253 b(pdc/a,psc/a)24 b(217)p 3044 2836 V 852 2956 V 904 2920 a(areacap)253 b(pcontact/a)24 b(50)p 3044 2956 V 852 3077 V 3044 3077 V 852 3167 V 904 3131 a(perimc)279 b(allMetal1)24 b(space)h(56)p 3044 3167 V 852 3288 V 904 3251 a(perimc)279 b(allMetal2)24 b(space)h(55)p 3044 3288 V 852 3408 V 3044 3408 V 852 3498 V 904 3462 a(o)o(v)o(erlap)259 b(metal1)24 b(pdif)n(f,ndif)n(f,psd,nsd)e(33)p 3044 3498 V 852 3619 V 904 3583 a(o)o(v)o(erlap)259 b(metal2)24 b(pdif)n(f,ndif)n(f,psd,nsd) e(17)i(metal1)p 3044 3619 V 852 3739 V 904 3703 a(o)o(v)o(erlap)259 b(metal1)24 b(poly)g(33)p 3044 3739 V 852 3860 V 904 3823 a(o)o(v)o(erlap)259 b(metal2)24 b(poly)g(17)h(metal1)p 3044 3860 V 852 3980 V 904 3944 a(o)o(v)o(erlap)259 b(metal2)24 b(metal1)g(33)p 3044 3980 V 852 4100 V 3044 4100 V 852 4191 V 904 4155 a(sideo)o(v)o(erlap)98 b(allMetal1)24 b(space)h(allDif)n(f)f(64)p 3044 4191 V 852 4311 V 904 4275 a(sideo)o(v)o(erlap)98 b(allMetal2)24 b(space)h(allDif)n(f)f(60)p 3044 4311 V 852 4431 V 904 4395 a(sideo)o(v)o(erlap)98 b(allMetal1)24 b(space)h(poly)f(64)p 3044 4431 V 852 4552 V 904 4516 a(sideo)o(v)o(erlap)98 b(allMetal2)24 b(space)h(poly)f(60)p 3044 4552 V 852 4672 V 904 4636 a(sideo)o(v)o(erlap)98 b(allMetal2)24 b(space)h(allMetal1)f(70)p 3044 4672 V 852 4793 V 3044 4793 V 852 4883 V 904 4847 a(fet)451 b(pfet)25 b(pdif)n(f,pdc/a)f(2)g(pfet)h(Vdd!)31 b(nwell)24 b(0)h(0)p 3044 4883 V 852 5003 V 904 4967 a(fet)451 b(nfet)25 b(ndif)n(f,ndc/a)f(2)g(nfet)h(GND!)g(pwell)f(0)h(0) p 3044 5003 V 852 5124 V 904 5088 a Fd(end)p 3044 5124 V 854 5127 2192 4 v 1423 5286 a Fg(T)-8 b(able)24 b(19:)31 b Fd(Extract)25 b Fg(section.)1850 5649 y(\22641\226)p eop end %%Page: 42 42 TeXDict begin 42 41 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)900 84 y Fd(style)h Fh(stylename)146 297 y Fg(All)32 b(subsequent)f(lines)h(up)g(to)g(the)g (ne)o(xt)g Fd(style)g Fg(line)g(or)g(the)g(end)h(of)f(the)g(section)g (are)h(interpreted)f(as)h(be-)0 418 y(longing)27 b(to)h(e)o(xtraction)f (style)h Fh(stylename)p Fg(.)41 b(If)29 b(there)f(is)g(no)g(initial)f Fd(style)h Fg(line,)h(the)f(\002rst)h(style)e(will)h(be)g(named)0 538 y(\223def)o(ault\224.)146 658 y(The)d(k)o(e)o(yw)o(ords)f Fd(ar)n(eacap)p Fg(,)i Fd(perimcap)p Fg(,)g(and)e Fd(r)n(esist)h Fg(de\002ne)h(the)f(capacitance)g(to)g(substrate)f(and)h(the)f(sheet)0 779 y(resisti)n(vity)f(of)j(each)h(of)e(the)h(Magic)f(layers)h(in)f(a)h (layout.)33 b(All)25 b(capacitances)i(that)e(appear)h(in)g(the)f Fd(extract)i Fg(sec-)0 899 y(tion)20 b(are)h(speci\002ed)g(as)f(an)h (inte)o(gral)e(number)h(of)h(attof)o(arads)g(\(per)g(unit)e(area)j(or)e (perimeter\),)i(and)e(all)g(resistances)0 1020 y(as)25 b(an)g(inte)o(gral)f(number)g(of)h(milliohms)d(per)j(square.)146 1140 y(The)g Fd(ar)n(eacap)h Fg(k)o(e)o(yw)o(ord)e(is)g(follo)n(wed)g (by)g(a)h(list)f(of)h(types)f(and)h(a)g(capacitance)h(to)e(substrate,)g (as)h(follo)n(ws:)900 1353 y Fd(ar)n(eacap)h Fh(types)e(C)146 1566 y Fg(Each)40 b(of)g(the)g(types)f(listed)g(in)h Fh(types)f Fg(has)h(a)g(capacitance)h(to)e(substrate)h(of)g Fh(C)g Fg(attof)o(arads)g(per)g(square)0 1686 y(lambda.)67 b(Each)38 b(type)f(can)g(appear)h(in)f(at)g(most)f(one)h Fd(ar)n(eacap)h Fg(line.)68 b(If)37 b(a)h(type)f(does)f(not)h(appear)h (in)f(an)o(y)0 1807 y Fd(ar)n(eacap)i Fg(line,)j(it)c(is)g(considered)h (to)f(ha)n(v)o(e)g(zero)i(capacitance)f(to)f(substrate)g(per)h(unit)f (area.)73 b(Since)39 b(most)0 1927 y(analysis)32 b(tools)f(compute)h (transistor)f(gate)h(capacitance)h(directly)f(from)g(the)h(area)g(of)g (the)f(transistor')-5 b(s)31 b(gate,)0 2048 y(Magic)25 b(should)g(produce)g(node)g(capacitances)i(that)e(do)g(not)g(include)g (gate)g(capacitances.)34 b(T)-8 b(o)25 b(ensure)h(this,)e(all)0 2168 y(transistors)f(should)h(ha)n(v)o(e)h(zero)g Fd(ar)n(eacap)h Fg(v)n(alues.)146 2288 y(The)c Fd(perimcap)g Fg(k)o(e)o(yw)o(ord)f(is)g (follo)n(wed)f(by)h(tw)o(o)g(type-lists)f(and)h(a)h(capacitance)g(to)f (substrate,)g(as)h(follo)n(ws:)900 2501 y Fd(perimcap)k Fh(intypes)e(outtypes)g(C)146 2714 y Fg(Each)32 b(edge)f(that)g(has)g (one)g(of)h(the)f(types)f(in)h Fh(intypes)g Fg(on)g(its)f(inside,)i (and)f(one)g(of)g(the)h(types)e(in)h Fh(outtypes)0 2835 y Fg(on)h(its)g(outside,)i(has)e(a)h(capacitance)h(to)e(substrate)g(of) h Fh(C)g Fg(attof)o(arads)g(per)g(lambda.)53 b(This)32 b(can)h(also)g(be)f(used)0 2955 y(as)h(an)h(approximation)d(of)i(the)g (ef)n(fects)h(due)f(to)f(the)h(side)n(w)o(alls)f(of)h(dif)n(fused)g (areas.)56 b(As)33 b(for)g Fd(ar)n(eacap)p Fg(,)j(each)0 3076 y(unique)22 b(combination)g(of)h(an)g Fh(intype)f Fg(and)h(an)g Fh(outtype)g Fg(may)f(appear)i(at)f(most)f(once)h(in)g(a) g Fd(perimcap)h Fg(line.)30 b(Also)0 3196 y(as)g(for)f Fd(ar)n(eacap)p Fg(,)j(if)d(a)h(combination)e(of)h Fh(intype)g Fg(and)h Fh(outtype)f Fg(does)g(not)g(appear)h(in)f(an)o(y)g Fd(perimcap)i Fg(line,)f(its)0 3316 y(perimeter)25 b(capacitance)g(per) g(unit)f(length)g(is)h(zero.)146 3437 y(The)g Fd(r)n(esist)g Fg(k)o(e)o(yw)o(ord)f(is)g(follo)n(wed)g(by)h(a)g(type-list)e(and)i(a)g (resistance)g(as)g(follo)n(ws:)900 3650 y Fd(r)n(esist)g Fh(types)g(R)146 3863 y Fg(The)g(sheet)g(resisti)n(vity)d(of)j(each)h (of)e(the)h(types)f(in)h Fh(types)f Fg(is)h Fh(R)f Fg(milliohms)f(per)i (square.)146 3983 y(Each)32 b Fd(r)n(esist)f Fg(line)g(in)g(f)o(act)h (de\002nes)g(a)f(\223resistance)h(class\224.)50 b(When)32 b(the)f(e)o(xtractor)g(outputs)f(the)h(area)h(and)0 4104 y(perimeter)d(of)g(nodes)g(in)g(the)g Fd(.ext)h Fg(\002le,)g(it)f(does) g(so)g(for)h(each)g(resistance)f(class.)44 b(Normally)-6 b(,)28 b(each)i(resistance)0 4224 y(class)e(consists)f(of)h(all)g (types)g(with)g(the)g(same)g(resistance.)41 b(Ho)n(we)n(v)o(er)l(,)28 b(if)g(you)g(wish)g(to)g(obtain)f(the)h(perimeter)0 4344 y(and)c(area)g(of)g(each)g(type)g(separately)f(in)h(the)f Fd(.ext)h Fg(\002le,)g(you)g(should)e(mak)o(e)i(each)g(into)f(its)g(o)n (wn)g(resistance)g(class)0 4465 y(by)i(using)e(a)i(separate)h Fd(r)n(esist)f Fg(line)f(for)h(each)h(type.)146 4585 y(In)33 b(addition)f(to)h(sheet)f(resisti)n(vities,)h(there)g(are)h(tw) o(o)e(other)h(w)o(ays)g(of)g(specifying)f(resistances.)55 b(Neither)0 4705 y(is)36 b(used)g(by)g(the)g(normal)g(Magic)g(e)o (xtractor)l(,)i(b)n(ut)e(both)g(are)h(used)f(by)g(the)g(resistance)g(e) o(xtractor)-5 b(.)64 b(Contacts)0 4826 y(ha)n(v)o(e)27 b(a)h(resistance)f(that)g(is)g(in)l(v)o(ersely)g(proportional)f(to)h (the)g(number)g(of)h(via)f(holes)g(in)g(the)h(contact,)f(which)h(is)0 4946 y(proportional)d(\(albeit)h(with)f(quantization\))g(to)h(the)h (area)g(of)f(the)g(contact.)35 b(The)27 b Fd(contact)g Fg(k)o(e)o(yw)o(ord)e(allo)n(ws)g(the)0 5067 y(resistance)g(for)g(a)g (single)f(via)g(hole)h(to)f(be)h(speci\002ed:)900 5280 y Fd(contact)h Fh(types)e(size)h(R)900 5400 y Fd(contact)h Fh(types)e(size)h(bor)l(der)f(separ)o(ation)f(R)1850 5649 y Fg(\22642\226)p eop end %%Page: 43 43 TeXDict begin 43 42 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)146 68 y(where)k Fh(types)g Fg(is)f(a)h(comma-separated)f(list)f(of)i(types,)g Fh(size)f Fg(is)g(in)g(lambda,)h(and)g Fh(R)f Fg(is)g(in)g(milliohms.) 40 b Fh(Size)0 188 y Fg(is)23 b(interpreted)h(as)g(a)g(hole-size)g (quantum;)f(the)g(number)h(of)g(holes)f(in)h(a)g(contact)g(is)f(equal)h (to)f(its)h(width)f(di)n(vided)0 309 y(by)30 b Fh(size)f Fg(times)g(its)g(length)g(di)n(vided)f(by)i Fh(size)p Fg(,)g(with)g(both)f(quotients)f(rounded)h(do)n(wn)g(to)h(the)f (nearest)h(inte)o(ger)-5 b(.)0 429 y(The)25 b(resistance)g(of)f(a)i (contact)e(is)h Fh(R)f Fg(di)n(vided)g(by)g(the)h(number)f(of)h(holes.) 146 549 y(Note)h(that)f(the)h Fh(size)g Fg(alone)f(may)h(not)f(compute) g(the)h(same)g(number)f(of)h(contact)g(cuts)f(as)h(w)o(ould)f(be)i (gener)n(-)0 670 y(ated)20 b(by)h(the)f Fh(cifoutput)e Fg(command,)j(since)f(it)g(has)g(no)g(understaning)f(of)i(border)f(and) g(separation,)h(and)f(therefore)0 790 y(may)29 b(compute)g(an)h (incorrect)g(contact)f(resistance.)45 b(T)-8 b(o)30 b(a)n(v)n(oid)f (this)f(problem,)i(the)g(second)f(form)g(pro)o(vides)g(a)0 911 y(w)o(ay)35 b(to)f(gi)n(v)o(e)f(v)n(alues)h(for)g Fh(bor)l(der)g Fg(and)h Fh(separ)o(ation)p Fg(,)g(again)f(in)g(units)f (of)i(lambda.)59 b(There)35 b(is)f(no)g(automatic)0 1031 y(check)24 b(to)f(guarantee)h(that)g(the)f(e)o(xtract)h(and)f (cifoutput)g(sections)g(agree)h(on)g(the)f(number)g(of)h(contact)g (cuts)f(for)h(a)0 1151 y(gi)n(v)o(en)f(contact)i(area.)146 1272 y(T)m(ransistors)38 b(also)h(ha)n(v)o(e)g(resistance)h (information)e(associated)h(with)f(them.)74 b(Ho)n(we)n(v)o(er)l(,)42 b(a)e(transistor')-5 b(s)0 1392 y(resistance)23 b(may)f(v)n(ary)g (depending)g(on)g(a)h(number)f(of)h(v)n(ariables,)f(so)g(a)h(single)f (parameter)h(is)f(generally)h(insuf)n(\002-)0 1513 y(cient)h(to)f (describe)h(it.)30 b(The)24 b Fd(fetr)n(esist)h Fg(line)e(allo)n(ws)g (sheet)h(resisti)n(vities)d(to)j(be)g(gi)n(v)o(en)f(for)h(a)g(v)n (ariety)f(of)h(dif)n(ferent)0 1633 y(con\002gurations:)900 1859 y Fd(fetr)n(esist)i Fh(fettypes)e(r)l(e)l(gion)g(R)146 2086 y Fg(where)38 b Fh(fettypes)f Fg(is)f(a)i(comma-separated)f(list)f (of)h(transistor)f(types)h(\(as)g(de\002ned)h(in)f Fd(fet)g Fg(lines)g(belo)n(w\),)0 2206 y Fh(r)l(e)l(gion)20 b Fg(is)g(a)h(string)e(used)h(to)h(distinguish)c(between)k(resistance)f (v)n(alues)g(for)h(a)f(fet)h(if)g(more)f(than)g(one)g(is)g(pro)o(vided) 0 2327 y(\(the)38 b(special)g Fh(r)l(e)l(gion)g Fg(v)n(alue)g(of)g (\223)p Fd(linear)p Fg(\224)h(is)f(required)g(for)g(the)g(resistance)h (e)o(xtractor\),)i(and)d Fh(R)g Fg(is)g(the)g(on-)0 2447 y(resistance)25 b(of)h(the)f(transistor)f(in)h(ohms)g(per)g(square)h (\()p Fh(not)f Fg(milliohms;)e(there)i(w)o(ould)g(otherwise)g(be)g(too) g(man)o(y)0 2568 y(zeroes\).)146 2688 y(Magic)c(also)g(e)o(xtracts)g (internodal)g(coupling)f(capacitances,)i(as)g(illustrated)e(in)h (Figure)g(12.)30 b(The)21 b(k)o(e)o(yw)o(ords)0 2808 y Fd(o)o(v)o(erlap)p Fg(,)k Fd(sidewall)p Fg(,)f Fd(sideo)o(v)o(erlap)p Fg(,)h(and)f Fd(sidehalo)h Fg(pro)o(vide)f(the)h(parameters)g(needed)g (to)f(do)h(this.)146 2929 y(Ov)o(erlap)f(capacitance)i(is)e(between)h (pairs)f(of)h(tile)f(types,)g(and)h(is)f(described)g(by)h(the)f Fd(o)o(v)o(erlap)h Fg(k)o(e)o(yw)o(ord)f(as)0 3049 y(follo)n(ws:)900 3276 y Fd(o)o(v)o(erlap)h Fh(toptypes)f(bottomtypes)f(cap)i Fg([)p Fh(shieldtypes)p Fg(])146 3502 y(where)h Fh(toptypes)p Fg(,)f Fh(bottomtypes)p Fg(,)f(and)h(optionally)f Fh(shieldtypes)g Fg(are)i(type-lists)e(and)h Fh(cap)h Fg(is)f(a)g(capacitance)0 3623 y(in)k(attof)o(arads)g(per)g(square)g(lambda.)43 b(The)29 b(e)o(xtractor)g(searches)h(for)f(tiles)g(whose)f(types)h(are) h(in)e Fh(toptypes)h Fg(that)0 3743 y(o)o(v)o(erlap)i(tiles)g(whose)h (types)g(are)h(in)f Fh(bottomtypes)p Fg(,)g(and)g(that)g(belong)g(to)f (dif)n(ferent)h(electrical)h(nodes.)52 b(\(The)0 3863 y(planes)28 b(of)h Fh(toptypes)f Fg(and)g Fh(bottomtypes)f Fg(must)h(be)g(disjoint\).)41 b(When)28 b(such)g(an)h(o)o(v)o(erlap)f (is)g(found,)h(the)f(capac-)0 3984 y(itance)j(to)f(substrate)h(of)g (the)f(node)h(of)g(the)g(tile)f(in)h Fh(toptypes)f Fg(is)g(deducted)h (for)g(the)g(area)h(of)f(the)g(o)o(v)o(erlap,)g(and)0 4104 y(replaced)25 b(by)g(a)g(capacitance)h(to)e(the)h(node)f(of)h(the) g(tile)f(in)g Fh(bottomtypes)p Fg(.)146 4225 y(If)g Fh(shieldtypes)d Fg(are)j(speci\002ed,)f(o)o(v)o(erlaps)f(between)h Fh(toptypes)f Fg(and)g Fh(bottomtypes)g Fg(that)g(also)h(o)o(v)o(erlap)e(a)i(type)0 4345 y(in)d Fh(shieldtypes)g Fg(are)h(not)f(counted.)29 b(The)21 b(types)f(in)g Fh(shieldtypes)g Fg(must)g(appear)h(on)f(a)h (dif)n(ferent)g(plane)f(\(or)h(planes\))0 4465 y(than)j(an)o(y)h(of)g (the)f(types)g(in)h Fh(toptypes)f Fg(or)h Fh(bottomtypes)p Fg(.)146 4586 y(P)o(arallel)g(wire)g(capacitance)h(is)e(between)h (pairs)f(of)h(edges,)g(and)g(is)f(described)h(by)f(the)h Fd(sidewall)f Fg(k)o(e)o(yw)o(ord:)900 4812 y Fd(sidewall)g Fh(intypes)g(outtypes)g(neartypes)g(fartypes)g(cap)146 5039 y Fg(where)j Fh(intypes)p Fg(,)e Fh(outtypes)p Fg(,)g Fh(neartypes)p Fg(,)h(and)g Fh(fartypes)f Fg(are)i(all)e(type-lists,)g (described)g(in)h(Figure)g(13.)34 b Fh(Cap)0 5159 y Fg(is)28 b(half)g(the)h(capacitance)g(in)f(attof)o(arads)g(per)h(lambda)f(when)g (the)g(edges)h(are)g(1)f(lambda)g(apart.)42 b(P)o(arallel)28 b(wire)0 5280 y(coupling)37 b(capacitance)j(is)e(computed)g(as)g(being) g(in)l(v)o(ersely)g(proportional)f(to)h(the)h(distance)f(between)h(tw)o (o)0 5400 y(edges:)48 b(at)34 b(2)f(lambda)g(separation,)j(it)d(is)g (equal)h(to)f(the)g(v)n(alue)h Fh(cap)p Fg(;)j(at)d(4)g(lambda)f (separation,)i(it)e(is)g(half)h(of)1850 5649 y(\22643\226)p eop end %%Page: 44 44 TeXDict begin 44 43 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)780 990 y @beginspecial 68 @llx 68 @lly 484 @urx 244 @ury 2808 @rwi @setspecial %%BeginDocument: ../psfigures/tut8.4.ps %!PS-Adobe-3.0 EPSF-3.0 %%Title: tut8.4 %%Creator: Xcircuit v2.0 %%CreationDate: Fri Apr 14 15:06:26 2000 %%Pages: 1 %%BoundingBox: 68 68 484 244 %%DocumentNeededResources: font Times-Roman font Times-Italic %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrowhead90 { % -20 -12 36 24 bbox begingate 1.00 90 -16 0 arrowhead endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 928 256 offsets 1.0000 inchscale 2.6000 setlinewidth 0.490 0.651 0.980 scb 192 480 beginpath 544 608 544 480 2 polyc 512 608 32 0.00 90.00 arc 192 640 1 polyc 240 1.00 endpath 1280 480 beginpath 928 608 928 480 2 polyc 960 608 32 180.00 90.00 arcn 1280 640 1 polyc 240 1.00 endpath sce 1.000 0.000 0.000 scb 192 192 beginpath 1120 320 1120 192 2 polyc 1088 320 32 0.00 90.00 arc 192 352 1 polyc 240 1.00 endpath sce 192 480 beginpath 544 608 544 480 2 polyc 512 608 32 0.00 90.00 arc 192 640 1 polyc 1 1.00 endpath 1280 480 beginpath 928 608 928 480 2 polyc 960 608 32 180.00 90.00 arcn 1280 640 1 polyc 1 1.00 endpath 192 192 beginpath 1120 320 1120 192 2 polyc 1088 320 32 0.00 90.00 arc 192 352 1 polyc 1 1.00 endpath (\(metal\)) {/Times-Roman 1.000 cf} 2 21 0 352 560 label (\(metal\)) {/Times-Roman 1.000 cf} 2 21 0 1120 560 label (\(poly\)) {/Times-Roman 1.000 cf} 2 21 0 656 272 label (sidewall overlap) {/Times-Italic 1.000 cf} 2 21 0 688 448 label (sidewall) {/Times-Italic 1.000 cf} 2 21 0 720 576 label (overlap) {/Times-Roman 1.000 cf} 2 21 0 352 424 label (\(oxide\)) {/Times-Roman 1.000 cf} 2 21 0 1024 416 label 1.00 0 560 576 arrowhead90 1.00 -1 912 576 arrowhead90 1.00 0 560 512 arrowhead90 1.00 -91 688 368 arrowhead90 1 1.00 560 576 640 576 2 polygon 1 1.00 912 576 800 576 2 polygon 1 1.00 560 512 688 512 688 480 3 polygon 1 1.00 688 416 688 368 2 polygon 1.00 -91 352 368 arrowhead90 1.00 270 352 464 arrowhead90 1 1.00 352 432 352 464 2 polygon 1 1.00 352 368 352 400 2 polygon pgsave restore showpage %%Trailer XCIRCsave restore %%EOF %%EndDocument @endspecial 0 1193 a(Figure)e(12:)28 b(Magic)21 b(e)o(xtracts)g(three) g(kinds)g(of)g(internodal)g(coupling)f(capacitance.)30 b(This)20 b(\002gure)i(is)f(a)h(side)f(vie)n(w)0 1314 y(of)30 b(a)g(set)f(of)h(masks)f(that)g(sho)n(ws)g(all)g(three)h(kinds) f(of)h(capacitance.)46 b Fh(Overlap)30 b Fg(capacitance)g(is)f (parallel-plate)0 1434 y(capacitance)e(between)g(tw)o(o)f(dif)n(ferent) g(kinds)f(of)i(material)e(when)i(the)o(y)e(o)o(v)o(erlap.)35 b Fh(P)-8 b(ar)o(allel)24 b(wir)l(e)j Fg(capacitance)0 1555 y(is)22 b(fringing-\002eld)g(capacitance)i(between)f(the)f (parallel)h(v)o(ertical)f(edges)h(of)g(tw)o(o)f(pieces)h(of)g (material.)29 b Fh(Side)o(wall)0 1675 y(o)o(verlap)21 b Fg(capacitance)i(is)e(fringing-\002eld)g(capacitance)i(between)e(the) h(v)o(ertical)f(edge)h(of)g(one)g(piece)g(of)g(material)0 1795 y(and)j(the)f(horizontal)g(surf)o(ace)i(of)f(another)f(piece)i(of) e(material)h(that)f(o)o(v)o(erlaps)g(the)g(v)o(ertical)g(edge.)1306 3160 y @beginspecial 68 @llx 68 @lly 292 @urx 268 @ury 1544 @rwi @setspecial %%BeginDocument: ../psfigures/maint2.11.ps %!PS-Adobe-3.0 EPSF-3.0 %%Title: maint2.11.ps %%Creator: Xcircuit v2.0 %%CreationDate: Tue Apr 18 12:05:00 2000 %%Pages: 1 %%BoundingBox: 68 68 292 268 %%DocumentNeededResources: font Helvetica-Oblique %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 672 288 offsets 1.0000 inchscale 2.6000 setlinewidth 0.490 0.651 0.980 scb 240 1.00 320 480 320 704 608 704 608 480 4 polygon sce 0.745 0.600 0.871 scb 240 1.00 192 192 192 320 768 320 768 192 4 polygon sce 1 1.00 320 704 320 480 608 480 608 704 4 polygon 1 1.00 192 192 192 320 768 320 768 192 4 polygon (tfar) {/Helvetica-Oblique 1.000 cf} 2 21 0 464 592 label (fartypes) {/Helvetica-Oblique 1.000 cf} 2 24 0 336 496 label (neartypes) {/Helvetica-Oblique 1.000 cf} 2 28 0 336 464 label (outtypes) {/Helvetica-Oblique 1.000 cf} 2 24 0 240 336 label (intypes) {/Helvetica-Oblique 1.000 cf} 2 28 0 240 304 label (tinside) {/Helvetica-Oblique 1.000 cf} 2 21 0 448 224 label pgsave restore showpage %%Trailer XCIRCsave restore %%EOF %%EndDocument @endspecial 0 3364 a(Figure)30 b(13:)39 b(P)o(arallel)29 b(wire)g(capacitance)h(is)f(between)h(pairs)f(of)g(edges.)44 b(The)29 b(capacitance)h(applies)f(between)0 3484 y(the)35 b(tiles)f Fh(tinside)f Fg(and)i Fh(tfar)f Fg(abo)o(v)o(e,)i(where)f Fh(tinside)p Fg(')-5 b(s)33 b(type)h(is)h(one)f(of)h Fh(intypes)p Fg(,)i(and)d Fh(tfar)p Fg(')-5 b(s)34 b(type)g(is)g(one)h (of)0 3604 y Fh(fartypes)p Fg(.)0 3953 y Fh(cap)p Fg(.)30 b(This)24 b(approximation)e(is)h(not)h(v)o(ery)f(good,)h(in)f(that)h (it)g(tends)f(to)h(o)o(v)o(erestimate)e(the)i(coupling)e(capacitance)0 4074 y(between)j(wires)g(that)f(are)h(f)o(arther)h(apart.)146 4194 y(T)-8 b(o)26 b(reduce)g(the)f(amount)g(of)g(searching)h(done)f (by)g(Magic,)h(there)g(is)f(a)g(threshold)g(distance)g(be)o(yond)g (which)0 4314 y(the)g(ef)n(fects)g(of)f(parallel)h(wire)g(coupling)f (capacitance)h(are)h(ignored.)k(This)24 b(is)g(set)h(as)g(follo)n(ws:) 900 4516 y Fd(sidehalo)g Fh(distance)146 4717 y Fg(where)f Fh(distance)f Fg(is)g(the)g(maximum)f(distance)h(between)g(tw)o(o)g (edges)g(at)h(which)f(Magic)g(considers)g(them)f(to)0 4838 y(ha)n(v)o(e)31 b(parallel)f(wire)i(coupling)d(capacitance.)50 b Fd(If)31 b(this)g(number)i(is)d(not)i(set)f(explicitly)g(in)g(the)h (technology)0 4958 y(\002le,)25 b(it)g(defaults)g(to)g(0,)g(with)g(the) h(r)n(esult)f(that)h(no)f(parallel)f(wir)n(e)i(coupling)f(capacitance)h (is)e(computed.)146 5078 y Fg(Side)n(w)o(all)37 b(o)o(v)o(erlap)e (capacitance)j(is)f(between)g(material)f(on)h(the)g(inside)f(of)h(an)g (edge)g(and)g(o)o(v)o(erlapping)0 5199 y(material)24 b(of)h(a)g(dif)n(ferent)g(type.)30 b(It)25 b(is)f(described)h(by)g(the) f Fd(sideo)o(v)o(erlap)h Fg(k)o(e)o(yw)o(ord:)900 5400 y Fd(sideo)o(v)o(erlap)g Fh(intypes)f(outtypes)g(o)o(vtypes)h(cap)1850 5649 y Fg(\22644\226)p eop end %%Page: 45 45 TeXDict begin 45 44 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)146 68 y(where)39 b Fh(intypes)p Fg(,)h Fh(outtypes)p Fg(,)h(and)d Fh(o)o(vtypes)g Fg(are)g(type-lists)f(and)h Fh(cap)g Fg(is)f(capacitance)i(in)f(attof)o (arads)g(per)0 188 y(lambda.)h(This)26 b(is)i(the)f(capacitance)h (associated)g(with)e(an)i(edge)g(with)f(a)h(type)f(in)g Fh(intypes)g Fg(on)h(its)e(inside)h(and)h(a)0 309 y(type)c(in)h Fh(outtypes)f Fg(on)g(its)g(outside,)g(that)g(o)o(v)o(erlaps)g(a)h (tile)f(whose)h(type)f(is)g(in)h Fh(o)o(vtypes)p Fg(.)30 b(See)c(Figure)f(12.)146 429 y(De)n(vices)36 b(are)h(represented)g(in)e (Magic)h(by)g(e)o(xplicit)f(tile)h(types.)64 b(The)36 b(e)o(xtraction)f(of)i(a)f(de)n(vice)g(id)g(ster)n(-)0 549 y(mined)d(by)g(the)h(declared)g(de)n(vice)g(type)f(and)h(the)f (information)g(about)g(types)g(which)h(comprise)f(the)g(v)n(arious)0 670 y(independent)24 b Fh(terminals)f Fg(of)i(the)g(de)n(vice.)900 898 y Fd(de)o(vice)g(mosfet)g Fh(model)f(gate)p 1942 898 30 4 v 36 w(types)h(sd)p 2297 898 V 35 w(types)g(subs)p 2740 898 V 35 w(types)f(subs)p 3182 898 V 35 w(node)p 3411 898 V 36 w(name)3681 898 y /bksp 2 string def bksp 0 92 put bksp show 3681 898 a 1200 1019 a Fg([)p Fh(perim)p 1472 1019 30 4 v 35 w(cap)h Fg([)p Fh(ar)l(ea)p 1888 1019 V 36 w(cap)p Fg(]])900 1139 y Fd(de)o(vice)g(capacitor)g Fh(model)g(top)p 2015 1139 V 35 w(types)g(bottom)p 2558 1139 V 34 w(types)g Fg([)p Fh(perim)p 3088 1139 V 35 w(cap)p Fg(])g Fh(ar)l(ea)p 3504 1139 V 36 w(cap)900 1260 y Fd(de)o(vice)g(r)n(esistor)g Fh(model)f(r)l(esist)p 2020 1260 V 35 w(types)h(term)p 2468 1260 V 36 w(types)900 1380 y Fd(de)o(vice)g(bjt)h Fh(model)e(base)p 1793 1380 V 36 w(types)g(emitter)p 2341 1380 V 35 w(types)h(collector)p 2961 1380 V 35 w(types)900 1500 y Fd(de)o(vice)g(diode)g Fh(model)g(pos)p 1860 1500 V 35 w(types)g(ne)l(g)p 2265 1500 V 35 w(types)900 1621 y Fd(de)o(vice)g(subcir)n(cuit)h Fh(model)f(gate)p 2085 1621 V 35 w(types)g Fg([)p Fh(term)p 2566 1621 V 35 w(types)g Fg([)p Fh(subs)p 3042 1621 V 35 w(types)p Fg(]])900 1741 y Fd(de)o(vice)g(rsubcir)n(cuit)i Fh(model)d(id)p 2035 1741 V 35 w(types)h(term)p 2483 1741 V 35 w(types)146 1970 y Fg(Ar)n(guments)f(are)i(as)f(follo)n(ws:)145 2198 y Fe(\017)49 b Fh(model)27 b Fg(The)g(SPICE)i(model)d(name)h(of)h(the)f (de)n(vice.)37 b(In)28 b(the)f(case)h(of)f(a)h(subcircuit,)e(it)h(is)g (the)g(subcircuit)244 2318 y(name.)73 b(F)o(or)39 b(resistor)g(and)g (capacitor)g(de)n(vices)g(for)g(which)f(a)i(simple,)h(unmodeled)d(de)n (vice)h(type)g(is)244 2439 y(needed,)25 b(the)f Fh(model)h Fg(can)g(be)g(the)g(k)o(e)o(yw)o(ord)f Fd(None)p Fg(.)145 2642 y Fe(\017)49 b Fh(gate)p 422 2642 V 35 w(types)25 b Fg(Layer)g(types)f(that)h(form)f(the)h(gate)f(re)o(gion)g(of)h(a)g (MOSFET)g(transistor)-5 b(.)145 2846 y Fe(\017)49 b Fh(sd)p 339 2846 V 35 w(types)30 b Fg(Layer)f(types)g(that)g(form)g(the)g (source)h(and)f(drain)h(re)o(gions)e(of)h(a)h(MOSFET)g(transistor)-5 b(.)42 b(Cur)n(-)244 2966 y(rently)24 b(there)h(is)g(no)f(w)o(ay)h(to)f (specify)h(a)g(de)n(vice)g(with)f(asymmetric)f(source)i(and)g(drain.) 145 3170 y Fe(\017)49 b Fh(subs)p 428 3170 V 35 w(types)29 b Fg(Layer)g(types)f(that)h(form)f(the)h(b)n(ulk)f(\(well)h(or)g (substrate\))f(re)o(gion)g(under)h(the)f(de)n(vice.)43 b(This)244 3290 y(can)21 b(be)g(the)g(k)o(e)o(yw)o(ord)f Fh(None)i Fg(for)f(a)g(de)n(vice)g(such)g(as)g(an)g(nFET)g(that)g(has)f (no)h(identi\002able)g(substrate)f(layer)244 3411 y(type)k (\(\223space\224)i(cannot)f(be)g(used)f(as)h(a)g(layer)g(type)g (here\).)145 3614 y Fe(\017)49 b Fh(top)p 378 3614 V 35 w(types)25 b Fg(Layer)g(types)f(that)g(form)h(the)g(top)f(plate)h (of)f(a)i(capacitor)-5 b(.)145 3818 y Fe(\017)49 b Fh(bottom)p 528 3818 V 34 w(types)25 b Fg(Layer)g(types)g(that)f(form)h(the)f (bottom)f(plate)i(of)g(a)g(capacitor)-5 b(.)145 4021 y Fe(\017)49 b Fh(r)l(esist)p 463 4021 V 35 w(types)20 b Fg(Layer)g(types)g(that)f(represent)i(the)e(primary)h(characterized)h (resisti)n(v)o(e)d(portion)h(of)h(a)h(resistor)244 4142 y(de)n(vice.)145 4345 y Fe(\017)49 b Fh(term)p 433 4345 V 35 w(types)27 b Fg(Layer)g(types)f(that)g(represent)h(the)f(ends)h (of)g(a)g(resistor)-5 b(.)35 b(Normally)25 b(this)h(is)g(a)h(contact)g (type,)244 4465 y(b)n(ut)39 b(in)g(the)g(case)h(of)f(silicide)g(block)f (or)i(high-resistance)e(implants,)k(it)d(may)g(be)g(normal)g(salicided) 244 4586 y(polysilicon)23 b(or)i(dif)n(fusion.)145 4789 y Fe(\017)49 b Fh(base)p 433 4789 V 35 w(types)25 b Fg(Layer)g(types)f (that)h(represent)g(the)f(base)h(re)o(gion)f(of)h(a)g(bipolar)g (junction)e(transistor)-5 b(.)145 4993 y Fe(\017)49 b Fh(emitter)p 533 4993 V 35 w(types)25 b Fg(Layer)g(types)f(that)g (represent)h(the)g(emitter)f(re)o(gion)g(of)h(a)g(bipolar)f(junction)g (transistor)-5 b(.)145 5196 y Fe(\017)49 b Fh(collector)p 605 5196 V 35 w(types)21 b Fg(Layer)g(types)g(that)g(represent)g(the)g (collector)g(re)o(gion)f(of)h(a)h(bipolar)e(junction)g(transistor)-5 b(.)145 5400 y Fe(\017)49 b Fh(pos)p 389 5400 V 35 w(types)22 b Fg(Layer)g(types)f(that)h(represent)g(the)f(positi)n(v)o(e)f (\(anode\))i(terminal)f(of)h(a)g(diode)f(or)h(P-N)h(junction.)1850 5649 y(\22645\226)p eop end %%Page: 46 46 TeXDict begin 46 45 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)145 68 y Fe(\017)49 b Fh(ne)l(g)p 390 68 30 4 v 36 w(types)25 b Fg(Layer)h(types)f(that)g (represent)h(the)g(ne)o(gati)n(v)o(e)d(\(cathode\))j(terminal)f(of)g(a) h(diode)f(or)h(P-N)g(junc-)244 188 y(tion.)145 391 y Fe(\017)49 b Fh(id)p 328 391 V 35 w(types)25 b Fg(Identi\002er)g (layers)g(that)f(identify)g(a)h(speci\002c)g(resistor)g(type.)145 593 y Fe(\017)49 b Fh(subs)p 428 593 V 35 w(node)p 657 593 V 35 w(name)23 b Fg(The)f(def)o(ault)g(name)h(of)f(a)h(substrate)f (node)g(in)g(cases)h(where)g(a)f(4-terminal)g(MOSFET)244 713 y(de)n(vice)i(is)h(missing)e(an)i(identi\002able)f(b)n(ulk)g (terminal,)g(or)h(when)f(the)h Fh(subs)p 2806 713 V 35 w(type)g Fg(is)f(the)h(k)o(e)o(yw)o(ord)f Fd(None)p Fg(.)145 915 y Fe(\017)49 b Fh(perim)p 483 915 V 35 w(cap)25 b Fg(A)g(v)n(alue)f(for)h(perimeter)g(capacitance)g(in)g(units)e(of)i (attoF)o(arads)g(per)g(lambda)145 1118 y Fe(\017)49 b Fh(ar)l(ea)p 429 1118 V 36 w(cap)24 b Fg(A)h(v)n(alue)f(for)i(area)f (capacitance)h(in)e(units)g(of)h(attoF)o(arads)f(per)h(lambda)g (squared.)146 1341 y(The)34 b Fh(subs)p 519 1341 V 35 w(node)p 748 1341 V 35 w(name)g Fg(can)f(be)h(a)g(Tcl)f(v)n(ariable)g (name)g(\(be)o(ginning)f(with)h(\223$\224\))g(in)h(the)f(Tcl-based)g(v) o(er)n(-)0 1462 y(sion)28 b(of)i(magic.)43 b(Thus,)30 b(instead)e(of)i(hard-coding)e(a)i(global)e(net)h(name)h(into)e(the)h (general-purpose,)h(project-)0 1582 y(independent)k(technology)f (\002le,)k(the)e(technology)e(\002le)i(can)g(contain)f(a)h(def)o(ault)f (global)g(po)n(wer)g(and)h(ground)0 1702 y(net)42 b(v)n(ariable,)j (normally)c Fd($VDD)g Fg(and)h Fd($VSS)p Fg(.)g(Each)g(project)g (should)e(then)i(set)f(these)h(v)n(ariables)f(\(in)g(the)0 1823 y Fa(.magicrc)19 b Fg(\002le,)j(for)g(e)o(xample\))e(to)g(the)h (correct)h(v)n(alue)e(for)h(the)g(project')-5 b(s)20 b(def)o(ault)h(global)f(po)n(wer)h(and)g(ground)0 1943 y(netw)o(orks.)146 2064 y(SPICE)28 b(has)f(tw)o(o)f(formats)g(for)h (resistors)e(and)i(capacitors:)34 b(one)26 b(uses)g(a)h(model,)f(and)h (the)f(other)h(does)f(not.)0 2184 y(The)g(model)g(implies)e(a)j (semiconductor)e(resistor)h(or)g(capacitor)l(,)h(and)f(tak)o(es)g(a)h (length)e(and)h(width)g(v)n(alue.)34 b(The)0 2304 y(resisti)n(vity)29 b(or)i(capacitance)h(per)f(unit)g(area)h(of)f(the)g(de)n(vices)f(is)h (assumed)f(to)h(be)g(declared)h(in)f(the)g(model,)g(so)0 2425 y(these)25 b(v)n(alues)f(are)h(not)f(generated)i(as)e(part)h(of)g (the)g(SPICE)h(netlist)d(output.)146 2545 y(Magic)30 b(technology)f(\002le)h(formats)g(27)f(and)h(earlier)h(only)e (understood)g(one)h(de)n(vice)f(type,)i(the)f(FET)g(tran-)0 2665 y(sistor)-5 b(.)42 b(The)29 b(e)o(xtraction)g(of)g(a)g(fet)h (\(with)e(gate,)i(sources,)g(and)f(drains\))g(from)g(a)g(collection)g (of)g(transistor)f(tiles)0 2786 y(is)33 b(go)o(v)o(erned)e(by)i(the)g (information)e(in)i(a)g Fd(fet)h Fg(line.)55 b(This)32 b(k)o(e)o(yw)o(ord)g(and)h(syntax)f(is)h(retained)g(for)g(backw)o(ard)0 2906 y(compatibility)-6 b(.)28 b(This)c(line)g(has)h(the)f(follo)n (wing)f(format:)900 3130 y Fd(fet)i Fh(types)g(dtypes)g(min-nterms)e (name)i(snode)49 b Fg([)p Fh(stypes)p Fg(])p Fh(gscap)24 b(gccap)146 3354 y(T)-7 b(ypes)32 b Fg(is)g(a)g(list)f(of)g(those)h (tiletypes)e(that)h(mak)o(e)h(up)g(this)f(type)g(of)h(transistor)-5 b(.)50 b(Normally)-6 b(,)32 b(there)g(will)f(be)0 3474 y(only)g(one)i(type)e(in)h(this)f(list,)i(since)f(Magic)g(usually)f (represents)i(each)f(type)g(of)g(transistor)g(with)f(a)h(dif)n(ferent)0 3594 y(tiletype.)146 3715 y Fh(Dtypes)23 b Fg(is)g(a)g(list)f(of)h (those)f(tiletypes)g(that)h(connect)g(to)f(the)h(dif)n(fusion)e (terminals)h(of)h(the)g(fet.)30 b(Each)24 b(transis-)0 3835 y(tor)i(of)g(this)f(type)h(must)f(ha)n(v)o(e)h(at)g(least)g Fh(min-nterms)f Fg(distinct)g(dif)n(fusion)f(terminals;)i(otherwise,)f (the)h(e)o(xtractor)0 3955 y(will)g(generate)h(an)g(error)g(message.)36 b(F)o(or)26 b(e)o(xample,)g(an)h Fd(efet)g Fg(in)g(the)f(scmos)g (technology)f(must)h(ha)n(v)o(e)g(a)h(source)0 4076 y(and)j(drain)g(in) f(addition)g(to)h(its)f(gate;)j Fh(min-nterms)d Fg(for)h(this)f(type)h (of)g(fet)g(is)f(2.)47 b(The)30 b(tiletypes)e(connecting)h(to)0 4196 y(the)h(gate)g(of)g(the)g(fet)g(are)h(the)f(same)g(as)g(those)g (speci\002ed)g(in)g(the)g Fd(connect)i Fg(section)d(as)i(connecting)e (to)h(the)g(fet)0 4317 y(tiletype)24 b(itself.)146 4437 y Fh(Name)i Fg(is)e(a)h(string)f(used)h(to)f(identify)g(this)g(type)g (of)h(transistor)f(to)g(simulation)f(programs.)146 4557 y(The)31 b(substrate)e(terminal)h(of)g(a)h(transistor)e(is)h (determined)g(in)g(one)g(of)h(tw)o(o)f(w)o(ays.)47 b(If)31 b Fh(stypes)f Fg(\(a)h(comma-)0 4678 y(separated)k(list)g(of)g(tile)g (types\))f(is)h(gi)n(v)o(en,)h(and)f(a)h(particular)f(transistor)f(o)o (v)o(erlaps)g(one)h(of)h(those)e(types,)j(the)0 4798 y(substrate)30 b(terminal)f(will)h(be)g(connected)g(to)g(the)g(node)h (of)f(the)g(o)o(v)o(erlapped)f(material.)47 b(Otherwise,)31 b(the)f(sub-)0 4918 y(strate)21 b(terminal)e(will)h(be)h(connected)g (to)f(the)h(node)f(with)g(the)h(global)f(name)g(of)h Fh(snode)f Fg(\(which)h Fh(must)f Fg(be)h(a)g(global)0 5039 y(name,)k(i.e.,)f(end)h(in)f(an)h(e)o(xclamation)f(point\).)146 5159 y Fh(Gscap)h Fg(is)g(the)g(capacitance)h(between)f(the)g (transistor')-5 b(s)24 b(gate)h(and)g(its)g(dif)n(fusion)e(terminals,)h (in)h(attof)o(arads)0 5280 y(per)k(lambda.)42 b(Finally)-6 b(,)28 b Fh(gccap)h Fg(is)f(the)g(capacitance)i(between)f(the)f(gate)g (and)h(the)f(channel,)i(in)e(attof)o(arads)h(per)0 5400 y(square)c(lambda.)30 b(Currently)-6 b(,)24 b Fh(gscap)h Fg(and)f Fh(gccap)h Fg(are)h(unused)e(by)g(the)h(e)o(xtractor)-5 b(.)1850 5649 y(\22646\226)p eop end %%Page: 47 47 TeXDict begin 47 46 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)146 68 y(In)30 b(technology)e(format)g(27)h(\002les,)i(de)n(vices)d(such)h(as)g (resistors,)g(capacitors,)i(and)e(bipolar)f(junction)g(tran-)0 188 y(sistors)d(could)i(be)g(e)o(xtracted)f(by)h(treating)f(them)g(lik) o(e)g(FETs,)h(using)f(a)h(\223)p Fd(fet)p Fg(\224)h(line)e(in)h(the)f (e)o(xtract)h(\002le,)g(and)g(as-)0 309 y(signing)e(the)h(terminal)f (classes)h(\(some)n(what)f(arbitrarily\))h(to)g(the)g(FET)h(terminal)e (classes)h(gate,)h(source/drain,)0 429 y(and)j(b)n(ulk.)46 b(Resistors)29 b(are)i(rather)g(cumbersome)e(using)g(this)g(method,)i (because)f(the)g(\223gate\224)g(terminal)g(maps)0 549 y(to)f(nothing)f(physical,)h(and)g(a)h(dummy)e(layer)h(must)g(be)g(dra) o(wn.)44 b(The)29 b(\223e)o(xt2spice\224)g(command)f(generates)i(an)0 670 y(\223M\224)f(spice)g(record)g(for)h(all)e(de)n(vices)h(declared)g (with)f(a)i Fd(fet)f Fg(line,)h(so)e(an)i(output)d(SPICE)k(deck)e(must) f(be)h(post-)0 790 y(processed)k(to)g(produce)g(the)g(correct)h(SPICE)g (de)n(vices)f(for)g(simulation.)54 b(One)33 b(important)f(other)h(dif)n (ference)0 911 y(between)25 b(the)g(older)h(form)f(and)g(the)g(ne)n (wer)g(is)g(the)g(ability)f(of)i(the)f(\223)p Fd(de)o(vice)p Fg(\224)h(records)f(to)g(handle)g(de)n(vices)g(with)0 1031 y(bends)f(or)h(other)g(irre)o(gular)f(geometry)-6 b(,)24 b(including)f(annular)i(\(ring-shaped\))f(FETs.)146 1154 y(Often)i(the)g(units)f(in)g(the)h(e)o(xtracted)g(circuit)f(for)h (a)h(cell)f(will)f(al)o(w)o(ays)g(be)h(multiples)e(of)i(certain)g (basic)g(units)0 1274 y(lar)n(ger)32 b(than)e(centimicrons)g(for)h (distance,)h(attof)o(arads)f(for)g(capacitance,)j(or)d(milliohms)d(for) j(resistance.)49 b(T)-8 b(o)0 1394 y(allo)n(w)23 b(lar)n(ger)i(units)e (to)h(be)g(used)g(in)g(the)g Fd(.ext)h Fg(\002le)f(for)h(this)e (technology)-6 b(,)23 b(thereby)h(reducing)g(the)g(\002le')-5 b(s)24 b(size,)g(the)0 1515 y Fd(extract)i Fg(section)e(may)g(specify)h (a)g(scale)g(for)g(an)o(y)f(of)h(the)g(three)g(units,)f(as)g(follo)n (ws:)900 1761 y Fd(cscale)h Fh(c)900 1882 y Fd(lambda)g Fh(l)900 2002 y Fd(rscale)g Fh(r)146 2247 y Fg(In)j(the)g(abo)o(v)o(e,) f Fh(c)h Fg(is)f(the)h(number)f(of)h(attof)o(arads)f(per)h(unit)f (capacitance)h(appearing)g(in)f(the)h Fd(.ext)g Fg(\002les,)g Fh(l)g Fg(is)0 2367 y(the)g(number)g(of)h(centimicrons)e(per)i(unit)e (length,)i(and)f Fh(r)g Fg(is)g(the)h(number)f(of)g(milliohms)e(per)j (unit)e(resistance.)0 2487 y(All)f(three)h(must)f(be)h(inte)o(gers;)f Fh(r)h Fg(should)e(di)n(vide)g(e)n(v)o(enly)h(all)g(the)h (resistance-per)n(-square)g(v)n(alues)f(speci\002ed)h(as)0 2608 y(part)e(of)g Fd(r)n(esist)g Fg(lines,)f(and)g Fh(c)i Fg(should)d(di)n(vide)h(e)n(v)o(enly)f(all)i(the)f(capacitance-per)n (-unit)i(v)n(alues.)146 2730 y(Magic')-5 b(s)25 b(e)o(xtractor)g (breaks)g(up)g(lar)n(ge)h(cells)f(into)g(chunks)f(for)i(hierarchical)g (e)o(xtraction,)e(to)h(a)n(v)n(oid)g(ha)n(ving)0 2851 y(to)f(process)g(too)g(much)g(of)g(a)h(cell)f(all)g(at)g(once)h(and)f (possibly)f(run)h(out)g(of)g(memory)-6 b(.)29 b(The)c(size)f(of)h (these)f(chunks)0 2971 y(is)g(determined)g(by)h(the)g Fd(step)g Fg(k)o(e)o(yw)o(ord:)900 3218 y Fd(step)g Fh(step)146 3462 y Fg(This)38 b(speci\002es)g(that)g(chunks)g(of)h Fh(step)e Fg(units)h(by)g Fh(step)g Fg(units)f(will)g(be)i(processed)f (during)g(hierarchical)0 3583 y(e)o(xtraction.)57 b(The)34 b(def)o(ault)g(is)f Fd(100)h Fg(units.)57 b(Be)34 b(careful)h(about)e (changing)h Fh(step)p Fg(;)k(if)33 b(it)h(is)f(too)h(small)f(then)g (the)0 3703 y(o)o(v)o(erhead)k(of)h(hierarchical)g(processing)f(will)g (increase,)k(and)d(if)g(it)f(is)h(too)f(lar)n(ge)h(then)g(more)f(area)i (will)e(be)0 3823 y(processed)32 b(during)f(hierarchical)h(e)o (xtraction)f(than)g(necessary)-6 b(.)52 b(It)32 b(should)e(rarely)i(be) g(necessary)g(to)g(change)0 3944 y Fh(step)g Fg(unless)g(the)g(minimum) f(feature)i(size)g(changes)f(dramatically;)k(if)c(so,)i(a)f(v)n(alue)f (of)h(about)f(50)h(times)e(the)0 4064 y(minimum)22 b(feature)k(size)f (appears)g(to)f(w)o(ork)h(f)o(airly)g(well.)146 4187 y(Magic)30 b(has)f(the)g(capability)g(to)g(generate)h(a)g (geometry-only)f(e)o(xtraction)f(of)i(a)g(netw)o(ork,)g(useful)f(for)h (3-D)0 4307 y(simulations)22 b(of)i(electric)g(\002elds)g(necessary)h (to)f(rigorously)e(determine)i(inductance)g(and)g(capacitance.)31 b(When)0 4427 y(this)25 b(feature)h(is)f(used,)h(it)f(is)g(necessary)h (for)g(the)g(\002eld-equation)f(solv)o(er)g(to)g(kno)n(w)g(the)g(v)o (ertical)g(stackup)g(of)h(the)0 4548 y(layout.)31 b(The)25 b(e)o(xtract)g(section)g(tak)o(es)g(care)h(of)f(this)f(by)h(allo)n (wing)f(each)i(magic)e(layer)i(to)f(be)g(gi)n(v)o(en)f(a)h (de\002nition)0 4668 y(of)g(height)f(and)h(thickness)e(of)i(the)g(f)o (abricated)g(layer)g(type:)900 4915 y Fd(height)h Fh(layer)o(s)e (height)g(thic)n(kness)146 5159 y Fg(where)i Fh(layer)o(s)g Fg(is)f(a)h(comma-separated)f(list)g(of)g(magic)g(layers)h(sharing)f (the)h(same)f(height)g(and)g(thickness,)0 5280 y(and)32 b Fh(height)f Fg(and)h Fh(thic)n(kness)f Fg(are)h(\003oating-point)f (numbers)g(gi)n(ving)f(the)h(height)g(of)h(the)g(bottom)e(of)i(the)g (layer)0 5400 y(abo)o(v)o(e)24 b(the)g(substrate,)g(and)h(the)g (thickness)f(of)g(the)h(layer)l(,)g(respecti)n(v)o(ely)-6 b(,)23 b(in)h(units)g(of)h(lambda.)1850 5649 y(\22647\226)p eop end %%Page: 48 48 TeXDict begin 48 47 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)0 99 y Fi(18)143 b(W)m(iring)36 b(section)0 323 y Fg(The)25 b Fd(wiring)f Fg(section)g(pro)o(vides)f(information)g(used)h(by)h(the)f Fd(:wir)n(e)h(switch)g Fg(command)e(to)i(generate)g(contacts.)0 444 y(See)30 b(T)-8 b(able)30 b(20)f(for)h(the)f Fd(wiring)h Fg(section)e(from)i(the)f(scmos)g(technology)f(\002le.)45 b(Each)30 b(line)f(in)g(the)g(section)g(has)0 564 y(the)c(syntax)900 797 y Fd(contact)h Fh(type)f(minSize)e(layer1)i(surr)l(ound1)d(layer2)j (surr)l(ound2)146 1149 y(T)-7 b(ype)36 b Fg(is)f(the)g(name)g(of)g(a)g (contact)g(layer)l(,)j(and)d Fh(layer1)g Fg(and)g Fh(layer2)g Fg(are)h(the)f(tw)o(o)f(wiring)h(layers)g(that)g(it)0 1269 y(connects.)54 b Fh(MinSize)32 b Fg(is)g(the)g(minimum)f(size)h (of)h(contacts)f(of)h(this)f(type.)54 b(If)33 b Fh(Surr)l(ound1)e Fg(is)h(non-zero,)i(then)0 1390 y(additional)28 b(material)h(of)h(type) f Fh(layer1)g Fg(will)g(be)g(painted)g(for)h Fh(surr)l(ound1)d Fg(units)i(around)g(contacts)g(of)h Fh(type)p Fg(.)45 b(If)0 1510 y Fh(surr)l(ound2)23 b Fg(is)h(non-zero,)h(it)f(indicates)g (an)h(o)o(v)o(erlap)f(distance)g(for)h Fh(layer2)p Fg(.)p 893 1653 2115 4 v 891 1774 4 121 v 943 1738 a Fd(wiring)p 3005 1774 V 891 1894 V 943 1858 a(contact)100 b Fg(pdcontact)127 b(4)99 b(metal1)g(0)h(pdif)n(f)178 b(0)p 3005 1894 V 891 2015 V 943 1978 a Fd(contact)100 b Fg(ndcontact)127 b(4)99 b(metal1)g(0)h(ndif)n(f)178 b(0)p 3005 2015 V 891 2135 V 943 2099 a Fd(contact)100 b Fg(pcontact)177 b(4)99 b(metal1)g(0)h(poly)192 b(0)p 3005 2135 V 891 2255 V 943 2219 a Fd(contact)100 b Fg(m2contact)f(4)g(metal1)g(0)h (metal2)e(0)p 3005 2255 V 891 2376 V 943 2340 a Fd(end)p 3005 2376 V 893 2379 2115 4 v 1444 2539 a Fg(T)-8 b(able)25 b(20:)30 b Fd(W)n(iring)25 b Fg(section)146 2884 y(During)k Fd(:wir)n(e)h(switch)f Fg(commands,)g(Magic)g(scans)g(the)g(wiring)g (information)f(to)g(\002nd)i(a)f(contact)g(whose)0 3005 y Fh(layer1)23 b Fg(and)h Fh(layer2)f Fg(correspond)g(to)g(the)g(pre)n (vious)g(and)g(desired)h(ne)n(w)f(wiring)f(materials)h(\(or)h(vice)g(v) o(ersa\).)30 b(If)24 b(a)0 3125 y(match)g(is)h(found,)f(a)h(contact)g (is)f(generated)h(according)g(to)f Fh(type)p Fg(,)h Fh(minSize)p Fg(,)f Fh(surr)l(ound1)p Fg(,)e(and)j Fh(surr)l(ound2)p Fg(.)0 3468 y Fi(19)143 b(Router)34 b(section)0 3693 y Fg(The)29 b Fd(r)n(outer)g Fg(section)f(of)h(a)g(technology)e(\002le) i(pro)o(vides)e(information)g(used)h(to)g(guide)g(the)h(automatic)e (routing)0 3813 y(tools.)j(The)24 b(section)h(contains)e(four)i(lines.) 30 b(See)c(T)-8 b(able)25 b(21)f(for)i(an)e(e)o(xample)g Fd(r)n(outer)j Fg(section.)p 597 3956 2706 4 v 595 4077 4 121 v 647 4040 a Fd(r)n(outer)p 3301 4077 V 595 4197 V 647 4161 a(lay)o(er1)333 b Fg(metal1)242 b(3)100 b(allMetal1)e(3)p 3301 4197 V 595 4317 V 647 4281 a Fd(lay)o(er2)333 b Fg(metal2)242 b(3)100 b(allMetal2)e(4)i(allPoly)-6 b(,allDif)n(f)97 b(1)p 3301 4317 V 595 4438 V 647 4402 a Fd(contacts)250 b Fg(m2contact)98 b(4)p 3301 4438 V 595 4558 V 647 4522 a Fd(gridspacing)i Fg(8)p 595 4678 V 647 4642 a Fd(end)p 3301 4678 V 597 4682 2706 4 v 1446 4841 a Fg(T)-8 b(able)25 b(21:)30 b Fd(Router)c Fg(section)146 5168 y(The)f(\002rst)g(tw)o(o)f (lines)h(ha)n(v)o(e)f(the)h(k)o(e)o(yw)o(ords)e Fd(lay)o(er1)i Fg(and)g Fd(lay)o(er2)f Fg(and)h(the)g(follo)n(wing)e(format:)900 5400 y Fd(lay)o(er1)i Fh(wir)l(eT)-7 b(ype)25 b(wir)l(eW)-5 b(idth)24 b(type-list)g(distance)g(type-list)g(distance)g Fg(.)15 b(.)g(.)1850 5649 y(\22648\226)p eop end %%Page: 49 49 TeXDict begin 49 48 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)146 69 y(The)o(y)g(de\002ne)h (the)f(tw)o(o)g(layers)g(used)g(for)g(routing.)31 b(After)26 b(the)f Fd(lay)o(er1)g Fg(or)g Fd(lay)o(er2)g Fg(k)o(e)o(yw)o(ord)f (are)i(tw)o(o)f(\002elds)0 189 y(gi)n(ving)f(the)i(name)f(of)h(the)g (material)f(to)h(be)g(used)f(for)h(routing)f(that)h(layer)g(and)f(the)h (width)f(to)g(use)h(for)g(its)f(wires.)0 309 y(The)33 b(remaining)f(\002elds)h(are)h(used)f(by)f(Magic)h(to)g(a)n(v)n(oid)f (routing)g(o)o(v)o(er)g(e)o(xisting)f(material)i(in)g(the)g(channels.)0 430 y(Each)26 b(pair)g(of)g(\002elds)f(contains)g(a)h(list)f(of)h (types)f(and)g(a)h(distance.)33 b(The)26 b(distance)f(indicates)g(ho)n (w)g(f)o(ar)i(a)o(w)o(ay)e(the)0 550 y(gi)n(v)o(en)g(types)i(must)f(be) h(from)g(routing)e(on)i(that)g(layer)-5 b(.)37 b(Layer1)27 b(and)g(layer2)g(are)h(not)e(symmetrical:)33 b(where)n(v)o(er)0 671 y(possible,)22 b(Magic)i(will)e(try)i(to)f(route)g(on)h(layer1)f (in)g(preference)i(to)f(layer2.)30 b(Thus,)23 b(in)g(a)h(single-metal)e (process,)0 791 y(metal)i(should)g(al)o(w)o(ays)g(be)h(used)g(for)g (layer1.)146 913 y(The)g(third)f(line)h(pro)o(vides)e(information)g (about)i(contacts.)30 b(It)25 b(has)f(the)h(format)900 1151 y Fd(contacts)g Fh(contactT)-7 b(ype)25 b(size)49 b Fg([)p Fh(surr)l(ound1)23 b(surr)l(ound2)p Fg(])146 1389 y(The)29 b(tile)g(type)g Fh(contactT)-7 b(ype)28 b Fg(will)g(be)i(used)e(to)h(mak)o(e)g(contacts)g(between)g(layer1)g (and)g(layer2.)43 b(Contacts)0 1509 y(will)18 b(be)h Fh(size)g Fg(units)f(square.)29 b(In)19 b(order)h(to)e(a)n(v)n(oid)h (placing)f(contacts)h(too)g(close)f(to)h(hand-routed)g(material,)g (Magic)0 1629 y(assumes)28 b(that)g(both)g(the)h(layer1)g(and)g(layer2) f(rules)h(will)f(apply)g(to)h(contacts.)42 b(If)29 b Fh(surr)l(ound1)e Fg(and)h Fh(surr)l(ound2)0 1750 y Fg(are)c(present,)f (the)o(y)g(specify)g(o)o(v)o(erlap)f(distances)h(around)g(contacts)f (for)i(layer1)f(and)g(layer2:)30 b(additional)22 b(layer1)0 1870 y(material)32 b(will)f(be)h(painted)g(for)g Fh(surr)l(ound1)e Fg(units)h(around)h(each)h(contact,)g(and)g(additional)d(layer2)j (material)0 1990 y(will)24 b(be)h(painted)f(for)h Fh(surr)l(ound2)e Fg(units)g(around)i(contacts.)146 2112 y(The)j(last)g(line)g(of)g(the)g Fd(r)n(outing)h Fg(section)e(indicates)h(the)g(size)g(of)g(the)g(grid)g (on)f(which)h(to)g(route.)40 b(It)28 b(has)g(the)0 2233 y(format)900 2471 y Fd(gridspacing)d Fh(distance)146 2708 y Fg(The)d Fh(distance)f Fg(must)g(be)h(chosen)g(lar)n(ge)g (enough)f(that)h(contacts)f(and/or)h(wires)g(on)f(adjacent)h(grid)g (lines)f(will)0 2829 y(not)j(generate)i(an)o(y)e(design)g(rule)h (violations.)0 3177 y Fi(20)143 b(Plo)o(wing)34 b(section)0 3403 y Fg(The)i Fd(plo)o(wing)f Fg(section)g(of)h(a)g(technology)e (\002le)i(identi\002es)f(those)g(types)h(of)f(tiles)g(whose)g(sizes)h (and)f(shapes)0 3523 y(should)25 b(not)i(be)f(changed)h(as)g(a)g (result)f(of)h(plo)n(wing.)34 b(T)-8 b(ypically)i(,)25 b(these)i(types)f(will)g(be)h(transistors)e(and)h(b)n(uried)0 3644 y(contacts.)k(The)25 b(section)f(currently)h(contains)f(three)h (kinds)f(of)g(lines:)900 3882 y Fd(\002xed)i Fh(types)900 4003 y Fd(co)o(v)o(er)n(ed)g Fh(types)900 4123 y Fd(drag)f Fh(types)146 4360 y Fg(where)h Fh(types)e Fg(is)h(a)g(type-list.)k(T)-8 b(able)25 b(22)f(gi)n(v)o(es)g(this)g(section)g(for)h(the)f(scmos)g (technology)g(\002le.)p 1318 4507 1264 4 v 1316 4627 4 121 v 1368 4591 a Fd(plo)o(wing)p 2580 4627 V 1316 4747 V 1368 4711 a(\002xed)232 b Fg(pfet,nfet,glass,pad)p 2580 4747 V 1316 4868 V 1368 4832 a Fd(co)o(v)o(er)n(ed)109 b Fg(pfet,nfet)p 2580 4868 V 1316 4988 V 1368 4952 a Fd(drag)237 b Fg(pfet,nfet)p 2580 4988 V 1316 5109 V 1368 5072 a Fd(end)p 2580 5109 V 1318 5112 1264 4 v 1424 5272 a Fg(T)-8 b(able)25 b(22:)30 b Fd(Plo)o(wing)24 b Fg(section)1850 5649 y(\22649\226)p eop end %%Page: 50 50 TeXDict begin 50 49 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)146 69 y(In)j(a)h Fd(\002xed)f Fg(line,)g(each)h(of)f Fh(types)g Fg(is)f(considered)h(to) f(be)h(\002x)o(ed-size;)h(re)o(gions)e(consisting)f(of)i(tiles)f(of)h (these)0 189 y(types)f(are)h(not)e(deformed)h(by)g(plo)n(wing.)33 b(Contact)26 b(types)g(are)h(al)o(w)o(ays)f(considered)g(to)f(be)i (\002x)o(ed-size,)f(so)g(need)0 309 y(not)e(be)h(included)f(in)h Fh(types)p Fg(.)146 430 y(In)i(a)f Fd(co)o(v)o(er)n(ed)i Fg(line,)e(each)h(of)g Fh(types)f Fg(will)f(remain)i(\223co)o(v)o (ered\224)f(by)g(plo)n(wing.)34 b(If)26 b(a)h(f)o(ace)g(of)g(a)g(co)o (v)o(ered)e(type)0 550 y(is)k(co)o(v)o(ered)g(with)g(a)g(gi)n(v)o(en)f (type)h(before)h(plo)n(wing,)f(it)g(will)f(remain)i(so)f(afterw)o (ards.)45 b(F)o(or)29 b(e)o(xample,)h(if)f(a)h(f)o(ace)0 671 y(of)e(a)g(transistor)f(is)g(co)o(v)o(ered)g(by)g(dif)n(fusion,)g (the)h(dif)n(fusion)e(w)o(on')n(t)h(be)h(allo)n(wed)f(to)g(slide)g (along)h(the)f(transistor)0 791 y(and)c(e)o(xpose)f(the)h(channel)g(to) g(empty)f(space.)31 b(Usually)-6 b(,)22 b(you)g(should)g(mak)o(e)h(all) g(\002x)o(ed-width)f(types)h(co)o(v)o(ered)f(as)0 911 y(well,)i(e)o(xcept)h(for)g(contacts.)146 1032 y(In)j(a)g Fd(drag)f Fg(line,)h(whene)n(v)o(er)f(material)g(of)g(a)h(type)f(in)g Fh(types)g Fg(mo)o(v)o(es,)g(it)g(will)f(drag)i(with)e(it)h(an)o(y)g (minimum-)0 1152 y(width)g(material)g(on)g(its)g(trailing)g(side.)38 b(This)27 b(can)h(be)g(used,)g(for)g(e)o(xample,)f(to)g(insure)h(that)f (when)g(a)h(transistor)0 1272 y(mo)o(v)o(es,)k(the)g(poly-o)o(v)o (erlap)e(forming)h(its)h(gate)f(gets)h(dragged)g(along)g(in)f(its)h (entirety)-6 b(,)32 b(instead)g(of)g(becoming)0 1393 y(elongated.)0 1730 y Fi(21)143 b(Plot)35 b(section)0 1953 y Fg(The)28 b Fd(plot)h Fg(section)f(of)g(the)g(technology)f (\002le)i(contains)f(information)e(used)i(by)h(Magic)e(to)h(generate)h (hardcop)o(y)0 2074 y(plots)e(of)g(layouts.)39 b(Plots)27 b(can)h(be)g(generated)g(in)f(dif)n(ferent)h(styles,)f(which)g (correspond)h(to)f(dif)n(ferent)g(printing)0 2194 y(mechanisms.)h(F)o (or)22 b(each)h(style)e(of)h(printing,)f(there)h(is)f(a)i(separate)f (subsection)e(within)h(the)h Fd(plot)g Fg(section.)29 b(Each)0 2314 y(subsection)24 b(is)g(preceded)h(by)g(a)g(line)f(of)h (the)g(form)900 2522 y Fd(style)g Fh(styleName)146 2730 y Fg(Magic)e(v)o(ersion)g(6.5)g(and)g(earlier)i(supported)d Fd(gr)n(emlin)p Fg(,)i Fd(v)o(ersatec)p Fg(,)g(and)g Fd(color)o(v)o(ersatec)g Fg(styles.)29 b(As)23 b(these)0 2850 y(are)f(thoroughly)e(obsolete,)h(v)o(ersions)f(7)i(and)f(abo)o(v)o (e)f(instead)h(implement)f(tw)o(o)h(formats)g Fd(postscript)h Fg(and)f Fd(pnm)p Fg(.)0 2971 y(Generally)-6 b(,)31 b(the)f Fd(pnm)h Fg(format)f(is)f(best)h(for)g(printouts)f(of)h(entire)g (chips,)h(and)f(the)g Fd(postscript)h Fg(format)f(is)g(best)0 3091 y(for)35 b(small)f(cells.)60 b(The)35 b(PostScript)g(output)e (includes)h(labels,)j(whereas)e(the)g(PNM)g(output)e(does)i(not.)60 b(The)0 3211 y(PostScript)27 b(output)g(is)g(v)o(ector)n(-dra)o(wn)f (with)h(stipple)f(\002lls,)i(whereas)g(the)f(PNM)h(output)e(is)h(pix)o (el-dra)o(wn,)g(with)0 3332 y(antialiasing.)55 b(Small)32 b(areas)i(of)g(layout)e(tend)h(to)g(look)g(arti\002cially)g(pix)o (ellated)e(in)i(the)g(PNM)h(format,)h(while)0 3452 y(lar)n(ge)d(areas)g (look)e(almost)g(photographic.)49 b(The)31 b(PostScript)g(output)f(is)h (a)g(perfect)h(rendering)f(of)g(the)g(Magic)0 3573 y(layout,)36 b(b)n(ut)e(the)h(\002les)g(become)g(v)o(ery)f(lar)n(ge)h(and)g(tak)o(e) g(long)f(spans)g(of)h(time)f(to)g(render)h(for)g(lar)n(ge)h(areas)f(of) 0 3693 y(layout.)146 3813 y(The)29 b Fd(postscript)f Fg(style)g(requires)g(three)h(separate)f(sections.)40 b(The)29 b(\002rst)f(section)f(de\002nes)i(the)f(stipple)f(pat-)0 3934 y(terns)e(used:)900 4142 y Fh(inde)n(x)g(pattern-bytes)p Fg(.)15 b(.)g(.)146 4349 y(The)29 b Fh(inde)n(x)f Fg(v)n(alues)g(are)h (arbitrary)g(b)n(ut)f(must)f(be)i(a)g(positi)n(v)o(e)d(inte)o(ger)i (and)g(must)g(be)h(unique)e(to)h(each)i(line.)0 4470 y(The)k(indices)f(will)h(be)g(referenced)h(in)f(the)g(third)f(section.) 58 b(The)34 b Fh(pattern-bytes)f Fg(are)h(al)o(w)o(ays)g(e)o(xactly)g (8)g(sets)0 4590 y(of)k(8-digit)f(he)o(xidecimal)f(numbers)h(\(4)i (bytes\))e(representing)h(a)g(total)f(of)h(16)g(bits)f(by)g(16)h(lines) f(of)h(pattern)0 4711 y(data.)44 b(If)30 b(a)f(solid)f(color)h(is)g (intended,)h(then)f(it)f(is)h(necessary)h(to)f(declare)h(a)f(stipple)f (pattern)h(of)g(all)g(ones.)44 b(The)0 4831 y(actual)26 b(PostScript)g(output)f(will)g(implement)g(a)h(solid)f(color)l(,)i(not) e(a)i(stipple)e(pattern,)h(for)g(considerably)g(f)o(aster)0 4951 y(rendering.)146 5072 y(The)20 b(second)g(section)f(de\002nes)i (the)e(colors)h(used)g(in)f(standard)h(printer)g(CMYK)f(notation)g (\(Cyan,)j(Magenta,)0 5192 y(Y)-10 b(ello)n(w)k(,)23 b(blacK\):)900 5400 y Fh(inde)n(x)i(C)g(M)g(Y)g(K)1850 5649 y Fg(\22650\226)p eop end %%Page: 51 51 TeXDict begin 51 50 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)p 498 64 2905 4 v 496 172 4 109 v 547 140 a Fd(plot)p 3401 172 V 496 280 V 547 248 a(style)100 b(postscript)p 3401 280 V 496 389 V 841 356 a Fg(5)470 b(FFFFFFFF)28 b(FFFFFFFF)g(FFFFFFFF)g (FFFFFFFF)g(.)15 b(.)g(.)p 3401 389 V 496 497 V 841 465 a(7)470 b(18181818)23 b(30303030)h(60606060)f(C0C0C0C0)j(.)15 b(.)g(.)p 3401 497 V 496 605 V 841 573 a(9)470 b(18181818)23 b(3C3C3C3C)j(3C3C3C3C)g(18181818)e(.)15 b(.)g(.)p 3401 605 V 496 714 V 841 681 a(10)420 b(F0F0F0F0)26 b(60606060)d(06060606)g (0F0F0F0F)j(.)15 b(.)g(.)p 3401 714 V 496 822 V 841 790 a(13)420 b(00000000)23 b(00000000)h(33333333)f(33333333)h(.)15 b(.)g(.)p 3401 822 V 496 930 V 3401 930 V 496 1039 V 841 1006 a(1)470 b(47)24 b(95)h(111)f(0)p 3401 1039 V 496 1147 V 841 1115 a(9)470 b(223)24 b(47)h(223)f(0)p 3401 1147 V 496 1256 V 841 1223 a(10)420 b(0)25 b(255)f(255)g(0)p 3401 1256 V 496 1364 V 841 1331 a(12)420 b(191)24 b(127)h(0)f(0)p 3401 1364 V 496 1472 V 841 1440 a(13)420 b(95)24 b(223)h(63)f(0)p 3401 1472 V 496 1581 V 841 1548 a(14)420 b(0)25 b(0)f(0)h(255)p 3401 1581 V 496 1689 V 841 1656 a(16)420 b(111)24 b(151)h(244)f(0)p 3401 1689 V 496 1797 V 841 1765 a(17)420 b(23)24 b(175)h(183)f(0)p 3401 1797 V 496 1906 V 3401 1906 V 496 2014 V 841 1981 a(pc,ndc,pdc,psc,nsc)1100 b(14)25 b(X)p 3401 2014 V 496 2122 V 841 2090 a(m2c)1676 b(14)25 b(B)p 3401 2122 V 496 2231 V 841 2198 a(m2c)1676 b(14)25 b(13)p 3401 2231 V 496 2339 V 841 2306 a(m2,m2c)1523 b(13)25 b(10)p 3401 2339 V 496 2447 V 841 2415 a(pdc,ndc,psc,nsc,pc,m1,m2c)750 b(12)25 b(9)p 3401 2447 V 496 2556 V 841 2523 a(poly)-6 b(,pc)1557 b(10)25 b(5)p 3401 2556 V 496 2664 V 841 2631 a(nfet)1693 b(9)25 b(7)p 3401 2664 V 496 2772 V 841 2740 a(nfet)1693 b(16)25 b(5)p 3401 2772 V 496 2881 V 841 2848 a(pfet)1693 b(1)25 b(7)p 3401 2881 V 496 2989 V 841 2956 a(pfet)1693 b(17)25 b(5)p 3401 2989 V 496 3097 V 841 3065 a(pdif)n(f,pdc)1487 b(1)25 b(5)p 3401 3097 V 496 3206 V 841 3173 a(ndif)n(f,ndc)1487 b(9)25 b(5)p 3401 3206 V 496 3314 V 3401 3314 V 496 3422 V 547 3390 a Fd(style)100 b(pnm)p 3401 3422 V 496 3531 V 841 3498 a Fg(dra)o(w)322 b(metal1)p 3401 3531 V 496 3639 V 841 3607 a(dra)o(w)g(metal2)p 3401 3639 V 496 3747 V 841 3715 a(dra)o(w)g(polysilicon)p 3401 3747 V 496 3856 V 841 3823 a(dra)o(w)g(ndif)n(fusion)p 3401 3856 V 496 3964 V 841 3932 a(dra)o(w)g(pdif)n(fusion)p 3401 3964 V 496 4072 V 841 4040 a(dra)o(w)g(ntransistor)p 3401 4072 V 496 4181 V 841 4148 a(dra)o(w)g(ptransistor)p 3401 4181 V 496 4289 V 841 4257 a(map)348 b(psubstratepdif)n(f)23 b(pdif)n(fusion)p 3401 4289 V 496 4397 V 841 4365 a(map)348 b(nsubstratendif)n(f)23 b(ndif)n(fusion)p 3401 4397 V 496 4506 V 841 4473 a(map)348 b(polycontact)24 b(polysilicon)e(metal1)p 3401 4506 V 496 4614 V 841 4582 a(map)348 b(m2contact)24 b(metal1)g(metal2)p 3401 4614 V 496 4722 V 841 4690 a(map)348 b(ndcontact)24 b(ndif)n(fusion)f(metal1)p 3401 4722 V 496 4831 V 841 4798 a(map)348 b(pdcontact)24 b(pdif)n(fusion)f(metal1)p 3401 4831 V 496 4939 V 547 4907 a Fd(end)p 3401 4939 V 498 4942 2905 4 v 0 5102 a Fg(T)-8 b(able)35 b(23:)52 b(Sample)35 b Fd(plot)h Fg(section)e(\(for)i(an)g(SCMOS)g(process\).)63 b(PostScript)35 b(stipple)f(patterns)h(ha)n(v)o(e)g(been)0 5210 y(truncated)25 b(due)f(to)h(space)g(limitations.)1850 5649 y(\22651\226)p eop end %%Page: 52 52 TeXDict begin 52 51 bop 0 -180 a Fg(February)26 b(13,)e(2006)1042 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)146 68 y(Lik)o(e)30 b(the)f(\002rst)h(section,)f(each)i Fh(inde)n(x)e Fg(must)f(be)i(a)g (unique)f(positi)n(v)o(e)e(inte)o(ger)l(,)j(and)f(the)g(color)h(v)n (alues)e(each)0 189 y(range)d(from)g(0)f(to)h(255.)146 309 y(The)g(third)f(section)g(assigns)g(colors)h(and)f(stipple)g (patterns)g(to)h(each)g(style:)900 538 y Fh(type-list)f(color)n(-inde)n (x)g(stipple-inde)n(x)p Fe(j)p Fd(X)p Fe(j)p Fd(B)146 767 y Fg(The)e Fh(type-list)g Fg(is)f(a)i(comma-separated)e(list)g(of)h (magic)g(layer)g(types)g(that)g(collecti)n(v)o(ely)e(use)h(the)h(same)g (color)0 887 y(and)h(style.)29 b(The)23 b Fh(color)n(-inde)n(x)f Fg(refers)h(to)g(one)f(of)h(the)g(colors)f(de\002ned)h(in)f(the)h (second)g(section,)f(and)h(the)f Fh(stipple-)0 1008 y(inde)n(x)35 b Fg(refers)h(to)e(one)h(of)g(the)g(stipple)f(patterns)h(de\002ned)g (in)g(the)f(\002rst)h(section.)61 b(In)35 b(addition)f(to)g(the)h (stipple)0 1128 y(pattern)28 b(indices,)g(tw)o(o)g(characters)h(are)g (recognized:)38 b Fd(B)29 b Fg(declares)g(that)e(a)i(border)g(will)e (be)h(dra)o(wn)g(around)g(the)0 1248 y(layer)k(boundary)-6 b(,)31 b(and)h Fd(X)f Fg(declares)h(that)f(the)g(layout)g(boundary)f (will)h(be)h(printed)e(o)o(v)o(er)h(with)f(a)i(cross)f(in)g(the)0 1369 y(same)25 b(manner)f(as)h(contact)g(areas)g(are)h(dra)o(wn)e(in)h (the)f(Magic)h(layout.)146 1489 y(T)-8 b(o)20 b(get)g(a)g(proper)g (PostScript)f(plot,)h(it)g(is)f(necessary)h(to)g(ha)n(v)o(e)f(a)h (properly)g(de\002ned)g Fd(plot)g(postscript)h Fg(section)0 1610 y(in)f(the)g(technology)e(\002le.)30 b(W)l(ithout)19 b(such)g(a)i(de\002ned)f(set,)h(the)f Fd(plot)g(postscript)h Fg(command)e(will)g(generate)i(blank)0 1730 y(output.)146 1850 y(The)k Fd(pnm)h Fg(style)e(declarations)g(are)i(as)f(follo)n(ws:) 900 2079 y Fd(draw)g Fh(ma)o(gic-type)900 2200 y Fd(map)g Fh(ma)o(gic-type)g(dr)o(aw-type)p Fg(.)15 b(.)g(.)146 2429 y(where)38 b(both)f Fh(ma)o(gic-type)g Fg(and)h Fh(dr)o(aw-type)f Fg(represent)h(a)g(magic)f(layer)h(name.)68 b(The)38 b Fd(draw)g Fg(command)0 2549 y(states)24 b(that)g(a)h (speci\002c)g(magic)f(type)g(will)g(be)h(output)e(e)o(xactly)h(as)g (dra)o(wn)g(on)h(the)f(layout.)30 b(The)24 b Fd(map)h Fg(statement)0 2669 y(declares)40 b(that)f(a)h(speci\002c)f(magic)g (type)g(will)g(be)h(dra)o(wn)f(as)g(being)g(composed)f(of)i(other)f (layers)h(declared)0 2790 y(as)28 b Fd(draw)g Fg(types.)39 b(The)28 b(colors)f(of)h(the)g Fd(draw)g Fg(types)f(will)g(be)h (blended)f(to)h(generate)g(the)g(mapped)f(layer)h(color)-5 b(.)0 2910 y(Colors)19 b(are)i(de\002ned)e(by)h(the)f(style)g(set)g (used)g(for)h(layout)f(and)g(de\002ned)h(in)f(the)g Fd(styles)h Fg(section)e(of)i(the)f(technology)0 3030 y(\002le.)39 b(Stipple)27 b(patterns,)g(borders,)h(and)f(cross-hatches)g(used)g(by)g (those)g(styles)g(are)h(ignored.)37 b(When)28 b(multiple)0 3151 y(styles)21 b(are)h(used)f(for)h(a)g(layer)g(type,)g(the)g(PNM)f (output)g(blends)g(the)g(base)h(color)f(of)h(each)g(of)g(those)f (styles.)29 b(Thus,)0 3271 y(contact)i(areas)h(by)f(def)o(ault)g(tend)g (to)g(sho)n(w)f(up)h(completely)f(black,)j(as)e(the)g(\223X\224)h (pattern)f(is)g(usually)f(de\002ned)0 3392 y(as)g(black,)i(and)e(black) g(blended)f(with)h(other)g(colors)f(remains)h(black.)47 b(This)29 b(is)h(why)f(the)h(abo)o(v)o(e)f(e)o(xample)g(re-)0 3512 y(de\002nes)e(all)g(of)h(the)f(contact)f(types)h(as)g(mapped)g (type)g(blends.)37 b(Contact)27 b(cuts)f(are)i(not)f(represented,)h (which)f(is)0 3632 y(generally)e(desired)f(if)h(the)g(plot)f(being)g (made)h(represents)f(a)h(lar)n(ge)h(area)g(of)e(layout.)146 3753 y(Unlik)o(e)j(the)h(PostScript)g(section,)g(the)f(PNM)h(plot)f (section)g(does)h Fh(not)f Fg(ha)n(v)o(e)h(to)f(be)h(declared.)40 b(Magic)28 b(will)0 3873 y(set)22 b(up)g(a)g(def)o(ault)g(style)f(for)h (PNM)g(plots)f(that)h(matches)f(\(more)h(or)g(less\))g(the)g(colors)g (of)g(the)g(layout)f(as)h(speci\002ed)0 3994 y(by)38 b(the)h Fd(styles)f Fg(section)g(of)h(the)f(technology)g(\002le.)73 b(The)38 b Fd(plot)h(pnm)h Fg(section)e(can)h(be)g(used)f(to)g(tweak)h (this)0 4114 y(def)o(ault)25 b(setup.)32 b(Normally)24 b(this)g(is)h(not)g(necessary)-6 b(.)32 b(The)26 b(def)o(ault)f(setup)f (is)h(helpful)g(in)g(that)g(it)g(allo)n(ws)f(the)h Fd(plot)0 4234 y(pnm)32 b Fg(command)f(to)g(be)h(used)f(with)g(all)g(technology)g (\002les,)i(including)d(those)h(written)g(before)h(the)g Fh(plot)e(pnm)0 4355 y Fg(command)24 b(option)f(w)o(as)i(implemented.)0 4695 y Fi(22)143 b(Conditionals,)33 b(File)i(Inclusions,)f(and)h(Macr)m (o)g(De\002nitions)0 4918 y Fg(The)c(\223ra)o(w\224)h(technology)e (\002les)i(in)e(the)i Fd(scmos)f Fg(subdirectory)f(of)h(the)g(Magic)g (distrib)n(ution)e(were)j(written)f(for)0 5039 y(a)j(C)g(preprocessor)g (and)g(cannot)g(be)f(read)i(directly)e(by)h(Magic.)57 b(The)34 b(C)g(preprocessor)g(must)f(\002rst)g(be)h(used)0 5159 y(to)e(eliminate)f(comments)g(and)i(e)o(xpand)f(macros)g(in)g(a)h (technology)e(\002le)i(before)g(it)f(gets)g(installed,)h(which)f(is)0 5280 y(done)h(during)f(the)i(\223)p Fd(mak)o(e)g(install)p Fg(\224)e(step)h(when)g(compiling)f(and)h(installing)e(Magic)i(from)g (source.)56 b(Macro)0 5400 y(de\002nitions)31 b(can)h(be)g(made)g(with) g(the)g(preprocessor)g Fd(#de\002ne)h Fg(statement,)g(and)f (\223conditional)f(compilation\224)1850 5649 y(\22652\226)p eop end %%Page: 53 53 TeXDict begin 53 52 bop 0 -180 a Fg(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)1043 b(February)25 b(13,)g(2006)0 70 y(can)k(be)g(speci\002ed)g (using)e Fd(#ifdef)p Fg(.)43 b(Also,)29 b(the)f(technology)g(\002le)h (can)g(be)g(split)e(into)h(parts)g(using)g(the)g Fd(#include)0 190 y Fg(statement)i(to)g(read)h(in)g(dif)n(ferent)f(parts)g(of)h(the)g (\002les.)48 b(Ho)n(we)n(v)o(er)l(,)31 b(this)f(has)g(for)h(the)g(most) e(part)i(pro)o(v)o(en)f(to)g(be)0 311 y(a)f(poor)f(method)f(for)i (maintaining)d(technology)h(\002les.)42 b(End-users)28 b(often)g(end)g(up)g(making)g(modi\002cations)e(to)0 431 y(the)32 b(technology)f(\002les)i(for)f(one)h(purpose)e(or)i (another)-5 b(.)52 b(The)o(y)32 b(should)f(not)h(need)h(to)e(be)i (making)e(changes)h(to)0 551 y(the)i(source)g(code)g(distrib)n(ution,)g (the)o(y)f(often)h(do)g(not)f(ha)n(v)o(e)h(write)g(access)h(to)e(the)h (source)g(distrib)n(ution,)g(and)0 672 y(furthermore,)e(the)e (elimination)f(of)i(comments)e(and)i(macros)f(from)g(the)h(\002le)g (mak)o(es)f(the)h(actual)f(technology)0 792 y(\002le)25 b(used)g(dif)n(\002cult)f(to)g(read)h(and)g(understand.)146 913 y(T)-7 b(echnology)27 b(\002le)i(formats)e(more)h(recent)g(that)g (27)f(include)h(se)n(v)o(eral)f(b)n(uilt-in)f(mechanisms)h(that)g(tak)o (e)h(the)0 1033 y(place)23 b(of)f(preprocessor)g(statements,)g(and)g (allo)n(w)f(the)h(technology)g(\002le)g(source)h(to)f(be)g(directly)g (edited)g(without)0 1153 y(the)29 b(need)g(to)g(re-process.)44 b(This)28 b(includes)h(the)g Fd(include)h Fg(statement,)f(which)g(may)f (be)i(used)f(an)o(ywhere)g(in)f(the)0 1274 y(technology)33 b(\002le,)j(the)e Fd(alias)f Fg(statement)g(in)g(the)h Fd(types)h Fg(section,)g(and)f(the)g Fd(v)o(ariant)g Fg(statement,)h(which)e(may)0 1394 y(be)e(used)f(in)g(the)g Fd(cif)n(output)p Fg(,)j Fd(ci\002nput)p Fg(,)h(or)d Fd(extract)g Fg(sections.)47 b(The)30 b Fd(alias)g Fg(statements)f (appear)i(in)f(the)h Fd(types)0 1515 y Fg(section,)22 b(co)o(v)o(ered)f(abo)o(v)o(e.)28 b(The)22 b Fd(include)h Fg(statement)e(may)g(appear)h(an)o(ywhere)g(in)f(the)h(\002le,)h(and)e (tak)o(es)h(the)f(form)900 1707 y Fd(include)26 b Fh(\002lename)146 1899 y Fg(Assuming)19 b(that)h(the)g(included)g(\002les)h(e)o(xist)e (in)h(the)g(search)h(path)g(Magic)f(uses)g(for)h(\002nding)f(system)f (\002les)i(\(see)0 2020 y(command)31 b Fd(path)h(sys)p Fg(\),)h(then)e(no)h(absolute)f(path)g(needs)h(to)f(be)h(spe\002cied)g (for)g Fh(\002lename)p Fg(.)51 b(Note)31 b(that)g(the)h(\002le)0 2140 y(contents)26 b(will)g(be)i(included)e(v)o(erbatim;)h(section)f (names)h(and)g Fd(end)h Fg(statements)e(that)h(appear)g(in)g(the)g (included)0 2260 y(\002le)e(should)f(not)g(e)o(xist)g(in)g(the)h (\002le)g(that)f(includes)g(it,)g(and)h(vice)g(v)o(ersa.)146 2381 y(The)i(most)f(common)g(use)g(of)h(\223#ifdef)5 b(\224)28 b(preprocessor)f(statements)f(in)g(the)h(def)o(ault)g (\223scmos\224)f(technology)0 2501 y(is)c(to)h(selecti)n(v)o(ely)d (de\002ne)k(dif)n(ferent)e(cifoutput,)g(ci\002nput,)g(and)h(e)o(xtract) g(\002les)f(for)h(process)g(v)n(ariants.)29 b(The)23 b(result)0 2621 y(is)d(that)g(these)g(sections)g(become)g(quite)g(lar)n (ge)h(and)f(repeat)h(man)o(y)e(de\002nitions)h(that)g(are)h(common)e (to)h(all)g(process)0 2742 y(v)n(ariations.)28 b(T)-7 b(echnology)20 b(\002le)i(format)f(30)f(de\002nes)i(the)f Fd(v)o(ariants)g Fg(option)f(to)h(the)g Fd(style)f Fg(statement)h(for)g (all)g(three)0 2862 y(sections)j Fd(ci\002nput)p Fg(,)i Fd(cif)n(output)p Fg(,)g(and)f Fd(extract)p Fg(.)31 b(This)24 b(statment)g(option)g(tak)o(es)g(the)h(form:)900 3055 y Fd(style)g Fh(stylename)f Fd(v)o(ariants)g Fh(variantname)o(,.)15 b(.)g(.)146 3247 y Fg(where)30 b Fh(stylename)f Fg(is)g(a)h(base)f (name)g(used)g(for)h(all)f(v)n(ariants,)g(and)h(one)f(of)g(the)h (comma-separated)f(list)f(of)0 3367 y Fh(variantname)p Fg(s)e(is)i(a)g(suf)n(\002x)f(appended)h(to)f(the)h Fh(stylename)f Fg(to)h(get)g(the)f(actual)h(name)g(as)g(it)f(w)o(ould)g(be)h(used)g (in,)0 3488 y(for)d(e)o(xample,)f(a)h Fd(cif)g(ostyle)f Fg(command.)30 b(F)o(or)25 b(e)o(xample,)f(the)g(statement)900 3680 y Fd(style)h(scmos0.18)e(v)o(ariants)i(\(p\),\(c\),\(pc\),\(\))146 3872 y Fg(de\002nes)19 b(four)g(similar)f(styles)g(named)g Fd(scmos0.18\(p\))p Fg(,)i Fd(scmos0.18\(c\))p Fg(,)g Fd(scmos0.18\(pc\))p Fg(,)g(and)e Fd(scmos0.18\(\))p Fg(.)0 3993 y(All)23 b(of)h(the)g(v)n(ariants)f(are)i(assumed)e(to)g (be)h(minor)f(v)n(ariations)g(on)g(the)h(base)g(style.)30 b(W)l(ithin)22 b(each)j(style)e(descrip-)0 4113 y(tion,)29 b(statements)e(may)h(apply)g(to)g(a)h(single)f(v)n(ariant,)h(a)g(group) f(of)g(v)n(ariants,)h(or)g(all)f(v)n(ariants.)41 b(After)29 b(the)f Fd(style)0 4233 y Fg(statement)i(has)i(been)f(processed,)i(all) e(follo)n(wing)e(lines)i(are)h(assumed)f(to)g(refer)h(to)f(all)g(v)n (ariants)f(of)i(the)f(base)0 4354 y(style)24 b(until)g(a)h Fd(v)o(ariant)g Fg(statment)e(is)i(encountered.)30 b(This)24 b(statment)g(tak)o(es)g(the)h(form:)900 4546 y Fd(v)o(ariant)g Fh(variantname)o(,.)15 b(.)g(.)146 4738 y Fg(to)36 b(refer)g(to)g(one)f (or)h(more)f(v)n(ariants)g(in)g(a)h(comma-separated)g(list.)62 b(All)35 b(lines)g(follo)n(wing)f(the)h Fd(v)o(ariant)0 4859 y Fg(statment)24 b(will)g(apply)g(only)g(to)h(the)f(speci\002c)i (process)f(v)n(ariants)f(in)g(the)h(list,)f(until)f(another)i Fd(v)o(ariant)g Fg(statement)0 4979 y(is)31 b(encountered.)51 b(The)32 b(special)f(character)i(\223)p Fd(*)p Fg(\224)f(can)g(be)f (used)g(as)h(a)g(shorthand)f(notation)f(for)i(specifying)e(all)0 5100 y(process)25 b(v)n(ariants:)900 5292 y Fd(v)o(ariant)g(*)1850 5649 y Fg(\22653\226)p eop end %%Trailer userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tut1.ps0000644000175000001440000012777310751423606015152 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: tut1.dvi %%Pages: 7 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman Courier %%+ Times-BoldItalic %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips tut1.dvi -o tut1.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1433 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Bold % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tut1.dvi) @start /Fa 1 63 df<7000000000000000FC00000000000000FF000000000000007FC0 0000000000001FF000000000000007FC00000000000001FF000000000000007FC0000000 0000001FF000000000000007FE00000000000001FF800000000000007FE0000000000000 1FF800000000000003FE00000000000000FF800000000000003FE00000000000000FF800 000000000003FF00000000000000FFC00000000000003FF00000000000000FFC00000000 000001FF000000000000007FC00000000000001FF000000000000007FC00000000000001 FF000000000000007FC00000000000001FE00000000000001FE00000000000007FC00000 00000001FF00000000000007FC0000000000001FF00000000000007FC0000000000001FF 0000000000000FFC0000000000003FF0000000000000FFC0000000000003FF0000000000 000FF80000000000003FE0000000000000FF80000000000003FE0000000000001FF80000 000000007FE0000000000001FF80000000000007FE0000000000001FF00000000000007F C0000000000001FF00000000000007FC0000000000001FF00000000000007FC000000000 0000FF00000000000000FC0000000000000070000000000000003B3878B44C>62 D E /Fb 135[50 2[55 28 39 39 2[50 55 78 3[28 1[50 1[44 3[50 8[66 11[61 17[33 8[50 49[{ TeXBase1Encoding ReEncodeFont }16 100.000003 /Times-BoldItalic rf /Fc 2 104 df<0000000FE0000000FFE0000003 FC0000000FE00000003FC00000007F80000000FF00000000FE00000001FC00000001FC00 000003F800000003F800000003F800000003F800000003F800000003F800000003F80000 0003F800000003F800000003F800000003F800000003F800000003F800000003F8000000 03F800000003F800000003F800000003F800000003F800000003F800000003F800000003 F800000003F800000003F800000003F800000003F800000003F800000003F800000003F8 00000003F800000003F800000007F000000007F00000000FE00000001FE00000003FC000 00007F80000000FE00000007F8000000FFE0000000FFE000000007F800000000FE000000 007F800000003FC00000001FE00000000FE000000007F000000007F000000003F8000000 03F800000003F800000003F800000003F800000003F800000003F800000003F800000003 F800000003F800000003F800000003F800000003F800000003F800000003F800000003F8 00000003F800000003F800000003F800000003F800000003F800000003F800000003F800 000003F800000003F800000003F800000003F800000003F800000003F800000003F80000 0003F800000001FC00000001FC00000000FE00000000FF000000007F800000003FC00000 000FE000000003FC00000000FFE00000000FE0236479CA32>102 DI E /Fd 103[60 30[60 60 60 1[60 60 60 60 1[60 60 60 60 60 60 1[60 1[60 60 60 60 60 60 60 7[60 60 2[60 60 60 60 1[60 60 1[60 60 2[60 1[60 60 60 60 60 60 60 60 5[60 1[60 5[60 60 60 60 60 60 45[{ TeXBase1Encoding ReEncodeFont }49 100.000003 /Courier rf /Fe 103[33 30[50 50 72 50 55 33 39 44 55 55 50 55 83 28 2[28 55 50 1[44 55 44 55 50 12[66 18[72 6[33 8[50 1[28 25 33 45[{ TeXBase1Encoding ReEncodeFont }30 100.000003 /Times-Bold rf /Ff 105[50 1[44 44 24[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 3[33 1[33 1[72 72 94 72 72 61 55 66 1[55 72 72 89 61 1[39 33 72 72 55 61 72 66 66 72 5[28 28 50 50 50 50 50 50 50 50 50 50 1[25 33 25 56 1[33 33 33 1[83 1[50 1[33 29[55 55 2[{ TeXBase1Encoding ReEncodeFont }78 100.000003 /Times-Roman rf /Fg 134[44 44 66 1[50 28 39 39 1[50 50 50 72 28 1[28 28 50 50 28 44 50 44 50 50 8[61 2[72 5[72 1[83 2[44 5[72 18[50 2[25 1[25 2[33 33 37[50 2[{ TeXBase1Encoding ReEncodeFont }34 100.000003 /Times-Italic rf /Fh 135[72 104 72 80 48 56 64 1[80 72 80 120 40 80 1[40 80 72 1[64 80 64 80 72 8[104 143 1[104 96 80 104 1[88 2[135 3[56 112 112 3[104 96 104 1[72 4[48 2[72 72 72 72 72 72 72 13[72 32[80 2[{ TeXBase1Encoding ReEncodeFont }46 143.999997 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 880 101 a Fh(Magic)36 b(T)-13 b(utorial)34 b(#1:)43 b(Getting)34 b(Started)1618 521 y Fg(J)n(ohn)24 b(Ousterhout)1401 941 y Ff(Computer)g(Science)i(Di)n(vision)1020 1062 y(Electrical)f (Engineering)f(and)h(Computer)f(Sciences)1473 1182 y(Uni)n(v)o(ersity)f (of)i(California)1544 1303 y(Berk)o(ele)o(y)-6 b(,)24 b(CA)h(94720)1448 1573 y Fg(\(Updated)f(by)h(other)o(s,)f(too.\))1053 1843 y Ff(This)g(tutorial)g(corresponds)g(to)g(Magic)h(v)o(ersion)e(7.) 0 2569 y Fh(1)143 b(What)36 b(is)f(Magic?)0 2793 y Ff(Magic)26 b(is)g(an)h(interacti)n(v)o(e)e(system)h(for)g(creating)h(and)f (modifying)f(VLSI)i(circuit)f(layouts.)35 b(W)l(ith)26 b(Magic,)h(you)0 2913 y(use)j(a)g(color)g(graphics)g(display)f(and)h(a) h(mouse)e(or)h(graphics)g(tablet)f(to)h(design)f(basic)h(cells)g(and)g (to)g(combine)0 3034 y(them)35 b(hierarchically)g(into)f(lar)n(ge)i (structures.)62 b(Magic)35 b(is)f(dif)n(ferent)h(from)g(other)h(layout) e(editors)h(you)f(may)0 3154 y(ha)n(v)o(e)f(used.)55 b(The)34 b(most)e(important)f(dif)n(ference)j(is)f(that)f(Magic)h(is)g (more)g(than)g(just)f(a)h(color)g(painting)f(tool:)0 3275 y(it)k(understands)g(quite)h(a)g(bit)f(about)g(the)h(nature)g(of)g (circuits)f(and)h(uses)g(this)f(information)f(to)i(pro)o(vide)f(you)0 3395 y(with)e(additional)f(operations.)60 b(F)o(or)35 b(e)o(xample,)h(Magic)f(has)g(b)n(uilt-in)e(kno)n(wledge)h(of)g(layout) g(rules;)40 b(as)35 b(you)0 3515 y(are)c(editing,)g(it)f(continuously)f (checks)i(for)g(rule)f(violations.)46 b(Magic)31 b(also)f(kno)n(ws)f (about)h(connecti)n(vity)f(and)0 3636 y(transistors,)g(and)g(contains)f (a)h(b)n(uilt-in)f(hierarchical)h(circuit)g(e)o(xtractor)-5 b(.)43 b(Magic)29 b(also)f(has)h(a)h Fg(plow)f Ff(operation)0 3756 y(that)h(you)h(can)g(use)f(to)h(stretch)f(or)h(compact)g(cells.)48 b(Lastly)-6 b(,)31 b(Magic)f(has)h(routing)e(tools)h(that)g(you)h(can)g (use)f(to)0 3876 y(mak)o(e)25 b(the)f(global)g(interconnections)g(in)g (your)h(circuits.)146 3997 y(Magic)f(is)g(based)g(on)g(the)g(Mead-Conw) o(ay)g(style)g(of)g(design.)30 b(This)23 b(means)h(that)g(it)f(uses)h (simpli\002ed)f(design)0 4117 y(rules)g(and)f(circuit)h(structures.)29 b(The)23 b(simpli\002cations)e(mak)o(e)h(it)h(easier)g(for)g(you)f(to)h (design)f(circuits)g(and)h(permit)0 4238 y(Magic)28 b(to)g(pro)o(vide)f (po)n(werful)g(assistance)h(that)f(w)o(ould)h(not)f(be)i(possible)d (otherwise.)41 b(Ho)n(we)n(v)o(er)l(,)27 b(the)o(y)h(result)0 4358 y(in)36 b(slightly)f(less)h(dense)g(circuits)g(than)h(you)f(could) g(get)g(with)g(more)g(comple)o(x)g(rules)g(and)h(structures.)65 b(F)o(or)0 4478 y(e)o(xample,)32 b(Magic)g(permits)f(only)f Fg(Manhattan)h Ff(designs)f(\(those)i(whose)f(edges)h(are)g(v)o (ertical)f(or)h(horizontal\).)0 4599 y(Circuit)23 b(designers)g(tell)g (us)g(that)g(our)g(conserv)n(ati)n(v)o(e)e(design)i(rules)g(cost)g (5-10\045)g(in)g(density)-6 b(.)28 b(W)-8 b(e)24 b(think)e(that)h(the)0 4719 y(density)h(sacri\002ce)i(is)e(compensated)g(for)h(by)g(reduced)g (design)f(time.)0 5056 y Fh(2)143 b(Ho)o(w)35 b(to)g(Get)g(Help)g(and)g (Report)f(Pr)m(oblems)0 5280 y Ff(There)27 b(are)g(se)n(v)o(eral)f(w)o (ays)g(you)g(can)g(get)h(help)f(about)f(Magic.)35 b(If)27 b(you)f(are)h(trying)f(to)g(learn)g(about)g(the)g(system,)0 5400 y(you)j(should)e(start)i(of)n(f)g(with)f(the)h(Magic)f(tutorials,) h(of)g(which)g(this)f(is)g(the)h(\002rst.)43 b(Each)30 b(tutorial)e(introduces)g(a)1875 5649 y(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Ff(September)25 b(26,)f(2001)1715 b(Magic)24 b(T)l(utorial)g(#1:)30 b(Getting)24 b(Started)p 449 3 3003 4 v 447 124 4 121 v 498 88 a(Magic)h(T)l(utorial)e(#1:)30 b(Getting)24 b(Started)p 3450 124 V 447 244 V 498 208 a(Magic)h(T)l(utorial)e(#2:)30 b(Basic)c(P)o(ainting)d(and)i(Selection) p 3450 244 V 447 364 V 498 328 a(Magic)g(T)l(utorial)e(#3:)30 b(Adv)n(anced)25 b(P)o(ainting)e(\(W)l(iring)i(and)f(Plo)n(wing\))p 3450 364 V 447 485 V 498 449 a(Magic)h(T)l(utorial)e(#4:)30 b(Cell)25 b(Hierarchies)p 3450 485 V 447 605 V 498 569 a(Magic)g(T)l(utorial)e(#5:)30 b(Multiple)24 b(W)l(indo)n(ws)p 3450 605 V 447 726 V 498 689 a(Magic)h(T)l(utorial)e(#6:)30 b(Design-Rule)25 b(Checking)p 3450 726 V 447 846 V 498 810 a(Magic)g(T)l(utorial)e(#7:)30 b(Netlists)24 b(and)h(Routing)p 3450 846 V 447 966 V 498 930 a(Magic)g(T)l(utorial)e(#8:)30 b(Circuit)25 b(Extraction)p 3450 966 V 447 1087 V 498 1051 a(Magic)g(T)l(utorial)e(#9:)30 b(F)o(ormat)25 b(Con)l(v)o(ersion)e (for)j(CIF)f(and)g(Calma)p 3450 1087 V 447 1207 V 498 1171 a(Magic)g(T)l(utorial)e(#10:)30 b(The)25 b(Interacti)n(v)o(e)f (Route)p 3450 1207 V 447 1328 V 498 1291 a(Magic)h(T)l(utorial)e(#11:) 30 b(Using)24 b(RSIM)i(with)e(Magic)p 3450 1328 V 449 1331 3003 4 v 447 1451 4 121 v 498 1415 a(Magic)h(Maintainer')-5 b(s)23 b(Manual)i(#1:)30 b(Hints)24 b(for)h(System)f(Maintainers)p 3450 1451 V 447 1572 V 498 1535 a(Magic)h(Maintainer')-5 b(s)23 b(Manual)i(#2:)30 b(The)25 b(T)-7 b(echnology)23 b(File)p 3450 1572 V 447 1692 V 498 1656 a(Magic)i(Maintainer')-5 b(s)23 b(Manual)i(#3:)30 b(Display)24 b(Styles,)g(Color)h(Maps,)f(and)h (Glyphs)p 3450 1692 V 447 1812 V 498 1776 a(Magic)g(Maintainer')-5 b(s)23 b(Manual)i(#4:)30 b(Using)24 b(Magic)g(Under)h(X)g(W)l(indo)n (ws)p 3450 1812 V 449 1816 3003 4 v 447 1936 4 121 v 498 1900 a(Magic)g(T)-7 b(echnology)24 b(Manual)g(#1:)30 b(NMOS)p 3450 1936 V 447 2056 V 498 2020 a(Magic)25 b(T)-7 b(echnology)24 b(Manual)g(#2:)30 b(SCMOS)p 3450 2056 V 449 2060 3003 4 v 404 2327 a(T)-8 b(able)25 b(1:)30 b(The)25 b(Magic)g(tutorials,)e(maintenance)i(manuals,)e(and)i (technology)f(manuals.)0 2573 y(particular)e(set)h(of)g(f)o(acilities)e (in)h(Magic.)30 b(There)23 b(is)f(also)g(a)h(set)g(of)f(manuals)g (intended)g(for)h(system)e(maintainers.)0 2694 y(These)33 b(describe)f(things)g(lik)o(e)g(ho)n(w)g(to)g(create)h(ne)n(w)g (technologies.)53 b(Finally)-6 b(,)33 b(there)g(is)f(a)h(set)g(of)f (technology)0 2814 y(manuals.)k(Each)28 b(one)e(of)i(the)e(technology)g (manuals)g(describes)h(the)g(features)g(peculiar)g(to)g(a)g(particular) g(tech-)0 2934 y(nology)-6 b(,)23 b(such)i(as)g(layer)g(names)f(and)h (design)f(rules.)31 b(T)-8 b(able)25 b(1)f(lists)g(all)g(of)h(the)g (Magic)g(manuals.)30 b(The)24 b(tutorials)0 3055 y(are)g(designed)e(to) g(be)h(read)g(while)g(you)f(are)i(running)d(Magic,)i(so)g(that)f(you)g (can)i(try)e(out)g(the)h(ne)n(w)f(commands)g(as)0 3175 y(the)o(y)k(are)i(e)o(xplained.)37 b(Y)-11 b(ou)27 b(needn')n(t)g(read) h(all)f(the)g(tutorials)f(at)h(once;)i(each)e(tutorial)f(lists)g(the)h (other)g(tutorials)0 3295 y(that)d(you)h(should)e(read)j(\002rst.)146 3416 y(The)e(tutorials)f(are)i(not)e(necessarily)h(complete.)30 b(Each)24 b(one)g(is)f(designed)h(to)f(introduce)h(a)g(set)g(of)g(f)o (acilities,)0 3536 y(b)n(ut)c(it)g(doesn')n(t)h(necessarily)f(co)o(v)o (er)g(e)n(v)o(ery)g(possibility)-6 b(.)26 b(The)21 b(ultimate)f (authority)f(on)i(ho)n(w)e(Magic)i(w)o(orks)f(is)g(the)0 3657 y(reference)28 b(manual,)e(which)g(is)g(a)h(standard)f(Unix)g Fg(man)g Ff(page.)35 b(The)27 b Fg(man)f Ff(page)g(gi)n(v)o(es)f (concise)h(and)h(complete)0 3777 y(descriptions)i(of)i(all)g(the)g (Magic)f(commands.)47 b(Once)32 b(you)e(ha)n(v)o(e)g(a)i(general)f (idea)g(ho)n(w)f(a)h(command)f(w)o(orks,)0 3897 y(the)24 b Fg(man)g Ff(page)g(is)g(probably)g(easier)g(to)g(consult)f(than)h (the)g(tutorial.)29 b(Ho)n(we)n(v)o(er)l(,)23 b(the)h Fg(man)g Ff(page)h(may)f(not)f(mak)o(e)0 4018 y(much)h(sense)h(until)f (after)h(you')-5 b(v)o(e)24 b(read)h(the)g(tutorial.)146 4138 y(A)h(third)e(w)o(ay)h(of)h(getting)e(help)g(is)h(a)n(v)n(ailable) g(on-line)f(through)g(Magic)h(itself.)31 b(The)26 b Fe(:help)g Ff(command)e(will)0 4259 y(print)i(out)g(one)h(line)f(for)h(each)h (Magic)e(command,)g(gi)n(ving)g(the)g(command')-5 b(s)25 b(syntax)h(and)h(an)g(e)o(xtremely)f(brief)0 4379 y(description)k(of)h (the)f(command.)48 b(This)30 b(f)o(acility)h(is)f(useful)g(if)h(you')-5 b(v)o(e)30 b(for)n(gotten)h(the)f(name)h(or)g(e)o(xact)g(syntax)0 4499 y(of)26 b(a)h(command.)33 b(After)27 b(each)g(screenful)f(of)g (help)g(information,)f Fe(:help)i Ff(stops)e(and)h(prints)f (\223\226More\226\224.)35 b(If)27 b(you)0 4620 y(type)e(a)h(space,)h (the)e(ne)o(xt)g(screenful)h(of)g(data)g(will)e(be)i(output,)f(and)g (if)h(you)f(type)h Fe(q)g Ff(the)g(rest)f(of)h(the)g(output)e(will)0 4740 y(be)h(skipped.)30 b(If)25 b(you')-5 b(re)25 b(interested)f(in)h (information)e(about)h(a)h(particular)g(subject,)f(you)g(can)i(type)900 4950 y Fe(:help)g Fg(subject)146 5159 y Ff(This)e(command)g(will)g (print)g(out)g(each)i(command)e(description)f(that)i(contains)f(the)g Fg(subject)g Ff(string.)146 5280 y(If)32 b(you)g(ha)n(v)o(e)f(a)h (question)e(or)i(problem)f(that)g(can')n(t)h(be)f(answered)h(with)f(an) o(y)g(of)h(the)f(abo)o(v)o(e)g(approaches,)0 5400 y(you)37 b(may)h(contact)f(the)h(Magic)f(authors)g(by)h(sending)f(mail)g(to)g Fd(magic@ucbarpa.Berkeley.EDU)p Ff(.)1875 5649 y(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Ff(Magic)24 b(T)l(utorial)g(#1:)30 b(Getting)24 b(Started)1715 b(September)25 b(26,)g(2001)0 68 y(This)k(will)g(log)h (your)g(message)f(in)h(a)h(\002le)f(\(so)g(we)g(can')n(t)h(for)n(get)f (about)g(it\))f(and)h(forw)o(ard)h(the)f(message)g(to)f(the)0 188 y(Magic)34 b(maintainers.)59 b(Magic)35 b(maintenance)f(is)g(a)h (mostly)e(v)n(olunteer)h(ef)n(fort,)j(so)d(when)h(you)f(report)h(a)g(b) n(ug)0 309 y(or)f(ask)f(a)i(question,)f Fg(please)g Ff(be)f (speci\002c.)58 b(Ob)o(viously)-6 b(,)34 b(the)f(more)h(speci\002c)g (you)f(are,)k(the)c(more)h(lik)o(ely)f(we)0 429 y(can)c(answer)h(your)e (question)g(or)h(reproduce)g(the)g(b)n(ug)g(you)f(found.)43 b(W)-8 b(e')o(ll)29 b(tend)g(to)f(answer)h(the)g(speci\002c)h(b)n(ug)0 549 y(reports)c(\002rst,)h(since)f(the)o(y)g(in)l(v)n(olv)o(e)f(less)g (time)h(on)g(our)g(part.)36 b(T)m(ry)26 b(to)g(describe)g(the)g(e)o (xact)g(sequence)h(of)f(e)n(v)o(ents)0 670 y(that)32 b(led)g(to)g(the)g(problem,)h(what)f(you)g(e)o(xpected)g(to)f(happen,)j (and)e(what)g(actually)g(happened.)53 b(If)33 b(possible,)0 790 y(\002nd)25 b(a)g(small)f(e)o(xample)g(that)h(reproduces)g(the)f (problem)h(and)f(send)h(us)g(the)f(rele)n(v)n(ant)g(\(small!\))31 b(\002les)25 b(so)g(we)g(can)0 911 y(mak)o(e)g(it)f(happen)h(here.)31 b(Or)25 b(best)f(of)h(all,)g(send)f(us)h(a)g(b)n(ug)f(\002x)h(along)f (with)h(a)g(small)e(e)o(xample)h(of)h(the)g(problem.)0 1256 y Fh(3)143 b(Graphics)34 b(Con\002guration)0 1481 y Ff(Magic)h(can)h(be)g(run)f(with)g(dif)n(ferent)g(graphics)g(hardw)o (are.)63 b(The)36 b(most)e(common)g(con\002guration)h(is)g(to)g(run)0 1601 y(Magic)26 b(under)h(X11)f(on)g(a)h(w)o(orkstation.)34 b(Another)26 b(w)o(ay)h(to)f(run)g(Magic)g(is)g(under)h(SunV)-6 b(ie)n(w)25 b(on)i(a)f(Sun)h(w)o(ork-)0 1722 y(station,)g(or)h(under)g (OpenGL)g(\(in)g(an)g(X11)f(en)l(vironment\))g(on)h(an)g(SGI)g(w)o (orkstation)f(or)h(Linux)f(box)g(with)g(ac-)0 1842 y(celerated)h(3D)g (video)f(hardw)o(are)h(and)g(dri)n(v)o(ers.)37 b(Le)o(gac)o(y)27 b(code)h(e)o(xists)e(supporting)g(AED)h(graphics)g(terminals)0 1962 y(and)e(X10)f(\(the)h(forerunner)g(of)g(X11\).)31 b(The)25 b(rest)f(of)h(this)f(section)g(concerns)h(X11.)146 2084 y(Before)32 b(starting)e(up)g(magic,)h(mak)o(e)g(sure)g(that)f (your)g Fd(DISPLAY)f Ff(v)n(ariable)h(is)g(set)h(correctly)-6 b(.)47 b(If)31 b(you)f(are)0 2204 y(running)24 b(magic)g(and)h(your)g (X)f(serv)o(er)h(on)g(the)f(same)h(machine,)f(set)h(it)f(to)h Fd(unix:0)p Ff(:)900 2439 y Fe(seten)l(v)h Fd(DISPLAY)58 b(unix:0)146 2673 y Ff(The)25 b(Magic)f(windo)n(w)f(is)h(an)g(ordinary) g(X)h(windo)n(w)-6 b(,)22 b(and)j(can)g(be)f(mo)o(v)o(ed)f(and)h (resized)h(using)e(the)h(windo)n(w)0 2794 y(manager)-5 b(.)146 2915 y(F)o(or)25 b(no)n(w)-6 b(,)24 b(you)g(can)h(skip)f(to)g (the)h(ne)o(xt)f(major)g(section:)30 b(\224Running)25 b(Magic\224.)0 3260 y Fh(4)143 b(Adv)o(anced)33 b(X)j(Use)0 3485 y Ff(The)f(X11)f(dri)n(v)o(er)g(can)h(read)g(in)f(windo)n(w)g (sizing)g(and)g(font)g(preferences)i(from)f(your)f Fg(.Xdefaults)f Ff(\002le.)61 b(The)0 3606 y(follo)n(wing)23 b(speci\002cations)h(are)i (recognized:)300 3841 y Fe(magic.windo)o(w:)477 b Ff(1000x600+10+10)300 3961 y Fe(magic.newwindo)o(w:)306 b Ff(300x300+400+100)300 4081 y Fe(magic.small:)580 b Ff(helv)o(etica8)300 4202 y Fe(magic.medium:)460 b Ff(helv)o(etica12)300 4322 y Fe(magic.lar)o(ge:)593 b Ff(helv)o(etica18)300 4443 y Fe(magic.xlar)o(ge:)543 b Ff(helv)o(etica24)146 4677 y Fe(magic.windo)o(w)28 b Ff(is)g(the)g(size)g(and)h(position)d(of)i (the)g(initial)f(windo)n(w)-6 b(,)27 b(while)h Fe(magic.newwindo)o(w)g Ff(is)g(the)0 4797 y(size)e(and)g(position)e(of)i(subsequent)f(windo)n (ws.)33 b(If)27 b(these)e(are)i(left)f(blank,)g(you)g(will)f(be)h (prompted)f(to)h(gi)n(v)o(e)e(the)0 4918 y(windo)n(w')-5 b(s)29 b(position)g(and)h(size.)49 b Fe(small)p Ff(,)31 b Fe(medium)p Ff(,)i Fe(lar)o(ge)p Ff(,)f(and)f Fe(xlar)o(ge)f Ff(are)h(v)n(arious)f(fonts)g(magic)g(uses)h(for)0 5038 y(labels.)e(Some)22 b(X11)f(serv)o(ers)g(read)h(the)f Fd(.Xdefaults)f Ff(\002le)i(only)e(when)i(you)f(initially)e(log)i(in;)h (you)f(may)g(ha)n(v)o(e)0 5158 y(to)j(run)h Fd(xrdb)59 b(-load)g(\230/.Xdefaults)22 b Ff(for)j(the)g(changes)f(to)h(tak)o(e)g (ef)n(fect.)146 5280 y(Under)j(X11,)f(Magic)g(can)h(run)f(on)g(a)g (display)f(of)i(an)o(y)f(depth)f(for)i(which)f(there)g(are)h(colormap)f (and)g(dstyle)0 5400 y(\002les.)37 b(Monochrome,)26 b(4)g(bit,)h(6)f (bit,)h(7)f(bit,)h(and)g(24)f(bit)g(\002les)h(for)g(MOS)g(are)g (distrib)n(uted)e(in)h(this)g(release.)37 b(Y)-11 b(ou)1875 5649 y(\2263\226)p eop %%Page: 4 4 4 3 bop 0 -180 a Ff(September)25 b(26,)f(2001)1715 b(Magic)24 b(T)l(utorial)g(#1:)30 b(Getting)24 b(Started)0 68 y(can)i(e)o (xplicitly)d(specify)i(ho)n(w)g(man)o(y)f(planes)h(Magic)g(is)g(to)g (use)g(by)g(adding)g(a)h(suf)n(\002x)f(numeral)f(between)i(1)f(and)0 188 y(7)35 b(to)f(\223XWIND\224)h(when)g(used)g(with)f(Magic')-5 b(s)33 b(\223-d\224)j(option.)59 b(F)o(or)35 b(e)o(xample,)h(\223magic) f(-d)g(XWIND1\224)f(runs)0 309 y(magic)23 b(on)g(a)h(monochrome)e (display)g(and)i(\223magic)f(-d)g(XWIND7\224)h(runs)f(magic)g(on)g(a)h (7)f(plane)h(display)-6 b(.)28 b(If)c(this)0 429 y(number)h(is)f(not)h (speci\002ed,)g(magic)g(checks)g(the)g(depth)g(of)g(the)g(display)f (and)h(picks)g(the)g(lar)n(gest)g(number)g(in)f(the)0 549 y(set)g Fc(f)p Ff(1,)g(4,)g(6,)h(7,)f(16,)g(24)p Fc(g)g Ff(that)g(the)g(display)f(will)g(support.)30 b(Another)24 b(w)o(ay)g(to)g(force)h(the)f(display)g(type)g(is)f(to)h(set)0 670 y(an)h(en)l(vironment)e(v)n(ariable)i(called)g Fd(MAGIC)p 1556 670 30 4 v 34 w(COLOR)f Ff(to)h(one)f(of)h(the)g(strings)e (\2238bit\224,)i(\22316bit\224,)f(or)h(\22324bit\224.)0 835 y Fb(Linux)g(note:)0 955 y Ff(Magic')-5 b(s)29 b(\223nati)n(v)o (e\224)f(display)h(\(e)o(xcept)h(when)f(using)g(the)g(OpenGL)h(interf)o (ace\))g(is)f(the)h(8-bit)f(PseudoColor)g(vi-)0 1076 y(sual)38 b(type.)71 b(24-bit)38 b(T)m(rueColor)g(visuals)f(pre)n(v)o (ent)h(Magic)g(from)g(allocating)f(colors)h(for)h(bit-plane)f(logical)0 1196 y(operations,)32 b(so)g(the)f(24-bit)g(interf)o(ace)h(is)f (visually)f(some)n(what)h(sub-par)l(,)i(requiring)e(stipple)f(patterns) h(on)g(all)0 1316 y(metal)26 b(layers,)h(for)h(instance.)36 b(Under)27 b(Linux,)f(a)h(fe)n(w)g(\(commercial\))f(X)h(dri)n(v)o(ers)f (will)g(support)f(8-bit)h(o)o(v)o(erlays)0 1437 y(on)k(top)f(of)h (24-bit)f(T)m(rueColor)h(when)g(using)f(32-bit)g(color)-5 b(.)45 b(This)29 b(is)h(the)g(ideal)f(w)o(ay)i(to)e(use)h(magic,)h (because)0 1557 y(the)c(colormap)g(for)h(the)g(rest)f(of)h(the)g (display)e(is)h(preserv)o(ed)h(when)f(the)h(cursor)f(is)h(inside)e(the) i(Magic)f(windo)n(w)-6 b(.)0 1678 y(Otherwise,)23 b(the)h(X)f(session)g (may)g(ha)n(v)o(e)h(to)f(be)h(started)f(using)g(\223)p Fd(startx)58 b(--bpp)h(8)p Ff(\224)24 b(to)f(force)h(it)f(to)h(use)f (the)0 1798 y(8-bit)h(PseudoColor)h(visual.)0 1963 y Fb(X11)g(remote)f(usage)h(note:)0 2083 y Ff(When)i(running)f(Magic)h (remotely)f(on)h(an)g(X)g(terminal,)g(the)g(colormap)f(allocation)g (may)h(dif)n(fer)g(for)g(the)g(local)0 2204 y(machine)e(compared)f(to)h (the)g(remote)f(machine.)31 b(In)25 b(some)f(cases,)h(this)f(can)h (cause)h(the)e(background)h(of)g(magic)0 2324 y(to)h(appear)h(black,)f (usually)g(with)f(a)i(black-on-black)f(cursor)-5 b(.)35 b(This)25 b(is)h(kno)n(wn)f(to)h(be)h(true)f(of)h(X11)f(dri)n(v)o(ers)f (for)0 2444 y(W)l(indo)n(ws)32 b(\(such)h(as)h(PC-XW)-8 b(are\),)37 b(due)d(to)f(the)g(w)o(ay)g(the)h(W)l(indo)n(ws)e(8-bit)g (PseudoColor)i(colormap)e(is)h(set)0 2565 y(up.)d(This)23 b(beha)n(vior)g(can)h(be)f(corrected)h(by)f(setting)g(tw)o(o)g(en)l (vironment)f(v)n(ariables)g(on)i(the)f(remote)g(machine)g(as)0 2685 y(follo)n(ws:)900 2893 y Fe(seten)l(v)j Fd(X)p 1253 2893 V 35 w(COLORMAP)p 1768 2893 V 34 w(BASE)59 b(128)900 3013 y Fe(seten)l(v)26 b Fd(X)p 1253 3013 V 35 w(COLORMAP)p 1768 3013 V 34 w(DEFAULT)58 b(0)146 3341 y Ff(This)39 b(causes)g(Magic)f(to)h(a)n(v)n(oid)f(trying)g(to)h(allocate)g(the)g (\002rst)g(color)f(in)h(the)g(colormap,)j(which)c(under)0 3462 y(W)l(indo)n(ws)23 b(is)i(\002x)o(ed)f(as)h(black.)0 3798 y Fh(5)143 b(Running)34 b(Magic)0 4022 y Ff(From)29 b(this)e(point)h(on,)h(you)g(should)e(be)i(sitting)e(at)i(a)g(Magic)f (w)o(orkstation)f(so)i(you)f(can)h(e)o(xperiment)e(with)h(the)0 4142 y(program)i(as)g(you)f(read)h(the)g(manuals.)45 b(Starting)30 b(up)f(Magic)h(is)f(usually)g(pretty)h(simple.)44 b(Just)29 b(log)h(in)f(and,)i(if)0 4263 y(needed,)25 b(start)f(up)h(your)f(f)o(a)n(v)n(orite)h(windo)n(w)f(system.)29 b(Then)c(type)f(the)h(shell)f(command)900 4470 y Fe(magic)g(tut1)146 4678 y(T)-9 b(ut1)28 b Ff(is)f(the)g(name)g(of)g(a)h(library)f(cell)g (that)f(you)h(will)f(play)h(with)g(in)f(this)h(tutorial.)36 b(At)27 b(this)f(point,)h(se)n(v)o(eral)0 4798 y(colored)36 b(rectangles)g(should)f(appear)i(on)f(the)g(color)g(display)f(along)h (with)g(a)g(white)g(box)g(and)g(a)g(cursor)-5 b(.)65 b(A)0 4918 y(message)29 b(will)g(be)h(printed)f(on)h(the)g(te)o(xt)f (display)f(to)i(tell)f(you)g(that)h Fe(tut1)g Ff(isn')n(t)f(writable)h (\(it')-5 b(s)29 b(in)g(a)h(read-only)0 5039 y(library\),)e(and)g(a)h (\223)p Fa(>)p Ff(\224)f(prompt)f(should)f(appear)-5 b(.)41 b(If)28 b(this)f(has)h(happened,)g(then)g(you)f(can)h(skip)f (the)h(rest)g(of)g(this)0 5159 y(section)c(\(e)o(xcept)h(for)g(the)f (note)h(belo)n(w\))f(and)h(go)f(directly)h(to)f(Section)h(5.)146 5280 y(Note:)36 b(in)27 b(the)g(tutorials,)f(when)i(you)e(see)i(things) e(printed)h(in)g(boldf)o(ace,)h(for)f(e)o(xample,)g Fe(magic)g(tut1)h Ff(from)0 5400 y(abo)o(v)o(e,)j(the)o(y)f(refer)i(to)e(things)f(you)h (type)h(e)o(xactly)-6 b(,)30 b(such)h(as)f(command)g(names)g(and)h (\002le)g(names.)48 b(These)30 b(are)1875 5649 y(\2264\226)p eop %%Page: 5 5 5 4 bop 0 -180 a Ff(Magic)24 b(T)l(utorial)g(#1:)30 b(Getting)24 b(Started)1715 b(September)25 b(26,)g(2001)0 69 y(usually)h(case)h (sensiti)n(v)o(e)d(\()p Fe(A)j Ff(is)g(dif)n(ferent)f(from)g Fe(a)p Ff(\).)37 b(When)27 b(you)f(see)h(things)e(printed)h(in)h (italics,)f(the)o(y)g(refer)h(to)0 189 y(classes)e(of)g(things)e(you)i (might)f(type.)31 b(Ar)n(guments)24 b(in)g(square)h(brack)o(ets)g(are)h (optional.)k(F)o(or)25 b(e)o(xample,)f(a)h(more)0 309 y(complete)f(description)g(of)h(the)f(shell)g(command)g(for)h(Magic)g (is)900 550 y Fe(magic)f Ff([)p Fg(\002le)p Ff(])146 788 y(Y)-11 b(ou)28 b(could)f(type)h(an)o(y)g(\002le)g(name)g(for)g Fg(\002le)p Ff(,)h(and)e(Magic)h(w)o(ould)f(start)h(editing)f(that)g (\002le.)41 b(It)28 b(turns)f(out)h(that)0 909 y Fe(tut1)i Ff(is)f(just)f(a)h(\002le)h(in)f(Magic')-5 b(s)28 b(cell)h(library)-6 b(.)44 b(If)29 b(you)g(didn')n(t)g(type)f(a)i(\002le)g(name,)g(Magic)f (w)o(ould)f(load)h(a)h(ne)n(w)0 1029 y(blank)24 b(cell.)146 1151 y(If)i(things)e(didn')n(t)h(happen)g(as)g(the)o(y)g(should)f(ha)n (v)o(e)h(when)g(you)g(tried)g(to)g(run)g(Magic,)g(an)o(y)f(of)i(se)n(v) o(eral)e(things)0 1271 y(could)k(be)h(wrong.)42 b(If)29 b(a)g(message)f(of)h(the)f(form)h(\223magic:)38 b(Command)27 b(not)h(found\224)h(appears)g(on)f(your)h(screen)0 1392 y(it)h(is)f(because)i(the)f(shell)f(couldn')n(t)h(\002nd)g(the)g(Magic) g(program.)46 b(The)30 b(most)f(stable)h(v)o(ersion)f(of)h(Magic)g(is)f (the)0 1512 y(directory)36 b Fd(\230cad/bin)p Ff(,)h(and)f(the)g(ne)n (west)g(public)f(v)o(ersion)g(is)h(in)f Fd(\230cad/new)p Ff(.)63 b(Y)-11 b(ou)36 b(should)f(mak)o(e)h(sure)0 1632 y(that)h(both)f(these)h(directories)g(are)h(in)e(your)h(shell)g(path.) 67 b(Normally)-6 b(,)38 b Fd(\230cad/new)e Ff(should)g(appear)i(before) 0 1753 y Fd(\230cad/bin)p Ff(.)g(If)29 b(this)e(sounds)g(lik)o(e)g (gibberish,)h(\002nd)g(a)g(Unix)g(hack)o(er)g(and)g(ha)n(v)o(e)g(him)f (or)h(her)g(e)o(xplain)f(to)h(you)0 1873 y(about)c(paths.)30 b(If)c(w)o(orst)e(comes)g(to)h(w)o(orst,)f(you)g(can)h(in)l(v)n(ok)o(e) g(Magic)f(by)h(typing)e(its)h(full)g(name:)900 2113 y Fe(\230cad/bin/magic)h(tut1)146 2352 y Ff(Another)31 b(possible)e(problem)i(is)f(that)h(Magic)f(might)g(not)g(kno)n(w)g (what)h(kind)f(of)h(display)f(you)h(are)g(using.)0 2472 y(T)-8 b(o)25 b(solv)o(e)e(this,)h(use)h(magic')-5 b(s)24 b Fe(-d)h Ff(\003ag:)900 2685 y Fe(magic)f(-d)i Fg(display)e Fe(tut1)0 2895 y Fg(Display)e Ff(is)h(usually)f(the)h(model)f(number)h (of)g(the)g(w)o(orkstation)f(you)g(are)i(using)e(or)h(the)g(name)g(of)h (your)e(windo)n(w)0 3016 y(system.)48 b(Look)31 b(in)f(the)h(manual)g (page)g(for)g(a)h(list)e(of)h(v)n(alid)f(names,)i(or)f(just)f(guess)h (something.)47 b(Magic)31 b(will)0 3136 y(print)24 b(out)g(the)h(list)f (of)h(v)n(alid)e(names)i(if)g(you)f(guess)g(wrong.)146 3258 y(If)h(you)f(are)h(using)f(a)g(graphics)g(terminal)g(\(not)g(a)g (w)o(orkstation\),)f(it)h(is)g(possible)f(that)h(Magic)g(doesn')n(t)g (kno)n(w)0 3378 y(which)i(serial)h(line)g(to)f(use.)37 b(T)-8 b(o)27 b(learn)g(ho)n(w)f(to)h(\002x)g(this,)f(read)i(about)e (the)h Fe(-g)g Ff(switch)f(in)g(the)h(magic\(1\))g(manual)0 3499 y(page.)k(Also)24 b(read)h(the)g(displays\(5\))f(manual)g(page.)0 3848 y Fh(6)143 b(The)35 b(Box)g(and)g(the)g(Cursor)0 4074 y Ff(T)-8 b(w)o(o)30 b(things,)g(called)g(the)f Fg(box)h Ff(and)g(the)g Fg(cur)o(sor)p Ff(,)g(are)h(used)f(to)f(select) h(things)f(on)h(the)f(color)h(display)-6 b(.)45 b(As)30 b(you)0 4195 y(mo)o(v)o(e)24 b(the)i(mouse,)f(the)g(cursor)h(mo)o(v)o (es)e(on)h(the)h(screen.)34 b(The)26 b(cursor)f(starts)g(out)h(with)e (a)i(crosshair)g(shape,)g(b)n(ut)0 4315 y(you')o(ll)i(see)i(later)f (that)g(its)g(shape)g(changes)g(as)g(you)g(w)o(ork)g(to)g(pro)o(vide)f (feedback)i(about)f(what)g(you')-5 b(re)29 b(doing.)0 4435 y(The)g(left)g(and)g(right)g(mouse)f(b)n(uttons)g(are)i(used)f(to) g(position)e(the)i(box.)43 b(If)30 b(you)f(press)g(the)g(left)g(mouse)f (b)n(utton)0 4556 y(and)g(then)f(release)h(it,)g(the)g(box)f(will)g(mo) o(v)o(e)f(so)h(that)h(its)f(lo)n(wer)g(left)g(corner)i(is)e(at)h(the)f (cursor)h(position.)37 b(If)29 b(you)0 4676 y(press)c(and)h(release)g (the)f(right)g(mouse)g(b)n(utton,)f(the)h(upper)h(right)e(corner)i(of)g (the)f(box)g(will)g(mo)o(v)o(e)f(to)h(the)g(cursor)0 4797 y(position,)k(b)n(ut)g(the)h(lo)n(wer)f(left)g(corner)h(will)f (not)g(change.)46 b(These)29 b(tw)o(o)h(b)n(uttons)e(are)i(enough)f(to) g(position)f(the)0 4917 y(box)k(an)o(ywhere)g(on)g(the)g(screen.)54 b(T)m(ry)32 b(using)g(the)g(b)n(uttons)f(to)h(place)g(the)h(box)e (around)i(each)g(of)f(the)g(colored)0 5037 y(rectangles)25 b(on)f(the)h(screen.)146 5159 y(Sometimes)j(it)h(is)g(con)l(v)o(enient) f(to)g(mo)o(v)o(e)g(the)h(box)g(by)f(a)i(corner)g(other)e(than)h(the)g (lo)n(wer)g(left.)43 b(T)-8 b(o)29 b(do)g(this,)0 5280 y(press)e(the)g(left)g(mouse)g(b)n(utton)f(and)h Fg(hold)g(it)g(down)p Ff(.)38 b(The)27 b(cursor)g(shape)h(changes)f(to)g(sho)n(w)f(you)h (that)g(you)f(are)0 5400 y(mo)o(ving)d(the)i(box)f(by)g(its)g(lo)n(wer) h(left)f(corner:)1875 5649 y(\2265\226)p eop %%Page: 6 6 6 5 bop 0 -180 a Ff(September)25 b(26,)f(2001)1715 b(Magic)24 b(T)l(utorial)g(#1:)30 b(Getting)24 b(Started)p 1870 3 160 4 v 1868 124 4 121 v 2028 124 V 1870 127 160 4 v 146 307 a(While)c(holding)f(the)h(b)n(utton)f(do)n(wn,)h(mo)o(v)o(e)e (the)i(cursor)h(near)f(the)g(lo)n(wer)g(right)f(corner)i(of)f(the)g (box,)h(and)f(no)n(w)0 428 y(click)j(the)g(right)f(mouse)g(b)n(utton)g (\(i.e.)31 b(press)22 b(and)i(release)f(it,)g(while)g(still)e(holding)h (do)n(wn)g(the)h(left)g(b)n(utton\).)29 b(The)0 548 y(cursor')-5 b(s)28 b(shape)g(will)g(change)g(to)g(indicate)g(that)g(you)g(are)h(no) n(w)e(mo)o(ving)g(the)h(box)g(by)g(its)g(lo)n(wer)f(right)h(corner)-5 b(.)0 668 y(Mo)o(v)o(e)21 b(the)h(cursor)g(to)g(a)h(dif)n(ferent)f (place)g(on)g(the)g(screen)h(and)g(release)f(the)h(left)f(b)n(utton.)28 b(The)23 b(box)f(should)f(mo)o(v)o(e)0 789 y(so)h(that)h(its)f(lo)n (wer)g(right)g(corner)h(is)f(at)h(the)g(cursor)g(position.)28 b(T)m(ry)22 b(using)g(this)f(feature)j(to)e(mo)o(v)o(e)f(the)i(box)f (so)h(that)0 909 y(it)h(is)h(almost)e(entirely)i(of)n(f-screen)g(to)f (the)h(left.)30 b(T)m(ry)25 b(mo)o(ving)e(the)h(box)h(by)f(each)h(of)g (its)f(corners.)146 1030 y(Y)-11 b(ou)27 b(can)h(also)f(reshape)g(the)g (box)g(by)g(corners)g(other)g(than)g(the)g(upper)g(right.)37 b(T)-8 b(o)27 b(do)g(this,)g(press)g(the)g(right)0 1150 y(mouse)e(b)n(utton)f(and)h(hold)g(it)g(do)n(wn.)32 b(The)25 b(cursor)h(shape)f(sho)n(ws)f(you)h(that)g(you)g(are)h(reshaping)f(the) h(box)f(by)g(its)0 1270 y(upper)g(right)f(corner:)p 1870 1406 V 2028 1526 4 121 v 146 1708 a(No)n(w)h(mo)o(v)o(e)g(the)g(cursor) h(near)g(some)g(other)f(corner)i(of)e(the)h(box)f(and)h(click)g(the)f (left)h(b)n(utton,)f(all)g(the)h(while)0 1829 y(holding)c(the)h(right)f (b)n(utton)g(do)n(wn.)30 b(The)23 b(cursor)g(shape)g(will)g(change)g (to)g(sho)n(w)f(you)h(that)g(no)n(w)f(you)h(are)h(reshap-)0 1949 y(ing)k(the)g(box)f(by)h(a)h(dif)n(ferent)f(corner)-5 b(.)41 b(When)28 b(you)g(release)h(the)f(right)f(b)n(utton,)h(the)g (box)g(will)f(reshape)i(so)f(that)0 2069 y(the)h(selected)g(corner)g (is)g(at)g(the)f(cursor)h(position)e(b)n(ut)i(the)g(diagonally)e (opposite)h(corner)h(is)g(unchanged.)43 b(T)m(ry)0 2190 y(reshaping)24 b(the)h(box)f(by)h(each)g(of)g(its)f(corners.)0 2528 y Fh(7)143 b(In)-6 b(v)o(oking)34 b(Commands)0 2752 y Ff(Commands)28 b(can)h(be)g(in)l(v)n(ok)o(ed)f(in)g(Magic)g(in)h (three)g(w)o(ays:)38 b(by)28 b(pressing)g(b)n(uttons)f(on)i(the)f (mouse;)i(by)e(typing)0 2872 y(single)i(k)o(e)o(ystrok)o(es)f(on)h(the) g(te)o(xt)g(k)o(e)o(yboard)g(\(these)g(are)h(called)g Fg(macr)l(os)p Ff(\);)h(or)f(by)f(typing)f(longer)h(commands)0 2992 y(on)f(the)h(te)o(xt)e(k)o(e)o(yboard)h(\(these)g(are)i(called)e Fg(long)g(commands)p Ff(\).)44 b(Man)o(y)28 b(of)i(the)f(commands)f (use)i(the)f(box)g(and)0 3113 y(cursor)c(to)f(help)h(guide)f(the)h (command.)146 3233 y(T)-8 b(o)35 b(see)g(ho)n(w)g(commands)e(can)j(be)f (in)l(v)n(ok)o(ed)f(from)g(the)h(b)n(uttons,)h(\002rst)f(position)e (the)i(box)g(o)o(v)o(er)f(a)h(small)0 3354 y(blank)27 b(area)h(in)e(the)h(middle)f(of)i(the)e(screen.)39 b(Then)27 b(mo)o(v)o(e)e(the)i(cursor)g(o)o(v)o(er)g(the)f(red)i(rectangle)f(and) g(press)g(the)0 3474 y(middle)32 b(mouse)g(b)n(utton.)53 b(At)33 b(this)f(point,)i(the)e(area)i(of)f(the)g(box)f(should)g(get)g (painted)h(red.)55 b(No)n(w)32 b(mo)o(v)o(e)f(the)0 3594 y(cursor)e(o)o(v)o(er)g(empty)f(space)i(and)f(press)g(the)g(middle)g(b) n(utton)f(again.)43 b(The)29 b(red)h(paint)f(should)f(go)h(a)o(w)o(ay) -6 b(.)43 b(Note)0 3715 y(ho)n(w)24 b(this)g(command)g(uses)g(both)g (the)h(cursor)g(and)f(box)h(locations)e(to)i(control)f(what)h(happens.) 146 3835 y(As)f(an)g(e)o(xample)f(of)h(a)g(macro,)g(type)g(the)f Fe(g)h Ff(k)o(e)o(y)f(on)h(the)g(te)o(xt)f(k)o(e)o(yboard.)29 b(A)24 b(grid)g(will)f(appear)h(on)g(the)f(color)0 3955 y(display)-6 b(,)27 b(along)g(with)g(a)i(small)d(black)i(box)g(marking) f(the)g(origin)g(of)h(the)g(cell.)40 b(If)28 b(you)g(type)f Fe(g)h Ff(again,)g(the)g(grid)0 4076 y(will)h(go)h(a)o(w)o(ay)-6 b(.)46 b(Y)-11 b(ou)30 b(may)f(ha)n(v)o(e)h(noticed)g(earlier)g(that)g (the)g(box)f(corners)i(didn')n(t)e(mo)o(v)o(e)g(to)g(the)h(e)o(xact)g (cursor)0 4196 y(position:)f(you)24 b(can)h(see)g(no)n(w)f(that)h(the)f (box)h(is)f(forced)h(to)g(f)o(all)f(on)h(grid)f(points.)146 4317 y(Long)30 b(commands)f(are)j(in)l(v)n(ok)o(ed)d(by)h(typing)g(a)g (colon)g(\(\223:\224\))43 b(or)31 b(semi-colon)e(\(\223;\224\).)48 b(After)31 b(you)f(type)g(the)0 4437 y(colon)i(or)h(semi-colon,)g(the)g (\223)p Fa(>)p Ff(\224)g(prompt)e(on)i(the)f(te)o(xt)g(screen)h(will)f (be)h(replaced)g(by)f(a)h(\223:\224)47 b(prompt.)53 b(This)0 4557 y(indicates)28 b(that)h(Magic)f(is)h(w)o(aiting)f(for)h(a)g(long)g (command.)42 b(At)28 b(this)g(point)g(you)h(should)f(type)g(a)i(line)e (of)h(te)o(xt,)0 4678 y(follo)n(wed)d(by)h(a)g(return.)37 b(When)27 b(the)g(long)g(command)f(has)h(been)g(processed,)g(the)g (\223)p Fa(>)p Ff(\224)h(prompt)e(reappears)h(on)0 4798 y(the)h(te)o(xt)f(display)-6 b(.)39 b(T)m(ry)27 b(typing)g(semi-colon)g (follo)n(wed)g(by)h(return)g(to)g(see)g(ho)n(w)f(this)g(w)o(orks.)40 b(Occasionally)28 b(a)0 4918 y(\223]\224)f(\(right)f(brack)o(et\))i (prompt)d(will)h(appear)-5 b(.)36 b(This)26 b(means)g(that)h(the)f (design-rule)g(check)o(er)i(is)e(re)n(v)o(erifying)f(part)0 5039 y(of)g(your)f(design.)30 b(F)o(or)25 b(no)n(w)f(you)g(can)i(just)d (ignore)i(this)f(and)h(treat)g(\223]\224)g(lik)o(e)f(\223)p Fa(>)p Ff(\224.)146 5159 y(Each)30 b(long)e(command)g(consists)f(of)i (the)g(name)g(of)g(the)g(command)e(follo)n(wed)h(by)h(ar)n(guments,)g (if)g(an)o(y)f(are)0 5280 y(needed)23 b(by)f(that)f(command.)29 b(The)23 b(command)e(name)h(can)h(be)f(abbre)n(viated,)g(just)g(as)g (long)g(as)g(you)g(type)g(enough)0 5400 y(characters)30 b(to)f(distinguish)d(it)j(from)g(all)g(other)g(long)f(commands.)42 b(F)o(or)29 b(e)o(xample,)h Fe(:h)f Ff(and)g Fe(:he)h Ff(may)f(be)g(used)1875 5649 y(\2266\226)p eop %%Page: 7 7 7 6 bop 0 -180 a Ff(Magic)24 b(T)l(utorial)g(#1:)30 b(Getting)24 b(Started)1715 b(September)25 b(26,)g(2001)0 68 y(as)32 b(abbre)n(viations)d(for)j Fe(:help)p Ff(.)52 b(On)31 b(the)g(other)g(hand,)i Fe(:u)f Ff(may)f(not)g(be)h(used)f(as)g(an)h (abbre)n(viation)e(for)i Fe(:undo)0 188 y Ff(because)25 b(there)g(is)g(another)f(command,)g Fe(:upsidedo)o(wn)p Ff(,)i(that)f(has)f(the)h(same)g(abbre)n(viation.)k(T)m(ry)24 b(typing)g Fe(:u)p Ff(.)146 309 y(As)32 b(an)g(e)o(xample)e(of)i(a)g (long)f(command,)i(put)e(the)g(box)g(o)o(v)o(er)g(empty)g(space)h(on)g (the)f(color)h(display)-6 b(,)31 b(then)0 429 y(in)l(v)n(ok)o(e)24 b(the)h(long)f(command)900 657 y Fe(:paint)i(r)n(ed)146 886 y Ff(The)f(box)f(should)f(\002ll)i(with)f(the)g(red)h(color)l(,)g (just)e(as)i(if)f(you)h(had)f(used)g(the)h(middle)e(mouse)h(b)n(utton)g (to)g(paint)0 1006 y(it.)54 b(Ev)o(erything)32 b(you)g(can)h(do)g(in)f (Magic)h(can)g(be)g(in)l(v)n(ok)o(ed)f(with)g(a)h(long)g(command.)53 b(It)33 b(turns)g(out)f(that)g(the)0 1126 y(macros)c(are)h(just)f(con)l (v)o(eniences)f(that)h(are)h(e)o(xpanded)f(into)f(long)h(commands)f (and)h(e)o(x)o(ecuted.)41 b(F)o(or)28 b(e)o(xample,)0 1247 y(the)d(long)f(command)g(equi)n(v)n(alent)e(to)j(the)g Fe(g)f Ff(macro)h(is)900 1475 y Fe(:grid)146 1703 y Ff(Magic)c(permits) e(you)h(to)g(de\002ne)i(ne)n(w)e(macros)g(if)h(you)f(wish.)28 b(Once)21 b(you')-5 b(v)o(e)20 b(become)h(f)o(amiliar)f(with)f(Magic)0 1824 y(you')o(ll)i(almost)g(certainly)g(w)o(ant)h(to)g(add)g(your)f(o)n (wn)h(macros)f(so)h(that)f(you)h(can)g(in)l(v)n(ok)o(e)g(quickly)f(the) g(commands)0 1944 y(you)j(use)h(most)f(frequently)-6 b(.)30 b(See)25 b(the)g Fg(ma)o(gic\(1\))f Ff(man)h(page)g(under)g(the) f(command)g Fe(:macr)n(o)p Ff(.)146 2065 y(One)h(more)g(long)f(command) g(is)g(of)h(immediate)e(use)i(to)g(you.)30 b(It)25 b(is)900 2293 y Fe(:quit)146 2521 y Ff(In)l(v)n(ok)o(e)d(this)g(command.)29 b(Note)22 b(that)f(before)i(e)o(xiting,)e(Magic)h(will)g(gi)n(v)o(e)f (you)g(one)i(last)e(chance)i(to)f(sa)n(v)o(e)g(the)0 2642 y(information)h(that)i(you')-5 b(v)o(e)24 b(modi\002ed.)30 b(T)-8 b(ype)25 b Fe(y)f Ff(to)h(e)o(xit)e(without)h(sa)n(ving)g(an)o (ything.)1875 5649 y(\2267\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tut7.ps0000644000175000001440000031461610751423606015152 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software %%Title: tut7.dvi %%Pages: 13 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman Helvetica font %%EndComments %DVIPSWebPage: (www.radicaleye.com) %DVIPSCommandLine: dvips -t letter tut7.dvi -o ../psfiles/tut7.ps %DVIPSParameters: dpi=600, compressed %DVIPSSource: TeX output 2006.04.12:1203 %%BeginProcSet: texc.pro %! /TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin /FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array /BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get }B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr 1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx 0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B /chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ /cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 {2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ 1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put }if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X 1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N /p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ /Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) (LaserWriter 16/600)]{A length product length le{A length product exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end %%EndProcSet %%BeginProcSet: 8r.enc % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndProcSet %%BeginProcSet: texps.pro %! TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type/integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics/Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{ dup sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[exch{dup CharStrings exch known not{pop/.notdef/Encoding true def} if}forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def} def end %%EndProcSet %%BeginProcSet: special.pro %! TeXDict begin/SDict 200 dict N SDict begin/@SpecialDefaults{/hs 612 N /vs 792 N/ho 0 N/vo 0 N/hsc 1 N/vsc 1 N/ang 0 N/CLIP 0 N/rwiSeen false N /rhiSeen false N/letter{}N/note{}N/a4{}N/legal{}N}B/@scaleunit 100 N /@hscale{@scaleunit div/hsc X}B/@vscale{@scaleunit div/vsc X}B/@hsize{ /hs X/CLIP 1 N}B/@vsize{/vs X/CLIP 1 N}B/@clip{/CLIP 2 N}B/@hoffset{/ho X}B/@voffset{/vo X}B/@angle{/ang X}B/@rwi{10 div/rwi X/rwiSeen true N}B /@rhi{10 div/rhi X/rhiSeen true N}B/@llx{/llx X}B/@lly{/lly X}B/@urx{ /urx X}B/@ury{/ury X}B/magscale true def end/@MacSetUp{userdict/md known {userdict/md get type/dicttype eq{userdict begin md length 10 add md maxlength ge{/md md dup length 20 add dict copy def}if end md begin /letter{}N/note{}N/legal{}N/od{txpose 1 0 mtx defaultmatrix dtransform S atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{ itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll curveto}}{{closepath}}pathforall newpath counttomark array astore/gc xdf pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack} if}N/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 -1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{ noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop 90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr 2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 -1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S TR}if}N/cp{pop pop showpage pm restore}N end}if}if}N/normalscale{ Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale }if 0 setgray}N/psfts{S 65781.76 div N}N/startTexFig{/psf$SavedState save N userdict maxlength dict begin/magscale true def normalscale currentpoint TR/psf$ury psfts/psf$urx psfts/psf$lly psfts/psf$llx psfts /psf$y psfts/psf$x psfts currentpoint/psf$cy X/psf$cx X/psf$sx psf$x psf$urx psf$llx sub div N/psf$sy psf$y psf$ury psf$lly sub div N psf$sx psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub TR/showpage{}N/erasepage{}N/copypage{}N/p 3 def @MacSetUp}N/doclip{ psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath moveto}N/endTexFig{end psf$SavedState restore}N/@beginspecial{SDict begin/SpecialSave save N gsave normalscale currentpoint TR @SpecialDefaults count/ocount X/dcount countdictstack N}N/@setspecial{ CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR }{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury lineto closepath clip}if/showpage{}N/erasepage{}N/copypage{}N newpath}N /@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{end} repeat grestore SpecialSave restore end}N/@defspecial{SDict begin}N /@fedspecial{end}B/li{lineto}B/rl{rlineto}B/rc{rcurveto}B/np{/SaveX currentpoint/SaveY X N 1 setlinecap newpath}N/st{stroke SaveX SaveY moveto}N/fil{fill SaveX SaveY moveto}N/ellipse{/endangle X/startangle X /yrad X/xrad X/savematrix matrix currentmatrix N TR xrad yrad scale 0 0 1 startangle endangle arc savematrix setmatrix}N end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tut7.dvi) @start %DVIPSBitmapFont: Fa cmr8 8 1 /Fa 1 51 df50 D E %EndDVIPSBitmapFont %DVIPSBitmapFont: Fb cmmi12 12 1 /Fb 1 79 df<91B500C0020FB5128082A2DA007F9239007FE00070ED1F8074C7FCDBEFF8 150E15CF03C7160C70151C1401DB83FE1518A2DB81FF1538140303001630831A704A6D7E 02061760163F7114E0140E020C6D6C5CA2706C1301141C021801075D83190302386D7E02 3094C8FC1601715B147002606DEB8006A294387FC00E14E04A023F130C18E0191C0101ED 1FF04A1618170FF0F838130391C83807FC30A2943803FE705B01060301136018FF19E001 0E81010C5F187FA2131C0118705A1338181F137801FC70C9FCEA03FFB512F88418065144 7CC34E>78 D E %EndDVIPSBitmapFont /Fc 134[50 50 72 50 55 33 39 44 1[55 50 55 83 28 55 33 28 55 50 33 44 55 44 55 50 3[33 1[33 4[72 1[66 55 2[61 1[72 7[61 2[72 8[33 1[50 50 2[50 50 50 50 50 28 43[55 55 2[{TeXBase1Encoding ReEncodeFont}44 99.6264 /Times-Bold rf /Fd 134[60 3[66 40 47 53 2[60 66 100 33 2[33 66 2[53 66 53 66 60 12[80 66 3[93 86 113 80 8[86 8[40 1[60 4[60 60 60 2[30 43[66 2[{TeXBase1Encoding ReEncodeFont}30 119.552 /Times-Bold rf /Fe 105[50 1[44 44 10[33 13[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 3[33 1[33 1[72 1[94 72 72 61 55 66 1[55 72 72 89 61 2[33 72 72 55 61 72 66 66 72 92 44 3[28 28 50 50 50 50 50 50 50 50 50 50 28 25 33 25 1[50 33 33 33 2[50 50 1[33 29[55 55 2[{TeXBase1Encoding ReEncodeFont}80 99.6264 /Times-Roman rf /Ff 134[44 2[44 50 28 39 39 1[50 50 50 72 28 2[28 50 50 28 44 50 44 50 50 11[72 5[72 4[44 33 1[72 17[50 3[50 2[25 33 25 2[33 33 37[50 2[{ TeXBase1Encoding ReEncodeFont}33 99.6264 /Times-Italic rf /Fg 136[104 1[80 48 56 64 2[72 80 120 40 80 1[40 80 72 48 64 80 64 80 72 9[143 2[96 1[104 3[104 135 96 2[56 112 1[88 96 1[104 8[48 72 72 72 72 72 72 72 72 72 13[72 35[{TeXBase1Encoding ReEncodeFont}41 143.462 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%BeginPaperSize: Letter letter %%EndPaperSize %%EndSetup %%Page: 1 1 1 0 bop 731 101 a Fg(Magic)35 b(T)-13 b(utorial)34 b(#7:)44 b(Netlists)34 b(and)h(Routing)1618 521 y Ff(J)n(ohn)24 b(Ousterhout)1401 941 y Fe(Computer)g(Science)i(Di)n(vision)1020 1062 y(Electrical)f(Engineering)f(and)h(Computer)f(Sciences)1473 1182 y(Uni)n(v)o(ersity)f(of)i(California)1544 1303 y(Berk)o(ele)o(y)-6 b(,)24 b(CA)h(94720)1448 1573 y Ff(\(Updated)f(by)h(other)o(s,)f (too.\))1053 1843 y Fe(This)g(tutorial)g(corresponds)g(to)g(Magic)h(v)o (ersion)e(7.)0 2415 y Fd(T)-11 b(utorials)30 b(to)f(r)n(ead)h(\002rst:) 300 2662 y Fe(Magic)24 b(T)l(utorial)g(#1:)30 b(Getting)24 b(Started)300 2782 y(Magic)g(T)l(utorial)g(#2:)30 b(Basic)25 b(P)o(ainting)f(and)h(Selection)300 2903 y(Magic)f(T)l(utorial)g(#3:)30 b(Adv)n(anced)24 b(P)o(ainting)g(\(W)l(iring)g(and)h(Plo)n(wing\))300 3023 y(Magic)f(T)l(utorial)g(#4:)30 b(Cell)25 b(Hierarchies)300 3143 y(Magic)f(T)l(utorial)g(#5:)30 b(Multiple)23 b(W)l(indo)n(ws)0 3503 y Fd(Netlist)30 b(Commands)f(intr)n(oduced)j(in)f(this)e (tutorial:)300 3750 y Fe(:e)o(xtract,)24 b(:\003ush,)g(:ripup,)g(:sa)n (v)o(enetlist,)f(:trace,)i(:writeall)0 3990 y Fd(Lay)m(out)k(Commands)h (intr)n(oduced)h(in)g(this)f(tutorial:)300 4237 y Fe(:channel,)24 b(:route)0 4476 y Fd(Macr)n(os)29 b(intr)n(oduced)i(in)g(this)f (tutorial:)300 4763 y Ff(\(none\))1875 5649 y Fe(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Fe(April)24 b(12,)h(2006)1717 b(Magic)24 b(T)l(utorial)g(#7:)30 b(Netlists)23 b(and)i(Routing)0 99 y Fg(1)143 b(Intr)m(oduction)0 331 y Fe(This)31 b(tutorial)f (describes)i(ho)n(w)e(to)h(use)h(Magic')-5 b(s)31 b(automatic)f (routing)h(tools)f(to)h(mak)o(e)h(interconnections)e(be-)0 451 y(tween)23 b(subcells)g(in)f(a)i(design.)29 b(In)24 b(addition)e(to)h(the)g(standard)g(Magic)f(router)l(,)i(which)f(is)g (in)l(v)n(ok)o(ed)f(by)h(the)g Fc(r)n(oute)0 572 y Fe(command)31 b(and)g(co)o(v)o(ered)h(in)f(this)g(tutorial,)h(tw)o(o)f(other)h (routing)e(tools)h(are)i(a)n(v)n(ailable.)50 b(A)32 b(gate-array)g (router)0 692 y Ff(Gar)l(outer)f Fe(permits)g(user)h(speci\002ed)h (channel)f(de\002nitions,)g(terminals)g(in)f(the)h(interior)g(of)g (cells,)i(and)e(route-)0 813 y(throughs)23 b(across)i(cells.)30 b(T)-8 b(o)24 b(learn)h(about)f(the)g(gate-array)h(router)f(read)h (this)f(\002rst)g(then)h(\223Magic)f(T)l(utorial)f(#12:)0 933 y(Routing)h(Gate)i(Arrays\224.)32 b(Finally)24 b(Magic)h(pro)o (vides)f(an)h(interacti)n(v)o(e)f(maze-router)i(that)e(tak)o(es)h (graphic)g(hints,)0 1053 y(the)35 b Ff(Ir)l(outer)p Fe(,)h(that)f (permits)f(the)h(user)g(to)f(control)h(the)f(o)o(v)o(erall)g(path)h(of) g(routes)f(while)h(lea)n(ving)f(the)h(tedious)0 1174 y(details)24 b(to)g(Magic.)31 b(The)25 b Ff(Ir)l(outer)e Fe(is)i(documented)e(in)i(\223Magic)g(T)l(utorial)e(#10:)30 b(The)25 b(Interacti)n(v)o(e)f(Router\224.)146 1298 y(The)f(standard)e (Magic)h(router)g(pro)o(vides)f(an)i Ff(obstacle-avoidance)d Fe(capability:)29 b(if)22 b(there)g(is)g(mask)g(material)0 1419 y(in)39 b(the)g(routing)f(areas,)43 b(the)c(router)g(can)h(w)o (ork)f(under)l(,)k(o)o(v)o(er)l(,)e(or)f(around)f(that)f(material)h(to) g(complete)f(the)0 1539 y(connections.)29 b(This)24 b(means)g(that)f (you)h(can)h(pre-route)f(k)o(e)o(y)g(signals)f(by)h(hand)g(and)g(ha)n (v)o(e)g(Magic)g(route)g(the)g(less)0 1659 y(important)i(signals)g (automatically)-6 b(.)35 b(In)27 b(addition,)g(you)f(can)i(route)f(po)n (wer)f(and)h(ground)g(by)g(hand)f(\(right)h(no)n(w)0 1780 y(we)e(don')n(t)f(ha)n(v)o(e)h(an)o(y)f(po)n(wer)n(-ground)g (routing)g(tools,)f(so)i(you)f Ff(have)h Fe(to)g(route)f(them)g(by)h (hand\).)146 1904 y(The)30 b(router)g Ff(only)f Fe(mak)o(es)g (connections)g(between)h(subcells;)h(to)e(mak)o(e)h(point-to-point)d (connections)i(be-)0 2025 y(tween)20 b(pieces)g(of)g(layout)f(within)f (a)j(single)e(cell)g(you)h(should)f(use)g(the)h(wiring)f(command)g (described)h(in)f(\223Magic)0 2145 y(T)l(utorial)g(#3:)28 b(Adv)n(anced)19 b(P)o(ainting)g(\(W)l(iring)h(and)g(Plo)n(wing\))f (\224)h(or)g(the)g(maze)h(router)f(described)g(in)g(\223Magic)g(T)l(u-) 0 2265 y(torial)25 b(#10:)32 b(The)26 b(Interacti)n(v)o(e)f (Router\224.)34 b(If)27 b(you)e(only)g(need)h(to)f(mak)o(e)h(a)g(fe)n (w)g(connections)f(you)g(are)i(probably)0 2386 y(better)e(of)n(f)f (doing)g(them)g(manually)-6 b(.)146 2510 y(The)30 b(\002rst)g(step)f (in)g(routing)g(is)g(to)g(tell)g(Magic)g(what)h(should)e(be)i (connected)g(to)f(what.)45 b(This)29 b(information)0 2631 y(is)j(contained)g(in)g(a)g(\002le)h(called)f(a)h Ff(netlist)p Fe(.)52 b(Sections)32 b(2,)i(3,)g(4,)g(and)f(5)f(describe) g(ho)n(w)g(to)g(create)h(and)f(modify)0 2751 y(netlists)26 b(using)g(Magic')-5 b(s)26 b(interacti)n(v)o(e)g(netlist)f(editing)h (tools.)37 b(Once)27 b(you')-5 b(v)o(e)27 b(created)h(a)f(netlist,)f (the)h(ne)o(xt)g(step)0 2871 y(is)d(to)f(in)l(v)n(ok)o(e)h(the)g (router)-5 b(.)30 b(Section)24 b(6)g(sho)n(ws)e(ho)n(w)i(to)f(do)h (this,)f(and)h(gi)n(v)o(es)f(a)h(brief)h(summary)e(of)h(what)g(goes)f (on)0 2992 y(inside)k(the)i(routing)e(tools.)40 b(Unless)28 b(your)g(design)g(is)f(v)o(ery)h(simple)g(and)g(has)g(lots)g(of)g(free) h(space,)h(the)e(routing)0 3112 y(probably)j(w)o(on')n(t)g(succeed)h (the)f(\002rst)g(time.)50 b(Section)31 b(7)g(describes)h(the)f (feedback)h(pro)o(vided)e(by)h(the)g(routing)0 3233 y(tools.)d (Sections)20 b(8)g(and)g(9)g(discuss)f(ho)n(w)g(you)g(can)i(modify)e (your)h(design)f(in)g(light)g(of)h(this)g(feedback)g(to)g(impro)o(v)o (e)0 3353 y(its)k(routability)-6 b(.)29 b(Y)-11 b(ou')o(ll)24 b(probably)g(need)h(to)f(iterate)h(a)g(fe)n(w)g(times)f(until)f(the)i (routing)f(is)g(successful.)0 3719 y Fg(2)143 b(T)-13 b(erminals)34 b(and)h(Netlists)0 3951 y Fe(A)24 b(netlist)f(is)g(a)h (\002le)g(that)g(describes)g(a)g(set)g(of)g(desired)f(connections.)30 b(It)24 b(contains)f(one)g(or)h(more)g Ff(nets)p Fe(.)30 b(Each)24 b(net)0 4072 y(names)30 b(a)h(set)f(of)h Ff(terminals)e Fe(that)h(should)f(all)i(be)f(wired)h(together)-5 b(.)47 b(A)30 b(terminal)g(is)g(simply)f(a)i(label)f(attached)0 4192 y(to)k(a)g(piece)h(of)f(mask)f(material)h(within)f(a)h(subcell;)k (it)c(is)f(distinguishable)f(from)i(ordinary)f(labels)h(within)f(a)0 4312 y(subcell)27 b(by)g(its)g(presence)h(within)f(a)h(netlist)e (\002le)i(and)g(by)f(certain)h(characteristics)f(common)g(to)g (terminals,)g(as)0 4433 y(described)e(belo)n(w)-6 b(.)146 4557 y(The)37 b(\002rst)g(step)f(in)h(b)n(uilding)e(a)i(netlist)e(is)h (to)h(label)f(the)h(terminals)e(in)i(your)f(design.)66 b(Figure)37 b(1)f(sho)n(ws)0 4678 y(an)f(e)o(xample.)61 b(Each)35 b(label)g(should)e(be)i(a)h(line)e(or)h(rectangle)h(running)e (along)g(the)h(edge)g(of)g(the)g(cell)g(\(point)0 4798 y(terminals)i(are)i(not)e(allo)n(wed\).)70 b(The)38 b(router)g(will)f (mak)o(e)h(a)h(connection)e(to)h(the)g(cell)g(some)n(where)f(along)h(a) 0 4918 y(terminal')-5 b(s)29 b(length.)46 b(If)30 b(the)g(label)g(isn') n(t)g(at)g(the)g(edge)g(of)g(the)g(cell,)h(Magic)f(will)f(route)h (recklessly)g(across)g(the)0 5039 y(cell)25 b(to)g(reach)g(the)g (terminal,)f(taking)h(the)f(shortest)g(path)h(between)g(the)g(terminal) f(and)h(a)h(routing)d(channel.)32 b(It')-5 b(s)0 5159 y(almost)27 b(al)o(w)o(ays)h(a)g(good)f(idea)h(to)g(arrange)h(for)f (terminal)f(labels)g(to)h(be)g(at)g(cell)g(edges.)40 b(The)28 b(label)g(must)f(be)h(at)0 5280 y(least)21 b(as)h(wide)g(as)g (the)f(minimum)f(width)h(of)g(the)h(routing)f(material;)h(the)f(wider)h (you)f(mak)o(e)h(the)g(label,)g(the)f(more)0 5400 y(\003e)o(xibility)i (you)h(gi)n(v)o(e)g(the)g(router)h(to)g(choose)f(a)h(good)g(point)e(to) i(connect)f(to)h(the)f(terminal.)1875 5649 y(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Fe(Magic)24 b(T)l(utorial)g(#7:)30 b(Netlists)23 b(and)i(Routing)1717 b(April)24 b(12,)h(2006)975 804 y @beginspecial 68 @llx 68 @lly 364 @urx 190 @ury 2340 @rwi @setspecial %%BeginDocument: ../psfigures/tut7.1.ps %!PS-Adobe-3.0 EPSF-3.0 %%Title: ../psfiles/tut7.1.ps %%Creator: Xcircuit v2.0 %%CreationDate: Fri Apr 14 13:29:20 2000 %%Pages: 1 %%BoundingBox: 68 68 364 190 %%DocumentNeededResources: font Helvetica font Times-Roman %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrow { % -12 -40 24 80 bbox begingate 1 0.80 0 -40 0 20 2 polygon 1.00 0 0 40 arrowhead endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 480 256 offsets 1.0000 inchscale 2.6000 setlinewidth 0.800 0.800 0.800 scb 240 1.00 192 192 192 496 960 496 960 192 4 polygon sce 0.490 0.651 0.980 scb 240 1.00 672 224 672 320 800 320 800 224 4 polygon 240 1.00 384 192 384 384 512 384 512 192 4 polygon sce 1 1.00 256 192 256 384 800 384 800 192 4 polygon 1.000 1.000 0.000 scb (Input) {/Helvetica 1.000 cf} 2 29 0 448 376 label sce (Cell Boundary) {/Times-Roman 1.000 cf} 2 27 0 848 444 label 1.000 1.000 0.000 scb (Output) {/Helvetica 1.000 cf} 2 20 0 808 272 label sce 1 1.00 672 224 800 224 2 polygon 1 1.00 672 320 800 320 2 polygon 1 1.00 512 384 512 192 2 polygon 1 1.00 384 384 384 192 2 polygon 1.000 1.000 0.000 scb 1 1.00 800 224 800 320 2 polygon 0 1.00 384 320 384 384 512 384 512 320 4 polygon sce 1.00 135 580 412 arrow pgsave restore showpage %%Trailer XCIRCsave restore %%EOF %%EndDocument @endspecial 0 1007 a(Figure)h(1:)33 b(An)26 b(e)o(xample)f(of)i (terminal)e(labels.)34 b(Each)26 b(terminal)f(should)g(be)h(labeled)g (with)g(a)g(line)g(or)g(rectangle)0 1127 y(along)e(the)h(edge)g(of)g (the)f(cell.)146 1499 y(T)-7 b(erminal)35 b(labels)h(must)e(be)i (attached)g(to)f(mask)g(material)g(that)h(connects)f(directly)g(to)h (one)f(of)h(Magic')-5 b(s)0 1620 y(tw)o(o)33 b(routing)f(layers)i (\(Routing)f(layers)g(are)h(de\002ned)g(in)f(Magic')-5 b(s)33 b(technology)f(\002le\).)57 b(F)o(or)34 b(e)o(xample,)g(in)f (the)0 1740 y(SCMOS)e(process)e(where)i(the)e(routing)g(layers)h(are)g (metal1)f(and)h(metal2,)h(dif)n(fusion)d(may)h(not)g(be)h(used)g(as)g (a)0 1860 y(terminal)21 b(since)h(neither)g(of)g(the)g(routing)f (layers)h(will)g(connect)g(directly)f(to)h(it.)29 b(On)22 b(the)g(other)g(hand,)g(a)h(terminal)0 1981 y(may)k(be)h(attached)g(to) g(dif)n(fusion-metal1)d(contact,)k(since)e(the)h(metal1)f(routing)g (layer)h(will)f(connect)g(properly)0 2101 y(to)h(it.)40 b(T)-7 b(erminals)27 b(can)i(ha)n(v)o(e)f(arbitrary)g(names,)h(e)o (xcept)e(that)h(the)o(y)g(should)f(not)g(contain)h(slashes)f (\(\223/\224\))i(or)f(the)0 2222 y(substring)g(\223feedthrough\224,)j (and)f(should)f(not)g(end)h(in)f(\223@\224,)i(\223$\224,)h(or)d (\223\210\224.)47 b(See)31 b(T)l(utorial)d(#2)i(for)g(a)g(complete)0 2342 y(description)24 b(of)h(labeling)e(con)l(v)o(entions.)146 2467 y(F)o(or)37 b(an)f(e)o(xample)f(of)h(good)g(and)g(bad)g (terminals,)i(edit)e(the)g(cell)g Fc(tut7a)p Fe(.)65 b(The)37 b(cell)f(doesn')n(t)g(mak)o(e)g(an)o(y)0 2587 y(electrical)c(sense,)i(b)n(ut)e(contains)g(se)n(v)o(eral)f(good)h(and) g(bad)g(terminals.)52 b(All)32 b(the)g(terminals)f(with)h(names)g(lik)o (e)0 2707 y Fc(bad1)f Fe(are)h(incorrect)f(or)g(undesirable)f(for)h (one)g(of)g(the)g(reasons)f(gi)n(v)o(en)g(abo)o(v)o(e,)h(and)g(those)f (with)g(names)h(lik)o(e)0 2828 y Fc(good4)25 b Fe(are)g(acceptable.)585 4835 y @beginspecial 68 @llx 68 @lly 535 @urx 385 @ury 3276 @rwi @setspecial %%BeginDocument: ../psfigures/tut7.2.ps %!PS-Adobe-3.0 EPSF-3.0 %%Title: tut7.2.ps %%Creator: Xcircuit v2.0 %%CreationDate: Fri Apr 14 13:50:28 2000 %%Pages: 1 %%BoundingBox: 68 68 535 385 %%DocumentNeededResources: font Helvetica font Times-Italic %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrowhead90 { % -20 -12 36 24 bbox begingate 1.00 90 -16 0 arrowhead endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 1117 536 offsets % 32.00 8.00 gridspace 1.0000 inchscale 2.6000 setlinewidth 0.545 0.137 0.137 scb 240 1.00 317 192 317 1016 1149 1016 1149 192 4 polygon sce 0.804 0.000 0.804 scb 240 1.00 333 208 333 968 1133 968 1133 208 4 polygon sce 1.000 0.647 0.000 scb 240 1.00 749 640 749 704 973 704 973 640 4 polygon sce 0.898 0.898 0.898 scb 240 1.00 493 648 493 792 637 792 637 648 4 polygon sce 0.824 0.706 0.549 scb 240 1.00 493 808 493 872 973 872 973 808 4 polygon 240 1.00 749 728 749 792 845 792 845 728 4 polygon 240 1.00 877 728 877 792 973 792 973 728 4 polygon sce 0.753 1.000 0.753 scb 240 1.00 493 480 493 544 973 544 973 480 4 polygon sce 0.490 0.651 0.980 scb 240 1.00 749 400 749 464 973 464 973 400 4 polygon sce 1.000 0.502 0.502 scb 240 1.00 749 320 749 384 973 384 973 320 4 polygon sce 1.000 1.000 0.753 scb 240 1.00 749 240 749 304 973 304 973 240 4 polygon sce 0.800 0.800 0.800 scb 240 1.00 493 240 493 304 717 304 717 240 4 polygon sce 1.000 0.753 0.753 scb 240 1.00 493 320 493 384 717 384 717 320 4 polygon sce 0.753 1.000 1.000 scb 240 1.00 493 400 493 464 717 464 717 400 4 polygon sce 1.000 1.000 1.000 scb (NETLIST MENU) {/Helvetica 0.800 cf} 2 25 0 733 984 label (Label) {/Helvetica 1.000 cf} 2 25 0 733 904 label sce (BusBit13) {/Helvetica 1.000 cf} 2 21 0 733 840 label 0 1.00 317 192 317 1016 1149 1016 1149 192 4 polygon 0 1.00 333 208 333 968 1133 968 1133 208 4 polygon 0 1.00 493 808 493 872 973 872 973 808 4 polygon 0 1.00 877 728 877 792 973 792 973 728 4 polygon 0 1.00 749 728 749 792 845 792 845 728 4 polygon 0 1.00 749 640 749 704 973 704 973 640 4 polygon 0 1.00 493 480 493 544 973 544 973 480 4 polygon 1.000 1.000 1.000 scb (Netlist) {/Helvetica 1.000 cf} 2 25 0 733 584 label sce (Find) {/Helvetica 1.000 cf} 2 21 0 853 672 label (13) {/Helvetica 1.000 cf} 2 21 0 797 760 label 0 1.00 493 648 493 792 637 792 637 648 4 polygon 1 1.00 541 648 541 792 2 polygon 1 1.00 589 792 589 648 2 polygon 1 1.00 493 744 637 744 2 polygon 1 1.00 493 696 637 696 2 polygon 1 1.00 557 720 573 720 2 polygon 1 1.00 565 728 565 712 2 polygon (Placer) {/Times-Italic 1.000 cf} 2 23 0 293 728 label (Current Netlist) {/Times-Italic 1.000 cf} 2 20 0 1165 512 label (Pumps) {/Times-Italic 1.000 cf} 2 20 0 1165 760 label (Current Text) {/Times-Italic 1.000 cf} 2 20 0 1165 840 label 0 1.00 493 400 493 464 717 464 717 400 4 polygon 0 1.00 749 400 749 464 973 464 973 400 4 polygon 0 1.00 493 320 493 384 717 384 717 320 4 polygon 0 1.00 749 320 749 384 973 384 973 320 4 polygon 0 1.00 493 240 493 304 717 304 717 240 4 polygon 0 1.00 749 240 749 304 973 304 973 240 4 polygon (Print) {/Helvetica 1.000 cf} 2 21 0 861 432 label (Cleanup) {/Helvetica 1.000 cf} 2 21 0 861 352 label (Show) {/Helvetica 1.000 cf} 2 21 0 861 272 label (No Net) {/Helvetica 1.000 cf} 2 21 0 605 272 label (Terms) {/Helvetica 1.000 cf} 2 21 0 605 352 label (Verify) {/Helvetica 1.000 cf} 2 21 0 605 432 label 1.00 0 989 840 arrowhead90 1.00 0 989 760 arrowhead90 1.00 0 989 512 arrowhead90 1.00 -1 477 720 arrowhead90 1 1.00 989 840 1165 840 2 polygon 1 1.00 989 760 1165 760 2 polygon 1 1.00 989 512 1165 512 2 polygon 1 1.00 469 720 301 720 2 polygon pgsave restore showpage %%Trailer XCIRCsave restore %%EOF %%EndDocument @endspecial 1406 5039 a(Figure)g(2:)30 b(The)25 b(netlist)f(menu.)146 5400 y(If)40 b(you)f(create)i(tw)o(o)e(or)g(more)g(terminal)g(labels)g (with)g(the)g(same)g(name)h(in)f(the)g(same)g(cell)h(the)f(router)1875 5649 y(\2263\226)p eop %%Page: 4 4 4 3 bop 0 -180 a Fe(April)24 b(12,)h(2006)1717 b(Magic)24 b(T)l(utorial)g(#7:)30 b(Netlists)23 b(and)i(Routing)p 457 3 2986 4 v 455 124 4 121 v 507 88 a(Button)p 1150 124 V 423 w(Action)p 3441 124 V 457 127 2986 4 v 455 247 4 121 v 507 211 a(Current)g(T)-7 b(e)o(xt)p 1150 247 V 191 w(Left-click:)30 b(prompt)24 b(for)h(more)g(labels)p 3441 247 V 455 368 V 1150 368 V 1202 332 a(Right-click:)30 b(adv)n(ance)24 b(to)h(ne)o(xt)f(label)p 3441 368 V 457 371 2986 4 v 455 491 4 121 v 507 455 a(Placer)p 1150 491 V 447 w(Left-click:)30 b(place)25 b(label)p 3441 491 V 455 612 V 1150 612 V 1202 576 a(Right-click:)30 b(change)25 b(label)f(te)o(xt)g(position)p 3441 612 V 457 615 2986 4 v 455 736 4 121 v 507 699 a(Pumps)p 1150 736 V 423 w(Left-click:)30 b(decrement)25 b(number)p 3441 736 V 455 856 V 1150 856 V 1202 820 a(Right-click:)30 b(increment)24 b(number)p 3441 856 V 457 859 2986 4 v 455 980 4 121 v 507 944 a(Find)p 1150 980 V 512 w(Search)i(under)e (box,)h(highlight)d(labels)p 3441 980 V 455 1100 V 1150 1100 V 1202 1064 a(matching)h(current)i(te)o(xt)p 3441 1100 V 457 1103 2986 4 v 455 1224 4 121 v 507 1188 a(Current)g(Netlist) p 1150 1224 V 99 w(Left-click:)30 b(prompt)24 b(for)h(ne)n(w)f(netlist) g(name)p 3441 1224 V 455 1344 V 1150 1344 V 1202 1308 a(Right-click:)30 b(use)24 b(edit)h(cell)f(name)h(as)g(netlist)e(name)p 3441 1344 V 457 1347 2986 4 v 455 1468 4 121 v 507 1432 a(V)-11 b(erify)p 1150 1468 V 446 w(Check)25 b(that)g(wiring)f(matches) g(netlist)f(\(same)i(as)p 3441 1468 V 455 1588 V 1150 1588 V 1202 1552 a(typing)e Fc(:v)o(erify)i Fe(command\))p 3441 1588 V 457 1592 2986 4 v 455 1712 4 121 v 507 1676 a(Print)p 1150 1712 V 501 w(Print)f(names)h(of)g(all)f(terminals)g(in)g (selected)h(net)p 3441 1712 V 455 1832 V 1150 1832 V 1202 1796 a(\(same)g(as)f(typing)g Fc(:print)i Fe(command\))p 3441 1832 V 457 1836 2986 4 v 455 1956 4 121 v 507 1920 a(T)-7 b(erms)p 1150 1956 V 447 w(Place)25 b(feedback)h(areas)f(on)g (screen)g(to)g(identify)f(all)g(terminals)p 3441 1956 V 455 2076 V 1150 2076 V 1202 2040 a(in)g(current)h(netlist)f(\(same)g (as)h Fc(:sho)o(wterms)h Fe(command\))p 3441 2076 V 457 2080 2986 4 v 455 2200 4 121 v 507 2164 a(Cleanup)p 1150 2200 V 363 w(Check)f(current)g(netlist)f(for)h(missing)e(labels)h(and)h (nets)p 3441 2200 V 455 2320 V 1150 2320 V 1202 2284 a(with)f(less)g(than)h(tw)o(o)f(terminals)g(\(same)g(as)h(typing)p 3441 2320 V 457 2324 2986 4 v 455 2444 4 121 v 1150 2444 V 1202 2408 a Fc(:cleanup)h Fe(command\))p 3441 2444 V 455 2565 V 507 2528 a(No)f(Net)p 1150 2565 V 404 w(Delete)g(selected) f(net)h(\(same)g(as)g Fc(:dnet)h Fe(command\))p 3441 2565 V 457 2568 2986 4 v 455 2688 4 121 v 507 2652 a(Sho)n(w)p 1150 2688 V 470 w(Highlight)d(paint)h(connected)h(to)f(material)g (under)h(box)p 3441 2688 V 455 2809 V 1150 2809 V 1202 2773 a(\(same)g(as)f(typing)g Fc(:sho)o(wnet)i Fe(command\))p 3441 2809 V 457 2812 2986 4 v 788 2971 a(T)-8 b(able)25 b(1:)31 b(A)24 b(summary)g(of)h(all)g(the)f(netlist)g(menu)g(b)n(utton) f(actions.)0 3328 y(will)29 b(assume)g(that)g(the)o(y)f(are)j (electrically)e(equi)n(v)n(alent)f(\(connected)h(together)h(within)e (the)h(cell\).)45 b(Because)31 b(of)0 3448 y(this,)k(when)f(routing)f (the)g(net)h(it)g(will)f(feel)h(free)h(to)e(connect)h(to)g(whiche)n(v)o (er)e(one)i(of)g(the)g(terminals)f(is)g(most)0 3568 y(con)l(v)o (enient,)k(and)e(ignore)g(the)h(others.)62 b(In)36 b(some)f(cases)g (the)h(router)f(may)g(tak)o(e)h(adv)n(antage)f(of)g(electrically)0 3689 y(equi)n(v)n(alent)17 b(terminals)i(by)g(using)f Ff(feed)h(thr)l(oughs)p Fe(:)26 b(entering)19 b(a)g(cell)h(at)f(one)g (terminal)g(to)g(mak)o(e)g(one)g(connection,)0 3809 y(and)32 b(e)o(xiting)e(through)h(an)g(equi)n(v)n(alent)f(terminal)h(on)h(the)f (w)o(ay)h(to)f(mak)o(e)h(another)g(connection)f(for)h(the)f(same)0 3929 y(net.)0 4267 y Fg(3)143 b(Menu)36 b(f)l(or)f(Label)g(Editing)0 4491 y Fe(Magic)25 b(pro)o(vides)e(a)i(special)g(menu)f(f)o(acility)g (to)h(assist)f(you)g(in)h(placing)f(terminal)g(labels)g(and)h(editing)f (netlists.)0 4611 y(T)-8 b(o)25 b(mak)o(e)f(the)h(menu)f(appear)l(,)i (in)l(v)n(ok)o(e)e(the)g(Magic)h(command)900 4825 y Fc(:specialopen)h (netlist)146 5039 y Fe(A)c(ne)n(w)f(windo)n(w)g(will)g(appear)h(in)f (the)h(lo)n(wer)n(-left)f(corner)h(of)g(the)g(screen,)g(containing)f (se)n(v)o(eral)g(rectangular)0 5159 y(areas)32 b(on)g(a)g(purple)f (background.)51 b(Each)32 b(of)f(the)h(rectangular)g(areas)g(is)f (called)h(a)g Ff(b)n(utton)p Fe(.)50 b(Clicking)31 b(mouse)0 5280 y(b)n(uttons)23 b(inside)g(the)i(menu)f(b)n(uttons)e(will)i(in)l (v)n(ok)o(e)g(v)n(arious)f(commands)g(to)h(edit)g(labels)g(and)h (netlists.)k(Figure)24 b(2)0 5400 y(sho)n(ws)19 b(a)h(diagram)f(of)h (the)g(netlist)f(menu)g(and)h(T)-8 b(able)20 b(I)g(summarizes)f(the)h (meaning)f(of)h(b)n(utton)e(clicks)i(in)f(v)n(arious)1875 5649 y(\2264\226)p eop %%Page: 5 5 5 4 bop 0 -180 a Fe(Magic)24 b(T)l(utorial)g(#7:)30 b(Netlists)23 b(and)i(Routing)1717 b(April)24 b(12,)h(2006)0 68 y(menu)k(items.)42 b(The)30 b(netlist)e(menu)g(can)i(be)f(gro)n(wn,)g(shrunk,)h(and)f(mo)o (v)o(ed)e(just)i(lik)o(e)f(an)o(y)h(other)g(windo)n(w;)h(see)0 188 y(\223Magic)e(T)l(utorial)g(#5:)38 b(Multiple)26 b(W)l(indo)n(ws\224)i(for)h(details.)41 b(It)29 b(also)f(has)g(its)g(o) n(wn)g(pri)n(v)n(ate)f(set)i(of)f(commands.)0 309 y(T)-8 b(o)25 b(see)g(what)f(commands)g(you)g(can)h(type)g(in)f(the)h(netlist) e(menu,)i(mo)o(v)o(e)e(the)i(cursor)f(o)o(v)o(er)g(the)h(menu)f(and)h (type)900 561 y Fc(:help)146 810 y Fe(Y)-11 b(ou)28 b(shouldn')n(t)e (need)i(to)f(type)g(commands)f(in)h(the)h(netlist)e(menu)h(v)o(ery)g (often,)h(since)g(almost)e(e)n(v)o(erything)0 931 y(you')o(ll)33 b(need)i(to)f(do)g(can)h(be)f(done)g(using)f(the)i(menu.)58 b(See)36 b(Section)e(9)g(for)h(a)f(description)g(of)g(a)h(fe)n(w)f(of)g (the)0 1051 y(commands)29 b(you)g(can)i(type;)h(the)d(complete)h(set)g (is)f(described)h(in)g(the)f(manual)h(page)g Ff(ma)o(gic\(1\))p Fe(.)46 b(One)30 b(of)g(the)0 1172 y(best)24 b(uses)g(for)g(the)h (commands)e(is)h(so)g(that)f(you)h(can)h(de\002ne)g(macros)f(for)h (them)e(and)i(a)n(v)n(oid)e(ha)n(ving)h(to)g(go)g(back)0 1292 y(and)32 b(forth)f(to)h(the)g(menu;)i(look)d(up)h(the)f Fc(:send)i Fe(command)e(in)g(the)h(man)g(page)g(to)f(see)h(ho)n(w)f(to) h(do)f(this.)51 b(The)0 1412 y(top)29 b(half)h(of)g(the)g(menu)f(is)g (for)h(placing)g(labels)f(and)h(the)f(bottom)g(half)g(is)h(for)g (editing)f(netlists.)44 b(This)29 b(section)0 1533 y(describes)c(the)f (label)h(f)o(acilities,)f(and)h(Section)f(4)h(describes)g(the)f (netlist)g(f)o(acilities.)146 1656 y(The)j(label)f(menu)h(mak)o(es)f (it)g(easy)h(for)g(you)f(to)g(enter)h(lots)f(of)h(labels,)f (particularly)g(when)h(there)g(are)g(man)o(y)0 1777 y(labels)i(that)g (are)h(the)f(same)g(e)o(xcept)g(for)g(a)h(number)l(,)f(e.g.)45 b Fc(b)n(us1)p Fe(,)30 b Fc(b)n(us2)p Fe(,)h Fc(b)n(us3)p Fe(,)g(etc.)44 b(There)30 b(are)g(four)f(sections)0 1897 y(to)h(the)f(label)h(menu:)41 b(the)29 b(current)i(te)o(xt,)f(the)g (placer)l(,)i(tw)o(o)d(pumps,)h(and)g(the)g Fc(Find)g Fe(b)n(utton.)46 b(T)-8 b(o)29 b(place)i(labels,)0 2017 y(\002rst)f(click)g(the)g(left)g(mouse)f(b)n(utton)g(o)o(v)o(er)g(the)h (current)g(te)o(xt)f(rectangle.)46 b(Then)30 b(type)g(one)g(or)g(more)g (labels)f(on)0 2138 y(the)23 b(k)o(e)o(yboard,)f(one)h(per)g(line.)29 b(Y)-11 b(ou)23 b(can)g(use)f(this)g(mechanism)g(to)g(enter)h(se)n(v)o (eral)f(labels)h(at)f(once.)30 b(T)-8 b(ype)23 b(return)0 2258 y(twice)k(to)f(signal)g(the)g(end)h(of)g(the)f(list.)36 b(At)26 b(this)g(point,)g(the)h(\002rst)g(of)f(the)h(labels)f(you)h (typed)f(will)g(appear)h(in)f(the)0 2378 y(current)f(te)o(xt)f (rectangle.)146 2502 y(T)-8 b(o)33 b(place)h(a)g(label,)h(position)c (the)j(box)e(o)o(v)o(er)h(the)g(area)h(you)f(w)o(ant)g(to)g(label,)i (then)e(click)g(the)h(left)f(mouse)0 2622 y(b)n(utton)c(inside)h(one)g (of)h(the)f(squares)g(of)h(the)f(placer)h(area.)49 b(A)30 b(label)g(will)g(be)g(created)i(with)d(the)h(current)h(te)o(xt.)0 2743 y(Where)25 b(you)f(click)h(in)f(the)g(placer)h(determines)f(where) h(the)g(label)f(te)o(xt)g(will)f(appear)i(relati)n(v)o(e)f(to)g(the)h (label)f(box:)0 2863 y(for)f(e)o(xample,)g(clicking)f(the)h (left-center)g(square)g(causes)h(the)f(te)o(xt)f(to)g(be)h(centered)h (just)e(to)h(the)g(left)g(of)g(the)g(box.)0 2983 y(Y)-11 b(ou)22 b(can)h(place)f(man)o(y)g(copies)g(of)g(the)g(same)g(label)g (by)g(mo)o(ving)f(the)h(box)g(and)g(clicking)g(the)g(placer)h(area)g (again.)0 3104 y(Y)-11 b(ou)26 b(can)i(re-orient)e(the)h(te)o(xt)f(of)h (a)g(label)f(by)h(clicking)f(the)g(right)g(mouse)g(b)n(utton)g(inside)g (the)g(placer)i(area.)37 b(F)o(or)0 3224 y(e)o(xample,)25 b(if)g(you)h(w)o(ould)e(lik)o(e)i(to)f(mo)o(v)o(e)f(a)i(label')-5 b(s)25 b(te)o(xt)f(so)i(that)f(it)g(appears)h(centered)g(abo)o(v)o(e)f (the)g(label,)h(place)0 3344 y(the)f(box)f(o)o(v)o(er)g(the)h(label)f (and)h(right-click)f(the)h(top-center)f(placer)i(square.)146 3468 y(If)k(you)f(entered)h(se)n(v)o(eral)f(labels)g(at)h(once,)h(only) d(the)i(\002rst)g(appears)f(in)h(the)f(current)h(te)o(xt)e(area.)46 b(Ho)n(we)n(v)o(er)l(,)0 3588 y(you)23 b(can)g(adv)n(ance)g(to)g(the)f (ne)o(xt)h(label)f(by)h(right-clicking)f(inside)g(the)h(current)g(te)o (xt)f(area.)31 b(In)23 b(this)f(w)o(ay)h(you)g(can)0 3709 y(place)32 b(a)f(long)g(series)g(of)g(labels)g(entirely)g(with)f (the)i(mouse.)49 b(T)m(ry)31 b(using)f(this)g(mechanism)h(to)f(add)i (labels)e(to)0 3829 y Fc(tut7a)p Fe(.)146 3952 y(The)20 b(tw)o(o)g(small)f(b)n(uttons)f(underneath)i(the)f(right)h(side)f(of)h (the)g(current)g(te)o(xt)f(area)i(are)f(called)g(pumps.)28 b(T)-8 b(o)20 b(see)0 4073 y(ho)n(w)30 b(these)h(w)o(ork,)h(enter)g(a)f (label)g(name)g(containing)e(a)j(number)e(into)g(the)h(current)g(te)o (xt)f(area,)k(for)d(e)o(xample,)0 4193 y Fc(b)n(us1)p Fe(.)54 b(When)33 b(you)f(do)g(this,)i(the)e(\2231\224)h(appears)g(in)f (the)h(left)f(pump.)53 b(Right-clicking)32 b(the)g(pump)g(causes)g(the) 0 4314 y(number)d(to)f(increment,)i(and)f(left-clicking)g(the)g(pump)f (causes)h(the)g(number)g(to)g(decrement.)43 b(This)29 b(mak)o(es)g(it)0 4434 y(easy)34 b(for)h(you)f(to)g(enter)g(a)h(series) f(of)g(numbered)g(signal)g(names.)58 b(If)35 b(a)g(name)f(has)g(tw)o(o) g(numbers)f(in)h(it,)i(the)0 4554 y(second)22 b(number)f(will)g(appear) i(in)f(the)f(second)h(pump,)g(and)g(it)f(can)i(be)f(incremented)f(or)h (decremented)g(too.)30 b(T)m(ry)0 4675 y(using)24 b(the)g(pumps)g(to)g (place)i(a)f(series)f(of)h(numbered)g(names.)146 4798 y(The)h(last)g(entry)g(in)g(the)f(label)h(portion)f(of)h(the)g(menu)g (is)g(the)f Fc(Find)i Fe(b)n(utton.)33 b(This)26 b(can)g(be)g(used)g (to)g(locate)g(a)0 4918 y(label)e(by)g(searching)g(for)g(a)h(gi)n(v)o (en)d(pattern.)31 b(If)24 b(you)g(click)g(the)g Fc(Find)h Fe(b)n(utton,)d(Magic)i(will)g(use)g(the)g(current)g(te)o(xt)0 5039 y(as)30 b(a)h(pattern)f(and)g(search)h(the)f(area)i(underneath)e (the)g(box)g(for)g(a)h(label)f(whose)g(name)g(contains)f(the)h (pattern.)0 5159 y(P)o(attern-matching)24 b(is)g(done)h(in)f(the)h (same)f(w)o(ay)h(as)g(in)f Ff(csh)p Fe(,)h(using)f(the)h(special)f (characters)i(\223*\224,)f(\223?\224,)g(\223)0 5280 y(\224,)e (\223[\224,)h(and)e(\223]\224.)31 b(T)m(ry)22 b(this)g(on)g Fc(tut7a)p Fe(:)30 b(enter)23 b(\223good*\224)f(into)g(the)g(current)h (te)o(xt)f(area,)h(place)g(the)g(box)f(around)g(the)0 5400 y(whole)29 b(cell,)i(then)e(click)h(on)f(the)g(\223Find\224)h(b)n (utton.)44 b(F)o(or)30 b(each)g(of)g(the)f(good)g(labels,)h(a)g (feedback)h(area)f(will)f(be)1875 5649 y(\2265\226)p eop %%Page: 6 6 6 5 bop 0 -180 a Fe(April)24 b(12,)h(2006)1717 b(Magic)24 b(T)l(utorial)g(#7:)30 b(Netlists)23 b(and)i(Routing)0 69 y(created)h(with)f(white)h(stripes)f(to)g(highlight)f(the)h(area.)35 b(The)26 b Fc(:feedback)i(\002nd)f Fe(command)e(can)h(be)g(used)f(to)h (step)0 189 y(through)h(the)h(areas,)i(and)e Fc(:feedback)i(clear)f Fe(will)e(erase)i(the)f(feedback)g(information)f(from)h(the)g(screen.) 41 b(The)0 309 y Fc(:feedback)26 b Fe(command)d(has)g(man)o(y)g(of)h (the)g(same)f(options)f(as)i Fc(:dr)n(c)h Fe(for)f(getting)f (information)f(about)h(feedback)0 430 y(areas;)h(see)g(the)g(Magic)f (manual)g(page)h(for)f(details,)g(or)h(type)f Fc(:feedback)j(help)e Fe(for)g(a)g(synopsis)e(of)h(the)h(options.)0 782 y Fg(4)143 b(Netlist)34 b(Editing)0 1010 y Fe(After)j(placing)f(terminal)f (labels,)k(the)d(ne)o(xt)g(step)g(is)g(to)g(specify)g(the)g (connections)f(between)i(them;)k(this)36 b(is)0 1130 y(called)22 b(netlist)f(editing.)28 b(The)22 b(bottom)f(half)h(of)g (the)g(netlist)e(menu)i(is)f(used)h(for)g(editing)f(netlists.)28 b(The)22 b(\002rst)g(thing)0 1251 y(you)h(must)g(do)g(is)g(to)g (specify)h(the)f(netlist)f(you)h(w)o(ant)h(to)f(edit.)30 b(Do)23 b(this)g(by)g(clicking)g(in)g(the)h(current)f(netlist)g(box.)0 1371 y(If)g(you)g(left-click,)g(Magic)f(will)g(prompt)g(you)g(for)h (the)g(netlist)f(name)g(and)h(you)g(can)g(type)f(it)h(at)g(the)f(k)o(e) o(yboard.)30 b(If)0 1491 y(you)24 b(right-click,)g(Magic)h(will)f(use)h (the)f(name)h(of)g(the)g(edit)f(cell)h(as)g(the)g(current)g(netlist)e (name.)31 b(In)25 b(either)g(case,)0 1612 y(Magic)f(will)g(read)h(the)g (netlist)e(from)h(disk)g(if)h(it)f(e)o(xists)f(and)h(will)g(create)i(a) e(ne)n(w)h(netlist)e(if)h(there)h(isn')n(t)f(currently)0 1732 y(a)j(netlist)f(\002le)h(with)f(the)g(gi)n(v)o(en)f(name.)37 b(Netlist)25 b(\002les)i(are)h(stored)e(on)h(disk)f(with)g(a)h (\223.net\224)g(e)o(xtension,)e(which)i(is)0 1853 y(added)g(by)g(Magic) g(when)h(it)e(reads)i(and)f(writes)g(\002les.)39 b(Y)-11 b(ou)27 b(can)g(change)h(the)f(current)h(netlist)e(by)h(clicking)f(the) 0 1973 y(current)32 b(netlist)f(b)n(utton)g(again.)52 b(Startup)32 b(Magic)g(on)g(the)g(cell)g Fc(tut7b)p Fe(,)j(open)d(the)g (netlist)f(menu,)i(and)f(set)g(the)0 2093 y(current)25 b(netlist)f(to)g Fc(tut7b)p Fe(.)32 b(Then)24 b(e)o(xpand)g(the)h (subcells)f(in)g Fc(tut7b)i Fe(so)f(that)f(you)g(can)i(see)f(their)f (terminals.)p 849 2243 2203 4 v 847 2363 4 121 v 899 2327 a(Button)p 1234 2363 V 115 w(Action)p 3050 2363 V 849 2366 2203 4 v 847 2487 4 121 v 899 2451 a(Left)p 1234 2487 V 221 w(Select)h(net,)g(using)f(nearest)h(terminal)f(to)g (cursor)-5 b(.)p 3050 2487 V 849 2490 2203 4 v 847 2610 4 121 v 899 2574 a(Right)p 1234 2610 V 165 w(T)d(oggle)24 b(nearest)h(terminal)f(into)g(or)h(out)f(of)p 3050 2610 V 847 2731 V 1234 2731 V 1286 2695 a(current)h(net.)p 3050 2731 V 849 2734 2203 4 v 847 2854 4 121 v 899 2818 a(Middle)p 1234 2854 V 98 w(Find)g(nearest)g(terminal,)e(join)h(its)g (net)h(with)f(the)p 3050 2854 V 847 2975 V 1234 2975 V 1286 2939 a(current)h(net.)p 3050 2975 V 849 2978 2203 4 v 465 3137 a(T)-8 b(able)24 b(2:)31 b(The)25 b(actions)f(of)h(the)f (mouse)g(b)n(uttons)g(when)g(the)h(terminal)f(tool)g(is)g(in)h(use.)146 3470 y(Netlist)d(editing)h(is)g(done)g(with)f(the)h(netlist)f(tool.)30 b(If)24 b(you)e(ha)n(v)o(en')n(t)h(already)h(read)g(\223T)l(utorial)e (#3:)30 b(Adv)n(anced)0 3590 y(P)o(ainting)37 b(\(W)l(iring)h(and)g (Plo)n(wing\)\224,)j(you)d(should)f(read)i(it)f(no)n(w)-6 b(,)40 b(up)f(through)e(Section)h(2.1.)71 b(T)l(utorial)37 b(#3)0 3711 y(e)o(xplained)22 b(ho)n(w)f(to)h(change)h(the)g(current)f (tool)g(by)g(using)g(the)g(space)h(macro)g(or)g(by)f(typing)f Fc(:tool)p Fe(.)30 b(Switch)22 b(tools)0 3831 y(to)i(the)h(netlist)f (tool)f(\(the)i(cursor)g(will)f(appear)h(as)g(a)h(thick)e(square\).)146 3953 y(When)h(the)g(netlist)f(tool)g(is)g(in)h(use)f(the)h(left,)g (right,)f(and)h(middle)f(b)n(uttons)f(in)l(v)n(ok)o(e)h(select,)h (toggle,)f(and)h(join)0 4074 y(operations)32 b(respecti)n(v)o(ely)e (\(see)j(T)-8 b(able)33 b(II\).)g(T)-8 b(o)32 b(see)h(ho)n(w)e(the)o(y) h(w)o(ork,)i(mo)o(v)o(e)d(the)h(cursor)g(o)o(v)o(er)g(the)g(terminal)0 4194 y Fc(right4)c Fe(in)f(the)g(top)g(subcell)g(of)g Fc(tut7b)i Fe(and)e(click)h(the)f(left)g(mouse)g(b)n(utton)f(\(you)i (may)f(ha)n(v)o(e)g(to)g(zoom)g(in)g(a)h(bit)0 4315 y(to)j(see)h(the)f (labels;)k(terminals)30 b(are)i(numbered)g(in)f(clockwise)g(order:)44 b Fc(right4)32 b Fe(is)f(the)g(fourth)h(terminal)e(from)0 4435 y(the)23 b(top)g(on)h(the)f(right)g(side\).)30 b(This)23 b(causes)h(the)f(net)g(containing)g(that)g(terminal)g(to)g(be)g (selected.)31 b(Three)24 b(hollo)n(w)0 4555 y(white)34 b(squares)h(will)f(appear)h(o)o(v)o(er)f(the)g(layout,)j(marking)c(the) i(terminals)f(that)g(are)h(supposed)f(to)g(be)h(wired)0 4676 y(together)30 b(into)f Fc(right4)p Fe(')-5 b(s)31 b(net.)47 b(Left-click)30 b(o)o(v)o(er)g(the)g Fc(left3)h Fe(terminal)e(in)h(the)g(same)h(subcell)e(to)h(select)h(its)e(net,)0 4796 y(then)24 b(select)h(the)g Fc(right4)g Fe(net)g(again.)146 4918 y(The)d(right)g(b)n(utton)f(is)g(used)h(to)g(toggle)f(terminals)g (into)h(or)g(out)f(of)h(the)g(current)h(net.)29 b(If)23 b(you)f(right-click)f(o)o(v)o(er)0 5039 y(a)26 b(terminal)e(that)h(is)g (in)g(the)g(current)h(net,)f(then)g(it)g(is)g(remo)o(v)o(ed)f(from)h (the)h(current)f(net.)33 b(If)25 b(you)g(right-click)g(o)o(v)o(er)0 5159 y(a)h(terminal)g(that)f(isn')n(t)h(in)f(the)h(current)g(net,)h(it) e(is)h(added)g(to)f(the)h(current)h(net.)34 b(A)26 b(single)f(terminal) g(can)i(only)e(be)0 5280 y(in)31 b(one)g(net)g(at)h(a)f(time,)i(so)e (if)g(a)g(terminal)g(is)g(already)g(in)g(a)h(net)f(when)g(you)g(toggle) g(it)g(into)f(another)h(net)g(then)0 5400 y(Magic)h(will)f(remo)o(v)o (e)g(it)g(from)h(the)g(old)g(net.)52 b(T)-8 b(oggle)31 b(the)h(terminal)g Fc(top4)g Fe(in)g(the)g(bottom)e(cell)i(out)g(of,)h (then)1875 5649 y(\2266\226)p eop %%Page: 7 7 7 6 bop 0 -180 a Fe(Magic)24 b(T)l(utorial)g(#7:)30 b(Netlists)23 b(and)i(Routing)1717 b(April)24 b(12,)h(2006)0 69 y(back)d(into,)g(the) g(net)f(containing)g Fc(right4)p Fe(.)30 b(No)n(w)21 b(toggle)h Fc(left3)g Fe(in)f(the)h(bottom)f(cell)h(into)f(this)g(net.) 29 b(Magic)22 b(w)o(arns)0 189 y(you)29 b(because)i(it)e(had)h(to)f (remo)o(v)o(e)g Fc(left3)h Fe(from)g(another)g(net)f(in)h(order)g(to)f (add)h(it)g(to)f Fc(right4)p Fe(')-5 b(s)30 b(net.)45 b(T)-8 b(ype)30 b Fc(u)g Fe(to)0 309 y(undo)23 b(this)f(change,)i(then) f(left-click)g(on)g Fc(left3)g Fe(to)g(mak)o(e)g(sure)h(it)f(got)f (restored)i(to)f(its)f(old)h(net)g(by)g(the)g(undo.)30 b(All)0 430 y(of)25 b(the)g(netlist-editing)d(operations)i(are)h (undo-able.)146 550 y(The)i(middle)f(b)n(utton)g(is)h(used)g(to)f(mer)n (ge)i(tw)o(o)f(nets)f(together)-5 b(.)37 b(If)27 b(you)g(middle-click)f (o)o(v)o(er)g(a)i(terminal,)e(all)0 671 y(the)h(terminals)g(in)g(its)f (net)i(are)g(added)f(to)g(the)h(current)f(net.)39 b(Play)27 b(around)h(with)e(the)i(three)f(b)n(uttons)f(to)h(edit)g(the)0 791 y(netlist)c Fc(tut7b)p Fe(.)146 911 y(Note:)46 b(the)33 b(router)f(does)g(not)g(mak)o(e)h(connections)f(to)g(terminals)f(in)h (the)h(top)f(le)n(v)o(el)f(cell.)54 b(It)33 b(only)f(w)o(orks)0 1032 y(with)27 b(terminals)g(in)h(subcells,)f(or)h(sub-subcells,)g (etc.)40 b(Because)29 b(of)f(this,)g(the)g(netlist)e(editor)i(does)f (not)h(permit)0 1152 y(you)c(to)h(select)f(terminals)g(in)h(the)f(top)g (le)n(v)o(el)g(cell.)31 b(If)25 b(you)f(click)h(o)o(v)o(er)f(such)g(a)h (terminal)f(Magic)h(prints)e(an)i(error)0 1272 y(message)f(and)h (refuses)g(to)g(mak)o(e)f(the)h(selection.)146 1393 y(If)33 b(you)g(left-click)f(o)o(v)o(er)g(a)h(terminal)f(that)g(is)g(not)g (currently)g(in)h(a)g(net,)h(Magic)e(creates)i(a)f(ne)n(w)f(net)g (auto-)0 1513 y(matically)-6 b(.)42 b(If)29 b(you)g(didn')n(t)f(really) h(w)o(ant)g(to)g(mak)o(e)g(a)g(ne)n(w)g(net,)h(you)e(ha)n(v)o(e)h(se)n (v)o(eral)f(choices.)44 b(Either)28 b(you)h(can)0 1634 y(toggle)e(the)h(terminal)f(out)g(of)h(its)f(o)n(wn)g(net,)h(you)g(can) g(undo)f(the)h(select)g(operation,)f(or)h(you)g(can)g(click)g(the)f Fc(No)0 1754 y(Net)h Fe(b)n(utton)d(in)i(the)g(netlist)f(menu)g(\(you)h (can)h(do)f(this)f(e)n(v)o(en)g(while)h(the)g(cursor)g(is)f(in)h(the)g (square)g(shape\).)38 b(The)0 1874 y Fc(No)29 b(Net)h Fe(b)n(utton)f(remo)o(v)o(es)f(all)h(terminals)g(from)g(the)h(current)f (net)h(and)f(destro)o(ys)g(the)h(net.)44 b(It')-5 b(s)29 b(a)h(bad)g(idea)f(to)0 1995 y(lea)n(v)o(e)c(single-net)e(terminals)h (in)h(the)f(netlist:)29 b(the)c(router)g(will)f(treat)h(them)f(as)h (errors.)146 2115 y(There)k(are)f(tw)o(o)g(w)o(ays)f(to)h(sa)n(v)o(e)f (netlists)f(on)i(disk;)g(these)g(are)g(similar)f(to)h(the)f(w)o(ays)h (you)f(can)h(sa)n(v)o(e)g(layout)0 2236 y(cells.)i(If)c(you)e(type)900 2455 y Fc(:sa)n(v)o(enetlist)g Fe([)p Ff(name)p Fe(])146 2674 y(with)41 b(the)g(cursor)g(o)o(v)o(er)g(the)g(netlist)f(menu,)45 b(the)c(current)g(netlist)f(will)h(be)g(sa)n(v)o(ed)g(on)g(disk)g(in)g (the)g(\002le)0 2795 y Ff(name)p Fe(.)p Fc(net)p Fe(.)31 b(If)26 b(no)e Ff(name)h Fe(is)f(typed,)g(the)h(name)g(of)g(the)f (current)h(netlist)f(is)g(used.)30 b(If)c(you)e(type)h(the)f(command) 900 3014 y Fc(:writeall)146 3233 y Fe(then)19 b(Magic)g(will)f(step)h (through)f(all)h(the)g(netlists)f(that)g(ha)n(v)o(e)h(been)h (modi\002ed)e(since)h(the)o(y)f(were)i(last)f(written,)0 3354 y(asking)30 b(you)g(if)g(you')-5 b(d)30 b(lik)o(e)g(them)g(to)g (be)h(written)f(out.)47 b(If)31 b(you)f(try)h(to)f(lea)n(v)o(e)g(Magic) g(without)f(sa)n(ving)h(all)g(the)0 3474 y(modi\002ed)24 b(netlists,)f(Magic)i(will)f(w)o(arn)h(you)f(and)h(gi)n(v)o(e)e(you)i (a)g(chance)g(to)g(write)f(them)h(out.)146 3594 y(If)k(you)e(mak)o(e)h (changes)g(to)g(a)g(netlist)f(and)h(then)f(decide)h(you)g(don')n(t)g(w) o(ant)f(them,)h(you)g(can)g(use)g(the)g Fc(:\003ush)0 3715 y Fe(netlist)e(command)h(to)g(thro)n(w)g(a)o(w)o(ay)g(all)g(of)h (the)g(changes)f(and)h(re-read)g(the)g(netlist)e(from)h(its)g(disk)g (\002le.)40 b(If)28 b(you)0 3835 y(create)f(netlists)d(using)g(a)j(te)o (xt)d(editor)i(or)f(some)g(other)h(program,)g(you)f(can)h(use)f Fc(:\003ush)i Fe(after)g(you')-5 b(v)o(e)25 b(modi\002ed)0 3955 y(the)g(netlist)e(\002le)i(in)g(order)g(to)f(mak)o(e)h(sure)g (that)f(Magic)h(is)f(using)g(the)g(most)g(up-to-date)h(v)o(ersion.)146 4076 y(The)f Fc(Print)f Fe(b)n(utton)f(in)h(the)g(netlist)f(menu)g (will)h(print)f(out)h(on)g(the)g(te)o(xt)f(screen)i(the)f(names)f(of)i (all)f(the)g(termi-)0 4196 y(nals)g(in)g(the)g(current)g(net.)30 b(T)m(ry)23 b(this)f(for)i(some)e(of)i(the)f(nets)f(in)h Fc(tut7b)p Fe(.)31 b(The)24 b(of)n(\002cial)f(name)g(of)g(a)h(terminal) e(looks)0 4317 y(a)27 b(lot)g(lik)o(e)g(a)g(Unix)f(\002le)i(name,)g (consisting)d(of)i(a)g(b)n(unch)g(of)g(\002elds)h(separated)f(by)g (slashes.)37 b(Each)27 b(\002eld)g(e)o(xcept)0 4437 y(the)21 b(last)f(is)h(the)g(id)f(of)h(a)g(subcell,)g(and)g(the)g(last)g (\002eld)g(is)f(the)h(name)g(of)g(the)g(terminal.)28 b(These)21 b(hierarchical)g(names)0 4557 y(pro)o(vide)f(unique)g(names) g(for)i(each)f(terminal,)g(e)n(v)o(en)f(if)h(the)f(same)h(terminal)f (name)h(is)f(re-used)h(in)g(dif)n(ferent)f(cells)0 4678 y(or)25 b(if)g(there)g(are)g(multiple)e(copies)i(of)g(the)f(same)h (cell.)146 4798 y(The)g Fc(V)-10 b(erify)25 b Fe(b)n(utton)f(will)g (check)h(the)f(paint)h(of)f(the)h(edit)f(cell)h(to)g(be)f(sure)h(it)g (implements)d(the)j(connections)0 4918 y(speci\002ed)g(in)f(the)g (current)g(netlist.)29 b(Feedback)d(areas)f(are)g(created)g(to)f(sho)n (w)f(nets)h(that)g(are)h(incomplete)e(or)i(nets)0 5039 y(that)f(are)i(shorted)e(together)-5 b(.)146 5159 y(The)29 b Fc(T)-9 b(erms)28 b Fe(b)n(utton)f(will)h(cause)g(Magic)g(to)g (generate)h(a)g(feedback)f(area)i(o)o(v)o(er)d(each)i(of)f(the)g (terminals)f(in)0 5280 y(the)h(current)g(netlist,)f(so)h(that)g(you)f (can)i(see)f(which)f(terminals)g(are)i(included)e(in)h(the)g(netlist.) 39 b(If)28 b(you)g(type)f(the)0 5400 y(command)d Fc(:feedback)j(clear)e Fe(in)f(a)h(layout)f(windo)n(w)g(then)g(the)h(feedback)g(will)f(be)h (erased.)1875 5649 y(\2267\226)p eop %%Page: 8 8 8 7 bop 0 -180 a Fe(April)24 b(12,)h(2006)1717 b(Magic)24 b(T)l(utorial)g(#7:)30 b(Netlists)23 b(and)i(Routing)146 69 y(The)30 b Fc(Cleanup)h Fe(b)n(utton)d(is)i(there)g(as)f(a)h(con)l (v)o(enience)g(to)f(help)h(you)f(cleanup)g(your)h(netlists.)44 b(If)30 b(you)f(click)0 189 y(on)d(it,)g(Magic)f(will)g(scan)i(through) e(the)g(current)i(netlist)d(to)i(mak)o(e)g(sure)g(it)g(is)f (reasonable.)35 b Fc(Cleanup)27 b Fe(looks)e(for)0 309 y(tw)o(o)31 b(error)h(conditions:)42 b(terminal)31 b(names)g(that)g (don')n(t)g(correspond)g(to)g(an)o(y)g(labels)g(in)g(the)g(design,)h (and)g(nets)0 430 y(that)27 b(don')n(t)g(ha)n(v)o(e)g(at)g(least)g(tw)o (o)g(terminals.)38 b(When)27 b(it)g(\002nds)g(either)g(of)h(these)f (conditions)f(it)g(prints)h(a)g(message)0 550 y(and)33 b(gi)n(v)o(es)e(you)h(the)h(chance)g(to)g(either)g(delete)f(the)h(of)n (fending)f(terminal)g(\(if)h(you)f(type)g Fc(dterm)p Fe(\),)k(delete)d(the)0 671 y(of)n(fending)25 b(net)g(\()p Fc(dnet)p Fe(\),)j(skip)d(the)g(current)h(problem)f(without)f (modifying)g(the)i(netlist)e(and)i(continue)f(looking)0 791 y(for)39 b(other)f(problems)g(\()p Fc(skip)p Fe(\),)k(or)d(abort)f (the)h Fc(Cleanup)g Fe(command)f(without)f(making)h(an)o(y)g(more)g (changes)0 911 y(\()p Fc(abort)p Fe(\).)146 1032 y(The)27 b Fc(Sho)o(w)g Fe(b)n(utton)f(pro)o(vides)f(an)i(additional)f (mechanism)f(for)i(displaying)e(the)i(paint)f(in)g(the)h(net.)36 b(If)28 b(you)0 1153 y(place)35 b(the)g(box)f(o)o(v)o(er)g(a)h(piece)g (of)g(paint)f(and)g(click)h(on)f Fc(Sho)o(w)p Fe(,)k(Magic)c(will)g (highlight)f(all)h(of)h(the)f(paint)g(in)0 1273 y(the)j(net)f(under)h (the)g(box.)66 b(This)36 b(is)g(similar)g(to)h(pointing)e(at)h(the)h (net)g(and)g(typing)e Fc(s)i Fe(three)g(times)f(to)g(select)0 1393 y(the)25 b(net,)h(e)o(xcept)f(that)g Fc(Sho)o(w)h Fe(doesn')n(t)g(select)f(the)h(net)f(\(it)g(uses)h(a)f(dif)n(ferent)h (mechanism)e(to)h(highlight)f(it\),)h(and)0 1514 y Fc(Sho)o(w)d Fe(will)e(trace)i(through)e(all)h(cells,)g(e)o(xpanded)g(or)g(not)g (\(the)g(selection)f(mechanism)g(only)h(considers)f(paint)g(in)0 1634 y(e)o(xpanded)j(cells\).)31 b(Once)24 b(you')-5 b(v)o(e)23 b(used)h Fc(Sho)o(w)g Fe(to)g(highlight)e(a)i(net,)g(the)g (only)f(w)o(ay)h(to)f(mak)o(e)h(the)g(highlighting)0 1754 y(go)k(a)o(w)o(ay)h(is)f(to)g(place)h(the)g(box)f(o)o(v)o(er)g (empty)f(space)i(and)g(in)l(v)n(ok)o(e)f Fc(Sho)o(w)h Fe(again.)42 b Fc(Sho)o(w)29 b Fe(is)f(an)h(old)f(command)0 1875 y(that)23 b(pre-dates)i(the)e(selection)h(interf)o(ace,)g(b)n(ut)g (we')-5 b(v)o(e)23 b(left)h(it)g(in)f(Magic)h(because)g(some)g(people)f (\002nd)h(it)g(useful.)0 2218 y Fg(5)143 b(Netlist)34 b(Files)0 2442 y Fe(Netlists)25 b(are)i(stored)f(on)g(disk)g(in)g (ordinary)g(te)o(xt)f(\002les.)35 b(Y)-11 b(ou)26 b(are)i(welcome)e(to) g(edit)g(those)f(\002les)i(by)f(hand)g(or)g(to)0 2562 y(write)h(programs)g(that)g(generate)g(the)h(netlists)d(automatically) -6 b(.)37 b(F)o(or)27 b(e)o(xample,)g(a)g(netlist)f(might)g(be)i (generated)0 2683 y(by)d(a)g(schematic)f(editor)h(or)g(by)f(a)i (high-le)n(v)o(el)d(simulator)-5 b(.)29 b(See)d(the)e(manual)h(page)g Ff(net\(5\))g Fe(for)g(a)g(description)f(of)0 2803 y(netlist)f(\002le)j (format.)0 3146 y Fg(6)143 b(Running)34 b(the)h(Router)0 3371 y Fe(Once)27 b(you')-5 b(v)o(e)26 b(created)h(a)f(netlist,)g(it)g (is)g(relati)n(v)o(ely)f(easy)h(to)g(in)l(v)n(ok)o(e)g(the)g(router)-5 b(.)36 b(First,)26 b(place)h(the)f(box)g(around)0 3491 y(the)21 b(area)g(you')-5 b(d)21 b(lik)o(e)f(Magic)g(to)h(consider)f (for)h(routing.)28 b(No)21 b(terminals)f(outside)f(this)h(area)i(will)e (be)h(considered,)0 3611 y(and)26 b(Magic)f(will)g(not)h(generate)g(an) o(y)f(paint)h(more)f(than)h(a)g(fe)n(w)g(units)f(outside)f(this)h(area) i(\(Magic)f(may)f(use)h(the)0 3732 y(ne)o(xt)g(routing)g(grid)h(line)f (outside)g(the)h(area\).)38 b(Load)27 b Fc(tut7d)p Fe(,)i Fc(:\003ush)f Fe(the)f(netlist)f(if)h(you)f(made)h(an)o(y)f(changes)h (to)0 3852 y(it,)d(set)h(the)f(box)h(to)f(the)h(bounding)e(box)h(of)h (the)g(cell,)g(and)f(then)h(in)l(v)n(ok)o(e)f(the)h(router)g(using)e (the)i(command:)900 4084 y Fc(:r)n(oute)146 4316 y Fe(When)j(the)f (command)f(completes,)h(the)g(netlist)f(should)g(be)i(routed.)38 b(Click)27 b(the)g Fc(V)-10 b(erify)27 b Fe(netlist)f(b)n(utton)g(to)0 4436 y(mak)o(e)31 b(sure)h(the)f(connections)f(were)i(made)f(correctly) -6 b(.)50 b(T)m(ry)31 b(deleting)g(a)g(piece)h(from)f(one)g(of)h(the)f (wires)g(and)0 4557 y(v)o(erify)e(again.)45 b(Feedback)31 b(areas)g(should)d(appear)j(to)e(indicate)g(where)h(the)g(routing)f(w)o (as)h(incorrect.)45 b(Use)30 b(the)0 4677 y Fc(:feedback)h Fe(command)c(to)h(step)h(through)e(the)i(areas)g(and,)g(e)n(v)o (entually)-6 b(,)27 b(to)i(delete)f(the)h(feedback)g(\()p Fc(:feedback)0 4798 y(help)d Fe(gi)n(v)o(es)d(a)i(synopsis)e(of)i(the)g (command)e(options\).)146 4918 y(If)28 b(the)g(router)f(is)h(unable)f (to)g(complete)g(the)g(connections,)h(it)f(will)g(report)g(errors)h(to) f(you.)39 b(Errors)28 b(may)f(be)0 5039 y(reported)g(in)f(se)n(v)o (eral)g(w)o(ays.)36 b(F)o(or)27 b(some)f(errors,)h(such)g(as)g(non-e)o (xistent)e(terminal)g(names,)i(messages)f(will)g(be)0 5159 y(printed.)44 b(F)o(or)29 b(other)g(errors,)i(cross-hatched)e (feedback)h(areas)g(will)e(be)i(created.)45 b(Most)28 b(of)h(the)g(feedback)h(ar)n(-)0 5280 y(eas)d(ha)n(v)o(e)f(messages)g (similar)g(to)g(\223Net)h(shifter/bit[0]/phi1:)32 b(Can')n(t)27 b(mak)o(e)g(bottom)e(connection.)-7 b(\224)36 b(T)-8 b(o)26 b(see)h(the)0 5400 y(message)c(associated)f(with)h(a)g(feedback) h(area,)g(place)g(the)f(box)f(o)o(v)o(er)g(the)h(feedback)h(area)g(and) f(type)g Fc(:feedback)1875 5649 y Fe(\2268\226)p eop %%Page: 9 9 9 8 bop 0 -180 a Fe(Magic)24 b(T)l(utorial)g(#7:)30 b(Netlists)23 b(and)i(Routing)1717 b(April)24 b(12,)h(2006)0 68 y Fc(wh)o(y)p Fe(.)52 b(In)31 b(this)g(case)i(the)e(message)h(means)f(that)h(for)g (some)f(reason)h(the)g(router)g(w)o(as)f(unable)h(to)f(connect)h(the)0 188 y(speci\002ed)e(net)g(\(named)f(by)h(one)g(of)f(its)g(terminals\))g (within)g(one)h(of)f(the)h(routing)f(channel.)45 b(The)30 b(terms)f(\223bot-)0 309 y(tom\224,)k(\223top\224,)h(etc.)53 b(may)32 b(be)g(misnomers)e(because)j(Magic)f(sometimes)e(rotates)i (channels)g(before)g(routing:)0 429 y(the)26 b(names)f(refer)i(to)e (the)h(direction)e(at)i(the)g(time)f(the)g(channel)h(w)o(as)g(routed,)f (not)g(the)h(direction)f(in)g(the)h(circuit.)0 549 y(Ho)n(we)n(v)o(er)l (,)i(the)h(location)f(of)g(the)h(feedback)g(area)h(indicates)e(where)h (the)g(connection)f(w)o(as)g(supposed)g(to)g(ha)n(v)o(e)0 670 y(been)d(made.)146 919 y(Y)-11 b(ou')-5 b(v)o(e)24 b(probably)f(noticed)h(by)f(no)n(w)h(that)f(the)h(router)g(sometimes)f (generates)h(unnecessary)g(wiring,)f(such)0 1040 y(as)36 b(inserting)f(e)o(xtra)h(jogs)g(and)g(U-shapes)g(in)g(wires)g(\(look)f (ne)o(xt)h(to)g Fc(right3)g Fe(in)g(the)g(top)g(cell\).)65 b(These)36 b(jogs)0 1160 y(are)31 b(particularly)f(noticeable)g(in)g (small)g(e)o(xamples.)46 b(Ho)n(we)n(v)o(er)l(,)31 b(the)f(router)h (actually)f(does)g Ff(better)g Fe(on)g(lar)n(ger)0 1281 y(e)o(xamples:)37 b(there)29 b(will)f(still)f(be)i(a)g(bit)f(of)g(e)o (xtra)h(wire,)g(b)n(ut)f(it')-5 b(s)28 b(ne)o(gligible)f(in)h (comparison)f(to)i(the)f(total)g(wire)0 1401 y(length)g(on)h(a)g(lar)n (ge)h(chip.)43 b(Some)29 b(of)g(this)f(wire)h(is)g(necessary)g(and)g (important:)38 b(it)29 b(helps)f(the)h(router)g(to)g(a)n(v)n(oid)0 1521 y(se)n(v)o(eral)j(problem)f(situations)g(that)h(w)o(ould)f(cause)i (it)f(to)g(f)o(ail)g(on)g(more)h(dif)n(\002cult)e(e)o(xamples.)53 b(Ho)n(we)n(v)o(er)l(,)33 b(you)0 1642 y(can)i(use)g(the)g Fc(straighten)h Fe(command)e(described)h(in)f(\223Magic)h(T)l(utorial)f (#3:)50 b(Adv)n(anced)35 b(P)o(ainting)f(\(W)l(iring)0 1762 y(and)26 b(Plo)n(wing\)\224)f(to)g(remo)o(v)o(e)g(unnecessary)h (jogs.)33 b(Please)27 b(don')n(t)e(judge)h(the)f(router)h(by)g(its)f (beha)n(vior)h(on)f(small)0 1882 y(e)o(xamples.)30 b(On)24 b(the)h(other)g(hand,)f(if)h(it)f(does)h(a)o(wful)f(things)f(on)i(big)f (e)o(xamples,)g(we')-5 b(d)25 b(lik)o(e)f(to)h(kno)n(w)e(about)i(it.) 146 2132 y(All)i(of)g(the)f(wires)h(placed)g(by)g(the)f(router)h(are)h (of)f(the)f(same)h(width,)f(so)h(the)g(router)f(w)o(on')n(t)h(be)g(v)o (ery)g(useful)0 2252 y(for)e(po)n(wer)f(and)h(ground)f(wiring.)146 2502 y(When)37 b(using)e(the)h(Magic)g(router)l(,)j(you)d(can)g(wire)h (po)n(wer)e(and)i(ground)e(by)h(hand)g(before)h(running)e(the)0 2622 y(router)-5 b(.)34 b(The)26 b(router)g(will)g(be)g(able)g(to)g(w)o (ork)g(around)g(your)g(hand-placed)g(connections)f(to)h(mak)o(e)g(the)g (connec-)0 2743 y(tions)c(in)i(the)f(netlist.)29 b(If)24 b(there)g(are)g(certain)g(k)o(e)o(y)f(signals)f(that)h(you)g(w)o(ant)g (to)h(wire)f(carefully)h(by)f(hand,)h(you)f(can)0 2863 y(do)j(this)f(too;)h(the)f(router)i(will)e(w)o(ork)h(around)f(them.)34 b(Signals)26 b(that)f(you)h(route)g(by)f(hand)h(should)f(not)g(be)i(in) e(the)0 2984 y(netlist.)k Fc(T)-9 b(utorial7b)26 b Fe(has)e(an)h(e)o (xample)f(of)h(\223hand)g(routing\224)f(in)g(the)h(form)g(of)g(a)g (piece)g(of)g(metal)f(in)h(the)f(middle)0 3104 y(of)k(the)f(circuit.)38 b(Undo)27 b(the)g(routing,)g(and)g(try)h(modifying)d(the)j(metal)e (and/or)i(adding)e(more)h(hand)h(routing)e(of)0 3224 y(your)f(o)n(wn)e(to)i(see)g(ho)n(w)f(it)g(af)n(fects)h(the)g(routing.) 146 3474 y(The)g(Magic)f(router)g(has)g(a)h(number)f(of)g(options)f (useful)h(for)h(getting)e(information)g(about)h(the)g(routing)f(and)0 3594 y(setting)g(routing)g(parameters.)31 b(Y)-11 b(ou)24 b(need)g(to)g(in)l(v)n(ok)o(e)f(the)h Fc(r)n(oute)i Fe(command)d(once)h (for)h(each)g(option)e(you)g(w)o(ant)0 3715 y(to)g(specify;)h(then)f (type)h Fc(:r)n(oute)h Fe(with)e(no)g(options)f(to)i(start)f(up)h(the)f (router)h(with)f(whate)n(v)o(er)g(parameters)h(you')-5 b(v)o(e)0 3835 y(set.)36 b(The)27 b Fc(viamin)p Fe(,)f(option)g(which)g (in)l(v)n(ok)o(es)g(a)h(routing)e(post-pass)h(is,)g(of)h(course,)g(in)l (v)n(ok)o(ed)f(AFTER)h(routing.)0 3955 y(T)-8 b(ype)34 b Fc(:r)n(oute)h(netlist)f Ff(\002le)f Fe(to)g(specify)h(a)g(netlist)e (for)i(the)g(routing)e(without)h(ha)n(ving)g(to)g(open)g(up)h(the)f (netlist)0 4076 y(menu.)54 b(The)33 b Fc(metal)f Fe(option)g(lets)g (you)g(toggle)g(metal)g(maximization)f(on)h(and)h(of)n(f;)j(if)d(metal) f(maximization)0 4196 y(is)c(turned)h(on,)g(the)g(router)f(con)l(v)o (erts)g(routing)g(from)g(the)h(alternate)g(routing)e(layer)i (\(\223poly\224\))g(to)f(the)h(preferred)0 4317 y(routing)d(layer)i (\(\223metal\224\))g(where)n(v)o(er)f(possible.)38 b(The)27 b Fc(vias)g Fe(option)f(controls)h(metal)g(maximization)f(by)h(spec-)0 4437 y(ifying)k(ho)n(w)g(man)o(y)g(grid)h(units)f(of)h(\223metal\224)g (con)l(v)o(ersion)f(mak)o(e)h(it)f(w)o(orthwhile)g(to)h(place)g(vias;)j (setting)c(this)0 4557 y(to)c(5)h(means)f(that)g(metal)g(maximization)f (will)g(add)i(e)o(xtra)f(vias)g(only)g(if)h(5)f(or)h(more)f(grid)g (units)g(of)g(\223poly\224)h(can)0 4678 y(be)33 b(con)l(v)o(erted)g(to) g(\223metal\224.)56 b(V)-6 b(ie)n(w)32 b(the)h(current)h(technology')-5 b(s)31 b(router)i(parameters)h(with)e(the)h Fc(tech)h Fe(option.)0 4798 y(The)28 b Fc(jog)p Fe(,)g Fc(obstacle)p Fe(,)g(and)g Fc(steady)f Fe(options)f(let)i(you)f(vie)n(w)g(and)g (change)h(parameters)g(to)f(control)g(the)g(channel)0 4918 y(router)21 b(\(this)e(feature)j(is)e(for)h(adv)n(anced)f (users\).)29 b(The)21 b Fc(viamin)f Fe(option)f(in)l(v)n(ok)o(es)h(a)h (via)f(minimization)f(algorithm)0 5039 y(which)24 b(reduces)h(the)f (number)g(of)h(vias)f(in)g(a)h(routed)f(layout.)30 b(This)24 b(can)h(be)g(used)f(as)g(a)h(post-processing)e(step)h(to)0 5159 y(impro)o(v)o(e)k(the)h(quality)f(of)i(the)f(routing.)44 b(This)28 b(may)h(be)h(useful)f(e)n(v)o(en)g(when)g(using)f(another)i (router)f(to)g(do)g(the)0 5280 y(actual)f(routing.)39 b(Finally)-6 b(,)27 b(sho)n(w)g(all)h(parameter)g(v)n(alues)f(with)g (the)h Fc(settings)g Fe(option.)38 b(The)28 b(options)f(and)g(their)0 5400 y(actions)d(are)i(summarized)e(in)g(T)-8 b(able)25 b(III.)1875 5649 y(\2269\226)p eop %%Page: 10 10 10 9 bop 0 -180 a Fe(April)24 b(12,)h(2006)1717 b(Magic)24 b(T)l(utorial)g(#7:)30 b(Netlists)23 b(and)i(Routing)p 563 3 2775 4 v 561 124 4 121 v 612 88 a(Option)p 1185 124 V 347 w(Action)p 3336 124 V 563 127 2775 4 v 561 247 4 121 v 612 211 a Fc(end)p 1185 247 V 471 w Fe(Print)g(the)f (channel)h(router)g(end)g(constant)p 3336 247 V 561 368 V 612 332 a Fc(end)p Ff(r)l(eal)p 1185 368 V 314 w Fe(Set)g(the)g (channel)f(router)h(end)g(constant)p 3336 368 V 563 371 2775 4 v 561 491 4 121 v 612 455 a Fc(help)p 1185 491 V 443 w Fe(Print)g(a)g(summary)e(of)i(the)g(router)g(options)p 3336 491 V 563 495 2775 4 v 561 615 4 121 v 612 579 a Fc(jog)p 1185 615 V 492 w Fe(Print)g(the)f(channel)h(router)g(minimum)d (jog)i(length)p 3336 615 V 561 736 V 612 699 a Fc(jog)h Ff(int)p 1185 736 V 361 w Fe(Set)g(the)g(minimum)d(jog)i(length,)g (measured)h(in)f(grid)h(units)p 3336 736 V 563 739 2775 4 v 561 859 4 121 v 612 823 a Fc(metal)p 1185 859 V 387 w Fe(T)-8 b(oggle)24 b(metal)g(maximization)f(on)i(or)g(of)n(f)p 3336 859 V 563 863 2775 4 v 561 983 4 121 v 612 947 a Fc(netlist)p 1185 983 V 365 w Fe(Print)g(the)f(name)h(of)g(the)f (current)h(net)g(list)p 3336 983 V 561 1103 V 612 1067 a Fc(netlist)g Ff(\002le)p 1185 1103 V 218 w Fe(Set)g(the)g(current)g (net)f(list)p 3336 1103 V 563 1107 2775 4 v 561 1227 4 121 v 612 1191 a Fc(obstacle)p 1185 1227 V 282 w Fe(Print)h(the)f (channel)h(router)g(obstacle)f(constant)p 3336 1227 V 561 1347 V 612 1311 a Fc(obstacle)h Ff(r)l(eal)p 1185 1347 V 100 w Fe(Set)g(the)g(obstacle)f(constant)p 3336 1347 V 563 1351 2775 4 v 561 1471 4 121 v 612 1435 a Fc(settings)p 1185 1471 V 304 w Fe(Print)h(a)g(list)e(of)i(all)g (router)g(parameters)p 3336 1471 V 563 1474 2775 4 v 561 1595 4 121 v 612 1559 a Fc(steady)p 1185 1595 V 354 w Fe(Print)g(the)f(channel)h(router)g(steady)f(net)h(constant)p 3336 1595 V 561 1715 V 612 1679 a Fc(steady)h Ff(int)p 1185 1715 V 222 w Fe(Set)f(the)g(steady)f(net)h(constant,)f(measured)g (in)h(grid)f(units)p 3336 1715 V 563 1719 2775 4 v 561 1839 4 121 v 612 1803 a Fc(tech)p 1185 1839 V 449 w Fe(Print)h(router)f (technology)g(information)p 3336 1839 V 563 1842 2775 4 v 561 1963 4 121 v 612 1927 a Fc(vias)p 1185 1963 V 458 w Fe(Print)h(the)f(metal)g(maximization)f(via)i(limit)p 3336 1963 V 561 2083 V 612 2047 a Fc(vias)f Ff(int)p 1185 2083 V 328 w Fe(Set)h(the)g(via)f(limit)p 3336 2083 V 563 2086 2775 4 v 561 2207 4 121 v 612 2171 a Fc(viamin)p 1185 2207 V 331 w Fe(Minimize)f(vias)i(in)f(a)h(routed)g(layout.)p 3336 2207 V 563 2210 2775 4 v 927 2477 a(T)-8 b(able)25 b(3:)30 b(A)25 b(summary)f(of)h(all)f(of)h(Magic)g(router)g(options.)0 2764 y Fg(7)143 b(Ho)o(w)35 b(the)g(Router)f(W)-11 b(orks)0 2991 y Fe(In)24 b(order)g(to)g(mak)o(e)f(the)h(router)g(produce)g(the)f (best)h(possible)e(results,)i(it)f(helps)g(to)h(kno)n(w)f(a)h(little)e (bit)i(about)f(ho)n(w)0 3111 y(it)32 b(w)o(orks.)55 b(The)32 b(router)h(runs)g(in)f(three)h(stages,)h(called)f Ff(c)o(hannel)f (de\002nition)p Fe(,)h Ff(global)f(r)l(outing)p Fe(,)g(and)h Ff(c)o(hannel)0 3232 y(r)l(outing)p Fe(.)51 b(In)33 b(the)f(channel)g (de\002nition)f(phase,)k(Magic)d(di)n(vides)e(the)i(area)i(of)e(the)g (edit)g(cell)g(into)g(rectangular)0 3352 y(routing)i(areas)h(called)g (channels.)60 b(The)35 b(channels)f(co)o(v)o(er)h(all)f(the)h(space)g (under)f(the)h(box)f(e)o(xcept)h(the)f(areas)0 3472 y(occupied)25 b(by)g(subcells.)31 b(All)25 b(of)g(Magic')-5 b(s)25 b(routing)f(goes)h(in)g(the)g(channel)g(areas,)h(e)o(xcept)f(that)g (stems)f(\(Section)0 3593 y(8.2\))h(may)f(e)o(xtend)g(o)o(v)o(er)g (subcells.)146 3715 y(T)-8 b(o)28 b(see)h(the)f(channel)g(structure)g (that)g(Magic)g(chose,)h(place)f(the)g(box)g(in)g Fc(tut7d)h Fe(as)f(if)h(you)e(were)i(going)e(to)0 3835 y(route,)e(then)f(type)g (the)h(command)900 4075 y Fc(:channel)146 4314 y Fe(in)30 b(the)g(layout)g(windo)n(w)-6 b(.)45 b(Magic)30 b(will)f(compute)h(the) g(channel)g(structure)g(and)g(display)g(it)f(on)h(the)h(screen)0 4434 y(as)j(a)f(collection)g(of)g(feedback)h(areas.)58 b(The)33 b(channel)h(structure)f(is)g(displayed)f(as)i(white)f (rectangles.)56 b(T)-8 b(ype)0 4554 y Fc(:feedback)27 b(clear)e Fe(when)g(you')-5 b(re)25 b(through)f(looking)f(at)i(them.) 146 4676 y(The)32 b(second)g(phase)g(of)g(routing)f(is)h(global)f (routing.)51 b(In)32 b(the)g(global)f(routing)g(phase,)j(Magic)e (considers)0 4797 y(each)22 b(net)f(in)g(turn)g(and)g(chooses)g(the)g (sequence)h(of)f(channels)h(the)f(net)g(must)f(pass)h(through)g(in)g (order)g(to)g(connect)0 4917 y(its)28 b(terminals.)41 b(The)28 b Ff(cr)l(ossing)f(points)g Fe(\(places)i(where)g(the)f(net)h (crosses)f(from)h(one)f(channel)h(to)f(another\))g(are)0 5037 y(chosen)d(at)f(this)g(point,)g(b)n(ut)g(not)g(the)h(e)o(xact)g (path)f(through)g(each)h(channel.)146 5159 y(In)36 b(the)f(third)g (phase,)j(each)e(channel)g(is)f(considered)g(separately)-6 b(.)62 b(All)35 b(the)g(nets)h(passing)e(through)h(that)0 5280 y(channel)30 b(are)h(e)o(xamined)e(at)h(once,)i(and)e(the)g(e)o (xact)g(path)g(of)h(each)f(net)g(is)g(decided.)47 b(Once)31 b(the)f(routing)f(paths)0 5400 y(ha)n(v)o(e)c(been)g(determined,)f (paint)g(is)g(added)h(to)f(the)h(edit)f(cell)h(to)f(implement)g(the)g (routing.)1850 5649 y(\22610\226)p eop %%Page: 11 11 11 10 bop 0 -180 a Fe(Magic)24 b(T)l(utorial)g(#7:)30 b(Netlists)23 b(and)i(Routing)1717 b(April)24 b(12,)h(2006)146 68 y(The)20 b(router)g(is)g(grid-based:)27 b(all)20 b(wires)g(are)h (placed)f(on)f(a)i(uniform)e(grid.)28 b(F)o(or)20 b(the)g(standard)f (nMOS)h(process)0 188 y(the)28 b(grid)g(spacing)g(is)g(7)h(units,)f (and)g(for)h(the)f(standard)g(SCMOS)h(process)g(it)f(is)g(8)g(units.)40 b(If)29 b(you)f(type)g Fc(:grid)h(8)0 309 y Fe(after)h(routing)d Fc(tut7b)p Fe(,)k(you')o(ll)d(see)i(that)e(all)h(of)g(the)f(routing)g (lines)h(up)f(with)g(its)g(lo)n(wer)h(and)g(left)g(sides)f(on)h(grid)0 429 y(lines.)55 b(F)o(ortunately)-6 b(,)34 b(you)e(don')n(t)h(ha)n(v)o (e)g(to)g(mak)o(e)g(your)f(cell)h(terminals)g(line)f(up)h(on)g(e)n(v)o (en)f(grid)h(boundaries.)0 549 y(During)24 b(the)h(routing)e(Magic)i (generates)g Ff(stems)f Fe(that)g(connect)h(your)f(terminals)g(up)g(to) h(grid)f(lines)g(at)h(the)f(edges)0 670 y(of)31 b(channels.)50 b(Notice)32 b(that)e(there')-5 b(s)31 b(space)h(left)f(by)g(Magic)g (between)h(the)f(subcells)g(and)g(the)g(channels;)j(this)0 790 y(space)25 b(is)g(used)f(by)h(the)f(stem)g(generator)-5 b(.)0 1178 y Fg(8)143 b(What)36 b(to)f(do)h(When)f(the)g(Router)f(F)l (ails)0 1417 y Fe(Don')n(t)27 b(be)h(surprised)f(if)h(the)f(router)h (is)f(unable)g(to)h(mak)o(e)f(all)g(the)h(connections)f(the)g(\002rst)h (time)f(you)g(try)g(it)g(on)h(a)0 1538 y(lar)n(ge)i(circuit.)45 b(Unless)29 b(you)h(ha)n(v)o(e)f(e)o(xtra)h(routing)e(space)j(in)e (your)g(chip,)i(you)e(may)h(ha)n(v)o(e)f(to)g(mak)o(e)h(slight)e(re-)0 1658 y(arrangements)23 b(to)g(help)g(the)g(router)g(out.)30 b(The)23 b(paragraphs)h(belo)n(w)e(describe)i(things)e(you)g(can)i(do)f (to)g(mak)o(e)g(life)0 1778 y(easier)h(for)g(the)g(router)-5 b(.)30 b(This)23 b(section)g(is)h(not)f(v)o(ery)h(well)f(de)n(v)o (eloped,)g(so)g(we')-5 b(d)24 b(lik)o(e)g(to)f(hear)i(about)e (techniques)0 1899 y(you)28 b(use)h(to)f(impro)o(v)o(e)f(routability)-6 b(.)39 b(If)30 b(you)e(disco)o(v)o(er)f(ne)n(w)h(techniques,)h(send)f (us)g(mail)g(and)h(we')o(ll)f(add)h(them)0 2019 y(to)24 b(this)g(section.)0 2363 y Fd(8.1)119 b(Channel)32 b(Structur)n(e)0 2566 y Fe(One)d(of)h(the)f(\002rst)g(things)f(to)h(check)h(when)f(the)h (router)f(f)o(ails)g(is)g(the)g(channel)g(structure.)44 b(If)30 b(using)e(the)h(Magic)0 2686 y(router)l(,)c(type)f Fc(:channel)i Fe(to)e(look)g(at)h(the)g(channels.)30 b(One)25 b(common)e(mistak)o(e)h(is)g(to)g(ha)n(v)o(e)h(some)f(of)h (the)f(desired)0 2807 y(routing)32 b(area)i(co)o(v)o(ered)f(by)f (subcells;)37 b(Magic)32 b(only)h(runs)f(wires)h(where)h(there)f(are)h (no)f(subcells.)55 b(Check)33 b(to)0 2927 y(be)e(sure)g(that)f(there)h (are)g(channels)g(e)n(v)o(erywhere)f(that)g(you')-5 b(re)31 b(e)o(xpecting)f(wires)g(to)h(run.)48 b(If)31 b(you)f(place)h(cells)0 3047 y(too)d(close)g(together)l(,)g(there)h(may)f(not)g(be)g(enough)g (room)f(to)h(ha)n(v)o(e)g(a)h(channel)f(between)g(the)g(cells;)i(when)e (this)0 3168 y(happens)33 b(Magic)g(will)f(route)h(willy-nilly)e (across)i(the)g(tops)f(of)i(cells)f(to)f(bring)h(terminals)f(out)h(to)g (channels,)0 3288 y(and)28 b(will)f(probably)h(generate)h(shorts)e(or)h (design-rule)g(violations.)39 b(T)-8 b(o)28 b(solv)o(e)f(the)h (problem,)g(mo)o(v)o(e)e(the)i(cells)0 3409 y(f)o(arther)g(apart.)38 b(If)28 b(there)f(are)h(man)o(y)e(skinn)o(y)g(channels,)h(it)g(will)f (be)i(dif)n(\002cult)e(for)h(the)g(router)h(to)f(produce)g(good)0 3529 y(routing.)i(T)m(ry)24 b(to)g(re-arrange)h(the)f(cell)g(structure) g(to)g(line)g(up)g(edges)g(of)g(nearby)g(cells)g(so)g(that)g(there)g (are)h(as)f(fe)n(w)0 3649 y(channels)31 b(as)g(possible)e(and)i(the)o (y)f(are)i(as)f(lar)n(ge)g(as)g(possible)f(\(before)i(doing)e(this)g (you')o(ll)g(probably)g(w)o(ant)g(to)0 3770 y(get)25 b(rid)f(of)h(the)g(e)o(xisting)e(routing)g(by)i(undo-ing)f(or)h(by)f (\003ushing)g(the)h(edit)f(cell\).)0 4113 y Fd(8.2)119 b(Stems)0 4317 y Fe(Another)30 b(problem)g(has)h(to)f(do)g(with)g(the)h (stem)f(generator)-5 b(.)48 b(Stems)30 b(are)i(the)e(pieces)h(of)g (wiring)f(that)g(connect)0 4437 y(terminals)i(up)h(to)f(grid)h(points)e (on)i(the)g(edges)g(of)g(channels.)54 b(The)33 b(current)h(stem)e (generation)g(code)h(doesn')n(t)0 4557 y(kno)n(w)c(about)g(connecti)n (vity)f(or)i(design)f(rules.)46 b(It)30 b(simply)e(\002nds)i(the)f (nearest)h(routing)f(grid)h(point)e(and)i(wires)0 4678 y(out)f(to)g(that)h(point,)f(without)g(considering)f(an)o(y)h(other)h (terminals.)44 b(If)30 b(a)g(terminal)f(is)h(not)f(on)g(the)h(edge)f (of)h(the)0 4798 y(cell,)37 b(the)d(stem)f(runs)h(straight)f(across)i (the)f(cell)g(to)g(the)g(nearest)h(channel,)h(without)d(an)o(y)h (consideration)f(for)0 4918 y(other)26 b(material)f(in)g(the)h(cell.)33 b(If)26 b(tw)o(o)f(terminals)g(are)h(too)f(close)h(together)l(,)f (Magic)h(may)f(decide)h(to)f(route)h(them)0 5039 y(both)i(to)g(the)h (same)f(grid)h(point.)41 b(When)29 b(this)e(happens,)i(you)g(ha)n(v)o (e)f(tw)o(o)g(choices.)43 b(Either)28 b(you)g(can)h(mo)o(v)o(e)e(the)0 5159 y(cell)e(so)g(that)f(the)h(terminals)f(ha)n(v)o(e)h(dif)n(ferent)f (nearest)i(grid)e(points)g(\(for)h(e)o(xample,)f(you)h(can)g(line)g (its)f(terminals)0 5280 y(up)h(with)f(the)g(grid)h(lines\),)f(or)h(if)g (this)f(doesn')n(t)g(w)o(ork)h(you')o(ll)f(ha)n(v)o(e)g(to)h(modify)f (the)g(cell)h(to)g(mak)o(e)f(the)h(terminals)0 5400 y(f)o(arther)g (apart.)1850 5649 y(\22611\226)p eop %%Page: 12 12 12 11 bop 0 -180 a Fe(April)24 b(12,)h(2006)1717 b(Magic)24 b(T)l(utorial)g(#7:)30 b(Netlists)23 b(and)i(Routing)146 68 y(The)f(place)h(where)f(stems)f(cause)i(the)e(most)g(trouble)h(is)f (in)h(PLAs,)g(man)o(y)f(of)h(which)g(ha)n(v)o(e)f(been)h(optimized)0 188 y(to)j(space)h(the)g(outputs)e(as)i(closely)f(together)g(as)g (possible.)38 b(In)28 b(some)f(cases)h(the)f(outputs)g(are)h(closer)g (together)0 309 y(than)35 b(the)g(routing)e(grid,)38 b(which)c(is)h(an)g(impossible)e(situation)g(for)i(the)g(stem)g (generator)-5 b(.)61 b(In)35 b(this)f(case,)k(we)0 429 y(think)28 b(the)h(best)g(approach)g(is)g(to)g(change)h(the)f(PLA)g (templates)f(to)h(space)h(the)f(outputs)f(f)o(arther)h(apart.)45 b(Either)0 549 y(space)33 b(them)g(e)o(xactly)f(the)h(same)g(as)h(the)f (router)g(grid)f(\(in)h(which)g(case)h(you)e(can)i(line)f(the)g(PLAs)g (up)g(before)0 670 y(routing)28 b(so)h(the)f(terminals)g(are)i(already) f(on)g(the)g(grid\),)g(or)h(space)f(the)g(outputs)e(at)i(least)g(1.5)f (grid)h(units)f(apart)0 790 y(so)g(the)g(stem)g(generator)g(w)o(on')n (t)g(ha)n(v)o(e)g(troubles.)40 b(Ha)n(ving)28 b(tightly-spaced)f(PLA)h (outputs)f(is)h(f)o(alse)g(economy:)0 911 y(it)c(mak)o(es)g(it)g(more)g (dif)n(\002cult)g(to)g(design)f(the)h(PLAs)h(and)f(results)g(in)g(a)o (wful)g(routing)f(problems.)29 b(Ev)o(en)24 b(if)g(Magic)0 1031 y(could)k(ri)n(v)o(er)n(-route)g(out)g(from)g(tightly-spaced)f (terminals)h(to)g(grid)g(lines)g(\(which)h(it)f(can')n(t\),)i(it)e(w)o (ould)g(require)0 1151 y Fb(N)88 1115 y Fa(2)153 1151 y Fe(space)d(to)f(route)h(out)f Fb(N)36 b Fe(lines;)24 b(it)g(tak)o(es)g(less)h(area)h(to)e(stretch)h(the)f(PLA.)0 1441 y Fd(8.3)119 b(Obstacles)0 1629 y Fe(The)32 b(router)h(tends)f(to) g(ha)n(v)o(e)g(special)g(dif)n(\002culties)f(with)h(obstacles)g (running)f(along)h(the)h(edges)f(of)h(channels.)0 1749 y(When)27 b(you')-5 b(v)o(e)27 b(placed)g(a)g(po)n(wer)g(wire)h(or)f (other)g(hand-routing)f(along)g(the)h(edge)h(of)f(a)h(channel,)f(the)g (channel)0 1870 y(router)i(will)f(often)h(run)g(material)f(under)h (your)g(wiring)f(in)h(the)f(other)h(routing)f(layer)l(,)i(thereby)f (blocking)f(both)0 1990 y(routing)38 b(layers)h(and)g(making)f(it)g (impossible)f(to)i(complete)f(the)h(routing.)72 b(Where)40 b(this)e(occurs,)k(you)d(can)0 2110 y(increase)f(the)f(chances)g(of)g (successful)g(routing)f(by)h(mo)o(ving)e(the)i(hand-routing)f(a)o(w)o (ay)h(from)g(the)g(channel)0 2231 y(edges.)55 b(It')-5 b(s)32 b(especially)g(important)g(to)g(k)o(eep)h(hand-routing)f(a)o(w)o (ay)h(from)f(terminals.)54 b(The)33 b(stem)f(generator)0 2351 y(will)24 b(not)h(pay)g(an)o(y)f(attention)g(to)h(hand-routing)e (when)i(it)g(generates)g(stems)f(\(it)h(just)f(mak)o(es)h(a)g(bee-line) g(for)g(the)0 2471 y(nearest)g(grid)f(point\),)g(so)h(it)f(may)g (accidentally)h(short)f(a)h(terminal)f(to)g(nearby)h(hand-routing.)1170 4150 y @beginspecial 68 @llx 68 @lly 304 @urx 304 @ury 1872 @rwi @setspecial %%BeginDocument: ../psfigures/tut7.3.ps %!PS-Adobe-3.0 EPSF-3.0 %%Title: ../psfiles/tut7.3.ps %%Creator: Xcircuit v2.0 %%CreationDate: Fri Apr 14 13:21:10 2000 %%Pages: 1 %%BoundingBox: 68 68 304 304 %%DocumentNeededResources: %%EndComments %%BeginProlog % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % %%BeginResource: procset XCIRCproc 2.0 2 % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def %%EndResource %%EndProlog % XCircuit output starts here. /mgrid { % -304 -304 608 608 bbox begingate 1 1.00 -256 304 -256 -304 2 polygon 1 1.00 -128 304 -128 -304 2 polygon 1 1.00 -304 224 304 224 2 polygon 1 1.00 -304 64 304 64 2 polygon 1 1.00 0 304 0 -304 2 polygon 1 1.00 256 304 256 -304 2 polygon 1 1.00 128 304 128 -304 2 polygon 1 1.00 -304 -256 304 -256 2 polygon 1 1.00 -304 -96 304 -96 2 polygon endgate } def %%Page: 1 1 %%PageOrientation: Portrait /pgsave save def bop % 848 560 offsets 1.0000 inchscale 2.6000 setlinewidth 0.490 0.651 0.980 scb 240 1.00 240 400 688 400 688 768 624 768 624 464 240 464 6 polygon sce 0.745 0.600 0.871 scb 240 1.00 496 224 496 384 560 384 560 224 4 polygon sce 0 1.00 496 224 496 384 560 384 560 224 4 polygon 0 1.00 240 400 688 400 688 768 624 768 624 464 240 464 6 polygon 0.616 0.624 0.925 scb 240 1.00 480 384 480 480 576 480 576 384 4 polygon sce 0 1.00 480 384 480 480 576 480 576 384 4 polygon 1 1.00 480 480 576 384 2 polygon 1 1.00 576 480 480 384 2 polygon 0.800 0.800 0.800 scb 1.00 0 496 496 mgrid sce pgsave restore showpage %%Trailer XCIRCsave restore %%EOF %%EndDocument @endspecial 0 4353 a(Figure)34 b(3:)48 b(When)34 b(placing)f(hand)h (routing,)h(it)e(is)g(best)h(to)f(place)h(wires)g(with)f(their)g(left)h (and)g(bottom)e(edges)0 4473 y(along)24 b(grid)h(lines,)f(and)g (contacts)h(centered)g(on)f(the)h(wires.)30 b(In)25 b(this)f(f)o (ashion,)g(the)h(hand)f(routing)g(will)g(block)g(as)0 4594 y(fe)n(w)h(routing)e(grid)i(lines)f(as)h(possible.)146 4918 y(When)33 b(placing)f(hand-routing,)h(you)f(can)h(get)g(better)f (routing)g(results)g(by)g(follo)n(wing)f(the)h(advice)h(illus-)0 5039 y(trated)28 b(in)f(Figure)h(3.)40 b(First,)28 b(display)f(the)g (routing)g(grid.)39 b(F)o(or)28 b(e)o(xample,)f(if)h(the)g(router)f(is) h(using)f(a)h(8-unit)f(grid)0 5159 y(\(which)21 b(is)g(true)g(for)h (the)f(standard)g(SCMOS)i(technology\),)e(type)g Fc(:grid)g(8)p Fe(.)30 b(Then)21 b(place)h(all)f(your)g(hand)g(routing)0 5280 y(with)j(its)f(left)i(and)f(bottom)f(edges)i(along)f(the)g(grid)g (lines.)30 b(Because)25 b(of)g(the)f(w)o(ay)h(the)f(routing)f(tools)h (w)o(ork,)g(this)0 5400 y(approach)h(results)f(in)g(the)h(least)g (possible)e(amount)h(of)h(lost)f(routing)f(space.)1850 5649 y(\22612\226)p eop %%Page: 13 13 13 12 bop 0 -180 a Fe(Magic)24 b(T)l(utorial)g(#7:)30 b(Netlists)23 b(and)i(Routing)1717 b(April)24 b(12,)h(2006)0 99 y Fg(9)143 b(Mor)m(e)36 b(Netlist)e(Commands)0 322 y Fe(In)22 b(addition)e(to)i(the)g(netlist)e(menu)i(b)n(uttons)e(and)i (commands)e(described)i(in)g(Section)f(4,)i(there)f(are)g(a)h(number)e (of)0 443 y(other)k(netlist)f(commands)f(you)i(can)g(in)l(v)n(ok)o(e)g (by)g(typing)e(in)i(the)g(netlist)f(windo)n(w)-6 b(.)29 b(Man)o(y)24 b(of)h(these)g(commands)0 563 y(are)33 b(te)o(xtual)e (equi)n(v)n(alents)f(of)j(the)f(menu)g(b)n(uttons.)51 b(Ho)n(we)n(v)o(er)l(,)33 b(the)o(y)e(allo)n(w)h(you)f(to)h(deal)h (with)e(terminals)g(by)0 683 y(typing)23 b(the)h(hierarchical)h(name)f (of)g(the)g(terminal)g(rather)h(than)e(by)h(pointing)f(to)h(it.)30 b(If)25 b(you)e(don')n(t)h(kno)n(w)g(where)0 804 y(a)32 b(terminal)e(is,)j(or)e(if)g(you)g(ha)n(v)o(e)g(deleted)h(a)f(label)h (from)f(your)g(design)f(so)h(that)g(there')-5 b(s)31 b(nothing)f(to)h(point)g(to,)0 924 y(you')o(ll)g(ha)n(v)o(e)g(to)g(use) h(the)g(te)o(xtual)e(commands.)50 b(Commands)31 b(that)g(don')n(t)g (just)g(duplicate)g(menu)g(b)n(uttons)f(are)0 1045 y(described)25 b(belo)n(w;)e(see)i(the)g Ff(ma)o(gic\(1\))g Fe(manual)f(page)h(for)g (details)f(on)g(the)h(others.)146 1165 y(The)g(netlist)f(command)900 1393 y Fc(:extract)146 1622 y Fe(will)f(generate)h(a)g(net)g(from)f(e)o (xisting)f(wiring.)30 b(It)23 b(looks)g(under)h(the)f(box)g(for)h (paint,)f(then)h(traces)g(out)f(all)g(the)0 1742 y(material)k(in)g(the) h(edit)f(cell)g(that)g(is)g(connected)h(electrically)f(to)g(that)g (paint.)39 b(Where)n(v)o(er)27 b(the)h(material)f(touches)0 1862 y(subcells)i(it)h(looks)f(for)h(terminals)g(in)f(the)h(subcells,)h (and)f(all)g(the)g(terminals)f(it)h(\002nds)g(are)g(placed)h(into)e(a)i (ne)n(w)0 1983 y(net.)f(W)-8 b(arning:)29 b(there)22 b(is)g(also)f(an)i Fc(extract)g Fe(command)e(for)h(layout)f(windo)n (ws,)g(and)h(it)g(is)g(totally)f(dif)n(ferent)g(from)0 2103 y(the)j Fc(extract)g Fe(command)f(in)h(netlist)e(windo)n(ws.)29 b(Mak)o(e)24 b(sure)f(you')-5 b(v)o(e)24 b(got)f(the)g(cursor)h(o)o(v)o (er)f(the)h(netlist)e(windo)n(w)0 2224 y(when)j(you)f(in)l(v)n(ok)o(e)g (this)g(command!)146 2344 y(The)30 b(netlist)f(editor)g(pro)o(vides)g (tw)o(o)g(commands)g(for)h(ripping)f(up)h(e)o(xisting)e(routing)h(\(or) h(other)f(material\).)0 2464 y(The)o(y)24 b(are)900 2693 y Fc(:ripup)900 2813 y(:ripup)i(netlist)146 3041 y Fe(The)31 b(\002rst)f(command)g(starts)g(by)g(\002nding)g(an)o(y)g(paint)g(in)g (the)g(edit)g(cell)g(that)g(lies)g(underneath)h(the)f(box.)47 b(It)0 3162 y(then)25 b(w)o(orks)g(outw)o(ard)f(from)h(that)g(paint)f (to)h(\002nd)g(all)g(paint)g(in)f(the)h(edit)g(cell)g(that)g(is)g (electrically)f(connected)h(to)0 3282 y(the)j(starting)g(paint.)42 b(All)28 b(of)g(this)g(paint)g(is)g(erased.)43 b(\()p Fc(:ripup)30 b Fe(isn')n(t)e(really)h(necessary)-6 b(,)29 b(since)g(the)f(same)h(ef)n(fect)0 3402 y(can)24 b(be)g(achie)n(v)o(ed) e(by)i(selecting)e(all)i(the)f(paint)g(in)g(the)h(net)f(and)h(deleting) e(the)i(selection;)f(it')-5 b(s)22 b(a)i(hango)o(v)o(er)e(from)0 3523 y(olden)34 b(days)g(when)g(there)g(w)o(as)h(no)f(selection\).)58 b(The)34 b(second)g(form)g(of)h(the)f(command,)h Fc(:ripup)h(netlist)p Fe(,)h(is)0 3643 y(similar)30 b(to)g(the)g(\002rst)h(e)o(xcept)f(that)g (it)h(starts)f(from)g(each)h(of)g(the)g(terminals)e(in)h(the)h(current) g(netlist)e(instead)h(of)0 3764 y(the)24 b(box.)30 b(An)o(y)24 b(paint)g(in)g(the)g(edit)g(cell)g(that)g(is)g(electrically)g (connected)h(to)f(a)h(terminal)e(is)h(erased.)31 b(The)25 b Fc(:ripup)0 3884 y(netlist)g Fe(command)f(may)g(be)h(useful)g(to)f (ripup)g(e)o(xisting)f(routing)h(before)h(rerouting.)146 4004 y(The)g(command)900 4233 y Fc(:trace)h Fe([)p Ff(name)p Fe(])146 4461 y(pro)o(vides)f(an)h(additional)e(f)o(acility)h(for)h(e)o (xamining)e(router)i(feedback.)34 b(It)26 b(highlights)d(all)j(paint)f (connected)0 4581 y(to)30 b(each)h(terminal)e(in)h(the)h(net)f (containing)f Ff(name)p Fe(,)i(much)f(as)h(the)f Fc(Sho)o(w)h Fe(menu)f(b)n(utton)f(does)h(for)g(paint)g(con-)0 4702 y(nected)25 b(to)f(an)o(ything)f(under)h(the)h(box.)30 b(The)25 b(net)f(to)g(be)h(highlighted)e(may)h(be)h(speci\002ed)g(by)f (naming)g(one)g(of)h(its)0 4822 y(terminals,)e(for)g(e)o(xample,)g Fc(:trace)i(shifter/bit[0]/phi1)p Fe(.)31 b(Use)23 b(the)h(trace)g (command)e(in)h(conjunction)g(with)f(the)0 4943 y(nets)29 b(speci\002ed)h(in)f(router)g(feedback)h(to)f(see)h(the)f(partially)f (completed)h(wiring)g(for)g(a)h(net.)44 b(Where)30 b(no)f(net)h(is)0 5063 y(speci\002ed,)25 b(the)g Fc(:trace)g Fe(command)f(highlights)f (the)h(currently)h(selected)g(net.)1850 5649 y(\22613\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tutscm4.ps0000644000175000001440000002434010751423606015642 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: tutscm4.dvi %%Pages: 1 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips tutscm4.dvi -o tutscm4.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Bold % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tutscm4.dvi) @start /Fa 138[66 40 47 53 2[60 66 100 33 2[33 66 2[53 66 53 1[60 12[80 6[113 9[86 8[40 55[66 2[{ TeXBase1Encoding ReEncodeFont }19 119.999948 /Times-Bold rf /Fb 105[50 28[50 2[50 50 28 39 33 1[50 50 50 78 28 2[28 50 50 33 44 50 44 1[44 12[61 55 2[55 2[89 3[33 4[72 66 1[72 6[28 50 1[50 1[50 2[50 50 2[25 33 25 8[50 35[{ TeXBase1Encoding ReEncodeFont }38 100.000003 /Times-Roman rf /Fc 139[28 1[39 2[50 50 3[28 28 50 2[44 3[50 14[61 3[66 83 35[33 33 40[{ TeXBase1Encoding ReEncodeFont }14 100.000003 /Times-Italic rf /Fd 138[80 48 56 64 2[72 80 1[40 2[40 80 72 1[64 80 64 1[72 12[96 80 5[135 3[56 14[48 5[72 2[72 3[48 9[72 32[80 2[{ TeXBase1Encoding ReEncodeFont }24 143.999997 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 709 101 a Fd(Magic)35 b(T)-13 b(utorial)34 b(#S-4:)43 b(The)35 b(design)g(rule)g(\002le)1655 521 y Fc(Rajit)24 b(Manohar)1296 941 y Fb(Deparment)g(of)h(Computer)g(Science)1271 1062 y(California)g(Institute)f(of)h(T)-7 b(echnology)1534 1182 y(P)o(asadena,)25 b(CA)h(91125)1053 1453 y(This)e(tutorial)g (corresponds)g(to)g(Magic)h(v)o(ersion)e(7.)0 1981 y Fa(T)-11 b(utorials)30 b(to)f(r)n(ead)h(\002rst:)300 2184 y Fb(Magic)24 b(T)l(utorial)g(#S-1:)31 b(The)24 b(scheme)h(command-line)f(interpreter)0 2388 y Fa(Commands)29 b(intr)n(oduced)j(in)f(this)f(tutorial:)300 2591 y Fb(:drc.)0 2795 y Fa(Macr)n(os)f(intr)n(oduced)i(in)g(this)f(tutorial:)300 3023 y Fc(\(None\))0 3620 y Fd(1)143 b(Intr)m(oduction)1875 5649 y Fb(\2261\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/maint1.ps0000644000175000001440000022667110751423606015443 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: maint1.dvi %%Pages: 17 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman Courier %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips maint1.dvi -o maint1.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Bold % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (maint1.dvi) @start /Fa 3 104 df<0001FF0000000FFFE000003FFFF800007FFFFC0001FFFFFF0003 FFFFFF8007FFFFFFC00FFFFFFFE01FFFFFFFF01FFFFFFFF03FFFFFFFF87FFFFFFFFC7FFF FFFFFC7FFFFFFFFCFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFF FFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFE7FFFFFFFFC7FFFFFFFFC7FFFFFFF FC3FFFFFFFF81FFFFFFFF01FFFFFFFF00FFFFFFFE007FFFFFFC003FFFFFF8001FFFFFF00 007FFFFC00003FFFF800000FFFE0000001FF000027267BAB32>15 D<0000000FE0000000FFE0000003FC0000000FE00000003FC00000007F80000000FF0000 0000FE00000001FC00000001FC00000003F800000003F800000003F800000003F8000000 03F800000003F800000003F800000003F800000003F800000003F800000003F800000003 F800000003F800000003F800000003F800000003F800000003F800000003F800000003F8 00000003F800000003F800000003F800000003F800000003F800000003F800000003F800 000003F800000003F800000003F800000003F800000003F800000007F000000007F00000 000FE00000001FE00000003FC00000007F80000000FE00000007F8000000FFE0000000FF E000000007F800000000FE000000007F800000003FC00000001FE00000000FE000000007 F000000007F000000003F800000003F800000003F800000003F800000003F800000003F8 00000003F800000003F800000003F800000003F800000003F800000003F800000003F800 000003F800000003F800000003F800000003F800000003F800000003F800000003F80000 0003F800000003F800000003F800000003F800000003F800000003F800000003F8000000 03F800000003F800000003F800000003F800000001FC00000001FC00000000FE00000000 FF000000007F800000003FC00000000FE000000003FC00000000FFE00000000FE0236479 CA32>102 DI E /Fb 1 61 df<00000000000001C000000000000007E000000000 00001FE00000000000007FC0000000000001FF00000000000007FC0000000000001FF000 00000000007FC0000000000001FF0000000000000FFC0000000000003FF0000000000000 FFC0000000000003FF0000000000000FF80000000000003FE0000000000000FF80000000 000003FE0000000000001FF80000000000007FE0000000000001FF80000000000007FE00 00000000001FF00000000000007FC0000000000001FF00000000000007FC000000000000 1FF00000000000007FC0000000000000FF00000000000000FF000000000000007FC00000 000000001FF000000000000007FC00000000000001FF000000000000007FC00000000000 001FF000000000000007FE00000000000001FF800000000000007FE00000000000001FF8 00000000000003FE00000000000000FF800000000000003FE00000000000000FF8000000 00000003FF00000000000000FFC00000000000003FF00000000000000FFC000000000000 01FF000000000000007FC00000000000001FF000000000000007FC00000000000001FF00 0000000000007FC00000000000001FE000000000000007E000000000000001C03B3878B4 4C>60 D E /Fc 137[60 60 1[60 60 2[60 60 60 60 60 1[60 60 60 1[60 60 60 1[60 13[60 6[60 4[60 60 2[60 1[60 60 16[60 60 60 45[{ TeXBase1Encoding ReEncodeFont }26 100.000003 /Courier rf /Fd 103[33 29[44 50 50 72 50 55 33 39 44 1[55 50 55 83 28 55 1[28 55 50 33 44 55 44 55 50 7[72 72 100 72 72 66 55 72 1[61 78 72 94 66 2[39 78 78 61 66 72 72 66 72 1[50 4[33 1[50 50 50 1[50 1[50 50 50 28 25 33 2[50 33 33 3[50 32[55 55 2[{ TeXBase1Encoding ReEncodeFont }65 100.000003 /Times-Bold rf /Fe 134[60 2[60 66 40 47 53 1[66 60 66 100 33 2[33 66 60 40 53 66 53 66 60 12[80 66 3[93 1[113 3[47 1[93 73 1[86 86 8[40 1[60 60 2[60 60 60 60 1[33 30 40 42[66 2[{ TeXBase1Encoding ReEncodeFont }40 119.999948 /Times-Bold rf /Ff 103[33 100 50 1[44 44 24[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 6[61 72 72 94 72 72 61 55 66 1[55 72 72 89 61 1[39 33 72 72 55 61 72 66 66 72 92 4[28 28 50 50 50 50 50 50 50 50 50 50 28 25 33 25 1[50 33 33 33 3[50 31[55 55 2[{ TeXBase1Encoding ReEncodeFont }79 100.000003 /Times-Roman rf /Fg 133[39 44 44 66 44 50 28 39 39 1[50 50 50 72 28 2[28 50 50 28 44 50 44 1[50 8[61 83 61 1[55 50 3[72 66 1[55 1[44 33 72 2[61 72 66 1[61 7[50 50 50 1[50 50 2[50 3[33 3[33 33 36[50 3[{ TeXBase1Encoding ReEncodeFont }47 100.000003 /Times-Italic rf /Fh 133[64 72 1[104 72 80 48 56 64 1[80 72 80 120 40 2[40 80 72 48 64 80 64 80 72 9[143 2[96 80 2[88 112 104 135 96 2[56 1[112 88 1[104 104 1[104 6[48 72 72 72 72 72 72 72 72 72 72 2[48 5[48 3[72 35[{ TeXBase1Encoding ReEncodeFont } 50 143.999997 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 49 101 a Fh(Magic)36 b(Maintainer')-5 b(s)33 b(Manual)i(#1:)44 b(Installation)33 b(and)i(De)n(v)o(elopment)1618 521 y Fg(J)n(ohn)24 b(Ousterhout)1707 641 y(W)-9 b(alter)24 b(Scott)1401 1062 y Ff(Computer)g(Science)i(Di)n(vision)1020 1182 y(Electrical)f(Engineering)f(and)h(Computer)f(Sciences)1473 1303 y(Uni)n(v)o(ersity)f(of)i(California)1544 1423 y(Berk)o(ele)o(y)-6 b(,)24 b(CA)h(94720)1687 1693 y Fg(T)-5 b(im)25 b(Edwar)l(ds)863 1814 y Ff(Johns)f(Hopkins)g(Uni)n(v)o(ersity)e(Applied)i(Physics)g (Laboratory)1578 1934 y(Laurel,)h(MD)f(20723)1053 2205 y(This)g(tutorial)g(corresponds)g(to)g(Magic)h(v)o(ersion)e(7.)0 2736 y Fe(T)-11 b(utorials)30 b(to)f(r)n(ead)h(\002rst:)300 2942 y Ff(All)24 b(of)h(them.)0 3147 y Fe(Commands)k(intr)n(oduced)j (in)f(this)f(tutorial:)300 3353 y Ff(:*pro\002le,)24 b(:*runstats,)g(:*see\003ags,)g(:*w)o(atch)0 3559 y Fe(Macr)n(os)29 b(intr)n(oduced)i(in)g(this)f(tutorial:)300 3791 y Fg(\(None\))0 4694 y Fh(1)143 b(Intr)m(oduction)0 4918 y Ff(This)39 b(document)g(pro)o(vides)f(some)h(information)g(to)g(help)g(system)g (administrators)f(and)h(w)o(ould-be)g(Magic)0 5039 y(maintainers)28 b(learn)i(about)e(the)h(system.)43 b(Before)30 b(doing)f(an)o(ything)e (to)i(the)g(internals)f(of)i(Magic,)g(you)e(should)0 5159 y(read)k(at)g(least)g(the)g(\002rst,)h(and)f(perhaps)g(all)f(four) l(,)j(of)e(the)f(papers)h(on)g(Magic)g(that)f(appeared)h(together)g(in) f(the)0 5280 y Fg(1984)25 b(Design)g(A)n(utomation)f(Confer)l(ence)p Ff(.)34 b(In)26 b(addition,)f(the)g(follo)n(wing)f(portions)h(of)h (magic)f(ha)n(v)o(e)g(their)h(o)n(wn)0 5400 y(papers:)1875 5649 y(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Ff(September)25 b(26,)f(2001)630 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#1:)30 b(Installation)23 b(and)i(De)n(v)o(elopment)300 84 y Fd(extractor)729 b Fg(1985)25 b(Design)f(A)n(utomation)f(Confer)l(ence)p Ff(,)i(page)g(286.)300 205 y Fd(channel)h(r)n(outer)496 b Fg(1985)25 b(Chapel)f(Hill)g(Confer)l(ence)i(on)e(VLSI)p Ff(,)h(page)g(145.)300 325 y Fd(ir)n(outer)h(and)f(mzr)n(outer)219 b Fg(1988)25 b(Design)f(A)n(utomation)f(Confer)l(ence)p Ff(,)i(page)g(672.)300 445 y Fd(r)n(esistance)h(extractor)285 b Fg(1987)25 b(Design)f(A)n(utomation)f(Confer)l(ence)p Ff(,)i(page)g(570.)0 797 y Fh(2)143 b(Compiling)34 b(and)h(Installing)f (Magic)0 1024 y Ff(If)h(you')-5 b(v)o(e)33 b(do)n(wnloaded)g(Magic)h (via)g(FTP)-11 b(,)35 b(then)f(it)g(shouldn')n(t)f(tak)o(e)h(much)g(w)o (ork)g(to)g(get)g(it)g(running.)58 b(Y)-11 b(ou)0 1144 y(should)36 b(\002rst)i(pick)e(a)i(location)e(for)i(Magic')-5 b(s)36 b(directory)h(tree.)69 b(Normally)36 b(\230cad)i(is)f(chosen,)j (meaning)d(that)0 1265 y(\223cad\224)30 b(is)f(a)h(username)f(on)g(the) g(system)g(with)f(a)i(home)f(directory)g(typically)f(something)g(lik)o (e)h(/home/cad/)f(or)0 1385 y(/usr/local/cad/,)g(b)n(ut)f(you)h(might)f (w)o(ant)h(to)g(pick)g(some)f(other)h(location)g(to)f(start,)i (particularly)f(if)g(you)g(do)g(not)0 1505 y(ha)n(v)o(e)33 b(root)f(pri)n(vile)o(ge)g(to)g(create)i(or)f(write)g(into)f(the)h (\230cad)h(directory)-6 b(.)54 b(If)34 b(you)e(choose)h(a)g(dif)n (ferent)g(location,)0 1626 y(set)28 b(your)f(shell)g(en)l(vironment)g (v)n(ariable)g Fd(CAD)p 1661 1626 30 4 v 35 w(HOME)h Ff(to)f(that)g(location)g(and)h(mentally)f(translate)g(the)h(\230cad)0 1746 y(references)e(in)f(this)e(document)h(to)h(the)f(location)g(you)h (chose.)146 1868 y(The)j(do)n(wnload)e(\002le)h(comes)g(in)g(tarred,)h (gzipped)f(format.)38 b(F)o(ollo)n(w)26 b(the)h(standard)g(procedure)h (to)f(uncom-)0 1989 y(press)e(and)f(e)o(xpand:)900 2232 y(tar)h(xzf)g(magic-7.1.tar)-5 b(.gz)900 2352 y(cd)25 b(magic-7.1)146 2593 y(F)o(ollo)n(wed)f(by)900 2836 y(mak)o(e)h (con\002g)146 3077 y(The)32 b(\002rst)f(prompt)g(asks)g(for)h (selection)e(of)i(the)f(graphics)g(interf)o(ace\(s\).)51 b(Magic)32 b(is)f(designed)f(to)h(link)g(its)0 3197 y(generic)24 b(graphics)f(calls)g(to)g(speci\002c)h(dri)n(v)o(er)e(calls)h(at)h (runtime,)e(so)h(an)o(y)g(combination)f(of)h(choices)h(is)f(possible.)0 3318 y(Choose)32 b(more)h(than)f(one)g(option)g(with)f(a)i (space-separated)g(list)f(of)h(option)e(numbers)g(at)i(the)f(prompt.)53 b(The)0 3438 y(choices)25 b(are)g(as)g(follo)n(ws:)120 3679 y(1.)49 b Fd(X11)36 b Ff(for)h(all)f(v)o(ersions)f(of)i(X11)f (\(currently)g(X11R6)g(is)g(standard\).)66 b(Se)n(v)o(eral)36 b(other)h(magic)f(options)244 3799 y(mak)o(e)27 b(use)h(of)f(X11)g (calls,)h(such)f(as)h(the)f(e)o(xtended)g(macro)g(package,)i(which)e (uses)g(the)g(X)h(serv)o(er')-5 b(s)27 b(k)o(e)o(y)244 3920 y(symbol)c(lookup)g(to)i(allo)n(w)e(macro)i(de\002nitions)e(on)i (function)e(and)i(k)o(e)o(ypad)f(k)o(e)o(ys,)g(so)g(the)g(X11)h (package)244 4040 y(is)f(preferred.)120 4253 y(2.)49 b Fd(OpenGL)42 b Ff(for)f(systems)f(ha)n(ving)h(OpenGL)g(capability)f (under)i(X11.)80 b(Generally)-6 b(,)44 b(this)d(applies)f(to)244 4373 y(SGI)c(hardw)o(are,)i(and)d(Linux)f(systems)g(with)h(accelerated) h(3D)f(video)g(hardw)o(are)g(implementing)e(the)244 4493 y(OpenGL)39 b(API,)h(and)f(an)h(OpenGL-capable)f(accelerated)i(X)e (serv)o(er)-5 b(.)74 b(This)39 b(option)f(is)h Fg(not)g Ff(recom-)244 4614 y(mended)29 b(for)h(non-hardw)o(are-accelerated)h (\(i.e.,)f(softw)o(are-implemented\))e(OpenGL)i(or)f(compatible)244 4734 y(\(e.g.,)d(Mesa\))g(serv)o(ers,)f(because)i(the)e(interf)o(ace)i (mak)o(es)e(hea)n(vy)h(use)g(of)f(color)h(blending,)f(implemented)244 4855 y(in)f(softw)o(are)h(by)g(dreadfully)f(slo)n(w)g(\003ood)g (\002lls.)120 5067 y(3.)49 b Fd(SunV)l(iew)30 b Ff(for)e(Sun)h(W)-8 b(orkstations.)40 b(This)28 b(option)f(is)h(rather)h(out)f(of)h(date,)g (because)g(although)e(Solaris)244 5188 y(still)c(supports)h(SunV)-6 b(ie)n(w)g(,)24 b(it)g(also)g(supports)g(the)g(superior)h(X11)f (protocol.)120 5400 y(4.)49 b Fd(X10)24 b Ff(is)h(le)o(gac)o(y)e(code)i (for)g(support)f(of)h(X10,)f(the)h(precursor)g(of)g(X11.)1875 5649 y(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Ff(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#1:)30 b(Installation)24 b(and)g(De)n(v)o(elopment)628 b(September)25 b(26,)g(2001)120 69 y(5.)49 b Fd(AED)21 b(graphics)g(terminals)f Ff(is)h(le)o(gac)o(y)e(code)i(for)f(support)g (of)h(ancient)f(serial-line)g(graphics)g(terminals.)244 189 y(The)o(y)k(were)h(great)h(machines,)e(once)h(long)f(ago)g(\(see)i (Appendix)e(A\).)146 427 y(The)f(ne)o(xt)e(prompt)g(asks)h(for)h(the)f (tar)n(get)g(operating)g(system.)28 b(Most)22 b(modern)f(UNIX)i(types)e (are)i(supported,)0 547 y(and)35 b(an)o(y)f(others)g(usually)g(f)o(all) g(under)h(the)g(cate)o(gory)f(of)h(BSD-)g(or)g(SYSV)-10 b(-compatible.)60 b(At)35 b(w)o(orst,)h(an)f(un-)0 667 y(supported)27 b(system)h(may)g(require)g(tweaking)g(the)g(compiler)g (\003ags,)h(which)f(is)g(best)g(done)g(directly)g(to)g(the)g(\002le)0 788 y Fc(misc/CFLAGS)j Ff(after)i(running)f(\223mak)o(e)h (con\002g\224.)56 b(Magic)32 b(can)i(be)f(compiled)f(for)h(only)f(one)h (system)f(at)h(a)0 908 y(time.)d(Select)25 b(one)g(of)g(the)g(follo)n (wing)d(options:)120 1146 y(1.)49 b Fd(Linux)120 1356 y Ff(2.)g Fd(NetBSD)26 b(1.x)120 1566 y Ff(3.)49 b Fd(Fr)n(eeBSD)26 b(2.x)120 1776 y Ff(4.)49 b Fd(OSF/1)24 b Ff(for)h(64-bit)f(systems)f (such)i(as)g(the)g(Digital)e(Alpha)i(AXP)120 1986 y(5.)49 b Fd(Solaris)24 b(2.x)120 2196 y Ff(6.)49 b Fd(SunOS)26 b(4.x)e Ff(for)h(pre-Solaris)g(Suns.)120 2406 y(7.)49 b Fd(SGI)24 b(IRIX)h Ff(for)g(Silicon)f(Graphics)h(systems)e(before)i (SGI)h(mo)o(v)o(ed)d(to)h(the)h(Linux/68000)e(platform)120 2616 y(8.)49 b Fd(OS/2)24 b(W)-6 b(ar)o(p)25 b Ff(IBM')-5 b(s)24 b(much-too-late)g(attempt)g(to)g(o)o(v)o(erthro)n(w)f(the)i (Bill)f(Gates)h(empire)120 2826 y(9.)49 b Fd(BSD)26 b(Unix)e(systems)h Ff(for)g(Ultrix)f(and)g(v)n(arious)g(Berk)o(ele)o(y)h(BSD)h(4.3-based)e (systems.)71 3036 y(10.)48 b Fd(SYSV)28 b(Unix)f(systems)f Ff(for)i(HPUX,)f(Apple')-5 b(s)26 b(defunct)h(A/UX,)g(and)g(v)n(arious) f(other)g(System)h(V)-10 b(-based)244 3156 y(systems.)146 3393 y(The)36 b(third)f(prompt)g(asks)g(for)h(machine)f(architecture)h (for)g(an)o(y)f(machines)h(requiring)f(special)g(compile)0 3514 y(\003ags.)c(The)o(y)24 b(are)i(the)e(follo)n(wing:)120 3751 y(1.)49 b Fd(Intel)27 b(80x86-based)g(w)o(orkstations)h Ff(for)f(Intel)g(and)g(AMD)g(platforms)f(\(Linux,)h(NetBSD,)g(FreeBSD,) 244 3872 y(OS/2)e(W)-8 b(arp\))120 4082 y(2.)49 b Fd(HP)24 b(68000-based)h(w)o(orkstations)120 4292 y Ff(3.)49 b Fd(HP/P)-7 b(A-based)24 b(w)o(orkstations)120 4502 y Ff(4.)49 b Fd(MIPS)25 b(w)o(orkstation)g Ff(\(RISCos4.0;)g(not)g (DECStations\))120 4712 y(5.)49 b Fd(An)25 b(A)n(pple)g(MacII)g Ff(\(A/UX\))120 4922 y(6.)49 b Fd(None)25 b(of)g(the)h(abo)o(v)o(e)f Ff(for)g(e)n(v)o(erything)e(else)i(\(Suns,)f(SGIs,)h(DECStations,)g (DEC)g(Alpha\))146 5159 y(The)42 b(\002nal)f(set)h(of)f(prompts)f (selects)h(v)n(arious)g(optional)f(modules.)79 b(On)41 b(modern)g(systems)f(with)h(v)n(ast)0 5280 y(amounts)d(of)i(memory)e (and)h(disk)g(space,)k(the)c(best)g(choice)h(is)f(to)f(use)i(all)f(of)g (them.)74 b(Systems)38 b(with)h(lo)n(w)0 5400 y(memory)24 b(o)o(v)o(erhead)g(\()p Fb(<)h Ff(128MB\))f(may)h(w)o(ant)g(to)f(a)n(v) n(oid)g(SCM)i(\(the)e(scheme)h(interpreter\).)1875 5649 y(\2263\226)p eop %%Page: 4 4 4 3 bop 0 -180 a Ff(September)25 b(26,)f(2001)630 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#1:)30 b(Installation)23 b(and)i(De)n(v)o(elopment)120 69 y(1.)49 b Fd(CALMA)p Ff(\227module)18 b(which)g(enables)h(reading)f(and)h(writing)f(GDS-II)i (\(otherwise)e(kno)n(wn)g(as)h(CALMA)244 189 y(or)25 b(\223streams\224\))g(format)f(\002les.)120 394 y(2.)49 b Fd(CIF)p Ff(\227module)29 b(which)h(enables)g(reading)h(and)f (writing)g(Caltech)h(Intermediate)f(F)o(ormat)g(\(CIF\))i(\002les.)244 514 y(Magic)f(only)g(kno)n(ws)f(ho)n(w)h(to)g(write)h(CIF)h(and)e (GDS-II,)i(so)e(at)h(least)f(one)h(of)f(these)h(tw)o(o)f(ought)g(to)g (be)244 635 y(selected.)120 840 y(3.)49 b Fd(PLO)l(T)p Ff(\227module)25 b(for)h(graphics)g(output.)33 b(Supports)25 b(PostScript,)h(direct)g(pix)o(el)f(output,)g(v)o(ersatec,)h(and)244 960 y(gremlin)e(formats.)120 1165 y(4.)49 b Fd(READLINE)p Ff(\227module)39 b(incorporating)g(the)h(GNU)h(\223readline\224)f (package)h(\(v)o(ersion)e(4.1\))h(into)f(the)244 1286 y(magic)24 b(command-line)g(interf)o(ace.)31 b(Readline)25 b(implements)e(command-line)g(history)h(and)h(editing.)120 1491 y(5.)49 b Fd(R)m(OUTE)p Ff(\227module)26 b(which)h(supports)f(v)n (arious)g(routing)h(tools)f(\(standard)h(router)l(,)h(interacti)n(v)o (e)e(router)l(,)244 1611 y(maze)f(router)l(,)g(channel)f(router)l(,)h (gate-array)g(router)l(,)g(and)g(global)f(router\).)120 1816 y(6.)49 b Fd(SCM)p Ff(\227module)26 b(implementing)g(the)h (\223scheme\224)h(command-line)e(interpreter)l(,)i(a)g(lisp-lik)o(e)e (program-)244 1936 y(ming)e(language)g(for)h(creating)g(ne)n(w)f (commands)g(and)h(procedures.)120 2142 y(7.)49 b Fd(SIM)p Ff(\227the)24 b(interacti)n(v)o(e)g(interf)o(ace)h(to)g(Stanford)g (irsim)e(\(rsim\))i(digital)e(switch)h(simulator)-5 b(.)120 2347 y(8.)49 b Fd(.magic)p Ff(\227Choice)25 b(of)g(using)g(either)g (the)g(old)g(or)h(the)f(ne)n(w)g(style)g(of)h(system)e(startup)h (\(.magic\))g(\002le.)33 b(The)244 2467 y(old)23 b(style)f(retains)h (compatibility;)e(the)i(ne)n(w)g(\002le)g(mak)o(es)g(use)g(of)h (interacti)n(v)o(e)d(macro)j(capability)-6 b(,)22 b(and,)h(if)244 2587 y(compiled)h(under)g(X11,)h(e)o(xtended)f(macro)h(capability)e (for)j(function,)d(cursor)l(,)i(and)g(k)o(e)o(ypad)f(k)o(e)o(ys.)146 2818 y(After)h(con\002guration,)g(compile)e(and)i(install)f(using)900 3049 y(mak)o(e)h(force)900 3169 y(mak)o(e)g(install)146 3400 y(The)h(remaining)f(sections)g(of)g(this)g(manual)g(deal)h(with)f (technical)h(issues)e(related)i(to)g(Magic)f(source)h(code)0 3520 y(and)f(its)f(de)n(v)o(elopment.)0 3862 y Fh(3)143 b(Sour)m(ce)35 b(Dir)m(ectory)f(Structur)m(e)0 4086 y Ff(There)h(are)h(49)e(source)h(subdirectories)f(in)g(Magic.)61 b(Most)33 b(of)i(these)g(consist)f(of)h(modules)e(of)i(source)g(code)0 4206 y(for)30 b(the)g(system,)f(for)i(e)o(xample)d Fd(database)p Ff(,)k Fd(main)p Ff(,)f(and)f Fd(utils)p Ff(.)45 b(See)31 b(Section)f(5)f(of)h(this)f(document)g(for)h(brief)0 4327 y(descriptions)d(of)i(what')-5 b(s)28 b(in)g(each)h(source)g (directory)-6 b(.)41 b(Besides)29 b(the)f(source)h(code,)g(the)g(other) f(subdirectories)0 4447 y(are:)145 4678 y Fa(\017)49 b Fd(doc)244 4798 y Ff(Contains)22 b(sources)g(for)h(all)f(the)g (documentation,)g(including)f Fg(man)h Ff(pages,)h(tutorials,)e(and)h (maintenance)244 4918 y(manuals.)71 b(Subdirectories)39 b(of)g Fd(doc)p Ff(,)j(e.g.)73 b Fd(doc/scmos)p Ff(,)41 b(contain)d(the)h(technology)f(manuals.)71 b(The)244 5039 y(Mak)o(e\002le)32 b(in)f(each)h(directory)g(can)g(be)g(used)f(to) h(run)f(of)n(f)h(the)f(documentation.)50 b(The)32 b(tutorials,)g(main-) 244 5159 y(tenance)f(manuals,)g(and)g(technology)f(manuals)g(all)h(use) f(LaT)-7 b(eX,)31 b(which)g(means)f(that)h(you)f(will)g(need)244 5280 y(the)c(LaT)-7 b(eX)27 b(package)g(to)f(recompile)g(the)g(manuals) g(from)g(source.)36 b(Documentation)25 b(is)h(also)g(a)n(v)n(ailable) 244 5400 y(online)e(in)g(HTML)g(format.)1875 5649 y(\2264\226)p eop %%Page: 5 5 5 4 bop 0 -180 a Ff(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#1:)30 b(Installation)24 b(and)g(De)n(v)o(elopment)628 b(September)25 b(26,)g(2001)145 69 y Fa(\017)49 b Fd(include)244 189 y Ff(Contains)24 b(copies)g(of)h(all)g(the)g(header)g(\002les)g (\(*.h\))g(from)f(all)h(the)g(modules.)145 396 y Fa(\017)49 b Fd(lib)244 516 y Ff(Contains)24 b(copies)g(of)h(each)h(of)f(the)f (compiled)g(and)h(link)o(ed)f(modules)f(\(*.o)i(and)g(*.a\).)145 723 y Fa(\017)49 b Fd(magic)244 843 y Ff(In)32 b(addition)f(to)g(the)h (source)g(main\(\))g(routine,)h(this)e(directory)g(is)h(where)g(the)g (modules)f(of)h(Magic)f(are)244 964 y(link)o(ed)24 b(to)g(form)h(the)f (e)o(x)o(ecutable)g(v)o(ersion)g(of)h(the)g(system.)146 1196 y(Magic)31 b(is)f(a)i(relati)n(v)o(ely)d(lar)n(ge)j(system:)41 b(there)32 b(are)f(around)g(575)g(source)g(\002les,)h(and)f(250,000)f (lines)g(of)i(C)0 1317 y(code.)e(In)22 b(order)g(to)f(mak)o(e)h(all)g (of)g(this)f(manageable,)h(we')-5 b(v)o(e)22 b(or)n(ganized)f(the)h (sources)g(in)f(a)h(tw)o(o-le)n(v)o(el)f(structure.)0 1437 y(Each)27 b(module)e(has)i(its)e(o)n(wn)h(subdirectory)-6 b(,)26 b(and)g(you)g(can)h(mak)o(e)g(changes)f(to)g(the)h(module)e(and) i(recompile)f(it)0 1558 y(by)31 b(w)o(orking)g(within)f(that)h (subdirectory)-6 b(.)50 b(The)31 b(CVS)i(method)d(of)i(softw)o(are)f (project)h(v)o(ersion)e(management)0 1678 y(has)h(been)h(implemented)e (to)h(mak)o(e)h(it)f(possible)f(for)i(se)n(v)o(eral)f(maintainers)f(to) h(w)o(ork)h(in)f(parallel.)51 b(The)31 b(CVS)0 1798 y(repository)f(for) h(magic)f(is)h(k)o(ept)f(at)h(host)f Fd(csl.cor)o(nell.edu)h Ff(in)g(directory)f Fd(/ufs/r)n(epository)p Ff(.)49 b(P)o(articipation) 29 b(in)0 1919 y(Magic)36 b(de)n(v)o(elopment)f(requires)h(a)h(remote)f (CVS)i(username)e(and)h(passw)o(ord)f(on)g(serv)o(er)g Fd(csl)p Ff(.)66 b(Logging)35 b(in)0 2039 y(simply)23 b(requires)i(the)g(e)o(x)o(ecution)e(of)i(the)f(follo)n(wing)f(CVS)j (command:)300 2273 y(cvs)f(-d)g(:pserv)o(er:)p Fg(cvslo)o(gin)p Ff(@csl.cornell.edu:/ufs/repository)19 b(login)146 2506 y(T)-8 b(o)25 b(do)n(wnload)e(the)i(latest)f(release)i(of)f(magic,)f (use)300 2739 y(cvs)h(-d)g(:pserv)o(er:)p Fg(cvslo)o(gin)p Ff(@csl.cornell.edu:/ufs/repository)19 b(check)o(out)25 b(magic)146 2972 y(This)j(will)f(create)i(a)f(directory)g(called)g (\223)p Fd(magic)p Ff(\224.)40 b(It)28 b(contains)g(the)g(entire)g (magic)f(distrib)n(ution.)38 b(Once)28 b(in)0 3092 y(the)f Fd(magic/)f Ff(directory)-6 b(,)26 b(the)g Fd(-d)i Ff(option)d(to)h (CVS)i(is)e(no)h(longer)f(required.)36 b(See)28 b(the)e Fd(cvs)h(\(1\))g Ff(manual)f(page)h(for)0 3213 y(details.)49 b(The)31 b(critical)g(CVS)h(commands)e(are)i(\223cvs)f(add\224)h(to)e (introduce)h(ne)n(w)g(\002les)g(to)g(the)g(repository)-6 b(,)31 b(\223cvs)0 3333 y(delete\224)h(to)f(remo)o(v)o(e)f(them,)i (\223cvs)g(update\224)f(to)g(mer)n(ge)g(in)g(an)o(y)g(ne)n(w)g(changes) h(found)e(in)h(the)h(repository)-6 b(,)31 b(and)0 3454 y(\223cvs)26 b(commit\224)e(to)i(send)f(local)h(changes)f(back)h(to)g (the)f(repository)-6 b(.)32 b(Simultaneous)25 b(changes)g(to)h(the)f (same)h(\002le)0 3574 y(are)33 b(mer)n(ged)f(mer)n(ged)g(by)f (heuristic;)k(con\003icts)c(are)i(\003agged,)h(to)d(be)h(resolv)o(ed)f (by)h(hand)g(on)f(a)h(case)h(by)f(case)0 3694 y(basis.)146 3815 y(There)26 b(are)f(tw)o(o)f(mailing)g(lists)f(associated)i(with)f (Magic)g(de)n(v)o(elopment:)120 4022 y(1.)49 b Fc (magic-hackers@csl.cornell.edu)31 b Ff(is)38 b(for)g(general)g(ne)n(ws) f(and)h(discussions)e(about)h(the)244 4142 y(de)n(v)o(elopment)22 b(process.)120 4349 y(2.)49 b Fc(magic-dev@csl.cornell.edu)26 b Ff(is)32 b(for)g(de)n(v)o(elopers)e(only)h(and)h(pro)o(vides)f (feedback)h(on)g(an)o(y)244 4470 y(CVS)26 b(changes)e(made)h(in)f(the)h (repository)-6 b(.)0 4813 y Fh(4)143 b(Compiling)34 b(and)h(Installing) 0 5038 y Ff(The)25 b(top-le)n(v)o(el)f(Mak)o(e\002le)h (\(\230cad/src/magic/Mak)o(e\002le\))g(pro)o(vides)f(man)o(y)h (options.)30 b(Before)d(using)d(the)h(Mak)o(e-)0 5159 y(\002le,)30 b(be)f(sure)g(to)g(set)f(your)h(CAD)p 1174 5159 30 4 v 36 w(HOME)f(shell)g(en)l(vironment)g(v)n(ariable)g(to)h (the)f(location)g(of)h(your)g(top-le)n(v)o(el)0 5279 y(cad)c(directory)g(\(if)g(it)f(is)g(not)h(the)f(standard)h(\230cad\).) 146 5400 y(The)g(most)f(useful)g(Mak)o(e\002le)h(options)f(are:)1875 5649 y(\2265\226)p eop %%Page: 6 6 6 5 bop 0 -180 a Ff(September)25 b(26,)f(2001)630 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#1:)30 b(Installation)23 b(and)i(De)n(v)o(elopment)145 69 y Fa(\017)49 b Fd(mak)o(e)25 b(con\002g)244 189 y Ff(Con\002gure)30 b(the)g(Magic)g(system)f(for)h (a)h(particular)e(type)h(of)g(display)f(or)h(operating)g(system.)45 b(This)29 b(just)244 309 y(runs)f(the)g Fd(:con\002g)h Ff(shell)f(script)f(to)h(set)g(up)g(a)h(couple)f(of)g(\002les.)41 b(The)29 b(curious)e(may)h(e)o(xamine)g(the)g(script)244 430 y(directly)-6 b(.)63 b(If)36 b(your)g(con\002guration)f(isn')n(t)g (handled)h(by)f(this)g(script,)j(then)e(you)f(can)i(use)e(it)h(simply)e (as)244 550 y(a)g(guide)g(as)g(to)g(what)f(to)h(do.)58 b(Much)34 b(of)g(the)g(con\002guration)f(is)h(done)g(with)f (compilation)f(\003ags.)59 b(See)244 671 y(Section)25 b Fd(??)f Ff(for)h(a)g(full)g(listing)e(of)i(them.)145 868 y Fa(\017)49 b Fd(mak)o(e)25 b(magic)244 989 y Ff(Mak)o(e)j(a)g(v)o (ersion)e(of)i(Magic.)39 b(All)27 b(sub-modules)f(are)i(remade,)h(if)f (needed,)g(and)g(then)f(the)h(\002nal)g(magic)244 1109 y(binary)c(is)h(produced.)145 1307 y Fa(\017)49 b Fd(mak)o(e)25 b(e)o(v)o(erything)244 1427 y Ff(Same)g(as)g(\223mak)o(e)g(magic\224.) 30 b(Both)25 b(options)e(mak)o(e)i(auxilary)g(programs)f(lik)o(e)g Fd(ext2sim)g Ff(and)h Fd(ext2spice)p Ff(.)145 1625 y Fa(\017)49 b Fd(mak)o(e)25 b(f)n(or)n(ce)244 1745 y Ff(F)o(orce)i (recompilation.)35 b(Lik)o(e)26 b(a)i(\223mak)o(e)e(e)n(v)o (erything\224,)g(e)o(xcept)g(that)h(object)f(\002les)h(are)g(\002rst)g (remo)o(v)o(ed)e(to)244 1866 y(force)g(complete)g(recompilation)e(from) h(scratch.)145 2064 y Fa(\017)49 b Fd(mak)o(e)25 b(clean)244 2184 y Ff(Delete)g(\002les)g(that)f(can)h(be)g(remade,)g(such)g(as)g (binaries,)f(object,)g(and)h(library)f(\002les.)145 2382 y Fa(\017)49 b Fd(mak)o(e)25 b(install)244 2502 y Ff(Install)f(the)g (Magic)h(binaries)f(in)h Fd(\230cad/bin)g Ff(\(or)g Fd($)p Fa(f)p Fd(CAD)p 2223 2502 30 4 v 36 w(HOME)p Fa(g)p Fd(/bin)f Ff(if)h(you)f(ha)n(v)o(e)h(that)f(set\).)146 2708 y(Putting)33 b(together)g(a)g(runnable)g(Magic)g(system)f(proceeds)i(in)f(tw)o(o)f (steps)h(after)h(a)g(source)f(\002le)h(has)f(been)0 2828 y(modi\002ed.)69 b(First,)41 b(the)c(source)h(\002le)g(is)g(compiled,)h (and)f(all)g(the)f(\002les)h(in)f(its)g(module)g(are)i(link)o(ed)e (together)0 2949 y(into)29 b(a)h(single)f(\002le)i Fg(xyz)p Fd(.o)p Ff(,)g(where)g Fg(xyz)f Ff(is)f(the)h(name)g(of)g(the)g (module.)45 b(Then)30 b(all)g(of)g(the)g(modules)e(are)j(link)o(ed)0 3069 y(together)h(to)f(form)h(an)h(e)o(x)o(ecutable)e(v)o(ersion)g(of)h (Magic.)53 b(The)32 b(command)f Fd(mak)o(e)i Ff(in)e(each)i(source)f (directory)0 3190 y(will)f(compile)f(and)i(link)e(the)i(module)e (locally;)k Fd(mak)o(e)e(install)f Ff(will)g(compile)f(and)i(link)e (it,)j(and)e(also)g(install)0 3310 y(it)37 b(in)h(the)f Fd(include)i Ff(and)f Fd(lib)g Ff(directories.)69 b(All)38 b(Mak)o(e\002les)g(are)g(set)g(up)f(to)h(use)g(the)f(compiler)g (\003ags)i(found)0 3430 y(in)30 b Fd(\230cad/sr)n(c/magic/misc/DFLA)-5 b(GS)29 b Ff(and)i Fd(\230cad/sr)n(c/magic/misc/CFLA)-5 b(GS)p Ff(.)29 b(A)i(list)e(of)i(\003ags)g(appears)f(in)0 3551 y(Section)25 b Fd(??)o Ff(.)146 3671 y(The)32 b(command)f Fd(mak)o(e)h Ff(in)g(the)f(subdirectory)g Fd(magic)h Ff(will)f(produce)h(a)g(runnable)f(v)o(ersion)g(of)h(Magic)f(in)0 3791 y(that)26 b(directory)-6 b(,)26 b(using)f(the)h(installed)f(v)o (ersions)g(of)h(all)g(modules.)34 b(T)-8 b(o)26 b(w)o(ork)g(with)f(the) h(uninstalled)f(v)o(ersion)g(of)0 3912 y(a)k(module,)e(create)i (another)g(subdirectory)e(identical)g(to)h Fd(magic)p Ff(,)h(and)f(modify)f(the)h(Mak)o(e\002le)g(so)g(that)g(it)f(uses)0 4032 y(uninstalled)33 b(v)o(ersions)h(of)h(the)g(rele)n(v)n(ant)f (modules.)60 b(F)o(or)35 b(e)o(xample,)i(the)e(Magic)g(team)f(uses)h (subdirectories)0 4153 y Fd(hamachitest)p Ff(,)43 b Fd(may)n(otest)p Ff(,)f Fd(mhatest)p Ff(,)g Fd(oustertest)p Ff(,)i(and)39 b Fd(wsstest)f Ff(that)h(we)g(use)f(to)h(test)f(ne)n(w)h(v)o(ersions)e (of)0 4273 y(modules)21 b(before)i(installing)d(them.)29 b(If)23 b(you)f(w)o(ant)g(to)g(remak)o(e)h(the)f(entire)g(system,)g (type)g(\223mak)o(e)g(magic\224)g(in)g(the)0 4393 y(top-le)n(v)o(el)h (directory)i(\()p Fd(\230cad/sr)n(c/magic)p Ff(\).)0 4730 y Fh(5)143 b(Summary)34 b(of)h(Magic)g(Modules)0 4953 y Ff(This)24 b(section)g(contains)g(brief)h(summaries)f(of)h(what) f(is)h(in)f(each)h(of)g(the)g(Magic)f(source)h(subdirectories.)145 5159 y Fa(\017)49 b Fd(calma)244 5280 y Ff(Contains)26 b(code)h(to)g(read)h(and)f(write)f(Calma)i(Stream-format)f(\002les.)37 b(It)27 b(uses)g(man)o(y)f(of)h(the)g(procedures)244 5400 y(in)d(the)h Fd(cif)g Ff(module.)1875 5649 y(\2266\226)p eop %%Page: 7 7 7 6 bop 0 -180 a Ff(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#1:)30 b(Installation)24 b(and)g(De)n(v)o(elopment)628 b(September)25 b(26,)g(2001)145 69 y Fa(\017)49 b Fd(cif)244 189 y Ff(Contains)22 b(code)i(to)f(process)g(the)g(CIF)h(sections)e(of) h(technology)f(\002les,)i(and)f(to)g(generate)h(CIF)g(\002les)f(from) 244 309 y(Magic.)145 518 y Fa(\017)49 b Fd(cmwind)244 638 y Ff(Contains)24 b(code)h(to)f(implement)g(special)g(windo)n(ws)f (for)i(editing)f(color)h(maps.)145 846 y Fa(\017)49 b Fd(commands)244 966 y Ff(The)22 b(procedures)g(in)g(this)g(module)f (contain)g(the)h(top-le)n(v)o(el)f(command)g(routines)g(for)i(layout)e (commands)244 1087 y(\(commands)28 b(that)g(are)i(v)n(alid)e(in)h(all)f (windo)n(ws)g(are)i(handled)e(in)h(the)g Fd(windo)o(ws)g Ff(module\).)42 b(These)29 b(rou-)244 1207 y(tines)21 b(generally)h(just)g(parse)g(the)g(commands,)g(check)g(for)h(errors,)g (and)f(call)g(other)h(routines)e(to)h(carry)h(out)244 1328 y(the)i(actions.)145 1536 y Fa(\017)49 b Fd(database)244 1656 y Ff(This)23 b(is)h(the)g(lar)n(gest)g(and)g(most)e(important)h (Magic)h(module.)29 b(It)24 b(implements)e(the)i(hierarchical)g(corner) n(-)244 1776 y(stitched)g(database,)h(and)f(reads)h(and)g(writes)g (Magic)f(\002les.)145 1984 y Fa(\017)49 b Fd(dbwind)244 2105 y Ff(Pro)o(vides)30 b(display)g(functions)g(speci\002c)h(to)g (layout)f(windo)n(ws,)h(including)e(managing)h(the)h(box,)h(redis-)244 2225 y(playing)24 b(layout,)g(and)g(displaying)f(highlights)g(and)i (feedback.)145 2433 y Fa(\017)49 b Fd(deb)n(ug)244 2554 y Ff(There')-5 b(s)25 b(not)f(much)g(in)g(this)g(module,)g(just)g(a)h (fe)n(w)g(routines)f(used)g(for)h(deb)n(ugging)f(purposes.)145 2762 y Fa(\017)49 b Fd(dr)n(c)244 2882 y Ff(This)28 b(module)f (contains)h(the)g(incremental)g(design-rule)g(check)o(er)-5 b(.)42 b(It)29 b(contains)f(code)g(to)g(read)i(the)e Fd(dr)n(c)244 3003 y Ff(sections)c(of)i(technology)e(\002les,)i(record) g(areas)g(to)f(be)h(recheck)o(ed,)g(and)g(recheck)g(those)f(areas)h(in) f(a)h(hier)n(-)244 3123 y(archical)f(f)o(ashion.)145 3331 y Fa(\017)49 b Fd(ext2dlys)244 3451 y Ff(The)27 b Fd(ext2dlys)f Ff(directory)g(isn')n(t)h(part)f(of)h(Magic)f(itself.) 36 b(It')-5 b(s)26 b(a)h(self-contained)f(program)h(that)f(uses)g(the) 244 3572 y(hierarchical)g Fd(.ext)g Ff(\002les)g(generated)h(by)e (Magic')-5 b(s)25 b(e)o(xtractor)h(and)g(an)g(optional)f(netlist)f (\002le)j(designating)244 3692 y(net)f(pinouts)g(\(for)h(purposes)f(of) h(counting)e(I/O)i(loads\),)f(and)h(produces)g(a)g(wire-delay)f (\002le.)37 b(Also)26 b(com-)244 3813 y(piles)h(an)h(e)o(x)o(ecutable)f Fd(sim2dlys)g Ff(for)i(delay)f(calculations)f(from)g Fd(.sim)h Ff(\002les.)40 b(These)28 b(programs)g(are)g(no)244 3933 y(longer)c(compiled)g(and)h(the)f(module)g(has)h(been)g(commented) f(out)g(in)g(the)h(top-le)n(v)o(el)e Fd(Mak)o(e\002le)p Ff(.)145 4141 y Fa(\017)49 b Fd(ext2sim)244 4261 y Ff(This)28 b(is)h(another)h(self-contained)e(program.)44 b(It')-5 b(s)29 b(a)h(self-contained)f(program)g(that)f(\003attens)i(the)f(hier) n(-)244 4382 y(archical)j Fd(.ext)f Ff(\002les)h(generated)f(by)g (Magic')-5 b(s)31 b(e)o(xtractor)f(into)h(a)h(single)e(\002le)i(in)e Fd(.sim)h Ff(format.)50 b(See)32 b(the)244 4502 y(manual)24 b(page)h Fd(ext2sim)f(\(1\))p Ff(.)145 4710 y Fa(\017)49 b Fd(ext2spice)244 4831 y Ff(This)26 b(is)g(another)g(self-contained)g (program.)36 b(It)26 b(con)l(v)o(erts)g Fd(.ext)h Ff(\002les)g(into)e (single)h(\002le)h(in)f(spice)g(format.)244 4951 y(See)g(the)e(manual)g (page)h Fd(ext2spice)h(\(1\))p Ff(.)145 5159 y Fa(\017)49 b Fd(extcheck)244 5280 y Ff(Y)-10 b(et)22 b(another)f(independent)g (program.)30 b(This)21 b(one)g(checks)i(the)e Fd(.ext)h Ff(\002les)g(for)g(global)f(node)h(connecti)n(vity)244 5400 y(and)j(summarizes)e(the)i(number)f(of)h(FETs,)g(nodes,)f(etc.)31 b(See)26 b(the)f(manual)f(page)h Fd(extcheck)h(\(1\))p Ff(.)1875 5649 y(\2267\226)p eop %%Page: 8 8 8 7 bop 0 -180 a Ff(September)25 b(26,)f(2001)630 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#1:)30 b(Installation)23 b(and)i(De)n(v)o(elopment)145 69 y Fa(\017)49 b Fd(ext\003at)244 189 y Ff(Contains)31 b(code)g(that)g(is)g(used)g(by)g(the)h Fd(extract)g Ff(module)e(and)h(the)h Fd(ext2.)15 b(.)g(.)65 b Ff(programs.)50 b(The)31 b(module)244 309 y(produces)24 b(a)i(library)e(that)g(is)h(link)o(ed)f(in)g(with)g(the)h(abo)o(v)o(e)f (programs.)145 542 y Fa(\017)49 b Fd(extract)244 662 y Ff(Contains)28 b(code)h(to)g(read)g(the)g Fd(extract)g Ff(sections)f(of)h(technology)f(\002les,)i(and)f(to)f(generate)i (hierarchical)244 782 y(circuit)24 b(descriptions)g(\()p Fd(.ext)h Ff(\002les\))g(from)g(Magic)f(layouts.)145 1015 y Fa(\017)49 b Fd(fsleeper)244 1135 y Ff(Lik)o(e)29 b Fd(ext2sim)p Ff(,)g(this)g(directory)f(is)h(a)h(self-contained)e (program)h(that)g(allo)n(ws)e(a)j(graphics)f(terminal)f(at-)244 1255 y(tached)20 b(to)g(one)h(machine)e(to)h(be)h(used)f(with)f(Magic)h (running)g(on)g(a)g(dif)n(ferent)g(machine.)29 b(See)22 b(the)e(manual)244 1376 y(page)25 b Fd(fsleeper)h(\(1\))p Ff(.)145 1608 y Fa(\017)49 b Fd(gar)n(outer)244 1728 y Ff(Contains)24 b(the)h(gate)f(array)i(router)e(from)h(La)o(wrence)g (Li)n(v)o(ermore)f(National)g(Labs.)145 1960 y Fa(\017)49 b Fd(gcr)244 2081 y Ff(Contains)25 b(the)h(channel)g(router)l(,)g (which)f(is)h(an)g(e)o(xtension)e(of)i(Ri)n(v)o(est')-5 b(s)25 b(greedy)h(router)g(that)f(can)h(handle)244 2201 y(switchbox)o(es)d(and)i(obstacles)f(in)g(the)h(channels.)145 2433 y Fa(\017)49 b Fd(graphics)244 2554 y Ff(This)23 b(is)g(the)g(lo)n(west-le)n(v)o(el)e(graphics)j(module.)29 b(It)23 b(contains)g(dri)n(v)o(er)g(routines)f(for)i(X11)f(and)h (OpenGL)f(as)244 2674 y(well)f(as)h(le)o(gac)o(y)f(dri)n(v)o(ers)g(for) h(the)g(AED)g(f)o(amily)f(of)h(display)f(terminals,)g(Sun)h(W)l(indo)n (ws,)e(and)i(X10.)30 b(The)244 2795 y(code)24 b(here)g(does)f(basic)h (clipping)e(and)h(dra)o(wing.)30 b(If)24 b(you)f(w)o(ant)g(to)h(mak)o (e)f(Magic)g(run)h(on)f(a)h(ne)n(w)f(kind)g(of)244 2915 y(display)-6 b(,)23 b(this)h(is)g(the)h(only)f(module)g(that)g(should)g (ha)n(v)o(e)g(to)h(change.)145 3147 y Fa(\017)49 b Fd(gr)n(outer)244 3267 y Ff(The)24 b(\002les)h(in)f(this)f(module)g(implement)g(the)h (global)g(router)l(,)g(which)g(computes)g(the)g(sequence)g(of)h(chan-) 244 3388 y(nels)f(that)h(each)g(net)g(is)f(to)g(pass)h(through.)145 3620 y Fa(\017)49 b Fd(ir)n(outer)244 3740 y Ff(Contains)28 b(the)g(interacti)n(v)o(e)f(router)h(written)g(by)g(Michael)f(Arnold)h (at)g(La)o(wrence)h(Li)n(v)o(ermore)e(National)244 3861 y(Labs.)68 b(This)37 b(router)g(allo)n(ws)f(the)h(user)h(to)f(route)g (nets)g(interacti)n(v)o(ely)-6 b(,)38 b(using)e(special)i(hint)e (layers)h(to)244 3981 y(control)24 b(the)h(routing.)145 4213 y Fa(\017)49 b Fd(lisp)244 4334 y Ff(This)24 b(module)g(contains)g (code)i(which,)e(if)h(the)g(SCHEME)g(option)f(is)h(chosen)f(at)i (compile)e(time,)g(imple-)244 4454 y(ments)k(the)h(lisp-lik)o(e)f (\223scheme\224)i(interpreter)-5 b(.)43 b(Scheme)30 b(enables)f(magic)g (commands)f(to)h(be)g(e)o(x)o(ecuted)244 4574 y(in)24 b(a)h(programming)f(language)g(frame)n(w)o(ork,)h(so)f(comple)o(x)g (functions)f(can)j(be)e(de\002ned.)145 4807 y Fa(\017)49 b Fd(macr)n(os)244 4927 y Ff(Implements)23 b(simple)h(k)o(e)o(yboard)g (macros.)145 5159 y Fa(\017)49 b Fd(magicusage)244 5280 y Ff(Lik)o(e)28 b Fd(ext2sim)p Ff(,)i(this)d(is)i(also)f(a)h (self-contained)f(program.)42 b(It)29 b(searches)g(through)f(a)h (layout)f(to)h(\002nd)f(all)244 5400 y(the)d(\002les)g(that)f(are)h (used)g(in)f(it.)31 b(See)25 b Fd(magicusage)g Ff(\(1\).)1875 5649 y(\2268\226)p eop %%Page: 9 9 9 8 bop 0 -180 a Ff(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#1:)30 b(Installation)24 b(and)g(De)n(v)o(elopment)628 b(September)25 b(26,)g(2001)145 69 y Fa(\017)49 b Fd(main)244 189 y Ff(This)23 b(module)g(contains)g(the)h(main)f(program)g(for)h (Magic,)g(which)g(parses)g(command-line)e(parameters,)244 309 y(initializes)h(the)i(w)o(orld,)f(and)h(then)f(transfers)h(control) f(to)h Fd(textio)p Ff(.)145 507 y Fa(\017)49 b Fd(misc)244 627 y Ff(A)25 b(fe)n(w)f(small)g(things)g(that)g(didn')n(t)g(belong)g (an)o(yplace)h(else.)145 824 y Fa(\017)49 b Fd(mpack)244 944 y Ff(Contains)22 b(routines)g(that)g(implement)f(the)i(Tpack)f (tile-packing)g(interf)o(ace)h(using)f(the)h(Magic)f(database.)244 1065 y(\(not)i(supported\))145 1262 y Fa(\017)49 b Fd(mzr)n(outer)244 1382 y Ff(Contains)24 b(maze)h(routing)f(routines)g(that)g(are)i(used)e (by)h(the)f(irouter)h(and)g(garouter)f(modules.)145 1579 y Fa(\017)49 b Fd(net2ir)244 1700 y Ff(Contains)24 b(a)h(program)g(to)f (con)l(v)o(ert)g(a)h(netlist)f(into)g(irouter)g(commands.)145 1897 y Fa(\017)49 b Fd(netlist)244 2017 y Ff(Netlist)23 b(manipulation)g(routines.)145 2214 y Fa(\017)49 b Fd(netmenu)244 2335 y Ff(Implements)23 b(netlists)g(and)i(the)g(special)f (netlist-editing)f(windo)n(ws.)145 2532 y Fa(\017)49 b Fd(parser)244 2652 y Ff(Contains)24 b(the)h(code)g(that)f(parses)h (command)f(lines)g(into)g(ar)n(guments.)145 2849 y Fa(\017)49 b Fd(plot)244 2970 y Ff(The)38 b(internals)g(of)h(the)f Fd(:plot)h Ff(command.)70 b(Code)39 b(to)f(write)h(PostScript,)i(ra)o (w)e(pix)o(el,)h(v)o(ersatec,)i(and)244 3090 y(gremlin)24 b(formats.)145 3287 y Fa(\017)49 b Fd(plo)o(w)244 3408 y Ff(This)24 b(module)g(contains)g(the)g(code)h(to)g(support)f(the)g Fd(:plo)o(w)h Ff(and)g Fd(:straighten)h Ff(commands.)145 3605 y Fa(\017)49 b Fd(prleak)244 3725 y Ff(Also)35 b(not)f(part)i(of)f (Magic)g(itself.)62 b(Prleak)36 b(is)f(a)h(self-contained)f(program)g (intended)g(for)g(use)h(in)f(de-)244 3846 y(b)n(ugging)25 b(Magic')-5 b(s)25 b(memory)h(allocator)-5 b(.)34 b(It)26 b(analyzes)h(a)f(trace)h(of)f(mallocs/frees)g(to)g(look)f(for)i(memory) 244 3966 y(leaks.)j(See)c(the)f(manual)f(page)h Fd(prleak)h(\(8\))f Ff(for)g(information)e(on)i(what)f(the)h(program)f(does.)145 4163 y Fa(\017)49 b Fd(r)n(eadline)244 4283 y Ff(\223readline\224)38 b(is)g(an)g(independent)f(library)g(of)h(routines)f(implementing)f (command-line)g(history)h(and)244 4404 y(editing.)29 b(V)-11 b(ersion)25 b(7.1)f(of)h(magic)f(uses)h(GNU)g(readline-4.1.)145 4601 y Fa(\017)49 b Fd(r)n(esis)244 4721 y Ff(Resis)25 b(is)f(a)h(module)f(that)h(does)f(better)h(resistance)g(e)o(xtraction)f (via)g(the)h(:e)o(xtresis)e(command.)30 b(Courtesy)244 4842 y(of)25 b(Don)f(Stark)h(of)g(Stanford.)145 5039 y Fa(\017)49 b Fd(r)n(outer)244 5159 y Ff(Contains)22 b(the)i(top-le)n(v)o(el)d(routing)h(code,)i(including)e(procedures)h (to)g(read)h(the)f(router)g(sections)g(of)g(tech-)244 5280 y(nology)j(\002les,)i(chop)f(free)h(space)f(up)g(into)f(channels,) i(analyze)f(obstacles,)g(and)g(paint)g(back)g(the)g(results)244 5400 y(produced)d(by)h(the)g(channel)f(router)-5 b(.)1875 5649 y(\2269\226)p eop %%Page: 10 10 10 9 bop 0 -180 a Ff(September)25 b(26,)f(2001)630 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#1:)30 b(Installation)23 b(and)i(De)n(v)o(elopment)145 67 y Fa(\017)49 b Fd(select)244 187 y Ff(This)23 b(module)f(contains)h(\002les)g(that)g(manage)h(the)f (selection.)30 b(The)23 b(routines)g(here)h(pro)o(vide)e(f)o(acilities) h(for)244 308 y(making)30 b(a)h(selection,)g(enumerating)f(what')-5 b(s)30 b(in)h(the)g(selection,)g(and)g(manipulating)e(the)h(selection)g (in)244 428 y(se)n(v)o(eral)24 b(w)o(ays,)g(such)h(as)g(mo)o(ving)e(it) h(or)h(cop)o(ying)f(it.)145 684 y Fa(\017)49 b Fd(signals)244 804 y Ff(Handles)24 b(signals)g(such)g(as)h(the)g(interrupt)f(k)o(e)o (y)g(and)h(control-Z.)145 1060 y Fa(\017)49 b Fd(sim)244 1180 y Ff(Pro)o(vides)24 b(an)h(interacti)n(v)o(e)e(interf)o(ace)j(to)e (the)h(simulator)e(rsim.)30 b(Courtesy)25 b(of)g(Mik)o(e)f(Cho)n(w)g (of)h(Stanford.)145 1436 y Fa(\017)49 b Fd(tech)244 1557 y Ff(This)24 b(module)h(contains)f(the)h(top-le)n(v)o(el)e(technology)h (\002le)i(reading)f(code,)h(and)f(the)g(current)g(technology)244 1677 y(\002les.)51 b(The)31 b(code)h(does)f(little)g(e)o(xcept)g(to)g (read)h(technology)e(\002le)i(lines,)h(parse)e(them)g(into)g(ar)n (guments,)244 1797 y(and)25 b(pass)f(them)g(of)n(f)h(to)f(clients)g(in) h(other)f(modules)g(\(such)h(as)f Fd(dr)n(c)i Ff(or)f Fd(database)p Ff(\).)145 2053 y Fa(\017)49 b Fd(textio)244 2173 y Ff(The)37 b(top-le)n(v)o(el)d(command)i(interpreter)-5 b(.)66 b(This)36 b(module)f(grabs)i(commands)e(from)i(the)f(k)o(e)o (yboard)g(or)244 2294 y(mouse)e(and)h(sends)f(them)g(to)h(the)g(windo)n (w)e(module)h(for)h(processing.)60 b(Also)34 b(pro)o(vides)g(routines)g (for)244 2414 y(message)24 b(and)h(error)h(printout,)d(and)i(to)f (manage)h(the)f(prompt)g(on)h(the)f(screen.)145 2670 y Fa(\017)49 b Fd(tiles)244 2790 y Ff(Implements)27 b(basic)h(corner)n (-stitched)g(tile)f(planes.)41 b(This)28 b(module)f(w)o(as)h(separated) h(from)f Fd(database)g Ff(in)244 2911 y(order)d(to)f(allo)n(w)g(other)h (clients)f(to)g(use)h(tile)f(planes)h(without)e(using)h(the)g(other)h (database)g(f)o(acilities)f(too.)145 3167 y Fa(\017)49 b Fd(undo)244 3287 y Ff(The)32 b Fd(undo)i Ff(module)d(pro)o(vides)g (the)i(o)o(v)o(erall)e(frame)n(w)o(ork)h(for)h(undo)e(and)i(redo)f (operations,)i(in)e(that)g(it)244 3407 y(stores)38 b(lists)f(of)i (actions.)71 b(Ho)n(we)n(v)o(er)l(,)41 b(all)d(the)h(speci\002c)g (actions)f(are)h(managed)g(by)f(clients)g(such)g(as)244 3528 y Fd(database)25 b Ff(or)g Fd(netmenu)p Ff(.)145 3783 y Fa(\017)49 b Fd(utils)244 3904 y Ff(This)22 b(module)g (implements)g(a)h(whole)g(b)n(unch)g(of)g(utility)e(procedures,)j (including)e(a)h(geometry)g(package)244 4024 y(for)37 b(dealing)e(with)h(rectangles)g(and)h(points)e(and)h(transformations,)i (a)e(heap)h(package,)j(a)c(hash)g(table)244 4145 y(package,)25 b(a)g(stack)g(package,)g(a)g(re)n(vised)f(memory)g(allocator)l(,)h(and) f(lots)g(of)h(other)g(stuf)n(f.)145 4400 y Fa(\017)49 b Fd(windo)o(ws)244 4521 y Ff(This)20 b(is)g(the)h(o)o(v)o(erall)e (windo)n(w)g(manager)-5 b(.)29 b(It)21 b(k)o(eeps)g(track)g(of)f(windo) n(ws)f(and)i(calls)f(clients)g(\(lik)o(e)h Fd(dbwind)244 4641 y Ff(and)f Fd(cmwind)p Ff(\))h(to)f(process)g(windo)n (w-speci\002c)f(operations)g(such)h(as)g(redisplaying)f(or)h (processing)f(com-)244 4762 y(mands.)42 b(Commands)27 b(that)i(are)g(v)n(alid)f(in)g(all)g(windo)n(ws,)g(such)h(as)g (resizing)f(or)h(mo)o(ving)d(windo)n(ws,)i(are)244 4882 y(implemented)23 b(here.)145 5138 y Fa(\017)49 b Fd(wiring)244 5258 y Ff(The)23 b(\002les)g(in)f(this)g(directory)h(implement)e(the)i Fd(:wir)n(e)g Ff(command.)30 b(There)23 b(are)h(routines)e(to)g(select) h(wiring)244 5378 y(material,)h(add)h(wire)g(le)o(gs,)f(and)g(place)i (contacts.)1850 5649 y(\22610\226)p eop %%Page: 11 11 11 10 bop 0 -180 a Ff(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#1:)30 b(Installation)24 b(and)g(De)n(v)o(elopment)628 b(September)25 b(26,)g(2001)0 99 y Fh(6)143 b(P)m(ortability)34 b(Issues)0 325 y Ff(Magic)23 b(runs)g(on)g(a)g(v)n(ariety)g(of)g (machines.)30 b(Running)23 b(\223mak)o(e)g(con\002g\224)h(in)e(the)i (top-le)n(v)o(el)d(source)j(directory)f(sets)0 446 y(the)h(compiletime) f(options.)28 b(If)d(you)f(are)h(porting)e(Magic,)h(you)g(should)f (modify)g(the)h(con\002guration)g(section)f(at)0 566 y(the)i(end)h(of)g(\002le)g(\224misc/magic.h\224)e(to)h(suit)g(your)h (machine,)f(by)g(testing)g(compiler)g(\003ags.)33 b(No)26 b(changes)f(should)0 687 y(be)g(made)g(that)f(w)o(ould)g(hamper)h (Magic')-5 b(s)24 b(operation)g(on)g(other)h(machines.)0 1035 y Fh(7)143 b(Compilation)33 b(Switches)0 1262 y Fd(??)146 1384 y Ff(Ov)o(er)c(the)g(years)g(Magic)g(has)g(acquired)g(a) h(number)e(of)h(compilation)e(switches.)43 b(While)29 b(it')-5 b(s)28 b(undesirable)0 1504 y(to)23 b(ha)n(v)o(e)f(so)h(man)o (y)-6 b(,)22 b(it)g(seems)h(una)n(v)n(oidable)f(since)h(people)f(use)h (Magic)g(on)g(such)f(a)i(wide)e(v)n(ariety)h(of)g(machines.)0 1625 y(The)30 b(\002le)h(\230cad/src/magic/misc/DFLA)l(GS)d(should)h (contain)h(the)g(compile)f(switches)g(that)h(you)f(wish)h(to)f(use)0 1745 y(at)i(your)g(site.)50 b(All)30 b(mak)o(e\002les)h(for)h(Magic)f (reference)h(the)g(common)e(DFLA)l(GS)h(\002le.)51 b(The)31 b(switches)f(in)h(this)0 1865 y(release)25 b(are)h(sho)n(wn)e(belo)n(w) -6 b(.)146 1987 y(These)23 b(\003ags)h(are)g(normally)e(setup)g(by)h (running)f(the)h(\224mak)o(e)g(con\002g\224)h(script)e(in)h (\230cad/src/magic.)30 b(Some)23 b(of)0 2108 y(them)h(are)i(turned)e (on)h(in)f(\224magic.h\224)h(when)f(a)i(particular)e(machine)h (con\002guration)f(is)g(detected.)0 2412 y Fe(7.1)119 b(Machine/OS)32 b(Compiletime)e(Options)0 2603 y Ff(The)24 b(follo)n(wing)d(switches)i(should)g(be)h(de\002ned)g(automatically)e (by)h(the)h Fd(:con\002g)g Ff(script)g(upon)f(selection)f(of)i(the)0 2723 y(tar)n(get)h(hardw)o(are)g(and)g(OS.)145 2962 y Fa(\017)49 b Ff(mips)244 3082 y(F)o(or)25 b(mips)e(processors,)i(such)f (as)h(the)g(DECstation.)145 3293 y Fa(\017)49 b Ff(MIPSEL)244 3413 y(F)o(or)25 b(little-endian)e(mips)h(processors,)g(such)h(as)f (the)h(DECstation)f(3100.)145 3624 y Fa(\017)49 b Ff(MIPSEB)244 3744 y(F)o(or)25 b(big-endian)f(mips)f(processors.)145 3955 y Fa(\017)49 b Ff(sun)244 4076 y(F)o(or)25 b(Sun)g(machines.)145 4286 y Fa(\017)49 b Ff(mc68000)244 4407 y(F)o(or)25 b(machines)f(which) g(ha)n(v)o(e)h(a)g(v)o(ersion)f(of)h(the)f(68000)g(as)h(the)g (processor)-5 b(.)145 4617 y Fa(\017)49 b Ff(sparc)244 4738 y(Sparc-based)26 b(machines.)145 4949 y Fa(\017)49 b Ff(i386)244 5069 y(F)o(or)25 b(Intel)f(x86-based)h(machines.)145 5280 y Fa(\017)49 b Ff(linux)244 5400 y(F)o(or)25 b(Linux)f(systems.) 1850 5649 y(\22611\226)p eop %%Page: 12 12 12 11 bop 0 -180 a Ff(September)25 b(26,)f(2001)630 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#1:)30 b(Installation)23 b(and)i(De)n(v)o(elopment)145 45 y Fa(\017)49 b Ff(v)n(ax)244 166 y(F)o(or)25 b(V)-13 b(AX)24 b(machines)g(\(le)o(gac)o(y\).)145 379 y Fa(\017)49 b Ff(lint)244 499 y(Used)25 b(to)f(bypass)g(things)g (that)g(lint)g(complains)f(about.)30 b(Don')n(t)25 b(turn)f(this)g(on.) 31 b(Lint)23 b(turns)i(it)f(on)g(itself.)146 740 y(If)i(needed,)f(you)f (can)h(put)f(the)h(follo)n(wing)e(switches)h(in)g(the)h(DFLA)l(GS)g (\002le:)145 982 y Fa(\017)49 b Ff(macII)244 1102 y(F)o(or)25 b(the)f(Apple)h(Mac-II)g(\(running)f(A/UX\))h(\(le)o(gac)o(y\).)145 1315 y Fa(\017)49 b Ff(SUNVIEW)244 1435 y(Used)25 b(when)f(including)f (Magic')-5 b(s)24 b(SunV)-6 b(ie)n(w)25 b(graphics)f(dri)n(v)o(ers.)145 1648 y Fa(\017)49 b Ff(SUN120)244 1769 y(F)o(or)25 b(the)f(Sun120)h (machine)f(\(le)o(gac)o(y\).)145 1982 y Fa(\017)49 b Ff(BSD4)p 493 1982 30 4 v 36 w(2)244 2102 y(Used)31 b(in)f(the)h(utils) f(module)g(to)g(patch)h(around)g(a)g(brok)o(en)g(v)o(ersion)f(of)h (\003sb)n(uf\(\))g(that)g(is)f(needed)i(in)e(the)244 2222 y(V)-13 b(AX)31 b(v)o(ersion)f(of)h(Unix)g(4.2)g(BSD)i(systems.)49 b(This)30 b(is)h(rarely)h(needed,)h(since)e(almost)g(all)g(v)o(ersion)f (of)244 2343 y(Unix)24 b(no)n(w)g(ha)n(v)o(e)h(this)e(b)n(ug)i(\002x)o (ed)f(\(le)o(gac)o(y\).)145 2555 y Fa(\017)49 b Ff(F)-7 b(ASYNC)244 2676 y(Hack)25 b(for)g(some)f(v)o(ersions)g(of)h(Sun2)f (softw)o(are)h(\(le)o(gac)o(y\).)145 2889 y Fa(\017)49 b Ff(NO)p 394 2889 V 36 w(V)-13 b(ARARGS)244 3009 y(Hack)25 b(for)g(machines)f(without)g(a)h(V)-13 b(ARARGS)25 b(package.)145 3222 y Fa(\017)49 b Ff(SYSV)244 3342 y(F)o(or)25 b(Unix)f(System)g(V) -13 b(.)146 3584 y(Flags)25 b(de\002ned,)g(if)g(needed,)g(in)f (\224magic.h\224)h(based)g(on)f(other)h(\003ags.)145 3825 y Fa(\017)49 b Ff(BIG)p 421 3825 V 36 w(ENDIAN)244 3946 y(Indicates)24 b(big)h(endian)f(byte)h(ordering)f(is)g(being)h (used.)145 4158 y Fa(\017)49 b Ff(LITTLE)p 588 4158 V 35 w(ENDIAN)244 4279 y(Indicates)24 b(little)g(endian)h(byte)f (ordering)g(is)h(being)f(used.)145 4492 y Fa(\017)49 b Ff(NEED)p 516 4492 V 35 w(MONCNTL)244 4612 y(Hack)25 b(for)g(machines)f(without)g(a)h(moncontrol)e(procedure.)145 4825 y Fa(\017)49 b Ff(NEED)p 516 4825 V 35 w(VFPRINTF)244 4945 y(Hack)25 b(for)g(machines)f(without)g(a)h(vfprintf)f(procedure.) 145 5158 y Fa(\017)49 b Ff(SIG)p 410 5158 V 36 w(RETURNS)p 899 5158 V 37 w(INT)244 5278 y(De\002ned)25 b(in)f(magic.h)f(for)i (systems)e(that)h(e)o(xpect)g(a)h(signal)e(handler)h(to)g(return)h(an)f (inte)o(ger)g(rather)h(than)f(a)244 5399 y(v)n(oid.)1850 5649 y(\22612\226)p eop %%Page: 13 13 13 12 bop 0 -180 a Ff(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#1:)30 b(Installation)24 b(and)g(De)n(v)o(elopment)628 b(September)25 b(26,)g(2001)0 82 y Fe(7.2)119 b(Graphics)31 b(Dri)o(v)o(er)f(Compile-time)g(Options)145 272 y Fa(\017)49 b Ff(X11)244 392 y(Used)25 b(in)f(the)h(graphics)f(module)g(for)h(the)g (X11)f(dri)n(v)o(er)-5 b(.)145 601 y Fa(\017)49 b Ff(OpenGL)244 721 y(Used)25 b(in)f(the)h(graphics)f(module)g(for)h(the)g(OpenGL/GLX)e (dri)n(v)o(er)-5 b(.)145 930 y Fa(\017)49 b Ff(XLIB)244 1050 y(Used)19 b(for)g(all)g(graphics)g(modules)e(based)i(on)g(an)g(X)h (serv)o(er)f(\(currently)-6 b(,)19 b(that)g(means)g(X11)f(and)h (OpenGL\).)145 1259 y Fa(\017)49 b Ff(X10)244 1379 y(Used)25 b(in)f(the)h(graphics)f(module)g(for)h(the)g(X10)f(dri)n(v)o(er)g(\(le) o(gac)o(y\).)145 1588 y Fa(\017)49 b Ff(AED)244 1708 y(Used)25 b(in)f(the)h(graphics)f(module)g(when)g(compiling)f(for)j (AED)e(displays)g(\(le)o(gac)o(y\).)145 1916 y Fa(\017)49 b Ff(GTCO)244 2037 y(Used)25 b(in)f(the)h(graphics)f(module)g(when)g (using)g(a)h(GTCO)h(bitpad)d(with)i(an)f(AED)h(display)f(\(le)o(gac)o (y\).)0 2339 y Fe(7.3)119 b(Compile-time)30 b(Options)g(f)m(or)g (Module)h(Inclusion)145 2528 y Fa(\017)49 b Ff(NO)p 394 2528 30 4 v 36 w(CALMA)244 2649 y(Flag)25 b(to)f(eliminate)g(the)h (calma)f(module,)g(to)h(reduce)g(the)g(size)f(of)h(Magic.)145 2857 y Fa(\017)49 b Ff(NO)p 394 2857 V 36 w(CIF)244 2978 y(Flag)25 b(to)f(eliminate)g(the)h(cif)g(module,)e(to)i(reduce)g(the)g (size)g(of)g(Magic.)145 3186 y Fa(\017)49 b Ff(NO)p 394 3186 V 36 w(EXT)244 3306 y(Flag)25 b(to)g(eliminate)g(the)g(e)o(xt)g (module,)f(to)h(reduce)h(the)f(size)h(of)f(Magic)g(\(le)o(gac)o(y;)f (not)h(among)g(con\002gura-)244 3427 y(tion)f(choices\).)145 3635 y Fa(\017)49 b Ff(NO)p 394 3635 V 36 w(PLO)l(T)244 3756 y(Flag)25 b(to)f(eliminate)g(the)h(plot)f(module,)f(to)i(reduce)g (the)g(size)g(of)f(Magic.)145 3964 y Fa(\017)49 b Ff(NO)p 394 3964 V 36 w(R)l(OUTE)244 4085 y(Flag)25 b(to)f(eliminate)g(the)h (router)f(modules,)g(to)g(reduce)i(the)e(size)h(of)g(Magic.)145 4293 y Fa(\017)49 b Ff(NO)p 394 4293 V 36 w(SIM)244 4413 y(Flag)25 b(to)f(eliminate)g(the)h(sim)f(module,)f(to)i(reduce)g(the)g (size)g(of)f(Magic.)145 4622 y Fa(\017)49 b Ff(NO)p 394 4622 V 36 w(SCHEME)p 834 4622 V 36 w(INTERPRETER)244 4742 y(Flag)25 b(to)f(eliminate)g(the)h(\223scheme\224)g(command-line)e (interpreter)-5 b(.)145 4951 y Fa(\017)49 b Ff(USE)p 438 4951 V 36 w(READLINE)244 5071 y(Flag)25 b(to)f(include)h(the)f(GNU) h(\223readline\224)g(package.)145 5280 y Fa(\017)49 b Ff(OLD)p 455 5280 V 35 w(DO)l(T)p 691 5280 V 36 w(MA)l(GIC)244 5400 y(Flag)25 b(indicating)e(use)i(of)g(the)g(original)e(\(backw)o (ardly)i(compatible\))f(system)g(startup)g(\223)p Fd(.magic)p Ff(\224)h(\002le.)1850 5649 y(\22613\226)p eop %%Page: 14 14 14 13 bop 0 -180 a Ff(September)25 b(26,)f(2001)630 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#1:)30 b(Installation)23 b(and)i(De)n(v)o(elopment)145 67 y Fa(\017)49 b Ff(LLNL)244 187 y(Flag)30 b(to)f(incorporate)g(La)o(wrence)h(Li)n(v)o(ermore)e(e)o (xtensions,)h(including)f(an)h(area)i(router)l(,)f(ne)n(w)f(channel)244 307 y(router)l(,)c(and)f(stretch)h(graphs)f(\(e)o(xperimental;)g(not)g (among)g(con\002guration)g(choices\).)0 670 y Fe(7.4)119 b(Deb)n(ugging)31 b(Compiletime)f(Options)145 879 y Fa(\017)49 b Ff(CELLDEB)o(UG)244 1000 y(Deb)n(ugging)24 b(\003ag)h(for)g(the)g (database)g(module.)145 1256 y Fa(\017)49 b Ff(COUNTWIDTHCALLS)244 1376 y(Deb)n(ugging)24 b(\003ag)h(for)g(the)g(plo)n(w)e(module.)145 1632 y Fa(\017)49 b Ff(DEB)o(UGWIDTH)244 1752 y(Deb)n(ugging)24 b(\003ag)h(for)g(the)g(plo)n(w)e(module.)145 2008 y Fa(\017)49 b Ff(DRCR)l(ULESHIST)n(O)244 2129 y(Deb)n(ugging/tuning)22 b(\003ag)j(for)g(the)g(drc)g(module.)145 2385 y Fa(\017)49 b Ff(FREEDEB)o(UG)244 2505 y(Memory)24 b(allocation)g(deb)n(ugging)f (\003ag.)145 2761 y Fa(\017)49 b Ff(MALLOCMEASURE)244 2881 y(Memory)24 b(allocation)g(deb)n(ugging)f(\003ag.)145 3137 y Fa(\017)49 b Ff(MALLOCTRA)l(CE)244 3258 y(Memory)24 b(allocation)g(deb)n(ugging)f(\003ag.)145 3514 y Fa(\017)49 b Ff(NOMA)l(CR)l(OS)244 3634 y(Memory)24 b(allocation)g(deb)n(ugging)f (\003ag.)145 3890 y Fa(\017)49 b Ff(P)-9 b(AINTDEB)o(UG)244 4010 y(Deb)n(ugging)24 b(\003ag)h(for)g(the)g(database)g(painting)e (routines.)145 4266 y Fa(\017)49 b Ff(P)-9 b(ARANOID)244 4387 y(Flag)32 b(to)f(enable)g(consistenc)o(y)f(checking.)51 b(W)l(ith)30 b(a)i(system)e(the)i(comple)o(xity)d(of)j(Magic,)g(you)f (should)244 4507 y(al)o(w)o(ays)24 b(lea)n(v)o(e)h(this)f(\003ag)h (turned)g(on)f(\(set)h(automatically)e(by)i(the)f Fd(:con\002g)i Ff(script\).)0 4914 y Fh(8)143 b(T)-13 b(echnology)33 b(and)i(Other)g(Support)f(Files)0 5159 y Ff(Besides)e(the)h(source)f (code)h(\002les,)h(there)f(are)g(a)g(number)f(of)g(other)h(\002les)f (that)g(must)g(be)g(managed)g(by)g(Magic)0 5280 y(maintainers,)i (including)e(color)h(maps,)i(technology)d(\002les,)j(and)e(other)g (stuf)n(f.)56 b(Belo)n(w)33 b(is)f(a)i(listing)d(of)j(those)0 5400 y(\002les)25 b(and)g(where)g(the)o(y)f(are)i(located.)1850 5649 y(\22614\226)p eop %%Page: 15 15 15 14 bop 0 -180 a Ff(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#1:)30 b(Installation)24 b(and)g(De)n(v)o(elopment)628 b(September)25 b(26,)g(2001)0 82 y Fe(8.1)119 b(T)-11 b(echnology)30 b(Files)0 270 y Ff(See)36 b(\223Magic)f(Maintainer')-5 b(s)34 b(Manual)h(#2:)51 b(The)35 b(T)-7 b(echnology)35 b(File\224)g(for)h(information)e(on)h(the)g(contents)f(of)0 390 y(technology)29 b(\002les.)45 b(The)30 b(sources)g(for)g (technology)f(\002les)h(are)g(contained)f(in)h(the)f(subdirectory)g Fd(tech)p Ff(,)k(in)c(\002les)0 511 y(lik)o(e)38 b Fd(scmos.tech)i Ff(and)e Fd(nmos.tech)p Ff(.)74 b(The)39 b(technology)e(\002les)i(that) g(Magic)f(actually)g(uses)h(at)g(runtime)e(are)0 631 y(k)o(ept)30 b(in)g(the)g(directory)h Fd($)p Fa(f)p Fd(CAD)p 1174 631 30 4 v 35 w(HOME)p Fa(g)p Fd(/lib/magic/sys)p Ff(;)p Fd(mak)o(e)d(install)h Ff(in)i Fd(tech)g Ff(will)f(cop)o(y)g (the)g(sources)0 752 y(to)g Fd($)p Fa(f)p Fd(CAD)p 430 752 V 36 w(HOME)p Fa(g)p Fd(/lib/magic/sys)p Ff(.T)-7 b(echnology)27 b(\002le)k(formats)f(ha)n(v)o(e)g(e)n(v)n(olv)o(ed)g (rapidly)g(during)g(Magic')-5 b(s)0 872 y(life,)40 b(so)c(we)i(use)f(v) o(ersion)e(numbers)i(to)f(allo)n(w)g(multiple)f(formats)i(of)g (technology)f(\002les)h(to)f(e)o(xist)g(at)h(once.)0 992 y(The)e(installed)f(v)o(ersions)g(of)i(technology)e(\002les)h(ha)n (v)o(e)g(names)g(lik)o(e)g Fd(nmos.tech27)p Ff(,)k(where)d Fd(27)f Ff(is)g(a)g(v)o(ersion)0 1113 y(number)-5 b(.)61 b(The)35 b(current)h(v)o(ersion)e(is)h(de\002ned)h(in)e(the)i(Mak)o (e\002le)f(for)h Fd(tech)p Ff(,)j(and)c(should)f(be)h(incremented)g(if) 0 1233 y(you)29 b(e)n(v)o(er)g(change)h(the)f(format)g(of)h(technology) e(\002les;)k(if)d(you)g(install)f(a)i(ne)n(w)f(format)g(without)f (changing)h(the)0 1353 y(v)o(ersion)24 b(number)l(,)g(pre-e)o(xisting)f (v)o(ersions)g(of)i(Magic)f(w)o(on')n(t)h(be)g(able)f(to)h(read)g(the)f (\002les.)31 b(After)25 b(incrementing)0 1474 y(the)39 b(v)o(ersion)f(number)l(,)k(you')o(ll)c(also)g(ha)n(v)o(e)h(to)f (re-mak)o(e)i(the)f Fd(tech)h Ff(module)e(since)g(the)h(v)o(ersion)f (number)h(is)0 1594 y(referenced)26 b(by)f(the)f(code)h(that)g(reads)g (the)g(\002les.)0 1887 y Fe(8.2)119 b(Display)30 b(Styles)0 2074 y Ff(The)g(display)f(style)g(\002le)i(sources)f(are)h(contained)e (in)h(the)g(source)g(directory)g Fd(graphics)p Ff(.)47 b(See)31 b(\223Magic)f(Main-)0 2195 y(tainer')-5 b(s)28 b(Manual)f(#3:)37 b(The)29 b(Display)e(Style)h(and)g(Glyph)g(Files\224) g(and)g(the)g(manual)g(page)g Fg(dstyle)g Ff(\(5\))h(for)f(a)h(de-)0 2315 y(scription)18 b(of)h(their)f(contents.)28 b Fd(Mak)o(e)19 b(install)f Ff(in)h Fd(graphics)g Ff(will)f(cop)o(y)h(the)f(\002les)h (to)g Fd($)p Fa(f)p Fd(CAD)p 3208 2315 V 35 w(HOME)p Fa(g)p Fd(/lib/magic/sys)p Ff(,)0 2435 y(which)24 b(is)h(where)g(Magic) f(looksfor)g(them)h(when)f(it)h(e)o(x)o(ecutes.)0 2728 y Fe(8.3)119 b(Glyph)31 b(Files)0 2915 y Ff(Glyph)d(\002les)g(are)i (described)e(in)g(Maintainer')-5 b(s)28 b(Manual)g(#3)g(and)g(the)h (manual)f(page)h Fg(glyphs)e Ff(\(5\);)k(the)o(y)d(de\002ne)0 3036 y(patterns)e(that)h(appear)h(in)e(the)h(cursor)-5 b(.)37 b(The)27 b(sources)f(for)i(glyph)e(\002les)h(appear)g(in)g(tw)o (o)f(places:)35 b(some)27 b(of)g(them)0 3156 y(are)20 b(in)e Fd(graphics)p Ff(,)i(in)f(\002les)g(lik)o(e)f Fd(color)-10 b(.glyphs)p Ff(,)20 b(and)f(some)f(others)g(are)i (de\002ned)f(in)f Fd(windo)o(ws/windo)o(w)p Fg(XX)p Fd(.glyphs)p Ff(.)0 3276 y(When)h(you)f Fd(mak)o(e)i(install)e Ff(in)g(those)g (directories,)i(the)f(glyphs)e(are)j(copied)e(to)h Fd($)p Fa(f)p Fd(CAD)p 3015 3276 V 35 w(HOME)p Fa(g)p Fd(/lib/magic/sys)p Ff(,which)0 3397 y(is)24 b(where)i(Magic)e(looks)g(for)h(them)f(when)h (it)f(e)o(x)o(ecutes.)0 3689 y Fe(8.4)119 b(Color)30 b(Maps)0 3877 y Ff(The)38 b(color)g(map)g(sources)g(are)h(also)f (contained)g(in)g(the)g(source)g(directory)g Fd(graphics)p Ff(.)71 b(Color)39 b(maps)e(ha)n(v)o(e)0 3997 y(names)26 b(lik)o(e)g Fd(mos.7bit.std.cmap)p Ff(,)h(where)g Fd(mos)f Ff(is)g(the)g(name)g(of)h(the)f(technology)f(style)h(to)g(which)g(the)g (color)0 4117 y(map)35 b(applies,)j Fd(7bit)e Ff(is)f(the)g(display)g (style,)j(and)d Fd(std)h Ff(is)f(a)h(type)g(of)g(monitor)-5 b(.)61 b(If)36 b(monitors)e(ha)n(v)o(e)h(radically)0 4238 y(dif)n(ferent)j(phosphors,)i(the)o(y)d(may)h(require)g(dif)n (ferent)g(color)g(maps)f(to)h(achie)n(v)o(e)f(the)h(same)g(af)n(fects.) 71 b(Right)0 4358 y(no)n(w)31 b(we)g(only)g(support)f(the)i Fd(std)g Ff(kind)e(of)i(monitor)-5 b(.)49 b(When)31 b(Magic)g(e)o(x)o (ecutes,)h(it)f(looks)g(for)g(color)h(maps)e(in)0 4479 y Fd($)p Fa(f)p Fd(CAD)p 322 4479 V 35 w(HOME)p Fa(g)p Fd(/lib/magic/sys)p Ff(;)p Fd(mak)o(e)e(install)i Ff(in)g Fd(graphics)h Ff(will)f(cop)o(y)g(them)g(there.)48 b(Although)29 b(color)0 4599 y(map)19 b(\002les)g(are)h(te)o(xtual,)f(editing)e(by)i (hand)g(is)g(undesirable;)h(use)f(Magic')-5 b(s)18 b(color)h(map)f (editing)g(windo)n(w)g(instead.)0 4936 y Fh(9)143 b(New)35 b(Display)f(Dri)o(v)o(ers)0 5159 y Ff(The)24 b(most)e(common)g(kind)h (of)h(change)f(that)h(will)e(be)i(made)f(to)g(Magic)h(is)f(probably)g (to)g(adapt)g(it)g(for)h(ne)n(w)f(kinds)0 5280 y(of)37 b(color)g(displays.)67 b(Each)37 b(display)f(dri)n(v)o(er)g(contains)g (a)i(standard)f(collection)f(of)h(procedures)g(to)g(perform)0 5400 y(basic)24 b(functions)f(such)h(as)g(placing)g(te)o(xt,)f(dra)o (wing)g(\002lled)h(rectangles,)g(or)h(changing)e(the)h(shape)g(of)h (the)f(cursor)-5 b(.)1850 5649 y(\22615\226)p eop %%Page: 16 16 16 15 bop 0 -180 a Ff(September)25 b(26,)f(2001)630 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#1:)30 b(Installation)23 b(and)i(De)n(v)o(elopment)0 69 y(A)h(table)f(\(de\002ned)h(in)g Fd(graphics/grMain.c)p Ff(\))g(holds)f(the)g(addresses)h(of)f(the)h (routines)f(for)h(the)f(current)h(display)0 189 y(dri)n(v)o(er)-5 b(.)28 b(At)20 b(initialization)e(time)h(this)g(table)h(is)g(\002lled)g (in)g(with)f(the)h(addresses)g(of)g(the)h(routines)e(for)h(the)g (particular)0 309 y(display)k(being)g(used.)30 b(All)25 b(graphics)f(calls)h(pass)f(through)g(the)h(table.)146 430 y(If)f(you)f(ha)n(v)o(e)g(a)g(display)f(other)i(than)e(the)i(ones)f (currently)g(de\002ned)g(\(X11,)g(OpenGL/GLX,)g(SunV)-6 b(ie)n(w)g(,)22 b(and)0 550 y(the)f(le)o(gac)o(y)f(X10)h(and)g(AED)g (dri)n(v)o(ers\),)f(and)i(you)e(w)o(ant)h(to)g(b)n(uild)f(a)i(ne)n(w)e (display)g(dri)n(v)o(er)l(,)h(we)h(recommend)e(start-)0 671 y(ing)k(with)g(the)g(routines)g(for)h(the)f(X11)g(\(all)h(the)f (\002les)h(in)f Fd(graphics)h Ff(named)f Fd(grX11su)p Fg(n)p Fd(.c)p Ff(\),)h(or)f(the)h(Sun)f(\(named)0 791 y Fd(grSunW)p Fg(n)p Fd(.c)p Ff(\).)32 b(Cop)o(y)25 b(the)f(\002les)h (into)f(a)h(ne)n(w)g(set)f(for)h(your)g(display)-6 b(,)23 b(change)i(the)f(names)h(of)g(the)f(routines,)g(and)0 911 y(modify)30 b(them)f(to)i(perform)f(the)h(equi)n(v)n(alent)d (functions)i(on)g(your)h(display)-6 b(.)46 b(Write)31 b(an)f(initialization)f(routine)0 1032 y(lik)o(e)i Fd(x11suSetDisplay)p Ff(,)h(and)f(add)g(information)f(to)g(the)h(display)f(type)h(tables)g (in)f Fd(graphics/grMain.c)p Ff(.)50 b(At)0 1152 y(this)31 b(point)g(you)h(should)f(be)i(all)f(set.)52 b(There)33 b(shouldn')n(t)e(be)h(an)o(y)g(need)g(to)g(modify)f(an)o(ything)g (outside)g(of)h(the)0 1272 y(graphics)24 b(module.)146 1393 y(The)i(signi\002cant)f(dif)n(ference)h(between)g(the)g(X11)f(dri) n(v)o(er)g(and)h(the)g(Sun)g(dri)n(v)o(er)f(depends)g(on)g(the)h (nature)g(of)0 1513 y(the)d(serv)o(er:)29 b(The)23 b(X11)g(serv)o(er)g (polls)e(for)j(ne)n(w)e(e)n(v)o(ents,)g(and)h(the)g(typical)f(\223main) g(loop\224)h(of)g(an)g(X11)f(application)0 1634 y(is)28 b(a)h(call)g(to)f Fd(XtMainLoop\(\))i Ff(which)f(ne)n(v)o(er)f(e)o (xits.)41 b(This)28 b(presents)g(a)h(problem)f(for)h(Magic,)h(which)e (is)g(inter)n(-)0 1754 y(rupt)i(dri)n(v)o(en,)h(a)h(choice)f(made)f (due)h(to)g(the)g(lar)n(ge)g(amount)f(of)h(internal)f(processing)g (\(e.g.,)j(interacti)n(v)o(e)c(DRC)0 1874 y(checking\))34 b(as)h(compared)f(to)g(the)g(small)g(amount)f(of)i(user)f(input)g (\(e.g.,)i(k)o(e)o(ystrok)o(es)e(and)g(mouse)g(b)n(uttons\).)0 1995 y(Magic)24 b(has)h(its)f(o)n(wn)g(blocking)f(loop,)h(which)g(is)h (a)g(call)f(to)h Fd(select)p Ff(\),)g(a)g(routine)f(which)g (continuously)f(polls)g(I/O)0 2115 y(de)n(vices)f(for)h(interrupts.)28 b(Because)c(X11)e(\(at)h(least)f(up)g(to)g(and)g(including)f(the)h(R6)h (v)o(ersion\))f(is)g(not)g(thread-safe,)0 2236 y(these)29 b(tw)o(o)f(loops)g(cannot)h(be)g(threads.)43 b(The)29 b(only)f(remaining)g(possibility)e(is)j(to)f(mak)o(e)h(the)g(X11)g (main)f(loop)0 2356 y(run)k(as)h(a)g(separate)f(process)h(\(in)f(the)g (case)h(of)g(X11,)g(called)g(\223X11Helper\224\),)h(capture)f(rele)n(v) n(ant)f(X)g(protocol)0 2476 y(messages)h(for)h(the)g(Magic)f(windo)n(w) -6 b(,)34 b(and)f(transmit)g(the)g(information)g(to)g(the)g(Magic)h (process)f(through)g(an)0 2597 y(I/O)f(pipe)h(\(the)f(use)h(of)f(which) g(triggers)g(the)h(I/O)f(interrupt)g(and)h(breaks)f(the)h Fd(select\(\))g Ff(loop\).)53 b(This)32 b(method)0 2717 y(has)24 b(certain)h(dra)o(wbacks,)e(the)h(main)g(one)g(being)g(that)g (if)g(Magic)g(crashes)g(for)h(an)o(y)e(reason,)i(the)f(helper)g (process)0 2837 y(remains)g(hanging)g(until)g(killed)g(by)g(hand)h(or)g (by)f(a)h(system)f(reboot.)146 2958 y(The)k(Sun)h(interf)o(ace)f(mak)o (es)g(graphics)g(calls)g(as)g(requested,)h(which)f(mak)o(es)f (implementation)f(for)i(Magic)0 3078 y(much)i(simpler)g(than)h(X11,)h (b)n(ut)f(consequently)f(pre)n(v)o(ents)f(remote)i(display)f(operation) g(and)h(ef)n(\002cient)g(multi-)0 3199 y(tasking,)24 b(the)g(major)h(reasons)f(for)h(X11')-5 b(s)24 b(success.)146 3319 y(Note)32 b(that)g(an)o(y)f(graphics)h(interf)o(aces)g(based)g(on) g Fg(thr)l(ead-safe)f Ff(graphics)h(systems)e(\(e.g.,)k(W)l(indo)n(ws)d (NT)-7 b(,)0 3439 y(and)25 b(hopefully)f(X11R7,)h(if)g(it)f(e)n(v)o(er) h(happens\))f(can)i(reduce)f(the)g(graphics)g(interf)o(ace)g(comple)o (xity)e(by)i(running)0 3560 y(the)g(X11)f(e)n(v)o(ent)g(handler)h(as)f (a)i(detached)f(thread.)0 3895 y Fh(10)143 b(Deb)m(ugging)34 b(and)h(W)m(izard)g(Commands)0 4119 y Ff(Magic)h(w)o(orks)g(\002ne)g (under)g(the)g(latest)g(v)o(ersions)f(of)h(dbx)g(and)g(GNU)g(gdb)l(.)64 b(The)37 b(Mak)o(e\002les)f(are)h(set)f(up)f(to)0 4239 y(compile)24 b(all)g(\002les)h(with)f(the)h Fd(-g)g Ff(switch,)f(which) g(creates)i(deb)n(ugging)d(information.)146 4359 y(In)k(the)f(past,)g (memory)g(and)g(speed)g(limitations)e(made)i(it)g(useful)g(to)g (include)f(a)i(\003ag,)g(found)f(in)g(script)g Fd(:in-)0 4480 y(stmodule)p Ff(,)d(to)f(strip)g(the)g(deb)n(ugging)f(symbols)f (from)i(the)g(object)g(\002les)g(when)g(linking)f(the)h(Magic)g(e)o(x)o (ecutable.)0 4600 y(Modern)h(systems)e(are)j(f)o(ast)f(and)g(ha)n(v)o (e)g(copious)f(amounts)g(of)h(both)f(system)g(memory)g(and)h(disk)g (space,)g(so)g(this)0 4721 y(option)h(is)g(set)g(to)h(\223NO\224)g(in)g (the)f(script.)146 4841 y(There)h(are)f(a)g(number)g(of)g(commands)e (that)i(we)g(implemented)e(in)i(Magic)f(to)h(assist)f(in)g(deb)n (ugging.)29 b(These)0 4961 y(commands)f(are)j(called)e Fg(wizar)l(d)g(commands)p Ff(,)h(and)g(aren')n(t)g(visible)e(to)h (normal)g(Magic)h(users.)44 b(The)o(y)29 b(all)g(start)0 5082 y(with)j(\223)p Fd(*)p Ff(\224.)54 b(T)-8 b(o)33 b(get)f(terse)h(online)f(help)g(for)h(the)f(wizard)h(commands,)g(type)g Fd(:help)g(wizard)g Ff(to)f(Magic.)54 b(The)0 5202 y(wizard)25 b(commands)f(aren')n(t)h(documented)f(v)o(ery)g(well.)31 b(Some)25 b(of)f(the)h(more)g(useful)f(ones)h(are:)145 5400 y Fa(\017)49 b Fd(*watch)25 b Fg(plane)1850 5649 y Ff(\22616\226)p eop %%Page: 17 17 17 16 bop 0 -180 a Ff(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#1:)30 b(Installation)24 b(and)g(De)n(v)o(elopment)628 b(September)25 b(26,)g(2001)244 68 y(This)30 b(causes)h(Magic)g(to)f (display)g(on)h(the)f(screen)i(the)f(corner)n(-stitched)f(tile)h (structure)f(for)h(one)g(of)g(the)244 188 y(planes)25 b(of)g(the)f(edit)h(cell.)31 b(F)o(or)25 b(e)o(xample,)f Fd(*watch)i(subcell)f Ff(will)f(display)g(the)h(structure)g(of)g(the)g (subcell)244 309 y(tile)19 b(plane,)h(including)e(the)h(address)h(of)f (the)g(record)h(for)g(each)g(tile)f(and)g(the)g(v)n(alues)g(of)h(its)e (corner)i(stitches.)244 429 y(W)l(ithout)26 b(this)g(command)h(it)g(w)o (ould)f(ha)n(v)o(e)h(been)h(virtually)e(impossible)f(to)i(deb)n(ug)g (the)g(database)h(mod-)244 549 y(ule.)145 753 y Fa(\017)49 b Fd(*pr)n(o\002le)26 b(on)p Ff(\227)p Fd(off)244 873 y Ff(If)31 b(you')-5 b(re)30 b(using)g(the)g(Unix)f(pro\002ling)h (tools)f(to)h(\002gure)h(out)f(where)h(the)f(c)o(ycles)g(are)h(going,)g (this)e(com-)244 994 y(mand)20 b(can)g(be)h(used)f(to)g(turn)g (pro\002ling)f(of)n(f)h(for)h(e)n(v)o(erything)d(e)o(xcept)i(the)h (particular)f(operation)f(you)h(w)o(ant)244 1114 y(to)31 b(measure.)53 b(This)31 b(command)g(doesn')n(t)g(w)o(ork)h(on)g(man)o (y)f(systems,)h(because)g(the)g(operating)f(system)244 1234 y(doesn')n(t)24 b(support)g(selecti)n(v)o(e)g(enabling)g(and)g (disabling)g(of)g(pro\002ling.)145 1438 y Fa(\017)49 b Fd(*runstats)244 1558 y Ff(This)22 b(command)g(prints)g(out)g(the)h (CPU)g(time)f(usage)h(since)g(the)f(last)h(in)l(v)n(ocation)e(of)i (this)f(command,)g(and)244 1679 y(also)i(the)h(total)f(since)h (starting)e(Magic.)145 1882 y Fa(\017)49 b Fd(*see\003ags)25 b Fg(\003a)o(g)244 2002 y Ff(If)j(you')-5 b(re)27 b(w)o(orking)g(on)g (the)h(router)l(,)g(this)e(command)h(allo)n(ws)f(you)h(to)g(see)h(the)f (v)n(arious)g(channel)g(router)244 2123 y(\003ags)19 b(by)g(displaying)e(them)i(as)g(feedback)h(areas.)29 b(The)19 b(cursor)g(should)f(\002rst)i(be)f(placed)g(o)o(v)o(er)f(the)h (channel)244 2243 y(whose)24 b(\003ags)h(you)g(w)o(ant)f(to)h(see.)0 2583 y Fh(A)143 b(Serial-Line)33 b(Graphics)h(Displays)0 2806 y Ff(This)h(section)f(remains)h(for)h(information)e(re)o(garding)g (the)h(serial-line)g(graphics)g(dri)n(v)o(er)-5 b(.)61 b(Although)33 b(totally)0 2927 y(outdated,)g(these)e(are)i(the)f (simplest)e(graphics)h(dri)n(v)o(er)g(routines,)i(and)f(at)g(least)f (for)i(no)n(w)e(are)h(w)o(orth)g(k)o(eeping)0 3047 y(around)25 b(for)g(reference,)h(particularly)e(when)h(attempting)e(to)h(implement) f(a)j(ne)n(w)e(graphics)g(dri)n(v)o(er)-5 b(.)146 3167 y(Serial-line)39 b(displays)e(require)i(some)f(additional)f(setup.)71 b(If)39 b(the)g(display)e(is)h(an)h(AED512)f(or)g(similar)0 3288 y(display)-6 b(,)31 b(it)g(will)g(be)g(attached)g(to)g(the)g (mainframe)g(via)h(an)f(RS232)h(port.)50 b(Magic)31 b(needs)g(to)g(be)g (able)h(to)f(read)0 3408 y(from)d(this)g(port,)h(and)f(there)h(are)g (tw)o(o)f(w)o(ays)g(to)g(do)g(this.)41 b(The)28 b(\002rst)h(is)f (simply)f(to)h(ha)n(v)o(e)g(no)g(login)g(process)g(for)0 3528 y(that)h(port)f(and)h(ha)n(v)o(e)g(your)f(system)g(administrator)g (change)h(the)g(protection)f(to)g(allo)n(w)g(all)h(processes)g(to)g (read)0 3649 y(from)34 b(the)h(port)f(and)g(write)h(to)f(it.)59 b(The)35 b(second)f(w)o(ay)h(is)f(to)g(ha)n(v)o(e)g(users)h(log)f(in)g (on)g(the)g(display)g(and)g(run)h(a)0 3769 y(process)c(that)f(changes)h (the)g(protection)f(of)h(the)g(display)-6 b(.)47 b(There)32 b(is)e(a)h(program)g(called)g Fd(sleeper)h Ff(distrib)n(uted)0 3890 y(with)h(Magic)g(v)o(ersions)g(6.5.1)g(and)g(earlier;)39 b(if)33 b(it')-5 b(s)33 b(run)h(from)f(an)h(AED)f(port)h(it)f(will)g (set)g(e)n(v)o(erything)f(up)h(so)0 4010 y(Magic)25 b(can)i(use)e(the)h (port.)33 b Fd(sleeper)27 b Ff(is)e(clumsy)g(to)g(use,)h(so)g(we)g (recommend)f(that)g(you)h(use)f(the)h(\002rst)g(solution)0 4130 y(\(no)f(login)e(process\).)146 4251 y(When)35 b(you')-5 b(re)35 b(running)e(on)i(mainframes,)h(Magic)e(will)g(need)h(to)f(kno)n (w)f(which)h(color)h(display)e(port)h(to)0 4371 y(use)e(from)g(each)h (terminal)e(port.)53 b(Users)32 b(can)h(type)f(this)f(information)g(as) h(command-line)f(switches)g(b)n(ut)h(it')-5 b(s)0 4492 y(clumsy)f(.)28 b(T)-8 b(o)23 b(simplify)e(things,)h(Magic)h(checks)g (the)f(\002le)h Fd(\230cad/lib/displays)g Ff(when)f(it)h(starts)f(up.) 30 b(The)22 b(displays)0 4612 y(\002le)32 b(tells)f(which)h(color)f (display)g(port)h(to)f(use)h(for)g(which)g(te)o(xt)e(terminal)h(port)h (and)g(also)f(tells)g(what)h(kind)f(of)0 4732 y(display)21 b(is)h(attached.)30 b(Once)22 b(this)f(\002le)i(is)f(set)g(up,)g(users) g(can)g(run)h(Magic)e(without)g(w)o(orrying)h(about)f(the)h(system)0 4853 y(con\002guration.)30 b(See)c(the)f(manual)f(page)h(for)g Fg(displays)e Ff(\(5\).)146 4973 y(One)g(last)e(note:)29 b(if)23 b(you')-5 b(re)22 b(running)f(on)h(an)h(AED)f(display)-6 b(,)21 b(you')o(ll)g(need)i(to)f(set)g(communication)e(switches)0 5093 y(3-4-5)25 b(to)f(up-do)n(wn-up.)1850 5649 y(\22617\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tuttcl4.ps0000644000175000001440000014543410751423606015652 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvips(k) 5.95a Copyright 2005 Radical Eye Software %%Title: tuttcl4.dvi %%Pages: 8 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman Courier-Bold %%+ Courier CMSY10 CMR12 CMMI12 %%DocumentPaperSizes: Letter %%EndComments %DVIPSWebPage: (www.radicaleye.com) %DVIPSCommandLine: dvips -t letter tuttcl4.dvi -o ../psfiles/tuttcl4.ps %DVIPSParameters: dpi=600 %DVIPSSource: TeX output 2006.04.14:1844 %%BeginProcSet: tex.pro 0 0 %! /TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin /FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array /BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get }B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr 1 add N}if}B/CharBuilder{save 3 1 roll S A/base get 2 index get S /BitMaps get S get/Cd X pop/ctr 0 N Cdx 0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx sub Cy .1 sub]{Ci}imagemask restore}B/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put }if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X 1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N /p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ /Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) (LaserWriter 16/600)]{A length product length le{A length product exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end %%EndProcSet %%BeginProcSet: 8r.enc 0 0 % File 8r.enc TeX Base 1 Encoding Revision 2.0 2002-10-30 % % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry, % W. Schmidt, P. Lehman", % version = "2.0", % date = "30 October 2002", % filename = "8r.enc", % email = "tex-fonts@@tug.org", % docstring = "This is the encoding vector for Type1 and TrueType % fonts to be used with TeX. This file is part of the % PSNFSS bundle, version 9" % @} % % The idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard encoding, ISO Latin 1, Windows ANSI including the euro symbol, % MacRoman, and some extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % These are /dotlessj /ff /ffi /ffl. % % (4) hyphen appears twice for compatibility with both ASCII and Windows. % % (5) /Euro was assigned to 128, as in Windows ANSI % % (6) Missing characters from MacRoman encoding incorporated as follows: % % PostScript MacRoman TeXBase1 % -------------- -------------- -------------- % /notequal 173 0x16 % /infinity 176 0x17 % /lessequal 178 0x18 % /greaterequal 179 0x19 % /partialdiff 182 0x1A % /summation 183 0x1B % /product 184 0x1C % /pi 185 0x1D % /integral 186 0x81 % /Omega 189 0x8D % /radical 195 0x8E % /approxequal 197 0x8F % /Delta 198 0x9D % /lozenge 215 0x9E % /TeXBase1Encoding [ % 0x00 /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef /Zcaron /zcaron % 0x10 /caron /dotlessi /dotlessj /ff /ffi /ffl /notequal /infinity /lessequal /greaterequal /partialdiff /summation /product /pi /grave /quotesingle % 0x20 /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % 0x80 /Euro /integral /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /Omega /radical /approxequal % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /Delta /lozenge /Ydieresis % 0xA0 /.notdef /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndProcSet %%BeginProcSet: texps.pro 0 0 %! TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]FontType 0 ne{/Metrics exch def dict begin Encoding{exch dup type/integertype ne{ pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def}ifelse}forall Metrics/Metrics currentdict end def}{{1 index type /nametype eq{exit}if exch pop}loop}ifelse[2 index currentdict end definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{dup sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[ exch{dup CharStrings exch known not{pop/.notdef/Encoding true def}if} forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def}def end %%EndProcSet %%BeginFont: CMMI12 %!PS-AdobeFont-1.1: CMMI12 1.100 %%CreationDate: 1996 Jul 27 08:57:55 % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. 11 dict begin /FontInfo 7 dict dup begin /version (1.100) readonly def /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def /FullName (CMMI12) readonly def /FamilyName (Computer Modern) readonly def /Weight (Medium) readonly def /ItalicAngle -14.04 def /isFixedPitch false def end readonly def /FontName /CMMI12 def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 58 /period put dup 110 /n put readonly def /FontBBox{-30 -250 1026 750}readonly def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA0529731C99A784CCBE85B4993B2EEBDE 3B12D472B7CF54651EF21185116A69AB1096ED4BAD2F646635E019B6417CC77B 532F85D811C70D1429A19A5307EF63EB5C5E02C89FC6C20F6D9D89E7D91FE470 B72BEFDA23F5DF76BE05AF4CE93137A219ED8A04A9D7D6FDF37E6B7FCDE0D90B 986423E5960A5D9FBB4C956556E8DF90CBFAEC476FA36FD9A5C8175C9AF513FE D919C2DDD26BDC0D99398B9F4D03D6A8F05B47AF95EF28A9C561DBDC98C47CF5 5250011D19E9366EB6FD153D3A100CAA6212E3D5D93990737F8D326D347B7EDC 4391C9DF440285B8FC159D0E98D4258FC57892DCC57F7903449E07914FBE9E67 3C15C2153C061EB541F66C11E7EE77D5D77C0B11E1AC55101DA976CCACAB6993 EED1406FBB7FF30EAC9E90B90B2AF4EC7C273CA32F11A5C1426FF641B4A2FB2F 4E68635C93DB835737567FAF8471CBC05078DCD4E40E25A2F4E5AF46C234CF59 2A1CE8F39E1BA1B2A594355637E474167EAD4D97D51AF0A899B44387E1FD933A 323AFDA6BA740534A510B4705C0A15647AFBF3E53A82BF320DD96753639BE49C 2F79A1988863EF977B800C9DB5B42039C23EB86953713F730E03EA22FF7BB2C1 D97D33FD77B1BDCC2A60B12CF7805CFC90C5B914C0F30A673DF9587F93E47CEA 5932DD1930560C4F0D97547BCD805D6D854455B13A4D7382A22F562D7C55041F 0FD294BDAA1834820F894265A667E5C97D95FF152531EF97258F56374502865D A1E7C0C5FB7C6FB7D3C43FEB3431095A59FBF6F61CEC6D6DEE09F4EB0FD70D77 2A8B0A4984C6120293F6B947944BE23259F6EB64303D627353163B6505FC8A60 00681F7A3968B6CBB49E0420A691258F5E7B07B417157803FCBE9B9FB1F80FD8 CA0DA1186446DD565542BCCC7D339A1EB34C7F49246E8D72E987EB477C6DB757 99AF86CEBCD7605C487A00CD2CD093098182DC57B20D78ECE0BECF3A0BF88EBA C866DB19F34BBBED6634AFC0F08D2AFB2A92578A6F8B4ADCD6594737FF6EED7D 5B536DA9E3E2CADB40DB7C600EA4D100D33C3B92B1CF857E012C4EB370BA8295 55B50047CD58E912E67E22C1B92F41D0BEE742201DF1841098B2FDEF9E460667 C94DA8A259380B5C76A572D8B6B17B2F6CC25937DFC98BBF8BC5699C73122C23 1D18E692199499119235481C272FAAA88C8F00D17DA078B463489A0F16B98378 4C3E03B20E1E4DE2E33BE9539AE5452FF616A0D8E3C4043F344213FF08CB0072 EB840136F4FAFA24A106A14739CB0585B002FDE204C47DE9F2E77E3F64B8C6F0 84CEB054B5BE8ED33A3E479DCF3FFA00F1F208687F3C3D53BF9F76C9A67E65C6 B49AF14843F0F3D20D5E7FD32F0616A4ADB9CD24FB46951FB63067C82917282B 1A1A99AAFC38898B5403623DDF7483614A77850F4D223B47827538F3C6FF2E06 5951E570C6FBDBC926AD9D057DFC75B48767682C539AE1EC576582E09ACAA28A C7CB884E63EF5BB1C96767316BCA34975AFE146BC2F2AFFD9DF13AC8B7FCC9C2 55DF310FC646F5BB0C24CD7F96FF126141F42D5B62D65309F76643567C4A6EE0 BCE68B5EC3C0C3CEF644CE706CBC31CB91F3991B77A1DB2CDF4CF85034EF34E0 98EEC275802627DD7F1560E30A5E65485E49CE13C88A514569AD848E520AF44B 787133A0E662511B89FA6936E78F7652A3976C9A831C74C4EC704BCD381303A6 D33217E0C788E05DB861 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: CMR12 %!PS-AdobeFont-1.1: CMR12 1.0 %%CreationDate: 1991 Aug 20 16:38:05 % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. 11 dict begin /FontInfo 7 dict dup begin /version (1.0) readonly def /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def /FullName (CMR12) readonly def /FamilyName (Computer Modern) readonly def /Weight (Medium) readonly def /ItalicAngle 0 def /isFixedPitch false def end readonly def /FontName /CMR12 def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 48 /zero put dup 49 /one put readonly def /FontBBox{-34 -251 988 750}readonly def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA052A014267B7904EB3C0D3BD0B83D891 016CA6CA4B712ADEB258FAAB9A130EE605E61F77FC1B738ABC7C51CD46EF8171 9098D5FEE67660E69A7AB91B58F29A4D79E57022F783EB0FBBB6D4F4EC35014F D2DECBA99459A4C59DF0C6EBA150284454E707DC2100C15B76B4C19B84363758 469A6C558785B226332152109871A9883487DD7710949204DDCF837E6A8708B8 2BDBF16FBC7512FAA308A093FE5CF4E9D2405B169CD5365D6ECED5D768D66D6C 68618B8C482B341F8CA38E9BB9BAFCFAAD9C2F3FD033B62690986ED43D9C9361 3645B82392D5CAE11A7CB49D7E2E82DCD485CBA04C77322EB2E6A79D73DC194E 59C120A2DABB9BF72E2CF256DD6EB54EECBA588101ABD933B57CE8A3A0D16B28 51D7494F73096DF53BDC66BBF896B587DF9643317D5F610CD9088F9849126F23 DDE030F7B277DD99055C8B119CAE9C99158AC4E150CDFC2C66ED92EBB4CC092A AA078CE16247A1335AD332DAA950D20395A7384C33FF72EAA31A5B89766E635F 45C4C068AD7EE867398F0381B07CB94D29FF097D59FF9961D195A948E3D87C31 821E9295A56D21875B41988F7A16A1587050C3C71B4E4355BB37F255D6B237CE 96F25467F70FA19E0F85785FF49068949CCC79F2F8AE57D5F79BB9C5CF5EED5D 9857B9967D9B96CDCF73D5D65FF75AFABB66734018BAE264597220C89FD17379 26764A9302D078B4EB0E29178C878FD61007EEA2DDB119AE88C57ECFEF4B71E4 140A34951DDC3568A84CC92371A789021A103A1A347050FDA6ECF7903F67D213 1D0C7C474A9053866E9C88E65E6932BA87A73686EAB0019389F84D159809C498 1E7A30ED942EB211B00DBFF5BCC720F4E276C3339B31B6EABBB078430E6A09BB 377D3061A20B1EB98796B8607EECBC699445EAA866C38E02DF59F5EDD378303A 0733B90E7835C0AAF32BA04F1566D8161EA89CD4D14DDB953F8B910BFC8A7F03 5020F55EF8FC2640ADADA156F6CF8F2EB6610F7EE8874A26CBE7CD154469B9F4 ED76886B3FB679FFDEB59BB6C55AF7087BA48B75EE2FB374B19BCC421A963E15 FE05ECAAF9EECDF4B2715010A320102E6F8CCAA342FA11532671CCCC52875960 84CC1832A068F03077BAA0C4CB6EB8A6ACF53741914AD12120F8BE6F0A9A65BF 0C099B28A58F40BCC782438962B9EF94FFFD64B4825C08E2F64F1C494F2FE514 0206F432B586845DEE85C5A0D896A89F2EE07B93CB341DE53930F82AEAEBDD18 5005D096E36BF691DE22DBA7F5D63F1552AE0BC8E675E2FB600691535BC72BFD 8EF2B5B1D9076592E540D76A56C21F61A5E1ECBC18EE7E8C8F0990685A38A4E4 81C19C4FAD43B6EF537879E828101FE69AD179FB7CC15F0EE9069DB29C6AF70E E394970A078D99CB082DF51B9C3A31E1526A048FE477F3997E36AD2F35347039 69A74AB1D2628C6558105E71BB6C72688BE5BEAF2B23C36D3A55888C532A36F6 092870681F340FBD5D423AFA2397B20555AA1AFBE03502406375C7EE481A5E3C 34613F21902308BF1FDEAD4FDB076109F23871A698CE725652E1D5D77E34221B A51A11F44332CDC79C72ECBC9619AE171DAFDB333DBD89945282B9FC3B508932 F371F2420BD6A5D79632D5457202C7DCEADBF8769717290F99487E129A387169 0D5FA2EF8AA2FA629A0759E0BFDDCD68B8D686661203ECD52508DA082505C743 B87C5D944C2B40 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont %%BeginFont: CMSY10 %!PS-AdobeFont-1.1: CMSY10 1.0 %%CreationDate: 1991 Aug 15 07:20:57 % Copyright (C) 1997 American Mathematical Society. All Rights Reserved. 11 dict begin /FontInfo 7 dict dup begin /version (1.0) readonly def /Notice (Copyright (C) 1997 American Mathematical Society. All Rights Reserved) readonly def /FullName (CMSY10) readonly def /FamilyName (Computer Modern) readonly def /Weight (Medium) readonly def /ItalicAngle -14.035 def /isFixedPitch false def end readonly def /FontName /CMSY10 def /PaintType 0 def /FontType 1 def /FontMatrix [0.001 0 0 0.001 0 0] readonly def /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for dup 0 /minus put dup 102 /braceleft put dup 103 /braceright put readonly def /FontBBox{-29 -960 1116 775}readonly def currentdict end currentfile eexec D9D66F633B846A97B686A97E45A3D0AA052F09F9C8ADE9D907C058B87E9B6964 7D53359E51216774A4EAA1E2B58EC3176BD1184A633B951372B4198D4E8C5EF4 A213ACB58AA0A658908035BF2ED8531779838A960DFE2B27EA49C37156989C85 E21B3ABF72E39A89232CD9F4237FC80C9E64E8425AA3BEF7DED60B122A52922A 221A37D9A807DD01161779DDE7D31FF2B87F97C73D63EECDDA4C49501773468A 27D1663E0B62F461F6E40A5D6676D1D12B51E641C1D4E8E2771864FC104F8CBF 5B78EC1D88228725F1C453A678F58A7E1B7BD7CA700717D288EB8DA1F57C4F09 0ABF1D42C5DDD0C384C7E22F8F8047BE1D4C1CC8E33368FB1AC82B4E96146730 DE3302B2E6B819CB6AE455B1AF3187FFE8071AA57EF8A6616B9CB7941D44EC7A 71A7BB3DF755178D7D2E4BB69859EFA4BBC30BD6BB1531133FD4D9438FF99F09 4ECC068A324D75B5F696B8688EEB2F17E5ED34CCD6D047A4E3806D000C199D7C 515DB70A8D4F6146FE068DC1E5DE8BC570317AAEA74A842CFD26F9591866F5A0 9B4EAD7395F5196B36997F1D59E88165C94739E74C2B40820F8C972B175ED79D 87C9E323C3CDD5C2BEE6409017767534E19F45AFCE2C6687733451AD2E75D112 42040BADFF90F5FCF3F2901FDEA619E64D6D0C6028216A78E7C25112B0D34428 AE383A46C0FE7D29AE9EE114224EF9BB7DC731072DBE736AB1358F37610C3762 F266B1016768B04306F3AC083DAF863E78CA401B28090A92C6AFC4FC601C2397 A24426104896F5D2D2E7651942A70EE036A943E59D3554AE462B9E0911B58F75 4ACDA535B87CFE5614EFDA21855F6F9C1FC25D2DDF53A49D8DA9188F3D7D1769 E55F4B40B211D1ACB084C157CE1608A3781D134EC608C6A1A6F1FE1707BDB0CF B111D95C18D611BFA1535A6CC94EA264FE45347D40DCD5C5390D862AC6291D44 B007322C02AED356974E5BD9C2C434430E50DBE4020B35220345B9B8C287AF4C ACCAD84CF351FE3878C61BAE570D9188760BE493FDE2C9C551E4BCE313039C74 54EBF847327459041B7F6D9D0920034D7FFEF514EC312B6090B07BFFE3E74AE7 BC3740D3072C9A78B16EBBB3EDE20CB6E506F6B66E8780B5631CBDF7D8B54EF5 AE5CAD8129B6C75472F6DC7E90C0A5E0CEFC3588635BA402B64852A03C3BEA47 57D73980B741FF62395F39DAFA78047ECE96DE9715D7ABAC46F9922220A24686 CDF91735904661E52C5FC67A76609DA9D7843D2415599C53C8F4388F4262BC19 289DE84C70F67EB0A6329242865E0DBCFBDCCEE1E111F0D9AC3AD5BD4FCA1C39 2E3317FD91906802B79D7D08E27AEE0440CD9AE58CCCBC4F8630C3089F3B091F 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 cleartomark %%EndFont TeXDict begin 40258431 52099146 1000 600 600 (tuttcl4.dvi) @start /Fa 145[58 51[27 58[{}2 99.6264 /CMMI12 rf /Fb 206[49 49 48[{}2 99.6264 /CMR12 rf /Fc 152[50 50 101[77{}3 99.6264 /CMSY10 rf /Fd 134[60 60 1[60 60 60 60 60 60 60 60 60 60 60 2[60 60 60 60 60 60 60 60 60 9[60 60 1[60 60 60 3[60 60 3[60 1[60 1[60 60 1[60 60 3[60 1[60 60 60 60 60 60 60 1[60 60 60 60 60 60 60 60 2[60 60 60 3[60 60 34[{TeXBase1Encoding ReEncodeFont}56 99.6264 /Courier rf /Fe 133[60 1[60 60 60 60 60 60 60 1[60 60 60 60 60 60 1[60 60 60 60 60 60 60 60 60 3[60 1[60 6[60 60 60 2[60 1[60 60 3[60 60 1[60 60 60 60 60 7[60 3[60 60 60 60 60 60 60 60 60 60 7[60 60 35[{TeXBase1Encoding ReEncodeFont}51 99.6264 /Courier-Bold rf /Ff 136[72 50 55 33 39 44 2[50 55 83 28 55 1[28 55 50 1[44 55 44 1[50 12[66 7[66 9[66 7[33 58[{TeXBase1Encoding ReEncodeFont}22 99.6264 /Times-Bold rf /Fg 138[66 40 47 53 2[60 66 100 33 2[33 66 2[53 66 53 1[60 12[80 6[113 9[86 8[40 55[66 2[{TeXBase1Encoding ReEncodeFont}19 119.552 /Times-Bold rf /Fh 64[44 29[33 10[50 1[44 44 24[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 33 2[33 1[33 1[72 72 94 72 72 61 55 66 1[55 72 72 89 61 1[39 33 72 72 55 61 72 66 66 72 1[44 3[28 28 50 50 50 50 50 50 50 50 50 50 28 25 33 25 2[33 33 33 2[50 50 1[33 29[55 55 2[{TeXBase1Encoding ReEncodeFont} 82 99.6264 /Times-Roman rf /Fi 134[44 1[66 44 50 28 39 39 1[50 50 50 72 28 2[28 50 50 28 44 50 44 50 50 5[39 6[55 50 61 3[66 83 3[33 3[61 22[25 33 25 2[33 33 2[83 1[50 35[{TeXBase1Encoding ReEncodeFont}36 99.6264 /Times-Italic rf /Fj 133[64 72 1[104 72 80 48 56 64 80 80 72 80 120 40 80 1[40 80 72 48 64 80 64 80 72 9[143 104 1[96 80 104 4[135 3[56 1[112 88 1[104 104 96 104 6[48 72 72 72 72 72 72 72 72 72 2[36 10[72 35[{TeXBase1Encoding ReEncodeFont}49 143.462 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%BeginPaperSize: Letter letter %%EndPaperSize end %%EndSetup %%Page: 1 1 TeXDict begin 1 0 bop 518 101 a Fj(Magic)35 b(Tcl)g(T)-13 b(utorial)34 b(#4:)44 b(Simulation)33 b(with)i(IRSIM)1546 521 y Fi(R.)25 b(T)-5 b(imothy)24 b(Edwar)l(ds)1583 941 y Fh(Space)i(Department)1434 1062 y(Johns)e(Hopkins)g(Uni)n(v)o(ersity) 1391 1182 y(Applied)g(Physics)g(Laboratory)1578 1303 y(Laurel,)h(MD)f(20723)819 1573 y(This)g(tutorial)g(corresponds)g(to)h (Tcl-based)f(Magic)h(v)o(ersion)e(7.2)0 2070 y Fg(T)-11 b(utorials)30 b(to)f(r)n(ead)h(\002rst:)300 2251 y Fh(Magic)24 b(T)l(utorial)g(#1:)30 b(Getting)24 b(Started)300 2371 y(Magic)g(T)l(utorial)g(#2:)30 b(Basic)25 b(P)o(ainting)f(and)h (Selection)300 2492 y(Magic)f(T)l(utorial)g(#4:)30 b(Cell)25 b(Hierarchies)300 2612 y(Magic)f(T)l(utorial)g(#8:)30 b(Circuit)25 b(Extraction)300 2732 y(Magic)f(T)l(utorial)g(#11:)30 b(Using)24 b(IRSIM)h(and)g(RSIM)h(with)e(Magic)0 2913 y Fg(Commands)29 b(intr)n(oduced)j(in)f(this)f(tutorial:)300 3093 y Fh(irsim)24 b(,)h(getnode,)f(goto)300 3213 y(graphnode,)g(w)o (atchnode,)h(unw)o(atchnode)300 3334 y(mo)o(v)o(enode,)e(w)o(atchtime,) h(unw)o(atchtime,)f(mo)o(v)o(etime)300 3454 y Fi(\(plus)h(the)h (standar)l(d)e(IRSIM)i(command)f(set\))0 3634 y Fg(Macr)n(os)29 b(intr)n(oduced)i(in)g(this)f(tutorial:)300 3832 y Fi(\(None\))0 4394 y Fj(1)143 b(IRSIM)35 b(V)-14 b(ersion)34 b(9.6)0 4618 y Fh(In)28 b(v)o(ersion)e(9.6,)i(IRSIM)h(has)e(been)h(redesigned)f (to)h(w)o(ork)f(under)h(the)f(Tcl)h(interpreter)l(,)g(in)f(the)h(same)f (manner)0 4738 y(as)g(Magic)g(v)o(ersion)g(7.2)g(does.)38 b(Lik)o(e)27 b(Magic)g(v)o(ersion)f(7.2,)i(section)e(of)i(Tcl)f(as)h (an)f(interpreter)h(is)e(speci\002ed)i(at)0 4859 y(compile-time,)j (along)g(with)g(v)n(arious)f(use)i(options.)49 b(The)31 b(\223)p Ff(mak)o(e)p Fh(\224)h(method)f(has)g(been)h(re)n(written)e (to)i(match)0 4979 y(the)25 b(one)f(which)h(Magic)f(uses,)h(so)f(IRSIM) i(can)f(be)g(compiled)f(and)g(installed)g(in)g(a)h(similar)f(manner:) 900 5159 y Fe(make)59 b(config)900 5280 y(make)g(tcl)900 5400 y(make)g(install-tcl)1875 5649 y Fh(\2261\226)p eop end %%Page: 2 2 TeXDict begin 2 1 bop 0 -180 a Fh(April)24 b(14,)h(2006)1437 b(Magic)25 b(Tcl)f(T)l(utorial)g(#4:)30 b(Simulation)23 b(with)h(IRSIM)146 68 y(Tcl-based)i(IRSIM,)g(lik)o(e)e(its)h (non-interpreter)g(v)o(ersion,)f(can)i(be)f(run)g(as)h(a)f(standalone)g (product,)g(and)g(will)0 188 y(simulate)33 b(a)i(circuit)f(from)g(a)h Fd(.sim)e Fh(format)h(\002le.)60 b(Ho)n(we)n(v)o(er)l(,)36 b(it)e(is)g(speci\002cally)g(designed)f(to)h(be)h(operated)0 309 y(in)27 b(conjunction)f(with)g(magic,)i(with)e(methods)g(for)i(pro) o(viding)d(feedback)j(directly)f(into)g(the)g(layout)f(from)h(the)0 429 y(simulation,)k(and)h(vice)g(v)o(ersa.)52 b(There)32 b(are)g(a)h(number)e(of)h Fi(cr)l(oss-application)d(commands)p Fh(,)j(detailed)g(belo)n(w)-6 b(,)0 549 y(which)36 b(belong)f(to)h (neither)g(Magic)f(or)h(IRSIM,)h(b)n(ut)f(are)h(applicable)e(when)h (both)g(are)g(running)g(in)f(the)h(Tcl)0 670 y(interpreter)25 b(at)g(the)f(same)h(time.)146 791 y(The)38 b(cross-application)f (commands)f(highlight)g(the)i(usefulness)e(of)i(the)g(method)f(of)h (compiling)d(each)0 911 y(application)24 b(as)h(a)g(loadable)f(Tcl)h (object)f(module.)146 1032 y(In)e(addition)f(to)g(cross-application)g (commands,)g(Tcl-based)h(IRSIM)h(allo)n(ws)d(the)i(use)g(of)g (interpreter)f(v)n(ari-)0 1152 y(ables,)31 b(conditionals,)f(and)g (control)f(structures)h(to)f(set)h(up)g(detailed)g(simulation)e(en)l (vironments.)45 b(A)30 b(random)0 1272 y(number)37 b(generator)h(has)f (been)h(added)g(to)f(the)g(Tcl-based)h(v)o(ersion,)h(allo)n(wing)d (generation)h(of)h(random)f(bit)0 1393 y(v)o(ectors)24 b(for)h(statistically-based)e(co)o(v)o(erage)h(of)h(input)f(pattern)h (spaces.)0 1734 y Fj(2)143 b(In)-6 b(v)o(oking)34 b(IRSIM)h(fr)m(om)g (Magic)0 1959 y Fh(W)l(ithin)e(the)h(Tcl/Tk)f(en)l(vironment,)j(IRSIM)f (is)e(easier)i(than)f(e)n(v)o(er)f(to)h(in)l(v)n(ok)o(e.)58 b(F)o(or)34 b(tutorial)f(purposes,)j(we)0 2079 y(will)30 b(use)i(the)f(same)g(cell)g(used)g(for)h(the)f(original)f(T)l(utorial)g (#11.)50 b(Unlik)o(e)30 b(the)h(original)g(v)o(ersion,)h(Magic)e(7.2)0 2199 y(requires)f(no)h(preparation)f(for)h(simulation)d(and)i(can)h (operate)g(directly)f(of)n(f)g(of)g(the)h(tutorial)e(directory)h (input.)0 2320 y(Start)c(magic)f(with)h(the)f(command-line)900 2551 y Fi(#)h Fe(magic)58 b(-w)i(-d)f(OGL)g(tut11a)146 2781 y Fh(Note)23 b(that)f(the)g(OpenGL)g(interf)o(ace)i(and)e(Wrapper) h(en)l(vironment)f(speci\002ed)g(abo)o(v)o(e)g(are)h(optional,)f(and)g (do)0 2902 y(not)i(af)n(fect)h(the)g(descriptions)e(in)i(this)f (tutorial.)146 3022 y(It)34 b(is)f(not)f(necessary)i(to)f(e)o(xtract!) 56 b(The)34 b(scripts)e(which)h(in)l(v)n(ok)o(e)g(IRSIM)h(are)g (capable)g(of)f(looking)f(for)i(a)0 3143 y(netlist)26 b(\002le)i(to)f(simulate)f(for)h(the)g(currently-loaded)g(cell.)38 b(Because)28 b(these)f(e)o(xist)g(for)g(the)g(tutorial)f(cells,)i(the)o (y)0 3263 y(will)c(be)h(used.)30 b(IRSIM)c(is)e(therefore)i(simply)d (in)l(v)n(ok)o(ed)h(by:)900 3494 y Fi(\045)h Fe(irsim)146 3725 y Fh(Y)-11 b(ou)25 b(will)f(see)h(a)g(sle)n(w)f(of)h(output)e (that)i(looks)f(lik)o(e)g(the)h(follo)n(wing:)300 3955 y Fd(Warning:)118 b(irsim)58 b(command)h('time')f(use)h (fully-qualified)e(name)h('::irsim::time')300 4076 y(Warning:)118 b(irsim)58 b(command)h('start')f(use)h(fully-qualified)d(name)j ('::irsim::start')300 4196 y(Warning:)118 b(irsim)58 b(command)h('help')f(use)h(fully-qualified)e(name)h('::irsim::help')300 4317 y(Warning:)118 b(irsim)58 b(command)h('path')f(use)h (fully-qualified)e(name)h('::irsim::path')300 4437 y(Warning:)118 b(irsim)58 b(command)h('clear')f(use)h(fully-qualified)d(name)j ('::irsim::clear')300 4557 y(Warning:)118 b(irsim)58 b(command)h('alias')f(use)h(fully-qualified)d(name)j('::irsim::alias') 300 4678 y(Warning:)118 b(irsim)58 b(command)h('set')f(use)h (fully-qualified)e(name)i('::irsim::set')300 4798 y(Warning:)118 b(irsim)58 b(command)h('exit')f(use)h(fully-qualified)e(name)h ('::irsim::exit')300 4918 y(Starting)g(irsim)h(under)f(Tcl)h (interpreter)300 5039 y(IRSIM)g(9.6)g(compiled)f(on)h(Thu)g(Mar)g(20)h (17:19:00)e(EST)h(2003)300 5159 y(Warning:)118 b(Aliasing)58 b(nodes)g('GND')h(and)g('Gnd')300 5280 y(/usr/local/lib/magic/tutorial) o(/tut1)o(1a.s)o(im:)113 b(Ignoring)58 b(lumped-resistance)600 5400 y(\('R')h(construct\))1875 5649 y Fh(\2262\226)p eop end %%Page: 3 3 TeXDict begin 3 2 bop 0 -180 a Fh(Magic)24 b(Tcl)h(T)l(utorial)f(#4:)30 b(Simulation)23 b(with)h(IRSIM)1439 b(April)24 b(14,)h(2006)300 205 y Fd(Read)59 b(/usr/local/lib/magic/tutorial)o(/tut)o(11a.s)o(im)54 b(lambda:1.00u)j(format:MIT)300 325 y(68)i(nodes;)g(transistors:)117 b(n-channel=56)57 b(p-channel=52)300 445 y(parallel)h(txtors:none)300 566 y Fi(\045)146 751 y Fh(These)25 b(comments)f(require)i(some)e(e)o (xplanation.)30 b(The)c(w)o(arning)e(messages)h(all)g(ha)n(v)o(e)g(to)f (do)h(with)g(the)g(f)o(act)0 872 y(that)i(certain)i(command)d(names)i (are)h(used)e(both)g(by)h(IRSIM)h(and)f(Magic,)g(or)g(by)g(IRSIM)g(and) g(Tcl)g(or)g(one)g(of)0 992 y(its)i(loaded)g(packages)g(\(such)g(as)h (Tk\).)47 b(There)30 b(are)h(se)n(v)o(eral)f(w)o(ays)g(to)g(w)o(ork)g (around)g(the)g(unfortunate)g(conse-)0 1112 y(quences)i(of)f(multiply)f (de\002ning)h(command)f(names,)j(b)n(ut)e(the)g(easiest)h(is)f(to)g (mak)o(e)g(use)h(of)f(the)h(Tcl)f(concept)0 1233 y(of)i Fi(namespaces)p Fh(.)56 b(A)33 b(complete)g(description)f(of)h(Tcl)g (namespaces)h(is)e(be)o(yond)h(the)g(scope)g(of)g(this)f(tutorial;)0 1353 y(ho)n(we)n(v)o(er)l(,)24 b(a)h(simple)f(description)f(suf)n (\002ces.)32 b(By)25 b(pre\002xing)g(a)g(\223scope\224)h(to)e(the)h (command,)f(the)h(command)f(can)0 1474 y(only)33 b(be)g(e)o(x)o(ecuted) g(when)g(the)g(complete)g(name)g(\(scope)g(plus)g(the)g(double)g(colon) g(`::')47 b(plus)33 b(the)g(command)0 1594 y(name\))25 b(is)f(entered.)146 1714 y(In)g(general,)g(the)g(ED)l(A)g(tools)e(mak)o (e)i(an)g(attempt)f(to)g(allo)n(w)g(commands)g(to)g(be)h(entered)g (without)f(the)g(scope)0 1835 y(pre\002x)g(at)f(the)g(command)g(line.) 29 b(As)22 b(long)g(as)g(command)f(names)h(are)h(unique,)f(this)g(is)f (done)h(without)f(comment.)0 1955 y(Ho)n(we)n(v)o(er)l(,)29 b(when)g(commands)e(o)o(v)o(erlap,)i(the)g(easiest)g(solution)e(is)h (to)h(require)g(the)g(scope)g(pre\002x.)43 b(Therefore,)0 2076 y(the)27 b(command)g(`)p Ff(set)p Fh(')h(w)o(ould)f(refer)i(to)e (the)h(Tcl)f Ff(set)h Fh(command)f(\(i.e.,)h(to)f(set)h(a)g(v)n (ariable\),)g(while)f(`)p Ff(irsim::set)p Fh(')0 2196 y(w)o(ould)e(refer)h(to)f(the)g(IRSIM)i(command.)k(Some)26 b(attempt)e(is)h(made)h(to)f(o)o(v)o(erload)f(commands)g(which)h (con\003ict)0 2316 y(b)n(ut)k(which)g(ha)n(v)o(e)g(unique)g(syntax,)h (so)f(that)g(it)g(is)g(possible)f(to)i(determine)f(which)g(use)g(is)g (intended)g(when)g(the)0 2437 y(command)24 b(is)g(dispatched)g(by)h (the)f(interpreter)-5 b(.)146 2557 y(In)30 b(addition)e(to)h(the)h(w)o (arnings,)g(there)g(are)g(a)g(fe)n(w)f(standard)h(w)o(arnings)f(about)g (global)f(name)i(aliases)f(and)0 2677 y(lumped)24 b(resistance,)g(and)h (some)f(information)g(about)g(the)h Fd(.sim)f Fh(\002le)h(which)f(w)o (as)h(read.)0 3011 y Fj(3)143 b(IRSIM)35 b(Command)f(Set)0 3235 y Fh(In)27 b(addition)e(to)h(the)g(e)o(xceptions)f(noted)h(abo)o (v)o(e)g(for)h(fully-quali\002ed)e(namespace)i(commands,)f(there)g(are) i(se)n(v-)0 3355 y(eral)i(IRSIM)h(commands)e(which)h(are)g(not)g (compatible)f(with)g(Tcl)h(syntax,)g(and)g(these)g(ha)n(v)o(e)g(been)g (renamed.)0 3475 y(The)d(old)e(and)i(ne)n(w)f(commands)f(are)i(as)g (follo)n(ws)e(\(see)i(the)f(IRSIM)i(documentation)c(for)j(the)f(full)g (set)h(of)f(com-)0 3596 y(mands\):)p 457 3690 2987 4 v 455 3811 4 121 v 507 3775 a(\277)122 b(sa)n(v)o(estate)633 b(sa)n(v)o(e)25 b(netw)o(ork)f(state)p 3441 3811 V 455 3931 V 507 3895 a(\241)133 b(restorestate)536 b(restore)25 b(netw)o(ork)g(state)p 3441 3931 V 455 4051 V 507 4015 a(\241\241)100 b(restoreall)619 b(restore)25 b(netw)o(ork)g(and)f (input)g(state)p 3441 4051 V 455 4172 V 507 4136 a(?)122 b(querysource)503 b(get)25 b(info)f(re)o(garding)g(source/drain)g (connections)p 3441 4172 V 455 4292 V 507 4256 a(!)133 b(querygate)597 b(get)25 b(info)f(re)o(garding)g(gate)g(connections)p 3441 4292 V 455 4413 V 673 4376 a(source)h Fi(\(Tcl)g(command\))99 b Fh(source)25 b(a)g(command)f(\002le)p 3441 4413 V 457 4416 2987 4 v 146 4557 a(Note)k(that)f(the)g(`')h(command)f(is)g (simply)f(superceded)i(by)f(the)g(Tcl)h(`)p Ff(sour)n(ce)p Fh(')h(command,)e(which)g(is)g(more)0 4678 y(general)36 b(in)f(that)h(it)f(allo)n(ws)f(a)i(mixture)f(of)h(Tcl)f(and)h(IRSIM)g (commands)f(\(and)h(commands)e(for)i(an)o(y)f(other)0 4798 y(loaded)25 b(package,)g(such)f(as)h(Magic\))g(to)f(be)h(combined) f(in)g(the)h(command)f(\002le.)146 4918 y(Once)40 b(loaded)f(into)g (Tcl)h(alongside)e(Magic)h(via)h(the)f Ff(irsim)g Fh(command,)j(the)e (IRSIM)g(commands)e(are)0 5039 y(typed)24 b(directly)g(into)f(the)i (Magic)f(command)f(line,)h(and)h(will)e(e)o(x)o(ecute)h(the)g (appropriate)h(IRSIM)g(function.)30 b(By)0 5159 y(repeating)23 b(the)h(contents)e(of)i(T)l(utorial)e(#11)h(in)g(the)g(Tcl)h(en)l (vironment,)e(this)h(method)f(should)g(become)i(clear)l(,)g(as)0 5280 y(will)g(the)h(bene\002ts)f(of)h(using)f(the)h(interpreter)g(en)l (vironment)e(for)i(simulation.)146 5400 y(T)-8 b(o)25 b(setup)f(the)h(simulation,)d(the)j(equi)n(v)n(alent)e(instruction)g (to)h(that)h(of)g(T)l(utorial)e(#11)h(is)h(the)f(follo)n(wing:)1875 5649 y(\2263\226)p eop end %%Page: 4 4 TeXDict begin 4 3 bop 0 -180 a Fh(April)24 b(14,)h(2006)1437 b(Magic)25 b(Tcl)f(T)l(utorial)g(#4:)30 b(Simulation)23 b(with)h(IRSIM)900 84 y Fi(\045)50 b Fe(source)58 b($)p Fc(f)p Fe(CAD)p 1747 84 30 4 v 35 w(HOME)p Fc(g)p Fe (/lib/magic/tutorial/tut11)o(a.cm)o(d)146 297 y Fh(Note)24 b(that)g(because)g(the)g Ff(sour)n(ce)h Fh(command)e(is)g(a)h(Tcl)g (command,)f(not)h(a)g(Magic)g(or)g(IRSIM)h(command,)e(it)0 417 y(it)i(necessary)g(to)g(specify)g(the)g(complete)g(path)f(to)h(the) g(\002le,)h(as)f(Tcl)g(does)g(not)g(understand)f(the)h(search)h(path)f (for)0 538 y(Magic)f(cells,)h(which)f(includes)g(the)h(tutorial)f (directory)-6 b(.)146 658 y(As)33 b(most)f(common)g(commands)g(are)i (not)f(among)f(the)h(set)g(that)g(cause)h(con\003icts)f(with)f(Magic)h (and)g(Tcl)0 778 y(commands,)23 b(the)i(tutorial)f(command)g(\002le)h (loads)f(and)h(e)o(x)o(ecutes)f(without)f(comment.)146 899 y(F)o(ollo)n(wing)32 b(the)i(e)o(xample)f(of)h(T)l(utorial)f(#11,)i (type)f Ff(c)g Fh(\(IRSIM)h(clock)f(command\))f(on)h(the)g(magic)f (com-)0 1019 y(mand)28 b(line)h(to)g(clock)g(the)f(circuit.)43 b(V)-11 b(alues)29 b(for)g(the)g(w)o(atched)g(nodes,)h(which)e(were)i (declared)g(in)e(the)h(tutorial)0 1139 y(command)24 b(\002le,)h(are)h (displayed)d(in)i(the)f(console)h(windo)n(w)-6 b(.)28 b(Lik)o(e)n(wise,)900 1331 y Fe(h)60 b(RESET)p 1326 1331 V 34 w(B)g(hold)0 1523 y Fh(will)24 b(set)h(the)f(nodes)g Fe(RESET)p 1025 1523 V 35 w(B)h Fh(and)g Fe(hold)f Fh(to)g(v)n(alue)g (1.)0 1860 y Fj(4)143 b(F)l(eedback)34 b(to)i(Magic)0 2084 y Fh(The)31 b(cross-application)f(commands)g(re)n(v)o(eal)h(the)g (usefulness)f(of)h(ha)n(ving)g(both)f(applications)g(as)h(e)o (xtensions)0 2204 y(of)25 b(the)g(same)f(Tcl)h(interpreter)-5 b(.)146 2324 y(While)34 b(Magic)g(and)g(IRSIM)g(are)h(acti)n(v)o(e)e (and)h(\002le)h Fd(tut11a)d Fh(is)i(loaded,)i(e)o(x)o(ecute)d(the)h (follo)n(wing)e(com-)0 2445 y(mands)24 b(from)h(the)f(command)g(line:) 900 2636 y Fe(stepsize)58 b(100)900 2757 y(watchnode)g(RESET)p 1804 2757 V 35 w(B)900 2877 y(watchnode)g(hold)0 3069 y Fh(Note)30 b(that)g(the)g(nodes)g(and)g(v)n(alues)g(are)h (immediately)e(printed)g(in)h(the)g(magic)g(windo)n(w)-6 b(,)30 b(making)g(use)g(of)g(the)0 3189 y(magic)c(\223)p Ff(element)p Fh(\224)h(command.)34 b(These)26 b(v)n(alues)g(are)h (persisent)e(in)h(the)g(sense)g(that)g(the)o(y)f(will)g(remain)h (through)0 3309 y(v)n(arious)19 b(transformations,)h(openings,)g(and)g (closings)f(of)h(the)g(layout)f(windo)n(w)-6 b(,)20 b(b)n(ut)f(the)o(y) h(are)h(temporary)e(in)h(the)0 3430 y(sense)25 b(that)g(the)o(y)f(will) h(not)f(be)i(sa)n(v)o(ed)e(along)h(with)f(the)h(layout)g(if)g(the)g (\002le)h(is)f(written)f(\(ho)n(we)n(v)o(er)l(,)g(this)g(beha)n(vior)0 3550 y(can)h(be)g(modi\002ed\).)146 3671 y(The)i Ff(watchnode)h Fh(command)d(requires)i(no)f(special)g(action)g(for)h(placing)f(the)h (label)f(elements)g(in)g(the)g(lay-)0 3791 y(out)31 b(because)i(magic)e (uses)h(the)g(labels)f(or)h(other)g(node)g(information)e(to)i(pinpoint) e(a)i(position)f(in)g(the)h(layout)0 3911 y(belonging)d(to)h(that)g (node,)i(and)e(places)h(the)f(label)g(element)g(there.)48 b(It)30 b(is)g(possible)g(to)g(use)g Ff(watchnode)i Fh(with)0 4032 y(v)o(ectors.)d(Ho)n(we)n(v)o(er)l(,)23 b(as)g(no)g(location)f (can)h(be)g(pinpointed)f(for)h(a)g(v)o(ector)l(,)g(the)g(magic)g (cursor)g(box)g(position)e(will)0 4152 y(be)k(used)f(to)h(place)g(the)g (label)f(element.)146 4273 y(Mo)o(v)o(e)g(the)g(magic)h(cursor)g(box)f (to)g(a)h(empty)f(space)i(in)e(the)h(layout)f(windo)n(w)-6 b(,)23 b(and)h(type)900 4464 y Fe(watchnode)58 b(bits)146 4656 y Fh(No)n(w)24 b(mo)o(v)o(e)g(the)g(cursor)h(box)g(to)f(another)h (empty)f(space)h(and)g(type)900 4847 y Fe(watchtime)0 5039 y Fh(No)n(w)f(all)h(of)g(the)f(simulation)f(v)n(alues)h(of)h (interest)f(are)h(displayed)f(directly)g(on)h(the)g(Magic)f(layout.)146 5159 y(The)31 b(display)f(of)h(an)o(y)g(node)f(can)i(be)f(remo)o(v)o (ed)e(with)i(the)f(command)g Fe(unwatchnode)p Fh(,)g(with)g(the)h(same) 0 5280 y(syntax)k(as)h Fe(watchnode)p Fh(,)h(and)f(similarly)-6 b(,)36 b(the)g(display)f(of)h(simulation)e(time)h(can)h(be)g(remo)o(v)o (ed)f(with)g(the)0 5400 y(command)24 b Fe(unwatchtime)p Fh(.)1875 5649 y(\2264\226)p eop end %%Page: 5 5 TeXDict begin 5 4 bop 0 -180 a Fh(Magic)24 b(Tcl)h(T)l(utorial)f(#4:)30 b(Simulation)23 b(with)h(IRSIM)1439 b(April)24 b(14,)h(2006)146 68 y(If)i(the)f(position)f(of)h(a)h(label)f(is)g(not)g(in)g(a)g(good)g (position)f(to)h(read,)h(or)f(the)g(relati)n(v)o(e)g(position)e(of)j (tw)o(o)f(labels)0 188 y(places)31 b(them)e(on)i(top)e(of)i(one)f (another)l(,)i(making)e(them)f(dif)n(\002cult)h(to)g(read,)j(the)d (labels)g(can)h(be)f(mo)o(v)o(ed)f(using)0 309 y(the)g Ff(mo)o(v)o(enode)g Fh(command.)42 b(F)o(or)29 b(instance,)g(the)g (node)f Fd(RESET)p 2296 309 30 4 v 35 w(B)h Fh(is)f(not)g(e)o(xactly)g (on)h(the)f(polysilicon)f(pad.)0 429 y(T)-8 b(o)25 b(center)g(it)f(e)o (xactly)g(on)h(the)g(pad,)f(select)h(the)g(square)g(pad,)f(so)h(that)f (the)h(box)f(cursor)h(is)f(on)h(it,)f(then)g(do)900 689 y Fe(movenode)58 b(RESET)p 1744 689 V 35 w(B)0 939 y Fh(The)36 b(label)g(will)f(be)h(mo)o(v)o(ed)f(so)g(that)h(it)f(is)h (centered)h(on)e(the)h(center)h(of)f(the)g(cursor)g(box.)64 b(The)36 b(equi)n(v)n(alent)0 1060 y(method)24 b(can)h(be)g(applied)f (to)h(the)f(time)g(v)n(alue)g(using)g(the)h Fe(movetime)e Fh(command.)146 1190 y(It)g(is)g(not)g(necessary)g(to)g(kno)n(w)f(the)h (name)g(of)g(a)g(node)g(in)g(order)h(to)e(query)h(or)g(display)g(its)f (simulation)f(v)n(alue.)0 1310 y(F)o(or)28 b(instance,)g(une)o(xpand)e (the)i(layout)f(of)h Fd(tut11a.mag)p Fh(,)e(select)i(an)f(unlabeled)h (node,)g(and)f(use)h(a)g(mixture)0 1430 y(of)d(IRSIM)h(and)e(magic)h (commands)e(to)i(w)o(atch)g(its)f(v)n(alue:)900 1690 y Fe(box)59 b(93)g(-104)g(94)h(-102)900 1811 y(select)e(area)900 1931 y(watchnode)g([getnode])0 2302 y Fh(In)39 b(this)f(e)o(xample,)k (both)c(the)h(node)g(\()p Fd(bit)p 1538 2302 V 35 w(1/tut11d)p 2053 2302 V 35 w(0/a)p 2268 2302 V 35 w(39)p 2423 2302 V 35 w(n23#)p Fh(\))g(and)g(its)f(v)n(alue)g(are)i(displayed.)0 2422 y(Lik)o(e)n(wise,)32 b(the)f Ff(getnode)h Fh(command)e(can)i(be)f (combined)f(with)h(other)g(IRSIM)h(commands)e(to)h(setup)f(clocks)0 2543 y(and)g(v)o(ectors)f(from)g(unlabeled)g(nodes.)45 b(This)29 b(can)h(be)g(particularly)f(useful)g(in)g(situations)f(where) i(it)f(may)h(not)0 2663 y(be)25 b(ob)o(vious)e(which)h(nodes)h(in)f(a)h (design)f(need)h(to)g(be)g(e)o(xamined)e(prior)i(to)f(running)g(the)h (simulation.)0 3063 y Fj(5)143 b(Analyzer)34 b(Display)0 3306 y Fh(Tcl-based)g(IRSIM)h(has)f(a)g(graphical)g(node)g(display)f (which)g(is)h(deri)n(v)o(ed)f(from)g(functions)g(a)n(v)n(ailable)h(in)f (the)0 3426 y(\223)p Ff(BL)-9 b(T)p Fh(\224)27 b(graphics)e(package.)32 b(These)25 b(functions)f(are)i(not)e(particularly)h(well-suited)f(for)h (display)f(of)h(logic)g(v)n(al-)0 3547 y(ues,)d(and)g(so)f(this)g(will) f(probably)h(be)h(replaced)g(in)f(the)h(future)g(with)e(a)i(more)g (appropriate)f(interf)o(ace.)30 b(Ho)n(we)n(v)o(er)l(,)0 3667 y(it)24 b(accomplishes)g(most)g(of)h(the)f(functions)g(of)h(the)f (former)h(X11-based)g(analyzer)g(display)-6 b(.)146 3797 y(In)27 b(the)f(Tcl-based)g(IRSIM,)h(no)f(special)g(command)g(is)g (needed)g(to)g(initialize)f(the)h(analyzer)h(display)-6 b(.)34 b(One)0 3917 y(command)24 b(sets)g(up)h(signals)e(to)i(be)g (displayed)f(in)g(the)h(analyzer)g(windo)n(w)-6 b(.)29 b(This)24 b(is:)900 4177 y Fe(graphnode)f Fi(name)i Fh([)p Fi(r)l(ow)p Fh(])f([)p Fi(of)n(fset)p Fh(])0 4428 y(F)o(or)h(display)f (of)h(multiple)f(signals)g(in)g(the)h(windo)n(w)-6 b(,)23 b(the)i(optional)f(ar)n(guments)h Fi(r)l(ow)f Fh(and)h Fi(of)n(fset)g Fh(are)g(pro)o(vided.)0 4548 y(Each)g(signal)f(which)g (declares)h(a)g(ne)n(w)f Fi(r)l(ow)g Fh(\(def)o(ault)h(zero\))g(will)f (appear)h(in)f(a)h(separate)g(graph)g(in)f(the)h(display)-6 b(.)0 4668 y(Signals)33 b(which)f(appear)i(in)f(the)g(same)g(graph,)i (ho)n(we)n(v)o(er)l(,)f(may)f(declare)h(a)f(non-zero)h Fi(of)n(fset)e Fh(which)h(will)f(set)0 4789 y(them)23 b(at)h(a)h(dif)n(ferent)e(v)o(ertical)h(placement)f(on)h(the)g(graph,)g (for)g(cases)h(in)e(which)h(this)f(pro)o(vides)g(better)g(vie)n(wing)0 4909 y(than)h(ha)n(ving)h(the)f(signals)g(directly)g(o)o(v)o (erlapping.)146 5039 y(The)29 b(analyzer)h(display)e(updates)h(at)g (the)g(end)g(of)g(each)h(simulation)d(c)o(ycle.)43 b(Logic)29 b(v)n(alues)f(are)i(displayed)0 5159 y(as)38 b(0)g(or)g(1,)j(with)c (unde\002ned)h(\(v)n(alue)f('X'\))i(v)n(alues)e(displayed)g(as)h(1/2.) 69 b(Note)38 b(that)g(the)f(BL)-9 b(T)g(-based)38 b(inter)n(-)0 5280 y(f)o(ace)d(prohibits)d(the)h(display)g(of)h(multi-bit)e(v)n (alues,)j(and)e(only)g(nodes,)j(not)d(v)o(ectors,)i(can)f(be)g(passed)g (to)f(the)0 5400 y Fe(graphnode)23 b Fh(command.)1875 5649 y(\2265\226)p eop end %%Page: 6 6 TeXDict begin 6 5 bop 0 -180 a Fh(April)24 b(14,)h(2006)1437 b(Magic)25 b(Tcl)f(T)l(utorial)g(#4:)30 b(Simulation)23 b(with)h(IRSIM)0 99 y Fj(6)143 b(W)m(ildcards)0 322 y Fh(The)35 b(original)f(IRSIM)i(used)f(\223wildcard\224)g(characters)g (in)g(the)g(form)g(of)g(standard)f(UNIX)h(\223re)o(gular)g(e)o(xpres-)0 443 y(sions\224)d(to)h(perform)h(operations)e(on)h(multiple)f(nodes)h (with)f(one)i(command.)55 b(Unfortunately)-6 b(,)34 b(there)f(w)o(as)h (a)0 563 y(syntactical)c(collision)f(between)h(IRSIM)h(and)g(Magic)f(o) o(v)o(er)g(the)g(use)h(of)f(brack)o(ets)h(\(`)p Fe([)p Fh(')g(and)f(`)p Fe(])p Fh('\).)48 b(Brack)o(ets)0 683 y(represent)20 b(groupings)e(in)h(re)o(gular)g(e)o(xpression)f(syntax.) 29 b(Ho)n(we)n(v)o(er)l(,)19 b(Magic)g(uses)g(brack)o(ets)h(to)f (represent)h(arrays)0 804 y(of)29 b(subcells.)42 b(Because)30 b(Tcl)f(itself)f(implements)f(re)o(gular)i(e)o(xpressions)e(in)i(the)g (form)f(of)h(the)g(Tcl)g(\223)p Fe(regexp)p Fh(\224)0 924 y(command,)34 b(there)f(is)f(a)h(w)o(ay)g(around)f(this)g(problem)g (in)g(the)g(Tcl)h(v)o(ersion)f(of)g(IRSIM.)i(IRSIM')-5 b(s)33 b(parsing)f(of)0 1045 y(re)o(gular)27 b(e)o(xpressions)f(has)i (been)f(disabled.)38 b(In)28 b(place)f(of)h(it,)g(Tcl)f(lists)f(may)h (be)h(passed)f(as)h(ar)n(guments)f(to)g(an)o(y)0 1165 y(command)j(which)h(pre)n(viously)e(w)o(ould)h(accept)i(wildcard)e (characters.)50 b(In)31 b(addition,)h(Tcl-IRSIM)f(de\002nes)h(a)0 1285 y(command)900 1480 y Fe(listnodes)0 1675 y Fh(which)23 b(returns)g(a)g(Tcl)g(list)f(of)h(all)g(the)g(nodes)g(de\002ned)g(in)g (the)g(netlist)f(input)g(\002le.)30 b(This)23 b(list)f(can)h(be)h (searched)f(by)0 1795 y(Tcl)k(re)o(gular)f(e)o(xpression)g(commands,)f (and)i(the)g(resulting)e(sub-lists)g(passed)i(as)f(node)h(ar)n(guments) f(to)g(IRSIM)0 1916 y(commands.)38 b(F)o(or)27 b(e)o(xample,)g(the)h (follo)n(wing)d(script)i(sets)g(all)g(nodes)g(in)g(the)h(circuit)f(\(e) o(xcept)g(for)h Fd(Vdd)p Fh(,)g(which)0 2036 y(is)c(\002x)o(ed\))h(to)g (zero,)g(then)f(releases)i(them:)900 2231 y Fe(set)59 b(nl)g([listnodes])900 2351 y(l)h($nl)900 2472 y(s)900 2592 y(x)g($nl)146 2787 y Fh(Brack)o(ets)33 b(in)f(indi)n(vidual)d (node)j(names)g(are)h(treated)f(as-is)g(by)f(IRSIM,)i(as)f(are)h(other) f(Magic-generated)0 2907 y(characters)25 b(such)e(as)h(the)g(slash,)f (underscore,)h(and)g(hash)g(mark.)30 b(Note,)24 b(ho)n(we)n(v)o(er)l(,) e(that)i(because)g(Tcl)g(itself)f(de-)0 3028 y(\002nes)f(brack)o(ets)g (as)g(representing)g(command)f(groupings)f(which)i(return)g(an)g (immediate)e(result,)i(the)g(follo)n(wing)0 3148 y(is)i(ille)o(gal:)900 3343 y Fi(\045)h Fe(l)59 b(multcell5)p 1673 3343 30 4 v 34 w(0[1,0]/a)p 2187 3343 V 34 w(13)p 2341 3343 V 36 w(n21#)900 3463 y Fd(invalid)f(command)g(name)h("1,0")0 3658 y Fh(Instead,)42 b(node)d(names)g(containing)e(brack)o(ets)i (should)f(be)h(surrounded)f(by)h(braces)g(\(`)p Fc(f)p Fh(')h(and)f(`)p Fc(g)p Fh('\),)k(which)0 3778 y(ef)n(fecti)n(v)o(ely) 36 b(turns)h(a)h(node)g(name)f(into)g(a)h(list)f(of)h(node)f(names)g (which)h(happens)f(to)g(contain)g(e)o(xactly)g(one)0 3899 y(entry:)900 4093 y Fi(\045)25 b Fe(l)59 b Fc(f)p Fe(multcell5)p 1723 4093 V 34 w(0[1,0]/a)p 2237 4093 V 34 w(13)p 2391 4093 V 36 w(n21#)p Fc(g)0 4409 y Fh(The)38 b(Tcl)g(v)o(ersions)f(of)h(Magic)g(and)g(IRSIM)h(are)g(set)f(up)g(in)g (such)g(a)g(w)o(ay)h(that)e(when)h(the)o(y)g(return)g(results)0 4529 y(containing)24 b(node)g(names,)g(these)h(names)g(are)g (automatically)e(treated)i(as)g(lists.)30 b(Therefore,)25 b(the)g(command)900 4724 y Fi(\045)g Fe(select)58 b(area)h([goto)g Fc(f)p Fe(multcell5)p 2680 4724 V 34 w(0[1,0]/a)p 3194 4724 V 34 w(13)p 3348 4724 V 35 w(n21#)p Fc(g)24 b Fe(])900 4844 y Fi(\045)h Fe(l)59 b([getnode])0 5039 y Fh(does)32 b(not)f(produce)h(an)o(y)g(error)g(when)g(the)g(arrayed)h(node)e(name)h (is)g(passed)g(to)f(the)h(IRSIM)h(\223)p Fe(l)p Fh(\224)f(command,)0 5159 y(and)g(sets)f(the)h(v)n(alue)f(of)h(the)g(node)f(to)h(zero)g(as)g (e)o(xpected.)52 b(It)31 b(is)h(only)f(when)h(node)f(names)h(are)g (entered)g(in)g(a)0 5280 y(script)20 b(or)g(from)g(the)g(command)f (line)h(that)f(precautions)h(must)f(be)h(tak)o(en)g(to)g(list-enclose)f (names)h(which)g(contain)0 5400 y(brack)o(ets.)1875 5649 y(\2266\226)p eop end %%Page: 7 7 TeXDict begin 7 6 bop 0 -180 a Fh(Magic)24 b(Tcl)h(T)l(utorial)f(#4:)30 b(Simulation)23 b(with)h(IRSIM)1439 b(April)24 b(14,)h(2006)0 99 y Fj(7)143 b(Scripting)34 b(IRSIM)h(Command)f(Sequences)0 324 y Fh(A)i(consequence)h(of)g(placing)e(IRSIM)j(in)e(an)g (interpreter)h(en)l(vironment)e(is)h(the)g(ability)g(to)g(use)g (interpreter)0 444 y(features)25 b(such)g(as)g(v)n(ariables,)f (conditionals,)e(and)j(loops)f(to)g(set)h(up)g(complicated)e (simulation)g(en)l(vironments.)0 788 y Fj(8)143 b(Deterministic)33 b(Bit)i(V)-14 b(ector)34 b(Generation)0 1013 y Fh(A)23 b(con)l(v)o(enience)g(function)f(has)i(been)f(added)g(to)g(Tcl-IRSIM)h (to)f(aid)g(in)g(generating)g(deterministic)e(sequences)0 1134 y(of)k(inputs.)k(This)24 b(is)h(the)f(command)900 1341 y Fe(bconvert)f Fi(value)i(bits)f Fh([)p Fi(dir)p Fh(])0 1548 y(where)j Fi(value)f Fh(is)h(an)f(inte)o(ger)g(decimal)g(v) n(alue,)g Fi(bits)g Fh(is)g(the)g(length)g(of)h(the)f(bit)g(v)o(ector)g (to)g(hold)g(the)g(con)l(v)o(ersion,)0 1669 y(and)g Fi(dir)g Fh(is)g(an)h(optional)e(direction)h(\003ag.)36 b(If)27 b Fi(dir)f Fh(is)g(1,)h(then)f(the)h(bit)e(v)o(ector)h(is)g(de\002ned)h (with)f(the)g(most)g(signif-)0 1789 y(icant)i(bit)g(\(MSB\))h(on)f(the) g(right.)41 b(The)28 b Fe(bconvert)f Fh(command)g(returns)h(the)g (string)g(v)n(alue)f(of)i(the)f(bit)g(v)o(ector)0 1909 y(containing)c Fd(0)g Fh(and)h Fd(1)g Fh(characters.)31 b(F)o(or)25 b(e)o(xample:)900 2143 y Fi(\045)g Fe(bconvert)58 b(20)h(5)900 2264 y Fd(10100)900 2384 y Fi(\045)25 b Fe(bconvert)58 b(20)h(5)h(1)900 2504 y Fd(00101)0 2849 y Fj(9)143 b(Random)34 b(Bit)h(V)-14 b(ector)34 b(Generation)0 3074 y Fh(The)c(tutorial)f(e)o(xamples)g(are)i(small)e(by)h(design,)g (b)n(ut)f(real)i(systems)e(\(such)g(as)i(a)f(microprocessor\))f(are)i (often)0 3194 y(so)d(comple)o(x)f(that)h(generating)g(and)g(simulating) e(an)i(e)o(xhausti)n(v)o(e)e(set)i(of)h(all)f(possible)e(states)i(of)h (the)f(circuit)g(is)0 3314 y(impossible,)h(and)h(instead)g(simulations) d(rely)k(on)e(the)h(generation)g(of)g(a)h(set)f(of)g (randomly-generated)f(inputs)0 3435 y(to)24 b(test)h(a)g(representati)n (v)o(e)f(set)g(of)h(states.)146 3556 y(Random)19 b(number)g(generation) g(is)g(not)g(a)g(b)n(uilt-in)f(feature)i(of)f(the)h(Tcl)f(language,)h (b)n(ut)f(se)n(v)o(eral)f(open-source)0 3676 y(packages)23 b(e)o(xist,)e(one)i(of)f(which)g(has)h(been)f(incorporated)h(into)e (the)h(IRSIM)i(9.6)e(source.)30 b(The)22 b(pseudorandom)0 3797 y(number)h(generator)g(is)g(compiled)f(as)h(a)g(separate)h(Tcl)f (package,)h(b)n(ut)e(is)h(loaded)g(by)f(the)h(IRSIM)h(startup)f (script.)0 3917 y(It)i(contains)f(one)h(command,)e Fe(random)p Fh(,)h(with)g(the)g(follo)n(wing)f(ar)n(guments:)900 4125 y Fe(random)h Fi(option)0 4331 y Fh(where)h Fi(option)f Fh(may)g(be)h(one)g(of:)244 4538 y Fe(-reset)e Fh(will)h(cause)i(the)e (generator)h(to)g(be)g(reseeded)g(using)f(current)h(pid)f(and)h (current)g(time.)244 4745 y Fe(-seed)f Fi(n)g Fh(will)g(reseed)i(the)e (generator)h(with)f(the)h(inte)o(ger)f(v)n(alue)g Fi(n)p Fh(.)244 4952 y Fe(-integer)e Fi(...)30 b Fh(will)23 b(cause)h(the)g(number)f(returned)h(to)f(be)h(rounded)f(do)n(wn)g(to)g (the)h(lar)n(gest)g(inte)o(ger)f(less)244 5073 y(than)h(or)h(equal)g (to)f(the)h(number)f(which)h(w)o(ould)f(otherwise)g(be)h(returned.)244 5280 y Fe(-normal)e Fi(m)h(s)h Fh(will)e(cause)i(the)f(number)g (returned)h(to)f(be)g(tak)o(en)h(from)f(a)h(gaussian)e(with)g(mean)i Fi(m)f Fh(and)244 5400 y(standard)g(de)n(viation)g Fi(s)p Fh(.)1875 5649 y(\2267\226)p eop end %%Page: 8 8 TeXDict begin 8 7 bop 0 -180 a Fh(April)24 b(14,)h(2006)1437 b(Magic)25 b(Tcl)f(T)l(utorial)g(#4:)30 b(Simulation)23 b(with)h(IRSIM)244 68 y Fe(-exponential)h Fi(m)i Fh(will)g(cause)g(the) g(number)g(returned)h(to)f(be)g(tak)o(en)h(from)f(an)g(e)o(xponential)f (distri-)244 188 y(b)n(ution)d(with)h(mean)h Fi(m)p Fh(.)244 392 y Fe(-uniform)h Fi(low)i(high)f Fh(will)g(cause)h(the)g(number)g (returned)g(to)f(be)h(tak)o(en)g(from)g(uniform)f(distrib)n(ution)244 512 y(on)d Fi([a,b\))p Fh(.)244 716 y Fe(-chi2)18 b Fi(n)i Fh(will)e(cause)i(the)f(number)g(returned)h(to)f(be)g(tak)o(en)h(from)f (the)g(chi2)g(distrib)n(ution)e(with)i Fi(n)g Fh(de)o(grees)244 836 y(of)25 b(freedom.)244 1039 y Fe(-select)32 b Fi(n)h(list)g Fh(will)f(cause)i Fi(n)f Fh(elements)g(to)g(be)h(selected)f(at)h (random)e(from)i(the)f(list)f Fi(list)h Fh(with)f(re-)244 1160 y(placement.)244 1363 y Fe(-choose)h Fi(n)h(list)g Fh(will)f(cause)i Fi(n)g Fh(elements)e(to)h(be)h(selected)g(at)f (random)g(from)g(the)h(list)e Fi(list)h Fh(without)244 1483 y(replacement.)244 1687 y Fe(-permutation)24 b Fi(n)i Fh(will)f(return)i(a)g(permutation)e(of)h Fb(0)17 b Fa(:)g(:)g(:)f(n)23 b Fc(\000)h Fb(1)i Fh(if)g Fi(n)h Fh(is)f(a)g(number)g(and)h(will)e (return)244 1807 y(a)g(permutation)e(of)i(its)f(elements)g(if)h Fi(n)g Fh(is)f(a)h(list.)146 2011 y(The)39 b(follo)n(wing)e(script)i (clocks)f(a)i(random)e(serial)h(bit)f(v)o(ector)h(into)f(a)h(state)g (machine,)j(assuming)c(that)0 2131 y Fe(bit)p 186 2131 30 4 v 35 w(in)25 b Fh(is)f(the)h(node)f(to)h(set,)f(and)h(that)f(the)h (proper)g(clock)g(v)o(ectors)f(ha)n(v)o(e)g(already)h(been)g(set)g(up:) 600 2334 y(for)g Fc(f)p Fh(set)f(i)h(0)p Fc(g)g(f)p Fh($i)f(\241)h(100) p Fc(g)f(f)p Fh(incr)h(i)p Fc(g)f(f)900 2455 y Fh(if)h Fc(f)p Fh([random])f(\241)h(0.5)p Fc(g)g(f)1421 2575 y Fh(l)g(bit)p 1586 2575 V 35 w(in)900 2696 y Fc(g)g Fh(else)g Fc(f)1421 2816 y Fh(h)g(bit)p 1608 2816 V 35 w(in)900 2936 y Fc(g)900 3057 y Fh(c)600 3177 y Fc(g)1875 5649 y Fh(\2268\226)p eop end %%Trailer userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tuttcl5.ps0000644000175000001440000002511410751423606015643 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software %%Title: tuttcl5.dvi %%Pages: 1 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman %%EndComments %DVIPSWebPage: (www.radicaleye.com) %DVIPSCommandLine: dvips -t letter tuttcl5.dvi -o ../psfiles/tuttcl5.ps %DVIPSParameters: dpi=600, compressed %DVIPSSource: TeX output 2006.04.12:1204 %%BeginProcSet: texc.pro %! /TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin /FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array /BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get }B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr 1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx 0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B /chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ /cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 {2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ 1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put }if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X 1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N /p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ /Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) (LaserWriter 16/600)]{A length product length le{A length product exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end %%EndProcSet %%BeginProcSet: 8r.enc % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndProcSet %%BeginProcSet: texps.pro %! TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type/integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics/Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{ dup sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[exch{dup CharStrings exch known not{pop/.notdef/Encoding true def} if}forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def} def end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tuttcl5.dvi) @start /Fa 105[50 28[50 2[50 50 28 39 33 1[50 50 50 78 28 50 1[28 50 50 1[44 50 44 50 44 11[72 61 55 2[55 2[89 61 1[39 1[72 3[72 2[72 9[50 3[50 50 50 50 1[25 33 25 44[{TeXBase1Encoding ReEncodeFont}39 99.6264 /Times-Roman rf /Fb 134[44 1[66 2[28 39 39 2[50 1[72 3[28 50 3[50 2[50 12[55 1[61 12[61 22[25 46[{TeXBase1Encoding ReEncodeFont}15 99.6264 /Times-Italic rf /Fc 138[80 48 56 64 1[80 72 80 1[40 2[40 1[72 48 2[64 1[72 9[143 2[96 80 5[135 18[48 4[72 3[72 13[72 35[{TeXBase1Encoding ReEncodeFont}21 143.462 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%BeginPaperSize: Letter letter %%EndPaperSize %%EndSetup %%Page: 1 1 1 0 bop 328 101 a Fc(Magic)36 b(Tcl)f(T)-13 b(utorial)34 b(#5:)43 b(Writing)35 b(Tcl)g(Scripts)g(f)l(or)g(Magic)1546 521 y Fb(R.)25 b(T)-5 b(imothy)24 b(Edwar)l(ds)1583 941 y Fa(Space)i(Department)1434 1062 y(Johns)e(Hopkins)g(Uni)n(v)o(ersity) 1391 1182 y(Applied)g(Physics)g(Laboratory)1578 1303 y(Laurel,)h(MD)f(20723)819 1573 y(This)g(tutorial)g(corresponds)g(to)h (Tcl-based)f(Magic)h(v)o(ersion)e(7.2)0 2320 y Fc(1)143 b(Scripting)34 b(in)i(Magic)1875 5649 y Fa(\2261\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tutwrl1.ps0000644000175000001440000011475310751423606015671 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: tutwrl1.dvi %%Pages: 4 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips tutwrl1.dvi -o tutwrl1.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Bold % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet %%BeginProcSet: special.pro TeXDict begin /SDict 200 dict N SDict begin /@SpecialDefaults{/hs 612 N /vs 792 N /ho 0 N /vo 0 N /hsc 1 N /vsc 1 N /ang 0 N /CLIP 0 N /rwiSeen false N /rhiSeen false N /letter{}N /note{}N /a4{}N /legal{}N}B /@scaleunit 100 N /@hscale{@scaleunit div /hsc X}B /@vscale{@scaleunit div /vsc X}B /@hsize{/hs X /CLIP 1 N}B /@vsize{/vs X /CLIP 1 N}B /@clip{ /CLIP 2 N}B /@hoffset{/ho X}B /@voffset{/vo X}B /@angle{/ang X}B /@rwi{ 10 div /rwi X /rwiSeen true N}B /@rhi{10 div /rhi X /rhiSeen true N}B /@llx{/llx X}B /@lly{/lly X}B /@urx{/urx X}B /@ury{/ury X}B /magscale true def end /@MacSetUp{userdict /md known{userdict /md get type /dicttype eq{userdict begin md length 10 add md maxlength ge{/md md dup length 20 add dict copy def}if end md begin /letter{}N /note{}N /legal{} N /od{txpose 1 0 mtx defaultmatrix dtransform S atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{itransform lineto} }{6 -2 roll transform 6 -2 roll transform 6 -2 roll transform{ itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll curveto}}{{ closepath}}pathforall newpath counttomark array astore /gc xdf pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack}if}N /txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 -1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop 90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr 2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 -1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S TR}if}N /cp {pop pop showpage pm restore}N end}if}if}N /normalscale{Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale}if 0 setgray} N /psfts{S 65781.76 div N}N /startTexFig{/psf$SavedState save N userdict maxlength dict begin /magscale true def normalscale currentpoint TR /psf$ury psfts /psf$urx psfts /psf$lly psfts /psf$llx psfts /psf$y psfts /psf$x psfts currentpoint /psf$cy X /psf$cx X /psf$sx psf$x psf$urx psf$llx sub div N /psf$sy psf$y psf$ury psf$lly sub div N psf$sx psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub TR /showpage{}N /erasepage{}N /copypage{}N /p 3 def @MacSetUp}N /doclip{ psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath moveto}N /endTexFig{end psf$SavedState restore}N /@beginspecial{SDict begin /SpecialSave save N gsave normalscale currentpoint TR @SpecialDefaults count /ocount X /dcount countdictstack N}N /@setspecial {CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR }{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury lineto closepath clip}if /showpage{}N /erasepage{}N /copypage{}N newpath }N /@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{ end}repeat grestore SpecialSave restore end}N /@defspecial{SDict begin} N /@fedspecial{end}B /li{lineto}B /rl{rlineto}B /rc{rcurveto}B /np{ /SaveX currentpoint /SaveY X N 1 setlinecap newpath}N /st{stroke SaveX SaveY moveto}N /fil{fill SaveX SaveY moveto}N /ellipse{/endangle X /startangle X /yrad X /xrad X /savematrix matrix currentmatrix N TR xrad yrad scale 0 0 1 startangle endangle arc savematrix setmatrix}N end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tutwrl1.dvi) @start /Fa 134[50 50 72 50 55 33 39 44 1[55 50 55 83 28 55 1[28 55 50 33 44 55 44 55 50 9[100 28[33 3[50 2[50 50 50 1[28 2[25 2[33 33 40[{ TeXBase1Encoding ReEncodeFont }33 100.000003 /Times-Bold rf /Fb 134[60 60 86 1[66 40 47 53 1[66 60 66 100 33 66 1[33 66 60 1[53 66 53 1[60 9[120 2[80 66 5[113 3[47 2[73 2[86 1[86 6[40 4[60 60 60 60 60 2[30 43[66 2[{ TeXBase1Encoding ReEncodeFont }36 119.999948 /Times-Bold rf /Fc 105[50 27[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 1[28 50 50 33 44 50 44 50 44 8[72 94 2[61 55 66 1[55 2[89 61 2[33 2[55 61 72 66 1[72 5[28 28 50 1[50 50 1[50 50 50 50 50 1[25 33 25 2[33 33 33 3[50 32[55 2[{ TeXBase1Encoding ReEncodeFont }58 100.000003 /Times-Roman rf /Fd 134[44 1[66 2[28 39 39 1[50 50 50 72 28 44 28 28 50 50 28 44 50 44 50 50 9[83 2[55 50 4[66 83 55 7[72 66 61 15[50 50 7[33 33 40[{ TeXBase1Encoding ReEncodeFont } 34 100.000003 /Times-Italic rf /Fe 134[72 72 104 1[80 48 56 64 2[72 80 1[40 2[40 80 72 1[64 80 64 1[72 9[143 2[96 1[104 4[135 3[56 2[88 96 104 104 1[104 6[48 5[72 72 72 72 3[48 9[72 35[{ TeXBase1Encoding ReEncodeFont }34 143.999997 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 540 101 a Fe(Magic)36 b(T)-13 b(utorial)33 b(#W)-5 b(-1:)44 b(Design-Rule)33 b(Extensions)1747 521 y Fd(Don)24 b(Stark)1359 941 y Fc(W)-8 b(estern)25 b(Research)h(Laboratory)1327 1062 y(Digital)e(Equipment)f(Corporation)1530 1182 y(P)o(alo)i(Alto,)f (CA)h(94301)1053 1453 y(This)f(tutorial)g(corresponds)g(to)g(Magic)h(v) o(ersion)e(7.)0 1996 y Fb(T)-11 b(utorials)30 b(to)f(r)n(ead)h (\002rst:)300 2214 y Fc(Magic)24 b(T)l(utorial)g(#6:)30 b(Design-Rule)25 b(Checking)300 2334 y(Magic)f(T)l(utorial)g(#9:)30 b(F)o(ormat)24 b(Con)l(v)o(ersion)g(for)h(CIF)h(and)f(Calma)300 2454 y(Magic)f(Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)0 2670 y Fb(Commands)29 b(intr)n(oduced)j(in)f(this)f(tutorial:)300 2888 y Fd(\(None\))0 3103 y Fb(Macr)n(os)f(intr)n(oduced)i(in)g(this)f(tutorial:)300 3351 y Fd(\(None\))0 3979 y Fe(1)143 b(Intr)m(oduction)0 4207 y Fc(Magic')-5 b(s)33 b(original)g(design)h(rule)g(check)o(er)h (has)f(pro)o(v)o(ed)e(inadequate)i(to)g(implement)e(all)i(the)g(rules)g (found)f(in)0 4328 y(adv)n(anced)25 b(technologies.)30 b(The)25 b(rules)g(described)g(in)f(this)h(section)f(allo)n(w)g(more)h (complicated)f(con\002gurations)0 4448 y(to)k(be)g(analyzed.)41 b(T)-8 b(w)o(o)27 b(ne)n(w)h(rules)g(check)g(a)h(re)o(gion')-5 b(s)26 b(area)j(and)f(its)g(maximum)e(width.)40 b(In)28 b(addition,)f(width,)0 4569 y(spacing,)d(area,)i(and)f(maxwidth)e (checks)i(may)f(no)n(w)g(be)h(performed)g(on)g(cif)g(layers.)0 4924 y Fe(2)143 b(Ar)m(ea)35 b(Rules)0 5152 y Fc(The)25 b Fa(ar)n(ea)g Fc(rule)g(is)f(used)h(to)f(check)h(the)g(minimum)d(area) k(of)f(a)g(re)o(gion.)30 b(Its)25 b(syntax)f(is:)900 5400 y Fa(ar)n(ea)h Fd(types)g(minar)l(ea)f(minedg)o(e)h(why)1875 5649 y Fc(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Fc(September)25 b(26,)f(2001)1234 b(Magic)25 b(T)l(utorial)e(#W)-6 b(-1:)30 b(Design-Rule)25 b(Extensions)146 68 y Fd(T)-7 b(ypes)20 b Fc(is)f(a)g(list)g(of)g(types)g(that)f (compose)h(the)g(re)o(gion,)h(all)f(of)g(which)g(must)f(be)i(on)f(the)g (same)g(plane.)29 b Fd(Minar)l(ea)0 188 y Fc(is)24 b(the)h(minimum)d (area)j(that)f(a)h(re)o(gion)f(must)g(ha)n(v)o(e,)g(while)g Fd(minedg)o(e)g Fc(is)g(the)h(minimum)d(length)i(of)g(an)h(edge)g(for)0 309 y(the)d(re)o(gion.)29 b(This)21 b(second)h(dimension)f(is)h (basically)f(an)h(optimization)f(to)g(mak)o(e)h(the)g(design)g(rule)g (check)o(er)h(run)0 429 y(f)o(aster;)h(without)d(it,)i(the)g(check)o (er)h(has)f(to)f(assume)h(that)f(a)i(re)o(gion)e(1)h(lambda)f(wide)h (and)g Fd(minar)l(ea)g Fc(long)f(is)g(le)o(gal,)0 549 y(and)29 b(it)f(must)f(e)o(xamine)h(a)h(much)f(lar)n(ger)h(area)g(when) g(checking)f(the)g(interaction)g(between)h(cells.)41 b(Specifying)0 670 y Fd(minedg)o(e)24 b Fc(reduces)i(this)d (interaction)h(distance.)31 b(An)24 b(e)o(xample)g(rule)h(is:)900 849 y Fa(ar)n(ea)g(\(emitter)-9 b(,em1c\)/npoly)26 b(6)f(2)2164 849 y (") show 2164 849 a 60 w Fa(emitter)h(must)f(be)h(at)f(least)f(2x3)3395 849 y (") show 3395 849 a 683 2415 a @beginspecial 68 @llx 68 @lly 331 @urx 211 @ury 3042 @rwi @setspecial %%BeginDocument: ../psfigures/tutw1.2.ps % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /pgsave save def bop % 576 260 offsets 1.0000 inchscale 2.6000 setlinewidth 0.439 1.000 0.314 scb 240 1.00 192 196 192 548 704 548 704 196 4 polygon sce (minarea) {/Times-Roman 1.000 cf} 2 21 0 448 372 label 0 1.00 192 196 192 548 704 548 704 196 4 polygon (minedge) {/Times-Roman 1.000 cf} 2 20 0 736 372 label 1 1.00 720 548 800 548 2 polygon 1 1.00 720 196 800 196 2 polygon 1 1.00 768 532 768 404 2 polygon 1 1.00 768 340 768 212 2 polygon 1.00 0 768 548 arrowhead 1.00 -181 768 196 arrowhead pgsave restore showpage XCIRCsave restore %%EndDocument @endspecial 1251 2618 a Fc(Figure)h(1:)31 b(Example)24 b(of)h(the)f(area)i(rule.)0 3136 y Fe(3)143 b(Maxwidth)35 b(Rules)0 3360 y Fc(Sometimes)28 b(a)h(technology)f(requires)g(that)h (a)g(re)o(gion)f(not)g(be)h(wider)g(than)g(a)g(certain)g(v)n(alue.)42 b(The)29 b Fa(maxwidth)0 3480 y Fc(rule)c(can)g(be)g(used)f(to)h(check) g(this.)900 3660 y Fa(maxwidth)g Fd(layer)o(s)f(mwidth)h(bends)f(why) 146 3839 y(Layer)o(s)p Fc(,)30 b(the)e(types)f(that)h(compose)f(the)h (re)o(gion,)g(must)g(all)f(be)i(in)f(the)g(same)g(plane.)40 b(The)29 b(re)o(gion)e(must)g(be)0 3960 y(less)20 b(than)h Fd(mwidth)f Fc(wide)g(in)h(either)f(the)h(horizontal)f(or)h(v)o (ertical)f(dimension.)27 b Fd(Bends)21 b Fc(tak)o(es)f(one)h(of)g(tw)o (o)f(v)n(alues,)0 4080 y Fa(bend)p 215 4080 30 4 v 37 w(illegal)29 b Fc(and)i Fa(bend)p 921 4080 V 37 w(ok)p Fc(.)47 b(F)o(or)30 b Fa(bend)p 1511 4080 V 38 w(illegal)f Fc(rules,)i(the)f(check)o(er)h(forms)f(a)h(bounding)e(box)g(around)h (all)0 4200 y(contiguous)23 b(tiles)h(of)h(the)g(correct)g(type,)g (then)f(checks)h(this)f(box')-5 b(s)24 b(width.)29 b(F)o(or)c(e)o (xample:)900 4380 y Fa(maxwidth)g(\(emitter)-9 b(,em1c\)/npoly)26 b(2)f(bend)p 2545 4380 V 37 w(illegal)2855 4380 y /bksp 2 string def bksp 0 92 put bksp show 2855 4380 a 1421 4500 a (") show 1421 4500 a 60 w Fa(emitter)h(width)f(cannot)h(be)g (o)o(v)o(er)f(2)2783 4500 y (") show 2783 4500 a 146 4680 a Fa(bend)p 361 4680 30 4 v 38 w(ok)19 b Fc(rules)g(are)g(used)g(to)f(check)i (structures)e(where)i(the)e(re)o(gion)g(must)g(be)h(locally)g(less)f (than)h(maxwidth,)0 4800 y(b)n(ut)24 b(may)h(contain)f(bends,)g(T')-5 b(s,)24 b(and)h(X')-5 b(s.)900 4980 y Fa(maxwidth)25 b(tr)n(ench)i(2)e(bend)p 1941 4980 V 37 w(ok)2102 4980 y (") show 2102 4980 a 60 w Fa(tr)n(ench)i(must)e(be)g(exactly)g(2)g(wide)3419 4980 y (") show 3419 4980 a 146 5159 a Fa(W)-6 b(ar)o(ning:)37 b Fc(the)28 b(bend)p 941 5159 30 4 v 35 w(ok)g(rule)g(is)g(basically)f (a)i(kludge,)f(and)g(may)g(f)o(ail)g(for)g(re)o(gions)f(composed)g(of)h (more)0 5280 y(than)e(one)g(type,)h(or)f(for)h(intersections)e(more)i (complicated)e(than)h(T')-5 b(s)26 b(or)h(X')-5 b(s.)35 b(Figure)26 b(3)h(sho)n(ws)e(some)h(e)o(xam-)0 5400 y(ples)e(of)h(both) f(types)h(of)f(rules.)1875 5649 y(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Fc(Magic)24 b(T)l(utorial)g(#W)-6 b(-1:)30 b(Design-Rule)24 b(Extensions)1233 b(September)25 b(26,)g(2001)0 1459 y @beginspecial 68 @llx 68 @lly 862 @urx 365 @ury 4680 @rwi @setspecial %%BeginDocument: ../psfigures/tutw1.1.ps % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /pgsave save def bop % 1200 357 offsets 1.0000 inchscale 2.6000 setlinewidth 0.800 0.800 0.800 scb 240 1.00 192 261 192 965 1072 965 1072 261 4 polygon 240 1.00 1136 261 1136 965 2288 965 2288 261 4 polygon sce 0.745 0.600 0.871 scb 240 1.00 720 549 720 645 912 645 912 549 4 polygon 241 1.00 496 581 368 581 368 677 592 677 592 485 496 485 496 581 7 polygon sce 0 1.00 720 549 720 645 912 645 912 549 4 polygon 0.490 0.651 0.980 scb 241 1.00 1232 389 1616 389 1616 901 1232 901 1232 485 1168 485 1168 421 1232 421 1232 389 1296 453 1296 805 1552 805 1552 453 1296 453 14 polygon 241 1.00 1840 389 1840 613 1744 613 1744 677 1840 677 1840 901 2192 901 2192 581 2256 581 2256 517 2192 517 2192 389 1840 389 1904 453 2128 453 2128 517 2064 517 2064 581 2128 581 2128 837 1904 837 1904 453 22 polygon sce 0 1.00 1296 453 1296 805 1552 805 1552 453 4 polygon 1 1.00 1904 453 1904 837 2128 837 2128 581 2064 581 2064 517 2128 517 2128 453 1904 453 9 polygon 1 1.00 2192 389 1840 389 1840 613 1744 613 1744 677 1840 677 1840 901 2192 901 2192 581 2256 581 2256 517 2192 517 2192 389 13 polygon 1 1.00 1232 485 1232 901 1616 901 1616 389 1232 389 1232 421 1168 421 1168 485 1232 485 9 polygon 1 1.00 496 581 368 581 368 677 592 677 592 485 496 485 496 581 7 polygon (mwidth) {/Times-Roman 1.000 cf} 2 23 0 336 629 label (mwidth) {/Times-Roman 1.000 cf} 2 23 0 416 437 label (mwidth) {/Times-Roman 1.000 cf} 2 20 0 928 597 label 1 1.00 928 645 1008 645 2 polygon 1 1.00 928 549 1008 549 2 polygon 1 1.00 960 661 960 709 2 polygon 1 1.00 960 533 960 485 2 polygon 1 1.00 352 581 272 581 2 polygon 1 1.00 320 565 320 517 2 polygon 1 1.00 352 677 272 677 2 polygon 1 1.00 320 693 320 741 2 polygon 1 1.00 496 469 496 405 2 polygon 1 1.00 592 469 592 405 2 polygon 1 1.00 576 437 432 437 2 polygon 1.00 0 960 549 arrowhead 1.00 0 320 581 arrowhead 1.00 -181 320 677 arrowhead 1.00 -181 960 645 arrowhead 1.00 -91 592 437 arrowhead 1.00 -91 496 437 arrowhead (invalid) {/Times-Roman 1.250 cf} 2 21 0 464 325 label (valid) {/Times-Roman 1.250 cf} 2 21 0 816 325 label (invalid) {/Times-Roman 1.250 cf} 2 21 0 1424 325 label (valid) {/Times-Roman 1.250 cf} 2 21 0 2016 325 label (bend_ok) {/Times-Roman 1.500 cf} 2 21 0 1728 213 label (bend_illegal) {/Times-Roman 1.500 cf} 2 21 0 608 213 label pgsave restore showpage XCIRCsave restore %%EndDocument @endspecial 324 x(Figure)k(2:)38 b(Examples)28 b(of)g(the)h(maxwidth)e (rule.)42 b(The)29 b(dogle)o(g)e(at)i(the)f(left)h(w)o(ould)f(be)g(ok)h (in)f(a)h Fa(bend)p 3555 1783 30 4 v 37 w(ok)g Fc(rule,)0 1903 y(b)n(ut)h(f)o(ails)g(in)g(a)h Fa(bend)p 755 1903 V 37 w(illegal)f Fc(one,)i(where)f(the)f(re)o(gion')-5 b(s)29 b(bounding)g(box)h(is)g(check)o(ed.)49 b(F)o(or)30 b Fa(bend)p 3514 1903 V 38 w(ok)g Fc(rules,)0 2023 y(each)e(tile)e(in)g (the)h(re)o(gion)f(is)h(check)o(ed.)37 b(The)27 b(left)g(shape)g(f)o (ails)f(in)h(tw)o(o)f(places:)35 b(the)27 b(top)f(horizontal)g(part)h (is)g(too)0 2144 y(thick)d(and)h(the)g(stub)f(at)g(the)h(bottom)e (intersects)h(the)h(re)o(gion)f(in)g(a)i(shape)e(other)h(than)f(a)i(T)e (or)h(X.)0 2525 y Fe(4)143 b(Rules)35 b(on)g(CIF)g(lay)o(ers)0 2749 y Fc(F)o(or)21 b(technologies)f(with)h(complicated)f(generated)i (layers,)f(it)g(is)g(often)g(dif)n(\002cult)f(to)h(check)h(design)e (rules)h(on)g(the)0 2869 y(abstract)30 b(types)f(that)g(are)h(dra)o(wn) g(in)f(Magic.)45 b(T)-8 b(o)29 b(ameliorate)h(this)e(problem,)i(the)g (e)o(xtended)f(check)o(er)h(allo)n(ws)0 2990 y(simple)19 b(checks)i(to)f(be)h(performed)f(on)g(cif)h(layers.)29 b(The)21 b(rules)f(that)g(can)h(be)f(check)o(ed)h(are)g(width,)g (spacing,)f(area,)0 3110 y(and)28 b(maxarea.)40 b(Since)28 b(checking)g(rules)f(on)h(the)f(cif)h(layers)g(requires)g(that)f(these) h(layers)g(be)f(generated,)i(these)0 3230 y(checks)k(are)h (considerably)e(slo)n(wer)g(than)g(the)h(normal)f(ones,)j(and)d(should) g(only)g(be)h(used)g(when)f(absolutely)0 3351 y(necessary)-6 b(.)0 3643 y Fb(4.1)119 b(Setting)31 b(the)f(CIF)g(style)0 3830 y Fc(The)25 b Fa(cifstyle)g Fc(rule)f(is)h(used)f(to)h(select)f (which)h Fa(cif)n(output)h Fc(style)e(is)g(used.)900 4033 y Fa(cifstyle)h Fd(cif)p 1330 4033 V 35 w(style)146 4236 y(Cif)p 274 4236 V 36 w(style)36 b Fc(must)f(be)h(one)h(of)f(the)g (cif)h(styles)e(included)g(in)h(the)g(cifoutput)f(section.)65 b(In)36 b(the)g(current)h(im-)0 4357 y(plementation,)c(the)g(cif)g (check)o(er)h(generates)g(all)e(the)h(layers)g(in)g(the)g(style)f(re)o (gardless)g(of)h(whether)g(the)o(y)f(are)0 4477 y(actually)27 b(used)h(in)g(design-rule)f(checks;)i(for)f(speed,)h(de\002ning)e(a)i (separate)f(cif)g(style)f(for)h(design)g(rule)f(check-)0 4597 y(ing)h(it)g(may)f(be)i(w)o(orthwhile)e(when)h(only)g(a)g(fe)n(w)h (layers)f(are)h(check)o(ed.)42 b(An)o(y)27 b(layer)i(in)f(the)g(cif)g (style,)h(de\002ned)0 4718 y(by)c(either)f(a)h Fd(layer)g Fc(or)g(a)g Fd(templayer)f Fc(rule,)h(may)g(be)g(check)o(ed.)0 5009 y Fb(4.2)119 b(W)n(idth)30 b(Checks)0 5197 y Fc(The)25 b(syntax)f(for)h Fa(cifwidth)h Fc(is)e(analogous)g(to)g(that)h(of)f (the)h(re)o(gular)g(width)e(rule:)900 5400 y Fa(cifwidth)j Fd(layer)e(width)h(why)1875 5649 y Fc(\2263\226)p eop %%Page: 4 4 4 3 bop 0 -180 a Fc(September)25 b(26,)f(2001)1234 b(Magic)25 b(T)l(utorial)e(#W)-6 b(-1:)30 b(Design-Rule)25 b(Extensions)146 68 y Fd(Layer)j Fc(is)g(a)g(single)e(cif)i(layer)-5 b(.)39 b(\(T)-8 b(o)28 b(do)f(width)g(checks)h(with)f(more)g(than)g(one)h(cif) g(layer)l(,)g Fa(or)g Fc(all)g(the)f(layers)0 188 y(into)d(a)h(ne)n(w)f Fd(templayer)p Fc(\).)31 b Fd(W)-5 b(idth)23 b Fc(is)i(the)f(minimum)f (width)h(of)g(the)h(re)o(gion)f(in)g(centimicrons.)0 483 y Fb(4.3)119 b(Spacing)31 b(Checks)0 671 y Fc(The)25 b Fa(cifspacing)g Fc(rule)g(is)f(also)h(v)o(ery)f(similar)g(to)g(the)h (re)o(gular)f(rule:)900 899 y Fa(cifspacing)h Fd(layer1)g(layer2)f (separ)o(ation)f(adjacency)h(why)146 1128 y(Layer1)35 b Fc(and)e Fd(layer2)h Fc(are)h(both)e(cif)h(layers.)58 b(If)34 b Fd(adjacency)g Fc(is)g Fa(touching)p 2771 1128 30 4 v 36 w(ok)p Fc(,)j(then)c(layer1)h(must)f(equal)0 1248 y(layer2.)59 b(F)o(or)34 b Fa(touching)p 880 1248 V 36 w(illegal)f Fc(rules,)j Fd(layer1)e Fc(and)g Fd(layer2)g Fc(may)f(be)i(an)o(y)e(tw)o(o)h(cif)g(layers.)59 b Fd(Separ)o(ation)32 b Fc(is)0 1368 y(gi)n(v)o(en)23 b(in)i(centimicrons.)0 1664 y Fb(4.4)119 b(Ar)n(ea)30 b(Checks)0 1851 y Fc(The)25 b(area)h(rule)e(is:)900 2080 y Fa(cifar)n(ea)h Fd(layer)g(minar)l(ea)f (minedg)o(e)h(why)146 2308 y(Layer)g Fc(is)e(again)g(a)h(single)f(cif)h (layer)-5 b(.)30 b Fd(minedg)o(e)23 b Fc(is)h(e)o(xpressed)f(in)g (centimicrons,)g(and)h Fd(minar)l(ea)f Fc(is)g(gi)n(v)o(en)f(in)0 2428 y(square)j(centimicrons.)0 2723 y Fb(4.5)119 b(Maxwidth)31 b(Checks)0 2911 y Fc(The)25 b(maxwidth)e(rule)i(is:)900 3139 y Fa(cifmaxwidth)g Fd(layer)g(mwidth)f(bends)g(why)146 3368 y Fc(Again,)g Fd(layer)h Fc(is)f(a)h(single)f(cif)h(layer)l(,)g (and)g Fd(mwidth)f Fc(is)h(gi)n(v)o(en)e(in)h(centimicrons.)1875 5649 y(\2264\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tut6.ps0000644000175000001440000007531110751423606015145 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: tut6.dvi %%Pages: 5 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips tut6.dvi -o tut6.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Bold % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tut6.dvi) @start /Fa 134[50 1[72 1[55 33 39 44 1[55 50 55 2[55 2[55 1[33 44 55 44 55 50 38[33 3[50 51[55 2[{ TeXBase1Encoding ReEncodeFont }20 100.000003 /Times-Bold rf /Fb 138[66 40 47 53 2[60 66 100 33 2[33 66 2[53 66 53 1[60 12[80 6[113 9[86 8[40 55[66 2[{ TeXBase1Encoding ReEncodeFont } 19 119.999948 /Times-Bold rf /Fc 105[50 1[44 44 10[33 14[50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 3[33 1[33 1[72 1[94 1[72 61 55 66 1[55 72 1[89 3[33 72 72 55 61 72 66 66 72 5[28 28 50 1[50 50 50 50 50 50 50 50 28 25 33 25 2[33 33 33 3[50 31[55 55 2[{ TeXBase1Encoding ReEncodeFont }70 100.000003 /Times-Roman rf /Fd 134[44 3[50 28 39 39 1[50 50 50 4[28 50 2[44 50 1[50 50 11[72 5[72 4[44 27[25 1[25 2[33 33 40[{ TeXBase1Encoding ReEncodeFont }21 100.000003 /Times-Italic rf /Fe 134[72 3[80 48 56 64 2[72 80 120 40 80 1[40 80 72 48 64 1[64 80 72 12[96 80 104 1[88 112 1[135 96 2[56 112 112 1[96 104 104 8[48 3[72 72 72 72 72 72 3[48 9[72 35[{ TeXBase1Encoding ReEncodeFont }40 143.999997 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 673 101 a Fe(Magic)35 b(T)-13 b(utorial)34 b(#6:)44 b(Design-Rule)33 b(Checking)1618 521 y Fd(J)n(ohn)24 b(Ousterhout)1401 941 y Fc(Computer)g(Science)i(Di)n(vision)1020 1062 y(Electrical)f(Engineering)f(and)h(Computer)f(Sciences)1473 1182 y(Uni)n(v)o(ersity)f(of)i(California)1544 1303 y(Berk)o(ele)o(y)-6 b(,)24 b(CA)h(94720)1448 1573 y Fd(\(Updated)f(by)h(other)o(s,)f (too.\))1053 1843 y Fc(This)g(tutorial)g(corresponds)g(to)g(Magic)h(v)o (ersion)e(7.)0 2356 y Fb(T)-11 b(utorials)30 b(to)f(r)n(ead)h(\002rst:) 300 2547 y Fc(Magic)24 b(T)l(utorial)g(#1:)30 b(Getting)24 b(Started)300 2668 y(Magic)g(T)l(utorial)g(#2:)30 b(Basic)25 b(P)o(ainting)f(and)h(Selection)300 2788 y(Magic)f(T)l(utorial)g(#4:)30 b(Cell)25 b(Hierarchies)0 2979 y Fb(Commands)k(intr)n(oduced)j(in)f (this)f(tutorial:)300 3171 y Fc(:drc)0 3362 y Fb(Macr)n(os)f(intr)n (oduced)i(in)g(this)f(tutorial:)300 3575 y Fc(y)0 4454 y Fe(1)143 b(Continuous)34 b(Design-Rule)f(Checking)0 4678 y Fc(When)28 b(you)f(are)h(editing)f(a)h(layout)e(with)h(Magic,)h (the)f(system)g(automatically)f(checks)i(design)f(rules)g(on)g(your)0 4798 y(behalf.)j(Ev)o(ery)22 b(time)g(you)h(paint)f(or)h(erase,)h(and)e (e)n(v)o(ery)h(time)f(you)g(mo)o(v)o(e)f(a)i(cell)g(or)g(change)g(an)g (array)h(structure,)0 4918 y(Magic)d(rechecks)h(the)f(area)i(you)e (changed)g(to)g(be)h(sure)f(you)g(ha)n(v)o(en')n(t)g(violated)g(an)o(y) g(of)g(the)h(layout)e(rules.)30 b(If)22 b(you)0 5039 y(do)g(violate)f(rules,)h(Magic)g(will)f(display)g(little)g(white)h (dots)f(in)h(the)g(vicinity)e(of)j(the)f(violation.)28 b(This)21 b(error)i(paint)0 5159 y(will)j(stay)h(around)g(until)f(you)h (\002x)g(the)g(problem;)h(when)f(the)g(violation)e(is)i(corrected,)i (the)e(error)g(paint)g(will)f(go)0 5280 y(a)o(w)o(ay)h(automatically)-6 b(.)35 b(Error)27 b(paint)g(is)f(written)g(to)h(disk)f(with)g(your)h (cells)g(and)g(will)f(re-appear)i(the)f(ne)o(xt)f(time)0 5400 y(the)f(cell)f(is)h(read)g(in.)30 b(There)c(is)e(no)h(w)o(ay)f(to) h(get)g(rid)f(of)h(it)f(e)o(xcept)h(to)f(\002x)h(the)g(violation.)1875 5649 y(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Fc(September)25 b(26,)f(2001)1411 b(Magic)24 b(T)l(utorial)f(#6:)31 b(Design-Rule)24 b(Checking)146 68 y(Continuous)h(design-rule)h(checking)g(means)g(that)g(you)g(al)o(w) o(ays)g(ha)n(v)o(e)g(an)g(up-to-date)g(picture)g(of)h(design-)0 188 y(rule)i(errors)g(in)f(your)g(layout.)41 b(There)29 b(is)f(ne)n(v)o(er)g(an)o(y)g(need)h(to)f(run)g(a)h(massi)n(v)o(e)e (check)i(o)o(v)o(er)e(the)i(whole)f(design)0 309 y(unless)21 b(you)g(change)h(your)f(design)g(rules.)29 b(When)22 b(you)f(mak)o(e)g(small)g(changes)g(to)g(an)h(e)o(xisting)e(layout,)h (you)g(will)0 429 y(\002nd)27 b(out)g(immediately)e(if)i(you')-5 b(v)o(e)26 b(introduced)g(errors,)i(without)e(ha)n(ving)g(to)h (completely)e(recheck)j(the)f(entire)0 549 y(layout.)146 670 y(T)-8 b(o)25 b(see)h(ho)n(w)f(the)g(check)o(er)h(w)o(orks,)f(run)g (Magic)g(on)g(the)g(cell)g Fa(tut6a)p Fc(.)33 b(This)25 b(cell)g(contains)f(se)n(v)o(eral)h(areas)h(of)0 790 y(metal)31 b(\(blue\),)i(some)d(of)i(which)e(are)i(too)f(close)g(to)g (each)h(other)f(or)g(too)g(narro)n(w)-6 b(.)49 b(T)m(ry)31 b(painting)f(and)h(erasing)0 911 y(metal)24 b(to)h(mak)o(e)f(the)h (error)h(paint)e(go)g(a)o(w)o(ay)h(and)g(re-appear)h(again.)0 1245 y Fe(2)143 b(Getting)34 b(Inf)l(ormation)g(about)g(Err)m(ors)0 1469 y Fc(In)f(man)o(y)f(cases,)j(the)e(reason)g(for)g(a)g(design-rule) g(violation)e(will)h(be)h(ob)o(vious)e(to)i(you)f(as)h(soon)f(as)h(you) g(see)0 1589 y(the)28 b(error)g(paint.)39 b(Ho)n(we)n(v)o(er)l(,)27 b(Magic)g(pro)o(vides)g(se)n(v)o(eral)g(commands)f(for)i(you)f(to)h (use)f(to)g(\002nd)h(violations)e(and)0 1709 y(\002gure)k(what')-5 b(s)28 b(wrong)h(in)g(case)h(it)f(isn')n(t)g(ob)o(vious.)42 b(All)29 b(of)g(the)g(design-rule)g(checking)g(commands)f(ha)n(v)o(e)h (the)0 1830 y(form)900 2020 y Fa(:dr)n(c)d Fd(option)146 2211 y Fc(where)d Fd(option)d Fc(selects)h(one)h(of)g(se)n(v)o(eral)f (commands)f(understood)h(by)g(the)h(design-rule)f(check)o(er)-5 b(.)30 b(If)22 b(you')-5 b(re)0 2331 y(not)30 b(sure)g(why)f(error)i (paint)e(has)h(suddenly)f(appeared,)j(place)f(the)f(box)g(around)f(the) h(error)h(paint)f(and)g(in)l(v)n(ok)o(e)0 2451 y(the)25 b(command)900 2642 y Fa(:dr)n(c)h(wh)o(y)146 2832 y Fc(This)36 b(command)g(will)g(recheck)h(the)g(area)g(underneath)g(the)f(box,)j (and)e(print)f(out)g(the)g(reasons)h(for)g(an)o(y)0 2953 y(violations)21 b(that)i(were)h(found.)30 b(Y)-11 b(ou)23 b(can)h(also)f(use)g(the)g(macro)h Fa(y)f Fc(to)g(do)g(the)h(same)f (thing.)29 b(T)m(ry)23 b(this)f(on)h(some)g(of)0 3073 y(the)k(errors)h(in)g Fa(tut6a)p Fc(.)39 b(It')-5 b(s)27 b(a)h(good)f(idea)g(to)h(place)f(the)h(box)f(right)g(around)g(the)h (area)g(of)g(the)f(error)h(paint:)36 b Fa(:dr)n(c)0 3194 y(wh)o(y)25 b Fc(rechecks)g(the)g(entire)f(area)i(under)f(the)g(box,)f (so)g(it)h(may)f(tak)o(e)h(a)g(long)f(time)g(if)h(the)g(box)f(is)g(v)o (ery)h(lar)n(ge.)146 3314 y(If)f(you')-5 b(re)24 b(w)o(orking)f(in)g(a) h(lar)n(ge)g(cell,)f(it)g(may)h(be)f(hard)h(to)f(see)h(the)f(error)i (paint.)k(T)-8 b(o)24 b(help)f(locate)g(the)h(errors,)0 3434 y(select)h(a)g(cell)g(and)f(then)h(use)g(the)f(command)900 3625 y Fa(:dr)n(c)i(\002nd)g Fc([)p Fd(nth)p Fc(])146 3815 y(If)38 b(you)f(don')n(t)g(pro)o(vide)f(the)h Fd(nth)g Fc(ar)n(gument,)j(the)d(command)f(will)h(place)h(the)f(box)g(around)g (one)g(of)g(the)0 3936 y(errors)26 b(in)f(the)g(selected)g(cell,)g(and) g(print)g(out)f(the)h(reason)h(for)f(the)g(error)l(,)h(just)f(as)g(if)g (you)g(had)g(typed)g Fa(:dr)n(c)h(wh)o(y)p Fc(.)0 4056 y(If)33 b(you)g(in)l(v)n(ok)o(e)f(the)h(command)f(repeatedly)-6 b(,)35 b(it)e(will)f(step)g(through)g(all)h(of)g(the)g(errors)h(in)e (the)h(selected)g(cell.)0 4176 y(\(remember)l(,)g(the)e(\223.)-7 b(\224)50 b(macro)32 b(can)f(be)h(used)e(to)h(repeat)h(the)f(last)g (long)f(command;)j(this)d(will)h(sa)n(v)o(e)g(you)f(from)0 4297 y(ha)n(ving)d(to)g(retype)h Fa(:dr)n(c)h(\002nd)g Fc(o)o(v)o(er)d(and)i(o)o(v)o(er)f(again\).)38 b(T)m(ry)27 b(this)g(out)g(on)g(the)h(errors)g(in)f Fa(tut6a)p Fc(.)39 b(If)28 b(you)g(type)f(a)0 4417 y(number)g(for)g Fd(nth)p Fc(,)h(the)f(command)f(will)h(go)g(to)g(the)g Fd(nth)g Fc(error)h(in)f(the)g(selected)g(cell,)h(instead)f(of)h(the)f(ne)o(xt)f (one.)0 4538 y(If)f(you)g(in)l(v)n(ok)o(e)f(this)g(command)f(with)h(no) h(cell)g(selected,)f(it)h(searches)g(the)g(edit)f(cell.)146 4658 y(A)f(third)f(drc)h(command)e(is)h(pro)o(vided)g(to)g(gi)n(v)o(e)f (you)h(summary)g(information)f(about)h(errors)h(in)f(hierarchical)0 4778 y(designs.)30 b(The)24 b(command)g(is)900 4969 y Fa(:dr)n(c)i(count)146 5159 y Fc(This)h(command)f(will)g(search)h(e)n (v)o(ery)g(cell)g(\(visible)f(or)h(not\))f(that)h(lies)f(underneath)h (the)g(box)g(to)f(see)i(if)f(an)o(y)0 5280 y(ha)n(v)o(e)g(errors)i(in)e (them.)39 b(F)o(or)28 b(each)g(cell)g(with)f(errors,)i Fa(:dr)n(c)g(count)g Fc(will)e(print)g(out)g(a)h(count)f(of)h(the)g (number)f(of)0 5400 y(error)e(areas.)1875 5649 y(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Fc(Magic)24 b(T)l(utorial)g(#6:)30 b(Design-Rule)25 b(Checking)1410 b(September)25 b(26,)g(2001)0 99 y Fe(3)143 b(Err)m(ors)35 b(in)g(Hierar)m(chical)f(Lay)l(outs)0 322 y Fc(The)j(design-rule)g(check)o(er)h(w)o(orks)e(on)h(hierarchical) h(layouts)e(as)h(well)g(as)g(single)f(cells.)67 b(There)38 b(are)g(three)0 443 y(o)o(v)o(erall)24 b(rules)g(that)g(describe)h(the) g(w)o(ay)g(that)f(Magic)h(checks)g(hierarchical)g(designs:)120 671 y(1.)49 b(The)26 b(paint)g(in)g(each)h(cell)f(must)f(obe)o(y)h(all) g(the)g(design)f(rules)i(by)f(itself,)f(without)g(considering)h(the)g (paint)244 792 y(in)e(an)o(y)h(other)f(cells,)h(including)e(its)h (children.)120 995 y(2.)49 b(The)23 b(combined)f(paint)h(of)g(each)h (cell)f(and)g(all)g(of)g(its)f(descendants)h(\(subcells,)g (sub-subcells,)f(etc.\))30 b(must)244 1116 y(be)24 b(consistent.)29 b(If)c(a)f(subcell)g(interacts)g(with)f(paint)h(or)g(with)f(other)h (subcells)g(in)f(a)i(w)o(ay)f(that)g(introduces)244 1236 y(a)33 b(design-rule)f(violation,)g(an)h(error)g(will)f(appear)h(in)f (the)h(parent.)54 b(In)32 b(designs)g(with)f(man)o(y)h(le)n(v)o(els)f (of)244 1356 y(hierarchy)-6 b(,)24 b(this)g(rule)h(is)f(applied)g (separately)h(to)f(each)i(cell)f(and)f(its)g(descendants.)120 1560 y(3.)49 b(Each)23 b(array)h(must)f(be)g(consistent)f(by)h(itself,) g(without)f(considering)g(an)o(y)h(other)g(subcells)f(or)h(paint)g(in)g (its)244 1680 y(parent.)46 b(If)31 b(the)f(neighboring)e(elements)i(of) g(an)g(array)h(interact)e(to)h(produce)g(a)g(design-rule)g(violation,) 244 1801 y(the)25 b(violation)e(will)h(appear)h(in)f(the)h(parent.)146 2029 y(T)-8 b(o)30 b(see)g(some)f(e)o(xamples)f(of)i(interaction)f (errors,)i(edit)e(the)g(cell)h Fa(tut6b)p Fc(.)46 b(This)29 b(cell)h(doesn')n(t)f(mak)o(e)g(sense)0 2150 y(electrically)-6 b(,)37 b(b)n(ut)d(illustrates)f(the)i(features)g(of)g(the)g (hierarchical)g(check)o(er)-5 b(.)62 b(On)34 b(the)h(left)g(are)h(tw)o (o)e(subcells)0 2270 y(that)29 b(are)h(too)f(close)g(together)-5 b(.)43 b(In)29 b(addition,)g(the)g(subcells)g(are)h(too)e(close)i(to)e (the)i(red)f(paint)g(in)g(the)g(top-le)n(v)o(el)0 2390 y(cell.)39 b(Mo)o(v)o(e)26 b(the)h(subcells)g(and/or)g(modify)f(the)i (paint)f(to)g(mak)o(e)g(the)h(errors)f(go)h(a)o(w)o(ay)f(and)h (reappear)-5 b(.)39 b(On)27 b(the)0 2511 y(right)33 b(side)h(of)f Fa(tut6b)i Fc(is)f(an)g(array)g(whose)g(elements)f(interact)g(to)h (produce)g(a)g(design-rule)f(violation.)56 b(Edit)0 2631 y(an)27 b(element)f(of)h(the)f(array)i(to)e(mak)o(e)h(the)f(violation)f (go)h(a)o(w)o(ay)-6 b(.)36 b(When)27 b(there)g(are)g(interaction)f (errors)h(between)0 2752 y(the)37 b(elements)f(of)h(an)g(array)-6 b(,)40 b(the)c(errors)h(al)o(w)o(ays)g(appear)g(near)h(one)f(of)f(the)h (four)g(corner)g(elements)f(of)h(the)0 2872 y(array)25 b(\(since)f(the)h(array)g(spacing)f(is)f(uniform,)h(Magic)g(only)f (checks)i(interactions)e(near)i(the)f(corners;)h(if)f(these)0 2992 y(elements)g(are)i(correct,)f(all)g(the)f(ones)h(in)f(the)h (middle)e(must)h(be)h(correct)h(too\).)146 3113 y(It')-5 b(s)25 b(important)f(to)h(remember)g(that)g(each)h(of)g(the)f(three)h (o)o(v)o(erall)e(rules)h(must)f(be)i(satis\002ed)f(independently)-6 b(.)0 3233 y(This)28 b(may)g(sometimes)f(result)h(in)g(errors)h(where)f (it)g(doesn')n(t)h(seem)f(lik)o(e)g(there)h(should)e(be)h(an)o(y)-6 b(.)41 b(Edit)28 b(the)g(cell)0 3353 y Fa(tut6c)g Fc(for)g(some)f(e)o (xamples)f(of)h(this.)38 b(On)27 b(the)g(left)h(side)f(of)g(the)g(cell) h(there)f(is)g(a)h(sli)n(v)o(er)e(of)h(paint)g(in)g(the)g(parent)0 3474 y(that)33 b(e)o(xtends)g(paint)g(in)g(a)h(subcell.)56 b(Although)32 b(the)i(o)o(v)o(erall)e(design)h(is)g(correct,)k(the)c (sli)n(v)o(er)f(of)i(paint)f(in)g(the)0 3594 y(parent)k(is)g(not)f (correct)i(by)f(itself,)i(as)e(required)g(by)g(the)g(\002rst)g(o)o(v)o (erall)f(rule)h(abo)o(v)o(e.)66 b(On)37 b(the)g(right)f(side)h(of)0 3715 y Fa(tut6c)d Fc(is)g(an)f(array)i(with)d(spacing)h(violations)f (between)i(the)f(array)i(elements.)56 b(Ev)o(en)33 b(though)f(the)i (paint)e(in)0 3835 y(the)d(parent)f(masks)g(some)g(of)h(the)g (problems,)f(the)h(array)g(is)g(not)f(consistent)f(by)i(itself)f(so)g (errors)h(are)h(\003agged.)0 3955 y(The)g(three)g(o)o(v)o(erall)e (rules)i(are)g(more)g(conserv)n(ati)n(v)o(e)e(than)h(strictly)g (necessary)-6 b(,)31 b(b)n(ut)e(the)o(y)g(reduce)h(the)g(amount)0 4076 y(of)25 b(rechecking)h(Magic)e(must)h(do.)31 b(F)o(or)25 b(e)o(xample,)g(the)g(array)h(rule)f(allo)n(ws)f(Magic)h(to)f(deduce)i (the)f(correctness)0 4196 y(of)f(an)g(array)h(by)f(looking)e(only)h(at) i(the)e(corner)i(elements;)e(if)h(paint)f(from)h(the)g(parent)g(had)g (to)g(be)g(considered)f(in)0 4317 y(checking)k(arrays,)i(it)e(w)o(ould) g(be)h(necessary)g(to)g(check)g(the)f(entire)h(array)g(since)g(there)g (might)e(be)i(parent)g(paint)0 4437 y(masking)c(some)g(errors)h(b)n(ut) f(not)g(all)h(\(as,)g(for)g(e)o(xample,)f(in)g Fa(tut6c)p Fc(\).)146 4557 y(Error)36 b(paint)e(appears)i(in)e(dif)n(ferent)h (cells)g(in)f(the)h(hierarchy)-6 b(,)37 b(depending)d(on)h(what)g(kind) f(of)h(error)h(w)o(as)0 4678 y(found.)46 b(Errors)30 b(resulting)f(from)h(paint)g(in)f(a)i(single)e(cell)h(cause)g(error)h (paint)f(to)f(appear)i(in)f(that)f(cell.)47 b(Errors)0 4798 y(resulting)21 b(from)h(interactions)f(and)h(arrays)g(appear)h(in) f(the)g(parent)g(of)g(the)g(interacting)f(cells)h(or)g(array)-6 b(.)30 b(Because)0 4918 y(of)g(the)h(w)o(ay)f(Magic)g(mak)o(es)g (interaction)g(checks,)i(errors)f(can)f(sometimes)f(\223b)n(ubble)h (up\224)g(through)g(the)g(hier)n(-)0 5039 y(archy)i(and)g(appear)h(in)f (multiple)f(cells.)52 b(When)33 b(tw)o(o)e(cells)h(o)o(v)o(erlap,)h (Magic)f(checks)g(this)g(area)h(by)f(cop)o(ying)0 5159 y(all)g(the)g(paint)f(in)h(that)f(area)i(from)f(both)f(cells)h(\(and)g (their)g(descendants\))f(into)g(a)i(b)n(uf)n(fer)f(and)g(then)f (checking)0 5280 y(the)26 b(b)n(uf)n(fer)-5 b(.)35 b(Magic)26 b(is)g(unable)g(to)g(tell)g(the)g(dif)n(ference)g(between)h(an)f(error) h(from)f(one)h(of)f(the)g(subcells)g(and)g(an)0 5400 y(error)j(that)f(comes)h(about)f(because)h(the)f(tw)o(o)g(subcells)g(o) o(v)o(erlap)f(incorrectly)-6 b(.)42 b(This)27 b(means)i(that)f(errors)h (in)f(an)1875 5649 y(\2263\226)p eop %%Page: 4 4 4 3 bop 0 -180 a Fc(September)25 b(26,)f(2001)1411 b(Magic)24 b(T)l(utorial)f(#6:)31 b(Design-Rule)24 b(Checking)0 68 y(interaction)k(area)j(of)e(a)h(cell)f(may)g(also)g(appear)h(in)f (the)g(cell')-5 b(s)28 b(parent.)45 b(Fixing)28 b(the)h(error)h(in)f (the)g(subcell)g(will)0 188 y(cause)c(the)g(error)g(in)g(the)f(parent)h (to)g(go)f(a)o(w)o(ay)h(also.)0 556 y Fe(4)143 b(T)-13 b(ur)n(ning)34 b(the)h(Check)o(er)e(Off)0 788 y Fc(W)-8 b(e)29 b(hope)g(that)g(in)g(most)e(cases)j(the)f(check)o(er)h(will)e (run)h(so)f(quickly)g(and)h(quietly)f(that)h(you)f(hardly)h(kno)n(w)f (it')-5 b(s)0 909 y(there.)31 b(Ho)n(we)n(v)o(er)l(,)23 b(there)i(will)e(probably)h(be)h(some)e(situations)g(where)i(the)f (check)o(er)h(is)f(irksome.)30 b(This)24 b(section)0 1029 y(describes)h(se)n(v)o(eral)f(w)o(ays)g(to)h(k)o(eep)g(the)f (check)o(er)i(out)e(of)h(your)g(hair)-5 b(.)146 1154 y(If)26 b(you')-5 b(re)25 b(w)o(orking)f(on)h(a)h(cell)f(with)f(lots)g (of)i(design-rule)e(violations)f(the)i(constant)g(redisplay)f(caused)h (by)0 1274 y(design-rule)h(checking)f(may)h(get)g(in)g(your)g(w)o(ay)g (more)g(than)g(it)g(helps.)34 b(This)25 b(is)h(particularly)g(true)g (if)g(you')-5 b(re)26 b(in)0 1395 y(the)21 b(middle)f(of)h(a)h(lar)n (ge)f(series)g(of)h(changes)f(and)g(don')n(t)g(care)h(about)e (design-rule)h(violations)e(until)h(the)h(changes)0 1515 y(are)26 b(\002nished.)k(Y)-11 b(ou)24 b(can)i(stop)e(the)g(redisplay)g (using)g(the)h(command)900 1778 y Fa(:see)g(no)g(err)n(ors)146 2037 y Fc(After)g(this)e(command)h(is)g(typed,)f(design-rule)h(errors)h (will)e(no)h(longer)g(be)h(displayed)e(on)h(the)g(screen.)31 b(The)0 2158 y(design-rule)h(check)o(er)i(will)f(continue)f(to)h(run)g (and)g(will)f(store)h(error)h(information)e(internally)-6 b(,)33 b(b)n(ut)g(it)f(w)o(on')n(t)0 2278 y(bother)24 b(you)h(by)f(displaying)f(it)i(on)f(the)h(screen.)31 b(When)25 b(you')-5 b(re)25 b(ready)g(to)f(see)i(errors)f(again,)f (type)900 2541 y Fa(:see)h(err)n(ors)146 2800 y Fc(There)j(can)f(also)f (be)h(times)f(when)h(it')-5 b(s)26 b(not)g(the)h(redisplay)f(that')-5 b(s)26 b(bothersome,)g(b)n(ut)h(the)f(amount)g(of)h(CPU)0 2921 y(time)21 b(the)h(check)o(er)h(tak)o(es)f(to)g(recheck)h(what)f (you')-5 b(v)o(e)21 b(changed.)30 b(F)o(or)22 b(e)o(xample,)g(if)g(a)g (lar)n(ge)h(subcell)e(is)h(mo)o(v)o(ed)e(to)0 3041 y(o)o(v)o(erlap)i (another)i(lar)n(ge)g(subcell,)f(the)g(entire)g(o)o(v)o(erlap)g(area)h (will)f(ha)n(v)o(e)g(to)g(be)h(recheck)o(ed,)g(and)g(this)e(could)h (tak)o(e)0 3161 y(se)n(v)o(eral)h(minutes.)30 b(If)25 b(the)g(prompt)f(on)g(the)h(te)o(xt)f(screen)i(is)e(a)h(\223]\224)h (character)l(,)g(it)e(means)h(that)f(the)h(command)f(has)0 3282 y(completed)f(b)n(ut)g(the)h(check)o(er)h(hasn')n(t)e(caught)h(up) f(yet.)30 b(Y)-11 b(ou)24 b(can)g(in)l(v)n(ok)o(e)f(ne)n(w)h(commands)e (while)i(the)f(check)o(er)0 3402 y(is)h(running,)g(and)h(the)g(check)o (er)g(will)f(suspend)g(itself)g(long)g(enough)g(to)h(process)f(the)h (ne)n(w)g(commands.)146 3527 y(If)d(the)f(check)o(er)h(tak)o(es)f(too)f (long)h(to)g(interrupt)f(itself)g(and)h(respond)g(to)g(your)g (commands,)f(you)h(ha)n(v)o(e)g(se)n(v)o(eral)0 3647 y(options.)33 b(First,)26 b(you)f(can)i(hit)e(the)h(interrupt)f(k)o(e)o (y)h(\(often)g(\210C\))h(on)e(the)h(k)o(e)o(yboard.)34 b(This)25 b(will)g(stop)g(the)h(check)o(er)0 3768 y(immediately)f(and)h (w)o(ait)g(for)g(your)g(ne)o(xt)g(command.)34 b(As)26 b(soon)g(as)g(you)g(issue)f(a)i(command)e(or)i(push)e(a)i(mouse)0 3888 y(b)n(utton,)c(the)i(check)o(er)h(will)e(start)g(up)h(again.)30 b(T)-8 b(o)24 b(turn)h(the)f(check)o(er)i(of)n(f)f(altogether)l(,)f (type)g(the)h(command)900 4151 y Fa(:dr)n(c)h(off)146 4410 y Fc(From)g(this)g(point)f(on,)h(the)g(check)o(er)h(will)e(not)h (run.)34 b(Magic)26 b(will)f(record)i(the)f(areas)h(that)f(need)g (rechecking)0 4530 y(b)n(ut)32 b(w)o(on')n(t)g(do)g(the)h(rechecks.)54 b(If)33 b(you)f(sa)n(v)o(e)g(your)g(\002le)h(and)f(quit)g(Magic,)i(the) e(information)f(about)h(areas)h(to)0 4651 y(recheck)27 b(will)e(be)h(sa)n(v)o(ed)f(on)h(disk.)33 b(The)26 b(ne)o(xt)f(time)g (you)h(read)g(in)g(the)g(cell,)g(Magic)f(will)g(recheck)i(those)e (areas,)0 4771 y(unless)j(you')-5 b(v)o(e)28 b(still)g(got)g(the)h (check)o(er)g(turned)g(of)n(f.)43 b(There)29 b(is)f(nothing)g(you)g (can)i(do)e(to)h(mak)o(e)f(Magic)h(for)n(get)0 4892 y(about)24 b(areas)i(to)e(recheck;)i Fa(:dr)n(c)g(off)f Fc(merely)f(postpones)g (the)g(recheck)i(operation)e(to)h(a)g(later)g(time.)146 5016 y(Once)38 b(you')-5 b(v)o(e)36 b(turned)h(the)g(check)o(er)h(of)n (f,)i(you)d(ha)n(v)o(e)g(tw)o(o)f(w)o(ays)h(to)g(mak)o(e)g(sure)g(e)n (v)o(erything)f(has)h(been)0 5137 y(recheck)o(ed.)32 b(The)24 b(\002rst)h(is)g(to)f(type)h(the)f(command)900 5400 y Fa(:dr)n(c)i(catchup)1875 5649 y Fc(\2264\226)p eop %%Page: 5 5 5 4 bop 0 -180 a Fc(Magic)24 b(T)l(utorial)g(#6:)30 b(Design-Rule)25 b(Checking)1410 b(September)25 b(26,)g(2001)146 68 y(This)c(command)g (will)f(run)i(the)f(check)o(er)i(and)e(w)o(ait)g(until)g(e)n(v)o (erything)e(has)j(been)f(recheck)o(ed)i(and)e(errors)h(are)0 188 y(completely)g(up)h(to)f(date.)30 b(When)23 b(the)g(command)f (completes,)g(the)h(check)o(er)h(will)e(still)g(be)h(enabled)g(or)g (disabled)0 309 y(just)29 b(as)g(it)h(w)o(as)f(before)h(the)g(command.) 44 b(If)30 b(you)f(get)h(tired)f(of)h(w)o(aiting)f(for)h Fa(:dr)n(c)h(catchup)p Fc(,)h(you)d(can)h(al)o(w)o(ays)0 429 y(hit)23 b(the)g(interrupt)f(k)o(e)o(y)h(to)g(abort)g(the)g (command;)g(the)g(recheck)h(areas)g(will)e(be)i(remembered)f(for)h (later)-5 b(.)29 b(T)-8 b(o)24 b(turn)0 549 y(the)h(check)o(er)g(back)g (on)g(permanently)-6 b(,)23 b(in)l(v)n(ok)o(e)h(the)h(command)900 778 y Fa(:dr)n(c)h(on)0 1117 y Fe(5)143 b(P)m(orting)34 b(Lay)l(outs)h(fr)m(om)g(Other)f(Systems)0 1341 y Fc(Y)-11 b(ou)30 b(should)f(not)h(need)g(to)g(read)h(this)e(section)h(if)g(you') -5 b(v)o(e)30 b(created)h(your)f(layout)g(from)g(scratch)g(using)f (Magic)0 1461 y(or)i(ha)n(v)o(e)g(read)g(it)g(from)g(CIF)h(using)e (Magic')-5 b(s)30 b(CIF)i(or)f(Calma)h(reader)-5 b(.)50 b(Ho)n(we)n(v)o(er)l(,)31 b(if)g(you)f(are)i(bringing)e(into)0 1582 y(Magic)23 b(a)h(layout)f(that)g(w)o(as)g(created)h(using)f(a)g (dif)n(ferent)h(editor)f(or)g(an)h(old)f(v)o(ersion)f(of)i(Magic)f (that)g(didn')n(t)f(ha)n(v)o(e)0 1702 y(continuous)g(checking,)h(read)h (on.)30 b(Y)-11 b(ou)23 b(may)g(also)f(need)i(to)f(read)h(this)e (section)h(if)g(you')-5 b(v)o(e)22 b(changed)i(the)f(design)0 1822 y(rules)i(in)f(the)h(technology)e(\002le.)146 1943 y(In)33 b(order)g(to)g(\002nd)g(out)f(about)g(errors)h(in)g(a)g(design) f(that)g(w)o(asn')n(t)h(created)g(with)f(Magic,)i(you)f(must)e(force)0 2063 y(Magic)g(to)g(recheck)h(e)n(v)o(erything)d(in)i(the)g(design.)49 b(Once)32 b(this)e(global)g(recheck)i(has)f(been)h(done,)g(Magic)f (will)0 2184 y(use)24 b(its)f(continuous)g(check)o(er)i(to)e(deal)i (with)e(an)o(y)g(changes)i(you)e(mak)o(e)h(to)g(the)g(design;)f(you)h (should)f(only)g(need)0 2304 y(to)g(do)g(the)h(global)e(recheck)j (once.)30 b(T)-8 b(o)24 b(mak)o(e)f(the)g(global)g(recheck,)i(load)e (your)g(design,)g(place)h(the)f(box)g(around)0 2424 y(the)i(entire)f (design,)g(and)h(type)900 2653 y Fa(:dr)n(c)h(check)146 2881 y Fc(This)h(will)f(cause)i(Magic)f(to)f(act)i(as)f(if)g(the)g (entire)h(area)g(under)f(the)g(box)g(had)g(just)f(been)i(modi\002ed:)34 b(it)27 b(will)0 3001 y(recheck)i(that)f(entire)g(area.)42 b(Furthermore,)29 b(it)e(will)h(w)o(ork)g(its)f(w)o(ay)h(do)n(wn)g (through)f(the)h(hierarchy;)h(for)g(e)n(v)o(ery)0 3122 y(subcell)24 b(found)g(underneath)h(the)g(box,)f(it)g(will)g(recheck)i (that)e(subcell)g(o)o(v)o(er)g(the)h(area)h(of)f(the)f(box.)146 3242 y(If)j(you)f(get)h(nerv)n(ous)f(that)g(a)h(design-rule)f (violation)e(might)i(someho)n(w)f(ha)n(v)o(e)h(been)h(missed,)e(you)h (can)h(use)0 3362 y Fa(:dr)n(c)35 b(check)g Fc(to)e(force)i(an)o(y)e (area)i(to)e(be)h(recheck)o(ed)g(at)g(an)o(y)f(time,)i(e)n(v)o(en)e (for)h(cells)f(that)g(were)i(created)f(with)0 3483 y(Magic.)52 b(Ho)n(we)n(v)o(er)l(,)33 b(this)e(should)g(ne)n(v)o(er)g(be)h (necessary)h(unless)e(you')-5 b(v)o(e)31 b(changed)h(the)g(design)g (rules.)52 b(If)32 b(the)0 3603 y(number)25 b(of)h(errors)g(in)g(the)g (layout)e(e)n(v)o(er)i(changes)g(because)g(of)g(a)g Fa(:dr)n(c)h(check) p Fc(,)h(it)d(is)g(a)i(b)n(ug)e(in)g(Magic)h(and)g(you)0 3724 y(should)e(notify)g(us)g(immediately)-6 b(.)1875 5649 y(\2265\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/maint3.ps0000644000175000001440000006621410751423606015440 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: maint3.dvi %%Pages: 4 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips maint3.dvi -o maint3.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Bold % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (maint3.dvi) @start /Fa 134[50 1[72 2[33 39 44 1[55 50 55 83 28 2[28 55 50 1[44 55 44 55 50 19[94 21[50 1[50 50 1[50 50 2[25 33 3[33 33 40[{ TeXBase1Encoding ReEncodeFont }28 100.000003 /Times-Bold rf /Fb 138[66 40 47 53 2[60 66 100 33 2[33 66 2[53 66 53 1[60 12[80 6[113 9[86 8[40 55[66 2[{ TeXBase1Encoding ReEncodeFont }19 119.999948 /Times-Bold rf /Fc 105[50 1[44 44 24[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 1[28 50 50 33 44 50 44 50 44 7[72 1[94 1[72 61 55 66 1[55 72 1[89 61 1[39 33 72 72 55 61 72 66 66 72 5[28 28 50 50 50 50 1[50 50 50 50 50 1[25 33 25 2[33 33 33 3[50 31[55 55 2[{ TeXBase1Encoding ReEncodeFont }68 100.000003 /Times-Roman rf /Fd 133[39 44 44 2[50 28 39 39 50 50 50 50 72 28 2[28 50 2[44 1[44 50 50 8[61 3[55 1[61 2[72 66 83 2[44 33 3[61 72 66 1[61 18[25 4[33 33 40[{ TeXBase1Encoding ReEncodeFont }34 100.000003 /Times-Italic rf /Fe 134[72 3[80 48 56 64 80 80 72 80 120 40 2[40 80 72 1[64 80 64 1[72 12[96 80 3[112 1[135 96 2[56 1[112 2[104 104 8[48 4[72 72 72 72 72 4[36 4[48 3[72 35[{ TeXBase1Encoding ReEncodeFont }36 143.999997 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 0 101 a Fe(Magic)35 b(Maintainer')-5 b(s)32 b(Manual)j(#3:)43 b(Display)33 b(Styles,)h(Colormaps,)f(and)1731 237 y(Glyphs)1630 657 y Fd(Robert)24 b(N.)i(Mayo)1618 778 y(J)n(ohn)e(Ousterhout)1401 1198 y Fc(Computer)g(Science)i(Di)n(vision)1020 1319 y(Electrical)f(Engineering)f(and)h(Computer)f(Sciences)1473 1439 y(Uni)n(v)o(ersity)f(of)i(California)1544 1559 y(Berk)o(ele)o(y)-6 b(,)24 b(CA)h(94720)1053 1830 y(This)f(tutorial)g(corresponds)g(to)g (Magic)h(v)o(ersion)e(7.)0 2351 y Fb(T)-11 b(utorials)30 b(to)f(r)n(ead)h(\002rst:)300 2549 y Fc(All)24 b(of)h(them.)0 2747 y Fb(Commands)k(intr)n(oduced)j(in)f(this)f(tutorial:)300 2945 y Fd(\(None\))0 3143 y Fb(Macr)n(os)f(intr)n(oduced)i(in)g(this)f (tutorial:)300 3364 y Fd(\(None\))0 4253 y Fe(1)143 b(Intr)m(oduction)0 4477 y Fc(This)23 b(document)g(gi)n(v)o(es)f(o)o(v)o(erall)h (information)f(about)h(the)h(\002les)g(that)f(tell)g(Magic)h(ho)n(w)e (to)i(display)f(information)0 4597 y(on)28 b(the)h(screen.)42 b(There)29 b(are)g(three)g(types)f(of)g(\002les)h(that)f(contain)g (display)g(information:)36 b(display)27 b(styles)h(\002les,)0 4718 y(color)n(-map)c(\002les,)h(and)g(glyph)f(\002les.)0 5056 y Fe(2)143 b(Display)34 b(Styles)0 5280 y Fc(Display)26 b(styles)g(\002les)h(describe)g(ho)n(w)f(to)g(dra)o(w)g(rectangular)i (areas)f(and)g(te)o(xt.)36 b(A)26 b(single)g(\002le)i(contains)e(a)h (lar)n(ge)0 5400 y(number)f(of)g(display)f(styles.)33 b(Each)27 b(display)e(style)g(contains)g(tw)o(o)h(kinds)f(of)h (information:)32 b(a\))26 b(ho)n(w)f(to)h(modify)1875 5649 y(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Fc(September)25 b(26,)f(2001)233 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#3:)30 b(Display)24 b(Styles,)g(Colormaps,)g(and)h(Glyphs)0 68 y(pix)o(els)j(\(which)h (bits)f(of)h(the)g(pix)o(el)f(should)g(be)h(changed)g(and)h(what)e (their)h(ne)n(w)g(v)n(alue\(s\))g(should)f(be\);)j(and)e(b\))0 188 y(which)d(pix)o(els)g(to)g(modify)-6 b(.)36 b(P)o(art)27 b(b\))g(consists)e(of)i(things)f(lik)o(e)g(\223\002ll)h(the)g(entire)g (area,)-7 b(\224)29 b(or)e(\223modify)f(only)g(those)0 309 y(pix)o(els)f(in)h(the)h(area)g(that)f(are)h(gi)n(v)o(en)e(by)i(a)g (particular)f(stipple)f(pattern,)-7 b(\224)27 b(or)g(\223dra)o(w)f(a)h (dashed-line)f(around)g(the)0 429 y(area')-5 b(s)25 b(outline.)-7 b(\224)30 b(In)25 b(the)g(case)g(of)g(te)o(xt,)f(\223which)h(pix)o(els) e(to)i(modify\224)f(is)g(determined)h(by)f(the)h(font)f(for)h(the)g(te) o(xt,)0 549 y(which)j(is)g(not)f(part)i(of)f(the)g(display)f(style,)h (so)g(the)g(display)g(style)f(information)g(for)h(this)g(is)g(ignored.) 40 b(See)29 b(the)0 670 y(manual)24 b(page)h Fa(dstyle)g(\(5\))g Fc(for)g(details)f(on)h(the)g(format)f(of)h(display)f(styles)f (\002les.)146 790 y(Display)g(styles)f(are)j(designed)e(to)g(tak)o(e)g (into)g(account)g(both)g(the)h(characteristics)f(of)h(certain)f (technologies)0 911 y(and)g(the)g(characteristics)h(of)f(certain)h (displays.)29 b(F)o(or)23 b(e)o(xample,)f(a)i(bipolar)f(process)g(may)g (require)h(information)0 1031 y(to)29 b(be)g(displayed)g(v)o(ery)g(dif) n(ferently)f(than)h(a)h(MOS)f(process,)h(and)g(a)f(black-and-white)g (display)f(will)h(be)g(used)0 1151 y(much)g(dif)n(ferently)f(than)h(a)g (color)g(display)-6 b(.)42 b(Thus)29 b(there)g(can)h(be)f(man)o(y)f (dif)n(ferent)h(display)f(styles)g(\002les,)i(each)0 1272 y(corresponding)i(to)g(a)h(particular)f(class)g(of)h(technologies) e(and)i(a)f(class)h(of)f(displays.)53 b(The)32 b(names)g(of)h(styles)0 1392 y(\002les)k(re\003ect)h(these)e(classes:)54 b(each)38 b(display)d(styles)h(\002le)h(has)g(a)g(name)g(of)g(the)f(form)h Fd(x)p Fa(.)p Fd(y)p Fa(.dstyle5)p Fc(,)j(where)d Fd(x)0 1513 y Fc(is)c(the)g(technology)e(class)i(\(gi)n(v)o(en)f(by)h(the)g Fa(styletype)g Fc(line)g(in)g(the)g Fa(styles)f Fc(section)h(of)g(the)g (technology)f(\002le\),)0 1633 y(and)e Fd(y)g Fc(is)g(the)f(class)h(of) g(display)-6 b(.)45 b(Each)30 b(display)f(dri)n(v)o(er)g(kno)n(ws)f (its)i(display)f(class;)j(the)d(dri)n(v)o(er)g(initialization)0 1753 y(routine)37 b(sets)h(an)g(internal)f(Magic)h(v)n(ariable)g(with)f (the)h(display)e(class)i(to)g(use.)70 b(Right)37 b(no)n(w)h(we)g(ha)n (v)o(e)g(tw)o(o)0 1874 y(display)d(styles)g(\002les:)54 b Fa(mos.7bit.dstyle5)35 b Fc(and)h Fa(mos.bw)-7 b(.dstyle5)p Fc(.)65 b(Both)36 b(\002les)g(contain)g(enough)f(dif)n(ferent)0 1994 y(styles)d(to)h(handle)g(a)h(v)n(ariety)e(of)h(MOS)h(processes,)h (including)c(both)i(nMOS)g(and)g(CMOS)h(\(hence)f(the)g Fa(mos)0 2114 y Fc(\002eld\).)46 b Fa(Mos.7bit.dstyle5)29 b Fc(is)g(designed)g(for)h(color)g(displays)e(with)h(at)h(least)f(se)n (v)o(en)g(bits)g(of)h(color)f(per)h(pix)o(el,)0 2235 y(while)24 b Fa(mos.bw)-7 b(.dstyle5)24 b Fc(is)g(for)h (black-and-white)f(displays)g(\(stipple)f(patterns)h(are)i(used)e (instead)g(of)g(colors\).)0 2571 y Fe(3)143 b(Color)35 b(Maps)0 2794 y Fc(The)23 b(display)f(styles)h(\002le)g(tells)g(ho)n(w) f(to)h(modify)f(pix)o(els,)g(b)n(ut)h(this)f(doesn')n(t)h(completely)f (specify)h(the)g(color)h(that)0 2915 y(will)e(be)h(displayed)e(on)i (the)f(screen)i(\(unless)e(the)g(screen)i(is)e(black-and-white\).)30 b(F)o(or)22 b(color)h(displays,)f(the)g(pix)o(el)0 3035 y(v)n(alues)j(are)h(used)f(to)g(inde)o(x)f(into)h(a)g Fd(color)g(map)p Fc(,)g(which)g(contains)g(the)g(red,)h(green,)g(and)f (blue)g(intensity)f(v)n(alues)0 3155 y(to)33 b(use)g(for)h(each)g(pix)o (el)e(v)n(alue.)55 b(The)34 b(v)n(alues)e(for)i(color)f(maps)g(are)h (stored)f(in)g(color)n(-map)f(\002les)i(and)f(can)h(be)0 3276 y(edited)d(using)f(the)h(color)n(-map-editing)e(windo)n(w)h(in)h (Magic.)49 b(See)32 b Fa(cmap)g(\(5\))g Fc(for)f(details)f(on)h(the)g (format)g(of)0 3396 y(color)n(-map)24 b(\002les.)146 3516 y(Each)i(display)f(styles)g(\002le)h(uses)f(a)h(separate)g(color)g (map.)33 b(Unfortunately)-6 b(,)24 b(some)i(monitors)e(ha)n(v)o(e)h (slightly)0 3637 y(dif)n(ferent)i(phosphors)g(than)h(others;)g(this)f (will)g(result)g(in)h(dif)n(ferent)f(colors)h(if)g(the)f(same)h (intensity)e(v)n(alues)h(are)0 3757 y(used)33 b(for)g(them.)54 b(T)-8 b(o)32 b(compensate)h(for)g(monitor)e(dif)n(ferences,)k(Magic)d (supports)g(multiple)f(color)i(maps)f(for)0 3878 y(each)c(display)f (style,)h(depending)f(on)g(the)h(monitor)e(being)h(used.)39 b(The)28 b(monitor)e(type)i(can)g(be)g(speci\002ed)g(with)0 3998 y(the)e Fa(-m)g Fc(command)f(line)h(switch)f(to)h(Magic,)g(with)f Fa(std)h Fc(as)h(the)e(def)o(ault.)35 b(Color)n(-map)25 b(\002les)i(ha)n(v)o(e)e(names)h(of)g(the)0 4118 y(form)e Fd(x)p Fa(.)p Fd(y)p Fa(.)p Fd(z)h Fa(.cmap1)p Fc(,)g(where)g Fd(x)f Fc(and)h Fd(y)g Fc(ha)n(v)o(e)f(the)g(same)g(meaning)g(as)h(for) f(display)g(styles)f(and)i Fd(z)f Fc(is)g(the)g(monitor)0 4239 y(type.)30 b(Ov)o(er)25 b(the)g(last)f(fe)n(w)h(years)g(monitor)e (phosphors)h(appear)h(to)g(ha)n(v)o(e)f(standardized)g(quite)h(a)g (bit,)f(so)g(almost)0 4359 y(all)j(monitors)f(no)n(w)g(w)o(ork)h(well)g (with)g(the)g Fa(std)h Fc(monitor)e(type.)38 b(The)27 b(color)g(map)g Fa(mos.7bit.std.cmap1)g Fc(is)g(the)0 4480 y(standard)d(one)h(used)g(at)g(Berk)o(ele)o(y)-6 b(.)0 4815 y Fe(4)143 b(T)-11 b(ranspar)m(ent)34 b(and)h(Opaque)f(Lay)o (ers)0 5039 y Fc(One)24 b(of)f(the)h(k)o(e)o(y)f(decisions)f(in)h (de\002ning)g(a)h(set)f(of)h(display)e(styles)h(for)h(a)g(color)f (display)f(is)h(ho)n(w)g(to)g(use)h(the)f(bits)0 5159 y(of)j(a)g(pix)o(el)f(\(this)g(section)h(doesn')n(t)f(apply)h(to)f (black-and-white)h(displays\).)33 b(One)26 b(option)e(is)i(to)f(use)h (a)h(separate)0 5280 y(bit)21 b(of)h(each)g(pix)o(el)e(\(called)i(a)g Fd(bit)f(plane)p Fc(\))g(for)h(each)g(mask)f(layer)-5 b(.)30 b(The)21 b(adv)n(antage)h(of)f(this)g(is)g(that)g(each)h (possible)0 5400 y(combination)i(of)i(layer)h(o)o(v)o(erlaps)d(results) h(in)h(a)g(dif)n(ferent)g(pix)o(el)f(v)n(alue,)g(and)h(hence)h(a)f(dif) n(ferent)g(color)f(\(if)i(you)1875 5649 y(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Fc(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#3:)30 b(Display)24 b(Styles,)h(Colormaps,)f(and)g(Glyphs) 232 b(September)25 b(26,)g(2001)0 68 y(wish\).)k(Thus,)22 b(for)g(e)o(xample,)g(if)g(metal)f(and)h(poly)f(are)i(represented)f (with)f(dif)n(ferent)h(bit)f(planes,)h(poly-without-)0 188 y(metal,)k(metal-without-poly)-6 b(,)24 b(poly-and-metal,)i(and)h (neither)n(-poly-nor)n(-metal)e(will)g(each)j(cause)f(a)f(dif)n(ferent) 0 309 y(v)n(alue)c(to)h(be)g(stored)f(in)h(the)f(pix)o(el.)29 b(A)23 b(dif)n(ferent)f(color)h(can)g(be)g(used)g(to)f(display)g(each)i (of)f(these)f(combinations.)0 429 y(T)-8 b(ypically)i(,)32 b(the)g(colors)g(are)g(chosen)g(to)g(present)g(an)g(illusion)e(of)i (transparenc)o(y:)45 b(the)31 b(poly-and-metal)g(color)0 549 y(is)c(chosen)g(to)g(mak)o(e)h(it)f(appear)h(as)f(if)h(metal)e (were)j(a)e(transparent)h(colored)f(foil)g(placed)g(on)h(top)e(of)i (poly)-6 b(.)37 b(Y)-11 b(ou)0 670 y(can)24 b(see)h(this)e(ef)n(fect)h (if)g(you)f(paint)g(polysilicon,)f(metal1,)i(and)g(metal2)f(on)g(top)h (of)g(each)g(other)g(in)g(our)f(standard)0 790 y(technologies.)146 918 y(The)30 b(problem)g(with)f(transparent)h(layers)g(is)f(that)h(the) o(y)f(require)h(man)o(y)f(bits)g(per)i(pix)o(el.)45 b(Most)29 b(color)h(dis-)0 1038 y(plays)h(don')n(t)g(ha)n(v)o(e)g(enough)g (planes)g(to)h(use)f(a)h(dif)n(ferent)f(one)h(for)f(each)h(mask)f (layer)-5 b(.)51 b(Another)31 b(option)f(is)h(to)0 1158 y(use)c(a)g(group)f(of)h(planes)g(together)-5 b(.)35 b(F)o(or)27 b(e)o(xample,)g(three)g(bits)e(of)i(a)h(pix)o(el)d(can)i (be)g(used)g(to)f(store)h(se)n(v)o(en)f(mask)0 1279 y(layers)35 b(plus)f(background,)j(with)d(each)i(mask)e(layer)i(corresponding)e(to) g(one)h(of)g(the)g(combinations)e(of)i(the)0 1399 y(three)25 b(bits.)k(The)c(problem)f(with)g(this)f(scheme)i(is)f(that)g(there)h (is)f(no)g(w)o(ay)h(to)f(represent)h(o)o(v)o(erlaps:)k(where)c(there)0 1520 y(is)e(an)h(o)o(v)o(erlap,)f(one)h(of)f(the)h(layers)g(must)e(be)i (displayed)f(at)h(the)f(e)o(xpense)g(of)h(the)g(others.)30 b(W)-8 b(e)24 b(call)f(this)g(scheme)0 1640 y(an)f Fd(opaque)g Fc(one)g(since)g(when)g(it)f(is)h(used)g(it)f(appears)i(as)f(if)g(each) h(layer)f(is)f(an)i(opaque)f(foil,)g(with)f(the)h(foils)f(lying)0 1760 y(on)h(top)g(of)h(each)g(other)g(in)f(some)g(priority)g(order)-5 b(.)30 b(This)22 b(mak)o(es)g(it)g(harder)h(to)f(see)h(what')-5 b(s)22 b(going)g(on)g(when)h(there)0 1881 y(are)j(se)n(v)o(eral)e(mask) g(layers)h(in)f(an)h(area.)146 2008 y(The)g(display)e(styles)h(\002les) g(we')-5 b(v)o(e)25 b(designed)e(for)i(Magic)f(use)g(a)h(combination)e (of)h(these)h(techniques)e(to)h(get)0 2129 y(as)33 b(much)g (transparenc)o(y)g(as)g(possible.)54 b(F)o(or)33 b(e)o(xample,)i(our)e Fa(mos.7bit.dstyle5)f Fc(\002le)i(uses)e(three)i(bits)e(of)h(the)0 2249 y(pix)o(el)c(in)h(an)g(opaque)h(scheme)f(to)g(represent)g (polysilicon,)g(dif)n(fusion,)g(and)g(v)n(arious)f(combinations)f(of)j (them)0 2369 y(such)g(as)g(transistors.)48 b(T)-8 b(w)o(o)31 b(additional)e(bits)h(are)i(used,)h(one)e(each,)i(for)e(the)g(tw)o(o)f (metal)h(layers,)h(so)f(the)o(y)f(are)0 2490 y(transparent)j(with)g (respect)g(to)g(each)h(other)g(and)f(the)g(poly-dif)n(f)f (combinations.)55 b(Thus,)34 b(although)f(only)f(one)0 2610 y(poly-dif)n(f)d(combination)f(can)j(appear)g(at)f(each)h(point,)f (it')-5 b(s)29 b(possible)g(to)h(see)g(the)g(o)o(v)o(erlaps)f(between)h (each)h(of)0 2730 y(these)e(combinations)f(and)i(each)g(combination)e (of)h(metal1)g(and)h(metal2.)44 b(Furthermore,)31 b(all)e(of)h(these)f (styles)0 2851 y(are)36 b(o)o(v)o(erridden)f(if)g(the)h(sixth)e(bit)h (of)h(the)g(pix)o(el)e(is)h(set.)63 b(In)36 b(this)f(case)h(the)f(lo)n (w)g(order)h(\002)n(v)o(e)f(bits)g(no)g(longer)0 2971 y(correspond)24 b(to)f(mask)g(layers;)h(the)o(y)f(are)i(used)e(for)h (opaque)g(layers)g(for)g(things)e(lik)o(e)i(labels)f(and)h(cell)g (bounding)0 3092 y(box)o(es,)31 b(and)g(o)o(v)o(erride)f(an)o(y)g(mask) g(information.)47 b(Thus,)32 b(for)f(e)o(xample,)g(when)g(metal1)f(is)g (displayed)g(it)g(only)0 3212 y(af)n(fects)h(one)f(bit)g(plane,)h(b)n (ut)f(when)h(labels)f(are)h(displayed,)f(the)h(entire)f(lo)n(w-order)g (six)g(bits)f(of)i(the)f(pix)o(el)f(are)0 3332 y(modi\002ed.)51 b(It')-5 b(s)32 b(important)e(that)i(the)g(opaque)f(layers)h(lik)o(e)g (labels)f(are)i(dra)o(wn)e(after)i(the)f(transparent)f(things)0 3453 y(that)22 b(the)o(y)f(blot)h(out;)g(this)f(is)h(guaranteed)g(by)g (gi)n(ving)f(them)h(higher)f(style)h(numbers)g(in)f(the)i(display)e (styles)g(\002les.)146 3580 y(Finally)-6 b(,)33 b(the)f(se)n(v)o(enth)e (bit)i(of)g(the)f(pix)o(el)g(is)h(used)g(for)g(highlights)e(lik)o(e)h (the)h(box)f(and)h(the)g(selection.)52 b(All)0 3701 y(64)27 b(entries)g(in)g(the)g(color)h(map)f(corresponding)f(to)h(pix)o(el)f(v) n(alues)h(with)f(this)h(bit)f(set)i(contain)e(the)i(same)f(v)n(alue,)0 3821 y(namely)38 b(pure)h(white.)73 b(This)38 b(mak)o(es)g(the)h (highlights)d(appear)k(opaque)e(with)h(respect)g(to)f(e)n(v)o(erything) f(else.)0 3941 y(Ho)n(we)n(v)o(er)l(,)31 b(since)g(the)o(y)g(ha)n(v)o (e)f(their)h(o)n(wn)g(bit)f(plane)h(which)g(is)f(completely)g (independent)h(of)g(an)o(ything)e(else,)0 4062 y(the)o(y)f(can)h(be)f (dra)o(wn)h(and)f(erased)h(without)e(ha)n(ving)h(to)g(redra)o(w)h(an)o (y)f(of)h(the)f(mask)g(information)f(underneath.)0 4182 y(This)e(is)h(why)f(the)h(box)f(can)i(be)f(mo)o(v)o(ed)e(relati)n(v)o (ely)h(quickly)-6 b(.)33 b(On)26 b(the)f(other)h(hand,)g(if)g(Magic)g (erases)g(a)h(label)f(it)0 4302 y(must)e(redra)o(w)h(all)f(the)h(mask)f (information)f(in)h(the)h(area)h(because)f(the)f(label)h(shared)g(pix)o (el)e(bits)h(with)g(the)h(mask)0 4423 y(information.)146 4550 y(Thus,)40 b(the)e(scheme)f(we')-5 b(v)o(e)38 b(been)f(using)g (for)h(Magic)f(is)g(a)h(hierarchical)g(combination)e(of)h(transparent)0 4671 y(and)29 b(opaque)g(layers.)42 b(This)29 b(scheme)f(is)h (de\002ned)g(almost)f(entirely)g(by)h(the)f(styles)g(\002le,)i(so)f (you)f(can)i(try)e(other)0 4791 y(schemes)k(if)f(you)h(wish.)51 b(Ho)n(we)n(v)o(er)l(,)32 b(you')-5 b(re)32 b(lik)o(ely)f(to)h(ha)n(v)o (e)f(problems)g(if)h(you)f(try)h(an)o(ything)e(too)h(radically)0 4911 y(dif)n(ferent;)21 b(we)g(ha)n(v)o(en')n(t)f(tried)g(an)o(y)g (schemes)g(b)n(ut)g(the)h(one)f(currently)h(being)e(used)i(so)f(there)h (are)g(probably)f(some)0 5032 y(code)25 b(dependencies)g(on)f(it.)146 5159 y(F)o(or)h(more)g(information)f(on)g(transparent)h(and)g(opaque)g (layers,)f(see)i(the)e(paper)i(\223The)f(User)g(Interf)o(ace)h(and)0 5280 y(Implementation)k(of)i(an)g(IC)h(Layout)e(Editor)l(,)-7 b(\224)33 b(which)f(appeared)g(in)g Fd(IEEE)g(T)-5 b(r)o(ansactions)29 b(on)j(CAD)g Fc(in)g(July)0 5400 y(1984.)1875 5649 y(\2263\226)p eop %%Page: 4 4 4 3 bop 0 -180 a Fc(September)25 b(26,)f(2001)233 b(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#3:)30 b(Display)24 b(Styles,)g(Colormaps,)g(and)h(Glyphs)0 99 y Fe(5)143 b(Glyphs)0 322 y Fc(Glyphs)30 b(are)i(small)e(rectangular)h(bit)g (patterns)f(that)h(are)h(used)e(in)h(tw)o(o)g(places)g(in)f(Magic.)50 b(The)31 b(primary)f(use)0 443 y(for)25 b(glyphs)f(is)h(for)h (programmable)e(cursors,)h(such)g(as)g(the)g(shapes)g(that)g(sho)n(w)f (you)h(which)f(corner)i(of)g(the)f(box)0 563 y(you')-5 b(re)25 b(mo)o(ving)d(and)j(the)g(v)n(arious)e(tools)h(described)g(in)g (T)l(utorial)g(#3.)30 b(Each)25 b(programmable)f(cursor)g(is)h(stored)0 683 y(as)h(a)h(glyph)e(describing)h(the)g(pattern)g(to)g(be)g (displayed)g(in)f(the)i(cursor)-5 b(.)34 b(The)27 b(second)f(use)g(of)g (glyphs)f(is)h(by)g(the)0 804 y(windo)n(w)d(package:)31 b(the)24 b(little)f(arro)n(w)h(icons)g(appearing)g(at)h(the)f(ends)g (of)g(scroll)g(bars)g(are)i(stored)d(as)i(glyphs,)e(as)0 924 y(is)k(the)g(zoom)g(box)f(in)h(the)g(lo)n(wer)n(-left)g(corner)h (of)f(the)g(windo)n(w)-6 b(.)36 b(W)-8 b(e)28 b(may)f(e)n(v)o(entually) e(use)i(glyphs)f(in)h(a)h(menu)0 1045 y(interf)o(ace)d(\(b)n(ut)g(don') n(t)f(hold)g(your)h(breath\).)146 1165 y(Glyphs)32 b(are)h(stored)f(in) g(ASCII)h(glyph)f(\002les,)i(each)f(of)g(which)f(can)h(hold)e(one)i(or) f(more)g(glyph)g(patterns.)0 1285 y(Each)j(glyph)g(is)g(represented)g (as)g(a)h(pattern)f(of)g(characters)h(representing)f(the)g(pix)o(els)f (in)h(the)g(glyph.)61 b(Each)0 1406 y(character)28 b(selects)f(a)g (display)f(style)h(from)f(the)h(current)h(display)d(styles)i(\002le;)h (the)f(display)f(style)g(indicates)g(the)0 1526 y(color)e(to)f(use)g (for)h(that)g(pix)o(el.)29 b(See)c(the)e(manual)g(page)h Fa(glyphs)g(\(5\))g Fc(for)g(details)f(on)g(the)h(syntax)f(of)h(glyphs) e(\002les.)146 1647 y(The)27 b(windo)n(w)f(glyphs)g(are)h(stored)g(in)f (\002les)i(of)f(the)f(form)h Fa(windo)o(ws)p Fd(XX)p Fa(.glyphs)p Fc(.)37 b(The)27 b Fd(XX)g Fc(indicates)f(ho)n(w)0 1767 y(wide)38 b(the)g(glyphs)f(are,)42 b(and)c(is)g(set)g(by)g(the)g (graphics)g(dri)n(v)o(er)f(for)h(a)h(particular)f(display)-6 b(.)69 b(W)-8 b(e)39 b(started)f(out)0 1887 y(with)30 b(a)h Fa(windo)o(ws7.glyphs)g Fc(and)f(a)i Fa(windo)o(ws11.glyphs)p Fc(.)48 b(Since)31 b(then,)h(display)e(resolution)f(has)i(increased)0 2008 y(greatly)d(so)h(we)g(ha)n(v)o(e)f(also)h(created)g(a)g Fa(windo)o(ws14.glyphs)f Fc(and)h(a)g Fa(windo)o(ws22.glyphs)p Fc(.)42 b(The)28 b(positions)f(of)0 2128 y(the)e(v)n(arious)e(glyphs)h (in)g(these)h(\002les)g(is)f(important,)g(and)g(is)h(de\002ned)g(in)f (the)h Fa(windo)o(w)g Fc(module)f(of)h(Magic.)146 2248 y(Programmable)g(cursors)g(are)h(stored)f(in)f(\002les)i(named)e Fd(x)p Fa(.glyphs)p Fc(,)i(where)f Fd(x)h Fc(is)e(determined)h(by)g (the)f(de)n(vice)0 2369 y(dri)n(v)o(er)f(for)i(the)g(display)-6 b(.)29 b(Displays)23 b(capable)i(of)f(supporting)f(full-color)h (cursors)g(use)g Fa(color)-10 b(.glyphs)p Fc(;)24 b(displays)0 2489 y(that)33 b(can)g(only)g(support)f(monochrome)g(cursors)h(used)g Fa(bw)-7 b(.glyphs)p Fc(.)56 b(The)33 b(order)h(of)f(the)g(v)n(arious)f (glyphs)g(in)0 2610 y(these)25 b(\002les)g(is)f(important.)29 b(It)c(is)f(de\002ned)i(by)e(the)h(\002les)g Fa(styles.h)f Fc(in)h(the)f Fa(misc)h Fc(module)f(of)h(Magic.)1875 5649 y(\2264\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tuttcl2.ps0000644000175000001440000002507510751423606015646 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software %%Title: tuttcl2.dvi %%Pages: 1 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman %%EndComments %DVIPSWebPage: (www.radicaleye.com) %DVIPSCommandLine: dvips -t letter tuttcl2.dvi -o ../psfiles/tuttcl2.ps %DVIPSParameters: dpi=600, compressed %DVIPSSource: TeX output 2006.04.12:1204 %%BeginProcSet: texc.pro %! /TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin /FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array /BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get }B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr 1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx 0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B /chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ /cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 {2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ 1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put }if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X 1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N /p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ /Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) (LaserWriter 16/600)]{A length product length le{A length product exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end %%EndProcSet %%BeginProcSet: 8r.enc % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndProcSet %%BeginProcSet: texps.pro %! TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type/integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics/Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{ dup sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[exch{dup CharStrings exch known not{pop/.notdef/Encoding true def} if}forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def} def end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tuttcl2.dvi) @start /Fa 105[50 28[50 2[50 50 28 39 33 1[50 50 50 78 28 50 1[28 50 50 1[44 50 44 50 44 11[72 61 55 2[55 2[89 61 1[39 1[72 3[72 2[72 9[50 3[50 50 50 50 1[25 33 25 44[{TeXBase1Encoding ReEncodeFont}39 99.6264 /Times-Roman rf /Fb 134[44 1[66 2[28 39 39 2[50 1[72 3[28 50 3[50 2[50 12[55 1[61 12[61 22[25 46[{TeXBase1Encoding ReEncodeFont}15 99.6264 /Times-Italic rf /Fc 138[80 48 1[64 1[80 72 2[40 2[40 80 72 1[64 1[64 1[72 9[143 1[104 96 6[135 3[56 1[112 12[48 7[72 72 13[72 35[{TeXBase1Encoding ReEncodeFont}22 143.462 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%BeginPaperSize: Letter letter %%EndPaperSize %%EndSetup %%Page: 1 1 1 0 bop 665 101 a Fc(Magic)35 b(Tcl)h(T)-13 b(utorial)33 b(#2:)44 b(The)35 b(Wrapper)g(GUI)1546 521 y Fb(R.)25 b(T)-5 b(imothy)24 b(Edwar)l(ds)1583 941 y Fa(Space)i(Department)1434 1062 y(Johns)e(Hopkins)g(Uni)n(v)o(ersity)1391 1182 y(Applied)g (Physics)g(Laboratory)1578 1303 y(Laurel,)h(MD)f(20723)819 1573 y(This)g(tutorial)g(corresponds)g(to)h(Tcl-based)f(Magic)h(v)o (ersion)e(7.2)0 2320 y Fc(1)143 b(The)35 b(Wrapper)g(GUI)1875 5649 y Fa(\2261\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tut9.ps0000644000175000001440000013251010751423606015143 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: tut9.dvi %%Pages: 6 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips tut9.dvi -o tut9.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Bold % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet %%BeginProcSet: special.pro TeXDict begin /SDict 200 dict N SDict begin /@SpecialDefaults{/hs 612 N /vs 792 N /ho 0 N /vo 0 N /hsc 1 N /vsc 1 N /ang 0 N /CLIP 0 N /rwiSeen false N /rhiSeen false N /letter{}N /note{}N /a4{}N /legal{}N}B /@scaleunit 100 N /@hscale{@scaleunit div /hsc X}B /@vscale{@scaleunit div /vsc X}B /@hsize{/hs X /CLIP 1 N}B /@vsize{/vs X /CLIP 1 N}B /@clip{ /CLIP 2 N}B /@hoffset{/ho X}B /@voffset{/vo X}B /@angle{/ang X}B /@rwi{ 10 div /rwi X /rwiSeen true N}B /@rhi{10 div /rhi X /rhiSeen true N}B /@llx{/llx X}B /@lly{/lly X}B /@urx{/urx X}B /@ury{/ury X}B /magscale true def end /@MacSetUp{userdict /md known{userdict /md get type /dicttype eq{userdict begin md length 10 add md maxlength ge{/md md dup length 20 add dict copy def}if end md begin /letter{}N /note{}N /legal{} N /od{txpose 1 0 mtx defaultmatrix dtransform S atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{itransform lineto} }{6 -2 roll transform 6 -2 roll transform 6 -2 roll transform{ itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll curveto}}{{ closepath}}pathforall newpath counttomark array astore /gc xdf pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack}if}N /txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 -1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop 90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr 2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 -1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S TR}if}N /cp {pop pop showpage pm restore}N end}if}if}N /normalscale{Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale}if 0 setgray} N /psfts{S 65781.76 div N}N /startTexFig{/psf$SavedState save N userdict maxlength dict begin /magscale true def normalscale currentpoint TR /psf$ury psfts /psf$urx psfts /psf$lly psfts /psf$llx psfts /psf$y psfts /psf$x psfts currentpoint /psf$cy X /psf$cx X /psf$sx psf$x psf$urx psf$llx sub div N /psf$sy psf$y psf$ury psf$lly sub div N psf$sx psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub TR /showpage{}N /erasepage{}N /copypage{}N /p 3 def @MacSetUp}N /doclip{ psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath moveto}N /endTexFig{end psf$SavedState restore}N /@beginspecial{SDict begin /SpecialSave save N gsave normalscale currentpoint TR @SpecialDefaults count /ocount X /dcount countdictstack N}N /@setspecial {CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR }{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury lineto closepath clip}if /showpage{}N /erasepage{}N /copypage{}N newpath }N /@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{ end}repeat grestore SpecialSave restore end}N /@defspecial{SDict begin} N /@fedspecial{end}B /li{lineto}B /rl{rlineto}B /rc{rcurveto}B /np{ /SaveX currentpoint /SaveY X N 1 setlinecap newpath}N /st{stroke SaveX SaveY moveto}N /fil{fill SaveX SaveY moveto}N /ellipse{/endangle X /startangle X /yrad X /xrad X /savematrix matrix currentmatrix N TR xrad yrad scale 0 0 1 startangle endangle arc savematrix setmatrix}N end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tut9.dvi) @start /Fa 134[50 1[72 50 55 33 39 44 1[55 50 55 83 28 2[28 1[50 33 44 55 44 55 50 12[66 3[61 12[72 5[57 2[33 50 4[50 2[50 50 1[25 33 3[33 33 36[55 55 2[{ TeXBase1Encoding ReEncodeFont }35 100.000003 /Times-Bold rf /Fb 138[66 40 47 53 2[60 66 100 33 2[33 66 2[53 66 53 1[60 12[80 6[113 9[86 8[40 55[66 2[{ TeXBase1Encoding ReEncodeFont } 19 119.999948 /Times-Bold rf /Fc 105[50 1[44 44 24[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 7[72 1[94 1[72 61 55 66 1[55 72 1[89 61 2[33 72 72 55 61 72 66 66 72 5[28 28 50 1[50 50 50 50 50 50 50 50 28 25 33 25 2[33 33 33 2[50 50 31[55 55 2[{ TeXBase1Encoding ReEncodeFont }70 100.000003 /Times-Roman rf /Fd 134[44 44 66 1[50 28 39 39 1[50 50 50 72 28 3[50 2[44 50 1[50 50 11[72 1[50 3[72 66 3[44 27[25 1[25 2[33 33 37[50 2[{ TeXBase1Encoding ReEncodeFont }27 100.000003 /Times-Italic rf /Fe 134[72 1[104 72 80 48 56 64 2[72 80 120 40 2[40 80 72 48 64 80 64 80 72 9[143 2[96 80 104 1[88 112 104 135 3[56 1[112 88 2[104 96 7[48 72 3[72 72 72 72 72 3[48 9[72 35[{ TeXBase1Encoding ReEncodeFont }42 143.999997 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 158 101 a Fe(Magic)36 b(T)-13 b(utorial)34 b(#9:)43 b(F)l(ormat)35 b(Con)-6 b(v)o(ersion)33 b(f)l(or)i(CIF)g(and)g(Calma) 1618 521 y Fd(J)n(ohn)24 b(Ousterhout)1401 941 y Fc(Computer)g(Science) i(Di)n(vision)1020 1062 y(Electrical)f(Engineering)f(and)h(Computer)f (Sciences)1473 1182 y(Uni)n(v)o(ersity)f(of)i(California)1544 1303 y(Berk)o(ele)o(y)-6 b(,)24 b(CA)h(94720)1448 1573 y Fd(\(Updated)f(by)h(other)o(s,)f(too.\))1053 1843 y Fc(This)g(tutorial)g(corresponds)g(to)g(Magic)h(v)o(ersion)e(7.)0 2336 y Fb(T)-11 b(utorials)30 b(to)f(r)n(ead)h(\002rst:)300 2513 y Fc(Magic)24 b(T)l(utorial)g(#1:)30 b(Getting)24 b(Started)300 2633 y(Magic)g(T)l(utorial)g(#2:)30 b(Basic)25 b(P)o(ainting)f(and)h(Selection)300 2754 y(Magic)f(T)l(utorial)g(#4:)30 b(Cell)25 b(Hierarchies)0 2930 y Fb(Commands)k(intr)n(oduced)j(in)f (this)f(tutorial:)300 3107 y Fc(:calma,)24 b(:cif)0 3284 y Fb(Macr)n(os)29 b(intr)n(oduced)i(in)g(this)f(tutorial:)300 3477 y Fd(\(None\))0 4334 y Fe(1)143 b(Basics)0 4557 y Fc(CIF)33 b(\(Caltech)f(Intermediate)f(F)o(orm\))g(and)g(Calma)h (Stream)f(F)o(ormat)g(are)h(standard)f(layout)g(description)f(lan-)0 4678 y(guages)g(used)g(to)g(transfer)h(mask-le)n(v)o(el)e(layouts)g (between)i(or)n(ganizations)e(and)h(design)g(tools.)46 b(This)30 b(tutorial)0 4798 y(describes)22 b(ho)n(w)f(Magic)h(can)h(be) f(used)g(to)g(read)h(and)f(write)g(\002les)g(in)g(CIF)i(and)e(Stream)g (formats.)30 b(The)22 b(v)o(ersion)f(of)0 4918 y(CIF)26 b(that)e(Magic)h(supports)f(is)g(CIF)i(2.0;)f(it)f(is)g(the)h(most)f (popular)g(layout)g(language)h(in)g(the)f(uni)n(v)o(ersity)f(design)0 5039 y(community)-6 b(.)40 b(The)29 b(Calma)g(format)g(that)f(Magic)h (supports)e(is)i(GDS)g(II)g(Stream)h(format,)f(v)o(ersion)f(3.0,)h (corre-)0 5159 y(sponding)21 b(to)h(GDS)h(II)g(Release)g(5.1.)30 b(This)22 b(is)g(probably)g(the)g(most)f(popular)h(layout)g (description)g(language)g(for)0 5280 y(the)j(industrial)e(design)h (community)-6 b(.)146 5400 y(T)e(o)25 b(write)g(out)f(a)h(CIF)h (\002le,)f(place)g(the)g(cursor)g(o)o(v)o(er)f(a)h(layout)f(windo)n(w)f (and)i(type)f(the)h(command)1875 5649 y(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Fc(September)25 b(26,)f(2001)781 b(Magic)24 b(T)l(utorial)g(#9:)30 b(F)o(ormat)24 b(Con)l(v)o(ersion)g(for)h(CIF)h (and)f(Calma)900 84 y Fa(:cif)146 289 y Fc(This)31 b(will)g(generate)i (a)f(CIF)h(\002le)f(called)g Fd(name)p Fa(.cif)p Fc(,)i(where)e Fd(name)g Fc(is)f(the)h(name)g(of)g(the)f(root)h(cell)g(in)f(the)0 409 y(windo)n(w)-6 b(.)32 b(The)26 b(CIF)h(\002le)g(will)e(contain)g(a) i(description)d(of)i(the)g(entire)g(cell)g(hierarchy)g(in)f(that)h (windo)n(w)-6 b(.)32 b(If)27 b(you)0 530 y(wish)d(to)h(use)f(a)h(name)g (dif)n(ferent)f(from)h(the)g(root)f(cell,)h(type)f(the)h(command)900 735 y Fa(:cif)g(write)g Fd(\002le)146 939 y Fc(This)j(will)g(store)h (the)g(CIF)h(in)e Fd(\002le)p Fa(.cif)p Fc(.)43 b(Start)29 b(Magic)g(up)f(to)h(edit)f Fa(tut9a)h Fc(and)g(generate)h(CIF)g(for)f (that)f(cell.)0 1060 y(The)23 b(CIF)h(\002le)f(will)f(be)h(in)f(ASCII)i (format,)f(so)f(you)h(can)g(use)f(Unix)h(commands)e(lik)o(e)h Fa(mor)n(e)i Fc(and)e Fa(vi)h Fc(to)f(see)h(what)0 1180 y(it)h(contains.)146 1301 y(T)-8 b(o)25 b(read)g(a)g(CIF)h(\002le)g (into)e(Magic,)g(place)h(the)g(cursor)g(o)o(v)o(er)e(a)j(layout)e (windo)n(w)f(and)i(type)f(the)h(command)900 1505 y Fa(:cif)g(r)n(ead)h Fd(\002le)146 1710 y Fc(This)38 b(will)f(read)i(the)f(\002le)g Fd(\002le)p Fa(.cif)h Fc(\(which)e(must)h(be)g(in)g(CIF)h(format\),)i (generate)e(Magic)f(cells)g(for)g(the)0 1831 y(hierarchy)d(described)g (in)g(the)g(\002le,)j(mak)o(e)d(the)g(entire)g(hierarchy)g(a)g(subcell) g(of)g(the)g(edit)g(cell,)i(and)e(run)g(the)0 1951 y(design-rule)18 b(check)o(er)i(to)f(v)o(erify)f(e)n(v)o(erything)g(read)h(from)g(the)g (\002le.)29 b(Information)18 b(in)h(the)g(top-le)n(v)o(el)e(cell)i (\(usually)0 2071 y(just)25 b(a)i(call)f(on)h(the)f(\223main\224)g (cell)g(of)h(the)f(layout\))g(will)f(be)i(placed)f(into)f(the)i(edit)f (cell.)35 b(Start)27 b(Magic)f(up)g(afresh)0 2192 y(and)35 b(read)g(in)f Fa(tut9a.cif)p Fc(,)k(which)c(you)h(created)g(abo)o(v)o (e.)60 b(It)34 b(will)g(be)h(easier)g(if)g(you)f(al)o(w)o(ays)h(read)g (CIF)h(when)0 2312 y(Magic)23 b(has)h(just)f(been)h(started)g(up:)29 b(if)24 b(some)f(of)h(the)g(cells)g(already)g(e)o(xist,)f(the)g(CIF)i (reader)g(will)e(not)g(o)o(v)o(erwrite)0 2432 y(them,)h(b)n(ut)g(will)g (instead)g(use)h(numbers)f(for)h(cell)g(names.)146 2553 y(T)-8 b(o)34 b(read)h(and)f(write)g(Stream-format)g(\002les,)i(use)e (the)g(commands)f Fa(:calma)h(r)n(ead)h Fc(and)f Fa(:calma)p Fc(,)i(respec-)0 2673 y(ti)n(v)o(ely)-6 b(.)43 b(These)30 b(commands)f(ha)n(v)o(e)g(the)h(same)g(ef)n(fect)g(as)g(the)g(CIF)h (commands,)e(e)o(xcept)h(that)f(the)o(y)g(operate)h(on)0 2794 y(\002les)24 b(with)g Fa(.strm)g Fc(e)o(xtensions.)29 b(Stream)24 b(is)g(a)h(binary)f(format,)g(so)f(you)h(can')n(t)h(e)o (xamine)e Fa(.strm)i Fc(\002les)f(with)g(a)g(te)o(xt)0 2914 y(editor)-5 b(.)146 3034 y(Stream)38 b(\002les)g(do)f(not)g (identify)g(a)g(top-le)n(v)o(el)f(cell,)41 b(so)c(you)g(w)o(on')n(t)g (see)h(an)o(ything)e(on)h(the)g(screen)h(after)0 3155 y(you')-5 b(v)o(e)24 b(used)g(the)g Fa(:calma)g(r)n(ead)i Fc(command.)j(Y)-11 b(ou')o(ll)24 b(ha)n(v)o(e)g(to)g(use)h(the)f Fa(:load)g Fc(command)g(to)g(look)g(at)g(the)g(cells)0 3275 y(you)d(read.)30 b(Ho)n(we)n(v)o(er)l(,)21 b(if)h(Magic)f(w)o(as)h (used)f(to)g(write)h(the)f(Calma)h(\002le)g(being)f(read,)i(the)e (library)h(name)f(reported)0 3396 y(by)k(the)f Fa(:calma)h(r)n(ead)h Fc(command)d(is)i(the)f(same)h(as)g(the)g(name)f(of)h(the)g(root)f (cell)h(for)g(that)f(library)-6 b(.)146 3516 y(Also,)43 b(Calma)d(format)f(places)h(some)f(limitations)e(on)i(the)h(names)f(of) h(cells:)60 b(the)o(y)39 b(can)h(only)f(contain)0 3636 y(alphanumeric)24 b(characters,)h(\223$\224,)g(and)g(\223)p 1427 3636 30 4 v 36 w(\224,)g(and)f(can)h(be)g(at)g(most)e(32)h (characters)i(long.)k(If)25 b(the)f(name)h(of)f(a)h(cell)0 3757 y(does)c(not)g(meet)g(these)h(limitations,)d Fa(:calma)j(write)g Fc(con)l(v)o(erts)e(it)h(to)g(a)h(unique)f(name)g(of)h(the)f(form)p 3410 3757 150 5 v 172 w Fd(n)p Fc(,)h(where)0 3877 y Fd(n)29 b Fc(is)f(a)h(small)f(inte)o(ger)-5 b(.)41 b(T)-8 b(o)29 b(a)n(v)n(oid)f(an)o(y)g(possible)f(con\003icts,)j(you)e(should) g(a)n(v)n(oid)g(using)g(names)g(lik)o(e)g(these)h(for)0 3997 y(your)c(o)n(wn)e(cells.)146 4118 y(Y)-11 b(ou)27 b(shouldn')n(t)e(need)i(to)g(kno)n(w)e(much)i(more)f(than)h(what')-5 b(s)26 b(abo)o(v)o(e)g(in)g(order)h(to)g(read)g(and)g(write)f(CIF)i (and)0 4238 y(Stream.)i(The)21 b(sections)f(belo)n(w)g(describe)i(the)e (dif)n(ferent)h(styles)f(of)i(CIF/Calma)g(that)e(Magic)h(can)g (generate)h(and)0 4359 y(the)31 b(limitations)e(of)j(the)f(CIF/Calma)h (f)o(acilities)f(\(you)g(may)g(ha)n(v)o(e)h(noticed)e(that)h(when)h (you)f(wrote)g(and)h(read)0 4479 y(CIF)24 b(abo)o(v)o(e)e(you)h(didn')n (t)f(quite)h(get)g(back)g(what)g(you)f(started)h(with;)g(Section)g(3)g (describes)f(the)h(dif)n(ferences)h(that)0 4599 y(can)k(occur\).)40 b(Although)26 b(the)h(discussion)f(mentions)g(only)h(CIF)-8 b(,)28 b(the)g(same)f(features)h(and)g(problems)e(apply)h(to)0 4720 y(Calma.)0 5056 y Fe(2)143 b(Styles)0 5280 y Fc(Magic)28 b(usually)f(kno)n(ws)g(se)n(v)o(eral)g(dif)n(ferent)h(w)o(ays)g(to)g (generate)g(CIF/Calma)i(from)e(a)g(gi)n(v)o(en)f(layout.)40 b(Each)28 b(of)0 5400 y(these)h(w)o(ays)g(is)f(called)h(a)g Fd(style)p Fc(.)43 b(Dif)n(ferent)29 b(styles)f(can)h(be)g(used)g(to)f (handle)h(dif)n(ferent)f(f)o(abrication)h(f)o(acilities,)1875 5649 y(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Fc(Magic)24 b(T)l(utorial)g(#9:)30 b(F)o(ormat)24 b(Con)l(v)o(ersion)g(for)h(CIF)h(and)f(Calma)781 b(September)25 b(26,)g(2001)0 68 y(which)f(may)g(dif)n(fer)g(in)g(the)g(names)g(the)o (y)g(use)g(for)h(layers)f(or)g(in)g(the)g(e)o(xact)h(mask)e(set)i (required)f(for)h(f)o(abrication.)0 188 y(Dif)n(ferent)34 b(styles)f(can)h(be)h(also)e(used)h(to)g(write)g(out)f(CIF/Calma)i (with)f(slightly)e(dif)n(ferent)h(feature)i(sizes)f(or)0 309 y(design)24 b(rules.)31 b(CIF/Calma)26 b(styles)e(are)i(described)f (in)g(the)f(technology)g(\002le)i(that)e(Magic)h(reads)g(when)g(it)g (starts)0 429 y(up;)d(the)g(e)o(xact)g(number)g(and)g(nature)g(of)g (the)g(styles)f(is)h(determined)f(by)h(whoe)n(v)o(er)f(wrote)h(your)g (technology)f(\002le.)0 549 y(There)h(are)h(separate)f(styles)e(for)i (reading)g(and)g(writing)e(CIF/Calma;)k(at)d(an)o(y)g(gi)n(v)o(en)g (time,)g(there)h(is)f(one)h(current)0 670 y(input)i(style)g(and)h(one)f (current)h(output)f(style.)146 790 y(The)f(standard)g(SCMOS)h (technology)d(\002le)j(pro)o(vides)d(an)i(e)o(xample)f(of)h(ho)n(w)g (dif)n(ferent)f(styles)g(can)h(be)g(used.)0 911 y(Start)i(up)g(Magic)f (with)g(the)h(SCMOS)g(technology)f(\()p Fa(magic)h(-Tscmos)p Fc(\).)31 b(Then)24 b(type)h(the)g(commands)900 1082 y Fa(:cif)g(ostyle)900 1202 y(:cif)g(istyle)146 1373 y Fc(The)e(\002rst)g(command)f(will)f(print)i(out)f(a)h(list)e(of)i (all)g(the)f(styles)g(in)g(which)h(Magic)f(can)h(write)g(CIF/Calma)g (\(in)0 1493 y(this)18 b(technology\))g(and)i(the)f(second)f(command)h (prints)f(out)g(the)h(styles)g(in)f(which)h(Magic)g(can)h(read)f (CIF/Calma.)0 1614 y(Y)-11 b(ou)31 b(use)g(the)h Fa(:cif)f Fc(command)g(to)g(change)g(the)g(current)h(styles,)g(b)n(ut)f(the)g (styles)f(are)i(used)f(for)h(both)f(CIF)h(and)0 1734 y(Calma)h(format)f(con)l(v)o(ersion.)53 b(The)33 b(SCMOS)g(technology)e (\002le)i(pro)o(vides)f(se)n(v)o(eral)g(output)f(styles.)53 b(The)33 b(ini-)0 1854 y(tial)d(\(def)o(ault\))h(style)e(for)i(writing) f(CIF)h(is)f Fa(lambda=1.0\(gen\))p Fc(.)49 b(This)29 b(style)h(generates)h(mask)f(layers)g(for)h(the)0 1975 y(MOSIS)h(scalable)g(CMOS)h(process,)g(where)f(each)h(Magic)f(unit)f (corresponds)g(to)g(1)h(micron)f(and)h(both)f(well)0 2095 y(polarities)21 b(are)h(generated.)30 b(See)23 b(the)e(technology) g(manual)g(for)h(more)g(information)e(on)i(the)f(v)n(arious)g(styles)g (that)0 2216 y(are)26 b(a)n(v)n(ailable.)k(Y)-11 b(ou)24 b(can)h(change)g(the)g(output)e(style)i(with)f(the)g(command)900 2386 y Fa(:cif)h(ostyle)g Fd(ne)o(wStyle)146 2557 y Fc(where)30 b Fd(ne)o(wStyle)f Fc(is)g(the)g(ne)n(w)f(style)h(you')-5 b(d)28 b(lik)o(e)h(to)g(use)g(for)g(output.)43 b(After)29 b(this)f(command,)h(an)o(y)g(future)0 2678 y(CIF)g(or)g(Calma)f (\002les)h(will)e(be)i(generated)f(with)g(the)g(ne)n(w)g(style.)40 b(The)29 b Fa(:cif)f(istyle)g Fc(command)f(can)i(be)f(used)g(in)0 2798 y(the)d(same)f(w)o(ay)h(to)g(see)g(the)f(a)n(v)n(ailable)g(styles) g(for)h(reading)g(CIF)h(and)f(to)f(change)h(the)g(current)g(style.)146 2919 y(Each)d(style)e(has)h(a)h(speci\002c)g(scalef)o(actor;)g(you)f (can')n(t)h(use)f(a)h(particular)f(style)f(with)h(a)g(dif)n(ferent)g (scalef)o(actor)-5 b(.)0 3039 y(T)d(o)35 b(change)h(the)f(scalef)o (actor)l(,)k(you')o(ll)34 b(ha)n(v)o(e)i(to)f(edit)g(the)g(appropriate) g(style)g(in)g(the)g Fa(ci\002nput)j Fc(or)d Fa(cif)n(output)0 3159 y Fc(section)28 b(of)h(the)f(technology)g(\002le.)43 b(This)28 b(process)h(is)f(described)g(in)h(\223Magic)f(Maintainer')-5 b(s)28 b(Manual)g(#2:)38 b(The)0 3280 y(T)-7 b(echnology)24 b(File.)-7 b(\224)0 3612 y Fe(3)143 b(Rounding)0 3835 y Fc(The)27 b(units)e(used)i(for)g(coordinates)f(in)g(Magic)g(are)i (generally)e(dif)n(ferent)h(from)f(those)g(in)g(CIF)i(\002les.)37 b(In)27 b(Magic,)0 3955 y(most)h(technology)h(\002les)h(use)f (lambda-based)g(units,)g(where)h(one)g(unit)f(is)g(typically)f(half)i (the)f(minimum)e(fea-)0 4076 y(ture)d(size.)31 b(In)25 b(CIF)g(\002les,)g(the)f(units)f(are)j(centimicrons)d(\(hundredths)g (of)i(a)g(micron\).)30 b(When)24 b(reading)h(CIF)g(and)0 4196 y(Calma)h(\002les,)h(an)f(inte)o(ger)f(scalef)o(actor)i(is)e(used) h(to)g(con)l(v)o(ert)f(from)h(centimicrons)f(to)h(Magic)f(units.)34 b(If)26 b(the)g(CIF)0 4317 y(\002le)h(contains)f(coordinates)g(that)h (don')n(t)f(scale)h(e)o(xactly)f(to)h(inte)o(ger)f(Magic)g(units,)g (Magic)h(rounds)f(the)g(coordi-)0 4437 y(nates)31 b(up)g(or)g(do)n(wn)g (to)g(the)g(closest)f(inte)o(ger)h(Magic)g(units.)49 b(A)31 b(CIF)h(coordinate)f(e)o(xactly)g(halfw)o(ay)g(between)0 4557 y(tw)o(o)21 b(Magic)g(units)f(is)h(rounded)g(do)n(wn.)29 b(The)21 b(\002nal)h(authority)e(on)h(rounding)f(is)h(the)g(procedure)h (CIFScaleCoord)0 4678 y(in)g(the)g(\002le)h(cif/CIFreadutils.c)f(When)g (rounding)f(occurs,)i(the)f(resulting)f(Magic)h(\002le)h(will)e(not)h (match)g(the)g(CIF)0 4798 y(\002le)j(e)o(xactly)-6 b(.)146 4918 y(T)f(echnology)30 b(\002les)h(usually)e(specify)i(geometrical)f (operations)g(such)g(as)h(bloating,)f(shrinking,)h(and-ing,)0 5039 y(and)c(or)n(-ing)f(to)h(be)g(performed)g(on)f(CIF)i(geometries)e (when)h(the)o(y)f(are)i(read)f(into)f(Magic.)37 b(These)27 b(geometrical)0 5159 y(operations)h(are)h(all)g(performed)f(in)h(the)f (CIF)i(coordinate)e(system)g(\(centimicrons\))f(so)i(there)g(is)f(no)g (rounding)0 5280 y(or)c(loss)e(of)i(accurac)o(y)g(in)f(the)g (operations.)30 b(Rounding)22 b(occurs)i(only)f(AFTER)h(the)f (geometrical)g(operations,)g(at)0 5400 y(the)i(last)f(possible)f (instant)h(before)h(entering)g(paint)f(into)g(the)g(Magic)h(database.) 1875 5649 y(\2263\226)p eop %%Page: 4 4 4 3 bop 0 -180 a Fc(September)25 b(26,)f(2001)781 b(Magic)24 b(T)l(utorial)g(#9:)30 b(F)o(ormat)24 b(Con)l(v)o(ersion)g(for)h(CIF)h (and)f(Calma)0 99 y Fe(4)143 b(Non-Manhattan)33 b(Geometries)0 417 y Fc(Magic)f(only)f(supports)g(Manhattan)g(features.)52 b(When)32 b(CIF)i(or)e(Calma)g(\002les)g(contain)f(non-Manhattan)g (fea-)0 537 y(tures,)37 b(the)o(y)e(are)h(approximated)e(with)g (Manhattan)g(ones.)62 b(The)35 b(approximations)e(occur)j(for)f(wires)g (\(if)g(the)0 658 y(centerline)22 b(contains)f(non-Manhattan)g(se)o (gments\))g(and)h(polygons)e(\(if)i(the)g(outline)f(contains)g (non-Manhattan)0 778 y(se)o(gments\).)39 b(In)28 b(these)g(cases,)h (the)f(non-Manhattan)e(se)o(gments)h(are)h(replaced)h(with)e(one)h(or)g (more)g(horizontal)0 899 y(and)j(v)o(ertical)g(se)o(gments)f(before)h (the)h(\002gure)f(is)g(processed.)50 b(Con)l(v)o(ersion)30 b(is)h(done)g(by)g(inserting)f(a)i(one-unit)0 1019 y(stairstep)24 b(on)h(a)g(45-de)o(gree)g(angle)g(until)f(a)i(point)e(is)g(reached)i (where)g(a)f(horizontal)g(or)g(v)o(ertical)f(line)h(can)g(reach)0 1139 y(the)f(se)o(gment')-5 b(s)22 b(endpoint.)29 b(Some)24 b(e)o(xamples)f(are)i(illustrated)e(in)g(the)h(\002gure)h(belo)n(w:)k (in)23 b(each)i(case,)g(the)f(\002gure)0 1260 y(on)h(the)f(left)h(is)f (the)h(one)g(speci\002ed)g(in)f(the)h(CIF)h(\002le,)f(and)g(the)f (\002gure)i(on)e(the)h(right)f(is)g(what)h(results)f(in)g(Magic.)877 4007 y @beginspecial 68 @llx 68 @lly 403 @urx 447 @ury 2574 @rwi @setspecial %%BeginDocument: ../psfigures/tut9.1.ps % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def % XCircuit output starts here. /dot { % -10 -10 20 20 bbox begingate 248 1.00 0 0 6 0.00 360.00 xcarc endgate } def /cifwire { % -272 -32 400 64 bbox begingate 0.490 0.651 0.980 scb 96 -32 beginpath 96 0 32 -90.00 90.00 arc -240 32 1 polyc -240 0 32 90.00 270.00 arc 96 -32 1 polyc 241 1.00 endpath sce 1 1.00 -240 0 96 0 2 polygon 1.00 0 96 0 dot 1.00 0 -240 0 dot 96 -32 beginpath 96 0 32 -90.00 90.00 arc -240 32 1 polyc -240 0 32 90.00 270.00 arc 96 -32 1 polyc 1 1.00 endpath endgate } def /pgsave save def bop % 800 1038 offsets % 32.00 8.00 gridspace 1.0000 inchscale 2.6000 setlinewidth 0.800 0.800 0.800 scb 241 1.00 672 302 800 302 1056 430 1056 558 928 686 736 654 672 590 672 302 8 polygon sce 0.490 0.651 0.980 scb 241 1.00 192 302 320 302 576 430 576 558 448 686 256 654 192 590 192 302 8 polygon sce 0.616 0.624 0.925 scb 241 1.00 672 302 864 302 864 366 928 366 928 430 1056 430 1056 558 992 558 992 622 928 622 928 686 864 686 864 622 672 622 672 302 15 polygon sce 0.490 0.651 0.980 scb 240 1.00 688 862 800 862 800 926 864 926 864 990 928 990 928 1054 992 1054 992 1182 928 1182 928 1118 864 1118 864 1054 800 1054 800 990 736 990 736 926 688 926 18 polygon sce 1.00 45 464 1070 cifwire 0 1.00 688 862 800 862 800 926 864 926 864 990 928 990 928 1054 992 1054 992 1182 928 1182 928 1118 864 1118 864 1054 800 1054 800 990 736 990 736 926 688 926 18 polygon 1 1.00 720 894 768 894 768 958 832 958 832 1022 896 1022 896 1086 960 1086 960 1150 9 polygon 1.00 0 960 1150 dot 1.00 0 720 894 dot 1 1.00 192 302 320 302 576 430 576 558 448 686 256 654 192 590 192 302 8 polygon 0.490 0.651 0.980 scb 241 1.00 800 302 864 302 864 334 800 302 4 polygon 240 1.00 672 590 704 622 672 622 3 polygon 240 1.00 864 678 928 686 864 686 3 polygon sce 1 1.00 672 302 864 302 864 366 928 366 928 430 1056 430 1056 558 992 558 992 622 928 622 928 686 864 686 864 622 672 622 672 302 15 polygon (CIF Wire) {/Helvetica 1.000 cf} 2 21 0 320 782 label (Resulting Magic Shape) {/Helvetica 1.000 cf} 2 21 0 864 782 label (CIF Polygon) {/Helvetica 1.000 cf} 2 21 0 352 206 label (Resulting Magic Shape) {/Helvetica 1.000 cf} 2 21 0 864 206 label pgsave restore showpage XCIRCsave restore %%EndDocument @endspecial 146 4512 a(The)29 b(shape)g(of)g(the)f(Magic)h(stairstep)f (depends)g(on)g(the)h(order)g(in)f(which)h(v)o(ertices)f(appear)h(in)g (the)f(CIF)i(or)0 4632 y(Calma)36 b(\002le.)62 b(The)36 b(stairstep)e(is)h(made)h(by)f(\002rst)g(incrementing)f(or)i (decrementing)f(the)g(x-coordinate,)i(then)0 4753 y(incrementing)d(or)g (decrementing)h(the)f(y-coordinate,)j(then)d(x,)j(then)e(y)-6 b(,)36 b(and)f(so)g(on.)60 b(F)o(or)35 b(e)o(xample,)h(in)e(the)0 4873 y(\002gure)j(abo)o(v)o(e,)i(the)e(polygon)f(w)o(as)h(speci\002ed)g (in)f(counter)n(-clockwise)h(order;)43 b(if)37 b(it)f(had)h(been)g (speci\002ed)g(in)0 4993 y(clockwise)24 b(order)h(the)g(result)f(w)o (ould)g(ha)n(v)o(e)h(been)g(slightly)e(dif)n(ferent.)146 5159 y(An)31 b(additional)f(approximation)f(occurs)j(for)f(wires.)50 b(The)31 b(CIF)h(wire)g(\002gure)f(assumes)g(that)f(round)h(caps)0 5280 y(will)f(be)h(generated)g(at)g(each)g(end)g(of)f(the)h(wire.)48 b(In)31 b(Magic,)h(square)f(caps)g(are)g(generated)g(instead.)48 b(The)31 b(top)0 5400 y(e)o(xample)24 b(of)h(the)f(\002gure)i(abo)o(v)o (e)e(illustrates)f(this)h(approximation.)1875 5649 y(\2264\226)p eop %%Page: 5 5 5 4 bop 0 -180 a Fc(Magic)24 b(T)l(utorial)g(#9:)30 b(F)o(ormat)24 b(Con)l(v)o(ersion)g(for)h(CIF)h(and)f(Calma)781 b(September)25 b(26,)g(2001)0 99 y Fe(5)143 b(Other)35 b(Pr)m(oblems)f(with)g(Reading) g(and)i(Writing)f(CIF)0 322 y Fc(Y)-11 b(ou)38 b(may)h(ha)n(v)o(e)f (noticed)g(that)h(when)f(you)h(wrote)f(out)g(CIF)i(for)f Fa(tut9a)h Fc(and)e(read)i(it)e(back)h(in)f(again,)k(you)0 443 y(didn')n(t)26 b(get)h(back)g(quite)f(what)g(you)g(started)h(with.) 35 b(Although)26 b(the)g(dif)n(ferences)h(shouldn')n(t)e(cause)j(an)o (y)e(serious)0 563 y(problems,)c(this)f(section)g(describes)h(what)g (the)o(y)g(are)h(so)f(you')o(ll)f(kno)n(w)g(what)h(to)g(e)o(xpect.)29 b(There)23 b(are)g(three)f(areas)0 683 y(where)f(there)f(may)h(be)f (discrepancies:)28 b(labels,)21 b(arrays,)g(and)g(contacts.)29 b(These)20 b(are)h(illustrated)e(in)h Fa(tut9b)p Fc(.)30 b(Load)0 804 y(this)25 b(cell,)g(then)h(generate)g(CIF)-8 b(,)27 b(then)e(read)h(the)g(CIF)g(back)g(in)f(again.)33 b(When)26 b(the)f(CIF)i(is)e(read)h(in,)g(you')o(ll)e(get)i(a)0 924 y(couple)c(of)h(w)o(arning)f(messages)g(because)h(Magic)f(w)o(on')n (t)g(allo)n(w)g(the)g(CIF)i(to)e(o)o(v)o(erwrite)g(e)o(xisting)e (cells:)29 b(it)22 b(uses)0 1045 y(ne)n(w)h(numbered)h(cells)f(instead) g(\(this)g(is)g(why)g(you)g(should)g(normally)g(read)h(CIF)h(with)e(a)h (\223clean)g(slate\224;)g(in)f(this)0 1165 y(case)34 b(it')-5 b(s)32 b(con)l(v)o(enient)g(to)h(ha)n(v)o(e)g(both)f(the)h (original)g(and)g(reconstructed)g(infromation)f(present)h(at)g(the)g (same)0 1285 y(time;)d(just)e(ignore)h(the)g(w)o(arnings\).)43 b(The)29 b(information)f(from)h(the)g(CIF)h(cell)f(appears)g(as)h(a)f (subcell)f(named)h Fa(1)0 1406 y Fc(right)e(on)g(top)g(of)g(the)h(old)e (contents)h(of)g Fa(tut9b)p Fc(;)j(select)d Fa(1)p Fc(,)h(mo)o(v)o(e)e (it)h(belo)n(w)g Fa(tut9b)p Fc(,)i(and)e(e)o(xpand)g(it)g(so)g(you)g (can)0 1526 y(compare)e(its)f(contents)g(to)g Fa(tut9b)p Fc(.)146 1647 y(The)c(\002rst)f(problem)g(area)i(is)e(that)g(CIF)h (normally)f(allo)n(ws)f(only)g(point)h(labels.)28 b(By)20 b(def)o(ault,)g(where)g(you)f(ha)n(v)o(e)0 1767 y(line)28 b(or)h(box)f(labels)g(in)g(Magic,)h(CIF)h(labels)e(are)h(generated)g (at)g(the)f(center)h(of)g(the)f(Magic)g(labels.)42 b(The)28 b(label)0 1887 y Fa(in)d Fc(in)f Fa(tut9y)i Fc(is)e(an)h(e)o(xample)f (of)h(a)g(line)f(label)h(that)f(gets)h(smashed)f(in)g(the)h(CIF)h (processing.)k(The)24 b(command)900 2103 y Fa(:cif)h(ar)n(ealabels)g(y) o(es)146 2319 y Fc(sets)36 b(a)g(switch)f(telling)g(Magic)h(to)f(use)h (an)h(e)o(xtension)d(to)i(cif)g(to)f(output)g(area-labels.)65 b(This)35 b(is)h(not)f(the)0 2440 y(def)o(ault)25 b(since)f(man)o(y)g (programs)g(that)h(tak)o(e)f(CIF)i(as)f(input)f(do)g(not)h(understand)f (this)g(e)o(xtension.)146 2560 y(If)g(you)f(are)h(reading)f(a)g(CIF)i (\002le)e(created)h(by)f(a)h(tool)e(other)h(than)g(Magic,)g(there)g(is) g(an)g(additional)f(problems)0 2681 y(with)h(labels.)30 b(The)23 b(CIF)i(label)f(construct)f(\(\223)p Fa(94)g Fd(label)h(x)g(y)g(layer)p Fc(\224\))f(has)h(an)g(optional)e Fd(layer)i Fc(\002eld)g(that)f(indicates)0 2801 y(the)i(layer)f(to)h (which)f(a)h(label)f(is)h(attached.)30 b(If)25 b(reading)g(a)g(CIF)h (\002le)f(generated)g(by)f(Magic,)g(this)g(\002eld)h(is)f(al)o(w)o(ays) 0 2921 y(present)j(and)h(so)f(a)h(label')-5 b(s)27 b(layer)g(is)g (unambiguous.)37 b(Ho)n(we)n(v)o(er)l(,)27 b(if)h(the)f(\002eld)h(is)f (absent,)g(Magic)h(must)e(decide)0 3042 y(which)g(layer)g(to)g(use.)35 b(It)27 b(does)f(this)f(by)h(looking)f(to)h(see)h(what)f(Magic)g (layers)g(lie)g(beneath)g(the)g(label)g(after)h(the)0 3162 y(CIF)h(has)e(been)h(read)g(in.)35 b(When)27 b(there)g(are)g(se)n (v)o(eral)f(layers,)g(it)g(chooses)g(the)h(one)f(appearing)h(LA)-11 b(TEST)26 b(in)g(the)0 3283 y Fa(types)i Fc(section)e(of)h(the)g (technology)f(\002le.)39 b(Usually)-6 b(,)26 b(it')-5 b(s)26 b(possible)g(to)h(ensure)g(that)g(the)g(right)f(layer)i(is)e (used)h(by)0 3403 y(placing)d(signal)f(layers)h(\(such)g(as)g(metal,)g (dif)n(fusion,)f(and)h(poly\))f(later)i(in)e(the)h(types)g(section)f (than)h(layers)g(such)0 3523 y(as)k(pwell)f(or)h(nplus.)38 b(Ho)n(we)n(v)o(er)l(,)27 b(sometimes)f(Magic)i(will)e(still)h(pick)g (the)h(wrong)f(layer)l(,)i(and)e(it)g(will)g(be)h(up)f(to)0 3644 y(you)d(to)h(mo)o(v)o(e)e(the)i(label)f(to)h(the)f(right)g(layer)h (yourself.)146 3764 y(The)20 b(second)f(problem)g(is)g(with)g(arrays.) 30 b(CIF)20 b(has)g(no)f(standard)g(array)i(construct,)f(so)f(when)g (Magic)h(outputs)0 3884 y(arrays)34 b(it)f(does)h(it)f(as)h(a)g (collection)f(of)g(cell)h(instances.)57 b(When)34 b(the)f(CIF)i(\002le) f(is)f(read)i(back)f(in,)h(each)f(array)0 4005 y(element)d(comes)h (back)g(as)f(a)i(separate)f(subcell.)51 b(The)32 b(array)g(of)g Fa(tut9y)g Fc(cells)g(is)f(an)h(e)o(xample)f(of)h(this.)50 b(Most)0 4125 y(designs)26 b(only)h(ha)n(v)o(e)g(a)h(fe)n(w)f(arrays)h (that)f(are)h(lar)n(ge)g(enough)f(to)g(matter;)g(where)h(this)f(is)g (the)g(case,)h(you)f(should)0 4246 y(go)d(back)g(after)h(reading)f(the) g(CIF)i(and)e(replace)h(the)f(multiple)e(instances)i(with)f(a)i(single) e(array)-6 b(.)31 b(Calma)24 b(format)0 4366 y(does)h(ha)n(v)o(e)f(an)h (array)h(construct,)e(so)g(it)g(doesn')n(t)h(ha)n(v)o(e)f(this)g (problem.)146 4486 y(The)i(third)e(discrepanc)o(y)h(is)g(that)g(where)h (there)f(are)h(lar)n(ge)g(contact)f(areas,)h(when)f(CIF)i(is)e(read)g (and)h(written)0 4607 y(the)h(area)h(of)f(the)g(contact)g(may)f(be)i (reduced)f(slightly)-6 b(.)35 b(This)26 b(happened)h(to)g(the)g(lar)n (ge)g(poly)g(contact)f(in)h Fa(tut9b)p Fc(.)0 4727 y(The)c(shrink)f (doesn')n(t)h(reduce)g(the)g(ef)n(fecti)n(v)o(e)f(area)i(of)g(the)e (contact;)i(it)e(just)g(reduces)h(the)g(area)h(dra)o(wn)f(in)g(Magic.)0 4847 y(T)-8 b(o)25 b(see)g(what')-5 b(s)24 b(happening)g(here,)h(place) g(the)g(box)f(around)h Fa(tut9b)h Fc(and)e Fa(1)p Fc(,)h(e)o(xpand)f(e) n(v)o(erything,)f(then)h(type)900 5064 y Fa(:cif)h(see)g(CCP)146 5280 y Fc(This)d(causes)h(feedback)h(to)e(be)h(displayed)e(sho)n(wing)g (CIF)j(layer)f(\223CCP\224)i(\(contact)e(cut)f(to)h(poly\).)29 b(Y)-11 b(ou)22 b(may)0 5400 y(ha)n(v)o(e)j(to)f(zoom)h(in)f(a)i(bit)e (to)h(distinguish)d(the)j(indi)n(vidual)e(via)i(holes.)30 b(Magic)25 b(generates)g(lots)f(of)h(small)f(contact)1875 5649 y(\2265\226)p eop %%Page: 6 6 6 5 bop 0 -180 a Fc(September)25 b(26,)f(2001)781 b(Magic)24 b(T)l(utorial)g(#9:)30 b(F)o(ormat)24 b(Con)l(v)o(ersion)g(for)h(CIF)h (and)f(Calma)0 68 y(vias)f(o)o(v)o(er)f(the)i(area)g(of)f(the)g (contact,)h(and)f(if)g(contacts)g(aren')n(t)h(e)o(xact)f(multiples)e (of)j(the)f(hole)g(size)g(and)h(spacing)0 188 y(then)c(e)o(xtra)h (space)g(is)f(left)h(around)g(the)f(edges.)30 b(When)22 b(the)f(CIF)i(is)f(read)g(back)g(in,)g(this)f(e)o(xtra)g(space)h(isn')n (t)f(turned)0 309 y(back)31 b(into)e(contact.)47 b(The)31 b(circuit)f(that)g(is)g(read)g(in)g(is)g(functionally)f(identical)h(to) g(the)g(original)g(circuit,)h(e)n(v)o(en)0 429 y(though)24 b(the)g(Magic)h(contact)f(appears)i(slightly)c(smaller)-5 b(.)146 549 y(There)24 b(is)f(an)g(additional)f(problem)g(with)h (generating)f(CIF)j(ha)n(ving)d(to)h(do)g(with)f(the)h(cell)h (hierarchy)-6 b(.)29 b(When)0 670 y(Magic)h(generates)h(CIF)-8 b(,)32 b(it)e(performs)g(geometric)g(operations)g(such)h(as)f(\223gro)n (w\224)h(and)f(\223shrink\224on)g(the)h(mask)0 790 y(layers.)63 b(Some)36 b(of)g(these)f(operations)g(are)h(not)f(guaranteed)h(to)g(w)o (ork)f(perfectly)h(on)f(hierarchical)h(designs.)0 911 y(Magic)20 b(detects)h(when)g(there)g(are)h(problems)d(and)i(creates)h (feedback)f(areas)h(to)e(mark)h(the)g(trouble)f(spots.)28 b(When)0 1031 y(you)h(write)g(CIF)-8 b(,)30 b(Magic)f(will)f(w)o(arn)i (you)e(that)h(there)h(were)f(troubles.)43 b(These)30 b(should)e(almost)g(ne)n(v)o(er)g(happen)0 1151 y(if)e(you)f(generate)h (CIF)h(from)f(designs)f(that)g(don')n(t)g(ha)n(v)o(e)h(an)o(y)f (design-rule)g(errors.)34 b(If)27 b(the)o(y)e(do)g(occur)l(,)h(you)g (can)0 1272 y(get)f(around)f(them)g(by)h(writing)f(cif)h(with)f(the)g (follo)n(wing)f(command)900 1500 y Fa(:cif)i(\003at)g Fd(\002leName)146 1728 y Fc(This)31 b(command)g(creates)h(an)g (internal)f(v)o(ersion)f(of)i(the)f(design)g(with)g(hierarchy)g(remo)o (v)o(ed,)h(before)h(out-)0 1849 y(puting)22 b(CIF)i(as)g(in)f Fa(cif)g(write)p Fc(.)30 b(An)24 b(alternati)n(v)o(e)d(approach)j(that) f(does)g(not)f(require)i(\003attening)e(is)h(to)g(modify)f(the)0 1969 y(technology)28 b(\002le)h(in)g(use.)43 b(Read)30 b(\223Magic)f(Maintainers)f(Manual)g(#2:)39 b(The)29 b(T)-7 b(echnology)28 b(File\224,)i(if)f(you)f(w)o(ant)0 2090 y(to)c(try)h(this)f(approach.)1875 5649 y(\2266\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tut10.ps0000644000175000001440000012173410751423606015221 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: tut10.dvi %%Pages: 9 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips tut10.dvi -o tut10.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Bold % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tut10.dvi) @start /Fa 1 16 df<0001FF0000000FFFE000003FFFF800007FFFFC0001FFFFFF0003 FFFFFF8007FFFFFFC00FFFFFFFE01FFFFFFFF01FFFFFFFF03FFFFFFFF87FFFFFFFFC7FFF FFFFFC7FFFFFFFFCFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFF FFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFE7FFFFFFFFC7FFFFFFFFC7FFFFFFF FC3FFFFFFFF81FFFFFFFF01FFFFFFFF00FFFFFFFE007FFFFFFC003FFFFFF8001FFFFFF00 007FFFFC00003FFFF800000FFFE0000001FF000027267BAB32>15 D E /Fb 133[44 50 50 72 50 55 33 39 44 1[55 50 55 83 28 1[33 28 55 50 33 44 55 44 55 50 7[72 3[72 66 55 72 2[78 72 94 66 2[39 3[66 72 72 66 72 6[33 7[50 50 50 1[25 33 2[50 42[{ TeXBase1Encoding ReEncodeFont }46 100.000003 /Times-Bold rf /Fc 134[60 3[66 40 47 53 2[60 66 100 33 2[33 66 60 1[53 66 53 1[60 12[80 1[86 4[113 80 5[73 2[86 8[40 4[60 1[60 60 60 2[30 43[66 2[{ TeXBase1Encoding ReEncodeFont }29 119.999948 /Times-Bold rf /Fd 105[50 1[44 44 10[33 13[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 33 2[33 1[33 3[94 1[72 61 55 66 1[55 72 72 89 61 1[39 33 72 72 55 61 72 66 66 72 5[28 28 50 50 50 50 50 50 50 50 50 50 1[25 33 25 2[33 33 33 3[50 1[33 29[55 55 2[{ TeXBase1Encoding ReEncodeFont }75 100.000003 /Times-Roman rf /Fe 134[44 2[44 50 28 39 39 1[50 50 50 72 28 2[28 50 50 28 44 50 44 50 50 12[55 1[61 1[61 1[66 83 3[33 2[61 1[72 66 1[61 11[50 2[50 50 2[25 33 3[33 33 37[50 2[{ TeXBase1Encoding ReEncodeFont }38 100.000003 /Times-Italic rf /Ff 104[143 28[64 72 1[104 72 80 48 56 64 1[80 72 80 120 40 80 1[40 80 72 48 64 80 64 80 72 48 8[143 104 104 96 80 104 1[88 1[104 135 96 2[56 112 112 3[104 8[48 72 72 72 72 72 72 72 72 72 72 2[48 36 4[48 3[72 35[{ TeXBase1Encoding ReEncodeFont }54 143.999997 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 617 101 a Ff(Magic)35 b(T)-13 b(utorial)34 b(#10:)44 b(The)35 b(Interacti)o(v)o(e)d(Router)1637 521 y Fe(Mic)o(hael)24 b(Arnold)1731 941 y Fd(O)h(Di)n(vision)1116 1062 y(La)o(wrence)g(Li)n (v)o(ermore)e(National)h(Laboratory)1511 1182 y(Li)n(v)o(ermore,)f(CA)i (94550)1053 1453 y(This)f(tutorial)g(corresponds)g(to)g(Magic)h(v)o (ersion)e(7.)0 1979 y Fc(T)-11 b(utorials)30 b(to)f(r)n(ead)h(\002rst:) 300 2182 y Fd(Magic)24 b(T)l(utorial)g(#1:)30 b(Getting)24 b(Started)300 2302 y(Magic)g(T)l(utorial)g(#2:)30 b(Basic)25 b(P)o(ainting)f(and)h(Selection)300 2423 y(Magic)f(T)l(utorial)g(#4:)30 b(Cell)25 b(Hierarchies)0 2625 y Fc(Commands)k(intr)n(oduced)j(in)f (this)f(tutorial:)300 2827 y Fd(:iroute)0 3030 y Fc(Macr)n(os)f(intr)n (oduced)i(in)g(this)f(tutorial:)300 3256 y Fd(\210R,)25 b(\210N)0 3852 y Ff(1)143 b(Intr)m(oduction)0 4076 y Fd(The)33 b(Magic)f(interacti)n(v)o(e)g(router)l(,)j Fe(Ir)l(outer)p Fd(,)e(pro)o(vides)f(an)h(interacti)n(v)o(e)f(interf)o (ace)h(to)f(Magic')-5 b(s)32 b(internal)h(maze)0 4196 y(router)-5 b(.)47 b(It)31 b(is)f(intended)g(as)g(an)h(aid)f(to)h (manual)f(routing.)46 b(Routing)30 b(is)g(done)g(one)h(connection)f(at) g(a)h(time,)g(the)0 4317 y(user)22 b(specifying)e(a)i(starting)f(point) f(and)i(destination)e(areas)i(prior)f(to)h(each)g(connection.)29 b(The)21 b(user)h(determines)0 4437 y(the)27 b(order)h(in)f(which)f (signals)g(are)i(routed)f(and)h(ho)n(w)e(multi-point)f(nets)i(are)h (decomposed)e(into)g(point-to-area)0 4557 y(connections.)49 b(In)31 b(addition)f(parameters)h(and)g(special)g(Magic)f Fe(hint)h Fd(layers)g(permit)f(the)h(user)g(to)g(control)f(the)0 4678 y(nature)25 b(of)h(the)f(routes.)31 b(T)-8 b(ypically)24 b(the)h(user)h(determines)e(the)h(o)o(v)o(erall)f(path)h(of)g(a)h (connection,)e(and)h(lea)n(v)o(es)g(the)0 4798 y(details)f(of)h (satisfying)e(the)i(design-rules,)f(and)g(detouring)g(around)h(or)g(o)o (v)o(er)f(minor)g(obstacles,)g(to)g(the)h(router)-5 b(.)146 4918 y(The)23 b(interacti)n(v)o(e)f(router)g(is)h(not)f(designed)g(for) h(fully)f(automatic)g(routing:)28 b(interactions)22 b(between)h(nets)f (are)0 5039 y(not)32 b(considered,)h(and)f(net)g(decomposition)e(is)i (not)f(automatic.)52 b(Thus)31 b(netlists)g(are)i(generally)f(not)f (suitable)0 5159 y(input)e(for)i(the)f(Irouter)-5 b(.)47 b(Ho)n(we)n(v)o(er)29 b(it)g(can)i(be)f(con)l(v)o(enient)g(to)f(obtain) h(endpoint)f(information)g(from)h(netlists.)0 5280 y(The)25 b Fe(Net2ir)f Fd(program)g(uses)g(netlist)f(information)g(to)h (generate)h(commands)f(to)g(the)g(Irouter)h(with)e(appropriate)0 5400 y(endpoints)j(for)i(speci\002ed)f(signals.)38 b(T)-8 b(ypically)26 b(a)i(user)g(might)e(setup)h(parameters)g(and)h(hints)e (to)h(ri)n(v)o(er)n(-route)g(a)1875 5649 y(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Fd(September)25 b(26,)f(2001)1373 b(Magic)25 b(T)l(utorial)e(#10:)30 b(The)25 b(Interacti)n(v)o(e)f(Router)0 68 y(set)g(of)g(connections,)f(and)h(then)g(generate)g(Irouter)h (commands)d(with)i(the)g(appropriate)g(endpoints)e(via)i(Net2ir)-5 b(.)0 188 y(F)o(or)25 b(details)f(on)g(Net2ir)h(see)g(the)g(manual)f (page)h Fe(net2ir\(1\))p Fd(.)146 310 y(This)38 b(tutorial)g(pro)o (vides)f(detailed)h(information)f(on)i(the)f(use)g(of)h(the)g(Irouter) -5 b(.)71 b(On-line)38 b(help,)k(Irouter)0 430 y(subcommands,)23 b(Irouter)i(parameters,)g(and)f(hint-layers)g(are)i(e)o(xplained.)0 777 y Ff(2)143 b(Getting)26 b(Started\227`Cntl-R',)d(`Cntl-N',)i(`:ir)m (oute')h(and)g(`:ir)m(oute)g(help')0 1003 y Fd(T)-8 b(o)22 b(mak)o(e)h(a)f(connection)g(with)g(the)g(Irouter)l(,)h(place)f(the)h (cursor)f(o)o(v)o(er)g(one)g(end)g(of)h(the)f(desired)g(connection)g (\(the)0 1123 y Fe(start-point)p Fd(\))h(and)i(the)f(box)h(at)f(the)h (other)g(end)f(\(the)h Fe(destination-ar)l(ea)p Fd(\).)k(Then)c(type) 900 1360 y Fb(Cntl-R)146 1596 y Fd(Note)36 b(that)g(the)g(box)f(must)g (be)h(big)g(enough)f(to)h(allo)n(w)f(the)h(route)g(to)f(terminate)h (entirely)f(within)g(it.)64 b(A)0 1717 y(design-rule)24 b(correct)i(connection)e(between)h(the)f(cursor)h(and)g(the)f(box)h (should)e(appear)-5 b(.)31 b(The)25 b(macro)900 1954 y Fb(Cntl-R)146 2190 y Fd(and)g(the)g(long)f(commands)900 2427 y Fb(:ir)n(oute)900 2547 y(:ir)n(oute)i(r)n(oute)146 2784 y Fd(are)32 b(all)e(equi)n(v)n(alent.)46 b(The)o(y)30 b(in)l(v)n(ok)o(e)g(the)g(Irouter)h(to)f(connect)g(the)h(cursor)f(with) g(the)h(interior)f(of)g(the)h(box.)0 2904 y(Note)25 b(that)g(the)g (last)g(connection)f(is)h(al)o(w)o(ays)g(left)g(selected.)33 b(This)24 b(allo)n(ws)g(further)i(terminals)e(to)h(be)g(connected)0 3024 y(to)f(the)h(route)g(with)f(the)g(second)h(Irouter)g(macro,)g Fb(Cntl-N)p Fd(.)g(T)m(ry)f(typing)900 3262 y Fb(Cntl-N)146 3498 y Fd(A)37 b(connection)f(between)h(the)g(cursor)g(and)g(the)g(pre) n(vious)e(route)i(should)f(appear)-5 b(.)67 b(In)37 b(general)g Fb(Cntl-N)0 3618 y Fd(routes)24 b(from)h(the)g(cursor)f(to)h(the)g (selection.)146 3739 y(There)36 b(are)g(a)f(number)f(of)i(commands)d (to)i(set)g(parameters)g(and)g(otherwise)f(interact)h(with)g(the)f (Irouter)-5 b(.)0 3860 y(These)25 b(commands)e(ha)n(v)o(e)i(the)g (general)g(form)900 4097 y Fb(:ir)n(oute)p Fe(subcommand)g Fd([)p Fe(ar)l(guments)p Fd(])146 4333 y(F)o(or)g(a)g(list)f(of)h (subcommands)e(and)i(a)g(short)f(description)g(of)g(each,)i(type)900 4570 y Fb(:ir)n(oute)g(help)146 4806 y Fd(Usage)f(information)f(on)g(a) h(subcommand)e(can)j(be)f(obtained)f(by)g(typing)900 5044 y Fb(:ir)n(oute)i(help)f Fd([)p Fe(subcommand)p Fd(])146 5280 y(As)h(with)g(Magic)f(in)h(general,)h(unique)e(abbre)n (viations)f(of)j(subcommands)d(and)i(most)f(of)h(their)g(ar)n(guments)0 5400 y(are)g(permitted.)j(Case)d(is)e(generally)h(ignored.)1875 5649 y(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Fd(Magic)24 b(T)l(utorial)g(#10:)30 b(The)25 b(Interacti)n(v)o(e)f(Router)1373 b(September)25 b(26,)g(2001)0 99 y Ff(3)143 b(:Undo)35 b(and)g(Cntl-C)0 322 y Fd(As)k(with)g(other)h(Magic)f(commands,)j(the)d(results)g(of)h Fb(:ir)n(oute)g Fd(can)g(be)g(undone)f(with)g Fb(:undo)p Fd(,)44 b(and)c(if)f(the)0 443 y(Irouter)24 b(is)g(taking)g(too)g(long) f(it)h(can)h(be)f(interrupted)g(with)f Fb(Cntl-C)p Fd(.)i(This)e(mak)o (es)h(it)g(easy)h(to)e(re\002ne)j(the)e(results)0 563 y(of)29 b(the)f(Irouter)g(by)h(trial)f(and)g(error)-5 b(.)42 b(If)29 b(you)e(don')n(t)i(lik)o(e)e(the)i(results)e(of)i(a)g (route,)g(undo)f(it,)g(tweak)h(the)f(Irouter)0 683 y(parameters)21 b(or)g(hints)f(you)h(are)h(using)e(and)h(try)g(again.)28 b(If)22 b(the)f(Irouter)g(is)g(taking)f(too)g(long,)h(you)g(can)g(v)o (ery)g(lik)o(ely)0 804 y(speed)j(things)f(up)h(by)g(interrupting)f(it,) h(resetting)f(performance)i(related)f(parameters,)h(and)f(trying)f (again.)30 b(The)0 924 y(details)24 b(of)h(parameters)g(and)g(hints)e (are)j(described)f(later)f(in)h(this)f(document.)0 1257 y Ff(4)143 b(Mor)m(e)36 b(about)f(Making)g(Connections\227`:ir)m(oute)d (r)m(oute')0 1481 y Fd(Start)25 b(points)f(for)h(routes)g(can)g(be)g (speci\002ed)g(via)g(the)g(cursor)l(,)g(labels,)f(or)h(coordinates.)31 b(Destination)23 b(areas)j(can)0 1601 y(be)c(speci\002ed)f(via)h(the)f (box,)h(labels,)f(coordinates)g(or)h(the)f(selection.)29 b(In)21 b(addition)g(start)g(and)g(destination)f(layers)0 1722 y(can)25 b(be)g(speci\002ed)g(e)o(xplicitly)-6 b(.)28 b(F)o(or)d(the)g(syntax)f(of)h(all)f(these)h(options)e(type)900 1903 y Fb(:ir)n(oute)j(help)f(r)n(oute)146 2085 y Fd(When)38 b(a)f(start)g(point)f(lies)h(on)g(top)f(of)h(e)o(xisting)f(geometry)g (it)h(is)g(assumed)f(that)h(a)g(connection)g(to)g(that)0 2205 y(material)31 b(is)g(desired.)50 b(If)31 b(this)g(is)g(not)f(the)i (case,)h(the)e(desired)g(starting)f(layer)i(must)e(be)i(e)o(xplicitly)d (speci\002ed.)0 2325 y(When)36 b(routing)f(to)h(the)g(selection)f(it)h (is)g(assumed)f(that)h(connection)f(to)h(the)g(selected)g(material)g (is)f(desired.)0 2446 y(By)d(def)o(ault,)g(routes)f(to)g(the)g(box)g (may)g(terminate)g(on)g(an)o(y)g(acti)n(v)o(e)f(route)h(layer)-5 b(.)50 b(If)32 b(you)f(are)h(ha)n(ving)f(trouble)0 2566 y(connecting)21 b(to)h(a)g(lar)n(ge)h(re)o(gion,)e(it)h(may)g(be)g (because)g(the)g(connection)f(point)g(or)h(area)h(is)f(too)f(f)o(ar)i (in)f(the)g(interior)0 2687 y(of)31 b(the)g(re)o(gion.)48 b(T)m(ry)31 b(mo)o(ving)e(it)h(to)n(w)o(ard)g(the)h(edge.)50 b(\(Alternately)30 b(see)h(the)g(discussion)e(of)i(the)g Fe(penetr)o(ation)0 2807 y Fd(parameter)25 b(in)g(the)f(wizard)h (section)f(belo)n(w)-6 b(.\))0 3140 y Ff(5)143 b(Hints)0 3364 y Fd(Magic)29 b(has)g(three)g(b)n(uilt-in)e(layers)i(for)h (graphical)e(control)h(of)g(the)g(Irouter)l(,)h Fb(fence)g Fd(\()p Fb(f)p Fd(\),)h Fb(magnet)e Fd(\()p Fb(mag)p Fd(\),)h(and)0 3484 y Fb(r)n(otate)24 b Fd(\()p Fb(r)p Fd(\).)30 b(These)23 b(layers)g(can)g(be)g(painted)f(and)h(erased)g (just)f(lik)o(e)g(other)h(Magic)f(layers.)30 b(The)23 b(ef)n(fect)g(each)g(has)0 3604 y(on)i(the)f(Irouter)h(is)g(described)f (belo)n(w)-6 b(.)0 3893 y Fc(5.1)119 b(The)30 b(F)m(ence)h(Lay)o(er)0 4081 y Fd(The)38 b(Irouter)f(w)o(on')n(t)h(cross)f(fence)h(boundaries.) 69 b(Thus)37 b(the)g(fence)h(layer)g(is)f(useful)h(both)e(for)i (carving)g(out)0 4201 y(routing-re)o(gions)20 b(and)j(for)f(blocking)f (routing)h(in)g(gi)n(v)o(en)e(areas.)31 b(It)22 b(is)g(frequently)g (useful)g(to)g(indicate)g(the)g(broad)0 4322 y(path)k(of)g(one)g(or)g (a)g(series)g(of)g(routes)g(with)f(fence.)35 b(In)26 b(addition)e(to)i(guiding)f(the)g(route,)h(the)g(use)g(of)g(fences)h (can)0 4442 y(greatly)e(speed)f(up)h(the)g(router)f(by)h(limiting)d (the)j(search.)0 4731 y Fc(5.2)119 b(The)30 b(Magnet)g(Lay)o(er)0 4918 y Fd(Magnets)f(attract)g(the)g(route.)45 b(The)o(y)29 b(can)g(be)h(used)f(to)g(pull)g(routes)g(in)g(a)h(gi)n(v)o(en)d (direction,)j(e.g.,)h(to)n(w)o(ards)d(one)0 5039 y(edge)c(of)f(a)h (channel.)30 b(Ov)o(er)23 b(use)h(of)f(magnets)g(can)h(mak)o(e)f (routing)g(slo)n(w)-6 b(.)28 b(In)c(particular)f(magnets)g(that)g(are)h (long)0 5159 y(and)j(f)o(ar)g(a)o(w)o(ay)g(from)f(the)h(actual)f(route) h(can)g(cause)g(performance)g(problems.)35 b(\(If)28 b(you)e(are)h(ha)n(ving)f(problems)0 5280 y(with)37 b(magnets)f(and)h (performance,)k(see)d(also)f(the)g(discussion)f(of)h(the)g Fe(penalty)g Fd(parameter)h(in)f(the)g(wizard)0 5400 y(section)24 b(belo)n(w)-6 b(.\))1875 5649 y(\2263\226)p eop %%Page: 4 4 4 3 bop 0 -180 a Fd(September)25 b(26,)f(2001)1373 b(Magic)25 b(T)l(utorial)e(#10:)30 b(The)25 b(Interacti)n(v)o(e)f(Router)0 82 y Fc(5.3)119 b(The)30 b(Rotate)g(Lay)o(er)0 270 y Fd(The)21 b(Irouter)f(associates)h(dif)n(ferent)f(weights)f(with)h (horizontal)g(and)h(v)o(ertical)f(routes)g(\(see)h(the)f(layer)n (-parameter)0 390 y(section)g(belo)n(w\).)29 b(This)20 b(is)h(so)g(that)f(a)i(preferred)g(routing)e(direction)g(can)i(be)f (established)f(for)h(each)h(layer)-5 b(.)29 b(When)0 511 y(tw)o(o)f(good)g(route-layers)h(are)g(a)n(v)n(ailable)f(\(as)h(in) f(a)h(tw)o(o-layer)n(-metal)g(process\))f(interference)i(between)f (routes)0 631 y(can)c(be)g(minimized)e(by)i(assigning)e(opposite)h (preferred)i(directions)d(to)i(the)f(layers.)146 752 y(The)35 b(rotate)f(layer)h(locally)f(in)l(v)o(erts)f(the)i(preferred)g (directions.)59 b(An)34 b(e)o(xample)g(use)g(of)h(the)f(rotate)h(layer) 0 872 y(might)18 b(in)l(v)n(olv)o(e)g(an)h Fb(L)p Fd(-shaped)h(b)n(us.) 28 b(The)19 b(natural)g(preferred)i(directions)d(on)h(one)g(le)o(g)g (of)g(the)g Fb(L)h Fd(are)g(the)f(opposite)0 992 y(from)25 b(the)f(other)l(,)h(and)g(thus)f(one)g(le)o(g)g(needs)h(to)g(be)g(mark) o(ed)f(with)g(the)h(rotate)g(layer)-5 b(.)0 1331 y Ff(6)143 b(Subcells)0 1555 y Fd(As)33 b(with)g(painting)f(and)h(other)g (operations)g(in)g(Magic,)i(the)e(Irouter')-5 b(s)33 b(output)f(is)h(written)g(to)g(the)g(cell)h(being)0 1675 y(edited.)j(What)27 b(the)g(router)g(sees,)h(that)e(is)h(which)g (features)g(act)h(as)f(obstacles,)g(is)f(determined)h(by)g(the)f(windo) n(w)0 1795 y(the)c(route)g(is)g(issued)f(to)h(\(or)g(other)g (designated)g(reference)h(windo)n(w)e(-)i(see)f(the)g(wizard)g (section.\))30 b(The)22 b(contents)0 1916 y(of)29 b(subcells)f(e)o (xpanded)g(in)g(the)h(route)g(windo)n(w)e(are)j(visible)d(to)i(the)f (Irouter)l(,)i(b)n(ut)f(it)f(only)g(sees)h(the)g(bounding)0 2036 y(box)o(es)34 b(of)h(une)o(xpanded)f(subcells.)61 b(These)35 b(bounding)f(box)o(es)g(appear)h(on)g(a)h(special)e Fb(SUBCELL)k Fd(pseudo-)0 2157 y(layer)-5 b(.)56 b(The)34 b(spacing)f(parameters)g(to)g(the)h Fb(SUBCELL)h Fd(layer)f(determine)f (e)o(xactly)g(ho)n(w)f(the)i(Irouter)f(treats)0 2277 y(une)o(xpanded)28 b(subcells.)41 b(\(See)29 b(the)g(section)f(on)g (spacing)g(parameters)h(belo)n(w)-6 b(.\))40 b(By)29 b(def)o(ault,)g(the)g(spacings)e(to)0 2397 y(the)21 b Fb(SUBCELL)j Fd(layer)e(are)g(lar)n(ge)g(enough)f(to)g(guarantee)h (that)g(no)f(design-rules)f(will)h(be)h(violated,)f(re)o(gardless)0 2518 y(of)31 b(the)f(contents)g(of)h(une)o(xpanded)e(subcells.)47 b(Routes)31 b(can)g(be)f(terminated)g(at)h(une)o(xpanded)e(subcells)h (in)g(the)0 2638 y(same)25 b(f)o(ashion)f(that)g(connections)g(to)g (other)h(pre-e)o(xisting)e(features)j(are)f(made.)0 2977 y Ff(7)143 b(Lay)o(er)34 b(P)o(arameters\227`:ir)m(oute)e(lay)o(ers')0 3200 y Fe(Route-layer)o(s)p Fd(,)i(speci\002ed)e(in)g(the)h Fb(mzr)n(outer)h Fd(section)e(of)g(the)h(technology)e(\002le,)k(are)e (the)f(layers)h(potentially)0 3321 y(a)n(v)n(ailable)26 b(to)g(the)h(Irouter)g(for)g(routing.)36 b(The)27 b Fb(lay)o(er)f Fd(subcommand)g(gi)n(v)o(es)f(access)i(to)g(parameters)g(associated)0 3441 y(with)20 b(these)h(route-layers.)30 b(Man)o(y)20 b(of)h(the)g(parameters)g(are)h(weights)f(for)g(f)o(actors)g(in)g(the)g (Irouter)g(cost-function.)0 3562 y(The)g(Irouter)f(stri)n(v)o(es)f(for) i(the)f(cheapest)h(possible)e(route.)29 b(Thus)20 b(the)g(balance)h (between)g(the)f(f)o(actors)h(in)f(the)g(cost-)0 3682 y(function)k(determines)g(the)g(character)i(of)f(the)g(routes:)30 b(which)24 b(layers)h(are)g(used)f(in)h(which)f(directions,)g(and)g (the)0 3802 y(number)37 b(of)g(contacts)g(and)h(jogs)e(can)i(be)f (controlled)g(in)g(this)f(w)o(ay)-6 b(.)68 b(But)38 b(be)f(careful!)70 b(Changes)37 b(in)g(these)0 3923 y(parameters)28 b(can)g(also)f (profoundly)g(in\003uence)h(performance.)40 b(Other)27 b(parameters)h(determine)f(which)g(of)h(the)0 4043 y(route-layers)i (are)i(actually)e(a)n(v)n(ailable)f(for)i(routing)f(and)g(the)g(width)g (of)g(routes)h(on)f(each)h(layer)-5 b(.)47 b(It)31 b(is)f(a)h(good)0 4164 y(idea)25 b(to)f(inacti)n(v)n(ate)g(route-layers)g(not)h(being)f (used)g(an)o(yw)o(ay)-6 b(,)24 b(as)h(this)f(speeds)g(up)h(routing.)146 4284 y(The)g(layers)g(subcommand)e(tak)o(es)i(a)g(v)n(ariable)f(number) h(of)f(ar)n(guments.)900 4507 y Fb(:ir)n(oute)i(lay)o(ers)146 4730 y Fd(prints)e(a)h(table)g(with)f(one)h(ro)n(w)f(for)h(each)h (route-layer)e(gi)n(ving)g(all)g(parameter)h(v)n(alues.)900 4954 y Fb(:ir)n(oute)h(lay)o(ers)p Fe(type)146 5177 y Fd(prints)e(all)h(parameters)g(associated)f(with)g(route-layer)h Fe(type)p Fd(.)900 5400 y Fb(:ir)n(oute)h(lay)o(ers)p Fe(type)e(par)o(ameter)1875 5649 y Fd(\2264\226)p eop %%Page: 5 5 5 4 bop 0 -180 a Fd(Magic)24 b(T)l(utorial)g(#10:)30 b(The)25 b(Interacti)n(v)o(e)f(Router)1373 b(September)25 b(26,)g(2001)146 69 y(prints)f(the)h(v)n(alue)f(of)h Fe(par)o(ameter)e Fd(for)i(layer)g Fe(type)p Fd(.)31 b(If)25 b Fe(type)g Fd(is)f(`)p Fb(*)p Fd(',)h(the)f(v)n(alue)g(of)h Fe(par)o(ameter)f Fd(is)g(printed)g(for)0 189 y(all)h(layers.)900 374 y Fb(:ir)n(oute)h(lay)o(ers)e Fe(type)h(par)o(ameter)f(value)146 559 y Fd(sets)h Fe(par)o(ameter)e Fd(to)i Fe(value)f Fd(on)h(layer)g Fe(type)p Fd(.)31 b(If)25 b Fe(type)g Fd(is)f(`)p Fb(*)p Fd(',)h Fe(par)o(ameter)f Fd(is)g(set)g(to)h Fe(value)g Fd(on)f(all)h(layers.)900 744 y Fb(:ir)n(oute)h(lay)o(ers)e Fe(type)h Fb(*)g Fe(value1)f(value2)h Fd(.)15 b(.)g(.)g Fe(valuen)146 928 y Fd(sets)25 b(a)g(ro)n(w)f(in)h(the)f(parameter)h (table.)900 1113 y Fb(:ir)n(oute)h(lay)o(ers)e(*)p Fe(par)o(ameter)g (value1)g(.)15 b(.)g(.)g(valuen)146 1298 y Fd(sets)25 b(a)g(column)f(in)g(the)h(table.)146 1418 y(There)h(are)f(six)f(layer)h (parameters.)145 1603 y Fa(\017)49 b Fb(acti)o(v)o(e)244 1724 y Fd(T)-8 b(ak)o(es)25 b(the)f(v)n(alue)h(of)f Fb(YES)i Fd(\(the)f(def)o(ault\))g(or)g Fb(NO)p Fd(.)f(Only)g(acti)n(v)o(e)g (layers)h(are)g(used)g(by)f(the)h(Irouter)-5 b(.)145 1916 y Fa(\017)49 b Fb(width)244 2037 y Fd(W)l(idth)22 b(of)g(routing)g(created)h(by)f(the)h(Irouter)f(on)g(the)h(gi)n(v)o(en) e(layer)-5 b(.)30 b(The)22 b(def)o(ault)g(is)h(the)f(minimum)e(width) 244 2157 y(permitted)k(by)g(the)h(design)f(rules.)145 2350 y Fa(\017)49 b Fb(hcost)244 2470 y Fd(Cost)24 b(per)i(unit-length) d(for)i(horizontal)f(se)o(gments)f(on)h(this)g(layer)-5 b(.)145 2662 y Fa(\017)49 b Fb(vcost)244 2783 y Fd(Cost)24 b(per)i(unit-length)d(for)i(v)o(ertical)f(se)o(gments.)145 2975 y Fa(\017)49 b Fb(jogcost)244 3096 y Fd(Cost)24 b(per)i(jog)e(\(transition)f(from)i(horizontal)f(to)g(v)o(ertical)g(se) o(gment\).)145 3288 y Fa(\017)49 b Fb(hintcost)244 3409 y Fd(Cost)24 b(per)i(unit-area)f(between)f(actual)h(route)g(and)g (magnet)f(se)o(gment.)0 3742 y Ff(8)143 b(Contact)34 b(P)o(arameters\227`:ir)m(oute)d(contacts')0 3966 y Fd(The)25 b Fb(contacts)g Fd(subcommand)f(gi)n(v)o(es)f(access)i(to)g(a)g(table)f (of)h(parameters)g(for)g(contact-types)f(used)h(in)f(routing,)0 4086 y(one)c(ro)n(w)g(of)h(parameters)f(per)h(type.)29 b(The)20 b(syntax)g(is)g(identical)g(to)g(that)g(of)g(the)g Fb(lay)o(ers)g Fd(subcommand)f(described)0 4207 y(abo)o(v)o(e,)24 b(and)g(parameters)h(are)h(printed)e(and)h(set)g(in)f(the)h(same)f(w)o (ay)-6 b(.)146 4327 y(There)26 b(are)f(three)g(contact-parameters.)145 4512 y Fa(\017)49 b Fb(acti)o(v)o(e)244 4632 y Fd(T)-8 b(ak)o(es)20 b(the)g(v)n(alue)g(of)g Fb(YES)i Fd(\(the)e(def)o(ault\))g (or)h Fb(NO)p Fd(.)e(Only)h(acti)n(v)o(e)f(contact)i(types)e(are)i (used)f(by)g(the)g(Irouter)-5 b(.)145 4825 y Fa(\017)49 b Fb(width)244 4945 y Fd(Diameter)28 b(of)h(contacts)f(of)h(this)f (type)g(created)h(by)g(the)f(Irouter)-5 b(.)42 b(The)29 b(def)o(ault)f(is)g(the)h(minimum)d(width)244 5066 y(permitted)e(by)g (the)h(design-rules.)145 5258 y Fa(\017)49 b Fb(cost)244 5378 y Fd(Cost)24 b(per)i(contact)e(char)n(ged)i(by)e(the)h(Irouter)g (cost-function.)1875 5649 y(\2265\226)p eop %%Page: 6 6 6 5 bop 0 -180 a Fd(September)25 b(26,)f(2001)1373 b(Magic)25 b(T)l(utorial)e(#10:)30 b(The)25 b(Interacti)n(v)o(e)f(Router)0 99 y Ff(9)143 b(Spacing)34 b(P)o(arameters\227`:ir)m(oute)e(spacing')0 322 y Fd(The)43 b(spacing)f(parameters)h(specify)g(minimum)e(spacings)h (between)h(the)g(route-types)f(\(route-layers)h(and)0 443 y(route-contacts\))38 b(and)f(arbitrary)h(Magic)g(types.)69 b(These)38 b(spacings)f(are)i(the)f(design-rules)f(used)g(internally)0 563 y(by)31 b(the)f(Irouter)h(during)f(routing.)48 b(Def)o(ault)30 b(v)n(alues)g(are)i(deri)n(v)o(ed)d(from)i(the)g Fb(dr)n(c)h Fd(section)e(of)h(the)f(technology)0 683 y(\002le.)g(These)22 b(v)n(alues)f(can)h(be)g(o)o(v)o(erridden)f(in)g(the)h Fb(mzr)n(outer)h Fd(section)e(of)h(the)g(technology)f(\002le.)30 b(\(See)23 b(the)e Fe(Ma)o(gic)0 804 y(Maintainer)o(s)27 b(Manual)i(on)g(T)-9 b(ec)o(hnolo)o(gy)28 b(F)l(iles)g Fd(for)i(details.\))43 b(Spacings)29 b(can)h(be)f(e)o(xamined)g(and)g (changed)g(at)0 924 y(an)o(y)21 b(time)h(with)f(the)h Fb(spacing)g Fd(subcommand.)28 b(Spacing)22 b(v)n(alues)f(can)h(be)h Fb(nil)p Fd(,)f Fb(0)p Fd(,)g(or)g(positi)n(v)o(e)e(inte)o(gers.)29 b(A)22 b(v)n(alue)0 1045 y(of)k Fb(nil)g Fd(means)f(there)i(is)e(no)h (spacing)f(constraint)g(between)h(the)g(route-layer)g(and)g(the)g(gi)n (v)o(en)e(type.)34 b(A)26 b(v)n(alue)f(of)0 1165 y Fb(0)g Fd(means)g(the)f(route-layer)h(may)g(not)g(o)o(v)o(erlap)e(the)i(gi)n (v)o(en)f(type.)31 b(If)25 b(a)g(positi)n(v)o(e)e(v)n(alue)h(is)h (speci\002ed,)g(the)g(Irouter)0 1285 y(will)g(maintain)g(the)h(gi)n(v)o (en)e(spacing)h(between)h(ne)n(w)g(routing)f(on)h(the)f(speci\002ed)i (route-layer)f(and)g(pre-e)o(xisting)0 1406 y(features)21 b(of)h(the)f(speci\002ed)g(type)g(\(e)o(xcept)f(when)h(connecting)g(to) f(the)h(type)g(at)g(an)g(end-point)f(of)i(the)f(ne)n(w)f(route\).)146 1526 y(The)25 b Fb(spacing)g Fd(subcommand)e(tak)o(es)i(se)n(v)o(eral)f (forms.)900 1745 y Fb(:ir)n(oute)i(spacing)146 1963 y Fd(prints)e(spacings)g(for)h(all)g(route-types.)30 b(\(Nil)24 b(spacings)g(are)i(omitted.\))900 2181 y Fb(:ir)n(oute)g(spacing)f Fe(r)l(oute-type)146 2400 y Fd(prints)f(spacings)g(for)h Fe(r)l(oute-type)p Fd(.)30 b(\(Nil)24 b(spacings)g(are)i(omitted.\))900 2618 y Fb(:ir)n(oute)g(spacing)f Fe(r)l(oute-type)f(type)146 2837 y Fd(prints)g(the)h(spacing)f(between)h Fe(r)l(oute-type)f Fd(and)h Fe(type)p Fd(.)900 3055 y Fb(:ir)n(oute)h(spacing)f Fe(r)l(oute-type)f(type)h(value)146 3273 y Fd(sets)g(the)f(spacing)h (between)f Fe(r)l(oute-type)g Fd(and)h Fe(type)g Fd(to)f Fe(value)p Fd(.)146 3394 y(The)30 b(spacings)e(associated)h(with)g (each)h(route-type)f(are)h(the)f(ones)h(that)f(are)h(observ)o(ed)e (when)i(the)f(Irouter)0 3514 y(places)j(that)g(route-type.)53 b(T)-8 b(o)33 b(change)f(the)g(spacing)g(between)h(tw)o(o)f (route-types,)h(tw)o(o)f(spacing)g(parameters)0 3634 y(must)26 b(be)i(changed:)36 b(the)27 b(spacing)g(to)g(the)g(\002rst)h (type)f(when)g(routing)f(on)i(the)f(second,)h(and)f(the)g(spacing)g(to) g(the)0 3755 y(second)e(type)f(when)h(routing)e(on)i(the)g(\002rst.)146 3875 y(Spacings)j(to)f(the)g Fb(SUBCELL)j Fd(pseudo-type)d(gi)n(v)o(e)f (the)h(minimum)e(spacing)j(between)f(a)h(route-type)f(and)0 3996 y(une)o(xpanded)32 b(subcells.)54 b(The)33 b Fb(SUBCELL)i Fd(spacing)d(for)h(a)g(gi)n(v)o(en)e(route-layer)i(def)o(aults)g(to)f (the)h(maximum)0 4116 y(spacing)28 b(to)g(the)g(route-layer)h(required) g(by)f(the)g(design-rules)g(\(in)g(the)h Fb(dr)n(c)g Fd(section)f(of)h(the)f(technology)g(\002le\).)0 4236 y(This)18 b(ensures)i(that)e(no)h(design-rules)g(will)f(be)h(violated)g (re)o(gardless)f(of)h(the)g(contents)g(of)g(the)g(subcell.)28 b(If)20 b(subcell)0 4357 y(designs)30 b(are)i(constrained)f(in)f(a)i(f) o(ashion)e(that)h(permits)f(closer)i(spacings)e(to)h(some)f(layers,)j (the)e Fb(SUBCELL)0 4477 y Fd(spacings)24 b(can)h(be)g(changed)g(to)f (tak)o(e)h(adv)n(antage)g(of)g(this.)0 4815 y Ff(10)143 b(Sear)m(ch)35 b(P)o(arameters\227`:sear)m(ch')0 5039 y Fd(The)c(Mzrouter)g(search)g(is)f(windo)n(wed.)48 b(Early)31 b(in)f(the)h(search)g(only)f(partial)h(paths)f(near)h(the)g(start)g (point)e(are)0 5159 y(considered;)c(as)g(the)h(search)f(progresses)g (the)g(windo)n(w)f(is)h(mo)o(v)o(ed)f(to)n(w)o(ards)g(the)h(goal.)32 b(This)25 b(pre)n(v)o(ents)f(combi-)0 5280 y(natorial)29 b(e)o(xplosion)f(during)i(the)g(search,)h(b)n(ut)f(still)e(permits)h (the)h(e)o(xploration)e(of)j(alternati)n(v)o(es)d(at)i(all)g(stages.)0 5400 y(The)23 b Fb(sear)n(ch)h Fd(subcommand)d(permits)h(access)h(to)f (tw)o(o)h(parameters)g(controlling)e(the)i(windo)n(wed)e(search,)j Fb(rate)p Fd(,)1875 5649 y(\2266\226)p eop %%Page: 7 7 7 6 bop 0 -180 a Fd(Magic)24 b(T)l(utorial)g(#10:)30 b(The)25 b(Interacti)n(v)o(e)f(Router)1373 b(September)25 b(26,)g(2001)0 69 y(and)30 b Fb(width)p Fd(.)45 b(The)30 b Fb(rate)g Fd(parameter)g(determines)f(ho)n(w)g(f)o(ast)g(the)h(windo) n(w)e(is)h(shifted)g(to)n(w)o(ards)f(the)i(goal,)g(and)0 189 y(the)e Fb(width)g Fd(parameter)g(gi)n(v)o(es)e(the)i(width)f(of)g (the)h(windo)n(w)-6 b(.)38 b(The)27 b(units)g(are)h(comparable)g(with)f (those)g(used)g(in)0 309 y(the)h(cost)f(parameters.)40 b(If)28 b(the)g(router)g(is)f(taking)g(too)g(long)h(to)f(complete,)h (try)f(increasing)h Fb(rate)p Fd(.)40 b(If)28 b(the)g(router)0 430 y(is)e(choosing)f(poor)h(routes,)g(try)g(decreasing)h Fb(rate)p Fd(.)35 b(The)27 b(windo)n(w)d(width)i(should)f(probably)g (be)i(at)f(least)g(twice)0 550 y(the)f(rate.)146 673 y(The)g(subcommand)e(has)i(this)f(form:)900 923 y Fb(:ir)n(oute)i(sear) n(ch)g Fd([)p Fe(par)o(ameter)p Fd(])d([)p Fe(value)p Fd(])146 1171 y(If)i Fe(value)e Fd(is)h(omitted,)f(the)g(current)h(v)n (alue)g(is)f(printed,)h(if)f Fe(par)o(ameter)g Fd(is)g(omitted)g(as)h (well,)g(both)f(parameter)0 1291 y(v)n(alues)h(are)i(printed.)0 1648 y Ff(11)143 b(Messages\227`:ir)m(oute)33 b(v)o(erbosity')0 1877 y Fd(The)25 b(number)f(of)h(messages)f(printed)g(by)h(the)f (Irouter)h(is)g(controlled)f(by)900 2127 y Fb(:ir)n(oute)i(v)o (erbosity)p Fe(value)146 2375 y Fd(If)i(v)o(erbosity)d(is)i(set)g(to)g Fb(0)p Fd(,)g(only)f(errors)i(and)f(w)o(arnings)f(are)i(printed.)37 b(A)27 b(v)n(alue)g(of)g Fb(1)g Fd(\(the)g(def)o(ault\))g(results)0 2495 y(in)d(short)h(messages.)30 b(A)24 b(v)n(alue)h(of)g Fb(2)f Fd(causes)h(statistics)e(to)i(be)g(printed.)0 2852 y Ff(12)143 b(V)-14 b(ersion\227`:ir)m(oute)33 b(v)o(ersion')0 3081 y Fd(The)25 b(subcommand)900 3331 y Fb(:ir)n(oute)h(v)o(ersion)146 3578 y Fd(prints)e(the)h(Irouter)g(v)o(ersion)f(in)g(use.)0 3935 y Ff(13)143 b(Sa)l(ving)35 b(and)g(Restoring)e(P)o (arameters\227`:ir)m(oute)f(sa)l(v)o(e')0 4164 y Fd(The)25 b(command)900 4415 y Fb(:ir)n(oute)h(sa)n(v)o(e)e Fe(\002le)p Fb(.ir)146 4662 y Fd(sa)n(v)o(es)31 b(a)o(w)o(ay)g(the)g(current)h (settings)e(of)h(all)h(the)f(Irouter)g(parameters)h(in)f(\002le)h Fe(\002le)p Fb(.ir)p Fd(.)50 b(P)o(arameters)31 b(can)h(be)0 4782 y(reset)25 b(to)f(these)h(v)n(alues)f(at)h(an)o(y)f(time)g(with)g (the)h(command)900 5032 y Fb(:sour)n(ce)h Fe(\002le)p Fb(.ir)146 5280 y Fd(This)d(feature)h(can)f(be)g(used)g(to)g(setup)g (parameter)n(-sets)g(appropriate)g(to)g(dif)n(ferent)f(routing)h(conte) o(xts.)28 b(Note)0 5400 y(that)c(the)h(e)o(xtension)e Fb(.ir)i Fd(is)f(recommended)h(for)g(Irouter)g(parameter)n(-\002les.) 1875 5649 y(\2267\226)p eop %%Page: 8 8 8 7 bop 0 -180 a Fd(September)25 b(26,)f(2001)1373 b(Magic)25 b(T)l(utorial)e(#10:)30 b(The)25 b(Interacti)n(v)o(e)f(Router)0 99 y Ff(14)143 b(W)m(izard)35 b(P)o(arameters\227`:ir)m(oute)d(wizard') 0 323 y Fd(Miscellaneous)27 b(parameters)i(that)f(are)i(probably)d(not) h(of)h(interest)f(to)g(the)h(casual)g(user)f(are)i(accessed)f(via)f (the)0 444 y Fb(wizard)d Fd(subcommand.)k(The)c(parameters)g(are)h(as)f (follo)n(ws:)145 675 y Fa(\017)49 b Fb(bloom)40 b Fd(T)-8 b(ak)o(es)40 b(on)g(a)g(non-ne)o(gati)n(v)o(e)d(inte)o(ger)i(v)n(alue.) 76 b(This)39 b(controls)h(the)f(amount)g(of)i(compulsory)244 795 y(searching)26 b(from)h(a)g(focus,)g(before)g(the)g(ne)o(xt)e (focus)i(is)f(pick)o(ed)h(based)f(on)h(the)f(cost-function)g(and)g (win-)244 916 y(do)n(w)k(position.)48 b(In)31 b(practice)h Fb(1)f Fd(\(the)g(def)o(ault)g(v)n(alue\))f(seems)h(to)g(be)g(the)g (best)f(v)n(alue.)49 b(This)31 b(parameter)244 1036 y(may)24 b(be)h(remo)o(v)o(ed)f(in)g(the)h(future.)145 1242 y Fa(\017)49 b Fb(boundsIncr)n(ement)43 b Fd(T)-8 b(ak)o(es)39 b(on)h(the)g(v)n(alue)f Fb(A)-5 b(UT)n(OMA)c(TIC)39 b Fd(or)h(a)g(positi)n(v)o(e)d(inte)o(ger)-5 b(.)75 b(Determines)244 1362 y(in)34 b(what)g(size)g(chunks)g(the)g(layout)g(is)g(preprocessed) g(for)h(routing.)58 b(This)33 b(preprocessing)h(\(blockage)244 1483 y(generation\))e(tak)o(es)h(a)g(signi\002cant)f(fraction)g(of)h (the)g(routing)e(time,)j(thus)e(performance)h(may)g(well)f(be)244 1603 y(impro)o(v)o(ed)23 b(by)h(e)o(xperimenting)f(with)h(this)g (parameter)-5 b(.)145 1809 y Fa(\017)49 b Fb(estimate)35 b Fd(T)-8 b(ak)o(es)35 b(on)g(a)g(boolean)g(v)n(alue.)60 b(If)36 b Fb(ON)e Fd(\(the)h(def)o(ault\))g(an)g(estimation)e(plane)i (is)g(generated)244 1929 y(prior)27 b(to)g(each)h(route)g(that)f (permits)f(cost-to-completion)g(estimates)g(to)h(f)o(actor)h(in)f (subcells)g(and)g(fence)244 2049 y(re)o(gions.)40 b(This)28 b(can)g(be)h(v)o(ery)f(important)f(to)h(ef)n(\002cient)g(routing.)40 b(Its)28 b(rarely)h(useful)f(to)g(turn)g(estimation)244 2170 y(of)n(f.)145 2375 y Fa(\017)49 b Fb(expandDests)35 b Fd(T)-8 b(ak)o(es)33 b(on)h(a)g(boolean)f(v)n(alue.)57 b(If)34 b Fb(ON)f Fd(\(not)g(the)h(def)o(ault\))f(destination)f(areas)j (are)f(e)o(x-)244 2496 y(panded)g(to)h(include)f(all)h(of)f(an)o(y)h (nodes)f(the)o(y)g(o)o(v)o(erlap.)60 b(This)34 b(is)g(particularly)g (useful)h(if)f(the)h(Irouter)244 2616 y(is)g(being)h(in)l(v)n(ok)o(ed)f (from)h(a)g(script,)i(since)e(it)g(is)f(dif)n(\002cult)g(to)h (determine)f(optimal)g(destination)f(areas)244 2737 y(automatically)-6 b(.)145 2942 y Fa(\017)49 b Fb(penalty)33 b Fd(T)-8 b(ak)o(es)33 b(on)f(a)i(rational)e(v)n(alue)g(\(def)o(ault)h(is)f(1024.0\).)54 b(It)32 b(is)h(not)f(strictly)f(true)i(that)g(the)f(router)244 3063 y(searches)k(only)e(within)g(its)h(windo)n(w)-6 b(.)60 b(P)o(aths)34 b(behind)h(the)g(windo)n(w)f(are)i(also)f (considered,)i(b)n(ut)e(with)244 3183 y(cost)27 b(penalized)g(by)h(the) f(product)g(of)h(their)f(distance)g(to)g(the)h(windo)n(w)e(and)h(the)h (penalty)f(f)o(actor)-5 b(.)39 b(It)27 b(w)o(as)244 3303 y(originally)e(thought)g(that)g(small)h(penalties)f(might)g(be)h (desirable,)h(b)n(ut)e(e)o(xperience,)i(so)f(f)o(ar)l(,)h(has)f(sho)n (wn)244 3424 y(that)f(lar)n(ge)g(penalties)g(w)o(ork)g(better)-5 b(.)31 b(In)25 b(particular)g(it)g(is)g(important)e(that)i(the)g(ratio) g(between)g(the)g(actual)244 3544 y(cost)f(of)h(a)g(route)g(and)g(the)g (initial)e(estimate)h(is)g(less)h(than)f(the)h(v)n(alue)f(of)h Fb(penalty)p Fd(,)h(otherwise)e(the)h(search)244 3665 y(can)20 b(e)o(xplode)g(\(tak)o(e)g(practically)g(fore)n(v)o(er\).)29 b(If)20 b(you)g(suspect)g(this)f(is)h(happening,)g(you)g(can)g(set)g Fb(v)o(erbosity)244 3785 y Fd(to)27 b Fb(2)g Fd(to)f(check,)i(or)g (just)e(increase)h(the)g(v)n(alue)g(of)g Fb(penalty)p Fd(.)38 b(In)28 b(summary)e(it)g(appears)i(that)f(the)f(v)n(alue)h(of) 244 3905 y(penalty)e(doesn')n(t)g(matter)h(much)f(as)h(long)f(as)h(it)f (is)g(lar)n(ge)h(\(b)n(ut)g(not)f(so)g(lar)n(ge)i(as)e(to)h(cause)g(o)o (v)o(er\003o)n(ws\).)32 b(It)244 4026 y(will)24 b(probably)g(be)h(remo) o(v)o(ed)e(in)i(the)f(future.)145 4231 y Fa(\017)49 b Fb(penetration)34 b Fd(This)d(parameter)i(tak)o(es)f(the)g(v)n(alue)g Fb(A)-5 b(UT)n(OMA)c(TIC)32 b Fd(or)h(a)f(positi)n(v)o(e)e(inte)o(ger) -5 b(.)52 b(It)33 b(deter)n(-)244 4352 y(mines)j(ho)n(w)g(f)o(ar)i (into)e(a)i(block)o(ed)e(area)i(the)f(router)g(will)f(penetrate)i(to)e (mak)o(e)h(a)h(connection.)66 b(Note)244 4472 y(ho)n(we)n(v)o(er)30 b(the)h(router)g(will)g(in)g(no)g(case)h(violate)e(spacing)h (constraints)f(to)h(nodes)g(not)g(in)l(v)n(olv)o(ed)e(in)i(the)244 4592 y(route.)145 4798 y Fa(\017)49 b Fb(windo)o(w)32 b Fd(This)g(parameter)h(tak)o(es)f(the)g(v)n(alue)g Fb(COMMAND)f Fd(\(the)i(def)o(ault\))f(or)g(a)h(windo)n(w)e(id)h(\(small)244 4918 y(inte)o(gers\).)i(It)26 b(determines)g(the)g(reference)i(windo)n (w)d(for)h(routes.)35 b(The)26 b(router)g(sees)h(the)f(w)o(orld)g(as)g (it)g(ap-)244 5039 y(pears)d(in)f(the)g(reference)j(windo)n(w)-6 b(,)21 b(e.g.,)i(it)f(sees)g(the)h(contents)f(of)g(subcells)g(e)o (xpanded)g(in)g(the)g(reference)244 5159 y(windo)n(w)-6 b(.)44 b(If)30 b Fb(windo)o(w)g Fd(is)f(set)h(to)f Fb(COMMAND)g Fd(the)h(reference)h(windo)n(w)e(is)g(the)h(one)f(that)h(contained)244 5280 y(the)22 b(cursor)f(when)h(the)g(route)g(w)o(as)f(in)l(v)n(ok)o (ed.)29 b(T)-8 b(o)22 b(set)f(the)h(reference)i(windo)n(w)c(to)h(a)i (\002x)o(ed)e(windo)n(w)-6 b(,)21 b(place)244 5400 y(the)k(cursor)f(in) h(that)f(windo)n(w)g(and)g(type:)1875 5649 y(\2268\226)p eop %%Page: 9 9 9 8 bop 0 -180 a Fd(Magic)24 b(T)l(utorial)g(#10:)30 b(The)25 b(Interacti)n(v)o(e)f(Router)1373 b(September)25 b(26,)g(2001)1144 84 y Fb(:ir)n(oute)h(wizard)f(windo)o(w)g(.)0 424 y Ff(Refer)m(ences)0 647 y Fd([1])49 b(M.H.)30 b(Arnold)g(and)h(W) -9 b(.S.)31 b(Scott,)56 b(\223)-8 b(An)30 b(Interacti)n(v)o(e)g(Maze)h (Router)g(with)f(Hints\224,)56 b Fe(Pr)l(oceedings)29 b(of)h(the)165 768 y(25th)24 b(Design)g(A)n(utomation)f(Confer)l(ence)p Fd(,)36 b(June)25 b(1988,)f(pp.)g(672\226676.)1875 5649 y(\2269\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tut8.ps0000644000175000001440000037071510751423606015155 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: tut8.dvi %%Pages: 15 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman Courier %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips tut8.dvi -o tut8.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Bold % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet %%BeginProcSet: special.pro TeXDict begin /SDict 200 dict N SDict begin /@SpecialDefaults{/hs 612 N /vs 792 N /ho 0 N /vo 0 N /hsc 1 N /vsc 1 N /ang 0 N /CLIP 0 N /rwiSeen false N /rhiSeen false N /letter{}N /note{}N /a4{}N /legal{}N}B /@scaleunit 100 N /@hscale{@scaleunit div /hsc X}B /@vscale{@scaleunit div /vsc X}B /@hsize{/hs X /CLIP 1 N}B /@vsize{/vs X /CLIP 1 N}B /@clip{ /CLIP 2 N}B /@hoffset{/ho X}B /@voffset{/vo X}B /@angle{/ang X}B /@rwi{ 10 div /rwi X /rwiSeen true N}B /@rhi{10 div /rhi X /rhiSeen true N}B /@llx{/llx X}B /@lly{/lly X}B /@urx{/urx X}B /@ury{/ury X}B /magscale true def end /@MacSetUp{userdict /md known{userdict /md get type /dicttype eq{userdict begin md length 10 add md maxlength ge{/md md dup length 20 add dict copy def}if end md begin /letter{}N /note{}N /legal{} N /od{txpose 1 0 mtx defaultmatrix dtransform S atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{itransform lineto} }{6 -2 roll transform 6 -2 roll transform 6 -2 roll transform{ itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll curveto}}{{ closepath}}pathforall newpath counttomark array astore /gc xdf pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack}if}N /txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 -1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop 90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr 2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 -1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S TR}if}N /cp {pop pop showpage pm restore}N end}if}if}N /normalscale{Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale}if 0 setgray} N /psfts{S 65781.76 div N}N /startTexFig{/psf$SavedState save N userdict maxlength dict begin /magscale true def normalscale currentpoint TR /psf$ury psfts /psf$urx psfts /psf$lly psfts /psf$llx psfts /psf$y psfts /psf$x psfts currentpoint /psf$cy X /psf$cx X /psf$sx psf$x psf$urx psf$llx sub div N /psf$sy psf$y psf$ury psf$lly sub div N psf$sx psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub TR /showpage{}N /erasepage{}N /copypage{}N /p 3 def @MacSetUp}N /doclip{ psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath moveto}N /endTexFig{end psf$SavedState restore}N /@beginspecial{SDict begin /SpecialSave save N gsave normalscale currentpoint TR @SpecialDefaults count /ocount X /dcount countdictstack N}N /@setspecial {CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR }{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury lineto closepath clip}if /showpage{}N /erasepage{}N /copypage{}N newpath }N /@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{ end}repeat grestore SpecialSave restore end}N /@defspecial{SDict begin} N /@fedspecial{end}B /li{lineto}B /rl{rlineto}B /rc{rcurveto}B /np{ /SaveX currentpoint /SaveY X N 1 setlinecap newpath}N /st{stroke SaveX SaveY moveto}N /fil{fill SaveX SaveY moveto}N /ellipse{/endangle X /startangle X /yrad X /xrad X /savematrix matrix currentmatrix N TR xrad yrad scale 0 0 1 startangle endangle arc savematrix setmatrix}N end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tut8.dvi) @start /Fa 7 62 df<0000FF00000007FFE000001F81F800003E007C0000FC003F0001 F8001F8001F0000F8003E00007C007C00003E007C00003E00FC00003F00F800001F01F80 0001F81F800001F83F800001FC3F800001FC3F800001FC3F000000FC7F000000FE7F0000 00FE7F000000FE7F000000FE7F000000FEFF000000FFFF000000FFFF000000FFFF000000 FFFF000000FFFF000000FFFF000000FFFF000000FFFF000000FFFF000000FFFF000000FF FF000000FFFF000000FFFF000000FFFF000000FFFF000000FFFF000000FFFF000000FFFF 000000FFFF000000FFFF000000FFFF000000FF7F000000FE7F000000FE7F000000FE7F00 0000FE7F000000FE7F800001FE3F800001FC3F800001FC3F800001FC1F800001F81F8000 01F80FC00003F00FC00003F00FC00003F007E00007E003E00007C003F0000FC001F8001F 8000FC003F00003E007C00001F81F8000007FFE0000000FF000028447CC131>48 D<000030000000F0000001F0000003F000001FF00000FFF000FFFFF000FFE7F000FF07F0 000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0 000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0 000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0 000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0 000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0 000007F0000007F0000007F0000007F0000007F0000007F0000007F000000FF800001FFC 007FFFFFFF7FFFFFFF7FFFFFFF204278C131>I<0003FE0000001FFFC000007FFFF00001 F80FFC0003C001FE00078000FF000E00007F801C00003FC01C00001FE03800001FF03000 000FF07000000FF860000007F86C000007F8FF000007FCFF800007FCFFC00007FCFFC000 03FCFFC00003FCFFC00003FCFFC00003FC7F800007FC3F000007FC00000007FC00000007 F800000007F80000000FF80000000FF00000001FF00000001FE00000001FE00000003FC0 0000007F800000007F00000000FF00000000FE00000001FC00000003F800000007F00000 0007E00000000FC00000001F800000003F000000007C00000000F800000000F000000001 E000000003C000000007800000000F00000C001E00000C003C00000C0038000018007000 001800E000001801C0000018038000003807000000300E000000701FFFFFFFF01FFFFFFF F03FFFFFFFF07FFFFFFFF0FFFFFFFFE0FFFFFFFFE0FFFFFFFFE026427BC131>I<000000 0380000000000380000000000780000000000F80000000000F80000000001F8000000000 3F80000000003F80000000007F8000000000FF8000000000FF8000000001FF8000000003 BF80000000033F80000000073F80000000063F800000000C3F800000001C3F8000000018 3F80000000303F80000000703F80000000603F80000000C03F80000001C03F8000000180 3F80000003003F80000007003F80000006003F8000000C003F8000001C003F8000001800 3F80000030003F80000070003F80000060003F800000E0003F800001C0003F8000018000 3F80000380003F80000300003F80000600003F80000E00003F80000C00003F8000180000 3F80003800003F80003000003F80006000003F8000E000003F8000FFFFFFFFFFC0FFFFFF FFFFC0FFFFFFFFFFC00000003F80000000003F80000000003F80000000003F8000000000 3F80000000003F80000000003F80000000003F80000000003F80000000003F8000000000 3F80000000003F80000000003F8000000000FFE00000007FFFFFC000007FFFFFC000007F FFFFC02A437DC231>52 D<000007FC0000003FFF000000FFFFC00003FC03E00007E000F0 001FC00038003F000058007E0001FC00FE0003FC00FC0007FC01F80007FC03F00007FC03 F00007FC07E00003F80FE00001F00FE00000001FC00000001FC00000001FC00000003F80 0000003F800000003F800000007F800000007F800000007F007F80007F01FFF0007F0780 FC00FF0E003E00FF1C001F80FF38000FC0FF700007E0FF600007E0FFE00003F0FFC00003 F8FFC00001F8FFC00001FCFF800001FCFF800000FEFF800000FEFF800000FEFF000000FF FF000000FFFF000000FFFF000000FF7F000000FF7F000000FF7F000000FF7F000000FF7F 000000FF7F800000FF3F800000FF3F800000FF3F800000FE1F800000FE1F800001FE1FC0 0001FC0FC00001FC0FC00003F807E00003F807E00007F003F00007E001F8000FC000FC00 1F80007E003F00003F80FE00000FFFF8000003FFE0000000FF800028447CC131>54 D<0000FF00000007FFE000001FFFF800007F00FE0000FC003F0001F0001F8003E0000FC0 03C00007E007C00003F00F800001F00F800001F00F000001F81F000000F81F000000F81F 000000F81F000000F81F800000F81F800000F81FC00001F81FC00001F01FE00001F00FF0 0003E00FFC0003E007FE0007C007FF800F8003FFC01F0001FFF03E0001FFF87800007FFE F000003FFFC000001FFFC0000007FFE0000003FFF8000007FFFC00001E7FFF00007C1FFF 8000F80FFFC001E003FFE003C001FFF007C0007FF80F80003FFC1F00000FFC3E000007FE 3E000001FE7C000000FE7C000000FF7C0000007FF80000003FF80000003FF80000001FF8 0000001FF80000001FF80000001FF80000001FFC0000001E7C0000003E7C0000003E7E00 00003C3E0000007C1F000000F81F800001F00FC00003E007E00007C003F8001F8000FF00 FF00003FFFFC00000FFFF0000001FF800028447CC131>56 D<7FFFFFFFFFFFFFFF00FFFF FFFFFFFFFFFF80FFFFFFFFFFFFFFFF807FFFFFFFFFFFFFFF000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000007FFFFFFFFFFFFFFF00FFFF FFFFFFFFFFFF80FFFFFFFFFFFFFFFF807FFFFFFFFFFFFFFF0041187BA44C>61 D E /Fb 134[60 60 60 60 60 60 60 60 1[60 60 60 60 60 60 1[60 60 60 60 60 60 60 60 60 10[60 1[60 4[60 1[60 3[60 1[60 12[60 3[60 60 5[60 60 1[60 1[60 2[60 5[60 33[{ TeXBase1Encoding ReEncodeFont }38 100.000003 /Courier rf /Fc 1 16 df<0001FF0000000FFFE000003FFFF800007FFFFC0001FFFFFF0003FFFF FF8007FFFFFFC00FFFFFFFE01FFFFFFFF01FFFFFFFF03FFFFFFFF87FFFFFFFFC7FFFFFFF FC7FFFFFFFFCFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFE FFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFE7FFFFFFFFC7FFFFFFFFC7FFFFFFFFC3F FFFFFFF81FFFFFFFF01FFFFFFFF00FFFFFFFE007FFFFFFC003FFFFFF8001FFFFFF00007F FFFC00003FFFF800000FFFE0000001FF000027267BAB32>15 D E /Fd 4 88 df<0000000018000000003C000000007C000000007C000000007800000000F8 00000000F800000000F000000001F000000001F000000001E000000003E000000003E000 000003C000000007C000000007C000000007800000000F800000000F800000001F000000 001F000000001E000000003E000000003E000000003C000000007C000000007C00000000 7800000000F800000000F800000000F000000001F000000001F000000003E000000003E0 00000003C000000007C000000007C000000007800000000F800000000F800000000F0000 00001F000000001F000000001E000000003E000000003E000000003C000000007C000000 007C00000000F800000000F800000000F000000001F000000001F000000001E000000003 E000000003E000000003C000000007C000000007C000000007800000000F800000000F80 0000000F000000001F000000001F000000003E000000003E000000003C000000007C0000 00007C000000007800000000F800000000F800000000F000000001F000000001F0000000 01E000000003E000000003E000000007C000000007C000000007800000000F800000000F 800000000F000000001F000000001F000000001E000000003E000000003E000000003C00 0000007C000000007C000000007800000000F800000000F800000000F000000000600000 000026647BCA31>61 D<7000000000000000FC00000000000000FF000000000000007FC0 0000000000001FF000000000000007FC00000000000001FF000000000000007FC0000000 0000001FF000000000000007FE00000000000001FF800000000000007FE0000000000000 1FF800000000000003FE00000000000000FF800000000000003FE00000000000000FF800 000000000003FF00000000000000FFC00000000000003FF00000000000000FFC00000000 000001FF000000000000007FC00000000000001FF000000000000007FC00000000000001 FF000000000000007FC00000000000001FE00000000000001FE00000000000007FC00000 00000001FF00000000000007FC0000000000001FF00000000000007FC0000000000001FF 0000000000000FFC0000000000003FF0000000000000FFC0000000000003FF0000000000 000FF80000000000003FE0000000000000FF80000000000003FE0000000000001FF80000 000000007FE0000000000001FF80000000000007FE0000000000001FF00000000000007F C0000000000001FF00000000000007FC0000000000001FF00000000000007FC000000000 0000FF00000000000000FC0000000000000070000000000000003B3878B44C>I<0000FF FFFFF800000000FFFFFFF800000000FFFFFFF80000000000FFE00000000000007FC00000 00000000FF80000000000000FF80000000000000FF00000000000000FF00000000000000 FF00000000000001FF00000000000001FE00000000000001FE00000000000001FE000000 00000003FE00000000000003FC00000000000003FC00000000000003FC00000000000007 FC00000000000007F800000000000007F800000000000007F80000000000000FF8000000 0000000FF00000000000000FF00000000000000FF00000000000001FF00000000000001F E00000000000001FE00000000000001FE00000000000003FE00000000000003FC0000000 0000003FC00000000000003FC00000000000007FC00000000000007F800000000000007F 800000000000007F80000000000000FF80000000000000FF00000000000000FF00000000 000000FF00000000000001FF00000000000001FE00000000C00001FE00000000C00001FE 00000001C00003FE00000001800003FC00000003800003FC00000003000003FC00000003 000007FC00000007000007F800000006000007F80000000E000007F80000001E00000FF8 0000001C00000FF00000003C00000FF00000003800000FF00000007800001FF0000000F8 00001FE0000001F000001FE0000003F000003FE000000FF000003FE000001FE000003FC0 0000FFE00000FFC00007FFC000FFFFFFFFFFFFC000FFFFFFFFFFFFC000FFFFFFFFFFFF80 003A447CC342>76 D87 D E /Fe 103[33 30[50 50 72 50 55 33 39 44 55 55 50 55 83 28 55 33 28 55 50 33 44 55 44 55 50 3[33 1[33 4[72 72 66 55 72 1[61 78 72 94 3[39 1[78 61 66 72 72 66 72 93 2[57 1[33 33 50 50 50 50 50 50 50 50 50 50 28 25 33 25 1[50 33 33 4[50 1[33 33[{ TeXBase1Encoding ReEncodeFont }68 100.000003 /Times-Bold rf /Ff 138[66 40 47 53 1[66 60 66 100 33 2[33 66 60 1[53 66 53 1[60 12[80 1[86 3[86 113 80 8[86 8[40 4[60 60 60 60 60 2[30 43[66 2[{ TeXBase1Encoding ReEncodeFont }30 119.999948 /Times-Bold rf /Fg 105[50 1[44 44 24[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 7[72 1[94 72 72 61 55 66 1[55 72 72 89 61 2[33 72 72 55 61 72 66 66 72 5[28 28 50 50 50 50 50 50 50 50 50 50 28 25 33 25 2[33 33 33 1[83 50 50 1[33 29[55 55 2[{ TeXBase1Encoding ReEncodeFont }75 100.000003 /Times-Roman rf /Fh 134[44 44 66 44 50 28 39 39 1[50 50 50 72 28 44 1[28 50 50 28 44 50 44 50 50 9[83 1[72 1[50 61 2[72 66 8[61 1[66 16[50 50 2[25 1[25 2[33 33 4[50 31[50 3[{ TeXBase1Encoding ReEncodeFont }39 100.000003 /Times-Italic rf /Fi 134[72 72 1[72 80 48 56 64 2[72 80 120 40 80 1[40 1[72 1[64 80 64 80 72 9[143 2[96 6[135 96 2[56 2[88 96 104 104 96 104 6[48 1[72 72 72 72 72 72 72 72 13[72 35[{ TeXBase1Encoding ReEncodeFont }40 143.999997 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 794 101 a Fi(Magic)35 b(T)-13 b(utorial)34 b(#8:)44 b(Cir)m(cuit)34 b(Extraction)1707 521 y Fh(W)-9 b(alter)24 b(Scott)1460 941 y Fg(Special)h(Studies)g(Program)1116 1062 y(La)o(wrence)g(Li)n(v)o(ermore)e(National)h(Laboratory)1538 1182 y(P)-11 b(.O.)25 b(Box)g(808,)f(L-270)1511 1303 y(Li)n(v)o(ermore,)f(CA)i(94550)1448 1573 y Fh(\(Updated)f(by)h(other)o (s,)f(too.\))1053 1843 y Fg(This)g(tutorial)g(corresponds)g(to)g(Magic) h(v)o(ersion)e(7.)0 2434 y Ff(T)-11 b(utorials)30 b(to)f(r)n(ead)h (\002rst:)300 2700 y Fg(Magic)24 b(T)l(utorial)g(#1:)30 b(Getting)24 b(Started)300 2820 y(Magic)g(T)l(utorial)g(#2:)30 b(Basic)25 b(P)o(ainting)f(and)h(Selection)300 2941 y(Magic)f(T)l (utorial)g(#4:)30 b(Cell)25 b(Hierarchies)0 3196 y Ff(Commands)k(intr)n (oduced)j(in)f(this)f(tutorial:)300 3462 y Fg(:e)o(xtract)0 3717 y Ff(Macr)n(os)f(intr)n(oduced)i(in)g(this)f(tutorial:)0 4029 y Fh(\(none\))146 4330 y Fe(Changes)c(since)f(Magic)f(v)o(ersion)h (4:)300 4642 y Fg(Ne)n(w)g(form)f(of)h Fe(:extract)h(unique)300 4762 y Fg(P)o(ath)f(length)f(e)o(xtraction)f(with)h Fe(:extract)i (length)300 4882 y Fg(Accurate)f(resistance)g(e)o(xtraction)f(with)g Fe(:extr)n(esis)300 5003 y Fg(Extraction)g(of)h(well)f(connecti)n(vity) f(and)i(substrate)f(nodes)300 5123 y(Checking)h(for)g(global)f(net)g (connectedness)h(in)f Fh(e)n(xt2sim)g Fg(\(1\))300 5244 y(Ne)n(w)h(programs:)k Fh(e)n(xt2spice)c Fg(\(1\))g(and)g Fh(e)n(xtc)o(hec)n(k)g Fg(\(1\))1875 5649 y(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Fg(September)25 b(26,)f(2001)1604 b(Magic)25 b(T)l(utorial)e(#8:)30 b(Circuit)25 b(Extraction)0 99 y Fi(1)143 b(Intr)m(oduction)0 322 y Fg(This)29 b(tutorial)g(co)o(v)o (ers)h(the)f(use)h(of)h(Magic')-5 b(s)29 b(circuit)h(e)o(xtractor)-5 b(.)45 b(The)30 b(e)o(xtractor)g(computes)f(from)h(the)g(layout)0 443 y(the)e(information)e(needed)i(to)g(run)g(simulation)e(tools)g (such)i(as)g Fh(crystal)f Fg(\(1\))h(and)g Fh(esim)g Fg(\(1\).)40 b(This)28 b(information)0 563 y(includes)f(the)h(sizes)f (and)h(shapes)f(of)h(transistors,)f(and)h(the)g(connecti)n(vity)-6 b(,)26 b(resistance,)i(and)g(parasitic)f(capaci-)0 683 y(tance)21 b(of)g(nodes.)29 b(Both)21 b(capacitance)h(to)e(substrate)h (and)g(se)n(v)o(eral)f(kinds)g(of)h(internodal)f(coupling)g (capacitances)0 804 y(are)26 b(e)o(xtracted.)146 924 y(Magic')-5 b(s)29 b(e)o(xtractor)g(is)g(both)g(incremental)f(and)i (hierarchical:)40 b(only)28 b(part)i(of)f(the)h(entire)f(layout)g(must) f(be)0 1045 y(re-e)o(xtracted)j(after)f(each)h(change,)h(and)e(the)g (structure)g(of)g(the)g(e)o(xtracted)g(circuit)g(parallels)g(the)g (structure)g(of)0 1165 y(the)38 b(layout)g(being)f(e)o(xtracted.)71 b(The)38 b(e)o(xtractor)g(produces)g(a)h(separate)g Fe(.ext)f Fg(\002le)h(for)f(each)h Fe(.mag)f Fg(\002le)h(in)f(a)0 1285 y(hierarchical)31 b(design.)47 b(This)30 b(is)g(in)g(contrast)g (to)g(pre)n(vious)g(e)o(xtractors,)h(such)f(as)h(Me)o(xtra,)g(which)f (produces)h(a)0 1406 y(single)24 b Fe(.sim)g Fg(\002le)h(that)g (represents)g(the)f(\003attened)h(\(fully-instantiated\))e(layout.)146 1526 y(Sections)36 b(2)h(through)e(4)i(introduce)e(Magic')-5 b(s)36 b Fe(:extract)h Fg(command)f(and)g(some)g(of)g(its)g(more)g(adv) n(anced)0 1647 y(features.)52 b(Section)31 b(5)h(describes)f(what)h (information)e(actually)h(gets)g(e)o(xtracted,)j(and)d(discusses)g (limitations)0 1767 y(and)c(inaccuracies.)36 b(Section)27 b(6)g(talks)f(about)g(e)o(xtraction)f(styles.)36 b(Although)25 b(the)h(hierarchical)i Fh(e)n(xt)e Fg(\(5\))h(format)0 1887 y(fully)19 b(describes)h(the)f(circuit)h(implemented)e(by)i(a)g (layout,)g(v)o(ery)f(fe)n(w)h(tools)f(currently)g(accept)i(it.)28 b(It)20 b(is)f(normally)0 2008 y(necessary)26 b(to)f(\003atten)g(the)g (e)o(xtracted)g(circuit)g(using)g(one)g(of)g(the)g(programs)g (discussed)f(in)h(Section)h(7,)f(such)g(as)0 2128 y Fh(e)n(xt2sim)f Fg(\(1\),)h Fh(e)n(xt2spice)g Fg(\(1\),)g(or)g Fh(e)n(xtc)o(hec)n(k)g Fg(\(1\).)0 2465 y Fi(2)143 b(Basic)35 b(Extraction)0 2688 y Fg(Y)-11 b(ou)29 b(can)h(use)f(Magic')-5 b(s)29 b(e)o(xtractor)g(in)g(one)h(of)f(se)n(v)o(eral)g(w)o(ays.)45 b(Normally)28 b(it)h(is)g(not)g(necessary)h(to)f(e)o(xtract)g(all)0 2808 y(cells)c(in)f(a)h(layout.)30 b(T)-8 b(o)25 b(e)o(xtract)f(only)g (those)g(cells)h(that)f(ha)n(v)o(e)h(changed)g(since)f(the)o(y)g(were)i (e)o(xtracted,)e(use:)900 3014 y Fe(:load)h Fh(r)l(oot)900 3134 y Fe(:extract)146 3339 y Fg(The)f(e)o(xtractor)f(looks)f(for)i(a)g Fe(.ext)g Fg(\002le)g(for)f(e)n(v)o(ery)g(cell)h(in)f(the)g(tree)h (that)f(descends)g(from)g(the)h(cell)f Fh(r)l(oot)p Fg(.)29 b(The)0 3460 y Fe(.ext)d Fg(\002le)f(is)g(searched)h(for)g(in)f(the)g (same)g(directory)h(that)e(contains)h(the)g(cell')-5 b(s)25 b Fe(.mag)g Fg(\002le.)33 b(An)o(y)24 b(cells)h(that)g(ha)n(v)o (e)0 3580 y(been)e(modi\002ed)e(since)i(the)o(y)e(were)i(last)f(e)o (xtracted,)h(and)f(all)g(of)g(their)h(parents,)f(are)h(re-e)o (xtracted.)30 b(Cells)23 b(ha)n(ving)0 3701 y(no)i Fe(.ext)g Fg(\002les)g(are)g(also)f(re-e)o(xtracted.)146 3821 y(T)-8 b(o)29 b(try)g(out)f(the)g(e)o(xtractor)h(on)f(an)h(e)o(xample,)g(cop)o (y)g(all)f(the)h Fe(tut8)p Fh(x)h Fg(cells)e(to)h(your)f(current)h (directory)g(with)0 3941 y(the)c(follo)n(wing)e(shell)h(commands:)900 4147 y Fe(cp)i(\230cad/lib/magic/tutorial/tut8*.mag)48 b(.)146 4352 y Fg(Start)26 b(magic)f(on)g(the)g(cell)g Fe(tut8a)h Fg(and)f(type)g Fe(:extract)p Fg(.)34 b(Magic)25 b(will)f(print)h(the)g(name)g(of)g(each)h(cell)g(\()p Fe(tut8a)p Fg(,)0 4472 y Fe(tut8b)p Fg(,)33 b Fe(tut8c)p Fg(,)g(and)e Fe(tut8d)p Fg(\))h(as)f(it)f(is)h(e)o(xtracted.)48 b(No)n(w)30 b(type)h Fe(:extract)h Fg(a)f(second)f(time.)48 b(This)30 b(time)h(nothing)0 4593 y(gets)25 b(printed,)f(since)h(Magic) f(didn')n(t)h(ha)n(v)o(e)f(to)h(re-e)o(xtract)g(an)o(y)g(cells.)31 b(No)n(w)24 b(delete)h(the)g(piece)g(of)g(poly)g(labelled)0 4713 y(\223)p Fe(delete)32 b(me)p Fg(\224)f(and)f(type)h Fe(:extract)g Fg(again.)48 b(This)29 b(time,)j(only)d(the)i(cell)f Fe(tut8a)h Fg(is)f(e)o(xtracted)h(as)f(it)g(is)g(the)h(only)0 4834 y(one)23 b(that)g(changed.)30 b(If)24 b(you)e(mak)o(e)i(a)f (change)h(to)e(cell)i Fe(tut8b)g Fg(\(do)f(it\))g(and)g(then)g(e)o (xtract)g(again,)f(both)h Fe(tut8b)h Fg(and)0 4954 y Fe(tut8a)h Fg(will)f(be)h(re-e)o(xtracted,)g(since)g Fe(tut8a)g Fg(is)f(the)h(parent)g(of)g Fe(tut8b)p Fg(.)146 5074 y(T)-8 b(o)25 b(force)g(all)g(cells)g(in)f(the)h(subtree)f(rooted) h(at)g(cell)f Fh(r)l(oot)g Fg(to)g(be)h(re-e)o(xtracted,)g(use)g Fe(:extract)h(all)p Fg(:)900 5280 y Fe(:load)p Fh(r)l(oot)900 5400 y Fe(:extract)g(all)1875 5649 y Fg(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Fg(Magic)24 b(T)l(utorial)g(#8:)30 b(Circuit)25 b(Extraction)1603 b(September)25 b(26,)g(2001)146 69 y(T)m(ry)g(this)e(also)i(on)f Fe(tut8a)p Fg(.)146 189 y(Y)-11 b(ou)25 b(can)g(also)f(use)h(the)g Fe(:extract)h Fg(command)d(to)i(e)o(xtract)f(a)h(single)f(cell)h(as)g(follo)n(ws:)900 422 y Fe(:extract)h(cell)f Fh(name)146 653 y Fg(will)33 b(e)o(xtract)g(just)g(the)g(selected)g(\(current\))h(cell,)i(and)d (place)h(the)f(output)f(in)i(the)f(\002le)h Fh(name)p Fg(.)56 b(Select)34 b(the)0 774 y(cell)29 b Fe(tut8b)h Fg(\()p Fe(tut8b)p 694 774 30 4 v 37 w(0)p Fg(\))f(and)g(type)g Fe(:extract)h(cell)e(differ)n(entFile)j Fg(to)e(try)f(this)g(out.)43 b(After)29 b(this)f(command,)h(the)0 894 y(\002le)24 b Fe(differ)n(entFile.ext)i Fg(will)d(contain)g(the)h(e)o(xtracted)g (circuit)f(for)i(the)e(cell)h Fe(tut8b)p Fg(.)32 b(The)24 b(children)f(of)h Fe(tut8b)h Fg(\(in)0 1014 y(this)g(case,)j(the)e (single)g(cell)g Fe(tut8d)p Fg(\))i(will)d(not)h(be)h(re-e)o(xtracted)f (by)g(this)g(command.)35 b(If)26 b(more)h(than)f(one)g(cell)h(is)0 1135 y(selected,)e(the)f(upper)n(-leftmost)g(one)h(is)f(e)o(xtracted.) 146 1256 y(Y)-11 b(ou)19 b(should)g(be)g(careful)h(about)f(using)g Fe(:extract)h(cell)p Fg(,)h(since)e(e)n(v)o(en)g(though)f(you)h(may)g (only)g(mak)o(e)g(a)h(change)0 1376 y(to)26 b(a)h(child)e(cell,)i(all)f (of)h(its)e(parents)i(may)f(ha)n(v)o(e)g(to)g(be)g(re-e)o(xtracted.)36 b(T)-8 b(o)26 b(re-e)o(xtract)h(all)f(of)g(the)h(parents)f(of)g(the)0 1496 y(selected)f(cell,)f(you)h(may)f(use)900 1728 y Fe(:extract)i(par)n(ents)146 1960 y Fg(T)m(ry)e(this)g(out)g(with)g Fe(tut8b)h Fg(still)e(selected.)31 b(Magic)24 b(will)g(e)o(xtract)g (only)f(the)i(cell)f Fe(tut8a)p Fg(,)h(since)f(it)g(is)h(the)f(only)0 2081 y(one)33 b(that)f(uses)h(the)g(cell)g Fe(tut8b)p Fg(.)56 b(T)-8 b(o)32 b(see)i(what)e(cells)h(w)o(ould)f(be)h(e)o (xtracted)g(by)f Fe(:extract)i(par)n(ents)h Fg(without)0 2201 y(actually)24 b(e)o(xtracting)g(them,)g(use)900 2433 y Fe(:extract)i(sho)o(wpar)n(ents)146 2665 y Fg(T)m(ry)f(this)e (command)h(as)h(well.)0 3007 y Fi(3)143 b(F)l(eedback:)43 b(Err)m(ors)34 b(and)h(W)-9 b(ar)n(nings)0 3232 y Fg(When)22 b(the)g(e)o(xtractor)g(encounters)g(problems,)f(it)h(lea)n(v)o(es)f (feedback)i(in)f(the)g(form)f(of)i(stippled)d(white)i(rectangu-)0 3352 y(lar)k(areas)h(on)e(the)h(screen.)34 b(Each)27 b(area)f(co)o(v)o(ers)f(the)h(portion)f(of)h(the)g(layout)f(that)g (caused)h(the)g(error)-5 b(.)34 b(Each)26 b(area)0 3472 y(also)e(has)g(an)g(error)g(message)g(associated)g(with)f(it,)g(which)h (you)g(can)g(see)g(by)g(using)f(the)h Fe(:feedback)i Fg(command.)0 3593 y(T)-8 b(ype)25 b Fe(:feedback)i(help)e Fg(while)g(in)f(Magic)g(for)h(assistance)g(in)f(using)g(the)h Fe(:feedback)i Fg(command.)146 3714 y(The)i(e)o(xtractor)f(will)g(al)o (w)o(ays)g(report)g(e)o(xtraction)g Fh(err)l(or)o(s)p Fg(.)40 b(These)29 b(are)g(problems)e(in)h(the)h(layout)e(that)h(may)0 3834 y(cause)c(the)g(output)e(of)i(the)f(e)o(xtractor)h(to)f(be)h (incorrect.)31 b(The)23 b(layout)g(should)g(be)h(\002x)o(ed)f(to)g (eliminate)g(e)o(xtraction)0 3954 y(errors)32 b(before)g(attempting)e (to)h(simulate)g(the)g(circuit;)k(otherwise,)d(the)g(results)f(of)g (the)h(simulation)d(may)j(not)0 4075 y(re\003ect)26 b(reality)-6 b(.)146 4196 y(Extraction)30 b(errors)i(can)f(come)g(from)g(violations) e(of)i(transistor)f(rules.)49 b(There)32 b(are)f(tw)o(o)g(rules)g (about)f(the)0 4316 y(formation)j(of)g(transistors:)47 b(no)33 b(transistor)g(can)h(be)g(formed,)h(and)f(none)f(can)h(be)g (destro)o(yed,)h(as)f(a)g(result)f(of)0 4436 y(cell)d(o)o(v)o(erlaps.) 44 b(F)o(or)30 b(e)o(xample,)h(it)e(is)g(ille)o(gal)f(to)i(ha)n(v)o(e)g (poly)f(in)g(one)h(cell)g(o)o(v)o(erlap)f(dif)n(fusion)f(in)h(another)h (cell,)0 4557 y(as)36 b(that)f(w)o(ould)f(form)h(a)h(transistor)f(in)g (the)g(parent)h(where)f(none)h(w)o(as)f(present)h(in)f(either)g(child.) 62 b(It)35 b(is)h(also)0 4677 y(ille)o(gal)23 b(to)h(ha)n(v)o(e)g(a)h (b)n(uried)f(contact)h(in)f(one)g(cell)h(o)o(v)o(erlap)e(a)i (transistor)f(in)g(another)l(,)g(as)h(this)f(w)o(ould)f(destro)o(y)h (the)0 4798 y(transistor)-5 b(.)53 b(V)-6 b(iolating)32 b(these)h(transistor)e(rules)i(will)f(cause)h(design-rule)g(violations) e(as)i(well)f(as)h(e)o(xtraction)0 4918 y(errors.)48 b(These)31 b(errors)g(only)f(relate)h(to)f(circuit)g(e)o(xtraction:)41 b(the)30 b(f)o(abricated)h(circuit)g(may)f(still)f(w)o(ork;)k(it)d (just)0 5038 y(w)o(on')n(t)25 b(be)f(e)o(xtracted)h(correctly)-6 b(.)146 5159 y(In)28 b(general,)h(it)e(is)h(an)g(error)g(for)h (material)e(of)h(tw)o(o)f(types)h(on)f(the)h(same)g(plane)f(to)h(o)o(v) o(erlap)f(or)h(ab)n(ut)f(if)h(the)o(y)0 5280 y(don')n(t)f(connect)g(to) h(each)g(other)-5 b(.)38 b(F)o(or)27 b(e)o(xample,)g(in)g(CMOS)h(it)f (is)g(ille)o(gal)f(for)h(p-dif)n(fusion)f(and)i(n-dif)n(fusion)d(to)0 5400 y(o)o(v)o(erlap)f(or)h(ab)n(ut.)1875 5649 y(\2263\226)p eop %%Page: 4 4 4 3 bop 0 -180 a Fg(September)25 b(26,)f(2001)1604 b(Magic)25 b(T)l(utorial)e(#8:)30 b(Circuit)25 b(Extraction)146 68 y(In)20 b(addition)e(to)h(errors,)i(the)f(e)o(xtractor)f(can)h(gi)n (v)o(e)e Fh(warnings)p Fg(.)28 b(If)20 b(only)f(w)o(arnings)f(are)j (present,)f(the)f(e)o(xtracted)0 188 y(circuit)26 b(can)h(still)e(be)i (simulated.)35 b(By)27 b(def)o(ault,)f(only)g(some)g(types)g(of)h(w)o (arnings)f(are)h(reported)g(and)f(displayed)0 309 y(as)f(feedback.)31 b(T)-8 b(o)25 b(cause)g(all)g(w)o(arnings)f(to)g(be)h(displayed,)f(use) 900 541 y Fe(:extract)i(war)o(n)f(all)146 773 y Fg(The)g(command)900 1005 y Fe(:extract)h(war)o(n)f Fh(warning)146 1237 y Fg(may)32 b(be)g(used)g(to)f(enable)h(speci\002c)g(w)o(arnings)g (selecti)n(v)o(ely;)h(see)f(belo)n(w)-6 b(.)51 b(T)-8 b(o)31 b(cause)i(no)e(w)o(arnings)g(to)h(be)0 1358 y(displayed,)24 b(or)h(to)f(disable)g(display)g(of)h(a)g(particular)g Fh(warning)p Fg(,)f(use)g(respecti)n(v)o(ely)900 1590 y Fe(:extract)i(war)o(n)f(no)g(all)f Fg(or)900 1710 y Fe(:extract)i(war)o(n)f(no)g Fh(warning)146 1942 y Fg(Three)j(dif)n (ferent)f(kinds)f(of)h(w)o(arnings)f(are)i(generated.)38 b(The)27 b Fe(dup)h Fg(w)o(arning)f(checks)g(to)g(see)g(whether)h(you)0 2063 y(ha)n(v)o(e)f(tw)o(o)g(electrically)g(unconnected)g(nodes)g(in)g (the)g(same)g(cell)h(labelled)f(with)f(the)i(same)f(name.)38 b(If)28 b(so,)g(you)0 2183 y(are)k(w)o(arned)f(because)h(the)f(tw)o(o)g (unconnected)f(nodes)h(will)f(appear)i(to)f(be)g(connected)g(in)g(the)g (resulting)f Fe(.ext)0 2304 y Fg(\002le,)k(which)e(means)g(that)f(the)h (e)o(xtracted)g(circuit)g(w)o(ould)f(not)h(represent)g(the)g(actual)g (layout.)52 b(This)31 b(is)h(bad)g(if)0 2424 y(you')-5 b(re)25 b(simulating)d(the)j(circuit)f(to)g(see)h(if)f(it)h(will)e(w)o (ork)i(correctly:)30 b(the)25 b(simulator)e(will)g(think)h(the)g(tw)o (o)h(nodes)0 2544 y(are)32 b(connected,)g(b)n(ut)f(since)g(there')-5 b(s)31 b(no)g(physical)e(wire)j(between)f(them,)h(the)f(electrons)g(w)o (on')n(t!)49 b(When)32 b(tw)o(o)0 2665 y(unconnected)e(nodes)f(share)h (the)g(same)g(label)g(\(name\),)h(the)f(e)o(xtractor)f(lea)n(v)o(es)h (feedback)h(squares)e(o)o(v)o(er)g(each)0 2785 y(instance)24 b(of)h(the)g(shared)g(name.)146 2906 y(It')-5 b(s)36 b(an)g(e)o(xcellent)f(idea)h(to)g(a)n(v)n(oid)g(labelling)e(tw)o(o)i (unconnected)g(nodes)f(with)h(the)g(same)f(name)h(within)0 3026 y(a)e(cell.)57 b(Instead,)36 b(use)e(the)f(\224correct\224)i(name) f(for)g(one)g(of)f(the)h(nodes,)h(and)f(some)f(mnemonic)g(b)n(ut)g(te)o (xtually)0 3147 y(distinct)25 b(name)h(for)h(the)f(other)g(nodes.)35 b(F)o(or)27 b(e)o(xample,)f(in)g(a)g(cell)h(with)e(multiple)g(po)n(wer) h(rails,)g(you)g(might)f(use)0 3267 y Fe(Vdd!)62 b Fg(for)35 b(one)f(of)h(the)g(rails,)i(and)e(names)f(lik)o(e)g Fe(Vdd#1)h Fg(for)g(the)g(others.)60 b(As)35 b(an)g(e)o(xample,)h(load)f(the)f (cell)0 3387 y Fe(tut8e)p Fg(.)44 b(If)30 b(the)f(tw)o(o)f(nodes)h(are) h(connected)f(in)f(a)i(higher)n(-le)n(v)o(el)d(cell)i(the)o(y)g(will)f (e)n(v)o(entually)f(be)i(mer)n(ged)g(when)0 3508 y(the)j(e)o(xtracted)f (circuit)h(is)f(\003attened.)52 b(If)33 b(you)e(w)o(ant)h(to)f (simulate)g(a)h(cell)g(out)f(of)h(conte)o(xt,)h(b)n(ut)e(still)g(w)o (ant)g(the)0 3628 y(higher)n(-le)n(v)o(el)d(nodes)h(to)g(be)h(hook)o (ed)f(up,)h(you)f(can)h(al)o(w)o(ays)g(create)g(a)g(dummy)e(parent)i (cell)f(that)g(hooks)g(them)0 3749 y(together)l(,)d(either)f(with)h (wire)g(or)g(by)f(using)g(the)h(same)f(name)h(for)g(pieces)g(of)g (paint)f(that)h(lie)f(o)o(v)o(er)g(the)h(terminals)0 3869 y(to)e(be)h(connected;)g(see)g(the)g(cell)f Fe(tut8f)i Fg(for)f(an)g(e)o(xample)f(of)h(this)f(latter)g(technique.)146 3990 y(Y)-11 b(ou)25 b(can)g(use)g(the)f(command)900 4222 y Fe(:extract)i(unique)146 4454 y Fg(as)j(an)h(automatic)e(means)g (of)i(labelling)d(nodes)i(in)g(the)f(manner)h(described)g(abo)o(v)o(e.) 43 b(Run)29 b(this)f(command)0 4575 y(on)g(the)h(cell)f Fe(tut8g)p Fg(.)43 b(A)28 b(second)h(v)o(ersion)e(of)i(this)f(command)f (is)h(pro)o(vided)g(for)g(compatibility)f(with)g(pre)n(vious)0 4695 y(v)o(ersions)c(of)i(Magic.)31 b(Running)900 4927 y Fe(:extract)26 b(unique)g(#)146 5159 y Fg(will)32 b(only)f(append)h (a)h(unique)f(numeric)g(suf)n(\002x)f(to)h(labels)g(that)g(end)g(with)g (a)h(\223)p Fe(#)p Fg(\224.)53 b(An)o(y)32 b(other)g(duplicate)0 5280 y(nodenames)26 b(that)g(also)g(don')n(t)g(end)h(in)f(a)h(\223)p Fe(!)p Fg(\224)37 b(\(the)26 b(global)g(nodename)g(suf)n(\002x)g(as)h (described)f(in)g(Section)h(5\))f(are)0 5400 y(\003agged)f(by)g (feedback.)1875 5649 y(\2264\226)p eop %%Page: 5 5 5 4 bop 0 -180 a Fg(Magic)24 b(T)l(utorial)g(#8:)30 b(Circuit)25 b(Extraction)1603 b(September)25 b(26,)g(2001)146 69 y(A)36 b(second)g(type)g(of)g(w)o(arning,)i Fe(fets)p Fg(,)h(checks)e(to)e(see)h(whether)h(an)o(y)e(transistors)g(ha)n(v)o(e) g(fe)n(wer)i(dif)n(fusion)0 189 y(terminals)19 b(than)i(the)f(minimum)e (for)j(their)f(types.)29 b(F)o(or)20 b(e)o(xample,)g(the)h(transistor)e (type)h(\223)p Fe(dfet)p Fg(\224)i(is)e(de\002ned)h(in)f(the)0 309 y Fe(nmos)j Fg(technology)e(\002le)i(as)f(requiring)g(tw)o(o)g(dif) n(fusion)f(terminals:)28 b(a)23 b(source)f(and)h(a)g(drain.)29 b(If)23 b(a)g(capacitor)g(with)0 430 y(only)d(one)i(dif)n(fusion)d (terminal)i(is)f(desired)h(in)g(this)g(technology)-6 b(,)20 b(the)h(type)g Fe(dcap)h Fg(should)e(be)h(used)g(instead.)29 b(The)0 550 y Fe(fets)20 b Fg(w)o(arning)f(is)g(a)h(consistenc)o(y)e (check)j(for)e(transistors)g(whose)g(dif)n(fusion)f(terminals)g(ha)n(v) o(e)i(been)g(accidentally)0 671 y(shorted)k(together)l(,)h(or)f(for)h (transistors)f(with)g(insuf)n(\002ciently)f(man)o(y)h(dif)n(fusion)f (terminals.)146 791 y(The)k(third)e(w)o(arning,)h Fe(labels)p Fg(,)h(is)f(generated)g(if)g(you)g(violate)g(the)g(follo)n(wing)e (guideline)i(for)g(placement)g(of)0 911 y(labels:)k(Whene)n(v)o(er)24 b(geometry)h(from)f(tw)o(o)h(subcells)f(ab)n(uts)g(or)h(o)o(v)o (erlaps,)e(it')-5 b(s)24 b(a)h(good)f(idea)h(to)g(mak)o(e)g(sure)g (that)0 1032 y(there)f(is)g(a)g(label)f(attached)h(to)g(the)f(geometry) h(in)f(each)i(subcell)e Fh(in)g(the)h(ar)l(ea)g(of)f(the)h(o)o(verlap)f (or)h(along)f(the)h(line)0 1152 y(of)h(ab)n(utment)p Fg(.)31 b(F)o(ollo)n(wing)23 b(this)i(guideline)f(isn')n(t)h(necessary) h(for)f(the)g(e)o(xtractor)g(to)g(w)o(ork,)h(b)n(ut)e(it)h(will)g (result)f(in)0 1272 y(noticeably)g(f)o(aster)h(e)o(xtraction.)146 1393 y(By)g(def)o(ault,)g(the)g Fe(dup)h Fg(and)e Fe(fets)i Fg(w)o(arnings)e(are)h(enabled,)g(and)g(the)f Fe(labels)h Fg(w)o(arning)f(is)h(disabled.)146 1513 y(Load)f(the)h(cell)f Fe(tut8h)p Fg(,)h(e)o(xpand)f(all)g(its)f(children)h(\()p Fe(tut8i)h Fg(and)f Fe(tut8j)p Fg(\),)h(and)f(enable)h(all)f(e)o (xtractor)g(w)o(arnings)0 1634 y(with)k Fe(:extract)h(war)o(n)f(all)p Fg(.)41 b(No)n(w)28 b(e)o(xtract)g Fe(tut8h)i Fg(and)e(all)g(of)h(its)e (children)h(with)g Fe(:extract)p Fg(,)i(and)f(e)o(xamine)e(the)0 1754 y(feedback)e(for)h(e)o(xamples)d(of)i(f)o(atal)g(errors)g(and)g(w) o(arnings.)0 2087 y Fi(4)143 b(Adv)o(anced)33 b(Cir)m(cuit)i (Extraction)0 2339 y Ff(4.1)119 b(Lengths)0 2527 y Fg(The)33 b(Magic)g(e)o(xtractor)g(has)g(a)g(rudimentary)f(ability)g(to)h (compute)f(wire)i(lengths)e(between)h(speci\002c)g(named)0 2647 y(points)19 b(in)h(a)h(circuit.)29 b(This)20 b(feature)h(is)f (intended)g(for)h(use)f(with)g(technologies)f(where)i(the)g(wire)f (length)g(between)0 2768 y(tw)o(o)31 b(points)f(is)h(more)g(important)f (than)h(the)g(total)g(capacitance)h(on)f(the)g(net;)k(this)30 b(may)h(occur)l(,)i(for)f(e)o(xample,)0 2888 y(when)e(e)o(xtracting)g (circuits)g(with)f(v)o(ery)h(long)g(wires)h(being)e(dri)n(v)o(en)h(at)g (high)g(speeds)g(\()p Fh(e)o(.g)o(.)p Fg(,)h(bipolar)f(circuits\).)0 3008 y(Currently)-6 b(,)27 b(you)g(must)e(indicate)i(to)g(Magic)f (which)h(pairs)g(of)g(points)f(are)h(to)g(ha)n(v)o(e)g(distances)f (computed.)36 b(Y)-11 b(ou)0 3129 y(do)32 b(this)g(by)g(pro)o(viding)f (tw)o(o)h(lists:)45 b(one)33 b(of)f Fh(driver)o(s)g Fg(and)h(one)f(of)h Fh(r)l(eceiver)o(s)p Fg(.)55 b(The)32 b(e)o(xtractor)h(computes)e(the)0 3249 y(distance)24 b(between)h(each)h(dri)n(v)o(er)d(and)i(each)h (recei)n(v)o(er)e(that)h(it)f(is)g(connected)h(to.)146 3369 y(Load)h(the)f(cell)h Fe(tut8k)p Fg(.)34 b(There)27 b(are)f(\002)n(v)o(e)f(labels:)32 b(tw)o(o)25 b(are)i(dri)n(v)o(ers)d (\()p Fe(dri)o(v)o(er1)j Fg(and)e Fe(dri)o(v)o(er2)p Fg(\))i(and)e(three)h(are)0 3490 y(recei)n(v)o(ers)e(\()p Fe(r)n(ecei)o(v)o(erA)p Fg(,)j Fe(r)n(ecei)o(v)o(erB)p Fg(,)f(and)f Fe(r)n(ecei)o(v)o(erC)p Fg(\).)h(T)-8 b(ype)24 b(the)h(commands:)900 3666 y Fe(:extract)h(length)f(dri)o(v)o(er)h(dri) o(v)o(er1)f(dri)o(v)o(er2)900 3787 y(:extract)h(length)f(r)n(ecei)o(v)o (er)h(r)n(ecei)o(v)o(erA)g(r)n(ecei)o(v)o(erB)h(r)n(ecei)o(v)o(erC)146 3963 y Fg(No)n(w)g(enable)g(e)o(xtraction)f(of)h(lengths)f(with)h Fe(:extract)h(do)f(length)h Fg(and)f(then)g(e)o(xtract)g(the)g(cell)g (\()p Fe(:extract)p Fg(\).)0 4084 y(If)e(you)f(e)o(xamine)g Fe(tut8k.ext)p Fg(,)i(you)e(will)g(see)h(se)n(v)o(eral)e Fe(distance)j Fg(lines,)e(corresponding)f(to)i(the)f(dri)n(v)o(er)n (-recei)n(v)o(er)0 4204 y(distances)e(described)g(abo)o(v)o(e.)29 b(These)22 b(distances)g(are)h(through)e(the)h(centerlines)g(of)h (wires)f(connecting)f(the)i(tw)o(o)0 4325 y(labels;)h(where)h(multiple) e(paths)i(e)o(xist,)e(the)i(shortest)f(is)g(used.)146 4445 y(Normally)h(the)g(dri)n(v)o(er)g(and)g(recei)n(v)o(er)g(tables)g (will)g(be)g(b)n(uilt)g(by)g(using)f Fe(:sour)n(ce)j Fg(to)e(read)h(a)g(\002le)g(of)f Fe(:extract)0 4565 y(length)32 b(dri)o(v)o(er)f Fg(and)g Fe(:extract)h(length)f(r)n(ecei)o(v)o(er)h Fg(commands.)48 b(Once)31 b(these)g(tables)f(are)i(created)f(in)g (Magic,)0 4686 y(the)o(y)24 b(remain)h(until)e(you)h(lea)n(v)o(e)h (Magic)g(or)f(type)h(the)g(command)900 4862 y Fe(:extract)h(length)f (clear)146 5039 y Fg(which)g(wipes)f(out)g(both)g(tables.)146 5159 y(Because)e(e)o(xtraction)e(of)h(wire)h(lengths)d(is)i Fh(not)f Fg(performed)h(hierarchically)-6 b(,)21 b(it)g(should)f(only)g (be)h(done)g(in)f(the)0 5280 y(root)26 b(cell)h(of)g(a)g(design.)35 b(Also,)27 b(because)g(it')-5 b(s)26 b(not)g(hierarchical,)h(it)f(can)h (tak)o(e)g(a)g(long)f(time)g(for)h(long,)f(comple)o(x)0 5400 y(wires)f(such)f(as)h(po)n(wer)f(and)h(ground)f(nets.)31 b(This)24 b(feature)h(is)g(still)e(e)o(xperimental)h(and)g(subject)g (to)h(change.)1875 5649 y(\2265\226)p eop %%Page: 6 6 6 5 bop 0 -180 a Fg(September)25 b(26,)f(2001)1604 b(Magic)25 b(T)l(utorial)e(#8:)30 b(Circuit)25 b(Extraction)0 82 y Ff(4.2)119 b(Resistance)0 283 y Fg(Magic)34 b(pro)o(vides)f(for)h (more)g(accurate)h(resistance)f(e)o(xtraction)f(using)g(the)h Fe(:extr)n(esis)h Fg(command.)58 b Fe(:extr)n(esis)0 403 y Fg(pro)o(vides)28 b(a)i(detailed)g(resistance/capacitance)g (description)e(for)i(nets)g(where)g(parasitic)f(resistance)h(is)f(lik)o (ely)0 524 y(to)24 b(signi\002cantly)g(af)n(fect)h(circuit)g(timing.)0 829 y Fe(4.2.1)99 b(T)-9 b(utorial)25 b(Intr)n(oduction)0 1030 y Fg(T)-8 b(o)30 b(try)g(out)g(the)g(resistance)g(e)o(xtractor)l (,)h(load)f(in)g(the)g(cell)g Fe(tut8r)p Fg(.)48 b(Extract)30 b(it)g(using)f Fe(:extract)p Fg(,)j(pause)f(magic,)0 1150 y(and)25 b(run)f(e)o(xt2sim)f(on)i(the)g(cell)f(with)g(the)h (command)900 1428 y Fe(ext2sim)f(tut8r)146 1699 y Fg(This)g(should)g (produce)h Fe(tut8r)-10 b(.sim)p Fg(,)25 b Fe(tut8r)-10 b(.nodes)p Fg(,)26 b(and)f Fe(tut8r)-10 b(.al)p Fg(.)31 b(Restart)25 b(magic)f(and)h(type)900 1977 y Fe(:extr)n(esis)g (tolerance)h(10)900 2098 y(:extr)n(esis)146 2369 y Fg(This)32 b(will)f(e)o(xtract)h(interconnect)g(resistances)g(for)h(an)o(y)e(net)h (where)h(the)f(interconnect)g(delay)g(is)g(at)g(least)0 2489 y(one-tenth)24 b(of)h(the)g(transistor)e(delay)-6 b(.)31 b(Magic)24 b(should)g(gi)n(v)o(e)f(the)i(messages:)900 2767 y Fe(:extr)n(esis)g(tolerance)h(10)900 2888 y(:extr)n(esis)900 3008 y(Adding)g(net2;)f(Tnew)h(=)f(0.428038ns,T)-9 b(old)24 b(=)g(0.3798ns)900 3128 y(Adding)i(net1;)f(Tnew)h(=)f(0.529005ns,T)-9 b(old)24 b(=)g(0.4122ns)900 3249 y(T)-9 b(otal)25 b(Nets:)31 b(7)900 3369 y(Nets)25 b(extracted:)32 b(2)25 b(\(0.285714\))900 3490 y(Nets)g(output:)32 b(2)25 b(\(0.285714\))146 3761 y Fg(These)33 b(may)f(v)n(ary)g(slightly)e(depending)i(on)g(your)g (technology)f(parameters.)54 b(The)32 b Fe(Adding)h([net])h Fg(lines)0 3881 y(describe)39 b(which)f(netw)o(orks)f(for)i(which)f (magic)g(produced)g(resistor)g(netw)o(orks.)71 b Fe(Tnew)40 b Fg(is)e(the)g(estimated)0 4002 y(delay)30 b(on)g(the)g(net)g (including)f(the)h(resistor)f(parasitics,)i(while)f Fe(T)-9 b(old)30 b Fg(is)g(the)g(delay)g(without)f(parasitics.)46 b(The)0 4122 y(ne)o(xt)35 b(line)g(describes)h(where)g(magic)f(thinks)g (the)g(slo)n(west)g(node)g(in)h(the)f(net)h(is.)63 b(The)36 b(\002nal)g(3)f(lines)g(gi)n(v)o(e)g(a)0 4243 y(brief)24 b(summary)f(of)i(the)e(total)h(number)f(of)i(nets,)e(the)h(nets)g (requiring)f(e)o(xtraction,)h(and)g(the)g(number)f(for)i(which)0 4363 y(resistors)f(were)h(added)g(to)g(the)f(output.)146 4490 y(Running)37 b(the)h(resistance)f(e)o(xtractor)h(also)f(produced)g (the)h(\002le)g Fe(cell.r)n(es.ext)p Fg(.)70 b(T)-8 b(o)37 b(produce)h(a)g Fe(.sim)f Fg(\002le)0 4610 y(containing)24 b(resistors,)f(quit)h(magic)h(and)f(type:)900 4888 y Fe(cat)h(tut8r)-10 b(.ext)26 b(tut8r)-10 b(.r)n(es.ext)26 b Fd(>)p Fe(tut8r)-10 b(.2.ext)900 5008 y(ext2sim)24 b(-R)h(-t!)32 b(-t#)25 b(tut8r)-10 b(.2)146 5280 y Fg(Comparing)32 b(the)g(tw)o(o)g(\002les,)j Fe(tut8r)-10 b(.sim)33 b Fg(and)f Fe(tut8r)-10 b(.2.sim)p Fg(,)34 b(sho)n(ws)d(that)h(the)h (latter)f(has)g(the)g(nodes)g(net1)0 5400 y(and)25 b(net2)f(split)g (into)g(se)n(v)o(eral)g(parts,)g(with)g(resistors)g(added)h(to)f (connect)h(the)g(ne)n(w)f(nodes)h(together)-5 b(.)1875 5649 y(\2266\226)p eop %%Page: 7 7 7 6 bop 0 -180 a Fg(Magic)24 b(T)l(utorial)g(#8:)30 b(Circuit)25 b(Extraction)1603 b(September)25 b(26,)g(2001)0 69 y Fe(4.2.2)99 b(General)25 b(Notes)g(on)g(using)g(the)g(r)n(esistance)h (extractor)0 260 y Fg(T)-8 b(o)36 b(use)h Fe(:extr)n(esis)p Fg(,)i(the)e(circuit)f(must)f(\002rst)i(be)f(e)o(xtracted)h(using)e Fe(:extract)i Fg(and)g(\003attened)g(using)e(e)o(xt2sim.)0 380 y(When)h(e)o(xt2sim)f(is)h(run,)i(do)e(not)g(use)g(the)g Fe(-t#)h Fg(and)f Fe(-t!)66 b Fg(\003ags)37 b(\(i.e.)65 b(don')n(t)36 b(trim)f(the)h(trailing)f(\224#\224)i(and)f(\224!\224)0 501 y(characters\))30 b(or)f(the)g Fe(-R)h Fg(\003ag)f(because)h Fe(:extr)n(esis)f Fg(needs)g(the)g Fe(.sim)g Fg(and)g Fe(.ext)g Fg(names)g(to)g(correspond)f(e)o(xactly)-6 b(,)0 621 y(and)21 b(it)f(needs)h(the)g(lumped)f(resistance)h(v)n (alues)f(that)g(the)h(e)o(xtractor)g(produces.)29 b(Also,)21 b(do)f(not)h(delete)g(or)g(rename)0 741 y(the)g Fe(.nodes)h Fg(\002le;)g Fe(:extr)n(esis)g Fg(needs)f(this)f(to)h(run.)29 b(Once)22 b(the)f Fe(.sim)f Fg(and)i Fe(.nodes)f Fg(\002les)h(ha)n(v)o (e)e(been)i(produced,)f(type)0 862 y(the)30 b(command)g Fe(:extr)n(esis)h Fg(while)f(running)f(magic)h(on)h(the)f(root)g(cell.) 48 b(As)30 b(the)g(resistance)h(e)o(xtractor)f(runs,)i(it)0 982 y(will)h(identify)h(which)f(nets)h(\(if)h(an)o(y\))e(for)i(which)f (it)f(is)h(producing)g(RC)h(netw)o(orks,)h(and)e(will)f(identify)g (what)0 1102 y(it)e(thinks)e(is)i(the)g(\224slo)n(west\224)f(point)g (in)g(the)h(netw)o(ork.)49 b(When)31 b(it)g(completes,)h(it)e(will)g (print)h(a)g(brief)g(summary)0 1223 y(of)37 b(ho)n(w)g(man)o(y)f(nets)h (it)f(e)o(xtracted)h(and)g(ho)n(w)g(man)o(y)f(required)h(supplemental)f (netw)o(orks.)67 b(The)37 b(resistance)0 1343 y(netw)o(orks)23 b(are)i(placed)f(in)g(the)g(\002le)g Fe(r)n(oot.r)n(es.ext)p Fg(.)31 b(T)-8 b(o)24 b(produce)g(a)h Fe(.sim)e Fg(\002le)i(with)e(the) h(supplemental)e(resistors,)0 1464 y(type)g Fe(cat)h(r)n(oot.ext)g(r)n (oot.r)n(es.ext)g Fd(>)p Fe(newname.ext)p Fg(,)h(and)e(then)h(rerun)f Fe(ext2sim)g Fg(on)h(the)f(ne)n(w)g(\002le.)30 b(During)22 b(this)0 1584 y(second)j Fe(ext2sim)f Fg(run,)h(the)f Fe(-t)h Fg(\003ag)h(may)e(be)h(used.)146 1706 y(Lik)o(e)h(e)o (xtraction)e(of)i(wire)f(lengths,)g(resistance)g(e)o(xtraction)g(is)g Fh(not)f Fg(performed)i(hierarchically;)f(it)g(should)0 1826 y(only)f(be)h(done)g(in)f(the)h(root)f(cell)h(of)g(a)g(design)f (and)h(can)g(tak)o(e)g(a)g(long)f(time)g(for)h(comple)o(x)f(wires.)0 2103 y Fe(4.2.3)99 b(Options,)24 b(F)n(eatur)n(es,)i(Ca)n(v)o(eats)e (and)h(Bugs)0 2295 y Fg(The)g(follo)n(wing)e(is)h(a)h(list)f(of)h (command)f(line)g(options)f(and)i(the)g(ar)n(guments)f(that)g(the)o(y)g (tak)o(e.)145 2535 y Fc(\017)49 b Fe(tolerance)26 b([v)o(alue])244 2655 y Fg(This)h(controls)g(ho)n(w)g(lar)n(ge)h(the)g(resistance)f(in)h (a)g(netw)o(ork)f(must)g(be)h(before)g(it)f(is)h(added)f(to)h(the)f (output)244 2776 y(description.)52 b Fe(v)o(alue)33 b Fg(is)f(de\002ned)g(as)h(the)f(minimum)e(ratio)i(of)h(transistor)e (resistance)i(to)f(interconnect)244 2896 y(resistance)c(that)g (requires)g(a)h(resistance)f(netw)o(ork.)40 b(The)29 b(def)o(ault)f(v)n(alue)f(is)h(1;)i(v)n(alues)d(less)h(than)g(1)g(will) 244 3016 y(cause)c(fe)n(wer)g(resistors)e(to)i(be)f(output)g(and)g (will)g(mak)o(e)g(the)h(program)f(run)h(f)o(aster)l(,)g(while)f(v)n (alues)f(greater)244 3137 y(than)i(1)h(will)f(produce)h(more)f(a)i(lar) n(ger)l(,)f(more)g(accurate)g(description)f(b)n(ut)g(will)g(run)h(slo)n (wer)-5 b(.)145 3349 y Fc(\017)49 b Fe(all)244 3469 y Fg(Causes)38 b(all)f(nets)g(in)g(the)g(circuit)g(to)g(be)g(e)o (xtracted;)44 b(no)37 b(comparison)f(between)h(transistor)g(size)g(and) 244 3589 y(lumped)24 b(resistance)g(is)h(performed.)30 b(This)25 b(option)e(is)h(not)h(recommended)f(for)h(lar)n(ge)g (designs.)145 3801 y Fc(\017)49 b Fe(simplify)24 b([on/off])244 3922 y Fg(T)l(urns)30 b(on/of)n(f)g(the)h(resistance)g(netw)o(ork)f (simpli\002cation)g(routines.)48 b(Magic)31 b(normally)f(simpli\002es)f (the)244 4042 y(resistance)38 b(netw)o(ork)g(it)g(e)o(xtracts)f(by)h (remo)o(ving)f(small)g(resistors;)44 b(specifying)37 b(this)h(\003ag)g(turns)g(this)244 4162 y(feature)25 b(of)n(f.)145 4374 y Fc(\017)49 b Fe(extout)25 b([on/off])244 4495 y Fg(T)l(urns)f(on)g(and)h(of)n(f)g(the)f(writing)g(of)h(the)g Fb(root.res.ext)d Fg(\002le.)31 b(The)25 b(def)o(ault)f(v)n(alue)g(is)h (on.)145 4707 y Fc(\017)49 b Fe(lumped)26 b([on/off])244 4827 y Fg(T)l(urns)40 b(on)g(the)h(writing)f(of)h Fb(root.res.lump)p Fg(.)76 b(This)40 b(\002le)h(contains)f(an)h(updated)f(v)n(alue)g(of)h (the)244 4947 y(lumped)24 b(resistance)g(for)h(each)h(net)f(that)f Fe(:extr)n(esis)h Fg(e)o(xtracts.)145 5159 y Fc(\017)49 b Fe(silent)25 b([on/off])244 5280 y Fg(This)38 b(option)f(suppresses)h (printing)f(of)h(the)h(name)f(and)h(location)e(of)i(nets)f(for)h(which) f(resistors)f(are)244 5400 y(produced.)1875 5649 y(\2267\226)p eop %%Page: 8 8 8 7 bop 0 -180 a Fg(September)25 b(26,)f(2001)1604 b(Magic)25 b(T)l(utorial)e(#8:)30 b(Circuit)25 b(Extraction)145 69 y Fc(\017)49 b Fe(skip)25 b(mask)244 189 y Fg(Speci\002es)h(a)f (list)e(of)i(layers)g(that)f(the)h(resistance)g(e)o(xtractor)f(is)h(to) f(ignore.)145 405 y Fc(\017)49 b Fe(help)244 526 y Fg(Print)25 b(brief)g(list)e(of)i(options.)146 772 y(Attrib)n(ute)36 b(labels)g(may)g(also)g(be)g(used)g(to)g(specify)h(certain)f(e)o (xtractor)g(options.)65 b(F)o(or)36 b(a)h(description)e(of)0 893 y(attrib)n(utes)24 b(and)g(ho)n(w)g(the)o(y)g(w)o(ork,)h(see)g (tutorial)f(2.)30 b(F)o(ollo)n(wing)23 b(is)h(a)i(description)d(of)i Fe(:extr)n(esis)g Fg(attrib)n(utes.)145 1139 y Fc(\017)49 b Fe(r)n(es:skip@)244 1259 y Fg(Causes)33 b(this)f(net)h(to)f(be)i (skipped.)54 b(This)32 b(is)g(useful)h(for)g(a)n(v)n(oiding)f(e)o (xtraction)g(of)h(po)n(wer)f(supplies)g(or)244 1380 y(other)25 b(DC)g(signals)e(that)i(are)g(not)g(labeled)f(Vdd)h(or)g(GND.)145 1596 y Fc(\017)49 b Fe(r)n(es:f)n(or)n(ce@)244 1717 y Fg(F)o(orces)30 b(e)o(xtraction)f(of)h(this)e(net)i(re)o(gardless)f(of) h(its)f(lumped)g(resistance)g(v)n(alue.)45 b(Nets)30 b(with)f(both)g(skip)244 1837 y(and)c(force)g(labels)g(attached)f(will) g(cause)h(the)g(e)o(xtractor)g(to)f(complain.)145 2053 y Fc(\017)49 b Fe(r)n(es:min=[v)o(alue]@)244 2174 y Fg(Sets)30 b(the)f(smallest)g(resistor)g(size)h(for)g(this)e(net.)46 b(The)30 b(def)o(ault)f(v)n(alue)g(is)h(the)f(resistance)h(of)g(the)f (lar)n(gest)244 2294 y(dri)n(ving)23 b(transistor)h(di)n(vided)f(by)i (the)f(tolerance)h(described)g(abo)o(v)o(e.)145 2510 y Fc(\017)49 b Fe(r)n(es:dri)o(v)o(e@)33 b Fg(-)f(Nets)g(with)g(no)g (dri)n(ving)f(transistors)f(will)i(normally)f(not)h(be)g(e)o(xtracted.) 53 b(This)31 b(option)244 2631 y(allo)n(ws)e(the)h(designer)f(to)h (specify)g(from)g(where)h(in)e(the)h(net)g(the)g(signal)f(is)h(dri)n(v) o(en.)45 b(This)30 b(is)f(primarily)244 2751 y(useful)d(when)g(e)o (xtracting)f(subcells,)g(where)i(the)f(transistors)e(dri)n(ving)h(a)h (gi)n(v)o(en)f(signal)g(may)h(be)g(located)244 2872 y(in)e(a)h(dif)n (ferent)g(cell.)0 3154 y Fe(4.2.4)99 b(T)-9 b(echnology)25 b(File)g(Changes)0 3347 y Fg(Certain)33 b(changes)f(must)f(be)i(made)f (in)g(the)g(e)o(xtract)g(section)g(of)h(the)f(technology)f(\002le)i(to) f(support)f(resistance)0 3468 y(e)o(xtraction.)39 b(These)28 b(include)g(the)g Fe(fetr)n(esist)g Fg(and)g Fe(contact)h Fg(lines,)f(plus)f(a)i(small)e(change)h(to)g(the)f(fet)i(line.)39 b(Full)0 3588 y(details)26 b(can)i(be)f(found)g(in)g(Magic)f (Maintainer')-5 b(s)26 b(Manual)h(#2.)37 b(The)27 b(only)g(thing)f(to)h (note)f(is)h(that,)g(contrary)g(to)0 3708 y(the)d(documentation,)e(the) i Fe(gccap)g Fg(and)g Fe(gscap)g Fg(parts)g(of)g(the)g(fet)g(line)f (MUST)h(be)g(set;)g(the)g(resistance)f(e)o(xtractor)0 3829 y(uses)h(them)h(to)f(calculate)h(RC)h(time)e(constants)g(for)h (the)f(circuit.)0 4185 y Fi(5)143 b(Extraction)34 b(Details)g(and)h (Limitations)0 4414 y Fg(This)28 b(section)g(e)o(xplores)g(in)h (greater)g(depth)f(what)h(gets)f(e)o(xtracted)h(by)f(Magic,)i(as)f (well)f(as)h(the)g(limitations)d(of)0 4534 y(the)f(circuit)g(e)o (xtractor)-5 b(.)30 b(A)25 b(detailed)g(e)o(xplanation)e(of)i(the)g (format)g(of)g(the)g Fe(.ext)g Fg(\002les)g(output)f(by)h(Magic)f(may)h (be)0 4655 y(found)20 b(in)g(the)g(manual)g(page)g Fh(e)n(xt)h Fg(\(5\).)30 b(\223Magic)20 b(Maintainer')-5 b(s)19 b(Manual)h(#2:)28 b(The)20 b(T)-7 b(echnology)20 b(File\224)g(describes)0 4775 y(ho)n(w)k(e)o(xtraction)g(parameters)h(are)g(speci\002ed)g(for)g (the)g(e)o(xtractor)-5 b(.)0 5087 y Ff(5.1)119 b(Nodes)0 5280 y Fg(Magic)28 b(approximates)g(the)h(pieces)f(of)h(interconnect)g (between)f(transistors)g(as)h(\223nodes\224.)42 b(A)29 b(node)f(is)h(lik)o(e)f(an)0 5400 y(equipotential)e(re)o(gion,)h(b)n (ut)g(also)h(includes)e(a)i(lumped)f(resistance)h(and)f(capacitance)i (to)e(substrate.)38 b(Figure)28 b(1)1875 5649 y(\2268\226)p eop %%Page: 9 9 9 8 bop 0 -180 a Fg(Magic)24 b(T)l(utorial)g(#8:)30 b(Circuit)25 b(Extraction)1603 b(September)25 b(26,)g(2001)1306 1294 y @beginspecial 68 @llx 68 @lly 246 @urx 247 @ury 1544 @rwi @setspecial %%BeginDocument: ../psfigures/tut8.1.ps % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def % XCircuit output starts here. /resistor { % -14 -64 28 128 bbox begingate % fundamental 1 1.00 0 64 0 36 2 polygon 1 1.00 0 -64 0 -36 2 polygon 1 1.00 0 -36 14 -30 -14 -18 14 -6 -14 6 14 18 -14 30 0 36 8 polygon 1.000 0.000 0.000 scb (r.1) {/Times-Roman 1.000 cf} 2 9 0 0 64 pinlabel (r.2) {/Times-Roman 1.000 cf} 2 13 0 0 -64 pinlabel sce (spice:R%i %pr.1 %pr.2 1.0K) {/Times-Roman 1.000 cf} 2 0 0 -208 -160 infolabel (sim:r %pr.1 %pr.2) {/Times-Roman 1.000 cf} 2 0 0 -208 -208 infolabel endgate } def /capacitor { % -32 -64 64 128 bbox begingate % fundamental 1 1.00 0 -64 0 -6 2 polygon 1 1.00 0 64 0 6 2 polygon 1 1.00 -32 6 32 6 2 polygon 1 1.00 -32 -6 32 -6 2 polygon 1.000 0.000 0.000 scb (c.1) {/Times-Roman 1.000 cf} 2 9 0 0 64 pinlabel (c.2) {/Times-Roman 1.000 cf} 2 13 0 0 -64 pinlabel sce (spice:C%i %pc.1 %pc.2 1.0P) {/Times-Roman 1.000 cf} 2 0 0 -208 -160 infolabel (sim:c %pc.1 %pc.2) {/Times-Roman 1.000 cf} 2 0 0 -208 -208 infolabel endgate } def /circle { % -6 -12 28 24 bbox begingate 1 1.00 16 0 6 0.00 360.00 xcarc 1 1.00 0 0 10 0 2 polygon 1.000 0.000 0.000 scb (out) {/Times-Roman 1.000 cf} 2 4 0 16 0 pinlabel (out) {/Times-Roman 1.000 cf} 2 7 0 0 0 pinlabel sce endgate } def /gnd { % -32 -60 64 68 bbox begingate 1 1.00 0 0 0 -32 2 polygon 1 1.00 -32 -32 32 -32 2 polygon 1 1.00 -18 -46 18 -46 2 polygon 1 1.00 -4 -60 4 -60 2 polygon 1.000 0.000 0.000 scb (GND) {/Times-Roman 1.000 cf} 2 1 0 0 0 pinglobal sce endgate } def /dot { % -10 -10 20 20 bbox begingate 248 1.00 0 0 6 0.00 360.00 xcarc endgate } def /pgsave save def bop % 430 412 offsets 1.0000 inchscale 2.6000 setlinewidth 1.00 0 430 508 resistor 1.00 315 504 486 resistor 1.00 270 526 412 resistor 1.00 270 334 412 resistor 1.00 0 430 316 capacitor 1 1.00 430 380 430 444 2 polygon 1 1.00 398 412 462 412 2 polygon 1 1.00 430 412 462 444 2 polygon 1.00 0 590 412 circle 1.00 45 550 532 circle 1.00 90 430 572 circle 1.00 180 270 412 circle (C) {/Times-Italic 1.000 cf} 2 20 0 478 316 label (/2) {/Times-Roman 1.000 cf} (R) {/Times-Italic 1.000 cf} 4 29 0 526 388 label (1) {/Times-Roman 1.000 cf} 2 20 0 630 412 label (2) {/Times-Roman 1.000 cf} 2 24 0 574 556 label (3) {/Times-Roman 1.000 cf} 2 25 0 430 620 label (N) {/Times-Italic 1.000 cf} 2 23 0 222 412 label (/2) {/Times-Roman 1.000 cf} (R) {/Times-Italic 1.000 cf} 4 29 0 334 388 label (/2) {/Times-Roman 1.000 cf} (R) {/Times-Italic 1.000 cf} 4 28 0 526 484 label (/2) {/Times-Roman 1.000 cf} (R) {/Times-Italic 1.000 cf} 4 23 0 398 540 label 1.00 0 430 252 gnd 1.00 0 430 412 dot (.) {/Times-Bold 1.000 cf} 2 21 0 364 486 label (.) {/Times-Bold 1.000 cf} 2 21 0 387 506 label (.) {/Times-Bold 1.000 cf} 2 21 0 350 460 label pgsave restore showpage XCIRCsave restore %%EndDocument @endspecial 0 1498 a(Figure)31 b(1:)42 b(Each)31 b(node)f(e)o (xtracted)h(by)f(Magic)g(has)h(a)g(lumped)f(resistance)g Fh(R)h Fg(and)f(a)h(lumped)f(capacitance)i Fh(C)0 1618 y Fg(to)d(the)h(substrate.)45 b(These)30 b(lumped)f(v)n(alues)g(can)h (be)g(interpreted)g(as)g(in)f(the)h(diagram)f(abo)o(v)o(e,)i(in)e (which)g(each)0 1738 y(de)n(vice)24 b(connected)h(to)g(the)f(node)h(is) f(attached)h(to)f(one)h(of)g(the)g(points)e Fh(1)p Fg(,)i Fh(2)p Fg(,)g(.)15 b(.)g(.)g(,)24 b Fh(N)p Fg(.)0 2108 y(sho)n(ws)29 b(ho)n(w)h(these)g(lumped)g(v)n(alues)g(are)h(intended)f (to)g(be)h(interpreted)f(by)g(the)g(analysis)g(programs)g(that)g(use)0 2229 y(the)25 b(e)o(xtracted)f(circuit.)146 2352 y(Each)k(node)g(in)g (an)g(e)o(xtracted)f(circuit)h(has)g(a)g(name,)g(which)g(is)f(either)h (one)g(of)g(the)f(labels)h(attached)g(to)f(the)0 2473 y(geometry)f(in)g(the)h(node)g(if)f(an)o(y)g(e)o(xist,)g(or)h (automatically)e(generated)i(by)g(the)f(e)o(xtractor)-5 b(.)36 b(These)27 b(latter)f(names)0 2593 y(are)h(al)o(w)o(ays)g(of)g (the)f(form)h Fh(p)p 985 2593 30 4 v 35 w(x)p 1064 2593 V 36 w(y#)p Fg(,)h(where)f Fh(p)p Fg(,)g Fh(x)p Fg(,)g(and)g Fh(y)g Fg(are)g(inte)o(gers,)f Fh(e)o(.g)o(.)p Fg(,)g Fe(3)p 2714 2593 V 36 w(104)p 2900 2593 V 35 w(17#)p Fg(.)36 b(If)27 b(a)g(label)g(ending)e(in)0 2713 y(the)31 b(character)g(\223)p Fe(!)p Fg(\224)50 b(is)30 b(attached)h(to)f(a)h (node,)h(the)f(node)f(is)g(considered)h(to)f(be)h(a)g(\223global\224.) 48 b(Post-processing)0 2834 y(programs)21 b(such)g(as)h Fh(e)n(xt2sim)f Fg(\(1\))h(will)f(check)h(to)f(ensure)g(that)h(nodes)f (in)g(dif)n(ferent)g(cells)g(that)g(are)i(labelled)e(with)0 2954 y(the)k(same)f(global)g(name)h(are)g(electrically)g(connected.)146 3078 y(Nodes)j(may)f(ha)n(v)o(e)h(attrib)n(utes)f(attached)h(to)g(them) f(as)h(well)f(as)h(names.)40 b(Node)28 b(attrib)n(utes)f(are)i(labels)e (end-)0 3198 y(ing)35 b(in)f(the)i(special)e(character)j(\223)p Fe(@)p Fg(\224,)h(and)d(pro)o(vide)f(a)i(mechanism)e(for)h(passing)f (information)g(to)h(analysis)0 3319 y(programs)d(such)g(as)g Fh(crystal)g Fg(\(1\).)53 b(The)33 b(man)f(page)g Fh(e)n(xt)h Fg(\(5\))g(pro)o(vides)e(additional)g(information)g(about)g(node)0 3439 y(attrib)n(utes.)0 3755 y Ff(5.2)119 b(Resistance)0 3949 y Fg(Magic)27 b(e)o(xtracts)g(a)g(lumped)g(resistance)g(for)h (each)g(node,)f(rather)h(than)f(a)h(point-to-point)d(resistance)i (between)0 4069 y(each)k(pair)f(of)h(de)n(vices)f(connected)g(to)g (that)g(node.)47 b(The)31 b(result)e(is)h(that)g(all)g(such)g (point-to-point)e(resistances)0 4190 y(are)e(approximated)d(by)i(the)f (w)o(orst-case)h(resistance)g(between)g(an)o(y)f(tw)o(o)h(points)e(in)h (that)h(node.)146 4313 y(By)j(def)o(ault,)f(node)f(resistances)h(are)g (approximated)f(rather)h(than)g(computed)f(e)o(xactly)-6 b(.)36 b(F)o(or)26 b(a)i(node)e(com-)0 4434 y(prised)c(entirely)f(of)h (a)g(single)f(type)h(of)g(material,)g(Magic)f(will)g(compute)g(the)h (node')-5 b(s)21 b(total)h(perimeter)f(and)h(area.)0 4554 y(It)g(then)g(solv)o(es)f(a)i(quadratic)f(equation)g(to)g(\002nd)g (the)g(width)g(and)g(height)f(of)i(a)g(simple)e(rectangle)h(with)g (this)f(same)0 4674 y(perimeter)31 b(and)g(area,)j(and)d(approximates)e (the)i(resistance)g(of)h(the)e(node)h(as)h(the)e(resistance)h(of)h (this)e(\223equi)n(v-)0 4795 y(alent\224)h(rectangle.)48 b(The)31 b(resistance)g(is)f(al)o(w)o(ays)g(tak)o(en)h(in)f(the)h (longer)f(dimension)f(of)i(the)f(rectangle.)49 b(When)0 4915 y(a)30 b(node)f(contains)f(more)i(than)f(a)h(single)e(type)h(of)h (material,)g(Magic)f(computes)f(an)i(equi)n(v)n(alent)d(rectangle)j (for)0 5036 y(each)25 b(type,)g(and)g(then)f(sums)g(the)g(resistances)h (as)g(though)e(the)i(rectangles)g(were)g(laid)g(end-to-end.)146 5159 y(This)30 b(approximation)e(for)j(resistance)f(does)f(not)h(tak)o (e)g(into)g(account)g(an)o(y)f(branching,)i(so)f(it)g(can)g(be)h(sig-)0 5280 y(ni\002cantly)26 b(in)f(error)i(for)f(nodes)g(that)f(ha)n(v)o(e)h (side)g(branches.)34 b(Figure)27 b(2)f(gi)n(v)o(es)e(an)i(e)o(xample.) 34 b(F)o(or)26 b(global)f(signal)0 5400 y(trees)33 b(such)f(as)g (clocks)g(or)h(po)n(wer)l(,)g(Magic')-5 b(s)32 b(estimate)f(of)i (resistance)f(will)g(lik)o(ely)f(be)h(se)n(v)o(eral)g(times)f(higher) 1875 5649 y(\2269\226)p eop %%Page: 10 10 10 9 bop 0 -180 a Fg(September)25 b(26,)f(2001)1604 b(Magic)25 b(T)l(utorial)e(#8:)30 b(Circuit)25 b(Extraction)0 68 y(than)f(the)h(actual)g(resistance)g(between)g(tw)o(o)f(points.)390 1444 y @beginspecial 68 @llx 68 @lly 652 @urx 303 @ury 3744 @rwi @setspecial %%BeginDocument: ../psfigures/tut8.2.ps % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def % XCircuit output starts here. /dot { % -10 -10 20 20 bbox begingate 248 1.00 0 0 6 0.00 360.00 xcarc endgate } def /pgsave save def bop % 992 510 offsets 1.0000 inchscale 2.6000 setlinewidth 0.800 0.800 0.800 scb 240 1.00 192 254 192 798 1728 798 1728 254 4 polygon sce 0.490 0.651 0.980 scb 240 1.00 1152 510 1408 510 1408 382 1248 382 1248 350 1568 350 1568 382 1440 382 1440 510 1568 510 1568 542 1344 542 1344 638 1664 638 1664 766 1632 766 1632 670 1312 670 1312 542 1152 542 20 polygon 240 1.00 256 510 448 510 448 318 672 318 672 638 800 638 800 510 960 510 960 542 832 542 832 670 640 670 640 350 480 350 480 542 256 542 16 polygon sce 0 1.00 256 510 448 510 448 318 672 318 672 638 800 638 800 510 960 510 960 542 832 542 832 670 640 670 640 350 480 350 480 542 256 542 16 polygon 0 1.00 1152 510 1408 510 1408 382 1248 382 1248 350 1568 350 1568 382 1440 382 1440 510 1568 510 1568 542 1344 542 1344 638 1664 638 1664 766 1632 766 1632 670 1312 670 1312 542 1152 542 20 polygon 1.000 1.000 0.000 scb 1 1.00 256 526 464 526 464 334 656 334 656 654 816 654 816 526 960 526 8 polygon 1 1.00 1152 526 1568 526 2 polygon 1 1.00 1248 366 1568 366 2 polygon 1 1.00 1424 366 1424 526 2 polygon 1 1.00 1328 526 1328 654 1648 654 1648 766 4 polygon 1.00 0 256 526 dot 1.00 0 960 526 dot 1.00 0 1152 526 dot 1.00 0 1568 526 dot sce (1) {/Helvetica 1.000 cf} 2 23 0 224 526 label (2) {/Helvetica 1.000 cf} 2 20 0 976 526 label (1) {/Helvetica 1.000 cf} 2 23 0 1120 526 label (2) {/Helvetica 1.000 cf} 2 20 0 1600 526 label (\(a\)) {/Times-Roman 1.000 cf} 2 21 0 560 206 label (\(b\)) {/Times-Roman 1.000 cf} 2 21 0 1424 206 label pgsave restore showpage XCIRCsave restore %%EndDocument @endspecial 0 1648 a(Figure)29 b(2:)39 b(Magic)29 b(approximates)f (the)h(resistance)g(of)g(a)h(node)f(by)f(assuming)g(that)h(it)f(is)h(a) g(simple)f(wire.)44 b(The)0 1768 y(length)39 b(and)h(width)e(of)i(the)g (wire)g(are)g(estimated)f(from)g(the)h(node')-5 b(s)39 b(perimeter)g(and)h(area.)76 b(\(a\))41 b(F)o(or)e(non-)0 1889 y(branching)29 b(nodes,)h(this)f(approximation)f(is)h(a)h(good)f (one.)46 b(\(b\))29 b(The)h(computed)f(resistance)g(for)h(this)f(node)h (is)0 2009 y(the)25 b(same)g(as)g(for)g(\(a\))g(because)h(the)e(side)h (branches)g(are)h(counted,)e(yet)h(the)g(actual)g(resistance)f(between) h(points)0 2129 y(1)g(and)f(2)h(is)g(signi\002cantly)e(less)h(than)h (in)f(\(a\).)146 2457 y(The)i(approximated)e(resistance)h(also)g(does)g (not)g(lend)g(itself)g(well)g(to)g(hierarchical)g(adjustments,)f(as)h (does)0 2578 y(capacitance.)40 b(T)-8 b(o)28 b(allo)n(w)e(programs)h (lik)o(e)h Fe(ext2sim)f Fg(to)g(incorporate)h(hierarchical)g (adjustments)d(into)i(a)h(resis-)0 2698 y(tance)g(approximation,)e (each)i(node)f(in)g(the)h Fe(.ext)g Fg(\002le)f(also)g(contains)g(a)h (perimeter)f(and)h(area)g(for)g(each)g(\223resis-)0 2818 y(tance)23 b(class\224)f(that)g(w)o(as)g(de\002ned)h(in)f(the)h (technology)e(\002le)i(\(see)f(\223Maintainer')-5 b(s)22 b(Manual)g(#2:)29 b(The)22 b(T)-7 b(echnology)0 2939 y(File,)g(\224)23 b(and)g Fh(e)n(xt)g Fg(\(5\)\).)30 b(When)23 b(\003attening)f(a)h(circuit,)f Fe(ext2sim)g Fg(uses)g(this)g(information)f(along)h(with)g(adjustments)0 3059 y(to)i(perimeter)h(and)g(area)h(to)e(produce)h(the)f(v)n(alue)h (it)f(actually)g(uses)h(for)g(node)f(resistance.)146 3179 y(If)39 b(you)e(wish)g(to)g(disable)g(the)h(e)o(xtraction)f(of)g (resistances)h(and)f(node)h(perimeters)f(and)h(areas,)k(use)37 b(the)0 3300 y(command)900 3495 y Fe(:extract)26 b(no)f(r)n(esistance) 146 3689 y Fg(which)37 b(will)g(cause)h(all)f(node)h(resistances,)i (perimeters,)g(and)e(areas)g(in)g(the)f Fe(.ext)h Fg(\002le)g(to)f(be)h (zero.)69 b(T)-8 b(o)0 3810 y(re-enable)26 b(e)o(xtraction)d(of)i (resistance,)g(use)g(the)f(command)900 4005 y Fe(:extract)i(do)f(r)n (esistance)p Fg(.)146 4199 y(Sometimes)i(it')-5 b(s)28 b(important)e(that)i(resistances)g(be)g(computed)f(more)h(accurately)h (than)f(is)f(possible)g(using)0 4320 y(the)33 b(lumped)f(approximation) g(abo)o(v)o(e.)55 b(Magic')-5 b(s)32 b Fe(:extr)n(esist)i Fg(command)e(does)h(this)f(by)h(computing)f(e)o(xplicit)0 4440 y(tw)o(o-terminal)20 b(resistors)h(and)g(modifying)f(the)h (circuit)g(netw)o(ork)g(to)g(include)g(them)f(so)h(it)g(re\003ects)i (more)e(e)o(xactly)0 4561 y(the)28 b(topology)f(of)i(the)f(layout.)40 b(See)30 b(the)e(section)g(on)g Fe(Adv)o(anced)i(Extraction)f Fg(for)g(more)f(details)f(on)i(e)o(xplicit)0 4681 y(resistance)c(e)o (xtraction)f(with)g Fe(:extr)n(esist)p Fg(.)0 4972 y Ff(5.3)119 b(Capacitance)0 5159 y Fg(Capacitance)22 b(to)e(substrate)g (comes)g(from)g(tw)o(o)g(dif)n(ferent)h(sources.)29 b(Each)21 b(type)f(of)h(material)f(has)g(a)h(capacitance)0 5280 y(to)k(substrate)f(per)i(unit)e(area.)33 b(Each)25 b(type)g(of)g(edge)g (\(i.e,)h(each)f(pair)h(of)f(types\))g(has)g(a)g(capacitance)h(to)f (substrate)0 5400 y(per)g(unit)f(length.)30 b(See)c(Figure)f(3.)30 b(The)25 b(computation)e(of)i(capacitance)h(may)e(be)h(disabled)f(with) 1850 5649 y(\22610\226)p eop %%Page: 11 11 11 10 bop 0 -180 a Fg(Magic)24 b(T)l(utorial)g(#8:)30 b(Circuit)25 b(Extraction)1603 b(September)25 b(26,)g(2001)975 1288 y @beginspecial 68 @llx 68 @lly 498 @urx 352 @ury 2340 @rwi @setspecial %%BeginDocument: ../psfigures/tut8.3.ps % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def % XCircuit output starts here. /mgrid { % -304 -368 736 736 bbox begingate 1 1.00 -256 368 -256 -368 2 polygon 1 1.00 -128 368 -128 -368 2 polygon 1 1.00 -304 192 432 192 2 polygon 1 1.00 -304 64 432 64 2 polygon 1 1.00 0 368 0 -368 2 polygon 1 1.00 256 368 256 -368 2 polygon 1 1.00 128 368 128 -368 2 polygon 1 1.00 -304 -192 432 -192 2 polygon 1 1.00 -304 -64 432 -64 2 polygon 1 1.00 -304 -320 432 -320 2 polygon 1 1.00 -304 320 432 320 2 polygon 1 1.00 384 368 384 -368 2 polygon endgate } def /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrow { % -12 -40 24 80 bbox begingate 1 0.80 0 -40 0 20 2 polygon 1.00 0 0 40 arrowhead endgate } def /pgsave save def bop % 720 464 offsets 1.0000 inchscale 2.6000 setlinewidth 0.133 0.545 0.133 scb 240 1.00 368 624 368 880 752 880 752 624 4 polygon sce 0.439 1.000 0.314 scb 241 1.00 240 240 880 240 880 496 752 496 752 624 368 624 368 496 240 496 8 polygon 1 1.00 752 864 752 880 2 polygon sce 0.800 0.800 0.800 scb 1.00 0 496 560 mgrid sce 0 1.00 368 624 368 880 752 880 752 624 4 polygon 1.000 1.000 1.000 scb (buried) {/Times-Roman 1.000 cf} 2 21 0 560 752 label sce (diffusion) {/Times-Roman 1.000 cf} 2 21 0 544 400 label (diff-space perimeter) {/Times-Roman 1.000 cf} 2 28 0 976 224 label (diff-buried perimeter) {/Times-Roman 1.000 cf} 2 21 0 944 704 label 3 1.00 368 624 368 496 240 496 240 240 880 240 880 496 752 496 752 624 8 polygon 1.00 60 928 256 arrow 1.000 1.000 1.000 scb 3 1.00 368 624 752 624 2 polygon 1.00 135 720 656 arrow sce pgsave restore showpage XCIRCsave restore %%EndDocument @endspecial 0 1491 a(Figure)g(3:)30 b(Each)25 b(type)f(of)h(edge)g (has)f(capacitance)i(to)e(substrate)g(per)h(unit)f(length.)30 b(Here,)25 b(the)f(dif)n(fusion-space)0 1612 y(perimeter)30 b(of)f(13)h(units)f(has)g(one)h(v)n(alue)f(per)h(unit)f(length,)h(and)g (the)f(dif)n(fusion-b)n(uried)f(perimeter)i(of)g(3)f(units)0 1732 y(another)-5 b(.)30 b(In)25 b(addition,)e(each)j(type)e(of)h (material)g(has)f(capacitance)i(per)f(unit)f(area.)900 2101 y Fe(:extract)i(no)f(capacitance)146 2307 y Fg(which)k(causes)h (all)f(substrate)f(capacitance)i(v)n(alues)f(in)g(the)g Fe(.ext)h Fg(\002le)f(to)g(be)h(zero.)45 b(It)29 b(may)g(be)h (re-enabled)0 2427 y(with)900 2633 y Fe(:extract)c(do)f(capacitance)p Fg(.)146 2839 y(Internodal)34 b(capacitance)h(comes)e(from)h(three)g (sources,)i(as)e(sho)n(wn)f(in)g(Figure)i(4.)58 b(When)34 b(materials)f(of)0 2960 y(tw)o(o)e(dif)n(ferent)f(types)h(o)o(v)o (erlap,)g(the)g(capacitance)h(to)f(substrate)f(of)h(the)g(one)g(on)g (top)g(\(as)g(determined)f(by)h(the)0 3080 y(technology\))h(is)h (replaced)h(by)e(an)i(internodal)e(capacitance)i(to)f(the)g(one)g(on)g (the)g(bottom.)54 b(Its)33 b(computation)0 3201 y(may)24 b(be)h(disabled)f(with)900 3407 y Fe(:extract)i(no)f(coupling)146 3613 y Fg(which)30 b(will)g(also)f(cause)i(the)f(e)o(xtractor)g(to)g (run)g(30\045)g(to)g(50\045)g(f)o(aster)-5 b(.)47 b(Extraction)29 b(of)h(coupling)f(capaci-)0 3733 y(tances)c(can)g(be)g(re-enabled)g (with)900 3939 y Fe(:extract)h(do)f(coupling)p Fg(.)146 4145 y(Whene)n(v)o(er)g(material)f(from)g(tw)o(o)h(subcells)f(o)o(v)o (erlaps)f(or)i(ab)n(uts,)f(the)g(e)o(xtractor)h(computes)f(adjustments) e(to)0 4266 y(substrate)d(capacitance,)j(coupling)c(capacitance,)k(and) e(node)f(perimeter)h(and)g(area.)30 b(Often,)20 b(these)g(adjustments)0 4386 y(mak)o(e)g(little)f(dif)n(ference)i(to)f(the)g(type)g(of)h (analysis)e(you)h(are)h(performing,)f(as)h(when)f(you)g(wish)f(only)h (to)g(compare)0 4506 y(netlists.)34 b(Ev)o(en)25 b(when)h(running)g (Crystal)g(for)g(timing)f(analysis,)h(the)g(adjustments)e(can)j(mak)o (e)f(less)g(than)g(a)g(5\045)0 4627 y(dif)n(ference)g(in)g(the)g (timing)e(of)i(critical)g(paths)g(in)f(designs)g(with)h(only)f(a)h (small)f(amount)g(of)i(inter)n(-cell)e(o)o(v)o(erlap.)0 4747 y(T)-8 b(o)25 b(disable)f(the)g(computation)f(of)i(these)g (adjustments,)e(use)900 4953 y Fe(:extract)j(no)f(adjustment)146 5159 y Fg(which)g(will)g(result)f(in)h(approximately)f(50\045)h(f)o (aster)h(e)o(xtraction.)31 b(This)25 b(speedup)g(is)f(not)h(entirely)g (additi)n(v)o(e)0 5280 y(with)i(the)h(speedup)g(resulting)e(from)i Fe(:extract)h(no)f(coupling)p Fg(.)41 b(T)-8 b(o)28 b(re-enable)h (computation)d(of)i(adjustments,)0 5400 y(use)d Fe(:extract)g(do)h (adjustment)p Fg(.)1850 5649 y(\22611\226)p eop %%Page: 12 12 12 11 bop 0 -180 a Fg(September)25 b(26,)f(2001)1604 b(Magic)25 b(T)l(utorial)e(#8:)30 b(Circuit)25 b(Extraction)488 1238 y @beginspecial 68 @llx 68 @lly 484 @urx 244 @ury 3510 @rwi @setspecial %%BeginDocument: ../psfigures/tut8.4.ps % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrowhead90 { % -20 -12 36 24 bbox begingate 1.00 90 -16 0 arrowhead endgate } def /pgsave save def bop % 928 256 offsets 1.0000 inchscale 2.6000 setlinewidth 0.490 0.651 0.980 scb 192 480 beginpath 544 608 544 480 2 polyc 512 608 32 0.00 90.00 arc 192 640 1 polyc 240 1.00 endpath 1280 480 beginpath 928 608 928 480 2 polyc 960 608 32 180.00 90.00 arcn 1280 640 1 polyc 240 1.00 endpath sce 1.000 0.000 0.000 scb 192 192 beginpath 1120 320 1120 192 2 polyc 1088 320 32 0.00 90.00 arc 192 352 1 polyc 240 1.00 endpath sce 192 480 beginpath 544 608 544 480 2 polyc 512 608 32 0.00 90.00 arc 192 640 1 polyc 1 1.00 endpath 1280 480 beginpath 928 608 928 480 2 polyc 960 608 32 180.00 90.00 arcn 1280 640 1 polyc 1 1.00 endpath 192 192 beginpath 1120 320 1120 192 2 polyc 1088 320 32 0.00 90.00 arc 192 352 1 polyc 1 1.00 endpath (\(metal\)) {/Times-Roman 1.000 cf} 2 21 0 352 560 label (\(metal\)) {/Times-Roman 1.000 cf} 2 21 0 1120 560 label (\(poly\)) {/Times-Roman 1.000 cf} 2 21 0 656 272 label (sidewall overlap) {/Times-Italic 1.000 cf} 2 21 0 688 448 label (sidewall) {/Times-Italic 1.000 cf} 2 21 0 720 576 label (overlap) {/Times-Roman 1.000 cf} 2 21 0 352 424 label (\(oxide\)) {/Times-Roman 1.000 cf} 2 21 0 1024 416 label 1.00 0 560 576 arrowhead90 1.00 -1 912 576 arrowhead90 1.00 0 560 512 arrowhead90 1.00 -91 688 368 arrowhead90 1 1.00 560 576 640 576 2 polygon 1 1.00 912 576 800 576 2 polygon 1 1.00 560 512 688 512 688 480 3 polygon 1 1.00 688 416 688 368 2 polygon 1.00 -91 352 368 arrowhead90 1.00 270 352 464 arrowhead90 1 1.00 352 432 352 464 2 polygon 1 1.00 352 368 352 400 2 polygon pgsave restore showpage XCIRCsave restore %%EndDocument @endspecial 0 1441 a(Figure)33 b(4:)47 b(Magic)33 b(e)o(xtracts)f (three)i(kinds)e(of)h(internodal)f(coupling)g(capacitance.)56 b(This)32 b(\002gure)i(is)f(a)g(cross-)0 1561 y(section)i(\(side)g(vie) n(w)-6 b(,)36 b(not)f(a)g(top)g(vie)n(w\))f(of)i(a)f(set)g(of)h(masks)e (that)h(sho)n(ws)f(all)h(three)g(kinds)f(of)h(capacitance.)0 1682 y Fh(Overlap)g Fg(capacitance)h(is)f(parallel-plate)g(capacitance) h(between)g(tw)o(o)e(dif)n(ferent)h(kinds)g(of)g(material)g(when)0 1802 y(the)o(y)26 b(o)o(v)o(erlap.)37 b Fh(Side)o(wall)26 b Fg(capacitance)h(is)g(parallel-plate)g(capacitance)h(between)f(the)g (v)o(ertical)f(edges)h(of)h(tw)o(o)0 1922 y(pieces)f(of)f(the)h(same)f (kind)g(of)h(material.)36 b Fh(Side)o(wall)25 b(o)o(verlap)h Fg(capacitance)i(is)e(orthogonal-plate)f(capacitance)0 2043 y(between)30 b(the)g(v)o(ertical)g(edge)g(of)g(one)g(piece)h(of)f (material)f(and)h(the)g(horizontal)g(surf)o(ace)g(of)h(another)f(piece) g(of)0 2163 y(material)24 b(that)h(o)o(v)o(erlaps)e(the)i(\002rst)g (edge.)0 2539 y Ff(5.4)119 b(T)-9 b(ransistors)0 2726 y Fg(Lik)o(e)25 b(the)g(resistances)g(of)g(nodes,)f(the)h(lengths)f (and)h(widths)f(of)h(transistors)f(are)i(approximated.)31 b(Magic)24 b(com-)0 2847 y(putes)e(the)g(contrib)n(ution)f(to)h(the)h (total)f(perimeter)g(by)h(each)g(of)f(the)h(terminals)e(of)i(the)g (transistor)-5 b(.)28 b(See)23 b(Figure)g(5.)0 2967 y(F)o(or)i (rectangular)f(transistors,)g(this)f(yields)h(an)h(e)o(xact)f($L)g(/)h (W$.)30 b(F)o(or)25 b(non-branching,)f(non-rectangular)g(tran-)0 3087 y(sistors,)29 b(it)g(is)h(still)e(possible)g(to)h(approximate)g ($L)g(/)h(W$)f(f)o(airly)h(well,)g(b)n(ut)f(substantial)f(inaccuracies) i(can)g(be)0 3208 y(introduced)c(if)g(the)h(channel)f(of)h(a)g (transistor)f(contains)f(branches.)37 b(Since)27 b(most)e(transistors)h (are)h(rectangular)l(,)0 3328 y(ho)n(we)n(v)o(er)l(,)c(Magic')-5 b(s)24 b(approximation)f(w)o(orks)i(well)f(in)h(practice.)p 371 3467 3158 4 v 369 3587 4 121 v 465 3551 a(T)-8 b(ype)303 b(Loc)270 b(A)24 b(P)150 b(Subs)263 b(Gate)296 b(Source)258 b(Drain)p 3527 3587 V 371 3591 3158 4 v 369 3711 4 121 v 421 3675 a(fet)25 b(nfet)149 b(59)25 b(1)g(60)f(2)149 b(8)25 b(12)111 b(GND!)f(Mid2)24 b(4)h Fe(N3)160 b Fg(Out)24 b(4)h(0)160 b(Vss#0)24 b(4)h(0)p 3527 3711 V 369 3831 V 421 3795 a(fet)g(nfet)149 b(36)25 b(1)g(37)f(2)149 b(8)25 b(12)133 b(Float)f(Mid1)24 b(4)h Fe(N2)127 b Fg(Mid2)24 b(4)g(0)127 b(Vss#0)24 b(4)h(0)p 3527 3831 V 369 3952 V 421 3916 a(fet)g(nfet)199 b(4)25 b(1)g(5)f(2)199 b(8)25 b(12)111 b(Vss#0)176 b(In)25 b(4)f Fe(N1)194 b Fg(Mid1)24 b(4)g(0)127 b(Vss#0)24 b(4)h(0)p 3527 3952 V 369 4072 V 421 4036 a(fet)g(pfet)100 b(59)24 b(25)h(60)f(26)99 b(8)25 b(12)133 b(Vdd!)138 b(Mid2)24 b(4)g Fe(P3)105 b Fg(Vdd#0)24 b(4)h(0)149 b(Out)25 b(4)f(0)p 3527 4072 V 369 4192 V 421 4156 a(fet)h(pfet)100 b(36)24 b(25)h(37)f(26)99 b(8)25 b(12)111 b(VBias)116 b(Mid1)24 b(4)g Fe(P2)105 b Fg(Vdd#0)24 b(4)h(0)116 b(Mid2)24 b(4)h(0)p 3527 4192 V 369 4313 V 421 4277 a(fet)g(pfet)149 b(4)25 b(25)g(5)f(26)149 b(8)25 b(12)99 b(Vdd#0)171 b(In)25 b(4)g Fe(P1)171 b Fg(Vdd#0)24 b(4)h(0)116 b(Mid1)24 b(4)h(0)p 3527 4313 V 371 4316 3158 4 v 1090 4476 a(T)-8 b(able)25 b(1:)31 b(The)24 b(transistor)g(section)g(of)h Fe(tut8l.ext)p Fg(.)146 4798 y(In)30 b(addition)e(to)g(ha)n(ving)h(gate,)h(source,)g (and)f(drain)h(terminals,)f(MOSFET)g(transistors)f(also)h(ha)n(v)o(e)g (a)g(sub-)0 4918 y(strate)i(terminal.)48 b(By)31 b(def)o(ault,)h(this)e (terminal)g(is)g(connected)h(to)f(a)h(global)f(node)h(that)f(depends)h (on)f(the)h(tran-)0 5039 y(sistor')-5 b(s)30 b(type.)49 b(F)o(or)31 b(e)o(xample,)h(p-channel)f(transistors)f(might)g(ha)n(v)o (e)h(a)g(substrate)f(terminal)h(of)g Fe(Vdd!)p Fg(,)j(while)0 5159 y(n-channel)28 b(transistors)f(w)o(ould)g(ha)n(v)o(e)h(one)g(of)g Fe(GND!)p Fg(.)40 b(Ho)n(we)n(v)o(er)l(,)28 b(when)g(a)g(transistor)f (is)h(surrounded)f(by)h(e)o(x-)0 5280 y(plicit)e(\223well\224)h (material)g(\(as)g(de\002ned)h(in)f(the)g(technology)f(\002le\),)i (Magic)f(will)f(o)o(v)o(erride)g(the)h(def)o(ault)g(substrate)0 5400 y(terminal)e(with)f(the)i(node)f(to)g(which)g(the)g(well)g (material)g(is)g(connected.)33 b(This)25 b(has)g(se)n(v)o(eral)g(adv)n (antages:)31 b(it)25 b(al-)1850 5649 y(\22612\226)p eop %%Page: 13 13 13 12 bop 0 -180 a Fg(Magic)24 b(T)l(utorial)g(#8:)30 b(Circuit)25 b(Extraction)1603 b(September)25 b(26,)g(2001)488 2170 y @beginspecial 68 @llx 68 @lly 467 @urx 364 @ury 3510 @rwi @setspecial %%BeginDocument: ../psfigures/tut8.5.ps % % PostScript prolog for output from xcircuit % Version: 2.0 % % Electrical circuit (and otherwise general) drawing program % % Written by Tim Edwards 8/5/93--2/25/99 (tim@bach.ece.jhu.edu) % The Johns Hopkins University % % supporting definitions --- these are the primary xcircuit types. /XCIRCsave save def /topmat matrix currentmatrix def /fontslant { /slant exch def [1 0 slant 1 0 0] exch findfont exch makefont dup length dict /ndict exch def { 1 index /FID ne { ndict 3 1 roll put } { pop pop } ifelse } forall ndict definefont pop} def /cf { dup type /realtype eq {40 mul /fscale exch def} if dup /xfont exch def findfont fscale scalefont setfont } def /Ss { gsave 0.67 dup scale gsave mty neg rmoveto glevel 1 add /glevel exch def } def /ss { gsave 0.67 dup scale gsave mty 0.5 mul rmoveto glevel 1 add /glevel exch def } def /ns { currentpoint transform % preserve x position! glevel {grestore} repeat /glevel 0 def itransform pop currentpoint pop sub 0 rmoveto } def /ul { showflag 1 eq { gsave currentpoint topmat setmatrix 0 0 moveto 2 index stringwidth pop (_) false charpath flattenpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint 3 -1 roll add moveto 0 rlineto stroke moveto } if } def /ol { showflag 1 eq { gsave gsave currentpoint topmat setmatrix 2 index stringwidth pop 3 index true charpath flattenpath pathbbox grestore exch pop exch pop topmat setmatrix (_) true charpath pathbbox grestore exch pop 1 index sub setlinewidth exch pop currentpoint exch 4 1 roll exch sub add moveto pop 0 rlineto stroke moveto } if } def /stW { gsave true charpath flattenpath pathbbox pop exch pop sub grestore } def /bs { stW 0 rmoveto } def /pspc 0 def /qS { (aa) stW (a a) stW sub 4 div 0 rmoveto } def /hS { qS qS } def /textx { dup 1 add copy 0 exch { exch dup type /stringtype eq {stringwidth pop add}{exec} ifelse } repeat neg ns } def /mty { 0 topmat setmatrix (A) true charpath flattenpath pathbbox exch pop exch sub exch pop neg grestore } def /texty { gsave 2 copy pop exec mty } def /tcenter { textx grestore 0.5 mul 0 rmoveto } def /tright { textx grestore fspc sub 0 rmoveto } def /tmiddle { texty 0.5 mul rmoveto } def /ttop { texty fspc sub rmoveto } def /tshow {{ dup type /stringtype eq {show}{exec} ifelse} repeat ns } def /label { gsave translate 0 0 moveto rotate /just exch def just 16 and 0 gt {0 1 dtransform gsave pagemat setmatrix idtransform exch grestore 1 0 dtransform gsave pagemat setmatrix idtransform exch grestore dup 0 eq {pop mul 0 gt} {3 1 roll pop pop 0 lt} ifelse {-1 /just just dup 3 and 1 ne {3 xor} if def} {1} ifelse exch 0 lt {-1 /just just dup 12 and 4 ne {12 xor} if def} {1} ifelse scale } if /glevel 0 def /showflag 0 def /fspc pspc def just 1 and 0 gt {gsave just 2 and 0 gt {tright}{tcenter} ifelse} {fspc 0 rmoveto} ifelse just 4 and 0 gt {just 8 and 0 gt {ttop}{tmiddle} ifelse} {0 fspc rmoveto} ifelse /showflag 1 def tshow grestore } def /pinlabel { hlevel 0 eq { /pspc 20 def label /pspc 0 def } { pop pop pop pop {pop} repeat } ifelse } def /pinglobal { pinlabel } def /infolabel { pinlabel } def /begingate { /hlevel hlevel 1 add def gsave translate 0 0 moveto dup 0 lt {neg 1 sub -1 1 scale} if rotate dup scale } bind def /makeparm {3 string cvs dup length 1 add string /tstr exch def tstr exch 1 exch putinterval tstr 0 (v) putinterval tstr cvn} bind def /beginparm { -1 1 {makeparm exch def} for dup type /arraytype eq { aload length -1 1 {makeparm exch def} for } if begingate } bind def /endgate { /hlevel hlevel 1 sub def grestore } bind def /hlevel 0 def /tmpa [1 0 0 1 0 0] def /gar {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {<30 70 60 02 03 07 06 20>} imagemask} bind {8 8 true tmpa {<0c 1e 1e 0c c0 e1 e1 c0>} imagemask} bind {8 8 true tmpa {<0f 0f 0f 0f f0 f0 f0 f0>} imagemask} bind {8 8 true tmpa {<3f f3 e1 e1 f3 3f 1e 1e>} imagemask} bind {8 8 true tmpa {} imagemask} bind {8 8 true tmpa {} imagemask} bind 7 array astore def /ppaint { gsave clip tmpa dup setmatrix pathbbox neg exch neg 4 2 roll neg 4 -1 roll 2 copy gt {exch} if 8 div ceiling 8 mul 4 2 roll neg 2 copy gt {exch} if 8 div ceiling 8 mul 3 -1 roll -8 5 -1 roll { 3 index exch 5 exch put dup -8 3 index { 3 index exch 4 exch put 3 index exec } for } for pop pop pop pop grestore } bind def /setstyles { currentlinewidth mul setlinewidth /style exch def style 1 and 0 gt not {closepath} if style 2 and 0 gt {currentlinewidth 4 mul dup 2 array astore 0 setdash} if style 4 and 0 gt {0.5 currentlinewidth 4 mul 2 array astore 0 setdash} if style dup 256 ge exch 480 lt and { gsave 1 setgray eofill grestore } if style 16 and 0 gt { gsave style 224 and -5 bitshift dup 7 lt {gar exch get ppaint} { pop eofill } ifelse grestore } if style 8 and 0 gt { newpath } { stroke } ifelse grestore } def /scb { gsave setrgbcolor } bind def /sce { grestore } bind def /polygon { gsave /num exch def moveto num 1 sub {lineto} repeat setstyles } def /xcarc { gsave newpath arc setstyles } def /elb { matrix currentmatrix 7 -1 roll 7 -1 roll translate 5 1 roll 4 -1 roll 3 index div 1 scale } def /ele { 0 4 1 roll 0 4 1 roll } bind def /ellipse { gsave elb newpath ele arc setmatrix setstyles } def /pellip { elb ele arc setmatrix } def /nellip { elb ele arcn setmatrix } def /spline { gsave moveto curveto setstyles } def /polyc { {lineto} repeat } bind def /beginpath { gsave moveto } bind def /endpath { setstyles } bind def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /insertion {/PSobj save def /showpage {} def bop translate} def /end_insert {PSobj restore} def /setpagemat {/pagemat matrix currentmatrix def} def /inchscale {setpagemat 0.375 mul dup scale} def /cmscale {setpagemat 0.35433071 mul dup scale} def % XCircuit output starts here. /arrowhead { % -12 -32 24 36 bbox begingate 8 -28 beginpath 3 -18 3 -15 0 0 curveto -3 -15 -3 -18 -8 -28 curveto -2 -26 2 -26 8 -28 curveto 249 1.00 endpath endgate } def /arrowhead90 { % -20 -12 36 24 bbox begingate 1.00 90 -16 0 arrowhead endgate } def /pgsave save def bop % 916 480 offsets 1.0000 inchscale 2.6000 setlinewidth 1.000 0.000 0.000 scb 240 1.00 260 736 260 800 324 800 324 736 4 polygon 240 1.00 516 736 516 800 580 800 580 736 4 polygon sce 0.439 1.000 0.314 scb 240 1.00 324 800 324 896 516 896 516 800 4 polygon 240 1.00 324 640 324 736 516 736 516 640 4 polygon sce 0.133 0.545 0.133 scb 240 1.00 324 736 324 800 516 800 516 736 4 polygon sce 1.000 0.000 0.000 scb 240 1.00 260 320 260 384 324 384 324 320 4 polygon 240 1.00 516 320 516 384 580 384 580 320 4 polygon sce 0.439 1.000 0.314 scb 240 1.00 324 384 324 512 516 512 516 384 4 polygon 240 1.00 324 192 324 320 516 320 516 192 4 polygon sce 0.133 0.545 0.133 scb 240 1.00 324 320 324 384 516 384 516 320 4 polygon sce 1.000 0.000 0.000 scb 240 1.00 852 736 852 800 916 800 916 736 4 polygon 240 1.00 1012 544 1012 608 1076 608 1076 544 4 polygon sce 0.439 1.000 0.314 scb 240 1.00 916 800 916 896 1172 896 1172 800 4 polygon sce 0.133 0.545 0.133 scb 240 1.00 916 736 916 800 1076 800 1076 736 4 polygon sce 0.439 1.000 0.314 scb 240 1.00 916 608 916 736 1012 736 1012 608 4 polygon sce 0.133 0.545 0.133 scb 240 1.00 1012 608 1012 736 1076 736 1076 608 4 polygon 240 1.00 388 288 388 416 452 416 452 288 4 polygon sce 0.439 1.000 0.314 scb 240 1.00 1076 608 1076 800 1172 800 1172 608 4 polygon sce (6) {/Times-Roman 1.000 cf} 2 21 0 420 928 label (6) {/Times-Roman 1.000 cf} 2 21 0 420 544 label (6) {/Times-Roman 1.000 cf} 2 21 0 1204 704 label (2) {/Times-Roman 1.000 cf} 2 21 0 1044 512 label (2) {/Times-Roman 1.000 cf} 2 21 0 820 768 label (2) {/Times-Roman 1.000 cf} 2 21 0 612 768 label (2) {/Times-Roman 1.000 cf} 2 21 0 612 352 label (1) {/Times-Roman 1.000 cf} 2 25 0 612 464 label (4) {/Times-Roman 1.000 cf} 2 21 0 884 672 label (\(a\)) {/Times-Roman 1.000 cf} 2 21 0 212 768 label (\(c\)) {/Times-Roman 1.000 cf} 2 21 0 212 352 label (\(b\)) {/Times-Roman 1.000 cf} 2 21 0 756 768 label 1 1.00 836 800 804 800 2 polygon 1 1.00 836 736 804 736 2 polygon 1.00 0 820 736 arrowhead 1.00 -181 820 800 arrowhead 1 1.00 1012 528 1012 480 2 polygon 1 1.00 1076 528 1076 480 2 polygon 1 1.00 1188 608 1236 608 2 polygon 1 1.00 1188 800 1236 800 2 polygon 1 1.00 852 608 900 608 2 polygon 1 1.00 596 384 644 384 2 polygon 1 1.00 596 320 644 320 2 polygon 1 1.00 532 416 644 416 2 polygon 1 1.00 596 736 644 736 2 polygon 1 1.00 596 800 644 800 2 polygon 1 1.00 324 912 324 960 2 polygon 1 1.00 516 912 516 960 2 polygon 1 1.00 324 528 324 576 2 polygon 1 1.00 516 528 516 576 2 polygon 1 1.00 452 544 500 544 2 polygon 1 1.00 388 544 340 544 2 polygon 1 1.00 388 928 340 928 2 polygon 1 1.00 452 928 500 928 2 polygon 1 1.00 612 816 612 848 2 polygon 1 1.00 612 720 612 688 2 polygon 1 1.00 820 816 820 864 2 polygon 1 1.00 820 720 820 672 2 polygon 1 1.00 612 400 612 448 2 polygon 1 1.00 612 304 612 256 2 polygon 1 1.00 996 512 948 512 2 polygon 1 1.00 1092 512 1140 512 2 polygon 1 1.00 1204 624 1204 672 2 polygon 1 1.00 1204 736 1204 784 2 polygon 1 1.00 884 640 884 624 2 polygon 1 1.00 884 704 884 720 2 polygon 1.00 0 612 736 arrowhead 1.00 0 612 320 arrowhead 1.00 0 1204 800 arrowhead 1.00 0 884 736 arrowhead 1.00 -181 884 608 arrowhead 1.00 -181 1204 608 arrowhead 1.00 -181 612 800 arrowhead 1.00 -181 612 384 arrowhead 1.00 -181 612 416 arrowhead 1.00 0 340 928 arrowhead90 1.00 0 340 544 arrowhead90 1.00 0 1092 512 arrowhead90 1.00 -1 996 512 arrowhead90 1.00 -1 500 544 arrowhead90 1.00 -1 500 928 arrowhead90 pgsave restore showpage XCIRCsave restore %%EndDocument @endspecial 0 2373 a(Figure)40 b(5:)61 b(\(a\))41 b(When)g (transistors)d(are)j(rectangular)l(,)j(it)c(is)g(possible)f(to)g (compute)h Fd(L=W)54 b Fg(e)o(xactly)-6 b(.)75 b(Here)0 2494 y Fh(gateperim)p Fa(=)37 b(4)p Fg(,)31 b Fh(sr)l(cperim)p Fa(=)37 b(6)p Fg(,)31 b Fh(dr)o(ainperim)p Fa(=)36 b(6)p Fg(,)31 b(and)f Fd(L=W)52 b Fa(=)37 b(2)p Fd(=)p Fa(6)p Fg(.)47 b(\(b\))30 b(The)h Fd(L=W)44 b Fg(of)30 b(non-branching)0 2614 y(transistors)19 b(can)i(be)g(approximated.)28 b(Here)21 b Fh(gateperim)p Fa(=)26 b(4)p Fg(,)21 b Fh(sr)l(cperim)p Fa(=)27 b(6)p Fg(,)22 b Fh(dr)o(ainperim)p Fa(=)j(10)p Fg(.)k(By)21 b(a)n(v)o(eraging)0 2735 y Fh(sr)l(cperim)29 b Fg(and)h Fh(dr)o(ainperim)e Fg(we)i(get)g Fd(L=W)51 b Fa(=)37 b(2)p Fd(=)p Fa(8)p Fg(.)45 b(\(c\))31 b(The)f Fd(L=W)44 b Fg(of)30 b(branching)f(transistors)g(is)g(not)g(well)0 2855 y(approximated.)44 b(Here)31 b Fh(gateperim)p Fa(=)k(16)p Fg(,)30 b Fh(sr)l(cperim)p Fa(=)37 b(2)p Fg(,)30 b Fh(dr)o(ainperim)p Fa(=)35 b(2)p Fg(.)45 b(Magic')-5 b(s)28 b(estimate)h(of)h Fd(L=W)44 b Fg(is)0 2975 y Fa(8)p Fd(=)p Fa(2)p Fg(,)25 b(whereas)h(in)f(f)o(act)h(because)g(of)g(current)g(spreading,)f Fd(W)40 b Fg(is)25 b(ef)n(fecti)n(v)o(ely)f(lar)n(ger)i(than)f Fa(2)h Fg(and)f Fd(L)h Fg(ef)n(fecti)n(v)o(ely)0 3096 y(smaller)e(than)h Fa(8)p Fg(,)f(so)h Fd(L=W)38 b Fg(is)25 b(o)o(v)o(erestimated.)0 3467 y(lo)n(ws)f(simulation)e(of)j(analog)f (circuits)h(in)f(which)g(wells)h(are)g(biased)f(to)h(dif)n(ferent)f (potentials,)f(and)i(it)f(pro)o(vides)0 3587 y(a)31 b(form)f(of)h (checking)f(to)g(ensure)h(that)f(wells)g(in)g(a)h(CMOS)g(process)f(are) h(e)o(xplicitly)e(tied)h(to)g(the)g(appropriate)0 3708 y(DC)25 b(v)n(oltage.)146 3831 y(T)m(ransistor)30 b(substrate)h(nodes)g (are)h(disco)o(v)o(ered)e(by)h(the)h(e)o(xtractor)f(only)f(if)i(the)f (transistor)f(and)i(the)f(o)o(v)o(er)n(-)0 3951 y(lapping)e(well)g (layer)h(are)h(in)e(the)h(same)f(cell.)46 b(If)30 b(the)o(y)f(appear)i (in)e(dif)n(ferent)g(cells,)i(the)f(transistor')-5 b(s)28 b(substrate)0 4071 y(terminal)c(will)g(be)h(set)f(to)h(the)f(def)o (ault)h(for)g(the)g(type)f(of)h(transistor)-5 b(.)146 4194 y(Load)26 b(the)h(cell)f Fe(tut8l)p Fg(,)h(e)o(xtract)f(it,)g(and) g(look)g(at)g(the)g(\002le)h Fe(tut8l.ext)p Fg(.)36 b(T)-8 b(able)26 b(1)g(sho)n(ws)f(the)h(lines)g(for)h(the)f(six)0 4314 y(transistors)21 b(in)i(the)f(\002le.)31 b(Y)-11 b(ou')o(ll)22 b(notice)g(that)h(the)f(substrate)g(terminals)g(\(the)h Fh(Subs)f Fg(column\))g(for)h(all)f(transistors)0 4435 y(are)i(dif)n(ferent.)30 b(Since)25 b(each)f(transistor)f(in)g(this)g (design)g(has)g(a)h(dif)n(ferent)g(gate)f(attrib)n(ute)g(attached)h(to) f(it)g(\(sho)n(wn)0 4555 y(in)h(bold)g(in)h(the)g(table,)f Fh(e)o(.g)o(.)p Fg(,)g Fe(N1)p Fg(,)g Fe(P2)p Fg(,)h(etc\),)g(we')o(ll) g(use)f(them)g(in)h(the)f(follo)n(wing)f(discussion.)146 4678 y(The)j(simplest)e(tw)o(o)i(transistors)f(are)h Fe(N3)g Fg(and)g Fe(P3)p Fg(,)g(which)f(don')n(t)h(appear)g(in)g(an)o (y)f(e)o(xplicitly)f(dra)o(wn)i(wells.)0 4798 y(The)20 b(substrate)f(terminals)g(for)h(these)f(are)i Fe(GND!)e Fg(and)h Fe(Vdd!)30 b Fg(respecti)n(v)o(ely)-6 b(,)19 b(since)g(that')-5 b(s)19 b(what)h(the)f(technology)0 4918 y(\002le)29 b(says)f(is)g(the)h(def)o(ault)f(for)h(the)f(tw)o(o)g (types)g(of)h(transistors.)40 b Fe(N1)29 b Fg(and)f Fe(P1)h Fg(are)g(standard)f(transistors)f(that)h(lie)0 5039 y(in)f(wells)f (tied)g(to)h(the)g(ground)f(and)h(po)n(wer)f(rails,)h(labelled)g(in)f (this)g(cell)h(as)g Fe(Vss#0)f Fg(and)h Fe(Vdd#0)g Fg(respecti)n(v)o (ely)-6 b(.)0 5159 y(\(The)o(y')h(re)29 b(not)g(labelled)g Fe(GND!)g Fg(and)g Fe(Vdd!)45 b Fg(so)29 b(you')o(ll)f(see)i(the)f(dif) n(ference)g(between)g Fe(N1)g Fg(and)h Fe(N3)p Fg(\).)44 b Fe(P2)29 b Fg(lies)0 5280 y(in)h(a)h(well)f(that)g(is)f(tied)h(to)g (a)h(dif)n(ferent)f(bias)g(v)n(oltage,)h Fe(VBias)p Fg(,)g(such)f(as)h (might)e(occur)h(in)g(an)h(analog)f(design.)0 5400 y(Finally)-6 b(,)32 b Fe(N2)g Fg(is)f(in)h(a)g(well)f(that)g(isn')n(t)h(tied)f(to)g (an)o(y)h(wire.)51 b(The)32 b(substrate)f(node)h(appears)g(as)f Fe(Float)h Fg(because)1850 5649 y(\22613\226)p eop %%Page: 14 14 14 13 bop 0 -180 a Fg(September)25 b(26,)f(2001)1604 b(Magic)25 b(T)l(utorial)e(#8:)30 b(Circuit)25 b(Extraction)0 69 y(that')-5 b(s)24 b(the)g(label)h(that)f(w)o(as)h(attached)g(to)f (the)h(well)g(surrounding)e Fe(N2)p Fg(.)146 190 y(The)41 b(ability)f(to)h(e)o(xtract)f(transistor)g(substrate)h(nodes)f(allo)n (ws)g(you)h(to)f(perform)h(a)h(simple)d(check)j(for)0 310 y(whether)34 b(or)h(not)f(transistors)f(are)i(in)f(properly)g (connected)h(\()p Fh(e)o(.g)o(.)p Fg(,)g(grounded\))f(wells.)59 b(In)35 b(a)g(p-well)f(CMOS)0 431 y(process,)24 b(for)g(e)o(xample,)f (you)h(might)e(set)i(the)g(def)o(ault)f(substrate)h(node)f(for)i (n-channel)e(transistors)g(to)h(be)g(some)0 551 y(distinguished)j (global)h(node)i(other)f(than)g(ground,)g Fh(e)o(.g)o(.)p Fg(,)h Fe(NSubstrateNode!)p Fg(.)46 b(Y)-11 b(ou)29 b(could)g(then)g(e) o(xtract)g(the)0 671 y(circuit,)35 b(\003atten)f(it)f(using)g Fh(e)n(xt2spice)g Fg(\(1\))h(\(which)f(preserv)o(es)h(substrate)f (nodes,)i(unlik)o(e)e Fh(e)n(xt2sim)g Fg(\(1\))h(which)0 792 y(ignores)29 b(them\),)h(and)f(look)g(at)g(the)g(substrate)g(node)g (\002elds)g(of)h(all)f(the)g(n-channel)g(transistors:)38 b(if)30 b(there)f(were)0 912 y(an)o(y)21 b(whose)h(substrate)f(nodes)h (weren')n(t)g(connected)g(to)g Fe(GND!)p Fg(,)g(then)f(these)h (transistors)f(appear)h(either)g(outside)0 1033 y(of)h(an)o(y)f(e)o (xplicit)f(well)h(\(their)h(substrate)f(nodes)g(will)g(be)g(the)h(def)o (ault)f(of)h Fe(NSubstrateNode)p Fg(\),)i(or)e(in)f(a)h(well)g(that)0 1153 y(isn')n(t)h(tied)h(to)f Fe(GND!)g Fg(with)g(a)i(substrate)e (contact.)0 1498 y Fi(6)143 b(Extraction)34 b(styles)0 1723 y Fg(Magic)25 b(usually)f(kno)n(ws)h(se)n(v)o(eral)f(dif)n(ferent) h(w)o(ays)h(to)f(e)o(xtract)g(a)g(circuit)h(from)f(a)g(gi)n(v)o(en)f (layout.)32 b(Each)26 b(of)f(these)0 1843 y(w)o(ays)h(is)h(called)f(a)h Fh(style)p Fg(.)36 b(Dif)n(ferent)26 b(styles)g(can)h(be)g(used)f(to)g (handle)h(dif)n(ferent)f(f)o(abrication)g(f)o(acilities,)h(which)0 1964 y(may)36 b(dif)n(fer)g(in)g(the)g(parameters)g(the)o(y)f(ha)n(v)o (e)h(for)h(parasitic)f(capacitance)h(and)f(resistance.)64 b(F)o(or)37 b(a)f(scalable)0 2084 y(technology)-6 b(,)41 b(such)e(as)g(the)g(def)o(ault)g Fe(scmos)p Fg(,)k(there)c(can)h(be)f (a)h(dif)n(ferent)f(e)o(xtraction)f(style)h(for)g(each)h(scale)0 2205 y(f)o(actor)-5 b(.)30 b(The)24 b(e)o(xact)g(number)g(and)g(nature) g(of)g(the)g(e)o(xtraction)f(styles)g(is)h(described)g(in)f(the)h (technology)f(\002le)i(that)0 2325 y(Magic)f(reads)i(when)e(it)h (starts.)30 b(At)24 b(an)o(y)g(gi)n(v)o(en)g(time,)g(there)h(is)f(one)h (current)g(e)o(xtraction)f(style.)146 2446 y(T)-8 b(o)25 b(print)f(a)h(list)f(of)h(the)f(e)o(xtraction)g(styles)g(a)n(v)n (ailable,)g(type)h(the)f(command)900 2681 y Fe(:extract)i(style)p Fg(.)146 2915 y(The)33 b Fe(scmos)g Fg(technology)f(currently)g(has)h (the)g(styles)f Fe(lambda=1.5)p Fg(,)i Fe(lambda=1.0)p Fg(,)h(and)e Fe(lambda=0.6)p Fg(,)0 3036 y(though)28 b(this)g(changes)g(o)o(v)o(er)g(time)g(as)h(technology)f(e)n(v)n(olv)o (es.)41 b(T)-8 b(o)29 b(change)g(the)f(e)o(xtraction)g(style)g(to)h Fh(style)p Fg(,)g(use)0 3156 y(the)c(command)900 3391 y Fe(:extract)h(style)p Fh(style)146 3625 y Fg(Each)31 b(style)e(has)h(a)h(speci\002c)f(scale)g(f)o(actor)h(between)f(Magic)g (units)f(and)h(physical)f(units)g(\()p Fh(e)o(.g)o(.)p Fg(,)h(microns\);)0 3746 y(you)25 b(can')n(t)h(use)f(a)h(particular)f (style)g(with)f(a)i(dif)n(ferent)f(scale)h(f)o(actor)-5 b(.)32 b(T)-8 b(o)25 b(change)h(the)f(scalef)o(actor)l(,)h(you')o(ll)e (ha)n(v)o(e)0 3866 y(to)g(edit)h(the)g(appropriate)f(style)g(in)h(the)g Fe(extract)g Fg(section)f(of)h(the)g(technology)f(\002le.)31 b(This)24 b(process)h(is)f(described)0 3986 y(in)g(\223Magic)h (Maintainer')-5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File.)-7 b(\224)0 4331 y Fi(7)143 b(Flattening)34 b(Extracted)f(Cir)m(cuits)0 4556 y Fg(Unfortunately)-6 b(,)19 b(v)o(ery)g(fe)n(w)h(tools)f(e)o(xist)f(to)i(tak)o(e)f(adv)n (antage)h(of)f(the)h Fh(e)n(xt)g Fg(\(5\))g(format)f(\002les)h (produced)g(by)f(Magic')-5 b(s)0 4677 y(e)o(xtractor)g(.)31 b(T)-8 b(o)25 b(use)g(these)h(\002les)f(for)g(simulation)f(or)h(timing) e(analysis,)i(you)g(will)f(most)g(lik)o(ely)g(need)i(to)f(con)l(v)o (ert)0 4797 y(them)f(to)h(a)g(\003attened)g(format,)f(such)h(as)g Fh(sim)f Fg(\(5\))h(or)g Fh(spice)f Fg(\(5\).)146 4918 y(There)c(are)h(se)n(v)o(eral)d(programs)h(for)h(\003attening)f Fh(e)n(xt)h Fg(\(5\))g(\002les.)29 b Fh(Ext2sim)18 b Fg(\(1\))i(produces)g Fh(sim)f Fg(\(5\))g(\002les)h(suitable)0 5039 y(for)i(use)g(with)f Fh(crystal)h Fg(\(1\),)g Fh(esim)g Fg(\(1\),)h(or)f Fh(r)o(sim)f Fg(\(1\).)30 b Fh(Ext2spice)22 b Fg(\(1\))g(is)f(used)h(to)g(produce)g Fh(spice)g Fg(\(5\))g(\002les)g (for)g(use)0 5159 y(with)h(the)h(circuit-le)n(v)o(el)f(simulator)f Fh(spice)i Fg(\(1\).)30 b(Finally)-6 b(,)23 b Fh(e)n(xtc)o(hec)n(k)i Fg(\(1\))f(can)h(be)f(used)f(to)h(perform)g(connecti)n(vity)0 5280 y(checking)29 b(and)g(will)g(summarize)f(the)h(number)g(of)g (\003attened)h(nodes,)g(transistors,)e(capacitors,)j(and)e(resistors)0 5400 y(in)22 b(a)g(circuit.)30 b(All)21 b(of)h(these)g(programs)g(mak)o (e)g(use)g(of)g(a)g(library)g(kno)n(wn)f(as)h Fh(e)n(xt\003at)g Fg(\(3\),)h(so)f(the)g(con)l(v)o(entions)e(for)1850 5649 y(\22614\226)p eop %%Page: 15 15 15 14 bop 0 -180 a Fg(Magic)24 b(T)l(utorial)g(#8:)30 b(Circuit)25 b(Extraction)1603 b(September)25 b(26,)g(2001)0 68 y(each)30 b(and)g(the)g(checks)g(the)o(y)f(perform)h(are)g (virtually)f(identical.)45 b(The)29 b(documentation)g(for)h Fh(e)n(xtc)o(hec)n(k)g Fg(co)o(v)o(ers)0 189 y(the)25 b(options)e(common)h(to)g(all)g(of)h(these)g(programs.)146 309 y(T)-8 b(o)29 b(see)h(ho)n(w)e Fh(e)n(xt2sim)h Fg(w)o(orks,)h(load) e(the)h(cell)g Fe(tut8n)i Fg(and)e(e)o(xpand)f(all)h(the)g Fe(tutm)h Fg(subcells.)43 b(Notice)29 b(ho)n(w)0 429 y(the)d Fe(GND!)f Fg(b)n(us)g(is)g(completely)g(wired,)h(b)n(ut)f(the)h Fe(Vdd!)34 b Fg(b)n(us)25 b(is)h(in)f(three)h(disconnected)f(pieces.)33 b(No)n(w)25 b(e)o(xtract)0 550 y(e)n(v)o(erything)f(with)h Fe(:extract)p Fg(,)j(then)d(e)o(xit)g(Magic)h(and)g(run)g Fe(ext2sim)g(tut8n)p Fg(.)35 b(Y)-11 b(ou')o(ll)25 b(see)i(the)e(follo) n(wing)f(sort)i(of)0 670 y(output:)300 898 y Fb(***)59 b(Global)g(name)f(Vdd!)119 b(not)59 b(fully)g(connected:)300 1019 y(One)g(portion)f(contains)g(the)h(names:)600 1139 y(left/Vdd!)300 1260 y(The)g(other)g(portion)f(contains)g(the)h(names:) 600 1380 y(center/Vdd!)300 1500 y(I'm)g(merging)f(the)h(two)h(pieces)e (into)h(a)g(single)g(node,)f(but)i(you)300 1621 y(should)e(be)i(sure)f (eventually)e(to)i(connect)g(them)g(in)g(the)g(layout.)300 1861 y(***)g(Global)g(name)f(Vdd!)119 b(not)59 b(fully)g(connected:)300 1982 y(One)g(portion)f(contains)g(the)h(names:)600 2102 y(left/Vdd!)600 2223 y(center/Vdd!)300 2343 y(The)g(other)g(portion)f (contains)g(the)h(names:)600 2463 y(right/Vdd!)300 2584 y(I'm)g(merging)f(the)h(two)h(pieces)e(into)h(a)g(single)g(node,)f(but) i(you)300 2704 y(should)e(be)i(sure)f(eventually)e(to)i(connect)g(them) g(in)g(the)g(layout.)300 2945 y(Memory)f(used:)119 b(56k)146 3173 y Fg(The)25 b(w)o(arning)f(messages)g(are)h(telling)e(you)h(that)g (the)h(global)e(name)i Fe(Vdd!)31 b Fg(isn')n(t)24 b(completely)g (wired)g(in)g(the)0 3294 y(layout.)33 b(The)26 b(\003attener)h(w)o (arns)f(you,)g(b)n(ut)f(goes)h(ahead)g(and)g(connects)g(the)g(pieces)g (together)f(an)o(yw)o(ay)h(to)f(allo)n(w)0 3414 y(you)i(to)f(simulate)g (the)h(circuit)g(as)g(though)f(it)h(had)g(been)g(completely)f(wired.)38 b(The)27 b(output)f(of)h Fh(e)n(xt2sim)g Fg(will)f(be)0 3534 y(three)h(\002les:)34 b Fe(tut8n.sim)p Fg(,)28 b Fe(tut8n.al)p Fg(,)f(and)g Fe(tut8n.nodes)p Fg(;)i(see)e Fh(e)n(xt2sim)f Fg(\(1\))h(or)g Fh(sim)f Fg(\(5\))h(for)g(more)g (information)0 3655 y(on)h(the)h(contents)e(of)i(these)f(\002les.)42 b(\223)p Fe(Magic)28 b(T)-9 b(utorial)29 b(#11:)38 b(Using)28 b(RSIM)h(with)f(Magic)p Fg(\224)h(e)o(xplains)e(ho)n(w)g(to)0 3775 y(use)e(the)f(output)g(of)h Fh(e)n(xt2sim)f Fg(with)g(the)h (switch-le)n(v)o(el)e(simulator)l(,)g Fh(r)o(sim)h Fg(\(1\).)1850 5649 y(\22615\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/addendum6_5.ps0000644000175000001440000004371310751423606016337 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: addendum6_5.dvi %%Pages: 3 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips addendum6_5.dvi -o addendum6_5.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Bold % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (addendum6_5.dvi) @start /Fa 136[72 50 55 33 39 44 55 55 50 55 83 28 2[28 55 50 1[44 55 1[55 50 51[33 41[55 55 2[{ TeXBase1Encoding ReEncodeFont } 22 100.000003 /Times-Bold rf /Fb 138[66 40 47 3[60 66 100 6[40 53 66 53 30[86 2[86 6[40 58[{ TeXBase1Encoding ReEncodeFont } 13 119.999948 /Times-Bold rf /Fc 103[33 1[50 27[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 9[94 72 72 61 55 66 1[55 72 72 89 61 2[33 72 1[55 61 72 66 66 72 6[28 50 1[50 50 50 50 50 50 50 50 28 25 33 25 2[33 33 33 3[50 31[55 55 2[{ TeXBase1Encoding ReEncodeFont }67 100.000003 /Times-Roman rf /Fd 133[39 44 1[66 44 50 28 39 39 1[50 50 50 72 28 2[28 50 50 28 44 50 44 50 50 13[50 38[25 40[50 3[{ TeXBase1Encoding ReEncodeFont }25 100.000003 /Times-Italic rf /Fe 135[72 104 1[80 48 56 64 2[72 80 120 3[40 1[72 48 64 80 64 1[72 10[104 3[104 3[104 135 3[56 2[88 96 104 104 1[104 6[48 3[72 72 72 72 72 72 2[36 46[{ TeXBase1Encoding ReEncodeFont }34 143.999997 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 661 99 a Fe(Magic)35 b(Addendum:)42 b(V)-14 b(ersion)34 b(6.5)h(differ)m(ences)1516 519 y Fd(Stefanos)24 b(Sidir)l(opoulos)1354 940 y Fc(Center)i(for)f(Inte)o(grated)f(Systems)1558 1060 y(Stanford)h(Uni)n(v)o(ersity)1547 1180 y(Stanford,)g(CA)h(94305) 1053 1451 y(This)e(tutorial)g(corresponds)g(to)g(Magic)h(v)o(ersion)e (7.)0 1964 y Fb(Affected)30 b(Documents:)300 2157 y Fc(Magic)24 b(T)l(utorial)g(#6:)30 b(Design-Rule)25 b(Checking)300 2277 y(Magic)f(T)l(utorial)g(#9:)30 b(F)o(ormat)24 b(Con)l(v)o(ersion)g (for)h(CIF)h(and)f(Calma)300 2398 y(Magic)f(T)l(utorial)g(#W)-6 b(-1:)30 b(Design-Rule)24 b(Extensions)300 2518 y(Magic)g(Maintainer') -5 b(s)24 b(Manual)g(#2:)30 b(The)25 b(T)-7 b(echnology)24 b(File)300 2638 y(Magic)g(man)h(pages:)30 b(e)o(xt2sim\(1\),)23 b(e)o(xt2spice\(1\),)h(e)o(xt\003at\(3\),)h(e)o(xt\(5\).)0 3198 y Fe(1)143 b(Intr)m(oduction)0 3421 y Fc(Magic)25 b(6.5)g(has)h(some)e(signi\002cant)h(modi\002cations)f(that)h(mak)o(e)g (some)g(of)h(the)f(original)g(v)o(ersion)f(6)h(documents)0 3542 y(obsolete.)57 b(The)35 b(purpose)e(of)h(this)f(addendum)g(is)h (to)g(highlight)e(these)h(dif)n(ferences)i(so)e(that)h(users)g(can)g (tak)o(e)0 3662 y(adv)n(antage)24 b(of)h(the)g(ne)n(w)f(features.)0 4000 y Fe(2)143 b(Extractor)34 b(Extensions)0 4223 y Fc(The)19 b(6.5)h(e)o(xtractor)f(uses)g(double)f(precision)h (\003oating)g(point)g(numbers)f(to)h(represent)h(capacitances.)29 b(Therefore)0 4344 y(all)f(the)g(capacitances)g(in)g(\(aF/sq-lambda\))g (associated)f(with)h(the)f Fd(ar)l(eacap,)i(perimc,)g(side)o(wall,)e (sideo)o(verlap)0 4464 y Fc(k)o(e)o(yw)o(ords)d(in)g(the)h(e)o(xtract)f (section)g(of)h(the)g(technology)f(\002le)h(can)g(be)g Fd(\003oating)e(point)h(number)o(s)p Fc(.)146 4584 y(Additionally)37 b(the)i(e)o(xtension)f(of)h(the)g(capacitance)h(to)f(\003oating)f (point)g(numbers)h(af)n(fects)g(the)g(manual)0 4705 y(pages)23 b(of)h(e)o(xt2sim\(1\),)d(e)o(xt2spice\(1\),)i(e)o(xt\003at\(3\),)g(e)o (xt\(5\))g(which)g(can)h(be)f(found)g(in)g(your)g(local)g(system)f (under)0 4825 y(CAD)p 216 4825 30 4 v 36 w(HOME/man)146 4946 y(The)31 b(6.5)f(e)o(xtractor)g(shields)f(the)i(perimeter)f (capacitance)h(from)f(layer)h(to)f(layer)-5 b(.)48 b(T)-8 b(o)30 b(f)o(acilitate)g(this)g(tw)o(o)0 5066 y(ne)n(w)c(commands)f Fd(planeor)l(der)-11 b(,)26 b(noplaneor)l(dering)e Fc(ha)n(v)o(e)i (been)h(introduced)e(and)i(the)f Fd(sideo)o(verlap)f Fc(command)0 5186 y(has)g(been)g(modi\002ed.)30 b(The)25 b(syntax)f(for)h(the)f(ne)n(w)h(commands)e(is:)900 5400 y Fa(planeorder)j Fd(plane)f(num)1875 5649 y Fc(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Fc(September)25 b(26,)f(2001)1400 b(Magic)25 b(Addendum:)k(V)-11 b(ersion)25 b(6.5)f(dif)n(ferences)146 68 y(Where)k Fd(plane)e Fc(is)h(one)g(of)g(the)g(de\002ned)g(planes)g (and)g Fd(num)f Fc(is)h(a)g(positi)n(v)o(e)e(inte)o(ger)h(indicating)g (the)g(ordering)0 189 y(of)h(this)g(plane)g(from)g(lo)n(wer)g(to)f (higher)-5 b(.)38 b(So)27 b(for)h(e)o(xample)e(the)h(metal1)g(plane)g (has)g(order)h(3)f(while)g(metal2)f(has)0 309 y(order)f(4.)146 429 y(In)e(case)g(you)f(dont)g(w)o(ant)h(to)f(specify)g(the)h(order)g (of)f(the)h(planes)f(the)h(e)o(xtractor)f(will)g(complain)f(and)i (assume)0 550 y(a)i(def)o(ault)g(one.)30 b(If)c(you)e(w)o(ant)h(to)f (suppress)g(the)h(w)o(arning)f(you)g(just)g(ha)n(v)o(e)h(to)f(issue)g (the)h(k)o(e)o(yw)o(ord:)900 776 y Fa(noplaneordering)146 1003 y Fc(The)g Fd(sideo)o(verlap)f Fc(k)o(e)o(yw)o(ord)g(syntax)g(has) h(been)g(altered)g(to:)900 1229 y Fa(sideo)o(v)o(erlap)g Fd(intypes)f(outtypes)g(o)o(vtypes)h(cap)g(shieldtypes)146 1456 y Fc(where)39 b Fd(intypes)p Fc(,)h Fd(outtypes)p Fc(,)h(and)d Fd(o)o(vtypes)g Fc(are)g(type-lists)f(and)h Fd(cap)g Fc(is)f(capacitance)i(in)f(attof)o(arads)g(per)0 1576 y(lambda.)h(This)26 b(is)i(the)f(capacitance)h(associated)g(with)e (an)i(edge)g(with)f(a)h(type)f(in)g Fd(intypes)g Fc(on)h(its)e(inside)h (and)h(a)0 1697 y(type)i(in)g Fd(outtypes)g Fc(on)g(its)f(outside,)i (that)f(o)o(v)o(erlaps)f(a)h(tile)g(whose)g(type)g(is)g(in)g Fd(o)o(vtypes)p Fc(.)47 b(If)31 b(the)f Fd(shieldtypes)g Fc(is)0 1817 y(present)24 b(ho)n(we)n(v)o(er)f(this)g(shields)g(the)h (capacitance.)32 b(So)24 b(for)h(e)o(xample)e(to)h(shield)f(metal-2)h (to)g(poly)f(capacitance)0 1938 y(use:)900 2164 y Fa(sideo)o(v)o(erlap) i Fc(M2Cap)g(\230M2Cap)g(PolyCap)g(19.41)f(M1Cap)0 2504 y Fe(3)143 b(DRC)35 b(Extensions)0 2727 y Fc(This)30 b(v)o(ersion)f(includes)h(code)h(fragments)f(implemented)f(in)h (DEC-WRL)h(by)g(Don)f(Stark)h(which)f(enable)g(to)0 2847 y(implement)35 b(more)h(complicated)g(DRC)h(rules.)66 b(F)o(or)37 b(a)g(description)e(of)i(these)f(enhancements)g(look)g(in)g (the)0 2968 y(magic)24 b(tutorial)g(#W1)h(which)f(can)h(be)g(found)g (in)f(the)h(\002le)g(doc/tutwrl1.ps)e(under)h(the)h(magic)f(source)h (tree.)0 3307 y Fe(4)143 b(CIF)35 b(extensions)0 3531 y Fc(T)-8 b(w)o(o)22 b(ne)n(w)f(commands)g(ha)n(v)o(e)h(been)g(inte)o (grated)f(in)g(the)h(cif)g(output)f(section)g(courtesy)h(of)g(Ste)n(v)o (en)f(T)-7 b(ell)21 b(and)h(Fred)0 3651 y(Heaton)j(at)f(UNC.)146 3771 y(The)h(\002rst)g(ne)n(w)f(command)g(is)g(a)h(command)f(that)g (enables)h(the)g(generation)f(of)h(DRC)g(correct)h(layers)e(at)h(the)0 3892 y(top)f(le)n(v)o(el)g(\(such)h(as)f(the)h(nwell)f(in)h(the)f (SCMOS)i(tech)f(\002les\).)31 b(The)25 b(syntax)f(is:)900 4118 y Fa(min-width)i Fd(width)146 4345 y Fc(The)39 b(width)e(ar)n (gument)h(is)g(in)g(centimicrons.)69 b(This)38 b(command)f(should)g(be) i(speci\002ed)f(within)f(a)i(layer)0 4465 y(sub-section)24 b(of)h(the)f(cifoutput)g(section)g(of)h(the)g(technology)e(\002le.)146 4586 y(The)i(second)g(command)f(is)g(an)h(e)o(xtension)e(to)i(the)f (squares)h(cif)g(output)e(command.)30 b(Its)25 b(syntax)f(is:)900 4812 y Fa(squar)n(es-grid)i Fd(bor)l(der)e(size)h(separ)o(ation)d(grid) 146 5039 y Fc(The)28 b(added)f(ar)n(gument)h(is)f Fd(grid)p Fc(.)38 b(It)27 b(is)g(in)g(units)g(of)g(centi-microns.)38 b(In)28 b(some)f(technologies,)f(all)i(features)0 5159 y(must)20 b(f)o(all)i(on)f(a)g(speci\002ed)h(grid.)29 b(In)22 b(our)f(case,)i(this)d(w)o(as)i(a)f(.05)g(micron)g(grid.)29 b(In)22 b(the)f(original)g(implementation)0 5280 y(of)28 b(magic,)h(if)g(lambda)e(w)o(as)i(not)f(set)g(to)g(some)g(inte)o(gral)f (multiple)g(of)h(the)g(grid)g(one)h(could)f(generate)h(contacts)0 5400 y(that)g(did)g(not)g(f)o(all)g(on)g(grid)g(boundaries.)44 b(By)30 b(specifying)e(the)i(grid)f(spacing,)h(the)f(ne)n(w)g (enhancement)g(to)g(the)1875 5649 y(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Fc(Magic)24 b(Addendum:)30 b(V)-11 b(ersion)24 b(6.5)g(dif)n(ferences)1401 b(September)25 b(26,)g(2001)0 68 y(contact)35 b(generation)f(code)h(will)f(allo)n(w)f(contacts)i(to)f (be)h(generated)g(on)f(grid.)60 b(This)34 b(does)h(introduce)f(some)0 188 y(problems.)29 b(In)24 b(particular)l(,)f(some)g(odd)g(size)h (contacts)f(will)f(not)h(be)h(able)g(to)f(generate)h(a)f(CIF)i(contact) e(structure)0 309 y(that)30 b(is)h(centered)g(on)g(its)f(corresponding) g(magic)g(contact.)49 b(This)30 b(is)g(not)h(a)g(problem)f(in)g(most)g (cases,)i(e)o(xcept)0 429 y(where)i(an)g(odd)g(size)g(contact)f(is)h (shared)g(between)g(tw)o(o)f(cells.)58 b(In)34 b(this)f(case,)j(the)e (CIF)h(contact)f(strucuture)0 549 y(might)g(be)i(shifted)f(to)g(the)h (left)f(during)g(CIF)i(generation)e(to)g(get)h(it)f(on)g(grid)h(and)f (the)h(other)f(cell)h(might)e(be)0 670 y(shifted)25 b(to)h(the)g (right.)33 b(The)26 b(superposition)e(of)i(these)g(tw)o(o)f(structures) h(may)f(create)i(an)f(ille)o(gal)e(contact)i(size)g(or)0 790 y(spacing.)38 b(Use)28 b(with)e(e)o(xtreme)h(care)i(or)e(combine)g (it)g(with)g(cifwidth)g(and)g(cifspacing)g(rules)g(to)g(v)o(erify)g (correct)0 911 y(operation.)0 1250 y Fe(5)143 b(New)35 b(commands)0 1474 y Fc(Three)25 b(ne)n(w)g(commands)e(ha)n(v)o(e)i (been)g(introduced)f(\(based)h(on)f(the)h(WRL)g(code)g(fragments)f(by)h (Bob)g(Mayo\):)900 1702 y Fa(goto)g Fd(nodename)146 1930 y Fc(Places)h(the)e(box/cross)g(o)o(v)o(er)g(the)h(node)f(named)h Fd(nodename)p Fc(.)900 2159 y Fa(\002ndlabel)h Fd(labelname)146 2387 y Fc(Places)g(the)e(box/cross)g(o)o(v)o(er)g(the)h(label)f Fd(nodename)p Fc(.)900 2615 y Fa(\003atten)i Fd(destname)146 2844 y Fc(Flattens)32 b(the)f(cell)h(in)f(the)g(current)h(layout)f (windo)n(w)f(and)i(places)f(it)h(in)f(the)g(cell)h(named)f Fd(cellname)p Fc(.)51 b(The)0 2964 y(labels)24 b(are)i(changed)f(to)f (retain)h(their)f(hierarchical)i(pre\002x)o(es.)1875 5649 y(\2263\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tut4.ps0000644000175000001440000014261510751423606015145 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: tut4.dvi %%Pages: 8 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips tut4.dvi -o tut4.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Bold % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tut4.dvi) @start /Fa 119[33 13[44 50 50 72 50 55 33 39 44 1[55 50 55 83 28 2[28 55 50 33 44 55 44 1[50 3[33 1[33 2[72 3[66 55 3[78 1[94 4[78 2[66 72 72 1[72 6[33 2[50 2[50 50 50 50 1[28 25 42[55 3[{ TeXBase1Encoding ReEncodeFont }44 100.000003 /Times-Bold rf /Fb 138[66 40 47 53 2[60 66 100 33 2[33 66 2[53 66 53 1[60 12[80 6[113 9[86 8[40 55[66 2[{ TeXBase1Encoding ReEncodeFont }19 119.999948 /Times-Bold rf /Fc 103[33 1[50 1[44 44 10[33 13[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 3[33 1[33 1[72 72 94 1[72 61 55 2[55 72 72 89 3[33 72 72 55 61 72 66 66 72 5[28 28 50 50 50 50 50 50 50 50 50 50 28 25 33 25 2[33 33 33 3[50 31[55 55 2[{ TeXBase1Encoding ReEncodeFont }74 100.000003 /Times-Roman rf /Fd 133[39 44 44 66 1[50 28 39 39 1[50 50 50 72 28 2[28 50 2[44 50 44 50 50 11[72 1[50 3[72 66 3[44 27[25 1[25 2[33 33 37[50 2[{ TeXBase1Encoding ReEncodeFont }30 100.000003 /Times-Italic rf /Fe 136[104 72 80 48 56 64 1[80 72 80 120 40 2[40 80 72 1[64 80 64 80 72 9[143 104 104 96 80 2[88 2[135 3[56 112 1[88 96 104 104 1[104 6[48 72 72 72 72 72 72 72 72 72 13[72 32[80 2[{ TeXBase1Encoding ReEncodeFont }45 143.999997 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 858 101 a Fe(Magic)35 b(T)-13 b(utorial)34 b(#4:)44 b(Cell)35 b(Hierar)m(chies)1618 521 y Fd(J)n(ohn)24 b(Ousterhout)1401 941 y Fc(Computer)g(Science)i(Di)n(vision)1020 1062 y(Electrical)f (Engineering)f(and)h(Computer)f(Sciences)1473 1182 y(Uni)n(v)o(ersity)f (of)i(California)1544 1303 y(Berk)o(ele)o(y)-6 b(,)24 b(CA)h(94720)1448 1573 y Fd(\(Updated)f(by)h(other)o(s,)f(too.\))1053 1843 y Fc(This)g(tutorial)g(corresponds)g(to)g(Magic)h(v)o(ersion)e(7.) 0 2374 y Fb(T)-11 b(utorials)30 b(to)f(r)n(ead)h(\002rst:)300 2580 y Fc(Magic)24 b(T)l(utorial)g(#1:)30 b(Getting)24 b(Started)300 2701 y(Magic)g(T)l(utorial)g(#2:)30 b(Basic)25 b(P)o(ainting)f(and)h(Selection)0 2907 y Fb(Commands)k(intr)n(oduced)j (in)f(this)f(tutorial:)300 3113 y Fc(:array)-6 b(,)25 b(:edit,)f(:e)o(xpand,)f(:\003ush,)i(:getcell,)f(:identify)-6 b(,)23 b(:load,)h(:path,)g(:see,)h(:une)o(xpand)0 3318 y Fb(Macr)n(os)k(intr)n(oduced)i(in)g(this)f(tutorial:)300 3550 y Fc(x,)25 b(X,)f(\210X)0 4453 y Fe(1)143 b(Intr)m(oduction)0 4678 y Fc(In)21 b(Magic,)g(a)g(layout)f(is)h(a)g(hierarchical)g (collection)f(of)h(cells.)29 b(Each)21 b(cell)g(contains)f(three)h (things:)27 b(paint,)21 b(labels,)0 4798 y(and)e(subcells.)28 b(T)l(utorial)18 b(#2)h(sho)n(wed)f(you)h(ho)n(w)f(to)h(create)h(and)g (edit)e(paint)h(and)g(labels.)29 b(This)18 b(tutorial)g(describes)0 4918 y(Magic')-5 b(s)34 b(f)o(acilities)h(for)g(b)n(uilding)f(up)h (cell)g(hierarchies.)62 b(Strictly)35 b(speaking,)i(hierarchical)f (structure)f(isn')n(t)0 5039 y(necessary:)43 b(an)o(y)31 b(design)f(that)g(can)i(be)f(represented)g(hierarchically)g(can)g(also) g(be)g(represented)g(\223\003at\224)h(\(with)0 5159 y(all)c(the)h (paint)f(and)h(labels)f(in)g(a)h(single)f(cell\).)43 b(Ho)n(we)n(v)o(er)l(,)28 b(man)o(y)g(things)f(are)j(greatly)e(impro)o (v)o(ed)f(if)i(you)f(use)h(a)0 5280 y(hierarchical)i(structure,)g (including)e(the)h(ef)n(\002cienc)o(y)g(of)h(the)f(design)f(tools,)i (the)f(speed)g(with)g(which)g(you)g(can)0 5400 y(enter)25 b(the)g(design,)f(and)g(the)h(ease)g(with)f(which)h(you)f(can)h(modify) f(it)g(later)-5 b(.)1875 5649 y(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Fc(September)25 b(26,)f(2001)1671 b(Magic)24 b(T)l(utorial)g(#4:)30 b(Cell)25 b(Hierarchies)0 99 y Fe(2)143 b(Selecting)34 b(and)h(V)-5 b(iewing)34 b(Hierar)m(chical)f (Designs)0 327 y Fc(\223Hierarchical)26 b(structure\224)f(means)g(that) g(each)g(cell)h(can)f(contain)g(other)g(cells)g(as)g(components.)30 b(T)-8 b(o)25 b(look)g(at)g(an)0 447 y(e)o(xample)c(of)h(a)g (hierarchical)g(layout,)g(enter)g(Magic)f(with)h(the)f(shell)g(command) g Fa(magic)h(tut4a)p Fc(.)30 b(The)22 b(cell)g Fa(tut4a)0 567 y Fc(contains)31 b(four)h(subcells)f(plus)g(some)g(blue)g(paint.)51 b(T)-8 b(w)o(o)32 b(of)g(the)g(subcells)f(are)h(instances)f(of)h(cell)g Fa(tut4x)g Fc(and)0 688 y(tw)o(o)f(are)h(instances)f(of)g Fa(tut4y)p Fc(.)51 b(Initially)-6 b(,)31 b(each)h(subcell)f(is)g (displayed)g(in)g Fd(une)n(xpanded)g Fc(form.)50 b(This)30 b(means)0 808 y(that)c(no)g(details)g(of)g(the)g(subcell)g(are)h (displayed;)f(all)g(you)g(see)h(is)f(the)g(cell')-5 b(s)26 b(bounding)f(box,)h(plus)g(tw)o(o)f(names)0 929 y(inside)e(the)h (bounding)f(box.)30 b(The)25 b(top)e(name)h(is)g(the)g(name)h(of)f(the) g(subcell)g(\(the)g(name)g(you)g(w)o(ould)f(type)h(when)0 1049 y(in)l(v)n(oking)f(Magic)i(to)f(edit)h(the)f(cell\).)31 b(The)25 b(cell')-5 b(s)24 b(contents)g(are)i(stored)f(in)f(a)h(\002le) g(with)g(this)e(name)i(plus)f(a)h Fa(.mag)0 1169 y Fc(e)o(xtension.)31 b(The)25 b(bottom)e(name)j(inside)e(each)i(bounding)e(box)g(is)h (called)g(an)h Fd(instance)e(identi\002er)p Fc(,)g(and)i(is)e(used)0 1290 y(to)g(distinguish)f(dif)n(ferent)h(instances)g(of)h(the)g(same)g (subcell.)30 b(Instance)25 b(id')-5 b(s)24 b(are)h(used)g(for)g (routing)f(and)g(circuit)0 1410 y(e)o(xtraction,)g(and)g(are)i (discussed)e(in)g(Section)h(6.)146 1533 y(Subcells)i(can)h(be)f (manipulated)f(using)g(the)h(same)g(selection)g(mechanism)f(that)g(you) h(learned)h(in)e(T)l(utorial)0 1653 y(#2.)33 b(T)-8 b(o)26 b(select)g(a)g(subcell,)f(place)h(the)g(cursor)f(o)o(v)o(er)g(the)h (subcell)f(and)h(type)f Fa(f)h Fc(\(\223)p Fa(f)p Fc(ind)g(cell\224\),) g(which)g(is)f(a)h(macro)0 1773 y(for)33 b Fa(:select)g(cell)p Fc(.)55 b(Y)-11 b(ou)32 b(can)i(also)e(select)h(a)g(cell)g(by)f(typing) g Fa(s)g Fc(when)h(the)g(cursor)f(is)h(o)o(v)o(er)f(a)h(location)f (where)0 1894 y(there')-5 b(s)29 b(no)f(paint;)i Fa(f)f Fc(is)g(probably)f(more)g(con)l(v)o(enient,)h(particularly)f(for)h (cells)g(that)f(are)i(completely)e(co)o(v)o(ered)0 2014 y(with)g(paint.)41 b(When)28 b(you)g(select)h(a)g(cell)f(the)g(box)g (will)g(be)h(set)f(to)g(the)g(cell')-5 b(s)28 b(bounding)f(box,)i(the)f (cell')-5 b(s)28 b(name)0 2135 y(will)d(be)h(highlighted,)e(and)h(a)h (message)g(will)f(be)g(printed)h(on)f(the)h(te)o(xt)e(display)-6 b(.)32 b(All)25 b(the)h(selection)f(operations)0 2255 y(\()p Fa(:mo)o(v)o(e)p Fc(,)h Fa(:copy)p Fc(,)h Fa(:delete)p Fc(,)g(etc.\))34 b(apply)25 b(to)g(subcells.)33 b(T)m(ry)25 b(selecting)g(and)h(mo)o(ving)e(the)h(top)g(subcell)g(in)h Fa(tut4a)p Fc(.)0 2375 y(Y)-11 b(ou)29 b(can)g(also)f(select)h (subcells)f(using)g(area)i(selection)e(\(the)h Fa(a)g Fc(and)f Fa(A)h Fc(macros\):)39 b(an)o(y)28 b(une)o(xpanded)g(subcells) 0 2496 y(that)c(intersect)h(the)f(area)i(of)f(the)g(box)f(will)g(be)h (selected.)146 2618 y(T)-8 b(o)28 b(see)g(what')-5 b(s)28 b(inside)f(a)h(cell)g(instance,)g(you)g(must)f Fd(e)n(xpand)g Fc(it.)40 b(Select)29 b(one)e(of)i(the)e(instances)h(of)g Fa(tut4y)p Fc(,)0 2739 y(then)c(type)h(the)g(command)900 2984 y Fa(:expand)h(toggle)146 3227 y Fc(or)g(in)l(v)n(ok)o(e)f(the)h (macro)f Fa(\210X)h Fc(which)g(is)f(equi)n(v)n(alent.)31 b(This)25 b(causes)h(the)g(internals)f(of)g(that)h(instance)f(of)h Fa(tut4y)0 3347 y Fc(to)g(be)g(displayed.)34 b(If)27 b(you)e(type)h Fa(\210X)g Fc(again,)g(the)g(instance)g(is)g(une)o (xpanded)f(so)h(you)f(only)h(see)g(a)h(bounding)e(box)0 3468 y(again.)50 b(The)31 b Fa(:expand)i(toggle)e Fc(command)f(e)o (xpands)h(all)g(of)g(the)h(selected)f(cells)g(that)g(are)h(une)o (xpanded,)g(and)0 3588 y(une)o(xpands)24 b(all)g(those)g(that)h(are)g (e)o(xpanded.)30 b(T)-8 b(ype)25 b Fa(\210X)g Fc(a)g(third)f(time)g(so) h(that)f Fa(tut4y)h Fc(is)g(e)o(xpanded.)146 3710 y(As)37 b(you)f(can)h(see)g(no)n(w)-6 b(,)38 b Fa(tut4y)f Fc(contains)f(an)g (array)i(of)e Fa(tut4x)h Fc(cells)g(plus)e(some)h(additional)g(paint.) 65 b(In)0 3831 y(Magic,)23 b(an)h(array)g(is)f(a)h(special)f(kind)g(of) h(instance)f(containing)f(multiple)g(copies)h(of)g(the)h(same)f (subcell)g(spaced)0 3951 y(at)k(\002x)o(ed)g(interv)n(als.)37 b(Arrays)27 b(can)h(be)f(one-dimensional)f(or)h(tw)o(o-dimensional.)36 b(The)27 b(whole)g(array)h(is)e(al)o(w)o(ays)0 4072 y(treated)h(as)f(a) h(single)e(instance:)34 b(an)o(y)26 b(command)f(that)h(operates)h(on)f (one)g(element)g(of)h(the)f(array)h(also)f(operates)0 4192 y(on)f(all)h(the)g(other)f(elements)g(simultaneously)-6 b(.)31 b(The)25 b(instance)h(identi\002ers)f(for)h(the)f(elements)g(of) h(the)g(array)g(are)0 4312 y(the)j(same)g(e)o(xcept)f(for)i(an)f(inde)o (x.)42 b(No)n(w)29 b(select)g(one)g(of)g(the)g(elements)f(of)h(the)g (array)h(and)f(e)o(xpand)f(it.)43 b(Notice)0 4433 y(that)24 b(the)h(entire)g(array)g(is)g(e)o(xpanded)f(at)h(the)f(same)h(time.)146 4555 y(When)40 b(you)f(ha)n(v)o(e)h(e)o(xpanded)f(the)g(array)-6 b(,)44 b(you')o(ll)39 b(see)h(that)f(the)h(paint)f(in)g(the)h(top-le)n (v)o(el)e(cell)h Fa(tut4a)i Fc(is)0 4676 y(displayed)23 b(more)g(brightly)g(than)g(the)h(paint)f(in)h(the)f Fa(tut4x)i Fc(instances.)k Fa(T)-9 b(ut4a)25 b Fc(is)e(called)h(the)f Fd(edit)h(cell)p Fc(,)g(because)0 4796 y(its)30 b(contents)f(are)j (currently)e(editable.)48 b(The)30 b(paint)g(in)g(the)h(edit)f(cell)g (is)g(normally)g(displayed)f(more)h(brightly)0 4916 y(than)22 b(other)f(paint)g(to)h(mak)o(e)g(it)f(clear)i(that)e(you)g(can)i (change)f(it.)29 b(As)22 b(long)f(as)h Fa(tut4a)g Fc(is)g(the)f(edit)h (cell,)g(you)f(cannot)0 5037 y(modify)27 b(the)i(paint)e(in)i Fa(tut4x)p Fc(.)42 b(T)m(ry)28 b(erasing)g(paint)g(from)g(the)g(area)i (of)e(one)h(of)f(the)h Fa(tut4x)f Fc(instances:)38 b(nothing)0 5157 y(will)24 b(be)h(changed.)31 b(Section)24 b(4)h(tells)f(ho)n(w)g (to)g(switch)h(the)f(edit)h(cell.)146 5280 y(Place)f(the)f(cursor)g(o)o (v)o(er)f(one)h(of)g(the)f Fa(tut4x)i Fc(array)f(elements)f(again.)30 b(At)22 b(this)g(point,)g(the)h(cursor)g(is)g(actually)0 5400 y(o)o(v)o(er)i(three)h(dif)n(ferent)f(cells:)32 b Fa(tut4x)26 b Fc(\(an)h(element)e(of)h(an)f(array)i(instance)e (within)g Fa(tut4y)p Fc(\),)h Fa(tut4y)g Fc(\(an)h(instance)1875 5649 y(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Fc(Magic)24 b(T)l(utorial)g(#4:)30 b(Cell)25 b(Hierarchies)1671 b(September)25 b(26,)g(2001)0 69 y(within)f Fa(tut4a)p Fc(\),)i(and)g Fa(tut4)p Fc(.)33 b(Ev)o(en)24 b(the)i(topmost)d(cell)j(in)f(the)g(hierarchy)g(is)g(treated)g(as)h(an) f(instance)g(by)h(Magic.)0 189 y(When)35 b(you)g(press)g(the)g Fa(s)g Fc(k)o(e)o(y)g(to)g(select)g(a)h(cell,)h(Magic)e(initially)f (chooses)g(the)i(smallest)d(instance)i(visible)0 309 y(underneath)j(the)h(cursor)l(,)j Fa(tut4x)d Fc(in)f(this)g(case.)73 b(Ho)n(we)n(v)o(er)l(,)40 b(if)f(you)f(in)l(v)n(ok)o(e)g(the)g Fa(s)h Fc(macro)g(again)f(\(or)g(type)0 430 y Fa(:select)p Fc(\))24 b(without)e(mo)o(ving)g(the)h(cursor)l(,)h(Magic)f(will)g (step)g(through)f(all)h(of)h(the)f(instances)g(under)h(the)f(cursor)g (in)0 550 y(order)-5 b(.)31 b(T)m(ry)24 b(this)g(out.)30 b(The)25 b(same)f(is)h(true)f(of)h(the)g Fa(f)g Fc(macro)g(and)g Fa(:select)g(cell)p Fc(.)146 671 y(When)31 b(there)h(are)g(man)o(y)e (dif)n(ferent)g(e)o(xpanded)h(cells)g(on)g(the)g(screen,)i(you)d(can)i (use)f(the)g(selection)f(com-)0 791 y(mands)23 b(to)g(select)g(paint)g (from)h(an)o(y)f(of)g(them.)30 b(Y)-11 b(ou)23 b(can)h(select)f(an)o (ything)f(that')-5 b(s)23 b(visible,)f(re)o(gardless)h(of)h(which)0 912 y(cell)37 b(it')-5 b(s)36 b(in.)68 b(Ho)n(we)n(v)o(er)l(,)39 b(as)f(mentioned)e(abo)o(v)o(e,)j(you)e(can)h(only)e(modify)g(paint)h (in)g(the)g(edit)g(cell.)68 b(If)38 b(you)0 1032 y(use)c Fa(:mo)o(v)o(e)g Fc(or)f Fa(:upsidedo)o(wn)j Fc(or)e(similar)e (commands)h(when)g(you')-5 b(v)o(e)34 b(selected)f(information)g (outside)f(the)0 1153 y(edit)25 b(cell,)g(the)g(information)f(outside)g (the)h(edit)g(cell)g(is)g(remo)o(v)o(ed)f(from)h(the)g(selection)g (before)h(performing)e(the)0 1273 y(operation.)146 1394 y(There)i(are)f(tw)o(o)f(additional)g(commands)f(you)i(can)g(use)g(for) g(e)o(xpanding)e(and)i(une)o(xpanding)e(cells:)900 1626 y Fa(:expand)900 1746 y(:unexpand)146 1978 y Fc(Both)38 b(of)h(these)f(commands)f(operate)h(on)g(the)g(area)h(underneath)f(the) g(box.)70 b(The)39 b Fa(:expand)g Fc(command)0 2099 y(will)30 b(recursi)n(v)o(ely)f(e)o(xpand)i(e)n(v)o(ery)f(cell)h(that)f (intersects)g(the)h(box)f(until)g(there)h(are)g(no)g(une)o(xpanded)f (cells)g(left)0 2219 y(under)e(the)g(box.)39 b(The)28 b Fa(:unexpand)j Fc(command)c(will)g(une)o(xpand)g(e)n(v)o(ery)g(cell)h (whose)f(area)i(intersects)f(the)g(box)0 2339 y(b)n(ut)j(doesn')n(t)f (completely)g(contain)h(it.)49 b(The)32 b(macro)f Fa(x)g Fc(is)g(equi)n(v)n(alent)e(to)i Fa(:expand)p Fc(,)j(and)d Fa(X)g Fc(is)g(equi)n(v)n(alent)e(to)0 2460 y Fa(:unexpand)p Fc(.)k(T)m(ry)24 b(out)g(the)h(v)n(arious)f(e)o(xpansion)f(and)i(une)o (xpansion)e(f)o(acilities)h(on)g Fa(tut4a)p Fc(.)0 2802 y Fe(3)143 b(Manipulating)34 b(Subcells)0 3027 y Fc(There)f(are)f(a)h (fe)n(w)f(other)g(commands,)h(in)e(addition)g(to)h(the)g(selection)f (commands)g(already)i(described,)h(that)0 3147 y(you')o(ll)24 b(need)h(in)f(order)h(to)g(manipulate)f(subcells.)29 b(The)c(command)900 3380 y Fa(:getcell)g Fd(name)146 3611 y Fc(will)f(\002nd)i(the)f(\002le)g Fd(name)p Fa(.mag)f Fc(on)h(disk,)f(read)i(the)f(cell)g(it)f(contains,)h(and)g(create)h(an) f(instance)f(of)i(that)e(cell)0 3732 y(with)j(its)g(lo)n(wer)n(-left)g (corner)i(aligned)e(with)g(the)h(lo)n(wer)n(-left)f(corner)i(of)e(the)h (box.)40 b(Use)27 b(the)h Fa(getcell)g Fc(command)0 3852 y(to)k(get)h(an)g(instance)f(of)h(the)g(cell)f Fa(tut4z)p Fc(.)56 b(After)33 b(the)f Fa(getcell)h Fc(command,)h(the)f(ne)n(w)f (instance)g(is)h(selected)f(so)0 3972 y(you)i(can)i(mo)o(v)o(e)d(it)h (or)h(cop)o(y)g(it)f(or)h(delete)g(it.)60 b(The)35 b Fa(getcell)g Fc(command)e(recognizes)i(additional)f(ar)n(guments)0 4093 y(that)25 b(permit)f(the)h(cell)h(to)e(be)i(positioned)d(using)h (labels)h(and/or)g(e)o(xplicit)f(coordinates.)31 b(See)26 b(the)g Fd(man)e Fc(page)i(for)0 4213 y(details.)146 4334 y(T)-8 b(o)32 b(turn)f(a)i(normal)e(instance)g(into)g(an)h(array) -6 b(,)34 b(select)e(the)g(instance)f(and)h(then)f(in)l(v)n(ok)o(e)h (the)f Fa(:array)h Fc(com-)0 4454 y(mand.)e(It)25 b(has)g(tw)o(o)f (forms:)900 4687 y Fa(:array)h Fd(xsize)g(ysize)900 4807 y Fa(:array)g Fd(xlo)g(xhi)f(ylo)h(yhi)146 5039 y Fc(In)30 b(the)f(\002rst)h(form,)h Fd(xsize)e Fc(indicates)g(ho)n(w)g(man)o(y)f (elements)h(the)g(array)i(should)d(ha)n(v)o(e)h(in)h(the)f (x-direction,)0 5159 y(and)34 b Fd(ysize)g Fc(indicates)g(ho)n(w)f(man) o(y)h(elements)f(it)h(should)f(ha)n(v)o(e)h(in)g(the)g(y-direction.)59 b(The)34 b(spacing)g(between)0 5280 y(elements)25 b(is)g(controlled)g (by)g(the)h(box')-5 b(s)24 b(width)h(\(for)h(the)g(x-direction\))f(and) h(height)e(\(for)j(the)e(y-direction\).)33 b(By)0 5400 y(changing)e(the)h(box)f(size,)j(you)d(can)h(space)g(elements)f(so)h (that)f(the)o(y)g(o)o(v)o(erlap,)h(ab)n(ut,)i(or)e(ha)n(v)o(e)f(gaps)g (between)1875 5649 y(\2263\226)p eop %%Page: 4 4 4 3 bop 0 -180 a Fc(September)25 b(26,)f(2001)1671 b(Magic)24 b(T)l(utorial)g(#4:)30 b(Cell)25 b(Hierarchies)0 68 y(them.)36 b(The)26 b(elements)g(are)i(gi)n(v)o(en)d(indices)h(from)h(0)f(to)h Fd(xsize)p Fc(-1)f(in)g(the)h(x-direction)f(and)h(from)f(0)h(to)f Fd(ysize)p Fc(-1)g(in)0 188 y(the)h(y-direction.)37 b(The)27 b(second)g(form)g(of)g(the)g(command)f(is)g(identical)h(to)f(the)h (\002rst)h(e)o(xcept)e(that)h(the)g(elements)0 309 y(are)36 b(gi)n(v)o(en)e(indices)h(from)g Fd(xlo)h Fc(to)f Fd(xhi)g Fc(in)g(the)g(x-direction)g(and)g(from)h Fd(ylo)f Fc(to)g Fd(yhi)g Fc(in)g(the)h(y-direction.)62 b(T)m(ry)0 429 y(making)24 b(a)h(4x4)f(array)i(out)e(of)h(the)g Fa(tut4z)g Fc(cell)g(with)f(gaps)g(between)h(the)g(cells.)146 553 y(Y)-11 b(ou)19 b(can)h(also)f(in)l(v)n(ok)o(e)f(the)h Fa(:array)h Fc(command)e(on)h(an)g(e)o(xisting)f(array)h(to)g(change)h (the)f(number)g(of)g(elements)0 673 y(or)29 b(spacing.)43 b(Use)28 b(a)i(size)f(of)g(1)f(for)i Fd(xsize)e Fc(or)h Fd(ysize)g Fc(in)g(order)g(to)f(get)h(a)g(one-dimensional)f(array)-6 b(.)43 b(If)29 b(there)g(are)0 794 y(se)n(v)o(eral)d(cells)g(selected,) h(the)g Fa(:array)g Fc(command)e(will)h(mak)o(e)h(each)g(of)f(them)g (into)g(an)h(array)g(of)g(the)g(same)f(size)0 914 y(and)31 b(spacing.)47 b(It)31 b(also)f(w)o(orks)g(on)h(paint)f(and)g(labels:)42 b(if)30 b(paint)g(and)h(labels)f(are)h(selected)g(when)g(you)f(in)l(v)n (ok)o(e)0 1034 y Fa(:array)p Fc(,)f(the)o(y)f(will)f(be)i(copied)e(man) o(y)h(times)f(o)o(v)o(er)g(to)h(create)i(the)e(array)-6 b(.)41 b(T)m(ry)28 b(using)f(the)h(array)h(command)e(to)0 1155 y(replicate)e(a)g(small)f(strip)g(of)h(paint.)0 1516 y Fe(4)143 b(Switching)34 b(the)h(Edit)g(Cell)0 1746 y Fc(At)28 b(an)o(y)f(gi)n(v)o(en)g(time,)g(you)h(are)h(editing)e (the)g(de\002nition)g(of)h(a)h(single)e(cell.)40 b(This)27 b(de\002nition)g(is)h(called)g(the)g Fd(edit)0 1867 y(cell)p Fc(.)i(Y)-11 b(ou)23 b(can)h(modify)f(paint)f(and)i(labels)f(in)g(the)g (edit)g(cell,)h(and)f(you)g(can)h(re-arrange)h(its)e(subcells.)29 b(Y)-11 b(ou)23 b(may)0 1987 y(not)28 b(re-arrange)h(or)g(delete)f(the) g(subcells)g(of)g(an)o(y)g(cells)g(other)g(than)g(the)g(edit)g(cell,)h (nor)f(may)g(you)g(modify)f(the)0 2107 y(paint)j(or)g(labels)g(of)h(an) o(y)f(cells)g(e)o(xcept)g(the)g(edit)h(cell.)47 b(Y)-11 b(ou)30 b(may)-6 b(,)31 b(ho)n(we)n(v)o(er)l(,)g(cop)o(y)f(information) f(from)h(other)0 2228 y(cells)25 b(into)f(the)h(edit)f(cell,)h(using)g (the)f(selection)h(commands.)30 b(T)-8 b(o)25 b(help)g(clarify)g(what)g (is)f(and)h(isn')n(t)g(modi\002able,)0 2348 y(Magic)f(displays)g(the)h (paint)f(of)h(the)f(edit)h(cell)f(in)h(brighter)f(colors)h(than)f (other)h(paint.)146 2472 y(When)h(you)f(rearrange)h(subcells)f(of)g (the)h(edit)f(cell,)g(you)g(aren')n(t)h(changing)f(the)g(subcells)g (themselv)o(es.)31 b(All)0 2592 y(you)26 b(can)h(do)f(is)g(change)h (the)f(w)o(ay)h(the)o(y)e(are)i(used)g(in)f(the)g(edit)g(cell)g (\(location,)h(orientation,)e(etc.\).)36 b(When)27 b(you)0 2713 y(delete)k(a)f(subcell,)i(nothing)d(happens)h(to)g(the)g(\002le)h (containing)e(the)i(subcell;)h(the)f(command)e(merely)h(deletes)0 2833 y(the)25 b(instance)f(from)h(the)f(edit)h(cell.)146 2957 y(Besides)33 b(the)f(edit)g(cell,)i(there)f(is)f(one)h(other)f (special)g(cell)g(in)h(Magic.)53 b(It')-5 b(s)32 b(called)g(the)h Fd(r)l(oot)e(cell)h Fc(and)h(is)0 3077 y(the)26 b(topmost)e(cell)i(in)f (the)h(hierarchy)-6 b(,)25 b(the)h(one)g(you)f(named)h(when)g(you)f (ran)h(Magic)g(\()p Fa(tut4a)g Fc(in)g(this)f(case\).)34 b(As)0 3198 y(you)28 b(will)g(see)g(in)g(T)l(utorial)f(#5,)i(there)g (can)g(actually)f(be)g(se)n(v)o(eral)g(root)g(cells)g(at)h(an)o(y)f(gi) n(v)o(en)f(time,)h(one)g(in)g(each)0 3318 y(windo)n(w)-6 b(.)50 b(F)o(or)31 b(no)n(w)-6 b(,)32 b(there)g(is)g(only)e(a)j(single) d(windo)n(w)h(on)g(the)h(screen,)i(and)d(thus)g(only)g(a)h(single)f (root)g(cell.)0 3438 y(The)23 b(windo)n(w)e(caption)h(at)g(the)h(top)f (of)g(the)h(color)f(display)f(contains)h(the)g(name)h(of)g(the)f(windo) n(w')-5 b(s)21 b(root)h(cell)g(and)0 3559 y(also)i(the)h(name)g(of)g (the)f(edit)h(cell.)146 3682 y(Up)f(until)f(no)n(w)-6 b(,)22 b(the)i(root)g(cell)g(and)f(the)h(edit)g(cell)g(ha)n(v)o(e)f (been)h(the)g(same.)30 b(Ho)n(we)n(v)o(er)l(,)23 b(this)g(need)h(not)f (al)o(w)o(ays)0 3803 y(be)i(the)f(case.)31 b(Y)-11 b(ou)24 b(can)h(switch)e(the)i(edit)f(cell)g(to)g(an)o(y)g(cell)g(in)g(the)g (hierarchy)g(by)h(selecting)e(an)i(instance)f(of)g(the)0 3923 y(de\002nition)g(you')-5 b(d)24 b(lik)o(e)h(to)f(edit,)g(and)h (then)f(typing)g(the)h(command)900 4178 y Fa(:edit)146 4430 y Fc(Use)38 b(this)f(command)f(to)i(switch)f(the)g(edit)g(cell)h (to)f(one)h(of)g(the)f Fa(tut4x)h Fc(instances)f(in)h Fa(tut4a)p Fc(.)69 b(Its)38 b(paint)0 4551 y(brightens,)24 b(while)h(the)g(paint)f(in)h Fa(tut4a)h Fc(becomes)f(dim.)31 b(If)26 b(you)e(w)o(ant)h(to)g(edit)g(an)g(element)g(of)g(an)h(array)-6 b(,)25 b(select)0 4671 y(the)37 b(array)-6 b(,)41 b(place)d(the)f (cursor)g(o)o(v)o(er)g(the)g(element)g(you')-5 b(d)37 b(lik)o(e)g(to)g(edit,)j(then)d(type)g Fa(:edit)p Fc(.)69 b(The)37 b(particular)0 4791 y(element)24 b(underneath)h(the)g(cursor)f (becomes)h(the)g(edit)f(cell.)146 4915 y(When)k(you)g(edit)g(a)g(cell,) h(you)f(are)h(editing)e(the)h(master)g(de\002nition)f(of)h(that)g (cell.)40 b(This)28 b(means)f(that)h(if)g(the)0 5035 y(cell)35 b(is)f(used)g(in)g(se)n(v)o(eral)g(places)h(in)f(your)h (design,)h(the)e(edits)g(will)g(be)h(re\003ected)h(in)e(all)g(those)g (places.)61 b(T)m(ry)0 5156 y(painting)21 b(and)i(erasing)f(in)g(the)g Fa(tut4x)h Fc(cell)g(that)f(you)g(just)f(made)i(the)f(edit)g(cell:)29 b(the)23 b(modi\002cations)e(will)g(appear)0 5276 y(in)j(all)h(of)g (its)f(instances.)146 5400 y(There)i(is)e(a)h(second)g(w)o(ay)g(to)f (change)h(the)g(edit)f(cell.)31 b(This)24 b(is)g(the)h(command)1875 5649 y(\2264\226)p eop %%Page: 5 5 5 4 bop 0 -180 a Fc(Magic)24 b(T)l(utorial)g(#4:)30 b(Cell)25 b(Hierarchies)1671 b(September)25 b(26,)g(2001)900 84 y Fa(:load)g Fd(name)146 522 y Fc(The)e Fa(:load)f Fc(command)g(loads)g (a)h(ne)n(w)f(hierarchy)g(into)g(the)h(windo)n(w)e(underneath)h(the)h (cursor)-5 b(.)29 b Fd(Name)23 b Fc(is)f(the)0 642 y(name)27 b(of)g(the)f(root)h(cell)g(in)f(the)h(hierarchy)-6 b(.)36 b(If)27 b(no)g Fd(name)f Fc(is)h(gi)n(v)o(en,)e(a)j(ne)n(w)e(unnamed)g (cell)h(is)f(loaded)h(and)g(you)0 762 y(start)e(editing)f(from)g (scratch.)32 b(The)25 b Fa(:load)g Fc(command)f(only)g(changes)h(the)g (edit)f(cell)h(if)g(there)h(is)e(not)h(already)g(an)0 883 y(edit)f(cell)h(in)g(another)f(windo)n(w)-6 b(.)0 1413 y Fe(5)143 b(Subcell)35 b(Usage)f(Con)-6 b(v)o(entions)0 1699 y Fc(Ov)o(erlaps)24 b(between)h(cells)g(are)h(occasionally)e (useful)g(to)h(share)g(b)n(usses)f(and)h(control)g(lines)f(running)g (along)g(the)0 1819 y(edges.)46 b(Ho)n(we)n(v)o(er)l(,)30 b(o)o(v)o(erlaps)f(cause)h(the)g(analysis)f(tools)g(to)h(w)o(ork)g (much)f(harder)i(than)e(the)o(y)h(w)o(ould)f(if)h(there)0 1940 y(were)d(no)e(o)o(v)o(erlaps:)32 b(where)n(v)o(er)25 b(cells)h(o)o(v)o(erlap,)f(the)h(tools)f(ha)n(v)o(e)g(to)h(combine)f (the)h(information)e(from)i(the)g(tw)o(o)0 2060 y(separate)e(cells.)30 b(Thus,)23 b(you)f(shouldn')n(t)h(use)g(o)o(v)o(erlaps)f(an)o(y)h(more) g(than)g(absolutely)f(necessary)-6 b(.)30 b(F)o(or)23 b(e)o(xample,)0 2180 y(suppose)f(you)h(w)o(ant)h(to)f(create)h(a)g (one-dimensional)d(array)j(of)g(cells)f(that)g(alternates)g(between)h (tw)o(o)e(cell)i(types,)0 2301 y(A)k(and)g(B:)h(\223)-8 b(AB)m(AB)m(AB)m(AB)m(AB)m(AB\224.)29 b(One)f(w)o(ay)g(to)g(do)g(this)f (is)h(\002rst)g(to)g(mak)o(e)g(an)h(array)g(of)f(A)g(instances)g(with)0 2421 y(lar)n(ge)34 b(gaps)f(between)h(them)f(\(\223)-8 b(A)34 b(A)f(A)h(A)g(A)f(A)-11 b(\224\),)34 b(then)f(mak)o(e)h(an)g (array)g(of)g(B)g(instances)f(with)g(lar)n(ge)h(gaps)0 2542 y(between)f(them)g(\(\223B)i(B)f(B)g(B)g(B)g(B\224\),)g(and)f (\002nally)g(place)h(one)g(array)g(on)f(top)g(of)g(the)g(other)h(so)f (that)g(the)g(B')-5 b(s)0 2662 y(nestle)31 b(in)g(between)g(the)g(A)-11 b(')-5 b(s.)49 b(The)32 b(problem)e(with)g(this)h(approach)g(is)g(that) g(the)g(tw)o(o)f(arrays)i(o)o(v)o(erlap)e(almost)0 2782 y(completely)-6 b(,)32 b(so)g(Magic)g(will)g(ha)n(v)o(e)g(to)g(go)g(to) g(a)g(lot)g(of)g(e)o(xtra)g(w)o(ork)g(to)g(handle)g(the)g(o)o(v)o (erlaps)f(\(in)h(this)g(case,)0 2903 y(there)f(isn')n(t)e(much)h(o)o(v) o(erlap)g(of)g(actual)g(paint,)h(b)n(ut)f(Magic)g(w)o(on')n(t)g(kno)n (w)g(this)f(and)i(will)e(spend)h(a)h(lot)e(of)i(time)0 3023 y(w)o(orrying)23 b(about)g(it\).)29 b(A)24 b(better)f(solution)f (is)h(to)g(create)h(a)g(ne)n(w)f(cell)g(that)g(contains)g(one)g (instance)g(of)g(A)h(and)f(one)0 3144 y(instance)28 b(of)h(B,)g(side)g (by)f(side.)42 b(Then)29 b(mak)o(e)g(an)g(array)g(of)g(the)g(ne)n(w)f (cell.)42 b(This)28 b(approach)h(mak)o(es)g(it)f(clear)h(to)0 3264 y(Magic)24 b(that)h(there)g(isn')n(t)f(an)o(y)g(real)i(o)o(v)o (erlap)d(between)i(the)g(A)-11 b(')-5 b(s)24 b(and)h(B')-5 b(s.)146 3414 y(If)30 b(you)f(do)g(create)h(o)o(v)o(erlaps,)f(you)g (should)f(use)i(the)f(o)o(v)o(erlaps)f(only)g(to)h(connect)h(the)f(tw)o (o)g(cells)g(together)l(,)0 3535 y(and)39 b(not)e(to)i(change)f(their)h (structure.)71 b(This)38 b(means)g(that)g(the)h(o)o(v)o(erlap)e(should) g(not)h(cause)h(transistors)e(to)0 3655 y(appear)l(,)31 b(disappear)l(,)f(or)f(change)h(size.)43 b(The)30 b(result)e(of)i(o)o (v)o(erlapping)d(the)i(tw)o(o)g(subcells)f(should)g(be)h(the)g(same)0 3775 y(electrically)24 b(as)g(if)g(you)f(placed)h(the)g(tw)o(o)g(cells) f(apart)i(and)e(then)h(ran)g(wires)g(to)g(hook)f(parts)h(of)g(one)g (cell)g(to)f(parts)0 3896 y(of)30 b(the)g(other)-5 b(.)46 b(The)31 b(con)l(v)o(ention)d(is)i(necessary)g(in)g(order)h(to)e(be)i (able)f(to)g(do)g(hierarchical)g(circuit)g(e)o(xtraction)0 4016 y(easily)24 b(\(it)h(mak)o(es)f(it)h(possible)e(for)i(each)h (subcell)e(to)g(be)h(circuit-e)o(xtracted)f(independently\).)146 4166 y(Three)33 b(kinds)e(of)h(o)o(v)o(erlaps)f(are)h(\003agged)h(as)f (errors)g(by)g(the)g(design-rule)f(check)o(er)-5 b(.)53 b(First,)33 b(you)f(may)g(not)0 4287 y(o)o(v)o(erlap)24 b(polysilicon)g(in)g(one)i(subcell)e(with)h(dif)n(fusion)f(in)h (another)g(cell)g(in)g(order)h(to)f(create)h(transistors.)31 b(Sec-)0 4407 y(ond,)g(you)f(may)g(not)g(o)o(v)o(erlap)f(transistors)g (or)h(contacts)g(in)g(one)g(cell)h(with)e(dif)n(ferent)h(kinds)g(of)g (transistors)f(or)0 4527 y(contacts)j(in)h(another)g(cell)f(\(there)i (are)f(a)g(fe)n(w)g(e)o(xceptions)f(to)g(this)g(rule)h(in)f(some)g (technologies\).)54 b(Third,)34 b(if)0 4648 y(contacts)h(from)g(dif)n (ferent)g(cells)g(o)o(v)o(erlap,)i(the)o(y)d(must)h(be)g(the)g(same)g (type)g(of)h(contact)f(and)g(must)f(coincide)0 4768 y(e)o(xactly:)29 b(you)24 b(may)f(not)h(ha)n(v)o(e)f(partial)h(o)o(v)o(erlaps.)29 b(This)23 b(rule)h(is)f(necessary)i(in)e(order)h(to)g(guarantee)g(that) f(Magic)0 4889 y(can)i(generate)h(CIF)f(for)h(f)o(abrication.)146 5039 y(Y)-11 b(ou)26 b(will)e(mak)o(e)h(life)h(a)g(lot)e(easier)i(on)g (yourself)f(\(and)g(on)h(Magic\))f(if)g(you)g(spend)g(a)h(bit)f(of)h (time)e(to)h(choose)0 5159 y(a)36 b(clean)h(hierarchical)f(structure.) 64 b(In)37 b(general,)i(the)d(less)f(cell)h(o)o(v)o(erlap)f(the)h (better)-5 b(.)64 b(If)37 b(you)e(use)h(e)o(xtensi)n(v)o(e)0 5280 y(o)o(v)o(erlaps)29 b(you')o(ll)g(\002nd)h(that)f(the)h(tools)f (run)h(v)o(ery)f(slo)n(wly)f(and)i(that)g(it')-5 b(s)29 b(hard)h(to)f(mak)o(e)h(modi\002cations)f(to)g(the)0 5400 y(circuit.)1875 5649 y(\2265\226)p eop %%Page: 6 6 6 5 bop 0 -180 a Fc(September)25 b(26,)f(2001)1671 b(Magic)24 b(T)l(utorial)g(#4:)30 b(Cell)25 b(Hierarchies)0 99 y Fe(6)143 b(Instance)34 b(Identi\002ers)0 328 y Fc(Instance)d (identi\002ers)g(are)h(used)f(to)g(distinguish)e(the)i(dif)n(ferent)g (subcells)f(within)g(a)h(single)g(parent.)50 b(The)31 b(cell)0 448 y(de\002nition)22 b(names)g(cannot)h(be)g(used)f(for)h (this)f(purpose)g(because)h(there)g(could)f(be)h(man)o(y)f(instances)g (of)h(a)g(single)0 568 y(de\002nition.)34 b(Magic)26 b(will)f(create)i(def)o(ault)f(instance)g(id')-5 b(s)25 b(for)i(you)f(when)g(you)f(create)i(ne)n(w)f(instances)g(with)f(the)0 689 y Fa(:get)k Fc(or)g Fa(:copy)g Fc(commands.)40 b(The)29 b(def)o(ault)f(id)g(for)h(an)f(instance)h(will)e(be)i(the)f(name)h(of)f (the)g(de\002nition)g(with)g(a)0 809 y(unique)d(inte)o(ger)g(added)h (on.)33 b(Y)-11 b(ou)26 b(can)g(change)g(an)g(id)f(by)g(selecting)h(an) f(instance)h(\(which)f(must)g(be)h(a)g(child)f(of)0 930 y(the)g(edit)f(cell\))h(and)g(in)l(v)n(oking)e(the)i(command)900 1178 y Fa(:identify)h Fd(ne)o(wid)146 1424 y Fc(where)k Fd(ne)o(wid)f Fc(is)g(the)g(identi\002er)g(you)f(w)o(ould)h(lik)o(e)f (the)h(instance)g(to)g(ha)n(v)o(e.)43 b Fd(Ne)o(wid)30 b Fc(must)e(not)g(already)i(be)0 1544 y(used)25 b(as)f(an)h(instance)g (identi\002er)f(of)h(an)o(y)g(subcell)f(within)f(the)i(edit)f(cell.)146 1667 y(An)o(y)d(node)g(or)g(instance)g(can)h(be)f(described)g(uniquely) f(by)h(listing)f(a)h(path)g(of)h(instance)f(identi\002ers,)g(starting)0 1788 y(from)29 b(the)g(root)f(cell.)44 b(The)29 b(standard)f(form)h(of) g(such)g(names)g(is)g(similar)e(to)i(Unix)f(\002le)i(names.)43 b(F)o(or)29 b(e)o(xample,)0 1908 y(if)f Fa(id1)h Fc(is)f(the)g(name)h (of)f(an)h(instance)f(within)f(the)h(root)g(cell,)h Fa(id2)g Fc(is)f(an)g(instance)h(within)e Fa(id1)p Fc(,)i(and)f Fa(node)i Fc(is)e(a)0 2029 y(node)f(name)h(within)f Fa(id2)p Fc(,)h(then)f Fa(id1/id2/node)h Fc(can)g(be)g(used)g(unambiguously)d (to)i(refer)i(to)e(the)h(node.)39 b(When)0 2149 y(you)24 b(select)h(a)g(cell,)g(Magic)f(prints)g(out)g(the)h(complete)f(path)h (name)f(of)h(the)g(instance.)146 2272 y(Arrays)34 b(are)g(treated)g (specially)-6 b(.)55 b(When)33 b(you)g(use)h Fa(:identify)g Fc(to)f(gi)n(v)o(e)f(an)i(array)g(an)f(instance)g(identi\002er)l(,)0 2392 y(each)h(element)g(of)g(the)g(array)g(is)g(gi)n(v)o(en)e(the)i (instance)f(identi\002er)h(you)f(speci\002ed,)k(follo)n(wed)32 b(by)i(one)g(or)g(tw)o(o)0 2513 y(array)39 b(subscripts)e(enclosed)i (in)f(square)g(brack)o(ets,)k(e.g,)g Fa(id3[2])d Fc(or)g Fa(id4[3][7])p Fc(.)72 b(When)38 b(the)h(array)g(is)f(one-)0 2633 y(dimensional,)31 b(there)h(is)f(a)h(single)e(subscript;)k(when)d (it)g(is)g(tw)o(o-dimensional,)g(the)g(\002rst)h(subscript)e(is)h(for)h (the)0 2753 y(y-dimension)23 b(and)i(the)f(second)h(for)g(the)g (x-dimension.)0 3109 y Fe(7)143 b(Writing)35 b(and)g(Flushing)f(Cells)0 3338 y Fc(When)22 b(you)f(mak)o(e)g(changes)h(to)f(your)h(circuit)f(in) g(Magic,)h(there)g(is)f(no)h(immediate)e(ef)n(fect)i(on)f(the)h(disk)f (\002les)h(that)0 3458 y(hold)f(the)g(cells.)30 b(Y)-11 b(ou)21 b(must)f(e)o(xplicitly)g(sa)n(v)o(e)h(each)h(cell)g(that)f(has) g(changed,)i(using)d(either)i(the)f Fa(:sa)n(v)o(e)g Fc(command)0 3579 y(or)g(the)h Fa(:writeall)f Fc(command.)28 b(Magic)21 b(k)o(eeps)h(track)f(of)h(the)f(cells)g(that)g(ha)n(v)o(e)g (changed)g(since)g(the)h(last)e(time)h(the)o(y)0 3699 y(were)30 b(sa)n(v)o(ed)f(on)g(disk.)44 b(If)30 b(you)f(try)g(to)g(lea) n(v)o(e)g(Magic)g(without)f(sa)n(ving)h(all)g(the)g(cells)h(that)f(ha)n (v)o(e)g(changed,)h(the)0 3819 y(system)24 b(will)h(w)o(arn)h(you)f (and)g(gi)n(v)o(e)f(you)h(a)h(chance)g(to)f(return)h(to)f(Magic)g(to)g (sa)n(v)o(e)g(them.)32 b(Magic)25 b(ne)n(v)o(er)g(\003ushes)0 3940 y(cells)33 b(behind)g(your)g(back,)j(and)d(ne)n(v)o(er)g(thro)n (ws)f(a)o(w)o(ay)h(de\002nitions)f(that)h(it)g(has)g(read)h(in.)56 b(Thus,)35 b(if)f(you)f(edit)0 4060 y(a)f(cell)g(and)g(then)g(use)g Fa(:load)g Fc(to)g(edit)f(another)h(cell,)i(the)e(\002rst)g(cell)g(is)g (still)f(sa)n(v)o(ed)g(in)h(Magic)f(e)n(v)o(en)h(though)f(it)0 4181 y(doesn')n(t)d(appear)h(an)o(ywhere)f(on)g(the)h(screen.)42 b(If)29 b(you)f(then)g(in)l(v)n(ok)o(e)f Fa(:load)i Fc(a)g(second)f (time)f(to)h(go)h(back)f(to)g(the)0 4301 y(\002rst)d(cell,)g(you')o(ll) f(get)g(the)h(edited)f(cop)o(y)-6 b(.)146 4424 y(If)31 b(you)e(decide)h(that)f(you')-5 b(d)29 b(really)h(lik)o(e)f(to)h (discard)f(the)h(edits)f(you')-5 b(v)o(e)29 b(made)h(to)f(a)h(cell)g (and)g(reco)o(v)o(er)f(the)0 4544 y(old)d(v)o(ersion,)g(there)g(are)i (tw)o(o)e(w)o(ays)g(you)g(can)h(do)f(it.)35 b(The)27 b(\002rst)f(w)o(ay)h(is)f(using)f(the)i Fa(\003ush)g Fc(option)e(in)h Fa(:writeall)p Fc(.)0 4665 y(The)f(second)f(w)o(ay)h (is)g(to)f(use)h(the)f(command)900 4913 y Fa(:\003ush)i Fc([)p Fd(cellname)p Fc(])146 5159 y(If)34 b(no)f Fd(cellname)g Fc(is)g(gi)n(v)o(en,)h(then)f(the)g(edit)g(cell)g(is)g(\003ushed.)56 b(Otherwise,)35 b(the)e(cell)g(named)g Fd(cellname)h Fc(is)0 5280 y(\003ushed.)48 b(The)31 b Fa(:\003ush)h Fc(command)e(will)f(e)o(xpunge)h(Magic')-5 b(s)30 b(internal)g(cop)o(y) h(of)f(the)h(cell)g(and)f(replace)i(it)e(with)0 5400 y(the)25 b(disk)f(cop)o(y)-6 b(.)1875 5649 y(\2266\226)p eop %%Page: 7 7 7 6 bop 0 -180 a Fc(Magic)24 b(T)l(utorial)g(#4:)30 b(Cell)25 b(Hierarchies)1671 b(September)25 b(26,)g(2001)146 68 y(When)k(you)f(are)h(editing)e(lar)n(ge)i(chips,)g(Magic)f(may)g(claim) g(that)g(cells)g(ha)n(v)o(e)g(changed)h(e)n(v)o(en)e(though)h(you)0 188 y(ha)n(v)o(en')n(t)h(modi\002ed)f(them.)43 b(Whene)n(v)o(er)28 b(you)h(modify)e(a)j(cell,)g(Magic)e(mak)o(es)h(changes)g(in)g(the)f (parents)h(of)g(the)0 309 y(cell,)24 b(and)f(their)g(parents,)h(and)f (so)g(on)h(up)f(to)g(the)g(root)g(of)h(the)f(hierarchy)-6 b(.)30 b(These)23 b(changes)h(record)g(ne)n(w)f(design-)0 429 y(rule)f(violations,)e(as)i(well)g(as)f(timestamp)f(and)i(bounding) e(box)i(information)e(used)i(by)f(Magic)h(to)f(k)o(eep)h(track)g(of)0 549 y(design)k(changes)h(and)g(enable)f(f)o(ast)h(cell)g(read-in.)37 b(Thus,)26 b(whene)n(v)o(er)h(you)f(change)h(one)g(cell)f(you')o(ll)g (generally)0 670 y(need)f(to)g(write)g(out)g(ne)n(w)g(copies)g(of)g (its)f(parents)h(and)g(grandparents.)32 b(If)26 b(you)e(don')n(t)h (write)g(out)g(the)g(parents,)g(or)0 790 y(if)k(you)g(edit)g(a)g(child) g(\223out)g(of)g(conte)o(xt\224)f(\(by)i(itself,)f(without)f(the)h (parents)g(loaded\),)h(then)f(you')o(ll)f(incur)h(e)o(xtra)0 911 y(o)o(v)o(erhead)i(the)g(ne)o(xt)f(time)h(you)g(try)g(to)g(edit)f (the)i(parents.)50 b(\223T)m(imestamp)29 b(mismatch\224)h(w)o(arnings)h (are)h(printed)0 1031 y(when)f(you')-5 b(v)o(e)31 b(edited)g(cells)h (out)e(of)i(conte)o(xt)e(and)i(then)f(later)h(go)f(back)h(and)f(read)h (in)f(the)h(cell)f(as)h(part)f(of)h(its)0 1151 y(parent.)52 b(These)32 b(aren')n(t)h(serious)e(problems;)j(the)o(y)e(just)f(mean)g (that)h(Magic)g(is)f(doing)g(e)o(xtra)h(w)o(ork)g(to)f(update)0 1272 y(information)23 b(in)i(the)f(parent)h(to)g(re\003ect)h(the)e (child')-5 b(s)24 b(ne)n(w)g(state.)0 1610 y Fe(8)143 b(Sear)m(ch)35 b(P)o(aths)0 1833 y Fc(When)29 b(man)o(y)e(people)i(are) g(w)o(orking)f(on)g(a)h(lar)n(ge)g(design,)g(the)f(design)g(will)g (probably)g(be)h(more)f(manageable)0 1954 y(if)j(dif)n(ferent)g(pieces) h(of)f(it)g(can)h(be)f(located)h(in)f(dif)n(ferent)g(directories)g(of)g (the)g(\002le)h(system.)49 b(Magic)31 b(pro)o(vides)0 2074 y(a)d(simple)f(mechanism)g(for)i(managing)e(designs)g(spread)h(o)o (v)o(er)g(se)n(v)o(eral)f(directories.)40 b(The)29 b(system)e (maintains)0 2195 y(a)33 b Fd(sear)l(c)o(h)f(path)g Fc(that)g(tells)g (which)g(directories)h(to)f(search)h(when)g(trying)e(to)i(read)g(in)f (cells.)54 b(By)33 b(def)o(ault,)h(the)0 2315 y(search)c(path)f(is)h (\223.)-7 b(\224,)31 b(which)e(means)g(that)g(Magic)g(looks)g(only)g (in)g(the)h(w)o(orking)e(directory)-6 b(.)45 b(Y)-11 b(ou)29 b(can)h(change)0 2435 y(the)25 b(path)f(using)g(the)h(command) 900 2654 y Fa(:path)h Fc([)p Fd(sear)l(c)o(hpath)p Fc(])146 2872 y(where)40 b Fd(sear)l(c)o(hpath)e Fc(is)h(the)g(ne)n(w)g(path)g (that)g(Magic)g(should)f(use.)74 b Fd(Sear)l(c)o(hpath)38 b Fc(consists)g(of)h(a)h(list)e(of)0 2992 y(directories)d(separated)h (by)g(colons.)63 b(F)o(or)36 b(e)o(xample,)h(the)f(path)f (\223.:\230ouster/x:a/b\224)g(means)g(that)g(if)h(Magic)g(is)0 3113 y(trying)d(to)g(read)h(in)f(a)h(cell)f(named)g(\223foo\224,)j(it)d (will)g(\002rst)h(look)e(for)i(a)g(\002le)g(named)f(\223foo.mag\224)g (in)h(the)f(current)0 3233 y(directory)-6 b(.)57 b(If)34 b(it)g(doesn')n(t)f(\002nd)h(the)g(\002le)g(there,)i(it)d(will)g(look)g (for)i(a)f(\002le)g(named)f(\223\230ouster/x/foo.mag\224,)i(and)0 3354 y(if)29 b(that)g(doesn')n(t)g(e)o(xist,)g(then)g(it)g(will)f(try)h (\223a/b/foo.mag\224)g(last.)44 b(T)-8 b(o)29 b(\002nd)g(out)g(what)g (the)g(current)h(path)f(is,)g(type)0 3474 y Fa(:path)k Fc(with)f(no)g(ar)n(guments.)53 b(In)32 b(addition)f(to)h(your)g(path,) i(this)d(command)h(will)f(print)h(out)g(the)g(system)f(cell)0 3594 y(library)k(path)g(\(where)i(Magic)e(looks)f(for)i(cells)f(if)h (it)f(can')n(t)h(\002nd)f(them)g(an)o(ywhere)h(in)f(your)g(path\),)j (and)d(the)0 3715 y(system)23 b(search)h(path)g(\(where)g(Magic)g (looks)e(for)j(\002les)f(lik)o(e)f(colormaps)g(and)h(technology)e (\002les)j(if)e(it)h(can')n(t)g(\002nd)0 3835 y(them)g(in)h(your)f (current)h(directory\).)146 3955 y(If)h(you')-5 b(re)25 b(w)o(orking)g(on)g(a)g(lar)n(ge)h(design,)e(you)h(should)f(use)h(the)g (search)h(path)f(mechanism)f(to)h(spread)g(your)0 4076 y(layout)h(o)o(v)o(er)g(se)n(v)o(eral)g(directories.)36 b(A)26 b(typical)g(lar)n(ge)i(chip)e(will)g(contain)g(a)h(fe)n(w)g (hundred)f(cells;)h(if)g(you)f(try)g(to)0 4196 y(place)f(all)f(of)h (them)f(in)g(the)h(same)f(directory)h(there)f(will)g(just)g(be)h(too)f (man)o(y)f(things)h(to)g(manage.)30 b(F)o(or)25 b(e)o(xample,)0 4317 y(place)f(the)g(datapath)g(in)f(one)h(directory)-6 b(,)23 b(the)h(control)f(unit)h(in)f(another)l(,)h(the)g(instruction)e (b)n(uf)n(fer)i(in)g(a)g(third,)f(and)0 4437 y(so)28 b(on.)43 b(T)m(ry)28 b(to)h(k)o(eep)g(the)f(size)h(of)g(each)g (directory)g(do)n(wn)f(to)g(a)h(fe)n(w)g(dozen)g(\002les.)43 b(Y)-11 b(ou)28 b(can)h(place)g(the)g Fa(:path)0 4557 y Fc(command)e(in)h(a)h Fa(.magic)f Fc(\002le)h(in)f(your)g(home)g (directory)g(or)g(the)g(directory)g(you)g(normally)f(run)i(Magic)f (from;)0 4678 y(this)d(will)g(sa)n(v)o(e)h(you)g(from)g(ha)n(ving)f(to) h(retype)g(it)g(each)g(time)g(you)f(start)h(up)g(\(see)g(the)g(Magic)g (man)g(page)g(to)g(\002nd)0 4798 y(out)k(about)f Fa(.magic)h Fc(\002les\).)47 b(If)31 b(all)f(you)f(w)o(ant)h(to)g(do)g(is)g(add)g (another)g(directory)g(onto)f(the)h(end)g(of)h(the)f(search)0 4918 y(path,)24 b(you)h(can)g(use)g(the)f Fa(:addpath)j Fc([)p Fd(dir)l(ectory)p Fc(])e(command.)146 5039 y(Because)c(there)f (is)g(only)f(a)h(single)f(search)i(path)e(that)h(is)f(used)h(e)n(v)o (erywhere)f(in)h(Magic,)g(you)g(must)e(be)i(careful)0 5159 y(not)28 b(to)f(re-use)i(the)f(same)g(cell)g(name)g(in)g(dif)n (ferent)g(portions)e(of)j(the)f(chip.)40 b(A)28 b(common)f(problem)g (with)h(lar)n(ge)0 5280 y(designs)23 b(is)h(that)f(dif)n(ferent)h (designers)f(use)h(the)g(same)g(name)g(for)g(dif)n(ferent)g(cells.)30 b(This)23 b(w)o(orks)h(\002ne)h(as)f(long)f(as)0 5400 y(the)i(designers)g(are)i(w)o(orking)d(separately)-6 b(,)25 b(b)n(ut)g(when)h(the)f(tw)o(o)g(pieces)h(of)g(the)f(design)g (are)h(put)f(together)g(using)1875 5649 y(\2267\226)p eop %%Page: 8 8 8 7 bop 0 -180 a Fc(September)25 b(26,)f(2001)1671 b(Magic)24 b(T)l(utorial)g(#4:)30 b(Cell)25 b(Hierarchies)0 68 y(a)34 b(search)g(path,)i(a)e(single)e(cop)o(y)i(of)g(the)f(cell)h(\(the)g (one)f(that)g(is)h(found)f(\002rst)h(in)f(the)g(search)i(path\))e(gets) g(used)0 188 y(e)n(v)o(erywhere.)146 309 y(There')-5 b(s)34 b(another)g(ca)n(v)o(eat)g(in)g(the)f(use)h(of)g(search)h (paths.)58 b(Magic)33 b(looks)g(for)h(system)f(\002les)h(in)g(\230cad,) j(b)n(ut)0 429 y(sometimes)26 b(it)h(is)h(helpful)f(to)h(put)f(Magic') -5 b(s)27 b(system)f(\002les)i(else)n(where.)40 b(If)29 b(the)e Fa(CAD)p 2977 429 30 4 v 36 w(HOME)g Fc(shell)g(en)l(viron-)0 549 y(ment)35 b(v)n(ariable)g(is)g(set,)j(then)e(Magic)f(uses)g(that)g (as)h(the)g(location)e(of)i(\230cad)g(instead)f(of)h(the)f(location)g (in)g(the)0 670 y(passw)o(ord)28 b(\002le.)44 b(This)28 b(o)o(v)o(errides)f(all)i(uses)f(of)h(\230cad)h(within)d(magic,)j (including)d(the)i(\230cad)g(seen)g(in)g(the)g(search)0 790 y(paths)24 b(printed)g(out)h(by)f Fa(:path)p Fc(.)0 1130 y Fe(9)143 b(Additional)34 b(Commands)0 1353 y Fc(This)c(section)h (describes)g(a)h(fe)n(w)f(additional)f(cell-related)h(commands)f(that)h (you)g(may)g(\002nd)g(useful.)50 b(One)31 b(of)0 1474 y(them)24 b(is)h(the)f(command)900 1702 y Fa(:select)h(sa)n(v)o(e)f Fd(\002le)146 1930 y Fc(This)g(command)g(tak)o(es)h(the)f(selection)g (and)h(writes)g(it)f(to)g(disk)g(as)h(a)g(ne)n(w)f(Magic)h(cell)g(in)f (the)h(\002le)g Fd(\002le)p Fa(.mag)p Fc(.)0 2051 y(Y)-11 b(ou)32 b(can)g(use)g(this)f(command)g(to)h(break)g(up)g(a)g(big)f (\002le)i(into)e(smaller)g(ones,)j(or)e(to)f(e)o(xtract)h(pieces)g (from)g(an)0 2171 y(e)o(xisting)23 b(cell.)146 2291 y(The)i(command)900 2520 y Fa(:dump)h Fd(cellName)f Fc([)p Fd(labelName)p Fc(])146 2748 y(does)h(the)f(opposite)g(of)g Fa(select)h(sa)n(v)o(e)p Fc(:)32 b(it)25 b(copies)g(the)h(contents)f(of)g(cell)h Fd(cellName)g Fc(into)f(the)g(edit)h(cell,)f(such)0 2868 y(that)20 b(the)f(lo)n(wer)n(-left)h(corner)g(of)g(label)g Fd(labelName)g Fc(is)g(at)g(the)f(lo)n(wer)n(-left)h(corner)g(of)g(the) g(box.)29 b(The)20 b(ne)n(w)g(material)0 2989 y(will)h(also)g(be)h (selected.)30 b(This)21 b(command)f(is)i(similar)e(in)i(form)f(to)g (the)h Fa(getcell)g Fc(command)f(e)o(xcept)g(that)g(it)g(copies)0 3109 y(the)j(contents)f(of)h(the)g(cell)g(instead)f(of)h(using)f(the)h (cell)g(as)g(a)h(subcell.)k(There)c(are)g(se)n(v)o(eral)e(forms)g(of)i Fa(dump)p Fc(;)g(see)0 3230 y(the)g Fd(man)f Fc(page)h(for)g(details.) 146 3350 y(The)g(main)f(purpose)g(of)h Fa(dump)h Fc(is)e(to)h(allo)n(w) e(you)i(to)f(create)i(a)f(library)f(of)h(cells)f(representing)h (commonly-)0 3470 y(used)19 b(structures)g(such)g(as)h(standard)f (transistor)f(shapes)i(or)f(special)h(contact)f(arrangements.)29 b(Y)-11 b(ou)19 b(can)h(then)f(de-)0 3591 y(\002ne)24 b(macros)g(that)f(in)l(v)n(ok)o(e)g(the)g Fa(dump)i Fc(command)e(to)g (place)h(the)f(cells.)30 b(The)24 b(result)f(is)g(that)g(a)h(single)f (k)o(e)o(ystrok)o(e)0 3711 y(is)h(all)h(you)f(need)h(to)g(cop)o(y)f (one)h(of)g(them)f(into)g(the)h(edit)f(cell.)146 3831 y(As)35 b(mentioned)e(earlier)l(,)k(Magic)d(normally)f(displays)g(the)i (edit)f(cell)g(in)g(brighter)g(colors)g(than)g(non-edit)0 3952 y(cells.)i(This)26 b(helps)h(to)f(distinguish)e(what)j(is)f (editable)g(from)h(what)g(is)f(not,)h(b)n(ut)f(may)g(mak)o(e)h(it)f (hard)h(for)g(you)f(to)0 4072 y(vie)n(w)e(non-edit)g(paint)g(since)h (it)f(appears)h(paler)-5 b(.)31 b(If)25 b(you)f(type)h(the)f(command) 900 4301 y Fa(:see)h(allSame)146 4529 y Fc(you')o(ll)19 b(turn)h(of)n(f)g(this)f(feature:)29 b(all)19 b(paint)h(e)n(v)o (erywhere)g(will)f(be)h(displayed)f(in)h(the)f(bright)h(colors.)28 b(The)20 b(w)o(ord)0 4649 y Fa(allSame)29 b Fc(must)f(be)h(typed)g (just)f(that)h(w)o(ay)-6 b(,)29 b(with)g(one)g(capital)g(letter)-5 b(.)43 b(If)29 b(you')-5 b(d)29 b(lik)o(e)f(to)h(restore)h(the)e(dif)n (ferent)0 4770 y(display)c(styles,)f(type)i(the)g(command)900 4998 y Fa(:see)g(no)g(allSame)146 5226 y Fc(Y)-11 b(ou)34 b(can)h(also)f(use)g(the)h Fa(:see)g Fc(command)e(to)h(selecti)n(v)o (ely)f(disable)g(display)h(of)g(v)n(arious)f(mask)h(layers)g(in)0 5347 y(order)25 b(to)g(mak)o(e)f(the)h(other)g(ones)f(easier)h(to)g (see.)31 b(F)o(or)24 b(details,)g(read)i(about)e Fa(:see)h Fc(in)g(the)f(Magic)h(man)f(page.)1875 5649 y(\2268\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tuttcl3.ps0000644000175000001440000002526610751423606015651 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software %%Title: tuttcl3.dvi %%Pages: 1 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman %%EndComments %DVIPSWebPage: (www.radicaleye.com) %DVIPSCommandLine: dvips -t letter tuttcl3.dvi -o ../psfiles/tuttcl3.ps %DVIPSParameters: dpi=600, compressed %DVIPSSource: TeX output 2006.04.12:1204 %%BeginProcSet: texc.pro %! /TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin /FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array /BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get }B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr 1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx 0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B /chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ /cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 {2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ 1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put }if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X 1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N /p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ /Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) (LaserWriter 16/600)]{A length product length le{A length product exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end %%EndProcSet %%BeginProcSet: 8r.enc % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndProcSet %%BeginProcSet: texps.pro %! TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type/integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics/Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{ dup sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[exch{dup CharStrings exch known not{pop/.notdef/Encoding true def} if}forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def} def end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tuttcl3.dvi) @start /Fa 105[50 28[50 2[50 50 28 39 33 1[50 50 50 78 28 50 1[28 50 50 1[44 50 44 50 44 11[72 61 55 2[55 2[89 61 1[39 1[72 3[72 2[72 9[50 3[50 50 50 50 1[25 33 25 44[{TeXBase1Encoding ReEncodeFont}39 99.6264 /Times-Roman rf /Fb 134[44 1[66 2[28 39 39 2[50 1[72 3[28 50 3[50 2[50 12[55 1[61 12[61 22[25 46[{TeXBase1Encoding ReEncodeFont}15 99.6264 /Times-Italic rf /Fc 135[72 2[80 48 56 64 1[80 72 80 120 40 2[40 80 72 48 64 80 64 1[72 12[96 5[104 135 7[96 1[104 8[48 6[72 72 72 13[72 32[80 2[{ TeXBase1Encoding ReEncodeFont}29 143.462 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%BeginPaperSize: Letter letter %%EndPaperSize %%EndSetup %%Page: 1 1 1 0 bop 466 101 a Fc(Magic)35 b(Tcl)g(T)-13 b(utorial)34 b(#3:)44 b(Extracting)33 b(and)i(Netlisting)1546 521 y Fb(R.)25 b(T)-5 b(imothy)24 b(Edwar)l(ds)1583 941 y Fa(Space)i(Department)1434 1062 y(Johns)e(Hopkins)g(Uni)n(v)o(ersity) 1391 1182 y(Applied)g(Physics)g(Laboratory)1578 1303 y(Laurel,)h(MD)f(20723)819 1573 y(This)g(tutorial)g(corresponds)g(to)h (Tcl-based)f(Magic)h(v)o(ersion)e(7.2)0 2320 y Fc(1)143 b(T)-13 b(ech)35 b(\002le)g(extensions)e(f)l(or)j(extraction)0 2606 y(2)143 b(Commands)33 b(exttospice)h(and)h(exttosim)1875 5649 y Fa(\2261\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tutscm3.ps0000644000175000001440000005373210751423606015650 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: tutscm3.dvi %%Pages: 2 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips tutscm3.dvi -o tutscm3.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Bold % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet %%BeginProcSet: special.pro TeXDict begin /SDict 200 dict N SDict begin /@SpecialDefaults{/hs 612 N /vs 792 N /ho 0 N /vo 0 N /hsc 1 N /vsc 1 N /ang 0 N /CLIP 0 N /rwiSeen false N /rhiSeen false N /letter{}N /note{}N /a4{}N /legal{}N}B /@scaleunit 100 N /@hscale{@scaleunit div /hsc X}B /@vscale{@scaleunit div /vsc X}B /@hsize{/hs X /CLIP 1 N}B /@vsize{/vs X /CLIP 1 N}B /@clip{ /CLIP 2 N}B /@hoffset{/ho X}B /@voffset{/vo X}B /@angle{/ang X}B /@rwi{ 10 div /rwi X /rwiSeen true N}B /@rhi{10 div /rhi X /rhiSeen true N}B /@llx{/llx X}B /@lly{/lly X}B /@urx{/urx X}B /@ury{/ury X}B /magscale true def end /@MacSetUp{userdict /md known{userdict /md get type /dicttype eq{userdict begin md length 10 add md maxlength ge{/md md dup length 20 add dict copy def}if end md begin /letter{}N /note{}N /legal{} N /od{txpose 1 0 mtx defaultmatrix dtransform S atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{itransform lineto} }{6 -2 roll transform 6 -2 roll transform 6 -2 roll transform{ itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll curveto}}{{ closepath}}pathforall newpath counttomark array astore /gc xdf pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack}if}N /txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 -1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop 90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr 2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 -1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S TR}if}N /cp {pop pop showpage pm restore}N end}if}if}N /normalscale{Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale}if 0 setgray} N /psfts{S 65781.76 div N}N /startTexFig{/psf$SavedState save N userdict maxlength dict begin /magscale true def normalscale currentpoint TR /psf$ury psfts /psf$urx psfts /psf$lly psfts /psf$llx psfts /psf$y psfts /psf$x psfts currentpoint /psf$cy X /psf$cx X /psf$sx psf$x psf$urx psf$llx sub div N /psf$sy psf$y psf$ury psf$lly sub div N psf$sx psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub TR /showpage{}N /erasepage{}N /copypage{}N /p 3 def @MacSetUp}N /doclip{ psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath moveto}N /endTexFig{end psf$SavedState restore}N /@beginspecial{SDict begin /SpecialSave save N gsave normalscale currentpoint TR @SpecialDefaults count /ocount X /dcount countdictstack N}N /@setspecial {CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR }{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury lineto closepath clip}if /showpage{}N /erasepage{}N /copypage{}N newpath }N /@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{ end}repeat grestore SpecialSave restore end}N /@defspecial{SDict begin} N /@fedspecial{end}B /li{lineto}B /rl{rlineto}B /rc{rcurveto}B /np{ /SaveX currentpoint /SaveY X N 1 setlinecap newpath}N /st{stroke SaveX SaveY moveto}N /fil{fill SaveX SaveY moveto}N /ellipse{/endangle X /startangle X /yrad X /xrad X /savematrix matrix currentmatrix N TR xrad yrad scale 0 0 1 startangle endangle arc savematrix setmatrix}N end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tutscm3.dvi) @start /Fa 1 63 df<7000000000000000FC00000000000000FF000000000000007FC0 0000000000001FF000000000000007FC00000000000001FF000000000000007FC0000000 0000001FF000000000000007FE00000000000001FF800000000000007FE0000000000000 1FF800000000000003FE00000000000000FF800000000000003FE00000000000000FF800 000000000003FF00000000000000FFC00000000000003FF00000000000000FFC00000000 000001FF000000000000007FC00000000000001FF000000000000007FC00000000000001 FF000000000000007FC00000000000001FE00000000000001FE00000000000007FC00000 00000001FF00000000000007FC0000000000001FF00000000000007FC0000000000001FF 0000000000000FFC0000000000003FF0000000000000FFC0000000000003FF0000000000 000FF80000000000003FE0000000000000FF80000000000003FE0000000000001FF80000 000000007FE0000000000001FF80000000000007FE0000000000001FF00000000000007F C0000000000001FF00000000000007FC0000000000001FF00000000000007FC000000000 0000FF00000000000000FC0000000000000070000000000000003B3878B44C>62 D E /Fb 1 1 df<7FFFFFFFFFFFFFE0FFFFFFFFFFFFFFF0FFFFFFFFFFFFFFF07FFFFFFF FFFFFFE03C04789A4D>0 D E /Fc 103[33 29[44 50 50 72 50 55 33 39 44 1[55 50 55 83 28 55 2[55 50 1[44 55 44 55 50 10[72 12[39 20[50 1[50 1[50 1[25 33 1[57 50 33 33 33 83 35[55 2[{ TeXBase1Encoding ReEncodeFont }37 100.000003 /Times-Bold rf /Fd 138[66 40 47 53 2[60 66 100 33 2[33 66 2[53 66 53 1[60 12[80 6[113 9[86 8[40 55[66 2[{ TeXBase1Encoding ReEncodeFont }19 119.999948 /Times-Bold rf /Fe 105[50 1[44 44 24[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 7[72 2[72 1[61 55 2[55 72 72 89 3[33 1[72 55 61 72 66 66 72 6[28 50 1[50 50 50 50 50 50 50 50 28 25 33 25 2[33 33 4[50 32[55 2[{ TeXBase1Encoding ReEncodeFont }63 100.000003 /Times-Roman rf /Ff 139[28 1[39 2[50 50 3[28 28 50 2[44 3[50 14[61 3[66 83 35[33 33 40[{ TeXBase1Encoding ReEncodeFont }14 100.000003 /Times-Italic rf /Fg 138[80 48 56 64 2[72 80 1[40 80 1[40 1[72 1[64 80 64 1[72 12[96 80 2[88 2[135 18[48 6[72 72 72 3[48 9[72 35[{ TeXBase1Encoding ReEncodeFont }24 143.999997 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 770 101 a Fg(Magic)35 b(T)-13 b(utorial)34 b(#S-3:)43 b(T)-11 b(ransistor)34 b(stacks)1655 521 y Ff(Rajit)24 b(Manohar)1282 941 y Fe(Department)g(of)h(Computer)f(Science)1271 1062 y(California)h(Institute)f(of)h(T)-7 b(echnology)1534 1182 y(P)o(asadena,)25 b(CA)h(91125)1053 1453 y(This)e(tutorial)g (corresponds)g(to)g(Magic)h(v)o(ersion)e(7.)0 1987 y Fd(T)-11 b(utorials)30 b(to)f(r)n(ead)h(\002rst:)300 2197 y Fe(Magic)24 b(T)l(utorial)g(#S-1:)31 b(The)24 b(scheme)h(command-line)f(interpreter)0 2406 y Fd(Commands)29 b(intr)n(oduced)j(in)f(this)f(tutorial:)300 2616 y Fe(:stack.p,)24 b(:stack.n,)g(:stack.tallp,)f(:stack.talln,)g(:prs.dra)o(w)-6 b(,)24 b(:prs.mgn,)300 2737 y(:prs.talldra)o(w)-6 b(,)23 b(:prs.tallmgn)0 2945 y Fd(Macr)n(os)29 b(intr)n(oduced)i(in)g(this)f (tutorial:)300 3182 y Ff(\(None\))0 4093 y Fg(1)143 b(Stacks)0 4319 y Fe(The)37 b(\002rst)f(step)g(in)h(laying)e(out)h(a)h (gate/operator)f(using)g(magic)g(tends)g(to)g(in)l(v)n(olv)o(e)f(dra)o (wing)h(the)g(transistor)0 4440 y(stacks)h(without)f(an)o(y)h(wiring,)j (labelling)c(all)h(the)h(important)e(nodes)h(in)g(the)g(circuit.)68 b(Since)38 b(the)f(e)o(xtractor)0 4560 y(pretends)24 b(that)f(nodes)h(that)f(ha)n(v)o(e)h(the)g(same)f(label)h(are)h (electrically)e(connected,)i(the)e(e)o(xtracted)h(circuit)g(can)g(be)0 4680 y(simulated)f(using)h(SPICE)i(to)f(obtain)f(some)g(indication)f (of)i(the)g(po)n(wer/speed)f(of)h(the)f(circuit.)146 4802 y Fc(stack.tallp)f Fe(and)g Fc(stack.talln)g Fe(can)g(be)f(used)h (to)f(dra)o(w)h(such)f(transistor)g(stacks)g(and)g(place)h(contacts)g (where)0 4922 y(required.)43 b(These)29 b(tw)o(o)g(functions)f(tak)o(e) h(a)g(transistor)f(width)g(and)h(a)g(list)f(of)h(strings)f(that)g (represent)h(the)g(stack)0 5043 y(as)i(their)f(ar)n(guments,)i(and)e (dra)o(w)h(the)f(stack)h(v)o(ertically)f(\(gates)g(run)g (horizontally\))g(at)h(the)f(current)h(box.)48 b(F)o(or)0 5163 y(e)o(xample,)900 5400 y Fc(\(stack.tallp)25 b(40)g('\(\()1622 5400 y (") show 1622 5400 a 60 w Fc(Vdd)1864 5400 y (") show 1864 5400 a 60 w Fc(\))1983 5400 y (") show 1983 5400 a 59 w Fc(a)2092 5400 y (") show 2092 5400 a 2177 5400 a (") show 2177 5400 a 60 w Fc(b)2292 5400 y (") show 2292 5400 a 85 w Fc(\()2410 5400 y (") show 2410 5400 a 60 w Fc(Inode)2713 5400 y (") show 2713 5400 a 60 w Fc(\))2831 5400 y (") show 2831 5400 a 60 w Fc(d)2946 5400 y (") show 2946 5400 a 85 w Fc(\()3064 5400 y (") show 3064 5400 a 60 w Fc(out)3262 5400 y (") show 3262 5400 a 60 w Fc(\)\)\))1875 5649 y Fe(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Fe(September)25 b(26,)f(2001)1563 b(Magic)25 b(T)l(utorial)e(#S-3:)31 b(T)m(ransistor)24 b(stacks)146 68 y(dra)o(ws)37 b(a)g(v)o(ertical)f(stack)h(of)g(p-transistors)e(with) h(the)h(dif)n(fusion)e(being)h(40)h(lambda)f(wide.)66 b(The)37 b(stack)0 188 y(be)o(gins)28 b(with)h(a)h(contact)f(labelled)h (\223Vdd\224,)g(follo)n(wed)f(by)g(tw)o(o)g(gates)g(labelled)g (\223a\224)i(and)e(\223b\224,)i(follo)n(wed)d(by)i(a)0 309 y(contact)k(labelled)f(\223Inode\224,)j(follo)n(wed)c(by)i(a)g (gate)f(labelled)g(\223d\224,)k(follo)n(wed)32 b(by)i(a)g(contact)f (labelled)g(\223out\224.)0 429 y(Contacts)28 b(are)i(indicated)e(by)g (placing)g(the)g(string)g(for)h(the)f(label)g(in)g(parenthesis.)42 b(Note)28 b(the)g(presence)i(of)e(the)0 549 y(quote)c(that)h(pre)n(v)o (ents)e(the)i(interpreter)g(from)f(attempting)f(to)i(e)n(v)n(aluate)f (the)g(list.)146 670 y(The)g(contact)g(width)f(and)h(contact-gate)f (spacing)h(together)f(amount)g(to)h(more)f(than)h(the)g(spacing)f (between)0 790 y(adjacent)30 b(gates.)47 b(Often)30 b(it)g(is)g (desired)g(to)g(eliminate)f(this)h(e)o(xtra)g(space)h(by)f(jogging)f (the)h(poly)f(wires)i(so)f(that)0 911 y(the)25 b(amount)g(of)h (internal)f(dif)n(fusion)f(capacitance)i(is)f(minimized.)31 b(The)26 b(functions)e Fc(stack.p)j Fe(and)e Fc(stack.n)i Fe(can)0 1031 y(be)e(used)f(to)h(do)f(so.)31 b(T)-8 b(yping)900 1259 y Fc(\(stack.tallp)25 b(40)g('\(\()1622 1259 y (") show 1622 1259 a 60 w Fc(Vdd)1864 1259 y (") show 1864 1259 a 60 w Fc(\))1983 1259 y (") show 1983 1259 a 59 w Fc(a)2092 1259 y (") show 2092 1259 a 2177 1259 a (") show 2177 1259 a 60 w Fc(b)2292 1259 y (") show 2292 1259 a 85 w Fc(\()2410 1259 y (") show 2410 1259 a 60 w Fc(Inode)2713 1259 y (") show 2713 1259 a 60 w Fc(\))2831 1259 y (") show 2831 1259 a 60 w Fc(d)2946 1259 y (") show 2946 1259 a 85 w Fc(\()3064 1259 y (") show 3064 1259 a 60 w Fc(out)3262 1259 y (") show 3262 1259 a 60 w Fc(\)\)\))146 1488 y Fe(will)f(dra)o(w)h(the)f(same)h(stack)g(and)f (jog)h(the)f(poly)g(wires)h(corresponding)f(to)g(the)h(gate)f(for)h (\223d\224.)0 1827 y Fg(2)143 b(Pr)m(oduction)34 b(rules)0 2051 y Fe(The)c(functions)e Fc(prs.draw)j Fe(and)f Fc(prs.mgn)g Fe(can)g(be)g(used)g(to)f(dra)o(w)h(the)f(transistor)g(stacks)g(that)h (implement)e(a)0 2171 y(production)c(rule.)30 b(F)o(or)25 b(instance,)900 2399 y Fc(\(prs.draw)h(40)1467 2399 y (") show 1467 2399 a 60 w Fc(x)f(&)g(y)f Fb(\000)29 b Fa(>)24 b Fc(z-)2067 2399 y (") show 2067 2399 a 61 w Fc(\))146 2628 y Fe(will)33 b(dra)o(w)g(the)g(stack)h(required)f(to)g(implement)f(the)h (speci\002ed)h(production)e(rule)i(with)e(width)h(20.)56 b(The)0 2748 y(function)24 b(tak)o(es)g(a)h(gate)g(width)f(and)g(a)h (single)f(production)g(rule)g(as)h(its)f(ar)n(guments.)30 b(Note)25 b(that)f(the)g(production)0 2868 y(rules)h(must)e(be)i(in)g (ne)o(gation)e(normal)h(form,)g(i.e.,)h(all)f(ne)o(gations)f(must)h(be) h(on)f(v)n(ariables.)146 2989 y(Contacts)32 b(can)h(be)f(shared)h (between)f(operators)g(by)g(pro)o(viding)e(a)j(list)e(of)h(production)f (rules)h(as)g(input)f(to)0 3109 y Fc(prs.mgn)p Fe(,)25 b(as)g(follo)n(ws:)900 3338 y Fc(\(prs.mgn)h(40)e(20)1559 3338 y (") show 1559 3338 a 59 w Fc(x)h(&)g(y)g Fb(\000)j Fa(>)d Fc(z-)2159 3338 y (") show 2159 3338 a 2244 3338 a (") show 2244 3338 a 60 w Fc(u)g(&)g(v)f Fb(\000)29 b Fa(>)24 b Fc(w-)2877 3338 y (") show 2877 3338 a 2962 3338 a (") show 2962 3338 a 60 w Fc(\230x)h(&)g(\230y)g Fb(\000)j Fa(>)d Fc(z+)3653 3338 y (") show 3653 3338 a 59 w Fc(\))146 3566 y Fe(The)g(contact)g(to)f(GND)h(will)f(be)h(shared)g(between)g (the)f(pull-do)n(wn)f(stacks)i(for)g(z)g(and)g(w)-6 b(.)146 3686 y(Both)37 b(production-rule)e(dra)o(wing)g(function)h(ensure)g (that)g(the)g(v)n(ariable)g(order)h(in)f(the)g(production)f(rule)0 3807 y(\(from)g(left)f(to)g(right\))g(corresponds)g(to)h(the)f(gate)g (order)h(in)f(the)h(transistor)e(stacks)h(\(from)h(po)n(wer)f(supply)f (to)0 3927 y(output\).)146 4047 y(It)27 b(is)e(not)h(al)o(w)o(ays)g (possible)f(to)h(directly)f(dra)o(w)h(a)h(production)e(rule)h(in)g(a)h (single)e(stack)h(with)g(no)f(additional)0 4168 y(internal)f(contacts.) 31 b(In)25 b(this)g(case,)g(the)g(function)f(creates)i(an)f(internal)f (node)h(name)g(of)g(the)g(form)g(\223)p 3449 4168 30 4 v 36 w(\224)g(follo)n(wed)0 4288 y(by)j(a)h(number)-5 b(.)41 b(Y)-11 b(ou)28 b(can)h(search)g(for)g(these)g(using)e Fc(\(label.sear)n(ch)2396 4288 y (") show 2396 4288 a 2461 4288 30 4 v 95 w Fc(*)2541 4288 y (") show 2541 4288 a 60 w Fc(\))p Fe(,)i(follo)n(wed)f(by)g Fc(\(label.\002nd-next\))p Fe(.)0 4408 y(T)-8 b(o)25 b(complete)f(the)g(implementation,)f(you)h (will)g(ha)n(v)o(e)g(to)h(wire)g(up)f(these)h(internal)f(contacts)h(as) f(well.)146 4529 y(Both)e Fc(prs.mgn)g Fe(and)g Fc(prs.draw)g Fe(dra)o(w)f(the)h(transistor)e(stacks)h(using)g Fc(stack.p)h Fe(and)g Fc(stack.n)p Fe(.)30 b(The)22 b(v)n(ariants)0 4649 y Fc(prs.tallmgn)j Fe(and)g Fc(prs.talldraw)f Fe(use)h Fc(stack.tallp)g Fe(and)g Fc(stack.talln)g Fe(instead.)1875 5649 y(\2262\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tut3.ps0000644000175000001440000012755210751423606015147 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: tut3.dvi %%Pages: 7 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips tut3.dvi -o tut3.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Bold % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tut3.dvi) @start /Fa 133[44 50 50 72 50 55 33 39 44 1[55 50 55 83 28 1[33 28 55 50 33 44 55 44 55 50 9[100 3[55 72 23[33 50 50 50 50 50 50 50 50 50 50 44[55 55 2[{ TeXBase1Encoding ReEncodeFont }40 100.000003 /Times-Bold rf /Fb 2 63 df<00000000000001C000000000000007E00000000000001FE000000000 00007FC0000000000001FF00000000000007FC0000000000001FF00000000000007FC000 0000000001FF0000000000000FFC0000000000003FF0000000000000FFC0000000000003 FF0000000000000FF80000000000003FE0000000000000FF80000000000003FE00000000 00001FF80000000000007FE0000000000001FF80000000000007FE0000000000001FF000 00000000007FC0000000000001FF00000000000007FC0000000000001FF0000000000000 7FC0000000000000FF00000000000000FF000000000000007FC00000000000001FF00000 0000000007FC00000000000001FF000000000000007FC00000000000001FF00000000000 0007FE00000000000001FF800000000000007FE00000000000001FF800000000000003FE 00000000000000FF800000000000003FE00000000000000FF800000000000003FF000000 00000000FFC00000000000003FF00000000000000FFC00000000000001FF000000000000 007FC00000000000001FF000000000000007FC00000000000001FF000000000000007FC0 0000000000001FE000000000000007E000000000000001C03B3878B44C>60 D<7000000000000000FC00000000000000FF000000000000007FC00000000000001FF000 000000000007FC00000000000001FF000000000000007FC00000000000001FF000000000 000007FE00000000000001FF800000000000007FE00000000000001FF800000000000003 FE00000000000000FF800000000000003FE00000000000000FF800000000000003FF0000 0000000000FFC00000000000003FF00000000000000FFC00000000000001FF0000000000 00007FC00000000000001FF000000000000007FC00000000000001FF000000000000007F C00000000000001FE00000000000001FE00000000000007FC0000000000001FF00000000 000007FC0000000000001FF00000000000007FC0000000000001FF0000000000000FFC00 00000000003FF0000000000000FFC0000000000003FF0000000000000FF8000000000000 3FE0000000000000FF80000000000003FE0000000000001FF80000000000007FE0000000 000001FF80000000000007FE0000000000001FF00000000000007FC0000000000001FF00 000000000007FC0000000000001FF00000000000007FC0000000000000FF000000000000 00FC0000000000000070000000000000003B3878B44C>62 D E /Fc 138[66 40 47 53 2[60 66 100 33 2[33 66 2[53 66 53 1[60 12[80 6[113 9[86 8[40 55[66 2[{ TeXBase1Encoding ReEncodeFont }19 119.999948 /Times-Bold rf /Fd 105[50 1[44 44 24[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 3[33 1[33 1[72 1[94 1[72 61 55 66 1[55 72 72 89 61 2[33 1[72 55 61 72 66 66 72 5[28 28 50 1[50 50 50 50 50 50 50 50 1[25 33 25 2[33 33 33 3[50 31[55 55 2[{ TeXBase1Encoding ReEncodeFont }70 100.000003 /Times-Roman rf /Fe 133[39 44 44 66 1[50 28 39 39 1[50 50 50 1[28 2[28 50 50 1[44 50 44 50 50 8[61 83 1[72 1[50 3[72 4[44 23[50 50 2[25 1[25 2[33 33 40[{ TeXBase1Encoding ReEncodeFont }32 100.000003 /Times-Italic rf /Ff 135[72 104 72 80 48 56 64 2[72 80 1[40 2[40 80 72 48 64 80 64 1[72 9[143 2[96 80 2[88 2[135 3[56 5[104 96 104 6[48 72 72 72 72 72 72 72 72 72 7[48 48 4[72 35[{ TeXBase1Encoding ReEncodeFont }40 143.999997 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 93 101 a Ff(Magic)35 b(T)-13 b(utorial)34 b(#3:)43 b(Adv)o(anced)34 b(P)o(ainting)f(\(W)m(iring)j(and)f(Plo)o(wing\))1618 521 y Fe(J)n(ohn)24 b(Ousterhout)1707 641 y(W)-9 b(alter)24 b(Scott)1401 1062 y Fd(Computer)g(Science)i(Di)n(vision)1020 1182 y(Electrical)f(Engineering)f(and)h(Computer)f(Sciences)1473 1303 y(Uni)n(v)o(ersity)f(of)i(California)1544 1423 y(Berk)o(ele)o(y)-6 b(,)24 b(CA)h(94720)1448 1693 y Fe(\(Updated)f(by)h(other)o(s,)f (too.\))1053 1964 y Fd(This)g(tutorial)g(corresponds)g(to)g(Magic)h(v)o (ersion)e(7.)0 2442 y Fc(T)-11 b(utorials)30 b(to)f(r)n(ead)h(\002rst:) 300 2607 y Fd(Magic)24 b(T)l(utorial)g(#1:)30 b(Getting)24 b(Started)300 2728 y(Magic)g(T)l(utorial)g(#2:)30 b(Basic)25 b(P)o(ainting)f(and)h(Selection)0 2893 y Fc(Commands)k(intr)n(oduced)j (in)f(this)f(tutorial:)300 3059 y Fd(:array)-6 b(,)25 b(:corner)l(,)g(:\002ll,)f(:\003ush,)g(:plo)n(w)-6 b(,)23 b(:straighten,)g(:tool,)h(:wire)0 3225 y Fc(Macr)n(os)29 b(intr)n(oduced)i(in)g(this)f(tutorial:)300 3403 y Fb(<)p Fd(space)p Fb(>)0 4093 y Ff(1)143 b(Intr)m(oduction)0 4317 y Fd(T)l(utorial)20 b(#2)i(sho)n(wed)e(you)h(the)h(basic)f(f)o (acilities)g(for)h(placing)f(paint)g(and)g(labels,)h(selecting,)g(and)f (manipulating)0 4437 y(the)j(things)f(that)h(are)h(selected.)31 b(This)23 b(tutorial)h(describes)g(tw)o(o)g(additional)f(f)o(acilities) g(for)i(manipulating)d(paint:)0 4557 y(wiring)39 b(and)h(plo)n(wing.)73 b(These)40 b(commands)e(aren')n(t)j(absolutely)d(necessary)-6 b(,)43 b(since)d(you)f(can)h(achie)n(v)o(e)f(the)0 4678 y(same)25 b(ef)n(fect)h(with)f(the)g(simpler)f(commands)h(of)g(T)l (utorial)f(#2;)h(ho)n(we)n(v)o(er)l(,)f(wiring)h(and)h(plo)n(wing)d (allo)n(w)i(you)f(to)0 4798 y(perform)31 b(certain)g(kinds)f(of)h (manipulations)d(much)i(more)h(quickly)f(than)g(you)h(could)f (otherwise.)48 b(W)l(iring)31 b(is)0 4918 y(described)d(in)g(Section)h (2;)h(it)e(allo)n(ws)f(you)h(to)g(place)h(wires)f(by)g(pointing)f(at)i (the)f(ends)g(of)h(le)o(gs)e(rather)i(than)f(by)0 5039 y(positioning)i(the)h(box,)j(and)e(also)f(pro)o(vides)g(for)h(con)l(v)o (enient)f(contact)h(placement.)52 b(Plo)n(wing)30 b(is)i(the)g(subject) 0 5159 y(of)k(Section)h(3.)64 b(It)37 b(allo)n(ws)e(you)g(to)h (re-arrange)i(pieces)e(of)g(your)g(circuit)g(without)f(ha)n(ving)h(to)f (w)o(orry)i(about)0 5280 y(design-rule)26 b(violations)g(being)g (created:)36 b(plo)n(wing)26 b(automatically)f(mo)o(v)o(es)h(things)g (out)g(of)i(the)f(w)o(ay)g(to)g(a)n(v)n(oid)0 5400 y(trouble.)1875 5649 y(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Fd(September)25 b(26,)f(2001)671 b(Magic)25 b(T)l(utorial)e(#3:)30 b(Adv)n(anced)24 b(P)o(ainting)g(\(W)l(iring)g (and)h(Plo)n(wing\))0 99 y Ff(2)143 b(W)m(iring)0 345 y Fd(The)24 b(box-and-painting)e(paradigm)i(described)g(in)g(T)l (utorial)e(#2)i(is)g(suf)n(\002cient)f(to)h(create)h(an)o(y)e(possible) g(layout,)0 466 y(b)n(ut)h(it')-5 b(s)24 b(relati)n(v)o(ely)g(inef)n (\002cient)g(since)h(three)g(k)o(e)o(ystrok)o(es)f(are)h(required)g(to) g(paint)f(each)i(ne)n(w)e(area:)32 b(tw)o(o)24 b(b)n(utton)0 586 y(clicks)32 b(to)g(position)e(the)j(box)f(and)g(one)g(more)g(to)g (paint)g(the)g(material.)53 b(This)32 b(section)g(describes)g(a)g(dif)n (ferent)0 707 y(painting)23 b(mechanism)g(based)h(on)g Fe(wir)l(es)p Fd(.)31 b(At)24 b(an)o(y)f(gi)n(v)o(en)g(time,)g(there)i (is)f(a)g(current)h(wiring)e(material)h(and)g(wire)0 827 y(thickness.)55 b(W)l(ith)33 b(the)g(wiring)g(interf)o(ace)h(you)f (can)h(create)g(a)g(ne)n(w)f(area)h(of)g(material)e(with)h(a)h(single)e (b)n(utton)0 947 y(click:)k(this)27 b(paints)g(a)h(straight-line)e(se)o (gment)g(of)i(the)g(current)g(material)f(and)h(width)e(between)i(the)g (end)f(of)h(the)0 1068 y(pre)n(vious)33 b(wire)h(se)o(gment)f(and)i (the)f(cursor)g(location.)58 b(Each)35 b(additional)e(b)n(utton)g (click)h(adds)g(an)g(additional)0 1188 y(se)o(gment.)29 b(The)c(wiring)f(interf)o(ace)i(also)e(mak)o(es)g(it)h(easy)g(for)g (you)f(to)h(place)g(contacts.)0 1599 y Ff(3)143 b(T)-13 b(ools)0 1845 y Fd(Before)33 b(learning)f(about)g(wiring,)h(you')o(ll)e (need)i(to)f(learn)g(about)g(tools.)52 b(Until)31 b(no)n(w)-6 b(,)33 b(when)f(you')-5 b(v)o(e)31 b(pressed)0 1965 y(mouse)36 b(b)n(uttons)f(in)h(layout)f(windo)n(ws)g(the)h(b)n(uttons)f(ha)n(v)o (e)h(caused)h(the)f(box)g(to)g(change)g(or)h(material)f(to)g(be)0 2086 y(painted.)e(The)26 b(truth)g(is)f(that)h(b)n(uttons)f(can)h(mean) g(dif)n(ferent)g(things)f(at)h(dif)n(ferent)g(times.)34 b(The)26 b(meaning)f(of)h(the)0 2206 y(mouse)d(b)n(uttons)f(depends)i (on)f(the)h Fe(curr)l(ent)f(tool)p Fd(.)30 b(Each)24 b(tool)f(is)g(identi\002ed)g(by)h(a)g(particular)g(cursor)f(shape)h (and)0 2327 y(a)h(particular)g(interpretation)f(of)h(the)f(mouse)g(b)n (uttons.)30 b(Initially)-6 b(,)23 b(the)h(current)h(tool)f(is)h(the)f (box)h(tool;)f(when)g(the)0 2447 y(box)f(tool)g(is)h(acti)n(v)o(e)e (the)i(cursor)g(has)g(the)f(shape)h(of)g(a)g(crosshair)-5 b(.)30 b(T)-8 b(o)23 b(get)h(information)e(about)h(the)h(current)g (tool,)0 2567 y(you)g(can)i(type)e(the)h(long)f(command)900 2884 y Fa(:tool)h(inf)n(o)146 3190 y Fd(This)33 b(command)f(prints)g (out)h(the)f(name)h(of)h(the)f(current)g(tool)f(and)h(the)g(meaning)g (of)g(the)g(b)n(uttons.)54 b(Run)0 3310 y(Magic)24 b(on)h(the)g(cell)f Fa(tut3a)i Fd(and)e(type)h Fa(:tool)f(inf)n(o)p Fd(.)146 3442 y(The)h Fa(:tool)g Fd(command)f(can)h(also)f(be)h(used)g(to)f (switch)g(tools.)30 b(T)m(ry)24 b(this)g(out)g(by)h(typing)e(the)i (command)900 3759 y Fa(:tool)146 4065 y Fd(Magic)e(will)f(print)g(out)g (a)i(message)e(telling)g(you)g(that)g(you')-5 b(re)24 b(using)d(the)i(wiring)f(tool,)g(and)h(the)g(cursor)g(will)0 4185 y(change)k(to)f(an)h(arro)n(w)g(shape.)36 b(Use)27 b(the)f Fa(:tool)h(inf)n(o)f Fd(command)g(to)g(see)h(what)g(the)f(b)n (uttons)f(mean)i(no)n(w)-6 b(.)35 b(Y)-11 b(ou')o(ll)0 4305 y(be)27 b(using)f(the)g(wiring)h(tool)e(for)j(most)d(of)i(the)g (rest)g(of)g(this)e(section.)37 b(The)26 b(macro)h(\223)g(\224)h (\(space\))f(corresponds)f(to)0 4426 y Fa(:tool)p Fd(.)k(T)m(ry)22 b(typing)f(the)h(space)h(k)o(e)o(y)f(a)h(fe)n(w)f(times:)28 b(Magic)22 b(will)g(c)o(ycle)g(circularly)g(through)g(all)g(of)h(the)f (a)n(v)n(ailable)0 4546 y(tools.)38 b(There)28 b(are)g(three)g(tools)f (in)g(Magic)g(right)g(no)n(w:)36 b(the)27 b(box)g(tool,)h(which)f(you)g (already)h(kno)n(w)f(about,)g(the)0 4667 y(wiring)c(tool,)g(which)g (you')o(ll)g(learn)h(about)f(in)h(this)f(tutorial,)f(and)i(the)g (netlist)e(tool,)h(which)g(has)h(a)g(square)g(cursor)0 4787 y(shape)g(and)g(is)g(used)g(for)g(netlist)f(editing.)30 b(\223T)l(utorial)23 b(#7:)29 b(Netlists)23 b(and)h(Routing\224)g(will) f(sho)n(w)g(you)h(ho)n(w)f(to)h(use)0 4907 y(the)h(netlist)e(tool.)146 5039 y(The)j(current)f(tool)g(af)n(fects)g(only)f(the)i(meanings)e(of)h (the)g(mouse)g(b)n(uttons.)30 b(It)c(does)f(not)f(change)i(the)f(mean-) 0 5159 y(ings)35 b(of)i(the)e(long)h(commands)f(or)h(macros.)64 b(This)36 b(means,)i(for)f(e)o(xample,)h(that)d(you)h(can)h(still)d (use)i(all)g(the)0 5280 y(selection)26 b(commands)f(while)h(the)g (wiring)g(tool)f(is)h(acti)n(v)o(e.)35 b(Switch)26 b(tools)f(to)h(the)g (wiring)g(tool,)g(point)f(at)i(some)0 5400 y(paint)d(in)h Fa(tut3a)p Fd(,)g(and)g(type)f(the)h Fa(s)f Fd(macro.)31 b(A)25 b(chunk)f(gets)h(selected)f(just)g(as)h(it)g(does)f(with)g(the)h (box)f(tool.)1875 5649 y(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Fd(Magic)24 b(T)l(utorial)g(#3:)30 b(Adv)n(anced)24 b(P)o(ainting)g(\(W)l(iring)g(and)h(Plo)n(wing\))670 b(September)25 b(26,)g(2001)0 99 y Ff(4)143 b(Basic)35 b(W)m(iring)0 329 y Fd(There)d(are)g(three)g(basic)g(wiring)e (commands:)43 b(selecting)31 b(the)g(wiring)g(material,)i(adding)e(a)h (le)o(g,)g(and)g(adding)0 449 y(a)c(contact.)41 b(This)27 b(section)g(describes)h(the)g(\002rst)g(tw)o(o)g(commands.)39 b(At)28 b(this)f(point)g(you)g(should)g(be)h(editing)f(the)0 569 y(cell)h Fa(tut3a)g Fd(with)f(the)h(wiring)f(tool)g(acti)n(v)o(e.) 38 b(The)28 b(\002rst)g(step)f(in)h(wiring)f(is)g(to)g(pick)h(the)g (material)f(and)h(width)e(to)0 690 y(use)h(for)h(wires.)38 b(This)27 b(can)h(be)f(done)g(in)g(tw)o(o)g(w)o(ays.)39 b(The)27 b(easiest)g(w)o(ay)g(is)g(to)g(\002nd)h(a)g(piece)f(of)h (material)f(of)g(the)0 810 y(right)f(type)h(and)g(width,)f(point)g(to)h (it)f(with)g(the)h(cursor)l(,)g(and)g(click)g(the)g(left)g(mouse)f(b)n (utton.)36 b(T)m(ry)26 b(this)g(in)h Fa(tut3a)0 930 y Fd(by)g(pointing)f(to)i(the)f(label)h Fa(1)g Fd(and)f(left-clicking.)39 b(Magic)27 b(prints)g(out)g(the)h(material)f(and)h(width)f(that)g(it)g (chose,)0 1051 y(selects)22 b(a)h(square)g(of)f(that)g(material)g(and)h (width)e(around)i(the)f(cursor)l(,)h(and)f(places)h(the)f(box)g(around) h(the)f(square.)0 1171 y(T)m(ry)i(pointing)f(to)i(v)n(arious)e(places)i (in)g Fa(tut3a)g Fd(and)g(left-clicking.)146 1295 y(Once)k(you')-5 b(v)o(e)27 b(selected)h(the)h(wiring)e(material,)h(the)g(right)g(b)n (utton)f(paints)g(le)o(gs)g(of)i(a)f(wire.)41 b(Left-click)28 b(on)0 1415 y(label)d Fa(1)g Fd(to)f(select)h(the)g(red)g(material,)g (then)g(mo)o(v)o(e)e(the)i(cursor)g(o)o(v)o(er)f(label)h Fa(2)g Fd(and)g(right-click.)30 b(This)25 b(will)f(paint)0 1535 y(a)j(red)g(wire)g(between)g Fa(1)g Fd(and)f Fa(2)p Fd(.)37 b(The)27 b(ne)n(w)f(wire)h(le)o(g)f(is)h(selected)f(so)h(that)f (you)h(can)g(modify)f(it)g(with)g(selection)0 1656 y(commands,)e(and)h (the)g(box)g(is)g(placed)h(o)o(v)o(er)e(the)h(tip)g(of)g(the)g(le)o(g)g (to)g(sho)n(w)f(you)h(the)g(starting)f(point)g(for)i(the)f(ne)o(xt)0 1776 y(wire)30 b(le)o(g.)46 b(Add)30 b(more)g(le)o(gs)f(to)h(the)g (wire)g(by)g(right-clicking)e(at)i Fa(3)g Fd(and)g(then)g Fa(4)p Fd(.)47 b(Use)30 b(the)g(mouse)f(b)n(uttons)f(to)0 1897 y(paint)c(another)h(wire)g(in)f(blue)h(from)f Fa(5)h Fd(to)f Fa(6)h Fd(to)g Fa(7)p Fd(.)146 2020 y(Each)34 b(le)o(g)f(of)h(a)g(wire)f(must)g(be)h(either)f(horizontal)g(or)g(v)o (ertical.)57 b(If)34 b(you)f(mo)o(v)o(e)f(the)h(cursor)h(diagonally)-6 b(,)0 2140 y(Magic)28 b(will)f(still)g(paint)h(a)g(horizontal)g(or)g(v) o(ertical)g(line)f(\(whiche)n(v)o(er)h(results)f(in)h(the)g(longest)f (ne)n(w)h(wire)h(le)o(g\).)0 2261 y(T)-8 b(o)28 b(see)h(ho)n(w)f(this)g (w)o(orks,)h(left-click)f(on)h Fa(8)f Fd(in)g Fa(tut3a)p Fd(,)i(then)f(right-click)e(on)i Fa(9)p Fd(.)42 b(Y)-11 b(ou')o(ll)28 b(get)g(a)h(horizontal)f(le)o(g.)0 2381 y(No)n(w)j(undo)h(the)f(ne)n(w)h(le)o(g)f(and)h(right-click)f(on)h Fa(10)p Fd(.)52 b(This)31 b(time)g(you')o(ll)g(get)h(a)g(v)o(ertical)g (le)o(g.)51 b(Y)-11 b(ou)32 b(can)g(force)0 2501 y(Magic)24 b(to)h(paint)f(the)h(ne)o(xt)f(le)o(g)g(in)g(a)h(particular)g (direction)f(with)g(the)h(commands)900 2754 y Fa(:wir)n(e)g(horizontal) 900 2874 y(:wir)n(e)g(v)o(ertical)146 3123 y Fd(T)m(ry)f(out)g(this)f (feature)i(by)f(left-clicking)g(on)g Fa(8)g Fd(in)g Fa(tut3a)p Fd(,)h(mo)o(ving)d(the)i(cursor)h(o)o(v)o(er)e Fa(10)p Fd(,)h(and)g(typing)g Fa(:wir)n(e)0 3244 y(ho)37 b Fd(\(abbre)n (viations)e(w)o(ork)h(for)h Fa(:wir)n(e)g Fd(command)f(options)f(just)g (as)i(the)o(y)e(do)i(else)n(where)f(in)g(Magic\).)66 b(This)0 3364 y(command)24 b(will)g(generate)h(a)g(short)f(horizontal)g (le)o(g)g(instead)h(of)f(a)i(longer)e(v)o(ertical)g(one.)0 3723 y Ff(5)143 b(Contacts)0 3952 y Fd(When)23 b(the)g(wiring)g(tool)f (is)h(acti)n(v)o(e,)f(the)i(middle)e(mouse)g(b)n(utton)g(places)h (contacts.)30 b(Undo)23 b(all)g(of)g(your)g(changes)0 4073 y(to)g Fa(tut3a)g Fd(by)g(typing)e(the)i(command)f Fa(:\003ush)i Fd(and)f(answering)f Fa(y)o(es)h Fd(to)g(the)f(question)g (Magic)g(asks.)30 b(This)22 b(thro)n(ws)0 4193 y(a)o(w)o(ay)27 b(all)h(of)g(the)f(changes)h(made)f(to)g(the)h(cell)f(and)h(re-loads)g (it)f(from)g(disk.)38 b(Dra)o(w)28 b(a)g(red)g(wire)g(le)o(g)f(from)g Fa(1)g Fd(to)0 4314 y Fa(2)p Fd(.)47 b(No)n(w)30 b(mo)o(v)o(e)e(the)i (cursor)h(o)o(v)o(er)e(the)h(blue)g(area)h(and)g(click)f(the)g(middle)f (mouse)g(b)n(utton.)46 b(This)30 b(has)g(se)n(v)o(eral)0 4434 y(ef)n(fects.)g(It)24 b(places)f(a)g(contact)h(at)f(the)g(end)g (of)h(the)f(current)g(wire)h(le)o(g,)e(selects)h(the)g(contact,)h(and)f (mo)o(v)o(es)e(the)j(box)0 4554 y(o)o(v)o(er)i(the)i(selection.)37 b(In)27 b(addition,)g(it)g(changes)g(the)g(wiring)f(material)h(and)g (thickness)g(to)g(match)f(the)i(material)0 4675 y(you)22 b(middle-click)o(ed.)29 b(Mo)o(v)o(e)20 b(the)j(cursor)f(o)o(v)o(er)g Fa(3)g Fd(and)g(right-click)g(to)g(paint)f(a)i(blue)f(le)o(g,)g(then)g (mak)o(e)h(a)f(contact)0 4795 y(to)i(purple)h(by)f(middle-clicking)f(o) o(v)o(er)h(the)h(purple)f(material.)31 b(Continue)24 b(by)g(dra)o(wing)g(a)h(purple)g(le)o(g)f(to)g Fa(4)p Fd(.)146 4918 y(Once)33 b(you')-5 b(v)o(e)32 b(dra)o(wn)f(the)i(purple) e(le)o(g)h(to)g Fa(4)p Fd(,)i(mo)o(v)o(e)d(the)h(cursor)g(o)o(v)o(er)g (red)g(material)g(and)g(middle-click.)0 5039 y(This)i(time,)i(Magic)f (prints)f(an)h(error)g(message)f(and)h(treats)g(the)f(click)h(just)f (lik)o(e)g(a)h(left-click.)60 b(Magic)35 b(only)0 5159 y(kno)n(ws)c(ho)n(w)g(to)g(mak)o(e)h(contacts)g(between)g(certain)g (combinations)e(of)i(layers,)h(which)f(are)h(speci\002ed)f(in)f(the)0 5280 y(technology)24 b(\002le)h(\(see)g(\223Magic)g(Maintainer')-5 b(s)24 b(Manual)g(#2:)31 b(The)25 b(T)-7 b(echnology)23 b(File\224\).)32 b(F)o(or)25 b(this)f(technology)-6 b(,)0 5400 y(Magic)24 b(doesn')n(t)h(kno)n(w)f(ho)n(w)g(to)g(mak)o(e)h (contacts)f(directly)g(between)h(purple)g(and)f(red.)1875 5649 y(\2263\226)p eop %%Page: 4 4 4 3 bop 0 -180 a Fd(September)25 b(26,)f(2001)671 b(Magic)25 b(T)l(utorial)e(#3:)30 b(Adv)n(anced)24 b(P)o(ainting)g(\(W)l(iring)g (and)h(Plo)n(wing\))0 99 y Ff(6)143 b(W)m(iring)36 b(and)f(the)g(Box)0 322 y Fd(In)29 b(the)g(e)o(xamples)f(so)h(f)o(ar)l(,)h(each)g(ne)n(w)f (wire)g(le)o(g)f(appeared)i(to)f(be)g(dra)o(wn)f(from)h(the)g(end)g(of) g(the)g(pre)n(vious)f(le)o(g)0 443 y(to)k(the)g(cursor)g(position.)51 b(In)32 b(f)o(act,)i(ho)n(we)n(v)o(er)l(,)e(the)g(ne)n(w)g(material)g (w)o(as)g(dra)o(wn)g(from)f(the)h Fe(box)g Fd(to)g(the)g(cursor)0 563 y(position.)c(Magic)23 b(automatically)f(repositions)f(the)i(box)g (on)g(each)h(b)n(utton)e(click)h(to)f(help)h(set)g(things)f(up)h(for)g (the)0 683 y(ne)o(xt)g(le)o(g.)30 b(Using)23 b(the)h(box)f(as)h(the)g (starting)f(point)g(for)h(wire)h(le)o(gs)e(mak)o(es)g(it)h(easy)g(to)f (start)h(wires)g(in)g(places)g(that)0 804 y(don')n(t)h(already)h(ha)n (v)o(e)f(material)f(of)i(the)f(right)f(type)h(and)h(width.)31 b(Suppose)25 b(that)g(you)g(w)o(ant)g(to)g(start)f(a)i(ne)n(w)f(wire)0 924 y(in)h(the)h(middle)e(of)i(an)g(empty)f(area.)37 b(Y)-11 b(ou)26 b(can')n(t)h(left-click)g(to)f(get)h(the)f(wire)h (started)f(there.)37 b(Instead,)27 b(you)f(can)0 1045 y(left-click)d(some)f(other)h(place)h(where)f(there')-5 b(s)23 b(the)g(right)f(material)h(for)g(the)g(wire,)h(type)f(the)g (space)g(bar)h(twice)e(to)0 1165 y(get)i(back)h(the)f(box)g(tool,)f(mo) o(v)o(e)g(the)h(box)g(where)h(you')-5 b(d)24 b(lik)o(e)g(the)g(wire)h (to)e(start,)h(hit)g(the)g(space)h(bar)g(once)f(more)0 1285 y(to)g(get)h(back)g(the)g(wiring)f(tool,)g(and)g(then)h (right-click)f(to)g(paint)g(the)h(wire.)31 b(T)m(ry)24 b(this)g(out)g(on)h Fa(tut3a)p Fd(.)146 1406 y(When)f(you)g(\002rst)g (start)f(wiring,)g(you)h(may)f(not)h(be)g(able)g(to)f(\002nd)h(the)g (right)f(kind)g(of)h(material)g(an)o(ywhere)f(on)0 1526 y(the)i(screen.)31 b(When)25 b(this)f(happens,)g(you)g(can)h(select)g (the)g(wiring)f(material)g(and)h(width)f(with)g(the)g(command)900 1733 y Fa(:wir)n(e)h(type)h Fe(layer)f(width)146 1940 y Fd(Then)f(mo)o(v)o(e)f(the)g(box)h(where)g(you')-5 b(d)24 b(lik)o(e)f(the)h(wire)g(to)g(start,)f(switch)g(to)h(the)g (wiring)f(tool,)g(and)h(right-click)0 2060 y(to)g(add)h(le)o(gs.)0 2397 y Ff(7)143 b(W)m(iring)36 b(and)f(the)g(Selection)0 2620 y Fd(Each)26 b(time)f(you)g(paint)g(a)h(ne)n(w)g(wire)g(le)o(g)f (or)h(contact)f(using)g(the)g(wiring)g(commands,)g(Magic)g(selects)h (the)g(ne)n(w)0 2741 y(material)33 b(just)g(as)g(if)h(you)f(had)h (placed)f(the)h(cursor)f(o)o(v)o(er)g(it)g(and)h(typed)f Fa(s)p Fd(.)57 b(This)33 b(mak)o(es)g(it)g(easy)h(for)f(you)g(to)0 2861 y(adjust)c(its)g(position)f(if)i(you)f(didn')n(t)g(get)h(it)f (right)g(initially)-6 b(.)44 b(The)30 b Fa(:str)n(etch)h Fd(command)e(is)g(particularly)h(useful)0 2982 y(for)f(this.)41 b(In)28 b Fa(tut3a)p Fd(,)i(paint)e(a)g(wire)h(le)o(g)f(in)g(blue)g (from)g Fa(5)h Fd(to)f Fa(6)g Fd(\(use)h Fa(:\003ush)g Fd(to)g(reset)f(the)h(cell)f(if)g(you')-5 b(v)o(e)28 b(made)0 3102 y(a)f(lot)e(of)i(changes\).)35 b(No)n(w)26 b(type)g Fa(R)h Fd(tw)o(o)e(or)i(three)g(times)e(to)h(stretch)g(the)g (le)o(g)g(o)o(v)o(er)f(to)h(the)h(right.)34 b(Middle-click)0 3222 y(o)o(v)o(er)24 b(purple)g(material,)h(then)f(use)h Fa(W)f Fd(to)h(stretch)f(the)h(contact)g(do)n(wnw)o(ard.)146 3343 y(It')-5 b(s)31 b(often)g(hard)h(to)f(position)e(the)j(cursor)f (so)g(that)g(a)h(wire)f(le)o(g)g(comes)g(out)g(right)f(the)i(\002rst)f (time,)h(b)n(ut)f(it')-5 b(s)0 3463 y(usually)30 b(easy)g(to)h(tell)f (whether)g(the)h(le)o(g)f(is)g(right)g(once)h(it')-5 b(s)29 b(painted.)48 b(If)31 b(it')-5 b(s)30 b(wrong,)h(then)g(you)f (can)h(use)f(the)0 3583 y(stretching)24 b(commands)f(to)i(shift)f(it)g (o)o(v)o(er)g(one)h(unit)f(at)h(a)g(time)f(until)f(it')-5 b(s)24 b(correct.)0 3920 y Ff(8)143 b(Bundles)34 b(of)i(W)m(ir)m(es)0 4144 y Fd(Magic)e(pro)o(vides)g(tw)o(o)g(additional)g(commands)f(that)i (are)g(useful)g(for)g(running)f Fe(b)n(undles)g Fd(of)h(parallel)f (wires.)0 4264 y(The)25 b(commands)e(are:)900 4471 y Fa(\002ll)i Fe(dir)l(ection)f Fd([)p Fe(layer)o(s)p Fd(])900 4591 y Fa(cor)o(ner)i Fe(dir)l(ection1)d(dir)l(ection2)h Fd([)p Fe(layer)o(s)p Fd(])146 4798 y(T)-8 b(o)31 b(see)f(ho)n(w)g(the) o(y)g(w)o(ork,)h(load)f(the)h(cell)f Fa(tut3b)p Fd(.)49 b(The)30 b Fa(:\002ll)h Fd(comand)f(e)o(xtends)f(a)i(whole)f(b)n(unch)g (of)h(paint)0 4918 y(in)g(a)i(gi)n(v)o(en)d(direction.)51 b(It)32 b(\002nds)f(all)h(paint)f(touching)g(one)g(side)h(of)g(the)f (box)h(and)g(e)o(xtends)e(that)i(paint)f(to)g(the)0 5039 y(opposite)26 b(side)g(of)i(the)e(box.)37 b(F)o(or)27 b(e)o(xample,)g Fa(:\002ll)g(left)h Fd(will)e(look)g(underneath)h(the)g (right)f(edge)h(of)g(the)g(box)g(for)0 5159 y(paint,)33 b(and)f(will)f(e)o(xtend)g(that)g(paint)h(to)f(the)h(left)g(side)f(of)h (the)g(box.)52 b(The)32 b(ef)n(fect)g(is)f(just)g(as)h(if)g(all)g(the)g (colors)0 5280 y(visible)c(underneath)g(that)h(edge)g(of)f(the)h(box)f (constituted)g(a)h(paint)f(brush;)i(Magic)e(sweeps)h(the)g(brush)f (across)0 5400 y(the)d(box)f(in)g(the)h(gi)n(v)o(en)e(direction.)30 b(Place)c(the)f(box)f(o)o(v)o(er)g(the)h(label)f(\223Fill)h(here\224)g (in)g Fa(tut3b)h Fd(and)e(type)h Fa(:\002ll)g(left)p Fd(.)1875 5649 y(\2264\226)p eop %%Page: 5 5 5 4 bop 0 -180 a Fd(Magic)24 b(T)l(utorial)g(#3:)30 b(Adv)n(anced)24 b(P)o(ainting)g(\(W)l(iring)g(and)h(Plo)n(wing\))670 b(September)25 b(26,)g(2001)146 69 y(The)e Fa(:cor)o(ner)h Fd(command)e(is)h(similar)e(to)i Fa(:\002ll)g Fd(e)o(xcept)g(that)f(it) h(generates)g(L-shaped)g(wires)f(that)h(follo)n(w)f(tw)o(o)0 189 y(sides)28 b(of)h(the)f(box,)i(tra)n(v)o(elling)d(\002rst)i(in)f Fe(dir)l(ection1)g Fd(and)g(then)h(in)f Fe(dir)l(ection2)p Fd(.)41 b(Place)30 b(the)f(box)f(o)o(v)o(er)g(the)g(label)0 309 y(\223Corner)e(here\224)f(in)g Fa(tut3b)h Fd(and)e(type)h Fa(:cor)o(ner)h(right)f(up)p Fd(.)146 433 y(In)e(both)e Fa(:\002ll)h Fd(and)g Fa(:cor)o(ner)p Fd(,)i(if)e Fe(layer)o(s)g Fd(isn')n(t)g(speci\002ed)g(then)g(all)g(layers)g(are)h(\002lled.)30 b(If)22 b Fe(layer)o(s)g Fd(is)g(gi)n(v)o(en)e(then)0 553 y(only)k(those)g(layers)h(are)h(painted.)k(Experiment)23 b(on)i Fa(tut3b)h Fd(with)e(the)h Fa(:\002ll)f Fd(and)h Fa(:cor)o(ner)h Fd(commands.)146 676 y(When)21 b(you')-5 b(re)21 b(painting)f(b)n(undles)g(of)g(wires,)i(it)e(w)o(ould)g(be)h (nice)g(if)g(there)g(were)h(a)f(con)l(v)o(enient)e(w)o(ay)i(to)g(place) 0 797 y(contacts)g(across)h(the)f(whole)g(b)n(undle)g(in)g(order)h(to)f (switch)g(to)g(a)h(dif)n(ferent)f(layer)-5 b(.)30 b(There')-5 b(s)21 b(no)g(single)g(command)0 917 y(to)26 b(do)g(this,)g(b)n(ut)g (you)h(can)g(place)f(one)h(contact)f(by)h(hand)f(and)g(then)h(use)f (the)h Fa(:array)f Fd(command)g(to)g(replicate)h(a)0 1037 y(single)22 b(contact)i(across)f(the)g(whole)g(b)n(undle.)30 b(Load)23 b(the)g(cell)g Fa(tut3c)p Fd(.)31 b(This)23 b(contains)f(a)i(b)n(undle)f(of)g(wires)g(with)g(a)0 1158 y(single)f(contact)h(already)g(painted)f(by)g(hand)h(on)g(the)f (bottom)g(wire.)30 b(T)-8 b(ype)22 b Fa(s)h Fd(with)f(the)h(cursor)g(o) o(v)o(er)f(the)g(contact,)0 1278 y(and)30 b(type)g Fa(S)h Fd(with)f(the)g(cursor)g(o)o(v)o(er)g(the)g(stub)f(of)i(purple)f (wiring)f(material)h(ne)o(xt)g(to)f(it.)47 b(No)n(w)30 b(place)g(the)h(box)0 1399 y(o)o(v)o(er)i(the)h(label)f(\223)-8 b(Array\224)35 b(and)f(type)f(the)h(command)f Fa(:array)h(1)g(10)p Fd(.)57 b(This)33 b(will)g(cop)o(y)h(the)f(selected)h(contact)0 1519 y(across)25 b(the)g(whole)f(b)n(undle.)146 1642 y(The)h(syntax)f(of)h(the)g Fa(:array)g Fd(command)f(is)900 1893 y Fa(:array)h Fe(xsize)g(ysize)146 2141 y Fd(This)34 b(command)f(mak)o(es)h(the)g(selection)g(into)g(an)g(array)h(of)g (identical)e(elements.)59 b Fe(Xsize)33 b Fd(speci\002es)i(ho)n(w)0 2262 y(man)o(y)d(total)g(instances)g(there)h(should)e(be)i(in)f(the)h (x-direction)f(when)h(the)f(command)g(is)g(\002nished)h(and)f Fe(ysize)0 2382 y Fd(speci\002es)27 b(ho)n(w)g(man)o(y)f(total)g (instances)g(there)i(should)e(be)h(in)g(the)g(y-direction.)36 b(In)28 b(the)f Fa(tut3c)h Fd(e)o(xample,)e Fa(xsize)0 2502 y Fd(w)o(as)c(one,)g(so)f(no)g(additional)g(copies)g(were)h (created)g(in)g(that)f(direction;)g Fa(ysize)h Fd(w)o(as)g(10,)f(so)h (9)f(additional)f(copies)0 2623 y(were)26 b(created.)33 b(The)25 b(box)g(is)g(used)g(to)g(determine)f(ho)n(w)h(f)o(ar)h(apart)f (the)g(elements)g(should)f(be:)31 b(the)26 b(width)e(of)h(the)0 2743 y(box)k(determines)g(the)g(x-spacing)g(and)g(the)g(height)g (determines)g(the)g(y-spacing.)44 b(The)29 b(ne)n(w)g(material)g(al)o (w)o(ays)0 2864 y(appears)c(abo)o(v)o(e)f(and)h(to)f(the)h(right)f(of)h (the)f(original)g(cop)o(y)-6 b(.)146 2987 y(In)29 b Fa(tut3c)p Fd(,)h(use)e Fa(:cor)o(ner)h Fd(to)f(e)o(xtend)g(the)g(purple)g(wires)g (and)h(turn)e(them)h(up.)41 b(Then)28 b(paint)g(a)h(contact)f(back)0 3107 y(to)d(blue)g(on)g(the)h(leftmost)e(wire,)i(add)f(a)h(stub)e(of)i (blue)f(paint)g(abo)o(v)o(e)f(it,)h(and)h(use)f Fa(:array)h Fd(to)f(cop)o(y)g(them)g(across)0 3228 y(the)g(top)f(of)h(the)f(b)n (undle.)30 b(Finally)-6 b(,)24 b(use)h Fa(:\002ll)g Fd(again)f(to)g(e)o (xtend)g(the)h(blue)f(b)n(undle)g(f)o(arther)i(up.)0 3585 y Ff(9)143 b(Plo)o(wing)0 3815 y Fd(Magic)28 b(contains)f(a)i(f)o (acility)f(called)g Fe(plowing)f Fd(that)h(you)g(can)h(use)f(to)g (stretch)g(and)g(compact)g(cells.)41 b(The)28 b(basic)0 3935 y(plo)n(wing)23 b(command)h(has)h(the)f(syntax)900 4186 y Fa(:plo)o(w)h Fe(dir)l(ection)f Fd([)p Fe(layer)o(s)p Fd(])146 4434 y(where)30 b Fe(dir)l(ection)d Fd(is)i(a)g(Manhattan)f (direction)g(lik)o(e)g Fa(left)h Fd(and)g Fe(layer)o(s)f Fd(is)g(an)h(optional,)f(comma-separated)0 4554 y(list)d(of)i(mask)f (layers.)35 b(The)26 b(plo)n(w)g(command)f(treats)h(one)h(side)e(of)i (the)f(box)g(as)g(if)h(it)f(were)h(a)f(plo)n(w)-6 b(,)25 b(and)i(sho)o(v)o(es)0 4675 y(the)d(plo)n(w)e(o)o(v)o(er)h(to)g(the)h (other)g(side)f(of)h(the)f(box.)30 b(F)o(or)24 b(e)o(xample,)f Fa(:plo)o(w)h(up)g Fd(treats)g(the)g(bottom)e(side)h(of)h(the)g(box)0 4795 y(as)h(a)g(plo)n(w)-6 b(,)23 b(and)i(mo)o(v)o(es)e(the)i(plo)n(w)e (to)i(the)f(top)h(of)f(the)h(box.)146 4918 y(As)e(the)g(plo)n(w)f(mo)o (v)o(es,)g(e)n(v)o(ery)h(edge)g(in)g(its)f(path)h(is)g(pushed)g(ahead)g (of)h(it)e(\(if)i Fe(layer)o(s)f Fd(is)f(speci\002ed,)i(then)f(only)0 5039 y(edges)i(on)g(those)g(layers)g(are)h(mo)o(v)o(ed\).)31 b(Each)26 b(edge)f(that)g(is)g(pushed)f(by)h(the)h(plo)n(w)e(pushes)g (other)h(edges)h(ahead)0 5159 y(of)c(it)g(in)g(a)h(w)o(ay)f(that)g (preserv)o(es)g(design)g(rules,)g(connecti)n(vity)-6 b(,)20 b(and)j(transistor)e(and)h(contact)g(sizes.)30 b(This)21 b(means)0 5280 y(that)32 b(material)g(ahead)g(of)h(the)f(plo) n(w)f(gets)h(compacted)f(do)n(wn)h(to)f(the)i(minimum)c(spacing)j (permitted)f(by)h(the)0 5400 y(design)24 b(rules,)h(and)f(material)h (that)f(crossed)h(the)f(plo)n(w')-5 b(s)23 b(original)h(position)f (gets)i(stretched)f(behind)g(the)h(plo)n(w)-6 b(.)1875 5649 y(\2265\226)p eop %%Page: 6 6 6 5 bop 0 -180 a Fd(September)25 b(26,)f(2001)671 b(Magic)25 b(T)l(utorial)e(#3:)30 b(Adv)n(anced)24 b(P)o(ainting)g(\(W)l(iring)g (and)h(Plo)n(wing\))146 68 y(Y)-11 b(ou)28 b(can)h(compact)f(a)g(cell)g (by)g(placing)g(a)g(lar)n(ge)h(plo)n(w)e(of)n(f)h(to)f(one)h(side)g(of) g(the)g(cell)h(and)f(plo)n(wing)e(across)0 188 y(the)g(whole)f(cell.)33 b(Y)-11 b(ou)26 b(can)g(open)f(up)h(space)g(in)f(the)h(middle)e(of)i(a) g(cell)g(by)f(dragging)g(a)h(small)f(plo)n(w)f(across)i(the)0 309 y(area)g(where)f(you)f(w)o(ant)h(more)g(space.)146 434 y(T)-8 b(o)30 b(try)f(out)g(plo)n(wing,)g(edit)g(the)g(cell)h Fa(tut3d)p Fd(,)i(place)d(the)h(box)f(o)o(v)o(er)g(the)g(rectangle)h (that')-5 b(s)28 b(labelled)h(\223Plo)n(w)0 555 y(here\224,)i(and)e (try)f(plo)n(wing)g(in)g(v)n(arious)g(directions.)42 b(Also,)30 b(try)e(plo)n(wing)f(only)i(certain)g(layers.)43 b(F)o(or)29 b(e)o(xample,)0 675 y(with)24 b(the)h(box)f(o)o(v)o(er)g (the)h(\223Plo)n(w)f(here\224)i(label,)e(try)900 946 y Fa(:plo)o(w)h(right)g(metal2)146 1212 y Fd(Nothing)g(happens.)34 b(This)25 b(is)h(because)g(there)g(are)h(no)f(metal2)f Fe(edg)o(es)h Fd(in)f(the)h(path)g(of)g(the)g(plo)n(w)-6 b(.)32 b(If)27 b(instead)0 1332 y(you)d(had)h(typed)900 1603 y Fa(:plo)o(w)g(right)g(metal1)146 1868 y Fd(only)f(the)h(metal)f (w)o(ould)g(ha)n(v)o(e)h(been)g(plo)n(wed)e(to)i(the)g(right.)146 1994 y(In)j(addition)e(to)h(plo)n(wing)f(with)h(the)g(box,)h(you)f(can) h(plo)n(w)e(the)i(selection.)38 b(The)28 b(command)e(to)h(do)h(this)e (has)0 2114 y(the)f(follo)n(wing)e(syntax:)900 2385 y Fa(:plo)o(w)i(selection)g Fd([)p Fe(dir)l(ection)f Fd([)p Fe(distance)p Fd(]])146 2651 y(This)i(is)g(v)o(ery)g(similar)f(to)h (the)g Fa(:str)n(etch)i Fd(command:)k(it)26 b(picks)g(up)g(the)g (selection)f(and)i(the)f(box)g(and)g(mo)o(v)o(es)0 2771 y(both)21 b(so)g(that)g(the)h(lo)n(wer)n(-left)f(corner)h(of)f(the)h (box)f(is)g(at)h(the)f(cursor)h(location.)29 b(Unlik)o(e)20 b(the)i Fa(:str)n(etch)h Fd(command,)0 2891 y(though,)h Fa(:plo)o(w)g(selection)i Fd(insures)e(that)g(design)g(rule)h (correctness)g(and)g(connecti)n(vity)e(are)i(preserv)o(ed.)146 3017 y(Load)36 b(the)f(cell)h Fa(tut3e)h Fd(and)e(use)h Fa(a)f Fd(to)h(select)f(the)h(area)g(underneath)g(the)f(label)h(that)f (says)g(\223select)h(me\224.)0 3138 y(Then)31 b(point)g(with)g(the)g (cursor)h(to)f(the)g(point)g(labelled)g(\223point)g(here\224)h(and)g (type)f Fa(:plo)o(w)h(selection)p Fd(.)51 b(Practice)0 3258 y(selecting)35 b(things)f(and)h(plo)n(wing)f(them.)62 b(Lik)o(e)35 b(the)g Fa(:str)n(etch)i Fd(command,)g(there)f(is)f(also)g (a)h(longer)f(form)g(of)0 3378 y Fa(:plo)o(w)28 b(selection)p Fd(.)40 b(F)o(or)27 b(e)o(xample,)h Fa(:plo)o(w)g(selection)g(do)o(wn)g (5)g Fd(will)e(plo)n(w)h(the)h(selection)f(and)g(the)h(box)f(do)n(wn)0 3499 y(10)e(units.)146 3624 y(Selecting)k(a)g(cell)g(and)g(plo)n(wing)e (it)h(is)h(a)g(good)f(w)o(ay)h(to)g(mo)o(v)o(e)e(the)i(cell.)42 b(Load)29 b Fa(tut3f)h Fd(and)f(select)f(the)h(cell)0 3745 y Fa(tut3e)p Fd(.)58 b(Point)34 b(to)f(the)h(label)f(\223point)g (here\224)i(and)e(plo)n(w)g(the)g(selection)g(with)g Fa(:plo)o(w)h(selection)p Fd(.)58 b(Notice)34 b(that)0 3865 y(all)f(connections)f(to)h(the)g(cell)g(ha)n(v)o(e)g(remained)g (attached.)56 b(The)33 b(cell)g(you)g(select)g(must)f(be)i(in)e(the)h (edit)g(cell,)0 3986 y(ho)n(we)n(v)o(er)-5 b(.)146 4111 y(The)31 b(plo)n(wing)e(operation)h(is)g(implemented)f(in)i(a)g(w)o(ay) g(that)f(tries)g(to)h(k)o(eep)f(your)h(design)f(as)h(compact)f(as)0 4232 y(possible.)f(T)-8 b(o)24 b(do)h(this,)e(it)h(inserts)f(jogs)h(in) g(wires)g(around)g(the)h(plo)n(w)-6 b(.)29 b(In)24 b(man)o(y)f(cases,)i (though,)e(the)i(additional)0 4352 y(jogs)h(are)i(more)e(trouble)h (than)f(the)o(y')-5 b(re)27 b(w)o(orth.)36 b(T)-8 b(o)27 b(reduce)h(the)e(number)h(of)g(jogs)f(inserted)g(by)h(plo)n(wing,)e (type)0 4472 y(the)g(command)900 4743 y Fa(:plo)o(w)g(nojogs)146 5009 y Fd(From)37 b(no)n(w)f(on,)k(Magic)d(will)f(insert)g(as)h(fe)n(w) g(jogs)g(as)g(possible)e(when)i(plo)n(wing,)h(e)n(v)o(en)e(if)h(this)f (means)0 5129 y(mo)o(ving)23 b(more)i(material.)30 b(Y)-11 b(ou)24 b(can)h(re-enable)h(jog)e(insertion)g(with)g(the)g(command)900 5400 y Fa(:plo)o(w)h(jogs)1875 5649 y Fd(\2266\226)p eop %%Page: 7 7 7 6 bop 0 -180 a Fd(Magic)24 b(T)l(utorial)g(#3:)30 b(Adv)n(anced)24 b(P)o(ainting)g(\(W)l(iring)g(and)h(Plo)n(wing\))670 b(September)25 b(26,)g(2001)146 69 y(Load)g(the)g(cell)f Fa(tut3d)i Fd(again)e(and)h(try)g(plo)n(wing)e(it)h(both)g(with)g(and)h (without)e(jog)i(insertion.)146 189 y(There)h(is)e(another)h(w)o(ay)g (to)g(reduce)g(the)g(number)g(of)g(jogs)f(introduced)g(by)h(plo)n (wing.)k(Instead)c(of)g(a)n(v)n(oiding)0 309 y(jogs)30 b(in)g(the)h(\002rst)g(place,)h(plo)n(wing)d(can)i(introduce)f(them)h (freely)g(b)n(ut)f(clean)h(them)f(up)h(as)f(much)h(as)f(possible)0 430 y(afterw)o(ard.)65 b(This)35 b(results)g(in)h(more)f(dense)h (layouts,)i(b)n(ut)d(possibly)f(more)i(jogs)f(than)h(if)g(you)f(had)h (enabled)0 550 y Fa(:plo)o(w)28 b(nojogs)p Fd(.)38 b(T)-8 b(o)28 b(tak)o(e)f(adv)n(antage)g(of)h(this)e(second)i(method)e(for)i (jog)f(reduction,)g(re-enable)h(jog)f(insertion)0 671 y(\()p Fa(:plo)o(w)e(jogs)p Fd(\))g(and)f(enable)h(jog)g(cleanup)f (with)g(the)h(command)900 899 y Fa(:plo)o(w)g(straighten)146 1127 y Fd(From)j(no)n(w)e(on,)i(Magic)f(will)f(attempt)h(to)g (straighten)f(out)h(jogs)g(after)h(each)g(plo)n(w)e(operation.)38 b(T)-8 b(o)27 b(disable)0 1248 y(straightening,)c(use)i(the)f(command) 900 1476 y Fa(:plo)o(w)h(nostraighten)146 1704 y Fd(It)d(might)f(seem)g (pointless)f(to)i(disable)f(jog)g(introduction)f(with)h Fa(:plo)o(w)h(nojogs)g Fd(at)g(the)f(same)h(time)f(straight-)0 1825 y(ening)31 b(is)h(enabled)g(with)f Fa(:plo)o(w)h(straighten)p Fd(.)52 b(While)32 b(it)f(is)h(true)g(that)f Fa(:plo)o(w)h(nojogs)g Fd(w)o(on')n(t)f(introduce)h(an)o(y)0 1945 y(ne)n(w)24 b(jogs)f(for)h Fa(:plo)o(w)g(straighten)h Fd(to)f(clean)g(up,)g(plo)n (wing)e(will)h(straighten)g(out)h(an)o(y)f(e)o(xisting)g(jogs)g(after)h (each)0 2065 y(operation.)146 2186 y(In)e(f)o(act,)g(there)g(is)f(a)h (separate)f(command)g(that)g(is)g(sometimes)e(useful)i(for)h(cleaning)f (up)g(layouts)f(with)h(man)o(y)0 2306 y(jogs,)j(namely)g(the)h(command) 900 2534 y Fa(:straighten)h Fe(dir)l(ection)146 2763 y Fd(where)32 b Fe(dir)l(ection)f Fd(is)g(a)h(Manhattan)f(direction,)h (e.g.,)h Fa(up)p Fd(,)h Fa(do)o(wn)p Fd(,)g Fa(right)p Fd(,)g(or)d Fa(left)p Fd(.)52 b(This)30 b(command)h(will)0 2883 y(start)21 b(from)g(one)h(side)f(of)g(the)g(box)g(and)h(pull)e (jogs)h(to)n(w)o(ard)g(that)f(side)h(to)h(straighten)e(them.)29 b(Load)21 b(the)g(cell)h Fa(tut3g)p Fd(,)0 3003 y(place)i(the)f(box)g (o)o(v)o(er)f(the)h(label)h(\223put)f(box)f(here\224,)j(and)e(type)g Fa(:straighten)h(left)p Fd(.)31 b(Undo)23 b(the)g(last)g(command)f(and) 0 3124 y(type)i Fa(:straighten)i(right)f Fd(instead.)30 b(Play)c(around)e(with)g(the)h Fa(:straighten)h Fd(command.)146 3244 y(There)j(is)g(one)f(more)h(feature)g(of)g(plo)n(wing)e(that)h(is) g(sometimes)f(useful.)42 b(If)29 b(you)f(are)h(w)o(orking)f(on)h(a)g (lar)n(ge)0 3365 y(cell)e(and)g(w)o(ant)g(to)g(mak)o(e)g(sure)g(that)f (plo)n(wing)g(ne)n(v)o(er)g(af)n(fects)h(an)o(y)g(geometry)f(outside)g (of)h(a)h(certain)f(area,)i(you)0 3485 y(can)c(place)g(a)g Fe(boundary)f Fd(around)h(the)f(area)i(you)f(w)o(ant)f(to)h(af)n(fect)g (with)f(the)g(command)900 3713 y Fa(:plo)o(w)h(boundary)146 3942 y Fd(The)h(box)g(is)g(used)g(to)f(specify)h(the)g(area)h(you)f(w)o (ant)g(to)g(af)n(fect.)35 b(After)26 b(this)f(command,)h(subsequent)e (plo)n(ws)0 4062 y(will)g(only)g(af)n(fect)h(the)g(area)h(inside)d (this)h(boundary)-6 b(.)146 4182 y(Load)19 b(the)g(cell)g Fa(tut3h)g Fd(place)h(the)e(box)h(o)o(v)o(er)f(the)g(label)h(\223put)g (boundary)f(here\224,)j(and)d(type)h Fa(:plo)o(w)g(boundary)p Fd(.)0 4303 y(No)n(w)25 b(mo)o(v)o(e)g(the)h(box)f(a)o(w)o(ay)-6 b(.)34 b(Y)-11 b(ou)26 b(will)f(see)i(the)f(boundary)f(highlighted)f (with)h(dotted)h(lines.)34 b(No)n(w)25 b(place)h(the)0 4423 y(box)f(o)o(v)o(er)g(the)g(area)i(labelled)e(\223put)g(plo)n(w)f (here\224)i(and)g(plo)n(w)e(up.)33 b(This)24 b(plo)n(w)h(w)o(ould)f (cause)i(geometry)f(outside)0 4544 y(of)35 b(the)f(boundary)g(to)h(be)f (af)n(fected,)k(so)c(Magic)g(reduces)h(the)g(plo)n(w)e(distance)i (enough)f(to)g(pre)n(v)o(ent)f(this)h(and)0 4664 y(w)o(arns)25 b(you)f(of)h(this)f(f)o(act.)31 b(No)n(w)24 b(undo)g(the)h(last)f(plo)n (w)g(and)h(remo)o(v)o(e)e(the)i(boundary)f(with)900 4892 y Fa(:plo)o(w)h(noboundary)146 5121 y Fd(Put)e(the)f(box)g(o)o(v)o(er)f (the)i(\223put)f(plo)n(w)f(here\224)i(label)f(and)h(plo)n(w)e(up)h (again.)29 b(This)22 b(time)g(there)g(w)o(as)h(no)f(boundary)0 5241 y(to)h(stop)f(the)h(plo)n(w)-6 b(,)22 b(so)h(e)n(v)o(erything)e(w) o(as)i(mo)o(v)o(ed)f(as)h(f)o(ar)h(as)f(the)g(height)f(of)i(the)f(box.) 29 b(Experiment)22 b(with)h(placing)0 5361 y(the)i(boundary)f(around)g (an)h(area)h(of)f(this)f(cell)h(and)f(plo)n(wing.)1875 5649 y(\2267\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/maint4.ps0000644000175000001440000005111410751423606015432 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: maint4.dvi %%Pages: 4 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips maint4.dvi -o maint4.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Bold % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (maint4.dvi) @start /Fa 1 16 df<0001FF0000000FFFE000003FFFF800007FFFFC0001FFFFFF0003 FFFFFF8007FFFFFFC00FFFFFFFE01FFFFFFFF01FFFFFFFF03FFFFFFFF87FFFFFFFFC7FFF FFFFFC7FFFFFFFFCFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFF FFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFEFFFFFFFFFE7FFFFFFFFC7FFFFFFFFC7FFFFFFF FC3FFFFFFFF81FFFFFFFF01FFFFFFFF00FFFFFFFE007FFFFFFC003FFFFFF8001FFFFFF00 007FFFFC00003FFFF800000FFFE0000001FF000027267BAB32>15 D E /Fb 137[60 66 40 47 53 1[66 60 66 100 33 2[33 66 60 40 53 66 53 1[60 8[86 3[80 6[113 8[86 86 8[40 6[60 60 60 60 1[30 43[66 2[{ TeXBase1Encoding ReEncodeFont }30 119.999948 /Times-Bold rf /Fc 75[33 29[50 1[44 26[50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 1[28 50 50 33 44 50 44 50 44 8[72 94 72 72 61 55 66 72 55 72 72 89 61 1[39 33 72 72 55 61 72 66 66 72 5[28 28 50 50 50 50 50 50 50 50 50 50 28 25 33 25 2[33 33 33 2[50 50 31[55 55 2[{ TeXBase1Encoding ReEncodeFont }73 100.000003 /Times-Roman rf /Fd 135[44 66 2[28 39 39 2[50 50 72 28 44 4[28 44 3[50 13[50 4[66 9[72 26[33 33 40[{ TeXBase1Encoding ReEncodeFont }18 100.000003 /Times-Italic rf /Fe 134[72 1[104 72 80 48 56 64 1[80 72 80 120 40 80 1[40 80 72 48 64 80 64 80 72 8[104 143 1[104 96 6[135 3[56 4[104 104 1[104 6[48 5[72 72 72 72 2[36 6[48 3[72 35[{ TeXBase1Encoding ReEncodeFont }39 143.999997 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 285 101 a Fe(Magic)35 b(Maintainer')-5 b(s)34 b(Manual)h(#4:)43 b(Using)35 b(Magic)g(Under)g(X)1665 237 y(W)m(indo)o(ws)1747 657 y Fd(Don)24 b(Stark)1338 1078 y Fc(Computer)h(Systems)f(Laboratory)1558 1198 y(Stanford)h(Uni)n (v)o(ersity)1547 1319 y(Stanford,)g(CA)h(94305)1053 1589 y(This)e(tutorial)g(corresponds)g(to)g(Magic)h(v)o(ersion)e(7.)0 2115 y Fb(T)-11 b(utorials)30 b(to)f(r)n(ead)h(\002rst:)300 2316 y Fc(Magic)24 b(T)l(utorial)g(#1:)30 b(Getting)24 b(Started)0 2517 y Fb(Commands)29 b(intr)n(oduced)j(in)f(this)f (tutorial:)300 2719 y Fd(\(None\))0 2920 y Fb(Macr)n(os)f(intr)n (oduced)i(in)g(this)f(tutorial:)300 3146 y Fd(\(None\))0 3485 y Fe(1)143 b(Intr)m(oduction)0 3709 y Fc(This)22 b(document)g(pro)o(vides)g(information)g(on)g(Magic')-5 b(s)23 b(X)g(dri)n(v)o(ers)e(that)i(may)g(be)g(of)g(help)g(to)f(system) g(maintain-)0 3829 y(ers.)0 4168 y Fe(2)143 b(Compiling)34 b(the)h(Corr)m(ect)f(X)h(Dri)o(v)o(er)f(f)l(or)h(y)l(our)g(system.)0 4392 y Fc(Unfortunately)-6 b(,)30 b(it)f(is)h(not)f(possible)g(to)h (link)f(with)g(both)g(the)h(X10)g(and)g(X11)g(libraries,)g(so)g(you)g (will)f(ha)n(v)o(e)g(to)0 4512 y(compile)24 b(Magic)g(dif)n(ferently)g (depending)g(on)h(the)f(v)o(ersion)g(of)h(X)g(that)f(you)h(are)g (running.)0 4807 y Fb(2.1)119 b(Compiling)31 b(f)m(or)f(X11)120 4995 y Fc(1.)49 b(Add)24 b(the)h(\003ag)g(-DX11)g(to)f(misc/DFLA)l(GS) 120 5197 y(2.)49 b(Add)24 b(-lX11)h(to)f(magic/LIBS)120 5400 y(3.)49 b(Change)25 b(the)g(SRCS)h(line)f(in)f(graphics/Mak)o (e\002le)g(to)h($B)m(ASE)p 2418 5400 30 4 v 36 w(SRCS)h($X11)p 2944 5400 V 36 w(SRCS)1875 5649 y(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Fc(September)25 b(26,)f(2001)516 b(Magic)25 b(Maintainer')-5 b(s)23 b(Manual)h(#4:)31 b(Using)23 b(Magic)i(Under)g(X)g(W)l(indo)n(ws)120 73 y(4.)49 b(Change)25 b(the)g(OBJS)g(line)g(to)f($B)m(ASE)p 1561 73 30 4 v 36 w(OBJS)h($X11)p 2076 73 V 35 w(OBJS)120 287 y(5.)49 b(Change)25 b(the)g(POBJS)h(line)e(to)g($B)m(ASE)p 1616 287 V 36 w(POBJS)i($X11)p 2187 287 V 35 w(POBJS)120 501 y(6.)49 b(Change)25 b(the)g(HELPER)p 1102 501 V 36 w(SRCS)i(line)d ($X11HELPER)p 2179 501 V 36 w(SRCS)120 715 y(7.)49 b(Change)25 b(the)g(HELPER)p 1102 715 V 36 w(SRCS)i(line)d($X11HELPER)p 2179 715 V 36 w(PR)l(OG)120 929 y(8.)49 b(Compile)24 b(the)h(module)e(graphics.o)120 1143 y(9.)49 b(Relink)24 b(magic)0 1451 y Fb(2.2)119 b(Compiling)31 b(f)m(or)f(X10)120 1643 y Fc(1.)49 b(Add)24 b(the)h(\003ag)g(-DX10)g(to)f(misc/DFLA)l(GS) 120 1857 y(2.)49 b(Add)24 b(-lX10)h(to)f(magic/LIBS)120 2071 y(3.)49 b(Change)25 b(the)g(SRCS)h(line)f(in)f(graphics/Mak)o (e\002le)g(to)h($B)m(ASE)p 2418 2071 V 36 w(SRCS)h($X10)p 2944 2071 V 36 w(SRCS)120 2285 y(4.)49 b(Change)25 b(the)g(OBJS)g(line) g(to)f($B)m(ASE)p 1561 2285 V 36 w(SRCS)i($X10)p 2087 2285 V 36 w(OBJS)120 2499 y(5.)49 b(Change)25 b(the)g(POBJS)h(line)e (to)g($B)m(ASE)p 1616 2499 V 36 w(SRCS)j($X10)p 2143 2499 V 35 w(POBJS)120 2713 y(6.)49 b(Change)25 b(the)g(HELPER)p 1102 2713 V 36 w(SRCS)i(line)d($X10HELPER)p 2179 2713 V 36 w(SRCS)120 2927 y(7.)49 b(Change)25 b(the)g(HELPER)p 1102 2927 V 36 w(SRCS)i(line)d($X10HELPER)p 2179 2927 V 36 w(PR)l(OG)120 3141 y(8.)49 b(Compile)24 b(the)h(module)e (graphics.o)120 3355 y(9.)49 b(Relink)24 b(magic)0 3708 y Fe(3)143 b(T)-11 b(r)m(oubleshooting)33 b(the)i(X)h(Dri)o(v)o(ers)0 3936 y Fc(The)31 b(follo)n(wing)e(is)h(a)i(list)e(of)h(problems)f (sometimes)f(encountered)i(in)f(running)g(Magic)h(under)g(X)g(and)g (some)0 4057 y(suggestions)23 b(about)h(ho)n(w)g(to)h(get)f(around)h (the)f(problem.)0 4365 y Fb(3.1)119 b(X11)30 b(Dri)o(v)o(er)145 4557 y Fa(\017)49 b Fc(F)o(onts)244 4678 y(W)-8 b(e)21 b(ha)n(v)o(e)g(tried)g(to)f(pick)h(a)g(set)g(of)g(fonts)f(that)h(most)f (machines)g(running)g(X11)h(Re)n(vision)e(3)i(will)f(ha)n(v)o(e,)i(b)n (ut)244 4798 y(there)i(is)g(nothing)f(to)h(guarantee)g(that)g(a)h(gi)n (v)o(en)d(machine)i(will)f(ha)n(v)o(e)h(a)h(font.)30 b(If)25 b(you')-5 b(re)24 b(getting)f(\224unable)244 4918 y(to)f(load)h(font\224)g(messages,)f(you)h(will)f(need)h(to)f (change)h(the)g(fonts)f(that)h(Magic)f(uses.)30 b(The)23 b(simplest)e(w)o(ay)244 5039 y(to)30 b(do)h(this)f(is)h(to)f(specify)h (them)f(in)h(your)g(.Xdef)o(aults)f(\002le)h(as)g(described)g(in)g (section)f(2.1.)49 b(T)-8 b(o)31 b(change)244 5159 y(the)f(def)o(ault)f (v)n(alues)h(that)f(Magic)h(uses,)h(change)f(the)g(\224fontnames\224)f (array)i(in)f(the)f(\002le)i(grX11su3.c)e(of)244 5280 y(the)k(graphics)g(module.)56 b(The)33 b(program)g Fd(xlsfonts)f Fc(will)h(tell)f(you)h(what)h(fonts)e(are)j(a)n(v)n(ailable)d(on)h (your)244 5400 y(machine.)1875 5649 y(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Fc(Magic)24 b(Maintainer')-5 b(s)24 b(Manual)g(#4:)30 b(Using)24 b(Magic)h(Under)g(X)f(W)l(indo)n(ws)515 b(September)25 b(26,)g(2001)145 68 y Fa(\017)49 b Fc(Strange)25 b(Color)g(Ef)n(fects)244 188 y(Magic)35 b(often)h(co-e)o(xists)e (rather)j(uneasily)d(with)h(other)h(X)g(applications)e(because)i(it)g (is)f(pick)o(y)g(about)244 309 y(which)c(colors)g(it)g(is)g(allocated.) 50 b(If)32 b(possible,)g(it)f(tries)g(to)g(allocate)g(the)g(colors)h (it)e(requires)i(out)f(of)g(the)244 429 y(display')-5 b(s)33 b(def)o(ault)h(colormap)g(because)h(this)f(perturbs)g(other)h (applications)e(the)i(least.)60 b(If)35 b(this)f(f)o(ails,)244 549 y(ho)n(we)n(v)o(er)l(,)d(Magic)g(mak)o(es)g(its)f(o)n(wn)h (colormap.)49 b(When)31 b(this)f(colormap)h(gets)g(installed)f(is)g(a)i (function)244 670 y(of)f(the)g(windo)n(w)f(manager;)k(most)d(windo)n(w) e(managers)j(install)d(it)i(when)g(the)g(cursor)h(is)f(in)f(the)i (magic)244 790 y(windo)n(w)-6 b(.)45 b(Unfortunately)-6 b(,)29 b(there)i(is)e(no)h(w)o(ay)g(to)g(guarantee)g(that)g(the)g (windo)n(w)f(manager)h(installs)e(the)244 911 y(magic)c(colormap)f (correctly;)i(if)f(you)g(get)g(erratic)h(colormap)f(beha)n(vior)l(,)g (try)g(using)f(a)i(lo)n(wer)e(number)h(of)244 1031 y(planes)g(or)h (reducing)g(the)f(number)h(of)g(colors)f(that)g(other)h(applications)e (use.)145 1244 y Fa(\017)49 b Fc(When)29 b(magic')-5 b(s)27 b(colormap)h(is)g(being)g(used,)i(other)e(windo)n(ws)f(may)h (change)h(color)l(,)h(possibly)c(to)j(some)244 1365 y(unusable)19 b(combination)e(such)i(as)h(black)f(on)g(black)h(or)f(white)g(on)g (white.)29 b(This)18 b(problem)h(can)h(sometimes)244 1485 y(be)f(ameliorated)f(by)h(changing)f(the)g(constants)g(X)p 1957 1485 30 4 v 36 w(COLORMAP)p 2546 1485 V 36 w(B)m(ASE)h(and)g(X)p 3087 1485 V 36 w(COLORMAP)p 3676 1485 V 36 w(RESER)-8 b(VED)244 1605 y(in)31 b(grX11su2.c;)i(a)f(more)f(complete)g (description)f(of)h(what)h(these)f(constants)f(do)h(is)g(included)g(in) g(that)244 1726 y(\002le.)68 b(V)-11 b(alues)37 b(for)g(these)g (constants)f(that)h(are)g(incompatible)f(with)g(your)h(machine)g(will)f (sometimes)244 1846 y(generate)25 b(Xerrors)g(in)g(XQueryColors.)145 2059 y Fa(\017)49 b Fc(F)o(ailure)25 b(to)f(prompt)g(user)h(for)g (windo)n(w)e(position)244 2180 y(Whether)e(or)g(not)f(the)g(designer)h (is)f(prompted)g(for)h(a)g(windo)n(w')-5 b(s)19 b(location)h(is)g (dependent)g(on)h(the)f(windo)n(w)244 2300 y(manager)-5 b(.)30 b(Certain)25 b(windo)n(w)f(managers,)g(notably)g Fd(twm)p Fc(,)h(do)g(not)f(al)o(w)o(ays)g(do)h(this.)0 2608 y Fb(3.2)119 b(X10)30 b(Dri)o(v)o(er)0 2800 y Fc(In)c(general,)h (the)g(V)-11 b(ersion)25 b(10)i(dri)n(v)o(er)e(is)h(less)g(reliable)g (than)g(the)g(X11)g(one.)36 b(If)26 b(you)g(ha)n(v)o(e)g(the)h(choice,) f(you)g(are)0 2920 y(better)f(of)n(f)f(running)g(under)h(X11.)145 3162 y Fa(\017)49 b Fc(grX2.GrXSetCMap:)31 b(F)o(ailed)24 b(to)g(get)h(color)g(cells)244 3283 y(Magic)37 b(gi)n(v)o(es)g(this)g (error)h(when)g(it)f(can')n(t)i(get)f(suf)n(\002cient)f(colors)g(to)h (run.)70 b(This)37 b(can)h(be)g(caused)g(by)244 3403 y(running)29 b(Magic)h(on)f(a)i(machine)e(with)h(an)g(insuf)n (\002cient)f(number)g(of)h(planes)g(\(8)g(planes)g(are)g(generally)244 3523 y(required)37 b(to)f(run)h(a)g(7)g(bit)f(dstyles)f(\002le\),)41 b(or)36 b(by)h(ha)n(ving)f(too)g(man)o(y)g(colors)g(already)h(used)g (by)f(other)244 3644 y(applications.)48 b(T)m(ry)30 b(using)g(only)g (black)h(and)g(white)g(xterms,)g(xclocks,)h(etc.,)h(and)e(see)g(if)g (the)g(problem)244 3764 y(goes)24 b(a)o(w)o(ay)-6 b(.)145 3978 y Fa(\017)49 b Fc(Couldn)535 3965 y(\264)538 3978 y(t)24 b(get)h(7)f(planes;)g(allocating)g(by)h(color)244 4098 y(Certain)i(X10)g(serv)o(ers,)h(most)e(notably)g(the)h(V)-11 b(axstationII-GPX,)26 b(allocate)h(colors)g(in)g(such)g(a)g(w)o(ay)h (that)244 4218 y(Magic)35 b(can)h(ne)n(v)o(er)e(get)i(the)f(7)g(color)g (planes)h(that)e(it)h(w)o(ants.)62 b(When)36 b(this)e(happens,)k(Magic) d(instead)244 4339 y(allocates)23 b(128)g(colors.)30 b(This)22 b(is)h(better)g(than)g(nothing,)g(b)n(ut)f(not)h(by)g(much;)g (strange)g(colors)g(often)h(result)244 4459 y(when)h(layers)f(o)o(v)o (erlap.)0 4811 y Fe(4)143 b(Ackno)o(wledgments)0 5039 y Fc(Man)o(y)35 b(people)h(share)h(the)f(credit)g(\(and)g(the)h (blame\))f(for)g(the)g(Magic)g(X)g(dri)n(v)o(ers.)64 b(The)36 b(original)g(X10)g(port)0 5159 y(w)o(as)f(done)g(by)f(Mark)h (Linton)f(and)g(Doug)h(P)o(an)g(at)f(Stanford)i(Uni)n(v)o(ersity)-6 b(.)58 b(W)-8 b(alter)35 b(Scott)f(and)h(Eric)g(Luno)n(w)0 5280 y(of)i(La)o(wrence)g(Li)n(v)o(ermore)e(National)h(Laboratories)h (modi\002ed)f(the)g(dri)n(v)o(er)g(and)h(the)g(windo)n(ws)e(module)g (so)0 5400 y(that)26 b(magic)g(windo)n(ws)f(act)i(lik)o(e)f(normal)f(X) i(windo)n(ws.)34 b(Meanwhile,)26 b(Da)n(v)o(e)g(Durfee)i(and)e(Markus)g (G.)g(Wloka)1875 5649 y(\2263\226)p eop %%Page: 4 4 4 3 bop 0 -180 a Fc(September)25 b(26,)f(2001)516 b(Magic)25 b(Maintainer')-5 b(s)23 b(Manual)h(#4:)31 b(Using)23 b(Magic)i(Under)g(X)g(W)l(indo)n(ws)0 68 y(of)30 b(Bro)n(wn)g(Uni)n(v)o (ersity)d(impro)o(v)o(ed)h(the)i(reliability)e(of)i(the)g(Stanford)g (X10)f(dri)n(v)o(er)g(and)h(added)g(support)f(for)h(a)0 188 y(v)n(ariable)i(number)g(of)g(planes.)53 b(Marco)33 b(P)o(apa)f(of)h(USC)g(con)l(v)o(erted)f(the)g(Bro)n(wn)g(X10)g(dri)n (v)o(er)g(to)g(X11.)53 b(Con-)0 309 y(currently)-6 b(,)38 b(someone)d(at)h(the)f(Uni)n(v)o(ersity)f(of)i(W)-8 b(ashington)34 b(con)l(v)o(erted)h(the)h(Stanford)g(X10)f(dri)n(v)o(er)g(to)h(X11.)0 429 y(The)26 b(X11)h(dri)n(v)o(er)e(in)h(this)g(distrib)n(ution)e(is)i (predominantly)e(a)j(mer)n(ge)g(of)g(the)f(UW)g(dri)n(v)o(er)g(with)g (the)g(multiwin-)0 549 y(do)n(w)32 b(features)g(of)h(the)f(LLNL)g(dri)n (v)o(er)-5 b(.)52 b(Some)33 b(of)f(the)g(ideas)h(for)f(supporting)f (dif)n(fering)h(plane)g(counts)f(were)0 670 y(borro)n(wed)26 b(from)g(the)h(USC/Bro)n(wn)g(w)o(ork.)36 b(Thanks)26 b(to)g(the)h(Digital)e(Equipment)g(Corporation)h(W)-8 b(estern)27 b(Re-)0 790 y(search)34 b(Laboratory)e(\(DECWRL\))i(for)g (use)e(of)i(their)e(computer)h(f)o(acilities,)h(and)f(to)f(Mik)o(e)h (Cho)n(w)f(of)i(Apple)0 911 y(Computer)24 b(for)h(the)g(Macintosh)f (II-speci\002c)h(changes.)1875 5649 y(\2264\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/doc/psfiles/tut2.ps0000644000175000001440000024645710751423606015154 0ustar timusers%!PS-Adobe-2.0 %%Creator: dvipsk 5.58f Copyright 1986, 1994 Radical Eye Software %%Title: tut2.dvi %%Pages: 12 %%PageOrder: Ascend %%BoundingBox: 0 0 612 792 %%DocumentFonts: Times-Bold Times-Italic Times-Roman Courier %%DocumentPaperSizes: Letter %%EndComments %DVIPSCommandLine: dvips tut2.dvi -o tut2.ps %DVIPSParameters: dpi=600, comments removed %DVIPSSource: TeX output 2001.09.26:1352 %%BeginProcSet: tex.pro /TeXDict 250 dict def TeXDict begin /N{def}def /B{bind def}N /S{exch}N /X{S N}B /TR{translate}N /isls false N /vsize 11 72 mul N /hsize 8.5 72 mul N /landplus90{false}def /@rigin{isls{[0 landplus90{1 -1}{-1 1} ifelse 0 0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[matrix currentmatrix{dup dup round sub abs 0.00001 lt{round}if} forall round exch round exch]setmatrix}N /@landscape{/isls true N}B /@manualfeed{statusdict /manualfeed true put}B /@copies{/#copies X}B /FMat[1 0 0 -1 0 0]N /FBB[0 0 0 0]N /nn 0 N /IE 0 N /ctr 0 N /df-tail{ /nn 8 dict N nn begin /FontType 3 N /FontMatrix fntrx N /FontBBox FBB N string /base X array /BitMaps X /BuildChar{CharBuilder}N /Encoding IE N end dup{/foo setfont}2 array copy cvx N load 0 nn put /ctr 0 N[}B /df{ /sf 1 N /fntrx FMat N df-tail}B /dfs{div /sf X /fntrx[sf 0 0 sf neg 0 0] N df-tail}B /E{pop nn dup definefont setfont}B /ch-width{ch-data dup length 5 sub get}B /ch-height{ch-data dup length 4 sub get}B /ch-xoff{ 128 ch-data dup length 3 sub get sub}B /ch-yoff{ch-data dup length 2 sub get 127 sub}B /ch-dx{ch-data dup length 1 sub get}B /ch-image{ch-data dup type /stringtype ne{ctr get /ctr ctr 1 add N}if}B /id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N /CharBuilder{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get /ch-data X pop /ctr 0 N ch-dx 0 ch-xoff ch-yoff ch-height sub ch-xoff ch-width add ch-yoff setcachedevice ch-width ch-height true[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 sub]{ch-image}imagemask restore}B /D{/cc X dup type /stringtype ne{]} if nn /base get cc ctr put nn /BitMaps get S ctr S sf 1 ne{dup dup length 1 sub dup 2 index S get sf div put}if put /ctr ctr 1 add N}B /I{ cc 1 add D}B /bop{userdict /bop-hook known{bop-hook}if /SI save N @rigin 0 0 moveto /V matrix currentmatrix dup 1 get dup mul exch 0 get dup mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N /eop{SI restore userdict /eop-hook known{eop-hook}if showpage}N /@start{userdict /start-hook known{start-hook}if pop /VResolution X /Resolution X 1000 div /DVImag X /IE 256 array N 0 1 255{IE S 1 string dup 0 3 index put cvn put}for 65781.76 div /vsize X 65781.76 div /hsize X}N /p{show}N /RMat[1 0 0 -1 0 0]N /BDot 260 string N /rulex 0 N /ruley 0 N /v{/ruley X /rulex X V}B /V {}B /RV statusdict begin /product where{pop product dup length 7 ge{0 7 getinterval dup(Display)eq exch 0 4 getinterval(NeXT)eq or}{pop false} ifelse}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale rulex ruley false RMat{BDot}imagemask grestore}}{{gsave TR -.1 .1 TR rulex ruley scale 1 1 false RMat{BDot}imagemask grestore}}ifelse B /QV{gsave newpath transform round exch round exch itransform moveto rulex 0 rlineto 0 ruley neg rlineto rulex neg 0 rlineto fill grestore}B /a{moveto}B /delta 0 N /tail {dup /delta X 0 rmoveto}B /M{S p delta add tail}B /b{S p tail}B /c{-4 M} B /d{-3 M}B /e{-2 M}B /f{-1 M}B /g{0 M}B /h{1 M}B /i{2 M}B /j{3 M}B /k{ 4 M}B /w{0 rmoveto}B /l{p -4 w}B /m{p -3 w}B /n{p -2 w}B /o{p -1 w}B /q{ p 1 w}B /r{p 2 w}B /s{p 3 w}B /t{p 4 w}B /x{0 S rmoveto}B /y{3 2 roll p a}B /bos{/SS save N}B /eos{SS restore}B end %%EndProcSet %%BeginFont: Times-Bold % @@psencodingfile@{ % author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", % version = "0.6", % date = "22 June 1996", % filename = "8r.enc", % email = "kb@@mail.tug.org", % address = "135 Center Hill Rd. // Plymouth, MA 02360", % codetable = "ISO/ASCII", % checksum = "119 662 4424", % docstring = "Encoding for TrueType or Type 1 fonts to be used with TeX." % @} % % Idea is to have all the characters normally included in Type 1 fonts % available for typesetting. This is effectively the characters in Adobe % Standard Encoding + ISO Latin 1 + extra characters from Lucida. % % Character code assignments were made as follows: % % (1) the Windows ANSI characters are almost all in their Windows ANSI % positions, because some Windows users cannot easily reencode the % fonts, and it makes no difference on other systems. The only Windows % ANSI characters not available are those that make no sense for % typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen % (173). quotesingle and grave are moved just because it's such an % irritation not having them in TeX positions. % % (2) Remaining characters are assigned arbitrarily to the lower part % of the range, avoiding 0, 10 and 13 in case we meet dumb software. % % (3) Y&Y Lucida Bright includes some extra text characters; in the % hopes that other PostScript fonts, perhaps created for public % consumption, will include them, they are included starting at 0x12. % % (4) Remaining positions left undefined are for use in (hopefully) % upward-compatible revisions, if someday more characters are generally % available. % % (5) hyphen appears twice for compatibility with both ASCII and Windows. % /TeXBase1Encoding [ % 0x00 (encoded characters from Adobe Standard not in Windows 3.1) /.notdef /dotaccent /fi /fl /fraction /hungarumlaut /Lslash /lslash /ogonek /ring /.notdef /breve /minus /.notdef % These are the only two remaining unencoded characters, so may as % well include them. /Zcaron /zcaron % 0x10 /caron /dotlessi % (unusual TeX characters available in, e.g., Lucida Bright) /dotlessj /ff /ffi /ffl /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef % very contentious; it's so painful not having quoteleft and quoteright % at 96 and 145 that we move the things normally found there down to here. /grave /quotesingle % 0x20 (ASCII begins) /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash % 0x30 /zero /one /two /three /four /five /six /seven /eight /nine /colon /semicolon /less /equal /greater /question % 0x40 /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O % 0x50 /P /Q /R /S /T /U /V /W /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore % 0x60 /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o % 0x70 /p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde /.notdef % rubout; ASCII ends % 0x80 /.notdef /.notdef /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl /circumflex /perthousand /Scaron /guilsinglleft /OE /.notdef /.notdef /.notdef % 0x90 /.notdef /.notdef /.notdef /quotedblleft /quotedblright /bullet /endash /emdash /tilde /trademark /scaron /guilsinglright /oe /.notdef /.notdef /Ydieresis % 0xA0 /.notdef % nobreakspace /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen % Y&Y (also at 45); Windows' softhyphen /registered /macron % 0xD0 /degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown % 0xC0 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis % 0xD0 /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls % 0xE0 /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis % 0xF0 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis ] def %%EndFont %%BeginProcSet: texps.pro TeXDict begin /rf{findfont dup length 1 add dict begin{1 index /FID ne 2 index /UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics exch def dict begin Encoding{exch dup type /integertype ne{pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} ifelse}forall Metrics /Metrics currentdict end def[2 index currentdict end definefont 3 -1 roll makefont /setfont load]cvx def}def /ObliqueSlant{dup sin S cos div neg}B /SlantFont{4 index mul add}def /ExtendFont{3 -1 roll mul exch}def /ReEncodeFont{/Encoding exch def}def end %%EndProcSet %%BeginProcSet: special.pro TeXDict begin /SDict 200 dict N SDict begin /@SpecialDefaults{/hs 612 N /vs 792 N /ho 0 N /vo 0 N /hsc 1 N /vsc 1 N /ang 0 N /CLIP 0 N /rwiSeen false N /rhiSeen false N /letter{}N /note{}N /a4{}N /legal{}N}B /@scaleunit 100 N /@hscale{@scaleunit div /hsc X}B /@vscale{@scaleunit div /vsc X}B /@hsize{/hs X /CLIP 1 N}B /@vsize{/vs X /CLIP 1 N}B /@clip{ /CLIP 2 N}B /@hoffset{/ho X}B /@voffset{/vo X}B /@angle{/ang X}B /@rwi{ 10 div /rwi X /rwiSeen true N}B /@rhi{10 div /rhi X /rhiSeen true N}B /@llx{/llx X}B /@lly{/lly X}B /@urx{/urx X}B /@ury{/ury X}B /magscale true def end /@MacSetUp{userdict /md known{userdict /md get type /dicttype eq{userdict begin md length 10 add md maxlength ge{/md md dup length 20 add dict copy def}if end md begin /letter{}N /note{}N /legal{} N /od{txpose 1 0 mtx defaultmatrix dtransform S atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{itransform lineto} }{6 -2 roll transform 6 -2 roll transform 6 -2 roll transform{ itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll curveto}}{{ closepath}}pathforall newpath counttomark array astore /gc xdf pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack}if}N /txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 -1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop 90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr 1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr 2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 -1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S TR}if}N /cp {pop pop showpage pm restore}N end}if}if}N /normalscale{Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale}if 0 setgray} N /psfts{S 65781.76 div N}N /startTexFig{/psf$SavedState save N userdict maxlength dict begin /magscale true def normalscale currentpoint TR /psf$ury psfts /psf$urx psfts /psf$lly psfts /psf$llx psfts /psf$y psfts /psf$x psfts currentpoint /psf$cy X /psf$cx X /psf$sx psf$x psf$urx psf$llx sub div N /psf$sy psf$y psf$ury psf$lly sub div N psf$sx psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub TR /showpage{}N /erasepage{}N /copypage{}N /p 3 def @MacSetUp}N /doclip{ psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath moveto}N /endTexFig{end psf$SavedState restore}N /@beginspecial{SDict begin /SpecialSave save N gsave normalscale currentpoint TR @SpecialDefaults count /ocount X /dcount countdictstack N}N /@setspecial {CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR }{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury lineto closepath clip}if /showpage{}N /erasepage{}N /copypage{}N newpath }N /@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{ end}repeat grestore SpecialSave restore end}N /@defspecial{SDict begin} N /@fedspecial{end}B /li{lineto}B /rl{rlineto}B /rc{rcurveto}B /np{ /SaveX currentpoint /SaveY X N 1 setlinecap newpath}N /st{stroke SaveX SaveY moveto}N /fil{fill SaveX SaveY moveto}N /ellipse{/endangle X /startangle X /yrad X /xrad X /savematrix matrix currentmatrix N TR xrad yrad scale 0 0 1 startangle endangle arc savematrix setmatrix}N end %%EndProcSet TeXDict begin 40258431 52099146 1000 600 600 (tut2.dvi) @start /Fa 134[60 3[60 60 60 2[60 60 3[60 60 1[60 2[60 60 60 9[60 39[60 2[60 11[60 34[{ TeXBase1Encoding ReEncodeFont }16 100.000003 /Courier rf /Fb 119[33 13[44 50 50 72 50 55 33 39 44 55 55 50 55 83 28 55 1[28 55 50 33 44 55 44 55 50 6[66 2[100 72 72 66 55 72 78 61 78 72 94 3[39 1[78 61 66 72 72 66 72 6[33 4[50 2[50 50 50 1[25 1[25 7[50 2[33 30[55 2[{ TeXBase1Encoding ReEncodeFont }56 100.000003 /Times-Bold rf /Fc 138[66 40 47 53 2[60 66 100 33 2[33 66 2[53 66 53 1[60 12[80 6[113 9[86 8[40 55[66 2[{ TeXBase1Encoding ReEncodeFont }19 119.999948 /Times-Bold rf /Fd 105[50 1[44 44 10[33 13[44 50 50 72 50 50 28 39 33 50 50 50 50 78 28 50 28 28 50 50 33 44 50 44 50 44 3[33 1[33 61 72 1[94 72 72 61 55 66 72 55 72 72 89 61 2[33 72 72 55 61 72 66 66 72 92 4[28 28 50 50 50 50 50 50 50 50 50 50 28 25 33 25 2[33 33 33 2[50 50 1[33 29[55 55 2[{ TeXBase1Encoding ReEncodeFont }80 100.000003 /Times-Roman rf /Fe 134[44 44 66 1[50 28 39 39 1[50 50 50 72 28 1[28 28 50 50 28 44 50 44 50 50 9[83 1[72 55 50 2[61 72 2[55 1[44 5[72 21[25 1[25 2[33 33 37[50 2[{ TeXBase1Encoding ReEncodeFont } 36 100.000003 /Times-Italic rf /Ff 134[72 2[72 80 48 56 64 1[80 72 80 120 40 2[40 80 72 1[64 80 64 80 72 9[143 1[104 96 80 2[88 112 1[135 96 5[88 96 1[104 96 7[48 72 72 72 72 72 72 72 72 72 72 12[72 35[{ TeXBase1Encoding ReEncodeFont }43 143.999997 /Times-Bold rf end %%EndProlog %%BeginSetup %%Feature: *Resolution 600dpi TeXDict begin %%PaperSize: Letter %%EndSetup %%Page: 1 1 1 0 bop 490 101 a Ff(Magic)36 b(T)-13 b(utorial)34 b(#2:)43 b(Basic)35 b(P)o(ainting)f(and)h(Selection)1618 521 y Fe(J)n(ohn)24 b(Ousterhout)1401 941 y Fd(Computer)g(Science)i(Di)n (vision)1020 1062 y(Electrical)f(Engineering)f(and)h(Computer)f (Sciences)1473 1182 y(Uni)n(v)o(ersity)f(of)i(California)1544 1303 y(Berk)o(ele)o(y)-6 b(,)24 b(CA)h(94720)1448 1573 y Fe(\(Updated)f(by)h(other)o(s,)f(too.\))1053 1843 y Fd(This)g(tutorial)g(corresponds)g(to)g(Magic)h(v)o(ersion)e(7.)0 2317 y Fc(T)-11 b(utorials)30 b(to)f(r)n(ead)h(\002rst:)300 2479 y Fd(Magic)24 b(T)l(utorial)g(#1:)30 b(Getting)24 b(Started)0 2641 y Fc(Commands)29 b(intr)n(oduced)j(in)f(this)f (tutorial:)300 2803 y Fd(:box,)24 b(:clockwise,)g(:cop)o(y)-6 b(,)24 b(:erase,)h(:\002ndbox)f(:grid,)g(:label,)300 2923 y(:layers,)g(:macro,)h(:mo)o(v)o(e,)e(:paint,)h(:redo,)g(:sa)n(v)o (e,)g(:select,)300 3043 y(:side)n(w)o(ays,)f(:undo,)h(:upsidedo)n(wn,)f (:vie)n(w)-6 b(,)23 b(:what,)h(:writeall,)g(:zoom)0 3205 y Fc(Macr)n(os)29 b(intr)n(oduced)i(in)g(this)f(tutorial:)300 3379 y Fd(a,)25 b(A,)g(c,)g(d,)f(\210D,)h(e,)g(E,)g(g,)g(G,)f(q,)h(Q,)g (r)l(,)g(R,)g(s,)g(S,)g(t,)f(T)-7 b(,)25 b(u,)f(U,)h(v)-6 b(,)24 b(w)-6 b(,)25 b(W)-9 b(,)24 b(z,)h(Z,)g(4)0 4213 y Ff(1)143 b(Cells)35 b(and)g(P)o(aint)0 4437 y Fd(In)i(Magic,)h(a)f (circuit)f(layout)g(is)g(a)g(hierarchical)h(collection)f(of)g Fe(cells)p Fd(.)65 b(Each)37 b(cell)f(contains)g(three)h(things:)0 4557 y(colored)26 b(shapes,)g(called)g Fe(paint)p Fd(,)f(that)g (de\002ne)h(the)g(circuit')-5 b(s)25 b(structure;)h(te)o(xtual)f Fe(labels)g Fd(attached)h(to)f(the)h(paint;)0 4678 y(and)c Fe(subcells)p Fd(,)g(which)g(are)h(instances)f(of)h(other)f(cells.)30 b(The)22 b(paint)g(is)g(what)g(determines)g(the)g(e)n(v)o(entual)f (function)0 4798 y(of)33 b(the)g(VLSI)h(circuit.)55 b(Labels)33 b(and)g(subcells)g(are)g(a)h(con)l(v)o(enience)f(for)g(you)g(in)g (managing)f(the)h(layout)f(and)0 4918 y(pro)o(vide)c(a)i(w)o(ay)f(of)g (communicating)e(information)h(between)h(v)n(arious)f(synthesis)g(and)h (analysis)f(tools.)43 b(This)0 5039 y(tutorial)23 b(e)o(xplains)f(ho)n (w)h(to)g(create)i(and)f(edit)f(paint)g(and)h(labels)f(in)g(simple)g (single-cell)g(designs,)f(using)h(the)h(ba-)0 5159 y(sic)h(painting)g (commands.)32 b(\223Magic)26 b(T)l(utorial)e(#3:)32 b(Adv)n(anced)25 b(P)o(ainting)g(\(W)l(iring)g(and)g(Plo)n(wing\)\224)g(describes)0 5280 y(some)35 b(more)h(adv)n(anced)f(features)h(for)h(manipulating)c (paint.)63 b(F)o(or)36 b(information)e(on)i(ho)n(w)f(to)g(b)n(uild)g (up)g(cell)0 5400 y(hierarchies,)25 b(see)g(\223Magic)g(T)l(utorial)e (#4:)30 b(Cell)25 b(Hierarchies\224.)1875 5649 y(\2261\226)p eop %%Page: 2 2 2 1 bop 0 -180 a Fd(September)25 b(26,)f(2001)1180 b(Magic)24 b(T)l(utorial)f(#2:)31 b(Basic)25 b(P)o(ainting)e(and)i(Selection)0 99 y Ff(2)143 b(P)o(ainting)34 b(and)h(Erasing)0 374 y Fd(Enter)e(Magic)g(to)g(edit)g(the)g(cell)g Fb(tut2a)h Fd(\(type)f Fb(magic)g(tut2a)g Fd(to)g(the)g(Unix)g(shell;)j(follo)n(w) c(the)h(directions)f(in)0 495 y(\223T)l(utorial)i(#1:)50 b(Getting)34 b(Started\224)h(if)g(you)f(ha)n(v)o(e)h(an)o(y)f(problems) g(with)g(this\).)60 b(The)35 b Fb(tut2a)g Fd(cell)g(is)f(a)i(sort)e(of) 0 615 y(palette:)g(it)26 b(sho)n(ws)g(a)h(splotch)e(of)i(each)g(of)g (se)n(v)o(eral)f(paint)g(layers)h(and)g(gi)n(v)o(es)e(the)h(names)h (that)f(Magic)g(uses)h(for)0 736 y(the)e(layers.)146 881 y(The)d(tw)o(o)f(basic)h(layout)f(operations)f(are)j(painting)d (and)i(erasing.)29 b(The)o(y)21 b(can)h(be)g(in)l(v)n(ok)o(ed)f(using)g (the)g Fb(:paint)0 1001 y Fd(and)31 b Fb(:erase)h Fd(long)f(commands,)g (or)h(using)e(the)h(b)n(uttons.)49 b(The)31 b(easiest)g(w)o(ay)h(to)f (paint)f(and)i(erase)g(is)f(with)f(the)0 1122 y(mouse)e(b)n(uttons.)41 b(T)-8 b(o)28 b(paint,)h(position)e(the)h(box)h(o)o(v)o(er)e(the)i (area)h(you')-5 b(d)28 b(lik)o(e)g(to)g(paint,)h(then)f(mo)o(v)o(e)g (the)g(cursor)0 1242 y(o)o(v)o(er)34 b(a)i(color)f(and)g(click)g(the)g (middle)f(mouse)h(b)n(utton.)61 b(T)-8 b(o)35 b(erase)h(e)n(v)o (erything)d(in)i(an)g(area,)k(place)c(the)h(box)0 1363 y(o)o(v)o(er)25 b(the)h(area,)h(mo)o(v)o(e)e(the)h(cursor)g(o)o(v)o(er) f(a)h(blank)g(spot,)f(and)h(click)g(the)g(middle)f(mouse)g(b)n(utton.) 33 b(T)m(ry)25 b(painting)0 1483 y(and)31 b(erasing)h(v)n(arious)e (colors.)50 b(If)32 b(the)f(screen)h(gets)f(totally)f(messed)h(up,)i (you)e(can)g(al)o(w)o(ays)h(e)o(xit)e(Magic)h(and)0 1603 y(restart)j(it.)58 b(While)33 b(you')-5 b(re)34 b(painting,)h(white)f (dots)f(may)g(occasionally)g(appear)i(and)f(disappear)-5 b(.)57 b(These)34 b(are)0 1724 y(design)g(rule)g(violations)e(detected) j(by)f(Magic,)i(and)e(will)g(be)g(e)o(xplained)f(in)h(\223Magic)h(T)l (utorial)e(#6:)49 b(Design)0 1844 y(Rule)25 b(Checking\224.)31 b(Y)-11 b(ou)24 b(can)i(ignore)e(them)g(for)h(no)n(w)-6 b(.)146 1990 y(It')h(s)34 b(completely)g(le)o(gal)f(to)i(paint)f(one)g (layer)h(on)g(top)f(of)h(another)-5 b(.)59 b(When)35 b(this)f(happens,)i(one)f(of)g(three)0 2110 y(things)21 b(may)g(occur)-5 b(.)30 b(In)22 b(some)f(cases,)i(the)f(layers)g(are)h (independent,)e(so)h(what)g(you')o(ll)f(see)h(is)f(a)i(combination)d (of)0 2230 y(the)26 b(tw)o(o,)f(as)h(if)g(each)g(were)h(a)f (transparent)g(colored)f(foil.)34 b(This)25 b(happens,)g(for)h(e)o (xample,)f(if)h(you)g(paint)f(metal1)0 2351 y(\(blue\))e(on)f(top)g(of) g(polysilicon)f(\(red\).)30 b(In)23 b(other)f(cases,)h(when)g(you)f (paint)g(one)g(layer)h(on)f(top)g(of)h(another)f(you')o(ll)0 2471 y(get)29 b(something)e(dif)n(ferent)h(from)g(either)h(of)g(the)g (tw)o(o)f(original)g(layers.)42 b(F)o(or)29 b(e)o(xample,)g(painting)e (poly)h(on)h(top)0 2591 y(of)e(ndif)n(f)f(produces)h(ntransistor)e (\(try)i(this\).)36 b(In)27 b(still)f(other)h(cases)g(the)f(ne)n(w)h (layer)g(replaces)g(the)g(old)f(one:)35 b(this)0 2712 y(happens,)d(for)f(e)o(xample,)g(if)g(you)f(paint)h(a)g(pcontact)f(on)h (top)f(of)h(ntransistor)-5 b(.)47 b(T)m(ry)30 b(painting)g(dif)n (ferent)g(layers)0 2832 y(on)c(top)g(of)h(each)g(other)g(to)f(see)h (what)g(happens.)35 b(The)27 b(meaning)f(of)h(the)f(v)n(arious)g (layers)g(is)g(discussed)g(in)g(more)0 2953 y(detail)e(in)h(Section)f (11)h(belo)n(w)-6 b(.)146 3098 y(There)29 b(is)f(a)h(second)f(w)o(ay)h (of)f(erasing)g(paint)g(that)g(allo)n(ws)f(you)h(to)g(erase)h(some)f (layers)g(without)f(af)n(fecting)0 3218 y(others.)45 b(This)29 b(is)h(the)f(macro)h Fb(\210D)g Fd(\(control-D,)f(for)h(\223) p Fb(D)p Fd(elete)g(paint\224\).)46 b(T)-8 b(o)29 b(use)h(it,)g (position)e(the)i(box)f(o)o(v)o(er)g(the)0 3339 y(area)24 b(to)g(be)f(erased,)h(then)f(mo)o(v)o(e)f(the)i(crosshair)f(o)o(v)o(er) g(a)g(splotch)g(of)g(paint)g(containing)f(the)i(layer\(s\))g(you')-5 b(d)23 b(lik)o(e)0 3459 y(to)28 b(erase.)43 b(T)-8 b(ype)28 b Fb(\210D)h Fd(k)o(e)o(y)e(on)i(the)f(te)o(xt)g(k)o(e)o(yboard:)37 b(the)28 b(colors)g(underneath)g(the)h(cursor)f(will)g(be)g(erased)h (from)0 3580 y(the)f(area)h(underneath)f(the)h(box,)f(b)n(ut)g(no)g (other)g(layers)g(will)g(be)g(af)n(fected.)42 b(Experiment)27 b(around)h(with)g(the)g Fb(\210D)0 3700 y Fd(macro)c(to)f(try)h(dif)n (ferent)f(combinations)e(of)j(paints)f(and)h(erases.)31 b(If)24 b(the)f(cursor)h(is)f(o)o(v)o(er)g(empty)g(space)h(then)f(the)0 3820 y Fb(\210D)i Fd(macro)g(is)f(equi)n(v)n(alent)f(to)i(the)f(middle) g(mouse)g(b)n(utton:)29 b(it)24 b(erases)i(e)n(v)o(erything.)146 3966 y(Y)-11 b(ou)25 b(can)g(also)f(paint)h(and)f(erase)i(using)e(the)g (long)g(commands)900 4394 y Fb(:paint)i Fe(layer)o(s)900 4515 y Fb(:erase)f Fe(layer)o(s)146 4918 y Fd(In)j(each)h(of)e(these)h (commands)f Fe(layer)o(s)g Fd(is)g(one)h(or)g(more)f(layer)h(names)g (separated)g(by)f(commas)g(\(you)h(can)0 5039 y(also)f(use)g(spaces)h (for)f(separators,)h(b)n(ut)f(only)f(if)i(you)f(enclose)g(the)g(entire) g(list)f(in)h(double-quotes\).)37 b(An)o(y)27 b(layer)0 5159 y(can)h(be)g(abbre)n(viated)f(as)h(long)f(as)h(the)f(abbre)n (viation)g(is)g(unambiguous.)37 b(F)o(or)28 b(e)o(xample,)g Fb(:paint)g(poly)-5 b(,metal1)0 5280 y Fd(will)26 b(paint)h(the)g (polysilicon)f(and)h(metal1)f(layers.)39 b(The)27 b(macro)g Fb(\210D)h Fd(is)f(prede\002ned)h(by)f(Magic)g(to)g(be)g Fb(:erase)h($)0 5400 y Fd(\()p Fb($)d Fd(is)f(a)h(pseudo-layer)g(that)f (means)h(\223all)f(layers)h(underneath)g(the)f(cursor\224\).)1875 5649 y(\2262\226)p eop %%Page: 3 3 3 2 bop 0 -180 a Fd(Magic)24 b(T)l(utorial)g(#2:)30 b(Basic)25 b(P)o(ainting)f(and)h(Selection)1179 b(September)25 b(26,)g(2001)0 99 y Ff(3)143 b(Undo)0 322 y Fd(There)26 b(are)f(probably)g(going)f(to) h(be)g(times)f(when)h(you')o(ll)f(do)h(things)f(that)g(you')o(ll)g (later)i(wish)e(you)h(hadn')n(t.)31 b(F)o(or)n(-)0 443 y(tunately)-6 b(,)23 b(Magic)h(has)h(an)g(undo)f(f)o(acility)g(that)g (you)g(can)h(use)f(to)h(restore)f(things)g(after)h(you')-5 b(v)o(e)24 b(made)g(mistak)o(es.)0 563 y(The)h(command)900 789 y Fb(:undo)146 1015 y Fd(\(or)l(,)k(alternati)n(v)o(ely)-6 b(,)27 b(the)h(macro)g Fb(u)p Fd(\))h(will)e(undo)h(the)g(ef)n(fects)g (of)g(the)g(last)f(command)h(you)f(in)l(v)n(ok)o(ed.)40 b(If)29 b(you)0 1135 y(made)36 b(a)h(mistak)o(e)e(se)n(v)o(eral)h (commands)f(back,)k(you)d(can)h(type)f Fb(:undo)h Fd(se)n(v)o(eral)f (times)f(to)h(undo)f(successi)n(v)o(e)0 1256 y(commands.)41 b(Ho)n(we)n(v)o(er)l(,)29 b(there)g(is)f(a)h(limit)e(to)h(all)h(this:) 37 b(Magic)29 b(only)f(remembers)g(ho)n(w)g(to)g(undo)g(the)h(last)f (ten)0 1376 y(or)d(so)g(commands.)30 b(If)25 b(you)g(undo)f(something)g (and)h(then)f(decide)i(you)e(w)o(anted)h(it)g(after)g(all,)g(you)f(can) i(undo)e(the)0 1496 y(undo)g(with)g(the)h(command)900 1722 y Fb(:r)n(edo)146 1948 y Fd(\()p Fb(U)34 b Fd(is)f(a)h(macro)g (for)g(this)f(command\).)56 b(T)m(ry)33 b(making)g(a)h(fe)n(w)g(paints) e(and)i(erases,)i(then)e(use)f Fb(:undo)i Fd(and)0 2068 y Fb(:r)n(edo)26 b Fd(to)e(w)o(ork)h(backw)o(ards)g(and)g(forw)o(ards)g (through)f(the)g(changes)h(you)f(made.)0 2408 y Ff(4)143 b(The)35 b(Selection)0 2631 y Fd(Once)23 b(you)e(ha)n(v)o(e)h(painted)g (a)h(piece)f(of)h(layout,)f(there)g(are)h(se)n(v)o(eral)f(commands)f (you)h(can)h(in)l(v)n(ok)o(e)e(to)h(modify)f(the)0 2752 y(layout.)31 b(Man)o(y)25 b(of)g(them)g(are)h(based)f(on)g(the)g Fe(selection)p Fd(:)31 b(you)25 b(select)g(one)g(or)h(more)f(pieces)g (of)g(the)h(design,)e(and)0 2872 y(then)g(perform)g(operations)g(such)g (as)g(cop)o(ying,)g(deletion,)f(and)h(rotation)g(on)g(the)g(selected)g (things.)29 b(T)-8 b(o)24 b(see)h(ho)n(w)0 2992 y(the)e(selection)g(w)o (orks,)g(load)g(cell)g Fb(tut2b)p Fd(.)31 b(Y)-11 b(ou)23 b(can)h(do)e(this)h(by)g(typing)f Fb(:load)h(tut2b)h Fd(if)f(you')-5 b(re)24 b(still)e(in)h(Magic,)0 3113 y(or)i(by)f(starting)g(up)h(Magic)f(with)g(the)h(shell)f(command)g Fb(magic)g(tut2b)p Fd(.)146 3233 y(The)31 b(\002rst)g(thing)f(to)g(do)h (is)f(to)g(learn)i(ho)n(w)d(to)i(select.)48 b(Mo)o(v)o(e)30 b(the)g(cursor)h(o)o(v)o(er)f(the)h(upper)g(portion)e(of)i(the)0 3354 y(L-shaped)d(blue)g(area)i(in)e Fb(tut2b)p Fd(,)i(and)f(type)f Fb(s)p Fd(,)h(which)f(is)g(a)h(macro)f(for)h Fb(:select)p Fd(.)42 b(The)29 b(box)f(will)f(jump)h(o)o(v)o(er)f(to)0 3474 y(co)o(v)o(er)d(the)h(v)o(ertical)g(part)g(of)g(the)g(\223L)-9 b(\224.)25 b(This)f(operation)g(selected)h(a)h(chunk)e(of)h(material.) 31 b(Mo)o(v)o(e)24 b(the)h(box)f(a)o(w)o(ay)0 3594 y(from)29 b(the)h(chunk,)g(and)f(you')o(ll)g(see)h(that)f(a)h(thin)e(white)h (outline)f(is)i(left)f(around)g(the)h(chunk)f(to)g(sho)n(w)f(that)h (it')-5 b(s)0 3715 y(selected.)30 b(No)n(w)23 b(mo)o(v)o(e)f(the)h (cursor)h(o)o(v)o(er)e(the)i(v)o(ertical)e(red)i(bar)g(on)f(the)g (right)g(of)h(the)f(cell)g(and)h(type)f Fb(s)p Fd(.)30 b(The)24 b(box)0 3835 y(will)g(mo)o(v)o(e)f(o)o(v)o(er)h(that)h(bar)l (,)g(and)f(the)h(selection)f(highlighting)e(will)i(disappear)h(from)f (the)h(blue)f(area.)146 3955 y(If)29 b(you)e(type)g Fb(s)h Fd(se)n(v)o(eral)f(times)g(without)f(mo)o(ving)g(the)i(cursor)l(,)h (each)f(command)f(selects)g(a)i(slightly)c(lar)n(ger)0 4076 y(piece)39 b(of)g(material.)72 b(Mo)o(v)o(e)37 b(the)i(cursor)g (back)g(o)o(v)o(er)f(the)g(top)g(of)h(the)g(blue)f(\223L)-9 b(\224,)39 b(and)g(type)f Fb(s)h Fd(three)g(times)0 4196 y(without)24 b(mo)o(ving)f(the)h(cursor)-5 b(.)31 b(The)25 b(\002rst)g Fb(s)g Fd(selects)g(a)g(chunk)g(\(a)g(rectangular)h(re)o (gion)e(all)h(of)g(the)g(same)f(type)h(of)0 4317 y(material\).)k(The)21 b(second)f Fb(s)g Fd(selects)h(a)g Fe(r)l(e)l(gion)f Fd(\(all)g(of)h(the)f(blue)h(material)f(in)g(the)h(re)o(gion)e (underneath)i(the)f(cursor)l(,)0 4437 y(rectangular)32 b(or)g(not\).)52 b(The)32 b(third)g Fb(s)f Fd(selects)h(a)g Fe(net)g Fd(\(all)g(of)g(the)g(material)g(that)f(is)h(electrically)g (connected)f(to)0 4557 y(the)c(original)f(chunk;)i(this)f(includes)f (the)h(blue)g(metal,)h(the)f(red)g(polysilicon,)f(and)h(the)g(contact)h (that)e(connects)0 4678 y(them\).)146 4798 y(The)f(macro)g Fb(S)g Fd(\(short)g(for)g Fb(:select)g(mor)n(e)p Fd(\))h(is)e(just)g (lik)o(e)h Fb(s)f Fd(e)o(xcept)h(that)f(it)g(adds)h(on)g(to)f(the)h (selection,)f(rather)0 4918 y(than)i(replacing)g(it.)34 b(Mo)o(v)o(e)24 b(the)i(cursor)g(o)o(v)o(er)f(the)h(v)o(ertical)g(red)g (bar)g(on)g(the)g(right)f(and)i(type)e Fb(S)i Fd(to)e(see)i(ho)n(w)e (this)0 5039 y(w)o(orks.)30 b(Y)-11 b(ou)25 b(can)g(also)f(type)h Fb(S)g Fd(multiple)e(times)h(to)g(add)h(re)o(gions)f(and)h(nets)f(to)g (the)h(selection.)146 5159 y(If)i(you)f(accidentally)g(type)f Fb(s)i Fd(or)f Fb(S)h Fd(when)f(the)g(cursor)g(is)g(o)o(v)o(er)f (space,)i(you')o(ll)f(select)g(a)g(cell)h(\()p Fb(tut2b)g Fd(in)f(this)0 5280 y(case\).)32 b(Y)-11 b(ou)24 b(can)i(just)e(undo)g (this)g(for)h(no)n(w)-6 b(.)30 b(Cell)25 b(selection)f(will)g(be)h (discussed)f(in)g(\223Magic)h(T)l(utorial)f(#4:)30 b(Cell)0 5400 y(Hierarchies\224.)1875 5649 y(\2263\226)p eop %%Page: 4 4 4 3 bop 0 -180 a Fd(September)25 b(26,)f(2001)1180 b(Magic)24 b(T)l(utorial)f(#2:)31 b(Basic)25 b(P)o(ainting)e(and)i(Selection)146 68 y(Y)-11 b(ou)24 b(can)h(also)e(select)h(material)g(by)g(area:)31 b(place)24 b(the)g(box)g(around)g(the)g(material)f(you')-5 b(d)24 b(lik)o(e)f(to)h(select)g(and)0 188 y(type)g Fb(a)h Fd(\(short)f(for)i Fb(:select)f(ar)n(ea)p Fd(\).)31 b(This)24 b(will)g(select)h(all)f(of)h(the)g(material)f(underneath)h(the)f(box.) 31 b(Y)-11 b(ou)24 b(can)h(use)0 309 y(the)g(macro)g Fb(A)f Fd(to)h(add)g(material)f(to)g(the)h(selection)f(by)h(area,)g (and)g(you)f(can)i(use)e(the)h(long)f(command)900 526 y Fb(:select)h Fd([)p Fb(mor)n(e)p Fd(])p Fb(ar)n(ea)h Fe(layer)o(s)146 743 y Fd(to)32 b(select)g(only)g(material)g(on)g (certain)g(layers.)53 b(Place)34 b(the)e(box)f(around)i(e)n(v)o (erything)d(in)i Fb(tut2b)h Fd(and)f(type)0 863 y Fb(:select)25 b(ar)n(ea)h(metal1)e Fd(follo)n(wed)g(by)g Fb(:select)i(mor)n(e)f(ar)n (ea)g(poly)p Fd(.)146 984 y(If)h(you')-5 b(d)25 b(lik)o(e)g(to)h(clear) g(out)f(the)g(selection)g(without)f(modifying)g(an)o(y)h(of)h(the)f (selected)g(material,)h(you)f(can)0 1104 y(use)g(the)f(command)900 1321 y Fb(:select)h(clear)146 1539 y Fd(or)j(type)f(the)g(macro)h Fb(C)p Fd(.)f(Y)-11 b(ou)28 b(can)g(clear)g(out)f(just)f(a)i(portion)f (of)g(the)h(selection)e(by)i(typing)e Fb(:select)i(less)f Fd(or)0 1659 y Fb(:select)g(less)e(ar)n(ea)i Fe(layer)o(s)p Fd(;)f(the)g(former)g(deselects)g(paint)f(in)h(the)g(order)g(that)g Fb(:select)g Fd(selects)g(paint,)g(while)f(the)0 1779 y(latter)d(deselects)f(paint)g(under)h(the)g(box)f(\(just)g(as)h Fb(:select)h(ar)n(ea)f Fd(selects)g(paint)f(under)h(the)f(box\).)30 b(F)o(or)22 b(a)g(synopsis)0 1900 y(of)j(all)f(the)h(options)e(to)i (the)f Fb(:select)i Fd(command,)e(type)900 2117 y Fb(:select)h(help)0 2455 y Ff(5)143 b(Operations)34 b(on)h(the)g(Selection)0 2678 y Fd(Once)25 b(you')-5 b(v)o(e)24 b(made)h(a)g(selection,)f(there) h(are)h(a)f(number)f(of)h(operations)f(you)g(can)h(perform)g(on)g(it:) 900 2896 y Fb(:delete)900 3016 y(:mo)o(v)o(e)g Fd([)p Fe(dir)l(ection)f Fd([)p Fe(distance)p Fd(]])900 3136 y Fb(:str)n(etch)i Fd([)p Fe(dir)l(ection)f Fd([)p Fe(distance)p Fd(]])900 3257 y Fb(:copy)900 3377 y(:upsidedo)o(wn)900 3497 y(:sideways)900 3618 y(:clockwise)g Fd([)p Fe(de)l(gr)l(ees)p Fd(])146 3955 y(The)k Fb(:delete)i Fd(command)d(deletes)g(e)n(v)o (erything)f(that')-5 b(s)28 b(selected.)44 b(W)-8 b(atch)29 b(out:)38 b Fb(:delete)30 b Fd(is)f(dif)n(ferent)f(from)0 4076 y Fb(:erase)p Fd(,)37 b(which)c(erases)i(paint)e(from)h(the)g (area)h(underneath)f(the)g(box.)58 b(Select)35 b(the)f(red)g(bar)g(on)g (the)g(right)f(in)0 4196 y Fb(tut2b)26 b Fd(and)f(type)f Fb(d)p Fd(,)h(which)g(is)f(a)h(macro)g(for)g Fb(:delete)p Fd(.)32 b(Undo)24 b(the)h(deletion)f(with)g(the)h Fb(u)g Fd(macro.)146 4317 y(The)c Fb(:mo)o(v)o(e)g Fd(command)f(picks)g(up)g (both)g(the)h(box)f(and)h(the)f(selection)g(and)h(mo)o(v)o(es)e(them)h (so)h(that)f(the)g(lo)n(wer)n(-)0 4437 y(left)25 b(corner)h(of)f(the)g (box)g(is)g(at)g(the)g(cursor)g(location.)31 b(Select)26 b(the)f(red)g(bar)h(on)f(the)g(right)f(and)i(mo)o(v)o(e)d(it)i(so)g (that)g(it)0 4557 y(f)o(alls)j(on)g(top)f(of)i(the)f(v)o(ertical)f (part)i(of)f(the)g(blue)g(\223L)-9 b(\224.)28 b(Y)-11 b(ou)28 b(can)h(use)f Fb(t)g Fd(\(\223)p Fb(t)p Fd(ranslate\224\))h(as) g(a)f(macro)h(for)f Fb(:mo)o(v)o(e)p Fd(.)0 4678 y(Practice)k(mo)o (ving)d(v)n(arious)h(things)g(around)h(the)g(screen.)50 b(The)31 b(command)f Fb(:copy)i Fd(and)f(its)g(macro)g Fb(c)g Fd(are)h(just)0 4798 y(lik)o(e)24 b Fb(:mo)o(v)o(e)h Fd(e)o(xcept)g(that)f(a)h(cop)o(y)g(of)g(the)f(selection)g(is)h(left)f (behind)h(at)f(the)h(original)f(position.)146 4918 y(There)32 b(is)e(also)h(a)g(longer)g(form)g(of)g(the)g Fb(:mo)o(v)o(e)g Fd(command)f(that)h(you)f(can)i(use)e(to)h(mo)o(v)o(e)f(the)g (selection)h(a)0 5039 y(precise)24 b(amount.)30 b(F)o(or)24 b(e)o(xample,)f Fb(:mo)o(v)o(e)h(up)h(10)f Fd(will)f(mo)o(v)o(e)g(the)h (selection)f(\(and)h(the)g(box\))g(up)g(10)g(units.)29 b(The)0 5159 y Fe(dir)l(ection)21 b Fd(ar)n(gument)g(can)h(be)f(an)o(y) g(direction)g(lik)o(e)g Fb(left)p Fd(,)i Fb(south)p Fd(,)g Fb(do)o(wn)p Fd(,)f(etc.)30 b(See)23 b(the)e(Magic)g(manual)g(page)h (for)0 5280 y(a)k(complete)e(list)h(of)g(the)g(le)o(gal)f(directions.) 32 b(The)25 b(macros)g Fb(q)p Fd(,)h Fb(w)p Fd(,)f Fb(e)p Fd(,)h(and)f Fb(r)h Fd(are)g(de\002ned)g(to)f(mo)o(v)o(e)f(the)h (selection)0 5400 y(left,)g(do)n(wn,)e(up,)i(and)g(right)f(\(respecti)n (v)o(ely\))f(by)i(one)g(unit.)1875 5649 y(\2264\226)p eop %%Page: 5 5 5 4 bop 0 -180 a Fd(Magic)24 b(T)l(utorial)g(#2:)30 b(Basic)25 b(P)o(ainting)f(and)h(Selection)1179 b(September)25 b(26,)g(2001)146 68 y(The)39 b Fb(:str)n(etch)i Fd(command)c(is)i(similar)e(to)i Fb(:mo)o(v)o(e)g Fd(e)o(xcept)f(that)g(it)g(stretches)h(and)g(erases)g (as)g(it)f(mo)o(v)o(es.)0 188 y Fb(:str)n(etch)25 b Fd(does)e(not)f (operate)h(diagonally)-6 b(,)22 b(so)h(if)g(you)f(use)h(the)g(cursor)g (to)g(indicate)g(where)g(to)g(stretch)g(to,)f(Magic)0 309 y(will)j(either)i(stretch)f(up,)g(do)n(wn,)f(left,)i(or)f(right,)g (whiche)n(v)o(er)f(is)h(closest.)34 b(The)27 b Fb(:str)n(etch)g Fd(command)f(mo)o(v)o(es)e(the)0 429 y(selection)30 b(and)h(also)g (does)g(tw)o(o)f(additional)g(things.)48 b(First,)32 b(for)g(each)f(piece)h(of)f(paint)f(that)h(mo)o(v)o(es,)f Fb(:str)n(etch)0 549 y Fd(will)j(erase)h(that)f(layer)h(from)g(the)f (re)o(gion)g(that)g(the)g(paint)g(passes)h(through)e(as)i(it)f(mo)o(v)o (es,)h(in)f(order)h(to)f(clear)0 670 y(material)26 b(out)g(of)g(its)g (w)o(ay)-6 b(.)35 b(Second,)27 b(if)g(the)f(back)g(edge)h(of)g(a)f (piece)h(of)f(selected)h(paint)f(touches)f(non-selected)0 790 y(material,)34 b(one)e(of)g(the)g(tw)o(o)g(pieces)g(of)g(paint)g (is)g(stretched)f(to)h(maintain)f(the)h(connection.)52 b(The)33 b(macros)f Fb(Q)p Fd(,)0 911 y Fb(W)p Fd(,)d Fb(E)p Fd(,)i(and)f Fb(R)f Fd(just)g(lik)o(e)h(the)f(macros)h Fb(q)p Fd(,)h(etc.)46 b(described)30 b(abo)o(v)o(e)f(for)h Fb(:mo)o(v)o(e)p Fd(.)46 b(The)30 b(macro)g Fb(T)g Fd(is)f (prede\002ned)0 1031 y(to)j Fb(:str)n(etch)p Fd(.)55 b(T)-8 b(o)32 b(see)h(ho)n(w)f(stretching)f(w)o(orks,)j(select)e(the)h (horizontal)e(piece)i(of)f(the)h(green)f(wire)h(in)f Fb(tut2b)0 1151 y Fd(and)26 b(type)f Fb(W)p Fd(,)g(then)g Fb(E)p Fd(.)h(Stretching)f(only)g(w)o(orries)h(about)f(material)g(in)g (front)g(of)h(and)f(behind)g(the)h(selection;)f(it)0 1272 y(ignores)j(material)g(to)f(the)i(sides)e(\(try)i(the)f Fb(Q)g Fd(and)g Fb(R)g Fd(macros)g(to)g(see\).)42 b(Y)-11 b(ou)28 b(can)g(use)h(plo)n(wing)d(\(described)i(in)0 1392 y(T)l(utorial)23 b(#3\))i(if)g(this)f(is)g(a)h(problem.)146 1513 y(The)g(command)e Fb(:upsidedo)o(wn)j Fd(will)d(\003ip)i(the)f (selection)f(upside)h(do)n(wn,)f(and)h Fb(:sideways)g Fd(\003ips)h(the)f(selec-)0 1633 y(tion)g(side)n(w)o(ays.)29 b(Both)c(commands)e(lea)n(v)o(e)h(the)h(selection)e(so)i(it)f(occupies) g(the)g(same)h(total)e(area)j(as)f(before,)g(b)n(ut)0 1753 y(with)c(the)g(contents)f(\003ipped.)30 b(The)21 b(command)g Fb(:clockwise)g Fd(will)g(rotate)g(the)g(selection)g (clockwise,)g(lea)n(ving)g(the)0 1874 y(lo)n(wer)n(-left)g(corner)h(of) g(the)f(ne)n(w)g(selection)g(at)g(the)h(same)f(place)h(as)g(the)f(lo)n (wer)n(-left)g(corner)h(of)g(the)f(old)g(selection.)0 1994 y Fe(De)l(gr)l(ees)k Fd(must)f(be)h(a)g(multiple)e(of)i(90,)f(and) h(def)o(aults)f(to)h(90.)146 2114 y(At)i(this)e(point)h(you)g(kno)n(w)f (enough)h(to)g(do)g(quite)g(a)h(bit)f(of)g(damage)h(to)f(the)g Fb(tut2b)i Fd(cell.)35 b(Experiment)26 b(with)0 2235 y(the)f(selection)f(commands.)29 b(Remember)c(that)g(you)f(can)h(use)g Fb(:undo)h Fd(to)e(back)h(out)g(of)f(trouble.)0 2573 y Ff(6)143 b(Labels)0 2797 y Fd(Labels)30 b(are)i(pieces)e(of)h(te)o (xt)f(attached)g(to)h(the)f(paint)g(of)h(a)g(cell.)48 b(The)o(y)30 b(are)h(used)g(to)f(pro)o(vide)f(information)g(to)0 2917 y(other)d(tools)g(that)g(will)g(process)g(the)g(circuit.)36 b(Most)25 b(labels)i(are)g(node)f(names:)34 b(the)o(y)25 b(pro)o(vide)h(an)h(easy)f(w)o(ay)h(of)0 3037 y(referring)j(to)g(nodes) f(in)g(tools)g(such)g(as)h(routers,)h(simulators,)e(and)h(timing)e (analyzers.)46 b(Labels)29 b(may)h(also)f(be)0 3158 y(used)i(for)h (other)f(purposes:)43 b(for)31 b(e)o(xample,)h(some)f(labels)g(are)h (treated)g(as)f Fe(attrib)n(utes)f Fd(that)g(gi)n(v)o(e)g(Crystal,)j (the)0 3278 y(timing)23 b(analyzer)l(,)i(information)f(about)g(the)h (direction)f(of)h(signal)f(\003o)n(w)g(through)g(transistors.)146 3398 y(Load)i(the)g(cell)f Fb(tut2c)i Fd(and)f(place)g(a)g(cross)g(in)f (the)h(middle)f(of)g(the)h(red)g(chunk)g(\(to)f(mak)o(e)h(a)g(cross,)g (position)0 3519 y(the)34 b(lo)n(wer)n(-left)g(corner)g(of)g(the)g(box) g(with)f(the)h(left)g(b)n(utton)f(and)h(then)g(click)g(the)g(right)f(b) n(utton)g(to)h(place)g(the)0 3639 y(upper)n(-right)d(corner)i(on)e(top) h(of)g(the)f(lo)n(wer)n(-left)h(corner\).)52 b(Then)32 b(type)g(type)f(the)h(command)f Fb(:label)h(test)p Fd(.)52 b(A)0 3760 y(ne)n(w)24 b(label)h(will)f(appear)h(at)g(the)g(position)e (of)i(the)f(box.)31 b(The)24 b(complete)h(syntax)f(of)g(the)h Fb(:label)g Fd(command)f(is)900 3978 y Fb(:label)h Fd([)p Fe(te)n(xt)g Fd([)p Fe(position)e Fd([)p Fe(layer)p Fd(]]])146 4196 y Fe(T)-9 b(e)n(xt)32 b Fd(must)e(be)h(supplied,)g(b)n(ut)g(the)g (other)g(ar)n(guments)f(can)h(be)h(def)o(aulted.)49 b(If)31 b Fe(te)n(xt)g Fd(has)g(an)o(y)g(spaces)g(in)g(it,)0 4317 y(then)20 b(it)g(must)f(be)i(enclosed)f(in)g(double)g(quotes.)28 b Fe(P)-8 b(osition)19 b Fd(tells)h(where)g(the)h(te)o(xt)e(should)g (be)i(displayed,)f(relati)n(v)o(e)0 4437 y(to)28 b(the)h(point)f(of)g (the)h(label.)42 b(It)29 b(may)f(be)h(an)o(y)g(of)f Fb(north)p Fd(,)j Fb(south)p Fd(,)f Fb(east)p Fd(,)g Fb(west)p Fd(,)g Fb(top)p Fd(,)g Fb(bottom)p Fd(,)g Fb(left)p Fd(,)g Fb(right)p Fd(,)g Fb(up)p Fd(,)0 4557 y Fb(do)o(wn)p Fd(,)c Fb(center)p Fd(,)g Fb(northeast)p Fd(,)g Fb(ne)p Fd(,)g Fb(southeast)p Fd(,)g Fb(se)p Fd(,)f Fb(southwest)p Fd(,)h Fb(sw)p Fd(,)e Fb(northwest)p Fd(,)j Fb(nw)p Fd(.)32 b(F)o(or)25 b(e)o(xample,)f(if)h Fb(ne)h Fd(is)0 4678 y(gi)n(v)o(en,)i(the)h(te)o(xt)f(will)g(be)h (displayed)f(abo)o(v)o(e)g(and)h(to)g(the)f(right)h(of)g(the)f(label)h (point.)42 b(If)29 b(no)g Fe(position)e Fd(is)i(gi)n(v)o(en,)0 4798 y(Magic)j(will)f(pick)g(a)i(position)d(for)i(you.)52 b Fe(Layer)32 b Fd(tells)g(which)f(paint)h(layer)g(to)f(attach)h(the)g (label)g(to.)52 b(If)32 b Fe(layer)0 4918 y Fd(co)o(v)o(ers)h(the)g (entire)g(area)h(of)g(the)f(label,)i(then)e(the)g(label)h(will)e(be)i (associated)e(with)h(the)g(particular)h(layer)-5 b(.)56 b(If)0 5039 y Fe(layer)26 b Fd(is)f(omitted,)f(or)i(if)g(it)f(doesn')n (t)h(co)o(v)o(er)f(the)h(label')-5 b(s)25 b(area,)h(Magic)g(initially)e (associates)h(the)h(label)f(with)g(the)0 5159 y(\223space\224)32 b(layer)l(,)g(then)f(checks)g(to)f(see)i(if)f(there')-5 b(s)30 b(a)h(layer)g(that)g(co)o(v)o(ers)f(the)h(whole)f(area.)50 b(If)31 b(there)h(is,)f(Magic)0 5280 y(mo)o(v)o(es)f(the)i(label)g(to)f (that)h(layer)-5 b(.)52 b(It)32 b(is)f(generally)h(a)h(bad)e(idea)i(to) e(place)h(labels)g(at)g(points)f(where)h(there)g(are)0 5400 y(se)n(v)o(eral)d(paint)f(layers,)j(since)e(it)g(will)f(be)i(hard) f(to)g(tell)g(which)g(layer)g(the)g(label)h(is)e(attached)i(to.)44 b(As)29 b(you)g(edit,)1875 5649 y(\2265\226)p eop %%Page: 6 6 6 5 bop 0 -180 a Fd(September)25 b(26,)f(2001)1180 b(Magic)24 b(T)l(utorial)f(#2:)31 b(Basic)25 b(P)o(ainting)e(and)i(Selection)0 68 y(Magic)h(will)g(ensure)h(that)f(labels)g(are)h(only)f(attached)g (to)g(layers)h(that)f(e)o(xist)f(e)n(v)o(erywhere)i(under)f(the)h (label.)35 b(T)-8 b(o)0 188 y(see)34 b(ho)n(w)f(this)g(w)o(orks,)j (paint)d(the)g(layer)i(pdif)n(f)e(\(bro)n(wn\))g(o)o(v)o(er)g(the)h (label)f(you)h(just)e(created:)50 b(the)33 b(label)h(will)0 309 y(switch)24 b(layers.)31 b(Finally)-6 b(,)23 b(erase)j(poly)e(o)o (v)o(er)g(the)h(area,)g(and)g(the)g(label)f(will)g(mo)o(v)o(e)f(again.) 146 429 y(Although)f(man)o(y)h(labels)g(are)i(point)d(labels,)h(this)g (need)h(not)f(be)h(the)f(case.)31 b(Y)-11 b(ou)23 b(can)h(label)g(an)o (y)f(rectangular)0 549 y(area)32 b(by)f(setting)f(the)h(box)g(to)f (that)h(area)h(before)g(in)l(v)n(oking)d(the)i(label)g(command.)49 b(This)30 b(feature)i(is)f(used)g(for)0 670 y(labelling)19 b(terminals)g(for)h(the)f(router)h(\(see)h(belo)n(w\),)f(and)g(for)g (labelling)f(tiles)g(used)g(by)h(Mpack,)g(the)g(tile)g(packing)0 790 y(program.)30 b Fb(T)-9 b(ut2c)26 b Fd(has)f(e)o(xamples)f(of)g (point,)g(line,)g(and)h(rectangular)g(labels.)146 911 y(All)g(of)h(the)f(selection)g(commands)f(apply)h(to)g(labels)f(as)i (well)f(as)h(paint.)31 b(Whene)n(v)o(er)25 b(you)g(select)g(paint,)g (the)0 1031 y(labels)i(attached)h(to)f(that)h(paint)f(will)g(also)g(be) h(selected.)39 b(Selected)29 b(labels)e(are)h(highlighted)e(in)i (white.)39 b(Select)0 1151 y(some)31 b(of)g(the)h(chunks)e(of)i(paint)f (in)g Fb(tut2c)h Fd(to)f(see)h(ho)n(w)f(the)g(labels)g(are)h(selected)f (too.)50 b(When)32 b(you)f(use)g(area)0 1272 y(selection,)d(labels)g (will)f(only)h(be)g(selected)h(if)f(the)o(y)f(are)i(completely)e (contained)h(in)g(the)g(area)h(being)f(selected.)0 1392 y(If)d(you')-5 b(d)24 b(lik)o(e)g(to)g(select)g Fe(just)f Fd(a)i(label)f(without)f(an)o(y)h(paint,)f(mak)o(e)i(the)f(box)g(into)f (a)i(cross)f(and)g(put)g(the)g(cross)g(on)0 1513 y(the)h(label:)30 b Fb(s)25 b Fd(and)f Fb(S)i Fd(will)e(select)g(just)g(the)h(label.)146 1633 y(There)k(are)h(se)n(v)o(eral)e(w)o(ays)g(to)h(erase)g(a)g(label.) 42 b(One)29 b(w)o(ay)g(is)f(to)g(select)h(and)g(then)f(delete)h(it.)42 b(Another)28 b(w)o(ay)0 1753 y(is)k(to)g(erase)g(the)g(paint)g(that)g (the)g(label)g(is)f(attached)i(to.)52 b(If)33 b(the)f(paint)f(is)h (erased)h(all)f(around)g(the)g(label,)h(then)0 1874 y(Magic)26 b(will)f(delete)i(the)f(label)g(too.)34 b(T)m(ry)26 b(attaching)f(a)i (label)f(to)g(a)g(red)h(area,)g(then)f(paint)g(blue)g(o)o(v)o(er)f(the) h(red.)36 b(If)0 1994 y(you)28 b(erase)g(blue)g(the)g(label)f(stays)h (\(since)g(it')-5 b(s)27 b(attached)h(to)f(red\),)j(b)n(ut)d(if)h(you)f (erase)i(the)f(red)g(then)g(the)g(label)g(is)0 2114 y(deleted.)146 2235 y(Y)-11 b(ou)19 b(can)g(also)g(erase)g(labels)g(using)f(the)g Fb(:erase)i Fd(command)e(and)g(the)h(pseudo-layer)g Fb(labels)p Fd(.)28 b(The)19 b(command)900 2453 y Fb(:erase)25 b(labels)146 2671 y Fd(will)d(erase)i(all)e(labels)g(that)g(lie)h(completely)e (within)h(the)g(area)i(of)f(the)f(box.)30 b(Finally)-6 b(,)22 b(you)g(can)h(erase)g(a)g(label)0 2792 y(by)i(making)f(the)i (box)f(into)f(a)i(cross)f(on)g(top)g(of)h(the)f(label,)g(then)g (clicking)g(the)g(middle)f(b)n(utton)g(with)h(the)g(cursor)0 2912 y(o)o(v)o(er)j(empty)h(space.)45 b(T)-7 b(echnically)h(,)29 b(this)f(will)h(erase)h(all)f(paint)g(layers)g(and)g(labels)g(too.)44 b(Ho)n(we)n(v)o(er)l(,)29 b(since)g(the)0 3033 y(box)24 b(has)h(zero)g(area,)h(erasing)f(paint)f(has)h(no)f(ef)n(fect:)31 b(only)24 b(the)h(labels)f(are)i(erased.)0 3371 y Ff(7)143 b(Labelling)34 b(Con)-6 b(v)o(entions)0 3594 y Fd(When)20 b(creating)f(labels,)h(Magic)f(will)g(permit)f(you)h(to)h(use)f (absolutely)f(an)o(y)h(te)o(xt)g(whatsoe)n(v)o(er)-5 b(.)27 b(Ho)n(we)n(v)o(er)l(,)19 b(man)o(y)0 3715 y(other)i(tools,)g (and)h(e)n(v)o(en)f(parts)g(of)h(Magic,)g(e)o(xpect)f(label)g(names)h (to)f(observ)o(e)g(certain)h(con)l(v)o(entions.)27 b(Except)22 b(for)0 3835 y(the)k(special)g(cases)g(described)g(belo)n(w)-6 b(,)25 b(labels)g(shouldn')n(t)g(contain)g(an)o(y)h(of)g(the)g (characters)h(\223/$@!\210\224.)34 b(Spaces,)0 3955 y(control)23 b(characters,)h(or)g(parentheses)f(within)f(labels)h(are)h(probably)f (a)h(bad)f(idea)h(too.)29 b(Man)o(y)23 b(of)g(the)h(programs)0 4076 y(that)f(process)h(Magic)g(output)e(ha)n(v)o(e)i(their)f(o)n(wn)g (restrictions)g(on)h(label)f(names,)h(so)f(you)h(should)e(\002nd)i(out) g(about)0 4196 y(the)38 b(restrictions)f(that)h(apply)f(at)h(your)g (site.)71 b(Most)37 b(labels)g(are)i(node)f(names:)57 b(each)39 b(one)f(gi)n(v)o(es)e(a)j(unique)0 4317 y(identi\002cation)23 b(to)h(a)h(set)f(of)h(things)e(that)h(are)h(electrically)f(connected.) 31 b(There)24 b(are)i(tw)o(o)d(kinds)h(of)g(node)h(names,)0 4437 y(local)k(and)h(global.)44 b(An)o(y)28 b(label)h(that)g(ends)h(in) f(\223!\224)45 b(is)29 b(treated)h(as)g(a)f(global)g(node)g(name;)j(it) d(will)f(be)i(assumed)0 4557 y(that)e(all)g(nodes)g(by)g(this)f(name,)i (an)o(ywere)f(in)g(an)o(y)g(cell)g(in)g(a)h(layout,)f(are)h (electrically)f(connected.)41 b(The)28 b(most)0 4678 y(common)e(global)g(names)h(are)h Fb(Vdd!)38 b Fd(and)27 b Fb(GND!)p Fd(,)g(the)g(po)n(wer)g(rails.)37 b(Y)-11 b(ou)27 b(should)f(al)o(w)o(ays)h(use)g(these)f(names)0 4798 y(e)o(xactly)-6 b(,)27 b(since)g(man)o(y)g(other)g(tools)f (require)i(them.)38 b(Nobody)27 b(kno)n(ws)f(why)h(\223GND!\224)h(is)f (all)g(in)g(capital)h(letters)0 4918 y(and)d(\223Vdd!\224)31 b(isn')n(t.)146 5039 y(An)o(y)e(label)f(that)h(does)g(not)f(end)h(in)g (\223!\224)44 b(or)29 b(an)o(y)g(of)g(the)g(other)f(special)h (characters)h(discussed)e(belo)n(w)g(is)h(a)0 5159 y(local)23 b(node)g(name.)30 b(It)23 b(refers)h(to)e(a)i(node)f(within)e(that)i (particular)g(cell.)30 b(Local)23 b(node)g(names)g(should)f(be)h (unique)0 5280 y(within)e(the)h(cell:)30 b(there)22 b(shouldn')n(t)f (be)i(tw)o(o)f(electrically)g(distinct)f(nodes)h(with)g(the)g(same)g (name.)30 b(On)22 b(the)g(other)0 5400 y(hand,)30 b(it)e(is)h (perfectly)g(le)o(gal,)g(and)g(sometimes)e(adv)n(antageous,)i(to)g(gi)n (v)o(e)e(more)i(than)g(one)g(name)g(to)f(the)h(same)1875 5649 y(\2266\226)p eop %%Page: 7 7 7 6 bop 0 -180 a Fd(Magic)24 b(T)l(utorial)g(#2:)30 b(Basic)25 b(P)o(ainting)f(and)h(Selection)1179 b(September)25 b(26,)g(2001)0 68 y(node.)46 b(It)29 b(is)h(also)f(le)o(gal)g(to)g(use)h(the)g(same)f (local)h(node)f(name)h(in)g(dif)n(ferent)f(cells:)40 b(the)30 b(tools)f(will)g(be)h(able)f(to)0 188 y(distinguish)22 b(between)j(them)f(and)h(will)f(not)g(assume)g(that)h(the)o(y)f(are)h (electrically)g(connected.)146 309 y(The)35 b(only)e(other)i(labels)e (currently)i(understood)e(by)h(the)g(tools)f(are)i Fe(attrib)n(utes)p Fd(.)58 b(Attrib)n(utes)33 b(are)i(pieces)0 429 y(of)g(te)o(xt)e (associated)h(with)g(a)h(particular)g(piece)g(of)f(the)h(circuit:)49 b(the)o(y)34 b(are)h(not)f(node)h(names,)h(and)f(need)g(not)0 549 y(be)30 b(unique.)44 b(F)o(or)30 b(e)o(xample,)g(an)g(attrib)n(ute) f(might)f(identify)h(a)h(node)f(as)h(a)g(chip)f(input,)h(or)g(it)f (might)f(identify)h(a)0 670 y(transistor)e(terminal)g(as)g(the)h (source)g(of)g(information)e(for)i(that)f(transistor)-5 b(.)38 b(An)o(y)27 b(label)g(whose)h(last)f(character)0 790 y(is)e(\223@\224,)h(\223$\224,)g(or)g(\223\210\224)g(is)g(an)f (attrib)n(ute.)33 b(There)26 b(are)g(three)g(dif)n(ferent)f(kinds)g(of) g(attrib)n(utes.)32 b(Node)26 b(attrib)n(utes)e(are)0 911 y(those)c(ending)f(with)h(\223@\224;)h(the)o(y)f(are)h(associated)e (with)h(particular)g(nodes.)29 b(T)m(ransistor)18 b(source/drain)i (attrib)n(utes)0 1031 y(are)30 b(those)f(ending)g(in)g(\223$\224;)j (the)o(y)c(are)i(associated)f(with)g(particular)g(terminals)g(of)g(a)h (transistor)-5 b(.)43 b(A)29 b(source)h(or)0 1151 y(drain)25 b(attrib)n(ute)f(must)h(be)g(attached)g(to)g(the)g(channel)g(re)o(gion) g(of)g(the)g(transistor)f(and)h(must)g(f)o(all)g(e)o(xactly)f(on)h(the) 0 1272 y(source)31 b(or)h(drain)f(edge)h(of)f(the)g(transistor)-5 b(.)49 b(The)32 b(third)e(kind)h(of)g(attrib)n(ute)g(is)g(a)g (transistor)g(gate)g(attrib)n(ute.)49 b(It)0 1392 y(ends)22 b(in)h(\223\210\224)g(and)g(is)f(attached)h(to)f(the)h(channel)g(re)o (gion)f(of)g(the)h(transistor)-5 b(.)28 b(T)-8 b(o)23 b(see)g(e)o(xamples)f(of)g(attrib)n(utes)g(and)0 1513 y(node)j(names,)f(edit)g(the)h(cell)g Fb(tut2d)h Fd(in)e(Magic.)146 1633 y(Special)j(con)l(v)o(entions)d(apply)h(to)h(labels)f(for)i (routing)d(terminals.)34 b(The)26 b(standard)f(Magic)h(router)g(\(in)l (v)n(ok)o(ed)0 1753 y(by)37 b Fb(:r)n(oute)p Fd(\))j(ignores)d(all)g (labels)g(e)o(xcept)g(for)h(those)f(on)h(the)f(edges)h(of)g(cells.)69 b(\(This)37 b(restriction)f(does)i(not)0 1874 y(apply)31 b(to)g(the)h(gate-array)g(router)l(,)h(Garoute,)h(or)d(to)h(the)f (interacti)n(v)o(e)f(router)l(,)k(Iroute\).)51 b(If)32 b(you)g(e)o(xpect)f(to)g(use)0 1994 y(the)c(standard)h(router)f(to)h (connect)f(to)g(a)h(particular)g(node,)g(you)f(should)f(place)i(the)g (label)f(for)h(that)f(node)h(on)f(its)0 2114 y(outermost)21 b(edge.)30 b(The)22 b(label)g(should)g(not)f(be)i(a)f(point)g(label,)g (b)n(ut)g(should)f(instead)h(be)g(a)h(horizontal)e(or)i(v)o(ertical)0 2235 y(line)31 b(co)o(v)o(ering)g(the)h(entire)g(edge)g(of)g(the)f (wire.)52 b(The)32 b(router)g(will)f(choose)h(a)g(connection)f(point)g (some)n(where)0 2355 y(along)c(the)h(label.)39 b(A)28 b(good)f(rule)h(of)f(thumb)g(is)g(to)g(label)h(all)f(nodes)h(that)f (enter)h(or)g(lea)n(v)o(e)f(the)h(cell)f(in)h(this)f(w)o(ay)-6 b(.)0 2476 y(F)o(or)20 b(more)h(details)e(on)h(ho)n(w)g(labels)g(are)h (used)f(by)g(the)g(standard)g(router)l(,)h(see)g(\223Magic)f(T)l (utorial)f(#7:)28 b(Netlists)19 b(and)0 2596 y(Routing\224.)29 b(Other)23 b(labeling)e(con)l(v)o(entions)g(are)i(used)f(by)g(the)g (Garouter)g(and)h(Irouter)l(,)g(consult)e(their)h(respecti)n(v)o(e)0 2716 y(tutorials)h(for)j(details.)0 3055 y Ff(8)143 b(Files)35 b(and)g(F)l(ormats)0 3278 y Fd(Magic)22 b(pro)o(vides)e(a)i(v)n(ariety) g(of)g(w)o(ays)f(to)h(sa)n(v)o(e)f(your)h(cells)g(on)f(disk.)29 b(Normally)-6 b(,)21 b(things)g(are)h(sa)n(v)o(ed)g(in)f(a)h(special)0 3398 y(Magic)34 b(format.)58 b(Each)35 b(cell)f(is)g(a)g(separate)h (\002le,)i(and)d(the)g(name)g(of)g(the)g(\002le)h(is)f(just)f(the)h (name)g(of)g(the)g(cell)0 3519 y(with)23 b Fb(.mag)h Fd(appended.)31 b(F)o(or)24 b(e)o(xample,)f(the)h(cell)g Fb(tut2a)h Fd(is)f(sa)n(v)o(ed)f(in)h(\002le)h Fb(tut2a.mag)p Fd(.)30 b(T)-8 b(o)24 b(sa)n(v)o(e)g(cells)g(on)g(disk,)0 3639 y(in)l(v)n(ok)o(e)g(the)h(command)900 3857 y Fb(:writeall)146 4076 y Fd(This)d(command)g(will)g(run)h(through)f(each)h(of)g(the)g (cells)g(that)f(you)g(ha)n(v)o(e)h(modi\002ed)f(in)h(this)f(editing)f (session,)0 4196 y(and)33 b(ask)f(you)h(what)f(to)g(do)h(with)f(the)g (cell.)55 b(Normally)-6 b(,)33 b(you')o(ll)f(type)g Fb(write)p Fd(,)j(or)e(just)f(hit)g(the)g(return)h(k)o(e)o(y)-6 b(,)33 b(in)0 4317 y(which)f(case)g(the)g(cell)h(will)e(be)h(written)g (back)g(to)g(the)g(disk)f(\002le)i(from)f(which)f(it)h(w)o(as)g(read)h (\(if)f(this)f(is)h(a)h(ne)n(w)0 4437 y(cell,)23 b(then)g(you')o(ll)g (be)g(ask)o(ed)h(for)f(a)h(name)f(for)h(the)f(cell\).)30 b(If)24 b(you)f(type)g Fb(auto)o(write)p Fd(,)h(then)f(Magic)g(will)g (write)g(out)0 4557 y(all)30 b(the)g(cells)g(that)f(ha)n(v)o(e)h (changed)g(without)f(asking)g(you)h(what)g(to)g(do)f(on)h(a)h (cell-by-cell)f(basis.)46 b Fb(Flush)30 b Fd(will)0 4678 y(cause)f(Magic)f(to)h(delete)f(its)g(internal)g(cop)o(y)h(of)g(the)f (cell)h(and)g(reload)f(the)h(cell)f(from)h(the)f(disk)g(cop)o(y)-6 b(,)29 b(thereby)0 4798 y(e)o(xpunging)f(all)h(edits)g(that)g(you')-5 b(v)o(e)29 b(made.)45 b Fb(Skip)30 b Fd(will)f(pass)g(on)g(to)g(the)h (ne)o(xt)e(cell)i(without)e(writing)h(this)f(cell)0 4918 y(\(b)n(ut)g(Magic)g(still)g(remembers)g(that)g(it)g(has)h(changed,)g (so)f(the)h(ne)o(xt)f(time)f(you)i(in)l(v)n(ok)o(e)e Fb(:writeall)i Fd(Magic)f(will)0 5039 y(ask)d(about)g(this)f(cell)h (again\).)32 b Fb(Abort)26 b Fd(will)e(stop)g(the)h(command)g (immediately)e(without)h(writing)g(or)h(checking)0 5159 y(an)o(y)f(more)h(cells.)146 5280 y Fb(IMPOR)l(T)-9 b(ANT)28 b(NO)l(TE:)g Fd(Unlik)o(e)f(vi)g(and)h(other)g(te)o(xt)e(editors,)i (Magic)f(doesn')n(t)g(k)o(eep)h(checkpoint)f(\002les.)0 5400 y(This)d(means)g(that)g(if)h(the)f(system)g(should)f(crash)i(in)f (the)h(middle)e(of)i(a)g(session,)e(you')o(ll)h(lose)g(all)h(changes)f (since)1875 5649 y(\2267\226)p eop %%Page: 8 8 8 7 bop 0 -180 a Fd(September)25 b(26,)f(2001)1180 b(Magic)24 b(T)l(utorial)f(#2:)31 b(Basic)25 b(P)o(ainting)e(and)i(Selection)0 68 y(the)h(last)f(time)g(you)g(wrote)h(out)g(cells.)33 b(It')-5 b(s)25 b(a)h(good)g(idea)g(to)f(sa)n(v)o(e)h(your)f(cells)h (frequently)f(during)g(long)g(editing)0 188 y(sessions.)146 309 y(Y)-11 b(ou)25 b(can)g(also)f(sa)n(v)o(e)h(the)g(cell)f(you')-5 b(re)25 b(currently)g(editing)e(with)h(the)h(command)900 544 y Fb(:sa)n(v)o(e)f Fe(name)146 777 y Fd(This)k(command)g(will)f (append)i(\223.mag\224)f(to)h Fe(name)f Fd(and)h(sa)n(v)o(e)f(the)g (cell)h(you)f(are)h(editing)f(in)g(that)g(location.)0 897 y(If)d(you)f(don')n(t)h(pro)o(vide)e(a)i(name,)g(Magic)f(will)g (use)h(the)f(cell')-5 b(s)24 b(name)h(\(plus)f(the)g(\223.mag\224)h(e)o (xtension\))e(as)i(the)g(\002le)0 1018 y(name,)g(and)f(it)h(will)f (prompt)f(you)i(for)g(a)g(name)g(if)f(the)h(cell)g(hasn')n(t)f(yet)h (been)g(named.)146 1139 y(Once)g(a)h(cell)e(has)h(been)g(sa)n(v)o(ed)f (on)h(disk)f(you)g(can)h(edit)g(it)f(by)h(in)l(v)n(oking)e(Magic)h (with)g(the)h(command)900 1373 y Fb(magic)f Fe(name)146 1606 y Fd(where)i Fe(name)e Fd(is)h(the)f(same)h(name)g(you)f(used)h (to)f(sa)n(v)o(e)g(the)h(cell)g(\(no)g(\223.mag\224)f(e)o(xtension\).) 146 1727 y(Magic)f(can)h(also)f(read)g(and)g(write)g(\002les)h(in)f (CIF)h(and)f(Calma)h(Stream)f(formats.)30 b(See)24 b(\223Magic)f(T)l (utorial)f(#9:)0 1848 y(F)o(ormat)i(Con)l(v)o(ersion)g(for)h(CIF)h(and) f(Calma\224)g(for)g(details.)0 2192 y Ff(9)143 b(Plotting)0 2417 y Fd(Magic)21 b(can)i(generate)f(hardcop)o(y)g(plots)e(of)i (layouts)f(in)g(four)h(w)o(ays:)29 b(postscript)21 b(\(color\),)h(v)o (ersatec)g(\(black-and-)0 2537 y(white)k(or)g(color\),)g(gremlin,)g (and)g(pix)o(els)f(\(a)h(generalized)h(pix)o(el-\002le)e(that)h(can)g (be)h(massaged)e(in)h(man)o(y)f(w)o(ays\).)0 2658 y(T)-8 b(o)25 b(plot)f(part)g(of)h(your)g(design)f(in)g(PostScript,)h(place)g (the)f(box)h(around)f(the)h(part)g(you')-5 b(d)24 b(lik)o(e)h(to)f (plot)g(and)h(type)900 2892 y Fb(:plot)g(postscript)146 3125 y Fd(This)33 b(will)f(generate)i(a)g(plot)f(of)g(the)g(area)i(of)e (the)h(box.)56 b(Ev)o(erything)31 b(visible)i(underneath)g(the)g(box)g (will)0 3246 y(appear)i(in)f(more-or)n(-less)h(the)f(same)h(w)o(ay)f (in)h(the)f(plot.)59 b Fe(W)-5 b(idth)33 b Fd(speci\002es)i(ho)n(w)f (wide)g(the)h(plot)f(will)f(be,)k(in)0 3366 y(inches.)k(Magic)28 b(will)f(scale)h(the)g(plot)g(so)g(that)f(the)i(area)g(of)f(the)g(box)g (comes)g(out)g(this)f(wide.)41 b(The)28 b(def)o(ault)g(for)0 3486 y Fe(width)d Fd(is)g(the)g(width)g(of)g(the)g(plotter)g(\(if)g Fe(width)g Fd(is)g(lar)n(ger)h(than)f(the)g(plotter)g(width,)g(it')-5 b(s)24 b(reduced)i(to)f(the)g(plotter)0 3607 y(width\).)37 b(If)28 b Fe(layer)o(s)f Fd(is)g(gi)n(v)o(en,)f(it)h(speci\002es)h(e)o (xactly)e(what)h(information)f(is)h(to)g(be)h(plotted.)37 b(Only)26 b(those)h(layers)0 3727 y(will)d(appear)h(in)g(the)f(plot.)30 b(The)25 b(special)g(\223layer\224)g Fb(labels)g Fd(will)f(enable)g (label)h(plotting.)146 3848 y(The)k(second)f(form)g(is)g(for)g(dri)n (ving)f(printers)h(lik)o(e)f(color)i(V)-11 b(ersatecs.)41 b(It)28 b(is)g(enabled)g(by)g(setting)g(the)g Fe(color)0 3969 y Fd(plot)21 b(parameter)i(to)f Fe(true)p Fd(.)29 b(A)22 b(table)g(of)h(stipples)d(for)j(the)f(primary)f(colors)h (\(black,)h(c)o(yan,)f(magenta)g(abd)g(yello)n(w\))0 4089 y(is)34 b(gi)n(v)o(en)g(in)g(the)h(technology)e(\002le.)61 b(When)35 b(the)f Fe(plot)g Fd(command)g(is)g(gi)n(v)o(en,)i(four)f (rasters)g(\(one)g(for)g(each)g(of)0 4209 y(the)29 b(colors\))f(are)h (generated,)h(separated)f(with)f(the)h(proper)g(control)f(sequences)g (for)h(the)g(printer)-5 b(.)42 b(Otherwise,)0 4330 y(operation)24 b(is)h(e)o(xactly)f(as)h(for)g(the)f(black-and-white)h(case.)146 4451 y(The)36 b(third)g(form)f(of)h(plotting)f(is)g(for)h(generating)g (Gremlin-format)f(\002les,)k(which)c(can)i(then)e(be)i(edited)0 4571 y(with)32 b(the)h(Gremlin)f(dra)o(wing)h(system)e(or)j(included)e (in)h(documents)e(processed)i(by)g(Grn)g(and)g(Ditrof)n(f.)55 b(The)0 4692 y(command)24 b(to)g(get)h(Gremlin)f(\002les)h(is)900 4926 y Fb(:plot)g(gr)n(emlin)g Fe(\002le)g Fd([)p Fe(layer)o(s)p Fd(])146 5159 y(It)31 b(will)f(generate)h(a)h(Gremlin-format)d(\002le)j (in)e Fe(\002le)h Fd(that)f(describes)h(e)n(v)o(erything)e(underneath)i (the)f(box.)49 b(If)0 5280 y Fe(layer)o(s)28 b Fd(is)g(speci\002ed,)h (it)e(indicates)h(which)g(layers)g(are)h(to)f(appear)g(in)g(the)g (\002le;)i(otherwise)e(e)n(v)o(erything)e(visible)0 5400 y(on)i(the)h(screen)g(is)g(output.)41 b(The)29 b(Gremlin)f(\002le)h(is) f(output)g(without)f(an)o(y)h(particular)h(scale;)h(use)f(the)g Fb(width)g Fd(or)1875 5649 y(\2268\226)p eop %%Page: 9 9 9 8 bop 0 -180 a Fd(Magic)24 b(T)l(utorial)g(#2:)30 b(Basic)25 b(P)o(ainting)f(and)h(Selection)1179 b(September)25 b(26,)g(2001)0 69 y Fb(height)h Fd(commands)e(in)h(Grn)g(to)g(scale)h(the)f(plot)f (when)h(it')-5 b(s)25 b(printed.)31 b(Y)-11 b(ou)25 b(should)f(use)h (the)g Fb(mg)g Fd(stipples)f(when)0 189 y(printing)f(Magic)i(Gremlin)f (plots;)f(these)i(will)f(produce)h(the)f(same)h(stipple)e(patterns)i (as)g Fb(:plot)g(v)o(ersatec)p Fd(.)146 316 y(Finally)-6 b(,)22 b(the)g(\223pix)o(els\224)f(style)h(of)g(plotting)f(generates)h (a)h(\002le)f(of)h(pix)o(el)e(v)n(alues)g(for)i(the)f(re)o(gion)f(to)h (be)g(plotted.)0 436 y(This)31 b(can)g(be)h(useful)f(for)g(input)f(to)h (other)g(image)g(tools,)h(or)f(for)h(generation)f(of)g(slides)f(and)i (vie)n(wgraphs)e(for)0 557 y(presentations.)51 b(The)31 b(\002le)i(consists)d(of)i(a)g(sequence)g(of)g(bytes,)h(three)f(for)g (each)h(pix)o(el,)f(written)f(from)h(left)f(to)0 677 y(right)26 b(and)h(top)g(to)f(bottom.)36 b(Each)27 b(three)g(bytes)g (represent)g(the)g(red,)h(green)f(and)g(blue)g(v)n(alues)f(used)h(to)f (display)0 797 y(the)j(pix)o(el.)44 b(Thus,)30 b(if)f(the)g(upper)n (-left-most)g(pix)o(el)f(were)i(to)f(be)h(red,)h(the)e(\002rst)h(three) f(bytes)g(of)h(the)f(\002le)h(w)o(ould)0 918 y(ha)n(v)o(e)25 b(v)n(alues)e(of)i(255,)g(0)f(and)h(0.)146 1045 y(The)30 b(resolution)e(of)i(the)f(generated)h(\002le)g(is)g(normally)e(512,)i (b)n(ut)f(can)h(be)g(controlled)f(by)g(setting)g(the)g(plot)0 1165 y(parameter)36 b Fe(pixW)-5 b(idth)p Fd(.)60 b(It)35 b(must)f(be)h(a)h(multiple)d(of)i(8;)40 b(Magic)35 b(will)f(round)h(up) g(if)g(an)g(inappropriate)g(v)n(alue)0 1285 y(is)d(entered.)53 b(The)32 b(height)f(of)h(the)g(\002le)h(is)f(determined)f(by)h(the)g (shape)g(of)g(the)g(box.)53 b(In)32 b(an)o(y)g(case,)i(the)e(actual)0 1406 y(resolution)g(of)i(the)f(\002le)h(is)f(appended)g(to)g(the)h (\002le)f(name.)57 b(F)o(or)33 b(e)o(xample,)i(plotting)d(a)h(square)h (re)o(gion,)h(2048)0 1526 y(pix)o(els)23 b(across,)i(will)f(result)g (in)h(a)g(\002le)g(named)g(something)e(lik)o(e)h (\223magicPlot1234a-2048-2048\224.)146 1653 y(There)c(are)h(se)n(v)o (eral)e(plotting)e(parameters)j(used)f(internally)g(to)g(Magic,)h(such) g(as)f(the)h(width)e(of)i(the)g(V)-11 b(ersatec)0 1774 y(printer)28 b(and)h(the)f(number)g(of)g(dots)g(per)h(inch)f(on)g(the)g (V)-11 b(ersatec)29 b(printer)-5 b(.)41 b(Y)-11 b(ou)28 b(can)h(modify)e(most)h(of)g(these)g(to)0 1894 y(w)o(ork)c(with)f(dif)n (ferent)g(printers.)30 b(F)o(or)24 b(details,)f(read)h(about)g(the)f(v) n(arious)g Fb(:plot)h Fd(command)f(options)f(in)i(the)f Fe(man)0 2014 y Fd(page.)0 2396 y Ff(10)143 b(Utility)34 b(Commands)0 2633 y Fd(There)28 b(are)h(se)n(v)o(eral)e(additional)f (commands)h(that)g(you)h(will)f(probably)g(\002nd)h(useful)f(once)h (you)f(start)h(w)o(orking)0 2753 y(on)d(real)g(cells.)30 b(The)25 b(command)900 3033 y Fb(:grid)g Fd([)p Fe(spacing)p Fd(])900 3154 y Fb(:grid)g Fe(xSpacing)f(ySpacing)900 3274 y Fb(:grid)h Fe(xSpacing)f(ySpacing)g(xOrigin)g(yOrigin)900 3395 y Fb(:grid)h(off)146 3668 y Fd(will)32 b(display)f(a)i(grid)f(o)o (v)o(er)f(your)h(layout.)53 b(Initially)-6 b(,)32 b(the)g(grid)g(has)g (a)h(one-unit)f(spacing.)52 b(T)-8 b(yping)32 b Fb(:grid)0 3789 y Fd(with)g(no)h(ar)n(guments)g(will)f(toggle)g(the)h(grid)g(on)g (and)g(of)n(f.)55 b(If)34 b(a)f(single)g(numerical)f(ar)n(gument)h(is)g (gi)n(v)o(en,)g(the)0 3909 y(grid)25 b(will)f(be)h(turned)f(on,)h(and)g (the)f(grid)h(lines)f(will)g(be)h Fe(spacing)f Fd(units)g(apart.)31 b(The)25 b(macro)g Fb(g)g Fd(pro)o(vides)f(a)h(short)0 4030 y(form)34 b(for)h Fb(:grid)g Fd(and)f Fb(G)g Fd(is)h(short)e(for)i Fb(:grid)g(2)p Fd(.)60 b(If)35 b(you)f(pro)o(vide)f(tw)o(o)h(ar)n (guments)g(to)g Fb(:grid)p Fd(,)j(the)o(y)d(are)h(the)0 4150 y(x-)29 b(and)g(y-spacings,)h(which)e(may)h(be)g(dif)n(ferent.)44 b(If)29 b(you)g(pro)o(vide)f(four)h(ar)n(guments,)h(the)f(last)f(tw)o (o)h(specify)g(a)0 4270 y(reference)f(point)e(through)g(which)g (horizontal)g(and)h(v)o(ertical)f(grid)g(lines)g(pass;)h(the)g(def)o (ault)f(is)g(to)h(use)f(\(0,0\))h(as)0 4391 y(the)h(grid)h(origin.)41 b(The)29 b(command)e Fb(:grid)i(off)g Fd(al)o(w)o(ays)g(turns)f(the)g (grid)g(of)n(f,)i(re)o(gardless)d(of)i(whether)g(or)f(not)h(is)0 4511 y(w)o(as)22 b(pre)n(viously)e(on.)29 b(When)22 b(the)g(grid)f(is)h (on,)g(a)g(small)f(black)g(box)h(is)f(displayed)g(to)g(mark)h(the)g (\(0,0\))f(coordinate)0 4632 y(of)k(the)g(cell)f(you')-5 b(re)25 b(editing.)146 4758 y(If)30 b(you)g(w)o(ant)f(to)g(create)i(a)f (cell)g(that)f(doesn')n(t)g(\002t)h(on)f(the)h(screen,)h(you')o(ll)e (need)h(to)f(kno)n(w)g(ho)n(w)g(to)g(change)0 4879 y(the)c(screen)g (vie)n(w)-6 b(.)29 b(This)c(can)g(be)g(done)f(with)g(three)h(commands:) 900 5159 y Fb(:zoom)g Fe(factor)900 5280 y Fb(:\002ndbox)h Fd([)p Fb(zoom)p Fd(])900 5400 y Fb(:view)1875 5649 y Fd(\2269\226)p eop %%Page: 10 10 10 9 bop 0 -180 a Fd(September)25 b(26,)f(2001)1180 b(Magic)24 b(T)l(utorial)f(#2:)31 b(Basic)25 b(P)o(ainting)e(and)i(Selection)146 68 y(If)32 b Fe(factor)e Fd(is)g(gi)n(v)o(en)f(to)i(the)f(zoom)h (command,)g(it)f(is)h(a)g(zoom-out)f(f)o(actor)-5 b(.)48 b(F)o(or)31 b(e)o(xample,)g(the)g(command)0 189 y Fb(:zoom)25 b(2)g Fd(will)f(change)i(the)f(vie)n(w)f(so)h(that)g(there)g(are)h (twice)f(as)g(man)o(y)f(units)g(across)h(the)g(screen)h(as)f(there)g (used)0 309 y(to)d(be)g(\()p Fb(Z)h Fd(is)f(a)g(macro)g(for)h(this\).) 29 b(The)22 b(ne)n(w)g(vie)n(w)f(will)h(ha)n(v)o(e)g(the)g(same)g (center)g(as)g(the)h(old)e(one.)30 b(The)22 b(command)0 429 y Fb(:zoom)j(.5)g Fd(will)e(increase)j(the)e(magni\002cation)g(so)h (that)f(only)g(half)h(as)g(much)f(of)h(the)g(circuit)f(is)g(visible.) 146 550 y(The)i Fb(:\002ndbox)i Fd(command)d(is)g(used)h(to)g(change)g (the)g(vie)n(w)f(according)h(to)g(the)f(box.)34 b(The)26 b(command)f(alone)0 670 y(just)20 b(mo)o(v)o(es)f(the)h(vie)n(w)g (\(without)g(changing)g(the)g(scale)h(f)o(actor\))h(so)e(that)g(the)h (box)f(is)g(in)h(the)f(center)h(of)g(the)g(screen.)0 790 y(If)31 b(the)g Fb(zoom)f Fd(ar)n(gument)g(is)h(gi)n(v)o(en)e(then) h(the)h(magni\002cation)e(is)i(changed)f(too,)i(so)e(that)g(the)h(area) g(of)g(the)g(box)0 911 y(nearly)25 b(\002lls)f(the)h(screen.)31 b Fb(z)25 b Fd(is)g(a)g(macro)g(for)g Fb(:\002ndbox)h(zoom)f Fd(and)g Fb(B)g Fd(is)f(a)h(macro)g(for)g Fb(:\002ndbox)p Fd(.)146 1031 y(The)g(command)e Fb(:view)i Fd(resets)f(the)g(vie)n(w)g (so)g(that)g(the)g(entire)h(cell)f(is)g(visible)f(in)h(the)g(windo)n(w) -6 b(.)29 b(It)24 b(comes)g(in)0 1152 y(handy)g(if)h(you)g(get)f(lost)g (in)g(a)i(big)e(layout.)30 b(The)24 b(macro)h Fb(v)g Fd(is)f(equi)n(v)n(alent)f(to)i Fb(:view)p Fd(.)146 1272 y(The)32 b(command)e Fb(:box)h Fd(prints)g(out)g(the)g(size)g(and)g (location)g(of)g(the)g(box)g(in)g(case)h(you')-5 b(d)30 b(lik)o(e)h(to)g(measure)0 1392 y(something)21 b(in)h(your)h(layout.)29 b(The)23 b(macro)f Fb(b)i Fd(is)e(prede\002ned)h(to)f Fb(:box)p Fd(.)31 b(The)22 b Fb(:box)h Fd(command)f(can)h(also)g(be)f (used)0 1513 y(to)i(set)h(the)g(box)f(to)g(a)i(particular)e(location,)g (height,)g(or)h(width.)30 b(See)25 b(the)g(man)f(page)h(for)g(details.) 146 1633 y(The)g(command)900 1827 y Fb(:what)146 2020 y Fd(will)k(print)g(out)f(information)g(about)h(what')-5 b(s)29 b(selected.)44 b(This)29 b(may)g(be)g(helpful)g(if)h(you')-5 b(re)29 b(not)g(sure)g(what)0 2141 y(layer)c(a)g(particular)g(piece)g (of)g(material)f(is,)h(or)f(what)h(layer)g(a)g(particular)g(label)f(is) h(attached)g(to.)146 2261 y(If)h(you)e(for)n(get)h(what)g(a)g(macro)g (means,)f(you)g(can)h(in)l(v)n(ok)o(e)g(the)f(command)900 2455 y Fb(:macr)n(o)h Fd([)p Fe(c)o(har)p Fd(])146 2649 y(This)i(command)g(will)f(print)h(out)g(the)h(long)e(command)h(that')-5 b(s)26 b(associated)i(with)e(the)i(macro)f Fe(c)o(har)p Fd(.)39 b(If)28 b(you)0 2769 y(omit)c Fe(c)o(har)p Fd(,)g(Magic)g(will) g(print)g(out)g(all)h(of)g(the)f(macro)h(associations.)k(The)c(command) 900 2963 y Fb(:macr)n(o)g Fe(c)o(har)f(command)146 3156 y Fd(W)-8 b(e)28 b(set)g(up)f Fe(c)o(har)g Fd(to)g(be)h(a)g(macro)g (for)g Fe(command)p Fd(,)g(replacing)f(the)h(old)f Fe(c)o(har)f Fd(macro)i(if)g(there)g(w)o(as)f(one.)40 b(If)0 3277 y Fe(command)28 b Fd(contains)f(an)o(y)h(spaces)g(then)g(it)g(must)f (be)h(enclosed)g(in)g(double-quotes.)39 b(T)-8 b(o)28 b(see)h(ho)n(w)e(this)h(w)o(orks,)0 3397 y(type)19 b(the)h(command)f Fb(:macr)n(o)h Fa(1)60 b("echo)e(You)h(just)g(typed)g(the)g(1)h(key.")p Fd(,)19 b(then)h(type)f(the)h(1)f(k)o(e)o(y)-6 b(.)146 3517 y(One)33 b(of)f(the)g(macros,)i(\223)p Fb(.)p Fd(\224,)g(has)e (special)g(meaning)f(in)h(Magic.)53 b(This)31 b(macro)h(is)g(al)o(w)o (ays)g(de\002ned)g(by)g(the)0 3638 y(system)c(to)h(be)g(the)g(last)g (long)g(command)f(you)h(typed.)43 b(Whene)n(v)o(er)29 b(you')-5 b(d)29 b(lik)o(e)g(to)f(repeat)i(a)g(long)e(command,)0 3758 y(all)d(you)f(ha)n(v)o(e)g(to)h(do)f(is)h(use)f(the)h(dot)f (macro.)0 4093 y Ff(11)143 b(What)36 b(the)f(Lay)o(ers)e(Mean)0 4317 y Fd(The)24 b(paint)g(layers)g(a)n(v)n(ailable)f(in)h(Magic)g(are) h(dif)n(ferent)f(from)g(those)f(that)h(you)g(may)g(be)g(used)g(to)g(in) g(Caesar)h(and)0 4437 y(other)20 b(systems)g(because)h(the)o(y)f(don')n (t)g(correspond)g(e)o(xactly)g(to)g(the)h(masks)f(used)g(in)g(f)o (abrication.)29 b(W)-8 b(e)21 b(call)g(them)0 4557 y Fe(abstr)o(act)h(layer)o(s)h Fd(because)h(the)o(y)f(correspond)g(to)g (constructs)g(such)g(as)h(wires)g(and)f(contacts,)g(rather)h(than)g (mask)0 4678 y(layers.)60 b(W)-8 b(e)35 b(also)f(call)h(them)f Fe(lo)o(gs)f Fd(because)i(the)o(y)f(look)g(lik)o(e)g(sticks)g(e)o (xcept)g(that)g(the)g(geometry)g(is)h(dra)o(wn)0 4798 y(fully)f(\003eshed)h(instead)g(of)g(as)g(lines.)60 b(In)35 b(Magic)g(there)g(is)f(one)h(paint)f(layer)h(for)h(each)f(kind)f(of)h (conducting)0 4918 y(material)h(\(polysilicon,)g(ndif)n(fusion,)h (metal1,)h(etc.\),)h(plus)c(one)h(additional)f(paint)g(layer)h(for)g (each)h(kind)e(of)0 5039 y(transistor)21 b(\(ntransistor)l(,)g (ptransistor)l(,)g(etc.\),)i(and,)g(\002nally)-6 b(,)21 b(one)h(further)h(paint)e(layer)h(for)g(each)h(kind)e(of)h(contact)0 5159 y(\(pcontact,)36 b(ndcontact,)f(m2contact,)h(etc.\))58 b(Each)34 b(layer)h(has)e(one)h(or)g(more)g(names)g(that)f(are)i(used)e (to)h(refer)0 5280 y(to)h(that)h(layer)g(in)f(commands.)62 b(T)-8 b(o)36 b(\002nd)g(out)f(the)g(layers)h(a)n(v)n(ailable)f(in)h (the)f(current)h(technology)-6 b(,)37 b(type)e(the)0 5400 y(command)1850 5649 y(\22610\226)p eop %%Page: 11 11 11 10 bop 0 -180 a Fd(Magic)24 b(T)l(utorial)g(#2:)30 b(Basic)25 b(P)o(ainting)f(and)h(Selection)1179 b(September)25 b(26,)g(2001)900 84 y Fb(:lay)o(ers)146 313 y Fd(In)i(addition)f(to)g (the)h(mask)f(layers,)h(there)g(are)g(a)h(fe)n(w)e(pseudo-layers)g (that)h(are)g(v)n(alid)f(in)g(all)h(technologies;)0 433 y(these)k(are)g(listed)f(in)g(T)-8 b(able)31 b(1.)48 b(Each)31 b(Magic)f(technology)g(also)g(has)h(a)g(technology)e(manual)h (describing)g(the)0 553 y(features)22 b(of)g(that)g(technology)-6 b(,)20 b(such)i(as)g(design)f(rules,)h(routing)f(layers,)h(CIF)h (styles,)f(etc.)30 b(If)22 b(you)f(ha)n(v)o(en')n(t)h(seen)0 674 y(an)o(y)i(of)h(the)g(technology)e(manuals)h(yet,)h(this)f(is)g(a)h (good)f(time)h(to)f(tak)o(e)h(a)g(look)f(at)h(the)f(one)h(for)g(your)g (process.)p 1123 815 1655 4 v 1121 935 4 121 v 1173 899 a Fb(err)n(ors)g Fd(\(design-rule)f(violations\))p 2776 935 V 1121 1056 V 1173 1019 a Fb(labels)p 2776 1056 V 1121 1176 V 1173 1140 a(subcells)p 2776 1176 V 1121 1296 V 1197 1260 a Fd(\(all)h(mask)f(layers\))p 2776 1296 V 1121 1417 V 1173 1381 a Fb($)g Fd(\(all)h(mask)f(layers)h(visible)f (under)g(cursor\))p 2776 1417 V 1123 1420 1655 4 v 914 1687 a(T)-8 b(able)25 b(1:)30 b(Pseudo-layers)25 b(a)n(v)n(ailable)f (in)h(all)f(technologies.)146 1924 y(If)38 b(you')-5 b(re)37 b(used)g(to)f(designing)g(with)g(mask)g(layers)h(\(e.g.)68 b(you')-5 b(v)o(e)36 b(been)h(reading)g(the)g(Mead-Conw)o(ay)0 2044 y(book\),)25 b(Magic')-5 b(s)25 b(log)g(style)g(will)f(tak)o(e)i (some)f(getting)f(used)i(to.)32 b(One)26 b(of)g(the)f(reasons)g(for)h (logs)f(is)g(to)g(sa)n(v)o(e)h(you)0 2165 y(w)o(ork.)53 b(In)32 b(Magic)g(you)g(don')n(t)g(dra)o(w)g(implants,)g(wells,)h(b)n (uried)f(windo)n(ws,)h(or)f(contact)g(via)g(holes.)52 b(Instead,)0 2285 y(you)21 b(dra)o(w)h(the)g(primary)f(conducting)g (layers)h(and)g(paint)f(some)g(of)h(their)g(o)o(v)o(erlaps)e(with)h (special)h(types)f(such)h(as)0 2405 y(n-transistor)27 b(or)i(polysilicon)d(contact.)41 b(F)o(or)28 b(transistors,)g(you)f (dra)o(w)i(only)e(the)h(actual)g(area)i(of)e(the)g(transistor)0 2526 y(channel.)60 b(Magic)35 b(will)e(generate)j(the)e(polysilicon)f (and)h(dif)n(fusion,)i(plus)e(an)o(y)g(necessary)h(implants,)g(when)0 2646 y(it)30 b(creates)i(a)f(CIF)g(\002le.)49 b(F)o(or)31 b(contacts,)g(you)g(paint)f(the)g(contact)h(layer)g(in)f(the)g(area)i (of)f(o)o(v)o(erlap)f(between)g(the)0 2767 y(conducting)g(layers.)49 b(Magic)30 b(will)g(generate)i(each)f(of)g(the)g(constituent)e(mask)h (layers)h(plus)f(vias)h(and)f(b)n(uried)0 2887 y(windo)n(ws)21 b(when)i(it)g(writes)f(the)h(CIF)h(\002le.)31 b(Figure)23 b(1)g(sho)n(ws)e(a)j(simple)e(cell)g(dra)o(wn)h(with)f(both)g(mask)h (layers)g(\(as)0 3007 y(in)i(Caesar\))h(and)f(with)f(logs)g(\(as)i(in)e (Magic\).)31 b(If)26 b(you')-5 b(re)25 b(curious)f(about)h(what)g(the)f (masks)h(will)f(look)g(lik)o(e)g(for)i(a)0 3128 y(particular)f(layout,) f(you)g(can)h(use)g(the)f Fb(:cif)i(see)f Fd(command)f(to)g(vie)n(w)g (the)h(mask)f(information.)146 3248 y(An)35 b(adv)n(antage)f(of)h(the)f (logs)g(used)h(in)f(Magic)g(is)g(that)h(the)o(y)e(simplify)g(the)i (design)f(rules.)60 b(Most)33 b(of)i(the)0 3368 y(formation)c(rules)h (\(e.g.)53 b(contact)31 b(structure\))h(go)g(a)o(w)o(ay)-6 b(,)33 b(since)f(Magic)g(automatically)e(generates)j(correctly-)0 3489 y(formed)g(structures)f(when)h(it)g(writes)f(CIF)-8 b(.)35 b(All)d(that)h(are)g(left)g(are)h(minimum)d(size)i(and)g (spacing)f(rules,)j(and)0 3609 y(Magic')-5 b(s)25 b(abstract)g(layers)g (result)g(in)g(fe)n(wer)h(of)g(these)f(than)g(there)h(w)o(ould)e(be)i (otherwise.)32 b(This)24 b(helps)h(to)g(mak)o(e)0 3730 y(Magic')-5 b(s)28 b(b)n(uilt-in)g(design)g(rule)h(check)o(er)g(v)o (ery)g(f)o(ast)g(\(see)g(\223Magic)g(T)l(utorial)f(#6:)38 b(Design)29 b(Rule)g(Checking\224\),)0 3850 y(and)c(is)f(one)h(of)g (the)f(reasons)h(plo)n(wing)e(is)h(possible.)1850 5649 y(\22611\226)p eop %%Page: 12 12 12 11 bop 0 -180 a Fd(September)25 b(26,)f(2001)1180 b(Magic)24 b(T)l(utorial)f(#2:)31 b(Basic)25 b(P)o(ainting)e(and)i (Selection)215 3935 y @beginspecial 190 @llx 28 @lly 420 @urx 764 @ury 3600 @rhi @setspecial %%BeginDocument: ../psfigures/tut2.2.ps /INIT { 72 exch div dup dup scale div exch findfont exch scalefont /TxFont exch def /BoxOutline exch def /#copies exch def TxFont dup /FontBBox get exch /FontMatrix get exch aload pop 4 index transform /bbhi exch def pop 3 -1 roll transform /bblow exch def /bbx exch def /bbhi bbhi bblow sub def /nChars matrix defaultmatrix 0 get abs 72 8.5 mul mul 64 div ceiling cvi def 1 1 dtransform abs dup 1 exch div /onePix exch def dup /resY exch def 1 exch div /iresY exch def abs dup /resX exch def 1 exch div /iresX exch def /bX 64 iresX mul def /bY 64 iresY mul def /pattFont StipplePattern definefont pop /patterns /pattFont findfont [iresX 64 mul 0 0 iresY 64 mul 0 0] makefont def /CA nChars 1 add string def } def /StipplePattern 45 dict def StipplePattern begin /FontType 3 def /FontMatrix [1 0 0 1 0 0] def /FontBBox [0 0 1 1] def /Encoding 256 array def /PattName (P0) def /tmpStr 1 string def /NoPatt {<00>} def 0 1 255 { Encoding exch /NoPatt put } for /BuildChar { 1 0 0 0 1 1 setcachedevice exch begin Encoding exch get load 64 64 true [64 0 0 64 0 0] 5 -1 roll imagemask end } def end /DefPatt { StipplePattern begin dup 30 tmpStr cvrs PattName exch 1 exch putinterval PattName cvn dup Encoding exch 4 -1 roll exch put exch store end } def /HEADER { 4 onePix mul add moveto show } def /SL { 0 1 nChars { exch dup 3 1 roll CA 3 1 roll put } for pop } def /SC { 0 1 nChars { exch dup 3 1 roll CA 3 1 roll put } for 4 mul colors exch 4 getinterval aload pop setcmykcolor } def /SP { patterns setfont 2 setlinewidth } def /ST { TxFont setfont onePix 2 mul setlinewidth } def /V { newpath moveto 0 exch rlineto stroke } def /H { newpath moveto 0 rlineto stroke } def /B { /h exch def /w exch def /y exch def /x exch def gsave newpath x y moveto w y lineto w h lineto x h lineto closepath clip x resX mul cvi 63 not and dup iresX mul exch w resX mul sub abs 63 add cvi 64 idiv /w exch def y resY mul cvi 63 not and dup iresY mul exch h resY mul sub abs 63 add cvi 64 idiv /h exch def /CH CA 0 w getinterval def moveto h { CH gsave show grestore 0 bY rmoveto } repeat grestore } def /L { gsave newpath dup bblow add 2 index bbx add exch moveto 0 bbhi rlineto 2 index stringwidth pop bbx abs 2 mul add 0 rlineto 0 bbhi neg rlineto closepath 1.0 setgray fill grestore moveto show } def /BB { /h exch def /w exch def /y exch def /x exch def grestore gsave newpath x y moveto w y lineto w h lineto x h lineto closepath BoxOutline 1 eq { gsave stroke grestore } if clip } def /BS { 4 copy BB exch pop exch pop exch bbhi add exch bbhi sub onePix sub L } def /MSAV { /Mstat save def } def /MRES { Mstat restore } def {<000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c00000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0>} 0 DefPatt {<000000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c00000000000000000000000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0>} 1 DefPatt {<00000000000000000c0c0c0c0c0c0c0c000000000000000000000000000000000000000000000000c0c0c0c0c0c0c0c000000000000000000000000000000000>} 5 DefPatt {<00000000000000000c0c0c0c0c0c0c0c000000000000000000000000000000000000000000000000c0c0c0c0c0c0c0c000000000000000000000000000000000>} 6 DefPatt {} 8 DefPatt {<8383838383838383c1c1c1c1c1c1c1c1e0e0e0e0e0e0e0e0707070707070707038383838383838381c1c1c1c1c1c1c1c0e0e0e0e0e0e0e0e0707070707070707>} 9 DefPatt {<8181818181818181c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3818181818181818118181818181818183c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c1818181818181818>} 11 DefPatt {} 16 DefPatt /colors [0.18 0.37 0.43 0.00 0.87 0.12 0.87 0.00 0.00 0.00 0.00 0.75 0.12 0.43 0.12 0.00 0.12 0.43 1.00 0.00 0.25 0.37 0.75 0.00 1.00 0.25 1.00 0.00 0.00 0.00 0.00 0.50 0.87 0.18 0.87 0.00 0.00 1.00 1.00 0.00 0.00 0.00 1.00 0.00 0.75 0.50 0.00 0.00 0.37 0.87 0.25 0.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 1.00 0.00 0.00 0.00 0.75 0.75 0.50 0.25 0.00 ] def 1 1 /Helvetica 10.0 300.000000 INIT % ST (tutcell.cif Scale: 0.212766 \(5404X\) Size: 14 x 47 microns ) 828 3150 HEADER SP 828 150 translate 0 SC 1532 0 0 V 894 0 0 H 1532 894 0 V 894 0 1532 H 0 0 894 1532 B 1 SC 1404 0 1596 V 894 0 1596 H 1404 894 1596 V 894 0 3000 H 0 1596 894 3000 B 5 SC 1022 191 1787 V 511 191 1787 H 1022 702 1787 V 511 191 2809 H 191 1787 702 2809 B 6 SC 1149 191 191 V 511 191 191 H 1149 702 191 V 511 191 1340 H 191 191 702 1340 B 8 SC 894 319 319 V 766 319 1915 V 383 511 574 V 319 319 511 1213 B 256 511 2170 V 319 1915 511 2681 B 255 319 319 H 255 574 319 V 63 511 574 H 511 319 574 574 B 63 511 957 H 256 574 957 V 255 319 1213 H 511 957 574 1213 B 255 319 1915 H 255 574 1915 V 63 511 2170 H 511 1915 574 2170 B 63 511 2426 H 255 574 2426 V 255 319 2681 H 511 2426 574 2681 B 9 SC 128 0 702 V 128 0 2234 V 702 0 702 H 128 702 702 V 702 0 830 H 0 702 702 830 B 766 0 2234 H 128 766 2234 V 766 0 2362 H 0 2234 766 2362 B 11 SC 192 0 319 V 192 0 2489 V 319 0 511 H 0 319 319 511 B 63 319 511 V 1213 319 957 V 63 319 2426 V 319 0 2489 H 0 2489 319 2681 B 63 574 511 V 255 319 574 H 319 319 574 574 B 255 319 957 H 511 574 957 V 447 574 1723 V 255 319 2170 H 319 957 574 2170 B 255 319 2426 H 63 574 2426 V 319 2426 574 2681 B 894 0 319 H 192 894 319 V 320 574 511 H 574 319 894 511 B 320 574 1468 H 255 894 1468 V 320 574 1723 H 574 1468 894 1723 B 320 574 2489 H 192 894 2489 V 894 0 2681 H 574 2489 894 2681 B 16 SC 128 383 383 V 128 383 1021 V 127 383 1979 V 128 383 2489 V 128 383 383 H 128 511 383 V 128 383 511 H 383 383 511 511 B 128 383 1021 H 128 511 1021 V 128 383 1149 H 383 1021 511 1149 B 128 383 1979 H 127 511 1979 V 128 383 2106 H 383 1979 511 2106 B 128 383 2489 H 128 511 2489 V 128 383 2617 H 383 2489 511 2617 B ST gsave % (tutcell1) 0 0 894 3000 BS % 0 0 894 3000 BB grestore showpage %%EndDocument @endspecial 1735 3635 a @beginspecial 72 @llx 72 @lly 540 @urx 560 @ury 2880 @rhi @setspecial %%BeginDocument: ../psfigures/tut2.1.ps % % PostScript prolog for output from magic plot % Version: 1.0 % written by Tim Edwards 4/05/00 JHU Applied Physics Laboratory % % supporting definitions /MAGICsave save def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /minit { /nChars matrix defaultmatrix 0 get abs 72 8.5 mul mul 64 div ceiling cvi def 1 1 dtransform abs dup 1 exch div /onePix exch def dup /resY exch def 1 exch div /iresY exch def abs dup /resX exch def 1 exch div /iresX exch def /bX 64 iresX mul def /bY 64 iresY mul def /pattFont StipplePattern definefont pop /patterns /pattFont findfont [iresX 64 mul 0 0 iresY 64 mul 0 0] makefont def /ca nChars 1 add string def } def /StipplePattern 45 dict def StipplePattern begin /FontType 3 def /FontMatrix [1 0 0 1 0 0] def /FontBBox [0 0 1 1] def /Encoding 256 array def /PattName (P0) def /tmpStr 1 string def /NoPatt {<00>} def 0 1 255 { Encoding exch /NoPatt put } for /BuildChar { 1 0 0 0 1 1 setcachedevice exch begin Encoding exch get load 64 64 true [64 0 0 64 0 0] 5 -1 roll imagemask end } def end /dp { StipplePattern begin dup 30 tmpStr cvrs PattName exch 1 exch putinterval PattName cvn dup Encoding exch 4 -1 roll exch put exch store end } def /sf { findfont exch scalefont setfont } bind def /sp { patterns setfont 2 setlinewidth } def /lb { gsave translate 0 0 moveto /just exch def gsave dup true charpath flattenpath pathbbox grestore exch 4 -1 roll exch sub 3 1 roll sub just 4 and 0 gt {just 8 and 0 eq {0.5 mul} if}{pop 0} ifelse exch just 1 and 0 gt {just 2 and 0 eq {0.5 mul} if}{pop 0} ifelse exch rmoveto show grestore } def /sl { 0 1 nChars { exch dup 3 1 roll ca 3 1 roll put } for pop } def /sc { setcmykcolor } bind def /l1 { onePix setlinewidth } def /l2 { onePix 2 mul setlinewidth } def /l3 { onePix 3 mul setlinewidth } def /ml { moveto lineto stroke } bind def /vl { moveto 0 exch rlineto stroke } bind def /hl { moveto 0 rlineto stroke } bind def /mr { rectstroke } bind def /mx { 4 copy rectstroke 4 -1 roll 4 -1 roll 4 copy moveto rlineto stroke 3 -1 roll dup neg 4 1 roll add moveto rlineto stroke } bind def /pl { gsave translate /d exch def 0 d neg moveto 0 d lineto stroke d neg 0 moveto d 0 lineto stroke grestore } bind def /fb {/h exch def /w exch def /y exch def /x exch def gsave newpath x y moveto w y lineto w h lineto x h lineto closepath clip x resX mul cvi 63 not and dup iresX mul exch w resX mul sub abs 63 add cvi 64 idiv /w exch def y resY mul cvi 63 not and dup iresY mul exch h resY mul sub abs 63 add cvi 64 idiv /h exch def /ch ca 0 w getinterval def moveto h { ch gsave show grestore 0 bY rmoveto } repeat grestore } def /f1 { 1.440 /Helvetica sf } def /f2 { 0.960 /HelveticaBold sf } def /f3 { 0.640 /Helvetica sf } def /col17 {0.090 0.686 0.718 0.000 sc} bind def /col16 {0.435 0.592 0.957 0.000 sc} bind def /col15 {0.749 0.498 0.247 0.000 sc} bind def /col14 {0.000 0.000 0.000 255.000 sc} bind def /col13 {0.373 0.875 0.247 0.000 sc} bind def /col12 {0.749 0.498 0.000 0.000 sc} bind def /col11 {0.000 0.000 1.000 0.000 sc} bind def /col10 {0.000 1.000 1.000 0.000 sc} bind def /col9 {0.875 0.184 0.875 0.000 sc} bind def /col8 {0.000 0.000 0.000 127.000 sc} bind def /col7 {1.000 0.247 1.000 0.000 sc} bind def /col6 {0.247 0.373 0.749 0.000 sc} bind def /col5 {0.122 0.435 1.000 0.000 sc} bind def /col4 {0.122 0.435 0.122 0.000 sc} bind def /col3 {0.000 0.000 0.000 192.000 sc} bind def /col2 {0.875 0.122 0.875 0.000 sc} bind def /col1 {0.184 0.373 0.435 0.000 sc} bind def {<000000000000000000000000000000003333333333333333333333333333333300000000000000000000000000000000cccccccccccccccccccccccccccccccc>} 13 dp {<00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000>} 12 dp {<010000800100008002000040020000400c0000300c000030f000000ff000000f000ff000000ff00000300c0000300c0000400200004002000080010000800100>} 11 dp {} 10 dp {<18181818181818183c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c18181818181818188181818181818181c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c38181818181818181>} 9 dp {<18181818181818180c0c0c0c0c0c0c0c060606060606060603030303030303038181818181818181c0c0c0c0c0c0c0c060606060606060603030303030303030>} 8 dp {<181818181818181830303030303030306060606060606060c0c0c0c0c0c0c0c08181818181818181030303030303030306060606060606060c0c0c0c0c0c0c0c>} 7 dp {<07070707070707070e0e0e0e0e0e0e0e1c1c1c1c1c1c1c1c38383838383838387070707070707070e0e0e0e0e0e0e0e0c1c1c1c1c1c1c1c18383838383838383>} 6 dp {} 5 dp {<00000000000000000000000000000000c0c0c0c0c0c0c0c00000000000000000000000000000000000000000000000000c0c0c0c0c0c0c0c0000000000000000>} 4 dp {<0003000300030003000c000c000c000c003000300030003000c000c000c000c003000300030003000c000c000c000c003000300030003000c000c000c000c000>} 3 dp {} 2 dp {} 1 dp /pgsave save def bop % 0 0 offsets 72 85 translate 12.500 12.500 scale minit 0 0 26 37 gsave rectclip l2 sp col2 4 sl col1 4 sl col9 5 sl l1 4 21 16 hl 4 21 16 vl 4 21 20 hl 21 16 25 20 fb 4 25 16 vl 1 8 10 hl 4 5 10 vl 4 5 14 hl 3 9 11 vl 5 10 9 14 fb 4 9 10 vl 4 21 11 hl 4 21 11 vl 1 21 14 vl 4 21 15 hl % 21 11 25 15 fb 4 25 11 vl 3 5 8 hl 6 5 8 vl 5 8 8 10 fb 2 8 8 vl 2 5 4 vl 3 5 6 hl 1 8 5 vl 5 4 8 6 fb 2 8 4 vl 4 5 0 hl 6 5 0 vl 1 8 4 hl 3 9 1 vl 5 0 9 4 fb 4 9 0 vl col1 5 sl 1 8 33 hl 4 5 33 vl 4 5 37 hl 5 33 9 37 fb 4 9 33 vl 3 5 32 hl 5 5 32 vl 5 32 8 33 fb 1 8 32 vl 1 5 29 vl 3 5 30 hl 5 29 8 30 fb 1 8 29 vl 4 5 25 hl 5 5 25 vl 1 8 29 hl 3 9 26 vl 5 25 9 29 fb 4 9 25 vl 4 21 21 hl 4 21 21 vl 4 21 25 hl 21 21 25 25 fb 4 25 21 vl col17 5 sl 3 5 30 hl 2 5 30 vl 3 5 32 hl 5 30 8 32 fb 2 8 30 vl 4 21 6 hl 4 21 6 vl 2 21 8 vl 4 21 10 hl 21 6 25 10 fb 4 25 6 vl col16 5 sl 3 5 6 hl 2 5 6 vl 3 5 8 hl 5 6 8 8 fb 2 8 6 vl 4 21 1 hl 4 21 1 vl 1 21 4 vl 4 21 5 hl 21 1 25 5 fb 4 25 1 vl col10 5 sl 5 0 30 hl 2 0 30 vl 5 0 32 hl 0 30 5 32 fb 2 5 30 vl 4 8 30 hl 2 8 30 vl 4 8 32 hl 8 30 12 32 fb 2 12 30 vl 4 21 26 hl 4 21 26 vl 1 21 29 vl 4 21 30 hl 21 26 25 30 fb 4 25 26 vl 5 0 6 hl 2 0 6 vl 5 0 8 hl 0 6 5 8 fb 2 5 6 vl 3 8 6 hl 2 8 6 vl 3 8 8 hl 8 6 11 8 fb 2 11 6 vl col1 7 sl 3 5 30 hl 2 5 30 vl 3 5 32 hl 5 30 8 32 fb 2 8 30 vl 4 21 6 hl 4 21 6 vl 2 21 8 vl 4 21 10 hl 21 6 25 10 fb 4 25 6 vl col9 8 sl 3 5 6 hl 2 5 6 vl 3 5 8 hl 5 6 8 8 fb 2 8 6 vl 4 21 1 hl 4 21 1 vl 1 21 4 vl 4 21 5 hl 21 1 25 5 fb 4 25 1 vl col6 1 sl col7 1 sl col11 7 sl col12 9 sl 4 5 33 hl 4 5 33 vl 4 5 37 hl 5 33 9 37 fb 4 9 33 vl 4 5 25 hl 5 5 25 vl 4 5 29 hl 3 9 26 vl 5 25 9 29 fb 4 9 25 vl 4 5 10 hl 4 5 10 vl 4 5 14 hl 3 9 11 vl 5 10 9 14 fb 4 9 10 vl 4 21 11 hl 4 21 11 vl 1 21 14 vl 4 21 15 hl % 21 11 25 15 fb 4 25 11 vl 4 5 0 hl 6 5 0 vl 4 5 4 hl 3 9 1 vl 5 0 9 4 fb 4 9 0 vl 5 0 34 hl 3 0 34 vl 5 0 37 hl 0 34 5 37 fb 3 5 34 vl 5 9 34 hl 3 9 34 vl 5 9 37 hl 2 14 35 vl 9 34 14 37 fb 3 14 34 vl 4 21 31 hl 4 21 31 vl 2 21 33 vl 1 21 34 vl 4 21 35 hl 21 31 25 35 fb 4 25 31 vl 7 5 22 vl 4 5 25 hl 5 22 9 25 fb 7 9 22 vl 5 9 18 hl 11 5 18 vl 5 9 22 hl 5 18 14 22 fb 4 14 18 vl 4 5 14 hl 15 5 14 vl 3 9 15 vl 5 14 9 18 fb 4 9 14 vl 5 0 0 hl 3 0 0 vl 5 0 3 hl 0 0 5 3 fb 4 5 0 vl 5 9 0 hl 4 9 0 vl 5 9 3 hl 9 0 14 3 fb 3 14 0 vl col13 10 sl col14 13 sl col14 11 sl col14 col14 l2 5 33 4 4 mx 5 25 4 4 mx 5 10 4 4 mx 21 11 4 4 mx 5 0 4 4 mx 21 31 4 4 mr 21 26 4 4 mr 21 21 4 4 mr 21 16 4 4 mr 21 11 4 4 mr 21 6 4 4 mr 21 1 4 4 mr grestore f1 0 setgray (Metal) 4 26 33 lb (Polysilicon) 4 26 28 lb (P-Diffusion) 4 26 23 lb (N-Diffusion) 4 26 18 lb (Contact) 4 26 13 lb (P-Fet) 4 26 8 lb (N-Fet) 4 26 3 lb pgsave restore showpage MAGICsave restore %%EndDocument @endspecial 0 4095 a(Figure)30 b(1:)40 b(An)29 b(e)o(xample)g(of)h(ho) n(w)f(the)g(logs)g(are)h(used.)45 b(The)30 b(\002gure)g(on)f(the)h (left)f(sho)n(ws)f(actual)i(mask)f(layers)0 4215 y(for)24 b(an)g(CMOS)g(in)l(v)o(erter)f(cell,)h(and)f(the)h(\002gure)g(on)g(the) f(right)g(sho)n(ws)f(the)i(layers)g(used)f(to)g(represent)h(the)g(cell) f(in)0 4335 y(Magic.)1850 5649 y(\22612\226)p eop %%Trailer end userdict /end-hook known{end-hook}if %%EOF magic-8.0.210/irouter/0000755000175000001440000000000011504623574013152 5ustar timusersmagic-8.0.210/irouter/irInternal.h0000644000175000001440000000544610751423606015440 0ustar timusers/* * irInternal.h -- * * This file defines data structures and constants and declares * variables INTERNAL TO THE IROUTER * but shared by two or more source files. * * Structures etc. that are exported by the irouter are defined in * irouter.h. * * Structures etc. that are local to a given source * file are declared at the top of that source file. * * Structures, etc., specific to a given function are usually defined at * the head of that function. * * ********************************************************************* * * Copyright (C) 1987, 1990 Michael H. Arnold, Walter S. Scott, and * * * the 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. * * ********************************************************************* * * rcsid $Header: /usr/cvsroot/magic-8.0/irouter/irInternal.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ */ #ifndef _IRINTERNAL_H #define _IRINTERNAL_H #include "irouter/irouter.h" #include "mzrouter/mzrouter.h" /* ------------------------ Version String -------------------------- */ #define IROUTER_VERSION "1.0" /* ------------------------ Debugging flags ------------------------- */ #include "irDebug.h" extern ClientData irDebugID; /* ------------------------ Routines Global to IRouter --------------- */ extern RouteType *irFindRouteType(); extern RouteLayer *irFindRouteLayer(); extern RouteContact *irFindRouteContact(); extern char *irRepeatChar(); /* ------------------------ Data Global to IRouter ------------------- */ extern MazeParameters *irMazeParms; /* irRouteLayer, Contact, and Type pointers should be identical to * corresponding fields in irMazeParms. They are referenced directly * instead of through parms struc for historical reasons */ extern RouteLayer *irRouteLayers; extern RouteContact *irRouteContacts; extern RouteType *irRouteTypes; extern int irRouteWid; /* Reference window for subcell expansion modes */ /* start types = methods of specifying route start */ #define ST_CURSOR 1 #define ST_LABEL 2 #define ST_POINT 3 /* dest types = methods of specifying route destination */ #define DT_BOX 1 #define DT_LABEL 2 #define DT_RECT 3 #define DT_SELECTION 4 #endif /* _IRINTERNAL_H */ magic-8.0.210/irouter/irUtils.c0000644000175000001440000000756510751423606014763 0ustar timusers/* * irUtils.c --- * * Misc. utility routines for irouter. * * * ********************************************************************* * * Copyright (C) 1987, 1990 Michael H. Arnold, Walter S. Scott, and * * * the 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/irouter/irUtils.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/list.h" #include "mzrouter/mzrouter.h" #include "irouter/irouter.h" #include "irouter/irInternal.h" /* * ---------------------------------------------------------------------------- * * irFindRouteType -- * * Search irRouteLayers and irRouteContacts lists for routeType of given * tile type. * * Results: * pointer to routetype struc if found, else Null. * * ---------------------------------------------------------------------------- */ RouteType * irFindRouteType(type) TileType type; { RouteType *rT; /* Search list of routetypes for one with appropriate type */ for (rT = irRouteTypes; rT && rT->rt_tileType!=type; rT=rT->rt_next) ; /* return result */ return(rT); } /* * ---------------------------------------------------------------------------- * * irFindRouteLayer -- * * search irRouteLayers struc for given tiletype. * * Results: * pointer to routelayer struc if found, else Null. * * ---------------------------------------------------------------------------- */ RouteLayer * irFindRouteLayer(type) TileType type; { RouteLayer *rL; /* Search list of routelayers for one with appropriate type */ for (rL = irRouteLayers; rL && rL->rl_routeType.rt_tileType!=type; rL=rL->rl_next) ; /* return result */ return(rL); } /* * ---------------------------------------------------------------------------- * * irFindRouteContact -- * * Search irRoutecontacts for given tiletype. * * Results: * pointer to routecontact struc if found, else Null. * * ---------------------------------------------------------------------------- */ RouteContact * irFindRouteContact(type) TileType type; { RouteContact *rC; /* Search list of routecontacts for one with appropriate type */ for (rC = irRouteContacts; rC && rC->rc_routeType.rt_tileType!=type; rC=rC->rc_next) ; /* return result */ return(rC); } /* * ---------------------------------------------------------------------------- * * irRepeatChar -- * * Build temporary string consisting of n repetitions of a character. * * Results: * Pointer to temporary string. * * Side effects: * RepeatString set to desired string. * * Note: * A call to this procedure destroys old strings previously built * by the procedure. * * ---------------------------------------------------------------------------- */ char RepeatString[100]; char * irRepeatChar(n,c) int n; char c; { int i; for(i=0; i #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "drc/drc.h" #include "select/select.h" #include "utils/signals.h" #include "textio/textio.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "utils/styles.h" #include "debug/debug.h" #include "utils/undo.h" #include "textio/txcommands.h" #include "utils/malloc.h" #include "utils/list.h" #include "../mzrouter/mzrouter.h" #include "irouter/irouter.h" #include "irouter/irInternal.h" /*------------------------------ Global Data ------------------------------*/ /* Debug flags */ ClientData irDebugID; int irDebEndPts; /* values identify flags to debug module */ int irDebNoClean; int irRouteWid = -1; /* if >=0, wid of window to use for determining * subcell expansion, and route cell. */ MazeParameters *irMazeParms = NULL; /* parameter settings passed to maze router */ /* the following RouteEtc pointers should have the same value as the * corresponding fileds in irMazeParms. They exist for historical * reasons. */ RouteLayer *irRouteLayers; RouteContact *irRouteContacts; RouteType *irRouteTypes; /* * ---------------------------------------------------------------------------- * * IRDebugInit -- * * This procedure is called when Magic starts up, and should not be * called again. * * Results: * None. * * Side effects: * Register ourselves with debug module * Setup some internal datastructures. * * ---------------------------------------------------------------------------- */ void IRDebugInit() { int n; /* debug struct */ static struct { char *di_name; int *di_id; } dflags[] = { "endpts", &irDebEndPts, "noclean", &irDebNoClean, 0 }; /* Register with debug module */ irDebugID = DebugAddClient("irouter", sizeof dflags/sizeof dflags[0]); for (n = 0; dflags[n].di_name; n++) *(dflags[n].di_id) = DebugAddFlag(irDebugID, dflags[n].di_name); return; } /* * ---------------------------------------------------------------------------- * * IRAfterTech -- * * This routine should be called after technology initialization or reloading, * and should be called *after* the maze routere has been initialized. * * Results: * None. * * Side effects: * Register ourselves with debug module * Setup some internal datastructures. * * ---------------------------------------------------------------------------- */ void IRAfterTech() { /* Initialize the irouter maze parameters with a copy of the "irouter" * style (default) parameters. */ if (irMazeParms != NULL) { /* Free any existing parameters */ MZFreeParameters(irMazeParms); irMazeParms = NULL; } irMazeParms = MZCopyParms(MZFindStyle("irouter")); if (irMazeParms != NULL) { /* set global type lists from current irouter parms. * These lists are often referenced directly rather than through * the parameter structure for historical reasons. */ irRouteLayers = irMazeParms->mp_rLayers; irRouteContacts = irMazeParms->mp_rContacts; irRouteTypes = irMazeParms->mp_rTypes; } } magic-8.0.210/irouter/irDebug.h0000644000175000001440000000342310751423606014703 0ustar timusers/* * irDebug.h -- * * Declarations of debugging flag "handles" for interactive router. * * This include file is referenced inside mzInternal.h, hence hiding this * file from make. This is so that debuging flags can be added without * forcing recompilation of everything. * * Debug flags are defined and registered with the debug module in irMain.c * NOTE: the values of the externs defined below are NOT THE FLAG VALUES, * rather they are handles for the flags - flags are tested with calls to * DebugIsSet(). * * Flags can be examined or set by the user via the ":*iroute debug" command. * * ********************************************************************* * * Copyright (C) 1987, 1990 Michael H. Arnold, Walter S. Scott, and * * * the 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. * * ********************************************************************* * * rcsid $Header: /usr/cvsroot/magic-8.0/irouter/irDebug.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ * */ extern int irDebEndPts; /* traces endpoint processing */ extern int irDebNoClean; /* doesn't cleanup after route, so data strucs * can be examined. */ magic-8.0.210/irouter/irCommand.c0000644000175000001440000016224010751423606015231 0ustar timusers/* * irCommand.c -- * * Command interface for interactive router. This file processes command * lines beginning with the `iroute' command. * * (The "wizard" command, `*iroute', for testing, debugging, etc., * is processed in irTestCmd.c.) * * ********************************************************************* * * Copyright (C) 1987, 1990 Michael H. Arnold, Walter S. Scott, and * * * the 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/irouter/irCommand.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include #include "tcltk/tclmagic.h" #include "utils/magic.h" #include "utils/geometry.h" #include "utils/hash.h" #include "tiles/tile.h" #include "database/database.h" #include "utils/signals.h" #include "textio/textio.h" #include "graphics/graphics.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "dbwind/dbwtech.h" #include "textio/txcommands.h" #include "utils/main.h" #include "utils/utils.h" #include "commands/commands.h" #include "utils/styles.h" #include "utils/malloc.h" #include "utils/list.h" #include "mzrouter/mzrouter.h" #include "irouter/irouter.h" #include "irouter/irInternal.h" /* window command issued to */ static MagWindow *irWindow; /* Subcommand table - declared here since its referenced before defined */ typedef struct { char *sC_name; /* name of iroute subcommand */ void (*sC_proc)(); /* Procedure implementing this subcommand */ char *sC_commentString; /* describes subcommand */ char *sC_usage; /* command syntax */ } SubCmdTableE; extern SubCmdTableE irSubcommands[]; /* * ---------------------------------------------------------------------------- * * irSetNoisyAutoInt * * Set integer parameter, interpeting the string "AUTOMATIC" (or prefix) * as -1. * * Results: * None. * * Side effects: * If valueS is a nonnull string, interpret and set parm * accordingly. * * If valueS is null, the parameter value is left unaltered. * * If file is nonnull parameter value is written to file. * * If file is null, parameter value is written to magic text window via * TxPrintf * * If file is (FILE *)1, parameter value is returned as a Tcl object * * ---------------------------------------------------------------------------- */ void irSetNoisyAutoInt(parm, valueS, file) int *parm; char *valueS; FILE *file; { int which; /* special value Table */ #define V_AUTOMATIC -1 static struct { char *sv_name; /* name */ int sv_type; } specialValues[] = { "automatic", V_AUTOMATIC, 0 }; /* If value non-null set parm */ if(valueS!=NULL) { int i; /* check if special value */ which = LookupStruct( valueS, (char **) specialValues, sizeof specialValues[0]); if(which == -1) { TxError("Ambiguous value: '%s'\n",valueS); TxError("Value must be 'AUTOMATIC', or a nonnegative integer\n"); return; } else if (which >= 0 ) { /* special value */ int type = specialValues[which].sv_type; if(type == V_AUTOMATIC) { *parm = -1; } else { /* should not ever get here */ ASSERT(FALSE,"irSetNoisyAutoInt"); } } else if(StrIsInt(valueS) && (i=atoi(valueS))>=0) { *parm = i; } else { TxError("Bad value: \"%s\"\n", valueS); TxError("Value must be 'AUTOMATIC', or a nonnegative integer\n"); return; } } /* Print parm value */ if(file) { if(*parm == -1) { fprintf(file,"AUTOMATIC"); } else { fprintf(file, "%8d ",*parm); } } else { if(*parm == -1) { TxPrintf("AUTOMATIC"); } else { TxPrintf("%8d ",*parm); } } return; } /* * ---------------------------------------------------------------------------- * * irLSet -- * * Set and display Route Layer parameter . * * Results: * None. * * Side effects: * Call low level routine of appropriate type to set/display parameter. * Value of parm can be displayed either in Magic text window (file is * NULL) or to a file. * * ---------------------------------------------------------------------------- */ #ifdef MAGIC_WRAPPER /* irLSetActive -- */ Tcl_Obj * irLSetActive(rL,s,file) RouteLayer *rL; char *s; FILE *file; { if (file == (FILE *)1) return Tcl_NewBooleanObj(rL->rl_routeType.rt_active); SetNoisyBool(&(rL->rl_routeType.rt_active), s, file); return NULL; } /* irLSetWidth -- */ Tcl_Obj * irLSetWidth(rL,s,file) RouteLayer *rL; char *s; FILE *file; { if (file == (FILE *)1) return Tcl_NewIntObj(rL->rl_routeType.rt_width); SetNoisyInt(&(rL->rl_routeType.rt_width),s,file); return NULL; } /* irLSetLength -- */ Tcl_Obj * irLSetLength(rL,s,file) RouteLayer *rL; char *s; FILE *file; { if (file == (FILE *)1) return Tcl_NewIntObj(rL->rl_routeType.rt_length); SetNoisyInt(&(rL->rl_routeType.rt_length),s,file); return NULL; } /* irLSetHCost -- */ Tcl_Obj * irLSetHCost(rL,s,file) RouteLayer *rL; char *s; FILE *file; { if (file == (FILE *)1) return Tcl_NewIntObj(rL->rl_hCost); SetNoisyInt(&(rL->rl_hCost),s,file); return NULL; } /* irLSetVCost -- */ Tcl_Obj * irLSetVCost(rL,s,file) RouteLayer *rL; char *s; FILE *file; { if (file == (FILE *)1) return Tcl_NewIntObj(rL->rl_vCost); SetNoisyInt(&(rL->rl_vCost),s,file); return NULL; } /* irLSetJogCost -- */ Tcl_Obj * irLSetJogCost(rL,s,file) RouteLayer *rL; char *s; FILE *file; { if (file == (FILE *)1) return Tcl_NewIntObj(rL->rl_jogCost); SetNoisyInt(&(rL->rl_jogCost),s,file); return NULL; } /* irLSetHintCost -- */ Tcl_Obj * irLSetHintCost(rL,s,file) RouteLayer *rL; char *s; FILE *file; { if (file == (FILE *)1) return Tcl_NewIntObj(rL->rl_hintCost); SetNoisyInt(&(rL->rl_hintCost),s,file); return NULL; } /* irLSetOverCost -- */ Tcl_Obj * irLSetOverCost(rL,s,file) RouteLayer *rL; char *s; FILE *file; { if (file == (FILE *)1) return Tcl_NewIntObj(rL->rl_overCost); SetNoisyInt(&(rL->rl_overCost),s,file); return NULL; } #else /* irLSetActive -- */ void irLSetActive(rL,s,file) RouteLayer *rL; char *s; FILE *file; { SetNoisyBool(&(rL->rl_routeType.rt_active),s,file); } /* irLSetWidth -- */ void irLSetWidth(rL,s,file) RouteLayer *rL; char *s; FILE *file; { SetNoisyInt(&(rL->rl_routeType.rt_width),s,file); } /* irLSetLength -- */ void irLSetLength(rL,s,file) RouteLayer *rL; char *s; FILE *file; { SetNoisyInt(&(rL->rl_routeType.rt_length),s,file); } /* irLSetHCost -- */ void irLSetHCost(rL,s,file) RouteLayer *rL; char *s; FILE *file; { SetNoisyInt(&(rL->rl_hCost),s,file); } /* irLSetVCost -- */ void irLSetVCost(rL,s,file) RouteLayer *rL; char *s; FILE *file; { SetNoisyInt(&(rL->rl_vCost),s,file); } /* irLSetJogCost -- */ void irLSetJogCost(rL,s,file) RouteLayer *rL; char *s; FILE *file; { SetNoisyInt(&(rL->rl_jogCost),s,file); } /* irLSetHintCost -- */ void irLSetHintCost(rL,s,file) RouteLayer *rL; char *s; FILE *file; { SetNoisyInt(&(rL->rl_hintCost),s,file); } /* irLSetOverCost -- */ void irLSetOverCost(rL,s,file) RouteLayer *rL; char *s; FILE *file; { SetNoisyInt(&(rL->rl_overCost),s,file); } #endif /* * ---------------------------------------------------------------------------- * * irCSet -- * * Set and display contact parameter . * * Results: * None. * * Side effects: * Call low level routine of appropriate type to set/display parameter. * Value of parm can be displayed either in Magic text window (file is * NULL) or to a file. * * ---------------------------------------------------------------------------- */ #ifdef MAGIC_WRAPPER /* irCSetActive -- */ Tcl_Obj * irCSetActive(rC,s, file) RouteContact *rC; char *s; FILE *file; { if (file == (FILE *)1) return Tcl_NewBooleanObj(rC->rc_routeType.rt_active); SetNoisyBool(&(rC->rc_routeType.rt_active),s,file); return NULL; } /* irCSetWidth -- */ Tcl_Obj * irCSetWidth(rC,s,file) RouteContact *rC; char *s; FILE *file; { if (file == (FILE *)1) return Tcl_NewIntObj(rC->rc_routeType.rt_width); SetNoisyInt(&(rC->rc_routeType.rt_width),s,file); return NULL; } /* irCSetLength-- */ Tcl_Obj * irCSetLength(rC,s,file) RouteContact *rC; char *s; FILE *file; { if (file == (FILE *)1) return Tcl_NewIntObj(rC->rc_routeType.rt_length); SetNoisyInt(&(rC->rc_routeType.rt_length),s,file); return NULL; } /* irCSetCost -- */ Tcl_Obj * irCSetCost(rC,s,file) RouteContact *rC; char *s; FILE *file; { if (file == (FILE *)1) return Tcl_NewIntObj(rC->rc_cost); SetNoisyInt(&(rC->rc_cost),s,file); return NULL; } #else /* irCSetActive -- */ void irCSetActive(rC,s, file) RouteContact *rC; char *s; FILE *file; { SetNoisyBool(&(rC->rc_routeType.rt_active),s,file); } /* irCSetWidth -- */ void irCSetWidth(rC,s,file) RouteContact *rC; char *s; FILE *file; { SetNoisyInt(&(rC->rc_routeType.rt_width),s,file); } /* irCSetLength -- */ void irCSetLength(rC,s,file) RouteContact *rC; char *s; FILE *file; { SetNoisyInt(&(rC->rc_routeType.rt_length),s,file); } /* irCSetCost -- */ void irCSetCost(rC,s,file) RouteContact *rC; char *s; FILE *file; { SetNoisyInt(&(rC->rc_cost),s,file); } #endif /* * ---------------------------------------------------------------------------- * * irSrSet -- * * Set and display search parameter . * * Results: * None. * * Side effects: * Call low level routine of appropriate type to set/display parameter. * Value of parm can be displayed either in Magic text window (file is * NULL) or to a file. * * ---------------------------------------------------------------------------- */ /* irSrSetRate -- */ void irSrSetRate(s,file) char *s; FILE *file; { SetNoisyDI(&irMazeParms->mp_wRate,s,file); } /* irSrSetWidth -- */ void irSrSetWidth(s,file) char *s; FILE *file; { SetNoisyDI(&(irMazeParms->mp_wWidth),s,file); } /* * ---------------------------------------------------------------------------- * * irWzdSet -- * * Set and display wizard parameter . * * Results: * None. * * Side effects: * Call low level routine of appropriate type to set/display parameter. * Value of parm can be displayed either in Magic text window (file is * NULL) or to a file. * * ---------------------------------------------------------------------------- */ /* irWzdSetBloomCost -- */ void irWzdSetBloomCost(s,file) char *s; FILE *file; { SetNoisyDI(&(irMazeParms->mp_bloomDeltaCost),s,file); } /* irWzdSetBloomLimit -- */ void irWzdSetBloomLimit(s,file) char *s; FILE *file; { SetNoisyDI(&(irMazeParms->mp_bloomLimit),s,file); } /* irWzdSetBoundsIncrement -- */ void irWzdSetBoundsIncrement(s,file) char *s; FILE *file; { irSetNoisyAutoInt(&(irMazeParms->mp_boundsIncrement),s,file); } /* irWzdSetEstimate -- */ void irWzdSetEstimate(s,file) char *s; FILE *file; { SetNoisyBool(&(irMazeParms->mp_estimate),s,file); } /* irWzdSetExpandEndpoints-- */ void irWzdSetExpandEndpoints(s, file) char *s; FILE *file; { SetNoisyBool(&(irMazeParms->mp_expandEndpoints),s,file); } /* irWzdSetPenalty -- */ void irWzdSetPenalty(s, file) char *s; FILE *file; { if(s) { /* arg given, set penalty to it */ float value; if(sscanf(s,"%f",&value)==1) { irMazeParms->mp_penalty.rf_mantissa = (int) (value * (1<mp_penalty.rf_nExponent)); } else { TxError("Bad penalty value: %s\n",s); } } /* print the current penalty factor. */ if(file) { fprintf(file,"%f", (double)irMazeParms->mp_penalty.rf_mantissa / (double)(1<mp_penalty.rf_nExponent)); } else { TxPrintf("%f", (double)irMazeParms->mp_penalty.rf_mantissa / (double)(1<mp_penalty.rf_nExponent)); } return; } /* irWzdSetPenetration-- */ void irWzdSetPenetration(s, file) char *s; FILE *file; { irSetNoisyAutoInt(&(irMazeParms->mp_maxWalkLength),s,file); } /* irWzdSetWindow -- */ void irWzdSetWindow(s, file) char *s; FILE *file; { int which; int i, type; /* special arg Table */ #define SP_COMMAND -1 #define SP_DOT -2 static struct { char *sp_name; /* name */ int sp_type; } specialArgs[] = { "command", SP_COMMAND, ".", SP_DOT, 0 }; if(s!=NULL) /* set parameter */ { /* check if special arg */ which = LookupStruct( s, (char **) specialArgs, sizeof specialArgs[0]); if(which == -1) { TxError("Ambiguous argument: '%s'\n",s); TxError("Argument must 'COMMAND', '.', or a nonneg. integer\n"); return; } else if (which >= 0 ) { /* special argument */ type = specialArgs[which].sp_type; if(type == SP_COMMAND) { irRouteWid = -1; } else { ASSERT(type==SP_DOT,"wzdSetWindow"); if(irWindow==NULL) { TxError("Point to a layout window first!\n"); return; } else irRouteWid = irWindow->w_wid; } } else if(StrIsInt(s) && (i=atoi(s))>=0) { irRouteWid = i; } else { TxError("Bad argument: \"%s\"\n", s); TxError("Argument must be 'COMMAND', '.', or a nonneg. integer\n"); return; } } /* Print current value of parm */ if(file) { if(irRouteWid == -1) { fprintf(file,"COMMAND"); } else { fprintf(file,"%d",irRouteWid); } } else { if(irRouteWid == -1) { TxPrintf("COMMAND"); } else { TxPrintf("%d",irRouteWid); } } return; } /* * ---------------------------------------------------------------------------- * * irContactsCmd -- * * Irouter subcommand to set and display parameters on contacts. * * Results: * None. * * Side effects: * Modify contact parameters and display them. * * ---------------------------------------------------------------------------- */ /* Contact Parameter Table */ static struct { char *cP_name; /* name of parameter */ #ifdef MAGIC_WRAPPER Tcl_Obj *(*cP_proc)(); /* Procedure processing this parameter */ #else void (*cP_proc)(); /* Procedure processing this parameter */ #endif } cParms[] = { "active", irCSetActive, "width", irCSetWidth, "length", irCSetLength, "cost", irCSetCost, 0 }; /* NEXTVALUE - returns pointer to next value arg (string). */ #define NEXTVALUE \ ( \ (argc <= 4) ? NULL : \ (nV_i >= argc-1) ? cmd->tx_argv[nV_i=4] : cmd->tx_argv[++nV_i] \ ) void irContactsCmd(w, cmd) MagWindow *w; TxCommand *cmd; { TileType tileType; RouteContact *rC; int argc = cmd->tx_argc; int which, n; int nV_i; /* Used by NEXTVALUE, must be initialized */ bool doList = FALSE; #ifdef MAGIC_WRAPPER /* Check for "-list" option */ if (!strncmp(cmd->tx_argv[argc - 1], "-list", 5)) { doList = TRUE; argc--; } #endif nV_i = argc - 1; /* Process by case */ if(argc == 2 || (argc == 3 && (strcmp(cmd->tx_argv[2],"*")==0)) || (argc >= 4 && (strcmp(cmd->tx_argv[2],"*")==0) && (strcmp(cmd->tx_argv[3],"*")==0))) { /* PROCESS ALL PARMS FOR ALL CONTACT TYPES */ #ifdef MAGIC_WRAPPER if (doList) { Tcl_Obj *alllist, *rlist, *rname, *robj; alllist = Tcl_NewListObj(0, NULL); /* Process contact parms */ for (rC = irRouteContacts; rC != NULL; rC = rC->rc_next) { rlist = Tcl_NewListObj(0, NULL); rname = Tcl_NewStringObj( DBTypeLongNameTbl[rC->rc_routeType.rt_tileType], -1); Tcl_ListObjAppendElement(magicinterp, rlist, rname); for (n = 0; cParms[n].cP_name; n++) { robj = (*cParms[n].cP_proc)(rC, NEXTVALUE, (FILE *)1); Tcl_ListObjAppendElement(magicinterp, rlist, robj); } Tcl_ListObjAppendElement(magicinterp, alllist, rlist); } Tcl_SetObjResult(magicinterp, alllist); } else #endif { /* Print Contact Heading */ TxPrintf("%-12.12s ", "contact"); for(n=0; cParms[n].cP_name; n++) { TxPrintf("%8.8s ",cParms[n].cP_name); } TxPrintf("\n"); TxPrintf("%-12.12s ", irRepeatChar(strlen("contact"),'-')); for(n=0; cParms[n].cP_name; n++) { TxPrintf("%8.8s ",irRepeatChar(strlen(cParms[n].cP_name),'-')); } TxPrintf("\n"); /* Process contact parms */ for (rC=irRouteContacts; rC!= NULL; rC=rC->rc_next) { TxPrintf("%-12.12s ", DBTypeLongNameTbl[rC->rc_routeType.rt_tileType]); for(n=0; cParms[n].cP_name; n++) { (*cParms[n].cP_proc)(rC,NEXTVALUE,NULL); } TxPrintf("\n"); } } } else if(argc==3 || (argc >= 4 && (strcmp(cmd->tx_argv[3],"*")==0))) { /* PROCESS ALL PARMS ASSOCIATED WITH CONTACT */ /* convert layer string to tileType */ tileType = DBTechNameType(cmd->tx_argv[2]); if(tileType<0) { TxError("Unrecognized layer (type): \"%.20s\"\n", cmd->tx_argv[2]); return; } if(rC=irFindRouteContact(tileType)) { /* Print Contact Heading */ TxPrintf("%-12.12s ", "contact"); for(n=0; cParms[n].cP_name; n++) { TxPrintf("%8.8s ",cParms[n].cP_name); } TxPrintf("\n"); TxPrintf("%-12.12s ", irRepeatChar(strlen("contact"),'-')); for(n=0; cParms[n].cP_name; n++) { TxPrintf("%8.8s ",irRepeatChar(strlen(cParms[n].cP_name),'-')); } TxPrintf("\n"); /* Process contact parms */ TxPrintf("%-12.12s ", DBTypeLongNameTbl[rC->rc_routeType.rt_tileType]); for(n=0; cParms[n].cP_name; n++) { (*cParms[n].cP_proc)(rC,NEXTVALUE,NULL); } TxPrintf("\n"); } else { TxError("Unrecognized route-contact: \"%.20s\"\n", cmd->tx_argv[2]); return; } } else if(argc>=4 && strcmp(cmd->tx_argv[2],"*")==0) { /* PROCESS A COLUMN (THE VALUES OF A PARAMETER FOR ALL CONTACTS) */ /* Lookup parameter name in contact parm table */ which = LookupStruct( cmd->tx_argv[3], (char **) cParms, sizeof cParms[0]); /* Process table lookup */ if (which == -1) { /* AMBIGUOUS PARAMETER */ TxError("Ambiguous parameter: \"%s\"\n", cmd->tx_argv[3]); return; } else if (which<0) { /* PARAMETER NOT FOUND */ TxError("Unrecognized parameter: %s\n", cmd->tx_argv[3]); TxError("Valid contact parameters are: "); for (n = 0; cParms[n].cP_name; n++) TxError(" %s", cParms[n].cP_name); TxError("\n"); return; } else { /* CONTACT PARAMETER FOUND */ /* Print Heading */ TxPrintf("%-12.12s ", "contact"); TxPrintf("%8.8s ",cParms[which].cP_name); TxPrintf("\n"); TxPrintf("%-12.12s ", irRepeatChar(strlen("contact"),'-')); TxPrintf("%8.8s ", irRepeatChar(strlen(cParms[which].cP_name),'-')); TxPrintf("\n"); /* Process contact parm */ for (rC=irRouteContacts; rC!= NULL; rC=rC->rc_next) { TxPrintf("%-12.12s ", DBTypeLongNameTbl[rC->rc_routeType.rt_tileType]); (*cParms[which].cP_proc)(rC,NEXTVALUE,NULL); TxPrintf("\n"); } } } else if(argc>=4) { /* PROCESS PARAMETER ASSOCIATED WITH CONTACT */ /* convert layer string to tileType */ tileType = DBTechNameType(cmd->tx_argv[2]); if(tileType<0) { TxError("Unrecognized layer (type): \"%.20s\"\n", cmd->tx_argv[2]); return; } if(rC=irFindRouteContact(tileType)) { /* Lookup contact parameter name in table */ which = LookupStruct( cmd->tx_argv[3], (char **) cParms, sizeof cParms[0]); /* Process result of lookup */ if (which >= 0) { /* parameter found - call proc that processes it * NULL second arg means display only */ (*cParms[which].cP_proc)(rC,NEXTVALUE,NULL); TxPrintf("\n"); } else if (which == -1) { /* ambiguous parameter - complain */ TxError("Ambiguous parameter: \"%s\"\n", cmd->tx_argv[3]); return; } else { /* unrecognized parameter - complain */ TxError("Unrecognized parameter: %s\n", cmd->tx_argv[3]); TxError("Valid contact parameters are: "); for (n = 0; cParms[n].cP_name; n++) TxError(" %s", cParms[n].cP_name); TxError("\n"); return; } } else { TxError("Unrecognized route-contact: \"%.20s\"\n", cmd->tx_argv[2]); return; } } /* Give warning if number of parm values didn't come out even */ if (nV_i != argc-1) { TxError("Warning: Number of parameter values didn't match number of parameters.\n"); } return; } /* * ---------------------------------------------------------------------------- * * irHelpCmd -- * * Irouter subcommand to describe available commands. (Driven by command * table, defined above IRCommand()). * * Results: * None. * * Side effects: * Display requested help info. * * ---------------------------------------------------------------------------- */ /*ARGSUSED*/ void irHelpCmd(w, cmd) MagWindow *w; TxCommand *cmd; { int n; int which; if(cmd->tx_argc == 2) { /* No arg, so print summary of commands */ TxPrintf("\niroute - route from cursor to box\n\n"); for(n=0; irSubcommands[n].sC_name!=NULL; n++) { TxPrintf("iroute %s - %s\n", irSubcommands[n].sC_name, irSubcommands[n].sC_commentString); } TxPrintf("\niroute help "); TxPrintf(" - print usage info for subcommand.\n\n"); } else { /* Lookup subcommand in table, and printed associated help info */ which = LookupStruct( cmd->tx_argv[2], (char **) irSubcommands, sizeof irSubcommands[0]); /* Process result of lookup */ if (which >= 0) { /* subcommand found - call print out its comment string and usage */ TxPrintf("\niroute %s - %s\n", irSubcommands[which].sC_name, irSubcommands[which].sC_commentString); TxPrintf("\nusage:\niroute %s\n", irSubcommands[which].sC_usage); } else if (which == -1) { /* ambiguous subcommand - complain */ TxError("Ambiguous iroute subcommand: \"%s\"\n", cmd->tx_argv[2]); } else { /* unrecognized subcommand - complain */ TxError("Unrecognized iroute subcommand: \"%s\"\n", cmd->tx_argv[2]); TxError("Valid iroute irSubcommands are: "); for (n = 0; irSubcommands[n].sC_name; n++) TxError(" %s", irSubcommands[n].sC_name); TxError("\n"); } } return; } /* * ---------------------------------------------------------------------------- * * irLayersCmd -- * * Irouter subcommand to set and display parameters on route layers. * * Results: * None. * * Side effects: * Modify contact parameters and display them. * * ---------------------------------------------------------------------------- */ /* Layer Parameter Table */ static struct { char *lP_name; /* name of parameter */ #ifdef MAGIC_WRAPPER Tcl_Obj *(*lP_proc)(); /* procedure processing this parameter */ #else void (*lP_proc)(); /* procedure processing this parameter */ #endif } lParms[] = { "active", irLSetActive, "width", irLSetWidth, "length", irLSetLength, "hCost", irLSetHCost, "vCost", irLSetVCost, "jogCost", irLSetJogCost, "hintCost", irLSetHintCost, "overCost", irLSetOverCost, 0 }; /* NEXTVALUE - returns pointer to next value arg (string). */ #define NEXTVALUE \ ( \ (argc <= 4) ? NULL : \ (nV_i >= argc-1) ? cmd->tx_argv[nV_i=4] : cmd->tx_argv[++nV_i] \ ) /*ARGSUSED*/ void irLayersCmd(w, cmd) MagWindow *w; TxCommand *cmd; { TileType tileType; RouteLayer *rL; bool doList = FALSE; int argc = cmd->tx_argc; int which, n; int nV_i; /* Used by NEXTVALUE, must be initialized */ #ifdef MAGIC_WRAPPER /* Check for "-list" option */ if (!strncmp(cmd->tx_argv[argc - 1], "-list", 5)) { doList = TRUE; argc--; } #endif nV_i = argc - 1; /* Process by case */ if(argc == 2 || (argc == 3 && (strcmp(cmd->tx_argv[2],"*")==0)) || (argc >= 4 && (strcmp(cmd->tx_argv[2],"*")==0) && (strcmp(cmd->tx_argv[3],"*")==0))) { /* PROCESS ALL PARMS FOR ALL ROUTE LAYERS */ #ifdef MAGIC_WRAPPER if (doList) { Tcl_Obj *alllist, *rlist, *robj, *rname; alllist = Tcl_NewListObj(0, NULL); /* Process parms for each route layer */ for (rL = irRouteLayers; rL != NULL; rL = rL->rl_next) { rlist = Tcl_NewListObj(0, NULL); rname = Tcl_NewStringObj( DBTypeLongNameTbl[rL->rl_routeType.rt_tileType], -1); Tcl_ListObjAppendElement(magicinterp, rlist, rname); for (n = 0; lParms[n].lP_name; n++) { robj = (*lParms[n].lP_proc)(rL, NEXTVALUE, (FILE *)1); Tcl_ListObjAppendElement(magicinterp, rlist, robj); } Tcl_ListObjAppendElement(magicinterp, alllist, rlist); } Tcl_SetObjResult(magicinterp, alllist); } else #endif { /* Print Route Layer Heading */ TxPrintf("%-12.12s ", "layer"); for(n=0; lParms[n].lP_name; n++) { TxPrintf("%8.8s ",lParms[n].lP_name); } TxPrintf("\n"); TxPrintf("%-12.12s ", irRepeatChar(strlen("layer"),'-')); for(n=0; lParms[n].lP_name; n++) { TxPrintf("%8.8s ", irRepeatChar(strlen(lParms[n].lP_name),'-')); } TxPrintf("\n"); /* Process parms for each route layer */ for (rL=irRouteLayers; rL!= NULL; rL=rL->rl_next) { TxPrintf("%-12.12s ", DBTypeLongNameTbl[rL->rl_routeType.rt_tileType]); for(n=0; lParms[n].lP_name; n++) { (*lParms[n].lP_proc)(rL,NEXTVALUE,NULL); } TxPrintf("\n"); } } } else if(argc==3 || (argc >= 4 && (strcmp(cmd->tx_argv[3],"*")==0))) { /* PROCESS ALL PARMS ASSOCIATED WITH ROUTE LAYER */ /* convert layer string to tileType */ tileType = DBTechNameType(cmd->tx_argv[2]); if(tileType<0) { TxError("Unrecognized layer (type): \"%.20s\"\n", cmd->tx_argv[2]); return; } if (rL=irFindRouteLayer(tileType)) { /* Print Route Layer Heading */ TxPrintf("%-12.12s ", "layer"); for(n=0; lParms[n].lP_name; n++) { TxPrintf("%8.8s ",lParms[n].lP_name); } TxPrintf("\n"); TxPrintf("%-12.12s ", irRepeatChar(strlen("layer"),'-')); for(n=0; lParms[n].lP_name; n++) { TxPrintf("%8.8s ", irRepeatChar(strlen(lParms[n].lP_name),'-')); } TxPrintf("\n"); /* Process parms for route layer */ TxPrintf("%-12.12s ", DBTypeLongNameTbl[rL->rl_routeType.rt_tileType]); for(n=0; lParms[n].lP_name; n++) { (*lParms[n].lP_proc)(rL,NEXTVALUE,NULL); } TxPrintf("\n"); } else { TxError("Unrecognized route layer or contact: \"%.20s\"\n", cmd->tx_argv[2]); return; } } else if(argc>=4 && strcmp(cmd->tx_argv[2],"*")==0) { /* PROCESS A COLUMN (THE VALUES OF A PARAMETER FOR ALL LAYERS) */ /* Lookup parameter name in layer parm table */ which = LookupStruct( cmd->tx_argv[3], (char **) lParms, sizeof lParms[0]); /* Process table lookup */ if (which == -1) { /* AMBIGUOUS PARAMETER */ TxError("Ambiguous parameter: \"%s\"\n", cmd->tx_argv[3]); return; } else if (which<0) { /* PARAMETER NOT FOUND */ TxError("Unrecognized parameter: %s\n", cmd->tx_argv[3]); TxError("Valid layer parameters are: "); for (n = 0; lParms[n].lP_name; n++) TxError(" %s", lParms[n].lP_name); TxError("\n"); return; } else { /* LAYER PARAMETER FOUND */ /* Print Heading */ TxPrintf("%-12.12s ", "layer"); TxPrintf("%8.8s ",lParms[which].lP_name); TxPrintf("\n"); TxPrintf("%-12.12s ", irRepeatChar(strlen("layer"),'-')); TxPrintf("%8.8s ", irRepeatChar(strlen(lParms[which].lP_name),'-')); TxPrintf("\n"); /* Process parm for each route layer */ for (rL=irRouteLayers; rL!= NULL; rL=rL->rl_next) { TxPrintf("%-12.12s ", DBTypeLongNameTbl[rL->rl_routeType.rt_tileType]); (*lParms[which].lP_proc)(rL,NEXTVALUE,NULL); TxPrintf("\n"); } } } else if(argc>=4) { /* PROCESS PARAMETER ASSOCIATED WITH ROUTE LAYER */ /* convert layer string to tileType */ tileType = DBTechNameType(cmd->tx_argv[2]); if(tileType<0) { TxError("Unrecognized layer (type): \"%.20s\"\n", cmd->tx_argv[2]); return; } if (rL=irFindRouteLayer(tileType)) { /* Lookup route layer parameter name in table */ which = LookupStruct( cmd->tx_argv[3], (char **) lParms, sizeof lParms[0]); /* Process result of lookup */ if (which >= 0) { /* parameter found - call proc that processes it * NULL second arg means display only */ (*lParms[which].lP_proc)(rL,NEXTVALUE,NULL); TxPrintf("\n"); } else if (which == -1) { /* ambiguous parameter - complain */ TxError("Ambiguous parameter: \"%s\"\n", cmd->tx_argv[3]); return; } else { /* unrecognized parameter - complain */ TxError("Unrecognized parameter: %s\n", cmd->tx_argv[3]); TxError("Valid route layer parameters are: "); for (n = 0; lParms[n].lP_name; n++) TxError(" %s", lParms[n].lP_name); TxError("\n"); return; } } else { TxError("Unrecognized layer: \"%.20s\"\n", cmd->tx_argv[2]); return; } } /* Give warning if number of parm values didn't come out even */ if (nV_i != argc-1) { TxError("Warning: Number of parameter values didn't match number of parameters.\n"); } return; } /* * ---------------------------------------------------------------------------- * * irRouteCmd -- * * Irouter subcommand to actually do a route. * * Results: * None. * * Side effects: * Compute a route and paint it into edit cell. * * ---------------------------------------------------------------------------- */ /* Route options Table */ static char* rOptions[] = { "-dbox", /* 0 */ "-dlabel", /* 1 */ "-dlayers", /* 2 */ "-drect", /* 3 */ "-dselection",/* 4 */ "-scursor", /* 5 */ "-slabel", /* 6 */ "-slayers", /* 7 */ "-spoint", /* 8 */ #ifdef MAGIC_WRAPPER "-timeout", /* 9 */ #endif NULL }; void irRouteCmd(w, cmd) MagWindow *w; TxCommand *cmd; { Point *startPtArg = NULL; /* pts to start point, if given on command */ Rect *destRectArg = NULL; /* pts to dest rect, if given on command */ char *startLabel = NULL; /* pts to labelname, if given on command */ char *destLabel = NULL; /* pts to labelname, if given on command */ List *startLayers = NULL; List *destLayers = NULL; int startType; /* type of start specifier */ int destType; /* type of destination specifier */ Point startPt; Rect destRect; int irResult = MZ_NO_ACTION; int i; /* index of arg being processed */ int argc = cmd->tx_argc; char **argv = cmd->tx_argv; TileTypeBitMask layerMask; RouteLayer *rL; /* set startType and destType to defaults */ startType = ST_CURSOR; destType = DT_BOX; /* skip over cmd name args */ i = 2; /* process options */ while(i=argc) { TxError("Missing label.\n"); goto leaveClean; } destLabel = argv[i]; break; case 2: /* dLayers */ if(++i>=argc) { TxError("Missing layer list.\n"); goto leaveClean; } (void) CmdParseLayers(argv[i],&layerMask); for(rL=irRouteLayers; rL!=NULL; rL=rL->rl_next) { if(TTMaskHasType(&layerMask,rL->rl_routeType.rt_tileType) && rL->rl_routeType.rt_active) { LIST_ADD(rL, destLayers); } } if(destLayers==NULL) { TxError("No active route layers in destination list!\n"); goto leaveClean; } break; case 3: /* dRect */ destType = DT_RECT; if(++i>=argc) { TxError("Incomplete coordinates.\n"); goto leaveClean; } if(!StrIsNumeric(argv[i])) { TxError("Non coordinate: %s\n",argv[i]); goto leaveClean; } destRect.r_xbot = cmdParseCoord(w, argv[i], FALSE, TRUE); if(++i>=argc) { TxError("Incomplete coordinates.\n"); goto leaveClean; } if(!StrIsNumeric(argv[i])) { TxError("Nonnumeric coordinate: %s\n",argv[i]); goto leaveClean; } destRect.r_ybot = cmdParseCoord(w, argv[i], FALSE, FALSE); if(++i>=argc) { TxError("Incomplete coordinates.\n"); goto leaveClean; } if(!StrIsNumeric(argv[i])) { TxError("Nonnumeric coordinate: %s\n",argv[i]); goto leaveClean; } destRect.r_xtop = cmdParseCoord(w, argv[i], FALSE, TRUE); if(++i>=argc) { TxError("Incomplete coordinates.\n"); goto leaveClean; } if(!StrIsNumeric(argv[i])) { TxError("Nonnumeric coordinate: %s\n",argv[i]); goto leaveClean; } destRect.r_ytop = cmdParseCoord(w, argv[i], FALSE, FALSE); destRectArg = &destRect; break; case 4: /* dSelection */ destType = DT_SELECTION; break; case 5: /* sCursor */ startType = ST_CURSOR; break; case 6: /* sLabel */ startType = ST_LABEL; if(++i>=argc) { TxError("Missing label.\n"); goto leaveClean; } startLabel = argv[i]; break; case 7: /* sLayers */ if(++i>=argc) { TxError("Missing layer list.\n"); goto leaveClean; } (void) CmdParseLayers(argv[i],&layerMask); for(rL=irRouteLayers; rL!=NULL; rL=rL->rl_next) { if(TTMaskHasType(&layerMask, rL->rl_routeType.rt_tileType) && rL->rl_routeType.rt_active) { LIST_ADD(rL, startLayers); } } if(startLayers==NULL) { TxError("No active route layers in start list!\n"); goto leaveClean; } break; case 8: /* sPoint */ startType = ST_POINT; if(++i>=argc) { TxError("Incomplete coordinates.\n"); goto leaveClean; } if(!StrIsNumeric(argv[i])) { TxError("Nonnumeric coordinate: %s\n",argv[i]); goto leaveClean; } startPt.p_x = cmdParseCoord(w, argv[i], FALSE, TRUE); if(++i>=argc) { TxError("Incomplete coordinates.\n"); goto leaveClean; } if(!StrIsNumeric(argv[i])) { TxError("Nonnumeric coordinate: %s\n",argv[i]); goto leaveClean; } startPt.p_y = cmdParseCoord(w, argv[i], FALSE, FALSE); startPtArg = &startPt; break; #ifdef MAGIC_WRAPPER case 9: if(++i>=argc) { TxError("No timeout value given.\n"); goto leaveClean; } if(!StrIsInt(argv[i])) { TxError("Noninteger timeout value: %s\n",argv[i]); goto leaveClean; } SigRemoveTimer(); SigTimerInterrupts(); SigSetTimer(atoi(argv[i])); break; #endif default: /* shouldn't happen */ ASSERT(FALSE,"irRouteCmd"); break; } /* advance to next option */ ++i; } /* We're done parsing the command, call irRoute to do the real work */ irResult = irRoute(w, startType, startPtArg, startLabel, startLayers, destType, destRectArg, destLabel, destLayers); #ifdef MAGIC_WRAPPER SigTimerDisplay(); /* Set Tcl Result to irResult */ switch (irResult) { case MZ_SUCCESS: Tcl_SetResult(magicinterp, "Route success", 0); break; case MZ_CURRENT_BEST: Tcl_SetResult(magicinterp, "Route best before interrupt", 0); break; case MZ_FAILURE: Tcl_SetResult(magicinterp, "Route failure", 0); break; case MZ_UNROUTABLE: Tcl_SetResult(magicinterp, "Route unroutable", 0); break; case MZ_INTERRUPTED: Tcl_SetResult(magicinterp, "Route interrupted", 0); break; case MZ_ALREADY_ROUTED: Tcl_SetResult(magicinterp, "Route already routed", 0); break; } #endif leaveClean: ListDealloc(startLayers); ListDealloc(destLayers); return; } /* * ---------------------------------------------------------------------------- * * irSearchCmd -- * * Irouter subcommand to set and display search parameters. * * Results: * None. * * Side effects: * Modify search parameters and display them. * * ---------------------------------------------------------------------------- */ /* Search Parameter Table */ static struct { char *srP_name; /* name of parameter */ void (*srP_proc)(); /* Procedure processing this parameter */ } srParms[] = { "rate", irSrSetRate, "width", irSrSetWidth, 0 }; void irSearchCmd(w, cmd) MagWindow *w; TxCommand *cmd; { /* Process by case */ if(cmd->tx_argc == 2) /* print values of all parms */ { int n; for(n=0; srParms[n].srP_name; n++) { TxPrintf(" %s=", srParms[n].srP_name); (*srParms[n].srP_proc)(NULL,NULL); } TxPrintf("\n"); } else if(cmd->tx_argc == 3 || cmd->tx_argc == 4) /* process single parameter */ { int which; /* Lookup parameter name in contact parm table */ which = LookupStruct( cmd->tx_argv[2], (char **) srParms, sizeof srParms[0]); /* Process table lookup */ if (which == -1) /* parameter ambiguous */ { TxError("Ambiguous parameter: \"%s\"\n", cmd->tx_argv[2]); return; } else if (which<0) /* parameter not found */ { int n; TxError("Unrecognized parameter: %s\n", cmd->tx_argv[2]); TxError("Valid search parameters are: "); for (n = 0; srParms[n].srP_name; n++) TxError(" %s", srParms[n].srP_name); TxError("\n"); return; } else /* parameter found - process it */ { char *arg; if(cmd->tx_argc == 3) /* just want current value - use null argument */ { arg = NULL; } else /* setting parameter, arg = value string */ { arg = cmd->tx_argv[3]; } TxPrintf(" %s=", srParms[which].srP_name); (*srParms[which].srP_proc)(arg,NULL); TxPrintf("\n"); } } else /* Too many arguments */ { TxError("Too many args on 'iroute search'\n"); } return; } /* * ---------------------------------------------------------------------------- * * irSpacingsCmd -- * * Irouter subcommand to set and display minimum spacings between * routetypes. * * * Results: * None. * * Side effects: * Modify and display spacing parameters. * * ---------------------------------------------------------------------------- */ void irSpacingsCmd(w, cmd) MagWindow *w; TxCommand *cmd; { TileType tileType; RouteType *rT; char *s; int which, value, argI, i, n; /* Special Value Table */ static struct { char *sV_name; /* name of value */ int sV_value; /* corresponding interger value */ } sValue[] = { "n", -1, "nil", -1, "none", -1, "null", -1, 0 }; /* Subcell Table */ static struct { char *sT_name; /* name of value */ int sT_value; /* corresponding interger value */ } subcellTable[] = { "subcell", TT_SUBCELL, 0 }; /* Process by case */ if(cmd->tx_argc == 2) { /* NO ARGS TO SPACING REQUEST - DISPLAY ALL SPACINGS */ /* Print spacings for each route type */ for (rT=irRouteTypes; rT!= NULL; rT=rT->rt_next) { TxPrintf("%s: ", DBTypeLongNameTbl[rT->rt_tileType]); for (i=0;irt_spacing[i]>=0) TxPrintf("%s=%d ",DBTypeLongNameTbl[i],rT->rt_spacing[i]); if(rT->rt_spacing[TT_SUBCELL]>=0) TxPrintf("%s=%d ","SUBCELL",rT->rt_spacing[TT_SUBCELL]); TxPrintf("\n\n"); } } else if(cmd->tx_argc==3) { /* ONE ARG TO SPACING REQUEST */ if (strcmp(cmd->tx_argv[2],"CLEAR")==0) { /* CLEAR ALL SPACINGS */ for (rT=irRouteTypes; rT!= NULL; rT=rT->rt_next) /* <=TT_MAXTYPES below includes TT_SUBCELL */ for (i=0;i<=TT_MAXTYPES;i++) rT->rt_spacing[i]= -1; } else { /* PRINT SPACINGS FOR GIVEN ROUTE LAYER */ /* convert layer string to tileType */ tileType = DBTechNameType(cmd->tx_argv[2]); if(tileType<0) { TxError("Unrecognized layer (type): \"%.20s\"\n", cmd->tx_argv[2]); return; } if (rT=irFindRouteType(tileType)) { TxPrintf("%s: ", DBTypeLongNameTbl[rT->rt_tileType]); for (i=0;irt_spacing[i]>=0) TxPrintf("%s=%d ", DBTypeLongNameTbl[i],rT->rt_spacing[i]); if(rT->rt_spacing[TT_SUBCELL]>=0) TxPrintf("%s=%d ","SUBCELL",rT->rt_spacing[TT_SUBCELL]); TxPrintf("\n\n"); } else { TxError("Unrecognized route layer or contact: \"%.20s\"\n", cmd->tx_argv[2]); return; } } } else if(cmd->tx_argc==4) { /* PRINT VALUE OF GIVEN SPACING */ /* convert layer string to tileType */ tileType = DBTechNameType(cmd->tx_argv[2]); if(tileType<0) { TxError("Unrecognized layer (type): \"%.20s\"\n", cmd->tx_argv[2]); return; } if ((rT=irFindRouteType(tileType))==NULL) { TxError("Unrecognized route layer or contact: \"%.20s\"\n", cmd->tx_argv[2]); return; } /* convert type-string spacing is "to" to tiletype */ tileType = DBTechNameType(cmd->tx_argv[3]); if(tileType<0) { /* if not a real type, check to see if "SUBCELL" */ which = LookupStruct( cmd->tx_argv[3], (char **) subcellTable, sizeof subcellTable[0]); if ( which>= 0) tileType = TT_SUBCELL; } if(tileType<0) { TxError("Unrecognized layer (type): \"%.20s\"\n", cmd->tx_argv[3]); return; } /* Print current value of spacing */ if(rT->rt_spacing[tileType] >= 0) TxPrintf("\t%d\n",rT->rt_spacing[tileType]); else TxPrintf("\tNIL\n"); } else if(EVEN(cmd->tx_argc)) { /* TYPE PARMS DON'T PAIR EVENLY WITH VALUE PARMS */ TxError("Type and value args don't pair evenly.\n"); TxError("Usage: *iroute spacing [routeType] [type1] [value1] [type2 value2] ... [typen valuen]\n"); } else { /* SET SPACINGS */ /* convert layer string to tileType */ tileType = DBTechNameType(cmd->tx_argv[2]); if(tileType<0) { TxError("Unrecognized layer (type): \"%.20s\"\n", cmd->tx_argv[2]); return; } if ((rT=irFindRouteType(tileType))==NULL) { TxError("Unrecognized route layer or contact: \"%.20s\"\n", cmd->tx_argv[2]); return; } /* Prepend tab to echo of new values */ TxPrintf("\t"); /* process type/value pairs */ for (argI=3; argItx_argc; argI +=2) { /* convert type-string spacing is "to" to tiletype */ tileType = DBTechNameType(cmd->tx_argv[argI]); if(tileType<0) { /* if not a real type, check to see if "SUBCELL" */ which = LookupStruct( cmd->tx_argv[argI], (char **) subcellTable, sizeof subcellTable[0]); if ( which>= 0) tileType = TT_SUBCELL; } if(tileType<0) { TxError("\nUnrecognized layer (type): \"%.20s\"\n", cmd->tx_argv[argI]); continue; } /* convert value-string to integer */ s = cmd->tx_argv[argI+1]; if (StrIsNumeric(s)) { value = cmdParseCoord(w, s, TRUE, FALSE); if (value < -1) { TxError("\nBad spacing value: %d\n",value); TxError("Valid spacing values are: "); TxError(" -1"); for (n = 0; sValue[n].sV_name; n++) TxError(" %s", sValue[n].sV_name); TxError("\n"); return; } } else { /* Lookup in special value table */ which = LookupStruct( s, (char **) sValue, sizeof sValue[0]); /* Process result of lookup */ if (which >= 0) { /* special value found, set string accordingly */ value = sValue[which].sV_value; } else if (which == -1) { /* ambiguous value - complain */ TxError("\nAmbiguous value: \"%s\"\n",s); continue; } else { /* unrecognized value - complain */ TxError("Bad spacing value: %s\n",s); TxError("Valid spacing values are: "); TxError(" -1"); for (n = 0; sValue[n].sV_name; n++) TxError(" %s", sValue[n].sV_name); TxError("\n"); continue; } } /* Set value in route type */ rT->rt_spacing[tileType]=value; /* Print new value */ if(rT->rt_spacing[tileType] != -1) TxPrintf(" %s=%d", (tileType == TT_SUBCELL ? "SUBCELL" : DBTypeLongNameTbl[tileType]), rT->rt_spacing[tileType]); else TxPrintf(" %s=NIL", (tileType==TT_SUBCELL ? "SUBCELL" : DBTypeLongNameTbl[tileType])); } TxPrintf("\n"); } return; } /* * ---------------------------------------------------------------------------- * * irVerbosityCmd -- * * Irouter subcommand to set amount of messages given by irouter and mzrouter. * * Results: * None. * * Side effects: * Sets verbosity parameter * * ---------------------------------------------------------------------------- */ void irVerbosityCmd(w, cmd) MagWindow *w; TxCommand *cmd; { if(cmd->tx_argc >3) { TxError("'iroute verbosity' only takes one arg!\n"); return; } if(cmd->tx_argc == 3) { int i; /* ONE ARG */ if(StrIsInt(cmd->tx_argv[2]) && (i=atoi(cmd->tx_argv[2]))>=0) { irMazeParms->mp_verbosity = i; } else { TxError("Bad argument: \"%s\"\n", cmd->tx_argv[2]); TxError("Argument must be a nonnegative integer\n"); return; } } /* Print current value of verbosity */ switch (irMazeParms->mp_verbosity) { case 0: /* shhhhh! we're in silent mode */ break; case 1: TxPrintf("\t1 (Brief messages)\n"); break; default: ASSERT(irMazeParms->mp_verbosity>=2,"irVerbosityCmd"); TxPrintf("\t%d (Lots of statistics)\n", irMazeParms->mp_verbosity); } return; } /* * ---------------------------------------------------------------------------- * * irVersionCmd -- * * Irouter subcommand to display irouter version string. * * Results: * None. * * Side effects: * Displays version string. * * ---------------------------------------------------------------------------- */ void irVersionCmd(w, cmd) MagWindow *w; TxCommand *cmd; { if(cmd->tx_argc == 2) { /* Print out version string */ TxPrintf("\tIrouter version %s\n", IROUTER_VERSION); } else { TxError("Too many args on 'iroute version'\n"); } return; } /* * ---------------------------------------------------------------------------- * * irWizardCmd -- * * Irouter subcommand to set and display less frequently modified parameters. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ /* Wizard Parameter Table */ static struct { char *wzdP_name; /* name of parameter */ void (*wzdP_proc)(); /* Procedure processing this parameter */ } wzdParms[] = { "bloom", irWzdSetBloomCost, "bloomLimit", irWzdSetBloomLimit, "boundsIncrement", irWzdSetBoundsIncrement, "estimate", irWzdSetEstimate, "expandEndpoints", irWzdSetExpandEndpoints, "penalty", irWzdSetPenalty, "penetration", irWzdSetPenetration, "window", irWzdSetWindow, 0 }; void irWizardCmd(w, cmd) MagWindow *w; TxCommand *cmd; { /* Process by case */ if(cmd->tx_argc == 2) /* print values of all parms */ { int n; for(n=0; wzdParms[n].wzdP_name; n++) { TxPrintf(" %s=", wzdParms[n].wzdP_name); (*wzdParms[n].wzdP_proc)(NULL,NULL); TxPrintf("\n"); } } else if(cmd->tx_argc == 3 || cmd->tx_argc == 4) /* process single parameter */ { int which; /* Lookup parameter name in contact parm table */ which = LookupStruct( cmd->tx_argv[2], (char **) wzdParms, sizeof wzdParms[0]); /* Process table lookup */ if (which == -1) /* parameter ambiguous */ { TxError("Ambiguous parameter: \"%s\"\n", cmd->tx_argv[2]); return; } else if (which<0) /* parameter not found */ { int n; TxError("Unrecognized parameter: %s\n", cmd->tx_argv[2]); TxError("Valid wizard parameters are: "); for (n = 0; wzdParms[n].wzdP_name; n++) TxError(" %s", wzdParms[n].wzdP_name); TxError("\n"); return; } else /* parameter found - process it */ { char *arg; if(cmd->tx_argc == 3) /* just want current value - use null argument */ { arg = NULL; } else /* setting parameter, arg = value string */ { arg = cmd->tx_argv[3]; } TxPrintf(" %s=", wzdParms[which].wzdP_name); (*wzdParms[which].wzdP_proc)(arg,NULL); TxPrintf("\n"); } } else /* Too many arguments */ { TxError("Too many args on 'iroute wizard'\n"); } return; } /* * ---------------------------------------------------------------------------- * * irSaveParametersCmd -- * * Irouter subcommand to create "source" file setting all irouter parameters * (except ref. window) to current value - to reset to these values just * source the file with `:source'. * * Results: * None. * * Side effects: * Write file of Magic commands to set parms. to current values. * * NOTE: * Note defined after all other commands, so it can make use of * datastructures defined just in front of other commands, * such as the search parameter table. * ---------------------------------------------------------------------------- */ void irSaveParametersCmd(w, cmd) MagWindow *w; TxCommand *cmd; { FILE *saveFile; RouteContact *rC; RouteLayer *rL; /* make sure exactly one arg given */ if(cmd->tx_argc !=3) { if(cmd->tx_argc == 2) TxError("Must specify save file!\n"); else TxError("Too many args on ':iroute saveParameter'\n"); return; } /* open save file */ saveFile = fopen(cmd->tx_argv[2], "w"); if (saveFile == NULL) { TxError("Could not open file '%s' for writing.\n", cmd->tx_argv[2]); return; } /* write header comment */ fprintf(saveFile,"# Irouter version %s\n", IROUTER_VERSION); fprintf(saveFile,"#\n"); fprintf(saveFile, "# This is a Magic command file generated by the Magic command\n"); fprintf(saveFile,"#\t:iroute saveParameters\n"); fprintf(saveFile,"# To restore these parameter settings,"); fprintf(saveFile," use the Magic `:source' command.\n\n"); /* turn verbosity down to errors and warnings, to avoid lots of * gibberish when the file is sourced. */ fprintf(saveFile,":iroute verbosity 0\n"); /* save CONTACT parameters */ for (rC=irRouteContacts; rC!= NULL; rC=rC->rc_next) { int n; fprintf(saveFile,":iroute contact %s * ", DBTypeLongNameTbl[rC->rc_routeType.rt_tileType]); for(n=0; cParms[n].cP_name; n++) { (*cParms[n].cP_proc)(rC,NULL,saveFile); } fprintf(saveFile,"\n"); } /* save LAYER paramters */ for (rL=irRouteLayers; rL!= NULL; rL=rL->rl_next) { int n; fprintf(saveFile,":iroute layer %s * ", DBTypeLongNameTbl[rL->rl_routeType.rt_tileType]); for(n=0; lParms[n].lP_name; n++) { (*lParms[n].lP_proc)(rL,NULL,saveFile); } fprintf(saveFile,"\n"); } /* save SEARCH parameters */ { int n; for(n=0; srParms[n].srP_name; n++) { fprintf(saveFile,":iroute search %s ", srParms[n].srP_name); (*srParms[n].srP_proc)(NULL,saveFile); fprintf(saveFile,"\n"); } } /* save SPACINGS */ { RouteType *rT; int i; fprintf(saveFile,":iroute spacings CLEAR\n"); for (rT=irRouteTypes; rT!= NULL; rT=rT->rt_next) { for (i=0;irt_spacing[i]>=0) fprintf(saveFile,":iroute spacings %s %s %d\n", DBTypeLongNameTbl[rT->rt_tileType], DBTypeLongNameTbl[i], rT->rt_spacing[i]); if(rT->rt_spacing[TT_SUBCELL]>=0) fprintf(saveFile,":iroute spacings %s %s %d\n", DBTypeLongNameTbl[rT->rt_tileType], "SUBCELL", rT->rt_spacing[TT_SUBCELL]); } } /* save WIZARD parameters */ { int n; for(n=0; wzdParms[n].wzdP_name; n++) { fprintf(saveFile,":iroute wizard %s ", wzdParms[n].wzdP_name); (*wzdParms[n].wzdP_proc)(NULL,saveFile); fprintf(saveFile,"\n"); } } /* save VERBOSITY parameter (done last so :source is silent) */ fprintf(saveFile,":iroute verbosity %d\n", irMazeParms->mp_verbosity); (void) fclose(saveFile); return; } /* * ---------------------------------------------------------------------------- * * IRCommand -- * * Command interface for interactive router. Processes `:iroute' command * lines. * * Results: * None. * * Side effects: * Depends on the command; see below. * * Organization: * We select a procedure based on the first keyword (argv[0]) * and call it to do the work of implementing the subcommand. Each * such procedure is of the following form: * * int * proc(argc, argv) * int argc; * char *argv[]; * { * } * * ---------------------------------------------------------------------------- */ /*--- Subcommand Table ---*/ SubCmdTableE irSubcommands[] = { "contacts", irContactsCmd, "set route-contact parameters", "contacts [type] [parameter] [value1] ... [valuen]\n\ \t(can use '*' for type or parameter)", "help", irHelpCmd, "summarize iroute subcommands", "help [subcommand]", "layers", irLayersCmd, "set route-layer parameters", "layers [type] [parameter] [value1] ... [valuen]\n\ \t(can use '*' for type or parameter)", "route", irRouteCmd, "connect point to node(s)", "route [options]\n\ \t-sLayers layers = layers route may start on.\n\ \t-sCursor = start route at cursor (DEFAULT)\n\ \t-sLabel name = start route at label of given name\n\ \t-sPoint x y = start route at given coordinates\n\ \t-dLayers layers = layers route may end on.\n\ \t-dBox = route to box (DEFAULT)\n\ \t-dLabel name = route to label of given name\n\ \t-dRect xbot ybot xtop ytop = route to rectangle of given coordinates\n\ \t-dSelection = route to selection", "saveParameters", irSaveParametersCmd, "write out all irouter parameters\n\ \t(can be read back with :source)", "saveParameters ", "search", irSearchCmd, "set parameters controlling the internal search for routes", "search [searchParameter] [value]", "spacings", irSpacingsCmd, "set minimum spacing between route-type and arbitrary type", "spacings [route-type] [type] [spacing] ... [typen spacingn]\n\ \t(types can be 'SUBCELL', spacing can be 'nil')\n\ iroute spacings CLEAR\n\ \t(sets all spacings to nil)", "verbosity", irVerbosityCmd, "control the amount of messages printed", "verbosity [level]\n\ \t(0 = errors and warnings only, 1 = brief, 2 = lots of statistics)", "version", irVersionCmd, "identify irouter version", "version", "wizard", irWizardCmd, "set miscellaneous parameters", "wizard [wizardParameter] [value]", 0 }, *subCmdP; void IRCommand(w, cmd) MagWindow *w; TxCommand *cmd; { int n; int which; /* make sure we have maze parameters */ if(irMazeParms==NULL) { TxError("Need irouter style in mzrouter section of technology file"); TxError(" to use irouter.\n"); return; } /* make window available to all subroutines */ irWindow = w; /* If in silent mode, turn printing off */ if(irMazeParms->mp_verbosity==0) { TxPrintOff(); } if(cmd->tx_argc == 1) { int irResult; /* No subcommand specified - so just route from cursor to box * No endpts or layers explicitly given on cmd, so args are * NULL below. */ irResult = irRoute(w, ST_CURSOR, (Point*)NULL, (char*)NULL, (List*)NULL, DT_BOX, (Point*)NULL, (char*)NULL, (List*)NULL); #ifdef MAGIC_WRAPPER /* Set Tcl Result to irResult */ switch (irResult) { case MZ_SUCCESS: Tcl_SetResult(magicinterp, "Route success", 0); break; case MZ_CURRENT_BEST: Tcl_SetResult(magicinterp, "Route best before interrupt", 0); break; case MZ_FAILURE: Tcl_SetResult(magicinterp, "Route failure", 0); break; case MZ_UNROUTABLE: Tcl_SetResult(magicinterp, "Route unroutable", 0); break; case MZ_INTERRUPTED: Tcl_SetResult(magicinterp, "Route interrupted", 0); break; case MZ_ALREADY_ROUTED: Tcl_SetResult(magicinterp, "Route already routed", 0); break; } #endif } else { /* Lookup subcommand in table */ which = LookupStruct( cmd->tx_argv[1], (char **) irSubcommands, sizeof irSubcommands[0]); /* Process result of lookup */ if (which >= 0) { /* subcommand found - call proc that implements it */ subCmdP = &irSubcommands[which]; (*subCmdP->sC_proc)(w,cmd); } else if (which == -1) { /* ambiguous subcommand - complain */ TxError("Ambiguous iroute subcommand: \"%s\"\n", cmd->tx_argv[1]); } else { /* unrecognized subcommand - complain */ TxError("Unrecognized iroute subcommand: \"%s\"\n", cmd->tx_argv[1]); TxError("Valid iroute irSubcommands are: "); for (n = 0; irSubcommands[n].sC_name; n++) TxError(" %s", irSubcommands[n].sC_name); TxError("\n"); } } /* turn printing back on, and return */ TxPrintOn(); return; } magic-8.0.210/irouter/Makefile0000644000175000001440000000040710751423606014610 0ustar timusers# # rcsid $Header: /usr/cvsroot/magic-8.0/irouter/Makefile,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ # MODULE = irouter MAGICDIR = .. SRCS = irCommand.c irMain.c irRoute.c irTestCmd.c irUtils.c include ${MAGICDIR}/defs.mak include ${MAGICDIR}/rules.mak magic-8.0.210/irouter/irTestCmd.c0000644000175000001440000001643010751423606015215 0ustar timusers/* * irTestCmd.c -- * * Code to process the `*iroute' command. * `*iroute' is a wizard command for debugging and testing. * * ********************************************************************* * * Copyright (C) 1987, 1990 Michael H. Arnold, Walter S. Scott, and * * * the 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/irouter/irTestCmd.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/hash.h" #include "tiles/tile.h" #include "database/database.h" #include "utils/signals.h" #include "textio/textio.h" #include "irouter/irouter.h" #include "graphics/graphics.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "dbwind/dbwtech.h" #include "textio/txcommands.h" #include "utils/main.h" #include "utils/utils.h" #include "commands/commands.h" #include "utils/styles.h" #include "utils/malloc.h" #include "utils/list.h" #include "../mzrouter/mzrouter.h" #include "irouter/irInternal.h" /* Subcommand table - declared here since its referenced before defined */ typedef struct { char *sC_name; /* name of iroute subcommand */ void (*sC_proc)(); /* Procedure implementing this subcommand */ char *sC_commentString; char *sC_usage; } TestCmdTableE; extern TestCmdTableE irTestCommands[]; /* * ---------------------------------------------------------------------------- * * irDebugTstCmd -- * * irouter wizard command (`:*iroute') to set/clear debug flags. * * Results: * None. * * Side effects: * Modify debug flags. * * ---------------------------------------------------------------------------- */ void irDebugTstCmd(w, cmd) MagWindow *w; TxCommand *cmd; { int result; bool value; if (cmd->tx_argc > 4) { TxPrintf("Too many args on '*iroute debug'\n"); return; } else if (cmd->tx_argc == 4) { /* two args, set or clear first arg according to second */ result = SetNoisyBool(&value,cmd->tx_argv[3], (FILE *) NULL); if (result == 0) { TxPrintf("\n"); DebugSet(irDebugID,1,&(cmd->tx_argv[2]),(bool) value); } else TxError("Unknown boolean value %s\n", cmd->tx_argv[2]); } else { /* list current values of flags */ DebugShow(irDebugID); } return; } /* * ---------------------------------------------------------------------------- * * irHelpTstCmd -- * * irouter wizard command (`:*iroute') to print help info on irouter wizard * commands. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void irHelpTstCmd(w, cmd) MagWindow *w; TxCommand *cmd; { int n; int which; if(cmd->tx_argc == 2) { /* No arg, so print summary of commands */ for(n=0; irTestCommands[n].sC_name!=NULL; n++) { TxPrintf("*iroute %s - %s\n", irTestCommands[n].sC_name, irTestCommands[n].sC_commentString); } TxPrintf("\n*iroute help [subcmd] - "); TxPrintf("Print usage info for subcommand.\n"); } else { /* Lookup subcommand in table, and printed associated help info */ which = LookupStruct( cmd->tx_argv[2], (char **) irTestCommands, sizeof irTestCommands[0]); /* Process result of lookup */ if (which >= 0) { /* subcommand found - print out its comment string and usage */ TxPrintf("*iroute %s - %s\n", irTestCommands[which].sC_name, irTestCommands[which].sC_commentString); TxPrintf("Usage: *iroute %s\n", irTestCommands[which].sC_usage); } else if (which == -1) { /* ambiguous subcommand - complain */ TxError("Ambiguous *iroute subcommand: \"%s\"\n", cmd->tx_argv[2]); } else { /* unrecognized subcommand - complain */ TxError("Unrecognized iroute subcommand: \"%s\"\n", cmd->tx_argv[2]); TxError("Valid *iroute subcommands are: "); for (n = 0; irTestCommands[n].sC_name; n++) TxError(" %s", irTestCommands[n].sC_name); TxError("\n"); } } return; } /* * ---------------------------------------------------------------------------- * * irParmsTstCmd -- * * irouter wizard command (`:*iroute') to dump parms. * commands. * * Results: * None. * * Side effects: * Dump routelayers and routecontacts. * * ---------------------------------------------------------------------------- */ void irParmsTstCmd(w, cmd) MagWindow *w; TxCommand *cmd; { MZPrintRLs(irRouteLayers); TxMore(""); MZPrintRCs(irRouteContacts); return; } /*--------------------------- Command Table ------------------------------ */ TestCmdTableE irTestCommands[] = { "debug", irDebugTstCmd, "set or clear debug flags", "debug [flag] [value]", "help", irHelpTstCmd, "summarize *iroute subcommands", "help [subcommand]", "parms", irParmsTstCmd, "print internal data structures", "parms", 0 }, *irTestCmdP; /* * ---------------------------------------------------------------------------- * * IRTest -- * * Command interface for testing the interactive router. * * Results: * None. * * Side effects: * Depends on the command; see below. * * Organization: * We select a procedure based on the first keyword (argv[0]) * and call it to do the work of implementing the rule. Each * such procedure is of the following form: * * int * proc(argc, argv) * int argc; * char *argv[]; * { * } * * ---------------------------------------------------------------------------- */ void IRTest(w, cmd) MagWindow *w; TxCommand *cmd; { int n; int which; if(cmd->tx_argc == 1) { /* No subcommand specified. */ TxPrintf("Must specify subcommand."); TxPrintf(" (type '*iroute help' for summary)\n"); } else { /* Lookup subcommand in table */ which = LookupStruct( cmd->tx_argv[1], (char **) irTestCommands, sizeof irTestCommands[0]); /* Process result of lookup */ if (which >= 0) { /* subcommand found - call proc that implements it */ irTestCmdP = &irTestCommands[which]; (*irTestCmdP->sC_proc)(w,cmd); } else if (which == -1) { /* ambiguous subcommand - complain */ TxError("Ambiguous subcommand: \"%s\"\n", cmd->tx_argv[1]); } else { /* unrecognized subcommand - complain */ TxError("Unrecognized subcommand: \"%s\"\n", cmd->tx_argv[1]); TxError("Valid subcommands:"); for (n = 0; irTestCommands[n].sC_name; n++) TxError(" %s", irTestCommands[n].sC_name); TxError("\n"); } } return; } magic-8.0.210/irouter/irouter.h0000644000175000001440000000325510751423606015016 0ustar timusers/* * irouter.h -- * * This file defines the interface provided by the interactive router * module, which is the top-level module that controls interactive * routing. * * ********************************************************************* * * Copyright (C) 1987, 1990 Michael H. Arnold, Walter S. Scott, and * * * the 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. * * ********************************************************************* * * rcsid $Header: /usr/cvsroot/magic-8.0/irouter/irouter.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ */ #ifndef _IROUTER_H #define _IROUTER_H #include "utils/magic.h" /* * Interface procedures. */ extern void IRDebugInit(); extern void IRTest(); extern void IRButtonProc(); extern void IRAfterTech(); /* * Technology file client procedures. * The sections should be processed in the order * listed below. */ /* "irouter" section */ extern void IRTechInit(); extern bool IRTechLine(); /* "drc" section */ extern void IRDRCInit(); extern bool IRDRCLine(); #endif /* _IROUTER_H */ magic-8.0.210/irouter/irRoute.c0000644000175000001440000007056111120112370014735 0ustar timusers/* * irRoute.c -- * * Sets up route and calls maze router to do it. * * ********************************************************************* * * Copyright (C) 1987, 1990 Michael H. Arnold, Walter S. Scott, and * * * the 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/irouter/irRoute.c,v 1.3 2008/12/11 04:20:08 tim Exp $"; #endif /* not lint */ /* --- Includes --- */ #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/hash.h" #include "tiles/tile.h" #include "database/database.h" #include "drc/drc.h" #include "textio/textio.h" #include "windows/windows.h" #include "utils/main.h" #include "dbwind/dbwind.h" #include "debug/debug.h" #include "utils/undo.h" #include "utils/signals.h" #include "utils/malloc.h" #include "utils/list.h" #include "utils/geofast.h" #include "utils/touchingtypes.h" #include "select/select.h" #include "../mzrouter/mzrouter.h" #include "irouter/irouter.h" #include "irouter/irInternal.h" /* --- Routines local to this file that are referenced before they are * defined --- */ List *irChooseEndPtLayers(); /* -------------------- Structures Local to this File -------------------- */ /* clientdata structure passed to filter functions when searching for * start and destination labels. */ typedef struct labelSearchData { Rect lsd_locRect; /* set to labels location by filter func */ char *lsd_name; /* label name to search for */ TileType lsd_type; /* layer that label is attached to */ int lsd_result; /* code giving result of search */ } LabelSearchData; /* result codes for lsd_result above */ #define LSR_NOTFOUND 10 #define LSR_NOTUNIQUE 20 #define LSR_FOUND 30 /* * ---------------------------------------------------------------------------- * * irRoute -- * * Top level procedure for the routing code. Initializes things, and * calls the maze router to make a connection. * * Results: * Passes back the result code of MZRoute() (see mzrouter.h for codes) * * Side effects: * Paint route into editcell. * * ---------------------------------------------------------------------------- */ int irRoute(cmdWindow, startType, argStartPt, argStartLabel, argStartLayers, destType, argDestRect, argDestLabel, argDestLayers) MagWindow *cmdWindow; /* window route command issued to */ int startType; /* how start is specified */ Point *argStartPt; /* location to route from (in edit cell coords) */ char *argStartLabel; /* label to route from */ List *argStartLayers; /* OK route layers to start route on */ int destType; /* how dest is specified */ Rect *argDestRect; /* location to route to (in edit cell coords) */ char *argDestLabel; /* label to route to */ List *argDestLayers; /* OK route layers to end route on */ { CellUse *routeUse; /* Toplevel cell visible during routing */ int expansionMask; /* Subcell expansion modes to use during * routing */ Point startPt; /* start and dest terminals */ List *startLayers = NULL; Rect destRect; List *destLayers = NULL; RoutePath *path = NULL; /* resulting path */ TileType startLayer = TT_SPACE; int mzResult = MZ_NO_ACTION; /* determine routeUse and expansionMask for this route. */ { MagWindow *window = NULL; /* find global reference window */ if(irRouteWid>=0) { window = WindSearchWid(irRouteWid); if (window == NULL) { TxError("Couldn't find route window (%d),", irRouteWid); TxError("using command window as reference.\n"); } } /* if no global reference window, use window command issued from */ if(window == NULL) { window = cmdWindow; } /* If reference window is nil, complain and exit */ if(window==NULL) { TxError("Point to a layout window first.\n"); return mzResult; } /* Set expansion mask to window route cmd issued to. Used * during searches. Subcells are treated as expanded if expanded in * window cmd issued to. */ expansionMask = ((DBWclientRec *)(window->w_clientData))->dbw_bitmask; /* Set routeUse to rootuse of reference window - * everything "visible" in * the reference window is visible * during routing. * But resulting route * is painted into edit cell. This distinction is important only * in the case of a subedit. If the user subedits a cell, the * context of the parent(s) will guide the route, but the route * will be painted into the edit cell. */ routeUse = (CellUse *) (window->w_surfaceID); /* make sure cmd issued from window in which edit cell * is being edited */ if (!EditCellUse || EditRootDef != routeUse->cu_def) { TxError("Nothing being edited in route window.\n"); return mzResult; } } /* initialize mzrouter */ MZInitRoute(irMazeParms, routeUse, expansionMask); /* Figure out start coordinates */ { Point irGetStartPoint(); startPt = irGetStartPoint(startType, argStartPt, argStartLabel, &startLayer, routeUse); /* check for failure */ if(startPt.p_x == MINFINITY) goto abort; } /* Set maze router dest area(s) */ if(destType == DT_SELECTION) /* add destination area for each selected area on an appropriate layer */ { int irSelectedTileFunc(); if(argDestLayers == NULL) /* no layer arg specified, generate dest areas for each active * route layer */ { RouteLayer *rL; for (rL = irRouteLayers; rL != NULL; rL = rL->rl_next) { if(rL->rl_routeType.rt_active) { /* set dest area for each selected tile * of type connecting to rL */ SelEnumPaint( &(DBConnectTbl[rL->rl_routeType.rt_tileType]), FALSE, /* TRUE = restricted to edit cell */ NULL, /* not used */ irSelectedTileFunc, (ClientData *) rL /* type of destarea */ ); } } } else /* generate dest areas for layers that are both specified and active */ { List *l; for(l=argDestLayers; l!=NULL; l=LIST_TAIL(l)) { RouteLayer *rL = (RouteLayer *) LIST_FIRST(l); if(rL->rl_routeType.rt_active) { /* set dest area for each selected tile * of type connecting to rL */ SelEnumPaint( &(DBConnectTbl[rL->rl_routeType.rt_tileType]), FALSE, /* TRUE = restricted to edit cell */ NULL, /* not used */ irSelectedTileFunc, (ClientData *) rL /* type of destarea */ ); } } } } else /* dest is defined by rectangle */ { Rect irGetDestRect(); TileType destLayer = TT_SPACE; destRect = irGetDestRect(destType, argDestRect, argDestLabel, &destLayer, routeUse); /* check for failure */ if(destRect.r_xtop == MINFINITY) goto abort; /* set a maze router dest area for extent of destRect * on each permitted dest layer. */ if (destLayer != TT_SPACE) { RouteLayer *rL; /* layer type returned by irGetDestRect */ for(rL = irRouteLayers; rL != NULL; rL = rL->rl_next) { if (rL->rl_routeType.rt_active && TTMaskHasType(&(DBConnectTbl[destLayer]), rL->rl_routeType.rt_tileType)) { MZAddDest(&destRect, rL->rl_routeType.rt_tileType); break; } } } else if (argDestLayers == NULL) { /* no layer arg specified, permit all active route layers */ RouteLayer *rL; for (rL = irRouteLayers; rL != NULL; rL = rL->rl_next) { if(rL->rl_routeType.rt_active) { MZAddDest(&destRect,rL->rl_routeType.rt_tileType); } } } else /* permit only layers that are both specified and active */ { List *l; for(l=argDestLayers; l!=NULL; l=LIST_TAIL(l)) { RouteLayer *rL = (RouteLayer *) LIST_FIRST(l); if(rL->rl_routeType.rt_active) { MZAddDest(&destRect,rL->rl_routeType.rt_tileType); } } } } if (startLayer != TT_SPACE) { RouteLayer *rL; /* layer type returned by irGetStartPoint */ for (rL = irRouteLayers; rL != NULL; rL = rL->rl_next) { if (rL->rl_routeType.rt_active && TTMaskHasType(&(DBConnectTbl[startLayer]), rL->rl_routeType.rt_tileType)) { MZAddStart(&startPt, rL->rl_routeType.rt_tileType); break; } } } else { /* Determine OK start layers */ List *l; startLayers = irChooseEndPtLayers( routeUse, expansionMask, &startPt, argStartLayers, "start"); if(SigInterruptPending) goto abort; if(DebugIsSet(irDebugID,irDebEndPts)) { TxPrintf("----- startLayers:\n"); MZPrintRLListNames(startLayers); } /* Set maze router start point(s) - one for each ok layer */ for(l=startLayers; l!=NULL;l=LIST_TAIL(l)) { RouteLayer *rL = (RouteLayer *)LIST_FIRST(l); TileType type = rL->rl_routeType.rt_tileType; MZAddStart(&startPt, type); } } /* Do the Route */ path = MZRoute(&mzResult); /* If MZRoute is interrupted it returns best path * found so far. */ if(SigInterruptPending) { if(path==NULL) { goto abort; } else { TxError("Search Interrupted!\n"); TxPrintf("Using best path found prior to interrupt.\n"); /* Clear interrupt to allow paint back of path */ SigInterruptPending = FALSE; } } /* paint route back into edit cell */ if (path) { RouteLayer *finalRL = path->rp_rLayer; CellUse *resultUse; /* Have MazeRouter paint path into resultCell */ resultUse = MZPaintPath(path); if(SigInterruptPending) goto abort; /* Copy to edit cell transforming from root to edit * coords. * Also select the entire route. * This paint job is undoable. */ { SearchContext scx; scx.scx_use = resultUse; scx.scx_area = resultUse->cu_def->cd_bbox; scx.scx_trans = RootToEditTransform; (void) DBCellCopyPaint(&scx, &DBAllButSpaceBits, 0, EditCellUse); DBReComputeBbox(EditCellUse->cu_def); } /* Select the route */ { SearchContext scx; /* Clear selection, and set selection display for reference * window and other windows containing routeUse as root. */ SelectClear(); if(SelectRootDef != routeUse->cu_def) { SelectRootDef = routeUse->cu_def; SelSetDisplay(SelectUse, SelectRootDef); } /* Copy route to selection cell, notifying undo of change */ scx.scx_use = resultUse; scx.scx_area = resultUse->cu_def->cd_bbox; scx.scx_trans = GeoIdentityTransform; SelRememberForUndo(TRUE, (CellDef *) NULL, (Rect *) NULL); (void) DBCellCopyPaint(&scx, &DBAllButSpaceBits, 0, SelectUse); SelRememberForUndo(FALSE, SelectRootDef, &(scx.scx_area)); /* Setup redisplay */ DBReComputeBbox(SelectDef); DBWHLRedraw(SelectRootDef, &(scx.scx_area), TRUE); DBWAreaChanged(SelectDef, &SelectDef->cd_bbox, DBW_ALLWINDOWS, &DBAllButSpaceBits); } /* Notify dbwind module (for redisplay), and DRC module * of changed area */ { Rect changedArea; GeoTransRect( &RootToEditTransform, &(resultUse->cu_def->cd_bbox), &changedArea); DBWAreaChanged(EditCellUse->cu_def, &changedArea, DBW_ALLWINDOWS, &DBAllButSpaceBits); DRCCheckThis(EditCellUse->cu_def, TT_CHECKPAINT, &changedArea); } /* Make sure we got here without interruption */ if(SigInterruptPending) goto abort; TxPrintf("Done Routing.\n"); TxFlushOut(); } else { TxError("Route Failed.\n"); } abort: if(SigInterruptPending) { TxError("Route Interrupted!\n"); } ListDealloc(startLayers); ListDealloc(destLayers); /* reclaim storage used by mzrouter */ if(!DebugIsSet(irDebugID, irDebNoClean)) { MZClean(); } return mzResult; } /* * --------------------------------------------------------------------- * * irGetStartPoint -- * * Compute start point. * * Results: * Returns point. * * Side effects: * Returns start layer type in startLayerPtr. * * --------------------------------------------------------------------- */ Point irGetStartPoint(startType, argStartPt, argStartLabel, startLayerPtr, routeUse) int startType; /* how start is specified */ Point *argStartPt; /* location to route from * (in edit cell coords) */ char *argStartLabel; /* label to route from */ TileType *startLayerPtr; /* layer type (returned value) */ CellUse *routeUse; /* toplevel cell visible to router */ { Point startPt; switch (startType) { case ST_POINT: /* start point coords given */ { /* convert from edit to routeUse coords (= root coordinates) */ GeoTransPoint(&EditToRootTransform,argStartPt,&startPt); } break; case ST_CURSOR: /* use cursor */ { MagWindow *pointWindow; pointWindow = ToolGetPoint(&startPt, (Rect *) NULL); if (pointWindow == NULL) { TxError("Can not use cursor as start:"); TxError(" cursor not in layout window.\n"); goto abort; } if (routeUse->cu_def != ((CellUse *)pointWindow->w_surfaceID)->cu_def) { TxError("Can not use cursor as start:"); TxError("cursor not in routecell.\n"); goto abort; } } break; case ST_LABEL: /* label name given */ { int irSelLabelsFunc(); int irAllLabelsFunc(); LabelSearchData lSD; lSD.lsd_name = argStartLabel; /* name to match */ lSD.lsd_result = LSR_NOTFOUND; /* first search selection */ (void) SelEnumLabels(&DBAllTypeBits, FALSE, /* TRUE = search only edit cell */ (bool *) NULL, irSelLabelsFunc, (ClientData) &lSD); if(SigInterruptPending) goto abort; if (lSD.lsd_result == LSR_NOTUNIQUE) { TxError("Warning: Start label '%s' not unique.\n", argStartLabel); } else if (lSD.lsd_result == LSR_NOTFOUND) /* No selected label matched, so search all labels */ { (void) DBSrLabelLoc(routeUse, argStartLabel, irAllLabelsFunc, (ClientData) &lSD); if(SigInterruptPending) goto abort; if (lSD.lsd_result == LSR_NOTUNIQUE) { TxError("Warning: Start label '%s' not unique.\n", argStartLabel); } else if (lSD.lsd_result == LSR_NOTFOUND) { TxError("Start label '%s' not found.\n", argStartLabel); goto abort; } } startPt = lSD.lsd_locRect.r_ll; if (startLayerPtr) *startLayerPtr = lSD.lsd_type; } break; default: /* shouldn't happen */ { ASSERT(FALSE,"irGetStartPoint"); } break; } return startPt; abort: startPt.p_x = MINFINITY; startPt.p_y = MINFINITY; return startPt; } /* * --------------------------------------------------------------------- * * irGetDestRect -- * * Compute destination rectangle. * * Results: * Returns rect. * * Side effects: * Returns layer type in destLayerPtr. * * --------------------------------------------------------------------- */ Rect irGetDestRect(destType, argDestRect, argDestLabel, destLayerPtr, routeUse) int destType; /* how dest is specified */ Rect *argDestRect; /* location to route to * (in edit cell coords) */ char *argDestLabel; /* label to route to */ TileType *destLayerPtr; /* layer type (returned value) */ CellUse *routeUse; /* toplevel cell visible to router */ { Rect destRect; switch (destType) { case DT_RECT: /* dest rect coords given */ { /* convert from edit to routeUse coords (= root coordinates) */ GeoTransRect(&EditToRootTransform,argDestRect,&destRect); } break; case DT_LABEL: /* dest rect given as label */ { int irSelLabelsFunc(); int irAllLabelsFunc(); LabelSearchData lSD; lSD.lsd_name = argDestLabel; /* name to match */ lSD.lsd_result = LSR_NOTFOUND; /* first search selection */ (void) SelEnumLabels(&DBAllTypeBits, FALSE, /* TRUE = search only edit cell */ (bool *) NULL, irSelLabelsFunc, (ClientData) &lSD); if(SigInterruptPending) goto abort; if (lSD.lsd_result == LSR_NOTUNIQUE) { TxError("Warning: Destination label '%s' not unique.\n", argDestLabel); } else if (lSD.lsd_result == LSR_NOTFOUND) { /* No selected label matched, so search all labels */ (void) DBSrLabelLoc(routeUse, argDestLabel, irAllLabelsFunc, (ClientData) &lSD); if(SigInterruptPending) goto abort; if (lSD.lsd_result == LSR_NOTUNIQUE) { TxError("Warning: Destination label '%s' not unique.\n", argDestLabel); } else if (lSD.lsd_result == LSR_NOTFOUND) { TxError("Destination label '%s' not found.\n", argDestLabel); goto abort; } } destRect = lSD.lsd_locRect; if (destLayerPtr) *destLayerPtr = lSD.lsd_type; } break; case DT_BOX: /* use box as dest rect */ { CellDef *boxDef; Rect box; if(!ToolGetBox(&boxDef,&box)) { TxError("Can not use box for dest: No Box.\n"); goto abort; } if (boxDef != routeUse->cu_def) { TxError("Can not use box for dest: "); TxError("box not in route cell.\n"); goto abort; } destRect = box; } break; default: /* shouldn't happen */ { ASSERT(FALSE,"irGetDestRect"); } break; } return destRect; abort: destRect.r_xbot = MINFINITY; destRect.r_ybot = MINFINITY; destRect.r_xtop = MINFINITY; destRect.r_ytop = MINFINITY; return destRect; } /* * --------------------------------------------------------------------- * * irSelLabelsFunc -- * * Called by SelEnumLabels on behalf of irRoute above, to find selected * label of given name. * * Results: * Returns 0 on first match, 1 on second match (to terminate search) * * Side effects: * Sets locRect in clientdata arg location off matching label. * * --------------------------------------------------------------------- */ int irSelLabelsFunc(label, cellUse, transform, clientData) Label *label; CellUse *cellUse; Transform *transform; ClientData clientData; { LabelSearchData *lsd = (LabelSearchData *)clientData; CellDef *cellDef = cellUse->cu_def; if (strcmp(lsd->lsd_name, label->lab_text) != 0) { /* this label doesn't match, continue search */ return 0; } else if (lsd->lsd_result == LSR_FOUND) { /* second match, set result and terminate search */ lsd->lsd_result = LSR_NOTUNIQUE; return 1; } else { /* first match, set location, result, and continue search */ GeoTransRect(transform, &(label->lab_rect), &(lsd->lsd_locRect)); lsd->lsd_result = LSR_FOUND; lsd->lsd_type = label->lab_type; return 0; } } /* * --------------------------------------------------------------------- * * irAllLabelsFunc -- * * Called by DBSrLabelLoc on behalf of irRoute above, to convert labelName * to location of label with matching name. * * Results: * Returns 0 on first match, 1 on second match (to terminate search) * * Side effects: * Sets locRect in clientdata arg to location of matching label. * * --------------------------------------------------------------------- */ int irAllLabelsFunc(rect, name, label, clientData) Rect *rect; char *name; Label *label; ClientData clientData; { LabelSearchData *lsd = (LabelSearchData *)clientData; if (lsd->lsd_result == LSR_FOUND) { if (GEO_SAMERECT(lsd->lsd_locRect, *rect)) return 0; /* second match, so set result and terminate search */ lsd->lsd_result = LSR_NOTUNIQUE; return 1; } else { /* first match, so set location, result, and continue search */ lsd->lsd_locRect = *rect; lsd->lsd_type = label->lab_type; lsd->lsd_result = LSR_FOUND; return 0; } } /* * --------------------------------------------------------------------- * * irSelectedTileFunc -- * * Called by SelEnumPaint on behalf of irRoute above, to process tile * associated with selection rect. * * Results: * Always returns 0 to continue search. * * Side effects: * Call MzAddDest on selected area. * * --------------------------------------------------------------------- */ int irSelectedTileFunc(rect, type, c) Rect *rect; TileType type; ClientData c; { RouteLayer *rL = (RouteLayer *) c; MZAddDest(rect, rL->rl_routeType.rt_tileType); /* return 0 to continue search */ return 0; } /* * ---------------------------------------------------------------------------- * * LayerInTouchingContact -- * * A Predicate. Checks whether the given routeLayer is a component of a * contact type in touchingTypes. Used by irChooseEndPtLayers below. * * Results: * TRUE if the RouteLayer is a component of a contact type in * touchingTypes, else FALSE. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool LayerInTouchingContact(rL,touchingTypes) RouteLayer *rL; TileTypeBitMask touchingTypes; { RouteContact *rC; for(rC=irRouteContacts; rC!=NULL; rC=rC->rc_next) { if(TTMaskHasType(&touchingTypes,rC->rc_routeType.rt_tileType) && (rC->rc_rLayer1==rL || rC->rc_rLayer2==rL)) return(TRUE); } return(FALSE); } /* * ---------------------------------------------------------------------------- * * irChooseEndPtLayers -- * * Figure out what layers are ok at an endpoint - if ambiguous ask user. * * Results: * List of ok layers at endpoint. * * Side effects: * May query user about intended layers at an endpoint. * * ---------------------------------------------------------------------------- */ List * irChooseEndPtLayers(routeUse,expansionMask,endPt,argLayers,endPtName) CellUse *routeUse; int expansionMask; /* mask of expanded subcells */ Point *endPt; List *argLayers; char *endPtName; { List *activeLayers; List *presentLayers; List *presentContacts; List *presentContactLayers; static char *actionNames[] = { "no", "yes", 0 }; List *l; RouteLayer *rL; if (DebugIsSet(irDebugID, irDebEndPts)) { TxPrintf("----- argLayers:\n"); MZPrintRLListNames(argLayers); } /* find activeLayers among argLayers (or irRouteLayers if argLayers NULL) */ activeLayers = NULL; if(argLayers) { /* layers given in arg, search these */ for(l=argLayers; l!=NULL; l=LIST_TAIL(l)) { rL = (RouteLayer*) LIST_FIRST(l); if(rL->rl_routeType.rt_active) { LIST_ADD(rL,activeLayers); } } } else { /* no layers given as arg, so search all route layers */ for(rL=irRouteLayers; rL!=NULL; rL=rL->rl_next) if(rL->rl_routeType.rt_active) { LIST_ADD(rL,activeLayers); } } if (DebugIsSet(irDebugID, irDebEndPts)) { TxPrintf("----- activeLayers:\n"); MZPrintRLListNames(activeLayers); } /* make lists of contacts (connecting two active layers) and * active layers which are present at the end point. */ { TileTypeBitMask touchingTypes; RouteContact *rC; touchingTypes = TouchingTypes(routeUse, expansionMask, endPt); /* Make list of present and active contacts */ presentContacts = NULL; presentContactLayers = NULL; for(rC =irRouteContacts; rC!=NULL; rC=rC->rc_next) { if(TTMaskHasType(&touchingTypes,rC->rc_routeType.rt_tileType) && ListContainsP(rC->rc_rLayer1, activeLayers) && ListContainsP(rC->rc_rLayer2, activeLayers)) { LIST_ADD(rC, presentContacts); LIST_ADD(rC->rc_rLayer1, presentContactLayers); LIST_ADD(rC->rc_rLayer2, presentContactLayers); } } if (DebugIsSet(irDebugID, irDebEndPts)) { TxPrintf("----- presentContacts:\n"); MZPrintRCListNames(presentContacts); TxPrintf("----- presentContactLayers:\n"); MZPrintRLListNames(presentContactLayers); } /* make list of present layers that are not constituents of contacts * above. If a contact is touching the endpt but one of * its constituent layers in not active, the other constituent * layer is treated as a presentLayer. */ presentLayers = NULL; for(l=activeLayers; l!=NULL; l=LIST_TAIL(l)) { rL = (RouteLayer *) LIST_FIRST(l); if((TTMaskHasType(&touchingTypes,rL->rl_routeType.rt_tileType) || LayerInTouchingContact(rL,touchingTypes)) && !ListContainsP(rL, presentContactLayers)) { LIST_ADD(rL,presentLayers); } } if (DebugIsSet(irDebugID, irDebEndPts)) { TxPrintf("----- presentLayers:\n"); MZPrintRLListNames(presentLayers); } } /* return appropriate layer list. */ { int numContacts, numLayers; numContacts = ListLength(presentContacts); numLayers = ListLength(presentLayers); if(numLayers == 0 && numContacts == 0) { /* No Layers present at endpt, return list of all active layers */ ListDealloc(presentLayers); ListDealloc(presentContacts); ListDealloc(presentContactLayers); return(activeLayers); } else if(numLayers == 1 && numContacts == 0) { /* Exactly one layer is both active and present, return list * containing only this layer. */ ListDealloc(activeLayers); ListDealloc(presentContacts); ListDealloc(presentContactLayers); return(presentLayers); } else if(numLayers == 0 && numContacts == 1) { /* Just one active contact under endpoint, * return layers connecting to that contact. */ List *l; RouteContact *rC; rC = (RouteContact *) LIST_FIRST(presentContacts); l = (List *) NULL; LIST_ADD(rC->rc_rLayer1,l); LIST_ADD(rC->rc_rLayer2,l); ListDealloc(activeLayers); ListDealloc(presentLayers); ListDealloc(presentContacts); ListDealloc(presentContactLayers); return(l); } else { /* Multiple nodes active and present, ask user which one * he wants to route to. */ char answer[100]; RouteLayer *rL; RouteLayer *pickedRL; RouteContact *rC; RouteContact *pickedRC; TxPrintf("Multiple nodes present at %s point:", endPtName); for(l=presentContacts; l!=NULL; l=LIST_TAIL(l)) { rC=(RouteContact *) LIST_FIRST(l); TxPrintf(" %s", DBTypeLongNameTbl[rC->rc_routeType.rt_tileType]); } for(l=presentLayers; l!=NULL; l=LIST_TAIL(l)) { rL=(RouteLayer *) LIST_FIRST(l); TxPrintf(" %s", DBTypeLongNameTbl[rL->rl_routeType.rt_tileType]); } TxPrintf("\n"); for(pickedRC=FALSE,l=presentContacts; l && !pickedRC; l=LIST_TAIL(l)) { rC = (RouteContact *) LIST_FIRST(l); if (!LIST_TAIL(l) && !presentLayers) { /* last choice, so take it */ pickedRC = rC; } else { /* ask user */ TxPrintf("Connect to %s? [yes] ", DBTypeLongNameTbl[rC->rc_routeType.rt_tileType]); if (TxGetLine(answer, sizeof answer) == NULL || answer[0] == '\0') (void) strcpy(answer,"yes"); if(Lookup(answer, actionNames) == 1) { /* Yes */ pickedRC = rC; } } } if(pickedRC) { List *l; l=NULL; LIST_ADD(rC->rc_rLayer1,l); LIST_ADD(rC->rc_rLayer2,l); ListDealloc(activeLayers); ListDealloc(presentLayers); ListDealloc(presentContacts); ListDealloc(presentContactLayers); return(l); } for(pickedRL=NULL,l=presentLayers; l && !pickedRL; l=LIST_TAIL(l)) { rL = (RouteLayer *) LIST_FIRST(l); if(!LIST_TAIL(l)) { /* Last choice so choose it automatically */ pickedRL=rL; } else { /* Ask user */ TxPrintf("Connect to %s? [yes] ", DBTypeLongNameTbl[rL->rl_routeType.rt_tileType]); if (TxGetLine(answer, sizeof answer) == NULL || answer[0] == '\0') (void) strcpy(answer,"yes"); if(Lookup(answer, actionNames) == 1) { /* Yes */ pickedRL = rL; } } } if(pickedRL) { l=NULL; LIST_ADD(rL,l); ListDealloc(activeLayers); ListDealloc(presentLayers); ListDealloc(presentContacts); ListDealloc(presentContactLayers); return(l); } /* User didn't pick anything, return null list */ { ListDealloc(activeLayers); ListDealloc(presentLayers); ListDealloc(presentContacts); ListDealloc(presentContactLayers); return(NULL); } } } } magic-8.0.210/magic/0000755000175000001440000000000011504623601012530 5ustar timusersmagic-8.0.210/magic/symbol.map0000644000175000001440000001512411135117610014535 0ustar timusersMAGIC_8.0 { global: Exttosim_Init; Exttospice_Init; Tclmagic_Init; Tclmagic_SafeInit; Tclplot_Init; Tclroute_Init; Magiclef_Init; ArgStr; CIFGetOutputScale; CellLibPath; CmdCheckForPaintFunc; CmdFuncs; CmdGetEditPoint; CmdGetRootPoint; CmdGetSelectedCell; CmdLongCommands; CmdParseLayers; DBAdjustLabels; DBAllButSpaceAndDRCBits; DBAllButSpaceBits; DBAllTypeBits; DBBoundPlane; DBCellClearDef; DBCellCopyCells; DBCellCopyDefBody; DBCellCopyPaint; DBCellDeleteUse; DBCellEnum; DBCellLookDef; DBCellNewDef; DBCellNewUse; DBCellReadArea; DBCellSetAvail; DBCellSrArea; DBCellSrDefs; DBClearPaintPlane; DBConnPlanes; DBConnectTbl; DBDeleteCell; DBErase; DBFixMismatch; DBFreePaintPlane; DBImageBits; DBIsSubcircuit; DBLayerTypeMaskTbl; DBNewPlane; DBNewYank; DBNoTreeSrTiles; DBNumPlanes; DBNumTypes; DBPaint; DBPaintPlane; DBPaintPlaneVert; DBPaintResultTbl; DBPlaceCell; DBPlaneLongNameTbl; DBPlaneTypes; DBPrintUseId; DBPropGet; DBPutLabel; DBReComputeBbox; DBSeeTypesAll; DBSetTrans; DBSpaceBits; DBSrLabelLoc; DBSrPaintArea; DBTechMinSetPlanes; DBTechName; DBTechNamePlane; DBTechNameType; DBTechNoisyNameMask; DBTechNoisyNameType; DBTechSubsetLayers; DBTechTypesToPlanes; DBTreeSrCells; DBTreeSrLabels; DBTreeSrTiles; DBTypeLongNameTbl; DBTypePaintPlanesTbl; DBTypePlaneTbl; DBTypeShortName; DBUndoEraseLabel; DBUndoPutLabel; DBUnLinkCell; DBUserLayerBits; DBWAreaChanged; DBWFeedbackAdd; DBWFeedbackClear; DBWFeedbackCount; DBWHLAddClient; DBWHLRedraw; DBWNumStyles; DBWSetBox; DBWStyleToTypesTbl; DBWStyleType; DBWclientID; DBWriteResultTbl; DBZeroTypeBits; DIMaxInt; DIZero; DQInit; DQPopFront; DQPushRear; DRCCatchUp; DRCCheckThis; DRCRulesTbl; DebugAddClient; DebugAddFlag; DebugSet; DebugShow; DebugAddClient; DebugAddFlag; DebugSet; DebugShow; DoubleMultI; DoubleMultII; DoubleString; DoubleToDFloat; EditCellUse; EditRootDef; EditToRootTransform; ExtGetDevInfo; ExtCompareStyle; Geo180Transform; Geo270Transform; Geo90Transform; GeoClip; GeoClipPoint; GeoIdentityTransform; GeoInclude; GeoIncludeAll; GeoIncludePoint; GeoInvertTrans; GeoNameToPos; GeoNullRect; GeoOppositePos; GeoScale; GeoSidewaysTransform; GeoTransPoint; GeoTransPos; GeoTransRect; GeoTransTrans; GeoTransTranslate; GeoTranslateTrans; GrClipTriangle; GrFastBox; GrGetColor; GrSetStuff; GrStippleTable; GrStyleTable; HashFind; HashFreeKill; HashInit; HashInitClient; HashKill; HashLookOnly; HashNext; HashStartSearch; HeapAddDInt; HeapAddInt; HeapInit; HeapInitType; HeapKill; HeapLookAtTop; HeapRemoveTop; ListContainsP; ListDealloc; ListDeallocC; ListLength; ListPop; ListReverse; Lookup; LookupStruct; MagAtof; Match; NLBuild; NLFree; NLNetName; NLSort; NMEnumNets; NMHasList; NMNetlistName; NMNewNetlist; NMUnsetCell; NMinit; Path; PaOpen; PaVisitAddClient; PaVisitFiles; PaVisitFree; PaVisitInit; RootToEditTransform; RtrContactWidth; RtrMetalWidth; RtrPolyWidth; RunStats; SelEnumCells; SelEnumLabels; SelEnumPaint; SelRememberForUndo; SelSetDisplay; SelectClear; SelectDef; SelectRootDef; SelectUse; SetNoisyBool; SetNoisyDI; SetNoisyInt; ShowRect; SigDisableInterrupts; SigEnableInterrupts; SigInterruptPending; SimSrConnect; StackFree; StackLook; StackNew; StackPop; StackPush; StrDup; StrIsInt; StrIsNumeric; StrIsWhite; SysLibPath; Tcl_printf; TechAddClient; TechDefault; TechError; TechHalo; TechLoad; TechSectionGetMask; TiAlloc; TiFreePlane; TiJoinX; TiJoinY; TiPlaneRect; TiSplitX; TiSplitY; TiSrArea; TiSrPoint; TiToRect; ToolGetBox; ToolGetEditBox; ToolGetPoint; ToolMoveBox; ToolMoveCorner; TouchingTypes; TxError; TxFlush; TxFlushErr; TxFlushOut; TxGetLine; TxGetLinePrompt; TxMore; TxPrintOff; TxPrintOn; TxPrintf; UndoBackward; UndoDisable; UndoEnable; WindReplaceCommand; WindSurfaceToScreen; WindSearchWid; WindUpdate; callocMagic; cmdParseCoord; dbSetPlaneTile; debugClients; extDevTable; freeMagic; magicinterp; mallocMagic; maskToPrint; niceabort; windCheckOnlyWindow; local: *; }; magic-8.0.210/magic/magicps.pro0000644000175000001440000000564610751423606014716 0ustar timusers%%BeginProlog % % PostScript prolog for output from magic plot % Version: 1.0 % written by Tim Edwards 4/05/00 JHU Applied Physics Laboratory % %%BeginResource: procset MAGICproc 1.0 1 % supporting definitions /MAGICsave save def /bop { 1 setlinecap 0 setlinejoin 6 setmiterlimit 0 setgray } def /ninit { /nChars matrix currentmatrix dup 0 get 0 eq {1} {0} ifelse get abs 72 8.5 mul mul 64 div ceiling cvi def } def /minit { 1 1 dtransform abs dup 1 exch div /onePix exch def dup /resY exch def 1 exch div /iresY exch def abs dup /resX exch def 1 exch div /iresX exch def /bX 64 iresX mul def /bY 64 iresY mul def /pattFont StipplePattern definefont pop /patterns /pattFont findfont [iresX 64 mul 0 0 iresY 64 mul 0 0] makefont def /ca nChars 1 add string def } def /StipplePattern 45 dict def StipplePattern begin /FontType 3 def /FontMatrix [1 0 0 1 0 0] def /FontBBox [0 0 1 1] def /Encoding 256 array def /PattName (P0) def /tmpStr 1 string def /NoPatt {<00>} def 0 1 255 { Encoding exch /NoPatt put } for /BuildChar { 1 0 0 0 1 1 setcachedevice exch begin Encoding exch get load 64 64 true [64 0 0 64 0 0] 5 -1 roll imagemask end } def end /dp { StipplePattern begin dup 30 tmpStr cvrs PattName exch 1 exch putinterval PattName cvn dup Encoding exch 4 -1 roll exch put exch store end } def /sf { findfont exch scalefont setfont } bind def /sp { patterns setfont 2 setlinewidth } def /lb { gsave translate 0 0 moveto /just exch def gsave dup true charpath flattenpath pathbbox grestore exch 4 -1 roll exch sub 3 1 roll sub just 4 and 0 gt {just 8 and 0 eq {0.5 mul} if}{pop 0} ifelse exch just 1 and 0 gt {just 2 and 0 eq {0.5 mul} if}{pop 0} ifelse exch rmoveto show grestore } def /sl { 0 1 nChars { exch dup 3 1 roll ca 3 1 roll put } for pop } def /sc { setcmykcolor } bind def /l1 { onePix setlinewidth } def /l2 { onePix 2 mul setlinewidth } def /l3 { onePix 3 mul setlinewidth } def /ml { moveto lineto stroke } bind def /vl { moveto 0 exch rlineto stroke } bind def /hl { moveto 0 rlineto stroke } bind def /mr { rectstroke } bind def /ms { rectfill } bind def /mx { 4 copy rectstroke 4 -1 roll 4 -1 roll 4 copy moveto rlineto stroke 3 -1 roll dup neg 4 1 roll add moveto rlineto stroke } bind def /pl { gsave translate /d exch def 0 d neg moveto 0 d lineto stroke d neg 0 moveto d 0 lineto stroke grestore } bind def /bx { x resX mul cvi 63 not and dup iresX mul exch w resX mul sub abs 63 add cvi 64 idiv /w exch def y resY mul cvi 63 not and dup iresY mul exch h resY mul sub abs 63 add cvi 64 idiv /h exch def /ch ca 0 w getinterval def moveto h { ch gsave show grestore 0 bY rmoveto } repeat grestore } def /fb {/h exch def /w exch def /y exch def /x exch def gsave newpath x y moveto w y lineto w h lineto x h lineto closepath clip bx } def /tb {1 sub 3 1 roll gsave newpath moveto {lineto} repeat closepath clip pathbbox /h exch def /w exch def /y exch def /x exch def bx } def magic-8.0.210/magic/Makefile0000644000175000001440000000460510751423606014203 0ustar timusers# # rcsid $Header: /usr/cvsroot/magic-8.0/magic/Makefile,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ # MODULE = magic MAGICDIR = .. SRCS = magicTop.c include ${MAGICDIR}/defs.mak EXTRA_LIBS = ${MAGICDIR}/cmwind/libcmwind.o ${MAGICDIR}/commands/libcommands.o \ ${MAGICDIR}/database/libdatabase.o ${MAGICDIR}/dbwind/libdbwind.o \ ${MAGICDIR}/drc/libdrc.o ${MAGICDIR}/debug/libdebug.o \ ${MAGICDIR}/extract/libextract.o ${MAGICDIR}/graphics/libgraphics.o \ ${MAGICDIR}/select/libselect.o ${MAGICDIR}/textio/libtextio.o \ ${MAGICDIR}/tiles/libtiles.o ${MAGICDIR}/windows/libwindows.o \ ${MAGICDIR}/wiring/libwiring.o ${MAGICDIR}/resis/libresis.o \ ${MAGICDIR}/sim/libsim.o ${MAGICDIR}/netmenu/libnetmenu.o \ ${MAGICDIR}/plow/libplow.o ${MAGICDIR}/utils/libutils.o \ ${MAIN_EXTRA_LIBS} BITMAPS = up.xbm down.xbm left.xbm right.xbm zoom.xbm DEST_XBM = $(BITMAPS:%=$(DESTDIR)${TCLDIR}/bitmaps/%) DFLAGS += -DMAGIC_DATE="\"`date`\"" LIBS += ${GR_LIBS} ${READLINE_LIBS} -lm ${LD_EXTRA_LIBS} \ ${OA_LIBS} ${TOP_EXTRA_LIBS} CLEANS += tclmagic${SHDLIB_EXT} libtclmagic${SHDLIB_EXT}.a proto.magicrc main: magic proto.magicrc tcl-main: tclmagic${SHDLIB_EXT} proto.magicrc tclmagic${SHDLIB_EXT}: ${EXTRA_LIBS} @echo --- making magic Tcl library \(tclmagic${SHDLIB_EXT}\) ${RM} tclmagic${SHDLIB_EXT} ${CC} ${CFLAGS} ${CPPFLAGS} -o $@ ${LDDL_FLAGS} ${LD_RUN_PATH} \ ${EXTRA_LIBS} -lc ${LIBS} proto.magicrc: proto.magicrc.m4 sed -e /CAD_DIR/s%CAD_DIR%${LIBDIR}%g proto.magicrc.m4 | \ ${M4} ${GR_DFLAGS} ${DFLAGS} > proto.magicrc install: $(DESTDIR)${BINDIR}/${MODULE}${EXEEXT} $(DESTDIR)${SYSDIR}/.magicrc \ $(DESTDIR)${SYSDIR}/magicps.pro install-tcl: $(DESTDIR)${TCLDIR}/tclmagic${SHDLIB_EXT} $(DESTDIR)${SYSDIR}/.magicrc \ $(DESTDIR)${SYSDIR}/magicps.pro ${DEST_XBM} $(DESTDIR)${TCLDIR}/tclmagic${SHDLIB_EXT}: tclmagic${SHDLIB_EXT} ${RM} $(DESTDIR)${TCLDIR}/tclmagic${SHDLIB_EXT} ${CP} tclmagic${SHDLIB_EXT} $(DESTDIR)${TCLDIR}/tclmagic${SHDLIB_EXT} $(DESTDIR)${TCLDIR}/bitmaps/%: bitmaps/% ${RM} $(DESTDIR)${TCLDIR}/bitmaps/$* ${CP} bitmaps/$* $(DESTDIR)${TCLDIR}/bitmaps/$* $(DESTDIR)${SYSDIR}/.magicrc: proto.magicrc ${RM} $(DESTDIR)${SYSDIR}/.magicrc ${CP} proto.magicrc $(DESTDIR)${SYSDIR}/.magicrc $(DESTDIR)${SYSDIR}/magicps.pro: magicps.pro ${RM} $(DESTDIR)${SYSDIR}/magicps.pro ${CP} magicps.pro $(DESTDIR)${SYSDIR}/magicps.pro include ${MAGICDIR}/rules.mak magic-8.0.210/magic/proto.magicrc.m40000644000175000001440000002111311120112371015526 0ustar timusers# $(CAD_ROOT)/magic/sys/.magicrc # System wide start up file for magic, defines default macros. # # rcsid $Header: /usr/cvsroot/magic-8.0/magic/proto.magicrc.m4,v 1.4 2008/12/11 04:20:09 tim Exp $ # dnl dnl Source file proto.magicrc.m4 dnl Process this file with the m4 macro processor dnl changequote([,])dnl ifdef([MAGIC_WRAPPER],[dnl puts stdout "Processing system .magicrc file" ])dnl (MAGIC_WRAPPER) ifelse(USE_NEW_MACROS,1,[dnl ############################################################################### # Default .magicrc macro file (new macros) ############################################################################### # A key macro a "select visible" macro A "select more visible" macro ^A "select less visible" # B key macro b "box" macro B "findbox" # C key macro c "copy" # D key macro d "delete" macro ^D "erase $" # E key macro e "edit" # F key macro f "sideways" macro F "upsidedown" # G key macro g "grid" macro G "grid 2" # I key macro i "select cell" macro I "select more cell" ifdef([XLIB],[macro Control_XK_i "select less cell"],[dnl]) # L key ifdef([USE_READLINE],[imacro l "labelpaint "],[dnl]) ifdef([MAGIC_WRAPPER],[imacro l "labelpaint "],[dnl]) macro L "shell ls" macro ^L "redraw" # M key macro m "move" macro M "stretch" # N key macro ^N "" # O key macro o "openwindow" macro O "closewindow" # P key ifdef([USE_READLINE],[imacro p "paint "],[dnl]) ifdef([MAGIC_WRAPPER],[imacro p "paint "],[dnl]) # Q key ifdef([XLIB],[macro Control_Shift_XK_q "quit"],[dnl]) # R key macro r "clockwise" macro R "clockwise 270" macro ^R "clockwise 180" # S key macro s "select" macro S "select more" macro ^S "select less" ifdef([XLIB],[macro Control_Shift_XK_s "undo ; select"],[dnl]) # U key macro u "undo" macro U "redo" # V key macro v "view" macro V "xview" # W key macro w "writeall" macro W "writeall force" # X key macro x "expand" macro X "unexpand" macro ^X "expand toggle" # Z key macro z "zoom .5" macro Z "zoom 2" macro ^Z "findbox zoom" ifdef([XLIB],[macro Control_Shift_XK_z "center"],[dnl]) # Question mark macro ? "drc why" macro / "select area; what ; select clear" # Comma key macro , "select clear" # Exclamation mark ifdef([USE_READLINE],[imacro ! "shell "],[dnl]) # Space bar macro " " "tool" ifdef([XLIB],[dnl macro Shift_XK_space "tool box" macro Control_XK_space "tool wiring" # Arrow keys (X11 versions only) macro XK_Left "scroll l .1 w" macro Shift_XK_Left "scroll l 1 w" macro Control_XK_Left "box grow w 1" macro Control_Shift_XK_Left "box shrink e 1" macro XK_Right "scroll r .1 w" macro Shift_XK_Right "scroll r 1 w" macro Control_XK_Right "box grow e 1" macro Control_Shift_XK_Right "box shrink w 1" macro XK_Up "scroll u .1 w" macro Shift_XK_Up "scroll u 1 w" macro Control_XK_Up "box grow n 1" macro Control_Shift_XK_Up "box shrink s 1" macro XK_Down "scroll d .1 w" macro Shift_XK_Down "scroll d 1 w" macro Control_XK_Down "box grow s 1" macro Control_Shift_XK_Down "box shrink n 1" # Keypad keys (X11 versions only) # Functions duplicated for use both with Num_Lock ON and OFF macro XK_KP_Delete "box size 0 0" macro XK_KP_Insert "box size 4 4" macro XK_KP_0 "box size 7 2" macro Shift_XK_KP_0 "box size 7 2" macro XK_0 "box size 7 2" macro Control_XK_KP_0 "box size 2 7" macro Control_XK_KP_Insert "box size 2 7" macro XK_KP_End "move sw 1" macro XK_KP_1 "stretch sw 1" macro Shift_XK_KP_1 "stretch sw 1" macro XK_1 "stretch sw 1" macro XK_KP_Down "move d 1" macro XK_KP_2 "stretch d 1" macro Shift_XK_KP_2 "stretch d 1" macro XK_2 "stretch d 1" macro XK_KP_Next "move se 1" macro XK_KP_3 "stretch se 1" macro Shift_XK_KP_3 "stretch se 1" macro XK_3 "stretch se 1" macro XK_KP_Left "move l 1" macro XK_KP_4 "stretch l 1" macro Shift_XK_KP_4 "stretch l 1" macro XK_4 "stretch l 1" macro XK_KP_Begin "findbox zoom" macro XK_KP_5 "findbox" macro Shift_XK_KP_5 "findbox" macro XK_5 "findbox" macro XK_KP_Right "move r 1" macro XK_KP_6 "stretch r 1" macro Shift_XK_KP_6 "stretch r 1" macro XK_6 "stretch r 1" macro XK_KP_Home "move nw 1" macro XK_KP_7 "stretch nw 1" macro Shift_XK_KP_7 "stretch nw 1" macro XK_7 "stretch nw 1" macro XK_KP_Up "move u 1" macro XK_KP_8 "stretch u 1" macro Shift_XK_KP_8 "stretch u 1" macro XK_8 "stretch u 1" macro XK_KP_Prior "move ne 1" macro XK_KP_9 "stretch ne 1" macro Shift_XK_KP_9 "stretch ne 1" macro XK_9 "stretch ne 1" # Scroll wheel bindings macro XK_Pointer_Button4 "scroll u .05 w" macro XK_Pointer_Button5 "scroll d .05 w" # Quick macro function keys for scmos tech (X11 versions only) macro XK_F1 "paint ndiff" macro XK_F2 "paint pdiff" macro XK_F3 "paint poly" macro XK_F4 "paint poly2" macro XK_F5 "paint m1" macro XK_F6 "paint m2" macro XK_F7 "paint m3" macro XK_F8 "paint m4" macro XK_F9 "paint ndc" macro XK_F10 "paint pdc" macro XK_F11 "paint pc" macro XK_F12 "paint via" ])dnl (ifdef XLIB) ],[dnl (else !USE_NEW_MACROS) ############################################################################### # Default .magicrc macro file (original) ############################################################################### echo "" macro s "select" macro S "select more" macro a "select area" macro A "select more area" macro f "select cell" macro C "select clear" macro d "delete" macro ^D "erase $" macro t "move" macro T "stretch" macro c "copy" macro ^X "expand toggle" macro x "expand" macro X "unexpand" macro q "move left 1" macro w "move down 1" macro e "move up 1" macro r "move right 1" macro Q "stretch left 1" macro W "stretch down 1" macro E "stretch up 1" macro R "stretch right 1" macro g "gridspace" macro G "gridspace 2" macro u "undo" macro U "redo" macro v "view" macro z "findbox zoom" macro Z "zoom 2" macro b "box" macro B "findbox" macro , "center" macro y "drc why" macro ^L "redraw" macro y "drc why" macro ? "help" macro o "openwindow" macro O "closewindow" macro " " "tool" macro ^R "iroute route -dBox" macro ^N "iroute route -dSelection" ])dnl (ifdef USE_NEW_MACROS) # Allow some box manipulation from all tools. ifdef([MAGIC_WRAPPER],[ macro Control_Button1 "*bypass box move bl cursor" macro Control_Button2 "*bypass paint cursor" macro Control_Button3 "*bypass box corner ur cursor" # Box tool button bindings macro Button1 "*bypass box move bl cursor" macro Shift_Button1 "*bypass box corner bl cursor" macro Button2 "*bypass paint cursor" macro Shift_Button2 "*bypass erase cursor" macro Button3 "*bypass box corner ur cursor" macro Shift_Button3 "*bypass box move ur cursor" ],[ macro Control_Button1 "box move bl cursor" macro Control_Button2 "paint cursor" macro Control_Button3 "box corner ur cursor" # Box tool button bindings macro Button1 "box move bl cursor" macro Shift_Button1 "box corner bl cursor" macro Button2 "paint cursor" macro Shift_Button2 "erase cursor" macro Button3 "box corner ur cursor" macro Shift_Button3 "box move ur cursor" ]) # Color window button bindings macro color Button1 "pushbutton left" macro color Button2 "pushbutton middle" macro color Button3 "pushbutton right" macro color u "undo" macro color U "redo" macro color plus "color next" macro color minus "color last" # Netlist window button bindings macro netlist Button1 "pushbutton left" macro netlist Button2 "pushbutton middle" macro netlist Button3 "pushbutton right" # Wind3D window key bindings macro wind3d L "level up" macro wind3d l "level down" macro wind3d C "cif" macro wind3d " " "defaults" macro wind3d ^L "refresh" macro wind3d Z "zoom 2.0 1 rel" macro wind3d z "zoom 0.5 1 rel" macro wind3d 1 "view 0 10 0 rel" macro wind3d 2 "view 0 -10 0 rel" macro wind3d 3 "view 10 0 0 rel" macro wind3d 4 "view -10 0 0 rel" macro wind3d 5 "view 0 0 10 rel" macro wind3d 6 "view 0 0 -10 rel" macro wind3d 7 "view 0 1 0 rel" macro wind3d 8 "view 0 -1 0 rel" macro wind3d 9 "view 1 0 0 rel" macro wind3d 0 "view -1 0 0 rel" ifdef([XLIB],[dnl macro wind3d XK_Up "scroll 0 -0.25 0 rel" macro wind3d XK_Down "scroll 0 0.25 0 rel" macro wind3d XK_Left "scroll 0.25 0 0 rel" macro wind3d XK_Right "scroll -0.25 0 0 rel" macro wind3d XK_minus "view 0 0 1 rel" macro wind3d XK_equal "view 0 0 -1 rel" macro wind3d XK_greater "zoom 1 2.0 rel" macro wind3d XK_less "zoom 1 0.5 rel" ])dnl (ifdef XLIB) # # Load basic set of fonts # setlabel font FreeSans.pt3 0.58 setlabel font FreeSerif.pt3 0.58 setlabel font FreeMono.pt3 0.6 # # Additions for Tcl GUI wrapper # changequote(<,>)dnl ifelse(MAGIC_WRAPPER,1,,)dnl (MAGIC_WRAPPER) changequote([,])dnl # ifdef([SCHEME_INTERPRETER],[dnl # # additions for default scm path # define scm-library-path "CAD_DIR/lib/magic/scm" load-scm "default.scm" load-scm "layout.scm" ])dnl (SCHEME_INTERPRETER) magic-8.0.210/magic/bitmaps/0000755000175000001440000000000011504623574014200 5ustar timusersmagic-8.0.210/magic/bitmaps/down.xbm0000644000175000001440000000037010751423606015654 0ustar timusers#define down_width 13 #define down_height 13 static unsigned char down_bits[] = { 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xff, 0x1f, 0xfe, 0x0f, 0xfc, 0x07, 0xf8, 0x03, 0xf0, 0x01, 0xe0, 0x00, 0x40, 0x00}; magic-8.0.210/magic/bitmaps/up.xbm0000644000175000001440000000036210751423606015332 0ustar timusers#define up_width 13 #define up_height 13 static unsigned char up_bits[] = { 0x40, 0x00, 0xe0, 0x00, 0xf0, 0x01, 0xf8, 0x03, 0xfc, 0x07, 0xfe, 0x0f, 0xff, 0x1f, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00}; magic-8.0.210/magic/bitmaps/zoom.xbm0000644000175000001440000000037010751423606015671 0ustar timusers#define zoom_width 13 #define zoom_height 13 static unsigned char zoom_bits[] = { 0xff, 0x1f, 0xff, 0x1f, 0x03, 0x18, 0x03, 0x18, 0xf3, 0x19, 0xf3, 0x19, 0xb3, 0x19, 0xf3, 0x19, 0xf3, 0x19, 0x03, 0x18, 0x03, 0x18, 0xff, 0x1f, 0xff, 0x1f}; magic-8.0.210/magic/bitmaps/right.xbm0000644000175000001440000000037310751423606016025 0ustar timusers#define right_width 13 #define right_height 13 static unsigned char right_bits[] = { 0x40, 0x00, 0xc0, 0x00, 0xc0, 0x01, 0xc0, 0x03, 0xc0, 0x07, 0xff, 0x0f, 0xff, 0x1f, 0xff, 0x0f, 0xc0, 0x07, 0xc0, 0x03, 0xc0, 0x01, 0xc0, 0x00, 0x40, 0x00}; magic-8.0.210/magic/bitmaps/left.xbm0000644000175000001440000000037010751423606015637 0ustar timusers#define left_width 13 #define left_height 13 static unsigned char left_bits[] = { 0x40, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x00, 0x7c, 0x00, 0xfe, 0x1f, 0xff, 0x1f, 0xfe, 0x1f, 0x7c, 0x00, 0x78, 0x00, 0x70, 0x00, 0x60, 0x00, 0x40, 0x00}; magic-8.0.210/magic/magicTop.c0000644000175000001440000000430710751423606014451 0ustar timusers/* magicTop.c - * * The top level of the Magic VLSI Layout system. * * This top level is purposely very short and is located directly in * the directory used to remake Magic. This is so that other * programs may use all of Magic as a library but still provide their * own 'main' procedure. * * ********************************************************************* * * 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/magic/magicTop.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include "utils/magic.h" #include "utils/malloc.h" /*--------------------------------------------------------------------------- * main: * * Top level of Magic. Do NOT add code to this routine, as all code * should go into `main.c' in the `main' directory. * * Results: * None. * * Side Effects: * Invokes Magic to edit a VLSI design. * *---------------------------------------------------------------------------- */ int main(argc, argv) int argc; char *argv[]; { magicMain(argc, argv); exit(0); } /* String containing the version number of magic. Don't change the string * here, nor its format. It is updated by the Makefile in this directory. * * The version string originates at the top of scripts/config. */ char *MagicVersion = MAGIC_VERSION; char *MagicRevision = MAGIC_REVISION; char *MagicCompileTime = MAGIC_DATE; magic-8.0.210/garouter/0000755000175000001440000000000011504623574013311 5ustar timusersmagic-8.0.210/garouter/TODO0000644000175000001440000000107110751423606013775 0ustar timusersTO DO: ----- Eliminate unnecessary stuff from router module, particularly user channel definition using labels. Via minimization. TEST: ---- Temporary hack: mechanism to use pre-routed stems provided by AMCC (possibly an "alias" command to the router that sets up a table mapping terminal names in the netlist to new names). Check for blockages in the channel; eliminate blocked layers from the list of layers we try to connect to during stem generation. Stem generation: be generous in allowing stems to use above grid lines as well as below. magic-8.0.210/garouter/OUTLINE0000644000175000001440000000234410751423606014353 0ustar timusersGate-array router. This is an initial version tuned specifically for the AMCC 3500 gate-array, intended mainly to develop experience in gate-array routing. It is intended that this form the foundation for a more general-purpose routing system integrated with the other Magic routing tools. Overall structure: ----------------- - Build netlist (just like in router module) - Channel generation: Differences from Magic router: - Channels are provided by the user rather than being generated automatically. There are commands of the several forms: garoute channel xlo ylo xhi yhi Define a general-purpose routing channel garoute channel xlo ylo xhi yhi [horizontal | vertical] Define either a horizontal or a vertical river-routing region - Channels are cleared by garoute clear - Terminals can appear inside river-routing channels. - Terminal pin assignment: Simply assign each pin to both sides of the channel, making certain that there isn't already a pin in the way. Assign edge pins to the channel side that is nearest. If pins are not already aligned, we will do stem generation; it's up to the user to leave enough room in the channels. - Global routing: magic-8.0.210/garouter/gaInternal.h0000644000175000001440000000730510751423606015550 0ustar timusers/* * gaInternal.h -- * * This file defines data structures and constantds and declares * variables INTERNAL TO THE GAROUTER. * but shard by two or more soruce files. * * * Structures etc. that are exported by the irouter are defined in * irouter.h. * * Structures etc. that are local to a given source * file are declared at the top of that source file. * * Structures, etc., specific to a given function are usually defined at * the head of that function. * * ********************************************************************* * * 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. * * ********************************************************************* * * rcsid $Header: /usr/cvsroot/magic-8.0/garouter/gaInternal.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ */ #ifndef _GAINTERNAL_H #define _GAINTERNAL_H #include "database/database.h" /* Sets limit on amount of searching before mzrouter gives up during * stem generation. The idea is not to waste time on routes that * fail. The number is the maximum number of "blooms" permit during * searching. See mzrouter documentation for details. */ #define MAZE_TIMEOUT 100; /* * Netlist structure. * This is similar to the netlist structures defined in the netmenu * package, but contains enough additional information that we * maintain our own here. * * Each netlist consists of a set of Net structures. These * point to a list of Terms that belong to the net. */ /* * A Term is a point from which routing proceeds. * It is possible for the same label to appear at several different * places in a cell. We assume that these points are connected * internally, and so only route to one. The one we choose for * routing appears on the net_terms list; all other Terms appear * on the term_others list. */ typedef struct term { Rect term_loc; /* Connect to anywhere in this area */ TileType term_layer; /* What type of material */ char *term_name; /* Pointer to HashEntry key, or NULL */ struct net *term_net; /* Back-pointer to net */ struct term *term_next; /* Next term in net */ int term_flags; /* See below */ struct term *term_others; /* Other valid starting points */ } Term; /* Flags for above */ #define TERM_FRINGE 0x01 /* Candidate for fringe routing */ #define TERM_FEEDTHROUGH 0x02 /* Member of feedthrough list */ #define TERM_ROUTED 0x04 /* Routed to rest of net */ /* Everything in a Net is electrically identical */ typedef struct net { struct net *net_next; /* Next net in nnl_netList */ struct term *net_terms; /* List of Terms in this net */ int net_prio; /* If > 0 then user-specified priority * with 1 meaning highest; if 0 then * no priority specified. * +++ NOT CURRENTLY USED +++ */ } Net; /* A NetList specifies a set of connections to be made */ typedef struct nnl { HashTable nnl_termHash; /* Map from names to Terms */ struct net *nnl_netList; /* List of all Nets */ } NewNetList; /* procedure declarations */ extern bool gaMazeInit(); #endif /* _GAINTERNAL_H */ magic-8.0.210/garouter/Makefile0000644000175000001440000000043510751423606014750 0ustar timusers# # rcsid $Header: /usr/cvsroot/magic-8.0/garouter/Makefile,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ # MODULE = garouter MAGICDIR = .. SRCS = gaChannel.c gaMain.c gaMaze.c gaSimple.c gaStem.c \ gaTest.c include ${MAGICDIR}/defs.mak include ${MAGICDIR}/rules.mak magic-8.0.210/garouter/gaSimple.c0000644000175000001440000004565011202560464015221 0ustar timusers/* * gaSimple.c - * * Code to try very simple stems * (straight line connection from pin to terminal * with a possible contact at or near each end) * * ********************************************************************* * * 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/garouter/gaSimple.c,v 1.2 2009/05/13 15:03:16 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/geofast.h" #include "utils/hash.h" #include "utils/heap.h" #include "tiles/tile.h" #include "database/database.h" #include "windows/windows.h" #include "utils/main.h" #include "dbwind/dbwind.h" #include "utils/signals.h" #include "netmenu/netmenu.h" #include "gcr/gcr.h" #include "router/router.h" #include "grouter/grouter.h" #include "garouter/garouter.h" #include "utils/netlist.h" #include "textio/textio.h" #include "utils/styles.h" #include "utils/malloc.h" #include "drc/drc.h" #include "debug/debug.h" #include "extract/extract.h" #include "extract/extractInt.h" bool gaIsClear(); /*--- Externals referenced in this file and not declared in include files ---*/ extern int gaMetalClear; extern int gaPolyClear; extern int gaContactClear; /* * ---------------------------------------------------------------------------- * * gaStemSimpleInit -- * * Initialize the SimpleStem struct to contain information on what * simple routes are possible. * * Simple routes are grid aligned straight routes from the terminal * to the pin, with a possible contact at the terminal and another near * the pin on the grid line just before the channel edge. * * If this routine returns TRUE, gaStemSimpleRoute() must still be called * to determine if a simple route is possible (and optionally to paint the * route into a cell). * * Results: * TRUE if successful, FALSE if it was not possible to make a * grid-aligned route. * * Side effects: * Fills in the fields of *simple. * * ---------------------------------------------------------------------------- */ bool gaStemSimpleInit(routeUse, term, pinPoint, pinSide, simple) CellUse *routeUse; /* Search this cell for obstacles */ NLTermLoc *term; /* Route from term->nloc_rect */ Point *pinPoint; /* Crossing point to reach */ int pinSide; /* Direction of pin from term. */ SimpleStem *simple; /* Fill this in */ { SimpleWire *sMetal = &simple->ss_metalWire; SimpleWire *sPoly = &simple->ss_polyWire; Rect *cTerm = &simple->ss_cTerm; Rect *cPin = &simple->ss_cPin; Rect *termLoc = &term->nloc_rect; /* * Check that the start terminal is big enough for the route to be * grid-aligned. The start terminal has to be big enough * to hold a grid-aligned wire on each of the routing types. */ { int bot, top; switch (pinSide) { case GEO_NORTH: case GEO_SOUTH: { bot = pinPoint->p_x; top = termLoc->r_xtop; if (bot < termLoc->r_xbot) return (FALSE); break; } case GEO_EAST: case GEO_WEST: { bot = pinPoint->p_y; top = termLoc->r_ytop; if (bot < termLoc->r_ybot) return (FALSE); break; } } if (bot + RtrMetalWidth > top || bot + RtrPolyWidth > top) return (FALSE); } /* Misc initialization */ { simple->ss_dir = pinSide; simple->ss_pinPoint = *pinPoint; simple->ss_termArea = term->nloc_rect; simple->ss_termType = term->nloc_label->lab_type; sMetal->sw_type = RtrMetalType; sPoly->sw_type = RtrPolyType; } /* Determine which types connect to terminal directly * (without adding a contact) */ if (simple->ss_termType == RtrContactType) { TTMaskSetOnlyType(&(simple->ss_termMask), RtrMetalType); TTMaskSetType(&(simple->ss_termMask), RtrPolyType); } else { TTMaskSetOnlyType(&(simple->ss_termMask), simple->ss_termType); } /* * Compute contact and wire areas. * Defn of areas: * - long wires run from terminal to pin, * - short wires run from terminal to contact near pin, * - pinStubs run from pinContact to pin. */ { switch (pinSide) { case GEO_NORTH: /* pin is directly above terminal */ { /* compute terminal contact location */ cTerm->r_xbot = pinPoint->p_x + RtrContactOffset; cTerm->r_ybot = termLoc->r_ytop - RtrContactWidth; cTerm->r_xtop = cTerm->r_xbot + RtrContactWidth; cTerm->r_ytop = cTerm->r_ybot + RtrContactWidth; /* compute pin contact location */ cPin->r_xbot = pinPoint->p_x + RtrContactOffset; cPin->r_ybot = (RTR_GRIDDOWN(pinPoint->p_y, RtrOrigin.p_y) + RtrContactOffset); cPin->r_xtop = cPin->r_xbot + RtrContactWidth; cPin->r_ytop = cPin->r_ybot + RtrContactWidth; /* compute poly pin stub location */ sPoly->sw_pinStub.r_xbot = pinPoint->p_x; sPoly->sw_pinStub.r_ybot = cPin->r_ytop; sPoly->sw_pinStub.r_xtop = pinPoint->p_x + RtrPolyWidth; sPoly->sw_pinStub.r_ytop = pinPoint->p_y; /* compute metal pin stub location */ sMetal->sw_pinStub.r_xbot = pinPoint->p_x; sMetal->sw_pinStub.r_ybot = cPin->r_ytop; sMetal->sw_pinStub.r_xtop = pinPoint->p_x + RtrMetalWidth; sMetal->sw_pinStub.r_ytop = pinPoint->p_y; /* compute short metal wire */ sMetal->sw_short.r_xbot = pinPoint->p_x; sMetal->sw_short.r_ybot = termLoc->r_ytop; sMetal->sw_short.r_xtop = pinPoint->p_x + RtrMetalWidth; sMetal->sw_short.r_ytop = cPin->r_ybot; /* compute short poly wire */ sPoly->sw_short.r_xbot = pinPoint->p_x; sPoly->sw_short.r_xtop = pinPoint->p_x + RtrPolyWidth; sPoly->sw_short.r_ybot = termLoc->r_ytop; sPoly->sw_short.r_ytop = cPin->r_ybot; /* compute long metal wire */ sMetal->sw_long = sMetal->sw_short; sMetal->sw_long.r_ytop = pinPoint->p_y; /* compute long poly wire */ sPoly->sw_long = sPoly->sw_short; sPoly->sw_long.r_ytop = pinPoint->p_y; break; } case GEO_SOUTH: /* pin is directly below terminal */ { /* compute terminal contact location */ cTerm->r_xbot = pinPoint->p_x + RtrContactOffset; cTerm->r_ybot = termLoc->r_ybot; cTerm->r_xtop = cTerm->r_xbot + RtrContactWidth; cTerm->r_ytop = cTerm->r_ybot + RtrContactWidth; /* compute pin contact location */ cPin->r_xbot = pinPoint->p_x + RtrContactOffset; cPin->r_ybot = (RTR_GRIDUP(pinPoint->p_y, RtrOrigin.p_y) + RtrContactOffset); cPin->r_xtop = cPin->r_xbot + RtrContactWidth; cPin->r_ytop = cPin->r_ybot + RtrContactWidth; /* compute poly pin stub location */ sPoly->sw_pinStub.r_xbot = pinPoint->p_x; sPoly->sw_pinStub.r_ybot = pinPoint->p_y; sPoly->sw_pinStub.r_xtop = pinPoint->p_x + RtrPolyWidth; sPoly->sw_pinStub.r_ytop = cPin->r_ybot; /* compute metal pin stub location */ sMetal->sw_pinStub.r_xbot = pinPoint->p_x; sMetal->sw_pinStub.r_ybot = pinPoint->p_y; sMetal->sw_pinStub.r_xtop = pinPoint->p_x + RtrMetalWidth; sMetal->sw_pinStub.r_ytop = cPin->r_ybot; /* compute short metal wire */ sMetal->sw_short.r_xbot = pinPoint->p_x; sMetal->sw_short.r_ybot = cPin->r_ytop; sMetal->sw_short.r_xtop = pinPoint->p_x + RtrMetalWidth; sMetal->sw_short.r_ytop = termLoc->r_ybot; /* compute short poly wire */ sPoly->sw_short.r_xbot = pinPoint->p_x; sPoly->sw_short.r_ybot = cPin->r_ytop; sPoly->sw_short.r_xtop = pinPoint->p_x + RtrPolyWidth; sPoly->sw_short.r_ytop = termLoc->r_ybot; /* long metal wire */ sMetal->sw_long = sMetal->sw_short; sMetal->sw_long.r_ybot = pinPoint->p_y; /* long poly wire */ sPoly->sw_long = sPoly->sw_short; sPoly->sw_long.r_ybot = pinPoint->p_y; break; } case GEO_EAST: /* pin is directly to right of terminal */ { /* compute terminal contact location */ cTerm->r_xbot = termLoc->r_xtop - RtrContactWidth; cTerm->r_ybot = pinPoint->p_y + RtrContactOffset; cTerm->r_xtop = cTerm->r_xbot + RtrContactWidth; cTerm->r_ytop = cTerm->r_ybot + RtrContactWidth; /* compute pin contact location */ cPin->r_xbot = (RTR_GRIDDOWN(pinPoint->p_x, RtrOrigin.p_x) + RtrContactOffset); cPin->r_ybot = pinPoint->p_y + RtrContactOffset; cPin->r_xtop = cPin->r_xbot + RtrContactWidth; cPin->r_ytop = cPin->r_ybot + RtrContactWidth; /* compute poly pin stub location */ sPoly->sw_pinStub.r_xbot = cPin->r_xtop; sPoly->sw_pinStub.r_ybot = pinPoint->p_y; sPoly->sw_pinStub.r_xtop = pinPoint->p_x; sPoly->sw_pinStub.r_ytop = pinPoint->p_y + RtrPolyWidth; /* compute metal pin stub location */ sMetal->sw_pinStub.r_xbot = cPin->r_xtop; sMetal->sw_pinStub.r_ybot = pinPoint->p_y; sMetal->sw_pinStub.r_xtop = pinPoint->p_x; sMetal->sw_pinStub.r_ytop = pinPoint->p_y + RtrMetalWidth; /* compute short metal wire */ sMetal->sw_short.r_xbot = termLoc->r_xtop; sMetal->sw_short.r_ybot = pinPoint->p_y; sMetal->sw_short.r_xtop = cPin->r_xbot; sMetal->sw_short.r_ytop = pinPoint->p_y + RtrMetalWidth; /* compute short poly wire */ sPoly->sw_short.r_xbot = termLoc->r_xtop; sPoly->sw_short.r_ybot = pinPoint->p_y; sPoly->sw_short.r_xtop = cPin->r_xbot; sPoly->sw_short.r_ytop = pinPoint->p_y + RtrPolyWidth; /* compute long metal wire */ sMetal->sw_long = sMetal->sw_short; sMetal->sw_long.r_xtop = pinPoint->p_x; /* compute long poly wire */ sPoly->sw_long = sPoly->sw_short; sPoly->sw_long.r_xtop = pinPoint->p_x; break; } case GEO_WEST: /* pin is directly to left of terminal */ { /* compute terminal contact location */ cTerm->r_xbot = termLoc->r_xbot; cTerm->r_ybot = pinPoint->p_y + RtrContactOffset; cTerm->r_xtop = cTerm->r_xbot + RtrContactWidth; cTerm->r_ytop = cTerm->r_ybot + RtrContactWidth; /* compute pin contact location */ cPin->r_xbot = (RTR_GRIDUP(pinPoint->p_x, RtrOrigin.p_x) + RtrContactOffset); cPin->r_ybot = pinPoint->p_y + RtrContactOffset; cPin->r_xtop = cPin->r_xbot + RtrContactWidth; cPin->r_ytop = cPin->r_ybot + RtrContactWidth; /* compute poly pin stub location */ sPoly->sw_pinStub.r_xbot = pinPoint->p_x; sPoly->sw_pinStub.r_ybot = pinPoint->p_y; sPoly->sw_pinStub.r_xtop = cPin->r_xbot; sPoly->sw_pinStub.r_ytop = pinPoint->p_y + RtrPolyWidth; /* compute metal pin stub location */ sMetal->sw_pinStub.r_xbot = pinPoint->p_x; sMetal->sw_pinStub.r_ybot = pinPoint->p_y; sMetal->sw_pinStub.r_xtop = cPin->r_xbot; sMetal->sw_pinStub.r_ytop = pinPoint->p_y + RtrMetalWidth; /* compute short metal wire */ sMetal->sw_short.r_xbot = cPin->r_xtop; sMetal->sw_short.r_ybot = pinPoint->p_y; sMetal->sw_short.r_xtop = termLoc->r_xbot; sMetal->sw_short.r_ytop = pinPoint->p_y + RtrMetalWidth; /* compute short poly wire */ sPoly->sw_short.r_xbot = cPin->r_xtop; sPoly->sw_short.r_ybot = pinPoint->p_y; sPoly->sw_short.r_xtop = termLoc->r_xbot; sPoly->sw_short.r_ytop = pinPoint->p_y + RtrPolyWidth; /* long metal wire */ sMetal->sw_long = sMetal->sw_short; sMetal->sw_long.r_xbot = pinPoint->p_x; /* long poly wire */ sPoly->sw_long = sPoly->sw_short; sPoly->sw_long.r_xbot = pinPoint->p_x; break; } } /* end switch */ } /* check which wires and contacts are blocked */ { Rect rTerm, rPin, rShortMetal, rShortPoly, rLongMetal, rLongPoly; Rect rStubMetal, rStubPoly; /* * bloat wire and contact areas to produce the areas that must * be clear of obstacles in order for a route to be possible. */ { GEO_EXPAND(cTerm, gaContactClear, &rTerm); GEO_EXPAND(cPin, gaContactClear, &rPin); GEO_EXPAND(&sMetal->sw_short, gaMetalClear, &rShortMetal); GEO_EXPAND(&sMetal->sw_long, gaMetalClear, &rLongMetal); GEO_EXPAND(&sMetal->sw_pinStub, gaMetalClear, &rStubMetal); GEO_EXPAND(&sPoly->sw_short, gaPolyClear, &rShortPoly); GEO_EXPAND(&sPoly->sw_long, gaPolyClear, &rLongPoly); GEO_EXPAND(&sPoly->sw_pinStub, gaPolyClear, &rStubPoly); } /* * Prune check areas at terminal and pin to allow prexisting * material at the connection points. * * (NOTE the terminal contact area is not trimmed, but will * only be checked on the layer (if any) that is not part * of the terminal) */ { Rect pruneR; /* compute prune area */ { pruneR = routeUse->cu_bbox; switch (pinSide) { case GEO_NORTH: { pruneR.r_ybot = termLoc->r_ytop; pruneR.r_ytop = pinPoint->p_y; break; } case GEO_SOUTH: { pruneR.r_ybot = pinPoint->p_y; pruneR.r_ytop = termLoc->r_ybot; break; } case GEO_EAST: { pruneR.r_xbot = termLoc->r_xtop; pruneR.r_xtop = pinPoint->p_x; break; } case GEO_WEST: { pruneR.r_xbot = pinPoint->p_x; pruneR.r_xtop = termLoc->r_xbot; } } } /* prune the areas (accept for rTerm) */ { GEOCLIP(&rPin, &pruneR); GEOCLIP(&rShortMetal, &pruneR); GEOCLIP(&rLongMetal, &pruneR); GEOCLIP(&rStubMetal, &pruneR); GEOCLIP(&rShortPoly, &pruneR); GEOCLIP(&rLongPoly, &pruneR); GEOCLIP(&rStubPoly, &pruneR); } } /* check areas for obstacles */ { /* terminal contact */ { if(!TTMaskHasType(&simple->ss_termMask, RtrMetalType)) { simple->ss_cTermOK = gaIsClear(routeUse, &rTerm, &RtrMetalObstacles); } if(!TTMaskHasType(&simple->ss_termMask, RtrPolyType)) { simple->ss_cTermOK = gaIsClear(routeUse, &rTerm, &RtrPolyObstacles); } } /* pin contact */ { TileTypeBitMask allObs; TTMaskSetMask3(&allObs, &RtrPolyObstacles, &RtrMetalObstacles); simple->ss_cPinOK = gaIsClear(routeUse, &rPin, &allObs); } /* short metal wire * (a short wire is only ok if both the short wire itself and * the complementary stub are clear) */ sMetal->sw_shortOK = (gaIsClear(routeUse, &rShortMetal, &RtrMetalObstacles) && gaIsClear(routeUse, &rStubPoly, &RtrPolyObstacles)); /* long metal wire */ sMetal->sw_longOK = gaIsClear(routeUse, &rLongMetal, &RtrMetalObstacles); /* short poly wire */ sPoly->sw_shortOK = (gaIsClear(routeUse, &rShortPoly, &RtrPolyObstacles) && gaIsClear(routeUse, &rStubMetal, &RtrMetalObstacles)); /* long poly wire */ sPoly->sw_longOK = gaIsClear(routeUse, &rLongPoly, &RtrPolyObstacles); } } return (TRUE); } /* * ---------------------------------------------------------------------------- * * gaIsClear -- * * * Check that r is clear of all material of types in mask. * * Results: * TRUE if the area is clear, FALSE if not. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool gaIsClear(use, r, mask) CellUse *use; Rect *r; TileTypeBitMask *mask; { int gaIsClearFunc(); SearchContext scx; scx.scx_use = use; scx.scx_trans = GeoIdentityTransform; scx.scx_area = *r; if (DebugIsSet(gaDebugID, gaDebStems)) { ShowRect(use->cu_def, r, STYLE_OUTLINEHIGHLIGHTS); TxMore("Checking clear area"); ShowRect(use->cu_def, r, STYLE_ERASEHIGHLIGHTS); } if (DBTreeSrTiles(&scx, mask, 0, gaIsClearFunc, (ClientData) NULL)) return (FALSE); return (TRUE); } /* * ---------------------------------------------------------------------------- * * gaIsClearFunc -- * * Called for tiles whose type matches 'mask' underneath the area * 'r' in gaIsClear() above. * * Results: * Always returns 1 since we only need a single obstacle to not have * a clear area. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ int gaIsClearFunc(tile, cxp) Tile *tile; TreeContext *cxp; { return 1; } /* * ---------------------------------------------------------------------------- * * gaStemSimpleRoute -- * * See if a simple type of route is possible given the pinLayer. * All other information describing the simple route is * present in *simple. * * Results: * TRUE if a route was possible, FALSE if not. * * Side effects: * Paints the path into 'def' if 'def' is non-NULL. * * ---------------------------------------------------------------------------- */ bool gaStemSimpleRoute(simple, pinLayer, def) SimpleStem *simple; /* Describes the route */ TileType pinLayer; /* Connect to pin on this layer */ CellDef *def; /* If non-NULL, paint to this def */ { SimpleWire *wPin, *wOther; /* * Determine which wire corresponds to pin * and which corresponds to the other route layer. */ if (pinLayer == RtrPolyType) { wPin = &simple->ss_polyWire; wOther = &simple->ss_metalWire; } else if (pinLayer == RtrMetalType) { wPin = &simple->ss_metalWire; wOther = &simple->ss_polyWire; } else { ASSERT(FALSE, "gaStemSimpleRoute: bad destType"); } if(TTMaskHasType(&simple->ss_termMask, pinLayer)) /* layer of pin also OK for final connection at terminal */ { if(wPin->sw_longOK) /* No contact connection */ { if(def) { DBPaint(def, &wPin->sw_long, wPin->sw_type); } return TRUE; } /* contact at pin only */ else if (TTMaskHasType(&simple->ss_termMask, wOther->sw_type) && wOther->sw_shortOK && simple->ss_cPinOK) { if(def) { DBPaint(def, &wOther->sw_short, wOther->sw_type); RtrPaintContact(def, &simple->ss_cPin); DBPaint(def, &wPin->sw_pinStub, wPin->sw_type); } return TRUE; } else if (simple->ss_cTermOK && wOther->sw_shortOK && simple->ss_cPinOK) /* two contact route */ { if(def) { RtrPaintContact(def, &simple->ss_cTerm); DBPaint(def, &wOther->sw_short, wOther->sw_type); RtrPaintContact(def, &simple->ss_cPin); DBPaint(def, &wPin->sw_pinStub, wPin->sw_type); } return TRUE; } else /* No simple route */ { return FALSE; } } else /* pin and terminal connections on opposite layers */ { if(simple->ss_cTermOK && wPin->sw_longOK) /* contact at terminal only */ { if(def) { RtrPaintContact(def, &simple->ss_cTerm); DBPaint(def, &wPin->sw_long, wPin->sw_type); } return TRUE; } else if(wOther->sw_shortOK && simple->ss_cPinOK) /* contact at pin only */ { if(def) { DBPaint(def, &wOther->sw_short, wOther->sw_type); RtrPaintContact(def, &simple->ss_cPin); DBPaint(def, &wPin->sw_pinStub, wPin->sw_type); } return TRUE; } else /* No simple route */ { return FALSE; } } } magic-8.0.210/garouter/gaTest.c0000644000175000001440000002606111176643240014706 0ustar timusers/* * gaTest.c -- * * Testing code for the gate-array router. * * ********************************************************************* * * 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/garouter/gaTest.c,v 1.2 2009/05/01 18:59:44 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/hash.h" #include "utils/heap.h" #include "tiles/tile.h" #include "database/database.h" #include "utils/signals.h" #include "textio/textio.h" #include "debug/debug.h" #include "gcr/gcr.h" #include "router/router.h" #include "grouter/grouter.h" #include "graphics/graphics.h" #include "garouter/garouter.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "textio/txcommands.h" #include "utils/main.h" #include "utils/utils.h" #include "commands/commands.h" #include "utils/styles.h" bool gaInitialized = FALSE; ClientData gaDebugID = 0; int gaDebChanOnly = 0; int gaDebChanStats = 0; int gaDebMaze = 0; int gaDebNoSimple = 0; int gaDebPaintStems = 0; int gaDebShowChans = 0; int gaDebShowMaze = 0; int gaDebStems = 0; int gaDebVerbose = 0; int gaDebNoClean = 0; /* Used in the "*garoute split" command */ PlaneMask gaSplitPlaneMask; void (*gaSplitPaintPlane)(); Rect gaSplitArea; int gaSplitType; /* Forward declarations */ void GAInit(); /* * ---------------------------------------------------------------------------- * * GATest -- * * Command interface for testing the gate-array router. * * Results: * None. * * Side effects: * Depends on the command; see below. * * ---------------------------------------------------------------------------- */ void GATest(w, cmd) MagWindow *w; TxCommand *cmd; { int n; typedef enum { CLRDEBUG, SETDEBUG, SHOWDEBUG} cmdType; static struct { char *cmd_name; cmdType cmd_val; } cmds[] = { "clrdebug", CLRDEBUG, "setdebug", SETDEBUG, "showdebug", SHOWDEBUG, 0 }; GAInit(); if (cmd->tx_argc == 1) { TxError("Must give subcommand\n"); goto badCmd; } n = LookupStruct(cmd->tx_argv[1], (LookupTable *) cmds, sizeof cmds[0]); if (n < 0) { TxError("Unrecognized subcommand: %s\n", cmd->tx_argv[1]); badCmd: TxError("Valid subcommands:"); for (n = 0; cmds[n].cmd_name; n++) TxError(" %s", cmds[n].cmd_name); TxError("\n"); return; } switch (cmds[n].cmd_val) { case SETDEBUG: DebugSet(gaDebugID, cmd->tx_argc - 2, &cmd->tx_argv[2], TRUE); break; case CLRDEBUG: DebugSet(gaDebugID, cmd->tx_argc - 2, &cmd->tx_argv[2], FALSE); break; case SHOWDEBUG: DebugShow(gaDebugID); break; } return; } /* * ---------------------------------------------------------------------------- * * GAGenChans -- * * Generate gate-array channels over the area 'area'. These channels * will be one of two types: CHAN_NORMAL, for channels over empty space, * or chanType (either CHAN_HRIVER or CHAN_VRIVER) for channels over * existing subcells. The output is a collection of "garoute channel" * commands on the file 'f'. * * Results: * None. * * Side effects: * Writes to 'f'. * * ---------------------------------------------------------------------------- */ void GAGenChans(chanType, area, f) int chanType; Rect *area; FILE *f; { extern void DBPaintPlane0(), DBPaintPlaneVert(); int gaSplitFunc(), gaSplitOut(); static CellDef *genDef = (CellDef *) NULL; static CellUse *genUse = (CellUse *) NULL; TileTypeBitMask obstacleMask; int halfUp, halfDown; SearchContext scx; Plane *plane; if (genDef == NULL) DBNewYank("__GENCHANNEL__", &genUse, &genDef); /* * Round the appropriate side of area down to the nearest * center-grid line. */ halfDown = RtrGridSpacing / 2; halfUp = RtrGridSpacing - halfDown; switch (chanType) { case CHAN_HRIVER: gaSplitPaintPlane = DBPaintPlane0; area->r_ytop = RTR_GRIDDOWN(area->r_ytop - halfUp, RtrOrigin.p_y) + halfUp; area->r_ybot = RTR_GRIDUP(area->r_ybot + halfDown, RtrOrigin.p_y) - halfDown; break; case CHAN_VRIVER: gaSplitPaintPlane = DBPaintPlaneVert; area->r_xtop = RTR_GRIDDOWN(area->r_xtop - halfUp, RtrOrigin.p_x) + halfUp; area->r_xbot = RTR_GRIDUP(area->r_xbot + halfDown, RtrOrigin.p_x) - halfDown; break; } /* Make sure everything in 'area' is read */ (void) DBCellReadArea(EditCellUse, area); DBFixMismatch(); /* Start with a clean slate */ DBCellClearDef(genDef); /* * Basic algorithm: * Find all cells in 'area'. Compute the bounding rectangle for * each plane that can affect routing. Bloat by RtrSubcellSepUp or * RtrSubcellSepDown (appropriate direction). Extend this to the top * and bottom of 'area' for CHAN_HRIVER channels, or to the left and * right of 'area' for CHAN_VRIVER ones, and paint into the DRC error * plane of genDef. */ TTMaskSetMask3(&obstacleMask, &RtrPolyObstacles, &RtrMetalObstacles); TTMaskSetType(&obstacleMask, RtrMetalType); TTMaskSetType(&obstacleMask, RtrPolyType); TTMaskSetType(&obstacleMask, RtrContactType); gaSplitPlaneMask = DBTechTypesToPlanes(&obstacleMask); gaSplitArea = *area; gaSplitType = chanType; scx.scx_use = EditCellUse; scx.scx_area = gaSplitArea; scx.scx_trans = GeoIdentityTransform; plane = genDef->cd_planes[PL_DRC_ERROR]; (void) DBCellSrArea(&scx, gaSplitFunc, (ClientData) plane); /* Output all the tiles that lie inside 'area' in 'plane */ (void) DBSrPaintArea((Tile *) NULL, plane, &gaSplitArea, &DBAllTypeBits, gaSplitOut, (ClientData) f); } /* * ---------------------------------------------------------------------------- * * gaSplitOut -- * * Called for each tile inside the area that was processed by GAGenChans() * above. Outputs each tile as the appropriate type of channel (space * tiles are CHAN_NORMAL, non-space are either CHAN_HRIVER or CHAN_VRIVER) * after first clipping to the area gaSplitArea. * * Results: * Always returns 0. * * Side effects: * Writes to 'f'. * * ---------------------------------------------------------------------------- */ int gaSplitOut(tile, f) Tile *tile; FILE *f; { Rect r; TITORECT(tile, &r); GeoClip(&r, &gaSplitArea); if (GEO_RECTNULL(&r)) return (0); fprintf(f, "garoute channel %d %d %d %d", r.r_xbot, r.r_ybot, r.r_xtop, r.r_ytop); if (TiGetType(tile) != TT_SPACE) fprintf(f, " %s", gaSplitType == CHAN_HRIVER ? "h" : "v"); fprintf(f, "\n"); return (0); } /* * ---------------------------------------------------------------------------- * * gaSplitFunc -- * * Called for each cell in the area being processed by GAGenChans() * above. Computes a "true" bounding box for the cell (only looking * at the layers that are obstacles to routing), and then extends the * box as follows: * * If producing CHAN_HRIVER channels, we extend the box to the * top and bottom of gaSplitArea, and bloat it to the right and * left to the next farthest-out line between two grid lines. * * If producing CHAN_VRIVER channels, we extend the box to the * left and right of gaSplitArea, and bloat it to the top and * bottom to the next farthest-out line between two grid lines. * * Results: * Always returns 0. * * Side effects: * Paints the bloated area into the DRC error plane of 'plane' * with a TileType of 1. * * ---------------------------------------------------------------------------- */ int gaSplitFunc(scx, plane) SearchContext *scx; Plane *plane; { int halfUp, halfDown; CellDef *def = scx->scx_use->cu_def; Rect r, rAll, rTrans; int pNum; /* Compute the bounding rect for the interesting planes */ rAll = GeoNullRect; for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) if (PlaneMaskHasPlane(gaSplitPlaneMask, pNum)) { if (DBBoundPlane(def->cd_planes[pNum], &r)) (void) GeoInclude(&r, &rAll); } GeoTransRect(&scx->scx_trans, &rAll, &rTrans); GeoClip(&rTrans, &gaSplitArea); /* Skip if no area */ if (GEO_RECTNULL(&rTrans)) return (0); /* Extend in the appropriate direction and bloat in the other one */ halfDown = RtrGridSpacing / 2; halfUp = RtrGridSpacing - halfDown; switch (gaSplitType) { case CHAN_HRIVER: rTrans.r_ytop = gaSplitArea.r_ytop; rTrans.r_ybot = gaSplitArea.r_ybot; rTrans.r_xtop += RtrSubcellSepUp; rTrans.r_xbot -= RtrSubcellSepDown; rTrans.r_xtop = RTR_GRIDUP(rTrans.r_xtop + halfDown, RtrOrigin.p_x) - halfUp; rTrans.r_xbot = RTR_GRIDDOWN(rTrans.r_xbot - halfUp, RtrOrigin.p_x) + halfDown; break; case CHAN_VRIVER: rTrans.r_xtop = gaSplitArea.r_xtop; rTrans.r_xbot = gaSplitArea.r_xbot; rTrans.r_ytop += RtrSubcellSepUp; rTrans.r_ybot -= RtrSubcellSepDown; rTrans.r_ytop = RTR_GRIDUP(rTrans.r_ytop + halfDown, RtrOrigin.p_y) - halfUp; rTrans.r_ybot = RTR_GRIDDOWN(rTrans.r_ybot - halfUp, RtrOrigin.p_y) + halfDown; break; } /* Paint into DRC error plane */ (*gaSplitPaintPlane)(plane, &rTrans, DBStdWriteTbl(1), (PaintUndoInfo *) NULL, FALSE); return (0); } /* * ---------------------------------------------------------------------------- * * GAInit -- * * One-time-only initialization for the gate-array router. * Called after technology initialization. * * Results: * None. * * Side effects: * Register ourself with the debug module and list all * debugging flags. Also initialize channel information. * * ---------------------------------------------------------------------------- */ void GAInit() { int n; static struct { char *di_name; int *di_id; } dflags[] = { "chanonly", &gaDebChanOnly, "chanstats", &gaDebChanStats, "maze", &gaDebMaze, "nosimple", &gaDebNoSimple, "paintstems", &gaDebPaintStems, "showchans", &gaDebShowChans, "showmaze", &gaDebShowMaze, "stems", &gaDebStems, "verbose", &gaDebVerbose, "noclean", &gaDebNoClean, 0 }; if (gaInitialized) return; gaInitialized = TRUE; /* Register ourselves with the debugging module */ gaDebugID = DebugAddClient("garouter", sizeof dflags/sizeof dflags[0]); for (n = 0; dflags[n].di_name; n++) *(dflags[n].di_id) = DebugAddFlag(gaDebugID, dflags[n].di_name); /* Initialize channel information */ GAChannelInitOnce(); } magic-8.0.210/garouter/gaMaze.c0000644000175000001440000002403710751423606014664 0ustar timusers/* * gaMaze.c - * * Code to interface to mzrouter for harder stems. * * ********************************************************************* * * 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/garouter/gaMaze.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/hash.h" #include "utils/heap.h" #include "utils/undo.h" #include "tiles/tile.h" #include "database/database.h" #include "windows/windows.h" #include "utils/main.h" #include "dbwind/dbwind.h" #include "utils/signals.h" #include "netmenu/netmenu.h" #include "gcr/gcr.h" #include "router/router.h" #include "grouter/grouter.h" #include "garouter/garouter.h" #include "gaInternal.h" #include "utils/netlist.h" #include "textio/textio.h" #include "utils/styles.h" #include "utils/malloc.h" #include "drc/drc.h" #include "debug/debug.h" #include "utils/list.h" #include "../mzrouter/mzrouter.h" /*-------------- Global data only referenced within this file ---------------*/ /* Parameter settings passed to mzrouter (initialized when first needed.) */ MazeParameters *gaMazeParms = NULL; /* Top Level Cell used by mzrouter during stem generation. * Contains a fence, to limit the scope of the search, * and the edit cell as a subcell */ CellUse *gaMazeTopUse; CellDef *gaMazeTopDef; CellUse *gaMazeTopSub; /* Forward declarations */ void gaMazeBounds(); /* * ---------------------------------------------------------------------------- * * gaMazeInit -- * * Initialize ga maze routing code. * Results: * TRUE if successful, FALSE if unsuccessful. * * Side effects: * sets up gaMazeTop cell. * * ---------------------------------------------------------------------------- */ bool gaMazeInit(routeUse) CellUse *routeUse; /* Cell routing will be done in - made subcell * of gaMazeTop */ { UndoDisable(); /* setup maze parms */ if (GAMazeInitParms() == FALSE) return FALSE; /* allocate gaMazeTop - if necessary */ if(!gaMazeTopUse) { DBNewYank("__GAMAZETOP", &gaMazeTopUse, &gaMazeTopDef); } /* unlink old subcell - if any */ if(gaMazeTopSub) { DBUnLinkCell(gaMazeTopSub, gaMazeTopDef); DBDeleteCell(gaMazeTopSub); DBCellDeleteUse(gaMazeTopSub); } /* make routeUse a subcell of gaMazeTop (using identity transform) */ { gaMazeTopSub = DBCellNewUse(routeUse->cu_def, "__MAZE_TOP_SUB"); DBPlaceCell(gaMazeTopSub, gaMazeTopDef); } UndoEnable(); return TRUE; } /* * ---------------------------------------------------------------------------- * * GAMazeInitParms -- Initialize ga maze routing parameters. * * Called by gaMazeInit the first time it is invoked. * Results: * TRUE if successful, FALSE if unsuccessful * * Side effects: * gaMazeParms setup. * * ---------------------------------------------------------------------------- */ bool GAMazeInitParms() { if (gaMazeParms != NULL) { MZFreeParameters(gaMazeParms); gaMazeParms = NULL; } /* Initialize to copy of default garouter parameters */ gaMazeParms = MZCopyParms(MZFindStyle("garouter")); if(gaMazeParms == NULL) return FALSE; /* optimize for this application */ gaMazeParms->mp_expandEndpoints = TRUE; gaMazeParms->mp_topHintsOnly = TRUE; gaMazeParms->mp_bloomLimit = MAZE_TIMEOUT; return TRUE; } /* * ---------------------------------------------------------------------------- * * gaMazeRoute -- * * Try to maze route from pinPoint to terminalLoc * ending up on a layer in `pinLayerMask' while constraining * all wiring to stay within boundingRect. * * Uses the Magic maze router (mzrouter module). * * Results: * Returns TRUE if a route is possible, FALSE if not. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool gaMazeRoute(routeUse, terminalLoc, pinPoint, pinLayerMask, side, writeFlag) CellUse *routeUse; /* Cell to route in - top level cell visible * to router and also cell route is painted * into. All subcells are treated as expanded * by the router, i.e. their contents are * examined. And routing across the tops of * subcells is permitted. */ NLTermLoc *terminalLoc; /* Terminal to connect to - somewhere in * interior of cell */ Point *pinPoint; /* Point to connect from (on edge of cell) */ TileTypeBitMask pinLayerMask; /* layer at pin (no more than one * bit should correspond to a known * routing layer) */ int side; /* side of cell destPoint lies on */ bool writeFlag; /* If non-null, paint back result (into * routeUse), otherwise just check if * route is possible. */ { Rect routeBounds; bool done = FALSE; /* setup bounding box */ { /* compute route bounds */ gaMazeBounds(terminalLoc, pinPoint, &routeBounds); /* Enforce route bounds with fence */ UndoDisable(); DBPaint(gaMazeTopDef, &routeBounds, TT_FENCE); DBReComputeBbox(gaMazeTopDef); UndoEnable(); /* Set bounds hint to fence - improves mzrouter performance */ gaMazeParms->mp_boundsHint = &routeBounds; } /* Initialize Maze Route */ { MZInitRoute(gaMazeParms, gaMazeTopUse, /* all subcells visible */ 0); } /* set maze router start point to pinPoint */ { TileType type; /* determine starting type from mask */ { RouteLayer *rL; /* find route layer corresponding to mask */ for(rL = gaMazeParms->mp_rLayers; rL!=NULL; rL=rL->rl_next) { if(TTMaskHasType(&pinLayerMask,rL->rl_routeType.rt_tileType)) { break; } } /* make sure we found a routelayer */ if (rL == NULL) { TxError("gaMaze.c: no routetypes in destLayerMask\n"); goto abort; } /* set type to tiletype of routelayer */ type = rL->rl_routeType.rt_tileType; } /* give the mzrouter the start point and type */ MZAddStart(pinPoint, type); } /* set maze router dest area to terminal loc and layer*/ { MZAddDest(&(terminalLoc->nloc_rect), terminalLoc->nloc_label->lab_type); } /* Do the Route */ { RoutePath *path; /* search for path */ path = MZRoute(NULL); /* Note: we could make use of the result code... */ if(SigInterruptPending) goto abort; /* If no path found, abort */ if(path == NULL) { goto abort; } /* if write flag set, paint back route path */ if (writeFlag) { CellUse *resultUse; /* Have MazeRouter paint the path into a cell*/ resultUse = MZPaintPath(path); if(SigInterruptPending) goto abort; /* Copy path to route cell */ { SearchContext scx; scx.scx_use = resultUse; scx.scx_area = resultUse->cu_def->cd_bbox; scx.scx_trans = GeoIdentityTransform; (void) DBCellCopyPaint(&scx, &DBAllButSpaceBits, 0, routeUse); DBReComputeBbox(routeUse->cu_def); } /* Notify dbwind module (for redisplay), and DRC module * of changed area */ { Rect changedArea; changedArea= routeUse->cu_def->cd_bbox; DBWAreaChanged(routeUse->cu_def, &changedArea, DBW_ALLWINDOWS, &DBAllButSpaceBits); DRCCheckThis(routeUse->cu_def, TT_CHECKPAINT, &changedArea); } } } /* Make sure we got here without interruption */ if(SigInterruptPending) goto abort; /* We are done */ done = TRUE; abort: /* cleanup and return */ UndoDisable(); DBErase(gaMazeTopDef, &routeBounds, TT_FENCE); UndoEnable(); /* cleanup after the mzrouter */ if(!DebugIsSet(gaDebugID, gaDebNoClean)) { MZClean(); } return done; } /* * ---------------------------------------------------------------------------- * * gaMazeBounds -- * * Pick a rectangular area for mazerouting containing terminalLoc and * enough extra slop to make sure connection and contacts are possible * at the end points. * * Results: * None. * * Side effects: * Sets *r to the area described above. * * ---------------------------------------------------------------------------- */ void gaMazeBounds(terminalLoc, pinPoint, r) NLTermLoc *terminalLoc; /* Terminal */ Point *pinPoint; /* Grid point */ Rect *r; /* Set to bounding area for maze route */ { /* set containing rectangle */ r->r_xbot = MIN(terminalLoc->nloc_rect.r_xbot, pinPoint->p_x); r->r_ybot = MIN(terminalLoc->nloc_rect.r_ybot, pinPoint->p_y); r->r_xtop = MAX(terminalLoc->nloc_rect.r_xtop, pinPoint->p_x); r->r_ytop = MAX(terminalLoc->nloc_rect.r_ytop, pinPoint->p_y); /* Adjust for width of routes */ { int width = 0; /* compute max active width */ { RouteType *rT; for(rT=gaMazeParms->mp_rTypes; rT!=NULL; rT=rT->rt_next) { if(rT->rt_active) { width = MAX(width, rT->rt_width); } } } /* Grow to top and right by max active width */ /* NOTE: Changed by Tim, 7/30/06. 1x max active width is WAY */ /* too constraining, and causes MANY routes to fail. We only */ /* want to avoid hapless searching far outside the local space */ /* that might cause routes to be placed in the way of other */ /* routes. */ { /* r->r_xtop += width; */ /* r->r_ytop += width; */ r->r_xtop += (2 * width); r->r_ytop += (2 * width); r->r_xbot -= (2 * width); r->r_ybot -= (2 * width); } } return; } magic-8.0.210/garouter/gaStem.c0000644000175000001440000010354510751423606014702 0ustar timusers/* * gaStem.c - * * Assignment of routing-grid pin locations to terminals. * * ********************************************************************* * * 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/garouter/gaStem.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/hash.h" #include "utils/heap.h" #include "tiles/tile.h" #include "database/database.h" #include "windows/windows.h" #include "utils/main.h" #include "dbwind/dbwind.h" #include "utils/signals.h" #include "netmenu/netmenu.h" #include "gcr/gcr.h" #include "router/router.h" #include "grouter/grouter.h" #include "garouter/garouter.h" #include "gaInternal.h" #include "utils/netlist.h" #include "textio/textio.h" #include "utils/styles.h" #include "utils/malloc.h" #include "drc/drc.h" #include "debug/debug.h" /* * If TRUE, leave feedback for each location for a terminal that * is unusable. If FALSE, only leave feedback if ALL locations * for a particular terminal are unusable. */ bool GAStemWarn = FALSE; /* Used locally */ int gaMaxAbove; /* The maximum distance any routing material extends * above (or to the right of) a routing grid line. */ int gaMaxBelow; /* Same as above, but for material below or to the * left of routing grid lines. */ int gaMinAbove; /* Minimum distance any routing material extends * above (or to the right of) a routing grid line. */ /* * The following are conservative distances around each of * metal, poly, and contact types that must be clear of material. */ int gaMetalClear, gaPolyClear, gaContactClear; /* Statistics */ int gaNumDegenerate; int gaNumLocs; int gaNumPairs; int gaNumInt, gaNumExt, gaNumNoChan; int gaNumInNorm; int gaNumOverlap; int gaNumNetBlock; int gaNumPinBlock; int gaNumMazeStem, gaNumSimpleStem; int gaNumSimplePaint, gaNumMazePaint, gaNumExtPaint; /* Forward declarations */ int gaStemContainingChannelFunc(); bool gaStemAssign(); void gaStemGridRange(); void gaStemPaint(); bool gaStemNetClear(); bool gaStemInternalFunc(); bool gaStemInternal(); bool gaStemGrow(); /* * ---------------------------------------------------------------------------- * * gaStemAssignAll -- * * Assign one or two crossing points to each terminal location. * Terminal locations must lie inside river-routing channels; * they are assigned crossings on either side of the channel * as long as those crossings are reachable by river-routing. * * If terminal locations aren't grid-aligned, this code takes * care of figuring out which grid-aligned crossing point to * use and ensuring that this point is reachable from the terminal. * * Results: * None. * * Side effects: * Adds one additional NLTermLoc to the netlist for each * terminal location that is given two crossing points. * When it isn't possible to assign any crossing points * to a NLTermLoc, it is deleted from the list and we * leave feedback. * * ---------------------------------------------------------------------------- */ void gaStemAssignAll(routeUse, netList) CellUse *routeUse; NLNetList *netList; { TileType t; /* Statistics */ gaNumDegenerate = 0; gaNumLocs = 0; gaNumInt = 0; gaNumExt = 0; gaNumNoChan = 0; gaNumPairs = 0; gaNumInNorm = 0; gaNumOverlap = 0; gaNumNetBlock = 0; gaNumPinBlock = 0; gaNumMazeStem = 0; gaNumSimpleStem = 0; /* * Compute the distance around metal, poly, and contact that * must be clear of material. */ gaMetalClear = gaPolyClear = 0; for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) { if (RtrMetalSeps[t] > gaMetalClear) gaMetalClear = RtrMetalSeps[t]; if (RtrPolySeps[t] > gaPolyClear) gaPolyClear = RtrPolySeps[t]; } gaContactClear = MAX(gaMetalClear + RtrMetalSurround, gaPolyClear + RtrPolySurround); /* Max distance any routing material extends above a grid line */ gaMaxAbove = MAX(RtrMetalWidth, RtrPolyWidth); gaMaxAbove = MAX(gaMaxAbove, RtrContactWidth - RtrContactOffset); /* Min distance any routing material extends above a grid line */ gaMinAbove = MIN(RtrMetalWidth, RtrPolyWidth); gaMinAbove = MIN(gaMinAbove, RtrContactWidth - RtrContactOffset); /* Max distance any routing material extends below a grid line */ gaMaxBelow = RtrContactOffset; /* Assign the stems (gaStemAssign() does the real work) */ RtrStemProcessAll(routeUse, netList, GAStemWarn, gaStemAssign); if (DebugIsSet(gaDebugID, gaDebVerbose)) { TxPrintf("%d terminals processed.\n", gaNumLocs); TxPrintf("%d internal, %d external, %d no channel.\n", gaNumInt, gaNumExt, gaNumNoChan); TxPrintf("%d paired internal stems.\n", gaNumPairs); TxPrintf("%d degenerate.\n", gaNumDegenerate); TxPrintf("%d discarded because inside normal channels.\n", gaNumInNorm); TxPrintf("%d discarded because overlapped channel boundaries.\n", gaNumOverlap); TxPrintf("%d possible stems blocked by other terminals.\n", gaNumNetBlock); TxPrintf("%d possible stems to blocked pins.\n", gaNumPinBlock); TxPrintf("%d simple paths, %d maze paths.\n", gaNumSimpleStem, gaNumMazeStem); } } /* * ---------------------------------------------------------------------------- * * gaStemAssign -- * * Do the real work of gaStemAssignAll() above -- assign one or two * crossing points to the terminal location 'loc'. * * Results: * TRUE if successful, FALSE if no locations could be assigned. * * Side effects: * May add one additional NLTermLoc to the list for 'loc', * in the position immediately following loc, if this location * is given two crossing points. The caller should be aware * of this in traversing a linked list of NLTermLocs. * * ---------------------------------------------------------------------------- */ bool gaStemAssign(routeUse, doWarn, loc, term, net, netList) CellUse *routeUse; /* Cell being routed */ bool doWarn; /* If TRUE, leave feedback for each error */ NLTermLoc *loc; /* Location considered */ NLTerm *term; /* Terminal of which loc is a location */ NLNet *net; /* Net to which it belongs */ NLNetList *netList; /* Netlist (searched for blocking terminals) */ { GCRChannel *ch; gaNumLocs++; /* * See if this location lies inside a river-routing channel. * If it does, return the channel containing it. */ if (ch = gaStemContainingChannel(routeUse, doWarn, loc)) { if (ch->gcr_type != CHAN_HRIVER && ch->gcr_type != CHAN_VRIVER) goto fail; gaNumInt++; return (gaStemInternal(routeUse, doWarn, loc, net, ch, netList)); } /* Not inside a river-routing channel. Try for a nearby normal channel */ if (RtrStemAssignExt(routeUse, doWarn, loc, term, net)) { gaNumExt++; return (TRUE); } if (doWarn) { DBWFeedbackAdd(&loc->nloc_rect, "No crossing reachable from terminal", routeUse->cu_def, 1, STYLE_PALEHIGHLIGHTS); } fail: gaNumNoChan++; return (FALSE); } /* * ---------------------------------------------------------------------------- * * gaStemContainingChannel -- * * Find the channel containing 'loc' if there is one. This channel, * if it exists, should be a river-routing channel. If it isn't, * we leave feedback if 'doWarn' is TRUE. * * If loc is degenerate, it can't lie on the border of a channel * (this restriction may be lifted later; it's just a pain to * deal with now). * * It is illegal for loc to straddle a channel boundary. * * Results: * Returns the channel as described above, or NULL if loc * didn't lie in a channel or it violated one of the above * conditions. * * Side effects: * Leaves feedback in the event of errors, if 'doWarn' is TRUE. * * ---------------------------------------------------------------------------- */ GCRChannel * gaStemContainingChannel(routeUse, doWarn, loc) CellUse *routeUse; /* For errors */ bool doWarn; /* If TRUE, leave feedback if error */ NLTermLoc *loc; /* Find a channel for this terminal */ { GCRChannel *ch; Rect area; /* Special handling is required for degenerate locs */ area = loc->nloc_rect; if (GEO_RECTNULL(&area)) if (!gaStemGrow(&area)) goto overlap; /* Ensure that only one channel is overlapped */ ch = (GCRChannel *) NULL; if (DBSrPaintArea((Tile *) NULL, RtrChannelPlane, &area, &DBAllTypeBits, gaStemContainingChannelFunc, (ClientData) &ch)) goto overlap; /* Illegal to be inside a normal channel */ if (ch && ch->gcr_type == CHAN_NORMAL) { gaNumInNorm++; if (doWarn) { DBWFeedbackAdd(&area, "Terminal is inside a normal routing channel", routeUse->cu_def, 1, STYLE_PALEHIGHLIGHTS); } } return (ch); overlap: gaNumOverlap++; if (doWarn) { DBWFeedbackAdd(&area, "Terminal overlaps a channel boundary", routeUse->cu_def, 1, STYLE_PALEHIGHLIGHTS); } return ((GCRChannel *) NULL); } /* * gaStemContainingChannelFunc -- * * Called via DBSrPaintArea on behalf of gaStemContainingChannel above * for each tile overlapping the area of a terminal, to determine * whether more than one channel is overlapped by that terminal. * * Results: * Returns 0 normally, or 1 if *pCh was non-zero and * the channel associated with tile was different from * *pCh. * * Side effects: * Sets *pCh to the channel associated with tile if there * was one. * * ---------------------------------------------------------------------------- */ int gaStemContainingChannelFunc(tile, pCh) Tile *tile; GCRChannel **pCh; { GCRChannel *ch; if (ch = (GCRChannel *) tile->ti_client) { if (*pCh) { if (ch != *pCh) return (1); } else *pCh = ch; } return (0); } /* * ---------------------------------------------------------------------------- * * gaStemGrow -- * * The terminal being processed (described by the initial value of *area) * is degenerate, so figure out which side is of interest and grow *area * in that direction. * * If *area is entirely contained by a channel or empty space, * we don't have to do anything. If it lies on the border * of a channel, then currently we reject it. * * Results: * TRUE if area is entirely contained in either channel or empty * space; FALSE otherwise. * * Side effects: * Modifies *area as described above. * * ---------------------------------------------------------------------------- */ bool gaStemGrow(area) Rect *area; { Rect r; GCRChannel *ch; r = *area; if (r.r_xbot == r.r_xtop) r.r_xbot--, r.r_xtop++; if (r.r_ybot == r.r_ytop) r.r_ybot--, r.r_ytop++; gaNumDegenerate++; /* OK if either zero or one channel is overlapped */ ch = (GCRChannel *) NULL; if (DBSrPaintArea((Tile *) NULL, RtrChannelPlane, &r, &DBAllTypeBits, gaStemContainingChannelFunc, (ClientData) &ch) == 0) return (TRUE); return (FALSE); } /* * ---------------------------------------------------------------------------- * * gaStemInternal -- * * Having determined that 'loc' lies entirely within a river-routing * channel, try to bring it out to both sides of the channel. * * If the terminal permits a grid aligned route, "simple" routes are * tried first. A simple route is a grid aligned straight line from * terminal to pin with a possible layer change at the terminal and * another at the grid point just prior to the pin. If simple routes * are not possible, the mzrouter() is called. * * Marks the pins in the channel OUTSIDE the river-routing channel with * net (the ones INSIDE the river-routing channel are left blank, * so the channel router won't try connecting them). Also sets gcr_pSeg * for the outside pins to GCR_STEMSEGID to tell the global router that * they are stem tips; the global router will reassign a real segment * number to the crossing point when the stem tip is used. * * Each NLTermLoc has nloc_chan set to the channels on the outside * of 'ch', rather than 'ch' itself, in order to be consistent with * gaStemExternal. * * Results: * TRUE if we succeeded in assigning one (or two) crossing points; * FALSE if none could be assigned. * * Side effects: * See above. * May add one additional NLTermLoc to the list for 'loc', * in the position immediately following loc, if this location * is given two crossing points. * * ---------------------------------------------------------------------------- */ bool gaStemInternal(routeUse, doWarn, loc, net, ch, netList) CellUse *routeUse; /* Cell being routed */ bool doWarn; /* If TRUE, leave feedback on all errors */ NLTermLoc *loc; /* Terminal being processed */ NLNet *net; /* Used for marking pins */ GCRChannel *ch; /* Channel containing loc */ NLNetList *netList; /* Netlist (searched for blocking terminals) */ { int min, max, start, lo, hi; /* Compute the grid lines that can be used for this terminal */ gaStemGridRange(ch->gcr_type, &loc->nloc_rect, &min, &max, &start); /* * Try each possibility until we find a grid line that is usable, * or until we've run out of possibilities. Work outward from * the starting point. We don't make any attempt to pick the * best grid line, so if we see one early that can only be routed * to one side, and one later that can be routed to both, we still * pick the earlier. The greedy strategy is simpler, and also we * expect that usually there will only be a single grid line per * terminal. */ if (gaStemInternalFunc(routeUse, loc, net, ch, start, netList)) return (TRUE); for (lo = start - RtrGridSpacing, hi = start + RtrGridSpacing; lo >= min || hi <= max; lo -= RtrGridSpacing, hi += RtrGridSpacing) { if (lo >= min) if (gaStemInternalFunc(routeUse, loc, net, ch, lo, netList)) return (TRUE); if (hi <= max) if (gaStemInternalFunc(routeUse, loc, net, ch, hi, netList)) return (TRUE); } if (doWarn) { DBWFeedbackAdd(&loc->nloc_rect, "Terminal can't be brought out to either channel boundary", routeUse->cu_def, 1, STYLE_PALEHIGHLIGHTS); } return (FALSE); } /* * ---------------------------------------------------------------------------- * * gaStemInternalFunc -- * * Try "simple" (straight line) routes and failing that mzroutes from * terminal to pins on both sides of the channel. * If it is possible to connect to one or both sides of the channel * mark loc->nloc_stem, * loc->nloc_chan, and loc->nloc_dir with the location of the * crossing chosen (add a new loc to the list if two crossings were * chosen), and mark the pins in the channels OUTSIDE of the crossings * as described in the comments to gaStemInternal() above. The pin * used for the crossing is stored in loc->nloc_pin. * * NOTE: loc->nloc_chan is the channel on the OUTSIDE of 'ch', * rather than 'ch' itself. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * See above, and also the comments to gaStemInternal(). * * ---------------------------------------------------------------------------- */ bool gaStemInternalFunc(routeUse, loc, net, ch, gridLine, netList) CellUse *routeUse; NLTermLoc *loc; NLNet *net; GCRChannel *ch; int gridLine; NLNetList *netList; { GCRPin *pin1, *pin2; NLTermLoc *loc2; Point p1, p2; int dir1, dir2; /* * Compute the areas that must be searched to ensure that * river-routes to the outside of the channel are possible. */ switch (ch->gcr_type) { case CHAN_HRIVER: p1.p_x = ch->gcr_area.r_xbot; p1.p_y = gridLine; p2.p_x = ch->gcr_area.r_xtop; p2.p_y = gridLine; dir1 = GEO_WEST; dir2 = GEO_EAST; break; case CHAN_VRIVER: p1.p_x = gridLine; p1.p_y = ch->gcr_area.r_ybot; p2.p_x = gridLine; p2.p_y = ch->gcr_area.r_ytop; dir1 = GEO_SOUTH; dir2 = GEO_NORTH; break; } if (DebugIsSet(gaDebugID, gaDebStems)) { TxPrintf("Loc: ll=(%d,%d) ur=(%d,%d)\n", loc->nloc_rect.r_xbot, loc->nloc_rect.r_ybot, loc->nloc_rect.r_xtop, loc->nloc_rect.r_ytop); TxPrintf("Try crossings: L=(%d,%d) and R=(%d,%d)\n", p1.p_x, p1.p_y, p2.p_x, p2.p_y); } pin1 = gaStemCheckPin(routeUse, loc, ch, dir1, &p1, netList); pin2 = gaStemCheckPin(routeUse, loc, ch, dir2, &p2, netList); if (DebugIsSet(gaDebugID, gaDebStems)) { if (pin1) TxPrintf("Success L=(%d,%d)\n", p1.p_x, p1.p_y); if (pin2) TxPrintf("Success R=(%d,%d)\n", p2.p_x, p2.p_y); if (pin1 == NULL && pin2 == NULL) TxPrintf("FAILURE ON BOTH CROSSINGS\n"); TxMore("--------"); } if (pin1 == (GCRPin *) NULL && pin2 == (GCRPin *) NULL) return (FALSE); if (pin1) { loc->nloc_dir = dir1; loc->nloc_stem = p1; loc->nloc_chan = pin1->gcr_linked->gcr_ch; loc->nloc_pin = pin1->gcr_linked; /* Mark the crossing OUTSIDE ch */ pin1->gcr_linked->gcr_pId = (GCRNet *) net; pin1->gcr_linked->gcr_pSeg = GCR_STEMSEGID; } if (pin2) { if (pin1) { /* Allocate a new NLTermLoc to hold the second crossing */ loc2 = (NLTermLoc *) mallocMagic(sizeof (NLTermLoc)); *loc2 = *loc; loc->nloc_next = loc2; loc = loc2; gaNumPairs++; } loc->nloc_dir = dir2; loc->nloc_stem = p2; loc->nloc_chan = pin2->gcr_linked->gcr_ch; loc->nloc_pin = pin2->gcr_linked; /* Mark the crossing OUTSIDE ch */ pin2->gcr_linked->gcr_pId = (GCRNet *) net; pin2->gcr_linked->gcr_pSeg = GCR_STEMSEGID; } return (TRUE); } /* * ---------------------------------------------------------------------------- * * gaStemCheckPin -- * * Determine if the crossing point at 'point' is reachable from 'loc'. * Simple connections are tried first. If these fail, the mzrouter module * is called. * * It must normally be possible to connect to either layer in the * adjacent channel (channel routing isn't guaranteed to leave a * signal on a particular layer since the layer used depends on the * channel orientation). However, if one layer is blocked in the * channel, then we only need to connect to the other layer. * * Results: * Returns the pin belonging to 'ch' and using the crossing * point at 'point' if a river-route is possible, or NULL * if no river-route is possible. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ GCRPin * gaStemCheckPin(routeUse, terminalLoc, ch, side, gridPoint, netList) CellUse *routeUse; /* Cell being routed */ NLTermLoc *terminalLoc; /* Terminal */ GCRChannel *ch; /* Channel whose pin we are to use */ int side; /* Direction 'gridPoint' lies relative to 'loc' */ Point *gridPoint; /* Crossing point to use */ NLNetList *netList; /* Searched for obstructing terminals */ { TileTypeBitMask destMask; GCRPin *pin; SimpleStem simple; short code; /* * Discard this pin immediately if any of the following are true: * - it is already occupied by a net * - it isn't adjacent to a usable channel (i.e, it has no gcr_linked * pin or its gcr_linked pin is blocked) * - there's another terminal from this netlist in the way */ pin = RtrPointToPin(ch, side, gridPoint); if (pin->gcr_pId != (GCRNet *) NULL || pin->gcr_linked == (GCRPin *) NULL || pin->gcr_linked->gcr_pId != (GCRNet *) NULL) { gaNumPinBlock++; return ((GCRPin *) NULL); } if (!gaStemNetClear(&terminalLoc->nloc_rect, gridPoint, side, netList)) { gaNumNetBlock++; return ((GCRPin *) NULL); } /* * What types are present at the pin location? * Only worry about connecting to layers that aren't * present in the channel. The code above assumes * that two-layer blockages at channel boundaries * will cause their corresponding pins to be marked * as blocked. */ code = pin->gcr_ch->gcr_result[pin->gcr_x][pin->gcr_y]; destMask = DBZeroTypeBits; if ((code & GCRBLKM) == 0) TTMaskSetType(&destMask, RtrMetalType); if ((code & GCRBLKP) == 0) TTMaskSetType(&destMask, RtrPolyType); ASSERT(!TTMaskEqual(&destMask, &DBZeroTypeBits), "gaStemCheckPin"); /* * Try to do things the simple way first, considering routes * of a very stylized nature: straight across with at most one * layer change over the terminal, and another on the grid line * just before the channel boundary. This avoids having to * call the maze router if we don't need to. */ if (DebugIsSet(gaDebugID, gaDebNoSimple)) goto hardway; if (!gaStemSimpleInit(routeUse, terminalLoc, gridPoint, side, &simple)) goto hardway; if (TTMaskHasType(&destMask, RtrMetalType) && !gaStemSimpleRoute(&simple, RtrMetalType, (CellDef *) NULL)) { goto hardway; } if (TTMaskHasType(&destMask, RtrPolyType) && !gaStemSimpleRoute(&simple, RtrPolyType, (CellDef *) NULL)) { goto hardway; } /* Win */ gaNumSimpleStem++; return pin; hardway: /* Simple connections have failed, so try using mzrouter. A connection * must be possible from EITHER ROUTING LAYER, so we know we can connect * no matter how the channel is routed. * * NULL writeUse is used so no paint is generated, we just check * if the connections are possible, deferring the actual stem generation * until after channel routing, so we know what layers to connect to. */ { bool writeFlag = FALSE; TileTypeBitMask polyMask, metalMask; TTMaskSetOnlyType(&polyMask, RtrPolyType); TTMaskSetOnlyType(&metalMask, RtrMetalType); if(gaMazeRoute(routeUse, terminalLoc, gridPoint, polyMask, side, writeFlag) && gaMazeRoute(routeUse, terminalLoc, gridPoint, metalMask, side, writeFlag)) { gaNumMazeStem++; return pin; } else { return ((GCRPin *) NULL); } } } /* * ---------------------------------------------------------------------------- * * gaStemNetClear -- * * Determine whether the area between termArea and the crossing point * 'point' is clear of other terminals that might want to share the * same grid line. The purpose of this procedure is primarily to avoid * doing something silly in the following situation (both terminals share * the same horizontal grid line in a CHAN_HRIVER river-routing channel): * * +---------------------------+ * | | * | +---+ +---+ | * | | A | | B | | * | +---+ +---+ | * | | * +---------------------------+ * * Here, terminal "A" should only be brought out to the left, and "B" * only to the right of the channel, since to do otherwise would block * a terminal completely. * * +++ Currently, we consider a path from termArea to point blocked * +++ by another terminal T only if T can use a single grid line, * +++ and this grid line is the same as that of point. * * Results: * TRUE if no terminals share the same grid line, FALSE otherwise. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool gaStemNetClear(termArea, point, side, netList) Rect *termArea; /* Area of the starting terminal */ Point *point; /* Crossing point where we want to end up */ int side; /* Direction of point relative to termArea */ NLNetList *netList; /* Netlist to check for terminals to avoid */ { int min, max, start, type, grid; NLTermLoc *loc; NLTerm *term; NLNet *net; Rect r; /* * First cut: determine a search area large enough so that any * terminals lying entirely outside of it can't possibly conflict * with this one. */ switch (side) { case GEO_NORTH: r.r_xbot = point->p_x - RtrSubcellSepUp; r.r_xtop = point->p_x + RtrSubcellSepDown; r.r_ybot = termArea->r_ytop; r.r_ytop = point->p_y + RtrSubcellSepDown; type = CHAN_VRIVER; break; case GEO_SOUTH: r.r_xbot = point->p_x - RtrSubcellSepUp; r.r_xtop = point->p_x + RtrSubcellSepDown; r.r_ybot = point->p_y - RtrSubcellSepUp; r.r_ytop = termArea->r_ybot; type = CHAN_VRIVER; break; case GEO_WEST: r.r_ybot = point->p_y - RtrSubcellSepUp; r.r_ytop = point->p_y + RtrSubcellSepDown; r.r_xbot = point->p_x - RtrSubcellSepUp; r.r_xtop = termArea->r_xbot; type = CHAN_HRIVER; break; case GEO_EAST: r.r_ybot = point->p_y - RtrSubcellSepUp; r.r_ytop = point->p_y + RtrSubcellSepDown; r.r_xbot = termArea->r_xtop; r.r_xtop = point->p_x + RtrSubcellSepDown; type = CHAN_HRIVER; break; } grid = (type == CHAN_HRIVER) ? point->p_y : point->p_x; /* Only need to do work if a terminal lies inside this search area */ for (net = netList->nnl_nets; net; net = net->nnet_next) { if (!GEO_OVERLAP(&net->nnet_area, &r)) continue; for (term = net->nnet_terms; term; term = term->nterm_next) { for (loc = term->nterm_locs; loc; loc = loc->nloc_next) if (GEO_OVERLAP(&loc->nloc_rect, &r)) { /* Only reject if both prefer same grid location */ gaStemGridRange(type, &loc->nloc_rect, &min,&max,&start); if (start == grid) return (FALSE); } } } return (TRUE); } /* * ---------------------------------------------------------------------------- * * gaStemGridRange -- * * Determine the range of grid lines usable by the terminal whose * area is 'r', for a river-routing channel whose type is 'type' * (one of CHAN_HRIVER or CHAN_VRIVER). Usable grid lines are at * most one grid line away from the relevant boundary of 'r'. * Pick a starting grid line that is as close to the center of the * range of usable grid points and that is also between the top * and bottom (for CHAN_HRIVER) or left and right (for CHAN_VRIVER) * of 'r'. * * Results: * None. * * Side effects: * Sets *pMinGrid, *pMaxGrid, and *pStart. * * ---------------------------------------------------------------------------- */ void gaStemGridRange(type, r, pMinGrid, pMaxGrid, pStart) int type; Rect *r; int *pMinGrid, *pMaxGrid, *pStart; { int min, max, start; switch (type) { case CHAN_HRIVER: { min = RTR_GRIDDOWN(r->r_ybot, RtrOrigin.p_y); max = RTR_GRIDDOWN(r->r_ytop - gaMaxAbove, RtrOrigin.p_y); start = (max + min)/2; start = RTR_GRIDDOWN(start, RtrOrigin.p_y); if (start < r->r_ybot && (start + RtrGridSpacing) < r->r_ytop) { start += RtrGridSpacing; } break; } case CHAN_VRIVER: { min = RTR_GRIDDOWN(r->r_xbot, RtrOrigin.p_x); max = RTR_GRIDDOWN(r->r_xtop - gaMaxAbove, RtrOrigin.p_x); start = (max + min)/2; start = RTR_GRIDDOWN(start, RtrOrigin.p_x); if (start < r->r_xbot && (start + RtrGridSpacing) < r->r_xtop) { start += RtrGridSpacing; } break; } default: { ASSERT(FALSE, "Bad channel type in gaStemGridRange"); break; } } max = MAX(max, start); min= MIN(min, start); *pMaxGrid = max; *pMinGrid = min; *pStart = start; } /* * ---------------------------------------------------------------------------- * * gaStemPaintAll -- * * Paint each stem that turned out to be connected. * See gaStemPaint() for details. * * Results: * None. * * Side effects: * Adds paint to 'routeUse->cu_def'. * * ---------------------------------------------------------------------------- */ void gaStemPaintAll(routeUse, netList) CellUse *routeUse; NLNetList *netList; { NLTermLoc *loc; NLTerm *term; int numInt; NLNet *net; gaNumSimplePaint = 0; gaNumMazePaint = 0; gaNumExtPaint = 0; RtrMilestoneStart("Painting stems"); for (net = netList->nnl_nets; net; net = net->nnet_next) { for (term = net->nnet_terms; term; term = term->nterm_next) for (loc = term->nterm_locs; loc; loc = loc->nloc_next) { if (SigInterruptPending) goto out; if (loc->nloc_dir > 0) gaStemPaint(routeUse, loc); } RtrMilestonePrint(); } out: RtrMilestoneDone(); if (DebugIsSet(gaDebugID, gaDebVerbose)) { numInt = gaNumSimplePaint + gaNumMazePaint; TxPrintf("%d simple, %d maze, %d total internal stems.\n", gaNumSimplePaint, gaNumMazePaint, numInt); TxPrintf("%d external stems painted.\n", gaNumExtPaint); TxPrintf("%d total stems painted.\n", numInt + gaNumExtPaint); } } /* * ---------------------------------------------------------------------------- * * gaStemPaint -- * * Paint a single stem. * Terminals that don't lie inside a river-routing channel are "external" * and are handled by the standard router stem-generator. Terminals that * lie inside a river-routing channel are "internal"; they are connected * to their stem tips on the channel boundary using simple routes if * possible, and failing that using the Magic maze-router (mzrouter). * * Results: * None. * * Side effects: * Adds paint to 'routeUse->cu_def'. * * ---------------------------------------------------------------------------- */ void gaStemPaint(routeUse, terminalLoc) CellUse *routeUse; NLTermLoc *terminalLoc; { TileTypeBitMask terminalLayerMask; /* Possible layers for stem at terminal */ TileTypeBitMask pinLayerMask; /* Possible layers for stem at pin */ Rect errArea; char *errReason; GCRPin *pin; short flags; /* * Find the pin used for this stem. If this pin wasn't actually * used by the global router, there's no point in routing a stem * to it so we return. */ pin = terminalLoc->nloc_pin; if (pin->gcr_pId == (GCRNet *) NULL) return; /* * Figure out which layers are OK to start routing and which * layers are OK to finish up on. Perform a sanity check: * if the destination layer isn't one of the legal routing * layers, just return. (This will catch pins that were * supposed to be routed by the channel router, but which * it was unable to connect to). */ flags = pin->gcr_ch->gcr_result[pin->gcr_x][pin->gcr_y]; if (!rtrStemMask(routeUse, terminalLoc, flags, &terminalLayerMask, &pinLayerMask)) { errReason = "Terminal is not on a legal routing layer"; GEO_EXPAND(&terminalLoc->nloc_rect, 1, &errArea); goto failure; } if (!TTMaskHasType(&pinLayerMask, RtrMetalType) && !TTMaskHasType(&pinLayerMask, RtrPolyType)) { /* To do: connect down to pin layer with contacts. */ /* Or, just let the maze router handle this. */ } /* * The terminal could be internal (terminalLoc->nloc_rect lies * inside a river-routing channel) or external (terminalLoc->nloc_rect * lies outside of a channel but the stem tip borders on a normal * routing channel). In the latter case, use the old stem * generation code (temporary measure until we get our own * code working). */ if (!RtrMazeStems && (pin->gcr_linked == (GCRPin *) NULL)) { /* Terminal didn't lie in a river-routing channel */ (void) RtrStemPaintExt(routeUse, terminalLoc); gaNumExtPaint++; return; } ASSERT(pin->gcr_linked->gcr_ch->gcr_type != CHAN_NORMAL, "gaStemPaint"); /* * Try a simple stem. */ if (!RtrMazeStems) { SimpleStem simple; Point *gridPoint = &(terminalLoc->nloc_stem); int side = terminalLoc->nloc_dir; if (gaStemSimpleInit(routeUse, terminalLoc, gridPoint, side, &simple)) { /* try ending on "metal" */ if (TTMaskHasType(&pinLayerMask, RtrMetalType)) { if(gaStemSimpleRoute(&simple,RtrMetalType,routeUse->cu_def)) { gaNumSimplePaint++; return; } } /* didn't work, so try ending on "poly" */ if (TTMaskHasType(&pinLayerMask, RtrPolyType)) { if(gaStemSimpleRoute(&simple,RtrPolyType,routeUse->cu_def)) { gaNumSimplePaint++; return; } } } } /* * Try the maze router. */ if (RtrMazeStems) { Point *pinPoint = &(terminalLoc->nloc_stem); int side = terminalLoc->nloc_dir; bool writeResult = TRUE; extern CellDef *gaMazeTopDef; /* Forward declaration quick hack. */ /* Note that by not running the gate array router, we may not */ /* have initialized the maze router at this point. */ if ((gaMazeTopDef == NULL) && (EditCellUse != NULL)) if (gaMazeInit(EditCellUse) == FALSE) goto totalLoss; if(gaMazeRoute(routeUse, terminalLoc, pinPoint, pinLayerMask, side, writeResult)) { gaNumMazePaint++; if(DebugIsSet(gaDebugID,gaDebShowMaze)) /* Feedback all maze routes so we can check them * (this will cause all maze routes to be reported as * routing errors) */ { Rect area; area = terminalLoc->nloc_rect; GeoIncludePoint(&terminalLoc->nloc_stem, &area); if (GEO_RECTNULL(&area)) { GEO_EXPAND(&area, 1, &area); } DBWFeedbackAdd(&area, "MAZE ROUTE", routeUse->cu_def, 1, STYLE_PALEHIGHLIGHTS); } return; } } /* * Total loss. * This should never happen! But there are a few cases when it can, * such as if we have given a difficult path to route from the channel, * over obstructions, to the pin, requiring the maze router, and the * maze router is not set up in the technology file. */ totalLoss: errReason = "Couldn't maze route final connection"; errArea = terminalLoc->nloc_rect; GeoIncludePoint(&terminalLoc->nloc_stem, &errArea); if (GEO_RECTNULL(&errArea)) { GEO_EXPAND(&errArea, 1, &errArea); } failure: DBWFeedbackAdd(&errArea, errReason, routeUse->cu_def, 1, STYLE_PALEHIGHLIGHTS); } magic-8.0.210/garouter/gaMain.c0000644000175000001440000004243510751423606014656 0ustar timusers/* * gaMain.c - * * Top-level of the gate-array router. * * For an overview of how routing systems work in general, see * the papers: * * "Magic's Obstacle-Avoiding Global Router", G.T. Hamachi and * J.K. Ousterhout, Proceedings of the 1985 Chapel Hill Conference * on VLSI, May 1985, pp. 393-418 * * "A Switchbox Router with Obstacle Avoidance", G.T. Hamachi * and J.K. Ousterhout, Proc 21st Design Automation Conference, * June 1984, pp. 173-179. * * "The PI (Placement and Interconnect) System", R.L. Rivest, * Proc 19th Design Automation Conference, June 1982, pp. 475-481. * * This router shares much code with the standard router in the "router" * module, and also makes use of the "grouter" (global-router) "gcr" * (channel-router), and "mzrouter" (maze-router) modules. * * The primary differences between this module and the "router" module * are that "garouter" allows the user to define channels explicitly * (rather than having them be generated automatically as they are in * the "router" module). These channels can overlap subcells arbitrarily, * unlike automatically generated channels which only appear in areas * where there are no subcells. * * User-specified channels can be specially identified as "river-routing" * channels. Unlike ordinary channels, these may contain routing terminals. * However, the routing across a river-routing channel is simpler than * that in an ordinary channel: tracks run either straight across horizontally, * for horizontal river routing channels, or vertically, for vertical * river routing channels, but never both. (See gcr.h for a description * of normal channels and the two kinds of river routing channels). * * Router organization: * ------------------- * * Routing is composed of a number of steps. First, the channels are * defined (by the user in this module) by calls to GADefineChannel(). * The remainder of the work is done in GARoute(), which: * * - reads the list of intended connections into a NLNetList * structure, * - generates "stems" for all terminals, * - sets up the channels for global routing, * - calls the global router to determine the sequence of channel * boundary points through which the route for each net will pass, * - calls the channel router to fill in the detailed routes for * each net in each channel structure, and then paint this * information back into the edit cell, * - generates paint for each stem generated at the start of routing * * The following sections briefly describe each of the above tasks in * a bit more detail: * * Nets and terminals: * ------------------ * * The connections that the router must make are described to it in * the form of a netlist, which comes from a text file that is either * generated outside of Magic or created using the netlist editor in * the "netmenu" module of Magic. Each "net" is a collection of named * terminals that must be connected. These terminals are described by * the hierarchical names of labels. Each terminal appears in exactly * one net. A given label may appear in several places in the same cell, * so a terminal may have several locations. The router assumes that all * of these locations are already electrically connected. * * * Channels and pins: * ----------------- * * This router is grid-based, meaning that wires are generated so that * their left-hand side and bottom align with evenly-spaced grid lines * in x and y. Two key structures, defined in gcr.h, represent the * routing problem in this grid-based world: the channel (GCRChannel) * and pin (GCRPin). Channels are rectangular areas with pins along * their boundaries: * * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * . . . . . . . * . +---X---------X---------X---------X---------X-----+ . * . | . . . . . | . * . | . . . . . | . * . . . X . P---------P---------P---------P---------P . . X . . * . | | . . . | | . * . | | . . . | | . * . | | . . . | | . * . . . X . P . . . . . . . . . . . . . . . . . . . P . . X . . * . | | . . . | | . * . | | . . . | | . * . | | . . . | | . * . . . X . P . . . . . . . . . . . . . . . . . . . P . . X . . * . | | . . . | | . * . | | . . . | | . * . | | . . . | | . * . . . X . P---------P---------P---------P---------P . . X . . * . | . . . . . | . * . +---X---------X---------X---------X---------X-----+ . * . . . . . . . * . . . . . . . * O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * * The dots indicate the grid lines. The set of grid points enclosed * by the channel is the inner dashed line. The actual channel boundary * lies between these grid lines and the next grid lines out. (To handle * the case where the grid spacing is odd, the boundary actually lies * at a location that is half the grid spacing (rounded down to the nearest * integer) DOWN and to the LEFT of a grid line, hence the asymmetry in * the diagram above. * * "Crossing points" lie along the channel boundary and are marked by X's. * Each crossing point has a pin associated with it; these pins are marked * by P's. (Note that the pins in the corners occupy the same grid * points but different crossing points; this reflects the fact that * the routing for a column and a track can overlap). * Each channel structure has four arrays of pins: one along each of its * LHS, RHS, and top and bottom (indexed as 1, 2, ... in order of * increasing x or y as appropriate; the 0th element of the pin * arrays is not used). * * When two channels share a common boundary, a single crossing * point may be associated with two pins: one in each channel. * During channel initialization (below), those pairs of pins * that share a crossing point are made to point to each other. * * * Stem generation: * --------------- * * Although the router is grid based, terminals in cells need not be * aligned to the routing grid. Stem generation is the process of * finding one (or two) channel pin(s) that are reachable from each * terminal in the routing problem, and marking these pins with the * net to which the terminal belongs. If a terminal lies in the middle * of a river-routing channel, up to two pins will be assigned to it * (on opposite sides of the channel). Otherwise, (e.g., if the terminal * is inside a cell but not in any channel) only one pin will be assigned, * in the channel closest to the terminal. * * Stem generation actually has two parts. The first only determines * if a stem CAN be run from a terminal to a pin, but doesn't generate * any paint, since not all terminals will necessarily be used by * the global router. (For example, if a terminal appears in more * than one place in a cell, it may be that only one of these places * is actually connected by the router). The second part of stem * generation, invoked after channel routing is complete, actually * paints the stems into the edit cell. * * Since the stem generator has no way of knowing which layer the * channel router will use for a signal it routes to a pin, it must * be possible for the final stems to connect to either routing * layer. The stem generator checks to ensure that it can connect * to either layer during the first part, and rejects pins it can't * reach on either layer (unless the area of the pin itself is covered * by one layer, in which case the stem only has to be able to connect * to the free layer). * * The code for stem generation is split between this module (for * stems inside river-routing channels), the "router" module (for * stems for terminals outside of any channel), and the "mzrouter" * module (used to determine when stems can be routed, if it isn't * obvious). * * Global routing: * -------------- * * Initially, all the pins in each channel are marked as not belonging * to any net, except for the pins that were assigned to terminals by * stem generation. The job of the global router is to find paths * (as sequences of pins) for all nets, and to mark the pins on a * given net's path with that net's identifier. These channels * and marked pins will be used as the input to the channel router. * * Channel routing: * --------------- * * Each channel structure contains a two-dimensional array with one * element for each internal grid point in the channel. The channel * router accepts a channel whose pins have been marked with net * identifiers, and fills in this internal array with flags indicating * the type of material/contact to place at that grid location. After * all channels have been routed, we use the information in these * internal arrays to generate actual paint for the edit cell. Since * channels are routed independently of what material is in adjacent * channels, sometimes it is necessary during this paintback to add * contacts at channel boundaries to switch routing layers. * * * ********************************************************************* * * 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/garouter/gaMain.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/hash.h" #include "utils/heap.h" #include "tiles/tile.h" #include "database/database.h" #include "windows/windows.h" #include "utils/main.h" #include "dbwind/dbwind.h" #include "utils/signals.h" #include "netmenu/netmenu.h" #include "gcr/gcr.h" #include "router/router.h" #include "grouter/grouter.h" #include "garouter/garouter.h" #include "utils/netlist.h" #include "textio/textio.h" #include "debug/debug.h" #include "drc/drc.h" /* * ---------------------------------------------------------------------------- * * GARouteCmd -- * * Top-level procedure for the gate-array router. * Routes the cell 'routeUse->cu_def' using the netlist 'netListName'. * * Results: * Returns the number of routing errors left as feedback. * Returning -1 means that routing was unable to commence * because of other errors (e.g, the netlist couldn't be * read) which were already reported to the user. * * Side effects: * Leaves paint in routeUse->cu_def. Leaves feedback where routing * errors occurred. Frees all the memory associated with channel * structures when done. * * ---------------------------------------------------------------------------- */ int GARouteCmd(routeUse, netListName) CellUse *routeUse; char *netListName; { int errs; NLNetList netList; GCRChannel *ch; NLNet *net; /* Initialize ga maze routing */ if(gaMazeInit(routeUse)==FALSE) { TxError("Could not initialize maze router.\n"); return(-1); } /* Ensure that there are channels defined */ if (gaChannelList == (GCRChannel *) NULL) { TxError("Must define channels before routing.\n"); return (-1); } /* Read the netlist */ if (gaBuildNetList(netListName, routeUse, &netList) < 0) return (-1); if (SigInterruptPending) goto done; /* Figure out the size of the routing area */ RouteArea.r_xbot = RouteArea.r_ybot = INFINITY; RouteArea.r_xtop = RouteArea.r_ytop = MINFINITY; for (ch = gaChannelList; ch && !SigInterruptPending; ch = ch->gcr_next) (void) GeoIncludeAll(&ch->gcr_area, &RouteArea); for (net = netList.nnl_nets; net; net = net->nnet_next) (void) GeoIncludeAll(&net->nnet_area, &RouteArea); errs = GARoute(gaChannelList, routeUse, &netList); done: /* Cleanup */ NLFree(&netList); GAClearChannels(); return (errs); } /* * ---------------------------------------------------------------------------- * * GARoute -- * * Routes the cell 'routeUse->cu_def' using the netlist 'netList'. * The list of channels is 'list'. These channels are fresh from * being allocated by GCRNewChannel(). * * Results: * Returns the number of routing errors left as feedback. * Returning -1 means that routing was unable to commence * because of other errors (e.g, the netlist couldn't be * read) which were already reported to the user. * * Side effects: * Leaves paint in routeUse->cu_def. Leaves feedback where routing * errors occurred. Frees all the memory associated with channel * structures when done. * * ---------------------------------------------------------------------------- */ int GARoute(list, routeUse, netList) GCRChannel *list; /* List of channels */ CellUse *routeUse; /* Cell being routed */ NLNetList *netList; /* List of nets to route */ { int feedCount = DBWFeedbackCount, errs; GCRChannel *ch; /* * Initialize all the pointers in the channel structure (stem assignment), * and also determine which tracks are available for river-routing * in channels so marked (CHAN_HRIVER or CHAN_VRIVER). */ gaChannelInit(list, routeUse, netList); if (SigInterruptPending || DebugIsSet(gaDebugID, gaDebChanOnly) || DebugIsSet(glDebugID, glDebStemsOnly)) goto done; /* Perform global routing */ RtrMilestoneStart("Global routing"); GlGlobalRoute(list, netList); RtrMilestoneDone(); if (SigInterruptPending || DebugIsSet(glDebugID, glDebGreedy)) goto done; /* Channel routing */ errs = 0; RtrMilestoneStart("Channel routing"); for (ch = list; ch && !SigInterruptPending; ch = ch->gcr_next) RtrChannelRoute(ch, &errs); RtrMilestoneDone(); if (errs > 0) TxError("%d bad connection%s.\n", errs, errs != 1 ? "s" : ""); if (SigInterruptPending) goto done; /* Paint results in a separate pass */ RtrMilestoneStart("Painting results"); for (ch = list; ch && !SigInterruptPending; ch = ch->gcr_next) { RtrMilestonePrint(); RtrPaintBack(ch, routeUse->cu_def); /* update bounding box NOW so searches during stem gen. * work correctly. */ DBReComputeBbox(routeUse->cu_def); } RtrMilestoneDone(); if (SigInterruptPending) goto done; if (DebugIsSet(gaDebugID, gaDebPaintStems)) { DRCCheckThis(routeUse->cu_def, TT_CHECKPAINT, &RouteArea); DBWAreaChanged(routeUse->cu_def, &RouteArea, DBW_ALLWINDOWS, &DBAllButSpaceBits); WindUpdate(); TxMore("After channel paintback"); } gaStemPaintAll(routeUse, netList); /* * Mark the areas modified. * Only areas inside the routing channels are actually affected. */ SigDisableInterrupts(); /* recomp bbox again just in case stem gen changed it (unlikely) */ DBReComputeBbox(routeUse->cu_def); DRCCheckThis(routeUse->cu_def, TT_CHECKPAINT, &RouteArea); DBWAreaChanged(routeUse->cu_def, &RouteArea, DBW_ALLWINDOWS, &DBAllButSpaceBits); SigEnableInterrupts(); done: /* Return number of errors */ return (DBWFeedbackCount - feedCount); } /* * ---------------------------------------------------------------------------- * * gaBuildNetList -- * * Construct the netlist that will be used for routing. * Use netListName if supplied; otherwise use the name of * the current netlist; if neither are set, use the name * of the cell 'routeUse->cu_def'. * * Leaves the constructed netlist in 'netList'. * * Results: * Returns the number of nets in netList. If there were * no nets, returns 0. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ int gaBuildNetList(netListName, routeUse, netList) char *netListName; CellUse *routeUse; NLNetList *netList; { CellDef *routeDef = routeUse->cu_def; int numNets; /* Select the netlist */ if (netListName == NULL) { if (!NMHasList()) { netListName = routeDef->cd_name; TxPrintf("No netlist selected yet; using \"%s\".\n", netListName); NMNewNetlist(netListName); } else netListName = NMNetlistName(); } else NMNewNetlist(netListName); if (DebugIsSet(gaDebugID, gaDebVerbose)) TxPrintf("Reading netlist %s.\n", netListName); RtrMilestoneStart("Building netlist"); numNets = NLBuild(routeUse, netList); RtrMilestoneDone(); if (numNets == 0) TxError("No nets to route.\n"); if (DebugIsSet(gaDebugID, gaDebVerbose)) TxPrintf("Read %d nets.\n", numNets); return (numNets); } magic-8.0.210/garouter/gaChannel.c0000644000175000001440000004300010751423606015327 0ustar timusers/* * gaChannel.c - * * Channel management for the gate-array router. * * ********************************************************************* * * 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/garouter/gaChannel.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "utils/hash.h" #include "utils/heap.h" #include "tiles/tile.h" #include "database/database.h" #include "windows/windows.h" #include "utils/main.h" #include "dbwind/dbwind.h" #include "utils/signals.h" #include "netmenu/netmenu.h" #include "gcr/gcr.h" #include "router/router.h" #include "grouter/grouter.h" #include "garouter/garouter.h" #include "utils/netlist.h" #include "textio/textio.h" #include "utils/styles.h" #include "debug/debug.h" /* List of all active channels */ GCRChannel *gaChannelList = NULL; /* Def used to hold channel plane */ CellDef *gaChannelDef = NULL; /* Forward declarations */ int gaSplitTile(); int gaSetClient(); void gaChannelStats(); void gaPinStats(); void gaPropagateBlockages(); void gaInitRiverBlockages(); #define CNULL ((ClientData) NULL) int gaTotNormCross, gaTotRiverCross, gaClearNormCross, gaClearRiverCross; /* * ---------------------------------------------------------------------------- * * GAChannelInitOnce -- * * Once-only channel initialization for the gate-array router. * * Results: * None. * * Side effects: * Allocates the tile plane used to hold channel information, * RtrChannelPlane. * * ---------------------------------------------------------------------------- */ void GAChannelInitOnce() { if (gaChannelDef == NULL) gaChannelDef = RtrFindChannelDef(); RtrChannelPlane = gaChannelDef->cd_planes[PL_DRC_ERROR]; GAClearChannels(); } /* * ---------------------------------------------------------------------------- * * GAClearChannels -- * * Clear any pre-existing channels in preparation for definition of * new ones. * * Results: * None. * * Side effects: * Paints TileType 1 (blocked) over the tile plane that records all * available channel area, and frees all channel structures. * * ---------------------------------------------------------------------------- */ void GAClearChannels() { GCRChannel *ch; Rect r; r.r_xbot = TiPlaneRect.r_xbot / 2; r.r_ybot = TiPlaneRect.r_ybot / 2; r.r_xtop = TiPlaneRect.r_xtop / 2; r.r_ytop = TiPlaneRect.r_ytop / 2; SigDisableInterrupts(); (void) DBPaintPlane(RtrChannelPlane, &r, DBStdWriteTbl(1), (PaintUndoInfo *) NULL); for (ch = gaChannelList; ch; ch = ch->gcr_next) GCRFreeChannel(ch); gaChannelList = (GCRChannel *) NULL; SigEnableInterrupts(); } /* * ---------------------------------------------------------------------------- * * GADefineChannel -- * * Add a new channel definition to the list of channels we know * about. First ensure that the channel boundaries are correctly * aligned (round down if they aren't) and also that the area of * this channel has not already been assigned to another channel. * * The parameter chanType is one of 0 (for an ordinary channel), * CHAN_HRIVER (for a horizontal river-routing channel), or CHAN_VRIVER * (for a vertical river-routing channel). * * The rectangle 'r' gives the area of the channel. * * Results: * TRUE on success, FALSE on failure. * * Side effects: * Paints the area of this channel into RtrChannelPlane (as space) * to mark that this area is used. * * ---------------------------------------------------------------------------- */ bool GADefineChannel(chanType, r) int chanType; Rect *r; { int length, width, halfGrid = RtrGridSpacing / 2; GCRChannel *ch; Point origin; Rect r2; /* * Make the channel boundaries lie halfway between grid lines. * To ensure consistent results when RtrGridSpacing is odd, * we always subtract halfGrid from a grid line. */ r2 = *r; r->r_xbot = RTR_GRIDUP(r->r_xbot, RtrOrigin.p_x) - halfGrid; r->r_ybot = RTR_GRIDUP(r->r_ybot, RtrOrigin.p_y) - halfGrid; r->r_xtop = RTR_GRIDDOWN(r->r_xtop, RtrOrigin.p_x) + RtrGridSpacing - halfGrid; r->r_ytop = RTR_GRIDDOWN(r->r_ytop, RtrOrigin.p_y) + RtrGridSpacing - halfGrid; if (r2.r_xbot != r->r_xbot || r2.r_ybot != r->r_ybot || r2.r_xtop != r->r_xtop || r2.r_ytop != r->r_ytop) { TxPrintf("Rounding channel to center-grid alignment: "); TxPrintf("ll=(%d,%d) ur=(%d,%d)\n", r->r_xbot, r->r_ybot, r->r_xtop, r->r_ytop); } /* Ensure no overlap */ if (DBSrPaintArea((Tile *) NULL, RtrChannelPlane, r, &DBSpaceBits, gaAlwaysOne, (ClientData) NULL)) { TxError("Channel ll=(%d,%d) ur=(%d,%d) overlaps existing channels\n", r->r_xbot, r->r_ybot, r->r_xtop, r->r_ytop); return (FALSE); } if (DebugIsSet(gaDebugID, gaDebShowChans)) DBWFeedbackAdd(r, "Channel area", EditCellUse->cu_def, 1, STYLE_OUTLINEHIGHLIGHTS); /* Paint it into the channel plane */ SigDisableInterrupts(); (void) DBPaintPlane(RtrChannelPlane, r, DBStdWriteTbl(TT_SPACE), (PaintUndoInfo *) NULL); /* Allocate the new channel */ RtrChannelBounds(r, &length, &width, &origin); ch = GCRNewChannel(length, width); ch->gcr_area = *r; ch->gcr_origin = origin; ch->gcr_type = chanType; /* Link it in with the pre-existing list */ ch->gcr_next = gaChannelList; gaChannelList = ch; SigEnableInterrupts(); return (TRUE); } /* * ---------------------------------------------------------------------------- * * gaChannelInit -- * * Called immediately prior to routing to set up lots of useful * information in channels: * * Tile plane initialization: * - Carve up the tile plane so each channel corresponds to a * single space tile, and unavailable areas correspond to * tiles of type 1. * - Make the ti_client fields of tiles in the channel plane * point to their corresponding channels. * * Obstacle initialization: * - Initialize the obstacle and hazard maps for each channel. * Identify pins too close to two-layer blockages and mark * them as already taken (by net GCR_BLOCKEDNETID). * - For river-routing channels, ensure that pairs of pins * can be river-routed to each other; if not, mark both * as unavailable. * * Pin initialization (including stem assignment): * - Fill in the global-routing information in the channel * structure. Specifically, set gcr_ch, gcr_side, gcr_linked, * and gcr_point for each GCRPin. Link available pins for * each side of the channel into a doubly-linked list so * they can be visited easily during global routing. * * Results: * None. * * Side effects: * Fills in a lot of information in the channel structures. * * ---------------------------------------------------------------------------- */ void gaChannelInit(list, routeUse, netList) GCRChannel *list; /* List of channels to process */ CellUse *routeUse; /* Cell being routed (searched for obstacles) */ NLNetList *netList; /* Netlist being routed */ { GCRChannel *ch; RtrMilestoneStart("Obstacle map initialization"); for (ch = list; ch && !SigInterruptPending; ch = ch->gcr_next) { /* Ensure that no channel tiles cross channel boundaries */ while (DBSrPaintArea((Tile *) NULL, RtrChannelPlane, &ch->gcr_area, &DBAllTypeBits, gaSplitTile, (ClientData) &ch->gcr_area)) /* Nothing */; /* Obstacle initialization */ RtrMilestonePrint(); RtrChannelObstacles(routeUse, ch); if (ch->gcr_type == CHAN_NORMAL) RtrChannelDensity(ch); RtrChannelCleanObstacles(ch); } RtrMilestoneDone(); /* * Set all ti_client fields in the channel plane to NULL, and then * for each channel set the ti_client fields of the tiles it overlaps * to point back to that channel. */ (void) DBSrPaintArea((Tile *) NULL, RtrChannelPlane, &TiPlaneRect, &DBAllTypeBits, gaSetClient, (ClientData) NULL); for (ch = list; ch && !SigInterruptPending; ch = ch->gcr_next) (void) DBSrPaintArea((Tile *) NULL, RtrChannelPlane, &ch->gcr_area, &DBAllTypeBits, gaSetClient, (ClientData) ch); if (SigInterruptPending) return; /* * Pin initialization. * This fills in a bunch of information needed for global * routing in each pin along each channel boundary. */ for (ch = list; ch && !SigInterruptPending; ch = ch->gcr_next) RtrPinsInit(ch); /* * Pick the actual pin locations for terminals. * This comes here because it needs the blockage and gcr_linked * information set above. However, it must precede marking * pairs of river-routing crossings as unavailable, since * these pairs are only marked unavailable for routes across * the channel. They may still be usable as stem tips, so * we can't block them until after stems have been assigned. */ gaStemAssignAll(routeUse, netList); if (SigInterruptPending) return; /* * Now mark pairs of river-routing crossings as unavailable. * A crossing is unavailable if a straight-across from one side * of the channel to the other on a single layer is impossible. * Propagate these blockages.. */ for (ch = list; ch && !SigInterruptPending; ch = ch->gcr_next) if (ch->gcr_type != CHAN_NORMAL) gaInitRiverBlockages(routeUse, ch); gaPropagateBlockages(list); if (SigInterruptPending) return; /* * Hazard initialization. * This has to happen after blockages have been propagated. */ RtrMilestoneStart("Hazard initialization"); for (ch = list; ch && !SigInterruptPending; ch = ch->gcr_next) if (ch->gcr_type == CHAN_NORMAL) { RtrHazards(ch); RtrMilestonePrint(); } RtrMilestoneDone(); /* * Link all the available pins along each side of each * channel into a linked list. Only unblocked pins with * non-NULL gcr_linked pins are linked into this list. * Since pins taken as stem tips by gaAssignPins above * were marked, these lists don't include any pins that * are stem tips. */ for (ch = list; ch && !SigInterruptPending; ch = ch->gcr_next) RtrPinsLink(ch); if (DebugIsSet(gaDebugID, gaDebChanStats)) gaChannelStats(list); } void gaChannelStats(list) GCRChannel *list; { GCRChannel *ch; int *tot, *clear, numTot, numClear; double fNorm, fRiver, fTot; gaTotNormCross = 0; gaTotRiverCross = 0; gaClearNormCross = 0; gaClearRiverCross = 0; for (ch = list; ch; ch = ch->gcr_next) { switch (ch->gcr_type) { case CHAN_NORMAL: tot = &gaTotNormCross; clear = &gaClearNormCross; break; case CHAN_HRIVER: case CHAN_VRIVER: tot = &gaTotRiverCross; clear = &gaClearRiverCross; break; } gaPinStats(ch->gcr_tPins, ch->gcr_length, tot, clear); gaPinStats(ch->gcr_bPins, ch->gcr_length, tot, clear); gaPinStats(ch->gcr_lPins, ch->gcr_width, tot, clear); gaPinStats(ch->gcr_rPins, ch->gcr_width, tot, clear); } numTot = gaTotRiverCross + gaTotNormCross; numClear = gaClearRiverCross + gaClearNormCross; fRiver = ((double) gaClearRiverCross / (double) gaTotRiverCross) * 100.0; fNorm = ((double) gaClearNormCross / (double) gaTotNormCross) * 100.0; fTot = ((double) numClear / (double) numTot) * 100.0; TxPrintf("Total pins: %d, clear: %d (%.1f%%)\n", numTot, numClear, fTot); TxPrintf("Norm chan pins: %d, clear: %d (%.1f%%)\n", gaTotNormCross, gaClearNormCross, fNorm); TxPrintf("River chan pins: %d, clear: %d (%.1f%%)\n", gaTotRiverCross, gaClearRiverCross, fRiver); } void gaPinStats(pins, nPins, pTot, pClear) GCRPin *pins; int nPins; int *pTot, *pClear; { GCRPin *pin, *pend; pin = &pins[1]; pend = &pins[nPins]; for ( ; pin <= pend; pin++) { *pTot += 1; if (pin->gcr_linked && pin->gcr_pId == (GCRNet *) NULL && pin->gcr_linked->gcr_pId == (GCRNet *) NULL) { *pClear += 1; } } } /* * ---------------------------------------------------------------------------- * * gaPropagateBlockages -- * * If a pin is blocked on one side of a channel BOUNDARY, * it is blocked on the other side as well. If a pin on * one side of a river-routing CHANNEL is blocked, the pin * on the other side gets blocked too. Several iterations * may be necessary to propagate blockages across all * channel boundaries and river-routing channels. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void gaPropagateBlockages(list) GCRChannel *list; { GCRChannel *ch; bool changed; do { changed = FALSE; for (ch = list; ch; ch = ch->gcr_next) if (RtrPinsBlock(ch)) changed = TRUE; } while (changed); } /* * ---------------------------------------------------------------------------- * * gaSetClient -- * * Called for each tile overlapping ch->gcr_area to set the * client pointer for that tile to 'cdata'. * * Results: * Always returns 0. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ int gaSetClient(tile, cdata) Tile *tile; ClientData cdata; { tile->ti_client = (ClientData) cdata; return (0); } /* * ---------------------------------------------------------------------------- * * gaSplitTile -- * * Called for each tile overlapping the area of a channel (the Rect 'r'), * we ensure that no tiles cross the channel boundary. If one does, we * split it at the boundary and return 1. * * Results: * Returns 1 if tile was split, or 0 if no split occurred. * We return 1 to ensure that DBSrPaintArea doesn't get * confused from our having modified the tile plane. * * Side effects: * May split 'tile'; if it does, we return 1. * * ---------------------------------------------------------------------------- */ int gaSplitTile(tile, r) Tile *tile; Rect *r; { Tile *tp; ASSERT(TiGetType(tile) == TT_SPACE, "gaSplitTile"); if (TOP(tile) > r->r_ytop) { tp = TiSplitY(tile, r->r_ytop); TiSetBody(tp, TT_SPACE); return (1); } if (BOTTOM(tile) < r->r_ybot) { tp = TiSplitY(tile, r->r_ybot); TiSetBody(tp, TT_SPACE); return (1); } if (LEFT(tile) < r->r_xbot) { tp = TiSplitX(tile, r->r_xbot); TiSetBody(tp, TT_SPACE); return (1); } if (RIGHT(tile) > r->r_xtop) { tp = TiSplitX(tile, r->r_xtop); TiSetBody(tp, TT_SPACE); return (1); } return (0); } /* * ---------------------------------------------------------------------------- * * gaInitRiverBlockages -- * * The channel 'ch' is a river-routing channel (ch->gcr_type is either * CHAN_HRIVER or CHAN_VRIVER). These channels can only be routed * across in a single direction (horizontally for CHAN_HRIVER, or * vertically for CHAN_VRIVER). * * If pins have already been taken by terminals (as stem tips), we * don't mark them as blocked. * * Results: * None. * * Side effects: * Marks pairs of pins on the channel boundary as blocked if * a river-route across the channel is not possible along * the track that runs between the pin pair. Blocked pins * have a special gcr_pId of GCR_BLOCKEDNETID to mark them as * "in use". * * ---------------------------------------------------------------------------- */ void gaInitRiverBlockages(routeUse, ch) CellUse *routeUse; GCRChannel *ch; { GCRPin *p1, *p2; int n, nPins, coord; SearchContext scx; switch (ch->gcr_type) { case CHAN_HRIVER: p1 = &ch->gcr_lPins[1]; p2 = &ch->gcr_rPins[1]; nPins = ch->gcr_width; scx.scx_area.r_xbot = ch->gcr_area.r_xbot; scx.scx_area.r_xtop = ch->gcr_area.r_xtop; coord = ch->gcr_origin.p_y + RtrGridSpacing; break; case CHAN_VRIVER: p1 = &ch->gcr_tPins[1]; p2 = &ch->gcr_bPins[1]; nPins = ch->gcr_length; scx.scx_area.r_ybot = ch->gcr_area.r_ybot; scx.scx_area.r_ytop = ch->gcr_area.r_ytop; coord = ch->gcr_origin.p_x + RtrGridSpacing; break; } scx.scx_use = routeUse; scx.scx_trans = GeoIdentityTransform; for (n = 1; n <= nPins; n++, p1++, p2++, coord += RtrGridSpacing) { switch (ch->gcr_type) { case CHAN_HRIVER: scx.scx_area.r_ybot = coord - RtrSubcellSepUp; scx.scx_area.r_ytop = coord + RtrSubcellSepDown; break; case CHAN_VRIVER: scx.scx_area.r_xbot = coord - RtrSubcellSepUp; scx.scx_area.r_xtop = coord + RtrSubcellSepDown; break; } /* * If obstacles to both routing layers are found, * then block this pair of crossing points if they * aren't already taken. */ if (DBTreeSrTiles(&scx, &RtrMetalObstacles, 0, gaAlwaysOne, CNULL) && DBTreeSrTiles(&scx, &RtrPolyObstacles, 0, gaAlwaysOne, CNULL)) { if (p1->gcr_pId == (GCRNet *) NULL) p1->gcr_pId = GCR_BLOCKEDNETID; if (p2->gcr_pId == (GCRNet *) NULL) p2->gcr_pId = GCR_BLOCKEDNETID; } } } int gaAlwaysOne() { return (1); } magic-8.0.210/garouter/garouter.h0000644000175000001440000000634410751423606015316 0ustar timusers/* * garouter.h -- * * Header file for the gate-array router. * * ********************************************************************* * * 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. * * ********************************************************************* * * rcsid $Header: /usr/cvsroot/magic-8.0/garouter/garouter.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ */ #ifndef _GAROUTER_H #define _GAROUTER_H #include "grouter/grouter.h" /* * The following structure describes "simple stems" -- routes * from a terminal to a grid point that are of a very simple * style, involving a straight-across wire and at most one * contact at either end. */ typedef struct { TileType sw_type; /* Type of wire */ Rect sw_long; /* Wire all the way to dest */ Rect sw_short; /* Wire only to pin contact */ Rect sw_pinStub; /* Wire from pin contact to pin */ bool sw_longOK; /* Space exists for long wire */ bool sw_shortOK; /* Space exists for short wire (implied * if sw_longOK is TRUE). */ } SimpleWire; typedef struct { /* Terminal */ TileType ss_termType; Rect ss_termArea; TileTypeBitMask ss_termMask; /* If ss_termType is a contact type, * this mask contains both metal and * poly; otherwise, it contains just * ss_termType. */ /* Pin */ int ss_dir; Point ss_pinPoint; /* Information describing the wires to paint */ SimpleWire ss_metalWire; /* Metal wire */ SimpleWire ss_polyWire; /* Poly wire */ /* Contacts */ Rect ss_cTerm; /* Contact over terminal */ bool ss_cTermOK; /* Contact over terminal is OK */ Rect ss_cPin; /* Contact near pin */ bool ss_cPinOK; /* Contact near pin is OK */ } SimpleStem; /* List of all active channels */ extern GCRChannel *gaChannelList; /* Def used to hold channel plane */ extern CellDef *gaChannelDef; /* Used during stem generation */ extern int gaMinAbove; extern int gaMaxAbove, gaMaxBelow; /* Debugging information */ extern bool gaInitialized; /* TRUE if registered with debug module */ extern ClientData gaDebugID; /* Our identity with the debugging module */ #include "gaDebug.h" /* Can add flags without total recompile */ /* Internal procedures */ extern GCRChannel *gaStemContainingChannel(); extern GCRPin *gaStemCheckPin(); extern int gaAlwaysOne(); extern bool gaMazeRoute(); /* Exported procedures */ extern int GARoute(); extern void GAChannelInitOnce(); extern void GAClearChannels(); extern bool GADefineChannel(); extern bool GAMazeInitParms(); /* Exported variables */ extern bool GAStemWarn; #endif /* _GAROUTER_H */ magic-8.0.210/garouter/gaDebug.h0000644000175000001440000000266610751423606015027 0ustar timusers/* * gaDebug.h -- * * Definitions of debugging flags for the gate-array router. * This is a separate include file so that new debugging flags * can be added to it without forcing recompilation of the * entire module. * * ********************************************************************* * * 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. * * ********************************************************************* * * rcsid $Header: /usr/cvsroot/magic-8.0/garouter/gaDebug.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ */ /* Flags */ extern int gaDebChanOnly; extern int gaDebChanStats; extern int gaDebMaze; extern int gaDebNoSimple; extern int gaDebPaintStems; extern int gaDebShowChans; extern int gaDebShowMaze; extern int gaDebStems; extern int gaDebVerbose; extern int gaDebNoClean; magic-8.0.210/sim/0000755000175000001440000000000012032325053012235 5ustar timusersmagic-8.0.210/sim/Makefile0000644000175000001440000000025610751423606013711 0ustar timusers# # rscid $Header: # MODULE = sim MAGICDIR = .. SRCS = SimDBstuff.c SimSelect.c SimRsim.c SimExtract.c include ${MAGICDIR}/defs.mak include ${MAGICDIR}/rules.mak magic-8.0.210/sim/sim.h0000644000175000001440000000134010751423606013205 0ustar timusers#ifndef _SIM_H #define _SIM_H #include "utils/magic.h" extern char *SimGetNodeCommand(); extern char *SimGetNodeName(); extern char *SimSelectNode(); extern bool SimGetReplyLine(); extern void SimRsimIt(); extern void SimEraseLabels(); extern bool efPreferredName(); extern void SimRsimHandler(); extern void SimInit(); extern bool SimRecomputeSel; extern bool SimInitGetnode; extern bool SimGetnodeAlias; extern bool SimSawAbortString; extern bool SimRsimRunning; extern bool SimIsGetnode; extern bool SimHasCoords; extern bool SimUseCoords; extern bool SimIgnoreGlobals; extern HashTable SimNodeNameTbl; extern HashTable SimGNAliasTbl; extern HashTable SimGetnodeTbl; extern HashTable SimAbortSeenTbl; #endif /* _SIM_H */ magic-8.0.210/sim/SimRsim.c0000664000175000001440000005500412027341350013774 0ustar timusers/* * SimRsim.c - * * This file provides routines for Magic to communicate with Rsim/Irsim. * Communications takes place using two pipes, one for Magic to * send a command to the simulator, the other to get back the reply. * * ********************************************************************* * * 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. * * ********************************************************************* * of California. All rights reserved. * */ #ifdef RSIM_MODULE #include #include #include #include #include #include #include #include #include #include "utils/magic.h" #include "utils/stack.h" #include "utils/geometry.h" #include "utils/utils.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/signals.h" #include "utils/styles.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "sim/sim.h" #include static bool InitRsim(); #define BUF_SIZE 1024 #define LINEBUF_SIZE 256 #define READBUF_SIZE 4096 + LINEBUF_SIZE #define E_RUNNING "Simulator already running.\n" #define E_PIPE1OP "Could not create Magic to Rsim pipe.\n" #define E_PIPE2OP "Could not create Rsim to Magic pipe.\n" #define E_NOFORK "Could not fork process.\n" #define E_NOSTART "Rsim not started.\n" #define E_PIPERD "Error reading pipe from Rsim.\n" #define E_PIPEWR "Could not write on pipe to Rsim.\n" #define P_READ 0 #define P_WRITE 1 static int status; static int pipeIn; /* Rsim --> Magic */ static int pipeOut; /* Magic --> Rsim */ static char keyBoardBuf[BUF_SIZE]; static bool RsimJustStarted = TRUE; static char rsim_prompt[20]; static int prompt_len; static int rsim_pid; bool SimRsimRunning = FALSE; bool SimHasCoords = FALSE; bool SimGetReplyLine(); /* Forward declaration */ void SimStopRsim(); /* *----------------------------------------------------------------------- * SimGetNodeCommand * * This function returns the "full" name of the rsim command if 'cmd' * should be applied to the selected node(s) or NULL if the command * should be shipped without any node names. * * Results: * A ptr to the command name or NULL. * * Side effects: * None. *----------------------------------------------------------------------- */ char * SimGetNodeCommand(cmd) char *cmd; { /* This table is used to define which Rsim commands are applied to * each node in the selection. Depending on the command, you * woudn't want to send a command to rsim for each node. For example * given the "s" command (to step the clock), you wouldn't want to * step the clock once for every node in the selection. */ static char *RsimNodeCommands[] = { "?", "!", "analyzer", "d", "h", "l", "path", "t", "u", "w", "x", NULL }; int cmdNum; cmdNum = Lookup( cmd, RsimNodeCommands ); cmd = (cmdNum >= 0) ? RsimNodeCommands[cmdNum] : (char *) NULL; return( cmd ); } /* *----------------------------------------------------------------------- * SimStartRsim * * This procedure is used to fork the rsim process. It takes a list of * arguements to pass to rsim when initiating the fork. The * environment variable RSIM is first checked to find the pathname for * rsim/irsim. If this variable does not exist, then BIN_DIR/irsim * is then used. * * Results: * TRUE if the fork was successful. * * Side effects: * None. *----------------------------------------------------------------------- */ bool SimStartRsim(argv) char *argv[]; /* list of rsim args for the fork */ { int child; int magToRsimPipe[2]; int rsimToMagPipe[2]; char *getenv(); char rsimfile[256]; char *cad = BIN_DIR; char *src, *dst; /* don't start another rsim if one is already running */ if (SimRsimRunning) { TxPrintf(E_RUNNING); return(FALSE); } /* Create the pipes. One is for Magic sending to rsim, the other * is for rsim sending to Magic. */ if (pipe(magToRsimPipe) < 0) { TxPrintf(E_PIPE1OP); return(FALSE); } if (pipe(rsimToMagPipe) < 0) { TxPrintf(E_PIPE2OP); return(FALSE); } /* Look for rsim; check for environ var first; if none, then * try to open the one located in BIN_DIR. */ src = getenv("RSIM"); if( src != NULL ) strcpy(rsimfile, src); else { src = cad; dst = rsimfile; if (PaExpand(&src, &dst, 100) == -1) { TxError ("Could not find " BIN_DIR "\n"); return(FALSE); } strcat(rsimfile, "/irsim"); } #ifndef NO_ACCESS_CALL if( access( rsimfile, 1 ) != 0 ) { TxPrintf("can not execute '%s'\n", rsimfile ); return(FALSE); } #endif FORK(child); /* #ifdef SYSV child = fork(); #else child = vfork(); #endif */ if (child == -1) { close(magToRsimPipe[P_READ]); close(magToRsimPipe[P_WRITE]); close(rsimToMagPipe[P_READ]); close(rsimToMagPipe[P_WRITE]); TxPrintf(E_NOFORK); return(FALSE); } if (child > 0) { /* This is the parent */ SimRsimRunning = TRUE; close(magToRsimPipe[P_READ]); close(rsimToMagPipe[P_WRITE]); pipeIn = rsimToMagPipe[P_READ]; pipeOut = magToRsimPipe[P_WRITE]; rsim_pid = child; } else { int i; /* This is the child */ close(magToRsimPipe[P_WRITE]); close(rsimToMagPipe[P_READ]); dup2(magToRsimPipe[P_READ], fileno(stdin)); dup2(rsimToMagPipe[P_WRITE], fileno(stderr)); dup2(rsimToMagPipe[P_WRITE], fileno(stdout)); for( i = 3; i < 15; i++ ) close( i ); /* try our best, folks..... */ execvp(rsimfile, argv); _exit(5); /* pick a number, any number */ } return(FALSE); /* to keep lint happy */ } /* *----------------------------------------------------------------------- * SimConnectRsim * * This procedure is called when Magic is sending commands to Rsim and * awaiting a reply. The reply is retrieved by successive calls * to SimGetReplyLine() which returns one line of the reply at a time. * * Magic sends a command to Rsim through one pipe, and * Rsim's reply comes back from the other pipe. * * Results: * None. * * Side effects: * The reply generated by Rsim is printed. * The reply buffer from SimGetReplyLine is statically allocated. * Subsequent calls will change the contents of this buffer. * *----------------------------------------------------------------------- */ void SimConnectRsim(escRsim) bool escRsim; /* TRUE if we should escape back to Magic */ { static char HELLO_MSG[] = "Type \"q\" to quit simulator or \".\" to escape back to Magic.\n"; char *replyLine; /* used to hold one line of the Rsim reply */ if (!SimRsimRunning) { TxPrintf(E_NOSTART); return; } /* read the header of the rsim reply and determine the prompt */ if( RsimJustStarted ) { if( ! InitRsim( escRsim ? NULL : HELLO_MSG ) ) return; } if (escRsim) { RsimJustStarted = FALSE; return; } if (!RsimJustStarted) { TxPrintf("%s", HELLO_MSG); } while (TRUE) { /* exceptions can toggle this flag. */ if (!SimRsimRunning) { return; } TxPrintf("%s", rsim_prompt); /* Read the user's command for Rsim */ if (TxGetLine(keyBoardBuf, BUF_SIZE) == 0) keyBoardBuf[0] = 0; /* prepare the Rsim command string */ strcat(keyBoardBuf, "\n"); /* check to see if we quit Rsim or escape back to Magic */ if ((keyBoardBuf[0] == '.') && (keyBoardBuf[1] == '\n')) { RsimJustStarted = FALSE; return; } if ((keyBoardBuf[0] == 'q') && (keyBoardBuf[1] == '\n')) { SimStopRsim(); return; } /* Send the command to Rsim and get the reply. */ if (write(pipeOut, keyBoardBuf, strlen(keyBoardBuf)) < 0) { TxPrintf(E_PIPEWR); SimStopRsim(); return; } if (!SimGetReplyLine(&replyLine)) { return; } while (replyLine != NULL) { TxPrintf("%s\n",replyLine); if (!SimGetReplyLine(&replyLine)) { return; } } } } /* *----------------------------------------------------------------------- * InitRsim * Read the initial header from rsim and determine the prompt. * The prompt is found by searching for the string enclosed * the last "\n" and "> ". * * Results: * Returns TRUE if rsim started correctly, else FALSE. * * Side effects: * Sets the rsim prompt and length. *----------------------------------------------------------------------- */ bool InitRsim(hello_msg) char *hello_msg; { char buff[READBUF_SIZE]; char *last; int nchars; bool first_time = TRUE; prompt_len = 0; do { nchars = 0; last = buff; if( SimFillBuffer( buff, &last, &nchars ) <= 0 ) { SimStopRsim(); /* rsim must have died */ TxPrintf( "\n" ); return( FALSE ); } buff[nchars] = '\0'; if( last[-1] == '>' && *last == ' ' ) { for( last--; last > buff && last[-1] != '\n'; last-- ); strcpy( rsim_prompt, last ); prompt_len = strlen( rsim_prompt ); *last = '\0'; } if( first_time ) { TxPrintf("Be sure your sim file matches the root cell of this window.\n"); if( hello_msg ) TxPrintf( "%s", hello_msg ); first_time = FALSE; } if( *buff ) TxPrintf( "%s", buff ); } while( prompt_len == 0 ); if( write( pipeOut, "has_coords\n", 11 ) < 0 ) { TxPrintf(E_PIPEWR); SimStopRsim(); return(FALSE); } SimHasCoords = FALSE; do { if( ! SimGetReplyLine( &last ) ) return( FALSE ); if( last != NULL && strncmp( last, "YES", 3 ) == 0 ) SimHasCoords = TRUE; } while( last ); return( TRUE ); } /* *----------------------------------------------------------------------- * SimStopRsim * * This procedure is called to kill off the Rsim process. The * exit condition is checked and a message is printed if necessary. * * Results: * None. * * Side effects: * The child Rsim process is killed. * *----------------------------------------------------------------------- */ void SimStopRsim() { int pid; if (SimRsimRunning) { /* closing the pipes to Rsim have the effect of killing it */ close(pipeOut); close(pipeIn); /* set the Rsim state flags */ RsimJustStarted = TRUE; SimRsimRunning = FALSE; kill(rsim_pid, SIGHUP); /* just in case rsim hangs */ if (WaitPid (rsim_pid, &status) == -1) return; pid = rsim_pid; switch (status & 0xFF) { case 0 : break; case 2 : TxPrintf("Simulator interrupted.\n"); break; default : TxPrintf("Simulator terminated abnormally.\n"); break; } } } /* *----------------------------------------------------------------------- * RsimErrorMsg * * This procedure prints out an error message. * * Results: * None. * * Side effects: * None. * *----------------------------------------------------------------------- */ void RsimErrorMsg() { static char msg[] = "The simulator must be running before this command " "can be executed. To do\n" "this enter the command \"rsim \". " "To escape back to\n" "Magic enter \".\" in response to the simulator prompt.\n"; TxPrintf("%s", msg); } /* *----------------------------------------------------------------------- * SimRsimIt * * This procedure takes an Rsim command and a node name to apply * the command to, constructs a complete Rsim command and sends it * to Rsim to process. * * Results: * None. * * Side effects: * Everything is set up so that GetReplyLine() should be called * after this routine to read the Rsim output for each node. * The reply buffer is statically allocated. Subsequent calls will * change the contents of this buffer. * *----------------------------------------------------------------------- */ void SimRsimIt(cmd, nodeName) char *cmd; char *nodeName; { static char cmdStr[256]; static char cleanName[256]; char *strptr; cmdStr[0] = 0; if (!SimRsimRunning) { RsimErrorMsg(); return; } /* change the node name to a form Rsim will accept. That is: * if CHANGE_SQBRACKET is defined (it really should not) then * "[" and "]" in the path name must be changed to a "." Also, the * trailing "#" of Magic generated node names must also be removed. */ strcpy(cleanName, nodeName); strptr = cleanName; while (*strptr != 0) { #ifdef CHANGE_SQBRACKET if ((*strptr == '[') || (*strptr == ']')) *strptr = '.'; #endif strptr++; } if (*--strptr == '#') { *strptr = 0; } sprintf(cmdStr, "%s %s\n", cmd, cleanName); /* send the command to Rsim */ if (write(pipeOut, cmdStr, strlen(cmdStr)) < 0) { TxPrintf(E_PIPEWR); SimStopRsim(); } } /* *----------------------------------------------------------------------- * SimFillBuffer * * This procedure reads characters from Rsim via a pipe and * places the characters into a buffer pointed by pLastChar. * It is assumed the buffer is at least READBUF_SIZE charcters * large, and that charCount contains the number of charcters * which remain unprocessed in the buffer. * If an interrupt is received while waiting for input from * rsim, then the signal is propagated to rsim and we try the * read again; this should get the simulator to its top level * command parser (or kill it depending on the simulator). * * Results: * Number of characters read into the buffer. * * Side effects: * pLastChar is updated to point to the last valid character * in the buffer. charCount is also updated to contain the * total number of unprocessed characters in the buffer. * Some i/o may take place. * *----------------------------------------------------------------------- */ int SimFillBuffer(buffHead, pLastChar, charCount) char *buffHead; /* ptr to start of buffer */ char **pLastChar; /* used to return ptr to last char * in the buffer. */ int *charCount; /* number of chars in the buffer */ { int charsRead = 0; char *temp; int n, nfd; #if defined(SYSV) || defined(CYGWIN) || defined(__FreeBSD__) || defined(__APPLE__) fd_set readfds, writefds, exceptfds; #else int nr, nex; #endif /* SYSV */ struct timeval timeout; /* Set the timeout to 5 seconds so we don't block indefinitely if */ /* something goes wrong with the pipe. */ timeout.tv_sec = 5; timeout.tv_usec = 0; /* read reply from Rsim */ #if defined(SYSV) || defined(CYGWIN) || defined(__FreeBSD__) || defined(__APPLE__) FD_ZERO(&readfds); FD_ZERO(&exceptfds); #endif /* SYSV */ nfd = pipeIn + 1; try_again: #if defined(SYSV) || defined(CYGWIN) || defined(__FreeBSD__) || defined(__APPLE__) FD_SET(pipeIn, &readfds); FD_ZERO(&writefds); FD_SET(pipeIn, &exceptfds); n = select(nfd, &readfds, &writefds, &exceptfds, &timeout); #else /* !SYSV */ nr = nex = 1 << pipeIn; n = select(nfd, &nr, (int *) NULL, &nex, &timeout); #endif if (n == 0) return 0; /* select() timed out */ else if (n < 0) { if (errno == EINTR) { if (SigInterruptPending) { kill(rsim_pid, SIGINT); SigInterruptPending = FALSE; } goto try_again; } } temp = *pLastChar; charsRead = read(pipeIn, temp, (READBUF_SIZE - 1 - *charCount)); if (charsRead > 0) { temp += charsRead; if (*charCount == 0) { temp--; } *pLastChar = temp; *charCount += charsRead; } ASSERT(((buffHead + READBUF_SIZE) > *pLastChar), "SimFillBuffer"); return(charsRead); } /* *----------------------------------------------------------------------- * SimShiftChars * * This procedure shifts unprocessed charcters in a buffer * to the beginning of the buffer and updates the head and * tail pointers to the valid buffer characters. * * Results: * None. * * Side effects: * Valid data in the buffer is shifted to the beginning of * the buffer. * *----------------------------------------------------------------------- */ void SimShiftChars(buffStart, lineStart, lastChar) char *buffStart; /* beginning of buffer */ char **lineStart; /* ptr to first valid char in buffer */ char **lastChar; /* ptr to last valid char in buffer */ { char *temp; char *temp1; if (buffStart == *lineStart) { return; } for (temp = buffStart, temp1 = *lineStart; temp1 <= *lastChar;) { *temp++ = *temp1++; } temp--; *lineStart = buffStart; *lastChar = temp; } /* *----------------------------------------------------------------------- * SimFindNewLine * * This procedure searches for a '\n' in the char buffer delimited by * buffStart and buffEnd. * * Results: * returns a ptr to the '\n' in the buffer. If no '\n' is found, * NULL is returned. * * Side effects: * None. * *----------------------------------------------------------------------- */ char * SimFindNewLine(buffStart, buffEnd) char *buffStart; /* first char in buffer */ char *buffEnd; /* last char in buffer */ { char *sp; for (sp = buffStart; sp <= buffEnd; sp++) { if (*sp == '\n') { return(sp); } } return(NULL); } /* *----------------------------------------------------------------------- * SimGetReplyLine * * This procedure returns the next line of an Rsim reply. It does this * by maintaining a character buffer to read the Rsim reply. This * buffer is scanned for '\n' which delimit lines, and lines are * returned from this buffer. This routine automatically refills * the reply buffer if no '\n' charcters are found. Head and tail * pointers to the "unprocessed" charcters in the buffer (those * characters beloning to a reply line in the buffer which has not * yet been returned) are maintained. * * We assume that the longest line Rsim will return is less than * 256 characters, and that at most 4K characters can be read * from a pipe in one read call. * * Results: * SimGetReplyLine returns TRUE if replyLine is a valid value, * otherwise it is FALSE. * If we find a line containing only the rsim prompt, replyLine * points to a NULL pointer and TRUE is returned. * * Side effects: * replyLine contains a pointer to the next Rsim reply line. * The buffer returned by replyLine is statically allcoated, so * subsequent calls to this routine will change this buffer. * *----------------------------------------------------------------------- */ bool SimGetReplyLine(replyLine) char **replyLine; { static char simReadBuff[READBUF_SIZE]; /* buffer in which to read the * rsim reply before processing * it. This is big enough for * one incomplete Rsim line * (256 chars) and for the * additional read from the * pipe to complete the line * (4K chars). */ static char *lineStart = simReadBuff; /* points to the first character * of the next reply line. */ static char *lastChar = simReadBuff; /* points the the last valid * char in the input buffer. */ static int charsInBuff = 0; /* number of characters left * in input buffer to process. */ char *strptr; char *strptr1; /* keep reading characters until we have at least enough for a prompt */ while (charsInBuff < prompt_len) { SimShiftChars(simReadBuff, &lineStart, &lastChar); status = SimFillBuffer(simReadBuff, &lastChar, &charsInBuff); if (status == 0) { /* no more characters to read; stop Rsim */ SimStopRsim(); *replyLine = NULL; return(FALSE); } if (status < 0) { TxPrintf(E_PIPERD); *replyLine = NULL; return(FALSE); } } /* check for the prompt at the end of the buffer, if found then * reset buffer pointers and character count. */ if (!(strncmp(rsim_prompt, lineStart, prompt_len))) { lineStart = lastChar = simReadBuff; charsInBuff = 0; *replyLine = NULL; return(TRUE); } /* Now try to extract a line out of the buffer. */ strptr = SimFindNewLine(lineStart, lastChar); if (!strptr) { /* haven't found a '\n' in the buffer yet */ SimShiftChars(simReadBuff, &lineStart, &lastChar); strptr1 = lastChar; /* keep trying to read characters until we find a '\n'; we * are assuming rsim reply lines are no more than LINEBUF_SIZE * characters in length. */ while (TRUE) { strptr = SimFindNewLine(lineStart, lastChar); if ((charsInBuff > LINEBUF_SIZE) || (strptr)) { break; } strptr1 = lastChar; status = SimFillBuffer(simReadBuff, &lastChar, &charsInBuff); if (status == 0) { /* no more characters to read; stop Rsim */ SimStopRsim(); *replyLine = NULL; return(FALSE); } if (status < 0) { TxPrintf(E_PIPERD); *replyLine = NULL; return(FALSE); } } } if (!strptr) { TxPrintf("Error in SimGetReplyLine -- Rsim line longer than 256 chars\n"); *replyLine = NULL; return(FALSE); } *strptr = 0; /* change the '\n' to a NULL */ strptr1 = lineStart; /* string to return */ lineStart = strptr + 1; /* start of next line */ charsInBuff -= (strlen(strptr1) + 1); /* + 1 because of the '\n' */ if (charsInBuff == 0) { /* reset buffer pointers */ lineStart = lastChar = simReadBuff; } *replyLine = strptr1; return(TRUE); } /* ---------------------------------------------------------------------------- * * SimInit -- * * Initialize this module. * * Results: * None. * * Side Effects: * Just initialization. * * ---------------------------------------------------------------------------- */ void SimInit() { static char *rsimdoc = "You are currently using the \"rsim\" tool. The button actions are:\n\ left - move the box so its lower-left corner is at cursor position\n\ right - resize box by moving upper-right corner to cursor position\n\ middle - display the Rsim node values of the selected paint\n\ You can move or resize the box by different corners by pressing left\n\ or right, holding it down, moving the cursor near a different corner\n\ and clicking the other (left or right) button down then up without\n\ releasing the initial button. Rsim must already have been started\n\ to display the node values on the circuit.\n"; DBWAddButtonHandler("rsim", SimRsimHandler, STYLE_CURS_RSIM, rsimdoc); } #endif /* RSIM_MODULE */ magic-8.0.210/sim/SimDBstuff.c0000664000175000001440000007537511745550372014450 0ustar timusers /* SimDBstuff.c - * * This file contains routines that extract electrically connected * regions of a layout for Magic. This extractor operates * hierarchically, across cell boundaries (SimTreeCopyConnect), as * well as within a single cell (SimSrConnect). * * This also contains routines corresponding to those in the DBWind * module. * * ********************************************************************* * * 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. * * ********************************************************************* * University of California */ #include #include #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 "textio/textio.h" #include "utils/signals.h" #include "utils/malloc.h" #include "extract/extractInt.h" #include "sim/sim.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "commands/commands.h" #include "textio/txcommands.h" #include "utils/styles.h" #include "graphics/graphics.h" /* The following structure is used to hold several pieces * of information that must be passed through multiple * levels of search function. */ struct conSrArg { CellDef *csa_def; /* Definition being searched. */ Plane *csa_plane; /* Current plane being searched. */ TileTypeBitMask *csa_connect; /* Table indicating what connects * to what. */ int (*csa_clientFunc)(); /* Client function to call. */ ClientData csa_clientData; /* Argument for clientFunc. */ bool csa_clear; /* FALSE means pass 1, TRUE * means pass 2. */ Rect csa_bounds; /* Area that limits search. */ }; /* For SimTreeSrConnect, the extraction proceeds in one pass, copying * all connected stuff from a hierarchy into a single cell. A list * is kept to record areas that still have to be searched for * hierarchical stuff. */ typedef struct { Rect area; /* Area to process */ TileTypeBitMask *connectMask; /* Connection mask for search */ TileType dinfo; /* Info about triangular search areas */ } conSrArea; struct conSrArg2 { CellUse *csa2_use; /* Destination use */ TileTypeBitMask *csa2_connect; /* Table indicating what connects * to what. */ Rect *csa2_bounds; /* Area that limits the search */ conSrArea *csa2_list; /* List of areas to process */ int csa2_top; /* Index of next area to process */ int csa2_size; /* Max. number bins in area list */ }; #define CSA2_LIST_START_SIZE 256 /* Forward declarations */ extern char *DBPrintUseId(); extern int dbcUnconnectFunc(); extern void SimInitScxStk(); extern void SimPopScx(); extern void SimMakePathname(); static char bestName[256]; /* * ---------------------------------------------------------------------------- * * SimConnectFunc * * This procedure is based upon the function dbcConnectFunc in the * database module. * * This procedure is invoked by SimTreeSrTiles from SimTreeCopyConnect, * whenever a tile is found that is connected to the current area * being processed. If the tile overlaps the search area in a non- * trivial way (i.e. more than a 1x1 square of overlap at a corner) * then the area of the tile is added onto the list of things to check. * The "non-trivial" overlap check is needed to prevent caddy-corner * tiles from being considered as connected. * * Results: * Returns 0 normally, 1 if an abort condition has been encountered. * * Side effects: * Paints into the destination definition. * * ---------------------------------------------------------------------------- */ int SimConnectFunc(tile, cx) Tile *tile; /* Tile found. */ TreeContext *cx; /* Describes context of search. The client * data is a pointer to the list head of * the conSrArg2's describing the areas * left to check. */ { struct conSrArg2 *csa2; Rect tileArea, *srArea, newarea; SearchContext *scx = cx->tc_scx; TileTypeBitMask notConnectMask, *connectMask; TileType loctype, ctype; TileType dinfo = 0; int i, pNum; static char nodeName[256]; CellDef *def; TerminalPath *tpath = cx->tc_filter->tf_tpath; TiToRect(tile, &tileArea); srArea = &scx->scx_area; if (((tileArea.r_xbot >= srArea->r_xtop-1) || (tileArea.r_xtop <= srArea->r_xbot+1)) && ((tileArea.r_ybot >= srArea->r_ytop-1) || (tileArea.r_ytop <= srArea->r_ybot+1))) { /* If the search area is only one unit wide or tall, then it's * OK to have only a small overlap. This happens only when * looking for an initial search tile. */ if (((srArea->r_xtop-1) != srArea->r_xbot) && ((srArea->r_ytop-1) != srArea->r_ybot)) return 0; } GeoTransRect(&scx->scx_trans, &tileArea, &newarea); /* Clip the current area down to something that overlaps the * area of interest. */ csa2 = (struct conSrArg2 *)cx->tc_filter->tf_arg; GeoClip(&newarea, csa2->csa2_bounds); if (GEO_RECTNULL(&newarea)) return 0; /* Stuff unique to the nodename search follows. */ if (tpath != (TerminalPath *)NULL) { /* Extract the node name */ char *n = tpath->tp_next; char c = *n; SigDisableInterrupts(); strcpy(nodeName, SimGetNodeName(cx->tc_scx, tile, tpath->tp_first)); SigEnableInterrupts(); *n = c; /* save the "best" name for this node */ if (bestName[0] == '\0' || efPreferredName(nodeName, bestName)) strcpy(bestName, nodeName); } loctype = TiGetTypeExact(tile); /* Resolve geometric transformations on diagonally-split tiles */ if (IsSplit(tile)) { dinfo = DBTransformDiagonal(loctype, &scx->scx_trans); loctype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile); } /* See if the destination cell contains stuff over the whole * current area (on its home plane) that is connected to it. * If so, then there's no need to process the current area, * since any processing that is needed was already done before. */ pNum = DBPlane(loctype); connectMask = &csa2->csa2_connect[loctype]; if (DBIsContact(loctype)) { TileTypeBitMask *rMask = DBResidueMask(loctype); TileTypeBitMask *cMask; TTMaskSetOnlyType(¬ConnectMask, loctype); /* Differenct contact types may share residues (6/18/04) */ for (ctype = TT_TECHDEPBASE; ctype < DBNumUserLayers; ctype++) { if (DBIsContact(ctype)) { cMask = DBResidueMask(ctype); if (TTMaskIntersect(rMask, cMask)) TTMaskSetType(¬ConnectMask, ctype); } } /* The mask of contact types must include all stacked contacts */ for (ctype = DBNumUserLayers; ctype < DBNumTypes; ctype++) { cMask = DBResidueMask(ctype); if TTMaskHasType(cMask, loctype) TTMaskSetType(¬ConnectMask, ctype); } TTMaskCom(¬ConnectMask); } else { TTMaskCom2(¬ConnectMask, connectMask); } def = csa2->csa2_use->cu_def; if (DBSrPaintNMArea((Tile *) NULL, def->cd_planes[pNum], dinfo, &newarea, ¬ConnectMask, dbcUnconnectFunc, (ClientData) connectMask) == 0) return 0; /* Paint this tile into the destination cell. */ DBNMPaintPlane(def->cd_planes[pNum], dinfo, &newarea, DBStdPaintTbl(loctype, pNum), (PaintUndoInfo *) NULL); /* Since the whole area of this tile hasn't been recorded, * we must process its area to find any other tiles that * connect to it. Add each of them to the list of things * to process. We have to expand the search area by 1 unit * on all sides because SimTreeSrTiles only returns things * that overlap the search area, and we want things that * even just touch. */ /* Only extend those sides bordering the diagonal tile */ if (dinfo & TT_DIAGONAL) { if (dinfo & TT_SIDE) /* right */ newarea.r_xtop += 1; else /* left */ newarea.r_xbot -= 1; if (((dinfo & TT_SIDE) >> 1) == (dinfo & TT_DIRECTION)) /* top */ newarea.r_ytop += 1; else /* bottom */ newarea.r_ybot -= 1; } else { newarea.r_xbot -= 1; newarea.r_ybot -= 1; newarea.r_xtop += 1; newarea.r_ytop += 1; } /* Abort the name search if the name is in the abort name search table * or if the name is global and the SimIgnoreGlobals flag is not set. */ if (SimSawAbortString || SigInterruptPending) return 1; else if (SimIsGetnode && !SimIgnoreGlobals) { i = strlen(nodeName); if (nodeName[i - 1] == '!') return 1; } /* Register the area and connection mask as needing to be processed */ if (++csa2->csa2_top == csa2->csa2_size) { /* Reached list size limit---need to enlarge the list */ /* Double the size of the list every time we hit the limit */ conSrArea *newlist; int i, lastsize = csa2->csa2_size; csa2->csa2_size *= 2; newlist = (conSrArea *)mallocMagic(csa2->csa2_size * sizeof(conSrArea)); for (i = 0; i < lastsize; i++) { newlist[i].area = csa2->csa2_list[i].area; newlist[i].connectMask = csa2->csa2_list[i].connectMask; newlist[i].dinfo = csa2->csa2_list[i].dinfo; } freeMagic((char *)csa2->csa2_list); csa2->csa2_list = newlist; } csa2->csa2_list[csa2->csa2_top].area = newarea; csa2->csa2_list[csa2->csa2_top].connectMask = connectMask; csa2->csa2_list[csa2->csa2_top].dinfo = dinfo; return 0; } /* * ---------------------------------------------------------------------------- * * SimTreeCopyConnect * * This procedure is very similar to DBTreeCopyConnect. * * This procedure copies connected information from a given cell * hierarchy to a given (flat) cell. Starting from the tile underneath * the given area, this procedure finds all paint in all cells * that is connected to that information. All such paint is * copied into the result cell. If there are several electrically * distinct nets underneath the given area, one of them is picked * at more-or-less random. * * Modified so the result cell is NOT first cleared of all paint. This * allows multiple calls, to highlight incomplete routing nets. * * Results: * None. * * Side effects: * The contents of the result cell are modified. * * ---------------------------------------------------------------------------- */ #define MAXPATHNAME 256 void SimTreeCopyConnect(scx, mask, xMask, connect, area, destUse, Node_Name) SearchContext *scx; /* Describes starting area. The * scx_use field gives the root of * the hierarchy to search, and the * scx_area field gives the starting * area. An initial tile must overlap * this area. The transform is from * coords of scx_use to destUse. */ TileTypeBitMask *mask; /* Tile types to start from in area. */ int xMask; /* Information must be expanded in all * of the windows indicated by this * mask. Use 0 to consider all info * regardless of expansion. */ TileTypeBitMask *connect; /* Points to table that defines what * each tile type is considered to * connect to. Use DBConnectTbl as * a default. */ Rect *area; /* The resulting information is * clipped to this area. Pass * TiPlaneRect to get everything. */ CellUse *destUse; /* Result use in which to place * anything connected to material of * type mask in area of rootUse. */ char *Node_Name; /* Name of node returned. * NOTE: Don't call this "NodeName", * because that conflicts with reserved * words in some compilers. */ { TerminalPath tpath; char pathName[MAXPATHNAME]; TileTypeBitMask *newmask; struct conSrArg2 csa2; TileType newtype; csa2.csa2_use = destUse; csa2.csa2_bounds = area; csa2.csa2_connect = connect; csa2.csa2_size = CSA2_LIST_START_SIZE; csa2.csa2_list = (conSrArea *)mallocMagic(CSA2_LIST_START_SIZE * sizeof(conSrArea)); csa2.csa2_top = -1; tpath.tp_first = tpath.tp_next = pathName; tpath.tp_last = pathName + MAXPATHNAME; pathName[0] = '\0'; bestName[0] = '\0'; (void) SimTreeSrTiles(scx, mask, xMask, &tpath, SimConnectFunc, (ClientData) &csa2); while (csa2.csa2_top >= 0) { newmask = csa2.csa2_list[csa2.csa2_top].connectMask; scx->scx_area = csa2.csa2_list[csa2.csa2_top].area; newtype = csa2.csa2_list[csa2.csa2_top].dinfo; csa2.csa2_top--; if (newtype & TT_DIAGONAL) SimTreeSrNMTiles(scx, newtype, newmask, xMask, &tpath, SimConnectFunc, (ClientData) &csa2); else SimTreeSrTiles(scx, newmask, xMask, &tpath, SimConnectFunc, (ClientData) &csa2); } freeMagic((char *)csa2.csa2_list); /* Recompute the bounding box of the destination and record * its area for redisplay. */ strcpy(Node_Name, bestName); DBReComputeBbox(destUse->cu_def); } /* * ---------------------------------------------------------------------------- * * efPreferredName -- * * This is the same function used in the ext2sim module. We need this * function for the rsim interface to Magic. * * Determine which of two names is more preferred. The most preferred * name is a global name. Given two non-global names, the one with the * fewest pathname components is the most preferred. If the two names * have equally many pathname components, we choose the shortest. * * Results: * TRUE if 'name1' is preferable to 'name2', FALSE if not. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool efPreferredName(name1, name2) char *name1, *name2; { int nslashes1, nslashes2; char *np1, *np2; if( name1[0] == '@' && name1[1] == '=' ) return( TRUE ); else if( name2[0] == '@' && name2[1] == '=' ) return( FALSE ); for (nslashes1 = 0, np1 = name1; *np1; ) { if (*np1++ == '/') nslashes1++; } for (nslashes2 = 0, np2 = name2; *np2; ) { if (*np2++ == '/') nslashes2++; } --np1; --np2; if (!SimIgnoreGlobals) { /* both are global names */ if ((*np1 == '!') && (*np2 == '!')) { /* check # of pathname components */ if (nslashes1 < nslashes2) return (TRUE); if (nslashes1 > nslashes2) return (FALSE); /* same # of pathname components; check length */ if (np1 - name1 < np2 - name2) return (TRUE); if (np1 - name1 > np2 - name2) return (FALSE); /* same # of pathname components; same length; use lex order */ if (strcmp(name1, name2) > 0) return(TRUE); else return(FALSE); } if (*np1 == '!') return(TRUE); if (*np2 == '!') return(FALSE); } /* neither name is global */ /* chose label over generated name */ if (*np1 != '#' && *np2 == '#') return (TRUE); if (*np1 == '#' && *np2 != '#') return (FALSE); /* either both are labels or generated names */ /* check pathname components */ if (nslashes1 < nslashes2) return (TRUE); if (nslashes1 > nslashes2) return (FALSE); /* same # of pathname components; check length */ if (np1 - name1 < np2 - name2) return (TRUE); if (np1 - name1 > np2 - name2) return (FALSE); /* same # of pathname components; same length; use lex ordering */ if (strcmp(name1, name2) > 0) return(TRUE); else return(FALSE); } /* * ---------------------------------------------------------------------------- * * SimSrConnect * * This is similar to the procedure DBSrConnect, except that the * marks on each tile in the cell are not erased. * * Search through a cell to find all paint that is electrically * connected to things in a given starting area. * * Results: * 0 is returned if the search finished normally. 1 is returned * if the search was aborted. * * Side effects: * The search starts from one (random) non-space tile in "startArea" * that matches the types in the mask parameter. For every paint * tile that is electrically connected to the initial tile and that * intersects the rectangle "bounds", func is called. Func should * have the following form: * * int * func(tile, clientData) * Tile *tile; * ClientData clientData; * { * } * * The clientData passed to func is the same one that was passed * to us. Func returns 0 under normal conditions; if it returns * 1 then the search is aborted. * * *** WARNING *** * * Func should not modify any paint during the search, since this * will mess up pointers kept by these procedures and likely cause * a core-dump. * * ---------------------------------------------------------------------------- */ int SimSrConnect(def, startArea, mask, connect, bounds, func, clientData) CellDef *def; /* Cell definition in which to carry out * the connectivity search. Only paint * in this definition is considered. */ Rect *startArea; /* Area to search for an initial tile. Only * tiles OVERLAPPING the area are considered. * This area should have positive x and y * dimensions. */ TileTypeBitMask *mask; /* Only tiles of one of these types are used * as initial tiles. */ TileTypeBitMask *connect; /* Pointer to a table indicating what tile * types connect to what other tile types. * Each entry gives a mask of types that * connect to tiles of a given type. */ Rect *bounds; /* Area, in coords of scx->scx_use->cu_def, * that limits the search: only tiles * overalapping this area will be returned. * Use TiPlaneRect to search everywhere. */ int (*func)(); /* Function to apply at each connected tile. */ ClientData clientData; /* Client data for above function. */ { struct conSrArg csa; int startPlane, result; Tile *startTile; /* Starting tile for search. */ extern int dbSrConnectFunc(); /* Forward declaration. */ extern int dbSrConnectStartFunc(); result = 0; csa.csa_def = def; csa.csa_bounds = *bounds; /* Find a starting tile (if there are many tiles underneath the * starting area, pick any one). The search function just saves * the tile address and returns. */ startTile = NULL; for (startPlane = PL_TECHDEPBASE; startPlane < DBNumPlanes; startPlane++) { if (DBSrPaintArea((Tile *) NULL, def->cd_planes[startPlane], startArea, mask, dbSrConnectStartFunc, (ClientData) &startTile) != 0) break; } if (startTile == NULL) return 0; /* Pass 1. During this pass the client function gets called. */ csa.csa_clientFunc = func; csa.csa_clientData = clientData; csa.csa_clear = FALSE; csa.csa_connect = connect; csa.csa_plane = def->cd_planes[startPlane]; if (dbSrConnectFunc(startTile, &csa) != 0) result = 1; return result; } /* *----------------------------------------------------------------------------- * * SimTreeSrTiles * * Similar to the procedure DBTreeSrTiles, although having a terminal * path similar to procedure DBTreeSrLabels. * * Recursively search downward from the supplied CellUse for * all visible paint tiles matching the supplied type mask. * * The procedure should be of the following form: * int * func(tile, cxp) * Tile *tile; * TreeContext *cxp; * { * } * * The SearchContext is stored in cxp->tc_scx, the user's arg is stored * in cxp->tc_filter->tf_arg, and the terminal path is stored in * cxp->tc_filter->tf_tpath. * * In the above, the scx transform is the net transform from the coordinates * of tile to "world" coordinates (or whatever coordinates the initial * transform supplied to SimTreeSrTiles was a transform to). Func returns * 0 under normal conditions. If 1 is returned, it is a request to * abort the search. * * *** WARNING *** * * The client procedure should not modify any of the paint planes in * the cells visited by SimTreeSrTiles, because we use DBSrPaintArea * instead of TiSrArea as our paint-tile enumeration function. * * Results: * 0 is returned if the search finished normally. 1 is returned * if the search was aborted. * * Side effects: * Whatever side effects are brought about by applying the * procedure supplied. * *----------------------------------------------------------------------------- */ int SimTreeSrTiles(scx, mask, xMask, tpath, func, cdarg) SearchContext *scx; /* Pointer to search context specifying * a cell use to search, an area in the * coordinates of the cell's def, and a * transform back to "root" coordinates. */ TileTypeBitMask *mask; /* Only tiles with a type for which * a bit in this mask is on are processed. */ int xMask; /* All subcells are visited recursively * until we encounter uses whose flags, * when anded with xMask, are not * equal to xMask. */ TerminalPath *tpath; /* Pointer to a structure describing a * partially filled-in terminal pathname. * Add new components as encountered. */ int (*func)(); /* Function to apply at each qualifying tile */ ClientData cdarg; /* Client data for above function */ { int SimCellTileSrFunc(); TreeFilter filter; filter.tf_func = func; filter.tf_arg = cdarg; filter.tf_mask = mask; filter.tf_xmask = xMask; filter.tf_planes = DBTechTypesToPlanes(mask); filter.tf_tpath = tpath; filter.tf_dinfo = 0; return SimCellTileSrFunc(scx, &filter); } /* * SimTreeSrNMTiles --- * This is a variant of the above in which the search is over * a non-Manhattan triangular area. */ int SimTreeSrNMTiles(scx, dinfo, mask, xMask, tpath, func, cdarg) SearchContext *scx; /* Pointer to search context specifying * a cell use to search, an area in the * coordinates of the cell's def, and a * transform back to "root" coordinates. */ TileType dinfo; /* Type containing information about the * triangular area to search. */ TileTypeBitMask *mask; /* Only tiles with a type for which * a bit in this mask is on are processed. */ int xMask; /* All subcells are visited recursively * until we encounter uses whose flags, * when anded with xMask, are not * equal to xMask. */ TerminalPath *tpath; /* Pointer to a structure describing a * partially filled-in terminal pathname. * Add new components as encountered. */ int (*func)(); /* Function to apply at each qualifying tile */ ClientData cdarg; /* Client data for above function */ { int SimCellTileSrFunc(); TreeFilter filter; filter.tf_func = func; filter.tf_arg = cdarg; filter.tf_mask = mask; filter.tf_xmask = xMask; filter.tf_dinfo = dinfo; filter.tf_planes = DBTechTypesToPlanes(mask); filter.tf_tpath = tpath; return SimCellTileSrFunc(scx, &filter); } /* * Filter procedure applied to subcells by SimTreeSrTiles(). */ int SimCellTileSrFunc(scx, fp) SearchContext *scx; TreeFilter *fp; { TreeContext context; TerminalPath *tp; CellDef *def = scx->scx_use->cu_def; int pNum, result; char *tnext; ASSERT(def != (CellDef *) NULL, "SimCellTileSrFunc"); if (!DBDescendSubcell(scx->scx_use, fp->tf_xmask)) return 0; if ((def->cd_flags & CDAVAILABLE) == 0) if (!DBCellRead(def, (char *) NULL, TRUE)) return 0; context.tc_scx = scx; context.tc_filter = fp; /* Create the path prefix */ /* Don't prepend the "Topmost cell" ID of the top-level cell. */ if ((fp->tf_tpath != (TerminalPath *)NULL) && (scx->scx_use->cu_parent != NULL)) { tp = fp->tf_tpath; tnext = tp->tp_next; tp->tp_next = DBPrintUseId(scx, tp->tp_next, tp->tp_last - tp->tp_next, FALSE); if (tp->tp_next < tp->tp_last) { *(tp->tp_next++) = '/'; *(tp->tp_next) = '\0'; } } /* * Apply the function first to any of the tiles in the planes * for this CellUse's CellDef that match the mask. */ result = 0; for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++) if (PlaneMaskHasPlane(fp->tf_planes, pNum)) { if (fp->tf_dinfo & TT_DIAGONAL) { TileType dinfo = DBTransformDiagonal(fp->tf_dinfo, &scx->scx_trans); if (DBSrPaintNMArea((Tile *) NULL, def->cd_planes[pNum], dinfo, &scx->scx_area, fp->tf_mask, fp->tf_func, (ClientData) &context)) { result = 1; goto cleanup; } } else if (DBSrPaintArea((Tile *) NULL, def->cd_planes[pNum], &scx->scx_area, fp->tf_mask, fp->tf_func, (ClientData) &context)) { result = 1; goto cleanup; } } /* * Now apply ourselves recursively to each of the CellUses * in our tile plane. */ if (DBCellSrArea(scx, SimCellTileSrFunc, (ClientData) fp)) result = 1; cleanup: /* Remove the trailing pathname component from the TerminalPath */ if ((fp->tf_tpath != (TerminalPath *)NULL) && (scx->scx_use->cu_parent != NULL)) { fp->tf_tpath->tp_next = tnext; *tnext = '\0'; } return (result); } /* * ---------------------------------------------------------------------------- * * SimPutLabel -- * * Same as DBPutLabel, except this does not set the cell modified flag. * * Place a rectangular label in the database, in a particular cell. * * It is the responsibility of higher-level routines to insure that * the material to which the label is being attached really exists at * this point in the cell, and that TT_SPACE is used if there is * no single material covering the label's entire area. The routine * DBAdjustLabels is useful for this. * * Results: * The return value is the actual alignment position used for * the label. This may be different from align, if align is * defaulted. * * Side effects: * Updates the label list in the CellDef to contain the label. * * ---------------------------------------------------------------------------- */ int SimPutLabel(cellDef, rect, align, text, type) CellDef *cellDef; /* Cell in which label is placed */ Rect *rect; /* Location of label; see above for description */ int align; /* Orientation/alignment of text. If this is < 0, * an orientation will be picked to keep the text * inside the cell boundary. */ char *text; /* Pointer to actual text of label */ TileType type; /* Type of tile to be labeled */ { Label *lab; int len, x1, x2, y1, y2, tmp, labx, laby; len = strlen(text) + sizeof (Label) - sizeof lab->lab_text + 1; lab = (Label *) mallocMagic((unsigned) len); strcpy(lab->lab_text, text); /* Pick a nice alignment if the caller didn't give one. If the * label is more than BORDER units from an edge of the cell, * use GEO_NORTH. Otherwise, put the label on the opposite side * from the boundary, so it won't stick out past the edge of * the cell boundary. */ #define BORDER 5 if (align < 0) { tmp = (cellDef->cd_bbox.r_xtop - cellDef->cd_bbox.r_xbot)/3; if (tmp > BORDER) tmp = BORDER; x1 = cellDef->cd_bbox.r_xbot + tmp; x2 = cellDef->cd_bbox.r_xtop - tmp; tmp = (cellDef->cd_bbox.r_ytop - cellDef->cd_bbox.r_ybot)/3; if (tmp > BORDER) tmp = BORDER; y1 = cellDef->cd_bbox.r_ybot + tmp; y2 = cellDef->cd_bbox.r_ytop - tmp; labx = (rect->r_xtop + rect->r_xbot)/2; laby = (rect->r_ytop + rect->r_ybot)/2; if (labx <= x1) { if (laby <= y1) align = GEO_NORTHEAST; else if (laby >= y2) align = GEO_SOUTHEAST; else align = GEO_EAST; } else if (labx >= x2) { if (laby <= y1) align = GEO_NORTHWEST; else if (laby >= y2) align = GEO_SOUTHWEST; else align = GEO_WEST; } else { if (laby <= y1) align = GEO_NORTH; else if (laby >= y2) align = GEO_SOUTH; else align = GEO_NORTH; } } lab->lab_just = align; lab->lab_type = type; lab->lab_rect = *rect; lab->lab_next = NULL; lab->lab_flags = 0; if (cellDef->cd_labels == NULL) cellDef->cd_labels = lab; else { ASSERT(cellDef->cd_lastLabel->lab_next == NULL, "SimPutLabel"); cellDef->cd_lastLabel->lab_next = lab; } cellDef->cd_lastLabel = lab; DBUndoPutLabel(cellDef, lab); return align; } #ifdef RSIM_MODULE /* * ---------------------------------------------------------------------------- * * SimRsimHandler * * This procedure is the button handler for the rsim tool. * * Results: * None. * * Side effects: * Left button: used to move the whole box by the lower-left corner. * Right button: used to re-size the box by its upper-right corner. * If one of the left or right buttons is pushed, then the * other is pushed, the corner is switched to the nearest * one to the cursor. This corner is remembered for use * in box positioning/sizing when both buttons have gone up. * Middle button: used to display the rsim node values of whatever * paint is selected. * * ---------------------------------------------------------------------------- */ void SimRsimHandler(w, cmd) MagWindow *w; /* Window containing cursor. */ TxCommand *cmd; /* Describes what happened. */ { static int buttonCorner = TOOL_ILG; int button = cmd->tx_button; if (button == TX_MIDDLE_BUTTON) { if (cmd->tx_buttonAction == TX_BUTTON_DOWN) SimRsimMouse(w); return; } if (cmd->tx_buttonAction == TX_BUTTON_DOWN) { if ((WindNewButtons & (TX_LEFT_BUTTON|TX_RIGHT_BUTTON)) == (TX_LEFT_BUTTON|TX_RIGHT_BUTTON)) { /* Both buttons are now down. In this case, the FIRST * button pressed determines whether we move or size, * and the second button is just used as a signal to pick * the closest corner. */ buttonCorner = ToolGetCorner(&cmd->tx_p); if (button == TX_LEFT_BUTTON) button = TX_RIGHT_BUTTON; else button = TX_LEFT_BUTTON; } else if (button == TX_LEFT_BUTTON) buttonCorner = TOOL_BL; else buttonCorner = TOOL_TR; dbwButtonSetCursor(button, buttonCorner); } else { /* A button has just come up. If both buttons are down and one * is released, we just change the cursor to reflect the current * corner and the remaining button (i.e. move or size box). */ if (WindNewButtons != 0) { if (button == TX_LEFT_BUTTON) dbwButtonSetCursor(TX_RIGHT_BUTTON, buttonCorner); else dbwButtonSetCursor(TX_LEFT_BUTTON, buttonCorner); return; } /* The last button has been released. Reset the cursor to normal * form and then move or size the box. */ GrSetCursor(STYLE_CURS_RSIM); switch (button) { case TX_LEFT_BUTTON: ToolMoveBox(buttonCorner, &cmd->tx_p, TRUE, (CellDef *) NULL); break; case TX_RIGHT_BUTTON: ToolMoveCorner(buttonCorner, &cmd->tx_p, TRUE, (CellDef *) NULL); } } } #endif magic-8.0.210/sim/SimExtract.c0000664000175000001440000005006112032325053014470 0ustar timusers/* * SimExtract.c * * This file provides routines to extract a single node name from the * Magic circuit. Some of this code is based on the Magic extract * module. * * ********************************************************************* * * 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. * * ********************************************************************* * of California. */ #include #include #include #include "tcltk/tclmagic.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 "utils/malloc.h" #include "textio/textio.h" #include "debug/debug.h" #include "extract/extract.h" #include "extract/extractInt.h" #include "utils/signals.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "utils/styles.h" #include "utils/stack.h" #include "sim/sim.h" /* When performing node name extraction, we mark all tiles of a node * as we walk through the database. Since nodes can span multiple cells, * we need to keep a list off all cell definitions which we marked during * the search so we can erase these marks when we are finished. */ typedef struct def_list_elt { CellDef *dl_def; struct def_list_elt *dl_next; } DefListElt; /* When the node name is extracted, all the labels associated with the * name are contained in a NodeRegion data structure. We save all the * node regions created during the name search, freeing them when we are * finished. */ static DefListElt *DefList = (DefListElt *) NULL; /* list of cell defs used in the node name search */ static NodeRegion *NodeRegList = (NodeRegion *) NULL; /* list of the nodes found in the current selection */ extern Stack *extNodeStack; /* stack used to process node tiles */ static ExtStyle *simExtStyle = NULL; /* * Mask with a bit set for every type of transistor. */ TileTypeBitMask SimTransMask; /* * Mask indicating which tile types may form a transistor * terminal (source/drain). */ TileTypeBitMask SimSDMask; /* * A mask indicating which tile types may be the active part * of a transistor. if type 't' is a possible transistor terminal, * then SimFetMask[t] indicates which tile types to search for the * 'gate' part. */ TileTypeBitMask SimFetMask[TT_MAXTYPES]; /* * Mask of planes for which SimFetMask is non-zero. */ PlaneMask SimFetPlanes; /* *---------------------------------------------------------------- * SimAddDefList -- * * This procedure adds a cell definition to the DefList. A cell * definition is added only if is not already in the list. * * Results: * None. * * Side effects: * The cell may be added to the list. * *---------------------------------------------------------------- */ void SimAddDefList(newdef) CellDef *newdef; { DefListElt *d; /* check to see if the cell def is already in our list */ for (d = DefList; d != (DefListElt *) NULL; d = d->dl_next) { if (d->dl_def == newdef) { return; } } /* add the cell def to the list */ if (DefList == (DefListElt *) NULL) { DefList = (DefListElt *) mallocMagic((unsigned) (sizeof(DefListElt))); DefList->dl_def = newdef; DefList->dl_next = (DefListElt *) NULL; return; } else { d = (DefListElt *) mallocMagic((unsigned) (sizeof(DefListElt))); d->dl_next = DefList; d->dl_def = newdef; DefList= d; } } /* *---------------------------------------------------------------- * SimInitDefList * * This procedure initializes the cell definition list. Any cell * definitions in the list have their tiles erased of the marks * we left during the node name search, and the space in the list * is freed. * * Results: * None. * * Side effects: * The cell definitions' tiles' marks we left are erased and the * list is set to NULL. * *---------------------------------------------------------------- */ void SimInitDefList() { DefListElt *p, *q; p = q = DefList; while (p != (DefListElt *) NULL) { q = p; p = p->dl_next; ExtResetTiles(q->dl_def, extUnInit); freeMagic(q); } DefList = (DefListElt *) NULL; } /* *---------------------------------------------------------------- * SimAddNodeList * * This procedure prepends a node region to the node region list. * * Results: * None. * * Side effects: * The region next pointer is updated. * *---------------------------------------------------------------- */ void SimAddNodeList(newnode) NodeRegion *newnode; { if( NodeRegList != (NodeRegion *) NULL ) newnode->nreg_next = NodeRegList; NodeRegList = newnode; } /* *---------------------------------------------------------------- * SimFreeNodeRegs * * This procedure frees the label regions stored in the list. * * Results: * None. * * Side effects: * The list is set to NULL. * *---------------------------------------------------------------- */ void SimFreeNodeRegs() { NodeRegion *p, *q; if( NodeRegList != (NodeRegion *) NULL ) /* sanity */ ExtFreeLabRegions((LabRegion *) NodeRegList ); NodeRegList = (NodeRegion *) NULL; } /* *---------------------------------------------------------------- * SimInitConnTables -- * * Initialize the connectivity tables for finding transistors connected * to the region being searched. *---------------------------------------------------------------- */ int SimInitConnTables() { int i, t, sd, p; SimTransMask = ExtCurStyle->exts_transMask; TTMaskZero( &SimSDMask ); for( t = TT_TECHDEPBASE; t < DBNumTypes; t++ ) { for (i = 0; !TTMaskHasType(&ExtCurStyle->exts_transSDTypes[t][i], TT_SPACE); i++) { TTMaskSetMask( &SimSDMask, &ExtCurStyle->exts_transSDTypes[t][i] ); TTMaskZero( &SimFetMask[t] ); } } SimFetPlanes = 0; for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) { if (TTMaskHasType(&SimTransMask, t)) { for (sd = TT_TECHDEPBASE; sd < DBNumTypes; sd++) { for (i = 0; !TTMaskHasType(&ExtCurStyle->exts_transSDTypes[t][i], TT_SPACE); i++) { if (TTMaskHasType(&ExtCurStyle->exts_transSDTypes[t][i], sd)) { TTMaskSetType(&SimFetMask[sd], t); SimFetPlanes |= PlaneNumToMaskBit(DBPlane(t)); } } } } } simExtStyle = ExtCurStyle; return 0; } #define IsTransGate( T ) ( TTMaskHasType( &SimTransMask, T ) ) #define IsTransTerm( T ) ( TTMaskHasType( &SimSDMask, T ) ) typedef struct { NodeRegion *region; /* Node to which this terminal is connected */ int pnum; /* Lowest numbered plane in this region */ Point pos; /* Lower-leftmost point for this node */ } TransTerm; typedef struct { LabRegion *t_dummy; /* UNUSED */ int t_pnum; /* Lowest numbered plane in this region */ int t_type; /* Type of tile that contains lreg_ll */ Point t_ll; /* Lower-leftmost point of 'gate' region */ int t_nterm; /* number of terminals (at most 2) */ bool t_do_terms; /* Set if we should collect terminals */ TransTerm t_term[10]; /* transistor 'source/drain' terminal(s) */ } SimTrans; static Tile *gateTile; /* Set to point to a transistor tile * whose gate is connected to the * node being searched */ static Tile *sdTile; /* Set to point to a transistor tile * whose source/drain is connected * to the node being searched */ static SimTrans transistor; /* Transistor being extracted */ typedef enum { ND_REGION, ND_NAME } RegOrName; typedef struct /* return value from SimFindOneNode */ { RegOrName nd_what; /* ND_REGION, => region, ND_NAME => nd_name */ NodeRegion *nd_region; /* The node region extracted */ char *nd_name; /* The 'final' node name */ } NodeSpec; /* *---------------------------------------------------------------- * SimTxtorLabel -- * * Return a string that identifies a node as a function of a transistor * position. * *---------------------------------------------------------------- */ char *SimTxtorLabel( nterm, tm, trans ) int nterm; Transform *tm; SimTrans *trans; { static char name[30]; Rect r1, r2; r1.r_ll = trans->t_ll; r1.r_xtop = r1.r_xbot + 1; r1.r_ytop = r1.r_ybot + 1; GeoTransRect( tm, &r1, &r2 ); if( nterm > 1 ) nterm = 1; sprintf( name, "@=%c%d,%d", "gsd"[nterm+1], r2.r_xbot, r2.r_ybot ); return( name ); } int SimSDTransFunc( tile, ptile ) Tile *tile; Tile **ptile; { *ptile = tile; return( 1 ); } int SimTransTerms( bp, trans ) Boundary *bp; SimTrans *trans; { TransTerm *term; Tile *tile = bp->b_outside; TileType type; NodeRegion *reg = (NodeRegion *) tile->ti_client; int pNum; int i; if (IsSplit(tile)) { switch(bp->b_direction) { case BD_LEFT: type = TiGetRightType(tile); break; case BD_RIGHT: type = TiGetLeftType(tile); break; case BD_TOP: type = TiGetBottomType(tile); break; case BD_BOTTOM: type = TiGetTopType(tile); break; } } else type = TiGetTypeExact(tile); pNum = DBPlane(type); for( i = 0; i < trans->t_nterm; i++ ) { term = &trans->t_term[i]; if( term->region == reg ) { if( pNum < term->pnum ) { term->pnum = pNum; term->pos = tile->ti_ll; } else if( pNum == term->pnum ) { if( LEFT(tile) < term->pos.p_x ) term->pos = tile->ti_ll; else if( LEFT(tile) == term->pos.p_x && BOTTOM(tile) < term->pos.p_y ) term->pos.p_y = BOTTOM(tile); } return( 0 ); } } term = &trans->t_term[ trans->t_nterm++ ]; term->region = reg; term->pnum = pNum; term->pos = tile->ti_ll; return( 0 ); } int SimTermNum( trans, reg ) SimTrans *trans; NodeRegion *reg; { int i, changed; TransTerm *p1, *p2, tmp; do { changed = 0; for( i = 0; i < trans->t_nterm-1; i++ ) { p1 = &(trans->t_term[i]); p2 = &(trans->t_term[i+1]); if( p2->pnum > p1->pnum ) continue; else if( p2->pnum == p1->pnum ) { if( p2->pos.p_x > p1->pos.p_x ) continue; else if( p2->pos.p_x == p1->pos.p_x && p2->pos.p_y > p1->pos.p_y ) continue; } changed = 1; tmp = *p1; *p1 = *p2; *p2 = tmp; } } while( changed ); for( i = 0; i < trans->t_nterm; i++ ) { if( trans->t_term[i].region == reg ) return( i ); } /* should never get here */ return( -1 ); } int SimTransistorTile(tile, pNum, arg) Tile *tile; int pNum; FindRegion *arg; { int i; TileType t; extSetNodeNum((LabRegion *)&transistor, pNum, tile); if (transistor.t_do_terms) { t = TiGetType(tile); for (i = 0; !TTMaskHasType(&ExtCurStyle->exts_transSDTypes[t][i], TT_SPACE); i++) extEnumTilePerim(tile, ExtCurStyle->exts_transSDTypes[t][i], SimTransTerms, (ClientData) &transistor ); } return (0); } int SimFindTxtor( tile, pNum, arg ) Tile *tile; int pNum; FindRegion *arg; { TileType type; extSetNodeNum( (LabRegion *) arg->fra_region, pNum, tile ); if( ! SimUseCoords ) /* keep searching, forget transistors */ return( 0 ); type = TiGetType( tile ); if( IsTransGate( type ) ) { gateTile = tile; /* found a transistor gate, stop searching */ return( 1 ); } else if( IsTransTerm( type ) && sdTile == (Tile *) NULL ) { Rect area; TITORECT( tile, &area ); GEO_EXPAND( &area, 1, &area ); for( pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++ ) if( PlaneMaskHasPlane( SimFetPlanes, pNum ) ) { if( DBSrPaintArea((Tile *) NULL, arg->fra_def->cd_planes[pNum], &area, &SimFetMask[type], SimSDTransFunc, (ClientData) &sdTile ) ) break; } } return( 0 ); } /* *---------------------------------------------------------------- * SimFindOneNode * * This procedure returns the node region for a tile which lies * in the node. * * Results: * A pointer to the node's node region data structure is returned. * * Side effects: * None. * *---------------------------------------------------------------- */ NodeSpec * SimFindOneNode( sx, tile ) SearchContext *sx; Tile *tile; { CellDef *def = sx->scx_use->cu_def; NodeRegion *reg; FindRegion arg; TileType type, loctype; static NodeSpec ret; /* Allocate a new node */ reg = (NodeRegion *) mallocMagic((unsigned) (sizeof(NodeRegion) )); reg->nreg_labels = (LabelList *) NULL; reg->nreg_cap = 0; reg->nreg_resist = 0; reg->nreg_pnum = DBNumPlanes; reg->nreg_next = (NodeRegion *) NULL; gateTile = sdTile = (Tile *) NULL; /* Find all connected paint in this cell */ arg.fra_connectsTo = ExtCurStyle->exts_nodeConn; arg.fra_def = def; if (IsSplit(tile)) type = SplitSide(tile) ? TiGetRightType(tile) : TiGetLeftType(tile); else type = TiGetTypeExact(tile); arg.fra_pNum = DBPlane(type); arg.fra_uninit = (ClientData) extUnInit; arg.fra_region = (Region *) reg; arg.fra_each = SimFindTxtor; (void) ExtFindNeighbors( tile, arg.fra_pNum, &arg ); if( gateTile != (Tile *) NULL ) { /* Determine the transistor position (leftmost-lowest tile) */ transistor.t_pnum = DBNumPlanes; transistor.t_do_terms = FALSE; gateTile->ti_client = (ClientData) extUnInit; arg.fra_connectsTo = &SimTransMask; if (IsSplit(tile)) loctype = SplitSide(gateTile) ? TiGetRightType(gateTile) : TiGetLeftType(gateTile); else loctype = TiGetTypeExact(gateTile); arg.fra_pNum = DBPlane(loctype); arg.fra_uninit = (ClientData) extUnInit; arg.fra_region = (Region *) reg; arg.fra_each = SimTransistorTile; (void) ExtFindNeighbors( gateTile, arg.fra_pNum, &arg ); /* Unmark current region since not all paint was traced */ arg.fra_connectsTo = ExtCurStyle->exts_nodeConn; arg.fra_pNum = DBPlane(type); arg.fra_uninit = (ClientData) reg; arg.fra_region = (Region *) extUnInit; arg.fra_each = (int (*)()) NULL; (void) ExtFindNeighbors( tile, arg.fra_pNum, &arg ); freeMagic( reg ); ret.nd_name = SimTxtorLabel( -1, &sx->scx_trans, &transistor ); ret.nd_what = ND_NAME; } else if( sdTile != (Tile *) NULL ) { int tNum; SimAddNodeList( reg ); SimAddDefList( def ); transistor.t_pnum = DBNumPlanes; transistor.t_nterm = 0; transistor.t_do_terms = TRUE; /* collect the transistor position, and its terminals */ arg.fra_connectsTo = &SimTransMask; if (IsSplit(tile)) loctype = SplitSide(sdTile) ? TiGetRightType(sdTile) : TiGetLeftType(sdTile); else loctype = TiGetTypeExact(sdTile); arg.fra_pNum = DBPlane(loctype); arg.fra_uninit = (ClientData) sdTile->ti_client; arg.fra_region = (Region *) &ret; arg.fra_each = SimTransistorTile; (void) ExtFindNeighbors( sdTile, arg.fra_pNum, &arg ); /* Unmark the transitor, since its not part of this region */ arg.fra_region = (Region *) arg.fra_uninit; arg.fra_uninit = (ClientData) &ret; arg.fra_each = (int (*)()) NULL; (void) ExtFindNeighbors( sdTile, arg.fra_pNum, &arg ); if( (tNum = SimTermNum( &transistor, reg )) < 0 ) { TxPrintf( "\tSimFindOneNode: bad transistor terminal number\n" ); goto use_name; } ret.nd_name = SimTxtorLabel( tNum, &sx->scx_trans, &transistor ); ret.nd_what = ND_NAME; } else /* no transistors found, get the regions labels */ { SimAddNodeList( reg ); SimAddDefList( def ); use_name: ExtLabelOneRegion( def, ExtCurStyle->exts_nodeConn, reg ); ret.nd_region = reg; ret.nd_what = ND_REGION; } return( &ret ); } /* *---------------------------------------------------------------- * SimGetNodeName * * This procedure uses the Magic circuit extraction code to generate * the node name. The node is extracted by searching the database * for all tiles electrically connected to the node. Each tile is * marked with a pointer to the node region it belongs to. It is * the node region data structure which contains the labels for a * node. The "preferred" label for the node is taken, and this * is combined with the path name to produce the complete node name. * * Results: * A pointer to the node name is returned. This is a pointer to * statically allocated memory, so subsequent calls to this procedure * will change the node name the returned pointer references. * * Side effects: * Any node region created is added to the node region list. *---------------------------------------------------------------- */ char * SimGetNodeName(sx, tp, path) SearchContext *sx; /* current search context */ Tile *tp; /* tile in this cell which is part * of the node */ char *path; /* path name of hierarchy of search */ { CellDef *def = sx->scx_use->cu_def; NodeRegion *nodeList; LabelList *ll; static char nodename[256]; char buff[256]; char *text; char *nname; SimSawAbortString = FALSE; if( SimUseCoords && simExtStyle != ExtCurStyle ) SimInitConnTables(); /* check to see if this tile has been extracted before */ if (tp->ti_client == extUnInit) { NodeSpec *ns; ns = SimFindOneNode(sx, tp); if( ns->nd_what == ND_NAME ) { SimSawAbortString = TRUE; return( ns->nd_name ); } nodeList = ns->nd_region; } else { nodeList = (NodeRegion *)(tp->ti_client); } /* generate the node name from the label region and the path name */ text = extNodeName((LabRegion *)nodeList); strcpy(buff, text); strcpy(nodename, path); strcat(nodename, text); /* check to see if we should abort the search on the node name */ if (!SimInitGetnode) { if (HashLookOnly(&SimGetnodeTbl, buff) != (HashEntry *) NULL) { SimSawAbortString = TRUE; if (HashLookOnly(&SimAbortSeenTbl, buff) == (HashEntry *) NULL) { HashFind(&SimAbortSeenTbl, buff); TxPrintf("Node name search aborted on \"%s\"\n", buff); } } } /* Check whether or not to print out node name aliases. Each alias * found is hashed in a table in order to suppress printing of * duplicate aliases. */ if (SimGetnodeAlias && SimIsGetnode) { if (HashLookOnly(&SimGNAliasTbl, nodename) == (HashEntry *) NULL) { HashFind(&SimGNAliasTbl, nodename); #ifdef MAGIC_WRAPPER Tcl_AppendElement(magicinterp, nodename); #else TxPrintf("alias: %s\n", nodename); #endif } } /* search the list of all labels for this node, creating the full * node name and returning the "best" node name found. */ for (ll = nodeList->nreg_labels; ll; ll = ll->ll_next) { if (ll->ll_label->lab_text == text) { for (ll = ll->ll_next; ll; ll = ll->ll_next) { nname = ll->ll_label->lab_text; if (extLabType(nname, LABTYPE_NAME)) { strcpy(nodename, path); strcat(nodename, nname); if (efPreferredName(nname, buff)) { strcpy(buff, nname); } if (SimGetnodeAlias && SimIsGetnode) { if (HashLookOnly(&SimGNAliasTbl, nodename) == (HashEntry *) NULL) { HashFind(&SimGNAliasTbl, nodename); #ifdef MAGIC_WRAPPER Tcl_AppendElement(magicinterp, nodename); #else TxPrintf("alias: %s\n", nodename); #endif } } } } break; } } strcpy(nodename, path); strcat(nodename, buff); return(nodename); } /* *---------------------------------------------------------------- * SimGetNodeCleanup * * This procedure is called to clean up the data structures and the * tile database after a node name is extracted. * * Results: * None. * * Side effects: * The node region list and cell def lists are re-initialized. *---------------------------------------------------------------- */ void SimGetNodeCleanUp() { SimFreeNodeRegs(); SimInitDefList(); } magic-8.0.210/sim/SimSelect.c.new0000644000175000001440000005572410751423606015107 0ustar timusers/* SimSelect.c - * * This file provides routines to make selections for Rsim by copying * things into a special cell named "__SELECT__". It is based * on code in the select module. * * ********************************************************************* * * 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. * * ********************************************************************* * of California */ #ifndef lint static char sccsid[] = "@(#)SimSelect.c 4.14 MAGIC (Berkeley) 10/3/85"; #endif /* not lint */ #include #ifdef SYSV #include #else #include #endif #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 "undo/undo.h" #include "commands/commands.h" #include "select/selInt.h" #include "main/main.h" #include "utils/malloc.h" #include "utils/signals.h" #include "sim/sim.h" /* Two cells worth of information are kept around by the selection * module. SelectDef and SelectUse are for the cells whose contents * are the current selection. Select2Def and Select2Use provide a * temporary working space for procedures that manipulate the selection. * for example, Select2Def is used to hold nets or regions while they * are being extracted by SelectRegion or SelectNet. Once completely * extracted, information is copied to SelectDef. Changes to * SelectDef are undo-able and redo-able (so that the undo package * can deal with selection changes), but changes to Select2Def are * not undo-able (undoing is always disabled when the cell is modified). */ extern CellDef *SelectDef, *Select2Def; extern CellUse *SelectUse, *Select2Use; typedef struct def_list_elt { CellDef *dl_def; struct def_list_elt *dl_next; bool dl_isMarked; } SimDefListElt; static SimDefListElt *SimCellLabList = (SimDefListElt *) NULL; /* list of all the cell defs we have * put RSIM labels in */ /* Data structure for node names extracted from the current selection. For * each node, save the node name, a tile which lies in the node, and * the text for the label corresponding to the node's rsim value. */ typedef struct TLE { char *tl_nodeName; Tile *tl_nodeTile; char *tl_simLabel; struct TLE *tl_next; } TileListElt; TileListElt *NodeList = (TileListElt *) NULL; /* list of all nodes in the selected area */ HashTable SimNodeNameTbl; /* node names found in the selected area */ HashTable SimGetnodeTbl; /* node names to abort name search on */ HashTable SimGNAliasTbl; /* node name aliases found during search */ HashTable SimAbortSeenTbl; /* aborted node names found during search */ bool SimRecomputeSel = TRUE; /* selection has changed */ bool SimInitGetnode = TRUE; /* Getnode called for the 1st time */ bool SimGetnodeAlias = FALSE; /* if node aliases are to be printed */ bool SimSawAbortString; /* if saw string to abort name search */ bool SimIsGetnode; /* true if command was issued from Getnode */ bool SimUseCoords; /* true if we should use trans. position */ bool SimIgnoreGlobals = TRUE; /* If FALSE, node names ending in "!" */ /* are treated as global node names. */ #ifndef RSIM_MODULE bool SimRsimRunning = FALSE; /* Always false if there's no rsim module */ #endif /* * ---------------------------------------------------------------------------- * * SimSelectNode -- * * This procedure selects an entire node. It is similar to SelectNet. * * Results: * Returns the node name. * * Side effects: * Starting from material of type "type" under scx, this procedure * finds all material in all expanded cells that are electrically- * connected to the starting material through a chain of expanded * cells. * * ---------------------------------------------------------------------------- */ char * SimSelectNode(scx, type, xMask, buffer) SearchContext *scx; /* Area to tree-search for material. The * transform must map to EditRoot coordinates. */ TileType type; /* The type of material to be considered. */ int xMask; /* Indicates window (or windows) where cells * must be expanded for their contents to be * considered. 0 means treat everything as * expanded. */ char *buffer; /* buffer to hold node name */ { TileTypeBitMask mask; char *strptr; TTMaskZero(&mask); TTMaskSetType(&mask, type); /* Clear out the temporary selection cell and yank all of the * connected paint into it. */ UndoDisable(); DBCellClearDef(Select2Def); SimTreeCopyConnect(scx, &mask, xMask, DBConnectTbl, &TiPlaneRect, Select2Use, buffer); UndoEnable(); /* Strip out path if name is global (ends with a "!") */ /* and flag SimIgnoreGlobals is not set. */ if (!SimIgnoreGlobals) { strptr = buffer + strlen(buffer) - 1; if (*strptr == '!') { *strptr = '\0'; while (strptr != buffer) { if (*strptr == '/') { strptr++; break; } strptr--; } } else { strptr = buffer; } } else strptr = buffer; return(strptr); } NullFunc() { return(0); } /* * ---------------------------------------------------------------------------- * SimFreeNodeList * * This procedure frees all space allocated for the node list * data structure. * * Results: * None. * * Side effects: * After the list has been deallocated, the head pointer is set to * a NULL value. * ---------------------------------------------------------------------------- */ void SimFreeNodeList(List) TileListElt **List; { TileListElt *current; TileListElt *temp; temp = *List; while (temp != NULL) { current = temp; temp = temp->tl_next; freeMagic(current->tl_nodeName); freeMagic(current); } *List = (TileListElt *) NULL; } TileListElt * simFreeNodeEntry(list, entry) TileListElt *list, *entry; { TileListElt *prev, *curr; prev = list; for( curr = prev->tl_next; curr != NULL; prev = curr,curr = curr->tl_next ) if( curr == entry ) { prev->tl_next = curr->tl_next; freeMagic( entry->tl_nodeName ); freeMagic( entry ); return( prev ); /* next element in list */ } /* should never get here */ return(entry); } /* * ---------------------------------------------------------------------------- * SimSelectArea * * This procedure checks the current selected paint in the circuit and * extracts the names of all the nodes in the selected area. * * Results: * Returns a list of node name data structures. * * Side Effects: * The tiles of the selection cell definition are first marked in the * search algorithm. After finishing the search, these marks are * erased. * * ---------------------------------------------------------------------------- */ typedef struct { TileListElt *NodeList; MagWindow *window; SearchContext *scx; } SimSelData; TileListElt * SimSelectArea(Rect *rect) { int plane; int SimSelectFunc(); SimSelData simseldata; SearchContext scx; /* only need to extract node names if the selection has changed or * if node aliases are to be printed. */ if (SimRecomputeSel || (SimGetnodeAlias && SimIsGetnode)) { SimFreeNodeList(&NodeList); HashInit(&SimAbortSeenTbl, 20, HT_STRINGKEYS); /* find all nodes in the current selection */ simseldata.NodeList = NodeList; simseldata.scx = &scx; simseldata.window = CmdGetRootPoint((Point *) NULL, &scx.scx_area); if (rect != NULL) scx.scx_area = *rect; if (simseldata.window != NULL) { for (plane = PL_TECHDEPBASE; plane < DBNumPlanes; plane++) { (void) DBSrPaintArea((Tile *) NULL, SelectDef->cd_planes[plane], &TiPlaneRect, &DBAllButSpaceAndDRCBits, SimSelectFunc, (ClientData) &simseldata); } } HashKill(&SimAbortSeenTbl); ExtResetTiles(SelectDef, (ClientData) MINFINITY); SimGetNodeCleanUp(); SimRecomputeSel = FALSE; } if (SigInterruptPending) { /* if caught an interrupt, be sure to recompute the selection * next time around. */ SimRecomputeSel = TRUE; } return(NodeList); } /* * ---------------------------------------------------------------------------- * SimSelectFunc * * This procedure is called for each tile in the current selection. * It first checks to see if the node the tile belongs to has not * yet been visited. If it has not been visited, then the node name * is extracted and all other tiles in the selection which belong to * this node are marked. * * Results: * Return 0 to keep the search going. * * Side effects: * The tiles in the selection cell definition are left marked. * It is the responsibility of the calling function to erase these * tile marks when finished. * ---------------------------------------------------------------------------- */ int SimSelectFunc(tile, simseldata) Tile *tile; /* Tile in SelectDef. */ SimSelData simseldata; { TileListElt **pHead; /* list of node names found */ TileTypeBitMask mask; SearchContext scx; DBWclientRec *crec; MagWindow *window; char nameBuff[256], *nodeName; TileListElt *newNodeTile; TileType type; bool coord; window = simseldata->window; /* check to see if the node has already been extracted */ if (tile->ti_client == (ClientData) 1) { return(0); } #ifdef NONMANHATTAN if (IsSplit(tile)) { type = (SplitSide(tile)) ? SplitRightType(tile): SplitLeftType(tile); } else #endif type = TiGetTypeExact(tile); /* get the tile's area, and initialize the tile's search context. */ TITORECT(tile, &scx.scx_area); #ifdef NONMANHATTAN /* make sure that search context isn't placed on an empty */ /* corner of a split tile. */ if (IsSplit(tile)) { if (SplitSide(tile)) scx.scx_area.r_xbot = scx.scx_area.r_xtop - 1; if (!(SplitDirection(tile) ^ SplitSide(tile))) scx.scx_area.r_ybot = scx.scx_area.r_ytop - 1; } #endif scx.scx_area.r_xtop = scx.scx_area.r_xbot + 1; scx.scx_area.r_ytop = scx.scx_area.r_ybot + 1; scx.scx_use = (CellUse *) window->w_surfaceID; scx.scx_trans = GeoIdentityTransform; crec = (DBWclientRec *) window->w_clientData; TTMaskZero(&mask); TTMaskSetType(&mask, type); TTMaskAndMask(&mask, &crec->dbw_visibleLayers); TTMaskAndMask(&mask, &DBAllButSpaceAndDRCBits); /* Check if the area is above a layer which is not visible. */ if (TTMaskIsZero(&mask)) { return(0); } /* mark all other tiles in the selection that are part of this node */ SimSrConnect(SelectDef, &scx.scx_area, &DBAllButSpaceAndDRCBits, DBConnectTbl, &TiPlaneRect, NullFunc, (ClientData) NULL); /* Pick a tile type to use for selection. */ for (type = TT_TECHDEPBASE; type < DBNumTypes; type += 1) { if (TTMaskHasType(&mask, type)) break; } nodeName = SimSelectNode(&scx, type, 0, nameBuff); /* add the node name to the list only if it has not been seen yet */ coord = (nodeName[0] == '@' && nodeName[1] == '=') ? TRUE : FALSE; if(coord || HashLookOnly(&SimNodeNameTbl, nodeName) == (HashEntry *) NULL) { if( ! coord ) HashFind(&SimNodeNameTbl, nodeName); newNodeTile = (TileListElt *) mallocMagic((unsigned) (sizeof (TileListElt))); newNodeTile->tl_nodeName = (char *) mallocMagic((unsigned) (strlen(nodeName) + 1)); strcpy(newNodeTile->tl_nodeName, nodeName); newNodeTile->tl_nodeTile = tile; newNodeTile->tl_next = *pHead; *pHead = newNodeTile; } return(0); } #ifdef RSIM_MODULE /* * ---------------------------------------------------------------------------- * SimSelection * * This procedure applies the specified rsim command to the list of * nodes in the current selection and also attaches the rsim node * value string to each node. * * Results: * returns FALSE if no nodes are in the selection. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool SimSelection(cmd) char *cmd; /* rsim command to apply to the selection */ { static char Hstring[] = "RSIM=1"; static char Lstring[] = "RSIM=0"; static char Xstring[] = "RSIM=X"; static char QUESTstring[] = "?"; char timeString[256]; TileListElt *current, *node_list; char *replyLine; char *strPtr; bool goodReply; extern RsimErrorMsg(); timeString[0] = 0; /* check to see if Rsim has been started yet */ if (!SimRsimRunning) { RsimErrorMsg(); return(FALSE); } /* get the list of all nodes in the selection */ SimIsGetnode = FALSE; SimUseCoords = SimHasCoords; HashInit(&SimNodeNameTbl, 60, HT_STRINGKEYS); node_list = SimSelectArea((Rect *)NULL); if (node_list == (TileListElt *) NULL) { TxPrintf("You must select paint (rather than a cell) to use Rsim on \ the selection.\n"); goto bad; } /* Walk the list of node names, apply the rsim command to each node, * and then process the results. */ for (current = node_list; current != NULL; current = current->tl_next) { current->tl_simLabel = QUESTstring; SimRsimIt(cmd, current->tl_nodeName); if (!SimGetReplyLine(&replyLine)) { goto bad; } if (!replyLine) { /* Rsim's reponse to the command was just a prompt. We are done * with the current node, so process the next node in the * selection. */ continue; } /* check for node names not recognized by Rsim */ if (strncmp(replyLine, "time = ", 7) == 0) { if (timeString[0] == 0) { strcpy(timeString, replyLine); } TxPrintf("%s not recognized in sim file\n", current->tl_nodeName); while(replyLine) { /* swallow Rsim reply until no more is left */ if (!SimGetReplyLine(&replyLine)) { goto bad; } } continue; } /* update the node value label strings */ if (*cmd == 'd') { char *name = current->tl_nodeName; bool coord = (name[0] == '@' && name[1] == '=') ? TRUE : FALSE; strPtr = rindex( replyLine, '=' ); if( strPtr == NULL ) strPtr = QUESTstring; else if( coord ) { *strPtr = '\0'; name = replyLine; if( HashLookOnly(&SimNodeNameTbl, name) == (HashEntry *) NULL) { freeMagic(current->tl_nodeName); current->tl_nodeName = (char *) mallocMagic((unsigned) (strlen(name) + 1)); strcpy(current->tl_nodeName, name); HashFind(&SimNodeNameTbl, current->tl_nodeName); *strPtr++ = '='; } else { current = simFreeNodeEntry( node_list, current ); *strPtr = '='; } } else strPtr++; switch (*strPtr) { case '1' : current->tl_simLabel = Hstring; break; case '0' : current->tl_simLabel = Lstring; break; case 'X' : current->tl_simLabel = Xstring; break; case '=' : break; default : current->tl_simLabel = QUESTstring; break; } } /* read all lines of the Rsim reply */ goodReply = TRUE; for (;replyLine; goodReply = SimGetReplyLine(&replyLine)) { if (!goodReply) { goto bad; } if (!strncmp(replyLine, "time = ", 7)) { if (!(timeString[0])) { strcpy(timeString, replyLine); } continue; } else if( *strPtr != '=' ) { TxPrintf("%s\n", replyLine); } } } if (timeString[0] != 0) { TxPrintf("%s\n", timeString); } HashKill(&SimNodeNameTbl); return(TRUE); bad: HashKill(&SimNodeNameTbl); return(FALSE); } #endif /* * ---------------------------------------------------------------------------- * SimAddLabels * * This procedure adds the node value labels to the Magic database * so they will be displayed in the layout. * * Results: * None. * * Side effects: * The cell modified flags are deliberately not set when these labels * are added to the database. * * ---------------------------------------------------------------------------- */ void SimAddLabels(SelectNodeList, rootuse) TileListElt *SelectNodeList; CellDef *rootuse; /* the root cell def for the window */ { TileListElt *current; Rect selectBox; int pos; /* walk the list of selected nodes, add the node value label to the * database. */ for (current = SelectNodeList; current != (TileListElt *) NULL; current = current->tl_next) { if (*(current->tl_simLabel) == '?') { continue; } TiToRect(current->tl_nodeTile, &selectBox); pos = SimPutLabel(rootuse, &selectBox, GEO_CENTER, current->tl_simLabel, TT_SPACE); DBReComputeBbox(rootuse); DBWLabelChanged(rootuse, current->tl_simLabel, &selectBox, pos, DBW_ALLWINDOWS); } } #ifdef RSIM_MODULE /* * ---------------------------------------------------------------------------- * SimRsimMouse * * This procedure erases the old rsim node labels and display the * node labels of the current selection. * * Results: * None. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ void SimRsimMouse(w) MagWindow *w; { CellUse *cu; bool sawcell; SimDefListElt *dummy; if ((w == (MagWindow *) NULL) || (w->w_client != DBWclientID)) { TxError("Put the cursor in a layout window\n"); return; } cu = (CellUse *)w->w_surfaceID; /* get root cell use for wind */ /* check to see if the cell def is already in our list */ sawcell = FALSE; for (dummy = SimCellLabList; dummy; dummy = dummy->dl_next) { if (dummy->dl_def == cu->cu_def) { sawcell = TRUE; break; } } if (!sawcell) { /* add the cell def to the list */ if (SimCellLabList == (SimDefListElt *) NULL) { SimCellLabList = (SimDefListElt *) mallocMagic((unsigned) (sizeof(SimDefListElt))); SimCellLabList->dl_isMarked = FALSE; SimCellLabList->dl_def = cu->cu_def; SimCellLabList->dl_next = (SimDefListElt *) NULL; dummy = SimCellLabList; } else { dummy = (SimDefListElt *) mallocMagic((unsigned) (sizeof(SimDefListElt))); dummy->dl_isMarked = FALSE; dummy->dl_next = SimCellLabList; dummy->dl_def = cu->cu_def; SimCellLabList= dummy; } } SimEraseLabels(); if (SimSelection("d")) { dummy->dl_isMarked = TRUE; SimAddLabels(NodeList, dummy->dl_def); } } #endif /*------------------------------------------------------*/ /* Experimental for DEF output. . . */ /* Function "func" is a callback process for each node. */ /* SimGetnode and SimGetsnode can both be recast as */ /* operating off of this function. */ /* */ /* "func" should be cast as: */ /* int func(Tile *tile, char *nodeName, ClientData cd); */ /*------------------------------------------------------*/ void SimProcessNode(func, shortnames, area, clientdata) ((int *)func)(); bool shortnames; Rect *area; ClientData clientdata; { TileListElt *current; /* get the list of node names */ SimIsGetnode = TRUE; SimUseCoords = shortnames; HashInit(&SimNodeNameTbl, 60, HT_STRINGKEYS); current = SimSelectArea(area); HashKill(&SimNodeNameTbl); if (current == (TileListElt *) NULL) { TxPrintf("You must select paint (not a cell) to use getnode.\n"); return; } for (; current != (TileListElt *) NULL; current = current->tl_next) if ((*func)(current->tl_nodeTile, current->tl_nodeName, clientdata) == 1) break; } /* * ---------------------------------------------------------------------------- * SimGetnode * * This procedure prints the node names of all selected nodes. * * Results: * None. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ void SimGetnode() { int SimGetnodeFunc(); SimProcessNode(SimGetnodeFunc, FALSE, NULL, (ClientData)NULL); } void SimGetsnode() { int SimGetnodeFunc(); SimProcessNode(SimGetnodeFunc, TRUE, NULL, (ClientData)NULL); } int SimGetnodeFunc(tile, nodeName, clientdata) Tile *tile; char *nodeName; ClientData clientdata; { #ifdef MAGIC_WRAPPER /* Return the node name as the result of the command */ Tcl_AppendElement(magicinterp, nodeName); #else TxPrintf("node name : %s\n", nodeName); #endif return 0; /* Continue the list */ } void OLD_SimGetnode() { TileListElt *current; /* get the list of node names */ SimIsGetnode = TRUE; SimUseCoords = FALSE; HashInit(&SimNodeNameTbl, 60, HT_STRINGKEYS); current = SimSelectArea((Rect *)NULL); HashKill(&SimNodeNameTbl); if (current == (TileListElt *) NULL) { TxPrintf("You must select paint (not a cell) to use getnode.\n"); return; } for (; current != (TileListElt *) NULL; current = current->tl_next) { #ifdef MAGIC_WRAPPER /* Return the node name as the result of the command */ Tcl_AppendElement(magicinterp, current->tl_nodeName); #else TxPrintf("node name : %s\n", current->tl_nodeName); #endif } } /* * ---------------------------------------------------------------------------- * SimGetsnode * * This procedure prints the short node names of all selected nodes. * * Results: * None. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ void OLD_SimGetsnode() { TileListElt *current; /* get the list of node names */ SimIsGetnode = TRUE; SimUseCoords = TRUE; HashInit(&SimNodeNameTbl, 60, HT_STRINGKEYS); current = SimSelectArea((Rect *)NULL); HashKill(&SimNodeNameTbl); if (current == (TileListElt *) NULL) { TxPrintf("You must select paint (not a cell) to use getnode.\n"); return; } for (; current != (TileListElt *) NULL; current = current->tl_next) { #ifdef MAGIC_WRAPPER /* Return the node short name as the result of the command */ Tcl_AppendElement(magicinterp, current->tl_nodeName); #else TxPrintf("short node name : %s\n", current->tl_nodeName); #endif } } /* * ---------------------------------------------------------------------------- * SimEraseLabels * * This procedure erases the RSIM labels from any cell defs they * may have been added to. * * Results: * None. * * Side effects: * Removes the RSIM labels from "marked" cell defs. * * ---------------------------------------------------------------------------- */ void SimEraseLabels() { SimDefListElt *p; for (p = SimCellLabList; p; p = p->dl_next) { if (p->dl_isMarked) { p->dl_isMarked = FALSE; DBEraseLabelsByContent(p->dl_def, (Rect *)NULL, -1, -1, "RSIM=X"); DBEraseLabelsByContent(p->dl_def, (Rect *)NULL, -1, -1, "RSIM=1"); DBEraseLabelsByContent(p->dl_def, (Rect *)NULL, -1, -1, "RSIM=0"); } } } magic-8.0.210/sim/SimSelect.c0000644000175000001440000005163111410650644014305 0ustar timusers/* SimSelect.c - * * This file provides routines to make selections for Rsim by copying * things into a special cell named "__SELECT__". It is based * on code in the select module. * * ********************************************************************* * * 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. * * ********************************************************************* * of California */ #ifndef lint static char sccsid[] = "@(#)SimSelect.c 4.14 MAGIC (Berkeley) 10/3/85"; #endif /* not lint */ #include #include #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/undo.h" #include "commands/commands.h" #include "select/selInt.h" #include "utils/main.h" #include "utils/malloc.h" #include "utils/signals.h" #include "sim/sim.h" /* Two cells worth of information are kept around by the selection * module. SelectDef and SelectUse are for the cells whose contents * are the current selection. Select2Def and Select2Use provide a * temporary working space for procedures that manipulate the selection. * for example, Select2Def is used to hold nets or regions while they * are being extracted by SelectRegion or SelectNet. Once completely * extracted, information is copied to SelectDef. Changes to * SelectDef are undo-able and redo-able (so that the undo package * can deal with selection changes), but changes to Select2Def are * not undo-able (undoing is always disabled when the cell is modified). */ extern CellDef *SelectDef, *Select2Def; extern CellUse *SelectUse, *Select2Use; typedef struct def_list_elt { CellDef *dl_def; struct def_list_elt *dl_next; bool dl_isMarked; } SimDefListElt; static SimDefListElt *SimCellLabList = (SimDefListElt *) NULL; /* list of all the cell defs we have * put RSIM labels in */ /* Data structure for node names extracted from the current selection. For * each node, save the node name, a tile which lies in the node, and * the text for the label corresponding to the node's rsim value. */ typedef struct TLE { char *tl_nodeName; Tile *tl_nodeTile; char *tl_simLabel; struct TLE *tl_next; } TileListElt; TileListElt *NodeList = (TileListElt *) NULL; /* list of all nodes in the selected area */ HashTable SimNodeNameTbl; /* node names found in the selected area */ HashTable SimGetnodeTbl; /* node names to abort name search on */ HashTable SimGNAliasTbl; /* node name aliases found during search */ HashTable SimAbortSeenTbl; /* aborted node names found during search */ bool SimRecomputeSel = TRUE; /* selection has changed */ bool SimInitGetnode = TRUE; /* Getnode called for the 1st time */ bool SimGetnodeAlias = FALSE; /* if node aliases are to be printed */ bool SimSawAbortString; /* if saw string to abort name search */ bool SimIsGetnode; /* true if command was issued from Getnode */ bool SimUseCoords; /* true if we should use trans. position */ bool SimIgnoreGlobals = TRUE; /* If FALSE, node names ending in "!" */ /* are treated as global node names. */ #ifndef RSIM_MODULE bool SimRsimRunning = FALSE; /* Always false if there's no rsim module */ #endif /* * ---------------------------------------------------------------------------- * * SimSelectNode -- * * This procedure selects an entire node. It is similar to SelectNet. * * Results: * Returns the node name. * * Side effects: * Starting from material of type "type" under scx, this procedure * finds all material in all expanded cells that are electrically- * connected to the starting material through a chain of expanded * cells. * * ---------------------------------------------------------------------------- */ char * SimSelectNode(scx, type, xMask, buffer) SearchContext *scx; /* Area to tree-search for material. The * transform must map to EditRoot coordinates. */ TileType type; /* The type of material to be considered. */ int xMask; /* Indicates window (or windows) where cells * must be expanded for their contents to be * considered. 0 means treat everything as * expanded. */ char *buffer; /* buffer to hold node name */ { TileTypeBitMask mask; char *strptr; TTMaskZero(&mask); TTMaskSetType(&mask, type); /* Clear out the temporary selection cell and yank all of the * connected paint into it. */ UndoDisable(); DBCellClearDef(Select2Def); SimTreeCopyConnect(scx, &mask, xMask, DBConnectTbl, &TiPlaneRect, Select2Use, buffer); UndoEnable(); /* Strip out path if name is global (ends with a "!") */ /* and flag SimIgnoreGlobals is not set. */ if (!SimIgnoreGlobals) { strptr = buffer + strlen(buffer) - 1; if (*strptr == '!') { *strptr = '\0'; while (strptr != buffer) { if (*strptr == '/') { strptr++; break; } strptr--; } } else { strptr = buffer; } } else strptr = buffer; return(strptr); } int NullFunc() { return(0); } /* * ---------------------------------------------------------------------------- * SimFreeNodeList * * This procedure frees all space allocated for the node list * data structure. * * Results: * None. * * Side effects: * After the list has been deallocated, the head pointer is set to * a NULL value. * ---------------------------------------------------------------------------- */ void SimFreeNodeList(List) TileListElt **List; { TileListElt *current; TileListElt *temp; temp = *List; while (temp != NULL) { current = temp; temp = temp->tl_next; freeMagic(current->tl_nodeName); freeMagic(current); } *List = (TileListElt *) NULL; } TileListElt * simFreeNodeEntry(list, entry) TileListElt *list, *entry; { TileListElt *prev, *curr; prev = list; for( curr = prev->tl_next; curr != NULL; prev = curr,curr = curr->tl_next ) if( curr == entry ) { prev->tl_next = curr->tl_next; freeMagic( entry->tl_nodeName ); freeMagic( entry ); return( prev ); /* next element in list */ } /* should never get here */ return(entry); } /* * ---------------------------------------------------------------------------- * SimSelectArea * * This procedure checks the current selected paint in the circuit and * extracts the names of all the nodes in the selected area. * * Results: * Returns a list of node name data structures. * * Side Effects: * The tiles of the selection cell definition are first marked in the * search algorithm. After finishing the search, these marks are * erased. * * ---------------------------------------------------------------------------- */ TileListElt * SimSelectArea(Rect *rect) { int plane; int SimSelectFunc(); /* only need to extract node names if the selection has changed or * if node aliases are to be printed. */ if (SimRecomputeSel || (SimGetnodeAlias && SimIsGetnode)) { SimFreeNodeList(&NodeList); HashInit(&SimAbortSeenTbl, 20, HT_STRINGKEYS); /* find all nodes in the current selection */ for (plane = PL_TECHDEPBASE; plane < DBNumPlanes; plane++) { (void) DBSrPaintArea((Tile *) NULL, SelectDef->cd_planes[plane], &TiPlaneRect, &DBAllButSpaceAndDRCBits, SimSelectFunc, (ClientData) &NodeList); } HashKill(&SimAbortSeenTbl); ExtResetTiles(SelectDef, (ClientData) CLIENTDEFAULT); SimGetNodeCleanUp(); SimRecomputeSel = FALSE; } if (SigInterruptPending) { /* if caught an interrupt, be sure to recompute the selection * next time around. */ SimRecomputeSel = TRUE; } return(NodeList); } /* * ---------------------------------------------------------------------------- * SimSelectFunc * * This procedure is called for each tile in the current selection. * It first checks to see if the node the tile belongs to has not * yet been visited. If it has not been visited, then the node name * is extracted and all other tiles in the selection which belong to * this node are marked. * * Results: * Return 0 to keep the search going. * * Side effects: * The tiles in the selection cell definition are left marked. * It is the responsibility of the calling function to erase these * tile marks when finished. * ---------------------------------------------------------------------------- */ int SimSelectFunc(tile, pHead) Tile *tile; /* Tile in SelectDef. */ TileListElt **pHead; /* list of node names found */ { TileTypeBitMask mask; SearchContext scx; DBWclientRec *crec; MagWindow *window; char nameBuff[256], *nodeName; TileListElt *newNodeTile; TileType type; bool coord; window = CmdGetRootPoint((Point *) NULL, &scx.scx_area); if (window == NULL) return 1; /* check to see if the node has already been extracted */ if (tile->ti_client == (ClientData) 1) { return(0); } if (IsSplit(tile)) { type = (SplitSide(tile)) ? SplitRightType(tile): SplitLeftType(tile); } else type = TiGetTypeExact(tile); /* get the tile's area, and initialize the tile's search context. */ TITORECT(tile, &scx.scx_area); /* make sure that search context isn't placed on an empty */ /* corner of a split tile. */ if (IsSplit(tile)) { if (SplitSide(tile)) scx.scx_area.r_xbot = scx.scx_area.r_xtop - 1; if (!(SplitDirection(tile) ^ SplitSide(tile))) scx.scx_area.r_ybot = scx.scx_area.r_ytop - 1; } scx.scx_area.r_xtop = scx.scx_area.r_xbot + 1; scx.scx_area.r_ytop = scx.scx_area.r_ybot + 1; scx.scx_use = (CellUse *) window->w_surfaceID; scx.scx_trans = GeoIdentityTransform; crec = (DBWclientRec *) window->w_clientData; TTMaskZero(&mask); TTMaskSetType(&mask, type); TTMaskAndMask(&mask, &crec->dbw_visibleLayers); TTMaskAndMask(&mask, &DBAllButSpaceAndDRCBits); /* Check if the area is above a layer which is not visible. */ if (TTMaskIsZero(&mask)) { return(0); } /* mark all other tiles in the selection that are part of this node */ SimSrConnect(SelectDef, &scx.scx_area, &DBAllButSpaceAndDRCBits, DBConnectTbl, &TiPlaneRect, NullFunc, (ClientData) NULL); /* Pick a tile type to use for selection. */ for (type = TT_TECHDEPBASE; type < DBNumTypes; type += 1) { if (TTMaskHasType(&mask, type)) break; } nodeName = SimSelectNode(&scx, type, CU_DESCEND_ALL, nameBuff); /* add the node name to the list only if it has not been seen yet */ coord = (nodeName[0] == '@' && nodeName[1] == '=') ? TRUE : FALSE; if(coord || HashLookOnly(&SimNodeNameTbl, nodeName) == (HashEntry *) NULL) { if( ! coord ) HashFind(&SimNodeNameTbl, nodeName); newNodeTile = (TileListElt *) mallocMagic((unsigned) (sizeof (TileListElt))); newNodeTile->tl_nodeName = (char *) mallocMagic((unsigned) (strlen(nodeName) + 1)); strcpy(newNodeTile->tl_nodeName, nodeName); newNodeTile->tl_nodeTile = tile; newNodeTile->tl_next = *pHead; *pHead = newNodeTile; } return(0); } #ifdef RSIM_MODULE /* * ---------------------------------------------------------------------------- * SimSelection * * This procedure applies the specified rsim command to the list of * nodes in the current selection and also attaches the rsim node * value string to each node. * * Results: * returns FALSE if no nodes are in the selection. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool SimSelection(cmd) char *cmd; /* rsim command to apply to the selection */ { static char Hstring[] = "RSIM=1"; static char Lstring[] = "RSIM=0"; static char Xstring[] = "RSIM=X"; static char QUESTstring[] = "?"; char timeString[256]; TileListElt *current, *node_list; char *replyLine; char *strPtr; bool goodReply; extern RsimErrorMsg(); timeString[0] = 0; /* check to see if Rsim has been started yet */ if (!SimRsimRunning) { RsimErrorMsg(); return(FALSE); } /* get the list of all nodes in the selection */ SimIsGetnode = FALSE; SimUseCoords = SimHasCoords; HashInit(&SimNodeNameTbl, 60, HT_STRINGKEYS); node_list = SimSelectArea((Rect *)NULL); if (node_list == (TileListElt *) NULL) { TxPrintf("You must select paint (rather than a cell) to use Rsim on \ the selection.\n"); goto bad; } /* Walk the list of node names, apply the rsim command to each node, * and then process the results. */ for (current = node_list; current != NULL; current = current->tl_next) { current->tl_simLabel = QUESTstring; SimRsimIt(cmd, current->tl_nodeName); if (!SimGetReplyLine(&replyLine)) { goto bad; } if (!replyLine) { /* Rsim's reponse to the command was just a prompt. We are done * with the current node, so process the next node in the * selection. */ continue; } /* check for node names not recognized by Rsim */ if (strncmp(replyLine, "time = ", 7) == 0) { if (timeString[0] == 0) { strcpy(timeString, replyLine); } TxPrintf("%s not recognized in sim file\n", current->tl_nodeName); while(replyLine) { /* swallow Rsim reply until no more is left */ if (!SimGetReplyLine(&replyLine)) { goto bad; } } continue; } /* update the node value label strings */ if (*cmd == 'd') { char *name = current->tl_nodeName; bool coord = (name[0] == '@' && name[1] == '=') ? TRUE : FALSE; strPtr = rindex( replyLine, '=' ); if( strPtr == NULL ) strPtr = QUESTstring; else if( coord ) { *strPtr = '\0'; name = replyLine; if( HashLookOnly(&SimNodeNameTbl, name) == (HashEntry *) NULL) { freeMagic(current->tl_nodeName); current->tl_nodeName = (char *) mallocMagic((unsigned) (strlen(name) + 1)); strcpy(current->tl_nodeName, name); HashFind(&SimNodeNameTbl, current->tl_nodeName); *strPtr++ = '='; } else { current = simFreeNodeEntry( node_list, current ); *strPtr = '='; } } else strPtr++; switch (*strPtr) { case '1' : current->tl_simLabel = Hstring; break; case '0' : current->tl_simLabel = Lstring; break; case 'X' : current->tl_simLabel = Xstring; break; case '=' : break; default : current->tl_simLabel = QUESTstring; break; } } /* read all lines of the Rsim reply */ goodReply = TRUE; for (;replyLine; goodReply = SimGetReplyLine(&replyLine)) { if (!goodReply) { goto bad; } if (!strncmp(replyLine, "time = ", 7)) { if (!(timeString[0])) { strcpy(timeString, replyLine); } continue; } else if( *strPtr != '=' ) { TxPrintf("%s\n", replyLine); } } } if (timeString[0] != 0) { TxPrintf("%s\n", timeString); } HashKill(&SimNodeNameTbl); return(TRUE); bad: HashKill(&SimNodeNameTbl); return(FALSE); } #endif /* * ---------------------------------------------------------------------------- * SimAddLabels * * This procedure adds the node value labels to the Magic database * so they will be displayed in the layout. * * Results: * None. * * Side effects: * The cell modified flags are deliberately not set when these labels * are added to the database. * * ---------------------------------------------------------------------------- */ void SimAddLabels(SelectNodeList, rootuse) TileListElt *SelectNodeList; CellDef *rootuse; /* the root cell def for the window */ { TileListElt *current; Rect selectBox; int pos; /* walk the list of selected nodes, add the node value label to the * database. */ for (current = SelectNodeList; current != (TileListElt *) NULL; current = current->tl_next) { if (*(current->tl_simLabel) == '?') { continue; } TiToRect(current->tl_nodeTile, &selectBox); pos = SimPutLabel(rootuse, &selectBox, GEO_CENTER, current->tl_simLabel, TT_SPACE); DBReComputeBbox(rootuse); DBWLabelChanged(rootuse, current->tl_simLabel, &selectBox, pos, DBW_ALLWINDOWS); } } #ifdef RSIM_MODULE /* * ---------------------------------------------------------------------------- * SimRsimMouse * * This procedure erases the old rsim node labels and display the * node labels of the current selection. * * Results: * None. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ void SimRsimMouse(w) MagWindow *w; { CellUse *cu; bool sawcell; SimDefListElt *dummy; if ((w == (MagWindow *) NULL) || (w->w_client != DBWclientID)) { TxError("Put the cursor in a layout window\n"); return; } cu = (CellUse *)w->w_surfaceID; /* get root cell use for wind */ /* check to see if the cell def is already in our list */ sawcell = FALSE; for (dummy = SimCellLabList; dummy; dummy = dummy->dl_next) { if (dummy->dl_def == cu->cu_def) { sawcell = TRUE; break; } } if (!sawcell) { /* add the cell def to the list */ if (SimCellLabList == (SimDefListElt *) NULL) { SimCellLabList = (SimDefListElt *) mallocMagic((unsigned) (sizeof(SimDefListElt))); SimCellLabList->dl_isMarked = FALSE; SimCellLabList->dl_def = cu->cu_def; SimCellLabList->dl_next = (SimDefListElt *) NULL; dummy = SimCellLabList; } else { dummy = (SimDefListElt *) mallocMagic((unsigned) (sizeof(SimDefListElt))); dummy->dl_isMarked = FALSE; dummy->dl_next = SimCellLabList; dummy->dl_def = cu->cu_def; SimCellLabList= dummy; } } SimEraseLabels(); if (SimSelection("d")) { dummy->dl_isMarked = TRUE; SimAddLabels(NodeList, dummy->dl_def); } } #endif /* * ---------------------------------------------------------------------------- * SimGetnode * * This procedure prints the node names of all selected nodes. * * Results: * None. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ void SimGetnode() { TileListElt *current; /* get the list of node names */ SimIsGetnode = TRUE; SimUseCoords = FALSE; HashInit(&SimNodeNameTbl, 60, HT_STRINGKEYS); current = SimSelectArea((Rect *)NULL); HashKill(&SimNodeNameTbl); if (current == (TileListElt *) NULL) { TxPrintf("You must select paint (not a cell) to use getnode.\n"); return; } for (; current != (TileListElt *) NULL; current = current->tl_next) { #ifdef MAGIC_WRAPPER /* Return the node name as the result of the command */ Tcl_AppendElement(magicinterp, current->tl_nodeName); #else TxPrintf("node name : %s\n", current->tl_nodeName); #endif } } /* * ---------------------------------------------------------------------------- * SimGetsnode * * This procedure prints the short node names of all selected nodes. * * Results: * None. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ void SimGetsnode() { TileListElt *current; /* get the list of node names */ SimIsGetnode = TRUE; SimUseCoords = TRUE; HashInit(&SimNodeNameTbl, 60, HT_STRINGKEYS); current = SimSelectArea((Rect *)NULL); HashKill(&SimNodeNameTbl); if (current == (TileListElt *) NULL) { TxPrintf("You must select paint (not a cell) to use getnode.\n"); return; } for (; current != (TileListElt *) NULL; current = current->tl_next) { #ifdef MAGIC_WRAPPER /* Return the node short name as the result of the command */ Tcl_AppendElement(magicinterp, current->tl_nodeName); #else TxPrintf("short node name : %s\n", current->tl_nodeName); #endif } } /* * ---------------------------------------------------------------------------- * SimEraseLabels * * This procedure erases the RSIM labels from any cell defs they * may have been added to. * * Results: * None. * * Side effects: * Removes the RSIM labels from "marked" cell defs. * * ---------------------------------------------------------------------------- */ void SimEraseLabels() { SimDefListElt *p; for (p = SimCellLabList; p; p = p->dl_next) { if (p->dl_isMarked) { p->dl_isMarked = FALSE; DBEraseLabelsByContent(p->dl_def, (Rect *)NULL, -1, "RSIM=X"); DBEraseLabelsByContent(p->dl_def, (Rect *)NULL, -1, "RSIM=1"); DBEraseLabelsByContent(p->dl_def, (Rect *)NULL, -1, "RSIM=0"); } } } magic-8.0.210/cif/0000755000175000001440000000000012502054263012212 5ustar timusersmagic-8.0.210/cif/CIFrdutils.c0000664000175000001440000012143612364011344014376 0ustar timusers/* CIFreadutils.c - * * This file contains routines that parse a file in CIF * format. This file contains the top-level routine for * reading CIF files, plus a bunch of utility routines * for skipping white space, parsing numbers and points, etc. * * ********************************************************************* * * 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/cif/CIFrdutils.c,v 1.4 2010/06/24 12:37:15 tim Exp $"; #endif /* not lint */ #include #include #include #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "cif/CIFint.h" #include "cif/CIFread.h" #include "cif/cif.h" #include "textio/textio.h" #include "utils/signals.h" #include "utils/undo.h" #include "utils/malloc.h" /* The following variables are used to provide one character of * lookahead. cifParseLaAvail is TRUE if cifParseLaChar contains * a valid character, FALSE otherwise. The PEEK and TAKE macros * are used to manipulate this stuff. */ bool cifParseLaAvail = FALSE; int cifParseLaChar = EOF; /* Below is a variable pointing to the CIF input file. It's used * by the PEEK and TAKE macros. The other stuff is used to keep * track of our location in the CIF file for error reporting * purposes. */ FILE *cifInputFile; FILE *cifErrorFile; int cifLineNumber; /* Number of current line. */ int cifTotalWarnings; /* Number of warnings detected */ int cifTotalErrors; /* Number of errors detected */ /* The variables used below hold general information about what * we're currently working on. */ int cifReadScale1; /* Scale factor: multiply by Scale1 */ int cifReadScale2; /* then divide by Scale2. */ int CIFRescaleLimit = CIFMAXRESCALE; /* Don't increase cifReadScale1 by more * than this amount; internal units * finer than this will be rounded. */ bool CIFRescaleAllow = TRUE; /* Don't subdivide the magic internal * grid if this is FALSE. */ bool CIFNoDRCCheck = FALSE; /* If TRUE, then cell is marked DRC clean * and not DRC checked. */ char *CIFErrorFilename; /* Name of file for error redirection */ int CifPolygonCount; /* Count of generated subcells * containing polygons. This number * is used to create a unique cell name. */ bool CIFSubcellPolygons = FALSE; /* If TRUE, each non-Manhattan polygon * will be put in a separate subcell * to avoid too much tile splitting */ Plane *cifReadPlane; /* Plane into which to paint material * NULL means no layer command has * been seen for the current cell. */ /* * ---------------------------------------------------------------------------- * * CIFReadError -- * * This procedure is called to print out error messages during * CIF file reading. * * Results: * None. * * Side effects: * An error message is printed. * * ---------------------------------------------------------------------------- */ /* VARARGS1 */ void CIFReadError(char *format, ...) { va_list args; cifTotalErrors++; if (CIFWarningLevel == CIF_WARN_NONE) return; if ((cifTotalErrors < 100) || (CIFWarningLevel != CIF_WARN_LIMIT)) { TxError("Error at line %d of CIF file: ", cifLineNumber); va_start(args, format); Vfprintf(stderr, format, args); va_end(args); } else if ((cifTotalErrors == 100) && (CIFWarningLevel == CIF_WARN_LIMIT)) { TxError("Error limit set: Remaining errors will not be reported.\n"); } } void CIFReadWarning(char *format, ...) { va_list args; cifTotalWarnings++; if (CIFWarningLevel == CIF_WARN_NONE) return; if ((cifTotalWarnings < 100) || (CIFWarningLevel != CIF_WARN_LIMIT)) { TxError("Warning at line %d of CIF file: ", cifLineNumber); va_start(args, format); Vfprintf(stderr, format, args); va_end(args); } else if ((cifTotalWarnings == 100) && (CIFWarningLevel == CIF_WARN_LIMIT)) { TxError("Warning limit set: Remaining warnings will not be reported.\n"); } } /* * ---------------------------------------------------------------------------- * * CIFScaleCoord * * This procedure does rounding and division to convert from * CIF units back into Magic units. * * "snap_type" may be one of: * COORD_EXACT: result must be an exact integer. If not, the * magic grid spacing is changed such that the result will * be an integer. * COORD_HALF_U: twice the result must be an exact integer. If * not, the magic grid spacing is changed as above. If the * result is 1/2, it is rounded up to the nearest integer. * COORD_HALF_L: same as above, but result is rounded down. * COORD_ANY: result may be fractional, and will be snapped to * the nearest magic grid. Generally, this is used for * labels whose position need not be exact. * * Results: * The result is the Magic unit equivalent to cifCoord. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ int CIFScaleCoord(cifCoord, snap_type) int cifCoord; /* A coordinate in CIF units. */ int snap_type; /* How to deal with fractional results */ { int result, scale, remain, denom; int mult, mfactor; /* If internal grid subdivision is disallowed, always round to the */ /* nearest grid unit. */ if (!CIFRescaleAllow) snap_type = COORD_ANY; scale = cifCurReadStyle->crs_scaleFactor; mult = cifCurReadStyle->crs_multiplier; /* Check for non-integer result and warn of fractional-lambda violation */ if ((remain = (cifCoord % scale)) != 0) { int lgcf = FindGCF(abs(cifCoord), scale); remain = abs(remain) / lgcf; denom = scale / lgcf; if (CIFTechLimitScale(1, denom)) snap_type = COORD_ANY; switch (snap_type) { case COORD_EXACT: CIFReadWarning("Input off lambda grid by %d/%d; grid redefined.\n", remain, denom); CIFTechInputScale(1, denom, FALSE); CIFTechOutputScale(1, denom); DRCTechScale(1, denom); PlowAfterTech(); ExtTechScale(1, denom); WireTechScale(1, denom); #ifdef LEF_MODULE LefTechScale(1, denom); #endif #ifdef ROUTE_MODULE RtrTechScale(1, denom); MZAfterTech(); IRAfterTech(); #endif DBScaleEverything(denom, 1); DBLambda[1] *= denom; ReduceFraction(&DBLambda[0], &DBLambda[1]); scale = cifCurReadStyle->crs_scaleFactor; result = cifCoord / scale; break; case COORD_HALF_U: case COORD_HALF_L: if (denom > 2) { CIFReadWarning("Input off lambda grid by %d/%d; grid redefined.\n", remain, denom); /* scale to nearest half-lambda */ if (!(denom & 0x1)) denom >>= 1; CIFTechInputScale(1, denom, FALSE); CIFTechOutputScale(1, denom); DRCTechScale(1, denom); PlowAfterTech(); ExtTechScale(1, denom); WireTechScale(1, denom); MZAfterTech(); IRAfterTech(); #ifdef LEF_MODULE LefTechScale(1, denom); #endif #ifdef ROUTE_MODULE RtrTechScale(1, denom); #endif DBScaleEverything(denom, 1); DBLambda[1] *= denom; ReduceFraction(&DBLambda[0], &DBLambda[1]); scale = cifCurReadStyle->crs_scaleFactor; } if (snap_type == COORD_HALF_U) result = cifCoord + (scale >> 1); else result = cifCoord - (scale >> 1); result /= scale; break; case COORD_ANY: CIFReadWarning("Input off lambda grid by %d/%d; snapped to grid.\n", abs(remain), abs(denom)); /* Careful: must round down a bit more for negative numbers, in * order to ensure that a point exactly halfway between Magic units * always gets rounded down, rather than towards zero (this would * result in different treatment of the same paint, depending on * where it is in the coordinate system. */ if (cifCoord < 0) result = cifCoord - ((scale)>>1); else result = cifCoord + ((scale-1)>>1); result /= scale; break; } } else result = cifCoord / scale; return result; } /* * ---------------------------------------------------------------------------- * * cifIsBlank -- * * Figures out whether a character qualifies as a blank in CIF. * A blank is anything except a digit, an upper-case character, * or the symbols "-", "(", "(", and ";". * * Results: * Returns TRUE if ch is a CIF blank, FALSE otherwise. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool cifIsBlank(ch) int ch; { if ( isdigit(ch) || isupper(ch) || (ch == '-') || (ch == ';') || (ch == '(') || (ch == ')') || (ch == EOF)) { return FALSE; } else return TRUE; } /* * ---------------------------------------------------------------------------- * * CIFSkipBlanks -- * * This procedure skips over whitespace in the CIF file, * keeping track of the line number and other information * for error reporting. * * Results: * None. * * Side effects: * Advances through the CIF file. * * ---------------------------------------------------------------------------- */ void CIFSkipBlanks() { while (cifIsBlank(PEEK())) { if (TAKE() == '\n') { cifLineNumber++; } } } /* * ---------------------------------------------------------------------------- * * CIFSkipSep -- * * Skip over separators in the CIF file. Blanks and upper-case * characters are separators. * * Results: * None. * * Side effects: * Advances through the CIF file. * * ---------------------------------------------------------------------------- */ void CIFSkipSep() { int ch; for (ch = PEEK() ; isupper(ch) || cifIsBlank(ch) ; ch = PEEK()) { if (TAKE() == '\n') { cifLineNumber++; } } } /* * ---------------------------------------------------------------------------- * * CIFSkipToSemi -- * * This procedure is called after errors. It skips everything * in the CIF file up to the next semi-colon. * * Results: * None. * * Side effects: * Advances through the CIF file. * * ---------------------------------------------------------------------------- */ void CIFSkipToSemi() { int ch; for (ch = PEEK() ; ((ch != ';') && (ch != EOF)) ; ch = PEEK()) { if (TAKE() == '\n') { cifLineNumber++; } } } /* * ---------------------------------------------------------------------------- * * CIFSkipSemi -- * * Skips a semi-colon, including blanks around the semi-colon. * * Results: * None. * * Side effects: * Advances through the CIF file. * * ---------------------------------------------------------------------------- */ void CIFSkipSemi() { CIFSkipBlanks(); if (PEEK() != ';') { CIFReadError("`;\' expected.\n"); return; } TAKE(); CIFSkipBlanks(); } /* * ---------------------------------------------------------------------------- * * CIFParseSInteger -- * * This procedure parses a signed integer from the CIF file. * * Results: * TRUE is returned if the parse completed without error, * FALSE otherwise. * * Side effects: * The integer pointed to by valuep is modified with the * value of the signed integer. * * ---------------------------------------------------------------------------- */ bool CIFParseSInteger(valuep) int *valuep; { bool is_signed; char buffer[ BUFSIZ ]; char *bufferp; *valuep = 0; CIFSkipSep(); if (PEEK() == '-') { TAKE(); is_signed = TRUE; } else is_signed = FALSE; bufferp = &buffer[0]; while (isdigit(PEEK())) *bufferp++ = TAKE(); if (bufferp == &buffer[0]) return FALSE; *bufferp = '\0'; *valuep = atoi(&buffer[0]); if (is_signed) *valuep = -(*valuep); return TRUE; } /* * ---------------------------------------------------------------------------- * * CIFParseInteger -- * * Parses a positive integer from the CIF file. * * Results: * TRUE is returned if the parse was completed successfully, * FALSE otherwise. * * Side effects: * The value pointed to by valuep is modified to hold the integer. * * ---------------------------------------------------------------------------- */ bool CIFParseInteger(valuep) int *valuep; { if (!CIFParseSInteger(valuep)) return FALSE; if (*valuep < 0) CIFReadError("negative integer not permitted.\n"); return TRUE; } /* * ---------------------------------------------------------------------------- * * CIFParsePoint -- * * Parse a point from a CIF file. A point is two integers * separated by CIF separators. * parameter "iscale" (internal scale factor) is usually 1, but * can be 2 to deal with half-lambda entries in the CIF by * returning double the result. * * Results: * TRUE is returned if the point was parsed correctly, otherwise * FALSE is returned. * * Side effects: * The parameter pointp is filled in with the coordinates of * the point. * * If the CIF scalefactors are such that the result would be a * fractional value, the definition of the CIF scale is altered * such that the result is integer, and all geometry read so far * is altered to match. This does not immediately affect the geometry * in the magic database; if that also appears to have fractional * units, it will be discovered by CIFScaleCoord and corrected. * * ---------------------------------------------------------------------------- */ bool CIFParsePoint(pointp, iscale) Point *pointp; int iscale; { int rescale; pointp->p_x = 0; pointp->p_y = 0; if (!CIFParseSInteger(&pointp->p_x)) return FALSE; pointp->p_x *= (cifReadScale1 * iscale); if (pointp->p_x % cifReadScale2 != 0) { rescale = cifReadScale2 / FindGCF(cifReadScale2, abs(pointp->p_x)); if ((cifReadScale1 * rescale) > CIFRescaleLimit) { CIFReadWarning("CIF units at maximum scale; value is rounded\n"); /* prepare for nearest-integer rounding */ if (pointp->p_x < 0) pointp->p_x -= ((cifReadScale2 - 1) >> 1); else pointp->p_x += (cifReadScale2 >> 1); } else { cifReadScale1 *= rescale; CIFInputRescale(rescale, 1); pointp->p_x *= rescale; } } pointp->p_x /= cifReadScale2; if (!CIFParseSInteger(&pointp->p_y)) return FALSE; pointp->p_y *= (cifReadScale1 * iscale); if (pointp->p_y % cifReadScale2 != 0) { rescale = cifReadScale2 / FindGCF(cifReadScale2, abs(pointp->p_y)); if ((cifReadScale1 * rescale) > CIFRescaleLimit) { CIFReadWarning("CIF units at maximum scale; value is rounded\n"); /* prepare for nearest-integer rounding */ if (pointp->p_y < 0) pointp->p_y -= ((cifReadScale2 - 1) >> 1); else pointp->p_y += (cifReadScale2 >> 1); } else { cifReadScale1 *= rescale; CIFInputRescale(rescale, 1); pointp->p_x *= rescale; pointp->p_y *= rescale; } } pointp->p_y /= cifReadScale2; return TRUE; } /* * ---------------------------------------------------------------------------- * * CIFParsePath -- * * This procedure parses a CIF path, which is sequence of * one or more points. * * Results: * TRUE is returned if the path was parsed successfully, * FALSE otherwise. * * Side effects: * Modifies the parameter pathheadpp to point to the path * that is constructed. * * Corrections: * CIF coordinates are multiplied by 2 to cover the case where * the path centerline lies on the half lambda grid but the line * itself is on-grid. This can't be done for polygons, so a * parameter "iscale" (internal scale) is added, and set to 1 for * polygons, 2 for wires when calling CIFParsePath(). * * ---------------------------------------------------------------------------- */ bool CIFParsePath(pathheadpp, iscale) CIFPath **pathheadpp; int iscale; { CIFPath *pathtailp, *newpathp; bool nonManhattan = FALSE; /* diagnostic only */ CIFPath path; int savescale; *pathheadpp = NULL; pathtailp = NULL; path.cifp_next = NULL; while (TRUE) { CIFSkipSep(); if (PEEK() == ';') break; savescale = cifReadScale1; if (!CIFParsePoint(&path.cifp_point, iscale)) { CIFFreePath(*pathheadpp); return FALSE; } if (savescale != cifReadScale1) { CIFPath *phead = *pathheadpp; int newscale = cifReadScale1 / savescale; while (phead != NULL) { phead->cifp_x *= newscale; phead->cifp_y *= newscale; phead = phead->cifp_next; } } newpathp = (CIFPath *) mallocMagic((unsigned) (sizeof (CIFPath))); *newpathp = path; if (*pathheadpp) { /* * Check that this segment is Manhattan. If not, remember the * fact and later introduce extra stair-steps to make the path * Manhattan. We don't do the stair-step introduction here for * two reasons: first, the same code is also used by the Calma * module, and second, it is important to know which side of * the polygon is the outside when generating the stair steps. */ if (pathtailp->cifp_x != newpathp->cifp_x && pathtailp->cifp_y != (newpathp->cifp_y)) { nonManhattan = TRUE; } pathtailp->cifp_next = newpathp; } else *pathheadpp = newpathp; pathtailp = newpathp; } return (*pathheadpp != NULL); } /* * ---------------------------------------------------------------------------- * * test_insideness -- * * Determine if a point is inside a rectangle defined by the * first three points in the given CIF path. * * Results: * TRUE if point is inside, FALSE if outside or on the border * * Side effects: * None. * ---------------------------------------------------------------------------- */ bool test_insideness(start, tpoint) CIFPath *start; Point *tpoint; { Rect tmprect, irect; tmprect.r_xbot = start->cifp_x; tmprect.r_ybot = start->cifp_y; tmprect.r_xtop = start->cifp_next->cifp_next->cifp_x; tmprect.r_ytop = start->cifp_next->cifp_next->cifp_y; GeoCanonicalRect(&tmprect, &irect); return ((tpoint->p_x > irect.r_xbot) && (tpoint->p_x < irect.r_xtop) && (tpoint->p_y > irect.r_ybot) && (tpoint->p_y < irect.r_ytop)) ? TRUE : FALSE; } /* * ---------------------------------------------------------------------------- * * seg_intersect -- * * Determine if two line segments intersect or touch * Expects first line to be manhattan. * * Results: * returns TRUE if segments intersect, FALSE otherwise * * Side effects: * value of respt contains point to which segment will be * truncated. * * ---------------------------------------------------------------------------- */ bool seg_intersect(tstart, bf, bs, respt) CIFPath *tstart; Point *bf, *bs; Point *respt; { int afx = tstart->cifp_x; int afy = tstart->cifp_y; int asx = tstart->cifp_next->cifp_x; int asy = tstart->cifp_next->cifp_y; int adx, ady; if (afx == asx) /* "a" is a vertical line */ { adx = afx + ((tstart->cifp_next->cifp_next->cifp_x > afx) ? 1 : -1); /* Ignore if b does not cross the x boundary of ad */ if ((bf->p_x > adx && bs->p_x > adx) || (bf->p_x < adx && bs->p_x < adx)) return FALSE; if (bs->p_x == bf->p_x) /* nonintersecting vertical lines */ return FALSE; respt->p_x = afx; respt->p_y = bf->p_y + (int) (((dlong)(bs->p_y - bf->p_y) * (dlong)(afx - bf->p_x)) / (dlong)(bs->p_x - bf->p_x)); if (((respt->p_y > afy) && (respt->p_y < asy)) || ((respt->p_y < afy) && (respt->p_y > asy))) return TRUE; } else /* (afy == asy), "a" is a horizontal line */ { ady = afy + ((tstart->cifp_next->cifp_next->cifp_y > afy) ? 1 : -1); /* Ignore if b does not cross the y boundary of ad */ if ((bf->p_y > ady && bs->p_y > ady) || (bf->p_y < ady && bs->p_y < ady)) return FALSE; if (bs->p_y == bf->p_y) /* nonintersecting horizontal lines */ return FALSE; respt->p_y = afy; respt->p_x = bf->p_x + (int) (((dlong)(bs->p_x - bf->p_x) * (dlong)(afy - bf->p_y)) / (dlong)(bs->p_y - bf->p_y)); if (((respt->p_x > afx) && (respt->p_x < asx)) || ((respt->p_x < afx) && (respt->p_x > asx))) return TRUE; } return FALSE; } /* * ---------------------------------------------------------------------------- * * path_intersect -- * * Determine if a path intersects the given line segment. * A path sharing a portion of the segment is not an intersection. * * ---------------------------------------------------------------------------- */ bool path_intersect(pathHead, start, respt) CIFPath *pathHead, *start; Point *respt; { CIFPath *path, *segcrossed, *new; Point tmppt; bool does_cross = FALSE, diagonal = FALSE; int tdist, newdist; tdist = newdist = INFINITY; for (path = pathHead; path->cifp_next; path = path->cifp_next) { /* don't compare with self */ if (path == start || path == start->cifp_next) continue; /* Does the path intersect the first line of the */ /* right triangle, continuing in the direction of */ /* the last point on the triangle? */ if (seg_intersect(start, &path->cifp_point, &path->cifp_next->cifp_point, &tmppt)) { newdist = (start->cifp_x - tmppt.p_x) + (start->cifp_y - tmppt.p_y); diagonal = TRUE; } /* Is the point inside the triangle, and the path is Manhattan? */ /* (Note that *both* tests can be true, in which case the one */ /* with the smaller absolute distance takes precedence.) */ if (test_insideness(start, &path->cifp_point)) { int tmpdist = abs(newdist); /* save this value */ if (path->cifp_x == path->cifp_next->cifp_x || path->cifp_y == path->cifp_next->cifp_y) { if (start->cifp_x == start->cifp_next->cifp_x) { newdist = path->cifp_y - start->cifp_y; if (abs(newdist) < tmpdist) { tmppt.p_x = start->cifp_x; tmppt.p_y = path->cifp_y; diagonal = FALSE; } } else { newdist = path->cifp_x - start->cifp_x; if (abs(newdist) < tmpdist) { tmppt.p_y = start->cifp_y; tmppt.p_x = path->cifp_x; diagonal = FALSE; } } } } else if (diagonal == FALSE) continue; newdist = abs(newdist); if ((!does_cross) || (newdist < tdist)) { does_cross = TRUE; respt->p_x = tmppt.p_x; respt->p_y = tmppt.p_y; tdist = newdist; segcrossed = (diagonal) ? path : NULL; } } /* If we're limited by another side of the polygon, then we're */ /* guaranteed that we'll have to add another point there. By */ /* doing it here, we avoid problems due to roundoff errors. */ if (does_cross && segcrossed) { new = (CIFPath *) mallocMagic((unsigned) (sizeof (CIFPath))); new->cifp_next = segcrossed->cifp_next; segcrossed->cifp_next = new; new->cifp_x = respt->p_x; new->cifp_y = respt->p_y; } return does_cross; } /* * ---------------------------------------------------------------------------- * * is_clockwise -- * * Determine if a path is clockwise or counterclockwise. * * Results: * TRUE if the path is clockwise, FALSE otherwise. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool is_clockwise(pathHead) CIFPath *pathHead; { CIFPath *path, *midx = NULL, *last; Point *p1, *p2, *p3; dlong sdir; int minx = INFINITY; /* Find out if this is a clockwise or counterclockwise path by */ /* finding the (a) leftmost point and assuming the polygon to fill */ /* is to the right. */ for (path = pathHead; path->cifp_next; path = path->cifp_next) { if (path->cifp_next->cifp_x < minx) { minx = path->cifp_next->cifp_x; midx = path->cifp_next; last = path; } } if (!midx) return TRUE; /* one-point polygon? */ /* Rare case of colinear points (implies degenerate polygon) requires */ /* moving along pointlist until points are not colinear and repeating */ /* the search for the minimum. */ if (last->cifp_x == midx->cifp_x) { for (path = pathHead; path && path->cifp_x == minx; path = path->cifp_next); if (!path) return TRUE; /* completely degenerate; direc. irrelevant */ minx = INFINITY; for (; path->cifp_next; path = path->cifp_next) { if (path->cifp_next->cifp_x < minx) { minx = path->cifp_next->cifp_x; midx = path->cifp_next; last = path; } } } if (!(midx->cifp_next)) midx = pathHead; /* p2 is the (a) leftmost point; p1 and p3 are the points before */ /* and after in the CIF path, respectively. */ p1 = &(last->cifp_point); p2 = &(midx->cifp_point); p3 = &(midx->cifp_next->cifp_point); /* Find which side p3 falls on relative to the line p1-p2. This */ /* determines whether the path is clockwise or counterclockwise. */ /* Use type dlong to avoid integer overflow. */ sdir = ((dlong)(p2->p_x - p1->p_x) * (dlong)(p3->p_y - p1->p_y) - (dlong)(p2->p_y - p1->p_y) * (dlong)(p3->p_x - p1->p_x)); return (sdir < 0) ? TRUE : FALSE; } /* * ---------------------------------------------------------------------------- * * CIFMakeManhattanPath -- * * Convert a non-Manhattan path into a Manhattan one by * breaking out triangles and leaving all Manhattan edges. * Additional points are added which reroute the CIF path * around the triangle. In the simplest case, each non-Manhattan * edge becomes a split tile bounding the edge endpoints. * However, if that split tile would extend beyond the boundary * of the CIF path, the edge is subdivided into as many * triangles as are necessary to complete the path while remaining * within the polygon boundary. Unfortunately, for non-45-degree * edges, the edge subdivision might not fall on an integer lambda * value, so the resulting edge could be off by as much as 1/2 * lambda. In this case, flag a warning. * * Results: * None. * * Side effects: * May insert additional points in the path. * May alter the intended geometry of a non-manhattan edge by as * much as 1/2 lambda. * * ---------------------------------------------------------------------------- */ void CIFMakeManhattanPath(pathHead, plane, resultTbl, ui) CIFPath *pathHead; Plane *plane; PaintResultType *resultTbl; PaintUndoInfo *ui; { CIFPath *new, *new2, *next, *path; int xinit, xdiff, xincr, xlast, x; int yinit, ydiff, yincr, ylast, y; bool clockwise; CIFPath *first, *last; Rect tt, tr; TileType type; clockwise = is_clockwise(pathHead); for (path = pathHead; path->cifp_next; path = path->cifp_next) { Point clipbase; int edir; next = path->cifp_next; /* No work if this segment is Manhattan */ if (path->cifp_x == next->cifp_x || path->cifp_y == next->cifp_y) continue; /* Otherwise, break out the triangle, then adjust as necessary */ new = (CIFPath *) mallocMagic((unsigned) (sizeof (CIFPath))); path->cifp_next = new; new->cifp_next = next; /* Generate split tiles as necessary to reach next->cifp_y */ if (clockwise) { first = next; last = path; } else { first = path; last = next; } edir = CIFEdgeDirection(first, last); if (edir == CIF_DIAG_DL || edir == CIF_DIAG_UR) { new->cifp_x = first->cifp_x; new->cifp_y = last->cifp_y; } else /* edir == CIF_DIAG_DR || edir == CIF_DIAG_UL */ { new->cifp_x = last->cifp_x; new->cifp_y = first->cifp_y; } /* Check if the segment from first to base intersects */ /* the polygon edge */ if (path_intersect(pathHead, path, &clipbase)) { new->cifp_x = clipbase.p_x; new->cifp_y = clipbase.p_y; new2 = (CIFPath *) mallocMagic((unsigned) (sizeof (CIFPath))); new->cifp_next = new2; new2->cifp_next = next; /* Use double long for the multiplication and */ /* division, or else integer overflow can occur. */ if (path->cifp_x == new->cifp_x) /* vertical line */ { new2->cifp_y = new->cifp_y; new2->cifp_x = path->cifp_x + (int) ((dlong)(new2->cifp_y - path->cifp_y) * (dlong)(next->cifp_x - path->cifp_x) / (dlong)(next->cifp_y - path->cifp_y)); } else { new2->cifp_x = new->cifp_x; new2->cifp_y = path->cifp_y + (int) ((dlong)(new2->cifp_x - path->cifp_x) * (dlong)(next->cifp_y - path->cifp_y) / (dlong)(next->cifp_x - path->cifp_x)); } } /* Break out the diagonal tile from the polygon and paint it. */ type = (edir == CIF_DIAG_UR || edir == CIF_DIAG_UL) ? 0 : TT_SIDE; type |= (edir == CIF_DIAG_UR || edir == CIF_DIAG_DL) ? 0 : TT_DIRECTION; type |= TT_DIAGONAL; tt.r_ll = path->cifp_point; tt.r_ur = path->cifp_next->cifp_next->cifp_point; GeoCanonicalRect(&tt, &tr); // TxPrintf("CIF read: Triangle %s %c at (%d, %d) plane %x\n", // (type & TT_SIDE) ? "right" : "left", (type & TT_DIRECTION) // ? '\\' : '/', tt.r_xbot, tt.r_ybot, plane); /* Final check---ensure that rectangle is not degenerate */ if (plane && (tr.r_xtop - tr.r_xbot > 0) && (tr.r_ytop - tr.r_ybot > 0)) DBNMPaintPlane(plane, type, &tr, resultTbl, ui); } } /* * ---------------------------------------------------------------------------- * * CIFEdgeDirection -- * * This procedure assigns a direction to the given edge. * * Results: * CIF_ZERO if the two points are the same * CIF_LEFT if the edge goes left * CIF_UP if the edge goes up * CIF_RIGHT if the edge goes right * CIF_DOWN if the edge goes down * CIF_DIAG if the edge is non-manhattan * * Side effects: * None. * * ---------------------------------------------------------------------------- */ int CIFEdgeDirection(first, last) CIFPath *first, *last; /* Edge to be categorized. */ { if (first->cifp_x < last->cifp_x) { if (first->cifp_y < last->cifp_y) return CIF_DIAG_UR; if (first->cifp_y > last->cifp_y) return CIF_DIAG_DR; return CIF_RIGHT; } if (first->cifp_x > last->cifp_x) { if (first->cifp_y < last->cifp_y) return CIF_DIAG_UL; if (first->cifp_y > last->cifp_y) return CIF_DIAG_DL; return CIF_LEFT; } if (first->cifp_y < last->cifp_y) return CIF_UP; if (first->cifp_y > last->cifp_y) return CIF_DOWN; return CIF_ZERO; } /* * ---------------------------------------------------------------------------- * * CIFCleanPath -- * * Removes a edge in a path if it has zero length (repeated points). * Combines two consecutive edges if their direction is the same, * and their direction is manhattan. * CIFCleanPath assumes that the path is closed, and will eliminate * the last edge if its direction is the same as the first. * * Results: * None. * * Side effects: * May delete points in the path. * * ---------------------------------------------------------------------------- */ void CIFCleanPath(pathHead) CIFPath *pathHead; { CIFPath *next, *path, *prev, *last; int dir1, dir2; if (!pathHead) return; prev = pathHead; path = prev->cifp_next; if (!path) return; while((dir1 = CIFEdgeDirection(prev, path)) == CIF_ZERO) { /* This is a repeated point. */ next = path->cifp_next; prev->cifp_next = next; freeMagic((char *) path); path = next; if (!path) return; } while (next = path->cifp_next) { if ((dir2 = CIFEdgeDirection(path, next)) == CIF_ZERO) { /* This is a repeated point. */ path->cifp_next = next->cifp_next; freeMagic((char *) next); continue; } /* Skip any non-manhattan (diagonal) edges. */ if (dir2 >= CIF_DIAG) goto path_inc; if (dir1 == dir2) { /* The middle point must go. */ prev->cifp_next = next; freeMagic((char *) path); path = next; dir1 = CIFEdgeDirection(prev, path); continue; } path_inc: dir1 = dir2; prev = path; path = next; } /* Ensure that the path has more than one point. */ if (!pathHead->cifp_next) { /* Ensure that the resulting path is closed. */ if ((pathHead->cifp_x != path->cifp_x) || (pathHead->cifp_y != path->cifp_y)) { next = (CIFPath *) mallocMagic((unsigned) (sizeof (CIFPath))); next->cifp_x = pathHead->cifp_x; next->cifp_y = pathHead->cifp_y; next->cifp_next = (CIFPath *) 0; path->cifp_next = next; prev = path; path = next; dir1 = CIFEdgeDirection(prev, path); } if ((dir2 = CIFEdgeDirection(pathHead, pathHead->cifp_next)) < CIF_DIAG) { /* We have at least two edges in the path. We have to */ /* fix the first edge and eliminate the last edge if */ /* the first and last edge have the same direction. */ if (dir1 == dir2) { pathHead->cifp_x = prev->cifp_x; pathHead->cifp_y = prev->cifp_y; prev->cifp_next = (CIFPath *) 0; freeMagic((char *) path); } } } } /* * ---------------------------------------------------------------------------- * * CIFFreePath -- * * This procedure frees up a path once it has been used. * * Results: * None. * * Side effects: * All the elements of path are returned to the storage allocator. * * ---------------------------------------------------------------------------- */ void CIFFreePath(path) CIFPath *path; /* Path to be freed. */ { while (path != NULL) { freeMagic((char *) path); path = path->cifp_next; } } /* * ---------------------------------------------------------------------------- * * cifCommandError -- * * This procedure is called when unknown CIF commands are found * in CIF files. It skips the command and advances to the next * command. * * Results: * None. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ void cifCommandError() { CIFReadError("unknown command `%c'; ignored.\n" , PEEK()); CIFSkipToSemi(); } /* * ---------------------------------------------------------------------------- * * cifParseEnd -- * * This procedure processes the "end" statement in a CIF file * (it ignores it). * * Results: * Always returns TRUE. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool cifParseEnd() { TAKE(); CIFSkipBlanks(); if (PEEK() != EOF) { CIFReadError("End command isn't at end of file.\n"); return FALSE; } return TRUE; } /* * ---------------------------------------------------------------------------- * * cifParseComment -- * * This command skips over user comments in CIF files. * * Results: * None. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool cifParseComment() { int opens; int ch; /* * take the '(' */ TAKE(); opens = 1; do { ch = TAKE(); if (ch == '(') opens++; else if (ch == ')') opens--; else if (ch == '\n') { cifLineNumber++; } else if (ch == EOF) { CIFReadError("(comment) extends to end of file.\n"); return FALSE; } } while (opens > 0); return TRUE; } /* * ---------------------------------------------------------------------------- * * CIFDirectionToTrans -- * * This procedure is used to convert from a direction vector * to a Magic transformation. The direction vector is a point * giving a direction from the origin. It better be along * one of the axes. * * Results: * The return value is the transformation corresponding to * the direction, or the identity transform if the direction * isn't along one of the axes. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ Transform * CIFDirectionToTrans(point) Point *point; /* Direction vector from origin. */ { if ((point->p_x != 0) && (point->p_y == 0)) { if (point->p_x > 0) return &GeoIdentityTransform; else return &Geo180Transform; } else if ((point->p_y != 0) && (point->p_x == 0)) { if (point->p_y > 0) return &Geo270Transform; else return &Geo90Transform; } CIFReadError("non-manhattan direction vector (%d, %d); ignored.\n", point->p_x, point->p_y); return &GeoIdentityTransform; } /* * ---------------------------------------------------------------------------- * * CIFParseTransform -- * * This procedure is called to read in a transform from a * CIF file. * * Results: * TRUE is returned if the parse completed successfully, and * FALSE is returned otherwise. * * Side effects: * The parameter pointed to by transformp is modified to * contain the transform indicated by the CIF file. * * ---------------------------------------------------------------------------- */ bool CIFParseTransform(transformp) Transform *transformp; { char ch; Point point; Transform tmp; int savescale; *transformp = GeoIdentityTransform; CIFSkipBlanks(); for (ch = PEEK() ; ch != ';' ; ch = PEEK()) { switch (ch) { case 'T': TAKE(); if (!CIFParsePoint(&point, 1)) { CIFReadError("translation, but no point.\n"); CIFSkipToSemi(); return FALSE; } GeoTranslateTrans(transformp, point.p_x, point.p_y, &tmp); *transformp = tmp; break; case 'M': TAKE(); CIFSkipBlanks(); ch = PEEK(); if (ch == 'X') GeoTransTrans(transformp, &GeoSidewaysTransform, &tmp); else if (ch == 'Y') GeoTransTrans(transformp, &GeoUpsideDownTransform, &tmp); else { CIFReadError("mirror, but not in X or Y.\n"); CIFSkipToSemi(); return FALSE; } TAKE(); *transformp = tmp; break; case 'R': TAKE(); if (!CIFParseSInteger(&point.p_x) || !CIFParseSInteger(&point.p_y)) { CIFReadError("rotation, but no direction.\n"); CIFSkipToSemi(); return FALSE; } GeoTransTrans(transformp, CIFDirectionToTrans(&point), &tmp); *transformp = tmp; break; default: CIFReadError("transformation expected.\n"); CIFSkipToSemi(); return FALSE; } CIFSkipBlanks(); } /* Before returning, we must scale the transform into Magic units. */ transformp->t_c = CIFScaleCoord(transformp->t_c, COORD_EXACT); savescale = cifCurReadStyle->crs_scaleFactor; transformp->t_f = CIFScaleCoord(transformp->t_f, COORD_EXACT); if (savescale != cifCurReadStyle->crs_scaleFactor) transformp->t_c *= (savescale / cifCurReadStyle->crs_scaleFactor); return TRUE; } /* * ---------------------------------------------------------------------------- * * CIFParseCommand -- * * Parse one CIF command and farm it out to a routine to handle * that command. * * Results: * None. * * Side effects: * May modify the contents of cifReadCellDef by painting or adding * new uses or labels. May also create new CellDefs. * * ---------------------------------------------------------------------------- */ void CIFReadFile(file) FILE *file; /* File from which to read CIF. */ { /* We will use 1-word CIF numbers as keys in this hash table */ CIFReadCellInit(1); if (cifCurReadStyle == NULL) { TxError("Don't know how to read CIF: nothing in tech file.\n"); return; } TxPrintf("Warning: CIF reading is not undoable! I hope that's OK.\n"); UndoDisable(); cifTotalWarnings = 0; cifTotalErrors = 0; CifPolygonCount = 0; cifInputFile = file; cifReadScale1 = 1; cifReadScale2 = 1; cifParseLaAvail = FALSE; cifLineNumber = 1; cifReadPlane = (Plane *) NULL; cifCurLabelType = TT_SPACE; while (PEEK() != EOF) { if (SigInterruptPending) goto done; CIFSkipBlanks(); switch (PEEK()) { case EOF: break; case ';': break; case 'B': (void) CIFParseBox(); break; case 'C': (void) CIFParseCall(); break; case 'D': TAKE(); CIFSkipBlanks(); switch (PEEK()) { case 'D': (void) CIFParseDelete(); break; case 'F': (void) CIFParseFinish(); break; case 'S': (void) CIFParseStart(); break; default: cifCommandError(); break; } break; case 'E': (void) cifParseEnd(); goto done; case 'L': (void) CIFParseLayer(); break; case 'P': (void) CIFParsePoly(); break; case 'R': (void) CIFParseFlash(); break; case 'W': (void) CIFParseWire(); break; case '(': (void) cifParseComment(); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': (void) CIFParseUser(); break; default: cifCommandError(); break; } CIFSkipSemi(); } CIFReadError("no \"End\" statement.\n"); done: CIFReadCellCleanup(0); UndoEnable(); } magic-8.0.210/cif/CIFrdpoly.c0000644000175000001440000002046111410650573014217 0ustar timusers/* CIFreadpoly.c - * * This file contains procedures that turn polygons into * rectangles, as part of CIF file reading. * * ********************************************************************* * * 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/cif/CIFrdpoly.c,v 1.3 2010/06/24 12:37:15 tim Exp $"; #endif /* not lint */ #include #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "cif/CIFint.h" #include "cif/CIFread.h" #include "utils/malloc.h" #define HEDGE 0 /* Horizontal edge */ #define REDGE 1 /* Rising edge */ #define FEDGE -1 /* Falling edge */ /* * ---------------------------------------------------------------------------- * * cifLowX -- * * This is a comparison procedure called by qsort. * * Results: * 1 if a.x > b.x, * -1 if a.x < b.x, * 0 otherwise. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ int cifLowX(a, b) CIFPath **a, **b; { Point *p, *q; p = &(*a)->cifp_point; q = &(*b)->cifp_point; if (p->p_x < q->p_x) return (-1); if (p->p_x > q->p_x) return (1); return (0); } /* * ---------------------------------------------------------------------------- * * cifLowY -- * * This is another comparison procedure called by qsort. * * Results: * 1 if a.y > b.y * -1 if a.y < b.y * 0 otherwise * * Side effects: * None. * * ---------------------------------------------------------------------------- */ int cifLowY(a, b) Point **a, **b; { if ((*a)->p_y < (*b)->p_y) return (-1); if ((*a)->p_y > (*b)->p_y) return (1); return (0); } /* * ---------------------------------------------------------------------------- * * cifOrient -- * * This procedure assigns a direction to each of the edges in a * polygon. * * Results: * TRUE is returned if all of the edges are horizontal or vertical, * FALSE is returned otherwise. If FALSE is returned, not all of * the directions will have been filled in. * * Side effects: * The parameter dir is filled in with the directions, which are * each one of HEDGE, REDGE, or FEDGE. * * ---------------------------------------------------------------------------- */ bool cifOrient(edges, nedges, dir) CIFPath *edges[]; /* Array of edges to be categorized. */ int dir[]; /* Array to hold directions. */ int nedges; /* Size of arrays. */ { Point *p, *q; int n; for (n = 0; n < nedges; n++) { /* note - path list should close on itself */ p = &edges[n]->cifp_point; q = &edges[n]->cifp_next->cifp_point; if (p->p_y == q->p_y) { /* note - point may connect to itself here */ dir[n] = HEDGE; continue; } if (p->p_x == q->p_x) { if (p->p_y < q->p_y) { dir[n] = REDGE; continue; } if (p->p_y > q->p_y) { dir[n] = FEDGE; continue; } /* Point connects to itself */ dir[n] = HEDGE; continue; } /* It's not Manhattan, folks. */ return (FALSE); } return (TRUE); } /* * ---------------------------------------------------------------------------- * * cifCross -- * * This procedure is used to see if an edge crosses a particular * area. * * Results: * TRUE is returned if edge is vertical and if it crosses the * y-range defined by ybot and ytop. FALSE is returned otherwise. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool cifCross(edge, dir, ybot, ytop) CIFPath *edge; /* Pointer to first of 2 path points in edge */ int dir; /* Direction of edge */ int ybot, ytop; /* Range of interest */ { int ebot, etop; switch (dir) { case REDGE: ebot = edge->cifp_point.p_y; etop = edge->cifp_next->cifp_point.p_y; return (ebot <= ybot && etop >= ytop); case FEDGE: ebot = edge->cifp_next->cifp_point.p_y; etop = edge->cifp_point.p_y; return (ebot <= ybot && etop >= ytop); } return (FALSE); } /* * ---------------------------------------------------------------------------- * * CIFPolyToRects -- * * Converts a manhattan polygon (specified as a path) into a * linked list of rectangles. * * Results: * The return value is a linked list of rectangles, or NULL if * something went wrong. * * Side effects: * Memory is allocated to hold the list of rectangles. It is * the caller's responsibility to free up the memory. * * ---------------------------------------------------------------------------- */ LinkedRect * CIFPolyToRects(path, plane, resultTbl, ui) CIFPath *path; /* Path describing a polygon. */ Plane *plane; /* Plane to draw on */ PaintResultType *resultTbl; PaintUndoInfo *ui; { int npts = 0, n, *dir, curr, wrapno; int xbot, xtop, ybot, ytop; Point **pts; CIFPath *p, **edges, *tail = 0; LinkedRect *rex = 0, *new; /* Close path list. */ for (tail = path; tail->cifp_next; tail = tail->cifp_next); if ((tail->cifp_x != path->cifp_x) || (tail->cifp_y != path->cifp_y)) { p = (CIFPath *) mallocMagic ((unsigned) sizeof (CIFPath)); p->cifp_x = path->cifp_x; p->cifp_y = path->cifp_y; p->cifp_next = (CIFPath *) 0; tail->cifp_next = p; } CIFMakeManhattanPath(path, plane, resultTbl, ui); for (p = path; p->cifp_next; p = p->cifp_next, npts++); pts = (Point **)mallocMagic(npts * sizeof(Point *)); dir = (int *)mallocMagic(npts * sizeof(int)); edges = (CIFPath **)mallocMagic(npts * sizeof(CIFPath *)); npts = 0; for (p = path; p->cifp_next; p = p->cifp_next, npts++) { pts[npts] = &(p->cifp_point); edges[npts] = p; } if (npts < 4) { CIFReadError("polygon with fewer than 4 points.\n" ); goto done; } /* Sort points by low y, edges by low x */ qsort ((char *) pts, npts, (int) sizeof (Point *), cifLowY); qsort ((char *) edges, npts, (int) sizeof (CIFPath *), cifLowX); /* Find out which direction each edge points. */ if (!cifOrient (edges, npts, dir)) { CIFReadError("non-manhattan polygon.\n" ); goto done; } /* Scan the polygon from bottom to top. At each step, process * a minimum-sized y-range of the polygon (i.e. a range such that * there are no vertices inside the range). Use wrap numbers * based on the edge orientations to determine how much of the * x-range for this y-range should contain material. */ for (curr = 1; curr < npts; curr++) { /* Find the next minimum-sized y-range. */ ybot = pts[curr-1]->p_y; while (ybot == pts[curr]->p_y) if (++curr >= npts) goto done; ytop = pts[curr]->p_y; /* Process all the edges that cross the y-range, from left * to right. */ for (wrapno=0, n=0; n < npts; n++) { if (wrapno == 0) xbot = edges[n]->cifp_x; if (!cifCross(edges[n], dir[n], ybot, ytop)) continue; wrapno += dir[n] == REDGE ? 1 : -1; if (wrapno == 0) { xtop = edges[n]->cifp_point.p_x; if (xbot == xtop) continue; new = (LinkedRect *) mallocMagic(sizeof(LinkedRect)); new->r_r.r_xbot = xbot; new->r_r.r_ybot = ybot; new->r_r.r_xtop = xtop; new->r_r.r_ytop = ytop; new->r_next = rex; rex = new; } } } /* Normally, the loop exits directly to done, below. It * only falls through here if the polygon has a degenerate * spike at its top (i.e. if there's only one point with * highest y-coordinate). */ done: freeMagic((char *)edges); freeMagic((char *)dir); freeMagic((char *)pts); return (rex); } magic-8.0.210/cif/CIFrdpt.c0000644000175000001440000005072111410650573013661 0ustar timusers/* CIFreadpaint.c - * * This file contains more routines to parse CIF files. In * particular, it contains the routines to handle paint, * including rectangles, wires, flashes, and polygons. * * ********************************************************************* * * 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/cif/CIFrdpt.c,v 1.2 2010/06/24 12:37:15 tim Exp $"; #endif /* not lint */ #include #include #include /* for wire path-to-poly path conversion */ #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "utils/malloc.h" #include "database/database.h" #include "windows/windows.h" #include "utils/main.h" #include "cif/CIFint.h" #include "cif/CIFread.h" /* * ---------------------------------------------------------------------------- * * CIFParseBox -- * * This procedure parses a CIF box command. * * Results: * TRUE is returned if the parse completed successfully, and * FALSE is returned otherwise. * * Side effects: * A box is added to the CIF information for this cell. The * box better not have corners that fall on half-unit boundaries. * * Correction: * A box may be centered on a half lambda grid but have width * and height such that the resulting box is entirely on the lambda * grid. So: don't divide by 2 until the last step! * ---Tim Edwards, 4/20/00 * * ---------------------------------------------------------------------------- */ bool CIFParseBox() { Point center; Point direction; Rect rectangle, r2; int savescale; /* Take the 'B'. */ TAKE(); if (cifReadPlane == NULL) { CIFSkipToSemi(); return FALSE; } /* Treat length and width as a point so we can make use of the code in */ /* CIFParsePoint(); however, before moving on, check that both values */ /* are strictly positive. */ if (!CIFParsePoint(&rectangle.r_ur, 1)) { CIFReadError("box, but no length and/or width; ignored.\n"); CIFSkipToSemi(); return FALSE; } if (rectangle.r_xtop <= 0) { CIFReadError("box length not strictly positive; ignored.\n"); CIFSkipToSemi(); return FALSE; } if (rectangle.r_ytop <= 0) { CIFReadError("box width not strictly positive; ignored.\n"); CIFSkipToSemi(); return FALSE; } savescale = cifReadScale1; if (!CIFParsePoint(¢er, 2)) { CIFReadError("box, but no center; ignored.\n"); CIFSkipToSemi(); return FALSE; } /* If reading the center causes a CIF input scale to be redefined, */ /* then the length and width must also be changed. */ if (savescale != cifReadScale1) { rectangle.r_xtop *= (cifReadScale1 / savescale); rectangle.r_ytop *= (cifReadScale1 / savescale); } rectangle.r_xbot = -rectangle.r_xtop; rectangle.r_ybot = -rectangle.r_ytop; /* Optional direction vector: have to build transform to do rotate. */ if (CIFParseSInteger(&direction.p_x)) { if (!CIFParseSInteger(&direction.p_y)) { CIFReadError("box, direction botched; box ignored.\n"); CIFSkipToSemi(); return FALSE; } GeoTransRect(CIFDirectionToTrans(&direction), &rectangle , &r2); } else r2 = rectangle; /* Offset by center only now that rotation is complete, and divide by two. */ r2.r_xbot = (r2.r_xbot + center.p_x) / 2; r2.r_ybot = (r2.r_ybot + center.p_y) / 2; r2.r_xtop = (r2.r_xtop + center.p_x) / 2; r2.r_ytop = (r2.r_ytop + center.p_y) / 2; DBPaintPlane(cifReadPlane, &r2, CIFPaintTable, (PaintUndoInfo *) NULL); return TRUE; } /* * ---------------------------------------------------------------------------- * * CIFParseFlash -- * * This routine parses and processes a roundflash command. The syntax is: * roundflash ::= R diameter center * * We approximate a roundflash by a box. * * Results: * TRUE is returned if the parse completed successfully, and * FALSE is returned otherwise. * * Side effects: * Paint is added to the current CIF plane. * * Corrections: Incorrectly implemented. Now CIFParsePoint returns the * center coordinate doubled; in this way, the center can be on the * half-lambda grid but the resulting block on-grid, if the diameter * is an odd number. * * ---------------------------------------------------------------------------- */ bool CIFParseFlash() { int diameter; int savescale; Point center; Rect rectangle; /* Take the 'R'. */ TAKE(); if (cifReadPlane == NULL) { CIFSkipToSemi(); return FALSE; } if (!CIFParseInteger(&diameter)) { CIFReadError("roundflash, but no diameter; ignored.\n"); CIFSkipToSemi(); return FALSE; } diameter *= cifReadScale1; if (diameter % cifReadScale2 != 0) CIFReadWarning("Roundflash diameter snapped to nearest integer boundary.\n"); diameter /= cifReadScale2; savescale = cifReadScale1; if (!CIFParsePoint(¢er, 2)) { CIFReadError("roundflash, but no center; ignored.\n"); CIFSkipToSemi(); return FALSE; } if (savescale != cifReadScale1) diameter *= (cifReadScale1 / savescale); rectangle.r_xbot = (center.p_x - diameter) / 2; rectangle.r_ybot = (center.p_y - diameter) / 2; rectangle.r_xtop = (center.p_x + diameter) / 2; rectangle.r_ytop = (center.p_y + diameter) / 2; DBPaintPlane(cifReadPlane, &rectangle, CIFPaintTable, (PaintUndoInfo *) NULL); return TRUE; } /* * ---------------------------------------------------------------------------- * * CIFPaintWirePath -- * * Draw a "wire path" described by the endpoints of a centerline through * a series of segments, and a wire width. We pass the plane and paint * table information so this routine can be used by the database for * painting paths from the command-line. * * Results: * None. * * Side effects: * Paints layout into magic. The original wire path is destroyed * (memory free'd). * * Notes: * Path coordinates for wires are always assumed to be twice the * actual value to avoid roundoff errors, since the centerline of * a path can be halfway between two coordinates of the layout grid * and still describe a polygon whose endpoints are all on the grid. * * Warning: * It is still possible to get roundoff problems with different * values of segment width at different angles caused by snapping * to grid points. While this is "as it should be", it causes * problems when process design rules demand geometry at 45 degrees * only, and the algorithm produces points that are 1 unit off. * A possible solution is to adjust "cwidth" to match the average * value of "width" after snapping at entering and exiting angles. * * ---------------------------------------------------------------------------- */ void CIFPaintWirePath(pathheadp, width, endcap, plane, ptable, ui) CIFPath *pathheadp; int width; bool endcap; Plane *plane; PaintResultType *ptable; PaintUndoInfo *ui; { CIFPath *pathp, *previousp, *nextp, *polypath; CIFPath *returnpath, *newpath, *savepath; LinkedRect *rectp; double theta, phi, alpha, delta, cwidth, adjwidth, testmitre, savetheta; double xmaxoff, ymaxoff, xminoff, yminoff; double xmin, ymin, xmax, ymax, xnext, ynext; bool firstpoint; /* Get rid of any repeat points, which just screw up the algorithm */ previousp = pathheadp; pathp = pathheadp->cifp_next; if (pathp != NULL) { while (pathp->cifp_next != NULL) { if (pathp->cifp_next->cifp_x == pathp->cifp_x && pathp->cifp_next->cifp_y == pathp->cifp_y) { previousp->cifp_next = pathp->cifp_next; freeMagic(pathp); } else previousp = pathp; pathp = pathp->cifp_next; } } previousp = pathheadp; polypath = NULL; /* Single-point paths are okay; just set the endpoints equal */ if (pathheadp->cifp_next == NULL) pathp = pathheadp; else pathp = pathheadp->cifp_next; firstpoint = TRUE; theta = 0; while (pathp != NULL) { /* Advance to the next point */ xmin = (double)previousp->cifp_x; xmax = (double)pathp->cifp_x; ymin = (double)previousp->cifp_y; ymax = (double)pathp->cifp_y; /* Angle of this segment */ savetheta = theta; theta = atan2(ymax - ymin, xmax - xmin); /* Look ahead to the next point */ if (firstpoint) { /* Back first point up by endcap amount (width, */ /* which is half the width of the route segment.) */ if (endcap) { xmin -= (double)width * cos(theta); ymin -= (double)width * sin(theta); } xminoff = (double)width * cos(theta - 1.5708); /* 90 degrees */ yminoff = (double)width * sin(theta - 1.5708); firstpoint = FALSE; newpath = (CIFPath *)mallocMagic(sizeof(CIFPath)); newpath->cifp_next = polypath; polypath = newpath; returnpath = polypath; /* returnpath is always at the end */ newpath->cifp_x = round((xmin + xminoff) / 2); newpath->cifp_y = round((ymin + yminoff) / 2); newpath = (CIFPath *)mallocMagic(sizeof(CIFPath)); newpath->cifp_next = polypath; polypath = newpath; newpath->cifp_x = round((xmin - xminoff) / 2); newpath->cifp_y = round((ymin - yminoff) / 2); } nextp = pathp->cifp_next; if (nextp != NULL) { xnext = (double)nextp->cifp_x; ynext = (double)nextp->cifp_y; phi = atan2(ynext - ymax, xnext - xmax); } else { /* Endpoint: create 1/2 width endcap */ phi = theta; if (endcap) { xmax += (double)width * cos(theta); ymax += (double)width * sin(theta); } } alpha = 0.5 * (phi - theta); testmitre = fabs(cos(alpha)); /* This routine does not (yet) do mitre limits, so for */ /* now, we do a sanity check. In the case of an */ /* extremely acute angle, we generate a warning and */ /* truncate the route. The mitre limit is arbitrarily */ /* set at 4 times the route width. Such extreme bends */ /* are usually DRC violations, anyway. Tighter bends */ /* than this tend to cause difficulties for the */ /* CIFMakeManhattanPath() routine. */ if (testmitre < 0.25) { if (testmitre < 1.0e-10) { /* Wire reverses direction. Break wire here, */ /* draw, and start new polygon. */ phi = theta; if (endcap) { xmax += (double)width * cos(theta); ymax += (double)width * sin(theta); } alpha = 0.5 * (phi - theta); firstpoint = TRUE; } else { TxError("Error: mitre limit exceeded at wire junction.\n"); TxError("Route has been truncated.\n"); break; } } delta = (0.5 * (phi + theta)) - 1.5708; cwidth = (double)width / cos(alpha); xmaxoff = cwidth * cos(delta); ymaxoff = cwidth * sin(delta); newpath = (CIFPath *)mallocMagic(sizeof(CIFPath)); newpath->cifp_next = polypath; polypath = newpath; newpath->cifp_x = round((xmax - xmaxoff) / 2); newpath->cifp_y = round((ymax - ymaxoff) / 2); newpath = (CIFPath *)mallocMagic(sizeof(CIFPath)); newpath->cifp_next = NULL; savepath = returnpath; returnpath->cifp_next = newpath; returnpath = newpath; newpath->cifp_x = round((xmax + xmaxoff) / 2); newpath->cifp_y = round((ymax + ymaxoff) / 2); if (firstpoint == TRUE || nextp == NULL) { /* Slow draw for non-Manhattan paths: */ /* Break the area up into triangles and rectangles */ rectp = CIFPolyToRects(polypath, plane, ptable, ui); CIFFreePath(polypath); for (; rectp != NULL ; rectp = rectp->r_next) { DBPaintPlane(plane, &rectp->r_r, ptable, ui); freeMagic((char *) rectp); } polypath = NULL; } else { Rect r; double a1, a2, r2, d1; Point newpt; /* Check if either of the two new segments travels opposite */ /* to theta. If so, then we need to find the intersection */ /* with the previous point, to avoid creating a cut-out */ /* wedge in the path. */ a1 = fabs(atan2(returnpath->cifp_y - savepath->cifp_y, returnpath->cifp_x - savepath->cifp_x) - theta); a2 = fabs(atan2(polypath->cifp_y - polypath->cifp_next->cifp_y, polypath->cifp_x - polypath->cifp_next->cifp_x) - theta); if (a1 > 0.1 && a1 < 6.1) { /* Find new intersection point */ d1 = cos(savetheta) * sin(phi) - sin(savetheta) * cos(phi); if (fabs(d1) > 1.0e-4) { r2 = (sin(phi) * (returnpath->cifp_x - savepath->cifp_x) - cos(phi) * (returnpath->cifp_y - savepath->cifp_y)) / d1; savepath->cifp_x += round(r2 * cos(savetheta)); savepath->cifp_y += round(r2 * sin(savetheta)); } } else if (a2 > 0.1 && a2 < 6.1) { /* Find new intersection point */ d1 = cos(savetheta) * sin(phi) - sin(savetheta) * cos(phi); if (fabs(d1) > 1.0e-4) { r2 = (sin(phi) * (polypath->cifp_x - polypath->cifp_next->cifp_x) - cos(phi) * (polypath->cifp_y - polypath->cifp_next->cifp_y)) / d1; polypath->cifp_next->cifp_x += round(r2 * cos(savetheta)); polypath->cifp_next->cifp_y += round(r2 * sin(savetheta)); } } } previousp = pathp; pathp = pathp->cifp_next; } CIFFreePath(pathheadp); } /* * ---------------------------------------------------------------------------- * * PaintPolygon -- * * Convert a list of points in the form of an array of type Point to a * CIFPath linked structure, and paint them into the database. * * Results: * None. * * Side effects: * Paints tiles into the layout database. Calling routine is * responsible for free'ing memory of the pointlist, if necessary. * * Notes: * This is a database routine, not a CIF routine. However, it makes * use of the CIFPath structure, so it is included here. * * ---------------------------------------------------------------------------- */ void PaintPolygon(pointlist, number, plane, ptable, ui) Point *pointlist; /* Array of Point structures */ int number; /* total number of points */ Plane *plane; /* Plane structure to paint into */ PaintResultType *ptable; /* Paint result table */ PaintUndoInfo *ui; /* Undo record */ { LinkedRect *rectp; CIFPath *newpath, *cifpath = (CIFPath *)NULL; int i; for (i = 0; i < number; i++) { newpath = (CIFPath *) mallocMagic((unsigned) sizeof (CIFPath)); newpath->cifp_x = pointlist[i].p_x; newpath->cifp_y = pointlist[i].p_y; newpath->cifp_next = cifpath; cifpath = newpath; } rectp = CIFPolyToRects(cifpath, plane, ptable, ui); CIFFreePath(cifpath); for (; rectp != NULL ; rectp = rectp->r_next) { DBPaintPlane(plane, &rectp->r_r, ptable, ui); freeMagic((char *) rectp); } } /* * ---------------------------------------------------------------------------- * * PaintWireList -- * * Convert a list of points in the form of an array of type Point to a * CIFPath linked structure, and paint them into the database. * * Results: * None. * * Side effects: * Paints tiles into the layout database. Calling routine is * responsible for free'ing memory of the pointlist, if necessary. * * Notes: * This is a database routine, not a CIF routine. However, it makes * use of the CIFPath structure, so it is included here. * * ---------------------------------------------------------------------------- */ void PaintWireList(pointlist, number, width, endcap, plane, ptable, ui) Point *pointlist; /* Array of Point structures */ int number; /* total number of points */ int width; /* Route width of path */ bool endcap; /* Whether or not to add 1/2 width endcaps */ Plane *plane; /* Plane structure to paint into */ PaintResultType *ptable; /* Paint result table */ PaintUndoInfo *ui; /* Undo record */ { CIFPath *newpath, *cifpath = (CIFPath *)NULL; int i; for (i = 0; i < number; i++) { newpath = (CIFPath *) mallocMagic((unsigned) sizeof (CIFPath)); newpath->cifp_x = pointlist[i].p_x; newpath->cifp_y = pointlist[i].p_y; newpath->cifp_next = cifpath; cifpath = newpath; } CIFPaintWirePath(cifpath, width, endcap, plane, ptable, ui); } /* * ---------------------------------------------------------------------------- * * CIFParseWire -- * * This procedure parses CIF wire commands, and adds paint * to the current CIF cell. A wire command consists of * an integer width, then a path. * * Results: * TRUE is returned if the parse completed successfully, and * FALSE is returned otherwise. * * Side effects: * The current CIF planes are modified. * * ---------------------------------------------------------------------------- */ bool CIFParseWire() { int width; CIFPath *pathheadp, *polypath; int savescale; /* Take the 'W'. */ TAKE(); if (cifReadPlane == NULL) { CIFSkipToSemi(); return FALSE; } if (!CIFParseInteger(&width)) { CIFReadError("wire, but no width; ignored.\n"); CIFSkipToSemi(); return FALSE; } width *= cifReadScale1; if (width % cifReadScale2 != 0) CIFReadWarning("Wire width snapped to nearest integer boundary.\n"); width /= cifReadScale2; savescale = cifReadScale1; if (!CIFParsePath(&pathheadp, 2)) { CIFReadError("wire, but improper path; ignored.\n"); CIFSkipToSemi(); return FALSE; } if (savescale != cifReadScale1) width *= (cifReadScale1 / savescale); CIFPaintWirePath(pathheadp, width, TRUE, cifReadPlane, CIFPaintTable, (PaintUndoInfo *)NULL); return TRUE; } /* * ---------------------------------------------------------------------------- * * CIFParseLayer -- * * This procedure parses layer changes. The syntax is: * layer ::= L { blank } processchar layerchars * * Results: * TRUE is returned if the parse completed successfully, and * FALSE is returned otherwise. * * Side effects: * Switches the CIF plane where paint is being saved. * * ---------------------------------------------------------------------------- */ bool CIFParseLayer() { #define MAXCHARS 4 char name[MAXCHARS+1]; char c; int i; TileType type; /* Take the 'L'. */ TAKE(); CIFSkipBlanks(); /* Get the layer name. */ for (i=0; i<=MAXCHARS; i++) { c = PEEK(); if (isdigit(c) || isupper(c)) name[i] = TAKE(); else break; } name[i] = '\0'; /* Set current plane for use by the routines that parse geometric * elements. */ type = CIFReadNameToType(name, FALSE); if (type < 0) { cifReadPlane = NULL; cifCurLabelType = TT_SPACE; CIFReadError("layer %s isn't known in the current style.\n", name); } else { cifCurLabelType = cifCurReadStyle->crs_labelLayer[type]; cifReadPlane = cifCurReadPlanes[type]; } CIFSkipToSemi(); return TRUE; } /* * ---------------------------------------------------------------------------- * * CIFParsePoly -- * * This procedure reads and processes a polygon command. The syntax is: * polygon ::= path * * Results: * TRUE is returned if the parse completed successfully, and * FALSE is returned otherwise. * * Side effects: * Paint is added to the current CIF plane. * * ---------------------------------------------------------------------------- */ bool CIFParsePoly() { CIFPath *pathheadp; LinkedRect *rectp; /* Take the 'P'. */ TAKE(); if (cifReadPlane == NULL) { CIFSkipToSemi(); return FALSE; } if (!CIFParsePath(&pathheadp, 1)) { CIFReadError("polygon, but improper path; ignored.\n"); CIFSkipToSemi(); return FALSE; } /* Convert the polygon to rectangles. */ rectp = CIFPolyToRects(pathheadp, cifReadPlane, CIFPaintTable, (PaintUndoInfo *)NULL); CIFFreePath(pathheadp); if (rectp == NULL) { /* The non-Manhattan geometry polygon parsing algorithm */ /* typically leaves behind degenerate paths, so they */ /* should not be considered erroneous. */ CIFSkipToSemi(); return FALSE; } for (; rectp != NULL ; rectp = rectp->r_next) { DBPaintPlane(cifReadPlane, &rectp->r_r, CIFPaintTable, (PaintUndoInfo *) NULL); freeMagic((char *) rectp); } return TRUE; } magic-8.0.210/cif/CIFrdcl.c0000664000175000001440000007756212364011344013646 0ustar timusers/* CIFreadcell.c - * * This file contains more routines to parse CIF files. In * particular, it contains the routines to handle cells, * both definitions and calls, and user-defined features * like labels. * * ********************************************************************* * * 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/cif/CIFrdcl.c,v 1.5 2010/08/25 17:33:55 tim Exp $"; #endif /* not lint */ #include #include #include #include "utils/magic.h" #include "utils/malloc.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "utils/undo.h" #include "database/database.h" #include "cif/CIFint.h" #include "cif/CIFread.h" #include "cif/cif.h" #include "calma/calma.h" #include "utils/utils.h" #include "windows/windows.h" #include "dbwind/dbwind.h" #include "utils/main.h" #include "drc/drc.h" /* The following variable is made available to the outside world, * and is the cell definition currently being modified. */ CellDef *cifReadCellDef; /* * The following hash table is used internally to keep track of * of all the cells we've seen definitions for or calls on. * The hash table entries contain pointers to cellDefs, and * are indexed by CIF cell number. If the CDAVAILABLE bit is * set it means we've read the cell's contents. If not set, it * means that the cell has been called but not yet defined. */ HashTable CifCellTable; /* The following variable is used to save and restore current * paint layer information so that we can resume the correct * layer after a subcell definition. */ Plane *cifOldReadPlane = NULL; /* The following boolean is TRUE if a subcell definition is being * read. FALSE means we're working on the EditCell. */ bool cifSubcellBeingRead; /* The following two collections of planes are used to hold CIF * information while cells are being read in (one set for the * outermost, unnamed cell, and one for the current subcell). * When a cell is complete, then geometrical operations are * performed on the layers and stuff is painted into Magic. */ Plane *cifEditCellPlanes[MAXCIFRLAYERS]; Plane *cifSubcellPlanes[MAXCIFRLAYERS]; Plane **cifCurReadPlanes = cifEditCellPlanes; /* Set of planes currently * in force. */ TileType cifCurLabelType = TT_SPACE; /* Magic layer on which to put '94' * labels that aren't identified by * type. */ /* The following variable is used to hold a subcell id between * the 91 statement and the (immediately-following?) call statement. * The string this points to is dynamically allocated, so it must * also be freed explicitly. */ char *cifSubcellId = NULL; /* * ---------------------------------------------------------------------------- * * CIFReadCellInit -- * * This procedure initializes the data structures in this * module just prior to reading a CIF file. * * If ptrkeys is 0, the keys used in this hash table will * be strings; if it is 1, the keys will be CIF numbers. * * Results: * None. * * Side effects: * The cell hash table is initialized, and things are set up * to put information in the EditCell first. * * ---------------------------------------------------------------------------- */ void CIFReadCellInit(ptrkeys) int ptrkeys; { int i; HashInit(&CifCellTable, 32, ptrkeys); cifReadCellDef = EditCellUse->cu_def; cifSubcellBeingRead = FALSE; cifCurReadPlanes = cifEditCellPlanes; for (i = 0; i < MAXCIFRLAYERS; i += 1) { if (cifEditCellPlanes[i] == NULL) cifEditCellPlanes[i] = DBNewPlane((ClientData) TT_SPACE); if (cifSubcellPlanes[i] == NULL) cifSubcellPlanes[i] = DBNewPlane((ClientData) TT_SPACE); } } /* * ---------------------------------------------------------------------------- * * cifForgetCell -- * * This local procedure is used to find a cell in the subcell * table and remove its CellDef entry. * * Results: * FALSE if no such entry was found, otherwise TRUE. * * Side effects: * Mucks with the CIF cell name hash table. * * ---------------------------------------------------------------------------- */ bool cifForgetCell(cifNum) int cifNum; { HashEntry *h; h = HashLookOnly(&CifCellTable, (char *)(spointertype)cifNum); if (h == NULL) return FALSE; else if (HashGetValue(h) == 0) return FALSE; HashSetValue(h, 0); return TRUE; } /* * ---------------------------------------------------------------------------- * * cifUniqueCell -- * * Attempt to find a cell in the CIF subcell name hash table. * If one exists, rename its definition so that it will not * be overwritten when the cell is redefined. * * Results: * None. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ void cifUniqueCell(cifNum) int cifNum; { HashEntry *h; CellDef *def, *testdef; char name[17]; int reused = 0; h = HashLookOnly(&CifCellTable, (char *)(spointertype)cifNum); if ((h == NULL) || HashGetValue(h) == 0) { /* Cell was deleted with "DD". Don't rename anything */ return; } sprintf(name, "%d", cifNum); def = DBCellLookDef(name); if (def == (CellDef *)NULL) return; /* Cell may have been called but not yet defined---this is okay. */ else if ((def->cd_flags & CDAVAILABLE) == 0) return; testdef = def; while (testdef != NULL) { sprintf(name, "%d_%d", cifNum, ++reused); testdef = DBCellLookDef(name); } DBCellRenameDef(def, name); h = HashFind(&CifCellTable, (char *)(spointertype)cifNum); HashSetValue(h, 0); CIFReadError("Warning: cell definition %d reused.\n", cifNum); } /* * ---------------------------------------------------------------------------- * * cifFindCell -- * * This local procedure is used to find a cell in the subcell * table, and create a new subcell if there isn't already * one there. If a new subcell is created, its CDAVAILABLE * is left FALSE. * * Results: * The return value is a pointer to the definition for the * cell whose CIF number is cifNum. * * Side effects: * A new CellDef may be created. * * ---------------------------------------------------------------------------- */ CellDef * cifFindCell(cifNum) int cifNum; /* The CIF number of the desired cell. */ { HashEntry *h; CellDef *def, *testdef; int reused; h = HashFind(&CifCellTable, (char *)(spointertype)cifNum); if (HashGetValue(h) == 0) { char name[15]; sprintf(name, "%d", cifNum); def = DBCellLookDef(name); if (def == NULL) { def = DBCellNewDef(name, (char *) NULL); /* Tricky point: call DBReComputeBbox here to make SURE * that the cell has a valid bounding box. Otherwise, * if the cell is used in a parent before being defined * then it will cause a core dump. */ DBReComputeBbox(def); } HashSetValue(h, def); } return (CellDef *) HashGetValue(h); } /* * ---------------------------------------------------------------------------- * * CIFScalePlanes -- * * Scale all of the CIF planes by the amount (scalen / scaled) * * ---------------------------------------------------------------------------- */ void CIFScalePlanes(scalen, scaled, planearray) int scalen; int scaled; Plane **planearray; { int pNum; Plane *newplane; for (pNum = 0; pNum < MAXCIFRLAYERS; pNum++) { if (planearray[pNum] != NULL) { newplane = DBNewPlane((ClientData) TT_SPACE); DBClearPaintPlane(newplane); dbScalePlane(planearray[pNum], newplane, pNum, scalen, scaled, TRUE); DBFreePaintPlane(planearray[pNum]); TiFreePlane(planearray[pNum]); planearray[pNum] = newplane; } } } /* * ---------------------------------------------------------------------------- * * CIFInputRescale -- * * Scale all CIF distances by n / d. Normally, rescaling is done in * the upward direction (n > 1, d = 1) in response to a value in the * CIF input that does not divide evenly into the database units of * the CIF planes. Currently there is no call to CIFInputRescale * with d > 1, but it is left for the possibility that scalefactors * could be restored after finishing a subcell definition, possibly * preventing integer overflow in large designs. * * Results: * None. * * Side effects: * Many. Adjusts the CIF input style scalefactor (CIF vs. magic * units), multiplier (CIF units vs. centimicrons), distances of all * CIF boolean operations, and the scale of all existing planes in * the current CIF database. * * ---------------------------------------------------------------------------- */ void CIFInputRescale(n, d) int n, d; { CIFReadStyle *istyle = cifCurReadStyle; CIFReadLayer *cl; CIFOp *op; int i; /* 2-step process for efficiency */ if (n > 1) { istyle->crs_scaleFactor *= n; istyle->crs_multiplier *= n; for (i = 0; i < istyle->crs_nLayers; i++) { cl = istyle->crs_layers[i]; for (op = cl->crl_ops; op != NULL; op = op->co_next) if (op->co_distance) op->co_distance *= n; } } if (d > 1) { istyle->crs_scaleFactor /= d; istyle->crs_multiplier /= d; for (i = 0; i < istyle->crs_nLayers; i++) { cl = istyle->crs_layers[i]; for (op = cl->crl_ops; op != NULL; op = op->co_next) if (op->co_distance) op->co_distance /= d; } } CIFScalePlanes(n, d, cifEditCellPlanes); if (cifEditCellPlanes != cifSubcellPlanes) CIFScalePlanes(n, d, cifSubcellPlanes); CIFReadWarning("CIF style %s: units rescaled by factor of %d / %d\n", istyle->crs_name, n, d); } /* * ---------------------------------------------------------------------------- * * CIFParseStart -- * * Parse the beginning of a symbol (cell) definition. * ds ::= D { blank } S integer [ sep integer sep integer ] * * Results: * TRUE is returned if the parse completed successfully, and * FALSE is returned otherwise. * * Side effects: * Set up information for the new cell, including the CIF * planes and creating a Magic cell (if one doesn't exist * already). * * ---------------------------------------------------------------------------- */ bool CIFParseStart() { int number; if (cifSubcellBeingRead) { CIFReadError("definition start inside other definition; ignored.\n"); CIFSkipToSemi(); return FALSE; } if (cifSubcellId != NULL) { CIFReadError("pending call identifier %s discarded.\n", cifSubcellId); (void) StrDup(&cifSubcellId, (char *) NULL); } /* Take the `S'. */ TAKE(); if (!CIFParseInteger(&number)) { CIFReadError("definition start, but no symbol number; ignored.\n"); CIFSkipToSemi(); return FALSE; } else if (number < 0) { CIFReadError("illegal negative symbol number; definition ignored.\n"); CIFSkipToSemi(); return FALSE; } if (!CIFParseInteger(&cifReadScale1)) { cifReadScale1 = 1; cifReadScale2 = 1; } else { cifReadScale1 *= cifCurReadStyle->crs_multiplier; /* Units not centimicrons */ if (!CIFParseInteger(&cifReadScale2)) { CIFReadError( "only one of two scale factors given; ignored.\n"); cifReadScale1 = 1; cifReadScale2 = 1; } } if (cifReadScale1 <= 0 || cifReadScale2 <= 0) { CIFReadError("Illegal scale %d / %d changed to 1 / 1\n", cifReadScale1, cifReadScale2); cifReadScale1 = 1; cifReadScale2 = 1; } /* * Set up the cell definition. */ cifUniqueCell(number); cifReadCellDef = cifFindCell(number); DBCellClearDef(cifReadCellDef); DBCellSetAvail(cifReadCellDef); cifOldReadPlane = cifReadPlane; cifReadPlane = (Plane *) NULL; cifSubcellBeingRead = TRUE; cifCurReadPlanes = cifSubcellPlanes; return TRUE; } /* * ---------------------------------------------------------------------------- * * CIFPaintCurrent -- * * This procedure does geometrical processing on the current * set of CIF planes, and paints the results into the current * CIF cell. * * Results: * None. * * Side effects: * Lots of information gets added to the current Magic cell. * * ---------------------------------------------------------------------------- */ void CIFPaintCurrent() { Plane *plane, *swapplane; int i; for (i = 0; i < cifCurReadStyle->crs_nLayers; i += 1) { TileType type; extern int cifPaintCurrentFunc(); /* Forward declaration. */ plane = CIFGenLayer(cifCurReadStyle->crs_layers[i]->crl_ops, &TiPlaneRect, (CellDef *) NULL, cifCurReadPlanes); /* Generate a paint/erase table, then paint from the CIF * plane into the current Magic cell. */ type = cifCurReadStyle->crs_layers[i]->crl_magicType; if (cifCurReadStyle->crs_layers[i]->crl_flags & CIFR_TEMPLAYER) { /* Swap planes */ swapplane = cifCurReadPlanes[type]; cifCurReadPlanes[type] = plane; plane = swapplane; } else { DBSrPaintArea((Tile *) NULL, plane, &TiPlaneRect, &CIFSolidBits, cifPaintCurrentFunc, (ClientData)type); } /* Recycle the plane, which was dynamically allocated. */ DBFreePaintPlane(plane); TiFreePlane(plane); } /* Now go through all the current planes and zero them out. */ for (i = 0; i < MAXCIFRLAYERS; i++) DBClearPaintPlane(cifCurReadPlanes[i]); } /* Below is the search function invoked for each CIF tile type * found for the current layer. */ int cifPaintCurrentFunc(tile, type) Tile *tile; /* Tile of CIF information. */ TileType type; /* Magic type to be painted. */ { Rect area; int pNum; int savescale; bool snap_type = COORD_EXACT; /* Contact types are allowed to be on half-lambda spacing, and are */ /* snapped to the nearest magic coordinate if the result is a */ /* fractional magic coordinate. */ if (DBIsContact(type)) snap_type = COORD_HALF_U; /* Compute the area of the CIF tile, then scale it into * Magic coordinates. */ TiToRect(tile, &area); area.r_xtop = CIFScaleCoord(area.r_xtop, snap_type); savescale = cifCurReadStyle->crs_scaleFactor; area.r_ytop = CIFScaleCoord(area.r_ytop, snap_type); if (snap_type == COORD_HALF_U) snap_type = COORD_HALF_L; if (savescale != cifCurReadStyle->crs_scaleFactor) { area.r_xtop *= (savescale / cifCurReadStyle->crs_scaleFactor); savescale = cifCurReadStyle->crs_scaleFactor; } area.r_xbot = CIFScaleCoord(area.r_xbot, snap_type); if (savescale != cifCurReadStyle->crs_scaleFactor) { area.r_xtop *= (savescale / cifCurReadStyle->crs_scaleFactor); area.r_ytop *= (savescale / cifCurReadStyle->crs_scaleFactor); savescale = cifCurReadStyle->crs_scaleFactor; } area.r_ybot = CIFScaleCoord(area.r_ybot, snap_type); if (savescale != cifCurReadStyle->crs_scaleFactor) { area.r_xtop *= (savescale / cifCurReadStyle->crs_scaleFactor); area.r_ytop *= (savescale / cifCurReadStyle->crs_scaleFactor); area.r_xbot *= (savescale / cifCurReadStyle->crs_scaleFactor); } /* Check for degenerate areas (from rescale limiting) before painting */ if ((area.r_xbot == area.r_xtop) || (area.r_ybot == area.r_ytop)) return 0; for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++) if (DBPaintOnPlane(type, pNum)) { DBNMPaintPlane(cifReadCellDef->cd_planes[pNum], TiGetTypeExact(tile), &area, DBStdPaintTbl(type, pNum), (PaintUndoInfo *) NULL); } return 0; /* To keep the search alive. */ } /* * ---------------------------------------------------------------------------- * * CIFParseFinish -- * * This procedure is called at the end of a cell definition. * * Results: * TRUE is returned if the parse completed successfully, and * FALSE is returned otherwise. * * Side effects: * Process the CIF planes and paint the results into the Magic * cell. * * ---------------------------------------------------------------------------- */ bool CIFParseFinish() { if (!cifSubcellBeingRead) { CIFReadError("definition finish without definition start; ignored.\n"); CIFSkipToSemi(); return FALSE; } if (cifSubcellId != NULL) { CIFReadError("pending call identifier %s discarded.\n", cifSubcellId); (void) StrDup(&cifSubcellId, (char *) NULL); } /* Take the `F'. */ TAKE(); /* Do the geometrical processing and paint this material back into * the appropriate cell of the database. Then restore the saved * layer info. */ CIFPaintCurrent(); DBAdjustLabels(cifReadCellDef, &TiPlaneRect); DBReComputeBbox(cifReadCellDef); cifReadCellDef = EditCellUse->cu_def; cifReadPlane = cifOldReadPlane; cifReadScale1 = 1; cifReadScale2 = 1; cifSubcellBeingRead = FALSE; cifCurReadPlanes = cifEditCellPlanes; return TRUE; } /* * ---------------------------------------------------------------------------- * * CIFParseDelete -- * * This procedure is called to handle delete-symbol statements. * * Results: * TRUE is returned if the parse completed successfully, and * FALSE is returned otherwise. * * Side effects: * The mapping between numbers and cells is modified to eliminate * some symbols. * * ---------------------------------------------------------------------------- */ bool CIFParseDelete() { int number; /* Take the `D'. */ TAKE(); if (!CIFParseInteger(&number)) { CIFReadError("definition delete, but no symbol number; ignored.\n"); CIFSkipToSemi(); return FALSE; } /* Unlink the hash entry from its target definition */ cifForgetCell(number); CIFSkipToSemi(); return TRUE; } /* * ---------------------------------------------------------------------------- * * cifParseName -- * * Parse a name, which is a string of alphabetics, numerics, * or underscores, possibly preceded by whitespace. * * Results: * The return value is a pointer to the name read from the * CIF file. This is a statically-allocated area, so the * caller should copy out of this area before invoking this * procedure again. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ char * cifParseName() { char ch; char *bufferp; static char buffer[128]; /* Skip white space. */ for (ch = PEEK() ; ch == ' ' || ch == '\t' ; ch = PEEK()) TAKE(); /* Read the string. */ bufferp = &buffer[0]; for (ch = PEEK() ; (! isspace(ch)) && ch != ';' ; ch = PEEK()) { *bufferp++ = TAKE(); } *bufferp = '\0'; return buffer; } /* * ---------------------------------------------------------------------------- * * cifParseUser9 -- * * This procedure processes user extension 9: the name of the * current symbol (cell) definition. * * Results: * TRUE is returned if the parse completed successfully, and * FALSE is returned otherwise. * * Side effects: * The current CIF symbol is renamed from its default "cifxx" name * to the given name. * * ---------------------------------------------------------------------------- */ bool cifParseUser9() { char *name; name = cifParseName(); if (!DBCellRenameDef(cifReadCellDef, name)) { CIFReadError("%s already exists, so cell from CIF is named %s.\n", name, cifReadCellDef->cd_name); } return TRUE; } /* * ---------------------------------------------------------------------------- * * CIFParseCall -- * * This procedure processes subcell uses. The syntax of a call is * call ::= C integer transform * * Results: * TRUE is returned if the parse completed successfully, and * FALSE is returned otherwise. * * Side effects: * A subcell is added to the current Magic cell we're generating. * * ---------------------------------------------------------------------------- */ bool CIFParseCall() { int called; Transform transform; CellUse *use; CellDef *def; /* Take the `C'. */ TAKE(); if (!CIFParseInteger(&called)) { CIFReadError("call, but no symbol number; ignored.\n"); CIFSkipToSemi(); return FALSE; } /* Get optional transformation. */ (void) CIFParseTransform(&transform); def = cifFindCell(called); /* avoid recursion */ if (DBIsAncestor(def, cifReadCellDef)) { CIFReadError("attempt to place cell use inside its own definition!\n"); CIFSkipToSemi(); return FALSE; } /* Find the use and add it to the current cell. Give it an * id also. */ use = DBCellNewUse(def, cifSubcellId); (void) DBLinkCell(use, cifReadCellDef); DBSetTrans(use, &transform); DBPlaceCell(use, cifReadCellDef); (void) StrDup(&cifSubcellId, (char *) NULL); return TRUE; } /* * ---------------------------------------------------------------------------- * * cifParseUser91 -- * * This procedure handles 91 user commands, which provide id's * for following cell calls. The syntax is: * 91 ::= 91 blanks name * * Results: * TRUE is returned if the parse completed successfully, and * FALSE is returned otherwise. * * Side effects: * The identifier is saved until the call is read. Then it is * used as the identifier for the cell. * * ---------------------------------------------------------------------------- */ bool cifParseUser91() { if (cifSubcellId != NULL) { CIFReadError("91 command with identifier %s pending; %s discarded.\n" , cifSubcellId , cifSubcellId); } (void) StrDup(&cifSubcellId, cifParseName()); return TRUE; } /* * ---------------------------------------------------------------------------- * * cifParseUser94 -- * * This procedure parses 94 user commands, which are labelled * points. The syntax is: * 94 ::= 94 blanks name point * * Results: * TRUE is returned if the parse completed successfully, and * FALSE is returned otherwise. * * Side effects: * A label is added to the current cell. * * ---------------------------------------------------------------------------- */ bool cifParseUser94() { Rect rectangle; char *name = NULL; TileType type; int layer, flags, i; int savescale; (void) StrDup(&name, cifParseName()); if (! CIFParsePoint(&rectangle.r_ll, 1)) { CIFReadError("94 command, but no location; ignored.\n"); CIFSkipToSemi(); return FALSE; } /* Scale the coordinates, then make the location into a * rectangle. */ rectangle.r_xbot = CIFScaleCoord(rectangle.r_xbot, COORD_ANY); savescale = cifCurReadStyle->crs_scaleFactor; rectangle.r_ybot = CIFScaleCoord(rectangle.r_ybot, COORD_ANY); if (savescale != cifCurReadStyle->crs_scaleFactor) rectangle.r_xbot *= (savescale / cifCurReadStyle->crs_scaleFactor); rectangle.r_ur = rectangle.r_ll; /* Get a layer, lookup the layer, then add the label to the * current cell. Tricky business: in order for the default * label location to be computed */ CIFSkipBlanks(); if (PEEK() != ';') { char *lname = cifParseName(); layer = CIFReadNameToType(lname, FALSE); if (layer < 0) { CIFReadError("label attached to unknown layer %s.\n", lname); type = TT_SPACE; } else { type = cifCurReadStyle->crs_labelLayer[layer]; } } else { type = cifCurLabelType; /* Should do this better, by defining cifCurLabelFlags. . . */ layer = -1; for (i = 0; i < cifCurReadStyle->crs_nLayers; i++) if (cifCurReadStyle->crs_labelLayer[i] == type) { layer = i; break; } } if (type >=0 ) { if (layer >= 0 && (cifCurReadStyle->crs_layers[layer]->crl_flags & CIFR_TEXTLABELS)) flags = LABEL_STICKY; else flags = 0; (void) DBPutLabel(cifReadCellDef, &rectangle, -1, name, type, flags); } freeMagic(name); return TRUE; } /* * ---------------------------------------------------------------------------- * * cifParseUser95 -- * * This procedure parses 95 user commands, which are labelled * points. The syntax is: * 95 ::= 95 blanks name length width point * * Results: * TRUE is returned if the parse completed successfully, and * FALSE is returned otherwise. * * Side effects: * An area label is added to the current cell. * * ---------------------------------------------------------------------------- */ bool cifParseUser95() { Rect rectangle; Point size, center; char *name = NULL; TileType type; int layer, i; int savescale; (void) StrDup(&name, cifParseName()); if (! CIFParsePoint(&size, 1)) { CIFReadError("95 command, but no size; ignored.\n"); CIFSkipToSemi(); return FALSE; } if (! CIFParsePoint(¢er, 1)) { CIFReadError("95 command, but no location; ignored.\n"); CIFSkipToSemi(); return FALSE; } /* Scale the coordinates and create the rectangular area. */ /* Remap center and size to lowerleft and upperright, respectively, */ /* so that half-lambda centers are resolved before remapping to */ /* magic coordinates. */ center.p_x = CIFScaleCoord(center.p_x - size.p_x/2, COORD_ANY); savescale = cifCurReadStyle->crs_scaleFactor; center.p_y = CIFScaleCoord(center.p_y - size.p_y/2, COORD_ANY); if (savescale != cifCurReadStyle->crs_scaleFactor) { center.p_x *= (savescale / cifCurReadStyle->crs_scaleFactor); savescale = cifCurReadStyle->crs_scaleFactor; } size.p_x = CIFScaleCoord(center.p_x + (size.p_x - size.p_x/2), COORD_ANY); if (savescale != cifCurReadStyle->crs_scaleFactor) { center.p_x *= (savescale / cifCurReadStyle->crs_scaleFactor); center.p_y *= (savescale / cifCurReadStyle->crs_scaleFactor); savescale = cifCurReadStyle->crs_scaleFactor; } size.p_y = CIFScaleCoord(center.p_y + (size.p_y - size.p_y/2), COORD_ANY); if (savescale != cifCurReadStyle->crs_scaleFactor) { center.p_x *= (savescale / cifCurReadStyle->crs_scaleFactor); center.p_y *= (savescale / cifCurReadStyle->crs_scaleFactor); size.p_x *= (savescale / cifCurReadStyle->crs_scaleFactor); } rectangle.r_xbot = center.p_x; rectangle.r_ybot = center.p_y; rectangle.r_xtop = size.p_x; rectangle.r_ytop = size.p_y; /* Get a layer, lookup the layer, then add the label to the * current cell. Tricky business: in order for the default * label location to be computed */ CIFSkipBlanks(); if (PEEK() != ';') { char *name = cifParseName(); layer = CIFReadNameToType(name, FALSE); if (layer < 0) { CIFReadError("label attached to unknown layer %s.\n", name); type = TT_SPACE; } else type = cifCurReadStyle->crs_labelLayer[layer]; } else { type = TT_SPACE; layer = -1; for (i = 0; i < cifCurReadStyle->crs_nLayers; i++) if (cifCurReadStyle->crs_labelLayer[i] == type) { layer = i; break; } } if (type >=0 ) { int flags; if (layer >= 0 && (cifCurReadStyle->crs_layers[layer]->crl_flags & CIFR_TEXTLABELS)) flags = LABEL_STICKY; else flags = 0; (void) DBPutLabel(cifReadCellDef, &rectangle, -1, name, type, flags); } freeMagic(name); return TRUE; } /* * ---------------------------------------------------------------------------- * * CIFParseUser -- * * This procedure is called to process user-defined statements. * The syntax is user ::= digit usertext. * * Results: * TRUE is returned if the parse completed successfully, and * FALSE is returned otherwise. * * Side effects: * Depends on the user command. * * ---------------------------------------------------------------------------- */ bool CIFParseUser() { char ch; ch = TAKE(); switch (ch) { case '9': ch = PEEK(); switch (ch) { case '1': (void) TAKE(); return cifParseUser91(); case '4': (void) TAKE(); return cifParseUser94(); case '5': (void) TAKE(); return cifParseUser95(); default: if (isspace(ch)) return cifParseUser9(); } default: CIFReadError("unimplemented user extension; ignored.\n"); CIFSkipToSemi(); return FALSE; } } /* * ---------------------------------------------------------------------------- * * CIFReadCellCleanup -- * * This procedure is called after processing the CIF file. * It performs various cleanup functions on the cells that * have been read in. * * Results: * None. * * Side effects: * The area of each cell is DRC'ed and redisplayed. Error * messages are output for any cells whose contents weren't * in the CIF file. An error message is also output if * we're still in the middle of reading a subcell. * * ---------------------------------------------------------------------------- */ void CIFReadCellCleanup(type) int type; // 0 = CIF, 1 = GDS, because routine is used by both { HashEntry *h; HashSearch hs; CellDef *def; MagWindow *window; if (cifSubcellBeingRead) { if (type == 0) CIFReadError("CIF ended partway through a symbol definition.\n"); else calmaReadError("GDS ended partway through a symbol definition.\n"); (void) CIFParseFinish(); } HashStartSearch(&hs); while (TRUE) { h = HashNext(&CifCellTable, &hs); if (h == NULL) break; def = (CellDef *) HashGetValue(h); if (def == NULL) { if (type == 0) CIFReadError("cell table has NULL entry (Magic error).\n"); else calmaReadError("cell table has NULL entry (Magic error).\n"); continue; } if (!(def->cd_flags & CDAVAILABLE)) { if (type == 0) CIFReadError("cell %s was used but not defined.\n", def->cd_name); else calmaReadError("cell %s was used but not defined.\n", def->cd_name); } if (def->cd_flags & CDPROCESSEDGDS) { def->cd_flags &= ~CDPROCESSEDGDS; } if (def->cd_flags & CDFLATGDS) { /* These cells have been flattened and are no longer needed. */ char *savename = StrDup((char **)NULL, def->cd_name); int pNum; Plane **gdsplanes = (Plane **)def->cd_client; UndoDisable(); for (pNum = 0; pNum < MAXCIFRLAYERS; pNum++) { if (gdsplanes[pNum] != NULL) { DBFreePaintPlane(gdsplanes[pNum]); TiFreePlane(gdsplanes[pNum]); } } freeMagic((char *)def->cd_client); if (def->cd_parents != (CellUse *)NULL) { CellUse *cu_p = def->cd_parents; if (type == 0) CIFReadError("CIF read warning: Cell %s has parent %s\n", savename, cu_p->cu_id); else calmaReadError("GDS read warning: Cell %s has parent %s\n", savename, cu_p->cu_id); def->cd_parents = (CellUse *)NULL; } if (DBCellDeleteDef(def) == FALSE) { if (type == 0) CIFReadError("CIF read error: Unable to delete cell %s\n", savename); else calmaReadError("GDS read error: Unable to delete cell %s\n", savename); } else { if (type == 0) CIFReadError("CIF read: Removed flattened cell %s\n", savename); else calmaReadError("GDS read: Removed flattened cell %s\n", savename); } UndoEnable(); freeMagic(savename); } else { if ((type == 0 && CIFNoDRCCheck == FALSE) || (type == 1 && CalmaNoDRCCheck == FALSE)) DRCCheckThis(def, TT_CHECKPAINT, &def->cd_bbox); DBWAreaChanged(def, &def->cd_bbox, DBW_ALLWINDOWS, &DBAllButSpaceBits); DBCellSetModified(def, TRUE); } } HashKill(&CifCellTable); /* Finally, do geometrical processing on the top-level cell. */ CIFPaintCurrent(); DBAdjustLabels(EditCellUse->cu_def, &TiPlaneRect); DBReComputeBbox(EditCellUse->cu_def); DBWAreaChanged(EditCellUse->cu_def, &EditCellUse->cu_def->cd_bbox, DBW_ALLWINDOWS, &DBAllButSpaceBits); DBCellSetModified(EditCellUse->cu_def, TRUE); } magic-8.0.210/cif/CIFread.h0000644000175000001440000001447611435252003013630 0ustar timusers/* * CIFread.h -- * * This file contains definitions used by the CIF reader, but not * by the CIF writing code. The definitions are only used internally * to this module. * * ********************************************************************* * * 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. * * ********************************************************************* * * * rcsid "$Header: /usr/cvsroot/magic-8.0/cif/CIFread.h,v 1.3 2010/08/25 17:33:55 tim Exp $ */ #ifndef _CIFREAD_H #define _CIFREAD_H #include "cif/CIFint.h" /* The structures below are built up by CIFreadtech.c to describe * various styles for reading CIF. */ /* The following structure describes a sequence of geometric * operations used to produce information for a single Magic * layer. There may be several of these structures for the * same Magic layer; in that case, the results end up being * OR'ed together. */ typedef struct { TileType crl_magicType; /* Magic layer to paint results. */ CIFOp *crl_ops; /* List of operations to generate * info for Magic layer. */ int crl_flags; /* Miscellaneous flags (see below). */ } CIFReadLayer; /* The CIFReadLayer flags are: * * CIFR_SIMPLE: Means this layer is a simple one, coming from only * a single OR operation, so it can be handled specially. * CIFR_TEMPLAYER: Means this layer is a temporary CIF layer, and that * the "crl_magicType" should be interpreted as a CIF layer. * CIFR_TEXTLABELS: Means this layer is used for text-only layers, not to * be moved or electrically connected to any other layer. */ #define CIFR_SIMPLE 1 #define CIFR_TEMPLAYER 2 #define CIFR_TEXTLABELS 4 /* The following structure defines a complete CIF read-in style. * The constant MAXCIFRLAYERS must be less than TT_MAXTYPES, and * is used both as the largest number of distinct CIF layer names * in all read styles, and as the larges number of distinct "layer" * commands in any one read style. */ #define MAXCIFRLAYERS (TT_MAXTYPES - 1) /* * To avoid the large memory demands of maintaining all CIF styles in * memory, we keep only the style names and re-read the technology file * as necessary */ typedef struct cifrkeep { struct cifrkeep *crs_next; char *crs_name; } CIFReadKeep; typedef struct cifrstyle { char crs_status; /* Status: Loaded, not loaded, or pending. */ char *crs_name; /* Name for this style of CIF input. */ TileTypeBitMask crs_cifLayers; /* Mask of CIF layers understood in * this style. */ int crs_nLayers; /* Number of CIFReadLayers involved. */ int crs_scaleFactor; /* Number of CIF units per Magic unit. */ int crs_multiplier; /* crs_scaleFactor / crs_multiplier = * units in traditional centimicrons. * So if crs_multiplier = 10, CIF units * are in nanometers (millimicrons). */ TileType crs_labelLayer[MAXCIFRLAYERS]; /* Gives the Magic layer to use for labels * on each possible CIF layer. */ CIFReadLayer *crs_layers[MAXCIFRLAYERS]; HashTable cifCalmaToCif; /* Table mapping from Calma layer numbers to * CIF layers */ int crs_flags; /* Mask of boolean cif-reading options */ } CIFReadStyle; /* option bitmasks used in crs_flags */ #define CRF_IGNORE_UNKNOWNLAYER_LABELS 1 #define CRF_NO_RECONNECT_LABELS 2 /* Methods to deal with fractional results of conversion from CIF to magic */ /* units (see routine CIFScaleCoord() for details). */ #define COORD_EXACT 0 #define COORD_HALF_U 1 #define COORD_HALF_L 2 #define COORD_ANY 3 /* For parsing CIF, we need to keep track of paths (wire locations * or polygon boundaries. These are just linked lists of points. */ #define CIF_ZERO 0 #define CIF_LEFT 1 #define CIF_UP 2 #define CIF_RIGHT 3 #define CIF_DOWN 4 #define CIF_DIAG 5 /* Specific diagonal directions */ #define CIF_DIAG_UL 5 #define CIF_DIAG_UR 6 #define CIF_DIAG_DL 7 #define CIF_DIAG_DR 8 typedef struct cifpath { Point cifp_point; /* A point in the path. */ struct cifpath *cifp_next; /* The next point in the path, or NULL. */ } CIFPath; #define cifp_x cifp_point.p_x #define cifp_y cifp_point.p_y /* Procedures */ extern bool CIFParseBox(), CIFParseWire(), CIFParsePoly(); extern bool CIFParseFlash(), CIFParseLayer(), CIFParseStart(); extern bool CIFParseFinish(), CIFParseDelete(), CIFParseUser(); extern bool CIFParseCall(), CIFParseTransform(), CIFParseInteger(); extern bool CIFParsePath(), CIFParsePoint(), CIFParseSInteger(); extern void CIFSkipToSemi(), CIFSkipSep(), CIFSkipBlanks(); extern void CIFFreePath(), CIFCleanPath(); extern void CIFReadCellInit(), CIFReadCellCleanup(); extern LinkedRect *CIFPolyToRects(); extern Transform *CIFDirectionToTrans(); extern int CIFReadNameToType(); /* Variable argument procedures require complete prototype */ extern void CIFReadError(char *format, ...); extern void CIFReadWarning(char *format, ...); /* Variables shared by the CIF-reading modules, see CIFreadutils.c * for more details: */ extern int cifReadScale1, cifReadScale2; extern int cifNReadLayers; extern Plane *cifReadPlane; extern Plane **cifCurReadPlanes; extern TileType cifCurLabelType; extern CIFReadStyle *cifCurReadStyle; extern bool cifSubcellBeingRead; extern CellDef *cifReadCellDef; extern FILE *cifInputFile; extern bool cifParseLaAvail; extern int cifParseLaChar; /* Macros to read characters, with one-character look-ahead. */ #define PEEK() ( cifParseLaAvail \ ? cifParseLaChar \ : (cifParseLaAvail = TRUE, \ cifParseLaChar = getc(cifInputFile))) #define TAKE() ( cifParseLaAvail \ ? (cifParseLaAvail = FALSE, cifParseLaChar) \ : (cifParseLaChar = getc(cifInputFile))) #endif /* _CIFREAD_H */ magic-8.0.210/cif/Makefile0000644000175000001440000000051310751423606013656 0ustar timusers# # rcsid $Header: /usr/cvsroot/magic-8.0/cif/Makefile,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $ # MODULE = cif MAGICDIR = .. SRCS = CIFgen.c CIFhier.c CIFmain.c CIFrdcl.c CIFrdpt.c CIFrdpoly.c \ CIFrdtech.c CIFrdutils.c CIFsee.c CIFtech.c CIFwrite.c include ${MAGICDIR}/defs.mak include ${MAGICDIR}/rules.mak magic-8.0.210/cif/CIFgen.c0000664000175000001440000027236212502054263013467 0ustar timusers/* CIFgen.c - * * This file provides routines that generate CIF from Magic * tile information, using one of the styles read from the * technology file. * * ********************************************************************* * * 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/cif/CIFgen.c,v 1.23 2010/06/24 20:35:54 tim Exp $"; #endif /* not lint */ #include #include /* for abs() */ #include /* for ceil() and sqrt() */ #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "cif/CIFint.h" #include "calma/calma.h" /* for CalmaContactArrays */ #include "commands/commands.h" /* for CmdFindNetProc() */ #include "select/selInt.h" /* for select use and def */ #include "utils/stack.h" #include "utils/malloc.h" #include "utils/maxrect.h" /* TRUE to run (very slow) algorithm for optimizing non-manhattan tiles */ /* (cuts size of output; see also the GDS "merge" option) */ bool CIFUnfracture = FALSE; /* The following global arrays hold pointers to the CIF planes * generated by the procedures in this module. There are two * kinds of planes: real CIF, which will ostensibly be output, * and temporary layers used to build up more complex geometric * functions. */ global Plane *CIFPlanes[MAXCIFLAYERS]; /* The following are paint tables used by the routines that implement * the geometric operations on mask layers, such as AND, OR, GROW, * etc. There are really only two tables. The first will paint * CIF_SOLIDTYPE over anything else, and the second will paint * space over anything else. These tables are used on planes with * only two tile types, TT_SPACE and CIF_SOLIDTYPE, so they only * have two entries each. */ PaintResultType CIFPaintTable[] = {CIF_SOLIDTYPE, CIF_SOLIDTYPE}; PaintResultType CIFEraseTable[] = {TT_SPACE, TT_SPACE}; /* The following local variables are used as a convenience to pass * information between CIFGen and the various search functions. */ static int growDistance; /* Distance to grow stuff. */ static Plane *cifPlane; /* Plane acted on by search functions. */ static int cifScale; /* Scale factor to use on tiles. */ extern void cifClipPlane(); extern void cifGenClip(); /* * ---------------------------------------------------------------------------- * * cifPaintFunc -- * * This search function is called during CIF_AND and CIF_OR * and CIF_ANDNOT operations for each relevant tile. * * Results: * Always returns 0 to keep the search alive. * * Side effects: * For the area of the tile, either paints or erases in * cifNewPlane, depending on the paint table passed as parameter. * The tile's area is scaled by cifScale first. * ---------------------------------------------------------------------------- */ int cifPaintFunc(tile, table) Tile *tile; PaintResultType *table; /* Used for painting. */ { Rect area; TiToRect(tile, &area); area.r_xbot *= cifScale; area.r_xtop *= cifScale; area.r_ybot *= cifScale; area.r_ytop *= cifScale; DBNMPaintPlane(cifPlane, TiGetTypeExact(tile), &area, table, (PaintUndoInfo *) NULL); CIFTileOps += 1; return 0; } /* * ---------------------------------------------------------------------------- * * cifGrowGridFunc -- * * Called for each relevant tile during grow-grid operations. * * Results: * Always returns 0 to keep the search alive. * * Side effects: * Scales the tile by cifScale, then expands its area by the * remainder of the distance to the nearest grid point, as * defined by the grid distance (growDistance) in the current * CIFOp, then paints this area into cifNewPlane using the table * passed as parameter. * ---------------------------------------------------------------------------- */ int cifGrowGridFunc(tile, table) Tile *tile; PaintResultType *table; /* Table to be used for painting. */ { Rect area; int remainder; /* To be done---handle non-Manhattan geometry */ TileType oldType = TiGetType(tile); TiToRect(tile, &area); /* In scaling the tile, watch out for infinities!! If something * is already infinity, don't change it. */ if (area.r_xbot > TiPlaneRect.r_xbot) area.r_xbot *= cifScale; if (area.r_ybot > TiPlaneRect.r_ybot) area.r_ybot *= cifScale; if (area.r_xtop < TiPlaneRect.r_xtop) area.r_xtop *= cifScale; if (area.r_ytop < TiPlaneRect.r_ytop) area.r_ytop *= cifScale; /* In scaling the tile, watch out for infinities!! If something * is already infinity, don't change it. */ if (area.r_xbot > TiPlaneRect.r_xbot) area.r_xbot -= (abs(area.r_xbot) % growDistance); if (area.r_ybot > TiPlaneRect.r_ybot) area.r_ybot -= (abs(area.r_ybot) % growDistance); if (area.r_xtop < TiPlaneRect.r_xtop) area.r_xtop += (abs(area.r_xtop) % growDistance); if (area.r_ytop < TiPlaneRect.r_ytop) area.r_ytop += (abs(area.r_ytop) % growDistance); DBPaintPlane(cifPlane, &area, table, (PaintUndoInfo *) NULL); CIFTileOps += 1; return 0; } /* * ---------------------------------------------------------------------------- * * cifGrowEuclideanFunc -- * * Called for each relevant tile during grow or shrink operations. * For growing, these are solid tiles. For shrinking, these are * space tiles. This routine differs from cifGrowFunc in that it * grows the minimum distance on non-Manhattan edges necessary to * create a euclidean distance to the edge of growDistance while * keeping corner points on-grid. This requires a substantially * different algorithm from cifGrowFunc. * * Results: * Always returns 0 to keep the search alive. * * Side effects: * Scales the tile by cifScale, then expands its area by the * distance in the current CIFOp, then paints this area into * cifNewPlane using the table passed as parameter. * ---------------------------------------------------------------------------- */ #define GROW_NORTH 0x1 #define GROW_SOUTH 0x2 #define GROW_EAST 0x4 #define GROW_WEST 0x8 #define STOP_NW 0x1 /* WN EN */ #define STOP_SW 0x2 /* NW +-------+ NE */ #define STOP_NE 0x4 /* | | */ #define STOP_SE 0x8 /* | | */ #define STOP_WN 0x10 /* SW +-------+ SE */ #define STOP_WS 0x20 /* WS ES */ #define STOP_EN 0x40 #define STOP_ES 0x80 int cifGrowEuclideanFunc(tile, table) Tile *tile; PaintResultType *table; /* Table to be used for painting. */ { Tile *tp; Rect area, rtmp; TileType oldType = TiGetTypeExact(tile); unsigned char growDirs = GROW_NORTH | GROW_SOUTH | GROW_EAST | GROW_WEST; unsigned char cornerDirs = 0; TiToRect(tile, &area); /* In scaling the tile, watch out for infinities!! If something * is already infinity, don't change it. */ if (area.r_xbot > TiPlaneRect.r_xbot) area.r_xbot *= cifScale; else growDirs &= ~GROW_WEST; if (area.r_ybot > TiPlaneRect.r_ybot) area.r_ybot *= cifScale; else growDirs &= ~GROW_SOUTH; if (area.r_xtop < TiPlaneRect.r_xtop) area.r_xtop *= cifScale; else growDirs &= ~GROW_EAST; if (area.r_ytop < TiPlaneRect.r_ytop) area.r_ytop *= cifScale; else growDirs &= ~GROW_NORTH; /* Grow on diagonal tiles: grow rectangular tiles around the */ /* straight edges of the right-triangle, then copy the diagonal */ /* tile (at its original size) in the direction of the diagonal. */ /* Note: A diagonal tile, by definition, can't have infinities. */ if (oldType & TT_DIAGONAL) { int growDistanceX, growDistanceY; int height, width; double hyp; if (oldType & TT_SIDE) growDirs &= ~GROW_WEST; else growDirs &= ~GROW_EAST; if (((oldType & TT_SIDE) >> 1) == (oldType & TT_DIRECTION)) growDirs &= ~GROW_SOUTH; else growDirs &= ~GROW_NORTH; /* Grow non-Manhattan edges to (the closest integer value */ /* to) growDistance along the normal to the edge. This */ /* will overestimate the distance only to the minimum */ /* amount necessary to ensure on-grid endpoints. */ width = area.r_xtop - area.r_xbot; height = area.r_ytop - area.r_ybot; hyp = sqrt((double)(width * width + height * height)); growDistanceY = ceil((growDistance * (hyp - height)) / width); growDistanceX = ceil((growDistance * (hyp - width)) / height); /* Draw vertical tile to distance X */ rtmp = area; if (!(growDirs & GROW_EAST)) rtmp.r_xtop = rtmp.r_xbot + growDistanceX; if (!(growDirs & GROW_WEST)) rtmp.r_xbot = rtmp.r_xtop - growDistanceX; if (!(growDirs & GROW_SOUTH)) rtmp.r_ybot -=growDistance; if (!(growDirs & GROW_NORTH)) rtmp.r_ytop += growDistance; DBPaintPlane(cifPlane, &rtmp, table, (PaintUndoInfo *) NULL); /* Draw horizontal tile to distance Y */ rtmp = area; if (!(growDirs & GROW_EAST)) rtmp.r_xtop += growDistance; if (!(growDirs & GROW_WEST)) rtmp.r_xbot -= growDistance; if (!(growDirs & GROW_SOUTH)) rtmp.r_ybot = rtmp.r_ytop - growDistanceY; if (!(growDirs & GROW_NORTH)) rtmp.r_ytop = rtmp.r_ybot + growDistanceY; DBPaintPlane(cifPlane, &rtmp, table, (PaintUndoInfo *) NULL); /* Finally: translate, resize, and paint the diagonal tile */ rtmp = area; if (!(growDirs & GROW_NORTH)) rtmp.r_ytop += growDistance; else rtmp.r_ytop -= growDistanceY; if (!(growDirs & GROW_SOUTH)) rtmp.r_ybot -= growDistance; else rtmp.r_ybot += growDistanceY; if (!(growDirs & GROW_EAST)) rtmp.r_xtop += growDistance; else rtmp.r_xtop -= growDistanceX; if (!(growDirs & GROW_WEST)) rtmp.r_xbot -= growDistance; else rtmp.r_xbot += growDistanceX; DBNMPaintPlane(cifPlane, oldType, &rtmp, table, (PaintUndoInfo *) NULL); oldType = (growDirs & GROW_EAST) ? TiGetRightType(tile) : TiGetLeftType(tile); } else DBPaintPlane(cifPlane, &area, table, (PaintUndoInfo *) NULL); /* Check tile corner areas for paint */ tp = TR(tile); if (TiGetLeftType(tp) == oldType) cornerDirs |= STOP_NE; for (; TOP(LB(tp)) > BOTTOM(tile); tp = LB(tp)); if (TiGetLeftType(tp) == oldType) cornerDirs |= STOP_SE; tp = RT(tile); if (TiGetBottomType(tp) == oldType) cornerDirs |= STOP_EN; for (; RIGHT(BL(tp)) > LEFT(tile); tp = BL(tp)); if (TiGetBottomType(tp) == oldType) cornerDirs |= STOP_WN; tp = BL(tile); if (TiGetRightType(tp) == oldType) cornerDirs |= STOP_SW; for (; BOTTOM(RT(tp)) < TOP(tile); tp = RT(tp)); if (TiGetRightType(tp) == oldType) cornerDirs |= STOP_NW; tp = LB(tile); if (TiGetTopType(tp) == oldType) cornerDirs |= STOP_WS; for (; LEFT(TR(tp)) < RIGHT(tile); tp = TR(tp)); if (TiGetTopType(tp) == oldType) cornerDirs |= STOP_ES; if (growDirs & GROW_NORTH) { rtmp = area; rtmp.r_ybot = area.r_ytop; rtmp.r_ytop = area.r_ytop + growDistance; if ((cornerDirs & (STOP_EN | STOP_NE)) == 0) if (growDirs & GROW_EAST) rtmp.r_xtop += growDistance; if ((cornerDirs & (STOP_WN | STOP_NW)) == 0) if (growDirs & GROW_WEST) rtmp.r_xbot -= growDistance; DBPaintPlane(cifPlane, &rtmp, table, (PaintUndoInfo *) NULL); } if (growDirs & GROW_EAST) { rtmp = area; rtmp.r_xbot = area.r_xtop; rtmp.r_xtop = area.r_xtop + growDistance; if ((cornerDirs & (STOP_EN | STOP_NE)) == 0) if (growDirs & GROW_NORTH) rtmp.r_ytop += growDistance; if ((cornerDirs & (STOP_SE | STOP_ES)) == 0) if (growDirs & GROW_SOUTH) rtmp.r_ybot -= growDistance; DBPaintPlane(cifPlane, &rtmp, table, (PaintUndoInfo *) NULL); } if (growDirs & GROW_SOUTH) { rtmp = area; rtmp.r_ytop = area.r_ybot; rtmp.r_ybot = area.r_ybot - growDistance; if ((cornerDirs & (STOP_SE | STOP_ES)) == 0) if (growDirs & GROW_EAST) rtmp.r_xtop += growDistance; if ((cornerDirs & (STOP_SW | STOP_WS)) == 0) if (growDirs & GROW_WEST) rtmp.r_xbot -= growDistance; DBPaintPlane(cifPlane, &rtmp, table, (PaintUndoInfo *) NULL); } if (growDirs & GROW_WEST) { rtmp = area; rtmp.r_xtop = area.r_xbot; rtmp.r_xbot = area.r_xbot - growDistance; if ((cornerDirs & (STOP_NW | STOP_WN)) == 0) if (growDirs & GROW_NORTH) rtmp.r_ytop += growDistance; if ((cornerDirs & (STOP_SW | STOP_WS)) == 0) if (growDirs & GROW_SOUTH) rtmp.r_ybot -= growDistance; DBPaintPlane(cifPlane, &rtmp, table, (PaintUndoInfo *) NULL); } CIFTileOps++; return 0; } /* * ---------------------------------------------------------------------------- * * cifGrowFunc -- * * Called for each relevant tile during grow or shrink operations. * For growing, these are solid tiles. For shrinking, these are * space tiles. * * Results: * Always returns 0 to keep the search alive. * * Side effects: * Scales the tile by cifScale, then expands its area by the * distance in the current CIFOp, then paints this area into * cifNewPlane using the table passed as parameter. * ---------------------------------------------------------------------------- */ int cifGrowFunc(tile, table) Tile *tile; PaintResultType *table; /* Table to be used for painting. */ { Rect area; TileType oldType = TiGetTypeExact(tile); TiToRect(tile, &area); /* In scaling the tile, watch out for infinities!! If something * is already infinity, don't change it. */ if (area.r_xbot > TiPlaneRect.r_xbot) area.r_xbot *= cifScale; if (area.r_ybot > TiPlaneRect.r_ybot) area.r_ybot *= cifScale; if (area.r_xtop < TiPlaneRect.r_xtop) area.r_xtop *= cifScale; if (area.r_ytop < TiPlaneRect.r_ytop) area.r_ytop *= cifScale; /* Grow on diagonal tiles: grow rectangular tiles around the */ /* straight edges of the right-triangle, then copy the diagonal */ /* tile (at its original size) in the direction of the diagonal. */ /* Note: A diagonal tile, by definition, can't have infinities. */ if (oldType & TT_DIAGONAL) { Rect rtmp; /* Grow top and bottom */ rtmp.r_ybot = area.r_ybot - growDistance; rtmp.r_ytop = area.r_ytop + growDistance; /* Grow around left or right edge */ if (oldType & TT_SIDE) { rtmp.r_xbot = area.r_xtop - growDistance; rtmp.r_xtop = area.r_xtop + growDistance; } else { rtmp.r_xbot = area.r_xbot - growDistance; rtmp.r_xtop = area.r_xbot + growDistance; } DBPaintPlane(cifPlane, &rtmp, table, (PaintUndoInfo *) NULL); /* Now do the same for the other edge. */ rtmp.r_xbot = area.r_xbot - growDistance; rtmp.r_xtop = area.r_xtop + growDistance; if (((oldType & TT_SIDE) >> 1) == (oldType & TT_DIRECTION)) /* top */ { rtmp.r_ybot = area.r_ytop - growDistance; rtmp.r_ytop = area.r_ytop + growDistance; } else /* bottom */ { rtmp.r_ybot = area.r_ybot - growDistance; rtmp.r_ytop = area.r_ybot + growDistance; } DBPaintPlane(cifPlane, &rtmp, table, (PaintUndoInfo *) NULL); /* Finally, Move and replace the diagonal tile */ if (oldType & TT_SIDE) { rtmp.r_xtop = area.r_xtop - growDistance; rtmp.r_xbot = area.r_xbot - growDistance; } else { rtmp.r_xtop = area.r_xtop + growDistance; rtmp.r_xbot = area.r_xbot + growDistance; } if (((oldType & TT_SIDE) >> 1) == (oldType & TT_DIRECTION)) /* top */ { rtmp.r_ytop = area.r_ytop - growDistance; rtmp.r_ybot = area.r_ybot - growDistance; } else /* bottom */ { rtmp.r_ytop = area.r_ytop + growDistance; rtmp.r_ybot = area.r_ybot + growDistance; } DBNMPaintPlane(cifPlane, oldType, &rtmp, table, (PaintUndoInfo *) NULL); } else { /* In scaling the tile, watch out for infinities!! If something * is already infinity, don't change it. */ if (area.r_xbot > TiPlaneRect.r_xbot) area.r_xbot -= growDistance; if (area.r_ybot > TiPlaneRect.r_ybot) area.r_ybot -= growDistance; if (area.r_xtop < TiPlaneRect.r_xtop) area.r_xtop += growDistance; if (area.r_ytop < TiPlaneRect.r_ytop) area.r_ytop += growDistance; DBPaintPlane(cifPlane, &area, table, (PaintUndoInfo *) NULL); } CIFTileOps += 1; return 0; } /* * ---------------------------------------------------------------------------- * * cifBloatFunc -- * * Called once for each tile to be selectively bloated. * * Results: * Always returns 0 to keep the search alive. * * Side effects: * Uses the bloat table in the current CIFOp to expand the * tile depending on which tiles it abuts, then paints the * expanded area into the new CIF plane. The bloat table * contains one entry for each tile type. When that tile * type is seen next to the current tile, the area of the current * tile is bloated by the table value in that location. The * only exception to this rule is that internal edges (between * two tiles of the same type) cause no bloating. * Note: the original tile is scaled into CIF coordinates. * ---------------------------------------------------------------------------- */ int cifBloatFunc(tile, clientData) Tile *tile; ClientData clientData; { Rect tileArea, cifArea, bloat; TileType oldType, type, topLeftType, bottomRightType; Tile *t; int tilestart, tilestop, cifstart, cifstop; BloatData *bloats = (BloatData *)clientData; int *bloatTable = (int *)bloats->bl_distance; oldType = TiGetTypeExact(tile); TiToRect(tile, &tileArea); /* Output the original area of the tile. */ cifArea = tileArea; cifArea.r_xbot *= cifScale; cifArea.r_xtop *= cifScale; cifArea.r_ybot *= cifScale; cifArea.r_ytop *= cifScale; /* This is a modified version of the nonmanhattan grow function. */ /* We grow only in the direction of the diagonal. */ /* This will not work in all situations! Corner extensions are not */ /* considered (but should be, for completeness). */ if (oldType & TT_DIAGONAL) { TileType otherType = (oldType & TT_SIDE) ? TiGetLeftType(tile) : TiGetRightType(tile); int dist = bloatTable[otherType]; /* The Euclidean grow function is identical to Euclidean bloat-or */ if (CIFCurStyle->cs_flags & CWF_GROW_EUCLIDEAN) { growDistance = dist; cifGrowEuclideanFunc(tile, CIFPaintTable); } else { /* Grow top and bottom */ if (((oldType & TT_SIDE) >> 1) == (oldType & TT_DIRECTION)) /* top */ { bloat.r_ybot = cifArea.r_ytop - dist; bloat.r_ytop = cifArea.r_ytop; } else /* bottom */ { bloat.r_ybot = cifArea.r_ybot; bloat.r_ytop = cifArea.r_ybot + dist; } /* Grow around left or right edge */ if (oldType & TT_SIDE) { bloat.r_xbot = cifArea.r_xbot - dist; bloat.r_xtop = cifArea.r_xtop; } else { bloat.r_xbot = cifArea.r_xbot; bloat.r_xtop = cifArea.r_xtop + dist; } DBPaintPlane(cifPlane, &bloat, CIFPaintTable, (PaintUndoInfo *) NULL); /* Now do the same for the left or right edge. */ if (((oldType & TT_SIDE) >> 1) == (oldType & TT_DIRECTION)) /* top */ { bloat.r_ybot = cifArea.r_ybot - dist; bloat.r_ytop = cifArea.r_ytop; } else /* bottom */ { bloat.r_ybot = cifArea.r_ybot; bloat.r_ytop = cifArea.r_ytop + dist; } if (oldType & TT_SIDE) { bloat.r_xbot = cifArea.r_xtop - dist; bloat.r_xtop = cifArea.r_xtop; } else { bloat.r_xbot = cifArea.r_xbot; bloat.r_xtop = cifArea.r_xbot + dist; } DBPaintPlane(cifPlane, &bloat, CIFPaintTable, (PaintUndoInfo *) NULL); /* Finally, Move and replace the diagonal tile */ if (oldType & TT_SIDE) { bloat.r_xtop = cifArea.r_xtop - dist; bloat.r_xbot = cifArea.r_xbot - dist; } else { bloat.r_xtop = cifArea.r_xtop + dist; bloat.r_xbot = cifArea.r_xbot + dist; } if (((oldType & TT_SIDE) >> 1) == (oldType & TT_DIRECTION)) /* top */ { bloat.r_ytop = cifArea.r_ytop - dist; bloat.r_ybot = cifArea.r_ybot - dist; } else /* bottom */ { bloat.r_ytop = cifArea.r_ytop + dist; bloat.r_ybot = cifArea.r_ybot + dist; } DBNMPaintPlane(cifPlane, oldType, &bloat, CIFPaintTable, (PaintUndoInfo *) NULL); } } else DBNMPaintPlane(cifPlane, oldType, &cifArea, CIFPaintTable, (PaintUndoInfo *) NULL); /* Go around the tile, scanning the neighbors along each side. * Start with the left side, and output the bloats along that * side, if any. */ tilestop = tileArea.r_ytop; cifstop = cifArea.r_ytop; type = oldType; /* If the tile type doesn't exist on the left side, skip */ if (oldType & TT_DIAGONAL) { type = TiGetLeftType(tile); if (oldType & TT_SIDE) { if (oldType & TT_DIRECTION) { topLeftType = type; goto dotop; } else { tilestop = tileArea.r_ybot; cifstop = cifArea.r_ybot; type = TiGetBottomType(tile); } } } bloat.r_ybot = cifArea.r_ybot - bloatTable[TiGetRightType(LB(tile))]; bloat.r_xtop = cifArea.r_xbot; for (t = BL(tile); BOTTOM(t) < TOP(tile); t = RT(t)) { if (BOTTOM(t) >= tilestop) continue; topLeftType = TiGetRightType(t); bloat.r_xbot = bloat.r_xtop - bloatTable[topLeftType]; if (TOP(t) > tilestop) bloat.r_ytop = cifstop; else bloat.r_ytop = cifScale * TOP(t); if ((bloatTable[topLeftType] != 0) && (topLeftType != type)) DBPaintPlane(cifPlane, &bloat, CIFPaintTable, (PaintUndoInfo *) NULL); bloat.r_ybot = bloat.r_ytop; } /* Now do the top side. Use the type of the top-left tile to * side-extend the left end of the top bloat in order to match * things up at the corner. */ dotop: cifstart = cifArea.r_xtop; tilestart = tileArea.r_xtop; /* If the tile type doesn't exist on the top side, skip */ if (oldType & TT_DIAGONAL) { type = TiGetTopType(tile); if (((oldType & TT_SIDE) >> 1) != (oldType & TT_DIRECTION)) { if (oldType & TT_SIDE) goto doright; else { cifstart = cifArea.r_xbot; tilestart = tileArea.r_xbot; type = TiGetLeftType(tile); } } } bloat.r_ybot = cifArea.r_ytop; bloat.r_xtop = cifstart; for (t = RT(tile); RIGHT(t) > LEFT(tile); t = BL(t)) { TileType otherType; if (LEFT(t) >= tilestart) continue; otherType = TiGetBottomType(t); bloat.r_ytop = bloat.r_ybot + bloatTable[otherType]; if (LEFT(t) <= tileArea.r_xbot) bloat.r_xbot = cifArea.r_xbot - bloatTable[topLeftType]; else bloat.r_xbot = cifScale * LEFT(t); if ((bloatTable[otherType] != 0) && (otherType != type)) DBPaintPlane(cifPlane, &bloat, CIFPaintTable, (PaintUndoInfo *) NULL); bloat.r_xtop = bloat.r_xbot; } /* Now do the right side. */ doright: tilestop = tileArea.r_ybot; cifstop = cifArea.r_ybot; /* If the tile type doesn't exist on the right side, skip */ if (oldType & TT_DIAGONAL) { type = TiGetRightType(tile); if (!(oldType & TT_SIDE)) { if (oldType & TT_DIRECTION) { bottomRightType = type; goto dobottom; } else { tilestop = tileArea.r_ytop; cifstop = cifArea.r_ytop; type = TiGetTopType(tile); } } } bloat.r_ytop = cifArea.r_ytop + bloatTable[TiGetLeftType(RT(tile))]; bloat.r_xbot = cifArea.r_xtop; for (t = TR(tile); TOP(t) > BOTTOM(tile); t = LB(t)) { if (TOP(t) <= tilestop) continue; bottomRightType = TiGetLeftType(t); bloat.r_xtop = bloat.r_xbot + bloatTable[bottomRightType]; if (BOTTOM(t) < tilestop) bloat.r_ybot = cifstop; else bloat.r_ybot = cifScale * BOTTOM(t); if ((bloatTable[bottomRightType] != 0) && (bottomRightType != type)) DBPaintPlane(cifPlane, &bloat, CIFPaintTable, (PaintUndoInfo *) NULL); bloat.r_ytop = bloat.r_ybot; } /* Now do the bottom side. Use the type of the bottom-right tile * to side-extend the right end of the bottom bloat in order to match * things up at the corner. */ dobottom: cifstart = cifArea.r_xbot; tilestart = tileArea.r_xbot; /* If the tile type doesn't exist on the bottom side, skip */ if (oldType & TT_DIAGONAL) { type = TiGetBottomType(tile); if (((oldType & TT_SIDE) >> 1) == (oldType & TT_DIRECTION)) { if (!(oldType & TT_DIRECTION)) goto endbloat; else { cifstart = cifArea.r_xtop; tilestart = tileArea.r_xtop; type = TiGetRightType(tile); } } } bloat.r_ytop = cifArea.r_ybot; bloat.r_xbot = cifstart; for (t = LB(tile); LEFT(t) < RIGHT(tile); t = TR(t)) { TileType otherType; if (RIGHT(t) <= tilestart) continue; otherType = TiGetTopType(t); bloat.r_ybot = bloat.r_ytop - bloatTable[otherType]; if (RIGHT(t) >= tileArea.r_xtop) bloat.r_xtop = cifArea.r_xtop + bloatTable[bottomRightType]; else bloat.r_xtop = cifScale * RIGHT(t); if ((bloatTable[otherType] != 0) && (otherType != type)) DBPaintPlane(cifPlane, &bloat, CIFPaintTable, (PaintUndoInfo *) NULL); bloat.r_xbot = bloat.r_xtop; } endbloat: CIFTileOps += 1; return 0; } /* * ---------------------------------------------------------------------------- * * cifBloatAllFunc -- * * Called once for each tile to be selectively bloated * using the CIFOP_BLOATALL operation. * * Results: * Always returns 0 to keep the search alive. * * Side effects: * Uses the bloat table in the current CIFOp to expand the tile, * depending on which tiles it abuts. All bordering material that * has bl_distance = 1 is painted into the result plane. * * ---------------------------------------------------------------------------- */ #define CIF_PENDING 0 #define CIF_UNPROCESSED CLIENTDEFAULT #define CIF_PROCESSED 1 #define CIF_IGNORE 2 #define PUSHTILE(tp, stack) \ if ((tp)->ti_client == (ClientData) CIF_UNPROCESSED) { \ (tp)->ti_client = (ClientData) CIF_PENDING; \ STACKPUSH((ClientData) (tp), stack); \ } int cifBloatAllFunc(tile, op) Tile *tile; /* The tile to be processed. */ CIFOp *op; /* Describes the operation to be performed */ { Rect area; TileTypeBitMask connect; Tile *t, *tp; TileType type; BloatData *bloats = (BloatData *)op->co_client; int i; static Stack *BloatStack = (Stack *)NULL; /* Create a mask of all connecting types (these must be in a single * plane), then call a search function to find all connecting material * of these types. */ TTMaskZero(&connect); for (i = 0; i < TT_MAXTYPES; i++) if (bloats->bl_distance[i] != 0) TTMaskSetType(&connect, i); /* This search function is based on drcCheckArea */ if (BloatStack == (Stack *)NULL) BloatStack = StackNew(64); PUSHTILE(tile, BloatStack); while (!StackEmpty(BloatStack)) { t = (Tile *) STACKPOP(BloatStack); if (t->ti_client != (ClientData)CIF_PENDING) continue; t->ti_client = (ClientData)CIF_PROCESSED; /* Get the tile into CIF coordinates. */ TiToRect(t, &area); area.r_xbot *= cifScale; area.r_ybot *= cifScale; area.r_xtop *= cifScale; area.r_ytop *= cifScale; DBNMPaintPlane(cifPlane, TiGetTypeExact(t), &area, CIFPaintTable, (PaintUndoInfo *) NULL); /* Top */ for (tp = RT(t); RIGHT(tp) > LEFT(t); tp = BL(tp)) if (TTMaskHasType(&connect, TiGetBottomType(tp))) PUSHTILE(tp, BloatStack); /* Left */ for (tp = BL(t); BOTTOM(tp) < TOP(t); tp = RT(tp)) if (TTMaskHasType(&connect, TiGetRightType(tp))) PUSHTILE(tp, BloatStack); /* Bottom */ for (tp = LB(t); LEFT(tp) < RIGHT(t); tp = TR(tp)) if (TTMaskHasType(&connect, TiGetTopType(tp))) PUSHTILE(tp, BloatStack); /* Right */ for (tp = TR(t); TOP(tp) > BOTTOM(t); tp = LB(tp)) if (TTMaskHasType(&connect, TiGetLeftType(tp))) PUSHTILE(tp, BloatStack); } /* Clear the tiles that were processed */ tile->ti_client = (ClientData)CIF_UNPROCESSED; STACKPUSH(tile, BloatStack); while (!StackEmpty(BloatStack)) { t = (Tile *) STACKPOP(BloatStack); /* Top */ for (tp = RT(t); RIGHT(tp) > LEFT(t); tp = BL(tp)) if (tp->ti_client != (ClientData)CIF_UNPROCESSED) { tp->ti_client = (ClientData)CIF_UNPROCESSED; STACKPUSH(tp, BloatStack); } /* Left */ for (tp = BL(t); BOTTOM(tp) < TOP(t); tp = RT(tp)) if (tp->ti_client != (ClientData)CIF_UNPROCESSED) { tp->ti_client = (ClientData)CIF_UNPROCESSED; STACKPUSH(tp, BloatStack); } /* Bottom */ for (tp = LB(t); LEFT(tp) < RIGHT(t); tp = TR(tp)) if (tp->ti_client != (ClientData)CIF_UNPROCESSED) { tp->ti_client = (ClientData)CIF_UNPROCESSED; STACKPUSH(tp, BloatStack); } /* Right */ for (tp = TR(t); TOP(tp) > BOTTOM(t); tp = LB(tp)) if (tp->ti_client != (ClientData)CIF_UNPROCESSED) { tp->ti_client = (ClientData)CIF_UNPROCESSED; STACKPUSH(tp, BloatStack); } } return 0; /* Keep the search alive. . . */ } /*--------------------------------------------------------------*/ /* Support routines and definitions for cifSquaresFillArea */ /*--------------------------------------------------------------*/ /*------------------------------------------------------*/ /* Data structure used for identifying contact strips */ /*------------------------------------------------------*/ typedef struct _linkedStrip { Rect area; bool vertical; /* Tile is vertical */ bool shrink_ld; /* Shrink left or down before creating cuts */ bool shrink_ur; /* Shrink right or up before creating cuts */ struct _linkedStrip *strip_next; } linkedStrip; typedef struct { int size; int pitch; linkedStrip *strips; } StripsData; /* *------------------------------------------------------- * * cifSquaresInitFunc -- * * Find the first unprocessed tile in the plane. * * Results: * Return 1 to stop the search and process. * Otherwise, return 0 to keep the search going. * *------------------------------------------------------- */ int cifSquaresInitFunc(tile, clientData) Tile *tile; ClientData clientData; { if (tile->ti_client == (ClientData) CIF_UNPROCESSED) return 1; else return 0; } /* *------------------------------------------------------- * * cifSquaresStripFunc -- * * Find vertical or horizontal strips of contact * material that is between 1 and 2 contact cuts wide. * Generate and return a list of all such strips. * * Results: Return 0 to keep the search going. * *------------------------------------------------------- */ int cifSquaresStripFunc(tile, stripsData) Tile *tile; StripsData *stripsData; { bool vertical; int width, height; linkedStrip *newStrip; Tile *tp, *tp2; Rect bbox; if (IsSplit(tile)) return 0; TiToRect(tile, &bbox); /* Check if the tile is wide enough for exactly one cut */ width = bbox.r_xtop - bbox.r_xbot; height = bbox.r_ytop - bbox.r_ybot; if (height > width) { vertical = TRUE; height = width; } else vertical = FALSE; if ((height < stripsData->size) || (height >= (stripsData->size + stripsData->pitch))) return 0; /* Ignore strips that are part of a larger */ /* collection of non-manhattan geometry. */ for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp)) if (IsSplit(tp)) break; if (BOTTOM(tp) < TOP(tile)) return 0; /* Note that the max horizontal stripes rule guarantees */ /* that a tile is always bounded on left and right by */ /* TT_SPACE. Thus, we only need to search the top and */ /* bottom boundaries of horizontal tiles. */ if (vertical) { newStrip = (linkedStrip *)mallocMagic(sizeof(linkedStrip)); newStrip->area = bbox; newStrip->vertical = TRUE; newStrip->shrink_ur = (TTMaskHasType(&CIFSolidBits, TiGetBottomType(RT(tile)))) ? TRUE : FALSE; newStrip->shrink_ld = (TTMaskHasType(&CIFSolidBits, TiGetTopType(LB(tile)))) ? TRUE : FALSE; newStrip->strip_next = stripsData->strips; stripsData->strips = newStrip; } else { int segstart, segend; int matchstart, matchend; tp = RT(tile); segend = RIGHT(tile); while (RIGHT(tp) > LEFT(tile)) { /* Isolate segments of space along the top of the tile */ while ((RIGHT(tp) > LEFT(tile)) && TTMaskHasType(&CIFSolidBits, TiGetBottomType(tp))) tp = BL(tp); segend = MIN(segend, RIGHT(tp)); while ((RIGHT(tp) > LEFT(tile)) && TTMaskHasType(&DBSpaceBits, TiGetBottomType(tp))) tp = BL(tp); segstart = MAX(LEFT(tile), RIGHT(tp)); if (segend <= segstart) break; /* Find matching segments along the bottom of the tile */ for (tp2 = LB(tile); RIGHT(tp2) < segstart; tp2 = TR(tp2)); while (LEFT(tp2) < segend) { while (RIGHT(tp2) < segstart) tp2 = TR(tp2); while ((LEFT(tp2) < segend) && TTMaskHasType(&CIFSolidBits, TiGetTopType(tp2))) tp2 = TR(tp2); matchstart = MAX(LEFT(tp2), segstart); while ((LEFT(tp2) < segend) && TTMaskHasType(&DBSpaceBits, TiGetTopType(tp2))) tp2 = TR(tp2); matchend = MIN(LEFT(tp2), segend); if (matchend <= matchstart) break; /* Process the strip */ newStrip = (linkedStrip *)mallocMagic(sizeof(linkedStrip)); newStrip->area = bbox; newStrip->area.r_xbot = matchstart; newStrip->area.r_xtop = matchend; newStrip->vertical = FALSE; newStrip->strip_next = stripsData->strips; newStrip->shrink_ur = (matchend != RIGHT(tile)) ? TRUE : FALSE; newStrip->shrink_ld = (matchstart != LEFT(tile)) ? TRUE : FALSE; stripsData->strips = newStrip; } } } return 0; } /* *------------------------------------------------------- * * cifSquaresResetFunc -- * * Unmark tiles * * Results: Return 0 to keep the search going. * *------------------------------------------------------- */ int cifSquaresResetFunc(tile, clientData) Tile *tile; ClientData clientData; /* unused */ { tile->ti_client = (ClientData) CIF_UNPROCESSED; return 0; } /* *------------------------------------------------------- * * cifUnconnectFunc -- * * Find space tiles inside a possible contact area * * Results: Return 1 to stop the ongoing search. * *------------------------------------------------------- */ int cifUnconnectFunc(tile, clientData) Tile *tile; ClientData clientData; /* unused */ { TileType t; t = TiGetTypeExact(tile); if (t == TT_SPACE) return 1; else if (t & TT_DIAGONAL) return 1; else if (tile->ti_client != (ClientData)CIF_PROCESSED) return 1; return 0; } /* * ---------------------------------------------------------------------------- * * cifRectBoundingBox -- * * Fill regions of the current CIF plane with rectangles that represent * the bounding box of each unconnected area. This function "cleans * up" areas processed by multiple rules and removes notches and * cut-outs. * * Results: * None. * * Side effects: * * ---------------------------------------------------------------------------- */ void cifRectBoundingBox(op, cellDef, plane) CIFOp *op; CellDef *cellDef; Plane *plane; { Tile *tile = NULL, *t, *tp; Rect bbox, area, *maxr; int i, j, savecount; TileType type; bool simple; static Stack *BoxStack = (Stack *)NULL; if (BoxStack == (Stack *)NULL) BoxStack = StackNew(64); while (DBSrPaintArea((Tile *)tile, plane, &TiPlaneRect, &CIFSolidBits, cifSquaresInitFunc, (ClientData)NULL) != 0) { /* Now, search for (nontrivially) connected tiles in all */ /* directions. Mark the tiles, and record the bounding box. */ /* (Largely copied from cifSquaresFillArea) */ simple = TRUE; tile = plane->pl_hint; TiToRect(tile, &bbox); PUSHTILE(tile, BoxStack); while (!StackEmpty(BoxStack)) { t = (Tile *) STACKPOP(BoxStack); if (t->ti_client != (ClientData)CIF_PENDING) continue; t->ti_client = (ClientData)CIF_PROCESSED; /* Adjust bounding box */ TiToRect(t, &area); GeoInclude(&area, &bbox); if (IsSplit(t)) simple = FALSE; /* Top */ for (tp = RT(t); RIGHT(tp) > LEFT(t); tp = BL(tp)) if (TTMaskHasType(&CIFSolidBits, TiGetBottomType(tp))) { simple = FALSE; PUSHTILE(tp, BoxStack); } /* Left */ for (tp = BL(t); BOTTOM(tp) < TOP(t); tp = RT(tp)) if (TTMaskHasType(&CIFSolidBits, TiGetRightType(tp))) { simple = FALSE; PUSHTILE(tp, BoxStack); } /* Bottom */ for (tp = LB(t); LEFT(tp) < RIGHT(t); tp = TR(tp)) if (TTMaskHasType(&CIFSolidBits, TiGetTopType(tp))) { simple = FALSE; PUSHTILE(tp, BoxStack); } /* Right */ for (tp = TR(t); TOP(tp) > BOTTOM(t); tp = LB(tp)) if (TTMaskHasType(&CIFSolidBits, TiGetLeftType(tp))) { simple = FALSE; PUSHTILE(tp, BoxStack); } } if (op->co_client == (ClientData)1) /* external */ { DBPaintPlane(cifPlane, &bbox, CIFPaintTable, (PaintUndoInfo *)NULL); CIFTileOps++; } else /* internal */ { if (simple) { DBPaintPlane(cifPlane, &bbox, CIFPaintTable, (PaintUndoInfo *)NULL); CIFTileOps++; } else { maxr = FindMaxRectangle2(&bbox, tile, plane); DBPaintPlane(cifPlane, maxr, CIFPaintTable, (PaintUndoInfo *)NULL); CIFTileOps++; } } /* Clear the tiles that were processed in this set */ tile->ti_client = (ClientData)CIF_IGNORE; STACKPUSH(tile, BoxStack); while (!StackEmpty(BoxStack)) { t = (Tile *) STACKPOP(BoxStack); /* Top */ for (tp = RT(t); RIGHT(tp) > LEFT(t); tp = BL(tp)) if (tp->ti_client == (ClientData)CIF_PROCESSED) { tp->ti_client = (ClientData)CIF_IGNORE; STACKPUSH(tp, BoxStack); } /* Left */ for (tp = BL(t); BOTTOM(tp) < TOP(t); tp = RT(tp)) if (tp->ti_client == (ClientData)CIF_PROCESSED) { tp->ti_client = (ClientData)CIF_IGNORE; STACKPUSH(tp, BoxStack); } /* Bottom */ for (tp = LB(t); LEFT(tp) < RIGHT(t); tp = TR(tp)) if (tp->ti_client == (ClientData)CIF_PROCESSED) { tp->ti_client = (ClientData)CIF_IGNORE; STACKPUSH(tp, BoxStack); } /* Right */ for (tp = TR(t); TOP(tp) > BOTTOM(t); tp = LB(tp)) if (tp->ti_client == (ClientData)CIF_PROCESSED) { tp->ti_client = (ClientData)CIF_IGNORE; STACKPUSH(tp, BoxStack); } } } /* Clear all the tiles that were processed */ DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect, &CIFSolidBits, cifSquaresResetFunc, (ClientData)NULL); } /* * ---------------------------------------------------------------------------- * * cifSquaresFillArea -- * * Fill areas in the current CIF output plane with contact cuts based on * the SQUARES operation passed in "op". This differs from the original * tile-based contact cut generation by collecting all connected tiles * in an area, and placing cuts relative to that area's bounding box. * A tile search is used to select the parts of any non-rectangular area * inside the bounding box that allow contact cuts, which lets cuts * be placed across tile boundaries and inside non-manhattan tiles. * It also allows contacts to be placed inside complex structures such * as (possibly intersecting) guardrings. * * Results: * None. * * Side effects: * * ---------------------------------------------------------------------------- */ void cifSquaresFillArea(op, cellDef, plane) CIFOp *op; CellDef *cellDef; Plane *plane; { Tile *tile, *t, *tp; Rect bbox, area, square, cut, llcut; int nAcross, nUp, left, pitch, size, diff, right; int i, j, k, savecount; TileType type; SquaresData *squares = (SquaresData *)op->co_client; StripsData stripsData; linkedStrip *stripList; bool simple; static Stack *CutStack = (Stack *)NULL; pitch = squares->sq_size + squares->sq_sep; size = squares->sq_size + 2 * squares->sq_border; diff = squares->sq_sep - 2 * squares->sq_border; if (CutStack == (Stack *)NULL) CutStack = StackNew(64); /* Two-pass algorithm */ /* Search the plane for "strips", sections of contact that are only */ /* wide enough for 1 cut. Process them separately, then erase the */ /* processed areas. The purpose of this is to avoid applying the */ /* contact matrix algorithm on non-convex spaces, such as guard */ /* rings, where centering the matrix on the bounding box of the */ /* contact area may produce a matrix misaligned with the contact */ /* strips, preventing any contacts from being drawn! Due to the */ /* maximum horizontal stripes rule for corner stitched tiles, we */ /* need only identify vertical contact strips. After processing */ /* and erasing them, all remaining areas will be convex. This */ /* algorithm allows contacts to be drawn in any arbitrary geometry. */ stripsData.size = size; stripsData.pitch = pitch; stripsData.strips = NULL; DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect, &CIFSolidBits, cifSquaresStripFunc, (ClientData)&stripsData); /* Generate cuts in each strip found, then erase the strip */ stripList = stripsData.strips; while (stripList != NULL) { Rect stripLess = stripList->area; if (diff > 0) { if (stripList->vertical) { if (stripList->shrink_ur) stripLess.r_ytop -= diff; if (stripList->shrink_ld) stripLess.r_ybot += diff; } else { if (stripList->shrink_ur) stripLess.r_xtop -= diff; if (stripList->shrink_ld) stripLess.r_xbot += diff; } } /* Create the cuts */ if (op->co_opcode == CIFOP_SQUARES) cifSquareFunc(&stripLess, op, &nUp, &nAcross, &llcut); else if (op->co_opcode == CIFOP_SQUARES_G) cifSquareGridFunc(&stripLess, op, &nUp, &nAcross, &llcut); cut.r_ybot = llcut.r_ybot; cut.r_ytop = llcut.r_ytop; for (i = 0; i < nUp; i++) { cut.r_xbot = llcut.r_xbot; cut.r_xtop = llcut.r_xtop; for (j = 0; j < nAcross; j++) { DBPaintPlane(cifPlane, &cut, CIFPaintTable, (PaintUndoInfo *)NULL); cut.r_xbot += pitch; cut.r_xtop += pitch; } cut.r_ybot += pitch; cut.r_ytop += pitch; } if (nUp == 0) { if (stripList->shrink_ur == 0 && stripList->shrink_ld == 0) { /* The following code is backwardly-compatible with the */ /* original behavior of allowing cuts that do not have */ /* sufficient border. Here, we restrict that to contact */ /* areas exactly matching the cut size. There should be */ /* a flag to allow contacts to be generated this way. */ if ((stripList->area.r_xtop - stripList->area.r_xbot == squares->sq_size) && (stripList->area.r_ytop - stripList->area.r_ybot == squares->sq_size)) { DBPaintPlane(cifPlane, &stripList->area, CIFPaintTable, (PaintUndoInfo *)NULL); CIFTileOps++; } else CIFError(&stripList->area, "no room for contact cuts in area!"); } /* Ad hoc rule catches problems due to contact areas of the proper */ /* size not fitting cuts because the grid offset prohibits it. */ else if (((stripList->area.r_ur.p_x - stripList->area.r_ll.p_x) * (stripList->area.r_ur.p_y - stripList->area.r_ll.p_y)) > 2 * (pitch * pitch)) CIFError(&stripList->area, "contact strip with no room for cuts!"); } DBPaintPlane(plane, &stripList->area, CIFEraseTable, (PaintUndoInfo *) NULL); freeMagic(stripList); stripList = stripList->strip_next; } /* 2nd pass: Search the plane for unmarked tiles */ while (DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect, &CIFSolidBits, cifSquaresInitFunc, (ClientData)NULL) != 0) { /* Now, search for (nontrivially) connected tiles in all */ /* directions. Mark the tiles, and record the bounding box. */ /* (Largely copied from cifBloatAllFunc) */ simple = TRUE; tile = plane->pl_hint; TiToRect(tile, &bbox); PUSHTILE(tile, CutStack); while (!StackEmpty(CutStack)) { t = (Tile *) STACKPOP(CutStack); if (t->ti_client != (ClientData)CIF_PENDING) continue; t->ti_client = (ClientData)CIF_PROCESSED; /* Adjust bounding box */ TiToRect(t, &area); GeoInclude(&area, &bbox); if (IsSplit(t)) simple = FALSE; /* Top */ for (tp = RT(t); RIGHT(tp) > LEFT(t); tp = BL(tp)) if (TTMaskHasType(&CIFSolidBits, TiGetBottomType(tp))) { simple = FALSE; PUSHTILE(tp, CutStack); } /* Left */ for (tp = BL(t); BOTTOM(tp) < TOP(t); tp = RT(tp)) if (TTMaskHasType(&CIFSolidBits, TiGetRightType(tp))) { simple = FALSE; PUSHTILE(tp, CutStack); } /* Bottom */ for (tp = LB(t); LEFT(tp) < RIGHT(t); tp = TR(tp)) if (TTMaskHasType(&CIFSolidBits, TiGetTopType(tp))) { simple = FALSE; PUSHTILE(tp, CutStack); } /* Right */ for (tp = TR(t); TOP(tp) > BOTTOM(t); tp = LB(tp)) if (TTMaskHasType(&CIFSolidBits, TiGetLeftType(tp))) { simple = FALSE; PUSHTILE(tp, CutStack); } } savecount = CIFTileOps; for (k = 0; k < 3; k++) /* prepare for up to 3 passes */ { /* Determine the contact cut offsets from the bounding box */ if (op->co_opcode == CIFOP_SQUARES) cifSquareFunc(&bbox, op, &nUp, &nAcross, &llcut); else if (op->co_opcode == CIFOP_SQUARES_G) cifSquareGridFunc(&bbox, op, &nUp, &nAcross, &llcut); cut.r_ybot = llcut.r_ybot; cut.r_ytop = llcut.r_ytop; /* For each contact cut area, check that there is */ /* no whitespace */ for (i = 0; i < nUp; i++) { cut.r_xbot = llcut.r_xbot; cut.r_xtop = llcut.r_xtop; square.r_ybot = cut.r_ybot - squares->sq_border; square.r_ytop = cut.r_ytop + squares->sq_border; for (j = 0; j < nAcross; j++) { square.r_xbot = cut.r_xbot - squares->sq_border; square.r_xtop = cut.r_xtop + squares->sq_border; /* If there is only one simple rectangle in the */ /* area, the area is convex, so we don't have to */ /* check for unconnected regions. */ if (simple || DBSrPaintArea((Tile *)tile, plane, &square, &DBAllTypeBits, cifUnconnectFunc, (ClientData)NULL) == 0) { DBPaintPlane(cifPlane, &cut, CIFPaintTable, (PaintUndoInfo *)NULL); CIFTileOps++; } cut.r_xbot += pitch; cut.r_xtop += pitch; } cut.r_ybot += pitch; cut.r_ytop += pitch; } if (savecount != CIFTileOps) break; /* In non-Manhattan regions with beveled corners, where */ /* the bounding box has space for 2 contacts, there may not */ /* be space in the shape itself for more than one. We will */ /* attempt to shrink X, Y, and/or both to fit (up to 3 */ /* passes may be necessary). */ if (nUp == 2) { int bdiff = 1 + (bbox.r_ytop - bbox.r_ybot) - (2 * (squares->sq_size + squares->sq_border) + squares->sq_sep); if (bdiff & 0x1) bdiff++; /* bdiff must be even */ bdiff >>= 1; /* take half */ bbox.r_ytop -= bdiff; bbox.r_ybot += bdiff; } else if (nAcross == 2) { int bdiff = 1 + (bbox.r_xtop - bbox.r_xbot) - (2 * (squares->sq_size + squares->sq_border) + squares->sq_sep); if (bdiff & 0x1) bdiff++; /* bdiff must be even */ bdiff >>= 1; /* take half */ bbox.r_xtop -= bdiff; bbox.r_xbot += bdiff; } else break; } if (savecount == CIFTileOps) CIFError(&bbox, "no room for contacts in area!"); /* Clear the tiles that were processed */ tile->ti_client = (ClientData)CIF_IGNORE; STACKPUSH(tile, CutStack); while (!StackEmpty(CutStack)) { t = (Tile *) STACKPOP(CutStack); /* Top */ for (tp = RT(t); RIGHT(tp) > LEFT(t); tp = BL(tp)) if (tp->ti_client == (ClientData)CIF_PROCESSED) { tp->ti_client = (ClientData)CIF_IGNORE; STACKPUSH(tp, CutStack); } /* Left */ for (tp = BL(t); BOTTOM(tp) < TOP(t); tp = RT(tp)) if (tp->ti_client == (ClientData)CIF_PROCESSED) { tp->ti_client = (ClientData)CIF_IGNORE; STACKPUSH(tp, CutStack); } /* Bottom */ for (tp = LB(t); LEFT(tp) < RIGHT(t); tp = TR(tp)) if (tp->ti_client == (ClientData)CIF_PROCESSED) { tp->ti_client = (ClientData)CIF_IGNORE; STACKPUSH(tp, CutStack); } /* Right */ for (tp = TR(t); TOP(tp) > BOTTOM(t); tp = LB(tp)) if (tp->ti_client == (ClientData)CIF_PROCESSED) { tp->ti_client = (ClientData)CIF_IGNORE; STACKPUSH(tp, CutStack); } } } /* Clear all the tiles that were processed */ DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect, &CIFSolidBits, cifSquaresResetFunc, (ClientData)NULL); } /* * ---------------------------------------------------------------------------- * * cifSlotsFillArea -- * * Fill areas in the current CIF output plane with contact cuts based on * the SLOTS operation passed in "op". This routine is like * cifSquaresFillArea but handles X and Y dimensions independently. * * Results: * None. * * Side effects: * * ---------------------------------------------------------------------------- */ void cifSlotsFillArea(op, cellDef, plane) CIFOp *op; CellDef *cellDef; Plane *plane; { Tile *tile, *t, *tp; Rect bbox, area, square, cut, llcut; int nAcross, nUp, left, spitch, lpitch, ssize, lsize; int diff, right; int xpitch, ypitch, xborder, yborder, xdiff, ydiff; int i, j, k, savecount; TileType type; SlotsData *slots = (SlotsData *)op->co_client; StripsData stripsData; linkedStrip *stripList; bool simple, vertical; static Stack *CutStack = (Stack *)NULL; spitch = slots->sl_ssize + slots->sl_ssep; lpitch = slots->sl_lsize + slots->sl_lsep; ssize = slots->sl_ssize + 2 * slots->sl_sborder; lsize = slots->sl_lsize + 2 * slots->sl_lborder; /* This may not be good in all cases! Amount to shorten a strip */ /* depends on the orientation of the cuts on either side of the */ /* connected strip edge. . . */ diff = slots->sl_lsep - slots->sl_lborder - slots->sl_sborder; if (CutStack == (Stack *)NULL) CutStack = StackNew(64); /* Two-pass algorithm */ /* Search the plane for "strips", sections of contact that are only */ /* wide enough for 1 cut. Process them separately, then erase the */ /* processed areas. The purpose of this is to avoid applying the */ /* contact matrix algorithm on non-convex spaces, such as guard */ /* rings, where centering the matrix on the bounding box of the */ /* contact area may produce a matrix misaligned with the contact */ /* strips, preventing any contacts from being drawn! Due to the */ /* maximum horizontal stripes rule for corner stitched tiles, we */ /* need only identify vertical contact strips. After processing */ /* and erasing them, all remaining areas will be convex. This */ /* algorithm allows contacts to be drawn in any arbitrary geometry. */ stripsData.size = ssize; stripsData.pitch = spitch; stripsData.strips = NULL; DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect, &CIFSolidBits, cifSquaresStripFunc, (ClientData)&stripsData); /* Generate cuts in each strip found, then erase the strip */ stripList = stripsData.strips; while (stripList != NULL) { Rect stripLess = stripList->area; if (diff > 0) { if (stripList->vertical) { if (stripList->shrink_ur) stripLess.r_ytop -= diff; if (stripList->shrink_ld) stripLess.r_ybot += diff; } else { if (stripList->shrink_ur) stripLess.r_xtop -= diff; if (stripList->shrink_ld) stripLess.r_xbot += diff; } } /* Create the cuts */ cifSlotFunc(&stripLess, op, &nUp, &nAcross, &llcut, stripList->vertical); cut = llcut; if (stripList->vertical) { for (i = 0; i < nUp; i++) { DBPaintPlane(cifPlane, &cut, CIFPaintTable, (PaintUndoInfo *)NULL); cut.r_ybot += lpitch; cut.r_ytop += lpitch; } } else { for (i = 0; i < nAcross; i++) { DBPaintPlane(cifPlane, &cut, CIFPaintTable, (PaintUndoInfo *)NULL); cut.r_xbot += lpitch; cut.r_xtop += lpitch; } } if (nUp == 0 || nAcross == 0) { if (stripList->shrink_ur == 0 && stripList->shrink_ld == 0) { /* The following code is backwardly-compatible with the */ /* original behavior of allowing cuts that do not have */ /* sufficient border. Here, we restrict that to contact */ /* areas exactly matching the cut size. There should be */ /* a flag to allow contacts to be generated this way. */ if (((stripList->area.r_xtop - stripList->area.r_xbot == slots->sl_ssize) && (stripList->area.r_ytop - stripList->area.r_ybot == slots->sl_lsize)) || ((stripList->area.r_xtop - stripList->area.r_xbot == slots->sl_lsize) && (stripList->area.r_ytop - stripList->area.r_ybot == slots->sl_ssize))) { DBPaintPlane(cifPlane, &stripList->area, CIFPaintTable, (PaintUndoInfo *)NULL); CIFTileOps++; } else CIFError(&stripList->area, "no room for contact cuts in area!"); } /* Ad hoc rule catches problems due to contact areas of the proper */ /* size not fitting cuts because the grid offset prohibits it. */ else if (((stripList->area.r_ur.p_x - stripList->area.r_ll.p_x) * (stripList->area.r_ur.p_y - stripList->area.r_ll.p_y)) > 2 * (lpitch * spitch)) CIFError(&stripList->area, "contact strip with no room for cuts!"); } DBPaintPlane(plane, &stripList->area, CIFEraseTable, (PaintUndoInfo *) NULL); freeMagic(stripList); stripList = stripList->strip_next; } /* 2nd pass: Search the plane for unmarked tiles */ while (DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect, &CIFSolidBits, cifSquaresInitFunc, (ClientData)NULL) != 0) { /* Now, search for (nontrivially) connected tiles in all */ /* directions. Mark the tiles, and record the bounding box. */ /* (Largely copied from cifBloatAllFunc) */ simple = TRUE; tile = plane->pl_hint; TiToRect(tile, &bbox); PUSHTILE(tile, CutStack); while (!StackEmpty(CutStack)) { t = (Tile *) STACKPOP(CutStack); if (t->ti_client != (ClientData)CIF_PENDING) continue; t->ti_client = (ClientData)CIF_PROCESSED; /* Adjust bounding box */ TiToRect(t, &area); GeoInclude(&area, &bbox); if (IsSplit(t)) simple = FALSE; /* Top */ for (tp = RT(t); RIGHT(tp) > LEFT(t); tp = BL(tp)) if (TTMaskHasType(&CIFSolidBits, TiGetBottomType(tp))) { simple = FALSE; PUSHTILE(tp, CutStack); } /* Left */ for (tp = BL(t); BOTTOM(tp) < TOP(t); tp = RT(tp)) if (TTMaskHasType(&CIFSolidBits, TiGetRightType(tp))) { simple = FALSE; PUSHTILE(tp, CutStack); } /* Bottom */ for (tp = LB(t); LEFT(tp) < RIGHT(t); tp = TR(tp)) if (TTMaskHasType(&CIFSolidBits, TiGetTopType(tp))) { simple = FALSE; PUSHTILE(tp, CutStack); } /* Right */ for (tp = TR(t); TOP(tp) > BOTTOM(t); tp = LB(tp)) if (TTMaskHasType(&CIFSolidBits, TiGetLeftType(tp))) { simple = FALSE; PUSHTILE(tp, CutStack); } } /* May want to attempt a second pass with the orthogonal alignment? */ if ((bbox.r_xtop - bbox.r_xbot) > (bbox.r_ytop - bbox.r_ybot)) vertical = FALSE; else vertical = TRUE; if (vertical) { xpitch = spitch; ypitch = lpitch; xborder = slots->sl_sborder; yborder = slots->sl_lborder; xdiff = 2 * (slots->sl_ssize + slots->sl_sborder) + slots->sl_ssep; ydiff = 2 * (slots->sl_lsize + slots->sl_lborder) + slots->sl_lsep; } else { xpitch = lpitch; ypitch = spitch; xborder = slots->sl_lborder; yborder = slots->sl_sborder; xdiff = 2 * (slots->sl_lsize + slots->sl_lborder) + slots->sl_lsep; ydiff = 2 * (slots->sl_ssize + slots->sl_sborder) + slots->sl_ssep; } savecount = CIFTileOps; for (k = 0; k < 3; k++) /* prepare for up to 3 passes */ { /* Determine the contact cut offsets from the bounding box */ cifSlotFunc(&bbox, op, &nUp, &nAcross, &llcut, vertical); cut.r_ybot = llcut.r_ybot; cut.r_ytop = llcut.r_ytop; /* For each contact cut area, check that there is */ /* no whitespace */ for (i = 0; i < nUp; i++) { cut.r_xbot = llcut.r_xbot; cut.r_xtop = llcut.r_xtop; square.r_ybot = cut.r_ybot - yborder; square.r_ytop = cut.r_ytop + yborder; for (j = 0; j < nAcross; j++) { square.r_xbot = cut.r_xbot - xborder; square.r_xtop = cut.r_xtop + xborder; /* If there is only one simple rectangle in the */ /* area, the area is convex, so we don't have to */ /* check for unconnected regions. */ if (simple || DBSrPaintArea((Tile *)tile, plane, &square, &DBAllTypeBits, cifUnconnectFunc, (ClientData)NULL) == 0) { DBPaintPlane(cifPlane, &cut, CIFPaintTable, (PaintUndoInfo *)NULL); CIFTileOps++; } cut.r_xbot += xpitch; cut.r_xtop += xpitch; } cut.r_ybot += ypitch; cut.r_ytop += ypitch; } if (savecount != CIFTileOps) break; /* In non-Manhattan regions with beveled corners, where */ /* the bounding box has space for 2 contacts, there may not */ /* be space in the shape itself for more than one. We will */ /* attempt to shrink X, Y, and/or both to fit (up to 3 */ /* passes may be necessary). */ if (nUp == 2) { int bdiff = 1 + (bbox.r_ytop - bbox.r_ybot) - ydiff; if (bdiff & 0x1) bdiff++; /* bdiff must be even */ bdiff >>= 1; /* take half */ bbox.r_ytop -= bdiff; bbox.r_ybot += bdiff; } else if (nAcross == 2) { int bdiff = 1 + (bbox.r_xtop - bbox.r_xbot) - xdiff; if (bdiff & 0x1) bdiff++; /* bdiff must be even */ bdiff >>= 1; /* take half */ bbox.r_xtop -= bdiff; bbox.r_xbot += bdiff; } else break; } if (savecount == CIFTileOps) CIFError(&bbox, "no room for contacts in area!"); /* Clear the tiles that were processed */ tile->ti_client = (ClientData)CIF_IGNORE; STACKPUSH(tile, CutStack); while (!StackEmpty(CutStack)) { t = (Tile *) STACKPOP(CutStack); /* Top */ for (tp = RT(t); RIGHT(tp) > LEFT(t); tp = BL(tp)) if (tp->ti_client == (ClientData)CIF_PROCESSED) { tp->ti_client = (ClientData)CIF_IGNORE; STACKPUSH(tp, CutStack); } /* Left */ for (tp = BL(t); BOTTOM(tp) < TOP(t); tp = RT(tp)) if (tp->ti_client == (ClientData)CIF_PROCESSED) { tp->ti_client = (ClientData)CIF_IGNORE; STACKPUSH(tp, CutStack); } /* Bottom */ for (tp = LB(t); LEFT(tp) < RIGHT(t); tp = TR(tp)) if (tp->ti_client == (ClientData)CIF_PROCESSED) { tp->ti_client = (ClientData)CIF_IGNORE; STACKPUSH(tp, CutStack); } /* Right */ for (tp = TR(t); TOP(tp) > BOTTOM(t); tp = LB(tp)) if (tp->ti_client == (ClientData)CIF_PROCESSED) { tp->ti_client = (ClientData)CIF_IGNORE; STACKPUSH(tp, CutStack); } } } /* Clear all the tiles that were processed */ DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect, &CIFSolidBits, cifSquaresResetFunc, (ClientData)NULL); } /* * ---------------------------------------------------------------------------- * * cifBloatMaxFunc -- * * Called once for each tile to be selectively bloated or * shrunk using the CIFOP_BLOATMAX or CIFOP_BLOATMIN operation. * * Results: * Always returns 0 to keep the search alive. * * Side effects: * Uses the bloat table in the current CIFOp to expand or shrink * the tile, depending on which tiles it abuts. The rectangular * area of the tile is modified by moving each side in or out * by the maximum bloat distance for any of its neighbors on * that side. The result is a new rectangle, which is OR'ed * into the result plane. Note: any edge between two tiles of * same type is given a zero bloat factor. * * ---------------------------------------------------------------------------- */ int cifBloatMaxFunc(tile, op) Tile *tile; /* The tile to be processed. */ CIFOp *op; /* Describes the operation to be performed * (all we care about is the opcode and * bloat table). */ { Rect area; int bloat, tmp; Tile *t; TileType type, otherType; BloatData *bloats = (BloatData *)op->co_client; /* Get the tile into CIF coordinates. */ type = TiGetType(tile); TiToRect(tile, &area); area.r_xbot *= cifScale; area.r_ybot *= cifScale; area.r_xtop *= cifScale; area.r_ytop *= cifScale; /* See how much to adjust the left side of the tile. */ if (op->co_opcode == CIFOP_BLOATMAX) bloat = -10000000; else bloat = 10000000; for (t = BL(tile); BOTTOM(t) < TOP(tile); t = RT(t)) { otherType = TiGetType(t); if (otherType == type) continue; tmp = bloats->bl_distance[otherType]; if (op->co_opcode == CIFOP_BLOATMAX) { if (tmp > bloat) bloat = tmp; } else if (tmp < bloat) bloat = tmp; } if ((bloat < 10000000) && (bloat > -10000000)) area.r_xbot -= bloat; /* Now figure out how much to adjust the top side of the tile. */ if (op->co_opcode == CIFOP_BLOATMAX) bloat = -10000000; else bloat = 10000000; for (t = RT(tile); RIGHT(t) > LEFT(tile); t = BL(t)) { otherType = TiGetType(t); if (otherType == type) continue; tmp = bloats->bl_distance[otherType]; if (op->co_opcode == CIFOP_BLOATMAX) { if (tmp > bloat) bloat = tmp; } else if (tmp < bloat) bloat = tmp; } if ((bloat < 10000000) && (bloat > -10000000)) area.r_ytop += bloat; /* Now the right side. */ if (op->co_opcode == CIFOP_BLOATMAX) bloat = -10000000; else bloat = 10000000; for (t = TR(tile); TOP(t) > BOTTOM(tile); t = LB(t)) { otherType = TiGetType(t); if (otherType == type) continue; tmp = bloats->bl_distance[otherType]; if (op->co_opcode == CIFOP_BLOATMAX) { if (tmp > bloat) bloat = tmp; } else if (tmp < bloat) bloat = tmp; } if ((bloat < 10000000) && (bloat > -10000000)) area.r_xtop += bloat; /* Lastly, do the bottom side. */ if (op->co_opcode == CIFOP_BLOATMAX) bloat = -10000000; else bloat = 10000000; for (t = LB(tile); LEFT(t) < RIGHT(tile); t = TR(t)) { otherType = TiGetType(t); if (otherType == type) continue; tmp = bloats->bl_distance[otherType]; if (op->co_opcode == CIFOP_BLOATMAX) { if (tmp > bloat) bloat = tmp; } else if (tmp < bloat) bloat = tmp; } if ((bloat < 10000000) && (bloat > -10000000)) area.r_ybot -= bloat; /* Make sure the tile didn't shrink into negativity. If it's * ok, paint it into the new plane being built. */ if ((area.r_xbot > area.r_xtop) || (area.r_ybot > area.r_ytop)) { TiToRect(tile, &area); area.r_xbot *= cifScale; area.r_xtop *= cifScale; area.r_ybot *= cifScale; area.r_ytop *= cifScale; CIFError(&area, "tile inverted by shrink"); } else DBNMPaintPlane(cifPlane, TiGetTypeExact(tile), &area, CIFPaintTable, (PaintUndoInfo *) NULL); CIFTileOps += 1; return 0; } /* * ---------------------------------------------------------------------------- * * inside_triangle -- * * Test if the specified rectangle is completely inside the tile. * Tile is presumed to be a split tile. * * Results: * TRUE if inside, FALSE if outside or overlapping. * * Side Effects: * None. * * Notes: * This is an optimized version of the code in DBtiles.c. It * assumes that the square is never infinite. * * ---------------------------------------------------------------------------- */ bool inside_triangle(rect, tile) Rect *rect; Tile *tile; { int theight, twidth; dlong f1, f2, f3, f4; theight = TOP(tile) - BOTTOM(tile); twidth = RIGHT(tile) - LEFT(tile); f1 = (dlong)(TOP(tile) - rect->r_ybot) * twidth; f2 = (dlong)(rect->r_ytop - BOTTOM(tile)) * twidth; if (SplitLeftType(tile) != TT_SPACE) { /* Inside-of-triangle check */ f4 = (dlong)(rect->r_xbot - LEFT(tile)) * theight; if (SplitDirection(tile) ? (f1 > f4) : (f2 > f4)) return TRUE; } else { /* Inside-of-triangle check */ f3 = (dlong)(RIGHT(tile) - rect->r_xtop) * theight; if (SplitDirection(tile) ? (f2 > f3) : (f1 > f3)) return TRUE; } return FALSE; } /* * ---------------------------------------------------------------------------- * * cifContactFunc -- * * Called for each relevant tile when chopping up contacts into * square cuts using the procedure of using a pre-defined cell * definition of a single contact and arraying the cell. * Technically, this is not a CIF function because CIF does not * have an array method for cells, so there is no advantage to * drawing lots of subcells in place of drawing lots of boxes. * In GDS, however, the array method is much more compact than * drawing individual cuts when the array size is larger than 1. * * Results: * Normally returns 0 to keep the search going. Return 1 if * the contact type cannot be found, which halts the search. * * Side effects: * Stuff is painted into cifPlane. * * ---------------------------------------------------------------------------- */ int cifContactFunc(tile, csi) Tile *tile; /* Tile to be diced up. */ CIFSquaresInfo *csi; /* Describes how to generate squares. */ { Rect area; int i, nAcross, j, nUp, left, bottom, pitch, halfsize; bool result; SquaresData *squares = csi->csi_squares; /* For now, don't allow squares on non-manhattan tiles */ if (IsSplit(tile)) return 0; TiToRect(tile, &area); pitch = squares->sq_size + squares->sq_sep; nAcross = (area.r_xtop - area.r_xbot + squares->sq_sep - (2 * squares->sq_border)) / pitch; if (nAcross == 0) { left = (area.r_xbot + area.r_xtop - squares->sq_size) / 2; if (left >= area.r_xbot) nAcross = 1; } else left = (area.r_xbot + area.r_xtop + squares->sq_sep - (nAcross * pitch)) / 2; nUp = (area.r_ytop - area.r_ybot + squares->sq_sep - (2 * squares->sq_border)) / pitch; if (nUp == 0) { bottom = (area.r_ybot + area.r_ytop - squares->sq_size) / 2; if (bottom >= area.r_ybot) nUp = 1; } else bottom = (area.r_ybot + area.r_ytop + squares->sq_sep - (nUp * pitch)) / 2; /* Lower-left coordinate should be centered on the contact cut, as * contact definitions are centered on the origin. */ halfsize = (squares->sq_size / 2); left += halfsize; bottom += halfsize; result = CalmaGenerateArray((FILE *)csi->csi_client, csi->csi_type, left, bottom, pitch, nAcross, nUp); return (result == TRUE) ? 0 : 1; } /* * ---------------------------------------------------------------------------- * * cifSlotFunc -- * * Called for each relevant tile area when chopping areas up into * slots (rectangles). Determines how to divide up the area into * slots, and generates the number of rows, columns, and the lower- * left-most cut rectangle. * * Results: * Always return 0 * * Side effects: * Pointers "rows", "columns", and "cut" are filled with * appropriate values. * * ---------------------------------------------------------------------------- */ int cifSlotFunc(area, op, numY, numX, cut, vertical) Rect *area; /* Area to be diced up */ CIFOp *op; /* Describes how to generate squares. */ int *numY, *numX; /* Return values: # rows and # columns */ Rect *cut; /* initial (lower left) cut area */ bool vertical; /* if TRUE, slot is aligned vertically */ { int i, j, xpitch, ypitch, delta; int *axtop, *axbot, *aytop, *aybot; int *sxtop, *sxbot, *sytop, *sybot; int *rows, *columns; SlotsData *slots = (SlotsData *)op->co_client; /* Orient to the short/long orientation of the tile */ /* Assume a vertical tile; if not, reorient area and remember */ if (vertical) { axbot = &area->r_xbot; aybot = &area->r_ybot; axtop = &area->r_xtop; aytop = &area->r_ytop; sxbot = &cut->r_xbot; sybot = &cut->r_ybot; sxtop = &cut->r_xtop; sytop = &cut->r_ytop; rows = numY; columns = numX; } else { axbot = &area->r_ybot; aybot = &area->r_xbot; axtop = &area->r_ytop; aytop = &area->r_xtop; sxbot = &cut->r_ybot; sybot = &cut->r_xbot; sxtop = &cut->r_ytop; sytop = &cut->r_xtop; rows = numX; columns = numY; } xpitch = slots->sl_ssize + slots->sl_ssep; calcX: *columns = (*axtop - *axbot + slots->sl_ssep - (2 * slots->sl_sborder)) / xpitch; if (*columns == 0) { *rows = 0; return 0; // *sxbot = (*axbot + *axtop - slots->sl_ssize) / 2; // if (*sxbot >= *axbot) *columns = 1; } else *sxbot = (*axbot + *axtop + slots->sl_ssep - (*columns * xpitch)) / 2; *sxtop = *sxbot + slots->sl_ssize; /* Check that we are not violating any gridlimit */ if (CIFCurStyle && (CIFCurStyle->cs_gridLimit > 1)) { delta = abs(*sxbot) % CIFCurStyle->cs_gridLimit; if (delta > 0) { *axtop -= 2 * delta; goto calcX; } } if (slots->sl_lsize > 0) { ypitch = slots->sl_lsize + slots->sl_lsep; calcY: *rows = (*aytop - *aybot + slots->sl_lsep - (2 * slots->sl_lborder)) / ypitch; if (*rows == 0) { return 0; // *sybot = (*aybot + *aytop - slots->sl_lsize) / 2; // if (*sybot >= *aybot) *rows = 1; } else *sybot = (*aybot + *aytop + slots->sl_lsep - (*rows * ypitch)) / 2; *sytop = *sybot + slots->sl_lsize; /* Check that we are not violating any gridlimit */ if (CIFCurStyle && (CIFCurStyle->cs_gridLimit > 1)) { delta = abs(*sybot) % CIFCurStyle->cs_gridLimit; if (delta > 0) { *aytop -= 2 * delta; goto calcY; } } } else { *rows = 1; *sybot = *aybot + slots->sl_lborder; *sytop = *aytop - slots->sl_lborder; /* There's no space to fit a slot */ if (*sytop - *sybot <= 0) return 0; } /* To be done---slot offsets */ return 0; } /* * ---------------------------------------------------------------------------- * * cifSquareFunc -- * * Called for each relevant rectangle when chopping areas up into * squares. Determines the number of rows and columns in the area * and returns these and the area of the lower-left cut. * * Results: * Always return 0 * * Side effects: * Results filled in the pointer positions passed to the function * * ---------------------------------------------------------------------------- */ int cifSquareFunc(area, op, rows, columns, cut) Rect *area; /* Area to be diced up */ CIFOp *op; /* Describes how to generate squares. */ int *rows, *columns; /* Return values: # rows and # columns, */ Rect *cut; /* initial (lower left) cut area. */ { int pitch, delta; bool glimit; SquaresData *squares = (SquaresData *)op->co_client; glimit = (CIFCurStyle && (CIFCurStyle->cs_gridLimit > 1)) ? TRUE : FALSE; pitch = squares->sq_size + squares->sq_sep; /* Compute the real border to leave around the sides. If only * one square will fit in a particular direction, center it * regardless of the requested border size. If more than one * square will fit, then fit it in extras only if at least the * requested border size can be left. Also center things in the * rectangle, so that the box's exact size doesn't matter. This * trickiness is done so that coincident contacts from overlapping * cells always have their squares line up, regardless of the * orientation of the cells. * * Update 1/13/09: Removed the "feature" that allows contact * cuts that violate the border requirement. The "slots" rule * can be used if necessary to generate cuts with different * border allowances. */ sqX: *columns = (area->r_xtop - area->r_xbot + squares->sq_sep - (2 * squares->sq_border)) / pitch; if (*columns == 0) { *rows = 0; return 0; // cut->r_xbot = (area->r_xbot + area->r_xtop - squares->sq_size) / 2; // if (cut->r_xbot >= area->r_xbot) *columns = 1; } else { cut->r_xbot = (area->r_xbot + area->r_xtop + squares->sq_sep - (*columns * pitch)) / 2; } /* Check for any gridlimit violation */ if (glimit) { delta = abs(cut->r_xbot) % CIFCurStyle->cs_gridLimit; if (delta > 0) { area->r_xtop -= 2 * delta; goto sqX; } } sqY: *rows = (area->r_ytop - area->r_ybot + squares->sq_sep - (2 * squares->sq_border)) / pitch; if (*rows == 0) { return 0; // cut->r_ybot = (area->r_ybot + area->r_ytop - squares->sq_size) / 2; // if (cut->r_ybot >= area->r_ybot) *rows = 1; } else { cut->r_ybot = (area->r_ybot + area->r_ytop + squares->sq_sep - (*rows * pitch)) / 2; } /* Check for any gridlimit violation */ if (glimit) { delta = abs(cut->r_ybot) % CIFCurStyle->cs_gridLimit; if (delta > 0) { area->r_ytop -= 2 * delta; goto sqY; } } cut->r_xtop = cut->r_xbot + squares->sq_size; cut->r_ytop = cut->r_ybot + squares->sq_size; return 0; } /* * ---------------------------------------------------------------------------- * * cifSquareGridFunc -- * * Called for each relevant rectangle when chopping areas up into * squares. Determines the number of rows and columns in the area * and returns these and the area of the lower-left cut. * * Results: * Always return 0 * * Side effects: * Results filled in the pointer positions passed to the function * * ---------------------------------------------------------------------------- */ int cifSquareGridFunc(area, op, rows, columns, cut) Rect *area; /* Area to be diced up */ CIFOp *op; /* Describes how to generate squares. */ int *rows, *columns; /* Return values: # rows and # columns, */ Rect *cut; /* initial (lower left) cut area. */ { Rect locarea; int left, bottom, right, top, pitch; int gridx, gridy, margin; SquaresData *squares = (SquaresData *)op->co_client; /* * It may be necessary to generate contacts on a specific grid; e.g., * to avoid placing contacts at half-lambda. If this is the case, * then the DRC section of the techfile should specify "no overlap" * for these types. * * This routine has been simplified. It flags a warning when there * is not enough space for a contact cut, rather than attempting to * draw a cut without enough border area. The routine has also been * extended to allow different x and y grids to be specified. This * allows certain tricks, such as generating offset contact grids on * a pad, as required by some processes. */ pitch = squares->sq_size + squares->sq_sep; gridx = squares->sq_gridx; gridy = squares->sq_gridy; locarea.r_xtop = area->r_xtop - squares->sq_border; locarea.r_ytop = area->r_ytop - squares->sq_border; locarea.r_xbot = area->r_xbot + squares->sq_border; locarea.r_ybot = area->r_ybot + squares->sq_border; left = locarea.r_xbot / gridx; left *= gridx; if (left < locarea.r_xbot) left += gridx; bottom = locarea.r_ybot / gridy; bottom *= gridy; if (bottom < locarea.r_ybot) bottom += gridy; *columns = (locarea.r_xtop - left + squares->sq_sep) / pitch; if (*columns == 0) { *rows = 0; return 0; } *rows = (locarea.r_ytop - bottom + squares->sq_sep) / pitch; if (*rows == 0) return 0; /* Center the contacts while remaining on-grid */ right = left + *columns * squares->sq_size + (*columns - 1) * squares->sq_sep; top = bottom + *rows * squares->sq_size + (*rows - 1) * squares->sq_sep; margin = ((locarea.r_xtop - right) - (left - locarea.r_xbot)) / (gridx * 2); locarea.r_xbot = left + margin * gridx; margin = ((locarea.r_ytop - top) - (bottom - locarea.r_ybot)) / (gridy * 2); locarea.r_ybot = bottom + margin * gridy; cut->r_ybot = locarea.r_ybot; cut->r_ytop = cut->r_ybot + squares->sq_size; cut->r_xbot = locarea.r_xbot; cut->r_xtop = cut->r_xbot + squares->sq_size; return 0; } /* * ---------------------------------------------------------------------------- * * cifSrTiles -- * * This is a utility procedure that just calls DBSrPaintArea * one or more times for the planes being used in processing * one CIFOp. * * Results: * None. * * Side effects: * This procedure itself has no side effects. For each of the * paint or temporary planes indicated in cifOp, we call * DBSrPaintArea to find the desired tiles in the desired * area for the operation. DBSrPaintArea is given func as a * search function, and cdArg as ClientData. * * ---------------------------------------------------------------------------- */ void cifSrTiles(cifOp, area, cellDef, temps, func, cdArg) CIFOp *cifOp; /* Geometric operation being processed. */ Rect *area; /* Area of Magic paint to consider. */ CellDef *cellDef; /* CellDef to search for paint. */ Plane *temps[]; /* Planes to use for temporaries. */ int (*func)(); /* Search function to pass to DBSrPaintArea. */ ClientData cdArg; /* Client data for func. */ { TileTypeBitMask maskBits; TileType t; int i; BloatData *bloats; /* When reading data from a cell, it must first be scaled to * CIF units. Check for CIFCurStyle, as we don't want to * crash while reading CIF/GDS just becuase the techfile * "cifoutput" section was blank. */ cifScale = (CIFCurStyle) ? CIFCurStyle->cs_scaleFactor : 1; /* Bloat operations have to be in a single plane */ switch (cifOp->co_opcode) { case CIFOP_BLOAT: case CIFOP_BLOATMIN: case CIFOP_BLOATMAX: bloats = (BloatData *)cifOp->co_client; i = bloats->bl_plane; maskBits = DBPlaneTypes[i]; TTMaskAndMask(&maskBits, &cifOp->co_paintMask); if (!TTMaskEqual(&maskBits, &DBZeroTypeBits)) DBSrPaintArea((Tile *) NULL, cellDef->cd_planes[i], area, &cifOp->co_paintMask, func, cdArg); break; default: for (i = PL_DRC_CHECK; i < DBNumPlanes; i++) { maskBits = DBPlaneTypes[i]; TTMaskAndMask(&maskBits, &cifOp->co_paintMask); if (!TTMaskEqual(&maskBits, &DBZeroTypeBits)) (void) DBSrPaintArea((Tile *) NULL, cellDef->cd_planes[i], area, &cifOp->co_paintMask, func, cdArg); } break; } /* When processing CIF data, use everything in the plane. */ cifScale = 1; for (t = 0; t < TT_MAXTYPES; t++, temps++) if (TTMaskHasType(&cifOp->co_cifMask, t)) (void) DBSrPaintArea((Tile *) NULL, *temps, &TiPlaneRect, &CIFSolidBits, func, (ClientData) cdArg); } /* * ---------------------------------------------------------------------------- * * CIFGenLayer -- * * This routine will generate one CIF layer. * It provides the core of the CIF generator. * * Results: * Returns a malloc'ed plane with tiles of type CIF_SOLIDTYPE * marking the area of this CIF layer as built up by op. * * Side effects: * None, except to create a new plane holding the CIF for the layer. * The CIF that's generated may fall outside of area... it's what * results from considering everything in area. In most cases the * caller will clip the results down to the desired area. * * ---------------------------------------------------------------------------- */ Plane * CIFGenLayer(op, area, cellDef, temps, clientdata) CIFOp *op; /* List of CIFOps telling how to make layer. */ Rect *area; /* Area to consider when generating CIF. Only * material in this area will be considered, so * the caller should usually expand his desired * area by one CIF radius. */ CellDef *cellDef; /* CellDef to search when paint layers are * needed for operation. */ Plane *temps[]; /* Temporary layers to be used when needed * for operation. */ ClientData clientdata; /* * Data that may be passed to the CIF operation * function. */ { Plane *temp; static Plane *nextPlane, *curPlane; Rect bbox; CIFOp *tempOp; CIFSquaresInfo csi; SearchContext scx; TileType ttype; char *netname; int (*cifGrowFuncPtr)() = (CIFCurStyle->cs_flags & CWF_GROW_EUCLIDEAN) ? cifGrowEuclideanFunc : cifGrowFunc; /* Set up temporary planes used during computation. One of these * will be returned as the result (whichever is curPlane at the * end of the computation). The other is saved for later use. */ if (nextPlane == NULL) nextPlane = DBNewPlane((ClientData) TT_SPACE); curPlane = DBNewPlane((ClientData) TT_SPACE); /* Go through the geometric operations and process them one * at a time. */ for ( ; op != NULL; op = op->co_next) { switch (op->co_opcode) { /* For AND, first collect all the stuff to be anded with * plane in a temporary plane. Then find all the places * where there isn't any stuff, and erase from the * current plane. */ case CIFOP_AND: DBClearPaintPlane(nextPlane); cifPlane = nextPlane; cifSrTiles(op, area, cellDef, temps, cifPaintFunc, (ClientData) CIFPaintTable); cifPlane = curPlane; cifScale = 1; (void) DBSrPaintArea((Tile *) NULL, nextPlane, &TiPlaneRect, &DBSpaceBits, cifPaintFunc, (ClientData) CIFEraseTable); break; /* For OR, just use cifPaintFunc to OR the areas of all * relevant tiles into plane. HOWEVER, if the co_client * record is non-NULL and CalmaContactArrays is TRUE, * then for each contact type, we do the paint function * separately, then call the contact array generation * procedure. */ case CIFOP_OR: cifPlane = curPlane; cifScale = (CIFCurStyle) ? CIFCurStyle->cs_scaleFactor : 1; if ((op->co_client != (ClientData)NULL) && (CalmaContactArrays == TRUE)) { TileTypeBitMask paintMask, errMask, *rMask; TileType i, j; TTMaskZero(&errMask); TTMaskZero(&paintMask); TTMaskSetMask(&paintMask, &op->co_paintMask); for (i = TT_TECHDEPBASE; i < DBNumUserLayers; i++) { if (TTMaskHasType(&paintMask, i)) { TTMaskSetOnlyType(&op->co_paintMask, i); for (j = DBNumUserLayers; j < DBNumTypes; j++) { rMask = DBResidueMask(j); if (TTMaskHasType(rMask, i)) TTMaskSetType(&op->co_paintMask, j); } cifSrTiles(op, area, cellDef, temps, cifPaintFunc, (ClientData) CIFPaintTable); csi.csi_squares = (SquaresData *)op->co_client; csi.csi_type = i; csi.csi_client = clientdata; if (DBSrPaintArea((Tile *) NULL, curPlane, &TiPlaneRect, &CIFSolidBits, cifContactFunc, (ClientData) &csi)) { /* Failure of DBSrPaintArea() (returns 1) * indicates that a contact cell type * could not be found for magic layer i. * Record the error for subsequent handling. */ TTMaskSetType(&errMask, i); } DBClearPaintPlane(curPlane); } } if (!TTMaskIsZero(&errMask)) { /* * Handle layers for which a contact cell could * not be found in the default manner. */ TTMaskZero(&op->co_paintMask); TTMaskSetMask(&op->co_paintMask, &errMask); cifSrTiles(op, area, cellDef, temps, cifPaintFunc, (ClientData) CIFPaintTable); } /* Recover the original magic layer mask for the cifop */ TTMaskZero(&op->co_paintMask); TTMaskSetMask(&op->co_paintMask, &paintMask); } else { cifSrTiles(op, area, cellDef, temps, cifPaintFunc, (ClientData) CIFPaintTable); } break; /* For ANDNOT, do exactly the same thing as OR, except erase * instead of paint. */ case CIFOP_ANDNOT: cifPlane = curPlane; cifSrTiles(op, area, cellDef, temps, cifPaintFunc, (ClientData) CIFEraseTable); break; /* For GROW, just find all solid tiles in the current plane, * and paint a larger version into a new plane. The switch * the current and new planes. */ case CIFOP_GROW: growDistance = op->co_distance; DBClearPaintPlane(nextPlane); cifPlane = nextPlane; cifScale = 1; (void) DBSrPaintArea((Tile *) NULL, curPlane, &TiPlaneRect, &CIFSolidBits, *cifGrowFuncPtr, (ClientData) CIFPaintTable); temp = curPlane; curPlane = nextPlane; nextPlane = temp; break; /* GROW_G grows non-uniformly to the indicated grid. */ case CIFOP_GROW_G: growDistance = op->co_distance; DBClearPaintPlane(nextPlane); cifPlane = nextPlane; cifScale = 1; (void) DBSrPaintArea((Tile *) NULL, curPlane, &TiPlaneRect, &CIFSolidBits, cifGrowGridFunc, (ClientData) CIFPaintTable); temp = curPlane; curPlane = nextPlane; nextPlane = temp; break; /* SHRINK is just like grow except work from the space tiles. */ case CIFOP_SHRINK: growDistance = op->co_distance; DBClearPaintPlane(nextPlane); DBPaintPlane(nextPlane, &TiPlaneRect, CIFPaintTable, (PaintUndoInfo *) NULL); cifPlane = nextPlane; cifScale = 1; (void) DBSrPaintArea((Tile *) NULL, curPlane, &TiPlaneRect, &DBSpaceBits, *cifGrowFuncPtr, (ClientData) CIFEraseTable); temp = curPlane; curPlane = nextPlane; nextPlane = temp; break; case CIFOP_BLOAT: cifPlane = curPlane; cifSrTiles(op, area, cellDef, temps, cifBloatFunc, op->co_client); break; case CIFOP_BLOATMAX: case CIFOP_BLOATMIN: cifPlane = curPlane; cifSrTiles(op, area, cellDef, temps, cifBloatMaxFunc, (ClientData) op); break; case CIFOP_BLOATALL: cifPlane = curPlane; cifSrTiles(op, area, cellDef, temps, cifBloatAllFunc, (ClientData) op); break; case CIFOP_SQUARES: if (CalmaContactArrays == FALSE) { DBClearPaintPlane(nextPlane); cifPlane = nextPlane; cifSquaresFillArea(op, cellDef, curPlane); temp = curPlane; curPlane = nextPlane; nextPlane = temp; } break; case CIFOP_SQUARES_G: DBClearPaintPlane(nextPlane); cifPlane = nextPlane; cifSquaresFillArea(op, cellDef, curPlane); temp = curPlane; curPlane = nextPlane; nextPlane = temp; break; case CIFOP_SLOTS: DBClearPaintPlane(nextPlane); cifPlane = nextPlane; cifSlotsFillArea(op, cellDef, curPlane); temp = curPlane; curPlane = nextPlane; nextPlane = temp; break; case CIFOP_MAXRECT: cifPlane = curPlane; DBClearPaintPlane(nextPlane); cifPlane = nextPlane; cifRectBoundingBox(op, cellDef, curPlane); temp = curPlane; curPlane = nextPlane; nextPlane = temp; break; case CIFOP_NET: netname = (char *)op->co_client; cifPlane = curPlane; ttype = CmdFindNetProc(netname, CIFDummyUse, &bbox, FALSE); if (ttype != TT_SPACE) { UndoDisable(); DBCellClearDef(Select2Def); scx.scx_area = bbox; scx.scx_use = CIFDummyUse; scx.scx_trans = GeoIdentityTransform; DBTreeCopyConnect(&scx, &DBConnectTbl[ttype], 0, DBConnectTbl, &TiPlaneRect, Select2Use); cifSrTiles(op, area, Select2Def, temps, cifPaintFunc, (ClientData) CIFPaintTable); DBCellClearDef(Select2Def); UndoEnable(); } break; case CIFOP_BBOX: if (CIFErrorDef == NULL) break; /* co_client contains the flag (1) for top-level only */ if ((int)op->co_client == 1) { /* Only generate output for the top-level cell */ int found = 0; CellUse *celluse; for (celluse = CIFErrorDef->cd_parents; celluse != (CellUse *) NULL; celluse = celluse->cu_nextuse) { if (celluse->cu_parent != (CellDef *) NULL) if ((celluse->cu_parent->cd_flags & CDINTERNAL) != CDINTERNAL) { found = 1; break; } } if (found != 0) break; } cifPlane = curPlane; bbox = CIFErrorDef->cd_bbox; cifScale = (CIFCurStyle) ? CIFCurStyle->cs_scaleFactor : 1; bbox.r_xbot *= cifScale; bbox.r_xtop *= cifScale; bbox.r_ybot *= cifScale; bbox.r_ytop *= cifScale; DBNMPaintPlane(curPlane, CIF_SOLIDTYPE, &bbox, CIFPaintTable, (PaintUndoInfo *)NULL); break; default: continue; } } return curPlane; } /* * ---------------------------------------------------------------------------- * * CIFGen -- * * This procedure generates a complete set of CIF layers for * a particular area of a particular cell. NOTE: if the argument * genAllPlanes is FALSE, only planes for those layers having * a bit set in 'layers' are generated; the others are set * to NULL. * * Results: * None. * * Side effects: * The parameters realPlanes and tempPlanes are modified * to hold the CIF and temporary layers for area of cellDef, * as determined by the current CIF generation rules. * * ---------------------------------------------------------------------------- */ void CIFGen(cellDef, area, planes, layers, replace, genAllPlanes, clientdata) CellDef *cellDef; /* Cell for which CIF is to be generated. */ Rect *area; /* Any CIF overlapping this area (in coords * of cellDef) will be generated. The CIF * will be clipped to this area. */ Plane **planes; /* Pointer to array of pointers to planes * to hold "real" CIF layers that are * generated. Pointers may initially be * NULL. */ TileTypeBitMask *layers; /* CIF layers to generate. */ bool replace; /* TRUE means that the new CIF is to replace * anything that was previously in planes. * FALSE means that the new CIF is to be * OR'ed in with the current contents of * planes. */ bool genAllPlanes; /* If TRUE, generate a tile plane even for * those layers not specified as being * generated in the 'layers' mask above. */ ClientData clientdata; /* Data that may be passed along to the * CIF operation functions. */ { int i; Plane *new[MAXCIFLAYERS]; Rect expanded, clip; /* * Generate the area in magic coordinates to search, and the area in * cif coordinates to use in clipping the results of CIFGenLayer(). */ cifGenClip(area, &expanded, &clip); /* * Generate all of the new layers in a temporary place. * If a layer isn't being generated, leave new[i] set to * NULL to indicate this fact. */ for (i = 0; i < CIFCurStyle->cs_nLayers; i++) { if (TTMaskHasType(layers,i)) { CIFErrorLayer = i; new[i] = CIFGenLayer(CIFCurStyle->cs_layers[i]->cl_ops, &expanded, cellDef, new, clientdata); /* Clean up the non-manhattan geometry in the plane */ if (CIFUnfracture) DBMergeNMTiles(new[i], &expanded, (PaintUndoInfo *)NULL); } else if (genAllPlanes) new[i] = DBNewPlane((ClientData) TT_SPACE); else new[i] = (Plane *) NULL; } /* * Now mask off all the unwanted material in the new layers, and * either OR them into the existing layers or replace the existing * material with them. */ for (i = 0; i < CIFCurStyle->cs_nLayers; i += 1) { if (new[i]) cifClipPlane(new[i], &clip); if (replace) { if (planes[i]) { DBFreePaintPlane(planes[i]); TiFreePlane(planes[i]); } planes[i] = new[i]; continue; } if (planes[i]) { if (new[i]) { cifPlane = planes[i]; cifScale = 1; (void) DBSrPaintArea((Tile *) NULL, new[i], &TiPlaneRect, &CIFSolidBits, cifPaintFunc, (ClientData) CIFPaintTable); DBFreePaintPlane(new[i]); TiFreePlane(new[i]); } } else planes[i] = new[i]; } } /* * ---------------------------------------------------------------------------- * * cifClipPlane -- * * Erase the portions of the plane 'plane' that lie outside of 'clip'. * * Results: * None. * * Side effects: * See above. * * ---------------------------------------------------------------------------- */ void cifClipPlane(plane, clip) Plane *plane; Rect *clip; { Rect r; if (clip->r_xtop < TiPlaneRect.r_xtop) { r = TiPlaneRect; r.r_xbot = clip->r_xtop; DBPaintPlane(plane, &r, CIFEraseTable, (PaintUndoInfo *) NULL); } if (clip->r_ytop < TiPlaneRect.r_ytop) { r = TiPlaneRect; r.r_ybot = clip->r_ytop; DBPaintPlane(plane, &r, CIFEraseTable, (PaintUndoInfo *) NULL); } if (clip->r_xbot > TiPlaneRect.r_xbot) { r = TiPlaneRect; r.r_xtop = clip->r_xbot; DBPaintPlane(plane, &r, CIFEraseTable, (PaintUndoInfo *) NULL); } if (clip->r_ybot > TiPlaneRect.r_ybot) { r = TiPlaneRect; r.r_ytop = clip->r_ybot; DBPaintPlane(plane, &r, CIFEraseTable, (PaintUndoInfo *) NULL); } } /* * ---------------------------------------------------------------------------- * * cifGenClip -- * * Compute two new areas from the original area: one ('expanded') * is expanded by a CIF halo and is used to determine how much of * the database to search to find what's relevant for CIF generation; * the other ('clip') is the CIF equivalent of area and is used to * clip the resulting CIF. This code is tricky because area may run * off to infinity, and we have to be careful not to expand past infinity. * * Results: * None. * * Side effects: * Sets *expanded and *clip. * * ---------------------------------------------------------------------------- */ void cifGenClip(area, expanded, clip) Rect *area; /* Any CIF overlapping this area (in coords * of cellDef) will be generated. The CIF * will be clipped to this area. */ Rect *expanded, *clip; { if (area->r_xbot > TiPlaneRect.r_xbot) { clip->r_xbot = area->r_xbot * CIFCurStyle->cs_scaleFactor; expanded->r_xbot = area->r_xbot - CIFCurStyle->cs_radius; } else clip->r_xbot = expanded->r_xbot = area->r_xbot; if (area->r_ybot > TiPlaneRect.r_ybot) { clip->r_ybot = area->r_ybot * CIFCurStyle->cs_scaleFactor; expanded->r_ybot = area->r_ybot - CIFCurStyle->cs_radius; } else clip->r_ybot = expanded->r_ybot = area->r_ybot; if (area->r_xtop < TiPlaneRect.r_xtop) { clip->r_xtop = area->r_xtop * CIFCurStyle->cs_scaleFactor; expanded->r_xtop = area->r_xtop + CIFCurStyle->cs_radius; } else clip->r_xtop = expanded->r_xtop = area->r_xtop; if (area->r_ytop < TiPlaneRect.r_ytop) { clip->r_ytop = area->r_ytop * CIFCurStyle->cs_scaleFactor; expanded->r_ytop = area->r_ytop + CIFCurStyle->cs_radius; } else clip->r_ytop = expanded->r_ytop = area->r_ytop; } /* * ---------------------------------------------------------------------------- * * CIFClearPlanes -- * * This procedure clears out a collection of CIF planes. * * Results: * None. * * Side effects: * Each of the planes in "planes" is re-initialized to point to * an empty paint plane. * * ---------------------------------------------------------------------------- */ void CIFClearPlanes(planes) Plane **planes; /* Pointer to an array of MAXCIFLAYERS * planes. */ { int i; for (i = 0; i < MAXCIFLAYERS; i++) { if (planes[i] == NULL) { planes[i] = DBNewPlane((ClientData) TT_SPACE); } else { DBClearPaintPlane(planes[i]); } } } magic-8.0.210/cif/CIFsee.c0000644000175000001440000003371511410650573013470 0ustar timusers/* CIFsee.c - * * This file provides procedures for displaying CIF layers on * the screen using the highlight facilities. * * ********************************************************************* * * 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/cif/CIFsee.c,v 1.5 2010/06/24 12:37:15 tim Exp $"; #endif /* not lint */ #include #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 "graphics/graphics.h" #include "dbwind/dbwind.h" #include "utils/styles.h" #include "cif/CIFint.h" #include "textio/textio.h" #include "utils/undo.h" /* The following variable holds the CellDef into which feedback * is to be placed for displaying CIF. */ static CellDef *cifSeeDef; /* Verbosity of warning messages */ global int CIFWarningLevel = CIF_WARN_DEFAULT; typedef struct { CellDef *paintDef; int layer; } PaintLayerData; typedef struct { char *text; int layer; int style; } SeeLayerData; /* * ---------------------------------------------------------------------------- * * cifPaintDBFunc -- * * This routine paints CIF back into the database at the inverse * scale at which it was generated. Otherwise, it is very much like * cifPaintCurrentFunc() in CIFrdcl.c. * * Results: * Always returns 0 to keep the search alive. * * Side effects: * Paint is generated in the cell. * ---------------------------------------------------------------------------- */ int cifPaintDBFunc(tile, pld) Tile *tile; /* Tile of CIF information. */ PaintLayerData *pld; { Rect area; int pNum; TileType type = pld->layer; /* Magic type to be painted. */ CellDef *paintDef = pld->paintDef; /* Cell to draw into. */ int cifScale = CIFCurStyle->cs_scaleFactor; PaintUndoInfo ui; /* Compute the area of the CIF tile, then scale it into * Magic coordinates. */ TiToRect(tile, &area); area.r_xtop /= cifScale; area.r_xbot /= cifScale; area.r_ytop /= cifScale; area.r_ybot /= cifScale; /* Check for degenerate areas (from rescale limiting) before painting */ if ((area.r_xbot == area.r_xtop) || (area.r_ybot == area.r_ytop)) return 0; ui.pu_def = paintDef; for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++) if (DBPaintOnPlane(type, pNum)) { ui.pu_pNum = pNum; DBNMPaintPlane(paintDef->cd_planes[pNum], TiGetTypeExact(tile), &area, DBStdPaintTbl(type, pNum), (PaintUndoInfo *) &ui); } return 0; /* To keep the search alive. */ } /* * ---------------------------------------------------------------------------- * * CIFPaintLayer -- * * Generates CIF over a given area of a given cell, then * paints the CIF layer back into the cell (or optionally, * into a separate cell) as a magic layer. * * Results: * None. * * Side effects: * Highlight information is drawn on the screen. * * ---------------------------------------------------------------------------- */ void CIFPaintLayer(rootDef, area, cifLayer, magicLayer, paintDef) CellDef *rootDef; /* Cell for which to generate CIF. Must be * the rootDef of a window. */ Rect *area; /* Area in which to generate CIF. */ char *cifLayer; /* CIF layer to highlight on the screen. */ int magicLayer; /* Magic layer to paint with the result */ CellDef *paintDef; /* CellDef to paint into (may be NULL) */ { int oldCount, i; char msg[100]; SearchContext scx; PaintLayerData pld; TileTypeBitMask mask, depend; /* Make sure the desired layer exists. */ if (!CIFNameToMask(cifLayer, &mask, &depend)) return; /* Paint directly into the root cellDef if passed a NULL paintDef*/ pld.paintDef = (paintDef == NULL) ? rootDef : paintDef; pld.layer = magicLayer; /* Flatten the area and generate CIF for it. */ CIFErrorDef = rootDef; CIFInitCells(); UndoDisable(); CIFDummyUse->cu_def = rootDef; GEO_EXPAND(area, CIFCurStyle->cs_radius, &scx.scx_area); scx.scx_use = CIFDummyUse; scx.scx_trans = GeoIdentityTransform; (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); oldCount = DBWFeedbackCount; CIFGen(CIFComponentDef, area, CIFPlanes, &depend, TRUE, TRUE); DBCellClearDef(CIFComponentDef); /* Report any errors that occurred. */ if (DBWFeedbackCount != oldCount) { TxPrintf("%d problems occurred. See feedback entries.\n", DBWFeedbackCount-oldCount); } /* Paint back the chosen layer. */ UndoEnable(); for (i = 0; i < CIFCurStyle->cs_nLayers; i++) if (TTMaskHasType(&mask, i)) DBSrPaintArea((Tile *)NULL, CIFPlanes[i], &TiPlaneRect, &CIFSolidBits, cifPaintDBFunc, (ClientData)&pld); DBWAreaChanged(rootDef, area, DBW_ALLWINDOWS, &mask); DBReComputeBbox(rootDef); DRCCheckThis(rootDef, TT_CHECKPAINT, area); } /* * ---------------------------------------------------------------------------- * * cifSeeFunc -- * * Called once for each tile that is to be displayed as feedback. * This procedure enters the tile as feedback. Note: the caller * must arrange for cifSeeDef to contain a pointer to the cell * def where feedback is to be displayed. * * Results: * Always returns 0 to keep the search alive. * * Side effects: * A new feedback area is created over the tile. The parameter * "text" is associated with the feedback. * ---------------------------------------------------------------------------- */ int cifSeeFunc(tile, sld) Tile *tile; /* Tile to be entered as feedback. */ SeeLayerData *sld; /* Layer and explanation for the feedback. */ { Rect area; TiToRect(tile, &area); if (((area.r_xbot & 0x1) || (area.r_ybot & 0x1)) && (CIFWarningLevel == CIF_WARN_ALIGN)) { TxError("Warning: Corner (%.1f, %.1f) has half-lambda placement.\n", (float)area.r_xbot / (float)CIFCurStyle->cs_scaleFactor, (float)area.r_ybot / (float)CIFCurStyle->cs_scaleFactor); } DBWFeedbackAdd(&area, sld->text, cifSeeDef, CIFCurStyle->cs_scaleFactor, sld->style | (TiGetTypeExact(tile) & (TT_DIAGONAL | TT_DIRECTION | TT_SIDE))); /* (preserve information about the geometry of a diagonal tile) */ return 0; } /* * ---------------------------------------------------------------------------- * * CIFSeeLayer -- * * Generates CIF over a given area of a given cell, then * highlights a particular CIF layer on the screen. * * Results: * None. * * Side effects: * Highlight information is drawn on the screen. * * ---------------------------------------------------------------------------- */ void CIFSeeLayer(rootDef, area, layer) CellDef *rootDef; /* Cell for which to generate CIF. Must be * the rootDef of a window. */ Rect *area; /* Area in which to generate CIF. */ char *layer; /* CIF layer to highlight on the screen. */ { int oldCount, i; char msg[100]; SearchContext scx; SeeLayerData sld; TileTypeBitMask mask, depend; /* Make sure the desired layer exists. */ if (!CIFNameToMask(layer, &mask, &depend)) return; /* Flatten the area and generate CIF for it. */ CIFErrorDef = rootDef; CIFInitCells(); UndoDisable(); CIFDummyUse->cu_def = rootDef; GEO_EXPAND(area, CIFCurStyle->cs_radius, &scx.scx_area); scx.scx_use = CIFDummyUse; scx.scx_trans = GeoIdentityTransform; (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); oldCount = DBWFeedbackCount; CIFGen(CIFComponentDef, area, CIFPlanes, &depend, TRUE, TRUE); DBCellClearDef(CIFComponentDef); /* Report any errors that occurred. */ if (DBWFeedbackCount != oldCount) { TxPrintf("%d problems occurred. See feedback entries.\n", DBWFeedbackCount-oldCount); } /* Display the chosen layer. */ (void) sprintf(msg, "CIF layer \"%s\"", layer); cifSeeDef = rootDef; sld.text = msg; for (i = 0; i < CIFCurStyle->cs_nLayers; i++) { if (TTMaskHasType(&mask, i)) { sld.layer = i; #ifdef THREE_D sld.style = CIFCurStyle->cs_layers[i]->cl_renderStyle + TECHBEGINSTYLES; #else sld.style = STYLE_PALEHIGHLIGHTS; #endif DBSrPaintArea((Tile *)NULL, CIFPlanes[i], &TiPlaneRect, &CIFSolidBits, cifSeeFunc, (ClientData)&sld); } } UndoEnable(); } /* * ---------------------------------------------------------------------------- * * CIFSeeHierLayer -- * * This procedure is similar to CIFSeeLayer except that it only * generates hierarchical interaction information. * * Results: * None. * * Side effects: * CIF information is highlighed on the screen. If arrays is * TRUE, then CIF that stems from array interactions is displayed. * if subcells is TRUE, then CIF stemming from subcell interactions * is displayed. If both are TRUE, then both are displayed. * * ---------------------------------------------------------------------------- */ void CIFSeeHierLayer(rootDef, area, layer, arrays, subcells) CellDef *rootDef; /* Def in which to compute CIF. Must be * the root definition of a window. */ Rect *area; /* Area in which to generate CIF. */ char *layer; /* CIF layer to be highlighted. */ bool arrays; /* TRUE means show array interactions. */ bool subcells; /* TRUE means show subcell interactions. */ { int i, oldCount; SeeLayerData sld; char msg[100]; TileTypeBitMask mask; /* Check out the CIF layer name. */ if (!CIFNameToMask(layer, &mask, NULL)) return; CIFErrorDef = rootDef; oldCount = DBWFeedbackCount; CIFClearPlanes(CIFPlanes); if (subcells) CIFGenSubcells(rootDef, area, CIFPlanes); if (arrays) CIFGenArrays(rootDef, area, CIFPlanes); /* Report any errors that occurred. */ if (DBWFeedbackCount != oldCount) { TxPrintf("%d problems occurred. See feedback entries.\n", DBWFeedbackCount - oldCount); } (void) sprintf(msg, "CIF layer \"%s\"", layer); cifSeeDef = rootDef; sld.text = msg; for (i = 0; i < CIFCurStyle->cs_nLayers; i++) { if (TTMaskHasType(&mask, i)) { sld.layer = i; #ifdef THREE_D sld.style = CIFCurStyle->cs_layers[i]->cl_renderStyle + TECHBEGINSTYLES; #else sld.style = STYLE_PALEHIGHLIGHTS; #endif DBSrPaintArea((Tile *)NULL, CIFPlanes[i], &TiPlaneRect, &CIFSolidBits, cifSeeFunc, (ClientData)&sld); } } } /* * ---------------------------------------------------------------------------- * * CIFCoverageLayer -- * * This procedure reports the total area coverage of a CIF layer * within the bounding box of the root CellDef. * * Results: * None. * * Side effects: * Prints results. * * ---------------------------------------------------------------------------- */ typedef struct { long long coverage; Rect bounds; } coverstats; void CIFCoverageLayer(rootDef, area, layer) CellDef *rootDef; /* Def in which to compute CIF coverage */ Rect *area; /* Area in which to compute coverage */ char *layer; /* CIF layer for coverage computation. */ { coverstats cstats; int i, scale; long long atotal, btotal; SearchContext scx; TileTypeBitMask mask, depend; float fcover; int cifCoverageFunc(); bool doBox = (area != &rootDef->cd_bbox) ? TRUE : FALSE; /* Check out the CIF layer name. */ if (!CIFNameToMask(layer, &mask, &depend)) return; CIFErrorDef = rootDef; CIFInitCells(); UndoDisable(); CIFDummyUse->cu_def = rootDef; GEO_EXPAND(area, CIFCurStyle->cs_radius, &scx.scx_area); scx.scx_use = CIFDummyUse; scx.scx_trans = GeoIdentityTransform; (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, cifHierCopyFunc, (ClientData) CIFComponentDef); CIFGen(CIFComponentDef, area, CIFPlanes, &depend, TRUE, TRUE); DBCellClearDef(CIFComponentDef); cstats.coverage = 0; cstats.bounds.r_xbot = cstats.bounds.r_xtop = 0; cstats.bounds.r_ybot = cstats.bounds.r_ytop = 0; for (i = 0; i < CIFCurStyle->cs_nLayers; i++) if (TTMaskHasType(&mask, i)) DBSrPaintArea((Tile *)NULL, CIFPlanes[i], &TiPlaneRect, &CIFSolidBits, cifCoverageFunc, (ClientData) &cstats); /* Print results */ scale = CIFCurStyle->cs_scaleFactor; btotal = (long long)(area->r_xtop - area->r_xbot); btotal *= (long long)(area->r_ytop - area->r_ybot); btotal *= (long long)(scale * scale); fcover = 0.0; if (btotal > 0.0) fcover = (float)cstats.coverage / (float)btotal; atotal = (long long)(cstats.bounds.r_xtop - cstats.bounds.r_xbot); atotal *= (long long)(cstats.bounds.r_ytop - cstats.bounds.r_ybot); TxPrintf("%s Area = %lld CIF units^2\n", doBox ? "Cursor Box" : "Cell", btotal); TxPrintf("Layer Bounding Area = %lld CIF units^2\n", atotal); TxPrintf("Layer Total Area = %lld CIF units^2\n", cstats.coverage); TxPrintf("Coverage in %s = %1.1f%%\n", doBox ? "box" : "cell", 100.0 * fcover); } int cifCoverageFunc(tile, arg) Tile *tile; ClientData *arg; { coverstats *cstats = (coverstats *)arg; Rect r; TiToRect(tile, &r); cstats->coverage += (long long)((r.r_xtop - r.r_xbot) * (r.r_ytop - r.r_ybot)); GeoInclude(&r, &cstats->bounds); return(0); } magic-8.0.210/cif/CIFint.h0000644000175000001440000002706111116007405013501 0ustar timusers/* * CIFint.h -- * * Defines things shared internally by the cif module of Magic, * but not generally needed outside the cif module. * * ********************************************************************* * * 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. * * ********************************************************************* * * rcsid "$Header: /usr/cvsroot/magic-8.0/cif/CIFint.h,v 1.3 2008/12/04 17:10:29 tim Exp $" */ #ifndef _CIFINT_H #define _CIFINT_H #include "database/database.h" /* The main data structure used in the cif module is a description * of how to generate CIF layers from the Magic tiles. There may * be several different styles for generating CIF from the same Magic * information, e.g. for fabricating at different geometries. Each * of these CIF styles involves three kinds of data. A "CIFStyle" * record gives overall information such as the number of layers. * One "CIFLayer" gives overall information for each layer, and * then a list of one or more "CIFOp" records describes a sequence * of geometrical operations to perform to generate the layer. This * data structure is built up by reading the technology file. */ /* A CIFOp starts from a partially-completed CIF layer, does something * to it, which may possibly involve some existing layers or temporary * layers, and creates the next stage of the partially-completed * CIF layer. Example operations are to AND with some existing paint, * or to grow by a certain amount. */ typedef struct bloat_data { int bl_plane; /* Plane on which a bloat or squares * operation is valid. */ int bl_distance[TT_MAXTYPES]; } BloatData; typedef struct squares_data { int sq_border; int sq_size; int sq_sep; int sq_gridx; /* Only used for "squares-grid" */ int sq_gridy; /* Only used for "squares-grid" */ } SquaresData; typedef struct slots_data { int sl_sborder; /* short tile side */ int sl_ssize; int sl_ssep; int sl_lborder; /* long tile side */ int sl_lsize; int sl_lsep; int sl_offset; } SlotsData; typedef struct cifop { TileTypeBitMask co_paintMask;/* Zero or more paint layers to consider. */ TileTypeBitMask co_cifMask; /* Zero or more other CIF layers. */ int co_opcode; /* Which geometric operation to use. See * below for the legal ones. */ int co_distance; /* Grow or shrink distance (if needed). */ ClientData co_client; /* Pointer to a BloatData, SquaresData, or * SlotsData structure, or NULL. */ struct cifop *co_next; /* Next in list of operations to perform. */ } CIFOp; /* The opcodes defined so far are: * * CIFOP_AND - AND current results with the layers indicated by * the masks. * CIFOP_ANDNOT - Wherever there is material indicated by the masks, * erase those areas from the current results. * CIFOP_OR - OR current results with the layers indicated by * the masks. * CIFOP_GROW - Grow the current results uniformly by co_distance. * CIFOP_GROW_G - Grow the current results to snap to the indicated grid. * CIFOP_SHRINK - Shrink the current results uniformly by co_distance. * CIFOP_BLOAT - Find layers in paintMask, then bloat selectively * according to bl_distance, and OR the results into * the current plane * CIFOP_SQUARES - Generates a pattern of squares (used for making * contact vias. Each square is co_distance large, * the squares are separated from each other by * co_distance, and they are inside the edge of * the material by at least co_distance. * CIFOP_SLOTS - Generate a pattern of rectangles (used for making * slots and slot vias). Similar to squares except * for different dimensions in short and long tile * dimensions. "0" for the long size indicates that * the slot should extend the length of the tile * minus the long-side border length. * CIFOP_BLOATMAX - Like CIFOP_BLOAT, except whole side of tile gets * bloated by same amount, which is max bloat from * anywhere along side. Bloats can be negative. * CIFOP_BLOATMIN - Same as CIFOP_BLOAT, except use min bloat from * anywhere along side. * CIFOP_BLOATALL - Added 3/21/05---bloat to encompass all connected * material of the indicated type(s). * CIFOP_BBOX - Added 4/2/05---create a single rectangle encompassing * the cell bounding box. This involves no magic type * layers but may itself be acted upon with grow/shrink * rules. * CIFOP_NET - Added 11/3/08---pull an entire electrical net into * the CIF layer, selectively picking layers. * CIFOP_MAXRECT - Reduce all areas to the largest internal fitting * rectangle. */ #define CIFOP_AND 1 #define CIFOP_OR 2 #define CIFOP_GROW 3 #define CIFOP_GROW_G 4 #define CIFOP_SHRINK 5 #define CIFOP_BLOAT 6 #define CIFOP_SQUARES 7 #define CIFOP_SLOTS 8 #define CIFOP_BLOATMAX 9 #define CIFOP_BLOATMIN 10 #define CIFOP_BLOATALL 11 #define CIFOP_ANDNOT 12 #define CIFOP_SQUARES_G 13 #define CIFOP_BBOX 14 #define CIFOP_NET 15 #define CIFOP_MAXRECT 16 /* Added by Tim 10/21/2004 */ /* The following structure is used to pass information on how to draw * contact subcell arrays for a specific magic contact tile type. For * the GDS write routine, the GDS file (FILE *) is passed as the client * data. */ typedef struct cifsquaresinfo { SquaresData *csi_squares; /* Information on how to generate squares */ TileType csi_type; /* Magic contact tile type */ ClientData csi_client; /* Used to pass output file info. */ } CIFSquaresInfo; /* The following data structure contains all the information about * a particular CIF layer. */ typedef struct { char *cl_name; /* Name of layer. */ CIFOp *cl_ops; /* List of operations. If NULL, layer is * determined entirely by cl_initial. */ int cl_growDist; /* Largest distance material may move in * this layer from its original Magic * position, due to grows. Expressed * in CIF units. If this layer uses temp * layers, this distance must include grows * from the temp layers. */ int cl_shrinkDist; /* Same as above, except for shrinks. */ int cl_flags; /* Bunches of flags: see below. */ int cl_calmanum; /* Number (0-63) of this layer for output as * Calma (GDS-II stream format), or -1 if * this layer should not be output. */ int cl_calmatype; /* Data type (0-63) for Calma output, or -1 * if this layer should not be output. */ int min_width; /* the minimum width rule in centi-microns * for the layer. This is used by Grow Sliver * to generate drc correct parent slivers */ #ifdef THREE_D int cl_renderStyle; /* Style to render CIF layer with */ float cl_height; /* (rendered) height of CIF layer above substrate */ float cl_thick; /* (rendered) thickness of CIF layer */ #endif } CIFLayer; /* The CIFLayer flags are: * * CIF_TEMP: Means that this is a temporary layer used to build * up CIF information. It isn't output in the CIF file. * CIF_BBOX_TOP: Indicates that the bounding box rectangle should * only be generated if the cell is a top-level cell. */ #define CIF_TEMP 1 #define CIF_BBOX_TOP 2 /* The following data structure describes a complete set of CIF * layers. The number of CIF layers (MAXCIFLAYERS) must not be * greater than the number of tile types (TT_MAXTYPES)!! */ #define MAXCIFLAYERS (TT_MAXTYPES - 1) typedef struct cifkeep { struct cifkeep *cs_next; char *cs_name; } CIFKeep; typedef struct cifstyle { char cs_status; /* Status: Loaded, not loaded, or pending. */ char *cs_name; /* Name used for this kind of CIF. */ int cs_nLayers; /* Number of layers. */ int cs_radius; /* Radius of interaction for hierarchical * processing (expressed in Magic units). */ int cs_stepSize; /* If non-zero, user-specified step size * for hierarchical processing (in Magic * units). */ int cs_gridLimit; /* The limit of grid scaling. This limits * the use of "scalegrid" to prevent Magic * from generating geometry smaller than the * process minimum grid. */ int cs_scaleFactor; /* Number of CIF units per Magic unit. * CIF units are usually centimicrons, but * see cs_expander below. */ int cs_reducer; /* Reduction factor (used only to reduce * number of zeroes in CIF files and make * file more readable). Default of 1. * Unused for GDS input/output. */ int cs_expander; /* cs_scaleFactor / cs_expander = scale in * centimicrons. Default of 1. Value 10 * means cs_scaleFactor is measured in * nanometers (millimicrons) */ TileTypeBitMask cs_yankLayers; /* For hierarchical processing, only these * Magic types need to be yanked. */ TileTypeBitMask cs_hierLayers; /* For hierarchical processing, only these * CIF layers need to be generated. */ int cs_labelLayer[TT_MAXTYPES]; /* Each entry corresponds to one Magic layer, * and gives index of CIF real layer to use * for labels attached to this Magic layer. * -1 means no known CIF layer for this Magic * layer. */ CIFLayer *cs_layers[MAXCIFLAYERS]; /* Describes how to generate each layer.*/ int cs_flags; /* bitmask of boolean-valued output options */ } CIFStyle; /* values for cs_flags */ #define CWF_PERMISSIVE_LABELS 0x01 #define CWF_GROW_SLIVERS 0x02 #define CWF_ANGSTROMS 0x04 #define CWF_GROW_EUCLIDEAN 0x08 #define CWF_SEE_VENDOR 0x10 /* Override vendor GDS flag in cells */ #define CWF_NO_ERRORS 0x20 /* Do not generate error msgs and fdbk */ /* procedures */ extern bool CIFNameToMask(); extern void CIFGenSubcells(); extern void CIFGenArrays(); extern void CIFGen(); extern void CIFClearPlanes(); extern Plane *CIFGenLayer(); extern void CIFInitCells(); extern int cifHierCopyFunc(); extern void CIFLoadStyle(); /* Shared variables and structures: */ extern Plane *CIFPlanes[]; /* Normal place to store CIF. */ extern CIFKeep *CIFStyleList; /* List of all CIF styles. */ extern CIFStyle *CIFCurStyle; /* Current style being used. */ extern CellUse *CIFComponentUse; /* Flatten stuff in here if needed. */ extern CellDef *CIFComponentDef; /* Corresponds to CIFComponentUse. */ extern CellUse *CIFDummyUse; /* Used to dummy up a CellUse for a * def. */ /* Valid values of CIFWarningLevel (see cif.h) */ typedef enum {CIF_WARN_DEFAULT, CIF_WARN_NONE, CIF_WARN_ALIGN, CIF_WARN_LIMIT, CIF_WARN_REDIRECT, CIF_WARN_END} CIFWarningTypes; /* Statistics counters: */ extern int CIFTileOps; extern int CIFHierTileOps; extern int CIFRects; extern int CIFHierRects; /* Tables used for painting and erasing CIF. */ extern PaintResultType CIFPaintTable[], CIFEraseTable[]; /* Procedures and variables for reporting errors. */ extern int CIFErrorLayer; extern CellDef *CIFErrorDef; extern void CIFError(); /* The following determines the tile type used to hold the CIF * information on its paint plane. */ #define CIF_SOLIDTYPE 1 extern TileTypeBitMask CIFSolidBits; #endif /* _CIFINT_H */ magic-8.0.210/cif/CIFtech.c0000664000175000001440000017047012214323201013625 0ustar timusers/* CIFtech.c - * * This module processes the portions of technology * files pertaining to CIF, and builds the tables * used by the CIF generator. * * ********************************************************************* * * 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/cif/CIFtech.c,v 1.7 2010/10/20 20:34:19 tim Exp $"; #endif /* not lint */ #include #include /* for atof() */ #include #include #include /* for pow() */ #include "utils/magic.h" #include "utils/geometry.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "utils/tech.h" #include "utils/utils.h" #include "utils/styles.h" #include "cif/CIFint.h" #include "calma/calmaInt.h" #include "textio/textio.h" #include "utils/malloc.h" #include "cif/cif.h" #include "drc/drc.h" /* For WRL's DRC-CIF extensions */ /* The following statics are used to keep track of things between * calls to CIFTechLine. */ static CIFLayer *cifCurLayer; /* Current layer whose spec. is being read. */ static CIFOp *cifCurOp; /* Last geometric operation read in. */ static bool cifGotLabels; /* TRUE means some labels have been assigned * to the current layer. */ /* The following is a TileTypeBitMask array with only the CIF_SOLIDTYPE * bit set in it. */ TileTypeBitMask CIFSolidBits; /* Forward Declarations */ void cifTechStyleInit(); bool cifCheckCalmaNum(); /* * ---------------------------------------------------------------------------- * * cifTechFreeStyle -- * * This procedure frees memory for the current CIF style, and * sets the current style to NULL. * * Results: * None. * * Side effects: * Memory is free'd. * * ---------------------------------------------------------------------------- */ void cifTechFreeStyle() { int i; CIFOp *op; CIFLayer *layer; if (CIFCurStyle != NULL) { /* Destroy old style structure and free memory allocated to it */ for (i = 0; i < MAXCIFLAYERS; i++) { layer = CIFCurStyle->cs_layers[i]; if (layer != NULL) { for (op = layer->cl_ops; op != NULL; op = op->co_next) { if (op->co_client != (ClientData)NULL) { switch (op->co_opcode) { case CIFOP_OR: case CIFOP_BBOX: case CIFOP_MAXRECT: /* These options use co_client to hold a single */ /* integer value, so it is not allocated. */ break; default: freeMagic((char *)op->co_client); break; } } freeMagic((char *)op); } freeMagic((char *)layer); } } freeMagic(CIFCurStyle); CIFCurStyle = NULL; } } /* * ---------------------------------------------------------------------------- * * cifTechNewStyle -- * * This procedure creates a new CIF style at the end of * the list of style and initializes it to completely * null. * * Results: * None. * * Side effects: * A new element is added to the end of CIFStyleList, and CIFCurStyle * is set to point to it. * * ---------------------------------------------------------------------------- */ void cifTechNewStyle() { cifTechFreeStyle(); cifTechStyleInit(); } /* * ---------------------------------------------------------------------------- * * cifTechStyleInit -- * * Fill in the current cif input style structure with initial values * * ---------------------------------------------------------------------------- */ void cifTechStyleInit() { int i; if (CIFCurStyle == NULL) CIFCurStyle = (CIFStyle *) mallocMagic(sizeof(CIFStyle)); CIFCurStyle->cs_name = NULL; CIFCurStyle->cs_status = TECH_NOT_LOADED; CIFCurStyle->cs_nLayers = 0; CIFCurStyle->cs_scaleFactor = 0; CIFCurStyle->cs_stepSize = 0; CIFCurStyle->cs_gridLimit = 0; CIFCurStyle->cs_reducer = 0; CIFCurStyle->cs_expander = 1; CIFCurStyle->cs_yankLayers = DBZeroTypeBits; CIFCurStyle->cs_hierLayers = DBZeroTypeBits; CIFCurStyle->cs_flags = 0; for (i=0; ics_labelLayer[i] = -1; for (i = 0; i < MAXCIFLAYERS; i++) CIFCurStyle->cs_layers[i] = NULL; } /* * ---------------------------------------------------------------------------- * * cifParseLayers -- * * Takes a comma-separated list of layers and turns it into two * masks, one of paint layers and one of previously-defined CIF * layers. * * Results: * None. * * Side effects: * The masks pointed to by the paintMask and cifMask parameters * are modified. If some of the layers are unknown, then an error * message is printed. * * ---------------------------------------------------------------------------- */ void cifParseLayers(string, style, paintMask, cifMask,spaceOK) char *string; /* List of layers. */ CIFStyle *style; /* Gives CIF style for parsing string.*/ TileTypeBitMask *paintMask; /* Place to store mask of paint layers. If * NULL, then only CIF layer names are * considered. */ TileTypeBitMask *cifMask; /* Place to store mask of CIF layers. If * NULL, then only paint layer names are * considered. */ int spaceOK; /* are space layers permissible in this cif layer? */ { TileTypeBitMask curCifMask, curPaintMask; char curLayer[40], *p, *cp; TileType paintType; int i; bool allResidues; if (paintMask != NULL) TTMaskZero(paintMask); if (cifMask != NULL) TTMaskZero(cifMask); while (*string != 0) { p = curLayer; if (*string == '*') { allResidues = TRUE; string++; } else allResidues = FALSE; while ((*string != ',') && (*string != 0)) *p++ = *string++; *p = 0; while (*string == ',') string += 1; /* See if this is a paint type. */ if (paintMask != NULL) { paintType = DBTechNameTypes(curLayer, &curPaintMask); if (paintType >= 0) goto okpaint; } else paintType = -2; okpaint: /* See if this is the name of another CIF layer. Be * careful not to let the current layer be used in * generating itself. Exact match is requred on CIF * layer names, but the same name can appear multiple * times in different styles. */ TTMaskZero(&curCifMask); if (cifMask != NULL) { for (i = 0; i < style->cs_nLayers; i++) { if (style->cs_layers[i] == cifCurLayer) continue; if (strcmp(curLayer, style->cs_layers[i]->cl_name) == 0) { TTMaskSetType(&curCifMask, i); } } } /* Make sure that there's exactly one match among cif and * paint layers together. */ if ((paintType == -1) || ((paintType >= 0) && !TTMaskEqual(&curCifMask, &DBZeroTypeBits))) { TechError("Ambiguous layer (type) \"%s\".\n", curLayer); continue; } if (paintType >= 0) { if (paintType == TT_SPACE && spaceOK ==0) TechError("\"Space\" layer not permitted in CIF rules.\n"); else { TileType rtype; TileTypeBitMask *rMask; TTMaskSetMask(paintMask, &curPaintMask); /* Add residues from '*' notation */ if (allResidues) for (rtype = TT_TECHDEPBASE; rtype < DBNumUserLayers; rtype++) { rMask = DBResidueMask(rtype); if (TTMaskHasType(rMask, paintType)) TTMaskSetType(paintMask, rtype); } } } else if (!TTMaskEqual(&curCifMask, &DBZeroTypeBits)) { TTMaskSetMask(cifMask, &curCifMask); } else { HashEntry *he; TileTypeBitMask *amask; he = HashLookOnly(&DBTypeAliasTable, curLayer); if (he != NULL) { amask = (TileTypeBitMask *)HashGetValue(he); TTMaskSetMask(paintMask, amask); } else TechError("Unrecognized layer (type) \"%s\".\n", curLayer); } } } /* * ---------------------------------------------------------------------------- * * CIFTechInit -- * * Called before loading a new technology. * * Results: * None. * * Side effects: * Clears out list of styles and resets the current style. * * ---------------------------------------------------------------------------- */ void CIFTechInit() { CIFKeep *style; /* Cleanup any old info. */ cifTechFreeStyle(); /* forget the list of styles */ for (style = CIFStyleList; style != NULL; style = style->cs_next) { freeMagic(style->cs_name); freeMagic(style); } CIFStyleList = NULL; } /* * ---------------------------------------------------------------------------- * * CIFTechStyleInit -- * * Called once at beginning of technology file read-in to * initialize data structures. * * Results: * None. * * Side effects: * Just clears out the layer data structures. * * ---------------------------------------------------------------------------- */ void CIFTechStyleInit() { CalmaTechInit(); /* Create the TileTypeBitMask array with only the CIF_SOLIDTYPE bit set */ TTMaskZero(&CIFSolidBits); TTMaskSetType(&CIFSolidBits, CIF_SOLIDTYPE); cifCurOp = NULL; cifCurLayer = NULL; cifGotLabels = FALSE; } /* * ---------------------------------------------------------------------------- * * CIFTechLimitScale -- * * Determine if the scalefactor (ns / ds), applied to the current * grid scaling, would result in a grid finer than the minimum * resolution allowed by the process, as set by the "gridlimit" * statement in the "cifoutput" section (note that the scaling * depends on the output style chosen, and can be subverted by * scaling while a fine-grid output style is active, then switching * to a coarse-grid output style). * * Note that even if the scalefactor is larger than the minimum * grid, it must be a MULTIPLE of the minimum grid, or else geometry * can be generated off-grid. * * Results: * TRUE if scaling by (ns / ds) would violate minimum grid resolution, * FALSE if not. * * Side effects: * None. * * ---------------------------------------------------------------------------- */ bool CIFTechLimitScale(ns, ds) int ns, ds; { int gridup, scaledown; /* If no output style is active, it's okay to refine the */ /* grid arbitrarily. */ if (CIFCurStyle == NULL) return FALSE; gridup = CIFCurStyle->cs_gridLimit * ds; if (gridup == 0) return FALSE; scaledown = CIFCurStyle->cs_scaleFactor * ns; if ((scaledown % gridup) != 0) return TRUE; return FALSE; } /* * ---------------------------------------------------------------------------- * * CIFParseScale -- * * Read a scale value and determine scaleFactor and expander values * * Results: * Returns the value for cs_scaleFactor * * Side effects: * Alters the value of expander (pointer to cs_expander) * * ---------------------------------------------------------------------------- */ int CIFParseScale(true_scale, expander) char *true_scale; int *expander; { char *decimal; short places; int n, d; decimal = strchr(true_scale, '.'); if (decimal == NULL) /* true_scale is integer */ { *expander = 1; return atoi(true_scale); } else { *decimal = '\0'; places = strlen(decimal + 1); d = pow(10,places); n = atoi(true_scale); *decimal = '.'; n *= d; n += atoi(decimal + 1); ReduceFraction(&n, &d); *expander = d; return n; } } /* * ---------------------------------------------------------------------------- * * CIFTechLine -- * * This procedure is called once for each line in the "cif" * section of the technology file. * * Results: * TRUE if line parsed correctly; FALSE if fatal error condition * encountered. * * Side effects: * Sets up information in the tables of CIF layers, and * prints error messages where there are problems. * * ---------------------------------------------------------------------------- */ bool CIFTechLine(sectionName, argc, argv) char *sectionName; /* The name of this section. */ int argc; /* Number of fields on line. */ char *argv[]; /* Values of fields. */ { TileTypeBitMask mask, tempMask, bloatLayers; int i, j, l, distance; CIFLayer *newLayer; CIFOp *newOp = NULL; CIFKeep *newStyle, *p; char **bloatArg; BloatData *bloats; SquaresData *squares; SlotsData *slots; if (argc <= 0) return TRUE; else if (argc >= 2) l = strlen(argv[1]); /* See if we're starting a new CIF style. If not, make * sure that the current (maybe default?) CIF style has * a name. */ if (strcmp(argv[0], "style") == 0) { if (argc != 2) { if ((argc != 4) || (strncmp(argv[2], "variant", 7))) { wrongNumArgs: TechError("Wrong number of arguments in %s statement.\n", argv[0]); errorReturn: if (newOp != NULL) freeMagic((char *) newOp); return TRUE; } } for (newStyle = CIFStyleList; newStyle != NULL; newStyle = newStyle->cs_next) { /* Here we're only establishing existance; */ /* break on the first variant found. */ if (!strncmp(newStyle->cs_name, argv[1], l)) break; } if (newStyle == NULL) { if (argc == 2) { newStyle = (CIFKeep *)mallocMagic(sizeof(CIFKeep)); newStyle->cs_next = NULL; newStyle->cs_name = StrDup((char **) NULL, argv[1]); /* Append to end of style list */ if (CIFStyleList == NULL) CIFStyleList = newStyle; else { for (p = CIFStyleList; p->cs_next; p = p->cs_next); p->cs_next = newStyle; } } else /* Handle style variants */ { CIFKeep *saveStyle = NULL; char *tptr, *cptr; /* 4th argument is a comma-separated list of variants. */ /* In addition to the default name recorded above, */ /* record each of the variants. */ tptr = argv[3]; while (*tptr != '\0') { cptr = strchr(tptr, ','); if (cptr != NULL) *cptr = '\0'; newStyle = (CIFKeep *)mallocMagic(sizeof(CIFKeep)); newStyle->cs_next = NULL; newStyle->cs_name = (char *)mallocMagic(l + strlen(tptr) + 1); sprintf(newStyle->cs_name, "%s%s", argv[1], tptr); /* Remember the first variant as the default */ if (saveStyle == NULL) saveStyle= newStyle; /* Append to end of style list */ if (CIFStyleList == NULL) CIFStyleList = newStyle; else { for (p = CIFStyleList; p->cs_next; p = p->cs_next); p->cs_next = newStyle; } if (cptr == NULL) break; else tptr = cptr + 1; } newStyle = saveStyle; } } if (CIFCurStyle == NULL) { cifTechNewStyle(); CIFCurStyle->cs_name = newStyle->cs_name; CIFCurStyle->cs_status = TECH_PENDING; } else if ((CIFCurStyle->cs_status == TECH_PENDING) || (CIFCurStyle->cs_status == TECH_SUSPENDED)) CIFCurStyle->cs_status = TECH_LOADED; else if (CIFCurStyle->cs_status == TECH_NOT_LOADED) { if (CIFCurStyle->cs_name == NULL) return (FALSE); else if (argc == 2) { if (!strcmp(argv[1], CIFCurStyle->cs_name)) CIFCurStyle->cs_status = TECH_PENDING; } else if (argc == 4) { /* Verify that the style matches one variant */ char *tptr, *cptr; if (!strncmp(CIFCurStyle->cs_name, argv[1], l)) { tptr = argv[3]; while (*tptr != '\0') { cptr = strchr(tptr, ','); if (cptr != NULL) *cptr = '\0'; if (!strcmp(CIFCurStyle->cs_name + l, tptr)) { CIFCurStyle->cs_status = TECH_PENDING; return TRUE; } if (cptr == NULL) return TRUE; else tptr = cptr + 1; } } } } return (TRUE); } /* Only continue past this point if we are loading the cif output style */ if (CIFCurStyle == NULL) return FALSE; if ((CIFCurStyle->cs_status != TECH_PENDING) && (CIFCurStyle->cs_status != TECH_SUSPENDED)) return TRUE; /* Process scalefactor lines next. */ if (strcmp(argv[0], "scalefactor") == 0) { if ((argc < 2) || (argc > 4)) goto wrongNumArgs; CIFCurStyle->cs_scaleFactor = CIFParseScale(argv[1], &CIFCurStyle->cs_expander); /* * The "nanometers" keyword multiplies the expander by 10. * Any reducer value and keyword "calmaonly" are now both ignored. */ if (argc >= 3) { if (strncmp(argv[argc - 1], "nanom", 5) == 0) CIFCurStyle->cs_expander *= 10; else if (strncmp(argv[argc - 1], "angstr", 6) == 0) CIFCurStyle->cs_expander *= 100; } CIFCurStyle->cs_reducer = 1; /* initial value only */ if (CIFCurStyle->cs_scaleFactor <= 0) { CIFCurStyle->cs_scaleFactor = 0; TechError("Scalefactor must be a strictly positive value.\n"); goto errorReturn; } return TRUE; } /* New for magic-7.3.100---allow GDS database units to be other */ /* than nanometers. Really, there is only one option here, which */ /* is "units angstroms". This option does not affect CIF output, */ /* whose units are fixed at centimicrons. */ if (strcmp(argv[0], "units") == 0) { if (argc != 2) goto wrongNumArgs; if (!strncmp(argv[1], "angstr", 6)) CIFCurStyle->cs_flags |= CWF_ANGSTROMS; return TRUE; } if (strcmp(argv[0], "stepsize") == 0) { if (argc != 2) goto wrongNumArgs; CIFCurStyle->cs_stepSize = atoi(argv[1]); if (CIFCurStyle->cs_stepSize <= 0) { TechError("Step size must be positive integer.\n"); CIFCurStyle->cs_stepSize = 0; } return TRUE; } /* Process "gridlimit" line next. */ if (strncmp(argv[0], "grid", 4) == 0) { if (StrIsInt(argv[1])) { CIFCurStyle->cs_gridLimit = atoi(argv[1]); if (CIFCurStyle->cs_gridLimit < 0) { TechError("Grid limit must be a positive integer.\n"); CIFCurStyle->cs_gridLimit = 0; } } else TechError("Unable to parse grid limit value.\n"); return TRUE; } /* Process "variant" lines next. */ if (strncmp(argv[0], "variant", 7) == 0) { int l; char *cptr, *tptr; /* If our style variant is not one of the ones declared */ /* on the line, then we ignore all input until we */ /* either reach the end of the style, the end of the */ /* section, or another "variant" line. */ if (argc != 2) goto wrongNumArgs; tptr = argv[1]; while (*tptr != '\0') { cptr = strchr(tptr, ','); if (cptr != NULL) { *cptr = '\0'; for (j = 1; isspace(*(cptr - j)); j++) *(cptr - j) = '\0'; } if (*tptr == '*') { CIFCurStyle->cs_status = TECH_PENDING; return TRUE; } else { l = strlen(CIFCurStyle->cs_name) - strlen(tptr); if (!strcmp(tptr, CIFCurStyle->cs_name + l)) { CIFCurStyle->cs_status = TECH_PENDING; return TRUE; } } if (cptr == NULL) break; else tptr = cptr + 1; } CIFCurStyle->cs_status = TECH_SUSPENDED; } /* Anything below this line is not parsed if we're in TECH_SUSPENDED mode */ if (CIFCurStyle->cs_status != TECH_PENDING) return TRUE; newLayer = NULL; if ((strcmp(argv[0], "templayer") == 0) || (strcmp(argv[0], "layer") == 0)) { if (CIFCurStyle->cs_nLayers == MAXCIFLAYERS) { cifCurLayer = NULL; TechError("Can't handle more than %d CIF layers.\n", MAXCIFLAYERS); TechError("Your local Magic wizard can fix this.\n"); goto errorReturn; } if (argc != 2 && argc != 3) { cifCurLayer = NULL; goto wrongNumArgs; } newLayer = CIFCurStyle->cs_layers[CIFCurStyle->cs_nLayers] = (CIFLayer *) mallocMagic(sizeof(CIFLayer)); CIFCurStyle->cs_nLayers += 1; if ((cifCurOp == NULL) && (cifCurLayer != NULL) && !cifGotLabels) { TechError("Layer \"%s\" contains no material.\n", cifCurLayer->cl_name); } newLayer->cl_name = NULL; (void) StrDup(&newLayer->cl_name, argv[1]); newLayer->cl_ops = NULL; newLayer->cl_flags = 0; newLayer->cl_calmanum = newLayer->cl_calmatype = -1; newLayer->min_width = 0; /* for growSlivers */ #ifdef THREE_D newLayer->cl_height = 0.0; newLayer->cl_thick = 0.0; newLayer->cl_renderStyle = STYLE_PALEHIGHLIGHTS - TECHBEGINSTYLES; #endif if (strcmp(argv[0], "templayer") == 0) newLayer->cl_flags |= CIF_TEMP; cifCurLayer = newLayer; cifCurOp = NULL; cifGotLabels = FALSE; /* Handle a special case of a list of layer names on the layer * line. Turn them into an OR operation. */ if (argc == 3) { cifCurOp = (CIFOp *) mallocMagic(sizeof(CIFOp)); cifCurOp->co_opcode = CIFOP_OR; cifParseLayers(argv[2], CIFCurStyle, &cifCurOp->co_paintMask, &cifCurOp->co_cifMask,FALSE); cifCurOp->co_distance = 0; cifCurOp->co_next = NULL; cifCurOp->co_client = (ClientData)NULL; cifCurLayer->cl_ops = cifCurOp; } return TRUE; } if (strcmp(argv[0], "labels") == 0) { if (cifCurLayer == NULL) { TechError("Must define layer before giving labels it holds.\n"); goto errorReturn; } if (cifCurLayer->cl_flags & CIF_TEMP) TechError("Why are you attaching labels to a temporary layer?\n"); if (argc != 2) goto wrongNumArgs; DBTechNoisyNameMask(argv[1], &mask); for (i=0; ics_labelLayer[i] = CIFCurStyle->cs_nLayers-1; } cifGotLabels = TRUE; return TRUE; } if ((strcmp(argv[0], "calma") == 0) || (strncmp(argv[0], "gds", 3) == 0)) { if (cifCurLayer == NULL) { TechError("Must define layers before giving their Calma types.\n"); goto errorReturn; } if (cifCurLayer->cl_flags & CIF_TEMP) TechError("Why assign a Calma number to a temporary layer?\n"); if (argc != 3) goto wrongNumArgs; if (!cifCheckCalmaNum(argv[1]) || !cifCheckCalmaNum(argv[2])) TechError("Calma layer and type numbers must be 0 to %d.\n", CALMA_LAYER_MAX); cifCurLayer->cl_calmanum = atoi(argv[1]); cifCurLayer->cl_calmatype = atoi(argv[2]); return TRUE; } if (strcmp(argv[0], "min-width") == 0) /* used in growSliver */ { if (cifCurLayer == NULL) { TechError("Must define layers before assigning a minimum width.\n"); goto errorReturn; } if (argc != 2) goto wrongNumArgs; cifCurLayer->min_width = atoi(argv[1]); CIFCurStyle->cs_flags |= CWF_GROW_SLIVERS; return TRUE; } if (strcmp(argv[0], "render") == 0) /* used by specialopen wind3d client */ { #ifdef THREE_D float height, thick; int i, style, lcnt; CIFLayer *layer; if (argc != 5) goto wrongNumArgs; cifCurLayer = NULL; /* This is not in a layer definition */ style = DBWTechParseStyle(argv[2]); if (style < 0) { TechError("Error: Bad render style for CIF layer.\n"); goto errorReturn; } if (!StrIsNumeric(argv[3]) || !StrIsNumeric(argv[4])) { TechError("Syntax: render