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: BOOLEANFALSE;
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: ROPEIO.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.