<> <> DIRECTORY IO, NumTypes, Random, Rope, RoseClocks, RoseCreate, RoseRun, RoseReadSim, RoseTypes, SwitchTypes; RoseTestB: CEDAR PROGRAM IMPORTS IO, NumTypes, Random, Rope, RoseClocks, RoseCreate, RoseRun, RoseReadSim, RoseTypes, SwitchTypes = BEGIN OPEN RoseCreate, RoseRun, RoseTypes; DataBits: CARDINAL = 8; AddressBits: CARDINAL = 2; MemLength: CARDINAL = TwoToThe[AddressBits]; CmdBits: CARDINAL = 2; BusWidth: CARDINAL = DataBits + AddressBits + CmdBits; Modules: CARDINAL = 3; Clients: CARDINAL = 16; ClientIndex: TYPE = [0 .. Clients); BusIO: TYPE = REF BusIORep; BusIORep: TYPE = RECORD [ data: PACKED ARRAY [0 .. DataBits) OF SwitchTypes.SwitchVal, address: PACKED ARRAY [0 .. AddressBits) OF SwitchTypes.SwitchVal, cmd: PACKED ARRAY [0 .. CmdBits) OF SwitchTypes.SwitchVal]; CreateBusIO: PROC [ct: CellType] RETURNS [ioAsAny: REF ANY] --IOCreator-- = BEGIN ioAsAny _ NEW [BusIORep]; END; MemState: TYPE = REF MemStateRep; MemStateRep: TYPE = RECORD [ mem: ARRAY [0 .. MemLength) OF ARRAY [0 .. DataBits) OF BOOL, a: [0 .. MemLength), read, write: BOOLEAN]; InitializeMemory: PROCEDURE [cell: Cell, leafily: BOOLEAN] --Initializer-- = BEGIN IF leafily THEN BEGIN ms: MemState _ NEW [MemStateRep _ [ mem: ALL[ALL[FALSE]], a: Random.Choose[0, MemLength-1], read: FALSE, write: FALSE]]; FOR row: CARDINAL IN [0 .. MemLength) DO FOR col: CARDINAL IN [0 .. DataBits) DO ms.mem[row][col] _ Random.Choose[0, 1] > 0; ENDLOOP; ENDLOOP; cell.realCellStuff.state _ ms; END; END; MemValsChanged: CellProc --PROC [cell: Cell]-- = BEGIN ms: MemState _ NARROW[cell.realCellStuff.state]; io: BusIO _ NARROW[cell.realCellStuff.switchIO]; BEGIN OPEN ms, io; wasReading: BOOLEAN _ read; oldAddr: [0 .. MemLength) _ a; TRUSTED {a _ StrictInt[DESCRIPTOR[address]]}; read _ NOT StrictBit[cmd[0]]; write _ NOT StrictBit[cmd[1]]; IF write THEN FOR col: CARDINAL IN [0 .. DataBits) DO mem[a][col] _ StrictBit[data[col]]; ENDLOOP; IF (read # wasReading) OR (read AND a # oldAddr) THEN PerturbPort[cell, 0]; END; END; MemPropQ: CellProc --PROC [cell: Cell]-- = BEGIN ms: MemState _ NARROW[cell.realCellStuff.state]; io: BusIO _ NARROW[cell.realCellStuff.switchIO]; BEGIN OPEN ms, io; IF read THEN FOR col: CARDINAL IN [0 .. DataBits) DO data[col].s[q] _ IF mem[a][col] THEN none ELSE drive; ENDLOOP; END; END; MemPropUD: CellProc --PROC [cell: Cell]-- = BEGIN ms: MemState _ NARROW[cell.realCellStuff.state]; io: BusIO _ NARROW[cell.realCellStuff.switchIO]; BEGIN OPEN ms, io; IF read THEN FOR col: CARDINAL IN [0 .. DataBits) DO data[col].s[d] _ IF mem[a][col] THEN none ELSE drive; ENDLOOP; END; END; ModuleIO: TYPE = REF ModuleIORep; ModuleIORep: TYPE = MACHINE DEPENDENT RECORD [ fill0(0:0..14): [0..32768), PhA(0:15..15): BOOLEAN, fill1(1:0..14): [0 .. 32768), PhB(1:15..15): BOOLEAN, fill2(2:0..14): [0 .. 32768), RqBar(2:15..15): BOOLEAN, fill3(3:0..14): [0 .. 32768), GrBar(3:15..15): BOOLEAN, Bus(4:0..SIZE[BusIORep]*16-1): BusIORep]; CreateModIO: PROC [ct: CellType] RETURNS [ioAsAny: REF ANY] --IOCreator-- = BEGIN ioAsAny _ NEW [ModuleIORep]; END; ModuleState: TYPE = REF ModuleStateRep; ModuleStateRep: TYPE = RECORD [ data, latched: [0 .. TwoToThe[DataBits]) _ 0, addr: [0 .. TwoToThe[AddressBits]) _ 0, read, write, dun: BOOLEAN _ FALSE]; InitializeMod: Initializer--PROCEDURE [cell: Cell, initData: REF ANY, leafily: BOOLEAN]-- = BEGIN IF leafily THEN cell.realCellStuff.state _ NEW [ModuleStateRep _ []]; END; ModSimple: CellProc--PROC [cell: Cell]-- = BEGIN ms: ModuleState _ NARROW[cell.realCellStuff.state]; newIO: ModuleIO _ NARROW[cell.realCellStuff.newIO]; oldIO: ModuleIO _ NARROW[cell.realCellStuff.oldIO]; BEGIN OPEN ms, newIO; IF PhB THEN dun _ GrBar = RqBar; IF dun AND PhA THEN BEGIN data _ Random.Choose[0, TwoToThe[DataBits]-1]; addr _ Random.Choose[0, TwoToThe[AddressBits]-1]; SELECT Random.Choose[1, 4] FROM 1 => write _ NOT (read _ TRUE); 2 => read _ NOT (write _ TRUE); 3, 4 => read _ write _ FALSE; ENDCASE => ERROR; RqBar _ NOT (read OR write); dun _ FALSE; END; IF PhB AND NOT GrBar THEN PerturbPort[cell, 4]; END; END; ModValsChanged: CellProc--PROC [cell: Cell]-- = BEGIN ms: ModuleState _ NARROW[cell.realCellStuff.state]; io: ModuleIO _ NARROW[cell.realCellStuff.switchIO]; BEGIN OPEN ms, io; IF dun THEN TRUSTED {latched _ StrictInt[DESCRIPTOR[Bus.data]]}; END; END; ModPropQ: CellProc--PROC [cell: Cell]-- = BEGIN ms: ModuleState _ NARROW[cell.realCellStuff.state]; io: ModuleIO _ NARROW[cell.realCellStuff.switchIO]; BEGIN OPEN ms, io; IF PhB AND NOT GrBar THEN TRUSTED BEGIN StrengthsFromInt[addr, [drive, none], DESCRIPTOR[Bus.address], q]; StrengthsFromInt[EncodeCmd[read, write], [none, drive], DESCRIPTOR[Bus.cmd], q]; IF write THEN StrengthsFromInt[data, [drive, none], DESCRIPTOR[Bus.data], q]; END; END; END; ModPropUD: CellProc--PROC [cell: Cell]-- = BEGIN ms: ModuleState _ NARROW[cell.realCellStuff.state]; io: ModuleIO _ NARROW[cell.realCellStuff.switchIO]; BEGIN OPEN ms, io; IF PhB AND NOT GrBar THEN TRUSTED BEGIN StrengthsFromInt[addr, [drive, none], DESCRIPTOR[Bus.address], d]; StrengthsFromInt[EncodeCmd[read, write], [none, drive], DESCRIPTOR[Bus.cmd], d]; IF write THEN StrengthsFromInt[data, [drive, none], DESCRIPTOR[Bus.data], d]; END; END; END; EncodeCmd: PROC [read, write: BOOLEAN] RETURNS [enc: [0..2]] = {enc _ IF read THEN 2 ELSE IF write THEN 1 ELSE 0}; ArbIO: TYPE = REF ArbIORep; ArbIORep: TYPE = MACHINE DEPENDENT RECORD [ fill0(0:0..14): [0 .. 32768), PhA(0:15..15): BOOLEAN, fill1(1:0..14): [0 .. 32768), PhB(1:15..15): BOOLEAN, fill2(2:0..14): [0 .. 32768), NewRqBar(2:15..15): BOOLEAN, clients(3:0..511): ARRAY ClientIndex OF Client]; Client: TYPE = MACHINE DEPENDENT RECORD [ fill0(0:0..14): [0 .. 32768), RqBar(0:15..15): BOOLEAN, fill1(1:0..14): [0 .. 32768), GnBar(1:15..15): BOOLEAN]; CreateArbIO: PROC [ct: CellType] RETURNS [ioAsAny: REF ANY] --IOCreator-- = BEGIN ioAsAny _ NEW [ArbIORep]; END; ArbState: TYPE = REF ArbStateRep; ArbStateRep: TYPE = RECORD [ startAt: ClientIndex _ 0, hasGrant: [0 .. Clients] _ Clients]; InitializeArb: Initializer--PROC [cell: Cell, initData: REF ANY, leafily: BOOLEAN]-- = BEGIN IF leafily THEN cell.realCellStuff.state _ NEW [ArbStateRep _ []]; END; ArbSimple: CellProc--PROC [cell: Cell]-- = BEGIN as: ArbState _ NARROW[cell.realCellStuff.state]; newIO: ArbIO _ NARROW[cell.realCellStuff.newIO]; oldIO: ArbIO _ NARROW[cell.realCellStuff.oldIO]; BEGIN OPEN as, newIO; AnyRq: PROC RETURNS [any: BOOLEAN] = {FOR client: ClientIndex IN ClientIndex DO IF NOT clients[client].RqBar THEN RETURN [TRUE]; ENDLOOP; any _ FALSE}; IF PhA THEN FOR client: ClientIndex IN ClientIndex DO clients[client].GnBar _ client # hasGrant; ENDLOOP; IF PhB THEN IF (NOT NewRqBar) OR (IF hasGrant < Clients THEN clients[hasGrant].RqBar ELSE AnyRq[]) THEN BEGIN hasGrant _ Clients; FOR offset: ClientIndex IN ClientIndex DO client: ClientIndex _ (offset + startAt) MOD Clients; IF NOT clients[client].RqBar THEN {hasGrant _ client; startAt _ (hasGrant+1) MOD Clients; EXIT}; ENDLOOP; END; END; END; ExpandArb: PROCEDURE [thisCell: Cell, to: ExpansionReceiver] --ExpandProc-- = BEGIN RoseReadSim.ReadSim[to: to, within: thisCell, fileName: "PassArb.sim"]; END; ExpandTestB: PROCEDURE [thisCell: Cell, to: ExpansionReceiver]--ExpandProc-- = BEGIN bits: StretchList _ NIL; Vdd: Node _ to.class.NodeInstance[to.instance, "Vdd", SwitchTypes.bitType, "H", NIL, SwitchTypes.refInput]; Gnd: Node _ to.class.NodeInstance[to.instance, "Gnd", SwitchTypes.bitType, "L", NIL, SwitchTypes.refInput]; Bus: Node _ to.class.NodeInstance[to.instance, "Bus", SwitchTypes.Bundle[BusWidth], DupRope["H", BusWidth]]; BusElts: ARRAY [0 .. BusWidth) OF Node _ ALL[NIL]; PhA: Node _ to.class.NodeInstance[to.instance, "PhA", NumTypes.boolType]; PhAs: Node _ to.class.NodeInstance[to.instance, "PhAs", SwitchTypes.bitType]; PhB: Node _ to.class.NodeInstance[to.instance, "PhB", NumTypes.boolType]; Requests, Grants: ARRAY ClientIndex OF Node; NewRqBar: Node _ to.class.NodeInstance[to.instance, "NEWRQ'", NumTypes.boolType, "TRUE"]; ClockGen: Cell _ to.class.CellInstance[to.instance, "Clock Generator", RoseClocks.ClockGen[[]].name, "PhA, PhB"]; to.class.ChangeReps[to.instance, PhA, PhAs, FALSE, TRUE]; FOR i: CARDINAL IN [0 .. BusWidth) DO BusElts[i] _ to.class.NodeInstance[to.instance, IO.PutFR["Bus[%g]", IO.card[i]], SwitchTypes.bitType, "H"]; [] _ to.class.CellInstance[ erInstance: to.instance, instanceName: IO.PutFR["Bus Precharger %g", IO.card[i]], typeName: "PassTrans", interfaceNodes: IO.PutFR["PhAs, Vdd, Bus[%g]", IO.card[i]]]; ENDLOOP; FOR client: ClientIndex IN ClientIndex DO Requests[client] _ to.class.NodeInstance[to.instance, IO.PutFR["RQ%02g'", IO.card[client]], NumTypes.boolType, "TRUE"]; Grants[client] _ to.class.NodeInstance[to.instance, IO.PutFR["GN%02g'", IO.card[client]], NumTypes.boolType, "TRUE"]; ENDLOOP; [] _ to.class.CellInstance[to.instance, "Arbiter", "Arbiter", "PHASEA: PhA, PHASEB: PhB"]; FOR i: CARDINAL IN [0 .. Modules) DO Mod: Cell _ to.class.CellInstance[ erInstance: to.instance, instanceName: IO.PutFR["Module %g", IO.card[i]], typeName: "Module", interfaceNodes: IO.PutFR["Rq': RQ%02g', Gr': GN%02g'", IO.card[i], IO.card[i]]]; ENDLOOP; [] _ to.class.CellInstance[to.instance, "Memory", "Memory", ""]; FOR i: CARDINAL DECREASING IN [0 .. BusWidth) DO bits _ CONS[Single[BusElts[i]], bits]; ENDLOOP; to.class.SplitJoin[erInstance: to.instance, a: LIST[Sub[Bus]], b: bits, writeA: TRUE, writeB: FALSE]; END; DupRope: PROC [basic: ROPE, times: INT] RETURNS [duped: ROPE] = BEGIN duped _ NIL; THROUGH [0 .. times) DO duped _ duped.Concat[basic] ENDLOOP; END; StrictBit: PROC [sv: SwitchTypes.SwitchVal] RETURNS [bit: BOOLEAN] = {bit _ SELECT sv.val FROM L => FALSE, X => ERROR, H => TRUE, ENDCASE => ERROR}; StrictInt: PROC [svs: LONG DESCRIPTOR FOR PACKED ARRAY OF SwitchTypes.SwitchVal] RETURNS [int: INT] = BEGIN Position: PROC [bit: [1 .. 32]] RETURNS [pos: [0 .. 32)] = {pos _ (IF bit < 17 THEN 16 ELSE 32) - bit}; asBits: PACKED ARRAY [0 .. 32) OF BOOLEAN _ ALL[FALSE]; length: CARDINAL _ LENGTH[svs]; FOR bit: INT IN [1 .. length] DO TRUSTED {asBits[Position[bit]] _ StrictBit[svs[length-bit]]}; ENDLOOP; int _ LOOPHOLE[asBits]; END; StrengthsFromInt: PROC [i: INT, sa: ARRAY BOOLEAN OF SwitchTypes.Strength, to: LONG DESCRIPTOR FOR PACKED ARRAY OF SwitchTypes.SwitchVal, si: SwitchTypes.StrengthIndex] = BEGIN length: CARDINAL _ LENGTH[to]; FOR bit: CARDINAL IN [1 .. length] DO TRUSTED {to[length-bit].s[si] _ sa[(i MOD 2) # 0]}; i _ i / 2; ENDLOOP; IF i # 0 THEN ERROR; END; Setup: PROC = BEGIN memPorts: Ports _ NEW [PortsRep[1]]; modPorts: Ports _ NEW [PortsRep[5]]; arbPorts: Ports _ NEW [PortsRep[35]]; [] _ Random.Init[seed: -1]; memPorts[0] _ [0, SIZE[BusIORep], "Bus", SwitchTypes.Bundle[BusWidth], TRUE, TRUE, TRUE]; [] _ RegisterCellType[ name: "Memory", ioCreator: CreateBusIO, initializer: InitializeMemory, evals: [ValsChanged: MemValsChanged, PropQ: MemPropQ, PropUD: MemPropUD], ports: memPorts]; modPorts[0] _ [0, 1, "PhA", NumTypes.boolType, TRUE]; modPorts[1] _ [1, 1, "PhB", NumTypes.boolType, TRUE]; modPorts[2] _ [2, 1, "Rq'", NumTypes.boolType, FALSE, TRUE]; modPorts[3] _ [3, 1, "Gr'", NumTypes.boolType, TRUE]; modPorts[4] _ [4, SIZE[BusIORep], "Bus", SwitchTypes.Bundle[BusWidth], TRUE, TRUE, TRUE]; [] _ RegisterCellType[ name: "Module", ioCreator: CreateModIO, initializer: InitializeMod, evals: [EvalSimple: ModSimple, ValsChanged: ModValsChanged, PropQ: ModPropQ, PropUD: ModPropUD], ports: modPorts]; arbPorts[0] _ [0, 1, "PHASEA", NumTypes.boolType, TRUE]; arbPorts[1] _ [1, 1, "PHASEB", NumTypes.boolType, TRUE]; arbPorts[2] _ [2, 1, "NEWRQ'", NumTypes.boolType, TRUE]; FOR client: ClientIndex IN ClientIndex DO arbPorts[3+2*client] _ [3+2*client, 1, IO.PutFR["RQ%02g'", IO.card[client]], NumTypes.boolType, TRUE]; arbPorts[4+2*client] _ [4+2*client, 1, IO.PutFR["GN%02g'", IO.card[client]], NumTypes.boolType, FALSE, TRUE]; ENDLOOP; [] _ RegisterCellType[ name: "Arbiter", ioCreator: CreateArbIO, expandProc: ExpandArb, initializer: InitializeArb, evals: [EvalSimple: ArbSimple], ports: arbPorts]; [] _ RegisterCellType[ name: "TestB", expandProc: ExpandTestB, evals: [], ports: NEW [PortsRep[0]]]; END; Setup[]; END.