问题
According to 1800-2012 specs,
Queue::delete( [input int index] )
deletes an element of a queue in SystemVerilog, furthermore, a Queue can perform the same operations as an unpacked Array, giving it access to:
Array::find_first_index( )
which returns the index of the first element matching a certain criteria. i.e.
find_first_index( x ) with ( x == 3)
Now I'd like to delete a unique item, guaranteed to exist, from the Queue. Combining 1 and 1 gives me:
queue.delete(queue.find_first_index( x ) with ( x == obj_to_del ));
The compiler does not appreciate that though saying that the argument passed must be either an integer or integer compatible. I could probably pull the two apart:
int index = queue.find_first_index( x ) with ( x == obj_to_del );
queue.delete( index );
or force an integer by typecasting find_first_index:
queue.delete(int'(queue.find_first_index( x ) with ( x == obj_to_del ))) //Just finished compiling, does not work.
The former does not look very elegant to me, and the latter seems somewhat forced which made me curious if there is maybe a more proper way to accomplish this. Is find_first_index possibly returning an array of size one with the index at location 0?
EDIT: I foolishly did not provide a self contained example: A stripped example of what I'm doing looks like:
class parent_task;
endclass;
class child_taskA extends parent_task;
endclass;
class child_taskB extends parent_task;
endclass;
class task_collector;
child_taskA A_queue[$];
child_taskB B_queue[$];
function delete_from_queue(parent_task task_to_del);
case (task_to_del.type):
A: A_queue.delete(A_queue.find_first_index( x ) with ( x == task_to_del));
B: B_queue.delete(B_queue.find_first_index( x ) with ( x == task_to_del));
default: $display("This shouldn't happen.");
endfunction
endclass
The error message, word for word is:
Error-[SV-IQDA] Invalid Queue delete argument
"this.A_queue.find_first_index( iterator ) with ((iterator == task))"
Queue method delete can take optional integer argument. So, argument passed
to it must be either integer or integer assignment compatible.
There are checks in place to make sure that the task in question exists before the call to delete_from_queue.
回答1:
queue.delete(int'(queue.find_first_index( x ) with ( x == obj_to_del )));
works for me. It would really help if you could provide complete self contained examples like the one below:
module top;
int queue[$] = {1,2,3,4,5};
let object_to_del = 3;
initial begin
queue.delete(int'(queue.find_first_index( x ) with ( x == object_to_del )));
$display("%p", queue);
end
endmodule
But what if there was no match? Would you not need to test the result from find_first_index() anyways before deleting?
回答2:
The int cast didn't work for me as well but the following worked
int index_to_del[$];
index_to_del = que.find_first_index(x) with ( x == task_to_del );
que.delete(index_to_del[0]);
来源:https://stackoverflow.com/questions/30494550/how-to-match-and-delete-an-element-from-a-queue