DIRECTORY CoreClasses, CoreCreate, CoreFlat, Logic, LogicUtils, Ports, Rosemary; LogicRegsImpl: CEDAR PROGRAM IMPORTS CoreCreate, CoreFlat, Logic, LogicUtils, Ports, Rosemary EXPORTS Logic = BEGIN OPEN Logic, CoreCreate; RegRef: TYPE = REF RegRec; RegRec: TYPE = RECORD [ ck, in, out, nOut, enable, reset: NAT _ LAST[NAT], prevCK: Ports.Level, master, slave: Ports.LevelSequence]; RegisterName: ROPE = Rosemary.Register[roseClassName: "Register", init: RegInit, evalSimple: RegSimple]; Register: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { cell: CellType _ LogicUtils.Extract["reg1B.sch", TRUE]; SELECT b FROM <=0 => LogicUtils.Error["Please specify size of register"]; ENDCASE => ct _ SequenceCell[name: RegisterName, baseCell: cell, count: b, sequencePorts: Wires["Input", "Output", "nOutput"]]; [] _ CoreFlat.CellTypeCutLabels[ct, macroCutSet]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "CK", "en"]; Ports.InitPorts[ct, ls, none, "Input"]; Ports.InitPorts[ct, ls, drive, "Output", "nOutput"]; }; RegInit: Rosemary.InitProc = { state: RegRef _ NEW[RegRec]; b: NAT; [state.ck, state.in, state.out, state.nOut, state.enable] _ Ports.PortIndexes[cellType.public, "CK", "Input", "Output", "nOutput", "en"]; b _ p[state.in].ls.size; state.master _ NEW[Ports.LevelSequenceRec[b]]; state.slave _ NEW[Ports.LevelSequenceRec[b]]; state.prevCK _ X; Ports.SetLS[state.master, X]; Ports.SetLS[state.slave, X]; Ports.SetLS[p[state.out].ls, X]; Ports.SetLS[p[state.nOut].ls, X]; stateAny _ state; }; RegSimple: Rosemary.EvalProc = { state: RegRef _ NARROW[stateAny]; IF p[state.ck].l=L THEN Ports.CopyLS[from: p[state.in].ls, to: state.master] ELSE IF (state.prevCK=L AND p[state.ck].l=H AND p[state.enable].l=H) THEN Ports.CopyLS[from: state.master, to: state.slave]; Ports.CopyLS[from: state.slave, to: p[state.out].ls]; Ports.NotLS[p[state.out].ls, p[state.nOut].ls]; state.prevCK _ p[state.ck].l; }; RegisterRName: ROPE = Rosemary.Register[roseClassName: "RegisterR", init: RegRInit, evalSimple: RegRSimple]; RegisterR: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { cell: CellType _ LogicUtils.Extract["reg1BitReset.sch", TRUE]; SELECT b FROM <=0 => LogicUtils.Error["Please specify size of register"]; ENDCASE => ct _ SequenceCell[name: RegisterRName, baseCell: cell, count: b, sequencePorts: Wires["Input", "Output", "nOutput"]]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "CK", "en", "r"]; Ports.InitPorts[ct, ls, none, "Input"]; Ports.InitPorts[ct, ls, drive, "Output", "nOutput"]; [] _ CoreFlat.CellTypeCutLabels[ct, macroCutSet]; }; RegRInit: Rosemary.InitProc = { state: RegRef _ NEW[RegRec]; b: NAT; [state.ck, state.in, state.out, state.nOut, state.enable, state.reset] _ Ports.PortIndexes[cellType.public, "CK", "Input", "Output", "nOutput", "en", "r"]; b _ p[state.in].ls.size; state.master _ NEW[Ports.LevelSequenceRec[b]]; state.slave _ NEW[Ports.LevelSequenceRec[b]]; state.prevCK _ X; Ports.SetLS[state.master, X]; Ports.SetLS[state.slave, X]; Ports.SetLS[p[state.out].ls, X]; Ports.SetLS[p[state.nOut].ls, X]; stateAny _ state; }; RegRSimple: Rosemary.EvalProc = { state: RegRef _ NARROW[stateAny]; IF p[state.ck].l=L THEN Ports.CopyLS[from: p[state.in].ls, to: state.master] ELSE IF (state.prevCK=L AND p[state.ck].l=H) THEN { IF p[state.reset].l=H THEN {Ports.SetLS[state.master, L]; Ports.SetLS[state.slave, L]} ELSE IF p[state.enable].l=H THEN Ports.CopyLS[from: state.master, to: state.slave]}; Ports.CopyLS[from: state.slave, to: p[state.out].ls]; Ports.NotLS[p[state.out].ls, p[state.nOut].ls]; state.prevCK _ p[state.ck].l; }; RegisterSimpleName: ROPE = Rosemary.Register[roseClassName: "RegisterSimple", init: RegSInit, evalSimple: RegSSimple]; RegisterSimple: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { SELECT b FROM <=0 => LogicUtils.Error["Please specify size of register"]; ENDCASE => ct _ SequenceCell[name: RegisterSimpleName, baseCell: LogicUtils.Extract["reg1BSimple.sch", TRUE], count: b, sequencePorts: Wires["Input", "Output", "nOutput"]]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "CK"]; Ports.InitPorts[ct, ls, none, "Input"]; Ports.InitPorts[ct, ls, drive, "Output", "nOutput"]; [] _ CoreFlat.CellTypeCutLabels[ct, macroCutSet]; }; RegSInit: Rosemary.InitProc = { state: RegRef _ NEW[RegRec]; b: NAT; [state.ck, state.in, state.out, state.nOut] _ Ports.PortIndexes[cellType.public, "CK", "Input", "Output", "nOutput"]; b _ p[state.in].ls.size; state.master _ NEW[Ports.LevelSequenceRec[b]]; state.slave _ NEW[Ports.LevelSequenceRec[b]]; state.prevCK _ X; Ports.SetLS[state.master, X]; Ports.SetLS[state.slave, X]; Ports.SetLS[p[state.out].ls, X]; Ports.SetLS[p[state.nOut].ls, X]; stateAny _ state; }; RegSSimple: Rosemary.EvalProc = { state: RegRef _ NARROW[stateAny]; IF p[state.ck].l=L THEN Ports.CopyLS[from: p[state.in].ls, to: state.master] ELSE IF (state.prevCK=L AND p[state.ck].l=H) THEN Ports.CopyLS[from: state.master, to: state.slave]; Ports.CopyLS[from: state.slave, to: p[state.out].ls]; Ports.NotLS[p[state.out].ls, p[state.nOut].ls]; state.prevCK _ p[state.ck].l; }; InvSeq: PROC [b: NAT] RETURNS [ct: CellType] ~ { SELECT b FROM <=0 => LogicUtils.Error["Please specify size of inverters' sequence"]; ENDCASE => ct _ SequenceCell[name: "InverterSequence", baseCell: Inv[], count: b, sequencePorts: Wires["I", "X"]]; }; TristateSeq: PROC [b: NAT] RETURNS [ct: CellType] ~ { SELECT b FROM <=0 => LogicUtils.Error["Please specify size of tristate drivers' sequence"]; ENDCASE => ct _ SequenceCell[name: "TristateSequence", baseCell: TstDriver[], count: b, sequencePorts: Wires["I", "X"]]; }; TstState: TYPE = REF TstStateRec; TstStateRec: TYPE = RECORD [ in, out, enable: NAT _ LAST[NAT]]; TstBufferName: ROPE = Rosemary.Register[roseClassName: "TstBuffer", init: TstBufferInit, evalSimple: TstBufferSimple]; TristateBuffer: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { insts: CellInstances _ LIST[ Instance[InvSeq[b], ["I", "Input"], ["X", "nInput"]], Instance[TristateBufferInv[b], ["Input", "nInput"], ["Output", "Output"]] ]; ct _ Cell[ name: TstBufferName, public: Wires["Vdd", "Gnd", Seq["Input", b], Seq["Output", b], "enable"], onlyInternal: Wires[Seq["nInput", b]], instances: insts]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: TstBufferName]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "enable"]; Ports.InitPorts[ct, ls, none, "Input"]; Ports.InitPorts[ct, ls, none, "Output"]; [] _ CoreFlat.CellTypeCutLabels[ct, macroCutSet]; }; TstBufferInit: Rosemary.InitProc = { state: TstState _ NEW[TstStateRec]; {OPEN state; [in, out, enable] _ Ports.PortIndexes[cellType.public, "Input", "Output", "enable"]}; stateAny _ state}; TstBufferSimple: Rosemary.EvalProc = { state: TstState _ NARROW[stateAny]; {OPEN state; IF p[enable].l=H THEN { p[out].d _ drive; Ports.CopyLS[from: p[in].ls, to: p[out].ls]; } ELSE p[out].d _ none; }}; TstBufferInvName: ROPE = Rosemary.Register[roseClassName: "TstBufferInv", init: TstBufferInvInit, evalSimple: TstBufferInvSimple]; TristateBufferInv: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { insts: CellInstances _ LIST[ Instance[TristateSeq[b], ["I", "Input"], ["X", "Output"], ["EN", "enable"], ["NEN", "nEnable"]], Instance[Inv[], ["I", "enable"], ["X", "nEnable"]] ]; ct _ Cell[ name: TstBufferInvName, public: Wires["Vdd", "Gnd", Seq["Input", b], Seq["Output", b], "enable"], onlyInternal: Wires["nEnable"], instances: insts]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: TstBufferInvName]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "enable"]; Ports.InitPorts[ct, ls, none, "Input"]; Ports.InitPorts[ct, ls, none, "Output"]; [] _ CoreFlat.CellTypeCutLabels[ct, macroCutSet]; }; TstBufferInvInit: Rosemary.InitProc = { state: TstState _ NEW[TstStateRec]; {OPEN state; [in, out, enable] _ Ports.PortIndexes[cellType.public, "Input", "Output", "enable"]}; stateAny _ state}; TstBufferInvSimple: Rosemary.EvalProc = { state: TstState _ NARROW[stateAny]; {OPEN state; IF p[enable].l=H THEN { p[out].d _ drive; Ports.NotLS[p[in].ls, p[out].ls]; } ELSE p[out].d _ none; }}; LatchName: ROPE = Rosemary.Register[roseClassName: "Latch", init: LatchInit, evalSimple: LatchSimple]; Latch: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] ~ { array: CellType; SELECT b FROM <=0 => LogicUtils.Error["Please specify size of latch"]; ENDCASE => array _ SequenceCell[name: LatchName, baseCell: DLatch[], count: b, sequencePorts: Wires["D", "Q"]]; ct _ Cell[name: LatchName, public: Wires["Vdd", "Gnd", "CK", Seq["Input", b], Seq["Output", b]], instances: LIST[Instance[array, ["D", "Input"], ["Q", "Output"], ["S", "CK"]]]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: LatchName]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "CK"]; Ports.InitPorts[ct, ls, none, "Input"]; Ports.InitPorts[ct, ls, drive, "Output"]; [] _ CoreFlat.CellTypeCutLabels[ct, macroCutSet]; }; LatchInit: Rosemary.InitProc = { state: RegRef _ NEW[RegRec]; {OPEN state; b: NAT; [ck, in, out] _ Ports.PortIndexes[cellType.public, "CK", "Input", "Output"]; b _ p[in].ls.size; master _ NEW[Ports.LevelSequenceRec[b]]; Ports.SetLS[master, X]; Ports.SetLS[p[out].ls, X]}; stateAny _ state; }; LatchSimple: Rosemary.EvalProc = { state: RegRef _ NARROW[stateAny]; {OPEN state; IF p[ck].l=H THEN Ports.CopyLS[from: p[in].ls, to: master]; IF p[ck].l=X THEN Ports.SetLS[master, X]; Ports.CopyLS[from: master, to: p[out].ls]; }}; END. LogicRegsImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Last Edited by: Louis Monier January 5, 1987 9:12:21 pm PST Christian LeCocq October 14, 1986 2:10:45 pm PDT Barth, October 10, 1986 5:30:59 pm PDT Register -- this type is shared among all registers Tristate Buffer -- "Vdd", "Gnd", Seq["I", b], Seq["X", b] -- "Vdd", "Gnd", Seq["I", b], Seq["X", b], "EN", "NEN" [] _ Register[2]; [] _ RegisterR[2]; [] _ RegisterSimple[2]; [] _ TristateBuffer[2]; [] _ TristateBufferInv[2]; [] _ Latch[2]; Κ {– "cedar" style˜codešœ™Kšœ Οmœ1™šžœž˜ Kšœ;˜;šžœ*˜1Kšœ˜Kšœ4˜4——Kšœ<˜