1

我正在关注一些向火箭芯片添加外围设备的示例。我使用了五个块作为参考。

下面是他们的 I2C 示例中的一个示例(我希望可以在这里发布)

case object PeripheryI2CKey extends Field[Seq[I2CParams]]

trait HasPeripheryI2C { this: BaseSubsystem =>
  val i2cNodes =  p(PeripheryI2CKey).map { ps =>
    I2C.attach(I2CAttachParams(ps, pbus, ibus.fromAsync)).ioNode.makeSink()
  }
}

trait HasPeripheryI2CBundle {
  val i2c: Seq[I2CPort]
}

trait HasPeripheryI2CModuleImp extends LazyModuleImp with HasPeripheryI2CBundle {
  val outer: HasPeripheryI2C
  val i2c  = outer.i2cNodes.zipWithIndex.map  { case(n,i) => n.makeIO()(ValName(s"i2c_$i")) }
}

我了解 makeIO 步骤,该步骤是打包并在其上应用 IO,但不了解 makeSink 步骤。他们为什么要做这一步,makeIO还不够吗?

4

1 回答 1

1

我不是火箭芯片外交方面的专家,但从代码的角度来看,我的想法makeIOmakeSink做的事情根本不同。

makeIO在 Chisel Module 实现中获取BundleBridgeSource并实现端口以驱动该源。上也有同样的方法BundleBrigeSink。我相信这种方法是您在 Bundle 桥的任一侧并在生成器的实际 Chisel 部分(而不是外交部分)中与其接口的方式。

makeSink把 aBundleBridgeSource变成 a BundleBridgeSink。它不会实现 Chisel 端口,它停留在外交世界而不是 Chisel 世界。

I2C您所包含的示例中,请注意带有的部分makeSink是如何混合到扩展的东西中的特征BaseSubsystem,它是外交的。另一方面,HasPeripheryI2CModuleImp它具有makeIO延伸LazyModuleImp部分,即 Chisel 部分。考虑这一点的一种方法是对同一事物的两种不同“观点”。凿子和外交使用不同的对象,因此i2cNodes(外交)与i2c(凿子)。

于 2019-06-03T01:27:22.480 回答