RoseDebug.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Barth, March 31, 1987 4:37:45 pm PST
Bertrand Serlet March 18, 1986 3:39:48 pm PST
Louis Monier June 12, 1986 10:01:02 am PDT
Hoel, July 31, 1986 12:18:39 pm PDT
Last Edited by: Louis Monier October 27, 1986 11:45:30 am PST
DIRECTORY Core, CoreClasses, CoreFlat, CoreOps, Commander, IO, ProcessProps, Rosemary;
RoseDebug: CEDAR PROGRAM
IMPORTS CoreFlat, CoreOps, IO, ProcessProps
EXPORTS
= BEGIN OPEN Rosemary;
HackSignal: SIGNAL = CODE;
CorrespondingPublic: PUBLIC PROC [instance: CoreClasses.CellInstance, actual: Core.Wire] RETURNS [public: Core.Wire ← NIL] = {
EachWirePair: CoreOps.EachWirePairProc = {
IF actualWire=actual THEN {public ← publicWire; quit ← TRUE};
};
[] ← CoreOps.VisitBinding[instance.actual, instance.type.public, EachWirePair];
};
← RoseDebug.FindHack[&new.data[0].type.data[49].type, &new.data[0].type.data[49].type.data.internal[11590]]
FindHack: PROC [cellType: Core.CellType, wire: Core.Wire] = {
rct: CoreClasses.RecordCellType ← NARROW[cellType.data];
FOR i: NAT IN [0..rct.size) DO
IF CoreOps.RecursiveMember[rct[i].actual, wire] THEN {
subrct: CoreClasses.RecordCellType ← NARROW[rct[i].type.data];
subWire: Core.Wire ← CorrespondingPublic[rct[i], wire];
FOR j: NAT IN [0..subrct.size) DO
IF CoreOps.RecursiveMember[subrct[j].actual, subWire] THEN GOTO found;
REPEAT found => {
CoreOps.Print[rct[i].type];
SIGNAL HackSignal[];
};
ENDLOOP;
};
ENDLOOP;
};
EUHack: PROC [simulation: Simulation] = {
FindInnerWire: Static.ConnectionCountProc = {
IF count>1000 THEN SIGNAL HackSignal;
};
Static.CountLeafConnections[simulation.cellType, FindInnerWire, CoreFlat.CreateCutSet[labels: LIST[Logic.logicCutSet, Logic.macroCutSet]]];
};
FindBigWires: PROC [simulation: Simulation] = {
FindWire: HashTable.EachPairAction = {
roseWire: RoseWire ← NARROW[value];
IF roseWire.channels# NIL AND roseWire.channels.size>1000 THEN SIGNAL HackSignal;
};
[] ← HashTable.Pairs[table: simulation.coreToRoseWires, action: FindWire];
};
CheckCore: PROC [simulation: Simulation] = {
CheckActual: CoreFlat.EachInstanceProc = {
parent: Core.CellType ← CoreFlat.GetCellType[root: simulation.coreCellType, path: path];
ct: Core.CellType ← instance.type;
rct: CoreClasses.RecordCellType ← NARROW[parent.data];
FOR i: NAT IN [0..instance.actual.size) DO
IF NOT CoreOps.RecursiveMember[rct.internal, instance.actual[i]] THEN ERROR;
ENDLOOP;
DO
IF ct.class#CoreClasses.identityCellClass THEN EXIT;
ct ← NARROW[ct.data];
ENDLOOP;
flatten ← ct.class#Logic.libCellClass AND ct.class#CoreClasses.recordCellClass AND ct.class#CoreClasses.transistorCellClass AND ct.class#CoreClasses.unspecifiedCellClass;
};
CoreFlat.EnumerateLeaves[root: simulation.coreCellType, eachInstance: CheckActual];
};
NeedEval: PROC [simulation: Simulation, out: Core.STREAMNIL] = {
IF out=NIL THEN out ← NARROW[ProcessProps.GetProp[$CommanderHandle], Commander.Handle].out;
IF simulation.perturbed#NIL THEN FOR roseWire: RoseWire ← simulation.perturbed, roseWire.nextPerturbedWire DO
ct: Core.CellType ← CoreFlat.GetCellType[simulation.coreCellType, roseWire.wire.path];
rct: CoreClasses.RecordCellType ← NARROW[ct.data];
IO.PutF[out, "%g ", IO.rope[CoreOps.GetFullWireNames[rct.internal, roseWire.wire.wire].first]];
IF roseWire=simulation.perturbed.previousPerturbedWire THEN EXIT;
ENDLOOP;
};
EnumerateRoseWires: PROC [simulation: Simulation] RETURNS [roseWires: LIST OF RoseWire ← NIL] = {
ConsWires: HashTable.EachPairAction = {
roseWire: RoseWire ← NARROW[value];
roseWires ← CONS[roseWire, roseWires];
};
[] ← HashTable.Pairs[table: simulation.coreToRoseWires, action: ConsWires];
};
MaxConnections: PROC [simulation: Simulation] RETURNS [wires, average, max, total: INT ← 0] = {
CountConnections: HashTable.EachPairAction = {
roseWire: RoseWire ← NARROW[value];
wires ← wires + 1;
total ← total + roseWire.connections.size;
max ← MAX[max, roseWire.connections.size];
};
[] ← HashTable.Pairs[table: simulation.coreToRoseWires, action: CountConnections];
average ← total/wires;
};
FilterXWires: PROC [sourceWires: LIST OF RoseWire] RETURNS [xwires: LIST OF RoseWire ← NIL] = {
FOR roseWires: LIST OF RoseWire ← sourceWires, roseWires.rest UNTIL roseWires=NIL DO
roseWire: RoseWire ← roseWires.first;
IF roseWire.currentValue=NIL THEN {
IF roseWire.wireLevel=X THEN xwires ← CONS[roseWires.first, xwires];
}
ELSE FOR bit: CARDINAL IN [0..roseWire.currentValue.size) DO
IF roseWire.currentValue[bit]=X THEN xwires ← CONS[roseWires.first, xwires];
ENDLOOP;
ENDLOOP;
};
FindCoreWires: PROC [simulation: Simulation, wire: Core.Wire] RETURNS [roseWires: LIST OF RoseWire ← NIL] = {
ConsWires: HashTable.EachPairAction = {
roseWire: RoseWire ← NARROW[value];
IF roseWire.wire.wire=wire THEN roseWires ← CONS[roseWire, roseWires];
};
[] ← HashTable.Pairs[table: simulation.coreToRoseWires, action: ConsWires];
};
RecomputeLoop: PROC [recomputed: RoseWire] RETURNS [BOOLFALSE] = {
saw: HashTable.Table ← HashTable.Create[];
FOR recomputed ← recomputed, recomputed.nextRecomputed UNTIL recomputed=NIL DO
IF NOT HashTable.Insert[saw, recomputed, $Saw] THEN RETURN [TRUE]
ENDLOOP;
saw ← saw;
};
PrintRecompute: PROC [simulation: Simulation, recomputed: RoseWire, out: Core.STREAMNIL] = {
IF out=NIL THEN out ← NARROW [ProcessProps.GetProp[$CommanderHandle], Commander.Handle].out;
FOR recomputed ← recomputed, recomputed.nextRecomputed UNTIL recomputed=NIL DO
IO.PutRope[out, CoreFlat.WirePathRope[simulation.cellType, recomputed.wire]];
IO.PutRope[out, "\n"];
ENDLOOP;
};
PerturbLoop: PROC [simulation: Simulation] RETURNS [BOOLFALSE] = {
sawNext: HashTable.Table ← HashTable.Create[];
sawPrevious: HashTable.Table ← HashTable.Create[];
FOR next: RoseWire ← simulation.perturbed, next.nextPerturbedWire UNTIL next=NIL DO
IF NOT HashTable.Insert[sawNext, next, $Saw] THEN RETURN [TRUE]
ENDLOOP;
FOR previous: RoseWire ← simulation.perturbed, previous.previousPerturbedWire UNTIL previous=NIL DO
IF NOT HashTable.Insert[sawPrevious, previous, $Saw] THEN RETURN [TRUE]
ENDLOOP;
};
Print: PROC [simulation: Simulation, out: Core.STREAMNIL] = {
Drive: PROC [drive: Ports.Drive] RETURNS [IO.Value] = {
RETURN[IO.rope[SELECT drive FROM
expect => "e",
none => "n",
chargeWeak => "cw",
chargeMediumWeak => "cmw",
charge => "c",
chargeMediumStrong => "cms",
chargeStrong => "cs",
force => "f",
driveWeak => "dw",
driveMediumWeak => "dmw",
drive => "d",
driveMediumStrong => "dms",
driveStrong => "ds",
infinite => "i",
ENDCASE => ERROR]];
};
Level: PROC [level: Ports.Level] RETURNS [IO.Value] = {
RETURN[IO.rope[SELECT level FROM
L => "L",
H => "H",
X => "X",
ENDCASE => ERROR]];
};
PrintTransistor: PROC [trans: RoseTransistor] = {
IF trans#NIL THEN IO.PutF[out, "%g%g%g", IO.int[LOOPHOLE[trans]], IO.rope[SELECT trans.type FROM nE => "n", pE => "p", nD => "d", ENDCASE => ERROR], Drive[trans.conductivity]];
};
PrintTransistors: PROC [trans: RoseTransistors] = {
IF trans#NIL THEN FOR t: NAT IN [0..trans.size) DO
IO.PutRope[out, " "];
PrintTransistor[trans[t]];
[] ← HashTable.Insert[table: tranTab, key: trans[t], value: $Transistor];
ENDLOOP;
};
PrintEachTransistor: HashTable.EachPairAction = {
GetWireName: PROC [roseWire: RoseWire] RETURNS [IO.Value] = {
rc: Core.CellType ← CoreFlat.GetCellType[simulation.coreCellType, roseWire.wire.path];
rct: CoreClasses.RecordCellType ← NARROW[rc.data];
RETURN[IO.rope[CoreOps.GetFullWireNames[rct.internal, roseWire.wire.wire].first]];
};
trans: RoseTransistor ← NARROW[key];
quit ← FALSE;
PrintTransistor[trans];
IO.PutF[out, ", gate: %g, ch1: %g, ch2: %g\n", GetWireName[trans.gate], GetWireName[trans.ch1], GetWireName[trans.ch2]];
};
PrintFieldDriveAndVals: PROC [fields: Fields] = {
IF fields#NIL THEN FOR f: NAT IN [0..fields.size) DO
field: Field ← fields[f];
IF field=NIL THEN LOOP;
IF field.portBinding.instance#NIL THEN IO.PutF[out, " %g -", IO.rope[CoreOps.GetCellTypeName[ field.portBinding.instance.instance.instance.type]]]
ELSE IO.PutRope[out, " <unknown> -"];
IO.PutF[out, " fd: %g, fv: %g\n", Drive[field.portBinding.currentDrive], IO.rope[Ports.LevelSequenceToRope[field.currentValue, field.currentValue.size]]];
ENDLOOP;
};
PrintWires: HashTable.EachPairAction = {
roseWire: RoseWire ← NARROW[value];
rc: Core.CellType ← CoreFlat.GetCellType[simulation.coreCellType, roseWire.wire.path];
rct ← NARROW[rc.data];
IF roseWire.currentValue=NIL THEN {
IO.PutFL[out, "%g - cd:%g, sd:%g, ud:%g, dd:%g, wd:%g, cl:%g, wl: %g\n", LIST[IO.rope[CoreOps.GetFullWireNames[rct.internal, roseWire.wire.wire].first], Drive[roseWire.connectionDrive], Drive[roseWire.switchDrive], Drive[roseWire.upDrive], Drive[roseWire.downDrive], Drive[roseWire.wireDrive], Level[roseWire.connectionLevel], Level[roseWire.wireLevel]]];
IO.PutRope[out, " gates:"];
PrintTransistors[roseWire.gates];
IO.PutRope[out, "\n channels:"];
PrintTransistors[roseWire.channels];
IO.PutRope[out, "\n"];
}
ELSE {
ERROR;
};
PrintFieldDriveAndVals[roseWire.connections];
};
tranTab: HashTable.Table ← HashTable.Create[];
rct: CoreClasses.RecordCellType;
IF out=NIL THEN out ← NARROW[ProcessProps.GetProp[$CommanderHandle], Commander.Handle].out;
[] ← HashTable.Pairs[table: simulation.coreToRoseWires, action: PrintWires];
[] ← HashTable.Pairs[tranTab, PrintEachTransistor];
};
END.