DIRECTORY Arbiter, BitOps, CoreClasses, CoreCreate, CoreFlat, CoreOps, CoreProperties, Logic, Ports, Rope, Rosemary; ArbiterImpl: CEDAR PROGRAM IMPORTS BitOps, CoreCreate, CoreClasses, CoreFlat, CoreOps, CoreProperties, Logic, Ports, Rosemary EXPORTS Arbiter = BEGIN OPEN Arbiter, CoreCreate; ArbNov87A: PUBLIC BOOL _ FALSE; -- 19 Jan 88 ArbInFrameInterface: Wire = WireList[LIST[ "nBusyIn", -- down the left side "nBusyOut", "nStopAct", "nBSStopOut", "nBSharedOut", "nBOwnerOut", "nStartGrant", Seq["OtherArbIn", maxArbiters-1, Seq[size: 3]], Seq["ArbReqOut", 3], Seq["nGrant", maxDevices], -- left to right across top Seq["nRequestOut", maxDevices, Seq[size: 2]], "nSStopIn", "nOwnerIn", "nSharedIn", "nLongGrant", "nHiPGrant", "nOwnerOut", -- down the right side Seq["nSharedOut", maxDevices], Seq["nSStopOut", maxDevices], Seq["DBus", 7], Seq["TInv", 2], Seq["TRec2v", 3], Seq["TIOBus", 6], "nBOwnerIn", -- left to right across bottom Seq["nBSharedIn", maxArbiters], Seq["nBSStopIn", maxArbiters], Seq["BdVersion", 2], Seq["SlotNo", 4], "DBdSel", Seq["nDHybridSel", 5], "Clock", "CKOut", "Vdd", "Gnd" --, "Gnd2V"-- ]]; ArbInFrameCT: PUBLIC PROC [arbNo: INT _ 0, pra: PRA _ ALL[DefaultPriority]] RETURNS [ ct: CoreCreate.CellType ] = { inst: CoreCreate.CellInstance; instances: CellInstances _ LIST[]; publics: Wire = ArbInFrameInterface; internals: Wire = WireList[LIST[ "Rst", Seq["DPriority", maxDevices, Seq[size: 9]], Seq["ArbNo", 3], Seq["ArbRovers6", 8, Seq[size: 3]], ]]; arbCT: CellType _ ArbExceptDBusCodeCT[]; arbDBusCT: CellType _ ArbDBusCodeCT[arbNo, pra]; ossIn: Wire _ CoreOps.FindWire[arbCT.public, "OSSIn"]; ossOut: Wire _ CoreOps.FindWire[arbCT.public, "OSSOut"]; pas: LIST OF PA _ LIST[ [public: "Ck", actual: "CKOut"], [public: ossIn[nOwnerOut], actual: "nOwnerOut"], [public: ossOut[nBOwnerOut], actual: "nBOwnerOut"], [public: ossIn[nBOwnerIn], actual: "nBOwnerIn"], [public: ossOut[nOwnerIn], actual: "nOwnerIn"], [public: ossIn[nSharedOut], actual: "nSharedOut"], [public: ossOut[nBSharedOut], actual: "nBSharedOut"], [public: ossIn[nBSharedIn], actual: "nBSharedIn"], [public: ossOut[nSharedIn], actual: "nSharedIn"], [public: ossIn[nSStopOut], actual: "nSStopOut"], [public: ossOut[nBSStopOut], actual: "nBSStopOut"], [public: ossIn[nBSStopIn], actual: "nBSStopIn"], [public: ossOut[nSStopIn], actual: "nSStopIn"]]; inst _ InstanceList[ type: arbCT, pas: pas, name: "ArbExcDBus" ]; instances _ CONS[inst, instances]; inst _ InstanceList[ type: arbDBusCT, pas: LIST[ [public: "Ck", actual: "Clock"], [public: "CkOut", actual: "CKOut"]], name: "ArbDBus" ]; instances _ CONS[inst, instances]; inst _ InstanceList[ type: Logic.Inv[], pas: LIST [ [public: "I", actual: CoreOps.FindWire[publics, "TInv"][0]], [public: "X", actual: CoreOps.FindWire[publics, "TInv"][1]] ], name: "TestInverter"]; instances _ CONS[inst, instances]; inst _ InstanceList[ type: Logic.Rec2V[], pas: LIST [ [public: "I", actual: CoreOps.FindWire[publics, "TRec2v"][0]], [public: "Vth", actual: CoreOps.FindWire[publics, "TRec2v"][1]], [public: "X", actual: CoreOps.FindWire[publics, "TRec2v"][2]] ], name: "TestRec2v"]; instances _ CONS[inst, instances]; ct _ CoreCreate.Cell[public: publics, onlyInternal: internals, instances: instances, name: "ArbInFrame"]; }; ArbExceptDBusName: ROPE = Rosemary.Register[roseClassName: "ArbExceptDBus", init: ArbExceptDBusInit, evalSimple: ArbExceptDBusSimple, scheduleIfClockEval: TRUE]; ArbExceptDBusInterface: Wire = WireList[LIST[ Seq["nRequestOut", maxDevices, Seq[size: 2]], -- request ports, radial Seq["nGrant", maxDevices], -- grant ports, radial "nHiPGrant", -- status, bussed "nLongGrant", Seq["ArbReqOut", 3], -- this arbiter's request to others Seq["OtherArbIn", maxArbiters-1, Seq[size: 3]], -- requests from other arbiters "nBusyOut", "nBusyIn", "nStartGrant", -- for logic analyzer trigger "nStopAct", -- DynaBus Stop Seq["ArbRovers6", 8, Seq[size: 3]], -- not wired out to real pins WireList[LIST["nOwnerOut", "nBOwnerIn", Seq["nSharedOut", 8], Seq["nBSharedIn", 8], Seq["nSStopOut", 8], Seq["nBSStopIn", 8]], "OSSIn"], WireList[LIST["nBOwnerOut", "nOwnerIn", "nBSharedOut", "nSharedIn", "nBSStopOut","nSStopIn"], "OSSOut"], Seq["DPriority", maxDevices, Seq[size: 9]], Seq["ArbNo", 3], "Rst", "Ck", "Vdd", "Gnd" ]]; ArbExceptDBusCodeCT: PUBLIC PROC RETURNS [ ct: CoreCreate.CellType ] = { dreq, dgrant, arbReqOut, otherArbIn, dPriority, ossIn, ossOut, arbRovers6: NAT; ct _ CoreClasses.CreateUnspecified[name: ArbExceptDBusName, public: ArbExceptDBusInterface]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: ArbExceptDBusName]; [] _ CoreFlat.CellTypeCutLabels[ct, Logic.logicCutSet]; dreq _ Ports.PortIndex[ct.public, "nRequestOut"]; dgrant _ Ports.PortIndex[ct.public, "nGrant"]; FOR d: Devices IN Devices DO [] _ Ports.InitPort[ct.public[dreq][d], c, aggregate, driveWeak]; [] _ Ports.InitPort[ct.public[dgrant][d], b, aggregate, driveWeak]; ENDLOOP; Ports.InitPorts[ct, b, drive, "nHiPGrant", "nLongGrant"]; arbReqOut _ Ports.PortIndex[ct.public, "ArbReqOut"]; FOR j: NAT IN [0..3) DO [] _ Ports.InitPort[ct.public[arbReqOut][j], b, aggregate, driveWeak]; ENDLOOP; otherArbIn _ Ports.PortIndex[ct.public, "OtherArbIn"]; FOR j: Arbiters IN [0..maxArbiters-1) DO [] _ Ports.InitPort[ct.public[otherArbIn][j], c, aggregate, driveWeak]; ENDLOOP; Ports.InitPorts[ct, b, driveWeak, "nBusyOut", "nStartGrant", "nBusyIn", "nStopAct"]; ossIn _ Ports.PortIndex[ct.public, "OSSIn"]; ossOut _ Ports.PortIndex[ct.public, "OSSOut"]; FOR d: Devices IN Devices DO [] _ Ports.InitPort[ct.public[ossIn][nSharedOut][d], b, aggregate, driveWeak]; [] _ Ports.InitPort[ct.public[ossIn][nSStopOut][d], b, aggregate, driveWeak]; ENDLOOP; FOR a: Arbiters IN Arbiters DO [] _ Ports.InitPort[ct.public[ossIn][nBSharedIn][a], b, aggregate, driveWeak]; [] _ Ports.InitPort[ct.public[ossIn][nBSStopIn][a], b, aggregate, driveWeak]; ENDLOOP; [] _ Ports.InitPort[ct.public[ossIn][nOwnerOut], b, aggregate, driveWeak]; [] _ Ports.InitPort[ct.public[ossIn][nBOwnerIn], b, aggregate, driveWeak]; [] _ Ports.InitPort[ct.public[ossOut][nBOwnerOut], b, aggregate, drive]; [] _ Ports.InitPort[ct.public[ossOut][nOwnerIn], b, aggregate, drive]; [] _ Ports.InitPort[ct.public[ossOut][nBSharedOut], b, aggregate, drive]; [] _ Ports.InitPort[ct.public[ossOut][nSharedIn], b, aggregate, drive]; [] _ Ports.InitPort[ct.public[ossOut][nBSStopOut], b, aggregate, drive]; [] _ Ports.InitPort[ct.public[ossOut][nSStopIn], b, aggregate, drive]; arbRovers6 _ Ports.PortIndex[ct.public, "ArbRovers6"]; FOR pr: Priority IN Priority DO [] _ Ports.InitPort[ct.public[arbRovers6][pr], c, aggregate, drive]; ENDLOOP; dPriority _ Ports.PortIndex[ct.public, "DPriority"]; FOR d: Devices IN Devices DO [] _ Ports.InitPort[ct.public[dPriority][d], c, aggregate, none]; ENDLOOP; Ports.InitPorts[ct, c, none, "ArbNo"]; Ports.InitPorts[ct, b, none, "Rst"]; Ports.InitPorts[ct, b, none, "Ck", "Vdd", "Gnd"]; }; ArbExceptDBusState: TYPE = REF ArbExceptDBusStateRec; ArbExceptDBusStateRec: TYPE = RECORD [ nRequestOut, nGrant, nHiPGrant, nLongGrant, ArbReqOut, OtherArbIn, nBusyOut, nBusyIn, nStartGrant, nStopAct, ArbRovers6, OSSIn, OSSOut, DPriority, ArbNo, Rst, Ck: NAT _ LAST[NAT], lastCk, lastDCk: BOOL _ TRUE, sm, ss: ArbSharedMSRec, m, s: ArbCoreMSRec ]; ArbExceptDBusInit: Rosemary.InitProc = { st: ArbExceptDBusState = (IF oldStateAny # NIL THEN NARROW[oldStateAny] ELSE NEW[ArbExceptDBusStateRec]); {OPEN st; [nRequestOut, nGrant, nHiPGrant, nLongGrant, ArbReqOut, OtherArbIn] _ Ports.PortIndexes[cellType.public, "nRequestOut", "nGrant", "nHiPGrant", "nLongGrant", "ArbReqOut", "OtherArbIn"]; [nBusyOut, nBusyIn, nStartGrant, nStopAct] _ Ports.PortIndexes[cellType.public, "nBusyOut", "nBusyIn", "nStartGrant", "nStopAct"]; [ArbRovers6] _ Ports.PortIndexes[cellType.public, "ArbRovers6"]; [OSSIn, OSSOut] _ Ports.PortIndexes[cellType.public, "OSSIn", "OSSOut"]; [DPriority, ArbNo, Rst, Ck] _ Ports.PortIndexes[cellType.public, "DPriority", "ArbNo", "Rst", "Ck"]; }; stateAny _ st; }; ArbExceptDBusSimple: PROC [p: Ports.Port, stateAny: REF ANY, clockEval: BOOL] RETURNS [ stateValue: Ports.LevelSequence _ NIL ]-- Rosemary.EvalProc -- = { st: ArbExceptDBusState _ NARROW[stateAny]; ArbShared[p, st, clockEval]; ArbCore[p, st, clockEval]; IF ~clockEval THEN st.lastCk _ p[st.Ck].b; }; DynaBusDrive: PROC [ p: Ports.Port, value: BOOL ] = { p.b _ NOT value; p.d _ IF value THEN drive ELSE driveWeak; }; ArbSharedMSRec: TYPE = RECORD [ OwnerOut: BOOL _ FALSE, BOwnerOut: BOOL _ FALSE, BOwnerIn: BOOL _ FALSE, OwnerIn: BOOL _ FALSE, SharedOut: ARRAY Devices OF BOOL _ ALL[FALSE], BSharedOut: BOOL _ FALSE, BSharedIn: ARRAY Arbiters OF BOOL _ ALL[FALSE], SharedIn: BOOL _ FALSE, SStopOut: ARRAY Devices OF BOOL _ ALL[FALSE], BSStopOut: BOOL _ FALSE, BSStopIn: ARRAY Arbiters OF BOOL _ ALL[FALSE], SStopIn: BOOL _ FALSE ]; ArbShared: PROC [p: Ports.Port, stateAny: REF ANY, clockEval: BOOL] -- Rosemary.EvalProc -- = { st: ArbExceptDBusState _ NARROW[stateAny]; SELECT TRUE FROM clockEval => NULL; p[st.Ck].b AND NOT st.lastCk => st.ss _ st.sm; NOT p[st.Ck].b => { st.sm.OwnerOut _ NOT p[st.OSSIn][nOwnerOut].b; st.sm.BOwnerOut _ st.ss.OwnerOut; st.sm.BOwnerIn _ NOT p[st.OSSIn][nBOwnerIn].b; st.sm.OwnerIn _ st.ss.BOwnerIn; st.sm.BSharedOut _ FALSE; st.sm.BSStopOut _ FALSE; FOR d: Devices IN Devices DO st.sm.SharedOut[d] _ NOT p[st.OSSIn][nSharedOut][d].b; st.sm.BSharedOut _ st.sm.BSharedOut OR st.ss.SharedOut[d]; st.sm.SStopOut[d] _ NOT p[st.OSSIn][nSStopOut][d].b; st.sm.BSStopOut _ st.sm.BSStopOut OR st.ss.SStopOut[d]; ENDLOOP; st.sm.SharedIn _ FALSE; st.sm.SStopIn _ FALSE; FOR a: Arbiters IN Arbiters DO st.sm.BSharedIn[a] _ NOT p[st.OSSIn][nBSharedIn][a].b; st.sm.SharedIn _ st.sm.SharedIn OR st.ss.BSharedIn[a]; st.sm.BSStopIn[a] _ NOT p[st.OSSIn][nBSStopIn][a].b; st.sm.SStopIn _ st.sm.SStopIn OR st.ss.BSStopIn[a]; ENDLOOP; }; ENDCASE => NULL; DynaBusDrive[p[st.OSSOut][nBOwnerOut], st.ss.BOwnerOut]; DynaBusDrive[p[st.OSSOut][nOwnerIn], st.ss.OwnerIn]; DynaBusDrive[p[st.OSSOut][nBSharedOut], st.ss.BSharedOut]; DynaBusDrive[p[st.OSSOut][nSharedIn], st.ss.SharedIn]; DynaBusDrive[p[st.OSSOut][nBSStopOut], st.ss.BSStopOut]; DynaBusDrive[p[st.OSSOut][nSStopIn], st.ss.SStopIn]; p[st.OSSIn][nOwnerOut].b _ TRUE; p[st.OSSIn][nBOwnerIn].b _ TRUE; FOR d: Devices IN Devices DO p[st.OSSIn][nSharedOut][d].b _ TRUE; p[st.OSSIn][nSStopOut][d].b _ TRUE; ENDLOOP; FOR a: Arbiters IN Arbiters DO p[st.OSSIn][nBSharedIn][a].b _ TRUE; p[st.OSSIn][nBSStopIn][a].b _ TRUE; ENDLOOP; }; OtherArbiters: TYPE = [0..LAST[Arbiters]); OtherDevices: TYPE = [0..LAST[Devices]); DevRqInfo: TYPE = RECORD [type: DevReqType _ L, len: PacketLength _ long5]; ArbCoreMSRec: TYPE = RECORD [ OtherArbInBI: ARRAY [0..maxArbiters-1) OF [0..8) _ ALL[0], BusyInBI: BOOL _ FALSE, StopActBI: BOOL _ FALSE, RequestOutBI: ARRAY Devices OF [0..4) _ ALL[0], ArbReset: BOOL _ FALSE, LongGrantBO: BOOL _ FALSE, HiPGrantBO: BOOL _ FALSE, GrantBO: ARRAY Devices OF BOOL _ ALL[FALSE], ArbReqOutBO: [0..8) _ 0, BusyOutBO: BOOL _ TRUE, StartGrantBO: BOOL _ TRUE, LGrantHL: DevReqType, RqCtrs: ARRAY Devices OF ARRAY DevReqType OF ReqCount, LongFIFO: ARRAY Devices OF ARRAY ReqCount OF BOOL _ ALL[ALL[FALSE]], RqPrior1: ARRAY Devices OF Priority, RqInfo1: ARRAY Devices OF DevRqInfo, Hold: ARRAY Devices OF BOOL _ ALL[TRUE], DevRovers1: ARRAY Priority OF Devices _ ALL[0], ArbReq2: Priority, AmongBest2: ARRAY Devices OF BOOL _ ALL[TRUE], DRQInfo2: ARRAY Devices OF DevRqInfo, ClaimsHi2: ARRAY OtherDevices OF BOOL _ ALL[TRUE], ThisArbIn3: Priority, BestDev3: ARRAY Devices OF BOOL, -- at most one true LongGrant3: PacketLength, HiPGrant3: DevReqType, ArbRovers3: ARRAY Priority OF Arbiters, -- pipe delay of arbRovers AClaimsHi3: ARRAY OtherArbiters OF BOOL _ ALL[TRUE], LLGrant4: BOOL _ TRUE, -- not latched in hardware LclGrant4: BOOL _ TRUE, NoHold4: BOOL _ TRUE, GntPoss4: BOOL _ TRUE, DNewGrant4: ARRAY Devices OF BOOL _ ALL[TRUE], Grant4: ARRAY Devices OF BOOL _ ALL[TRUE], BstArbClaim4: Priority, AmgBest4: ARRAY Arbiters OF BOOL _ ALL[TRUE], ClaimsHi4: ARRAY OtherArbiters OF BOOL _ ALL[TRUE], StopAct4: BOOL _ TRUE, -- 19 Jan 88 LclGrant5: BOOL _ TRUE, GGrant5: BOOL _ TRUE, BestArb5: ARRAY OtherArbiters OF BOOL _ ALL[TRUE], BstArbClaim5: Priority, ArbRovers6: ARRAY Priority OF Arbiters, BusyOut: BOOL _ TRUE, -- not latched in hardware GCtr: ARRAY [0..2) OF BOOL _ ALL[TRUE] ]; ArbCore: PROC [p: Ports.Port, stateAny: REF ANY, clockEval: BOOL] -- Rosemary.EvalProc -- = { st: ArbExceptDBusState _ NARROW[stateAny]; SELECT TRUE FROM clockEval => NULL; p[st.Ck].b AND NOT st.lastCk => st.s _ st.m; -- positive-going clock edge NOT p[st.Ck].b => { -- clock low BusIn: PROC = { FOR a: Arbiters IN [0..maxArbiters-1) DO st.m.OtherArbInBI[a] _ p[st.OtherArbIn][a].c; ENDLOOP; st.m.BusyInBI _ NOT p[st.nBusyIn].b; st.m.StopActBI _ NOT p[st.nStopAct].b; FOR d: Devices IN Devices DO st.m.RequestOutBI[d] _ 3-p[st.nRequestOut][d].c; ENDLOOP; st.m.ArbReset _ p[st.Rst].b AND NOT st.s.StopActBI; }; BusOut: PROC = { FOR dev: Devices IN Devices DO st.m.GrantBO[dev] _ st.m.Grant4[dev]; ENDLOOP; st.m.HiPGrantBO _ st.m.HiPGrant3 = H; st.m.LongGrantBO _ st.m.LongGrant3 = long5; st.m.ArbReqOutBO _ st.m.ArbReq2; st.m.BusyOutBO _ st.m.BusyOut; st.m.StartGrantBO _ st.m.LclGrant4; }; NvrMind: PROC [ p: Priority ] RETURNS [ Priority ] = { RETURN[(IF (p <= HoldPriority) THEN HoldPriority ELSE NoRequestPriority)]; }; RealReq: PROC [ p: Priority ] RETURNS [ BOOL ] = { RETURN[(p # HoldPriority) AND (p # NoRequestPriority)]; }; Pipe0: PROC = { FOR dev: Devices IN Devices DO reqCode: DevReqCode; pr: PriorityRec; TRUSTED { reqCode _ LOOPHOLE[st.s.RequestOutBI[dev]]; pr _ LOOPHOLE[p[st.DPriority][dev].c]; }; FOR drt: DevReqType IN DevReqType DO up: [0..1] = (SELECT TRUE FROM drt=L AND ((reqCode = reqL) OR ((reqCode = reqH) AND NOT pr.nFIFOEna)) => 1, drt=H AND ((reqCode = reqH) AND pr.nFIFOEna) => 1, ENDCASE => 0); down: [0..1] = (IF st.s.DNewGrant4[dev] AND drt = st.s.LGrantHL THEN 1 ELSE 0); st.m.RqCtrs[dev][drt] _ (IF st.s.ArbReset THEN 0 ELSE MAX[MIN[st.s.RqCtrs[dev][drt]+up, LAST[ReqCount]]-down, 0] ); ENDLOOP; -- drt FOR q: ReqCount IN ReqCount DO looksLong: BOOL = (st.s.RequestOutBI[dev] MOD 2 = 1); occ: INT = st.s.RqCtrs[dev][L]-1; st.m.LongFIFO[dev][q] _ (occ < q AND looksLong) -- fill -- OR (occ <= q AND looksLong AND st.s.DNewGrant4[dev]) -- fill -- OR (occ >= q AND st.s.LongFIFO[dev][q] AND NOT st.s.DNewGrant4[dev]) -- hold -- OR (occ > q AND (q < LAST[ReqCount]) AND st.s.LongFIFO[dev][q+1] AND st.s.DNewGrant4[dev]) -- shift -- ; ENDLOOP; -- q ENDLOOP; -- dev st.m.LGrantHL _ st.s.HiPGrant3; }; EncodeUnary8: PROC [ a: ARRAY [0..8) OF BOOL ] RETURNS [ c: [0..8) ] = { FOR cv: [0..8) IN [0..8) DO IF a[cv] THEN {c _ cv; RETURN}; ENDLOOP; c _ 0; }; EncodeUnary7: PROC [ a: ARRAY [0..7) OF BOOL ] RETURNS [ c: [0..8) ] = { FOR cv: [0..7) IN [0..7) DO IF a[cv] THEN {c _ cv+1; RETURN}; ENDLOOP; c _ 0; }; Pipe1: PROC = { FOR dev: Devices IN Devices DO pr: PriorityRec; TRUSTED { pr _ LOOPHOLE[p[st.DPriority][dev].c] }; SELECT TRUE FROM st.m.RqCtrs[dev][H] > 0 => { st.m.RqPrior1[dev] _ pr.hiP; st.m.RqInfo1[dev] _ [H, IF pr.hiLong THEN long5 ELSE short2]; }; st.m.RqCtrs[dev][L] > 0 => { st.m.RqPrior1[dev] _ pr.loP; st.m.RqInfo1[dev] _ [L, IF pr.loLong THEN long5 ELSE short2]; }; ENDCASE => { st.m.RqPrior1[dev] _ NoRequestPriority; st.m.RqInfo1[dev] _ []; }; IF (NOT pr.nFIFOEna) AND (NOT st.m.LongFIFO[dev][0]) THEN st.m.RqInfo1[dev].len _ short2; st.m.Hold[dev] _ (SELECT st.s.RequestOutBI[dev] FROM ORD[DevReqCode[release]] => FALSE, ORD[DevReqCode[seize]] => TRUE, ENDCASE => st.s.Hold[dev]); ENDLOOP; -- dev FOR pr: Priority IN Priority DO st.m.DevRovers1[pr] _ (SELECT TRUE FROM st.s.ArbReset => 0, st.s.LclGrant4 AND pr=st.s.BstArbClaim4 => EncodeUnary8[st.s.DNewGrant4], ENDCASE => st.m.DevRovers1[pr]); ENDLOOP; }; Pipe2: PROC = { minP: Priority; anyHold: BOOL; anyHold _ FALSE; minP _ NoRequestPriority; FOR dev: Devices IN Devices DO minP _ MIN[minP, st.s.RqPrior1[dev]]; IF st.s.Hold[dev] THEN { anyHold _ TRUE; minP _ MIN[minP, HoldPriority]; }; ENDLOOP; FOR dev: OtherDevices IN OtherDevices DO st.m.ClaimsHi2[dev] _ (st.s.DevRovers1[st.s.RqPrior1[dev]] <= dev); ENDLOOP; st.m.ArbReq2 _ (SELECT TRUE FROM NOT st.s.LclGrant4 => minP, anyHold => HoldPriority, ENDCASE => NoRequestPriority ); FOR dev: Devices IN Devices DO st.m.AmongBest2[dev] _ st.s.RqPrior1[dev] <= minP; ENDLOOP; st.m.DRQInfo2 _ st.s.RqInfo1; }; Pipe3: PROC = { HotDevice: PROC [ dev: Devices ] RETURNS [ hot: BOOL ] = INLINE { hot _ st.s.AmongBest2[dev] AND (dev > 0) AND st.s.ClaimsHi2[dev-1]; }; anyHi, ffzHi, ffzLo: BOOL _ FALSE; TRUSTED { st.m.LongGrant3 _ LOOPHOLE[0]; st.m.HiPGrant3 _ LOOPHOLE[0]; }; FOR dev: Devices IN Devices DO anyHi _ anyHi OR HotDevice[dev]; ENDLOOP; FOR dev: Devices IN Devices DO st.m.BestDev3[dev] _ (NOT ffzHi AND HotDevice[dev]) OR (NOT anyHi AND NOT ffzLo AND st.s.AmongBest2[dev]); IF st.m.BestDev3[dev] THEN [len: st.m.LongGrant3, type: st.m.HiPGrant3] _ st.s.DRQInfo2[dev]; ffzHi _ ffzHi OR HotDevice[dev]; ffzLo _ ffzLo OR st.s.AmongBest2[dev]; ENDLOOP; FOR a: OtherArbiters IN OtherArbiters DO st.m.AClaimsHi3[a] _ (st.s.ArbRovers6[st.s.ArbReq2] <= a); ENDLOOP; st.m.ThisArbIn3 _ (IF st.s.LclGrant4 THEN NvrMind[st.s.ArbReq2] ELSE st.s.ArbReq2); st.m.ArbRovers3 _ st.s.ArbRovers6; }; Pipe4: PROC = { oap, oapFiltered: ARRAY OtherArbiters OF Priority; otherWins: BOOL _ FALSE; st.m.NoHold4 _ (NOT st.s.LclGrant5) OR (st.s.ThisArbIn3 > HoldPriority); st.m.BstArbClaim4 _ st.s.ThisArbIn3; FOR a: OtherArbiters IN OtherArbiters DO oap[a] _ st.s.OtherArbInBI[a]; oapFiltered[a] _ (IF st.s.BestArb5[a] THEN NoRequestPriority ELSE oap[a]); otherWins _ otherWins OR (oapFiltered[a] < st.s.ThisArbIn3) OR ((oapFiltered[a] = st.s.ThisArbIn3) AND st.s.AClaimsHi3[a]); st.m.BstArbClaim4 _ MIN[st.m.BstArbClaim4, oapFiltered[a]]; st.m.NoHold4 _ st.m.NoHold4 AND ((NOT st.s.BestArb5[a]) OR (oap[a] > HoldPriority)); ENDLOOP; st.m.GntPoss4 _ NOT st.m.GGrant5 AND NOT st.s.BusyInBI -- AND NOT st.s.StopActBI -- ; -- 5 Oct 87 st.m.LclGrant4 _ st.m.GntPoss4 AND NOT st.s.StopActBI AND RealReq[st.s.ThisArbIn3] AND NOT otherWins AND st.m.NoHold4; -- 5 Oct 87 st.m.LLGrant4 _ st.m.LclGrant4 AND (st.s.LongGrant3 = long5); IF NOT ArbNov87A THEN st.m.StopAct4 _ st.s.StopActBI; -- 19 Jan 88 FOR dev: Devices IN Devices DO st.m.DNewGrant4[dev] _ st.s.BestDev3[dev] AND st.m.LclGrant4; st.m.Grant4[dev] _ st.m.DNewGrant4[dev] OR (NOT st.m.GntPoss4 AND st.s.Grant4[dev]); ENDLOOP; FOR a: Arbiters IN Arbiters DO st.m.AmgBest4[a] _ (IF a=0 THEN st.s.ThisArbIn3 ELSE oapFiltered[a-1]) <= st.m.BstArbClaim4; ENDLOOP; FOR a: OtherArbiters IN OtherArbiters DO st.m.ClaimsHi4[a] _ (st.s.ArbRovers3[oapFiltered[a]] <= a); ENDLOOP; }; Pipe5: PROC = { AmgBest: PROC [ a: OtherArbiters ] RETURNS [ BOOL ] = INLINE { RETURN[st.s.AmgBest4[a+1]]; -- [0] is this arbiter }; anyHi, ffzHi: BOOL _ FALSE; ffzLo: BOOL _ st.s.AmgBest4[0]; st.m.LclGrant5 _ st.s.LclGrant4; st.m.GGrant5 _ RealReq[st.s.BstArbClaim4] AND st.s.NoHold4 AND st.s.GntPoss4 AND (ArbNov87A OR NOT st.s.StopAct4 -- 19 Jan 88 -- ); FOR a: OtherArbiters IN OtherArbiters DO -- this arbiter never ClaimsHi anyHi _ anyHi OR (AmgBest[a] AND st.s.ClaimsHi4[a]); ENDLOOP; FOR a: OtherArbiters IN OtherArbiters DO st.m.BestArb5[a] _ (st.m.GGrant5 AND NOT ffzHi AND (AmgBest[a] AND st.s.ClaimsHi4[a])) OR (st.m.GGrant5 AND NOT anyHi AND NOT ffzLo AND AmgBest[a]); ffzHi _ ffzHi OR (AmgBest[a] AND st.s.ClaimsHi4[a]); ffzLo _ ffzLo OR AmgBest[a]; ENDLOOP; st.m.BstArbClaim5 _ st.s.BstArbClaim4; }; Pipe6: PROC = { FOR pr: Priority IN Priority DO st.m.ArbRovers6[pr] _ (SELECT TRUE FROM st.s.ArbReset => p[st.ArbNo].c, (st.s.GGrant5 AND pr = st.s.BstArbClaim5) => EncodeUnary7[st.s.BestArb5], ENDCASE => st.s.ArbRovers6[pr]); ENDLOOP; }; GCtr: PROC = { FOR i: [0..2) IN [0..2) DO st.m.GCtr[i] _ (SELECT TRUE FROM st.m.LLGrant4 => TRUE, i < 1 => st.s.GCtr[i+1], ENDCASE => FALSE); ENDLOOP; st.m.BusyOut _ st.m.LLGrant4 OR st.s.GCtr[0]; }; BusIn; Pipe5; -- Pipe4 before Pipe4 because Pipe4 needs st.m.GGrant5 Pipe4; -- Pipe4 before Pip11 and Pipe2 because both need st.m.LclGrant4 Pipe0; -- Pipe0 before Pipe1 because Pipe1 needs st.m.RqCtrs and st.m.LongFIFO Pipe1; Pipe2; Pipe3; Pipe6; GCtr; BusOut; }; -- clock low ENDCASE => NULL; FOR dev: Devices IN Devices DO DynaBusDrive[p[st.nGrant][dev], st.s.GrantBO[dev]]; ENDLOOP; DynaBusDrive[p[st.nHiPGrant], st.s.HiPGrantBO]; DynaBusDrive[p[st.nLongGrant], st.s.LongGrantBO]; FOR i: NAT IN [0..3) DO DynaBusDrive[p[st.ArbReqOut][i], NOT BitOps.EBFW[st.s.ArbReqOutBO, i, 3]]; ENDLOOP; DynaBusDrive[p[st.nBusyOut], st.s.BusyOutBO]; DynaBusDrive[p[st.nStartGrant], st.s.StartGrantBO]; FOR pr: Priority IN Priority DO -- debugging output p[st.ArbRovers6][pr].c _ st.s.ArbRovers6[pr]; ENDLOOP; p[st.nBusyIn].b _ TRUE; p[st.nStopAct].b _ TRUE; FOR a: Arbiters IN [0..maxArbiters-1) DO p[st.OtherArbIn][a].c _ 7; ENDLOOP; FOR d: Devices IN Devices DO p[st.nRequestOut][d].c _ 3; ENDLOOP; }; ArbDBusName: ROPE = Rosemary.Register[roseClassName: "ArbDBusCode", init: ArbDBusInit, evalSimple: ArbDBusSimple, scheduleIfClockEval: TRUE]; ArbPropsLen: NAT = 4; ArbDBusInterface: Wire = WireList[LIST[ Seq["DBus", 7], Seq["SlotNo", 4], Seq["BdVersion", 2], Seq["nDHybridSel", 5], "DBdSel", Seq["DPriority", maxDevices, Seq[size: 9]], Seq["ArbNo", 3], "CkOut", "Rst", "Ck", "Vdd", "Gnd" ]]; ArbDBusCodeCT: PUBLIC PROC [arbNo: INT _ 0, pra: PRA _ ALL[DefaultPriority]] RETURNS [ ct: CoreCreate.CellType ] = { dBus, dPriority: NAT; ct _ CoreClasses.CreateUnspecified[name: ArbDBusName, public: ArbDBusInterface]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: ArbDBusName]; [] _ CoreFlat.CellTypeCutLabels[ct, Logic.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, "nDHybridSel"]; 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, "CkOut"]; Ports.InitPorts[ct, b, drive, "Rst"]; Ports.InitPorts[ct, b, none, "Ck", "Vdd", "Gnd"]; ct.properties _ CoreProperties.PutProp[ct.properties, $arbNo, NEW[INT _ arbNo]]; ct.properties _ CoreProperties.PutProp[ct.properties, $pra, NEW[PRA _ pra]]; }; ArbiterDBusState: TYPE = REF ArbiterDBusStateRec; ArbiterDBusStateRec: TYPE = RECORD [ DBus, SlotNo, BdVersion, nDHybridSel, DBdSel, DPriority, ArbNo, Rst, CkOut, Ck: NAT _ LAST[NAT], lastCk, lastDCk : BOOL _ TRUE, m, s: MSRec, -- sync with Ck dm, ds: ArbDMSRec -- asynch state ]; ArbDBusInit: Rosemary.InitProc = { st: ArbiterDBusState = (IF oldStateAny # NIL THEN NARROW[oldStateAny] ELSE NEW[ArbiterDBusStateRec]); r: REF ANY; arbNo: INT _ 0; pra: PRA _ ALL[DefaultPriority]; r _ CoreProperties.GetProp[cellType.properties, $arbNo]; IF r # NIL AND ISTYPE[r, REF INT] THEN arbNo _ NARROW[r, REF INT]^; r _ CoreProperties.GetProp[cellType.properties, $pra]; IF r # NIL AND ISTYPE[r, REF PRA] THEN pra _ NARROW[r, REF PRA]^; FOR d: Devices IN Devices DO st.ds.DevPriority[d] _ st.dm.DevPriority[d] _ pra[d]; -- saves a lot of DBus initialization ENDLOOP; st.ds.ArbProps _ st.dm.ArbProps _ LOOPHOLE[ArbProps[arbNo: arbNo, hySelDec: TRUE]]; [st.DBus] _ Ports.PortIndexes[cellType.public, "DBus"]; [st.SlotNo, st.BdVersion, st.nDHybridSel, st.DBdSel] _ Ports.PortIndexes[cellType.public, "SlotNo", "BdVersion", "nDHybridSel", "DBdSel"]; [st.DPriority, st.ArbNo, st.Rst] _ Ports.PortIndexes[cellType.public, "DPriority", "ArbNo", "Rst"]; [st.CkOut, st.Ck] _ Ports.PortIndexes[cellType.public, "CkOut", "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) _ 0, arbNo (0: 12..14): [0..8), hySelDec(0: 15..15): BOOL ]; MSRec: TYPE = RECORD [ Reset: 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, clockEval: BOOL] RETURNS [ stateValue: Ports.LevelSequence _ NIL ]-- Rosemary.EvalProc -- = { st: ArbiterDBusState _ NARROW[stateAny]; dba: DBusAddr; thisBd: BOOL; TRUSTED {dba _ LOOPHOLE[st.ds.DBAddr]}; thisBd _ NOT p[st.DBus][DAddress].b AND (dba.board = p[st.SlotNo].c); SELECT TRUE FROM clockEval => NULL; p[st.DBus][DShiftCK].b AND NOT st.lastDCk => { st.lastDCk _ TRUE; st.ds _ st.dm; }; NOT p[st.DBus][DShiftCK].b => { -- DShiftCK low, compute DBus master stages dsi: BOOL = p[st.DBus][DSerialIn].b; st.lastDCk _ FALSE; 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; }; -- DShiftCK low 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[0], 0, PriorityRecLen], 2 => BitOps.EBFW[st.ds.ArbProps, 0, ArbPropsLen], 3 => BitOps.EBFW[st.ds.BoardVersionShadow, 0, 2], ENDCASE => FALSE) ELSE TRUE) }; p[st.nDHybridSel].c _ 01FH - (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; SELECT TRUE FROM clockEval => NULL; p[st.Ck].b AND NOT st.lastCk => { st.lastCk _ TRUE; st.s _ st.m; }; NOT p[st.Ck].b => { st.lastCk _ FALSE; st.m.Reset[0] _ NOT p[st.DBus][nDReset].b; st.m.Reset[1] _ st.s.Reset[0]; }; ENDCASE => NULL; p[st.CkOut].b _ p[st.Ck].b; p[st.Rst].b _ st.s.Reset[1]; }; END. ArbiterImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. McCreight May 27, 1987 11:41:13 am PDT Last Edited by: McCreight January 19, 1988 2:00:02 pm PST Don Curry September 7, 1988 8:11:41 pm PDT implement the first fabricated version, or the current version. This comes in three parts. The first makes the record cell for ArbInFrame. The second is the functional specification for ArbExceptDBus. And the third is the functional specification for DBusSect. ArbInFrame "RecAdj", ArbExceptDBus Requesting devices Backpanel Debugging OSSIn OSSOut DBus Misc .. master (loads during clock low) / slave (transfers out when clock goes high) State kept in master/slave form to avoid feedback races.. Passive pull-up The following assignment of state to pipe stage can be misleading for feedback loops. Bus in Bus out Pipe stage 0 Pipe Stage 1 Pipe Stage 2 device 0 never claims high Pipe Stage 3 Pipe Stage 4 Pipe Stage 5 Pipe Stage 6 Grant cycle counter Warning: combinatorial from Pipe0 Find the minimum (best) priority request among all local device requests. Include any Hold as a request at HoldPriority. If we are recovering from a local grant, request either at HoldPriority or NoRequestPriority based on Hold. See whether any other arbiter is making a higher-priority request than this one, or the same priority and between the rover and this arbiter. Another arbiter has better priority The rover points ahead of another arbiter with equal priority Decide whether a grant will happen next cycle. Gate the individual device grant wires. Pipe information forward to help change arbiter rover. Pipe4 before GCtr because GCtr needs st.m.LLGrant4 DynaBusDrive inverts; for this signal we don't want that Passive pull-up ArbDBus 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šœ<™˜>Jšœ@˜@Jšœ=˜=Jšœ˜—Jšœ˜—šœ œ˜"J˜—šœT˜TJ˜—J˜—J™Jš  ™ ™Jšœžœœ„œ˜’J˜šžœœ˜-šœ™Jšœ.Ÿ˜FJšœŸ˜1Jšœ Ÿ˜J˜ J˜—šœ ™ JšœŸ#˜8Jšœ0Ÿ˜OJ˜JšœŸ˜,Jšœ Ÿ˜J˜—™ Jšœ$Ÿ˜A—J™™šœ œ˜'Jšœ+˜+J˜4—J˜—šœ™šœ œ˜'Jšœ˜J˜$—J˜—™Jšœ+˜+J˜J˜—J˜™J˜—J˜J˜—šžœœœœ ˜HJšœKœ˜OJ˜J˜\J˜KJšœ7˜7J˜1J˜.šœ œ ˜J˜AJ˜CJšœ˜—Jšœ9˜9Jšœ4˜4šœœœ˜JšœF˜FJšœ˜—Jšœ6˜6šœ œ˜(J˜GJšœ˜—JšœT˜TJ˜Jšœ,˜,Jšœ.˜.šœ œ ˜JšœN˜NJšœM˜MJšœ˜—šœ œ ˜JšœN˜NJšœM˜MJšœ˜—JšœJ˜JJšœJ˜JJšœH˜HJšœF˜FJšœI˜IJšœG˜GJšœH˜HJšœF˜FJ˜Jšœ6˜6šœœ ˜JšœD˜DJšœ˜J˜—Jšœ4˜4šœ œ ˜J˜AJšœ˜—J˜&J˜$J˜J˜1J˜J˜J˜—Jšœœœ˜5šœœœ˜&šœB˜BJšœ)˜)Jšœ ˜ Jšœ˜J˜Jšžœœœœ˜—Jšœœœ˜J˜˜JšœO™OJšœ9™9—J˜J˜—šžœ˜(š œœœœœœœ˜iJšœœ˜ JšœΈ˜ΈJšœ‚˜‚J˜Jšœ@˜@J˜JšœH˜HJ˜Jšœd˜dJ˜—J˜J˜J˜—šžœœœœ œœ%œŸœ˜šJšœœ ˜*Jšœ˜Jšœ˜Jšœ œ˜*J˜—J˜šž œœœ˜5Jšœœ˜Jšœœœœ ˜)Jšœ˜J˜—šœœœ˜Jšžœœœ˜Jšž œœœ˜Jšžœœœ˜Jšžœœœ˜Jš ž œœ œœœœ˜.Jšž œœœ˜Jš ž œœ œœœœ˜/Jšžœœœ˜Jš žœœ œœœœ˜-Jšž œœœ˜Jš žœœ œœœœ˜.Jšžœœ˜Jšœ˜J˜—š ž œœœœ œŸœ˜_Jšœœ ˜*šœœ˜Jšœ œ˜Jšœ œœ˜/šœ˜Jšœœ˜.Jšœ!˜!Jšœœ˜.Jšœ˜J˜Jšœœ˜Jšœœ˜šœ œ ˜Jšœœ˜6Jšœ$œ˜:Jšœœ˜4Jšœ"œ˜7Jšœ˜J˜—Jšœœ˜Jšœœ˜šœ œ ˜Jšœœ˜6Jšœ œ˜6Jšœœ˜4Jšœœ˜3Jšœ˜—Jšœ˜—Jšœœ˜J˜—Jšœ8˜8Jšœ4˜4Jšœ:˜:Jšœ6˜6Jšœ8˜8Jšœ4˜4J˜Jšœ™Jšœœ˜ Jšœœ˜ šœ œ ˜Jšœœ˜$Jšœœ˜#Jšœ˜—šœ œ ˜Jšœœ˜$Jšœœ˜#Jšœ˜—J˜J˜—Jšœœœ ˜*Jšœœœ ˜(J˜Jšœ œœ3˜KJ˜šœœœ˜J˜JšœU™UJ™šœ™Jšž œœœ œ˜:Jšžœœœ˜Jšž œœœ˜Jšž œœ œ œ˜/Jšžœœœ˜J˜—šœ™Jšž œœœ˜Jšž œœœ˜Jš žœœ œœœœ˜,Jšœ˜Jšž œœœ˜Jšž œœœ˜J˜—šœ ™ Jšžœ ˜Jš žœœ œœ œ ˜6Jšžœœ œœ œœœœœ˜DJ™—šœ ™ Jšžœœ œ ˜$Jšžœœ œ ˜$Jš žœœ œœœœ˜(Jšž œœ œ œ˜/J˜—šœ ™ Jšžœ ˜Jš ž œœ œœœœ˜.Jšžœœ œ ˜%š ž œœœœœœ˜2Jšœ™—J™—šœ ™ Jšž œ ˜Jš žœœ œœŸ˜4Jšž œ˜Jšž œ ˜Jšž œœ œ Ÿ˜BJš ž œœœœœœ˜4J™—šœ ™ JšžœœœŸ˜1Jšž œœœ˜J˜Jšžœœœ˜Jšžœœœ˜Jš ž œœ œœœœ˜.Jš žœœ œœœœ˜*Jšž œ ˜Jš žœœ œœœœ˜-Jš ž œœœœœœ˜3J˜JšžœœœŸ ˜#J˜—šœ ™ Jšž œœœ˜Jšžœœœ˜Jš žœœœœœœ˜2Jšž œ ˜J˜—šœ ™ Jšž œœ œ ˜'J˜—šœ™JšžœœœŸ˜0Jš žœœœœœœ˜&J˜—J˜J˜J˜—š žœœœœ œŸœ˜]Jšœœ ˜*J˜šœœ˜Jšœ œ˜Jšœ œœŸ˜IšœŸ ˜ J˜šžœœ˜šœ œ˜(Jšœ-˜-Jšœ˜—Jšœœ˜$Jšœœ˜&šœ œ ˜Jšœ0˜0Jšœ˜—Jšœœœ˜3Jšœ˜J˜—šžœœ˜šœœ ˜Jšœ%˜%Jšœ˜—Jšœ%˜%Jšœ+˜+Jšœ ˜ Jšœ˜Jšœ#˜#Jšœ˜J˜—šžœœœ˜6Jšœœœœ˜JJ˜J˜—šžœœœœ˜2Jšœœ˜7J˜J˜—šžœœ˜šœœ ˜Jšœ˜Jšœ˜šœ˜ Jšœ œ˜+Jšœœ˜&Jšœ˜—šœœ ˜$šœœœ˜Jš œœœœœ˜LJšœœœ˜2Jšœ˜—Jš œœœœœ˜Ošœœœ˜5Jšœœœ˜:J˜—JšœŸ˜—šœ œ ˜Jšœ œœ˜5Jšœœ˜!šœ˜Jšœ œ Ÿ œ˜%Jšœ œ œŸ œ˜?Jš œ œœœŸ œ˜OJš œ œœ œœŸ œ˜e—JšœŸ˜ —JšœŸ˜—J˜J˜J˜—š ž œœœœœœ˜Hšœ œ˜Jšœœ œ˜Jšœ˜—Jšœ˜Jšœ˜J˜—š ž œœœœœœ˜Hšœ œ˜Jšœœ œ˜!Jšœ˜—Jšœ˜Jšœ˜J˜—Jšžœœ˜˜šœœ ˜Jšœ!™!Jšœ˜Jšœœ˜2šœœ˜šœ˜Jšœ˜Jšœœ œœ ˜=Jšœ˜—šœ˜Jšœ˜Jšœœ œœ ˜=Jšœ˜—šœ˜ Jšœ'˜'Jšœ˜J˜—J˜—š œœœœ˜9Jšœ˜—J˜šœœ˜4Jšœœ˜"Jšœœ˜Jšœ˜—JšœŸ˜J˜—šœœ ˜šœœœ˜'Jšœ˜Jšœœ7˜IJšœ˜ —Jšœ˜—J˜J˜—šžœœ˜J˜Jšœ œ˜J˜šœζ™ζJšœ œ˜J˜šœœ ˜Jšœœ˜%šœœ˜Jšœ œ˜Jšœœ˜J˜—Jšœ˜—šœœ˜(JšœC˜CJšœ˜—šœœœ˜ Jšœ˜J˜Jšœ˜J˜—šœœ ˜Jšœ2˜2Jšœ˜—Jšœ˜—J˜J˜—Jšžœœ˜˜š ž œœœœœ˜AJšœœ œ˜CJšœ˜J˜—Jšœœœ˜"šœ˜ Jšœœ˜Jšœœ˜J˜—šœœ ˜Jšœœ˜ Jšœ˜—šœœ ˜šœ˜Jšœœœ˜!Jš œœœœœ˜3—šœ˜JšœB˜B—Jšœœ˜ Jšœœ˜&Jšœ˜J˜—šœœ˜(Jšœ:˜:Jšœ˜J˜—Jšœœœœ˜SJšœ"˜"J˜J˜—šžœœ˜Jšœœœ ˜2Jšœ œœ˜J™šœ™Jšœœœ"˜HJšœ$˜$šœœ˜(Jšœ˜Jšœœœœ ˜Jšœ˜šœ#˜%J™#—šœ$œ˜JšœŸ˜2Jšœ˜J˜—Jšœœœ˜Jšœœ˜Jšœ ˜ Jš œ*œœœ œœŸœ˜ƒšœœœŸ˜GJšœœ œ˜4Jšœ˜—šœœ˜(šœ˜Jš œœœœ œ˜FJš œœœœœœ ˜:—Jšœœ œ˜4Jšœœ ˜Jšœ˜J˜—Jšœ&˜&Jšœ˜J˜—šžœœ˜šœœ ˜šœœœ˜'Jšœ˜Jšœœ8˜IJšœ˜ —Jšœ˜—J˜J˜—šžœœ˜šœ œ˜šœœœ˜ Jšœœ˜Jšœ˜Jšœœ˜—Jšœ˜—Jšœœ˜-J˜J˜—Jšœ˜JšœŸ6˜=šœŸ@˜GJšœ2™2—JšœŸG˜NJ˜J˜J˜J˜J˜J˜JšœŸ ˜—Jšœœ˜J˜—šœœ ˜Jšœ3˜3Jšœ˜—Jšœ/˜/Jšœ1˜1šœœœ˜šœ!œœ˜JJšœ8™8—Jšœ˜—Jšœ-˜-Jšœ3˜3J˜šœœ œŸ˜3J˜-Jšœ˜—J˜Jšœ™Jšœœ˜Jšœœ˜šœ œ˜(Jšœ˜Jšœ˜—šœ œ ˜Jšœ˜Jšœ˜—J˜J˜J˜J˜J˜——Jš ™J˜J˜Jšœž œœvœ˜ŽJ˜Jšž œœ˜J˜šžœœ˜'™J˜J˜J˜J˜J˜ —J˜™Jšœ+˜+J˜J˜J˜J˜—™J˜—J˜J˜—šž œœœ œ œœœ ˜tJšœœ˜JšœP˜PJšœE˜EJšœ7˜7J˜J˜*šœœœ˜'J˜œœ ˜PJšœ<œœ ˜LJ˜J˜—Jšœœœ˜1šœœœ˜$˜-Jšœ˜Jš œžœœœœ˜—Jšœœœ˜Jšœ Ÿ˜šœŸ˜!JšœO™OJšœ9™9—J˜J˜—šž œ˜"Jš œœœœœœœ˜eJšœœœ˜ Jšœœ˜Jšœœœ˜ Jšœ8˜8Jšœœœœœœœ œœœ˜CJšœ6˜6Jšœœœœœœœœœœ˜AJ˜šœ œ ˜Jšœ6Ÿ%˜[Jšœ˜—Jšœ"œ"œ˜SJšœ7˜7J˜ŠJšœc˜cJ˜FJ˜J˜J˜—J˜J˜š œ œœ œœ˜+J˜J˜J˜J˜J˜J˜J˜—š œ œœ œœ˜+J˜!J˜Jšœ˜J˜J˜—šœœœ˜Jš œœœœœœ˜(J˜J˜—šœ œœ˜JšžœŸ˜5Jšžœ˜$Jšž œœ œœ˜6JšžœŸ˜7Jšžœ˜&J˜—˜J˜—šž œœœœ œœ%œŸœ˜”Jšœœ ˜(J˜Jšœœ˜ Jšœœ˜'Jšœ œœ˜EJ˜šœœ˜Jšœ œ˜šœœœ˜.Jšœ œ˜Jšœ˜J˜—šœŸ+˜KJšœœ˜$Jšœ œ˜J˜šœœ˜šœ˜šœœ˜J˜ J˜.J˜—JšœŸ˜4J˜—šœœŸœ˜9JšœI˜Išœ ˜šœ$œ˜)J˜ J˜7J˜J˜—˜šœ œ ˜šœœ˜#šœ œœ œ˜)Jšœœ-˜8—JšœB˜BJšœ˜Jšœ ˜ —Jšœ˜——šœœ˜"J˜ J˜9J˜J˜—Jšœœ˜—J˜—šœŸ œ˜*Jšœ-˜-—Jšœœ˜—JšœŸ˜—Jšœœ˜J˜—Jš œœ œœœ ˜Xšœœ œ˜Kšœœ ˜Jšœ œ˜/Jšœ œ*˜:Jšœ œ!˜1Jšœ œ!˜1Jšœœ˜—Jšœœ˜ J˜—šœ˜šœœœ-˜DšœŸœ˜#šœœœ œ˜(šœœ œ˜'J˜-—Jšœ˜——šœŸ œ˜Jšœœ;˜F—Jšœœ˜——Jšœ˜Jšœœ$˜?šœ œ ˜šœœ˜#Jšœ ˜ Jšœ˜Jšœ˜Jšœ ˜ —Jšœ˜—J˜šœœ˜Jšœ œ˜šœ œœ˜!Jšœ œ˜Jšœ ˜ J˜—šœ˜Jšœ œ˜Jšœœ˜*Jšœ˜Jšœ˜—Jšœœ˜—J˜Jšœ˜Jšœ˜Jšœ˜J˜—Jšœ˜J˜——…—lL—΅