ArbDBusImpl.mesa
Copyright c 1986 by Xerox Corporation. All rights reserved.
McCreight May 15, 1987 5:26:12 pm PDT
Last Edited by: McCreight August 21, 1987 11:44:25 am PDT
DIRECTORY Arbiter, BitOps, CoreClasses, CoreCreate, CoreFlat, CoreOps, Ports, Rope, Rosemary;
ArbDBusImpl: CEDAR PROGRAM
IMPORTS BitOps, CoreCreate, CoreClasses, CoreFlat, Ports, Rosemary
EXPORTS Arbiter
= BEGIN OPEN Arbiter, CoreCreate;
logicCutSet: Rope.ROPE = "Logic"; -- should be Logic.logicCutSet, actually
ArbPropsLen: NAT = 4;
Arbiter DBus Interface
ArbDBusName: ROPE = Rosemary.Register[roseClassName: "ArbDBusCode", init: ArbDBusInit, evalSimple: ArbDBusSimple];
ArbDBusInterface: Wire = WireList[LIST[
DBus
Seq["DBus", 7],
Seq["SlotNo", 4],
Seq["BdVersion", 2],
Seq["DHybridSel", 5],
"DBdSel",
Interface to Arbiter
Seq["DPriority", maxDevices, Seq[size: 9]],
Seq["ArbNo", 3],
"Freeze",
"Rst",
Misc
"Ck", "Vdd", "Gnd"
]];
ArbDBusCodeCT: PUBLIC PROC RETURNS [ ct: CoreCreate.CellType ] = {
dBus, dPriority: NAT;
ct ← CoreClasses.CreateUnspecified[name: ArbDBusName, public: ArbDBusInterface];
[] ← Rosemary.BindCellType[cellType: ct, roseClassName: ArbDBusName];
[] ← CoreFlat.CellTypeCutLabels[ct, logicCutSet];
dBus ← Ports.PortIndex[ct.public, "DBus"];
FOR j: NAT IN [DShiftCK..DSerialOut] DO
[] ← Ports.InitPort[ct.public[dBus][j], b, aggregate, none];
ENDLOOP;
Ports.InitPorts[ct, c, none, "SlotNo", "BdVersion"];
Ports.InitPorts[ct, b, drive, "DBdSel"];
Ports.InitPorts[ct, c, drive, "DHybridSel"];
dPriority ← Ports.PortIndex[ct.public, "DPriority"];
FOR d: NAT IN Devices DO
[] ← Ports.InitPort[ct.public[dPriority][d], c, aggregate, drive];
ENDLOOP;
Ports.InitPorts[ct, c, drive, "ArbNo"];
Ports.InitPorts[ct, b, drive, "Rst"];
Ports.InitPorts[ct, b, drive, "Freeze"];
Ports.InitPorts[ct, b, none, "Ck", "Vdd", "Gnd"];
};
ArbiterState: TYPE = REF ArbiterStateRec;
ArbiterStateRec: TYPE = RECORD [
DBus, SlotNo, BdVersion, DHybridSel, DBdSel,
DPriority, ArbNo, Rst, Freeze,
Ck: NATLAST[NAT],
lastCk, lastDCk : BOOLTRUE,
m, s: MSRec, -- sync with Ck
dm, ds: ArbDMSRec -- asynch state
.. master (loads during clock low) / slave (transfers out when clock goes high)
State kept in master/slave form to avoid feedback races..
];
ArbDBusInit: Rosemary.InitProc = {
st: ArbiterState = (IF oldStateAny # NIL THEN NARROW[oldStateAny] ELSE NEW[ArbiterStateRec]);
{OPEN st;
[DBus] ← Ports.PortIndexes[cellType.public, "DBus"];
[SlotNo, BdVersion, DHybridSel, DBdSel] ← Ports.PortIndexes[cellType.public, "SlotNo", "BdVersion", "DHybridSel", "DBdSel"];
[DPriority, ArbNo, Rst, Freeze] ← Ports.PortIndexes[cellType.public, "DPriority", "ArbNo", "Rst", "Freeze"];
[Ck] ← Ports.PortIndexes[cellType.public, "Ck"];
};
stateAny ← st;
};
DBusAddr: TYPE = MACHINE DEPENDENT RECORD [
board (0: 0..3): [0..16),
hybrid (0: 4..7): [0..16),
interface (0: 8..10): [0..8),
chip (0: 11..12): [0..4),
path (0: 13..15): [0..8)
];
ArbProps: TYPE = MACHINE DEPENDENT RECORD [
unused (0: 0..11): [0..4096),
arbNo (0: 12..14): [0..8),
hySelDec(0: 15..15): BOOL
];
MSRec: TYPE = RECORD [
Reset, Freeze: ARRAY [0..2) OF BOOLALL[FALSE]
];
ArbDMSRec: TYPE = RECORD [
DBAddr: BitOps.BitWord ← 0, -- has structure DBusAddr
SignatureShadow: BitOps.BitWord ← 0,
DevPriority: ARRAY Devices OF BitOps.BitWord ← ALL[0],
ArbProps: BitOps.BitWord ← 0, -- has structure ArbProps
BoardVersionShadow: BitOps.BitWord ← 0
];
ArbDBusSimple: PROC [p: Ports.Port, stateAny: REF ANY] -- Rosemary.EvalProc -- = {
st: ArbiterState ← NARROW[stateAny];
dba: DBusAddr;
thisBd: BOOL;
IF p[st.DBus][DShiftCK].b AND NOT st.lastDCk THEN st.ds ← st.dm;
TRUSTED {dba ← LOOPHOLE[st.ds.DBAddr]};
thisBd ← NOT p[st.DBus][DAddress].b AND (dba.board = p[st.SlotNo].c);
IF NOT p[st.DBus][DShiftCK].b THEN { -- DShiftCK low, compute DBus master stages
dsi: BOOL = p[st.DBus][DSerialIn].b;
st.dm ← st.ds;
SELECT TRUE FROM
p[st.DBus][DAddress].b => {
st.dm.DBAddr ← BitOps.IBIW[
source: dsi,
container: BitOps.WShift[st.ds.DBAddr, 1, 16],
bitPosition: 15];
st.dm.SignatureShadow ← 5041H; -- type 1, revision 1
};
thisBd AND (dba.hybrid = 0) -- the arbiter itself -- => {
st.dm.BoardVersionShadow ← BitOps.WShift[st.ds.BoardVersionShadow, 1, 2];
SELECT dba.path FROM
0 => st.dm.SignatureShadow ← BitOps.IBIW[
source: dsi,
container: BitOps.WShift[st.ds.SignatureShadow, 1, 16],
bitPosition: 15,
containerWidth: 16];
1 =>
FOR d: Devices IN Devices DO
st.dm.DevPriority[d] ← BitOps.IBIW[
source: (IF d=LAST[Devices] THEN dsi ELSE
BitOps.EBFW[st.ds.DevPriority[d+1], 0, PriorityRecLen]),
container: BitOps.WShift[st.ds.DevPriority[d], 1, PriorityRecLen],
bitPosition: PriorityRecLen-1,
containerWidth: PriorityRecLen];
ENDLOOP;
2 => st.dm.ArbProps ← BitOps.IBIW[
source: dsi,
container: BitOps.WShift[st.ds.ArbProps, 1, ArbPropsLen],
bitPosition: ArbPropsLen-1,
containerWidth: ArbPropsLen];
ENDCASE => NULL;
};
thisBd -- other hybrid on this board -- =>
st.dm.BoardVersionShadow ← p[st.BdVersion].c;
ENDCASE => NULL;
};
p[st.DBus][DSerialOut].d ← (IF (thisBd AND (dba.hybrid = 0)) THEN drive ELSE driveWeak);
TRUSTED { p[st.DBus][DSerialOut].b ← (IF (thisBd AND (dba.hybrid = 0)) THEN
(SELECT dba.path FROM
0 => BitOps.EBFW[st.ds.SignatureShadow, 0, 16],
1 => BitOps.EBFW[st.ds.DevPriority[maxDevices-1], 0, PriorityRecLen],
2 => BitOps.EBFW[st.ds.ArbProps, 0, ArbPropsLen],
3 => BitOps.EBFW[st.ds.BoardVersionShadow, 0, 2],
ENDCASE => FALSE)
ELSE TRUE)
};
p[st.DHybridSel].c ←
(SELECT BitOps.EBFW[st.ds.ArbProps, ArbPropsLen-1, ArbPropsLen] FROM
TRUE -- decoded hybrid select -- =>
(IF thisBd AND dba.hybrid IN [1..5] THEN
BitOps.IBIW[source: TRUE, container: 0,
bitPosition: dba.hybrid-1, containerWidth: 5]
ELSE 0),
FALSE -- encoded -- =>
BitOps.ECFW[container: st.ds.DBAddr, fieldPosition: 4, fieldWidth: 5],
ENDCASE => ERROR);
p[st.DBdSel].b ← thisBd;
p[st.ArbNo].c ← BitOps.ECFW[st.ds.ArbProps, 0, 3, ArbPropsLen];
FOR d: Devices IN Devices DO
p[st.DPriority][d].c ← BitOps.ECFW[
container: st.ds.DevPriority[d],
fieldPosition: 0,
fieldWidth: PriorityRecLen,
containerWidth: PriorityRecLen];
ENDLOOP;
st.lastDCk ← p[st.DBus][DShiftCK].b;
IF p[st.Ck].b AND NOT st.lastCk THEN st.s ← st.m;
IF NOT p[st.Ck].b THEN {
st.m.Freeze[0] ← p[st.DBus][DShiftCK].b;
st.m.Reset[0] ← p[st.DBus][DShiftCK].b;
st.m.Freeze[1] ← st.s.Freeze[0];
st.m.Reset[1] ← st.s.Reset[0];
};
st.lastCk ← p[st.Ck].b;
p[st.Rst].b ← st.s.Reset[1];
p[st.Freeze].b ← st.s.Freeze[1];
};
END.