DIRECTORY Core, CoreClasses, CoreCreate, CoreOps, CoreProperties, GList, PatchWork, Pipal, PipalCore, PipalInt, PipalMos, RefTab, Tiling; TilingImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreCreate, CoreOps, CoreProperties, GList, PatchWork, PipalCore, PipalInt, PipalMos, RefTab EXPORTS Tiling ~ BEGIN OPEN Tiling; CellType : TYPE = Core.CellType; Properties : TYPE = Core.Properties; ROPE: TYPE = Core.ROPE; Wire: TYPE = Core.Wire; WireSeq: TYPE = Core.WireSeq; Wires: TYPE = Core.Wires; PA: TYPE = CoreCreate.PA; WR: TYPE = CoreCreate.WR; Object: TYPE = Pipal.Object; 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] = { 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]; }; 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 PipalCore.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]; 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 ]; }; XYTile: PipalMos.XYTileProc = { tiles: TileArray = NARROW [data]; RETURN [PatchWork.Layout[tiles[y][x].type]]; }; IJAbutBox: PROC [tiles: TileArray, i, j: NAT] RETURNS [PipalInt.Rectangle] = { RETURN [PipalInt.AbutBox[PatchWork.Layout[tiles[i][j].type]]]; }; LayoutTiling: PatchWork.LayoutProc = { tiles: TileArray = NARROW [CoreProperties.GetCellTypeProp[cellType, $Tiles]]; sizeX: NAT = tiles[0].size; sizeY: NAT = tiles.size; FOR i: NAT IN [0 .. sizeY) DO height: INT = IJAbutBox[tiles, i, 0].size.y; FOR j: NAT IN [1 .. sizeX) DO IF height#IJAbutBox[tiles, i, j].size.y THEN ERROR; -- assumption not verified ENDLOOP; ENDLOOP; FOR j: NAT IN [0 .. sizeX) DO width: INT = IJAbutBox[tiles, 0, j].size.x; FOR i: NAT IN [1 .. sizeY) DO IF width#IJAbutBox[tiles, i, j].size.x THEN ERROR; -- assumption not verified ENDLOOP; ENDLOOP; obj _ PipalMos.CreateTiling[sizeX, sizeY, XYTile, tiles]; }; DecorateTiling: PatchWork.DecorateProc = { tiles: TileArray = NARROW [CoreProperties.GetCellTypeProp[cellType, $Tiles]]; sizeX: NAT = tiles[0].size; sizeY: NAT = tiles.size; offset: PipalInt.Position _ PipalInt.zeroVector; ir: PipalInt.Rectangle _ PipalInt.AbutBox[obj]; 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]; IF seq#NIL THEN FOR i: NAT IN [0 .. seq.size) DO trans: PipalInt.Transformation = [PipalInt.Sub[offset, IJAbutBox[tiles, i, j].base]]; pubPort: Object _ PipalCore.GetPort[PipalCore.layoutDecoration, seq[i].pub]; IF pubPort#Pipal.void THEN PipalCore.AddPort[ PipalCore.layoutDecoration, seq[i].act, PipalMos.CreateClipEnum[ir, PipalInt.TransformObject[trans, pubPort]] ]; ENDLOOP; offset.x _ offset.x + IJAbutBox[tiles, i, j].size.x; ENDLOOP; offset.y _ offset.y + IJAbutBox[tiles, i, 0].size.y; ENDLOOP; }; cache: RefTab.Ref _ PipalCore.CreateNeighborsCache[]; LayoutNeighborX: PUBLIC NeighborProc = { [] _ PatchWork.Layout[ct1]; -- to make sure the cellType is decorated [] _ PatchWork.Layout[ct2]; -- to make sure the cellType is decorated publicPairs _ PipalCore.CachedEnumerateNeighbors[PipalCore.layoutDecoration, PipalMos.LayoutTouch, TRUE, ct1, ct2, cache]; }; LayoutNeighborY: PUBLIC NeighborProc = { [] _ PatchWork.Layout[ct1]; -- to make sure the cellType is decorated [] _ PatchWork.Layout[ct2]; -- to make sure the cellType is decorated publicPairs _ PipalCore.CachedEnumerateNeighbors[PipalCore.layoutDecoration, PipalMos.LayoutTouch, FALSE, ct1, ct2, cache]; }; SchematicsNeighborX: PUBLIC NeighborProc ={ publicPairs _ PipalCore.CachedEnumerateNeighbors[PipalCore.schematicsDecoration, PipalMos.SchematicTouch, TRUE, ct1, ct2, cache]; }; SchematicsNeighborY: PUBLIC NeighborProc ={ publicPairs _ PipalCore.CachedEnumerateNeighbors[PipalCore.schematicsDecoration, PipalMos.SchematicTouch, FALSE, ct1, ct2, cache]; }; [] _ PatchWork.RegisterLayoutAtom[$Tiling, LayoutTiling, DecorateTiling]; END. ธTilingImpl.mesa Copyright ำ 1986, 1987, 1988 by Xerox Corporation. All rights reversed. Created by Bertrand Serlet on September 19, 1986 1:48:15 pm PDT Bertrand Serlet May 9, 1988 0:03:18 am PDT Barth, October 16, 1986 6:39:20 pm PDT Jean-Marc Frailong January 17, 1988 9:33:06 pm PST Conveniences Utilities 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 We check that sizes of the IR verify the assumptions We tile and decorate Predefined NeighborProcs Initialization ส ˜codešœ™KšœH™HKšœ<ฯk™?Kšœ*™*Kšœ#™&Kšœ/™2—K™š ˜ Kšœ8˜8Kšœ˜K˜ K˜&Kšœ˜—K˜šฯn œœ˜Kšœk˜rKšœ˜Kšœœœ˜—head™ Kšœ œ˜ Kšœ œ˜$Kšœœœ˜Kšœœ ˜Kšœ œ˜Kšœœ˜Kšœœœ˜Kšœœœ˜Kšœœ˜—™ 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šœ˜—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šœœ˜!Jšœ&˜,J˜J˜—šž œœœœ˜NJšœ8˜>J˜J˜—šž œ˜&Kšœœ4˜MKšœœ˜Kšœœ˜Kšœœ™4šœœœ˜Kšœœ!˜,šœœœ˜Kšœ&œœŸ˜NKšœ˜—Kšœ˜—šœœœ˜Kšœœ!˜+šœœœ˜Kšœ%œœŸ˜MKšœ˜—Kšœ˜—Kšœ9˜9K˜K˜—šžœ˜*Kšœœ4˜MKšœœ˜Kšœœ˜Kšœ0˜0Kšœ/˜/Jšœ™šœœœ˜Kšœ ˜ šœœœ˜K˜Jšœ$˜$š œœœœœœ˜0KšœU˜UKšœL˜Lšœœ˜-Kšœ˜Kšœ ˜ KšœE˜EKšœ˜—Kšœ˜—Kšœ4˜4Kšœ˜—Kšœ4˜4Kšœ˜—K˜——™šœ5˜5K™—šžœœ˜(JšœŸ)˜EJšœŸ)˜EJšœcœ˜zK˜K˜—šžœœ˜(JšœŸ)˜EJšœŸ)˜EJšœcœ˜{K˜K˜—šžœœ˜+Jšœjœ˜J˜K˜—šžœœ˜+Jšœjœ˜‚J˜——™JšœI˜IK˜—Kšœ˜—…—)"8๔