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
DIRECTORY
Core, CoreClasses, CoreCreate, CoreIO, CoreFlat, DynaBusInterface, IO, Ports, PWCoreHack, Rosemary, RosemaryUser, SmallCacheLogic, SCParms, Sisyph, SmallCacheUtils, TerminalIO;
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.WR ← NIL;
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 [
BOOL ←
FALSE] = {
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 [
BOOL ←
FALSE] = {
FOR i: NAT IN [0..ls.size) DO IF ls[i]=X THEN RETURN [TRUE] ENDLOOP;
};