PWCoreDecoder.mesa
Copyright © 1985 by Xerox Corporation. All rights reversed.
Created by Bertrand Serlet, February 7, 1986 5:47:29 pm PST
Bertrand Serlet November 9, 1986 0:42:44 am PST
DIRECTORY
CD, Core, CoreClasses, CoreCreate, CoreOps, IO, PW, PWCore, Sisyph, TilingClass;
PWCoreDecoder: CEDAR PROGRAM
IMPORTS CoreClasses, CoreCreate, CoreOps, IO, PW, PWCore, Sisyph, TilingClass =
BEGIN OPEN CoreCreate;
Basic Cells
schDesign: CD.Design ← PW.OpenDesign["PWCoreDecoder"];
layoutDesign: CD.Design ← schDesign;
cx: Sisyph.Context ← Sisyph.Create[schDesign];
Extract: PROC [name: ROPE] RETURNS [cellType: CellType] = {
cellType ← Sisyph.ExtractSchematicByName[IO.PutR[IO.rope[name], IO.rope[".sch"]], cx];
PWCore.SetGet[cellType, layoutDesign];
};
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=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 PW.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]
];
PWCore.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: NATIF indexSize=0 THEN NAT[PW.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"
];
PWCore.SetAbutY[cellType];
};
A column of inverters
AlpsDecoderOutputInverters: PROC [nbBits: NAT, indexSize: NAT ← 0] RETURNS [cellType: CellType] = {
indexSize=0 means in fact 2^nbBits
size: NATIF indexSize=0 THEN NAT[PW.TwoToThe[nbBits]] ELSE indexSize;
cellType ← SequenceCell[alpsCascode, size, Wires["Plus", "Minus"]];
PWCore.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: NATIF indexSize=0 THEN NAT[PW.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"
];
PWCore.SetAbutX[cellType];
};
Decoder with PWCore.AbutCell
A simple line with the cascode inverter at the end
AlpsDecoderLineQuick: PROC [nbBits: NAT, index: NAT, pWellEach: NAT ← 4] RETURNS [cellType: CellType] = {
abutInstances: LIST OF PWCore.AbutInstance ← LIST [
[PWCore.Layout[alpsCascode], LIST [["Minus", "Output"], ["Vdd", "Vdd"]]]
];
FOR i: NAT DECREASING IN [0 .. nbBits) DO
abutInstances ← CONS [
[PWCore.Layout[IF PW.XthBitOfN[i, index] THEN alpsOne ELSE alpsZero],
LIST [["Gnd", "Gnd"], ["Input", Index["Input", i]], ["NotInput", Index["NotInput", i]]]
],
abutInstances];
IF (i MOD pWellEach) = 0
THEN abutInstances ← CONS [[PWCore.Layout[alpsPWell]], abutInstances];
ENDLOOP;
cellType ← PWCore.AbutCell[
public: Wires[Seq[size: nbBits, name: "Input"], Seq[size: nbBits, name: "NotInput"], "Output", "Gnd", "Vdd"],
abutInstances: abutInstances,
inX: TRUE
];
};
AlpsDecoderFullArrayQuick: PROC [nbBits: NAT, indexMin: NAT ← 0, indexSize: NAT ← 0, pWellEach: NAT ← 4] RETURNS [cellType: CellType] = {
indexSize=0 means in fact 2^nbBits
size: NATIF indexSize=0 THEN NAT[PW.TwoToThe[nbBits]] ELSE indexSize;
instances: LIST OF CellInstance ← NIL;
FOR i: NAT DECREASING IN [0 .. size) DO
instances ← CONS [
Instance[
AlpsDecoderLineQuick[nbBits, i + indexMin, pWellEach],
["Output", Index["Output", i]]],
instances];
ENDLOOP;
cellType ← Cell[
public: Wires[Seq[size: nbBits, name: "Input"], Seq[size: nbBits, name: "NotInput"], Seq[size: size, name: "Output"], "Gnd", "Vdd"],
instances: instances,
name: "AlpsDecoderFullArrayQuick"
];
PWCore.SetAbutY[cellType];
};
Decoder with PWCore.AbutList
A simple line with the cascode inverter at the end
AlpsDecoderLineList: PROC [nbBits: NAT, index: NAT, pWellEach: NAT ← 4] RETURNS [cellType: CellType] = {
subs: LIST OF CellType ← LIST [alpsCascode];
FOR i: NAT DECREASING IN [0 .. nbBits) DO
subs ← CONS [IF PW.XthBitOfN[i, index] THEN alpsOne ELSE alpsZero, subs];
IF (i MOD pWellEach) = 0 THEN subs ← CONS [alpsPWell, subs];
ENDLOOP;
cellType ← PWCore.AbutList[subs, TRUE];
};
AlpsDecoderFullArrayList: PROC [nbBits: NAT, indexMin: NAT ← 0, indexSize: NAT ← 0, pWellEach: NAT ← 4] RETURNS [cellType: CellType] = {
indexSize=0 means in fact 2^nbBits
size: NATIF indexSize=0 THEN NAT[PW.TwoToThe[nbBits]] ELSE indexSize;
subs: LIST OF CellType ← NIL;
FOR i: NAT DECREASING IN [0 .. size) DO
subs ← CONS [AlpsDecoderLineList[nbBits, i + indexMin, pWellEach], subs];
ENDLOOP;
cellType ← PWCore.AbutList[subs, FALSE];
};
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: TilingClass.TileArray = NEW [TilingClass.TileArrayRec[1]];
tileRow: TilingClass.TileRow = NEW [TilingClass.TileRowRec[nbBits+2]];
tileRow[nbBits+1] ← NEW [TilingClass.TileRec ← [
type: alpsCascode, renaming: LIST [["Minus", "Output"], ["Vdd", "Vdd"]]
]];
tileRow[0] ← NEW [TilingClass.TileRec ← [
type: alpsPWell , renaming: LIST [["Gnd", "Gnd"]]
]];
tileArray[0] ← tileRow;
FOR i: NAT IN [0 .. nbBits) DO
tileRow[i+1] ← NEW [TilingClass.TileRec ← [
type: IF PW.XthBitOfN[i, index] THEN alpsOne ELSE alpsZero,
renaming: LIST [["Gnd", "Gnd"], ["Input", Index["Input", i]], ["NotInput", Index["NotInput", i]]]
]];
ENDLOOP;
cellType ← TilingClass.CreateTiling[
public: Wires[Seq[size: nbBits, name: "Input"], Seq[size: nbBits, name: "NotInput"], "Output", "Gnd", "Vdd"],
tileArray: tileArray,
neighborX: CustomNeighborInX,
neighborY: NIL
];
};
CustomNeighborInX: TilingClass.NeighborProc = {
publicPairs ← LIST [
[IF ct1=alpsPWell THEN "Plus" ELSE "PlusRight", IF ct2=alpsCascode THEN "Plus" ELSE "PlusLeft"],
["Minus", "Minus"]
];
};
AlpsDecoderFullArrayRowTiling: PROC [nbBits: NAT, indexMin: NAT ← 0, indexSize: NAT ← 0] RETURNS [cellType: CellType] = {
indexSize=0 means in fact 2^nbBits
size: NATIF indexSize=0 THEN NAT[PW.TwoToThe[nbBits]] ELSE indexSize;
tileArray: TilingClass.TileArray = NEW [TilingClass.TileArrayRec[size]];
FOR i: NAT IN [0 .. size) DO
tileRow: TilingClass.TileRow = NEW [TilingClass.TileRowRec[1]];
tileArray[i] ← tileRow;
tileRow[0] ← NEW [TilingClass.TileRec ← [
type: AlpsDecoderLineRowTiling[nbBits, i + indexMin],
renaming: LIST [["Gnd", "Gnd"], ["Vdd", "Vdd"], ["Input", "Input"], ["NotInput", "NotInput"], ["Output", Index["Output", i]]]
]];
ENDLOOP;
cellType ← TilingClass.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: TilingClass.NeighborProc = {};
Decoder with Tiling and standard NeighborProc
AlpsDecoderFullArrayTiling: PROC [nbBits: NAT, indexMin: NAT ← 0, indexSize: NAT ← 0] RETURNS [cellType: CellType] = {
indexSize=0 means in fact 2^nbBits
size: NATIF indexSize=0 THEN NAT[PW.TwoToThe[nbBits]] ELSE indexSize;
tileArray: TilingClass.TileArray = NEW [TilingClass.TileArrayRec[size]];
FOR i: NAT IN [0 .. size) DO
tileRow: TilingClass.TileRow = NEW [TilingClass.TileRowRec[nbBits+2]];
tileRow[nbBits+1] ← NEW [TilingClass.TileRec ← [
type: alpsCascode, renaming: LIST [["Minus", Index["Output", i]], ["Vdd", "Vdd"]]
]];
tileRow[0] ← NEW [TilingClass.TileRec ← [
type: alpsPWell, flatten: TRUE , renaming: LIST [["Gnd", "Gnd"]]
]];
FOR j: NAT IN [0 .. nbBits) DO
tileRow[j+1] ← NEW [TilingClass.TileRec ← [
type: IF PW.XthBitOfN[j, i] THEN alpsOne ELSE alpsZero,
flatten: TRUE,
renaming: LIST [["Gnd", "Gnd"], ["Input", Index["Input", j]], ["NotInput", Index["NotInput", j]]]
]];
ENDLOOP;
tileArray[i] ← tileRow;
ENDLOOP;
cellType ← TilingClass.CreateTiling[
public: Wires[Seq[size: nbBits, name: "Input"], Seq[size: nbBits, name: "NotInput"], Seq[size: size, name: "Output"], "Gnd", "Vdd"],
tileArray: tileArray,
neighborX: TilingClass.LayoutNeighborX,
neighborY: TilingClass.LayoutNeighborY,
name: "AlpsDecoderFullArrayTiling"
];
};
END.