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]]; }; END. ςSoftHdwStatsImpl.mesa Copyright Σ 1988 by Xerox Corporation. All rights reserved. Barth, November 10, 1988 5:30:15 pm PST Rope.Equal[name, "VbDr"] => { Combinatorial.MakeCombinatorial[cell]; CoreFlat.NextBoundCellType[cell, target, flatCell, instance, index, parent, flatParent, data, bindings, Fix]; }; Recursive Split MakeNewSeq: PROC [old: Core.WireSeq, oldToNew: RefTab.Ref] RETURNS [new: Core.WireSeq] = { new _ CoreOps.CreateWires[size: old.size]; FOR j: NAT IN [0 .. new.size) DO new[j] _ CoreOps.CopyWireUsingTable[old[j], oldToNew]; ENDLOOP; }; MakeNewSeqFlat: PROC [old: Core.WireSeq, oldToNew: RefTab.Ref, flatCell: CoreFlat.FlatCellTypeRec] RETURNS [new: Core.WireSeq] = { CopyWire: PROC [old: CoreFlat.FlatWire] RETURNS [new: Core.Wire] = { new _ NARROW [RefTab.Fetch[oldToNew, old].val]; IF new#NIL THEN RETURN; new _ CreateWires[size: old.wire.size, name: GetShortWireName[old.wire]]; [] _ RefTab.Insert[oldToNew, old, new]; DoEach[old.wire, new]; }; DoEach: PROC [old, new: Core.Wire] = { FOR i: NAT IN [0 .. old.size) DO flatOld: CoreFlat.FlatWire _ NEW[CoreFlat.FlatWireRec]; flatOld.flatCell _ flatCell; flatOld.wire _ old[i]; new[i] _ CopyWire[flatOld]; ENDLOOP; }; new _ CoreOps.CreateWires[size: old.size]; DoEach[old, new]; }; CellData: TYPE = REF CellDataRec; CellDataRec: TYPE = RECORD [ oldToNew: RefTab.Ref _ NIL, instances: CoreClasses.Instances _ NIL]; MakeCellData: PROC RETURNS [cellData: CellData] = { cellData _ NEW[CellDataRec]; cellData.oldToNew _ RefTab.Create[hash: CoreFlat.FlatWireHash, equal: CoreFlat.FlatWireEqual]; }; AddCell: PROC [data: CellData, instance: CoreClasses.CellInstance, parentFlatCell: CoreFlat.FlatCellTypeRec] = { actual: Core.Wire _ MakeNewSeqFlat[instance.actual, data.oldToNew, parentFlatCell]; new: CoreClasses.CellInstance _ CoreClasses.CreateInstance[actual, instance.type]; data.instances _ CONS[new, data.instances]; }; BuildInternal: PROC [data: CellData] RETURNS [internal: Core.Wire] = { InsertAnInternal: RefTab.EachPairAction = { internal[nextInternal] _ NARROW[key]; nextInternal _ nextInternal + 1; }; actualTable: RefTab.Ref _ RefTab.Create[]; nextInternal: NAT _ 0; FOR instances: CoreClasses.Instances _ data.instances, instances.rest UNTIL instances=NIL DO actual: Core.Wire _ instances.first.actual; FOR i: NAT IN [0..actual.size) DO [] _ RefTab.Insert[actualTable, actual[i], $Inserted]; ENDLOOP; ENDLOOP; internal _ CoreOps.CreateWires[RefTab.Size[actualTable]]; [] _ RefTab.Pairs[actualTable, InsertAnInternal]; IF nextInternal#internal.size THEN ERROR; }; RecursiveReplace: PROC [ MakeInstance: PROC [data: CellData, other, parent: RefTab.Ref] RETURNS [instance: CoreClasses.CellInstance] = { CheckPublic: RefTab.EachPairAction = { old: CoreFlat.FlatWire _ NARROW[key]; new: Core.Wire _ NARROW[val]; IF RefTab.Fetch[other, old].found OR RefTab.Fetch[parent, old].found THEN { FOR w: Core.Wires _ publics, w.rest UNTIL w=NIL DO IF CoreOps.RecursiveMember[w.first, new] THEN EXIT; REPEAT FINISHED => { publics _ CONS[new, publics]; oldPublics _ CONS[old, oldPublics]; } ENDLOOP; }; }; internal: Core.Wire _ BuildInternal[data]; publics: Core.Wires _ NIL; public: Core.Wire; oldPublics: CoreFlat.FlatWires _ NIL; [] _ RefTab.Pairs[data.oldToNew, CheckPublic]; public _ CoreOps.CreateWire[publics]; actual _ CoreOps.CopyWire[public]; FOR nextActual: NAT IN [0..public.size) DO actual[nextActual] _ RecursiveReplace[ ENDLOOP; ct: Core.CellType _ CoreClasses.CreateRecordCell[ public: public, internal: internal, instances: data.instances]; instance _ CoreClasses.CreateInstance[CoreOps.CreateWire[actuals], ct] }; MakeNonCombinatorial: PROC [cell: Core.CellType] = { CoreProperties.PutCellTypeProp[rc, $Combinatorial, NEW [BOOL _ FALSE]]; }; SplitCombinatorialRecursive: PROC [root: Core.CellType] RETURNS [split: Core.CellType] = { SplitOne: PROC [cell: Core.CellType] RETURNS [split _ Core.CellType] = { rc: Core.CellType; IF Combinatorial.IsCombinatorial[cell] OR Combinatorial.IsNonCombinatorial[cell] THEN RETURN [cell]; rc _ CoreOps.ToBasic[cell]; IF (split _ NARROW[RefTab.Fetch[originalToSplit, rc].val])=NIL THEN { allNonComb, allComb: BOOL _ TRUE; rct: CoreClasses.RecordCellType _ NARROW[rc.data]; combs: CellData _ MakeCellData[]; nonCombs: CellData _ MakeCellData[]; parent: CellData _ MakeCellData[]; public: Core.Wire _ MakeNewSeqFlat[rc.public, parent.oldToNew, CoreFlat.rootCellType]; FOR i: NAT IN [0..rct.size) DO BinCell: PROC [cell: Core.CellType] RETURNS [BOOL] = { SELECT TRUE FROM Combinatorial.IsCombinatorial[cell] => { AddCell[combs, rct[i], CoreFlat.rootCellType]; allNonComb _ FALSE; RETURN[FALSE]; }; Combinatorial.IsNonCombinatorial[cell] => { AddCell[nonCombs, rct[i], CoreFlat.rootCellType]; allComb _ FALSE; RETURN[FALSE]; }; cell.class=CoreClasses.transistorCellClass OR cell.class=CoreClasses.unspecifiedCellClass => ERROR; ENDCASE => RETURN[TRUE]; }; subCell: Core.CellType _ rct[i].type; IF BinCell[subCell] THEN { subSplit: Core.CellType _ SplitOne[subCell]; IF BinCell[subSplit] THEN { ssrct: CoreClasses.RecordCellType _ NARROW[subSplit.data]; flatCell: CoreFlat.FlatCellTypeRec _ [CoreFlat.ExtendPath[CoreFlat.nullInstancePath, i, rct], 0]; AddCell[combs, ssrct[0], flatCell]; AddCell[nonCombs, ssrct[1], flatCell]; allNonComb _ FALSE; allComb _ FALSE; }; }; ENDLOOP; SELECT TRUE FROM allComb AND allNonComb => ERROR; allComb => { Combinatorial.MakeCombinatorial[rc]; RETURN[rc]; }; allNonComb => { MakeNonCombinatorial[rc]; RETURN[rc]; }; ENDCASE => { comb: CoreClasses.CellInstance _ MakeInstance[combs]; nonComb: CoreClasses.CellInstance _ MakeInstance[nonCombs]; split _ CoreClasses.CreateRecordCell[ public: public, internal: BuildInternal[parent], instances: LIST [comb, nonComb]]; IF NOT RefTab.Insert[originalToSplit, rc, split] THEN ERROR; }; }; }; originalToSplit: RefTab.Ref _ RefTab.Create[]; split _ SplitOne[root]; }; Κ n– "cedar" style˜codešœ™K™K˜Kšœœ3œ&˜{Kšœ˜—˜K˜——šžœœ˜/Kšœ œœœ˜šžœ ˜#Kšœ œ!˜0šœœ˜šœ™Kšœ&™&Kšœm™mK™—šœœ"˜@K˜2Kšœœ ˜Ešœœ2œ˜>Kšœœ,˜Kšœ œœ˜Kšœ œœ˜Kšœœ4œœ˜EK˜—šœ˜Kšœ(œ˜˜>K˜K˜—šžœœ˜6šžœ ˜$Kšœ œ!˜0šœœ˜Kšœ+œ0œ˜cšœ$œ(œ˜lKšœœœœ$˜;šœœœ˜Kšœœœ˜Kšœœ'œœ˜8K˜—K˜K˜—Kšœr˜y—K˜—šž œ˜%Kšœœ˜"Kšœœœœ˜Kšœ+œ&œ˜cKšœ˜šœ%œ˜-Kšœ@˜@šœ)œœ˜>K˜Kšœ œ3œ&˜}Kšœ˜—K˜—K˜—K˜(Kšœ œ˜Kšœ ˜ K˜K˜)Kšœ'œ˜:K˜K˜—head™šž œœ+œ™ZKšœ*™*šœœœœ™!Kšœ6™6Kšœ™—K™K™—šžœœOœ™‚šžœœœ™DKšœœ#™/Kšœœœœ™KšœI™IKšœ'™'Kšœ™J™—šžœœ™&šœœœ™ Jšœœ™7Jšœ™J™Jšœ™Jšœ™—J™—Kšœ*™*Kšœ™K™K™—Kšœ œœ ™!šœ œœ™Kšœœ™Kšœ#œ™(K™—šž œœœ™3Jšœ œ™Kšœ^™^K™K™—šžœœc™pKšœS™SKšœR™RJšœœ™+K™K™—šž œœœ™Fšžœ™+Kšœœ™%Kšœ ™ K™—K™*Kšœœ™šœCœ œ™\K™+šœœœ™!K™6Kšœ™—Kšœ™—K™9K™1Kšœœœ™)K™K™—K™šž œœ-œ)™ošž œ™&Kšœœ™%Kšœœ™šœ œ!œ™Kšœ!œœ™2Kšœ'œœ™3šœœ™Kšœ œ™Kšœ œ™#K™—Kšœ™—K™—K™—K™*Kšœœ™Kšœ™Kšœ!œ™%Kšœ.™.Kšœ%™%Kšœ"™"šœ œœ™*K™&Kšœ™—šœ1™1Jšœ™Jšœ™Jšœ™—JšœF™FK™K™—šžœœ™4Kšœ3œœœ™GKšœ™K™—šžœœœ™Zšžœœœ™HK™Kšœ%œ(œœ™dK™šœ œ)œœ™EKšœœœ™!Kšœ"œ ™2Jšœ!™!Jšœ$™$Jšœ"™"KšœV™Všœœœ™šžœœœœ™6šœœ™šœ(™(Kšœ.™.Kšœ œ™Kšœœ™K™—šœ+™+Kšœ1™1Kšœ œ™Kšœœ™K™—Kšœ+œ0œ™cKšœœœ™—K™—Kšœ%™%šœœ™Kšœ,™,šœœ™Kšœ$œ™:Kšœa™aKšœ#™#Kšœ&™&Kšœ œ™Kšœ œ™K™—K™—Kšœ™—šœœ™Kšœœœ™ šœ ™ Kšœ$™$Kšœ™ K™—šœ™Kšœ™Kšœ™ K™—šœ™ Kšœ5™5Kšœ;™;šœ%™%Jšœ™Jšœ!™!Jšœ œ™!—Kšœœ+œœ™