DIRECTORY BitOps, CoreCreate, CoreFlat, Logic, LogicUtils, Ports, Rosemary; LogicMuxesImpl: CEDAR PROGRAM IMPORTS BitOps, CoreCreate, CoreFlat, Logic, LogicUtils, Ports, Rosemary EXPORTS Logic = BEGIN OPEN Logic, CoreCreate; MuxDN1Name: ROPE = "MuxDN1"; MuxDN1: PUBLIC PROC [n: NAT] RETURNS [ct: CellType] ~ { SELECT n FROM 0 => LogicUtils.Error["Please provide parameters for 1-bit decoded multiplexer"]; 1 => LogicUtils.Error["What the hell is a 1-input decoded multiplexer ???"]; 2 => RETURN[LogicUtils.Extract["NormalizedMuxD21.sch", TRUE]]; 3 => RETURN[LogicUtils.Extract["NormalizedMuxD31.sch", TRUE]]; 4 => RETURN[LogicUtils.Extract["NormalizedMuxD41.sch", TRUE]]; ENDCASE => { insts: CellInstances _ LIST[Instance[Inv[], ["I", "nOutput"], ["X", "Output"]]]; seq: CellType _ CoreCreate.SequenceCell[ baseCell: TristateI[], count: n, sequencePorts: Wires["I", "EN"]]; insts _ CONS[Instance[seq, ["I", "In"], ["EN", "Select"], ["X", "nOutput"]], insts]; ct _ Cell[ name: MuxDN1Name, public: Wires["Vdd", "Gnd", Seq["Select", n], Seq["In", n], "Output"], onlyInternal: Wires["nOutput"], instances: insts]; }; }; MuxN1Name: ROPE = "MuxN1"; MuxN1: PUBLIC PROC [n: NAT] RETURNS [ct: CellType] = { SELECT n FROM 0 => LogicUtils.Error["Please provide parameters for 1-bit encoded multiplexer"]; 1 => LogicUtils.Error["What the hell is a 1-input encoded multiplexer ???"]; 2 => RETURN[LogicUtils.Extract["NormalizedMux21.sch", TRUE]]; 3 => RETURN[LogicUtils.Extract["NormalizedMux31.sch", TRUE]]; 4 => RETURN[LogicUtils.Extract["NormalizedMux41.sch", TRUE]]; ENDCASE => { s: INT _ BitOps.NBits[n]; insts: CellInstances _ LIST[ Instance[MuxDN1[n], ["Select", "decoded"], ["In", "In"], ["Output", "Output"]], Instance[DecoderS[s, n], ["Address", "Select"], ["Select", "decoded"]]]; ct _ Cell[name: MuxN1Name, public: Wires["Vdd", "Gnd", Seq["Select", s], Seq["In", n], "Output"], onlyInternal: Wires[Seq["decoded", n]], instances: insts]; }; }; MuxDName: ROPE = Rosemary.Register[roseClassName: "MuxD", init: MuxInit, evalSimple: MuxDSimple]; MuxD: PUBLIC PROC [n, b: NAT] RETURNS [ct: CellType] = { wl: LIST OF WR _ NIL; muxDN1: CellType _ MuxDN1[n]; inputOfMux: Wire _ FindWire[muxDN1.public, "In"]; insts: CellInstances _ NIL; input: Wire _ Seq["In", n, Seq[size: b]]; output: Wire _ Seq["Output", b]; select: Wire _ Seq["Select", n]; IF n=0 OR b=0 THEN LogicUtils.Error["Please provide parameters for decoded multiplexer"]; IF b=1 THEN LogicUtils.Error["Please use the 1-bit version of the multiplexer"]; IF n=1 THEN LogicUtils.Error["What the hell is a 1-input decoded multiplexer ???"]; FOR bit: NAT IN [0..b) DO pas: LIST OF PA; actual: Wire; wrs: LIST OF WR _ NIL; FOR choice: NAT DECREASING IN [0..n) DO wrs _ CONS[input[choice][bit], wrs]; ENDLOOP; actual _ WireList[wrs]; wl _ CONS[actual, wl]; pas _ LIST[["Output", output[bit]], ["Select", select], [inputOfMux, actual]]; insts _ CONS[InstanceList[muxDN1, pas], insts]; ENDLOOP; ct _ Cell[ name: MuxName, public: Wires["Vdd", "Gnd", select, input, output], onlyInternal: WireList[wl], instances: insts]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: MuxDName]; [] _ CoreFlat.CellTypeCutLabels[ct, macroCutSet]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd"]; Ports.InitPorts[ct, ls, none, "Select"]; Ports.InitPorts[ct, ls, drive, "Output"]; FOR i: NAT IN [0..n) DO Ports.InitPorts[ct, ls, none, input[i]]; ENDLOOP; }; WhichSingleHigh: PROC [ls: Ports.LevelSequence] RETURNS [n: NAT _ LAST[NAT], ok: BOOL _ FALSE] ~ { FOR i: NAT IN [0..ls.size) DO SELECT TRUE FROM ls[i]=X => RETURN[i, FALSE]; -- invalid select line ls[i]=H AND ok => RETURN[n, FALSE]; -- more than one high ls[i]=H AND ~ok => {n _ i; ok _ TRUE}; -- remember this one ENDCASE => NULL; ENDLOOP; }; MuxDSimple: Rosemary.EvalProc = { state: MuxState _ NARROW[stateAny]; n: NAT; ok: BOOL; [n, ok] _ WhichSingleHigh[p[state.select].ls]; IF ok THEN Ports.CopyLS[from: p[state.in][n].ls, to: p[state.out].ls] ELSE Ports.SetLS[p[state.out].ls, X]; }; MuxName: ROPE = Rosemary.Register[roseClassName: "Mux", init: MuxInit, evalSimple: MuxSimple]; Mux: PUBLIC PROC [n, b: NAT] RETURNS [ct: CellType] = { sizeSel: INT _ BitOps.NBits[n]; input: Wire _ Seq["In", n, Seq[size: b]]; insts: CellInstances _ LIST[ Instance[DecoderS[sizeSel, n], ["Address", "Select"], ["Select", "decoded"]], Instance[MuxD[n, b], ["Select", "decoded"], ["In", "In"], ["Output", "Output"]]]; ct _ Cell[ name: MuxName, public: Wires["Vdd", "Gnd", Seq["Select", sizeSel], input, Seq["Output", b]], onlyInternal: Wires[Seq["decoded", n]], instances: insts]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: MuxName]; [] _ CoreFlat.CellTypeCutLabels[ct, macroCutSet]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd"]; Ports.InitPorts[ct, ls, none, "Select"]; Ports.InitPorts[ct, ls, drive, "Output"]; FOR i: NAT IN [0..n) DO Ports.InitPorts[ct, ls, none, input[i]]; ENDLOOP; }; MuxState: TYPE = REF MuxStateRec; MuxStateRec: TYPE = RECORD [ select, in, out: NAT _ LAST[NAT]]; MuxInit: Rosemary.InitProc = { state: MuxState _ NEW[MuxStateRec]; [state.select, state.in, state.out] _ Ports.PortIndexes[cellType.public, "Select", "In", "Output"]; stateAny _ state}; MuxSimple: Rosemary.EvalProc = { state: MuxState _ NARROW[stateAny]; IF LogicUtils.HasX[p[state.select].ls] THEN Ports.SetLS[p[state.out].ls, X] ELSE { sel: NAT _ Ports.LSToC[p[state.select].ls]; IF sel>=p[state.in].size THEN Rosemary.Stop[]; Ports.CopyLS[from: p[state.in][sel].ls, to: p[state.out].ls]; }; }; DecoderSName: ROPE = Rosemary.Register[roseClassName: "DecoderS", init: DecoderSInit, evalSimple: DecoderSSimple]; DecoderS: PUBLIC PROC [a: NAT, s: NAT _ 0] RETURNS [ct: CellType] = { inv, nor: CellType; norInput, address, nAd, nnAd, select: Wire; insts: CellInstances _ NIL; IF a=0 THEN LogicUtils.Error["Please provide parameter(s) for decoder"]; IF a=1 THEN SELECT s FROM 1 => RETURN[LogicUtils.Extract["decoder11.sch", TRUE]]; 2 => RETURN[LogicUtils.Extract["decoder12.sch", TRUE]]; ENDCASE => NULL; IF s=0 THEN s _ BitOps.TwoToThe[a]; inv _ Inv[]; nor _ Nor[a]; norInput _ FindWire[nor.public, "I"]; address _ Seq["Address", a]; nAd _ Seq["nAd", a]; nnAd _ Seq["nnAd", a]; select _ Seq["Select", s]; FOR i: NAT IN [0..a) DO insts _ CONS[Instance[inv, ["I", address[i]], ["X", nAd[i]] ], insts]; insts _ CONS[Instance[inv, ["I", nAd[i]], ["X", nnAd[i]] ], insts]; ENDLOOP; FOR i: NAT IN [0..s) DO pas: LIST OF PA _ LIST[["X", select[i]]]; FOR in: NAT IN [0..a) DO pas _ CONS[[norInput[in], IF BitOps.EBFW[i, in, a] THEN nAd[in] ELSE nnAd[in]], pas]; ENDLOOP; insts _ CONS[InstanceList[nor, pas], insts]; ENDLOOP; ct _ Cell[name: DecoderSName, public: Wires["Vdd", "Gnd", address, select], onlyInternal: Wires[nAd, nnAd], instances: insts]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: DecoderSName]; [] _ CoreFlat.CellTypeCutLabels[ct, macroCutSet]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd"]; Ports.InitPorts[ct, ls, none, "Address"]; Ports.InitPorts[ct, ls, drive, "Select"]; }; DecoderState: TYPE = REF DecoderStateRec; DecoderStateRec: TYPE = RECORD [ decoderAd, decoderSel, decoderEnable: NAT _ LAST[NAT]]; DecoderSInit: Rosemary.InitProc = { state: DecoderState _ NEW[DecoderStateRec]; [state.decoderAd, state.decoderSel] _ Ports.PortIndexes[cellType.public, "Address", "Select"]; stateAny _ state}; DecoderSSimple: Rosemary.EvalProc = { state: DecoderState _ NARROW[stateAny]; ad: NAT; IF LogicUtils.HasX[p[state.decoderAd].ls] THEN {Ports.SetLS[p[state.decoderSel].ls, X]; RETURN}; ad _ Ports.LSToC[p[state.decoderAd].ls]; IF ad>p[state.decoderSel].ls.size THEN LogicUtils.Error["The address is out of bounds"]; Ports.SetLS[p[state.decoderSel].ls, L]; p[state.decoderSel].ls[ad] _ H; }; DecoderName: ROPE = Rosemary.Register[roseClassName: "Decoder", init: DecoderInit, evalSimple: DecoderSimple]; Decoder: PUBLIC PROC [a: NAT, s: NAT _ 0] RETURNS [ct: CellType] = { inv: CellType _ Inv[]; nor: CellType _ Nor[a+1]; -- one more input for nEnable norInput: Wire _ FindWire[nor.public, "I"]; insts: CellInstances _ LIST[Instance[inv, ["I", "Enable"], ["X", "nEnable"]]]; -- invert enable address: Wire _ Seq["Address", a]; nAd: Wire _ Seq["nAd", a]; nnAd: Wire _ Seq["nnAd", a]; select: Wire; IF s=0 THEN s _ BitOps.TwoToThe[a]; select _ Seq["Select", s]; FOR i: NAT IN [0..a) DO insts _ CONS[Instance[inv, ["I", address[i]], ["X", nAd[i]] ], insts]; insts _ CONS[Instance[inv, ["I", nAd[i]], ["X", nnAd[i]] ], insts]; ENDLOOP; FOR i: NAT IN [0..s) DO pas: LIST OF PA _ LIST[["X", select[i]], [norInput[a], "nEnable"]]; FOR in: NAT IN [0..a) DO pas _ CONS[[norInput[in], IF BitOps.EBFW[i, in, a] THEN nAd[in] ELSE nnAd[in]], pas]; ENDLOOP; insts _ CONS[InstanceList[nor, pas], insts]; ENDLOOP; ct _ Cell[name: DecoderName, public: Wires["Vdd", "Gnd", address, select, "Enable"], onlyInternal: Wires[nAd, nnAd, "nEnable"], instances: insts]; [] _ Rosemary.BindCellType[cellType: ct, roseClassName: DecoderName]; [] _ CoreFlat.CellTypeCutLabels[ct, macroCutSet]; Ports.InitPorts[ct, l, none, "Vdd", "Gnd", "Enable"]; Ports.InitPorts[ct, ls, none, "Address"]; Ports.InitPorts[ct, ls, drive, "Select"]; }; DecoderInit: Rosemary.InitProc = { state: DecoderState _ NEW[DecoderStateRec]; [state.decoderAd, state.decoderSel, state.decoderEnable] _ Ports.PortIndexes[cellType.public, "Address", "Select", "Enable"]; stateAny _ state}; DecoderSimple: Rosemary.EvalProc = { state: DecoderState _ NARROW[stateAny]; SELECT p[state.decoderEnable].l FROM L => Ports.SetLS[p[state.decoderSel].ls, L]; H => { ad: NAT; IF LogicUtils.HasX[p[state.decoderAd].ls] THEN {Ports.SetLS[p[state.decoderSel].ls, X]; RETURN}; ad _ Ports.LSToC[p[state.decoderAd].ls]; IF ad>p[state.decoderSel].ls.size THEN LogicUtils.Error["The address is out of bounds"]; Ports.SetLS[p[state.decoderSel].ls, L]; p[state.decoderSel].ls[ad] _ H}; ENDCASE => Ports.SetLS[p[state.decoderSel].ls, X]; }; END. LogicMuxesImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Last Edited by: Louis Monier January 5, 1987 9:13:57 pm PST Barth, October 10, 1986 5:30:37 pm PDT Decoded 1-Bit multiplexer -- Public: "Vdd", "Gnd", Seq["Select", n], Seq["In", n], "Output" -- the output is through a single inverter -- In[i] is connected to an inverting tristate driver whose enable is Select[i] Encoded 1-Bit multiplexer -- Public: "Vdd", "Gnd", Seq["Select", s], Seq["In", n], "Output", with s=NbBits[n] Decoded b-Bit n-Input multiplexer -- A simple sequence of muxDN1; easier to layout and faster than the encoded version! -- I still have to add the buffers on the select lines (*) -- Create b instances of type MuxDN1[n], with pretty complex bindings Encoded Muxes -- Make a special case for n=2, 3, 4 using the 1-bit decoded vesion and buffers (*) Decoder -- The simple decoder is implemented as "s" a-input nors; each input is inverted twice to produce complementary values, and the inputs of the nors are chosen among those. -- inverter pairs on all inputs -- one a-input nor per output -- recognize the input "i" -- The decoder with enable: if enable=L all outputs are low -- inverter pairs on all inputs -- one (a+1)-input nor per output -- recognize the input "i" Κ – "cedar" style˜codešœ™Kšœ Οmœ1™Kšœžœ,žœ˜>Kšœžœ,žœ˜>šžœ˜ K™*Kšœžœ5˜PK™Ošœ(˜(Kšœ!˜!Kšœ!˜!—šœžœA˜MKšœ˜—šœ ˜ Kšœ˜KšœG˜GKšœ ˜ Kšœ˜—Kšœ˜——K˜——šŸ™KšœS™SKšŸ œžœ ˜š Ÿœžœžœžœžœ˜6šžœž˜ KšœQ˜QKšœL˜LKšœžœ+žœ˜=Kšœžœ+žœ˜=Kšœžœ+žœ˜=šžœ˜ Kšœžœ˜šœžœ˜KšœO˜OKšœH˜H—šœ˜KšœG˜GKšœ(˜(Kšœ˜—Kšœ˜——K˜——šŸ!™!K™UK™:KšŸœžœS˜aš Ÿœžœžœžœžœ˜8Kš œžœžœžœžœ˜Kšœ˜Kšœ1˜1Kšœžœ˜Kšœ)˜)Kšœ ˜ Kšœ ˜ KšžœžœžœG˜YKšžœžœE˜PKšžœžœH˜SKšœE™Ešžœžœžœž˜Kšœžœžœžœ˜K˜ Kš œžœžœžœžœ˜š žœ žœž œžœž˜'Kšœžœ˜$Kšžœ˜—K˜Kšœžœ ˜KšœžœD˜NKšœžœ#˜/Kšžœ˜—šœ ˜ Kšœ˜Kšœ3˜3Kšœ˜Kšœ˜—KšœB˜BKšœ1˜1Kšœ+˜+Kšœ(˜(Kšœ)˜)Kš žœžœžœžœ*žœ˜IKšœ˜—šŸœžœžœžœžœžœžœžœ˜bšžœžœžœž˜šžœžœž˜Kšœ žœžœΟc˜4Kšœžœžœžœ‘˜9Kšœžœžœ‘˜;Kšžœžœ˜—Kšžœ˜—K˜—šŸ œ˜!Kšœžœ ˜#Kšœžœžœ˜Kšœ.˜.Kšžœžœ<˜FKšžœ!˜%Kšœ˜——šŸ ™ K™SKšŸœžœQ˜^š Ÿœžœžœžœžœ˜7Kšœ žœ˜Kšœ)˜)šœžœ˜KšœN˜NKšœQ˜Q—šœ ˜ Kšœ˜KšœN˜NKšœ(˜(Kšœ˜—KšœA˜AKšœ1˜1Kšœ+˜+Kšœ(˜(Kšœ)˜)Kš žœžœžœžœ*žœ˜IKšœ˜—Kšœ žœžœ ˜!šœ žœžœ˜Kšœžœžœžœ˜"—šŸœ˜Kšœžœ˜#Kšœc˜cKšœ˜—šŸ œ˜ Kšœžœ ˜#Kšžœ%žœ ˜Kšžœ˜Kšœžœ#˜+Kšžœžœ˜.Kšœ=˜=K˜—Kšœ˜——šŸ™K™«KšŸ œžœ`˜rš Ÿœžœžœžœžœžœ˜EKšœ˜Kšœ+˜+Kšœžœ˜Kšžœžœ=˜Hšžœžœžœž˜Kšœžœ%žœ˜7Kšœžœ%žœ˜7Kšžœžœ˜—Kšžœžœ˜#Kšœ ˜ Kšœ ˜ Kšœ%˜%Kšœ˜Kšœ˜Kšœ˜Kšœ˜K™šžœžœžœž˜Kšœžœ:˜FKšœžœ7˜CKšžœ˜—K™šžœžœžœž˜Kš œžœžœžœžœ˜)K™šžœžœžœž˜Kš œžœžœžœ žœ žœ˜UKšžœ˜—Kšœžœ ˜,Kšžœ˜—šœ˜Kšœ-˜-Kšœ ˜ Kšœ˜—KšœF˜FKšœ1˜1Kšœ+˜+Kšœ)˜)Kšœ)˜)Kšœ˜—K˜Kšœžœžœ˜)šœžœžœ˜ Kšœ&žœžœžœ˜7—šŸ œ˜#Kšœžœ˜+Kšœ^˜^Kšœ˜—šŸœ˜%Kšœžœ ˜'Kšœžœ˜Kšžœ(žœ*žœ˜`Kšœ(˜(Kšžœ žœ2˜XKšœ(˜(Kšœ˜Kšœ˜—K˜K™;KšŸ œžœ]˜nš Ÿœžœžœžœžœžœ˜DKšœ˜Kšœ‘˜7Kšœ+˜+Kšœžœ4‘˜_Kšœ"˜"Kšœ˜Kšœ˜Kšœ ˜ Kšžœžœ˜#Kšœ˜K™šžœžœžœž˜Kšœžœ:˜FKšœžœ7˜CKšžœ˜—K™!šžœžœžœž˜Kš œžœžœžœžœ-˜CK™šžœžœžœž˜Kš œžœžœžœ žœ žœ˜UKšžœ˜—Kšœžœ ˜,Kšžœ˜—šœ˜Kšœ7˜7Kšœ+˜+Kšœ˜—K˜KšœE˜EKšœ1˜1Kšœ5˜5Kšœ)˜)Kšœ)˜)Kšœ˜—šŸ œ˜"Kšœžœ˜+Kšœ}˜}Kšœ˜—šŸ œ˜$Kšœžœ ˜'šžœž˜$Kšœ,˜,šœ˜Kšœžœ˜Kšžœ(žœ*žœ˜`Kšœ(˜(Kšžœ žœ2˜XKšœH˜H—Kšžœ+˜2—Kšœ˜—K˜—Kšžœ˜K˜K™—…—&’6±