本文参考了博客Verilog中任务(task)和函数(function)_在路上的少年的博客-CSDN博客_task函数对task和function的区别比较。这里做一些简单总结;
在网上如果搜索task(任务)和function(函数)的区别,真的是好多资料。但是最近在看《Verilog HDL高级数字设计》一书时,看到了task和function一节,以前项目里的组长说最好不要写task和function,把想复用的逻辑功能写成module。看这本书的时候,我自己阅读了task的定义和调用,发现task和module一样都有端口的定义,那module和task有什么区别;主要的区别在于module可以实现很复杂的功能,里面可以包括时序和组合等各种设计要素;然而task却不可以,task里面不可以有always这样的语句,亦即task即使实现某种逻辑功能,也只能实现组合逻辑功能(如果写成module就不局限于此)。还有task可以自己调用自己,并且这样也有可能是可综合的;而module是不可以自己例化自己的,这是不合法的,更不要说可否综合;另外module的例化是和always和assign这样的语言要素是处在同一个层次的,如下代码段所示, 模块的例化和always以及assign语句是平行的;但是task的调用却只能在过程块里,而不能在过程块之外(always块或者initial块之外)。所以经过上面的辨析,你会发现,搞混淆module和task或者觉得两者是等效的想法是很可笑的。
example_unit inst_example_unit(
.module_input_port(inst_input_port),
.module_output_port(inst_output_port),
...
)
always@(posedge clk)
begin
...
call_some_task;
end
assign example_sig=...;
另外原博客中作者将task的重复调用对应到硬件上的逻辑复制,得出会造成占用大量的硬件面积的结论。没错,但是module模块的批量例化也会出现这样的情况;不同的是module模块可以通过耗散较多的时序来将需要用多个相同模块处理的任务分摊在多个时钟周期里,这样就不用多次例化而造成的面积成倍增长。而task本身不支持时序设计,所以也就只能通过反复调用来达到目的,当然如果一个设计中的确需要这样做,是没问题,因需求而异。
关于task和function的区别这里就不讲了,网上的资料很多也很详细,只说一点:task和function综合出来的电路都是组合电路,如果你想在task和function来写时序功能,那你需要的是module而不是这两个;task和function的区别是很明显的,基本上都是写法上,定义上,调用上的区别。根据这些区别,很容易辨识他们的应用场景
--------------------------------2022.05.06更新------------------------------------
最近在阅读UVM验证的书籍,发现其实早期还没有SystemVerilog这样的专门验证语言,Verilog为了能支持更多的验证功能,所以在语言定义中添加了一些用于验证的语法。其中task和function就主要是为IC验证人员用的,而不是为IC设计人员设计的(虽然IC设计也可以使用该功能)。