IFUSimStackBuf.mesa
Last edited by Curry October 22, 1986 3:29:31 pm PDT
Don Curry October 24, 1986 5:49:21 pm PDT
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];
[]𡤌oreFlat.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
THENNARROW[oldStateAny]
ELSENEW[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.