LoginSignup
0

More than 5 years have passed since last update.

posted at

updated at

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

BTB

最後に残ったのがBTB(Branch Target Buffer)である。分岐先バッファとは、そのネーミングから分岐先命令キャッシュとの印象を持っていたが、一般には分岐元アドレスをタグにし、分岐先アドレスを引くキャッシュのようである。であれば、ネーミングとしてはBAC(Branch Address Cache)等にしたほうが誤解が少ないように思う。実際にBTAC(Branch Target Address Cache)という用語もあるようだ。図のほうが理解しやすいので回路図から見てみよう。

image.png

基本的にBIA(分岐命令アドレス)とBTA(分岐先アドレス)を格納する1R1WのRAMがインスタンスされている。

`include "constants.vh"
`default_nettype none
module btb(
       input wire              clk,
       input wire              reset,
       input wire [`ADDR_LEN-1:0]  pc,
       output wire             hit,
       output wire [`ADDR_LEN-1:0] jmpaddr,
       input wire              we,
       input wire [`ADDR_LEN-1:0]  jmpsrc,
       input wire [`ADDR_LEN-1:0]  jmpdst,
       input wire              invalid2
       );

   wire [`ADDR_LEN-1:0]       tag_data;
   reg [`BTB_IDX_NUM-1:0]     valid;

512bitのバリッドビットが実装されている。

   wire [`BTB_IDX_SEL-1:0]    waddr = jmpsrc[3+:`BTB_IDX_SEL];
   wire [`ADDR_LEN-1:0]       pc2 = pc+4;

   wire               hit1 = ((tag_data == pc) && valid[pc[3+:`BTB_IDX_SEL]]) ? 
                  1'b1 : 1'b0;
   wire               hit2 = ((tag_data == pc2) && ~invalid2 
                      && valid[pc[3+:`BTB_IDX_SEL]]) ? 1'b1 : 1'b0;
   assign hit = hit1 | hit2;

PCがタグデータ(分岐元アドレス)と一致し、かつPCでバリッドビットを引き、バリッドであればhit1をtrueとする。PC+4のアドレスがタグデータ(分岐元アドレス)と一致し、かつPCでバリッドビットを引き、バリッドであればhit2をtrueとする。hit信号はhit1またはhit2がtrueのときにtrueとする。

ところで、妙な記法があることにお気づきだろうか。PCの3ビットオフセットのビット切り出しを行っているが、これはプラスコロンという配列表記法のようで、以下で説明を見つけた。
https://stackoverflow.com/questions/18067571/indexing-vectors-and-arrays-with/18068296#18068296
PC[3+:9]という表記は、コロンの左が開始ビット(+)あるいは終了ビット(-)であり、コロンの右側は常にビット幅とのこと。この場合は3ビット目から9ビットを切り出す、つまりPC[3+9-1:3]=PC[11:3]ということになる。

   always @ (negedge clk) begin
      if (reset) begin
     valid <= 0;
      end else begin
     if (we) begin
        valid[waddr] <= 1'b1;
     end
      end
   end

これはバリッドビットの制御ロジックである。バリッドビットはリセットでクリアされ、外部からのweのアサート時に、waddrの示すvalidをtrueとする。weはどこから来るかといえば、ROB(リオーダバッファ)の分岐コミット信号のようである。

   ram_sync_1r1w #(`BTB_IDX_SEL, `ADDR_LEN, `BTB_IDX_NUM) bia
     (
      .clk(~clk),
      .raddr1(pc[3+:`BTB_IDX_SEL]),
      .rdata1(tag_data),
      .waddr(waddr),
//    .wdata(jmpsrc[31:3+`BTB_IDX_SEL]),
      .wdata(jmpsrc),
      .we(we)
      );

   ram_sync_1r1w #(`BTB_IDX_SEL, `ADDR_LEN, `BTB_IDX_NUM) bta
     (
      .clk(~clk),
      .raddr1(pc[3+:`BTB_IDX_SEL]),
      .rdata1(jmpaddr),
      .waddr(waddr),
      .wdata(jmpdst),
      .we(we)
      );

endmodule // btb

前述のとおりBIA(分岐命令アドレス)とBTA(分岐先アドレス)を格納する1R1WのRAMのインスタンス。

読書会(5)はこちら
https://qiita.com/mocapapa/private/eb736d6b936b6c9c8e22

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
What you can do with signing up
0