DIRECTORY BitOps, CoreClasses, CoreCreate, CoreFlat, CoreProperties, MSI, Ports, Rosemary; MSIImpl: CEDAR PROGRAM IMPORTS BitOps, CoreClasses, CoreCreate, CoreFlat, CoreProperties, Ports, Rosemary EXPORTS MSI = BEGIN OPEN MSI, CoreCreate; XthBitOfN: PROC [x, n: INT] RETURNS [BOOL] ~ { RETURN[BitOps.EBFD[container: n, bitPosition: 31-x]]; }; LatchName: ROPE = Rosemary.Register[roseClassName: "Latch", init: LatchInit, evalSimple: LatchSimple]; LatchVdd: NAT = 0; LatchGnd: NAT = 1; LatchLoad: NAT = 2; LatchInput: NAT = 3; LatchOutput: NAT = 4; Latch: PUBLIC PROC RETURNS [ct: CellType] = { ct _ CoreClasses.CreateUnspecified[ name: LatchName, public: Wires["Vdd", "Gnd", "Load", "Input", "Output"]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: LatchName]; [] _ CoreFlat.CellTypeCutLabels[ct, "MSI"]; [] _ Ports.InitPort[wire: ct.public[LatchVdd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[LatchGnd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[LatchLoad], levelType: l]; [] _ Ports.InitPort[wire: ct.public[LatchInput], levelType: l]; [] _ Ports.InitPort[wire: ct.public[LatchOutput], levelType: l, initDrive: drive]; }; LatchInit: Rosemary.InitProc = { state: REF Ports.Level _ NEW[Ports.Level]; state^ _ X; stateAny _ state; }; LatchSimple: Rosemary.EvalProc = { state: REF Ports.Level _ NARROW[stateAny]; SELECT p[LatchLoad].l FROM H => state^ _ p[LatchInput].l; X => IF state^#p[LatchInput].l THEN state^ _ X; ENDCASE; p[LatchOutput].l _ state^; }; RegisterName: ROPE = Rosemary.Register[roseClassName: "Register", init: RegisterInit, evalSimple: RegisterSimple]; RegVdd: NAT = 0; RegGnd: NAT = 1; RegLoad: NAT = 2; RegInput: NAT = 3; RegOutput: NAT = 4; Register: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { ct _ CoreClasses.CreateUnspecified[ name: RegisterName, public: Wires["Vdd", "Gnd", "Load", Seq["Input", b], Seq["Output", b]]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: RegisterName]; [] _ CoreFlat.CellTypeCutLabels[ct, "MSI"]; [] _ Ports.InitPort[wire: ct.public[RegVdd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[RegGnd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[RegInput], levelType: ls]; [] _ Ports.InitPort[wire: ct.public[RegLoad], levelType: l]; [] _ Ports.InitPort[wire: ct.public[RegOutput], levelType: ls, initDrive: drive]; }; RegisterInit: Rosemary.InitProc = { size: NAT _ p[RegInput].ls.size; state: Ports.LevelSequence _ NEW[Ports.LevelSequenceRec[size]]; FOR i: NAT IN [0..size) DO state[i] _ X; ENDLOOP; stateAny _ state; }; RegisterSimple: Rosemary.EvalProc = { state: Ports.LevelSequence _ NARROW[stateAny]; SELECT p[RegLoad].l FROM H => FOR i: NAT IN [0..p[RegInput].ls.size) DO state[i] _ p[RegInput].ls[i]; ENDLOOP; X => FOR i: NAT IN [0..p[RegInput].ls.size) DO IF state[i]#p[RegInput].ls[i] THEN state[i] _ X; ENDLOOP; ENDCASE; FOR i: NAT IN [0..p[RegOutput].ls.size) DO p[RegOutput].ls[i] _ state[i]; ENDLOOP; }; ConstantName: ROPE = Rosemary.Register[roseClassName: "Constant", init: ConstantInit, evalSimple: ConstantSimple]; ConstantProp: ATOM = CoreProperties.RegisterProperty[prop: $MSIConstant]; ConstantVdd: NAT = 0; ConstantGnd: NAT = 1; ConstantOutput: NAT = 2; Constant: PUBLIC PROC [b: NAT, v: INT] RETURNS [ct: CellType] = { ct _ CoreClasses.CreateUnspecified[ name: ConstantName, public: Wires["Vdd", "Gnd", Seq["Output", b]]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: ConstantName]; [] _ CoreFlat.CellTypeCutLabels[ct, "MSI"]; [] _ Ports.InitPort[wire: ct.public[ConstantVdd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[ConstantGnd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[ConstantOutput], levelType: ls, initDrive: drive]; CoreProperties.PutCellTypeProp[ct, ConstantProp, NEW[INT _ v]]; }; ConstantInit: Rosemary.InitProc = { stateAny _ CoreProperties.GetCellTypeProp[cellType, ConstantProp]; }; ConstantSimple: Rosemary.EvalProc = { state: REF INT _ NARROW[stateAny]; bits: NAT _ p[ConstantOutput].ls.size; FOR i: NAT IN [0..bits) DO p[ConstantOutput].ls[i] _ IF XthBitOfN[x: bits-1-i, n: state^] THEN H ELSE L; ENDLOOP; }; MultiplexorName: ROPE = Rosemary.Register[roseClassName: "Multiplexor", evalSimple: MultiplexorSimple]; MultiplexorSelect: NAT = 0; MultiplexorInput: NAT = 1; MultiplexorOutput: NAT = 2; Multiplexor: PUBLIC PROC [i: NAT _ 2] RETURNS [ct: CellType] = { ct _ CoreClasses.CreateUnspecified[ name: MultiplexorName, public: Wires[Seq["Select", i], Seq["Input", i], "Output"]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: MultiplexorName]; [] _ CoreFlat.CellTypeCutLabels[ct, "MSI"]; [] _ Ports.InitPort[wire: ct.public[MultiplexorSelect], levelType: ls]; [] _ Ports.InitPort[wire: ct.public[MultiplexorInput], levelType: ls]; [] _ Ports.InitPort[wire: ct.public[MultiplexorOutput], levelType: l, initDrive: drive]; }; MultiplexorSimple: Rosemary.EvalProc = { foundH: BOOL _ FALSE; FOR i: NAT IN [0..p[MultiplexorSelect].ls.size) DO SELECT p[MultiplexorSelect].ls[i] FROM X => {p[MultiplexorOutput].l _ X; EXIT}; H => IF foundH THEN {p[MultiplexorOutput].l _ X; EXIT} ELSE { foundH _ TRUE; p[MultiplexorOutput].l _ p[MultiplexorInput].ls[i]; }; ENDCASE; ENDLOOP; IF NOT foundH THEN p[MultiplexorOutput].l _ X; }; BusMultiplexorName: ROPE = Rosemary.Register[roseClassName: "BusMultiplexor", evalSimple: BusMultiplexorSimple]; BusMultiplexorSelect: NAT = 0; BusMultiplexorInput: NAT = 1; BusMultiplexorOutput: NAT = 2; BusMultiplexor: PUBLIC PROC [b: NAT, i: NAT _ 2] RETURNS [ct: CellType] = { ct _ CoreClasses.CreateUnspecified[ name: BusMultiplexorName, public: Wires[Seq["Select", i], Seq["Input", i, Seq[size: b]], Seq["Output", b]]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: BusMultiplexorName]; [] _ CoreFlat.CellTypeCutLabels[ct, "MSI"]; [] _ Ports.InitPort[wire: ct.public[BusMultiplexorSelect], levelType: ls]; FOR in: NAT IN [0..i) DO [] _ Ports.InitPort[wire: ct.public[BusMultiplexorInput][in], levelType: ls]; ENDLOOP; [] _ Ports.InitPort[wire: ct.public[BusMultiplexorOutput], levelType: ls, initDrive: drive]; }; BusMultiplexorSimple: Rosemary.EvalProc = { SetX: PROC = { FOR bit: NAT IN [0..p[BusMultiplexorOutput].ls.size) DO p[BusMultiplexorOutput].ls[bit] _ X; ENDLOOP; }; foundH: BOOL _ FALSE; FOR i: NAT IN [0..p[BusMultiplexorSelect].ls.size) DO SELECT p[BusMultiplexorSelect].ls[i] FROM X => {SetX[]; EXIT}; H => IF foundH THEN {SetX[]; EXIT} ELSE { foundH _ TRUE; FOR bit: NAT IN [0..p[BusMultiplexorOutput].ls.size) DO p[BusMultiplexorOutput].ls[bit] _ p[BusMultiplexorInput][i].ls[bit]; ENDLOOP; }; ENDCASE; ENDLOOP; IF NOT foundH THEN SetX[]; }; BuffersName: ROPE = Rosemary.Register[roseClassName: "Buffers", evalSimple: BuffersSimple]; BuffersVdd: NAT = 0; BuffersGnd: NAT = 1; BuffersInput: NAT = 2; BuffersOutput: NAT = 3; Buffers: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { ct _ CoreClasses.CreateUnspecified[ name: BuffersName, public: Wires["Vdd", "Gnd", Seq["Input", b], Seq["Output", b]]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: BuffersName]; [] _ CoreFlat.CellTypeCutLabels[ct, "MSI"]; [] _ Ports.InitPort[wire: ct.public[BuffersVdd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[BuffersGnd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[BuffersInput], levelType: ls]; [] _ Ports.InitPort[wire: ct.public[BuffersOutput], levelType: ls, initDrive: drive]; }; BuffersSimple: Rosemary.EvalProc = { FOR i: NAT IN [0..p[BuffersInput].ls.size) DO p[BuffersOutput].ls[i] _ p[BuffersInput].ls[i]; ENDLOOP; }; TristateBuffersName: ROPE = Rosemary.Register[roseClassName: "TristateBuffers", evalSimple: TristateBuffersSimple]; TristateBuffersVdd: NAT = 0; TristateBuffersGnd: NAT = 1; TristateBuffersDrive: NAT = 2; TristateBuffersInput: NAT = 3; TristateBuffersOutput: NAT = 4; TristateBuffers: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { ct _ CoreClasses.CreateUnspecified[ name: TristateBuffersName, public: Wires["Vdd", "Gnd", "Drive", Seq["Input", b], Seq["Output", b]]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: TristateBuffersName]; [] _ CoreFlat.CellTypeCutLabels[ct, "MSI"]; [] _ Ports.InitPort[wire: ct.public[TristateBuffersVdd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[TristateBuffersGnd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[TristateBuffersDrive], levelType: l]; [] _ Ports.InitPort[wire: ct.public[TristateBuffersInput], levelType: ls]; [] _ Ports.InitPort[wire: ct.public[TristateBuffersOutput], levelType: ls]; }; TristateBuffersSimple: Rosemary.EvalProc = { p[TristateBuffersOutput].d _ IF p[TristateBuffersDrive].l#L THEN drive ELSE none; FOR i: NAT IN [0..p[TristateBuffersInput].ls.size) DO p[TristateBuffersOutput].ls[i] _ p[TristateBuffersInput].ls[i]; ENDLOOP; }; AdderName: ROPE = Rosemary.Register[roseClassName: "Adder", evalSimple: AdderSimple]; AdderVdd: NAT = 0; AdderGnd: NAT = 1; AdderCarryIn: NAT = 2; AdderA: NAT = 3; AdderB: NAT = 4; AdderSum: NAT = 5; AdderCarryOut: NAT = 6; Adder: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { ct _ CoreClasses.CreateUnspecified[ name: AdderName, public: Wires["Vdd", "Gnd", "CarryIn", Seq["A", b], Seq["B", b], Seq["Sum", b], "CarryOut"]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: AdderName]; [] _ CoreFlat.CellTypeCutLabels[ct, "MSI"]; [] _ Ports.InitPort[wire: ct.public[AdderVdd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[AdderGnd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[AdderCarryIn], levelType: l]; [] _ Ports.InitPort[wire: ct.public[AdderA], levelType: ls]; [] _ Ports.InitPort[wire: ct.public[AdderB], levelType: ls]; [] _ Ports.InitPort[wire: ct.public[AdderSum], levelType: ls, initDrive: drive]; [] _ Ports.InitPort[wire: ct.public[AdderCarryOut], levelType: l, initDrive: drive]; }; AdderSimple: Rosemary.EvalProc = { carry: Ports.Level _ p[AdderCarryIn].l; FOR i: NAT DECREASING IN [0..p[AdderA].ls.size) DO a: Ports.Level _ p[AdderA].ls[i]; b: Ports.Level _ p[AdderB].ls[i]; IF carry=X OR a=X OR b=X THEN { p[AdderSum].ls[i] _ X; carry _ X; } ELSE { ba: BOOL _ IF a=H THEN TRUE ELSE FALSE; bb: BOOL _ IF b=H THEN TRUE ELSE FALSE; bc: BOOL _ IF carry=H THEN TRUE ELSE FALSE; p[AdderSum].ls[i] _ IF BXor[ba, BXor[bb, bc]] THEN H ELSE L; carry _ IF (ba AND (bb OR bc)) OR (bb AND bc) THEN H ELSE L; }; ENDLOOP; p[AdderCarryOut].l _ carry; }; ComparatorName: ROPE = Rosemary.Register[roseClassName: "Comparator", evalSimple: ComparatorSimple]; CmpVdd: NAT = 0; CmpGnd: NAT = 1; CmpA: NAT = 2; CmpB: NAT = 3; CmpAEqB: NAT = 4; Comparator: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { ct _ CoreClasses.CreateUnspecified[ name: ComparatorName, public: Wires["Vdd", "Gnd", Seq["A", b], Seq["B", b], "AEqB"]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: ComparatorName]; [] _ CoreFlat.CellTypeCutLabels[ct, "MSI"]; [] _ Ports.InitPort[wire: ct.public[CmpVdd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[CmpGnd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[CmpA], levelType: ls]; [] _ Ports.InitPort[wire: ct.public[CmpB], levelType: ls]; [] _ Ports.InitPort[wire: ct.public[CmpAEqB], levelType: l, initDrive: drive]; }; ComparatorSimple: Rosemary.EvalProc = { p[CmpAEqB].l _ H; FOR i: NAT IN [0..p[CmpA].ls.size) DO IF p[CmpA].ls[i]#p[CmpB].ls[i] THEN p[CmpAEqB].l _ L; IF p[CmpA].ls[i]=X OR p[CmpB].ls[i]=X THEN {p[CmpAEqB].l _ X; EXIT}; ENDLOOP; }; DecoderName: ROPE = Rosemary.Register[roseClassName: "Decoder", evalSimple: DecoderSimple]; DecoderVdd: NAT = 0; DecoderGnd: NAT = 1; DecoderAddress: NAT = 2; DecoderSelect: NAT = 3; ClockedDecoderClock: NAT = 4; Decoder: PUBLIC PROC [a: NAT, s: NAT _ 0] RETURNS [ct: CellType] = { IF s=0 THEN s _ BitOps.TwoToThe[a]; ct _ CoreClasses.CreateUnspecified[ name: DecoderName, public: Wires["Vdd", "Gnd", Seq["Address", a], Seq["Select", s]]]; InitDecoder[ct]; }; ClockedDecoder: PUBLIC PROC [a: NAT, s: NAT _ 0] RETURNS [ct: CellType] = { IF s=0 THEN s _ BitOps.TwoToThe[a]; ct _ CoreClasses.CreateUnspecified[ name: "ClockedDecoder", public: Wires["Vdd", "Gnd", Seq["Address", a], Seq["Select", s], "Clock"]]; InitDecoder[ct]; [] _ Ports.InitPort[wire: ct.public[ClockedDecoderClock], levelType: l]; }; InitDecoder: PROC [ct: CellType] = { [] _ Rosemary.BindCellType[cellType: ct, roseClassName: DecoderName]; [] _ CoreFlat.CellTypeCutLabels[ct, "MSI"]; [] _ Ports.InitPort[wire: ct.public[DecoderVdd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[DecoderGnd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[DecoderAddress], levelType: ls]; [] _ Ports.InitPort[wire: ct.public[DecoderSelect], levelType: ls, initDrive: drive]; }; DecoderSimple: Rosemary.EvalProc = { SetLevel: PROC[l: Ports.Level] = { FOR i: NAT IN [0..p[DecoderSelect].ls.size) DO p[DecoderSelect].ls[i] _ l; ENDLOOP; }; clocked: BOOL _ p.size-1=ClockedDecoderClock; IF clocked AND p[ClockedDecoderClock].l=X THEN SetLevel[X] ELSE { SetLevel[L]; IF NOT clocked OR p[ClockedDecoderClock].l=H THEN { bits: NAT _ p[DecoderAddress].ls.size; address: NAT _ 0; FOR i: NAT IN [0..bits) DO SELECT p[DecoderAddress].ls[i] FROM L => address _ 2*address; H => address _ (2*address) + 1; X => SetLevel[X]; ENDCASE => ERROR; ENDLOOP; IF address>p[DecoderSelect].ls.size THEN SIGNAL Rosemary.Stop[]; p[DecoderSelect].ls[address] _ H; }; }; }; ShiftRegisterName: ROPE = Rosemary.Register[roseClassName: "ShiftRegister", init: ShiftRegisterInit, evalSimple: ShiftRegisterSimple]; ShiftRegisterVdd: NAT = 0; ShiftRegisterGnd: NAT = 1; ShiftRegisterShiftA: NAT = 2; ShiftRegisterShiftB: NAT = 3; ShiftRegisterLoadA: NAT = 4; ShiftRegisterLeftNRight: NAT = 5; ShiftRegisterLeftInput: NAT = 6; ShiftRegisterRightInput: NAT = 7; ShiftRegisterInput: NAT = 8; ShiftRegisterOutput: NAT = 9; ShiftRegister: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { ct _ CoreClasses.CreateUnspecified[ name: ShiftRegisterName, public: Wires["Vdd", "Gnd", "ShiftA", "ShiftB", "LoadA", "LeftNRight", "LeftInput", "RightInput", Seq["Input", b], Seq["Output", b]]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: ShiftRegisterName]; [] _ CoreFlat.CellTypeCutLabels[ct, "MSI"]; [] _ Ports.InitPort[wire: ct.public[ShiftRegisterVdd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[ShiftRegisterGnd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[ShiftRegisterShiftA], levelType: l]; [] _ Ports.InitPort[wire: ct.public[ShiftRegisterShiftB], levelType: l]; [] _ Ports.InitPort[wire: ct.public[ShiftRegisterLoadA], levelType: l]; [] _ Ports.InitPort[wire: ct.public[ShiftRegisterLeftNRight], levelType: l]; [] _ Ports.InitPort[wire: ct.public[ShiftRegisterLeftInput], levelType: l]; [] _ Ports.InitPort[wire: ct.public[ShiftRegisterRightInput], levelType: l]; [] _ Ports.InitPort[wire: ct.public[ShiftRegisterInput], levelType: ls]; [] _ Ports.InitPort[wire: ct.public[ShiftRegisterOutput], levelType: ls, initDrive: drive]; }; ShiftRegisterState: TYPE = REF ShiftRegisterStateRec; ShiftRegisterStateRec: TYPE = RECORD [ a: Ports.LevelSequence _ NIL, b: Ports.LevelSequence _ NIL]; ShiftRegisterInit: Rosemary.InitProc = { state: ShiftRegisterState _ NEW[ShiftRegisterStateRec]; size: NAT _ p[ShiftRegisterOutput].ls.size; state.a _ NEW[Ports.LevelSequenceRec[size]]; state.b _ NEW[Ports.LevelSequenceRec[size]]; FOR i: NAT IN [0..size) DO state.a[i] _ state.b[i] _ X; ENDLOOP; stateAny _ state; }; ShiftRegisterSimple: Rosemary.EvalProc = { SetX: PROC = { FOR bit: NAT IN [0..sizeMOne] DO state.a[bit] _ state.b[bit] _ p[ShiftRegisterOutput].ls[bit] _ X; ENDLOOP; }; state: ShiftRegisterState _ NARROW[stateAny]; sizeMOne: NAT _ p[ShiftRegisterInput].ls.size-1; IF p[ShiftRegisterShiftA].l=X OR p[ShiftRegisterShiftB].l=X OR p[ShiftRegisterLoadA].l=X OR (p[ShiftRegisterShiftA].l#L AND p[ShiftRegisterLoadA].l#L) THEN SetX[] ELSE { IF p[ShiftRegisterShiftA].l=H THEN { IF p[ShiftRegisterLeftNRight].l=X THEN SetX[] ELSE { IF p[ShiftRegisterLeftNRight].l=H THEN { FOR i: NAT IN [0..sizeMOne) DO state.a[i] _ state.b[i+1]; ENDLOOP; state.a[sizeMOne] _ p[ShiftRegisterRightInput].l; } ELSE { FOR i: NAT DECREASING IN [0..sizeMOne) DO state.a[i+1] _ state.b[i]; ENDLOOP; state.a[0] _ p[ShiftRegisterLeftInput].l; }; }; }; IF p[ShiftRegisterLoadA].l=H THEN { FOR i: NAT IN [0..sizeMOne] DO state.a[i] _ p[ShiftRegisterInput].ls[i]; ENDLOOP; }; IF p[ShiftRegisterShiftB].l=H THEN { FOR i: NAT IN [0..sizeMOne] DO state.b[i] _ state.a[i]; ENDLOOP; }; FOR i: NAT IN [0..sizeMOne] DO p[ShiftRegisterOutput].ls[i] _ state.b[i]; ENDLOOP; }; }; CounterName: ROPE = Rosemary.Register[roseClassName: "Counter", init: CounterInit, evalSimple: CounterSimple]; CounterVdd: NAT = 0; CounterGnd: NAT = 1; CounterCountA: NAT = 2; CounterCountB: NAT = 3; CounterLoadA: NAT = 4; CounterUpNDown: NAT = 5; CounterInput: NAT = 6; CounterOutput: NAT = 7; Counter: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { ct _ CoreClasses.CreateUnspecified[ name: CounterName, public: Wires["Vdd", "Gnd", "CountA", "CountB", "LoadA", "UpNDown", Seq["Input", b], Seq["Output", b]]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: CounterName]; [] _ CoreFlat.CellTypeCutLabels[ct, "MSI"]; [] _ Ports.InitPort[wire: ct.public[CounterVdd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[CounterGnd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[CounterCountA], levelType: l]; [] _ Ports.InitPort[wire: ct.public[CounterCountB], levelType: l]; [] _ Ports.InitPort[wire: ct.public[CounterLoadA], levelType: l]; [] _ Ports.InitPort[wire: ct.public[CounterUpNDown], levelType: l]; [] _ Ports.InitPort[wire: ct.public[CounterInput], levelType: ls]; [] _ Ports.InitPort[wire: ct.public[CounterOutput], levelType: ls, initDrive: drive]; }; CounterState: TYPE = REF CounterStateRec; CounterStateRec: TYPE = RECORD [ a: Ports.LevelSequence _ NIL, b: Ports.LevelSequence _ NIL]; CounterInit: Rosemary.InitProc = { state: CounterState _ NEW[CounterStateRec]; size: NAT _ p[CounterOutput].ls.size; state.a _ NEW[Ports.LevelSequenceRec[size]]; state.b _ NEW[Ports.LevelSequenceRec[size]]; FOR i: NAT IN [0..size) DO state.a[i] _ state.b[i] _ X; ENDLOOP; stateAny _ state; }; CounterSimple: Rosemary.EvalProc = { SetX: PROC = { FOR bit: NAT IN [0..size) DO state.a[bit] _ state.b[bit] _ p[CounterOutput].ls[bit] _ X; ENDLOOP; }; state: CounterState _ NARROW[stateAny]; size: NAT _ p[CounterInput].ls.size; IF p[CounterCountA].l=X OR p[CounterCountB].l=X OR p[CounterLoadA].l=X OR (p[CounterCountA].l#L AND p[CounterLoadA].l#L) THEN SetX[] ELSE { IF p[CounterCountA].l=H THEN { IF p[CounterUpNDown].l=X THEN SetX[] ELSE { IF p[CounterUpNDown].l=H THEN { carry: Ports.Level _ H; FOR i: NAT DECREASING IN [0..size) DO state.a[i] _ IF carry=X OR state.b[i]=X THEN X ELSE IF BXor[carry=H, state.b[i]=H] THEN H ELSE L; carry _ IF carry=X OR state.b[i]=X THEN X ELSE IF carry=H AND state.b[i]=H THEN H ELSE L; ENDLOOP; } ELSE { borrow: Ports.Level _ H; FOR i: NAT DECREASING IN [0..size) DO state.a[i] _ IF borrow=X OR state.b[i]=X THEN X ELSE IF BXor[borrow=H, state.b[i]=H] THEN H ELSE L; borrow _ IF borrow=X OR state.b[i]=X THEN X ELSE IF borrow=H AND state.b[i]=L THEN H ELSE L; ENDLOOP; }; }; }; IF p[CounterLoadA].l=H THEN { FOR i: NAT IN [0..size) DO state.a[i] _ p[CounterInput].ls[i]; ENDLOOP; }; IF p[CounterCountB].l=H THEN { FOR i: NAT IN [0..size) DO state.b[i] _ state.a[i]; ENDLOOP; }; FOR i: NAT IN [0..size) DO p[CounterOutput].ls[i] _ state.b[i]; ENDLOOP; }; }; RegisterFileName: ROPE = Rosemary.Register[roseClassName: "RegisterFile", init: RegisterFileInit, evalSimple: RegisterFileSimple]; RegisterFileProp: ATOM = CoreProperties.RegisterProperty[prop: $MSIRegisterFile]; RegisterFileVdd: NAT = 0; RegisterFileGnd: NAT = 1; RegisterFileLoad: NAT = 2; RegisterFileAddress: NAT = 3; RegisterFileInput: NAT = 4; RegisterFileOutput: NAT = 5; RegisterFile: PUBLIC PROC [b: NAT, a: NAT, w: NAT _ 0] RETURNS [ct: CellType] = { ct _ CoreClasses.CreateUnspecified[ name: RegisterFileName, public: Wires["Vdd", "Gnd", "Load", Seq["Address", a], Seq["Input", b], Seq["Output", b]]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: RegisterFileName]; [] _ CoreFlat.CellTypeCutLabels[ct, "MSI"]; [] _ Ports.InitPort[wire: ct.public[RegisterFileVdd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[RegisterFileGnd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[RegisterFileLoad], levelType: l]; [] _ Ports.InitPort[wire: ct.public[RegisterFileAddress], levelType: ls]; [] _ Ports.InitPort[wire: ct.public[RegisterFileInput], levelType: ls]; [] _ Ports.InitPort[wire: ct.public[RegisterFileOutput], levelType: ls, initDrive: drive]; IF w=0 THEN w _ BitOps.TwoToThe[a]; CoreProperties.PutCellTypeProp[ct, RegisterFileProp, NEW[NAT _ w]]; }; RegisterFileState: TYPE = REF RegisterFileStateRec; RegisterFileStateRec: TYPE = RECORD [ bits: SEQUENCE size: NAT OF Ports.LevelSequence]; RegisterFileInit: Rosemary.InitProc = { words: NAT _ NARROW[CoreProperties.GetCellTypeProp[cellType, RegisterFileProp], REF NAT]^; bits: NAT _ p[RegisterFileOutput].ls.size; state: RegisterFileState _ NEW[RegisterFileStateRec[words]]; FOR w: NAT IN [0..words) DO state[w] _ NEW[Ports.LevelSequenceRec[bits]]; FOR b: NAT IN [0..bits) DO state[w][b] _ X; ENDLOOP; ENDLOOP; stateAny _ state; }; RegisterFileSimple: Rosemary.EvalProc = { state: RegisterFileState _ NARROW[stateAny]; words: NAT _ state.size; bits: NAT _ p[RegisterFileOutput].ls.size; adr: NAT _ 0; FOR a: NAT IN [0..p[RegisterFileAddress].ls.size) DO aBit: Ports.Level _ p[RegisterFileAddress].ls[a]; IF aBit=X THEN { IF p[RegisterFileLoad].l#L THEN FOR w: NAT IN [0..words) DO FOR b: NAT IN [0..bits) DO state[w][b] _ X; ENDLOOP; ENDLOOP; FOR b: NAT IN [0..bits) DO p[RegisterFileOutput].ls[b] _ X; ENDLOOP; EXIT; } ELSE adr _ 2*adr + (IF p[RegisterFileAddress].ls[a]=H THEN 1 ELSE 0); REPEAT FINISHED => { IF p[RegisterFileLoad].l=H THEN FOR b: NAT IN [0..bits) DO state[adr][b] _ p[RegisterFileInput].ls[b]; ENDLOOP ELSE IF p[RegisterFileLoad].l=X THEN FOR b: NAT IN [0..bits) DO state[adr][b] _ X; ENDLOOP; FOR b: NAT IN [0..bits) DO p[RegisterFileOutput].ls[b] _ state[adr][b]; ENDLOOP; } ENDLOOP; }; MultiPortRegisterFileName: ROPE = Rosemary.Register[roseClassName: "MultiPortRegisterFile", init: MultiPortRegisterFileInit, evalSimple: MultiPortRegisterFileSimple]; MultiPortRegisterFileProp: ATOM = CoreProperties.RegisterProperty[prop: $MSIMultiPortRegisterFile]; MultiPortRegisterFileVdd: NAT = 0; MultiPortRegisterFileGnd: NAT = 1; MultiPortRegisterFileLoad: NAT = 2; MultiPortRegisterFileWriteAddress: NAT = 3; MultiPortRegisterFileReadAddress: NAT = 4; MultiPortRegisterFileInput: NAT = 5; MultiPortRegisterFileOutput: NAT = 6; MultiPortRegisterFile: PUBLIC PROC [b: NAT, a: NAT, w: NAT _ 0, rp: NAT _ 1, wp: NAT _ 1] RETURNS [ct: CellType] = { ct _ CoreClasses.CreateUnspecified[ name: MultiPortRegisterFileName, public: Wires["Vdd", "Gnd", Seq["Load", wp], Seq["WriteAddress", wp, Seq[size: a]], Seq["ReadAddress", rp, Seq[size: a]], Seq["Input", wp, Seq[size: b]], Seq["Output", rp, Seq[size: b]]]]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: MultiPortRegisterFileName]; [] _ CoreFlat.CellTypeCutLabels[ct, "MSI"]; [] _ Ports.InitPort[wire: ct.public[MultiPortRegisterFileVdd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[MultiPortRegisterFileGnd], levelType: l]; [] _ Ports.InitPort[wire: ct.public[MultiPortRegisterFileLoad], levelType: ls]; FOR port: NAT IN [0..wp) DO [] _ Ports.InitPort[wire: ct.public[MultiPortRegisterFileWriteAddress][port], levelType: ls]; [] _ Ports.InitPort[wire: ct.public[MultiPortRegisterFileInput][port], levelType: ls]; ENDLOOP; FOR port: NAT IN [0..rp) DO [] _ Ports.InitPort[wire: ct.public[MultiPortRegisterFileReadAddress][port], levelType: ls]; [] _ Ports.InitPort[wire: ct.public[MultiPortRegisterFileOutput][port], levelType: ls, initDrive: drive]; ENDLOOP; IF w=0 THEN w _ BitOps.TwoToThe[a]; CoreProperties.PutCellTypeProp[ct, MultiPortRegisterFileProp, NEW[NAT _ w]]; }; MultiPortRegisterFileState: TYPE = REF MultiPortRegisterFileStateRec; MultiPortRegisterFileStateRec: TYPE = RECORD [ bits: SEQUENCE size: NAT OF Ports.LevelSequence]; MultiPortRegisterFileInit: Rosemary.InitProc = { words: NAT _ NARROW[CoreProperties.GetCellTypeProp[cellType, MultiPortRegisterFileProp], REF NAT]^; bits: NAT _ p[MultiPortRegisterFileOutput][0].ls.size; state: MultiPortRegisterFileState _ NEW[MultiPortRegisterFileStateRec[words]]; FOR w: NAT IN [0..words) DO state[w] _ NEW[Ports.LevelSequenceRec[bits]]; FOR b: NAT IN [0..bits) DO state[w][b] _ X; ENDLOOP; ENDLOOP; stateAny _ state; }; MultiPortRegisterFileSimple: Rosemary.EvalProc = { state: MultiPortRegisterFileState _ NARROW[stateAny]; words: NAT _ state.size; bits: NAT _ p[MultiPortRegisterFileOutput][0].ls.size; FOR port: NAT IN [0..p[MultiPortRegisterFileInput].size) DO adr: NAT _ 0; FOR a: NAT IN [0..p[MultiPortRegisterFileWriteAddress][port].ls.size) DO aBit: Ports.Level _ p[MultiPortRegisterFileWriteAddress][port].ls[a]; IF aBit=X THEN { IF p[MultiPortRegisterFileLoad].ls[port]#L THEN FOR w: NAT IN [0..words) DO FOR b: NAT IN [0..bits) DO state[w][b] _ X; ENDLOOP; ENDLOOP; EXIT; } ELSE adr _ 2*adr + (IF p[MultiPortRegisterFileWriteAddress][port].ls[a]=H THEN 1 ELSE 0); REPEAT FINISHED => { IF p[MultiPortRegisterFileLoad].ls[port]=H THEN FOR b: NAT IN [0..bits) DO state[adr][b] _ p[MultiPortRegisterFileInput][port].ls[b]; ENDLOOP ELSE IF p[MultiPortRegisterFileLoad].ls[port]=X THEN FOR b: NAT IN [0..bits) DO state[adr][b] _ X; ENDLOOP; } ENDLOOP; ENDLOOP; FOR port: NAT IN [0..p[MultiPortRegisterFileOutput].size) DO adr: NAT _ 0; FOR a: NAT IN [0..p[MultiPortRegisterFileReadAddress][port].ls.size) DO aBit: Ports.Level _ p[MultiPortRegisterFileReadAddress][port].ls[a]; IF aBit=X THEN { FOR b: NAT IN [0..bits) DO p[MultiPortRegisterFileOutput][port].ls[b] _ X; ENDLOOP; EXIT; } ELSE adr _ 2*adr + (IF p[MultiPortRegisterFileReadAddress][port].ls[a]=H THEN 1 ELSE 0); REPEAT FINISHED => { FOR b: NAT IN [0..bits) DO p[MultiPortRegisterFileOutput][port].ls[b] _ state[adr][b]; ENDLOOP; } ENDLOOP; ENDLOOP; }; BXor: PROC [x, y: BOOL] RETURNS [z: BOOL] = { z _ (x AND NOT y) OR (NOT x AND y) }; END. ΦMSIImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Barth, October 10, 1986 5:34:30 pm PDT Last Edited by: Louis Monier August 7, 1986 8:14:58 pm PDT Quick fix so that it compiles; probably wrong. --LMM Extract the xth bit in the interger N Warning: bit 0 is the LOW order bit (lsb) Latch Register Constant Multiplexor BusMultiplexor Buffers TristateBuffers Adder Comparator Decoders ShiftRegister Counter RegisterFile MultiPortRegisterFile Κ– "cedar" style˜codešœ ™ Kšœ Οmœ1™˜>Kšœ?˜?KšœR˜RKšœ˜K˜—š‘ œ˜ Kšœžœžœ˜*K˜ Kšœ˜Kšœ˜K˜—š‘ œ˜"Kšœžœžœ ˜*šžœž˜Kšœ˜Kšœžœžœ ˜/Kšžœ˜—Kšœ˜Kšœ˜K˜——šœ™Kš‘ œžœ`˜rKš‘œžœ˜Kš‘œžœ˜Kš‘œžœ˜Kš‘œžœ˜Kš‘ œžœ˜K˜š ‘œžœžœžœžœ˜9šœ#˜#Kšœ˜KšœH˜H—KšœF˜FKšœ+˜+Kšœ;˜;Kšœ;˜;Kšœ>˜>Kšœ<˜šœ#˜#Kšœ˜Kšœ†˜†—KšœK˜KKšœ+˜+KšœE˜EKšœE˜EKšœH˜HKšœH˜HKšœG˜GKšœL˜LKšœK˜KKšœL˜LKšœH˜HKšœ[˜[Kšœ˜K˜—Kšœžœžœ˜5šœžœžœ˜&Kšœžœ˜Kšœžœ˜K˜—š‘œ˜(Kšœžœ˜7Kšœžœ"˜+Kšœ žœ˜,Kšœ žœ˜,Kš žœžœžœ žœžœ˜@Kšœ˜Kšœ˜K˜—š‘œ˜*K˜š‘œžœ˜šžœžœžœž˜ KšœA˜AKšžœ˜—K˜K˜—Kšœžœ ˜-Kšœ žœ#˜0Kš žœžœžœžœžœžœ˜’šžœ˜šžœžœ˜$Kšžœ žœ˜-šžœ˜šžœ žœ˜(šžœžœžœž˜Kšœ˜Kšžœ˜—Kšœ1˜1K˜—šžœ˜š žœžœž œžœž˜)Kšœ˜Kšžœ˜—Kšœ)˜)K˜—K˜—K˜—šžœžœ˜#šžœžœžœž˜Kšœ)˜)Kšžœ˜—K˜—šžœžœ˜$šžœžœžœž˜Kšœ˜Kšžœ˜—K˜—šžœžœžœž˜Kšœ*˜*Kšžœ˜—Kšœ˜—Kšœ˜K˜——š‘™Kš‘ œžœ]˜nKš‘ œžœ˜Kš‘ œžœ˜Kš‘ œžœ˜Kš‘ œžœ˜Kš‘ œžœ˜Kš‘œžœ˜Kš‘ œžœ˜Kš‘ œžœ˜K˜š ‘œžœžœžœžœ˜8šœ#˜#Kšœ˜Kšœh˜h—KšœE˜EKšœ+˜+Kšœ?˜?Kšœ?˜?KšœB˜BKšœB˜BKšœA˜AKšœC˜CKšœB˜BKšœU˜UKšœ˜K˜—Kšœžœžœ˜)šœžœžœ˜ Kšœžœ˜Kšœžœ˜K˜—š‘ œ˜"Kšœžœ˜+Kšœžœ˜%Kšœ žœ˜,Kšœ žœ˜,Kš žœžœžœ žœžœ˜@Kšœ˜Kšœ˜K˜—š‘ œ˜$K˜š‘œžœ˜šžœžœžœ ž˜Kšœ;˜;Kšžœ˜—Kšœ˜K˜—Kšœžœ ˜'Kšœžœ˜$KšžœžœΟtœžœžœžœžœ˜„šžœ˜šžœžœ˜Kšžœžœ˜$šžœ˜šžœžœ˜Kšœ˜šžœžœž œ ž˜%Kšœ žœ žœžœžœžœžœžœ˜aKšœžœ žœžœžœžœ žœžœžœ˜YKšžœ˜—K˜—šžœ˜Kšœ˜šžœžœž œ ž˜%Kšœ žœ žœžœžœžœžœžœ˜cKšœ žœ žœžœžœžœ žœžœžœ˜\Kšžœ˜—K˜—K˜—K˜—šžœžœ˜šžœžœžœ ž˜Kšœ#˜#Kšžœ˜—K˜—šžœžœ˜šžœžœžœ ž˜Kšœ˜Kšžœ˜—K˜—šžœžœžœ ž˜Kšœ$˜$Kšžœ˜—Kšœ˜—Kšœ˜K˜——š‘ ™ Kš‘œžœl˜‚Kš‘œžœ;˜QKš‘œžœ˜Kš‘œžœ˜Kš‘œžœ˜Kš‘œžœ˜Kš‘œžœ˜Kš‘œžœ˜K˜š‘ œžœžœžœžœžœžœ˜Qšœ#˜#Kšœ˜Kšœ[˜[—KšœJ˜JKšœ+˜+KšœD˜DKšœD˜DKšœE˜EKšœI˜IKšœG˜GKšœZ˜ZKšžœžœ˜#Kšœ5žœžœ˜CKšœ˜K˜—Kšœžœžœ˜3šœžœžœ˜%Kšœžœžœžœ˜1K˜—š‘œ˜'Kš œžœžœ=žœžœ˜ZKšœžœ!˜*Kšœžœ˜<šžœžœžœ ž˜Kšœ žœ˜-šžœžœžœ ž˜Kšœ˜Kšžœ˜—Kšžœ˜—Kšœ˜Kšœ˜K˜—š‘œ˜)Kšœžœ ˜,Kšœžœ˜Kšœžœ!˜*Kšœžœ˜ šžœžœžœ%ž˜4Kšœ1˜1šžœžœ˜š žœžœžœžœžœ ž˜;šžœžœžœ ž˜Kšœ˜Kšžœ˜—Kšžœ˜—šžœžœžœ ž˜Kšœ ˜ Kšžœ˜—Kšžœ˜K˜—Kšžœžœ žœžœ˜Ešžœžœ˜š žœžœžœžœžœ ž˜:Kšœ+˜+Kšž˜—š žœžœžœžœžœžœ ž˜?Kšœ˜Kšžœ˜—šžœžœžœ ž˜Kšœ,˜,Kšžœ˜—K˜—Kšžœ˜—Kšœ˜K˜——š‘™Kš‘œžœ‡˜¦Kš‘œžœD˜cKš‘œžœ˜"Kš‘œžœ˜"Kš‘œžœ˜#Kš‘!œžœ˜+Kš‘ œžœ˜*Kš‘œžœ˜$Kš‘œžœ˜%K˜š‘œžœžœžœžœžœ žœ žœžœ˜tšœ#˜#Kšœ ˜ KšœΌ˜Ό—KšœS˜SKšœ+˜+KšœM˜MKšœM˜MKšœO˜Ošžœžœžœ ž˜Kšœ]˜]KšœV˜VKšžœ˜—šžœžœžœ ž˜Kšœ\˜\Kšœi˜iKšžœ˜—Kšžœžœ˜#Kšœ>žœžœ˜LKšœ˜K˜—Kšœžœžœ˜Ešœžœžœ˜.Kšœžœžœžœ˜1K˜—š‘œ˜0Kš œžœžœFžœžœ˜cKšœžœ-˜6Kšœ$žœ'˜Nšžœžœžœ ž˜Kšœ žœ˜-šžœžœžœ ž˜Kšœ˜Kšžœ˜—Kšžœ˜—Kšœ˜Kšœ˜K˜—š‘œ˜2Kšœ$žœ ˜5Kšœžœ˜Kšœžœ-˜6šžœžœžœ)ž˜;Kšœžœ˜ šžœžœžœ9ž˜HKšœE˜Ešžœžœ˜š žœ)žœžœžœžœ ž˜Kšžœžœžœ ž˜Kšœ˜Kšžœ˜—Kšžœ˜—Kšžœ˜K˜—Kšžœžœ4žœžœ˜Yšžœžœ˜š žœ)žœžœžœžœ ž˜JKšœ:˜:Kšž˜—š žœžœ)žœžœžœžœ ž˜OKšœ˜Kšžœ˜—K˜—Kšžœ˜—Kšžœ˜—šžœžœžœ*ž˜