In the following type and constant declaration, the last value in the array will not actually be 2**35-1, since integers greater than 2**31-1 are not standard VHDL (2002)
library ieee;
use ieee.numeric_std.all;
-- Boilerplate elided...
constant X_SIZE : natural := 40; -- Really, anything greater than 32
type x_array is array(natural range <>) of signed;
constant XS : x_array := (
to_signed(0, X_SIZE),
to_signed(1, X_SIZE),
to_signed(2**35 - 1, X_SIZE) -- Not possible!
);
I can’t do to_signed(2, X_SIZE)**35 - 1 because exponentiation is not defined on signed. I’m loathe to type out the full array because it seems clunky and X_SIZE might change in the future. So how do I create the value I want here? Is there a better way than literally typing out 40 0s and 1s?
Depending on the value, there are a few ways to do it.
x"1FFFFFFFF"(X_SIZE-1 downto 35 => '0', others => '1')— be warned though, if you try to combine this with other operators or functions, the compiler will not be able to infer the required size of the vector. You’ll need to do something like:(X_SIZE-1 downto 35 => '1', 35 downto 0 => '0'). At this point you might not be saving much space, but depending on what you’re doing, it might make your intent much clearer than a literal.shift_left(to_unsigned(1, X_SIZE), 35) - 1.