-- 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]; } }; }.