{"id":14093,"date":"2020-04-16T11:06:12","date_gmt":"2020-04-16T15:06:12","guid":{"rendered":"https:\/\/blogs.mentor.com\/verificationhorizons\/?p=14093"},"modified":"2026-03-27T08:51:14","modified_gmt":"2026-03-27T12:51:14","slug":"systemverilog-parameterized-classes","status":"publish","type":"post","link":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/2020\/04\/16\/systemverilog-parameterized-classes\/","title":{"rendered":"SystemVerilog Parameterized Classes"},"content":{"rendered":"<p>SystemVerilog allows you to create modules and classes that are parameterized. This makes them more flexible, and able to work on a range of data types instead of just a single one. This concept is widely used in UVM, especially the uvm_config_db configuration database. Try these examples yourself.<\/p>\n<h3>Parameterized by value<\/h3>\n<p>Let\u2019s start with a simple class with a bit vector. The class has a parameter for the width of the vector. (Good programming practice is to always have a default for your parameters.)<\/p>\n<pre>class Vector #(parameter WIDTH=1);\n  bit [WIDTH-1:0] data;\nendclass<\/pre>\n<p>You can now declare handles for classes with vectors of various widths.<\/p>\n<pre>Vector v1;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Default: data width=1\nVector #(8) v8;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ 8-bit data\nVector #(.WIDTH(16)) v16;\u00a0 \/\/ 16-bit data\ninitial begin\n  v1 = new();\n  $display(\"v1 \", $typename(v1.data));\u00a0\/\/ v1 bit[0:0]\n  v8 = new();\n  $display(\"v8 \", $typename(v8.data)); \/\/ v8 bit[7:0]\nend<\/pre>\n<p><a href=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2020\/04\/param_value-3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-14111\" src=\"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/54\/2020\/04\/param_value-3-520x288.png\" alt=\"\" width=\"401\" height=\"222\" \/><\/a><\/p>\n<p>Every time you specify a value, you are essentially creating a new class. So you can imagine that the v8 line above creates the following class declaration.<\/p>\n<pre>class Vector__8;\n  bit [8-1:0] data;\nendclass<\/pre>\n<p>The handles v1, v8, and v16 are not type compatible as each is for a separate class, Vector__1, Vector__8, and Vector__16. You can\u2019t assign between these handles, even with $cast().<\/p>\n<h3>Parameterized by type<\/h3>\n<p>Say your boss asked you to write a utility class for a stack in SystemVerilog. You might come up with something like this.<\/p>\n<pre>class Stack;\n  int items[64], idx=0;\n  function void push(input int val);\n    items[idx++] = val;\n  endfunction\n\n  function int pop();\n    return items[idx--];\n  endfunction\nendclass<\/pre>\n<p>Your class was so popular that other people on your project asked for a stack of bytes, a stack of real values and more. Rather than write dozens of new classes, just modify your old one. The code for push() and pop() remains the same, it just works on a different type.<\/p>\n<pre>class Stack #(parameter type T=int);\n  T items[64], idx=0;\n  function void push(input T val); \u2026\n  function T pop(); \u2026\nendclass\n\nStack\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 int_stack;\u00a0\u00a0 \/\/ Default: Stack of ints\nStack #(bit[7:0]) byte_stack;\u00a0 \/\/ Stack of 8-bit values\nStack #(real)\u00a0\u00a0\u00a0\u00a0 real_stack;\u00a0 \/\/ Stack of real values<\/pre>\n<p>Once again, these three declarations essentially create three new classes. As a result, these handles are not type compatible.<\/p>\n<p>Of course you could have just told your boss to use the SystemVerilog queue data type, but what\u2019s the fun of doing that?<\/p>\n<h3>More tips<\/h3>\n<p>The keyword \u201cparameter\u201d in the class header is optional.<\/p>\n<p>Make the parameter name upper case to show it is not a variable.<\/p>\n<p><em>Enjoy your verification journey!<\/em><br \/>\n<em>Chris Spear<\/em><\/p>\n<p>Keep learning at <a href=\"http:\/\/mentor.com\/training\" target=\"_blank\" rel=\"noopener\">mentor.com\/training<\/a><br \/>\nQuestions or ideas? <a href=\"https:\/\/verificationacademy.com\/ask-chris-spear\" target=\"_blank\" rel=\"noopener\">verificationacademy.com\/ask-chris-spear<\/a><br \/>\nView my recent webinar on <a href=\"https:\/\/verificationacademy.com\/sessions\/uvm-coding-guidelines-tips-and-tricks-you-probably-didnt-know\" target=\"_blank\" rel=\"noopener\">UVM Coding Guidelines<\/a> and the <a href=\"https:\/\/verificationacademy.com\/sessions\/uvm-coding-guidelines-tips-and-tricks-you-probably-didnt-know\/rte\/questions--answers\" target=\"_blank\" rel=\"noopener\">Questions and Answers<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>SystemVerilog allows you to create modules and classes that are parameterized. This makes them more flexible, and able to work&#8230;<\/p>\n","protected":false},"author":71586,"featured_media":0,"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":[7,1,982,10],"tags":[300,301,382,515,630,631,728,751,774,787,805,831],"industry":[],"product":[],"coauthors":[980],"class_list":["post-14093","post","type-post","status-publish","format-standard","hentry","category-learning-resources","category-news","category-systemverilog","category-tips-tricks","tag-cast","tag-typename","tag-class","tag-handle","tag-parameter","tag-parameterized-class","tag-specialized-class","tag-systemverilog","tag-type","tag-uvm","tag-uvm_config_db","tag-verilog"],"_links":{"self":[{"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/posts\/14093","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=14093"}],"version-history":[{"count":1,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/posts\/14093\/revisions"}],"predecessor-version":[{"id":18198,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/posts\/14093\/revisions\/18198"}],"wp:attachment":[{"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/media?parent=14093"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/categories?post=14093"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/tags?post=14093"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/industry?post=14093"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/product?post=14093"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/verificationhorizons\/wp-json\/wp\/v2\/coauthors?post=14093"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}