Do you `include or import?

Let’s say I’m creating an OVM component collection - with drivers, monitors, agents, etc. I have separate .sv files for each component to keep them nicely isolated and to help people find which file contains which class.

I’ve noticed a lot of textbook examples tend to include lower-level files using the **include** compiler directive. For example, the top file might include a top-level top.svh which in turn `includes all the other files, .sv and .svh.

I come from a C background, where #including header files is typical, but #including implementation files (.c) is a huge no-no. So I’m a bit averse to this style.

The other style I’ve seen is where each file also declares a package. These packages are added to the work library as they are compiled. Any other file that needs to use the facilities of this package uses the importkeyword.

This is quite nice and behaves more like Python. But it adds the overhead of putting every file into its own package.

Which is the better way to do this? Which is more scalable over large projects? Has anyone taken either approach to its logical conclusion and found it to be beneficial or detrimental in any way? What are the trade-offs of each approach?

Also, I assume it’s wise to name the package as the same thing as the filename that defines it. Does this clash with a class of the same name? Can I have a file called xbus_driver.sv that declares “package xbux_driver” and also defines a class called “xbus_driver”?

Would love to know what experienced OVM people think about this. Thanks.

I would prefer importing rather than include. It is a good idea to have all the files related to one agent in single package rather than creating separate package for each file.

I would prefer importing rather than include. It is a good idea to have all the files related to one agent in single package rather than creating separate package for each file.

How do you put multiple files into a single package? Is it possible to declare the same package in multiple files, thereby adding more than one file to the package? Or do you use `include to bring in multiple files into one high level pkg file?

David,

The `include directive and the import statement are two distinct features of SystemVerilog and are not exclusive to one another.

As in most other languages, the include directive is just a mechanism for assembling text. The directive provides two key pieces of functionality:

  • maintain repetitive blocks of text in a single file
  • specify file compilation order dependences from within a file instead of on the compiler command line

Both are employed when including header files in C/C++, but only the latter is employed when including files that make up a package in SystemVerilog).

The import statement in SystemVerilog is analogous to `including header files in C/C++ or the using namespace statement in C++. The package definition is analogous to the actual implementation in C/C++.

There will be a paper presented at the upcoming DVCon10 that covers this in more detail.

Dave Rich

There will be a paper presented at the upcoming DVCon10 that covers this in more detail.

Thanks Dave, that makes sense to me. Will the paper be available to non-attendees?

However I’m still not exactly sure I understand how packages are declared. It seems to me that a single file can declare zero, one or more packages, but I haven’t seen any examples of a package spanning multiple files.

Is it as simple as `including all sub-files under a top-level file that declares the package, or can multiple files re-open a package declaration and add themselves to it? I.e. can multiple files declare the same package and the result is the aggregate?

How do you put multiple files into a single package? Is it possible to declare the same package in multiple files, thereby adding more than one file to the package? Or do you use `include to bring in multiple files into one high level pkg file?

Hi David,

I mean including multiple files into one high level Package file. When an agent is coded it requires Sequence item, driver, monitor and sequencer need to be coded. Include all the files related to agent in one package. Compile this package and import the package wherever Agent instantiation requires. This will avoid including all the agent related files wherever Agent instantiation requires. Include is something like copy paste of the code. So if you include all the agent files every time agent files will be compiled, which won’t be the case if you use import by including all the files in package.

Hi David,
I mean including multiple files into one high level Package file. When an agent is coded it requires Sequence item, driver, monitor and sequencer need to be coded. Include all the files related to agent in one package. Compile this package and import the package wherever Agent instantiation requires. This will avoid including all the agent related files wherever Agent instantiation requires. Include is something like copy paste of the code. So if you include all the agent files every time agent files will be compiled, which won’t be the case if you use import by including all the files in package.

Hi Vishnu,

Thank you for your clarification. I think I understand now - you use `include to bring together multiple files into a single package that a higher level file can simply import.

I suppose this also allows a single file to appear in more than one package - do you use ifndef/define ‘guardians’ to prevent multiple-definition errors or does SV not require this?

I use ifndef/define ‘guardians’ to prevent multiple-definition errors.

David,

I think you need to understand a few things about the compilation process.

The first is that the compiler goes through a pre-processor step. This step processes all the include files, conditionals, and text macros into a single stream of text. Except for error reporting and debugging, the compiler does not care how many files were used to make up that stream of text.

Within that stream of text are design units- those are modules, interfaces, program blocks and packages. These can be compiled in any order, except that SV requires that packages be compiled before being imported.

In tools like Questa, whenever you compile a design unit, it gets stored in a work library, replacing the previous version if one already exists. If you recompile a package, you will need to recompile and other design unit that imported it.

SystemVerilog also supports separate compilation units. A compilation unit is one stream of text. The default in Questa is eachfile on the compiler command line is one stream of text. You can also define it to be allfiles on the command line as one stream of text, creating a single compilation unit. If you have multiple compiler command lines, then you will have at least one compilation unit per command line.

If you have multiple compilation units and have a set of classes that need to be shared across the compilation units, then you must use a package to define those classes. The same is true for any user defined type.

Dave

The paper I mentioned has been posted in the latest issue of Verification Horizons. It covers more about the use of packages than the problems with `include.

@dave_59: thank you for the follow-up, that article does look useful.

Just posted an article on class definitions and packages imports versus `include. http://go.mentor.com/package-import-versus-include