IStack.rose
Copyright © 1984 by Xerox Corporation. All rights reserved.
Last edited by: McCreight, April 9, 1984 1:34:58 pm PST
Last edited by: Curry, August 21, 1984 12:35:43 pm PDT
Directory Dragon, DragOpsCross, DragonMicroPLA;
Imports BitOps, Dragon, DragonIFU;
Cedar
depth: NAT = 16;
gap: NAT = 5;
lwx: NAT = 7;
lpx: NAT = 32-lwx;
m1:NAT = depth-1;
;
IStack: CELL [
Interface within IFU
PushLevel3BA <BOOL,
IStkPushBA  <BOOL,
IStkPopBA  <BOOL,
IStkEmptyA  >BOOL,
IStkTooFullA  >BOOL,
Lev0BaddrBA <INT[8], -- for LIFUR
Lev3CaddrBA <INT[8], -- for SIFUR
Lev3PBA   <INT[32],
Lev3LBA   <INT[8],
XBus    =INT[32],
XBSourceBA  <EnumType["DragonMicroPLA.XBSource"],
Serial debugging interface
ResetAB   <BOOL,
DHoldAB   <BOOL,
DShiftAB   <BOOL,
DExecuteAB  <BOOL,
DNSelectAB  <BOOL,
DDataInAB  <BOOL,
DDataOutAB  =BOOL,
Timing and housekeeping interface
RescheduleAB <BOOL,
PhA    <BOOL,
PhB    <BOOL
]
State
Note: When a signal ends in an x, it is calculated during x and stable during x'.
iStk: ARRAY [0..depth) OF RECORD [
valid: ARRAY Dragon.Phase OF BOOLALL[FALSE],
p: Dragon.HexWord,
l: Dragon.HexByte
],
pushYoungestA, popYoungestA, pushEldestA, popEldestA, wasEmpty: BOOLFALSE
EvalSimple
b0: DragOpsCross.ProcessorRegister ← DragonIFU.BytetoPR[Lev0BaddrBA];
c3: DragOpsCross.ProcessorRegister ← DragonIFU.BytetoPR[Lev3CaddrBA];
Valid:PROC[index:NAT] RETURNS[BOOLEAN] = {
RETURN[NOT ResetAB AND iStk[index MOD depth].valid[a]]};
IF PhA THEN
BEGIN
top, bot, size: [0..depth] ← depth;
delta:INT[-2..+2] ← 0;
Dragon.Assert[NOT(IStkPushBA AND PushLevel3BA)];
pushYoungestA ← IStkPushBA OR PushLevel3BA;
popYoungestA ← IStkPopBA;
pushEldestA  ← c3 = ifuEldestPC;
popEldestA  ← b0 = ifuEldestPC;
wasEmpty  ← FALSE;
IF pushYoungestA THEN delta ← delta+1;
IF popYoungestA THEN delta ← delta-1;
IF pushEldestA  THEN delta ← delta+1;
IF popEldestA  THEN delta ← delta-1;
Dragon.Assert[NOT pushEldestA  OR NOT popEldestA,  "Not Both at once"];
Dragon.Assert[NOT pushYoungestA OR NOT popYoungestA, "Not Both at once"];
FOR i: NAT IN [0..depth) DO iStk[i].valid[a] ← iStk[i].valid[b] ENDLOOP;
FOR i: NAT IN [0..depth) DO
IF Valid[i] AND NOT Valid[i+ 1] THEN top ← i;
IF Valid[i] AND NOT Valid[i+m1] THEN bot ← i;
ENDLOOP;
IF top=depth OR bot=depth THEN {
Dragon.Assert[top=depth AND bot=depth, "Both or neither"];
top ← 0; bot ← 1; wasEmpty ← TRUE;
IF Valid[0] THEN Dragon.Assert[FALSE, "IStack completely full"]};
size ← (top+(depth-bot)+1) MOD depth;
SELECT delta+size FROM
<0     => Dragon.Assert[FALSE, "IStack Underflowed"];
=0     => {IStkEmptyA ← TRUE; IStkTooFullA ← FALSE};
IN(0..depth-gap] => {IStkEmptyA ← FALSE; IStkTooFullA ← FALSE};
ENDCASE   => {IStkEmptyA ← FALSE; IStkTooFullA ← TRUE};
iStk[(top+1) MOD depth] ←
[ p:Dragon.LFD[Lev3PBA], l:BitOps.ECFW[Lev3LBA, lwx, 0, lwx] ];
SELECT TRUE FROM
b0 IN [ifuYoungestL..ifuEldestPC] => {
Dragon.Assert[ NOT wasEmpty ];
SELECT b0 FROM
ifuYoungestL => XBus ← BitOps.ICID[iStk[top].l, [0,0], 32, lpx, lwx];
ifuYoungestPC => XBus ← Dragon.LTD[iStk[top].p];
ifuEldestL  => XBus ← BitOps.ICID[iStk[bot].l, [0,0], 32, lpx, lwx];
ifuEldestPC  => XBus ← Dragon.LTD[iStk[bot].p];
ENDCASE   => NULL}; -- Not an IFU stack register
c3 IN [ifuYoungestL..ifuEldestPC] =>
SELECT c3 FROM
ifuYoungestL => iStk[top].l ← BitOps.ECFD[XBus, 32, lpx, lwx];
ifuYoungestPC => iStk[top].p ← Dragon.LFD[XBus];
ifuEldestL  => iStk[bot].l ← BitOps.ECFD[XBus, 32, lpx, lwx];
ifuEldestPC  => iStk[(bot+m1) MOD depth].p ← Dragon.LFD[XBus];
ENDCASE   => NULL; -- Not an IFU stack register
ENDCASE => NULL; -- nothing special happening
END;
IF PhB THEN
BEGIN
FOR i: NAT IN [0..depth) DO
iStk[i].valid[b] ←
(Valid[i] AND NOT popYoungestA AND NOT popEldestA) OR
(Valid[i] AND Valid[i+m1] AND NOT popYoungestA) OR
(Valid[i] AND Valid[i+1] AND NOT popEldestA) OR
(Valid[i] AND Valid[i+1] AND Valid[i+m1]) OR
(Valid[i+1 ] AND pushEldestA) OR
(Valid[i+m1] AND pushYoungestA) OR
(wasEmpty AND pushEldestA  AND i=0) OR
(wasEmpty AND pushYoungestA AND i=1);
ENDLOOP;
FOR i: NAT IN [0..depth) DO
IF iStk[i].valid[b]
AND NOT iStk[(i+1) MOD depth].valid[b] -- top
AND XBSourceBA = iStackPC THEN {
Dragon.Assert[ NOT IStkEmptyA ];
XBus ← Dragon.LTD[iStk[i].p]};
ENDLOOP;
END;
ENDCELL