It depends, but it is almost always preferable to specify the range.
For illustration, consider this example:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity naturals is
Port ( clk : in std_logic;
rst : in std_logic;
count : out std_logic_vector(2 downto 0));
end naturals;
architecture behavioral of naturals is
signal count_intern : natural := 0;
begin
count <= std_logic_vector(to_unsigned(count_intern, count'length));
process(clk)
begin
if (rising_edge(clk)) then
if (rst = '1') then
count_intern <= 0;
elsif (count_intern = 5) then
count_intern <= 0;
else
count_intern <= count_intern + 1;
end if;
end if;
end process;
end behavioral;
This is a simple counter going from 0 to 5.
It's simulation looks like this:

However, I didn't limit the signal count_intern
- so, internally it is 31-bits (integers are 32-bits, naturals are 31). Even though I am only actually using the lower 3 bits, all 31 end up in the addition and comparison operations. Why? Because on startup, the initial value of count_intern
is undefined. It might, for instance, begin with a value of 7 - at which point, the counter will increment until all 31 bits fill up and overflow back to 0. The initialization (to 0) that I supplied in the code, only applies to simulation - it is ignored by the synthesizer.
The post-synthesis schematic, therefore, looks like this:

I realize the image is too large to make out its details - but that's the point. It's a mess; and for a very simple circuit.
Now, let's replace the single line:
signal count_intern : natural := 0;
with
signal count_intern : natural range 0 to 5 := 0;
Without proof, the simulation is exactly the same. However, the post-synthesis schematic now resolves to:

In fact, the results of this can be confirmed even post-implementation - where it truly counts:
Without limiting the natural range:

With range limit:

Notice the difference in flip-flops used.
While I used Naturals here, this (of course) extends to Integers as well.
Implementation results may vary. Here I am using the default settings in Vivado 2015. Either way, the point is - it is safer and preferable to always specify the range.
natural range 0 to 3
to make it clear you'll never allow negative values). \$\endgroup\$ – Brian Drummond Nov 5 '17 at 16:57integer
is -2*31+1 to 2**31-1. It depends on your optimizer to recognize if bits 4 to 31 are unused in your case. I recommend typeunsigned(3 downto 0)
to store values. \$\endgroup\$ – Paebbels Nov 5 '17 at 16:58