SmallCacheLogicImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Created: Sindhu July 27, 1987 2:00:51 pm PDT
Pradeep Sindhu April 29, 1988 4:37:14 pm PDT
Don Curry June 10, 1988 1:23:41 pm PDT
Contains low-level utility procs used in writing behavioral procs.
DIRECTORY
Core, CoreClasses, CoreCreate, CoreIO, CoreFlat, DynaBusInterface, IO, Ports, PWCoreHack, Rosemary, RosemaryUser, SmallCacheLogic, SCParms, Sisyph, SmallCacheUtils, TerminalIO;
SmallCacheLogicImpl: CEDAR PROGRAM
IMPORTS CoreClasses, CoreCreate, CoreIO, CoreFlat, IO, Ports, PWCoreHack, Rosemary, Sisyph, SmallCacheUtils, TerminalIO
EXPORTS SmallCacheLogic
~ BEGIN OPEN SmallCacheLogic;
Public Procs
SmallCache: PUBLIC PROC [cts: CellTypeSpec, cx: Context] RETURNS [ct: CellType] = {
SELECT cts FROM
Schematic => ct ← Sisyph.ES["SmallCache.sch", Sisyph.Create[SmallCacheUtils.GetDesign["SmallCache"], cx]];
Procedure => ERROR; -- there is no top level proc for the cache
CoreFile => ct ← CoreIO.RestoreCellType[cellName: "SmallCache.icon", fileName: "SmallCache.core"];
ENDCASE => ERROR};
SCacheHybrid: PUBLIC PROC [cts: SCParms.CellTypeSpec, cx: Sisyph.Context]
RETURNS [ct: SmallCacheLogic.CellType] = {
SELECT cts FROM
Schematic => ct ← Sisyph.ES["SCacheHybrid.sch", cx];
CoreFile  => ct ← PWCoreHack.Retrieve["SCacheHybrid"];
ENDCASE  => ERROR};
SCache: PUBLIC PROC [cts: SCParms.CellTypeSpec, cx: Sisyph.Context]
RETURNS [ct: SmallCacheLogic.CellType] = {
SELECT cts FROM
Schematic => ct ← Sisyph.ES["SCache.sch", cx];
CoreFile  => ct ← PWCoreHack.Retrieve["SCache"];
ENDCASE  => ERROR};
Inner: PUBLIC PROC [cts: SCParms.CellTypeSpec, cx: Sisyph.Context]
RETURNS [ct: SmallCacheLogic.CellType] = {
SELECT cts FROM
Schematic => ct ← Sisyph.ES["SCacheInner.sch", cx];
CoreFile  => ct ← PWCoreHack.Retrieve["SCacheInner"];
ENDCASE  => ERROR};
LeftCtl: PUBLIC PROC [cts: SCParms.CellTypeSpec, cx: Sisyph.Context]
RETURNS [ct: SmallCacheLogic.CellType] = {
SELECT cts FROM
Schematic => ct ← Sisyph.ES["SCacheLeftCtl.sch", cx];
CoreFile  => ct ← PWCoreHack.Retrieve["SCacheLeftCtl"];
ENDCASE  => ERROR};
DataPath: PUBLIC PROC [cts: SCParms.CellTypeSpec, cx: Sisyph.Context]
RETURNS [ct: SmallCacheLogic.CellType] = {
SELECT cts FROM
Schematic => ct ← Sisyph.ES["SCacheDataPath.sch", cx];
CoreFile  => ct ← PWCoreHack.Retrieve["SCacheDataPath"];
ENDCASE  => ERROR};
RightCtl: PUBLIC PROC [cts: SCParms.CellTypeSpec, cx: Sisyph.Context]
RETURNS [ct: SmallCacheLogic.CellType] = {
SELECT cts FROM
Schematic => ct ← Sisyph.ES["SCacheRightCtl.sch", cx];
CoreFile  => ct ← PWCoreHack.Retrieve["SCacheRightCtl"];
ENDCASE  => ERROR};
Declare: PUBLIC PROC [signals: Signals, name: ROPE, l: Level, st: SignalType] RETURNS [ix: NAT] = {
signals[signals.numSignals] ← [name: name, st: st, l: l];
ix ← signals.numSignals;
signals.numSignals ← signals.numSignals+1;
};
DeclareS: PUBLIC PROC [signals: Signals, name: ROPE, size: NAT, lc: CARD, st: SignalType] RETURNS [ix: NAT] = {
ls: LevelSequence ← NEW [LevelSequenceRec[size]];
SELECT lc FROM
= 0 => FOR i: NAT IN [0..size) DO ls[i] ← L ENDLOOP;
= Xs => FOR i: NAT IN [0..size) DO ls[i] ← X ENDLOOP;
ENDCASE => IF size <= 32 THEN Ports.LCToLS[lc, ls] ELSE ERROR; -- Can't initialize it
signals[signals.numSignals] ← [name: name, size: size, st: st, ls: ls];
ix ← signals.numSignals;
signals.numSignals ← signals.numSignals+1;
};
Create: PUBLIC PROC [roseClassName: ROPE, signals: Signals] RETURNS [ct: CellType] = {
nameList: LIST OF CoreCreate.WRNIL;
FOR i: NAT IN [0..signals.numSignals) DO
IF signals[i].name=NIL THEN LOOP;
IF signals[i].size=0
THEN nameList ← CONS[signals[i].name, nameList]
ELSE nameList ← CONS[CoreCreate.Seq[signals[i].name, signals[i].size], nameList]
ENDLOOP;
ct ← CoreClasses.CreateUnspecified[public: CoreCreate.WireList[nameList, roseClassName, NIL]];
[] ← Rosemary.BindCellType[cellType: ct, roseClassName: roseClassName];
[] ← CoreFlat.CellTypeCutLabels[ct, "Logic"];
FOR i: NAT IN [0..signals.numSignals) DO
SwitchType: TYPE = RECORD [BOOL, SignalType];
switch: SwitchType ← [signals[i].size=0, signals[i].st];
IF signals[i].name=NIL THEN LOOP;
SELECT switch FROM
[TRUE, Input] => [] ← Ports.InitPorts[ct, l, none, signals[i].name]; 
[TRUE, InputOutput] => [] ← Ports.InitPorts[ct, l, none, signals[i].name]; 
[TRUE, Output] => [] ← Ports.InitPorts[ct, l, drive, signals[i].name];
[TRUE, Power] => [] ← Ports.InitPorts[ct, b, none, signals[i].name];
[FALSE, Input] => [] ← Ports.InitPorts[ct, ls, none, signals[i].name];
[FALSE, InputOutput] => [] ← Ports.InitPorts[ct, ls, none, signals[i].name];
[FALSE, Output] => [] ← Ports.InitPorts[ct, ls, drive, signals[i].name];
ENDCASE => ERROR;
ENDLOOP;
};
GetPortIndices: PUBLIC PROC [signals: Signals, ct: CellType] = {
FOR i: NAT IN [0..signals.numSignals) DO
IF signals[i].name=NIL THEN LOOP;
signals[i].index ← Ports.PortIndex[ct.public, signals[i].name];
ENDLOOP;
};
XInInputs: PUBLIC PROC [p: Port, s: Signals] RETURNS [BOOLFALSE] = {
PrintName: PROC [name: ROPE] = {
TerminalIO.PutF["*** Input %g is an X\n", IO.rope[name]];
};
FOR i: NAT IN [0..s.numSignals) DO
IF s[i].name=NIL OR s[i].st#Input THEN LOOP;
IF s[i].size=0
THEN {IF p[s[i].index].l=X THEN {PrintName[s[i].name]; RETURN[TRUE]}}
ELSE {IF XInLS[p[s[i].index].ls] THEN {PrintName[s[i].name]; RETURN[TRUE]}}
ENDLOOP;
};
OutputsToX: PUBLIC PROC [p: Port, s: Signals] = {
FOR i: NAT IN [0..s.numSignals) DO
IF s[i].name=NIL OR s[i].st#Output THEN LOOP;
IF s[i].size=0
THEN p[s[i].index].l ← X
ELSE Ports.SetLS[p[s[i].index].ls, X]
ENDLOOP;
};
OutputsToDefault: PUBLIC PROC [p: Port, s: Signals] = {
FOR i: NAT IN [0..s.numSignals) DO
IF s[i].name=NIL OR s[i].st#Output THEN LOOP;
IF s[i].size=0
THEN p[s[i].index].l ← s[i].l
ELSE CopyLS[p[s[i].index].ls, s[i].ls]
ENDLOOP;
};
CopyInputValues: PUBLIC PROC [s: Signals, p: Port] = {
FOR i: NAT IN [0..s.numSignals) DO
IF s[i].name=NIL OR (s[i].st#Input AND s[i].st#InputOutput) THEN LOOP;
IF s[i].size=0
THEN s[i].l ← p[s[i].index].l
ELSE CopyLS[s[i].ls, p[s[i].index].ls]
ENDLOOP;
};
CopySignals: PUBLIC PROC [to, from: Signals] = {
to.numSignals ← from.numSignals;
FOR i: NAT IN [0..from.numSignals) DO
IF from[i].name=NIL THEN LOOP;
to[i].name ← from[i].name;
to[i].size ← from[i].size;
to[i].st ← from[i].st;
to[i].l ← from[i].l;
IF from[i].size > 0 THEN {
IF to[i].ls=NIL THEN to[i].ls ← NEW [LevelSequenceRec[to[i].size]];
CopyLS[to[i].ls, from[i].ls];
};
to[i].index ← from[i].index;
ENDLOOP;
};
CopyLS: PUBLIC PROC [dest, source: LevelSequence, index: NAT ← 0] = {
sourceStart, destStart, size: NAT ← 0;
IF dest.size < source.size
THEN {size ← dest.size; sourceStart ← index}
ELSE {size ← source.size; destStart ← index};
FOR i: NAT IN [0..size) DO dest[destStart+i] ← source[sourceStart+i] ENDLOOP;
};
XInLS: PUBLIC PROC [ls: LevelSequence] RETURNS [BOOLFALSE] = {
FOR i: NAT IN [0..ls.size) DO IF ls[i]=X THEN RETURN [TRUE] ENDLOOP;
};
END.