Chisel makeSink方法为外围设备制作IOs的目的是什么

Chisel makeSink方法为外围设备制作IOs的目的是什么,chisel,rocket-chip,Chisel,Rocket Chip,我在跟踪一些为火箭飞船添加外围设备的例子。 我使用了sifive块作为参考 下面是他们I2C示例中的一个示例(我希望可以在这里发布) 我理解makeIO步骤,即获取一个包并在其上应用IO,但不理解makeSink步骤。 他们为什么要这样做,难道makeIO还不够吗 我不是火箭芯片外交方面的专家,但从代码上看,我认为makeIO和makeSink做了根本不同的事情 makeIO获取BundleBridgeSource并具体化凿子模块实现中用于驱动该源的端口。在BundleBrigeSink上也有相

我在跟踪一些为火箭飞船添加外围设备的例子。 我使用了sifive块作为参考

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

我理解makeIO步骤,即获取一个包并在其上应用IO,但不理解makeSink步骤。
他们为什么要这样做,难道makeIO还不够吗

我不是火箭芯片外交方面的专家,但从代码上看,我认为
makeIO
makeSink
做了根本不同的事情

makeIO
获取
BundleBridgeSource
并具体化凿子模块实现中用于驱动该源的端口。在
BundleBrigeSink
上也有相同的方法。我相信这种方法是你在发电机的实际凿子部分(与外交部分相反)中选择束桥的任意一侧并与之连接的方法

makeSink
BundleBridgeSource
转换为
BundleBridgeSink
。它并没有实现凿子端口,而是停留在外交世界而不是凿子世界

在您包含的
I2C
示例中,请注意带有
makeSink
的部件是如何混合到扩展
BaseSubsystem
的特性中的,这是一种外交手段。另一方面,
haspheryi2cmoduleimp
具有
makeIO
扩展的
LazyModuleImp
是凿子部分。思考这个问题的一种方式是对同一件事有两种不同的“观点”。凿子和外交使用不同的对象,因此
i2cNodes
(外交)与
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")) }
}