2

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

  1. 它有四个std_logic_vector输入,分别命名为a、和。输入和是有符号数,输入和是无符号数。bcdabcd
  2. 它有四个输出,分别名为u、和。输出和 是有符号数,输出和是无符号数。vwxuvwx
  3. 输出定义如下:

    u = a + b

    v = a / 2

    w = c * d

    x = c * 2

  4. 内部信号是整数。

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

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;
4

2 回答 2

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),因此可能会在模拟过程中引起问题。

于 2016-09-21T18:49:11.323 回答
1

第 37 行是错误:VHDL 中 natural 的最大范围是 31 位(因为 natural 是整数范围的非负子集)所以to_unsigned32 位范围是......有问题的(非正式地,大卫可能会一起很快就会有 LRM 参考)。为什么您的模拟器在错误的行上报告它,我无法回答。GHDL 按预期报告“错误:operator2.vhd:37 的绑定检查失败”。

请注意,真正的问题是这一行:

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

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

我建议将“sw”设为 32 位无符号而不是整数,这样可以正确处理整个范围。

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

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

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

正如评论中所指出的,使用natural而不是integer给出一个有效的默认值(natural'left= 0)而不是一个不能转换为unsignedinteger'left= -2**31)

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

我会更进一步,声明正确类型的所有端口,signedunsigned酌情声明,并消除大多数对可读性没有任何作用的不必要的类型转换。这也将完全消除内部信号,从而大大减少冗长的设计。

于 2016-09-20T19:41:31.483 回答