SoftHdw25D.mesa
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Barth, February 9, 1989 3:54:03 pm PST
DIRECTORY BitOps, CD, CDBasics, CDInstances, CDOps, DABasics
, ImagerSample, PW, Rope, SF;
SoftHdw25D:
CEDAR
PROGRAM
IMPORTS BitOps, CD, CDBasics, CDInstances, CDOps, ImagerSample, PW, SF
EXPORTS
= BEGIN
TileType: TYPE = {MinorArray, BoardTraces, Corner, Clock0, Clock1, RAMEven, RAMOdd, ROMEven, ROMOdd, MuxRDLUToRDEven, MuxRDLUToRDOdd, MuxLURDToLUEven, MuxLURDToLUOdd, Program, Inverter, FlipFlop, OLUToI, OLUToRD, ORDToI, ORDToLU, ORDToL, RToI, LUToLU, LUToI, RDToRD, RDToI, OToP, RDToP, LUToP, LToP, PToI, PToRD, StartStopStateSlow, StartStopStateFast, BoxDecodeToDataPath, SampleMapCount, SampleMapExtension, SampleMapMux, SampleMapRam};
tileNames: ARRAY TileType OF Rope.ROPE ← ["MinorArray", "BoardTraces", "Corner", "Clock0", "Clock1", "RAMEven", "RAMOdd", "ROMEven", "ROMOdd", "MuxRDLUToRDEven", "MuxRDLUToRDOdd", "MuxLURDToLUEven", "MuxLURDToLUOdd", "Program", "Inverter", "FlipFlop", "OLUToI", "OLUToRD", "ORDToI", "ORDToLU", "ORDToL", "RToI", "LUToLU", "LUToI", "RDToRD", "RDToI", "OToP", "RDToP", "LUToP", "LToP", "PToI", "PToRD", "StartStopStateSlow", "StartStopStateFast", "BoxDecodeToDataPath", "SampleMapCount", "SampleMapExtension", "SampleMapMux", "SampleMapRam"];
tileObjects: ARRAY TileType OF CD.Object ← ALL[NIL];
InterconnectTileType: TYPE = TileType[OLUToI..RDToI];
PinTileType: TYPE = TileType[OToP..PToRD];
SoftHdwPgmTileType: TYPE = TileType[MinorArray..PToRD];
SoftHdw25DTileType: TYPE = TileType[StartStopStateSlow..SampleMapRam];
MachineSizes: TYPE = RECORD [sAddressBits, fAddressBits, pixelsPerChunk, bitsPerPixel: INT];
LoadTiles:
PROC = {
design: CD.Design ← PW.OpenDesign["SoftHdwPgm.dale"];
CDOps.SetMutability[design, readonly];
FOR index: TileType
IN SoftHdwPgmTileType
DO
tileObjects[index] ← PW.Get[design, tileNames[index]];
ENDLOOP;
design ← PW.OpenDesign["SoftHdw25D.dale"];
CDOps.SetMutability[design, readonly];
FOR index: TileType
IN SoftHdw25DTileType
DO
tileObjects[index] ← PW.Get[design, tileNames[index]];
ENDLOOP;
};
CreateChip:
PROC [size: DABasics.Position]
RETURNS [object:
CD.Object] = {
minorArray: CD.Object ← tileObjects[MinorArray];
boardTraces: CD.Object ← tileObjects[BoardTraces];
boardTracesSize: DABasics.Position ← CD.InterestSize[boardTraces];
corner: CD.Object ← tileObjects[Corner];
inner: CD.Object ← PW.Array[minorArray, size.x, size.y];
side: CD.Object ← PW.ArrayY[boardTraces, size.y];
middle: CD.Object ← PW.AbutX[side, inner, side];
topBottom: CD.Object ← PW.AbutX[corner, PW.ArrayX[PW.FlipX[PW.Rot90[boardTraces]], size.x], corner];
object ← PW.AbutY[topBottom, middle, topBottom];
};
lambda: INT = 8;
minorSize: INT = 128*lambda;
minorSpace: INT = 24*lambda;
tileWidth: INT = 32*lambda;
tileHeight: INT = 24*lambda;
outputHeight: INT = 20*lambda;
inputHeight: INT = 16*lambda;
tile0: INT = tileWidth + 3*tileHeight;
tile1: INT = tileWidth + 2*tileHeight;
tile2: INT = tileWidth + tileHeight;
tile3: INT = tileWidth;
chunksPerRAM: INT = 8;
bitsPerRAMROMPair: INT = 8;
CreateSampleMap:
PROC [sizes: MachineSizes, position: ImagerSample.Vec, map: ImagerSample.SampleMap]
RETURNS [object:
CD.Object] = {
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]];
};
CreateBox:
PROC [sizes: MachineSizes, box:
SF.Box]
RETURNS [object:
CD.Object] = {
decodeObject: CD.Object ← CreateBoxDecode[sizes, box];
decodeWidth: INT ← CD.InterestSize[decodeObject].x;
il: CD.InstanceList ← NIL;
il ← CONS[CreateInstance[decodeObject, [0, 0]], il];
IF sizes.bitsPerPixel#1 THEN ERROR; -- not yet implemented
FOR dataIndex:
INT
IN [0..sizes.pixelsPerChunk)
DO
x: INT ← decodeWidth + outputHeight + ((dataIndex/4)*minorSize) + ((dataIndex MOD 4)*minorSpace);
il ← CONS[InstantiateProgramTile[[x, tile3 + inputHeight]], il];
IF dataIndex >= (box.min.f MOD sizes.pixelsPerChunk) THEN il ← CONS[InstantiateProgramTile[[x, tile0 + inputHeight]], il];
IF dataIndex < (box.max.f MOD sizes.pixelsPerChunk) THEN il ← CONS[InstantiateProgramTile[[x, tile1 + inputHeight]], il];
ENDLOOP;
object ← PW.CreateCell[il, [0, 0, decodeWidth + ((sizes.pixelsPerChunk+3)/4)*minorSize, minorSize+tileWidth]];
};
CreateBoxDecode:
PROC [sizes: MachineSizes, box:
SF.Box]
RETURNS [object:
CD.Object] = {
slowObject: CD.Object ← CreateStartStop[sizes.sAddressBits, box.min.s, box.max.s, StartStopStateSlow];
slowWidth: INT ← CD.InterestSize[slowObject].x;
fastObject: CD.Object ← CreateStartStop[sizes.fAddressBits, box.min.f/sizes.pixelsPerChunk, box.max.f/sizes.pixelsPerChunk, StartStopStateFast];
fastWidth: INT ← CD.InterestSize[fastObject].x;
il: CD.InstanceList ← NIL;
il ← CONS[CreateInstance[slowObject, [0, 0]], il];
il ← CONS[CreateInstance[fastObject, [slowWidth-tileWidth, 0]], il];
il ← CONS[InstantiateTile[OLUToRD, [slowWidth-tileWidth, tile3]], il];
il ← CONS[CreateInstance[tileObjects[BoxDecodeToDataPath], [slowWidth + fastWidth - 2*tileWidth, 0]], il];
FOR minorIndex:
INT
IN [1..fastWidth/minorSize)
DO
il ← CONS[InstantiateTile[RDToRD, [slowWidth - tileWidth + minorIndex*minorSize, tile3]], il];
ENDLOOP;
IF ((fastWidth/minorSize) MOD 2) = 0 THEN il ← CONS[InstantiateTile[Inverter, [slowWidth + fastWidth - 2*tileWidth, tile3]], il];
object ← PW.CreateCell[il, [0, 0, slowWidth + fastWidth + minorSize - tileWidth, minorSize+tileWidth]];
};
CreateStartStop:
PROC [bits:
INT, start, stop:
INT, logicTile: TileType]
RETURNS [object:
CD.Object] = {
startObject: CD.Object ← CreateDecoder[bits, start];
IF start=stop
THEN {
ERROR; -- single chunk height or width boxes not yet implemented
}
ELSE {
stopObject: CD.Object ← CreateDecoder[bits, stop];
decoder: CD.Object ← PW.AbutY[stopObject, startObject];
il: CD.InstanceList ← NIL;
il ← CONS[CreateInstance[decoder, [0, tileWidth + 2*tileHeight]], il];
il ← CONS[InstantiateTile[logicTile, [minorSize*((bits+1)/2), 0]], il];
object ← PW.CreateCell[il, [0, 0, minorSize*(((bits+1)/2)+1) + tileWidth, minorSize+tileWidth]];
};
};
CreateDecoder:
PROC [bits:
INT, constant:
INT]
RETURNS [object:
CD.Object] = {
il: CD.InstanceList ← NIL;
FOR bitIndex:
INT
IN [0..bits)
DO
adjust: INT ← minorSize*(bitIndex/2) + tileWidth + inputHeight + 2*minorSpace*(bitIndex MOD 2) + (IF BitOps.EBFD[constant, bitIndex, bits] THEN minorSpace ELSE 0);
il ← CONS[InstantiateProgramTile[[adjust, outputHeight]], il];
ENDLOOP;
FOR minorIndex:
INT
IN [1..(bits+1)/2)
DO
x: INT ← minorIndex*minorSize;
il ← CONS[InstantiateTile[OLUToI, [x, 0]], il];
il ← CONS[InstantiateTile[Inverter, [x, 0]], il];
il ← CONS[InstantiateProgramTile[[x+tileWidth, outputHeight]], il];
ENDLOOP;
object ← PW.CreateCell[il, [0, 0, minorSize*((bits+1)/2) + tileWidth, tileHeight]];
};
InstantiateProgramTile:
PROC [position: DABasics.Position]
RETURNS [instance:
CD.Instance] = {
object: CD.Object ← tileObjects[Program];
size: DABasics.Position ← CD.InterestSize[object];
size.x ← size.x/2;
size.y ← size.y/2;
instance ← CreateInstance[object, CDBasics.SubPoints[position, size]];
};
InstantiateTile:
PROC [tile: TileType, position: DABasics.Position, orientation: DABasics.Orientation ← original]
RETURNS [instance:
CD.Instance] = {
object: CD.Object ← tileObjects[tile];
instance ← CreateInstance[object, position, orientation];
};
CreateInstance:
PROC [object:
CD.Object, offset: DABasics.Position, orientation: DABasics.Orientation ← original]
RETURNS [instance:
CD.Instance] = {
base: DABasics.Position ← CD.InterestBase[object];
tbase: DABasics.Position ← CDBasics.MapPoint[base, [[0, 0], orientation]];
toff: DABasics.Position ← CDBasics.SubPoints[offset, tbase];
instance ← CDInstances.NewInst[object, [toff, orientation]];
};
Test:
PROC = {
sizes: MachineSizes ← [10, 8, 8, 1];
myBox: SF.Box ← [[1,1],[9,9]];
chip: CD.Object ← CreateChip[[16, 8]];
decoder: CD.Object ← CreateDecoder[sizes.sAddressBits, 5];
startStop: CD.Object ← CreateStartStop[sizes.sAddressBits, 5, 7, StartStopStateSlow];
boxDecode: CD.Object ← CreateBoxDecode[sizes, myBox];
box: CD.Object ← CreateBox[sizes, myBox];
map: ImagerSample.SampleMap ← ImagerSample.NewSampleMap[box: myBox, bitsPerSample: 1];
sampleMap: CD.Object ← CreateSampleMap[sizes, [1,1], map];
il: CD.InstanceList ← NIL;
il ← CONS[CreateInstance[chip, [-32*lambda,-32*lambda]], il];
il ← CONS[CreateInstance[decoder, [0,tileWidth]], il];
il ← CONS[CreateInstance[startStop, [0,minorSize]], il];
il ← CONS[CreateInstance[boxDecode, [0,2*minorSize]], il];
il ← CONS[CreateInstance[box, [0,3*minorSize]], il];
il ← CONS[CreateInstance[sampleMap, [0,4*minorSize]], il];
[] ← PW.Draw[PW.CreateCell[il]];
};
LoadTiles[];
END.