在always_ff块内调用的任务内部阻止分配的行为

时间:2018-03-02 15:19:51

标签: verilog system-verilog hdl

到处寻找这个问题的答案,但我还没有找到答案。

我已经有一个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块内的任务中,我有点担心使用阻塞分配。

有人可以帮忙吗?如果您需要更多信息,请告诉我,我可以给出一些澄清。

2 个答案:

答案 0 :(得分:1)

这会产生竞争条件,很可能无效。它与您使用任务无关。您正在尝试读取在另一个并发进程中分配的信号(queue_out)的值。到达If语句时是否更新是竞赛。对所有超出always_ff块的变量进行非阻塞赋值,它可以保证您获得之前的值。

答案 1 :(得分:0)

为了弄清楚这些东西,你可以精神上内联always_ff中的任务。顺便说一下,它看起来真的像你的情况一样。现在,请记住,任何always块的执行必须在执行任何其他块之前完成。因此,以下内容永远不会在同一时钟边缘评估为'5':

    query_in = 3;
    if (query_out == 5)

query_out将变为5 after此块(您的任务)将被评估,并且仅在下一个时钟边缘准备就绪。所以,你应该得到一个周期的延迟。

您需要将其拆分为几个常规块。