{"id":17477,"date":"2022-09-06T14:58:00","date_gmt":"2022-09-06T18:58:00","guid":{"rendered":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/?p=17477"},"modified":"2026-03-27T08:49:50","modified_gmt":"2026-03-27T12:49:50","slug":"systemverilog-implicit-handles","status":"publish","type":"post","link":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/2022\/09\/06\/systemverilog-implicit-handles\/","title":{"rendered":"SystemVerilog: Implicit handles"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p>In the <a><u>last blog post<\/u> <\/a><a href=\"#_msocom_1\">[SC(SECL1]<\/a>&nbsp;Farmer Ted asked you to keep track of his animals and you wrote some SystemVerilog classes, using public, protected, and local members. This week you are enhancing the code using the implicit handles, this and super.<\/p>\n\n\n\n<p>Quick definition: <em>implicit<\/em> means the language \/ tool creates the member for you. If you had to create it yourself, like the weight property, it would be <em>explicit<\/em>. Also, what I am calling a \u201chandle\u201d is technically called a \u201cclass variable\u201d that holds an \u201cobject handle\u201d. Everyone I know says \u201chandle\u201d to refer to the variable.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What is this?<\/h2>\n\n\n\n<p>How can your routine access a class-level variable when there is a local variable with the same name? This often happens when a set() method or the constructor initializes a class property with an argument. A common style is to give the argument the same name as the class property, such as weight shown here. If the assignment was just \u201cweight = weight\u201d, both names would refer to the closest definition, which is the routine argument. The solution is to use the implicit handle, this, to assign the class property. The code below won&#8217;t work without the \u201cthis\u201d handle.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Animal;<br>  int weight; \/\/ Class-level property<br><br>&nbsp; virtual function void set_weight_kg(input int weight);<br>&nbsp; &nbsp;&nbsp;<strong>this<\/strong>.weight = weight;&nbsp; \/\/ class property = routine argument<br>&nbsp; endfunction<br>endclass<\/code><\/pre>\n\n\n\n<p>This diagram color codes the scope. Members of the Animal class are in blue including the <em>this<\/em> handle in the upper right, while names associated with the set_weight_kg() method are in purple.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2022\/07\/this_handle.png\" alt=\"Implicit handle: this\" class=\"wp-image-17481\" width=\"488\" height=\"241\" srcset=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2022\/07\/this_handle.png 611w, https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2022\/07\/this_handle-600x297.png 600w\" sizes=\"auto, (max-width: 488px) 100vw, 488px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Department of redundant redundancies<\/h3>\n\n\n\n<p>Sometimes you might use the handle even when not needed, just to be clear. The function below copies properties from the object that rhs handle (right hand side) points to, into the current object. The code still works without the \u201cthis\u201d, but the handle emphasizes what you are trying to do. There is no penalty for being extra careful.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Animal;<br>&nbsp; int <strong>weight<\/strong>; \/\/ Class-level property<br><br>&nbsp; virtual function void copy(Animal rhs);<br>&nbsp;&nbsp;&nbsp; this.weight = rhs.weight; \/\/ Copy class member from rhs<br>&nbsp; endfunction<br>endclass<\/code><\/pre>\n\n\n\n<p>How can you tell if the handle is redundant? You can remove it and see if the code still seems to work, a risky approach. Instead, prove to yourself \u2013 is there a weight member in the local scope, the function? No? Then then the handle is redundant.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">It\u2019s a bird, it\u2019s a plane<\/h2>\n\n\n\n<p>In a derived class, you might want to reference a member of the base class. A common example is a virtual method that overrides a base class method and wants to call that base method. Here is the Animal class with a virtual print() method.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Animal;<br>&nbsp; protected int weight;<br><br>&nbsp; virtual function void print();<br>&nbsp;&nbsp;&nbsp; $display(\"Animal: %0d kg\", weight);<br>&nbsp; endfunction<br>endclass<\/code><\/pre>\n\n\n\n<p>The class Sheep extends Animal and has a property, shorn, to let you know if the sheep had a haircut. The class needs a print() method to display this class property. It also needs to display the base class Animal properties, but you don\u2019t want to hardcode that into the Sheep class. Instead, call the Animal\u2019s print method. Wait, if the Sheep print calls print(), it will call itself! You need a handle to members of Animal. The implicit handle super comes to your rescue!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Sheep;<br>&nbsp; bit shorn;<br><br>&nbsp; virtual function void print();<br>&nbsp;&nbsp;&nbsp; $write(\"Sheep: shorn=%b\", shorn);<br>&nbsp;&nbsp;&nbsp; <strong>super<\/strong>.print();<br>&nbsp; endfunction<br>endclass<\/code><\/pre>\n\n\n\n<p>The method calls $write() instead of $display()so that the final output is one long line.<\/p>\n\n\n\n<p>Here is a diagram showing the Sheep class in green and the <em>super<\/em> handle in the upper right.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2022\/07\/super.png\" alt=\"Super handle to base members\" class=\"wp-image-17482\" width=\"406\" height=\"291\" srcset=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2022\/07\/super.png 634w, https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2022\/07\/super-600x430.png 600w\" sizes=\"auto, (max-width: 406px) 100vw, 406px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Skipping class<\/h2>\n\n\n\n<p>When I show the super handle to students, someone often asks what if you call super.<em>method<\/em>() and there is no corresponding method in the parent class. When Merino::set_weight_kg() calls super.set_weight_kg(), there is no such method in Sheep, so the compiler keeps looking and finds the method in the base Animal class.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Merino extends Sheep;<br>&nbsp; virtual function void set_weight_kg(int weight);<br>&nbsp;&nbsp;&nbsp; super.set_weight_kg(weight); \/\/ Ends up in Animal method<br>&nbsp; endfunction<br>endclass<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Super-duper handles<\/h2>\n\n\n\n<p>The other common question is if a method can call super.super.method(). Maybe my students read too many comics? The answer is that the implicit handles super and this are local members, so they can only be used inside the class. If Merino tried calling super.super.method(), the first super handle is legal, but the second refers to a local property in the Sheep class, which is illegal. Bad news for the fanboys, good news for OOP purists.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Experiment<\/h2>\n\n\n\n<p>Try merging the code from this post along with the earlier code. You can then either step through the simulation, line-by-line, or sprinkle the following to trace the execution.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$display(\"%m\");<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Learn More<\/h2>\n\n\n\n<p>You can learn more about these topics including Oriented Programming with Siemens SystemVerilog for Verification course. It is offered in <a href=\"https:\/\/training.plm.automation.siemens.com\/ilt\/iltdescription.cfm?pID=268489-US_____EDA__2021.4_1199\" target=\"_blank\" rel=\"noopener\">instructor led<\/a> format by our industry expert instructors, or in a self-paced <a href=\"https:\/\/training.plm.automation.siemens.com\/mytraining\/viewlibrary.cfm?memTypeID=287545&amp;memID=287545\" target=\"_blank\" rel=\"noopener\">on-demand<\/a> format. It can also be tailored to address your specific design goals and show you how to set up an environment for reuse for additional designs.&nbsp; Also, you can now earn a digital badge\/level 1 certificate by taking our <a href=\"https:\/\/training.plm.automation.siemens.com\/mytraining\/viewlibrary.cfm?memTypeID=288054&amp;memID=288054\" target=\"_blank\" rel=\"noopener\">Advanced Topics Badging Exam<\/a>. This will enable you to showcase your knowledge of this topic by displaying the badge in your social media and email signature.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><a id=\"_msocom_1\"><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction In the last blog post [SC(SECL1]&nbsp;Farmer Ted asked you to keep track of his animals and you wrote some&#8230;<\/p>\n","protected":false},"author":71586,"featured_media":17481,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spanish_translation":"","french_translation":"","german_translation":"","italian_translation":"","polish_translation":"","japanese_translation":"","chinese_translation":"","footnotes":""},"categories":[1,982,10],"tags":[951,382,950,952,953,506,1470,1471,585,612,614,648,751],"industry":[],"product":[],"coauthors":[980],"class_list":["post-17477","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-news","category-systemverilog","category-tips-tricks","tag-base-class","tag-class","tag-class-variable","tag-derived-class","tag-extended-class","tag-functional-verification","tag-handles","tag-implicit-handle","tag-member","tag-object-oriented-programming","tag-oop","tag-property","tag-systemverilog"],"featured_image_url":"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2022\/07\/this_handle.png","_links":{"self":[{"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/posts\/17477","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/users\/71586"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/comments?post=17477"}],"version-history":[{"count":4,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/posts\/17477\/revisions"}],"predecessor-version":[{"id":17573,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/posts\/17477\/revisions\/17573"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/media\/17481"}],"wp:attachment":[{"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/media?parent=17477"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/categories?post=17477"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/tags?post=17477"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/industry?post=17477"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/product?post=17477"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/coauthors?post=17477"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}