Verilog,函数调用参数传递的值没有传递到调用部分,错在哪里?

verilog语言中任务和函数的区别_百度知道
verilog语言中任务和函数的区别
我有更好的答案
任务和函数有助于简化程序,有点类似与Fortran语言的subroutine和function。任务和函数的共同点:1.任务和函数必须在模块内定义,其作用范围仅适用于该模块,可以在模块内多次调用。2.任务和函数中可以声明局部变量,如寄存器,时间,整数,实数和事件,但是不能声明线网类型的变量。3.任务和函数中只能使用行为级语句,但是不能包含always和initial块,设计者可以在always和initial块中调用任务和函数。任务和函数的不同点:函数
函数能调用另一个函数,但是不能调用任务
任务可以调用另一个任务,也可以调用函数
函数总是在仿真时刻0开始
任务可以在非零时刻开始执行
函数一定不能包含任何延迟,事件或者时序控制声明语句
任务可以包含延迟,事件或者时序控制声明语句
函数至少要有一个输入变量,也可以有多个输入变量
任务可以没有或者有多个输入,输出,输入输出变量
函数只能返回一个值,函数不能有输出或者双向变量
任务不返回任何值,或者返回多个输出或双向变量值
由上述的特点决定:函数用于替代纯组合逻辑的verilog代码,而任务可以代替verilog的任何代码。8.2任务任务使用关键字task和endtask来进行声明,如果子程序满足下面任何一个条件,则必须使用任务而不能使用函数。1.子程序中包含有延迟,时序或者事件控制结构2.没有输出或者输出变量超过一个3.没有输入变量例:
parameter delay=10;
reg [15:0] A,B, AB_AND,AB_OR,AB_XOR;
always @(A or B)
bitwise_ope(AB_AND,AB_OR,AB_XOR,A,B);
output [15:0] ab_and,ab_or,ab_
input [15:0] a,b;
#delay ab_and=a&b;
ab_or=a|b;
ab_xor=a^b;
always @(posedge clk)
bitwise_xor(ef_xor,e,f);
always @(posedege clk2)
bitwise_xor(cd_xor,c,d)
task autumatic bitwise_
output ab_
ab_xor=a^b;endendtask
自动(可重入)任务:verilog任务中所有声明的变量地址空间都是静态分配的,因此如果在一个模块中多次调用任务时,可能会造成地址空间的冲突,为了避免这个问题,verilog通过在task关键字后面添加automatic使任务称为可重入的,这时在调用任务时,会自动给任务声明变量分配动态地址空间,这样有效避免了地址空间的冲突。8.3 函数函数使用关键字function和endfunction定义,对于子程序,如果满足下述所有条件则可以用函数来完成:1.在子程序中不含有延迟时序或者控制结构2.子程序只有一个返回值3.至少有一个输入变量4.没有输出或者双向变量5.不含有非阻塞赋值语句
例:module parity;reg [31:0]always @(addr)begin
parity=calc_parity(addr);endfunction calc_input [31:0]begincalc_parity=^endendfunctionendmodule
跟任务调用一样,在模块中如果调用多次函数,也会碰到地址冲突的问题,因此也引入automatic关键字来对函数可重用性声明。没有进行可重用性声明的函数不可以多次或者递归调用,进行了可重用性声明的函数可以递归调用。常量函数和带符号函数(函数声明时加signed关键字说明)parameter RAM_DEPTH=256;input [clogb2(RAM_DEPTH)-1:0]//clogb2函数返回值为8function integer clogb2(input integer depth);begin
for(clogb2=0; depth&0;clogb2=clogb2+1)
depth=depth&1;endendfunctionendmodule
练习:用两种不同的方法设计一个功能相同的模块,完成4个8位2进制输入数据的冒泡排序。第一种,用纯组合逻辑实现;第二种,假设8位数据按照时钟节拍串行输入,要求时钟触发任务的执行,每个时钟周期完成一次数据交换的操作。//----------------- 第一种 ------------------module sort4(ra,rb,rc,rd,a,b,c,d);output[7:0] ra,rb,rc,input[7:0] a,b,c,d;reg[7:0] ra,rb,rc,reg[7:0] va,vb,vc,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
//make a task of comparinginout[7:0] x,y; reg[7:0]
endendtaskendmodule//----------------- 第二种 ------------------module sort4(clk,reset,ra,rb,rc,rd,a);output[7:0] ra,rb,rc,input[7:0]input clk,reg[7:0] ra,rb,rc,reg[7:0] va,vb,vc,always @ (posedge clk) begin
if(!reset)
va&=0;vb&=0;vc&=0;vd&=0;
va&=a; endalways @ (posedge clk) beginchange(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
//make a task of comparinginout[7:0] x,y; reg[7:0]
endendtaskendmodule
采纳率:68%
来自团队:
任务可以有input、output和inout,数量不限,函数只有input参数,且至少有一个任务可以包含有时序控制(如延时等),函数不能包含有任何延迟,仿真时间为0;任务可以用disable中断,函数不允许disable、wait语句;任务可以通过I/O端口实现值传递,函数名即输出变量名,通过函数返回值;任务可以调用其他任务和函数,函数只能调用其他函数,不能调用任务;任务可以定义自己的仿真时间单位,函数只能与主模块共用一个仿真时间单位;函数通过一个返回一个值来响应输入信号的值,任务却能支持多种目的,能计算多个结果值,结果值只能通过被调用的任务的输出端口输出或总线端口送出;另外在函数中不能有wire型变量.任务定义语法:
task &任务名&;
&端口及数据类型声明语句&
&语句1&......endtask函数定义的语法:function &返回值类型或范围&(函数名)
&端口说明语句&
&变量类型说明语句&
&语句&......
endendfunction从百度搜,有很多相关介绍
本回答被网友采纳
分呢? 哈哈!书本p114
本回答被提问者采纳
为您推荐:
其他类似问题
verilog的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。verilog中函数function 中的变量可以和调用模块的变量重名吗 - FPGA|CPLD|ASIC论坛 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
verilog中函数function 中的变量可以和调用模块的变量重名吗
21:44:50  
verilog中函数function 中的变量可以和调用模块的变量重名吗
,有没有影响
06:14:53  
谢谢分享,正是我感兴趣的主题。
08:12:36  
这个是没有影响的,function中的变量只对function内部有效,对于外部只作为输入,无影响.
Powered by
供应链服务
版权所有 (C) 深圳华强聚丰电子科技有限公司Verilog函数与任务_百度文库
赠送免券下载特权
10W篇文档免费专享
部分付费文档8折起
每天抽奖多种福利
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
Verilog函数与任务
&&Verilog函数与任务 区别与联系
阅读已结束,下载本文需要
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,同时保存到云知识,更方便管理
加入VIP
还剩5页未读,
定制HR最喜欢的简历
你可能喜欢verilog中的function用法与例子
函数的功能和任务的功能类似,但二者还存在很大的不同。在 Verilog HDL 语法中也存
在函数的定义和调用。
1.函数的定义
函数通过关键词 function 和 endfunction 定义,不允许输出端口声明(包括输出和双向
端口) ,但可以有多个输入端口。函数定义的语法如下:
function [range] function_
input_declaration
other_declarations
procedural_statement
endfunction
其中,function 语句标志着函数定义结构的开始;[range]参数指定函数返回值的类型或
位宽,是一个可选项,若没有指定,默认缺省值为 1 比特的寄存器数据;function_id 为所定
义函数的名称,对函数的调用也是通过函数名完成的,并在函数结构体内部代表一个内部变
量,函数调用的返回值就是通过函数名变量传递给调用语句;input_declaration 用于对寒暑
各个输入端口的位宽和类型进行说明,在函数定义中至少要有一个输入端口;endfunction
为函数结构体结束标志。下面给出一个函数定义实例。
定义函数实例。
//定义输入变量
input A, B;
//定义函数体
endfunction
函数定义在函数内部会隐式定义一个寄存器变量, 该寄存器变量和函数同名并且位宽也
一致。函数通过在函数定义中对该寄存器的显式赋值来返回函数计算结果。此外,还有下列
几点需要注意:
(1)函数定义只能在模块中完成,不能出现在过程块中;
(2)函数至少要有一个输入端口;不能包含输出端口和双向端口;
(3) 在函数结构中, 不能使用任何形式的时间控制语句 (#、 wait 等) , 也不能使用 disable
中止语句;
(4)函数定义结构体中不能出现过程块语句(always 语句) ;
(5)函数内部可以调用函数,但不能调用任务。
2.函数调用
和任务一样,函数也是在被调用时才被执行的,调用函数的语句形式如下:
func_id(expr1, expr2, ........., exprN)
其中,func_id 是要调用的函数名,expr1, expr2, ......exprN是传递给函数的输入参数列
表,该输入参数列表的顺序必须与函数定义时声明其输入的顺序相同。下面给出一个函数调
函数调用实例。
module comb15 (A, B, CIN, S, COUT);
input [3:0] A, B;
input CIN;
output [3:0] S;
output COUT;
wire [1:0] S0, S1, S2, S3;
function signed [1:0] ADD;
input A, B, CIN;
reg S, COUT;
S = A ^ B ^ CIN;
COUT = (A&B) | (A&CIN) | (B&CIN);
ADD = {COUT, S};
endfunction
assign S0 = ADD (A[0], B[0], CIN),
S1 = ADD (A[1], B[1], S0[1]),
S2 = ADD (A[2], B[2], S1[1]),
S3 = ADD (A[3], B[3], S2[1]),
S = {S3[0], S2[0], S1[0], S0[0]},
COUT = S3[1];
在函数调用中,有下列几点需要注意:
(1)函数调用可以在过程块中完成,也可以在 assign 这样的连续赋值语句中出现。
(2)函数调用语句不能单独作为一条语句出现,只能作为赋值语句的右端操作数。下载费用: 9.00 元 &
&&&&&&&&&&&&verilog系统函数
verilog系统函数
还剩页未读,继续阅读
下载文档到电脑,查找使用更方便
下载需:<b style="color: #ff 元
内容要点:
verilog系统函数Verilog 中常用的系统函数( 14:54:39) 转载 ▼标签: 杂谈分类: FPGA 的研究 Verilog HDL 常用的系统任务1.$display(,);//显示变量的值或变量的范围,自动加换行如:$display(“dout=%d dout”,dout);2.$write();//和上面的用法相同,但是不会自动加换行3.$monitor(,);//在多模块调试的情况下,许多模块中都调用了$monitor,因为任何时刻只能有一个$monitor 起作用,因此需配合$monitoron 与$monitoroff 使用,把需要监视的模块用$monitoron 打开,在监视完毕后及时用$monitoroff 关闭,以便把$monitor 让给其他模块使用。$monitor 与$display 的不同处还在于$monitor往往在 initial 块中调用,只要不调用$monitoroff,$monitor 便不间断地对所设定的信号进行监视。4.$time 系统函数:返回 64 位的整数来表示当前的仿真时刻; $realtime 系统函数:返回一个实型数表示当前仿真时刻。都以模块的仿真时间尺度为基准。5.$monitor($realtime,,"set=%b",set);//其中一个用法5.系统任务$finish:退出仿真器,返回操作系统6.系统任务$stop:暂停仿真器7.系统任务$random:$random%b 或者{$random}%b8.系统任务$readmemb 和$readmemh:用于从文件中读取数据到寄存器中,任何时候都可以被执行(数据方向:文件>>寄存器);有以下用法:1) $readmemb("",);2) $readmemb("",,);3) $readmemb("",,,);4) $readmemh("",);5) $readmemh("",,);6) $readmemh("",,,);其中文件中的地址表示方式@hhhh--hh,但是寄存器中的地址可直接用数表示。这里说的地址均是寄存器的地址。9.显示层次任务:$display("Dispalying in %m");//可以显示正在仿真的位置10.选通显示:$strobe(,);//可以保证当所有的赋值语句完成之后才进行显示,同步机制。11.值变转储任务:将调试过程中感兴趣的信号转存到 VCD 文件中的任务。$dumpfile();// 选择转储的 VCD 文件$dumpvars();// 选择需要存储的 VCD 变量范围$//建立一个监测点,转储当前所有 VCD 变量的现行值$和$//控制转储的开始和结束,可用时间延时控制转储过程。1.激励的设置相应于被测试模块的输入激励设置为 reg 型,输出相应设置为 wire 类型,双向端口 inout 在测试中需要进行处理。方法 1:为双向端口设置中间变量 inout_reg 作为该 inout 的输出寄存,inout 口在 testbench 中要定义为 wire 型变量,然后用输出使能控制传输方向。eg:inout [0:0] bi_dir_wire [0:0] bi_dir_reg [0:0] bi_dir_port_reg bi_dir_port_assign bi_dir_port=bi_dir_port_oe?bi_dir_port_reg:1'用 bi_dir_port_oe 控制端口数据方向,并利用中间变量寄存器改变其值。等于两个模块之间用 inout 双向口互连。往端口写(就是往模块里面输入)方法 2:使用 force 和 release 语句,这种方法不能准确反映双向端口的信号变化,但这种方法可以反映块内信号的变化。具体如示:module test();wire data_reg data_# //延时force data_inout=1' //强制作为输入端口...............#release data_ //释放输入端口endmodule从文本文件中读取和写入向量1)读取文本文件:用 $readmemb 系统任务从文本文件中读取二进制向量(可以包含输入激励和输出期望值)。$readmemh 用于读取十六进制文件。例如:reg [7:0] mem[1:256] // a 8-bit, 256-word 定义存储器 meminitial $readmemh ( "mem.data", mem ) // 将.dat 文件读入寄存器 mem 中initial $readmemh ( "mem.data", mem, 128, 1 ) // 参数为寄存器加载数据的地址始终2)输出文本文件:打开输出文件用?$fopen 例如:integer out_ // out_file 是一个文件描述,需要定义为 integer 类型out_file = $fopen ( " cpu.data " ); // cpu.data 是需要打开的文件,也就是最终的输出文本设计中的信号值可以通过$fmonitor, $fdisplay,2. Verilog 和 Ncverilog 命令使用库文件或库目录ex). ncverilog -f run.f -v lib/lib.v -y lib2 +libext+.v //一般编译文件在 run.f 中, 库文件在 lib.v 中,lib2 目录中的.v 文件系统自动搜索使用库文件或库目录,只编译需要的模块而不必全部编译3.Verilog Testbench 信号记录的系统任务:1). SHM 数据库可以记录在设计仿真过程中信号的变化. 它只在 probes 有效的时间内记录你 set probe on 的信号的变化.ex). $shm_open("waves.shm"); //打开波形数据库$shm_probe(top, "AS"); // set probe on "top",第二个参数: A -- signals of the specific scrope S -- Ports of the specified scope and below, excluding library cellsC -- Ports of the specified scope and below, including library cellsAS -- Signals of the specified scope and below, excluding library cellsAC -- Signals of the specified scope and below, including library cells还有一个 M ,表示当前 scope 的 memories, 可以跟上面的结合使用, "AM" "AMS" "AMC"什么都不加表示当前 scope 的$shm_close //关闭数据库2). VCD 数据库也可以记录在设计仿真过程中信号的变化. 它只记录你选择的信号的变化.ex). $dumpfile("filename"); //打开数据库$dumpvars(1, top.u1); //scope = top.u1, depth = 1第一个参数表示深度, 为 0 时记录所有深度; 第二个参数表示 scope,省略时表当前的 scope.$ //depth = all scope = all$dumpvars(0); //depth = all scope = current$dumpvars(1, top.u1); //depth = 1 scope = top.u1$dumpoff //暂停记录数据改变 ,信号变化不写入库文件中$dumpon //重新恢复记录3). Debussy fsdb 数据库也可以记录信号的变化, 它的优势是可以跟 debussy 结合, 方便调试.如果要在 ncverilog 仿真时,记录信号, 首先要设置 debussy:a. setenv LD_LIBRARY_PATH :$LD_LIBRARY_PATH(path for debpli.so file (/share/PLI/nc_xl//nc_loadpli1))b. while invoking ncverilog use the +ncloadpli1 option.ncverilog -f run.f +debug +ncloadpli1=debpli:deb_PLIPtrfsdb 数据库文件的记录方法,是使用$fsdbDumpfile 和$fsdbDumpvars 系统函数, 使用方法参见 VCD注意: 在用 ncverilog 的时候,为了正确地记录波形 ,要使用参数: "+access+rw", 否则没有读写权限在记录信号或者波形时需要指出被记录信号的路径,如:tb.module.u1.clk.………………………………………………………………………………………………………关于信号记录的系统任务的说明:在 testbench 中使用信号记录的系统任务,就可以将自己需要的部分的结果以及波形文件记录下来(可采用 sigalscan 工具查看),适用于对较大的系统进行仿真,速度快,优于全局仿真。使用简单,在 testbench 中添加: initiaverilog系统函数
暂无评论,赶快抢占沙发吧。

我要回帖

更多关于 php 调用函数传递变量 的文章

 

随机推荐