文章目录
VHDL的操作符号
VHDL赋值运算符
VHDL语言中共有3种赋值符号——“<=”、“:=”和“=>”。
<=
“<=”符号为signal专用,对signal的赋值能且只能使用“<=”赋值符号。 举例如下:
signal a : std_logic;
a <= ‘1’;
“<=”符号是一种有延迟的赋值,即赋值操作不是立即生效的。编译器会根据你代码所描述的功能以及在程序中所处的位置,来决定产生这种延迟的硬件逻辑结构是组合逻辑还是时序逻辑。
:=
单独使用时,“:=”符号为variable专用,对variable的赋值能且只能使用“:=”赋值符号。举例如下:
variable b : std_logic;
b := ‘0’;
此时,“:=”符号是一种无延迟的赋值,即赋值操作立即生效,这点与软件编程的思路很像。
除此以外,“:=”符号还有一种用途,就是初始化赋值。这个时候“:=”是依附于声明语句而使用的,应用的对象可以是signal、variable以及constant中的任何一种。
=>
“=>”符号为映射赋值符号,从某种意义上来说,它不能算是一种赋值运算符,而应该是一种连线符号,因为它只是为赋值符号的左右两边建立起一种连接关系而已。 因此与“<=”和“:=”不同,“=>”本身并不明确表示赋值的方向关系,即到底是把左边的数据写到右边去还是把右边的数据写到左边去。而对于“<=”和“:=”来说,赋值的方向显然非常明显,为从右至左。Architecture中的例化语句就是映射赋值符号应用的一个典型例子,无论端口方向是in还是out,都一律使用“=>”来进行映射赋值,至于赋值的方向,编译器会根据上下文自己去推断。
“=>”符号应用的地方很多,刚刚提到的元件例化语句(instance)的赋值语法如下:
<instance_name> : <component_name>
port map (
<port_name> => <signal_name>,
<other ports>...
);
而信号量的映射赋值则稍有不同,例如:
signal a, b : std_logic_vector(3 downto 0);
a <= (0 => ‘1’, 2 => '1', others => '0'); -- a = ”0101”
b <= (others => ‘1’); -- b = “1111”;
注意这里面有一个新的语法others,这在对逻辑向量赋值时非常好用,能够帮我们方便的完成一些高位宽向量的赋值。并且,类似像b这样的信号赋值,即是以后代码修改、扩展或减少了b的bit位数,赋值语句也可以不需要做任何修改,非常便于程序的维护和变更。
位置赋值
VHDL语言中仅有的三种赋值符号都已经介绍完了,可是赋值操作的形式并没有就此终结。除了以上三种赋值形式外,VHDL语言还有一种基于位置赋值的方式,这种赋值方式其实也属于映射赋值的范畴,但它不需要任何操作符,编译器仅仅根据参数的位置就可以进行映射赋值。
在VHDL语言中,元件例化、过程及函数调用都可以这样赋值,这一点跟C语言的函数调用非常类似。不过对于凡是支持“=>”符号来进行映射赋值地方,建议大家还是不要使用位置赋值,因为映射赋值是位置无关的,这样会在很大程度上减少程序出错的可能性,并且方便日后的修改与维护。
VHDL按位运算符
按位运算符是一类最基本的运算符,可以认为它们直接对应数字逻辑中的与、或、非门等逻辑门,在VHDL中它们的描述如下:
NOT
NOT是取反运算符。它是一个单目运算符,即作用于一个操作数,对它进行按位取反。相当于数字逻辑电路中的“非门”,例如:
signal a : std_logic := '1';
signal b : std_logic_vector (3 downto 0) := "1000";
a <= not a; -- a = '0'
b <= not b; -- b = "0111"
AND
AND是与运算符。它是一个双目运算符,即必须有两个操作数,对它们进行按位与运算,相当于数字逻辑电路中的“与门”。例如:
signal a0 : std_logic := '1';
signal b0 : std_logic := '1';
signal c0 : std_logic;
signal a1 : std_logic_vector (3 downto 0) := "1101";
signal b1 : std_logic_vector (3 downto 0) := "1011";
signal c1 : std_logic_vector (3 downto 0);
c0 <= a0 and b0; -- c0 = '1'
c1 <= a1 and b1; --</