I’m doing something like this in SV but it gives me error.
`define s 8
int array[31:0];
int size =`s;
int queue[$];
task t();
for(int i=31;i>=0;i-=size )
queue.push_back(array[i-:size]); //This doesn't works
/* queue.push_back(array[i-:`s]); //This works // */
endtask
If the range of slicing MAX-MIN is fixed than i can do it but how to do if MAX-MIN is not fixed ?
How to implement above code without using defines because i want a variable size whose value is random (simulation time) but array is expecting compile time constant?
In reply to aditgupta100:
You are trying to push [i-:size] (or specifically [i-:`s]) ints into a queue of int. This might give incompatible assignment type.
Moreover, the slicing operator (+: or -:) expects the right-hand value (the one after ‘:’) to be constant. Since macros are compile time constants (text substitutes), the macro might work. Sitll the incompatible type assignment shall be showcased by simulator.
In reply to sharvil111:
In my usecase even the right hand side needs to be a variable (which is random) so it can’t be macro. So any workaround? what shall i do?
In reply to aditgupta100:
The with clause of the streaming operator can help here.
typedef int intQ_t[$];
for(int i=31;i>=size;i-=size )
queue = {queue, intQ_t'({>>{array with [i-:size]}})};
Note that the push_back() method can only push one element on the the queue at a time.
A bit-stream cast could do the assignment in one statement without a for loop
queue = intQ_t'(array);
In reply to dave_59:
In reply to aditgupta100:
The with clause of the streaming operator can help here.
typedef int intQ_t[$];
for(int i=31;i>=size;i-=size )
queue = {queue, intQ_t'({>>{array with [i-:size]}})};
Note that the push_back() method can only push one element on the the queue at a time.
A bit-stream cast could do the assignment in one statement without a for loop
queue = intQ_t'(array);
Hi Dave thanks for replying.
Can you please elaborate a more , i’m not able to understand how this works ?
I want to push slices of array to the queue such that the size of queue is (32/size) ie queue.size() = 4 in my case.
Thanks
In reply to dave_59:
Hi dave i tried your code as it is and it is giving me error :
ncvlog: *E,SOWUNS with expression in streaming concatenation is not supported.
In reply to aditgupta100:
You have to take up unsupported features with your vendor. This works fine in Questa.
It would help if you showed an example with the data you expect array and queue. Your latest description does not match what your original code was trying to do. Each push_back() was trying to push 8 elements onto the queue, and the for-loop iterated 4 times.
In reply to dave_59:
Say i have a 32 bit array ex. :
arr = 0xAFAFAFAF
and i want a queue to be like this if size = 8
queue[0] = AF
queue[1] = AF
queue[2] = AF
queue[3] = AF
Hence queue size is 4.
But if the size =16 queue should be
queue[0] = AFAF
queue[1] = AFAF
In reply to aditgupta100:
You can try this it worked for me . Check Convert task .
class t1;
//bit [31:0] array;
int array;
int size=8;
int queue[$];
task convert;
int tmp;
int temp_array;
temp_array = this.array;
for (int i=1; i*size <= 32; i++) begin
tmp = temp_array & ((1 << size)-1);
temp_array = temp_array >> size;
queue.push_back(tmp);
end
endtask
task print_queue();
foreach(queue[i]) begin
$display("\n queue[%d]=%0h",i,queue[i]);
end
endtask
task delete_queue();
queue= {};
endtask
endclass
module m1;
t1 t;
initial begin
t=new();
t.array= 32'hAFAF_AFAF;
t.size = 8;
t.convert();
t.print_queue();
t.delete_queue();
$display("\nChanging size to 16");
t.size = 16;
t.convert();
t.print_queue();
t.delete_queue();
$display("\nChanging array value ");
t.array=32'h5345_7821;
t.convert();
t.print_queue();
t.delete_queue();
$display("\nChanging size to 16");
t.size = 8;
t.convert();
t.print_queue();
t.delete_queue();
end
endmodule