CrossRAMDataBuffer.mesa
Copyright © 1985 by Xerox Corporation. All rights reservedSinix.Extract
Barth, November 7, 1985 4:41:32 pm PST
Louis Monier October 28, 1985 8:34:19 am PST
Bertrand Serlet December 6, 1985 5:04:44 pm PST
DIRECTORY CD, CDSymbolicObjects, Convert, CoreClasses, CoreCompose, CoreFlatten, CoreProperties, IO, PW, PWCore, PWPins, Rope, Rosemary, Sinix;
CrossRAMDataBuffer: CEDAR PROGRAM
IMPORTS CDSymbolicObjects, Convert, CoreCompose, CoreFlatten, CoreProperties, IO, PW, PWCore, PWPins, Rope, Rosemary, Sinix =
BEGIN OPEN CoreCompose;
Ports: Vdd, Gnd, WriteB, nWriteB, ReadB, nReadB, DataB[SEQ: columnOcts], Select[SEQ: select], Bit[SEQ: columnOcts*select], nBit[SEQ: columnOcts*select]
DataBuffer: ROPE = RegisterStructureProc[name: "DataBuffer", proc: CreateDataBuffer];
CreateDataBuffer: StructureProc = {
columnOcts: INT ← GetInt[context, $columnOcts];
cellType ← CreateSequenceCell[
name: DataBuffer,
baseCell: CreateStructure[name: "DataBufferBit", context: context],
count: columnOcts,
sequencePorts: "Bit, nBit, DataB"];
IF GetBool[context, $PWCore] THEN PWCore.SetArrayX[cellType: cellType];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
DataBufferBit: ROPE = RegisterStructureProc[name: "DataBufferBit", proc: CreateDataBufferBit];
CreateDataBufferBit: StructureProc = {
cellType ← CreateRecordCell[
name: DataBufferBit,
context: context,
public: CreateWires[context,
"Vdd, Gnd, WriteB, nWriteB, ReadB, nReadB, DataB,
Select[SEQ:select], Bit[SEQ:select], nBit[SEQ:select]"],
instances: LIST [
[type: CreateStructure[name: "DataBufferOct", context: context], actual: "GndLow: Gnd"],
[type: CreateStructure[name: "DecoderStitch", context: context]]
]];
IF GetBool[context, $PWCore] THEN PWCore.SetAbutX[cellType: cellType];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
IF GetBool[context, $Rosemary] THEN Rosemary.Bind[cellType: cellType, roseClassName: DataBufferBitRoseClass];
CoreProperties.PutCellTypeProp[on: cellType, prop: CoreFlatten.CoreFlattenCutSets, value: LIST["JustAboveTransistors"]];
};
DataBufferBitRoseClass: ROPE = Rosemary.Register[roseClassName: DataBufferBit, init: DataBufferBitInit, evalSimple: DataBufferBitSimple];
Vdd: NAT = 0;
Gnd: NAT = 1;
WriteB: NAT = 2;
nWriteB: NAT = 3;
ReadB: NAT = 4;
nReadB: NAT = 5;
DataB: NAT = 6;
Select: NAT = 7;
Bit: NAT = 8;
nBit: NAT = 9;
DataBufferBitInit: Rosemary.InitProc = {
p[Vdd].type ← b;
p[Gnd].type ← b;
p[WriteB].type ← b;
p[nWriteB].type ← b;
p[ReadB].type ← b;
p[nReadB].type ← b;
p[DataB].type ← b;
FOR port: NAT IN [0..p[Select].size) DO
p[Select][port].type ← b;
ENDLOOP;
FOR port: NAT IN [0..p[Bit].size) DO
p[Bit][port].type ← b;
ENDLOOP;
FOR port: NAT IN [0..p[nBit].size) DO
p[nBit][port].type ← b;
ENDLOOP;
};
DataBufferBitSimple: Rosemary.EvalProc = {
someSelect: BOOLFALSE;
whichSelect: NAT;
write: BOOL ← p[WriteB].b OR NOT p[nWriteB].b;
read: BOOL ← p[ReadB].b OR NOT p[nReadB].b;
FOR port: NAT IN [0..p[Select].size) DO
p[Bit][port].d ← none;
p[nBit][port].d ← none;
IF p[Select][port].b THEN {
IF (read OR write) AND someSelect THEN SIGNAL Rosemary.Stop[];
someSelect ← TRUE;
whichSelect ← port;
};
ENDLOOP;
IF NOT p[Vdd].b OR p[Gnd].b OR (write AND read) THEN SIGNAL Rosemary.Stop[];
IF write AND someSelect THEN {
p[Bit][whichSelect].d ← IF (p[DataB].b AND NOT p[nWriteB].b) OR (NOT p[DataB].b AND p[WriteB].b) THEN drive ELSE none;
p[nBit][whichSelect].d ← IF (p[DataB].b AND p[WriteB].b) OR (NOT p[DataB].b AND NOT p[nWriteB].b) THEN drive ELSE none;
p[Bit][whichSelect].b ← p[DataB].b;
p[nBit][whichSelect].b ← NOT p[DataB].b;
};
p[DataB].d ← none;
IF read THEN {
IF someSelect THEN {
p[DataB].d ← IF (p[nBit][whichSelect].b AND p[ReadB].b) OR (NOT p[nBit][whichSelect].b AND NOT p[nReadB].b) THEN drive ELSE none;
p[DataB].b ← NOT p[nBit][whichSelect].b;
}
ELSE {
p[DataB].b ← FALSE;
p[DataB].d ← drive;
};
};
};
DataBufferOct: ROPE = RegisterStructureProc[name: "DataBufferOct", proc: CreateDataBufferOct];
CreateDataBufferOct: StructureProc = {
onlyInternal: Wire ← CreateWires[context, "Buffer, nBuffer"];
cellType ← CreateRecordCell[
name: DataBufferOct,
context: context,
public: CreateWires[context,
"Vdd, Gnd, GndLow, WriteB, nWriteB, ReadB, nReadB, DataB,
Select[SEQ: select], Bit[SEQ: select], nBit[SEQ: select]"],
onlyInternal: onlyInternal,
instances: LIST [
[type: CreateStructure[name: "BitLineConnectSeq", context: context], actual: "Gnd: GndLow"],
[type: CreateStructure[name: "DataBufferMux", context: context]],
[type: CreateStructure[name: "DataBufferMuxBit", context: context]],
[type: CreateStructure[name: "BitDrive", context: context]]
]];
BS: We need the following to avoid nBuffer and Buffer pins that inadvertantly cross the boundary of the cell to mismatch in PWCore, since they are not part of the public
IF GetBool[context, $PWCore] THEN PWCore.SetLayout[cellType, PWCore.HidePins[onlyInternal, PW.AbutListY[NIL, PWCore.GateWays[cellType]]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
Ports: Gnd, Bit[SEQ: select], nBit[SEQ: select]
BitLineConnectSeq: ROPE = RegisterStructureProc[name: "BitLineConnectSeq", proc: CreateBitLineConnectSeq];
CreateBitLineConnectSeq: StructureProc = {
select: INT ← GetInt[context, $select];
cellType ← CreateSequenceCell[
name: BitLineConnectSeq,
baseCell: CreateStructure[name: "BitLineConnect", context: context],
count: select,
sequencePorts: "Bit, nBit"];
IF GetBool[context, $PWCore] THEN PWCore.SetArrayX[cellType: cellType];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
BitLineConnect: ROPE = RegisterStructureProc[name: "BitLineConnect", proc: CreateBitLineConnect];
CreateBitLineConnect: StructureProc = {
cellType ← CreateRecordCell[
name: BitLineConnect,
context: context,
public: CreateWires[context, "Gnd, Bit, nBit"]];
IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
DataBufferMux : ROPE = RegisterStructureProc[name: "DataBufferMux", proc: CreateDataBufferMux];
CreateDataBufferMux: StructureProc = {
select: INT ← GetInt[context, $select];
DataBufferMuxLayout: PROC[] RETURNS [obj: PW.Object] = {
Rename: PWPins.ChangePinProc = {
oldRope: ROPE ← CDSymbolicObjects.GetName[oldPin];
newPin ← PWPins.CopyInstance[oldPin];
IF Rope.Match["VSelect[*]", oldRope] AND PWPins.GetSide[obj, oldPin]=top
THEN CDSymbolicObjects.SetName[newPin, IO.PutFR["Select[%g]", IO.int[Convert.IntFromRope[Rope.Substr[oldRope, 8, Rope.Length[oldRope]-9]]]]];
IF Rope.Match["Select[*]", oldRope] AND PWPins.GetSide[obj, oldPin]=top
THEN CDSymbolicObjects.SetName[newPin, IO.PutFR["Select[%g]", IO.int[select-1]]];
};
DataBufferMuxSelect: PW.XYFunction ={
resultingOb ← SELECT TRUE FROM
y<x => BitSelNoPoly,
y=x => BitSelContact,
y>x => BitSelPoly,
ENDCASE => ERROR;
};
design: CD.Design ← NARROW[GetRef[context, $sourceCDDesign]];
BitSelNoPoly: PW.Object ← PW.Get[design, "BitSelNoPoly"];
BitSelContact: PW.Object ← PW.Get[design, "BitSelContact"];
BitSelPoly: PW.Object ← PW.Get[design, "BitSelPoly"];
obj ← PW.MapFunctionIndexPins[NIL, DataBufferMuxSelect, 0, select, 0, select, [bottom: LIST["Bit", "nBit"], top: LIST["VSelect", "Select", "Bit", "nBit"], left: LIST["Select"], right: LIST["Select"]]];
obj ← PWPins.ChangePins[NIL, obj, Rename];
};
cellType ← CreateRecordCell[
name: DataBufferMux,
context: context,
public: CreateWires[context, "Select[seq: select], Bit[seq: select], nBit[seq: select]"]
];
IF GetBool[context, $PWCore] THEN PWCore.SetLayout[cellType, PWCore.LabelPins[cellType.public, DataBufferMuxLayout[]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
DataBufferMuxBit: ROPE = RegisterStructureProc[name: "DataBufferMuxBit", proc: CreateDataBufferMuxBit];
CreateDataBufferMuxBit: StructureProc = {
select: INT ← GetInt[context, $select];
cellType ← CreateRecordCell[
name: DataBufferMuxBit,
context: context,
public: CreateWires[context, "Buffer, nBuffer, Select[seq: select], Bit[seq: select], nBit[seq: select]"],
instances: LIST [
[type: CreateStructure[name: BitMuxEnd, context: context],
actual: "Select: Select[0], Bit: Bit[0], nBit: nBit[0]"],
[type: CreateStructure[name: BitMuxSeq, context: context],
actual: "Select: Select[start: 1, len: select-1], Bit: Bit[start: 1, len: select-1], nBit: nBit[start: 1, len: select-1]"]]];
IF GetBool[context, $PWCore] THEN PWCore.SetAbutX[cellType: cellType];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
Following is copy if BitMuxBit, need to fix this
BitMuxEnd: ROPE = RegisterStructureProc[name: "BitMuxEnd", proc: CreateBitMuxEnd];
CreateBitMuxEnd: StructureProc = {
cellType ← CreateRecordCell[
name: BitMuxEnd,
context: context,
public: CreateWires[context, "Select, Bit, nBit, Buffer, nBuffer"],
instances: LIST [
[type: CreateTransistor[name: "Transistor", type: nE],
actual: "gate: Select, ch1: Bit, ch2: Buffer"],
[type: CreateTransistor[name: "Transistor", type: nE],
actual: "gate: Select, ch1: nBit, ch2: nBuffer"]]
];
IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
BitMuxSeq: ROPE = RegisterStructureProc[name: "BitMuxSeq", proc: CreateBitMuxSeq];
CreateBitMuxSeq: StructureProc = {
select: INT ← GetInt[context, $select];
cellType ← CreateSequenceCell[
name: BitMuxSeq,
baseCell: CreateStructure[name: BitMux, context: context],
count: select-1,
sequencePorts: "Select, Bit, nBit"];
IF GetBool[context, $PWCore] THEN PWCore.SetArrayX[cellType: cellType];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
Ports: Gnd, Select, Bit, nBit, Buffer, nBuffer
BitMux: ROPE = RegisterStructureProc[name: "BitMux", proc: CreateBitMuxBit];
CreateBitMuxBit: StructureProc = {
cellType ← CreateRecordCell[
name: BitMux,
context: context,
public: CreateWires[context, "Select, Bit, nBit, Buffer, nBuffer"],
instances: LIST [
[type: CreateTransistor[name: "Transistor", type: nE],
actual: "gate: Select, ch1: Bit, ch2: Buffer"],
[type: CreateTransistor[name: "Transistor", type: nE],
actual: "gate: Select, ch1: nBit, ch2: nBuffer"]]
];
IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
BitDrive: ROPE = RegisterStructureProc[name: "BitDrive", proc: CreateBitDrive];
CreateBitDrive: StructureProc = {
PushInt[context: context, prop: $SSIWidth, val: 4];
PushReal[context: context, prop: $SSIRatio, val: 2.5];
cellType ← CreateRecordCell[
name: BitDrive,
context: context,
public: CreateWires[context, "Vdd, Gnd, WriteB, nWriteB, ReadB, nReadB, DataB, Buffer, nBuffer"],
onlyInternal: CreateWires[context, "ndatab"],
instances: LIST [
[type: CreateStructure[name: "Inverter", context: context],
actual: "Input: DataB, Output: ndatab"], 
[type: CreateStructure[name: "TristateBuffer", context: context],
actual: "nInput: nBuffer, Drive: ReadB, nDrive: nReadB, Output: DataB"], 
[type: CreateStructure[name: "TristateBuffer", context: context],
actual: "nInput: DataB, Drive: WriteB, nDrive: nWriteB, Output: nBuffer"], 
[type: CreateStructure[name: "TristateBuffer", context: context],
actual: "nInput: ndatab, Drive: WriteB, nDrive: nWriteB, Output: Buffer"]]];
IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
DecoderStitch: ROPE = RegisterStructureProc[name: "DecoderStitch", proc: CreateDecoderStitch];
CreateDecoderStitch: StructureProc = {
select: INT ← GetInt[context, $select];
cellType ← CreateRecordCell[
name: DecoderStitch,
context: context,
public: CreateWires[context, "Vdd, Gnd, WriteB, nWriteB, ReadB, nReadB, Select[seq: select]"]];
IF GetBool[context, $PWCore] THEN PWCore.SetGet[cellType: cellType, source: NARROW[GetRef[context, $sourceCDDesign]]];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
END.