How to Access a Protected Property or Method in SystemVerilog
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! 🙂
