CrossRAMDecoder.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Barth, November 7, 1985 5:44:29 pm PST
Louis Monier October 24, 1985 7:56:58 pm PDT
Bertrand Serlet November 20, 1985 7:42:20 pm PST
DIRECTORY Basics, CD, CDPinObjects, Core, CoreClasses, CoreCompose, CoreFlatten, CoreOps, CoreProperties, IO, PW, PWCore, PWPins, Rope, Rosemary, Sinix;
CrossRAMDecoder: CEDAR PROGRAM
IMPORTS Basics, CDPinObjects, CoreCompose, CoreFlatten, CoreProperties, IO, PW, PWCore, PWPins, Rope, Rosemary, Sinix =
BEGIN OPEN CoreCompose;
Wire: TYPE = Core.Wire;
rowQuads, addressDecoderBits: INT
Decoder: ROPE = RegisterStructureProc[name: "Decoder", proc: CreateDecoder];
CreateDecoder: StructureProc = {
rowQuads: INT ← GetInt[context, $rowQuads];
rowPairs: INT ← 2*rowQuads;
nRopesVdd: ROPE ← "Vdd";
nRopesGnd: ROPE ← "Gnd";
FOR row: INT IN (0 .. rowPairs) DO
nRopesVdd ← Rope.Cat[nRopesVdd, ", Vdd"];
ENDLOOP;
FOR row: INT IN (0 .. rowPairs) DO
nRopesGnd ← Rope.Cat[nRopesGnd, ", Gnd"];
ENDLOOP;
RegisterIntProperty[prop: $andDecoderBits];
RegisterIntProperty[prop: $rowPairs];
PushInt[context: context, prop: $andDecoderBits, val: GetInt[context, $addressDecoderBits]-1];
PushInt[context: context, prop: $rowPairs, val: rowPairs];
cellType ← CreateRecordCell[
name: Decoder,
context: context,
public: CreateWires[context, "Vdd, Gnd, VddLeft, VddMiddle, VddRight, GndLeft, GndMiddle, AccessB, AdrBit[seq: addressDecoderBits], nAdrBit[seq: addressDecoderBits], Word[seq: 4*rowQuads]"],
onlyInternal: CreateWires[context, "nDecode[seq: 2*rowQuads]"],
instances: LIST [
[type: CreateStructure[name: "DecoderLeftColumn", context: context]],
[type: CreateStructure[name: "DecoderAndPlane", context: context],
actual: IO.PutFR["Vdd: [%g], VddWell1: [%g], VddWell2: [%g], Gnd: [%g], AdrBit: AdrBit[start: 0, len: andDecoderBits], nAdrBit: nAdrBit[start: 0, len: andDecoderBits]", IO.rope[nRopesVdd], IO.rope[nRopesVdd], IO.rope[nRopesVdd], IO.rope[nRopesGnd]]],
[type: CreateStructure[name: "DecoderRightColumn", context: context], actual: IO.PutFR["Vdd: [%g]", IO.rope[nRopesVdd]]],
[type: CreateStructure[name: "DecoderLogicColumn", context: context],
actual: "Vdd: VddMiddle, Gnd: GndMiddle, TreeSelect: [AdrBit[addressDecoderBits-1], nAdrBit[addressDecoderBits-1]]"]
]
];
IF GetBool[context, $PWCore] THEN PWCore.SetAbutX[cellType: cellType];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};
andDecoderBits, row: INT
Ports: Vdd, Gnd, AdrBit[0..andDecoderBits), nAdrBit[0..andDecoderBits), nDecodeGnd, nDecodeVdd (the last 2 are to be connected later)
DecoderRow: ROPE = RegisterStructureProc[name: "DecoderRow", proc: CreateDecoderRow];
CreateDecoderRow: StructureProc = {
andDecoderBits: INT ← GetInt[context, $andDecoderBits];
row: INT ← GetInt[context, $row];
design: CD.Design ← NARROW[GetRef[context, $sourceCDDesign]];
dec0: PW.Object ← PW.Get[design, "DecoderZero"];
dec1: PW.Object ← PW.Get[design, "DecoderOne"];
DecoderSelect: PW.XYFunction ={
RenameEach: PWPins.ChangePinProc = {
name: ROPE ← CDPinObjects.GetName[oldPin];
SELECT TRUE FROM
Rope.Equal[name, "nDecodeGnd"] OR Rope.Equal[name, "nDecodeVdd"] OR Rope.Equal[name, "VddWell2"] OR Rope.Equal[name, "VddWell1"] OR Rope.Equal[name, "Vdd"] OR Rope.Equal[name, "Gnd"] => newPin ← PWPins.CopyInstance[oldPin];
Rope.Equal[name, "AdrBit"] OR Rope.Equal[name, "nAdrBit"] => {
newPin ← PWPins.CopyInstance[oldPin];
CDPinObjects.SetName[newPin, Rope.Cat[name, "[", IO.PutR[IO.int[x]], "]"]];
};
ENDCASE  => ERROR;
};
oddBit: BOOLPW.XthBitOfN[x, row];
resultingOb ← IF oddBit THEN dec1 ELSE dec0;
resultingOb ← PWPins.ChangePins[NIL, resultingOb, RenameEach];
};
actual: ROPE ← "Input: [";
FOR bit: INT IN [0 .. andDecoderBits) DO
actual ← Rope.Cat[actual, IO.PutFR["%gAdrBit[%g]", IO.rope[IF Basics.BITAND[Basics.BITSHIFT[row, bit-andDecoderBits+1], 1]#0 THEN NIL ELSE "n"], IO.int[bit]]];
IF bit<andDecoderBits-1 THEN actual ← Rope.Cat[actual, ", "];
ENDLOOP;
cellType ← CreateRecordCell[
name: DecoderRow,
context: context,
public: CreateWires[context, "Vdd, VddWell1, VddWell2, Gnd, AdrBit[seq: andDecoderBits], nAdrBit[seq: andDecoderBits], nDecodeGnd, nDecodeVdd"],
instances: LIST [
this one should be serie-transistor instead of NAND
[type: CreateStructure[name: "NAnd", context: context],
actual: Rope.Cat[actual, "], nOutput: nDecodeGnd"]],
this one should be parallel-transistor instead of NAND
[type: CreateStructure[name: "NAnd", context: context],
actual: Rope.Cat[actual, "], nOutput: nDecodeVdd"]]
]
];
IF GetBool[context, $PWCore] THEN PWCore.SetLayout[cellType, PWCore.LabelPins[cellType.public, PW.MapFunctionX[NIL, DecoderSelect, 0, andDecoderBits]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};
rowPairs, andDecoderBits: INT
Ports: Vdd, Gnd, AdrBit[0..andDecoderBits), nAdrBit[0..andDecoderBits), nDecode[0..rowPairs)
DecoderAndPlane: ROPE = RegisterStructureProc[name: "DecoderAndPlane", proc: CreateDecoderAndPlane];
CreateDecoderAndPlane: StructureProc = {
rowPairs: INT ← GetInt[context, $rowPairs];
andDecoderBits: INT ← GetInt[context, $andDecoderBits];
instances: InstanceList ← NIL;
RegisterIntProperty[prop: $row];
PushInt[context: context, prop: $SSIInputCount, val: GetInt[context, $andDecoderBits]];
PushInt[context: context, prop: $SSIWidth, val: 4];
PushReal[context: context, prop: $SSIRatio, val: 2.5];
FOR row: INT IN [0..rowPairs) DO-- decreasing?
PushInt[context: context, prop: $row, val: row];
instances ← CONS[
[actual: IO.PutFLR["Vdd: Vdd[%g], VddWell1: VddWell1[%g], VddWell2: VddWell2[%g], Gnd: Gnd[%g], nDecodeGnd: nDecode[%g], nDecodeVdd: nDecode[%g]", LIST [IO.int[row], IO.int[row], IO.int[row], IO.int[row], IO.int[row], IO.int[row]]],
type: CreateStructure[name: "DecoderRow", context: context]],
instances];
ENDLOOP;
cellType ← CreateRecordCell[
name: DecoderAndPlane,
context: context,
public: CreateWires[context,
"Vdd[seq: rowPairs], VddWell1[seq: rowPairs], VddWell2[seq: rowPairs], Gnd[seq: rowPairs], AdrBit[seq: andDecoderBits], nAdrBit[seq: andDecoderBits], nDecode[seq: rowPairs]"],
instances: instances];
IF GetBool[context, $PWCore] THEN PWCore.SetAbutFlipY[cellType: cellType, flip: FALSE];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};
Ports: Vdd, Gnd
DecoderLeftColumn: ROPE = RegisterStructureProc[name: "DecoderLeftColumn", proc: CreateDecoderLeftColumn];
CreateDecoderLeftColumn: StructureProc = {
cellType ← CreateSequenceCell[
name: DecoderLeftColumn,
baseCell: CreateStructure[name: DecoderLeftPair, context: context],
count: GetInt[context: context, prop: $rowQuads]];
IF GetBool[context, $PWCore] THEN PWCore.SetArrayY[cellType: cellType];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};
Ports: Vdd, Gnd
DecoderLeftPair: ROPE = RegisterStructureProc[name: "DecoderLeftPair", proc: CreateDecoderLeftPair];
CreateDecoderLeftPair: StructureProc = {
decoderLeft: Core.CellType ← CreateStructure[name: "DecoderLeft", context: context];
cellType ← CreateRecordCell[
name: DecoderLeftPair,
context: context,
public: CreateWires[context, "Vdd, Gnd"],
instances: LIST [
[type: decoderLeft],
[type: decoderLeft]]];
IF GetBool[context, $PWCore] THEN PWCore.SetAbutFlipY[cellType: cellType, flip: FALSE];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};
Ports: Vdd, Gnd
DecoderLeft: ROPE = RegisterStructureProc[name: "DecoderLeft", proc: CreateDecoderLeft];
CreateDecoderLeft: StructureProc = {
cellType ← CreateRecordCell[
name: DecoderLeft,
context: context,
public: CreateWires[context, "Vdd, Gnd"]];
IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};
Ports: Vdd, nDecode[0..2*rowQuads)
DecoderRightColumn: ROPE = RegisterStructureProc[name: "DecoderRightColumn", proc: CreateDecoderRightColumn];
CreateDecoderRightColumn: StructureProc = {
cellType ← CreateSequenceCell[
name: DecoderRightColumn,
baseCell: CreateStructure[name: "DecoderRightPair", context: context],
count: GetInt[context: context, prop: $rowQuads],
sequencePorts: "nDecode, Vdd"];
IF GetBool[context, $PWCore] THEN PWCore.SetArrayY[cellType: cellType];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};
Ports: Vdd, nDecode[0..2)
DecoderRightPair: ROPE = RegisterStructureProc[name: "DecoderRightPair", proc: CreateDecoderRightPair];
CreateDecoderRightPair: StructureProc = {
decoderRight: Core.CellType ← CreateStructure[name: "DecoderRight", context: context];
cellType ← CreateRecordCell[
name: DecoderRightPair,
context: context,
public: CreateWires[context, "Vdd[seq: 2], nDecode[seq: 2]"],
instances: LIST [
[actual: "Vdd: Vdd[0], nDecode: nDecode[0]",
type: decoderRight],
[actual: "Vdd: Vdd[1], nDecode: nDecode[1]",
type: decoderRight]]];
IF GetBool[context, $PWCore] THEN PWCore.SetAbutFlipY[cellType: cellType, flip: FALSE];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};
Ports: Vdd, nDecode
DecoderRight: ROPE = RegisterStructureProc[name: "DecoderRight", proc: CreateDecoderRight];
CreateDecoderRight: StructureProc = {
cellType ← CreateRecordCell[
name: DecoderRight,
context: context,
public: CreateWires[context, "Vdd, nDecode"]];
IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};
Ports: Vdd, Gnd, AccessB, TreeSelect[0..2), Word[0..4*rowQuads), nDecode[0..2*rowQuads)
DecoderLogicColumn: ROPE = RegisterStructureProc[name: "DecoderLogicColumn", proc: CreateDecoderLogicColumn];
CreateDecoderLogicColumn: StructureProc = {
cellType ← CreateSequenceCell[
name: DecoderLogicColumn,
baseCell: CreateStructure[name: DecoderLogicPair, context: context],
count: GetInt[context: context, prop: $rowQuads],
sequencePorts: "nDecode, Word"];
IF GetBool[context, $PWCore] THEN PWCore.SetArrayY[cellType: cellType];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};
Ports: Vdd, Gnd, AccessB, TreeSelect[0..2), Word[0..4), nDecode[0..2)
DecoderLogicPair: ROPE = RegisterStructureProc[name: "DecoderLogicPair", proc: CreateDecoderLogicPair];
CreateDecoderLogicPair: StructureProc = {
decoderLogic: Core.CellType ← CreateStructure[name: "DecoderLogic", context: context];
data: CoreClasses.RecordCellType;
cellType ← CreateRecordCell[
name: DecoderLogicPair,
context: context,
public: CreateWires[context, "VddLeft, Vdd, VddRight, GndLeft, Gnd, AccessB, TreeSelect[seq: 2], nDecode[seq: 2], Word[seq: 4]"],
instances: LIST [
[actual: "Word: Word[start: 0, len: 2], nDecode: nDecode[0]",
type: decoderLogic],
[actual: "Word: Word[start: 2, len: 2], nDecode: nDecode[1]",
type: decoderLogic]]];
data ← NARROW [cellType.data];
IF GetBool[context, $PWCore] THEN PWCore.SetAbutFlipY[cellType: cellType, flip: FALSE];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};
Ports: Vdd, Gnd, AccessB, TreeSelect[0..2), Word[0..2), nDecode
DecoderLogic: ROPE = RegisterStructureProc[name: "DecoderLogic", proc: CreateDecoderLogic];
CreateDecoderLogic: StructureProc = {
cellType ← CreateSequenceCell[
name: DecoderLogic,
baseCell: CreateStructure[name: WordDriver, context: context],
count: 2,
sequencePorts: "TreeSelect, Word"];
IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};
Ports: Vdd, Gnd, AccessB, TreeSelect, Word, nDecode
WordDriver: ROPE = RegisterStructureProc[name: "WordDriver", proc: CreateWordDriver];
CreateWordDriver: StructureProc = {
instances: InstanceList ← LIST [
[actual: "gate: TreeSelect, ch1: nDecode, ch2: nTreeDecode",
type: CreateTransistor[name: "Transistor", type: nE]],
[actual: "gate: TreeSelect, ch1: Vdd, ch2: nTreeDecode",
type: CreateTransistor[name: "Transistor", type: pE]]];
PushInt[context: context, prop: $SSIInputCount, val: 2];
PushInt[context: context, prop: $SSIWidth, val: 4];
PushReal[context: context, prop: $SSIRatio, val: 2.5];
instances ← CONS[[
actual: "Input: nTreeDecode, Output: Decode",
type: CreateStructure[name: "Inverter", context: context]], instances];
instances ← CONS[[
actual: "Input: [AccessB, Decode], Output: Word",
type: CreateStructure[name: "And", context: context]], instances];
cellType ← CreateRecordCell[
name: WordDriver,
context: context,
public: CreateWires[context, "VddLeft, Vdd, VddRight, GndLeft, Gnd, AccessB, TreeSelect, Word, nDecode"],
onlyInternal: CreateWires[context, "nTreeDecode, Decode"],
instances: instances];
IF GetBool[context, $Rosemary] THEN Rosemary.Bind[cellType: cellType, roseClassName: WordDriverRoseClass];
CoreProperties.PutCellTypeProp[on: cellType, prop: CoreFlatten.CoreFlattenCutSets, value: LIST["JustAboveTransistors"]];
};
WordDriverRoseClass: ROPE = Rosemary.Register[roseClassName: WordDriver, init: WordDriverInit, evalSimple: WordDriverSimple];
VddLeft: NAT = 0;
Vdd: NAT = 1;
VddRight: NAT = 2;
GndLeft: NAT = 3;
Gnd: NAT = 4;
AccessB: NAT = 5;
TreeSelect: NAT = 6;
Word: NAT = 7;
nDecode: NAT = 8;
WordDriverInit: Rosemary.InitProc = {
FOR port: NAT IN [0..p.size) DO
p[port].type ← b;
ENDLOOP;
p[Word].d ← drive;
};
WordDriverSimple: Rosemary.EvalProc = {
IF NOT p[VddLeft].b OR NOT p[Vdd].b OR NOT p[VddRight].b THEN SIGNAL Rosemary.Stop[];
IF p[GndLeft].b OR p[Gnd].b THEN SIGNAL Rosemary.Stop[];
p[Word].b ← p[TreeSelect].b AND p[AccessB].b AND NOT p[nDecode].b;
};
END.