How to Access a Protected Property or Method in SystemVerilog

How to Access a Protected Property or Method in SystemVerilog

Posted by

You might get into a scenario in which you really need to access a protected property or maybe a protected method from some SystemVerilog class.

If override is not a solution for you then you might get away with this trick: create a subclass and via static functions access any properties from a reference which is of parent class type.

Let’s see this trick in an example.

Let’s consider that we have a class called monitor which has a protected property and a protected function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class monitor;
 
  //this counter is not accessible from outside the class
  protected int unsigned counter;
 
  function new();
    counter = 1982;
  endfunction

  //this function is not accessible from outside the class
   protected function void increment_counter();
      counter++;
   endfunction
 
endclas

Next, let’s create a subclass of monitor and implement some static functions through which to access the protected API of a reference of type monitor.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class hack_monitor extends monitor;
 
  static function void set_counter(monitor mon, int unsigned value);
    mon.counter = value;
  endfunction
 
  static function int unsigned get_counter(monitor mon);
    return mon.counter;
  endfunction
 
  static function void increment_counter(monitor mon);
    mon.increment_counter();
  endfunction
 
endclass

Notice that the functions in hack_monitor are working with a pointer to the monitor class, so there is no need for any UVM overrides and you can apply this to existing objects.

Let’s see this code in action:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
module top;
 
  initial begin
    automatic monitor my_monitor = new();
   
    //get the counter value
    $display("counter: %0d", hack_monitor::get_counter(my_monitor));
   
    //set new value
    hack_monitor::set_counter(my_monitor, 9);
   
    $display("counter: %0d", hack_monitor::get_counter(my_monitor));
   
    //access the protected function
    hack_monitor::increment_counter(my_monitor);
   
    $display("counter: %0d", hack_monitor::get_counter(my_monitor));
  end
 
endmodule

The output is this:

1
2
3
# counter: 1982
# counter: 9
# counter: 10

This behavior is described in LRM:

A protected class property or method has all of the characteristics of a local member, except that it can be inherited; it is visible to subclasses.

Within a class, a local method or class property of the same class can be referenced, even if it is in a different instance of the same class

You can also run this code on EDA Playground.

Hope this helps! 🙂

Cristian Slav

Leave a Reply

Your email address will not be published.