FPGA開発日記

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

AXIバスリクエスト中に命令フラッシュが入った場合を考慮した命令Fetcherの実装(2)

実際に実装したハードウェアをシミュレーションしてみる。

現状はまだ公開できる段階には無いので、とりあえず波形のみ貼り付ける。

f:id:msyksphinz:20160815014911p:plain

まず、このIFUでは128bit x 4burstの命令フェッチリクエストを出している。 この際、MARリクエストバッファを4エントリ分消費する。全て0x00アラインでのリクエストなので、エントリの内容は0xf(全て1)である。

MAR_VALIDとMAR_READYがAssertされる、つまりリクエストが受理された段階でMAR先頭ポインタを4つ分インクリメントする。 これを、リクエストバッファの空きがあるまで続ける。

次にMRデータバッファだが、MR_VALIDとMR_READYが両方Assertされる、つまりリクエストに対するリプライがあった時点でエントリに1を立てる。

そして、次ステージが空いているならば、すぐさまデータを次ステージに送出し、MRリクエストバッファのエントリ、MARリケストバッファのエントリをクリアする。

次に命令フラッシュが発生した場合の処理だが、これも波形を載せる。

f:id:msyksphinz:20160815020125p:plain

まずフラッシュが発生する以前に、既に複数のAXIリクエストが発生していることを考える。これらのリプライを待たないと、本当に欲しいフラッシュ後のデータは返ってこない。

そのため、

  • MARリクエストバッファとMRリクエストバッファの両方のエントリが0で無い場合(データ取得済)は内容をフラッシュする。
  • MARリクエストバッファのみエントリが0で無い場合(リクエストを出したがデータは返ってきていない)はキャンセルバッファを有効化する。
  • データが返ってきた場合、当該キャンセルバッファのエントリが有効になっている場合は、データをそのまま破棄する。そしてキャンセルバッファの内容も0に戻す。
  • 全てのキャンセルバッファが0になった場合、全てのフラッシュ前のフェッチデータを取得し終えたので、次からのデータは有効なデータである。ここからは、取得したデータを次のステージに渡し始める。

この際、リクエストバッファをクリアする際に、命令発行エントリポインタの場所をリクエスト先頭ポインタの場所に合わせる。これにより、以降のリクエストで取得した命令のみ次のステージに渡すことになる。