StructureFromCoreImpl.Mesa
Last Edited by: Spreitzer, April 28, 1986 4:53:52 pm PDT
DIRECTORY Asserting, Basics, Core, CoreClasses, CoreFlat, CoreOps, CoreProperties, CoreStructuralComparison, HashTable, IO, Rope, RopeHash, StructuralComparisonDataStructure, StructureFromCore;
StructureFromCoreImpl: CEDAR PROGRAM
IMPORTS Asserting, CoreClasses, CoreFlat, CoreOps, CoreProperties, HashTable, IO, Rope, RopeHash, StructuralComparisonDataStructure
EXPORTS StructureFromCore
SHARES StructuralComparisonDataStructure =
BEGIN OPEN CC: CoreClasses, CO: CoreOps, CP: CoreProperties, CoreStructuralComparison, StructuralComparisonDataStructure;
implKey: ATOM = $StructureFromCoreImplInstance;
implVal: REF ROPENEW [ROPE ← "New for this one"];
ColorerKey: ATOM = $CoreStructureColorer;
Colorer: TYPE = REF ColorerPrivate;
ColorerPrivate: TYPE = RECORD [
CellTypeColor: PROC [ct: Core.CellType] RETURNS [Color],
ColorPorts: PROC [ct: Core.CellType, SetColor: PROC [Core.Wire, Color]]
Must set the color of each atom of the public wire.
];
wireColorKey: ATOM = CP.RegisterProperty[
$LichenStructureFromCoreImplWireColor,
CP.Props[[CP.propPrint, CP.PropDontPrint]]];
structureFromFlattenedCore: ATOM = CP.RegisterProperty[
$StructureFromFlattenedCore,
CP.Props[[CP.propPrint, CP.PropDontPrint]]];
structureFromUnflattenedCore: ATOM = CP.RegisterProperty[
$StructureFromUnflattenedCore,
CP.Props[[CP.propPrint, CP.PropDontPrint]]];
backHashKey: ATOM = $StructureFromCoreImplCellTypeToBackpointerHashtable;
structureToCore: ATOM = $StructureToCore;
emptyPath: CoreFlat.PackedPath = [];
GetGraph: PUBLIC PROC [cct: Core.CellType, internals, flatten: BOOL] RETURNS [sct: CellType] = {
raw: REF ANY;
colorer: Colorer ← NIL;
backHash: HashTable.Table;
flattenByAnotherName: BOOL = flatten;
structureFromCoreCellType: ATOM = IF flatten THEN structureFromFlattenedCore ELSE structureFromUnflattenedCore;
sct ← NIL;
DO
raw ← CP.GetCellClassProp[cct.class, ColorerKey];
IF raw # NIL THEN WITH raw SELECT FROM
x: Colorer => colorer ← x;
ENDCASE;
raw ← CP.GetCellTypeProp[cct, structureFromCoreCellType];
IF raw # NIL THEN WITH raw SELECT FROM
x: CellType => sct ← IF Asserting.FnVal[implKey, x.otherPublic] = implVal THEN x ELSE NIL;
ENDCASE => sct ← NIL;
IF sct # NIL THEN EXIT;
IF colorer # NIL THEN EXIT;
IF cct.class.recast = NIL THEN EXIT;
cct ← CO.Recast[cct];
ENDLOOP;
IF sct = NIL THEN {
seen: HashTable.Table = HashTable.Create[];
pi: PortIndex ← 0;
DefinePorts: PROC [wire: Core.Wire] RETURNS [subWires: BOOLTRUE, quit: BOOLFALSE] --CO.EachWireProc-- = {
IF wire.size = 0 AND NOT seen.Fetch[wire].found THEN {
name: ROPE = UnionNames[CO.GetFullWireNames[cct.public, wire]];
sct.ports[pi] ← [
name: name,
color: GetWireColor[wire]
];
IF NOT seen.Insert[wire, $T] THEN ERROR;
pi ← pi + 1;
};
};
IF colorer = NIL THEN colorer ← defaultColorer;
sct ← NEW [CellTypeRep ← [
name: GetCellTypeName[cct],
color: FilterColor[colorer.CellTypeColor[cct]],
ports: NEW [PortSeq[CO.WireBits[cct.public]]],
otherPublic: Asserting.AssertFn1[structureToCore, cct, Asserting.AssertFn1[implKey, implVal, NIL]]
]];
CP.PutCellTypeProp[cct, structureFromCoreCellType, sct];
colorer.ColorPorts[cct, SetWireColor];
[] ← CO.VisitWire[cct.public, DefinePorts];
IF pi # sct.ports.length THEN ERROR;
};
IF sct.internalsKnown OR NOT internals THEN RETURN;
sct.internalsKnown ← TRUE;
backHash ← HashTable.Create[hash: HashDescendant, equal: DescendantEqual];
sct.otherPrivate ← Asserting.AssertFn1[backHashKey, backHash, sct.otherPrivate];
{
Prefix: PROC [path: CoreFlat.PackedPath] RETURNS [prefix: ROPE] = {
IF path.length=0 THEN RETURN [NIL];
prefix ← CoreFlat.PathRope[cct, path].Concat["/"];
};
BeforeExpand: PROC [bindings: HashTable.Table, path: CoreFlat.PackedPath, cellType: Core.CellType] = {
DefineInternal: PROC [key, value: REF ANY] RETURNS [quit: BOOLFALSE] --HashTable.EachPairAction-- = {
wb: CoreFlat.WireBind = NARROW[value];
IF wb.wire.size # 0 THEN RETURN;
{dw: DescendantWire = NEW [DescendantWirePrivate ← [wb.path, wb.wire]];
IF NOT backHash.Fetch[dw].found THEN {
iw: Core.Wire = wb.wire;
rct: CC.RecordCellType = NARROW[cellType.data];
name: ROPE = Prefix[dw.path].Concat[UnionNames[CO.GetFullWireNames[rct.internal, iw]]];
v: Vertex = NEW [VertexRep ← [
name: name,
class: net,
other: Asserting.AssertFn1[structureToCore, dw, NIL]
]];
IF NOT backHash.Insert[dw, v] THEN ERROR;
AddPart[sct, v];
};
}};
[] ← bindings.Pairs[DefineInternal];
};
SeeInstance: PROC [bindings: HashTable.Table, path: CoreFlat.PackedPath, instance: CC.CellInstance] RETURNS [flatten: BOOL] = {
flatten ← flattenByAnotherName AND CO.ToBasic[instance.type].class = CC.recordCellClass;
IF flatten THEN RETURN;
{ci: CC.CellInstance = instance;
di: DescendantCellInstance = NEW [DescendantCellInstancePrivate ← [path, ci]];
name: ROPE = Prefix[path].Concat[CC.GetCellInstanceName[ci]];
type: CellType = GetGraph[ci.type, FALSE, FALSE];
v: Vertex = NEW [VertexRep ← [
name: name,
class: cell,
type: type,
other: Asserting.AssertFn1[structureToCore, di, NIL]
]];
pi: PortIndex ← 0;
seen: HashTable.Table = HashTable.Create[];
SeeBinding: PROC [actualWire, publicWire: Core.Wire] RETURNS [subWires: BOOLTRUE, quit: BOOLFALSE] --CO.EachWirePairProc-- = {
pw: Core.Wire = publicWire;
IF pw.size = 0 AND NOT seen.Fetch[pw].found THEN {
awb: CoreFlat.WireBind = NARROW[bindings.Fetch[actualWire].value];
adw: DescendantWire = NEW [DescendantWirePrivate ← [awb.path, awb.wire]];
nv: Vertex = GetStructure[sct, adw];
IF nv = NIL THEN ERROR;
Link[v, nv, type.ports[pi].color];
IF NOT seen.Insert[pw, $T] THEN ERROR;
pi ← pi + 1;
};
};
IF NOT backHash.Insert[di, v] THEN ERROR;
AddPart[sct, v];
[] ← CO.VisitBinding[ci.actual, ci.type.public, SeeBinding];
IF pi # type.ports.length THEN ERROR;
}};
CoreFlat.EnumerateLeaves[cct, SeeInstance, NIL, BeforeExpand, NIL]};
{pi: PortIndex ← 0;
seen: HashTable.Table = HashTable.Create[];
SetPortNet: PROC [wire: Core.Wire] RETURNS [subWires: BOOLTRUE, quit: BOOLFALSE] --CO.EachWireProc-- = {
IF wire.size = 0 AND NOT seen.Fetch[wire].found THEN {
dw: DescendantWire = NEW [DescendantWirePrivate ← [emptyPath, wire]];
nv: Vertex = GetStructure[sct, dw];
IF nv = NIL THEN ERROR;
sct.ports[pi].net ← nv;
IF NOT seen.Insert[wire, $T] THEN ERROR;
pi ← pi + 1;
};
};
[] ← CO.VisitWire[cct.public, SetPortNet];
IF pi # sct.ports.length THEN ERROR;
};
AddMirror[sct];
sct ← sct;
};
ForgetGraph: PUBLIC PROC [sct: CellType] = {
cct: Core.CellType = GetCellType[sct];
EnumerateParts[sct, DestroyVertex, TRUE];
sct^ ← [];
CP.PutCellTypeProp[cct, structureFromFlattenedCore, NIL];
CP.PutCellTypeProp[cct, structureFromUnflattenedCore, NIL];
};
AddPart: PROC [sct: CellType, v: Vertex] = {
v.nextPart ← sct.firstPart;
sct.firstPart ← v;
sct.size ← sct.size + 1};
Link: PROC [cv, nv: Vertex, edgeColor: Color] = {
e: Edge = NEW [EdgeRep ← [
sides: [
net: [v: nv, next: NIL, prev: nv.lastEdge],
cell: [v: cv, next: NIL, prev: cv.lastEdge]],
color: edgeColor]];
IF nv.lastEdge = NIL THEN nv.firstEdge ← e ELSE nv.lastEdge.sides[net].next ← e;
IF cv.lastEdge = NIL THEN cv.firstEdge ← e ELSE cv.lastEdge.sides[cell].next ← e;
nv.lastEdge ← cv.lastEdge ← e;
};
DestroyVertex: PROC [v: Vertex] = {
WHILE v.firstEdge # NIL DO
e: Edge ← v.firstEdge;
v.firstEdge ← e.sides[v.class].next;
e.sides[v.class] ← [NIL, NIL, NIL];
ENDLOOP;
v^ ← [class: v.class];
};
AddMirror: PROC [sct: CellType] = {
v: Vertex = NEW [VertexRep ← [
name: " The Outside World! ",
class: cell,
type: sct,
isMirror: TRUE
]];
sct.mirror ← v;
FOR pi: PortIndex IN [0 .. sct.ports.length) DO
Link[v, sct.ports[pi].net, sct.ports[pi].color];
ENDLOOP;
};
SetWireColor: PROC [wire: Core.Wire, color: Color] = {
CP.PutWireProp[wire, wireColorKey, NEW [Color ← color]];
};
GetWireColor: PROC [wire: Core.Wire] RETURNS [color: Color] = {
rc: REF Color = NARROW[CP.GetWireProp[wire, wireColorKey]];
color ← rc^;
};
GetCellType: PUBLIC PROC [sct: CellType] RETURNS [cct: Core.CellType] = {
cct ← NARROW[Asserting.FnVal[structureToCore, sct.otherPublic]];
};
GetStructure: PUBLIC PROC [sct: CellType, core: Descendant] RETURNS [v: Vertex] = {
backHash: HashTable.Table = NARROW[Asserting.FnVal[backHashKey, sct.otherPrivate]];
v ← NARROW[backHash.Fetch[core].value];
};
GetCore: PUBLIC PROC [v: Vertex] RETURNS [core: Descendant] = {
core ← Asserting.FnVal[structureToCore, v.other];
};
HashDescendant: PROC [ra: REF ANY] RETURNS [hash: CARDINAL] = {
org: Descendant = ra;
hash ← WITH org SELECT FROM
x: DescendantWire => x.path.PathHash[] + RefHash[x.wire],
x: DescendantCellInstance => x.path.PathHash[] + RefHash[x.instance],
ENDCASE => ERROR;
};
DescendantEqual: PROC [r1, r2: REF ANY] RETURNS [equal: BOOL] = {
o1: Descendant = r1;
o2: Descendant = r2;
equal ← WITH o1 SELECT FROM
x: DescendantWire => WITH o2 SELECT FROM
y: DescendantWire => x.path.PathEqual[y.path] AND x.wire = y.wire,
ENDCASE => FALSE,
x: DescendantCellInstance => WITH o2 SELECT FROM
y: DescendantCellInstance => x.path.PathEqual[y.path] AND x.instance = y.instance,
ENDCASE => FALSE,
ENDCASE => ERROR;
};
RefHash: PROC [ra: REF ANY] RETURNS [hash: CARDINAL] = INLINE {
ln: Basics.LongNumber ← [lc[LOOPHOLE[ra]]];
hash ← ln.lo + ln.hi;
};
defaultColorer: Colorer ← NEW [ColorerPrivate ← [DefaultCellTypeColor, DefaultColorPorts]];
DefaultCellTypeColor: PROC [ct: Core.CellType] RETURNS [color: Color] = {
name: ROPECO.GetCellTypeName[ct];
color ← RopeHash.FromRope[name];
};
DefaultColorPorts: PROC [ct: Core.CellType, SetColor: PROC [Core.Wire, Color]] = {
ColorPort: PROC [wire: Core.Wire] RETURNS [subWires: BOOLTRUE, quit: BOOLFALSE] --CO.EachWireProc-- = {
IF wire.size = 0 THEN {
name: ROPE = UnionNames[CO.GetFullWireNames[ct.public, wire]];
SetColor[wire, RopeHash.FromRope[name]];
};
};
[] ← CO.VisitWire[ct.public, ColorPort];
};
transistorColorer: Colorer ← NEW [ColorerPrivate ← [TransistorCellTypeColor, ColorTransistorPorts]];
TransistorCellTypeColor: PROC [ct: Core.CellType] RETURNS [color: Color] = {
td: CC.Transistor = NARROW[ct.data];
color ← SELECT td.type FROM
nE => 36,
pE => 24,
nD => 33,
ENDCASE => ERROR;
};
ColorTransistorPorts: PROC [ct: Core.CellType, SetColor: PROC [Core.Wire, Color]] = {
ColorPort: PROC [wire: Core.Wire] RETURNS [subWires: BOOLTRUE, quit: BOOLFALSE] --CO.EachWireProc-- = {
IF wire.size = 0 THEN {
name: ROPE = CO.GetShortWireName[wire];
SetColor[wire, SELECT TRUE FROM
name.Substr[len: 2].Equal["ch", FALSE] => channelColor,
name.Equal["gate", FALSE] => gateColor,
ENDCASE => ERROR
];
};
};
[] ← CO.VisitWire[ct.public, ColorPort];
};
gateColor: Color ← 47;
channelColor: Color ← 834;
UnionNames: PROC [names: LIST OF ROPE] RETURNS [unioned: ROPE] = {
unioned ← NIL;
FOR names ← names, names.rest WHILE names # NIL DO
unioned ← IF unioned=NIL THEN names.first ELSE Rope.Cat[unioned, "|", names.first];
ENDLOOP;
unioned ← unioned;
};
GetCellTypeName: PROC [cct: Core.CellType] RETURNS [name: ROPE] = {
IF (name ← CO.GetCellTypeName[cct]).Length[] # 0 THEN RETURN;
cct ← CO.ToBasic[cct];
IF (name ← CO.GetCellTypeName[cct]).Length[] # 0 THEN RETURN;
WITH cct.data SELECT FROM
t: CC.Transistor => {
name ← IO.PutFR[
"%g(%g/%g)",
[rope[SELECT t.type FROM
nE => "nE",
pE => "pE",
nD => "nD",
ENDCASE => ERROR]],
[integer[t.length]],
[integer[t.width]]];
[] ← CO.SetCellTypeName[cct, name];
};
ENDCASE => name ← IO.PutFR["%xB^", [cardinal[LOOPHOLE[cct]]]];
};
Start: PROC = {
CP.PutCellClassProp[CC.transistorCellClass, ColorerKey, transistorColorer];
};
Start[];
END.