I have a sort of following code in the body of my UVM virtual seq:
begin:
for(int x=0; x<8; x++) begin
fork begin
automatic int x_idx = x;
for(int i=0; i<100; i++) begin
if(!my_sequence[x_idx].randomize() with {...}
my_sequence[x_idx].start(p_sequencer.my_sequencer[x_idx];
end
end join_none
end
end
Code information:
But when I run the code I get error on the "if(!my_sequence..." line of code. Error being:
The object is being used before it was constructed/allocated.
I also tested the code by getting rid of the outer for loop and instead using index numbers as follows:
fork begin
automatic int x_idx = x;
for(int i=0; i<100; i++) begin
if(!my_sequence[0].randomize() with {...}
my_sequence[0].start(p_sequencer.my_sequencer[0];
end
end join_none
fork begin
automatic int x_idx = x;
for(int i=0; i<100; i++) begin
if(!my_sequence[0].randomize() with {...}
my_sequence[1].start(p_sequencer.my_sequencer[1];
end
end join_none
...
This seems to work. But I want to write better code with for loop.
Another info: While debugging using DVE I saw the x_idx value to be 8. Not sure why it is showing as 8 and also not sure if that's the reason for the bug.
Your problem is you placed the x_idx
declaration inside the begin/end
block that is inside the fork/join_none
. You don't want the initialization to happen when the parallel threads start executing; you want it to happen as each iteration of the for loop executes. You should write it as
begin
for(int x=0; x<8; x++)
fork
int x_idx = x;
for(int i=0; i<100; i++) begin
if(!my_sequence[x_idx].randomize() with {...}
my_sequence[x_idx].start(p_sequencer.my_sequencer[x_idx];
end
join_none
end
Also, there's no need to use the automatic
keyword inside a class—all variables declared inside a class method have an implicit automatic lifetime.
Note that declarations inside fork/join's initialize upon hitting the fork block, not when the statements inside the fork begin their threads. The declarations are not separate threads. You could also write as:
begin
for(int x=0; x<8; x++) begin
int x_idx = x;
fork
for(int i=0; i<100; i++) begin
if(!my_sequence[x_idx].randomize() with {...}
my_sequence[x_idx].start(p_sequencer.my_sequencer[x_idx];
end
join_none
end
end
In both cases, there is a new instance of x_idx
for every loop iteration, but the statements inside the fork/join_none
don't begin executing until after all iterations complete.