<> <> <> <<>> DIRECTORY Combinatorial, Core, CoreClasses, CoreFlat, CoreIO, CoreOps, CoreProperties, FS, IO, PWCore, RefTab, Rope, TerminalIO; SoftHdwStatsImpl: CEDAR PROGRAM IMPORTS Combinatorial, CoreClasses, CoreFlat, CoreIO, CoreOps, CoreProperties, FS, IO, PWCore, RefTab, Rope, TerminalIO EXPORTS = BEGIN GenerateStats: PROC = { EachFile: FS.NameProc = { root: Core.CellType _ CoreIO.RestoreCellType[fileName: fullFName]; IO.PutRope[stats, "\n"]; IO.PutRope[stats, fullFName]; Leaves[root, stats]; continue _ TRUE; }; stats: IO.STREAM _ FS.StreamOpen["SoftHdwCoreStats.txt", $create]; FS.EnumerateForNames["SoftHdwCore*.core", EachFile]; IO.Close[stats]; }; Leaves: PROC [root: Core.CellType, stats: IO.STREAM] = { CellData: TYPE = REF CellDataRec; CellDataRec: TYPE = RECORD [ layoutAtom: ATOM, count: INT]; FlattenCell: CoreFlat.BoundFlatCellProc = { atom: ATOM _ PWCore.GetLayoutAtom[cell]; SELECT TRUE FROM cell.class=CoreClasses.transistorCellClass => ERROR; atom#NIL AND atom#$SCRemote => { cellName: Rope.ROPE _ CoreOps.GetCellTypeName[cell]; cellData: CellData _ NARROW[RefTab.Fetch[cellDataTable, cell].val]; IF cellData=NIL THEN { cellData: CellData _ NEW[CellDataRec]; cellData.layoutAtom _ atom; cellData.count _ 1; IF NOT RefTab.Insert[cellDataTable, cell, cellData] THEN ERROR; } ELSE cellData.count _ cellData.count + 1; IF Rope.Equal[cellName, "ff"] OR Rope.Equal[cellName, "ffEn"] THEN { clock: Core.Wire _ CoreOps.FindWire[cell.public, "CK"]; flatClock: CoreFlat.FlatWire _ NARROW[RefTab.Fetch[bindings, clock].val]; clockCountRef: REF INT _ NARROW[RefTab.Fetch[clockWireTable, flatClock].val]; IF clockCountRef=NIL THEN { clockCountRef _ NEW[INT _ 1]; IF NOT RefTab.Insert[clockWireTable, flatClock, clockCountRef] THEN ERROR; }; clockCountRef^ _ clockCountRef^ + 1; }; }; ENDCASE => CoreFlat.NextBoundCellType[cell, target, flatCell, instance, index, parent, flatParent, data, bindings, FlattenCell]; }; PrintCell: RefTab.EachPairAction = { cellType: Core.CellType _ NARROW[key]; cellData: CellData _ NARROW[val]; IO.PutF[stats, "\n Cell: %g, atom: %g, count: %g", IO.rope[CoreOps.GetCellTypeName[cellType]], IO.atom[cellData.layoutAtom], IO.int[cellData.count]]; cellCount _ cellCount + cellData.count; }; PrintWire: RefTab.EachPairAction = { flatClock: CoreFlat.FlatWire _ NARROW[key]; clockCountRef: REF INT _ NARROW[val]; IO.PutF[stats, " (%g, %g)", IO.rope[CoreFlat.WirePathRope[root, flatClock^]], IO.int[clockCountRef^]]; }; cellDataTable: RefTab.Ref _ RefTab.Create[]; clockWireTable: RefTab.Ref _ RefTab.Create[hash: CoreFlat.FlatWireHash, equal: CoreFlat.FlatWireEqual]; cellCount: INT _ 0; FlattenCell[cell: root]; IO.PutRope[stats, "\n"]; IO.PutRope[stats, CoreOps.GetCellTypeName[root]]; [] _ RefTab.Pairs[cellDataTable, PrintCell]; IO.PutF[stats, "\n Total cells: %g", IO.int[cellCount]]; IO.PutRope[stats, "\n Clock wires:"]; [] _ RefTab.Pairs[clockWireTable, PrintWire]; IO.PutRope[stats, "\n"]; }; LayoutAtoms: PROC [root: Core.CellType] = { FlattenCell: CoreFlat.BoundFlatCellProc = { atom: ATOM _ PWCore.GetLayoutAtom[cell]; IF atom#NIL THEN [] _ RefTab.Insert[atomTable, atom, atom]; IF cell.class#CoreClasses.transistorCellClass THEN CoreFlat.NextBoundCellType[cell, target, flatCell, instance, index, parent, flatParent, data, bindings, FlattenCell]; }; PrintAtom: RefTab.EachPairAction = { atom: ATOM _ NARROW[key]; TerminalIO.PutF[" %g", IO.atom[atom]]; }; atomTable: RefTab.Ref _ RefTab.Create[]; FlattenCell[cell: root]; TerminalIO.PutRope["\n"]; [] _ RefTab.Pairs[atomTable, PrintAtom]; TerminalIO.PutRope["\n"]; }; PrintCombinatorial: PROC [root: Core.CellType] = { outputs: Core.Wires _ Combinatorial.GetTypedWires[root, output]; TerminalIO.PutF["\n\nCell: %g", IO.rope[CoreOps.GetCellTypeName[root]]]; FOR wires: Core.Wires _ outputs, wires.rest UNTIL wires=NIL DO wire: Core.Wire _ wires.first; TerminalIO.PutF["\n %g: %g", IO.rope[CoreOps.GetFullWireName[root.public, wire]], IO.rope[Combinatorial.GetOutput[wire]]]; ENDLOOP; }; FixSoftHdwCoreB: PROC [root: Core.CellType] = { ParentData: TYPE = REF NAT; Fix: CoreFlat.BoundFlatCellProc = { name: Rope.ROPE _ CoreOps.GetCellTypeName[cell]; SELECT TRUE FROM < {>> <> <> <<};>> Rope.Equal[name, "InvBSeq"] OR Rope.Equal[name, "MuxInvDr"] => { x: Core.Wire _ CoreOps.FindWire[cell.public, "X"]; canonized: CoreFlat.FlatWire _ NARROW[RefTab.Fetch[bindings, x].val]; IF NOT RefTab.Insert[alreadyDriven, canonized, $Driven] THEN { parentData: ParentData _ NARROW[RefTab.Fetch[parentDataTable, parent].val]; IF parentData=NIL THEN { parentData _ NEW[NAT _ 0]; IF NOT RefTab.Insert[parentDataTable, parent, parentData] THEN ERROR; }; { parentRCT: CoreClasses.RecordCellType _ NARROW[parent.data]; newRCT: CoreClasses.RecordCellType _ NEW[CoreClasses.RecordCellTypeRec[parentRCT.size-1]]; adjustedIndex: NAT _ index-parentData^; FOR i: NAT IN [0..adjustedIndex) DO newRCT[i] _ parentRCT[i]; ENDLOOP; FOR i: NAT IN [adjustedIndex..newRCT.size) DO newRCT[i] _ parentRCT[i+1]; ENDLOOP; newRCT.internal _ parentRCT.internal; parent.data _ newRCT; parentData^ _ parentData^ + 1; }; }; CoreProperties.PutCellTypeProp[cell, $Combinatorial, NEW[BOOL _ TRUE]]; Combinatorial.PutOutput[x, "~I"]; }; cell.class=CoreClasses.transistorCellClass OR cell.class=CoreClasses.unspecifiedCellClass => NULL; ENDCASE => CoreFlat.NextBoundCellType[cell, target, flatCell, instance, index, parent, flatParent, data, bindings, Fix]; }; alreadyDriven: RefTab.Ref _ RefTab.Create[hash: CoreFlat.FlatWireHash, equal: CoreFlat.FlatWireEqual]; parentDataTable: RefTab.Ref _ RefTab.Create[]; Fix[cell: root, bindings: CoreFlat.InitialBindingTable[root]]; }; PrintLogicalPrimitives: PROC [root: Core.CellType] = { Walk: CoreFlat.BoundFlatCellProc = { name: Rope.ROPE _ CoreOps.GetCellTypeName[cell]; SELECT TRUE FROM cell.class=CoreClasses.transistorCellClass OR cell.class=CoreClasses.unspecifiedCellClass => ERROR; Combinatorial.IsCombinatorial[cell] OR Combinatorial.IsNonCombinatorial[cell] OR Rope.Equal[name, "ff"] => { count: REF INT _ NARROW[RefTab.Fetch[cellTable, cell].val]; IF count=NIL THEN { count _ NEW[INT _ 0]; IF NOT RefTab.Insert[cellTable, cell, count] THEN ERROR; }; count^ _ count^ + 1; }; ENDCASE => CoreFlat.NextBoundCellType[cell, target, flatCell, instance, index, parent, flatParent, data, bindings, Walk]; }; PrintACell: RefTab.EachPairAction = { cell: Core.CellType _ NARROW[key]; count: REF INT _ NARROW[val]; TerminalIO.PutF["\n Cell: %g, count: %g", IO.rope[CoreOps.GetCellTypeName[cell]], IO.int[count^]]; cellCount _ cellCount + count^; IF Combinatorial.IsCombinatorial[cell] THEN { outputs: Core.Wires _ Combinatorial.GetTypedWires[cell, output]; FOR wires: Core.Wires _ outputs, wires.rest UNTIL wires=NIL DO wire: Core.Wire _ wires.first; TerminalIO.PutF["\n %g: %g", IO.rope[CoreOps.GetFullWireName[cell.public, wire]], IO.rope[Combinatorial.GetOutput[wire]]]; ENDLOOP; }; }; cellTable: RefTab.Ref _ RefTab.Create[]; cellCount: INT _ 0; Walk[root]; TerminalIO.PutRope["\n\n"]; [] _ RefTab.Pairs[cellTable, PrintACell]; TerminalIO.PutF["\n Total cells: %g", IO.int[cellCount]]; }; <> <> <> <> <> <> <<};>> <<>> <> <> <> <> <> <<[] _ RefTab.Insert[oldToNew, old, new];>> <> <<};>> <> <> <> <> <> <> <> <<};>> <> <> <<};>> <<>> <> <> <> <> <<>> <> <> <> <<};>> <<>> <> <> <> <> <<};>> <<>> <> <> <> <> <<};>> <> <> <> <> <> <<[] _ RefTab.Insert[actualTable, actual[i], $Inserted];>> <> <> <> <<[] _ RefTab.Pairs[actualTable, InsertAnInternal];>> <> <<};>> <<>> <> <> <> <> <> <> <> <> < {>> <> <> <<}>> <> <<};>> <<};>> <> <> <> <> <<[] _ RefTab.Pairs[data.oldToNew, CheckPublic];>> <> <> <> <> <> <> <> <> <> <> <<};>> <<>> <> <> <<};>> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> < ERROR;>> < {>> <> <> <<};>> < {>> <> <> <<};>> < {>> <> <> <> <> <> <> <> <<};>> <<};>> <<};>> <> <> <<};>> <<>> END.