Common part
B4: TYPE = {and, nand, or, nor};
nameInLib: ARRAY B4 OF ROPE = [and: "and", nand: "nand", or: "or", nor: "nor"];
nameOfCT: ARRAY B4 OF ROPE = [and: "And", nand: "Nand", or: "Or", nor: "Nor"];
rootCT: ARRAY B4 OF B4 = [and: nor, nand: nand, or: nand, nor: nor];
leafCT:
ARRAY
B4
OF
B4 = [and: nand, nand: and, or: nor, nor: or];
B4Small:
PROC [b4:
B4, n:
NAT]
RETURNS [ct: CellType] ~ {
Compute the celltype for those that have explicit layout
fullName: ROPE = IO.PutFR["%g n=%g", IO.rope[nameOfCT[b4]], IO.int[n]];
sc: CellType;
pas: LIST OF PA;
ct ← CacheFetch[fullName];
IF ct#NIL THEN RETURN[ct];
sc ← MakeSC[IO.PutFR["%g%g", IO.rope[nameInLib[b4]], IO.int[n]]];
pas ← LIST[["I-A", "I[0]"], ["I-B", "I[1]"]];
IF n>2 THEN pas ← CONS[["I-C", "I[2]"], pas];
IF n>3 THEN pas ← CONS[["I-D", "I[3]"], pas];
ct ← Cell[name:
IO.PutFR["%g%g",
IO.rope[nameOfCT[b4]],
IO.int[n]],
public: Wires["Vdd", "Gnd", Seq["I", n], "X"],
instances: LIST[InstanceList[sc, pas]]];
CacheStore[fullName, ct];
};
B4Large:
PROC [b4:
B4, n:
NAT]
RETURNS [ct: CellType] ~ {
Compute all 4 generic functions
-- and -> nor2(nand)
-- nand -> nand2(and)
-- or -> nand2(nor)
-- nor -> nor2(or)
fullName: ROPE;
input: Wire;
n1: NAT = n/2;
SELECT n
FROM
0 => Error[IO.PutFR["Please specify the number of inputs of the `%g' gate", IO.rope[nameInLib[b4]]]];
1 => RETURN [Extract[IF b4=and OR b4=or THEN "wrappedInvPair.sch" ELSE "wrappedInv.sch"]];
<=4 => RETURN [B4Small[b4, n]];
ENDCASE => NULL; -- general case, see below
fullName ← IO.PutFR["%g n=%g", IO.rope[nameOfCT[b4]], IO.int[n]];
ct ← CacheFetch[fullName];
IF ct#NIL THEN RETURN[ct];
Here comes the general case
input ← Seq["I", n];
ct ← Cell[name:
IO.PutFR["%g%g",
IO.rope[nameOfCT[b4]],
IO.int[n]],
instances:
LIST[
Instance[B4Small[rootCT[b4], 2], ["I", Wires["One", "Two"]]],
Instance[B4Large[leafCT[b4], n1], ["X", "One"], ["I", Range[input, 0, n1]]],
Instance[B4Large[leafCT[b4], n-n1], ["X", "Two"], ["I", Range[input, n1, n-n1]]]
],
public: Wires["Vdd", "Gnd", input, "X"],
onlyInternal: Wires["One", "Two"]];
CacheStore[fullName, ct];
};
Interface calls
And:
PUBLIC
PROC[n:
NAT]
RETURNS [ct: CellType] = {ct ← B4Large[and, n]};
Nand:
PUBLIC
PROC[n:
NAT]
RETURNS [ct: CellType] = {ct ← B4Large[nand, n]};
Or:
PUBLIC
PROC[n:
NAT]
RETURNS [ct: CellType] = {ct ← B4Large[or, n]};
Nor: PUBLIC PROC[n: NAT] RETURNS [ct: CellType] = {ct ← B4Large[nor, n]};