<> <> DIRECTORY Convert, Core, CoreCreate, CoreIO, CoreOps, CoreClasses, CoreName, CoreProperties, HashTable, IFUSim, IO, Rope, Rosemary; IFUSimComplete: CEDAR PROGRAM IMPORTS Convert, CoreClasses, CoreCreate, CoreName, CoreIO, CoreOps, CoreProperties, HashTable, IO, Rope, Rosemary EXPORTS IFUSim = BEGIN CellType: TYPE = Core.CellType; Wire: TYPE = Core.Wire; Wires: TYPE = Core.Wires; ROPE: TYPE = Core.ROPE; Table: TYPE = HashTable.Table; Field: TYPE = REF FieldRec; FieldRec: TYPE = RECORD[root: ROPE, wire: Wire, adj: BOOL]; WR: TYPE = REF _ NIL; FormalIFU: PUBLIC PROC RETURNS[ifu: CellType] = { formalName: ROPE _ "FormalIFU"; subCell: CellType _ CoreOps.Recast[CoreIO.RestoreCellType["IFUComplete"]]; rec: CoreClasses.RecordCellType; publics: Wires _ NIL; actual: Wire _ CoreOps.CreateWires[size: subCell.public.size]; nameFields: Table _ HashTable.Create[]; newPubs: Table _ HashTable.Create[]; Register: PROC[old, new: ROPE, size: INT _ 0, index: INT _ -1, adj: BOOL _ TRUE] = { f: Field; wire: Wire; new _ CoreName.RopeNm[new]; wire _ NARROW[HashTable.Fetch[newPubs, new].value]; IF wire=NIL THEN { wire _ CoreCreate.Seq[name: new, size: size]; [] _ HashTable.Store[newPubs, new, wire]}; IF wire.size#size THEN ERROR; f _ NEW[FieldRec _ [ root: CoreName.RopeNm[old], wire: (IF index#-1 THEN wire[index] ELSE wire), adj: adj] ]; publics _ CONS[wire, publics]; [] _ HashTable.Store[nameFields, f.root, f]}; [] _ MarkWeakTransistors[subCell, "VBB"]; Register[ "Pad-IPAddr", "IPData", 32 ]; Register[ "Pad-NewFetchBAA", "IPCmdA", 8, 7 ]; Register[ "Pad-IPFaultingB", "IPFaultB", 4, 0 ]; Register[ "Pad-IPRejectB", "IPRejectB" ]; Register[ "Pad-DPCmnd3ABB", "DPCmdA", 8 ]; Register[ "Pad-DPFaultB", "DPFaultB", 4 ]; Register[ "Pad-DPRejectB", "DPRejectB" ]; Register[ "Pad-EUAluOp2ABB", "EUAluOp2AB", 4 ]; Register[ "Pad-EUCondSel2ABB", "EUCondSel2AB", 4 ]; Register[ "Pad-EURdFromPBus3ABB", "EURdFromPBus3AB" ]; Register[ "Pad-EUWriteToPBus3ABB", "EUWriteToPBus3AB" ]; Register[ "Pad-EUCondition2B", "EUCondition2B" ]; Register[ "Pad-XBus", "KBus", 32 ]; Register[ "Pad-ResetAB", "ResetAB" ]; Register[ "Pad-RescheduleAB", "RescheduleAB" ]; Register[ "PhA", "PhA" ]; Register[ "PhB", "PhB" ]; Register[ "NotPhA", "NotPhA" ]; Register[ "NotPhB", "NotPhB" ]; Register[ "NotPreChg", "NotPhA" ]; Register[ "DShA", "DShA" ]; Register[ "DShB", "DShB" ]; Register[ "DShRd", "DShRd" ]; Register[ "DShWt", "DShWt" ]; Register[ "Pad-DShIn", "DShIn" ]; Register[ "Pad-DShOut", "DShOut" ]; Register[ "VDD", "Vdd" ]; Register[ "GND", "Gnd" ]; Register[ "PadVDD", "PadVdd" ]; Register[ "PadGND", "PadGnd" ]; Register[ "VBB", "Vdd" ]; Register[ "FireControlV", "Vdd" ]; FOR index: INT IN [0..actual.size) DO f: Field; name: ROPE _ CoreName.WireNm[subCell.public[index]].n; sigRec: CoreName.SigRec _ NameSig[name]; idx: INT _ sigRec.idx; IF subCell.public[index].size#0 THEN ERROR; sigRec.idx _ -1; name _ CoreName.SigName[sigRec]; f _ NARROW[HashTable.Fetch[nameFields, name].value]; IF f=NIL THEN ERROR; actual[index] _ IF f.wire.size=0 THEN f.wire ELSE IF f.adj THEN f.wire[ Adj[ idx ] ] ELSE f.wire[ idx ]; ENDLOOP; rec _ NEW [CoreClasses.RecordCellTypeRec[1]]; ifu _ NEW [Core.CellTypeRec _ [ class: CoreClasses.recordCellClass, public: CoreOps.CreateWire[publics], data: rec ]]; rec.internal _ CoreOps.CreateWire[publics]; rec[0] _ NEW [CoreClasses.CellInstanceRec _ [actual: actual, type: subCell]]; [ ] _ CoreOps.SetCellTypeName[ifu, formalName]}; CorrespondingWires: PROC[atomic1, wire1, wire2: Wire] RETURNS[atomic2s: Wires _ NIL] = { visitProc: CoreOps.EachWirePairProc = {IF actualWire=atomic1 THEN FOR ws: Wires _ atomic2s, ws.rest WHILE ws #NIL DO IF ws.first=publicWire THEN EXIT; REPEAT FINISHED => atomic2s _ CONS[publicWire, atomic2s] ENDLOOP}; [ ] _ CoreOps.VisitBinding[wire1, wire2, visitProc]}; transistorGateCount: PUBLIC ATOM _ CoreIO.RegisterProperty[ CoreProperties.RegisterProperty[ $TransistorGateCount, CoreProperties.Props[ [CoreProperties.propCompare, CoreProperties.PropIntCompare], [CoreProperties.propCopy, NEW[CoreProperties.PropCopyProc _ CopyINT ]], [CoreProperties.propPrint, NEW[CoreProperties.PropPrintProc _ PrintTGC ]] ] ], WriteINT, ReadINT ]; WriteINT: CoreIO.PropWriteProc = {CoreIO.WriteInt[h, NARROW[value, REF INT]^]}; ReadINT: CoreIO.PropReadProc = {RETURN[ NEW[INT _ CoreIO.ReadInt[h] ] ]}; CopyINT: CoreProperties.PropCopyProc ={RETURN[NEW[INT_NARROW[value, REF INT]^]]}; PrintTGC: CoreProperties.PropPrintProc = {to.PutF[" Transistor Gate Count: %g", IO.int[NARROW[val, REF INT]^]]}; MarkWeakTransistors: PROC [cell: CellType, wr: WR] RETURNS[count: INT _ 0] = { refInt: REF INT; gate: Wire; WITH wr SELECT FROM wire: Wire => gate _ wire; rope: ROPE => gate _ CoreOps.FindWire [cell.public, rope]; text: REF TEXT => gate _ CoreOps.FindWire [cell.public, Rope.FromRefText[text]]; ENDCASE => ERROR; IF gate=NIL THEN ERROR; refInt _ NARROW[CoreProperties.GetWireProp[gate, transistorGateCount].value]; IF refInt#NIL THEN RETURN[refInt^]; SELECT cell.class FROM CoreClasses.transistorCellClass => ERROR; CoreClasses.recordCellClass => { data: CoreClasses.RecordCellType _ NARROW[cell.data]; FOR child: NAT IN [0..data.size) DO wires: Wires _ CorrespondingWires [gate, data.instances[child].actual, data.instances[child].type.public]; FOR wires _ wires, wires.rest WHILE wires#NIL DO cnt: INT; IF data.instances[child].type.class = CoreClasses.transistorCellClass THEN { IF data.instances[child].type.public[0] # wires.first THEN ERROR; [ ] _ Rosemary.SetTransistorInstanceSize[data.instances[child], driveWeak]; cnt _ 1} ELSE cnt _ MarkWeakTransistors[ data.instances[child].type, wires.first ]; count _ count + cnt ENDLOOP ENDLOOP }; ENDCASE => { recast: CellType _ CoreOps.Recast[cell]; wires: Wires _ CorrespondingWires[gate, cell.public, recast.public]; IF wires.rest#NIL THEN ERROR; count _ MarkWeakTransistors[ recast, wires.first ]}; CoreProperties.PutWireProp[gate, transistorGateCount, NEW[INT _ count]]}; NameSig: PROC[name: ROPE] RETURNS[sigRec: CoreName.SigRec] = { base: INT = 10; val: INT _ -1; DO -- Removes bracketed indexes begin: INT _ name.Find["[", 0 ]; end: INT _ name.Find["]", 0 ]; last: ROPE _ IF (end+1) < name.Length[] THEN name.Substr[end+1] ELSE NIL; IF begin=-1 THEN EXIT; val _ MAX[0, val]; val _ val*base + Convert.IntFromRope[name.Substr[begin+1, end-begin-1]]; name _ Rope.Cat[name.Substr[0, begin], last]; ENDLOOP; sigRec _ CoreName.NameSig[name]; sigRec.idx _ MAX[sigRec.idx, val]}; < 31, 40 => 32>> Adj: PROC[dec: INT] RETURNS[oct: INT _ 0] = { digits: LIST OF INT _ NIL; WHILE dec#0 DO digits _ CONS[dec MOD 10, digits]; dec _ dec/10 ENDLOOP; WHILE digits#NIL DO oct _ oct*8 + digits.first; digits _ digits.rest ENDLOOP}; END.