LoginSignup
0
0

More than 3 years have passed since last update.

RISC-Vソースコード読書会(6)

Last updated at Posted at 2020-08-07

<ID>

ここからIDステージ(<ID>)。<IF>でフェッチした命令に従い命令デコードをするほか、タグ生成を実行する。

Tag Generator

ソースはsrc/fpga/tag_generator.v。何のタグかというと、分岐投機実行タグである。"Modern Processor Design"の229ページから231ページにかけて、分岐の投機実行について書かれている。分岐予測の2つの側面があり、ひとつは分岐の投機実行と、他のひとつは分岐の妥当性検証及び修復である。分岐の投機実行は仮実行という印をタグに登録しておき、後で分岐予測の妥当性検証を実行する。その際に予測がはずれていれば、タグにより分岐を無効化する必要がある。これが修復と呼ばれるプロセスになる。

`include "constants.vh"
`default_nettype none
module tag_generator(
             input wire             clk,
             input wire             reset,
             input wire             branchvalid1,
             input wire             branchvalid2,
             input wire             prmiss,
             input wire             prsuccess,
             input wire             enable,
             input wire [`SPECTAG_LEN-1:0]  tagregfix,
             output wire [`SPECTAG_LEN-1:0] sptag1,
             output wire [`SPECTAG_LEN-1:0] sptag2,
             output wire            speculative1,
             output wire            speculative2,
             output wire            attachable,
             output reg [`SPECTAG_LEN-1:0]  tagreg
             );

//   reg [`SPECTAG_LEN-1:0]                tagreg;
   reg [`BRDEPTH_LEN-1:0]              brdepth;

   assign sptag1 = (branchvalid1) ? 
           {tagreg[`SPECTAG_LEN-2:0], tagreg[`SPECTAG_LEN-1]}
           : tagreg;

inst1が有効な分岐命令であることを示すbranchvalid1がtrueのとき、5bitの分岐投機タグtagregを左へ1ビットローテートし、sptag1とする。

   assign sptag2 = (branchvalid2) ? 
           {sptag1[`SPECTAG_LEN-2:0], sptag1[`SPECTAG_LEN-1]}
           : sptag1;

inst2が有効な分岐命令であることを示すbranchvalid2がtrueのとき、5bitの分岐投機タグsptag1を左へ1ビットローテートし、sptag2とする。

   assign speculative1 = (brdepth != 0) ? 1'b1 : 1'b0;

brdepth(投機分岐の深さ)が0で無い場合は、inst1が投機命令であることを示すspeculative1をtrueとする。

   assign speculative2 = ((brdepth != 0) || branchvalid1) ? 1'b1 : 1'b0;

brdepth(投機分岐の深さ)が0で無いかまたはinst1が有効な分岐命令の場合は、inst2が投機命令であることを示すspeculative1をtrueとする。

   assign attachable = (brdepth + branchvalid1 + branchvalid2) 
     > (`BRANCH_ENT_NUM + prsuccess) ? 1'b0 : 1'b1;

brdepth(投機分岐の深さ)と命令1及び命令2が分岐命令の場合の数を加えた数が、エントリ数を超えている場合は、
タグの割り当て可能を示す信号attachableをfalseとする。

   always @ (posedge clk) begin
      if (reset) begin
     tagreg <= `SPECTAG_LEN'b1;
     brdepth <= `BRDEPTH_LEN'b0;
      end else begin
     tagreg <= prmiss ? tagregfix :
           ~enable ? tagreg : 
           sptag2;
     brdepth <= prmiss ? `BRDEPTH_LEN'b0 :
            ~enable ? brdepth - prsuccess :
            brdepth + branchvalid1 + branchvalid2 - prsuccess;
      end
   end

endmodule // tag_generator
`default_nettype wire

クロック毎にtagregとbrdepthを更新する。更新のしかたは、tagregは、予測ミスの場合はtagregの修復値をロードし、そうでない場合は、イネーブルでない場合はtagregを、イネーブルの場合はsptag2をロードする。
分岐深さは、予測ミスの場合はゼロをロードし、そうでない場合は、イネーブルでない場合は分岐深さを
イネーブルの場合は分岐深さにbranchvalid1及びbranchvalid2を加えたものをロードする。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0