从 always_ff 块内调用的任务内的阻塞分配行为
Behaviour of Blocking Assignments inside Tasks called from within always_ff blocks
在网上到处找这个问题的答案,但我还没有找到答案。
我目前有一个 SystemVerilog 项目,我在主模块的单独模块中实现了循环缓冲区。队列模块本身有一个从一组信号中获取数据的同步部分,但它也有一个响应输入的组合部分。现在,当我想在我的主模块中查询该队列的状态时,一个任务在 always_ff 块内使用阻塞赋值设置输入,然后下一条语句读取输出并对其进行操作。
在几乎 SystemVerilog 中,一个示例看起来像这样:
module foo(clk, ...)
queue = queue(clk, ...)
always_ff@(posedge clk)
begin
check_queue(...)
end
task check_queue();
begin
query_in = 3;
if (query_out == 5)
begin
<<THINGS HAPPEN>>
end
end
endtask
endmodule
module queue(clk, query_in, query_out)
always_comb
begin
query_out = query_in + 2;
end
endmodule
我的问题基本上归结为,这个想法行得通吗?在我看来,因为队列是组合的,所以它应该在应用输入刺激后立即响应它应该没问题,但因为它在 always_ff 块内的任务中,我有点担心阻塞分配的使用。
有人可以帮忙吗?如果您需要更多信息,请告诉我,我可以提供一些说明。
这会造成竞争条件,很可能不会起作用。它与您使用任务无关。您正在尝试读取在另一个并发进程中分配的信号 (queue_out
) 的值。当您到达 If
语句时它是否得到更新是一场竞赛。对 always_ff
块之外的所有变量使用 non-blocking 赋值,它保证你得到以前的值。
为了弄清楚这些东西,您可以在脑子里将任务内联到 always_ff 中。顺便说一句,在你的情况下它看起来真的像一个函数。现在,请记住,任何 always 块的执行必须在任何其他块执行之前完成。因此,以下将永远不会在同一时钟边沿评估为“5”:
query_in = 3;
if (query_out == 5)
query_out 将变为 5 after
这个块(你的任务)被评估并且仅在下一个时钟边沿准备就绪。所以,你应该得到一个周期的延迟。
你需要把它分成几个 always 块。
在网上到处找这个问题的答案,但我还没有找到答案。
我目前有一个 SystemVerilog 项目,我在主模块的单独模块中实现了循环缓冲区。队列模块本身有一个从一组信号中获取数据的同步部分,但它也有一个响应输入的组合部分。现在,当我想在我的主模块中查询该队列的状态时,一个任务在 always_ff 块内使用阻塞赋值设置输入,然后下一条语句读取输出并对其进行操作。
在几乎 SystemVerilog 中,一个示例看起来像这样:
module foo(clk, ...)
queue = queue(clk, ...)
always_ff@(posedge clk)
begin
check_queue(...)
end
task check_queue();
begin
query_in = 3;
if (query_out == 5)
begin
<<THINGS HAPPEN>>
end
end
endtask
endmodule
module queue(clk, query_in, query_out)
always_comb
begin
query_out = query_in + 2;
end
endmodule
我的问题基本上归结为,这个想法行得通吗?在我看来,因为队列是组合的,所以它应该在应用输入刺激后立即响应它应该没问题,但因为它在 always_ff 块内的任务中,我有点担心阻塞分配的使用。
有人可以帮忙吗?如果您需要更多信息,请告诉我,我可以提供一些说明。
这会造成竞争条件,很可能不会起作用。它与您使用任务无关。您正在尝试读取在另一个并发进程中分配的信号 (queue_out
) 的值。当您到达 If
语句时它是否得到更新是一场竞赛。对 always_ff
块之外的所有变量使用 non-blocking 赋值,它保证你得到以前的值。
为了弄清楚这些东西,您可以在脑子里将任务内联到 always_ff 中。顺便说一句,在你的情况下它看起来真的像一个函数。现在,请记住,任何 always 块的执行必须在任何其他块执行之前完成。因此,以下将永远不会在同一时钟边沿评估为“5”:
query_in = 3;
if (query_out == 5)
query_out 将变为 5 after
这个块(你的任务)被评估并且仅在下一个时钟边沿准备就绪。所以,你应该得到一个周期的延迟。
你需要把它分成几个 always 块。