DIRECTORY CD, CDBasics, Core, CoreClasses, CoreCreate, CoreOps, CoreProperties, CoreGeometry, GList, PrincOps, PW, PWCore, RefTab, Sinix, Sisyph, TilingClass; TilingClassImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CoreClasses, CoreCreate, CoreOps, CoreProperties, CoreGeometry, GList, PW, PWCore, RefTab, Sisyph EXPORTS TilingClass ~ BEGIN OPEN TilingClass; PubActs: TYPE = REF PubActsRec; PubActsRec: TYPE = RECORD [pubActs: SEQUENCE size: NAT OF RECORD [pub, act: Wire]]; PutTilePubActs: PROC [tile: Tile, pubs, acts: Wires] = { size: NAT _ GList.Length[pubs]; seq: PubActs _ NEW [PubActsRec[size]]; IF size#GList.Length[acts] THEN ERROR; FOR i: NAT IN [0 .. size) DO seq[i] _ [pub: pubs.first, act: acts.first]; pubs _ pubs.rest; acts _ acts.rest; ENDLOOP; tile.properties _ CoreProperties.PutProp[tile.properties, $TilingClassPubActs, seq]; }; GetTilePubActs: PROC [tile: Tile] RETURNS [seq: PubActs] = { seq _ NARROW [CoreProperties.GetProp[tile.properties, $TilingClassPubActs]]; }; PutTileInstance: PROC [tile: Tile, instance: CoreClasses.CellInstance] = { tile.properties _ CoreProperties.PutProp[tile.properties, $TilingClassInstance, instance]; }; GetTileInstance: PROC [tile: Tile] RETURNS [instance: CoreClasses.CellInstance] = { RETURN [NARROW [CoreProperties.GetProp[tile.properties, $TilingClassInstance]]]; }; Replace: PROC [fused: RefTab.Ref, old: Wire] RETURNS [new: Wire] = { new _ RootWire[fused, old]; FOR i: NAT IN [0 .. old.size) DO new[i] _ Replace[fused, old[i]] ENDLOOP; }; RootWire: PROC [fused: RefTab.Ref, wire: Wire] RETURNS [root: Wire] = { up: Wire; root _ wire; DO up _ NARROW [RefTab.Fetch[fused, root].val]; IF up=root THEN ERROR; IF up=NIL THEN EXIT; root _ up; ENDLOOP; [] _ RefTab.Replace[fused, wire, root]; }; Fuse: PROC [fused: RefTab.Ref, wire1, wire2: Wire] = { root1: Wire = RootWire[fused, wire1]; root2: Wire = RootWire[fused, wire2]; IF root1=root2 THEN RETURN; IF root1.size#root2.size THEN ERROR; [] _ RefTab.Store[fused, root1, root2]; FOR i: NAT IN [0 .. root1.size) DO Fuse[fused, root1[i], root2[i]] ENDLOOP; }; FuseNeighbors: PROC [neighbor: NeighborProc, tile1, tile2: Tile, fused: RefTab.Ref] = { ct1: CellType = tile1.type; ct2: CellType = tile2.type; FOR list: LIST OF CoreGeometry.WirePair _ neighbor[ct1, ct2], list.rest WHILE list#NIL DO Fuse[fused, CoreClasses.CorrespondingActual[GetTileInstance[tile1], list.first.wire1], CoreClasses.CorrespondingActual[GetTileInstance[tile2], list.first.wire2]]; ENDLOOP; }; CreateActual: PROC [subPublicToActual: RefTab.Ref, public: WireSeq] RETURNS [actual: WireSeq] = { actual _ NARROW [RefTab.Fetch[subPublicToActual, public].val]; IF actual#NIL THEN RETURN; actual _ CoreOps.CreateWires[size: public.size]; [] _ RefTab.Store[subPublicToActual, public, actual]; FOR i: NAT IN [0 .. public.size) DO actual[i] _ CreateActual[subPublicToActual, public[i]]; ENDLOOP; }; CreateInstance: PROC [public: WireSeq, tile: Tile, xindex, yindex: NAT] RETURNS [instance: CoreClasses.CellInstance]= { subPublicToActual: RefTab.Ref = RefTab.Create[]; actual: WireSeq = CoreOps.CreateWires[size: tile.type.public.size]; FOR list: LIST OF PA _ tile.renaming, list.rest WHILE list#NIL DO pub: Wire = CoreCreate.FindWire[tile.type.public, list.first.public]; act: Wire = CoreCreate.FindWire[public, list.first.actual]; IF pub=NIL OR act=NIL THEN ERROR; -- bad renaming list [] _ RefTab.Store[subPublicToActual, pub, act]; ENDLOOP; FOR i: NAT IN [0 .. tile.type.public.size) DO actual[i] _ CreateActual[subPublicToActual, tile.type.public[i]]; ENDLOOP; instance _ CoreClasses.CreateInstance[actual: actual, type: tile.type, props: CoreProperties.Props[[$TilingXIndex, NEW [NAT _ xindex]], [$TilingYIndex, NEW [NAT _ yindex]]]]; }; tilingClass: PUBLIC Core.CellClass _ NEW [Core.CellClassRec _ [name: "Tiling", recast: RecastTiling, layersProps: FALSE, properties: CoreProperties.Props[[$Layout, $Recast]]]]; CreateTiling: PUBLIC PROC [public: WireSeq, tileArray: TileArray, neighborX, neighborY: NeighborProc, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [tiling: CellType] = { tiling _ CoreOps.CreateCellType[ class: tilingClass, public: public, data: NEW [TilingDataRec _ [tileArray: tileArray, neighborX: neighborX, neighborY: neighborY]], name: name, props: props ]; }; RecastTiling: Core.RecastProc = { ReplaceAndAddToPublicHT: PROC [old: Wire] RETURNS [new: Wire] ~ { new _ RootWire[fused, old]; [] _ RefTab.Insert[publicHT, new, NIL]; FOR i: NAT IN [0 .. old.size) DO new[i] _ ReplaceAndAddToPublicHT[old[i]] ENDLOOP; }; tilingData: TilingData = NARROW [me.data]; public: WireSeq = CoreOps.CopyWire[me.public]; fused: RefTab.Ref = CoreOps.CreateBindingTable[me.public, public]; -- keys are fused to values tiles: TileArray = tilingData.tileArray; sizeX: NAT = tiles[0].size; sizeY: NAT = tiles.size; internalsOnly: Wires _ NIL; instances: LIST OF CoreClasses.CellInstance _ NIL; publicHT: RefTab.Ref _ RefTab.Create[]; --used as a speedup to CoreOps.RecursiveMember[public, wire] FOR i: NAT IN [0 .. sizeY) DO IF tiles[i].size#sizeX THEN ERROR; FOR j: NAT IN [0 .. sizeX) DO tile: Tile = tiles[i][j]; instance: CoreClasses.CellInstance _ CreateInstance[me.public, tile, j, i]; IF NOT CoreOps.CorrectConform[instance.actual, instance.type.public] THEN ERROR; PutTileInstance[tile, instance]; IF tile.flatten THEN { rct: CoreClasses.RecordCellType = NARROW [tile.type.data]; publicToActual: RefTab.Ref = CoreOps.CreateBindingTable[instance.type.public, instance.actual]; FOR ii: NAT IN [0 .. rct.size) DO actual: WireSeq = CoreOps.CreateWires[size: rct[ii].type.public.size]; FOR k: NAT IN [0 .. rct[ii].type.public.size) DO actual[k] _ NARROW [RefTab.Fetch[publicToActual, rct[ii].actual[k]].val]; ENDLOOP; instances _ CONS [CoreClasses.CreateInstance[actual: actual, type: rct[ii].type, props: CoreProperties.Props[[$TilingXIndex, NEW [NAT _ j]], [$TilingYIndex, NEW [NAT _ i]]]], instances]; ENDLOOP; } ELSE instances _ CONS [instance, instances]; ENDLOOP; ENDLOOP; FOR i: NAT IN [0 .. sizeY) DO FOR j: NAT IN [1 .. sizeX) DO FuseNeighbors[tilingData.neighborX, tiles[i][j-1], tiles[i][j], fused]; ENDLOOP; ENDLOOP; FOR j: NAT IN [0 .. sizeX) DO FOR i: NAT IN [1 .. sizeY) DO FuseNeighbors[tilingData.neighborY, tiles[i-1][j], tiles[i][j], fused]; ENDLOOP; ENDLOOP; FOR i: NAT IN [0 .. public.size) DO public[i] _ ReplaceAndAddToPublicHT[public[i]]; ENDLOOP; FOR list: LIST OF CoreClasses.CellInstance _ instances, list.rest WHILE list#NIL DO instance: CoreClasses.CellInstance = list.first; instance.actual _ Replace[fused, instance.actual]; IF NOT CoreOps.Conform[instance.actual, instance.type.public] THEN ERROR; -- the tiles shorts parts of the public together FOR k: NAT IN [0 .. instance.actual.size) DO wire: Wire = instance.actual[k]; IF NOT RefTab.Fetch[publicHT, wire].found AND NOT CoreOps.Member[internalsOnly, wire] THEN internalsOnly _ CONS [wire, internalsOnly]; ENDLOOP; ENDLOOP; IF NOT CoreOps.Conform[public, me.public] THEN ERROR; -- the tiles shorts parts of the public together FOR i: NAT IN [0 .. sizeY) DO FOR j: NAT IN [0 .. sizeX) DO IF i=0 OR i=sizeY-1 OR j=0 OR j=sizeX-1 THEN { tile: Tile = tiles[i][j]; pubs, acts: Wires _ NIL; DecorateIfOutside: PROC [pub: Wire] = { act: Wire = RootWire[fused, CoreClasses.CorrespondingActual[GetTileInstance[tile], pub]]; IF act=NIL THEN ERROR; IF NOT RefTab.Fetch[publicHT, act].found THEN RETURN; IF CoreOps.Member[pubs, pub] THEN RETURN; -- already seen pubs _ CONS [pub, pubs]; acts _ CONS [act, acts]; }; CoreOps.VisitRootAtomics[tile.type.public, DecorateIfOutside]; PutTilePubActs[tile, pubs, acts]; }; ENDLOOP; ENDLOOP; FOR i: NAT DECREASING IN [0 .. sizeY) DO FOR j: NAT DECREASING IN [0 .. sizeX) DO PutTileInstance[tiles[i][j], NIL]; ENDLOOP; ENDLOOP; new _ CoreClasses.CreateRecordCell[ public: public, internal: CoreOps.UnionWire[public, CoreOps.CreateWire[internalsOnly]], instances: instances, name: CoreOps.GetCellTypeName[me], props: CoreProperties.Props[[$Layout, $Tiling], [$Tiles, tiles]], giveNames: TRUE ]; }; LayoutTiling: PWCore.LayoutProc = { Layout: PROC [i, j: NAT] RETURNS [CD.Object] = {RETURN [PWCore.Layout[tiles[i][j].type]]}; Tiles: PROC [x, y: NAT] RETURNS [CD.Object] = {RETURN [Layout[y, x]]}; tiles: TileArray = NARROW [CoreProperties.GetCellTypeProp[cellType, $Tiles]]; sizeX: NAT = tiles[0].size; sizeY: NAT = tiles.size; offset: CD.Position _ [0, 0]; ir: CD.Rect; FOR i: NAT IN [0 .. sizeY) DO height: INT = CD.InterestSize[Layout[i, 0]].y; FOR j: NAT IN [1 .. sizeX) DO IF height#CD.InterestSize[Layout[i, j]].y THEN ERROR; -- assumption not verified ENDLOOP; ENDLOOP; FOR j: NAT IN [0 .. sizeX) DO width: INT = CD.InterestSize[Layout[0, j]].x; FOR i: NAT IN [1 .. sizeY) DO IF width#CD.InterestSize[Layout[i, j]].x THEN ERROR; -- assumption not verified ENDLOOP; ENDLOOP; FOR i: NAT IN [0 .. sizeY) DO offset.x _ 0; FOR j: NAT IN [0 .. sizeX) DO offset.x _ offset.x + CD.InterestSize[Layout[i, j]].x; ENDLOOP; offset.y _ offset.y + CD.InterestSize[Layout[i, 0]].y; ENDLOOP; ir _ [0, 0, offset.x, offset.y]; offset _ [0, 0]; FOR i: NAT IN [0 .. sizeY) DO offset.x _ 0; FOR j: NAT IN [0 .. sizeX) DO tile: Tile = tiles[i][j]; seq: PubActs = GetTilePubActs[tile]; layout: CD.Object = Layout[i, j]; trans: CoreGeometry.Transformation = [CDBasics.SubPoints[offset, CD.InterestBase[layout]]]; IF seq#NIL THEN FOR i: NAT IN [0 .. seq.size) DO pins: CoreGeometry.Instances _ CoreGeometry.GetPins[PWCore.extractMode.decoration, seq[i].act]; FOR list: CoreGeometry.Instances _ CoreGeometry.GetPins[PWCore.extractMode.decoration, seq[i].pub], list.rest WHILE list#NIL DO IF CoreGeometry.TransfedNotAtEdge[trans, ir, list.first] THEN LOOP; pins _ CONS [CoreGeometry.Transform[trans, list.first], pins]; ENDLOOP; CoreGeometry.PutPins[PWCore.extractMode.decoration, seq[i].act, pins]; ENDLOOP; offset.x _ offset.x + CD.InterestSize[Layout[i, j]].x; ENDLOOP; offset.y _ offset.y + CD.InterestSize[Layout[i, 0]].y; ENDLOOP; obj _ PW.CreateTiling[sizeX, sizeY, Tiles]; }; cache: RefTab.Ref _ CoreGeometry.CreateNeighborsCache[]; LayoutNeighborX: PUBLIC NeighborProc = { [] _ PWCore.Layout[ct1]; -- to make sure the cellType is decorated [] _ PWCore.Layout[ct2]; -- to make sure the cellType is decorated publicPairs _ CoreGeometry.CachedEnumerateNeighbors[PWCore.extractMode.decoration, PWCore.extractMode.touchProc, TRUE, ct1, ct2, cache]; }; LayoutNeighborY: PUBLIC NeighborProc = { [] _ PWCore.Layout[ct1]; -- to make sure the cellType is decorated [] _ PWCore.Layout[ct2]; -- to make sure the cellType is decorated publicPairs _ CoreGeometry.CachedEnumerateNeighbors[PWCore.extractMode.decoration, PWCore.extractMode.touchProc, FALSE, ct1, ct2, cache]; }; SchematicsNeighborX: PUBLIC NeighborProc ={ publicPairs _ CoreGeometry.CachedEnumerateNeighbors[Sisyph.mode.decoration, Sisyph.mode.touchProc, TRUE, ct1, ct2, cache]; }; SchematicsNeighborY: PUBLIC NeighborProc ={ publicPairs _ CoreGeometry.CachedEnumerateNeighbors[Sisyph.mode.decoration, Sisyph.mode.touchProc, FALSE, ct1, ct2, cache]; }; [] _ PWCore.RegisterLayoutAtom[$Tiling, LayoutTiling]; END. HTilingClassImpl.mesa Copyright ำ 1986, 1987 by Xerox Corporation. All rights reversed. Created by Bertrand Serlet on September 19, 1986 1:48:15 pm PDT Bertrand Serlet September 12, 1987 5:11:52 pm PDT Barth, October 16, 1986 6:39:20 pm PDT Jean-Marc Frailong January 17, 1988 9:33:06 pm PST Utilities -- The old version, recursive; on a 128 by 128 array, the machine -> 815 RootWire: PROC [fused: RefTab.Ref, wire: Wire] RETURNS [root: Wire] = { root _ NARROW [RefTab.Fetch[fused, wire].val]; IF root=NIL THEN RETURN [wire]; IF root=wire THEN ERROR; root _ RootWire[fused, root]; [] _ RefTab.Replace[fused, wire, root]; }; make a simpler renaming table [public of tile -> public of me.public] Tiling Create instances (even with not the right wires yet) Find who to fuse, first progressing in rows Find who to fuse, progressing in columns Replace the public and note all public wires in publicHT Replace in instances the actuals Compute the internal only wires -- Preparing the decoration by storing on each tile the list of publics which decorations should be offset and added and the list of corresponding actuals [part of public]. Cleanup Generating the layout, now We check that sizes of the IR verify the assumptions We compute the ir (necessary for finding the decorations) We tile and decorate Predefined NeighborProcs Initialization ส ˜codešœ™KšœB™BKšœ<ฯk™?Kšœ1™1Kšœ#™&K™2—K™Kš œœcœ-˜žK˜šฯnœœ˜KšœœSœ˜wKšœ ˜Kšœœœ ˜—head™ Jšœ œœ ˜š œ œœ œœœœ˜SJ˜—šžœœ$˜8Jšœœ˜Jšœœ˜&Jšœœœ˜&šœœœ œ˜Jšœ-˜-Jšœ#˜#Jšœ˜—JšœT˜TJ˜J˜—šžœœœ˜Kšœœœœ˜Kšœ0˜0Kšœ5˜5šœœœ˜#Kšœ7˜7Kšœ˜—K˜K˜—šžœœ/œœ(˜wKšœ0˜0KšœC˜CKšœE™Eš œœœœœœ˜AKšœE˜EKšœ;˜;Kš œœœœœœฯc˜6Kšœ/˜/Kšœ˜—šœœœ˜-KšœA˜AKšœ˜—Kš œsœœœœ˜ฎK˜——™šœ œœJœ9˜ฐK˜—šž œœœSœœœœ˜ฏšœ ˜ Kšœ˜Kšœ˜KšœœW˜`Kšœ˜Kšœ˜—K˜K˜—šž œ˜!šžœœ œ˜AKšœ˜Kšœ"œ˜'Kš œœœœ*œ˜RK˜—Kšœœ ˜*K˜.KšœCŸ˜^Kšœ(˜(Kšœœ˜Kšœœ˜Kšœœ˜Kšœ œœœ˜2Kšœ(Ÿ<˜dKšœ4™4šœœœ˜Kšœœœ˜"šœœœœ˜Kšœ˜KšœK˜KKšœœ?œœ˜PKšœ ˜ šœœ˜Kšœ"œ˜:Kšœ_˜_šœœœ˜!KšœF˜Fšœœœ!˜0Kšœ œ7˜IKšœ˜—Kš œ œmœœœœ˜บKšœ˜—Kšœœ œ˜.—Kšœ˜—Kšœ˜—K™+šœœœ˜šœœœ˜KšœG˜GKšœ˜—Kšœ˜—K™(šœœœ˜šœœœ˜KšœG˜GKšœ˜—Kšœ˜—Jšœ8™8šœœœ˜#Kšœ/˜/Kšœ˜—J™ š œœœ1œœ˜SKšœ0˜0Kšœ2˜2Kš œœ8œœŸ0˜zJ™šœœœ˜,Kšœ ˜ Jš œœ$œœ%œœ˜†Kšœ˜—Kšœ˜—Jš œœ$œœŸ0˜fJšŸฌ™ฌšœœœ˜šœœœ˜š œœ œœ œ˜.K˜Kšœœ˜šžœœ˜'KšœY˜YKšœœœœ˜Kšœœ#œœ˜5KšœœœŸ˜9Jšœœ ˜Jšœœ ˜K˜—Kšœ>˜>Jšœ!˜!K˜—Kšœ˜—Kšœ˜—J™š œœ œœ˜(š œœ œœ˜(Kšœœ˜"Kšœ˜—Kšœ˜—šœ#˜#Jšœ˜JšœH˜HJšœ˜Jšœ"˜"JšœA˜AJšœ ˜Jšœ˜—J˜J˜—šž œ˜#Kš žœœœœœ œ$˜ZKš žœœœœœ œ˜FKšœœ4˜MKšœœ˜Kšœœ˜Kšœœ˜Kšœœ˜ Kšœ™Kšœœ™4šœœœ˜Kšœœœ˜.šœœœ˜Kš œœœœŸ˜PKšœ˜—Kšœ˜—šœœœ˜Kšœœœ˜-šœœœ˜Kš œœœœŸ˜OKšœ˜—Kšœ˜—J™9šœœœ˜Kšœ ˜ šœœœ˜Kšœœ˜6Kšœ˜—Kšœœ˜6Kšœ˜—Jšœ ˜ Jšœ™Kšœ˜šœœœ˜Kšœ ˜ šœœœ˜K˜Jšœ$˜$Kšœœ˜!KšœAœ˜[š œœœœœœ˜0Kšœ_˜_šœkœœ˜Kšœ7œœ˜CKšœœ3˜>Kšœ˜—KšœF˜FKšœ˜—Kšœœ˜6Kšœ˜—Kšœœ˜6Kšœ˜—Kšœœ#˜+K˜——™šœ8˜8K™—šžœœ˜(JšœŸ)˜BJšœŸ)˜BJšœqœ˜ˆK˜K˜—šžœœ˜(JšœŸ)˜BJšœŸ)˜BJšœqœ˜‰K˜K˜—šžœœ˜+Jšœcœ˜zJ˜K˜—šžœœ˜+Jšœcœ˜{J˜——™Jšœ6˜6K˜—Kšœ˜—…—+B=•