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: NAT _ LAST[NAT], ram: SEQUENCE size: NAT OF Ports.LevelSequence]; CreateEURam: PUBLIC PROC [] RETURNS [ct: CellType] = { ct _ EUUtils.Fetch["EURam"]; IF ct=NIL THEN { ct _ EUUtils.Extract["EURam.sch"]; EUUtils.Store["EURam", ct]; }; }; CreateRamTop: PUBLIC PROC RETURNS [cellType: CellType] = { cellType _ EUUtils.CSeqX["RamTop", EUUtils.Extract["PrechQuadSt.sch"], 32, LIST["naBit", "bBit", "cBit", "ncBit"]]; }; 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]; }; CreateRamRow: PROC RETURNS [cellType: CellType] = { cellType _ EUUtils.CSeqX["RamRow", EUUtils.Extract["RamQuadSt.sch"], 32, LIST["naBit", "bBit", "cBit", "ncBit"]]; }; 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 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]; }; 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]; }; CreateRamMux: PUBLIC PROC RETURNS [cellType: CellType] = { cellType _ EUUtils.CSeqX["RamMux", EUUtils.Extract["MuxQuadSt.sch"], 32, LIST["naBit", "bBit", "cBit", "ncBit", "na", "b", "c", "nc"]]; }; CreateRamReadWrite: PUBLIC PROC RETURNS [cellType: CellType] = { cellType _ EUUtils.CSeqX["RamReadWrite", EUUtils.Extract["RamRW.sch"], 32, LIST["na", "b", "c", "nc", "ramA", "ramB", "cBus"]]; }; END. °EURamImpl.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 August 11, 1986 11:58:52 pm PDT Last Edited by: Louis Monier November 6, 1986 3:27:12 pm PST -- (ramA, ramB, cBus)[0..32), selRam((selA, selB, selC)[0..nRows), (selALow, selBLow, selCLow)[0..4) ), Vdd, Gnd, nPrech -- Pull-up on top -- (naBit, bBit, cBit, ncBit)[0..32)[0..4), nPrech, Vdd, Gnd -- 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 -- The RAM row -- (naBit, bBit, cBit, ncBit)[0..32)[0..4), selA, selB, selC, Vdd, Gnd -- The ROM row -- (naBit, bBit, cBit, ncBit)[0..32)[0..4), selA, selB, selC, Vdd, Gnd -- 0 is msb, on the left, and must be at the beginning of the list -- (naBit, bBit, cBit, ncBit)[0..4), selA, selB, selC, Vdd, Gnd -- Muxes on bottom -- (naBit, bBit, cBit, ncBit)[0..4)[0..32), (na, b, c, nc)[0..32), (selALow, selBLow, selCLow)[0..4), Gnd -- Read-write on bottom -- (na, b, c, nc, ramA, ramB, cBus)[0..32), Vdd, Gnd 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: BOOL _ FALSE; 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]; }}; Κ3– "cedar" style˜codešœ™Kšœ Οmœ1™—Kšœ˜—K™Kš‘™Kšœ4™4š œžœžœžœ˜@šœJ˜JKšžœ0˜4—Kšœ˜—K™Kšžœ˜K˜K™J˜K™Kš œžœW™kK˜šΠbn œ™ Kšœžœ!™8šœžœ™ šœJ™JKšœ~™~—šžœžœžœž™)Kšœ žœž™-Kšžœ™ ——Kšœ™Kšœ™Kšœ™—š œžœ(™6Kš žœžœžœžœžœ™LKšœ.’™KK™—šŸ œ™"Kšœžœ ™%Jšœžœ™ Jšœžœ™Jšœ?žœžœ™LJšœ$žœ™(š žœžœžœžœ’,™QKš žœžœžœžœžœžœ™NKš žœžœžœžœžœžœ™NKš žœžœžœžœžœžœ™NKšœ žœžœžœ™EKšžœ™—šžœžœžœž’-™Dšžœžœ™Kšžœ žœžœžœ™;—šžœžœ™Kšžœ žœžœžœ™;—šžœžœ™Kšžœ žœžœžœ™;—Kšžœ™—Jšžœžœ žœ,™HKšžœžœ’™2Kšžœžœ žœ,™HJšžœžœ žœ,™HKšœ™K™—K˜—…—τ$Χ