If
和case语句是VHDL里边两个非常重要的语句,如何用好她们来描述逻辑电路和时序电路是学会VHDL编程重要的一步。if 和
case语句有一定的相关性,也有一定的区别。相同的地方是他们可以实现几乎一样的功能。下面主要介绍一下她们之间的区别。
If
语句每个分支之间是有优先级的,综合得到的电路是类似级联的结构。Case语句每个分支是平等的,综合得到的电路则是一个多路选择器。因此,多个if
elseif语句综合得到的逻辑电路延时往往比case语句要大。一些初学者在一开始往往喜欢用if
elsif语句,因为这种语法表达起来更加直接,但是在运行速度比较关键的项目中,使用case语句的效果会更好。下面的例子给出了if语句和case语句的综合结果:
http://www.eefocus.com/data/myspace/3/19038//blog/fe5505c1.jpg
If 语句综合结果
http://www.eefocus.com/data/myspace/3/19038//blog/8a2c41a1.jpg
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;
加载中,请稍候......