FPGA開発日記

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

TileLinkのDiplomacyを使った実際のデザインを試してみる (6. TLPatternPusherを使ったテストベンチの作成)

前回までのデザインでは、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)))))
...
}

上記のように、WritePatternReadPattern、そしてReadExpectPatternが利用できる。これを使ってTileLinkのバスを生成してみよう。

ターゲット回路

使うのは前回と同様の2つのマスターを接続したマスターの構成である。この中のfuzz1fuzz2を置き換えてTLPatternPusherに改造する。

f:id:msyksphinz:20200102221750p:plain
2マスターを使ったデザインで、マスターに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つのメモリアクセス操作を登録した。

  1. WritePattern(0x100, 0x2, 0x12345678)
  2. ReadExpectPattern(0x100, 0x2, 0x12345678)

次に、pusher2にも同様に2つのメモリアクセスを登録した。

  1. WritePattern(0x200, 0x2, 0x12345678)
  2. 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
f:id:msyksphinz:20200102221842p:plain

RTLシミュレーションにより、正しく制御オペレーションが生成されていることが確認できた。