Parameterized Classes

Hi all,

I am in the middle of writing a parametrized class, and I hit a road block. Is there a way I can overwrite a parameter in the type_id::create call?

For example, can I do something similar to this?

Class A #(int j=10)

endclass

Class B
A m_a;
int mode;

function void build();
case(mode)
0: m_a = A#(7)::type_id::create(…);
1: m_a = A#(2)::type_id::create(…);
2: m_a = A#(11)::type_id::create(…);
default: m_a = A#(4)::type_id::create(…);
endcase
endfunction
endclass

Any comment is greatly appreciated!

Thanks,
Billy

Hi Billy,

The code below works for me. You will get a warning from the UVM, but that is a symptom of the factory and parameterized classes - you can ignore it.

In the snippet:

case (i)
        0: begin
          $display("Making 7");
          //c = p7::type_id::create("p7", this);
          c = parameterized_class#(7)::type_id::create("p7", this);
          end
        1: begin
          $display("Making 1000");
          //c = p1000::type_id::create("p1000", this);
          c = parameterized_class#(1000)::type_id::create("p1000", this);
          end
      endcase

there are TWO possible solutions. One is the code as you wrote it. The other code is a non-parameterized wrapper around the parameterization (the commented out lines creating a ‘c’). The wrappers are the class definitions ‘p7’ and ‘p1000’. Personally, I don’t prefer the wrapper. I prefer the code the way you wrote it.

Best regards,
rich

import uvm_pkg::*;
`include "uvm_macros.svh"

class parameterized_class #(int T = 42) extends uvm_component;
  `uvm_component_utils(parameterized_class#(T))

  function new(string name = "p", uvm_component parent = null);
    super.new(name, parent);
  endfunction

  task run_phase(uvm_phase phase);
    $display("Class parameterized_class#(%0d) running", T);
  endtask
endclass

class p7 extends parameterized_class#(7);
  `uvm_component_utils(parameterized_class#(7))

  function new(string name = "p#(7)", uvm_component parent = null);
    super.new(name, parent);
  endfunction
endclass

class p1000 extends parameterized_class#(1000);
  `uvm_component_utils(parameterized_class#(1000))

  function new(string name = "p#(1000)", uvm_component parent = null);
    super.new(name, parent);
  endfunction
endclass

class env extends uvm_env;
  `uvm_component_utils(env)

  function new(string name = "env", uvm_component parent = null);
    super.new(name, parent);
  endfunction

  function void build_phase(uvm_phase phase);
    uvm_component c;

    for (int i = 0; i < 2; i++) begin
      case (i)
        0: begin
          $display("Making 7");
          //c = p7::type_id::create("p7", this);
          c = parameterized_class#(7)::type_id::create("p7", this);
          end
        1: begin
          $display("Making 1000");
          //c = p1000::type_id::create("p1000", this);
          c = parameterized_class#(1000)::type_id::create("p1000", this);
          end
      endcase
      c.print();
    end
  endfunction

  task run_phase(uvm_phase phase);
    phase.raise_objection(this);
    $display("Running env");
    phase.drop_objection(this);
  endtask
endclass

module top();
  initial 
    run_test("env");
endmodule

In reply to richedelman:

Thanks Rich… It helped me

In reply to chandanc9:

HI :
follow-up questions regarding parameter class, might not directly related to Billy’s question.

Q1. Is it possible you can give more details on below flow? sure as how typdef foo #(2) dummy is used

class foo #( int W = 1) extends uvm_component;
            typedef uvm_component_registery#(foo#(w), "mytest");
           ....
       endclass
       module top;
         typedef foo#(222) dummy;
          ....
            run_test("mytest");
       endmodule

I am aware that the test_name is uvm_component instead of mytest from the output below.

UVM_INFO @ 0: reporter [RNTST] Running test _uvm_component (via factory override for test "mytest")..._

Q2. how can I turn on uvm_factory::m_debug_display(…)?

Q3. In general, cons/pros of using create_by_name vs create_by_type

Thanks

In reply to richedelman:

import uvm_pkg::*;
`include "uvm_macros.svh"

class parameterized_class #(int T = 42) extends uvm_component;
  `uvm_component_utils(parameterized_class#(T))

  function new(string name = "p", uvm_component parent = null);
    super.new(name, parent);
  endfunction

  task run_phase(uvm_phase phase);
    $display("Class parameterized_class#(%0d) running", T);
  endtask
endclass

Why the class “parameterized_class” is not registered with the `uvm_componenet_param_utils ?

In reply to Abuzar Gaffari:

For that particular example, I think it was a mistake. Using
`uvm_componenet_param_utils
means no factory name is registered, and eliminates the warning.

For the last example, using
`uvm_componenet_utils
works as long as there is only one specialization of the class. run_test requires a ‘by name’ factory registration.

You may want to read: Parameterized Classes, Static Members and the Factory Macros - Verification Horizons