以下の内容はhttps://msyksphinz.hatenablog.com/entry/2020/03/09/040000より取得しました。


Diplomacyを使ってOCPバスを作成する(14. Xbarの理解)

DiplomacyのXbarについて理解を深めるためにソースコードを読んでみよう。とりまOCPの実装をしたいのだが、何せ内部を理解しないとどうも改造できそうにない気がしてきた。どうにかしてソースコードを理解しなければ。

NexusNodeについて

NexusNodeは複数のSlaveと複数のMasterを接続することのできるノードだ。接続中に、ノードの信号情報を変更することもできる。

f:id:msyksphinz:20200305001925p:plain
  val node = TLNexusNode(
    clientFn  = { seq =>
      seq(0).copy(
        minLatency = seq.map(_.minLatency).min,
        clients = (TLXbar.mapInputIds(seq) zip seq) flatMap { case (range, port) =>
          port.clients map { client => client.copy(
            sourceId = client.sourceId.shift(range.start)
          )}
        }
      )
    },
    managerFn = { seq =>
      val fifoIdFactory = TLXbar.relabeler()
      seq(0).copy(
        minLatency = seq.map(_.minLatency).min,
        endSinkId = TLXbar.mapOutputIds(seq).map(_.end).max,
        managers = seq.flatMap { port =>
          require (port.beatBytes == seq(0).beatBytes,
            s"Xbar data widths don't match: ${port.managers.map(_.name)} has ${port.beatBytes}B vs ${seq(0).managers.map(_.name)} has ${seq(0).beatBytes}B")
          val fifoIdMapper = fifoIdFactory()
          port.managers map { manager => manager.copy(
            fifoId = manager.fifoId.map(fifoIdMapper(_))
          )}
        }
      )
    })

The clientFn is a function that takes the TLClientPortParameters of the input as an argument and returns the corresponding parameters for the output. The managerFn takes the TLManagerPortParameters of the output as an argument and returns the corresponding parameters for the input.

clientFnTLClientPortParameterを引数に取る関数で、出力に対して相当するパラメータを返す。

managerFnTLManagerPortParametersを引数に取る関数で、入力に対して相当するパラメータを返す。

例えば、2つのMasterを接続した場合には以下のようにsourceIdが設定された。

sourceId = IdRange(1,2)
sourceId = IdRange(0,1)

次に、requestAIOについて調べていく。Xbarには、リクエストがどのターゲットに対してリクエストを発行しているのかを示すrequestAIOなどという信号が定義されている。

    val requestAIO = (connectAIO zip addressA) map { case (c, i) => outputPortFns(c).map { o => unique(c) || o(i) } }
    val requestCIO = (connectCIO zip addressC) map { case (c, i) => outputPortFns(c).map { o => unique(c) || o(i) } }
    val requestBOI = out.map { o => inputIdRanges.map  { i => i.contains(o.b.bits.source) } }
    val requestDOI = out.map { o => inputIdRanges.map  { i => i.contains(o.d.bits.source) } }
    val requestEIO = in.map  { i => outputIdRanges.map { o => o.contains(i.e.bits.sink) } }

requestAIOは、縦方向がマスター側、横方向がスレーブ側となる。これはリクエストの発行状況を示しているのか?

                  slave
                ~~~~~~~~~
requestAIO[0] = 1,1,1,1,1, |
requestAIO[1] = 1,1,1,1,1, |
requestAIO[2] = 1,1,1,1,1, | masters
requestAIO[3] = 1,1,1,1,1, |

requestDOIは、逆に縦方向がスレーブ側、横方向がマスター側となる。これはレスポンスの発行状況を示しているのか?

                 master
               ~~~~~~~~
requestDOI[0] = 1,0,0,0, |
requestDOI[1] = 0,0,0,1, |
requestDOI[2] = 0,0,0,1, | slave
requestDOI[3] = 0,0,0,1, |
requestDOI[4] = 0,0,0,1, |



以上の内容はhttps://msyksphinz.hatenablog.com/entry/2020/03/09/040000より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14