<> <> <<>> <> DIRECTORY Core, CoreClasses, CoreCreate, Ports, Rope, Rosemary, RosemaryUser; <<>> DAToolsIntroAdder4BehProc: CEDAR PROGRAM <> IMPORTS CoreClasses, CoreCreate, Ports, Rosemary ~ BEGIN CellType : TYPE = Core.CellType; CellTypes: TYPE = LIST OF Core.CellType; Level: TYPE = Ports.Level; Properties : TYPE = Core.Properties; ROPE: TYPE = Core.ROPE; Wire: TYPE = Core.Wire; Wires: TYPE = Core.Wires; <> PA: TYPE = CoreCreate.PA; WR: TYPE = CoreCreate.WR; FlipFlop: TYPE = RECORD[master, slave: Ports.Level]; AdderState: TYPE = REF AdderStateRec; AdderStateRec: TYPE = RECORD [ prevClk: Ports.Level, Reg1: FlipFlop, Reg4: ARRAY [0..3] OF FlipFlop, tempCin: Ports.Level ]; en, CIN, A, B, SUM, Cout, Clock:NAT; Adder4Definition: PUBLIC PROC [] RETURNS [ct: CellType] = { <> public: Wire _ CoreCreate.WireList[LIST [CoreCreate.Seq["SUM",4], CoreCreate.Seq["A",4], CoreCreate.Seq["B",4], "en", "Clock", "Cout", "CIN" ]]; <<>> ct _ CoreClasses.CreateUnspecified[public: public]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: Adder4BehProcName]; <<>> <> <> <> <<>> Ports.InitPorts[ct, ls, none, "A", "B"]; Ports.InitPorts[ct, l, none, "en", "Clock", "CIN"]; Ports.InitPorts[ct, l, drive, "Cout"]; Ports.InitPorts[ct, ls, drive,"SUM"]; }; Adder4BehProcInit: Rosemary.InitProc = { <<--PROC [cellType: Core.CellType, p: Ports.Port, oldStateAny: REF ANY _ NIL] RETURNS [stateAny: REF ANY _ NIL]-->> adderstate: AdderState _ IF oldStateAny=NIL THEN NEW[AdderStateRec] ELSE NARROW[oldStateAny, AdderState]; adderstate.prevClk _ X; FOR i: INT IN [0..3] DO adderstate.Reg4[i].master _ X; adderstate.Reg4[i].slave _ X; ENDLOOP; adderstate.Reg1.master _ X; adderstate.Reg1.slave _ X; << This next procedure call is a convenience. It returns the names of the wires as numerical indices, thus allowing the sequence of port wires to be indexed by familiar names rather than numbers.>> [en, CIN, A, B, SUM, Cout, Clock] _ Ports.PortIndexes[cellType.public, "en", "CIN", "A", "B","SUM", "Cout", "Clock"]; stateAny _ adderstate; }; Adder4BehProcEval: Rosemary.EvalProc = { <<--PROC [p: Ports.Port, stateAny: REF ANY]-->> i, numHigh: INT; <<>> adderstate: AdderState _ NARROW[stateAny]; <> << >> IF adderstate.prevClk = H AND p[Clock].l = L AND p[en].l = H THEN {adderstate.tempCin _ p[CIN].l; numHigh _ 0; FOR i DECREASING IN [0..3] DO numHigh _ 0; IF p[A].ls[i] = H THEN numHigh _ numHigh + 1; IF p[B].ls[i] = H THEN numHigh _ numHigh + 1; IF adderstate.tempCin = H THEN numHigh _ numHigh + 1; adderstate.Reg4[i].master _ IF numHigh MOD 2 = 1 THEN H ELSE L; adderstate.tempCin _ IF numHigh >= 2 THEN H ELSE L; ENDLOOP; adderstate.Reg1.master _ adderstate.tempCin;}; <> <<>> IF adderstate.prevClk = L AND p[Clock].l = H THEN{ FOR i IN [0..3] DO adderstate.Reg4[i].slave _ adderstate.Reg4[i].master; ENDLOOP; adderstate.Reg1.slave _ adderstate.Reg1.master;}; <> p[Cout].l _ adderstate.Reg1.slave; FOR i: INT IN [0..3] DO p[SUM].ls[i] _ adderstate.Reg4[i].slave; ENDLOOP; adderstate.prevClk _ p[Clock].l; }; Adder4BehProcName: ROPE = Rosemary.Register[roseClassName: "Adder4Definition", init: Adder4BehProcInit, evalSimple: Adder4BehProcEval]; END. <<>>