How to create a parameterized class with the parameter automatically got

hi:

I want to create a parameterized class with the parameter automatically got by the class handle in order to make the code more flexible, so I write the code like here: Edit code - EDA Playground , however an error occurred on line 27, So how can I implement my idea ?

thanks!

In reply to jianfeng.he:

A parameter has to be constant at elaboration. In your approach this is not the case.
BTW extending your driver from uvm_driver parameterized with the seq_item solves your problem.

See here (1) - EDA Playground

In reply to jianfeng.he:

I believe you many want to use type(tr) instead of tr.get_type(). But you need to show more examples of the flexibility you are looking for.

In reply to dave_59:

In reply to jianfeng.he:
I believe you many want to use type(tr) instead of tr.get_type(). But you need to show more examples of the flexibility you are looking for.

Yes, I tried type(tr) before, but it didn’t work as expected. The flexibility is that the type of drv can be determined by the type of tr I pass, code like this: Edit code - EDA Playground

In reply to chr_sue:

Maybe I didn’t express my intention clearly.
Actually I want to decide which kind of drv should be instantiated by the type of tr passed, instead of instantiating a fixed drv in advance

In reply to jianfeng.he:

You can create a lookup table that associates a transaction type with a driver type. uvm_object_wrapper is a proxy class that serves as an object representing a uvm_class type without actually creating an object of that type.

uvm_object_wrapper lookup[uvm_object_wrapper];

  initial begin
    lookup[base_trans::get_type()] = drv#(base_trans)::get_type();
    lookup[user_def_trans::get_type()] = drv#(user_def_trans)::get_type();
    lookup[user_def_abn_trans::get_type()] = drv#(user_def_abn_trans)::get_type();


    tr0 = new;
    tr1 = new;
    tr2 = new;
    
    $display("--------------------");
    
    create_drv(tr0);
    $display("--------------------");
    create_drv(tr1);
    $display("--------------------");
    create_drv(tr2);
    
  end
  function void create_drv(base_trans tr0);
    $cast(driver,lookup[tr0.get_object_type()].create_component($sformatf("drv_%0s",tr0.get_type_name()),null));
    driver.create_tr();
  endfunction

It’s very unusual to be creating transaction objects in the UVM’s build_phase. You can apply this technique for create transaction proxy objects instead of transaction objects directly.

uvm_object_wrapper lookup[uvm_object_wrapper];
uvm_object_wrapper tr0, tr1,tr2
  initial begin
    lookup[base_trans::get_type()] = drv#(base_trans)::get_type();
    lookup[user_def_trans::get_type()] = drv#(user_def_trans)::get_type();
    lookup[user_def_abn_trans::get_type()] = drv#(user_def_abn_trans)::get_type();


    tr0 = base_trans::get_type();
    tr1 = user_def_trans::get_type();
    tr2 = user_def_abn_trans::get_type()
    
    $display("--------------------");
    
    create_drv(tr0);
    $display("--------------------");
    create_drv(tr1);
    $display("--------------------");
    create_drv(tr2);
    
  end
  function void create_drv(uvm_object_wrapper tr0);
    $cast(driver,lookup[tr0].create_component($sformatf("drv_%0s",tr0.get_type_name()),null));
    driver.create_tr();
  endfunction

In reply to dave_59:

Thank you for your help, Dave!