CrossRAMTop.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Barth, November 7, 1985 4:51:50 pm PST
Louis Monier October 25, 1985 12:09:38 pm PDT
Bertrand Serlet December 6, 1985 2:07:19 pm PST
DIRECTORY Basics, CD, Core, CoreBeau, CoreClasses, CoreCompose, CoreOps, IO, PWCore, Rope, Sinix;
CrossRAMTop: CEDAR PROGRAM
IMPORTS Basics, CoreBeau, CoreCompose, CoreOps, PWCore, Sinix =
BEGIN OPEN CoreCompose;
addressBits, addressDecoderBits, columnOcts, select, log2Select: NAT
CrossRAMTop: ROPE = RegisterStructureProc[name: "CrossRAMTop", proc: CreateCrossRAMTop];
CreateCrossRAMTop: StructureProc = {
addressBits: INT ← GetInt[context, $addressBits];
addressDecoderBits: INT ← GetInt[context, $addressDecoderBits];
columnOcts: INT ← GetInt[context, $columnOcts];
select: INT ← GetInt[context, $select];
log2Select: INT ← GetInt[context, $log2Select];
driverPairCount: INT ← (addressBits-log2Select)/2;
PushInt[context, $driverPairCount, driverPairCount];
cellType ← CreateRecordCell[
name: CrossRAMTop,
context: context,
public: CreateWires[context, "VddLeft, VddRight, Gnd, WriteB, nWriteB, ReadB, nReadB,
AddressB[seq: addressBits],
DataB[seq: columnOcts],
AdrBit[seq: addressDecoderBits], nAdrBit[seq: addressDecoderBits],
Bit[seq: select*columnOcts], nBit[seq: select*columnOcts]"],
onlyInternal: CreateWires[context, "VddHigh, GndHigh, Select[seq: select]"],
instances: LIST [
[type: DecoderDriverLeft[context: context, log2Select: log2Select],
actual: "Vdd: VddLeft, AddressB: AddressB[start: 0, len: log2Select]"],
[type: DecoderDriverSequence[context: context, log2Select: log2Select, driverPairCount: driverPairCount],
actual: "Vdd: VddLeft, VddTop: VddLeft, VddHigh: VddLeft, GndHigh: Gnd, LowAddressB: AddressB[start: 0, len: log2Select], HighAddressB: AddressB[start: log2Select, len: addressBits-log2Select]"],
[type: DecoderLogicDriver[context: context, select: select, log2Select: log2Select],
actual: "Vdd: VddLeft, AddressB: AddressB[start: 0, len: log2Select], AdrBit: AdrBit[addressDecoderBits-1], nAdrBit: nAdrBit[addressDecoderBits-1]"],
[type: CreateStructure[name: "DataBuffer", context: context], actual: "Vdd: VddRight"],
[type: DataBufferRight[context: context], actual: "Vdd: VddRight"]
]
];
IF GetBool[context, $PWCore] THEN PWCore.SetAbutX[cellType: cellType];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
Ports: Vdd, AddressB[0..log2Select)
DecoderDriverLeft: PROC [context: CoreCompose.Context, log2Select: INT] RETURNS [cellType: CellType] = {
cellType ← CoreBeau.Cell[
name: "DecoderDriverLeft",
public: CoreBeau.Wires["Vdd", "Gnd", CoreBeau.Seq["AddressB", log2Select]],
instances: NIL
];
IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
DecoderDriverSequence: PROC [context: CoreCompose.Context, log2Select, driverPairCount: INT] RETURNS [cellType: CellType] = {
driverCount: INT ← 2*driverPairCount;
MakeStackPA: PROC [base: ROPE] RETURNS [pa: CoreBeau.PA] = {
pa ← [public: base, actual: CoreBeau.Indexes[wr: base, length: driverCount-2]];
};
MakePairPA: PROC [base: ROPE] RETURNS [pa: CoreBeau.PA] = {
pa ← [public: base, actual: CoreBeau.Indexes[wr: base, start: driverCount-2, length: 2]];
};
cellType ← CoreBeau.Cell[
name: "DecoderDriverSequence",
public: CoreBeau.Wires["Vdd", "Gnd", "VddTop", "VddHigh", "GndHigh", CoreBeau.Seq["LowAddressB", log2Select], CoreBeau.Seq["HighAddressB", driverCount], CoreBeau.Seq["AdrBit", driverCount], CoreBeau.Seq["nAdrBit", driverCount]],
instances: LIST [
CoreBeau.Instance[
DecoderDriverStackBitSeq[context: context, log2Select: log2Select, driverPairCount: driverPairCount],
MakeStackPA["HighAddressB"], MakeStackPA["AdrBit"], MakeStackPA["nAdrBit"]
],
CoreBeau.Instance[
DecoderDriverTreeBit[context: context, log2Select: log2Select],
MakePairPA["HighAddressB"], MakePairPA["AdrBit"], MakePairPA["nAdrBit"]
]
]
];
IF GetBool[context, $PWCore] THEN PWCore.SetAbutX[cellType: cellType];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
DecoderDriverStackBitSeq: PROC [context: CoreCompose.Context, log2Select, driverPairCount: INT] RETURNS [cellType: CellType] = {
cellType ← CoreBeau.SequenceCell[
name: "DecoderDriverStackBitSeq",
baseCell: DecoderDriverStackBit[context: context, log2Select: log2Select],
count: driverPairCount-1,
sequencePorts: CoreBeau.Wires["HighAddressB", "AdrBit", "nAdrBit"]];
IF GetBool[context, $PWCore] THEN PWCore.SetArrayX[cellType: cellType];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
DecoderDriverStackBit: PROC [context: CoreCompose.Context, log2Select: INT] RETURNS [cellType: CellType] = {
decoderDriver: Core.CellType ← DecoderDriver[context: context, log2Select: log2Select];
cellType ← CoreBeau.Cell[
name: "DecoderDriverStackBit",
public: CoreOps.CopyWire[decoderDriver.public],
instances: LIST [CoreBeau.Instance[decoderDriver]]];
IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
DecoderDriverTreeBit: PROC [context: CoreCompose.Context, log2Select: INT] RETURNS [cellType: CellType] = {
decoderDriver: Core.CellType ← DecoderDriver[context: context, log2Select: log2Select];
cellType ← CoreBeau.Cell[
name: "DecoderDriverTreeBit",
public: CoreOps.CopyWire[decoderDriver.public],
instances: LIST [CoreBeau.Instance[decoderDriver]]];
IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
Ports: Vdd, Gnd, LowAddressB[0..log2Select), HighAddressB[0..2), AdrBit[0..2), nAdrBit[0..2),
DecoderDriverCellType: Core.CellType;
DecoderDriver: PROC [context: CoreCompose.Context, log2Select: INT] RETURNS [cellType: CellType] = {
IF DecoderDriverCellType#NIL THEN RETURN[DecoderDriverCellType];
DecoderDriverCellType ← cellType ← CoreBeau.SequenceCell[
name: "DecoderDriver",
baseCell: DecoderDriverHalf[context: context, log2Select: log2Select],
count: 2,
sequencePorts: CoreBeau.Wires["HighAddressB", "AdrBit", "nAdrBit"]];
};
DecoderDriverHalf: PROC [context: CoreCompose.Context, log2Select: INT] RETURNS [cellType: CellType] = {
inverter4, inverter16: Core.CellType;
PushReal[context: context, prop: $SSIRatio, val: 2.5];
PushInt[context: context, prop: $SSIWidth, val: 4];
inverter4 ← CreateStructure[name: "Inverter", context: context];
PushInt[context: context, prop: $SSIWidth, val: 16];
inverter16 ← CreateStructure[name: "Inverter", context: context];
cellType ← CoreBeau.Cell[
name: "DecoderDriverHalf",
public: CoreBeau.Wires["Vdd", "Gnd", "VddTop", "VddHigh", "GndHigh", "HighAddressB", "AdrBit", "nAdrBit", CoreBeau.Seq["LowAddressB", log2Select]],
onlyInternal: CoreBeau.Wires["nAddress"],
instances: LIST [
CoreBeau.Instance[inverter4, ["Vdd", "VddHigh"], ["Gnd", "GndHigh"], ["Input", "HighAddressB"], ["Output", "nAddress"]],
CoreBeau.Instance[inverter16, ["Input", "nAddress"], ["Output", "AdrBit"]],
CoreBeau.Instance[inverter16, ["Input", "HighAddressB"], ["Output", "nAdrBit"]]
]];
};
DecoderLogicDriver: PROC [context: CoreCompose.Context, select, log2Select: INT] RETURNS [cellType: CellType] = {
invert8: Core.CellType;
and: Core.CellType; -- inputCount: log2Select, width: 16
instances: LIST OF CoreClasses.CellInstance ← NIL; -- fill in!
PushReal[context: context, prop: $SSIRatio, val: 2.5];
PushInt[context: context, prop: $SSIWidth, val: 8];
invert8 ← CreateStructure[name: "Inverter", context: context];
PushInt[context: context, prop: $SSIWidth, val: 16];
PushInt[context: context, prop: $SSIInputCount, val: log2Select];
and ← CreateStructure[name: "And", context: context];
-- Drop three inverters
FOR adrBit: INT IN [0 .. log2Select) DO
instances ← CONS [
CoreBeau.Instance[
invert8,
["Input", CoreBeau.Index["AddressB", adrBit]],
["Output", CoreBeau.Index["nHighAddressB", adrBit]]
],
instances];
ENDLOOP;
-- Drop eight nand gates
FOR sel: INT IN [0 .. select) DO
bind: LIST OF CoreBeau.WRNIL;
FOR adrBit: INT DECREASING IN [0 .. log2Select) DO
bind ← CONS [
CoreBeau.Index[
IF Basics.BITAND[Basics.BITSHIFT[sel, adrBit-log2Select+1], 1]#0 THEN "AddressB" ELSE "nHighAddressB",
adrBit],
bind];
ENDLOOP;
instances ← CONS [
CoreBeau.Instance[
and,
["Input", CoreBeau.WireList[bind]],
["Output", CoreBeau.Index["Select", sel]]
],
instances];
ENDLOOP;
cellType ← CoreBeau.Cell[
name: "DecoderLogicDriver",
public: CoreBeau.Wires["Vdd", "Gnd", "AdrBit", "nAdrBit", CoreBeau.Seq["AddressB", log2Select], CoreBeau.Seq["Select", select]],
onlyInternal: CoreBeau.Wires[CoreBeau.Seq["nHighAddressB", log2Select]],
instances: instances
];
IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
DataBufferRight: PROC [context: CoreCompose.Context] RETURNS [cellType: CellType] = {
cellType ← CoreBeau.Cell[
name: "DataBufferRight",
public: CoreBeau.Wires["Vdd", "WriteB", "nWriteB", "ReadB", "nReadB"],
instances: NIL
];
IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
RegisterIntProperty[prop: $driverPairCount];
END.