一些问题导致他们自己采取递归解决方案。在Verilog中可以进行递归实例化吗?模块可以实例化自己吗?
答案 0 :(得分:3)
一些问题导致他们自己采取递归解决方案。找到一组数字的最小值就是这样的工作:基本上,一组数字的最小值是前一半的最小值和后一半的最小值。
采用一组数字。将其分成两半。找出每一半的最小值。整个集合中的最小值是每一半最小值中的较小者。您如何找到每一半的最小值?好吧,每一半都是一组数字,所以对于每一半,请回到本段的开头...
它是递归的。最终,您得到一组一个数字。该集合的最小值显然是该数字,因此问题变得无关紧要,这就是递归解决问题的关键。那么,我们如何在硬件中使用递归实例化呢?
我们需要一个带有N个输入的可参数化模块。在模块内部,如果N大于2,我们实例化模块的2个副本,并将一半的输入路由到一个,将一半的输入路由到另一个。然后,模块的输出是这两个子模块中较小的输出。但是,如果N为1,我们只需将输入直接连接到输出即可。就是这样。
要在Verilog中执行此操作,我们将不得不使用参数,并且考虑到我们可能实例化某些东西或可能不实例化某些东西,因此会生成语句。
因此,这是此算法的Verilog实现:
module MinN #(parameter N = 8, W=16) (input [(N*W)-1:0] I, output [W-1:0] Min);
wire [W-1:0] Min1, Min2;
generate
if (N == 1)
begin : Neq1
assign Min1 = I;
assign Min2 = I;
end
else
begin : Ngt1
MinN #(.N(N-(N/2)), .W(W)) M1 (.I( I[(N*W)-1:((N/2)*W)]), .Min(Min1));
MinN #(.N(N/2), .W(W)) M2 (.I(I[((N/2)*W)-1: 0]), .Min(Min2));
end
endgenerate
assign Min = (Min1 < Min2) ? Min1 : Min2;
endmodule
有两个参数:N是输入的数量,W是输入的宽度。不幸的是,这很复杂:Verilog不允许使用阵列端口。相反,我们必须使用宽度N * W的单个矢量输入。您可以在代码中看到这一点。这使代码变得复杂,因为随后必须进行计算才能索引此输入向量的位。
因此,我们代码的核心是generate块。在其中,我们测试参数N来查看我们正在处理多少输入。如果我们要处理一个输入,那么工作就很容易:最小值等于那个输入。否则,我们将处理一个以上的输入,因此将一半的输入发送到MinN模块的一个实例,将其余的发送到另一个实例。在生成块之外,我们通过比较每个子块的输出来确定总体最小值。
当然,这在SystemVerilog中是可能的,因为Verilog是SystemVerilog的子集。但这实际上在SystemVerilog中会更容易,因为允许使用阵列端口。
这是可以综合的。