DIRECTORY CacheModel, DisplayModel, DynaStats, DynaSeer, IO, MemoryModel, ViewerIO; DynaSeerImpl: CEDAR PROGRAM IMPORTS CacheModel, DisplayModel, DynaStats, IO, MemoryModel EXPORTS DynaSeer = BEGIN OPEN DynaSeer; oneDataCycles: Cycles _ LIST [MakeCycle[DataCycle]]; fourDataCycles: Cycles _ LIST [MakeCycle[DataCycle], MakeCycle[DataCycle], MakeCycle[DataCycle], MakeCycle[DataCycle]]; CreateDevice: PUBLIC PROC [] RETURNS [device: Device] = { device _ NEW [DeviceRec]; }; MakeCycle: PUBLIC PROC [cmd: Cmd, deviceId, master: DeviceId _ 0, data: INT _ 0] RETURNS [cycle: Cycle] = { cycle _ NEW [CycleRec _ [cmd: cmd, deviceId: deviceId, master: master, data: data, grantLatency: 0]]; }; MakeNoOp: PUBLIC PROC [] RETURNS [cycle: Cycle] = { cycle _ MakeCycle[NoOp]; }; MakeDataCycles: PUBLIC PROC [length: Length] RETURNS [Cycles] = { SELECT length FROM One => RETURN [NIL]; Two => RETURN [oneDataCycles]; Five => RETURN [fourDataCycles] ENDCASE => ERROR; }; MakeBubble: PUBLIC PROC [] RETURNS [cycle: Cycle] = { cycle _ MakeCycle[Bubble]; }; MakeRequest: PUBLIC PROC [length: Length, header: Cycle, priority: Priority _ Low] RETURNS [request: Request] = { cycles: Cycles _ CONS [header, MakeDataCycles[length]]; request _ NEW [RequestRec _ [length, cycles, priority]]; }; IsDataCycle: PUBLIC PROC [cycle: Cycle] RETURNS [BOOL _ FALSE] ~ {RETURN[cycle.cmd=DataCycle]}; IsUsefulCycle: PUBLIC PROC [cycle: Cycle] RETURNS [BOOL _ FALSE] ~ { RETURN[cycle.cmd#NoOp AND cycle.cmd#Bubble]}; IsHeaderCycle: PUBLIC PROC [cycle: Cycle] RETURNS [BOOL _ FALSE] ~ { RETURN[IsUsefulCycle[cycle] AND NOT IsDataCycle[cycle]]}; IsReplyCycle: PUBLIC PROC [cycle: Cycle] RETURNS [BOOL _ FALSE] ~ { RETURN[cycle.cmd=RBRply OR cycle.cmd=WBRply OR cycle.cmd=WSRply]}; IsRequestCycle: PUBLIC PROC [cycle: Cycle] RETURNS [BOOL _ FALSE] ~ { RETURN[cycle.cmd=RBRqst OR cycle.cmd=WBRqst OR cycle.cmd=WSRqst]}; IsDisplay: PUBLIC PROC [handle: Handle, deviceId: DeviceId] RETURNS [BOOL _ FALSE] ~ { RETURN[deviceId=handle.display]}; IsCache: PUBLIC PROC [handle: Handle, deviceId: DeviceId] RETURNS [BOOL _ FALSE] ~ { RETURN[deviceId>=handle.firstcache AND deviceId<=handle.lastcache]}; IsMemory: PUBLIC PROC [handle: Handle, deviceId: DeviceId] RETURNS [BOOL _ FALSE] ~ { RETURN[deviceId>=handle.firstmem AND deviceId<=handle.lastmem]}; CreateSimulation: PUBLIC PROC [in, out: IO.STREAM, numCycles, numMemories, numCaches, arbLatency: INT] RETURNS [handle: Handle] = { deviceId: DeviceId _ 0; handle _ NEW [HandleRec]; handle.numCycles _ numCycles; handle.firstmem _ handle.memPtr _ deviceId; FOR i: INT IN [1..numMemories] DO handle.devices _ CONS[MemoryModel.CreateMemory[deviceId], handle.devices]; deviceId _ deviceId+1; ENDLOOP; handle.lastmem _ deviceId-1; handle.firstcache _ handle.cacheLPPtr _ handle.cacheHPPtr _ deviceId; FOR i: INT IN [1..numCaches] DO handle.devices _ CONS[CacheModel.CreateCache[deviceId], handle.devices]; deviceId _ deviceId+1; ENDLOOP; handle.lastcache _ deviceId-1; handle.display _ deviceId; handle.devices _ CONS[DisplayModel.CreateDisplay[deviceId], handle.devices]; handle.history _ NIL; handle.in _ in; handle.out _ out; handle.arbLatency _ arbLatency }; RunSimulation: PUBLIC PROC [handle: Handle] = { currentRequest: Request; currentCycle: Cycle; IF handle.lastcache >= handle.firstcache THEN CacheModel.Init[handle]; IF handle.lastmem >= handle.firstmem THEN MemoryModel.Init[handle]; DisplayModel.Init[handle]; DynaStats.Init[handle]; FOR dl: LIST OF Device _ handle.devices, dl.rest WHILE dl#NIL DO dl.first.init[handle, dl.first]; ENDLOOP; handle.cycleNumber _ 1; handle.lastNonDataCycle _ MakeNoOp[]; WHILE handle.cycleNumber <= handle.numCycles DO currentRequest _ Arbitrate[handle]; IF IsBubble[handle, currentRequest.cycles.first] THEN THROUGH [1..handle.bubblesPerSwitch] DO currentRequest.cycles _ CONS[MakeBubble[], currentRequest.cycles]; ENDLOOP; FOR cl: LIST OF Cycle _ currentRequest.cycles, cl.rest WHILE cl#NIL DO currentCycle _ cl.first; FOR dl: LIST OF Device _ handle.devices, dl.rest WHILE dl#NIL DO dl.first.cycle[handle, dl.first, currentCycle]; ENDLOOP; DynaStats.AddToHistory[handle, currentCycle]; handle.cycleNumber _ handle.cycleNumber+1; ENDLOOP; ENDLOOP; }; GetIntParm: PUBLIC PROC [in, out: IO.STREAM, prompt: ROPE, default: INT] RETURNS [val: INT] = { IO.PutF[out, "%g ( %g ): ", IO.rope[prompt], IO.int[default]]; IF IO.PeekChar[in] = '\n THEN val _ default ELSE val _ IO.GetInt[in]; [] _ IO.GetChar[in]; }; GetRealParm: PUBLIC PROC [in, out: IO.STREAM, prompt: ROPE, default: REAL] RETURNS [val: REAL] = { IO.PutF[out, "%g ( %g ): ", IO.rope[prompt], IO.real[default]]; IF IO.PeekChar[in] = '\n THEN val _ default ELSE val _ IO.GetReal[in]; [] _ IO.GetChar[in]; }; OnSameBoard: PROC [handle: Handle, one, two: DeviceId] RETURNS [BOOL] ~ { RETURN [ (one IN [handle.firstmem .. handle.lastmem] AND two IN [handle.firstmem .. handle.lastmem]) OR (one IN [handle.firstcache .. handle.lastcache] AND two IN [handle.firstcache .. handle.lastcache]) OR (one > handle.lastcache AND two > handle.lastcache)]; }; IsBubble: PROC [handle: Handle, cycle: Cycle] RETURNS [BOOL _ FALSE] ~ { RETURN [IsUsefulCycle[handle.lastNonDataCycle] AND IsHeaderCycle[cycle] AND NOT OnSameBoard[handle, handle.lastNonDataCycle.master, cycle.master]]; }; Arbitrate: PROC [handle: Handle] RETURNS [request: Request] = { ptr: DeviceId; Incr: PROC [val, first, last: DeviceId] RETURNS[newVal: DeviceId] = { newVal _ IF val+1>last THEN first ELSE val+1 }; ptr _ handle.cacheHPPtr; WHILE TRUE DO request _ handle.cacheHPRequests[ptr]; IF request#NIL AND request.cycles.first.grantLatency >= handle.arbLatency THEN { handle.cacheHPPtr _ Incr[ptr, handle.firstcache, handle.lastcache]; handle.cacheHPRequests[ptr] _ NIL; RETURN; }; ptr _ Incr[ptr, handle.firstcache, handle.lastcache]; IF ptr=handle.cacheHPPtr THEN EXIT; ENDLOOP; ptr _ handle.memPtr; WHILE TRUE DO request _ handle.memRequests[ptr]; IF request#NIL AND request.cycles.first.grantLatency >= handle.arbLatency THEN { handle.memPtr _ Incr[ptr, handle.firstmem, handle.lastmem]; handle.memRequests[ptr] _ NIL; RETURN; }; ptr _ Incr[ptr, handle.firstmem, handle.lastmem]; IF ptr=handle.memPtr THEN EXIT; ENDLOOP; request _ handle.displayHPRequest; IF request#NIL AND request.cycles.first.grantLatency >= handle.arbLatency THEN {handle.displayHPRequest _ NIL; RETURN}; ptr _ handle.cacheLPPtr; WHILE TRUE DO request _ handle.cacheLPRequests[ptr]; IF request#NIL AND request.cycles.first.grantLatency >= handle.arbLatency THEN { handle.cacheLPPtr _ Incr[ptr, handle.firstcache, handle.lastcache]; handle.cacheLPRequests[ptr] _ NIL; RETURN; }; ptr _ Incr[ptr, handle.firstcache, handle.lastcache]; IF ptr=handle.cacheLPPtr THEN EXIT; ENDLOOP; request _ handle.displayLPRequest; IF request#NIL AND request.cycles.first.grantLatency >= handle.arbLatency THEN {handle.displayLPRequest _ NIL; RETURN}; request _ MakeRequest[One, MakeNoOp[]]; }; END. `DynaSeerImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Written By: Pradeep Sindhu September 18, 1986 4:52:07 pm PDT Pradeep Sindhu September 26, 1986 11:28:42 pm PDT Last Edited by: Louis Monier September 24, 1986 2:02:42 pm PDT Russ Atkinson (RRA) September 25, 1986 6:22:55 pm PDT Device and Bus Procs Simulation Procs Memories must have consecutive device numbers starting with 0 Caches must have consecutive device numbers Display automatically gets the highest device id Initialize modules Initialize all devices Run for the appropriate number of cycles Internal Utilities If any high-priority cache requests then select one If any memory requests then select one If any displayHP request then select it If any low-priority cache requests then select one If any low-priority display request then select it No request found! Κ»– "cedar" style˜codešœ™Kšœ Οmœ1™K™5K™—KšΟk œ1žœ˜TJ˜•StartOfExpansion[]šΡbln œžœž˜Kšžœ&žœ ˜Kš žœžœžœžœžœ ˜EKšœžœ ˜Kšœ˜—K˜š  œžœžœ žœžœ žœ žœžœžœ˜bKšžœžœžœ˜?Kš žœžœžœžœžœ ˜FKšœžœ ˜Kšœ˜—K˜K˜—™K˜š  œžœ&žœžœ˜Išžœ˜ Kš œžœ%žœžœ&žœ˜_Kš œžœ)žœžœ*žœ˜gKšœžœ˜5—K˜—K˜š  œžœ žœžœžœ˜HKšžœ)žœžœžœD˜“K˜—K˜š  œžœžœ˜?K˜š œžœžœ˜EKšœ žœ žœžœ˜,K˜—K˜K™3K˜šžœžœž˜ Kšœ&˜&šžœ žœžœ8žœ˜PK˜CKšœžœ˜"Kšžœ˜K˜—K˜5Kšžœžœžœ˜#Kšžœ˜—K˜K™&K˜šžœžœž˜ Kšœ"˜"šžœ žœ7žœ˜PK˜;Kšœžœ˜Kšžœ˜K˜—K˜1Kšžœžœžœ˜Kšžœ˜—K˜K™'Kšœ"˜"Kš žœ žœžœ7žœžœžœ˜wK™K™2K˜šžœžœž˜ Kšœ&˜&šžœ žœžœ7žœ˜PK˜CKšœžœ˜"Kšžœ˜K˜—K˜5Kšžœžœžœ˜#Kšžœ˜—K˜K™2Kšœ"˜"Kš žœ žœžœ7žœžœžœ˜wK˜K™Kšœ'˜'K˜—K˜—Kšžœ˜K˜—…—4'O