G. B.
G. B.

Reputation: 628

SystemVerilog constructor return value

I want to do something like this, but it results in an error:

class MyPacket;
  function MyPacket not_fun_ction();
    $display("not fun");
    return this;
  endfunction
endclass

module testbench;
  MyPacket temp;
  initial
  begin
    temp = MyPacket::new().not_fun_ction().not_fun_ction();
  end
endmodule

I know, that I can't specify a return value to the constructor (link). But the constructor returns the object reference, because this assignment works: temp = MyPacket::new();. Why can't I just call a member method on the returned reference? In most other object oriented programming languages, this should be valid.

(I know, that it works when I write it as 2 separate statements:

temp = MyPacket::new(); 
temp.not_fun_ction().not_fun_ction();`, 

but I wanted to write it in a single statement.)

Upvotes: 0

Views: 107

Answers (2)

dave_59
dave_59

Reputation: 42623

Two syntactical problems with what you are trying to do.

  1. function chaining was just officially added to the IEEE 1800-2023 LRM, although most tools already support it
  2. Because of new being a reserved keyword, it can only appear as the sole RHS of an assignment; not as part of a larger expression. (in this case, a function chain)

There is an easy workaround to get what you are looking for by creating a static wrapper for the constructor.

    class MyPacket;
      function MyPacket not_fun_ction();
        $display("not fun");
        return this;
      endfunction
      static function MyPacket New;
        New = new;
      endfunction
    endclass
    
    module testbench;
      MyPacket temp,t;
      initial
      begin
        temp = MyPacket::New().not_fun_ction().not_fun_ction();
      end
    endmodule

Upvotes: 3

Serge
Serge

Reputation: 12344

But the constructor returns the object reference -- wrong. It works in c++ but not in verilog.

LRM: The new operation is defined as a function with no return type, and like any other function, it shall be nonblocking. Even though new does not specify a return type, the left-hand side of the assignment determines the return type.

So, it is a special type of a function which only works in direct assignments only. The following will work:

initial
  begin
    temp = new;
    temp.not_fun_ction().not_fun_ction();
  end

Upvotes: 2

Related Questions