RoseTestB.Mesa
Last Edited by: Spreitzer, March 19, 1984 1:57:53 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: IOCreator
--PROC [cell: Cell, initData: REF ANY]-- =
BEGIN
cell.realCellStuff.switchIO ← NEW [BusIORep];
cell.realCellStuff.newIO ← NEW [BusIORep];
cell.realCellStuff.oldIO ← 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: Initializer
--PROCEDURE [cell: Cell, initData: REF ANY, leafily: BOOLEAN]-- =
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: IOCreator
--PROC [cell: Cell, initData: REF ANY]-- =
BEGIN
cell.realCellStuff.switchIO ← NEW [ModuleIORep];
cell.realCellStuff.newIO ← NEW [ModuleIORep];
cell.realCellStuff.oldIO ← 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: IOCreator
--PROC [cell: Cell, initData: REF ANY]-- =
BEGIN
cell.realCellStuff.switchIO ← NEW [ArbIORep];
cell.realCellStuff.newIO ← NEW [ArbIORep];
cell.realCellStuff.oldIO ← 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: ExpandProc
--PROCEDURE [thisCell: Cell, initData: REF ANY]-- =
BEGIN
RoseReadSim.ReadSim[within: thisCell, fileName: "PassArb.sim"];
END;
ExpandTestB: ExpandProc
--PROCEDURE [thisCell: Cell, initData: REF ANY]-- =
BEGIN
bits: StretchList ← NIL;
Vdd: Node ← CreateNode[thisCell, "Vdd", SwitchTypes.bitType, "H", SwitchTypes.refInput];
Gnd: Node ← CreateNode[thisCell, "Gnd", SwitchTypes.bitType, "L", SwitchTypes.refInput];
Bus: Node ← CreateNode[thisCell, "Bus", SwitchTypes.Bundle[BusWidth], DupRope["H", BusWidth]];
BusElts: ARRAY [0 .. BusWidth) OF Node ← ALL[NIL];
PhA: Node ← CreateNode[thisCell, "PhA", NumTypes.boolType];
PhAs: Node ← CreateNode[thisCell, "PhAs", SwitchTypes.bitType];
PhB: Node ← CreateNode[thisCell, "PhB", NumTypes.boolType];
Requests, Grants: ARRAY ClientIndex OF Node;
NewRqBar: Node ← CreateNode[thisCell, "NEWRQ'", NumTypes.boolType, "TRUE"];
ClockGen: Cell ← CreateCell[thisCell, "Clock Generator", "ClockGen", "PhA, PhB", RoseClocks.Init[style: FourStep]];
ChangeReps[thisCell, PhA, PhAs, FALSE, TRUE];
FOR i:
CARDINAL
IN [0 .. BusWidth)
DO
BusElts[i] ← CreateNode[thisCell, IO.PutFR["Bus[%g]", IO.card[i]], SwitchTypes.bitType, "H"];
[] ← CreateCell[
within: thisCell,
instanceName: IO.PutFR["Bus Precharger %g", IO.card[i]],
className: "PassTrans",
interfaceNodes: IO.PutFR["PhAs, Vdd, Bus[%g]", IO.card[i]]];
ENDLOOP;
FOR client: ClientIndex
IN ClientIndex
DO
Requests[client] ← CreateNode[thisCell, IO.PutFR["RQ%02g'", IO.card[client]], NumTypes.boolType, "TRUE"];
Grants[client] ← CreateNode[thisCell, IO.PutFR["GN%02g'", IO.card[client]], NumTypes.boolType, "TRUE"];
ENDLOOP;
[] ← CreateCell[thisCell, "Arbiter", "Arbiter", "PHASEA: PhA, PHASEB: PhB"];
FOR i:
CARDINAL
IN [0 .. Modules)
DO
Mod: Cell ← CreateCell[
within: thisCell,
instanceName: IO.PutFR["Module %g", IO.card[i]],
className: "Module",
interfaceNodes: IO.PutFR["Rq': RQ%02g', Gr': GN%02g'", IO.card[i], IO.card[i]]];
ENDLOOP;
[] ← CreateCell[thisCell, "Memory", "Memory", ""];
FOR i:
CARDINAL
DECREASING
IN [0 .. BusWidth)
DO
bits ← CONS[Single[BusElts[i]], bits];
ENDLOOP;
SplitJoin[within: thisCell, 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];
[] ← RegisterCellClass[
className: "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];
[] ← RegisterCellClass[
className: "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;
[] ← RegisterCellClass[
className: "Arbiter",
ioCreator: CreateArbIO,
expandProc: ExpandArb,
initializer: InitializeArb,
evals: [EvalSimple: ArbSimple],
ports: arbPorts];
[] ← RegisterCellClass[
className: "TestB",
expandProc: ExpandTestB,
evals: [],
ports: NEW [PortsRep[0]]];
END;
Setup[];
END.