Welcome ! This website will help YOU (recent graduates/professionals) learn verification languages like SystemVerilog and UVM. Register for free and access more content !

Why do we need parameterization for classes ?

At times it would be much easier to write a generic class which can be instantiated in multiple ways to achieve different array sizes or data types. This avoids the need to re-write code for specific features like size or type and instead allow a single specification to be used for different objects. This is achieved by extending the SystemVerilog parameter mechanism to classes.

Parameters are like constants that are local to the specified class. Classes are allowed to have default value for each parameter that can be overridden during class instantiation.


  // Declare parameterized class
  class <name_of_class> #(<parameters>);
  class Trans #(addr = 32);
  // Override class parameter
  <name_of_class>  #(<parameters>) <name_of_inst>;
  Trans #(.addr(16)) obj;


Parameterized Classes

Given below is a parameterized class which has size as the parameter that can be changed during instantiation.

// A class is parameterized by #(<parameters>) 
// Here, we define a parameter called "size" and gives it 
// a default value of 8. The "size" parameter is used to
// define the size of the "out" variable
class something #(int size = 8);
  bit [size-1:0] out;
module tb;
  // Override default value of 8 with the given values in #()
  something  #(16) sth1;                 // pass 16 as "size" to this class object
  something  #(.size (8)) sth2;          // pass 8 as "size" to this class object
  typedef something #(4) td_nibble;      // create an alias for a class with "size" = 4 as "nibble"
  td_nibble nibble;
  initial begin
    // 1. Instantiate class objects
    sth1 = new;
    sth2 = new;
    nibble = new;  
    // 2. Print size of "out" variable. $bits() system task will return
    // the number of bits in a given variable
    $display ("sth1.out   = %0d bits", $bits(sth1.out));
    $display ("sth2.out   = %0d bits", $bits(sth2.out));
    $display ("nibble.out = %0d bits", $bits(nibble.out));
Simulation Log
ncsim> run
sth1.out   = 16 bits
sth2.out   = 8 bits
nibble.out = 4 bits
ncsim: *W,RNQUIE: Simulation is complete.

Click to try this example in a simulator!   

Pass datatype as a parameter

Data-type is parameterized in this case and can be overridden during instantiation. In the previous case, we defined parameters to have a specific value.

// "T" is a parameter that is set to have a default value of "int"
// Hence "items" will be "int" by default 
class stack #(type T = int);
  T item;             
  function T add_a (T a);   
    return item + a;
module tb;
  stack          st;   // st.item is by default of int type
  stack #(bit[3:0])   bs;   // bs.item will become a 4-bit vector
  stack #(real)     rs;   // rs.item will become a real number
    initial begin
      st = new;
      bs = new;
      rs = new;
      // Assign different values, and add 10 to these values
      // Then print the result - Note the different values printed
      // that are affected by change in data type
      st.item = -456;
      $display ("st.item = %0d", st.add_a (10));
      bs.item = 8'hA1;
      $display ("bs.item = %0d", bs.add_a (10));
      rs.item = 3.14;
      $display ("rs.item = %0.2f", rs.add_a (10));

Note that any type can be supplied as a parameter, including user-defined type such as class or struct.

Simulation Log
ncsim> run
st.item = -446
bs.item = 11
rs.item = 13.14
ncsim: *W,RNQUIE: Simulation is complete.

Click to try this example in a simulator!   

Was this article helpful ?

We use cookies to personalize content and ads, to provide social media features and to analyze our traffic. You consent to our cookies if you continue to use our website. To find out more about the cookies we use and how to delete them, see our privacy policy.

  I accept cookies from this site.
EU Cookie Directive plugin by www.channeldigital.co.uk