IFUSrcInstrDecode:
CEDAR
PROGRAM
IMPORTS CoreFrame, CoreGlue, CoreName, IFUCoreCtl, IFUCoreDrive, IO, PLAOps, REFBit, Rope, WatchStats
EXPORTS IFUSrc =
BEGIN
ROPE: TYPE = Core.ROPE;
root: ROPE = "InstrDecode";
plaRoot: ROPE = Rope.Cat["IFUPLA", root];
PlaDscs: TYPE = ARRAY [0..nofPlas) OF REF PLAD;
nofPlas: INT = IFUPLAInstrDecode.InstrDecodeOutCount; -- 1;
PLAD: TYPE = IFUCoreCtl.PLADescriptionRec;
ExceptionalOutSignals: ARRAY [0..nofPlas) OF ROPE;
PhB: ROPE ← CoreName.RopeNm["PhB"];
IDPlaFireV: ROPE ← CoreName.RopeNm["IDPlaFireV"];
IDPlaNotPhA: ROPE ← CoreName.RopeNm["IDPlaNotPhA"];
InstrDecode:
PUBLIC
PROC [sIn:
ROPE, altOut:
ROPE ←
NIL]
RETURNS [cellType: Core.CellType, sOut: ROPE] = {
cachedName: ROPE ← CoreName.RopeNm[plaRoot.Cat["Main"]];
IF (cellType ← CoreFrame.ReadFrameCache[cachedName])=NIL THEN {
{
maxOuts: INT ← 0;
ins: REF ← REFBit.NEWFromName[plaRoot.Cat[".", root.Cat["In"] ] ];
plaDscs: PlaDscs;
drivesOut: Core.CellType ←
CoreFrame.NewFrameCell[name: root.Cat["OutDr"], rec: [first: bottom], size: nofPlas];
drivesIn: Core.CellType;
FOR index:
INT
IN [0..nofPlas)
DO
plaName: ROPE ← IO.PutFR["%g%g", IO.rope[plaRoot], IO.int[index] ];
plaDscs[index] ←
NEW[
PLAD ← [
name: plaName,
plaType: precharged,
includeIns: FALSE,
plaPhs: [AB, A, ABB, B, BA],
capSides: none,
fire: PhB,
fireV: IDPlaFireV,
nPreChg: IDPlaNotPhA ] ];
plaDscs[index].ttt ← PLAOps.ReadPLAFile[plaName.Cat[".ttt"], log];
maxOuts ← MAX[maxOuts, REFBit.Desc[plaDscs[index].ttt.out].bitForm.size];
ENDLOOP;
sOut ← sIn;
FOR index:
INT
IN [0..nofPlas)
DO
plaDscs[index].nofOrCols ← maxOuts;
IFUCoreCtl.MakePLA1[plaDscs[index]];
IFUCoreDrive.AdjustDriveOutPh[plaDscs[index].outDrs, ExceptionalOutSignals[index]];
sOut ← IFUCoreDrive.ConnectDrives[plaDscs[index].outDrs, sOut];
CoreFrame.FCT[drivesOut].seq[index] ← IFUCoreCtl.CellProc[outSec, plaDscs[index]];
ENDLOOP;
[plaDscs[0].inDrs, sOut] ← IFUCoreDrive.CapDrives[plaDscs[0].inDrs, sOut, altOut];
IFUCoreDrive.AdjustDriveInPhRef[A, plaDscs[0].inDrs, ExceptionalInSignals];
drivesIn ← IFUCoreDrive.DrivesToFrame[root.Cat["InDr"], plaDscs[0].inDrs];
FOR index:
INT
IN [0..nofPlas)
DO
IF WatchStats.GetWatchStats[].vmFree < 10000 THEN SIGNAL IFUSrc.Rollback[NIL];
IF WatchStats.GetWatchStats[].vmFree < 10000 THEN ERROR;
plaDscs[index].inDrs ← plaDscs[0].inDrs; -- share input name changes
IFUCoreCtl.MakePLA2[plaDscs[index]] ENDLOOP;
CheckConsistancyOfInstrDecodePLAs[plaDscs];
cellType ← CoreFrame.NewFrameCells[name: cachedName, rec: [first: top], cells:
LIST[
CoreFrame.NewFrameCells[name: root.Cat["InSBDr"], rec: [first: left], cells:
LIST[
CoreGlue.CellProc[name: root.Cat["InSB"], b: conn, r: conn],
drivesIn ]],
drivesOut ]];
[ ] ← CoreName.CellNm[cellType, cachedName];
IFUCoreDrive.SetDShiftIO[cellType, sIn, sOut];
CoreFrame.WriteFrameCache[cellType]};
};
[sIn, sOut] ← IFUCoreDrive.GetDShiftIO[cellType];
cellType ← CoreFrame.NewFrameCells[name: root, rec: [first: left], cells:
LIST[
CoreGlue.CellProc[l: ext, r: conn],
cellType ]]};
CheckConsistancyOfInstrDecodePLAs:
PROC[plaDscs: PlaDscs] = {
DeCONS:
PROC[rope: ROPE, list:
LIST
OF ROPE]
RETURNS[LIST OF ROPE] = {
IF Rope.Equal[rope, list.first] THEN RETURN[list.rest];
FOR temp:
LIST
OF ROPE ← list, temp.rest
WHILE temp.rest#
NIL
DO
IF NOT Rope.Equal[rope, temp.rest.first] THEN LOOP;
temp.rest ← temp.rest.rest;
EXIT
REPEAT
FINISHED => log.PutF
["\n ERROR: %g not driven by any of the Instruction Decode PLA's", IO.rope[rope]]
ENDLOOP;
RETURN[list]};
format: REFBit.Format;
outlist: LIST OF ROPE;
FOR index:
INT
IN [0..nofPlas)
DO
format ← REFBit.Desc[plaDscs[index].ttt.out].bitForm;
FOR bit:
INT
IN [0..format.size)
DO
IF format[bit].name # NIL THEN outlist ← CONS[format[bit].name, outlist];
IF format[bit].nameInv # NIL THEN outlist ← CONS[format[bit].nameInv, outlist];
ENDLOOP;
ENDLOOP;
format ← REFBit.Desc[plaRoot.Cat[".", root, "Out"]].bitForm;
FOR bit:
INT
IN [0..format.size)
DO
IF format[bit].name #
NIL
THEN outlist ←
DeCONS[CoreName.BitRopeToSigRope[format[bit].name], outlist];
IF format[bit].nameInv #
NIL
THEN outlist ←
DeCONS[CoreName.BitRopeToSigRope[format[bit].nameInv], outlist];
ENDLOOP;
IF outlist#NIL THEN Signal[]}; -- main pla did not define these outputs
log: IO.STREAM ← CoreFrame.GetLog[];
ExceptionalInSignals:
ROPE ← "
UserMode0AB ← FlagAB.6 ";
ExceptionalOutSignals[6] ← "
PcBusSrcOffSetPCBA NotPcBusSrcOffSetPCBA
PcBusSrcPipe3BA NotPcBusSrcPipe3BA
PcBusSrcStackBA NotPcBusSrcStackBA
PcBusSrcXopGenBA NotPcBusSrcXopGenBA
PcBusSrcTrapGenBA NotPcBusSrcTrapGenBA
PcBusSrcAlpBetGamDelBA NotPcBusSrcAlpBetGamDelBA
PcBusSrcXBA NotPcBusSrcXBA
PcBusSrcPcBA NotPcBusSrcPcBA
X2ALitSourceNone0BA NotX2ALitSourceNone0BA ";
ExceptionalOutSignals[5] ← NIL;
ExceptionalOutSignals[4] ← NIL;
ExceptionalOutSignals[3] ← "
NotCRegOffBA.0
NotPushScBA "; -- CRegOffBA.0 and PushScBA not used
ExceptionalOutSignals[2] ← NIL;
ExceptionalOutSignals[1] ← NIL;
ExceptionalOutSignals[0] ← "
AluOpIsOp47BA NotAluOpIsOp47BA
CondSelIsOp57BA NotCondSelIsOp57BA
X1ASrcStackLAc NotX1ASrcStackLAc
X1ASrcStackPAc NotX1ASrcStackPAc
X1ASrcSLimitAc NotX1ASrcSLimitAc
X1ADstSLimitAc
X1ADstStackBA NotX1ADstStackBA ";
END.