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: NAT ← LAST[NAT],
lastClock: BOOL];
mem: ARRAY [0..memMax] OF Rope.ROPE;
-------------------- Tamarin Memory Initialization ---------------------
ReadMemory:
PUBLIC
PROC [name: Rope.
ROPE ←
NIL] = {
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:
ATOM ←
NIL]
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.