RoseTestB.Mesa
Last Edited by: Spreitzer, January 23, 1985 11:13:25 pm PST
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: BOOLEANFALSE];
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 BOOLEANALL[FALSE];
length: CARDINALLENGTH[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: CARDINALLENGTH[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.