0

LazyModule 和 LazyModuleImp 有什么区别?就像 Rocket-chip/doc 下的外交演示所说:The desired hardware for the module must be written inside LazyModuleImp. 但考虑以下代码:

class A(implicit p: Parameters) extends LazyModule {
  val b = LazyModule(new Leaf)
  val c = LazyModule(new Leaf)

  val input = b.input
  val output = c.output

  val bOutput = b.output.makeSink
  val cInput = BundleBridgeSource[Bool](() => Bool())
  c.input := cInput
  lazy val module = new LazyModuleImp(this) {
    cInput.bundle := bOutput.bundle
  }
}

:=是一个硬件操作,它出现在 LazyModuleImp 的内部和外部,那么应该在 LazyModuleImp 中放置哪些代码?

4

1 回答 1

1

考虑 LazyModule 的最佳方式(IMO)是 LazyModule 基本上有两个部分

  1. 非硬件实现(外部的一切LazyModuleImp)这是我们定义Nodes、解析参数、做任何人们认为是“软件”的地方
  2. 硬件实现(里面的一切LazyModuleImp) 这是我们创建实际硬件的地方。我们一般使用我们在外面解析的参数来构建一些硬件。

就外交而言,:=实际上是一种Node联系。您在其中连接两个外交节点。执行此连接时,您实际上是在“绘制”从一个节点到另一个节点的路径。在外交演示的情况下,您将连接AdderDriverNodeAdderNode. 这是在外部执行的,LazyModuleImp因为我们需要在构建硬件之前定义这个节点图。

例如,如果您查看AdderTestHarness,您可以在 之外看到以下内容LazyModuleImp

  // create edges via binding operators between nodes in order to define a complete graph
  drivers.foreach{ driver => adder.node := driver.node }

  drivers.zip(monitor.nodeSeq).foreach { case (driver, monitorNode) => monitorNode := driver.node }
  monitor.nodeSum := adder.node

在这里,我们将驱动程序连接到加法器,将驱动程序连接到监视器,然后将加法器连接到监视器。这些连接基于为每个节点定义的 Bundle 生成创建硬件。

所以我倾向于考虑LazyModules,一般来说,外交是一种创建硬件的两遍方法。第一步是定义硬件拓扑。这是在LazyModuleImp. 我将描述每个部分是如何连接的,并解析宽度、地址等参数。第二遍是实际的硬件生成。在这里,我的所有参数都应该被解析,并且我定义的硬件现在已经创建。

外交令人印象深刻,但可能很难掌握。特别是如果来自严格的硬件背景或严格的软件背景。它需要对某些软件范式如何工作以掌握参数/边缘分辨率的架构有深刻的理解,然后你就会遇到使用它来实际创建一些真实硬件的障碍。

于 2021-05-09T14:39:08.600 回答