<> <> 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.