verilog 任务和功能

任务和功能

•当同一代码在设计中多次使用时,使用任务和功能:

○ 减少代码量。

○ 便于维护。

•任务和功能必须在模块中声明和使用。标题包含以下参数:

○ 功能的输入参数(仅)。

○ 任务的输入/输出/inout参数。

•函数的返回值声明为有符号或无符号。内容类似于组合的内容总是块。

Tasks and Functions Examples
Filename: functions_1.v
//
// An example of a function in Verilog
//
// File: functions_1.v
//
module functions_1 (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;
begin
S = A ^ B ^ CIN;
COUT = (A&B) | (A&CIN) | (B&CIN);
ADD = {COUT, S};
end
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];
endmodule
Filename: task_1.v
In this coding example, the same functionality is described with a task.
// Verilog tasks
// tasks_1.v
//
module tasks_1 (A, B, CIN, S, COUT);
input [3:0] A, B;
input CIN;
output [3:0] S;
output COUT;
reg [3:0] S;
reg COUT;
reg [1:0] S0, S1, S2, S3;
task ADD;
input A, B, CIN;
output [1:0] C;
reg [1:0] C;
reg S, COUT;
begin
S = A ^ B ^ CIN;
COUT = (A&B) | (A&CIN) | (B&CIN);
C = {COUT, S};
end
endtask
always @(A or B or CIN)
begin
ADD (A[0], B[0], CIN, S0);
ADD (A[1], B[1], S0[1], S1);
ADD (A[2], B[2], S1[1], S2);
ADD (A[3], B[3], S2[1], S3);
S = {S3[0], S2[0], S1[0], S0[0]};
COUT = S3[1];
end
endmodule

使用递归任务和函数

Verilog-2001支持递归任务和函数。

•仅对自动关键字使用递归。

•递归次数会自动限制,以防止无休止的递归调用。这个默认值为64。

•使用-recursion_iteration_limit设置允许的递归调用数。

Example of Recursive Tasks and Functions
function automatic [31:0] fac;
input [15:0] n;
if (n == 1)
fac = 1;
else
fac = n * fac(n-1); //recursive function call
endfunction

使用常量函数和表达式

Vivado合成支持函数调用来计算常数值。常数假定为是十进制整数。

•以二进制、八进制、十进制或十六进制指定常量。

•要明确指定常量,请在它们前面加上适当的语法。

Example of Constant Functions
Filename: functions_contant.v
// A function that computes and returns a constant value
//
// functions_constant.v
//
module functions_constant (clk, we, a, di, do);
parameter ADDRWIDTH = 8;
parameter DATAWIDTH = 4;
input clk;
input we;
input [ADDRWIDTH-1:0] a;
input [DATAWIDTH-1:0] di;
output [DATAWIDTH-1:0] do;
function integer getSize;
input addrwidth;
begin
getSize = 2**addrwidth;
end
endfunction
reg [DATAWIDTH-1:0] ram [getSize(ADDRWIDTH)-1:0];
always @(posedge clk) begin
if (we)
ram[a] <= di;
end
assign do = ram[a];
endmodule

常量表达式示例

以下常量表达式表示相同的值。

•2010年4月

•4’012

•10年4月

•4英尺高

使用阻塞和非阻塞程序

作业

阻塞性和非阻塞性程序分配分别具有时间控制功能分配声明。

•磅号(#)和at号(@)是时间控制语句。

•这些语句会延迟执行后面的语句,直到指定的事件评估为真。

•对于合成,忽略磅(#)延迟。

Blocking Procedural Assignment Syntax Example One
reg a;
a = #10 (b | c);
Blocking Procedural Assignment Syntax Example Two (Alternate)
if (in1) out = 1'b0;
else out = in2;

此分配阻止当前进程在继续执行其他语句同时,主要用于仿真。

有关Vivado模拟的Verilog格式的更多信息,请参阅Vivado Design Suite User指南:逻辑仿真(UG900)。

非阻塞过程赋值语法示例一

variable <= @(posedge_or_negedge_bit) expression;

非阻塞赋值在语句执行时计算表达式,并允许

同一进程中的其他语句同时执行。变量发生变化

仅在指定的延迟之后。

非阻塞性程序分配示例二

此编码示例显示了如何使用非阻塞过程分配。

if (in1) out <= 1'b1;
else out <= in2;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cckkppll

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值