-- File: [Indigo]<Sakura>Dragon>DragonProcessorImpl8.sak
-- Dragon processor with random fetch
-- 23-Mar-82 11:33:38z
DIRECTORY
DragonCache,
DragonProcessor,
SakuraRT,
SimIO;
DragonProcessorImpl8: MONITOR
IMPORTS DragonCache, SakuraRT, SimIO
EXPORTS DragonProcessor = {
ProcID: STRING = "Proc1: ";
Processor: PUBLIC DEVICE = {
IN ClockA, ClockB, Fault, Reject: BOOLEAN, InData: DragonCache.PbusType
OUT Op: DragonCache.PbusOp, RQ: BOOLEAN, OutData: DragonCache.PbusType
GUARDIAN {}
CONTROL {
Store: PROC [loc: CARDINAL, data: LONG CARDINAL]= {
vp: LONG CARDINAL;
bl: [0..37B];
word: [0..3];
printval: LONG CARDINAL;
[vp, bl, word] ← SplitAddress[loc];
printval ← word+bl*4+vp*128;
WHEN ClockB UP: {
RQ ← TRUE;
Op ← Store;
OutData ← [Instruction[vp, bl, word]]};
DO
WHEN ClockA UP: IF ~Reject THEN EXIT;
ENDLOOP;
SimIO.WF2[" %sStore started %ld*n", ProcID, @printval];
WHEN ClockB UP: OutData ← [Data[data]]; -- Match
WHEN ClockB UP: RQ ← FALSE;
SimIO.WF2[" %sStore finished %ld*n", ProcID, @printval]};
StoreAndRead: PROC [loc, prevloc: CARDINAL, data,
prevdata: LONG CARDINAL] = {
vp, prevvp: LONG CARDINAL;
bl, prevbl: [0..37B];
word, prevword: [0..3];
printval: LONG CARDINAL;
[vp, bl, word] ← SplitAddress[loc];
printval ← word+bl*4+vp*128;
WHEN ClockB UP: {
RQ ← TRUE;
Op ← Store;
OutData ← [Instruction[vp, bl, word]]};
DO
WHEN ClockA UP: IF ~Reject THEN EXIT;
ENDLOOP;
[prevvp, prevbl, prevword] ← SplitAddress[prevloc];
SakuraRT.Delay[40];
DragonCache.CheckVal[prevvp, prevbl, prevword, prevdata];
SimIO.WF2[" %sStore started %ld*n", ProcID, @printval];
WHEN ClockB UP: OutData ← [Data[data]]; -- Match
WHEN ClockB UP: RQ ← FALSE;
SimIO.WF2[" %sStore finished %ld*n", ProcID, @printval]};
Fetch: PROC [loc: CARDINAL]= {
vp: LONG CARDINAL;
bl: [0..37B];
word: [0..3];
printval: LONG CARDINAL;
[vp, bl, word] ← SplitAddress[loc];
printval ← word+bl*4+vp*128;
WHEN ClockB UP: {
RQ ← TRUE;
Op ← Fetch;
OutData ← [Instruction[vp, bl, word]]};
DO
WHEN ClockA UP: IF ~Reject THEN EXIT;
ENDLOOP;
SimIO.WF2[" %sFetch started %ld*n", ProcID, @printval];
WHEN ClockB UP: RQ ← FALSE;
SimIO.WF2[" %sFetch finished %ld*n", ProcID, @printval]};
FetchAndRead: PROC [loc: CARDINAL, data: CARDINAL] = {
vp: LONG CARDINAL;
bl: [0..37B];
word: [0..3];
printval: LONG CARDINAL;
[vp, bl, word] ← SplitAddress[loc];
printval ← word+bl*4+vp*128;
RQ ← TRUE;
Op ← Fetch;
OutData ← [Instruction[vp, bl, word]];
DO
WHEN ClockA UP: IF ~Reject THEN EXIT;
ENDLOOP;
SimIO.WF2[" %sFetch started %ld*n", ProcID, @printval];
WHEN ClockB UP: {
SakuraRT.Delay[30];
WITH b: InData SELECT FROM
Data => IF data # b.data THEN ERROR;
ENDCASE => ERROR;
RQ ← FALSE};
SimIO.WF2[" %sFetch finished %ld*n", ProcID, @printval]};
Read: PROC [prevloc: CARDINAL, prevdata: LONG CARDINAL] = {
prevvp: LONG CARDINAL;
prevbl: [0..37B];
prevword: [0..3];
DO
WHEN ClockA UP: IF ~Reject THEN EXIT;
ENDLOOP;
[prevvp, prevbl, prevword] ← SplitAddress[prevloc];
SakuraRT.Delay[40];
DragonCache.CheckVal[prevvp, prevbl, prevword, prevdata]};
SplitAddress: PROC [loc: CARDINAL] RETURNS [vp: LONG CARDINAL,
bl: [0..37B], word: [0..3]] = {
word ← loc MOD 4;
loc ← loc / 4;
bl ← loc MOD 40B;
vp ← loc / 40B};
i: CARDINAL;
TestNum: CARDINAL = 100;
RQ ← FALSE;
WHEN ClockB UP: NULL;
WHEN ClockB UP: NULL;
Fetch[0];
FOR i IN [1..TestNum) DO
FetchAndRead[i, i*2 - 2];
ENDLOOP;
Read[TestNum-1, (TestNum-1)*2];
Store[0, 0];
FOR i IN [1..TestNum) DO
StoreAndRead[i, i-1, i*2, i*2 - 2];
ENDLOOP;
SimIO.WF1["%s+++++++++++++++++++++++++++++++++++++++++++++++++++*n1000", ProcID];
}
};
}.