【Verilog 教程】6.2Verilog任务

关键词:任务
任务与函数的区别

和函数一样,任务(task)可以用来描述共同的代码段,并在模块内任意位置被调用,让代码更加的直观易读。函数一般用于组合逻辑的各种转换和计算,而任务更像一个过程,不仅能完成函数的功能,还可以包含时序控制逻辑。下面对任务与函数的区别进行概括:
在这里插入图片描述
任务
任务声明

任务在模块中任意位置定义,并在模块内任意位置引用,作用范围也局限于此模块。

模块内子程序出现下面任意一个条件时,则必须使用任务而不能使用函数。

1)子程序中包含时序控制逻辑,例如延迟,事件控制等
2)没有输入变量
3)没有输出或输出端的数量大于 1
Verilog 任务声明格式如下:

task       task_id ;port_declaration ;procedural_statement ;
endtask

任务中使用关键字 input、output 和 inout 对端口进行声明。input 、inout 型端口将变量从任务外部传递到内部,output、inout 型端口将任务执行完毕时的结果传回到外部。

进行任务的逻辑设计时,可以把 input 声明的端口变量看做 wire 型,把 output 声明的端口变量看做 reg 型。但是不需要用 reg 对 output 端口再次说明。

对 output 信号赋值时也不要用关键字 assign。为避免时序错乱,建议 output 信号采用阻塞赋值。

例如,一个带延时的异或功能 task 描述如下:

task xor_oper_iner;input [N-1:0]   numa;input [N-1:0]   numb;output [N-1:0]  numco ;//output reg [N-1:0]  numco ; //无需再注明 reg 类型,虽然注明也可能没错#3  numco = numa ^ numb ;//assign #3 numco = numa ^ numb ; //不用assign,因为输出默认是reg
endtask

任务在声明时,也可以在任务名后面加一个括号,将端口声明包起来。

上述设计可以更改为:

task xor_oper_iner(input [N-1:0]   numa,input [N-1:0]   numb,output [N-1:0]  numco  ) ; #3  numco       = numa ^ numb ;
endtask

任务调用

任务可单独作为一条语句出现在 initial 或 always 块中,调用格式如下:

task_id(input1, input2, …,outpu1, output2, …);

任务调用时,端口必须按顺序对应。

输入端连接的模块内信号可以是 wire 型,也可以是 reg 型。输出端连接的模块内信号要求一定是 reg 型,这点需要注意。

对上述异或功能的 task 进行一个调用,完成对异或结果的缓存。

module xor_oper#(parameter         N = 4)(input             clk ,input             rstn ,input [N-1:0]     a ,input [N-1:0]     b ,output [N-1:0]    co  );reg [N-1:0]          co_t ;always @(*) begin          //任务调用xor_oper_iner(a, b, co_t);endreg [N-1:0]          co_r ;always @(posedge clk or negedge rstn) beginif (!rstn) beginco_r   <= 'b0 ;endelse beginco_r   <= co_t ;         //数据缓存endendassign       co = co_r ;/*------------ task -------*/task xor_oper_iner;input [N-1:0]   numa;input [N-1:0]   numb;output [N-1:0]  numco ;#3  numco       = numa ^ numb ;   //阻塞赋值,易于控制时序endtaskendmodule

对上述异或功能设计进行简单的仿真,testbench 描述如下。

激励部分我们使用简单的 task 进行描述,激励看起来就更加的清晰简洁。

其实,task 最多的应用场景还是应用于 testbench 中进行仿真。task 在一些编译器中也不支持综合。

`timescale 1ns/1nsmodule test ;reg          clk, rstn ;initial beginrstn      = 0 ;#8 rstn   = 1 ;forever beginclk = 0 ; # 5;clk = 1 ; # 5;endendreg  [3:0]   a, b;wire [3:0]   co ;initial begina         = 0 ;b         = 0 ;sig_input(4'b1111, 4'b1001, a, b);sig_input(4'b0110, 4'b1001, a, b);sig_input(4'b1000, 4'b1001, a, b);endtask sig_input ;input [3:0]       a ;input [3:0]       b ;output [3:0]      ao ;output [3:0]      bo ;@(posedge clk) ;ao = a ;bo = b ;endtask ; // sig_inputxor_oper         u_xor_oper(.clk              (clk  ),.rstn             (rstn ),.a                (a    ),.b                (b    ),.co               (co   ));initial beginforever begin#100;if ($time >= 1000)  $finish ;endendendmodule // test

仿真结果如下。

由图可知,异或输出逻辑结果正确,相对于输入有 3ns 的延迟。

且连接信号 a,b,co_t 与任务内部定义的信号 numa,numb,numco 状态也保持一致。
在这里插入图片描述
任务操作全局变量
因为任务可以看做是过程性赋值,所以任务的 output 端信号返回时间是在任务中所有语句执行完毕之后。

任务内部变量也只有在任务中可见,如果想具体观察任务中对变量的操作过程,需要将观察的变量声明在模块之内、任务之外,可谓之"全局变量"。

例如有以下 2 种尝试利用 task 产生时钟的描述方式。

//way1 to decirbe clk generating, not work
task clk_rvs_iner ;output    clk_no_rvs ;# 5 ;     clk_no_rvs = 0 ;# 5 ;     clk_no_rvs = 1 ;
endtask 
reg          clk_test1 ;
always clk_rvs_iner(clk_test1);//way2: use task to operate global varialbes to generating clk
reg          clk_test2 ;
task clk_rvs_global ;# 5 ;     clk_test2 = 0 ;# 5 ;     clk_test2 = 1 ;
endtask // clk_rvs_iner
always clk_rvs_global;

仿真结果如下。

第一种描述方式,虽然任务内部变量会有赋值 0 和赋值 1 的过程操作,但中间变化过程并不可见,最后输出的结果只能是任务内所有语句执行完毕后输出端信号的最终值。所以信号 clk_test1 值恒为 1,此种方式产生不了时钟。

第二种描述方式,虽然没有端口信号,但是直接对"全局变量"进行过程操作,因为该全局变量对模块是可见的,所以任务内信号翻转的过程会在信号 clk_test2 中体现出来。
在这里插入图片描述
automatic 任务
和函数一样,Verilog 中任务调用时的局部变量都是静态的。可以用关键字 automatic 来对任务进行声明,那么任务调用时各存储空间就可以动态分配,每个调用的任务都各自独立的对自己独有的地址空间进行操作,而不影响多个相同任务调用时的并发执行。

如果一任务代码段被 2 处及以上调用,一定要用关键字 automatic 声明。

当没有使用 automatic 声明任务时,任务被 2 次调用,可能出现信号间干扰,例如下面代码描述:

task test_flag ;input [3:0]       cnti ;input             en ;output [3:0]      cnto ;if (en) cnto = cnti ;
endtaskreg          en_cnt ;
reg [3:0]    cnt_temp ;
initial beginen_cnt    = 1 ;cnt_temp  = 0 ;#25 ;     en_cnt = 0 ;
end
always #10 cnt_temp = cnt_temp + 1 ;reg [3:0]             cnt1, cnt2 ;
always @(posedge clk) test_flag(2, en_cnt, cnt1);       //task(1)
always @(posedge clk) test_flag(cnt_temp, !en_cnt, cnt2);//task(2)

仿真结果如下。

en_cnt 为高时,任务 (1) 中信号 en 有效, cnt1 能输出正确的逻辑值;

此时任务 (2) 中信号 en 是不使能的,所以 cnt2 的值被任务 (1) 驱动的共用变量 cnt_temp 覆盖。

en_cnt 为低时,任务 (2) 中信号 en 有效,所以任务 (2) 中的信号 cnt2 能输出正确的逻辑值;而此时信号 cnt1 的值在时钟的驱动下,一次次被任务 (2) 驱动的共用变量 cnt_temp 覆盖。

可见,任务在两次并发调用中,共用存储空间,导致信号相互间产生了影响。
在这里插入图片描述
其他描述不变,只在上述 task 声明时加入关键字 automatic,如下所以。

task automatic test_flag ;

此时仿真结果如下。

en_cnt 为高时,任务 (1) 中信号 cnt1 能输出正确的逻辑值,任务 (2) 中信号 cnt2 的值为 X;
en_cnt 为低时,任务 (2) 中信号 cnt2 能输出正确的逻辑值,任务 (1) 中信号 cnt1 的值为 X;
可见,任务在两次并发调用中,因为存储空间相互独立,信号间并没有产生影响。

在这里插入图片描述

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

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

相关文章

高防服务器给企业带来的优势有哪些?

高防服务器主要指的是能够提供给网络安全提供高防护的服务器&#xff0c;通过流量清洗、负载均衡等手段来抵御DDoS攻击、CC攻击这一类流量攻击&#xff0c;为企业提供了强大的数据保障&#xff0c;互联网时代数据安全是放在第一位的&#xff0c;数据泄漏的话不论对于企业还是对…

google的日志glog安装及使用

1.glog glog是google出的一个轻量级的c日志库 2.下载及编译 下载或克隆库&#xff0c;我选择的是V0.6.0版本&#xff1a; github.com/goolge/glog/releases/tag/v0.6.0 我用cmake编译&#xff08;参考&#xff1a;github.com/google/glog#cmake&#xff09; 按照说明步骤进…

Python入门自学进阶-Web框架——42、Web框架了解-bottle、flask

WEB框架的三大组件&#xff1a;路由系统、控制器&#xff08;含模板渲染&#xff09;、数据库操作 微型框架&#xff1a;依赖第三方写的socket&#xff0c;WSGI&#xff0c; 本身功能少 安装&#xff1a; pip install bottle pip install flask 安装flask&#xff0c;同时安…

力扣每日一题(+日常水题|树型dp)

740. 删除并获得点数 - 力扣&#xff08;LeetCode&#xff09; 简单分析一下: 每一个数字其实只有2个状态选 or 不 可得预处理每一个数初始状态(不选为0,选为所有x的个数 * x)累加即可 for(auto &x : nums)dp[x][1] x;每选一个树 i 删去 i 1 和 i - 1 故我们可以将 i…

【笔记】离线Ubuntu20.04+mysql 5.7.36 + xtrabackup定时增量备份脚本

一、环境 ● Ubuntu版本查看 lsb_release -a● mysql 版本查看 mysql --version我的是ubuntu 20.04&#xff0c;mysql是5.7.36&#xff0c;所以要用 install_percona-xtrabackup-24 二、原理 备份 通过ubuntu自带的定时器运行增量备份脚本备份文件可以存储在映射后的其他…

26593-2011 无损检测仪器 工业用X射线CT装置性能测试方法

声明 本文是学习GB-T 26593-2011 无损检测仪器 工业用X射线CT装置性能测试方法. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了工业用X 射线CT 装置(以下简称CT 装置)性能测试的术语、定义、缩略语以及空间 分辨力、密度分辨率…

#硬件电路设计VL817-Q7(B0)芯片拓展USB3.0一转四调试心得

供电电路 基于XL4005的电源供电电路 SS34肖特基二极管 ZMM5V1稳压二极管 SMAJ15A TVS &#xff08;注意这个封装搞错5V会短接&#xff09; Vout0.8*[1(R2R3)/R1] D14 SR05静电防护器件 一路稳压两路TVS 共模电感 &#xff1a; 型号&#xff1a; SDCW2012-2-900TF 品牌&#…

Mac 苹果系统使用nvm use 切换node版本号

windows在使用 nvm 管理并切换 node 时&#xff0c;通过 nvm use 切换node版本会全局切换。也就是node版本号切换后只要不手动更改就会一直保持当前版本号不变。 但博主最近换了苹果系统后&#xff0c;发现苹果系统不能全局更改node版本。我在 vscode中使用nvm use x.x.x之后&…

Midjourney 生成油画技巧

基本 prompt oil painting, a cute corgi dog surrounded with colorful flowers技法 Pointillism 点描绘法 笔刷比较细&#xff0c;图像更精细 oil painting, a cute corgi dog surrounded with colorful flowers, pontillismImpasto 厚涂绘法 笔刷比较粗&#xff0c;图像…

Prometheus-监控Mysql进阶用法(1)(安装配置)

阿丹&#xff1a; 在开发和生产环境中有可能会出现慢mysql等问题&#xff0c;那么这里就需要我们优秀的程序员来进行监控和解决&#xff0c;那么如何借助云原生的监控系统来完成这个操作呢&#xff1f; 环境描述&#xff1a; 使用一台空白的阿里云服务器2核4G。 服务器基本安装…

Python:使用PySimpleGUI中sg.Input控件获取数据plot导致yticks错乱

sg.Input获取y轴数据代码 sg.Text(First Read:, font("Times New Roman", 9)),sg.Input(key-first_read-, size(25, 1), default_text0,0,0, justificationcenter, font("Times New Roman", 9), expand_xTrue), sg.Text(Second Read:, font("Times Ne…

PHP8中的构造方法和析构方法-PHP8知识详解

今日分享的内容是php8中的构造方法和析构方法&#xff0c;我们把构造方法和析构方法这两个方法分开来讲&#xff1a; 1、构造方法 构造方法存在于每个声明的类中&#xff0c;主要作用是执行一些初始化任务。如果类中没有直接声明构造方法&#xff0c;那么类会默认地生成一个没…

人工智能 与 搜索引擎的较量

随着科技的不断进步&#xff0c;人工智能&#xff08;AI&#xff09;已经渗透到了我们生活的方方面面&#xff0c;搜索引擎也不例外。AI与传统搜索引擎之间的较量成为了科技界和互联网用户关注的热点话题。 人工智能 与 搜索引擎的较量 A - 搜索引擎B - 人工智能AI 的优势理解力…

「C++之STL」关于在模拟实现STL容器中的深浅拷贝问题

文章目录 前言杨辉三角深浅拷贝问题模拟实现的vector对题目杨辉三角引发的程序崩溃原因解决办法 前言 在学习STL容器中,不仅需要学会容器的使用,同时也需要了解容器的大体框架以及各个函数的模拟实现才能更好的去了解这个容器; 杨辉三角 在LeetCode中有一道这样的题目,给定一…

jvm垃圾收集算法

简介 由于《分代收集理论》和不同垃圾收集算法&#xff0c;Java堆应该被划分为不同区域&#xff0c;一般至少会把Java堆划分为新生代&#xff08;Young Generation&#xff09;和老年代&#xff08;Old Generation&#xff09;两个区域。 垃圾收集器可以只回收其中某一个或者…

单片机外设-串口(UART)详情

目录 学习UART要先认识一些基础知识 一&#xff1a;什么是串行、并行通信&#xff1f; &#xff08;1&#xff09;串行通信 串行通信概念&#xff1a; 串行通信的特点&#xff1a; &#xff08;2&#xff09;并行通信 并行通信概念&#xff1a; 并行通信特点&#xff1…

【Linux】Linux远程访问Windows下的MySQL数据库

1.建立Windows防火墙规则 首先需要开放windows防火墙&#xff0c;针对3306端口单独创建一条规则&#xff0c;允许访问。 打开windows安全中心防火墙与保护&#xff0c;点击高级设置 进入之后&#xff0c;点击入站规则&#xff0c;新建一条规则 新建端口入站规则 端口填写330…

问题 - 谷歌浏览器 network 看不到接口请求解决方案

谷歌浏览器 -> 设置 -> 重置设置 -> 将设置还原为其默认值 查看接口情况&#xff0c;选择 All 或 Fetch/XHR&#xff0c;勾选 Has blocked cookies 即可 如果万一还不行&#xff0c;卸载浏览器重装。 参考&#xff1a;https://www.cnblogs.com/tully/p/16479528.html

C# 字符串和正则表达式

C# 字符串和正则表达式 System.String 类StringBuilder 成员格式化字符串正则表达式 System.String 类 StringBuilder 成员 格式化字符串 正则表达式

python加入环境变量

今天没事玩了会python,之前都是在windows下玩的&#xff0c;没什么问题。 今天要在dos窗口下运行python&#xff0c;却发现运行不了。而且在python安装目录下是可以运行的&#xff0c;于是我知道了我在安装python的时候没选择加入环境变量。我对windows还有是有定了解的&#x…