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

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'.

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.

Related

Conditional use of libraries when simulating VHDL design with ModelSim in Pre-Synthesis / Post-Synthesis

In my VHDL design there is a 16-bits std_logic_vector. The bit in position 15 is currently not used and the synthesizer (SynplifyPro) throws a warning saying that bit is not used and will be pruned:
#W:CL190 : DATAGEN.vhd(93) | Optimizing register bit MYREG(15) to a constant 0. To keep the instance, apply constraint syn_preserve=1 on the instance.
#W:CL260 : DATAGEN.vhd(93) | Pruning register bit 15 of MYREG(15 downto 0). If this is not the intended behavior, drive the input with valid values, or an input from the top level.
As suggested by the synthesizer, I have added the required attribute and I was able to get rid of these warnings. To add these attributes, I had to include the Synplify library:
library synplify;
at the top of the file, and then define the attribute as follows:
ATTRIBUTE SYN_PRESERVE : BOOLEAN;
ATTRIBUTE SYN_PRESERVE OF MYREG : SIGNAL IS TRUE;
If I try to run ModelSim on Post-Synthesis everything is fine. However, when I try to run ModelSim on Pre-synthesis, it gives me the error:
** Error: .../DATAGEN.vhd(20): (vcom-1598) Library "synplify" not found.
I believe that the problem is because Pre-Synthesis simulation is not supposed to use this library. In fact, if I remove this everything works. The reason for which I would like to keep using the Pre-Synthesis simulation is because it is much faster than Post-Synthesis. However, this issue forces me to keep commenting out this lib for Pre-synthesis and putting it back for Post-synthesis?
Is it possible to use something like conditional include?
Note: I prefer to keep the unused bits, therefore adding the attribute for avoid pruning works fine for me.
Is it possible to use something like conditional include?
The upcoming VHDL-2019 standard supports conditional compilation and some simulators, for example RivieraPro, have started to support that. With such support you can do things like
`if INCLUDE_SYNPLIFY = "true" then
library synplify;
`end if
I don't think ModelSim has that yet but what you can do is to just define a synplify library with vlib and include that when calling vsim. If you are using VUnit you can simply add the following to your run script
prj.add_library("synplify")

Randomize dut parameters in system verilog

I am writing a test bench in system verilog for a dut, and in the field it is possible for the parameter DEPTH to change and so I have been trying to figure out how to randomize a parameter. It is currently set at 20 but it has a range of 7 to 255. Any suggestions and help would be greatly appreciated.
I know you cant directly in the script randomize it but ive heard of others do it by creating a package that they run along side the test that can insert random values as parameters.
It isn't possible to randomize parameter values, as these need to be fixed at elaboration time and randomization is a run-time task.
What I think you mean is that you can create a small SystemVerilog program that can model your parameters inside a class, randomize that and then write a package based on that.
class my_params;
rand bit [7:0] depth;
constraint legal_depth {
depth inside { [7:255] };
}
function void write_param_pkg();
// open a file
// start writing to it based on the randomized values
end
endclass
You can then instantiate this class in some dummy top module and use it to dump a package:
module param_randomizer;
initial begin
my_params params = new();
if (!params.randomize())
$fatal(...)
params.write_params_pkg();
end
endmodule
The output of writing the package could be:
package my_params_pkg;
parameter DEPTH = 42;
endpackage
This you need to call before you start compiling your real testbench. The testbench will import this package and set the DUT's parameter to this one:
module testbench;
my_design dut #(my_params::DEPTH) (...);
endmodule
If you only have one parameter (as opposed to multiple which are related to each other), it might not make sense to do the randomization in SystemVerilog, as scripting should be enough.
Here is some solution I found, not sure if it's what you're looking for:
https://verificationacademy.com/forums/ovm/randomizing-module-parameters
In a nutshell:
You can create a class with fields inside representing values of parameters that are to be randomized. Then you instantiate it in a new module, which randomizes that class and outputs a new package file with random values for parameters. Finally, you compile that package with the rest of your modules.
As has been stated by the other answers, parameter values have to be resolved at elaboration time. Typically they are passed in to the simulator command line:
vsim -gDEPTH=42
I don't think there's any advantage to using the SystemVerilog constraint solver to randomise your parameters. The hassle of writing out a package from SystemVerilog to feed into a subsequent compilation suggests something is wrong. Ideally all of the SystemVerilog code should be picking up the chosen parameter from the elaborated DUT so a package isn't required*. It's probably easier to update your build scripts, for example:
vsim -gDEPTH=$(shuf -i 7-255 -n 1)
Obviously this can be made more generic as part of an overall test harness. If you need constrained randomisation for parameters (unlikely but possible) then you could always use a more powerful scripting language.
This has the added advantage that if you have other configuration values (for example for non SystemVerilog software that is executed as part of the test) these can all be set from a single place and passed into the simulation.
* although it seems people often do use a package to share parameters because it can be awkward to access DUT params. Again for generating code and writing to files, you may find that using a standard scripting language will be more powerful easier to maintain.

need to use std_logic_Arith with std_logic_signed/unsigned

I read in many VHDL file headers : use ieee.std_logic_arith.all along with ieee.std_logic_signed.all , i can't see any benefit of this as the latter package(Signed)makes use of the former(Arith) automatically in its implementation. Any clarification why they are used together?
I have the same remark re. ieee.std_logic_unsigned.all
Thank you
First of all, when you use a package, you are not automatically importing all of the packages that package uses, so you need to use both explicitly if you want the features of both.
std_logic_signed/unsigned overloads mathematical and relational operators to treat std_logic_vector as a signed/unsigned number, respectively. std_logic_arith overloads the same operators, but only specifically for the signed and unsigned types it defines. If you want to use specific numeric types, you use std_logic_arith. If you want to treat all generic std_logic_vectors as signed or unsigned numbers, you use one of the others.
Or actually, don't use either, and use the standard ieee.numeric_std instead, which accomplishes the same thing as the std_logic_arith (you will need to typecast instead of directly operating on std_logic_vector, but this is generally better anyway).

ghdl elaborate an entity in a package

I have a VHDL program and I can't elaborate it with GHDL, because the entity to elaborate is in a package. How do I elaborate an entity in a package with GHDL?
EDIT:
Thanks for the answers, after some time I figured out that the code in a package was something like an interface and we are supposed to implement this component ourselves and I falsely assumed that it was complete. Sorry for the wrong question, I am new to VHDL and am learning the ropes and couldn't find any explanation on google since my assumptions were wrong.
I don't believe it is legal to put an entity inside a package. You can put types, subtypes, constants, signals, files, aliases, component, attributes and groups into a package.
So you can put a component definition, which can map to an entity, inside of a package. This is convenient so that you could put a component in a single shared package instead of putting it in the architecture of every design unit that needs to use the functionality of the entity.
I'm quite confident that the VHDL standard does not allow to declare entities in packages. Only components, subprograms, signals, constants, types and subtypes can be declared there.

Why do I need to redeclare VHDL components before instantiating them in other architectures?

I've been scratching my head since my first VHDL class and decided to post my question here.
Given that I have a declared entity (and also an architecture of it) and want to instantiate it inside another architecture, why is it that I seemingly have to redeclare the "entity" (component) inside this containing architecture before instantiating it?
Isn't the compiler smart enough to match an instantiation to its architecture just by its name? Where is the need for the component declaration?
You can directly instantiate the component, if desired:
MyInstantiatedEntity : entity work.MyEntity_E
generic map (
config => whatever)
port map (
clk => signal1,
clk_vid => signal2,
...
Creating a component declaration gives you the extra ability to change what gets bound to the instantiation via a configuration specification or similar.
Back when I did my VHDL assignments back when I was in school, I was required to have all our code all in one file so I don't remember whether or not you could write one file for each module and how it was done.
That being said, you would have to declare the entity you would use when defining the behavior, if you were using it much in the same way that you would define prototypes, structures, classes and whatnot in C or C++. The difference here is that you don't have the luxury of defining header files for this "redeclaration" in VHDL (at least I don't think there is an equivalent). So it seems perfectly reasonable to me to have to do this. Note that VHDL came out when C was very common and the compilers weren't "smart enough" as they are today.
A VHDL guru might have a definitive answer for this but this is how I understand it.

Resources