如何在 VHDL 中使用 Case-When 语句
Case-When 语句将导致程序根据信号、变量或表达式的值从多个不同路径中取一个。它是具有多个 Elsif 的 If-Then-Elsif-Else 语句的更优雅的替代方案。
其他编程语言也有类似的结构,使用诸如 switch 之类的关键字 , 案例 ,或选择 .除此之外,Case-When 语句通常用于在 VHDL 中实现多路复用器。继续阅读,或观看视频了解如何操作!
这篇博文是基本 VHDL 教程系列的一部分。
Case-When 语句的基本语法是:case <expression> is
when <choice> =>
code for this branch
when <choice> =>
code for this branch
...
end case;
<expression> 通常是变量或信号。 Case语句可能包含多个when 选项,但只会选择一个选项。
<choice> 可能是像 "11" 这样的唯一值 :when "11" =>
或者它可以是像 5 to 10 这样的范围 :when 5 to 10 =>
它可以包含多个值,例如 1|3|5 :when 1|3|5 =>
最重要的是,others 选择。只要没有其他选择匹配,就会选择它:when others =>
others 选择相当于 Else If-Then-Elsif-Else 语句中的分支。
运动
在本视频教程中,我们将学习如何使用 VHDL 中的 Case-When 语句创建多路复用器:
我们在本教程中创建的最终代码:
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;
我们按下运行后 ModelSim 中的波形窗口,并在时间轴上放大:
当我们在 ModelSim 中按下运行按钮时,模拟器控制台的输出:
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
分析
首先,我们使用 If-Then-Elsif-Else 创建了一个进程,该进程将转发其中一个信号 Sig1 , Sig2 , Sig3 , 或 Sig4 ,基于选择器信号 Sel 的值 .
然后我们使用 Case-When 语句创建了一个完全相同的流程。从波形中我们可以看出两个进程的输出信号,Output1 和 Output2 , 行为完全相同。
在我们的示例中,Sel 信号只有四个合法值。但是如果有更多的可能性,我们可以很容易地看到 Case-When 语句可以帮助使代码更具可读性。这是大多数 VHDL 设计人员创建此类组件的首选方式。
了解多路复用器 是这个练习的奖励点。多路复用器,或简称 MUX,是数字设计中的核心组件。它只是一个开关,可以选择多个输入中的一个,并将其转发到输出。
这是我们的 MUX 如何转发所选输入信号的说明:
我们使用了 others 捕获 Sel 的所有值的子句 这不是一或零。正如我们在 std_logic 教程中了解到的,这些信号可以有许多不是 '0' 的值 或 '1' .通过输出 'X' 来处理这些值是一种很好的设计实践 .这表示该信号上的未知值,并且在下游逻辑中也是可见的。
从波形中我们可以看出,当Sel 信号变红,Output1 和 Output2 也改为"XX" .这是 when others => 在行动中。
此外,由于 Sel,ModelSim 中的控制台输出显示警告 信号设置为 "UU" . “** Warning:NUMERIC_STD.”=”:metavalue detected, returned FALSE”消息出现在 50 ns 仿真时间,这正是信号变为红色的时间。
外卖
- 可以使用 Case-When 代替多个 If-Then-Elsif 语句
when others =>可用于实现默认选择- 最好使用 Case-When 语句创建多路复用器
转到下一个教程 »
VHDL