Multiplexers and Decoders

Here’s something that wasn’t emphasized in my digital design courses, which every amateur digital designer should be aware of: decoders and three-state buffers use fewer logic gates than large multiplexers. Obviously when one uses commercial devices with an output enable, the decoder functionality is implicit, but whenever it comes to incorporating selection logic into our own designs acting on our own data, the more natural choice is a conventional multiplexer. Both approaches have benefits and drawbacks, but which is “better?” First, a quick look at the differences between the two: a multiplexer uses a combination of AND and OR gates to select between a number of inputs and always drives the output accordingly. A decoder/three-state selection device (which is really also called a multiplexer, but I’ll try to avoid some confusion) uses only AND gates and single transistors to drive the output with just one of the inputs when it is selected. The key aspect here is that there is not always an output of 0 or 1—a third option, high impedance (or Hi-Z), is available, corresponding to “no value.” This happens because each of the combination of select pins controls whether each input drives the output or not, rather than all inputs driving something regardless of utility. The differences between the two can be seen by implementing generic multiplexer functionality for a 1-bit, 8:1 multiplexer. Without three-stated buses, this requires 24 two-input AND gates and 7 two-input OR gates. The schematic shows that there are six logic gates between the input and the output of the multiplexer:

8 to 1 mux

8 to 1 mux

By comparison, the same functionality can be realized using only 16 two-input AND gates and 8 three-state output buffer elements. The schematic is also much simpler:

8 to 1 decoder

8 to 1 decoder

This reduces the gate delay between input and output to two gates plus a transistor. This would make it seem like three-state buffers and decoders are the obvious choice for every situation, because they have a shorter gate delay and use fewer transistors, which has many benefits. However, there are hidden problems associated with this design, making it unsuitable for some situations.

First, if the design is being developed for an FPGA, the AND/OR approach is more versatile. Why? Because FPGAs do not implement traditional combinational circuits. Often, combinational blocks are instead broken into units that can be implemented by 4-input Look-Up Tables (LUTs), which means that any function that can be described by such a lookup table has the same speed cost, regardless of the number of gates that would be required to implement it otherwise. Next, three-state elements are not readily available within most of the logic blocks (although an FPGA could be built to not have this restriction), meaning that more interconnect must be used to route signals through three-state elements, although it is more common for the compiler to simply recognize the situations and convert it into a multiplexer that can be implemented easily with the LUTs.

Second, when working with CMOS, each transistor has an capacitive property. Therefore, as more transistors are tied to the same bus, even in a Hi-Z mode, the capacitance will cause the rise and fall times to increase, in a manner similar to having an increased fanout. This can create problems with setup time in very high speed situations, whereas the rise and fall time of an AND/OR multiplexer output will not vary with the number of inputs (although the total propagation delay will—the two must be balanced, so it is possible that the longer rise time is shorter than the longer propagation delay).

Third, although this isn’t really a big problem, is that during transients when switching, it’s possible for two three-state elements to have their enables asserted at the same time, potentially causing the bus to be driven both low and high at the same time. This is going to happen for an extremely short period of time, as the switching time is usually less than the delay of a single inverter, so I think the additional power dissipation caused by this situation is negligible compared to the sum of leakage current and normal switching power consumption

But, these three considerations aside, if you’re designing an ASIC or wiring together something with discrete components (a rarity in itself), it’s possible that replacing AND/OR multiplexers with decoders and a three-state buffer could increase the throughput of the digital circuit you’re designing, or just make it easier for you to wire, with fewer things to keep track of. It’s hard to say which approach is better, but it’s certainly important to understand how to use both effectively, because many situations will call for one or the other for optimal performance.

Finally, a quick Verilog reference (because the Internet is thoroughly lacking in this department), I find the easiest way to implement a three-state bus is with structural Verilog, defining a module to handle the three-state output (although sometimes it can be incorporated into a larger module). In this case, the module has a parameterized width, and it is used to build a mux of parameterized width as well:

// sel = 0: A => C
// sel = 1: B => C
module mux2x1(A, B, C, sel);
	parameter width = 32;

	input [width-1:0] A;
	input [width-1:0] B;
	input sel;

	output [width-1:0] C;

	en_buffer #(.width(width)) selected (.A(B), .C(C), .EN(sel));
	en_buffer #(.width(width)) not_selected (.A(A), .C(C), .EN(~sel));

endmodule

module en_buffer(A, C, EN);
	parameter width = 32;

	input [width-1:0] A;
	input EN;

	output [width-1:0] C;

	assign C = (EN ? A : {(width){1'bz}});

endmodule

1 person likes this post.

Posted in Hardware.

Tagged with .


0 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.



Some HTML is OK

or, reply to this post via trackback.