ArbSimImpl.mesa
Copyright c 1986 by Xerox Corporation. All rights reserved.
Barth, April 4, 1987 10:21:15 am PST
Last Edited by: McCreight September 27, 1988 3:11:01 pm PDT
Jean-Marc Frailong October 4, 1988 11:43:41 am PDT
Don Curry September 7, 1988 11:15:02 am PDT
DIRECTORY
Arbiter, Basics, Commander, CommandTool, Core, CoreCreate, CoreFlat, CoreOps, CoreProperties, IO, Logic, Ports, Rope, Random, Rosemary, RosemaryUser;
ArbSimImpl: CEDAR PROGRAM
IMPORTS Arbiter, Basics, Commander, CommandTool, CoreCreate, CoreFlat, CoreOps, CoreProperties, IO, Logic, Ports, Random, Rope, Rosemary, RosemaryUser
=
BEGIN OPEN CoreCreate, Arbiter;
BEGIN OPEN Arbiter;
arbSys:  Core.CellType ← NIL;
tester:   RosemaryUser.Tester ← NIL;
rs:    Random.RandomStream ← Random.Create[-1, 12345];
CreateArbSysCellType: PROC[useSchematic: BOOLFALSE, useDBus: BOOLFALSE, 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.PANIL;
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]];
ENDLOOP; -- a
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 ];
AddArbSysProp[$DBusInits, dBusInits];
AddArbSysProp[$Tester, tester]};
DoArbiterSim: PROC [cmd: Commander.Handle]
RETURNS [result: REFNIL, msg: IO.ROPENIL] -- Commander.CommandProc -- = {
useSchematic: BOOLFALSE;
useDBus:   BOOLFALSE;
cutSet:   CoreFlat.CutSet ← Logic.fast;
argv:    CommandTool.ArgumentVector = CommandTool.Parse[cmd];
startTest:   IO.ROPENIL;
FOR i: NAT IN [1..argv.argc) DO
SELECT Rope.Fetch[argv[i], 0] FROM
'+, '- =>
FOR j: INT IN [1..Rope.Length[argv[i]]) DO
SELECT Rope.Fetch[argv[i], j] FROM
's, 'S => {useSchematic ← TRUE};
'd, 'D => {useDBus   ← TRUE};
't, 'T => {cutSet   ← Logic.gate; useSchematic ← TRUE};
ENDCASE ENDLOOP;
ENDCASE => startTest ← argv[i];
ENDLOOP;
CreateArbSysCellType[useSchematic, useDBus, cutSet, startTest];
IF startTest#NIL THEN RosemaryUser.StartTest[tester]};
Commander.Register["ArbiterSim", DoArbiterSim, "Set up a simulation of 8 arbiters, each receiving random requests from 8 requesters. +s => use one schematic arbiter, +d => use the DBus to initialize the arbiters."];
END.