Return to previous page Advance to next page

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:

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 Case statement.

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:

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
MUX
Latch
Priority Encoder + Latch
parallel

Latch
Latch
full

MUX
Priority Encoder
full-parallel

MUX
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
Data Inputs
s[1:0]
MUX selector
o
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
Data Inputs
s[1:0]
MUX selector
o
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 b or c or d or s) 
  begin 
    case (s) 
      2'b00   : o = a; 
      2'b01   : o = b; 
      2'b10   : o = c; 
      default : o = d; 
    endcase 
  end 
endmodule 

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
Data Inputs
s[3:0]
MUX Selector
o
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 <= a when (s(0)='0') else 'Z'; 
o <= b when (s(1)='0') else 'Z'; 
o <= c when (s(2)='0') else 'Z'; 
o <= d when (s(3)='0') else '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 o = s[3] ? a :1'bz; 
assign o = s[2] ? b :1'bz; 
assign o = s[1] ? c :1'bz; 
assign o = s[0] ? d :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
Data Inputs
s[1:0]
Selector
o
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 

Return to previous page Advance to next page