Ref logic in a task

Hi SV forum

I have a task where the argument is ref logic


task do_something (ref logic [15:0] data)
  wait_some_time();
  $display(data);
endtask : do_something

An additional task calls do_something task with virtual interface item as argument


  task call_task ();
    do_something (vif.item)
  endtask : call_task

The problem is that I want call do_something() with different interfaces item size but always lower then 16 bit.
If for example vif.item size is [7:0] I get the error
packed array [15:0] of logic’ but found ‘packed array [7:0] of logic’ instead
I understand why it happens but how can I fix this?
I tried casting, concatenation but with out success

In reply to shimonc:

You may have to parameterize your do_something task, but without knowing your overall requirements it will be difficult to suggest a solution.

I don’t think parametrization will help because I need it dynamically changing.
Let me explain.
lets assume I have the following interfaces


interface protocol_a;
  logic [7:0] data_a;
endinterface

interface protocol_b;
  logic [12:0] data_b;
endinterface

Now I want to do the following


virtual protocol_a vif_protocol_a;
virtual protocol_b vif_protocol_b;

task call_task ();
  do_something (vif_protecol_a.data_a);
  do_something (vif_protecol_b.data_b);
endtask : call_task

I need that do_something will support input from many interfaces items with different item sizes.
Just to give you a context, do_somthing reads a value of a register form RAL and compare it to the interface that this specific register controls.
I use ref logic because I don’t know exactly when the register will be read, so I need that the value of the input will reflect the exact value of the interface when the register if finally been read.

In reply to shimonc:

Hi shimonc,

You can use parametrized class to implement the logic with variable width.


class var_width #(parameter WIDTH=0);
 static task do_something(ref logic [WIDTH-1 : 0] data);
  wait_some_time();
  $display(data);
 endtask
endclass

// In your module or class
 var_width#(8)::do_something(vif.data_a);
 var_width#(12)::do_something(vif.data_b);