How to pass unknown number of parameter in the function

I’d like to implement a function in the base class, and several child class extended this base one.


class my_base extends uvm_test;
   ...
   function void my_parse(....);   // here is my question  
      ...
   endfunction : my_parse

endclass : my_base

actually I have several my_child class which required to inherit the my_base and call my_parse function but with different number of parameters and different type of parameters…
for example
in my_child1 class, I want to use my_parse(uint32 a, string b);
in my_child2 class, I want to use my_parse(string a, uint32 b, uint32 c);
in my_child3 class, I want ot use my_parse(sting a, string b, string c);
and so on…

How to implement the my_parse function in the base class ? Thank you

In reply to zz8318:

If a method is non-virtual (which is the way you wrote my_parse), you can override a method with different arguments prototypes in each derived class.

In reply to dave_59:

Hi Dave,

I actually don’t want to use override because I have to code the function in each child class.

In the base class, is that possible to parse the number of parameter and do some functional way according to them in the function my_parse ?

What I mean is like below:

class my_base
function void my_parse (…);
int num = xxxxx // the number of parameters
for (int i = 0; i < num; i++) begin
if (parameter(i} == …)
// do something
end
endfunction
endclass

In reply to zz8318:

Your requirements and intentions are not clear to me.
What you seem to be asking for is function overloading, something SystemVerilog does not have.
But if you are asking the base class function to be able to understand all the possible variations of my_parse, why not have a different function name for each variation? Other options are using argument defaults and pass by name and pass only the arguments you want. You need to explain in a lot more detail what you want to have happen based which arguments get passed. Please see this Wonderful Sound Effects To Help You Work Or Relax - Gizmo's Best

In reply to zz8318:

A function cannot morph itself based on different argument types. This cannot work like python where you can pass **kwargs and parse them.
Use different functions like Dave says or pass the superset of arguments to the function in the base class and use default assignment. Then use case statements to do different things.

In reply to dave_59:

Let me try to clarify more clear here. What I want to implement is described as below.

The my_parse function is defined in the base test. and then for example, I have four (maybe more in the future) child test. and the first child test will call this function with two parameters, one is int a and the other is string b. the second will call this function with three parameters (one is int a, one is int b and another is string c). The third will call it with four parameters ( let’s say all is string xxx) an the fourth will call it with one parameter only which is int a. (and fifth, sixth, and so on in the future created, will call this function with parameters that is different type and different number.)

What this function defined in base test is to assign the specific data to these parameters. the first parameter with string type will be assigned to “AA” and the second one will be assigned to “BB”. Meanwhile the first parameter with int type will be assigned to 1 and the second will be assigned to 2. and so on …

So I want to have this function in the base test which can parse how many parameters and what type of each of them and then do the assignment.

Thanks you.

In reply to zz8318:

You keep asking for the same feature using different words. That feature does not exist in SystemVerilog. You need to tell us the reason behind the feature request. There are ways of building lists of data so you don’t have to create functions with a fixed number of arguments. And it seems from the psuedo-code base class function you gave, it’s going to have to know how to deal with a specific set of types.

In reply to dave_59:

Thanks both. I see the SV is not support the feature I described and I will figure it out how to solve the requirement in my side.

In reply to zz8318:

If you plan to pass a fixed set of types (i.e. string, uint32, byte), I would look at tagged unions and pass an dynamic array of the tagged union types. Then you can use tagged expressions to select the code you want to execute.

In reply to dave_59:

Hi Dave, The type is fixed because we only use string and uint32 to pass the parameters. But the number is not determined. Each child class probably have any numbers to pass the parameters. Maybe the first child class have two parameters when call this my_parse()function and the second child class have ten parameters when call it…

Just as kernalmode1 mentioned, I need the similar way in Perl/Python where we can pass **kwargs and parse them…

In reply to zz8318:

I strongly suggest you look at tagged unions

typedef union tagged {
    string Str;
    uint32 Uin;
} arg_t;

function void my_parse( arg_t args[]);
  foreach(args[i])
      case (args[i]) matches
        tagged Str . s: $display("arg[%od] is a string %s",i,s);
        tagged Uin . n: $display("arg[%od] is a uint32 %d",i,n);
      endcase
endfunction

In reply to dave_59:

I see. I will try your suggestion. Thank you very much