FPGA開発日記

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

Diplomacyを使ってOCPバスを作成する(5. OCP SRAMのデバッグ)

Diplomacyを使ってOCPバスを作成している。OCP SRAMの動作を確認しているが、どうも上手く動いていないようだ。Diplomacyの構成を確認している。SRAMは1サイクル後にReadデータが出てくるので、それに合わせてパイプを調整した。

    val d_raw_data  = Wire(Vec(4, UInt(8.W)))
    dontTouch(d_raw_data)
    val w_mem_read = in.cmd.fire() && in.cmd.bits.mcmd === OCPMessages.Read
    d_raw_data := mem.read(in.cmd.bits.address, w_mem_read)

    val r_resp_valid = Reg(Bool())
    val r_resp_bits_tagId = Reg(UInt())

データは1サイクル後に出てくるのでそのまま接続するが、resp_validresp_tagIdがその分1サイクル遅延を挿入している。

    when (w_mem_read) {
      r_resp_valid := true.B
      r_resp_bits_tagId := in.cmd.bits.tagId
    } .otherwise {
      r_resp_valid := false.B
      r_resp_bits_tagId := 0.U
    }

    in.resp.valid := r_resp_valid
    in.resp.bits.data  := Cat(d_raw_data.reverse)
    in.resp.bits.tagId := r_resp_bits_tagId

あとは、PatternPusher側でReadリクエストを出しているときはflight信号をAssertして、その間は次のコマンドを出さないように調整した。

    when ((cmd.fire() && cmd.bits.mcmd === OCPMessages.Write) ||
      data.fire() ||
      resp.fire()
    ) {
      step := step + UInt(1)
    }

    when (cmd.fire() && cmd.bits.mcmd === OCPMessages.Read) {
      flight := true.B
    }

    when (resp.fire()) {
      flight := false.B
    }
...
    cmd.valid  := pvalid(step) && io.run && !flight && ready && !end
    cmd.bits   := pbits(step)

    data.valid := wvalid(step) && io.run && ready && !end
    data.bits  := wbits(step)

この状態でシミュレーションを行った。ちゃんと動作しているようだ。ここまでは良し。次に、機能の拡張や部品の追加を行っていく。

f:id:msyksphinz:20200201003827p:plain
OCP SRAMを接続した際のPatternPusherシミュレーション結果