SmallCacheDataPathImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Don Curry, March 16, 1988 5:11:45 pm PST
DIRECTORY SmallCacheDataPath, CMosB, Core, CoreClasses, CoreOps, DataPath, IO, Ports, Rosemary;
SmallCacheDataPathImpl: CEDAR PROGRAM
IMPORTS CoreClasses, CoreOps, DataPath, IO, Ports, Rosemary
EXPORTS SmallCacheDataPath =
BEGIN
Exports
Structure: PUBLIC PROC[wds, bits: NAT] RETURNS [public: Core.Wires] = {-- strc and flat
Transforms a flat bus of w*b bits into a structured bus of w words of b bits
flat[i] = strc[i/w][i MOD w]
strc: Core.Wire ← CoreOps.CreateWires[wds,  "strc"];
flat: Core.Wire ← CoreOps.CreateWires[wds*bits, "flat"];
IF bits=0 OR wds=0 THEN ERROR; -- Please provide parameters for Structure
FOR wd: NAT IN [0..wds) DO
strc[wd] ← CoreOps.CreateWires[bits];
FOR bit: NAT IN [0..bits) DO
flat[wd*bits + bit] ← strc[wd][bit] ← CoreOps.CreateWires[0] ENDLOOP ENDLOOP;
public ← LIST [strc, flat]};
BusShort: PUBLIC PROC[size: INT] RETURNS[wire: Core.Wire] = {
sub: Core.Wire ← CoreOps.CreateWires[0, "sw"];
wire ← CoreOps.CreateWires[size, "w"];
FOR i: INT IN [0..size) DO wire[i] ← sub ENDLOOP};
Trans: PUBLIC PROC[type: CoreClasses.TransistorType, length, width: INT]
RETURNS [cellType: Core.CellType] = {
name: IO.ROPEIO.PutFR["%g%gx%g",
IO.rope[CoreClasses.transistorTypeNames[type]],
IO.int[length],
IO.int[width]];
cellType ← CoreClasses.CreateTransistor[type, length, width, name]};
DPFF
DP32FFName: IO.ROPE = Rosemary.Register
["DP32FFSeq", DPFFSeqInit, DPFFSeqSimple, NIL, TRUE];
DP64FFName: IO.ROPE = Rosemary.Register
["DP64FFSeq", DPFFSeqInit, DPFFSeqSimple, NIL, TRUE];
DPFFSeqState:  TYPE = REF DPFFSeqStateRec;
DPFFSeqStateRec: TYPE = RECORD [
in, out, ck: Ports.Port ← NIL,
master, slave: Ports.LevelSequence];
DPFFSeqInit: Rosemary.InitProc = {
state: DPFFSeqState;
IF oldStateAny=NIL
THEN {
size: NAT ← p[Ports.PortIndex[cellType.public, "D"]].ls.size;
state   ← NEW[DPFFSeqStateRec];
state.master ← NEW[Ports.LevelSequenceRec[size]];
state.slave ← NEW[Ports.LevelSequenceRec[size]]}
ELSE state  ← NARROW[oldStateAny];
state.ck ← p[Ports.PortIndex[cellType.public, "CK"]];
state.in ← p[Ports.PortIndex[cellType.public, "D"]];
state.out ← p[Ports.PortIndex[cellType.public, "Q"]];
Ports.PutDrive[state.out, drive];
Ports.SetLS[state.master, X];
Ports.SetLS[state.slave, X];
Ports.SetLS[state.out.ls, X];
stateAny ← state};
DPFFSeqSimple: Rosemary.EvalProc = {
state: DPFFSeqState ← NARROW[stateAny];
IF ~clockEval THEN {
SELECT state.ck.l FROM
L => Ports.CopyLS[from: state.in.ls, to: state.master];
H => Ports.CopyLS[from: state.master, to: state.slave];
ENDCASE => {
IF state.slave#state.master THEN Ports.SetLS[state.slave, X];
IF state.master#state.in.ls THEN Ports.SetLS[state.master, X]}};
Ports.CopyLS[from: state.slave, to: state.out.ls]};
DPEnFF
DP32EnFFName: IO.ROPE = Rosemary.Register
["DP32EnFFSeq", DPEnFFSeqInit, DPEnFFSeqSimple, NIL, TRUE];
DP64EnFFName: IO.ROPE = Rosemary.Register
["DP64EnFFSeq", DPEnFFSeqInit, DPEnFFSeqSimple, NIL, TRUE];
DPEnFFSeqState:  TYPE = REF DPEnFFSeqStateRec;
DPEnFFSeqStateRec: TYPE = RECORD [
in, out, ck, en, dis: Ports.Port ← NIL,
master, slave: Ports.LevelSequence];
DPEnFFSeqInit: Rosemary.InitProc = {
state: DPEnFFSeqState;
IF oldStateAny=NIL
THEN {
size: NAT ← p[Ports.PortIndex[cellType.public, "D"]].ls.size;
state   ← NEW[DPEnFFSeqStateRec];
state.master ← NEW[Ports.LevelSequenceRec[size]];
state.slave ← NEW[Ports.LevelSequenceRec[size]]}
ELSE state  ← NARROW[oldStateAny];
state.ck ← p[Ports.PortIndex[cellType.public, "CK"]];
state.in ← p[Ports.PortIndex[cellType.public, "D"]];
state.out ← p[Ports.PortIndex[cellType.public, "Q"]];
state.en ← p[Ports.PortIndex[cellType.public, "En"]];
state.dis ← p[Ports.PortIndex[cellType.public, "nEn"]];
Ports.PutDrive[state.out, drive];
Ports.SetLS[state.master, X];
Ports.SetLS[state.slave, X];
Ports.SetLS[state.out.ls, X];
stateAny ← state};
DPEnFFSeqSimple: Rosemary.EvalProc = {
state: DPEnFFSeqState ← NARROW[stateAny];
IF ~clockEval THEN {
SELECT state.ck.l FROM
L => IF state.en.l=state.dis.l
THEN Ports.SetLS[state.master, X]
ELSE IF state.en.l=H
THEN Ports.CopyLS[from: state.slave, to: state.master]
ELSE Ports.CopyLS[from: state.in.ls, to: state.master];
H => Ports.CopyLS[from: state.master, to: state.slave];
ENDCASE => {
IF state.slave#state.master THEN Ports.SetLS[state.slave, X];
IF state.master#state.in.ls THEN Ports.SetLS[state.master, X]}};
Ports.CopyLS[from: state.slave, to: state.out.ls]};
DPLatch
DP32LatchName: IO.ROPE = Rosemary.Register
["DP32LatchSeq", DPLatchSeqInit, DPLatchSeqSimple, NIL, FALSE];
DP64LatchName: IO.ROPE = Rosemary.Register
["DP64LatchSeq", DPLatchSeqInit, DPLatchSeqSimple, NIL, FALSE];
DPLatchSeqState:  TYPE = REF DPLatchSeqStateRec;
DPLatchSeqStateRec: TYPE = RECORD [
in, out, en: Ports.Port ← NIL,
slave: Ports.LevelSequence ];
DPLatchSeqInit: Rosemary.InitProc = {
state: DPLatchSeqState;
IF oldStateAny=NIL
THEN {
size: NAT  ← p[Ports.PortIndex[cellType.public, "D"]].ls.size;
state   ← NEW[DPLatchSeqStateRec];
state.slave ← NEW[Ports.LevelSequenceRec[size]]}
ELSE state ← NARROW[oldStateAny];
state.in ← p[Ports.PortIndex[cellType.public, "D"]];
state.out ← p[Ports.PortIndex[cellType.public, "Q"]];
state.en ← p[Ports.PortIndex[cellType.public, "En"]];
Ports.PutDrive[state.out, drive];
Ports.SetLS[state.out.ls, X];
Ports.SetLS[state.slave, X];
stateAny ← state};
DPLatchSeqSimple: Rosemary.EvalProc = {
state: DPLatchSeqState ← NARROW[stateAny];
IF state.en.l=H
THEN Ports.CopyLS[from: state.in.ls, to: state.slave];
Ports.CopyLS[from: state.slave, to: state.out.ls];
Ports.PutDrive[state.out, drive]};
DPComp
DP32CompName: IO.ROPE = Rosemary.Register
["DP32CompSeq", DPCompSeqInit, DPCompSeqSimple];
DP64CompName: IO.ROPE = Rosemary.Register
["DP64CompSeq", DPCompSeqInit, DPCompSeqSimple];
DPCompSeqState:  TYPE = REF DPCompSeqStateRec;
DPCompSeqStateRec: TYPE = RECORD [a, b, mat: Ports.Port];
DPCompSeqInit: Rosemary.InitProc = {
state: DPCompSeqState ← IF oldStateAny=NIL
THENNEW[DPCompSeqStateRec]
ELSENARROW[oldStateAny];
state.a  ← p[Ports.PortIndex[cellType.public, "A"]];
state.b  ← p[Ports.PortIndex[cellType.public, "B"]];
state.mat ← p[Ports.PortIndex[cellType.public, "Match"]];
stateAny ← state};
DPCompSeqSimple: Rosemary.EvalProc = {
state: DPCompSeqState ← NARROW[stateAny];
level: Ports.Level ← H;
FOR index: NAT IN [0..state.a.ls.size) DO
SELECT TRUE FROM
state.a.ls[index]=X,
state.b.ls[index]=X     => {level ← X; EXIT};
state.a.ls[index] # state.b.ls[index] => {level ← L};
ENDCASE ENDLOOP;
IF level=H
THEN Ports.PutDrive[state.mat,   none]
ELSE Ports.PutLevel[state.mat, level, drive]};
DPMux2
DP32MuxName: IO.ROPE = Rosemary.Register
["DP32Mux2Seq", DPMux2SingSelSeqInit, DPMux2SingSelSeqSimple];
DP64MuxName: IO.ROPE = Rosemary.Register
["DP64Mux2Seq", DPMux2DualSelSeqInit, DPMux2DualSelSeqSimple];
DPMux2SingSelSeqState:  TYPE = REF DPMux2SingSelSeqStateRec;
DPMux2DualSelSeqState:  TYPE = REF DPMux2DualSelSeqStateRec;
DPMux2SingSelSeqStateRec: TYPE = RECORD [in0, in1, sel0,  out: Ports.Port];
DPMux2DualSelSeqStateRec: TYPE = RECORD [in0, in1, sel0, sel1, out: Ports.Port];
DPMux2SingSelSeqInit: Rosemary.InitProc = {
state: DPMux2SingSelSeqState ← IF oldStateAny=NIL
THENNEW[DPMux2SingSelSeqStateRec]
ELSENARROW[oldStateAny];
state.in0  ← p[Ports.PortIndex[cellType.public, "In0"]];
state.in1  ← p[Ports.PortIndex[cellType.public, "In1"]];
state.sel0  ← p[Ports.PortIndex[cellType.public, "Sel0"]];
state.out  ← p[Ports.PortIndex[cellType.public, "Out"]];
Ports.PutDrive[state.out, drive];
stateAny  ← state};
DPMux2DualSelSeqInit: Rosemary.InitProc = {
state: DPMux2DualSelSeqState ← IF oldStateAny=NIL
THENNEW[DPMux2DualSelSeqStateRec]
ELSENARROW[oldStateAny];
state.in0  ← p[Ports.PortIndex[cellType.public, "In0"]];
state.in1  ← p[Ports.PortIndex[cellType.public, "In1"]];
state.sel0  ← p[Ports.PortIndex[cellType.public, "Sel0"]];
state.sel1  ← p[Ports.PortIndex[cellType.public, "Sel1"]];
state.out  ← p[Ports.PortIndex[cellType.public, "Out"]];
Ports.PutDrive[state.out, drive];
stateAny  ← state};
DPMux2SingSelSeqSimple: Rosemary.EvalProc = {
state: DPMux2SingSelSeqState ← NARROW[stateAny];
FOR index: NAT IN [0..state.in0.ls.size) DO
state.out.ls[index] ← IF state.sel0.l=H
THEN state.in0.ls[index]
ELSE state.in1.ls[index] ENDLOOP};
DPMux2DualSelSeqSimple: Rosemary.EvalProc = {
state: DPMux2DualSelSeqState ← NARROW[stateAny];
FOR index: NAT IN [0..state.in0.ls.size) DO
state.out.ls[index] ← IF state.sel0.l=state.sel1.l THEN X ELSE IF state.sel0.l=H
THEN state.in0.ls[index]
ELSE state.in1.ls[index] ENDLOOP};
DPTst
DP32TstName: IO.ROPE = Rosemary.Register
["DP32TstSeq", DPTstSingEnSeqInit, DPTstSingEnSeqSimple];
DP64TstName: IO.ROPE = Rosemary.Register
["DP64TstSeq", DPTstDualEnSeqInit, DPTstDualEnSeqSimple];
DP64TstFlipYName: IO.ROPE = Rosemary.Register
["DP64TstFlipYSeq", DPTstDualEnSeqInit, DPTstDualEnSeqSimple];
DPTstSingEnSeqState:  TYPE = REF DPTstSingEnSeqStateRec;
DPTstDualEnSeqState:  TYPE = REF DPTstDualEnSeqStateRec;
DPTstSingEnSeqStateRec: TYPE = RECORD [in, out, en:  Ports.Port];
DPTstDualEnSeqStateRec: TYPE = RECORD [in, out, en, dis: Ports.Port];
DPTstSingEnSeqInit: Rosemary.InitProc = {
state: DPTstSingEnSeqState ← IF oldStateAny=NIL
THENNEW[DPTstSingEnSeqStateRec]
ELSENARROW[oldStateAny];
state.in ← p[Ports.PortIndex[cellType.public, "In"]];
state.out ← p[Ports.PortIndex[cellType.public, "Out"]];
state.en ← p[Ports.PortIndex[cellType.public, "En"]];
Ports.PutDrive[state.out, drive];
stateAny ← state};
DPTstDualEnSeqInit: Rosemary.InitProc = {
state: DPTstDualEnSeqState ← IF oldStateAny=NIL
THENNEW[DPTstDualEnSeqStateRec]
ELSENARROW[oldStateAny];
state.in ← p[Ports.PortIndex[cellType.public, "In"]];
state.out ← p[Ports.PortIndex[cellType.public, "Out"]];
state.en ← p[Ports.PortIndex[cellType.public, "En"]];
state.dis ← p[Ports.PortIndex[cellType.public, "nEn"]];
Ports.PutDrive[state.out, drive];
stateAny ← state};
DPTstSingEnSeqSimple: Rosemary.EvalProc = {
state: DPTstSingEnSeqState ← NARROW[stateAny];
IF state.en.l=H THEN {
Ports.CopyLS[state.in.ls, state.out.ls];
Ports.PutDrive[state.out, drive]}};
DPTstDualEnSeqSimple: Rosemary.EvalProc = {
state: DPTstDualEnSeqState ← NARROW[stateAny];
IF state.en.l=state.dis.l
THEN {Ports.SetLS[state.out.ls, X]; Ports.PutDrive[state.out, drive]}
ELSE {
Ports.CopyLS[state.in.ls, state.out.ls];
Ports.PutDrive[state.out, (IF state.en.l=H THEN drive ELSE none)]}};
Spec Registration
DataPath.RegisterDataPathSpec["SmallCache64", NEW[DataPath.DPSpecRec ← [
layDWidth: 65*CMosB.lambda]]];
DataPath.RegisterDataPathSpec["SmallCache32", NEW[DataPath.DPSpecRec ← [
layDWidth: 162*CMosB.lambda]]];
END.