DIRECTORY Convert, Core, CoreCreate, CoreFlat, CoreIO, CoreOps, CoreClasses, CoreName, CoreProperties, FS, HashTable, IFUSim, IO, PLASim, Ports, Rope, Rosemary, TerminalIO; IFUSimImpl: CEDAR PROGRAM IMPORTS Convert, CoreClasses, CoreCreate, CoreFlat, CoreName, CoreIO, CoreOps, CoreProperties, FS, HashTable, IFUSim, IO, PLASim, Ports, Rope, Rosemary, TerminalIO EXPORTS IFUSim = BEGIN CellType: TYPE = Core.CellType; Properties: TYPE = Core.Properties; 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, octalIdx: BOOL]; WR: TYPE = REF _ NIL; Context: TYPE = REF ContextRec; ContextRec: TYPE = RECORD[ name: ROPE, cell: CellType, public: Wire, publics: Wires, internals: Wires, -- publics with no actuals regPubs: Table, nameFields: Table, weakTrans: INT ]; transistorGateCount: PUBLIC ATOM _ CoreIO.RegisterProperty[ CoreProperties.RegisterProperty[ $TransistorGateCount, CoreProperties.Props[ [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] ] ]}; PrintTGC: CoreProperties.PropPrintProc = {to.PutF[" Transistor Gate Count: %g", IO.int[NARROW[val, REF INT]^]]}; NewContext: PROC[name: ROPE, cell: CellType, public: Wire] RETURNS[ctx: Context] = { register: CoreOps.EachWireProc = { name: ROPE _ CoreName.WireNm[wire].n; IF name.Length[]#0 THEN []_HashTable.Store[ctx.regPubs, name, wire]}; ctx _ NEW[ContextRec _ [ name: name, cell: cell, public: public, publics: NIL, regPubs: HashTable.Create[], nameFields: HashTable.Create[], weakTrans: 0 ] ]; []_CoreOps.VisitWire[public, register] }; BindingRec: TYPE = RECORD[ bot: ROPE, top: ROPE, size: INT _ 0, index: INT _ -1, octalIdx: BOOL _ FALSE]; ifuToCluster2Bindings: LIST OF BindingRec _ LIST[ ["Pad-IPData", "IPData", 32, -1, TRUE ], ["Pad-NewFetchBAA", "IPCmdFetchA", ], ["Pad-IPFaultingB", "IPFaultingB" ], ["Pad-IPRejectB", "IPRejectB" ], ["Pad-DPCmnd2BAA", "DPCmdA", 8 ], ["Pad-DPFaultB", "DPFaultB", 4 ], ["Pad-DPRejectB", "DPRejectB" ], ["Pad-UserMode2BAA", "UserMode2BA", ], ["Pad-EUAluOp2ABB", "EUAluOp2AB", 4 ], ["Pad-EUCondSel2ABB", "EUCondSel2AB", 4 ], ["Pad-EURdFromPBus3ABB", "EURdFromPBus3AB" ], ["Pad-EUWriteToPBus3ABB", "EUWriteToPBus3AB" ], ["Pad-EUCondition2B", "EUCondition2B" ], ["Pad-XBus", "KBus", 32, -1, TRUE ], ["Pad-ResetAB", "ResetAB" ], ["Pad-RescheduleAB", "RescheduleAB" ], ["PhA", "PhA" ], ["PhB", "PhB" ], ["NotPhA", "NotPhA" ], ["NotPhB", "NotPhB" ], ["DShA", "DShA" ], ["DShB", "DShB" ], ["DShRd", "DShRd" ], ["DShWt", "DShWt" ], ["Pad-DShIn", "DShIn" ], ["Pad-DShOut", "DShOut" ], ["VDD", "Vdd" ], ["GND", "Gnd" ], ["PadVDD", "PadVdd" ], ["PadGND", "PadGnd" ], ["VBB", "Vdd" ], ["IDPlaFireV", "Vdd" ], ["IDPlaNotPhA", "NotPhA" ] ]; MakeFlatBotPublicCtx: PROC[binds: LIST OF BindingRec] RETURNS[ctx: CoreName.Context] ={ publics: Wires _ NIL; temp: Wires _ NIL; ctx _ CoreName.NewContext[]; FOR binds _ binds, binds.rest WHILE binds#NIL DO b: BindingRec _ binds.first; IF b.size=0 THEN []_CoreName.CtxWire[ctx, b.bot] ELSE FOR i: INT IN [0..b.size) DO []_CoreName.CtxWire[ctx, (IF NOT b.octalIdx OR b.size<8 THEN IO.PutFR["%g.%g", IO.rope[b.bot], IO.int[i]] ELSE IO.PutFR["%g.%02b", IO.rope[b.bot], IO.int[i]]) ] ENDLOOP; ENDLOOP}; RegTopBinds: PROC[ ctx: Context, binds: LIST OF BindingRec] = { FOR binds _ binds, binds.rest WHILE binds#NIL DO b: BindingRec _ binds.first; f: Field; wire: Wire; b.top _ CoreName.RopeNm[b.top]; wire _ NARROW[HashTable.Fetch[ctx.regPubs, b.top].value]; IF wire=NIL THEN { wire _ CoreCreate.Seq[name: b.top, size: b.size]; [] _ HashTable.Store[ctx.regPubs, b.top, wire]; ctx.publics _ CONS[wire, ctx.publics]}; IF wire.size#b.size THEN ERROR; f _ NEW[FieldRec _ [ root: CoreName.RopeNm[b.bot], wire: (IF b.index#-1 THEN wire[b.index] ELSE wire), octalIdx: b.octalIdx] ]; IF b.index#-1 THEN ctx.internals _ CONS[wire, ctx.internals]; -- partially connctd publics [] _ HashTable.Store[ctx.nameFields, f.root, f]; ENDLOOP}; FormalCell: PUBLIC PROC[ctx: Context] RETURNS[formalCell: CellType] = { rec: CoreClasses.RecordCellType; actual: Wire _ CoreOps.CreateWires[size: ctx.cell.public.size]; public: Wire _ IF ctx.publics#NIL THEN CoreOps.CreateWire[ctx.publics] ELSE ctx.public; IF ctx.public#NIL AND ctx.public#public THEN Signal[]; TerminalIO.WriteF["Recasting %g\n", IO.time[]]; TerminalIO.WriteF["Marking Trans %g\n", IO.time[]]; ctx.weakTrans _ MarkGatedTransistorsWeak[ctx.cell, "VBB"]; TerminalIO.WriteF["Setting Up %g\n", IO.time[]]; SetUp[ctx.cell]; TerminalIO.WriteF["Generate Formal %g\n", IO.time[]]; FOR index: INT IN [0..actual.size) DO f: Field; name: ROPE _ CoreName.WireNm[ctx.cell.public[index]].n; sigRec: CoreName.SigRec _ NameSig[name]; idx: INT _ sigRec.idx; IF ctx.cell.public[index].size#0 THEN ERROR; sigRec.idx _ -1; name _ CoreName.SigName[sigRec]; f _ NARROW[HashTable.Fetch[ctx.nameFields, name].value]; IF f=NIL THEN ERROR; actual[index] _ IF f.wire.size=0 THEN f.wire ELSE IF f.octalIdx THEN f.wire[ Adj[ idx ] ] ELSE f.wire[ idx ]; ENDLOOP; rec _ NEW [CoreClasses.RecordCellTypeRec[1]]; formalCell _ NEW [Core.CellTypeRec _ [ class: CoreClasses.recordCellClass, public: public, data: rec ]]; IF ctx.internals=NIL THEN rec.internal _ public -- this is ok ELSE { FOR i: INT IN [0..public.size) DO ctx.internals _ CONS[public[i], ctx.internals] ENDLOOP; rec.internal _ CoreOps.CreateWire[ctx.internals]}; rec[0] _ NEW [CoreClasses.CellInstanceRec _ [actual: actual, type: ctx.cell]]; [ ] _ CoreOps.SetCellTypeName[formalCell, ctx.name]}; 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]}; SubstituteRecasted: PUBLIC PROC [cell: CellType] RETURNS[recasted: CellType] = { recasted _ cell; SELECT cell.class FROM CoreClasses.recordCellClass => { data: CoreClasses.RecordCellType _ NARROW[cell.data]; FOR child: NAT IN [0..data.size) DO data.instances[child].type _ SubstituteRecasted[data.instances[child].type] ENDLOOP}; ENDCASE => IF cell.class.recast#NIL THEN recasted _ SubstituteRecasted[CoreOps.Recast[cell]]}; MarkGatedTransistorsWeak: PUBLIC PROC [cell: CellType, wr: WR] RETURNS[count: INT _ 0] = {RETURN[MarkGatedTypedTransistorsWeak[cell, wr, both]]}; MarkGatedTypedTransistorsWeak: PROC [cell: CellType, wr: WR, ttype: {p, n, both}] 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; IF gate=NIL THEN {TerminalIO.WriteRope["Skipping misslabeled gate wire\n"]; RETURN} ELSE 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 _ 0; IF data.instances[child].type.class # CoreClasses.transistorCellClass THEN cnt _ MarkGatedTransistorsWeak[ data.instances[child].type, wires.first ] ELSE IF data.instances[child].type.public[0] = wires.first THEN { td: CoreClasses.Transistor _ NARROW[data.instances[child].type.data]; doit: BOOL _ SELECT ttype FROM p=>(td.type=pE), n=>(td.type=nE), ENDCASE=>TRUE; IF doit THEN { [ ] _ Rosemary.SetTransistorInstanceSize[data.instances[child], driveWeak]; cnt _ 1}}; 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 _ MarkGatedTransistorsWeak[ 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]}; Adj: PUBLIC 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}; cacheQuick: CellType _ NIL; cacheRouted: CellType _ NIL; RoutedIFU: PROC RETURNS[CellType] = { IF cacheRouted=NIL THEN TerminalIO.WriteF["Read/Recast: %g %g", IO.rope["IFUComplete"], IO.time[]]; cacheRouted _ CoreIO.RestoreCellType["IFUComplete"]; TerminalIO.WriteF[". "]; cacheRouted _ SubstituteRecasted[cacheRouted]; TerminalIO.WriteF[". "]; [ ] _ CoreName.CellNm[cacheRouted, "IFURouted"]; RETURN[cacheRouted]}; QuickIFU: PROC RETURNS[cell: CellType] = { IF cacheQuick=NIL THEN { GetCell: PROC[subCellNm: ROPE] RETURNS[subCell: CellType] = { TerminalIO.WriteF["Read/Recast: %g %g . . ", IO.rope[subCellNm], IO.time[]]; subCell _ CoreIO.RestoreCellType[subCellNm]; TerminalIO.WriteF[". "]; subCell _ SubstituteRecasted[subCell]; TerminalIO.WriteF[". done\n"]}; wireTbl: CoreName.Context _ MakeFlatBotPublicCtx[ifuToCluster2Bindings]; public: Wire _ CoreName.WireFromCtx[wireTbl]; modules: LIST OF CellType = LIST[ GetCell["IFUControlPipe"], GetCell["IFUABForm"], GetCell["IFULSForm"], GetCell["IFUStackBuf"], GetCell["IFUPCFormBot"], GetCell["IFUPCFormTop"], GetCell["IFUXaForm"], GetCell["IFUFetchBuf"], GetCell["IFUFetch"], GetCell["IFULeftColumnCore"], GetCell["IFURightColumnCore"], GetCell["IFUPadTopCore"], GetCell["IFUPadLtCore"], GetCell["IFUPadRtCore"], GetCell["IFUPadBotCore"] ]; cacheQuick _ CoreName.BindModules[public, modules, "IFUQuick"]; }; RETURN[cacheQuick]}; FormalIFU: PUBLIC PROC[public: Wire _ NIL, quick: BOOL] RETURNS[ifu: CellType] = { ctx: Context; ifu _ IF quick THEN QuickIFU[] ELSE RoutedIFU[]; ctx _ NewContext["FormalIFU", ifu, public]; RegTopBinds[ctx, ifuToCluster2Bindings]; ifu _ FormalCell[ctx]}; FilePresent: PUBLIC PROC[name: ROPE] RETURNS[present: BOOL _ TRUE] = { ENABLE FS.Error => {present _ FALSE; CONTINUE}; file: FS.OpenFile _ FS.Open[name]; IF present THEN FS.Close[file] ELSE TerminalIO.WriteF["\n%g not present", IO.rope[name]]}; EnumPropLists: PROC [cell: Core.CellType, eachList: PROC[pList: Properties] RETURNS[Properties]] = { eachWireProc: CoreOps.EachWireProc = {wire.properties _ eachList[wire.properties]}; cell.properties _ eachList[cell.properties]; []_CoreOps.VisitWire[cell.public, eachWireProc]; IF cell.class=CoreClasses.recordCellClass THEN { data: CoreClasses.RecordCellType _ NARROW[cell.data]; []_CoreOps.VisitWire[data.internal, eachWireProc]; FOR child: NAT IN [0..data.size) DO data[child].properties _ eachList[data[child].properties]; []_CoreOps.VisitWire[data[child].actual, eachWireProc]; EnumPropLists[data[child].type, eachList] ENDLOOP } }; FindAllProps: PROC[cell: Core.CellType] RETURNS[atoms: LIST OF ATOM _ NIL]= { propTable: HashTable.Table _ HashTable.Create[]; eachAtom: HashTable.EachPairAction = { atoms _ CONS[NARROW[key, ATOM], atoms]}; eachProp: PROC [prop: ATOM, val: REF ANY _ NIL] = {[]_HashTable.Store[propTable, prop, prop]}; eachList: PROC[pList: Properties] RETURNS[Properties] = { CoreProperties.Enumerate[pList, eachProp]; RETURN[pList]}; EnumPropLists[cell, eachList]; []_HashTable.Pairs[propTable, eachAtom]}; RemoveExtraneousProps: PROC[cell: Core.CellType, keepers: HashTable.Table] = { eachList: PROC[pList: Properties] RETURNS[Properties] = { atoms: LIST OF ATOM _ NIL; eachProp: PROC [prop: ATOM, val: REF ANY _ NIL] = {IF ~HashTable.Fetch[keepers, prop].found THEN atoms _ CONS[prop, atoms]}; CoreProperties.Enumerate[pList, eachProp]; FOR atoms _ atoms, atoms.rest WHILE atoms#NIL DO pList _ CoreProperties.PutProp[pList, atoms.first, NIL] ENDLOOP; RETURN[pList]}; EnumPropLists[cell, eachList]}; SetUp: PUBLIC PROC[cell: Core.CellType] = { name: ROPE _ CoreName.CellNm[cell].n; IF CoreProperties.GetCellTypeProp[cell, $RoseBehave].value#NIL THEN RETURN; SELECT TRUE FROM name=dpPreChg => { []_Rosemary.BindCellType[cell, dpPreChg]; []_CoreFlat.CellTypeCutLabels[cell, dpPreChg]; InitPort[cell.public, "0", b, none]; InitPort[cell.public, "out0", b, drive]}; name=dpLatchPreChg => { []_Rosemary.BindCellType[cell, dpLatchPreChg]; []_CoreFlat.CellTypeCutLabels[cell, dpPreChg]; InitPort[cell.public, "in0", b, none]; InitPort[cell.public, "out0", b, drive]}; name=dpDebugRec => { []_Rosemary.BindCellType[cell, dpDebugRec]; []_CoreFlat.CellTypeCutLabels[cell, dpDebugRec]; InitPort[cell.public, "in0", b, none]; InitPort[cell.public, "in1", b, none]; InitPort[cell.public, "0", b, none]; InitPort[cell.public, "1", b, none]; InitPort[cell.public, "2", b, none]; InitPort[cell.public, "out0", b, drive]}; name=dpLatchG => { []_Rosemary.BindCellType[cell, dpLatchG]; []_CoreFlat.CellTypeCutLabels[cell, dpLatch]; InitPort[cell.public, "out0", b, drive]; []_MarkGatedTypedTransistorsWeak[cell, CoreOps.FindWire[cell.public, "out0"], p]}; name=dpLatchV => { []_Rosemary.BindCellType[cell, dpLatchV]; []_CoreFlat.CellTypeCutLabels[cell, dpLatch]; InitPort[cell.public, "out0", b, drive]; []_MarkGatedTypedTransistorsWeak[cell, CoreOps.FindWire[cell.public, "out0"], p]}; name=dpLatch => { []_Rosemary.BindCellType[cell, dpLatch]; []_CoreFlat.CellTypeCutLabels[cell, dpLatch]; InitPort[cell.public, "in0", b, none]; InitPort[cell.public, "0", b, none]; InitPort[cell.public, "out0", b, drive]; []_MarkGatedTypedTransistorsWeak[cell, CoreOps.FindWire[cell.public, "out0"], p]}; name=dpLatchCtl => { []_Rosemary.BindCellType[cell, dpLatchCtl]; []_CoreFlat.CellTypeCutLabels[cell, dpLatch]; InitPort[cell.public, "in1", b, none]; InitPort[cell.public, "in0", b, none]; InitPort[cell.public, "out0", b, drive]; []_MarkGatedTypedTransistorsWeak[cell, CoreOps.FindWire[cell.public, "out0"], p]}; name=drLatch => { data: CoreClasses.RecordCellType _ NARROW[cell.data]; []_Rosemary.BindCellType[cell, drLatch]; []_CoreFlat.CellTypeCutLabels[cell, drLatch]; []_MarkGatedTransistorsWeak[cell, CoreOps.FindWire[data.internal, "nDrLatch-io"]]; []_MarkGatedTransistorsWeak[cell, CoreOps.FindWire[data.internal, "nbit"]]; []_MarkGatedTransistorsWeak[cell, CoreOps.FindWire[data.internal, "DShDataOut"]]; InitPort[cell.public, "DrLatch-io", b, none]; InitPort[cell.public, "DShDataIn", b, none]; InitPort[cell.public, "DShDataOut", b, drive]; InitPort[cell.public, "DShA", b, none]; InitPort[cell.public, "DShB", b, none]; InitPort[cell.public, "DShWt", b, none]; InitPort[cell.public, "DShRd", b, none]}; Rope.Equal[name.Substr[0,4], "Mux|"] => { data: CoreClasses.RecordCellType _ NARROW[cell.data]; ctl: ROPE_ MuxNameField[name, ctl]; in: ROPE_ MuxNameField[name, in]; blankIns: INT _ 0; IF data.size=0 THEN RETURN; []_Rosemary.BindCellType [cell, genericMux]; []_CoreFlat.CellTypeCutLabels [cell, genericMux]; FOR child: NAT IN [0..data.size) DO [] _ Rosemary.SetTransistorInstanceSize[data.instances[child], driveWeak]; ENDLOOP; FOR i: INT IN [0..ctl.Length[]) DO wire: Wire; wire _ CoreOps.FindWire[cell.public, ctl.Substr[i,1]]; IF wire=NIL THEN Signal[]; []_Ports.InitPort[wire: wire, levelType: b, initDrive: none]; wire _ CoreOps.FindWire[cell.public, in.Substr[i,1]]; IF wire#NIL THEN []_Ports.InitPort[wire: wire, levelType: b, initDrive: none] ELSE blankIns _ blankIns+1; ENDLOOP; IF (data.size+blankIns)#ctl.Length[] THEN Signal[]; InitPort[cell.public, MuxNameField[name, out].Substr[0,1], l, drive]}; name=ifuFetchBuf => IFUSim.FetchBufInitPort [cell]; name=ifuStackBuf => IFUSim.StackBufInitPort [cell]; ENDCASE => SELECT cell.class FROM PLASim.simplePLAClass => PLASim.SetUpRose[cell]; CoreClasses.transistorCellClass => ERROR; CoreClasses.recordCellClass => { data: CoreClasses.RecordCellType _ NARROW[cell.data]; FOR child: NAT IN [0..data.size) DO IF data.instances[child].type.class # CoreClasses.transistorCellClass THEN SetUp[ data.instances[child].type] ELSE { trans: CoreClasses.Transistor _ NARROW[data.instances[child].type.data]; length: REAL _ trans.length; width: REAL _ trans.width; IF length/width > .5 THEN [] _ Rosemary.SetTransistorInstanceSize[data.instances[child], driveWeak]}; ENDLOOP }; ENDCASE => {Signal[]} }; InitPort: PROC [wire: Wire, name: ROPE, levelType: Ports.LevelType, initDrive: Ports.Drive] ={ wire _ CoreOps.FindWire[wire, name]; IF wire#NIL THEN []_Ports.InitPort[wire: wire, levelType: levelType, initDrive: initDrive]}; dpPreChg: ROPE _ Rosemary.Register[CoreName.RopeNm["DpPreChg"], DpPreChgInit, DpPreChgEval]; dpLatchPreChg: ROPE _ Rosemary.Register[CoreName.RopeNm["DpLatchPreChg"], DpLatchPreChgInit, DpPreChgEval]; dpDebugRec: ROPE _ Rosemary.Register[CoreName.RopeNm["DpDebugRec"], DpDebugRecInit, DpDebugRecEval]; dpLatch: ROPE _ Rosemary.Register[CoreName.RopeNm["DpLatch"], DpLatchInit, DpLatchEval]; dpLatchG: ROPE _ Rosemary.Register[CoreName.RopeNm["DpLatch-G-="], DpLatchGVInit, DpLatchGEval]; dpLatchV: ROPE _ Rosemary.Register[CoreName.RopeNm["DpLatch-V-="], DpLatchGVInit, DpLatchVEval]; dpLatchCtl: ROPE _ Rosemary.Register[CoreName.RopeNm["DpLatchCtl"], DpLatchCtlInit, DpLatchEval]; drLatch: ROPE _ Rosemary.Register[CoreName.RopeNm["DrLatch"], DrLatchInit, DrLatchEval]; genericMux: ROPE _ Rosemary.Register[CoreName.RopeNm["GenericMux"], MuxInit, MuxEval]; ifuFetchBuf: ROPE _ CoreName.RopeNm["IFUFetchBuf"]; ifuStackBuf: ROPE _ CoreName.RopeNm["IFUStackBuf"]; upOneLevel: ROPE _ CoreName.RopeNm["UpOneLevel"]; simpleMux: ROPE _ CoreName.RopeNm["SimpleMux"]; DrLatchState: TYPE = REF DrLatchStateRec; DrLatchStateRec: TYPE = RECORD[ io, DShIn, DShOut, DShA, DShB, DShWt, DShRd: INT _ -1, inside: BOOL _ FALSE]; DpPreChgState: TYPE = REF DpPreChgStateRec; DpPreChgStateRec: TYPE = RECORD[in, out: INT _ -1]; DpDebugRecState: TYPE = REF DpDebugRecStateRec; DpDebugRecStateRec: TYPE = RECORD [in0, in1, ctl0, ctl1, ctl2, out: INT _ -1, bit: BOOL _ FALSE]; DpLatchState: TYPE = REF DpLatchStateRec; DpLatchStateRec: TYPE = RECORD[ in, ctl, out: INT _ -1, inside: BOOL _ FALSE]; MuxState: TYPE = REF MuxStateRec; MuxStateRec: TYPE = RECORD[ ctl: MuxPinSeq, in: MuxPinSeq, out: INT]; MuxPinSeq: TYPE = REF MuxPinSeqRec; MuxPinSeqRec: TYPE = RECORD[SEQUENCE size: CARDINAL OF INTEGER]; DrLatchInit: Rosemary.InitProc = { s: DrLatchState _ IF oldStateAny # NIL THEN NARROW[oldStateAny] ELSE NEW[DrLatchStateRec]; s^ _ [ io: CoreOps.GetWireIndex[cellType.public, "DrLatch-io"], DShIn: CoreOps.GetWireIndex[cellType.public, "DShDataIn"], DShOut: CoreOps.GetWireIndex[cellType.public, "DShDataOut"], DShA: CoreOps.GetWireIndex[cellType.public, "DShA"], DShB: CoreOps.GetWireIndex[cellType.public, "DShB"], DShWt: CoreOps.GetWireIndex[cellType.public, "DShWt"], DShRd: CoreOps.GetWireIndex[cellType.public, "DShRd"], inside: FALSE ]; RETURN[s]}; DpPreChgInit: Rosemary.InitProc = { s: DpPreChgState _ IF oldStateAny # NIL THEN NARROW[oldStateAny] ELSE NEW[DpPreChgStateRec]; s^ _ [ in: CoreOps.GetWireIndex[cellType.public, "0"], out: CoreOps.GetWireIndex[cellType.public, "out0"]]; RETURN[s]}; DpLatchPreChgInit: Rosemary.InitProc = { s: DpPreChgState _ IF oldStateAny # NIL THEN NARROW[oldStateAny] ELSE NEW[DpPreChgStateRec]; s^ _ [ in: CoreOps.GetWireIndex[cellType.public, "in0"], out: CoreOps.GetWireIndex[cellType.public, "out0"]]; RETURN[s]}; DpDebugRecInit: Rosemary.InitProc = { s: DpDebugRecState _ IF oldStateAny # NIL THEN NARROW[oldStateAny] ELSE NEW[DpDebugRecStateRec]; s^ _ [ in0: CoreOps.GetWireIndex[cellType.public, "in0"], in1: CoreOps.GetWireIndex[cellType.public, "in1"], ctl0: CoreOps.GetWireIndex[cellType.public, "0"], ctl1: CoreOps.GetWireIndex[cellType.public, "1"], ctl2: CoreOps.GetWireIndex[cellType.public, "2"], out: CoreOps.GetWireIndex[cellType.public, "out0"], bit: FALSE ]; RETURN[s]}; DpLatchInit: Rosemary.InitProc = { s: DpLatchState _ IF oldStateAny # NIL THEN NARROW[oldStateAny] ELSE NEW[DpLatchStateRec]; s^ _ [ in: CoreOps.GetWireIndex[cellType.public, "in0"], ctl: CoreOps.GetWireIndex[cellType.public, "0"], out: CoreOps.GetWireIndex[cellType.public, "out0"], inside: FALSE ]; RETURN[s]}; DpLatchGVInit: Rosemary.InitProc = { s: DpLatchState _ IF oldStateAny # NIL THEN NARROW[oldStateAny] ELSE NEW[DpLatchStateRec]; s^ _ [out: CoreOps.GetWireIndex[cellType.public, "out0"] ]; RETURN[s]}; DpLatchCtlInit: Rosemary.InitProc = { s: DpLatchState _ IF oldStateAny # NIL THEN NARROW[oldStateAny] ELSE NEW[DpLatchStateRec]; s^ _ [ in: CoreOps.GetWireIndex[cellType.public, "in0"], ctl: CoreOps.GetWireIndex[cellType.public, "in1"], out: CoreOps.GetWireIndex[cellType.public, "out0"], inside: FALSE ]; RETURN[s]}; MuxInit: Rosemary.InitProc = { name: ROPE _ CoreName.CellNm[cellType].n; s: MuxState; ctl: ROPE _ MuxNameField[name, ctl]; in: ROPE _ MuxNameField[name, in]; s _ NEW[MuxStateRec]; s.ctl _ NEW[MuxPinSeqRec[ctl.Length[]]]; s.in _ NEW[MuxPinSeqRec[ctl.Length[]]]; FOR i: CARDINAL IN [0..s.ctl.size) DO s.ctl[i] _ CoreOps.GetWireIndex[cellType.public, ctl.Substr[i,1] ]; s.in[i] _ CoreOps.GetWireIndex[cellType.public, in.Substr[i,1] ]; ENDLOOP; s.out _ CoreOps.GetWireIndex[cellType.public, MuxNameField[name, out].Substr[0,1]]; RETURN[s]}; DrLatchEval: Rosemary.EvalProc = { s: DrLatchState _ NARROW[stateAny]; IF p[s.DShRd].b AND p[s.DShA].b THEN Signal[]; IF p[s.DShRd].b AND p[s.DShWt].b THEN Signal[]; IF p[s.DShA].b THEN s.inside _ p[s.DShIn].b; IF p[s.DShRd].b THEN s.inside _ NOT p[s.io].b; IF p[s.DShWt].b THEN {p[s.io].b _ NOT s.inside; p[s.io].d _ drive} ELSE p[s.io].d _ none; IF p[s.DShB].b THEN p[s.DShOut].b _ s.inside }; DpPreChgEval: Rosemary.EvalProc = { s: DpPreChgState _ NARROW[stateAny]; IF NOT p[s.in].b THEN {p[s.out].d _ drive; p[s.out].b _ TRUE} ELSE {p[s.out].d _ none}}; DpDebugRecEval: Rosemary.EvalProc = { s: DpDebugRecState _ NARROW[stateAny]; IF p[s.ctl0].b AND p[s.ctl1].b THEN Signal[]; IF p[s.ctl0].b THEN s.bit _ p[s.in0].b; IF p[s.ctl1].b THEN s.bit _ p[s.in1].b; IF p[s.ctl2].b THEN p[s.out].b _ s.bit }; DpLatchEval: Rosemary.EvalProc = { s: DpLatchState _ NARROW[stateAny]; IF p[s.ctl].b THEN s.inside _ p[s.in].b; p[s.out].b _ s.inside }; DpLatchGEval: Rosemary.EvalProc = { s: DpLatchState _ NARROW[stateAny]; p[s.out].b _ FALSE }; DpLatchVEval: Rosemary.EvalProc = { s: DpLatchState _ NARROW[stateAny]; p[s.out].b _ TRUE }; MuxEval: Rosemary.EvalProc = { s: MuxState _ NARROW[stateAny]; count: CARDINAL _ 0; last: CARDINAL _ 0; FOR i: CARDINAL IN [0..s.ctl.size) DO IF p[s.ctl[i]].b AND s.in[i]#-1 THEN {count _ count+1; last _ i} ENDLOOP; SELECT count FROM 0 => { }; 1 => IF s.in[last]#-1 THEN p[s.out].l _ IF p[s.in[last]].b THEN H ELSE L; ENDCASE => p[s.out].l _ X}; MuxNameField: PROC[name: ROPE, type: {ctl, in, out}] RETURNS[field: ROPE _ NIL] = { index: CARDINAL _ SELECT type FROM ctl=>1, in=>2, ENDCASE=>3; THROUGH [0..index] DO name _ name.Substr[name.Find["|"]+1] ENDLOOP; field _ name.Substr[0, name.Find["|"]]}; Signal: SIGNAL = CODE; keepPropTable: HashTable.Table _ HashTable.Create[]; []_HashTable.Store[keepPropTable, $CoreName, NEW[INT _ 0]]; END. ”IFUSimImpl.mesa Last Edited by Curry October 24, 1986 10:18:23 am PDT Don Curry November 2, 1986 7:23:01 pm PST Adjustment for octal rope incorrectly converted using base 10. eg. 37 => 31, 40 => 32 IF FilePresent["IFURouted.core"] THEN { TerminalIO.WriteF["Read: %g %g . . . ", IO.rope["IFURouted"], IO.time[]]; cacheRouted _ CoreIO.RestoreCellType["IFURouted"]; cacheRouted _ SubstituteRecasted[cacheRouted]; TerminalIO.WriteF["done\n"]} ELSE { RemoveExtraneousProps[cacheRouted, keepPropTable]; TerminalIO.WriteF[". "]; CoreIO.SaveCellType[cacheRouted]; TerminalIO.WriteF["done\n"]}; IF FilePresent["IFUQuick.core"] THEN { TerminalIO.WriteF["Read: %g %g . . . ", IO.rope["IFUQuick"], IO.time[]]; cacheQuick _ CoreIO.RestoreCellType["IFUQuick"]; cacheQuick _ SubstituteRecasted[cacheQuick]; TerminalIO.WriteF["done\n"]} ELSE { GetCell["IFUDataColumnCore"], TerminalIO.WriteF["Remove Props: %g %g . . . ", IO.rope["IFUQuick"], IO.time[]]; RemoveExtraneousProps[cacheQuick, keepPropTable]; TerminalIO.WriteF[" done\n"]; CoreIO.SaveCellType[cacheQuick]}; DrLatch Transistors DrLatch-io nDrLatch-io GND DrLatch-io nDrLatch-io VDD nDrLatch-io DrLatch-io GND weakTransistor nDrLatch-io DrLatch-io VDD weakTransistor bit nbit GND bit nbit VDD nbit bit GND weakTransistor nbit bit VDD weakTransistor nDShDataOut DShDataOut GND nDShDataOut DShDataOut VDD DShDataOut nDShDataOut GND weakTransistor DShDataOut nDShDataOut VDD weakTransistor DShWt nbit DrLatch-io DShRd bit nDrLatch-io DShB nbit nDShDataOut DShA bit DShDataIn ENDCASE => {recast: CellType _ CoreOps.Recast[cell]; SetUp[ recast ]} }; Must Agree with IFUCoreDataMuxImpl.ExpandDataMuxFrameHard CreateNameLetterCode []_HashTable.Store[keepPropTable, $Layout, NEW[INT _ 0]]; []_HashTable.Store[keepPropTable, $WireCap, NEW[INT _ 0]]; []_HashTable.Store[keepPropTable, $RootCap, NEW[INT _ 0]]; []_HashTable.Store[keepPropTable, $CapaLabel, NEW[INT _ 0]]; []_HashTable.Store[keepPropTable, $TransistorGateCount, NEW[INT _ 0]]; []_HashTable.Store[keepPropTable, $TransistorCount, NEW[INT _ 0]]; []_HashTable.Store[keepPropTable, $CoreIOGlobal, NEW[INT _ 0]]; []_HashTable.Store[keepPropTable, $CoreBlockSides, NEW[INT _ 0]]; []_HashTable.Store[keepPropTable, $GivenName, NEW[INT _ 0]]; []_HashTable.Store[keepPropTable, $FusedByName, NEW[INT _ 0]]; []_HashTable.Store[keepPropTable, $CoreNameToWireCache, NEW[INT _ 0]]; []_HashTable.Store[keepPropTable, $CoreWireToNamesCache NEW[INT _ 0]]; []_HashTable.Store[keepPropTable, $ClusterInfo, NEW[INT _ 0]]; []_HashTable.Store[keepPropTable, $PortData, NEW[INT _ 0]]; []_HashTable.Store[keepPropTable, $RoseFixedWire, NEW[INT _ 0]]; []_HashTable.Store[keepPropTable, $RoseCutSet, NEW[INT _ 0]]; []_HashTable.Store[keepPropTable, $RoseTransistorSize, NEW[INT _ 0]]; []_HashTable.Store[keepPropTable, $RoseBehave, NEW[INT _ 0]]; Κ˜™Jšœ5™5Icode™)—J˜JšΟk œuœ,˜¬J˜šΟn Πblœœ˜Jšœoœ+˜£Jšœ ˜—š˜J˜Jšœ œ˜ Jšœ œ˜#Jšœœ ˜Jšœ œ˜Jšœœœ˜Jšœ œ˜ Jšœ œœ ˜Jš œ œœœœ˜AJšœœœœ˜J˜Jšœ œœ ˜šœ œœ˜Jšœœ˜ Jšœ˜Jšœ˜Jšœ˜JšœΟc˜-Jšœ˜Jšœ˜Jšœ œ˜—J˜šΟbœœœ˜;šœ ˜ Jšœ‘œ˜šœ˜Jšœœ ‘œ˜O——Jšœ ˜ Jšœ ˜ —Jšžœ-œœœ˜PJšžœœœœ˜IšΠbnœ!˜)Jš œ(œœœœ˜H—J˜šž œœœ œ˜Tšœ"˜"Jšœœ˜%Jšœœ.˜E—šœœ˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ œ˜Jšœ˜Jšœ˜Jšœ˜—Jšœ)˜)—J˜šœ œœ˜Jšœœ˜ Jšœœ˜ Jšœœ˜Jšœœ˜Jšœ œœ˜—J˜šœœœœ˜1Jšœ*œ˜1Jšœ,˜,Jšœ+˜+Jšœ)˜)Jšœ)˜)Jšœ+˜+Jšœ)˜)Jšœ-˜-Jšœ,˜,Jšœ/˜/Jšœ0˜0Jšœ2˜2Jšœ-˜-Jšœ&œ˜-Jšœ%˜%Jšœ-˜-Jšœ˜Jšœ˜Jšœ"˜"Jšœ"˜"Jšœ˜Jšœ˜Jšœ ˜ Jšœ ˜ Jšœ#˜#Jšœ%˜%Jšœ˜Jšœ˜Jšœ"˜"Jšœ"˜"Jšœ˜Jšœ#˜#Jšœ'˜'—J˜š žœœœœ œ˜WJšœœ˜Jšœœ˜Jšœ˜šœœœ˜0Jšœ˜šœ ˜ Jšœ ˜$š˜šœœœ ˜šœœœ œ ˜7Jšœœœœ˜2Jšœœœœ ˜6—Jšœ˜———Jšœ˜ ——J˜šž œœ˜Jšœ˜Jšœœœ˜šœœœ˜0Jšœ˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœœ,˜9šœœœ˜Jšœ1˜1Jšœ/˜/Jšœœ˜'—Jšœœœ˜šœœ˜Jšœ˜Jšœœ œœ˜4Jšœ˜—Jšœ œœ ˜ZJšœ0˜0Jšœ˜ ——J˜šž œœœœ˜GJšœ"˜"JšœB˜Bšœœ ˜$Jšœ ˜$Jšœ ˜—Jšœ œœœ ˜6Jšœ$œ ˜/Jšœ(œ ˜3Jšœ:˜:Jšœ+œ ˜6Jšœ˜Jšœ*œ ˜5šœœœ˜%Jšœ ˜ Jšœœ-˜9Jšœ)˜)Jšœœ˜Jšœœœ˜,Jšœ˜Jšœ‘œ ˜"Jšœœ.˜8Jšœœœœ˜šœœ˜ Jšœ˜ šœœ ˜Jšœ ‘œ ˜Jšœ˜——Jšœ˜—Jšœœ$˜/šœ œ˜&Jšœ$˜$Jšœ˜Jšœ˜—šœ˜Jšœ  ˜(šœ˜Jš œœœœœœ˜YJšœ2˜2——Jšœ œB˜PJšœ5˜5—J˜J˜šžœœœœ˜Xšœ&˜&šœœ˜šœœœ˜2Jšœœœ˜!Jšœœœœ˜B———Jšœ5˜5—J˜šžœœœœ˜PJšœ˜šœ ˜˜ Jšœ#œ ˜5šœœœ˜#Jšœžœ˜KJš ˜ ——šœœ˜#Jšœ žœ˜:———J˜š žœœœœœœ˜VJšœœ1˜:—J˜šžœœœ˜QJšœœ ˜Jšœœœ˜Jšœ ˜ šœœ˜Jšœ˜Jšœœ3˜=JšœœœC˜QJšœ˜—šœ˜ Jšœ<œ˜GJšœ œ"‘œ ˜R—Jšœœœœ ˜#šœ ˜Jšœ#œ˜)˜!Jšœ#œ ˜5šœœœ˜#šœ!˜!JšœH˜H—šœœœ˜0Jšœœ˜ šœC˜EJšœJ˜Nšœœ4œ˜AJšœœ"˜Ešœœœ˜Jšœ"œœ˜0—šœœ˜JšœK˜KJšœ ˜ ———Jšœœœ˜&———šœ˜ J˜(JšœE˜EJšœ œœœ˜Jšœ9˜9——Jšœ!‘œœœ ˜I—J˜šžœœœœ˜>Jšœœ˜Jšœœ˜šœ ˜Jšœœ˜ Jšœœ˜Jš œœœœœœ˜IJšœ œœ˜Jšœœ ˜JšœH˜HJšœ.œ˜6—Jšœ ˜ Jšœ œ˜#—J˜JšœB ™Xš žœœœœœœ ˜4Jš œœœœœ˜Jš œœ œœœ˜HJšœœœ2œ˜N—J˜Jšœœ˜Jšœœ˜J˜šž œœœ˜%šœ œœ˜šœ™ šœ™Jšœ(œœ ™IJšœ2™2Jšœ.™.Jšœ™—šœ™Jšœ(œœ ˜KJšœM˜MJšœI˜IJšœ0˜0JšœP™PJšœC™C———Jšœ˜—J˜šžœœœ˜*šœ œœ˜šœ™šœ™Jšœ(œœ ™HJšœ0™0Jšœ,™,Jšœ™—šœ™Jšž˜šžœœ œœ˜=Jšœ-œœ ˜LJšœE˜EJšœH˜H—JšœI˜IJšœ.˜.šœ œœ œ˜!šœ™Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜—Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜—Jšœ?˜?Jšœ˜Jšœ0œœ ™PJšœ1™1Jšœ™Jšœ!™!———Jšœ˜—J˜š ž œœœœ œœ˜RJšœ ˜ Jšœœœ œ ˜0Jšœ+˜+Jšœ(˜(Jšœ˜—J˜šž œœœœœ œœ˜FJšœœœœ˜/Jšœœ œ ˜"Jš œœœ œ'œ˜Z—J˜šœ™Jšœ™Jšœ™Jšœœ™-Jšœœ™-Jšœ™Jšœ™Jšœœ™$Jšœœ™$Jšœ™Jšœ™Jšœœ™,Jšœœ™,Jšœ™Jšœ™Jšœ™Jšœ™—J˜šž œ˜Jšœ œœ˜PJšœS˜SJšœ‘œ˜,Jšœ‘ œ˜0šœ(œ˜0Jšœ#œ ˜5Jšœ‘ œ˜2šœœœ˜#Jšœ"‘ œ ˜:Jšœ‘œ˜7Jšœ‘œ œ˜6———J˜šž œœœœœœœ˜MJšœ0˜0šœ&˜&Jšœœœœ ˜(—š œ œœœœœ˜1Jšœ,˜,—šœ œœ˜9Jšœ*˜*Jšœ ˜—Jšœ˜Jšœ)˜)—J˜šžœœ3˜Nšœ œœ˜9Jš œœœœœ˜š œ œœœœœ˜1Jšœœ'œ œ˜J—Jšœ*˜*šœœœ˜0Jšœ3œœ˜@—Jšœ ˜—Jšœ˜—J˜šžœœœ˜+Jšœœ˜%Jšœ9œœœ˜Kšœœ˜šœ˜Jšœ)˜)Jšœ.˜.Jšœ(˜(Jšœ,˜,—šœ˜Jšœ.˜.Jšœ.˜.Jšœ)˜)Jšœ,˜,—šœ˜Jšœ+˜+Jšœ0˜0Jšœ)˜)Jšœ)˜)Jšœ(˜(Jšœ(˜(Jšœ(˜(Jšœ,˜,—šœ˜Jšœ)˜)Jšœ-˜-Jšœ+˜+JšœR˜R—šœ˜Jšœ)˜)Jšœ-˜-Jšœ+˜+JšœR˜R—šœ˜Jšœ(˜(Jšœ-˜-Jšœ)˜)Jšœ(˜(Jšœ+˜+JšœR˜R—šœ˜Jšœ+˜+Jšœ-˜-Jšœ)˜)Jšœ)˜)Jšœ+˜+JšœR˜R—šœ˜Jšœ#œ ˜5Jšœ(˜(Jšœ-˜-JšœR˜RJšœK˜KJšœQ˜QJšœ.˜.Jšœ-˜-Jšœ.˜.Jšœ)˜)Jšœ)˜)Jšœ*˜*Jšœ+˜+—šœ*˜*Jšœ#œ ˜5Jšœœ˜#Jšœœ˜"Jšœ œ˜Jšœ œœ˜Jšœ,˜,Jšœ1˜1šœœœ˜#JšœJ˜JJšœ˜—šœœœ˜"Jšœ ˜ Jšœ6˜6Jšœœœ ˜Jšœ=˜=Jšœ5˜5šœ˜ Jšœ=˜AJšœ˜—Jšœ˜—Jšœ#œ ˜3JšœF˜F—Jšœ3˜3Jšœ3˜3šœœ ˜!Jšœ1˜1Jšœ#œ˜)˜!Jšœ#œ ˜5šœœœ˜#šœC˜EJšœ#˜'šœ˜Jšœ œ"˜HJšœœ˜Jšœœ˜šœ˜JšœK˜K——Jšœ˜ ———JšœB™IJšœ˜———J˜šžœ˜šœœ8˜OJšœ$˜$šœœ˜JšœK˜K———J˜šœ œ1˜@Jšœ˜—šœœ6˜IJšœ!˜!—šœ œ3˜DJšœ ˜ —šœ œ0˜>Jšœ˜—šœ œ4˜BJšœ˜—šœ œ4˜BJšœ˜—šœ œ3˜CJšœ˜—šœ œ0˜>Jšœ˜—šœ œ3˜DJšœ˜—Jšœœ"˜4Jšœœ"˜4Jšœ œ!˜2Jšœ œ ˜0J˜Jšœœœ˜+šœœœ˜Jšœ&žœœ˜6Jšœœœ˜—Jšœœœ˜,Jšœœœ œ˜3Jšœœœ˜0šœœ˜!Jšœ"œ œœ˜?—Jšœœœ˜*šœœœ˜Jšœœ˜Jšœœœ˜—Jšœ œœ ˜$šœ œœ˜Jšœ˜Jšœ˜Jšœœ˜ —Jšœ œœ˜%Jš œœœœœœœ˜AJ˜šž œ˜"šœœ˜&Jšœœ ˜Jšœœ˜—šœ˜Jšœ:˜:Jšžœ5˜:Jšžœ6˜Jšœ0œœ™>Jšœ0œœ™>Jšœ2œœ™@Jšœ9œœ™GJšœ6œœ™DJšœ4œœ™BJšœ5œœ™CJšœ1œœ™?Jšœ3œœ™AJšœ8œœ™FJšœ8œœ™FJšœ3œœ™AJšœ1œœ™?Jšœ4œœ™BJšœ3œœ™AJšœ8œœ™FJšœ2œœ™@J˜J˜Jšœ˜—J˜J˜—…—^όˆ