DIRECTORY Basics, DFUtilities, FS, IO, LichenDataStructure, LichenOps, LichenTransforms, LichenTransformsPrivate, List, RedBlackTree, RefTab, Rope, ViewerIO; LichenPrimitiveTransforms: CEDAR PROGRAM IMPORTS IO, LichenDataStructure, LichenOps, LichenTransforms, LichenTransformsPrivate, List, RedBlackTree, RefTab, Rope EXPORTS LichenOps, LichenTransforms, LichenTransformsPrivate = BEGIN OPEN LichenDataStructure, LichenTransforms, LichenOps, LichenTransformsPrivate; --Not YET implemented-- nyet: PUBLIC ERROR = CODE; Error: PUBLIC ERROR [format: ROPE, v1, v2, v3, v4, v5: IO.Value _ [null[]]] = CODE; Differentiate: PUBLIC PROC [design: Design, newNames: Names, instances: REF ANY] RETURNS [newCT: CellType] = BEGIN oldCT: CellType _ NIL; vl: LORA _ NIL; ConsumeInstance: PROC [v: Vertex] = { SELECT v.class FROM cell => NULL; net => Err[[], "%g is a net, not a cell", IO.rope[GlobalVertexName[v]]]; ENDCASE => ERROR; IF oldCT = NIL THEN oldCT _ v.type ELSE IF oldCT # v.type THEN Err[[], "%g of type %g, not %g", IO.rope[PickAName[v.names]], IO.rope[PickAName[v.type.names]], IO.rope[PickAName[oldCT.names]]]; vl _ CONS[v, vl]}; EnumerateVertices[design, instances, ConsumeInstance]; newCT _ NEW [CellTypeRep _ [design: design, names: newNames, file: NIL, publicKnown: TRUE, privateKnown: TRUE, ports: CopyPorts[oldCT.ports], parts: NIL]]; CopyParts[newCT, oldCT]; FOR vl _ vl, vl.rest WHILE vl # NIL DO ChangeType[v: NARROW[vl.first], from: oldCT, to: newCT]; ENDLOOP; END; Undifferentiate: PUBLIC PROC [design: Design, toTypeA, fromTypes: REF ANY] RETURNS [changed: VertexList] = BEGIN toType: CellType _ ToType[design, toTypeA]; oldTypes: LIST OF CellType _ NIL; oldCount: NAT _ 0; ConsumeType: PROC [ct: CellType] = { oldTypes _ CONS[ct, oldTypes]; oldCount _ oldCount + 1}; EnumerateCellTypes[design, fromTypes, ConsumeType]; FOR oldTypes _ oldTypes, oldTypes.rest WHILE oldTypes # NIL DO WHILE oldTypes.first.firstInstance # NIL DO v: Vertex _ oldTypes.first.firstInstance; IF IsMirror[v] THEN ERROR; --AM2 ChangeType[v: v, from: oldTypes.first, to: toType]; changed _ CONS[v, changed]; ENDLOOP; DeleteType[design, oldTypes.first]; ENDLOOP; END; NewEmptyCellType: PUBLIC PROC [design: Design, names: Names] RETURNS [cellType: CellType] = BEGIN cellType _ NEW [CellTypeRep _ [ design: design, names: names, file: NIL, publicKnown: TRUE, privateKnown: TRUE, ports: NEW [PortSeq[0]], parts: RedBlackTree.Create[GetAliasKey, CompareAliases], mirror: NIL]]; AddWorld[cellType]; Insert[design.cellTypesByName, names, cellType]; design.cellTypesByAddress.Insert[cellType, cellType]; END; CreateEmpty: PUBLIC PROC [design: Design, childNames: Names, childType, parentType: CellType] RETURNS [child: Vertex] = BEGIN child _ NEW [VertexRep _ [names: childNames, type: childType, parent: parentType, class: cell]]; IF NOT IsEmpty[childType] THEN Err[[], "Asked to create empty child %g of non-empty type %g in %g", IO.refAny[PickAName[childNames]], IO.refAny[PickAName[childType.names]], IO.refAny[PickAName[parentType.names]]]; LinkInstance[child]; AddVertex[child]; NoteChange[child.parent]; END; DeleteEmpty: PUBLIC PROC [design: Design, child: Vertex] RETURNS [parentType: CellType] = BEGIN parentType _ child.parent; IF NOT IsEmpty[child.type] THEN Err[[], "Child %g in %g is of a non-empty type (%g)", IO.rope[PickAName[child.names]], IO.rope[PickAName[child.parent.names]], IO.rope[PickAName[child.type.names]]]; IF (child.firstEdge # NIL) # (child.lastEdge # NIL) THEN ERROR; IF child.firstEdge # NIL THEN ERROR; NoteChange[child.parent]; DeleteVertex[child]; END; RenameVertices: PUBLIC PROC [design: Design, parentA, vertices: REF ANY, renamer: Renamer] = { parentType: CellType _ ToType[design, parentA]; changed: BOOL _ FALSE; PerVertex: PROC [v: Vertex] = { newNames: Names _ renamer.Rename[renamer.data, v.names, implicitClass].newNames; IF v.parent # parentType THEN ERROR; IF newNames # v.names THEN { changed _ TRUE; Delete[v.parent.parts, v.names, v]; v.names _ newNames; Insert[v.parent.parts, v.names, v]; }; }; EnumerateVertices[parentType, vertices, PerVertex]; IF changed THEN NoteChange[parentType]; }; RenamePorts: PUBLIC PROC [design: Design, typeA: REF ANY, renamer: Renamer] = { parentType: CellType _ ToType[design, typeA]; changed: BOOL _ FALSE; FOR portIndex: PortIndex IN [0 .. parentType.ports.length) DO newNames: Names; newEquiv: EquivClass; [newNames, newEquiv] _ renamer.Rename[renamer.data, parentType.ports[portIndex].names, parentType.ports[portIndex].equivClass]; IF newNames # parentType.ports[portIndex].names OR newEquiv # parentType.ports[portIndex].equivClass THEN { changed _ TRUE; parentType.ports[portIndex].names _ newNames; parentType.ports[portIndex].equivClass _ newEquiv}; ENDLOOP; IF changed THEN NoteChange[parentType]; }; RenameCellType: PUBLIC PROC [design: Design, typeA: REF ANY, renamer: Renamer] = { ct: CellType _ ToType[design, typeA]; newNames: Names; newEquiv: EquivClass; [newNames, newEquiv] _ renamer.Rename[renamer.data, ct.names, ct.equivClass]; IF newNames # ct.names OR newEquiv # ct.equivClass THEN { NoteChange[ct]; Delete[design.cellTypesByName, ct.names, ct]; ct.names _ newNames; ct.equivClass _ newEquiv; Insert[design.cellTypesByName, ct.names, ct]; }; }; RenameTypes: PUBLIC PROC [design: Design, typesA: REF ANY, renamer: Renamer] = { PerType: PROC [ct: CellType] = { newNames: Names; newEquiv: EquivClass; [newNames, newEquiv] _ renamer.Rename[renamer.data, ct.names, ct.equivClass]; IF newNames # ct.names OR newEquiv # ct.equivClass THEN { NoteChange[ct]; Delete[design.cellTypesByName, ct.names, ct]; ct.names _ newNames; ct.equivClass _ newEquiv; Insert[design.cellTypesByName, ct.names, ct]; }; }; EnumerateCellTypes[design, typesA, PerType]; }; RenameAll: PUBLIC PROC [design: Design, renamer: Renamer] = { FOR ct: CellType _ FirstCellType[design], NextCellType[ct] WHILE ct # NIL DO EnsureParts[ct]; RenameCellType[design, ct, renamer]; RenamePorts[design, ct, renamer]; IF ExpansionKnown[ct] THEN RenameVertices[design, ct, all, renamer]; ENDLOOP; }; ToNamesS: PUBLIC PROC [ra: REF ANY] RETURNS [ns: NamesS] = { WITH ra SELECT FROM x: NamesS => ns _ x; x: NamesList => ns _ NamesListToSeq[x]; ENDCASE => ERROR}; NamesListToSeq: PUBLIC PROC [l: NamesList] RETURNS [s: NamesS] = { size: CARDINAL _ 0; FOR m: NamesList _ l, m.rest WHILE m # NIL DO size _ size+1 ENDLOOP; s _ NEW [NamesSeq[size]]; FOR i: NAT IN [0 .. s.length) DO s[i] _ l.first; l _ l.rest; ENDLOOP; }; ListNames: PUBLIC PROC [vertexs: VertexS] RETURNS [nl: NamesList] = { tail: NamesList _ nl _ NIL; FOR i: NAT IN [0 .. vertexs.length) DO last: NamesList _ LIST[vertexs[i].names]; IF tail = NIL THEN nl _ last ELSE tail.rest _ last; tail _ last; ENDLOOP; }; ToType: PUBLIC PROC [design: Design, ra: REF ANY] RETURNS [type: CellType] = { WITH ra SELECT FROM r: ROPE => type _ NARROW[Lookup[design.cellTypesByName, r]]; ct: CellType => type _ ct; ENDCASE => ERROR}; ToRope: PUBLIC PROC [ra: REF ANY] RETURNS [rope: ROPE] = {rope _ NARROW[ra]}; ToVertex: PUBLIC PROC [context, ra: REF ANY] RETURNS [v: Vertex] = { WITH ra SELECT FROM vertex: Vertex => v _ vertex; rope: ROPE => { ct: CellType _ NARROW[context]; EnsureParts[ct]; v _ NARROW[Lookup[ct.parts, rope]]}; lora: LORA => { design: Design _ NARROW[context]; ct: CellType _ ToType[design, lora.first]; name: ROPE _ NARROW[lora.rest.first]; EnsureParts[ct]; v _ NARROW[Lookup[ct.parts, name]]}; ENDCASE => ERROR}; ToVertexS: PUBLIC PROC [context, ra: REF ANY] RETURNS [vs: VertexS] = { WITH ra SELECT FROM s: VertexS => vs _ s; lora: LORA => { vs _ NEW [VertexSeq[List.Length[lora]]]; FOR i: NAT IN [0 .. vs.length) DO vs[i] _ ToVertex[context, lora.first]; lora _ lora.rest; ENDLOOP; IF lora # NIL THEN ERROR}; bag: Bag => { vl: VertexList _ NIL; count: INT _ 0; PerElement: PROC [e: REF ANY] = { v: Vertex _ NARROW[e]; vl _ CONS[v, vl]; count _ count +1}; bag.Enumerate[context: context, data: bag.data, to: PerElement]; vs _ NEW [VertexSeq[count]]; FOR vl _ vl, vl.rest WHILE vl # NIL DO count _ count - 1; vs[count] _ vl.first; ENDLOOP; IF count # 0 THEN ERROR; }; ENDCASE => ERROR}; VVSMapFromTIIlNames: PUBLIC PROC [design: Design, l: TIIlNamesList] RETURNS [m: Mapper] = { rtm: RefTabMapper _ NEW [RefTabMapperRep _ [NIL, RefTab.Create[]]]; rtm.asMapper _ m _ NEW [MapperRep _ [RefTabMap, rtm]]; FOR tiill: TIIlNamesList _ l, tiill.rest WHILE tiill # NIL DO tiiln: TIIlNames _ tiill.first; ct: CellType _ NARROW[Lookup[design.cellTypesByName, tiiln.typeName]]; v1: Vertex _ NARROW[Lookup[ct.parts, tiiln.v1Name]]; v2s: VertexS _ ToVertexS[ct, tiiln.v2Names]; [] _ rtm.refTab.Store[v1, v2s]; ENDLOOP; }; RefTabMapper: TYPE = REF RefTabMapperRep; RefTabMapperRep: TYPE = RECORD [ asMapper: Mapper, refTab: RefTab.Ref ]; RefTabMap: PROC [data, domain: REF ANY] RETURNS [range: REF ANY] = { rtm: RefTabMapper _ NARROW[data]; range _ rtm.refTab.Fetch[domain].val}; OneMap: PUBLIC PROC [from, to: REF ANY] RETURNS [mapper: Mapper] = { om: OneMapper _ NEW [OneMapperRep _ [from, to]]; mapper _ NEW [MapperRep _ [MapOne, om]]}; OneMapper: TYPE = REF OneMapperRep; OneMapperRep: TYPE = RECORD [from, to: REF ANY]; MapOne: PROC [data, domain: REF ANY] RETURNS [range: REF ANY] = { om: OneMapper _ NARROW[data]; range _ IF domain = om.from THEN om.to ELSE NIL}; GenName: PROC RETURNS [name: ROPE] = {name _ IO.PutFR[" gen%g", IO.card[genCount _ genCount + 1]]}; genCount: NAT _ 0; JoinNames: PUBLIC PROC [parent, child: Names, dot: BOOL _ TRUE] RETURNS [joined: Names] = {joined _ [progged: LIST[PickAName[parent].Cat[IF dot THEN "." ELSE NIL, PickAName[child]]]]}; QualifyEquivClass: PUBLIC PROC [qual: Names, equivClass: EquivClass, dot: BOOL _ TRUE] RETURNS [quald: EquivClass] = {quald _ IF equivClass # implicitClass THEN PickAName[qual].Cat[IF dot THEN "." ELSE NIL, equivClass] ELSE implicitClass}; IsEmpty: PROC [type: CellType] RETURNS [isEmpty: BOOL] = { EnsureParts[type]; EnsurePorts[type]; isEmpty _ type.ports.length = 0 AND type.cellCount = 0}; CopyPorts: PROC [p: PortS] RETURNS [q: PortS] = { q _ NEW [PortSeq[p.length]]; FOR pi: NAT IN [0 .. q.length) DO q[pi] _ p[pi] ENDLOOP; }; CopyParts: PROC [newCT, oldCT: CellType] = { oldParts: SymbolTable _ oldCT.parts; newParts: SymbolTable; Copy: PROC [ra: REF ANY] RETURNS [stop: BOOL] = { oldV: Vertex _ NARROW[AntiAlias[ra]]; newV: Vertex; stop _ FALSE; newV _ CopyWork[oldV]}; CopyWork: PROC [oldV: Vertex] RETURNS [newV: Vertex] = { newV _ NARROW[Lookup[newParts, PickAName[oldV.names]]]; IF newV # NIL THEN RETURN; newV _ NEW [VertexRep _ [names: oldV.names, type: oldV.type, parent: newCT, class: oldV.class]]; AddVertex[newV]; IF newV.class = net THEN RETURN; LinkInstance[newV]; FOR oldE: Edge _ oldV.firstEdge, oldE.sides[cell].next WHILE oldE # NIL DO newNet: Vertex _ CopyWork[oldE.sides[net].v]; IF oldE.sides[cell].v # oldV THEN ERROR; AddEdge[newV, newNet]; ENDLOOP; }; IF oldCT.parts = NIL OR newCT.parts # NIL THEN ERROR; IF newCT.mirror # NIL THEN ERROR; newCT.parts _ newParts _ RedBlackTree.Create[GetAliasKey, CompareAliases]; oldParts.EnumerateIncreasing[Copy]; AddWorld[newCT]; }; DeleteType: PROC [design: Design, type: CellType] = { IF (type.firstInstance = NIL) # (type.lastInstance = NIL) THEN ERROR; IF (type.firstInstance # NIL) OR (type.lastInstance # NIL) THEN ERROR; --AM2 Delete[design.cellTypesByName, type.names, type]; IF design.cellTypesByAddress.Delete[type].data # type THEN ERROR; }; ChangeType: PROC [v: Vertex, from, to: CellType] = { IF v.type # from THEN ERROR; NoteChange[v.parent]; UnlinkInstance[v]; v.type _ to; LinkInstance[v]}; AddEdge: PUBLIC PROC [cv, nv: Vertex] = { pi: NAT = IF cv.lastEdge # NIL THEN cv.lastEdge.portIndex+1 ELSE 0; e: Edge _ NEW [EdgeRep _ [sides: [cell: [v: cv, next: NIL, prev: cv.lastEdge], net: [v: nv, next: NIL, prev: nv.lastEdge]], color: noColor, portIndex: pi]]; IF cv.class # cell OR nv.class # net THEN ERROR; IF e.sides[cell].prev # NIL THEN e.sides[cell].prev.sides[cell].next _ e ELSE cv.firstEdge _ e; IF e.sides[net].prev # NIL THEN e.sides[net].prev.sides[net].next _ e ELSE nv.firstEdge _ e; cv.lastEdge _ nv.lastEdge _ e; }; END. ~LichenPrimitiveTransforms.Mesa Last Edited by: Spreitzer, July 11, 1985 9:37:49 pm PDT VVMapFromTIINames: PROC [design: Design, l: TIINamesList] RETURNS [m: Mapper] = { rtm: RefTabMapper _ NEW [RefTabMapperRep _ [NIL, RefTab.Create[]]]; rtm.asMapper _ m _ NEW [MapperRep _ [RefTabMap, rtm]]; FOR tiil: TIINamesList _ l, tiil.rest WHILE tiil # NIL DO tiin: TIINames _ tiil.first; ct: CellType _ NARROW[Lookup[design.cellTypesByName, tiin.typeName]]; v1: Vertex _ NARROW[Lookup[ct.parts, tiin.v1Name]]; v2: Vertex _ NARROW[Lookup[ct.parts, tiin.v2Name]]; [] _ rtm.refTab.Store[v1, v2]; ENDLOOP; }; AM1 says this can't be the mirror. ΚG– "cedar" style˜Icode™J™7K˜KšΟk œœœx˜K˜šΠbxœœ˜(Kšœœm˜wKšœ7˜>K˜KšœœK˜UK˜KšΟcœœœœ˜2K˜Kš œœœ œœœ˜SK˜š Οn œœœ.œœœ˜lKš˜Kšœœ˜Kšœœœ˜š œœ˜%šœ ˜Kšœœ˜ Kšœ*œ˜HKšœœ˜—Kšœ œœœœœ"œœ œ˜ΐKšœœ ˜—Kšœ6˜6Kš œœ8œœœ(œ˜›Kšœ˜šœœœ˜&Kšœœ$˜8Kšœ˜—Kšœ˜—K˜š  œœœ&œœœ˜jKš˜Kšœ+˜+Kšœ œœ œ˜!Kšœ œ˜š  œœ˜$Kšœ œ˜Kšœ˜—Kšœ3˜3šœ$œ œ˜>šœ œ˜+K˜)Kšœ œœŸ˜ Kšœ3˜3Kšœ œ ˜Kšœ˜—K˜#Kšœ˜—Kšœ˜—K˜š œœœ œ˜[Kš˜šœ œ˜K˜K˜ Kšœœ˜ Kšœ œ˜Kšœœ˜Kšœœ˜Kšœ8˜8Kšœœ˜—K˜K˜0K˜5Kšœ˜—K˜š  œœœFœ˜wKš˜KšœœU˜`Kš œœœFœ œ%œ&˜ΥK˜K˜K˜Kšœ˜—K˜š  œœœ!œ˜YKš˜K˜Kš œœœ7œœ&œ$˜ΕKš œœœœœ˜?Kšœœœœ˜$K˜K˜Kšœ˜—K˜š  œœœ%œœ˜^K˜/Kšœ œœ˜š  œœ˜KšœP˜PKšœœœ˜$šœœ˜Kšœ œ˜K˜#Kšœ˜K˜#Kšœ˜—K˜—K˜3Kšœ œ˜'K˜—K˜š   œœœœœ˜OKšœ-˜-Kšœ œœ˜šœœ ˜=Kšœ˜Kšœ˜Kšœ˜šœ.œ3œ˜kKšœ œ˜Kšœ-˜-Kšœ3˜3—Kšœ˜—Kšœ œ˜'K˜—K˜š  œœœœœ˜RK˜%Kšœ˜Kšœ˜KšœM˜Mšœœœ˜9Kšœ˜K˜-Kšœ˜Kšœ˜K˜-Kšœ˜—K˜—K˜š   œœœœœ˜Pš œœ˜ Kšœ˜Kšœ˜KšœM˜Mšœœœ˜9Kšœ˜K˜-Kšœ˜Kšœ˜K˜-Kšœ˜—K˜—Kšœ,˜,K˜—K˜š  œœœ'˜=šœ8œœ˜LK˜K˜$K˜!Kšœœ*˜DKšœ˜—K˜—K˜š  œœœœœœ˜<šœœ˜K˜Kšœ'˜'Kšœœ˜——K˜š œœœœ˜BKšœœ˜Kš œœœœœ˜DKšœœ˜šœœœ˜ K˜K˜ Kšœ˜—K˜—K˜š  œœœœ˜EKšœœ˜šœœœ˜&Kšœœ˜)Kšœœœ œ˜3K˜ Kšœ˜—K˜—K˜š  œœœœœœ˜Nšœœ˜Kšœœ œ$˜Kšœ œ˜—K˜š   œœœœœœ˜YKš œœœœœœ˜^—K˜š  œœœ,œœœ˜tKšœ œœœœœœœ˜z—K˜š œœœ œ˜:K˜K˜Kšœ œ˜8—K˜š  œœ œ˜1Kšœœ˜Kš œœœœœ˜8K˜—K˜š  œœ˜,Kšœ$˜$Kšœ˜š  œœœœœœ˜1šœœ˜%K™"—K˜ Kšœœ˜ Kšœ˜—š œœœ˜8Kšœœ*˜7Kšœœœœ˜KšœœV˜`K˜Kšœœœ˜ K˜šœ4œœ˜JK˜-Kšœœœ˜(K˜Kšœ˜—K˜—Kš œœœœœœ˜5Kšœœœœ˜!KšœJ˜JKšœ#˜#Kšœ˜K˜—K˜š  œœ%˜5Kš œœœœœ˜EKš œœœœœœŸ˜LKšœ1˜1Kšœ4œœ˜AKšœ˜—K˜š  œœ$˜4Kšœœœ˜K˜Kšœ˜Kšœ ˜ Kšœ˜—K˜š œœœ˜)Kš œœœœœœ˜CKšœ œ)œ)œ7˜œKšœœœœ˜0Kšœœœ)œ˜_Kšœœœ'œ˜\K˜K˜—K˜Kšœ˜——…—/bA'