1

我有一个多核火箭芯片系统。但是,我希望这些火箭瓦片中的一个与其他瓦片异步。

我们正在尝试通过以下方式做到这一点:

class WithTilesCrossing extends Config((site, here, up) => {
  case RocketCrossingKey => site(RocketTilesKey).head.hartId match {
    case 2 => up(RocketCrossingKey) map { r =>
      r.copy(crossingType = AsynchronousCrossing(),
             master = TileMasterPortParams())}
    case _ => up(RocketCrossingKey) map { r =>
      r.copy(crossingType = SynchronousCrossing(BufferParams(1)),
             master = TileMasterPortParams())}
  }
})

所以这就是 harthartId = 2应该是异步的,其余的应该是同步的。

以上,当添加到我们的配置中时,似乎没有做任何事情。

但是,如果我使用WithAsynchronousRocketTilesfromsrc/main/scala/subsystem/Config.scala那么我会将所有图块转换为异步。

那么,我将如何只做一个瓷砖?

根据杰克的建议更新:

直接尝试该代码给出了:

[error] Config.scala:189:16: not found: value crossingType
[error]         r.copy(crossingType = AsynchronousCrossing(),
[error]                ^
[error] Config.scala:190:11: not found: value master
[error]           master = TileMasterPortParams())
[error]           ^
[error] Config.scala:192:16: not found: value crossingType
[error]         r.copy(crossingType = SynchronousCrossing(BufferParams(1)),
[error]                ^
[error] Config.scala:193:11: not found: value master
[error]           master = TileMasterPortParams())
[error]           ^
[error] four errors found

这是令人惊讶的。所以我想我可能需要做这up()件事并尝试了这个:

  case RocketCrossingKey => site(RocketTilesKey).map { r =>
    r.hartId match {
      case 2 => up(RocketCrossingKey) map { k => k.copy(crossingType = AsynchronousCrossing(), master = TileMasterPortParams()) }
      case _ => up(RocketCrossingKey) map { k => k.copy(crossingType = SynchronousCrossing(BufferParams(1)), master = TileMasterPortParams()) }
    }
  }

但是,这会导致 elab 错误:

[error] Caused by: java.lang.ClassCastException: scala.collection.immutable.$colon$colon cannot be cast to freechips.rocketchip.subsystem.RocketCrossingParams
[error]         at freechips.rocketchip.subsystem.HasRocketTiles.$anonfun$rocketTiles$1(RocketSubsystem.scala:41)
[error]         at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:234)
[error]         at scala.collection.immutable.List.foreach(List.scala:389)
[error]         at scala.collection.TraversableLike.map(TraversableLike.scala:234)
[error]         at scala.collection.TraversableLike.map$(TraversableLike.scala:227)
[error]         at scala.collection.immutable.List.map(List.scala:295)
[error]         at freechips.rocketchip.subsystem.HasRocketTiles.$init$(RocketSubsystem.scala:41)
[error]         at freechips.rocketchip.subsystem.RocketSubsystem.<init>(RocketSubsystem.scala:70)

所以仍然坚持如何RocketCrossingParams在每个瓷砖的基础上修改这个原件并返回它。

4

1 回答 1

1

查看 的定义RocketCrossingKey

case object RocketCrossingKey extends Field[Seq[RocketCrossingParams]](List(RocketCrossingParams()))

您会注意到类型是Seq[RocketCrossingParams]. 这意味着(尽管我可能是错的),我们RocketCrossingParams每个瓦片有 1 个。在您的代码片段中,您只查看第一个 this Seq(通过.head)检查它hartId是否等于 2,然后如果是,则迭代所有RocketCrossingKeys 并将它们设置为AsynchronousCrossing.

尝试以下类似的方法,我们对其进行迭代并仅将索引替换为hartId == 2

case RocketCrossingKey => site(RocketTilesKey).map { r =>
  if (r.hartId == 2) { // or you can match on it, whatever
    r.copy(crossingType = AsynchronousCrossing(),
           master = TileMasterPortParams())
  } else {
    r.copy(crossingType = SynchronousCrossing(BufferParams(1)),
           master = TileMasterPortParams())
  }
}

编辑:RocketCrossingKey我错过了两者兼有的事实RocketTilesKey

所以这里的问题是有两个parallelSeq的参数:

  • RocketTilesKey这给了我们RocketTileParams,每个瓷砖 1
  • RocketCrossingKey这给了我们RocketCrossingParams,每个瓷砖 1或者如果只有 1,它适用于所有

也有可能没有RocketTileParamscontains hartId == 2,所以让我们适当地处理一切:

  case RocketCrossingKey =>
    val tileParams = site(RocketTilesKey)
    val crossingParams = site(RocketCrossingKey)

    // One might assume hartId 2 == index 2 but that may not be the case
    // Also there may not even *be* a tile with hartId == 2
    val indexOfHartId2: Option[Int] =
      tileParams.zipWithIndex.collectFirst { case (r, idx) if r.hartId == 2 => idx }

    indexOfHartId2.map { idx =>
      // This duplicates logic from HasTiles.perTileOrGlobalSetting
      // If there's only 1, it applies to all
      val crossings = site(RocketCrossingKey) match {
        case Seq(one) => List.fill(tileParams.size)(one)
        case many     => many
      }
      // Back to the original answer using the proper index for hartId == 2
      crossings.zipWithIndex.map { case (c, i) =>
        if (i == idx) { // or you can match on it, whatever
          c.copy(crossingType = AsynchronousCrossing(),
                 master = TileMasterPortParams())
        } else {
          c.copy(crossingType = SynchronousCrossing(BufferParams(1)),
                 master = TileMasterPortParams())
        }
      }
    }.getOrElse(crossingParams) // If we don't even have hardId == 2, return original value
于 2020-03-20T17:20:25.783 回答