verilog函数和任务

目录

一、函数

函数在模块中任意位置定义,并在模块内任意位置引用,作用范围也局限于此模块,一般用于组合逻辑的计算。

函数的声明和使用

函数的声明:

复制代码
function [N-1] function_name;
	input d1;
	integer i;
	parameter M=1;
	....
	begin
		...
	end
endfunction

function [N-1] function_name(input d1,....);
	integer i;
	...
	begin
		...
	end
endfunction

函数在声明时会隐式声明宽为N、名字为function_name的寄存器变量,函数返回值通过该变量传递。

函数的调用:

复制代码
...
b=function_name(a);

常数函数

常数函数:仿真开始前在编译期间就计算出结果的函数。

复制代码
function integer logb2;
	input integer depth;
	...
endfunction

automatic函数

一般函数的局部变量是静态的,即函数的每次调用,函数的局部变量都会使用同一个存储空间。两个函数调用行为同时对同一块地址进行操作,会导致不确定的函数结果。

用 automatic 修饰的函数在调用时是可以自动分配新的内存空间的。

复制代码
function automatic fac;
	....
endfunction

函数的特点

1)不含有任何延迟、时序或时序控制逻辑
2)至少有一个输入变量
3)只有一个返回值,且没有输出
4)不含有非阻塞赋值语句
5)函数可以调用其他函数,但是不能调用任务

二、任务

任务在模块中任意位置定义,并在模块内任意位置引用,作用范围也局限于此模块,用于描述一个过程,可以包含时序逻辑

复制代码
task task_name;
	input [N-1] a;
	output [N-1] b;
	...
endtask

task task_name(input [N-1] a,...);
	...
endtask

任务调用

任务可以单独作为一条语句放在initial或always块中。

复制代码
task_name(a,b,...);

任务调用时端口必须按顺序对应 ,输入端连接的模块内信号可以是 wire 型,也可以是 reg 型。输出端连接的模块内信号要求一定是 reg 型

任务操作全局变量

任务的 output 端信号返回时间是在任务中所有语句执行完毕之后,任务内部变量也只有在任务中可见,如果想具体观察任务中对变量的操作过程,需要将观察的变量声明在模块之内、任务之外。

复制代码
//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任务

用关键字 automatic 来对任务进行声明,那么任务调用时各存储空间就可以动态分配,每个调用的任务都各自独立的对自己独有的地址空间进行操作,而不影响多个相同任务调用时的并发执行

任务的特点

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

三、任务和函数的区别

比较点 函数 任务
输入 至少有一个输入,端口声明不能包含inout型 可以没有输入,端口声明可以为inout型
输出 没有输出 可用没有或者有多个输出
返回值 至少一个 没有
仿真时刻 总在零时刻就开始执行 可用在非零时刻执行
时序逻辑 不能包含任何时序逻辑 不能出现always语句,但可用包含其它时序控制
调用 函数只能调用函数,不能调用任务 任务可用调用函数和任务
书写 函数不能单独作为一条语句出现,只能放在赋值语句右端 可用单独作为一条语句出现
相关推荐
每月一号准时摆烂1 小时前
数字电子技术基础(六十)——使用Digital软件绘制脉冲触发的触发器
fpga开发
广药门徒2 小时前
STM32简易计算机设计
stm32·单片机·嵌入式硬件
Ronin-Lotus4 小时前
嵌入式硬件篇---拓展板
嵌入式硬件
天天爱吃肉82184 小时前
【低成本STM32的T-BOX开发实战:高可靠的车联网解决方案】
stm32·单片机·嵌入式硬件·云原生
不脱发的程序猿7 小时前
在超频单片机时,需要注意哪些稳定性问题?
单片机·嵌入式硬件
sword devil9007 小时前
STM32项目实战:ADC采集
stm32·单片机·嵌入式硬件
-liming-7 小时前
单片机设计_停车场车位管理系统(AT89C52、LCD1602)
单片机·嵌入式硬件·51单片机
不脱发的程序猿8 小时前
单片机超频怎么搞?
单片机·嵌入式硬件·单片机超频
hahaha60169 小时前
uart16550详细说明
stm32·单片机·嵌入式硬件
Invinciblenuonuo9 小时前
STM32八股【9】-----volatile关键字
stm32·单片机·嵌入式硬件