"range constraint violation" 尝试在 VHDL 中模拟电路时出错
"range constraint violation" error when trying to simulate a circuit in VHDL
我是 VHDL 的新手,我正在尝试如下模拟一个块:
- 它有四个
std_logic_vector
输入,名称为 a
、b
、c
和 d
。
输入 a
和 b
是有符号数,输入 c
和 d
是
无符号数。
- 它有四个输出名为
u
、v
、w
和 x
。输出 u
和 v
是有符号数,输出 w
和 x
是无符号数。
输出定义如下:
u = a + b
v = a / 2
w = c * d
x = c * 2
内部信号为整数。
我能够编译模块和测试平台。我遇到的问题是当我尝试模拟电路时显示以下错误消息:
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;
第 37 行是错误:VHDL 中自然数的最大范围是 31 位(因为自然数是整数范围的非负子集)所以 to_unsigned
32 位范围是 .. . 有问题(非正式地,David 可能很快就会与 LRM 参考资料一起使用)。为什么你的模拟器报错行,我答不上来。 GHDL 按预期报告 "error: bound check failure at operator2.vhd:37"。
请注意,真正的问题是这一行:
sw <= to_integer(unsigned(c)) * to_integer(unsigned(d));
它试图将两个 16 位无符号数的乘积填充到具有 31 位正数范围的整数中,这...并不总是有效。
我建议将 "sw" 设为 32 位无符号整数,而不是整数,这样可以正确处理整个范围。
为了清楚起见,我会考虑对其他内部信号做同样的事情。没有必要在数值范围的基础上这样做,但如果你将它们保持为 "integer",最好改进它们的声明以使设计意图明确:
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 位 - 那也可以。
我会更进一步,声明所有正确类型的端口,signed
或 unsigned
视情况而定,并消除大多数不必要的类型转换,这些转换对可读性没有任何作用。这也将完全消除内部信号,从而大大减少冗长的设计。
当您使用整数值时,您应该初始化它们的值。在您的信号(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),这样可能会在模拟过程中出现问题。
我是 VHDL 的新手,我正在尝试如下模拟一个块:
- 它有四个
std_logic_vector
输入,名称为a
、b
、c
和d
。 输入a
和b
是有符号数,输入c
和d
是 无符号数。 - 它有四个输出名为
u
、v
、w
和x
。输出u
和v
是有符号数,输出w
和x
是无符号数。 输出定义如下:
u = a + b
v = a / 2
w = c * d
x = c * 2
内部信号为整数。
我能够编译模块和测试平台。我遇到的问题是当我尝试模拟电路时显示以下错误消息:
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;
第 37 行是错误:VHDL 中自然数的最大范围是 31 位(因为自然数是整数范围的非负子集)所以 to_unsigned
32 位范围是 .. . 有问题(非正式地,David 可能很快就会与 LRM 参考资料一起使用)。为什么你的模拟器报错行,我答不上来。 GHDL 按预期报告 "error: bound check failure at operator2.vhd:37"。
请注意,真正的问题是这一行:
sw <= to_integer(unsigned(c)) * to_integer(unsigned(d));
它试图将两个 16 位无符号数的乘积填充到具有 31 位正数范围的整数中,这...并不总是有效。
我建议将 "sw" 设为 32 位无符号整数,而不是整数,这样可以正确处理整个范围。
为了清楚起见,我会考虑对其他内部信号做同样的事情。没有必要在数值范围的基础上这样做,但如果你将它们保持为 "integer",最好改进它们的声明以使设计意图明确:
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 位 - 那也可以。
我会更进一步,声明所有正确类型的端口,signed
或 unsigned
视情况而定,并消除大多数不必要的类型转换,这些转换对可读性没有任何作用。这也将完全消除内部信号,从而大大减少冗长的设计。
当您使用整数值时,您应该初始化它们的值。在您的信号(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),这样可能会在模拟过程中出现问题。