Search code examples
system-veriloguvm

The parent argument in the uvm_component constructor


I expected my_child to inherit the say_hello function from my_parent in the following code, but it did not.

Can someone explain to me what exactly parent argument does?

class my_parent extends uvm_component;
  `uvm_component_utils(my_parent);
  
  function new(string name = "my_parent", uvm_component parent);
    super.new(name, parent);
  endfunction: new
  
  function void say_hello;
    $display("Hello, UVM!");
  endfunction: say_hello
endclass: my_parent
/*========================================*/

class my_child extends uvm_component;
  `uvm_component_utils(my_child);
  
  function new(string name = "my_child", uvm_component parent);
    super.new(name, parent);
  endfunction: new
endclass: my_child
/*========================================*/

module top;
  my_parent p;
  my_child c;
  
  initial begin
    p = my_parent::type_id::create("p", null);
    c = my_child::type_id::create("c", p);
    c.say_hello;
  end 
endmodule: top

Solution

  • You are mixing up the terms parent and child with the principals of class inheritance. They are distinct objects. A parent creates a child, and the uvm_component represents a hierarchal family tree in a database. Each component you create has a handle to its parent, and the parent has a list of handles that are its children.

    class my_child extends uvm_component;
      `uvm_component_utils(my_child);
      function new(string name = "my_child", uvm_component parent);
        super.new(name, parent);
      endfunction: new
    endclass: my_child
    class my_parent extends uvm_component;
      `uvm_component_utils(my_parent);
      my_child child;
      function new(string name = "my_parent", uvm_component parent);
        super.new(name, parent);
      endfunction: new
      function void build_phase(uvm_phase phase;
         child = my_child::type_id::create("child", this); // 'this' is the parent object
      endfunction : build_phase
    endclass: my_parent
    module top;
      my_parent p;  
      initial begin
        p = my_parent::type_id::create("p", null);
      end 
    endmodule: top
    

    When using inheritance, we have entended or derived classes, they are not the children of the base class.

    import uvm_pkg::*;
    `include "uvm_macros.svh"
    class my_child extends uvm_component;
      `uvm_component_utils(my_child);
    
      function new(string name = "my_child", uvm_component parent);
        super.new(name, parent);
      endfunction: new
      task  run_phase(uvm_phase phase);
        $display("Hello, UVM!, from base");
      endtask: run_phase
    endclass: my_child
    class my_parent extends uvm_component;
      `uvm_component_utils(my_parent);
      my_child child;
      function new(string name = "my_parent", uvm_component parent);
        super.new(name, parent);
      endfunction: new
      function void build_phase(uvm_phase phase);
        child = my_child::type_id::create("cchild", this); // 'this' is the parent object
      endfunction : build_phase
    endclass: my_parent
    class my_child_extended extends my_child;
      `uvm_component_utils(my_child_extended);
    
      function new(string name = "my_child", uvm_component parent);
        super.new(name, parent);
      endfunction: new
    endclass: my_child_extended
    module top;
      my_parent p;  
      initial begin
        my_child::type_id::set_type_override(my_child_extended::get_type());
        run_test("my_parent");
      end 
    endmodule: top