【FPGA篇章五】FPGA函数任务:对讲解函数与任务专题展开详解
欢迎大家关注我的微信公众账号,支持程序媛写出更多优秀的文章

任务和函数也属于过程块,多用于仿真文件设计中,使用两者的目的有所区别:
函数(function):对输入的值执行一些处理,返回一个新的值。
因此至少有一个input类型的参数,不能有inout或output类型的参数。
函数在一个仿真时间单位内执行完毕,因此不能包含任务、不能使用非阻塞赋值。
使用上都是把函数作为表达式中的一个操作数。
任务(task):其实作用与module差不多,只是能在过程块中调用,实现的功能比函数更加广泛。
任务可以包含时序控制语句,也可以调用其它任务和函数;
可以使用任意类型的参数,也可以没有参数。
将一个数据按位取反后得到一个新的数据,
将这个功能用任务的形式实现,调用时形式如下:
switch_bytess(old_word, new_word);
将这个功能用函数的形式实现,调用时形式如下:
new_word = switch_bytess(old_word);
接下来分别介绍任务和函数的一些用法,再给出Verilog支持的系统任务和系统函数。
1 函数(function)
函数用作表达式中的一个操作数。一个函数的声明架构如下:
function 返回值位宽或类型说明 函数名;
端口声明;
局部变量定义;
//函数主体
begin
语句1;
.....
语句n;
end
endfunction
下面是一个function的例子:
module alu(a,b,product,result);
input[:] a,b;
output[:] product,result;
wire[:] a,b;
reg[:] product,result;
reg [:] all_result; always@(a,b)
begin //注意调用函数的方法与任务不同;
all_result = cal(a,b);
product = all_result[:];
result = all_result[:];
end //定义函数cal
function [:] cal;
input[:] a;
input[:] b;
reg[:] temp; begin
product = a*b;
temp = a*a;
result = temp-b;
cal = {product,result};
end
endfunction endmodule
函数的默认返回值是一个标量,可以使用“[范围或类型]”将返回值设置为real、integer、time、realtime或矢量。
定义函数时,函数内部会隐式地定义一个和函数名相同的数据。函数内部可以直接使用这个数据,这个数据的值便是函数的返回值。
递归函数
verilog中的函数是不能进行递归调用的;设计模块中若某函数在两个不同的地方被同时并发调用,由于这两个调用同时对同一块地址空问进行操作,那么计算结果将是不确定的。
若在函数声明时使用了关键字automatic,那么该函数将成为自动的或可递归的.
下例说明如何定义自动函数,来完成阶乘运算:
//用函数的递归调用定义阶乘计算
module top;
.................. //定义自动(递归)函数
function automatic integer factorial;
input [ : ] oper;
begin
if (oper >= )
factorial = factorial( oper - ) * oper;//递归调用
else
factorial=:
end
endfunction integer result;
initial
begin
result = factorial ();
end
endmodule
2 任务(task)
任务(task)定义与调用的格式分别如下:
//任务定义的格式为:
task 任务名 ;
端口及数据类型声明语句;
其他语句;
endtask //任务调用的格式为:
任务名 (端口1,端口2,……)
比如下面是定义一个任务的例子:
//使用任务描述运算单元
module alu(a,b,result);
input[:] a,b;
output[:] result;
wire[:] a,b;
reg[:] result; always@(a, b)
begin
//按照任务中定义的端口顺序调用任务
cal(a,b, result);
end //定义任务cal
task cal;
//任务端口列表
input[:] a;
input[:] b;
output[:] result;
//内部定义局部变量(必须reg型)
reg[:] temp;
begin
temp = a*a;
result = temp-b;
end
endtask
endmodule
任务的定义和module差不多,只不过端口列表中的参数可以是任意数据类型。
使用“disable+任务名”可以提前终止任务的执行。
自动任务
任务在本质上是静态的,任务中的所有声明项的地址空间是静态分配的。因此,如果这个任务在模块中的两个地方被同时调用,则这两个任务调用将对同一块地址空间进行操作。操作的结果很有可能是错误的。
为了避免这个问题,Verilog通过在task关键字前面添加关键字automatic,使任务成为可重入的,这样声明的任务也称为自动任务,每次调用时,在动态任务中声明的所有模块项的存储空间都是动态分配的,每个调用都对各自独立的地址空间进行操作。这样,每个任务调用只对自己所拥有的独立变量副本进行操作.因此可以得到正确的执行结果。
module auto_task;
reg [:] cd_add, ef_add;
reg [:] c, d , e, f;
reg clk1,clk2;
parameter delay=; initial
begin
clk1=; clk2=;
c=;d=;e=;f=;
# c=;d=;e=;f=;
# $stop;
end
initial forever # clk1=~clk1;
initial forever # clk2=~clk2; task automatic adder; // 任务定义
output [: ] ab_adder;
input [: ] a, b;
begin
#delay ab_adder = a + b;
end
endtask always @(posedge clk1)
adder(ef_add,e,f); always @ (posedge clk2)
adder(cd_add, c, d); endmodule
3 任务task与function的区别
不同点:
| 任务 task | 函数 function |
| 通常用于调试,或对硬件进行行为描述 | 通常用于计算,或描述组合逻辑 |
| 可以包含时序控制(#延迟,@, wait) | 不能包含任何延迟;函数仿真时间为0 |
| 可以有 input,output,和inout参数 | 只含有input参数并由函数名返回一个结果 |
| 可以调用其他任务或函数 | 可以调用其他函数,但不能调用任务 |
共同点:
1)任务和函数必须在module内调用
2)在任务和函数中不能声明wire
3)所有输入输出都是局部寄存器
4)任务函数执行完成后才返回结果
4 小结
(1)任务和函数都用来对设计中多处使用的公共代码进行定义,使用任务和函数可以将模块分割成许多个可独立管理的子单元,增强了模块的可读性和可维护性。
(2)任务可以有任意多个输入、输入/输出(inout)和输出变量。在任务中可以使用延迟、事件和时序控制结构,在任务中可以调用其他的任务和函数;
(3)自动任务使用关键字automatic进行定义,它的每一次调用都对不同的地址空间进行操作。因此,在被多次并发调用时仍然可以获得正确的结果;
(4)函数只能有一个返回值,并且至少要有一个输入变量。在函数中不能使用延迟、事件和时序控制结构。在函数可以调用其它函数,但不能调用任务;
(5)当声明函数时,Verilog仿真器都会隐含地声明一个同名的寄存器变量,函数的返回值通过这个寄存器传递回调用处;
(6)递归函数使用关键字automatic进行定义,递归函数每一次调用都拥有不同的地址空间。因此对这种函数的递归调用和并发调用可以得到正确的结果;
(7)任务和函数都包含在设计层次中,可以通过层次名对它们进行调用。
【FPGA篇章五】FPGA函数任务:对讲解函数与任务专题展开详解的更多相关文章
- Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量
Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量 一丶线程的理论知识 什么是线程: 1.线程是一堆指令,是操作系统调度 ...
- 《手把手教你》系列技巧篇(四十五)-java+ selenium自动化测试-web页面定位toast-上篇(详解教程)
1.简介 在使用appium写app自动化的时候介绍toast的相关元素的定位,在Web UI测试过程中,也经常遇到一些toast,那么这个toast我们这边如何进行测试呢?今天宏哥就分两篇介绍一下. ...
- Java进阶篇之十五 ----- JDK1.8的Lambda、Stream和日期的使用详解(很详细)
前言 本篇主要讲述是Java中JDK1.8的一些新语法特性使用,主要是Lambda.Stream和LocalDate日期的一些使用讲解. Lambda Lambda介绍 Lambda 表达式(lamb ...
- python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解
1.前言 Python的描述符是接触到Python核心编程中一个比较难以理解的内容,自己在学习的过程中也遇到过很多的疑惑,通过google和阅读源码,现将自己的理解和心得记录下来,也为正在为了该问题 ...
- (转)Python内置函数进阶之“属性(property())”详解
原文:https://blog.csdn.net/GeekLeee/article/details/78519767 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.c ...
- [转]五分钟看懂UML类图与类的关系详解
在画类图的时候,理清类和类之间的关系是重点.类的关系有泛化(Generalization).实现(Realization).依赖(Dependency)和关联(Association).其中关联又分为 ...
- 五分钟看懂UML类图与类的关系详解
在画类图的时候,理清类和类之间的关系是重点.类的关系有泛化(Generalization).实现(Realization).依赖(Dependency)和关联(Association).其中关联又分为 ...
- 第五周-磁盘分区GPT、shell脚本练习、lvm详解
1. 描述GPT是什么,应该怎么使用 Linux中磁盘分区分为MBR和GPT. MBR全称为Master Boot Record,为主引导记录,是传统的分区机制,应用于绝大多数使用的BIOS的PC设备 ...
- Servlet第五篇【介绍会话技术、Cookie的API、详解、应用】
什么是会话技术 基本概念: 指用户开一个浏览器,访问一个网站,只要不关闭该浏览器,不管该用户点击多少个超链接,访问多少资源,直到用户关闭浏览器,整个这个过程我们称为一次会话. 为什么我们要使用会话技术 ...
随机推荐
- GeiGebra指令
- PHP安全(文件包含、变量覆盖、代码执行)
文件包含漏洞 本地文件包含 截断技巧: ../../etc/passwd%00(\x00 \0) 利用操作系统对目录最大长度的限制,可以不需要0字节而达到截断的目的.目录字符串,在windows下25 ...
- I - Fill The Bag codeforces 1303D
题解:注意这里的数组a中的元素,全部都是2的整数幂.然后有二进制可以拼成任意数.只要一堆2的整数幂的和大于x,x也是2的整数幂,那么那一堆2的整数幂一定可以组成x. 思路:位运算,对每一位,如果该位置 ...
- 基础_TCP/IP
概念明确: 1:TCP/IP代表传输控制协议/网际协议,指的是一系列协议 为什么会叫TCP/IP.因为用的多, 2:HTTP 是属于应用层的协议 3:OSI七层模型和TCP/IP 平等,只是TCP/ ...
- mysql 更改默认字符集
mysql 默认字符集概述 首先,MySQL的字符集问题主要是两个概念: haracter Sets Collations 前者是字符内容及编码,后者是对前者进行比较操作的一些规则.这两个参数集可以在 ...
- Java中集合的初等案例
我有五个学生,请把这个学生的信息储存到数组中,并遍历数组,获取得到每一个学生信息. 学生:Strdent 成员变量:name,age 构造方法:无参,带参 成员方法:getXxx()/setXxx() ...
- python 给字典按值排序,同样适合于其他
sorted_items = sorted(dico.items(),key=lambda x:(-x[1],x[0]))
- 天池Docker学习赛笔记
容器的基本概念 什么是容器? 容器就是一个视图隔离.资源可限制.独立文件系统的进程集合.所谓"视图隔离"就是能够看到部分进程以及具有独立的主机名等:控制资源使用率则是可以对于内存大 ...
- appium同时运行两台真机
执行命令: appium -p 4494 -bp 2253 -U GWY0217207001793 appium -p 4493 -bp 2252 -U 77fdaabc server 设置:http ...
- 前端开发--ajax
使用ajax,他是有两个模块的,一个是客户端,一个是服务端. 客户端负责发送数据,发送数据的方式有两种,一种是GET,另一种是POST. 服务端是用来接收,处理数据和发送请求的数据. 要想使用ajax ...