TRDataPathImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Don Curry, November 11, 1987 1:36:42 am PST
Last Edited by: Gasbarro February 15, 1988 10:56:21 am PST
DIRECTORY TRDataPath, Core, CoreClasses, CoreOps, CoreProperties, CMosB, DataPath, IO, Ports, Rope, Rosemary, RosemaryUser;
TRDataPathImpl: CEDAR PROGRAM
IMPORTS CoreClasses, CoreOps, CoreProperties, DataPath, IO, Ports, Rosemary, RosemaryUser
EXPORTS TRDataPath =
BEGIN
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.ROPEIO.PutFR["%g%gx%g",
IO.rope[CoreClasses.transistorTypeNames[type]],
IO.int[length],
IO.int[width]];
cellType ← CoreClasses.CreateTransistor[type, length, width, name]
};
DPEdgeFF, DPEdgeFFTop
DPEdgeFFName: Rope.ROPE = Rosemary.Register[roseClassName: "DPEdgeFFSeq", init: DPEdgeFFSeqInit, evalSimple: DPEdgeFFSeqSimple, scheduleIfClockEval: TRUE];
DPEdgeFFTopName: Rope.ROPE = Rosemary.Register[roseClassName: "DPEdgeFFTopSeq", 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];
};
DPInv
DPInvName: Rope.ROPE = Rosemary.Register[roseClassName: "DPInvSeq", init: DPInvSeqInit, evalSimple: DPInvSeqSimple];
DPInvSeqState: TYPE = REF DPInvSeqStateRec;
DPInvSeqStateRec: TYPE = RECORD [
in0, out0: Ports.Port];
DPInvSeqInit: Rosemary.InitProc = {
state: DPInvSeqState ← IF oldStateAny=NIL THEN NEW[DPInvSeqStateRec] ELSE NARROW[oldStateAny];
state.in0 ← p[Ports.PortIndex[cellType.public, "in0"]];
state.out0 ← p[Ports.PortIndex[cellType.public, "out0"]];
state.out0.d ← drive;
stateAny ← state;
};
DPInvSeqSimple: Rosemary.EvalProc = {
state: DPInvSeqState ← NARROW[stateAny];
Ports.NotLS[state.in0.ls, state.out0.ls];
};
DPAnd2
DPAnd2Name: Rope.ROPE = Rosemary.Register[roseClassName: "DPAnd2Seq", init: DPAnd2SeqInit, evalSimple: DPAnd2SeqSimple];
DPAnd2SeqState: TYPE = REF DPAnd2SeqStateRec;
DPAnd2SeqStateRec: TYPE = RECORD [
in0, en, out0: Ports.Port];
DPAnd2SeqInit: Rosemary.InitProc = {
state: DPAnd2SeqState ← IF oldStateAny=NIL THEN NEW[DPAnd2SeqStateRec] ELSE NARROW[oldStateAny];
state.in0 ← p[Ports.PortIndex[cellType.public, "in0"]];
state.en ← p[Ports.PortIndex[cellType.public, "en"]];
state.out0 ← p[Ports.PortIndex[cellType.public, "out0"]];
state.out0.d ← drive;
stateAny ← state;
};
DPAnd2SeqSimple: Rosemary.EvalProc = {
state: DPAnd2SeqState ← NARROW[stateAny];
SELECT TRUE FROM
state.en.l=H => Ports.CopyLS[state.in0.ls, state.out0.ls];
state.en.l=L => Ports.SetLS[state.out0.ls, L];
state.en.l=X => Ports.SetLS[state.out0.ls, X];
ENDCASE => ERROR;
};
DPNor2
DPNor2Name: Rope.ROPE = Rosemary.Register[roseClassName: "DPNor2Seq", init: DPNor2SeqInit, evalSimple: DPNor2SeqSimple];
DPNor2SeqState: TYPE = REF DPNor2SeqStateRec;
DPNor2SeqStateRec: TYPE = RECORD [
in0, in1, out0: Ports.Port];
DPNor2SeqInit: Rosemary.InitProc = {
state: DPNor2SeqState ← IF oldStateAny=NIL THEN NEW[DPNor2SeqStateRec] ELSE NARROW[oldStateAny];
state.in0 ← p[Ports.PortIndex[cellType.public, "in0"]];
state.in1 ← p[Ports.PortIndex[cellType.public, "in1"]];
state.out0 ← p[Ports.PortIndex[cellType.public, "out0"]];
state.out0.d ← drive;
stateAny ← state;
};
DPNor2SeqSimple: Rosemary.EvalProc = {
state: DPNor2SeqState ← NARROW[stateAny];
FOR index: NAT IN [0..state.in0.ls.size) DO
state.out0.ls[index] ← SELECT TRUE FROM
state.in0.ls[index]=L AND state.in1.ls[index]=L => H,
state.in0.ls[index]=H OR state.in1.ls[index]=H => L,
ENDCASE => X;
ENDLOOP;
};
DPWireOr
DPWireOrName: Rope.ROPE = Rosemary.Register[roseClassName: "DPWireOrSeq", init: DPWireOrSeqInit, evalSimple: DPWireOrSeqSimple];
DPWireOrSeqState: TYPE = REF DPWireOrSeqStateRec;
DPWireOrSeqStateRec: TYPE = RECORD [
in, out: Ports.Port,
size: NAT];
DPWireOrSeqInit: Rosemary.InitProc = {
state: DPWireOrSeqState;
IF oldStateAny=NIL THEN {
state ← NEW[DPWireOrSeqStateRec];
state.size ← Ports.Size[p[Ports.PortIndex[cellType.public, "in"]]];
} ELSE state ← NARROW[oldStateAny];
state.in ← p[Ports.PortIndex[cellType.public, "in"]];
state.out ← p[Ports.PortIndex[cellType.public, "out"]];
stateAny ← state;
};
DPWireOrSeqSimple: Rosemary.EvalProc = {
state: DPWireOrSeqState ← NARROW[stateAny];
state.out.d ← none;
FOR i: NAT IN [0..state.size) DO
IF state.in.ls[i] = H THEN {state.out.l ← L; state.out.d ← drive; EXIT};
IF state.in.ls[i] = X THEN {state.out.l ← X; state.out.d ← drive; EXIT};
ENDLOOP;
};
DPWireOrTerm
DPWireOrTermName: Rope.ROPE = Rosemary.Register[roseClassName: "DPWireOrTerm", init: DPWireOrTermInit, evalSimple: DPWireOrTermSimple];
DPWireOrTermState: TYPE = REF DPWireOrTermStateRec;
DPWireOrTermStateRec: TYPE = RECORD [out: Ports.Port];
DPWireOrTermInit: Rosemary.InitProc = {
state: DPWireOrTermState ← IF oldStateAny=NIL THEN NEW[DPWireOrTermStateRec] ELSE NARROW[oldStateAny];
stateAny ← state;
};
DPWireOrTermSimple: Rosemary.EvalProc = {
state: DPWireOrTermState ← NARROW[stateAny];
state.out.l ← H;
state.out.d ← driveWeak;
};
DPXOr
DPXOrName: Rope.ROPE = Rosemary.Register[roseClassName: "DPXOrSeq", 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;
};
DPSCTri
DPSCTriName: Rope.ROPE = Rosemary.Register[roseClassName: "DPSCTriSeq", init: DPSCTriSeqInit, evalSimple: DPSCTriSeqSimple];
DPSCTriSeqState: TYPE = REF DPSCTriSeqStateRec;
DPSCTriSeqStateRec: TYPE = RECORD [
in, out, en, dis: Ports.Port];
DPSCTriSeqInit: Rosemary.InitProc = {
state: DPSCTriSeqState ← IF oldStateAny=NIL THEN NEW[DPSCTriSeqStateRec] 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"]];
stateAny ← state;
};
DPSCTriSeqSimple: Rosemary.EvalProc = {
state: DPSCTriSeqState ← 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;
};
DPSCBuf
DPSCBufName: Rope.ROPE = Rosemary.Register[roseClassName: "DPSCBufSeq", init: DPBufSeqInit, evalSimple: DPBufSeqSimple];
DPBufSeqState: TYPE = REF DPBufSeqStateRec;
DPBufSeqStateRec: TYPE = RECORD [
in, out: Ports.Port];
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];
};
CBuf
DPCBufName: Rope.ROPE = Rosemary.Register[roseClassName: "CBufSeq", init: DPCBufSeqInit, evalSimple: DPCBufSeqSimple];
DPCBufSeqState: TYPE = REF DPCBufSeqStateRec;
DPCBufSeqStateRec: TYPE = RECORD [
in, out, en: Ports.Port];
DPCBufSeqInit: Rosemary.InitProc = {
state: DPCBufSeqState ← IF oldStateAny=NIL THEN NEW[DPCBufSeqStateRec] 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"]];
stateAny ← state;
};
DPCBufSeqSimple: Rosemary.EvalProc = {
state: DPCBufSeqState ← NARROW[stateAny];
Ports.CopyLS[state.in.ls, state.out.ls];
state.out.d ← IF state.en.l=H THEN drive ELSE none;
};
CReg
DPCRegName: Rope.ROPE = Rosemary.Register[roseClassName: "CRegSeq", init: DPCRegSeqInit, evalSimple: DPCRegSeqSimple];
DPCRegSeqState: TYPE = REF DPCRegSeqStateRec;
DPCRegSeqStateRec: TYPE = RECORD [
nC, C, Sel, Q: Ports.Port,
slave, nSlave: Ports.LevelSequence,
size: NAT];
DPCRegSeqInit: Rosemary.InitProc = {
state: DPCRegSeqState;
IF oldStateAny=NIL THEN {
state ← NEW[DPCRegSeqStateRec];
state.size ← Ports.Size[p[Ports.PortIndex[cellType.public, "C"]]];
state.slave ← NEW[Ports.LevelSequenceRec[state.size]];
state.nSlave ← NEW[Ports.LevelSequenceRec[state.size]];
} ELSE state ← NARROW[oldStateAny];
state.nC ← p[Ports.PortIndex[cellType.public, "nC"]];
state.C ← p[Ports.PortIndex[cellType.public, "C"]];
state.Sel ← p[Ports.PortIndex[cellType.public, "Sel"]];
state.Q ← p[Ports.PortIndex[cellType.public, "Q"]];
state.Q.d ← drive;
Ports.SetLS[state.slave, X];
Ports.SetLS[state.nSlave, X];
Ports.SetLS[state.Q.ls, X];
stateAny ← state;
};
DPCRegSeqSimple: Rosemary.EvalProc = {
state: DPCRegSeqState ← NARROW[stateAny];
IF state.Sel.l = H THEN {
FOR i: NAT IN [0..state.size) DO
SELECT TRUE FROM
state.C.ls[i]=H AND state.nC.ls[i]=H => { -- read
IF state.slave[i]=H THEN state.nC.ls[i] ← L;
IF state.nSlave[i]=H THEN state.C.ls[i] ← L;
};
state.C.ls[i]=L AND state.nC.ls[i]=H => { -- write 0
state.slave[i] ← L;
state.nSlave[i] ← H;
};
state.C.ls[i]=H AND state.nC.ls[i]=L => { -- write 1
state.slave[i] ← H;
state.nSlave[i] ← L;
};
ENDCASE => { -- LL, LX, XL, HX, XH, XX
state.slave[i] ← X;
state.nSlave[i] ← X;
};
ENDLOOP;
FOR i: NAT IN [0..state.size) DO
state.C.ds[i] ← IF state.nSlave[i] = H THEN drive ELSE driveWeak;
state.nC.ds[i] ← IF state.slave[i] = H THEN drive ELSE driveWeak;
ENDLOOP;
} ELSE {
FOR i: NAT IN [0..state.size) DO
Ports.PutDriveSequence[state.C, i, none];
Ports.PutDriveSequence[state.nC, i, none];
ENDLOOP
};
Ports.CopyLS[state.slave, state.Q.ls];
};
DPDPRamTopWEn
DPDPRamTopWEnName: Rope.ROPE = Rosemary.Register[roseClassName: "DPDPRamTopWEnSeq", init: DPDPRamTopWEnSeqInit, evalSimple: DPDPRamTopWEnSeqSimple];
DPDPRamTopWEnSeqState: TYPE = REF DPDPRamTopWEnSeqStateRec;
DPDPRamTopWEnSeqStateRec: TYPE = RECORD [
DIn, WrEn, nPChg, nB, B: Ports.Port];
DPDPRamTopWEnSeqInit: Rosemary.InitProc = {
state: DPDPRamTopWEnSeqState ← IF oldStateAny=NIL THEN NEW[DPDPRamTopWEnSeqStateRec] ELSE NARROW[oldStateAny];
state.DIn ← p[Ports.PortIndex[cellType.public, "DIn"]];
state.WrEn ← p[Ports.PortIndex[cellType.public, "WrEn"]];
state.nPChg ← p[Ports.PortIndex[cellType.public, "nPChg"]];
state.nB ← p[Ports.PortIndex[cellType.public, "nB"]];
state.B ← p[Ports.PortIndex[cellType.public, "B"]];
stateAny ← state;
};
DPDPRamTopWEnSeqSimple: Rosemary.EvalProc = {
state: DPDPRamTopWEnSeqState ← NARROW[stateAny];
IF state.nPChg.l=L THEN {
Ports.SetLS[state.nB.ls, H];
Ports.SetLS[state.B.ls, H];
state.nB.d ← driveWeak;
state.B.d ← driveWeak;
};
IF state.WrEn.l=H THEN {
Ports.NotLS[state.DIn.ls, state.nB.ls];
Ports.CopyLS[state.DIn.ls, state.B.ls];
state.nB.d ← drive;
state.B.d ← drive;
};
IF state.WrEn.l#H AND state.nPChg.l#L THEN {
state.nB.d ← none;
state.B.d ← none;
};
};
DPDPRamTop
DPDPRamTopName: Rope.ROPE = Rosemary.Register[roseClassName: "DPDPRamTopSeq", init: DPDPRamTopSeqInit, evalSimple: DPDPRamTopSeqSimple];
DPDPRamTopSeqState: TYPE = REF DPDPRamTopSeqStateRec;
DPDPRamTopSeqStateRec: TYPE = RECORD [
DIn, nB, B: Ports.Port];
DPDPRamTopSeqInit: Rosemary.InitProc = {
state: DPDPRamTopSeqState ← IF oldStateAny=NIL THEN NEW[DPDPRamTopSeqStateRec] ELSE NARROW[oldStateAny];
state.DIn ← p[Ports.PortIndex[cellType.public, "DIn"]];
state.nB ← p[Ports.PortIndex[cellType.public, "nB"]];
state.B ← p[Ports.PortIndex[cellType.public, "B"]];
state.nB.d ← drive;
state.B.d ← drive;
stateAny ← state;
};
DPDPRamTopSeqSimple: Rosemary.EvalProc = {
state: DPDPRamTopSeqState ← NARROW[stateAny];
Ports.NotLS[state.DIn.ls, state.nB.ls];
Ports.CopyLS[state.DIn.ls, state.B.ls];
};
DPDPRamBit
DPDPRamBitName: Rope.ROPE = Rosemary.Register[roseClassName: "DPDPRamBitSeq", init: DPDPRamBitSeqInit, evalSimple: DPDPRamBitSeqSimple];
DPDPRamBitSeqState: TYPE = REF DPDPRamBitSeqStateRec;
DPDPRamBitSeqStateRec: TYPE = RECORD [
RB, nB, B, Wr, Rd: Ports.Port,
slave, nSlave: Ports.LevelSequence,
size: NAT];
DPDPRamBitSeqInit: Rosemary.InitProc = {
state: DPDPRamBitSeqState;
IF oldStateAny=NIL THEN {
state ← NEW[DPDPRamBitSeqStateRec];
state.size ← Ports.Size[p[Ports.PortIndex[cellType.public, "RB"]]];
state.slave ← NEW[Ports.LevelSequenceRec[state.size]];
state.nSlave ← NEW[Ports.LevelSequenceRec[state.size]];
} ELSE state ← NARROW[oldStateAny];
state.RB ← p[Ports.PortIndex[cellType.public, "RB"]];
state.nB ← p[Ports.PortIndex[cellType.public, "nB"]];
state.B ← p[Ports.PortIndex[cellType.public, "B"]];
state.Wr ← p[Ports.PortIndex[cellType.public, "Wr"]];
state.Rd ← p[Ports.PortIndex[cellType.public, "Rd"]];
Ports.SetLS[state.slave, X];
Ports.SetLS[state.nSlave, X];
CoreProperties.PutCellTypeProp[cellType, RosemaryUser.stateToMaxCharsProcProp, NEW[RosemaryUser.StateToMaxCharsProc ← DPDPRamStateToMaxChars]];
CoreProperties.PutCellTypeProp[cellType, RosemaryUser.stateToRopeProcProp, NEW[RosemaryUser.StateToRopeProc ← DPDPRamStateToRope]];
stateValue ← state.slave;
stateAny ← state;
};
DPDPRamBitSeqSimple: Rosemary.EvalProc = {
state: DPDPRamBitSeqState ← NARROW[stateAny];
IF state.Wr.l = H THEN {
FOR i: NAT IN [0..state.size) DO
SELECT TRUE FROM
state.B.ls[i]=H AND state.nB.ls[i]=H => { -- read
IF state.slave[i]=H THEN state.nB.ls[i] ← L;
IF state.nSlave[i]=H THEN state.B.ls[i] ← L;
};
state.B.ls[i]=L AND state.nB.ls[i]=H => { -- write 0
state.slave[i] ← L;
state.nSlave[i] ← H;
};
state.B.ls[i]=H AND state.nB.ls[i]=L => { -- write 1
state.slave[i] ← H;
state.nSlave[i] ← L;
};
ENDCASE => { -- LL, LX, XL, HX, XH, XX
state.slave[i] ← X;
state.nSlave[i] ← X;
};
ENDLOOP;
Ports.CopyLS[state.slave, state.B.ls];
Ports.CopyLS[state.nSlave, state.nB.ls];
FOR i: NAT IN [0..state.size) DO
state.B.ds[i] ← IF state.nSlave[i] = H THEN drive ELSE driveWeak;
state.nB.ds[i] ← IF state.slave[i] = H THEN drive ELSE driveWeak;
ENDLOOP;
} ELSE {
FOR i: NAT IN [0..state.size) DO
Ports.PutDriveSequence[state.B, i, none];
Ports.PutDriveSequence[state.nB, i, none];
ENDLOOP;
};
Ports.CopyLS[state.nSlave, state.RB.ls];
FOR i: NAT IN [0..state.size) DO
state.RB.ds[i] ← IF state.RB.ls[i]=L AND state.Rd.l=H THEN drive ELSE none;
ENDLOOP;
stateValue ← state.slave;
};
DPDPRamStateToMaxChars: RosemaryUser.StateToMaxCharsProc = {
state: DPDPRamBitSeqState ← NARROW[stateAny];
maxChars ← (state.size+3)/4 + 1; --round to max number of hex digits
};
DPDPRamStateToRope: RosemaryUser.StateToRopeProc = {
rope ← Ports.LSToRope[value];
};
DPDPRamBot
DPDPRamBotName: Rope.ROPE = Rosemary.Register[roseClassName: "DPDPRamBotSeq", init: DPDPRamBotSeqInit, evalSimple: DPDPRamBotSeqSimple];
DPDPRamBotSeqState: TYPE = REF DPDPRamBotSeqStateRec;
DPDPRamBotSeqStateRec: TYPE = RECORD [
RB, DOut: Ports.Port];
DPDPRamBotSeqInit: Rosemary.InitProc = {
state: DPDPRamBotSeqState ← IF oldStateAny=NIL THEN NEW[DPDPRamBotSeqStateRec] ELSE NARROW[oldStateAny];
state.RB ← p[Ports.PortIndex[cellType.public, "RB"]];
state.DOut ← p[Ports.PortIndex[cellType.public, "DOut"]];
Ports.SetLS[state.RB.ls, H];
state.RB.d ← driveWeak;
state.DOut.d ← drive;
stateAny ← state;
};
DPDPRamBotSeqSimple: Rosemary.EvalProc = {
state: DPDPRamBotSeqState ← NARROW[stateAny];
Ports.NotLS[state.RB.ls, state.DOut.ls];
Ports.SetLS[state.RB.ls, H];
};
DPDecoder
DPDecoderName: Rope.ROPE = Rosemary.Register[roseClassName: "DPDecoderSeq", init: DPDecoderSeqInit, evalSimple: DPDecoderSeqSimple];
DPDecoderSeqState: TYPE = REF DPDecoderSeqStateRec;
DPDecoderSeqStateRec: TYPE = RECORD [
RA, WA, wEn, CK, Rd, Wr: Ports.Port,
size: NAT];
DPDecoderSeqInit: Rosemary.InitProc = {
state: DPDecoderSeqState ← IF oldStateAny=NIL THEN NEW[DPDecoderSeqStateRec] ELSE NARROW[oldStateAny];
state.RA ← p[Ports.PortIndex[cellType.public, "RA"]];
state.WA ← p[Ports.PortIndex[cellType.public, "WA"]];
state.wEn ← p[Ports.PortIndex[cellType.public, "wEn"]];
state.CK ← p[Ports.PortIndex[cellType.public, "CK"]];
state.Rd ← p[Ports.PortIndex[cellType.public, "Rd"]];
state.Wr ← p[Ports.PortIndex[cellType.public, "Wr"]];
state.Rd.d ← drive;
state.Wr.d ← drive;
stateAny ← state;
};
DPDecoderSeqSimple: Rosemary.EvalProc = {
state: DPDecoderSeqState ← NARROW[stateAny];
IF Ports.HasX[state.RA.ls] THEN Ports.SetLS[state.Rd.ls, X] ELSE {
Ports.SetLS[state.Rd.ls, L];
Ports.PutLevelSequence[state.Rd, Ports.LSToC[state.RA.ls], H];
};
IF state.wEn.l = X OR state.CK.l = X OR Ports.HasX[state.WA.ls] THEN Ports.SetLS[state.Wr.ls, X] ELSE {
Ports.SetLS[state.Wr.ls, L];
IF state.wEn.l = H AND state.CK.l = L THEN Ports.PutLevelSequence[state.Wr, Ports.LSToC[state.WA.ls], H];
};
};
Initialization
DataPath.RegisterDataPathSpec["TR72", 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.