FPGA開発日記

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

TileLinkのCache Coherencyプロトコル (1. TileLinkの定義チャネル)

TileLinkはAMBA、OCP(Open Core Protocol)のような共通バスプロトコルとしてSiFive社により定義されたプロトコルである。SiFive社が公開しているRocket-Chip、BOOM、ChipyardやDiplomacyを理解するときには必ず通らなければならない仕様だ。

このプロトコルは、大きく分けて3つのプロトコルから構成されている。

  • TileLink-UL (Uncached LinghtWeight) : リードライトのみをサポートする
  • TileLink-UH (Uncached Heavy):リードライト、バースト転送、アトミックなどをサポートする
  • TileLink-C (Cached):ブロック転送、コヒーレンシ制御などをサポートする

このうちULとUHは簡単に理解できると思うので、TileLink-Cについて読み解いていく。TileLink-Cはキャッシュコヒーレンシをサポートしている。どのような信号が定義されていて、どのようにコヒーレントを維持するのかについて仕様書を読みながら読み解いていくことにする。

ちなみに、Chipyardのコンフィグレーション環境には、マルチコア向けにL2 Inclusiveキャッシュが搭載されている。これにはTileLinkを用いたマルチコア向けのコヒーレンシ制御が搭載されているはずである。

TileLink-Cが定義するチャネル

OCPは3種類、AMBAは5種類(だった気がする)のチャネル定義しているが、同様にTileLinkでも5種類のチャネルを定義している。TileLink-Cではそのすべてのチャネルを使用し、すべてのコマンドをサポートしている。

  • A:リクエストチャネル。データの読み出しリクエストの授受、書き込みリクエスト送出時のデータもこのチャネルに含まれる。
  • B:TileLink-Cでは、データ領域に対してOwnerやPermissionなどの属性が付けられる。このPermissionやOwnerの制御のために使用されるチャネル。
  • C:チャネルBのリクエストに対して応答するためのチャネルとなっている。メッセージの創出やデータの創出などに使用する。
  • D:チャネルAの読み込みリクエストに対して応答するために使用するチャネルとなっている。主にデータの転送に使用する。
  • E:リクエストに対するエラーレスポンスのために使用する。

以下の図が、各チャネルの方向を示している。同一チャネル内で信号の方向が逆になる事は無い。下記の図の左側のモジュールをマスター、右側のモジュールをスレーブとすると、A、C、Eはマスターからスレーブへ、BとDはスレーブからマスターへと転送される役割を持っている。

f:id:msyksphinz:20210519234714p:plain

TileLinkは常にマスターとスレーブの関係でTree構造を作り出すようになっている。つまり、以下のように複数のコアと階層を持っているような構成を取る訳であるが、この時に葉(コア側)はリクエストを出す側(つまりAチャネルが出力になる)、枝やルート(キャッシュなど)はリクエストを受ける側(つまりAチャネルが入力になる)という構成でツリーが構成されていく。

f:id:msyksphinz:20210519234741p:plain

そうするとだいたい想像がつくであろうが、以下のようなデータフローの流れになるであろう。

  • Aチャネルを使ってコア(マスター)はキャッシュ(スレーブ)に対してリクエストを送出する。
    • そのレスポンス(データ読み込みなど)はDチャネルを使って応答する。
  • キャッシュ(スレーブ)からコア(マスター)へのリクエストはBチャネルを使って応答する。
    • 例えばL2キャッシュからコアへのスヌープ信号の送出など。

TileLink-UL, TileLink-UHに加えて、TileLink-Cでは以下のようなコマンドが使用可能になっている。

f:id:msyksphinz:20210519234802p:plain
  • AcquireBlock:マスターがスレーブにブロックデータの取得を要求する。リクエストを受け取ったスレーブはGrantGrantDataを使ってブロックを返す。
  • AquirePerm:マスターがスレーブにブロックデータの権限を要求する。例えば、読み込み専用のブロックを、書き込み用に権限グレードアップするためなどに使用する。リクエストを受け取ったスレーブらGrantを使って要求応答を返す。
  • ProbeBlock :スレーブからマスターに対して、マスターの持っているブロックの権限を変更するために使用する。リクエストを受け取ったマスターはProbeAckProbeAckDataを使って応答する。リクエストの種類によってはProbeAckDataを使ってデータブロックをマスターからスレーブに返す。
  • ProbePerm:スレーブからマスターに対して、マスターの持っているブロックの権限を変更するために使用する。リクエストを受け取ったマスターはProbeAckを使って応答する。
  • Release:マスターがスレーブに対してブロックの解放を行うために使用する。データの移動は発生しない(ブロックの書き換えを行っていない場合、ブラックを破棄するだけで良い、ということだと思われる)リクエストを受け取ったスレーブはReleaseAckを使って応答する。
  • ReleaseData:マスターがスレーブに対してブロックの解放を行うために使用する。データの移動が発生する。リクエストを受け取ったスレーブはReleaseAckを使って応答する。