SmallCacheBlockAssemblyRegisterImpl.mesa
Pradeep Sindhu April 26, 1988 12:51:28 pm PDT
Paraminder Sahai September 24, 1987 0:27:17 am PDT
DIRECTORY
Core, CoreClasses, CoreCreate, CoreFlat, Ports, Rosemary, RosemaryUser, SmallCacheLogic, SCParms, Sisyph;
SmallCacheBlockAssemblyRegisterImpl: CEDAR PROGRAM
IMPORTS CoreClasses, CoreCreate, CoreFlat, Ports, Rosemary, SCParms, Sisyph
EXPORTS SmallCacheLogic
~ BEGIN OPEN SmallCacheLogic;
Constants and Type Defs
InternalState: TYPE = RECORD [
bar: LevelSequence,
en: LevelSequence
];
State: TYPE = REF StateRec;
StateRec: TYPE = RECORD [
bCycleAdrs: LevelSequence,
master: InternalState,
slave: InternalState
];
Signal Defs
CycleIn, BCtlBlkWt5, BCycle0, BCycle1, BlkWtData, Clock: NAT;
Public Procs
BlockAssemblyRegister: PUBLIC PROC [cts: CellTypeSpec, cx: Context] RETURNS [ct: CellType] = {
public: Wire ← CoreCreate.WireList[LIST[CoreCreate.Seq["CycleIn", SCParms.numBitsPerCycle],
CoreCreate.Seq["BlkWtData", SCParms.numBitsPerLine], "BCtlBlkWt5", "BCycle0", "BCycle1", "Clock"]];
SELECT cts FROM
Schematic => ct ← Sisyph.ES["BlockAssemblyRegister.sch", cx];
Procedure => {
ct ← CoreClasses.CreateUnspecified[public: public];
[] ← Rosemary.BindCellType[cellType: ct, roseClassName: myBlockAssRegName];
[] ← CoreFlat.CellTypeCutLabels[ct, "Logic"];
Ports.InitPorts[ct, ls, none, "CycleIn"];
Ports.InitPorts[ct, l, none, "BCtlBlkWt5", "BCycle0", "BCycle1", "Clock"];
Ports.InitPorts[ct, ls, drive, "BlkWtData"];
};
CoreFile => ERROR
ENDCASE => ERROR
};
Internal Procs
Init: Rosemary.InitProc = {
s: State;
IF oldStateAny=NIL
THEN {
s ← NEW [StateRec];
s.bCycleAdrs ← NEW [LevelSequenceRec[SCParms.logNumCyclesPerLine]];
s.master.bar ← NEW [LevelSequenceRec[SCParms.numBitsPerLine]];
s.master.en ← NEW [LevelSequenceRec[SCParms.numCyclesPerLine]];
s.slave.bar ← NEW [LevelSequenceRec[SCParms.numBitsPerLine]];
s.slave.en ← NEW [LevelSequenceRec[SCParms.numCyclesPerLine]];
}
ELSE s ← NARROW [oldStateAny, State];
Ports.SetLS[s.bCycleAdrs, X];
Ports.SetLS[s.master.bar, X];
Ports.SetLS[s.master.en, X];
Ports.SetLS[s.slave.bar, X];
Ports.SetLS[s.slave.en, X];
[CycleIn, BCtlBlkWt5, BCycle0, BCycle1, BlkWtData, Clock] ← Ports.PortIndexes[cellType.public, "CycleIn", "BCtlBlkWt5", "BCycle0", "BCycle1", "BlkWtData", "Clock"];
stateAny ← s;
};
Simple: Rosemary.EvalProc = {
s: State ← NARROW[stateAny];
IF NOT clockEval THEN SELECT p[Clock].l FROM
L => {
numEnablesHigh: NAT ← 0;
FOR cycle: NAT IN [0..SCParms.numCyclesPerLine) DO
Compute master.en[cycle]
IF p[BCycle0].l=H OR p[BCtlBlkWt5].l=H
THEN s.master.en[cycle] ← L
ELSE {
prevCycle: INT;
FOR i: NAT IN [0..SCParms.logNumCyclesPerLine) DO
s.bCycleAdrs[i] ← p[CycleIn].ls[SCParms.numBitsPerCycle-SCParms.numWordsPerCycle*(SCParms.logNumWordsPerLine-i)+1];
ENDLOOP;
prevCycle ← (cycle-1) MOD SCParms.numCyclesPerLine;
IF prevCycle<0 THEN prevCycle ← SCParms.numCyclesPerLine-1;
IF (p[BCycle1].l=H AND Ports.LSToC[s.bCycleAdrs]=cycle) OR s.slave.en[prevCycle]=H
THEN s.master.en[cycle] ← H
ELSE s.master.en[cycle] ← L
};
Compute master.bar[cycle]
SELECT s.slave.en[cycle] FROM
H => {
IF (numEnablesHigh ← numEnablesHigh+1) > 1 THEN ERROR;
FOR i: NAT IN [0..SCParms.numBitsPerWord) DO
s.master.bar[i*SCParms.numWordsPerLine+SCParms.numWordsPerCycle*cycle] ← p[CycleIn].ls[2*i];
s.master.bar[i*SCParms.numWordsPerLine+SCParms.numWordsPerCycle*cycle+1] ← p[CycleIn].ls[2*i+1]
ENDLOOP;
};
X => {
FOR i: NAT IN [0..SCParms.numBitsPerWord) DO
s.master.bar[i*SCParms.numWordsPerLine+SCParms.numWordsPerCycle*cycle] ← X;
s.master.bar[i*SCParms.numWordsPerLine+SCParms.numWordsPerCycle*cycle+1] ← X
ENDLOOP;
};
ENDCASE
ENDLOOP;
};
H => {
Ports.CopyLS[s.master.en, s.slave.en];
Ports.CopyLS[s.master.bar, s.slave.bar];
};
X => {
Ports.SetLS[s.master.en, X];
Ports.SetLS[s.master.bar, X];
Ports.SetLS[s.slave.en, X];
Ports.SetLS[s.slave.bar, X];
};
ENDCASE => ERROR;
Ports.CopyLS[s.slave.bar, p[BlkWtData].ls]
};
myBlockAssRegName: ROPE = Rosemary.Register[roseClassName: "SmallCacheBlockAssemblyRegister", init: Init, evalSimple: Simple, scheduleIfClockEval: TRUE];
END.