Verilog中的task,function,module的本质区别

本文参考了博客Verilog中任务(task)和函数(function)_在路上的少年的博客-优快云博客_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设计也可以使用该功能)。

Verilog HDL语言中,`task` 和 `function` 都可以用于实现函数式模块,但它们有不同的工作方式和应用场景。 1. Task (任务): - Task是一个可执行的过程,它可以在任何时候暂停和恢复执行。Task通常用于处理并发操作,比如模拟环境下的事件驱动行为,或者需要执行一些耗时的操作。 - Task的语法结构通常是 `task task_name(parameters); ... endtask;` - 它允许内部状态并返回值,但不像function那样可以简单地返回结果。 - Task的实例化不需要参数,只需直接调用即可。 例如,一个简单的任务可能像这样: ```verilog task display_info(string message); // task body $display("Info: %s", message); endtask initial begin display_info("Hello from Task"); end ``` 2. Function (函数): - FunctionVerilog中主要用于计算并返回一个值,但它不能包含副作用(如改变其他变量),也不能引发事件。 - Function的语法结构通常是 `function return_type function_name(parameters); ... return expression; endfunction;` - 当从主模块调用一个函数时,函数会被立即执行,并将结果赋值给调用者。 例如,一个简单的函数可能是: ```verilog function string get_message(); return "Hello from Function"; endfunction reg [7:0] result = get_message(); // 显示函数的结果 ``` 为了演示,你可以创建两个文件:一个名为`your_module.v`的Verilog源文件(包含taskfunction定义),另一个名为`your_module_tb.v`的测试bench文件(包含任务和函数的实例化以及仿真设置)。 ```verilog // your_module.v module your_module; task display_info(message); $display("Info: %s", message); endtask function string get_message(); return "Hello from Function"; endfunction endmodule // your_module_tb.v module your_module_tb; reg your_module U; initial begin // Task call example U.display_info(get_message()); // Function call and assign to a wire for simulation wire result = U.get_message(); $display("Result: %b", result); end endmodule ``` 然后,你可以使用Verilog simulator(如Icarus Verilog、ModelSim等)对这两个文件进行联合仿真。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值