<> <> <> <<>> <<>> DIRECTORY Core, CoreClasses, CoreCreate, CoreFlat, Ports, Rosemary, RosemaryUser, SCLogic, SCParms; <<>> SCBWdWtPipeImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreCreate, CoreFlat, Ports, Rosemary, SCParms EXPORTS SCLogic ~ BEGIN OPEN SCLogic; <> NumBitsPerWord: NAT = SCParms.numBitsPerWord; InternalState: TYPE = RECORD [ en: ARRAY [0..3] OF Level, a, b, c: LevelSequence ]; State: TYPE = REF StateRec; StateRec: TYPE = RECORD [ master: InternalState, slave: InternalState ]; <> EnBWdWtPipe, RplyData, D, Q, Clock: NAT; <> SCBWdWtPipe : PUBLIC PROC [] RETURNS [ct: CellType] = { public: Wire _ CoreCreate.WireList[LIST[CoreCreate.Seq["RplyData",NumBitsPerWord], CoreCreate.Seq["D",NumBitsPerWord], CoreCreate.Seq["Q",NumBitsPerWord], "EnBWdWtPipe", "Clock"]]; ct _ CoreClasses.CreateUnspecified[public: public]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: bWdWtPipeName]; [] _ CoreFlat.CellTypeCutLabels[ct, "Logic"]; Ports.InitPorts[ct, ls, none, "D"]; Ports.InitPorts[ct, l, none, "EnBWdWtPipe", "Clock"]; Ports.InitPorts[ct, ls, drive, "RplyData"]; Ports.InitPorts[ct, ls, drive, "Q"] }; <> Init: Rosemary.InitProc = { s: State; IF oldStateAny=NIL THEN { s _ NEW [StateRec]; s.master.a _ NEW [LevelSequenceRec[NumBitsPerWord]]; s.master.b _ NEW [LevelSequenceRec[NumBitsPerWord]]; s.master.c _ NEW [LevelSequenceRec[NumBitsPerWord]]; s.slave.a _ NEW [LevelSequenceRec[NumBitsPerWord]]; s.slave.b _ NEW [LevelSequenceRec[NumBitsPerWord]]; s.slave.c _ NEW [LevelSequenceRec[NumBitsPerWord]]; } ELSE s _ NARROW [oldStateAny, State]; FOR i : INT IN [0..3] DO s.master.en[i] _ X; s.slave.en[i] _ X; ENDLOOP; Ports.SetLS[s.master.a, X]; Ports.SetLS[s.master.b, X]; Ports.SetLS[s.master.c, X]; Ports.SetLS[s.slave.a, X]; Ports.SetLS[s.slave.b, X]; Ports.SetLS[s.slave.c, X]; [EnBWdWtPipe, RplyData, D, Q, Clock] _ Ports.PortIndexes[cellType.public, "EnBWdWtPipe", "RplyData", "D", "Q", "Clock"]; stateAny _ s; }; Simple: Rosemary.EvalProc = { s: State _ NARROW[stateAny]; IF NOT clockEval THEN SELECT p[Clock].l FROM L => { s.master.en[3] _ s.slave.en[2]; s.master.en[2] _ s.slave.en[1]; s.master.en[1] _ s.slave.en[0]; s.master.en[0] _ p[EnBWdWtPipe].l; IF p[EnBWdWtPipe].l=H THEN Ports.CopyLS[p[D].ls, s.master.a]; IF s.slave.en[1]=H THEN Ports.CopyLS[s.slave.a, s.master.b]; IF s.slave.en[3]=H THEN Ports.CopyLS[s.slave.b, s.master.c]; }; H => { FOR i: NAT IN [0..3] DO s.slave.en[i] _ s.master.en[i] ENDLOOP; Ports.CopyLS[s.master.a, s.slave.a]; Ports.CopyLS[s.master.b, s.slave.b]; Ports.CopyLS[s.master.c, s.slave.c]; }; X => { FOR i: NAT IN [0..3] DO s.slave.en[i] _ s.master.en[i] ENDLOOP; Ports.SetLS[s.master.a, X]; Ports.SetLS[s.master.b, X]; Ports.SetLS[s.master.c, X]; Ports.SetLS[s.slave.a, X]; Ports.SetLS[s.slave.b, X]; Ports.SetLS[s.slave.c, X]; }; ENDCASE => ERROR; Ports.CopyLS[s.slave.a, p[RplyData].ls]; Ports.CopyLS[s.slave.c, p[Q].ls]; }; bWdWtPipeName: ROPE = Rosemary.Register[roseClassName: "SCBWdWtPipe", init: Init, evalSimple: Simple, scheduleIfClockEval: TRUE]; END. <<>>