makeSink方法为外围设备创建IO的目的是什么

时间:2019-06-03 01:09:35

标签: chisel rocket-chip

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

下面是他们的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还不够?

1 个答案:

答案 0 :(得分:1)

我不是火箭芯片外交方面的专家,但我看了一眼代码,认为makeIOmakeSink做的事情根本不同。

makeIO使用BundleBridgeSource并在凿子模块实现中实现端口以驱动该源。 BundleBrigeSink有相同的方法。我相信,这种方法是您将Bundle桥的任一侧作为接口并在生成器的实际凿子部分(而不是外交部分)与之交互的方式。

makeSinkBundleBridgeSource变成BundleBridgeSink。它并未实现凿子港口,而是停留在外交世界而不是凿子世界。

在您包括的I2C的示例中,请注意带有makeSink的部分是如何融合到扩展BaseSubsystem的事物中的,这是外交的特征。另一方面,具有HasPeripheryI2CModuleImp的{​​{1}}扩展了凿子部分的makeIO。考虑这一点的一种方法是对同一事物的两种不同“观点”。凿子和外交使用不同的对象,因此LazyModuleImp(外交)与i2cNodes(凿子)。