اصول کار multiplexer ها توضیح داده شود

The Case-When statement will cause the program to take one out of multiple different paths, depending on the value of a signal, variable, or expression. It’s a more elegant alternative to an If-Then-Elsif-Else statement with multiple Elsif’s.

Other programming languages have similar constructs, using keywords such as a switch, case, or select. Among other things, Case-When statements are commonly used for implementing multiplexers in VHDL. Continue reading, or watch the video to find out how!

This blog post is part of the Basic VHDL Tutorials series.

The basic syntax for the Case-When statement is:
case <expression> is
when <choice> =>
code for this branch
when <choice> =>
code for this branch
...
end case;

The <expression> is usually a variable or a signal. The Case statement may contain multiple when choices, but only one choice will be selected.

The <choice> may be a unique value like "11":
when "11" =>

Or it can be a range like 5 to 10:
when 5 to 10 =>

It can contain several values like 1|3|5:
when 1|3|5 =>

And most importantly, the others choice. It is selected whenever no other choice was matched:
when others =>

The others choice is equivalent to the Else branch in the If-Then-Elsif-Else statement.


library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity T14_CaseWhenTb is
end entity;

architecture sim of T14_CaseWhenTb is

signal Sig1 : unsigned(7 downto 0) := x"AA";
signal Sig2 : unsigned(7 downto 0) := x"BB";
signal Sig3 : unsigned(7 downto 0) := x"CC";
signal Sig4 : unsigned(7 downto 0) := x"DD";

signal Sel : unsigned(1 downto 0) := (others => '0');

signal Output1 : unsigned(7 downto 0);
signal Output2 : unsigned(7 downto 0);

begin

-- Stimuli for the selector signal
process is
begin
wait for 10 ns;
Sel <= Sel + 1;
wait for 10 ns;
Sel <= Sel + 1;
wait for 10 ns;
Sel <= Sel + 1;
wait for 10 ns;
Sel <= Sel + 1;
wait for 10 ns;
Sel <= "UU";
wait;
end process;

-- MUX using if-then-else
process(Sel, Sig1, Sig2, Sig3, Sig4) is
begin

if Sel = "00" then
Output1 <= Sig1;
elsif Sel = "01" then
Output1 <= Sig2;
elsif Sel = "10" then
Output1 <= Sig3;
elsif Sel = "11" then
Output1 <= Sig4;
else -- 'U', 'X', '-' etc.
Output1 <= (others => 'X');
end if;

end process;

-- Equivalent MUX using a case statement
process(Sel, Sig1, Sig2, Sig3, Sig4) is
begin

case Sel is
when "00" =>
Output2 <= Sig1;
when "01" =>
Output2 <= Sig2;
when "10" =>
Output2 <= Sig3;
when "11" =>
Output2 <= Sig4;
when others => -- 'U', 'X', '-', etc.
Output2 <= (others => 'X');
end case;

end process;

end architecture;

First, we created a process using If-Then-Elsif-Else that would forward one of the signals Sig1, Sig2, Sig3, or Sig4, based on the value of the selector signal Sel.

Then we created a process that did exactly the same, using the Case-When statement. We can see from the waveform that the output signals from the two processes, Output1 and Output2, behave exactly the same.

In our example, the Sel signal has only four legal values. But if there had been a higher number of possibilities, we can easily see that the Case-When statement can help making code more readable. This is the preferred way of creating such a component by most VHDL designers.

Understanding of the multiplexer was the bonus point of this exercise. Multiplexers, or MUX’s for short, are central components in digital design. It is simply a switch that selects one of several inputs, and forwards it to the output.

This is an illustration of how our MUX forwards the selected input signal:
mux
We used the others clause to catch all values of Sel which were not ones or zeros. As we learned in the std_logic tutorial, these signals can have a number of values which are not '0' or '1'. It’s good design practice to deal with these values by outputting 'X'. This indicates an unknown value on this signal, and it will be visible in downstream logic as well.

We can see from the waveform that when the Sel signal turned red, Output1 and Output2 also changed to "XX". This is when others => in action.

Additionally, the console output in ModelSim shows a warning because of the Sel signal being set to "UU". The “** Warning: NUMERIC_STD.”=”: metavalue detected, returning FALSE” messages appear at 50 ns simulation time, which is exactly when the signals turn red.

Case-When can be used instead of multiple If-Then-Elsif statements
The when others => can be used to implement a default choice
Multiplexers are preferably created using Case-When statements