SystemVerilog学习笔记(七):函数与任务

函数

函数的主要用途是编写一段可以随时调用n次的代码,只需调用函数名即可,不需要任何模拟时间来执行。函数是返回类型,仅返回函数声明中提到的单个值,如果未声明则返回一个位的值。

语法:

initial  
begin function_name(arguments); 
endfunction <return_type(optional)> function_name(arguments);`statement1;statement2;. .  statementN;
endfunction 

限制:

  • 函数内部的代码中不允许有#、@、wait等耗时语句
  • 只能返回一个值
  • 无法从函数中调用任务,因为任务允许有耗时的语句

调用函数有很多变体:

  • 调用以值作为参数的函数
  • 调用以变量作为参数的函数
  • 使用表达式中的值调用函数
  • C使用带位置参数的变量调用函数
  • 调用自动函数
  • 通过变量的引用调用带有变量的函数
  • 调用返回类型为 void 的函数
  • 通过传递数组来调用函数
  • 调用具有默认值的变量的函数
  • 从函数调用任务(使用 fork 和 join_none 的例外情况)

调用以值作为参数的函数

示例:

          int result;  initial  begin  result=sum(5,6);  $display("\treturned from function and");  $display("\tstored the value of sum in result");    $display("\n\t@ %0t ns, value of sum is %0d",$time,result);     end  function int sum(int var1,var2);    $display("entered into function");   return var1+var2;  endfunction   

在上面的示例中,函数名称是 sum,其返回类型为 int,即它仅返回一个 int 值。

流程图:

01 (1)

调用以变量作为参数的函数

示例:

          int result,a=5,b=6;    initial  begin  $display("\tcalling the function");  result=sum(a,b);  $display("\treturned from function and");  $display("\tstored the value of sum in result");  $display("\n\t@ %0t ns, value of sum is %0d",$time,result);    end function int sum(input int a,b);  $display("entered into function");   return a+b;  endfunction  

流程图:

02

使用表达式中的值调用函数

示例:

          initial  begin   $display("\n\t@ %0t ns, value of sum is %0d",$time,sum(5,6));    end  function int sum(int var1,var2);  $display("entered into function");   return var1+var2;  endfunction  

使用带位置参数的变量调用函数

示例:

          initial  begin   result=sum(.var1(5),.var2(6));  $display("\treturned from function and");  $display("\tstored the value of sum in result");  $display("\n\t@ %0t ns, value of sum is %0d",$time,result);      end  function int sum(int var1,var2); $display("entered into function");   return var1+var2;  endfunction  

调用自动函数

语法:

function automatic function_name(arguments);

示例:

          module func_automatic();int result1,result2;function int factorial_static(int var1);if(var1>=2)result1=factorial_static(var1-1)*var1;elsebeginresult1=1;endreturn result1;endfunctionfunction automatic int factorial_automatic(int var1);if(var1>=2)result2=factorial_automatic(var1-1)*var1;elsebeginresult2=1;endreturn result2;endfunctioninitialbeginresult1=factorial_static(5);result2=factorial_automatic(5);$display("factorial_static:%0d",result1);$display("factorial_automatic:%0d",result2);endendmodule: func_automatic  

这里我们使用带有 automatic 关键字的函数,这意味着每当调用该函数时都会创建新的内存,而在 static 中,每当调用该函数时都会使用相同的内存。

通过变量的引用调用带有变量的函数

语法:

function automatic data_type function_name(ref arguments);

流程图:

03

示例:

          int result,addend,augend;  initial  begin   addend=5;  augend=6;  $display("\tBefore calling function -> addend = %0d , augend = %0d",addend,augend);  $display("\tcalling the functions");  result=sum_without_ref(addend,augend);  $display("\tafter calling function without ref -> addend = %0d, augend =%0d",addend,augend);  result=sum_with_ref(addend,augend);  $display("\tafter calling function with ref -> addend = %0d, augend =%0d",addend,augend);  end  function automatic int sum_with_ref(ref int var1,var2);  int temp;  $display("\n\tentered into with ref function");  temp=var1;  var1=var2;  var2=temp;  $display("\tswapped variables by using ref ");  return var1+var2;  endfunction : sum_with_ref  function int sum_without_ref(input int var1,var2);  int temp;  $display("\n\tentered into without ref function");  temp=var1;  var1=var2;  var2=temp;  $display("\tswapped variables by without using ref ");  return var1+var2;  endfunction : sum_without_ref  

当通过传递变量引用来调用函数时,需要提及关键字 automatic 和 ref,如上例所示。

调用返回类型为 void 的函数

语法:

//type casting  
void'(function_name(arguments));

或者

//declaring the function as void type which doesn't return any value.   
function void function_name(arguments);

示例:

          initial  begin  display("\t ----output for function void return type-----");  display("\t passing string to function for displaying");  end  function void display(string str);  $display("%s",str);    endfunction: display  

通过传递数组来调用函数

语法:

data_type array_name[size]; 
function automatic return_type function_name(ref data_type array_name);  

示例:

          int array[5];  void'(fun_arr(array));  $display("\treturned from function");  $display("\n\t@ %0t ns, Array elements = %0p",$time,array);  end  function automatic int fun_arr(ref int arr[5]);  $display("\tEntered the function");  foreach(arr[i])begin  arr[i]=i+1;  end  $display("\t values assigned to array elements starts from 1");  return 0;  endfunction  

一般来说,我们不能从函数返回数组,但可以使用引用传递来传递数组,并且可以在函数中操作该数组。

调用具有默认值的变量的函数

语法:

function_name()
function <return_type> function_name(varable1=deafult_value,variable2=default_value)

示例:

          initialbegin$display("\t ----output for function passing by values through variables-----");$display("\tcalling the function");result=sum();$display("\treturned from function and");$display("\tstored the value of sum in result");$display("\n\t@ %0t ns, value of sum is %0d",$time,result);endfunction int sum(input int var1=2,var2=3);$display("\n\tentered into function ");return var1+var2;endfunction: sum

在此示例中,调用函数但不传递任何值或变量,那么在这种情况下,函数所需的两个变量将采用分配给它们的默认值,即在本例中为 2 & 3 得出的总和为 5。

如果调用函数时没有值和变量,并且函数没有任何默认值,则模拟器将抛出错误。

从函数调用任务

一般来说,从函数调用任务是非法的,编译器会报错,但有一种特殊情况,可以使用 fork join_none 从函数调用任务,如下例所示。

示例:

          initial  begin$display("\t@ %0t ns, In the initial block",$time);  $display("\tcalling function");  #1 void'(function_call);  end  function function_call;  fork  $display( "\t@ %0t ns I'm in function",$time);  $display("\t@ %0t ns, calling task from func",$time);  task_call;  join_none  endfunction  task task_call;  #1 $display( "\t@ %0t ns , I'm in task",$time);  #1 $display("\t@ %0t ns,leaving from task",$time);  endtask  

流程图:

05

任务

任务(task)与函数类似,但任务可以计算多个变量并使用输出或 inout 语句返回它们,但不像函数那样必需,即任务不是返回类型,并且任务能够具有诸如 #、@、等待。任务也可以调用另一个任务和函数。

语法:

task_name(arguments); task task_name(arguments); 
statement1; 
statement2; 
. 
.  
statementN;  
endtask  

限制:

  • 任务不可综合

流程图

01

automatic task

每当声明为 automatic task 时,每次调用该任务时,模拟器都会分配新的内存。一般来说,任务在模块内部是静态的,要使其自动执行,需要添加 automatic 关键字,如下所示。

语法:

task automatic task_name()

示例:

         task automatic factorial_automatic(int var1);#1;if(var1>=2)beginfactorial_automatic(var1-1);result=result*var1;endelsebeginresult=1;->a;endendtaskinitialbeginforkfactorial_static(5);factorial_automatic(5);joinforkwait(a.triggered);$display("@ %0t ns , factorial_automatic:%0d",$time,result);end

流程图:

02

从任务中调用函数

示例:

       initialbegin$display("\t ----output for func from task----");$display("\t@ %0t ns, In the initial block",$time);$display("\tcalling task");task_sum;$display("\treturned to initial from function");end  task task_sum;#1 $display( "\t@ %0t ns , I'm in task",$time);$display("\tcalling func inside a task");#1 void'(function_sum);$display("\treturned to task from function");endtaskfunction function_sum;$display( "\t@ %0t ns I'm in function",$time);endfunction

从函数中调用任务是非法的,但从任务中调用 func 是正常的,因为函数没有任何耗时的语句。

流程图:

03

全局任务

如果一个任务是在模​​块和类之外声明的,则该任务被称为全局任务,默认的全局任务本质上是静态的。该全局任务可以从任何模块调用,通过以下示例可以更好地理解。

示例:

     task mul(input int var1,var2,output int res);#1 res=var1*var2;endtaskmodule task1();int multiplicand=5,multiplicator=6,result;initialbegin$display("\t ----output of global task----");mul(multiplicand,multiplicator,result);$display("\t @ %0t ns , %0d X %0d = %0d",$time,multiplicand,multiplicator,result);endendmodulemodule task2();int r;initialbegin#2 mul(7,8,r);$display("\t @ %0t ns , 7 X 8 = %0d",$time,r);endendmodule

禁用任务

可以通过在任务名称中使用关键字 disable 来禁用任务,这会在调用禁用时停止该特定任务。

示例:

      module disable_task();initialbegin$display("\t ----output of disable task----");forkdisplay_task();#20 disable display_task.task_A;joinendtask display_task();begin : task_A$display("\t @ %0t ns , task_A initiated",$time);#30 $display("\t @ %0t ns , task_A finished",$time);end :task_Abegin : task_B$display("\t @ %0t ns , task_B initiated",$time);#10 $display("\t @ %0t ns , task_B finished",$time);end :task_Bendtaskendmodule

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/885665.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

物理验证Calibre LVS | SMIC Process过LVS时VNW和VPW要如何做处理?

SMIC家工艺的数字后端实现PR chipfinish写出来的带PG netlist如下图所示。我们可以看到标准单元没有VNW和VPW pin的逻辑连接关系。 前几天小编在社区星球上分享了T12nm ananke_core CPU低功耗设计项目的Calibre LVS案例&#xff0c;就是关于标准单元VPP和VBB的连接问题。 目前…

纯前端实现在线预览excel文件(插件: LuckyExcel、Luckysheet)

概述 在实际开发中&#xff0c;遇到需要在线预览各种文件的需求&#xff0c;最近遇到在线预览excel文件的需求&#xff0c;在此记录一下&#xff01;本文主要功能实现&#xff0c;用于插件 LuckyExcel &#xff0c;Luckysheet&#xff01;废话不多说&#xff0c;上代码&#xf…

LocalDate和LocalDateTime类

在Java 8中引入的LocalDate表示一个格式为yyyy-MM-dd的日期&#xff0c;如2024-06-13。它不存储时间或时区。我们可以从LocalDate中获取许多其他的日期字段&#xff0c;如年日(day-of-year)、周日(day-of-week)、月日(month-of-year)等等。 1 初始化 LocalDate以年月日的格式输…

信息安全工程师(82)操作系统安全概述

一、操作系统安全的概念 操作系统安全是指操作系统在基本功能的基础上增加了安全机制与措施&#xff0c;从而满足安全策略要求&#xff0c;具有相应的安全功能&#xff0c;并符合特定的安全标准。在一定约束条件下&#xff0c;操作系统安全能够抵御常见的网络安全威胁&#xff…

小程序源码-模版 100多套小程序(附源码)

一、搭建开发环境 搭建环境可以从这里开始&#xff1a; 微信小程序从零开始开发步骤&#xff08;一&#xff09;搭建开发环境 - 简书 二、程序示例 1、AppleMusic https://download.csdn.net/download/m0_54925305/89977187 2、仿B站首页 https://download.csdn.net/downlo…

安装baidubce库

直接pip install baidubce会带来一系列后续文件缺失问题&#xff0c;应该&#xff1a; pip install bce-python-sdk

【Java】-- 异常

1. 异常的概念与体系结构 1.1 异常的概念 在Java中&#xff0c;将程序执行过程中发生的不正常行为称为异常。 public class Test {public static void main(String[] args) {//算术&#xff08;ArithmeticException&#xff09;异常 // int a 5/0; // System.…

从零开始:利用Portainer CE和cpolar搭建NextCloud私有云存储

文章目录 前言1. 在PortainerCE中创建NextCloud容器2. 公网远程访问本地NextCloud容器2.1 内网穿透工具安装3.2 创建远程连接公网地址 3. 固定NextCloud私有云盘公网地址 前言 本文将介绍如何在本地利用Portainer CE的可视化界面创建NextCloud私有云盘容器&#xff0c;并通过c…

[安洵杯 2019]easy_web 详细题解

知识点: 编码转换 命令执行 linux空格_关键字绕过 打开页面 发现url 是 /index.php?imgTXpVek5UTTFNbVUzTURabE5qYz0&cmd 有img参数和cmd参数 cmd参数是没赋值的,随便赋值为123456 页面没有反应 鼠标移动到图片下面时发现有东西,当然直接查看页面源代码也可以发现 尝…

第2章 数据的表示和运算

王道学习 考纲内容 &#xff08;一&#xff09;数制与编码 进位计数制及其相互转换&#xff1b;定点数的编码表示 &#xff08;二&#xff09;运算方法和运算电路 基本运算部件&#xff1a;加法器&#xff1b;算术逻辑单元&#xff08;ALU&#xff09;…

Web3 游戏周报(11.03 - 11.09)

回顾上周的区块链游戏概况&#xff0c;查看 Footprint Analytics 与 ABGA 最新发布的数据报告。 【11.03 - 11.09】Web3 游戏行业动态&#xff1a; Ton Accelerator 推出名为「Synergy」的 500 万美元计划&#xff0c;旨在推动跨链创新&#xff0c;创造 TON 用户与 EVM 网络适应…

数据分析:16s差异分析DESeq2 | Corncob | MaAsLin2 | ALDEx2

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍DESeq2原理计算步骤结果Corncob原理计算步骤结果MaAsLin2原理计算步骤结果ALDEx2原理计算步骤结果加载R包数据链接数据预处理微生物数据样本信息提取物种名称过滤零值保留结果读取…

H.264/H.265播放器EasyPlayer.js无插件H5播放器关于WASM的压缩优化

在当今的Web开发领域&#xff0c;流媒体播放器的性能和效率至关重要&#xff0c;尤其是在处理大型视频文件和高分辨率视频流时。EasyPlayer.js RTSP播放器作为一款先进的流媒体播放器&#xff0c;它在WebAssembly&#xff08;WASM&#xff09;的压缩优化方面表现出色&#xff0…

使用 Python 从 REST URL 下载文件

使用 Python 从 REST URL 下载文件&#xff0c;可以使用 requests 库来简化文件的下载和保存过程。以下是一个示例代码&#xff0c;展示了如何从给定的 REST API 或 URL 下载文件并保存到本地。 1、问题背景 我们需要编写一个脚本&#xff0c;从一个支持 REST URL 的网站下载一…

SpringMVC学习记录(三)之响应数据

SpringMVC学习记录&#xff08;三&#xff09;之响应数据 一、页面跳转控制1、快速返回模板视图2、转发和重定向 二、返回JSON数据1、前置准备2、ResponseBody 三、返回静态资源1、静态资源概念2、访问静态资源 /*** TODO: 一个controller的方法是控制层的一个处理器,我们称为h…

CSDN做样板,教我们如何为新网站引流

CSDN为我们做了个很好的例子&#xff0c;详细请看下图 亮点分析&#xff1a; 1. 未采用硬广在网站上进行引流。减少了给用户在直觉上的造成的反感&#xff1b; 2. 在GitHub的转跳页面中&#xff0c;植入额外的关联网站链接。虽然对用户解决问题没啥鸟用&#xff0c;但是人家能…

什么是头皮EA(剥头皮EA)?

在许多外汇交易者的眼中&#xff0c;剥头皮交易一直是一个神秘的存在。一部分人认为它是一种“外汇禁招”&#xff0c;而另一部分人则认为它比日内交易更容易盈利。那么&#xff0c;外汇剥头皮到底是什么&#xff1f;它与点差之间又有怎样的关系&#xff1f;本文将对剥头皮交易…

华为ensp防火墙配置(纯享版)

文章目录 前言一、拓扑结构二、配置步骤1.路由器配置&#xff08;路由器代替互联网&#xff09;2.server和pc配置3.防护墙配置4.测试 总结 前言 防火墙是生活和项目中不可或缺的一部分&#xff0c;本篇文章对华为的ensp防火墙配置做一个总结。在之前的dhcp配置中有软件的下载地…

区块链技术在数字版权管理中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 区块链技术在数字版权管理中的应用 区块链技术在数字版权管理中的应用 区块链技术在数字版权管理中的应用 引言 区块链技术概述 …

docker 拉取MySQL8.0镜像以及安装

目录 一、docker安装MySQL镜像 搜索images 拉取MySQL镜像 二、数据挂载 在/root/mysql/conf中创建 *.cnf 文件 创建容器,将数据,日志,配置文件映射到本机 检查MySQL是否启动成功&#xff1a; 三、DBeaver数据库连接 问题一、Public Key Retrieval is not allowed 问题…