CrossRAMImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Barth, November 4, 1985 7:20:51 pm PST
Louis Monier September 20, 1985 3:46:52 pm PDT
Bertrand Serlet December 8, 1985 5:19:05 pm PST
Hoel, December 5, 1985 8:19:34 pm PST
DIRECTORY CD, CMos, Core, CoreClasses, CoreCompose, CoreOps, CrossRAM, IO, Onion, PWCore, Rope, Rosemary, Sinix;
CrossRAMImpl: CEDAR PROGRAM
IMPORTS CMos, CoreCompose, CoreOps, IO, Onion, PWCore, Rope, Rosemary, Sinix =
BEGIN OPEN CrossRAM, CoreCompose;
rowQuads: INT = 2; -- 58;
columnOcts: INT = 15; -- when changing this parameter, add new DataB[i] pins in the cell library.
addressBits: INT = 11;
dataBits: INT = columnOcts;
select: INT = 8;
log2Select: INT = 3;
addressDecoderBits: INT = 8;
AddressIndex: TYPE = [0 .. addressBits);
DataIndex: TYPE = [0 .. dataBits);
CrossRAM: ROPE = RegisterStructureProc[name: "CrossRAM", proc: CreateCrossRAM];
CreateCrossRAM: StructureProc = {
data: CoreClasses.RecordCellType;
PushInt[context: context, prop: $rowQuads, val: rowQuads];
PushInt[context: context, prop: $columnOcts, val: columnOcts];
PushInt[context: context, prop: $addressBits, val: addressBits];
PushInt[context: context, prop: $dataBits, val: dataBits];
PushInt[context: context, prop: $select, val: select];
PushInt[context: context, prop: $log2Select, val: log2Select];
PushInt[context: context, prop: $addressDecoderBits, val: addressDecoderBits];
-- BS: changed for generating layout
cellType ← CreateRecordCell[
name: CrossRAM,
context: context,
public: CreateWires[context, "Vdd, Gnd, PadVdd, PadGnd, nPrecharge, Access, Write, Read, Address[seq: addressBits], Data[seq: dataBits]"],
onlyInternal: CreateWires[context, "nPrechargeB, AccessB, WriteB, nWriteB, ReadB, nReadB, AddressB[seq: addressBits], DataB[seq: dataBits]"],
instances: LIST [
[type: CreateStructure[name: CrossRAMInner, context: context]],
[type: CreateStructure[name: CrossRamPadFrame, context: context]]
]];
cellType ← CreateRecordCell[
name: CrossRAM,
context: context,
public: CoreOps.WiresToWire[NIL],
onlyInternal: CreateWires[context, "Vdd, Gnd, nPrechargeB, AccessB, WriteB, nWriteB, ReadB, nReadB, AddressB[seq: addressBits], DataB[seq: dataBits]"],
instances: LIST [
[type: CreateStructure[name: CrossRAMInner, context: context]],
[type: CreateStructure[name: CrossRamPadFrame, context: context]]
]];
data ← NARROW [cellType.data];
IF GetBool[context, $PWCore] THEN {
lambda: INT = 2; -- to be changed for other technologies
params: Onion.LayersParameters ← NEW [Onion.LayersParametersRec ← [radialLayer: CMos.met, ringLayer: CMos.met2, ringWidth: Onion.RingWidthIs8, wireExtendProc: Onion.WireExtendMetToMet]];
inner, outer, all: CD.Object;
position: CD.Position;
inner ← PWCore.GateWay[data[0]];
outer ← PWCore.GateWay[data[1]];
inner ← Onion.MakeInner[NIL, inner];
position ← Onion.Center[inner, outer];
position.x ← 214; -- magic number! (Jeff) ; commented for small Crossrams, although it makes the Vdd and Gnd lines wrong when commented (BS)
position.y ← position.y + 5445; -- to help route small crossrams (BS)
position.y ← 46; -- another magic number! (Jeff) ; commented for small Crossrams (BS)
all ← Onion.LRSRoute[NIL, inner, outer, position, params].cell;
PWCore.SetLayout[cellType, all];
};
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
IF GetBool[context, $Rosemary] THEN Rosemary.Bind[cellType: cellType, roseClassName: CrossRAMRoseClass];
};
CrossRAMRoseClass: ROPE = Rosemary.Register[roseClassName: CrossRAM, init: CrossRAMInit, evalSimple: CrossRAMSimple];
CrossRAMInit: Rosemary.InitProc = {
stateAny ← NEW[CrossRAMStateRec[4*rowQuads]];
IF dataBits>16 OR addressBits>16 THEN ERROR;
FOR port: NAT IN [Vdd..Read] DO
p[port].type ← b;
ENDLOOP;
p[Address].type ← c;
FOR port: NAT IN [0..p[Address].size) DO
p[Address][port].type ← sub;
ENDLOOP;
p[Data].type ← c;
FOR port: NAT IN [0..p[Data].size) DO
p[Data][port].type ← sub;
ENDLOOP;
};
CrossRAMSimple: Rosemary.EvalProc = {
state: CrossRAMState ← NARROW[stateAny];
IF NOT p[Vdd].b OR p[Gnd].b OR NOT p[PadVdd].b OR p[PadGnd].b THEN SIGNAL Rosemary.Stop[];
IF (NOT p[nPrecharge].b AND p[Access].b) OR (p[Write].b AND p[Read].b) OR (NOT p[nPrecharge].b AND p[Write].b) THEN SIGNAL Rosemary.Stop[];
IF NOT p[nPrecharge].b THEN state.precharged ← TRUE;
p[Data].d ← none;
IF p[Access].b THEN {
IF NOT state.precharged THEN SIGNAL Rosemary.Stop[];
IF state.accessOccured AND state.address#p[Address].c THEN SIGNAL Rosemary.Stop[];
state.accessOccured ← TRUE;
state.address ← p[Address].c;
IF p[Read].b THEN {
p[Data].c ← state.memory[state.address].data;
p[Data].d ← drive;
};
IF p[Write].b THEN state.memory[state.address].data ← p[Data].c;
};
IF NOT p[Access].b AND state.accessOccured THEN {
state.accessOccured ← FALSE;
state.precharged ← FALSE;
};
};
CrossRamPadFrame: ROPE = RegisterStructureProc[name: "CrossRamPadFrame", proc: CreateCrossRamPadFrame];
CreateCrossRamPadFrame: StructureProc = {
inputPad: Core.CellType ← CreateStructure[name: "InputPad", context: context];
differentialInputPad: Core.CellType ← CreateStructure[name: "DifferentialInputPad", context: context];
bidirectionalPad: Core.CellType ← CreateStructure[name: "BidirectionalPad", context: context];
instances: InstanceList ← LIST [
[type: inputPad, actual: "Vdd: PadVdd, Gnd: PadGnd, Pad: nPrecharge, Output: nPrechargeB"],
[type: inputPad, actual: "Vdd: PadVdd, Gnd: PadGnd, Pad: Access, Output: AccessB"],
[type: differentialInputPad, actual: "Vdd: PadVdd, Gnd: PadGnd, Pad: Write, Output: WriteB, nOutput: nWriteB"],
[type: differentialInputPad, actual: "Vdd: PadVdd, Gnd: PadGnd, Pad: Read, Output: ReadB, nOutput: nReadB"]];
FOR addressPad: AddressIndex IN AddressIndex DO
instances ← CONS[[type: inputPad, actual: IO.PutFR["Vdd: PadVdd, Gnd: PadGnd, Pad: Address[%g], Output: AddressB[%g]", IO.int[addressPad], IO.int[addressPad]]], instances];
ENDLOOP;
FOR dataPad: DataIndex IN DataIndex DO
instances ← CONS[[type: bidirectionalPad, actual: IO.PutFR["Vdd: PadVdd, Gnd: PadGnd, Read: ReadB, nRead: nReadB, Write: WriteB, nWrite: nWriteB, Pad: Data[%g], Data: DataB[%g]", IO.int[dataPad], IO.int[dataPad]]], instances];
ENDLOOP;
-- BS: changed for generating layout
cellType ← CreateRecordCell[
name: CrossRamPadFrame,
context: context,
public: CreateWires[context, "Vdd, Gnd, PadVdd, PadGnd, nPrecharge, Access, Write, Read, Address[seq: addressBits], Data[seq: dataBits], nPrechargeB, AccessB, WriteB, nWriteB, ReadB, nReadB, AddressB[seq: addressBits], DataB[seq: dataBits]"],
instances: instances];
cellType ← CreateRecordCell[
name: CrossRamPadFrame,
context: context,
public: CreateWires[context, "Vdd, Gnd, nPrechargeB, AccessB, WriteB, nWriteB, ReadB, nReadB, AddressB[seq: addressBits], DataB[seq: dataBits]"],
onlyInternal: CreateWires[context, "PadVdd, PadGnd, nPrecharge, Access, Write, Read, Address[seq: addressBits], Data[seq: dataBits]"],
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]];
};
CrossRAMInner: ROPE = RegisterStructureProc[name: "CrossRAMInner", proc: CreateCrossRAMInner];
CreateCrossRAMInner: StructureProc = {
bottom: Core.CellType;
MarkContext[context: context, mark: $InnerMark];
PushInt[context: context, prop: $addressDecoderBits, val: addressDecoderBits-1];
bottom ← CreateStructure[name: "Bottom", context: context];
PopContext [context: context, mark: $InnerMark];
cellType ← CreateRecordCell[
name: CrossRAMInner,
context: context,
public: CreateWires[context, "Vdd, Gnd, nPrechargeB, AccessB, WriteB, nWriteB, ReadB, nReadB, AddressB[seq: addressBits], DataB[seq: dataBits]"],
onlyInternal: CreateWires[context, "AdrBit[seq: addressDecoderBits], nAdrBit[seq: addressDecoderBits], Bit[seq: select*columnOcts], nBit[seq: select*columnOcts]"],
instances: LIST [
[type: bottom],
[type: CreateStructure[name: Middle, context: context], actual: "VddMiddle: Vdd, GndLeft: Gnd, GndMiddle: Gnd, VddArray: Vdd, GndArray: Gnd"],
[type: CreateStructure[name: "CrossRAMTop", context: context], actual: "VddLeft: Vdd, VddRight: Vdd"]]];
IF GetBool[context, $PWCore] THEN PWCore.SetAbutY[cellType];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
Middle: ROPE = RegisterStructureProc[name: "Middle", proc: CreateMiddle];
CreateMiddle: StructureProc = {
rowQuads: INT ← GetInt[context, $rowQuads];
nRopes: ROPE ← "VddArray";
FOR i: INT IN (0 .. 2*rowQuads) DO nRopes ← Rope.Cat[nRopes, ", VddArray"] ENDLOOP;
cellType ← CreateRecordCell[
name: Middle,
context: context,
public: CreateWires[context, "Vdd, Gnd, VddMiddle, GndLeft, GndMiddle, VddArray, GndArray, AccessB, AdrBit[seq: addressDecoderBits], nAdrBit[seq: addressDecoderBits], Bit[seq: select*columnOcts], nBit[seq: select*columnOcts]"],
onlyInternal: CreateWires[context, "Word[seq: 4*rowQuads]"],
instances: LIST [
[type: CreateStructure[name: "Decoder", context: context], actual: "VddRight: VddArray"],
[type: CreateStructure[name: "RAMArray", context: context], actual: IO.PutFR["Gnd: GndArray, Vdd: [%g]", IO.rope[nRopes]]],
[type: CreateStructure[name: RightPowerSeq, context: context], actual: "Vdd: VddArray"]
]];
IF GetBool[context, $PWCore] THEN PWCore.SetAbutX[cellType];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
Port: Vdd
RightPowerSeq: ROPE = RegisterStructureProc[name: "RightPowerSeq", proc: CreateRightPowerSeq];
CreateRightPowerSeq: StructureProc = {
cellType ← CreateSequenceCell[
name: RightPowerSeq,
baseCell: CreateStructure[name: RightPower, context: context],
count: 2*rowQuads];
IF GetBool[context, $PWCore] THEN PWCore.SetArrayY[cellType];
IF GetBool[context, $Sinix] THEN [] ← Sinix.Extract[PWCore.GetLayout[cellType]];
};
RightPower: ROPE = RegisterStructureProc[name: "RightPower", proc: CreateRightPower];
CreateRightPower: StructureProc = {
cellType ← CreateRecordCell[
name: RightPower,
context: context,
public: CreateWires[context, "Vdd"]];
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: $rowQuads];
RegisterIntProperty[prop: $columnOcts];
RegisterIntProperty[prop: $addressBits];
RegisterIntProperty[prop: $dataBits];
RegisterIntProperty[prop: $select];
RegisterIntProperty[prop: $log2Select];
RegisterIntProperty[prop: $addressDecoderBits];
END.