1

I use a TCL script to generate a VHDL pkg for each submodule repository that stores the compilation date time and git hash of the submodule. The constant storing 32 bit git hash is called MAIN_GIT_HASH and is an std_logic_vector.

I now have multiple packages that all contain a constant called MAIN_GIT_HASH and I need to include them into the same source file using the VHDL "use" directive. Now the question is, what is the correct way to select the correct constant from each package since just writing "MAIN_GIT_HASH" will be ambigious?

gyuunyuu
  • 526
  • 5
  • 17

2 Answers2

6

Each of the packages either needs to have a unique name or needs to be analyzed into a separate library.

If you use separate libraries, you simply reference it using a package path:

library Submodule1 ; 
use Submodule1.HashPkg.MAIN_GIT_HASH ;  -- just get the relevant constant

Should a design need to reference more than one HashPkg (like your use case), then you can reference the constant with the same notation as above:

HashReg <= Submodule1.HashPkg.MAIN_GIT_HASH ;

If you use unique named packages, then they could all be put into the same library. Assuming that that library is the same as the one into which you are compiling the current design unit, then you can reference it as being in work:

use work.Submodule1HashPkg.MAIN_GIT_HASH ;
. . . 
HashReg <= work.Submodule1HashPkg.MAIN_GIT_HASH ;
Jim Lewis
  • 3,601
  • 10
  • 20
4

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.

user16145658
  • 695
  • 1
  • 5
  • 10