Hack.mesa
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Barth, September 11, 1989 5:40:31 pm PDT
DIRECTORY Histograms, HistogramsViewing, RefTab, RefTabImpl, SoftHdwCompiler;
Hack: CEDAR PROGRAM
IMPORTS RefTab, Histograms, HistogramsViewing
SHARES RefTabImpl
= BEGIN
CountChain: PROC [table: RefTabImpl.Impl, index: CARDINAL] RETURNS [count: INT ← 0] = {
FOR node: RefTabImpl.Node ← table.data[index], node.next UNTIL node=NIL DO
count ← count + 1;
ENDLOOP;
};
CountPrimitives: PROC [sinks: SoftHdwCompiler.Primitives] RETURNS [count: INT ← 0] = {
FOR sl: SoftHdwCompiler.Primitives ← sinks, sl.rest UNTIL sl=NIL DO
count ← count+1;
ENDLOOP;
};
HistogramRefTab: PROC [table: RefTabImpl.Impl] = {
h: Histograms.Histogram ← Histograms.Create1D[];
FOR index: CARDINAL IN [0..table.data.max) DO
size: INT ← CountChain[table, index];
Histograms.Change[h, index, size];
ENDLOOP;
[] ← HistogramsViewing.Show[h];
};
HistogramConnectionCount: PROC [wireMap: RefTab.Ref] = {
DoAWire: RefTab.EachPairAction = {
p: SoftHdwCompiler.Primitive ← NARROW[val];
sinks: INT ← CountPrimitives[p.sinks];
Histograms.Change[h, sinks, 1];
};
h: Histograms.Histogram ← Histograms.Create1D[];
[] ← RefTab.Pairs[wireMap, DoAWire];
[] ← HistogramsViewing.Show[h];
};
HistogramSlack: PROC [network: SoftHdwDelayPath.DelayNetwork] = {
DoAWire: RefTab.EachPairAction = {
p: SoftHdwCompiler.Primitive ← NARROW[val];
sinks: INT ← 0;
FOR sl: SoftHdwCompiler.Primitives ← p.sinks, sl.rest UNTIL sl=NIL DO
sinks ← sinks+1;
ENDLOOP;
Histograms.Change[h, sinks, 1];
};
h: Histograms.Histogram ← Histograms.Create1D[];
primDone: RefTab.Ref ← RefTab.Create[];
SoftHdwDelayPath.ComputeSlack[network];
FOR el: SoftHdwDelayPath.DelayEvents ← network.allDelayEvents, el.rest UNTIL el=NIL DO
event: SoftHdwDelayPath.DelayEvent ← el.first;
IF NOT event.primaryInput THEN {
primitive: SoftHdwCompiler.Primitive ← NARROW[event.
Histograms.Change[h, slack, 1];
};
ENDLOOP;
[] ← HistogramsViewing.Show[h];
};
HistogramGroupSize: PROC [flatCell: SoftHdwCompiler.FlatCell] = {
DoAWire: RefTab.EachPairAction = {
p: SoftHdwCompiler.Primitive ← NARROW[val];
IF p.sinks#NIL AND p.sinks.rest=NIL THEN {
IF RootPrimitive[primitiveMap, p.sinks.first]#p THEN {
IF NOT RefTab.Insert[primitiveMap, p, p.sinks.first] THEN ERROR;
};
};
};
CountGroup: RefTab.EachPairAction = {
p: SoftHdwCompiler.Primitive ← NARROW[val];
root: SoftHdwCompiler.Primitive ← RootPrimitive[primitiveMap, p];
count: REF INTNIL;
IF root=NIL THEN root ← p;
count ← NARROW[RefTab.Fetch[primitiveCount, root].val];
IF count=NIL THEN {
count ← NEW[INT];
count^ ← 0;
IF NOT RefTab.Insert[primitiveCount, root, count] THEN ERROR;
};
count^ ← count^ + 1;
};
HistogramGroup: RefTab.EachPairAction = {
count: REF INTNARROW[val];
Histograms.Change[h, count^, count^];
};
h: Histograms.Histogram ← Histograms.Create1D[];
primitiveMap: RefTab.Ref ← RefTab.Create[];
primitiveCount: RefTab.Ref ← RefTab.Create[];
[] ← RefTab.Pairs[flatCell.wires, DoAWire];
[] ← RefTab.Pairs[flatCell.wires, CountGroup];
[] ← RefTab.Pairs[primitiveCount, HistogramGroup];
[] ← HistogramsViewing.Show[h];
};
HistogramGroupSizeMultiple: PROC [flatCell: SoftHdwCompiler.FlatCell] = {
DoAWire: RefTab.EachPairAction = {
p: SoftHdwCompiler.Primitive ← NARROW[val];
sinks: INT ← CountPrimitives[p.sinks];
IF sinks>1 AND sinks<5 THEN {
outputRoot: SoftHdwCompiler.Primitive ← RootPrimitive[primitiveMap, p];
FOR pl: SoftHdwCompiler.Primitives ← p.sinks, pl.rest UNTIL pl=NIL DO
inputRoot: SoftHdwCompiler.Primitive ← RootPrimitive[primitiveMap, pl.first];
IF outputRoot#inputRoot THEN {
IF NOT RefTab.Insert[primitiveMap, outputRoot, inputRoot] THEN ERROR;
outputRoot ← inputRoot;
};
ENDLOOP;
};
};
CountGroup: RefTab.EachPairAction = {
p: SoftHdwCompiler.Primitive ← NARROW[val];
root: SoftHdwCompiler.Primitive ← RootPrimitive[primitiveMap, p];
count: REF INTNIL;
IF root=NIL THEN root ← p;
count ← NARROW[RefTab.Fetch[primitiveCount, root].val];
IF count=NIL THEN {
count ← NEW[INT];
count^ ← 0;
IF NOT RefTab.Insert[primitiveCount, root, count] THEN ERROR;
};
count^ ← count^ + 1;
};
HistogramGroup: RefTab.EachPairAction = {
count: REF INTNARROW[val];
Histograms.Change[h, count^, count^];
};
h: Histograms.Histogram ← Histograms.Create1D[];
primitiveMap: RefTab.Ref ← RefTab.Create[];
primitiveCount: RefTab.Ref ← RefTab.Create[];
[] ← RefTab.Pairs[flatCell.wires, DoAWire];
[] ← RefTab.Pairs[flatCell.wires, CountGroup];
[] ← RefTab.Pairs[primitiveCount, HistogramGroup];
[] ← HistogramsViewing.Show[h];
};
RootPrimitive: PROC [primitiveMap: RefTab.Ref, primitive: SoftHdwCompiler.Primitive] RETURNS [rootPrimitive: SoftHdwCompiler.Primitive] = {
rootPrimitive ← NARROW [RefTab.Fetch[primitiveMap, primitive].val];
IF rootPrimitive=NIL THEN RETURN [primitive];
rootPrimitive ← RootPrimitive[primitiveMap, rootPrimitive];
[] ← RefTab.Replace[primitiveMap, primitive, rootPrimitive];
};
Orientation: TYPE = REF OrientationType;
OrientationType: TYPE = {vertical, horizontal, ambiguous};
CountEvenOdd: PROC [flatCell: SoftHdwCompiler.FlatCell] RETURNS [vertical, horizontal, ambiguous, ambiguousMultipleSinks: INT ← 0] = {
Inverse: PROC [curr: OrientationType] RETURNS [inverse: OrientationType] = {
inverse ← SELECT curr FROM
vertical => horizontal,
horizontal => vertical,
ambiguous => current,
ENDCASE => ERROR;
};
SetOrientation: PROC [p: SoftHdwCompiler.Primitive, c: OrientationType] RETURNS[new: BOOLFALSE] = {
o: Orientation ← NARROW[RefTab.Fetch[primitiveOrientation, p].val];
IF o=NIL THEN {
o ← NEW[OrientationType];
o^ ← c;
IF NOT RefTab.Insert[primitiveOrientation, p, o] THEN ERROR;
new ← TRUE;
}
ELSE IF o^#c THEN o^ ← ambiguous;
};
DoAWire: RefTab.EachPairAction = {
p: SoftHdwCompiler.Primitive ← NARROW[val];
IF NOT RefTab.Fetch[primitiveOrientation, p].found THEN {
toVisit: SoftHdwCompiler.Primitives ← LIST[p];
IF NOT SetOrientation[p, current] THEN ERROR;
current ← Inverse[current];
UNTIL toVisit=NIL DO
SetPrim: PROC [prim: SoftHdwCompiler.Primitive] = {
IF prim#NIL THEN IF SetOrientation[prim, c] THEN toVisit ← CONS[prim, toVisit];
};
prim: SoftHdwCompiler.Primitive ← toVisit.first;
c: OrientationType ← Inverse[NARROW[RefTab.Fetch[primitiveOrientation, prim].val, Orientation]^];
toVisit ← toVisit.rest;
FOR i: NAT IN [0..prim.size) DO
SetPrim[prim[i].source];
ENDLOOP;
FOR sinks: SoftHdwCompiler.Primitives ← prim.sinks, sinks.rest UNTIL sinks=NIL DO
SetPrim[sinks.first];
ENDLOOP;
ENDLOOP;
};
};
CountOrientations: RefTab.EachPairAction = {
p: SoftHdwCompiler.Primitive ← NARROW[key];
o: Orientation ← NARROW[val];
SELECT o^ FROM
vertical => vertical ← vertical + 1;
horizontal => horizontal ← horizontal + 1;
ambiguous => {
ambiguous ← ambiguous + 1;
IF p.sinks#NIL AND p.sinks.rest#NIL THEN ambiguousMultipleSinks ← ambiguousMultipleSinks + 1;
};
ENDCASE => ERROR;
};
primitiveOrientation: RefTab.Ref ← RefTab.Create[];
current: OrientationType ← vertical;
[] ← RefTab.Pairs[flatCell.wires, DoAWire];
[] ← RefTab.Pairs[primitiveOrientation, CountOrientations];
};
END.