<> <> <> <<>> DIRECTORY SmallCacheDataPath, CMosB, Core, CoreClasses, CoreOps, DataPath, IO, Ports, Rosemary; SmallCacheDataPathImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreOps, DataPath, IO, Ports, Rosemary EXPORTS SmallCacheDataPath = BEGIN <> Structure: PUBLIC PROC[wds, bits: NAT] RETURNS [public: Core.Wires] = {-- strc and flat <> <> strc: Core.Wire _ CoreOps.CreateWires[wds, "strc"]; flat: Core.Wire _ CoreOps.CreateWires[wds*bits, "flat"]; IF bits=0 OR wds=0 THEN ERROR; -- Please provide parameters for Structure FOR wd: NAT IN [0..wds) DO strc[wd] _ CoreOps.CreateWires[bits]; FOR bit: NAT IN [0..bits) DO flat[wd*bits + bit] _ strc[wd][bit] _ CoreOps.CreateWires[0] ENDLOOP ENDLOOP; public _ LIST [strc, flat]}; BusShort: PUBLIC PROC[size: INT] RETURNS[wire: Core.Wire] = { sub: Core.Wire _ CoreOps.CreateWires[0, "sw"]; wire _ CoreOps.CreateWires[size, "w"]; FOR i: INT IN [0..size) DO wire[i] _ sub ENDLOOP}; Trans: PUBLIC PROC[type: CoreClasses.TransistorType, length, width: INT] RETURNS [cellType: Core.CellType] = { name: IO.ROPE _ IO.PutFR["%g%gx%g", IO.rope[CoreClasses.transistorTypeNames[type]], IO.int[length], IO.int[width]]; cellType _ CoreClasses.CreateTransistor[type, length, width, name]}; <> DP32FFName: IO.ROPE = Rosemary.Register ["DP32FFSeq", DPFFSeqInit, DPFFSeqSimple, NIL, TRUE]; DP64FFName: IO.ROPE = Rosemary.Register ["DP64FFSeq", DPFFSeqInit, DPFFSeqSimple, NIL, TRUE]; DPFFSeqState: TYPE = REF DPFFSeqStateRec; DPFFSeqStateRec: TYPE = RECORD [ in, out, ck: Ports.Port _ NIL, master, slave: Ports.LevelSequence]; DPFFSeqInit: Rosemary.InitProc = { state: DPFFSeqState; IF oldStateAny=NIL THEN { size: NAT _ p[Ports.PortIndex[cellType.public, "D"]].ls.size; state _ NEW[DPFFSeqStateRec]; state.master _ NEW[Ports.LevelSequenceRec[size]]; state.slave _ NEW[Ports.LevelSequenceRec[size]]} ELSE state _ NARROW[oldStateAny]; state.ck _ p[Ports.PortIndex[cellType.public, "CK"]]; state.in _ p[Ports.PortIndex[cellType.public, "D"]]; state.out _ p[Ports.PortIndex[cellType.public, "Q"]]; Ports.PutDrive[state.out, drive]; Ports.SetLS[state.master, X]; Ports.SetLS[state.slave, X]; Ports.SetLS[state.out.ls, X]; stateAny _ state}; DPFFSeqSimple: Rosemary.EvalProc = { state: DPFFSeqState _ NARROW[stateAny]; IF ~clockEval THEN { SELECT state.ck.l FROM L => Ports.CopyLS[from: state.in.ls, to: state.master]; H => Ports.CopyLS[from: state.master, to: state.slave]; ENDCASE => { IF state.slave#state.master THEN Ports.SetLS[state.slave, X]; IF state.master#state.in.ls THEN Ports.SetLS[state.master, X]}}; Ports.CopyLS[from: state.slave, to: state.out.ls]}; <> DP32EnFFName: IO.ROPE = Rosemary.Register ["DP32EnFFSeq", DPEnFFSeqInit, DPEnFFSeqSimple, NIL, TRUE]; DP64EnFFName: IO.ROPE = Rosemary.Register ["DP64EnFFSeq", DPEnFFSeqInit, DPEnFFSeqSimple, NIL, TRUE]; DPEnFFSeqState: TYPE = REF DPEnFFSeqStateRec; DPEnFFSeqStateRec: TYPE = RECORD [ in, out, ck, en, dis: Ports.Port _ NIL, master, slave: Ports.LevelSequence]; DPEnFFSeqInit: Rosemary.InitProc = { state: DPEnFFSeqState; IF oldStateAny=NIL THEN { size: NAT _ p[Ports.PortIndex[cellType.public, "D"]].ls.size; state _ NEW[DPEnFFSeqStateRec]; state.master _ NEW[Ports.LevelSequenceRec[size]]; state.slave _ NEW[Ports.LevelSequenceRec[size]]} ELSE state _ NARROW[oldStateAny]; state.ck _ p[Ports.PortIndex[cellType.public, "CK"]]; state.in _ p[Ports.PortIndex[cellType.public, "D"]]; state.out _ p[Ports.PortIndex[cellType.public, "Q"]]; state.en _ p[Ports.PortIndex[cellType.public, "En"]]; state.dis _ p[Ports.PortIndex[cellType.public, "nEn"]]; Ports.PutDrive[state.out, drive]; Ports.SetLS[state.master, X]; Ports.SetLS[state.slave, X]; Ports.SetLS[state.out.ls, X]; stateAny _ state}; DPEnFFSeqSimple: Rosemary.EvalProc = { state: DPEnFFSeqState _ NARROW[stateAny]; IF ~clockEval THEN { SELECT state.ck.l FROM L => IF state.en.l=state.dis.l THEN Ports.SetLS[state.master, X] ELSE IF state.en.l=H THEN Ports.CopyLS[from: state.slave, to: state.master] ELSE Ports.CopyLS[from: state.in.ls, to: state.master]; H => Ports.CopyLS[from: state.master, to: state.slave]; ENDCASE => { IF state.slave#state.master THEN Ports.SetLS[state.slave, X]; IF state.master#state.in.ls THEN Ports.SetLS[state.master, X]}}; Ports.CopyLS[from: state.slave, to: state.out.ls]}; <> DP32LatchName: IO.ROPE = Rosemary.Register ["DP32LatchSeq", DPLatchSeqInit, DPLatchSeqSimple, NIL, FALSE]; DP64LatchName: IO.ROPE = Rosemary.Register ["DP64LatchSeq", DPLatchSeqInit, DPLatchSeqSimple, NIL, FALSE]; DPLatchSeqState: TYPE = REF DPLatchSeqStateRec; DPLatchSeqStateRec: TYPE = RECORD [ in, out, en: Ports.Port _ NIL, slave: Ports.LevelSequence ]; DPLatchSeqInit: Rosemary.InitProc = { state: DPLatchSeqState; IF oldStateAny=NIL THEN { size: NAT _ p[Ports.PortIndex[cellType.public, "D"]].ls.size; state _ NEW[DPLatchSeqStateRec]; state.slave _ NEW[Ports.LevelSequenceRec[size]]} ELSE state _ NARROW[oldStateAny]; state.in _ p[Ports.PortIndex[cellType.public, "D"]]; state.out _ p[Ports.PortIndex[cellType.public, "Q"]]; state.en _ p[Ports.PortIndex[cellType.public, "En"]]; Ports.PutDrive[state.out, drive]; Ports.SetLS[state.out.ls, X]; Ports.SetLS[state.slave, X]; stateAny _ state}; DPLatchSeqSimple: Rosemary.EvalProc = { state: DPLatchSeqState _ NARROW[stateAny]; IF state.en.l=H THEN Ports.CopyLS[from: state.in.ls, to: state.slave]; Ports.CopyLS[from: state.slave, to: state.out.ls]; Ports.PutDrive[state.out, drive]}; <> DP32CompName: IO.ROPE = Rosemary.Register ["DP32CompSeq", DPCompSeqInit, DPCompSeqSimple]; DP64CompName: IO.ROPE = Rosemary.Register ["DP64CompSeq", DPCompSeqInit, DPCompSeqSimple]; DPCompSeqState: TYPE = REF DPCompSeqStateRec; DPCompSeqStateRec: TYPE = RECORD [a, b, mat: Ports.Port]; DPCompSeqInit: Rosemary.InitProc = { state: DPCompSeqState _ IF oldStateAny=NIL THEN NEW[DPCompSeqStateRec] ELSE NARROW[oldStateAny]; state.a _ p[Ports.PortIndex[cellType.public, "A"]]; state.b _ p[Ports.PortIndex[cellType.public, "B"]]; state.mat _ p[Ports.PortIndex[cellType.public, "Match"]]; stateAny _ state}; DPCompSeqSimple: Rosemary.EvalProc = { state: DPCompSeqState _ NARROW[stateAny]; level: Ports.Level _ H; FOR index: NAT IN [0..state.a.ls.size) DO SELECT TRUE FROM state.a.ls[index]=X, state.b.ls[index]=X => {level _ X; EXIT}; state.a.ls[index] # state.b.ls[index] => {level _ L}; ENDCASE ENDLOOP; IF level=H THEN Ports.PutDrive[state.mat, none] ELSE Ports.PutLevel[state.mat, level, drive]}; <> DP32MuxName: IO.ROPE = Rosemary.Register ["DP32Mux2Seq", DPMux2SingSelSeqInit, DPMux2SingSelSeqSimple]; DP64MuxName: IO.ROPE = Rosemary.Register ["DP64Mux2Seq", DPMux2DualSelSeqInit, DPMux2DualSelSeqSimple]; DPMux2SingSelSeqState: TYPE = REF DPMux2SingSelSeqStateRec; DPMux2DualSelSeqState: TYPE = REF DPMux2DualSelSeqStateRec; DPMux2SingSelSeqStateRec: TYPE = RECORD [in0, in1, sel0, out: Ports.Port]; DPMux2DualSelSeqStateRec: TYPE = RECORD [in0, in1, sel0, sel1, out: Ports.Port]; DPMux2SingSelSeqInit: Rosemary.InitProc = { state: DPMux2SingSelSeqState _ IF oldStateAny=NIL THEN NEW[DPMux2SingSelSeqStateRec] ELSE NARROW[oldStateAny]; state.in0 _ p[Ports.PortIndex[cellType.public, "In0"]]; state.in1 _ p[Ports.PortIndex[cellType.public, "In1"]]; state.sel0 _ p[Ports.PortIndex[cellType.public, "Sel0"]]; state.out _ p[Ports.PortIndex[cellType.public, "Out"]]; Ports.PutDrive[state.out, drive]; stateAny _ state}; DPMux2DualSelSeqInit: Rosemary.InitProc = { state: DPMux2DualSelSeqState _ IF oldStateAny=NIL THEN NEW[DPMux2DualSelSeqStateRec] ELSE NARROW[oldStateAny]; state.in0 _ p[Ports.PortIndex[cellType.public, "In0"]]; state.in1 _ p[Ports.PortIndex[cellType.public, "In1"]]; state.sel0 _ p[Ports.PortIndex[cellType.public, "Sel0"]]; state.sel1 _ p[Ports.PortIndex[cellType.public, "Sel1"]]; state.out _ p[Ports.PortIndex[cellType.public, "Out"]]; Ports.PutDrive[state.out, drive]; stateAny _ state}; DPMux2SingSelSeqSimple: Rosemary.EvalProc = { state: DPMux2SingSelSeqState _ NARROW[stateAny]; FOR index: NAT IN [0..state.in0.ls.size) DO state.out.ls[index] _ IF state.sel0.l=H THEN state.in0.ls[index] ELSE state.in1.ls[index] ENDLOOP}; DPMux2DualSelSeqSimple: Rosemary.EvalProc = { state: DPMux2DualSelSeqState _ NARROW[stateAny]; FOR index: NAT IN [0..state.in0.ls.size) DO state.out.ls[index] _ IF state.sel0.l=state.sel1.l THEN X ELSE IF state.sel0.l=H THEN state.in0.ls[index] ELSE state.in1.ls[index] ENDLOOP}; <> DP32TstName: IO.ROPE = Rosemary.Register ["DP32TstSeq", DPTstSingEnSeqInit, DPTstSingEnSeqSimple]; DP64TstName: IO.ROPE = Rosemary.Register ["DP64TstSeq", DPTstDualEnSeqInit, DPTstDualEnSeqSimple]; DP64TstFlipYName: IO.ROPE = Rosemary.Register ["DP64TstFlipYSeq", DPTstDualEnSeqInit, DPTstDualEnSeqSimple]; DPTstSingEnSeqState: TYPE = REF DPTstSingEnSeqStateRec; DPTstDualEnSeqState: TYPE = REF DPTstDualEnSeqStateRec; DPTstSingEnSeqStateRec: TYPE = RECORD [in, out, en: Ports.Port]; DPTstDualEnSeqStateRec: TYPE = RECORD [in, out, en, dis: Ports.Port]; DPTstSingEnSeqInit: Rosemary.InitProc = { state: DPTstSingEnSeqState _ IF oldStateAny=NIL THEN NEW[DPTstSingEnSeqStateRec] ELSE NARROW[oldStateAny]; state.in _ p[Ports.PortIndex[cellType.public, "In"]]; state.out _ p[Ports.PortIndex[cellType.public, "Out"]]; state.en _ p[Ports.PortIndex[cellType.public, "En"]]; Ports.PutDrive[state.out, drive]; stateAny _ state}; DPTstDualEnSeqInit: Rosemary.InitProc = { state: DPTstDualEnSeqState _ IF oldStateAny=NIL THEN NEW[DPTstDualEnSeqStateRec] ELSE NARROW[oldStateAny]; state.in _ p[Ports.PortIndex[cellType.public, "In"]]; state.out _ p[Ports.PortIndex[cellType.public, "Out"]]; state.en _ p[Ports.PortIndex[cellType.public, "En"]]; state.dis _ p[Ports.PortIndex[cellType.public, "nEn"]]; Ports.PutDrive[state.out, drive]; stateAny _ state}; DPTstSingEnSeqSimple: Rosemary.EvalProc = { state: DPTstSingEnSeqState _ NARROW[stateAny]; IF state.en.l=H THEN { Ports.CopyLS[state.in.ls, state.out.ls]; Ports.PutDrive[state.out, drive]}}; DPTstDualEnSeqSimple: Rosemary.EvalProc = { state: DPTstDualEnSeqState _ NARROW[stateAny]; IF state.en.l=state.dis.l THEN {Ports.SetLS[state.out.ls, X]; Ports.PutDrive[state.out, drive]} ELSE { Ports.CopyLS[state.in.ls, state.out.ls]; Ports.PutDrive[state.out, (IF state.en.l=H THEN drive ELSE none)]}}; <> DataPath.RegisterDataPathSpec["SmallCache64", NEW[DataPath.DPSpecRec _ [ layDWidth: 65*CMosB.lambda]]]; DataPath.RegisterDataPathSpec["SmallCache32", NEW[DataPath.DPSpecRec _ [ layDWidth: 162*CMosB.lambda]]]; END. <<>>