EURamImpl.mesa
Copyright © 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 August 11, 1986 11:58:52 pm PDT
Last Edited by: Louis Monier November 6, 1986 3:27:12 pm PST
DIRECTORY CD, CoreCreate, CoreFlat, EUInner, EUUtils, Rosemary, Ports, PWCore;
EURamImpl: CEDAR PROGRAM
IMPORTS CoreCreate, EUUtils, PWCore
EXPORTS EUInner =
BEGIN OPEN CoreCreate, EUInner;
EURamState: TYPE = REF EURamStateRec;
EURamStateRec: TYPE = RECORD[
nPrech, selA, selB, selC, selALow, selBLow, selCLow, ramA, ramB, cBus: NATLAST[NAT],
ram: SEQUENCE size: NAT OF Ports.LevelSequence];
-- (ramA, ramB, cBus)[0..32), selRam((selA, selB, selC)[0..nRows), (selALow, selBLow, selCLow)[0..4) ), Vdd, Gnd, nPrech
CreateEURam: PUBLIC PROC [] RETURNS [ct: CellType] = {
ct ← EUUtils.Fetch["EURam"];
IF ct=NIL THEN {
ct ← EUUtils.Extract["EURam.sch"];
EUUtils.Store["EURam", ct];
};
};
-- Pull-up on top
-- (naBit, bBit, cBit, ncBit)[0..32)[0..4), nPrech, Vdd, Gnd
CreateRamTop: PUBLIC PROC RETURNS [cellType: CellType] = {
cellType ← EUUtils.CSeqX["RamTop", EUUtils.Extract["PrechQuadSt.sch"], 32,
LIST["naBit", "bBit", "cBit", "ncBit"]];
};
-- The complete array: a mess because of these ROM bits (cf. EMM)
-- The row 33 (= constAdr/4) is made of four words of ROM.
-- 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
CreateRamArray: PUBLIC PROC RETURNS [cellType: CellType] = {
insts: CellInstances ← NIL;
ramRow: CellType ← CreateRamRow[];
flipRomRow: CellType ← PWCore.RotateCellType[CreateRomRow[], $FlipY];
flipRamRow: CellType ← PWCore.RotateCellType[ramRow, $FlipY];
IF EUUtils.constAdr/4 MOD 2=0 THEN ERROR; -- else change the orientation of the rom row!
FOR i: NAT IN [0..EUUtils.nRows) DO
insts ← CONS[
Instance[
SELECT TRUE FROM
i=EUUtils.constAdr/4 => flipRomRow,
i MOD 2 = 0 => ramRow,
ENDCASE => flipRamRow,
["selA", Index["selA", i]], ["selB", Index["selB", i]], ["selC", Index["selC", i]]
],
insts];
ENDLOOP;
cellType ← Cell[name: "RamArray",
public: Wires["Vdd", "Gnd", Seq["selA", EUUtils.nRows], Seq["selB", EUUtils.nRows], Seq["selC", EUUtils.nRows],
Seq["naBit", 32, Seq[size: 4]], Seq["bBit", 32, Seq[size: 4]], Seq["cBit", 32, Seq[size: 4]], Seq["ncBit", 32, Seq[size: 4]] ],
instances: insts];
PWCore.SetAbutY[cellType];
};
-- The RAM row
-- (naBit, bBit, cBit, ncBit)[0..32)[0..4), selA, selB, selC, Vdd, Gnd
CreateRamRow: PROC RETURNS [cellType: CellType] = {
cellType ← EUUtils.CSeqX["RamRow", EUUtils.Extract["RamQuadSt.sch"], 32,
LIST["naBit", "bBit", "cBit", "ncBit"]];
};
-- The ROM row
-- (naBit, bBit, cBit, ncBit)[0..32)[0..4), selA, selB, selC, Vdd, Gnd
CreateRomRow: PROC RETURNS [cellType: CellType] = {
rom0: CellType ← EUUtils.Extract["Rom0Cell.sch"];
rom1: CellType ← EUUtils.Extract["Rom1Cell.sch"];
stitch: CellType ← EUUtils.Extract["RamStitch.sch"];
rom0000: CellType ← CreateRomQuad[rom0, rom0, rom0, rom0, stitch]; -- msb
rom0011: CellType ← CreateRomQuad[rom0, rom0, rom1, rom1, stitch];
rom0101: CellType ← CreateRomQuad[rom0, rom1, rom0, rom1, stitch]; -- lsb
-- 0 is msb, on the left, and must be at the beginning of the list
insts: CellInstances ← NIL;
insts ← CONS[Instance[rom0101,
["naBit", Index["naBit", 31]], ["bBit", Index["bBit", 31]],
["cBit", Index["cBit", 31]], ["ncBit", Index["ncBit", 31]]], insts];
insts ← CONS[Instance[rom0011,
["naBit", Index["naBit", 30]], ["bBit", Index["bBit", 30]],
["cBit", Index["cBit", 30]], ["ncBit", Index["ncBit", 30]]], insts];
FOR i: NAT DECREASING IN [0..30) DO
insts ← CONS[Instance[rom0000,
["naBit", Index["naBit", i]], ["bBit", Index["bBit", i]],
["cBit", Index["cBit", i]], ["ncBit", Index["ncBit", i]]], insts];
ENDLOOP;
cellType ← Cell[name: "RomRow",
public: Wires[Seq["naBit", 32, Seq[size: 4]], Seq["bBit", 32, Seq[size: 4]], Seq["cBit", 32, Seq[size: 4]], Seq["ncBit", 32, Seq[size: 4]], "selA", "selB", "selC", "Vdd", "Gnd"],
instances: insts];
PWCore.SetAbutX[cellType];
};
-- (naBit, bBit, cBit, ncBit)[0..4), selA, selB, selC, Vdd, Gnd
CreateRomQuad: PROC [b0, b1, b2, b3, stitch: CellType] RETURNS [cellType: CellType] = {
rom0: CellInstance ← Instance[b0,
["naBit", "naBit[0]"], ["bBit", "bBit[0]"], ["cBit", "cBit[0]"], ["ncBit", "ncBit[0]"]];
ram1: CellInstance ← Instance[b1,
["naBit", "naBit[1]"], ["bBit", "bBit[1]"], ["cBit", "cBit[1]"], ["ncBit", "ncBit[1]"]];
ram2: CellInstance ← Instance[b2,
["naBit", "naBit[2]"], ["bBit", "bBit[2]"], ["cBit", "cBit[2]"], ["ncBit", "ncBit[2]"]];
ram3: CellInstance ← Instance[b3,
["naBit", "naBit[3]"], ["bBit", "bBit[3]"], ["cBit", "cBit[3]"], ["ncBit", "ncBit[3]"]];
s: CellInstance ← Instance[stitch];
cellType ← Cell[name: "RomQuadSt",
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];
};
-- Muxes on bottom
-- (naBit, bBit, cBit, ncBit)[0..4)[0..32), (na, b, c, nc)[0..32), (selALow, selBLow, selCLow)[0..4), Gnd
CreateRamMux: PUBLIC PROC RETURNS [cellType: CellType] = {
cellType ← EUUtils.CSeqX["RamMux", EUUtils.Extract["MuxQuadSt.sch"], 32,
LIST["naBit", "bBit", "cBit", "ncBit", "na", "b", "c", "nc"]];
};
-- Read-write on bottom
-- (na, b, c, nc, ramA, ramB, cBus)[0..32), Vdd, Gnd
CreateRamReadWrite: PUBLIC PROC RETURNS [cellType: CellType] = {
cellType ← EUUtils.CSeqX["RamReadWrite", EUUtils.Extract["RamRW.sch"], 32,
LIST["na", "b", "c", "nc", "ramA", "ramB", "cBus"]];
};
END.
EURamRoseClass: ROPE = Rosemary.Register[roseClassName: "EURam", init: EURamInit, evalSimple: EURamSimple];
EURamInit: Rosemary.InitProc = {
state: EURamState ← NEW[EURamStateRec[EUUtils.nbWords]];
{OPEN state;
[nPrech, selA, selB, selC, selALow, selBLow, selCLow, ramA, ramB, cBus] ←
Ports.PortIndexes[cellType.public, "nPrech", "selA", "selB", "selC", "selALow", "selBLow", "selCLow", "ramA", "ramB", "cBus"];
FOR word: NAT IN [0..EUUtils.nbWords) DO
ram[word] ← NEW[Ports.LevelSequenceRec[32]];
ENDLOOP;};
ResetRam[state, X];
stateAny ← state;
};
ResetRam: PROC [state: EURamState, l: Ports.Level] ~ {
FOR i: NAT IN [0..EUUtils.nbWords) DO Ports.SetLS[state.ram[i], l]; ENDLOOP;
Ports.SetLS[state.ram[EUUtils.constAdr], L];  -- OK, other constants too!!!
};
EURamSimple: Rosemary.EvalProc = {
state: EURamState ← NARROW[stateAny];
{OPEN state;
max: NAT ← 255;
anyX, oneHiA, oneHiB, oneHiC, oneHiAlow, oneHiBlow, oneHiClow: BOOLFALSE;
aAdr, bAdr, cAdr, aLow, bLow, cLow: NAT;
FOR i: NAT IN [0..EUUtils.nRows) DO  -- no two select lines high at the same time
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..4) DO -- no two select lines high at the same time
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 Ports.CopyLS[p[cBus].ls, ram[4*cAdr+cLow]];
IF anyX THEN ResetRam[state, X]; -- nasty stuff!!!
IF oneHiA AND oneHiAlow THEN Ports.CopyLS[ram[4*aAdr+aLow], p[ramA].ls];
IF oneHiB AND oneHiBlow THEN Ports.CopyLS[ram[4*bAdr+bLow], p[ramB].ls];
}};