AddPrimitive:
PROC [output: CoreFlat.FlatWire, negateOutput:
BOOL, inputs: PolarizedInputs, clock: CoreFlat.FlatWire ←
NIL] = {
p: Primitive;
index: CARDINAL ← 0;
size: CARDINAL ← 0;
FOR il: PolarizedInputs ← inputs, il.rest
UNTIL il=
NIL
DO
size ← size + 1;
ENDLOOP;
p ← NEW[PrimitiveRec[size]];
p.flatClock ← IF clock=NIL THEN NIL ELSE FetchUnique[clock];
p.flatCell ← flatCell;
p.flatOutput ← FetchUnique[output];
p.negateOutput ← negateOutput;
FOR fws: PolarizedInputs ← inputs, fws.rest
UNTIL fws=
NIL
DO
equivalent: CoreFlat.FlatWire;
polarity: BOOL;
[equivalent, polarity] ← GetEquivalent[fws.first.flatInput, fws.first.negate];
p.inputs[index].flatInput ← FetchUnique[equivalent];
p.inputs[index].negate ← polarity;
p.inputs[index].source ← NIL;
index ← index + 1;
ENDLOOP;
IF
NOT RefTab.Insert[flat.wires, output, p]
THEN {
ep: Primitive ← NARROW[RefTab.Fetch[flat.wires, output].val];
IF p.flatClock#ep.flatClock THEN ERROR;
IF p.flatOutput#ep.flatOutput THEN ERROR;
IF p.negateOutput#ep.negateOutput THEN ERROR;
IF p.size#ep.size THEN ERROR;
FOR index:
CARDINAL
IN [0..size)
DO
IF p.inputs[index].flatInput#ep.inputs[index].flatInput THEN ERROR;
IF p.inputs[index].negate#ep.inputs[index].negate THEN ERROR;
ENDLOOP;
};
};
name: Rope.ROPE ← CoreOps.GetCellTypeName[cell];
ELSE
SELECT primitiveType^
FROM
ignore, equate => NULL;
and, nand, or, nor => {
flatOutput: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "X"];
flatInputs: PolarizedInputs ← NIL;
Combinatorial.MakeCombinatorial[cell];
FOR wl: Core.Wires ← Combinatorial.GetTypedWires[cell, input], wl.rest
UNTIL wl=
NIL
DO
flatInput: CoreFlat.FlatWire ← CanonizeWire[bindings, flatCell, wl.first];
flatInputs ← CONS[[flatInput, invertInputs[primitiveType^]], flatInputs];
ENDLOOP;
AddPrimitive[flatOutput, invertOutput[primitiveType^], flatInputs];
};
xor2, xnor2 => {
a: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "I-A"];
b: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "I-B"];
x: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "X"];
i1: CoreFlat.FlatWire ← CreateWire[flatCell];
i2: CoreFlat.FlatWire ← CreateWire[flatCell];
AddPrimitive[i1, FALSE, LIST[[a, TRUE], [b, FALSE]]];
AddPrimitive[i2, FALSE, LIST[[a, FALSE], [b, TRUE]]];
AddPrimitive[x, primitiveType^=xnor2, LIST[[i1, FALSE], [i2, FALSE]]];
};
a22o2i, o22a2i => {
a: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "A"];
b: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "B"];
c: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "C"];
d: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "D"];
x: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "X"];
i1: CoreFlat.FlatWire ← CreateWire[flatCell];
i2: CoreFlat.FlatWire ← CreateWire[flatCell];
invertInputs: BOOL ← primitiveType^=o22a2i;
AddPrimitive[i1, FALSE, LIST[[a, invertInputs], [b, invertInputs]]];
AddPrimitive[i2, FALSE, LIST[[c, invertInputs], [d, invertInputs]]];
AddPrimitive[x, NOT invertInputs, LIST[[i1, FALSE], [i2, FALSE]]];
};
a21o2i, o21a2i => {
a: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "A"];
b: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "B"];
c: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "C"];
x: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "X"];
i: CoreFlat.FlatWire ← CreateWire[flatCell];
invert: BOOL ← primitiveType^=o21a2i;
AddPrimitive[i, FALSE, LIST[[a, invert], [b, invert]]];
AddPrimitive[x, NOT invert, LIST[[i, FALSE], [c, NOT invert]]];
};
ff => {
d: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "D"];
q: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "Q"];
ck: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "CK"];
AddPrimitive[q, FALSE, LIST[[d, FALSE]], ck];
};
ffEn => {
en: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "en"];
d: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "D"];
q: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "Q"];
ck: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "CK"];
i1: CoreFlat.FlatWire ← CreateWire[flatCell];
i2: CoreFlat.FlatWire ← CreateWire[flatCell];
i3: CoreFlat.FlatWire ← CreateWire[flatCell];
AddPrimitive[i1, FALSE, LIST[[en, FALSE], [d, FALSE]]];
AddPrimitive[i2, FALSE, LIST[[en, TRUE], [q, FALSE]]];
AddPrimitive[i3, FALSE, LIST[[i1, FALSE], [i2, FALSE]]];
AddPrimitive[q, FALSE, LIST[[i3, FALSE]], ck];
};
tstDriver => {
x: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "X"];
triData: TriData ← NARROW[RefTab.Fetch[triDataTable, x].val];
IF triData.count>1
THEN {
i: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "I"];
en: CoreFlat.FlatWire ← GetNamedWire[bindings, cell.public, flatCell, "EN"];
i1: CoreFlat.FlatWire ← CreateWire[flatCell];
i2: CoreFlat.FlatWire ← CreateWire[flatCell];
previous: CoreFlat.FlatWire ← IF triData.count=2 THEN triData.lastInput ELSE CreateWire[flatCell];
AddPrimitive[i1, FALSE, LIST[[en, FALSE], [i, FALSE]]];
AddPrimitive[i2, FALSE, LIST[[en, TRUE], [previous, FALSE]]];
AddPrimitive[triData.next, FALSE, LIST[[i1, FALSE], [i2, FALSE]]];
triData.count ← triData.count - 1;
triData.next ← previous;
};
};
ENDCASE => ERROR;