DIRECTORY BitOps, Core, CoreCreate, CoreOps, IO, Logic, LogicUtils, Ports, Rosemary; LogicMuxesImpl: CEDAR PROGRAM IMPORTS BitOps, CoreCreate, CoreOps, IO, Logic, LogicUtils, Ports EXPORTS Logic = BEGIN OPEN LogicUtils, CoreCreate; ReverseBits: PUBLIC PROC [b: NAT] RETURNS [public: Core.Wires] ~ { wA: Wire _ Seq["A", b]; wB: Wire _ Seq["B", b]; IF b=0 THEN Error["Please provide parameters for ReverseBits"]; FOR i: NAT IN [0..b) DO wB[i] _ wA[b-1-i] ENDLOOP; public _ LIST [wA, wB]; }; Transpose: PUBLIC PROC [b, w: NAT] RETURNS [public: Core.Wires] ~ { wSide: Wire _ Seq["wSide", w, Seq[size: b]]; bSide: Wire _ Seq["bSide", b, Seq[size: w]]; IF b=0 OR w=0 THEN Error["Please provide parameters for Transpose"]; FOR i: NAT IN [0..w) DO word: Wire = wSide[i]; FOR j: NAT IN [0..b) DO bSide[j][i] _ word[j] ENDLOOP; ENDLOOP; public _ LIST [wSide, bSide]; }; Interleave: PUBLIC PROC [b: NAT] RETURNS [public: Core.Wires] ~ { even: Wire _ Seq["Even", b]; odd: Wire _ Seq["Odd", b]; result: Wire _ Seq["Result", 2*b]; IF b=0 THEN Error["Please provide parameters for Interleave"]; FOR i: NAT IN [0..b) DO result[2*i] _ even[i]; result[2*i+1] _ odd[i]; ENDLOOP; public _ LIST [even, odd, result]; }; MuxDN1: PUBLIC PROC [n: NAT] RETURNS [ct: CellType] ~ { fullName: ROPE = IO.PutFR["MuxDN1 n=%g", IO.int[n]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; SELECT n FROM 0 => Error["Please provide parameters for 1-bit decoded multiplexer"]; 1 => Error["What the hell is a 1-input decoded multiplexer ???"]; 2 => ct _ SCBlock[Extract["NormalizedMuxD21.sch"]]; 3 => ct _ SCBlock[Extract["NormalizedMuxD31.sch"]]; 4 => ct _ SCBlock[Extract["NormalizedMuxD41.sch"]]; ENDCASE => ct _ Extract["muxDN1.sch", LIST[["n", n]]]; CacheStore[fullName, ct]; }; MuxN1: PUBLIC PROC [n: NAT] RETURNS [ct: CellType] = { fullName: ROPE = IO.PutFR["MuxN1 n=%g", IO.int[n]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; SELECT n FROM 0 => Error["Please provide parameters for 1-bit encoded multiplexer"]; 1 => Error["What the hell is a 1-input encoded multiplexer ???"]; 2 => ct _ SCBlock[Extract["NormalizedMux21.sch"]]; 3 => ct _ SCBlock[Extract["NormalizedMux31.sch"]]; 4 => ct _ SCBlock[Extract["NormalizedMux41.sch"]]; ENDCASE => ct _ Extract["muxN1.sch", LIST[["nb", n], ["ad", BitOps.NBits[n]]]]; CacheStore[fullName, ct]; }; MuxDRoseClass: ROPE = RoseClass["MuxD", MuxInit, MuxDSimple]; MuxD: PUBLIC PROC [n, b: NAT] RETURNS [ct: CellType] = { input: Wire; fullName: ROPE = IO.PutFR["MuxD n=%g b=%g", IO.int[n], IO.int[b]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; IF n=0 OR b=0 THEN Error["Please provide parameters for decoded multiplexer"]; IF b=1 THEN Error["Please use the 1-bit version of the decoded multiplexer"]; IF n=1 THEN Error["What the hell is a 1-input decoded multiplexer ???"]; ct _ Extract[IF b<=4 THEN "MuxDSmall.sch" ELSE "MuxDLarge.sch", LIST [["nb", b], ["nw", n]]]; SimulateMacro[ct, MuxDRoseClass]; input _ CoreOps.FindWire[ct.public, "In"]; 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; CacheStore[fullName, ct]; }; 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]; }; MuxRoseClass: ROPE = RoseClass["Mux", MuxInit, MuxSimple]; Mux: PUBLIC PROC [n, b: NAT] RETURNS [ct: CellType] = { input: Wire; fullName: ROPE = IO.PutFR["Mux n=%g b=%g", IO.int[n], IO.int[b]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; IF n=0 OR b=0 THEN Error["Please provide parameters for multiplexer"]; IF b=1 THEN Error["Please use the 1-bit version of the multiplexer"]; IF n=1 THEN Error["What the hell is a 1-input multiplexer ???"]; IF n=2 THEN ct _ Extract["mux2b.sch", LIST [["nb", b]]] ELSE ct _ Extract["mux.sch", LIST [["nb", b], ["nw", n], ["na", BitOps.NBits[n]]]]; SimulateMacro[ct, MuxRoseClass]; input _ CoreOps.FindWire[ct.public, "In"]; 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; CacheStore[fullName, ct]; }; MuxState: TYPE = REF MuxStateRec; MuxStateRec: TYPE = RECORD [ select, in, out: NAT _ LAST[NAT]]; MuxInit: Rosemary.InitProc = { state: MuxState _ IF oldStateAny=NIL THEN NEW[MuxStateRec] ELSE NARROW[oldStateAny]; [state.select, state.in, state.out] _ Ports.PortIndexes[cellType.public, "Select", "In", "Output"]; stateAny _ state; }; MuxSimple: Rosemary.EvalProc = { state: MuxState _ NARROW[stateAny]; IF Ports.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 Ports.SetLS[p[state.out].ls, X] -- range exceeded ELSE Ports.CopyLS[from: p[state.in][sel].ls, to: p[state.out].ls]; }; }; InvMuxRoseClass: ROPE = RoseClass["InvMux", InvMuxInit, InvMuxSimple]; InvMux: PUBLIC PROC [b: NAT] RETURNS [ct: CellType] = { fullName: ROPE = IO.PutFR["InvMux b=%g", IO.int[b]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; IF b=0 THEN Error["Please specify size of inverting mux"]; ct _ Extract["invMux2b.sch", LIST[["b", b]]]; SimulateMacro[ct, InvMuxRoseClass]; Ports.InitPorts[ct, l, none, "Select"]; Ports.InitPorts[ct, ls, none, "In0", "In1"]; Ports.InitPorts[ct, ls, drive, "nOut"]; CacheStore[fullName, ct]; }; InvMuxState: TYPE = REF InvMuxStateRec; InvMuxStateRec: TYPE = RECORD [ select, in0, in1, out: NAT _ LAST[NAT]]; InvMuxInit: Rosemary.InitProc = { state: InvMuxState _ NEW[InvMuxStateRec]; [state.select, state.in0, state.in1, state.out] _ Ports.PortIndexes[cellType.public, "Select", "In0", "In1", "nOut"]; stateAny _ state; }; InvMuxSimple: Rosemary.EvalProc = { state: InvMuxState _ NARROW[stateAny]; SELECT p[state.select].l FROM L => Ports.NotLS[a: p[state.in0].ls, b: p[state.out].ls]; H => Ports.NotLS[a: p[state.in1].ls, b: p[state.out].ls]; ENDCASE => Ports.SetLS[p[state.out].ls, X]; }; DecoderState: TYPE = REF DecoderStateRec; DecoderStateRec: TYPE = RECORD [decoderAd, decoderSel, decoderEnable: NAT _ LAST[NAT]]; DecoderBuffer: PROC [a: NAT] RETURNS [ct: CellType] ~ { drive: INT = BitOps.TwoToThe[a-1]; ct _ SequenceCell[baseCell: Logic.SymDriver[drive], count: a, sequencePorts: Wires["I", "nX", "X"]]; }; DecoderSBody: PROC [a, s: NAT] RETURNS [ct: CellType] ~ { nor: CellType; norInput, nAd, nnAd, select: Wire; insts: CellInstances _ NIL; nor _ Logic.Nor[a]; -- a>= 2 norInput _ FindWire[nor.public, "I"]; nAd _ Seq["nAd", a]; nnAd _ Seq["nnAd", a]; select _ Seq["Select", s]; 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: "DecoderSBody", public: Wires["Vdd", "Gnd", nAd, nnAd, select], instances: insts]; }; DecoderSRoseClass: ROPE = RoseClass["DecoderS", DecoderSInit, DecoderSSimple]; DecoderS: PUBLIC PROC [a: NAT, s: NAT _ 0] RETURNS [ct: CellType] = { fullName: ROPE; IF a=0 THEN Error["Please provide parameter(s) for decoder"]; IF s>BitOps.TwoToThe[a] THEN Error["s too large in decoder"]; IF s=0 THEN s _ BitOps.TwoToThe[a]; fullName _ IO.PutFR["DecoderS a=%g s=%g", IO.int[a], IO.int[s]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; SELECT TRUE FROM a=1 AND s=1 => ct _ SCBlock[Extract["decoder11.sch"]]; a=1 AND s=2 => ct _ SCBlock[Extract["decoder12.sch"]]; ENDCASE => { -- general case nAd: Wire _ Seq["nAd", a]; nnAd: Wire _ Seq["nnAd", a]; select: Wire _ Seq["Select", s]; address: Wire _ Seq["Address", a]; insts: CellInstances _ NIL; insts _ CONS[Instance[DecoderBuffer[a], ["I", address], ["nX", nAd], ["X", nnAd] ], insts]; insts _ CONS[Instance[DecoderSBody[a, s], ["Select", select], ["nAd", nAd], ["nnAd", nnAd] ], insts]; ct _ Cell[name: "DecoderS", public: Wires["Vdd", "Gnd", address, select], onlyInternal: Wires[nAd, nnAd], instances: insts]; }; SimulateMacro[ct, DecoderSRoseClass]; Ports.InitPorts[ct, ls, none, "Address"]; Ports.InitPorts[ct, ls, drive, "Select"]; CacheStore[fullName, ct]; }; DecoderSInit: Rosemary.InitProc = { state: DecoderState _ IF oldStateAny=NIL THEN NEW[DecoderStateRec] ELSE NARROW[oldStateAny]; [state.decoderAd, state.decoderSel] _ Ports.PortIndexes[cellType.public, "Address", "Select"]; stateAny _ state; }; DecoderSSimple: Rosemary.EvalProc = { state: DecoderState _ NARROW[stateAny]; ad: NAT; IF Ports.HasX[p[state.decoderAd].ls] THEN {Ports.SetLS[p[state.decoderSel].ls, X]; RETURN}; ad _ Ports.LSToC[p[state.decoderAd].ls]; Ports.SetLS[p[state.decoderSel].ls, L]; IF adBitOps.TwoToThe[a] THEN Error["s too large in decoder"]; IF s=0 THEN s _ BitOps.TwoToThe[a]; fullName _ IO.PutFR["Decoder a=%g s=%g", IO.int[a], IO.int[s]]; ct _ CacheFetch[fullName]; IF ct#NIL THEN RETURN[ct]; address _ Seq["Address", a]; nAd _ Seq["nAd", a]; nnAd _ Seq["nnAd", a]; select _ Seq["Select", s]; insts _ CONS[Instance[DecoderBuffer[a], ["I", address], ["nX", nAd], ["X", nnAd] ], insts]; insts _ CONS[Instance[Logic.InvDriver[s], ["I", "Enable"], ["X", "nEn"] ], insts]; insts _ CONS[Instance[DecoderBody[a, s], ["Select", select], ["nAd", nAd], ["nnAd", nnAd], ["nEn", "nEn"] ], insts]; ct _ Cell[name: "Decoder", public: Wires["Vdd", "Gnd", address, select, "Enable"], onlyInternal: Wires[nAd, nnAd, "nEn"], instances: insts]; SimulateMacro[ct, DecoderRoseClass]; Ports.InitPorts[ct, l, none, "Enable"]; Ports.InitPorts[ct, ls, none, "Address"]; Ports.InitPorts[ct, ls, drive, "Select"]; CacheStore[fullName, ct]; }; DecoderInit: Rosemary.InitProc = { state: DecoderState _ IF oldStateAny=NIL THEN NEW[DecoderStateRec] ELSE NARROW[oldStateAny]; [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 Ports.HasX[p[state.decoderAd].ls] THEN {Ports.SetLS[p[state.decoderSel].ls, X]; RETURN}; ad _ Ports.LSToC[p[state.decoderAd].ls]; Ports.SetLS[p[state.decoderSel].ls, L]; IF ad Ports.SetLS[p[state.decoderSel].ls, X]; }; END. zLogicMuxesImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Last Edited by: Louis Monier August 26, 1987 6:11:47 pm PDT Jean-Marc Frailong October 22, 1987 0:21:37 am PDT Pradeep Sindhu February 27, 1987 2:51:12 pm PST Barth, October 10, 1986 5:30:37 pm PDT Useful wire icons The wire icons described here are all unnamed wire icons. Code for a wire icon that reverses the order of the bits within a b-bit bus. Each bit will have the structure described by p, a void rope meaning atomic. Code for a wire icon that transforms a bus of w words of b bits into a bus of b words of w bits (i.e. bSide[b][w] = wSide[w][b]) Code for a wire icon that interleaves buses. The interleaved bus is E[0], O[0], E[1], ... The even and odd buses are b bits wide, the interleaved bus is 2b bits wide. 1-Bit multiplexers Decoded 1-Bit multiplexer -- Public: "Vdd", "Gnd", Seq["Select", n], Seq["In", n], "Output" Encoded 1-Bit multiplexer -- Public: "Vdd", "Gnd", Seq["Select", s], Seq["In", n], "Output", with s=NbBits[n] b-Bit n-Input multiplexers Common code Decoded b-Bit n-Input multiplexer -- A simple sequence of muxDN1; easier to layout and faster than the encoded version! Encoded b-Bit n-Input multiplexer -- Make a special case for n=2, 3, 4 using the 1-bit decoded version and buffers (*) Inverting b-Bit 2-Input multiplexer -- 2 inputs, n bits Decoders Shared types & procedures -- (Address, nAd, nnAd)[0..a) Simple Decoder -- Select[0..s), (nAd, nnAd)[0..a) with a>=2 -- one a-input nor per output -- recognize the input "i" -- 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. Decoder with enable -- The decoder with enable: if enable=L all outputs are low -- nEn, Select[0..s), (nAd, nnAd)[0..a)with a>=2 -- one (a+1)-input nor per output -- recognize the input "i" ΚK– "cedar" style˜codešœ™Kšœ Οmœ1™šžœžœžœž˜Kšœ˜Kšœ˜Kšžœ˜—Kšœ žœ˜"K˜——šœ™šœ™KšΟcA™Aš  œžœžœžœžœ˜7Kšœ žœžœžœ ˜4K˜Kšžœžœžœžœ˜šžœž˜ KšœF˜FKšœA˜AKšœ3˜3Kšœ3˜3Kšœ3˜3Kšžœžœ ˜6—Kšœ˜K˜——šœ™Kš‘S™Sš  œžœžœžœžœ˜6Kšœ žœžœžœ ˜3K˜Kšžœžœžœžœ˜šžœž˜ KšœF˜FKšœA˜AKšœ2˜2Kšœ2˜2Kšœ2˜2Kšžœžœ&˜O—Kšœ˜K˜———šœ™L™ šœ!™!Kš‘U™UKš  œžœ*˜=š  œžœžœžœžœ˜8K˜ Kš œ žœžœžœ žœ ˜BK˜Kšžœžœžœžœ˜Kšžœžœžœ<˜NKšžœžœB˜MKšžœžœ=˜HKš œ žœžœžœžœ˜]Kšœ!˜!K˜*KšœR˜RKš žœžœžœžœ)žœ˜HKšœ˜Kšœ˜K˜—š œžœžœžœžœžœžœžœ˜bšžœžœžœž˜šžœžœž˜Kšœ žœžœ‘˜4Kšœžœžœžœ‘˜9Kšœžœžœ‘˜;Kšžœžœ˜—Kšžœ˜—K˜K˜—š  œ˜!Kšœžœ ˜#Kšœžœžœ˜Kšœ.˜.Kšžœžœ<˜FKšžœ!˜%Kšœ˜——šœ!™!Kš‘T™TKš  œžœ(˜:š  œžœžœžœžœ˜7K˜ Kš œ žœžœžœ žœ ˜AK˜Kšžœžœžœžœ˜Kšžœžœžœ4˜FKšžœžœ:˜EKšžœžœ5˜@Kšžœžœžœ ˜7Kšžœžœ2˜SKšœ ˜ K˜*KšœR˜RKš žœžœžœžœ)žœ˜HKšœ˜Kšœ˜K˜—Kšœ žœžœ ˜!šœ žœžœ˜Kšœžœžœžœ˜"—š œ˜Kš œžœ žœžœžœžœžœ˜TKšœc˜cKšœ˜Kšœ˜—š  œ˜ Kšœžœ ˜#Kšžœ žœ ˜Fšžœ˜Kšœžœ#˜+Kšžœžœ!‘˜OKšžœ>˜BK˜—Kšœ˜——šœ#™#Kš‘™Kš œžœ1˜Fš  œžœžœžœžœ˜7Kšœ žœžœžœ ˜4K˜Kšžœžœžœžœ˜Kšžœžœ/˜:Kšœžœ ˜-Kšœ#˜#Kšœ'˜'KšœT˜TKšœ˜Kšœ˜K˜—Kšœ žœžœ˜'šœžœžœ˜Kšœžœžœžœ˜(—š  œ˜!Kšœžœ˜)Kšœu˜uKšœ˜Kšœ˜—š  œ˜#Kšœžœ ˜&šžœž˜Kšœ9˜9Kšœ9˜9Kšžœ$˜+—Kšœ˜———™™Kšœžœžœ˜)š œžœžœ(žœžœžœ˜WK˜—Kš‘™š  œžœžœžœ˜7Kšœžœ˜"Kšœd˜dK˜K˜——šœ™Kš‘,™,š  œžœžœžœ˜9Kšœ˜Kšœ"˜"Kšœžœ˜Kšœ‘˜Kšœ%˜%Kšœ˜Kšœ˜Kšœ˜Kš‘™šžœžœžœž˜Kš œžœžœžœžœ˜)Kš‘™šžœžœžœž˜Kš œžœžœžœ žœ žœ˜UKšžœ˜—Kšœžœ ˜,Kšžœ˜—šœ˜Kšœ/˜/Kšœ˜—K˜K˜—Kš‘«™«Kš œžœ7˜Nš  œžœžœžœžœžœ˜EKšœ žœ˜Kšžœžœ2˜=Kšžœžœ!˜=Kšžœžœ˜#Kšœ žœžœ žœ ˜@K˜Kšžœžœžœžœ˜šžœžœž˜Kšœžœ/˜6Kšœžœ/˜6šžœ‘˜Kšœ˜Kšœ˜Kšœ ˜ Kšœ"˜"Kšœžœ˜KšœžœO˜[KšœžœY˜ešœ˜Kšœ-˜-Kšœ ˜ Kšœ˜—Kšœ˜——Kšœ%˜%KšœS˜SKšœ˜Kšœ˜—K˜š  œ˜#Kš œžœ žœžœžœžœžœ˜\Kšœ^˜^Kšœ˜Kšœ˜—š œ˜%Kšœžœ ˜'Kšœžœ˜Kšžœ#žœ*žœ˜[Kšœ(˜(Kšœ'˜'Kšžœ žœ ˜FKšœ˜——šœ™Kš‘;™;Kš‘0™0š  œžœžœžœ˜8Kšœ ‘˜9Kšœ"˜"Kšœžœ˜Kšœ%˜%Kšœ˜Kšœ˜Kšœ˜Kš‘!™!šžœžœžœž˜Kš œžœžœžœžœ)˜?Kš‘™šžœžœžœž˜Kš œžœžœžœ žœ žœ˜UKšžœ˜—Kšœžœ ˜,Kšžœ˜—šœ˜Kšœ6˜6Kšœ˜—K˜—K˜Kš œžœ4˜Jš  œžœžœžœžœžœ˜DKšœ!˜!Kšœžœ˜Kšœ žœ˜Kšžœžœ>˜IKšžœžœ!˜=Kšžœžœ˜#Kšœ žœžœ žœ ˜?K˜Kšžœžœžœžœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜KšœžœO˜[KšœžœF˜RKšœžœh˜tšœ˜Kšœ7˜7Kšœ'˜'Kšœ˜—Kšœ$˜$Kšœ'˜'KšœS˜SKšœ˜Kšœ˜K˜—š  œ˜"Kš œžœ žœžœžœžœžœ˜\Kšœ}˜}Kšœ˜Kšœ˜—š  œ˜$Kšœžœ ˜'šžœž˜$Kšœ,˜,šœ˜Kšœžœ˜Kšžœ#žœ*žœ˜[Kšœ(˜(Kšœ'˜'Kšžœ žœ!˜G—Kšžœ+˜2—Kšœ˜———˜K˜—Kšžœ˜K˜K™—…—.4Cω