【verilog教程】verilog任务

1. 任务与函数的区别

和函数(function)一样,任务(task)可以用来描述共同的代码段,并在模块内任意位置被调用。

函数一般用于组合逻辑 的各种转换和计算;而任务更像一个过程,不仅能完成函数的功能,还可以包含时序控制逻辑。

任务与函数的区别:

比较点 函数 任务
输入 函数至少有一个输入,端口不能包含 inout 型 任务可以没有或者多个输入,且端口声明可以为 inout 型
输出 函数没有输出 任务可以没有或者多个输出
返回值 函数至少有一个返回值 任务没有返回值
仿真时刻 函数总在零时刻就开始执行 任务可以在非零时刻执行
时序逻辑 函数不能包含任何时序控制逻辑 任务不能出现 always 语句,但可以包含其它时序控制,如延时语句
调用 函数只能调用函数,不能调用任务 任务可以调用函数与任务
书写规范 函数不能单独作为一条语句出现,只能放在赋值语句的右端 任务可以作为一条语句出现在语句块中

2. 任务

2.1 任务声明

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

格式如下

verilog 复制代码
task task_id ;
	port_declaration ;
	procedural_statement ;
endtask

task <任务名字> ;
	<端口声明> ;
	<操作语句> ;
endtask

任务中使用 input,output,inout 对端口进行声明。

input,inout 型端口将变量从任务外部传递到内部,output,inout 型端口将任务执行完后的结果传回内部。

示例如下

verilog 复制代码
task add ;
	input wire a ;
	input wire b ;
	output reg c ;

	#3 c = a & b ;

endtask

2.2 任务调用

任务可单独作为一条语句出现在 initial,always 块中。

格式如下

verilog 复制代码
task_id( input1, input2, ... output1, output2, ... ) ;

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

输入端连接的模块内信号可以时 wire,reg 型。

输出端连接的模块内信号一定是 reg 型。

示例如下

verilog 复制代码
module test(

	input wire       clk_i		,
	input wire       rst_n_i	,
	input wire [7:0] a_i 		,
	input wire [7:0] b_i 		,
	output reg [7:0] c_i
);

reg [7:0] c_r ;

always @(*) begin
	x( a, b, c_r ) ; /// 函数调用
end

reg [7:0] c_r1 ;

always @( posedge clk_i or rst_n_i ) begin
	if( !rst_n_i ) begin
		c_r1 <= 0 ;
	end
	else begin
		c_r1 <= c_r ;
	end
end

always @( posedge clk_i or negedge rst_n_i ) begin
	if (!rst_n_i ) begin
		c_i <= 0 ;
	end
	else begin
		c_i <= c_r1 ;
	end
end

/// 函数
task x ;
	input wire [7:0] numa ;
	input wire [7:0] numb ;

	output reg [7:0] numc ;

	#10 numc = numa ^ numb ;
endtask

endmodule

3. 任务操作全局变量

因为任务可以看作过程性赋值,所以任务的 output 端信号返回时间是在任务中所有语句执行完毕之后。

示例如下

verilog 复制代码
/// example1
task clk1 ;
	output clk ;
	#5 ; clk = 0 ;
	#5 ; clk = 1 ; 
endtask

reg clk1_r ;

always clk1( clk1r ) ;

/// example2
reg clk2_r ;

task clk2 ;
	#5 ; clk2_r = 0 ;
	#5 ; clk2_r = 1 ;
endtask

always clk2 ;
  1. 第 1 种描述方式

    虽然任务内部有赋值 0 和赋值 1 的操作,但是中间变化的过程并不可见。

    最后输出的结果只能是任务内所有语句执行完毕后输出端信号的最终值。

    所以信号 clk 1 的值恒为 1。这种方式产生不了时钟。

  2. 第 2 种描述方式

    虽然没有端口信号,但是直接对 全局变量 进行过程赋值,因此该全局变量对模块是可见的。

    因此任务内该信号翻转过程会在信号 clk 2 中体现出来。这种方式会产生一个 10 个时间单位的周期的时钟。

【图床问题,仿真图待补充】

4. automatic 任务

和函数一样,verilog 中任务调用时的局部变量都是静态的。

可以用关键字 automatic 来对任务进行声明,那么任务调用时个存储空间就可以动态分配。

每个调用的任务都各自独立的对自己独有的地址空间进行操作,而不影响多个相同任务调用时的并发执行。

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

当没有使用 automatic 声明任务时,任务被 2 次调用,可能出现信号间干扰。

【工程待补充】

相关推荐
深夜情感老师2 小时前
centos离线安装ssh
linux·centos·ssh
9527华安6 小时前
国产紫光同创FPGA视频采集转SDI编码输出,基于HSSTHP高速接口,提供2套工程源码和技术支持
fpga开发·音视频·紫光同创·sdi·高速接口·hssthp
菜鸟射手6 小时前
QT creater和vs2017文件路径问题
linux·c++·windows·qt
@Aurora.7 小时前
【项目日记(三)】
linux·服务器·网络
白总Server7 小时前
Nginx 中间件
大数据·linux·运维·服务器·nginx·bash·web
S&Z34637 小时前
[FPGA基础] 原语简介篇
fpga开发
Dlrbw7 小时前
FPGA——DDS信号发生器设计
笔记·fpga开发
望获linux8 小时前
实时操作系统在服务型机器人中的关键作用
linux·机器人·操作系统·开源软件·rtos·具身智能
哈哈幸运9 小时前
Linux Sed 深度解析:从日志清洗到 K8s 等12个高频场景
linux·运维·编辑器·sed
心随_风动9 小时前
主流操作系统对比分析(macOS、Linux、Windows、Unix)
linux·windows·macos