【问题标题】:Correct way of using tasks in VerilogVerilog中使用任务的正确方法
【发布时间】:2015-09-18 18:39:18
【问题描述】:

我有一个用于 FIFO 的 Verilog 测试平台,我认为使用任务来执行推送和弹出会比我现在所做的更有效。目前,我使用一系列repeat (ticks) @ (negedge clk) 语句来推送、弹出或推送和弹出一个长的初始开始/结束块。

这使得代码丑陋且难以阅读。我宁愿有一个任务,push_task(ticks),我可以打电话。像这样的 -

initial begin
    task_push(5);
    task_pop(2);
    task_push(10);
    ...
end

问题是,如果我这样写我的push_task -

task push_task;
    input [31:0] ticks;
    repeat (ticks) begin
            push <= 1'b1;
            push_data <= $random % (2**DATA_WIDTH);
            @ (negedge clk);
            push <= 1'b0;
        end
    end
endtask

我有一个类似的pop_task,然后我可以推送或弹出,但不能同时进行。如何让两者同时执行或按顺序执行,具体取决于我想要做什么?

一个明显的方法是创建第三个任务,两者兼而有之。另一种方法是有一个具有三个输入、滴答声、推送和弹出的单一任务,并根据任务的输入是否被断言来断言推送和弹出.

有没有人有另一种(更好的?)方法来做到这一点?我可以在网上找到大量关于任务的语法是什么以及如何编写它们的信息。没有太多关于正确使用它们的方法是什么。

【问题讨论】:

    标签: verilog


    【解决方案1】:

    使用fork-join 进行并行操作,begin-end 用于顺序操作。允许嵌套。

    例如:

    initial begin
      task_push(10);
      fork // parallel operations
        task_push(4);
        task_pop(7);
      join
      // back to sequential
      fork // another parallel operation
        task_push(6);
        begin // sequential within parallel
          task_pop(2);
          @(negedge clk); // no pop for one cycle
          task_pop(3);
        end
      join
    end
    

    仅供参考,我建议将您的任务更改为更像以下内容。标头更常规; IEEE1364-2001 及更高版本和 IEEE1800 样式,而不是传统的 IEEE1364-1995 样式。将分配移动到循环外的push 将在模拟中节省一些 CPU 周期。您的 CPU 时间可能无关紧要,但在扩展到更大的项目时需要考虑。

    task push_task(input [31:0] ticks);
    begin
      push <= 1'b1;
      repeat (ticks) begin
        push_data <= $random % (2**DATA_WIDTH);
        @(negedge clk);
      end
      push <= 1'b0;
    end
    endtask
    

    【讨论】:

    • 这行得通。谢谢你。如果可以的话,关于您关于节省 CPU 周期的“专业提示”,在将推送移出重复循环之前有一个 begin 是否更正确?正如预期的那样,这对我有用。没有它,我会得到错误(使用 iverilog 作为模拟器)。
    • 在 IEEE 1363-1995(非 ANSI 样式)中需要任何语句之前具有 begin。它成为 ANSI 样式的可选(括号中定义的输入/输出)。在IEEE 1800-2012 中,领先的begin 已全面运行。我不确定它何时成为完全可选的;我得查一下。在 v0.9 中,iverilog 应该在 push 之前不接受 begin;在 v0.8 中,您可能需要根据 iverilog.wikia.com() 使用 -g2 进行编译
    • 我查看了所有 LRM 并使用了 EDAplayground 上的代码。显然,所有版本的 IEEE1364 (Verilog) 都需要 begin-end 用于任务或函数中的多个语句。它适用于所有版本的 IEEE1800 (SystemVerilog),我在其中进行大部分开发。最新的iverilog 通过-g2009-g2012 编译标志部分支持SystemVerilog。
    • 这是有道理的。非常感谢这个例子。请问42线上的“Nothing stem”评论指的是什么?
    • 这要么是我忘记删除的废弃想法,要么是“无步骤”的拼写错误,因为一个周期没有弹出。我更新以使其更清晰。
    猜你喜欢
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    相关资源
    最近更新 更多