MCDataPathImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Don Curry, November 11, 1987 1:36:42 am PST
DIRECTORY MCDataPath, Core, CoreClasses, CoreOps, CMosB, DataPath, IO, Ports, Rope, Rosemary;
MCDataPathImpl:
CEDAR
PROGRAM
IMPORTS CoreClasses, CoreOps, DataPath, IO, Ports, Rosemary
EXPORTS MCDataPath =
EXPORTS
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]};
DPEdgeFF
DPEdgeFFName: Rope.
ROPE = Rosemary.Register[roseClassName: "DPEdgeFFSeq", init: DPEdgeFFSeqInit, evalSimple: DPEdgeFFSeqSimple, scheduleIfClockEval:
TRUE];
DPEdgeFFSeqState: TYPE = REF DPEdgeFFSeqStateRec;
DPEdgeFFSeqStateRec:
TYPE =
RECORD [
in, out, ck: Ports.Port ← NIL,
master, slave: Ports.LevelSequence];
DPEdgeFFSeqInit: Rosemary.InitProc = {
state: DPEdgeFFSeqState;
IF oldStateAny=
NIL
THEN {
size: NAT ← p[Ports.PortIndex[cellType.public, "D"]].ls.size;
state ← NEW[DPEdgeFFSeqStateRec];
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.out.d ← drive;
Ports.SetLS[state.master, X];
Ports.SetLS[state.slave, X];
Ports.SetLS[state.out.ls, X];
stateAny ← state;
};
DPEdgeFFSeqSimple: Rosemary.EvalProc = {
state: DPEdgeFFSeqState ← 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];
};
DPTSLatch
DPTSLatchName: Rope.
ROPE = Rosemary.Register[roseClassName: "DPTSLatchSeq", init: DPTSLatchSeqInit, evalSimple: DPTSLatchSeqSimple, scheduleIfClockEval:
TRUE];
DPTSLatchSeqState: TYPE = REF DPTSLatchSeqStateRec;
DPTSLatchSeqStateRec:
TYPE =
RECORD [
in, out, ck, en, dis: Ports.Port ← NIL,
slave: Ports.LevelSequence
];
DPTSLatchSeqInit: Rosemary.InitProc = {
state: DPTSLatchSeqState;
IF oldStateAny=
NIL
THEN {
size: NAT ← p[Ports.PortIndex[cellType.public, "D"]].ls.size;
state ← NEW[DPTSLatchSeqStateRec];
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, "dis"]];
state.out.d ← drive;
Ports.SetLS[state.out.ls, X];
Ports.SetLS[state.slave, X];
stateAny ← state;
};
DPTSLatchSeqSimple: Rosemary.EvalProc = {
state: DPTSLatchSeqState ← NARROW[stateAny];
IF ~clockEval THEN {IF state.ck.l=H THEN Ports.CopyLS[from: state.in.ls, to: state.slave]};
IF state.en.l=H
AND state.dis.l=L
THEN {
state.out.d ← drive;
Ports.CopyLS[from: state.slave, to: state.out.ls]}
ELSE state.out.d ← none;
};
DPNOr3
DPNOr3Name: Rope.
ROPE = Rosemary.Register[roseClassName: "DPNOr3Seq", init: DPNOr3SeqInit, evalSimple: DPNOr3SeqSimple];
DPNOr3SeqState: TYPE = REF DPNOr3SeqStateRec;
DPNOr3SeqStateRec:
TYPE =
RECORD [
in0, in1, in2, out: Ports.Port];
DPNOr3SeqInit: Rosemary.InitProc = {
state: DPNOr3SeqState ← IF oldStateAny=NIL THEN NEW[DPNOr3SeqStateRec] ELSE NARROW[oldStateAny];
state.in0 ← p[Ports.PortIndex[cellType.public, "in0"]];
state.in1 ← p[Ports.PortIndex[cellType.public, "in1"]];
state.in2 ← p[Ports.PortIndex[cellType.public, "in2"]];
state.out ← p[Ports.PortIndex[cellType.public, "out0"]];
state.out.d ← drive;
stateAny ← state;
};
DPNOr3SeqSimple: Rosemary.EvalProc = {
state: DPNOr3SeqState ← NARROW[stateAny];
FOR index:
NAT
IN [0..state.in0.ls.size)
DO
state.out.ls[index] ←
SELECT
TRUE
FROM
state.in0.ls[index]=H OR state.in1.ls[index]=H OR state.in2.ls[index]=H => L,
state.in0.ls[index]=X OR state.in1.ls[index]=X OR state.in2.ls[index]=X => X,
ENDCASE => H;
ENDLOOP;
};
DPXOr, DPXOrTop, DPXOrBot
DPXOrName: Rope.ROPE = Rosemary.Register[roseClassName: "DPXOrSeq", init: DPXOrSeqInit, evalSimple: DPXOrSeqSimple];
DPXOrTopName: Rope.ROPE = Rosemary.Register[roseClassName: "DPXOrTopSeq", init: DPXOrSeqInit, evalSimple: DPXOrSeqSimple];
DPXOrBotName: Rope.ROPE = Rosemary.Register[roseClassName: "DPXOrBotSeq", init: DPXOrSeqInit, evalSimple: DPXOrSeqSimple];
DPXOrSeqState: TYPE = REF DPXOrSeqStateRec;
DPXOrSeqStateRec:
TYPE =
RECORD [
in0, in1, out: Ports.Port];
DPXOrSeqInit: Rosemary.InitProc = {
state: DPXOrSeqState ← IF oldStateAny=NIL THEN NEW[DPXOrSeqStateRec] ELSE NARROW[oldStateAny];
state.in0 ← p[Ports.PortIndex[cellType.public, "in0"]];
state.in1 ← p[Ports.PortIndex[cellType.public, "in1"]];
state.out ← p[Ports.PortIndex[cellType.public, "out0"]];
state.out.d ← drive;
stateAny ← state;
};
DPXOrSeqSimple: Rosemary.EvalProc = {
state: DPXOrSeqState ← NARROW[stateAny];
FOR index:
NAT
IN [0..state.in0.ls.size)
DO
state.out.ls[index] ←
SELECT
TRUE
FROM
state.in0.ls[index]=X OR state.in1.ls[index]=X => X,
state.in0.ls[index] = state.in1.ls[index] => L,
ENDCASE => H;
ENDLOOP;
};
DPInv, DPInvDr
DPInvName: Rope.ROPE = Rosemary.Register[roseClassName: "DPInvSeq", init: DPInvSeqInit, evalSimple: DPInvSeqSimple];
DPInvDrName: Rope.ROPE = Rosemary.Register[roseClassName: "DPInvDrSeq", init: DPInvSeqInit, evalSimple: DPInvSeqSimple];
DPInvSeqState: TYPE = REF DPInvSeqStateRec;
DPInvSeqStateRec:
TYPE =
RECORD [
DPInvSeqInit: Rosemary.InitProc = {
state: DPInvSeqState ← IF oldStateAny=NIL THEN NEW[DPInvSeqStateRec] ELSE NARROW[oldStateAny];
state.in ← p[Ports.PortIndex[cellType.public, "in0"]];
state.out ← p[Ports.PortIndex[cellType.public, "out0"]];
state.out.d ← drive;
stateAny ← state;
};
DPInvSeqSimple: Rosemary.EvalProc = {
state: DPInvSeqState ← NARROW[stateAny];
Ports.NotLS[state.in.ls, state.out.ls];
};
DPTriDrInv, DPSCTriInv
DPTriDrInvName: Rope.ROPE = Rosemary.Register[roseClassName: "DPTriDrInvSeq", init: DPTriDrSeqInit, evalSimple: DPTriDrSeqSimple];
DPSCTriInvName: Rope.ROPE = Rosemary.Register[roseClassName: "DPSCTriInvSeq", init: DPTriDrSeqInit, evalSimple: DPTriDrSeqSimple];
DPTriDrSeqState: TYPE = REF DPTriDrSeqStateRec;
DPTriDrSeqStateRec:
TYPE =
RECORD [
in, out, en, dis: Ports.Port];
DPTriDrSeqInit: Rosemary.InitProc = {
state: DPTriDrSeqState ← IF oldStateAny=NIL THEN NEW[DPTriDrSeqStateRec] 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, "dis"]];
state.out.d ← drive;
stateAny ← state;
};
DPTriDrSeqSimple: Rosemary.EvalProc = {
state: DPTriDrSeqState ← NARROW[stateAny];
Ports.CopyLS[state.in.ls, state.out.ls];
state.out.d ← IF state.en.l=H AND state.dis.l=L THEN drive ELSE none;
};
DPBuf, DPSCBuf
DPBufName: Rope.ROPE = Rosemary.Register[roseClassName: "DPBufSeq", init: DPBufSeqInit, evalSimple: DPBufSeqSimple];
DPSCBufName: Rope.ROPE = Rosemary.Register[roseClassName: "DPSCBufSeq", init: DPBufSeqInit, evalSimple: DPBufSeqSimple];
DPBufSeqState: TYPE = REF DPBufSeqStateRec;
DPBufSeqStateRec:
TYPE =
RECORD [
DPBufSeqInit: Rosemary.InitProc = {
state: DPBufSeqState ← IF oldStateAny=NIL THEN NEW[DPBufSeqStateRec] ELSE NARROW[oldStateAny];
state.in ← p[Ports.PortIndex[cellType.public, "in0"]];
state.out ← p[Ports.PortIndex[cellType.public, "out0"]];
state.out.d ← drive;
stateAny ← state;
};
DPBufSeqSimple: Rosemary.EvalProc = {
state: DPBufSeqState ← NARROW[stateAny];
Ports.CopyLS[state.in.ls, state.out.ls];
};
DataPath.RegisterDataPathSpec["MC72",
NEW[DataPath.DPSpecRec ← [
layDWidth: 72* CMosB.lambda,
schDWidth: 9* 4* CMosB.lambda,
layBusW: 8* CMosB.lambda,
schBusW: 4* CMosB.lambda,
metPitch: 8* CMosB.lambda,
met2Pitch: 8* CMosB.lambda,
leftTail: 4* CMosB.lambda, -- to center of 0th bus
rightTail: 4* CMosB.lambda, -- metPitch-leftTail
initialYSize: 3* CMosB.lambda, -- for channel use (=>top
gndBus: 0,
vddBus: 1,
pwrW: 5* CMosB.lambda,
metW: 3* CMosB.lambda,
met2W: 4* CMosB.lambda,
polW: 2* CMosB.lambda,
difW: 2* CMosB.lambda,
pinSize: 2* CMosB.lambda ]]];
END.