DIRECTORY Core, CoreClasses, CoreFlat, CoreOps, CoreProperties, HashTable, Static, TerminalIO; StaticImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreFlat, CoreOps, CoreProperties, HashTable, TerminalIO EXPORTS Static = BEGIN OPEN Static; staticProp: ATOM = $Static; unconnectedOKAtom: ATOM = $UnconnectedOk; staticCutSetProp: PUBLIC ATOM _ $StaticCutSet; UnconnectedOK: PUBLIC PROC [wire: Core.Wire] RETURNS [same: Core.Wire] = { CoreProperties.PutWireProp[wire, staticProp, unconnectedOKAtom]; same _ wire; }; CheckCount: PUBLIC ConnectionCountProc = { IF (NOT unconnectedOK) AND ((public AND count<1) OR (NOT public AND count<2)) THEN { TerminalIO.WriteRope[CoreOps.GetFullWireName[wireRoot, wire]]; TerminalIO.WriteRope[IF public THEN " of cell " ELSE " in cell "]; TerminalIO.WriteRope[CoreOps.GetCellTypeName[cellType]]; TerminalIO.WriteRope[" has "]; SELECT count FROM 0 => TerminalIO.WriteRope["no connection"]; 1 => TerminalIO.WriteRope["only one connection"]; ENDCASE => ERROR; TerminalIO.WriteLn[]; }; }; WireInfo: TYPE = REF WireInfoRec; WireInfoRec: TYPE = RECORD [ count: INT _ 0, unconnectedOK: BOOL _ FALSE]; CountLeafConnections: PUBLIC PROC [root: Core.CellType, eachWireCount: ConnectionCountProc, cutSet: CoreFlat.CutSet _ NIL] = { CheckPublicCount: PROC [wire: Core.Wire] = { publicInfo: WireInfo _ NARROW[HashTable.Fetch[publicTable, wire].value]; IF HashTable.Fetch[publicVisit, wire].found THEN RETURN; IF NOT HashTable.Insert[publicVisit, wire, $Visited] THEN ERROR; eachWireCount[publicInfo.count, root.public, wire, TRUE, root, publicInfo.unconnectedOK]; }; Check: PROC [cell: Core.CellType, flatCell: CoreFlat.FlatCellTypeRec _ CoreFlat.rootCellType, instance: CoreClasses.CellInstance _ NIL] = { GetPublicInfo: PROC [publicWire: Core.Wire, thisCell: Core.CellType, thisFlatCell: CoreFlat.FlatCellTypeRec, thisInstance: CoreClasses.CellInstance] RETURNS [publicInfo: WireInfo] = { publicInfo _ NARROW[HashTable.Fetch[publicTable, publicWire].value]; IF publicInfo=NIL THEN { Check[thisCell, thisFlatCell, thisInstance]; publicInfo _ NARROW[HashTable.Fetch[publicTable, publicWire].value]; IF publicInfo=NIL THEN ERROR; }; }; SELECT TRUE FROM cell.class=CoreClasses.transistorCellClass OR cell.class=CoreClasses.unspecifiedCellClass OR CoreFlat.CutSetMemberResolved[flatCell, instance, cell, cutSet] => { InsertLeafPublic: PROC [wire: Core.Wire] = { [] _ HashTable.Insert[publicTable, wire, NEW[WireInfoRec _ [count: 1]]]; }; CoreOps.VisitRootAtomics[cell.public, InsertLeafPublic]; }; cell.class=CoreClasses.recordCellClass => { InsertRecordPublic: PROC [wire: Core.Wire] = { [] _ HashTable.Insert[publicTable, wire, NEW[WireInfoRec]]; }; CheckInternalCount: PROC [wire: Core.Wire] = { internalInfo: WireInfo _ NIL; IF HashTable.Fetch[publicTable, wire].found THEN RETURN; IF HashTable.Fetch[visitCheck, wire].found THEN RETURN; IF NOT HashTable.Insert[visitCheck, wire, $Visited] THEN ERROR; internalInfo _ NARROW[HashTable.Fetch[internalTable, wire].value]; eachWireCount[internalInfo.count, rct.internal, wire, FALSE, cell, internalInfo.unconnectedOK]; }; rct: CoreClasses.RecordCellType _ NARROW[cell.data]; internalTable: HashTable.Table _ HashTable.Create[]; visitCheck: HashTable.Table _ HashTable.Create[]; CoreOps.VisitRootAtomics[cell.public, InsertRecordPublic]; FOR i: NAT IN [0..rct.size) DO ComputeInternalCount: CoreOps.EachWirePairProc = { actualInfo, publicInfo: WireInfo; IF publicWire.size>0 THEN RETURN; IF HashTable.Fetch[visitCompute, publicWire].found THEN RETURN; IF NOT HashTable.Insert[visitCompute, publicWire, $Visited] THEN ERROR; publicInfo _ GetPublicInfo[publicWire, rct[i].type, [CoreFlat.ExtendPath[flatCell.path, i, rct], 0], rct[i]]; actualInfo _ NARROW[HashTable.Fetch[internalTable, actualWire].value]; IF actualInfo=NIL THEN { actualInfo _ NARROW[HashTable.Fetch[publicTable, actualWire].value]; IF actualInfo=NIL THEN { actualInfo _ NEW[WireInfoRec]; IF NOT HashTable.Insert[internalTable, actualWire, actualInfo] THEN ERROR; }; }; actualInfo.count _ actualInfo.count + publicInfo.count; }; visitCompute: HashTable.Table _ HashTable.Create[]; IF CoreOps.VisitBindingSeq[rct[i].actual, rct[i].type.public, ComputeInternalCount] THEN ERROR; ENDLOOP; PropagateUnconnectedOK[rct.internal, internalTable, publicTable]; CoreOps.VisitRootAtomics[rct.internal, CheckInternalCount]; }; ENDCASE => { ComputePublicCount: CoreOps.EachWirePairProc = { publicInfo: WireInfo; IF publicWire.size>0 THEN RETURN; publicInfo _ GetPublicInfo[publicWire, thisCell, [flatCell.path, flatCell.recastCount+1], instance]; [] _ HashTable.Insert[publicTable, actualWire, publicInfo]; }; thisCell: Core.CellType _ CoreOps.Recast[cell]; IF thisCell=cell THEN Check[cell, flatCell, instance] ELSE IF CoreOps.VisitBindingSeq[cell.public, thisCell.public, ComputePublicCount] THEN ERROR; }; }; publicVisit: HashTable.Table _ HashTable.Create[]; publicTable: HashTable.Table _ HashTable.Create[]; -- Core.Wire to WireInfo IF cutSet=NIL THEN cutSet _ NARROW[CoreProperties.GetCellTypeProp[root, staticCutSetProp]]; Check[root]; CoreOps.VisitRootAtomics[root.public, CheckPublicCount]; }; CountDirectConnections: PUBLIC PROC [root: Core.CellType, eachWireCount: ConnectionCountProc, cutSet: CoreFlat.CutSet _ NIL] = { Check: PROC [cell: Core.CellType, flatCell: CoreFlat.FlatCellTypeRec _ CoreFlat.rootCellType, instance: CoreClasses.CellInstance _ NIL] = { IF HashTable.Fetch[cellTypeVisit, cell].found THEN RETURN; IF NOT HashTable.Insert[cellTypeVisit, cell, $Visited] THEN ERROR; SELECT TRUE FROM cell.class=CoreClasses.transistorCellClass OR cell.class=CoreClasses.unspecifiedCellClass OR CoreFlat.CutSetMemberResolved[flatCell, instance, cell, cutSet] => RETURN; cell.class=CoreClasses.recordCellClass => { InsertRecordPublic: PROC [wire: Core.Wire] = { [] _ HashTable.Insert[publicTable, wire, $Public]; }; CheckWireCount: PROC [wire: Core.Wire] = { wireInfo: WireInfo _ NARROW[HashTable.Fetch[internalTable, wire].value]; publicWire: BOOL _ HashTable.Fetch[publicTable, wire].found; IF HashTable.Fetch[visitCheck, wire].found THEN RETURN; IF NOT HashTable.Insert[visitCheck, wire, $Visited] THEN ERROR; eachWireCount[wireInfo.count, rct.internal, wire, publicWire, cell, wireInfo.unconnectedOK]; }; rct: CoreClasses.RecordCellType _ NARROW[cell.data]; publicTable: HashTable.Table _ HashTable.Create[]; internalTable: HashTable.Table _ HashTable.Create[]; visitCheck: HashTable.Table _ HashTable.Create[]; PropagateUnconnectedOK[rct.internal, internalTable]; FOR i: NAT IN [0..rct.size) DO ComputeInternalCount: CoreOps.EachWirePairProc = { actualInfo: WireInfo; IF publicWire.size>0 THEN RETURN; IF HashTable.Fetch[visitCompute, publicWire].found THEN RETURN; IF NOT HashTable.Insert[visitCompute, publicWire, $Visited] THEN ERROR; actualInfo _ NARROW[HashTable.Fetch[internalTable, actualWire].value]; actualInfo.count _ actualInfo.count + 1; }; visitCompute: HashTable.Table _ HashTable.Create[]; IF CoreOps.VisitBindingSeq[rct[i].actual, rct[i].type.public, ComputeInternalCount] THEN ERROR; Check[rct[i].type, [CoreFlat.ExtendPath[flatCell.path, i, rct], 0], rct[i]]; ENDLOOP; CoreOps.VisitRootAtomics[cell.public, InsertRecordPublic]; CoreOps.VisitRootAtomics[rct.internal, CheckWireCount]; }; ENDCASE => { new: Core.CellType _ CoreOps.Recast[cell]; IF cell=new THEN Check[cell, flatCell, instance] ELSE Check[new, [flatCell.path, flatCell.recastCount+1], instance]; }; }; cellTypeVisit: HashTable.Table _ HashTable.Create[]; -- Marks analyzed cells IF cutSet=NIL THEN cutSet _ NARROW[CoreProperties.GetCellTypeProp[root, staticCutSetProp]]; Check[root]; }; PropagateUnconnectedOK: PROC [wire: Core.Wire, internalTable: HashTable.Table, publicTable: HashTable.Table _ NIL, ok: BOOL _ FALSE] = { ok _ ok OR CoreProperties.GetWireProp[wire, staticProp]=unconnectedOKAtom; IF wire.size>0 THEN FOR i: NAT IN [0..wire.size) DO PropagateUnconnectedOK[wire[i], internalTable, publicTable, ok]; ENDLOOP ELSE { wireInfo: WireInfo _ NARROW[HashTable.Fetch[internalTable, wire].value]; IF wireInfo=NIL THEN { IF publicTable#NIL THEN wireInfo _ NARROW[HashTable.Fetch[publicTable, wire].value]; IF wireInfo=NIL THEN { wireInfo _ NEW[WireInfoRec]; IF NOT HashTable.Store[internalTable, wire, wireInfo] THEN ERROR; }; }; wireInfo.unconnectedOK _ wireInfo.unconnectedOK OR ok; }; }; END. ΆStaticImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Barth, December 29, 1986 1:50:42 pm PST Last Edited by: Gasbarro January 13, 1987 1:34:40 pm PST ΚB– "cedar" style˜codešœ™Kšœ Οmœ1™˜>Kšœžœžœ žœ˜BKšœ8˜8Kšœ˜šžœž˜Kšœ+˜+Kšœ1˜1Kšžœžœ˜—Kšœ˜K˜—K˜K˜—Kšœ žœžœ ˜!šœ žœžœ˜Kšœžœ˜Kšœžœžœ˜K˜—š œžœžœUžœ˜~K˜š œžœ˜,Kšœžœ+˜HKšžœ*žœžœ˜8Kšžœžœ/žœžœ˜@Kšœ3žœ"˜YK˜K˜—š œžœxžœ˜‹K˜š  œžœ‚žœ˜·Kšœ žœ1˜Dšžœ žœžœ˜Kšœ,˜,Kšœ žœ1˜DKšžœ žœžœžœ˜K˜—K˜K˜—šžœžœž˜šœ+žœ-žœE˜‘K˜š œžœ˜,Kšœ)žœ˜HK˜K˜—Kšœ8˜8K˜—šœ+˜+K˜š œžœ˜.Kšœ)žœ˜;K˜K˜—š œžœ˜.Kšœžœ˜Kšžœ*žœžœ˜8Kšžœ)žœžœ˜7Kšžœžœ.žœžœ˜?Kšœžœ-˜BKšœ6žœ$˜_K˜K˜—Kšœ"žœ ˜4Kšœ4˜4K˜1Kšœ:˜:šžœžœžœž˜K˜š œ˜2Kšœ!˜!Kšžœžœžœ˜!Kšžœ1žœžœ˜?Kšžœžœ6žœžœ˜GKšœm˜mKšœ žœ3˜Fšžœ žœžœ˜Kšœ žœ1˜Dšžœ žœžœ˜Kšœ žœ˜Kšžœžœ9žœžœ˜JK˜—K˜—Kšœ7˜7K˜K˜—K˜3KšžœRžœžœ˜_Kšžœ˜—KšœA˜AKšœ;˜;K˜—šžœ˜ K˜š œ˜0Kšœ˜Kšžœžœžœ˜!Kšœd˜dKšœ<˜