TestPatchWork.mesa
Copyright Ó 1988 by Xerox Corporation. All rights reversed.
Created by Bertrand Serlet, May 9, 1988 0:06:38 am PDT
Bertrand Serlet May 12, 1988 11:50:09 pm PDT
DIRECTORY
BitOps, Core, CoreClasses, CoreCreate, CoreOps,
PatchWork, PipalSisyph, Tiling;
TestPatchWork:
CEDAR
PROGRAM
IMPORTS BitOps, CoreClasses, CoreCreate, CoreOps, PatchWork, PipalSisyph, Tiling =
BEGIN
Inverters
CreateInverter:
PROC []
RETURNS [cellType: CellType] = {
In: Wire ← CoreOps.CreateWire[name: "In"];
Out: Wire ← CoreOps.CreateWire[name: "Out"];
Gnd: Wire ← CoreOps.CreateWire[name: "Gnd"];
Vdd: Wire ← CoreOps.CreateWire[name: "Vdd"];
ntrans: CoreClasses.CellInstance ←
NEW [CoreClasses.CellInstanceRec ← [
actual: CoreOps.CreateWire[LIST [In, Out, Gnd]],
type: CoreClasses.CreateTransistor[nE]
]];
ptrans: CoreClasses.CellInstance ←
NEW [CoreClasses.CellInstanceRec ← [
actual: CoreOps.CreateWire[LIST [In, Out, Vdd, Vdd]],
type: CoreClasses.CreateTransistor[pE]
]];
cellType ← CoreClasses.CreateRecordCell[
public: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd]],
internal: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd]],
instances: LIST [ntrans, ptrans],
name: "TestPatchWork.Inverter"
];
PatchWork.SetGet[cellType];
};
Create2Inverter:
PROC []
RETURNS [cellType: CellType] = {
In: Wire ← CoreOps.CreateWire[name: "In"];
Out: Wire ← CoreOps.CreateWire[name: "Out"];
Gnd: Wire ← CoreCreate.Seq[size:2, name: "Gnd"];
Vdd: Wire ← CoreCreate.Seq[size:2, name: "Vdd"];
Intern: Wire ← CoreOps.CreateWire[name: "Intern"];
inverter: CellType ← CreateInverter[];
first: CoreClasses.CellInstance ←
NEW [CoreClasses.CellInstanceRec ← [
actual: CoreOps.CreateWire[LIST [In, Intern, Gnd[0], Vdd[0]]],
type: inverter
]];
second: CoreClasses.CellInstance ←
NEW [CoreClasses.CellInstanceRec ← [
actual: CoreOps.CreateWire[LIST [Intern, Out, Gnd[1], Vdd[1]]],
type: inverter
]];
cellType ← CoreClasses.CreateRecordCell[
public: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd]],
internal: CoreOps.CreateWire[LIST [In, Out, Gnd, Vdd, Intern]],
instances: LIST [first, second],
name: "TestPatchWork.Inverter2"
];
PatchWork.SetAbutX[cellType];
};
Decoder Basic Cells
XthBitOfN:
PUBLIC
PROC [x, n:
INT]
RETURNS [
BOOL] = {
RETURN [
IF x<0
THEN
FALSE
ELSE (n/BitOps.TwoToThe[x])
MOD 2 =1]};
Extract:
PROC [name:
ROPE]
RETURNS [cellType: CellType] = {
cellType ← PipalSisyph.Extract[Rope.Cat["TestPatchWork", name, ".sch"]];
};
alpsOne: CellType ← Extract["AlpsOne"];
alpsZero: CellType ← Extract["AlpsZero"];
alpsPWell: CellType ← Extract["AlpsPWell"];
alpsCascode: CellType ← Extract["AlpsCascode"];
Decoder CoreCreate Method
A simple line without the cascode inverter at the end
AlpsDecoderLine:
PROC [nbBits:
NAT, index:
NAT, pWellEach:
NAT ← 4]
RETURNS [cellType: CellType] = {
PlusI: PROC [i: NAT] RETURNS [WR] = {RETURN [IF i=0 THEN "Gnd" ELSE IF i=nbBits THEN "Plus" ELSE Index["InternalPlus", i]]};
Input: Wire ← Seq[size: nbBits, name: "Input"];
NotInput: Wire ← Seq[size: nbBits, name: "NotInput"];
Plus: Wire ← CoreOps.CreateWire[name: "Plus"];
Minus: Wire ← CoreOps.CreateWire[name: "Minus"];
InternalPlus: Wire ← Seq[size: nbBits, name: "InternalPlus"];
Gnd: Wire ← CoreOps.CreateWire[name: "Gnd"];
instances: LIST OF CellInstance ← NIL;
FOR i:
NAT
IN [0 .. nbBits)
DO
IF (i
MOD pWellEach) = 0
THEN instances ← CONS [Instance[alpsPWell, ["Plus", PlusI[i]]], instances];
instances ←
CONS [
Instance[
IF XthBitOfN[i, index] THEN alpsOne ELSE alpsZero,
["PlusLeft", PlusI[i]],
["PlusRight", PlusI[i+1]],
["Input", Index["Input", i]],
["NotInput", Index["NotInput", i]]],
instances];
ENDLOOP;
cellType ← Cell[
public: Wires[Input, NotInput, Plus, Minus, Gnd],
onlyInternal: Wires[InternalPlus],
instances: CoreClasses.ReverseCellInstances[instances]
];
PatchWork.SetAbutX[cellType];
};
A simple array without the cascode inverters at the end
AlpsDecoderArray:
PROC [nbBits:
NAT, indexMin:
NAT ← 0, indexSize:
NAT ← 0, pWellEach:
NAT ← 4]
RETURNS [cellType: CellType] = {
indexSize=0 means in fact 2^nbBits
size: NAT ← IF indexSize=0 THEN NAT[BitOps.TwoToThe[nbBits]] ELSE indexSize;
Input: Wire ← Seq[size: nbBits, name: "Input"];
NotInput: Wire ← Seq[size: nbBits, name: "NotInput"];
Plus: Wire ← Seq[size: size, name: "Plus"];
Minus: Wire ← Seq[size: size, name: "Minus"];
Gnd: Wire ← CoreOps.CreateWire[name: "Gnd"];
instances: LIST OF CellInstance ← NIL;
FOR i:
NAT
IN [0 .. size)
DO
instances ←
CONS [
Instance[
AlpsDecoderLine[nbBits, i + indexMin, pWellEach],
["Plus", Index["Plus", i]],
["Minus", Index["Minus", i]]],
instances];
ENDLOOP;
cellType ← Cell[
public: Wires[Input, NotInput, Plus, Minus, Gnd],
instances: CoreClasses.ReverseCellInstances[instances],
name: "AlpsDecoderArray"
];
PatchWork.SetAbutY[cellType];
};
A column of inverters
AlpsDecoderOutputInverters:
PROC [nbBits:
NAT, indexSize:
NAT ← 0]
RETURNS [cellType: CellType] = {
indexSize=0 means in fact 2^nbBits
size: NAT ← IF indexSize=0 THEN NAT[BitOps.TwoToThe[nbBits]] ELSE indexSize;
cellType ← SequenceCell[alpsCascode, size, Wires["Plus", "Minus"]];
PatchWork.SetArrayY[cellType];
};
A simple array with the cascode inverters at the end
AlpsDecoderFullArray:
PROC [nbBits:
NAT, indexMin:
NAT ← 0, indexSize:
NAT ← 0, pWellEach:
NAT ← 4]
RETURNS [cellType: CellType] = {
indexSize=0 means in fact 2^nbBits
size: NAT ← IF indexSize=0 THEN NAT[BitOps.TwoToThe[nbBits]] ELSE indexSize;
Input: Wire ← Seq[size: nbBits, name: "Input"];
NotInput: Wire ← Seq[size: nbBits, name: "NotInput"];
Plus: Wire ← Seq[size: size, name: "Plus"];
Output: Wire ← Seq[size: size, name: "Output"];
Gnd: Wire ← CoreOps.CreateWire[name: "Gnd"];
Vdd: Wire ← CoreOps.CreateWire[name: "Vdd"];
cellType ← Cell[
public: Wires[Input, NotInput, Output, Gnd, Vdd],
onlyInternal: Wires[Plus],
instances:
LIST [
Instance[AlpsDecoderArray[nbBits, indexMin, size, pWellEach], ["Minus", "Output"]],
Instance[AlpsDecoderOutputInverters[nbBits, size], ["Minus", "Output"]]],
name: "AlpsDecoderFullArray"
];
PatchWork.SetAbutX[cellType];
};
Decoder with 2 Tilings and custom NeighborProc
A simple line with the cascode inverter at the end
AlpsDecoderLineRowTiling:
PROC [nbBits:
NAT, index:
NAT]
RETURNS [cellType: CellType] = {
tileArray: Tiling.TileArray = NEW [Tiling.TileArrayRec[1]];
tileRow: Tiling.TileRow = NEW [Tiling.TileRowRec[nbBits+2]];
tileRow[nbBits+1] ←
NEW [Tiling.TileRec ← [
type: alpsCascode, renaming: LIST [["Minus", "Output"], ["Vdd", "Vdd"]]
]];
tileRow[0] ←
NEW [Tiling.TileRec ← [
type: alpsPWell, renaming: LIST [["Gnd", "Gnd"], ["Plus", "Gnd"]]
]];
tileArray[0] ← tileRow;
FOR i:
NAT
IN [0 .. nbBits)
DO
tileRow[i+1] ←
NEW [Tiling.TileRec ← [
type: IF XthBitOfN[i, index] THEN alpsOne ELSE alpsZero,
renaming: LIST [["Gnd", "Gnd"], ["Input", Index["Input", i]], ["NotInput", Index["NotInput", i]]]
]];
ENDLOOP;
cellType ← Tiling.CreateTiling[
public: Wires[Seq[size: nbBits, name: "Input"], Seq[size: nbBits, name: "NotInput"], "Output", "Gnd", "Vdd"],
tileArray: tileArray,
neighborX: CustomNeighborInX,
neighborY: NIL
];
};
CustomNeighborInX: Tiling.NeighborProc = {
publicPairs ←
LIST [
[FindWire[ct1.public,
IF ct1=alpsPWell
THEN "Plus"
ELSE "PlusRight"],
FindWire[ct2.public, IF ct2=alpsCascode THEN "Plus" ELSE "PlusLeft"]],
[FindWire[ct1.public, "Minus"],
FindWire[ct2.public, "Minus"]]
];
};
AlpsDecoderFullArrayRowTiling:
PROC [nbBits:
NAT, indexMin:
NAT ← 0, indexSize:
NAT ← 0]
RETURNS [cellType: CellType] = {
indexSize=0 means in fact 2^nbBits
size: NAT ← IF indexSize=0 THEN NAT[BitOps.TwoToThe[nbBits]] ELSE indexSize;
tileArray: Tiling.TileArray = NEW [Tiling.TileArrayRec[size]];
FOR i:
NAT
IN [0 .. size)
DO
tileRow: Tiling.TileRow = NEW [Tiling.TileRowRec[1]];
tileArray[i] ← tileRow;
tileRow[0] ←
NEW [Tiling.TileRec ← [
type: AlpsDecoderLineRowTiling[nbBits, i + indexMin],
renaming: LIST [["Gnd", "Gnd"], ["Vdd", "Vdd"], ["Input", "Input"], ["NotInput", "NotInput"], ["Output", Index["Output", i]]]
]];
ENDLOOP;
cellType ← Tiling.CreateTiling[
public: Wires[Seq[size: nbBits, name: "Input"], Seq[size: nbBits, name: "NotInput"], Seq[size: size, name: "Output"], "Gnd", "Vdd"],
tileArray: tileArray,
neighborX: NIL,
neighborY: CustomNeighborInY,
name: "AlpsDecoderFullArrayRowTiling"
];
};
CustomNeighborInY: Tiling.NeighborProc = {};