Search code examples
vhdlfpga

Are there any disadvantages to using '.all' in a 'use' clause?


Like the title says, why would you not just always use 'mylib.mypkg.all'? In some code I see things like:

use mylib.mypkg.func1;
use mylib.mypkg.func2;

When I would think I could just do:

use mylib.mypkg.all

Is there an advantage or purpose in only selecting certain functions or components besides just being explicit?

I'm new to VHDL and 'use' seems very similar to '#include' from C for me, so correct me if that is a poor way of thinking.

I've searched other questions and elsewhere online and I can't seem to find any reason why I shouldn't just always use '.all'.


Solution

  • Using .all on a use clause will make everything in that package visible. Which may be fine.

    But as an engineer picking a design up, imagine my horror when I see this:

    use lib.pkg1.all;
    use lib.pkg2.all;
    use lib.pkg3.all;
    use lib.pkg4.all;
    use lib.pkg5.all;
    use lib.pkg6.all;
    use lib.pkg7.all;
    ...and so on
    

    And then see this:

    if some_sig = some_constant_from_a_package then
    

    Its quite confusing keeping track of whats from which package, and then which package I need to modify, and I end up constantly using search to find where some constant is actually defined.

    Luckily, VHDL allows direct referencing to make everyone's life easier. So you can do this:

    if some_sig = lib.pkg4.some_constant then
    

    It makes keeping track of where everything is much easier. But sometimes its just easier to do a .all include. Certain operators are defined implicitly for all types. Which can lead to interesting and confusing errors

    use lib.pkg.some_type;
    
    signal a,b : some_type;
    
    ...
    
    if a = b then
    

    Here, you'll get an error because the "=" function that got declared implicitly with the type doesnt get included, and hence the compiler cannot see the function. You will need to either use a .all use, import the "=" function:

    use lib.pkg."=";
    

    or a direct reference:

    if a lib.pkg."=" b then
    

    There is a final problem - invisibility. If two packages declare items with the same name and you include both packages, the compiler doesn't know which one you mean and will make them both invisible. The most common way to do this is with the following includes:

    use ieee.numeric_std.all;
    use ieee.std_logic_arith.all;
    

    Here, the vhdl standard package numeric_std and non-standard std_logic_arith both define signed and unsigned types. And hence the following will throw a syntax error:

    signal a : unsigned(7 downto 0);
    

    To get around this, you will need to directly reference which type you meant:

    signal a : ieee.numeric_std.unsigned(7 downto 0);
    signal b : ieee.std_logic_arith.unsigned(7 downto 0);
    

    Remember, these types are not the same and hence not directly compatible.