SmallCacheDataPathImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Don Curry, March 16, 1988 5:11:45 pm PST
SmallCacheDataPathImpl:
CEDAR
PROGRAM
IMPORTS CoreClasses, CoreOps, DataPath, IO, Ports, Rosemary
EXPORTS SmallCacheDataPath =
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.
ROPE ←
IO.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
THEN NEW[DPCompSeqStateRec]
ELSE NARROW[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
THEN NEW[DPMux2SingSelSeqStateRec]
ELSE NARROW[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
THEN NEW[DPMux2DualSelSeqStateRec]
ELSE NARROW[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
THEN NEW[DPTstSingEnSeqStateRec]
ELSE NARROW[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
THEN NEW[DPTstDualEnSeqStateRec]
ELSE NARROW[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]]];