EU2UtilsImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Louis Monier June 3, 1986 2:54:39 pm PDT
Bertrand Serlet August 26, 1986 1:30:17 am PDT
Last Edited by: Louis Monier September 12, 1986 12:41:56 pm PDT
DIRECTORY BasicTime, CoreCreate, CoreOps, Dragon, DragOpsCross, EU2Utils, IO, Ports, TerminalIO;
EU2UtilsImpl: CEDAR PROGRAM
IMPORTS BasicTime, CoreCreate, CoreOps, IO, Ports, TerminalIO
EXPORTS EU2Utils =
BEGIN OPEN CoreCreate, EU2Utils;
times: LIST OF BasicTime.GMTNIL;
time: BasicTime.GMT;
PrintStart: PUBLIC PROC [name: ROPENIL] ~ {
time ← BasicTime.Now[]; -- Start the stop watch
times ← CONS[time, times];
TerminalIO.WriteRopes["Starting ", name];
TerminalIO.WriteLn[];
};
PrintStop: PUBLIC PROC [name: ROPENIL]~ {
min, sec: INT;
time ← times.first;
times ← times.rest;
sec ← BasicTime.Period[time, BasicTime.Now[]];
min ← sec/60; sec ← sec MOD 60;
TerminalIO.WriteF["finished % in %g min %g sec", IO.rope[name], IO.int[min], IO.int[sec]];
TerminalIO.WriteLn[];
};
TopOnlyBuses: PROC [reg: PipeRange] RETURNS [buses: Wire] ~ {
names: LIST OF WRNIL;
FOR l: Buses ← sources[reg].topOnlyBuses, l.rest WHILE l#NIL DO
names ← CONS[sources[l.first].name, names];
ENDLOOP;
buses ← IF names=NIL THEN NIL ELSE WireList[names];
};
BotOnlyBuses: PROC [reg: PipeRange] RETURNS [buses: Wire] ~ {
names: LIST OF WRNIL;
FOR l: Buses ← sources[reg].botOnlyBuses, l.rest WHILE l#NIL DO
names ← CONS[sources[l.first].name, names];
ENDLOOP;
buses ← IF names=NIL THEN NIL ELSE WireList[names];
};
ThroughBuses: PROC [reg: PipeRange] RETURNS [buses: Wire] ~ {
names: LIST OF WRNIL;
FOR l: Buses ← sources[reg].throughBuses, l.rest WHILE l#NIL DO
names ← CONS[sources[l.first].name, names];
ENDLOOP;
buses ← IF names=NIL THEN NIL ELSE WireList[names];
};
-- All the buses at the level of this source
AllBuses: PUBLIC PROC [reg: PipeRange] RETURNS [buses: Wire] ~ {
buses ← Union[TopOnlyBuses[reg], BotOnlyBuses[reg], ThroughBuses[reg]];
};
PortIndex: PUBLIC PROC [wire: Wire, name: ROPE] RETURNS [index: NAT] ~ {
index ← CoreOps.GetWireIndex[wire, name];
IF index=-1 THEN ERROR; -- not found
};
InitLeafPorts: PUBLIC PROC [public: Wire, initDrive: Ports.Drive] = {
InitAtomic: CoreOps.EachWireProc ~ {
IF wire.size=0 THEN [] ← Ports.InitPort[wire: wire, levelType: b, initDrive: initDrive];
};
[] ← CoreOps.VisitWire[public, InitAtomic];
};
Bus: PUBLIC PROC [name: ROPENIL] RETURNS [Wire] ~ {RETURN[Seq[name, wordSize]]};
Name: PUBLIC PROC [name: ROPE, wire: Wire] RETURNS [Wire] ~ {
RETURN [CoreOps.SetShortWireName[wire, name]];
};
NameList: PUBLIC PROC [name: ROPE, wrs: LIST OF WR] RETURNS [wire: Wire] ~ {
wire ← WireList[wrs];
RETURN [CoreOps.SetShortWireName[wire, name]];
};
-- External wires: the golden wires, bonded by Bonnie
GenWiresForBonnie: PUBLIC PROC RETURNS [Wire] ~ {
RETURN [WireList[LIST[
"Vdd", "Gnd", "PadVdd", "PadGnd", "PhA", "PhB", "VRef",
Bus["DPData"], "DPRejectB", Bus["KBus"],
"EURdFromPBus3AB", "EUWriteToPBus3AB",
Seq["EUAluOp2AB", sizeALUOps],
Seq["EUCondSel2AB", sizeCondSelects], "EUCondition2B",
"DShA", "DShB", "DShRd", "DShWt", "DShIn", "DShOut",
"DHold", Seq["DStAd", 4]
]]];
};
-- PGE and clock wires, inside the chip
GenPGnEWires: PUBLIC PROC RETURNS [Wire] = {
RETURN [Wires["Vdd", "Gnd"]]};
GenClockWires: PUBLIC PROC RETURNS [Wire] = {
RETURN [Wires["phA", "phB", "nPhA", "nPhB"]]};
-- Wires from and to pads: Onionized (Salut Bertrand!)
GenWiresCtrlToPads: PUBLIC PROC RETURNS [Wire] = {
RETURN [Wires["enWrtPBusPhA", "enWrtPBusPhB", "enWrtIFUPhA", "enWrtIFUPhB", "condition"]]; -- from control to pads
};
GenWiresPadsToCtrl: PUBLIC PROC RETURNS [Wire] = {
RETURN [Wires["writePBus", "res3BisP", "reject",
Seq["aluOp", sizeALUOps], Seq["condSel", sizeCondSelects]]];
};
GenWiresDBus: PUBLIC PROC RETURNS [Wire] = { -- hacked DBus
RETURN [Wires["hold", "shiftA", "shiftB", "read", "write", "shIn", "shOut", Seq["dStateAd", 4]]];
};
GenWiresDPToPads: PUBLIC PROC RETURNS [Wire] = {
RETURN [Wires[-- between datapath and pads
Bus["fromIFU"], Bus["toIFU"], Bus["toPBus"], Bus["fromPBus"] ]];
};
GenWiresForOnion: PUBLIC PROC RETURNS [Wire] = {
RETURN [CoreCreate.Union[-- between chip and pads
GenClockWires[],  -- all four clocks
GenWiresCtrlToPads[],  -- all four enWrite and condition
GenWiresPadsToCtrl[],  -- reject, aluOp, condSel, store and fetch
GenWiresDBus[],  -- hold, shiftA, shiftB, read, write, shIn, shOut and dStateAd
GenWiresDPToPads[] ]]; -- all four buses out of the data path
};
-- Wires between control and datapath: channel routed
GenWiresCtrlToRam: PUBLIC PROC RETURNS [Wire] ~ {
RETURN [Wires[-- from control to datapath
Seq["selA", nRows], -- output of the y-decoder
Seq["selB", nRows], -- output of the y-decoder
Seq["selC", nRows], -- output of the y-decoder
Seq["selALow", sizeSelLow], -- output of the x-decoder
Seq["selBLow", sizeSelLow], -- output of the x-decoder
Seq["selCLow", sizeSelLow], -- output of the x-decoder
"nPrech",
"dRamRead"  -- read the port A of the ram onto cBus for debugging (DBus)
]];
};
GenWiresRamToCtrl: PUBLIC PROC RETURNS [Wire] ~ {
RETURN [Wires[-- addresses to the ram decoder, from datapath to control
Seq["ramAdr", 3, Wires[Seq["Hi", sizeAdrH], Seq["Low", sizeAdrL]] ]]];
};
GenRegSelWire: PUBLIC PROC [reg: PipeRange] RETURNS [Wire] ~ {
RETURN [Seq[sources[reg].nameSel, sources[reg].sizeSel+2]]; -- sources+read+write
};
GenWiresCtrlToRegs: PUBLIC PROC RETURNS [Wire] ~ {
wires: LIST OF WRNIL;
FOR reg: PipeRange IN PipeRange DO IF reg#cBus THEN wires ← CONS[GenRegSelWire[reg], wires] ENDLOOP;
wires ← CONS[Seq["selcBusSrc", 3], wires];
-- control from Alps to multiplexers and debug ports of pipeline registers
RETURN [WireList[wires]];
};
GenWiresCtrlToALU: PUBLIC PROC RETURNS [Wire] = { -- control for ALU
RETURN [Wires["carryIn", Seq["op", 5]]] };
GenWiresCtrlToFU: PUBLIC PROC RETURNS [Wire] = { -- control to the field unit
RETURN [Wires["insert", Seq["mask", sizeK], Seq["shift", sizeK], Seq["sh", wordSize+1]]] };
GenWiresDPToCtrl: PUBLIC PROC RETURNS [Wire] = {
RETURN [Wires[Bus["kReg"] -- from datapath to control
-- multiplexed on KBus, latched inside the DP, inputs for the control
]];
};
GenWiresForRouter: PUBLIC PROC RETURNS [Wire] = {
RETURN [CoreCreate.Union[-- between control and datapath
GenWiresCtrlToRam[],  -- sel and dRamRead
GenWiresCtrlToRegs[],  -- selXXXSrc
GenWiresCtrlToALU[],  -- op and carryIn
GenWiresCtrlToFU[],  -- insert, mask, shift, and sh
GenWiresDPToCtrl[],  -- kReg
Wires["zero", "carryOut", Seq["res", 8], Seq["opL", 3], Seq["opR", 3]],
Wires["carryAB", "carryBA", "kernal", "lz", "il"]]];
};
aluOps: PUBLIC ARRAY Dragon.ALUOps OF ALUOpRec;
sources: PUBLIC ARRAY SourceRange OF Source;
-- Initialization starts here
PRtoByte: PROC[pr: DragOpsCross.ProcessorRegister] RETURNS [byte: NAT]={byte ← ORD[pr]};
Array: PROC [a, b, c, d, e: NAT ← 0] RETURNS [InputSels] ~ {RETURN[[a, b, c, d, e]]};
stackAdr: PUBLIC NAT ← PRtoByte[euStack];
junkAdr: PUBLIC NAT ← PRtoByte[euJunk];
fieldAdr: PUBLIC NAT ← PRtoByte[euField];
marAdr: PUBLIC NAT ← PRtoByte[euMAR];
constAdr: PUBLIC NAT ← PRtoByte[euConstant];
IFUAdr: PUBLIC NAT ← PRtoByte[euToKBus];
bogusAdr: PUBLIC NAT ← PRtoByte[euBogus];
KernalLimit: PUBLIC LONG CARDINAL ← DragOpsCross.KernalLimit;
dReadBus: PUBLIC ROPE ← "cBus";
nRows: PUBLIC NAT ← 40;
nbWords: PUBLIC NAT ← sizeSelLow*nRows;
-- Flags to provoke/read checkpoints.
useInnerCheckpoint: PUBLIC BOOLTRUE;
useControlCheckpoint: PUBLIC BOOLTRUE;
useRamControlCheckpoint: PUBLIC BOOLTRUE;
useDPControlCheckpoint: PUBLIC BOOLTRUE;
useDataPathCheckpoint: PUBLIC BOOLTRUE;
usekRegAndRightCheckpoint: PUBLIC BOOLTRUE;
useRamCheckpoint: PUBLIC BOOLTRUE;
useALUCheckpoint: PUBLIC BOOLTRUE;
aluOps[SAdd] ← [op: add,  cIn: prev,  cOut: zero];
aluOps[SSub]  ← [op: add,  cIn: nprev,  cOut: zero, invertB: TRUE];
aluOps[UAdd]  ← [op: add,  cIn: prev,  cOut: comp];
aluOps[USub]  ← [op: add,  cIn: nprev,  cOut: ncomp, invertB: TRUE];
aluOps[VAdd]  ← [op: add,  cIn: zero,  cOut: prev];
aluOps[VSub]  ← [op: add,  cIn: one,  cOut: prev, invertB: TRUE];
aluOps[LAdd]  ← [op: add,  cIn: zero,  cOut: zero];
aluOps[LSub]  ← [op: add,  cIn: one,  cOut: zero, invertB: TRUE];
aluOps[VAdd2]  ← aluOps[VAdd];
aluOps[BndChk]  ← [op: add,  cIn: one,  cOut: prev, invertB: TRUE];
aluOps[Or]   ← [op: or,  cIn: zero,  cOut: prev];
aluOps[And]  ← [op: and,  cIn: zero,  cOut: prev];
aluOps[Xor]  ← [op: xor,  cIn: zero,  cOut: prev];
aluOps[FOP]  ← aluOps[Or]; -- or anything else?
sources[ifuIn] ← [name: "ifuIn",
trackPosX: 5,
topOnlyBuses: NIL,
botOnlyBuses: LIST[ifuIn],
throughBuses: LIST[cBus]];
sources[ramA] ← [name: "ramA",
trackPosX: 1,
topOnlyBuses: NIL,
botOnlyBuses: LIST[ramA, ramB, cBus],
throughBuses: NIL];
sources[ramB] ← [name: "ramB",
trackPosX: 2,
topOnlyBuses: NIL,
botOnlyBuses: LIST[ramA, ramB, cBus],
throughBuses: NIL];
sources[kReg] ← [name: "kReg",
nameSel: "selKRegSrc", -- PhB
sizeSel: 1,
trackPosX: 3,
topOnlyBuses: NIL,
botOnlyBuses: LIST[kReg, ifuIn],
throughBuses: LIST[ramA, ramB, cBus],
inputs: Array[ifuIn]];
sources[right] ← [name: "right",
nameSel: "selRightSrc", -- PhA
sizeSel: 5,
trackPosX: 5,
topOnlyBuses: LIST[ifuIn],
botOnlyBuses: LIST[right, field, r2B],
throughBuses: LIST[ramA, ramB, cBus],
inputs: Array[ramB, r2B, cBus, ifuIn, field]];
sources[field] ← [name: "field",
nameSel: "selFieldSrc", -- PhA
sizeSel: 1,
trackPosX: 0,
topOnlyBuses: LIST[field],
botOnlyBuses: NIL,
throughBuses: LIST[ramA, ramB, r2B, cBus, right],
inputs: Array[cBus]];
sources[left] ← [name: "left",
nameSel: "selLeftSrc", -- PhA
sizeSel: 3,
trackPosX: 1,
topOnlyBuses: LIST[ramA],
botOnlyBuses: LIST[left],
throughBuses: LIST[ramB, r2B, cBus, right],
inputs: Array[ramA, r2B, cBus]];
sources[st2A] ← [name: "st2A",
nameSel: "selSt2ASrc", -- PhA
sizeSel: 3,
trackPosX: 2,
topOnlyBuses: LIST[ramB],
botOnlyBuses: LIST[st2A],
throughBuses: LIST[left, r2B, cBus, right],
inputs: Array[ramB, r2B, cBus]];
sources[aluOut] ← [name: "aluOut",
trackPosX: 5,
topOnlyBuses: LIST[right],
botOnlyBuses: LIST[aluOut],
throughBuses: LIST[left, st2A, r2B, cBus]];
sources[r2B] ← [name: "r2B",
nameSel: "selRes2BASrc", -- PhB
sizeSel: 3,
trackPosX: 3,
topOnlyBuses: LIST[aluOut],
botOnlyBuses: LIST[fuOut],
throughBuses: LIST[left, st2A, r2B, cBus],
inputs: Array[aluOut, fuOut, left]];
sources[fuOut] ← [name: "fuOut",
trackPosX: 5,
topOnlyBuses: LIST[left, fuOut],
botOnlyBuses: NIL,
throughBuses: LIST[st2A, r2B, cBus]];
sources[st2B] ← [name: "st2B",
nameSel: "selSt2BASrc", -- PhB
sizeSel: 1,
trackPosX: 5,
topOnlyBuses: LIST[st2A],
botOnlyBuses: LIST[st2B],
throughBuses: LIST[r2B, cBus],
inputs: Array[st2A]];
sources[st3A] ← [name: "st3A",
nameSel: "selSt3ABSrc", -- PhA
sizeSel: 2,
trackPosX: 5,
topOnlyBuses: LIST[st2B],
botOnlyBuses: LIST[st3A],
throughBuses: LIST[r2B, cBus],
inputs: Array[st2B, cBus]];
sources[pDriver] ← [name: "pDriver", -- special
trackPosX: 5,
topOnlyBuses: LIST[st3A],
botOnlyBuses: LIST[pDriver],
throughBuses: LIST[r2B, cBus],
inputs: Array[st3A, r2B]];
sources[r3A] ← [name: "r3A",
nameSel: "selRes3ABSrc", -- PhA
sizeSel: 1,
trackPosX: 3,
topOnlyBuses: LIST[r2B],
botOnlyBuses: LIST[r3A],
throughBuses: LIST[cBus, pDriver],
inputs: Array[r2B]];
sources[r3B] ← [name: "r3B",
nameSel: "selRes3BASrc", -- PhB
sizeSel: 1,
trackPosX: 3,
topOnlyBuses: LIST[r3A],
botOnlyBuses: LIST[r3B],
throughBuses: LIST[pDriver, cBus],
inputs: Array[r3A]];
sources[cBus] ← [name: "cBus",
nameSel: "selcBusSrc", -- PhA
tristate: TRUE,
sizeSel: 2,
trackPosX: 4,
topOnlyBuses: LIST[r3B],
botOnlyBuses: LIST[dataIn],
throughBuses: LIST[pDriver, cBus],
inputs: Array[r3B, dataIn]];
sources[dataIn] ← [name: "dataIn",
nameSel: "selDataInSrc", -- PhB
sizeSel: 1,
trackPosX: 2,
topOnlyBuses: LIST[dataIn],
botOnlyBuses: LIST[pIn],
throughBuses: LIST[pDriver, cBus],
inputs: Array[pIn]];
sources[pIn] ← [name: "pIn",
trackPosX: 3,
topOnlyBuses: LIST[pIn],
botOnlyBuses: NIL,
throughBuses: LIST[cBus]];
END.