LoginSignup
1
0

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-12-30

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

1
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
1
0