FPGA開発日記

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

自作CPUの動作周波数改善検討 (1. RVCデコーダの改善検討)

自作CPUのフロントエンドデコーダ部分が非常に重たいのだが,この改良を考えている.

重たい部分というのは,RVC命令(16-bit命令)を拡張して32-bit命令に変換する部分だ. RVC命令は32-bit命令(RVI命令)の中に混在して現れ,しかもRVCをサポートしている環境では32-bit命令を16-bitアラインに配置することが許可されているため非常に面倒になる.

例えば,128-bitの命令キャッシュブロックに以下のように命令が含まれていたとする.赤いブロック(16-bit)はRVC命令で,白いブロックはRVI命令を含む. 白いブロックはRVIなので,当然2ブロックで連続となる. この例では,とりあえずRVI命令のアラインがずれていることは考えず,最初の1ブロックにRVC命令が挿入されている一般的なケースを考える.

RVCかどうかを判定するのは16-bitブロックの下位2-bitが11かどうか(insn[1:0]==2'b11 ならば RVI, そうでなければRVC) を使って判定するので,RVCかどうかで切り出すブロックの位置が変わる. しかしこれを逐次的にやっているとクリティカルパスが伸びてしまうだろう.

そこで,とりあえずすべてのブロックをRVI命令に変換してみる.これで,16-bit x 8個の命令を(変換に失敗してもいいので) 32-bit x 8個の命令に変換する. この変換自体はおそらく重たいものではないだろう.各ブロック間の依存関係も存在しない.

そして,この後適切なブロックを切り出す処理が必要になる.イメージとしては以下のように切り出す.

で,それぞれを切り出す判定論理をどのように作るか考えてみる.

  • insn0 : alignされているものとすると,insn_origin[0]==RVC ならば insn_trans_rvi[0] ,そうでなければ {insn_origin[1], insn_origin[0]}
  • insn1 : insn_rvc[0] だとすると,insn_origin[1] == RVC ならば insn_trans_rvi[1]そうでなければ{insn_origin[2], insn_origin[1]}`

insn2からがめんどい.insn2が取り込まれる可能性があるのをリストアップして考える:

  • insn_rvc[1:0]==2'b00 :前の2つのブロックが両方ともRVCではないので, insn_origin[5:4] が選ばれる
  • insn_rvc[1:0]==2'b01 :前の2つのブロックのうち1つがRVCなので,insn_origin[4:3]が選ばれる
  • insn_rvc[1:0]==2'b10 :前の2つのブロックのうち1つがRVCなので,insn_origin[4:3]が選ばれる
  • insn_rvc[1:0]==2'b11 :前の2つのブロックが両方ともRVCなので,insn_origin[3:2]が選ばれる.

となる.つまり,当たり前の結果だが前に何個のブロックがRVCかということに依存することになる.

同様に,insn3 になると,

  • insn_rvc[2:0]==3'b000 :前の3つのブロックがすべてRVCではないので, insn_origin[7:6] が選ばれる
  • insn_rvc[2:0]==3'b001 :前の3つのブロックのうち1つがRVCなので,insn_origin[6:5]が選ばれる
  • insn_rvc[2:0]==3'b010 :前の3つのブロックのうち1つがRVCなので,insn_origin[6:5]が選ばれる
  • insn_rvc[2:0]==3'b100 :前の3つのブロックのうち1つがRVCなので,insn_origin[6:5]が選ばれる
  • insn_rvc[2:0]==3'b011 :前の3つのブロックが2つがRVCなので,insn_origin[5:4]が選ばれる.
  • insn_rvc[2:0]==3'b110 :前の3つのブロックが2つがRVCなので,insn_origin[5:4]が選ばれる.
  • insn_rvc[2:0]==3'b111 :前の3つのブロックがすべてRVCなので,insn_origin[4:3]が選ばれる.

こう考えると,RVCの判定状況を Prefix Sum を使ってインデックスを計算する,ということになるか.