Search code examples
vhdlvivado

VHDL overcome maximum integer limit


I have a generic value X which can exceed the positive maximum integer limit 2147483647. I was getting it in generic portion of the entity declaration:

X : integer := 3000000000;
Y : integer := 128; -- maximum 1024 (11 bits)
Z : integer := 1000 -- maximum 65535 (16 bits)

However, X is not directly used in the architecture but a constant named C is used. I define the constant in the architecture by:

constant C : unsigned(63 downto 0) := to_unsigned ( (X / Y) / 1000 * Z, 64);

However because X can exceed the integer limit, this solution is not feasible. Therefore, I have decided to use unsigned (I am using ieee.numeric_std library) in the entity decleration such as:

X : unsigned(63 downto 0) := x"00000000B2D05E00"; -- equivalent of 3000000000d
Y : integer := 128; -- maximum 1024 (11 bits)
Z : integer := 1000 -- maximum 65535 (16 bits)

Then, to calculate the constant:

constant C : unsigned(63 downto 0) := ((X / to_unsigned(Y, 11)) / to_unsigned(1000,10) * to_unsigned(Z, 21));

I choose the length of Z as 21 because Y and 1000d has total length of 21 (10+11).

However, Vivado gives me an error "mismatched array sizes in rhs and lhs of assignment."

How should I overcome this situation? What is the proper way of solving it? My way may be incorrect, I am open to any method.

Thanks.


Solution

  • Vivado is correct - the sizes do missmatch. The result of the "/" function returns the length of the left operand. So here, you have

    (X / to_unsigned(Y, 11)
    

    Which returns a 64 bit result

    / to_unsigned(1000,10)
    

    returns another 64 bit result. And finally:

    * to_unsigned(Z, 21));
    

    Is a 64 bit value * 21 bit, giving a 85bit number. You will need to resize the result to 64 bits with the resize function:

    resize(result, X'length);
    

    There is no checking for overflow with this function other than an assertion warning, you need to ensure you will never overflow the 64 bit number.