Verilog初级教程(18)Verilog中的函数与任务

网友投稿 918 2022-05-30

文章目录

前言

正文

函数

语法

函数声明

从函数中返回一个值

函数调用

函数规则

任务

语法

任务调用

全局任务

函数与任务之间的区别

往期回顾

参考资料及推荐关注

前言

函数与任务是仿真中常用的语法,但合理使用也可以在设计中使用,可以综合。

正文

函数

很多时候我们会发现某些代码是重复的,在RTL中被多次调用。它们大多不消耗仿真时间,可能涉及复杂的计算,需要用不同的数据值来完成。在这种情况下,我们可以声明一个函数,将重复的代码放在函数里面,让它返回结果。这将大大减少RTL中的行数,因为现在你需要做的就是进行函数调用,并传递需要在其上进行计算的数据。事实上,这与C语言中的函数非常相似。

函数的目的是返回一个要在表达式中使用的值。一个函数定义总是以关键字function开始,后面是返回类型、名称和用括弧括起来的端口列表。当Verilog找到endfunction关键字时,就知道一个函数定义结束了。注意,一个函数至少要声明一个输入,如果函数没有返回任何东西,则返回类型为void。

Verilog初级教程(18)Verilog中的函数与任务

function [automatic] [return_type] name ([port_list]); [statements] endfunction

1

2

3

关键字automatic将使函数重入,在任务中声明的项目被动态分配,而不是在任务的不同调用之间共享。这对于递归函数,以及当同一个函数在分叉时被N个进程并发执行时,将非常有用。

有两种方式来声明函数的输入。

function [7:0] sum; input [7:0] a, b; begin sum = a + b; end endfunction function [7:0] sum (input [7:0] a, b); begin sum = a + b; end endfunction

1

2

3

4

5

6

7

8

9

10

11

12

函数定义将隐含地创建一个与函数同名的内部变量。因此,在函数的作用域内声明另一个同名的变量是非法的。返回值是通过将函数结果赋值给内部变量来初始化的。

sum = a + b;

1

函数调用是一个带有表达式的操作数,其语法如下图所示。

reg [7:0] result; reg [7:0] a, b; initial begin a = 4; b = 5; #10 result = sum (a, b); end

1

2

3

4

5

6

7

8

函数不能包含任何时间控制的语句,如#, @, wait, posedge, negedge

函数不能调用任务,因为它可能会消耗仿真时间,但可以调用其他函数。

函数应该至少有一个输入

函数不能有非阻塞性的赋值或force…release或assign…deassign。

函数不能有任何触发器

函数不能有output或者inout

任务

函数的作用是对输入进行一些处理,并返回一个单一的值,而任务则更为通用,它可以计算出多个结果值,并使用output和inout类型的参数返回。任务可以包含@、posedge等仿真耗时元素。任务有两种写法,我们接下来会看到。

// Style 1 task [name]; input [port_list]; inout [port_list]; output [port_list]; begin [statements] end endtask // Style 2 task [name] (input [port_list], inout [port_list], output [port_list]); begin [statements] end endtask

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

关键字automatic将使任务重入,否则它将默认为静态的。如果一个任务是静态的,那么它的所有成员变量将在同一任务的不同调用中被共享,该任务已被启动为并发运行。注意,auomatic任务项不能通过层次引用来访问。

如果任务不需要任何参数,那么可以避免使用参数列表。如果任务需要参数,则可以在调用任务时在同一条语句中提供参数。

task sum (input [7:0] a, b, output [7:0] c); begin c = a + b; end endtask // or task sum; input [7:0] a, b; output [7:0] c; begin c = a + b; end endtask initial begin reg [7:0] x, y , z; sum (x, y, z); end

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

任务使能参数(x,y,z)对应于任务定义的参数(a,b,c)。由于a和b是输入,x和y的值将分别放在a和b中。由于c被声明为输出,并且在调用过程中与z连接,所以总和将自动从c传递到变量z中。

在所有模块之外声明的任务称为全局任务,因为它们具有全局范围,可以在任何模块中调用。

// This task is outside all modules task display(); $display("Hello World !"); endtask module des; initial begin display(); end endmodule

1

2

3

4

5

6

7

8

9

10

11

仿真结果:

Hello World !

1

往期回顾

Verilog初级教程(17)Verilog中的case语句

Verilog初级教程(16)Verilog中的控制块

Verilog初级教程(15)Verilog中的阻塞与非阻塞语句

Verilog初级教程(14)Verilog中的赋值语句

Verilog初级教程(13)Verilog中的块语句

Verilog初级教程(12)Verilog中的generate块

Verilog初级教程(11)Verilog中的initial块

Verilog初级教程(10)Verilog的always块

Verilog初级教程(9)Verilog的运算符

Verilog初级教程(8)Verilog中的assign语句

Verilog初级教程(7)Verilog模块例化以及悬空端口的处理

Verilog初级教程(6)Verilog模块与端口

Verilog初级教程(5)Verilog中的多维数组和存储器

Verilog初级教程(4)Verilog中的标量与向量

Verilog初级教程(3)Verilog 数据类型

Verilog初级教程(2)Verilog HDL的初级语法

Verilog初级教程(1)认识 Verilog HDL

芯片设计抽象层及其设计风格

Verilog以及VHDL所倡导的的代码准则

FPGA/ASIC初学者应该学习Verilog还是VHDL?

参考资料及推荐关注

Verilog Functions

Verilog Task

交个朋友

IDE

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:C语言学习第11篇---union enum, sizeof, typedef 分析
下一篇:【用户案例】华为好望商城丨智慧视觉助力湖北数字新基建,共建城市智能体!
相关文章