<> 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: 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 _CoreClasses.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 = { <> 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. <<>>