DIRECTORY BitOps, CoreClasses, CoreCreate, CoreFlat, CoreOps, CoreProperties, Logic, LogicUtils, Ports, Rosemary, Static; LogicArithImpl: CEDAR PROGRAM IMPORTS BitOps, CoreCreate, CoreFlat, CoreOps, CoreProperties, Logic, LogicUtils, Ports, Rosemary, Static EXPORTS Logic = BEGIN OPEN Logic, CoreCreate; AdderName: ROPE = Rosemary.Register[roseClassName: "Adder", init: AdderInit, evalSimple: AdderSimple]; Adder: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { oneBitAdder: CellType _ LogicUtils.Extract["oneBitAdder.sch", TRUE]; -- designed by Alfred insts: CellInstances _ LIST[Instance[oneBitAdder, ["A", "A[0]"], ["B", "B[0]"], ["Sum", "Sum[0]"], ["Cout", "carryOut"], ["C", "carry[0]"]]]; IF b=0 THEN LogicUtils.Error["Please specify a number of bits for the adder"]; IF b=1 THEN RETURN[ Cell[name: AdderName, public: Wires["Vdd", "Gnd", "carryIn", "A", "B", "Sum", "carryOut"], instances: LIST[Instance[oneBitAdder, ["A", "A"], ["B", "B"], ["C", "carryIn"], ["Sum", "Sum"], ["Cout", "carryOut"]]]]]; FOR i: NAT IN [1..b-1) DO insts _ CONS[ Instance[oneBitAdder, ["A", Index["A", i]], ["B", Index["B", i]], ["Sum", Index["Sum", i]], ["Cout", Index["carry", i-1]], ["C", Index["carry", i]]], insts]; ENDLOOP; insts _ CONS[ Instance[oneBitAdder, ["A", Index["A", b-1]], ["B", Index["B", b-1]], ["Sum", Index["Sum", b-1]], ["Cout", Index["carry", b-2]], ["C", "carryIn"]], insts]; ct _ Cell[ name: AdderName, public: Wires["Vdd", "Gnd", "carryIn", Seq["A", b], Seq["B", b], Seq["Sum", b], "carryOut"], onlyInternal: Wires[Seq["carry", b-1]], instances: insts]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: AdderName]; [] _ CoreFlat.CellTypeCutLabels[ct, macroCutSet]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "carryIn"]; Ports.InitPorts[ct, l, drive, "carryOut"]; Ports.InitPorts[ct, ls, none, "A", "B"]; Ports.InitPorts[ct, ls, drive, "Sum"]; }; AdderState: TYPE = REF AdderStateRec; AdderStateRec: TYPE = RECORD [ inA, inB, sum, carryIn, carryOut: NAT _ LAST[NAT]]; AdderInit: Rosemary.InitProc = { state: AdderState _ IF oldStateAny=NIL THEN NEW[AdderStateRec] ELSE NARROW[oldStateAny]; [state.inA, state.inB, state.sum, state.carryIn, state.carryOut] _ Ports.PortIndexes[cellType.public, "A", "B", "Sum", "carryIn", "carryOut"]; stateAny _ state}; AdderSimple: Rosemary.EvalProc = { state: AdderState _ NARROW[stateAny]; carry: Ports.Level _ p[state.carryIn].l; FOR i: NAT DECREASING IN [0..p[state.sum].ls.size) DO [carry, p[state.sum].ls[i]] _ SumL[p[state.inA].ls[i], p[state.inB].ls[i], carry]; ENDLOOP; p[state.carryOut].l _ carry; }; ConstantName: ROPE = "Constant"; Constant: PUBLIC PROC [b: NAT, v: INT] RETURNS [ct: CellType] = { vCard: CARD = LOOPHOLE[v]; gnd: Wire _ Static.UnconnectedOK[CoreOps.CreateWire[name: "Gnd"]]; vdd: Wire _ Static.UnconnectedOK[CoreOps.CreateWire[name: "Vdd"]]; output: Wire _ Static.UnconnectedOK[CoreOps.CreateWires[size: b, name: "Output"]]; SELECT b FROM <=32 => FOR i: NAT IN [0..b) DO output[i] _ IF BitOps.EBFD[vCard, i, b] THEN vdd ELSE gnd; ENDLOOP; >32 => {sign: Wire _ IF v<0 THEN vdd ELSE gnd; FOR i: NAT IN [0..b-32) DO output[i] _ sign; ENDLOOP; FOR i: NAT IN [b-32..b) DO output[i] _ IF BitOps.EBFD[vCard, i-b+32, 32] THEN vdd ELSE gnd; ENDLOOP; }; ENDCASE => ERROR; ct _ Cell[name: ConstantName, public: Wires[gnd, vdd, output], instances: NIL]; }; ComparatorName: ROPE = Rosemary.Register[roseClassName: "Comparator", init: ComparatorInit, evalSimple: ComparatorSimple]; Comparator: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { xnorSeq: CellType; insts: CellInstances; IF b=0 THEN LogicUtils.Error["Please specify a number of bits for the comparator"]; xnorSeq _ SequenceCell[name: "XnorSequence", baseCell: Xnor2[], count: b, sequencePorts: Wires["I-A", "I-B", "X"]]; insts _ LIST[ Instance[xnorSeq, ["I-A", "A"], ["I-B", "B"], ["X", "Output"]], Instance[And[b], ["I", "Output"], ["X", "AEqB"]] ]; ct _ Cell[ name: ComparatorName, public: Wires["Vdd", "Gnd", Seq["A", b], Seq["B", b], "AEqB"], onlyInternal: Wires[Seq["Output", b]], instances: insts]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: ComparatorName]; [] _ CoreFlat.CellTypeCutLabels[ct, macroCutSet]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd"]; Ports.InitPorts[ct, ls, none, "A", "B"]; Ports.InitPorts[ct, l, drive, "AEqB"]; }; ComparatorState: TYPE = REF ComparatorStateRec; ComparatorStateRec: TYPE = RECORD [a, b, eq: NAT _ LAST[NAT]]; ComparatorInit: Rosemary.InitProc = { state: ComparatorState _ IF oldStateAny=NIL THEN NEW[ComparatorStateRec] ELSE NARROW[oldStateAny]; [state.a, state.b, state.eq] _ Ports.PortIndexes[cellType.public, "A", "B", "AEqB"]; stateAny _ state}; ComparatorSimple: Rosemary.EvalProc = { state: ComparatorState _ NARROW[stateAny]; p[state.eq].l _ LSEqual[p[state.a].ls, p[state.b].ls]; }; EqConstantName: ROPE = Rosemary.Register[roseClassName: "EqConstant", init: EqConstantInit, evalSimple: EqConstantSimple]; EqConstant: PUBLIC PROC [b: NAT, v: INT] RETURNS [ct: CellType] = { vCard: CARD = LOOPHOLE[v]; insts: CellInstances _ NIL; internals: LIST OF WR _ NIL; pas: LIST OF PA _ LIST[["X", "out"]]; -- output of the nor in: Wire _ Seq["In", b]; inv: CellType _ Inv[]; nor: CellType _ Nor[b]; norInput: Wire _ FindWire[nor.public, "I"]; IF b=0 THEN LogicUtils.Error["Please specify a number of bits for the comparator to a constant"]; FOR i: NAT IN [0..b) DO IF BitOps.EBFD[vCard, i, b] THEN { -- add inverter newWire: Wire _ Wires[]; internals _ CONS[newWire, internals]; insts _ CONS[Instance[inv, ["I", in[i]], ["X", newWire]], insts]; pas _ CONS[[norInput[i], newWire], pas]; } ELSE {pas _ CONS[[norInput[i], in[i]], pas]}; ENDLOOP; insts _ CONS[InstanceList[nor, pas], insts]; ct _ Cell[ name: EqConstantName, public: Wires["Vdd", "Gnd", in, "out"], onlyInternal: IF internals=NIL THEN NIL ELSE WireList[internals], instances: insts]; CoreProperties.PutCellTypeProp[ct, $value, NEW[LONG CARDINAL _ LOOPHOLE[v]]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: EqConstantName]; [] _ CoreFlat.CellTypeCutLabels[ct, macroCutSet]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd"]; Ports.InitPorts[ct, ls, none, "In"]; Ports.InitPorts[ct, l, drive, "out"]; }; EqConstantState: TYPE = REF EqConstantStateRec; EqConstantStateRec: TYPE = RECORD [ eqIn, eqOut: NAT, val: Ports.LevelSequence]; EqConstantInit: Rosemary.InitProc = { state: EqConstantState _ IF oldStateAny=NIL THEN NEW[EqConstantStateRec] ELSE NARROW[oldStateAny]; [state.eqIn, state.eqOut] _ Ports.PortIndexes[cellType.public, "In", "out"]; state.val _ NEW[Ports.LevelSequenceRec[cellType.public[state.eqIn].size]]; Ports.LCToLS[NARROW[CoreProperties.GetCellTypeProp[cellType, $value], REF LONG CARDINAL]^, state.val]; stateAny _ state; }; EqConstantSimple: Rosemary.EvalProc = { state: EqConstantState _ NARROW[stateAny]; p[state.eqOut].l _ LSEqual[p[state.eqIn].ls, state.val]; }; LSEqual: PROC [ls1, ls2: Ports.LevelSequence] RETURNS [eq: Ports.Level] ~ { IF ls1.size#ls2.size THEN ERROR; eq _ H; FOR i: NAT IN [0..ls1.size) DO eq _ Ports.AndL[eq, LEqual[ls1[i], ls2[i]]]; ENDLOOP; }; LEqual: PROC [l1, l2: Ports.Level] RETURNS [eq: Ports.Level] ~ { eq _ SELECT l1 FROM L => Ports.NotL[l2], H => l2, ENDCASE => X; }; SumL: PROC [a, b, c: Ports.Level] RETURNS [carry, s: Ports.Level] ~ { v: ARRAY Ports.Level OF NAT _ [0, 1, 0]; -- value of the level d: ARRAY Ports.Level OF NAT _ [0, 0, 1]; -- possible delta lower, higher: NAT; cl, ch, sl, sh: Ports.Level; lower _ v[a]+v[b]+v[c]; -- lower sum higher _ lower+d[a]+d[b]+d[c]; -- higher sum [cl, sl] _ TwoBitsToLevels[lower]; [ch, sh] _ TwoBitsToLevels[higher]; carry _ MergeLevels[cl, ch]; s _ IF carry#X THEN MergeLevels[sl, sh] ELSE X; }; TwoBitsToLevels: PROC [n: NAT] RETURNS [c, s: Ports.Level] ~ { SELECT n FROM 0 => RETURN[L, L]; 1 => RETURN[L, H]; 2 => RETURN[H, L]; 3 => RETURN[H, H]; ENDCASE => ERROR; }; MergeLevels: PROC [b1, b2: Ports.Level] RETURNS [l: Ports.Level] ~ { l _ IF b1=b2 THEN b1 ELSE X}; END. κLogicArithImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Last Edited by: Louis Monier January 5, 1987 9:12:44 pm PST Christian LeCocq October 14, 1986 2:06:31 pm PDT Barth, October 10, 1986 5:33:40 pm PDT Adder -- b>1 please -- Sum[0] is the (wrong Mesa order) high-order bit Constant -- Value must fit on 32-bit; sign-extended if b>32; Comparator Comparator with a constant 26-Dec-86 Frailong.pa Logic Date: 26 Dec 86 15:47:01 PST From: Frailong.pa Subject: Logic To: Monier cc: Frailong Reply-To: Frailong A suggestion of improvement for the EqConstant icon: would it be possible to allow the v parameter to accept both a REF INT and a LIST OF INT (or REF thereof)? The idea is to allow a constant comparator to return a comparison for a set of constants. This occurs quite frequently (at least in my design). Of course, the obvious solution is to have a set on EqConstant's and to OR the results. Obviously, a noticeably more efficient implementation is produced by merging the comparators (the gain is the inverters for bits that need it, plus the final OR which may very often bee simplified). I'm not really sure this is worth the effort, but I would be interested if you find a very simple implementation. Jean-Marc Κ ΅– "cedar" style˜codešœ™Kšœ Οmœ1™žœΟc˜Zšœžœ˜2Kšœ[˜[—KšžœžœC˜Nšžœžœžœ˜šœ˜KšœD˜DKšœ žœj˜y——šžœžœžœ ž˜šœžœ˜ šœ˜KšœF˜FKšœ:˜:—Kšœ˜—Kšžœ˜—šœžœ˜ šœ˜KšœL˜LKšœ2˜2—Kšœ˜—K˜šœ ˜ Kšœ˜Kšœ]˜]Kšœ(˜(Kšœ˜—KšœC˜CKšœ1˜1Kšœ6˜6Kšœ*˜*Kšœ(˜(Kšœ&˜&Kšœ˜K˜—Kšœ žœžœ˜%šœžœžœ˜Kšœ"žœžœžœ˜3—šŸ œ˜ Kš œžœ žœžœžœžœžœ˜XKšœŽ˜ŽKšœ˜—šŸ œ˜"Kšœžœ ˜%Kšœ(˜(š žœžœž œžœž˜5KšœR˜RKšžœ˜—Kšœ˜Kšœ˜——™K™3KšŸ œžœ˜ š Ÿœžœžœžœžœžœ˜AKšœžœžœ˜KšœB˜BKšœB˜BKšœR˜Ršžœž˜ šœ˜šžœžœžœžœ˜Kš œ žœžœžœžœ˜;Kšžœ˜——šœ˜Kšœžœžœžœ˜'Kš žœžœžœ žœžœ˜5šžœžœžœ žœ˜Kš œ žœžœžœžœ˜AKšžœ˜—K˜—Kšžœžœ˜—KšœJžœ˜OKšœ˜——šŸ ™ KšŸœžœf˜zš Ÿ œžœžœžœžœ˜;Kšœ˜Kšœ˜KšžœžœH˜Sšœ,˜,Kšœ˜Kšœ ˜ Kšœ)˜)—šœžœ˜ Kšœ?˜?Kšœ0˜0Kšœ˜—šœ ˜ Kšœ˜Kšœ?˜?Kšœ'˜'Kšœ˜—K˜KšœH˜HKšœ1˜1Kšœ+˜+Kšœ(˜(Kšœ&˜&Kšœ˜—Kšœžœžœ˜/Kš œžœžœ žœžœžœ˜>šŸœ˜%Kš œžœ žœžœžœžœžœ˜bKšœT˜TKšœ˜—šŸœ˜'Kšœžœ ˜*Kšœ6˜6Kšœ˜——šŸ™KšŸœžœf˜zš Ÿ œžœžœžœžœžœ˜CKšœžœžœ˜Kšœžœ˜Kš œ žœžœžœžœ˜Kš œžœžœžœžœ‘˜;Kšœ˜Kšœ˜Kšœ˜Kšœ+˜+KšžœžœV˜ašžœžœžœžœ˜šžœžœžœ‘˜2K˜Kšœ žœ˜%Kšœžœ6˜BKšœžœ˜(K˜—Kšžœžœ˜-Kšžœ˜—Kšœžœ!˜-šœ ˜ Kšœ˜Kšœ(˜(Kš œžœ žœžœžœžœ˜BKšœ˜—Kš œ+žœžœžœžœ˜MKšœH˜HKšœ1˜1Kšœ+˜+Kšœ$˜$Kšœ%˜%Kšœ˜—Kšœžœžœ˜/šœžœžœ˜#Kšœ žœ˜,—šŸœ˜%Kš œžœ žœžœžœžœžœ˜bKšœL˜LKšœ žœ;˜JKš œ žœ3žœžœžœ˜fKšœ˜K˜K˜—šŸœ˜'Kšœžœ ˜*Kšœ8˜8Kšœ˜K˜—šŸœžœ!žœ˜KKšžœžœžœ˜ K˜šžœžœžœž˜Kšœ-˜-Kšžœ˜—K˜K˜—šŸœžœžœ˜@šœžœž˜Kšœ˜Kšœ˜Kšžœ˜ —K˜K˜—šŸœžœžœ˜EKšœžœ žœžœ‘˜>Kšœžœ žœžœ‘˜:Kšœžœ˜Kšœ˜Kšœ‘ ˜$Kšœ‘ ˜,Kšœ"˜"Kšœ#˜#Kšœ˜Kšœžœ žœžœ˜/K˜K˜—š œžœžœžœ˜>šžœž˜ Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšžœžœ˜—K˜K˜—šŸ œžœžœ˜DKšœžœžœžœ˜K™——Kšžœ˜K˜K˜K˜header™JšΠbsœ™Jš’œ ™Jš’œ™Jš’œ™ Jš’œ ™ Jš’œ ™J™Ibodyš œWΟbœžœž œžœγžœΖ™ΐN™JšΠbi ™ —K˜—…—"-Α