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; -- 60; 
columnOcts: INT = 15;
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];
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 {
params: Onion.LayersParameters _ NEW [Onion.LayersParametersRec _ [radialLayer: CMos.met, ringLayer: CMos.met2, ringWidth: Onion.RingWidthIs8, wireExtendProc: Onion.WireExtendMetToMet]];
inner, outer, all: CD.Object;
inner _ Onion.MakeInner[NIL, PWCore.GateWay[data[0]]]; outer _ PWCore.GateWay[data[1]];
all _ Onion.LRSRoute[NIL, inner, outer, Onion.Center[inner, outer], params].cell;
PWCore.SetLayout[cellType, all];
};
IF GetBool[context, $Sinix] THEN [] _ Sinix.ExtractObj[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;
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.ExtractObj[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: "VddLeft: Vdd, VddMiddle: Vdd, VddRight: 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.ExtractObj[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 .. rowQuads) DO nRopes _ Rope.Cat[nRopes, ", VddArray"] ENDLOOP;
cellType _ CreateRecordCell[
name: Middle,
context: context,
public: CreateWires[context, "Vdd, Gnd, VddLeft, VddMiddle, VddRight, 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]],
[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.ExtractObj[PWCore.GetLayout[cellType]];
};

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.ExtractObj[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.ExtractObj[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.

��r��CrossRAMImpl.mesa
Copyright c 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 November 21, 1985 5:12:31 pm PST
-- 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]]
]];
-- 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];
Port: Vdd
�Êå��–
"cedar" style˜�codešœ™Kšœ
Ïmœ1™<K™&K™.K™0—K˜�KšÏk	œžœ;žœ'˜pK˜�•StartOfExpansion[]šÏbœžœž˜Kšžœžœ)˜OKšžœžœ˜!—K˜�Kšœ
žœÏc˜Kšœžœ˜Kšœ
žœ˜Kšœ
žœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜K˜�Kšœžœ˜&Kšœžœ˜ K˜�šŸœžœA˜Ošœ!˜!Kšœ!˜!Kšœ:˜:Kšœ>˜>Kšœ@˜@Kšœ:˜:Kšœ6˜6Kšœ>˜>KšœN˜NKšÐbc$™$šŸ™KšŸ™KšŸ™KšŸŠ™ŠKšŸ™šŸÐbkŸ™KšŸ?™?KšŸA™AKšŸ™——šœ˜Kšœ˜Kšœ˜Kšœžœ˜!Kšœ—˜—šœžœ˜Kšœ?˜?KšœA˜AKšœ˜——Kšœžœ˜šžœžœ˜#Jšœ!žœ–˜ºKšœžœ˜Kšœžœ<˜WKšœžœ9˜QKšœ ˜ K˜—Kšžœžœ3˜SKšžœžœE˜hKšœ˜—K˜�—Kšœžœ^˜ušœ#˜#Kšœžœ˜-Kšžœ
žœžœžœ˜,šžœžœžœ
ž˜Kšœ˜Kšžœ˜—Kšœ˜šžœžœžœž˜(Kšœ˜Kšžœ˜—Kšœ˜šžœžœžœž˜%Kšœ˜Kšžœ˜—Kšœ˜—šœ%˜%Kšœžœ˜(Kšžœžœ
žœ
žœžœ
žœ
žœžœ˜ZKšžœžœžœžœ
žœžœžœžœ
žœžœ˜‹Kšžœžœžœžœ˜4Kšœ˜šžœ
žœ˜Kšžœžœžœžœ˜4Kšžœžœžœžœ˜RKšœžœ˜Kšœ˜šžœžœ˜Kšœ-˜-Kšœ˜Kšœ˜—Kšžœžœ.˜@K˜—šžœžœ
žœžœ˜1Kšœžœ˜Kšœžœ˜Kšœ˜—Kšœ˜—K˜�šœžœQ˜gšœ)˜)KšœN˜NKšœf˜fKšœ^˜^šœžœ˜ Kšœ[˜[KšœS˜SKšœo˜oKšœm˜m—šžœžœž˜/Kš	œžœžœKžœžœ˜¬Jšžœ˜—šžœžœž˜&Kš	œžœ"žœžœžœ˜âJšžœ˜—Kš¡$™$šŸ™KšŸ™KšŸ™KšŸò™òKšŸ™—šœ˜Kšœ˜K˜Kšœ‘˜‘Kšœ†˜†Kšœ˜—Kšžœžœ+žœ$˜vKšžœžœ3˜SKšœ˜—K˜�—šŸ
œžœK˜^šœ&˜&Kšœ˜Kšœ0˜0KšœP˜PKšœ;˜;Kšœ0˜0šœ˜Kšœ˜K˜Kšœ‘˜‘Kšœ£˜£šœžœ˜Kšœ˜Kšœ«˜«Kšœh˜h——Jšžœžœ˜<Jšžœžœ3˜SKšœ˜—K˜�—šœžœ=˜Išœ˜Kšœ
žœ˜+Kšœžœ˜Kš
žœžœžœžœ)žœ˜Qšœ˜Kšœ
˜
K˜Kšœö˜öKšœ<˜<šœžœ˜Kšœ;˜;KšœDžœ#žœ˜{KšœW˜WKšœ˜——Jšžœžœ˜<Jšžœžœ3˜SKšœ˜—K˜�—Jšœ	™	šœžœK˜^šœ&˜&šœ˜Kšœ˜Kšœ>˜>Kšœ˜—Jšžœžœ˜=Jšžœžœ3˜SKšœ˜—K˜�—šœžœE˜Ušœ#˜#šœ˜Kšœ˜K˜Kšœ%˜%—Kšžœžœ+žœ$˜vKšžœžœ3˜SKšœ˜—K˜�—Kšœ%˜%Kšœ'˜'Kšœ(˜(Kšœ%˜%Kšœ#˜#Kšœ'˜'Kšœ/˜/K˜�Kšžœ˜K˜�—�…—����"Ü��/3��