DIRECTORY CD, CoreCreate, EU2Ram, EU2LeafUtils, EU2Utils, LayoutCheckpoint, Rosemary, Ports, PWCore;

EU2RamImpl: CEDAR PROGRAM
IMPORTS CoreCreate, EU2LeafUtils, EU2Utils, LayoutCheckpoint, Rosemary, Ports, PWCore 
EXPORTS EU2Ram = 
BEGIN OPEN CoreCreate, EU2Ram, EU2LeafUtils, EU2Utils;

public: Wire _ Wires[
"Vdd", "Gnd", "dRamRead", "nPrech", Bus["ramA"], Bus["ramB"], Bus["cBus"], 
-- select lines
Seq["selA", nRows], Seq["selB", nRows], Seq["selC", nRows], 
Seq["selALow", sizeSelLow], Seq["selBLow", sizeSelLow], Seq["selCLow", sizeSelLow] 
];
Vdd: PUBLIC NAT _ PortIndex[public, "Vdd"];
Gnd: PUBLIC NAT _ PortIndex[public, "Gnd"];
dRamRead: PUBLIC NAT _ PortIndex[public, "dRamRead"];
nPrech: PUBLIC NAT _ PortIndex[public, "nPrech"];
selA: PUBLIC NAT _ PortIndex[public, "selA"];
selB: PUBLIC NAT _ PortIndex[public, "selB"];
selC: PUBLIC NAT _ PortIndex[public, "selC"];
selALow: PUBLIC NAT _ PortIndex[public, "selALow"];
selBLow: PUBLIC NAT _ PortIndex[public, "selBLow"];
selCLow: PUBLIC NAT _ PortIndex[public, "selCLow"];
ramA: PUBLIC NAT _ PortIndex[public, "ramA"];
ramB: PUBLIC NAT _ PortIndex[public, "ramB"];
cBus: PUBLIC NAT _ PortIndex[public, "cBus"];
CreateEU2Ram: PUBLIC PROC RETURNS [cellType: CellType] = {
top, array, mux, rw: CellInstance;
IF EU2Utils.useRamCheckpoint THEN RETURN [LayoutCheckpoint.Retrieve["EU2Ram"]];
PrintStart["EU2Ram"];
mux _ Instance[type: CreateRamMux[]];
rw _ Instance[type: CreateRamReadWrite[]];
top _ Instance[type: CreateRamTop[]];
array _ Instance[type: CreateRamArray[]];	
cellType _ Cell[name: "EU2Ram",
public: public, 
onlyInternal: Wires[
Seq["naBit", wordSize, Seq[size: 4]], Bus["na"], 
Seq["bBit", wordSize, Seq[size: 4]], Bus["b"], 
Seq["ncBit", wordSize, Seq[size: 4]], Bus["nc"], 
Seq["cBit", wordSize, Seq[size: 4]], Bus["c"]],
instances: LIST [rw, mux, array, top]];
[] _ Ports.InitPort[cellType.public[dRamRead], l, none];
[] _ Ports.InitPort[cellType.public[nPrech], l, none];	-- not used in simulation
[] _ Ports.InitPort[cellType.public[selA], ls, none];
[] _ Ports.InitPort[cellType.public[selB], ls, none];
[] _ Ports.InitPort[cellType.public[selC], ls, none];
[] _ Ports.InitPort[cellType.public[selALow], ls, none];
[] _ Ports.InitPort[cellType.public[selBLow], ls, none];
[] _ Ports.InitPort[cellType.public[selCLow], ls, none];
[] _ Ports.InitPort[cellType.public[ramA], ls, drive];
[] _ Ports.InitPort[cellType.public[ramB], ls, drive];
[] _ Ports.InitPort[cellType.public[cBus], ls, none];	-- actually both ways
[] _ Rosemary.BindCellType[cellType: cellType, roseClassName: EU2RamRoseClass];
[] _ Rosemary.AddCutSets[cellType: cellType, cs1: EU2RamRoseClass];
PWCore.SetAbutY[cellType];
PrintStop["EU2Ram"];
};
EU2RamRoseClass: ROPE = Rosemary.Register[roseClassName: "EU2Ram", init: EU2RamInit, evalSimple: EU2RamSimple];

EU2RamInit: Rosemary.InitProc = {
state: EU2RamState _ NEW[EU2RamStateRec[EU2Utils.nbWords]];
FOR word: NAT IN [0..EU2Utils.nbWords) DO
state.ram[word] _ NEW[Ports.LevelSequenceRec[32]];
ENDLOOP;
ResetRam[state, X];
FOR bit: NAT IN [0..32) DO
allXes[bit] _ X;
ENDLOOP;
stateAny _ state;
};
allXes: Ports.LevelSequence _ NEW[Ports.LevelSequenceRec[32]];
ResetRam: PROC [state: EU2RamState, l: Ports.Level] ~ {
FOR i: NAT IN [0..EU2Utils.nbWords) DO
FOR bit: NAT IN [0..32) DO
state.ram[i][bit] _ l;
ENDLOOP;
ENDLOOP;
FOR bit: NAT IN [0..32) DO
state.ram[constAdr][bit] _ L;
ENDLOOP;
};
CopyLS: PROC [source, dest: Ports.LevelSequence] ~ {
FOR bit: NAT IN [0..source.size) DO
dest[bit] _ source[bit];
ENDLOOP;
};
EU2RamSimple: Rosemary.EvalProc = {
state: EU2RamState _ NARROW[stateAny];
{OPEN state;
max: NAT _ 255;
anyX, oneHiA, oneHiB, oneHiC, oneHiAlow, oneHiBlow, oneHiClow: BOOL _ FALSE;
aAdr, bAdr, cAdr, aLow, bLow, cLow: NAT;
FOR i: NAT IN [0..EU2Utils.nRows) DO
IF p[selA].ls[i]=H THEN {IF oneHiA THEN anyX _ TRUE; aAdr _ i; oneHiA _ TRUE};
IF p[selB].ls[i]=H THEN {IF oneHiB THEN anyX _ TRUE; bAdr _ i; oneHiB _ TRUE};
IF p[selC].ls[i]=H THEN {IF oneHiC THEN anyX _ TRUE; cAdr _ i; oneHiC _ TRUE};
anyX _ anyX OR p[selA].ls[i]=X OR p[selB].ls[i]=X OR p[selC].ls[i]=X;
ENDLOOP;
FOR i: NAT IN [0..EU2Utils.sizeSelLow) DO
IF p[selALow].ls[i]=H THEN {
IF oneHiAlow THEN anyX _ TRUE; aLow _ i; oneHiAlow _ TRUE};
IF p[selBLow].ls[i]=H THEN {
IF oneHiBlow THEN anyX _ TRUE; bLow _ i; oneHiBlow _ TRUE};
IF p[selCLow].ls[i]=H THEN {
IF oneHiClow THEN anyX _ TRUE; cLow _ i; oneHiClow _ TRUE};
ENDLOOP;
IF oneHiC AND oneHiClow THEN CopyLS[p[cBus].ls, ram[4*cAdr+cLow]];
IF anyX THEN ResetRam[state, X];	-- nasty stuff!!!
IF oneHiA AND oneHiAlow THEN {
p[ramA].d _ drive;
CopyLS[ram[4*aAdr+aLow], p[ramA].ls];
}
ELSE p[ramA].d _ none;
IF oneHiB AND oneHiBlow THEN {
p[ramB].d _ drive;
CopyLS[ram[4*bAdr+bLow], p[ramB].ls];
}
ELSE p[ramB].d _ none;
p[cBus].d _ none;

IF p[dRamRead].l=H THEN {p[cBus].d _ drive; CopyLS[ram[4*aAdr+aLow], p[cBus].ls]};
IF p[dRamRead].l=X THEN {p[cBus].d _ drive; CopyLS[allXes, p[cBus].ls]};
}};
CreateRamTop: PROC RETURNS [cellType: CellType] = {
cellType _ SequenceCell[name: "RamTop",
baseCell: CreatePrechQuadSt[], count: wordSize,
sequencePorts: Wires["naBit", "bBit", "cBit", "ncBit"]];
PWCore.SetArrayX[cellType];
};
CreatePrechQuadSt: PROC RETURNS [cellType: CellType] = {
q: CellInstance _ Instance[type: CreatePrechQuad[]];
s: CellInstance _ Instance[type: Extract["RamPrechSt.sch"]];
cellType _ Cell[name: "PrechQuadSt",
public: Wires[Seq["naBit", 4], Seq["bBit", 4], Seq["cBit", 4], Seq["ncBit", 4], "nPrech", "Vdd", "Gnd"], 
instances: LIST [q, s]];
PWCore.SetAbutX[cellType];
};
CreatePrechQuad: PROC RETURNS [cellType: CellType] = {
cellType _ SequenceCell[name: "PrechQuad",
baseCell: Extract["RamPrech.sch"], count: 4,
sequencePorts: Wires["naBit", "bBit", "cBit", "ncBit"]];
PWCore.SetArrayX[cellType];
};
CreateRamArray: PROC RETURNS [cellType: CellType] = {
insts: CellInstances _ NIL;
ramRow: CellType _ CreateRamRow[];
ramPair: CellType _ CreateRowPair[ramRow, ramRow];
ramRomPair: CellType _ CreateRowPair[ramRow, CreateRamRomRow[]];
IF constAdr/4 MOD 2=0 THEN ERROR;	-- otherwise change the orientation of the rom row!
FOR i: NAT IN [0..nRows/2) DO
insts _ CONS[
Instance[IF i=constAdr/8 THEN ramRomPair ELSE ramPair,
["selA0", Index["selA", 2*i]], ["selA1", Index["selA", 2*i+1]], 
["selB0", Index["selB", 2*i]], ["selB1", Index["selB", 2*i+1]], 
["selC0", Index["selC", 2*i]], ["selC1", Index["selC", 2*i+1]]],
insts];
ENDLOOP;
cellType _ Cell[name: "RamArray",
public: Wires["Vdd", "Gnd", Seq["selA", nRows], Seq["selB", nRows], Seq["selC", nRows],
Seq["naBit", wordSize, Seq[size: 4]], Seq["bBit", wordSize, Seq[size: 4]], Seq["cBit", wordSize, Seq[size: 4]], Seq["ncBit", wordSize, Seq[size: 4]] ], 
instances: insts];
PWCore.SetAbutY[cellType];
};
CreateRowPair: PROC[topCt, botCt: CellType] RETURNS [cellType: CellType] = {
top, bot: CellInstance;
top _ Instance[topCt,
["selA", "selA0"], ["selB", "selB0"], ["selC", "selC0"]];
bot _ Instance[PWCore.RotateCellType[botCt, $FlipY],
["selA", "selA1"], ["selB", "selB1"], ["selC", "selC1"]];
cellType _ Cell[name: "RowPair",
public: Wires["Vdd", "Gnd", "selA0", "selA1", "selB0", "selB1", "selC0", "selC1",
Seq["naBit", wordSize, Seq[size: 4]], Seq["bBit", wordSize, Seq[size: 4]], Seq["cBit", wordSize, Seq[size: 4]], Seq["ncBit", wordSize, Seq[size: 4]] ], 
instances: LIST[bot, top]];
PWCore.SetAbutY[cellType];
};
CreateRamRomRow: PROC RETURNS [cellType: CellType] = {
cellType _ SequenceCell[name: "RamRomRow",
baseCell: CreateRamRomQuadSt[], count: wordSize,
sequencePorts: Wires["naBit", "bBit", "cBit", "ncBit"]];
PWCore.SetArrayX[cellType];
};
CreateRamRomQuadSt: PROC RETURNS [cellType: CellType] = {
ramCell: CellType _ Extract["RamCell.sch"];
rom0: CellInstance _ Instance[Extract["Rom0Cell.sch"], 
["naBit", "naBit[0]"], ["bBit", "bBit[0]"], ["cBit", "cBit[0]"], ["ncBit", "ncBit[0]"]];
ram1: CellInstance _ Instance[ramCell,
["naBit", "naBit[1]"], ["bBit", "bBit[1]"], ["cBit", "cBit[1]"], ["ncBit", "ncBit[1]"]];
ram2: CellInstance _ Instance[ramCell,
["naBit", "naBit[2]"], ["bBit", "bBit[2]"], ["cBit", "cBit[2]"], ["ncBit", "ncBit[2]"]];
ram3: CellInstance _ Instance[ramCell,
["naBit", "naBit[3]"], ["bBit", "bBit[3]"], ["cBit", "cBit[3]"], ["ncBit", "ncBit[3]"]];
s: CellInstance _ Instance[Extract["RamStitch.sch"]];
cellType _ Cell[name: "RamRomQuadSt",
public: Wires["Vdd", "Gnd", "selA", "selB", "selC", 
Seq["naBit", 4], Seq["bBit", 4], Seq["cBit", 4], Seq["ncBit", 4]], 
instances: LIST [rom0, ram1, ram2, ram3, s]];
PWCore.SetAbutX[cellType];
};
CreateRamRow: PROC RETURNS [cellType: CellType] = {
cellType _ SequenceCell[name: "RamRow",
baseCell: CreateRamQuadSt[], count: wordSize,
sequencePorts: Wires["naBit", "bBit", "cBit", "ncBit"]];
PWCore.SetArrayX[cellType];
};
CreateRamQuadSt: PROC RETURNS [cellType: CellType] = {
q: CellInstance _ Instance[type: CreateRamQuad[]];
s: CellInstance _ Instance[type: Extract["RamStitch.sch"]];
cellType _ Cell[name: "RamQuadSt",
public: Wires["Vdd", "Gnd", "selA", "selB", "selC", 
Seq["naBit", 4], Seq["bBit", 4], Seq["cBit", 4], Seq["ncBit", 4]], 
instances: LIST [q, s]];
PWCore.SetAbutX[cellType];
};
CreateRamQuad: PROC RETURNS [cellType: CellType] = {
cellType _ SequenceCell[name: "RamQuad",
baseCell: Extract["RamCell.sch"], count: 4,
sequencePorts: Wires["naBit", "bBit", "cBit", "ncBit"]];
PWCore.SetArrayX[cellType];
};

CreateRamMux: PROC RETURNS [cellType: CellType] = {
cellType _ SequenceCell[name: "RamMux",
baseCell: Extract["MuxQuadSt.sch"], count: wordSize,
sequencePorts: Wires["naBit", "bBit", "cBit", "ncBit", "na", "b", "c", "nc"]];
PWCore.SetArrayX[cellType];
};
CreateRamReadWrite: PROC RETURNS [cellType: CellType] = {
cellType _ SequenceCell[name: "RamReadWrite",
baseCell: Extract["RamRW.sch"], count: wordSize,
sequencePorts: Wires["na", "b", "c", "nc", "ramA", "ramB", "cBus"]];
PWCore.SetArrayX[cellType];
};
END.

��,��EU2RamImpl.mesa
Copyright c 1985 by Xerox Corporation.  All rights reserved.
Louis Monier June 17, 1986 2:25:11 pm PDT
Barth, June 17, 1986 4:02:10 pm PDT
Bertrand Serlet May 11, 1986 7:45:06 pm PDT


-- (ramA, ramB, cBus)[0..32), (selA, selB, selC)[0..nRows), (selALow, selBLow, selCLow)[0..4), Vdd, Gnd, dRamRead, nPrech

-- ramA and ramB always output, cBus output during debugging only
-- no two select lines high at the same time
-- no two select lines high at the same time


-- Pull-up on top
-- (naBit, bBit, cBit, ncBit)[0..32)[0..4), nPrech, Vdd, Gnd

-- (naBit, bBit)[0..4), nPrech, Vdd, Gnd

-- The complete array: a mess because of these ROM bits (cf. EMM)
-- The row 33 (= constAdr/4) has one ROM word and three RAM words.
-- The row zero is on top (because of CONS and AbutY)
-- (naBit, bBit, cBit, ncBit)[0..32)[0..4), (selA, selB, selC)[0..nRows), Vdd, Gnd

-- The pairs of rows
-- (naBit, bBit, cBit, ncBit)[0..32)[0..4), (selA, selB, selC)[0..2), Vdd, Gnd

-- The RAM and ROM row
-- (naBit, bBit, cBit, ncBit)[0..32)[0..4), (selA, selB, selC), Vdd, Gnd
-- (naBit, bBit, cBit, ncBit)[0..4), selA, selB, selC, Vdd, Gnd

-- The RAM row
-- (naBit, bBit, cBit, ncBit)[0..32)[0..4), (selA, selB, selC)[0..2), Vdd, Gnd
-- (naBit, bBit, cBit, ncBit)[0..4), selA, selB, selC, Vdd, Gnd
-- (naBit, bBit, cBit, ncBit)[0..4), selA, selB, selC, Vdd, Gnd
-- Muxes on bottom
-- (naBit, bBit, cBit, ncBit)[0..4)[0..32), (a, b, c, nc)[0..32), (selALow, selBLow, selCLow)[0..4), Gnd

-- Read-write on bottom
-- (na, b, c, nc, ramA, ramB, cBus)[0..32), dRamRead, Vdd, Gnd


�Ê
~��–
"cedar" style˜�codešœ™Kšœ
Ïmœ1™<K™)K™#K™+—K˜�KšÏk	œžœX˜dK˜�•StartOfExpansion[]šÏb
œžœž˜KšžœO˜VKšžœ
˜Kšžœžœ,˜6—K˜�šœ˜KšœK˜KKšÏc˜Kšœ<˜<KšœS˜SKšœ˜—K™�Kšœžœžœ˜+Kšœžœžœ˜+Kšœ
žœžœ!˜5Kšœžœžœ˜1Kšœžœžœ˜-Kšœžœžœ˜-Kšœžœžœ˜-Kšœ	žœžœ ˜3Kšœ	žœžœ ˜3Kšœ	žœžœ ˜3Kšœžœžœ˜-Kšœžœžœ˜-Kšœžœžœ˜-K™�Kšœy™yšÏnœžœžœ˜:Kšœ"˜"Kšžœžœžœ'˜OKšœ˜Kšœ%˜%Kšœ*˜*Kšœ%˜%Kšœ*˜*šœ˜Kšœ˜šœ˜Kšœ1˜1Kšœ/˜/Kšœ1˜1Kšœ/˜/—Kšœžœ˜'—Kšœ8˜8Kšœ7 ˜PKšœ5˜5Kšœ5˜5Kšœ5˜5Kšœ8˜8Kšœ8˜8Kšœ8˜8Kšœ6˜6Kšœ6˜6Kšœ6 ˜KKšœO˜OKšœC˜CKšœ˜Kšœ˜Kšœ˜—K™�Kš¡œžœZ˜oK˜�šÐbn
œ˜!Kšœžœ#˜;šžœžœžœž˜)Kšœžœ˜2Kšžœ˜—Kšœ˜šžœžœžœ	ž˜Kšœ˜Kšžœ˜—Kšœ˜Kšœ˜—Kšœžœ˜>š¡œžœ)˜7šžœžœžœž˜&šžœžœžœ	ž˜Kšœ˜Kšžœ˜—Kšžœ˜—šžœžœžœ	ž˜Kšœ˜Kšžœ˜—K˜—š¡œžœ(˜4šžœžœžœž˜#Kšœ˜Kšžœ˜—K˜—KšœA™AšŸœ˜#Kšœžœ˜&Jšœžœ˜Jšœžœ˜Jšœ?žœžœ˜LJšœ$žœ˜(šžœžœžœž˜$K™,Kšžœžœžœžœžœžœ˜NKšžœžœžœžœžœžœ˜NKšžœžœžœžœžœžœ˜NKšœžœžœžœ˜EKšžœ˜—šžœžœžœž˜)K™,šžœžœ˜Kšžœžœžœžœ˜;—šžœžœ˜Kšžœžœžœžœ˜;—šžœžœ˜Kšžœžœžœžœ˜;—Kšžœ˜—Jšžœžœžœ&˜BKšžœžœ ˜2šžœžœžœ˜Kšœ˜Jšœ%˜%J˜—Jšžœ˜šžœžœžœ˜Kšœ˜Jšœ%˜%J˜—Jšžœ˜Jšœ˜J˜�Jšžœžœ;˜RJšžœžœ1˜HKšœ˜K™�K™�—šÏl™Kš <™<š¡œžœžœ˜3šœ'˜'Kšœ/˜/Kšœ8˜8—Kšœ˜Kšœ˜—K™�Kšœ œ™(š¡œžœžœ˜8Kšœ4˜4Kšœ<˜<šœ$˜$Kšœi˜iKšœžœ	˜—Kšœ˜Kšœ˜—š¡œžœžœ˜6šœ*˜*Kšœ,˜,Kšœ8˜8—Kšœ˜Kšœ˜——K™�š£A™AKšœB™BK™5KšœR™Rš¡œžœžœ˜5Kšœžœ˜Kšœ"˜"Kšœ2˜2Kšœ@˜@Kš	žœžœžœžœ 3˜Ušžœžœžœž˜šœžœ˜
šœ	žœžœžœ	˜6Kšœ@˜@Kšœ@˜@Kšœ@˜@—Kšœ˜—Kšžœ˜—šœ!˜!šœW˜WKšœ˜˜˜—Kšœ˜—Kšœ˜Kšœ˜——K™�š£™KšœN™Nš¡
œžœžœ˜LKšœ˜šœ˜Kšœ9˜9—šœ4˜4Kšœ9˜9—šœ ˜ šœQ˜QKšœ˜˜˜—Kšœžœ˜—Kšœ˜Kšœ˜—K™�—š£™KšœH™Hš¡œžœžœ˜6šœ*˜*Kšœ0˜0Kšœ8˜8—Kšœ˜Kšœ˜—Kšœ?™?š¡œžœžœ˜9Kšœ+˜+šœ7˜7KšœX˜X—šœ&˜&KšœX˜X—šœ&˜&KšœX˜X—šœ&˜&KšœX˜X—Kšœ5˜5šœ%˜%šœ4˜4KšœC˜C—Kšœžœ˜-—Kšœ˜Kšœ˜—K™�—š£™KšœN™Nš¡œžœžœ˜3šœ'˜'Kšœ-˜-Kšœ8˜8—Kšœ˜Kšœ˜—Kšœ?™?š¡œžœžœ˜6Kšœ2˜2Kšœ;˜;šœ"˜"šœ4˜4KšœC˜C—Kšœžœ	˜—Kšœ˜Kšœ˜—Kšœ?™?š¡
œžœžœ˜4šœ(˜(Kšœ+˜+Kšœ8˜8—Kšœ˜Kšœ˜K˜�——š£™Kšœh™hš¡œžœžœ˜3šœ'˜'Kšœ4˜4KšœN˜N—Kšœ˜Kšœ˜——K™�š£™Kšœ>™>š¡œžœžœ˜9šœ-˜-Kšœ0˜0KšœD˜D—Kšœ˜Kšœ˜——K™�K™�Kšžœ˜K˜�—�…—����&l��7��