微信公众号获取更多FPGA相关源码:

1.Verilog的任务及函数
结构化设计是将任务分解为较小的,更易管理的单元,并将可重用代码进行封装。这通过将设计分成模块,或任务和函数实现。
任务(task)
- 通常用于调试,或对硬件进行行为描述
- 可以包含时序控制(#延迟,@, wait)
- 可以有 input,output,和inout参数
- 可以调用其他任务或函数
函数(function)
- 通常用于计算,或描述组合逻辑
- 不能包含任何延迟;函数仿真时间为0
- 只含有input参数并由函数名返回一个结果
- 可以调用其他函数,但不能调用任务
注意事项:
- 任务和函数必须在module内调用
- 在任务和函数中不能声明wire
- 所有输入/输出都是局部寄存器
- 任务/函数执行完成后才返回结果。
- 例如,若任务/函数中有forever语句,则永远不会返回结果
2.任务主要特点:
- 任务可以有input,output 和 inout参数。
- 传送到任务的参数和与任务I/O说明顺序相同。尽管传送到任务的参数名称与任务内部I/O说明的名字可以相同,但在实际中这通常不是一个好的方法。参数名的唯一性可以使任务具有好的模块性。
- 可以在任务内使用时序控制。
- 在Verilog中任务定义一个新范围(scope)
- 要禁止任务,使用关键字disable 。
易错点:
- 从代码中多处调用任务时要小心。因为任务的局部变量只有一个拷贝,并行调用任务可能导致错误的结果。在任务中使用时序控制时这种情况时常发生。
- 在任务或函数中引用调用模块的变量时要小心。如果想使任务或函数能从另一个模块调用,则所有在任务或函数内部用到的变量都必须列在端口列表中。
3.任务举例
- 下面的任务中含有时序控制和一个输入,并引用了一个module变量,但没有output、inout、内部变量,也不显示任何结果。
- 时序控制中使用的信号(例如clk)一定不能作为任务的输入,因为输入值只向该任务传送一次。
module top;
reg clk, a, b;
DUT u1 (out, a, b, clk);
always #5 clk = !clk;
task neg_clocks;
input [31:0] number_of_edges;
repeat( number_of_edges) @( negedge clk);
endtask
initial begin
clk = 0; a = 1; b = 1;
neg_clocks(3); // 任务调用
a = 0; neg_clocks (5);
b = 0;
end
endmodule
- 下面的任务中有输入,输出,时序控制和一个内部变量,并且引用了一个module变量。但没有双向端口,也没有显示。
- 任务调用时的参数按任务定义的顺序列出。
module mult (clk, a, b, out, en_mult);
input clk, en_mult;
input [3: 0] a, b;
output [7: 0] out;
reg [7: 0] out;
always @( posedge clk)
multme (a, b, out); // 任务调用
task multme; // 任务定义
input [3: 0] xme, tome;
output [7: 0] result;
wait (en_mult)
result = xme * tome;
endtask
endmodule
微信公众号获取更多FPGA相关源码:

2477

被折叠的 条评论
为什么被折叠?



