<> <> <> 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]}; < 31, 40 => 32>> 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 }; < {recast: CellType _ CoreOps.Recast[cell]; SetUp[ recast ]} };>> 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]]; <<[]_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]];>> END.