-1
\$\begingroup\$

Code link: [https://edaplayground.com/x/9cte]

For the below code

class mem_test extends uvm_test;

  `uvm_component_utils(mem_test)

  function new(string name, uvm_component parent);
  super.new(name, parent);
endfunction

  
  virtual function void end_of_elaboration_phase(uvm_phase phase);
    super.end_of_elaboration_phase(phase);
     uvm_top.print_topology();
  endfunction
  
endclass

I don't get any compilation error but for

class mem_test extends uvm_test;

  `uvm_component_utils(mem_test)

  virtual function void end_of_elaboration_phase(uvm_phase phase);
    super.end_of_elaboration_phase(phase);
     uvm_top.print_topology();
  endfunction
  
endclass

I get

[2025-11-21 03:32:42 UTC] xrun -Q -unbuffered '-timescale' '1ns/1ns' '-sysv' '-access' '+rw' -uvmnocdnsextra -uvmhome $UVM_HOME $UVM_HOME/src/uvm_macros.svh design.sv testbench.sv TOOL: xrun 23.09-s001: Started on Nov 20, 2025 at 22:32:42 EST xrun: 23.09-s001: (c) Copyright 1995-2023 Cadence Design Systems, Inc. class mem_test extends uvm_test; | xmvlog: *E,FAABP3 (mem_test.sv,1|31): The implicit call to super.new() is missing an actual argument for the formal argument 'name' . class mem_test extends uvm_test; | xmvlog: *E,FAABP3 (mem_test.sv,1|31): The implicit call to super.new() is missing an actual argument for the formal argument 'parent' . xrun: *E,VLGERR: An error occurred during parsing. Review the log file for errors with the code *E and fix those identified problems to proceed. Exiting with code (status 1). TOOL: xrun 23.09-s001: Exiting on Nov 20, 2025 at 22:32:43 EST (total: 00:00:01) Exit code expected: 0, received: 1

But default arguments were not given for the first version in which new constructor was defined in the class. So why this error did not appeared for first version?

\$\endgroup\$
0

1 Answer 1

2
\$\begingroup\$

I think you are confusing defaults with implicits, and formal/actual arguments.

In the definition of uvm_test:

virtual class uvm_test extends uvm_component;
  function new (string name, uvm_component parent);
    super.new(name,parent);
  endfunction
...

Its constructor, new(), is defined with two formal arguments: name and parent. Inside the constructor, a single statement calls super.new with name and parent as the actual arguments. This call triggers the constructor of uvm_component, which also has two formal arguments with the same names: name and parent.

When you call a method, whether it’s a task, function, or constructor, every formal argument you define must be passed an actual argument when you call that method. For instance, if you define a constructor with two formal arguments, it must be passed two actual arguments when called, assuming that the types of the actual arguments are compatible with the types of the formal arguments.

An exception to this rule is when you define a method, you can provide default values for your formal arguments. This means that passing an actual argument is optional. However, there are no default arguments involved in your question.

Whenever you declare a class, it implicitly defines a constructor without any formal arguments unless you explicitly declare one. Additionally, in any extended class constructor, it implicitly adds a call to super.new() as the first statement if you don’t explicitly do so. Therefore, any implicitly declared constructor in an extended class will also have a call to super.new().

That implicit call to super.new() will not have any actual arguments. If the base class has formal arguments and you haven’t provided defaults for them, the compiler will generate an error. This is what happens in the second version of your class mem_test which is effectively declared as:

class mem_test extends uvm_test;

  `uvm_component_utils(mem_test)
  function new();
     super.new();
  endfunction
  virtual function void end_of_elaboration_phase(uvm_phase phase);
    super.end_of_elaboration_phase(phase);
     uvm_top.print_topology();
  endfunction
  
endclass

Also note that embedded in the code generated by the `uvm_component_utils(mem_test) factory registration macro is a call to mem_test::new(name,parent). That means any constructor registered with the factory must have two formal arguments; name and parent.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.