Verilog学习之路(12)— 任务和函数
一、前言
在VerilogHDL中提供了任务和函数,可以将较大的行为级设计划分为较小的代码段,允许设计者将需要在多个地方重复使用的相同代码提取出来,编写成任务和函数,这样可以使代码更加简洁和易懂。
任务和函数的区别如下所示:
二、任务
如下为一个交通灯控制任务的实例:
module traffic_tb;
reg red, amber, green, clk;
reg [2:1] order;
parameter ON=1, OFF=0, RED_TICS=35, AMBER_TICS=3, GREEN_TICS=20;
// clk generate
always begin
#100 clk = 0;
#100 clk = 1;
end
// task define
task light;
output r;
output a;
output g;
input [31:0] tic_time;
input [2:1] order;
begin
r = OFF; g = OFF; a = OFF;
case(order)
2'b01: r = ON;
2'b10: g = ON;
2'b11: a = ON;
default:{r, g, a} = 3'b111;
endcase
repeat(tic_time) @(posedge clk);
end
endtask
// initial the light
initial begin
order = 2'b00;
light(red, amber, green, 0, order);
end
always begin
order = 2'b01;
light(red, amber, green, RED_TICS, order); // turn on the red light
order = 2'b10;
light(red, amber, green, AMBER_TICS, order); // turn on the amber light
order = 2'b11;
light(red, amber, green, GREEN_TICS, order); // turn on the green light
end
endmodule
仿真运行可以看到波形如下所示,从中我们可以看到,输出变量是在任务执行完成后进行赋值的,并不会跟随任务内变量的变化而变化。
二、函数
如下以阶乘运算为例说明函数的使用
module tryfact_tb;
function [31:0] factorial;
input [3:0] operand;
reg [3:0] index;
begin
factorial = 1;
for(index = 1; index <= operand; index = index+1)
factorial = factorial * index;
end
endfunction
reg [31:0] result;
reg [3:0] n;
initial begin
result = 1;
for (n = 1; n <= 9; n=n+1) begin
result = factorial(n);
$display("n = %d, result = %d", n, result);
end
end
endmodule
其仿真运行结果如下所示