-- ChipNetExtract.mesa -- A circuit extraction package -- that runs inside Chipmonk. -- last modified by E. McCreight, December 21, 1982 3:26 PM -- written by E. McCreight, November 3, 1981 3:06 PM DIRECTORY Ascii, CellInstPQ, ChipDRC, ChipExpand, ChipFeature, ChipNetDefs, ChipOrient, ChipReticle, ChipUserInt, ChipWire, CWF, FeaturePST, InlineDefs, LeftFeaturePQ, ppdefs, RightFeaturePQ, ZoneAllocDefs; ChipNetExtract: PROGRAM IMPORTS CellInstPQ, ChipDRC, ChipExpand, ChipFeature, ChipNetDefs, ChipOrient, ChipReticle, ChipUserInt, ChipWire, CWF, FeaturePST, InlineDefs, LeftFeaturePQ, ppdefs, RightFeaturePQ, ZoneAllocDefs EXPORTS ChipNetDefs, ppdefs = BEGIN OPEN ppdefs, ChipUserInt, ChipNetDefs, CellInstPQ; aux: PUBLIC TYPE = CellProto; currentX: PUBLIC Coord; deltaOrigin: PUBLIC CoordPoint; notingMark: PUBLIC BOOLEAN _ FALSE; ItemInWorld: PUBLIC PROCEDURE[c: ItemRef] RETURNS[CoordRect] = BEGIN ob: obPtr _ c.head.proto.ob; r: Rect _ ChipOrient.MapRect[ itemInCell: getRect[ItemRefToLp[c]], cellInstOrient: c.head.orient, cellSize: [x: ob.size[0], y: ob.size[1]]]; min: CoordPoint _ c.head.min; scale: Coord _ coordScale[c.head.proto.locNumScale]; RETURN[[x1: min.x+scale*r.x1, y1: min.y+scale*r.y1, x2: min.x+scale*r.x2, y2: min.y+scale*r.y2]]; END; -- of ItemInWorld ShowFeature: PUBLIC PROCEDURE[f: FeaturePtr] = BEGIN s: STRING _ [100]; CWF.SWF1[sto: s, s: "Feature on layer %s.", a: levelNames[f.lev]]; RemarkAtPoint[p: RefCoordPt[f.cover], s: s]; END; RefCoordPt: PUBLIC PROCEDURE[r: CoordRect] RETURNS[Point] = BEGIN corner1, corner2: Point; corner1 _ ScalePointToChipmonk[[x: r.x1, y: r.y1]]; corner2 _ ScalePointToChipmonk[[x: r.x2, y: r.y2]]; RETURN[ChipOrient.RefPt[ [x1: corner1.x, y1: corner1.y, x2: corner2.x, y2: corner2.y]]]; END; -- of RefCoordPt DistributeNetsToSources: PROCEDURE[id: NetIdPtr] RETURNS[NetIdPtr] = BEGIN nextNetId: NetIdPtr; unclaimed: NetIdPtr _ NIL; FOR netId: NetIdPtr _ id, nextNetId WHILE netId#NIL DO nextNetId _ netId.next; WITH did: netId SELECT FROM free => {did.next _ unclaimed; unclaimed _ @did}; well => NULL; normal => IF did.source#NIL THEN {did.next _ did.source.nets; did.source.nets _ @did} ELSE {did.next _ unclaimed; unclaimed _ @did}; ENDCASE; ENDLOOP; RETURN[unclaimed]; END; -- of DistributeNetsToSources HeSetsParamsAndSaysYes: PUBLIC PROCEDURE[ s1, s2: STRING _ NIL] RETURNS[bit: BOOLEAN] = BEGIN DO answer: STRING; BEGIN bit _ ChipUserInt.HeSaysYes[s1, s2 ! Punt => GOTO SetParameters]; RETURN; EXITS SetParameters => NULL; END; answer _ RequestString["Set debugging parameters:"L, "(Pause at -M-ark)"]; IF answer.length>=1 THEN SELECT answer[0] FROM 'm, 'M => notingMark _ NOT notingMark; ENDCASE => NULL; ppdefs.FreeString[answer]; ENDLOOP; END; -- of HeSetsParamsAndSaysYes ExtractNets: PROCEDURE[univLp: listPtr] = BEGIN OPEN ChipOrient, LeftFeaturePQ, RightFeaturePQ; -- Scan proceeds from left to right. univ: Rect; leftFq: LeftFeaturePQHandle; rightFq: RightFeaturePQHandle; cq, deadcq: CellInstPQHandle; rootC: CellCallPtr; c: InstancePtr; lp: listPtr; slice: ChipWire.SlicePtr; topSelections, topItemCount: CARDINAL _ 0; Action: TYPE = {enterCellItem, enterFeatures, exitFeatures, exitCell, none}; delay: ARRAY Action OF Coord _ [ enterCellItem: ScaleFromChipmonk[0], enterFeatures: ScaleFromChipmonk[featureDelay], exitFeatures: ScaleFromChipmonk[featureDelay], exitCell: ScaleFromChipmonk[3*featureDelay], none: ScaleFromChipmonk[0]]; SelectNext: PROCEDURE RETURNS [next: Action] = BEGIN x: Coord; next _ none; IF CellInstPQSize[cq]>0 THEN {next _ enterCellItem; x _ CellInstPQMin[cq].x}; IF LeftFeaturePQSize[leftFq]>0 AND (LeftFeaturePQMin[leftFq].cover.x1+delay[enterFeatures]< x+delay[next] OR next=none) THEN BEGIN next _ enterFeatures; x _ LeftFeaturePQMin[leftFq].cover.x1 END; IF RightFeaturePQSize[rightFq]>0 AND (RightFeaturePQMin[rightFq].cover.x2+delay[exitFeatures]< x+delay[next] OR next=none) THEN BEGIN next _ exitFeatures; x _ RightFeaturePQMin[rightFq].cover.x2 END; IF CellInstPQSize[deadcq]>0 AND (CellInstPQMin[deadcq].x+delay[exitCell]< x+delay[next] OR next=none) THEN {next _ exitCell; x _ CellInstPQMin[deadcq].x}; END; IF univLp=NIL THEN RETURN; FOR lpp: listPtr _ univLp, lpp.nxt WHILE lpp#NIL DO topItemCount _ topItemCount+1; IF lpp.selected THEN topSelections _ topSelections+1; ENDLOOP; IF topSelections=0 THEN BEGIN Explain["Nothing selected, nothing extracted!"]; RETURN; END; univ _ ChipOrient.BoundingRect[univLp]; deltaOrigin _ [x: ScaleFromChipmonk[univ.x1-featureDelay], y: ScaleFromChipmonk[univ.y1-featureDelay]]; rootC _ instanceZ.NEW[cell Instance _ [min: ScalePointFromChipmonk[[x: 0, y: 0]], proto: ChipExpand.MakeProto[ ob: uz.NEW[cell object _ [p: NIL, size: [univ.x2-univ.x1, univ.y2-univ.y1, univ.x2-univ.x1], refCnt: 1, l: snerd, -- if anybody uses this, he's in trouble returnable: FALSE, marked: FALSE, varpart: cell[cnt: topItemCount, ptr: univLp]]], name: "Top level design"], caller: [NIL, 0], nets: cell[] ]]; ColorOff[]; rightFq _ NewRightFeaturePQ[uz]; leftFq _ NewLeftFeaturePQ[uz]; cq _ NewCellInstPQ[uz]; deadcq _ NewCellInstPQ[uz]; slice _ ChipWire.NewSlice[]; [] _ ChipExpand.ProtoSeq[rootC]; InsertCellInstPQ[p: cq, item: [ScalePointFromChipmonk[[univ.x1, univ.y1]].x, [rootC, 0]]]; InsertCellInstPQ[p: deadcq, item: [ScalePointFromChipmonk[[univ.x2, univ.y2]].x, [rootC, 0]]]; DO SELECT SelectNext[] FROM enterCellItem => BEGIN -- enter a new item from a cell lps: ListPtrSeqPtr; cir: ItemRef; idx: CellIndex; cqi: CellInstPt _ ExtractCellInstPQ[cq]; [x: currentX, call: cir] _ cqi; [head: c, idx: idx] _ cir; lps _ c.proto.seq[orientToSortClass[c.orient]]; lp _ lps[idx]; ChipExpand.MakeInstance[item: [c, idx], slice: slice, futureFeatures: leftFq, presentFeatures: rightFq, cellQ: cq, deadCellQ: deadcq]; END; enterFeatures => BEGIN EnterAFeature: PROCEDURE[f: FeaturePtr] = BEGIN IF notingMark THEN ChipFeature.NoteMark[f.cover, "New %s feature at f^ contains mark.", levelNames[f.lev]]; ChipWire.WireEntered[f, slice]; FeaturePST.InsertFeaturePST[p: slice[f.lev], item: f]; InsertRightFeaturePQ[rightFq, f]; END; -- of EnterAFeature sampleCover: CoordRect _ LeftFeaturePQMin[leftFq].cover; currentX _ sampleCover.x1; ChipFeature.BWCursor[world: [ x: sampleCover.x1, y: sampleCover.y1]]; MapEqualLeftFeaturePQ[p: leftFq, proc: EnterAFeature]; IF ChipDRC.doingDRC THEN ChipDRC.LeftEdges[leftFq]; DeleteEqualLeftFeaturePQ[leftFq]; END; exitFeatures => BEGIN ExitAFeature: PROCEDURE[f: FeaturePtr] = BEGIN FeaturePST.DeleteFeaturePST[p: slice[f.lev], item: f]; IF notingMark THEN ChipFeature.NoteMark[f.cover, "Old %s feature at f^ contains mark.", levelNames[f.lev]]; ChipWire.WireLeft[f, slice]; IF NOT ChipDRC.doingDRC THEN f _ ChipFeature.DestroyFeature[f]; END; -- of ExitAFeature currentX _ RightFeaturePQMin[rightFq].cover.x2; MapEqualRightFeaturePQ[p: rightFq, proc: ExitAFeature]; IF ChipDRC.doingDRC THEN ChipDRC.RightEdges[rightFq]; DeleteEqualRightFeaturePQ[rightFq]; END; exitCell => BEGIN cqi: CellInstPt _ ExtractCellInstPQ[deadcq]; [x: currentX, call: [head: c]] _ cqi; ChipExpand.ExitInstance[c]; END; ENDCASE => EXIT; ENDLOOP; slice _ ChipWire.DestroySlice[slice]; cq _ DestroyCellInstPQ[cq]; leftFq _ DestroyLeftFeaturePQ[leftFq]; rightFq _ DestroyRightFeaturePQ[rightFq]; IF ChipDRC.doingDRC THEN BEGIN currentX _ ScalePointFromChipmonk[[univ.x2, univ.y2]].x+1; FOR id: NetIdPtr _ allNets, id.next WHILE id#NIL DO ChipDRC.PurgeDRCViolations[id]; ENDLOOP; END; allNets _ DistributeNetsToSources[allNets]; ChipDRC.FinishDRC[rootC]; WriteSimFile[rootC]; ColorOn[]; END; -- of ExtractNets -- M a i n P r o g r a m featureZ: PUBLIC UNCOUNTED ZONE _ ZoneAllocDefs.GetAnXMZone[checkSegments: TRUE]; netZ: PUBLIC UNCOUNTED ZONE _ ZoneAllocDefs.GetAnXMZone[checkSegments: TRUE]; netIdZ: PUBLIC UNCOUNTED ZONE _ ZoneAllocDefs.GetAnXMZone[checkSegments: TRUE]; instanceZ: PUBLIC UNCOUNTED ZONE _ ZoneAllocDefs.GetAnXMZone[checkSegments: TRUE]; clusterZ: PUBLIC UNCOUNTED ZONE _ ZoneAllocDefs.GetAnXMZone[checkSegments: TRUE]; uz: PUBLIC UNCOUNTED ZONE _ ZoneAllocDefs.GetAnXMZone[checkSegments: TRUE]; transZ: PUBLIC UNCOUNTED ZONE _ ZoneAllocDefs.GetAnXMZone[checkSegments: TRUE]; levelNames: PUBLIC ARRAY ExtractLevel OF STRING _ ALL[NIL]; isConductor: PUBLIC ARRAY ExtractLevel OF BOOLEAN _ ALL[FALSE]; levelNames[unknown] _ "?"; levelNames[nWell] _ "nWell"; levelNames[nWellRequired] _ "nWellRequired"; levelNames[nWellForbidden] _ "nWellForbidden"; levelNames[pWell] _ "pWell"; levelNames[pWellRequired] _ "pWellRequired"; levelNames[pWellForbidden] _ "pWellForbidden"; levelNames[nDepletion] _ "nDepletionImplant"; levelNames[nDepletionRequired] _ "nDepletionRequired"; levelNames[nDepletionForbidden] _ "nDepletionForbidden"; levelNames[nBuriedContact] _ "nBuriedContact"; levelNames[nBuriedContactRequired] _ "nBuriedContactRequired"; levelNames[nBuriedContactForbidden] _ "nBuriedContactForbidden"; levelNames[thinOx] _ "ThinOx"; levelNames[nPlus] _ "nPlus"; levelNames[nPlusRequired] _ "nPlusRequired"; levelNames[nPlusForbidden] _ "nPlusForbidden"; levelNames[pPlus] _ "pPlus"; levelNames[pPlusRequired] _ "pPlusRequired"; levelNames[pPlusForbidden] _ "pPlusForbidden"; levelNames[nImplant] _ "nSDImplant"; levelNames[pImplant] _ "pSDImplant"; levelNames[nGate] _ "nGate"; levelNames[nGateRequired] _ "nGateRequired"; levelNames[nGateForbidden] _ "nGateForbidden"; levelNames[pGate] _ "pGate"; levelNames[pGateRequired] _ "pGateRequired"; levelNames[pGateForbidden] _ "pGateForbidden"; levelNames[poly] _ "Poly"; levelNames[polyRequired] _ "polyRequired"; levelNames[polyForbidden] _ "polyForbidden"; levelNames[cut] _ "Cut"; levelNames[metal] _ "Metal"; levelNames[via] _ "Via"; levelNames[metal2] _ "Metal2"; levelNames[pad] _ "Pad"; isConductor[nPlus] _ TRUE; isConductor[pPlus] _ TRUE; isConductor[poly] _ TRUE; isConductor[metal] _ TRUE; isConductor[metal2] _ TRUE; BEGIN ENABLE BEGIN Punt => GOTO Exit; -- for exits UNWIND => ColorOn[]; END; SELECT TRUE FROM HeSetsParamsAndSaysYes["Extract selected circuit?"L] => BEGIN ChipDRC.SetupDRC[ HeSetsParamsAndSaysYes[ "Shall I also check design rules?"L, "(..slows things down a bit...)"L]]; ExtractNets[masterList]; END; HeSetsParamsAndSaysYes["Then I'll make reticles, OK?"L] => ChipReticle.ExtractReticles[masterList]; ENDCASE => Explain["That's all I can do at the moment."L]; EXITS Exit => NULL; END; -- give back the storage we allocated featureZ _ ZoneAllocDefs.DestroyAnXMZone[featureZ]; netZ _ ZoneAllocDefs.DestroyAnXMZone[netZ]; netIdZ _ ZoneAllocDefs.DestroyAnXMZone[netIdZ]; instanceZ _ ZoneAllocDefs.DestroyAnXMZone[instanceZ]; clusterZ _ ZoneAllocDefs.DestroyAnXMZone[clusterZ]; uz _ ZoneAllocDefs.DestroyAnXMZone[uz]; transZ _ ZoneAllocDefs.DestroyAnXMZone[transZ]; END. -- of ChipNetExtract