SystemVerilog: Class Member Visibility
Farmer Ted wants to keep track of the animals on his property and asks you to write the code. Since you have access to Questa SIM, you decide to write the code in SystemVerilog. Start by creating a class for an Animal with a property (variable) to hold its weight. Here is a first start with your class and the first animal.
module farm; class Animal; int weight; // In kg endclass Animal dolly; // handle to an Animal object initial begin dolly = new(); dolly.weight = 100; $display("dolly weighs %0d", dolly.weight); end endmodule
A problem with this code is the units: is weight in pounds, kilograms, ounces, or grams? Yes, there is a comment, but who reads the documentation? By allowing the user to read and write the variable, you are exposing the implementation. If you ever decide to change the units from kilograms to grams, the above code will make a 100-gram animal. That’s a mighty small sheep!
With most OOP languages, you are encouraged to limit direct access to class members, especially properties (variables), to prevent this sort of bug. The recommendation is to create set() and get() methods. In SystemVerilog, the default access is public, which means that other code can read and write properties and call all methods (routines). There is no keyword for this behavior.
When you want to limit access to members, there are three “trust” levels. The base class can always access to members that it defines. An extended class is like family: you trust this child code, but you may want to limit access to the most sensitive information about the parent (base) class. Finally is code in unrelated classes, where you don’t want anyone to change the weight and possibly make an illegal value.
The first level of limiting access is to declare a member as protected. In the code below, since you are restricting who can see the weight property, you need to make public methods to read and write it. The derived class, Sheep, can access weight, but the farm module cannot.
The most restrictive level is local. The Animal class has a unique id value for every object and does not let anyone, not even the derived Sheep class, access this.
module farm; class Animal; protected int weight; // In kg virtual function int get_weight_kg(); return weight; endfunction virtual function void set_weight_kg(input int w); weight = w; endfunction local static int count=0; local int id; function new(); id = count++; endfunction endclass : Animal class Sheep extends Animal; function new(input int w_kg); weight = w_kg; // Legal: derived class can access protected endfunction endclass Sheep dolly; initial begin dolly = new(100); $display("dolly weighs %0d", dolly.weight); end endmodule : farm
Experiment with visibility
Try the above code on your favorite simulator. In the farm module, can you set weight with the set*() method? Can you set the weight directly with the c handle? In the Sheep class, can you read or write the id? Create
get_weight_gram() methods in Animal.
Much of your code will be for testbenches: the components and stimulus. If you protect too many members, it will be hard to inject errors or randomize properties. However, if you are creating utilities or base classes (such as UVM), you might want to limit access to some of the internals to protect yourself against devious users.
There are several problems with the above examples. What if your 100kg sheep goes on a diet and loses 400kg? The weight is an
int, which can be negative, which is not realistic. Physical values, such as weight or packet size, should be treated as unsigned values. Have checks in any set*() methods for these illegal values. Also, since weight represents a continuous value, it should be a real number. Finally, the best way to organize classes is to define them in a package and import it.
You can learn more about these topics including Oriented Programming with Siemens SystemVerilog for Verification course. It is offered in instructor led format by our industry expert instructors, or in a self-paced on-demand format. It can also be tailored to address your specific design goals and show you how to set up an environment for reuse for additional designs. Also, you can now earn a digital badge/level 1 certificate by taking our Advanced Topics Badging Exam. This will enable you to showcase your knowledge of this topic by displaying the badge in your social media and email signature.