欢迎大家关注我的微信公众账号,支持程序媛写出更多优秀的文章

任务和函数也属于过程块,多用于仿真文件设计中,使用两者的目的有所区别:

函数(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函数任务:对讲解函数与任务专题展开详解的更多相关文章

  1. Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量

    Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量 一丶线程的理论知识 什么是线程:    1.线程是一堆指令,是操作系统调度 ...

  2. 《手把手教你》系列技巧篇(四十五)-java+ selenium自动化测试-web页面定位toast-上篇(详解教程)

    1.简介 在使用appium写app自动化的时候介绍toast的相关元素的定位,在Web UI测试过程中,也经常遇到一些toast,那么这个toast我们这边如何进行测试呢?今天宏哥就分两篇介绍一下. ...

  3. Java进阶篇之十五 ----- JDK1.8的Lambda、Stream和日期的使用详解(很详细)

    前言 本篇主要讲述是Java中JDK1.8的一些新语法特性使用,主要是Lambda.Stream和LocalDate日期的一些使用讲解. Lambda Lambda介绍 Lambda 表达式(lamb ...

  4. python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解

     1.前言 Python的描述符是接触到Python核心编程中一个比较难以理解的内容,自己在学习的过程中也遇到过很多的疑惑,通过google和阅读源码,现将自己的理解和心得记录下来,也为正在为了该问题 ...

  5. (转)Python内置函数进阶之“属性(property())”详解

    原文:https://blog.csdn.net/GeekLeee/article/details/78519767 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.c ...

  6. [转]五分钟看懂UML类图与类的关系详解

    在画类图的时候,理清类和类之间的关系是重点.类的关系有泛化(Generalization).实现(Realization).依赖(Dependency)和关联(Association).其中关联又分为 ...

  7. 五分钟看懂UML类图与类的关系详解

    在画类图的时候,理清类和类之间的关系是重点.类的关系有泛化(Generalization).实现(Realization).依赖(Dependency)和关联(Association).其中关联又分为 ...

  8. 第五周-磁盘分区GPT、shell脚本练习、lvm详解

    1. 描述GPT是什么,应该怎么使用 Linux中磁盘分区分为MBR和GPT. MBR全称为Master Boot Record,为主引导记录,是传统的分区机制,应用于绝大多数使用的BIOS的PC设备 ...

  9. Servlet第五篇【介绍会话技术、Cookie的API、详解、应用】

    什么是会话技术 基本概念: 指用户开一个浏览器,访问一个网站,只要不关闭该浏览器,不管该用户点击多少个超链接,访问多少资源,直到用户关闭浏览器,整个这个过程我们称为一次会话. 为什么我们要使用会话技术 ...

随机推荐

  1. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(四)之Operators

    At the lowest level, data in Java is manipulated using operators Using Java Operators An operator ta ...

  2. 常用Linux命令的基本使用

    01.常用Linux命令的基本使用 序号 命令 对应英文 作用 01 ls list 查看当前文件夹下的内容 02 pwd print work directory 查看当前所在文件夹 03 cd [ ...

  3. stand up meeting 12-10

    今天项目会议正好利用了大家上课前的十五分钟,大家对项目进度和项目中所遇到的问题进行了沟通. 由于天赋同学与重阳小组沟通及时有效,在mapping的过程中直接将单词本中的type与我们单词挑战中的que ...

  4. Bi-shoe and Phi-shoe LightOJ - 1370

    欧拉函数. 欧拉函数打表模板: #define maxn 3000010 int p[maxn]; void oula(){ int i,j; ; i<=maxn; i++) p[i]=i; ; ...

  5. Springboot:静态资源加载(七)

    WebMvc自动配置: 搜索WebMvcAutoConfiguration自动装配类: 第一种方式通过webjars加载静态资源: https://www.webjars.org(通过maven加载依 ...

  6. Java中常量的概念

    常量:在程序执行过程中,其值不发生改变的量.分类:A:字面值常量B:自定义常量字面值常量A:字符串常量(用“”括起来的内容).举例:"hello"B:整数常量 (所有的整数)举例: ...

  7. Mac安装多版本JDK

    0. 配置JDK环境 安装完成之后,配置.bash_profile文件 使用source ./bash_profile激活 2. 如何切换默认的jdk? 使用java -version就可以看默认版本 ...

  8. qt 怎么让程序自带字体,就是说在操作系统上没有的字体

    字体要加到.qrc文件中 QString Widget::loadFontFamilyFromTTF() { static QString font; static bool loaded = fal ...

  9. Debugging Under Unix: gdb Tutorial (https://www.cs.cmu.edu/~gilpin/tutorial/)

    //注释掉 #include <iostream.h> //替换为 #include <iostream> using namespace std; Contents Intr ...

  10. Nodejs的介绍

    Nodejs的介绍 Node.js的是建立在Chrome的JavaScript的运行时,可方便地构建快速,可扩展的网络应用程序的平台.Node.js使用事件驱动,非阻塞I/O模型,轻量.高效,可以完美 ...