mesa
Copyright c 1986 by Xerox Corporation. All rights reserved.
Curry, September 17, 1986 10:10:17 pm PDT
DIRECTORY Basics, Core, CoreFrame, CoreName, CoreXform, IFUSrc, IFUCoreData, IO, Rope;
IFUSrcControlPipe: CEDAR PROGRAM
IMPORTS CoreFrame, CoreName, IFUCoreData, IO, Rope
EXPORTS IFUSrc =
BEGIN
Assumption: Except for CondEffect, all abort values are Zero.
ROPE:  TYPE = Core.ROPE;
Ph:  TYPE = CoreName.Ph;
xform:  CoreXform.Xform ← IFUCoreData.Interleaved48;
XBus: ROPE = CoreName.RopeNm["XBus."];
GND:  ROPE = CoreName.RopeNm["GND"];
tKey:  ROPE ← CoreName.RopeNm["t"];
rKey:  ROPE ← CoreName.RopeNm["r"];
lKey:  ROPE ← CoreName.RopeNm["l"];
definitions: ARRAY [0..32) OF ROPE = [ 
"l: EStkOverflow1BA l: EStkOverflow2BA  ",
"l: InstFault0BA   l: InstFault2BA  ",
"r: KIsRtOp0BA   l: KIsRtOp1BA   ", -- to interlock
"r: FCtlIsRtOp0BA  l: FCtlIsRtOp1BA  ", -- to interlock
"r: Push0BA    t: Push1AB l: Push2AB l: Push3AB ",
"r: Pop0BA    t: Pop1AB  t: Pop2AB l: Pop3AB ",
"r: NotX2ALitSourceNone0BA r: X2ASrcLit1BA ",
NIL,
"r: KPadsIn0BA   r: KPadsIn3BA   ",
"r: InstStarting0BA  l: InstStarting2BA  ",
"l: EUSt3AIsCBus1BA t: EUSt3AIsCBus2BA ",
"t: DPCmnd0BA.7  r: EUWriteToPBus3AB ",
"t: EUAluOp0BA.0  r: EUAluOp2AB.0 ",
"t: EUAluOp0BA.1  r: EUAluOp2AB.1 ",
"t: EUAluOp0BA.2  r: EUAluOp2AB.2 ",
"t: EUAluOp0BA.3  r: EUAluOp2AB.3 ",
Non-zero alternate input IFUPLAMainControl.CondEffect[bubble]=3
"r: CondEffect0BA.0 l: CondEffect1BA.0 l: CondEffect2BA.0
2Ax: VDD 2Bx: VDD 3Ax: VDD ",
"r: CondEffect0BA.1 l: CondEffect1BA.1 l: CondEffect2BA.1
2Ax: VDD 2Bx: VDD 3Ax: VDD ",
"r: CIsField0BA  l: CIsField2AB  l: CIsField3AB   ",
"r: DPCmndIsRd0BA l: DPCmndIsRd2BA r: EURdFromPBus3AB ",
"t: EUCondSel0BA.0 r: EUCondSel2AB.0 l: EUCondSel3AB.0 3Ax: EUCondSel2BA.0",
"t: EUCondSel0BA.1 r: EUCondSel2AB.1 l: EUCondSel3AB.1 3Ax: EUCondSel2BA.1",
"t: EUCondSel0BA.2 r: EUCondSel2AB.2 l: EUCondSel3AB.2 3Ax: EUCondSel2BA.2",
"t: EUCondSel0BA.3 r: EUCondSel2AB.3 l: EUCondSel3AB.3 3Ax: EUCondSel2BA.3",
"t: DPCmnd0BA.0  r: DPCmnd2BA.0 ",
"t: DPCmnd0BA.1  r: DPCmnd2BA.1 ",
"t: DPCmnd0BA.2  r: DPCmnd2BA.2 ",
"t: DPCmnd0BA.3  r: DPCmnd2BA.3 ",
"t: DPCmnd0BA.4  r: DPCmnd2BA.4 ",
"t: DPCmnd0BA.5  r: DPCmnd2BA.5 ",
"t: DPCmnd0BA.6  r: DPCmnd2BA.6 ",
"t: DPCmnd0BA.7  r: DPCmnd2BA.7 " ];
See also IFUSrcABForm.forthByteBA
forthByteBA:  ROPE = "(
EUSt3AIsCBus2BA
EUAluLeftSrc1BA.0  EUAluLeftSrc1BA.1
EUAluRightSrc1BA.0 EUAluRightSrc1BA.1 EUAluRightSrc1BA.2
EUStore2ASrc1BA.0  EUStore2ASrc1BA.1 )";
other0BLeftSignals:  LIST OF REF = LIST[
-- EUSt3AIsCBus2BA --
"EUAluLeftSrc1BA.0", "EUAluLeftSrc1BA.1",
"EUAluRightSrc1BA.0", "EUAluRightSrc1BA.1", "EUAluRightSrc1BA.2",
"EUStore2ASrc1BA.0", "EUStore2ASrc1BA.1" ];
other0BRightSignals: LIST OF REF = LIST[
"PushPendingAB", "PopPendingAB",
"AluOpBA.0",  "AluOpBA.1",  "AluOpBA.2",  "AluOpBA.3",  -- PreAluOp
"CondSelBA.0", "CondSelBA.1", "CondSelBA.2", "CondSelBA.3", -- PreCondSel
"DPCmndBA.0", "DPCmndBA.1", "DPCmndBA.2", "DPCmndBA.3", -- PreDPCmnd
"DPCmndBA.4", "DPCmndBA.5", "DPCmndBA.6", "DPCmndBA.7" ]; -- PreDPCmnd
keySigs: REF KeySigs ← MakeKeySigs[];
KeySigs: TYPE = ARRAY [0..32) OF LIST OF KeySig;
KeySig: TYPE = RECORD[key: ROPE, sig: CoreName.SigRec];
CP0BLeft:  LIST OF REF ← BuildInList[cy: 0, ph: BA, side: left];
CP0BRight:  LIST OF REF ← BuildInList[cy: 0, ph: BA, side: right];
CP1BLeft:  LIST OF REF ← BuildInList[cy: 1, ph: BA, side: left];
CP1BRight:  LIST OF REF ← BuildInList[cy: 1, ph: BA, side: right];
CPOutLeft:  LIST OF REF ← BuildOutSide[side: left];
CPOutRight: LIST OF REF ← BuildOutSide[side: right];
CPPre1BAWd: LIST OF REF ← BuildWd[cy: 1, ph: BA, withoutFirst:TRUE, withoutLast:TRUE];
CP2AxWdNul: LIST OF REF ← BuildAltWd[key: "2Ax"];
CP2BxWdNul: LIST OF REF ← BuildAltWd[key: "2Bx"];
CP3AxWdNul: LIST OF REF ← BuildAltWd[key: "3Ax"];
orIn0: ROPE = "
( NIL NIL NIL NIL Push2AB  Push12AB  Pop1AB Pop12AB )";
orIn1: ROPE = "
( NIL NIL NIL NIL Push1AB  Push3AB   Pop2AB Pop3AB )";
orOut: ROPE = "
( NIL NIL NIL NIL Push12AB PushPendingAB Pop12AB PopPendingAB )";
op47: ROPE = "
(NIL NIL NIL NIL OpBA.4   OpBA.5   OpBA.6   OpBA.7 )";
op57: ROPE = "
(NIL NIL NIL NILGND    OpBA.5   OpBA.6   OpBA.7 )";
preAluOp0BA: LIST OF ROPELIST[
"NIL","NIL","NIL","NIL",
"AluOpBA.0","AluOpBA.1","AluOpBA.2","AluOpBA.3"];
euAluOp0B:  LIST OF ROPELIST[
"NIL","NIL","NIL","NIL",
"EUAluOp0B.0","EUAluOp0B.1","EUAluOp0B.2","EUAluOp0B.3"];
euAluOp0BA:  LIST OF ROPELIST[
"NIL","NIL","NIL","NIL",
"EUAluOp0BA.0","EUAluOp0BA.1","EUAluOp0BA.2","EUAluOp0BA.3"];
preCondSel0BA: LIST OF ROPELIST[
"NIL","NIL","NIL","NIL",
"CondSelBA.0","CondSelBA.1","CondSelBA.2","CondSelBA.3"];
euCondSel0B: LIST OF ROPELIST[
"NIL","NIL","NIL","NIL",
"EUCondSel0B.0","EUCondSel0B.1","EUCondSel0B.2","EUCondSel0B.3"];
euCondSel0BA: LIST OF ROPELIST[
"NIL","NIL","NIL","NIL",
"EUCondSel0BA.0","EUCondSel0BA.1","EUCondSel0BA.2","EUCondSel0BA.3"];
predpCmnd0BA: LIST OF ROPELIST[
"DPCmndBA.0","DPCmndBA.1","DPCmndBA.2","DPCmndBA.3",
"DPCmndBA.4","DPCmndBA.5","DPCmndBA.6","DPCmndBA.7"];
dpCmnd0B: LIST OF ROPELIST[
"DPCmnd0B.0","DPCmnd0B.1","DPCmnd0B.2","DPCmnd0B.3",
"DPCmnd0B.4","DPCmnd0B.5","DPCmnd0B.6","DPCmnd0B.7"];
dpCmnd0BA: LIST OF ROPELIST[
"DPCmnd0BA.0","DPCmnd0BA.1","DPCmnd0BA.2","DPCmnd0BA.3",
"DPCmnd0BA.4","DPCmnd0BA.5","DPCmnd0BA.6","DPCmnd0BA.7"];
Sequencial in interleaved spec
dDataIn: ROPE = " (
( DData.01 DData.05 DData.11 DData.15 DData.21 DData.25 DData.31 DData.35 )
( DData.02 DData.06 DData.12 DData.16 DData.22 DData.26 DData.32 DData.36 )
( DData.03 DData.07 DData.13 DData.17 DData.23 DData.27 DData.33 DData.37 )
( DData.04 DData.10 DData.14 DData.20 DData.24 DData.30 DData.34 DShRightOut ) )";
dDataOut: ROPE = " (
(DShOut DData.04 DData.10 DData.14 DData.20 DData.24 DData.30 DData.34 )
(DData.01 DData.05 DData.11 DData.15 DData.21 DData.25 DData.31 DData.35 )
(DData.02 DData.06 DData.12 DData.16 DData.22 DData.26 DData.32 DData.36 )
(DData.03 DData.07 DData.13 DData.17 DData.23 DData.27 DData.33 DData.37 ) )";
XBusxx: ROPE = " (
( XBus.00 XBus.04 XBus.10 XBus.14 XBus.20 XBus.24 XBus.30 XBus.34 )
( XBus.01 XBus.05 XBus.11 XBus.15 XBus.21 XBus.25 XBus.31 XBus.35 )
( XBus.02 XBus.06 XBus.12 XBus.16 XBus.22 XBus.26 XBus.32 XBus.36 )
( XBus.03 XBus.07 XBus.13 XBus.17 XBus.23 XBus.27 XBus.33 XBus.37 ) )";
CPShiftOp47Top: LIST OF REF = LIST [
XBus,
LIST[ op47, forthByteBA, NIL, "BetaBA." ] ];
CPShiftOp47: PROC RETURNS[cellType: Core.CellType] = {
cellType ← IFUCoreData.CellProc[
subClass: "SwitchBox",
name:  "CPShiftOp47",
top:  CPShiftOp47Top,
left:  "( DShOut )",
right:  "( DShRightOut )",
bot:  CPShiftOp47Bot,
xform:  IFUCoreData.Interleaved48 ]};
CPShiftOp47Bot: LIST OF REF = LIST [
XBus,
LIST[ NIL, forthByteBA, NIL, "BetaBA." ],
LIST[ NIL, op47,    op57, NIL],
NIL,
dDataOut,
dDataIn ];
DebugShiftRegister: PROC RETURNS[cellType: Core.CellType] = {
cellType ← IFUCoreData.CellProc[
subClass: "GPRow",
name:  "DataPathDebug",
type:   "DpDebugRec",
top:  CPShiftOp47Bot,
left:  "( DShA DShRd DShB DShWt )",
right:  "( DShA DShRd DShB DShWt )",
in:   LIST[ dDataIn, "XBus." ],
out:  LIST[ dDataOut ],
bot:  CPMux0BTop,
xform:  IFUCoreData.Interleaved48 ]};
CPMux0BTop: LIST OF REF = LIST [
XBus,
LIST[ NIL, forthByteBA, NIL, "BetaBA." ],
LIST[ NIL, op47,    op57, NIL] ];
CPMux0B: PROC RETURNS[cellType: Core.CellType] = {
cellType ← IFUCoreData.CellProc[
subClass: "Mux",
name:  "CPMux0B",
top:  CPMux0BTop,
right:  "(
AluOpIsOp47BA   NotAluOpIsOp47BA
CondSelIsOp57BA  NotCondSelIsOp57BA
DPCmndSelBetaBA  DPCmndSelNormalBA )",
in:   LIST[
LIST[ NIL, op47, NIL, NIL ],  LIST[ NIL, preAluOp0BA, NIL, NIL ],
LIST[ NIL, NIL, op57, NIL ],  LIST[ NIL, NIL, preCondSel0BA, NIL ],
LIST[ NIL, NIL, NIL, "BetaBA." ], LIST[ NIL, NIL, NIL, predpCmnd0BA ] ],
out:  LIST[ LIST[ NIL, euAluOp0B, euCondSel0B, dpCmnd0B ] ],
bot:  CPLatch0BTop,
xform:  IFUCoreData.Interleaved48 ]};
CPLatch0BTop: LIST OF REF = LIST [
XBus,
LIST[ NIL, forthByteBA, NIL,     NIL ],
NIL,
LIST[ NIL, euAluOp0B,  euCondSel0B,  dpCmnd0B ],
LIST[ NIL, preAluOp0BA, preCondSel0BA,  predpCmnd0BA ] ];
CPLatch0B: PROC RETURNS[cellType: Core.CellType] = {
cellType ← IFUCoreData.CellProc[
subClass: "GPRow",
name:  "CPLatch0B",
type:   "( DpLatchOr DpLatch DpLatch DpLatch )",
left:  LIST["PhB", "VBB"],
top:  CPLatch0BTop,
in:   LIST[
LIST[ orIn0, euAluOp0B, euCondSel0B, dpCmnd0B ],
LIST[ orIn1, NIL,   NIL,    NIL ]],
out:  LIST[LIST[ orOut, euAluOp0BA, euCondSel0BA, dpCmnd0BA ]],
bot:  CPMergeInTop,
xform:  IFUCoreData.Interleaved48 ]};
CPMergeInTop: LIST OF REF = LIST [
XBus,
LIST[ NIL, forthByteBA, NIL,     NIL ],
LIST[ orOut, euAluOp0BA, euCondSel0BA, dpCmnd0BA ],
LIST[ orIn1, NIL, NIL, NIL ],
LIST[ orIn0, preAluOp0BA, preCondSel0BA, predpCmnd0BA ] ];
CPMergeIn: PROC RETURNS[cellType: Core.CellType] = {
cellType ← IFUCoreData.CellProc[
subClass: "SwitchBox",
name:  "CPMergeIn",
top:  CPMergeInTop,
left:  CCat[ LIST[CP0BLeft, CPOutLeft]],
right:  CCat[ LIST[CP0BRight, CPOutRight ] ],
bot:  LIST[XBus, Conn[0,0,BA], NIL, Conn[1,0,BA], Conn[2,0,BA], Conn[3,0,BA]],
xform:  IFUCoreData.Interleaved48 ]};
CPLatch1A: PROC RETURNS[cellType: Core.CellType] = {
cellType ← IFUCoreData.CellProc[
subClass: "GPRow",
name:  "CPLatch1A",
type:   "DpLatch",
left:  LIST["LoadStage1Ac", "VBB"],
top:  LIST[XBus, Conn[0,0,BA], NIL, Conn[1,0,BA], Conn[2,0,BA], Conn[3,0,BA]],
in:   LIST[BuildWd[0, BA]],
out:  LIST[BuildWd[1, AB]],
bot:  LIST[XBus, Conn[0,1,AB], NIL, Conn[1,1,AB], Conn[2,1,AB], Conn[3,1,AB]],
xform:  IFUCoreData.Interleaved48 ]};
CPLatch1B: PROC RETURNS[cellType: Core.CellType] = {
cellType ← IFUCoreData.CellProc[
subClass: "GPRow",
name:  "CPLatch1B",
type:   "DpLatch",
left:  LIST["LoadStage1Bc", "VBB"],
top:  LIST[XBus, Conn[0,1,AB], NIL, Conn[1,1,AB], Conn[2,1,AB], Conn[3,1,AB]],
in:   LIST[BuildWd[1, AB]],
out:  LIST[BuildWd[cy: 1, ph: BA, withoutFirst:TRUE, withoutLast:FALSE]],
bot:  LIST[XBus, CPPre1BAWd, NIL, Conn[1,1,BA], Conn[2,1,BA], Conn[3,1,BA]],
xform:  IFUCoreData.Interleaved48 ]};
CPMergeIn1B: PROC RETURNS[cellType: Core.CellType] = {
cellType ← IFUCoreData.CellProc[
subClass: "SwitchBox",
name:  "CPMergeIn1B",
top:  LIST[XBus, CPPre1BAWd, NIL, Conn[1,1,BA], Conn[2,1,BA], Conn[3,1,BA]],
left:  CP1BLeft,
right:  CP1BRight,
bot:  LIST[XBus, Conn[0,1,BA], NIL, Conn[1,1,BA], Conn[2,1,BA], Conn[3,1,BA]],
xform:  IFUCoreData.Interleaved48 ]};
CPMux2A: PROC RETURNS[cellType: Core.CellType] = {
cellType ← IFUCoreData.CellProc[
subClass: "Mux",
name:  "CPMux2A",
top:  LIST[XBus, Conn[0,1,BA], NIL, Conn[1,1,BA], Conn[2,1,BA], Conn[3,1,BA]],
left:  LIST["Stage2ABubbleBA", "Stage2ANormalBA"],
in:   LIST[CP2AxWdNul, BuildWd[1, BA]],
out:  LIST[BuildWd[2, A]],
bot:  LIST[XBus, NIL, Conn[0,2,A], Conn[1,2,A], Conn[2,2,A], Conn[3,2,A]],
xform:  IFUCoreData.Interleaved48 ]};
CPLatch2A: PROC RETURNS[cellType: Core.CellType] = {
cellType ← IFUCoreData.CellProc[
subClass: "GPRow",
name:  "CPLatch2A",
type:   "DpLatch",
left:  LIST["LoadStage2Ac", "VBB"],
top:  LIST[XBus, NIL, Conn[0,2,A], Conn[1,2,A], Conn[2,2,A], Conn[3,2,A]],
in:   LIST[BuildWd[2, A]],
out:  LIST[BuildWd[2, AB]],
bot:  LIST[XBus, Conn[0,2,AB], NIL, Conn[1,2,AB], Conn[2,2,AB], Conn[3,2,AB]],
xform:  IFUCoreData.Interleaved48 ]};
CPMux2B: PROC RETURNS[cellType: Core.CellType] = {
cellType ← IFUCoreData.CellProc[
subClass: "Mux",
name:  "CPMux2B",
top:  LIST[XBus, Conn[0,2,AB], NIL, Conn[1,2,AB], Conn[2,2,AB], Conn[3,2,AB]],
left:  LIST["Stage2BAbortAB", "Stage2BNormalAB"],
in:   LIST[CP2BxWdNul, BuildWd[2, AB]],
out:  LIST[BuildWd[2, B]],
bot:  LIST[XBus, NIL, Conn[0,2,B], Conn[1,2,B], Conn[2,2,B], Conn[3,2,B]],
xform:  IFUCoreData.Interleaved48 ]};
CPLatch2B: PROC RETURNS[cellType: Core.CellType] = {
cellType ← IFUCoreData.CellProc[
subClass: "GPRow",
name:  "CPLatch2B",
type:   "DpLatch",
left:  LIST["PhB", "VBB"],
top:  LIST[XBus, NIL, Conn[0,2,B], Conn[1,2,B], Conn[2,2,B], Conn[3,2,B]],
in:   LIST[BuildWd[2, B]],
out:  LIST[BuildWd[2, BA]],
bot:  LIST[XBus, Conn[0,2,BA], NIL, Conn[1,2,BA], Conn[2,2,BA], Conn[3,2,BA]],
xform:  IFUCoreData.Interleaved48 ]};
CPMux3A: PROC RETURNS[cellType: Core.CellType] = {
cellType ← IFUCoreData.CellProc[
subClass: "Mux",
name:  "CPMux3A",
top:  LIST[XBus, Conn[0,2,BA], NIL, Conn[1,2,BA], Conn[2,2,BA], Conn[3,2,BA]],
left:  LIST["Stage3AAbortBA", "Stage3ANormalBA"],
in:   LIST[CP3AxWdNul, BuildWd[2, BA]],
out:  LIST[BuildWd[3, A]],
bot:  LIST[XBus, NIL, Conn[0,3,A], Conn[1,3,A], Conn[2,3,A], Conn[3,3,A]],
xform:  IFUCoreData.Interleaved48 ]};
CPLatch3A: PROC RETURNS[cellType: Core.CellType] = {
cellType ← IFUCoreData.CellProc[
subClass: "GPRow",
name:  "CPLatch3A",
type:   "DpLatch",
left:  LIST["LoadStage3Ac", "VBB"],
top:  LIST[XBus, NIL, Conn[0,3,A], Conn[1,3,A], Conn[2,3,A], Conn[3,3,A]],
in:   LIST[BuildWd[3, A]],
out:  LIST[BuildWd[3, AB]],
bot:  LIST[XBus, Conn[0,3,AB], NIL, Conn[1,3,AB], Conn[2,3,AB], Conn[3,3,AB]],
xform:  IFUCoreData.Interleaved48 ]};
CPLatch3B: PROC RETURNS[cellType: Core.CellType] = {
cellType ← IFUCoreData.CellProc[
subClass: "GPRow",
name:  "CPLatch3B",
type:   "DpLatch",
top:  LIST[XBus, Conn[0,3,AB], NIL, Conn[1,3,AB], Conn[2,3,AB], Conn[3,3,AB]],
left:  LIST["PhB", "VBB"],
in:   LIST[BuildWd[3, AB]],
out:  LIST[BuildWd[3, BA]],
bot:  LIST[XBus],
xform:  IFUCoreData.Interleaved48 ]};
ShuffleXBus: PROC RETURNS[cellType: Core.CellType] = {
cellType ← IFUCoreData.CellProc[
subClass: "SwitchBox",
name:  "ShuffleXBus",
top:  LIST[XBus],
bot:  LIST[NIL, NIL, NIL, NIL, XBusxx], -- keep one away from GND and VDD
xform:  IFUCoreData.Interleaved48 ]};
MakeKeySigs: PROC RETURNS[keySigs: REF KeySigs] = {
keySigs ← NEW[KeySigs ← ALL[NIL]];
FOR physical: INT IN [0..32) DO
logical: INT ← CoreXform.XformIndex[IFUCoreData.Interleaved48, rl, physical].i;
logical: INT ← physical; -- need to match location of Op and beta for muxing
in:   IO.STREAM;
temp:  LIST OF KeySig;
IF definitions[physical] = NIL THEN LOOP;
in ← IO.RIS[definitions[physical]];
WHILE NOT in.EndOf[] DO
item: ROPE;
keySig: KeySig;
keySig.key ← CoreName.RopeNm[IO.GetTokenRope[in! IO.EndOfStream => EXIT].token];
item   ← CoreName.RopeNm[IO.GetTokenRope[in].token];
keySig.sig ← CoreName.NameSig[item];
keySigs[logical] ← CONS[keySig, keySigs[logical]]; ENDLOOP;
temp ← keySigs[logical]; keySigs[logical] ← NIL;
FOR temp ← temp, temp.rest WHILE temp#NIL
DO keySigs[logical] ← CONS[temp.first, keySigs[logical]] ENDLOOP;
ENDLOOP};
CompareSigToCyPh: PROC[sig: CoreName.SigRec, cy: INT, ph: Ph]
RETURNS[Basics.Comparison] = {
RETURN[ SELECT sig.cy FROM
> cy => greater,
< cy => less,
ENDCASE => SELECT sig.ph FROM
> ph => greater,
< ph => less,
ENDCASE => equal]};
BuildInList: PROC[cy: INT, ph: Ph, side: {left, right}] RETURNS[result: LIST OF REF] = {
IF cy=0 AND side=left THEN result ← other0BLeftSignals;
IF cy=0 AND side=right THEN result ← other0BRightSignals;
FOR bit: INT DECREASING IN [0..32) DO
IF keySigs[bit]=NIL THEN LOOP;
IF cy#keySigs[bit].first.sig.cy OR
ph#keySigs[bit].first.sig.ph THEN LOOP;
SELECT keySigs[bit].first.key FROM
tKey  => LOOP;
lKey  => IF side#left THEN LOOP;
rKey   => IF side#right THEN LOOP;
ENDCASE => LOOP;
result ← CONS[ CoreName.SigName[ keySigs[bit].first.sig ], result] ENDLOOP};
Signal: SIGNAL = CODE;
BuildWd: PROC[cy: INT, ph: Ph, withoutFirst, withoutLast: BOOLFALSE]
RETURNS[result: LIST OF REF] = {
FOR bit: INT IN [0..32) DO
last: KeySig;
IF keySigs[bit]=NIL THEN {result ← CONS[NIL, result]; LOOP};
FOR list: LIST OF KeySig ← keySigs[bit], list.rest WHILE list#NIL DO
SELECT list.first.key FROM tKey, lKey, rKey => last ← list.first; ENDCASE => EXIT;
ENDLOOP;
IF
CompareSigToCyPh[keySigs[bit].first.sig, cy, ph]=greater OR
CompareSigToCyPh[keySigs[bit].first.sig, cy, ph]=equal AND withoutFirst OR
CompareSigToCyPh[last.sig,    cy, ph]=less OR
CompareSigToCyPh[last.sig,    cy, ph]=equal AND withoutLast
THEN {result ← CONS[NIL, result]; LOOP};
last ← keySigs[bit].first;
FOR list: LIST OF KeySig ← keySigs[bit].rest, list.rest DO
IF list=NIL THEN GOTO finished;
SELECT list.first.key FROM tKey, lKey, rKey => { }; ENDCASE => GOTO finished;
SELECT CompareSigToCyPh[list.first.sig, cy, ph] FROM
greater => {last.sig.cy ← cy; last.sig.ph ← ph; EXIT}; -- preserve last name
less  => {last ← list.first; LOOP};      -- update last
ENDCASE => {last ← list.first; EXIT};       -- use last
REPEAT finished => {result ← CONS[NIL, result]; LOOP} ENDLOOP;
result ← CONS[CoreName.SigName[last.sig], result];
ENDLOOP;
RETURN[ReversePartition[result]]};
BuildAltWd: PROC[key: ROPE] RETURNS[result: LIST OF REF] = {
key ← CoreName.RopeNm[key];
FOR bit: INT IN [0..32) DO
found: BOOLFALSE;
FOR list: LIST OF KeySig ← keySigs[bit], list.rest WHILE list#NIL DO
SELECT list.first.key FROM tKey, lKey, rKey => LOOP; ENDCASE;
IF list.first.key=key THEN
{found←TRUE; result ← CONS[CoreName.SigName[list.first.sig], result]; EXIT};
ENDLOOP;
IF NOT found THEN result ← CONS[GND, result];
ENDLOOP;
RETURN[ReversePartition[result]]};
Conn: PROC[index, cy: INT, ph: Ph] RETURNS[result: LIST OF REF] = {
IF index=0 THEN RETURN[BuildWd[cy, ph, FALSE, TRUE]];
FOR bit: INT IN [0..32) DO
left: INT ← index;
found: BOOLFALSE;
FOR list: LIST OF KeySig ← keySigs[bit], list.rest WHILE list#NIL DO
SELECT list.first.key FROM
tKey, lKey, rKey => {
IF left=0 THEN {
found←TRUE;
IF CompareSigToCyPh[list.first.sig, cy, ph] # greater
THEN result ← CONS[NIL, result]
ELSE result ← CONS[CoreName.SigName[list.first.sig], result];
EXIT};
left ← left-1};
ENDCASE => EXIT;
ENDLOOP;
IF NOT found THEN result ← CONS[NIL, result];
ENDLOOP;
RETURN[ReversePartition[result]]};
BuildOutSide: PROC[side: {left, right}] RETURNS[result: LIST OF REF] = {
FOR bit: INT IN [0..32) DO
IF keySigs[bit]=NIL THEN LOOP;
FOR list: LIST OF KeySig ← keySigs[bit].rest, list.rest WHILE list#NIL DO
SELECT list.first.key FROM
tKey => LOOP;
lKey => IF side=left THEN result ← CONS[CoreName.SigName[list.first.sig], result];
rKey  => IF side=right THEN result ← CONS[CoreName.SigName[list.first.sig], result];
ENDCASE => EXIT;
ENDLOOP;
ENDLOOP};
CCat: PROC[list: LIST OF REF] RETURNS[result: LIST OF REFNIL] = {
CCatRope: PROC[lst: LIST OF ROPE] =
{IF lst=NIL THEN RETURN; CCatRope[lst.rest]; result ← CONS[lst.first, result]};
CCatMain: PROC[lst: LIST OF REF] = {
IF lst=NIL THEN RETURN;
CCatMain[lst.rest];
IF lst.first#NIL THEN WITH lst.first SELECT FROM
l:  LIST OF ROPE => CCatRope[l];
l:  LIST OF REF  => CCatMain[l];
rope: ROPE  => result ← CONS[rope, result];
text: REF TEXT  => result ← CONS[Rope.FromRefText[text], result];
ENDCASE     => ERROR};
CCatMain[list]};
ReversePartition: PROC[list: LIST OF REF] RETURNS[result: LIST OF REFNIL] = {
FOR byte: INT DECREASING IN [0..4) DO
bList: LIST OF REFNIL;
FOR bit: INT DECREASING IN [0..8) DO
bList ← CONS[list.first, bList];
list ← list.rest ENDLOOP;
result ← CONS[bList, result] ENDLOOP };
ControlPipe: PUBLIC PROC RETURNS[cellType: Core.CellType] = {
name: ROPE ← CoreName.RopeNm["IFUControlPipe"];
IF (cellType ← CoreFrame.ReadFrameCache[name])=NIL THEN {
cellType ← CoreFrame.NewFrameCells[
name:  name,
rec:  [first: top],
cells: LIST[
CPShiftOp47[],
DebugShiftRegister[],
CPMux0B[],
CPLatch0B[],
CPMergeIn[],
CPLatch1A[],
CPLatch1B[],
CPMergeIn1B[],
CPMux2A[],
CPLatch2A[],
CPMux2B[],
CPLatch2B[],
CPMux3A[],
CPLatch3A[],
CPLatch3B[]
ShuffleXBus[]
] ];
CoreFrame.WriteFrameCache[cellType]}};
END.