<<-- TamRegFileCells.mesa Copyright Ó 1987 by Xerox Corporation. All rights reserved. September 29, 1987 10:01:20 pm PDT Last Edited by: Krivacic April June 26, 1987 3:09:37 pm PDT >> <> DIRECTORY Basics, BitOps, Core, CoreCreate, CoreFlat, CoreClasses, Logic, CoreProperties, Ports, Rosemary, RosemaryUser, TamPorts, Rope, TamDefs, TerminalIO, IO; TamRegFileCells: CEDAR PROGRAM IMPORTS Ports, Rosemary, TamPorts, TerminalIO, IO = BEGIN OPEN TamDefs, TamPorts; <<-- Register File Implementation>> <<>> banks: NAT = 6; bankSize: NAT = 40; nextRegAddr: NAT _ 0; curRegAddr: ARRAY BOOL OF NAT; registerArray: ARRAY [0..576) OF Rope.ROPE; debug: BOOL _ FALSE; RegisterFile: PUBLIC PROC[r: Rope.ROPE, uWriteOctal, uDSwap: BOOL, regAddr: NAT, nClock, nClock2, writeOk, writeBack: BOOL] RETURNS [d1, d2: Rope.ROPE]= { IF nClock2 THEN nextRegAddr _ regAddr ELSE {curRegAddr[~nClock] _ nextRegAddr; IF debug THEN TerminalIO.PutF["Set RegAddr[%g] _ %g \n", IO.bool[~nClock], IO.int[nextRegAddr]]; }; d1 _ registerArray[curRegAddr[TRUE]]; d2 _ (IF (curRegAddr[TRUE]-1) >= 0 THEN registerArray[curRegAddr[TRUE]-1] ELSE "0000000000000000000000000000000000"); IF d1 = NIL THEN d1 _ "0000000000000000000000000000000000"; IF d2 = NIL THEN d2 _ "0000000000000000000000000000000000"; IF uDSwap THEN {temp: Rope.ROPE _ d1; d1 _ d2; d2 _ temp;}; IF nClock2 AND nClock AND writeOk AND writeBack THEN { registerArray[curRegAddr[FALSE]] _ r; IF debug THEN TerminalIO.PutF["Write RegAddr[%g] _ %g \n", IO.int[curRegAddr[FALSE]], IO.rope[r]]; IF uWriteOctal THEN FOR i: NAT _ curRegAddr[FALSE] + 1, i + 1 WHILE (i MOD 8) # 0 DO registerArray[i] _ r; ENDLOOP; }; }; <<>> <<>> <<-------------------- Create RegFile Cell --------------------->> RegisterFileState: TYPE = REF RegisterFileStateRec; RegisterFileStateRec: TYPE = RECORD [ d1, d2, r, writeBack, writeOk, nextRegAddr, nClock2, nClock, writeOctal, dSwap, rd1addr, rd2addr, state, vdd, gnd: NAT _ LAST[NAT]]; <<-- Rosemary Register File Initialization>> RegisterFileInit: Rosemary.InitProc = { <<>> <<--PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [stateAny: REF ANY _ NIL]-->> state: RegisterFileState _ NEW[RegisterFileStateRec]; [state.vdd, state.gnd] _ Ports.PortIndexes[cellType.public, "Vdd", "Gnd"]; [state.r, state.nextRegAddr, state.writeOctal, state.dSwap, state.rd1addr, state.rd2addr, state.writeBack, state.writeOk, state.nClock2, state.nClock ] _ Ports.PortIndexes[cellType.public, "R", "NextRegAddr", "WriteOctal", "DSwap", "RD1addr", "RD2addr", "WriteBack", "WriteOk", "nClock2", "nClock"]; [state.d1, state.d2] _ Ports.PortIndexes[cellType.public, "D1", "D2"]; [] _ Rosemary.SetFixedWire[cellType.public[state.vdd], H]; [] _ Rosemary.SetFixedWire[cellType.public[state.gnd], L]; stateAny _ state; }; <<-- Rosemary Register File Eval Proc>> RegisterFileEvalSimple: Rosemary.EvalProc = { <> XSet: PROC [p: Ports.Port, index: NAT, val: CARD, name: ATOM _ NIL] = { IF HasXs[p, index] THEN { SetPVal[p, index, val]; p[index].d _ none; IF clockset THEN TerminalIO.PutF["X Input in Reg File: %g index: %g \n", IO.atom[name], IO.int[index]]; }; }; state: RegisterFileState _ NARROW[stateAny]; d1, d2: Rope.ROPE; clockset: BOOL_ TRUE; anyXs: BOOL _ FALSE; -- Clear any inputs with X'x XSet[p, state.nClock, 0, $nClock]; XSet[p, state.nClock2, 0, $nClock2]; clockset _ PortToBool[p,state.nClock2]; XSet[p, state.r, 0, $r]; XSet[p, state.writeBack, 0, $writeBack]; XSet[p, state.writeOk, 0, $writeOk]; XSet[p, state.dSwap, 0, $dSwap]; XSet[p, state.rd1addr, 0, $rd1addr]; XSet[p, state.rd2addr, 0, $rd2addr]; XSet[p, state.nextRegAddr, 0, $nextRegAddr]; IF ~anyXs THEN { [d1, d2] _ RegisterFile[Ports.LSToRope[p[state.r].ls, 34, 2], PortToBool[p,state.writeOctal], PortToBool[p,state.dSwap], PortToNat[p,state.nextRegAddr], PortToBool[p,state.nClock], PortToBool[p,state.nClock2], PortToBool[p,state.writeOk], PortToBool[p,state.writeBack] ]; TamPorts.RopeToLS[d1, p[state.d1].ls]; TamPorts.RopeToLS[d2, p[state.d2].ls]; p[state.d1].d _ (IF PortToNat[p,state.rd1addr] = 0 THEN drive ELSE none); p[state.d2].d _ (IF PortToNat[p,state.rd2addr] = 0 THEN drive ELSE none); } ELSE { p[state.d1].d _ none; p[state.d2].d _ none; }; }; regFileName: Rope.ROPE _ Rosemary.Register[roseClassName: "RegisterFileTile", init: RegisterFileInit, evalSimple: RegisterFileEvalSimple]; <<>> END.