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.
|
(sel, i1, i2, i3, i4, o1);
input [1:0] i1, i2, i3, i4;
always @(sel or i1 or i2 or i3 or i4)
|
|
always @(sel or i1 or i2 or i3)
|
neither Full nor Parallel
|
module notfull_notparallel
(sel1, sel2, i1, i2, o1);
|
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:
- 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.
|
|
|
|
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:
Related source file is multiplexers_1.vhd.
Found 1-bit 4-to-1 multiplexer for signal <o>.
inferred 1 Multiplexer(s).
=============================
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.
|
|
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.
|
|
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;
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.
|
|
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.
|
|
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
沒有留言:
張貼留言