Use selected names.
The cause:
IEEE Std 1076-2008
12.4 Use clauses
In order to determine which declarations are made directly visible at a given place by use clauses, consider the set of declarations identified by all use clauses whose scopes enclose this place. Any declaration in this set is a potentially visible declaration. A potentially visible declaration is actually made directly visible except in the following three cases:
a) A potentially visible declaration is not made directly visible if the place considered is within the immediate scope of a homograph of the declaration.
b) If two potentially visible declarations are homographs and one is explicitly declared and the other is implicitly declared, then the implicit declaration is not made directly visible.
c) Potentially visible declarations that have the same designator and that are not covered by case b) are not made directly visible unless each of them is either an enumeration literal specification or the declaration of a subprogram.
12.3 Visibility
...Each of two declarations is said to be a homograph of the other if and only if both declarations have the same designator, and they denote different named entities, and either overloading is allowed for at most one of the two, or overloading is allowed for both declarations and they have the same parameter and result type profile (see 4.5.1).
12.5 The context of overload resolution
12.5 The context of overload resolution
Overloading is defined for names, subprograms, and enumeration literals.
Your constant declarations are not homographs, not enumeration literals nor declarations of subprograms. None of the multiple declarations of constants with the same name would be directly visible.
4.7 Package declarations
Items declared immediately within a simple or a generic-mapped package declaration become visible by selection within a given design unit wherever the name of that package is visible in the given unit. Such items may also be made directly visible by an appropriate use clause (see 12.4). Items declared immediately within an uninstantiated package declaration cannot be made visible outside of the package.
The cure:
back to 12.3:
Visibility is either by selection or direct. A declaration is visible by selection at places that are defined as follows:
...
f) For a declaration given in a package declaration, other than in a package declaration that defines an uninstantiated package: at the place of the suffix in a selected name whose prefix denotes the package.
...
8.3 Selected names
A selected name is used to denote a named entity whose declaration appears either within the declaration of another named entity or within a design library.
selected_name ::= prefix . suffix
suffix ::=
simple_name
| character_literal
| operator_symbol
| all
A selected name can denote an element of a record, an object designated by an access value, or a named entity whose declaration is contained within another named entity, particularly within a library, a package, or a protected type. Furthermore, a selected name can denote all named entities whose declarations are contained within a library or a package.
If we peruse 8. Names, 8.1 General we find that a prefix can be a name, including a selected name.
A code example:
library ieee;
use ieee.std_logic_1164.all;
package pkg1 is
constant MAIN_GIT_HASH: std_logic_vector := x"ffffffff";
end pkg1;
library ieee;
use ieee.std_logic_1164.all;
package pkg2 is
constant MAIN_GIT_HASH: std_logic_vector := x"00000000";
end pkg2;
library ieee;
use ieee.std_logic_1164.all;
use work.pkg1.all;
use work.pkg2.all;
entity foo is
end entity;
architecture fum of foo is
function to_string (inp: std_logic_vector) return string is -- before -2008
variable image_str: string (1 to inp'length);
alias input_str: std_logic_vector (1 to inp'length) is inp;
begin
for i in input_str'range loop
image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i)));
end loop;
return image_str;
end function;
begin
process
begin
report LF & HT & " MAIN_GIT_HASH = " & to_string(work.MAIN_GIT_HASH);
report LF & HT & "pkg1 MAIN_GIT_HASH = "
& to_string(work.pkg1.MAIN_GIT_HASH);
report LF & HT & "pkg2 MAIN_GIT_HASH = "
& to_string(work.pkg2.MAIN_GIT_HASH);
wait;
end process;
end architecture;
where
ghdl:error: compilation error
%: ghdl -a multiple_packages.vhdl
multiple_packages.vhdl:37:63:error: unit "main_git_hash" not found in library "work"
report LF & HT & " MAIN_GIT_HASH = " & to_string(work.MAIN_GIT_HASH);
^
ghdl:error: compilation error
%:
ghdl isn't very descriptive (doesn't track visibility in it's name look up to tell us why it isn't visible) while Modelsim may be more expressive, something along the lines of:
Error (10621): VHDL Use Clause error at multiple_packages.vhdl(37): more than one Use Clause imports a declaration of simple name "MAIN_GIT_HASH"
This error shows up a lot where users provide use clauses for both IEEE package numeric_std and Synopsys package std_logic_arith.
Commenting out line 37 we can demonstrate the use of selected names where direct visibility is not available:
ghdl:error: compilation error
%: ghdl -a multiple_packages.vhdl
%: ghdl -e foo
%: ghdl -r foo
multiple_packages.vhdl:38:9:@0ms:(report note):
pkg1 MAIN_GIT_HASH = 11111111111111111111111111111111
multiple_packages.vhdl:40:9:@0ms:(report note):
pkg2 MAIN_GIT_HASH = 00000000000000000000000000000000
%:
Note with a use work.all;
making the package names visible the selected name prefixes could be simple_names instead of themselves being selected names.