recursion - Verilog中可以递归实例化吗?

标签 recursion verilog system-verilog

有些问题会导致递归解决方案。 Verilog中可以递归实例化吗?模块是否可以实例化自己?

最佳答案

有些问题会导致递归解决方案。求一组数的最小值就是这样的工作:基本上,一组数的最小值是前半部分的最小值和后半部分的最小值中的最小值。

取一组数字。将该组分成两半。找出每一半的最小值。整个集合的最小值是每一半的最小值中的较小者。你如何找到每一半的最小值?好吧,每一半都是一组数字,所以对于每一半,回到本段的开头......

它是递归的。最终,您会得到一组一个数字。该集合的最小值显然是那个数字,所以问题变得微不足道,这就是递归解决问题的关键。那么,我们如何在硬件中使用递归实例化来做到这一点呢?

我们需要一个具有 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 的单个向量输入。您可以在代码中看到这一点。这使代码复杂化,因为必须进行计算以索引该输入向量的位。

所以,我们代码的核心是生成 block 。在其中,我们测试参数 N 以查看我们正在处理多少个输入。如果我们处理一个输入,那么工作很简单:最小值正好等于那个输入。否则,我们将处理多个输入,因此将一半的输入发送到 MinN 模块的一个实例,其余的发送到另一个实例。在生成 block 之外,我们通过比较每个子 block 的输出来确定总体最小值。

当然,这在 SystemVerilog 中是可能的,因为 Verilog 是 SystemVerilog 的一个子集。但在 SystemVerilog 中实际上会更容易,因为您可以使用阵列端口。

这是可以合成的。

关于recursion - Verilog中可以递归实例化吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55296169/

相关文章:

Scala 使用可变变量来实现其 api

syntax-error - 一个简单的增量寄存器

verilog - 如何在系统verilog中使用枚举中的算术表达式?

syntax-error - UVM 序列体任务给出未知的编译错误

system-verilog - 如何在 systemverilog 断言中使用整个运算符

php - 如何通过mysql表跟踪parent_id?

c++ - 字符串中最长连续字符的长度

java - 从伪代码(NTRUEncrypt)实现递归

verilog - VERILOG 中的随机 0、1、-1

verilog - 在测试台文件中解释这个语法错误