MemoryExample.OrgMesa
Last Edited by: Spreitzer, February 14, 1984 8:24 pm
DIRECTORY BitOps, IO, NumTypes, Rope, RoseCreate, RoseRun, RoseTypes, SwitchTypes;
MemoryExample:
CEDAR
PROGRAM
IMPORTS BitOps, IO, NumTypes, RoseCreate, RoseRun, SwitchTypes =
BEGIN OPEN RoseCreate, RoseRun, RoseTypes;
WordCount: CARDINAL = 4;
WordSize: CARDINAL = 4;
MemIO: TYPE = REF MemIORep;
MemIORep:
TYPE =
MACHINE
DEPENDENT
RECORD [
wordLines(0:0..127): ARRAY [0 .. WordCount) OF WordLine,
bitLines(8:0..63): ARRAY [0 .. WordSize) OF SwitchTypes.SwitchValHolder];
WordLine:
TYPE =
MACHINE
DEPENDENT
RECORD [
fill0(0:0..14): [0 .. 32768),
read(0:15..15): BOOL,
fill1(1:0..14): [0 .. 32768),
write(1:15..15): BOOL];
MemState: TYPE = REF MemStateRep;
MemStateRep:
TYPE =
RECORD [
words: ARRAY [0 .. WordCount) OF Word,
lastRead: ARRAY [0 .. WordCount) OF BOOL];
Word: TYPE = PACKED ARRAY [0 .. WordSize) OF BOOL;
MemPropQ: CellProc
--PROC [cell: Cell]-- =
BEGIN
io: MemIO ← NARROW[cell.realCellStuff.newIO];
state: MemState ←
NARROW[cell.realCellStuff.state];
{OPEN io, state;
FOR word:
CARDINAL
IN [0 .. WordCount)
DO
IF wordLines[word].read
THEN
FOR bit:
CARDINAL
IN [0 .. WordSize)
DO
IF words[word][bit] THEN bitLines[bit].held.s[q] ← drive;
ENDLOOP;
ENDLOOP};
END;
MemPropUD: CellProc
--PROC [cell: Cell]-- =
BEGIN
io: MemIO ← NARROW[cell.realCellStuff.newIO];
state: MemState ←
NARROW[cell.realCellStuff.state];
{OPEN io, state;
FOR word:
CARDINAL
IN [0 .. WordCount)
DO
IF wordLines[word].read
THEN
FOR bit:
CARDINAL
IN [0 .. WordSize)
DO
IF words[word][bit] THEN bitLines[bit].held.s[d] ← drive;
ENDLOOP;
ENDLOOP};
END;
MemValsChanged: CellProc
--PROC [cell: Cell]-- =
BEGIN
io: MemIO ← NARROW[cell.realCellStuff.newIO];
state: MemState ←
NARROW[cell.realCellStuff.state];
{OPEN io, state;
FOR word:
CARDINAL
IN [0 .. WordCount)
DO
IF wordLines[word].write
THEN
FOR bit:
CARDINAL
IN [0 .. WordSize)
DO
words[word][bit] ← bitLines[bit].held.val = H;
ENDLOOP;
ENDLOOP};
END;
MemOther: CellProc
--PROC [cell: Cell]-- =
BEGIN
newIO: MemIO ← NARROW[cell.realCellStuff.newIO];
oldIO: MemIO ← NARROW[cell.realCellStuff.oldIO];
state: MemState ← NARROW[cell.realCellStuff.state];
oldIO^ ← newIO^;
{OPEN newIO, state;
readdif: BOOLEAN ← FALSE;
FOR word:
CARDINAL
IN [0 .. WordCount)
DO
IF wordLines[word].write
THEN
FOR bit:
CARDINAL
IN [0 .. WordSize)
DO
words[word][bit] ← bitLines[bit].held.val = H;
ENDLOOP;
readdif ← readdif OR wordLines[word].read # lastRead[word];
lastRead[word] ← wordLines[word].read;
ENDLOOP;
IF readdif
THEN
FOR bit:
CARDINAL
IN [0 .. WordSize)
DO
PerturbPort[cell, 2*WordCount + bit];
ENDLOOP};
END;
CreateMemIO: IOCreator
--PROC [cell: Cell, initData: REF ANY]-- = {
cell.realCellStuff.newIO ← NEW [MemIORep];
cell.realCellStuff.oldIO ← NEW [MemIORep]};
InitMem: Initializer
--PROCEDURE [cell: Cell, initData: REF ANY, leafily: BOOLEAN]-- =
BEGIN
IF leafily
THEN {
ms: MemState ← NEW [MemStateRep];
cell.realCellStuff.state ← ms;
FOR word: CARDINAL IN [0 .. WordCount) DO ms.lastRead[word] ← FALSE ENDLOOP};
END;
DriverIO: TYPE = REF DriverIORep;
DriverIORep:
TYPE =
MACHINE
DEPENDENT
RECORD [
bitLines(0:0..63): ARRAY [0 .. WordSize) OF SwitchTypes.SwitchValHolder,
fill1(4:0..11): [0 .. 4096),
asInt(4:12..15): [0 .. 16),
fill2(5:0..14): [0 .. 32768),
drive(5:15..15): BOOL];
DriverState: TYPE = REF DriverStateRep;
DriverStateRep:
TYPE =
RECORD [
wasDriven: BOOL,
lastDriven: [0 .. 16)];
CreateDriverIO: IOCreator
--PROC [cell: Cell, initData: REF ANY]-- = {
cell.realCellStuff.newIO ← NEW [DriverIORep];
cell.realCellStuff.oldIO ← NEW [DriverIORep]};
InitDriver: Initializer
--PROCEDURE [cell: Cell, initData: REF ANY, leafily: BOOLEAN]-- =
BEGIN
IF leafily THEN cell.realCellStuff.state ← NEW [DriverStateRep ← [FALSE, 0]];
END;
DriverPropQ: CellProc
--PROC [cell: Cell]-- =
BEGIN
io: DriverIO ←
NARROW[cell.realCellStuff.newIO];
{OPEN io;
IF drive
THEN
FOR bit:
CARDINAL
IN [0 .. WordSize)
DO
bitLines[bit].held.s[q] ← drive;
ENDLOOP};
END;
DriverPropUD: CellProc
--PROC [cell: Cell]-- =
BEGIN
io: DriverIO ←
NARROW[cell.realCellStuff.newIO];
{OPEN io;
IF drive
THEN
FOR bit:
CARDINAL
IN [0 .. WordSize)
DO
IF BitOps.
EBFW[asInt, 4, bit]
THEN bitLines[bit].held.s[u] ← drive
ELSE bitLines[bit].held.s[d] ← drive
ENDLOOP};
END;
DriverValsChanged: CellProc
--PROC [cell: Cell]-- =
BEGIN
io: DriverIO ←
NARROW[cell.realCellStuff.newIO];
{OPEN io;
IF
NOT drive
THEN {
FOR bit:
CARDINAL
IN [0 .. WordSize)
DO
asInt ← BitOps.IBIW[bitLines[bit].held.val = H, asInt, 4, bit];
ENDLOOP;
ScheduleCell[cell]}};
END;
DriverOther: CellProc
--PROC [cell: Cell]-- =
BEGIN
io: DriverIO ← NARROW[cell.realCellStuff.newIO];
state: DriverState ←
NARROW[cell.realCellStuff.state];
{OPEN io, state;
IF drive # wasDriven
OR (drive
AND asInt # lastDriven)
THEN {
FOR bit: CARDINAL IN [0 .. WordSize) DO PerturbPort[cell, bit] ENDLOOP;
wasDriven ← drive;
lastDriven ← asInt}};
END;
ExpandMemoryExample: ExpandProc
--PROCEDURE [thisCell: Cell, initData: REF ANY]-- =
BEGIN
writes, reads: ARRAY [0 .. WordCount) OF Node;
bits: ARRAY [0 .. WordSize) OF Node;
asInt: Node ← CreateNode[thisCell, "asInt", NumTypes.NumType[4]];
drive: Node ← CreateNode[thisCell, "drive", NumTypes.boolType, "TRUE"];
FOR word:
CARDINAL
IN [0 .. WordCount)
DO
writes[word] ← CreateNode[thisCell, IO.PutFR["Write[%g]", IO.card[word]], NumTypes.boolType];
reads[word] ← CreateNode[thisCell, IO.PutFR["Read[%g]", IO.card[word]], NumTypes.boolType];
ENDLOOP;
FOR bit:
CARDINAL
IN [0 .. WordSize)
DO
bits[bit] ← CreateNode[thisCell, IO.PutFR["Bit[%g]", IO.card[bit]], SwitchTypes.bitType];
ENDLOOP;
[] ← CreateCell[thisCell, "driver", "Driver", ""];
[] ← CreateCell[thisCell, "mem", "Mem", ""];
END;
Setup:
PROC =
BEGIN
memPorts: Ports ← NEW [PortsRep[2*WordCount + WordSize]];
driverPorts: Ports ← NEW [PortsRep[WordSize + 2]];
FOR word:
CARDINAL
IN [0 .. WordCount)
DO
memPorts[2*word+0] ← [2*word+0, 1, IO.PutFR["Read[%g]", IO.card[word]], NumTypes.boolType, TRUE];
memPorts[2*word+1] ← [2*word+1, 1, IO.PutFR["Write[%g]", IO.card[word]], NumTypes.boolType, TRUE];
ENDLOOP;
FOR bit:
CARDINAL
IN [0 .. WordSize)
DO
name: ROPE ← IO.PutFR["Bit[%g]", IO.card[bit]];
memPorts[2*WordCount+bit] ← [2*WordCount+bit, 1, name, SwitchTypes.bitType, TRUE, TRUE, TRUE];
driverPorts[bit] ← [bit, 1, name, SwitchTypes.bitType, TRUE, TRUE, TRUE];
ENDLOOP;
driverPorts[WordSize+0] ← [WordSize+0, 1, "asInt", NumTypes.NumType[4], TRUE, TRUE];
driverPorts[WordSize+1] ← [WordSize+1, 1, "drive", NumTypes.boolType, TRUE];
[] ← RegisterCellClass[
className: "Mem",
ioCreator: CreateMemIO,
initializer: InitMem,
evals: [ValsChanged: MemValsChanged, PropQ: MemPropQ, PropUD: MemPropUD, Other: MemOther],
ports: memPorts];
[] ← RegisterCellClass[
className: "Driver",
ioCreator: CreateDriverIO,
initializer: InitDriver,
evals: [ValsChanged: DriverValsChanged, PropQ: DriverPropQ, PropUD: DriverPropUD, Other: DriverOther],
ports: driverPorts];
[] ← RegisterCellClass[
className: "MemoryExample",
expandProc: ExpandMemoryExample,
evals: [],
ports: NEW [PortsRep[0]]];
END;
Setup[];
END.