StructuralComparisonDataStructureImpl.Mesa
Last tweaked by Mike Spreitzer on March 7, 1989 4:28:48 pm PST
DIRECTORY Asserting, CoreStructuralComparison, Histograms, HistogramsOut, IO, RealFns, Rope, StructuralComparisonDataStructure, StructuralComparisonOps, StructuredStreams, UnparserBuffer;
StructuralComparisonDataStructureImpl: CEDAR PROGRAM
IMPORTS Asserting, Histograms, HistogramsOut, IO, RealFns, Rope, StructuralComparisonDataStructure, StructuredStreams, UnparserBuffer
EXPORTS CoreStructuralComparison, StructuralComparisonDataStructure, StructuralComparisonOps
=
BEGIN OPEN CSC:CoreStructuralComparison, StructuralComparisonDataStructure, SS:StructuredStreams, UB:UnparserBuffer;
ViewStats: TYPE ~ REF ViewStatsPrivate;
ViewStatsPrivate: PUBLIC TYPE ~ StructuralComparisonDataStructure.ViewStatsPrivate;
TransistorTolerances: TYPE ~ CSC.TransistorTolerances;
TransistorDim: TYPE ~ CSC.TransistorDim;
TransistorTolerancesPrivate: TYPE ~ CSC.TransistorTolerancesPrivate;
graphIDToRope: PUBLIC GraphDescriptions ← [A: "A", B: "B", Unspecified: "Unspecified"];
wideTransistorTolerances: PUBLIC TransistorTolerances ~ NEW [TransistorTolerancesPrivate ← ALL[[1.0E-6, 1.0E6]]];
tightTransistorTolerances: PUBLIC TransistorTolerances ~ NEW [TransistorTolerancesPrivate ← ALL[[1.0, 1.0]]];
TransistorDimName: PUBLIC ARRAY TransistorDim OF ROPE ← ["length", "width"];
FormatTolerances: PUBLIC PROC [ttols: TransistorTolerances] RETURNS [ROPE] ~ {
Fmt: PROC [dim: TransistorDim] RETURNS [rope: ROPE] ~ {
t: CSC.Tolerance ~ ttols[dim];
IF t.min=1.0/t.max OR t.max=1.0/t.min
THEN rope ← IO.PutFR["%g: %g", [rope[TransistorDimName[dim]]], [real[t.max]]]
ELSE rope ← IO.PutFR["%g: %g..%g", [rope[TransistorDimName[dim]]], [real[t.min]], [real[t.max]]]};
RETURN Fmt[length].Cat[", ", Fmt[width]]};
endOfQ: PUBLIC Vertex ← NEW [VertexRep];
initialNetColor: Color ← 1;
mirrorColor: Color ← 2;
InitialColor: PUBLIC PROC [v: Vertex] RETURNS [initialColor: Color] = {
SELECT v.class FROM
net => initialColor ← initialNetColor;
cell => initialColor ← IF IsMirror[v] THEN mirrorColor ELSE v.type.color;
ENDCASE => ERROR;
initialColor ← FilterColor[initialColor];
};
mergeBreak: Vertex ← NIL;
MergeVertices: PUBLIC PROC [parent: CellType, v1, v2: Vertex] RETURNS [merged, doomed: Vertex] =
BEGIN
MoveToMerged: PROC [e: Edge] = {
e.sides[net].v ← merged;
};
IF v1 = v2 THEN RETURN [v1, NIL];
merged ← v1;
doomed ← v2;
IF merged.deleted OR doomed.deleted THEN ERROR;
IF merged.class # doomed.class THEN ERROR;
IF v1=mergeBreak OR v2=mergeBreak THEN merged ← merged;
doomed.better ← merged;
merged.name ← UnionNames[merged.name, doomed.name];
SELECT merged.class FROM
net => {
EnumerateFullEdges[doomed, MoveToMerged, FALSE];
IF doomed.firstEdge # NIL THEN {
IF merged.lastEdge # NIL THEN merged.lastEdge.sides[net].next ← doomed.firstEdge ELSE merged.firstEdge ← doomed.firstEdge;
merged.lastEdge ← doomed.lastEdge;
doomed.firstEdge.sides[net].prev ← merged.lastEdge;
doomed.firstEdge ← NIL;
doomed.lastEdge ← NIL;
};
};
cell => -- If they're cells, the caller asserts that they are connected identically — i.e., nothing needs to be done but delete the doomed vertex and the edges touching it.-- parent.transCounts.flatTransMerges ← parent.transCounts.flatTransMerges + merged.type.transCounts.flatTransistors;
ENDCASE => ERROR;
DeleteVertex[parent, doomed];
merged.other ← Asserting.Union[merged.other, doomed.other];
END;
UnionNames: PROC [n1, n2: ROPE] RETURNS [un: ROPE] = {
un ← IF n1.Length[] = 0 THEN n2 ELSE IF n2.Length[] = 0 THEN n1 ELSE n1.Cat["|", n2];
};
DeleteVertex: PUBLIC PROC [parent: CellType, v: Vertex] = {
Killit: PROC [e: Edge] = {
RemoveEdge[e];
};
EnumerateFullEdges[v, Killit, FALSE];
v.deleted ← TRUE;
SELECT v.class FROM
cell => parent.cellCount ← parent.cellCount - 1;
net => parent.netCount ← parent.netCount - 1;
ENDCASE => ERROR;
parent.size ← parent.size - 1;
};
RemoveEdge: PUBLIC PROC [e: Edge] = {
FOR dir: VertexClass IN VertexClass DO
[e.sides[dir].v.firstEdge, e.sides[dir].v.lastEdge] ← UnlinkEdge[e.sides[dir].v.firstEdge, e.sides[dir].v.lastEdge, e, dir];
ENDLOOP;
};
UnlinkEdge: PROC [head, tail, e: Edge, dir: VertexClass] RETURNS [newHead, newTail: Edge] = {
newHead ← head; newTail ← tail;
IF e.sides[dir].next # NIL THEN e.sides[dir].next.sides[dir].prev ← e.sides[dir].prev ELSE newTail ← e.sides[dir].prev;
IF e.sides[dir].prev # NIL THEN e.sides[dir].prev.sides[dir].next ← e.sides[dir].next ELSE newHead ← e.sides[dir].next;
};
PrintObject: PROC [to: IO.STREAM, PrintIt: PROC, cond: UB.BreakCondition ← width, sep: ROPENIL] = {
SS.Bp[to, cond, step, sep];
SS.Begin[to];
PrintIt[!UNWIND => SS.End[to]];
SS.End[to];
};
step: NAT ← 3;
PrintCellType: PROC [to: IO.STREAM, ct: CellType] ~ {
NetPrint: PROC ~ {
first: BOOLTRUE;
PerVertex: PROC [v: Vertex] ~ {
IF v.class#net THEN RETURN;
IF first
THEN {first ← FALSE; SS.Bp[to, width, step]}
ELSE {to.PutRope[","]; SS.Bp[to, width, step, " "]};
to.PutRope[v.name];
RETURN};
to.PutRope["wires = ("];
ct.EnumerateParts[PerVertex, FALSE];
to.PutRope[")"];
RETURN};
CellPrint: PROC ~ {
sep: ROPENIL;
PerVertex: PROC [v: Vertex] ~ {
IPrint: PROC ~ {PrintInstance[to, ct, v]};
IF v.class#cell THEN RETURN;
IF sep#NIL THEN to.PutRope[";"];
PrintObject[to, IPrint, width, sep];
sep ← " ";
RETURN};
to.PutRope["components = ("];
ct.EnumerateParts[PerVertex, TRUE];
to.PutRope[")"];
RETURN};
IF NOT SS.IsAnSS[to] THEN to ← SS.Create[UB.NewInittedHandle[[margin: 69, output: [stream[to]]]]];
to.PutF["%g: CellType ~ {", [rope[ct.name]]];
PrintObject[to, NetPrint];
to.PutRope[";"];
PrintObject[to, CellPrint, width, " "];
to.PutRope["}"];
RETURN};
PrintInstance: PROC [to: IO.STREAM, ct: CellType, v: Vertex] ~ {
first: BOOLTRUE;
pi: PortIndex ← 0;
PerEdge: PROC [c: Color, w: Vertex] ~ {
IF first
THEN {first ← FALSE; SS.Bp[to, width, step]}
ELSE {to.PutRope[","]; SS.Bp[to, width, step, " "]};
IF ct.ports[pi].color # c THEN ERROR;
to.PutF["%g(%08x): %g", [rope[ct.ports[pi].name]], [cardinal[c]], [rope[w.name]]];
pi ← pi + 1;
RETURN};
to.PutF["%g: %g[", [rope[v.name]], [rope[ct.name]]];
v.EnumerateEdges[PerEdge, TRUE];
to.PutRope["]"];
IF pi#ct.ports.length THEN ERROR;
RETURN};
factor: REAL ← RealFns.Root[4, 2];
minbin: PUBLIC REAL ← 0.1;
CreateViewStatsPair: PUBLIC PROC RETURNS [vsp: CSC.ViewStatsPair] ~ {
FOR r: CSC.Role IN CSC.Role DO
vsp[r] ← NEW [ViewStatsPrivate ← [ALL[NIL] ]];
FOR g: Generation IN Generation DO
vsp[r].sizeDists[g] ← Histograms.Create2D[iFactor: factor, jFactor: factor, iOffset: minbin, jOffset: minbin, logI: TRUE, logJ: TRUE];
ENDLOOP;
ENDLOOP;
RETURN};
FmtViewStatsPair: PUBLIC PROC [vsp: CSC.ViewStatsPair, roleNames: CSC.RoleNames] RETURNS [ROPE] ~ {
out: IO.STREAM ~ IO.ROS[];
FOR r: CSC.Role IN CSC.Role DO
out.PutRope[roleNames[r]]; out.PutRope["\n"];
out.PutF["Cell types missing transistor counts: %g\n\n", [integer[vsp[r].missingTransistors]] ];
FOR g: Generation IN Generation DO
out.PutF["%g\nMax flat transistors: %g\nMax flat wires: %g\nCell type size distribution: ", [rope[genNames[g]]], [integer[vsp[r].maxFlatTransistors[g]]], [integer[vsp[r].maxFlatWires[g]]]];
HistogramsOut.WriteTo[vsp[r].sizeDists[g], out, TRUE, TRUE];
out.PutRope["\n\n"];
ENDLOOP;
out.PutRope["\n"];
ENDLOOP;
RETURN out.RopeFromROS[]};
genNames: ARRAY Generation OF ROPE ~ ["Original", "Reconciled"];
END.