class test extends uvm_test;!
`uvm_component_utils(test)!
!
env env_h;!
!
function new(string name, uvm_component parent);!
super.new(name, parent);!
endfunction!
endclass!
env.sv
class env extends uvm_env;!
`uvm_component_utils(env)!
!
function new(string name, uvm_component parent);!
super.new(name, parent);!
endfunction!
!
endclass!
when compile, I only compile the first 3 files i.e. top.sv, test_pkg.sv, env_pkg.sv
The question is, I didn’t add import test_pkg::*; inside module top.
But the simulation correctly found test and didn’t report UVM_FATAL.
Why? I expected that the UVM factory won’t be able to create test because I didn’t import test_pkg.
On the other hand, if I don’t compile test_pkg.sv, the simulator will print UVM_FATAL because it didn’t find test.
Factory registration is all performed within the uvm_pkg. You don’t have to import the test_pkg into module top. Static variable initialization is one SystemVerilog feature enabling the factory.
However, packages must be brought into existence, just like modules. When a module is instantiated within another module, a dependency emerges, but who dictates the top-level module? If a package isn’t imported, what determines that it belonging in a design? Tools offer compilation conventions to help guide this decision. Traditionally, the contents of the main files on the compilation command line are deemed part of the design. This is in contrast to library files where only referenced components are incorporated.
So first, the registry of an uvm component in a package will still be specialized even I don’t import this package but just compile it?
Secondly, do you mean I shouldn’t put my package on the compilation command line since they are not part of the design? Then what should I do to use them?
Importing a package is not required for factory registration. However, importing a package into something that is already part of the design is a guarantee that the package becomes part of the design.
So you should put the package file on the compilation command if it is not otherwise `included. This assumes you are compiling all code in one command. Tools have a number of different compilation flows.
I recommend putting all units (modules, interfaces and packages) on the compilation command line as separate compilation units. This makes it much more efficient for dealing with incremental or separate compilation in tools that support that.
Leave `include for files that cannot be separated from the files that include them. That would be files of macro definitions, or classes that are part of a package
Instead of including files inside the package and compiling the package, I saw some people even putting all the files to the compilation command line.
I assume that changing one file inside a package will cause the whole package to be recompiled? (for example in questa?)
I think what they try to do is to change one file without recompiling the whole package again. It can maximize the use of separate compilation. Do you think this is a good habit?