Queue: initialize with correct size

Is there a way to initialize just the size of a queue (like a dynamic array) without spending time on initializing the values?

I have for example a function taking and producing Queues of the same size:


typedef real realQ[$];
function  realQ times2(const ref real in[$]);
    realQ={};
    foreach(in[i]) begin
        roundQ_C.push_back(2*in[i]);
    end
endfunction

I would think the multiple push_backs are costing more simulation time than needed (probably reallocation memory).

An alternative could be to initialize realQ to a Queue of the correct size from the start and use simple indexing instead of push_back. How could I do that? I assume I could do:

real tmp[]
tmp =new[in.size()];
realQ=tmp;

But probably there is a better way?

Hi Nilu,
You want size of the queue to be fixed. You can use the bonded queue - [:N] where the size will be N+1 elements. byte q1[:127] //Queue with max size of 128
Regards
Vivek

In reply to Vivek:

Bounding the max size of a queue still does not allocate it.

In reply to dave_59:

Yes, as Dave said this isn’t reallying what I need.
I am looking for something like the reserve method of c++ queue’s (vector):

Requests that the vector capacity be at least enough to contain n elements.
If n is greater than the current vector capacity, the function causes the container to reallocate its storage increasing its capacity to n (or greater).
In all other cases, the function call does not cause a reallocation and the vector capacity is not affected.
This function has no effect on the vector size and cannot alter its elements.

There is no way to allocate any type of variable in SystemVerilog without assigning it a value. You might as well just copy the input array to the output array of the function directly, and then multiplying each element in place

You also need to think about why you would want to use a queue versus a dynamic array.

The structure of a queue is optimized so that adding a single element does not require reallocation of memory, nor does it require contiguous memory for any size of the queue. However, you pay a penalty in memory size for each element, as well as overhead in allocating each element. The structure of a dynamic array is such that it allocates a contiguous block of memory at once. Resizing the array could require re-allocating the entire array.

So it’s best to use a dynamic array if the array size will be known at its initialization and will never change during the array’s lifetime.

In reply to dave_59:

Thanks, I didn’t know that the internal structure of queue would not per se require reallocation if some size would be exceeded (unlike in some other languages).
The caller of the function is using push_back, hence the function logically also uses a queue.

In reply to NiLu:

One other point I forgot to mention was the cost of accessing individual elements. A queue is designed for easy access to its head(first) and tail(last) elements. Accessing an element by index requires traversal of the queue. So you might be better off making the input and output of your function dynamic arrays. SystemVerilog can pass dynamic arrays to queues and back quite easily as long as the elements are the same type. I assume your actual function is much more complicated that what you have shown, so this might be a better option.

In reply to dave_59:

Thanks! Good point.

Edit: it seems passing a queue to a function expecting a reference to a dynamic array is not possible in SV? I.e. this is not allowed:

function automatic void g(const ref int a[]);
    foreach(a[i])
        $display(a[i]);
endfunction

...

        automatic int d[];
        automatic int q[$]={1,2,3,4,5};
        d=q;
        g(d);
        g(q);   // <--- not OK!


Without using a reference it is working. Guess it makes sense that using a reference ‘assignment’ between both is not possible.