次に作るのは、TLXbarを使って2つのスレーブを使ったデザインだ。2つのスレーブを接続することで、例えば2つのRAMを使ってスレーブに接続できるようになる。
ターゲット回路
例えば、以下のようなデザインを作成した。
class TLTwoRAM(ramBeatBytes: Int, txns: Int)(implicit p: Parameters) extends LazyModule { val pusher = LazyModule(new TLPatternPusher("pat1", Seq( new WritePattern(0x100, 0x2, 0x012345678L), new WritePattern(0x500, 0x2, 0x0abcdef01L), new ReadExpectPattern(0x100, 0x2, 0x012345678L), new ReadExpectPattern(0x500, 0x2, 0x0abcdef01L) ))) val model = LazyModule(new TLRAMModel("SRAMSimple")) val xbar = LazyModule(new TLXbar) val ram0 = LazyModule(new TLRAM(AddressSet(0x0, 0x3ff), beatBytes = ramBeatBytes)) val ram1 = LazyModule(new TLRAM(AddressSet(0x400, 0x3ff), beatBytes = ramBeatBytes)) xbar.node := model.node := pusher.node ram0.node := xbar.node ram1.node := xbar.node lazy val module = new LazyModuleImp(this) with UnitTestModule { pusher.module.io.run := true.B io.finished := pusher.module.io.done } }
これは、xbarを通じて1つのマスターに対して2つのスレーブを接続している。2つのRAMのアドレスマップを以下のように構成する。
0x000 - 0x3ff
0x400 - 0x7ff
この時のPatternPusherは以下のようにパタンを挿入する。
WritePattern
: 0x100に対してサイズ22バイトの書き込み 0x12345678 を行う。WritePattern
: 0x500に対してサイズ22バイトの書き込み 0xabcdef01 を行う。ReadExpectPattern
: 0x100に対してサイズ22バイトの読み込み操作を行い、想定するデータは0x12345678である。ReadExpectPattern
: 0x500に対してサイズ22バイトの読み込み操作を行い、想定するデータは0xabcdef01である。
実行結果
波形を取った結果、以下のようになった。無事に2つのRAMにアクセスしていることが確認できる。
TileLinkのノード関係図
ノード関係図は正常に作成されている。
2マスター2スレーブのTileLinkバスを作成する
次に、複数マスター・複数スレーブの構成を作成してみる。
class TLManyMasterManySlave(ramBeatBytes: Int, txns: Int)(implicit p: Parameters) extends LazyModule { val pusher0 = LazyModule(new TLPatternPusher("pat1", Seq( new WritePattern(0x100, 0x2, 0x012345678L), new WritePattern(0x500, 0x2, 0x0abcdef01L), new ReadExpectPattern(0x100, 0x2, 0x012345678L), new ReadExpectPattern(0x500, 0x2, 0x0abcdef01L) ))) val pusher1 = LazyModule(new TLPatternPusher("pat1", Seq( new WritePattern(0x200, 0x2, 0x012345678L), new WritePattern(0x600, 0x2, 0x0abcdef01L), new ReadExpectPattern(0x200, 0x2, 0x012345678L), new ReadExpectPattern(0x600, 0x2, 0x0abcdef01L) ))) val model0 = LazyModule(new TLRAMModel("SRAMSimple")) val model1 = LazyModule(new TLRAMModel("SRAMSimple")) val xbar = LazyModule(new TLXbar) val ram0 = LazyModule(new TLRAM(AddressSet(0x0, 0x3ff), beatBytes = ramBeatBytes)) val ram1 = LazyModule(new TLRAM(AddressSet(0x400, 0x3ff), beatBytes = ramBeatBytes)) xbar.node := model0.node := pusher0.node xbar.node := model1.node := pusher1.node ram0.node := xbar.node ram1.node := xbar.node lazy val module = new LazyModuleImp(this) with UnitTestModule { pusher0.module.io.run := true.B pusher1.module.io.run := true.B io.finished := pusher0.module.io.done && pusher1.module.io.done } }
これでRTLシミュレーションを実行する。