DIRECTORY Basics, BitTwiddling, Cucumber, NumTypes, IO, PrincOps, PrincOpsUtils, Process, Rope, RoseClocks, RoseCreate, RoseEvents, RoseRun, RoseTypes, SwitchTypes, ViewRec; RoseClocksImpl: CEDAR MONITOR IMPORTS Cucumber, IO, NumTypes, PrincOpsUtils, Process, RoseCreate, RoseEvents, RoseRun, RoseTypes, VR: ViewRec EXPORTS RoseClocks = BEGIN OPEN RoseClocks; ROPE: TYPE = Rope.ROPE; Cell: TYPE = RoseTypes.Cell; ClockType: TYPE = REF RoseClockArgs; ClockGen: PUBLIC PROC [args: RoseClockArgs] RETURNS [ct: RoseTypes.CellType] = {name: ROPE _ IO.PutFR[ "ClockGen[%g,%g]", IO.rope[SELECT args.sense FROM ActiveHigh => "ActiveHigh", ActiveLow => "ActiveLow", ENDCASE => ERROR], IO.rope[SELECT args.style FROM TwoStep => "TwoStep", FourStep => "FourStep", ENDCASE => ERROR]]; IF (ct _ RoseCreate.GetCellType[name]) # NIL THEN RETURN; ct _ RoseCreate.RegisterCellType[ name: name, ioCreator: CreateClockGenIO, driveCreator: CreateClockGenDrive, initializer: InitializeClockGen, evals: [EvalSimple: ClockGenSimple], ports: clockGenPorts, typeData: NEW [RoseClockArgs _ args] ]; }; ClockGenSimpleIORef: TYPE = REF ClockGenSimpleIORec; ClockGenSimpleIORec: TYPE = RECORD [ phil: [0 .. BitTwiddling.TwoToThe[Basics.bitsPerWord-2]) _ 0, phi1, phi2: BOOL]; ClockGenSwitchIORef: TYPE = REF ClockGenSwitchIORec; ClockGenSwitchIORec: TYPE = RECORD [ phi1, phi2: SwitchTypes.SwitchVal]; ClockGenDriveRef: TYPE = REF ClockGenDriveRec; ClockGenDriveRec: TYPE = RECORD [ tag: RoseTypes.DriveTagType, drives: PACKED ARRAY ClockGenPort OF RoseTypes.DriveLevel]; ClockGenPort: TYPE = {phi1, phi2, fill2, fill3}; ClockState: TYPE = REF ClockStateRep; ClockStateRep: TYPE = RECORD [ type: ClockType, display: Display, rv: VR.RecordViewer, cell, root: Cell, notice: CONDITION, stopResponse: StopResponse _ Abort, stopped: PrincOps.FrameHandle _ NIL]; StopResponse: TYPE = {Resume, Abort}; Display: TYPE = REF DisplayRep; DisplayRep: TYPE = RECORD [ sofar: INTEGER, state: State, status: Status _ Normal, Cycle: PROC [cell: Cell, cycles: CARDINAL], Step: PROC [cell: Cell], Interrupt: PROC, Disable: PROC [cell: Cell] RETURNS [ok: BOOL], Proceed, Abort: PROC [cell: Cell] ]; State: TYPE = [0..6); Status: TYPE = {Normal, Interrupted}; clockHandler: Cucumber.Handler _ NEW [Cucumber.HandlerRep _ [ PrepareWhole: PrepareClock, PartTransfer: TransferClock]]; displayHandler: Cucumber.Handler _ NEW [Cucumber.HandlerRep _ [ PartTransfer: TransferDisplay]]; PrepareClock: Cucumber.Bracket--PROC [whole: REF ANY, where: IO.STREAM, direction: Direction, data: REF ANY] RETURNS [leaveTheseToMe: SelectorList _ NIL]-- = {leaveTheseToMe _ LIST[$notice]}; TransferClock: Cucumber.PartTransferProc = UNCHECKED BEGIN cs: ClockState _ NARROW[whole]; SELECT part.first FROM $type, $rv, $cell, $root, $notice, $stopped => NULL; $display => Cucumber.Transfer[what: cs.display, where: where, direction: direction]; ENDCASE => ERROR Cucumber.Error[IO.PutFR["Unexpected field %g in Clock State", IO.atom[NARROW[part.first]]]]; END; TransferDisplay: Cucumber.PartTransferProc = {}; CreateClockGenIO: PROC [ct: RoseTypes.CellType, switch: BOOL] RETURNS [ioAsAny: REF ANY] --RoseTypes.IOCreator-- = {ioAsAny _ IF switch THEN NEW [ClockGenSwitchIORec] ELSE NEW [ClockGenSimpleIORec]}; CreateClockGenDrive: PROC [ct: RoseTypes.CellType] RETURNS [driveAsAny: REF ANY] --RoseTypes.DriveCreator-- = {driveAsAny _ NEW [ClockGenDriveRec]}; InitializeClockGen: RoseTypes.Initializer = BEGIN cgi: ClockType _ NARROW[cell.type.typeData]; newIO: ClockGenSimpleIORef _ NARROW[cell.realCellStuff.newIO]; oldIO: ClockGenSimpleIORef _ NARROW[cell.realCellStuff.oldIO]; display: Display _ NEW [DisplayRep _ [ sofar: 0, state: Initial[cgi.style], Cycle: DoCycle, Step: DoStep, Interrupt: Interrupt, Disable: Disable, Proceed: Proceed, Abort: Abort ]]; cs: ClockState _ NEW [ClockStateRep _ [ type: cgi, display: display, cell: cell, root: RootCell[cell] ]]; [newIO.phi1, newIO.phi2] _ StateToBits[cgi.sense][Initial[cgi.style]]; cell.realCellStuff.state _ cs; TRUSTED {Process.InitializeCondition[condition: @cs.notice, ticks: Process.SecondsToTicks[5]]}; cs.rv _ VR.ViewRef[ agg: display, specs: CONS[["state", Value[val: NIL, visible: TRUE, dontAssign: TRUE]], CONS[["sofar", Value[val: NIL, visible: TRUE, dontAssign: TRUE]], CONS[["status", Value[val: NIL, visible: TRUE, dontAssign: TRUE]], VR.BindAllOfATypeFromRefs[rec: display, handle: NEW [Cell _ cell]] ]]], viewerInit: [name: cell.name, iconic: FALSE], createOptions: [exclusiveProcs: FALSE]]; END; RootCell: PROC [cell: Cell] RETURNS [root: Cell] = {FOR root _ cell, root.parent WHILE root.parent # NIL DO NULL ENDLOOP}; Initial: ARRAY Style OF State = [5, 0]; Interrupt: PROC = {RoseRun.stop _ TRUE}; Disable: PROC [cell: Cell] RETURNS [ok: BOOL] = BEGIN cs: ClockState _ NARROW[cell.realCellStuff.state]; ok _ (cs.stopped # NIL) AND RoseRun.DisableThisStop[cs.stopped]; END; Proceed: ENTRY PROC [cell: Cell] = BEGIN cs: ClockState _ NARROW[cell.realCellStuff.state]; cs.stopResponse _ Resume; cs.display.status _ Normal; BROADCAST cs.notice; END; Abort: ENTRY PROC [cell: Cell] = BEGIN cs: ClockState _ NARROW[cell.realCellStuff.state]; cs.stopResponse _ Abort; cs.display.status _ Normal; BROADCAST cs.notice; END; GetStopResponse: ENTRY PROC [cell: Cell, msg: ROPE, data: REF ANY] RETURNS [sr: StopResponse] = BEGIN cs: ClockState _ NARROW[cell.realCellStuff.state]; RoseEvents.Notify[$Interrupt, NIL, TRUE]; TRUSTED {cs.stopped _ PrincOpsUtils.MyLocalFrame[]}; cs.display.status _ Interrupted; cs.rv.DisplayMessage[msg]; WHILE cs.display.status = Interrupted DO WAIT cs.notice; ENDLOOP; RoseRun.stop _ FALSE; sr _ cs.stopResponse; cs.stopped _ NIL; RoseEvents.Notify[$Start, NIL, TRUE]; END; DoStep: PROC [cell: Cell] = BEGIN RoseEvents.Notify[$Start, NIL, TRUE]; Step[cell !UNWIND => RoseEvents.Notify[$Stop, NIL, TRUE]]; RoseEvents.Notify[$Stop, NIL, TRUE]; END; Step: PUBLIC PROC [cell: Cell] = BEGIN cs: ClockState _ NARROW[cell.realCellStuff.state]; cs.display.state _ Transitions[cs.display.state]; RoseRun.ScheduleCell[cell]; RoseRun.Run[cell.sim !RoseTypes.Stop => CHECKED BEGIN SELECT GetStopResponse[cell, msg, data] FROM Resume => RESUME; Abort => ERROR ABORTED; ENDCASE => ERROR; END]; END; DoCycle: PROC [cell: Cell, cycles: CARDINAL] = BEGIN RoseEvents.Notify[$Start, NIL, TRUE]; Cycle[cell, cycles !UNWIND => RoseEvents.Notify[$Stop, NIL, TRUE]]; RoseEvents.Notify[$Stop, NIL, TRUE]; END; Cycle: PUBLIC PROC [cell: Cell, cycles: CARDINAL] = BEGIN cs: ClockState _ NARROW[cell.realCellStuff.state]; cs.display.sofar _ 0; DO IF cs.display.state = TestTime[cs.type.style] THEN BEGIN IF cycles < 1 THEN EXIT; cycles _ cycles - 1; cs.display.sofar _ cs.display.sofar + 1; END; Step[cell]; IF cs.display.state = EndTime[cs.type.style] THEN RoseEvents.Notify[$EndOfClockCycle, cs.root, TRUE !RoseTypes.Stop => CHECKED BEGIN SELECT GetStopResponse[cell, msg, data] FROM Resume => RESUME; Abort => ERROR ABORTED; ENDCASE => ERROR; END]; ENDLOOP; END; TestTime: ARRAY Style OF State = [5, 0]; EndTime: ARRAY Style OF State = [5, 3]; Transitions: ARRAY State OF State = [1, 2, 3, 0, 5, 4]; StateToBits: ARRAY Sense OF ARRAY State OF RECORD [BOOL, BOOL] = [ [ [FALSE, FALSE], [TRUE, FALSE], [FALSE, FALSE], [FALSE, TRUE], [TRUE, FALSE], [FALSE, TRUE] ], [ [TRUE, TRUE], [FALSE, TRUE], [TRUE, TRUE], [TRUE, FALSE], [FALSE, TRUE], [TRUE, FALSE] ] ]; ClockGenSimple: PROC [cell: Cell, perturb: PROC [portIndex: RoseTypes.PortIndex]] --RoseTypes.CellProc-- = { cs: ClockState _ NARROW[cell.realCellStuff.state]; newIO: ClockGenSimpleIORef _ NARROW[cell.realCellStuff.newIO]; [newIO.phi1, newIO.phi2] _ StateToBits[cs.type.sense][cs.display.state]; }; clockGenPorts: RoseTypes.Ports _ NEW [RoseTypes.PortsRep[2]]; bpw: NAT = Basics.bitsPerWord; bps: NAT = SwitchTypes.bitsPerSwitchVal; Setup: PROC = BEGIN clockGenPorts[0] _ [ simple: [0, bpw-2, 1], switch: [0, 0, bps], name: "PhaseA", type: NumTypes.boolType, output: TRUE]; clockGenPorts[1] _ [ simple: [0, bpw-1, 1], switch: [1, 0, bps], name: "PhaseB", type: NumTypes.boolType, output: TRUE]; clockHandler.Register[CODE[ClockStateRep]]; displayHandler.Register[CODE[DisplayRep]]; END; Setup[]; END.  [Indigo]r>Rosemary.DF=>RoseClocksImpl.Mesa Last Edited by: Spreitzer, May 1, 1985 11:37:26 pm PDT Last Edited by: Barth, June 9, 1983 11:09 am Κ =˜JšœΟmœ!™4J™7J™,Icode˜KšΟk œ+žœw˜­K˜šΠbxœžœž˜Kšžœ žœPžœ ˜oKšžœ ˜—K˜Kšžœžœ ˜K˜Kšžœžœžœ˜Kšœžœ˜K˜Kšœ žœžœ˜$K˜šΟnœžœžœžœ˜Nšœžœžœ˜Kšœ˜Kš žœžœ žœ7žœžœ˜gKš žœžœ žœ/žœžœ˜`—Kšžœ'žœžœžœ˜9˜!Kšœ ˜ K˜K˜"K˜ K˜$K˜Kšœ žœ˜'—Kšœ˜—K˜Kšœžœžœ˜4šœžœžœ˜$Kšœ=˜=Kšœ žœ˜—K˜Kšœžœžœ˜4šœžœžœ˜$K˜#—K˜Kšœžœžœ˜.šœžœžœ˜!Kšœ˜Kšœžœžœžœ˜;—K˜Kšœžœ˜0K˜Kšœ žœžœ˜%šœžœžœ˜Kšœ˜K˜Kšœžœ˜K˜Kšœž œ˜Kšœ#˜#Kšœ žœ˜%—K˜Kšœžœ˜%K˜Kšœ žœžœ ˜šœ žœžœ˜Kšœžœ˜Kšœ ˜ K˜Kš œžœžœ˜+Kš œžœ˜Kš  œžœ˜Kš œžœžœžœ˜.Kšœ  œžœ˜$—K˜Kšœžœ ˜K˜Kšœžœ˜%K˜šœ!žœ˜=Kšœ˜K˜—K˜šœ#žœ˜?K˜ —K˜š  œΟc}œ˜Kšœžœ ˜!—K˜šœ+ž ˜4Kšž˜Kšœžœ˜šžœ ž˜Kšœ/žœ˜4K˜TKš žœžœžœ-žœžœ˜m—Kšžœ˜—K˜Kšœ0˜0K˜š œžœ"žœžœ žœžœ‘œ˜rKš œ žœžœžœžœžœ˜T—K˜š  œžœžœžœžœ‘œ˜mKšœžœ˜&—K˜šœ+˜+Kšž˜Kšœžœ˜,Kšœžœ˜>Kšœžœ˜>šœžœ˜&K˜ K˜K˜K˜ K˜K˜K˜K˜—šœžœ˜'K˜ K˜K˜ K˜—KšœF˜FKšœ˜KšžœX˜_šœžœ ˜K˜ š œžœžœ žœžœ˜HKšžœžœ žœžœ˜AKšžœžœ žœžœ˜BKšžœ.žœ˜G—Kšœ&žœ˜-Kšœ žœ˜(—Kšžœ˜—K˜š œžœžœ˜2Kš œžœžœžœžœžœžœ˜G—K˜Kšœ žœžœ˜'K˜Kš  œžœžœ˜(K˜š œžœžœžœ˜/Kšž˜Kšœžœ˜2Kšœžœžœ%˜@Kšžœ˜—K˜š œžœžœ˜"Kšž˜Kšœžœ˜2Kšœ˜Kšœ˜Kšž œ ˜Kšžœ˜—K˜š œžœžœ˜ Kšž˜Kšœžœ˜2Kšœ˜Kšœ˜Kšž œ ˜Kšžœ˜—K˜š œžœžœžœžœžœžœ˜_Kšž˜Kšœžœ˜2Kšœžœžœ˜)Kšžœ-˜4Kšœ ˜ Kšœ˜šžœ!ž˜(Kšžœ ˜Kšžœ˜—Kšœžœ˜Kšœ˜Kšœ žœ˜Kšœžœžœ˜%Kšžœ˜—K˜š œžœ˜Kšž˜Kšœžœžœ˜%Kšœ žœžœžœ˜:Kšœžœžœ˜$Kšžœ˜—K˜š œžœžœ˜ Kšž˜Kšœžœ˜2Kšœ1˜1K˜˜šœž˜Kšž˜šžœ"ž˜,Kšœ žœ˜Kšœ žœžœ˜Kšžœžœ˜—Kšžœ˜——Kšžœ˜—K˜š œžœžœ˜.Kšž˜Kšœžœžœ˜%Kšœžœžœžœ˜CKšœžœžœ˜$Kšžœ˜—K˜š œžœžœžœ˜3Kšž˜Kšœžœ˜2K˜šž˜šžœ,ž˜2Kšž˜Kšžœ žœžœ˜K˜K˜(Kšžœ˜—Kšœ ˜ šžœ+žœ.ž˜cšœž˜Kšž˜šžœ"ž˜,Kšœ žœ˜Kšœ žœžœ˜Kšžœžœ˜—Kšžœ˜——Kšžœ˜—Kšžœ˜—K˜Kšœ žœžœ˜(K˜Kšœ žœžœ˜'K˜Kšœ žœžœ˜7K˜šœ žœžœžœžœžœžœžœ˜@šœ˜šœ˜Kšœžœžœ˜Kšœžœžœ˜Kšœžœžœ˜Kšœžœžœ˜Kšœžœžœ˜Kšœžœžœ˜—˜Kšœžœžœ˜ Kšœžœžœ˜Kšœžœžœ˜ Kšœžœžœ˜Kšœžœžœ˜Kšœžœžœ˜———K˜š œžœžœ#‘œ˜lKšœžœ˜2Kšœžœ˜>KšœH˜HKšœ˜—K˜Kšœ!žœ˜=K˜Kšœžœ˜Kšœžœ ˜(K˜š œžœ˜ Kšž˜šœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœžœ˜—šœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœžœ˜—K˜Kšœžœ˜+Kšœžœ˜*Kšžœ˜—K˜K˜K˜Kšžœ˜—…— +η