If 和case语句是VHDL里边两个非常重要的语句,如何用好她们来描述逻辑电路和时序电路是学会VHDL编程重要的一步。if 和 case语句有一定的相关性,也有一定的区别。相同的地方是他们可以实现几乎一样的功能。下面主要介绍一下她们之间的区别。
If 语句每个分支之间是有优先级的,综合得到的电路是类似级联的结构。Case语句每个分支是平等的,综合得到的电路则是一个多路选择器。因此,多个if elseif语句综合得到的逻辑电路延时往往比case语句要大。一些初学者在一开始往往喜欢用if elsif语句,因为这种语法表达起来更加直接,但是在运行速度比较关键的项目中,使用case语句的效果会更好。下面的例子给出了if语句和case语句的综合结果
If 语句综合结果
Case语句综合结果
有关if, case语句另外一个值得一提的东西是在用if或者case语句做逻辑电路的时候,必须为信号设置默认值。有两种方法,第一种方法是在if, case语句之前对目标信号进行赋值,采用这种方法,就不必专门写else或者when others语句对信号进行默认赋值。第二种方法就是在else或者when others语句中对信号进行默认条件下的赋值。如果违反了上述规则,那么会在综合电路的时候形成一个transparent latch,也就是电平触发的锁存器,这对电路的时序分析等会造成很大的麻烦。
在时序电路中,如果没有在else语句或者when others语句中对信号赋值,那么综合工具会认为寄存器保持当前输入。从电路图上看,即把寄存器的输出接回寄存器的输入。
有兴趣的朋友可以用综合工具试一下面的代码,鉴于篇幅,时序电路部分的代码就不贴了,有需要的朋友可以给我留言。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity CaseComb is
port
(aSel : in std_logic_vector(3 downto 0);
aDin : in std_logic_vector(3 downto 0);
aDout : out std_logic);
end CaseComb;
architecture rtl of CaseComb is
begin
process(aSel, aDin)
begin
case aSel is
when "1000" =>
aDout <= aDin(3);
when "0100" =>
aDout <= aDin(2);
when "0010" =>
aDout <= aDin(1);
when "0001" =>
aDout <= aDin(0);
when others =>
--aDout <= '0';
end case;
end process;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity IfComb is
port
(aSel : in std_logic_vector(3 downto 0);
aDin : in std_logic_vector(3 downto 0);
aDout : out std_logic);
end IfComb;
architecture rtl of IfComb is
begin
process(aSel, aDin)
begin
if aSel(3)='1' then
aDout <= aDin(3);
elsif aSel(2)='1' then
aDout <= aDin(2);
elsif aSel(1)='1' then
aDout <= aDin(1);
elsif aSel(0)='1' then
aDout <= aDin(0);
--else
-- aDout <= '0';
end if;
end process;
end rtl;
文章评论(0条评论)
登录后参与讨论