在Verilog中使用任务的正确方法

时间:2015-09-18 18:39:19

标签: verilog

我有一个用于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,然后我可以推或弹,但不能同时推两个。我如何让两者同时执行或按顺序执行,具体取决于我想要做什么?

一种显而易见的方法是创建同时执行这两项操作的第三项任务。另一种方法是使用三个输入,滴答,推送和弹出进行单一任务,并根据是否断言任务的输入来确定推送和弹出

有没有人有另一种(更好?)方式这样做?我可以在网上找到大量有关任务语法和编写方法的信息。关于使用它们的正确方法并不多。

1 个答案:

答案 0 :(得分: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&amp;以上和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