Classes are a fundamental concept that allows you to create complex data structures and encapsulate behavior within your code. Classes provide a way to define new types that can have properties (variables) and methods (functions or tasks). This object-oriented programming paradigm makes it easier to model and manage complex systems by promoting modularity, reusability, and organization.
Features of SystemVerilog OOPs:
Encapsulation
Inheritance
Polymorphism
Data Abstraction
class Dashrat; string name = "Dashrat"; int weight = 80; int age = 30; function print_details(); $display( "Dashrat Call : Name -> %s", name ); $display( "Dashrat Call : Weight -> %d", weight ); $display( "Dashrat Call : Age -> %d", age ); endfunction function hello_print(); $display( "Hello Dashrat" ); endfunction endclass class Ram extends Dashrat; string name = "Ram"; function print_parent(); $display( "Ram Call : Name -> %s", name ); // Ram's Variable $display( "Ram Call : Weight -> %d", weight ); // Dashrat's Variable $display( "Ram Call : Age -> %d", age ); // Dashrat's Variable endfunction function hello_print(); $display( "Hello Ram" ); endfunction /* Inherited Code -------------- Variable -> weight age Methods -> print_details Overridded Code ( Can access parent using "super."" keyword ) ------------------------------------------------------------- Variable -> name Methods -> hello_print */ endclass class Lava extends Ram; int age = 10; function print_parent(); $display( "Lava Call : Name -> %s", name ); // Ram's variable $display( "Lava Call : Weight -> %d", weight ); // Dashrat's variable $display( "Lava Call : Age -> %d", age ); // Lava's variable endfunction function hello_print(); $display( "Hello Lava" ); endfunction /* Inherited Code -------------- Variable -> weight ( from "Dashrat" class ) name ( from "Ram" class ) Methods -> print_details ( from "Dashrat" class ) Overridded Code --------------- Variable -> age Methods -> hello_print */ endclass
class Parent; string name; protected int weight; local int age; function print_details(); $display( "Parent Call : Name -> %s", name ); $display( "Parent Call : Weight -> %d", weight ); $display( "Parent Call : Age -> %d", age ); endfunction endclass class Child extends Parent; function print_parent(); $display( "Child Call : Name -> %s", name ); $display( "Child Call : Weight -> %d", weight ); $display( "Child Call : Age -> %d", age ); // Inaccessible endfunction endclass class GrandChild extends Child; function print_grand_parent(); $display( "GrandChild Call : Name -> %s", name ); $display( "GrandChild Call : Weight -> %d", weight ); // Inaccessible $display( "GrandChild Call : Age -> %d", age ); // Inaccessible endfunction endclass
/* Shallow copy refers to a direct way of copying a class without taking its dynamic elements into account. All the elements of a class which have do not deal with pointers and whic are basically access by value are copied as it is. The execption of shallow copy is that it treats pointers as variable values and hence does not really create a copy of the pointer memory, but rather points to the same memory. An example is given below: */ class Occupation; string occ = "Unemployed"; function new(string oc = "Unemployed"); this.occ = oc; endfunction endclass class Original; int age = 10; string name = "Sonu"; Occupation o; function new(string occ = "Unemployed"); o = new(occ); endfunction function void print(); $display( "Name : %s", name ); $display( "Age : %d", age ); $display( "Occu : %s", o.occ ); endfunction endclass module top; Original a, b; initial begin a = new("Pilot"); a.print(); b = new; b.print(); b = new a; b.print(); b.name = "Rinzler"; b.print(); a.o.occ = "Fireman"; a.print(); b.print(); end endmodule
class P; int age; endclass class C extends P; int age; endclass module top; P p; C c; initial begin p = new; c = new; p.age = 100; c.age = 50; $display( "Age : %0d", p ); $display( "Age : %0d", c ); p = c; $display( "Age : %0d", p ); end endmodule
/* 100 50 0 0 is printed because after casting "p" now has the pointer to the base class memory of "c", which if you see was never initialized and hence age will have the datatype's default value */
class A; string name = "Arjun"; virtual function void print_name(); $display( "Name : %s", name ); endfunction endclass class B extends A; string name = "Buddy"; function void print_name(); $display( "Name : %s", name ); endfunction endclass module top; A a; B b; initial begin a = new; b = new; a.print_name; b.print_name; b.name = "Big Brother"; a.name = "Arya"; a = b; a.print_name; a.name = "Bro"; b.print_name; $cast( a, b ); b.print_name; end endmodule
/* Arya Buddy Arjun Big Brother Big Brother */
module top; class A; int age = 10; endclass endmodule
class A; module top; logic M; endmodule endclass
class A; class B; int age = 20; endclass endclass
class A; local int age = 10; function show_age(); $display( "Age : %0d", age ); endfunction endclass class B; int age = 30; /* Add modificaitons here */ endclass
// The code can be re-written like this class A; local int age = 10; function show_age(); $display( "Age : %0d", age ); endfunction endclass class B; int age = 30; A a; /* Accessing parent class */ function new(); a = super; endfunction endclass module top; B b; initial begin b = new; $display( "B Age : %0d", b.age ); b.a.show_age(); // Accessing parent class indirectly b.a.age = 100; b.a.show_age(); // Accessing parent class indirectly end endmodule
class A; static int CLASS_INST; function new(); $display("Class Created : %0d", CLASS_INST); CLASS_INST++; endfunction endclass module top; A a1,a2; initial begin a1 = new; a2 = new; end endmodule
class A; static A CLASS_INST[$]; static int INST_NUM; int LOCAL_INST_NUM; static int S_TRACKER; // Only used to track the original creation and deletion int TRACKER; // Same as above function new(); $display("Class Created : %0d", INST_NUM); CLASS_INST.push_back(this); LOCAL_INST_NUM = INST_NUM; INST_NUM++; TRACKER = S_TRACKER++; endfunction function destroy(); CLASS_INST.delete(LOCAL_INST_NUM); $display("Instance %0d Destroyed", LOCAL_INST_NUM); foreach(CLASS_INST[i]) begin if( i >= LOCAL_INST_NUM ) begin CLASS_INST[i].LOCAL_INST_NUM--; end end INST_NUM--; LOCAL_INST_NUM = -1; // Basically means its destroyed endfunction function printInst(); $display("Instance Number : %0d ( Tracker Details : %0d )", LOCAL_INST_NUM, TRACKER); endfunction endclass module top; A p0,p1,p2,p3,p4; initial begin p1 = new; p1.printInst; p2 = new; p2.printInst; p3 = new; p3.printInst; p4 = new; p4.printInst; p2.destroy; p1.printInst; p2.printInst; p3.printInst; p4.printInst; end endmodule
class EVEN; rand int num; virtual function int genEvenNum(); // Generate an EVEN number >0 & <1000 return ( ( ( $urandom % 1001 ) >> 1 ) << 1 ); endfunction endclass module top; EVEN e; initial begin e = new; repeat(5) begin $display( "Generated Number : %0d", e.genEvenNum ); end end endmodule
class EVEN; rand int num; virtual function int genEvenNum(); // Generate an EVEN number >0 & <1000 return ( ( ( $urandom % 1001 ) >> 1 ) << 1 ); endfunction endclass module top; EVEN e; initial begin e = new; repeat(5) begin $display( "Generated Number : %0d", (e.genEvenNum>>2)<<2 ); // Modificaiton made here end end endmodule