DIRECTORY Basics, DFUtilities, FS, IO, LichenDataStructure, LichenOps, LichenTransforms, LichenTransformsPrivate, RedBlackTree, RedBlackTreeExtras, RefTab, Rope, ViewerIO; LichenChildishTransforms: CEDAR PROGRAM IMPORTS IO, LichenOps, LichenTransformsPrivate, RedBlackTree, RedBlackTreeExtras, RefTab, Rope EXPORTS LichenTransforms = BEGIN OPEN LichenDataStructure, LichenTransforms, LichenOps, LichenTransformsPrivate; KeepPort: NAT = LAST[NAT] - 1; LowerChildren: PUBLIC PROC [design: Design, childTypeA: REF ANY, gcNamesl: NamesList, sibber: Mapper--child => siblings--, newPortNamer: NewPortNamer] RETURNS [gcs: VertexS, children: VertexList] = BEGIN gcNamess: NamesS _ ToNamesS[gcNamesl]; childType: CellType _ ToType[design, childTypeA]; gcTypes: CellTypeS _ NIL; first: BOOL _ TRUE; grandChildAnsss: GrandChildAnsSS; dif: BOOL _ FALSE; oldPorts: PortS _ childType.ports; childAnses: ChildAnses _ NEW [ChildAnsesRep[oldPorts.length]]; losses, gains, remains, newChildPortIndex: NAT _ 0; oldGCConnectionss: VertexSS--gcPortIndex--; oldNetToConnections: RefTab.Ref; Survey: PROC [child: Vertex, sibs: VertexS] = { IF first THEN { connectionCount: INT _ 0; grandChildAnsss _ NEW [GrandChildAnsSSeq[sibs.length]]; oldGCConnectionss _ NEW [VertexSSeq[sibs.length]]; gcTypes _ NEW [CellTypeSeq[sibs.length]]; FOR i: NAT IN [0 .. sibs.length) DO gcTypes[i] _ sibs[i].type; connectionCount _ connectionCount + gcTypes[i].ports.length; ENDLOOP; oldNetToConnections _ RefTab.Create[connectionCount]; }; IF sibs.length # gcTypes.length THEN { Warn[[], "Different number of siblings (%g, rather than %g) at %g", IO.card[sibs.length], IO.card[gcTypes.length], IO.refAny[GlobalVertexName[child]]]; dif _ TRUE} ELSE FOR i: NAT IN [0 .. sibs.length) DO IF sibs[i].type # gcTypes[i] THEN { Warn[[], "%g is a %g, not a %g", IO.refAny[GlobalVertexName[sibs[i]]], IO.refAny[PickAName[sibs[i].type.names]], IO.refAny[PickAName[gcTypes[i].names]]]; dif _ TRUE} ELSE IF sibs[i] = child THEN { Warn[[], "Child %g sibbed to itself", IO.refAny[GlobalVertexName[child]]]; dif _ TRUE} ELSE { gcPortIndex: NAT _ 0; IF first THEN { oldGCConnectionss[i] _ NEW [VertexSeq[gcTypes[i].ports.length]]; grandChildAnsss[i] _ NEW [GrandChildAnsSeq[gcTypes[i].ports.length]]; FOR gcpi: NAT IN [0 .. grandChildAnsss[i].length) DO grandChildAnsss[i][gcpi] _ [sawSelves: NEW [BoolSeq[sibs.length]]]; ENDLOOP}; FOR e: Edge _ sibs[i].firstEdge, e.sides[cell].next WHILE e # NIL DO sawBord, sawBords, sawElse: BOOL _ FALSE; sawSelves: BoolS _ NEW [BoolSeq[sibs.length]]; net: Vertex _ e.sides[net].v; FOR i: NAT IN [0 .. sibs.length) DO sawSelves[i] _ FALSE ENDLOOP; IF e.sides[cell].v # sibs[i] THEN ERROR; FOR f: Edge _ net.firstEdge, f.sides[net].next WHILE f # NIL DO IF f.sides[net].v # net THEN ERROR; IF f.sides[cell].v = child THEN { sawBords _ sawBord; sawBord _ TRUE; grandChildAnsss[i][gcPortIndex].oldChildPortIndex _ f.portIndex; } ELSE {sawSomeSelf: BOOL _ FALSE; FOR j: NAT IN [0 .. sibs.length) DO IF f.sides[cell].v = sibs[j] THEN sawSomeSelf _ sawSelves[j] _ TRUE; ENDLOOP; IF NOT sawSomeSelf THEN sawElse _ TRUE ELSE IF first THEN { selfEdges: EdgeList _ NARROW[oldNetToConnections.Fetch[net].val]; selfEdges _ CONS[f, selfEdges]; [] _ oldNetToConnections.Store[net, selfEdges]; }; }; ENDLOOP; IF NOT sawSelves[i] THEN ERROR; IF first THEN { grandChildAnsss[i][gcPortIndex].sawBord _ sawBord; grandChildAnsss[i][gcPortIndex].sawBords _ sawBords; grandChildAnsss[i][gcPortIndex].sawElse _ sawElse; grandChildAnsss[i][gcPortIndex].sawSelves _ sawSelves; IF sawBord AND NOT (sawElse OR sawBords) THEN { losses _ NoteLoss[netMapper, net, losses]; childAnses[grandChildAnsss[i][gcPortIndex].oldChildPortIndex].newPortIndex _ NullPortIndex; }; IF sawElse AND NOT sawBord THEN gains _ NoteGain[netMapper, net, gains]; oldGCConnectionss[i][gcPortIndex] _ net; } ELSE { Dif: PROC = {Warn[[], "%g & %g are connected differently than the first pair", IO.refAny[GlobalVertexName[child]], IO.refAny[GlobalVertexName[sibs[i]]]]; dif _ TRUE}; IF grandChildAnsss[i][gcPortIndex].sawBord # sawBord THEN Dif[]; IF grandChildAnsss[i][gcPortIndex].sawBords # sawBords THEN Dif[]; IF grandChildAnsss[i][gcPortIndex].sawElse # sawElse THEN Dif[]; FOR j: NAT IN [0 .. sibs.length) DO IF grandChildAnsss[i][gcPortIndex].sawSelves[j] # sawSelves[j] THEN Dif[]; ENDLOOP}; gcPortIndex _ gcPortIndex + 1; ENDLOOP; }; ENDLOOP; first _ FALSE; }; newPorts: PortS; newPortIndex: NAT _ 0; inside: VertexS--oldChildIndex-- _ NEW [VertexSeq[oldPorts.length]]; insideEdge: Edge; parentTypes: RefTab.Ref _ RefTab.Create[]; netMapper: RefTab.Ref _ RefTab.Create[]; portNameNotes: SymbolTable _ RedBlackTree.Create[GetNameEntryKey, CompareNameEntries]; portClassNotes: SymbolTable _ RedBlackTree.Create[GetNameEntryKey, CompareNameEntries]; children _ NIL; IF KeepPort = NullPortIndex THEN ERROR; FOR e: Edge _ childType.mirror.firstEdge, e.sides[cell].next WHILE e # NIL DO IF e.sides[cell].v # childType.mirror THEN ERROR; inside[e.portIndex] _ e.sides[net].v; ENDLOOP; FOR ocpi: NAT IN [0 .. oldPorts.length) DO childAnses[ocpi] _ [newPortIndex: KeepPort]; ENDLOOP; FOR child: Vertex _ childType.firstInstance, child.nextInstance WHILE child # NIL DO sibsAsAny: REF ANY; IF IsMirror[child] THEN ERROR; --AM2 sibsAsAny _ sibber.map[sibber.data, child]; IF sibsAsAny = NIL THEN {Warn[[], "No siblings given for %g", IO.rope[GlobalVertexName[child]]]; dif _ TRUE} ELSE WITH sibsAsAny SELECT FROM vs: VertexS => Survey[child, vs]; ENDCASE => {Warn[[], "Siblings for %g should be a CompareTransforms.VertexS, not %g", IO.rope[GlobalVertexName[child]], IO.refAny[sibsAsAny]]; dif _ TRUE}; ENDLOOP; IF first OR dif THEN RETURN [NIL, NIL]; NoteChange[childType]; gcs _ NEW [VertexSeq[gcTypes.length]]; FOR i: NAT IN [0 .. gcs.length) DO gcs[i] _ NEW [VertexRep _ [names: gcNamess[i], type: gcTypes[i], parent: childType, class: cell]]; AddVertex[gcs[i]]; LinkInstance[gcs[i]]; ENDLOOP; remains _ oldPorts.length - losses; newPorts _ NEW [PortSeq[remains + gains]]; insideEdge _ childType.mirror.firstEdge; FOR oldPortIndex: NAT IN [0 .. oldPorts.length) DO nextInsideEdge: Edge _ insideEdge.sides[cell].next; IF insideEdge.sides[cell].v # childType.mirror THEN ERROR; IF insideEdge.portIndex # oldPortIndex THEN ERROR; SELECT childAnses[oldPortIndex].newPortIndex FROM KeepPort => { newPorts[newChildPortIndex] _ oldPorts[oldPortIndex]; childAnses[oldPortIndex].newPortIndex _ newChildPortIndex; insideEdge.portIndex _ newChildPortIndex; newChildPortIndex _ newChildPortIndex + 1}; NullPortIndex => RemoveEdge[insideEdge]; ENDCASE => ERROR; insideEdge _ nextInsideEdge; ENDLOOP; IF insideEdge # NIL THEN ERROR; IF newChildPortIndex # remains THEN ERROR; FOR i: NAT IN [0 .. gcs.length) DO FOR gcIndex: NAT IN [0 .. gcTypes[i].ports.length) DO AddPort: PROC RETURNS [insideNet: Vertex] = { outsideNet: Vertex _ oldGCConnectionss[i][gcIndex]; insideAsAny: REF ANY _ netMapper.Fetch[outsideNet].val; IF insideAsAny = NIL THEN ERROR; IF ISTYPE[insideAsAny, Vertex] THEN RETURN [NARROW[insideAsAny]]; IF insideAsAny # $AddPort THEN ERROR; insideNet _ NEW [VertexRep _ [names: outsideNet.names, parent: childType, class: net]]; AddVertex[insideNet]; newPorts[newChildPortIndex] _ [netNames: LIST[PickAName[insideNet.names]]]; [newPorts[newChildPortIndex].names, newPorts[newChildPortIndex].equivClass] _ newPortNamer.NameNewPort[newPortNamer.data, TRUE, childType, newPorts, newChildPortIndex, outsideNet, NARROW[oldNetToConnections.Fetch[outsideNet].val]]; NoteNaming[portNameNotes, portClassNotes, newPorts, newChildPortIndex, outsideNet, NARROW[oldNetToConnections.Fetch[outsideNet].val]]; grandChildAnsss[i][gcIndex].newChildPortIndex _ newChildPortIndex; AddEdge[childType.mirror, insideNet]; newChildPortIndex _ newChildPortIndex + 1; [] _ netMapper.Store[outsideNet, insideNet]; }; MakeDummy: PROC RETURNS [insideNet: Vertex] = { insideNet _ NARROW[netMapper.Fetch[oldGCConnectionss[i][gcIndex]].val]; IF insideNet # NIL THEN RETURN; insideNet _ NEW [VertexRep _ [names: oldGCConnectionss[i][gcIndex].names, parent: childType, class: net]]; AddVertex[insideNet]; IF NOT netMapper.Store[oldGCConnectionss[i][gcIndex], insideNet] THEN ERROR; }; AddEdge[gcs[i], IF grandChildAnsss[i][gcIndex].sawBord THEN inside[grandChildAnsss[i][gcIndex].oldChildPortIndex] ELSE IF grandChildAnsss[i][gcIndex].sawElse THEN AddPort[] ELSE MakeDummy[]]; ENDLOOP; ENDLOOP; IF newChildPortIndex # newPorts.length THEN ERROR; FixNames[childType, newPorts, remains, newPortNamer, portNameNotes, portClassNotes]; childType.ports _ newPorts; CheckType[childType, check, ignore, TRUE]; FOR child: Vertex _ childType.firstInstance, child.nextInstance WHILE child # NIL DO sibs: VertexS; IF IsMirror[child] THEN ERROR; --AM2 children _ CONS[child, children]; sibs _ NARROW[sibber.map[sibber.data, child]]; IF sibs.length # gcs.length THEN ERROR --caller blew it--; FOR i: NAT IN [0 .. sibs.length) DO IF sibs[i].parent # child.parent THEN ERROR --caller blew it--; WHILE sibs[i].firstEdge # NIL DO e: Edge _ sibs[i].firstEdge; net: Vertex _ e.sides[net].v; gcPortIndex: NAT _ e.portIndex; IF grandChildAnsss[i][gcPortIndex].sawElse AND NOT grandChildAnsss[i][gcPortIndex].sawBord THEN { any: REF ANY _ netMapper.Fetch[oldGCConnectionss[i][gcPortIndex]].val; IF any # child THEN { AddEdge[child, net]; [] _ netMapper.Store[oldGCConnectionss[i][gcPortIndex], child]}; }; IF NOT (grandChildAnsss[i][gcPortIndex].sawElse OR grandChildAnsss[i][gcPortIndex].sawBords) THEN DeleteVertex[net] ELSE RemoveEdge[e]; ENDLOOP; DeleteVertex[sibs[i]]; ENDLOOP; NoteChange[child.parent]; IF losses>0 THEN RenumberOutsideEdges[child]; [] _ parentTypes.Store[child.parent, chig]; ENDLOOP; [] _ parentTypes.Pairs[CheckPerType]; END; chig: LORA _ LIST[$check, $ignore]; ChildAnses: TYPE = REF ChildAnsesRep; ChildAnsesRep: TYPE = RECORD [SEQUENCE--oldChildIndex-- length: NAT OF ChildAns]; ChildAns: TYPE = RECORD [newPortIndex: NAT]; GrandChildAnsSS: TYPE = REF GrandChildAnsSSeq; GrandChildAnsSSeq: TYPE = RECORD [ SEQUENCE length: CARDINAL OF GrandChildAnsS]; GrandChildAnsS: TYPE = REF GrandChildAnsSeq; GrandChildAnsSeq: TYPE = RECORD [ SEQUENCE--gcPortIndex-- length: PortIndex OF GrandChildAns]; GrandChildAns: TYPE = RECORD [ sawSelves: BoolS, oldChildPortIndex, newChildPortIndex: PortIndex _ NullPortIndex, sawBord, sawBords, sawElse: BOOL _ FALSE]; RaiseGrandchildren: PUBLIC PROC [design: Design, gcsA: REF ANY, newPortNamer: NewPortNamer] RETURNS [newChildrens: VertexSList] = BEGIN gcs: VertexS _ ToVertexS[design, gcsA]; childType: CellType _ gcs[0].parent; oldPorts: PortS _ childType.ports; newPorts: PortS; inside: VertexS--oldChildIndex-- _ NEW [VertexSeq[oldPorts.length]]; oldGCConnectionss: VertexSS--gcPortIndex-- _ NEW [VertexSSeq[gcs.length]]; losses, gains, remains, gcPortIndex, newChildPortIndex: NAT _ 0; childAnses: ChildAnses _ NEW [ChildAnsesRep[oldPorts.length]]; grandChildAnsss: GrandChildAnsSS _ NEW [GrandChildAnsSSeq[gcs.length]]; parentTypes: RefTab.Ref _ RefTab.Create[]; netMapper: RefTab.Ref _ RefTab.Create[]; oldNetToConnections: RefTab.Ref; portNameNotes: SymbolTable _ RedBlackTree.Create[GetNameEntryKey, CompareNameEntries]; portClassNotes: SymbolTable _ RedBlackTree.Create[GetNameEntryKey, CompareNameEntries]; newChildrens _ NIL; FOR p: NAT IN [0 .. inside.length) DO inside[p] _ NIL ENDLOOP; {connectionCount: INT _ 0; FOR i: NAT IN [0 .. gcs.length) DO connectionCount _ connectionCount + gcs[i].type.ports.length; ENDLOOP; oldNetToConnections _ RefTab.Create[connectionCount]; }; FOR i: NAT IN [0 .. gcs.length) DO oldGCConnectionss[i] _ NEW [VertexSeq[gcs[i].type.ports.length]]; grandChildAnsss[i] _ NEW [GrandChildAnsSeq[gcs[i].type.ports.length]]; FOR p: NAT IN [0 .. grandChildAnsss[i].length) DO grandChildAnsss[i][p] _ [] ENDLOOP; IF gcs[i].parent = gcs[i].type THEN ERROR; IF gcs[i].parent # childType THEN ERROR; gcPortIndex _ 0; FOR e: Edge _ gcs[i].firstEdge, e.sides[cell].next WHILE e # NIL DO sawBord, sawBords, sawElse: BOOL _ FALSE; sawSelves: BoolS _ NEW [BoolSeq[gcs.length]]; net: Vertex _ e.sides[net].v; IF e.sides[cell].v # gcs[i] THEN ERROR; oldGCConnectionss[i][gcPortIndex] _ net; FOR f: Edge _ net.firstEdge, f.sides[net].next WHILE f # NIL DO IF f.sides[net].v # net THEN ERROR; IF IsMirror[f.sides[cell].v] THEN { sawBords _ sawBord; sawBord _ TRUE; grandChildAnsss[i][gcPortIndex].oldChildPortIndex _ f.portIndex; IF (inside[f.portIndex] # NIL) AND (inside[f.portIndex] # net) THEN ERROR ELSE inside[f.portIndex] _ net} ELSE {sawSomeSelves: BOOL _ FALSE; FOR j: NAT IN [0 .. gcs.length) DO IF f.sides[cell].v = gcs[j] THEN sawSomeSelves _ sawSelves[j] _ TRUE; ENDLOOP; IF NOT sawSomeSelves THEN sawElse _ TRUE ELSE { selfEdges: EdgeList _ NARROW[oldNetToConnections.Fetch[net].val]; selfEdges _ CONS[f, selfEdges]; [] _ oldNetToConnections.Store[net, selfEdges]; }; }; ENDLOOP; IF NOT sawSelves[i] THEN ERROR; grandChildAnsss[i][gcPortIndex].sawBord _ sawBord; grandChildAnsss[i][gcPortIndex].sawBords _ sawBords; grandChildAnsss[i][gcPortIndex].sawElse _ sawElse; grandChildAnsss[i][gcPortIndex].sawSelves _ sawSelves; IF (net.suspect _ (sawBord AND NOT (sawElse OR sawBords))) THEN losses _ NoteLoss[netMapper, net, losses]; IF sawElse AND NOT sawBord THEN gains _ NoteGain[netMapper, net, gains]; gcPortIndex _ gcPortIndex + 1; ENDLOOP; IF gcPortIndex # gcs[i].type.ports.length THEN ERROR; ENDLOOP; remains _ oldPorts.length - losses; newPorts _ NEW [PortSeq[remains + gains]]; newChildPortIndex _ 0; FOR cpi: NAT IN [0 .. oldPorts.length) DO keep: BOOL _ TRUE; IF inside[cpi] # NIL THEN { keep _ NOT inside[cpi].suspect; inside[cpi].suspect _ FALSE}; childAnses[cpi].newPortIndex _ IF keep THEN newChildPortIndex ELSE NullPortIndex; IF keep THEN { newPorts[newChildPortIndex] _ oldPorts[cpi]; newChildPortIndex _ newChildPortIndex + 1}; ENDLOOP; IF newChildPortIndex # remains THEN ERROR; FOR i: NAT IN [0 .. gcs.length) DO FOR e: Edge _ gcs[i].firstEdge, e.sides[cell].next WHILE e # NIL DO net: Vertex _ e.sides[net].v; gcPortIndex: NAT _ e.portIndex; IF e.sides[cell].v # gcs[i] THEN ERROR; IF grandChildAnsss[i][gcPortIndex].sawElse AND NOT grandChildAnsss[i][gcPortIndex].sawBord THEN { IF oldGCConnectionss[i][gcPortIndex] # net THEN ERROR; SELECT netMapper.Fetch[net].val FROM $AddPorted => NULL; $AddPort => { newPorts[newChildPortIndex] _ [netNames: LIST[PickAName[net.names]]]; [newPorts[newChildPortIndex].names, newPorts[newChildPortIndex].equivClass] _ newPortNamer.NameNewPort[newPortNamer.data, TRUE, childType, newPorts, newChildPortIndex, net, NARROW[oldNetToConnections.Fetch[net].val]]; NoteNaming[portNameNotes, portClassNotes, newPorts, newChildPortIndex, net, NARROW[oldNetToConnections.Fetch[net].val]]; grandChildAnsss[i][gcPortIndex].newChildPortIndex _ newChildPortIndex; AddEdge[childType.mirror, net]; newChildPortIndex _ newChildPortIndex + 1; [] _ netMapper.Store[net, $AddPorted]}; ENDCASE => ERROR; }; ENDLOOP; ENDLOOP; IF newChildPortIndex # newPorts.length THEN ERROR; FixNames[childType, newPorts, remains, newPortNamer, portNameNotes, portClassNotes]; NoteChange[childType]; childType.ports _ newPorts; FOR i: NAT IN [0 .. gcs.length) DO WHILE gcs[i].firstEdge # NIL DO e: Edge _ gcs[i].firstEdge; net: Vertex _ e.sides[net].v; gcPortIndex: NAT _ e.portIndex; IF NOT (grandChildAnsss[i][gcPortIndex].sawElse OR grandChildAnsss[i][gcPortIndex].sawBords) THEN DeleteVertex[net] ELSE RemoveEdge[e]; ENDLOOP; DeleteVertex[gcs[i]]; ENDLOOP; IF losses>0 THEN RenumberInsideEdges[childType]; CheckType[childType, check, ignore, TRUE]; FOR child: Vertex _ childType.firstInstance, child.nextInstance WHILE child # NIL DO sibs: VertexS _ NEW [VertexSeq[gcs.length]]; oldNets: VertexS--oldChildIndex-- _ NEW [VertexSeq[oldPorts.length]]; newNets: VertexS--Gain-- _ NEW [VertexSeq[gains]]; oldChildIndex, newChildIndex: NAT _ 0; nextChildEdge: Edge _ badEdge; IF IsMirror[child] THEN ERROR; --AM2 FOR i: NAT IN [0 .. sibs.length) DO sibs[i] _ NEW [VertexRep _ [names: JoinNames[child.names, gcs[i].names], type: gcs[i].type, parent: child.parent, class: cell]]; AddVertex[sibs[i]]; LinkInstance[sibs[i]]; ENDLOOP; FOR ce: Edge _ child.firstEdge, nextChildEdge WHILE ce # NIL DO nextChildEdge _ ce.sides[cell].next; oldNets[oldChildIndex] _ ce.sides[net].v; IF ce.portIndex # oldChildIndex THEN ERROR; IF (childAnses[oldChildIndex].newPortIndex # NullPortIndex) THEN { IF newChildIndex # childAnses[oldChildIndex].newPortIndex THEN ERROR; newChildIndex _ (ce.portIndex _ newChildIndex) + 1} ELSE RemoveEdge[ce]; oldChildIndex _ oldChildIndex + 1; ENDLOOP; IF newChildIndex # oldPorts.length - losses THEN ERROR; FOR newChildIndex IN [newChildIndex .. newPorts.length) DO innerNet: Vertex _ NARROW[Lookup[child.type.parts, newPorts[newChildIndex].netNames.first]]; outerNet: Vertex _ NEW [VertexRep _ [names: JoinNames[child.names, innerNet.names], parent: child.parent, class: net]]; AddVertex[outerNet]; AddEdge[child, outerNet]; newNets[newChildIndex - remains] _ outerNet; ENDLOOP; FOR i: NAT IN [0 .. gcs.length) DO FOR ci: NAT IN [0 .. gcs[i].type.ports.length) DO MakeDummyNet: PROC [iNet: Vertex] RETURNS [oNet: Vertex] = { oNet _ NARROW[netMapper.Fetch[iNet].val]; IF oNet = NIL OR oNet.parent # child.parent THEN { oNet _ NEW [VertexRep _ [names: JoinNames[child.names, iNet.names], parent: child.parent, class: net]]; AddVertex[oNet]; [] _ netMapper.Store[iNet, oNet]; }; }; AddEdge[ sibs[i], IF grandChildAnsss[i][ci].sawBord THEN oldNets[grandChildAnsss[i][ci].oldChildPortIndex] ELSE IF grandChildAnsss[i][ci].sawElse THEN newNets[grandChildAnsss[i][ci].newChildPortIndex - remains] ELSE MakeDummyNet[oldGCConnectionss[i][ci]]]; ENDLOOP; ENDLOOP; NoteChange[child.parent]; [] _ parentTypes.Store[child.parent, chig]; newChildrens _ CONS[sibs, newChildrens]; ENDLOOP; [] _ parentTypes.Pairs[CheckPerType]; END; NoteLoss: PROC [netMapper: RefTab.Ref, net: Vertex, oldLosses: CARDINAL] RETURNS [newLosses: CARDINAL] = { m: REF ANY _ netMapper.Fetch[net].val; newLosses _ oldLosses; SELECT m FROM NIL => {newLosses _ newLosses + 1; [] _ netMapper.Store[net, $DePort]}; $DePort => NULL; ENDCASE => ERROR; }; NoteGain: PROC [netMapper: RefTab.Ref, net: Vertex, oldGains: CARDINAL] RETURNS [newGains: CARDINAL] = { m: REF ANY _ netMapper.Fetch[net].val; newGains _ oldGains; SELECT m FROM NIL => {newGains _ newGains + 1; [] _ netMapper.Store[net, $AddPort]}; $AddPort => NULL; ENDCASE => ERROR; }; NameEntry: TYPE = REF NameEntryRep; NameEntryRep: TYPE = RECORD [name: ROPE, sources: PortNameSourceList]; PortNameSourceList: TYPE = LIST OF PortNameSource; PortNameSource: TYPE = RECORD [ index: NAT, oldNet: Vertex, oldConnections: EdgeList]; GetNameEntryKey: PROC [data: REF ANY] RETURNS [key: ROPE] --RedBlackTree.GetKey-- = { ne: NameEntry _ NARROW[data]; key _ ne.name}; CompareNameEntries: PROC [k, data: REF ANY] RETURNS [c: Basics.Comparison] --RedBlackTree.Compare-- = { k1: ROPE _ NARROW[k]; k2: ROPE _ GetNameEntryKey[data]; c _ k1.Compare[k2]; }; NoteNaming: PROC [portNameNotes, portClassNotes: SymbolTable, ports: PortS, index: NAT, oldNet: Vertex, oldConnections: EdgeList] = { DoName: PROC [name: ROPE, st: SymbolTable] = { ne: NameEntry _ NARROW[st.Lookup[name]]; IF ne = NIL THEN st.Insert[ne _ NEW [NameEntryRep _ [name, NIL]], name]; ne.sources _ CONS[[index, oldNet, oldConnections], ne.sources]; }; DoList: PROC [rl: RopeList] = { FOR rl _ rl, rl.rest WHILE rl # NIL DO DoName[rl.first, portNameNotes] ENDLOOP; }; DoList[ports[index].names.designed]; DoList[ports[index].names.unknown]; DoList[ports[index].names.progged]; DoName[ports[index].equivClass, portClassNotes]; }; NameStuffs: TYPE = REF NameStuffSeq; NameStuffSeq: TYPE = RECORD [stuffs: SEQUENCE length: CARDINAL OF NameStuff]; NameStuff: TYPE = RECORD [ collided: BOOL _ FALSE, oldNet: Vertex _ NIL, oldConnections: EdgeList _ NIL]; FixNames: PROC [cellType: CellType, ports: PortS, firstIndex: NAT, newPortNamer: NewPortNamer, portNameNotes, portClassNotes: SymbolTable] = { indices: NAT _ ports.length - firstIndex; ns: NameStuffs _ NEW [NameStuffSeq[indices]]; first: BOOL _ TRUE; DO st: SymbolTable; someCollided: BOOL _ FALSE; PerName: PROC [ra: REF ANY] RETURNS [stop: BOOL] = { ne: NameEntry _ NARROW[ra]; IF ne.sources.rest # NIL THEN { IF st.Delete[ne].data # ne THEN ERROR; FOR pnsl: PortNameSourceList _ ne.sources, pnsl.rest WHILE pnsl # NIL DO di: NAT _ pnsl.first.index - firstIndex; IF ns[di].collided AND (ns[di].oldNet # pnsl.first.oldNet OR ns[di].oldConnections # pnsl.first.oldConnections) THEN ERROR; ns[di] _ [TRUE, pnsl.first.oldNet, pnsl.first.oldConnections]; someCollided _ TRUE; ENDLOOP; }; }; FOR di: NAT IN [0 .. indices) DO ns[di].collided _ FALSE ENDLOOP; RedBlackTreeExtras.StatelessEnumerateIncreasing[(st _ portNameNotes), PerName, GetNameEntryKey]; RedBlackTreeExtras.StatelessEnumerateIncreasing[(st _ portClassNotes), PerName, GetNameEntryKey]; IF NOT someCollided THEN RETURN; IF NOT first THEN ERROR; FOR di: NAT IN [0 .. indices) DO IF ns[di].collided THEN { newNames: Names; newEquivClass: EquivClass; [newNames, newEquivClass] _ newPortNamer.NameNewPort[data: newPortNamer.data, first: FALSE, ct: cellType, ports: ports, portIndex: firstIndex+di, oldNet: ns[di].oldNet, oldConnections: ns[di].oldConnections]; NoteNaming[portNameNotes, portClassNotes, ports, firstIndex+di, ns[di].oldNet, ns[di].oldConnections]; }; ENDLOOP; first _ FALSE; ENDLOOP; }; RenumberInsideEdges: PROC [ct: CellType] = { portIndex: NAT _ 0; FOR e: Edge _ ct.mirror.firstEdge, e.sides[cell].next WHILE e # NIL DO IF e.sides[cell].v # ct.mirror THEN ERROR; IF e.portIndex < portIndex THEN ERROR; e.portIndex _ portIndex; portIndex _ portIndex + 1; ENDLOOP; }; RenumberOutsideEdges: PROC [v: Vertex] = { portIndex: NAT _ 0; FOR e: Edge _ v.firstEdge, e.sides[cell].next WHILE e # NIL DO IF e.sides[cell].v # v THEN ERROR; IF e.portIndex < portIndex THEN ERROR; e.portIndex _ portIndex; portIndex _ portIndex + 1; ENDLOOP; }; END. €LichenChildishTransforms.Mesa Last Edited by: Spreitzer, July 15, 1985 7:34:50 pm PDT Estimate number of connected nets: ΚΡ˜J™J™7J˜IcodešΟk œœœ†˜«K˜šΠbxœœ˜'KšœœT˜^Kšœ˜K˜KšœœK˜UK˜Kšœ œœœ˜K˜šΟn œœœœœ%Οcœœ'˜ΕKš˜Kšœ&˜&Kšœ1˜1Kšœœ˜Kšœœœ˜Kšœ!˜!Kšœœœ˜K˜"Kšœœ"˜>Kšœ+œ˜3Kšœ œ˜+K˜ šŸœœ#˜/šœœ˜Kšœœ˜Kšœœ"˜7Kšœœ˜2Kšœ œ˜)šœœœ˜#Kšœ˜Kšœ<˜Kšœ#œ!˜GK˜*K˜(Kšœ ˜ KšœV˜VKšœW˜WKšœœ˜Kš œœœœ œœ˜>™"Kšœœ˜šœœœ˜"Kšœ=˜=Kšœ˜—Kšœ5˜5K˜—šœœœ˜"Kšœœ'˜AKšœœ.˜FKš œœœ"œœ˜UKšœœœ˜*Kšœœœ˜(Kšœ˜šœ0œœ˜CKšœœœ˜)Kšœœ˜-K˜Kšœœœ˜'Kšœ(˜(šœ,œœ˜?Kšœœœ˜#šœœ˜#Kšœ˜Kšœ œ˜Kšœ@˜@Kš œœœœœœ˜i—šœœœ˜"šœœœ˜"Kšœœ œ˜EKšœ˜—Kšœœœ ˜(šœ˜Kšœœ%˜AKšœ œ˜Kšœ/˜/K˜—K˜—Kšœ˜—Kšœœœœ˜Kšœ2˜2Kšœ4˜4Kšœ2˜2Kšœ6˜6Kš œœœ œ œ+˜jKšœ œœ œ)˜HKšœ˜Kšœ˜—Kšœ(œœ˜5Kšœ˜—K˜#Kšœ œ˜*Kšœ˜šœœœ˜)Kšœœœ˜šœœœ˜Kšœœ˜Kšœœ˜—Kšœœœœ˜Qšœœ˜Kšœ,˜,Kšœ+˜+—Kšœ˜—Kšœœœ˜*šœœœ˜"šœ0œœ˜CK˜Kšœ œ˜Kšœœœ˜'šœ)œœ)œ˜aKšœ)œœ˜6šœ˜$Kšœœ˜šœ ˜ Kšœ)œ˜EKšœzœ/œ&˜ΩKšœLœ&˜xKšœF˜FK˜Kšœ*˜*Kšœ'˜'—Kšœœ˜—K˜—Kšœ˜—Kšœ˜—Kšœ%œœ˜2KšœT˜TK˜K˜šœœœ˜"šœœ˜Kšœ˜K˜Kšœ œ˜Kš œœ*œ+œœ˜‡Kšœ˜—K˜Kšœ˜—Kšœ œ ˜0Kšœ$œ˜*šœ=œ œ˜TKšœœ˜,Kšœ œœ˜EKšœ œœ˜2Kšœœ˜&K˜Kšœœœ ˜$šœœœ˜#Kšœ œs˜€Kšœ˜K˜Kšœ˜—šœ+œœ˜?Kšœ$˜$Kšœ)˜)Kšœœœ˜+šœ9˜;šœ˜Kšœ8œœ˜EKšœ3˜3—Kšœ˜—Kšœ"˜"Kšœ˜—Kšœ*œœ˜7šœœ$˜:KšœœC˜\Kšœœa˜wKšœ˜Kšœ˜Kšœ,˜,Kšœ˜—šœœœ˜"šœœœ!˜1šŸ œœœ˜Kšœœ˜Kšœ˜—K˜—K˜—Kš œœœœœœ˜AKšœ`˜`Kšœa˜aKšœœœœ˜ Kšœœœœ˜šœœœ˜ šœœ˜K˜K˜KšœUœv˜ΠKšœf˜fK˜—Kšœ˜—Kšœœ˜Kšœ˜—Kšœ˜—K˜šŸœœ˜,Kšœ œ˜šœ3œœ˜FKšœœœ˜*Kšœœœ˜&K˜K˜Kšœ˜—Kšœ˜—K˜šŸœœ˜*Kšœ œ˜šœ+œœ˜>Kšœœœ˜"Kšœœœ˜&K˜K˜Kšœ˜—Kšœ˜—K˜Kšœ˜——…—UΚn