From f6d4da56ceab9c033f460ac374665903790e212d Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 1 Apr 2019 11:26:00 -0400 Subject: [PATCH 01/44] Extended the "lef read" command when used to annotate existing cells so that PIN information including USE and CLASS are added to port labels (previously only the bounding box was annotated). --- lef/lefRead.c | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/lef/lefRead.c b/lef/lefRead.c index 29040813..45886837 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -966,7 +966,7 @@ LefReadGeometry(lefMacro, f, oscale, do_list) LinkedRect *newRect, *rectList; Point *pointList; int points; - Rect *paintrect, *contact; + Rect *paintrect, *contact = NULL; static char *geometry_keys[] = { "LAYER", @@ -1013,7 +1013,7 @@ LefReadGeometry(lefMacro, f, oscale, do_list) { // Cut layers defined as contacts use the contact // dimensions, not the dimension from the LEF file - if (DBIsContact(curlayer) && !(GEO_RECTNULL(contact))) + if (DBIsContact(curlayer) && contact && !(GEO_RECTNULL(contact))) { paintrect->r_xbot = (paintrect->r_xbot + paintrect->r_xtop); paintrect->r_ybot = (paintrect->r_ybot + paintrect->r_ytop); @@ -1173,12 +1173,13 @@ enum lef_pin_keys {LEF_DIRECTION = 0, LEF_USE, LEF_PORT, LEF_CAPACITANCE, LEF_SHAPE, LEF_NETEXPR, LEF_PIN_END}; void -LefReadPin(lefMacro, f, pinname, pinNum, oscale) +LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported) CellDef *lefMacro; FILE *f; char *pinname; int pinNum; float oscale; + bool is_imported; { char *token; int keyword, subkey; @@ -1272,7 +1273,26 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale) LefEndStatement(f); break; case LEF_PORT: - LefReadPort(lefMacro, f, pinname, pinNum, pinDir, pinUse, oscale); + if (is_imported) + { + Label *lab; + + LefSkipSection(f, NULL); + /* Skip the port geometry but find the pin name and */ + /* annotate with the use and direction. Note that */ + /* there may be multiple instances of the label. */ + for (lab = lefMacro->cd_labels; lab; lab = lab->lab_next) + { + if (!strcmp(lab->lab_text, pinname)) + { + lab->lab_flags &= ~(PORT_USE_MASK | PORT_DIR_MASK | + PORT_CLASS_MASK); + lab->lab_flags = pinNum | pinUse | pinDir | PORT_DIR_MASK; + } + } + } + else + LefReadPort(lefMacro, f, pinname, pinNum, pinDir, pinUse, oscale); break; case LEF_CAPACITANCE: case LEF_ANTENNADIFF: @@ -1501,10 +1521,7 @@ origin_error: TxPrintf(" Macro defines pin %s\n", token); */ sprintf(tsave, "%.127s", token); - if (is_imported) - LefSkipSection(f, tsave); - else - LefReadPin(lefMacro, f, tsave, pinNum++, oscale); + LefReadPin(lefMacro, f, tsave, pinNum++, oscale, is_imported); break; case LEF_OBS: /* Diagnostic */ @@ -1751,7 +1768,7 @@ enum lef_layer_keys {LEF_LAYER_TYPE=0, LEF_LAYER_WIDTH, LEF_LAYER_PROPERTY, LEF_LAYER_ACDENSITY, LEF_LAYER_DCDENSITY, LEF_LAYER_MINDENSITY, LEF_LAYER_ANTENNADIFF, LEF_LAYER_ANTENNAAREA, LEF_LAYER_ANTENNASIDE, - LEF_VIA_DEFAULT, LEF_VIA_LAYER, LEF_VIA_RECT, + LEF_VIA_DEFAULT, LEF_VIA_LAYER, LEF_VIA_RECT, LEF_VIA_FOREIGN, LEF_VIA_ENCLOSURE, LEF_VIA_PREFERENCLOSURE, LEF_VIARULE_OVERHANG, LEF_VIARULE_METALOVERHANG, LEF_VIARULE_VIA, @@ -1805,6 +1822,7 @@ LefReadLayerSection(f, lname, mode, lefl) "DEFAULT", "LAYER", "RECT", + "FOREIGN", "ENCLOSURE", "PREFERENCLOSURE", "OVERHANG", @@ -1943,6 +1961,7 @@ LefReadLayerSection(f, lname, mode, lefl) LefAddViaGeometry(f, lefl, curlayer, oscale); LefEndStatement(f); break; + case LEF_VIA_FOREIGN: case LEF_VIARULE_VIA: case LEF_VIA_ENCLOSURE: case LEF_VIA_PREFERENCLOSURE: @@ -1984,7 +2003,7 @@ enum lef_sections {LEF_VERSION = 0, LEF_USEMINSPACING, LEF_CLEARANCEMEASURE, LEF_NAMESCASESENSITIVE, LEF_PROPERTYDEFS, LEF_UNITS, LEF_SECTION_LAYER, - LEF_SECTION_VIA, LEF_SECTION_VIARULE, + LEF_SECTION_VIA, LEF_SECTION_VIARULE, LEF_SECTION_NONDEFAULTRULE, LEF_SECTION_SPACING, LEF_SECTION_SITE, LEF_PROPERTY, LEF_NOISETABLE, LEF_CORRECTIONTABLE, LEF_IRDROP, LEF_ARRAY, LEF_SECTION_TIMING, LEF_EXTENSION, LEF_MACRO, @@ -2017,6 +2036,7 @@ LefRead(inName, importForeign) "LAYER", "VIA", "VIARULE", + "NONDEFAULTRULE", "SPACING", "SITE", "PROPERTY", @@ -2177,6 +2197,12 @@ LefRead(inName, importForeign) LefReadLayerSection(f, tsave, keyword, lefl); break; + case LEF_SECTION_NONDEFAULTRULE: + token = LefNextToken(f, TRUE); + TxPrintf("LEF file: Defines non-default rule %s (ignored)\n", token); + sprintf(tsave, "%.127s", token); + LefSkipSection(f, tsave); + break; case LEF_SECTION_SPACING: LefSkipSection(f, sections[LEF_SECTION_SPACING]); break; From 7e738576bcaa959d955aba063c78f578b2533533 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 1 Apr 2019 12:23:48 -0400 Subject: [PATCH 02/44] Corrected errors in LEF output syntax (missing semicolons at statement ends on properties imported from a LEF file). Never noticed before because writing LEF after reading LEF was unusual. --- lef/lefRead.c | 6 ++++-- lef/lefWrite.c | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lef/lefRead.c b/lef/lefRead.c index 45886837..d9986192 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -2004,8 +2004,8 @@ enum lef_sections {LEF_VERSION = 0, LEF_NAMESCASESENSITIVE, LEF_PROPERTYDEFS, LEF_UNITS, LEF_SECTION_LAYER, LEF_SECTION_VIA, LEF_SECTION_VIARULE, LEF_SECTION_NONDEFAULTRULE, - LEF_SECTION_SPACING, LEF_SECTION_SITE, LEF_PROPERTY, - LEF_NOISETABLE, LEF_CORRECTIONTABLE, LEF_IRDROP, + LEF_NOWIREEXTENSIONATPIN, LEF_SECTION_SPACING, LEF_SECTION_SITE, + LEF_PROPERTY, LEF_NOISETABLE, LEF_CORRECTIONTABLE, LEF_IRDROP, LEF_ARRAY, LEF_SECTION_TIMING, LEF_EXTENSION, LEF_MACRO, LEF_END}; @@ -2037,6 +2037,7 @@ LefRead(inName, importForeign) "VIA", "VIARULE", "NONDEFAULTRULE", + "NOWIREEXTENSIONATPIN", "SPACING", "SITE", "PROPERTY", @@ -2097,6 +2098,7 @@ LefRead(inName, importForeign) LefEndStatement(f); break; case LEF_NAMESCASESENSITIVE: + case LEF_NOWIREEXTENSIONATPIN: LefEndStatement(f); break; case LEF_PROPERTYDEFS: diff --git a/lef/lefWrite.c b/lef/lefWrite.c index 495c00b2..30859c11 100644 --- a/lef/lefWrite.c +++ b/lef/lefWrite.c @@ -741,18 +741,18 @@ lefWriteMacro(def, f, scale, hide) propvalue = (char *)DBPropGet(def, "LEFclass", &propfound); if (propfound) { - fprintf(f, " CLASS %s\n", propvalue); + fprintf(f, " CLASS %s ;\n", propvalue); class = propvalue; } else { /* Needs a class of some kind. Use BLOCK as default if not defined */ - fprintf(f, " CLASS BLOCK\n"); + fprintf(f, " CLASS BLOCK ;\n"); } propvalue = (char *)DBPropGet(def, "LEFsource", &propfound); if (propfound) - fprintf(f, " SOURCE %s\n", propvalue); + fprintf(f, " SOURCE %s ;\n", propvalue); fprintf(f, " FOREIGN %s ;\n", def->cd_name); @@ -787,7 +787,7 @@ lefWriteMacro(def, f, scale, hide) propvalue = (char *)DBPropGet(def, "LEFsymmetry", &propfound); if (propfound) - fprintf(f, " SYMMETRY %s\n", propvalue); + fprintf(f, " SYMMETRY %s ;\n", propvalue); /* Generate cell for yanking obstructions */ From 5e9f274f6531820965ad5033f6fd068c97a9fb26 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 23 Apr 2019 14:32:11 -0400 Subject: [PATCH 03/44] Modified the way magic does wiring so that when working on a grid, the wires stay centered on a centerline with respect to each other. Also corrected the long-standing minor issue that the outline drawing of the wire does not update when using the mouse scroll wheel, making it unclear that the wire size has changed until the wire position changes. --- tcltk/tools.tcl | 8 ++--- wiring/wireOps.c | 94 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 78 insertions(+), 24 deletions(-) diff --git a/tcltk/tools.tcl b/tcltk/tools.tcl index cbca18a3..b127292e 100644 --- a/tcltk/tools.tcl +++ b/tcltk/tools.tcl @@ -655,11 +655,11 @@ proc magic::tool {{type next}} { 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_Button1 "wire incr type ; wire show" macro Shift_Button2 "wire switch" - macro Shift_Button3 "wire decr type" - macro Button4 "wire incr width" - macro Button5 "wire decr width" + macro Shift_Button3 "wire decr type ; wire show" + macro Button4 "wire incr width ; wire show" + macro Button5 "wire decr width ; wire show" } netlist { diff --git a/wiring/wireOps.c b/wiring/wireOps.c index b7464377..252089c9 100644 --- a/wiring/wireOps.c +++ b/wiring/wireOps.c @@ -301,6 +301,7 @@ WireAddLeg(rect, point, direction) SearchContext scx; Point cursorPos; TileTypeBitMask mask; + int hwidth = WireWidth / 2; if (WireType == 0) { @@ -372,20 +373,34 @@ WireAddLeg(rect, point, direction) if (direction == WIRE_HORIZONTAL) { + /* If the rect height is not the same as WireWidth, then center */ + /* the new wire segment on the rect. */ + + if (rect->r_ytop - rect->r_ybot != WireWidth) + { + int rmid = (rect->r_ytop + rect->r_ybot) / 2; + rect->r_ybot = rmid - hwidth; + rect->r_ytop = rect->r_ybot + WireWidth; + + rmid = (rect->r_xtop + rect->r_xbot) / 2; + rect->r_xbot = rmid - hwidth; + rect->r_xtop = rect->r_xbot + WireWidth; + } + /* 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; + new.r_xbot = rect->r_xbot; + new.r_xtop = point->p_x + hwidth; WireLastDir = GEO_EAST; } else if (point->p_x < rect->r_xbot) { - new.r_xtop = rect->r_xbot; - new.r_xbot = point->p_x; + new.r_xtop = rect->r_xtop; + new.r_xbot = point->p_x - hwidth; WireLastDir = GEO_WEST; } else return; /* Nothing to paint! */ @@ -395,7 +410,7 @@ WireAddLeg(rect, point, direction) * the wires so there's no real choice. */ - new.r_ybot = point->p_y - WireWidth/2; + new.r_ybot = point->p_y - hwidth; if (new.r_ybot < rect->r_ybot) new.r_ybot = rect->r_ybot; else if (new.r_ybot > rect->r_ytop - WireWidth) @@ -404,20 +419,34 @@ WireAddLeg(rect, point, direction) } else { + /* If the rect width is not the same as WireWidth, then center */ + /* the new wire segment on the rect. */ + + if (rect->r_xtop - rect->r_xbot != WireWidth) + { + int rmid = (rect->r_xtop + rect->r_xbot) / 2; + rect->r_xbot = rmid - hwidth; + rect->r_xtop = rect->r_xbot + WireWidth; + + rmid = (rect->r_ytop + rect->r_ybot) / 2; + rect->r_ybot = rmid - hwidth; + rect->r_ytop = rect->r_ybot + WireWidth; + } + /* 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; + new.r_ybot = rect->r_ybot; + new.r_ytop = point->p_y + hwidth; WireLastDir = GEO_NORTH; } else if (point->p_y < rect->r_ybot) { - new.r_ytop = rect->r_ybot; - new.r_ybot = point->p_y; + new.r_ytop = rect->r_ytop; + new.r_ybot = point->p_y - hwidth; WireLastDir = GEO_SOUTH; } else return; /* Nothing to paint! */ @@ -453,7 +482,7 @@ WireAddLeg(rect, point, direction) SelectChunk(&scx, WireType, 0, &leg, FALSE); } - /* Make the box a square at the tip of the new are just painted. */ + /* Make the box a square at the tip of the new area just painted. */ switch (WireLastDir) { @@ -517,6 +546,7 @@ WireShowLeg() int direction = WIRE_CHOOSE; int delx, dely; MagWindow *w; + int hwidth = WireWidth / 2; if (WireType == 0) return; @@ -557,20 +587,32 @@ WireShowLeg() if (direction == WIRE_HORIZONTAL) { + /* Correct for different width between wire and rect. */ + if (rect->r_ytop - rect->r_ybot != WireWidth) + { + int rmid = (rect->r_ytop + rect->r_ybot) / 2; + rect->r_ybot = rmid - hwidth; + rect->r_ytop = rect->r_ybot + WireWidth; + + rmid = (rect->r_xtop + rect->r_xbot) / 2; + rect->r_xbot = rmid - hwidth; + rect->r_xtop = rect->r_xbot + WireWidth; + } + /* 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; + new.r_xbot = rect->r_xbot; + new.r_xtop = point->p_x + hwidth; WireLastDir = GEO_EAST; } else if (point->p_x < rect->r_xbot) { - new.r_xtop = rect->r_xbot; - new.r_xbot = point->p_x; + new.r_xtop = rect->r_xtop; + new.r_xbot = point->p_x - hwidth; WireLastDir = GEO_WEST; } else return; /* Nothing to paint! */ @@ -580,7 +622,7 @@ WireShowLeg() * the wires so there's no real choice. */ - new.r_ybot = point->p_y - WireWidth/2; + new.r_ybot = point->p_y - hwidth; if (new.r_ybot < rect->r_ybot) new.r_ybot = rect->r_ybot; else if (new.r_ybot > rect->r_ytop - WireWidth) @@ -589,25 +631,37 @@ WireShowLeg() } else { + /* Correct for different width between wire and rect. */ + if (rect->r_xtop - rect->r_xbot != WireWidth) + { + int rmid = (rect->r_xtop + rect->r_xbot) / 2; + rect->r_xbot = rmid - hwidth; + rect->r_xtop = rect->r_xbot + WireWidth; + + rmid = (rect->r_ytop + rect->r_ybot) / 2; + rect->r_ybot = rmid - hwidth; + rect->r_ytop = rect->r_ybot + WireWidth; + } + /* 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; + new.r_ybot = rect->r_ybot; + new.r_ytop = point->p_y + hwidth; WireLastDir = GEO_NORTH; } else if (point->p_y < rect->r_ybot) { - new.r_ytop = rect->r_ybot; - new.r_ybot = point->p_y; + new.r_ytop = rect->r_ytop; + new.r_ybot = point->p_y - hwidth; WireLastDir = GEO_SOUTH; } else return; /* Nothing to paint! */ - new.r_xbot = point->p_x - WireWidth/2; + new.r_xbot = point->p_x - hwidth; if (new.r_xbot < rect->r_xbot) new.r_xbot = rect->r_xbot; if (new.r_xbot > rect->r_xtop - WireWidth) From 9ec23203fba04498b3c998a029f80d191031483b Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 24 Apr 2019 10:48:45 -0400 Subject: [PATCH 04/44] Extended the wiring section definition to add wire extensions in addition to wire overlaps, and added a method when painting contacts to draw the necessary wire extension past the contact. Since the wiring method draws single contacts by default, this wiring method assumes a change in direction between layers. But the main point is to generate wire contacts without DRC errors. --- wiring/wireOps.c | 57 ++++++++++-- wiring/wireTech.c | 41 +++++++-- wiring/wireTech.c.new | 204 ------------------------------------------ wiring/wiring.h | 5 ++ 4 files changed, 90 insertions(+), 217 deletions(-) delete mode 100644 wiring/wireTech.c.new diff --git a/wiring/wireOps.c b/wiring/wireOps.c index 252089c9..8c4de863 100644 --- a/wiring/wireOps.c +++ b/wiring/wireOps.c @@ -723,7 +723,8 @@ WireAddContact(newType, newWidth) CellDef *boxRootDef; TileType oldType; TileTypeBitMask mask, allmask; - int oldOverlap, newOverlap, i, totalSize, oldDir; + int oldOverlap, newOverlap, oldExtend, newExtend; + int i, totalSize, oldDir; Contact *contact; SearchContext scx; @@ -769,6 +770,8 @@ WireAddContact(newType, newWidth) { oldOverlap = contact->con_surround1; newOverlap = contact->con_surround2; + oldExtend = contact->con_extend1; + newExtend = contact->con_extend2; goto gotContact; } if ((contact->con_layer2 == oldType) && @@ -776,10 +779,12 @@ WireAddContact(newType, newWidth) { oldOverlap = contact->con_surround2; newOverlap = contact->con_surround1; + oldExtend = contact->con_extend2; + newExtend = contact->con_extend1; goto gotContact; } } - TxError("Sorry, but the technology file doesn't define a contact\n"); + TxError("The technology file doesn't define a contact\n"); TxError(" between \"%s\" and \"%s\".\n", DBTypeLongName(oldType), DBTypeLongName(WireType)); return; @@ -793,18 +798,18 @@ WireAddContact(newType, newWidth) */ gotContact: - totalSize = contact->con_size + 2*oldOverlap; + 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_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_ybot)) / 2; contactArea.r_ytop = contactArea.r_ybot + totalSize; } @@ -855,6 +860,48 @@ WireAddContact(newType, newWidth) (void) GeoInclude(&tmp2, &editArea); DBPaintValid(EditCellUse->cu_def, &tmp2, &mask, 0); } + if (contact->con_extend1 != 0) + { + TTMaskSetOnlyType(&mask, contact->con_layer1); + TTMaskSetType(&allmask, contact->con_layer1); + tmp2 = tmp; + switch(oldDir) + { + case GEO_NORTH: + case GEO_SOUTH: + tmp2.r_ybot -= contact->con_extend1; + tmp2.r_ytop += contact->con_extend1; + break; + case GEO_EAST: + case GEO_WEST: + tmp2.r_xbot -= contact->con_extend1; + tmp2.r_xtop += contact->con_extend1; + break; + } + (void) GeoInclude(&tmp2, &editArea); + DBPaintValid(EditCellUse->cu_def, &tmp2, &mask, 0); + } + if (contact->con_extend2 != 0) + { + TTMaskSetOnlyType(&mask, contact->con_layer2); + TTMaskSetType(&allmask, contact->con_layer2); + tmp2 = tmp; + switch(oldDir) + { + case GEO_NORTH: + case GEO_SOUTH: + tmp2.r_xbot -= contact->con_extend2; + tmp2.r_xtop += contact->con_extend2; + break; + case GEO_EAST: + case GEO_WEST: + tmp2.r_ybot -= contact->con_extend2; + tmp2.r_ytop += contact->con_extend2; + break; + } + (void) GeoInclude(&tmp2, &editArea); + DBPaintValid(EditCellUse->cu_def, &tmp2, &mask, 0); + } DBAdjustLabels(EditCellUse->cu_def, &editArea); DBWAreaChanged(EditCellUse->cu_def, &editArea, DBW_ALLWINDOWS, &allmask); diff --git a/wiring/wireTech.c b/wiring/wireTech.c index 5c8af8d9..a857080b 100644 --- a/wiring/wireTech.c +++ b/wiring/wireTech.c @@ -91,22 +91,25 @@ WireTechLine(sectionName, argc, argv) char *argv[]; /* Pointers to fields of line. */ { Contact *new; + int hasExtend = 0; if (strcmp(argv[0], "contact") != 0) { TechError("Unknown wiring keyword: %s. Line ignored.\n", argv[0]); return TRUE; } - if (argc != 7) + if ((argc != 7) && (argc != 9)) { - TechError("\"contact\" lines must have exactly 7 arguments.\n"); + TechError("\"contact\" lines must have exactly 7 or 9 arguments.\n"); return TRUE; } + if (argc == 9) hasExtend = 1; new = (Contact *) mallocMagic(sizeof(Contact)); new->con_type = DBTechNoisyNameType(argv[1]); new->con_layer1 = DBTechNoisyNameType(argv[3]); - new->con_layer2 = DBTechNoisyNameType(argv[5]); + new->con_layer2 = DBTechNoisyNameType(argv[5 + hasExtend]); + new->con_extend1 = new->con_extend2 = 0; if ((new->con_type < 0) || (new->con_layer1 < 0) || (new->con_layer2 < 0)) { errorReturn: @@ -116,22 +119,38 @@ WireTechLine(sectionName, argc, argv) if (!StrIsInt(argv[2])) { - TechError("3rd field must be an integer.\n"); + TechError("Contact size 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"); + TechError("Contact surround distance must be an integer.\n"); goto errorReturn; } else new->con_surround1 = atoi(argv[4]); - if (!StrIsInt(argv[6])) + if (!StrIsInt(argv[6 + hasExtend])) { - TechError("6th field must be an integer.\n"); + TechError("Contact surround distance must be an integer.\n"); goto errorReturn; } - else new->con_surround2 = atoi(argv[6]); + else new->con_surround2 = atoi(argv[6 + hasExtend]); + + if (argc == 9) + { + if (!StrIsInt(argv[5])) + { + TechError("Contact extend distance must be an integer.\n"); + goto errorReturn; + } + else new->con_extend1 = atoi(argv[5]); + if (!StrIsInt(argv[8])) + { + TechError("Contact extend distance must be an integer.\n"); + goto errorReturn; + } + else new->con_extend2 = atoi(argv[8]); + } new->con_next = WireContacts; WireContacts = new; @@ -201,5 +220,11 @@ WireTechScale(scalen, scaled) con->con_surround2 *= scaled; con->con_surround2 /= scalen; + + con->con_extend1 *= scaled; + con->con_extend1 /= scalen; + + con->con_extend2 *= scaled; + con->con_extend2 /= scalen; } } diff --git a/wiring/wireTech.c.new b/wiring/wireTech.c.new deleted file mode 100644 index 4c69735e..00000000 --- a/wiring/wireTech.c.new +++ /dev/null @@ -1,204 +0,0 @@ -/* - * 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; - } -} - diff --git a/wiring/wiring.h b/wiring/wiring.h index 022596e4..5f7254a0 100644 --- a/wiring/wiring.h +++ b/wiring/wiring.h @@ -48,10 +48,15 @@ typedef struct _Contact * con_layer1 must be painted around the * edge of the contact. */ + int con_extend1; /* How much additional material of type + * con_layer1 must extend beyond the + * contact in the orientation of the route. + */ TileType con_layer2; /* Same information for second layer that * the contact connects. */ int con_surround2; + int con_extend2; ContactPtr con_next; /* Pointer to next contact record */ } Contact; From b8bfaa50663d61720071699247ff2ec5510a672a Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Fri, 3 May 2019 09:14:25 -0400 Subject: [PATCH 05/44] Corrected command option "select [more|less] cell ", which was not recognizing the more|less option and therefore failing to search for the instance , rendering the command non-functional. --- commands/CmdRS.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/commands/CmdRS.c b/commands/CmdRS.c index ec2698f3..692e82bb 100644 --- a/commands/CmdRS.c +++ b/commands/CmdRS.c @@ -1349,7 +1349,8 @@ Okay: * click" code. */ - if ((cmd->tx_argc == 3) && (optionArgs == &cmd->tx_argv[2])) + if ((cmd->tx_argc == 3) && (optionArgs == &cmd->tx_argv[2]) && + (more == FALSE) && (less == FALSE)) { use = lastUse = scx.scx_use; p.p_x = scx.scx_use->cu_xlo; From fc7249b04c446cd204b42ad09d6336b1b8713363 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Fri, 3 May 2019 10:13:06 -0400 Subject: [PATCH 06/44] Extended the "port" command to operate on labels in non-edit cells as long as the command is not attempting to modify the port. Attempts to modify ports in non-edit cells result in an error message that is more helpful than the previous "Exactly one label must be present..." text. --- commands/CmdLQ.c | 108 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 99 insertions(+), 9 deletions(-) diff --git a/commands/CmdLQ.c b/commands/CmdLQ.c index bb72d6c0..7f3f2310 100644 --- a/commands/CmdLQ.c +++ b/commands/CmdLQ.c @@ -1004,6 +1004,54 @@ CmdPolygon(w, cmd) freeMagic(plist); } +/*----------------------------------------------------------------------*/ +/* cmdPortLabelFunc() --- */ +/*----------------------------------------------------------------------*/ + +int +cmdPortLabelFunc1(scx, label, tpath, cdata) + SearchContext *scx; + Label *label; + TerminalPath *tpath; + ClientData cdata; +{ + Label **rlab = (Label **)cdata; + + if (GEO_SURROUND(&scx->scx_area, &label->lab_rect)) + { + if (*rlab != NULL) + { + // More than one label in the area; ambiguous. + *rlab = NULL; + return 1; + } + *rlab = label; + } + return 0; +} + +int +cmdPortLabelFunc2(scx, label, tpath, cdata) + SearchContext *scx; + Label *label; + TerminalPath *tpath; + ClientData cdata; +{ + Label **rlab = (Label **)cdata; + + if (GEO_OVERLAP(&scx->scx_area, &label->lab_rect)) + { + if (*rlab != NULL) + { + // More than one label in the area; ambiguous. + *rlab = NULL; + return 1; + } + *rlab = label; + } + return 0; +} + /*----------------------------------------------------------------------*/ /* portFindLabel --- */ /* */ @@ -1015,12 +1063,13 @@ CmdPolygon(w, cmd) /*----------------------------------------------------------------------*/ Label * -portFindLabel(editDef, port, unique) +portFindLabel(editDef, port, unique, nonEdit) CellDef *editDef; bool unique; bool port; + bool *nonEdit; // TRUE if label is not in the edit cell { - bool found; + int found; Label *lab, *sl; Rect editBox; @@ -1029,33 +1078,62 @@ portFindLabel(editDef, port, unique) */ ToolGetEditBox(&editBox); - found = FALSE; + found = 0; + if (nonEdit) *nonEdit = FALSE; lab = NULL; for (sl = editDef->cd_labels; sl != NULL; sl = sl->lab_next) { if (GEO_OVERLAP(&editBox, &sl->lab_rect)) { - if (found == TRUE) + if (found > 0) { /* Let's do this again with the GEO_SURROUND function */ /* and see if we come up with only one label. */ - found = FALSE; + found = 0; for (sl = editDef->cd_labels; sl != NULL; sl = sl->lab_next) { if (GEO_SURROUND(&editBox, &sl->lab_rect)) { - if (found == TRUE && unique == TRUE) return NULL; + if (found > 0 && unique == TRUE) return NULL; lab = sl; - found = TRUE; + found++; } } break; } lab = sl; - found = TRUE; + found++; + if (nonEdit) *nonEdit = FALSE; } } + + /* If no label was found, then search the hierarchy under the box. */ + /* The calling routine may determine whether a label that is not in */ + /* the edit cell may be valid for the command (e.g., if querying */ + /* but not changing values). */ + + if (found == 0) + { + SearchContext scx; + scx.scx_area = editBox; + scx.scx_use = EditCellUse; + scx.scx_trans = GeoIdentityTransform; + + /* First check for exactly one label surrounded by the cursor box. */ + /* If that fails, check for exactly one label overlapping the */ + /* cursor box. */ + + DBTreeSrLabels(&scx, &DBAllButSpaceBits, 0, NULL, TF_LABEL_ATTACH, + cmdPortLabelFunc1, (ClientData) &lab); + if (lab == NULL) + DBTreeSrLabels(&scx, &DBAllButSpaceBits, 0, NULL, TF_LABEL_ATTACH, + cmdPortLabelFunc2, (ClientData) &lab); + + if (lab != NULL) + if (nonEdit) *nonEdit = TRUE; + } + return lab; } /* @@ -1121,6 +1199,7 @@ CmdPort(w, cmd) int i, idx, pos, type, option, argc; unsigned short dirmask; bool found; + bool nonEdit = FALSE; Label *lab, *sl; Rect editBox, tmpArea; CellDef *editDef = EditCellUse->cu_def; @@ -1254,7 +1333,7 @@ CmdPort(w, cmd) if (option != PORT_LAST) { if (lab == NULL) - lab = portFindLabel(editDef, TRUE, TRUE); + lab = portFindLabel(editDef, TRUE, TRUE, &nonEdit); if (option == PORT_EXISTS) { @@ -1297,6 +1376,17 @@ CmdPort(w, cmd) } } + /* Check for options that cannot operate on a non-edit cell label */ + if (nonEdit) + { + if ((option == PORT_MAKE) || (option == PORT_MAKEALL) || + (option == PORT_REMOVE) || (argc == 3)) + { + TxError("Cannot modify a port in an non-edit cell.\n"); + return; + } + } + /* Handle all command options */ switch (option) { From 770a6f4a1764866da34948d3864765cef6542b1f Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 6 May 2019 16:30:29 -0400 Subject: [PATCH 07/44] Updated the handling of fixed bounding boxes for abstract views (once corrected in an experimental branch but never merged). This avoids changing the actual bounding box of the cell to match the LEF bounding box, but defines a property instead and uses that property for certain functions such as displaying the bounding box outline or selecting the cell. This avoids certain related errors such as the failure to extract connections to areas outside of the fixed bounding box. --- commands/CmdCD.c | 21 +++++++++++++++- database/DBcellbox.c | 5 ---- database/DBcellsrch.c | 25 +++++++++++++++++++ database/DBio.c | 58 ++++++++++++++++--------------------------- lef/defRead.c | 20 ++++++++++++++- lef/lefRead.c | 42 +++++++++++++++++++------------ select/selDisplay.c | 27 ++++++++++++++++++-- 7 files changed, 136 insertions(+), 62 deletions(-) diff --git a/commands/CmdCD.c b/commands/CmdCD.c index 65db84f9..6cd842a0 100644 --- a/commands/CmdCD.c +++ b/commands/CmdCD.c @@ -3678,7 +3678,7 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx) Point childPoint, editPoint, rootPoint; CellDef *def, *rootDef, *editDef; bool hasChild, hasRoot, hasTrans; - Rect rootBox; + Rect rootBox, bbox; Transform *tx_cell, trans_cell; char **av; char *cellnameptr, *fullpathname; @@ -3792,6 +3792,25 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx) return FALSE; } + /* + * Get def's bounding box. If def is an abstract view with CDFIXEDBBOX + * set, then used the property FIXED_BBOX to set the bounding box. + */ + bbox = def->cd_bbox; + if (def->cd_flags & CDFIXEDBBOX) + { + char *propvalue; + bool found; + + propvalue = DBPropGet(def, "FIXED_BBOX", &found); + if (found) + { + if (sscanf(propvalue, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot, + &bbox.r_xtop, &bbox.r_ytop) != 4) + bbox = def->cd_bbox; + } + } + /* * Parse the remainder of the arguments to find out the reference * points in the child cell and the edit cell. Use the defaults diff --git a/database/DBcellbox.c b/database/DBcellbox.c index 6eb8d95d..db702aa5 100644 --- a/database/DBcellbox.c +++ b/database/DBcellbox.c @@ -616,11 +616,6 @@ dbReComputeBboxFunc(cellDef, boundProc, recurseProc) bool foundAny; int pNum; - /* Cells which declare their bounding box to be fixed */ - /* must return immediately. */ - - if (cellDef->cd_flags & CDFIXEDBBOX) return; - /* * Include area of subcells separately */ diff --git a/database/DBcellsrch.c b/database/DBcellsrch.c index a8fb9edc..5590f230 100644 --- a/database/DBcellsrch.c +++ b/database/DBcellsrch.c @@ -1810,6 +1810,31 @@ donecell: DBScalePoint(&cellDef->cd_extended.r_ll, scalen, scaled); DBScalePoint(&cellDef->cd_extended.r_ur, scalen, scaled); + /* If the cell is an abstract view with a fixed bounding box, then */ + /* adjust the bounding box property to match the new scale. */ + + if ((cellDef->cd_flags & CDFIXEDBBOX) != 0) + { + Rect r; + bool found; + char *propval; + + propval = (char *)DBPropGet(cellDef, "FIXED_BBOX", &found); + if (found) + { + if (sscanf(propval, "%d %d %d %d", &r.r_xbot, &r.r_ybot, + &r.r_xtop, &r.r_ytop) == 4) + { + DBScalePoint(&r.r_ll, scalen, scaled); + DBScalePoint(&r.r_ur, scalen, scaled); + + propval = (char *)mallocMagic(40); + sprintf(propval, "%d %d %d %d", r.r_xbot, r.r_ybot, + r.r_xtop, r.r_ytop); + DBPropPut(cellDef, "FIXED_BBOX", propval); + } + } + } return 0; } diff --git a/database/DBio.c b/database/DBio.c index 09ee7d7a..3f6aca45 100644 --- a/database/DBio.c +++ b/database/DBio.c @@ -1584,17 +1584,17 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled) if (!strcmp(propertyname, "GDS_FILE")) cellDef->cd_flags |= CDVENDORGDS; - /* Also process FIXED_BBOX property, but do not keep */ - /* the property, as it should be regenerated on cell */ - /* output from the current scale. */ + /* Also process FIXED_BBOX property, as units must match */ if (!strcmp(propertyname, "FIXED_BBOX")) { + Rect locbbox; + if (sscanf(propertyvalue, "%d %d %d %d", - &(cellDef->cd_bbox.r_xbot), - &(cellDef->cd_bbox.r_ybot), - &(cellDef->cd_bbox.r_xtop), - &(cellDef->cd_bbox.r_ytop)) != 4) + &(locbbox.r_xbot), + &(locbbox.r_ybot), + &(locbbox.r_xtop), + &(locbbox.r_ytop)) != 4) { TxError("Cannot read bounding box values in %s property", propertyname); @@ -1605,20 +1605,25 @@ dbReadProperties(cellDef, line, len, f, scalen, scaled) { if (scalen > 1) { - cellDef->cd_bbox.r_xbot *= scalen; - cellDef->cd_bbox.r_ybot *= scalen; - cellDef->cd_bbox.r_xtop *= scalen; - cellDef->cd_bbox.r_ytop *= scalen; + locbbox.r_xbot *= scalen; + locbbox.r_ybot *= scalen; + locbbox.r_xtop *= scalen; + locbbox.r_ytop *= scalen; } if (scaled > 1) { - cellDef->cd_bbox.r_xbot /= scaled; - cellDef->cd_bbox.r_ybot /= scaled; - cellDef->cd_bbox.r_xtop /= scaled; - cellDef->cd_bbox.r_ytop /= scaled; + locbbox.r_xbot /= scaled; + locbbox.r_ybot /= scaled; + locbbox.r_xtop /= scaled; + locbbox.r_ytop /= scaled; } - cellDef->cd_extended = cellDef->cd_bbox; cellDef->cd_flags |= CDFIXEDBBOX; + storedvalue = (char *)mallocMagic(40); + sprintf(storedvalue, "%d %d %d %d", + locbbox.r_xbot, locbbox.r_ybot, + locbbox.r_xtop, locbbox.r_ytop); + (void) DBPropPut(cellDef, propertyname, storedvalue); + } } else @@ -2538,27 +2543,6 @@ DBCellWriteFile(cellDef, f) DBPropEnum(cellDef, dbWritePropFunc, (ClientData)f); } - /* Fixed bounding box goes into a special property in output file */ - /* This is not kept internally as a property, so that it can be */ - /* read and written in the correct units without regard to internal */ - /* changes in scaling. */ - - if (cellDef->cd_flags & CDFIXEDBBOX) - { - // If there were no explicit properties, then we need to - // write the header - - if (cellDef->cd_props == (ClientData)NULL) - FPRINTF(f, "<< properties >>\n"); - - sprintf(lstring, "string FIXED_BBOX %d %d %d %d\n", - cellDef->cd_bbox.r_xbot / reducer, - cellDef->cd_bbox.r_ybot / reducer, - cellDef->cd_bbox.r_xtop / reducer, - cellDef->cd_bbox.r_ytop / reducer); - FPRINTF(f, lstring); - } - FPRINTF(f, "<< end >>\n"); if (fflush(f) == EOF || ferror(f)) diff --git a/lef/defRead.c b/lef/defRead.c index 370e3992..0b5e3261 100644 --- a/lef/defRead.c +++ b/lef/defRead.c @@ -577,7 +577,7 @@ DefReadLocation(use, f, oscale, tptr) float oscale; Transform *tptr; { - Rect *r, tr; + Rect *r, tr, rect; int keyword; char *token; float x, y; @@ -611,7 +611,25 @@ DefReadLocation(use, f, oscale, tptr) /* restore the lower-left corner position. */ if (use) + { r = &use->cu_def->cd_bbox; + + /* Abstract views with fixed bounding boxes use the FIXED_BBOX property */ + + if (use->cu_def->cd_flags & CDFIXEDBBOX) + { + char *propval; + bool found; + + propval = DBPropGet(use->cu_def, "FIXED_BBOX", &found); + if (found) + { + if (sscanf(propval, "%d %d %d %d", &rect.r_xbot, &rect.r_ybot, + &rect.r_xtop, &rect.r_ytop) == 4) + r = ▭ + } + } + } else r = &GeoNullRect; diff --git a/lef/lefRead.c b/lef/lefRead.c index d9986192..3904ade4 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -1370,7 +1370,7 @@ LefReadMacro(f, mname, oscale, importForeign) CellDef *lefMacro; HashEntry *he; - char *token, tsave[128]; + char *token, tsave[128], *propval; int keyword, pinNum; float x, y; bool has_size, is_imported = FALSE; @@ -1558,40 +1558,50 @@ origin_error: } /* Finish up creating the cell */ + DBReComputeBbox(lefMacro); if (is_imported) { - /* Redefine cell bounding box to match the LEF macro */ - /* Leave "extended" to mark the original bounding box */ + /* Define the FIXED_BBOX property to match the LEF macro */ if (has_size) { - lefMacro->cd_bbox = lefBBox; lefMacro->cd_flags |= CDFIXEDBBOX; + propval = (char *)mallocMagic(40); + sprintf(propval, "%d %d %d %d", + lefBBox.r_xbot, lefBBox.r_ybot, + lefBBox.r_xtop, lefBBox.r_ytop); + DBPropPut(lefMacro, "FIXED_BBOX", propval); } } else { DBAdjustLabelsNew(lefMacro, &TiPlaneRect, 1); - if (!has_size) + if (has_size) { - LefError(" Macro does not define size: computing from geometry\n"); - DBReComputeBbox(lefMacro); + lefMacro->cd_flags |= CDFIXEDBBOX; + propval = (char *)mallocMagic(40); + sprintf(propval, "%d %d %d %d", + lefBBox.r_xbot, lefBBox.r_ybot, + lefBBox.r_xtop, lefBBox.r_ytop); + DBPropPut(lefMacro, "FIXED_BBOX", propval); } else { - char *propstr = (char *)mallocMagic(64); - int reducer = DBCellFindScale(lefMacro); + LefError(" Macro does not define size: computing from geometry\n"); - lefMacro->cd_bbox = lefBBox; - lefMacro->cd_extended = lefBBox; + /* Set the placement bounding box property to the current bounding box */ + lefMacro->cd_flags |= CDFIXEDBBOX; + propval = (char *)mallocMagic(40); + sprintf(propval, "%d %d %d %d", + lefMacro->cd_bbox.r_xbot, + lefMacro->cd_bbox.r_ybot, + lefMacro->cd_bbox.r_xtop, + lefMacro->cd_bbox.r_ytop); + DBPropPut(lefMacro, "FIXED_BBOX", propval); + DRCCheckThis(lefMacro, TT_CHECKPAINT, &lefMacro->cd_bbox); } - - /* Fix the bounding box and do not allow edits */ - lefMacro->cd_flags |= /* CDNOEDIT | */ CDFIXEDBBOX; - - DRCCheckThis(lefMacro, TT_CHECKPAINT, &lefMacro->cd_bbox); } /* Note: The value here is ignored, setting to "TRUE". */ diff --git a/select/selDisplay.c b/select/selDisplay.c index 90b06233..aa84a2b1 100644 --- a/select/selDisplay.c +++ b/select/selDisplay.c @@ -307,11 +307,34 @@ selRedisplayCellFunc(scx, window) SearchContext *scx; /* Describes cell found. */ MagWindow *window; /* Window in which to redisplay. */ { - Rect tmp, screen; + Rect tmp, screen, bbox; Point p; char idName[100]; - GeoTransRect(&scx->scx_trans, &scx->scx_use->cu_def->cd_bbox, &tmp); + /* Selections of cells with a fixed bounding box flag show the outline */ + /* of the fixed bounding box, not the actual bounding box. */ + + if (scx->scx_use->cu_def->cd_flags & CDFIXEDBBOX) + { + bool found; + char *propval; + + propval = (char *)DBPropGet(scx->scx_use->cu_def, "FIXED_BBOX", &found); + if (found) + { + if (sscanf(propval, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot, + &bbox.r_xtop, &bbox.r_ytop) == 4) + GeoTransRect(&scx->scx_trans, &bbox, &tmp); + else + found = FALSE; + } + if (!found) + GeoTransRect(&scx->scx_trans, &scx->scx_use->cu_def->cd_bbox, &tmp); + } + else + { + GeoTransRect(&scx->scx_trans, &scx->scx_use->cu_def->cd_bbox, &tmp); + } if (!DBSrPaintArea((Tile *) NULL, selRedisplayPlane, &tmp, &DBAllButSpaceBits, selAlways1, (ClientData) NULL)) return 0; From f7d57c913c795046931782cf048b67293d98529b Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sat, 11 May 2019 15:09:01 -0400 Subject: [PATCH 08/44] Modified "def write" to prevent out-of-bounds array access when writing vias. However, the underlying problem, which is that stacked vias are not decomposed into their constituent parts, has not been addressed. A "-units" option was added to the "def write" command to force the units of the output file to be different than the default of 1000 (nanometers). No checks are made for whether values can be accurately represented at the specified scale. --- lef/defWrite.c | 30 ++++++++++++++++++------------ lef/lefCmd.c | 23 +++++++++++++++++++++-- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/lef/defWrite.c b/lef/defWrite.c index def222be..acd15a73 100644 --- a/lef/defWrite.c +++ b/lef/defWrite.c @@ -84,10 +84,11 @@ char *defGetType(); /* Forward declaration */ */ void -defWriteHeader(def, f, oscale) +defWriteHeader(def, f, oscale, units) CellDef *def; /* Def for which to generate DEF output */ FILE *f; /* Output to this file */ float oscale; + int units; /* Units for UNITS; could be derived from oscale */ { TileType type; @@ -113,10 +114,10 @@ defWriteHeader(def, f, oscale) /* technology). */ fprintf(f, " TECHNOLOGY %s ;\n", DBTechName); - /* As I understand it, this refers to the scalefactor of the GDS */ - /* file output. Magic does all GDS in nanometers, so the LEF */ - /* scalefactor (conversion to microns) is always 1000. */ - fprintf(f, " UNITS DISTANCE MICRONS 1000 ;\n"); + /* The DEF scalefactor (conversion to microns) is always 1000 */ + /* (nanometers) unless overridden on the command line. */ + + fprintf(f, " UNITS DISTANCE MICRONS %d ;\n", units); /* Die area, taken from the cell def bounding box. */ fprintf(f, " DIEAREA ( %.10g %.10g ) ( %.10g %.10g ) ;\n", @@ -1864,10 +1865,10 @@ defMakeInverseLayerMap() TileType i; char *lefname; - lefMagicToLefLayer = (LefMapping *)mallocMagic(DBNumUserLayers + lefMagicToLefLayer = (LefMapping *)mallocMagic(DBNumTypes * sizeof(LefMapping)); memset(lefMagicToLefLayer, 0, sizeof(LefMapping) * TT_TECHDEPBASE); - for (i = TT_TECHDEPBASE; i < DBNumUserLayers; i++) + for (i = TT_TECHDEPBASE; i < DBNumTypes; i++) { lefname = defGetType(i, &lefl); lefMagicToLefLayer[i].lefName = lefname; @@ -1916,23 +1917,28 @@ defMakeInverseLayerMap() */ void -DefWriteCell(def, outName, allSpecial) +DefWriteCell(def, outName, allSpecial, units) CellDef *def; /* Cell being written */ char *outName; /* Name of output file, or NULL. */ bool allSpecial; /* Treat all nets as SPECIALNETS? */ + int units; /* Force units to this value (default 1000) */ { char *filename; FILE *f; NetCount nets; int total; - float scale = CIFGetOutputScale(1); /* Note that "1" here corresponds - * to "1000" in the header UNITS line - */ + float scale; + LefMapping *lefMagicToLefLayer; int i; lefLayer *lefl; HashEntry *he; + /* Note that "1" corresponds to "1000" in the header UNITS line, */ + /* or units of nanometers. 10 = centimicrons, 1000 = microns. */ + + scale = CIFGetOutputScale(1000 / units); + f = lefFileOpen(def, outName, ".def", "w", &filename); TxPrintf("Generating DEF output %s for cell %s:\n", filename, def->cd_name); @@ -1949,7 +1955,7 @@ DefWriteCell(def, outName, allSpecial) return; } - defWriteHeader(def, f, scale); + defWriteHeader(def, f, scale, units); lefMagicToLefLayer = defMakeInverseLayerMap(); diff --git a/lef/lefCmd.c b/lef/lefCmd.c index 86e390cf..546988db 100644 --- a/lef/lefCmd.c +++ b/lef/lefCmd.c @@ -61,7 +61,7 @@ CmdLef(w, cmd) MagWindow *w; TxCommand *cmd; { - int option, i, cargs; + int option, i, cargs, units = 1000; /* Default nanometers */ char **msg, *namep; CellUse *selectedUse; CellDef *selectedDef; @@ -219,6 +219,25 @@ CmdLef(w, cmd) else TxPrintf("The \"-hide\" option is only for lef write\n"); } + else if (!strncmp(cmd->tx_argv[i], "-units", 5)) + { + if (is_lef) + TxPrintf("The \"-units\" option is only for def write\n"); + else + { + i++; + cargs--; + if ((cmd->tx_argc < i) || (!StrIsInt(cmd->tx_argv[i]))) + { + TxPrintf("The \"-units\" option requires an argument.\n"); + } + else + { + units = atoi(cmd->tx_argv[i]); + // To do: Check range of units + } + } + } else goto wrongNumArgs; cargs--; } @@ -236,7 +255,7 @@ CmdLef(w, cmd) else namep = cmd->tx_argv[2]; if (!is_lef) - DefWriteCell(selectedUse->cu_def, namep, allSpecial); + DefWriteCell(selectedUse->cu_def, namep, allSpecial, units); else LefWriteCell(selectedUse->cu_def, namep, selectedUse->cu_def == EditRootDef, lefTech, lefHide); From e2dd5f5157ce09de87f22b1403504e5ceb9b8f41 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 16 May 2019 09:52:59 -0400 Subject: [PATCH 09/44] Corrected the wiring command (adjustment to recent change for centering wires on grid lines when using a snap grid) so that the wire width is maintained when switching from one layer to another, when the wire width is larger than the minimum for the route layer. --- commands/CmdTZ.c | 2 +- wiring/wireOps.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/commands/CmdTZ.c b/commands/CmdTZ.c index af3467ec..3065450d 100644 --- a/commands/CmdTZ.c +++ b/commands/CmdTZ.c @@ -1411,7 +1411,7 @@ CmdWire(w, cmd) else { width = DRCGetDefaultLayerWidth(type); - WireAddContact(type, width); + WireAddContact(type, (WireWidth < width) ? width : WireWidth); } } else if (!strcmp(cmd->tx_argv[2], "width")) diff --git a/wiring/wireOps.c b/wiring/wireOps.c index 8c4de863..41a249cd 100644 --- a/wiring/wireOps.c +++ b/wiring/wireOps.c @@ -816,22 +816,22 @@ WireAddContact(newType, newWidth) switch (oldDir) { case GEO_NORTH: - i = contactArea.r_ytop - totalSize; + i = contactArea.r_ytop - WireWidth; if (i > contactArea.r_ybot) contactArea.r_ybot = i; break; case GEO_SOUTH: - i = contactArea.r_ybot + totalSize; + i = contactArea.r_ybot + WireWidth; if (i < contactArea.r_ytop) contactArea.r_ytop = i; break; case GEO_EAST: - i = contactArea.r_xtop - totalSize; + i = contactArea.r_xtop - WireWidth; if (i > contactArea.r_xbot) contactArea.r_xbot = i; break; case GEO_WEST: - i = contactArea.r_xbot + totalSize; + i = contactArea.r_xbot + WireWidth; if (i < contactArea.r_xtop) contactArea.r_xtop = i; break; From 704f1dc69f4ebbe8ab5d3ec47fc05a75449e3837 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 16 May 2019 17:41:42 -0400 Subject: [PATCH 10/44] Corrected an error that has been in the magic code forever, in which if a GDS (CIF) layer is dependent on, and only on, a templayer or layers that get hierarchically processed, it will not get added to the list of layers needing hierarchical processing, and therefore end up not being generated in the output. --- cif/CIFtech.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/cif/CIFtech.c b/cif/CIFtech.c index cdc5fcc7..ff9e2b03 100644 --- a/cif/CIFtech.c +++ b/cif/CIFtech.c @@ -1846,6 +1846,24 @@ CIFTechFinal() } } + /* Added by Tim, 5/16/19 */ + /* Layers that depend on hierarchically generated layers */ + /* (i.e., templayers) must themselves be hierarchically */ + /* processed. */ + + for (i = 0; i < style->cs_nLayers; i++) + { + TileTypeBitMask ourDepend, mmask; + + ourDepend = DBZeroTypeBits; + for (op = style->cs_layers[i]->cl_ops; op != NULL; op = op->co_next) + TTMaskSetMask(&ourDepend, &op->co_cifMask); + + TTMaskAndMask3(&mmask, &ourDepend, &style->cs_hierLayers); + if (!TTMaskIsZero(&mmask)) + TTMaskSetType(&style->cs_hierLayers, i); + } + /* Added by Tim, 10/18/04 */ /* Go through the layer operators looking for those that */ From 24786b208a0f078361cab4eb91f7eca3b1b2e383 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 22 May 2019 10:38:00 -0400 Subject: [PATCH 11/44] Corrected a badly-implemented search for electrical connectivity through labels with the same text (particularly necessary for abstract views, since the real connectivity may not be represented). The original implementation could generate very deep subroutine call stacks and lead to stack overflow. The new implementation performs the same check but without the deep nesting. --- database/DBconnect.c | 161 ++++++++++++++++++++++-------------------- defs.mak | 6 +- scripts/config.log | 20 +++--- scripts/config.status | 14 ++-- scripts/defs.mak | 6 +- 5 files changed, 108 insertions(+), 99 deletions(-) diff --git a/database/DBconnect.c b/database/DBconnect.c index ff007e5d..f1f5a6ab 100644 --- a/database/DBconnect.c +++ b/database/DBconnect.c @@ -689,30 +689,71 @@ dbcConnectLabelFunc(scx, lab, tpath, csa2) CellDef *orig_def = scx->scx_use->cu_def; Label *slab; int lidx = lab->lab_flags & PORT_NUM_MASK; + TileTypeBitMask *connectMask; /* Check for equivalent ports. For any found, call */ /* DBTreeSrTiles recursively on the type and area */ /* of the label. */ + /* Don't recurse, just add area to the csa2_list. */ + /* Only add the next label found to the list. If there */ + /* are more equivalent ports, they will be found when */ + /* processing this label's area. */ + for (slab = orig_def->cd_labels; slab != NULL; slab = slab->lab_next) if ((slab->lab_flags & PORT_DIR_MASK) && (slab != lab)) if ((slab->lab_flags & PORT_NUM_MASK) == lidx) { - SearchContext scx2 = *csa2->csa2_topscx; - TileTypeBitMask mask; + Rect newarea; + int pNum; // Do NOT go searching on labels connected to space! if (slab->lab_type == TT_SPACE) continue; - TTMaskSetOnlyType(&mask, slab->lab_type); - GeoTransRect(&scx->scx_trans, &slab->lab_rect, &scx2.scx_area); - // Expand search area by 1 to capture edge and point labels. - scx2.scx_area.r_xbot--; - scx2.scx_area.r_xtop++; - scx2.scx_area.r_ybot--; - scx2.scx_area.r_ytop++; - DBTreeSrTiles(&scx2, &mask, csa2->csa2_xMask, - dbcConnectFunc, (ClientData) csa2); + GeoTransRect(&scx->scx_trans, &slab->lab_rect, &newarea); + + // Avoid infinite looping. If material under the label + // has already been added to the destination, then ignore. + + connectMask = &csa2->csa2_connect[slab->lab_type]; + + pNum = DBPlane(slab->lab_type); + if (DBSrPaintArea((Tile *) NULL, def->cd_planes[pNum], + &newarea, connectMask, dbcUnconnectFunc, + (ClientData) NULL) == 1) + continue; + + newarea.r_xbot--; + newarea.r_xtop++; + newarea.r_ybot--; + newarea.r_ytop++; + + /* 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)); + memcpy((void *)newlist, (void *)csa2->csa2_list, + (size_t)lastsize * sizeof(conSrArea)); + 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 = 0; + + /* See above: Process only one equivalent port at a time */ + break; } } return 0; @@ -809,34 +850,12 @@ dbcConnectFunc(tile, cx) if (DBIsContact(loctype)) { -// TileType ctype; -// TileTypeBitMask *cMask, *rMask = DBResidueMask(loctype); - -// TTMaskSetOnlyType(¬ConnectMask, loctype); - /* Different contact types may share residues (6/18/04) */ /* Use TTMaskIntersect(), not TTMaskEqual()---types */ /* which otherwise stack may be in separate cells */ /* (12/1/05) */ -// 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); TTMaskZero(¬ConnectMask); TTMaskSetMask(¬ConnectMask, &DBNotConnectTbl[loctype]); @@ -864,43 +883,6 @@ dbcConnectFunc(tile, cx) &newarea, DBStdPaintTbl(loctype, pNum), (PaintUndoInfo *) NULL); - /* Check the source def for any labels belonging to this */ - /* tile area and plane, and add them to the destination. */ - - searchtype = TF_LABEL_ATTACH; - if (IsSplit(tile)) - { - /* If the tile is split, then labels attached to the */ - /* opposite point of the triangle are NOT connected. */ - - if (SplitSide(tile)) - { - if (SplitDirection(tile)) - searchtype |= TF_LABEL_ATTACH_NOT_SW; - else - searchtype |= TF_LABEL_ATTACH_NOT_NW; - } - else - { - if (SplitDirection(tile)) - searchtype |= TF_LABEL_ATTACH_NOT_NE; - else - searchtype |= TF_LABEL_ATTACH_NOT_SE; - } - } - - /* Note that the search must be done from the top since zero-size */ - /* port labels can be on any part of the hierarchy with no paint */ - /* underneath in its own cell to trigger the callback function. */ - - /* Copy information from top search context into new search context */ - scx2 = *csa2->csa2_topscx; - scx2.scx_area = newarea; - - DBTreeSrLabels(&scx2, connectMask, csa2->csa2_xMask, NULL, - searchtype, dbcConnectLabelFunc, - (ClientData) csa2); - /* 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 @@ -947,12 +929,6 @@ dbcConnectFunc(tile, cx) newlist = (conSrArea *)mallocMagic(csa2->csa2_size * sizeof(conSrArea)); memcpy((void *)newlist, (void *)csa2->csa2_list, (size_t)lastsize * 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; } @@ -1023,6 +999,7 @@ DBTreeCopyConnect(scx, mask, xMask, connect, area, destUse) struct conSrArg2 csa2; TileTypeBitMask *newmask; TileType newtype; + unsigned char searchtype; csa2.csa2_use = destUse; csa2.csa2_xMask = xMask; @@ -1052,6 +1029,38 @@ DBTreeCopyConnect(scx, mask, xMask, connect, area, destUse) (ClientData) &csa2); else DBTreeSrTiles(scx, newmask, xMask, dbcConnectFunc, (ClientData) &csa2); + + /* Check the source def for any labels belonging to this */ + /* tile area and plane, and add them to the destination. */ + + /* (This code previously in dbcConnectFunc, but moved to avoid */ + /* running the cell search from the top within another cell */ + /* search, which creates deep stacks and can trigger stack */ + /* overflow.) */ + + searchtype = TF_LABEL_ATTACH; + if (newtype & TT_DIAGONAL) + { + /* If the tile is split, then labels attached to the */ + /* opposite point of the triangle are NOT connected. */ + + if (newtype & TT_SIDE) + { + if (newtype & TT_DIRECTION) + searchtype |= TF_LABEL_ATTACH_NOT_SW; + else + searchtype |= TF_LABEL_ATTACH_NOT_NW; + } + else + { + if (newtype & TT_DIRECTION) + searchtype |= TF_LABEL_ATTACH_NOT_NE; + else + searchtype |= TF_LABEL_ATTACH_NOT_SE; + } + } + DBTreeSrLabels(scx, newmask, xMask, NULL, searchtype, + dbcConnectLabelFunc, (ClientData) &csa2); } freeMagic((char *)csa2.csa2_list); diff --git a/defs.mak b/defs.mak index a18d3130..c3bb2089 100644 --- a/defs.mak +++ b/defs.mak @@ -62,16 +62,16 @@ LIB_SPECS_NOSTUB = -L/usr/lib64 -ltk8.6 -L/usr/lib64 -ltcl8.6 WISH_EXE = /usr/bin/wish TCL_LIB_DIR = /usr/lib MAGIC_VERSION = 8.2 -MAGIC_REVISION = 53 +MAGIC_REVISION = 101 CC = gcc CPP = gcc -E CXX = g++ CPPFLAGS = -I. -I${MAGICDIR} -DFLAGS = -DCAD_DIR=\"${LIBDIR}\" -DBIN_DIR=\"${BINDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DUSE_TCL_STUBS -DUSE_TK_STUBS -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DMAGIC_VERSION=\"8.2\" -DMAGIC_REVISION=\"53\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_PATHS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DFILE_LOCKS=1 -DCALMA_MODULE=1 -DCIF_MODULE=1 -DPLOT_MODULE=1 -DLEF_MODULE=1 -DROUTE_MODULE=1 -DUSE_NEW_MACROS=1 -DHAVE_LIBGL=1 -DHAVE_LIBGLU=1 -DVECTOR_FONTS=1 -DHAVE_LIBCAIRO=1 -DMAGIC_WRAPPER=1 -DTHREE_D=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DGCORE=\"/bin/gcore\" +DFLAGS = -DCAD_DIR=\"${LIBDIR}\" -DBIN_DIR=\"${BINDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DUSE_TCL_STUBS -DUSE_TK_STUBS -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DMAGIC_VERSION=\"8.2\" -DMAGIC_REVISION=\"101\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_PATHS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DFILE_LOCKS=1 -DCALMA_MODULE=1 -DCIF_MODULE=1 -DPLOT_MODULE=1 -DLEF_MODULE=1 -DROUTE_MODULE=1 -DUSE_NEW_MACROS=1 -DHAVE_LIBGL=1 -DHAVE_LIBGLU=1 -DVECTOR_FONTS=1 -DHAVE_LIBCAIRO=1 -DMAGIC_WRAPPER=1 -DTHREE_D=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DGCORE=\"/bin/gcore\" DFLAGS += -DSHDLIB_EXT=\".so\" -DNDEBUG -DFLAGS_NOSTUB = -DCAD_DIR=\"${LIBDIR}\" -DBIN_DIR=\"${BINDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DMAGIC_VERSION=\"8.2\" -DMAGIC_REVISION=\"53\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_PATHS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DFILE_LOCKS=1 -DCALMA_MODULE=1 -DCIF_MODULE=1 -DPLOT_MODULE=1 -DLEF_MODULE=1 -DROUTE_MODULE=1 -DUSE_NEW_MACROS=1 -DHAVE_LIBGL=1 -DHAVE_LIBGLU=1 -DVECTOR_FONTS=1 -DHAVE_LIBCAIRO=1 -DMAGIC_WRAPPER=1 -DTHREE_D=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DGCORE=\"/bin/gcore\" +DFLAGS_NOSTUB = -DCAD_DIR=\"${LIBDIR}\" -DBIN_DIR=\"${BINDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DMAGIC_VERSION=\"8.2\" -DMAGIC_REVISION=\"101\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_PATHS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DFILE_LOCKS=1 -DCALMA_MODULE=1 -DCIF_MODULE=1 -DPLOT_MODULE=1 -DLEF_MODULE=1 -DROUTE_MODULE=1 -DUSE_NEW_MACROS=1 -DHAVE_LIBGL=1 -DHAVE_LIBGLU=1 -DVECTOR_FONTS=1 -DHAVE_LIBCAIRO=1 -DMAGIC_WRAPPER=1 -DTHREE_D=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DGCORE=\"/bin/gcore\" DFLAGS_NOSTUB += -DSHDLIB_EXT=\".so\" -DNDEBUG CFLAGS = -g -m64 -fPIC -Wimplicit-int -fPIC diff --git a/scripts/config.log b/scripts/config.log index bef74eaf..1c3c70ad 100644 --- a/scripts/config.log +++ b/scripts/config.log @@ -125,7 +125,7 @@ configure: failed program was: | #define PACKAGE_BUGREPORT "" | #define PACKAGE_URL "" | #define MAGIC_VERSION "8.2" -| #define MAGIC_REVISION "53" +| #define MAGIC_REVISION "101" | /* end confdefs.h. */ | #include configure:3476: result: gcc -E @@ -146,7 +146,7 @@ configure: failed program was: | #define PACKAGE_BUGREPORT "" | #define PACKAGE_URL "" | #define MAGIC_VERSION "8.2" -| #define MAGIC_REVISION "53" +| #define MAGIC_REVISION "101" | /* end confdefs.h. */ | #include configure:3596: checking for g++ @@ -302,7 +302,7 @@ configure: failed program was: | #define PACKAGE_BUGREPORT "" | #define PACKAGE_URL "" | #define MAGIC_VERSION "8.2" -| #define MAGIC_REVISION "53" +| #define MAGIC_REVISION "101" | #define STDC_HEADERS 1 | #define HAVE_SYS_TYPES_H 1 | #define HAVE_SYS_STAT_H 1 @@ -343,7 +343,7 @@ configure: failed program was: | #define PACKAGE_BUGREPORT "" | #define PACKAGE_URL "" | #define MAGIC_VERSION "8.2" -| #define MAGIC_REVISION "53" +| #define MAGIC_REVISION "101" | #define STDC_HEADERS 1 | #define HAVE_SYS_TYPES_H 1 | #define HAVE_SYS_STAT_H 1 @@ -433,7 +433,7 @@ configure: failed program was: | #define PACKAGE_BUGREPORT "" | #define PACKAGE_URL "" | #define MAGIC_VERSION "8.2" -| #define MAGIC_REVISION "53" +| #define MAGIC_REVISION "101" | #define STDC_HEADERS 1 | #define HAVE_SYS_TYPES_H 1 | #define HAVE_SYS_STAT_H 1 @@ -506,7 +506,7 @@ configure: failed program was: | #define PACKAGE_BUGREPORT "" | #define PACKAGE_URL "" | #define MAGIC_VERSION "8.2" -| #define MAGIC_REVISION "53" +| #define MAGIC_REVISION "101" | #define STDC_HEADERS 1 | #define HAVE_SYS_TYPES_H 1 | #define HAVE_SYS_STAT_H 1 @@ -634,7 +634,7 @@ configure:7575: checking for cairo_user_to_device in -lcairo configure:7600: gcc -o conftest -g -lm conftest.c -lcairo -lGLU -lGL >&5 configure:7600: $? = 0 configure:7609: result: yes -configure:8414: creating ./config.status +configure:8417: creating ./config.status ## ---------------------- ## ## Running config.status. ## @@ -759,7 +759,7 @@ CPPFLAGS='' CSH='/bin/csh' CXX='g++' CXXFLAGS='-g -O2' -DEFS='-DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DMAGIC_VERSION=\"8.2\" -DMAGIC_REVISION=\"53\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_PATHS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DFILE_LOCKS=1 -DCALMA_MODULE=1 -DCIF_MODULE=1 -DPLOT_MODULE=1 -DLEF_MODULE=1 -DROUTE_MODULE=1 -DUSE_NEW_MACROS=1 -DHAVE_LIBGL=1 -DHAVE_LIBGLU=1 -DVECTOR_FONTS=1 -DHAVE_LIBCAIRO=1 -DMAGIC_WRAPPER=1 -DTHREE_D=1 -Dlinux=1 -DSYSV=1 -DISC=1' +DEFS='-DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DMAGIC_VERSION=\"8.2\" -DMAGIC_REVISION=\"101\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_PATHS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DFILE_LOCKS=1 -DCALMA_MODULE=1 -DCIF_MODULE=1 -DPLOT_MODULE=1 -DLEF_MODULE=1 -DROUTE_MODULE=1 -DUSE_NEW_MACROS=1 -DHAVE_LIBGL=1 -DHAVE_LIBGLU=1 -DVECTOR_FONTS=1 -DHAVE_LIBCAIRO=1 -DMAGIC_WRAPPER=1 -DTHREE_D=1 -Dlinux=1 -DSYSV=1 -DISC=1' DEPEND_FLAG='-MM' ECHO_C='' ECHO_N='printf' @@ -784,7 +784,7 @@ LIB_SPECS=' -L/usr/lib64 -ltkstub8.6 -L/usr/lib64 -ltclstub8.6' LIB_SPECS_NOSTUB=' -L/usr/lib64 -ltk8.6 -L/usr/lib64 -ltcl8.6' LTLIBOBJS='' M4='/bin/m4' -MAGIC_REVISION='53' +MAGIC_REVISION='101' MAGIC_VERSION='8.2' MCPP='${MAGICDIR}/scripts/preproc.py' OA='' @@ -886,7 +886,7 @@ unused=' readline lisp' #define PACKAGE_BUGREPORT "" #define PACKAGE_URL "" #define MAGIC_VERSION "8.2" -#define MAGIC_REVISION "53" +#define MAGIC_REVISION "101" #define STDC_HEADERS 1 #define HAVE_SYS_TYPES_H 1 #define HAVE_SYS_STAT_H 1 diff --git a/scripts/config.status b/scripts/config.status index a51e5746..d8bc0035 100755 --- a/scripts/config.status +++ b/scripts/config.status @@ -427,7 +427,7 @@ Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." -ac_pwd='/home/tim/gitsrc/magic-8.2/scripts' +ac_pwd='/home/tim/gitsrc/magic/scripts' srcdir='..' INSTALL='/bin/install -c' test -n "$AWK" || AWK=awk @@ -588,7 +588,7 @@ S["INSTALL_TARGET"]="install-tcl" S["ALL_TARGET"]="tcl" S["OA_LIBS"]="" S["OA"]="" -S["MAGIC_REVISION"]="53" +S["MAGIC_REVISION"]="101" S["MAGIC_VERSION"]="8.2" S["SCPP"]="gcc -E -x c" S["MCPP"]="${MAGICDIR}/scripts/preproc.py" @@ -676,11 +676,11 @@ S["ECHO_T"]="" S["ECHO_N"]="-n" S["ECHO_C"]="" S["DEFS"]="-DPACKAGE_NAME=\\\"\\\" -DPACKAGE_TARNAME=\\\"\\\" -DPACKAGE_VERSION=\\\"\\\" -DPACKAGE_STRING=\\\"\\\" -DPACKAGE_BUGREPORT=\\\"\\\" -DPACKAGE_URL=\\\"\\\" -DMAGIC_VERSION="\ -"\\\"8.2\\\" -DMAGIC_REVISION=\\\"53\\\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHA"\ -"VE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_U"\ -"NSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_PATHS_H=1 -DHAVE"\ -"_VA_COPY=1 -DHAVE___VA_COPY=1 -DFILE_LOCKS=1 -DCALMA_MODULE=1 -DCIF_MODULE=1 -DPLOT_MODULE=1 -DLEF_MODULE=1 -DROUTE_MODULE=1 -DUSE_NEW_MACROS=1 -DHA"\ -"VE_LIBGL=1 -DHAVE_LIBGLU=1 -DVECTOR_FONTS=1 -DHAVE_LIBCAIRO=1 -DMAGIC_WRAPPER=1 -DTHREE_D=1 -Dlinux=1 -DSYSV=1 -DISC=1" +"\\\"8.2\\\" -DMAGIC_REVISION=\\\"101\\\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DH"\ +"AVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_"\ +"UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_PATHS_H=1 -DHAV"\ +"E_VA_COPY=1 -DHAVE___VA_COPY=1 -DFILE_LOCKS=1 -DCALMA_MODULE=1 -DCIF_MODULE=1 -DPLOT_MODULE=1 -DLEF_MODULE=1 -DROUTE_MODULE=1 -DUSE_NEW_MACROS=1 -DH"\ +"AVE_LIBGL=1 -DHAVE_LIBGLU=1 -DVECTOR_FONTS=1 -DHAVE_LIBCAIRO=1 -DMAGIC_WRAPPER=1 -DTHREE_D=1 -Dlinux=1 -DSYSV=1 -DISC=1" S["mandir"]="${datarootdir}/man" S["localedir"]="${datarootdir}/locale" S["libdir"]="${exec_prefix}/lib" diff --git a/scripts/defs.mak b/scripts/defs.mak index a18d3130..c3bb2089 100644 --- a/scripts/defs.mak +++ b/scripts/defs.mak @@ -62,16 +62,16 @@ LIB_SPECS_NOSTUB = -L/usr/lib64 -ltk8.6 -L/usr/lib64 -ltcl8.6 WISH_EXE = /usr/bin/wish TCL_LIB_DIR = /usr/lib MAGIC_VERSION = 8.2 -MAGIC_REVISION = 53 +MAGIC_REVISION = 101 CC = gcc CPP = gcc -E CXX = g++ CPPFLAGS = -I. -I${MAGICDIR} -DFLAGS = -DCAD_DIR=\"${LIBDIR}\" -DBIN_DIR=\"${BINDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DUSE_TCL_STUBS -DUSE_TK_STUBS -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DMAGIC_VERSION=\"8.2\" -DMAGIC_REVISION=\"53\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_PATHS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DFILE_LOCKS=1 -DCALMA_MODULE=1 -DCIF_MODULE=1 -DPLOT_MODULE=1 -DLEF_MODULE=1 -DROUTE_MODULE=1 -DUSE_NEW_MACROS=1 -DHAVE_LIBGL=1 -DHAVE_LIBGLU=1 -DVECTOR_FONTS=1 -DHAVE_LIBCAIRO=1 -DMAGIC_WRAPPER=1 -DTHREE_D=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DGCORE=\"/bin/gcore\" +DFLAGS = -DCAD_DIR=\"${LIBDIR}\" -DBIN_DIR=\"${BINDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DUSE_TCL_STUBS -DUSE_TK_STUBS -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DMAGIC_VERSION=\"8.2\" -DMAGIC_REVISION=\"101\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_PATHS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DFILE_LOCKS=1 -DCALMA_MODULE=1 -DCIF_MODULE=1 -DPLOT_MODULE=1 -DLEF_MODULE=1 -DROUTE_MODULE=1 -DUSE_NEW_MACROS=1 -DHAVE_LIBGL=1 -DHAVE_LIBGLU=1 -DVECTOR_FONTS=1 -DHAVE_LIBCAIRO=1 -DMAGIC_WRAPPER=1 -DTHREE_D=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DGCORE=\"/bin/gcore\" DFLAGS += -DSHDLIB_EXT=\".so\" -DNDEBUG -DFLAGS_NOSTUB = -DCAD_DIR=\"${LIBDIR}\" -DBIN_DIR=\"${BINDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DMAGIC_VERSION=\"8.2\" -DMAGIC_REVISION=\"53\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_PATHS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DFILE_LOCKS=1 -DCALMA_MODULE=1 -DCIF_MODULE=1 -DPLOT_MODULE=1 -DLEF_MODULE=1 -DROUTE_MODULE=1 -DUSE_NEW_MACROS=1 -DHAVE_LIBGL=1 -DHAVE_LIBGLU=1 -DVECTOR_FONTS=1 -DHAVE_LIBCAIRO=1 -DMAGIC_WRAPPER=1 -DTHREE_D=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DGCORE=\"/bin/gcore\" +DFLAGS_NOSTUB = -DCAD_DIR=\"${LIBDIR}\" -DBIN_DIR=\"${BINDIR}\" -DTCL_DIR=\"${TCLDIR}\" -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DMAGIC_VERSION=\"8.2\" -DMAGIC_REVISION=\"101\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_VOID_P=8 -DSIZEOF_UNSIGNED_INT=4 -DSIZEOF_UNSIGNED_LONG=8 -DSIZEOF_UNSIGNED_LONG_LONG=8 -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_DIRENT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_PATHS_H=1 -DHAVE_VA_COPY=1 -DHAVE___VA_COPY=1 -DFILE_LOCKS=1 -DCALMA_MODULE=1 -DCIF_MODULE=1 -DPLOT_MODULE=1 -DLEF_MODULE=1 -DROUTE_MODULE=1 -DUSE_NEW_MACROS=1 -DHAVE_LIBGL=1 -DHAVE_LIBGLU=1 -DVECTOR_FONTS=1 -DHAVE_LIBCAIRO=1 -DMAGIC_WRAPPER=1 -DTHREE_D=1 -Dlinux=1 -DSYSV=1 -DISC=1 -DGCORE=\"/bin/gcore\" DFLAGS_NOSTUB += -DSHDLIB_EXT=\".so\" -DNDEBUG CFLAGS = -g -m64 -fPIC -Wimplicit-int -fPIC From ec8ffe73334f6a40f4f175bc27a5193bd3ec45bf Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 22 May 2019 14:24:44 -0400 Subject: [PATCH 12/44] Corrected an error in the GDS read routine which attempts to kill a hash table that was never initialized, if the GDS file input reader encounters an error in the GDS data. --- calma/CalmaRdcl.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/calma/CalmaRdcl.c b/calma/CalmaRdcl.c index 353a4d45..5fb77f31 100644 --- a/calma/CalmaRdcl.c +++ b/calma/CalmaRdcl.c @@ -288,6 +288,7 @@ calmaParseStructure(filename) int mfactor; off_t filepos; bool was_called; + bool was_initialized; CellDef *def; /* Make sure this is a structure; if not, let the caller know we're done */ @@ -296,7 +297,8 @@ calmaParseStructure(filename) return (FALSE); /* Read the structure name */ - if (!calmaSkipExact(CALMA_BGNSTR)) goto syntaxerror;; + was_initialized = FALSE; + if (!calmaSkipExact(CALMA_BGNSTR)) goto syntaxerror; if (!calmaReadStringRecord(CALMA_STRNAME, &strname)) goto syntaxerror; TxPrintf("Reading \"%s\".\n", strname); @@ -354,6 +356,7 @@ calmaParseStructure(filename) /* Initialize the hash table for layer errors */ HashInit(&calmaLayerHash, 32, sizeof (CalmaLayerType) / sizeof (unsigned)); + was_initialized = TRUE; /* Body of structure: a sequence of elements */ osrefs = nsrefs = 0; @@ -466,7 +469,7 @@ done: /* Syntax error: skip to CALMA_ENDSTR */ syntaxerror: - HashKill(&calmaLayerHash); + if (was_initialized == TRUE) HashKill(&calmaLayerHash); return (calmaSkipTo(CALMA_ENDSTR)); } From 243e9652e52712129125dad104515ec1cb44768a Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 22 May 2019 16:12:13 -0400 Subject: [PATCH 13/44] Added information to the GDS read routine error output to indicate the byte position of the error. --- calma/CalmaRead.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/calma/CalmaRead.c b/calma/CalmaRead.c index 25c5e3aa..1ddd00a8 100644 --- a/calma/CalmaRead.c +++ b/calma/CalmaRead.c @@ -353,25 +353,31 @@ 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; { + off_t filepos; + calmaTotalErrors++; if (CIFWarningLevel == CIF_WARN_NONE) return; if ((calmaTotalErrors < 100) || (CIFWarningLevel != CIF_WARN_LIMIT)) { + filepos = ftello(calmaInputFile); if (CIFWarningLevel == CIF_WARN_REDIRECT) { if (calmaErrorFile != NULL) { - fprintf(calmaErrorFile, "Error while reading cell \"%s\": ", + fprintf(calmaErrorFile, "Error while reading cell \"%s\" ", cifReadCellDef->cd_name); + fprintf(calmaErrorFile, "(byte position %"DLONG_PREFIX"ld): ", + (dlong)filepos); fprintf(calmaErrorFile, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); } } else { - TxError("Error while reading cell \"%s\": ", cifReadCellDef->cd_name); + TxError("Error while reading cell \"%s\" ", cifReadCellDef->cd_name); + TxError("(byte position %"DLONG_PREFIX"d): ", (dlong)filepos); TxError(format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); } } From 30a2226dbb7913ae5f4494aa7879b6d1d1d0bf69 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 22 May 2019 16:52:34 -0400 Subject: [PATCH 14/44] Corrected a problem in CalmaWrite where a cell that was defined redundantly was flagged, and output anyway, but the cellname was not being written to the output, resulting in a bad GDS file. --- calma/CalmaWrite.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/calma/CalmaWrite.c b/calma/CalmaWrite.c index e782005d..7879ecb1 100644 --- a/calma/CalmaWrite.c +++ b/calma/CalmaWrite.c @@ -404,6 +404,8 @@ calmaDumpStructure(def, cellstart, outf, calmaDefHash, filename) { /* Structure is defined more than once */ TxError("Structure %s defined redundantly in GDS\n", strname); + /* To be considered: Should the structure be output more than once? */ + calmaOutStringRecord(CALMA_STRNAME, newnameptr, outf); } else if (!strcmp(strname, def->cd_name)) { From a56309fdb6f50d4c817a89fa45964110023224c8 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 22 May 2019 17:03:52 -0400 Subject: [PATCH 15/44] Additional change to CalmaWrite: when handling cellnames with lengths exceeding the maximum GDS name length (32 characters), truncate by removing all but the last 32 characters, instead of the previous behavior which was to remove all but the first 32 characters. The last 32 characters are far more likely to be unique than the first 32, given that the usual reason for extra- long names is the concatentation of hierarchical names. --- calma/CalmaWrite.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/calma/CalmaWrite.c b/calma/CalmaWrite.c index 7879ecb1..44e0d6d9 100644 --- a/calma/CalmaWrite.c +++ b/calma/CalmaWrite.c @@ -2757,16 +2757,17 @@ calmaOutStringRecord(type, str, f) /* * Make sure length is even. * Output at most CALMANAMELENGTH characters. + * If the name is longer than CALMANAMELENGTH, then output the + * last CALMANAMELENGTH characters (since cell names are more + * likely to be unique in the last characters than in the first + * characters). */ if (len & 01) len++; if (len > CALMANAMELENGTH) { - char csav; TxError("Warning: Cellname %s truncated ", str); - csav = *(str + 32); - *(str + 32) = '\0'; - TxError("to %32s (GDS format limit)\n", str); - *(str + 32) = csav; + TxError("to %s (GDS format limit)\n", str + len - CALMANAMELENGTH); + locstr = str + len - CALMANAMELENGTH; len = CALMANAMELENGTH; } calmaOutI2(len+4, f); /* Record length */ From b098fbbfbb8a2206a1893cc9f2a155f67088c360 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 28 May 2019 17:14:24 -0400 Subject: [PATCH 16/44] Modified the "def write" routine to strip any path component off of a cell name (although cell names are not supposed to have path components, so need to find out where they came from. . .). --- lef/defWrite.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lef/defWrite.c b/lef/defWrite.c index acd15a73..b9353d5b 100644 --- a/lef/defWrite.c +++ b/lef/defWrite.c @@ -1821,6 +1821,7 @@ defComponentFunc(cellUse, defdata) { FILE *f = defdata->f; float oscale = defdata->scale; + char *nameroot; /* Ignore any cellUse that does not have an identifier string. */ if (cellUse->cu_id == NULL) return 0; @@ -1831,8 +1832,17 @@ defComponentFunc(cellUse, defdata) return 0; } + /* In case the cd_name contains a path component (it's not supposed to), */ + /* remove it. */ + + nameroot = strrchr(cellUse->cu_def->cd_name, '/'); + if (nameroot != NULL) + nameroot++; + else + nameroot = cellUse->cu_def->cd_name; + fprintf(f, " - %s %s\n + PLACED ( %.10g %.10g ) %s ;\n", - cellUse->cu_id, cellUse->cu_def->cd_name, + cellUse->cu_id, nameroot, (float)cellUse->cu_bbox.r_xbot * oscale, (float)cellUse->cu_bbox.r_ybot * oscale, defTransPos(&cellUse->cu_transform)); From e4bfe864ba9e3a351313dbb228f143be56d9dd91 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 4 Jun 2019 09:15:56 -0400 Subject: [PATCH 17/44] Modified the techfile "wiring" section to allow a scalefactor with the same interpretation as the scalefactor for the DRC section: Values in the section are interpreted as lambda divided by the scalefactor. That allows the wiring values to be real units such as nanometers and avoid problems with fractional lambda values. --- wiring/wireInt.h | 1 + wiring/wireOps.c | 42 +++++++++++++++++++++--------------------- wiring/wireTech.c | 17 +++++++++++++++++ 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/wiring/wireInt.h b/wiring/wireInt.h index ed5d5b4f..68a3c5c8 100644 --- a/wiring/wireInt.h +++ b/wiring/wireInt.h @@ -30,6 +30,7 @@ extern TileType WireType; extern int WireWidth; extern int WireLastDir; +extern int WireUnits; /* Undo procedure: */ diff --git a/wiring/wireOps.c b/wiring/wireOps.c index 41a249cd..57fb40e5 100644 --- a/wiring/wireOps.c +++ b/wiring/wireOps.c @@ -768,19 +768,19 @@ WireAddContact(newType, newWidth) if ((contact->con_layer1 == oldType) && (contact->con_layer2 == WireType)) { - oldOverlap = contact->con_surround1; - newOverlap = contact->con_surround2; - oldExtend = contact->con_extend1; - newExtend = contact->con_extend2; + oldOverlap = contact->con_surround1 / WireUnits; + newOverlap = contact->con_surround2 / WireUnits; + oldExtend = contact->con_extend1 / WireUnits; + newExtend = contact->con_extend2 / WireUnits; goto gotContact; } if ((contact->con_layer2 == oldType) && (contact->con_layer1 == WireType)) { - oldOverlap = contact->con_surround2; - newOverlap = contact->con_surround1; - oldExtend = contact->con_extend2; - newExtend = contact->con_extend1; + oldOverlap = contact->con_surround2 / WireUnits; + newOverlap = contact->con_surround1 / WireUnits; + oldExtend = contact->con_extend2 / WireUnits; + newExtend = contact->con_extend1 / WireUnits; goto gotContact; } } @@ -798,7 +798,7 @@ WireAddContact(newType, newWidth) */ gotContact: - totalSize = contact->con_size + 2 * oldOverlap; + totalSize = (contact->con_size / WireUnits) + 2 * oldOverlap; contactArea = oldLeg; if ((contactArea.r_xtop - contactArea.r_xbot) < totalSize) { @@ -848,7 +848,7 @@ WireAddContact(newType, newWidth) { TTMaskSetOnlyType(&mask, contact->con_layer1); TTMaskSetType(&allmask, contact->con_layer1); - GEO_EXPAND(&tmp, contact->con_surround1, &tmp2); + GEO_EXPAND(&tmp, contact->con_surround1 / WireUnits, &tmp2); (void) GeoInclude(&tmp2, &editArea); DBPaintValid(EditCellUse->cu_def, &tmp2, &mask, 0); } @@ -856,7 +856,7 @@ WireAddContact(newType, newWidth) { TTMaskSetOnlyType(&mask, contact->con_layer2); TTMaskSetType(&allmask, contact->con_layer2); - GEO_EXPAND(&tmp, contact->con_surround2, &tmp2); + GEO_EXPAND(&tmp, contact->con_surround2 / WireUnits, &tmp2); (void) GeoInclude(&tmp2, &editArea); DBPaintValid(EditCellUse->cu_def, &tmp2, &mask, 0); } @@ -869,13 +869,13 @@ WireAddContact(newType, newWidth) { case GEO_NORTH: case GEO_SOUTH: - tmp2.r_ybot -= contact->con_extend1; - tmp2.r_ytop += contact->con_extend1; + tmp2.r_ybot -= contact->con_extend1 / WireUnits; + tmp2.r_ytop += contact->con_extend1 / WireUnits; break; case GEO_EAST: case GEO_WEST: - tmp2.r_xbot -= contact->con_extend1; - tmp2.r_xtop += contact->con_extend1; + tmp2.r_xbot -= contact->con_extend1 / WireUnits; + tmp2.r_xtop += contact->con_extend1 / WireUnits; break; } (void) GeoInclude(&tmp2, &editArea); @@ -890,13 +890,13 @@ WireAddContact(newType, newWidth) { case GEO_NORTH: case GEO_SOUTH: - tmp2.r_xbot -= contact->con_extend2; - tmp2.r_xtop += contact->con_extend2; + tmp2.r_xbot -= contact->con_extend2 / WireUnits; + tmp2.r_xtop += contact->con_extend2 / WireUnits; break; case GEO_EAST: case GEO_WEST: - tmp2.r_ybot -= contact->con_extend2; - tmp2.r_ytop += contact->con_extend2; + tmp2.r_ybot -= contact->con_extend2 / WireUnits; + tmp2.r_ytop += contact->con_extend2 / WireUnits; break; } (void) GeoInclude(&tmp2, &editArea); @@ -923,13 +923,13 @@ WireAddContact(newType, newWidth) SelectArea(&scx, &mask, 0); if (contact->con_surround1 != 0) { - GEO_EXPAND(&tmp, contact->con_surround1, &scx.scx_area); + GEO_EXPAND(&tmp, contact->con_surround1 / WireUnits, &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); + GEO_EXPAND(&tmp, contact->con_surround2 / WireUnits, &scx.scx_area); TTMaskSetOnlyType(&mask, contact->con_layer2); SelectArea(&scx, &mask, 0); } diff --git a/wiring/wireTech.c b/wiring/wireTech.c index a857080b..7f49e9a9 100644 --- a/wiring/wireTech.c +++ b/wiring/wireTech.c @@ -37,6 +37,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ /* Linked list to store contact information collected by this module: */ Contact *WireContacts; +int WireUnits; // Units per lambda for wiring sizes /* @@ -65,6 +66,7 @@ WireTechInit() freeMagic((char *) WireContacts); WireContacts = WireContacts->con_next; } + WireUnits = 1; } /* @@ -93,6 +95,21 @@ WireTechLine(sectionName, argc, argv) Contact *new; int hasExtend = 0; + if (!strcmp(argv[0], "scalefactor")) + { + if (argc != 2) + { + TechError("\"scalefactor\" line must have exactly 2 arguments.\n"); + return TRUE; + } + if (!StrIsInt(argv[1])) + { + TechError("\"scalefactor\" argument must be an integer.\n"); + return TRUE; + } + WireUnits = atoi(argv[1]); + } + if (strcmp(argv[0], "contact") != 0) { TechError("Unknown wiring keyword: %s. Line ignored.\n", argv[0]); From 8170dbe01f9f7af2e0f6dd0a2f3c5025394eed33 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 4 Jun 2019 12:13:47 -0400 Subject: [PATCH 18/44] Additional corrections to the wiring for some code changes that were made where contacts are placed when shifting up on metal layer but not made for the reverse case. Also corrected one inconsistency with non-minimum width wires. --- commands/CmdTZ.c | 4 +- wiring/wireOps.c | 135 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 104 insertions(+), 35 deletions(-) diff --git a/commands/CmdTZ.c b/commands/CmdTZ.c index 3065450d..36969938 100644 --- a/commands/CmdTZ.c +++ b/commands/CmdTZ.c @@ -1348,7 +1348,7 @@ CmdWire(w, cmd) case DECREMENT: if (cmd->tx_argc != 3 && cmd->tx_argc != 4) goto badargs; - if (!strcmp(cmd->tx_argv[2], "type")) + if (!strcmp(cmd->tx_argv[2], "type") || !strcmp(cmd->tx_argv[2], "layer")) { Contact *contact; type = TT_SPACE; @@ -1371,7 +1371,7 @@ CmdWire(w, cmd) else { width = DRCGetDefaultLayerWidth(type); - WireAddContact(type, width); + WireAddContact(type, (WireWidth < width) ? width : WireWidth); } } else if (!strcmp(cmd->tx_argv[2], "width")) diff --git a/wiring/wireOps.c b/wiring/wireOps.c index 57fb40e5..5a9e09b0 100644 --- a/wiring/wireOps.c +++ b/wiring/wireOps.c @@ -706,6 +706,9 @@ WireShowLeg() * ---------------------------------------------------------------------------- */ +#define WIRING_CONTACT_UP 1 +#define WIRING_CONTACT_DOWN 0 + void WireAddContact(newType, newWidth) TileType newType; /* New type of material to use for wiring. @@ -723,8 +726,9 @@ WireAddContact(newType, newWidth) CellDef *boxRootDef; TileType oldType; TileTypeBitMask mask, allmask; - int oldOverlap, newOverlap, oldExtend, newExtend; - int i, totalSize, oldDir; + int conSurround1, conSurround2, conExtend1, conExtend2, conSize; + int oldOverlap, newOverlap; + int i, totalSize, oldDir, updown; Contact *contact; SearchContext scx; @@ -768,19 +772,39 @@ WireAddContact(newType, newWidth) if ((contact->con_layer1 == oldType) && (contact->con_layer2 == WireType)) { - oldOverlap = contact->con_surround1 / WireUnits; - newOverlap = contact->con_surround2 / WireUnits; - oldExtend = contact->con_extend1 / WireUnits; - newExtend = contact->con_extend2 / WireUnits; + conSurround1 = contact->con_surround1 / WireUnits; + if ((contact->con_surround1 % WireUnits) != 0) conSurround1++; + conSurround2 = contact->con_surround2 / WireUnits; + if ((contact->con_surround2 % WireUnits) != 0) conSurround2++; + conExtend1 = contact->con_extend1 / WireUnits; + if ((contact->con_extend1 % WireUnits) != 0) conExtend1++; + conExtend2 = contact->con_extend2 / WireUnits; + if ((contact->con_extend2 % WireUnits) != 0) conExtend2++; + conSize = contact->con_size / WireUnits; + if ((contact->con_size % WireUnits) != 0) conSize++; + + oldOverlap = conSurround1; + newOverlap = conSurround2; + updown = WIRING_CONTACT_UP; goto gotContact; } if ((contact->con_layer2 == oldType) && (contact->con_layer1 == WireType)) { - oldOverlap = contact->con_surround2 / WireUnits; - newOverlap = contact->con_surround1 / WireUnits; - oldExtend = contact->con_extend2 / WireUnits; - newExtend = contact->con_extend1 / WireUnits; + conSurround1 = contact->con_surround1 / WireUnits; + if ((contact->con_surround1 % WireUnits) != 0) conSurround1++; + conSurround2 = contact->con_surround2 / WireUnits; + if ((contact->con_surround2 % WireUnits) != 0) conSurround2++; + conExtend1 = contact->con_extend1 / WireUnits; + if ((contact->con_extend1 % WireUnits) != 0) conExtend1++; + conExtend2 = contact->con_extend2 / WireUnits; + if ((contact->con_extend2 % WireUnits) != 0) conExtend2++; + conSize = contact->con_size / WireUnits; + if ((contact->con_size % WireUnits) != 0) conSize++; + + oldOverlap = conSurround2; + newOverlap = conSurround1; + updown = WIRING_CONTACT_DOWN; goto gotContact; } } @@ -798,7 +822,8 @@ WireAddContact(newType, newWidth) */ gotContact: - totalSize = (contact->con_size / WireUnits) + 2 * oldOverlap; + totalSize = conSize + 2 * oldOverlap; + if (totalSize < WireWidth) totalSize = WireWidth; contactArea = oldLeg; if ((contactArea.r_xtop - contactArea.r_xbot) < totalSize) { @@ -816,22 +841,22 @@ WireAddContact(newType, newWidth) switch (oldDir) { case GEO_NORTH: - i = contactArea.r_ytop - WireWidth; + i = contactArea.r_ytop - totalSize; if (i > contactArea.r_ybot) contactArea.r_ybot = i; break; case GEO_SOUTH: - i = contactArea.r_ybot + WireWidth; + i = contactArea.r_ybot + totalSize; if (i < contactArea.r_ytop) contactArea.r_ytop = i; break; case GEO_EAST: - i = contactArea.r_xtop - WireWidth; + i = contactArea.r_xtop - totalSize; if (i > contactArea.r_xbot) contactArea.r_xbot = i; break; case GEO_WEST: - i = contactArea.r_xbot + WireWidth; + i = contactArea.r_xbot + totalSize; if (i < contactArea.r_xtop) contactArea.r_xtop = i; break; @@ -844,23 +869,23 @@ WireAddContact(newType, newWidth) TTMaskSetOnlyType(&mask, contact->con_type); TTMaskSetOnlyType(&allmask, contact->con_type); DBPaintValid(EditCellUse->cu_def, &tmp, &mask, 0); - if (contact->con_surround1 != 0) + if (conSurround1 != 0) { TTMaskSetOnlyType(&mask, contact->con_layer1); TTMaskSetType(&allmask, contact->con_layer1); - GEO_EXPAND(&tmp, contact->con_surround1 / WireUnits, &tmp2); + GEO_EXPAND(&tmp, conSurround1, &tmp2); (void) GeoInclude(&tmp2, &editArea); DBPaintValid(EditCellUse->cu_def, &tmp2, &mask, 0); } - if (contact->con_surround2 != 0) + if (conSurround2 != 0) { TTMaskSetOnlyType(&mask, contact->con_layer2); TTMaskSetType(&allmask, contact->con_layer2); - GEO_EXPAND(&tmp, contact->con_surround2 / WireUnits, &tmp2); + GEO_EXPAND(&tmp, conSurround2, &tmp2); (void) GeoInclude(&tmp2, &editArea); DBPaintValid(EditCellUse->cu_def, &tmp2, &mask, 0); } - if (contact->con_extend1 != 0) + if (conExtend1 != 0) { TTMaskSetOnlyType(&mask, contact->con_layer1); TTMaskSetType(&allmask, contact->con_layer1); @@ -869,19 +894,41 @@ WireAddContact(newType, newWidth) { case GEO_NORTH: case GEO_SOUTH: - tmp2.r_ybot -= contact->con_extend1 / WireUnits; - tmp2.r_ytop += contact->con_extend1 / WireUnits; + if (updown == WIRING_CONTACT_UP) + { + tmp2.r_ybot -= conExtend1; + tmp2.r_ytop += conExtend1; + tmp2.r_xbot -= conSurround1; + tmp2.r_xtop += conSurround1; + } + else { + tmp2.r_xbot -= conExtend1; + tmp2.r_xtop += conExtend1; + tmp2.r_ybot -= conSurround1; + tmp2.r_ytop += conSurround1; + } break; case GEO_EAST: case GEO_WEST: - tmp2.r_xbot -= contact->con_extend1 / WireUnits; - tmp2.r_xtop += contact->con_extend1 / WireUnits; + if (updown == WIRING_CONTACT_UP) + { + tmp2.r_xbot -= conExtend1; + tmp2.r_xtop += conExtend1; + tmp2.r_ybot -= conSurround1; + tmp2.r_ytop += conSurround1; + } + else { + tmp2.r_ybot -= conExtend1; + tmp2.r_ytop += conExtend1; + tmp2.r_xbot -= conSurround1; + tmp2.r_xtop += conSurround1; + } break; } (void) GeoInclude(&tmp2, &editArea); DBPaintValid(EditCellUse->cu_def, &tmp2, &mask, 0); } - if (contact->con_extend2 != 0) + if (conExtend2 != 0) { TTMaskSetOnlyType(&mask, contact->con_layer2); TTMaskSetType(&allmask, contact->con_layer2); @@ -890,13 +937,35 @@ WireAddContact(newType, newWidth) { case GEO_NORTH: case GEO_SOUTH: - tmp2.r_xbot -= contact->con_extend2 / WireUnits; - tmp2.r_xtop += contact->con_extend2 / WireUnits; + if (updown == WIRING_CONTACT_UP) + { + tmp2.r_xbot -= conExtend2; + tmp2.r_xtop += conExtend2; + tmp2.r_ybot -= conSurround2; + tmp2.r_ytop += conSurround2; + } + else { + tmp2.r_ybot -= conExtend2; + tmp2.r_ytop += conExtend2; + tmp2.r_xbot -= conSurround2; + tmp2.r_xtop += conSurround2; + } break; case GEO_EAST: case GEO_WEST: - tmp2.r_ybot -= contact->con_extend2 / WireUnits; - tmp2.r_ytop += contact->con_extend2 / WireUnits; + if (updown == WIRING_CONTACT_UP) + { + tmp2.r_ybot -= conExtend2; + tmp2.r_ytop += conExtend2; + tmp2.r_xbot -= conSurround2; + tmp2.r_xtop += conSurround2; + } + else { + tmp2.r_xbot -= conExtend2; + tmp2.r_xtop += conExtend2; + tmp2.r_ybot -= conSurround2; + tmp2.r_ytop += conSurround2; + } break; } (void) GeoInclude(&tmp2, &editArea); @@ -921,15 +990,15 @@ WireAddContact(newType, newWidth) scx.scx_area = tmp; TTMaskSetOnlyType(&mask, contact->con_type); SelectArea(&scx, &mask, 0); - if (contact->con_surround1 != 0) + if (conSurround1 != 0) { - GEO_EXPAND(&tmp, contact->con_surround1 / WireUnits, &scx.scx_area); + GEO_EXPAND(&tmp, conSurround1, &scx.scx_area); TTMaskSetOnlyType(&mask, contact->con_layer1); SelectArea(&scx, &mask, 0); } - if (contact->con_surround2 != 0) + if (conSurround2 != 0) { - GEO_EXPAND(&tmp, contact->con_surround2 / WireUnits, &scx.scx_area); + GEO_EXPAND(&tmp, conSurround2, &scx.scx_area); TTMaskSetOnlyType(&mask, contact->con_layer2); SelectArea(&scx, &mask, 0); } From 8f7db3942c29be12d6ee3bb2fe0e3d7dc86dc299 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 4 Jun 2019 16:17:17 -0400 Subject: [PATCH 19/44] Fixed the "writeall force" command, which was behaving exactly the same as "writeall", meaning that "force" was not being honored and only cells that were modified were being written, in either case. --- commands/CmdTZ.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/commands/CmdTZ.c b/commands/CmdTZ.c index 36969938..ff9559d9 100644 --- a/commands/CmdTZ.c +++ b/commands/CmdTZ.c @@ -1736,17 +1736,20 @@ CmdWriteall(w, cmd) int cmdWriteallFunc(); static char *force[] = { "force", 0 }; int argc; + int flags = CDMODIFIED | CDBOXESCHANGED | CDSTAMPSCHANGED; - if ((cmd->tx_argc >= 2) && (Lookup(cmd->tx_argv[1], force) < 0)) + if (cmd->tx_argc >= 2) { - TxError("Usage: %s [force [cellname ...]]\n", cmd->tx_argv[0]); - return; + flags = 0; + if (Lookup(cmd->tx_argv[1], force) < 0) + { + TxError("Usage: %s [force [cellname ...]]\n", cmd->tx_argv[0]); + return; + } } - DBUpdateStamps(); argc = cmd->tx_argc; - (void) DBCellSrDefs(CDMODIFIED|CDBOXESCHANGED|CDSTAMPSCHANGED, - cmdWriteallFunc, (ClientData)cmd); + (void) DBCellSrDefs(flags, cmdWriteallFunc, (ClientData)cmd); cmd->tx_argc = argc; } From bbf600836313f3816466b78097929c314eb4213a Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 5 Jun 2019 15:03:51 -0400 Subject: [PATCH 20/44] Enhancements to cifinput and cifoutput in the tech file: Added option "labels ... cellid" to handle some vendor files where apparently to get around the 30-character cell name limit, the actual cellname is encoded on a text layer. Added new cifop "boundary" (no arguments) for cases where a cell abutment box is encoded on a GDS layer; this now translates the bounding box to the FIXED_BBOX property, as is done with the LEF bounding box. Also corrected the property set function to free existing property value allocated memory when overwriting a property with a new value. --- calma/CalmaRdpt.c | 15 ++++++++----- calma/calmaInt.h | 3 +++ cif/CIFgen.c | 24 ++++++++++++++++++++ cif/CIFint.h | 9 +++++--- cif/CIFrdcl.c | 56 ++++++++++++++++++++++++++++++++++++++++++----- cif/CIFrdpt.c | 5 +++-- cif/CIFrdtech.c | 8 +++---- cif/CIFread.h | 4 ++-- cif/CIFtech.c | 14 ++++++++++-- database/DBprop.c | 3 +++ wiring/wireTech.c | 1 + 11 files changed, 117 insertions(+), 25 deletions(-) diff --git a/calma/CalmaRdpt.c b/calma/CalmaRdpt.c index cd5109c2..aee5c4b2 100644 --- a/calma/CalmaRdpt.c +++ b/calma/CalmaRdpt.c @@ -57,8 +57,6 @@ extern HashTable calmaDefInitHash; extern void calmaLayerError(); bool calmaReadPath(); -typedef enum { LABEL_TYPE_NONE, LABEL_TYPE_TEXT, LABEL_TYPE_PORT } labelType; - /* * ---------------------------------------------------------------------------- * @@ -274,7 +272,6 @@ calmaElementBoundary() } } - CIFPropRecordPath(cifReadCellDef, pathheadp, FALSE); rp = CIFPolyToRects(pathheadp, plane, CIFPaintTable, (PaintUndoInfo *)NULL); CIFFreePath(pathheadp); @@ -300,7 +297,7 @@ calmaElementBoundary() rpc.r_ytop /= calmaReadScale1; if ((ciftype >= 0) && - ((cifCurReadStyle->crs_labelSticky[ciftype] != LABEL_TYPE_NONE))) + (cifCurReadStyle->crs_labelSticky[ciftype] != LABEL_TYPE_NONE)) { Label *lab; TileType type; @@ -652,7 +649,7 @@ calmaElementPath() } } - CIFPropRecordPath(cifReadCellDef, pathheadp, TRUE); + CIFPropRecordPath(cifReadCellDef, pathheadp, TRUE, "path"); CIFPaintWirePath(pathheadp, width, (pathtype == CALMAPATH_SQUAREFLUSH || pathtype == CALMAPATH_CUSTOM) ? FALSE : TRUE, plane, CIFPaintTable, (PaintUndoInfo *)NULL); @@ -715,7 +712,7 @@ calmaElementText() cifnum = CIFCalmaLayerToCifLayer(layer, textt, cifCurReadStyle); if (cifnum < 0) { - if(cifCurReadStyle->crs_flags & CRF_IGNORE_UNKNOWNLAYER_LABELS) + if (cifCurReadStyle->crs_flags & CRF_IGNORE_UNKNOWNLAYER_LABELS) type = -1; else { calmaLayerError("Label on unknown layer/datatype", layer, textt); @@ -889,6 +886,12 @@ calmaElementText() r.r_ll.p_x * cifCurReadStyle->crs_scaleFactor, r.r_ll.p_y * cifCurReadStyle->crs_scaleFactor); } + else if (cifCurReadStyle->crs_labelSticky[cifnum] == LABEL_TYPE_CELLID) + { + /* Special handling of label layers marked "cellid" in the techfile. */ + /* The actual cellname is the ID string, not the GDS structure name. */ + DBCellRenameDef(cifReadCellDef, textbody); + } else if (type < 0) { calmaReadError("Warning: label \"%s\" at (%d, %d) is on unhandled" diff --git a/calma/calmaInt.h b/calma/calmaInt.h index 978da3a6..407d5c40 100644 --- a/calma/calmaInt.h +++ b/calma/calmaInt.h @@ -130,6 +130,9 @@ typedef struct /* Length of record header */ #define CALMAHEADERLENGTH 4 +/* Label types */ +typedef enum { LABEL_TYPE_NONE, LABEL_TYPE_TEXT, LABEL_TYPE_PORT, LABEL_TYPE_CELLID } labelType; + /* ------------------------- Input macros ----------------------------- */ /* Globals for Calma reading */ diff --git a/cif/CIFgen.c b/cif/CIFgen.c index 86eb3fb7..d063a087 100644 --- a/cif/CIFgen.c +++ b/cif/CIFgen.c @@ -3036,6 +3036,29 @@ CIFGenLayer(op, area, cellDef, temps, clientdata) } break; + case CIFOP_BOUNDARY: + cifPlane = curPlane; + /* This function for cifoutput only. cifinput handled separately. */ + if (cellDef && (cellDef->cd_flags & CDFIXEDBBOX)) + { + char *propvalue; + bool found; + + propvalue = (char *)DBPropGet(cellDef, "FIXED_BBOX", &found); + if (!found) break; + if (sscanf(propvalue, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot, + &bbox.r_xtop, &bbox.r_ytop) != 4) break; + + cifScale = (CIFCurStyle) ? CIFCurStyle->cs_scaleFactor : 1; + bbox.r_xbot *= cifScale; + bbox.r_xtop *= cifScale; + bbox.r_ybot *= cifScale; + bbox.r_ytop *= cifScale; + DBNMPaintPlane(cifPlane, CIF_SOLIDTYPE, &bbox, + CIFPaintTable, (PaintUndoInfo *)NULL); + } + break; + case CIFOP_BBOX: if (CIFErrorDef == NULL) break; @@ -3149,6 +3172,7 @@ CIFGen(cellDef, area, planes, layers, replace, genAllPlanes, clientdata) 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); diff --git a/cif/CIFint.h b/cif/CIFint.h index f7f82105..6d3ef7ba 100644 --- a/cif/CIFint.h +++ b/cif/CIFint.h @@ -121,6 +121,8 @@ typedef struct cifop * the cell bounding box. This involves no magic type * layers but may itself be acted upon with grow/shrink * rules. + * CIFOP_BOUNDARY - Added 6/5/19---map the FIXED_BBOX property bounding + * box coordinates into CIF layer geometry. * 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 @@ -144,9 +146,10 @@ typedef struct cifop #define CIFOP_ANDNOT 12 #define CIFOP_SQUARES_G 13 #define CIFOP_BBOX 14 -#define CIFOP_NET 15 -#define CIFOP_MAXRECT 16 -#define CIFOP_COPYUP 17 +#define CIFOP_BOUNDARY 15 +#define CIFOP_NET 16 +#define CIFOP_MAXRECT 17 +#define CIFOP_COPYUP 18 /* Added by Tim 10/21/2004 */ /* The following structure is used to pass information on how to draw diff --git a/cif/CIFrdcl.c b/cif/CIFrdcl.c index 9654af0a..1ddbfb8e 100644 --- a/cif/CIFrdcl.c +++ b/cif/CIFrdcl.c @@ -559,13 +559,15 @@ cifCopyPaintFunc(tile, cifCopyRec) int CIFPaintCurrent() { + extern int cifMakeBoundaryFunc(); /* Forward declaration. */ + extern int cifPaintCurrentFunc(); /* Forward declaration. */ + Plane *plane, *swapplane; int i; for (i = 0; i < cifCurReadStyle->crs_nLayers; i++) { TileType type; - extern int cifPaintCurrentFunc(); /* Forward declaration. */ CIFOp *op; plane = CIFGenLayer(cifCurReadStyle->crs_layers[i]->crl_ops, @@ -641,6 +643,23 @@ CIFPaintCurrent() } } } + else if (op == NULL) + { + /* Handle boundary layer */ + + op = cifCurReadStyle->crs_layers[i]->crl_ops; + while (op) + { + if (op->co_opcode == CIFOP_BOUNDARY) break; + op = op->co_next; + } + + if (op && (DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect, + &DBAllButSpaceBits, cifCheckPaintFunc, + (ClientData)NULL) == 1)) + DBSrPaintArea((Tile *) NULL, plane, &TiPlaneRect, + &CIFSolidBits, cifMakeBoundaryFunc, (ClientData)NULL); + } /* Swap planes */ swapplane = cifCurReadPlanes[type]; @@ -652,8 +671,8 @@ CIFPaintCurrent() DBSrPaintArea((Tile *) NULL, plane, &TiPlaneRect, &CIFSolidBits, cifPaintCurrentFunc, (ClientData)type); - } - + } + /* Recycle the plane, which was dynamically allocated. */ DBFreePaintPlane(plane); @@ -668,9 +687,34 @@ CIFPaintCurrent() return 0; } -/* Below is the search function invoked for each CIF tile type - * found for the current layer. - */ +/* Use CIF layer geometry to define a fixed bounding box for the current cell */ + +int +cifMakeBoundaryFunc(tile, clientdata) + Tile *tile; /* Tile of CIF information. */ + ClientData clientdata; /* Not used */ +{ + /* It is assumed that there is one rectangle for the boundary. */ + /* If there are multiple rectangles defined with the boundary */ + /* layer, then the last one defines the FIXED_BBOX property. */ + + Rect area; + char propertyvalue[128], *storedvalue; + + TiToRect(tile, &area); + + if (cifReadCellDef->cd_flags & CDFIXEDBBOX) + CIFReadError("Warning: Cell %s boundary was redefined.\n", + cifReadCellDef->cd_name); + + sprintf(propertyvalue, "%d %d %d %d", + area.r_xbot, area.r_ybot, area.r_xtop, area.r_ytop); + storedvalue = StrDup((char **)NULL, propertyvalue); + DBPropPut(cifReadCellDef, "FIXED_BBOX", storedvalue); + cifReadCellDef->cd_flags |= CDFIXEDBBOX; +} + +/* Paint CIF layer geometry into the current cell def as magic layer "type" */ int cifPaintCurrentFunc(tile, type) diff --git a/cif/CIFrdpt.c b/cif/CIFrdpt.c index d0cf25cf..ec3846af 100644 --- a/cif/CIFrdpt.c +++ b/cif/CIFrdpt.c @@ -234,9 +234,10 @@ CIFParseFlash() */ void -CIFPropRecordPath(def, pathheadp, iswire) +CIFPropRecordPath(def, pathheadp, iswire, propname) CellDef *def; CIFPath *pathheadp; + char *propname; { extern float CIFGetOutputScale(); CIFPath *pathp; @@ -273,7 +274,7 @@ CIFPropRecordPath(def, pathheadp, iswire) /* Reallocate pathstr to be no larger than needed to hold the path contents */ StrDup(&pathstr, pathstr); - DBPropPut(def, "path", (ClientData)pathstr); + DBPropPut(def, propname, (ClientData)pathstr); } /* diff --git a/cif/CIFrdtech.c b/cif/CIFrdtech.c index 0ec99571..297ad7b6 100644 --- a/cif/CIFrdtech.c +++ b/cif/CIFrdtech.c @@ -62,9 +62,6 @@ CIFOp *cifCurReadOp; /* Last geometric operation seen. */ void cifReadStyleInit(); void CIFReadLoadStyle(); -/* Label types used by the "labels" statement option */ -typedef enum { LABEL_TYPE_NONE, LABEL_TYPE_TEXT, LABEL_TYPE_PORT } labelType; - /* * ---------------------------------------------------------------------------- * @@ -858,6 +855,8 @@ CIFReadTechLine(sectionName, argc, argv) calmaLabelType = LABEL_TYPE_TEXT; else if (!strcmp(argv[2], "port")) calmaLabelType = LABEL_TYPE_PORT; + else if (!strncmp(argv[2], "cell", 4)) + calmaLabelType = LABEL_TYPE_CELLID; else goto wrongNumArgs; } @@ -952,6 +951,8 @@ CIFReadTechLine(sectionName, argc, argv) newOp->co_opcode = CIFOP_SHRINK; else if (strcmp(argv[0], "copyup") == 0) newOp->co_opcode = CIFOP_COPYUP; + else if (strcmp(argv[0], "boundary") == 0) + newOp->co_opcode = CIFOP_BOUNDARY; else { TechError("Unknown statement \"%s\".\n", argv[0]); @@ -967,7 +968,6 @@ CIFReadTechLine(sectionName, argc, argv) if (argc != 2) goto wrongNumArgs; CIFParseReadLayers(argv[1], &newOp->co_cifMask); break; - case CIFOP_GROW: case CIFOP_GROW_G: case CIFOP_SHRINK: diff --git a/cif/CIFread.h b/cif/CIFread.h index bd225e04..5656600f 100644 --- a/cif/CIFread.h +++ b/cif/CIFread.h @@ -54,8 +54,8 @@ typedef struct * the "crl_magicType" should be interpreted as a CIF layer. */ -#define CIFR_SIMPLE 1 -#define CIFR_TEMPLAYER 2 +#define CIFR_SIMPLE 1 +#define CIFR_TEMPLAYER 2 /* The following structure defines a complete CIF read-in style. * The constant MAXCIFRLAYERS must be less than TT_MAXTYPES, and diff --git a/cif/CIFtech.c b/cif/CIFtech.c index ff9e2b03..54bb05c6 100644 --- a/cif/CIFtech.c +++ b/cif/CIFtech.c @@ -104,6 +104,7 @@ cifTechFreeStyle() case CIFOP_OR: case CIFOP_BBOX: case CIFOP_MAXRECT: + case CIFOP_BOUNDARY: /* These options use co_client to hold a single */ /* integer value, so it is not allocated. */ break; @@ -802,8 +803,7 @@ CIFTechLine(sectionName, argc, argv) if (CIFCurStyle->cs_status != TECH_PENDING) return TRUE; newLayer = NULL; - if ((strcmp(argv[0], "templayer") == 0) - || (strcmp(argv[0], "layer") == 0)) + if ((strcmp(argv[0], "templayer") == 0) || (strcmp(argv[0], "layer") == 0)) { if (CIFCurStyle->cs_nLayers == MAXCIFLAYERS) { @@ -1047,6 +1047,8 @@ CIFTechLine(sectionName, argc, argv) newOp->co_opcode = CIFOP_NET; else if (strcmp(argv[0], "maxrect") == 0) newOp->co_opcode = CIFOP_MAXRECT; + else if (strcmp(argv[0], "boundary") == 0) + newOp->co_opcode = CIFOP_BOUNDARY; else { TechError("Unknown statement \"%s\".\n", argv[0]); @@ -1196,6 +1198,12 @@ bloatCheck: goto wrongNumArgs; break; + case CIFOP_BOUNDARY: + /* CIFOP_BOUNDARY has no arguments */ + if (argc != 1) + goto wrongNumArgs; + break; + case CIFOP_SQUARES_G: case CIFOP_SQUARES: @@ -1752,6 +1760,7 @@ CIFTechFinal() { case CIFOP_OR: case CIFOP_BBOX: + case CIFOP_BOUNDARY: case CIFOP_MAXRECT: case CIFOP_NET: break; @@ -2232,6 +2241,7 @@ CIFTechOutputScale(n, d) { case CIFOP_OR: case CIFOP_BBOX: + case CIFOP_BOUNDARY: case CIFOP_MAXRECT: case CIFOP_NET: break; diff --git a/database/DBprop.c b/database/DBprop.c index 2ea9b652..c2ded840 100644 --- a/database/DBprop.c +++ b/database/DBprop.c @@ -55,6 +55,7 @@ DBPropPut(cellDef, name, value) { HashTable *htab; HashEntry *entry; + char *oldvalue; /* Honor the NOEDIT flag */ if (cellDef->cd_flags & CDNOEDIT) return; @@ -67,6 +68,8 @@ DBPropPut(cellDef, name, value) htab = (HashTable *) cellDef->cd_props; entry = HashFind(htab, name); + oldvalue = (char *)HashGetValue(entry); + if (oldvalue != NULL) freeMagic(oldvalue); HashSetValue(entry, value); } diff --git a/wiring/wireTech.c b/wiring/wireTech.c index 7f49e9a9..a8e4aa75 100644 --- a/wiring/wireTech.c +++ b/wiring/wireTech.c @@ -108,6 +108,7 @@ WireTechLine(sectionName, argc, argv) return TRUE; } WireUnits = atoi(argv[1]); + return TRUE; } if (strcmp(argv[0], "contact") != 0) From 0cd45ae6f746839d0e72c4ba63ed65b14830122d Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 5 Jun 2019 16:48:45 -0400 Subject: [PATCH 21/44] Modified the cell clear routine so that it removes properties in addition to subcells, paint, and labels. Otherwise problems arise if a cell is read from LEF followed by GDS; the GDS view overwrites the LEF but the property "LEFview" remains and causes problems when writing GDS output subsequently. --- database/DBcellsubr.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/database/DBcellsubr.c b/database/DBcellsubr.c index a430d671..4b9f96a8 100644 --- a/database/DBcellsubr.c +++ b/database/DBcellsubr.c @@ -157,7 +157,8 @@ dbCopyDefFunc(tile, def) * DBCellClearDef -- * * Empties out all tile planes of the indicated CellDef, making it - * as though the def had been newly allocated. + * as though the def had been newly allocated. This also removes all + * labels and all properties from the cell. * * Results: * None. @@ -221,6 +222,10 @@ DBCellClearDef(cellDef) freeMagic((char *) lab); cellDef->cd_labels = (Label *) NULL; cellDef->cd_lastLabel = (Label *) NULL; + + /* Remove all defined properties */ + DBPropClearAll(cellDef); + SigEnableInterrupts(); } From 87c07451d1867f302d456e864632a3c2af7b7b09 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 5 Jun 2019 17:02:20 -0400 Subject: [PATCH 22/44] Corrected the LEF read routine so that when LEF is read to annotate an existing GDS file, the "LEFview" property is not set (i.e., it should not be marked as an abstract view because it is still a GDS view). --- lef/lefRead.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lef/lefRead.c b/lef/lefRead.c index 3904ade4..a15a4202 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -1604,10 +1604,18 @@ origin_error: } } + /* Note: When the LEF view is used to annotate an */ + /* existing GDS view, then the view is not considered */ + /* "abstract"; otherwise, writing GDS output gets very */ + /* complicated and inefficient. */ + /* Note: The value here is ignored, setting to "TRUE". */ /* The "extract" command only cares that the key exists. */ + /* i.e., setting it to "FALSE" would be ineffective. */ + + if (!is_imported) + DBPropPut(lefMacro, "LEFview", StrDup((char **)NULL, "TRUE")); - DBPropPut(lefMacro, "LEFview", StrDup((char **)NULL, "TRUE")); DBWAreaChanged(lefMacro, &lefMacro->cd_bbox, DBW_ALLWINDOWS, &DBAllButSpaceBits); } From 51b70f65776cf191cbcbfa66eeef76788b8cf2ab Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 6 Jun 2019 09:59:56 -0400 Subject: [PATCH 23/44] Corrected an error in the LEF/DEF geometry reading, because I discovered that not all LEF/DEF rectangle coordinates are in canonical order. Took the opportunity to update the LefError() routine with an additional argument so that it can separate errors, warnings, and informational messages, and will correctly state whether the output is for a LEF or DEF read operation. --- lef/defRead.c | 90 ++++++++++--------- lef/lefInt.h | 15 +++- lef/lefRead.c | 240 +++++++++++++++++++++++++++++++++++++------------- lef/lefTech.c | 7 +- 4 files changed, 240 insertions(+), 112 deletions(-) diff --git a/lef/defRead.c b/lef/defRead.c index 0b5e3261..b71d6ddd 100644 --- a/lef/defRead.c +++ b/lef/defRead.c @@ -105,7 +105,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) if (routeLayer < 0) { - LefError("Unknown layer type \"%s\" for NEW route\n", token); + LefError(DEF_ERROR, "Unknown layer type \"%s\" for NEW route\n", token); continue; } paintLayer = routeLayer; @@ -116,7 +116,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) token = LefNextToken(f, TRUE); if (sscanf(token, "%f", &w) != 1) { - LefError("Bad width in special net\n"); + LefError(DEF_ERROR, "Bad width in special net\n"); continue; } if (w != 0) @@ -138,7 +138,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) else if (valid == FALSE) { - LefError("Route has via name \"%s\" but no points!\n", token); + LefError(DEF_ERROR, "Route has via name \"%s\" but no points!\n", token); continue; } he = HashLookOnly(&LefInfo, token); @@ -197,7 +197,8 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) } else if ((paintLayer = DBTechNameType(LefLower(token))) >= 0) { - LefError("Error: Via \"%s\" named but undefined.\n", token); + LefError(DEF_ERROR, "Error: Via \"%s\" named but undefined.\n", + token); newRoute->r_r.r_xbot = refp.p_x - paintWidth; newRoute->r_r.r_ybot = refp.p_y - paintWidth; newRoute->r_r.r_xtop = refp.p_x + paintWidth; @@ -209,7 +210,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) newRoute->r_r.r_ytop >>= 1; } else - LefError("Via name \"%s\" unknown in route.\n", token); + LefError(DEF_ERROR, "Via name \"%s\" unknown in route.\n", token); /* After the via, the new route layer becomes whatever */ /* residue of the via was NOT the previous route layer. */ @@ -244,7 +245,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) } } else - LefError("Via name \"%s\" unknown in route.\n", token); + LefError(DEF_ERROR, "Via name \"%s\" unknown in route.\n", token); } else { @@ -261,7 +262,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) { if (valid == FALSE) { - LefError("No reference point for \"*\" wildcard\n"); + LefError(DEF_ERROR, "No reference point for \"*\" wildcard\n"); goto endCoord; } } @@ -271,7 +272,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) } else { - LefError("Cannot parse X coordinate.\n"); + LefError(DEF_ERROR, "Cannot parse X coordinate.\n"); goto endCoord; } token = LefNextToken(f, TRUE); /* read Y */ @@ -279,7 +280,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) { if (valid == FALSE) { - LefError("No reference point for \"*\" wildcard\n"); + LefError(DEF_ERROR, "No reference point for \"*\" wildcard\n"); freeMagic(newRoute); newRoute = NULL; goto endCoord; @@ -291,7 +292,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) } else { - LefError("Cannot parse Y coordinate.\n"); + LefError(DEF_ERROR, "Cannot parse Y coordinate.\n"); goto endCoord; } @@ -306,7 +307,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) { /* non-default route extension */ if (sscanf(token, "%f", &z) != 1) - LefError("Can't parse route extension value.\n"); + LefError(DEF_ERROR, "Can't parse route extension value.\n"); /* all values will be divided by 2, so we need */ /* to multiply up by 2 now. */ @@ -326,7 +327,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) /* Skip over nonmanhattan segments, reset the reference */ /* point, and output a warning. */ - LefError("Can't deal with nonmanhattan geometry in route.\n"); + LefError(DEF_ERROR, "Can't deal with nonmanhattan geometry in route.\n"); locarea.r_xbot = refp.p_x; locarea.r_ybot = refp.p_y; } @@ -471,7 +472,7 @@ DefReadNets(f, rootDef, sname, oscale, special, total) keyword = Lookup(token, net_keys); if (keyword < 0) { - LefError("Unknown keyword \"%s\" in NET " + LefError(DEF_INFO, "Unknown keyword \"%s\" in NET " "definition; ignoring.\n", token); LefEndStatement(f); continue; @@ -508,7 +509,7 @@ DefReadNets(f, rootDef, sname, oscale, special, total) subkey = Lookup(token, net_property_keys); if (subkey < 0) { - LefError("Unknown net property \"%s\" in " + LefError(DEF_INFO, "Unknown net property \"%s\" in " "NET definition; ignoring.\n", token); continue; } @@ -530,7 +531,7 @@ DefReadNets(f, rootDef, sname, oscale, special, total) case DEF_NET_END: if (!LefParseEndStatement(f, sname)) { - LefError("Net END statement missing.\n"); + LefError(DEF_ERROR, "Net END statement missing.\n"); keyword = -1; } break; @@ -542,7 +543,7 @@ DefReadNets(f, rootDef, sname, oscale, special, total) TxPrintf(" Processed %d%s nets total.\n", processed, (special) ? " special" : ""); else - LefError("Warning: Number of nets read (%d) does not match " + LefError(DEF_WARNING, "Number of nets read (%d) does not match " "the number declared (%d).\n", processed, total); freeMagic((char *)defLayerMap); @@ -600,7 +601,7 @@ DefReadLocation(use, f, oscale, tptr) keyword = Lookup(token, orientations); if (keyword < 0) { - LefError("Unknown macro orientation \"%s\".\n", token); + LefError(DEF_ERROR, "Unknown macro orientation \"%s\".\n", token); return -1; } @@ -668,7 +669,7 @@ DefReadLocation(use, f, oscale, tptr) return 0; parse_error: - LefError("Cannot parse location: must be ( X Y ) orient\n"); + LefError(DEF_ERROR, "Cannot parse location: must be ( X Y ) orient\n"); return -1; } @@ -755,7 +756,7 @@ DefReadPins(f, rootDef, sname, oscale, total) if (keyword < 0) { - LefError("Unknown keyword \"%s\" in PINS " + LefError(DEF_INFO, "Unknown keyword \"%s\" in PINS " "definition; ignoring.\n", token); LefEndStatement(f); continue; @@ -769,7 +770,7 @@ DefReadPins(f, rootDef, sname, oscale, total) if (pending) { - LefError("Pin specified without layer, was not placed.\n"); + LefError(DEF_ERROR, "Pin specified without layer, was not placed.\n"); } /* Update the record of the number of pins */ @@ -781,7 +782,7 @@ DefReadPins(f, rootDef, sname, oscale, total) token = LefNextToken(f, TRUE); if (sscanf(token, "%2047s", pinname) != 1) { - LefError("Bad pin statement: Need pin name\n"); + LefError(DEF_ERROR, "Bad pin statement: Need pin name\n"); LefEndStatement(f); break; } @@ -799,7 +800,7 @@ DefReadPins(f, rootDef, sname, oscale, total) subkey = Lookup(token, pin_property_keys); if (subkey < 0) { - LefError("Unknown pin property \"%s\" in " + LefError(DEF_ERROR, "Unknown pin property \"%s\" in " "PINS definition; ignoring.\n", token); continue; } @@ -814,7 +815,7 @@ DefReadPins(f, rootDef, sname, oscale, total) token = LefNextToken(f, TRUE); subkey = Lookup(token, pin_classes); if (subkey < 0) - LefError("Unknown pin class\n"); + LefError(DEF_ERROR, "Unknown pin class\n"); else pinDir = lef_class_to_bitmask[subkey]; break; @@ -869,7 +870,7 @@ DefReadPins(f, rootDef, sname, oscale, total) case DEF_PINS_END: if (!LefParseEndStatement(f, sname)) { - LefError("Pins END statement missing.\n"); + LefError(DEF_ERROR, "Pins END statement missing.\n"); keyword = -1; } break; @@ -880,7 +881,7 @@ DefReadPins(f, rootDef, sname, oscale, total) if (processed == total) TxPrintf(" Processed %d pins total.\n", processed); else - LefError("Warning: Number of pins read (%d) does not match " + LefError(DEF_WARNING, "Number of pins read (%d) does not match " "the number declared (%d).\n", processed, total); } @@ -939,7 +940,7 @@ DefReadVias(f, sname, oscale, total) if (keyword < 0) { - LefError("Unknown keyword \"%s\" in VIAS " + LefError(DEF_INFO, "Unknown keyword \"%s\" in VIAS " "definition; ignoring.\n", token); LefEndStatement(f); continue; @@ -957,7 +958,7 @@ DefReadVias(f, sname, oscale, total) token = LefNextToken(f, TRUE); if (sscanf(token, "%2047s", vianame) != 1) { - LefError("Bad via statement: Need via name\n"); + LefError(DEF_ERROR, "Bad via statement: Need via name\n"); LefEndStatement(f); break; } @@ -977,7 +978,7 @@ DefReadVias(f, sname, oscale, total) } else { - LefError("Warning: Composite via \"%s\" redefined.\n", vianame); + LefError(DEF_WARNING, "Composite via \"%s\" redefined.\n", vianame); lefl = LefRedefined(lefl, vianame); } @@ -993,7 +994,7 @@ DefReadVias(f, sname, oscale, total) subkey = Lookup(token, via_property_keys); if (subkey < 0) { - LefError("Unknown via property \"%s\" in " + LefError(DEF_INFO, "Unknown via property \"%s\" in " "VIAS definition; ignoring.\n", token); continue; } @@ -1010,7 +1011,7 @@ DefReadVias(f, sname, oscale, total) case DEF_VIAS_END: if (!LefParseEndStatement(f, sname)) { - LefError("Vias END statement missing.\n"); + LefError(DEF_ERROR, "Vias END statement missing.\n"); keyword = -1; } break; @@ -1021,7 +1022,7 @@ DefReadVias(f, sname, oscale, total) if (processed == total) TxPrintf(" Processed %d vias total.\n", processed); else - LefError("Warning: Number of vias read (%d) does not match " + LefError(DEF_WARNING, "Number of vias read (%d) does not match " "the number declared (%d).\n", processed, total); } @@ -1093,7 +1094,7 @@ DefReadComponents(f, rootDef, sname, oscale, total) if (keyword < 0) { - LefError("Unknown keyword \"%s\" in COMPONENT " + LefError(DEF_INFO, "Unknown keyword \"%s\" in COMPONENT " "definition; ignoring.\n", token); LefEndStatement(f); continue; @@ -1111,7 +1112,8 @@ DefReadComponents(f, rootDef, sname, oscale, total) token = LefNextToken(f, TRUE); if (sscanf(token, "%511s", usename) != 1) { - LefError("Bad component statement: Need use and macro names\n"); + LefError(DEF_ERROR, "Bad component statement: Need " + "use and macro names\n"); LefEndStatement(f); break; } @@ -1129,8 +1131,8 @@ DefReadComponents(f, rootDef, sname, oscale, total) defMacro->cd_flags &= ~CDNOTFOUND; if (!DBCellRead(defMacro, (char *)NULL, TRUE, NULL)) { - LefError("Cell %s is not defined. Maybe you have not " - "read the corresponding LEF file?\n", + LefError(DEF_ERROR, "Cell %s is not defined. Maybe you " + "have not read the corresponding LEF file?\n", token); LefEndStatement(f); DBCellDeleteDef(defMacro); @@ -1163,7 +1165,7 @@ DefReadComponents(f, rootDef, sname, oscale, total) subkey = Lookup(token, property_keys); if (subkey < 0) { - LefError("Unknown component property \"%s\" in " + LefError(DEF_INFO, "Unknown component property \"%s\" in " "COMPONENT definition; ignoring.\n", token); continue; } @@ -1198,7 +1200,7 @@ DefReadComponents(f, rootDef, sname, oscale, total) case DEF_COMP_END: if (!LefParseEndStatement(f, sname)) { - LefError("Component END statement missing.\n"); + LefError(DEF_ERROR, "Component END statement missing.\n"); keyword = -1; } @@ -1216,7 +1218,7 @@ DefReadComponents(f, rootDef, sname, oscale, total) if (processed == total) TxPrintf(" Processed %d subcell instances total.\n", processed); else - LefError("Warning: Number of subcells read (%d) does not match " + LefError(DEF_WARNING, "Number of subcells read (%d) does not match " "the number declared (%d).\n", processed, total); } @@ -1330,7 +1332,7 @@ DefRead(inName) keyword = Lookup(token, sections); if (keyword < 0) { - LefError("Unknown keyword \"%s\" in DEF file; ignoring.\n", token); + LefError(DEF_INFO, "Unknown keyword \"%s\" in DEF file; ignoring.\n", token); LefEndStatement(f); continue; } @@ -1346,7 +1348,7 @@ DefRead(inName) token = LefNextToken(f, TRUE); if (strcmp(token, DBTechName)) { - LefError("Warning: DEF technology name \"%s\" does not" + LefError(DEF_WARNING, "DEF technology name \"%s\" does not" " match current magic technology name \"%s\"\n", token, DBTechName); } @@ -1366,8 +1368,8 @@ DefRead(inName) token = LefNextToken(f, TRUE); if (sscanf(token, "%d", &dscale) != 1) { - LefError("Invalid syntax for UNITS statement.\n"); - LefError("Assuming default value of 100\n"); + LefError(DEF_ERROR, "Invalid syntax for UNITS statement.\n"); + LefError(DEF_INFO, "Assuming default value of 100\n"); dscale = 100; } /* We don't care if the scale is 100, 200, 1000, or 2000. */ @@ -1453,7 +1455,7 @@ DefRead(inName) case DEF_END: if (!LefParseEndStatement(token, "DESIGN")) { - LefError("END statement out of context.\n"); + LefError(DEF_ERROR, "END statement out of context.\n"); keyword = -1; } break; @@ -1461,7 +1463,7 @@ DefRead(inName) if (keyword == DEF_END) break; } TxPrintf("DEF read: Processed %d lines.\n", lefCurrentLine); - LefError(NULL); /* print statement of errors, if any, and reset */ + LefError(DEF_SUMMARY, NULL); /* print statement of errors, if any, and reset */ /* Cleanup */ diff --git a/lef/lefInt.h b/lef/lefInt.h index e6568423..8f069404 100644 --- a/lef/lefInt.h +++ b/lef/lefInt.h @@ -131,7 +131,18 @@ TileType LefReadLayer(); LefMapping *defMakeInverseLayerMap(); -void LefError(char *, ...); /* Variable argument procedure requires */ - /* parameter list. */ +void LefError(int, char *, ...); /* Variable argument procedure requires */ + /* parameter list. */ + +/* Definitions for type passed to LefError() */ + +#define LEF_ERROR 0 +#define LEF_WARNING 1 +#define LEF_INFO 2 +#define LEF_SUMMARY 3 +#define DEF_ERROR 4 +#define DEF_WARNING 5 +#define DEF_INFO 6 +#define DEF_SUMMARY 7 #endif /* _LEFINT_H */ diff --git a/lef/lefRead.c b/lef/lefRead.c index a15a4202..43ef32d9 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -279,11 +279,15 @@ LefNextToken(f, ignore_eol) /* *------------------------------------------------------------ * - * LefError -- + * LefDefError -- * * Print an error message (via TxError) giving the line * number of the input file on which the error occurred. * + * "type" is one of the following (see lef.h): + * LEF_ERROR, LEF_WARNING, LEF_INFO, + * DEF_ERROR, DEF_WARNING, DEF_INFO + * * Results: * None. * @@ -294,34 +298,126 @@ LefNextToken(f, ignore_eol) */ void -LefError(char *fmt, ...) +LefError(int type, char *fmt, ...) { - static int errors = 0; + static int errors = 0, warnings = 0, messages = 0; va_list args; - if (fmt == NULL) /* Special case: report any errors and reset */ + char *lefdeftypes[] = {"LEF", "DEF", "techfile lef section"}; + + int mode, level; + char *lefdeftype; + + switch (type) { + case LEF_INFO: + mode = 0; + level = 0; + break; + case LEF_WARNING: + mode = 0; + level = 1; + break; + case LEF_ERROR: + mode = 0; + level = 2; + break; + case LEF_SUMMARY: + mode = 0; + level = -1; + break; + case DEF_INFO: + mode = 1; + level = 0; + break; + case DEF_WARNING: + mode = 1; + level = 1; + break; + case DEF_ERROR: + mode = 1; + level = 2; + break; + case DEF_SUMMARY: + mode = 1; + level = -1; + break; + } + lefdeftype = lefdeftypes[mode]; + + if ((fmt == NULL) || (level == -1)) { + /* Special case: report any errors and reset */ + if (errors) - { - TxPrintf("LEF Read: encountered %d error%s total.\n", errors, - (errors == 1) ? "" : "s"); - errors = 0; - } + TxPrintf("%s Read: encountered %d error%s total.\n", + lefdeftype, errors, (errors == 1) ? "" : "s"); + + if (warnings) + TxPrintf("%s Read: encountered %d warning%s total.\n", + lefdeftype, warnings, (warnings == 1) ? "" : "s"); + + errors = 0; + warnings = 0; + messages = 0; return; } - if (errors < LEF_MAX_ERRORS) - { - TxError("LEF Read, Line %d: ", lefCurrentLine); - va_start(args, fmt); - Vfprintf(stderr, fmt, args); - va_end(args); - TxFlushErr(); - } - else if (errors == LEF_MAX_ERRORS) - TxError("LEF Read: Further errors will not be reported.\n"); + switch (level) { - errors++; + case 2: + if (errors < LEF_MAX_ERRORS) + { + if (lefCurrentLine >= 0) + TxError("%s read, Line %d (Error): ", lefdeftype, lefCurrentLine); + else + TxError("%s read (Error): ", lefdeftype); + va_start(args, fmt); + Vfprintf(stderr, fmt, args); + va_end(args); + TxFlushErr(); + } + else if (errors == LEF_MAX_ERRORS) + TxError("%s Read: Further errors will not be reported.\n", + lefdeftype); + errors++; + break; + + case 1: + if (warnings < LEF_MAX_ERRORS) + { + if (lefCurrentLine >= 0) + TxError("%s read, Line %d (Warning): ", lefdeftype, lefCurrentLine); + else + TxError("%s read (Warning): ", lefdeftype); + va_start(args, fmt); + Vfprintf(stderr, fmt, args); + va_end(args); + TxFlushErr(); + } + else if (warnings == LEF_MAX_ERRORS) + TxError("%s read: Further warnings will not be reported.\n", + lefdeftype); + warnings++; + break; + + case 0: + if (messages < LEF_MAX_ERRORS) + { + if (lefCurrentLine >= 0) + TxPrintf("%s read, Line %d (Message): ", lefdeftype, lefCurrentLine); + else + TxPrintf("%s read (Message): ", lefdeftype); + va_start(args, fmt); + Vfprintf(stdout, fmt, args); + va_end(args); + TxFlushOut(); + } + else if (messages == LEF_MAX_ERRORS) + TxPrintf("%s read: Further messages will not be reported.\n", + lefdeftype); + messages++; + break; + } } /* @@ -368,7 +464,7 @@ LefParseEndStatement(f, match) token = LefNextToken(f, (match == NULL) ? FALSE : TRUE); if (token == NULL) { - LefError("Bad file read while looking for END statement\n"); + LefError(LEF_ERROR, "Bad file read while looking for END statement\n"); return 0; } @@ -407,7 +503,7 @@ LefParseEndStatement(f, match) * None. * * Side Effects: - * Reads input from the specified file. Prints an + * reads input from the specified file. Prints an * error message if the expected END record cannot * be found. * @@ -445,7 +541,7 @@ LefSkipSection(f, section) } } - LefError("Section %s has no END record!\n", section); + LefError(LEF_ERROR, "Section %s has no END record!\n", section); return; } @@ -623,7 +719,7 @@ LefReadLayers(f, obstruct, lreturn, rreturn) token = LefNextToken(f, TRUE); if (*token == ';') { - LefError("Bad Layer statement\n"); + LefError(LEF_ERROR, "Bad Layer statement\n"); return -1; } else @@ -670,8 +766,8 @@ LefReadLayers(f, obstruct, lreturn, rreturn) } if ((curlayer < 0) && ((!lefl) || (lefl->lefClass != CLASS_IGNORE))) { - LefError("Don't know how to parse layer \"%s\"\n", token); - LefError("Try adding this name to the LEF techfile section\n"); + LefError(LEF_ERROR, "Don't know how to parse layer \"%s\"\n", token); + LefError(LEF_ERROR, "Try adding this name to the LEF techfile section\n"); } } return curlayer; @@ -736,6 +832,7 @@ LefReadRect(f, curlayer, oscale) char *token; float llx, lly, urx, ury; static Rect paintrect; + Rect lefrect; bool needMatch = FALSE; token = LefNextToken(f, TRUE); @@ -768,16 +865,23 @@ LefReadRect(f, curlayer, oscale) if (*token != ')') goto parse_error; } if (curlayer < 0) - LefError("No layer defined for RECT.\n"); + { + LefError(LEF_ERROR, "No layer defined for RECT.\n"); + paintrect.r_xbot = paintrect.r_ybot = 0; + paintrect.r_xtop = paintrect.r_ytop = 0; + } else { /* Scale coordinates (microns to magic internal units) */ /* Need to scale grid if necessary! */ - paintrect.r_xbot = (int)roundf(llx / oscale); - paintrect.r_ybot = (int)roundf(lly / oscale); - paintrect.r_xtop = (int)roundf(urx / oscale); - paintrect.r_ytop = (int)roundf(ury / oscale); + lefrect.r_xbot = (int)roundf(llx / oscale); + lefrect.r_ybot = (int)roundf(lly / oscale); + lefrect.r_xtop = (int)roundf(urx / oscale); + lefrect.r_ytop = (int)roundf(ury / oscale); + + /* Insist on non-inverted rectangles */ + GeoCanonicalRect(&lefrect, &paintrect); /* Diagnostic */ /* @@ -791,7 +895,7 @@ LefReadRect(f, curlayer, oscale) return (&paintrect); parse_error: - LefError("Bad port geometry: RECT requires 4 values.\n"); + LefError(LEF_ERROR, "Bad port geometry: RECT requires 4 values.\n"); return (Rect *)NULL; } @@ -836,7 +940,7 @@ LefReadPolygon(f, curlayer, oscale, ppoints) if (token == NULL || *token == ';') break; if (sscanf(token, "%f", &px) != 1) { - LefError("Bad X value in polygon.\n"); + LefError(LEF_ERROR, "Bad X value in polygon.\n"); LefEndStatement(f); break; } @@ -844,12 +948,12 @@ LefReadPolygon(f, curlayer, oscale, ppoints) token = LefNextToken(f, TRUE); if (token == NULL || *token == ';') { - LefError("Missing Y value in polygon point!\n"); + LefError(LEF_ERROR, "Missing Y value in polygon point!\n"); break; } if (sscanf(token, "%f", &py) != 1) { - LefError("Bad Y value in polygon.\n"); + LefError(LEF_ERROR, "Bad Y value in polygon.\n"); LefEndStatement(f); break; } @@ -987,7 +1091,8 @@ LefReadGeometry(lefMacro, f, oscale, do_list) keyword = Lookup(token, geometry_keys); if (keyword < 0) { - LefError("Unknown keyword \"%s\" in LEF file; ignoring.\n", token); + LefError(LEF_INFO, "Unknown keyword \"%s\" in LEF file; ignoring.\n", + token); LefEndStatement(f); continue; } @@ -1082,7 +1187,8 @@ LefReadGeometry(lefMacro, f, oscale, do_list) case LEF_GEOMETRY_END: if (LefParseEndStatement(f, NULL) == 0) { - LefError("Geometry (PORT or OBS) END statement missing.\n"); + LefError(LEF_ERROR, "Geometry (PORT or OBS) END " + "statement missing.\n"); keyword = -1; } break; @@ -1133,12 +1239,12 @@ LefReadPort(lefMacro, f, pinName, pinNum, pinDir, pinUse, oscale) /* Set this label to be a port */ if (lefMacro->cd_labels == NULL) - LefError("Internal error: No labels in cell!\n"); + LefError(LEF_ERROR, "Internal error: No labels in cell!\n"); else { newlab = lefMacro->cd_lastLabel; if (strcmp(newlab->lab_text, pinName)) - LefError("Internal error: Can't find the label!\n"); + LefError(LEF_ERROR, "Internal error: Can't find the label!\n"); else /* Make this a port */ newlab->lab_flags = pinNum | pinUse | pinDir | PORT_DIR_MASK; } @@ -1248,7 +1354,8 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported) keyword = Lookup(token, pin_keys); if (keyword < 0) { - LefError("Unknown keyword \"%s\" in LEF file; ignoring.\n", token); + LefError(LEF_INFO, "Unknown keyword \"%s\" in LEF file; ignoring.\n", + token); LefEndStatement(f); continue; } @@ -1258,7 +1365,7 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported) token = LefNextToken(f, TRUE); subkey = Lookup(token, pin_classes); if (subkey < 0) - LefError("Improper DIRECTION statement\n"); + LefError(LEF_ERROR, "Improper DIRECTION statement\n"); else pinDir = lef_class_to_bitmask[subkey]; LefEndStatement(f); @@ -1267,7 +1374,7 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported) token = LefNextToken(f, TRUE); subkey = Lookup(token, pin_uses); if (subkey < 0) - LefError("Improper USE statement\n"); + LefError(LEF_ERROR, "Improper USE statement\n"); else pinUse = lef_use_to_bitmask[subkey]; LefEndStatement(f); @@ -1310,7 +1417,7 @@ LefReadPin(lefMacro, f, pinname, pinNum, oscale, is_imported) case LEF_PIN_END: if (LefParseEndStatement(f, pinname) == 0) { - LefError("Pin END statement missing.\n"); + LefError(LEF_ERROR, "Pin END statement missing.\n"); keyword = -1; } break; @@ -1404,7 +1511,7 @@ LefReadMacro(f, mname, oscale, importForeign) sprintf(newname, "%250s_%d", mname, suffix); he = HashFind(&lefDefInitHash, newname); } - LefError("Cell \"%s\" was already defined in this file. " + LefError(LEF_WARNING, "Cell \"%s\" was already defined in this file. " "Renaming this cell \"%s\"\n", mname, newname); lefMacro = DBCellLookDef(newname); if (lefMacro == NULL) @@ -1444,7 +1551,8 @@ LefReadMacro(f, mname, oscale, importForeign) keyword = Lookup(token, macro_keys); if (keyword < 0) { - LefError("Unknown keyword \"%s\" in LEF file; ignoring.\n", token); + LefError(LEF_INFO, "Unknown keyword \"%s\" in LEF file; ignoring.\n", + token); LefEndStatement(f); continue; } @@ -1470,7 +1578,7 @@ LefReadMacro(f, mname, oscale, importForeign) LefEndStatement(f); break; size_error: - LefError("Bad macro SIZE; requires values X BY Y.\n"); + LefError(LEF_ERROR, "Bad macro SIZE; requires values X BY Y.\n"); LefEndStatement(f); break; case LEF_ORIGIN: @@ -1489,7 +1597,7 @@ size_error: LefEndStatement(f); break; origin_error: - LefError("Bad macro ORIGIN; requires 2 values.\n"); + LefError(LEF_ERROR, "Bad macro ORIGIN; requires 2 values.\n"); LefEndStatement(f); break; case LEF_SYMMETRY: @@ -1549,7 +1657,7 @@ origin_error: case LEF_MACRO_END: if (LefParseEndStatement(f, mname) == 0) { - LefError("Macro END statement missing.\n"); + LefError(LEF_ERROR, "Macro END statement missing.\n"); keyword = -1; } break; @@ -1589,7 +1697,8 @@ origin_error: } else { - LefError(" Macro does not define size: computing from geometry\n"); + LefError(LEF_WARNING, " Macro does not define size: " + "computing from geometry\n"); /* Set the placement bounding box property to the current bounding box */ lefMacro->cd_flags |= CDFIXEDBBOX; @@ -1718,12 +1827,12 @@ LefAddViaGeometry(f, lefl, curlayer, oscale) if ((currect->r_xtop - currect->r_xbot != edgeSize) || (currect->r_ytop - currect->r_ybot != edgeSize)) { - LefError("Warning: Cut size for magic type \"%s\" (%d x %d) does " + LefError(LEF_WARNING, "Cut size for magic type \"%s\" (%d x %d) does " "not match LEF/DEF\n", DBTypeLongNameTbl[lefl->type], edgeSize, edgeSize); - LefError(" via cut size (%d x %d). Magic layer cut size will " - "be used!\n", + LefError(LEF_WARNING, "Via cut size (%d x %d). Magic layer " + "cut size will be used!\n", currect->r_xtop - currect->r_xbot, currect->r_ytop - currect->r_ybot); } @@ -1865,7 +1974,8 @@ LefReadLayerSection(f, lname, mode, lefl) keyword = Lookup(token, layer_keys); if (keyword < 0) { - LefError("Unknown keyword \"%s\" in LEF file; ignoring.\n", token); + LefError(LEF_INFO, "Unknown keyword \"%s\" in LEF file; ignoring.\n", + token); LefEndStatement(f); continue; } @@ -1877,7 +1987,7 @@ LefReadLayerSection(f, lname, mode, lefl) { typekey = Lookup(token, layer_type_keys); if (typekey < 0) - LefError("Unknown layer type \"%s\" in LEF file; " + LefError(LEF_WARNING, "Unknown layer type \"%s\" in LEF file; " "ignoring.\n", token); } if (lefl->lefClass != typekey) @@ -1886,7 +1996,8 @@ LefReadLayerSection(f, lname, mode, lefl) /* and so having a different TYPE is an error. */ /* Otherwise just ignore the type. */ if (typekey == CLASS_ROUTE || typekey == CLASS_VIA) - LefError("Attempt to reclassify layer %s from %s to %s\n", + LefError(LEF_ERROR, "Attempt to reclassify layer %s " + "from %s to %s\n", lname, layer_type_keys[lefl->lefClass], layer_type_keys[typekey]); } @@ -1990,7 +2101,7 @@ LefReadLayerSection(f, lname, mode, lefl) case LEF_LAYER_END: if (LefParseEndStatement(f, lname) == 0) { - LefError("Layer END statement missing.\n"); + LefError(LEF_ERROR, "Layer END statement missing.\n"); keyword = -1; } break; @@ -2096,13 +2207,15 @@ LefRead(inName, importForeign) HashInit(&LefCellTable, 32, HT_STRINGKEYS); HashInit(&lefDefInitHash, 32, HT_STRINGKEYS); oscale = CIFGetOutputScale(1000); + lefCurrentLine = 0; while ((token = LefNextToken(f, TRUE)) != NULL) { keyword = Lookup(token, sections); if (keyword < 0) { - LefError("Unknown keyword \"%s\" in LEF file; ignoring.\n", token); + LefError(LEF_INFO, "Unknown keyword \"%s\" in LEF file; ignoring.\n", + token); LefEndStatement(f); continue; } @@ -2154,7 +2267,7 @@ LefRead(inName, importForeign) LefSkipSection(f, tsave); else { - LefError("Warning: Cut type \"%s\" redefined.\n", token); + LefError(LEF_WARNING, "Cut type \"%s\" redefined.\n", token); lefl = LefRedefined(lefl, token); LefReadLayerSection(f, tsave, keyword, lefl); } @@ -2178,7 +2291,7 @@ LefRead(inName, importForeign) } else if (DBIsContact(mtype) && (keyword == LEF_SECTION_LAYER)) { - LefError("Layer %s maps to a magic contact layer; " + LefError(LEF_ERROR, "Layer %s maps to a magic contact layer; " "must be defined in lef section of techfile\n", token); LefSkipSection(f, tsave); @@ -2186,7 +2299,7 @@ LefRead(inName, importForeign) } else if (!DBIsContact(mtype) && (keyword != LEF_SECTION_LAYER)) { - LefError("Via %s maps to a non-contact magic layer; " + LefError(LEF_ERROR, "Via %s maps to a non-contact magic layer; " "must be defined in lef section of techfile\n", token); LefSkipSection(f, tsave); @@ -2209,7 +2322,8 @@ LefRead(inName, importForeign) lefl = (lefLayer *)HashGetValue(he); if (lefl && lefl->type < 0) { - LefError("Layer %s is only defined for obstructions!\n", token); + LefError(LEF_ERROR, "Layer %s is only defined for " + "obstructions!\n", token); LefSkipSection(f, tsave); break; } @@ -2265,7 +2379,7 @@ LefRead(inName, importForeign) case LEF_END: if (LefParseEndStatement(f, "LIBRARY") == 0) { - LefError("END statement out of context.\n"); + LefError(LEF_ERROR, "END statement out of context.\n"); keyword = -1; } break; @@ -2273,7 +2387,7 @@ LefRead(inName, importForeign) if (keyword == LEF_END) break; } TxPrintf("LEF read: Processed %d lines.\n", lefCurrentLine); - LefError(NULL); /* print statement of errors, if any */ + LefError(LEF_SUMMARY, NULL); /* print statement of errors, if any */ /* Cleanup */ HashKill(&LefCellTable); diff --git a/lef/lefTech.c b/lef/lefTech.c index 007ad0db..272e4302 100644 --- a/lef/lefTech.c +++ b/lef/lefTech.c @@ -115,6 +115,7 @@ LefTechInit() HashKill(&LefInfo); } HashInit(&LefInfo, 32, HT_STRINGKEYS); + lefCurrentLine = -1; } /* @@ -252,17 +253,17 @@ LefTechLine(sectionName, argc, argv) if (i == 0) { - LefError("Bad magic layer type \"%s\" in LEF layer definition.\n", argv[1]); + TechError("Bad magic layer type \"%s\" in LEF layer definition.\n", argv[1]); return TRUE; } else if ((i == 2) && (option != LEFTECH_OBS)) { - LefError("Can only define multiple types for via obstruction layers.\n"); + TechError("Can only define multiple types for via obstruction layers.\n"); return TRUE; } else if (i > 2) { - LefError("Too many types in LEF layer definition.\n"); + TechError("Too many types in LEF layer definition.\n"); return TRUE; } From 53078588aec57b02c4c8e269e9887b745a266d5e Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 6 Jun 2019 14:53:07 -0400 Subject: [PATCH 24/44] Changed the size of argv[] in efReadLine() to be 128 instead of 64 because I overran the 64 array with too many resistclasses in a techfile. This really should be dynamically allocated; this requires parsing the line to count tokens and reallocating as needed (to be done). --- ext2spice/ext2spice.c | 1 + extflat/EFbuild.c | 4 ++-- extflat/EFread.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ext2spice/ext2spice.c b/ext2spice/ext2spice.c index 1129300b..1aa1bfc9 100644 --- a/ext2spice/ext2spice.c +++ b/ext2spice/ext2spice.c @@ -1685,6 +1685,7 @@ topVisit(def, doStub) EFNodeName *unnumbered; sname = (EFNodeName *) HashGetValue(he); + if (sname == NULL) continue; /* Should not happen */ snode = sname->efnn_node; if (!(snode->efnode_flags & EF_PORT)) continue; diff --git a/extflat/EFbuild.c b/extflat/EFbuild.c index d6b11fd6..684168f1 100644 --- a/extflat/EFbuild.c +++ b/extflat/EFbuild.c @@ -223,8 +223,8 @@ efAdjustSubCap(def, nodeName, nodeCapAdjust) EFNode *node; HashEntry *he; - he = HashFind(&def->def_nodes, nodeName); - if (nodename = (EFNodeName *) HashGetValue(he)) + he = HashLookOnly(&def->def_nodes, nodeName); + if (he && (nodename = (EFNodeName *) HashGetValue(he))) { node = nodename->efnn_node; node->efnode_cap += (EFCapValue) nodeCapAdjust; diff --git a/extflat/EFread.c b/extflat/EFread.c index c8c4471e..81384a5c 100644 --- a/extflat/EFread.c +++ b/extflat/EFread.c @@ -174,7 +174,7 @@ efReadDef(def, dosubckt, resist, noscale, toplevel) int argc, ac, n; CellDef *dbdef; EFCapValue cap; - char line[1024], *argv[64], *name, *attrs; + char line[1024], *argv[128], *name, *attrs; int rscale = 1; /* Multiply resistances by this */ int cscale = 1; /* Multiply capacitances by this */ float lscale = 1.0; /* Multiply lambda by this */ From 547f0448d9b0ec47f37ba84927d1626e53946c3f Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Fri, 7 Jun 2019 14:13:50 -0400 Subject: [PATCH 25/44] Cleanup of a number of uninitialized variable issues flagged by the compiler. Some are obscure functions (plot verstatec hasn't been used in years) but others (like SPICE distributed junctions) are potentially significant sources of unexpected crashes on systems that don't zero uninitialized memory. --- calma/CalmaWrite.c | 10 ++++------ drc/DRCtech.c | 2 +- ext2spice/ext2hier.c | 2 ++ ext2spice/ext2spice.c | 3 ++- plot/plotRutils.c | 1 + plot/plotVers.c | 2 +- router/rtrChannel.c | 1 + select/selCreate.c | 4 ++-- 8 files changed, 14 insertions(+), 11 deletions(-) diff --git a/calma/CalmaWrite.c b/calma/CalmaWrite.c index 44e0d6d9..82b1929f 100644 --- a/calma/CalmaWrite.c +++ b/calma/CalmaWrite.c @@ -365,9 +365,8 @@ CalmaWrite(rootDef, f) */ bool -calmaDumpStructure(def, cellstart, outf, calmaDefHash, filename) +calmaDumpStructure(def, outf, calmaDefHash, filename) CellDef *def; - off_t cellstart; FILE *outf; HashTable *calmaDefHash; char *filename; @@ -593,10 +592,9 @@ syntaxerror: */ void -calmaFullDump(def, fi, cellstart, outf, filename) +calmaFullDump(def, fi, outf, filename) CellDef *def; FILE *fi; - off_t cellstart; FILE *outf; char *filename; { @@ -659,7 +657,7 @@ calmaFullDump(def, fi, cellstart, outf, filename) } HashSetValue(he, StrDup(NULL, uniqlibname)); - while (calmaDumpStructure(def, cellstart, outf, &calmaDefHash, filename)) + while (calmaDumpStructure(def, outf, &calmaDefHash, filename)) if (SigInterruptPending) goto done; calmaSkipExact(CALMA_ENDLIB); @@ -813,7 +811,7 @@ calmaProcessDef(def, outf) he = HashLookOnly(&calmaLibHash, retfilename); if (he == NULL) - calmaFullDump(def, fi, cellstart, outf, retfilename); + calmaFullDump(def, fi, outf, retfilename); fclose(fi); def->cd_flags |= CDVENDORGDS; diff --git a/drc/DRCtech.c b/drc/DRCtech.c index c56f477b..62c09066 100644 --- a/drc/DRCtech.c +++ b/drc/DRCtech.c @@ -2159,9 +2159,9 @@ drcSpacing(argc, argv) } else { - runlength = distance; layers2 = argv[3]; distance = atoi(argv[4]); + runlength = distance; adjacency = argv[5]; why = drcWhyDup(argv[6]); } diff --git a/ext2spice/ext2hier.c b/ext2spice/ext2hier.c index af204cdb..d56a3846 100644 --- a/ext2spice/ext2hier.c +++ b/ext2spice/ext2hier.c @@ -182,6 +182,7 @@ spcHierWriteParams(hc, dev, scale, l, w, sdM) // For parameter an followed by parameter pn, // process both at the same time + sdM = getCurDevMult(); if (plist->parm_next && plist->parm_next->parm_type[0] == 'p' && plist->parm_next->parm_type[1] == plist->parm_type[1]) @@ -228,6 +229,7 @@ spcHierWriteParams(hc, dev, scale, l, w, sdM) // For parameter pn followed by parameter an, // process both at the same time + sdM = getCurDevMult(); if (plist->parm_next && plist->parm_next->parm_type[0] == 'a' && plist->parm_next->parm_type[1] == plist->parm_type[1]) diff --git a/ext2spice/ext2spice.c b/ext2spice/ext2spice.c index 1aa1bfc9..aff8e18c 100644 --- a/ext2spice/ext2spice.c +++ b/ext2spice/ext2spice.c @@ -2335,6 +2335,7 @@ spcdevVisit(dev, hierName, scale, trans) name, esSpiceF); fprintf(esSpiceF, " %s", EFDevTypes[dev->dev_type]); + sdM = getCurDevMult(); spcWriteParams(dev, hierName, scale, l, w, sdM); break; @@ -3796,8 +3797,8 @@ devDistJunctVisit(dev, hierName, scale, trans) return 0; } - w = (int)((float)w * scale); EFGetLengthAndWidth(dev, &l, &w); + w = (int)((float)w * scale); for (i = 1; idev_nterm; i++) { diff --git a/plot/plotRutils.c b/plot/plotRutils.c index 97837334..64e72de9 100644 --- a/plot/plotRutils.c +++ b/plot/plotRutils.c @@ -196,6 +196,7 @@ PlotFreeRaster(raster) * have been created with PlotNewRaster. */ { + if (raster == NULL) return; freeMagic((char *) raster->ras_bits); freeMagic((char *) raster); } diff --git a/plot/plotVers.c b/plot/plotVers.c index fbecfda4..8b797552 100644 --- a/plot/plotVers.c +++ b/plot/plotVers.c @@ -1084,7 +1084,7 @@ PlotVersatec(scx, layers, xMask, user_scale) Raster *raster = NULL; /* CMYK color separated raster buffers. */ - Raster *kRaster, *cRaster, *mRaster, *yRaster; + Raster *kRaster = NULL, *cRaster = NULL, *mRaster = NULL, *yRaster = NULL; haveColorMessage = FALSE; GeoTransRect(&scx->scx_trans, &scx->scx_area, &rootClip); diff --git a/router/rtrChannel.c b/router/rtrChannel.c index 7d448a2a..b6fe742e 100644 --- a/router/rtrChannel.c +++ b/router/rtrChannel.c @@ -310,6 +310,7 @@ RtrChannelObstacles(use, ch) scx.scx_area.r_ytop += w * RtrGridSpacing + down; scx.scx_use = use; scx.scx_trans = GeoIdentityTransform; + TTMaskZero(&allObs); TTMaskSetMask3(&allObs, &RtrMetalObstacles, &RtrPolyObstacles); (void) DBTreeSrTiles(&scx, &allObs, 0, rtrChannelObstacleMark, (ClientData) ch); diff --git a/select/selCreate.c b/select/selCreate.c index f0d74184..1aa495cf 100644 --- a/select/selCreate.c +++ b/select/selCreate.c @@ -1232,8 +1232,8 @@ selACPaintFunc2(tile, selACarg) Rect rrect, orect; int np, i, j; - ttype = (selACarg->ttype & TT_SIDE) ? ((ttype & TT_RIGHTMASK) >> 14) : - ttype & TT_LEFTMASK; + ttype = (selACarg->ttype & TT_SIDE) ? ((selACarg->ttype & TT_RIGHTMASK) >> 14) : + selACarg->ttype & TT_LEFTMASK; if (type & TT_DIAGONAL) rtype = (type & TT_SIDE) ? SplitRightType(tile) : From 6d5d370e8cb172450cb781ac718c8cd5f863aeea Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Fri, 7 Jun 2019 15:00:39 -0400 Subject: [PATCH 26/44] Corrected a few additional uninitialized variable situations that had been shadowed by the previous set of fixes. --- ext2spice/ext2hier.c | 5 ++++- ext2spice/ext2spice.c | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ext2spice/ext2hier.c b/ext2spice/ext2hier.c index d56a3846..5cb2a048 100644 --- a/ext2spice/ext2hier.c +++ b/ext2spice/ext2hier.c @@ -663,6 +663,7 @@ spcdevHierVisit(hc, dev, scale) "base", esSpiceF); fprintf(esSpiceF, " %s", EFDevTypes[dev->dev_type]); + sdM = getCurDevMult(); spcHierWriteParams(hc, dev, scale, l, w, sdM); break; @@ -790,6 +791,7 @@ spcdevHierVisit(hc, dev, scale) subnode->efnode_name->efnn_hier, "diode_bot", esSpiceF); fprintf(esSpiceF, " %s", EFDevTypes[dev->dev_type]); + sdM = getCurDevMult(); spcHierWriteParams(hc, dev, scale, l, w, sdM); break; @@ -810,6 +812,7 @@ spcdevHierVisit(hc, dev, scale) gate->dterm_node->efnode_name->efnn_hier, "diode_top", esSpiceF); fprintf(esSpiceF, " %s", EFDevTypes[dev->dev_type]); + sdM = getCurDevMult(); spcHierWriteParams(hc, dev, scale, l, w, sdM); break; @@ -1516,8 +1519,8 @@ devDistJunctHierVisit(hc, dev, scale) return 0; } - w = (int)((float)w * scale); EFGetLengthAndWidth(dev, &l, &w); + w = (int)((float)w * scale); for (i = 1; idev_nterm; i++) { diff --git a/ext2spice/ext2spice.c b/ext2spice/ext2spice.c index aff8e18c..6947027a 100644 --- a/ext2spice/ext2spice.c +++ b/ext2spice/ext2spice.c @@ -2457,6 +2457,7 @@ spcdevVisit(dev, hierName, scale, trans) name, esSpiceF); fprintf(esSpiceF, " %s", EFDevTypes[dev->dev_type]); + sdM = getCurDevMult(); spcWriteParams(dev, hierName, scale, l, w, sdM); break; @@ -2474,6 +2475,7 @@ spcdevVisit(dev, hierName, scale, trans) name, esSpiceF); fprintf(esSpiceF, " %s", EFDevTypes[dev->dev_type]); + sdM = getCurDevMult(); spcWriteParams(dev, hierName, scale, l, w, sdM); break; From e296246c9265657d43d6acbf1988957e1a8403df Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Fri, 7 Jun 2019 21:39:37 -0400 Subject: [PATCH 27/44] One last correction, as I accidentally dropped two calls to getCurDevMult() inside spcHierWriteParams(), where it was being passed as an argument, therefore making a redundant call and wasting compute cycles. --- ext2spice/ext2hier.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/ext2spice/ext2hier.c b/ext2spice/ext2hier.c index 5cb2a048..e5686cbf 100644 --- a/ext2spice/ext2hier.c +++ b/ext2spice/ext2hier.c @@ -182,7 +182,6 @@ spcHierWriteParams(hc, dev, scale, l, w, sdM) // For parameter an followed by parameter pn, // process both at the same time - sdM = getCurDevMult(); if (plist->parm_next && plist->parm_next->parm_type[0] == 'p' && plist->parm_next->parm_type[1] == plist->parm_type[1]) @@ -229,7 +228,6 @@ spcHierWriteParams(hc, dev, scale, l, w, sdM) // For parameter pn followed by parameter an, // process both at the same time - sdM = getCurDevMult(); if (plist->parm_next && plist->parm_next->parm_type[0] == 'a' && plist->parm_next->parm_type[1] == plist->parm_type[1]) From 5bd3fb91c966fa65c7798cc810bb27f2058be797 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sat, 15 Jun 2019 12:50:32 -0400 Subject: [PATCH 28/44] Corrected the argument passing from the top-level wrapper for configure script to the actual configure script. --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index d47bb69e..ae0a0fc1 100755 --- a/configure +++ b/configure @@ -9,4 +9,4 @@ # script itself. It also sets up CFLAGS without the default optimizer # flag (-O2). -( CFLAGS="-g"; export CFLAGS; cd scripts ; ./configure $* ) +( CFLAGS="-g"; export CFLAGS; cd scripts ; ./configure "$@" ) From 95ca3d93cc9ed81018db2eac37ee5196865b5ffe Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 2 Jul 2019 10:48:34 -0400 Subject: [PATCH 29/44] Added the handling of SHAPE statements in NET records in the DEF file read routine. --- lef/defRead.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lef/defRead.c b/lef/defRead.c index b71d6ddd..a8477fcc 100644 --- a/lef/defRead.c +++ b/lef/defRead.c @@ -431,8 +431,8 @@ endCoord: enum def_net_keys {DEF_NET_START = 0, DEF_NET_END}; enum def_netprop_keys { DEF_NETPROP_USE = 0, DEF_NETPROP_ROUTED, DEF_NETPROP_FIXED, - DEF_NETPROP_COVER, DEF_NETPROP_SOURCE, DEF_NETPROP_WEIGHT, - DEF_NETPROP_PROPERTY}; + DEF_NETPROP_COVER, DEF_NETPROP_SOURCE, DEF_NETPROP_SHAPE, + DEF_NETPROP_WEIGHT, DEF_NETPROP_PROPERTY}; void DefReadNets(f, rootDef, sname, oscale, special, total) @@ -460,6 +460,7 @@ DefReadNets(f, rootDef, sname, oscale, special, total) "FIXED", "COVER", "SOURCE", + "SHAPE", "WEIGHT", "PROPERTY", NULL @@ -516,7 +517,10 @@ DefReadNets(f, rootDef, sname, oscale, special, total) switch (subkey) { case DEF_NETPROP_USE: - /* Presently, we ignore this */ + case DEF_NETPROP_SHAPE: + /* Presently, we ignore this, except to */ + /* absorb the following value. */ + token = LefNextToken(f, TRUE); break; case DEF_NETPROP_ROUTED: case DEF_NETPROP_FIXED: From 49d98115bb4d0849a262c308bf57ecf333b85a81 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 3 Jul 2019 13:58:13 -0400 Subject: [PATCH 30/44] Added a number of enhancements to the DEF reading to handle various forms of syntax found in the LEF/DEF spec up to version 5.8. Handles vias formed by parameter and a number of syntax variations that mess up the usual parsing. Corrected an error in the calculation of wire extensions when wires are given with three coordinates. --- lef/defRead.c | 335 +++++++++++++++++++++++++++++++++++++++++++++++--- lef/lefInt.h | 1 + lef/lefRead.c | 94 ++++++++++++++ 3 files changed, 415 insertions(+), 15 deletions(-) diff --git a/lef/defRead.c b/lef/defRead.c index a8477fcc..5dadbfd4 100644 --- a/lef/defRead.c +++ b/lef/defRead.c @@ -53,6 +53,25 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ *------------------------------------------------------------ */ +enum def_netspecial_keys {DEF_SPECNET_SHAPE = 0, DEF_SPECNET_STYLE, + DEF_SPECNET_USE, DEF_SPECNET_VOLTAGE, DEF_SPECNET_FIXEDBUMP, + DEF_SPECNET_ORIGINAL, DEF_SPECNET_PATTERN, DEF_SPECNET_ESTCAP, + DEF_SPECNET_WEIGHT, DEF_SPECNET_PROPERTY}; + +enum def_netspecial_shape_keys { + DEF_SPECNET_SHAPE_RING = 0, + DEF_SPECNET_SHAPE_PADRING, + DEF_SPECNET_SHAPE_BLOCKRING, + DEF_SPECNET_SHAPE_STRIPE, + DEF_SPECNET_SHAPE_FOLLOWPIN, + DEF_SPECNET_SHAPE_IOWIRE, + DEF_SPECNET_SHAPE_COREWIRE, + DEF_SPECNET_SHAPE_BLOCKWIRE, + DEF_SPECNET_SHAPE_BLOCKAGEWIRE, + DEF_SPECNET_SHAPE_FILLWIRE, + DEF_SPECNET_SHAPE_FILLWIREOPC, + DEF_SPECNET_SHAPE_DRCFILL}; + char * DefAddRoutes(rootDef, f, oscale, special, defLayerMap) CellDef *rootDef; /* Cell to paint */ @@ -67,11 +86,43 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) bool valid = FALSE; /* is there a valid reference point? */ bool initial = TRUE; Rect locarea; + int extend; float x, y, z, w; int routeWidth, paintWidth, saveWidth; TileType routeLayer, paintLayer; HashEntry *he; lefLayer *lefl; + int keyword; + + static char *specnet_keys[] = { + "SHAPE", + "STYLE", + "USE", + "VOLTAGE", + "FIXEDBUMP", + "ORIGINAL", + "PATTERN", + "ESTCAP", + "WEIGHT", + "PROPERTY", + NULL + }; + + static char *specnet_shape_keys[] = { + "RING", + "PADRING", + "BLOCKRING", + "STRIPE", + "FOLLOWPIN", + "IOWIRE", + "COREWIRE", + "BLOCKWIRE", + "BLOCKAGEWIRE", + "FILLWIRE", + "FILLWIREOPC", + "DRCFILL", + NULL + }; while (initial || (token = LefNextToken(f, TRUE)) != NULL) { @@ -130,6 +181,135 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) paintWidth = (lefl) ? lefl->info.route.width : DEFAULT_WIDTH * DBLambda[1] / DBLambda[0]; } + else if ((*token == '+') && (special == TRUE)) + { + int netstyle; + + /* Check for SHAPE, STYLE, or USE keywords */ + token = LefNextToken(f, TRUE); + keyword = Lookup(token, specnet_keys); + if (keyword < 0) + { + LefError(DEF_INFO, "Unknown keyword \"%s\" in SPECIALNET " + "definition; ignoring.\n", token); + LefEndStatement(f); + continue; + } + switch(keyword) + { + case DEF_SPECNET_STYLE: + token = LefNextToken(f, TRUE); + if (sscanf(token, "%d", &netstyle) != 1) + { + LefError(DEF_INFO, "Net style \"%s\" in SPECIALNET " + "definition is not a number; ignoring.\n", token); + LefEndStatement(f); + continue; + } + break; + + case DEF_SPECNET_SHAPE: + token = LefNextToken(f, TRUE); + keyword = Lookup(token, specnet_shape_keys); + if (keyword < 0) + { + LefError(DEF_INFO, "Unknown SHAPE \"%s\" in SPECIALNET " + "definition; ignoring.\n", token); + LefEndStatement(f); + continue; + } + break; + + case DEF_SPECNET_PROPERTY: + /* Ignore except to absorb the next two tokens. */ + token = LefNextToken(f, TRUE); /* Drop through */ + + case DEF_SPECNET_USE: + case DEF_SPECNET_VOLTAGE: + case DEF_SPECNET_ORIGINAL: + case DEF_SPECNET_PATTERN: + case DEF_SPECNET_ESTCAP: + case DEF_SPECNET_WEIGHT: + /* Ignore except to absorb the next token. */ + token = LefNextToken(f, TRUE); /* Drop through */ + + case DEF_SPECNET_FIXEDBUMP: + /* Ignore this keyword */ + break; + + + } + } + else if (!strcmp(token, "RECT")) + { + /* NOTE: Use of "RECT" in NETS is not in the LEF/DEF spec. */ + /* However, its use has been seen. So "special" is not */ + /* checked here. */ + + /* Read an (llx lly urx ury) rectangle */ + token = LefNextToken(f, TRUE); /* read llx */ + if (*token == '(') token = LefNextToken(f, TRUE); + if (sscanf(token, "%f", &x) == 1) + { + locarea.r_xbot = (int)roundf((2 * x) / oscale); + } + else + { + LefError(DEF_ERROR, "Cannot parse X coordinate in RECT.\n"); + goto endCoord; + } + + token = LefNextToken(f, TRUE); /* read lly */ + if (sscanf(token, "%f", &y) == 1) + { + locarea.r_ybot = (int)roundf((2 * y) / oscale); + } + else + { + LefError(DEF_ERROR, "Cannot parse Y coordinate in RECT.\n"); + goto endCoord; + } + + token = LefNextToken(f, TRUE); /* read urx */ + if (sscanf(token, "%f", &x) == 1) + { + locarea.r_xtop = (int)roundf((2 * x) / oscale); + } + else + { + LefError(DEF_ERROR, "Cannot parse X coordinate in RECT.\n"); + goto endCoord; + } + token = LefNextToken(f, TRUE); /* read ury */ + if (sscanf(token, "%f", &y) == 1) + { + locarea.r_ytop = (int)roundf((2 * y) / oscale); + } + else + { + LefError(DEF_ERROR, "Cannot parse Y coordinate in RECT.\n"); + goto endCoord; + } + token = LefNextToken(f, TRUE); /* read closing parens */ + if (*token != ')') + { + LefError(DEF_ERROR, "Bad coordinates in RECT.\n"); + goto endCoord; + } + } + else if (!strcmp(token, "POLYGON")) + { + LefError(DEF_ERROR, "Route has POLYGON entries, this is not handled!\n", + token); + token = LefNextToken(f, TRUE); /* read opening parens */ + goto endCoord; + } + else if (!strcmp(token, "VIRTUAL")) + { + /* Is this a LEF 5.8 thing? Not sure if it should be ignored! */ + /* Should the whole wire leg be ignored? */ + continue; + } else if (*token != '(') /* via name */ { /* A '+' or ';' record ends the route */ @@ -256,7 +436,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) locarea.r_xbot = refp.p_x; locarea.r_ybot = refp.p_y; - /* Read an (X Y) point */ + /* Read an (X Y [extend]) point */ token = LefNextToken(f, TRUE); /* read X */ if (*token == '*') { @@ -301,7 +481,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) /* is apparently how everyone interprets it, and is true for */ /* 5.6 spec. */ - z = (special) ? 0 : paintWidth; + extend = (special) ? 0 : paintWidth; token = LefNextToken(f, TRUE); if (*token != ')') { @@ -313,7 +493,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) /* to multiply up by 2 now. */ else - z *= 2; + extend = (int)roundf((2 * z) / oscale); } /* Indicate that we have a valid reference point */ @@ -351,8 +531,8 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) } else { - newRoute->r_r.r_xbot -= z; - newRoute->r_r.r_xtop += z; + newRoute->r_r.r_xbot -= extend; + newRoute->r_r.r_xtop += extend; } if (newRoute->r_r.r_ybot == newRoute->r_r.r_ytop) @@ -362,8 +542,8 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) } else { - newRoute->r_r.r_ybot -= z; - newRoute->r_r.r_ytop += z; + newRoute->r_r.r_ybot -= extend; + newRoute->r_r.r_ytop += extend; } /* If we don't have integer units here, we should */ @@ -431,8 +611,8 @@ endCoord: enum def_net_keys {DEF_NET_START = 0, DEF_NET_END}; enum def_netprop_keys { DEF_NETPROP_USE = 0, DEF_NETPROP_ROUTED, DEF_NETPROP_FIXED, - DEF_NETPROP_COVER, DEF_NETPROP_SOURCE, DEF_NETPROP_SHAPE, - DEF_NETPROP_WEIGHT, DEF_NETPROP_PROPERTY}; + DEF_NETPROP_COVER, DEF_NETPROP_SOURCE, DEF_NETPROP_WEIGHT, + DEF_NETPROP_PROPERTY}; void DefReadNets(f, rootDef, sname, oscale, special, total) @@ -460,7 +640,6 @@ DefReadNets(f, rootDef, sname, oscale, special, total) "FIXED", "COVER", "SOURCE", - "SHAPE", "WEIGHT", "PROPERTY", NULL @@ -517,7 +696,6 @@ DefReadNets(f, rootDef, sname, oscale, special, total) switch (subkey) { case DEF_NETPROP_USE: - case DEF_NETPROP_SHAPE: /* Presently, we ignore this, except to */ /* absorb the following value. */ token = LefNextToken(f, TRUE); @@ -697,7 +875,8 @@ enum def_pins_keys {DEF_PINS_START = 0, DEF_PINS_END}; enum def_pins_prop_keys { DEF_PINS_PROP_NET = 0, DEF_PINS_PROP_DIR, DEF_PINS_PROP_LAYER, DEF_PINS_PROP_USE, - DEF_PINS_PROP_PLACED, DEF_PINS_PROP_FIXED}; + DEF_PINS_PROP_PLACED, DEF_PINS_PROP_FIXED, + DEF_PINS_PROP_PORT, DEF_PINS_PROP_SPECIAL}; void DefReadPins(f, rootDef, sname, oscale, total) @@ -718,6 +897,7 @@ DefReadPins(f, rootDef, sname, oscale, total) Transform t; lefLayer *lefl; bool pending = FALSE; + bool hasports = FALSE; static char *pin_keys[] = { "-", @@ -732,6 +912,8 @@ DefReadPins(f, rootDef, sname, oscale, total) "USE", "PLACED", "FIXED", + "PORT", + "SPECIAL", NULL }; @@ -768,6 +950,7 @@ DefReadPins(f, rootDef, sname, oscale, total) switch (keyword) { case DEF_PINS_START: /* "-" keyword */ + hasports = FALSE; // Flag an error if a pin was waiting on a layer // specification that was never given. @@ -804,12 +987,24 @@ DefReadPins(f, rootDef, sname, oscale, total) subkey = Lookup(token, pin_property_keys); if (subkey < 0) { - LefError(DEF_ERROR, "Unknown pin property \"%s\" in " + LefError(DEF_INFO, "Unknown pin property \"%s\" in " "PINS definition; ignoring.\n", token); continue; } switch (subkey) { + case DEF_PINS_PROP_SPECIAL: + /* Ignore this */ + break; + case DEF_PINS_PROP_PORT: + /* Ignore this, except that each port adds to */ + /* the count of total pins processed. Note */ + /* that since "processed" is incremented before */ + /* the first PORT is seen, then "processed" */ + /* should not be incremented until the 2nd PORT */ + if (hasports) processed++; + hasports = TRUE; + break; case DEF_PINS_PROP_USE: case DEF_PINS_PROP_NET: /* Get the net name, but ignore it */ @@ -909,7 +1104,10 @@ DefReadPins(f, rootDef, sname, oscale, total) enum def_vias_keys {DEF_VIAS_START = 0, DEF_VIAS_END}; enum def_vias_prop_keys { - DEF_VIAS_PROP_RECT = 0}; + DEF_VIAS_PROP_RECT = 0, DEF_VIAS_PROP_VIARULE, + DEF_VIAS_PROP_CUTSIZE, DEF_VIAS_PROP_LAYERS, + DEF_VIAS_PROP_CUTSPACING, DEF_VIAS_PROP_ENCLOSURE, + DEF_VIAS_PROP_ROWCOL}; void DefReadVias(f, sname, oscale, total) @@ -927,6 +1125,13 @@ DefReadVias(f, sname, oscale, total) lefLayer *lefl; HashEntry *he; + /* For generated vias */ + bool generated = FALSE; + int sizex, sizey, spacex, spacey; + int encbx, encby, enctx, encty; + int rows = 1, cols = 1; + TileType tlayer, clayer, blayer; + static char *via_keys[] = { "-", "END", @@ -935,6 +1140,12 @@ DefReadVias(f, sname, oscale, total) static char *via_property_keys[] = { "RECT", + "VIARULE", + "CUTSIZE", + "LAYERS", + "CUTSPACING", + "ENCLOSURE", + "ROWCOL", NULL }; @@ -991,7 +1202,17 @@ DefReadVias(f, sname, oscale, total) while ((token = LefNextToken(f, TRUE)) != NULL) { - if (*token == ';') break; + if (*token == ';') { + if (generated == TRUE) { + /* Complete the generated via */ + LefGenViaGeometry(f, lefl, + sizex, sizey, spacex, spacey, + encbx, encby, enctx, encty, + rows, cols, tlayer, clayer, blayer, + oscale); + } + break; + } if (*token != '+') continue; token = LefNextToken(f, TRUE); @@ -1008,6 +1229,90 @@ DefReadVias(f, sname, oscale, total) curlayer = LefReadLayer(f, FALSE); LefAddViaGeometry(f, lefl, curlayer, oscale); break; + + case DEF_VIAS_PROP_VIARULE: + token = LefNextToken(f, TRUE); + /* Ignore this. To do: Parse VIARULE statements */ + /* and use the rule to fill any missing values. */ + break; + case DEF_VIAS_PROP_CUTSIZE: + token = LefNextToken(f, TRUE); + if (sscanf(token, "%d", &sizex) != 1) + { + LefError(DEF_ERROR, "Invalid syntax for CUTSIZE.\n"); + /* To do: Get cut size from DRC ruleset */ + } + token = LefNextToken(f, TRUE); + if (sscanf(token, "%d", &sizey) != 1) + { + LefError(DEF_ERROR, "Invalid syntax for CUTSIZE.\n"); + /* To do: Get cut size from DRC ruleset */ + } + generated = TRUE; + break; + case DEF_VIAS_PROP_LAYERS: + blayer = LefReadLayer(f, FALSE); + clayer = LefReadLayer(f, FALSE); + tlayer = LefReadLayer(f, FALSE); + generated = TRUE; + break; + case DEF_VIAS_PROP_CUTSPACING: + token = LefNextToken(f, TRUE); + if (sscanf(token, "%d", &spacex) != 1) + { + LefError(DEF_ERROR, "Invalid syntax for CUTSPACING.\n"); + /* To do: Get cut spacing from DRC ruleset */ + } + token = LefNextToken(f, TRUE); + if (sscanf(token, "%d", &spacey) != 1) + { + LefError(DEF_ERROR, "Invalid syntax for CUTSPACING.\n"); + /* To do: Get cut spacing from DRC ruleset */ + } + generated = TRUE; + break; + case DEF_VIAS_PROP_ENCLOSURE: + token = LefNextToken(f, TRUE); + if (sscanf(token, "%d", &enctx) != 1) + { + LefError(DEF_ERROR, "Invalid syntax for ENCLOSURE.\n"); + /* To do: Get cut enclosures from DRC ruleset */ + } + token = LefNextToken(f, TRUE); + if (sscanf(token, "%d", &encty) != 1) + { + LefError(DEF_ERROR, "Invalid syntax for ENCLOSURE.\n"); + /* To do: Get cut enclosures from DRC ruleset */ + } + token = LefNextToken(f, TRUE); + if (sscanf(token, "%d", &encbx) != 1) + { + LefError(DEF_ERROR, "Invalid syntax for ENCLOSURE.\n"); + /* To do: Get cut enclosures from DRC ruleset */ + } + token = LefNextToken(f, TRUE); + if (sscanf(token, "%d", &encby) != 1) + { + LefError(DEF_ERROR, "Invalid syntax for ENCLOSURE.\n"); + /* To do: Get cut enclosures from DRC ruleset */ + } + generated = TRUE; + break; + case DEF_VIAS_PROP_ROWCOL: + token = LefNextToken(f, TRUE); + if (sscanf(token, "%d", &rows) != 1) + { + LefError(DEF_ERROR, "Invalid syntax for ROWCOL.\n"); + rows = 1; + } + token = LefNextToken(f, TRUE); + if (sscanf(token, "%d", &cols) != 1) + { + LefError(DEF_ERROR, "Invalid syntax for ROWCOL.\n"); + cols = 1; + } + generated = TRUE; + break; } } break; diff --git a/lef/lefInt.h b/lef/lefInt.h index 8f069404..9c31dd80 100644 --- a/lef/lefInt.h +++ b/lef/lefInt.h @@ -126,6 +126,7 @@ LinkedRect *LefReadGeometry(); void LefEstimate(); lefLayer *LefRedefined(); void LefAddViaGeometry(); +void LefGenViaGeometry(); Rect *LefReadRect(); TileType LefReadLayer(); diff --git a/lef/lefRead.c b/lef/lefRead.c index 43ef32d9..95479743 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -1729,6 +1729,100 @@ origin_error: &DBAllButSpaceBits); } +/* + *------------------------------------------------------------ + * + * LefGenViaGeometry -- + * + * Create geometry for a VIA section from a DEF file + * using via generation parameters. + * + * Results: + * None. + * + * Side Effects: + * Adds to the lefLayer record for a via definition. + * + *------------------------------------------------------------ + */ + +void +LefGenViaGeometry(f, lefl, sizex, sizey, spacex, spacey, + encbx, encby, enctx, encty, rows, cols, + tlayer, clayer, blayer, oscale) + FILE *f; /* LEF file being read */ + lefLayer *lefl; /* pointer to via info */ + int sizex, sizey; /* cut size */ + int spacex, spacey; /* cut spacing */ + int encbx, encby; /* bottom enclosure of cuts */ + int enctx, encty; /* top enclosure of cuts */ + int rows, cols; /* number of cut rows and columns */ + TileType tlayer; /* Top layer type */ + TileType clayer; /* Cut layer type */ + TileType blayer; /* Bottom layer type */ + float oscale; /* output scaling */ +{ + Rect rect; + int i, j, x, y, w, h, sw, sh; + LinkedRect *viaLR; + + /* Compute top layer rect */ + + w = (sizex * cols) + (spacex * (cols - 1)) + 2 * enctx; + h = (sizey * rows) + (spacey * (rows - 1)) + 2 * encty; + + rect.r_xtop = (int)roundf(w / oscale); + rect.r_xbot = -rect.r_xtop; + rect.r_ytop = (int)roundf(h / oscale); + rect.r_ybot = -rect.r_ytop; + + /* Set via area to the top layer */ + lefl->info.via.area = rect; + lefl->type = tlayer; + + /* Compute bottom layer rect */ + + w = (sizex * cols) + (spacex * (cols - 1)) + 2 * encbx; + h = (sizey * rows) + (spacey * (rows - 1)) + 2 * encby; + + rect.r_xtop = (int)roundf(w / oscale); + rect.r_xbot = -rect.r_xtop; + rect.r_ytop = (int)roundf(h / oscale); + rect.r_ybot = -rect.r_ytop; + + viaLR = (LinkedRect *)mallocMagic(sizeof(LinkedRect)); + viaLR->r_next = lefl->info.via.lr; + lefl->info.via.lr = viaLR; + viaLR->r_type = tlayer; + viaLR->r_r = rect; + + w = (sizex * cols) + (spacex * (cols - 1)); + h = (sizey * rows) + (spacey * (rows - 1)); + x = -w / 2; + y = -h / 2; + + for (i = 0; i < cols; i++) + { + for (j = 0; j < rows; j++) + { + rect.r_xbot = (int)roundf(x / oscale); + rect.r_ybot = (int)roundf(y / oscale); + rect.r_xtop = rect.r_xbot + (int)roundf(sizex / oscale); + rect.r_ytop = rect.r_ybot + (int)roundf(sizey / oscale); + + viaLR = (LinkedRect *)mallocMagic(sizeof(LinkedRect)); + viaLR->r_next = lefl->info.via.lr; + lefl->info.via.lr = viaLR; + viaLR->r_type = clayer; + viaLR->r_r = rect; + + y += sizey + spacey; + } + x += sizex + spacex; + y = -h / 2; + } +} + /* *------------------------------------------------------------ * From 38fa141db57ff29c5c1a113a13a0256b91357b59 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 3 Jul 2019 14:05:01 -0400 Subject: [PATCH 31/44] One minor correction to the creation of generated vias in defRead.c. --- lef/lefRead.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lef/lefRead.c b/lef/lefRead.c index 95479743..6986135c 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -1765,6 +1765,7 @@ LefGenViaGeometry(f, lefl, sizex, sizey, spacex, spacey, Rect rect; int i, j, x, y, w, h, sw, sh; LinkedRect *viaLR; + float hscale = oscale / 2; /* Compute top layer rect */ @@ -1805,10 +1806,10 @@ LefGenViaGeometry(f, lefl, sizex, sizey, spacex, spacey, { for (j = 0; j < rows; j++) { - rect.r_xbot = (int)roundf(x / oscale); - rect.r_ybot = (int)roundf(y / oscale); - rect.r_xtop = rect.r_xbot + (int)roundf(sizex / oscale); - rect.r_ytop = rect.r_ybot + (int)roundf(sizey / oscale); + rect.r_xbot = (int)roundf(x / hscale); + rect.r_ybot = (int)roundf(y / hscale); + rect.r_xtop = rect.r_xbot + (int)roundf(sizex / hscale); + rect.r_ytop = rect.r_ybot + (int)roundf(sizey / hscale); viaLR = (LinkedRect *)mallocMagic(sizeof(LinkedRect)); viaLR->r_next = lefl->info.via.lr; From 5ba84b068abb29c3ebcbb3566c93a43e91ac03a5 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 3 Jul 2019 14:24:52 -0400 Subject: [PATCH 32/44] Was missing needed expansion of via cut sizes to match magic's internal definition of via areas, when reading parameterized vias from a DEF file. --- lef/lefRead.c | 181 ++++++++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 81 deletions(-) diff --git a/lef/lefRead.c b/lef/lefRead.c index 6986135c..3b5e7cbf 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -1729,6 +1729,101 @@ origin_error: &DBAllButSpaceBits); } +/* + *------------------------------------------------------------ + * + * LefGrowVia --- + * + * For LEF contact types matching magic contact types, size the + * LEF contact cut to cover the minimum rectangle in the other + * layers that satisfies the CIF/GDS contact generation. Use + * the "cifinput" style to determine how much the via layer + * needs to grow to make a contact area. If the "cifinput" + * style is not defined, then determine rules from "cifoutput". + * + *------------------------------------------------------------ + */ + +void LefGrowVia(curlayer, currect, lefl) + TileType curlayer; + Rect *currect; + lefLayer *lefl; +{ + if (DBIsContact(curlayer) && cifCurReadStyle != NULL) + { + int growSize; + + /* Get the amount (in magic units) that the layer needs to */ + /* expand according to the "cifinput" style rules to convert */ + /* a contact cut to a magic contact layer. */ + + growSize = CIFReadGetGrowSize(curlayer); + + /* All internal LEF via geometry values are doubled */ + growSize <<= 1; + + if (growSize % cifCurReadStyle->crs_scaleFactor == 0) + growSize /= cifCurReadStyle->crs_scaleFactor; + else + growSize = growSize / cifCurReadStyle->crs_scaleFactor + 1; + + if (growSize > 0) + { + /* cifinput styles expect the cut size to be correct, so */ + /* there is no check for correctness of the layer. */ + + currect->r_xbot = currect->r_xbot - growSize; + currect->r_ybot = currect->r_ybot - growSize; + currect->r_xtop = currect->r_xtop + growSize; + currect->r_ytop = currect->r_ytop + growSize; + } + } + else if (DBIsContact(curlayer) && CIFCurStyle != NULL) + { + int edgeSize = 0, contSize, halfSize; + + /* Get the minimum size of a contact (cut + borders) from cifoutput */ + contSize = CIFGetContactSize(curlayer, &edgeSize, NULL, NULL); + + /* All internal LEF via geometry values are doubled */ + contSize <<= 1; + edgeSize <<= 1; + + if (contSize % CIFCurStyle->cs_scaleFactor == 0) + contSize /= CIFCurStyle->cs_scaleFactor; + else + contSize = contSize / CIFCurStyle->cs_scaleFactor + 1; + + if (edgeSize % CIFCurStyle->cs_scaleFactor == 0) + edgeSize /= CIFCurStyle->cs_scaleFactor; + else + edgeSize = edgeSize / CIFCurStyle->cs_scaleFactor + 1; + + if (edgeSize > 0 && contSize > 0) + { + /* Flag a warning if the cut size is different from what's expected */ + if ((currect->r_xtop - currect->r_xbot != edgeSize) || + (currect->r_ytop - currect->r_ybot != edgeSize)) + { + LefError(LEF_WARNING, "Cut size for magic type \"%s\" (%d x %d) does " + "not match LEF/DEF\n", + DBTypeLongNameTbl[lefl->type], + edgeSize, edgeSize); + LefError(LEF_WARNING, "Via cut size (%d x %d). Magic layer " + "cut size will be used!\n", + currect->r_xtop - currect->r_xbot, + currect->r_ytop - currect->r_ybot); + } + + halfSize = contSize >> 1; + currect->r_xbot = ((currect->r_xbot + currect->r_xtop) / 2) - halfSize; + currect->r_ybot = ((currect->r_ybot + currect->r_ytop) / 2) - halfSize; + currect->r_xtop = currect->r_xbot + contSize; + currect->r_ytop = currect->r_ybot + contSize; + } + } +} + /* *------------------------------------------------------------ * @@ -1811,6 +1906,9 @@ LefGenViaGeometry(f, lefl, sizex, sizey, spacex, spacey, rect.r_xtop = rect.r_xbot + (int)roundf(sizex / hscale); rect.r_ytop = rect.r_ybot + (int)roundf(sizey / hscale); + /* Expand via to the size used by magic */ + LefGrowVia(clayer, &rect, lefl); + viaLR = (LinkedRect *)mallocMagic(sizeof(LinkedRect)); viaLR->r_next = lefl->info.via.lr; lefl->info.via.lr = viaLR; @@ -1858,87 +1956,8 @@ LefAddViaGeometry(f, lefl, curlayer, oscale) /* Don't create any geometry for unknown layers! */ if (curlayer < 0) return; - /* For LEF contact types matching magic contact types, */ - /* size the LEF contact cut to cover the minimum */ - /* rectangle in the other layers that satisfies the */ - /* CIF/GDS contact generation. Use the "cifinput" style */ - /* to determine how much the via layer needs to grow to */ - /* make a contact area. If the "cifinput" style is not */ - /* defined, then determine rules from "cifoutput". */ - - if (DBIsContact(curlayer) && cifCurReadStyle != NULL) - { - int growSize; - - /* Get the amount (in magic units) that the layer needs to */ - /* expand according to the "cifinput" style rules to convert */ - /* a contact cut to a magic contact layer. */ - - growSize = CIFReadGetGrowSize(curlayer); - - /* All internal LEF via geometry values are doubled */ - growSize <<= 1; - - if (growSize % cifCurReadStyle->crs_scaleFactor == 0) - growSize /= cifCurReadStyle->crs_scaleFactor; - else - growSize = growSize / cifCurReadStyle->crs_scaleFactor + 1; - - if (growSize > 0) - { - /* cifinput styles expect the cut size to be correct, so */ - /* there is no check for correctness of the layer. */ - - currect->r_xbot = currect->r_xbot - growSize; - currect->r_ybot = currect->r_ybot - growSize; - currect->r_xtop = currect->r_xtop + growSize; - currect->r_ytop = currect->r_ytop + growSize; - } - } - else if (DBIsContact(curlayer) && CIFCurStyle != NULL) - { - int edgeSize = 0, contSize, halfSize; - - /* Get the minimum size of a contact (cut + borders) from cifoutput */ - contSize = CIFGetContactSize(curlayer, &edgeSize, NULL, NULL); - - /* All internal LEF via geometry values are doubled */ - contSize <<= 1; - edgeSize <<= 1; - - if (contSize % CIFCurStyle->cs_scaleFactor == 0) - contSize /= CIFCurStyle->cs_scaleFactor; - else - contSize = contSize / CIFCurStyle->cs_scaleFactor + 1; - - if (edgeSize % CIFCurStyle->cs_scaleFactor == 0) - edgeSize /= CIFCurStyle->cs_scaleFactor; - else - edgeSize = edgeSize / CIFCurStyle->cs_scaleFactor + 1; - - if (edgeSize > 0 && contSize > 0) - { - /* Flag a warning if the cut size is different from what's expected */ - if ((currect->r_xtop - currect->r_xbot != edgeSize) || - (currect->r_ytop - currect->r_ybot != edgeSize)) - { - LefError(LEF_WARNING, "Cut size for magic type \"%s\" (%d x %d) does " - "not match LEF/DEF\n", - DBTypeLongNameTbl[lefl->type], - edgeSize, edgeSize); - LefError(LEF_WARNING, "Via cut size (%d x %d). Magic layer " - "cut size will be used!\n", - currect->r_xtop - currect->r_xbot, - currect->r_ytop - currect->r_ybot); - } - - halfSize = contSize >> 1; - currect->r_xbot = ((currect->r_xbot + currect->r_xtop) / 2) - halfSize; - currect->r_ybot = ((currect->r_ybot + currect->r_ytop) / 2) - halfSize; - currect->r_xtop = currect->r_xbot + contSize; - currect->r_ytop = currect->r_ybot + contSize; - } - } + /* Expand via to the size used by magic */ + LefGrowVia(curlayer, currect, lefl); if (GEO_SAMERECT(lefl->info.via.area, GeoNullRect)) { From 0141ca8c95fc4a661ae29fd9d83501b74eb9605a Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 3 Jul 2019 14:52:22 -0400 Subject: [PATCH 33/44] Corrected error in generated vias (set top layer type on bottom, so bottom layer went missing). --- lef/defRead.c | 25 ++++++++++++++++++++----- lef/lefRead.c | 2 +- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/lef/defRead.c b/lef/defRead.c index 5dadbfd4..ed824a25 100644 --- a/lef/defRead.c +++ b/lef/defRead.c @@ -86,7 +86,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) bool valid = FALSE; /* is there a valid reference point? */ bool initial = TRUE; Rect locarea; - int extend; + int extend, lextend, hextend; float x, y, z, w; int routeWidth, paintWidth, saveWidth; TileType routeLayer, paintLayer; @@ -435,6 +435,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) /* Record current reference point */ locarea.r_xbot = refp.p_x; locarea.r_ybot = refp.p_y; + lextend = extend; /* Read an (X Y [extend]) point */ token = LefNextToken(f, TRUE); /* read X */ @@ -510,6 +511,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) LefError(DEF_ERROR, "Can't deal with nonmanhattan geometry in route.\n"); locarea.r_xbot = refp.p_x; locarea.r_ybot = refp.p_y; + lextend = extend; } else { @@ -522,6 +524,19 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) locarea.r_xtop = refp.p_x; locarea.r_ytop = refp.p_y; + /* Change route segment to a canonical rectangle. If */ + /* the route is flipped relative to canonical coords, */ + /* then the wire extentions have to be swapped as well. */ + + if ((locarea.r_xtop < locarea.r_xbot) || + (locarea.r_ytop < locarea.r_ybot)) + { + hextend = lextend; + lextend = extend; + } + else + hextend = extend; + GeoCanonicalRect(&locarea, &newRoute->r_r); if (newRoute->r_r.r_xbot == newRoute->r_r.r_xtop) @@ -531,8 +546,8 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) } else { - newRoute->r_r.r_xbot -= extend; - newRoute->r_r.r_xtop += extend; + newRoute->r_r.r_xbot -= lextend; + newRoute->r_r.r_xtop += hextend; } if (newRoute->r_r.r_ybot == newRoute->r_r.r_ytop) @@ -542,8 +557,8 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) } else { - newRoute->r_r.r_ybot -= extend; - newRoute->r_r.r_ytop += extend; + newRoute->r_r.r_ybot -= lextend; + newRoute->r_r.r_ytop += hextend; } /* If we don't have integer units here, we should */ diff --git a/lef/lefRead.c b/lef/lefRead.c index 3b5e7cbf..a212aecf 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -1889,7 +1889,7 @@ LefGenViaGeometry(f, lefl, sizex, sizey, spacex, spacey, viaLR = (LinkedRect *)mallocMagic(sizeof(LinkedRect)); viaLR->r_next = lefl->info.via.lr; lefl->info.via.lr = viaLR; - viaLR->r_type = tlayer; + viaLR->r_type = blayer; viaLR->r_r = rect; w = (sizex * cols) + (spacex * (cols - 1)); From d839cc26e287dd07ef705c71921ee15134b25b63 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 3 Jul 2019 15:36:21 -0400 Subject: [PATCH 34/44] One last problem fixed, as RECT entries in nets are relative, not absolute. --- lef/defRead.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lef/defRead.c b/lef/defRead.c index ed824a25..ab8cdfda 100644 --- a/lef/defRead.c +++ b/lef/defRead.c @@ -246,12 +246,17 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) /* However, its use has been seen. So "special" is not */ /* checked here. */ + /* The rectangle coordinates are relative to the current */ + /* reference point, not absolute. */ + + newRoute = (LinkedRect *)mallocMagic(sizeof(LinkedRect)); + /* Read an (llx lly urx ury) rectangle */ token = LefNextToken(f, TRUE); /* read llx */ if (*token == '(') token = LefNextToken(f, TRUE); if (sscanf(token, "%f", &x) == 1) { - locarea.r_xbot = (int)roundf((2 * x) / oscale); + locarea.r_xbot = (refp.p_x / 2) + (int)roundf(x / oscale); } else { @@ -262,7 +267,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) token = LefNextToken(f, TRUE); /* read lly */ if (sscanf(token, "%f", &y) == 1) { - locarea.r_ybot = (int)roundf((2 * y) / oscale); + locarea.r_ybot = (refp.p_y / 2) + (int)roundf(y / oscale); } else { @@ -273,7 +278,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) token = LefNextToken(f, TRUE); /* read urx */ if (sscanf(token, "%f", &x) == 1) { - locarea.r_xtop = (int)roundf((2 * x) / oscale); + locarea.r_xtop = (refp.p_x / 2) + (int)roundf(x / oscale); } else { @@ -283,7 +288,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) token = LefNextToken(f, TRUE); /* read ury */ if (sscanf(token, "%f", &y) == 1) { - locarea.r_ytop = (int)roundf((2 * y) / oscale); + locarea.r_ytop = (refp.p_y / 2) + (int)roundf(y / oscale); } else { @@ -296,6 +301,7 @@ DefAddRoutes(rootDef, f, oscale, special, defLayerMap) LefError(DEF_ERROR, "Bad coordinates in RECT.\n"); goto endCoord; } + GeoCanonicalRect(&locarea, &newRoute->r_r); } else if (!strcmp(token, "POLYGON")) { From d95d8ba2efb36377ea88392be4dfcf928f804d82 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 8 Jul 2019 20:36:48 -0400 Subject: [PATCH 35/44] Corrected the generation of bounding box positions from a GDS boundary layer, which was being saved in GDS coordinates, not magic database coordinates. --- cif/CIFrdcl.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/cif/CIFrdcl.c b/cif/CIFrdcl.c index 1ddbfb8e..d9809ec2 100644 --- a/cif/CIFrdcl.c +++ b/cif/CIFrdcl.c @@ -700,8 +700,31 @@ cifMakeBoundaryFunc(tile, clientdata) Rect area; char propertyvalue[128], *storedvalue; + int savescale; TiToRect(tile, &area); + area.r_xtop = CIFScaleCoord(area.r_xtop, COORD_EXACT); + savescale = cifCurReadStyle->crs_scaleFactor; + area.r_ytop = CIFScaleCoord(area.r_ytop, COORD_EXACT); + if (savescale != cifCurReadStyle->crs_scaleFactor) + { + area.r_xtop *= (savescale / cifCurReadStyle->crs_scaleFactor); + savescale = cifCurReadStyle->crs_scaleFactor; + } + area.r_xbot = CIFScaleCoord(area.r_xbot, COORD_EXACT); + 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, COORD_EXACT); + 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); + } if (cifReadCellDef->cd_flags & CDFIXEDBBOX) CIFReadError("Warning: Cell %s boundary was redefined.\n", @@ -712,6 +735,7 @@ cifMakeBoundaryFunc(tile, clientdata) storedvalue = StrDup((char **)NULL, propertyvalue); DBPropPut(cifReadCellDef, "FIXED_BBOX", storedvalue); cifReadCellDef->cd_flags |= CDFIXEDBBOX; + return 0; } /* Paint CIF layer geometry into the current cell def as magic layer "type" */ From c31b3058482ffb06fb27946fe18aa1c8a791a17d Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Sun, 14 Jul 2019 12:07:38 -0400 Subject: [PATCH 36/44] Corrected the dependency list in the Makefile for "modules", which should depend on database/database.h; otherwise running distributed make can start compiling modules before the database.h file is created. --- Makefile | 2 +- cif/Depend | 5 +++-- commands/Depend | 11 ++++++----- drc/Depend | 8 ++++---- extcheck/Depend | 3 --- extract/Depend | 9 +++++---- graphics/Depend | 33 +++++++++++++++++++++++++++++---- lef/Depend | 2 +- lisp/Depend | 6 ++++++ textio/Depend | 14 +++++++------- utils/Depend | 31 ++++++++++++++++--------------- windows/Depend | 2 +- 12 files changed, 79 insertions(+), 47 deletions(-) delete mode 100644 extcheck/Depend diff --git a/Makefile b/Makefile index 2e483885..58eeedb1 100644 --- a/Makefile +++ b/Makefile @@ -47,7 +47,7 @@ database/database.h: database/database.h.in @echo --- making header file database/database.h ${SCRIPTS}/makedbh database/database.h.in database/database.h -modules: +modules: database/database.h depend @echo --- making modules for dir in ${MODULES} ${PROGRAMS}; do \ (cd $$dir && ${MAKE} module); done diff --git a/cif/Depend b/cif/Depend index cb199a1e..3ebdec12 100644 --- a/cif/Depend +++ b/cif/Depend @@ -12,8 +12,9 @@ CIFmain.o: CIFmain.c ../tcltk/tclmagic.h ../utils/magic.h \ ../windows/windows.h ../dbwind/dbwind.h ../utils/styles.h CIFrdcl.o: CIFrdcl.c ../utils/magic.h ../utils/malloc.h \ ../utils/geometry.h ../tiles/tile.h ../utils/hash.h ../utils/undo.h \ - ../database/database.h ../cif/CIFint.h ../cif/CIFread.h ../utils/utils.h \ - ../windows/windows.h ../dbwind/dbwind.h ../utils/main.h ../drc/drc.h + ../database/database.h ../cif/CIFint.h ../cif/CIFread.h ../cif/cif.h \ + ../calma/calma.h ../utils/utils.h ../windows/windows.h \ + ../dbwind/dbwind.h ../utils/main.h ../drc/drc.h CIFrdpt.o: CIFrdpt.c ../utils/magic.h ../utils/geometry.h ../tiles/tile.h \ ../utils/hash.h ../utils/malloc.h ../database/database.h \ ../windows/windows.h ../utils/main.h ../cif/CIFint.h ../cif/CIFread.h diff --git a/commands/Depend b/commands/Depend index b2c29da6..9e566656 100644 --- a/commands/Depend +++ b/commands/Depend @@ -40,11 +40,12 @@ CmdLQ.o: CmdLQ.c ../tcltk/tclmagic.h ../utils/magic.h ../utils/malloc.h \ ../netmenu/netmenu.h CmdRS.o: CmdRS.c ../tcltk/tclmagic.h ../utils/magic.h ../utils/stack.h \ ../utils/geometry.h ../utils/utils.h ../tiles/tile.h ../utils/hash.h \ - ../database/database.h ../database/fonts.h ../windows/windows.h \ - ../dbwind/dbwind.h ../utils/main.h ../commands/commands.h \ - ../textio/textio.h ../graphics/graphics.h ../utils/tech.h ../drc/drc.h \ - ../textio/txcommands.h ../utils/malloc.h ../utils/netlist.h \ - ../netmenu/netmenu.h ../select/select.h ../utils/signals.h ../sim/sim.h + ../utils/styles.h ../database/database.h ../database/fonts.h \ + ../windows/windows.h ../dbwind/dbwind.h ../utils/main.h \ + ../commands/commands.h ../textio/textio.h ../graphics/graphics.h \ + ../utils/tech.h ../drc/drc.h ../textio/txcommands.h ../utils/malloc.h \ + ../utils/netlist.h ../netmenu/netmenu.h ../select/select.h \ + ../utils/signals.h ../sim/sim.h CmdTZ.o: CmdTZ.c ../tcltk/tclmagic.h ../utils/magic.h ../utils/malloc.h \ ../utils/geometry.h ../utils/utils.h ../tiles/tile.h ../utils/hash.h \ ../database/database.h ../windows/windows.h ../dbwind/dbwind.h \ diff --git a/drc/Depend b/drc/Depend index d8c486cb..08a0cf08 100644 --- a/drc/Depend +++ b/drc/Depend @@ -15,10 +15,10 @@ DRCcontin.o: DRCcontin.c ../tcltk/tclmagic.h ../utils/magic.h \ ../dbwind/dbwtech.h ../utils/main.h ../commands/commands.h ../drc/drc.h \ ../utils/signals.h ../graphics/graphics.h ../utils/undo.h \ ../utils/malloc.h -DRCmain.o: DRCmain.c ../utils/magic.h ../utils/malloc.h \ - ../textio/textio.h ../utils/geometry.h ../tiles/tile.h ../utils/hash.h \ - ../database/database.h ../windows/windows.h ../dbwind/dbwind.h \ - ../drc/drc.h ../utils/undo.h +DRCmain.o: DRCmain.c ../tcltk/tclmagic.h ../utils/magic.h \ + ../utils/malloc.h ../textio/textio.h ../utils/geometry.h ../tiles/tile.h \ + ../utils/hash.h ../database/database.h ../windows/windows.h \ + ../dbwind/dbwind.h ../drc/drc.h ../utils/undo.h DRCsubcell.o: DRCsubcell.c ../utils/magic.h ../textio/textio.h \ ../utils/geometry.h ../tiles/tile.h ../utils/hash.h \ ../database/database.h ../drc/drc.h ../windows/windows.h \ diff --git a/extcheck/Depend b/extcheck/Depend deleted file mode 100644 index 9cba00af..00000000 --- a/extcheck/Depend +++ /dev/null @@ -1,3 +0,0 @@ -extcheck.o: extcheck.c ../utils/magic.h ../utils/paths.h \ - ../utils/geometry.h ../utils/hash.h ../utils/utils.h \ - ../utils/pathvisit.h ../extflat/extflat.h ../utils/runstats.h diff --git a/extract/Depend b/extract/Depend index 7171cc1a..cf4319dd 100644 --- a/extract/Depend +++ b/extract/Depend @@ -9,7 +9,7 @@ ExtBasic.o: ExtBasic.c ../tcltk/tclmagic.h ../utils/magic.h \ ../database/database.h ../utils/malloc.h ../textio/textio.h \ ../debug/debug.h ../extract/extract.h ../extract/extractInt.h \ ../extract/extDebugInt.h ../utils/signals.h ../windows/windows.h \ - ../dbwind/dbwind.h ../utils/styles.h ../utils/stack.h + ../dbwind/dbwind.h ../utils/styles.h ../utils/stack.h ../utils/utils.h ExtCell.o: ExtCell.c ../utils/magic.h ../utils/geometry.h \ ../utils/styles.h ../tiles/tile.h ../utils/hash.h ../database/database.h \ ../utils/malloc.h ../textio/textio.h ../debug/debug.h \ @@ -57,8 +57,8 @@ ExtRegion.o: ExtRegion.c ../utils/magic.h ../utils/geometry.h \ ../tiles/tile.h ../utils/hash.h ../database/database.h ../utils/malloc.h \ ../textio/textio.h ../debug/debug.h ../extract/extract.h \ ../extract/extractInt.h ../extract/extDebugInt.h ../utils/signals.h -ExtSubtree.o: ExtSubtree.c ../utils/magic.h ../utils/geometry.h \ - ../utils/geofast.h ../tiles/tile.h ../utils/hash.h \ +ExtSubtree.o: ExtSubtree.c ../tcltk/tclmagic.h ../utils/magic.h \ + ../utils/geometry.h ../utils/geofast.h ../tiles/tile.h ../utils/hash.h \ ../database/database.h ../utils/malloc.h ../textio/textio.h \ ../debug/debug.h ../extract/extract.h ../extract/extractInt.h \ ../extract/extDebugInt.h ../utils/signals.h ../windows/windows.h \ @@ -67,7 +67,8 @@ ExtTech.o: ExtTech.c ../tcltk/tclmagic.h ../utils/magic.h \ ../utils/utils.h ../utils/geometry.h ../tiles/tile.h ../utils/hash.h \ ../database/database.h ../database/databaseInt.h ../utils/malloc.h \ ../textio/textio.h ../utils/tech.h ../debug/debug.h ../extract/extract.h \ - ../extract/extractInt.h ../extract/extDebugInt.h ../cif/CIFint.h + ../extract/extractInt.h ../extract/extDebugInt.h ../cif/CIFint.h \ + ../cif/cif.h ExtTest.o: ExtTest.c ../utils/magic.h ../utils/utils.h \ ../utils/geometry.h ../utils/styles.h ../tiles/tile.h ../utils/hash.h \ ../database/database.h ../utils/malloc.h ../windows/windows.h \ diff --git a/graphics/Depend b/graphics/Depend index 6546e387..ff4c0a1f 100644 --- a/graphics/Depend +++ b/graphics/Depend @@ -93,10 +93,10 @@ grTOGL2.o: grTOGL2.c ../tcltk/tclmagic.h ../utils/magic.h \ grTOGLInt.h grTOGL3.o: grTOGL3.c ../tcltk/tclmagic.h ../utils/magic.h \ ../utils/geometry.h ../utils/malloc.h ../windows/windows.h \ - ../graphics/graphics.h ../graphics/graphicsInt.h ../textio/textio.h \ - ../utils/signals.h ../utils/utils.h ../utils/hash.h \ - ../graphics/grTOGLInt.h ../graphics/grTkCommon.h ../database/fonts.h \ - ../tiles/tile.h + ../graphics/graphics.h ../graphics/graphicsInt.h ../dbwind/dbwind.h \ + ../database/database.h ../tiles/tile.h ../utils/hash.h \ + ../textio/textio.h ../utils/signals.h ../utils/utils.h \ + ../graphics/grTOGLInt.h ../graphics/grTkCommon.h ../database/fonts.h grTOGL4.o: grTOGL4.c ../tcltk/tclmagic.h ../utils/magic.h \ ../utils/magsgtty.h ../textio/textio.h ../utils/geometry.h \ ../windows/windows.h ../graphics/graphics.h ../graphics/graphicsInt.h \ @@ -136,3 +136,28 @@ X11Helper.o: X11Helper.c grX11thread.o: grX11thread.c ../utils/magic.h ../utils/geometry.h \ ../graphics/graphics.h ../windows/windows.h ../graphics/graphicsInt.h \ grX11Int.h +grTCairo1.o: grTCairo1.c ../tcltk/tclmagic.h ../utils/main.h \ + ../windows/windows.h ../utils/magic.h ../utils/geometry.h \ + ../database/database.h ../tiles/tile.h ../utils/hash.h ../utils/malloc.h \ + ../utils/magsgtty.h ../graphics/graphics.h ../graphics/graphicsInt.h \ + ../textio/textio.h ../textio/txcommands.h ../utils/signals.h \ + ../utils/utils.h ../drc/drc.h ../utils/macros.h \ + ../graphics/grTCairoInt.h ../utils/paths.h ../graphics/grTkCommon.h +grTCairo2.o: grTCairo2.c ../tcltk/tclmagic.h ../utils/magic.h \ + ../textio/textio.h ../utils/geometry.h ../graphics/glyphs.h \ + ../windows/windows.h ../graphics/graphics.h ../graphics/graphicsInt.h \ + grTCairoInt.h ../textio/txcommands.h +grTCairo3.o: grTCairo3.c ../tcltk/tclmagic.h ../utils/magic.h \ + ../utils/geometry.h ../utils/malloc.h ../windows/windows.h \ + ../graphics/graphics.h ../graphics/graphicsInt.h ../dbwind/dbwind.h \ + ../database/database.h ../tiles/tile.h ../utils/hash.h \ + ../textio/textio.h ../utils/signals.h ../utils/utils.h \ + ../graphics/grTCairoInt.h ../graphics/grTkCommon.h ../database/fonts.h +grTCairo4.o: grTCairo4.c ../tcltk/tclmagic.h ../utils/magic.h \ + ../utils/magsgtty.h ../textio/textio.h ../utils/geometry.h \ + ../windows/windows.h ../graphics/graphics.h ../graphics/graphicsInt.h \ + ../graphics/grTkCommon.h ../textio/txcommands.h grTCairoInt.h +grTCairo5.o: grTCairo5.c ../tcltk/tclmagic.h ../utils/magic.h \ + ../utils/styles.h ../utils/hash.h ../textio/textio.h ../utils/geometry.h \ + ../graphics/glyphs.h ../windows/windows.h ../graphics/graphics.h \ + ../graphics/graphicsInt.h grTkCommon.h grTCairoInt.h diff --git a/lef/Depend b/lef/Depend index c30ba247..37ec5a4f 100644 --- a/lef/Depend +++ b/lef/Depend @@ -19,7 +19,7 @@ lefRead.o: lefRead.c ../tcltk/tclmagic.h ../utils/magic.h \ ../utils/geometry.h ../tiles/tile.h ../utils/hash.h ../utils/undo.h \ ../database/database.h ../windows/windows.h ../graphics/graphics.h \ ../dbwind/dbwind.h ../utils/malloc.h ../textio/textio.h ../cif/cif.h \ - ../cif/CIFint.h ../lef/lefInt.h + ../cif/CIFint.h ../cif/CIFread.h ../lef/lefInt.h defRead.o: defRead.c ../tcltk/tclmagic.h ../utils/magic.h \ ../utils/geometry.h ../tiles/tile.h ../utils/hash.h ../utils/undo.h \ ../database/database.h ../windows/windows.h ../dbwind/dbwind.h \ diff --git a/lisp/Depend b/lisp/Depend index 66f52c37..b09f6811 100644 --- a/lisp/Depend +++ b/lisp/Depend @@ -22,6 +22,12 @@ lispFrame.o: lispFrame.c ../lisp/lisp.h lispInt.h ../utils/magic.h \ lispTrace.o: lispTrace.c ../lisp/lisp.h lispInt.h ../utils/magic.h \ ../utils/geometry.h ../textio/txcommands.h ../textio/textio.h \ ../utils/malloc.h +lispMagic.o: lispMagic.c ../lisp/lisp.h lispInt.h ../utils/magic.h \ + ../utils/geometry.h ../textio/txcommands.h lispargs.h ../utils/geofast.h \ + ../textio/textio.h ../utils/malloc.h ../tiles/tile.h ../utils/hash.h \ + ../database/database.h ../windows/windows.h ../dbwind/dbwind.h \ + ../utils/main.h ../commands/commands.h ../utils/utils.h \ + ../select/select.h lispArith.o: lispArith.c ../lisp/lisp.h lispInt.h ../utils/magic.h \ ../utils/geometry.h ../textio/txcommands.h lispargs.h ../textio/textio.h \ ../utils/malloc.h diff --git a/textio/Depend b/textio/Depend index a2fd88ff..76214273 100644 --- a/textio/Depend +++ b/textio/Depend @@ -1,10 +1,10 @@ -txCommands.o: txCommands.c ../utils/magsgtty.h ../utils/magic.h \ - ../textio/textio.h ../utils/geometry.h ../textio/txcommands.h \ - ../textio/textioInt.h ../utils/macros.h ../utils/hash.h \ - ../windows/windows.h ../tiles/tile.h ../database/database.h \ - ../dbwind/dbwind.h ../drc/drc.h ../utils/signals.h \ - ../graphics/graphics.h ../utils/dqueue.h ../utils/malloc.h \ - ../utils/utils.h ../lisp/lisp.h +txCommands.o: txCommands.c ../tcltk/tclmagic.h ../utils/magsgtty.h \ + ../utils/magic.h ../textio/textio.h ../utils/geometry.h \ + ../textio/txcommands.h ../textio/textioInt.h ../utils/macros.h \ + ../utils/hash.h ../windows/windows.h ../tiles/tile.h \ + ../database/database.h ../dbwind/dbwind.h ../drc/drc.h \ + ../utils/signals.h ../graphics/graphics.h ../utils/dqueue.h \ + ../utils/malloc.h ../utils/utils.h ../lisp/lisp.h txInput.o: txInput.c ../utils/magsgtty.h ../utils/magic.h ../utils/main.h \ ../windows/windows.h ../utils/geometry.h ../database/database.h \ ../tiles/tile.h ../utils/hash.h ../textio/textio.h \ diff --git a/utils/Depend b/utils/Depend index 8e4f10c3..4f469cb1 100644 --- a/utils/Depend +++ b/utils/Depend @@ -18,19 +18,20 @@ list.o: list.c ../utils/magic.h ../utils/utils.h ../utils/malloc.h \ lookup.o: lookup.c ../utils/magic.h ../utils/utils.h lookupany.o: lookupany.c lookupfull.o: lookupfull.c ../utils/magic.h -macros.o: macros.c ../utils/magic.h ../utils/utils.h ../utils/hash.h \ - ../utils/malloc.h ../utils/macros.h ../windows/windows.h \ - ../utils/geometry.h -main.o: main.c ../utils/main.h ../windows/windows.h ../utils/magic.h \ +macros.o: macros.c ../utils/magic.h ../utils/main.h ../windows/windows.h \ ../utils/geometry.h ../database/database.h ../tiles/tile.h \ - ../utils/hash.h ../utils/malloc.h ../utils/magsgtty.h ../utils/macros.h \ - ../textio/textio.h ../textio/txcommands.h ../utils/tech.h ../drc/drc.h \ - ../graphics/graphics.h ../dbwind/dbwind.h ../commands/commands.h \ - ../utils/signals.h ../utils/utils.h ../utils/runstats.h ../cif/cif.h \ - ../router/router.h ../lef/lef.h ../extract/extract.h ../utils/undo.h \ - ../netmenu/netmenu.h ../plow/plow.h ../utils/paths.h ../wiring/wiring.h \ - ../plot/plot.h ../sim/sim.h ../utils/list.h ../mzrouter/mzrouter.h \ - ../lisp/lisp.h ../graphics/wind3d.h + ../utils/hash.h ../utils/utils.h ../utils/malloc.h ../utils/macros.h +main.o: main.c ../tcltk/tclmagic.h ../utils/main.h ../windows/windows.h \ + ../utils/magic.h ../utils/geometry.h ../database/database.h \ + ../tiles/tile.h ../utils/hash.h ../utils/malloc.h ../utils/magsgtty.h \ + ../utils/macros.h ../textio/textio.h ../textio/txcommands.h \ + ../utils/tech.h ../drc/drc.h ../graphics/graphics.h ../dbwind/dbwind.h \ + ../commands/commands.h ../utils/signals.h ../utils/utils.h \ + ../utils/runstats.h ../cif/cif.h ../router/router.h ../lef/lef.h \ + ../extract/extract.h ../utils/undo.h ../netmenu/netmenu.h ../plow/plow.h \ + ../utils/paths.h ../wiring/wiring.h ../plot/plot.h ../sim/sim.h \ + ../utils/list.h ../mzrouter/mzrouter.h ../lisp/lisp.h \ + ../graphics/wind3d.h malloc.o: malloc.c ../tcltk/tclmagic.h ../utils/magic.h ../utils/malloc.h match.o: match.c ../utils/magic.h ../textio/textio.h maxrect.o: maxrect.c ../utils/maxrect.h ../database/database.h \ @@ -63,9 +64,9 @@ set.o: set.c ../utils/magic.h ../utils/utils.h ../utils/geometry.h \ show.o: show.c ../utils/magic.h ../utils/geometry.h ../windows/windows.h \ ../graphics/graphics.h ../utils/hash.h ../tiles/tile.h \ ../database/database.h ../dbwind/dbwind.h -tech.o: tech.c ../utils/magic.h ../utils/geometry.h ../utils/utils.h \ - ../utils/tech.h ../textio/textio.h ../windows/windows.h \ - ../utils/malloc.h +tech.o: tech.c ../database/database.h ../tiles/tile.h ../utils/magic.h \ + ../utils/geometry.h ../utils/hash.h ../utils/utils.h ../utils/tech.h \ + ../textio/textio.h ../windows/windows.h ../utils/malloc.h touchtypes.o: touchtypes.c ../utils/magic.h ../utils/geometry.h \ ../utils/geofast.h ../tiles/tile.h ../utils/hash.h \ ../database/database.h diff --git a/windows/Depend b/windows/Depend index 17fdaf7b..4127f723 100644 --- a/windows/Depend +++ b/windows/Depend @@ -10,7 +10,7 @@ windCmdAM.o: windCmdAM.c ../tcltk/tclmagic.h ../utils/magic.h \ ../utils/signals.h ../graphics/graphics.h ../utils/styles.h \ ../textio/txcommands.h ../graphics/glyphs.h ../windows/windInt.h \ ../tiles/tile.h ../database/database.h ../dbwind/dbwind.h \ - ../utils/utils.h + ../utils/utils.h ../cif/cif.h windCmdNR.o: windCmdNR.c ../utils/magic.h ../textio/textio.h \ ../utils/geometry.h ../windows/windows.h ../graphics/glyphs.h \ ../windows/windInt.h ../tiles/tile.h ../utils/hash.h \ From feac3d94dd564930ba090c8bcdeb7554092a1335 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 16 Jul 2019 10:32:36 -0400 Subject: [PATCH 37/44] Added missing handling of text in GDS input with PRESENTATION followed by WIDTH (previously it assumed that PRESENTATION and WIDTH were mutually exclusive). --- calma/CalmaRdpt.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/calma/CalmaRdpt.c b/calma/CalmaRdpt.c index aee5c4b2..60b6ffc4 100644 --- a/calma/CalmaRdpt.c +++ b/calma/CalmaRdpt.c @@ -772,6 +772,11 @@ calmaElementText() else if (nbytes > 0 && rtype != CALMA_STRANS) calmaSkipSet(ignore); + /* NOTE: Record may contain both PRESENTATION and WIDTH */ + PEEKRH(nbytes, rtype); + if (nbytes > 0 && rtype != CALMA_STRANS) + calmaSkipSet(ignore); + READRH(nbytes, rtype); if (nbytes > 0 && rtype == CALMA_STRANS) { From 70927709c7c20d975c4521e0787f3cf741626ca2 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 16 Jul 2019 11:45:10 -0400 Subject: [PATCH 38/44] Added the capability to read a value from a WIDTH entry for text. Still not sure how it is supposed to be used, exactly. Used it to set a default text size in case a MAG value is missing. --- calma/CalmaRdpt.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/calma/CalmaRdpt.c b/calma/CalmaRdpt.c index 60b6ffc4..9745e0d2 100644 --- a/calma/CalmaRdpt.c +++ b/calma/CalmaRdpt.c @@ -774,7 +774,21 @@ calmaElementText() /* NOTE: Record may contain both PRESENTATION and WIDTH */ PEEKRH(nbytes, rtype); - if (nbytes > 0 && rtype != CALMA_STRANS) + if (nbytes > 0 && rtype == CALMA_WIDTH) + { + /* Use WIDTH value to set the font size */ + if (!calmaReadI4Record(CALMA_WIDTH, &size)) + { + calmaReadError("Error in reading WIDTH in calmaElementText()\n") ; + return; + } + size *= calmaReadScale1; + if (size % calmaReadScale2 != 0) + calmaReadError("Text width snapped to nearest integer boundary.\n"); + + size /= calmaReadScale2; + } + else if (nbytes > 0 && rtype != CALMA_STRANS) calmaSkipSet(ignore); READRH(nbytes, rtype); From cd32e39d58079ae383219a8de390f184e0c09b93 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 16 Jul 2019 16:26:56 -0400 Subject: [PATCH 39/44] Modified the GDS read routine to account for use of WIDTH in a text record without a MAG in the PRESENTATION record to override it. --- calma/CalmaRdpt.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/calma/CalmaRdpt.c b/calma/CalmaRdpt.c index 9745e0d2..c6e4c6d1 100644 --- a/calma/CalmaRdpt.c +++ b/calma/CalmaRdpt.c @@ -725,7 +725,7 @@ calmaElementText() angle = 0; /* Default size is 1um */ - size = (int)((800 * cifCurReadStyle->crs_multiplier) + size = (int)((1000 * cifCurReadStyle->crs_multiplier) / cifCurReadStyle->crs_scaleFactor); /* Default position is bottom-right (but what the spec calls "top-left"!) */ pos = GEO_SOUTHEAST; @@ -776,17 +776,23 @@ calmaElementText() PEEKRH(nbytes, rtype); if (nbytes > 0 && rtype == CALMA_WIDTH) { + int width; + /* Use WIDTH value to set the font size */ - if (!calmaReadI4Record(CALMA_WIDTH, &size)) + if (!calmaReadI4Record(CALMA_WIDTH, &width)) { calmaReadError("Error in reading WIDTH in calmaElementText()\n") ; return; } - size *= calmaReadScale1; - if (size % calmaReadScale2 != 0) - calmaReadError("Text width snapped to nearest integer boundary.\n"); + width *= calmaReadScale1; + if (width % calmaReadScale2 != 0) + calmaReadError("Text width snapped to nearest integer boundary.\n"); - size /= calmaReadScale2; + width /= calmaReadScale2; + + /* Convert to database units, because dimension goes to PutLabel */ + /* and is not converted through CIFPaintCurrent(). */ + size = CIFScaleCoord(width, COORD_ANY); } else if (nbytes > 0 && rtype != CALMA_STRANS) calmaSkipSet(ignore); @@ -801,9 +807,10 @@ calmaElementText() 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) + /* "size" is the label size in 10 * (database units) */ + size = (int)((dval * 1000 * cifCurReadStyle->crs_multiplier) / cifCurReadStyle->crs_scaleFactor); } else From 8183f72b00b3ebf0799ee3b1f0377d5768836c2e Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 17 Jul 2019 10:20:52 -0400 Subject: [PATCH 40/44] Added a missing include for utils/utils.h which has the function prototype for StrDup(). Otherwise, use of StrDup() in the LEF read routine can cause an inscrutible crash. --- lef/lefRead.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lef/lefRead.c b/lef/lefRead.c index a212aecf..500606bc 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -32,6 +32,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "tiles/tile.h" #include "utils/hash.h" #include "utils/undo.h" +#include "utils/utils.h" /* For StrDup() */ #include "database/database.h" #include "windows/windows.h" #include "graphics/graphics.h" From 9ec5e8e747c328e7f932fa8c3c3bba89d5832ab9 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Fri, 19 Jul 2019 22:58:45 -0400 Subject: [PATCH 41/44] Modified DEF reads to avoid instance names with brackets. Not sure if this is the best policy. The brackets should be okay but interfere with ext2spice when it reads them from the .ext file and decides that they refer to arrays. May be a better way to handle this. --- lef/Depend | 7 ++++--- lef/defRead.c | 18 +++++++++++++++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/lef/Depend b/lef/Depend index 37ec5a4f..9b997139 100644 --- a/lef/Depend +++ b/lef/Depend @@ -17,9 +17,10 @@ defWrite.o: defWrite.c ../tcltk/tclmagic.h ../utils/magic.h \ ../cif/cif.h ../extflat/extflat.h ../lef/lefInt.h ../drc/drc.h lefRead.o: lefRead.c ../tcltk/tclmagic.h ../utils/magic.h \ ../utils/geometry.h ../tiles/tile.h ../utils/hash.h ../utils/undo.h \ - ../database/database.h ../windows/windows.h ../graphics/graphics.h \ - ../dbwind/dbwind.h ../utils/malloc.h ../textio/textio.h ../cif/cif.h \ - ../cif/CIFint.h ../cif/CIFread.h ../lef/lefInt.h + ../utils/utils.h ../database/database.h ../windows/windows.h \ + ../graphics/graphics.h ../dbwind/dbwind.h ../utils/malloc.h \ + ../textio/textio.h ../cif/cif.h ../cif/CIFint.h ../cif/CIFread.h \ + ../lef/lefInt.h defRead.o: defRead.c ../tcltk/tclmagic.h ../utils/magic.h \ ../utils/geometry.h ../tiles/tile.h ../utils/hash.h ../utils/undo.h \ ../database/database.h ../windows/windows.h ../dbwind/dbwind.h \ diff --git a/lef/defRead.c b/lef/defRead.c index ab8cdfda..afe49a2a 100644 --- a/lef/defRead.c +++ b/lef/defRead.c @@ -1392,7 +1392,7 @@ DefReadComponents(f, rootDef, sname, oscale, total) CellDef *defMacro; CellUse *defUse; Transform t; - char *token; + char *token, *dptr; char usename[512]; int keyword, subkey, values; int processed = 0; @@ -1447,6 +1447,22 @@ DefReadComponents(f, rootDef, sname, oscale, total) LefEndStatement(f); break; } + + /* Does use name contain brackets? If so, this can */ + /* interfere with magic's use of arrays. */ + + /* NOTE: It is not clear that this needs to be */ + /* done during DEF read. The only confusion comes */ + /* from the arrays being parsed by ExtFlat when */ + /* doing ext2spice. */ + + dptr = strchr(usename, '['); + if (dptr != NULL) { + *dptr = '_'; + dptr = strchr(dptr + 1, ']'); + if (dptr != NULL) *dptr = '_'; + } + token = LefNextToken(f, TRUE); /* Find the corresponding macro definition */ From c2291391500e78c0f8572d0d404e33a6881d01da Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 23 Jul 2019 08:06:41 -0400 Subject: [PATCH 42/44] Changed two output lines in the LEF read subroutine to conform to the standard message/warning/error method. --- Makefile | 1 + lef/lefRead.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 58eeedb1..23e22d4b 100644 --- a/Makefile +++ b/Makefile @@ -58,6 +58,7 @@ libs: (cd $$dir && ${MAKE} lib); done depend: database/database.h + @echo --- making dependencies ${RM} */Depend for dir in ${MODULES} ${UNUSED_MODULES} ${PROGRAMS}; do \ (cd $$dir && ${MAKE} depend); done diff --git a/lef/lefRead.c b/lef/lefRead.c index 500606bc..22978f7c 100644 --- a/lef/lefRead.c +++ b/lef/lefRead.c @@ -2448,7 +2448,7 @@ LefRead(inName, importForeign) case LEF_SECTION_NONDEFAULTRULE: token = LefNextToken(f, TRUE); - TxPrintf("LEF file: Defines non-default rule %s (ignored)\n", token); + LefError(LEF_INFO, "Defines non-default rule %s (ignored)\n", token); sprintf(tsave, "%.127s", token); LefSkipSection(f, tsave); break; @@ -2457,7 +2457,7 @@ LefRead(inName, importForeign) break; case LEF_SECTION_SITE: token = LefNextToken(f, TRUE); - TxPrintf("LEF file: Defines site %s (ignored)\n", token); + LefError(LEF_INFO, "Defines site %s (ignored)\n", token); sprintf(tsave, "%.127s", token); LefSkipSection(f, tsave); break; From d08593997a30a3e7964a788ca505318e3ca7d5bd Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 23 Jul 2019 08:45:42 -0400 Subject: [PATCH 43/44] Cleaned up an inconsistency with GDS read-in that generates informational output that references a (non-existing) CIF file. --- calma/CalmaRdcl.c | 34 +++++++++++------------ calma/CalmaRdio.c | 16 +++++------ calma/CalmaRdpt.c | 56 +++++++++++++++++++------------------- calma/CalmaRead.c | 8 +++--- calma/calma.h | 1 + cif/CIFrdcl.c | 69 +++++++++++++++++++++++++++++++++-------------- cif/CIFrdutils.c | 2 +- cif/cif.h | 4 +++ commands/CmdCD.c | 2 +- 9 files changed, 113 insertions(+), 79 deletions(-) diff --git a/calma/CalmaRdcl.c b/calma/CalmaRdcl.c index 5fb77f31..28acae08 100644 --- a/calma/CalmaRdcl.c +++ b/calma/CalmaRdcl.c @@ -141,7 +141,7 @@ calmaSetPosition(sname) return originalPos; } - calmaReadError("Cell \"%s\" is used but not defined in this file.\n", sname); + CalmaReadError("Cell \"%s\" is used but not defined in this file.\n", sname); return originalPos; } @@ -318,23 +318,23 @@ calmaParseStructure(filename) if (!CalmaPostOrder) { - calmaReadError("Cell \"%s\" was already defined in this file.\n", + CalmaReadError("Cell \"%s\" was already defined in this file.\n", strname); - calmaReadError("Ignoring duplicate definition\n"); + CalmaReadError("Ignoring duplicate definition\n"); } calmaNextCell(); return TRUE; } else { - calmaReadError("Cell \"%s\" was already defined in this file.\n", + CalmaReadError("Cell \"%s\" was already defined in this file.\n", strname); for (suffix = 1; HashGetValue(he) != NULL; suffix++) { (void) sprintf(newname, "%s_%d", strname, suffix); he = HashFind(&calmaDefInitHash, newname); } - calmaReadError("Giving this cell a new name: %s\n", newname); + CalmaReadError("Giving this cell a new name: %s\n", newname); strncpy(strname, newname, CALMANAMELENGTH*2); } } @@ -437,7 +437,7 @@ calmaParseStructure(filename) * the appropriate cell of the database. */ - CIFPaintCurrent(); + CIFPaintCurrent(FILE_CALMA); } DBAdjustLabelsNew(cifReadCellDef, &TiPlaneRect, @@ -508,7 +508,7 @@ calmaParseElement(filename, pnsrefs, pnpaths) READRH(nbytes, rtype); if (nbytes < 0) { - calmaReadError("Unexpected EOF.\n"); + CalmaReadError("Unexpected EOF.\n"); return (FALSE); } @@ -536,7 +536,7 @@ calmaParseElement(filename, pnsrefs, pnpaths) calmaElementText(); break; case CALMA_NODE: - calmaReadError("NODE elements not supported: skipping.\n"); + CalmaReadError("NODE elements not supported: skipping.\n"); calmaSkipSet(node); break; default: @@ -664,10 +664,10 @@ calmaElementSref(filename) if (DBIsAncestor(def, cifReadCellDef)) { - calmaReadError("Cell %s is an ancestor of %s", + 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"); + CalmaReadError(" and can't be used as a subcell.\n"); + CalmaReadError("(Use skipped)\n"); return -1; } @@ -722,12 +722,12 @@ calmaElementSref(filename) nref = nbytes / 8; if (nref > 3) { - calmaReadError("Too many points (%d) in SREF/AREF\n", nref); + 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"); + 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; @@ -856,8 +856,8 @@ calmaElementSref(filename) 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); + 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; @@ -868,8 +868,8 @@ calmaElementSref(filename) 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); + 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; diff --git a/calma/CalmaRdio.c b/calma/CalmaRdio.c index f70f19a8..24fc6c21 100644 --- a/calma/CalmaRdio.c +++ b/calma/CalmaRdio.c @@ -110,8 +110,8 @@ calmaReadTransform(ptrans, name) 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)); + 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; @@ -144,13 +144,13 @@ calmaReadTransform(ptrans, name) case 0: case 90: case 180: case 270: break; default: - calmaReadError("Non-Manhattan angle (%d) in transform\n", angle); + 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); + CalmaReadError(" Rounding to %d degrees.\n", angle); } /* @@ -223,7 +223,7 @@ calmaReadI2Record(type, pvalue) return (TRUE); eof: - calmaReadError("Unexpected EOF.\n"); + CalmaReadError("Unexpected EOF.\n"); return (FALSE); } @@ -268,7 +268,7 @@ calmaReadI4Record(type, pvalue) return (TRUE); eof: - calmaReadError("Unexpected EOF.\n"); + CalmaReadError("Unexpected EOF.\n"); return (FALSE); } @@ -317,7 +317,7 @@ calmaReadStringRecord(type, str) return (TRUE); eof: - calmaReadError("Unexpected EOF.\n"); + CalmaReadError("Unexpected EOF.\n"); return (FALSE); } @@ -478,7 +478,7 @@ calmaSkipExact(type) return (TRUE); eof: - calmaReadError("Unexpected EOF.\n"); + CalmaReadError("Unexpected EOF.\n"); return (FALSE); } diff --git a/calma/CalmaRdpt.c b/calma/CalmaRdpt.c index c6e4c6d1..61e6e87f 100644 --- a/calma/CalmaRdpt.c +++ b/calma/CalmaRdpt.c @@ -143,7 +143,7 @@ calmaReadPoint(p, iscale) rescale = calmaReadScale2 / FindGCF(calmaReadScale2, abs(p->p_x)); if ((calmaReadScale1 * rescale) > CIFRescaleLimit) { - calmaReadError("Warning: calma units at max scale; value rounded\n"); + CalmaReadError("Warning: calma units at max scale; value rounded\n"); if (p->p_x < 0) p->p_x -= ((calmaReadScale2 - 1) >> 1); else @@ -165,7 +165,7 @@ calmaReadPoint(p, iscale) rescale = calmaReadScale2 / FindGCF(calmaReadScale2, abs(p->p_y)); if ((calmaReadScale1 * rescale) > CIFRescaleLimit) { - calmaReadError("Warning: calma units at max scale; value rounded\n"); + CalmaReadError("Warning: calma units at max scale; value rounded\n"); if (p->p_y < 0) p->p_y -= ((calmaReadScale2 - 1) >> 1); else @@ -216,7 +216,7 @@ calmaElementBoundary() if (!calmaReadI2Record(CALMA_LAYER, &layer) || !calmaReadI2Record(CALMA_DATATYPE, &dt)) { - calmaReadError("Missing layer or datatype in boundary/box.\n"); + CalmaReadError("Missing layer or datatype in boundary/box.\n"); return; } @@ -234,7 +234,7 @@ calmaElementBoundary() if (!calmaReadPath(&pathheadp, (plane == NULL) ? 0 : 1)) { if (plane != NULL) - calmaReadError("Error while reading path for boundary/box; ignored.\n"); + CalmaReadError("Error while reading path for boundary/box; ignored.\n"); return; } @@ -329,7 +329,7 @@ calmaElementBoundary() if (cifCurReadPlanes == cifEditCellPlanes) { - CIFPaintCurrent(); + CIFPaintCurrent(FILE_CALMA); DBReComputeBbox(cifReadCellDef); DRCCheckThis(cifReadCellDef, TT_CHECKPAINT, &cifReadCellDef->cd_bbox); DBWAreaChanged(cifReadCellDef, &cifReadCellDef->cd_bbox, @@ -383,7 +383,7 @@ calmaElementBox() if (!calmaReadI2Record(CALMA_LAYER, &layer) || !calmaReadI2Record(CALMA_BOXTYPE, &dt)) { - calmaReadError("Missing layer or datatype in boundary/box.\n"); + CalmaReadError("Missing layer or datatype in boundary/box.\n"); return; } @@ -407,7 +407,7 @@ calmaElementBox() READRH(nbytes, rtype); if (nbytes < 0) { - calmaReadError("EOF when reading box.\n"); + CalmaReadError("EOF when reading box.\n"); return; } if (rtype != CALMA_XY) @@ -420,7 +420,7 @@ calmaElementBox() npoints = (nbytes - CALMAHEADERLENGTH) / 8; if (npoints != 5) { - calmaReadError("Box doesn't have 5 points.\n"); + CalmaReadError("Box doesn't have 5 points.\n"); (void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH); return; } @@ -491,7 +491,7 @@ calmaElementPath() if (pathtype != CALMAPATH_SQUAREFLUSH && pathtype != CALMAPATH_SQUAREPLUS && pathtype != CALMAPATH_CUSTOM) { - calmaReadError("Warning: pathtype %d unsupported (ignored).\n", pathtype); + CalmaReadError("Warning: pathtype %d unsupported (ignored).\n", pathtype); pathtype = CALMAPATH_SQUAREFLUSH; } @@ -505,13 +505,13 @@ calmaElementPath() { if (!calmaReadI4Record(CALMA_WIDTH, &width)) { - calmaReadError("Error in reading WIDTH in calmaElementPath()\n") ; + CalmaReadError("Error in reading WIDTH in calmaElementPath()\n") ; return; } } width *= calmaReadScale1; if (width % calmaReadScale2 != 0) - calmaReadError("Wire width snapped to nearest integer boundary.\n"); + CalmaReadError("Wire width snapped to nearest integer boundary.\n"); width /= calmaReadScale2; @@ -528,12 +528,12 @@ calmaElementPath() if (nbytes > 0 && rtype == CALMA_BGNEXTN) { if (!calmaReadI4Record(CALMA_BGNEXTN, &extend1)) - calmaReadError("Error in reading BGNEXTN in path (ignored)\n") ; + 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"); + CalmaReadError("Wire extension snapped to nearest integer boundary.\n"); extend1 *= 2; extend1 /= calmaReadScale2; } @@ -543,12 +543,12 @@ calmaElementPath() if (nbytes > 0 && rtype == CALMA_ENDEXTN) { if (!calmaReadI4Record(CALMA_ENDEXTN, &extend2)) - calmaReadError("Error in reading ENDEXTN in path (ignored)\n") ; + 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"); + CalmaReadError("Wire extension snapped to nearest integer boundary.\n"); extend2 *= 2; extend2 /= calmaReadScale2; } @@ -558,7 +558,7 @@ calmaElementPath() savescale = calmaReadScale1; if (!calmaReadPath(&pathheadp, 2)) { - calmaReadError("Improper path; ignored.\n"); + CalmaReadError("Improper path; ignored.\n"); return; } if (savescale != calmaReadScale1) @@ -656,7 +656,7 @@ calmaElementPath() if (cifCurReadPlanes == cifEditCellPlanes) { - CIFPaintCurrent(); + CIFPaintCurrent(FILE_CALMA); DBReComputeBbox(cifReadCellDef); DRCCheckThis(cifReadCellDef, TT_CHECKPAINT, &cifReadCellDef->cd_bbox); DBWAreaChanged(cifReadCellDef, &cifReadCellDef->cd_bbox, @@ -781,12 +781,12 @@ calmaElementText() /* Use WIDTH value to set the font size */ if (!calmaReadI4Record(CALMA_WIDTH, &width)) { - calmaReadError("Error in reading WIDTH in calmaElementText()\n") ; + CalmaReadError("Error in reading WIDTH in calmaElementText()\n") ; return; } width *= calmaReadScale1; if (width % calmaReadScale2 != 0) - calmaReadError("Text width snapped to nearest integer boundary.\n"); + CalmaReadError("Text width snapped to nearest integer boundary.\n"); width /= calmaReadScale2; @@ -840,7 +840,7 @@ calmaElementText() nbytes -= CALMAHEADERLENGTH; if (nbytes < 8) { - calmaReadError("Not enough bytes in point record.\n"); + CalmaReadError("Not enough bytes in point record.\n"); } else { @@ -890,15 +890,15 @@ calmaElementText() } } if (changed) { - calmaReadError("Warning: improper characters fixed in label '%s'\n", + CalmaReadError("Warning: improper characters fixed in label '%s'\n", savstring); if (!algmsg) { algmsg = TRUE; - calmaReadError(" (algorithm used: trailing dropped, " + CalmaReadError(" (algorithm used: trailing dropped, " " and ' ' changed to '_', \n" " other non-printables changed to '?')\n"); } - calmaReadError(" modified label is '%s'\n", textbody); + CalmaReadError(" modified label is '%s'\n", textbody); freeMagic(savstring); } } @@ -908,7 +908,7 @@ calmaElementText() /* Place the label */ if (strlen(textbody) == 0) { - calmaReadError("Warning: Ignoring empty string label at (%d, %d)\n", + 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); } @@ -920,7 +920,7 @@ calmaElementText() } else if (type < 0) { - calmaReadError("Warning: label \"%s\" at (%d, %d) is on unhandled" + 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); @@ -1036,7 +1036,7 @@ calmaReadPath(pathheadpp, iscale) READRH(nbytes, rtype); if (nbytes < 0) { - calmaReadError("EOF when reading path.\n"); + CalmaReadError("EOF when reading path.\n"); return (FALSE); } if (rtype != CALMA_XY) @@ -1063,7 +1063,7 @@ calmaReadPath(pathheadpp, iscale) } } if (ABS(path.cifp_x) > 0x0fffffff || ABS(path.cifp_y) > 0x0fffffff) { - calmaReadError("Warning: Very large point in path: (%d, %d)\n", + CalmaReadError("Warning: Very large point in path: (%d, %d)\n", path.cifp_x, path.cifp_y); } if (feof(calmaInputFile)) @@ -1141,6 +1141,6 @@ calmaLayerError(mesg, layer, dt) if (HashGetValue(he) == NULL) { HashSetValue(he, (ClientData) 1); - calmaReadError("%s, layer=%d type=%d\n", mesg, layer, dt); + CalmaReadError("%s, layer=%d type=%d\n", mesg, layer, dt); } } diff --git a/calma/CalmaRead.c b/calma/CalmaRead.c index 1ddd00a8..9421a9af 100644 --- a/calma/CalmaRead.c +++ b/calma/CalmaRead.c @@ -232,7 +232,7 @@ done: freeMagic(libname); } - CIFReadCellCleanup(1); + CIFReadCellCleanup(FILE_CALMA); HashKill(&calmaDefInitHash); UndoEnable(); @@ -330,7 +330,7 @@ calmaParseUnits() /* * ---------------------------------------------------------------------------- * - * calmaReadError -- + * CalmaReadError -- * * This procedure is called to print out error messages during * Calma file reading. @@ -349,7 +349,7 @@ calmaParseUnits() void /*VARARGS1*/ -calmaReadError(format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) +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; { @@ -408,7 +408,7 @@ calmaUnexpected(wanted, got) int wanted; /* Type of record we wanted */ int got; /* Type of record we got */ { - calmaReadError("Unexpected record type in input: \n"); + CalmaReadError("Unexpected record type in input: \n"); if (CIFWarningLevel == CIF_WARN_NONE) return; if (calmaTotalErrors < 100 || (CIFWarningLevel != CIF_WARN_LIMIT)) diff --git a/calma/calma.h b/calma/calma.h index 86a70887..8c98ed4e 100644 --- a/calma/calma.h +++ b/calma/calma.h @@ -42,5 +42,6 @@ extern bool CalmaWrite(); extern void CalmaReadFile(); extern void CalmaTechInit(); extern bool CalmaGenerateArray(); +extern void CalmaReadError(); #endif /* _CALMA_H */ diff --git a/cif/CIFrdcl.c b/cif/CIFrdcl.c index d9809ec2..2157b15a 100644 --- a/cif/CIFrdcl.c +++ b/cif/CIFrdcl.c @@ -557,7 +557,8 @@ cifCopyPaintFunc(tile, cifCopyRec) */ int -CIFPaintCurrent() +CIFPaintCurrent(filetype) + bool filetype; { extern int cifMakeBoundaryFunc(); /* Forward declaration. */ extern int cifPaintCurrentFunc(); /* Forward declaration. */ @@ -658,7 +659,7 @@ CIFPaintCurrent() &DBAllButSpaceBits, cifCheckPaintFunc, (ClientData)NULL) == 1)) DBSrPaintArea((Tile *) NULL, plane, &TiPlaneRect, - &CIFSolidBits, cifMakeBoundaryFunc, (ClientData)NULL); + &CIFSolidBits, cifMakeBoundaryFunc, (ClientData)filetype); } /* Swap planes */ @@ -692,7 +693,7 @@ CIFPaintCurrent() int cifMakeBoundaryFunc(tile, clientdata) Tile *tile; /* Tile of CIF information. */ - ClientData clientdata; /* Not used */ + ClientData clientdata; /* Pass the file type (CIF or CALMA) */ { /* It is assumed that there is one rectangle for the boundary. */ /* If there are multiple rectangles defined with the boundary */ @@ -701,6 +702,7 @@ cifMakeBoundaryFunc(tile, clientdata) Rect area; char propertyvalue[128], *storedvalue; int savescale; + bool filetype = (bool)clientdata; TiToRect(tile, &area); area.r_xtop = CIFScaleCoord(area.r_xtop, COORD_EXACT); @@ -727,8 +729,35 @@ cifMakeBoundaryFunc(tile, clientdata) } if (cifReadCellDef->cd_flags & CDFIXEDBBOX) - CIFReadError("Warning: Cell %s boundary was redefined.\n", - cifReadCellDef->cd_name); + { + char *propvalue; + bool found; + + /* Only flag a warning if the redefined boundary was */ + /* different from the original. */ + + propvalue = (char *)DBPropGet(cifReadCellDef, "FIXED_BBOX", &found); + if (found) + { + Rect bbox; + if (sscanf(propvalue, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot, + &bbox.r_xtop, &bbox.r_ytop) == 4) + { + if ((bbox.r_xbot != area.r_xbot) || + (bbox.r_ybot != area.r_ybot) || + (bbox.r_xtop != area.r_xtop) || + (bbox.r_ytop != area.r_ytop)) + { + if (filetype == FILE_CIF) + CIFReadError("Warning: Cell %s boundary was redefined.\n", + cifReadCellDef->cd_name); + else + CalmaError("Warning: Cell %s boundary was redefined.\n", + cifReadCellDef->cd_name); + } + } + } + } sprintf(propertyvalue, "%d %d %d %d", area.r_xbot, area.r_ybot, area.r_xtop, area.r_ytop); @@ -841,7 +870,7 @@ CIFParseFinish() * layer info. */ - CIFPaintCurrent(); + CIFPaintCurrent(FILE_CIF); DBAdjustLabels(cifReadCellDef, &TiPlaneRect); DBReComputeBbox(cifReadCellDef); @@ -1389,8 +1418,8 @@ CIFParseUser() */ void -CIFReadCellCleanup(type) - int type; // 0 = CIF, 1 = GDS, because routine is used by both +CIFReadCellCleanup(filetype) + bool filetype; { HashEntry *h; HashSearch hs; @@ -1400,10 +1429,10 @@ CIFReadCellCleanup(type) if (cifSubcellBeingRead) { - if (type == 0) + if (filetype == FILE_CIF) CIFReadError("CIF ended partway through a symbol definition.\n"); else - calmaReadError("GDS ended partway through a symbol definition.\n"); + CalmaReadError("GDS ended partway through a symbol definition.\n"); (void) CIFParseFinish(); } @@ -1416,24 +1445,24 @@ CIFReadCellCleanup(type) def = (CellDef *) HashGetValue(h); if (def == NULL) { - if (type == 0) + if (filetype == FILE_CIF) CIFReadError("cell table has NULL entry (Magic error).\n"); else - calmaReadError("cell table has NULL entry (Magic error).\n"); + CalmaReadError("cell table has NULL entry (Magic error).\n"); continue; } flags = def->cd_flags; if (!(flags & CDAVAILABLE)) { - if (type == 0) + if (filetype == FILE_CIF) 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); + CalmaReadError("cell %s was used but not defined.\n", def->cd_name); } def->cd_flags &= ~CDPROCESSEDGDS; - if ((type == 0 && CIFNoDRCCheck == FALSE) || - (type == 1 && CalmaNoDRCCheck == FALSE)) + if ((filetype == FILE_CIF && CIFNoDRCCheck == FALSE) || + (filetype == 1 && CalmaNoDRCCheck == FALSE)) DRCCheckThis(def, TT_CHECKPAINT, &def->cd_bbox); DBWAreaChanged(def, &def->cd_bbox, DBW_ALLWINDOWS, &DBAllButSpaceBits); DBCellSetModified(def, TRUE); @@ -1441,7 +1470,7 @@ CIFReadCellCleanup(type) /* Do geometrical processing on the top-level cell. */ - CIFPaintCurrent(); + CIFPaintCurrent(FILE_CIF); DBAdjustLabels(EditCellUse->cu_def, &TiPlaneRect); DBReComputeBbox(EditCellUse->cu_def); DBWAreaChanged(EditCellUse->cu_def, &EditCellUse->cu_def->cd_bbox, @@ -1485,7 +1514,7 @@ CIFReadCellCleanup(type) if (!(def->cd_flags & CDFLATTENED)) CIFReadError("%s read error: Unresolved geometry in cell" " %s maps to no magic layers\n", - (type == 0) ? "CIF" : "GDS", def->cd_name); + (filetype == FILE_CIF) ? "CIF" : "GDS", def->cd_name); #if 0 /* Remove the cell if it has no parents, no children, and no geometry */ @@ -1498,11 +1527,11 @@ CIFReadCellCleanup(type) if (DBCellDeleteDef(def) == FALSE) { CIFReadError("%s read error: Unable to delete cell %s\n", - (type == 0) ? "CIF" : "GDS", savename); + (filetype == FILE_CIF) ? "CIF" : "GDS", savename); } else { - if (type == 0) + if (filetype == FILE_CIF) TxPrintf("CIF read: Removed flattened cell %s\n", savename); else TxPrintf("GDS read: Removed flattened cell %s\n", savename); diff --git a/cif/CIFrdutils.c b/cif/CIFrdutils.c index 5d279eaa..9da32840 100644 --- a/cif/CIFrdutils.c +++ b/cif/CIFrdutils.c @@ -1660,6 +1660,6 @@ CIFReadFile(file) CIFReadError("no \"End\" statement.\n"); done: - CIFReadCellCleanup(0); + CIFReadCellCleanup(FILE_CIF); UndoEnable(); } diff --git a/cif/cif.h b/cif/cif.h index 6dc608ad..4f08a748 100644 --- a/cif/cif.h +++ b/cif/cif.h @@ -30,6 +30,10 @@ * depends on the size of the layout. */ +/* Passed to CIFPaintCurrent() for print statement formatting */ +#define FILE_CIF 0 +#define FILE_CALMA 1 + /* Exported global variables (commands/CmdCD.c) */ extern int CIFWarningLevel; diff --git a/commands/CmdCD.c b/commands/CmdCD.c index 6cd842a0..88607b96 100644 --- a/commands/CmdCD.c +++ b/commands/CmdCD.c @@ -3802,7 +3802,7 @@ cmdDumpParseArgs(cmdName, w, cmd, dummy, scx) char *propvalue; bool found; - propvalue = DBPropGet(def, "FIXED_BBOX", &found); + propvalue = (char *)DBPropGet(def, "FIXED_BBOX", &found); if (found) { if (sscanf(propvalue, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot, From 93d25e7cf71fa8fac4e6d1a5e8da44262bb4424a Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 24 Jul 2019 12:30:03 -0400 Subject: [PATCH 44/44] Removed the rule for building database.h from rules.mak and instead created a dependency on database.h for compiling any source file. This should (I hope) avoid conflicts when running "make" with the "-j" option for parallel compilation. --- rules.mak | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/rules.mak b/rules.mak index 1fa3e75a..36006fb1 100644 --- a/rules.mak +++ b/rules.mak @@ -20,7 +20,7 @@ ${DEPEND_FILE}: # Original Depend file generating line: # ${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS} ${DEPEND_FLAG} ${SRCS} > ${DEPEND_FILE} -.c.o: +.c.o: ../database/database.h @echo --- compiling ${MODULE}/$*.o ${RM} $*.o ${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS} -c $*.c @@ -47,10 +47,6 @@ ${DESTDIR}${BINDIR}/${MODULE}${EXEEXT}: ${MODULE}${EXEEXT} ${RM} ${DESTDIR}${BINDIR}/${MODULE}${EXEEXT} ${CP} ${MODULE}${EXEEXT} ${DESTDIR}${BINDIR} -../database/database.h: ../database/database.h.in - @echo --- making header file database/database.h - ${SCRIPTS}/makedbh ../database/database.h.in ../database/database.h - clean: ${RM} ${CLEANS}