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 November 21, 1985 4:40:58 pm PST
DIRECTORY Basics, CD, Core, CoreClasses, CoreCompose, CoreOps, IO, PWCore, Rope, Sinix;
CrossRAMTop: CEDAR PROGRAM
IMPORTS Basics, CoreCompose, CoreOps, IO, PWCore, Rope, 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];
PushInt[context, $driverPairCount, (addressBits-log2Select)/2];
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: CreateStructure[name: DecoderDriverLeft, context: context],
actual: "Vdd: VddLeft, AddressB: AddressB[start: 0, len: log2Select]"],
[type: CreateStructure[name: DecoderDriverSequence, context: context],
actual: "Vdd: VddLeft, VddTop: VddLeft, VddHigh: VddLeft, GndHigh: Gnd, LowAddressB: AddressB[start: 0, len: log2Select], HighAddressB: AddressB[start: log2Select, len: addressBits-log2Select]"],
[type: CreateStructure[name: DecoderLogicDriver, context: context],
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: CreateStructure[name: DataBufferRight, context: context], actual: "Vdd: VddRight"]
]
];
IF GetBool[context, $PWCore] THEN PWCore.SetAbutX[cellType: cellType];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};
Ports: Vdd, AddressB[0..log2Select)
DecoderDriverLeft: ROPE = RegisterStructureProc[name: "DecoderDriverLeft", proc: CreateDecoderDriverLeft];
CreateDecoderDriverLeft: StructureProc = {
cellType ← CreateRecordCell[
name: DecoderDriverLeft,
context: context,
public: CreateWires[context, "Vdd, Gnd, AddressB[seq: log2Select]"]];
IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};
DecoderDriverSequence: ROPE = RegisterStructureProc[name: "DecoderDriverSequence", proc: CreateDecoderDriverSequence];
CreateDecoderDriverSequence: StructureProc = {
driverCount: INT ← 2*GetInt[context, $driverPairCount];
MakeStackRope: PROC [base: ROPE] RETURNS [ROPE] = {
RETURN[IO.PutFR["%g: %g[start:0, len:%g]", IO.rope[base], IO.rope[base], IO.int[driverCount-2]]];};
MakePairRope: PROC [base: ROPE] RETURNS [ROPE] = {
RETURN[IO.PutFR["%g: %g[start:%g, len:2]", IO.rope[base], IO.rope[base], IO.int[driverCount-2]]];};
cellType ← CreateRecordCell[
name: DecoderDriverSequence,
context: context,
public: CreateWires[context,
"Vdd, Gnd, VddTop, VddHigh, GndHigh,
LowAddressB[seq: log2Select],
HighAddressB[seq: 2*driverPairCount],
AdrBit[seq: 2*driverPairCount], nAdrBit[seq: 2*driverPairCount]"],
instances: LIST [
[type: CreateStructure[name: DecoderDriverStackBitSeq, context: context],
actual: Rope.Cat[MakeStackRope["HighAddressB"], ", ", MakeStackRope["AdrBit"], ", ", MakeStackRope["nAdrBit"]]],
[type: CreateStructure[name: DecoderDriverTreeBit, context: context],
actual: Rope.Cat[MakePairRope["HighAddressB"], ", ", MakePairRope["AdrBit"], ", ", MakePairRope["nAdrBit"]]]
]
];
IF GetBool[context, $PWCore] THEN PWCore.SetAbutX[cellType: cellType];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};
DecoderDriverStackBitSeq: ROPE = RegisterStructureProc[name: "DecoderDriverStackBitSeq", proc: CreateDecoderDriverStackBitSeq];
CreateDecoderDriverStackBitSeq: StructureProc = {
cellType ← CreateSequenceCell[
name: DecoderDriverStackBitSeq,
baseCell: CreateStructure[name: DecoderDriverStackBit, context: context],
count: GetInt[context: context, prop: $driverPairCount]-1,
sequencePorts: "HighAddressB, AdrBit, nAdrBit"];
IF GetBool[context, $PWCore] THEN PWCore.SetArrayX[cellType: cellType];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};
DecoderDriverStackBit: ROPE = RegisterStructureProc[name: "DecoderDriverStackBit", proc: CreateDecoderDriverStackBit];
CreateDecoderDriverStackBit: StructureProc = {
decoderDriver: Core.CellType ← CreateStructure[name: DecoderDriver, context: context];
cellType ← CreateRecordCell[
name: DecoderDriverStackBit,
context: context,
public: CoreOps.CopyWire[decoderDriver.public],
instances: LIST [[type: decoderDriver]]];
IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};
DecoderDriverTreeBit: ROPE = RegisterStructureProc[name: "DecoderDriverTreeBit", proc: CreateDecoderDriverTreeBit];
CreateDecoderDriverTreeBit: StructureProc = {
decoderDriver: Core.CellType ← CreateStructure[name: DecoderDriver, context: context];
cellType ← CreateRecordCell[
name: DecoderDriverTreeBit,
context: context,
public: CoreOps.CopyWire[decoderDriver.public],
instances: LIST [[type: decoderDriver]]];
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, LowAddressB[0..log2Select), HighAddressB[0..2), AdrBit[0..2), nAdrBit[0..2),
DecoderDriver: ROPE = RegisterStructureProc[name: "DecoderDriver", proc: CreateDecoderDriver];
DecoderDriverCellType: Core.CellType;
CreateDecoderDriver: StructureProc = {
IF DecoderDriverCellType#NIL THEN RETURN[DecoderDriverCellType];
DecoderDriverCellType ← cellType ← CreateSequenceCell[
name: DecoderDriver,
baseCell: CreateStructure[name: DecoderDriverHalf, context: context],
count: 2,
sequencePorts: "HighAddressB, AdrBit, nAdrBit"];
};
DecoderDriverHalf: ROPE = RegisterStructureProc[name: "DecoderDriverHalf", proc: CreateDecoderDriverHalf];
CreateDecoderDriverHalf: StructureProc = {
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 ← CreateRecordCell[
name: DecoderDriverHalf,
context: context,
public: CreateWires[context, "Vdd, Gnd, VddTop, VddHigh, GndHigh, HighAddressB, AdrBit, nAdrBit, LowAddressB[seq: log2Select]"],
onlyInternal: CreateWires[context, "nAddress"],
instances: LIST [
[actual: "Vdd: VddHigh, Gnd: GndHigh, Input: HighAddressB, Output: nAddress",
type: inverter4],
[actual: "Input: nAddress, Output: AdrBit",
type: inverter16],
[actual: "Input: HighAddressB, Output: nAdrBit",
type: inverter16]]];
};
DecoderLogicDriver: ROPE = RegisterStructureProc[name: "DecoderLogicDriver", proc: CreateDecoderLogicDriver];
CreateDecoderLogicDriver: StructureProc = {
select: INT ← GetInt[context, $select];
log2Select: INT ← GetInt[context, $log2Select];
invert8: Core.CellType;
and: Core.CellType; -- inputCount: log2Select, width: 16
instances: InstanceList ← 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[[type: invert8, actual: IO.PutFR["Input: AddressB[%g], Output: nHighAddressB[%g]", IO.int[adrBit], IO.int[adrBit]]], instances];
ENDLOOP;
-- Drop eight nand gates
FOR sel: INT IN [0..select) DO
bind: ROPENIL;
FOR adrBit: INT IN [0..log2Select) DO
bind ← Rope.Cat[bind, IF Basics.BITAND[Basics.BITSHIFT[sel, adrBit-log2Select+1], 1]#0 THEN IO.PutFR["AddressB[%g]", IO.int[adrBit]] ELSE IO.PutFR["nHighAddressB[%g]", IO.int[adrBit]]];
IF adrBit < log2Select-1 THEN bind ← Rope.Cat[bind, ", "];
ENDLOOP;
instances ← CONS[[type: and, actual: IO.PutFR["Input: [%g], Output: Select[%g]", IO.rope[bind], IO.int[sel]]], instances];
ENDLOOP;
cellType ← CreateRecordCell[
name: DecoderLogicDriver,
context: context,
public: CreateWires[context, "Vdd, Gnd, AdrBit, nAdrBit, AddressB[seq: log2Select], Select[seq: select]"],
onlyInternal: CreateWires[context, "nHighAddressB[seq: log2Select]"],
instances: instances];
IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};
DataBufferRight: ROPE = RegisterStructureProc[name: "DataBufferRight", proc: CreateDataBufferRight];
CreateDataBufferRight: StructureProc = {
cellType ← CreateRecordCell[
name: DataBufferRight,
context: context,
public: CreateWires[context, "Vdd, WriteB, nWriteB, ReadB, nReadB"]];
IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.ExtractObj[PWCore.GetLayout[cellType]];
};
RegisterIntProperty[prop: $driverPairCount];
END.