Class Variables and Assignments in SystemVerilog
Good OOP style says you should start your project with a common base class (or several). When you want to change its default behavior, extend it to make a new class by overriding methods and adding new properties. Everything in the base class is inherited so anything the base class can do, the extended class can also do. What is the relationship between the class variables that point to an object, and how can you assign between them?
This is the fourth post in a series on OOP and UVM. Here is the previous post on $cast() with enumerated types. You might also want to read this post on Class Variables and Objects. Some people use “handle” for “class variable”. Whatever floats your boat!
Start with a base class for an automobile. It has the property for the color, and a method drive().
class Automobile; string color; task drive(); ... endtask endclass
This looks handy but sometimes you need to carry something big like a desk – you need a pickup truck! An important measure of a pickup is the size of its bed.
class Pickup extends Automobile; int bed_size; endclass
Notice that a Pickup is an Automobile. Everything you can do with an Automobile, like set the color, and call drive(), you can also do with a Pickup.
Declare some class variables.
Automobile a; // Declare an Automobile class variable Pickup p; // And a Pickup variable
Can the variable a point to a Pickup object?
p = new(); // Construct a Pickup object a = p; // Legal? Yes!
Yes! What can you do with an Automobile object? You can call drive() and look at the color property. Those members exist in the Pickup object.
a.drive(); // Yes – legal a.color = "red"; // Yes – legal
Can the variable p point to an Automobile object?
a = new(); // Construct an Automobile object p = a; // ERROR: will not compile
The assignment won’t even compile as an extended class handle can never point to a base object. If that was allowed, you could then have the following code that tries to access the bed_size property in an Automobile object. The code will compile, but there is no such property.
p.bed_size = 64; // ERROR: No bed_size in Automobile object
Relationship between class variable
Here is a diagram of the two classes, and the variables that point to their objects.
You can see that an Automobile variable can point to both Automobile and Pickup object, but a Pickup variable can only point to a Pickup object. The range of values for the base class variable is larger than the extended variable’s range. That didn’t make sense to me until I made the above Venn diagram.
Here are the rules for assigning between base and derived class variables.
This post introduces the concept of the legal values for a class variable, for both a base and extended object. Stay tuned next time when I lose my car in the parking lot, and one more rule.
Try this code with your favorite simulator. Lean forward, make mistakes, get messy!
Where can I get a code ? “Try this code with your favorite simulator. Lean forward, make mistakes, get messy!”
I got error
xmvlog: *E,NOTCLM (testbench.sv,23|22): bed_size is not a class item.
I surely do upcast with a = p; it means that p is possible to use the Automobile class handle to call inherited Automobile class data members and methods. but why does it make error?
int num = 1;
class Pickup extends Automobile;
int bed_size =4;
Automobile a; // Declare an Automobile class variable
Pickup p; // And a Pickup variable
p = new();
a = p;