前回までのデザインでは、Fuzzerと呼ばれるランダムテストパタンを使っていたが、これでは思うように制御ができない。いろいろと調べているとTLPatternPusher
を使うと制御できそうだ。この使い方を調べてみよう。
TLPatternPusherとは
TLPatternPusher
はTileLinkのマスターとしてパタンを挿入するためのノードだ。TLPatternPusher
はReadとWriteのパタンを挿入することができる。
rocketchip/src/main/scala/tilelink/PatternPusher.scala
case class WritePattern(address: BigInt, size: Int, data: BigInt) extends Pattern ... case class ReadPattern(address: BigInt, size: Int) extends Pattern ... case class ReadExpectPattern(address: BigInt, size: Int, data: BigInt) extends Pattern ... class TLPatternPusher(name: String, pattern: Seq[Pattern])(implicit p: Parameters) extends LazyModule { val node = TLClientNode(Seq(TLClientPortParameters(Seq(TLClientParameters(name = name))))) ... }
上記のように、WritePattern
とReadPattern
、そしてReadExpectPattern
が利用できる。これを使ってTileLinkのバスを生成してみよう。
ターゲット回路
使うのは前回と同様の2つのマスターを接続したマスターの構成である。この中のfuzz1
とfuzz2
を置き換えてTLPatternPusher
に改造する。
実際のScalaの回路
class TLOriginalRAMSimple(ramBeatBytes: Int, txns: Int)(implicit p: Parameters) extends LazyModule { val pusher1 = LazyModule(new TLPatternPusher("pat1", Seq( new WritePattern(0x100, 0x2, 0x12345678), new ReadExpectPattern(0x100, 0x2, 0x12345678)))) val pusher2 = LazyModule(new TLPatternPusher("pat2", Seq( new WritePattern(0x200, 0x2, 0x12345678), new ReadExpectPattern(0x200, 0x2, 0x12345678)))) val model1 = LazyModule(new TLRAMModel("SRAMSimple")) val model2 = LazyModule(new TLRAMModel("SRAMSimple")) val xbar = LazyModule(new TLXbar) val ram = LazyModule(new TLRAM(AddressSet(0x0, 0x3ff), beatBytes = ramBeatBytes))
まず、pusher1
には2つのメモリアクセス操作を登録した。
WritePattern(0x100, 0x2, 0x12345678)
ReadExpectPattern(0x100, 0x2, 0x12345678)
次に、pusher2
にも同様に2つのメモリアクセスを登録した。
WritePattern(0x200, 0x2, 0x12345678)
ReadExpectPattern(0x200, 0x2, 0x12345678)
これで同様に2つのマスターを接続した回路を作成する。
ram.node := xbar.node xbar.node := TLDelayer(0.25) := model1.node := pusher1.node xbar.node := TLDelayer(0.25) := model2.node := pusher2.node
RTLシミュレーションを実行してみる。
make testlink
RTLシミュレーションにより、正しく制御オペレーションが生成されていることが確認できた。