Search code examples
constructorsystem-verilog

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.)


Solution

  • 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