Today we continue with the Logic Design series on SystemVerilog in order to talk about Packages.
So, without further ado, let's get straight into it!
Design Hierarchy
In Verilog all data and methods (functions, tasks) are defined in modules. Only system tasks and functions are global and can be accessed from anywhere. Thus, modules contain instances of other modules. But, this module hierarchy can easily becomes complicated, which leads to much time being spent in port list maintenance.
SystemVerilog enhances the hierarchical design introducing the module ports, that we've already discussed. These allow any data type to be passed. Additionally;
modules can be nested (module declared within another module)
port connections are named far simpler
interfaces allow for bundled connections between modules
time and precision specs are bound to modules
and then there are also packages, which we will discuss today.
Packages
Packages are introduced for sharing common code across multiple modules, programs, interfaces etc. This basically allows code to be re-usable by definition.
Package Definition
Packages are defined within the package and endpackage keywords:
packagename;...endpackage
They can contain parameters, data, types, tasks, functions, sequences, properties, but not assign statements. Variables need to be declared before any initial and always blocks.
Hierarchical definitions are also forbidden, except if they are created within the package or are the cause of importing another package.
Importing Packages
Packages are imported using the import keyword followed by the package name and the scope resolution operator ::, which specifies what to import. Importing everything is as simple as adding a * after that operator.
For example:
importpackage1::myFunc;importpackage2::*;
imports only the function myFunc from package1, and everything from package2.
Definition Collision
If the same definition (identifier) exists in both the top level and the imported package, we are talking about a collision of definitions. From these two the top level definition will be preferred by the simulator. For example, this could mean that the initial value of the top level would be used instead of the package's value for some variable.
In order to "apply" the package's value the package name has to be explicitly mentioned by using the :: operator, as shown below.
value=var;// use top level definitionvalue=packageName::var;// use package definition