How can a task return a Queue?

I need a task to return a queue. How can I do this ? I was able to do this using a function in the following way

typedef bit array_type[$]

function array_type my_function();


return queue_of_elements;
endfunction : my_function

However, I need to move away from function to a task as I need to have some delay element in that (Delay). But I’m not sure how to make my task return that queue_of_elements.

Please suggest me a solution.

Thank You

You can make one of the task’s arguments an output:

task my_task(output array_type q);
...
q = {1,0,1,1};
...
endtask

The will copy the array upon existing the task.

If the task is going to update the queue before some delay, and another process needs to see the queue before the task returns, then you can use a ref argument.

task my_task(ref array_type q);
...
q = {1,0,1,1};
...
endtask

In reply to dave_59:

Thanks a lot. This is working as I wanted.

In reply to szy0014:

Hi, Dave,

Could you please explain what do you mean by “If the task is going to update the queue before some delay” we could use a ref argument ?

Why the key word ref could provide some delay here, it appears to me that only difference is that how to copy the q (output means task copy the value when it ends, the ref means we pass the handle of variable inside the task)…

Thanks,

WangYang

In reply to caowangyang:

WangYang,

The ref argument does not provide delay, it allows the tasks to consume time and keep the argument values in sync. A better example is passing a clock to a task

task t(ref bit clk);
  repeat (10) @(posdege clk) $display("tick-tock");
endtask

Had you passed clk as an input argument, the task would hang as it would never see a change.
If you have a task with no blocking statements, or a function, there really is no point in having ref arguments except as an optimization to prevent the copying of large arrays (which many tools do as an optimization implicitly for you anyways)

In reply to dave_59:

Thanks, Dave, it is clear enough for me.

In reply to dave_59:

Will this work, if i call such a task from a fork join?
i have a task with output argument of type queue, not ref such simple output. i call this task from fork join. size of the queue is zero after fork join exits.

In reply to twainerm:

For input, output and inout task arguments, it makes no difference what the datatype of the argument is. The input argument get copied by value upon entering the task, and output arguments get copied when exiting the tasks.

Hii Dave,

I am facing one issue for example

typedef logic [7:0] byte_q[$];

logic [7:0] temp_q[$];

function byte_q decode_data(input string hex_string);
logic [7:0]  l_byte_queue[$];
................ 
...............
return  l_byte_queue;
endfunction

so, here i am returning a queue so i need to store this queue data inside another queue

function void write_tx(seq_item  seq_item_h);
foreach (seq_item.data[i])begin
temp_q.push_back(decode_data(seq_item_h.data[i]));
................
endfunction

class seq_item extends uvm_sequence_item;
string data [];
endclass

so while pushing into temp_q i am getting error like cannot assign an unpacked type ‘reg[7:0] []’ to a packed type ‘reg [7:0]’

The push_back() method of a queue can only push one element onto the queue at a time. You can either add another nested foreach loop or use an array concatenation

temp_q = {temp_q, decode_data(seq_item_h.data[i]));
1 Like