DIRECTORY CoreClasses, CoreCreate, CoreFlat, IO, Logic, LogicUtils, Ports, Rosemary; LogicSimpleImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreCreate, CoreFlat, IO, Logic, LogicUtils, Ports, Rosemary EXPORTS Logic = BEGIN OPEN Logic, CoreCreate; IXRef: TYPE = REF IXRec; IXRec: TYPE = RECORD [in, out: NAT _ LAST[NAT]]; I4XRef: TYPE = REF I4XRec; I4XRec: TYPE = RECORD [in0, in1, in2, in3, out: NAT _ LAST[NAT]]; IXInit: Rosemary.InitProc = { state: IXRef _ IF oldStateAny=NIL THEN NEW[IXRec] ELSE NARROW[oldStateAny]; [state.in, state.out] _ Ports.PortIndexes[cellType.public, "I", "X"]; stateAny _ state; }; I2XInit: Rosemary.InitProc = { state: I4XRef _ IF oldStateAny=NIL THEN NEW[I4XRec] ELSE NARROW[oldStateAny]; [state.in0, state.in1, state.out] _ Ports.PortIndexes[cellType.public, "I-A", "I-B", "X"]; stateAny _ state; }; InvName: ROPE = Rosemary.Register[roseClassName: "Inv", init: InvInit, evalSimple: InvSimple]; Inv: PUBLIC PROC RETURNS [ct: CellType] = { ct _ LogicUtils.MakeSC[nameInLib: "inv", width: 2, name: InvName, public: Wires["Vdd", "Gnd", "I", "X"]]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "I"]; Ports.InitPorts[ct, l, drive, "X"]; }; InvInit: Rosemary.InitProc = { state: IXRef _ IF oldStateAny=NIL THEN NEW[IXRec] ELSE NARROW[oldStateAny]; [state.in, state.out] _ Ports.PortIndexes[cellType.public, "I", "X"]; stateAny _ state}; InvSimple: Rosemary.EvalProc = { state: IXRef _ NARROW[stateAny]; p[state.out].l _ SELECT p[state.in].l FROM L => H, H => L, ENDCASE => X; }; BufferName: ROPE = Rosemary.Register[roseClassName: "Buffer", init: InvInit, evalSimple: InvSimple]; Buffer: PUBLIC PROC[d: NAT] RETURNS [ct: CellType] = { buffer2: CellType _ LogicUtils.MakeSC[nameInLib: "invBuffer", width: 3, name: BufferName, public: Wires["Vdd", "Gnd", "I", "X"]]; ct _ SequenceCell[name: BufferName, baseCell: buffer2, count: MAX[d/2, 1]]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "I"]; Ports.InitPorts[ct, l, drive, "X"]; }; TstRef: TYPE = REF TstRec; TstRec: TYPE = RECORD [in, out, en, nEn: NAT _ LAST[NAT]]; TstInit: Rosemary.InitProc = { state: TstRef _ IF oldStateAny=NIL THEN NEW[TstRec] ELSE NARROW[oldStateAny]; [state.in, state.out, state.en, state.nEn] _ Ports.PortIndexes[cellType.public, "I", "X", "EN", "NEN"]; stateAny _ state; }; TstDriverName: ROPE = Rosemary.Register[roseClassName: "TstDriver", init: TstInit, evalSimple: TstDriverSimple]; TstDriver: PUBLIC PROC RETURNS [ct: CellType] = { ct _ LogicUtils.MakeSC[nameInLib: "tstDriver", width: 4, name: TstDriverName, public: Wires["Vdd", "Gnd", "I", "X", "EN", "NEN"]]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "I", "EN", "NEN", "X"]; }; TstDriverSimple: Rosemary.EvalProc = { -- by Pradeep state: TstRef _ NARROW[stateAny]; {OPEN state; IF p[en].l#L AND p[in].l#L THEN { -- N-Section of TstDriver p[out].d _ drive; IF p[en].l=H AND p[in].l=H THEN p[out].l _ L ELSE p[out].l _ X; RETURN; }; IF p[nEn].l#H AND p[in].l#H THEN { -- P-Section of TstDriver p[out].d _ drive; IF p[nEn].l=L AND p[in].l=L THEN p[out].l _ H ELSE p[out].l _ X; RETURN; }; p[out].d _ none; }}; TristateI: PUBLIC PROC RETURNS [ct: CellType] ~ {ct _ LogicUtils.Extract["3BufferI.icon", TRUE]}; TristateNI: PUBLIC PROC RETURNS [ct: CellType] ~ {ct _ LogicUtils.Extract["3BufferNI.icon", TRUE]}; B4: TYPE = {and, nand, or, nor}; nameInLib: ARRAY B4 OF ROPE = ["and", "nand", "or", "nor"]; nameOfCT: ARRAY B4 OF ROPE = ["And", "Nand", "Or", "Nor"]; rootCT: ARRAY B4 OF B4 = [nor, nand, nand, nor]; leafCT: ARRAY B4 OF B4 = [nand, and, nor, or]; InternalB4: PROC [b4: B4, n: NAT] RETURNS [ct: CellType] = { scPublic: Wire _ SELECT n FROM 2 => Wires["Vdd", "Gnd", "I-A", "I-B", "X"], 3 => Wires["Vdd", "Gnd", "I-A", "I-B", "I-C", "X"], 4 => Wires["Vdd", "Gnd", "I-A", "I-B", "I-C", "I-D", "X"], ENDCASE => ERROR; nameLib: ROPE _ IO.PutFR["%g%g", IO.rope[nameInLib[b4]], IO.int[n]]; nameCT: ROPE _ IO.PutFR["%g%g", IO.rope[nameOfCT[b4]], IO.int[n]]; sc: CellType _ LogicUtils.MakeSC[ nameInLib: nameLib, name: nameCT, width: n+1+(IF b4=and OR b4=or THEN 1 ELSE 0), public: scPublic]; pas: LIST OF PA _ LIST[["I-A", "I[0]"], ["I-B", "I[1]"]]; IF n>2 THEN pas _ CONS[["I-C", "I[2]"], pas]; IF n>3 THEN pas _ CONS[["I-D", "I[3]"], pas]; ct _ Cell[name: IO.PutFR["Normalized%g", IO.rope[nameCT]], public: Wires["Vdd", "Gnd", Seq["I", n], "X"], instances: LIST[InstanceList[sc, pas]]]; }; B4Large: PROC [b4: B4, n: NAT] RETURNS [ct: CellType] ~ { input: Wire = Seq["I", n]; n1: NAT _ n/2; root, c1, c2: CellInstance; SELECT n FROM 0, 1 => LogicUtils.Error["@@@ This should never happen, call implementor @@@"]; 2, 3, 4 => RETURN[InternalB4[b4, n]]; ENDCASE => NULL; -- for n>4, see further root _ Instance[InternalB4[rootCT[b4], 2], ["I", Wires["One", "Two"]]]; c1 _ Instance[B4Large[leafCT[b4], n1], ["X", "One"], ["I", Range[input, 0, n1]]]; c2 _ Instance[B4Large[leafCT[b4], n-n1], ["X", "Two"], ["I", Range[input, n1, n-n1]]]; ct _ Cell[name: IO.PutFR["%g%g", IO.rope[nameOfCT[b4]], IO.int[n]], public: Wires["Vdd", "Gnd", input, "X"], onlyInternal: Wires["One", "Two"], instances: LIST[root, c1, c2]]; }; AndName: ROPE = Rosemary.Register[roseClassName: "And", init: IXInit, evalSimple: AndSimple]; And: PUBLIC PROC[n: NAT] RETURNS [ct: CellType] = { IF n=0 THEN LogicUtils.Error["Please specify the number of inputs of the `and' gate"]; IF n=1 THEN LogicUtils.Error["What the hell is a 1-input `and' gate???"]; ct _ B4Large[and, n]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: AndName]; [] _ CoreFlat.CellTypeCutLabels[ct, logicCutSet]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd"]; Ports.InitPorts[ct, ls, none, "I"]; Ports.InitPorts[ct, l, drive, "X"]; }; AndSimple: Rosemary.EvalProc = { state: IXRef _ NARROW[stateAny]; allHigh: BOOL _ TRUE; FOR i: NAT IN [0..p[state.in].ls.size) DO IF p[state.in].ls[i]=L THEN {p[state.out].l _ L; RETURN}; allHigh _ allHigh AND p[state.in].ls[i]=H; ENDLOOP; p[state.out].l _ SELECT TRUE FROM allHigh => H, ENDCASE => X; }; NandName: ROPE = Rosemary.Register[roseClassName: "Nand", init: IXInit, evalSimple: NandSimple]; Nand: PUBLIC PROC[n: NAT] RETURNS [ct: CellType] = { IF n=0 THEN LogicUtils.Error["Please specify the number of inputs of the `nand' gate"]; IF n=1 THEN LogicUtils.Error["What the hell is a 1-input `nand' gate???"]; ct _ B4Large[nand, n]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: NandName]; [] _ CoreFlat.CellTypeCutLabels[ct, logicCutSet]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd"]; Ports.InitPorts[ct, ls, none, "I"]; Ports.InitPorts[ct, l, drive, "X"]; }; NandSimple: Rosemary.EvalProc = { state: IXRef _ NARROW[stateAny]; allHigh: BOOL _ TRUE; FOR i: NAT IN [0..p[state.in].ls.size) DO IF p[state.in].ls[i]=L THEN {p[state.out].l _ H; RETURN}; allHigh _ allHigh AND p[state.in].ls[i]=H; ENDLOOP; p[state.out].l _ SELECT TRUE FROM allHigh => L, ENDCASE => X; }; OrName: ROPE = Rosemary.Register[roseClassName: "Or", init: IXInit, evalSimple: OrSimple]; Or: PUBLIC PROC[n: NAT] RETURNS [ct: CellType] = { IF n=0 THEN LogicUtils.Error["Please specify the number of inputs of the `or' gate"]; IF n=1 THEN LogicUtils.Error["What the hell is a 1-input `or' gate???"]; ct _ B4Large[or, n]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: OrName]; [] _ CoreFlat.CellTypeCutLabels[ct, logicCutSet]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd"]; Ports.InitPorts[ct, ls, none, "I"]; Ports.InitPorts[ct, l, drive, "X"]; }; OrSimple: Rosemary.EvalProc = { state: IXRef _ NARROW[stateAny]; allLow: BOOL _ TRUE; FOR i: NAT IN [0..p[state.in].ls.size) DO IF p[state.in].ls[i]=H THEN {p[state.out].l _ H; RETURN}; allLow _ allLow AND p[state.in].ls[i]=L; ENDLOOP; p[state.out].l _ SELECT TRUE FROM allLow => L, ENDCASE => X; }; NorName: ROPE = Rosemary.Register[roseClassName: "Nor", init: IXInit, evalSimple: NorSimple]; Nor: PUBLIC PROC[n: NAT] RETURNS [ct: CellType] = { IF n=0 THEN LogicUtils.Error["Please specify the number of inputs of the `nor' gate"]; IF n=1 THEN LogicUtils.Error["What the hell is a 1-input `nor' gate???"]; ct _ B4Large[nor, n]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: NorName]; [] _ CoreFlat.CellTypeCutLabels[ct, logicCutSet]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd"]; Ports.InitPorts[ct, ls, none, "I"]; Ports.InitPorts[ct, l, drive, "X"]; }; NorSimple: Rosemary.EvalProc = { state: IXRef _ NARROW[stateAny]; allLow: BOOL _ TRUE; FOR i: NAT IN [0..p[state.in].ls.size) DO IF p[state.in].ls[i]=H THEN {p[state.out].l _ L; RETURN}; allLow _ allLow AND p[state.in].ls[i]=L; ENDLOOP; p[state.out].l _ SELECT TRUE FROM allLow => H, ENDCASE => X; }; Xor2Name: ROPE = Rosemary.Register[roseClassName: "Xor2", init: I2XInit, evalSimple: Xor2Simple]; Xnor2Name: ROPE = Rosemary.Register[roseClassName: "Xnor2", init: I2XInit, evalSimple: Xnor2Simple]; Xor2: PUBLIC PROC RETURNS [ct: CellType] = { ct _ LogicUtils.MakeSC[nameInLib: "xor2", name: Xor2Name, width: 6, public: Wires["Vdd", "Gnd", "I-A", "I-B", "X"]]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "I-A", "I-B"]; Ports.InitPorts[ct, l, drive, "X"]; }; Xor2Simple: Rosemary.EvalProc = { state: I4XRef _ NARROW[stateAny]; p[state.out].l _ SELECT TRUE FROM p[state.in0].l=X OR p[state.in1].l=X => X, p[state.in0].l=p[state.in1].l => L, ENDCASE => H; }; Xnor2: PUBLIC PROC RETURNS [ct: CellType] = { ct _ LogicUtils.MakeSC[nameInLib: "xnor2", name: Xnor2Name, width: 6, public: Wires["Vdd", "Gnd", "I-A", "I-B", "X"]]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "I-A", "I-B"]; Ports.InitPorts[ct, l, drive, "X"]; }; Xnor2Simple: Rosemary.EvalProc = { state: I4XRef _ NARROW[stateAny]; p[state.out].l _ SELECT TRUE FROM p[state.in0].l=X OR p[state.in1].l=X => X, p[state.in0].l=p[state.in1].l => H, ENDCASE => L; }; A22o2iName: ROPE = Rosemary.Register[roseClassName: "A22o2i", init: CG4Init, evalSimple: A22o2iSimple]; A21o2iName: ROPE = Rosemary.Register[roseClassName: "A21o2i", init: CG3Init, evalSimple: A21o2iSimple]; O22a2iName: ROPE = Rosemary.Register[roseClassName: "O22a2i", init: CG4Init, evalSimple: O22a2iSimple]; CG4Init: Rosemary.InitProc = { state: I4XRef _ IF oldStateAny=NIL THEN NEW[I4XRec] ELSE NARROW[oldStateAny]; [state.in0, state.in1, state.in2, state.in3, state.out] _ Ports.PortIndexes[cellType.public, "A", "B", "C", "D", "X"]; stateAny _ state; }; CG3Init: Rosemary.InitProc = { state: I4XRef _ IF oldStateAny=NIL THEN NEW[I4XRec] ELSE NARROW[oldStateAny]; [state.in0, state.in1, state.in2, state.out] _ Ports.PortIndexes[cellType.public, "A", "B", "C", "X"]; stateAny _ state; }; A22o2i: PUBLIC PROC[] RETURNS [ct: CellType] = { ct _ LogicUtils.MakeSC[nameInLib: "a22o2i", width: 5, name: A22o2iName, public: Wires["Vdd", "Gnd", "A", "B", "C", "D", "X"]]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "A", "B", "C", "D"]; Ports.InitPorts[ct, l, drive, "X"]; }; A22o2iSimple: Rosemary.EvalProc = { state: I4XRef _ NARROW[stateAny]; p[state.out].l _ SELECT TRUE FROM (p[state.in0].l=H AND p[state.in1].l=H) OR (p[state.in2].l=H AND p[state.in3].l=H) => L, (p[state.in0].l=L OR p[state.in1].l=L) AND (p[state.in2].l=L OR p[state.in3].l=L) => H, ENDCASE => X; }; A21o2i: PUBLIC PROC[] RETURNS [ct: CellType] = { ct _ LogicUtils.MakeSC[nameInLib: "a21o2i", width: 4, name: A21o2iName, public: Wires["Vdd", "Gnd", "A", "B", "C", "X"]]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "A", "B", "C"]; Ports.InitPorts[ct, l, drive, "X"]; }; A21o2iSimple: Rosemary.EvalProc = { state: I4XRef _ NARROW[stateAny]; p[state.out].l _ SELECT TRUE FROM (p[state.in0].l=H AND p[state.in1].l=H) OR p[state.in2].l=H => L, (p[state.in0].l=L OR p[state.in1].l=L) AND p[state.in2].l=L => H, ENDCASE => X; }; O22a2i: PUBLIC PROC[] RETURNS [ct: CellType] = { ct _ LogicUtils.MakeSC[nameInLib: "o22a2i", width: 5, name: O22a2iName, public: Wires["Vdd", "Gnd", "A", "B", "C", "D", "X"]]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "A", "B", "C", "D"]; Ports.InitPorts[ct, l, drive, "X"]; }; O22a2iSimple: Rosemary.EvalProc = { state: I4XRef _ NARROW[stateAny]; p[state.out].l _ SELECT TRUE FROM (p[state.in0].l=H OR p[state.in1].l=H) AND (p[state.in2].l=H OR p[state.in3].l=H) => L, (p[state.in0].l=L AND p[state.in1].l=L) OR (p[state.in2].l=L AND p[state.in3].l=L) => H, ENDCASE => X; }; FFName: ROPE = Rosemary.Register[roseClassName: "FF", init: FFInit, evalSimple: FFSimple]; FlipFlop: PUBLIC PROC RETURNS [ct: CellType] = { ct _ LogicUtils.MakeSC[nameInLib: "ff", width: 10, name: FFName, public: Wires["Vdd", "Gnd", "D", "Q", "NQ", "CK"]]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "D", "CK"]; Ports.InitPorts[ct, l, drive, "Q", "NQ"]; }; FFRef: TYPE = REF FFRec; FFRec: TYPE = RECORD [ ffD, ffQ, ffNQ, ffClock: NAT _ LAST[NAT], master, slave: Ports.Level]; FFInit: Rosemary.InitProc = { state: FFRef _ IF oldStateAny=NIL THEN NEW[FFRec] ELSE NARROW[oldStateAny]; state.master _ state.slave _ X; [state.ffD, state.ffQ, state.ffNQ, state.ffClock] _ Ports.PortIndexes[cellType.public, "D", "Q", "NQ", "CK"]; p[state.ffQ].l _ p[state.ffNQ].l _ X; stateAny _ state; }; FFSimple: Rosemary.EvalProc = { state: FFRef _ NARROW[stateAny]; SELECT p[state.ffClock].l FROM L => state.master _ p[state.ffD].l; H => state.slave _ state.master; ENDCASE => { IF state.slave#state.master THEN state.slave _ X; IF state.master#p[state.ffD].l THEN state.master _ X; }; p[state.ffQ].l _ state.slave; p[state.ffNQ].l _ Ports.NotL[state.slave]; }; FFenName: ROPE = Rosemary.Register[roseClassName: "FFen", init: FFenInit, evalSimple: FFenSimple]; FlipFlopEnable: PUBLIC PROC RETURNS [ct: CellType] = { ct _ LogicUtils.MakeSC[nameInLib: "ffEn", width: 14, name: FFenName, public: Wires["Vdd", "Gnd", "D", "Q", "NQ", "CK", "en", "nEn"]]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "D", "CK", "en", "nEn"]; Ports.InitPorts[ct, l, drive, "Q", "NQ"]; }; FFenRef: TYPE = REF FFenRec; FFenRec: TYPE = RECORD [ ffD, ffQ, ffNQ, ffClock, ffen, ffnEn: NAT _ LAST[NAT], master, slave: Ports.Level]; FFenInit: Rosemary.InitProc = { state: FFenRef _ IF oldStateAny=NIL THEN NEW[FFenRec] ELSE NARROW[oldStateAny]; state.master _ state.slave _ X; [state.ffD, state.ffQ, state.ffNQ, state.ffClock, state.ffen, state.ffnEn, ] _ Ports.PortIndexes[cellType.public, "D", "Q", "NQ", "CK", "en", "nEn"]; p[state.ffQ].l _ p[state.ffNQ].l _ X; stateAny _ state; }; FFenSimple: Rosemary.EvalProc = { state: FFenRef _ NARROW[stateAny]; SELECT p[state.ffClock].l FROM L => { state.master _ SELECT TRUE FROM p[state.ffen].l=H AND p[state.ffnEn].l=L => p[state.ffD].l, p[state.ffen].l=L AND p[state.ffnEn].l=H => state.slave, ENDCASE => X; }; H => state.slave _ state.master; ENDCASE => { IF state.slave#state.master THEN state.slave _ X; IF state.master#p[state.ffD].l THEN state.master _ X; }; p[state.ffQ].l _ state.slave; p[state.ffNQ].l _ Ports.NotL[state.slave]; }; RSName: ROPE = Rosemary.Register[roseClassName: "RS", init: RSInit, evalSimple: RSSimple]; RS: PUBLIC PROC RETURNS [ct: CellType] = { ct _ CoreClasses.CreateUnspecified[name: RSName, public: Wires["Vdd", "Gnd", "R", "S", "Q", "nQ"]]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "R", "S"]; Ports.InitPorts[ct, l, drive, "Q", "NQ"]; }; RSRef: TYPE = REF RSRec; RSRec: TYPE = RECORD [ r, s, q, nq: NAT _ LAST[NAT], bit: Ports.Level]; -- a copy of Q RSInit: Rosemary.InitProc = { state: RSRef _ IF oldStateAny=NIL THEN NEW[RSRec] ELSE NARROW[oldStateAny]; state.bit _ X; [state.r, state.s, state.q, state.nq] _ Ports.PortIndexes[cellType.public, "R", "S", "Q", "nQ"]; p[state.q].l _ p[state.nq].l _ X; stateAny _ state; }; RSSimple: Rosemary.EvalProc = { state: RSRef _ NARROW[stateAny]; SELECT TRUE FROM p[state.r].l=H => { state.bit _ p[state.q].l _ L; p[state.nq].l _ Ports.NotL[p[state.s].l]; }; p[state.r].l=L AND p[state.s].l=H => { state.bit _ p[state.q].l _ H; p[state.nq].l _ L; }; p[state.r].l=L AND p[state.s].l=L => { p[state.q].l _ state.bit; p[state.nq].l _ Ports.NotL[state.bit]; }; ENDCASE => state.bit _ p[state.q].l _ p[state.nq].l _ X; }; FF2: PUBLIC PROC RETURNS [ct: CellType] = {ct _ LogicUtils.Extract["ff2.sch", TRUE]}; FF4: PUBLIC PROC RETURNS [ct: CellType] = {ct _ LogicUtils.Extract["ff4.sch", TRUE]}; StorageName: ROPE = Rosemary.Register[roseClassName: "Storage", init: StorageInit, evalSimple: StorageSimple]; Storage: PUBLIC PROC RETURNS [ct: CellType] = { ct _ CoreClasses.CreateUnspecified[name: StorageName, public: Wires["Vdd", "Gnd", "bit", "nbit"]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: StorageName]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "bit", "nbit"]; [] _ CoreFlat.CellTypeCutLabels[ct, macroCutSet]; }; StorageRef: TYPE = REF StorageRec; StorageRec: TYPE = RECORD [bit, nBit: NAT _ LAST[NAT]]; StorageInit: Rosemary.InitProc = { state: StorageRef _ NEW[StorageRec]; {OPEN state; [bit, nBit] _ Ports.PortIndexes[cellType.public, "bit", "nbit"]; p[bit].l _ X; p[bit].d _ driveWeak; p[nBit].l _ X; p[nBit].d _ driveWeak}; stateAny _ state}; StorageSimple: Rosemary.EvalProc = {NULL}; -- cf. Pradeep DLName: ROPE = Rosemary.Register[roseClassName: "DL", init: DLInit, evalSimple: DLSimple]; DLatch: PUBLIC PROC RETURNS [ct: CellType] = { ct _ LogicUtils.MakeSC[nameInLib: "dLatch", width: 9, name: DLName, public: Wires["Vdd", "Gnd", "D", "Q", "S"]]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "D", "S"]; Ports.InitPorts[ct, l, drive, "Q"]; }; DLRef: TYPE = REF DLRec; DLRec: TYPE = RECORD [ dlD, dlQ, dlS: NAT _ LAST[NAT], mem: Ports.Level]; DLInit: Rosemary.InitProc = { state: DLRef _ IF oldStateAny=NIL THEN NEW[DLRec] ELSE NARROW[oldStateAny]; state.mem _ X; [state.dlD, state.dlQ, state.dlS] _ Ports.PortIndexes[cellType.public, "D", "Q", "S"]; p[state.dlQ].l _ X; stateAny _ state; }; DLSimple: Rosemary.EvalProc = { state: DLRef _ NARROW[stateAny]; IF p[state.dlS].l=H THEN state.mem _ p[state.dlD].l ELSE IF p[state.dlS].l=X THEN IF p[state.dlD].l#state.mem THEN state.mem _ X; p[state.dlQ].l _ state.mem; }; END. jLogicSimpleImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Last Edited by: Louis Monier January 14, 1987 7:32:56 pm PST Christian LeCocq October 17, 1986 6:05:34 pm PDT Barth, October 10, 1986 5:38:40 pm PDT Alfred Permuy September 11, 1986 10:19:56 pm PDT Pradeep Sindhu September 11, 1986 11:38:39 pm PDT This package contains all basic cells present in the library (nand2, flip-flop, ...) and very simple macros: n-inputs and gates, buffer of arbitrary size, ... -- Corresponding to very common types of publics Inverter(s) -- A buffer of drive d is equivalent to d inverters connected in parallel Tristate Driver Common to the And, Nand, Or, Nor -- and -> nor2(nand) -- nand -> nand2(and) -- or -> nand2(nor) -- nor -> nor2(or) And Nand Or Nor Xor and Xnor Complex gates Edge-Triggered Flip-Flop (one input, one clock, complementary outputs) -- of course state.master is the inverse of the physical master level in the current CMosB implementation, but nobody has access to the real value, so let's keep things simple... Edge-Triggered Flip-Flop (with data enable) -- of course state.master is the inverse of the physical master level in the current CMosB implementation, but nobody has access to the real value, so let's keep things simple... RS Flip-Flop (not a SC) Edge-Triggered Flip-Flops (2 and 4 inputs) Storage (not a SC) Latch (1 input) ΚL– "cedar" style˜codešœ™Kšœ Οmœ1™žœ ˜KKšœ0˜0Kšœ#˜#Kšœ˜——šŸ™Kšœžœžœ˜Kš œžœžœžœžœžœ˜:šŸœ˜Kš œžœ žœžœžœ žœžœ˜MKšœg˜gKšœ˜Kšœ˜—K˜KšŸ œžœ]˜pšŸ œžœžœžœ˜1šœ8˜8KšœI˜I—KšœB˜BKšœ˜K˜—šŸœΟc ˜5Kšœžœ ˜!Kšœžœ˜ šžœ žœ žœ‘˜˜IKšœ˜KšœA˜AKšœ1˜1Kšœ+˜+Kšœ#˜#Kšœ#˜#Kšœ˜—šŸ œ˜ Kšœžœ ˜ Kšœ žœžœ˜šžœžœžœž˜)Kšžœžœžœ˜9Kšœžœ˜*Kšžœ˜—šœžœžœž˜!Kšœ ˜ Kšžœ˜ —Kšœ˜——™KšŸœžœR˜`š Ÿœžœžœžœžœ˜4KšžœžœL˜WKšžœžœ?˜JKšœ˜KšœB˜BKšœ1˜1Kšœ+˜+Kšœ#˜#Kšœ#˜#Kšœ˜—šŸ œ˜!Kšœžœ ˜ Kšœ žœžœ˜šžœžœžœž˜)Kšžœžœžœ˜9Kšœžœ˜*Kšžœ˜—šœžœžœž˜!Kšœ ˜ Kšžœ˜ —Kšœ˜——™KšŸœžœN˜Zš Ÿœžœžœžœžœ˜2KšžœžœJ˜UKšžœžœ=˜HKšœ˜Kšœ@˜@Kšœ1˜1Kšœ+˜+Kšœ#˜#Kšœ#˜#Kšœ˜—šŸœ˜Kšœžœ ˜ Kšœžœžœ˜šžœžœžœž˜)Kšžœžœžœ˜9Kšœžœ˜(Kšžœ˜—šœžœžœž˜!Kšœ ˜ Kšžœ˜ —Kšœ˜——™KšŸœžœP˜]š Ÿœžœžœžœžœ˜3KšžœžœK˜VKšžœžœ>˜IKšœ˜KšœA˜AKšœ1˜1Kšœ+˜+Kšœ#˜#Kšœ#˜#Kšœ˜—šŸ œ˜ Kšœžœ ˜ Kšœžœžœ˜šžœžœžœž˜)Kšžœžœžœ˜9Kšœžœ˜(Kšžœ˜—šœžœžœž˜!Kšœ ˜ Kšžœ˜ —Kšœ˜——™ KšŸœžœS˜aKšŸ œžœU˜dK˜šŸœžœžœžœ˜,šœD˜DKšœ0˜0—Kšœ9˜9Kšœ#˜#Kšœ˜—K˜šŸ œ˜!Kšœžœ ˜!šœžœžœž˜!Kšœžœ˜*Kšœ#˜#Kšžœ˜ —Kšœ˜K˜—šŸœžœžœžœ˜-šœF˜FKšœ0˜0—Kšœ9˜9Kšœ#˜#Kšœ˜K˜—šŸ œ˜"Kšœžœ ˜!šœžœžœž˜!Kšœžœ˜*Kšœ#˜#Kšžœ˜ —Kšœ˜——™ KšŸ œžœW˜gKšŸ œžœW˜gKšŸ œžœW˜gK˜šŸœ˜Kš œžœ žœžœžœ žœžœ˜MKšœv˜vKšœ˜Kšœ˜—šŸœ˜Kš œžœ žœžœžœ žœžœ˜MKšœf˜fKšœ˜Kšœ˜—K˜šŸœžœžœžœ˜0šœ6˜6KšœH˜H—Kšœ?˜?Kšœ#˜#Kšœ˜—šŸ œ˜#Kšœžœ ˜!šœžœžœž˜!Kšœžœžœžœ˜XKšœžœžœžœ˜WKšžœ˜ —Kšœ˜—K˜šŸœžœžœžœ˜0šœ6˜6KšœC˜C—Kšœ:˜:Kšœ#˜#Kšœ˜—šŸ œ˜#Kšœžœ ˜!šœžœžœž˜!Kšœžœžœ˜AKšœžœžœ˜AKšžœ˜ —Kšœ˜K˜—šŸœžœžœžœ˜0šœ6˜6KšœH˜H—Kšœ?˜?Kšœ#˜#Kšœ˜—šŸ œ˜#Kšœžœ ˜!šœžœžœž˜!Kšœžœžœžœ˜WKšœžœžœžœ˜XKšžœ˜ —Kšœ˜——™FKšŸœžœN˜ZšŸœžœžœžœ˜0šœ3˜3KšœA˜A—Kšœ6˜6Kšœ)˜)Kšœ˜K˜—Kšœžœžœ˜šœžœžœ˜Kšœžœžœžœ˜)Kšœ˜—K˜šŸœ˜Kš œžœ žœžœžœžœžœ˜KKšœ˜Kšœm˜mKšœ%˜%Kšœ˜Kšœ˜K˜—šŸœ˜Kšœ²™²Kšœžœ ˜ šžœž˜Kšœ#˜#Kšœ ˜ šžœ˜ Kšžœžœ˜1Kšžœžœ˜5K˜——KšœI˜IKšœ˜——™+KšŸœžœT˜bšŸœžœžœžœ˜6šœ5˜5KšœP˜P—KšœC˜CKšœ)˜)Kšœ˜K˜—Kšœ žœžœ ˜šœ žœžœ˜Kšœ&žœžœžœ˜6Kšœ˜—K˜šŸœ˜Kš œžœ žœžœžœ žœžœ˜OKšœ˜Kšœ•˜•Kšœ%˜%Kšœ˜Kšœ˜K˜—šŸ œ˜!Kšœ²™²Kšœžœ ˜"šžœž˜šœ˜šœžœžœž˜Kšœžœ&˜;Kšœžœ#˜8Kšžœ˜ —Kšœ˜—Kšœ ˜ šžœ˜ Kšžœžœ˜1Kšžœžœ˜5K˜——KšœI˜IKšœ˜——™KšŸœžœN˜ZšŸœžœžœžœ˜*šœ1˜1Kšœ2˜2—Kšœ5˜5Kšœ)˜)Kšœ˜K˜—Kšœžœžœ˜šœžœžœ˜Kšœ žœžœžœ˜Kšœ‘˜!—K˜šŸœ˜Kš œžœ žœžœžœžœžœ˜KKšœ˜Kšœ`˜`Kšœ!˜!Kšœ˜Kšœ˜K˜—šŸœ˜Kšœžœ ˜ šžœžœž˜šœ˜Kšœ˜Kšœ)˜)K˜—šœžœ˜&Kšœ˜Kšœ˜K˜—šœžœ˜&Kšœ˜Kšœ&˜&K˜—Kšžœ1˜8—Kšœ˜——™*Kš Ÿœžœžœžœ6žœ˜UKš Ÿœžœžœžœ6žœ˜U—šŸ™KšŸ œžœ]˜nšŸœžœžœžœ˜/šœ6˜6Kšœ,˜,—KšœE˜EKšœ:˜:Kšœ1˜1Kšœ˜K˜—Kšœ žœžœ ˜"Kš œ žœžœ žœžœžœ˜7šŸ œ˜"Kšœžœ ˜$šœžœ˜ Kšœ@˜@Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜—Kšœ˜K˜—KšŸ œžœ‘˜9—™KšŸœžœN˜ZšŸœžœžœžœ˜.šœ6˜6Kšœ:˜:—Kšœ5˜5Kšœ#˜#Kšœ˜K˜—Kšœžœžœ˜šœžœžœ˜Kšœžœžœžœ˜Kšœ˜—K˜šŸœ˜Kš œžœ žœžœžœžœžœ˜KKšœ˜KšœV˜VKšœ˜Kšœ˜Kšœ˜K˜—šŸœ˜Kšœžœ ˜ š žœžœžœžœžœ˜RKšžœžœ˜/—Kšœ˜Kšœ˜——Kšžœ˜K˜—…—E~_4