FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

Diplomacyを使ってAXI4スレーブを接続する回路を作成する

Diplomacyのマスターとスレーブを作れるようになったので、次はAXI4を使ってみる。Diplomacyの部品にはAXI4の部品もそろっており、それ以外にもAHB、APBのDiplomacyの部品も用意されている。

rocketchip/src/main/scala
├── amba
│    ├── ahb
│    ├── apb
│    └── axi4
└── tilelink

それぞれのバスでどのような部品が用意されているのか、例えばAXI4の部品を除いてみる。

AsyncCrossing.scala
Buffer.scala
Bundles.scala
CrossingHelper.scala
Deinterleaver.scala
Delayer.scala
Filter.scala
Fragmenter.scala
IdIndexer.scala
Monitor.scala
Nodes.scala
Parameters.scala
Protocol.scala
RegisterRouter.scala
SRAM.scala
Test.scala
ToTL.scala
UserYanker.scala
Xbar.scala

この中で、AXI4RAMとTLToAXI(TileLinkからAXI4への変換)を使ってスレーブにAXI4のRAMを接続してみよう。

実装の方法はとても簡単で、これまで通りバスに対してTLToAXI4で変換用ブリッジを挿入して、その下にAXI4RAMを挿入する。

import freechips.rocketchip.tilelink._
import freechips.rocketchip.amba.axi4._  // AXI4のパッケージを挿入する。

class TLAXI4Slave(ramBeatBytes: Int, txns: Int)(implicit p: Parameters) extends LazyModule {
...
  val xbar      = LazyModule(new TLXbar)
  val slavereg0 = LazyModule(new TLRAM(AddressSet(0x000, 0x3ff), beatBytes = ramBeatBytes))
  // スレーブの一つはAXI4RAMとする。
  val slavereg1 = LazyModule(new AXI4RAM(AddressSet(0x400, 0x3ff), beatBytes = ramBeatBytes))
...
  slavereg0.node := xbar.node
  // TLToAXI4でTileLinkからAXI4に変換してRAMを接続する。
  slavereg1.node := TLToAXI4() := xbar.node

これで回路を生成してモデルを確認してみる。slavereg1とtl2axi4のノードの矢印の色が変わっていて、ここがAXI4であることを示している。

f:id:msyksphinz:20200116000246p:plain
AXI4スレーブを接続したDiplomacyノード接続関係図

この状態で合成してシミュレーションを行った。

f:id:msyksphinz:20200116000310p:plain
AXI4スレーブを接続したDiplomacyノード回路のRTLシミュレーション結果

正しく動作しているようだ。