EqConstant:
PUBLIC
PROC [b:
NAT, v:
INT]
RETURNS [ct: CellType] = {
NOR all the zeros, AND all the ones, and AND2 these two together
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"];
-- sort out the zeros from the ones, and create the internals
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[LONG CARDINAL ← LOOPHOLE[v]]];
SimulateMacro[ct, RoseClass[eqConstantName, EqConstantInit, EqConstantSimple]];
Ports.InitPorts[ct, ls, none, "In"]; Ports.InitPorts[ct, l, drive, "out"];
CacheStore[fullName, ct];
};
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];
};