Consider the following VHDL code:
constant c : std_logic_vector(7 downto 0) := (7 downto 6 => '1', others => '0');
Here, the indices 7 and 6 are important: they indicate which elements should be 1, and from that, the compiler can derive which ones should be 0.
Question 1
If I understand correctly, this can also be written as
constant c : std_logic_vector(7 downto 0) := (7 downto 6 => '1') & (5 downto 0 => '0');
Now I am wondering how exactly this works, and whether the indices still matter or only the difference between them. The way I understand it, the expression (x downto y => z)
creates an array with indices x downto y
, whose elements are all equal to z
(and have the same type). But do these indices matter when arrays are concatenated? I.e., could I also write any of the following:
constant c : std_logic_vector(7 downto 0) := (1 downto 0 => '1') & (5 downto 0 => '0');
constant c : std_logic_vector(7 downto 0) := (99 downto 98 => '1') & (4 downto -1 => '0');
Of course one could say that those statements, esp. the last one, aren't really clear, but my question is: Would they have the same result? Or would they cause some kind or error?
The reason I am wondering about this is that you could also write
constant c : std_logic_vector(7 downto 0) := "11" & "000000";
and the literal "11"
doesn't have any range specified, so I'm not sure what exactly the type of this literal would be, but certainly not std_logic_vector(7 downto 6)
.
Question 2
Finally, I am wondering what is the difference between
constant c : std_logic_vector(7 downto 0) := (7 downto 6 => '1') & (5 downto 0 => '0');
and
constant c : std_logic_vector(7 downto 0) := (7 downto 6 => '1', 5 downto 0 => '0');
By this I mean: Is there any reason you would want/need to write the former (which seems more error-prone because it will give unexpected results if you e.g. swap the 2 aggregates) instead of the latter? Or is it just a matter of taste?
Here, if you check the range of SOME_CONSTANT, you'll see its (0 to 7). This is because std_logic_vector is declared as:
The 'low value of natural is 0, which is the start point.
Lets say you went a bit crazy, and this:
and you declared a constant:
The results are:
Because
'U'
is the low value ofstd_logic
, followed by 'X'.On the other questions, it all works because VHDL is always context driven, and for arrays as long as the lengths match, the resulting arrays can always be mapped from 'left to 'right. In your examples the length is correct, and the subtype is know from the declaration, so mapping can occur as you specified.
NOTE:
(4 downto -1 => '0');
is illegal, because -1 is not a valid index value for a std_logic_vector, so you would get an error (probably from the&
function because it cannot work out what type you meant, because it cannot be std_logic_vector).constant c : std_logic_vector(7 downto 0) := x"C0";
what you use and when may depend on what is clearest to the user(s).