Imports BitOps, Dragon; 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 [ PreFetchFaultedBA >BOOL, GetNextInstB EnumType["Dragon.PBusCommands"], IPRejectB BOOL, IBufWrtWdClkB > INT[4], IBufRdByteClkA > INT[16], BufHasAtLeast1A > BOOL, -- control slice BufHasAtLeast2A > BOOL, BufHasAtLeast3A > BOOL, BufHasAtLeast5A > BOOL, OpLengthAB < INT[3], DHold0BA, 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 ENDCELL; IFUStackControl: CELL [ ResetBA < BOOL, IStkPushBA < BOOL, IStkPopBA < BOOL, IStkEmptyA > BOOL, IStkTooFullA > BOOL, PushEldestPCA < BOOL, PopEldestPCA < BOOL, WritePCStackBA < BOOL, IPCStkWrtClkA > INT[16], IPCStkRdClkB > INT[16], ILStkWrtClkA < INT[16], ILStkRdClkB < INT[16], Lev0BaddrBA 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; ENDCELL IFURAMControl.rose Copyright c 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 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 P Interfaces for IFU cache Control slice to IPCHandler Control slice to IPrefetchBuffer Control slice to IReg 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. Timing and housekeeping interface Interface to IFU control Control slice to IPCStack Control slice to ILStack 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. Ê J˜šÐbl™™Jšœ Ïmœ1™Jšœ& œ˜0Jšœ$ œ˜=Jšœ œ œ˜>Jš œ ¢˜/——Jš œ ¢˜-—Jšœ  œ˜Jš ˜—š ˜Jš ˜š œ  ˜Jš ˜Jšœ œ1˜BJšœ œ& œ˜LJšœ œ! œ  œ ˜OJ˜š œ  œ  œ˜ Jšœ œ˜:Jšœ œ˜"Jš œ  œ œ˜A—J˜Jšœ œ˜%š œ  ˜Jšœ œ˜5Jšœ œ œ˜4Jš œ  œ œ˜?Jš œ œ œ˜7—Jšœ  œ˜Jš œ˜—Jšœ˜Jš œ˜J˜—š œ ˜ Jš ˜J˜šœ œ œ ˜Jšœ˜Jšœ˜Jšœ˜Jš œ ˜—J˜šœ  œ œ ˜Jšœ˜Jšœ˜Jšœ˜Jš œ ˜J˜—J˜š œ œ œ  ˜š œ˜Jš œ œ  œ¢˜-š œ œ˜ Jšœ œ˜ Jšœ œ ˜——Jš œ˜—Jš œ˜———Jš ˜—…—ä/2