TamUCodeCells.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Krivacic September 17, 1987 12:01:54 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, TamarinUCodeImpl, TerminalIO, IO, Tam, List;
TamUCodeCells: CEDAR PROGRAM
IMPORTS Ports, Rosemary, TamPorts, BitOps, TamarinUtilImpl, TerminalIO, IO, Tam, Rope
= BEGIN OPEN TamDefs, TamPorts;
-------------------- UCode Rom ---------------------
UCodeState: TYPE = REF UCodeStateRec;
UCodeStateRec: TYPE = RECORD [
mi, mil, nUCodeMuxSel, uCodeSel, aAddr, bAddr, precondAddr, newOpcode, nStall, nClock, vdd, gnd: NATLAST[NAT],
lastClock: BOOL];
lastMi, lastMil, nextMil: Rope.ROPE;
debug: BOOLFALSE;
UCodeInit: Rosemary.InitProc = {
--PROC [cellType: Core.CellType, p: Ports.Port] RETURNS [stateAny: REF ANY ← NIL]--
state: UCodeState ← NEW[UCodeStateRec];
lastMi ← Tam.uCodeRomA[0];
lastMil ← Tam.uCodeRomA[0];
nextMil ← lastMi;
state.lastClock ← FALSE;
[state.vdd, state.gnd, state.nClock] ← Ports.PortIndexes[cellType.public, "Vdd", "Gnd", "nClock"];
[state.nUCodeMuxSel, state.aAddr, state.bAddr, state.nStall, state.uCodeSel, state.precondAddr, state.newOpcode] ← Ports.PortIndexes[cellType.public, "nUCodeMuxSel", "aAddr", "bAddr", "nStall", "UCodeSel", "Precond", "newOpcode"];
[state.mi] ← Ports.PortIndexes[cellType.public, "MI"];
[] ← Rosemary.SetFixedWire[cellType.public[state.vdd], H];
[] ← Rosemary.SetFixedWire[cellType.public[state.gnd], L];
stateAny ← state;
};
UCodeEvalSimple: Rosemary.EvalProc = {
PROC [p: Ports.Port, stateAny: REF ANY]--
XSet: PROC [p: Ports.Port, index: NAT, val: CARD, name: ATOMNIL] =
{
IF HasXs[p, index] THEN {
SetPVal[p, index, val];
p[index].d ← none;
IF debug OR clockset THEN TerminalIO.PutF["X Input in UCode: %g index: %g \n", IO.atom[name], IO.int[index]];
};
};
clockset: BOOLTRUE;
aAddr: NAT ← 0;
state: UCodeState   ← NARROW[stateAny];
-- Clear any inputs with X's, setup to go to Reset
XSet[p, state.nClock, 0, $nClock];
clockset ← PortToBool[p, state.nClock];
IF debug THEN TerminalIO.PutF["nClock: %g \n", IO.int[PortToNat[p, state.nClock]]];
XSet[p, state.aAddr, 8, $aAddr];
XSet[p, state.bAddr, 9, $bAddr];
XSet[p, state.nUCodeMuxSel, 11, $nUCodeMuxSel];
XSet[p, state.uCodeSel, 1, $uCodeSel];
XSet[p, state.nStall, 1, $nStall];
XSet[p, state.precondAddr, 0, $precondAddr];
XSet[p, state.newOpcode, 128, $newOpcode];
IF PortToBool[p, state.nStall] THEN
IF PortToBool[p, state.uCodeSel] THEN {  -- Use A side of Rom
           -- Select the source for the A side Address
aAddr ← SELECT PortToNat[p, state.nUCodeMuxSel] FROM
7 => PortToNat[p, state.aAddr],
11 => PortToNat[p, state.precondAddr],
13 => BitOps.WordAND[PortToNat[p, state.newOpcode], 0F8H],
14 => PortToNat[p, state.newOpcode],
ENDCASE =>
0;
SELECT PortToNat[p, state.nUCodeMuxSel] FROM
7, 11, 13, 14 => {};
ENDCASE =>
TerminalIO.PutF["BAD nUCodeMuxSel Mil: %g \n", IO.int[PortToNat[p, state.nUCodeMuxSel]]];
lastMi ← Tam.uCodeRomA[aAddr];
}
ELSE           -- Use B side of Rom
lastMi ← Tam.uCodeRomB[PortToNat[p, state.bAddr]]
ELSE lastMi ← lastMil;
IF clockset THEN {
nextMil ← lastMi;
IF debug THEN {
TerminalIO.PutF["New Mi: %g \n", IO.rope[lastMi]];
TerminalIO.PutF[" from: %g, Select: %g, addr: %g, baddr: %g, \n", IO.int[PortToNat[p, state.uCodeSel]], IO.int[PortToNat[p, state.nUCodeMuxSel]], IO.int[aAddr], IO.int[PortToNat[p, state.bAddr]]];
};
}
ELSE {
lastMil ← nextMil;
IF debug THEN TerminalIO.PutF["New Mil: %g \n", IO.rope[lastMil]];
};
FOR i: List.LORA ← Tam.uCodeOrder, i.rest WHILE i # NIL DO
bitRec: Tam.BitPos ← NARROW[i.first];
bit: NAT ← bitRec.bitPos;
SELECT bitRec.bitType FROM
latch => p[state.mi].ls[bit] ← TamPorts.CharToLevel[Rope.Fetch[lastMil, bit]];
unlatched => p[state.mi].ls[bit] ← TamPorts.CharToLevel[Rope.Fetch[lastMi, bit]];
both => p[state.mi].ls[bit] ← TamPorts.CharToLevel[Rope.Fetch[lastMi, bit]];
ENDCASE;
ENDLOOP;
p[state.mi].d ← drive;
state.lastClock ← clockset;
stateAny ← state;
};
uCodeName: Rope.ROPE = Rosemary.Register[roseClassName: "UCodeRom", init: UCodeInit, evalSimple: UCodeEvalSimple];
END.