我有两个设计:
library ieee;
use ieee.std_logic_1164.all;
entity eq_test1 is
port (a,b : IN std_logic_vector (1 downto 0);
o : OUT std_logic);
end eq_test1;
architecture strange_behavior of eq_test1 is
begin
P: process (a,b)
begin
if a = b then o <= '1';
else o <= '0';
end if;
end process P;
end strange_behavior;
强制在Modelsim中有一个“00”而b有一个“0L”表示o变为'0'。 因此L不被解释为0,“00”=“0L”为假。确定。
但是当我采用相同的设计并添加
时use ieee.std_logic_unsigned.all;
到列表中,行为是不同的。 然后“00”=“0L”返回true,因此L IS与0相同(0变为“1”)。 包含未签名的包,即使“0X”=“0Z”也返回true。
任何人都可以解释原因吗?
答案 0 :(得分:5)
添加use ieee.std_logic_unsigned.all;
就像打开潘多拉盒子一样
Synopsys库。经过下面的深潜,得出结论是
在这种情况下,std_logic_unsigned包使值'0'和'L'相等
通过一张桌子。
当“=”运算符重新定义为:
时,调用开始function "="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is
begin
return UNSIGNED(L) = UNSIGNED(R);
end;
然而,这仅仅是开始,因为std_logic_unsigned包括
use IEEE.std_logic_arith.all;
,定义了类型:
type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
“=”中UNSIGNED的比较因此导致调用std_logic_arith函数:
function "="(L: UNSIGNED; R: UNSIGNED) return BOOLEAN is
-- synopsys subpgm_id 341
constant length: INTEGER := max(L'length, R'length);
begin
return bitwise_eql( STD_ULOGIC_VECTOR( CONV_UNSIGNED(L, length) ),
STD_ULOGIC_VECTOR( CONV_UNSIGNED(R, length) ) );
end;
在这个函数中,CONV_UNSIGNED很有意思:
function CONV_UNSIGNED(ARG: UNSIGNED; SIZE: INTEGER) return UNSIGNED is
constant msb: INTEGER := min(ARG'length, SIZE) - 1;
subtype rtype is UNSIGNED (SIZE-1 downto 0);
variable new_bounds: UNSIGNED (ARG'length-1 downto 0);
variable result: rtype;
-- synopsys built_in SYN_ZERO_EXTEND
-- synopsys subpgm_id 372
begin
-- synopsys synthesis_off
new_bounds := MAKE_BINARY(ARG);
if (new_bounds(0) = 'X') then
result := rtype'(others => 'X');
return result;
end if;
result := rtype'(others => '0');
result(msb downto 0) := new_bounds(msb downto 0);
return result;
-- synopsys synthesis_on
end;
现在我们接近了,因为上面的电话:
function MAKE_BINARY(A : UNSIGNED) return UNSIGNED is
-- synopsys built_in SYN_FEED_THRU
variable one_bit : STD_ULOGIC;
variable result : UNSIGNED (A'range);
begin
-- synopsys synthesis_off
for i in A'range loop
if (IS_X(A(i))) then
assert false
report "There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)."
severity warning;
result := (others => 'X');
return result;
end if;
result(i) := tbl_BINARY(A(i));
end loop;
return result;
-- synopsys synthesis_on
end;
在这里,我们有'L'等于'0'的原因,因为tbl_BINARY 是一个常量定义为:
type tbl_type is array (STD_ULOGIC) of STD_ULOGIC;
constant tbl_BINARY : tbl_type :=
('X', 'X', '0', '1', 'X', 'X', '0', '1', 'X');
要理解这种映射,与它的定义一致是有用的 STD_ULOGIC中的值:
std_ulogic: ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-');
tbl_BINARY: ( 'X', 'X', '0', '1', 'X', 'X', '0', '1', 'X');
这表明通过tbl_BINARY转换后的等效组 是('U','X','Z','W',' - '),('0','L')和('1','H')。
结束评论是即使通过std_logic_unsigned包驻留 在一个名为“ieee”的库中,该包不是像VHDL那样的IEEE标准,而是一个 Synopsys包。该软件包以及其他相关的Synopsys软件包具有 已经存在了一段时间并被广泛使用。
但是,您可以考虑使用IEEE标准包numeric_std。
答案 1 :(得分:2)
简短的回答是std_logic_unsigned
及其预定的替代numeric_std_unsigned
,正确处理了&#39; H&#39;和&#39; L&#39;作为&#39; 1&#39;和&#39; 0&#39;。
&#34; unsigned&#34;包将std_logic_unsigned视为无符号数值。以下是一些好处:
Addr = 0
)混合而不是(Addr = "0000"
)在供应商(综合)实施VHDL-2008匹配关系运算符?= ?/= ?> ?>= ?<
和?<=
之前,我建议您使用其中一个包。当他们实现匹配关系时,我建议在新设计中使用它们。
有关VHDL-2008功能的更多信息,请参阅http://www.synthworks.com/blog/vhdl-standards/
答案 2 :(得分:1)
查看std_logic_unsigned的定义。它取代了原来的“=”定义如下
function "="(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN is
begin
return UNSIGNED(L) = UNSIGNED(R);
end;
并且由于UNSIGNED类型是一个不知道文字'h'和'l'的整数类型,因此它被解析为整数值,因此'l'变为'0',语义等价于UNSIGNED