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; ArbDBusName: ROPE = Rosemary.Register[roseClassName: "ArbDBusCode", init: ArbDBusInit, evalSimple: ArbDBusSimple]; ArbDBusInterface: Wire = WireList[LIST[ Seq["DBus", 7], Seq["SlotNo", 4], Seq["BdVersion", 2], Seq["DHybridSel", 5], "DBdSel", Seq["DPriority", maxDevices, Seq[size: 9]], Seq["ArbNo", 3], "Freeze", "Rst", "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: NAT _ LAST[NAT], lastCk, lastDCk : BOOL _ TRUE, m, s: MSRec, -- sync with Ck dm, ds: ArbDMSRec -- asynch state ]; 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 BOOL _ ALL[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. vArbDBusImpl.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 Arbiter DBus Interface DBus Interface to Arbiter Misc .. master (loads during clock low) / slave (transfers out when clock goes high) State kept in master/slave form to avoid feedback races.. ΚΦ˜šœ™Jšœ<™