数据透视怎么弄(数据透视怎么做)
918
2022-05-30
文章目录
前言
正文
函数
语法
函数声明
从函数中返回一个值
函数调用
函数规则
任务
语法
任务调用
全局任务
函数与任务之间的区别
往期回顾
参考资料及推荐关注
前言
函数与任务是仿真中常用的语法,但合理使用也可以在设计中使用,可以综合。
正文
函数
很多时候我们会发现某些代码是重复的,在RTL中被多次调用。它们大多不消耗仿真时间,可能涉及复杂的计算,需要用不同的数据值来完成。在这种情况下,我们可以声明一个函数,将重复的代码放在函数里面,让它返回结果。这将大大减少RTL中的行数,因为现在你需要做的就是进行函数调用,并传递需要在其上进行计算的数据。事实上,这与C语言中的函数非常相似。
函数的目的是返回一个要在表达式中使用的值。一个函数定义总是以关键字function开始,后面是返回类型、名称和用括弧括起来的端口列表。当Verilog找到endfunction关键字时,就知道一个函数定义结束了。注意,一个函数至少要声明一个输入,如果函数没有返回任何东西,则返回类型为void。
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小时内删除侵权内容。