<> <> <> DIRECTORY Asserting, Atom, Basics, Core, CoreClasses, CoreFlat, CoreIO, CoreOps, CoreProperties, CoreStructuralComparison, Histograms, IO, PWCLCoreFlatExtras, RefTab, Rope, RopeHash, StructuralComparisonDataStructure, StructuralComparisonOps, StructureFromCore; StructureFromCoreImpl: CEDAR PROGRAM IMPORTS Asserting, Atom, CoreClasses, CoreFlat, CoreIO, CoreOps, CoreProperties, CoreStructuralComparison, Histograms, IO, RefTab, Rope, RopeHash, StructuralComparisonDataStructure, StructuralComparisonOps EXPORTS StructureFromCore, CoreStructuralComparison SHARES StructuralComparisonDataStructure = BEGIN OPEN CC: CoreClasses, CF: CoreFlat, CIO: CoreIO, CO: CoreOps, CP: CoreProperties, StructuralComparisonOps, CoreStructuralComparison, StructuralComparisonDataStructure; ViewStats: TYPE ~ REF ViewStatsPrivate; ViewStatsPrivate: PUBLIC TYPE ~ StructuralComparisonDataStructure.ViewStatsPrivate; ATOMList: TYPE = LIST OF ATOM; LosingConstraint: SIGNAL ~ CODE; DroppedConnection: PUBLIC SIGNAL [subroot: Core.CellType, public, actual: DescendantWire] ~ CODE; BogusMerge: PUBLIC SIGNAL [subroot: Core.CellType, w1, w2: DescendantWire, from: DescendantCellInstance] ~ CODE; implKey: ATOM = $StructureFromCoreImplInstance; implVal: REF ROPE _ NEW [ROPE _ "New for this one"]; ColorerKey: ATOM = $CoreStructureColorer; Colorer: TYPE = REF ColorerPrivate; ColorerPrivate: TYPE = RECORD [ CellTypeColor: PROC [ct: Core.CellType] RETURNS [Color], ColorPorts: PROC [ct: Core.CellType, SetColor: PROC [Core.Wire, Color]] <> ]; TransCountsKey: ATOM = CP.RegisterProperty[ $StructureFromCoreImplTransistorCounts]; wireRepProp: ATOM = CIO.RegisterProperty[ CP.RegisterProperty[ $LichenStructureFromCoreImplWireReplacement, CP.Props[[CP.propPrint, CP.PropDontPrint]]], DontWrite, DontRead]; wireColorKey: ATOM = CP.RegisterProperty[ $LichenStructureFromCoreImplWireColor, CP.Props[[CP.propPrint, CP.PropDontPrint]]]; structureFromCorePrefix: ROPE = "StructureFromCore with SubtreeSpec="; structureFromCorePrefixLength: INT = structureFromCorePrefix.Length[]; structureFromCoreFormat: ROPE = structureFromCorePrefix.Concat["%g(%g), MergeSpec=%g(%g), and internals=%g"]; SpecAndKeyList: TYPE = LIST OF SpecAndKey; SpecAndKey: TYPE = RECORD [sts: SubtreeSpec, ms: MergeSpec, internals: BOOL, key: ATOM]; stsToKey: SpecAndKeyList _ NIL; backHashKey: ATOM = $StructureFromCoreImplCellTypeToBackpointerHashtable; structureToCore: ATOM = $StructureToCore; depub: ATOM ~ $StructureFromCoreImplDepublicize; debug: BOOL _ TRUE; GetKeyForSpecs: PROC [sts: SubtreeSpec, ms: MergeSpec, internals: BOOL] RETURNS [key: ATOM] = { FOR stks: SpecAndKeyList _ stsToKey, stks.rest WHILE stks # NIL DO IF stks.first.sts=sts AND stks.first.ms=ms AND stks.first.internals=internals THEN RETURN [stks.first.key]; ENDLOOP; key _ CP.RegisterProperty[ Atom.MakeAtom[IO.PutFR[ structureFromCoreFormat, [cardinal[LOOPHOLE[sts, CARDINAL]]], [refAny[NEW [SubtreeSpec _ sts]]], [cardinal[LOOPHOLE[ms, CARDINAL]]], [refAny[NEW [MergeSpec _ ms]]], [boolean[internals]] ]], CP.Props[[CP.propPrint, CP.PropDontPrint]]]; stsToKey _ CONS[[sts, ms, internals, key], stsToKey]; RETURN}; GetGraph: PUBLIC PROC [ttols: TransistorTolerances _ NIL, cct: Core.CellType, internals: BOOL, specData: REF ANY, sts: SubtreeSpec, ms: MergeSpec, SurveyPart: PROC [v: Vertex, core: REF ANY --UNION [Wire, CellInstance]--] _ NIL, vs: ViewStats _ NIL] RETURNS [sct: CellType] = { original: Core.CellType = cct; PushTimer[$getGraph]; {ENABLE UNWIND => PopTimer[$getGraph]; colorer: Colorer = WITH CP.InheritCellTypeProp[cct, ColorerKey] SELECT FROM x: Colorer => x, ENDCASE => defaultColorer; structureFromCoreCellType: ATOM = GetKeyForSpecs[sts, ms, internals]; backHash: RefTab.Ref; tc: TransCounts _ NARROW[CP.InheritCellTypeProp[cct, TransCountsKey]]; uncounted: BOOL _ tc=NIL; IF internals THEN { IF cct.class = CC.transistorCellClass THEN ERROR; IF tc=NIL THEN tc _ NEW [TransCountsPrivate _ []] ELSE tc^ _ []} ELSE IF tc=NIL THEN { IF cct.class = CC.transistorCellClass THEN ERROR; tc _ NEW [TransCountsPrivate _ []]}; WITH CP.GetCellTypeProp[cct, structureFromCoreCellType] SELECT FROM x: CellType => sct _ IF Asserting.FnVal[implKey, x.otherPublic] = implVal THEN x ELSE NIL; ENDCASE => sct _ NIL; IF sct = NIL THEN { sct _ NEW [CellTypeRep _ [ name: GetCellTypeName[original], color: FilterColor[colorer.CellTypeColor[original]], ports: NEW [PortSeq[CO.WireSeqBits[original.public]]], transCounts: tc, otherPublic: Asserting.AssertFn1[structureToCore, original, Asserting.AssertFn1[implKey, implVal, NIL]] ]]; sct.ports.length _ 0; CP.PutCellTypeProp[original, structureFromCoreCellType, sct]; colorer.ColorPorts[original, SetWireColor]; IF NOT internals THEN { wireToPort: RefTab.Ref = RefTab.Create[]; pi: PortIndex _ 0; DefinePorts: PROC [wire: Core.Wire] = { IF NOT wireToPort.Fetch[wire].found THEN { name: ROPE = UnionNames[CO.GetFullWireNames[original.public, wire]]; sct.ports[pi] _ [ name: name, color: GetWireColor[wire, noColor] ]; IF sct.ports[pi] = [] THEN ERROR; IF NOT wireToPort.Insert[wire, NEW [PortIndex _ pi]] THEN ERROR; pi _ pi + 1; }; }; EnumerateInstances: PROC [Consume: PROC [ci: CoreClasses.CellInstance] RETURNS [stop: BOOL _ FALSE]] ~ {}; IdentifyActual: PROC [ci: CoreClasses.CellInstance, actual: Core.Wire, describe: BOOL _ FALSE] RETURNS [ActualID] ~ {ERROR}; mergingDone: BOOL _ FALSE; Consume: PROC [ds: Element] --MergeConsumer-- ~ { fw1: CF.FlatWire ~ NARROW[ds.first]; i1: PortIndex _ NARROW[wireToPort.Fetch[fw1.wire].val, REF PortIndex]^; IF fw1.flatCell.path.length#0 OR sct.ports[i1]=[] THEN ERROR; FOR ds _ ds.rest, ds.rest WHILE ds#NIL DO fw2: CF.FlatWire ~ NARROW[ds.first]; i2: PortIndex _ NARROW[wireToPort.Fetch[fw2.wire].val, REF PortIndex]^; IF fw2.flatCell.path.length#0 OR i1=i2 OR sct.ports[i2]=[] THEN ERROR; IF i2 ForgetGraph[sct]; backHash _ RefTab.Create[hash: HashDescendant, equal: DescendantEqual]; sct.otherPrivate _ Asserting.AssertFn1[backHashKey, backHash, sct.otherPrivate]; { IntroduceWires: PROC [flatCell: CF.FlatCellTypeRec, wireRoot: CF.WireRoot, root: Core.Wire, bindings: CF.Bindings] = { DefineInternal: PROC [wire: Core.Wire] = { IF bindings = NIL OR NOT bindings.Fetch[wire].found THEN { dw: CF.FlatWire = NEW [CF.FlatWireRec _ [flatCell: flatCell, wireRoot: wireRoot, wire: wire]]; IF NOT backHash.Fetch[dw].found THEN { name: ROPE ~ CF.WirePathRope[root: original, wire: dw^]; v: Vertex = NEW [VertexRep _ [ name: name, class: net, other: Asserting.AssertFn1[structureToCore, dw, NIL] ]]; IF NOT backHash.Insert[dw, v] THEN ERROR; AddPart[sct, v]; IF SurveyPart # NIL THEN SurveyPart[v, wire]; }; }; }; CO.VisitRootAtomics[root, DefineInternal]; }; Flatten: PROC [cell: Core.CellType, target: CF.FlatCellTypeRec _ CF.allFlatCells, flatCell: CF.FlatCellTypeRec _ [], instance: CF.CellInstance _ NIL, index: NAT _ LAST[NAT], parent: Core.CellType _ NIL, flatParent: CF.FlatCellTypeRec _ [], data: REF ANY _ NIL, bindings: CF.Bindings _ NIL] --CF.BoundFlatCellProc-- = { path: DescendantCellInstancePrivate = flatCell.path; ans: SubtreeAns ~ IF path.length > 0 THEN sts[specData, instance, path, ttols] ELSE [NIL]; flatten: BOOL = ans.leafType = NIL; rct: CC.RecordCellType ~ IF cell.class = CC.recordCellClass THEN NARROW[cell.data] ELSE NIL; IF flatten THEN { EnumerateInstances: PROC [Consume: PROC [ci: CC.CellInstance] RETURNS [stop: BOOL _ FALSE]] = { IF cell.class = CC.recordCellClass THEN FOR i: NAT IN [0 .. rct.size) DO IF Consume[rct[i]] THEN EXIT; ENDLOOP; }; IdentifyActual: PROC [ci: CoreClasses.CellInstance, actual: Core.Wire, describe: BOOL _ FALSE] RETURNS [ActualID] = { dw: DescendantWire ~ NARROW[bindings.Fetch[actual].val]; IF dw # NIL THEN RETURN [[dw, IF describe THEN CF.WirePathRope[original, dw^] ELSE NIL]]; RETURN [[actual, IF describe THEN CF.WirePathRope[original, [flatCell: flatCell, wire: actual]] ELSE NIL]]; }; ConsumeMerge: PROC [ds: Element] = { v: Vertex _ CanonizeAndGetStructure[sct, path, ds.first]; fw, sw: Core.Wire _ NIL; WITH ds.first SELECT FROM dw: DescendantWire => { IF dw.flatCell.path.length#0 THEN ERROR; fw _ dw.wire}; dci: DescendantCellInstance => v _ v; ENDCASE => ERROR; IF v=NIL THEN ERROR; FOR ds _ ds.rest, ds.rest WHILE ds # NIL DO w: Vertex _ CanonizeAndGetStructure[sct, path, ds.first]; IF w=NIL THEN ERROR; IF fw#NIL THEN { WITH ds.first SELECT FROM dw: DescendantWire => { IF dw.flatCell.path.length#0 THEN ERROR; sw _ dw.wire}; dci: DescendantCellInstance => ERROR; ENDCASE => ERROR; PostMerge[cell, fw, sw]}; v _ MergeVertices[sct, v, w].merged; IF v=NIL THEN ERROR; ENDLOOP; }; Depublicize: PROC [pw: Core.Wire] ~ { dw: DescendantWire ~ NEW [CoreFlat.FlatWireRec _ [flatCell: flatCell, wire: pw]]; v: Vertex ~ GetStructure[sct, dw]; v.other _ Asserting.AssertFn1[fn: depub, val: $TRUE, inAdditionTo: v.other, mayMute: TRUE]; RETURN}; IgnoreDepublicity: PROC [pw: Core.Wire] ~ {RETURN}; IF cell.class=CC.recordCellClass THEN { IF vs#NIL THEN vs.sizeDists[Original].ChangeTransformed[MAX[minbin, rct.size], MAX[minbin, rct.internal.size]]; IntroduceWires[flatCell, internal, rct.internal, bindings]}; CF.NextBoundCellType[cell, target, flatCell, instance, index, parent, flatParent, data, bindings, Flatten]; ms[specData, cell, path.length=0 AND flatCell.recastCount#0, EnumerateInstances, IdentifyActual, ConsumeMerge, IF path.length=0 AND flatCell.recastCount=0 THEN Depublicize ELSE IgnoreDepublicity]; } ELSE { ci: CC.CellInstance = instance; di: DescendantCellInstance = NEW [DescendantCellInstancePrivate _ path]; name: ROPE ~ CF.InstancePathRope[original, path]; type: CellType = GetGraph[ttols, ans.leafType, FALSE, specData, sts, MergeNothing, NIL]; itc: TransCounts ~ NARROW[CP.InheritCellTypeProp[cell, TransCountsKey]]; v: Vertex = NEW [VertexRep _ [ name: name, class: cell, type: type, other: Asserting.AssertFn1[structureToCore, di, NIL] ]]; bounded: RefTab.Ref ~ RefTab.Create[]; pi: PortIndex _ 0; SeeBinding: PROC [from: REF ANY, ProduceTos: ToProducer] --MapConsumer-- = { leafPub: Core.Wire ~ NARROW[from]; theV: Vertex _ NIL; PerInstPub: PROC [to: REF ANY] --ToConsumer-- ~ { instPub: Core.Wire ~ NARROW[to]; adw: DescendantWire = NARROW[bindings.Fetch[instPub].val]; IF adw = NIL THEN ERROR; IF NOT bounded.Insert[instPub, leafPub] THEN ERROR; {nv: Vertex = GetStructure[sct, adw]; IF nv = NIL THEN ERROR; IF theV=NIL THEN Link[v, theV _ nv, type.ports[pi].color] ELSE IF (theV _ MergeVertices[sct, theV, nv].merged)=NIL THEN ERROR; RETURN}}; IF leafPub.size=0 THEN { ProduceTos[PerInstPub]; IF theV=NIL THEN ERROR; pi _ pi + 1; RETURN}; RETURN}; sats: RefTab.Ref ~ RefTab.Create[]; CheckBinding: PROC [instPub: Core.Wire] ~ { adw: DescendantWire ~ NARROW[bindings.Fetch[instPub].val]; rep: Core.Wire ~ Canonize[instPub, FALSE]; IF rep#NIL THEN { sat: DescendantWire ~ NARROW[sats.Fetch[rep].val]; SELECT TRUE FROM sat=NIL => IF NOT sats.Insert[rep, adw] THEN ERROR; CF.FlatWireEqual[sat, adw] => NULL; adw.flatCell.path.length#0 OR NOT CO.RecursiveMember[original.public, adw.wire] => BogusMerge[original, adw, sat, di]; sat.flatCell.path.length#0 OR NOT CO.RecursiveMember[original.public, sat.wire] => BogusMerge[original, adw, sat, di]; ENDCASE => PostMerge[original, adw.wire, sat.wire]}; IF bounded.Fetch[instPub].found THEN RETURN; IF adw = NIL THEN ERROR; {nv: Vertex = GetStructure[sct, adw]; IF nv = NIL THEN ERROR; IF nv.firstEdge#NIL OR NOT bounded.Insert[nv, instPub] THEN DroppedConnection[original, NEW [DescendantWirePrivate _ [flatCell: flatCell, wireRoot: public, wire: instPub]], adw]; RETURN}}; IF NOT backHash.Insert[di, v] THEN ERROR; AddPart[sct, v]; IF itc#NIL THEN { tc.flatTransistors _ tc.flatTransistors + itc.flatTransistors; tc.flatTransMerges _ tc.flatTransMerges + itc.flatTransMerges; tc.flatWires _ tc.flatWires + itc.flatWires; tc.flatWireDels _ tc.flatWireDels + itc.flatWireDels; } ELSE IF vs#NIL THEN vs.missingTransistors _ vs.missingTransistors+1; ans.publicInvMapEnumerator.Enumerate[ans.publicInvMapEnumerator.data, SeeBinding]; IF pi#type.ports.length THEN ERROR; CO.VisitRootAtomics[ci.type.public, CheckBinding]; IF SurveyPart # NIL THEN SurveyPart[v, ci]; }; IF ans.Pop#NIL THEN ans.Pop[specData]; RETURN}; IntroduceWires[[], public, original.public, NIL]; Flatten[original, CF.allFlatCells, [], NIL, LAST[NAT], NIL, [], NIL, RefTab.Create[]]; IF sct.ports.length#0 THEN ERROR; }; {pi: PortIndex _ 0; seen: RefTab.Ref = RefTab.Create[]; SetPortNet: PROC [wire: Core.Wire] = { dw: DescendantWire = NEW [DescendantWirePrivate _ [wireRoot: public, wire: wire]]; nv: Vertex = GetStructure[sct, dw]; IF nv = NIL THEN ERROR; IF NOT seen.Fetch[nv].found THEN { IF NOT seen.Insert[nv, $TRUE] THEN ERROR; SELECT Asserting.FnVal[depub, nv.other] FROM $TRUE => { nv.other _ Asserting.Remove1[depub, $TRUE, nv.other, TRUE]; RETURN}; NIL => { first: BOOL _ TRUE; color: Color _ 0; FOR ds: Element _ GetCore[nv], ds.rest WHILE ds # NIL DO dw: DescendantWire = NARROW[ds.first]; IF dw.path.length # 0 THEN ERROR; IF first THEN first _ FALSE; color _ color + GetWireColor[dw.wire, 0]; ENDLOOP; IF first THEN ERROR; sct.ports[pi] _ [ name: nv.name, net: nv, color: FilterColor[color] ]; pi _ pi + 1; RETURN}; ENDCASE => ERROR; }; RETURN}; [] _ CO.VisitRootAtomics[original.public, SetPortNet]; sct.ports.length _ pi; }; AddMirror[sct]; {CheckVertex: PROC [v: Vertex] ~ { IF v.class=net AND v.firstEdge=NIL THEN { IF debug THEN Log["Deleting lonely %g in %g.\n", [rope[v.name]], [rope[sct.name]]]; DeleteVertex[sct, v]; tc.flatWireDels _ tc.flatWireDels + 1; }; RETURN}; sct.EnumerateParts[CheckVertex, FALSE]; IF sct.netCount < sct.ports.length THEN ERROR; tc.flatWires _ tc.flatWires + (sct.netCount - sct.ports.length); IF vs#NIL THEN vs.sizeDists[Reconciled].ChangeTransformed[MAX[minbin, sct.cellCount], MAX[minbin, sct.netCount]]; CP.PutCellTypeProp[cct, TransCountsKey, tc]; }; }}; PopTimer[$getGraph]; RETURN}; ForgetGraph: PUBLIC PROC [sct: CellType] = { cct: Core.CellType = GetCellType[sct]; propsToRemove: ATOMList _ NIL; FindPropsToRemove: PROC [prop: ATOM, val: REF ANY _ NIL] = { IF structureFromCorePrefix.Equal[Atom.GetPName[prop].Substr[len: structureFromCorePrefixLength]] THEN propsToRemove _ CONS[prop, propsToRemove]; }; EnumerateParts[sct, DestroyVertex, TRUE]; sct^ _ CellTypeRep[destroyed: TRUE]; CP.Enumerate[cct.properties, FindPropsToRemove]; FOR propsToRemove _ propsToRemove, propsToRemove.rest WHILE propsToRemove # NIL DO CP.PutCellTypeProp[cct, propsToRemove.first, NIL]; ENDLOOP; RETURN}; AddPart: PROC [sct: CellType, v: Vertex] = { v.nextPart _ sct.firstPart; sct.firstPart _ v; sct.size _ sct.size + 1; SELECT v.class FROM cell => sct.cellCount _ sct.cellCount + 1; net => sct.netCount _ sct.netCount + 1; ENDCASE => ERROR; RETURN}; Link: PROC [cv, nv: Vertex, edgeColor: Color] = { e: Edge = NEW [EdgeRep _ [ sides: [ net: [v: nv, next: NIL, prev: nv.lastEdge], cell: [v: cv, next: NIL, prev: cv.lastEdge]], color: edgeColor]]; IF nv.lastEdge = NIL THEN nv.firstEdge _ e ELSE nv.lastEdge.sides[net].next _ e; IF cv.lastEdge = NIL THEN cv.firstEdge _ e ELSE cv.lastEdge.sides[cell].next _ e; nv.lastEdge _ cv.lastEdge _ e; RETURN}; DestroyVertex: PROC [v: Vertex] = { IF v=NIL THEN RETURN; WHILE v.firstEdge # NIL DO e: Edge _ v.firstEdge; v.firstEdge _ e.sides[v.class].next; e.sides[v.class] _ [NIL, NIL, NIL]; ENDLOOP; v^ _ [class: v.class]; RETURN}; AddMirror: PROC [sct: CellType] = { v: Vertex = NEW [VertexRep _ [ name: " The Outside World! ", class: cell, type: sct, isMirror: TRUE ]]; sct.mirror _ v; FOR pi: PortIndex IN [0 .. sct.ports.length) DO Link[v, sct.ports[pi].net, sct.ports[pi].color]; ENDLOOP; RETURN}; PostMerge: PROC [cct: Core.CellType, w1, w2: Core.Wire] ~ { w1 _ Canonize[w1, TRUE]; w2 _ Canonize[w2, TRUE]; IF w1#w2 THEN CP.PutWireProp[w1, wireRepProp, w2]; RETURN}; Canonize: PROC [w: Core.Wire, fix: BOOL] RETURNS [Core.Wire] ~ { original: Core.Wire ~ w; IF CP.GetWireProp[w, wireRepProp]=NIL THEN { IF fix THEN {CP.PutWireProp[w, wireRepProp, w]; RETURN [w]} ELSE RETURN [NIL]; }; DO v: Core.Wire ~ NARROW[CP.GetWireProp[w, wireRepProp]]; IF v=NIL THEN ERROR; IF v=w THEN RETURN [w]; w _ v; ENDLOOP}; GetCommonalityConstraints: PUBLIC PROC [subroot: Core.CellType] RETURNS [RefTab.Ref] ~ { constraints: RefTab.Ref ~ RefTab.Create[]; PerAtomic: PROC [wire: Core.Wire] ~ { cw: Core.Wire ~ Canonize[wire, FALSE]; IF cw#NIL THEN { constraint: RefTab.Ref _ NARROW[constraints.Fetch[cw].val]; IF constraint=NIL AND NOT constraints.Insert[cw, constraint _ RefTab.Create[]] THEN ERROR; IF NOT constraint.Insert[wire, wire] THEN ERROR} ELSE wire _ wire}; CO.VisitRootAtomics[subroot.public, PerAtomic]; RETURN [constraints]}; SetWireColor: PROC [wire: Core.Wire, color: Color] = { CP.PutWireProp[wire, wireColorKey, NEW [Color _ color]]; RETURN}; GetWireColor: PROC [wire: Core.Wire, default: Color] RETURNS [color: Color] = { rc: REF Color = NARROW[CP.GetWireProp[wire, wireColorKey]]; color _ IF rc#NIL THEN rc^ ELSE IF default#noColor THEN default ELSE ERROR; RETURN}; GetCellType: PUBLIC PROC [sct: CellType] RETURNS [cct: Core.CellType] = { cct _ NARROW[Asserting.FnVal[structureToCore, sct.otherPublic]]; RETURN}; CanonizeAndGetStructure: PUBLIC PROC [sct: CellType, insert: DescendantCellInstancePrivate, core: --not necessarily canonical--Descendant] RETURNS [v: Vertex] = { backHash: RefTab.Ref = NARROW[Asserting.FnVal[backHashKey, sct.otherPrivate]]; cd: --Canonized--Descendant _ core; WITH core SELECT FROM di: DescendantCellInstance => cd _ NEW [DescendantCellInstancePrivate _ CF.RaiseRootOfInstancePath[insert, di^]]; dw: DescendantWire => { original: Core.CellType = GetCellType[sct]; cd _ NEW [CF.FlatWireRec _ CF.CanonizeWire[original, CF.RaiseRootOfFlatWire[insert, dw^]]]; }; ENDCASE => ERROR; v _ NARROW[backHash.Fetch[cd].val]; IF v=NIL THEN RETURN; FOR v _ v, v.better UNTIL v.better=NIL DO NULL ENDLOOP; RETURN}; GetStructure: PUBLIC PROC [sct: CellType, core: --Canonized--Descendant] RETURNS [v: Vertex] = { backHash: RefTab.Ref = NARROW[Asserting.FnVal[backHashKey, sct.otherPrivate]]; FOR v _ NARROW[backHash.Fetch[core].val], v.better UNTIL v.better = NIL DO NULL ENDLOOP; RETURN}; GetCore: PUBLIC PROC [v: Vertex] RETURNS [core: Element] = { Note: PROC [assertion: Asserting.Assertion] --Asserting.AssertionConsumer-- = { d: Descendant = Asserting.FnVal[structureToCore, LIST[assertion]]; core _ CONS[d, core]; RETURN}; core _ NIL; Asserting.EnumerateAssertionsAbout[structureToCore, v.other, Note]; RETURN}; defaultColorer: Colorer _ NEW [ColorerPrivate _ [DefaultCellTypeColor, DefaultColorPorts]]; DefaultCellTypeColor: PROC [ct: Core.CellType] RETURNS [color: Color] = { name: ROPE _ CO.GetCellTypeName[ct]; color _ RopeHash.FromRope[name]; color _ color * color; RETURN}; DefaultColorPorts: PROC [ct: Core.CellType, SetColor: PROC [Core.Wire, Color]] = { ColorPort: PROC [wire: Core.Wire] = { SetColor[wire, RefHash[wire]]; RETURN}; [] _ CO.VisitRootAtomics[ct.public, ColorPort]; RETURN}; transistorColorer: Colorer _ NEW [ColorerPrivate _ [TransistorCellTypeColor, ColorTransistorPorts]]; TransistorCellTypeColor: PROC [ct: Core.CellType] RETURNS [color: Color] = { td: CC.Transistor = NARROW[ct.data]; color _ SELECT td.type FROM nE => 36, pE => 24, nD => 33, ENDCASE => ERROR; RETURN}; ColorTransistorPorts: PROC [ct: Core.CellType, SetColor: PROC [Core.Wire, Color]] = { ColorPort: PROC [wire: Core.Wire] = { name: ROPE = CO.GetShortWireName[wire]; SetColor[wire, SELECT TRUE FROM name.Equal[CC.transistorPortNames[ch1]] => channelColor, name.Equal[CC.transistorPortNames[ch2]] => channelColor, name.Equal[CC.transistorPortNames[gate]] => gateColor, name.Equal[CC.transistorPortNames[Vdd]] => substrateColor, ENDCASE => ERROR ]; RETURN}; [] _ CO.VisitRootAtomics[ct.public, ColorPort]; RETURN}; gateColor: Color _ 47; channelColor: Color _ 834; substrateColor: Color _ 99; UnionNames: PROC [names: LIST OF ROPE] RETURNS [unioned: ROPE] = { unioned _ NIL; FOR names _ names, names.rest WHILE names # NIL DO unioned _ IF unioned=NIL THEN names.first ELSE Rope.Cat[unioned, "|", names.first]; ENDLOOP; RETURN}; GetCellTypeName: PROC [cct: Core.CellType] RETURNS [name: ROPE] = { IF (name _ CO.GetCellTypeName[cct]).Length[] # 0 THEN RETURN; cct _ CO.ToBasic[cct]; IF (name _ CO.GetCellTypeName[cct]).Length[] # 0 THEN RETURN; WITH cct.data SELECT FROM t: CC.Transistor => { transistorLength: INT _ NARROW[CoreProperties.GetCellTypeProp[cct, CoreClasses.lengthProp], REF INT]^; transistorWidth: INT _ NARROW[CoreProperties.GetCellTypeProp[cct, CoreClasses.widthProp], REF INT]^; name _ IO.PutFR[ "%g(%g/%g)", [rope[SELECT t.type FROM nE => "nE", pE => "pE", nD => "nD", ENDCASE => ERROR]], [integer[transistorLength]], [integer[transistorWidth]]]; [] _ CO.SetCellTypeName[cct, name]; }; ENDCASE => name _ IO.PutFR["%xH^", [cardinal[LOOPHOLE[cct]]]]; RETURN}; DontWrite: PROC [stream: IO.STREAM, prop: ATOM, value: REF ANY] ~ { IF complain THEN SIGNAL LosingConstraint--can't survive CoreIO, so can't have constraints here--; }; complain: BOOL _ TRUE; DontRead: PROC [stream: IO.STREAM, prop: ATOM] RETURNS [value: REF ANY] ~ {RETURN [NIL]}; Start: PROC = { CP.PutCellClassProp[CC.transistorCellClass, ColorerKey, transistorColorer]; CP.PutCellClassProp[CC.transistorCellClass, TransCountsKey, NEW [TransCountsPrivate _ [1, 0]] ]; }; Start[]; END.