verilog语言中任务和函数的区别?
1个回答
2022-12-11 · 百度认证:北京惠企网络技术有限公司官方账号
关注
展开全部
任务和函数有助于简化程序,有点类似与Fortran语言的subroutine和function。\x0d\x0a\x0d\x0a任务和函数的共同点:\x0d\x0a\x0d\x0a1.任务和函数必须在模块内定义,其作用范围仅适用于该模块,可以在模块内多次调用。\x0d\x0a\x0d\x0a2.任务和函数中可以声明局部变量,如寄存器,时间,整数,实数和事件,但是不能声明线网类型的变量。\x0d\x0a\x0d\x0a3.任务和函数中只能使用行为级语句,但是不能包含always和initial块,设计者可以在always和initial块中调用任务和函数。\x0d\x0a\x0d\x0a任务和函数的不同点:\x0d\x0a函数 任务 \x0d\x0a函数能调用另一个函数,但是不能调用任务 任务可以调用另一个任务,也可以调用函数 \x0d\x0a函数总是在仿真时刻0开始 任务可以在非零时刻开始执行 \x0d\x0a函数一定不能包含任何延迟,事件或者时序控制声明语句 任务可以包含延迟,事件或者时序控制声明语句 \x0d\x0a函数至少要有一个输入变量,也可以有多个输入变量 任务可以没有或者有多个输入,输出,输入输出变量 \x0d\x0a函数只能返回一个值,函数不能有输出或者双向变量 任务不返回任何值,或者返回多个输出或双向变量值 \x0d\x0a\x0d\x0a由上述的特点决定:函数用于替代纯组合逻辑的verilog代码,而任务可以代替verilog的任何代码。\x0d\x0a\x0d\x0a8.2任务\x0d\x0a\x0d\x0a任务使用关键字task和endtask来进行声明,如果子程序满足下面任何一个条件,则必须使用任务而不能使用函数。\x0d\x0a\x0d\x0a1.子程序中包含有延迟,时序或者事件控制结构\x0d\x0a\x0d\x0a2.没有输出或者输出变量超过一个\x0d\x0a\x0d\x0a3.没有输入变量\x0d\x0a\x0d\x0a例:\x0d\x0a\x0d\x0amodule operation; \x0d\x0aparameter delay=10; \x0d\x0areg [15:0] A,B, AB_AND,AB_OR,AB_XOR; \x0d\x0aalways @(A or B) \x0d\x0abegin \x0d\x0a bitwise_ope(AB_AND,AB_OR,AB_XOR,A,B); \x0d\x0aend \x0d\x0atask bitwise_oper; \x0d\x0aoutput [15:0] ab_and,ab_or,ab_xor; \x0d\x0ainput [15:0] a,b; \x0d\x0abegin \x0d\x0a #delay ab_and=a&b; \x0d\x0a ab_or=a|b; \x0d\x0a ab_xor=a^b; \x0d\x0aend \x0d\x0aendtask \x0d\x0aalways @(posedge clk) \x0d\x0a bitwise_xor(ef_xor,e,f); \x0d\x0aalways @(posedege clk2) \x0d\x0a bitwise_xor(cd_xor,c,d) \x0d\x0atask autumatic bitwise_xor; \x0d\x0aoutput ab_xor; \x0d\x0ainput a,b; \x0d\x0abegin\x0d\x0a ab_xor=a^b;\x0d\x0aend\x0d\x0aendtask \x0d\x0aendmodule \x0d\x0a\x0d\x0a自动(可重入)任务:verilog任务中所有声明的变量地址空间都是静态分配的,因此如果在一个模块中多次调用任务时,可能会造成地址空间的冲突,为了避免这个问题,verilog通过在task关键字后面添加automatic使任务称为可重入的,这时在调用任务时,会自动给任务声明变量分配动态地址空间,这样有效避免了地址空间的冲突。\x0d\x0a\x0d\x0a8.3 函数\x0d\x0a\x0d\x0a函数使用关键字function和endfunction定义,对于子程序,如果满足下述所有条件则可以用函数来完成:\x0d\x0a\x0d\x0a1.在子程序中不含有延迟时序或者控制结构\x0d\x0a2.子程序只有一个返回值\x0d\x0a3.至少有一个输入变量\x0d\x0a4.没有输出或者双向变量\x0d\x0a5.不含有非阻塞赋值语句 \x0d\x0a\x0d\x0a例:\x0d\x0a\x0d\x0amodule parity;\x0d\x0areg [31:0] addr;\x0d\x0areg parity;\x0d\x0aalways @(addr)\x0d\x0abegin\x0d\x0a parity=calc_parity(addr);\x0d\x0aend\x0d\x0afunction calc_parity;\x0d\x0ainput [31:0] addr;\x0d\x0abegin\x0d\x0acalc_parity=^addr;\x0d\x0aend\x0d\x0aendfunction\x0d\x0aendmodule \x0d\x0a\x0d\x0a跟任务调用一样,在模块中如果调用多次函数,也会碰到地址冲突的问题,因此也引入automatic关键字来对函数可重用性声明。没有进行可重用性声明的函数不可以多次或者递归调用,进行了可重用性声明的函数可以递归调用。\x0d\x0a\x0d\x0a常量函数和带符号函数(函数声明时加signed关键字说明)\x0d\x0a\x0d\x0amodule ram;\x0d\x0aparameter RAM_DEPTH=256;\x0d\x0ainput [clogb2(RAM_DEPTH)-1:0] addr;//clogb2函数返回值为8\x0d\x0afunction integer clogb2(input integer depth);\x0d\x0abegin\x0d\x0a for(clogb2=0; depth>0;clogb2=clogb2+1)\x0d\x0a depth=depth>1;\x0d\x0aend\x0d\x0aendfunction\x0d\x0aendmodule \x0d\x0a\x0d\x0a练习:用两种不同的方法设计一个功能相同的模块,完成4个8位2进制输入数据的冒泡排序。第一种,用纯组合逻辑实现;第二种,假设8位数据按照时钟节拍串行输入,要求时钟触发任务的执行,每个时钟周期完成一次数据交换的操作。\x0d\x0a\x0d\x0a//----------------- 第一种 ------------------\x0d\x0a\x0d\x0amodule sort4(ra,rb,rc,rd,a,b,c,d);\x0d\x0a\x0d\x0aoutput[7:0] ra,rb,rc,rd;\x0d\x0a\x0d\x0ainput[7:0] a,b,c,d;\x0d\x0a\x0d\x0areg[7:0] ra,rb,rc,rd;\x0d\x0a\x0d\x0areg[7:0] va,vb,vc,vd;\x0d\x0a\x0d\x0aalways @ (a or b or c or d)\x0d\x0a\x0d\x0a begin\x0d\x0a\x0d\x0a {va,vb,vc,vd}={a,b,c,d};\x0d\x0a\x0d\x0achange(va,vb);\x0d\x0a\x0d\x0a change(vb,vc);\x0d\x0a\x0d\x0a change(vc,vd);\x0d\x0a\x0d\x0achange(va,vb);\x0d\x0a\x0d\x0a change(vb,vc);\x0d\x0a\x0d\x0achange(va,vb);\x0d\x0a\x0d\x0a{ra,rb,rc,rd}={va,vb,vc,vd};\x0d\x0a\x0d\x0a end\x0d\x0a\x0d\x0atask change; //make a task of comparing\x0d\x0a\x0d\x0ainout[7:0] x,y; \x0d\x0a\x0d\x0areg[7:0] tmp;\x0d\x0a\x0d\x0a if(x>y) \x0d\x0a\x0d\x0a begin\x0d\x0a\x0d\x0a tmp=x; \x0d\x0a\x0d\x0a x=y;\x0d\x0a\x0d\x0a y=tmp;\x0d\x0a\x0d\x0a end\x0d\x0a\x0d\x0aendtask\x0d\x0a\x0d\x0aendmodule\x0d\x0a\x0d\x0a//----------------- 第二种 ------------------\x0d\x0a\x0d\x0amodule sort4(clk,reset,ra,rb,rc,rd,a);\x0d\x0a\x0d\x0aoutput[7:0] ra,rb,rc,rd;\x0d\x0a\x0d\x0ainput[7:0] a;\x0d\x0a\x0d\x0ainput clk,reset;\x0d\x0a\x0d\x0areg[7:0] ra,rb,rc,rd;\x0d\x0a\x0d\x0areg[7:0] va,vb,vc,vd;\x0d\x0a\x0d\x0aalways @ (posedge clk)\x0d\x0a\x0d\x0a begin\x0d\x0a\x0d\x0a if(!reset)\x0d\x0a\x0d\x0a begin\x0d\x0a\x0d\x0a va<=0;vb<=0;vc<=0;vd<=0;\x0d\x0a\x0d\x0a end\x0d\x0a\x0d\x0a else\x0d\x0a\x0d\x0a va<=a;\x0d\x0a\x0d\x0a end\x0d\x0a\x0d\x0aalways @ (posedge clk)\x0d\x0a\x0d\x0a begin\x0d\x0a\x0d\x0achange(va,vb);\x0d\x0a\x0d\x0a change(vb,vc);\x0d\x0a\x0d\x0a change(vc,vd);\x0d\x0a\x0d\x0achange(va,vb);\x0d\x0a\x0d\x0a change(vb,vc);\x0d\x0a\x0d\x0achange(va,vb);\x0d\x0a\x0d\x0a{ra,rb,rc,rd}={va,vb,vc,vd};\x0d\x0a\x0d\x0a end\x0d\x0a\x0d\x0atask change; //make a task of comparing\x0d\x0a\x0d\x0ainout[7:0] x,y; \x0d\x0a\x0d\x0areg[7:0] tmp;\x0d\x0a\x0d\x0a if(x>y) \x0d\x0a\x0d\x0a begin\x0d\x0a\x0d\x0a tmp=x; \x0d\x0a\x0d\x0a x=y;\x0d\x0a\x0d\x0a y=tmp;\x0d\x0a\x0d\x0a end\x0d\x0a\x0d\x0aendtask\x0d\x0a\x0d\x0aendmodule
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询