<> <> <> DIRECTORY Core, CoreFlat, CoreName, IFUSim, Rosemary, Ports, Rope; IFUSimStackBuf: CEDAR PROGRAM IMPORTS CoreFlat, CoreName, IFUSim, Rosemary, Ports, Rope EXPORTS IFUSim = BEGIN ROPE: TYPE = Core.ROPE; CellType: TYPE = Core.CellType; Signal: SIGNAL = CODE; stackBuf: ROPE _ Rosemary.Register[CoreName.RopeNm["StackBuf"], StackBufInit, StackBufEval]; NotPCStackRdData: ROPE _ CoreName.RopeNm["NotPCStackRdData"]; PCStackWtData: ROPE _ CoreName.RopeNm["PCStackWtData"]; NotStatStackRdData: ROPE _ CoreName.RopeNm["NotStatStackRdData"]; StatStackWtData: ROPE _ CoreName.RopeNm["StatStackWtData"]; StkLdL: ROPE _ CoreName.RopeNm["StkLdL"]; StkLdP: ROPE _ CoreName.RopeNm["StkLdP"]; StkRd: ROPE _ CoreName.RopeNm["StkRd"]; StackBufState: TYPE = REF StackBufStateRec; StackBufStateRec: TYPE = RECORD[ pc: StackBufBits, stat: StackBufBits, pRdBus: StackColPins, sRdBus: StackColPins, pWtBus: StackColPins, sWtBus: StackColPins, ldP: StackRowPins, ldL: StackRowPins, rd: StackRowPins ]; StackBufBits: TYPE = PACKED ARRAY [0..16) OF ARRAY [0..32) OF Ports.Level _ ALL[ALL[L]]; StackRowPins: TYPE = ARRAY [0..16) OF CARDINAL; StackColPins: TYPE = ARRAY [0..32) OF CARDINAL; StackBufInitPort: PUBLIC PROC [cell: CellType] = { []_Rosemary.BindCellType [cell, stackBuf]; []_CoreFlat.CellTypeCutLabels [cell, "UpOneLevel"]; FOR i: INT IN [0..cell.public.size) DO name: ROPE _ CoreName.WireNm[cell.public[i]].n; sig: CoreName.SigRec _ CoreName.NameSig[name]; IF (cell.public[i].size#0) OR (name.Length[]=0) THEN Signal[]; SELECT sig.root FROM NotPCStackRdData, NotStatStackRdData => []_Ports.InitPort[wire: cell.public[i], levelType: l, initDrive: drive]; PCStackWtData, StatStackWtData => []_Ports.InitPort[wire: cell.public[i], levelType: l, initDrive: none]; ENDCASE => []_Ports.InitPort[wire: cell.public[i], levelType: b, initDrive: none]; ENDLOOP}; StackBufInit: Rosemary.InitProc = { s: StackBufState _ IF oldStateAny # NIL THEN NARROW[oldStateAny] ELSE NEW[StackBufStateRec]; FOR bit: INT IN [0..cellType.public.size) DO name: ROPE _ CoreName.WireNm[cellType.public[bit]].n; sig: CoreName.SigRec _ CoreName.NameSig[name]; SELECT sig.root FROM NotPCStackRdData => s.pRdBus [ IFUSim.Adj[sig.idx] ] _ bit; -- octal indexes NotStatStackRdData => s.sRdBus [ IFUSim.Adj[sig.idx] ] _ bit; -- octal indexes PCStackWtData => s.pWtBus [ IFUSim.Adj[sig.idx] ] _ bit; -- octal indexes StatStackWtData => s.sWtBus [ IFUSim.Adj[sig.idx] ] _ bit; -- octal indexes StkLdP => s.ldP [ sig.idx ] _ bit; StkLdL => s.ldL [ sig.idx ] _ bit; StkRd => s.rd [ sig.idx ] _ bit; ENDCASE ENDLOOP; RETURN[s]}; StackBufEval: Rosemary.EvalProc = { s: StackBufState _ NARROW[stateAny]; lastRd: CARDINAL _ 0; cntRd: CARDINAL _ 0; FOR row: CARDINAL IN [0..16) DO IF p[s.ldP [row]].b THEN FOR bit: CARDINAL IN [0..32) DO s.pc [row][bit] _ p[ s.pWtBus [bit] ].l ENDLOOP; IF p[s.ldL [row]].b THEN FOR bit: CARDINAL IN [0..32) DO s.stat [row][bit] _ p[ s.sWtBus [bit] ].l ENDLOOP; IF p[s.rd [row]].b THEN {cntRd _ cntRd + 1; lastRd _ row} ENDLOOP; FOR bit: CARDINAL IN [0..32) DO SELECT cntRd FROM 0 => { p[ s.pRdBus [bit] ].d _ none; p[ s.sRdBus [bit] ].d _ none}; 1 => { p[ s.pRdBus [bit] ].d _ drive; p[s.pRdBus[bit]].l _ Ports.NotL[s.pc [lastRd][bit]]; p[ s.sRdBus [bit] ].d _ drive; p[s.sRdBus[bit]].l _ Ports.NotL[s.stat [lastRd][bit]]}; ENDCASE => { p[ s.pRdBus [bit] ].d _ drive; p[ s.pRdBus [bit] ].l _ X; p[ s.sRdBus [bit] ].d _ drive; p[ s.sRdBus [bit] ].l _ X}; ENDLOOP}; END.