DIRECTORY BitOps, CoreClasses, CoreCreate, CoreOps, CoreProperties, IO, Logic, LogicUtils, Ports, Rosemary, Static; LogicArithImpl: CEDAR PROGRAM IMPORTS BitOps, CoreCreate, CoreOps, CoreProperties, IO, Logic, LogicUtils, Ports, Static EXPORTS Logic = BEGIN OPEN LogicUtils, CoreCreate; 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]] _ Ports.SumL[p[state.inA].ls[i], p[state.inB].ls[i], carry]; ENDLOOP; p[state.carryOut].l _ carry; }; AdderRoseClass: ROPE = RoseClass["Adder", AdderInit, AdderSimple]; Adder: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { fullName: ROPE = IO.PutFR["Adder b=%g", IO.int[b]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; SELECT b FROM 0 => Error["Please specify a number of bits for the adder"]; 1 => { ct _ Extract["oneBitAdder.sch"]; -- designed by Alfred CacheStore[fullName, ct]; }; ENDCASE => { ct _ SequenceCell[baseCell: Adder[1], count: b, sequencePorts: Wires["A", "B", "Sum"], stitchPorts: LIST[["carryOut", "carryIn"]], name: "Adder"]; SimulateMacro[ct, AdderRoseClass]; Ports.InitPorts[ct, l, none, "carryIn"]; Ports.InitPorts[ct, l, drive, "carryOut"]; Ports.InitPorts[ct, ls, none, "A", "B"]; Ports.InitPorts[ct, ls, drive, "Sum"]; CacheStore[fullName, ct]; }; }; 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: "Constant", public: Wires[gnd, vdd, output], instances: NIL]; }; 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; }; ComparatorRoseClass: ROPE = RoseClass["Comparator", ComparatorInit, ComparatorSimple]; Comparator: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { fullName: ROPE = IO.PutFR["Comparator b=%g", IO.int[b]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; IF b=0 THEN Error["Please specify a number of bits for the comparator"]; ct _ Extract["comparator.sch", LIST[["b", b]]]; SimulateMacro[ct, ComparatorRoseClass]; Ports.InitPorts[ct, ls, none, "A", "B"]; Ports.InitPorts[ct, l, drive, "AEqB"]; CacheStore[fullName, ct]; }; 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]; }; EqConstantRoseClass: ROPE = RoseClass["EqConstant", EqConstantInit, EqConstantSimple]; EqConstant: PUBLIC PROC [b: NAT, v: INT] RETURNS [ct: CellType] = { eqConstantName: ROPE = "EqConstant"; vCard: CARD = LOOPHOLE[v]; n0, n1: NAT _ 0; int0, int1: Wire; in: Wire; wr0, wr1: LIST OF WR _ NIL; fullName: ROPE = IO.PutFR["EqConstant b=%g v=%g", IO.int[b], IO.int[v]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; IF b=0 THEN Error["Please specify a number of bits for the constant comparator"]; in _ Seq["In", b]; FOR i: NAT IN [0..b) DO IF BitOps.EBFD[vCard, i, b] THEN {n1 _ n1+1; wr1 _ CONS[in[i], wr1]} ELSE {n0 _ n0+1; wr0 _ CONS[in[i], wr0]}; ENDLOOP; SELECT TRUE FROM n0+n1#b => ERROR; -- just a check n0=0 => { -- and[b] is enough ct _ Cell[name: eqConstantName, public: Wires["Vdd", "Gnd", in, "out"], instances: LIST[InstanceList[Logic.And[b], LIST[["X", "out"], ["I", in]]]]]; }; n1=0 => { -- nor[b] is enough ct _ Cell[name: eqConstantName, public: Wires["Vdd", "Gnd", in, "out"], instances: LIST[InstanceList[Logic.Nor[b], LIST[["X", "out"], ["I", in]]]]]; }; ENDCASE => { subCT: CellType = Extract["eqConstant2Inputs.sch", LIST[["n0", n0], ["n1", n1]]]; int0 _ WireList[wr0]; int1 _ WireList[wr1]; ct _ Cell[name: eqConstantName, public: Wires["Vdd", "Gnd", in, "out"], onlyInternal: Wires[int0, int1], instances: LIST[InstanceList[subCT, LIST[["out", "out"], ["in0", int0], ["in1", int1]]]]]; }; CoreProperties.PutCellTypeProp[ct, $value, NEW[INT _ v]]; SimulateMacro[ct, EqConstantRoseClass]; Ports.InitPorts[ct, ls, none, "In"]; Ports.InitPorts[ct, l, drive, "out"]; CacheStore[fullName, ct]; }; 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]; v: INT = NARROW[CoreProperties.GetCellTypeProp[cellType, $value], REF INT]^; [state.eqIn, state.eqOut] _ Ports.PortIndexes[cellType.public, "In", "out"]; state.val _ NEW[Ports.LevelSequenceRec[cellType.public[state.eqIn].size]]; Ports.LCToLS[LOOPHOLE [v], state.val]; stateAny _ state; }; EqConstantSimple: Rosemary.EvalProc = { state: EqConstantState _ NARROW[stateAny]; p[state.eqOut].l _ LSEqual[p[state.eqIn].ls, state.val]; }; END. LLogicArithImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Last Edited by: Louis Monier August 26, 1987 5:41:22 pm PDT Jean-Marc Frailong October 21, 1987 11:03:08 pm PDT Christian LeCocq October 14, 1986 2:06:31 pm PDT Barth, August 6, 1987 5:07:02 pm PDT Adder Shared types & functions Ripple carry adder Constant Value must fit on 32-bit; sign-extended if b>32; Comparators Shared code Full comparator Comparator with a constant NOR all the zeros, AND all the ones, and AND2 these two together -- sort out the zeros from the ones, and create the internals Κν– "cedar" style˜codešœ™Kšœ Οmœ1™š œ˜%Kš œžœ žœžœžœžœžœ˜bKšœT˜TKšœ˜Kšœ˜—š œ˜'Kšœžœ ˜*Kšœ6˜6Kšœ˜——šœ™Kš œžœ=˜Vš   œžœžœžœžœžœ˜CKšœ@™@Kšœžœ˜$Kšœžœžœ˜Kšœžœ˜Kšœ˜Kšœ ˜ Kš œ žœžœžœžœ˜Kš œ žœžœžœ žœ ˜HK˜Kšžœžœžœžœ˜KšžœžœF˜QKš‘=™=Kšœ˜šžœžœžœž˜Kšžœžœžœžœ˜EKšžœžœ˜)Kšžœ˜—šžœžœž˜Kšœ žœ‘˜"šœ ‘˜šœ ˜ Kšœ(˜(Kšœ žœžœ˜L—Kšœ˜—šœ ‘˜šœ ˜ Kšœ(˜(Kšœ žœžœ˜L—Kšœ˜—šžœ˜ Kšœ3žœ˜QKšœ˜Kšœ˜šœ ˜ Kšœ(˜(Kšœ!˜!Kšœ žœžœ2˜Z—Kšœ˜——Kšœ+žœžœ˜9Kšœ'˜'KšœJ˜JKšœ˜Kšœ˜K˜—Kšœžœžœ˜/Kšœžœžœžœ˜Oš œ˜%Kš œžœ žœžœžœžœžœ˜bKš œžœžœ3žœžœ˜LKšœL˜LKšœ žœ;˜JKšœ žœ˜&Kšœ˜K˜K˜—š œ˜'Kšœžœ ˜*Kšœ8˜8Kšœ˜K˜———Kšžœ˜K˜—…—F"