FPGA開発日記

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

L1Dキャッシュのキャッシュライン置き換え方法再考

自作CPUのL1Dキャッシュについていろいろ考えているが、やはりキャッシュラインを置き換えるタイミングでの書き込み制御が甘くランダムテストでバグを出してしまっている。

L1Dを置き換えるとき、ロード命令によるL1Dアクセスを行い、キャッシュミスかつウェイが一つも空いていないときは特定のキャッシュラインを置き換える。 そして置き換え対象となるキャッシュラインに対して、別のストア命令が書き込み要求を出した場合にどうするのかという微妙なサイクルの置き換え問題が発生する。

これは自分用のメモであまり他人が呼んでも意味がないものなのだが、以下のようにストア命令がまずL1Dキャッシュの中身を確認し、キャッシュラインが存在していればそのまま書き込みを行う。キャッシュラインのリクエストと読み込みに1サイクルずつ、キャッシュラインへの書き込みリクエストに1サイクルで合計3サイクル掛かる計算になっている。

f:id:msyksphinz:20220313001913p:plain

L1Dキャッシュへのアクセスはアービトレーションされているため、1サイクル目と3サイクル目に、別のロード命令がL1Dリクエストを出す事は無いが、2サイクル目には読み込み要求を出せる。そしてそこで1サイクル目と3サイクル目に書き込み対象としたキャッシュラインを追い出した場合どうするか。

キャッシュラインの置き換えには、L1D Miss Unitの一部を使用している。ロード命令はL1Dのキャッシュアクセス、Miss Unitへのリクエスト送出の間の微妙のタイミングで書き込みデータが喪失してしまう可能性があり、これが問題となる。

f:id:msyksphinz:20220313002501p:plain

これはどうしたらいいのかいろいろ考えたが、やはりロード命令をパイプラインに流している最中に置き換え対象キャッシュラインを持ってしまうのが問題なので、L1Dへの書き込みをもう少し慎重に行う必要がある。

具体的には、これまでは1サイクルで行っていたL1Dへの書き込みを、

  1. タグにアクセスして本当に当該キャッシュラインが存在しているか確認する。消えている場合はもう一度L2Cからの読み込みリクエストやり直し
  2. データを書き込み。この時に1. で取り出したキャッシュラインとマージすれば、L1DのSRAMのバイトイネーブルをいちいちいじる必要がない。

こういう風にパイプラインを変更する必要があるだろう。はあ、また実装し直しか...