CreateArbSysCellType:
PROC[useSchematic:
BOOL←
FALSE, useDBus:
BOOL←
FALSE, cutSet: CoreFlat.CutSet, startTest:
IO.
ROPE ] = {
OPEN CC: CoreCreate;
AddArbSysProp:
PROC [ prop:
ATOM, value:
REF
ANY ] =
{arbSys.properties 𡤌oreProperties.PutProp[on: arbSys.properties, prop: prop, value: value]};
dBusInits: Arbiter.DBusInitList ← NIL;
inst: CoreCreate.CellInstance;
instances: CoreCreate.CellInstances ← LIST[];
arbCT: ARRAY Arbiters OF Core.CellType;
reqDevCT: ARRAY Arbiters OF ARRAY Devices OF Core.CellType;
buf: Core.CellType = Logic.Driver[1]; -- pin isolation for vector capture
port: NAT;
bpPAs: LIST OF CoreCreate.PA ← NIL;
systemTests: LIST OF IO.ROPE ← GetSystemTests[];
arb0Path: IO.ROPE ← "/Arb0";
publics: Core.Wire = CoreCreate.WireList[
LIST[
CC.Seq["nRequestOuts", maxArbiters, CC.Seq[size: maxDevices, protoChild: CC.Seq[size: 2]]],
CC.Seq["nGrants", maxArbiters, CC.Seq[size: maxDevices]],
CC.Seq["nHiPGrants", maxArbiters],
CC.Seq["nLongGrants", maxArbiters],
CC.Seq["ArbReqs", maxArbiters, CC.Seq[size: 3]],
"nStartGrant",
CC.Seq["nBusyOuts", maxArbiters+1], -- one port for patch
"nBusyIn",
CC.Seq["ArbRovers6s", maxArbiters,
CC.Seq[size: 8, protoChild:
CC.Seq[size: 3]]],
... strictly for debugging
CC.Seq["nOwnerOuts", maxArbiters],
CC.Seq["nBOwnerOuts", maxArbiters],
"nBOwnerIn",
CC.Seq["nOwnerIns", maxArbiters],
CC.Seq["nSharedOuts", maxArbiters, CC.Seq[size: maxDevices]],
CC.Seq["nBShareds", maxArbiters],
CC.Seq["nBSharedBufs", maxArbiters],
CC.Seq["nSharedIns", maxArbiters],
CC.Seq["nSStopOuts", maxArbiters, CC.Seq[size: maxDevices]],
CC.Seq["nBSStops", maxArbiters],
CC.Seq["nBSStopBufs", maxArbiters],
CC.Seq["nSStopIns", maxArbiters],
"nStopAct",
CC.Seq["DBus", 7],
CC.Seq["SlotNos", maxArbiters, CC.Seq[size: 4]],
CC.Seq["nDHybridSels", maxArbiters, CC.Seq[size: 5]],
CC.Seq["BdVersions", maxArbiters, CC.Seq[size: 2]],
CC.Seq["DBdSels", maxArbiters],
CC.Seq["CKOuts", maxArbiters],
CC.Seq["TInv", 2],
CC.Seq["TRec2v", 3],
"RecAdj",
CC.Seq["TIOBus", 6],
"nDynaBusBusy", "nHolding",
"Ck", "Vdd", --"Gnd2V",-- "Gnd"
]];
IF startTest#
NIL
THEN {
systemTests ← CONS[startTest, systemTests];
FOR list:
LIST
OF
IO.
ROPE ← systemTests, list.rest
WHILE list.rest#
NIL
DO
IF ~list.rest.first.Equal[startTest] THEN LOOP;
list.rest ← list.rest.rest;
EXIT ENDLOOP};
FOR a: Arbiters
IN Arbiters
DO
pas: LIST OF CoreCreate.PA;
pra: PRA;
InsertCardInBoolSeq:
PROC [ source:
CARDINAL, container: Ports.BoolSequence, fieldPosition, fieldWidth:
NAT ] = {
FOR i:
NAT
DECREASING
IN [fieldPosition..fieldPosition+fieldWidth)
DO
container[i] ← (Basics.BITAND[source, 1] # 0);
source ← Basics.BITSHIFT[source, -1];
ENDLOOP};
CodeDPP:
PROC [dpp: DevPortParams]
RETURNS [code:
CARDINAL] =
{RETURN[2*dpp.priority+(IF dpp.length=long5 THEN 1 ELSE 0)]};
arbNo: Arbiter.DBusInitItem ← [addr: 4096*a+2, bits: NEW[Ports.BoolSequenceRec[4]]];
dPriority: Arbiter.DBusInitItem ← [addr: 4096*a+1, bits: NEW[Ports.BoolSequenceRec[72]]];
InsertCardInBoolSeq[a, arbNo.bits, 0, 3];
arbNo.bits[3] ← TRUE; -- hybrid select in decoded form
FOR d: Devices
IN Devices
DO
pl: ARRAY DevReqType OF DevPortParams;
FOR drt: DevReqType
IN DevReqType
DO
pl[drt].priority ← HoldPriority;
WHILE pl[drt].priority = HoldPriority
DO
pl[drt].priority ← rs.ChooseInt[0, 6];
ENDLOOP;
pl[drt].length ← (IF rs.ChooseInt[0, 1] > 0 THEN long5 ELSE short2);
ENDLOOP; -- drt
IF pl[H].priority > pl[L].priority
THEN {
-- reverse them
t: DevPortParams ← pl[H];
pl[H] ← pl[L];
pl[L] ← t;
};
pra[d] ← (
IF rs.ChooseInt[0, 1] > 0
-- memory port
THEN (34*CodeDPP[[priority: pl[H].priority, length: long5]])
ELSE (32*CodeDPP[pl[H]]+2*CodeDPP[pl[L]]+1));
InsertCardInBoolSeq[pra[d], dPriority.bits, 9*d, 9];
reqDevCT[a][d] ← Arbiter.ArbRandReq[pra[d], $FullARR];
inst ← CoreCreate.InstanceList[
type: reqDevCT[a][d],
pas:
LIST [
[public: "nRequestOut", actual: CoreOps.FindWire[publics, "nRequestOuts"][a][d]],
[public: "nGrant", actual: CoreOps.FindWire[publics, "nGrants"][a][d]],
[public: "nHiPGrant", actual: CoreOps.FindWire[publics, "nHiPGrants"][a]],
[public: "nLongGrant", actual: CoreOps.FindWire[publics, "nLongGrants"][a]],
[public: "nOwnerOut", actual: CoreOps.FindWire[publics, "nOwnerOuts"][a]],
[public: "nOwnerIn", actual: CoreOps.FindWire[publics, "nOwnerIns"][a]],
[public: "nSharedOut", actual: CoreOps.FindWire[publics, "nSharedOuts"][a][d]],
[public: "nSharedIn", actual: CoreOps.FindWire[publics, "nSharedIns"][a]],
[public: "nSStopOut", actual: CoreOps.FindWire[publics, "nSStopOuts"][a][d]],
[public: "nSStopIn", actual: CoreOps.FindWire[publics, "nSStopIns"][a]],
[public: "nDReset", actual: CoreOps.FindWire[publics, "DBus"][nDReset]]
],
name: IO.PutFR["Arb%dReq%d", IO.int[a], IO.int[d]] ];
instances ← CONS[inst, instances];
ENDLOOP; -- d
arbCT[a] ← (
IF a=0
AND useSchematic
THEN SchematicCT[cellName: "ArbiterSch", designName: "Arbiter25"]
.. this needs parametrizing
ELSE Arbiter.ArbInFrameCT[a, pra]);
pas ←
LIST[
[public: "nRequestOut", actual: CoreOps.FindWire[publics, "nRequestOuts"][a]],
[public: "nGrant", actual: CoreOps.FindWire[publics, "nGrants"][a]],
[public: "nHiPGrant", actual: CoreOps.FindWire[publics, "nHiPGrants"][a]],
[public: "nLongGrant", actual: CoreOps.FindWire[publics, "nLongGrants"][a]],
[public: "ArbReqOut", actual: CoreOps.FindWire[publics, "ArbReqs"][a]],
[public: "nBusyOut", actual: CoreOps.FindWire[publics, "nBusyOuts"][a]],
[public: "nBusyIn", actual: "nBusyIn"],
[public: "ArbRovers6", actual: CoreOps.FindWire[publics, "ArbRovers6s"][a]],
[public: "nOwnerOut", actual: CoreOps.FindWire[publics, "nOwnerOuts"][a]],
[public: "nBOwnerOut", actual: CoreOps.FindWire[publics, "nBOwnerOuts"][a]],
[public: "nBOwnerIn", actual: "nBOwnerIn"],
[public: "nOwnerIn", actual: CoreOps.FindWire[publics, "nOwnerIns"][a]],
[public: "nSharedOut", actual: CoreOps.FindWire[publics, "nSharedOuts"][a]],
[public: "nBSharedOut", actual: CoreOps.FindWire[publics, "nBShareds"][a]],
[public: "nBSharedIn", actual: "nBSharedBufs"],
[public: "nSharedIn", actual: CoreOps.FindWire[publics, "nSharedIns"][a]],
[public: "nSStopOut", actual: CoreOps.FindWire[publics, "nSStopOuts"][a]],
[public: "nBSStopOut", actual: CoreOps.FindWire[publics, "nBSStops"][a]],
[public: "nBSStopIn", actual: "nBSStopBufs"],
[public: "nSStopIn", actual: CoreOps.FindWire[publics, "nSStopIns"][a]],
[public: "Clock", actual: "Ck"],
[public: "CKOut", actual: CoreOps.FindWire[publics, "CKOuts"][a]],
[public: "DBdSel", actual: CoreOps.FindWire[publics, "DBdSels"][a]],
[public: "nDHybridSel", actual: CoreOps.FindWire[publics, "nDHybridSels"][a]],
[public: "BdVersion", actual: CoreOps.FindWire[publics, "BdVersions"][a]],
[public: "SlotNo", actual: CoreOps.FindWire[publics, "SlotNos"][a]]
];
The following code interconnects the ArbReq bus. Arbiter x has its rover pointers initialized to x during reset, so our interconnection must be consistent with that. Assume that Arbiter x's ArbReqOut wire is connected to ArbReqs[x]. Then Arbiter 0's public ArbReqIn[0] wire should be connected to ArbReqs[7], its public ArbReqIn[1] wire to ArbReqs[6], and so on. Likewise Arbiter 1's public ArbReqIn[0] wire should be connected to ArbReqs[0], its public ArbReqIn[1] wire to ArbReqs[7], and so on. In general Arbiter a's public ArbReqIn[oa] wire should be connected to ArbReqs[(a-1-oa) MOD maxArbiters].
FOR oa: OtherArbiters
IN OtherArbiters
DO
FOR j:
NAT
IN [0..3)
DO
pas ←
CONS[[
public: (
IF (a=0
AND useSchematic)
THEN (CoreOps.FindWire[arbCT[a].public, "OtherArbInT"][j][oa])
ELSE (CoreOps.FindWire[arbCT[a].public, "OtherArbIn"][oa][j])),
actual: CoreOps.FindWire[publics, "ArbReqs"]
[(a-1-oa+2*maxArbiters) MOD maxArbiters][j]
], pas];
ENDLOOP; -- j
ENDLOOP; -- oa
IF (a=0 AND useSchematic) THEN {
pas ← CONS[[public: "Gnd2VTop", actual: "Gnd2V"], pas];
pas ← CONS[[public: "Gnd2VLeft", actual: "Gnd2V"], pas]};
inst ← CoreCreate.InstanceList[
type: arbCT[a],
pas: pas,
name: IO.PutFR["Arb%d", IO.int[a]] ];
instances ← CONS[inst, instances];
inst ← CoreCreate.InstanceList[
type: buf,
pas:
LIST [
[public: "I", actual: CoreOps.FindWire[publics, "nBShareds"][a]],
[public: "X", actual: CoreOps.FindWire[publics, "nBSharedBufs"][a]]
],
name: IO.PutFR["SharedBuf%d", IO.int[a]] ];
instances ← CONS[inst, instances];
inst ← CoreCreate.InstanceList[
type: buf,
pas:
LIST [
[public: "I", actual: CoreOps.FindWire[publics, "nBSStops"][a]],
[public: "X", actual: CoreOps.FindWire[publics, "nBSStopBufs"][a]]
],
name: IO.PutFR["SStopBuf%d", IO.int[a]] ];
instances ← CONS[inst, instances];
FOR i:
NAT
IN [0..2)
DO
inst ← CoreCreate.InstanceList[
type: buf,
pas:
LIST [
[public: "I", actual: CoreOps.FindWire[publics, "nDHybridSels"][a][i]],
[public: "X", actual: CoreOps.FindWire[publics, "BdVersions"][a][i]]
],
name: IO.PutFR["BdVersBuf%d-%d", IO.int[i], IO.int[a]] ];
instances ← CONS[inst, instances];
ENDLOOP;
IF useDBus
OR (a=0
AND useSchematic)
THEN
dBusInits ← CONS[NEW[Arbiter.DBusInitItem ← arbNo], CONS[NEW[Arbiter.DBusInitItem ← dPriority], dBusInits]];
inst ← CoreCreate.InstanceList[
type: Logic.And[maxArbiters],
pas:
LIST [
[public: "I", actual: "nBOwnerOuts"],
[public: "X", actual: "nBOwnerIn"]
],
name: "OwnerAnd"];
instances ←
CONS[inst, instances];
inst ← CoreCreate.InstanceList[
type: Logic.And[maxArbiters+1],
pas:
LIST [
[public: "I", actual: "nBusyOuts"],
[public: "X", actual: "nBusyIn"]
],
name: "BusyAnd"];
instances ←
CONS[inst, instances];
inst ← CoreCreate.InstanceList[
type: CreateSanity[],
pas:
LIST [
[public: "nDReset", actual: CoreOps.FindWire[publics, "DBus"][nDReset]]],
name: "San"];
instances ← CONS[inst, instances];
arbSys ← CoreCreate.Cell[public: publics, onlyInternal:
NIL, instances: instances,
name: "ArbSys" ];
FOR a: Arbiters
IN Arbiters
DO
[] ← Ports.InitPort[CoreOps.FindWire[arbSys.public, "SlotNos"][a], c];
[] ← Ports.InitTesterDrive[CoreOps.FindWire[arbSys.public, "SlotNos"][a], force];
[] ← Ports.InitPort[CoreOps.FindWire[arbSys.public, "nDHybridSels"][a], c];
ENDLOOP; -- a
port ← CoreOps.GetWireIndex[arbSys.public, "DBus"];
FOR i:
NAT
IN (DSerialOut..DShiftCK]
DO
Ports.InitTesterDrive[arbSys.public[port][i], force];
ENDLOOP; -- i
Ports.InitTesterDrives[arbSys, force, "Ck"];
[] ← Rosemary.SetFixedWire[CoreOps.FindWire[arbSys.public, "Vdd"], H];
[] ← Rosemary.SetFixedWire[CoreOps.FindWire[arbSys.public, "Gnd"], L];
[] ← Rosemary.SetFixedWire[CoreOps.FindWire[arbSys.public, "Gnd2V"], L];
CoreProperties.PutCellTypeProp[arbSys, $DUT, arb0Path];
CoreProperties.PutCellTypeProp[arbSys, $Tests, systemTests];
tester ← RosemaryUser.TestProcedureViewer[cellType: arbSys,
testButtons: systemTests,
name: "Arbiter System Test",
displayWires:
LIST[
NEW[CoreFlat.FlatWireRec ← CoreFlat.ParseWirePath[arbSys, "Ck"]],
NEW[CoreFlat.FlatWireRec ← CoreFlat.ParseWirePath[arbSys, "DBus"]],
NEW[CoreFlat.FlatWireRec ← CoreFlat.ParseWirePath[arbSys, "ArbReqs"]],
NEW[CoreFlat.FlatWireRec ← CoreFlat.ParseWirePath[arbSys, "nLongGrants"]],
NEW[CoreFlat.FlatWireRec ← CoreFlat.ParseWirePath[arbSys, "nHiPGrants"]],
NEW[CoreFlat.FlatWireRec ← CoreFlat.ParseWirePath[arbSys, "nStartGrant"]],
NEW[CoreFlat.FlatWireRec ← CoreFlat.ParseWirePath[arbSys, "nGrants"]],
NEW[CoreFlat.FlatWireRec ← CoreFlat.ParseWirePath[arbSys, "nBusyIn"]],
NEW[CoreFlat.FlatWireRec ← CoreFlat.ParseWirePath[arbSys, "nDynaBusBusy"]],
NEW[CoreFlat.FlatWireRec ← CoreFlat.ParseWirePath[arbSys, "nHolding"]]
],
cutSet: cutSet ];