Is overflow defined for VHDL numeric_std signed/unsigned

♀尐吖头ヾ 提交于 2019-12-12 10:53:33

问题


If I have an unsigned(MAX downto 0) containing the value 2**MAX - 1, do the VHDL (87|93|200X) standards define what happens when I increment it by one? (Or, similarly, when I decrement it by one from zero?)


回答1:


Short answer:

There is no overflow handling, the overflow carry is simply lost. Thus the result is simply the integer result of your operation modulo 2^MAX.

Longer answer:

The numeric_std package is a standard package but it is not is the Core the VHDL standards (87,93,200X). For reference : numeric_std.vhd

The + operator in the end calls the ADD_UNSIGNED (L, R : unsigned; C : std_logic) function (with C = '0'). Note that any integer/natural operand is first converted into an unsigned.

The function's definition is:

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;

As you can see an "overflow" occurs if CBIT='1' (carry bit) for i = L_left. The result bit RESULT(i) is calculated normally and the last carry bot value is ignored.




回答2:


I've had the problem with wanting an unsigned to overflow/underflow as in C or in Verilog and here is what I came up with (result and delta are 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

For overflow '0' & result makes an unsigned which is 1 bit larger to be able to correctly accommodate the value of the addition. The MSB is then removed by the resize command which yields the correct overflow value. Same for underflow.




回答3:


For a value of MAX equal to 7 adding 1 to 2**7 - 1 (127) will result in the value 2**7 (128).

The maximum unsigned value is determined by the length of an unsigned array type:

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;

The aggregate (others => '1') represents a '1' in each element of somename which is an unsigned array type and represents the maximum binary value possible.

This gives:

foo.vhdl:15:9:@0ms:(report note): somename'length = 8
foo.vhdl:16:9:@0ms:(report note): somename maximum value = 255

The length is 8 and the numerical value range representable by the unsigned array type is from 0 to 2**8 - 1 (255), the maximum possible value is greater than 2**7 (128) and there is no overflow.

This was noticed in a newer question VHDL modulo 2^32 addition. In the context of your accepted answer it assumes you meant length instead of the leftmost value.

The decrement from zero case does result in a value of 2**8 - 1 (255) (MAX = 7). An underflow or an overflow depending on your math religion.

Hat tip to Jonathan Drolet for pointing this out in the linked newer question.



来源:https://stackoverflow.com/questions/11769754/is-overflow-defined-for-vhdl-numeric-std-signed-unsigned

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!