Basics, BitOps, Core, CoreClasses, CoreCreate, CoreProperties, Ports, Rosemary, RosemaryUser, TamPorts, Rope, TamDefs, TamSim;
PcCells:
CEDAR
PROGRAM
IMPORTS Ports, Rosemary, TamPorts, TamSim, Basics, TamDefs
= BEGIN OPEN TamDefs, TamPorts, TamSim;
busBits: NAT ← 32;
-------------------- PcLogic ---------------------
PcState: TYPE = REF PcStateRec;
PcStateRec: TYPE = RECORD [d1, r, uRD1Addr, uW2Addr, uOpLength, clocks, pcNext, pcWrite, pcAddr, iBufEmpty, vdd, gnd: NAT ← LAST[NAT]];
PcInit: Rosemary.InitProc = {
--PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [stateAny: REF ANY ← NIL]--
state: PcState ← NEW[PcStateRec];
[] ← Ports.InitPorts[cellType, ls, none, "D1", "R", "uRD1Addr", "uW2Addr", "uOpLength", "clocks"];
[] ← Ports.InitPorts[cellType, ls, drive, "PcNext", "PcWrite", "PcAddr", "IBufEmpty"];
[state.d1, state.r, state.uRD1Addr, state.uW2Addr, state.uOpLength, state.clocks, state.pcNext, state.pcWrite, state.pcAddr, state.iBufEmpty, state.vdd, state.gnd] ← Ports.PortIndexes[cellType.public, "D1", "R", "uRD1Addr", "uW2Addr", "uOpLength", "clocks", "PcNext", "PcWrite", "PcAddr", "IBufEmpty", "Vdd", "Gnd"];
[] ← Rosemary.SetFixedWire[cellType.public[state.vdd], H];
[] ← Rosemary.SetFixedWire[cellType.public[state.gnd], L];
stateAny ← state;
};
PcEvalSimple: Rosemary.EvalProc = {
-- PROC [p: Ports.Port, stateAny: REF ANY]--
d1: Word;
pcNext, pcWrite, iBufEmpty: NAT;
state: PcState ← NARROW[stateAny];
hasXs: BOOL ← TamPorts.HasXs[p, state.d1] OR TamPorts.HasXs[p, state.uRD1Addr] OR TamPorts.HasXs[p, state.uW2Addr] OR TamPorts.HasXs[p, state.uOpLength] OR TamPorts.HasXs[p, state.clocks];
[d1, pcNext, pcWrite, iBufEmpty] ←
PcLogic[
PortToWord[p,state.r],
PortToNat[p,state.uRD1Addr],
PortToNat[p,state.uW2Addr],
PortToNat[p,state.uOpLength],
PortToNat[p,state.clocks]];
IF d1 = OnesWord THEN ClrP[p[state.d1], 1] ELSE SetPWord[p[state.d1], 1, d1];
SetP[p, state.pcNext, pcNext];
SetP[p, state.pcWrite, pcWrite];
SetP[p, state.iBufEmpty, iBufEmpty];
};
-------------------- IBufLogic ---------------------
IBufState: TYPE = REF IBufStateRec;
IBufStateRec: TYPE = RECORD [d1, d2, xBus, pcNext, ibWaddr, wtIbuf, stopIBWt, opLength, opLength0, selIBufData, clock, r, ibufN, opCode, vdd, gnd: NAT ← LAST[NAT],
iBufArray: ARRAY [0..7] OF CARD,
valid: ARRAY[0..7] OF BOOL,
lastClock: BOOL
];
IBufInit: Rosemary.InitProc = {
--PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [stateAny: REF ANY ← NIL]--
state: IBufState ← NEW[IBufStateRec];
[] ← Ports.InitPorts[cellType, l, none, "Vdd", "Gnd"];
[] ← Ports.InitPorts[cellType, ls, none, "D1", "D2", "XBus", "PCNext", "IbWaddr", "WtIbuf", "StopIbWt", "OpLength", "OpLength0", "SelIBufData", "Clock"];
[] ← Ports.InitPorts[cellType, ls, drive, "R", "IbufN", "OpCode"];
[state.vdd, state.gnd] ← Ports.PortIndexes[cellType.public, "Vdd", "Gnd"];
[state.d1, state.d2, state.xBus, state.pcNext, state.ibWaddr, state.wtIbuf, state.stopIBWt, state.opLength, state.opLength0, state.selIBufData, state.clock] ← Ports.PortIndexes[cellType.public, "D1", "D2", "XBus", "PCNext", "IbWaddr", "WtIbuf", "StopIbWt", "OpLength", "OpLength0", "SelIBufData", "Clock"];
[state.r, state.ibufN, state.opCode] ← Ports.PortIndexes[cellType.public, "R", "IbufN", "OpCode"];
state.valid ← [FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE];
state.iBufArray ← [0, 0, 0, 0, 0, 0, 0, 0];
state.lastClock ← FALSE;
[] ← Rosemary.SetFixedWire[cellType.public[state.vdd], H];
[] ← Rosemary.SetFixedWire[cellType.public[state.gnd], L];
stateAny ← state;
};
IBufEvalSimple: Rosemary.EvalProc = {
PROC [p: Ports.Port, stateAny: REF ANY]--
overFlow, carry, gt: BOOL ← FALSE;
state: IBufState ← NARROW[stateAny];
hasXs: BOOL ← TamPorts.HasXs[p, state.opCode] OR TamPorts.HasXs[p, state.pcNext] OR TamPorts.HasXs[p, state.ibWaddr] OR TamPorts.HasXs[p, state.wtIbuf] OR TamPorts.HasXs[p, state.opLength] OR TamPorts.HasXs[p, state.selIBufData] OR TamPorts.HasXs[p, state.d1] OR TamPorts.HasXs[p, state.d2];
};
-------------------- InstDP ---------------------
InstDPState: TYPE = REF InstDPStateRec;
InstDPStateRec: TYPE = RECORD [d1, r, load, nByteSel, selIBufData, shiftSel, selCur, selNext, selWrite, nWtIBuf, clock, ibufN, opCode, xBus, vdd, gnd: NAT ← LAST[NAT],
iBufArray: ARRAY [0..7] OF CARD,
valid: ARRAY[0..7] OF BOOL,
lastClock: BOOL
];
InstDPInit: Rosemary.InitProc = {
--PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [stateAny: REF ANY ← NIL]--
state: InstDPState ← NEW[InstDPStateRec];
[] ← Ports.InitPorts[cellType, l, none, "Vdd", "Gnd"];
[] ← Ports.InitPorts[cellType, ls, none, "R", "load", "nByteSel", "SelIBufData", "ShiftSel", "SelCur", "SelNext", "SelWrite", "nWtIBuf", "CK", "XBus"];
[] ← Ports.InitPorts[cellType, ls, drive, "D1", "IbufN", "OpCode"];
[state.vdd, state.gnd] ← Ports.PortIndexes[cellType.public, "Vdd", "Gnd"];
[state.r, state.load, state.nByteSel, state.selIBufData, state.shiftSel, state.selCur, state.selNext, state.selWrite, state.nWtIBuf, state.clock, state.xBus] ← Ports.PortIndexes[cellType.public, "R", "load", "nByteSel", "SelIBufData", "ShiftSel", "SelCur", "SelNext", "SelWrite", "nWtIBuf", "CK", "XBus"];
[state.d1, state.ibufN, state.opCode] ← Ports.PortIndexes[cellType.public, "D1", "IbufN", "OpCode"];
state.valid ← [FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE];
state.iBufArray ← [0, 0, 0, 0, 0, 0, 0, 0];
state.lastClock ← FALSE;
[] ← Rosemary.SetFixedWire[cellType.public[state.vdd], H];
[] ← Rosemary.SetFixedWire[cellType.public[state.gnd], L];
stateAny ← state;
};
InstDPEvalSimple: Rosemary.EvalProc = {
PROC [p: Ports.Port, stateAny: REF ANY]--
ibl, nibl, curIWd, nextIWd, iBSres, D1: TamDefs.Word ← ZerosWord;
ibufN, opCode, selIBufData: NAT ← 0;
state: InstDPState ← NARROW[stateAny];
xS: BOOL ← HasXs[p, state.selCur] OR HasXs[p, state.selNext] OR HasXs[p, state.selWrite];
ClrP[p, state.ibufN];
ClrP[p, state.opCode];
IF
NOT xS
THEN {
IF
NOT (HasXs[p, state.xBus]
OR HasXs[p, state.nWtIBuf]
OR HasXs[p, state.clock])
THEN
[ibl, nibl] ←
IBufDrive[
PortToWord[p, state.xBus],
PortToNat[p, state.nWtIBuf],
PortToNat[p, state.clock]];
IF
NOT (HasXs[p, state.selCur]
OR HasXs[p, state.selNext]
OR HasXs[p, state.selWrite])
THEN
[curIWd, nextIWd] ←
IBufReg[ibl, nibl,
PortToNat[p, state.selCur],
PortToNat[p, state.selNext],
PortToNat[p, state.selWrite]];
IF
NOT TamPorts.HasXs[p, state.shiftSel]
THEN
[iBSres, ibufN, opCode] ←
IShifter[curIWd, nextIWd,
PortToNat[p, state.shiftSel]];
SetP[p, state.opCode, opCode];
SetP[p, state.ibufN, ibufN];
IF
NOT (HasXs[p, state.selIBufData]
OR HasXs[p, state.nByteSel]
OR HasXs[p, state.load]
OR HasXs[p, state.clock])
THEN
D1 ←
TamSim.IBufDataRegs[iBSres, selIBufData ← PortToNat[p, state.selIBufData],
Basics.BITXOR[PortToNat[p, state.nByteSel], 0FH],
PortToNat[p, state.load],
PortToNat[p, state.clock]];
};
IF selIBufData = 1 THEN SetPWord[p[state.d1], 1, D1] ELSE ClrP[p[state.d1], 1];
};
-------------------- IBuf6TCell ---------------------
IBuf6TCellState: TYPE = REF IBuf6TCellStateRec;
IBuf6TCellStateRec: TYPE = RECORD [in, nIn, selWrite, out, vdd, gnd: NAT ← LAST[NAT], storedval: NAT];
IBuf6TCellInit: Rosemary.InitProc = {
--PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [stateAny: REF ANY ← NIL]--
state: IBuf6TCellState ← NEW[IBuf6TCellStateRec];
[] ← Ports.InitPorts[cellType, l, none, "Vdd", "Gnd"];
[] ← Ports.InitPorts[cellType, ls, none, "In", "nIn", "SelWrite"];
[] ← Ports.InitPorts[cellType, ls, drive, "Out",];
[state.vdd, state.gnd] ← Ports.PortIndexes[cellType.public, "Vdd", "Gnd"];
[state.in, state.nIn, state.selWrite, state.out] ← Ports.PortIndexes[cellType.public, "In", "nIn", "SelWrite", "Out"];
state.storedval ← 0;
[] ← Rosemary.SetFixedWire[cellType.public[state.vdd], H];
[] ← Rosemary.SetFixedWire[cellType.public[state.gnd], L];
stateAny ← state;
};
IBuf6TCellEvalSimple: Rosemary.EvalProc = {
PROC [p: Ports.Port, stateAny: REF ANY]--
state: IBuf6TCellState ← NARROW[stateAny];
xS: BOOL ← HasXs[p, state.in] OR HasXs[p, state.nIn] OR HasXs[p, state.selWrite];
IF
NOT xS
THEN
IF PortToNat[p, state.selWrite] = 1
THEN {
in: NAT ← PortToNat[p, state.in];
nIn: NAT ← PortToNat[p, state.nIn];
IF (in + nIn) = 1 THEN state.storedval ← in;
};
SetP[p, state.out, state.storedval];
p[state.out].d ← drive;
stateAny ← state;
};
BoolToInt:
PROC [b:
BOOL]
RETURNS [
NAT] = {
RETURN[
IF b
THEN 1
ELSE 0]};
EUSelect:
PROC [p: Ports.Port, portindex:
NAT]
RETURNS [
NAT] = {
RETURN[TamPorts.PortToNat[p, portindex] / 16];
};
EUMask:
PROC [p: Ports.Port, portindex:
NAT]
RETURNS [
CARD] = {
RETURN[TamPorts.PortToNat[p, portindex] MOD 16];
};
-------------------- LU - Logical Unit ---------------------
LuState: TYPE = REF LuStateRec;
LuStateRec: TYPE = RECORD [d1, d2, r, euControl, nEuControl, vdd, gnd: NAT ← LAST[NAT]];
LuInit: Rosemary.InitProc = {
--PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [stateAny: REF ANY ← NIL]--
state: LuState ← NEW[LuStateRec];
[] ← Ports.InitPorts[cellType, ls, none, "D1", "D2", "EUControl", "nEUControl"];
[] ← Ports.InitPorts[cellType, ls, drive, "R"];
[state.d1, state.d2, state.r, state.euControl, state.nEuControl, state.vdd, state.gnd] ← Ports.PortIndexes[cellType.public, "D1", "D2", "R", "EUControl", "nEUControl", "Vdd", "Gnd"];
[] ← Rosemary.SetFixedWire[cellType.public[state.vdd], H];
[] ← Rosemary.SetFixedWire[cellType.public[state.gnd], L];
stateAny ← state;
};
LuEvalSimple: Rosemary.EvalProc = {
PROC [p: Ports.Port, stateAny: REF ANY]--
state: LuState ← NARROW[stateAny];
hasXs: BOOL ← TamPorts.HasXs[p, state.euControl] OR TamPorts.HasXs[p, state.d1] OR TamPorts.HasXs[p, state.d2];
IF (
NOT hasXs)
AND (
LOOPHOLE[EUSelect[p, state.euControl], EuUnits] =
LU)
THEN
TamPorts.SetP[
p,
state.r,
WordToCard[
LogicalUnit[
EUMask[p, state.euControl],
PortToWord[p[state.d1], 1],
PortToWord[p[state.d2], 1]]]]
ELSE TamPorts.ClrP[p[state.r], 1];
};
-------------------- Adder ---------------------
AdderState: TYPE = REF AdderStateRec;
AdderStateRec: TYPE = RECORD [d1, d2, r, euControl, nEuControl, euCC, vdd, gnd: NAT ← LAST[NAT]];
AdderInit: Rosemary.InitProc = {
--PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [stateAny: REF ANY ← NIL]--
state: AdderState ← NEW[AdderStateRec];
[] ← Ports.InitPort[
wire: Ports.FindWire[cellType.public, "D1"],
levelType: composite,
driveType: aggregate,
initDrive: none,
initDrives:
NIL
];
[] ← Ports.InitPorts[cellType, l, none, "Vdd", "Gnd"];
[] ← Ports.InitPorts[cellType, ls, none, "D1", "D2", "EUControl", "nEUControl"];
[] ← Ports.InitPorts[cellType, ls, drive, "R", "euCC"];
[state.d1, state.d2, state.r, state.euControl, state.nEuControl, state.euCC, state.vdd, state.gnd] ← Ports.PortIndexes[cellType.public, "D1", "D2", "R", "EUControl", "nEUControl", "euCC", "Vdd", "Gnd"];
[] ← Rosemary.SetFixedWire[cellType.public[state.vdd], H];
[] ← Rosemary.SetFixedWire[cellType.public[state.gnd], L];
stateAny ← state;
};
AdderEvalSimple: Rosemary.EvalProc = {
PROC [p: Ports.Port, stateAny: REF ANY]--
result: TamDefs.Word;
overFlow, carry, gt: BOOL ← FALSE;
state: AdderState ← NARROW[stateAny];
hasXs: BOOL ← TamPorts.HasXs[p, state.euControl] OR TamPorts.HasXs[p, state.d1] OR TamPorts.HasXs[p, state.d2];
IF
NOT hasXs
THEN
[result, overFlow, carry, gt] ←
TamSim.Adder[
EUMask[p, state.euControl],
TamPorts.PortToWord[p, state.d1],
TamPorts.PortToWord[p, state.d2]];
TamPorts.SetP[p, state.euCC, BoolToInt[carry]*4+BoolToInt[overFlow]*2+BoolToInt[gt]];
IF (
NOT hasXs)
AND (
LOOPHOLE[EUSelect[p, state.euControl], EuUnits] = Adder)
THEN
TamPorts.SetP[p, state.r, TamDefs.WordToCard[result]]
ELSE TamPorts.ClrP[p, state.r];
};
-------------------- Shifter ---------------------
ShifterState: TYPE = REF ShifterStateRec;
ShifterStateRec: TYPE = RECORD [d1, d2, r, euControl, nEuControl, muxBus, vdd, gnd: NAT ← LAST[NAT]];
ShifterInit: Rosemary.InitProc = {
--PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [stateAny: REF ANY ← NIL]--
state: ShifterState ← NEW[ShifterStateRec];
[] ← Ports.InitPorts[cellType, l, none, "Vdd", "Gnd"];
[] ← Ports.InitPorts[cellType, ls, none, "D1", "D2", "MuxBus", "EUControl", "nEUControl"];
[] ← Ports.InitPorts[cellType, ls, drive, "R"];
[state.d1, state.d2, state.r, state.euControl, state.nEuControl, state.muxBus, state.vdd, state.gnd] ← Ports.PortIndexes[cellType.public, "D1", "D2", "R", "EUControl", "nEUControl", "MuxBus", "Vdd", "Gnd"];
[] ← Rosemary.SetFixedWire[cellType.public[state.vdd], H];
[] ← Rosemary.SetFixedWire[cellType.public[state.gnd], L];
stateAny ← state;
};
ShifterEvalSimple: Rosemary.EvalProc = {
PROC [p: Ports.Port, stateAny: REF ANY]--
state: ShifterState ← NARROW[stateAny];
hasXs: BOOL ← TamPorts.HasXs[p, state.euControl] OR TamPorts.HasXs[p, state.d1] OR TamPorts.HasXs[p, state.d2] OR TamPorts.HasXs[p, state.muxBus];
IF (
NOT hasXs)
AND (
LOOPHOLE[EUSelect[p, state.euControl], EuUnits] = Shifter)
THEN
TamPorts.SetP[p, state.r,
TamDefs.WordToCard[
TamSim.Shifter[
EUMask[p, state.euControl],
TamPorts.PortToWord[p, state.d1],
TamPorts.PortToWord[p, state.d2],
TamPorts.GetPVal[p, state.muxBus]]]]
ELSE TamPorts.ClrP[p, state.r];
};
-------------------- Priority ---------------------
PriorityState: TYPE = REF PriorityStateRec;
PriorityStateRec: TYPE = RECORD [d1, r, euControl, vdd, gnd: NAT ← LAST[NAT]];
PriorityInit: Rosemary.InitProc = {
--PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [stateAny: REF ANY ← NIL]--
state: PriorityState ← NEW[PriorityStateRec];
[] ← Ports.InitPorts[cellType, l, none, "Vdd", "Gnd"];
[] ← Ports.InitPorts[cellType, ls, none, "D1", "EUControl"];
[] ← Ports.InitPorts[cellType, ls, drive, "R"];
[state.d1, state.r, state.euControl, state.vdd, state.gnd] ← Ports.PortIndexes[cellType.public, "D1", "R", "EUControl", "Vdd", "Gnd"];
[] ← Rosemary.SetFixedWire[cellType.public[state.vdd], H];
[] ← Rosemary.SetFixedWire[cellType.public[state.gnd], L];
stateAny ← state;
};
PriorityEvalSimple: Rosemary.EvalProc = {
PROC [p: Ports.Port, stateAny: REF ANY]--
state: PriorityState ← NARROW[stateAny];
hasXs: BOOL ← TamPorts.HasXs[p, state.d1];
IF (
NOT hasXs)
AND (
LOOPHOLE[EUSelect[p, state.euControl], EuUnits] = Prior)
THEN
TamPorts.SetP[p, state.r,
TamDefs.WordToCard[
TamSim.PriorityEncoder[
TamPorts.PortToWord[p, state.d1]]]]
ELSE TamPorts.ClrP[p, state.r];
};
-------------------- ExecutionUnits ---------------------
ExecutionUnitsState: TYPE = REF ExecutionUnitsStateRec;
ExecutionUnitsStateRec: TYPE = RECORD [d1, d2, r, euControl, muxBus, euCC, vdd, gnd: NAT ← LAST[NAT]];
ExecutionUnitsInit: Rosemary.InitProc = {
--PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [stateAny: REF ANY ← NIL]--
state: ExecutionUnitsState ← NEW[ExecutionUnitsStateRec];
[] ← Ports.InitPorts[cellType, ls, none, "D1", "D2", "MuxBus", "EUControl"];
[] ← Ports.InitPorts[cellType, ls, drive, "R", "euCC"];
[state.d1, state.d2, state.r, state.euControl, state.muxBus, state.euCC, state.vdd, state.gnd] ← Ports.PortIndexes[cellType.public, "D1", "D2", "R", "EUControl", "MuxBus", "euCC", "Vdd", "Gnd"];
[] ← Rosemary.SetFixedWire[cellType.public[state.vdd], H];
[] ← Rosemary.SetFixedWire[cellType.public[state.gnd], L];
stateAny ← state;
};
ExecutionUnitsEvalSimple: Rosemary.EvalProc = {
PROC [p: Ports.Port, stateAny: REF ANY]--
result: TamDefs.Word;
setresult, overFlow, carry, gt: BOOL ← FALSE;
state: ExecutionUnitsState ← NARROW[stateAny];
hasXs: BOOL ← TamPorts.HasXs[p, state.euControl] OR TamPorts.HasXs[p, state.d1] OR TamPorts.HasXs[p, state.d2] OR TamPorts.HasXs[p, state.muxBus];
IF
NOT hasXs
THEN
[setresult, result, overFlow, carry, gt] ←
TamSim.ExecutionUnits[
TamPorts.PortToNat[p, state.euControl],
TamPorts.PortToWord[p, state.d1],
TamPorts.PortToWord[p, state.d2],
TamPorts.PortToNat[p, state.muxBus]];
IF hasXs
OR NOT setresult
THEN TamPorts.ClrP[p, state.r]
ELSE TamPorts.SetP[p, state.r, TamDefs.WordToCard[result]] ;
TamPorts.SetP[p, state.euCC, BoolToInt[carry]*4+BoolToInt[overFlow]*2+BoolToInt[gt]];
};
-------------------- Register File ---------------------
RegisterFileState: TYPE = REF RegisterFileStateRec;
RegisterFileStateRec: TYPE = RECORD [
d1, d2, r, writeOctal, dSwap, rd1Addr, rd2Addr, state, nextRAddr, clocks, vdd, gnd: NAT ← LAST[NAT]];
RegisterFileInit: Rosemary.InitProc = {
--PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [stateAny: REF ANY ← NIL]--
state: RegisterFileState ← NEW[RegisterFileStateRec];
[] ← Ports.InitPorts[cellType, l, none, "Vdd", "Gnd", "Clocks"];
[] ← Ports.InitPorts[cellType, ls, none, "R", "WriteOctal", "DSwap", "Rd1Addr", "Rd2Addr", "NextRAddr"];
[] ← Ports.InitPorts[cellType, ls, drive, "D1", "D2"];
[state.vdd, state.gnd, state.clocks] ← Ports.PortIndexes[cellType.public, "Vdd", "Gnd", "Clocks"];
[state.r, state.writeOctal, state.dSwap, state.rd1Addr, state.rd2Addr, state.nextRAddr] ← Ports.PortIndexes[cellType.public, "R", "WriteOctal", "DSwap", "Rd1Addr", "Rd2Addr", "NextRAddr"];
[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;
};
RegisterFileEvalSimple: Rosemary.EvalProc = {
PROC [p: Ports.Port, stateAny: REF ANY]--
state: RegisterFileState ← NARROW[stateAny];
d1, d2: TaggedWord;
setd1, setd2: BOOL;
xS: BOOL ← HasXs[p, state.clocks] OR HasXs[p, state.writeOctal] OR HasXs[p, state.dSwap] OR HasXs[p, state.state] OR HasXs[p, state.nextRAddr];
ClrPTaggedWord[p, state.d1];
ClrPTaggedWord[p, state.d2];
IF
NOT xS
THEN {
[setd1, setd2, d1, d2] ←
RegisterFile[];
IF setd1 THEN SetPTaggedWord[p, state.d1, d1];
IF setd2 THEN SetPTaggedWord[p, state.d1, d2];
};
stateAny ← state;
};
-------------------- RegFile6TRamCell ---------------------
regFile6TCellName: Rope.ROPE = Rosemary.Register[roseClassName: "RegFile6TRamCell", init: RegFile6TRamCellInit, evalSimple: RegFile6TRamCellEvalSimple];
RegFile6TRamCellState: TYPE = REF RegFile6TRamCellStateRec;
RegFile6TRamCellStateRec: TYPE = RECORD [in, nIn, selWrite, out, vdd, gnd: NAT ← LAST[NAT], storedval: NAT];
Reg6TRamCell:
PUBLIC
PROC
RETURNS [ct: CoreCreate.CellType] = {
ct ← CoreClasses.CreateUnspecified[
name: regFile6TCellName,
public: CoreCreate.Wires["In", "nIn", "Out", "SelWrite", "Vdd", "Gnd"]];
[] ← Rosemary.BindCellType[cellType: ct, roseClassName: regFile6TCellName];
[] ← CoreFlat.CellTypeCutLabels[ct, Logic.logicCutSet];
TerminalIO.PutRope["Creating 6T RamCell"];
};
RegFile6TRamCellInit: Rosemary.InitProc = {
--PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [stateAny: REF ANY ← NIL]--
state: RegFile6TRamCellState ← NEW[RegFile6TRamCellStateRec];
[] ← Ports.InitPorts[cellType, l, none, "Vdd", "Gnd"];
[] ← Ports.InitPorts[cellType, l, none, "In", "nIn", "SelWrite"];
[] ← Ports.InitPorts[cellType, l, drive, "Out",];
[state.vdd, state.gnd] ← Ports.PortIndexes[cellType.public, "Vdd", "Gnd"];
[state.in, state.nIn, state.selWrite, state.out] ← Ports.PortIndexes[cellType.public, "In", "nIn", "SelWrite", "Out"];
state.storedval ← 0;
[] ← Rosemary.SetFixedWire[cellType.public[state.vdd], H];
[] ← Rosemary.SetFixedWire[cellType.public[state.gnd], L];
stateAny ← state;
};
RegFile6TRamCellEvalSimple: Rosemary.EvalProc = {
PROC [p: Ports.Port, stateAny: REF ANY]--
state: RegFile6TRamCellState ← NARROW[stateAny];
xS: BOOL ← HasXs[p, state.in] OR HasXs[p, state.nIn] OR HasXs[p, state.selWrite];
IF
NOT xS
THEN
IF PortToNat[p, state.selWrite] = 1
THEN {
in: NAT ← PortToNat[p, state.in];
nIn: NAT ← PortToNat[p, state.nIn];
IF (in + nIn) = 1 THEN state.storedval ← in;
};
IF state.storedval = 1 THEN p[state.out].d ← none
ELSE {SetP[p, state.out, state.storedval]; p[state.out].d ← drive;};
stateAny ← state;
};
-------------------- TagCCLogic ---------------------
TagCCState: TYPE = REF TagCCStateRec;
TagCCStateRec: TYPE = RECORD [d1, d2, uDpCC, tagCC, vdd, gnd: NAT ← LAST[NAT]];
TagCCInit: Rosemary.InitProc = {
--PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [stateAny: REF ANY ← NIL]--
state: TagCCState ← NEW[TagCCStateRec];
[] ← Ports.InitPorts[cellType, ls, none, "D1", "D2", "uDpCC"];
[] ← Ports.InitPorts[cellType, ls, drive, "TagCondRes"];
[state.d1, state.d2, state.uDpCC, state.tagCC, state.vdd, state.gnd] ← Ports.PortIndexes[cellType.public, "D1", "D2", "uDpCC", "TagCondRes", "Vdd", "Gnd"];
[] ← Rosemary.SetFixedWire[cellType.public[state.vdd], H];
[] ← Rosemary.SetFixedWire[cellType.public[state.gnd], L];
stateAny ← state;
};
TagCCEvalSimple: Rosemary.EvalProc = {
-- PROC [p: Ports.Port, stateAny: REF ANY]--
state: TagCCState ← NARROW[stateAny];
hasXs: BOOL ← HasXs[p, state.d1] OR HasXs[p, state.d2] OR HasXs[p, state.uDpCC];
IF
NOT hasXs
THEN
SetP[
p,
state.tagCC,
WordToCard[
TagCC[
PortToNat[p, state.uDpCC],
PortToWord[p, state.d1],
PortToWord[p, state.d2]]]]
ELSE SetP[p, state.tagCC, 0];
stateAny ← state;
};
-------------------- TagUnit Logic ---------------------
TagUnitState: TYPE = REF TagUnitStateRec;
TagUnitStateRec: TYPE = RECORD [d1, d2, r, uTag, vdd, gnd: NAT ← LAST[NAT]];
TagUnitInit: Rosemary.InitProc = {
--PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [stateAny: REF ANY ← NIL]--
state: TagUnitState ← NEW[TagUnitStateRec];
[] ← Ports.InitPorts[cellType, ls, none, "D1Tag", "D2Tag", "uTag"];
[] ← Ports.InitPorts[cellType, ls, drive, "RTag"];
[state.d1, state.d2, state.uTag, state.r, state.vdd, state.gnd] ← Ports.PortIndexes[cellType.public, "D1", "D2", "uTag", "R", "Vdd", "Gnd"];
[] ← Rosemary.SetFixedWire[cellType.public[state.vdd], H];
[] ← Rosemary.SetFixedWire[cellType.public[state.gnd], L];
stateAny ← state;
};
TagUnitEvalSimple: Rosemary.EvalProc = {
-- PROC [p: Ports.Port, stateAny: REF ANY]--
state: TagUnitState ← NARROW[stateAny];
hasXs: BOOL ← HasXs[p, state.d1] OR HasXs[p, state.d2] OR HasXs[p, state.uTag];
IF
NOT hasXs
THEN
SetP[
p,
state.r,
TagUnit[
PortToNat[p, state.uTag],
PortToNat[p, state.d1],
PortToNat[p, state.d2]]]
ELSE SetP[p, state.r, 0];
stateAny ← state;
};
-------------------- SpecialRegs Logic ---------------------
SpecialRegsState: TYPE = REF SpecialRegsStateRec;
SpecialRegsStateRec: TYPE = RECORD [d1, d2, r, uRD1Addr, uRD2Addr, uW2Addr, clocks, vdd, gnd: NAT ← LAST[NAT]];
SpecialRegsInit: Rosemary.InitProc = {
--PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [stateAny: REF ANY ← NIL]--
state: SpecialRegsState ← NEW[SpecialRegsStateRec];
[] ← Ports.InitPorts[cellType, ls, none, "D1", "D2", "uRD1Addr", "uRD2Addr", "uW2Addr", "clocks"];
[] ← Ports.InitPorts[cellType, ls, drive, "R"];
[state.d1, state.d2, state.uRD1Addr, state.uRD2Addr, state.uW2Addr, state.clocks, state.vdd, state.gnd] ← Ports.PortIndexes[cellType.public, "D1", "D2", "uRD1Addr", "uRD2Addr", "uW2Addr", "clocks", "Vdd", "Gnd"];
[] ← Rosemary.SetFixedWire[cellType.public[state.vdd], H];
[] ← Rosemary.SetFixedWire[cellType.public[state.gnd], L];
stateAny ← state;
};
SpecialRegsEvalSimple: Rosemary.EvalProc = {
-- PROC [p: Ports.Port, stateAny: REF ANY]--
state: SpecialRegsState ← NARROW[stateAny];
hasXs: BOOL ← HasXs[p, state.d1] OR HasXs[p, state.d2] OR HasXs[p, state.uRD1Addr] OR HasXs[p, state.uRD2Addr] OR HasXs[p, state.uW2Addr];
IF
NOT hasXs
THEN
SetP[
p,
state.r,
WordToCard[
SpecialRegs[
PortToNat[p, state.uRD1Addr],
PortToWord[p, state.d1],
PortToWord[p, state.d2]]]]
ELSE ClrP[p, state.r];
stateAny ← state;
};
specialRegsName: Rope.ROPE = Rosemary.Register[roseClassName: "SpecialRegs", init: SpecialRegsInit, evalSimple: SpecialRegsEvalSimple];
tagUnitName: Rope.ROPE = Rosemary.Register[roseClassName: "TagUnit", init: TagUnitInit, evalSimple: TagUnitEvalSimple];
tagCCName: Rope.ROPE = Rosemary.Register[roseClassName: "TagCC", init: TagCCInit, evalSimple: TagCCEvalSimple];
regFileName: Rope.ROPE = Rosemary.Register[roseClassName: "RegisterFile", init: RegisterFileInit, evalSimple: RegisterFileEvalSimple];
executionUnitsName: Rope.ROPE = Rosemary.Register[roseClassName: "ExecutionUnits", init: ExecutionUnitsInit, evalSimple: ExecutionUnitsEvalSimple];
shifterName: Rope.ROPE = Rosemary.Register[roseClassName: "Shifter", init: ShifterInit, evalSimple: ShifterEvalSimple];
luName: Rope.ROPE = Rosemary.Register[roseClassName: "LU", init: LuInit, evalSimple: LuEvalSimple];
adderName: Rope.ROPE = Rosemary.Register[roseClassName: "Adder", init: AdderInit, evalSimple: AdderEvalSimple];
priorityName: Rope.ROPE = Rosemary.Register[roseClassName: "Priority", init: PriorityInit, evalSimple: PriorityEvalSimple];
iBuf6TCellName: Rope.ROPE = Rosemary.Register[roseClassName: "IBuf6TCell", init: IBuf6TCellInit, evalSimple: IBuf6TCellEvalSimple];
instDPName: Rope.ROPE = Rosemary.Register[roseClassName: "InstDP", init: InstDPInit, evalSimple: InstDPEvalSimple];
iBufLogicName: Rope.ROPE = Rosemary.Register[roseClassName: "IBufLogic", init: IBufInit, evalSimple: IBufEvalSimple];
PcName: Rope.ROPE = Rosemary.Register[roseClassName: "PcLogic", init: PcInit, evalSimple: PcEvalSimple];
END.