TamMemCells.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Krivacic September 23, 1987 2:42:24 pm PDT
Last Edited by: Krivacic September 14, 1987 2:43:13 pm
DIRECTORY
Basics, BitOps, Core, CoreClasses, CoreCreate, CoreProperties, Ports, Rosemary, RosemaryUser, TamPorts, Rope, TamDefs, TamarinUtilImpl, TerminalIO, IO, Sisyph, FS;
TamMemCells: CEDAR PROGRAM
IMPORTS Ports, Rosemary, TamPorts, TamarinUtilImpl, TerminalIO, IO, CoreClasses, CoreCreate, FS, Rope
SHARES TamarinUtilImpl
= BEGIN OPEN TamDefs;
-------------------- Tamarin Memory Types ---------------------
memMax: NAT = 1000;
MemState: TYPE = REF MemStateRec;
MemStateRec: TYPE = RECORD [
writeData, writeTag, writeCycle, cas, physAddr, x, nClock, vdd, gnd: NATLAST[NAT],
lastClock: BOOL];
mem: ARRAY [0..memMax] OF Rope.ROPE;
-------------------- Tamarin Memory Initialization ---------------------
ReadMemory: PUBLIC PROC [name: Rope.ROPENIL] = {
stream: IO.STREAM;
memIndex: NAT;
memData: Rope.ROPE;
stream ← FS.StreamOpen[(IF name = NIL THEN "TamMemory" ELSE name)];
WHILE ~IO.EndOf[stream] DO
memIndex ← IO.GetInt[stream];
memData ← IO.GetTokenRope[stream].token;
mem[memIndex] ← memData;
ENDLOOP;
IO.Close[stream];
};
-------------------- Tamarin Memory Cell Creation ---------------------
CreateMemory: PUBLIC PROC [tamarinCx: Sisyph.Context] RETURNS [cellType: Core.CellType] = {
cellType 𡤌oreClasses.CreateUnspecified[CoreCreate.WireList[LIST["Vdd", "Gnd", "nClock", "WriteData", "WriteTag", "WriteCycle", "Cas", CoreCreate.Seq["PhysAddr", 32], CoreCreate.Seq["X", 40] ]], "Memory"];
[] ← Ports.InitPorts[cellType, l, none, "Vdd", "Gnd", "nClock", "WriteData", "WriteTag", "WriteCycle"];
[] ← Ports.InitPorts[cellType, ls, none, "PhysAddr", "X"];
};
-------------------- Tamarin Memory Cell Initialization ---------------------
MemInit: Rosemary.InitProc = {
--PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [stateAny: REF ANY ← NIL]--
state: MemState ← NEW[MemStateRec];
state.lastClock ← FALSE;
[state.vdd, state.gnd, state.nClock] ← Ports.PortIndexes[cellType.public, "Vdd", "Gnd", "nClock"];
[state.writeData, state.writeTag, state.writeCycle, state.cas, state.physAddr, state.x] ← Ports.PortIndexes[cellType.public, "WriteData", "WriteTag", "WriteCycle", "Cas", "PhysAddr", "X"];
[] ← Rosemary.SetFixedWire[cellType.public[state.vdd], H];
[] ← Rosemary.SetFixedWire[cellType.public[state.gnd], L];
stateAny ← state;
};
-------------------- Tamarin Memory Evaluation Proc ---------------------
MemEvalSimple: Rosemary.EvalProc = {
PROC [p: Ports.Port, stateAny: REF ANY]--
XSet: PROC [p: Ports.Port, index: NAT, val: CARD, name: ATOMNIL] RETURNS [pval: CARD] =
{
IF TamPorts.HasXs[p, index] THEN {
TamPorts.SetPVal[p, index, val];
p[index].d ← none;
TerminalIO.PutF["X Input in Mem: %g index: %g \n", IO.atom[name], IO.int[index]];
};
pval ← TamPorts.PortToCard[p, index];
};
state: MemState   ← NARROW[stateAny];
-- Clear any inputs with X's, setup to go to Reset
nClock: CARD ← XSet[p, state.nClock, 0, $nClock];
writeData: CARD ← XSet[p, state.writeData, 0, $writeData];
writeTag: CARD ← XSet[p, state.writeTag, 0, $writeTag];
writeCycle: CARD ← XSet[p, state.writeCycle, 0, $writeCycle];
casXSet: CARD ← XSet[p, state.cas, 0, $cas];
physAddr: CARD ← XSet[p, state.physAddr, 0, $physAddr];
clockset: BOOL ← TamPorts.PortToBool[p, state.nClock];
writing: BOOL ← TamPorts.PortToBool[p, state.writeCycle];
wtag: BOOL ← TamPorts.PortToBool[p, state.writeTag];
wdata: BOOL ← TamPorts.PortToBool[p, state.writeData];
cas: BOOL ← TamPorts.PortToBool[p, state.cas];
tag, data, xBus, memRope: Rope.ROPE;
p[state.x].d ← none;
IF clockset AND cas THEN
IF writing THEN {  -- chip is writing memory
xBus ← Ports.LSToRope[p[state.x].ls, 40, 2];
tag ← Rope.Substr[(IF wtag THEN xBus ELSE mem[physAddr]), 0, 6];
data ← Rope.Substr[(IF wdata THEN xBus ELSE mem[physAddr]), 6, 34];  
memRope ← Rope.Concat[tag, data];
mem[physAddr] ← memRope;
TerminalIO.PutF["Writing Mem[%g] ← %g \n", IO.int[physAddr], IO.rope[memRope]];
}
ELSE {    -- chip is reading memory
memRope ← mem[physAddr];
TamPorts.RopeToLS[memRope, p[state.x].ls];
p[state.x].d ← drive;
TerminalIO.PutF["Reading Mem[%g] ← %g \n", IO.int[physAddr], IO.rope[memRope]];
};
stateAny ← state;
};
uCodeName: Rope.ROPE = Rosemary.Register[roseClassName: "Memory", init: MemInit, evalSimple: MemEvalSimple];
END.