%
Page Numbers: Yes First Page: 1
Heading:
Ifu1.mcMay 6, 1982 10:51 PM%
TITLE[Ifu1];
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CONTENTS
TESTDESCRIPTION
beginIfu1:Control subroutine that calls each test in this file
i.XXXXXXIfuReset, PcFG←, getPcX, ifuJump, resched, various scope loops, etc.
ifuMemRW:read and write ifu memory
iMemRandAddrs:Ifu memory r/w test that uses random addrs and random data.
iMemAddrs:Test addressing logic for ifu memory.
ifuMScopeLoop:infinite loop that reads location 0 then location 1 of IfuM
iSingleStepTest:single step, under Dorado processor control, ifu
itTestCase1:First test that uses the ifuTest register
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%
May 6, 1982 10:51 PM
Add comments in ifu1.itTestCase1
April 21, 1982 1:45 PM
Improve single step test to checkout more bits in the pipeline
April 13, 1982 6:23 PM
Improve IfuScopeLoop
June 18, 1981 9:26 AM
Move common code from this file into IfuSubrs.mc
May 18, 1981 2:25 PM
Fix nextPat to invoke cycleRandV to get better performance from the random number generator.
February 1, 1980 7:58 PM
Fix stack handling bug in return code of addressing test. Fix old bug in fastStore code that was fetching rather than storing.
February 1, 1980 7:48 PM
Add code to mask out unwanted bits from getIfuLH in addressing test.
February 1, 1980 6:37 PM
Add iMemAddrs, an addressing logic test.
February 1, 1980 5:06 PM
Improve the set of patterns generated by pat16.
September 19, 1979 1:13 PM
Reset expectedDispatch<0 after invoking iSingleStepTest.
September 19, 1979 12:55 PM
Move beginIfu1 to the beginning of the file, add more and better comments, and set up iSingleStepTest to loop 400 times.
September 17, 1979 5:29 PM
Add iSingleStepTest.
July 3, 1979 1:53 AM
Increment return link in checkException by 1 -- because afterdispatch will also decrement it & we need compatability. This increment occurs after the potential error check where the link has been decremented to make error interpretation easier.
July 3, 1979 1:17 AM
Decrement return link in checkException by 1 -- so that it points to where we came from rather than where to return to, which is irrelevant..
July 3, 1979 12:06 AM
Add code to enable dynamically selected exception conditions.
June 29, 1979 11:46 AM
Modify afterDispatch to save POINTERS into (stack+1), but to return control with stkp = entering value. Do this since afterDispatch resets RBASE to defaultRegion, and some tests want to check the value that RBASE got set to when the IfuJump occured.
June 20, 1979 9:14 AM
Add call to resetIfu in iMemRandAddrs and cause beginIfu1 to invoke iMemRandAddrs.
June 20, 1979 8:50 AM
Add ifuLHmaskC masking to data in iMemRandAddrs
June 20, 1979 7:35 AM
Add random address generation test (iMemRandAddrs)
June 19, 1979 10:34 AM
Fix register clobbering bug in new version of ifuMemRW.
June 18, 1979 8:56 AM
Fix bug in 3rd pattern of nextPat16.
June 17, 1979 4:04 PM
Add entry points for all the exception conditions
June 15, 1979 3:24 PM
Enable random patterns in iMemRW
June 5, 1979 12:43 PM
Remove i.testCase2L since test2 has been removed from default diagnostic.
June 5, 1979 11:31 AM
Add disableConditionTask
May 30, 1979 10:08 AM
Add random numbers to pat16 code; diddle iMemRW to reset the Ifu only once.
May 9, 1979 9:05 AM
Fix subroutine mode error in ifuMScopeLoop. Move contents section to top of file & add more comments.
May 4, 1979 10:57 AM
Add scope loop for checking Ram speed.
May 3, 1979 8:44 AM
Add calls to setIUsingInstrSet before invoking initIfuM1Thru(3,16)
April 26, 1979 9:53 AM
Add pat8 subroutines.
April 25, 1979 12:13 PM
Add fastExit, fastFetch, fastStore code.
April 24, 1979 5:27 PM
Remove references to dispatchOffset, simplify afterDispatch.
April 22, 1979 5:10 PM
Move iAddFGParity thru itStep into ifuStepSubrs.mc
February 7, 1979 10:35 AM
Add breakpoints to rampe, kfault, resched entries; explicitly place all the entry points for the instructions.
February 6, 1979 2:16 PM
Add requisite noop after PcF←.
February 5, 1979 12:54 PM
Add ifAd20 -- ifu pause/halt code
February 5, 1979 9:59 AM
Change opifad13,14,16 to do ifuJumps directly.
January 18, 1979 6:44 PM
Fix misc. bugs in pattern16, muffler bit reading code
January 17, 1979 3:52 PM
More Rev-Bb mods: define exception code for instrSet 1 (locations 200,204,214,234,274). Define itMosFhSh.
January 15, 1979 4:52 PM
Rev-Bb mods: instrSet bits, complemented, are or’d into Exception addresses. InstrSet bits 2,3 pick bytes right to left. Cycled 0 pattern for Ifu memory test.
%
* February 1, 1980 6:37 PM
beginIfu1:
pushReturn[];
call[disableConditionalTask];
call[ifuMemRW];
call[iMemRandAddrs];
call[iMemAddrs];
call[iSingleStepTest];
expectedDispatch←a1;
returnP[];
* November 30, 1978 9:07 AM
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
SINGLE STEP and INITIAL DEBUGGING CODE:
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
top level;
i.getPcX: branch[.], t ← not(PcX’);
i.ifuJump: ifuJump[0];* try ifu next macro...
i.ifuJumpF:
ifuJump[0, r odd], r0;* conditional branch condition is false
noop;
i.ifuJumpT:
t ← (r0)+1;
ifuJump[0, ALU=0];* conditional branch condition is true
noop;
i.mos: branch[.], mos ← t;* set instructyion set w/ t
i.nextData: branch[.], t ← ID;* get next data from ifu
i.noResched: branch[.], noReschedule;* NO resched
i.reset: branch[.], IfuReset;* Ifu Reset
i.resched: branch[.], reschedule;* resched
i.setPcFG: branch[.], PcF←t;* SET T
i.test: branch[.], ifuTest ← t;* load TEST register
i.tick: branch[.], ifutick;* Tick
i.WriteLHL: * Write LEFT HALF IFU ram SET. rscr3 = addr, rscr4 = value
rscr ← rscr4;* value to write kept in rscr4
call[putIfuLH], t ← rscr3;* address to write kept in rscr3
branch[i.WriteLHL];* do it again for scope loop
i.WriteRHL: * Write RIGHT HALF IFU ram. SET rscr3 = addr, rscr4 = value
rscr ← rscr4;* value to write kept in rscr4
call[putIfuRH], t ← rscr3;* address to write kept in rscr3
branch[i.WriteRHL];* do it again for scope loop
i.ReadLHL: * Read LEFT HALF IFU ram. SET rscr3 = addr
call[getIfuLH], t ← rscr3;* keep addr to read in rscr3
branch[i.ReadLHL];* do it again for scope loop
i.ReadRHL: * Read RIGHT HALF IFU ram. SET rscr3 = addr
call[getIfuRH], t ← rscr3;* keep addr to read in rscr3
branch[i.ReadRHL];* do it again for scope loop
i.testCase1L:
call[setIUsingInstrSet], t ← 1C;
call[InitIfuM1Thru3];
call[itTestCase1];
branch[.-1];
%* commented out since we’re removed test2 from ifu default diagnostic
i.testCase2L:
call[setIUsingInstrSet], t ← 1C;
call[initIfuM0Thru16];
call[itTestCase2];
branch[.-1];
%
i.WRl:*Write, then Read an ifu memory location
rscr ← 1c;* use FF constants so it’s easy to patch.
t ← 2c;
call[putIfuRH];
t←1c;
call[getIfuRH];
branch[i.WRl];
i.RWl:*Read, then Write an ifu memory location
t←1c;* use FF constants so it’s easy to patch.
call[getIfuRH];
rscr ← 1c;
t ← 2c;
call[putIfuRH];
branch[i.RWl];
* May 4, 1979 10:59 AM
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
iMemRWRead and write the ifu RAM
FOR pat IN NPats DO
saveRandState[];-- remember random number state
FOR iAddrX IN [0..1777B] DO
ifuLoMem[addr] ← getPattern[pat, addr];
ifuHiMem[addr] ← getPattern[pat, addr];
ENDLOOP:
restoreRandState[];-- restore random number state
FOR iAddrX IN [0..1777B] DO
IF ifuLoMem[addr] # getPattern[pat,addr] THEN ERROR;
IF ifuHiMem[addr] # getPattern[pat,addr] THEN ERROR;
ENDLOOP;-- end of address loop;
ENDLOOP;-- end of pattern loop
Notice that this code pushes the stack and keeps the current address there.
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ifuMemRW: * read and write the Ifu memory
pushReturn[];
IfuReset[];* make sure its stopped
call[iPat16], stkp+1;* init 16 bit patterns. keep addr on stack
iMemPatL:
call[nextPat16];* select next 16 bit pattern or exit
branch[afterIMemPatL,ALU=0];
noop;* for placement
call[saveRandState];
call[iIAddr];* init ifu addresses
iMemAddrWL:
call[nextIAddr];* select next ifu address or exit
branch[afterIAddrWL,ALU=0], stack ← t;* save current addr on stack!
noop;
* Write Left Half of Ifu memory
call[getPat16], t ← stack;* rtn t = pattern
rscr ← t;* pass pattern in rscr
call[putIfuLH], t ← stack;* write ifu left half
* Write Right Half of Ifu memory
call[getPat16], t ← stack;* rtn t = pattern
rscr ← t;* pass pattern in rscr
call[putIfuRH], t ← stack;* write Ifu right half
branch[iMemAddrWL];
* June 19, 1979 10:34 AM
* Now read and check
afterIaddrWL:
call[restoreRandState];
call[iIAddr];
iMemAddrRL:
call[nextIAddr];
branch[afterIAddrRL, ALU=0], stack ← t;* save current addr on stack!
noop;
* Check Left Half
call[getIfuLH];* read back left half
rscr ← t;* remember LH in rscr.
call[getPat16], t ← stack;* rtns t = pattern
rscr ← (rscr) and (ifuLHmaskC);* remove ID count, InstrSet
t ← t and (ifuLHmaskC);* ignore corresponding bits in pattern
(rscr) # t;
skpif[ALU=0];* iAddrx= address that failed
iMemLHErr1:* left half data not what we wrote.
error;* t = expected value; rscr = value from ifu
* Check Right Half
call[getIfuRH], t ← stack;* read back right half
rscr ← t;* remember RH in rscr.
call[getPat16], t ← stack;* rtns t = pattern
(rscr) # t;
skpif[ALU=0];* iAddrx= address that failed
iMemRHErr1:* right half data not what we wrote
error;* t = expected value, rscr = ifu value
branch[iMemAddrRL];* branch for next address
afterIAddrRL:
branch[iMemPatL];
afterIMemPatL:
pReturnP[];* extra pop since we’ve kep iAddr there.
* June 20, 1979 9:13 AM
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
iMemRandAddrs
This test generates a series of pairs ofrandom addresses, writes into those pairs of locations and then checks the data to see that it is correct.
FOR itrs IN [0..10000] DO
addr2 ← addr1 ← getRandom[] and (1777B);
UNTIL addr2 # addr1 DO addr2 ← getRandom[] and (1777B);
lh1 ← getRandom[] and lhMask; rh1 ← getRandom[];
lh2 ← getRandom[] and lhMask; rh2 ← getRandom[];
ifuLhMem[addr1] ← lh1; ifuRhMem[addr1] ← rh1;
ifuLhMem[addr2] ← lh2; ifuRhMem[addr2] ← rh2;
IF (ifuLhMem[addr1] and ifuLHmask) # lh1 THEN ERROR;
IF ifuRhMem[addr1] # rh1 THEN ERROR:
IF (ifuLhMem[addr2] and ifuLHmask) # lh2 THEN ERROR;
IF ifuRhMem[addr2] # rh2 THEN ERROR;
ENDLOOP;
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
iMemRandAddrs: pushReturn[];
call[resetIfu];
t ← 10000C;
cnt ← t;* loop 10000B times
iMemRandAddrsL:
noop;* for placement
call[get1Rand];
iAddr1 ← t ← t and (1777C);
iAddr2 ← t;
iMemRandAddrsL2:* get 2 unique, random addresses
call[get1Rand];
t ← t and (1777C);* isolate the bits for ifu ram addresses
t # (iAddr1);
branch[iMemRandAddrsL2, ALU=0];* still need different, random address
noop;* for placement
call[get1Rand], iAddr2 ← t;* get random values
call[get1Rand], value1left ← t and (IfuLHmaskC);
call[get1Rand], value1right ← t;
call[get1Rand], value2left ← t and (IfuLHmaskC);
* now write random data into our two randomly chosen locations
value2right ← t;* write into iAddr1
rscr ← value1left;
call[putIfuLh], t ← iAddr1;
rscr ← value1right;
call[putIfuRh], t ← iAddr1;
rscr ← value2left;* write into iAddr2
call[putIfuLh], t ← iAddr2;
rscr ← value2right;
call[putIfuRh], t ← iAddr2;
* now check that the data is correct.
call[getIfuLh], t ← iAddr1;
t ← t and (IfuLHmaskC);* remove the extra, non Ifu Ram bits
t # (value1left);
skpif[ALU=0];
iMemRandAddrsErr1lh:* value at iAddr1 has left half value in T
error;* and it doesn’t match value1left.
call[getIfuRh], t ← iAddr1;
t # (value1right);
skpif[ALU=0];
iMemRandAddrsErr1rh:* value at iAddr1 has right half value in T
error;* and it doesn’t match value1right
call[getIfuLh], t ← iAddr2;
t ← t and (IfuLHmaskC);* remove the extra, non Ifu Ram bits
t # (value2left);
skpif[ALU=0];
iMemRandAddrsErr2lh:* value at iAddr2 has left half value in T
error;* and it doesn’t match value2left
call[getIfuRh], t ← iAddr2;
t # (value2right);
skpif[ALU=0];
iMemRandAddrsErr2rh:* value at iAddr2 has right half value in T
error;* and it doesn’t match value2right
loopUntil[cnt=0&-1, iMemRandAddrsL];
returnP[];
* February 1, 1980 6:39 PM
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
iMemAddrs
This test checks the memory addressing logic. It assumes that the data bits work. Failures in the data bits may produce a spurious complaint from this test. The algorithm is identical to the one employed in all the microcoded addressing tests for the memory system.
Storage Addressing Test
Background memory w/ 0 then write -1 into ascending addresses. Before the write,
check that the word that is about to be written is still zero. Suppose it is non zero.
Then there was an addressing error. Remember the address of the non zero word, background memory with zeros again and proceed writing -1s. This time, check the
previously clobbered address each time before writing the -1. This approach will catch the reference that clobbers the known location. The same algorithm can be applied for
descending addresses, mutatis mutandi, to finish a complete check of the addressing logic.
iAddrCheck: PROCEDURE=
BEGIN
zeroMem: PROCEDURE
BEGIN
FOR i IN IfuMemLimits DO IfuMem[i]←0; ENDLOOP;
END;
findErrUp: PROCEDURE [clobbered: VA] =
BEGIN
zeroMem[];
FOR i IN VA DO
IF IfuMem[clobbered]#0 THEN SIGNAL ErrUp[i-1, clobbered];
IfuMem[i] ← -1;
ENDLOOP;
SIGNAL IntermittentErrUp[clobbered];
END;
findErrDown: PROCEDURE [clobbered: VA] =
BEGIN
zeroMem[];
FOR i DECREASING IN VA DO
IF IfuMem[clobbered] #0 THEN SIGNAL ErrDown[i+1, clobbered];
IfuMem[i] ← -1;
ENDLOOP;
SIGNAL IntermittentErrDown[clobbered];
END;
-- this is the program
zeroMem[];
FOR i IN VA DO
IF IfuMem[i] # 0 THEN FindErrUp[i];
IfuMem[i] ← -1;
ENDLOOP;
zeroMem[];
FOR i DECREASING IN VA DO
IF IfuMem[i] # 0 THEN FindErrDown[i];
IfuMem[i] ← -1;
ENDLOOP;
END;
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
iMemAddrs:
pushReturn[];
call[zeroIfuMemory];
call[iIAddr],stkp+1;
iAddrUpL:
call[nextIAddr];
branch[iAddrUpLxit, alu=0], stack ← t;
noop;
call[getIfuLH],t←stack;* check the left half
PD←t and (IfuLHmaskC);
skpif[ALU=0];
branch[iAddrUpFindErr];
rscr←a1;
call[putIfuLH],t←stack;* write all ones into left half
call[getIfuRH],t←stack;* check the right half
PD←t;
skpif[ALU=0];
branch[iAddrUpFindErr];
rscr←a1;
call[putIfuRH],t←stack;* write all ones into right half
branch[iAddrUpL];
iAddrUpLxit:
call[zeroIfuMemory];
call[iIAddrDownCtrl];
iAddrDownL:
call[nextIAddrDown];
branch[iAddrTestDone, alu=0], stack ← t;
noop;
call[getIfuLH],t←stack;* check the left half
PD←t and (IfuLHmaskC);
skpif[ALU=0];
branch[iAddrDownFindErr];
rscr←a1;
call[putIfuLH],t←stack;* write all ones into left half
call[getIfuRH],t←stack;* check the right half
PD←t;
skpif[ALU=0];
branch[iAddrDownFindErr];
rscr←a1;
call[putIfuRH],t←stack;* write all ones into right half
branch[iAddrDownL];
* January 11, 1979 9:14 AM
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
iAddrUpFindErr
This test tries to isolate the reference that clobbered the location (denote it the target location) that was detected by the iAddrUpL loop. The test proceeds as before except that as it ascends memory it continually checks to see if the target location has been clobbered yet.
In general, stack[stkp] contains the "current" address, and
stack[stkp-1] contains the clobbered address detected in iAddrUpL.
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
iAddrUpFindErr:
t←stack&+1;* we’ll save clobbered (target location)
stack←t;* location in stack!
call[zeroIfuMemory];
stkp-1;
call[getIfuLH],t←stack&+1;* reexamine target location
PD←t and (IfuLHmaskC);
skpif[ALU=0],stkp-1;
iAddrUpErr1a:* zeroIfuMemory didn’t work. stkp has
error;* address in question.
call[getIfuRH], t←stack&+1;
PD←t;
skpif[alu=0],stkp-1;
iAddrUpErr1b:* zeroIfuMemory didn’t work. stkp has
error;* address in question.
call[iIAddr],stkp+1;
iAddrUpFindL:
call[nextIAddr];
branch[iAddrUpNoFind, alu=0], stack&-1 ← t;
noop;
call[getIfuLH],t←stack&+1;* check the left half of target addr
PD←t and (IfuLHmaskC);
skpif[ALU=0];
iAddrUpErr2a:* the last store, (value on the stack)-1,
error;* clobbered location at (stkp-1).
rscr←a1;
call[putIfuLH],t←stack;* write all ones into left half
stkp-1;* must check right half of targert addr
call[getIfuRH],t←stack&+1;* check the right half
PD←t;
skpif[ALU=0];
iAddrUpErr2b:* the last store, (value on the stack)-1,
error;* clobbered location at (stkp-1).
rscr←a1;
call[putIfuRH],t←stack;* write all ones into right half
branch[iAddrUpFindL];
iAddrUpNoFind:
error;* intermittent error;
* February 1, 1980 7:57 PM
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
iAddrDownFindErr
This test tries to isolate the reference that clobbered the location (denote it the target location) that was detected by the iAddrDownL loop. The test proceeds as before except that as it descends memory it continually checks to see if the target location has been clobbered yet. Use Flush← to force the target munch out of the cache.
In general, stack[stkp] contains the "current" address, and
stack[stkp-1] contains the clobbered address detected in iAddrUpL.
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
iAddrDownFindErr:
t←stack&+1;* we’ll save clobbered (target location)
stack←t;* location in stack!
call[zeroIfuMemory];
stkp-1;
call[getIfuLH],t←stack&+1;* reexamine target location
PD←t and (IfuLHmaskC);
skpif[ALU=0],stkp-1;
iAddrDownErr1a:* zeroIfuMemory didn’t work. stkp has
error;* address in question.
call[getIfuRH], t←stack&+1;
PD←t;
skpif[alu=0],stkp-1;
iAddrDownErr1b:* zeroIfuMemory didn’t work. stkp has
error;* address in question.
call[iIAddrDownCtrl],stkp+1;
iAddrDownFindL:
call[nextIAddrDown];
branch[iAddrDownNoFind, alu=0], stack ← t;
noop;
call[getIfuLH],t←stack&+1;* check the left half of target addr
PD←t and (IfuLHmaskC);
skpif[ALU=0];
iAddrDownErr2a:* the last store, (value on the stack)-1,
error;* clobbered location at (stkp-1).
rscr←a1;
call[putIfuLH],t←stack;* write all ones into left half
stkp-1;* must check right half of targert addr
call[getIfuRH],t←stack&+1;* check the right half
PD←t;
skpif[ALU=0];
iAddrDownErr2b:* the last store, (value on the stack)-1,
error;* clobbered location at (stkp-1).
rscr←a1;
call[putIfuRH],t←stack;* write all ones into right half
branch[iAddrDownFindL];
iAddrDownNoFind:
error;* intermittent error;
iAddrTestDone:
pReturnP[];
* February 1, 1980 7:25 PM
zeroIfuMemory:
pushReturn[];
call[iIAddr],stkp+1;* we’ll keep the addr on stack
ziMemL:
call[nextIAddr];
branch[ziMemXit, ALU=0], stack←t;* exit if no more addresses to zero
rscr←a0;
call[putIfuLH], t←stack;* zero the left half
rscr←a0;
call[putIfuRH], t←stack;* zero the right half
branch[ziMemL];
ziMemXit:
pReturnP[];
returnP[];
* April 13, 1982 6:05 PM
top level;
IfuMScopeLoop2:
t ← 1c;
stkp ← t;
rscr←a0;
call[ifuDoScopeL], rscr2←1c;
branch[.-1];* trully infinite loop;
IfuMScopeLoop:* enter w/ rscr=loc for all 0s, rscr2=loc for all 1s
call[ifuDoScopeL];
branch[.-1];* truly infinite loop
ifuDoScopeL:* enter w/ 0’s loc=rscr, all 1s’ loc=rscr2
t←rscr;
stack&+1←t;
t←rscr2;
call[resetIfu], stack←t;
* use ff constants so we can patch it later!
call[tGetsA0sLoc],rscr←0C;
call[putIfuLH];* write zeros in 1st loc left half
call[tGetsA0sLoc],rscr←0C;
call[putIfuRH];* write zeros in 1st loc right half
call[tGetsA1sLoc], rscr← cm1;
call[putIfuLH];* write all ones in location 1 left half
call[tGetsA1sLoc], rscr← cm1;
call[putIfuRH];* write all ones in location 1 right half
noop;* keep placement happy
ifuMScopeL:
call[tGetsA0sLoc];
call[getIfuLH];* read 0s LH
call[tGetsA1sLoc];
call[getIfuLH];* read 1s LH
call[tGetsA0sLoc];
call[getIfuRH];* read 0s RH
call[tGetsA1sLoc];
call[getIfuRH];
branch[ifuMScopeL];* read 1s RH
tGetsA0sLoc: subroutine;
stkP-1;
return,t←stack&+1;
tGetsA1sLoc: subroutine;
return, t←stack;
* April 25, 1982 5:59 PM
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
iSingleStepTest
This test uses the Ifu’s TEST register to single step the ifu throug
its paces. The program invokes subroatines that actually clock the Ifu and selected FFs to occur. The "microcode" that we are singlestepping would look like,
PcF←2;* try a 2-byte instruction
IfuJump[0];
t←ID;* somehow, we get back here after IfuJump
t # 10c;* we expect 10 for alpha
skpif[ALU=0];
IDerr:
error;
t←not(pcX’);
t # (2c);
skpif[ALU=0];* we set PcF to 2
PcXerr1:
error;
t←ID;
t # (2c);* we should get IL after alpha
skpif[ALU=0];
IDerr2:
error;
PcF←3c;
IfuJump[0];* somehow, we get back here after IfuJump
t←ID;
t # 20C;
skpif[ALU=0];* expect 20=alpha, 100=beta
IDerr3:
error;
t←not(PcX’);
t # (3c);* we set PcF to 3
skpif[ALU=0];
PcXerr2:
error;
t←ID;
t # (100c);* expect 100=beta
skpif[ALU=0];
IdErr4:
error;
t←ID;
t # (3c);* should get IL after beta
skpif[ALU=0];
IDerr5:
error;
note that the microcode above is a GROSS OVERSIMPLIFICATION of what is happening. It provides "orientation" only!
The way this test works is to initialize the Ifu ram and then to loop 400B times calling the subroutine that actually tests, in single-step mode, the Ifu.
Within this subroutine and iSingleStepTest, stkp points to the ifu data being tested, and stkp-1 points to the pc value being tested.
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
iSingleStepTest:* single step, under Dorado processor control, ifu
pushReturn[];
call[setIusingInstrSet], t←1c;
call[initIfuM1Thru3];
t← 1c, stkp+1;
stack←t;* This is the PC address we’ll test
t←377c, stkp+1;
stack←t;* This is the ifuData (alpha)
iSingleStepTestL:
t←stack&-1;
q←stack&+1;
call[itTestCase1], rscr←q;* t= alpha byte, rscr= pc value
stkp-1;* now we left cycle the expected pc value
stack← lsh[stack,1];
skpif[ALU#0];
stack←1c;* restart if only 1 bit drops off end
stkp+1;
stack←(stack)-1;* change expected alpha value
loopUntil[ALU<0, iSingleStepTestL];
stkP-2;* pop "test alpha" and "test Pc"
returnP[];
* April 25, 1982 5:44 PM
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
run the ifu thru one test case
Enter: t= test alpha value, rscr=test pc value
USE: stkp-1 points to pc value, stkp points to alpha value
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
itTestCase1: subroutine;
pushReturn[];
q← t, stkp+1;* save expected alpha in q
t←rscr;* save the expected pc value
stack&+1← t;* at "stkp-1"
stack← q;* save expected alpha at "stkp"
itTestCase10:
call[itResetSH];* RESET
t ← 1c;* use instruction set 1
call[itMosFhSh];
%
OPCODE 1 in this sequence comes from location 2 in the Ifu Ram. It is a two byter. We must step the "2" into J. The ifudata is 10 for this sequence. We write PcF with 2.
%
call[itNoopFHSH];
call[itGetPcVal];* retrive pc val from stkp-1
call[itNewPcFHSH], q←t;* NewPc←t, save new pc val in q
call[itNoopFHSH], t←q;* keep new pc value on Bmux during tick
call[itNoopFH];
noop;* here for placement
itTestCase11:
call[itMemAckSHFH];* MemAck Sh Fh
rscr←q;* if odd Pc then we must provide an
skpIf[r odd], rscr;* "additional response" from the memory
branch[itEvenPc];* since the 1st byte (the opcode) will
itOddPc:
call[itMakeFDAckSh];* empty FG completely (odd PcFG means we
call[itMemAckFh];* use only one of the two bytes!).
call[itSetFGFDSh], t ← 2c;* address word 2 in ifu ram (data for j)
call[itNoopFhSh];
call[itSetFGFh], t←stack;* data for H (allows Mld, Jld on next t0)
call[itSetFGSh], t← 3c;* next opcode=3
branch[itTestCase12];
itEvenPc:
call[itMakeFDSh];* MakeF←D SH
call[itNoopFH];
call[itSetFGSH], t ← 2c;* value for J
call[itSetFGFH], t ← stack;* value for H (alpha)
call[itNoopSH];
itTestCase12:
call[itNoopFH];
expectedDispatch ← opAt15;* we expect ifujump to goto opAt15
call[itIfuJumpSH];* IfuJump[0]
call[itNoopFH];
call[itNextDataSH];* ←NextData
t#(stack);
skpif[ALU=0];
itCaseErr10:
Breakpoint;
noop;* here for placement
call[itNoopFH];
call[itGetPcVal];* retrieve pc value from stkp-1
q←t;
call[itGetPcXSH];* ←PcX
t # (q);
skpif[ALU=0];
itCaseErr12:
Breakpoint;* pcx wasn’t correct
t←1c;* patch this instruction if you want
Q←t;* to loop more than once
itCaseL1:
noop;* Get Instr Length from ←NextData
call[itNoopFH];
call[itNextDataSH];* ←NextData
t#(2c);* should get instruction length
skpif[ALU=0];
itCaseErr13:
Breakpoint;
noop;
t←(Q)-1;
loopUntil[ALU=0, itCaseL1],Q←t;* check out instruction length a few times
* April 22, 1982 10:55 PM
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
OPCODE2 in this sequence comes from location 3 in the Ifu Ram. It is a three byter. We must step the "3" into J. Likewise we step 20 and 100 into H. Allow the normal sequencing of the pipe to increment PcFG, etc. Remember that if the starting Pc was odd that the test for the 2 byte opcode has already provided us with a valid opcode in J. This happens because the odd pc means that only one byte of the first word contains interesting data (the opcode byte) and the next word contains both the alpha byte for the 2 byte opcode AND the next opcode byte!
%*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
it3ByteOpcode:
call[itGetPcVal];
q←t;* restore pc into q
call[itNoopFH];
call[itMemAckShFh];* MemAck Sh Fh
call[itMakeFDAckSh];* MakeF←D, memAck Sh
call[itMemAckFH];* MemAck, Fh
rscr← q;* we’ve kept q=starting Pc
skpif[r odd], rscr;* even case needs beta from second word
branch[itEvenPc2];
call[itNoopSh];* opcode’s been in J since itOddPc put it
branch[itSetAlphaBeta];* there
itEvenPc2:
call[itSetFGFDSh], t ← 3c;* address word 3 in ifu ram (data for j, MakeF←D, MakeF←D)
itSetAlphaBeta:
call[itSetFGFh], t ← 20c;* data for h
itTestCase21:
call[itNoopSH];
call[itSetFGFH], t ← 100c;*Third byte
noop;* for placement
expectedDispatch ← opAt15;* we expect ifujump to goto opAt15
call[itIfuJumpSH];* IfuJump[0]
call[itNoopFH];
call[itNextDataSH];* ←NextData
t#(20C);
skpif[ALU=0];
itCaseErr20:
Breakpoint;
noop;* here for placement
call[itNoopFH];
call[itGetPcVal];* retrieve original pc val from stkp-1
t← t+(2C);* add 2 since this instr follows a 2 byter
call[itGetPcXSH], q← t;* ←PcX for 3 byte opcode
t # (q);
skpif[ALU=0];
itCaseErr22:
Breakpoint;* pcx wasn’t correct
call[itNoopFH];
call[itNextDataSH];* ←NextData for 3rd byte
t # (100c);
skpif[ALU=0];
itCaseErr23:
Breakpoint;
t←1c;* patch this instruction if you want
Q←t;* to loop more than once
itCaseL2:
noop;* top of ←NextData loop that gets "IL"
call[itNoopFH];* when it does next datas
call[itNextDataSH];
t#(3c);* should get instruction length
skpif[ALU=0];
itCaseErr24:
Breakpoint;
noop;* for placement
t←(Q)-1;
loopUntil[ALU=0, itCaseL2],Q←t;* check out instruction length a few times
itTestCase1Xit:
stkP-2;* pop "alpha test value" andj "test Pc"
returnP[];
itGetPcVal: subroutine;
stkp-1;
return, t← stack&+1;