Verilog基础语法——函数function与任务task

发布于:2025-07-14 ⋅ 阅读:(13) ⋅ 点赞:(0)

Verilog基础语法——函数function、任务task与模块module

写在前面

  在Verilog中,为了提升代码的复用度,一般会使用函数function与任务task对复用逻辑进行封装,但两者的用途、语法和可综合性有显著差异。

一、基本概念

1.1 function

  函数function的定义格式如下:

function <函数返回值类型> <函数返回值位宽> <函数名><函数输入端口声明>
<函数内部变量声明>
begin // 并行块语句
	//...
 	//...
end
endfunction

  其调用格式如下:

<函数名><输入端口><输出端口>;

1.2 task

  任务task的定义格式如下:

task <任务名><任务输入输出端口声明>
<任务内部变量声明>
begin // 并行块语句
	//...
	//...
end
endtask

  其调用格式如下:

<任务名><输入端口><输出端口>;

1.3 function与task的异同

  task与function的关系如下:

在这里插入图片描述
  其中,task中可以调用task和function,而function只能调用function。而函数function与任务task的异同可以总结为下表:

function task
内部允许调用function 内部允许调用function
内部不允许调用task 内部允许调用task
至少有一个输入变量 可以有多个或无输入变量
只有一个返回值,无输出变量(output) 可以有多个或无输出变量(output),没有返回值
函数调用可以在过程块(begin-end)和连续赋值语句中进行 任务调用只能在过程快(begin-end)中进行
函数的内部不能使用任何时间控制语句(@、#、wait等) 任务中可以使用时间控制语句
内部仅可适用阻塞赋值 内部可以适用阻塞赋值/非阻塞赋值

Q:什么时候使用任务task?什么时候使用函数function?
  当需要实现简单的组合逻辑运算,并且在代码中多次复用时,建议使用函数function。比如实现一个简单的位宽计算行数,根据数据的最大值,计算数据位宽:

function integer clogb2 (input integer depth);
begin
    for(clogb2=0; depth>0; clogb2=clogb2+1)
    begin
        depth = depth >> 1;  
    end                        
end
endfunction

注:对于Verilog-2005版本,有位宽计算系统函数$clog2,为什么还需要自己写位宽计算函数,这是由于不是所有版本的编译器都支持该函数,自己写的位宽计算函数可以方便代码跨平台移植。

  当需要实现包含时序控制的代码时,建议使用任务task。特别应该注意的是:task一般在仿真验证中搭配@、#、wait等时间控制语句进行使用,在可综合设计中应慎用(尽量不用) ,因为task的可综合具有工具依赖性,即使不带时间控制语句且为纯组合逻辑,也并非所有综合工具都可综合。

写在后面

  在本文中,我们学习了函数function与任务task的基本语法和区别,并对两者适用的场景进行说明。


🧐:以上为个人学习笔记,如有疑问,欢迎评论区交流探讨 !!!


网站公告

今日签到

点亮在社区的每一天
去签到