在 Verilog 中使用任务的正确方法
Correct way of using tasks in Verilog
我有一个用于 FIFO 的 Verilog 测试台,我认为使用任务来执行推送和弹出会比我现在正在做的更有效。目前,我使用一系列 repeat (ticks) @ (negedge clk)
语句在长初始 begin/end 块中推送、弹出或推送和弹出。
这使得代码难看且难以阅读。我宁愿有一个任务,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
,那么我可以推送或弹出但不能同时两者。如何让两者同时执行或按顺序执行取决于我想做什么?
一个明显的方法是创建第三个任务来完成这两项任务。另一种方法是使用 three 输入、ticks、push 和 pop 进行单一任务,并根据 inputs 是否对 push 和 pop 进行断言任务是否断言。
有没有人有其他(更好的?)方法来做到这一点?我可以在网上找到大量关于任务语法是什么以及如何编写它们的信息。没有太多关于它们的正确使用方法是什么。
使用 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
仅供参考,我建议将您的任务更改为更像以下内容。 header 更常规; 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
我有一个用于 FIFO 的 Verilog 测试台,我认为使用任务来执行推送和弹出会比我现在正在做的更有效。目前,我使用一系列 repeat (ticks) @ (negedge clk)
语句在长初始 begin/end 块中推送、弹出或推送和弹出。
这使得代码难看且难以阅读。我宁愿有一个任务,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
,那么我可以推送或弹出但不能同时两者。如何让两者同时执行或按顺序执行取决于我想做什么?
一个明显的方法是创建第三个任务来完成这两项任务。另一种方法是使用 three 输入、ticks、push 和 pop 进行单一任务,并根据 inputs 是否对 push 和 pop 进行断言任务是否断言。
有没有人有其他(更好的?)方法来做到这一点?我可以在网上找到大量关于任务语法是什么以及如何编写它们的信息。没有太多关于它们的正确使用方法是什么。
使用 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
仅供参考,我建议将您的任务更改为更像以下内容。 header 更常规; 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