DIRECTORY CD, CDBasics, CDCells, CDDirectory, CDImports, CDInstances, CDOps, CDProperties, CDRects, CDTexts, DABasics, ExtractOps, FS, IO, PW, RefTab, Rope, SoftHdwAssembly, SoftHdwBasics, SymTab, TerminalIO, ViewerClasses; SoftHdwAssemblyImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDDirectory, CDImports, CDInstances, CDOps, CDProperties, CDRects, CDTexts, ExtractOps, FS, IO, PW, RefTab, Rope, SoftHdwBasics, SymTab, TerminalIO EXPORTS SoftHdwAssembly = BEGIN OPEN SoftHdwAssembly; Create: PUBLIC PROC [instances: ProgramInstances _ NIL, tiles: ArrayPositions _ NIL, coordinates: Coordinates _ MinorArray, object: CD.Object _ NIL] RETURNS [program: Program] = { program _ NEW[ProgramRec _ [ tiles: tiles, instances: instances, coordinates: coordinates, object: object]]; }; Instance: PUBLIC PROC [program: Program, minorArray: Position _ [0, 0], chip: Position _ [0, 0], rotation: Rotation _ None] RETURNS [instance: ProgramInstance]= { instance _ NEW[ProgramInstanceRec _ [ program: program, rotation: rotation, chip: chip, minorArray: minorArray]]; }; CPI: PUBLIC PROC [old: ProgramInstances, program: Program, minorArray: Position _ [0, 0], chip: Position _ [0, 0], rotation: Rotation _ None] RETURNS [new: ProgramInstances] = { new _ CONS[Instance[program, minorArray, chip, rotation], old]; }; CTI: PUBLIC PROC [old: ArrayPositions, type: TileType, orientation: Orientation, grain: Position, minorArray: Position _ [0, 0], chip: Position _ [0, 0]] RETURNS [new: ArrayPositions] = { tile: ArrayPosition _ SoftHdwBasics.CreateArrayPosition[type, orientation, grain, minorArray, chip]; IF NOT (type IN TileType) THEN ERROR; new _ CONS[tile, old]; }; AbutX: PUBLIC PROC [t1, t2, t3, t4, t5, t6: Program _ NIL] RETURNS [program: Program] = { subPrograms: Programs _ NIL; IF t6#NIL THEN subPrograms _ CONS[t6, subPrograms]; IF t5#NIL THEN subPrograms _ CONS[t5, subPrograms]; IF t4#NIL THEN subPrograms _ CONS[t4, subPrograms]; IF t3#NIL THEN subPrograms _ CONS[t3, subPrograms]; IF t2#NIL THEN subPrograms _ CONS[t2, subPrograms]; IF t1#NIL THEN subPrograms _ CONS[t1, subPrograms]; program _ AbutXList[subPrograms]; }; AbutXList: PUBLIC PROC [subPrograms: Programs] RETURNS [program: Program] = { instances: ProgramInstances _ NIL; position: Position _ [0, 0]; coordinates: Coordinates _ IF subPrograms=NIL THEN Grain ELSE subPrograms.first.coordinates; FOR sp: Programs _ subPrograms, sp.rest UNTIL sp=NIL DO IF coordinates#sp.first.coordinates THEN ERROR; instances _ ConsByCoordinate[instances, sp.first, position]; position.x _ position.x + Size[sp.first].x; ENDLOOP; program _ Create[instances: instances, coordinates: coordinates]; }; AbutY: PUBLIC PROC [t1, t2, t3, t4, t5, t6: Program _ NIL] RETURNS [program: Program] = { subPrograms: Programs _ NIL; IF t6#NIL THEN subPrograms _ CONS[t6, subPrograms]; IF t5#NIL THEN subPrograms _ CONS[t5, subPrograms]; IF t4#NIL THEN subPrograms _ CONS[t4, subPrograms]; IF t3#NIL THEN subPrograms _ CONS[t3, subPrograms]; IF t2#NIL THEN subPrograms _ CONS[t2, subPrograms]; IF t1#NIL THEN subPrograms _ CONS[t1, subPrograms]; program _ AbutYList[subPrograms]; }; AbutYList: PUBLIC PROC [subPrograms: Programs] RETURNS [program: Program] = { instances: ProgramInstances _ NIL; position: Position _ [0, 0]; coordinates: Coordinates _ IF subPrograms=NIL THEN Grain ELSE subPrograms.first.coordinates; FOR sp: Programs _ subPrograms, sp.rest UNTIL sp=NIL DO IF coordinates#sp.first.coordinates THEN ERROR; instances _ ConsByCoordinate[instances, sp.first, position]; position.y _ position.y + Size[sp.first].y; ENDLOOP; program _ Create[instances: instances, coordinates: coordinates]; }; ArrayX: PUBLIC PROC [program: Program, nx: INT] RETURNS [array: Program] = { instances: ProgramInstances _ NIL; position: Position _ [0, 0]; xSize: INT _ Size[program].x; FOR count: INT IN [0..nx) DO instances _ ConsByCoordinate[instances, program, position]; position.x _ position.x + xSize; ENDLOOP; array _ Create[instances: instances, coordinates: program.coordinates]; }; ArrayY: PUBLIC PROC [program: Program, ny: INT] RETURNS [array: Program] = { instances: ProgramInstances _ NIL; position: Position _ [0, 0]; ySize: INT _ Size[program].y; FOR count: INT IN [0..ny) DO instances _ ConsByCoordinate[instances, program, position]; position.y _ position.y + ySize; ENDLOOP; array _ Create[instances: instances, coordinates: program.coordinates]; }; ConsByCoordinate: PROC [old: ProgramInstances, program: Program, position: Position] RETURNS [new: ProgramInstances] = { new _ SELECT program.coordinates FROM Grain => ERROR, MinorArray => CPI[old: old, program: program, minorArray: position], Chip => CPI[old: old, program: program, chip: position], ENDCASE => ERROR; }; Number: TYPE = DABasics.Number; lambda: Number _ 8; grainSize: Number _ 24*lambda; longIndent: Number _ 16*lambda; minorArraySpacing: Number _ 2*longIndent; interChipSize: Number _ 32*lambda; chipSpacing: Number _ 2*interChipSize; chipMinorArrayOffset: Position _ [16*lambda, 16*lambda]; minorArrayGrainOffset: Position _ [minorArraySpacing, minorArraySpacing]; rotationToCDOrientation: ARRAY Rotation OF CD.Orientation _ [original, rotate90X]; orientationToCDOrientation: ARRAY Orientation OF CD.Orientation _ [rotate90X, original]; MinorArrayChipSize: PROC [sizes: ArrayPosition] RETURNS [minorArraySize: Position, chipSize: Position] = { minorArraySize _ [sizes.grain.x*grainSize+minorArraySpacing, sizes.grain.y*grainSize+minorArraySpacing]; chipSize _ [sizes.minorArray.x*minorArraySize.x+chipSpacing, sizes.minorArray.y*minorArraySize.y+chipSpacing]; }; Parse: PUBLIC PROC [object: CD.Object] RETURNS [program: Program] = { ParseRecursive: PROC [object: CD.Object] RETURNS [program: Program _ NIL, tileType: TileType _ InputEnabled] = { program _ NARROW[RefTab.Fetch[map, object].val]; IF program=NIL THEN { instances: ProgramInstances _ NIL; tiles: ArrayPositions _ NIL; base: Position _ CD.InterestBase[object]; One: CDCells.InstEnumerator = { subProgram: Program; subTileType: TileType; trans: CD.Transformation _ [CDBasics.SubPoints[CDBasics.MapPoint[CD.InterestBase[inst.ob], inst.trans], base], inst.trans.orient]; IF CDTexts.IsText[inst.ob] THEN RETURN; [subProgram, subTileType] _ ParseRecursive[inst.ob]; IF subProgram=NIL THEN { p: ArrayPositionRec _ TransformationToTile[minorArraySize, chipSize, trans, subTileType]; tiles _ CTI[tiles, p.type, p.orientation, p.grain, p.minorArray, p.chip]; } ELSE { rotation: Rotation _ SELECT trans.orient FROM original => None, rotate90X => Rotate90FlipX, ENDCASE => ERROR; chip, minorArray: Position; [chip, minorArray] _ OffsetToProgram[minorArraySize, chipSize, trans.off]; instances _ CPI[instances, subProgram, minorArray, chip, rotation]; }; }; leafName: Rope.ROPE; UNTIL CDCells.IsCell[object] DO object _ CDDirectory.Expand1[object].new; ENDLOOP; leafName _ NARROW[CDProperties.GetObjectProp[object, $SoftHdwLeaf]]; IF leafName#NIL THEN { FOR index: TileType IN TileType DO IF Rope.Equal[leafName, tileNames[index]] THEN { tileType _ index; RETURN; }; ENDLOOP; ERROR; }; [] _ CDCells.EnumerateInstances[object, One]; program _ Create[instances, tiles, MinorArray, object]; IF NOT RefTab.Store[map, object, program] THEN ERROR; }; }; map: RefTab.Ref _ RefTab.Create[]; minorArraySize, chipSize: Position; sizes: ArrayPosition _ NEW[ArrayPositionRec]; sizes.chip _ [1, 1]; sizes.minorArray _ [LAST[Number], LAST[Number]]; sizes.grain _ [4, 4]; [minorArraySize, chipSize] _ MinorArrayChipSize[sizes]; program _ ParseRecursive[object].program; IF program=NIL THEN ERROR; -- an isolated tile is not a program }; OffsetToProgram: PROC [minorArraySize, chipSize: Position, offset: Position] RETURNS [chip, minorArray, remainder: Position] = { chip _ [0,0]; -- hack, only parse MinorArray coordinate system for now minorArray.x _ offset.x/minorArraySize.x; minorArray.y _ offset.y/minorArraySize.y; offset.x _ offset.x - minorArray.x*minorArraySize.x; offset.y _ offset.y - minorArray.y*minorArraySize.y; remainder _ offset; }; TransformationToTile: PROC [minorArraySize, chipSize: Position, trans: CD.Transformation, type: TileType] RETURNS [tile: ArrayPositionRec] = { tile.type _ type; tile.orientation _ SELECT trans.orient FROM original => Horizontal, rotate90X => Vertical, ENDCASE => ERROR; [tile.chip, tile.minorArray, trans.off] _ OffsetToProgram[minorArraySize, chipSize, trans.off]; SELECT type FROM OToP, RUToP, LDToP, LToP, PToI, PToRU, PToLD, PToL => ERROR; ORUToI, LDToLD, OLDToI, ORUToL, Tristate, RUToRU, ORUToLD, LDToI, OLDToRU, LToI, RUToI, Inverter, FlipFlop, ParallelInput, InputEnabled => { trans.off _ CDBasics.SubPoints[trans.off, minorArrayGrainOffset]; tile.grain.x _ trans.off.x/grainSize; tile.grain.y _ trans.off.y/grainSize; trans.off _ CDBasics.SubPoints[trans.off, [tile.grain.x*grainSize, tile.grain.y*grainSize]]; SELECT TRUE FROM tile.grain.x>=0 AND tile.grain.y>=0 => { tile.type _ InputEnabled; tile.orientation _ SELECT trans.off FROM [16*lambda, 12*lambda] => Vertical, [12*lambda, 16*lambda] => Horizontal, ENDCASE => ERROR; }; tile.type=ParallelInput => { SELECT TRUE FROM tile.grain.x<0 => { tile.orientation _ Horizontal; tile.grain.x _ 0; }; tile.grain.y<0 => { tile.orientation _ Vertical; tile.grain.y _ 0; }; ENDCASE => ERROR; } ENDCASE => SELECT tile.orientation FROM Horizontal => tile.grain.x _ 0; Vertical => tile.grain.y _ 0; ENDCASE => ERROR; }; RAMEven, RAMOdd => IF trans.off#[0,0] OR tile.orientation#Horizontal THEN ERROR; ENDCASE => ERROR; }; CDToArrayPosition: PUBLIC PROC [sizes: ArrayPosition, coordinates: Coordinates, mouse: Position] RETURNS [ambiguous: BOOL _ FALSE, position: ArrayPosition _ NIL] = { ProbeNodeType: TYPE = {pLong, pInput, pOutput, pLeftDown, pRightUp, pInputEnabled}; probeNodeTypeToNodeType: ARRAY ProbeNodeType OF NodeType = [Long, Input, Output, LeftDown, RightUp, InputEnabled]; probePositions: ARRAY Orientation OF ARRAY ProbeNodeType OF Position = [ [[4*lambda, 0*lambda], -- Vertical Long [16*lambda, 0*lambda], -- Vertical Input [20*lambda, 0*lambda], -- Vertical Output [8*lambda, 0*lambda], -- Vertical LeftDown [12*lambda, 0*lambda], -- Vertical RightUp [20*lambda, 16*lambda]], -- Vertical InputEnabled [[0*lambda, 4*lambda], -- Horizontal Long [0*lambda, 16*lambda], -- Horizontal Input [0*lambda, 20*lambda], -- Horizontal Output [0*lambda, 8*lambda], -- Horizontal LeftUp [0*lambda, 12*lambda], -- Horizontal RightDown [16*lambda, 20*lambda]]]; -- Horizontal InputEnabled minorArraySize, chipSize: Position; minorMouse: Position; [minorArraySize, chipSize] _ MinorArrayChipSize[sizes]; IF coordinates#MinorArray THEN ERROR; -- nyi position _ NEW[ArrayPositionRec]; [position.chip, position.minorArray, mouse] _ OffsetToProgram[minorArraySize, chipSize, mouse]; minorMouse _ mouse; mouse _ CDBasics.SubPoints[mouse, minorArrayGrainOffset]; position.grain _ [mouse.x/grainSize, mouse.y/grainSize]; mouse _ CDBasics.SubPoints[mouse, [position.grain.x*grainSize, position.grain.y*grainSize]]; SELECT TRUE FROM minorMouse.x { position.type _ Long; position.orientation _ Horizontal; }; minorMouse.x=minorArraySize.x => FOR pnt: ProbeNodeType IN ProbeNodeType DO IF mouse.y=probePositions[Horizontal][pnt].y THEN { position.type _ probeNodeTypeToNodeType[pnt]; position.orientation _ Horizontal; EXIT; }; REPEAT FINISHED => RETURN[TRUE, NIL] ENDLOOP; minorMouse.y { position.type _ Long; position.orientation _ Vertical; }; minorMouse.y=(minorArraySize.y-minorArraySpacing) => FOR pnt: ProbeNodeType IN ProbeNodeType DO IF mouse.x=probePositions[Horizontal][pnt].x THEN { position.type _ probeNodeTypeToNodeType[pnt]; position.orientation _ Vertical; EXIT; }; REPEAT FINISHED => RETURN[TRUE, NIL] ENDLOOP; ENDCASE => { FOR orient: Orientation IN Orientation DO FOR pnt: ProbeNodeType IN ProbeNodeType DO IF probePositions[orient][pnt]=mouse THEN { position.type _ probeNodeTypeToNodeType[pnt]; position.orientation _ orient; GOTO found; }; ENDLOOP; REPEAT found => NULL; FINISHED => RETURN[TRUE, NIL]; ENDLOOP; }; SELECT position.type FROM InputEnabled => NULL; Long => SELECT position.orientation FROM Vertical => { position.minorArray.y _ 0; position.grain.y _ 0; }; Horizontal => { position.minorArray.x _ 0; position.grain.x _ 0; }; ENDCASE; Input, Output, LeftDown, RightUp => SELECT position.orientation FROM Vertical => position.grain.y _ 0; Horizontal => position.grain.x _ 0; ENDCASE; ENDCASE => ERROR; }; Print: PUBLIC PROC [sizes: ArrayPosition, program: Program] RETURNS [object: CD.Object] = { PrintRecursive: PROC [program: Program] RETURNS [object: CD.Object] = { object _ NARROW[RefTab.Fetch[map, program].val]; IF object=NIL THEN { ConsInstance: PROC [object: CD.Object, trans: CD.Transformation] = { trans.off _ CDBasics.SubPoints[trans.off, CDBasics.OrientedSize[CD.InterestBase[object], trans.orient]]; il _ CONS[CDInstances.NewInst[object, trans], il]; }; il: CD.InstanceList _ NIL; size: Position _ Size[program]; multiplier: Position _ SELECT program.coordinates FROM Grain => ERROR, MinorArray => minorArraySize, Chip => chipSize, ENDCASE => ERROR; upperRight: Position _ [size.x*multiplier.x, size.y*multiplier.y]; FOR tiles: ArrayPositions _ program.tiles, tiles.rest UNTIL tiles=NIL DO tile: ArrayPosition _ tiles.first; subObject: CD.Object _ tileObjects[tile.type]; subTrans: CD.Transformation _ TileToTransformation[minorArraySize, chipSize, tile]; ConsInstance[subObject, subTrans]; ENDLOOP; FOR instances: ProgramInstances _ program.instances, instances.rest UNTIL instances=NIL DO instance: ProgramInstance _ instances.first; subObject: CD.Object _ PrintRecursive[instance.program]; subTrans: CD.Transformation _ ProgramToTransformation[minorArraySize, chipSize, instance.chip, instance.minorArray]; subTrans.orient _ rotationToCDOrientation[instance.rotation]; IF instance.program.coordinates=MinorArray AND program.coordinates=Chip THEN subTrans.off _ CDBasics.AddPoints[subTrans.off, chipMinorArrayOffset]; ConsInstance[subObject, subTrans]; ENDLOOP; IF program.coordinates=MinorArray THEN upperRight _ CDBasics.AddPoints[upperRight, [minorArraySpacing, minorArraySpacing]]; object _ PW.CreateCell[il, [0, 0, upperRight.x, upperRight.y]]; IF NOT RefTab.Store[map, program, object] THEN ERROR; }; }; map: RefTab.Ref _ RefTab.Create[]; minorArraySize, chipSize: Position; [minorArraySize, chipSize] _ MinorArrayChipSize[sizes]; IF sizes.grain # [4,4] THEN ERROR; object _ PrintRecursive[program]; }; PrintAndDraw: PUBLIC PROC [sizes: ArrayPosition, program: Program] RETURNS [design: CD.Design] = { il: CD.InstanceList _ NIL; programObject: CD.Object _ Print[sizes, program]; arrayObject: CD.Object _ CreateArray[sizes, program]; programInterestBase: Position _ CD.InterestBase[programObject]; arrayInterestBase: Position _ CD.InterestBase[arrayObject]; il _ CONS[CDInstances.NewInst[programObject, [[-programInterestBase.x, -programInterestBase.y], original]], il]; il _ CONS[CDInstances.NewInst[arrayObject, [[-arrayInterestBase.x, -arrayInterestBase.y], original]], il]; design _ PW.Draw[PW.CreateCell[il]]; }; ProgramToTransformation: PROC [minorArraySize, chipSize: Position, chip: Position, minorArray: Position] RETURNS [trans: CD.Transformation _ [[0, 0], original]] = { trans.off.x _ chip.x*chipSize.x; trans.off.y _ chip.y*chipSize.y; trans.off.x _ trans.off.x + minorArray.x*minorArraySize.x; trans.off.y _ trans.off.y + minorArray.y*minorArraySize.y; }; TileToTransformation : PROC [minorArraySize, chipSize: Position, tile: ArrayPosition] RETURNS [trans: CD.Transformation _ [[0, 0], original]] = { typeOffset: Position _ SELECT tile.type FROM OToP, RUToP, LDToP, LToP, PToI, PToRU, PToLD, PToL => ERROR, ORUToI, LDToLD, OLDToI, ORUToL, Tristate, RUToRU, ORUToLD, LDToI, OLDToRU, LToI, RUToI, Inverter, FlipFlop, Master => [0, 32], ParallelInput => [28, 48], InputEnabled => [44, 48], RAMEven, RAMOdd => [0, 0], Input => [30, 48], Output => [30, 52], LeftDown => [32, 40], RightUp => [32, 44], Long => [16, 36], ENDCASE => ERROR; typeOffset _ [typeOffset.x*lambda, typeOffset.y*lambda]; trans _ ProgramToTransformation[minorArraySize, chipSize, tile.chip, tile.minorArray]; trans.orient _ orientationToCDOrientation[tile.orientation]; trans.off.x _ trans.off.x + tile.grain.x*grainSize; trans.off.y _ trans.off.y + tile.grain.y*grainSize; trans.off _ CDBasics.AddPoints[trans.off, SELECT tile.orientation FROM Vertical => [typeOffset.y, typeOffset.x], Horizontal => [typeOffset.x, typeOffset.y], ENDCASE => ERROR]; }; CreateArray: PROC [sizes: ArrayPosition, program: Program] RETURNS [object: CD.Object] = { minorArray: CD.Object _ baseObjects[MinorArray]; size: Position _ Size[program]; SELECT program.coordinates FROM Grain => ERROR; -- should paint inside of minor array MinorArray => { inner: CD.Object _ PW.Array[minorArray, size.x, size.y]; ir: CD.Rect _ CDBasics.Extend[CD.InterestRect[inner], 16*8]; object _ PW.CreateCell[LIST[CDInstances.NewInst[inner, [[0,0],original]]], ir]; }; Chip => { inner: CD.Object _ PW.Array[minorArray, sizes.minorArray.x, sizes.minorArray.y]; boardTraces: CD.Object _ baseObjects[BoardTraces]; boardTracesSize: DABasics.Position _ CD.InterestSize[boardTraces]; corner: CD.Object _ baseObjects[Corner]; side: CD.Object _ PW.ArrayY[boardTraces, sizes.minorArray.y]; middle: CD.Object _ PW.AbutX[PW.FlipX[side], inner, side]; top: CD.Object _ PW.AbutX[corner, PW.ArrayX[PW.FlipX[PW.Rot90[boardTraces]], sizes.minorArray.x], corner]; bottom: CD.Object _ PW.AbutX[corner, PW.ArrayX[PW.FlipY[PW.FlipX[PW.Rot90[boardTraces]]], sizes.minorArray.x], corner]; chip: CD.Object _ PW.AbutY[bottom, middle, top]; object _ PW.Array[chip, size.x, size.y] }; ENDCASE => ERROR; }; Stats: PUBLIC PROC [program: Program] = { RecursiveStats: PROC [program: Program] = { FOR instances: ProgramInstances _ program.instances, instances.rest UNTIL instances=NIL DO instance: ProgramInstance _ instances.first; RecursiveStats[instance.program]; ENDLOOP; FOR tiles: ArrayPositions _ program.tiles, tiles.rest UNTIL tiles=NIL DO tile: ArrayPosition _ tiles.first; IF tile.type=FlipFlop THEN { TerminalIO.PutRope["\n"]; TerminalIO.PutRope[SoftHdwBasics.ArrayPositionToRope[tile]]; }; ENDLOOP; }; RecursiveStats[program]; }; Pickle: PUBLIC PROC [program: Program, fileName: Rope.ROPE] = { RecursivePickle: PROC [program: Program] = { id: Rope.ROPE _ NARROW[RefTab.Fetch[map, program].val]; IF id=NIL THEN { size: INT _ 0; id _ IO.PutFR["P%g", IO.int[nextID]]; nextID _ nextID + 1; IF NOT RefTab.Insert[map, program, id] THEN ERROR; IO.PutF[stream,"%g ", IO.rope[id]]; FOR instances: ProgramInstances _ program.instances, instances.rest UNTIL instances=NIL DO size _ size + 1; ENDLOOP; IO.PutF[stream, "%g ", IO.int[size]]; FOR instances: ProgramInstances _ program.instances, instances.rest UNTIL instances=NIL DO instance: ProgramInstance _ instances.first; RecursivePickle[instance.program]; IO.PutF[stream, "%g ", IO.rope[SELECT instance.rotation FROM None => "N", Rotate90FlipX => "R", ENDCASE => ERROR]]; PutPosition[instance.chip]; PutPosition[instance.minorArray]; ENDLOOP; size _ 0; FOR tiles: ArrayPositions _ program.tiles, tiles.rest UNTIL tiles=NIL DO size _ size + 1; ENDLOOP; IO.PutF[stream, "%g ", IO.int[size]]; FOR tiles: ArrayPositions _ program.tiles, tiles.rest UNTIL tiles=NIL DO tile: ArrayPosition _ tiles.first; IO.PutF[stream, """%g"" ", IO.rope[SoftHdwBasics.ArrayPositionToRope[tile]]] ENDLOOP; IO.PutF[stream, "%g ", IO.rope[SELECT program.coordinates FROM Grain => "G", MinorArray => "M", Chip => "C", ENDCASE => ERROR]]; } ELSE IO.PutF[stream,"%g ", IO.rope[id]]; }; PutPosition: PROC [position: Position] = { IO.PutF[stream, "%g %g ", IO.int[position.x], IO.int[position.y]]; }; stream: IO.STREAM _ FS.StreamOpen[fileName, $create]; map: RefTab.Ref _ RefTab.Create[]; nextID: INT _ 0; RecursivePickle[program]; IO.Close[stream]; }; Unpickle: PUBLIC PROC [fileName: Rope.ROPE] RETURNS [program: Program] = { RecursiveUnpickle: PROC RETURNS [program: Program] = { id: Rope.ROPE _ IO.GetID[stream]; IF (program _ NARROW[SymTab.Fetch[map, id].val])=NIL THEN { size: INT _ 0; program _ NEW[ProgramRec]; IF NOT SymTab.Insert[map, id, program] THEN ERROR; size _ IO.GetInt[stream]; THROUGH [0..size) DO instance: ProgramInstance _ NEW[ProgramInstanceRec]; instance.program _ RecursiveUnpickle[]; id _ IO.GetID[stream]; instance.rotation _ SELECT TRUE FROM Rope.Equal[id, "N"] => None, Rope.Equal[id, "R"] => Rotate90FlipX, ENDCASE => ERROR; instance.chip _ GetPosition[]; instance.minorArray _ GetPosition[]; program.instances _ CONS[instance, program.instances]; ENDLOOP; size _ IO.GetInt[stream]; THROUGH [0..size) DO program.tiles _ CONS[SoftHdwBasics.RopeToArrayPosition[ IO.GetRopeLiteral[stream]], program.tiles]; ENDLOOP; id _ IO.GetID[stream]; program.coordinates _ SELECT TRUE FROM Rope.Equal[id, "G"] => Grain, Rope.Equal[id, "M"] => MinorArray, Rope.Equal[id, "C"] => Chip, ENDCASE => ERROR; }; }; GetPosition: PROC RETURNS[position: Position] = { position _ [IO.GetInt[stream], IO.GetInt[stream]]; }; stream: IO.STREAM _ FS.StreamOpen[fileName, $read]; map: SymTab.Ref _ SymTab.Create[]; program _ RecursiveUnpickle[]; IO.Close[stream]; }; Size: PUBLIC PROC [program: Program] RETURNS [size: Position] = { min: Position _ [LAST[DABasics.Number], LAST[DABasics.Number]]; max: Position _ [0, 0]; FOR tiles: ArrayPositions _ program.tiles, tiles.rest UNTIL tiles=NIL DO tile: ArrayPosition _ tiles.first; position: Position _ SELECT program.coordinates FROM Grain => (IF tile.minorArray#[0,0] OR tile.chip#[0,0] THEN ERROR ELSE tile.grain), MinorArray => (IF tile.chip#[0,0] THEN ERROR ELSE tile.minorArray), Chip => tile.chip, ENDCASE => ERROR; min.x _ MIN[position.x, min.x]; min.y _ MIN[position.y, min.y]; max.x _ MAX[position.x, max.x]; max.y _ MAX[position.y, max.y]; ENDLOOP; FOR instances: ProgramInstances _ program.instances, instances.rest UNTIL instances=NIL DO instance: ProgramInstance _ instances.first; position: Position _ SELECT program.coordinates FROM Grain => ERROR, MinorArray => (IF instance.chip#[0,0] THEN ERROR ELSE instance.minorArray), Chip => instance.chip, ENDCASE => ERROR; IF ORD[instance.program.coordinates]>ORD[program.coordinates] THEN ERROR; -- trying to embed a higher level construct inside a lower level construct IF instance.rotation=None THEN { min.x _ MIN[position.x, min.x]; min.y _ MIN[position.y, min.y]; IF ORD[instance.program.coordinates]=ORD[program.coordinates] THEN { subSize: Position _ Size[instance.program]; max.x _ MAX[position.x+subSize.x-1, max.x]; max.y _ MAX[position.y+subSize.y-1, max.y]; }; } ELSE { min.x _ MIN[position.y, min.x]; min.y _ MIN[position.x, min.y]; IF ORD[instance.program.coordinates]=ORD[program.coordinates] THEN { subSize: Position _ Size[instance.program]; max.x _ MAX[position.y+subSize.y-1, max.x]; max.y _ MAX[position.x+subSize.x-1, max.y]; }; }; ENDLOOP; size.x _ max.x + 1; size.y _ max.y + 1; }; EnumerateTiles: PUBLIC PROC [program: Program, eachTile: EachTileProc] = { EnumerateTilesRecursive: PROC [program: Program, chip: Position, minorArray: Position] = { FOR tiles: ArrayPositions _ program.tiles, tiles.rest UNTIL tiles=NIL DO position^ _ tiles.first^; position.chip _ CDBasics.AddPoints[chip, position.chip]; position.minorArray _ CDBasics.AddPoints[minorArray, position.minorArray]; eachTile[position]; ENDLOOP; FOR instances: ProgramInstances _ program.instances, instances.rest UNTIL instances=NIL DO instance: ProgramInstance _ instances.first; IF instance.rotation#None THEN ERROR; EnumerateTilesRecursive[instance.program, CDBasics.AddPoints[chip, instance.chip], CDBasics.AddPoints[minorArray, instance.minorArray]]; ENDLOOP; }; position: ArrayPosition _ NEW[ArrayPositionRec]; EnumerateTilesRecursive[program, [0,0], [0,0]]; }; OpenDesign: PUBLIC PROC [designName: Rope.ROPE] RETURNS [design: CD.Design] = { design _ PW.OpenDesign[designName]; CDOps.SetMutability[design, readonly]; IF NOT CDImports.LoadAndBindAll[design, false] THEN ERROR; }; highlightRectangleWidth: Number = 3*lambda; HighlightDesign: PUBLIC PROC [design: CD.Design, sizes: ArrayPosition, positions: ColoredArrayPositions _ NIL, viewer: ViewerClasses.Viewer _ NIL, label: Rope.ROPE _ NIL] = { instances: CD.InstanceList _ NIL; minorArraySize, chipSize: Position; [minorArraySize, chipSize] _ MinorArrayChipSize[sizes]; FOR pl: ColoredArrayPositions _ positions, pl.rest UNTIL pl=NIL DO position: ArrayPosition _ pl.first.position; object: CD.Object _ IF position.type=Long THEN CDRects.CreateRect[[(IF position.orientation=Vertical THEN sizes.minorArray.y*minorArraySize.y ELSE sizes.minorArray.x*minorArraySize.x), highlightRectangleWidth], colorToLayer[pl.first.color]] ELSE nodeHighlightObjects[position.type][pl.first.color]; transform: CD.Transformation _ TileToTransformation[minorArraySize, chipSize, position]; instance: CD.Instance; transform.off _ CDBasics.SubPoints[transform.off, CDBasics.OrientedSize[CD.InterestBase[object], transform.orient]]; instance _ NEW[CD.InstanceRep _ [ ob: object, trans: transform]]; instances _ CONS[instance, instances]; ENDLOOP; ExtractOps.HighlightDesignList[design: design, highlight: instances, viewer: viewer, label: label]; }; LoadTile: PUBLIC PROC [design: CD.Design, tileName: Rope.ROPE] RETURNS [program: Program] = { object: CD.Object _ PW.Get[design, tileName]; program _ Parse[object]; }; tileNames: ARRAY TileType OF Rope.ROPE _ ["OToP", "RUToP", "LDToP", "LToP", "PToI", "PToRU", "PToLD", "PToL", "ORUToI", "LDToLD", "OLDToI", "ORUToL", "Tristate", "RUToRU", "ORUToLD", "LDToI", "OLDToRU", "LToI", "RUToI", "Inverter", "FlipFlop", "Program", "Program", "RAMEven", "RAMOdd"]; tileObjects: ARRAY TileType OF CD.Object _ ALL[NIL]; nodeHighlightObjects: ARRAY NodeType OF ARRAY HighlightColor OF CD.Object; colorToLayer: ARRAY HighlightColor OF CD.Layer _ [CD.FetchLayer[NIL, $red], CD.FetchLayer[NIL, $green], CD.FetchLayer[NIL, $blue], CD.FetchLayer[NIL, $yellow], CD.FetchLayer[NIL, $black]]; BaseType: TYPE = {MinorArray, BoardTraces, Corner}; baseNames: ARRAY BaseType OF Rope.ROPE _ ["MinorArray", "BoardTraces", "Corner"]; baseObjects: ARRAY BaseType OF CD.Object _ ALL[NIL]; LoadTiles: PROC = { design: CD.Design _ PW.OpenDesign["SoftHdw.dale"]; CDOps.SetMutability[design, readonly]; FOR index: NodeType IN NodeType DO FOR currentColor: HighlightColor IN HighlightColor DO nodeHighlightObjects[index][currentColor] _ NIL; ENDLOOP; ENDLOOP; FOR index: TileType IN TileType DO tileObjects[index] _ PW.Get[design, tileNames[index]]; FOR currentColor: HighlightColor IN HighlightColor DO instances: CD.InstanceList _ NIL; One: CDCells.InstEnumerator = { IF CDRects.IsSimpleRect[inst.ob] THEN { size: Position _ CD.InterestSize[inst.ob]; instance: CD.Instance; IF size.x>size.y THEN size.y _ highlightRectangleWidth ELSE size.x _ highlightRectangleWidth; instance _ CDInstances.NewInst[ CDRects.CreateRect[size, colorToLayer[currentColor]], inst.trans]; instances _ CONS[instance, instances]; }; }; [] _ CDCells.EnumerateInstances[tileObjects[index], One]; IF instances=NIL THEN nodeHighlightObjects[index][currentColor] _ CDRects.CreateRect[CD.InterestSize[tileObjects[index]], CD.shadeLayer] ELSE { nodeHighlightObjects[index][currentColor] _ CDCells.CreateCell[il: instances, ir: CD.InterestRect[tileObjects[index]]]; CDCells.SetSimplificationTreshhold[nodeHighlightObjects[index][currentColor], 1.0]; }; ENDLOOP; ENDLOOP; FOR index: BaseType IN BaseType DO baseObjects[index] _ PW.Get[design, baseNames[index]]; ENDLOOP; FOR node: NodeType IN [Master..RightUp] DO length: INT _ SELECT node FROM Input, Output => 98, LeftDown, RightUp => 96, Long => 1, -- hack, really must create these dynamically Master => 8, Interchip => 8, -- hack, don't really know what it is yet ENDCASE => ERROR; FOR currentColor: HighlightColor IN HighlightColor DO nodeHighlightObjects[node][currentColor] _ CDRects.CreateRect[[length*lambda, highlightRectangleWidth], colorToLayer[currentColor]]; ENDLOOP; ENDLOOP; nodeHighlightObjects[Master] _ nodeHighlightObjects[FlipFlop]; }; LoadTiles[]; END. SoftHdwAssemblyImpl.mesa Copyright ำ 1988 by Xerox Corporation. All rights reserved. Barth, September 7, 1989 4:50:39 pm PDT Program Creation Parse And Print Geometric Constants and Utilities Parse Print Really need to adjust for any shift in coordinate systems. should construct minor array from more primitive components Utilities Should check for overflow, requires sizes parameter. Also should check for tile type and coordinate system compatibility. size.x _ max.x - min.x + 1; size.y _ max.y - min.y + 1; Tile Loading ส“– "cedar" style˜codešœ™K™˜IK˜—šœ˜šœœ˜-K˜Kšœ˜Kšœœ˜—Kšœ˜KšœJ˜JKšœ œ4˜CK˜—Kšœ˜—Kšœœ˜šœ˜Kšœ)˜)Kšœ˜—Kšœ œ3˜Dšœ œœ˜šœœ ˜"šœ(œ˜0Kšœ˜Kšœ˜K˜—Kšœ˜—Kšœ˜K˜—Kšœ-˜-Kšœ7˜7Kšœœ$œœ˜5K˜—K˜—K˜"Kšœ#˜#Kšœœ˜-K˜Kšœœ œ ˜0K˜Kšœ7˜7Kšœ)˜)Kš œ œœœฯc$˜@K˜K˜—šžœœ8œ,˜€KšœŸ8˜GKšœ)˜)Kšœ)˜)Kšœ4˜4Kšœ4˜4Kšœ˜K˜K˜—šžœœ-œ!œ˜ŽKšœ˜šœœ˜+K˜K˜Kšœœ˜—Kšœ_˜_šœ˜Kšœ6œ˜<šœŒ˜ŒKšœA˜AKšœ%˜%Kšœ%˜%Kšœ\˜\šœœ˜šœœ˜(Kšœ˜šœœ ˜(Kšœ#˜#Kšœ%˜%Kšœœ˜—K˜—šœ˜šœœ˜šœ˜Kšœ˜Kšœ˜K˜—šœ˜Kšœ˜Kšœ˜K˜—Kšœœ˜—K˜—šœœ˜'K˜K˜Kšœœ˜——K˜—Kš œœœœœ˜PKšœœ˜—K˜K˜—šžœœœCœ œœœ˜ฅKšœœ@˜SKšœœœC˜rš œœ œœœ ˜HKšœ(˜(Kšœ)˜)Kšœ*˜*Kšœ+˜+Kšœ+˜+Kšœ2˜2Kšœ*˜*Kšœ+˜+Kšœ,˜,Kšœ+˜+Kšœ/˜/Kšœ5˜5—Kšœ#˜#Kšœ˜Kšœ7˜7KšœœœŸ˜-Kšœ œ˜!Kšœ_˜_Kšœ˜Kšœ9˜9Kšœ8˜8Kšœ\˜\šœœ˜šœœ1˜SKšœ˜Kšœ"˜"K˜—šœ!œœ˜Kšœ+œ˜3Kšœ-˜-Kšœ"˜"Kšœ˜K˜—Kš œœœœœ˜$Kšœ˜—šœœ/˜QKšœ˜Kšœ ˜ K˜—šœ5œœ˜_šœ+œ˜3Kšœ-˜-Kšœ ˜ Kšœ˜K˜—Kš œœœœœ˜$Kšœ˜—šœ˜ šœœ ˜)šœœ˜*šœ#œ˜+Kšœ-˜-Kšœ˜Kšœ˜ K˜—Kšœ˜—š˜Kšœ œ˜Kšœœœœ˜—Kšœ˜—K˜——šœ˜Kšœœ˜šœœ˜(šœ ˜ Kšœ˜Kšœ˜K˜—šœ˜Kšœ˜Kšœ˜K˜—Kšœ˜—šœ$œ˜DKšœ!˜!Kšœ#˜#Kšœ˜—Kšœœ˜—K˜K˜——™š žœœœ*œ œ ˜[šžœœœ œ ˜GKšœ œ!˜0šœœœ˜šž œœ œœ˜DKšœ@œ&˜hKšœœ)˜2K˜—Kšœœœ˜K˜šœœ˜6Kšœ œ˜Kšœ˜Kšœ˜Kšœœ˜—KšœB˜Bšœ3œœ˜HK˜"Kšœ œ!˜.Kšœ œG˜SKšœ"˜"Kšœ˜—šœAœ œ˜ZKšœ,˜,Kšœ œ+˜8Kšœ œh˜tKšœ=˜=Kšœ)œœG˜“K™:Kšœ"˜"Kšœ˜—Kšœ œU˜{Kšœ œ4˜?Kšœœ$œœ˜5K˜—K˜—K˜"Kšœ#˜#Kšœ7˜7Kšœœœ˜"Kšœ!˜!˜K˜——š ž œœœ*œ œ ˜bKšœœœ˜Kšœœ ˜1Kšœ œ&˜5Kšœ œ˜?Kšœœ˜;Kšœœg˜pKšœœa˜jKšœ œœ˜$K˜K˜—šžœœLœ œ)˜คKšœ ˜ Kšœ ˜ Kšœ:˜:Kšœ:˜:K˜K˜—šžœœ;œ œ)˜‘šœœ ˜,Kšœ6œ˜Kšœ ˜ Kšœ˜Kšœ ˜ Kšœœ˜—Kšœ˜—Kšœœœ ˜(Kšœ˜—šž œœ˜*Kšœœœ˜BK˜—Kšœœœœ˜5K˜"Kšœœ˜K˜Kšœ˜K˜K˜—š žœœœœœ˜Jšžœœœ˜6Kšœ œœ˜!šœ œœœ˜;Kšœœ˜Kšœ œ ˜Kšœœ!œœ˜2Kšœœ˜šœ ˜Kšœœ˜4Kšœ'˜'Kšœœ˜šœœœ˜$Kšœ˜Kšœ%˜%Kšœœ˜—Kšœ˜Kšœ$˜$Kšœœ˜6Kšœ˜—Kšœœ˜šœ ˜Kšœœ#œ)˜cKšœ˜—Kšœœ˜šœ œœ˜&Kšœ˜Kšœ"˜"Kšœ˜Kšœœ˜—Kšœ˜—Kšœ˜—šž œœœ˜1Kšœ œœ˜2K˜—Kšœœœœ˜3K˜"Kšœ˜Kšœ˜K˜K˜———™ šžœœœœ˜AK™4K™DKšœœœ˜?Kšœ˜šœ3œœ˜HK˜"šœœ˜4Kš œ œœœœœ ˜RKš œœœœœ˜CKšœ˜Kšœœ˜—Kšœœ˜Kšœœ˜Kšœœ˜Kšœœ˜Kšœ˜—šœAœ œ˜ZKšœ,˜,šœœ˜4Kšœ œ˜Kš œœœœœ˜KKšœ˜Kšœœ˜—Kš œœœœœŸJ˜•šœœ˜ Kšœœ˜Kšœœ˜šœœœœ˜DKšœ+˜+Kšœœ ˜+Kšœœ ˜+K˜—K˜—šœ˜Kšœœ˜Kšœœ˜šœœœœ˜DKšœ+˜+Kšœœ ˜+Kšœœ ˜+K˜—K˜—Kšœ˜—Kšœ™Kšœ™Kšœ˜Kšœ˜J˜K˜—šžœœœ/˜Jšžœœ=˜Zšœ3œœ˜HKšœ˜Kšœ8˜8KšœJ˜JKšœ˜Kšœ˜—šœAœ œ˜ZKšœ,˜,Kšœœœ˜%Kšœˆ˜ˆKšœ˜—Kšœ˜—Kšœœ˜0Kšœ/˜/K˜K˜—š ž œœœœœ œ ˜OKšœ œ˜#Kšœ&˜&Kšœœ)œœ˜:K˜K˜—K˜+šžœ œ œBœ!œœœ˜ฎKšœ œœ˜!Kšœ#˜#Kšœ7˜7šœ0œœ˜BKšœ,˜,Kšœœ œœœœ%œ_œ5˜ชKšœ œK˜XKšœ œ ˜KšœHœ*˜tšœ œœ˜!Kšœ ˜ Kšœ˜—Kšœ œ˜&Kšœ˜—Kšœc˜cKšœ˜K˜—š žœœœ œœœ˜]Kšœœ œ˜-Kšœ˜K˜K˜——™ Kšœ œ œœ๙˜Ÿš œ œ œœ œœ˜4K˜—Kš œœ œœœœ˜Jšœœœœ œ œ œ œ œ œ œ œ œ œ ˜ผK˜—Kšœ œ&˜4Kšœ œ œœ+˜Qš œ œ œœ œœ˜4K˜—šž œœ˜Kšœœ œ˜2Kšœ&˜&šœœ ˜"šœœ˜5Kšœ,œ˜0Kšœ˜—Kšœ˜—šœœ ˜"Kšœœ˜6šœœ˜5Kšœ œœ˜!šžœ˜šœœ˜'Kšœœ˜*Kšœ œ ˜Kšœœ"œ"˜]šœ˜Kšœ5˜5Kšœ ˜ —Kšœ œ˜&K˜—K˜—Kšœ9˜9Kš œ œœ@œ#œ ˜ˆšœ˜KšœRœ#˜wKšœS˜SK˜—Kšœ˜—Kšœ˜—šœœ ˜"Kšœœ˜6Kšœ˜—šœœ˜*šœœœ˜Kšœ˜Kšœ˜Kšœ Ÿ-˜9K˜ KšœŸ)˜:Kšœœ˜—šœœ˜5Kšœ„˜„Kšœ˜—Kšœ˜—Kšœ>˜>K˜K˜——Kšœ ˜ K˜Kšœ˜—…—nญ