0

我有两个设计:

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 中强制 a 具有“00”而 b 具有“0L”表明 o 变为“0”。所以L不被解释为0,“00”=“0L”是假的。好的。

但是当我采用相同的设计并添加

use ieee.std_logic_unsigned.all;

到列表中,行为是不同的。然后 "00" = "0L" 返回真,所以 L IS 与 0 相同(0 变为 '1')。包括未签名的包,即使“0X”=“0Z”返回true。

谁能解释为什么?

4

3 回答 3

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。

于 2013-07-23T15:11:50.023 回答
2

简短的回答是std_logic_unsigned,以及它的预期替换numeric_std_unsigned,正确地将“H”和“L”处理为“1”和“0”。

“无符号”包将 std_logic_unsigned 视为无符号数值。这里有一些好处:

  • 正确处理“H”和“L”
  • 输入的数值处理,尤其是当它们大小不同时
  • 支持将 std_logic_vector 与整数混合 ( Addr = 0) 而不是 ( Addr = "0000")
  • 重载 >、>=、<、<=,因此它们进行数学排序而不是字典排序。如果尺寸不同,这很重要。

在供应商(综合)实现 VHDL-2008 匹配关系运算符之前?= ?/= ?> ?>= ?<?<=我建议您使用这些包之一。当他们实现匹配关系时,我建议在新设计中使用它们。

有关 VHDL-2008 功能的更多信息,请参阅http://www.synthworks.com/blog/vhdl-standards/

于 2013-07-23T15:46:40.960 回答
2

查看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 中的语义等价

于 2013-07-23T09:11:18.677 回答