Mastering the Case-When Statement in VHDL: Efficient Multiplexer Design
The Case-When statement directs a VHDL program along one of several paths based on a signal, variable, or expression. It offers a cleaner, more readable alternative to lengthy if-then-elsif-else chains, particularly when handling multiple discrete values.
Many programming languages use constructs like switch or case; in VHDL, the case construct is a staple for building multiplexers and other selection logic.
This article is part of our Basic VHDL Tutorials series.
Basic Syntax
The canonical structure of a case statement is:
case <expression> is
when <choice> =>
-- code for this branch
when <choice> =>
-- code for this branch
...
end case;
The <expression> is typically a signal or variable. Although a case can contain many when branches, only one will execute during simulation.
Each <choice> can be:
- A single value, e.g.,
when "11" => - A range, e.g.,
when 5 to 10 => - A list of values, e.g.,
when 1|3|5 => - The
otherskeyword, which matches any value not explicitly listed.
Practical Exercise: Building a 4-to-1 Multiplexer
Below is the complete VHDL code that demonstrates a 4-to-1 multiplexer implemented with both if-then-elsif and case approaches.
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
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 =>
Output2 <= (others => 'X');
end case;
end process;
end architecture;
After running the simulation in ModelSim, the waveform shows identical behavior for Output1 and Output2. When the selector Sel takes an undefined value (e.g., "UU"), the when others => clause outputs 'X', signaling an unknown state.
The console output contains the following warning at 50 ns, indicating a metavalue comparison:
VSIM 2> run # ** Warning: NUMERIC_STD."=": metavalue detected, returning FALSE # Time: 50 ns Iteration: 1 Instance: /t14_casewhentb # ** Warning: NUMERIC_STD."=": metavalue detected, returning FALSE # Time: 50 ns Iteration: 1 Instance: /t14_casewhentb # ** Warning: NUMERIC_STD."=": metavalue detected, returning FALSE # Time: 50 ns Iteration: 1 Instance: /t14_casewhentb # ** Warning: NUMERIC_STD."=": metavalue detected, returning FALSE # Time: 50 ns Iteration: 1 Instance: /t14_casewhentb
Key Takeaways
- Use
casestatements to replace longif-then-elsifchains for better readability. - Implement a default path with
when others =>to handle unexpected values. - Multiplexers are most cleanly expressed with
caseconstructs in VHDL.
Continue to the next tutorial for more advanced VHDL concepts.
VHDL
- Leveraging In‑Process Procedures for Cleaner VHDL FSM Design
- Using Impure Functions in VHDL: Enhancing FSM Readability and Maintainability
- Mastering VHDL Functions: A Practical Guide to Efficient Design
- Using Procedures in VHDL: Simplify Your Design with Reusable Code
- Leveraging Constants and Generic Maps in VHDL for Flexible Module Design
- Mastering Concurrent Statements in VHDL: A Practical Guide
- Mastering Signed and Unsigned Types in VHDL: A Practical Guide
- Mastering VHDL Wait Statements: Wait On, Wait Until, and Combined Usage
- Mastering While Loops in VHDL: Dynamic Iteration Control
- Mastering For‑Loops in VHDL: A Practical Guide