如果我有一个unsigned(MAX downto 0)
包含 value 的值2**MAX - 1
,VHDL (87|93|200X) 标准是否定义了当我将它增加一时会发生什么?(或者,类似地,当我从零减一时?)
3 回答
简短的回答:
没有溢出处理,溢出进位只是丢失了。因此,结果只是您的运算模 2^MAX的整数结果。
更长的答案:
该numeric_std
包是标准包,但它不是 VHDL 标准 (87,93,200X) 的核心。供参考:numeric_std.vhd
最后的+
操作员调用ADD_UNSIGNED (L, R : unsigned; C : std_logic)
函数(with C = '0'
)。请注意,任何整数/自然操作数首先转换为unsigned
.
该函数的定义是:
function ADD_UNSIGNED (L, R : unsigned; C : std_logic) return unsigned is
constant L_left : integer := L'length-1;
alias XL : unsigned(L_left downto 0) is L;
alias XR : unsigned(L_left downto 0) is R;
variable RESULT : unsigned(L_left downto 0);
variable CBIT : std_logic := C;
begin
for i in 0 to L_left loop
RESULT(i) := CBIT xor XL(i) xor XR(i);
CBIT := (CBIT and XL(i)) or (CBIT and XR(i)) or (XL(i) and XR(i));
end loop;
return RESULT;
end ADD_UNSIGNED;
如您所见,如果CBIT='1'
(进位) for会发生“溢出” i = L_left
。结果位RESULT(i)
正常计算,最后一个进位机器人值被忽略。
我遇到了想要unsigned
在 C 或 Verilog 中溢出/下溢的问题,这就是我想出的(result
并且delta
是unsigned
):
result <= unsigned(std_logic_vector(resize(('1' & result) - delta, result'length))); -- proper underflow
result <= unsigned(std_logic_vector(resize(('0' & result) + delta, result'length))); -- proper overflow
因为溢出'0' & result
使得 anunsigned
大 1 位以便能够正确容纳加法的值。然后通过resize
产生正确溢出值的命令删除 MSB。下溢也一样。
对于等于 7 的 MAX 值,将 1 添加到 2**7 - 1 (127) 将得到值 2**7 (128)。
最大无符号值由无符号数组类型的长度决定:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity foo is
end entity;
architecture faa of foo is
constant MAX: natural := 7;
signal somename: unsigned (MAX downto 0) := (others => '1');
begin
UNLABELED:
process
begin
report "somename'length = " & integer'image(somename'length);
report "somename maximum value = " &integer'image(to_integer(somename));
wait;
end process;
end architecture;
聚合(others => '1')
表示每个元素中的“1”somename
是无符号数组类型,并表示可能的最大二进制值。
这给出了:
foo.vhdl:15:9:@0ms:(report note): somename'length = 8
foo.vhdl:16:9:@0ms:(report note): somename 最大值 = 255
长度为8,无符号数组类型可表示的数值范围为0到2**8 - 1(255),最大可能值大于2**7(128)且无溢出。
这在一个较新的问题VHDL modulo 2^32 add中被注意到。在您接受的答案的上下文中,它假定您的意思是长度而不是最左边的值。
从零开始的递减确实会导致值 2**8 - 1 (255) (MAX = 7)。下溢或上溢取决于您的数学信仰。
乔纳森·德罗莱特(Jonathan Drolet)在链接的较新问题中指出了这一点。