Monday, 1 February 2016

NEW in SystemVerilog

class base;
function new ();
$display ("%m from base class new");
endfunction : new
endclass : base
class child extends base;
function new ();
// Implicitly super.new is called by compiler
$display ("%m from child class new");
endfunction : new
endclass : child
module top();
base b;
child c;
initial begin
c = new();
end
endmodule : top
//Output:
// $unit::\base::new from base class new
// $unit::\child::new from child class new
// Q. What is the return type of the constructor?
// A1. On the return “type” it is different from other functions.
// It is very “adaptive in nature”
// i.e. it returns what the LHS requires.
// i.e. it returns an object of the type of the handle that appears on the LHS.
// Hence there is NO return type declared for this special function.
// As per SystemVerilog LRM,
// If a class does not provide an explicit user-defined new method,
// an implicit new method shall be provided automatically.
// The new method of a derived class shall first call its base class constructor super.new().
// A super.new call shall be the first statement executed in the constructor.
// This is because the superclass shall be initialized before the current class and,
// if the user code does not provide an initialization,
// the compiler shall insert a call to super.new automatically.
view raw sv_new1.sv hosted with ❤ by GitHub


class base;
function new ();
$display ("%m from base class new");
endfunction : new
endclass : base
class child extends base;
function new ();
super.new(); //Explicitly super.new called
$display ("%m from child class new");
endfunction : new
endclass : child
module top();
base b;
child c;
initial begin
c = new();
end
endmodule : top
//Output:
// $unit::\base::new from base class new
// $unit::\child::new from child class new
view raw sv_new2.sv hosted with ❤ by GitHub


class base;
function new (int unsigned id);
$display ("%m from base class new");
endfunction : new
endclass : base
class child extends base;
function new ();
$display ("%m from child class new");
endfunction : new
endclass : child
module top();
base b;
child c;
initial begin
c = new();
end
endmodule : top
// There is an error: recall that the base’s new is always called,
// but now the “id” argument is NOT provided for the IMPLICIT call to new.
//Output:
//Error-[SV-SNCIM] Super new call is missing
//top2.sv, 7
//$unit
// Base class constructor specification is missing in derived class 'child'.
// Please add <base class>::new arguments to 'extends' specification or add
// call to 'super.new' in <derived class>::new.
// Below is the possible ways to fix this error.
// 1. Add default arguement in constructor of base (super) class.
// 2. Explicitly call super.new with required arguements.
view raw sv_new3.sv hosted with ❤ by GitHub


class base;
function new (int unsigned id = 1);
$display ("%m from base class new");
endfunction : new
endclass : base
class child extends base;
function new ();
$display ("%m from child class new");
endfunction : new
endclass : child
module top();
base b;
child c;
initial begin
c = new();
end
endmodule : top
//Output:
// $unit::\base::new from base class new
// $unit::\child::new from child class new
// Q: Can we declare constructor as virtual?
// A1. In the above code we just added an argument called “id” to the base class constructor.
// In the derived we decided to “forget” about it.
// If it was a “virtual” function, as per the semantics, this would be illegal
// i.e. the function prototype/signature must remain same across inheritance.
// However the re-definition of new in derived class is just fine.
// A2. Constructor of a class is never and ever extended by a derived.
// A3. As mentioned in A1, function signature of derived class's constructor can be
// a different then signature of base class's constructor.
// However signature must remain same across inheritance.
view raw sv_new4.sv hosted with ❤ by GitHub


class base;
function new (int unsigned id);
$display ("%m from base class new");
endfunction : new
endclass : base
class child extends base;
function new ();
super.new(1);
$display ("%m from child class new");
endfunction : new
endclass : child
module top();
base b;
child c;
initial begin
c = new();
end
endmodule : top
//Output:
// $unit::\base::new from base class new
// $unit::\child::new from child class new
// When using the super within new, super.new shall be the first statement executed in the constructor.
// This is because the superclass shall be initialized before the current class and,
// if the user code does not provide an initialization,
// the compiler shall insert a call to super.new automatically.
view raw sv_new5.sv hosted with ❤ by GitHub

2 comments:

  1. Hi Sagar, you are doing great job and helping to our platform a lot. Please contonue this and go ahead. Thankyou very much.

    ReplyDelete