DIRECTORY CD, BitmapViewers, BitOps, Imager, ImagerPixel, ImagerSample, Rope, SF, SoftHdwAssembly, SoftHdwRaster, SoftHdwSimulate, ViewerClasses; SoftHdwRasterImpl: CEDAR PROGRAM IMPORTS BitmapViewers, BitOps, ImagerPixel, ImagerSample, SoftHdwAssembly, SoftHdwSimulate EXPORTS SoftHdwRaster = BEGIN OPEN SoftHdwAssembly, SoftHdwRaster; RasterTileType: TYPE = {StartStopStateSlow, StartStopStateFast, BoxDecodeToDataPath, FullAdder}; rasterTileNames: ARRAY RasterTileType OF Rope.ROPE _ ["StartStopStateSlow", "StartStopStateFast", "BoxDecodeToDataPath", "FullAdder"]; rasterPrograms: ARRAY RasterTileType OF Program _ ALL[NIL]; rasterBaseSizes: ArrayPosition _ NEW[ArrayPositionRec _ [ chip: [1, 1], minorArray: [16, 6], grain: [4, 4]]]; LoadTiles: PROC = { design: CD.Design _ OpenDesign["SoftHdwRaster.dale"]; FOR index: RasterTileType IN RasterTileType DO rasterPrograms[index] _ LoadTile[design, rasterTileNames[index]]; ENDLOOP; }; CreateHi: PUBLIC PROC [sizes: MachineSizes] RETURNS [program: Program] = { ConnectAddress: PROC [minorY: INT, minorXOffset: INT, bits: INT] = { FOR index: INT IN [0..2*bits) DO xGrain: INT _ index MOD 4; xMinorArray: INT _ minorXOffset + (index/4); tl _ CTI[old: tl, type: RDToI, orientation: Vertical, grain: [xGrain, 0], minorArray: [xMinorArray, minorY]]; tl _ CTI[old: tl, type: RDToRD, orientation: Vertical, grain: [xGrain, 0], minorArray: [xMinorArray, minorY]]; IF (minorY MOD 2) = 0 THEN tl _ CTI[old: tl, type: Inverter, orientation: Vertical, grain: [xGrain, 0], minorArray: [xMinorArray, minorY]]; ENDLOOP; }; hLeft: Program _ CreateBox[sizes, [[50,50],[200,60]]]; hBar: Program _ CreateBox[sizes, [[125,50],[135,100]]]; hRight: Program _ CreateBox[sizes, [[50,100],[200,110]]]; iTop: Program _ CreateBox[sizes, [[50,150],[60,200]]]; iPost: Program _ CreateBox[sizes, [[50,170],[200,180]]]; iBottom: Program _ CreateBox[sizes, [[190,150],[200,200]]]; decodeWidth: INT _ Size[hLeft].x-(sizes.pixelsPerChunk+3)/4; pl: ProgramInstances _ NIL; tl: ArrayPositions _ NIL; pl _ CPI[old: pl, program: hLeft, minorArray: [0, 0]]; pl _ CPI[old: pl, program: hBar, minorArray: [0, 1]]; pl _ CPI[old: pl, program: hRight, minorArray: [0, 2]]; pl _ CPI[old: pl, program: iTop, minorArray: [0, 3]]; pl _ CPI[old: pl, program: iPost, minorArray: [0, 4]]; pl _ CPI[old: pl, program: iBottom, minorArray: [0, 5]]; FOR minorYIndex: INT IN [1..6) DO ConnectAddress[minorYIndex, 0, sizes.sAddressBits]; ConnectAddress[minorYIndex, ((sizes.sAddressBits+1)/2)+1, sizes.fAddressBits]; FOR dataIndex: INT IN [0..sizes.pixelsPerChunk) DO xGrain: INT _ dataIndex MOD 4; xMinorArray: INT _ decodeWidth + (dataIndex/4); tl _ CTI[old: tl, type: OLUToI, orientation: Vertical, grain: [xGrain, 0], minorArray: [xMinorArray, minorYIndex]]; tl _ CTI[old: tl, type: Inverter, orientation: Vertical, grain: [xGrain, 0], minorArray: [xMinorArray, minorYIndex]]; tl _ CTI[old: tl, type: ParallelInput, orientation: Vertical, grain: [xGrain, 0], minorArray: [xMinorArray, minorYIndex]]; ENDLOOP; ENDLOOP; program _ Create[sizes: rasterBaseSizes, instances: pl, tiles: tl]; }; CreateBox: PUBLIC PROC [sizes: MachineSizes, box: SF.Box] RETURNS [program: Program] = { decodeProgram: Program _ CreateBoxDecode[sizes, box]; decodeWidth: INT _ Size[decodeProgram].x; pl: ProgramInstances _ NIL; tl: ArrayPositions _ NIL; pl _ CPI[old: pl, program: decodeProgram, minorArray: [0, 0]]; IF sizes.bitsPerPixel#1 THEN ERROR; -- not yet implemented FOR dataIndex: INT IN [0..sizes.pixelsPerChunk) DO xGrain: INT _ dataIndex MOD 4; xMinorArray: INT _ decodeWidth + (dataIndex/4); tl _ CTI[old: tl, type: InputEnabled, orientation: Vertical, grain: [xGrain, 2], minorArray: [xMinorArray, 0]]; IF dataIndex >= (box.min.f MOD sizes.pixelsPerChunk) THEN tl _ CTI[old: tl, type: InputEnabled, orientation: Vertical, grain: [xGrain, 0], minorArray: [xMinorArray, 0]]; IF dataIndex < (box.max.f MOD sizes.pixelsPerChunk) THEN tl _ CTI[old: tl, type: InputEnabled, orientation: Vertical, grain: [xGrain, 1], minorArray: [xMinorArray, 0]]; ENDLOOP; FOR minorIndex: INT IN [1..(sizes.pixelsPerChunk+3)/4) DO FOR grain: INT IN [0..2] DO tl _ CTI[old: tl, type: RDToRD, orientation: Horizontal, grain: [0, grain], minorArray: [minorIndex+decodeWidth, 0]]; tl _ CTI[old: tl, type: RDToI, orientation: Horizontal, grain: [0, grain], minorArray: [minorIndex+decodeWidth, 0]]; IF (minorIndex MOD 2) = 1 THEN tl _ CTI[old: tl, type: Inverter, orientation: Horizontal, grain: [0, grain], minorArray: [minorIndex+decodeWidth, 0]]; ENDLOOP; ENDLOOP; program _ Create[sizes: rasterBaseSizes, instances: pl, tiles: tl]; }; CreateBoxDecode: PROC [sizes: MachineSizes, box: SF.Box] RETURNS [program: Program] = { slowProgram: Program _ CreateStartStop[sizes.sAddressBits, box.min.s, box.max.s, rasterPrograms[StartStopStateSlow]]; slowSize: INT _ Size[slowProgram].x; fastProgram: Program _ CreateStartStop[sizes.fAddressBits, box.min.f/sizes.pixelsPerChunk, box.max.f/sizes.pixelsPerChunk, rasterPrograms[StartStopStateFast]]; fastSize: INT _ Size[fastProgram].x; abut: Program _ AbutX[slowProgram, fastProgram, rasterPrograms[BoxDecodeToDataPath]]; pl: ProgramInstances _ NIL; tl: ArrayPositions _ NIL; pl _ CPI[old: pl, program: abut, minorArray: [0, 0]]; tl _ CTI[old: tl, type: OLUToRD, orientation: Horizontal, grain: [0, 3], minorArray: [slowSize, 0]]; FOR minorIndex: INT IN [1..fastSize-1) DO tl _ CTI[old: tl, type: RDToRD, orientation: Horizontal, grain: [0, 3], minorArray: [minorIndex+slowSize, 0]]; ENDLOOP; IF (sizes.fAddressBits MOD 2) = 0 THEN tl _ CTI[old: tl, type: Inverter, orientation: Horizontal, grain: [0, 3], minorArray: [slowSize+fastSize, 0]]; program _ Create[sizes: rasterBaseSizes, instances: pl, tiles: tl]; }; CreateStartStop: PROC [bits: INT, start, stop: INT, logicProgram: Program] RETURNS [program: Program] = { startProgram: Program _ CreateDecoder[bits, start, 0]; IF start=stop THEN { ERROR; -- single chunk height or width boxes not yet implemented } ELSE { stopProgram: Program _ CreateDecoder[bits, stop, 1]; pl: ProgramInstances _ NIL; pl _ CPI[old: pl, program: startProgram, minorArray: [0, 0]]; pl _ CPI[old: pl, program: stopProgram, minorArray: [0, 0]]; pl _ CPI[old: pl, program: logicProgram, minorArray: [(bits+1)/2, 0]]; program _ Create[sizes: rasterBaseSizes, instances: pl]; }; }; CreateDecoder: PROC [bits: INT, constant: INT, grainY: INT] RETURNS [program: Program] = { tl: ArrayPositions _ NIL; FOR bitIndex: INT IN [0..bits) DO tl _ CTI[old: tl, type: InputEnabled, orientation: Horizontal, grain: [2*(bitIndex MOD 2) + (IF BitOps.EBFD[constant, bitIndex, bits] THEN 1 ELSE 0), grainY], minorArray: [bitIndex/2, 0]]; ENDLOOP; FOR minorIndex: INT IN [0..((bits+1)/2)-1) DO tl _ CTI[old: tl, type: OLUToI, orientation: Horizontal, grain: [0, grainY], minorArray: [minorIndex+1, 0]]; tl _ CTI[old: tl, type: Inverter, orientation: Horizontal, grain: [0, grainY], minorArray: [minorIndex+1, 0]]; tl _ CTI[old: tl, type: ParallelInput, orientation: Horizontal, grain: [0, grainY], minorArray: [minorIndex+1, 0]]; ENDLOOP; program _ Create[sizes: rasterBaseSizes, tiles: tl]; }; CreateSampleMap: PUBLIC PROC [sizes: MachineSizes, position: ImagerSample.Vec, map: ImagerSample.SampleMap] RETURNS [program: Program] = { }; Test: PROC = { StoreAddress: PROC [offset: INT, size: INT, value: INT] = { FOR index: INT IN [0..size) DO bit: BOOL _ BitOps.EBFD[value, index, size]; position.minorArray _ [offset + index/addressBitsPerMinorArray, 0]; position.grain _ [2*(index MOD addressBitsPerMinorArray), 0]; position.type _ Input; SoftHdwSimulate.Store[simulation, position, NOT bit]; position.type _ RightDown; SoftHdwSimulate.Store[simulation, position, NOT bit]; position.grain.x _ position.grain.x + 1; position.type _ Input; SoftHdwSimulate.Store[simulation, position, bit]; position.type _ RightDown; SoftHdwSimulate.Store[simulation, position, bit]; ENDLOOP; }; sizes: MachineSizes _ NEW[MachineSizesRec _ [sAddressBits: 8, fAddressBits: 5, pixelsPerChunk: 8, bitsPerPixel: 1]]; addressBitsPerMinorArray: INT _ 2; slowDecodeWidth: INT _ ((sizes.sAddressBits+addressBitsPerMinorArray-1) / addressBitsPerMinorArray) + 1; decodeWidth: INT _ slowDecodeWidth + ((sizes.fAddressBits+addressBitsPerMinorArray-1) / addressBitsPerMinorArray) + 2; program: Program _ CreateHi[sizes]; programHeight: INT _ Size[program].y; simulation: SoftHdwSimulate.Simulation _ SoftHdwSimulate.Create["Box Test", program]; position: ArrayPosition _ NEW[ArrayPositionRec]; rasterDisplay: RasterDisplay _ RasterDisplayCreate[sizes]; position.chip _ [0, 0]; position.orientation _ Vertical; SoftHdwSimulate.Initialize[simulation]; FOR dataIndex: INT IN [0..sizes.pixelsPerChunk) DO position.minorArray _ [decodeWidth + (dataIndex/4), 0]; position.grain _ [dataIndex MOD 4, 0]; position.type _ Input; SoftHdwSimulate.Store[simulation, position, FALSE]; ENDLOOP; FOR sAddress: INT IN [0..BitOps.TwoToThe[sizes.sAddressBits]) DO StoreAddress[0, sizes.sAddressBits, sAddress]; FOR fAddress: INT IN [0..BitOps.TwoToThe[sizes.fAddressBits]) DO StoreAddress[slowDecodeWidth, sizes.fAddressBits, fAddress]; SoftHdwSimulate.Relax[simulation]; SoftHdwSimulate.MasterToSlave[simulation]; SoftHdwSimulate.Relax[simulation]; SoftHdwSimulate.Sample[simulation]; position.type _ Output; FOR dataIndex: INT IN [0..sizes.pixelsPerChunk) DO position.minorArray _ [decodeWidth + (dataIndex/4), programHeight-1]; position.grain _ [dataIndex MOD 4, 0]; RasterDisplayStore[rasterDisplay, [fAddress*sizes.pixelsPerChunk+dataIndex, sAddress], IF SoftHdwSimulate.Fetch[simulation, position] THEN 1 ELSE 0]; ENDLOOP; ENDLOOP; BitmapViewers.Refresh[rasterDisplay.viewer]; ENDLOOP; }; TestFullAdder: PROC = { program: Program _ rasterPrograms[FullAdder]; simulation: SoftHdwSimulate.Simulation _ SoftHdwSimulate.Create["FullAdder Test", program]; position: ArrayPosition _ NEW[ArrayPositionRec]; position.chip _ [0, 0]; position.minorArray.x _ 0; SoftHdwSimulate.Initialize[simulation]; FOR xIndex: INT IN [0..2) DO x: BOOL _ IF xIndex=0 THEN FALSE ELSE TRUE; position.type _ Input; position.orientation _ Vertical; position.grain _ [0, 0]; position.minorArray.y _ 1; SoftHdwSimulate.Store[simulation, position, x]; position.minorArray.y _ 2; SoftHdwSimulate.Store[simulation, position, x]; FOR yIndex: INT IN [0..2) DO y: BOOL _ IF yIndex=0 THEN FALSE ELSE TRUE; position.type _ Input; position.orientation _ Vertical; position.grain _ [1, 0]; position.minorArray.y _ 0; SoftHdwSimulate.Store[simulation, position, y]; position.minorArray.y _ 2; SoftHdwSimulate.Store[simulation, position, y]; FOR cIndex: INT IN [0..2) DO c: BOOL _ IF cIndex=0 THEN FALSE ELSE TRUE; sum: BOOL _ (x AND y AND c) OR (NOT x AND NOT y AND c) OR (NOT x AND y AND NOT c) OR (x AND NOT y AND NOT c); carry: BOOL _ (x AND y) OR (x AND c) OR (y AND c); position.type _ Input; position.orientation _ Horizontal; position.grain _ [0, 0]; position.minorArray.y _ 2; SoftHdwSimulate.Store[simulation, position, NOT c]; SoftHdwSimulate.Relax[simulation]; position.type _ Output; position.orientation _ Vertical; position.grain _ [3, 0]; position.minorArray.y _ 0; IF SoftHdwSimulate.Fetch[simulation, position]#sum THEN ERROR; position.type _ Output; position.orientation _ Horizontal; position.grain _ [0, 0]; position.minorArray.y _ 2; IF NOT SoftHdwSimulate.Fetch[simulation, position]#carry THEN ERROR; ENDLOOP; ENDLOOP; ENDLOOP; }; RasterDisplay: TYPE = REF RasterDisplayRec; RasterDisplayRec: TYPE = RECORD [ viewer: ViewerClasses.Viewer, sampleMap: Imager.SampleMap, bitMap: Imager.PixelMap]; RasterDisplayCreate: PROC [sizes: MachineSizes] RETURNS [rasterDisplay: RasterDisplay] = { rasterDisplay _ NEW[RasterDisplayRec]; rasterDisplay.viewer _ BitmapViewers.CreateBitmapViewer[$SoftHdwRasterViewers, [name: "Soft Hardware Raster"]]; rasterDisplay.sampleMap _ ImagerSample.NewSampleMap[box: [min: SF.zeroVec, max: [BitOps.TwoToThe[sizes.fAddressBits]*sizes.pixelsPerChunk, BitOps.TwoToThe[sizes.sAddressBits]]], bitsPerSample: sizes.bitsPerPixel]; rasterDisplay.bitMap _ ImagerPixel.MakePixelMap[rasterDisplay.sampleMap]; rasterDisplay.viewer.data _ rasterDisplay; }; RasterDisplayStore: PROC [rasterDisplay: RasterDisplay, position: Position, sample: WORD] = { vec: SF.Vec _ [s: position.y, f: position.x]; ImagerSample.Put[rasterDisplay.sampleMap, vec, sample]; }; RasterDisplayNotifier: BitmapViewers.NotifyAdjustmentProc = { vd: BitmapViewers.ViewDescription _ BitmapViewers.Describe[viewer]; IF NOT vd.visible THEN BitmapViewers.SetBitmap[viewer, NIL] ELSE { rasterDisplay: RasterDisplay _ NARROW[viewer.data]; BitmapViewers.SetBitmap[viewer: viewer, bitmap: rasterDisplay.bitMap]; BitmapViewers.Refresh[viewer]; }; }; LoadTiles[]; BitmapViewers.RegisterBitmapViewerClass[$SoftHdwRasterViewers, [], RasterDisplayNotifier]; END. NSoftHdwRasterImpl.mesa Copyright Σ 1989 by Xerox Corporation. All rights reserved. Barth, April 28, 1989 5:48:04 pm PDT RasterTileType: TYPE = {StartStopStateSlow, StartStopStateFast, BoxDecodeToDataPath, SampleMapCount, SampleMapExtension, SampleMapMux, SampleMapRam}; rasterTileNames: ARRAY RasterTileType OF Rope.ROPE _ ["StartStopStateSlow", "StartStopStateFast", "BoxDecodeToDataPath", "SampleMapCount", "SampleMapExtension", "SampleMapMux", "SampleMapRam"]; chunksPerRAM: INT = 8; bitsPerRAMROMPair: INT = 8; EmitRAM: PROC [y: INT] = { FOR index: INT IN [0..sizes.pixelsPerChunk/bitsPerRAMROMPair) DO x: INT _ decodeWidth-tileWidth+2*index*minorSize; il _ CONS[InstantiateTile[SampleMapRam, [x, y]], il]; ENDLOOP; }; box: SF.Box _ SF.Displace[ImagerSample.GetBox[map], position]; widthInChunks: INT _ ((box.max.f-1)/sizes.pixelsPerChunk) - (box.min.f/sizes.pixelsPerChunk) + 1; heightInChunks: INT _ box.max.s-box.min.s; chunkCount: INT _ widthInChunks*heightInChunks; decodeObject: CD.Object _ CreateBoxDecode[sizes, box]; decodeWidth: INT _ CD.InterestSize[decodeObject].x; il: CD.InstanceList _ NIL; IF ImagerSample.GetBitsPerSample[map]#1 THEN ERROR; -- not yet implemented IF sizes.bitsPerPixel#ImagerSample.GetBitsPerSample[map] THEN ERROR; IF (sizes.pixelsPerChunk MOD bitsPerRAMROMPair)#0 THEN ERROR; -- not yet implemented il _ CONS[CreateInstance[decodeObject, [0, 0]], il]; il _ CONS[InstantiateTile[SampleMapCount, [decodeWidth - tileWidth - 7*minorSize, -minorSize]], il]; FOR index: INT IN [0..sizes.pixelsPerChunk/bitsPerRAMROMPair) DO x: INT _ decodeWidth-tileWidth+2*index*minorSize; il _ CONS[InstantiateTile[SampleMapMux, [x, 0]], il]; ENDLOOP; EmitRAM[-minorSize]; FOR index: INT IN [1..(chunkCount/chunksPerRAM)-1] DO y: INT _ -(index+1)*minorSize; il _ CONS[InstantiateTile[SampleMapExtension, [decodeWidth - tileWidth - 4*minorSize, y]], il]; EmitRAM[y]; ENDLOOP; object _ PW.CreateCell[il, [0, -(chunkCount/chunksPerRAM)*minorSize, decodeWidth + ((sizes.pixelsPerChunk+3)/4)*minorSize, minorSize+tileWidth]]; sample: ImagerSample.Sample _ ImagerSample.Get[map, [s, f]]; Raster Display Κ,˜codešœ™K™KšœœO™aKšœœ™*Kšœ œ ™/Kšœœ&™6Kšœ œœ™3Kšœœœ™Kšœ&œœŸ™JKšœ7œœ™DKš œœœœŸ™TKšœœ+™4Kšœœ[™dšœœœ-™@Kšœœ+™1Kšœœ,™5Kšœ™—Kšœ™šœœœ"™5Kšœœ™KšœœV™_Kšœ ™ Kšœ™—Kšœ œ†™‘Kšœ<™Kšœ˜Kšœ"˜"Kšœ˜Kšœ˜Kšœœ3œœ˜DKšœ˜—Kšœ˜—Kšœ˜—K˜K˜—headšœ™Kšœœœ˜+šœœœ˜!Kšœ˜K˜Kšœ˜K˜—šžœœœ#˜ZKšœœ˜&Kšœo˜oKšœ?œ”˜ΥKšœI˜IKšœ*˜*K˜K˜—šžœœ<œ˜]Kšœœ&˜-Kšœ7˜7K˜K˜—šžœ(˜=JšœC˜CJšœœ œ!œ˜;šœ˜Jšœœ˜3KšœF˜FKšœ˜J˜—K˜K˜——Kšœ ˜ KšœZ˜ZK˜Kšœ˜K™—…—2J€