CreateRamControl:
PUBLIC PROC
RETURNS [cellType: CellType] = {
inDriver: CellType ← EU2LeafUtils.AlpsExtract["InputDriver.sch"];
outClkDriver: CellType ← EU2LeafUtils.AlpsExtract["ClockedOutputDriver.sch"];
inputDrivers: Inputs ← NIL;
outputDrivers: Outputs ← NIL;
outputDriver: OutputRec;
expr: Expression ← NIL;
public: Wire ← Union[GenPGnEWires[], GenWiresCtrlToRam[], GenWiresRamToCtrl[], Wires["reject", "nPhA"]];
ramAdr: Wire ← FindWire[public, "ramAdr"];
reject: Expression ← WireVar[public, "reject"];
nReject: Expression ← Not[reject];
aHi: Wire ← ramAdr[a][hi];
bHi: Wire ← ramAdr[b][hi];
cHi: Wire ← ramAdr[c][hi];
aLow: Wire ← ramAdr[a][low];
bLow: Wire ← ramAdr[b][low];
cLow: Wire ← ramAdr[c][low];
cAdr: Wire ← ramAdr[c];
-- Input inverters to the Alps blocks (25 pieces)
-- ramAdr[aAdrH, bAdrH, cAdrH, aAdrL, bAdrL, cAdrL] and reject
FOR i:
INT
IN [0..sizeAdrH)
DO
inputDrivers ← CONS[[input: Index[aHi, i], driver: inDriver], inputDrivers];
inputDrivers ← CONS[[input: Index[bHi, i], driver: inDriver], inputDrivers];
inputDrivers ← CONS[[input: Index[cHi, i], driver: inDriver], inputDrivers];
ENDLOOP;
FOR i:
INT
IN [0..sizeAdrL)
DO
inputDrivers ← CONS[[input: Index[aLow, i], driver: inDriver], inputDrivers];
inputDrivers ← CONS[[input: Index[bLow, i], driver: inDriver], inputDrivers];
inputDrivers ← CONS[[input: Index[cLow, i], driver: inDriver], inputDrivers];
ENDLOOP;
inputDrivers ← CONS[[input: "reject", driver: inDriver], inputDrivers];
-- Enable Write on the KBus (IFU side)
outputDriver ← [driver: outClkDriver, pas:
LIST[["Clock", "nPhA"]],
output: "enWrtIFU",
expr: EqualInt[public, cAdr, IFUAdr]];
outputDrivers ← CONS[outputDriver, outputDrivers];
-- Precharge of the RAM: follows nPhB, so it gets PhB
outputDriver ← [driver: outClkDriver, pas: LIST[["Clock", "PhB"]],
output: "nPrech",
expr: true];
outputDrivers ← CONS[outputDriver, outputDrivers];
-- Output drivers, all of the same type: they follow PhA, so they get nPhA;
FOR i:
INT
IN [0..nRows)
DO
-- selHi[i][a] ← aAdrH=i
outputDriver ← [driver: outClkDriver, pas:
LIST[["Clock", "nPhA"]],
output: Index["selA", i],
expr: EqualInt[public, aHi, i]];
outputDrivers ← CONS[outputDriver, outputDrivers];
-- selHi[i][b] ← bAdrH=i
outputDriver ← [driver: outClkDriver, pas:
LIST[["Clock", "nPhA"]],
output: Index["selB", i],
expr: EqualInt[public, bHi, i]];
outputDrivers ← CONS[outputDriver, outputDrivers];
-- selHi[i][c] ← (cAdrH=i).~reject for i#marAdr/4
-- selHi[marAdr/4][c] ← (cAdrH=i)+reject
expr ←
IF i=marAdr/4
THEN Or[reject, EqualInt[public, cHi, i]]
ELSE And[nReject, EqualInt[public, cHi, i]];
outputDriver ← [driver: outClkDriver, pas:
LIST[["Clock", "nPhA"]],
output: Index["selC", i],
expr: expr];
outputDrivers ← CONS[outputDriver, outputDrivers];
ENDLOOP;
FOR i:
INT
IN [0..sizeSelLow)
DO
-- selLow[i][a] ← aAdrL=i
outputDriver ← [driver: outClkDriver, pas:
LIST[["Clock", "nPhA"]],
output: Index["selALow", i],
expr: EqualInt[public, aLow, i]];
outputDrivers ← CONS[outputDriver, outputDrivers];
-- selLow[i][b] ← bAdrL=i
outputDriver ← [driver: outClkDriver, pas:
LIST[["Clock", "nPhA"]],
output: Index["selBLow", i],
expr: EqualInt[public, bLow, i]];
outputDrivers ← CONS[outputDriver, outputDrivers];
-- selLow[i][c] ← (cAdrL=i).~reject for i#marAdr MOD 4
-- selHi[marAdr MOD 4][c] ← (cAdrL=i)+reject
expr ←
IF i=marAdr
MOD 4
THEN Or[reject, EqualInt[public, cLow, i]]
ELSE And[nReject, EqualInt[public, cLow, i]];
outputDriver ← [driver: outClkDriver, pas:
LIST[["Clock", "nPhA"]],
output: Index["selCLow", i],
expr: expr];
outputDrivers ← CONS[outputDriver, outputDrivers];
ENDLOOP;
cellType ← AlpsCell[
name: "RamControl",
public: public,
inputs: inputDrivers,
outputs: outputDrivers,
fillerOutputDriver: PW.Get[EU2LeafUtils.eu2Design, "FillerOutputDriver.mask"],
fillerCornerDriver: PW.Get[EU2LeafUtils.eu2Design, "FillerCornerDriver.mask"]
];
};