08-任务Task和函数Function
任务Task和函数Function
类似于c语言中的函数
Task
- task 含有input\output\inout语句
- task消耗仿真时间
task中可以写延迟:#20 延迟20个仿真时间单位
时钟周期 @(posedge Clk) 等待下一个时钟周期上升沿
事件 @event 等待某一个事件被触发
task task_name;
begin
paramters
input
output
reg
...
end
endtask
function
- function是不消耗仿真时间的,其中没有等待和延迟
- function中不能有控制仿真时间的语句:@和#
- function是不能调用task的,因为function不能控制时间
- void function空函数,没有返回值
function [range] function_name;
begin
parameters; //range范围表示function返回值的
input;
reg;
end
endfunction
- SV中task和function中不需要使用begin end
task reset();
reset_l = 1'b0;
#100
reset_l = 1'b1; // 电平什么时候拉高和什么时候拉低需要有时间单位
endtask
function add2(int n);
n+2;
endfunction
传递参数
通过名字传递参数
- verilog通过形式参数的名字传递参数,减少错误
- 参数的顺序不受限制
- 传递参数的语法与verilog端口连接的方式相同
functon int divide(input int numerator,denominator);
if(denominator == 0) begin
return 0;
end
else
return numerator/denominator;
endfunction
always_ff@(posedge Clk) begin
result <= divide(b,a); //传递参数的顺序与定义的参数顺序相同
end
- 这种传递参数的方式,如果参数校多,就会分不清楚实参和形参的对应关系
- 采用 .形参名(实参) 的形式进行传参
always_ff @(posedge Clk)
result <= divide(.denominator(b),.numerator(a));
- 这种传递参数的方式可以与定义参数的顺序不同
形式参数的默认方向和类型
- 每个形式参数可以给一个默认值
- 调用task和function时不传递参数就会使用默认值
function int increment(int count=0,step=1);
increment = count+step;
endfunction
always_ff @(posedge clock)
result = increment(data_bus);//只传入一个参数,第二个使用默认参数
参数的传递方式
常见任务task和函数function传递参数值的方法时复制,传递参数的时候,是将实参复制一份传递给形参,两者指向不同内存存储的变量,函数体内进行操作的时候,不会影响原有的实参
- 参数传递默认情况下跟左侧的参数类型保持一致
function int increment(int count=0,step=1); //step的数据类型与count一致都是int,默认与左边一致
- input-- 默认情况下,在开始的时候复制实参给形参
- output--结束的时候,将输出的值复制一份给返回位置
- inout--开始输入的时候,在结束时输出,一份复制的数值
task和function阻塞情况
- task是没有返回值的
- function会将执行结果返回到调用位置
// 使用递归的方式计算n的阶乘
task print_sum(integer a[],input start=0);
automatic int sum = 0;
for(int j = start;j<a.size();j++)
sum += a[j];
$display("sum of the array is %0d",sum);//%0d的意思是将变量的数值,以前面不含0的十进制数的形式打印
endtask
print_sum(my_array)
function int factorial(int n);
int share_value = 0;
if(n=2) return (1);
else return (n*factorial(n-1));
endfunction
Result = factorial(my_value)
- Task消耗时间,可以阻塞
- Functions不能阻塞
参数传递是具有粘连性的
输入参数的数据类型与左边的保持一致
Verilog系统函数
系统函数都是以$符号开头的
- $random
可以使用$random或者使用$random(seed)
int a;
initial begin
a = $random(20);//随机种子默认值为0,可以更改为别的数
$display("a = %d",a)
end
- $urandom()产生32bit的无符号数
int a;
initial begin
a = $urandom(20);// a定义的int是有符号数,虽然随机数产生的是无符号数,但是赋值之后a仍然为有符号数
$display("a = %d",a)
end
$urandom_range(min,max) 产生一定范围内的无符号随机数
代码的生命周期
代码是有生命周期的
function int adder;
int a; // 函数内部定义的a 和在module定义的a所占用的内存空间是不同的,函数执行结束后会自动销毁
a = a+1;
endfunction
int a;
initial begin
a = adder();
$display("a = %d",a);
end
- 当遇到endfunction,endtask,return的时候,会结束task和function,销毁其中的变量
- 循环语句遇到end或者break的时候,结束循环
08-任务Task和函数Function的更多相关文章
- JavaScript入门-函数function(二)
JavaScript入门-函数function(二) 递归函数 什么是递归函数? 递归简单理解就是,在函数体里,调用自己. //我们在求一个10的阶乘的时候,可能会这么做 //写一个循环 var to ...
- Javascript自执行匿名函数(function() { })()的原理分析
匿名函数指没有指定函数名或指针的函数,自执行匿名函数只是其中一种,下文中称这种函数为:自执行函数 下面是一个最常见的自执行函数: // 传统匿名函数 (function() { alert('hell ...
- JavaScript自运行函数(function(){})()的理解
今天打开JQuery源文件(jquery-1.8.3), 看到JQuery的初始化过程是这样的 (function( window, undefined ) { // .... })( window ...
- 深入理解javascript中的立即执行函数(function(){…})()
投稿:junjie 字体:[增加 减小] 类型:转载 时间:2014-06-12 我要评论 这篇文章主要介绍了深入理解javascript中的立即执行函数,立即执行函数也叫立即调用函数,通常它的写法是 ...
- javaScript的函数(Function)对象的声明(@包括函数声明和函数表达式)
写作缘由: 平时再用js写函数的时候,一般都是以惯例 function fn () {} 的方式来声明一个函数,在阅读一些优秀插件的时候又不免见到 var fn = function () {} 这种 ...
- 函数(Function)作用域 / 远程函数执行
函数跟变量一样也是有作用域的:Global.Script.Local.Private Global:作用于整个PowerShell会话,只要PowerShell会话不结束,被Global修饰的变量和函 ...
- Javascript自执行匿名函数(function() { })()的原理浅析
匿名函数就是没有函数名的函数.这篇文章主要介绍了Javascript自执行匿名函数(function() { })()的原理浅析的相关资料,需要的朋友可以参考下 函数是JavaScript中最灵活的一 ...
- Javascript学习之函数(function)
在JS中,Function(函数)类型实际上是对象;每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法.由于函数是对象,因此函数名实际上也是一个指向函数对象的指针. 一 函 ...
- js立即执行函数: (function ( ){...})( ) 与 (function ( ){...}( ))
( function(){…} )() ( function (){…} () ) 是两种javascript立即执行函数的常见写法,最初我以为是一个括号包裹匿名函数,再在后面加个括号调用函数,最后达 ...
- 深入理解立即执行函数(function(){})();
( function(){-} )()和( function (){-} () )是两种javascript立即执行函数的常见写法,要理解立即执行函数,需要先理解一些函数的基本概念. 1,函数声明,函 ...
随机推荐
- C++ Qt开发:Charts绘图组件概述
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍QCharts ...
- k8s~动态生成pvc和pv
有时,我们不想手动建立pv和pvc,这时,我们可以通过strongClass存储类来帮我们实现,动态建立pvc,并动态为它分配pv存储空间,我们以nfs为例,说一下动态分配在nfs存储截至上建立pv的 ...
- 痞子衡嵌入式:在i.MXRT1170上快速点亮一款全新LCD屏的方法与步骤(MIPI DSI接口)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在i.MXRT1170上快速点亮一款全新LCD屏的方法与步骤. 我们知道 LCD 屏的接口有很多:DPI-RGB.MIPI DSI.DB ...
- python异步编程之asyncio高阶API
asyncio 高阶API列表 asyncio中函数可以分为高阶函数和低阶函数.低阶函数用于调用事件循环.linux 套接字.信号等更底层的功能,高阶函数是屏蔽了更多底层细节的任务并发,任务执行函数. ...
- HTTP 代理服务器的设计与实现(C++)
实验内容 设计并实现一个基本 HTTP 代理服务器.要求在指定端口(例如 8080)接收来自客户的 HTTP 请求并且根据其中的 URL 地址访问该地址 所指向的 HTTP 服务器(原服务器),接收 ...
- Asp .Net Core 系列:基于 Swashbuckle.AspNetCore 包 集成 Swagger
什么是 Swagger? Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.它提供了一种规范的方式来定义.构建和文档化 RESTful Web ...
- PLG SaaS 案例:如何实践外链自动增长策略?
首先任何的商业逻辑,光流量增长,没法变现是没用的. 就像博客群发提效工具,得有对应的用户,更得有对应付费用户群体的画像.剩下的就是靠增长,被动让他们找到你的产品,用产品解决他们痛点,他们自然而然会付费 ...
- 618狂欢结束,来聊聊华为云GaussDB NoSQL的蓬勃张力
又到了一年一度的 618大促的时候,随着近十年网上购物的兴起,各大平台在不同的时期推出各种购物促销活动,极大的促进了消费,刺激了市场.同样,在科技领域,为了支撑突然而来的高并发,支持千万人同时在线浏览 ...
- GaussDB技术解读丨数据库迁移创新实践
本文分享自华为云社区<DTCC 2023专家解读丨GaussDB技术解读系列之数据库迁移创新实践>,作者:GaussDB 数据库. 近日,以"数智赋能 共筑未来"为主题 ...
- 面试官让列举Spring的事务会失效的场景,我说了8个
本文分享自华为云社区<哪些场景下Spring的事务会失效?>,作者:冰 河 . 在日常工作中,如果对Spring的事务管理功能使用不当,则会造成Spring事务不生效的问题.而针对Spri ...