使用 for 循环构造使用多个音序器时出现 UVM 错误
UVM error when using multiple sequencers using for loop construct
我的 UVM 虚拟序列主体中有以下代码:
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
代码信息:
- 我有 8 个音序器,每个音序器接收自己的序列。因此第一个“for 循环”有 8 次迭代。
- 在学习了一些教程之后,我了解到使用 fork-join 我可以运行 8 个序列并行到 8 个序列器。
但是当我 运行 代码时,我在“if(!my_sequence...”行代码中出错。错误是:
The object is being used before it was constructed/allocated.
我还通过摆脱外部 for 循环并使用如下索引号来测试代码:
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
...
这似乎有效。但是我想用for循环写出更好的代码。
其他信息:使用 DVE 调试时,我看到 x_idx 值为 8。不确定为什么显示为 8,也不确定这是否是错误的原因。
您的问题是您将 x_idx
声明放在 begin/end
块内,该块位于 fork/join_none
内。您不希望在并行线程开始执行时进行初始化;您希望它在 for 循环的每次迭代执行时发生。你应该写成
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
此外,无需在 class 中使用 automatic
关键字——在 class 方法中声明的所有变量都具有隐式自动生命周期。
请注意,fork/join 中的声明是在遇到 fork 块时初始化的,而不是在 fork 中的语句开始其线程时初始化的。声明不是单独的线程。你也可以这样写:
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
在这两种情况下,每个循环迭代都有一个新的 x_idx
实例,但是 fork/join_none
中的语句直到 after[=27] 才开始执行=] 所有迭代完成。
我的 UVM 虚拟序列主体中有以下代码:
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
代码信息:
- 我有 8 个音序器,每个音序器接收自己的序列。因此第一个“for 循环”有 8 次迭代。
- 在学习了一些教程之后,我了解到使用 fork-join 我可以运行 8 个序列并行到 8 个序列器。
但是当我 运行 代码时,我在“if(!my_sequence...”行代码中出错。错误是:
The object is being used before it was constructed/allocated.
我还通过摆脱外部 for 循环并使用如下索引号来测试代码:
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
...
这似乎有效。但是我想用for循环写出更好的代码。
其他信息:使用 DVE 调试时,我看到 x_idx 值为 8。不确定为什么显示为 8,也不确定这是否是错误的原因。
您的问题是您将 x_idx
声明放在 begin/end
块内,该块位于 fork/join_none
内。您不希望在并行线程开始执行时进行初始化;您希望它在 for 循环的每次迭代执行时发生。你应该写成
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
此外,无需在 class 中使用 automatic
关键字——在 class 方法中声明的所有变量都具有隐式自动生命周期。
请注意,fork/join 中的声明是在遇到 fork 块时初始化的,而不是在 fork 中的语句开始其线程时初始化的。声明不是单独的线程。你也可以这样写:
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
在这两种情况下,每个循环迭代都有一个新的 x_idx
实例,但是 fork/join_none
中的语句直到 after[=27] 才开始执行=] 所有迭代完成。