我是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;
答案 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位 - 这也可以。
我会更进一步,根据需要声明所有类型正确的端口signed
或unsigned
,并消除大多数不必要的类型转换,这些转换不会为了可读性而做任何事情。这也将完全消除内部信号,因为设计的冗长程度要小得多。
答案 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),这样可能会在模拟过程中引起问题。