Thursday, 4 February 2016

$unit vs $root in SystemVerilog



In one line you can say that, $unit represents the top level of each compilation unit, but $root refers to the top level instance.

Now let’s discuss it in little-bit more detail.

$root:

  • $root is the root of the instantiation tree.
  • SystemVerilog introduced the concept of $root as a global scope that allowed any kind of declaration (data types, classes, variables) along with module definitions nested in that global scope.
  • Any un-instantiated module is implicitly instantiated in $root.
  • A top-level module is implicitly instantiated once in $root, and its instance name is the same as the module name.


$unit:

  • A compilation unit formalizes a scope that represents what is visible in a compilation step – called $unit in SystemVerilog.
  • SystemVerilog borrowed the concept of packages from VHDL and standardized the concept of a compilation unit. A package allows you to compile definitions in a separate step and import those definitions into another compilation step.

Basic example of $unit,
-----------------------------------------------------------------------------------------------------------------
string name = "Sagar";
module mod();
string name = "SSS";
task print();
$display( { "You've got 1 ", $unit::name, "!" } );
$display( { "I've got 1 ", name, "!" } );
$display( { "I've got 2 ", $root.mod.name, "!" } );
endtask : print
initial begin
print();
end
endmodule
//Output:
// You've got 1 Sagar!
// I've got 1 SSS!
// I've got 2 SSS!
view raw unit_scope.sv hosted with ❤ by GitHub

-----------------------------------------------------------------------------------------------------------------

If you have a design that is compiled as a single compilation unit, there is really no conceptual difference between $unit and $root.

However, once you have a design with multiple compilation units, then $unit represents the top level of each compilation unit, and there is nothing in $root except for the implicitly instantiated module instances.


The only time you need to use $root or $unit is when a local name in the current scope hides a name in a higher level scope. For example,

-----------------------------------------------------------------------------------------------------------------
// --------- Compilation unit 1 ----------
// Contain only pkg1
package pkg1;
function void print;
$display("comp1");
endfunction : print
endpackage : pkg1
// --------- Compilation unit 2 ----------
// Contain only pkg2
package pkg2;
function void print;
$display("comp2");
endfunction : print
endpackage : pkg2
// --------- Compilation unit 3 ----------
// Contain task->print, module mod3, mod2, mod1
// mod3 is instantiated in mod2.
// mod2 is instantiated in mod1.
// mod1 is not instantiated any where.
// So, mod1 is implicitly instantiated in $root.
function void print;
$display("unit");
endfunction : print
module mod3();
function void print;
$display("mod3");
endfunction : print
endmodule : mod3
module mod2();
mod3 mod1(); // same name as top-level module
function void print;
$display("mod2");
endfunction : print
initial begin
#5;
$display($time," From initial block of module mod2");
$root.mod1.print(); // prints "mod1"
mod1.print(); // prints "mod3"
pkg1::print(); // prints "comp1"
pkg2::print(); // prints "comp2"
$unit::print(); // prints "unit"
end
endmodule : mod2
module mod1(); // top-level module
mod2 m2();
function void print;
$display("mod1");
endfunction : print
initial begin
#1;
$display($time," From initial block of module mod1");
print(); // prints "mod1"
$root.mod1.print(); // prints "mod1"
pkg1::print(); // prints "comp1"
pkg2::print(); // prints "comp2"
m2.print(); // prints "mod2"
m2.mod1.print(); // prints "mod3"
$unit::print(); // prints "unit"
end
endmodule : mod1
//Output:
// 1 From initial block of module mod1
// mod1
// mod1
// comp1
// comp2
// mod2
// mod3
// unit
// 5 From initial block of module mod2
// mod1
// mod3
// comp1
// comp2
// unit
view raw unit_vs_root.sv hosted with ❤ by GitHub

-----------------------------------------------------------------------------------------------------------------

Here module “mod2” and module “mod1” has same task called “print”. The ambiguity is resolved by giving priority to the local scope and thereby preventing access to the top-level path. $root allows explicit access to the top level in those cases in which the name of the top-level module is insufficient to uniquely identify the path.

Note that there is no way for compilation unit 1 to directly refer to anything in compilation unit 2, or the other way around.

Reference:
1. https://blogs.mentor.com/verificationhorizons/blog/2009/09/25/unit-vs-root/

7 comments:

  1. This is really informative, Keep more posting. We have training institute of vlsi. Someone have interest. visit us.Physical Design Training Institutes in Bangalore|Top VLSI Training Institutes in Bangalore

    ReplyDelete
  2. I liked the posts, for your information why content is not monetised are u waiting for adsense approval.I have found another alternative ads http://tinyurl.com/zl83sk9 works fine for my blog http://basicsofvlsi.blogspot.in/

    ReplyDelete
    Replies
    1. Thanks :).
      Yes, I am waiting for approval from adsense.
      I will check alternative you have mentioned.

      Delete
  3. I liked the posts, for your information why content is not monetised are u waiting for adsense approval.I have found another alternative ads http://tinyurl.com/zl83sk9 works fine for my blog http://basicsofvlsi.blogspot.in/

    ReplyDelete