IFURAMControl.rose
Copyright © 1984 by Xerox Corporation. All rights reserved.
Last edited by: McCreight, September 11, 1984 5:58:58 pm PDT
Last edited by: Curry, September 28, 1984 10:14:09 am PDT
Cedar
iBufWords: NAT = 4;
iBufBytes: NAT = 4*iBufWords;
iStackWords: NAT = 16;
InBufInterval:
PROC [ point, base, length:
NAT, modulus:
NAT ← iBufBytes ]
RETURNS [
BOOL ] =
{RETURN[InInterval[point, base, length, modulus]};
InStackInterval:
PROC [ point, base, length:
NAT, modulus:
NAT ← iStackWords ]
RETURNS [
BOOL ] =
{RETURN[InInterval[point, base, length, modulus]};
InInterval:
PROC [ point, base, length, modulus:
NAT ]
RETURNS [
BOOL ] =
{RETURN[Mod[point-base, modulus] < length]};
Mod:
PROC [ x:
INTEGER, modulus:
NAT ]
RETURNS [
NAT ] =
{RETURN[(x+modulus) MOD modulus]};
IFUFetchControl:
CELL [
Signal names obey the following convention: If a signal x is computed during PhA and remains valid throughout the following PhB, it is denoted as xAB. If x is computed during PhA and can change during the following PhB (as, for example, in precharged logic), it is denoted as xA. In this latter case, a client wanting to use x during PhB must receive it in his own latch open during PhA. xBA and xB are defined symmetrically. Positive logic is assumed (asserted = TRUE = 1 = more positive logic voltage); negative-logic signals have an extra "N" at or very near the beginning of the signal name (e.g., PNPError for PBus Negative-TRUE Parity Error).
Interface to IFU control
PreFetchFaultedBA >BOOL,
GetNextInstB <BOOL, -- iff InstReadyA
JumpB <BOOL, -- allowed any time
JumpByteOffsetB <INT[2],
P Interfaces for IFU cache
IPCmdA >EnumType["Dragon.PBusCommands"],
IPRejectB <BOOL,
IPFaultB <EnumType["Dragon.PBusFaults"],
IPNPErrorB =BOOL,
Control slice to IPCHandler
IncrPrefetchPCBA > BOOL,
Control slice to IPrefetchBuffer
IBufWrtWdClkB > INT[4],
IBufRdByteClkA > INT[16],
Control slice to IReg
BufHasAtLeast1A > BOOL, -- control slice
BufHasAtLeast2A > BOOL,
BufHasAtLeast3A > BOOL,
BufHasAtLeast5A > BOOL,
OpLengthAB < INT[3],
Serial debugging interface
All the following signals change during PhA and propagate during the remainder of PhA and PhB, giving an entire clock cycle for them to propagate throughout the machine. Each user must receive them into a latch open during PhB. The effects of changes are intended to happen throughout the following PhA, PhB pair.
DHold0BA, DHold1AB <BOOL, -- must be high before testing
Timing and housekeeping interface
PhA <BOOL,
PhB <BOOL
]
State
phBNeedsCheck: BOOL ← FALSE,
pendingJumpBA, pendingJumpAB: BOOL,
jumpFinishedBA, jumpFinishedAB: BOOL,
newFetchBA: BOOL,
fetchingBA, fetchingAB: BOOL,
faultedBA, faultedAB: BOOL,
firstWrtWordBA, firstWrtWordAB: [0..iBufWords),
firstRdByteBA, firstRdByteAB: [0..iBufBytes)
EvalSimple
IF PhA
THEN
BEGIN
pendingJumpAB ← pendingJumpBA;
jumpFinishedAB ← jumpFinishedBA;
fetchingAB ← fetchingBA;
faultedAB ← faultedBA;
firstRdByteAB ← firstRdByteBA;
firstWrtWordAB ← firstWrtWordBA;
IPCmdA ← IF newFetchBA THEN Fetch ELSE NoOp;
BufHasAtLeast1A ← jumpFinishedBA AND firstRdByteBA#4*firstWrtWordBA;
BufHasAtLeast2A ← ((firstRdByteBA+1) MOD iBufBytes)#4*firstWrtWordBA;
BufHasAtLeast3A ← ((firstRdByteBA+2) MOD iBufBytes)#4*firstWrtWordBA;
BufHasAtLeast5A ← ((firstRdByteBA+3)
MOD iBufBytes)#4*firstWrtWordBA
AND
((firstRdByteBA+4) MOD iBufBytes)#4*firstWrtWordBA;
IBufRdByteClkA ← BitOps.WShift[op: 1, containerWidth: 16, shift: firstRdByteBA];
END -- of PhA evaluation
IF PhB
THEN
BEGIN
pendingJumpBA ← (DHold1AB
AND pendingJumpAB)
OR
(pendingJumpAB AND IPRejectB) OR
(NOT DHold1AB AND JumpB AND IPRejectB);
jumpFinishedBA ← (DHold1AB
AND jumpFinishedAB)
OR
(jumpFinishedAB AND NOT JumpB) OR
(NOT DHold1AB AND NOT pendingJumpAB AND NOT JumpB AND NOT IPRejectB);
newFetchBA ←
(NOT DHold1AB AND NOT faultedAB AND NOT IPRejectB AND fetchingAB AND NOT InBufInterval[point: 4*firstWrtWordAB, base: firstRdByteAB, length: 9] -- plenty of space exists -- ) OR
(NOT DHold1AB AND NOT faultedAB AND NOT IPRejectB AND NOT fetchingAB AND NOT InBufInterval[point: 4*firstWrtWordAB, base: firstRdByteAB, length: 5] -- slightly less space exists -- );
fetchingBA ← (DHold1AB
AND fetchingAB)
OR
(fetchingAB AND IPRejectB AND IPFaultB#None) OR
newFetchBA;
faultedBA ← (DHold1AB
AND faultedAB)
OR
(faultedAB AND NOT JumpB) OR
(NOT DHold1AB AND IPFaultB#None);
firstWrtWordBA ←
SELECT
TRUE
FROM
DHold1AB => firstWrtWordAB,
JumpB => 0,
fetchingAB AND NOT IPRejectB => (firstWrtWordAB+1) MOD iBufWords,
ENDCASE => firstWrtWordAB;
firstRdByteBA ←
SELECT
TRUE
FROM
DHold1AB=> firstRdByteAB,
JumpB => JumpByteOffsetB,
GetNextInstB => (firstRdByteAB+OpLengthAB) MOD iBufBytes,
ENDCASE => firstRdByteAB;
IncrPrefetchPCBA ←
NOT DHold1AB
AND fetchingAB
AND NOT IPRejectB
AND NOT pendingJumpAB
AND NOT JumpB;
IBufWrtWdClkB ← BitOps.WShift[op: (IF fetchingAB THEN 1 ELSE 0), containerWidth: 4, shift: firstWrtWordAB];
phBNeedsCheck ← TRUE;
END -- of PhB evaluation
ELSE
BEGIN
IF phBNeedsCheck
THEN
BEGIN
Dragon.Assert[NOT (IPFaultB # None AND NOT IPRejectB)];
Dragon.Assert[NOT (GetNextInstB AND (JumpB OR NOT jumpFinishedBA OR InBufInterval[point: 4*firstWrtWordAB, base: firstRdByteAB, length: OpLengthAB]))];
phBNeedsCheck ← FALSE;
END;
IBufWrtWdClkB ← 0;
END
IFUStackControl:
CELL [
Interface to IFU control
ResetBA < BOOL,
IStkPushBA < BOOL,
IStkPopBA < BOOL,
IStkEmptyA > BOOL,
IStkTooFullA > BOOL,
Control slice to IPCStack
PushEldestPCA < BOOL,
PopEldestPCA < BOOL,
WritePCStackBA < BOOL,
IPCStkWrtClkA > INT[16],
IPCStkRdClkB > INT[16],
Control slice to ILStack
ILStkWrtClkA < INT[16],
ILStkRdClkB < INT[16],
Lev0BaddrBA <INT[8], -- for LIFUR
Lev3CaddrBA <INT[8], -- for SIFUR
XBSourceBA <EnumType["DragonMicroPLA.XBSource"],
Serial debugging interface
All the following signals change during PhA and propagate during the remainder of PhA and PhB, giving an entire clock cycle for them to propagate throughout the machine. Each user must receive them into a latch open during PhB. The effects of changes are intended to happen throughout the following PhA, PhB pair.
DHold0BA, DHold1AB <BOOL, -- must be high before testing
PhA <BOOL,
PhB <BOOL
]
State
phALast: BOOL;
topBA, topAB, bottomBA, bottomAB: [0..iStackWords),
pushYoungestA, popYoungestA, pushEldestA, popEldestA, wasEmpty: BOOL ← FALSE
EvalSimple
b0: DragOpsCross.ProcessorRegister ← DragonIFU.BytetoPR[Lev0BaddrBA];
c3: DragOpsCross.ProcessorRegister ← DragonIFU.BytetoPR[Lev3CaddrBA];
IF PhA
THEN
BEGIN
topAB ←
SELECT
TRUE
FROM
DHold0BA => topBA,
ResetBA => 0,
IStkPushBA OR PushLevel3BA => topBA+1,
IStkPopBA => topBA-1,
ENDCASE => topBA;
bottomAB ←
SELECT
TRUE
FROM
DHold0BA => bottomBA,
ResetBA => 0,
c3 = ifuEldestPC => bottomBA-1,
b0 = ifuEldestPC => bottomBA+1,
ENDCASE => bottomBA;
IStkEmptyA ← topBA=bottomBA;
IStkTooFull ← Mod[topBA-bottomBA, iStackWords] < (iStackWords-gap);
IPCStkWrtClkA ← BitOps.WShift[op: 1, containerWidth: 16, shift: topBA];
ILStkWrtClkA ← BitOps.WShift[op: 1, containerWidth: 16, shift: topBA];
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
phALast ← TRUE;
END
ELSE
BEGIN
IF phALast
THEN
BEGIN
Dragon.Assert[NOT Dragon.MoreThanOneOf[IStkPushBA, PushLevel3BA]];
Dragon.Assert[NOT Dragon.MoreThanOneOf[c3 = ifuEldestPC, b0 = ifuEldestPC]];
Dragon.Assert[NOT Dragon.MoreThanOneOf[IStkPushBA OR PushLevel3BA, IStkPopBA]];
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};
phALast ← FALSE;
END;
IPCStkWrtClkA ← 0;
END;
IF PhB
THEN
BEGIN
topBA ←
SELECT
TRUE
FROM
DHold1AB => topAB,
pushYoungestA => topAB+1,
popYoungestA => topAB-1,
ENDCASE => topAB;
bottomBA ←
SELECT
TRUE
FROM
DHold1AB => bottomAB,
pushEldestA => bottomAB-1,
popEldestA => bottomAB+1,
ENDCASE => bottomAB;
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;