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 = { 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; 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] _ Replace[fused, 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 CoreOps.RecursiveMember[public, wire] 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 CoreOps.RecursiveMember[public, act] 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. ðTilingClassImpl.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 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 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™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˜—šž œ˜!Kšœœ ˜*K˜.KšœCŸ˜^Kšœ(˜(Kšœœ˜Kšœœ˜Kšœœ˜Kšœ œœœ˜2Kšœ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™šœœœ˜#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šœœ&œœ˜8KšœœœŸ˜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šœ˜—…—)þ;©