尝试在VHDL中模拟电路时出现“范围约束违规”错误

时间:2016-09-20 19:09:38

标签: integer vhdl unsigned signed bitvector

我是VHDL的新手,我正在尝试按如下方式模拟一个块:

  1. 它有四个std_logic_vector个输入,名为abcd。 输入ab是有符号数字,输入cd是 无符号数。
  2. 它有四个名为uvwx的输出。输出uv 已签名的数字和输出wx是无符号数字。
  3. 输出定义如下:

    u = a + b

    v = a / 2

    w = c * d

    x = c * 2

  4. 内部信号是整数。

  5. 我能够编译模块和测试台。我遇到的问题是,当我尝试模拟电路时,会显示以下错误消息:

    ncsim: *E,TRRANGEC: range constraint violation.
              File: ./operator2.vhd, line = 38, pos = 36
             Scope: :inst_operator:$PROCESS_007
              Time: 0 FS + 0
    

    因此,模拟器无法启动。我不明白这条线怎么可能是错的:

    x <= std_logic_vector(to_unsigned(sx, 17));
    

    我尝试过改变这一行与其他那些做同样的行,我在同一行得到错误。如果我删除此行,则会在第37行报告错误。您能否给我一个提示,以找出我的错误?以下是该模块的代码:

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    
    entity operator2 is
        port(
            a: in std_logic_vector(15 downto 0);
            b: in std_logic_vector(15 downto 0);
            c: in std_logic_vector(15 downto 0);
            d: in std_logic_vector(15 downto 0);
            u: out std_logic_vector(16 downto 0);
            v: out std_logic_vector(14 downto 0);
            w: out std_logic_vector(31 downto 0);
            x: out std_logic_vector(16 downto 0)
        );
    
    end entity operator2;
    
    architecture a2 of operator2 is
    
        signal su: integer;
        signal sv: integer;
        signal sw: integer;
        signal sx: integer;
    
    begin
    
        --signals affectation
        su <= to_integer(signed(a)) + to_integer(signed(b));
        sv <= to_integer(signed(a)) / 2;
        sw <= to_integer(unsigned(c)) * to_integer(unsigned(d));
        sx <= to_integer(unsigned(c)) * 2;
    
        --outputs affectation
        u <= std_logic_vector(to_signed(su, 17));
        v <= std_logic_vector(to_signed(sv, 15));
        w <= std_logic_vector(to_unsigned(sw, 32));
        x <= std_logic_vector(to_unsigned(sx, 17)); --This is the line reporting the error during the simulation**
    
    end architecture a2;
    

2 个答案:

答案 0 :(得分:1)

第37行是错误:VHDL中自然的最大范围是31位(因为自然是整数范围的非负子集),因此具有32位范围的to_unsigned是...有问题的(非正式地,大卫很可能会很快与LRM参考)。为什么你的模拟器报错了,我无法回答。 GHDL报告&#34;错误:在operator2.vhd:37&#34;如预期的那样。

请注意,REAL问题是这一行:

 sw <= to_integer(unsigned(c)) * to_integer(unsigned(d));

试图将两个16位无符号的乘积填充到一个31位正范围的整数中,这......并不总是有效。

我建议制作&#34; sw&#34; 32位无符号不是整数,它将正确处理整个范围。

为了清晰起见,我考虑对其他内部信号做同样的事情。没有必要在数值范围的基础上这样做,但如果你将它们保持为&#34;整数&#34;最好改进他们的声明以使设计意图明确:

signal sx: integer;                   -- obscures the design
signal sx: natural range 0 to 131071; -- documents the intent

如果您这样做了,您可能会更快地看到问题。

正如评论中指出的那样,使用natural而不是integer会提供有效的默认值(natural'left = 0)而不是无法转换为unsigned的默认值}(integer'left = -2 ** 31)

或者,在其输入(C和D)上提供保证 - 如果您可以将其中至少一个限制为15位 - 这也可以。

我会更进一步,根据需要声明所有类型正确的端口signedunsigned,并消除大多数不必要的类型转换,这些转换不会为了可读性而做任何事情。这也将完全消除内部信号,因为设计的冗长程度要小得多。

答案 1 :(得分:1)

使用整数值时,应初始化它们的值。在你的信号(su,sv,sw和sx)中你必须这样做,因为它们是整数值(从-2 ^ 31到2 ^ 31)。 请尝试:

signal su: integer :=0;
signal sv: integer :=0;
signal sw: integer :=0;
signal sx: integer :=0;

如果你没有初始化它们,它们将取最高值(2 ^ 31),这样可能会在模拟过程中引起问题。