verilog语言中任务和函数的区别?
任务和函数有助于简化程序,有点类似与Fortran语言的subroutine和function。
任务和函数的共同点:
1.任务和函数必须在模块内定义,其作用范围仅适用于该模块,可以在模块内多次调用。
2.任务和函数中可以声明局部变量,如寄存器,时间,整数,实数和事件,但是不能声明线网类型的变量。
3.任务和函数中只能使用行为级语句,但是不能包含always和initial块,设计者可以在always和initial块中调用任务和函数。
任务和函数的不同点:
函数 任务
函数能调用另一个函数,但是不能调用任务 任务可以调用另一个任务,也可以调用函数
函数总是在仿真时刻0开始 任务可以在非零时刻开始执行
函数一定不能包含任何延迟,事件或者时序控制声明语句 任务可以包含延迟,事件或者时序控制声明语句
函数至少要有一个输入变量,也可以有多个输入变量 任务可以没有或者有多个输入,输出,输入输出变量
函数只能返回一个值,函数不能有输出或者双向变量 任务不返回任何值,或者返回多个输出或双向变量值
由上述的特点决定:函数用于替代纯组合逻辑的verilog代码,而任务可以代替verilog的任何代码。
8.2任务
任务使用关键字task和endtask来进行声明,如果子程序满足下面任何一个条件,则必须使用任务而不能使用函数。
1.子程序中包含有延迟,时序或者事件控制结构
2.没有输出或者输出变量超过一个
3.没有输入变量
例:
module operation;
parameter delay=10;
reg [15:0] A,B, AB_AND,AB_OR,AB_XOR;
always @(A or B)
begin
bitwise_ope(AB_AND,AB_OR,AB_XOR,A,B);
end
task bitwise_oper;
output [15:0] ab_and,ab_or,ab_xor;
input [15:0] a,b;
begin
#delay ab_and=a&b;
ab_or=a|b;
ab_xor=a^b;
end
endtask
always @(posedge clk)
bitwise_xor(ef_xor,e,f);
always @(posedege clk2)
bitwise_xor(cd_xor,c,d)
task autumatic bitwise_xor;
output ab_xor;
input a,b;
begin
ab_xor=a^b;
end
endtask
endmodule
自动(可重入)任务:verilog任务中所有声明的变量地址空间都是静态分配的,因此如果在一个模块中多次调用任务时,可能会造成地址空间的冲突,为了避免这个问题,verilog通过在task关键字后面添加automatic使任务称为可重入的,这时在调用任务时,会自动给任务声明变量分配动态地址空间,这样有效避免了地址空间的冲突。
8.3 函数
函数使用关键字function和endfunction定义,对于子程序,如果满足下述所有条件则可以用函数来完成:
1.在子程序中不含有延迟时序或者控制结构
2.子程序只有一个返回值
3.至少有一个输入变量
4.没有输出或者双向变量
5.不含有非阻塞赋值语句
例:
module parity;
reg [31:0] addr;
reg parity;
always @(addr)
begin
parity=calc_parity(addr);
end
function calc_parity;
input [31:0] addr;
begin
calc_parity=^addr;
end
endfunction
endmodule
跟任务调用一样,在模块中如果调用多次函数,也会碰到地址冲突的问题,因此也引入automatic关键字来对函数可重用性声明。没有进行可重用性声明的函数不可以多次或者递归调用,进行了可重用性声明的函数可以递归调用。
常量函数和带符号函数(函数声明时加signed关键字说明)
module ram;
parameter RAM_DEPTH=256;
input [clogb2(RAM_DEPTH)-1:0] addr;//clogb2函数返回值为8
function integer clogb2(input integer depth);
begin
for(clogb2=0; depth>0;clogb2=clogb2+1)
depth=depth>1;
end
endfunction
endmodule
练习:用两种不同的方法设计一个功能相同的模块,完成4个8位2进制输入数据的冒泡排序。第一种,用纯组合逻辑实现;第二种,假设8位数据按照时钟节拍串行输入,要求时钟触发任务的执行,每个时钟周期完成一次数据交换的操作。
//----------------- 第一种 ------------------
module sort4(ra,rb,rc,rd,a,b,c,d);
output[7:0] ra,rb,rc,rd;
input[7:0] a,b,c,d;
reg[7:0] ra,rb,rc,rd;
reg[7:0] va,vb,vc,vd;
always @ (a or b or c or d)
begin
{va,vb,vc,vd}={a,b,c,d};
change(va,vb);
change(vb,vc);
change(vc,vd);
change(va,vb);
change(vb,vc);
change(va,vb);
{ra,rb,rc,rd}={va,vb,vc,vd};
end
task change; //make a task of comparing
inout[7:0] x,y;
reg[7:0] tmp;
if(x>y)
begin
tmp=x;
x=y;
y=tmp;
end
endtask
endmodule
//----------------- 第二种 ------------------
module sort4(clk,reset,ra,rb,rc,rd,a);
output[7:0] ra,rb,rc,rd;
input[7:0] a;
input clk,reset;
reg[7:0] ra,rb,rc,rd;
reg[7:0] va,vb,vc,vd;
always @ (posedge clk)
begin
if(!reset)
begin
va<=0;vb<=0;vc<=0;vd<=0;
end
else
va<=a;
end
always @ (posedge clk)
begin
change(va,vb);
change(vb,vc);
change(vc,vd);
change(va,vb);
change(vb,vc);
change(va,vb);
{ra,rb,rc,rd}={va,vb,vc,vd};
end
task change; //make a task of comparing
inout[7:0] x,y;
reg[7:0] tmp;
if(x>y)
begin
tmp=x;
x=y;
y=tmp;
end
endtask
endmodule
1、task定义可以没有输入。function必须至少输入
2、function智能与主模块共用同一个仿真时间单位,而task可以定义自己的方阵时间单位
3、function要有返回值,返回一个值,而task不需要返回值。
4、function不能启动task,而task可以启动其他task和function
任务和函数的共同点:
1.任务和函数必须在模块内定义,其作用范围仅适用于该模块,可以在模块内多次调用。
2.任务和函数中可以声明局部变量,如寄存器,时间,整数,实数和事件,但是不能声明线网类型的变量。
3.任务和函数中只能使用行为级语句,但是不能包含always和initial块,设计者可以在always和initial块中调用任务和函数。
任务和函数的不同点:
函数 任务
函数能调用另一个函数,但是不能调用任务 任务可以调用另一个任务,也可以调用函数
函数总是在仿真时刻0开始 任务可以在非零时刻开始执行
函数一定不能包含任何延迟,事件或者时序控制声明语句 任务可以包含延迟,事件或者时序控制声明语句
函数至少要有一个输入变量,也可以有多个输入变量 任务可以没有或者有多个输入,输出,输入输出变量
函数只能返回一个值,函数不能有输出或者双向变量 任务不返回任何值,或者返回多个输出或双向变量值
由上述的特点决定:函数用于替代纯组合逻辑的verilog代码,而任务可以代替verilog的任何代码。
8.2任务
任务使用关键字task和endtask来进行声明,如果子程序满足下面任何一个条件,则必须使用任务而不能使用函数。
1.子程序中包含有延迟,时序或者事件控制结构
2.没有输出或者输出变量超过一个
3.没有输入变量
例:
module operation;
parameter delay=10;
reg [15:0] A,B, AB_AND,AB_OR,AB_XOR;
always @(A or B)
begin
bitwise_ope(AB_AND,AB_OR,AB_XOR,A,B);
end
task bitwise_oper;
output [15:0] ab_and,ab_or,ab_xor;
input [15:0] a,b;
begin
#delay ab_and=a&b;
ab_or=a|b;
ab_xor=a^b;
end
endtask
always @(posedge clk)
bitwise_xor(ef_xor,e,f);
always @(posedege clk2)
bitwise_xor(cd_xor,c,d)
task autumatic bitwise_xor;
output ab_xor;
input a,b;
begin
ab_xor=a^b;
end
endtask
endmodule
自动(可重入)任务:verilog任务中所有声明的变量地址空间都是静态分配的,因此如果在一个模块中多次调用任务时,可能会造成地址空间的冲突,为了避免这个问题,verilog通过在task关键字后面添加automatic使任务称为可重入的,这时在调用任务时,会自动给任务声明变量分配动态地址空间,这样有效避免了地址空间的冲突。
8.3 函数
函数使用关键字function和endfunction定义,对于子程序,如果满足下述所有条件则可以用函数来完成:
1.在子程序中不含有延迟时序或者控制结构
2.子程序只有一个返回值
3.至少有一个输入变量
4.没有输出或者双向变量
5.不含有非阻塞赋值语句
例:
module parity;
reg [31:0] addr;
reg parity;
always @(addr)
begin
parity=calc_parity(addr);
end
function calc_parity;
input [31:0] addr;
begin
calc_parity=^addr;
end
endfunction
endmodule
跟任务调用一样,在模块中如果调用多次函数,也会碰到地址冲突的问题,因此也引入automatic关键字来对函数可重用性声明。没有进行可重用性声明的函数不可以多次或者递归调用,进行了可重用性声明的函数可以递归调用。
常量函数和带符号函数(函数声明时加signed关键字说明)
module ram;
parameter RAM_DEPTH=256;
input [clogb2(RAM_DEPTH)-1:0] addr;//clogb2函数返回值为8
function integer clogb2(input integer depth);
begin
for(clogb2=0; depth>0;clogb2=clogb2+1)
depth=depth>1;
end
endfunction
endmodule
练习:用两种不同的方法设计一个功能相同的模块,完成4个8位2进制输入数据的冒泡排序。第一种,用纯组合逻辑实现;第二种,假设8位数据按照时钟节拍串行输入,要求时钟触发任务的执行,每个时钟周期完成一次数据交换的操作。
//----------------- 第一种 ------------------
module sort4(ra,rb,rc,rd,a,b,c,d);
output[7:0] ra,rb,rc,rd;
input[7:0] a,b,c,d;
reg[7:0] ra,rb,rc,rd;
reg[7:0] va,vb,vc,vd;
always @ (a or b or c or d)
begin
{va,vb,vc,vd}={a,b,c,d};
change(va,vb);
change(vb,vc);
change(vc,vd);
change(va,vb);
change(vb,vc);
change(va,vb);
{ra,rb,rc,rd}={va,vb,vc,vd};
end
task change; //make a task of comparing
inout[7:0] x,y;
reg[7:0] tmp;
if(x>y)
begin
tmp=x;
x=y;
y=tmp;
end
endtask
endmodule
//----------------- 第二种 ------------------
module sort4(clk,reset,ra,rb,rc,rd,a);
output[7:0] ra,rb,rc,rd;
input[7:0] a;
input clk,reset;
reg[7:0] ra,rb,rc,rd;
reg[7:0] va,vb,vc,vd;
always @ (posedge clk)
begin
if(!reset)
begin
va<=0;vb<=0;vc<=0;vd<=0;
end
else
va<=a;
end
always @ (posedge clk)
begin
change(va,vb);
change(vb,vc);
change(vc,vd);
change(va,vb);
change(vb,vc);
change(va,vb);
{ra,rb,rc,rd}={va,vb,vc,vd};
end
task change; //make a task of comparing
inout[7:0] x,y;
reg[7:0] tmp;
if(x>y)
begin
tmp=x;
x=y;
y=tmp;
end
endtask
endmodule
电脑中的文件格式
LOG 日志文件LPD Helix Nut和Bolt文件LRC Intel可视电话文件LSL Corel Paradox保存的库文件LSP AutoLISP、CommonLISP和其他LISP语言文件LST 列表文件LU ThoughtWing库单元文件LVL Parallax Software的 Miner Descent\/D2 Level扩展LWLO Lightwave分层对象文件LWOB Lightwave对象文件LWP Lotus WordPro 96\/97文件LWSC Lightwave...
文件扩展名到底有多少种,都是什么意思啊?
LOG 日志文件 LPD Helix Nut和Bolt文件 LRC Intel可视电话文件 LSL Corel Paradox保存的库文件 LSP AutoLISP、CommonLISP和其他LISP语言文件 LST 列表文件 LU ThoughtWing库单元文件 LVL Parallax Software的 Miner Descent\/D2 Level扩展 LWLO Lightwave分层对象文件 LWOB Lightwave对象文件 LWP Lotus WordPro 96\/97...
拓显中诺: 由“$+函数名”这种特殊的表示方式表示的任务和函数称为"系统任务"或"系统函数".顾名思义,"系统任务"或"系统函数"是由系统所给定的(相当于verilog帮你写的一个函数),用户没法去修改,只能够调用.用户自己写的函数或任务不能加$,以便与系统任务和系统函数区分开.常见的系统函数有$display,$write等.
鄱阳县18313239347: 感觉verilog语言中没有必要把函数与任务分开处理,整合成C中的函数不行? - ?
拓显中诺: 最好不用1. 首先verilog是硬件语言,是并行的执行方式2. C是软件语言,串行的执行方式 请楼主在学verilog时就要转变一种思维方式,verilog写成的将来都必须要成综合成电路的,如果整合在一起电路会非常臃肿,实现功率并不高,这跟C有很大的区别 一般函数和任务尽量少用,除非是testbench或运算中非用不可以的
鄱阳县18313239347: verilog中task和function的区别 - ?
拓显中诺: 1、task定义可以没有输入.function必须至少输入 2、function智能与主模块共用同一个仿真时间单位,而task可以定义自己的方阵时间单位 3、function要有返回值,返回一个值,而task不需要返回值. 4、function不能启动task,而task可以启动其他task和function
鄱阳县18313239347: verilog中的函数和任务能综合吗 - ?
拓显中诺: 简单的函数是可以综合的,任务一般是不可综合的.这个是有标准可以查的.
鄱阳县18313239347: Verilog语言里如何调用函数? - ?
拓显中诺: verilog中函数(function)都是有返回值的,在定义函数时如果你不声明返回值的类型和宽度,则默认为1个1位的reg型变量. verilog中调用函数和C语言类似,格式为:函数名(实参1,实参2...) 例如你定义了一个函数die,此函数中声明为input的端口为a,b,实际调用时用到的变量为aa,bb,假设要把返回值赋给q,则调用语句为: q=die(aa,bb); 需要注意的是不能把die(aa,bb)作为一条完整的语句,它实际相当于一个操作数.——Medied.Lee
鄱阳县18313239347: 请教verilog里变量声明时和有什么区别 - ?
拓显中诺: 1、模块声明的扩展 (1) Verilog‐2001允许将端口声明和数据类型声明放在同一条语句中,例子如下:向左转|向右转 (2)Verilog‐2001中增加了ANSIC风格的输入输出端口声明,可以用于module,task和function.例子如下:向左转|向右转 ...
鄱阳县18313239347: verilog中if else和case语句有什么区别 - ?
拓显中诺: 功能差不多,if else有优先级,case没有,一般类别少的用if else,类别多用case. 例如: if (data == 1) out <= 2'b01; else if (data1 == 1) out <= 2'b10; else out <= 2'b00; case (addr[3:0]) 4'h0: out = 0; 4'h1: out = 1; 4'h2: out = 2; 4'h3: out = 3; 4'h4: out = 4; default: out = 0; endcase
鄱阳县18313239347: verilog @符号什么意思 - ?
拓显中诺: @也就是个循环等待相当于while,不断判断其括号内的事件是否发生,当事件发生时就进入always模块执行一次;if在程序中是按顺序执行,如果没有嵌套在大循环中就只执行一次.
鄱阳县18313239347: verilog中@是什么意思?有什么用? - ?
拓显中诺: 看看英文意思就能明白、助记.@读作at, 当...的时候.always, 总是,一直. always @(posedge CLK), 意思是:当CLK信号上升沿的时候,总是(执行下述语句)