-- BusSlave.sak -- last edited by: Suzuki August 5, 1981 9:58 AM BusSlave: DEVICE = { IN -- Memory bus BusException: BOOLEAN, MemoryBus: MemoryBusType, -- Master process Next: BOOLEAN -- TriMOS control BusDone, Ready: BOOLEAN, OUT -- Memory bus Advnace, Shared: BOOLEAN, -- Master process Done, Exception, Start, MapEnd, ValidData: BOOLEAN, -- TriMOS control Advnace: BOOLEAN GUARDIAN STATE DATAFLOW CONTROL REPEAT { Exception _ FALSE; SELECT MemoryBus.Op FROM Fetch => BusFetchSlave[]; Store => BusStoreSlave[]; SFetch => BusSFetchSlave[]; SetMapDirty => BusSetMapDirtySlave[]; InvalidateVp => BusInvalidateVpSlave[]; WriteMap => BusWriteMapSlave[]; ReadMap => BusReadMapSlave[]; WriteMapFlags => BusWriteMapFlagsSlave[]; ENDCASE}; }; --1) Bus Slave procedures success: BOOLEAN; loc: [0..CacheSize); BusFetchSlave: PROC = { Start _ TRUE; SELECT { WHEN Next UP -> -- Data is not on the cache. This cache is in control SlaveFetch[] || WHEN Ready UP -> -- Some other cache is in control {[success, loc] _ RpBMatch[MemoryBus.Arg]; IF success THEN { Cache[loc].flags.shared _ TRUE; Shared _ TRUE}; OneStep[]; IF success THEN BackDoorAccess[] ELSE IdleSteps[]}; } }; SlaveFetch: PROC = { Advance _ TRUE; WHEN BusDone UP: IF BusException THEN {Exception _ TRUE; RETURN}; THROUGH [0..1] DO WHEN Ready UP: ValidData _ TRUE; WHEN Next UP: Advnace _ TRUE; ValidData _ FALSE; WHEN BusDone UP: IF BusException THEN {Exception _ TRUE; RETURN}; ENDLOOP}; BackDoorAccess: PROC = { i: CARDINAL; FOR i IN [0..1] DO MemoryBus.Data _ Cache[loc].data.long[i]; OneStep[]; ENDLOOP; }; IdleStep: PROC = { THROUGH [0..1] DO OneStep[]; ENDLOOP}; BusStoreSlave: PROC = { Start _ TRUE; SELECT { WHEN Next UP -> -- This cache is in control {StoreInstruction[]; SlaveStore[]} || WHEN Ready UP -> -- some other cache is in control {StoreInstruction[]; OneStep[]; IF success THEN BackDoorStore[] ELSE SlaveIdleSteps[]} } }; StoreInstruction: PROC = { SetRpDirty[]; [success, loc] _ RpBMatch[MemoryBus.Arg]; IF success THEN Cache[loc].flags.ceDirty _ FALSE}; SlaveIdleSteps: PROC = { StepPhases[2]; WHEN BusDone UP: NULL}; BackDoorStore: PROC = { i: CARDINAL; FOR i IN [0..1] DO Cache[loc].data.long[i] _ MemoryBus.Data; OneStep[]; ENDLOOP}; SlaveStore: PROC = { Advance _ TRUE; WHEN BusDone UP: IF BusException THEN {Exception _ TRUE; RETURN}; Done _ TRUE; THROUGH [0..1] DO WHEN Next UP: Advnace _ TRUE; WHEN BusDone UP: IF BusException THEN {Exception _ TRUE; RETURN}; Done _ TRUE; ENDLOOP}; BusSFetchSlave: PROC = { START _ TRUE; SELECT { WHEN Next UP -> -- This cache is in control {SetRpDirty[]; SlaveFetch[]; IF Shared THEN SlaveStore[]} || WHEN Ready UP -> { StoreInstruction[]; -- success is set by Match OneStep[]; IF success THEN {BackDoorAccess[]; BackDoorStore[]} ELSE IdleSteps[]} } }; BusInvalidateVpSlave: PROC = { FOR loc IN [0..CacheSize) DO AcquireArbiter[loc]; IF Cache[loc].rp = MemoryBus.Arg THEN Cache[loc].flags.vaValid _ FALSE ReleaseArbiter[loc]; ENDLOOP; DataTaken _ TRUE}; BusReadMapSlave, BusWriteMapSlave, BusWriteMapFlagsSlave: PROC = { MapPrologue[]; StepPhases[1]}; MapPrologue, BusSetMapDirtySlave: PROC = { DataTaken _ TRUE; DO WHEN DataReady UP: IF MemoryBus.flags.mapend THEN { MapEnd _ TRUE; DataTaken _ TRUE; EXIT}; DataTaken _ TRUE; StepPhases[2]; ENDLOOP}; StepPhases: PROC[num:CARDINAL] = { THROUGH [1..num] DO WHEN Ready UP: Advance _ TRUE; ENDLOOP}; OneStep: PROC = { Advance _ TRUE; WHEN BusDone UP: NULL}; (635)\f9G503g3G26g3G26g3G28g3G38g3G40g3G32g3G30g3G845g15G63g3G77g1G1407g1G22g1G9g1G20g1G66g1G15g1G17g1G42g1G18g1G3g1G20g1G35g1G18g1G21g1G10g1G19g1G16g1G11g1G