{"id":16211,"date":"2021-06-14T09:34:05","date_gmt":"2021-06-14T13:34:05","guid":{"rendered":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/?p=16211"},"modified":"2026-03-27T08:49:59","modified_gmt":"2026-03-27T12:49:59","slug":"systemverilog-class-variables-and-objects","status":"publish","type":"post","link":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/2021\/06\/14\/systemverilog-class-variables-and-objects\/","title":{"rendered":"SystemVerilog Class Variables and Objects"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p>How can you visualize the relationship between classes and objects in SystemVerilog? This is the first post in a series on Object-Oriented Programming in SystemVerilog and UVM. To best absorb this, you should know how to write a class in SystemVerilog. Let\u2019s get started!<\/p>\n\n\n\n<p>When you first learn OOP, it can be easy to mix up class variables and objects. I started when I was, so this was especially hard. Get ready to flex your brain muscles! How are objects like a neighborhood?<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"359\" src=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2021\/06\/1.1-neighborhood-1024x359.png\" alt=\"A neighborhood of 4 houses, each a different color and address\" class=\"wp-image-16212\" srcset=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2021\/06\/1.1-neighborhood-1024x359.png 1024w, https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2021\/06\/1.1-neighborhood-600x210.png 600w, https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2021\/06\/1.1-neighborhood-768x269.png 768w, https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2021\/06\/1.1-neighborhood-900x316.png 900w, https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2021\/06\/1.1-neighborhood.png 1306w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>For a quick review of the terms in this article, see Dave&#8217;s excellent <a href=\"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/2013\/07\/16\/class-on-classes\" target=\"_blank\" rel=\"noreferrer noopener\">description<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Variables and values<\/h2>\n\n\n\n<p>In Verilog, a variable v has a value, 5, so I would say that v has the value 5, a direct relationship.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"349\" height=\"284\" src=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2021\/06\/1.2-variable.png\" alt=\"The variable v equals 5\" class=\"wp-image-16213\"\/><\/figure>\n\n\n\n<p><br>OOP has a two-step relationship between class variables, properties, and values. As you read this article, I encourage you to fire up your favorite editor, wrap these code examples with module-endmodule and simulate with your favorite tool, stepping through the code with the GUI. Don\u2019t just lean back and read \u2013 lean forward and absorb what you see! A true engineer practices their craft and improves their skills.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Welcome to my neighborhood<\/h2>\n\n\n\n<p>The blueprint for a house says what the house will look like, with N doors and M windows. However, &nbsp;you can&#8217;t live in a blueprint &#8211; you need to construct the house, which occupies physical space. Here is a house with 1 door, 1 window, painted blue.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"483\" height=\"418\" src=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2021\/06\/1.3-house.png\" alt=\"A single house\" class=\"wp-image-16214\"\/><\/figure>\n\n\n\n<p>Build enough houses and you have a neighborhood of houses, each identical, but separate. You can have many identical houses so how do you tell them apart? In this image, each has a different color and address.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"359\" src=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2021\/06\/1.1-neighborhood-1024x359.png\" alt=\"A neighborhood of houses\" class=\"wp-image-16212\" srcset=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2021\/06\/1.1-neighborhood-1024x359.png 1024w, https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2021\/06\/1.1-neighborhood-600x210.png 600w, https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2021\/06\/1.1-neighborhood-768x269.png 768w, https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2021\/06\/1.1-neighborhood-900x316.png 900w, https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2021\/06\/1.1-neighborhood.png 1306w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>When you want to describe group of related features and functionality in SystemVerilog, such as a transaction, describe it with a class. The transaction has properties (variables) such as data and address, and methods (subroutines) that operate on the properties. A class encapsulates these properties and methods, describing what is in the transaction and how it operates. Think of the class as the blueprint for a transaction.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Construct an object<\/h2>\n\n\n\n<p>In the neighborhood above, you need to build a house as you can&#8217;t live in a blueprint. Likewise, a transaction class describes what it looks like, but you need to build a transaction object to provide space in memory for the address and data values. When you construct an object, the simulator allocates a chunk of memory to hold all the properties for a single class, such as a transaction.<\/p>\n\n\n\n<p>Here is a SystemVerilog class for a TX transaction with data and an ID.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">class Tx;\n  bit [31:0] data;\n  bit [23:0] id;\n endclass<\/pre>\n\n\n\n<p>A SystemVerilog object is stored in memory at a given address. In other languages you would refer to the object with pointer that holds its address. SystemVerilog uses a handle, which has both the address and the type, such as the Tx type. A class variable holds the handle. Here is an object (house) at address 1, and the class variable (mailbox) that points to it. (This is not the SystemVerilog mailbox type &#8211; just a rough dwelling analogy.)<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"601\" height=\"315\" src=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2021\/06\/1.4-mailbox-house.png\" alt=\"A mailbox outside a house\" class=\"wp-image-16215\"\/><\/figure>\n\n\n\n<p>Now declare the class variable t1 of type Tx.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Tx t1;<\/pre>\n\n\n\n<p>Initially, t1 equals null, which means it does not point to any object. Construct a Tx object by calling the special function new().<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">t1 = new();<\/pre>\n\n\n\n<p>SystemVerilog allocates space for the Tx object and returns a handle to the object. The class variable t1 now holds that handle.<br>Because a handle includes the type of the object, you can only assign it to the appropriate class variable. You can\u2019t assign a Tx handle to a Xbus class variable. This check for compatibility is why a SystemVerilog handles are called \u201ctype-safe\u201d.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">class Xbus;\n  bit [31:0] data, addr;\n  int id;\nendclass\nXbus x1;\ninitial x1 = t1; \/\/ Illegal code: mismatched types; won't compile.<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">One step beyond<\/h2>\n\n\n\n<p>Don\u2019t confuse the class variable and the object. Construct a Tx object using the handle t1 and give it the ID 42.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Tx t1, t2;\nt1 = new();\nt1.data = 2;\nt1.id = 42;<\/pre>\n\n\n\n<p>At this point you might be tempted to call the object \u201ct1\u201d. After all, you just set the value of data and id with the name \u201ct1\u201d. This relationship looks like:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"472\" height=\"149\" src=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2021\/06\/1_5_t1_obj.png\" alt=\"A class variable t1 pointing to an object \/ house\" class=\"wp-image-16256\"\/><\/figure>\n\n\n\n<pre class=\"wp-block-preformatted\">t2 = t1;\nt2.data = 8;\n$display(t1.data); \/\/ Displays: 8<\/pre>\n\n\n\n<p>Two class variables now point to a single object. You changed the variable in the one object with the t2 class variable and printed with t1. The connection between the class variables and the object is through the handles.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"470\" height=\"249\" src=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2021\/06\/1_6-t1_t2_obj.png\" alt=\"Two class variables, t1 and t2, pointing to an object\" class=\"wp-image-16254\"\/><\/figure>\n\n\n\n<p>Don\u2019t call the object t1 or t2 \u2013 those are the class variable names. If you set t1 to null, t2 still has a handle to the object.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">t1 = null;\nt2.data = 7;<\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"473\" height=\"249\" src=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2021\/06\/1_7_t1_null.png\" alt=\"t1 is null, t2 still points to the object\" class=\"wp-image-16255\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">What&#8217;s in a name?<\/h2>\n\n\n\n<p>How should you refer to an object? SystemVerilog doesn\u2019t let you see the address where an object is stored in memory. I like to make a property such as an integer ID or string name. I might have a whole \u201cneighborhood\u201d of objects and need to tell them apart. I could call the above object, \u201c42\u201d.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p>A SystemVerilog variable is tightly connected to its value. In contrast, a class variable refers to an object, which has variables, a looser connection. More details in the next post!<\/p>\n\n\n\n<p>Some SystemVerilog users, like myself, are lazy and use the term \u201chandle\u201d (type-safe pointer) to refer to a class variable (stores a handle).<\/p>\n\n\n\n<p>Here is the next&nbsp;<a href=\"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/2021\/06\/21\/verification-class-categories\/\" target=\"_blank\" rel=\"noreferrer noopener\">post<\/a> in this series.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction How can you visualize the relationship between classes and objects in SystemVerilog? This is the first post in a&#8230;<\/p>\n","protected":false},"author":72251,"featured_media":16256,"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,383,950,952,953,515,594,612,614,648,751,787,813],"industry":[],"product":[205],"coauthors":[942],"class_list":["post-16211","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-handles","tag-class-variable","tag-derived-class","tag-extended-class","tag-handle","tag-method","tag-object-oriented-programming","tag-oop","tag-property","tag-systemverilog","tag-uvm","tag-variable","product-questa"],"featured_image_url":"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2021\/06\/1_5_t1_obj.png","_links":{"self":[{"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/posts\/16211","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\/72251"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/comments?post=16211"}],"version-history":[{"count":5,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/posts\/16211\/revisions"}],"predecessor-version":[{"id":17687,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/posts\/16211\/revisions\/17687"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/media\/16256"}],"wp:attachment":[{"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/media?parent=16211"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/categories?post=16211"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/tags?post=16211"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/industry?post=16211"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/product?post=16211"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/coauthors?post=16211"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}