FPGA開発日記

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

Chiselを使ってMNISTハードウェアアクセラレータを実装(FPGAでデバッグ中 → 原因判明)

前回の続き。結局いろいろログを取り巻くって、TileLinkがデータをアウトオブオーダで返していることに気が付いていなかった。 これまでの自分の設計は、メモリリードがすべてインオーダで帰ってくることを前提にしたものだった。しまった。

msyksphinz.hatenablog.com

f:id:msyksphinz:20180125005416p:plain

f:id:msyksphinz:20180124234445p:plain

ログは少しわかりにくいが、インオーダで帰ってくるはずのデータがアウトオブオーダで帰ってくることで、格納されるべきFIFOがずれてしまい、計算結果が合わなくなっている。うーん、これは修正しなければならない。

というか、Chisel にはQueueという謎のインタフェースがある。これを使うとうまく問題を解決できないだろうか。

...
class AccumulatorExample(n: Int = 4)(implicit p: Parameters) extends RoCC()(p) {
  val regfile = Mem(n, UInt(width = xLen))
  val busy = Reg(init = Vec.fill(n){Bool(false)})

  val cmd = Queue(io.cmd)
  val funct = cmd.bits.inst.funct
  val addr = cmd.bits.rs2(log2Up(n)-1,0)
  val doWrite = funct === UInt(0)
...

あとは、ReorderQueueというインタフェースもある。これも役に立ちそうだ。

class ReorderQueue[T <: Data](dType: T, tagWidth: Int, size: Option[Int] = None)
    extends Module {
  val io = new Bundle {
    val enq = new ReorderEnqueueIO(dType, tagWidth).flip
    val deq = new ReorderDequeueIO(dType, tagWidth)
  }

  val tagSpaceSize = 1 << tagWidth
  val actualSize = size.getOrElse(tagSpaceSize)

  if (tagSpaceSize > actualSize) {
    val roq_data = Reg(Vec(actualSize, dType))
    val roq_tags = Reg(Vec(actualSize, UInt(width = tagWidth)))
...