【发布时间】:2017-10-18 15:43:09
【问题描述】:
在我的 FPGA/Verilog 课程中,我的教授刚刚复习了函数。
他是说在函数中,您按程序编写代码。然后,当您要调用该函数时,您可以在 always 块中调用它(即程序上),也可以使用 assign 语句调用它。
对我来说,如何用过程代码编写函数并随后被连续调用是没有意义的。
如果有人对这个(可能)基本问题有任何见解,非常感谢。
【问题讨论】:
在我的 FPGA/Verilog 课程中,我的教授刚刚复习了函数。
他是说在函数中,您按程序编写代码。然后,当您要调用该函数时,您可以在 always 块中调用它(即程序上),也可以使用 assign 语句调用它。
对我来说,如何用过程代码编写函数并随后被连续调用是没有意义的。
如果有人对这个(可能)基本问题有任何见解,非常感谢。
【问题讨论】:
它与组合逻辑块几乎完全相同。你这样写,但它被合成为完全不同的东西。考虑以下几点:
always @* begin
a = b + c;
d = b + a;
end
always @(posedge clk) begin
out <= d + in;
end
这与以下内容完全相同:
function integer calc_d(integer b, integer c) begin
integer a;
integer d;
a = b + c;
d = b + a;
calc_d = d;
end
endfunction
always @(posedge clk) begin
out <= calc_d(b, c) + in;
end
【讨论】:
在 Verilog 或任何其他事件驱动的模拟中没有 continuous 这样的东西。所有行为都是由离散事件驱动的,这意味着信号改变了它的值,或者等待一段离散的时间过去。
Verilog 中的连续赋值只是定义表达式的一种方式,这样当 RHS 表达式的任何操作数发生变化时,表达式都会被计算并将其结果传播到 LHS 目标。任何逻辑或算术表达式都可以包含函数调用。
【讨论】:
返回值的函数(非 void 函数)在 verilog 中用作表达式的操作数。它封装了一个verilog表达式,该表达式可以由函数中的多个语句组成。因此,它可以在任何可以使用表达式的地方使用。程序块和连续赋值语句就是这样的地方。
连续赋值术语是一个历史术语,其目的是将值驱动到网络中(如果输入表达式值发生变化,则不断更改网络的值)。因此,如果在 rhs 中使用一个函数,它只是根据其输入提供值计算。
所以,这里有一个例子:
function automatic reg[3:0] sum (reg[3:0] a, reg[3:0] b);
sum = a + b;
endfunction // b
reg [3:0] r;
wire [3:0] w;
// use function in the procedural block
always @*
r = sum(a, b);
// use function in the continuous assignment
assign w = sum(a,b);
【讨论】: