%
Page Numbers: Yes First Page: 1
Heading:
DORADO:memChaosS.mcSeptember 22, 1981 10:04 AM%

title[memChaosS];
%
Table of Contents by order of occurence
sChaosTestmain program for chaos test
setChaosCodepatch vartious locations in IM
chaosSimInitStart up the task simulator
startChaosStart up a pass of entire chaos test
checkErrorreturn ALU#0 if (loopOnError) and (errorOccured)
chaosErrorlocation that handles chaos errors. when at breakpoint, t = "error number"
iChaosScopeLoopremembers that an error has occured if loopOnError is true.
%
%
September 22, 1981 10:05 AM
Add noops to help placement.
September 14, 1979 3:40 PM
move sChaosChkAddrs into memSubrsCkhaos to help with micro STORAGE FULL problem. move isChaosMem and iSavedHoldValue, too.
June 25, 1979 11:33 PM
fix incomplete edit to the loop control of sChaosTest (sChaosTop).
June 25, 1979 10:48 PM
Cause startChaos to use getChaosTaskFreq, fix old, old bug in chaosError (called getSubrScr instead of getsSubrScr), add comments.
June 25, 1979 2:34 PM
Make chaostest into subroutine called from memRWs.mc
June 25, 1979 8:34 AM
Change placement locations to accommodate ifu entry points.
April 18, 1979 11:36 AM
Move iChaosCache, iChaosCode into memChaosSubrs.mc
April 18, 1979 10:06 AM
Remove sMainChaosRtn, perform ←FaultInfo[] before temporarily enabling the conditional task.
February 28, 1979 11:07 AM
Move actual test code into memChaosSubrs.mc
January 16, 1979 3:18 PM
Fix code init so that the random addresses selected occur in sChaosRow0, sChaosRow1. Rename constants for clarity. Reset mcr after cache init so that it no longer restricts the cache to one row only.
January 13, 1979 12:23 AM
Shorten maximum interval before Task simulator starts up. Max longWait delay set to 37B.
%

top level;

* January 16, 1979 3:22 PM
%
CHAOS
Mixed Timing and Memory-Op Test
Goal: Test memory by generating random memory operations that are delayed by random amounts of time. The memory operations will be executed by two different tasks to increase the storage traffic and occurence of odious boundary conditions.

Generating the Environment and Memory-Ops

The test scans two different rows of the cache (8 munches). Random numbers determine which row, which munch, which word will be referenced. This requires one bit of row address, four bits of word address (in the munch), two bits of munch address (the "addressing" of munches is encoded in the address bits outside the cache), and one bit of shadow address. The shadow address bit provides an extra collection of virtual addresses that map into the same two rows of the cache and consequently prevent the cache from containing all the munches of interest.

Cache Row0 and Row1 are the two cache rows tested. The address bits that encode (
columnNumber lshift skipCacheShift) select columns zero through three respectively. The shadow bit, encoded by 4 lshift skipCacheShift, provides enough address space to overflow the cache.

Chaos uses the following structure:
General Initialization
Background storage with known values (mem[va] ← va)
Run Chaos test
Use the random number generator to select the munches that will be present in the cache. Randomly set cflags.Dirty.
Randomly select one of the four possible test patterns for task 0 and for task 17. A test pattern is a pair of references separated by a delay (eg., fetch, delay, store, or store, delay, store).
Randomly select both the addresses referenced by task 0 and task 17, and the delay between those references.
Run the test.
Check that the interesting values are correct
Begin again

Random Selection of Munches in the Cache

The test must know which addresses to make present in each column of the first two rows of the cache, and it needs the value for the cache flag dirty bit.

Actually, the test needs only two random bits for cache initialization:
one bit selects cflags.dirty (or not)
The other bit selects the shadow bit.
For code initialization four fields are used in each random number:
wordX which selects which word in the munch
rowX which selects which of the two possible rows will be selected
colX which selects which column will be addressed
delay which selects the parameter to longWait which the code invokes after the first memory reference during the test.
%


* June 25, 1979 11:34 PM
%
codeRand
These constants and shifts describe the format applied to random numbers to decide which addresses the chaos test code will reference and to decide how long the delay will be after the first memory reference.
%

mc[
codeRand.store, 40];
mc[
codeRand.wordX, 17];
mc[
codeRand.rowX, 20];
set[
codeRand.colSize, 2];* mc[codeRand.colX, 300];
set[
codeRand.colShift, 6];
set[
codeRand.delaySize, 5];* mc[codeRand.delay, 17400]
set[
codeRand.delayShift, 10];

mc[
addr.shadowBit, lshift[4,skipCacheShift]];* va bit for shadow address

* addrRand is a two bit nibble selected from the current two lsb of a random number.
* the test uses addrRand to determine how to initialize each column of the two rows
* in the cache.
mc[
addrRand.dirty, 1];* mask bit for address template.
mc[
addrRand.shadow, 2];* mask bit for address template

mc[
instr.jcnLongJumpC, 0];
mc[
instr.ffMask,177400];

set[
instr.ffShift, 10];
mc[
instr.jcn4thru7C, 17];
set[
instr.notJcn4Thru7Shift, 4];* rt justify portion of an IM address not encoded by
set[
instr.notJcn4Thru7Size, 10];* the jcn[4:7] bits. also define size constant -- for ldf

set[
chaosTestBase, 7000]; mc[chaosTestBaseC, chaosTestBase];*++duplicated in memSubrsChaos.mc+++++
set[
chaosDelayBase, 7400]; mc[chaosDelayBaseC, chaosDelayBase];*++duplicated in memSubrsChaos.mc+++++

set[
chaosStage0Loc, 5400]; mc[chaosStage0locC, chaosStage0Loc];
set[
chaosStageSimLoc, 6000]; mc[chaosStageSimLocC, chaosStageSimLoc];
set[
chaosSimInitLoc, 6440];
mc[chaosSimInitLoc0C, and[chaosSimInitLoc, 7400]];
mc[chaosSimInitLoc1C, and[chaosSimInitLoc, 377]];

sChaosTest:
pushReturn[];
checkMtest[memFlags.sChaos, sChaosDone];
noop;* for placement
t ← flags.taskSim;* don’t bother to execute unless
call[checkFlags];* task simulating is enabled
skpif[alu#0];
branch[sChaosDone];* no tasking, no chaos
noop;

call[isChaosMem];* init memory so that mem[va] = va.
call[iSchaosX];
sChaosTop:
call[nextChaosX];* see if its time for another test
skpif[alu#0];
branch[sChaosTopXit];* check all sva for consistency, then exit
noop;

call[iSavedHoldValue];* perform task simulator init
call[saveRandState];
chaosScopeLoop:
call[iChaosCache];* select cache addresses and flags
noop;* for placement.
call[isChaosCode];* init RM for chaos test, WRITE delay constant
sChaosStart:
call[startChaos];* run the test with both tasks running
call[checkError];* see if an scope loop error occured in the past
skpif[alu=0];
branch[ichaosScopeLoop];* perform scope loop
branch[sChaosTop];

sChaosTopXit:
call[sChaosChkAddrs];
sChaosDone:
noop;* for placement
call[disableConditionalTask];
returnP[];


* January 8, 1979 11:00 PM
%
Set Chaos Code
Patch the delay constant and staging locations in the chaos test as required by the current random number values. When the test executes, a branch must be made to the proper location in IM to perform the pair of memory ops and the intervening delay. setChaosCode initializes the jump to that test and it initializes the B-mux constant that provides the delay between the two operations.

Enter with T = 0 or 4 (task 0 or task sim, an offset into some tables), rscr2 = the last random number used, and sChaosRandV the current random number in use. The concatenation of the two store bits from these two pseudo random numbers provides an index into a table of IM locations. These locations point to the starting point of the proper test in the chaosTestBase table, and point to the address of the B-mux constant in the chaosDelayBase table. The contents of these tables are actual instructions, so addressing them is a matter of adding the constructed constant to a base value. The offset in T address the simTask locations. For example:
ChaosTestBase + 000beginning of fetch-fetch test
+ 001beginning of fetch-store test
+ 010beginning of store-fetch test
+ 011begining of store-store test
+ 111beginning of fetch-fetch (sim task)
+ 101beginning of fetch-store (sim task)
+ 110beginning of store-fetch (sim task)
+ 111beginning of store-store (sim task)

setChaosCode: PROCEDURE[taskOffset, oldRandomV, currentRandomV] =
BEGIN
index ← IF oldRandomV.store THEN 2 ELSE 0;
index ← index +IF currentRandomV.store THEN 1 ELSE 0;
index ← index + offset;

gotoAddr ← index + ChaosTestBase;
gotoInstrRightHalf ← 120B;
-- jc = 1, jn[0:1] = 01
gotoInstrRightHalf ← gotoInstrRightHalf + (gotoLoc AND 17B);
-- jn[2:5]
gotoLoc ← [ (gotoLoc AND (NOT 17B) -- isolate remaining bits--) LSHIFT 4];
-- position for FF constant
gotoInstrRightHalf ← gotoInstrRightHalf + gotoLoc;

IF index = 0 THEN IMRH[chaosStage0Loc] ← gotoInstrRightHalf
ELSE IMRH[chaosStageSimLoc] ← gotoInstrRightHalf;

ffConstant ← currentRandomV AND ffCountstantMask;
-- isolate delay field
ffConstant ← ffConstant LSHIFT ffConstantShift;
-- position for micro instruction
codeLoc ← ChaosDelayTable + offset;
instr ← IMRH[codeLoc];
instr ← instr ANd (not ffConstantMask);
-- isolate rest of instruction
instr ← instr OR ffConstant;
-- add our new ff constant
IMRH[codeLoc] ← ffConstant;
END;
%

* January 16, 1979 3:48 PM

setChaosCode:
subroutine;* T = task offset (0=> task 0, 4 =>simTask)
*
rscr2 = old random number, sChaosRandV = current random number
saveReturnAndT[sRlink, sSubrScr];

(rscr2) AND (codeRand.store);* see if store bit is set
skpif[alu=0], t ← t-t;
t ← 2c;
(sChaosRandV) AND (codeRand.store);* see if store bit is set
skpif[alu=0], rscr ← t;* copy current value into rscr
rscr ← t + 1;* rscr = index

call[getSsubrScr];* restore task offset into T
t ← t + (rscr);* t ← offset + index
sSubrScr ← t;* save complete index in sSubrScr

setChaosCodeJump:
%
The format for a long jump is that jcn[4:7] contains the low 4 bits of the target address, and FF[0:7] contains the remaining 8 bits of the target address. In the code below, instr.jcnLongJumpC is a constant that properly sets the other bits of jcn.
%
rscr ← (instr.jcnLongJumpC);* encode long jump
t ← rscr2 ← t + (chaosTestBaseC);* generate address to jump to
t ← t AND (instr.jcn4thru7C);* add low order bits of address
rscr ← (rscr) + t;

%
Now finish constructing the long jump to the target address. First right justify the remaining bits of the address (ie., those bits not encoded in jcn[4:7]), then left shift those bits into the FF field of the microinstruction.
%
rscr2 ← ldf[rscr2, instr.notJcn4Thru7size, instr.notJcn4Thru7Shift];
rscr2 ← lsh[rscr2, instr.ffShift];
t ← rscr2;
rscr ← (rscr) + t;* this is right half of the micro instruction

call[getSsubrScr];* choose between task0 stage location and
t ← t AND (4C);* simulator stage location
skpif[alu=0], t ← chaosStage0LocC;
t ← chaosStageSimLocC;

call[putIMRH];* Write the GOTO[properTest]

setChaosCodeConstant:
call[getSsubrScr];* get address of instruction whose B-mux
t ← t + (chaosDelayBaseC);* constant (FF) must be initialized
call[getIMRH];

rscr2 ← not(instr.ffMask);* remove the current FF bits
t ← t and (rscr2);
rscr ← t;

t ← ldf[sChaosRandV, codeRand.delaySize, codeRand.delayShift];* rt. justify delay
t ← lsh[t, instr.ffShift];* position delay for ff constant
rscr ← t OR (rscr);* rscr = new instruction

call[getSsubrScr];
t ← t + (ChaosDelayBaseC);
call[putIMRH];* write the delay constant
returnUsing[sRlink];

* April 24, 1978 3:01 PM
%
Chaos Simulator Initialization Code
Set Q to zero upon entry (the sim code sets q to 1 when it is done). ChaosSimStageit has been initialized with a long branch to the proper test sequence by setChaosCode.
Task 0 maintains responsibility for checking the consistency of the results.

This code does not "return" to caller because
chaosSimStageIt has been patched with
a branch to test code that explicitly (via goto) returns to the chaos checking code.
%
top level;
chaosSimInit:
t ← q,at[chaosSimInitLoc];* hold value passed in Q

RBASE ← rbase[defaultRegion];
q ← r0;

rscr ← t-t;* zero the current membase
call[setBR], rscr2 ← t-t;

RBASE ← rbase[rm10];* initialize rbase and branch to the test
top level;
noop;* allow pc to get off page

chaosSimStageit:
noop,at[chaosStageSimLoc];* patched by setChaosCode !!
error;* should never get here
% should branch to code that looks like,
hold ← t, block;
<test code sequence>
branch[chaosSimXit];
%
set[xtask,1];
chaosSimXit:
t ← 0c;
t ← t + 1, hold&tasksim ← t;
noop;* 1st instr after hold&tasksim← doesnt count
q ← t, block;
branch[.], breakpoint;* should never get here
set[xtask,0];

* June 25, 1979 10:49 PM
%
Start Chaos Code

Start up the chaos simulator and proceed with the current memory test. This code checks that all the relevant memory locations are correct.
%
knowRbase[defaultRegion];
startChaos: subroutine;
pushReturn[];

call[setMCR], t ← r0;

rscr ← t-t;* zero the current membase
call[setBR], rscr2 ← t-t;

call[getChaosTaskFreq];* construct hold value
q←t;

taskingOn;
t ← (chaosSimInitLoc0C);
t ← t + (chaosSimInitLoc1C);
subroutine;
link ← t;
top level;
ldTPC ← simTaskLevelC;
notify[simTaskLevel];
noop;
RBASE ← rbase[rm00];
chaos0Stageit:
goto[.+1],at[chaosStage0Loc];
error;

chaosAfterChk0:* arrive here via explicit goto from task0 test.
* Perform an exhaustive test of RM and storage values
t ← q;* see if sim task is done
branch[., alu=0], t ← q;

t ← rm01;
t ← t # (rm00);
skpif[alu=0];
sChaosErr01:* rm00 # rm01
branch[chaosError], t ← 1c;

fetch ← rm00;
t ← md;
rm01 ← t;
t ← t # (rm00);
skpif[alu=0];
sChaosErr02:* mem[rm00] # rm00
branch[chaosError], t ← 2c;* rm01 = MD

t ← rm03;
t ← t # (rm02);
skpif[alu=0];
sChaosErr03:* rm02 # rm03
branch[chaosError], t ← 3c;

FETCH ← rm02;
rm03 ← MD;
t ← rm03;
t ← t # (rm02);
skpif[alu=0];
sChaosErr04:* mem[rm02] # rm02
branch[chaosError], t ← 4c;* rm03 = MD

* TEST Chaos SimTask registers and locations
t ← rm11;
t ← t # (rm10);
skpif[alu=0];
sChaosErr11:* rm10 # rm11
branch[chaosError], t ← 5c;

fetch ← rm10;
t ← md;
rm01 ← t;
t ← t # (rm10);
skpif[alu=0];
sChaosErr12:* mem[rm10] # rm10
branch[chaosError], t ← 6c;* rm11 = MD, t = bad bits

t ← rm13;
t ← t # (rm12);
skpif[alu=0];
sChaosErr13:* rm02 # rm13
branch[chaosError], t ← 7c;

FETCH ← rm12;
rm13 ← MD;
t ← rm13;
t ← t # (rm12);
skpif[alu=0];
sChaosErr14:* mem[rm12] # rm12
branch[chaosError], t ← 10c;* rm13 = MD
returnP[];

* April 27, 1978 3:19 PM
%
Chaos Error: breakpoint or scope loop
%
knowRbase[defaultRegion];
checkError: subroutine;* return alu#0 if (loopOnError) AND (error occured)
saveReturn[Srlink];
t ← memState.loopOnError;* see if we care
call[checkMemState];
skpif[alu#0];* presume no errors
branch[checkErrorRtn], t ← r0;* don’t loop so return w/ alu=0
t ← memState.loopErrorOccured;
call[checkMemState];
skpif[alu=0], t ← r0;
t ← (r0) + 1;
checkErrorRtn:
returnAndBranch[Srlink, t];

top level;
chaosError:
RBASE ← rbase[defaultRegion];
sSubrScr ← t;* remember error value

t ← (memState.loopOnError);
call[checkMemState];
skpif[alu=0];
branch[chaosErr1];* do the scope loop

call[getsSubrScr];* get the error number into t. See code after startChaos
error;* to decode significance of error number.

chaosErr1:
call[loopErrorOccured];* now fall thru to iChaosScopeLoop

iChaosScopeLoop:
call[loopErrorOccured];* remember that err occured for future ref.
call[restoreRandState];
branch[chaosScopeLoop];

set[xtask,0];
knowRbase[defaultRegion];