You are on page 1of 6

Multiplexers

XST supports different description styles for multiplexers, such as If-Then-Else or Case. When writing MUXs, you must pay particular attention in order to avoid common traps. For example, if you describe a MUX using a Case statement, and you do not specify all values of the selector, you may get latches instead of a multiplexer. Writing MUXs you can also use "don't cares" to describe selector values. During the macro inference step, XST makes a decision to infer or not infer the MUXs. For example, if the MUX has several inputs that are the same, then XST can decide not to infer it. In the case that you do want to infer the MUX, you can force XST by using the design constraint called mux_extract. If you use Verilog, then you have to be aware that Verilog Case statements can be full or not full, and they can also be parallel or not parallel. A Case statement is:

FULL if all possible branches are specified PARALLEL if it does not contain branches that can be executed simultaneously

The following tables gives three examples of Case statements with different characteristics.

Full and Parallel Case

module full (sel, i1, i2, i3, i4, o1); input [1:0] sel; input [1:0] i1, i2, i3, i4; output [1:0] o1; reg [1:0] o1; always @(sel or i1 or i2 or i3 or i4) begin case (sel) 2'b00: o1 = i1; 2'b01: o1 = i2; 2'b10: o1 = i3; 2'b11: o1 = i4; endcase end endmodule

not Full but Parallel

module notfull (sel, i1, i2, i3, o1); input [1:0] sel; input [1:0] i1, i2, i3; output [1:0] o1; reg [1:0] o1; always @(sel or i1 or i2 or i3) begin case (sel) 2'b00: o1 = i1; 2'b01: o1 = i2; 2'b10: o1 = i3; endcase end endmodule

neither Full nor Parallel

module notfull_notparallel (sel1, sel2, i1, i2, o1); input [1:0] sel1, sel2; input [1:0] i1, i2; output [1:0] o1; reg [1:0] o1; always @(sel1 or sel2) begin case (2'b00) sel1: o1 = i1;

sel2: o1 = i2; endcase end endmodule XST automatically determines the characteristics of the Case statements and generates logic using Multiplexers, Priority Encoders and Latches that best implement the exact behavior of the Casestatement. This characterization of the Case statements can be guided or modified by using the Case Implementation Style parameter (Please refer to the "Design Constraints" chapter for more details). Accepted values for this parameter are default, full, parallel and full-parallel:

If the default is used, XST will implement the exact behavior of the Case statements. If full is used, XST will consider that Case statements are complete and will avoid latch creation. If parallel is used, XST will consider that the branches cannot occur in parallel and will not use a priority

encoder.

If full-parallel is used, XST will consider that Case statements are complete and that the branches cannot occur in parallel, therefore saving latches and priority encoders. The following table indicates the resources used to synthesize the three examples above using the four Case Implementation Styles. The term "resources" means the functionality. For example, if using "notfull_notparallel" with the Case Implementation Style "default", from the functionality point of view, XST will implement Priority Encoder + Latch. But, it does not inevitably mean that XST will infer the priority encoder during the macro recognition step.

Case Implementation Full notfull notfull_notparallel


default parallel full full-parallel MUX Latch Latch MUX MUX Priority Encoder + Latch Latch Priority Encoder MUX

Note Specifying full, parallel or full-parallel may result in an implementation with a behavior that may differ from the behavior of the initial model.
Log File
The XST log file reports the type and size of recognized MUXs during the macro recognition step: ... Synthesizing Unit <mux>. Related source file is multiplexers_1.vhd. Found 1-bit 4-to-1 multiplexer for signal <o>. Summary: inferred 1 Multiplexer(s). Unit <mux> synthesized. ============================= HDL Synthesis Report Macro Statistics # Multiplexers : 1

1-bit 4-to-1 multiplexer : 1 ============================== ...

Related Constraints
Related constraints are mux_extract and mux_style.

4-to-1 1-bit MUX using IF Statement


The following table shows pin definitions for a 4-to-1 1-bit MUX using an If statement.

IO Pins Description
a, b, c, d s[1:0] o Data Inputs MUX selector Data Output

VHDL Code
Following is the VHDL code for a 4-to-1 1-bit MUX using an If statement. library ieee; use ieee.std_logic_1164.all; entity mux is port (a, b, c, d : in std_logic; s : in std_logic_vector (1 downto 0); o : out std_logic); end mux; architecture archi of mux is begin process (a, b, c, d, s) begin if (s = "00") then o <= a; elsif (s = "01") then o <= b; elsif (s = "10") then o <= c; else o <= d; end if; end process; end archi;

Verilog Code
Following is the Verilog code for a 4-to-1 1-bit MUX using an If Statement. module mux (a, b, c, d, s, o); input a,b,c,d; input [1:0] s; output o; reg o; always @(a or b or c or d or s) begin if (s == 2'b00) o = a; else if (s == 2'b01) o = b; else if (s == 2'b10) o = c; else o = d; end endmodule

4-to-1 MUX Using CASE Statement


The following table shows pin definitions for a 4-to-1 1-bit MUX using a Case statement.

IO Pins Description
a, b, c, d s[1:0] o Data Inputs MUX selector Data Output

VHDL Code
Following is the VHDL code for a 4-to-1 1-bit MUX using a Case statement. library ieee; use ieee.std_logic_1164.all;

entity mux is
port (a, b, c, d : in std_logic; s : in std_logic_vector (1 downto 0); o : out std_logic); end mux; architecture archi of mux is begin process (a, b, c, d, s) begin case s is when "00" => o <= a; when "01" => o <= b; when "10" => o <= c; when others => o <= d; end case; end process; end archi;

Verilog Code
Following is the Verilog Code for a 4-to-1 1-bit MUX using a Case statement. module mux (a, b, c, d, s, o); input a,b,c,d; input [1:0] s; output o; reg o; always @(a or begin case (s) 2'b00 : 2'b01 : 2'b10 : default : endcase end endmodule b or c or d or s) o o o o = = = = a; b; c; d;

4-to-1 MUX Using Tristate Buffers


This section shows VHDL and Verilog examples for a 4-to-1 Mux using tristate buffers The following table shows pin definitions for a 4-to-1 1-bit MUX using tristate buffers.

IO Pins Description
a, b, c, d s[3:0] o Data Inputs MUX Selector Data Output

VHDL Code
Following is the VHDL code for a 4-to-1 1-bit MUX using tristate buffers. library ieee; use ieee.std_logic_1164.all; entity mux is port (a, b, c, d : in std_logic; s : in std_logic_vector (3 downto 0); o : out std_logic); end mux; architecture archi of mux is begin o o o o <= <= <= <= a b c d when when when when (s(0)='0') (s(1)='0') (s(2)='0') (s(3)='0') else else else else 'Z'; 'Z'; 'Z'; 'Z';

end archi;

Verilog Code
Following is the Verilog Code for a 4-to-1 1-bit MUX using tristate buffers. module mux (a, b, c, d, s, o); input a,b,c,d; input [3:0] s; output o; assign assign assign assign o o o o = = = = s[3] s[2] s[1] s[0] ? ? ? ? a b c d :1'bz; :1'bz; :1'bz; :1'bz;

endmodule

No 4-to-1 MUX
The following example does not generate a 4-to-1 1-bit MUX, but 3-to-1 MUX with 1-bit latch. The reason is that not all selector values were described in the If statement. It is supposed that for the s=11 case, "O" keeps its old value, and therefore a memory element is needed. The following table shows pin definitions for a 3-to-1 1-bit MUX with a 1-bit latch.

IO Pins Description
a, b, c, d s[1:0] o Data Inputs Selector Data Output

VHDL Code
Following is the VHDL code for a 3-to-1 1-bit MUX with a 1-bit latch. library ieee; use ieee.std_logic_1164.all; entity mux is port (a, b, c, d : in std_logic; s : in std_logic_vector (1 downto 0); o : out std_logic); end mux; architecture archi of mux is begin process (a, b, c, d, s) begin if (s = "00") then o <= a; elsif (s = "01") then o <= b; elsif (s = "10") then o <= c; end if; end process; end archi;

Verilog Code
Following is the Verilog code for a 3-to-1 1-bit MUX with a 1-bit latch. module mux (a, b, c, d, s, o); input a,b,c,d; input [1:0] s; output o; reg o; always @(a or b or c or d or s) begin if (s == 2'b00) o = a; else if (s == 2'b01) o = b; else if (s == 2'b10) o = c; end endmodule