文章目录
- 任务
- 任务定义
- 任务调用
- 函数
- 函数说明部分
- 函数调用
- 值变转储文件
任务
一个任务就像一个过程,它可以从描述的不同位置执行共同的代码段。共同的代码段用任务定义编写成任务,这样它就能够从设计描述的不同位置通过任务调用被调用。任务可以包含时序控制,即时延控制,并且任务也能调用其它任务和函数。
任务定义
任务定义的形式如下:
task task_id;[declarations]procedural_statement
endtask
任务可以没有或有一个或多个参数。值通过参数传入和传出任务。除输入参数外(参数从任务中接收值),任务还能带有输出参数(从任务中返回值)和输入输出参数。任务的定义在模块说明部分中编写。例如:
module Has_Task;parameter MAXBITS = 8;task Reverse_Bits;input[MAXBITS-1:0] Din;output[MAXBITS-1:0] Dout;integer K;beginfor(K=0; K<MAXBITS; K=K+1)Dout[MAXBITS-K] = Din[K]endendtask
endmodule
任务的输入和输出在任务开始处声明。这些输入和输出的顺序决定了它们在任务调用中的顺序。
任务调用
一个任务由任务调用语句调用。任务调用语句给出传入任务的参数值和接收结果的变量值。任务调用语句是过程性语句,可以在 always
语句或 initial
语句中使用。形式如下:
task_id[(expr1, expr2, ..., exprN)];
任务调用语句中参数列表必须与任务定义中的输入、输出和输入输出参数说明的顺序匹配。此外,参数要按值传递,不能按地址传递。下面是调用任务 Reverse_Bits
的实例:
reg[MAXBITS-1:0] Reg_X, New_Reg;
Reverse_Bits(Reg_X, New_Reg)
注意因为任务能够包含定时控制,任务可在被调用后再经过一定时延才返回值。因为任务调用语句是过程性语句,所以任务调用中的输出和输入输出参数必须是寄存器类型的。
函数
函数,如同任务一样,也可以在模块不同位置执行共同代码。函数与任务的不同之处是函数只能返回一个值,它不能包含任何时延或时序控制(必须立即执行),并且它不能调用其它的任务。此外,函数必须带有至少一个输入,在函数中允许没有输出或输入输出说明。函数可以调用其它的函数。
函数说明部分
函数说明部分可以在模块说明中的任何位置出现,函数的输入是由输入说明指定,形式如下:
function[range] function_id;input_declarationother_declarationsprocedural_statament
endfunction
函数实例如下:
module Function_Exampleparameter MAXBITS = 8;function[MAXBITS-1:0] Reverse_Bits;input[MAXBITS-1:0] Din;integer K;beginfor(K=0; K<MAXBITS; K=K+1)Reverse_Bits[MAXBITS-K] = Din[K];endendfunction
endmodule
函数定义在函数内部隐式地声明一个寄存器变量,该寄存器变量与函数同名并且取值范围相同。函数通过在函数定义中显式地对该寄存器赋值来返回函数值。对这一寄存器的赋值必须出现在函数定义中。
函数调用
函数调用是表达式的一部分。形式如下:
func_id(expr1, expr2,..., exprN)
以下是函数调用的例子:
reg[MAXBITS-1:0] New_Reg, Reg_X;
New_Reg = Reverse_Bits(Reg_X);
与任务相似,函数定义中声明的所有局部寄存器都是静态的,即函数中的局部寄存器在函数的多个调用之间保持它们的值。
值变转储文件
值变转储(VCD)文件包含设计中指定变量取值变化的信息。它的主要目的是为其它后处理工具提供信息。
下面的系统任务用于创建和将信息导入 VCD 文件:
$dumpfile
:本系统任务指定转储文件名,例如
$dumpfile("uart.dump");
dumpvars
:本系统任务指定哪些变量值变化时转储进转储文件。
dumpoff
:本系统任务促使转储任务被挂起。
dumplimit
:本系统任务为 VCD 文件指定最大长度(字节)。转储在达到此界限时停止。
dumpflush
:本系统任务刷新操作系统 VCD 文件缓冲区中的数据,将数据存到 VCD 文件中。执行此系统任务后,转储任务处于唤醒状态。
下面是在 5~12 之间计数的可逆计数器的例子:
module CountUpDown(Clk, Count, Up_Down);input Clk, Up_Down;output[0:3] Count;reg[0:3] Count;initial Count = 'd5;always@(posedge Clk) beginif(Up_Down)beginCount = Count + 1;if(Count > 12)Count = 12endelsebeginCount = Count - 1;if(Count < 5)Count = 5;endend
endmodulemodule Test;reg Clock, UpDn;wire[0:3] Cnt_Out;parameter ON_DELAY = 1, OFF_DELAY = 2;CountUpDown C1(Clock, Cnt_Out, UpDn);always beginClock = 1;#ON_DELAYClock = 0;#OFF_DELAY;endinitial beginUpDn = 0;#50 UpDn = 1;#100 $dumpflush;$stop;endinitial begin$dumpfile("count.dump");$dumplimit(4096);$dumpvars(0, Test);$dumpvars(0, C1.Count, C1.Clk, C1.Up_Down);end
endmodule