FPGA開発日記

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

分岐予測の評価キット Branch Prediction Championship Kit をDPIで実RTLに接続する試行

Branch Prediction Championship Kitの使い方がわかってきたので、これを実際のRTLと接続して性能検証する機能を作ってみようと思う。

まず適当に作ってみたBimodal 分岐予測器を用意する。これをDPI-Cで接続してみよう。

// Bimodal

module predictor
(
 input logic         i_clk,
 input logic         i_reset_n,

 input logic         i_pred_valid,
 input logic [63: 0] i_pred_pc,
 output logic        o_pred_taken,

 input logic         i_update_valid,
 input logic [63: 0] i_update_pc,
 input logic         i_result_taken
 );

localparam TABLE_W = 10;
localparam TABLE_SIZE = 1 << TABLE_W;

typedef struct packed {
  logic          valid;
  logic [ 1: 0]  count;
} bimodal_entry_t;

bimodal_entry_t  r_bimodal[TABLE_SIZE-1: 0];

logic [TABLE_W-1: 0] w_pred_index;
assign w_pred_index = i_pred_pc [2 +: TABLE_W];
....

always_ff @ (posedge i_clk, negedge i_reset_n) begin
  if (!i_reset_n) begin
    o_pred_taken <= 1'b0;
  end else begin
    if (i_pred_valid) begin
      o_pred_taken <= r_bimodal[w_pred_index].count[1];
    end else begin
      o_pred_taken <= 1'b0;
    end
  end
end

logic [TABLE_SIZE-1: 0][ 1: 0]  v_count;
generate for (genvar v_idx = 0; v_idx < TABLE_SIZE; v_idx++) begin : v_loop
  assign v_count[v_idx] = r_bimodal[v_idx].count;
end
endgenerate

endmodule // predictor

C++側の実装ソースコードは、C++モデルのインスタンスPREDICTORと、RTLのモデルVpredictorを用意して実行する。

  ///////////////////////////////////////////////
  // Init variables
  ///////////////////////////////////////////////

  PREDICTOR *brpred = new PREDICTOR();  // this instantiates the predictor code

  ///////////////////////////////////////////////
  // Init RTL
  ///////////////////////////////////////////////

  int time_counter = 0;
  Vpredictor *dut = new Vpredictor();
  VerilatedFstC* tfp = NULL;
  Verilated::traceEverOn(true);
  tfp = new VerilatedFstC;
  dut->trace(tfp, 100);  // Trace 100 levels of hierarchy
  tfp->open("simx.fst");

こんな感じで接続して分岐予測の結果をC++とRTLで一致比較する。

        // Predict Response
        dut->i_pred_valid = 0;
        dut->i_pred_pc = 0;
        dut->i_clk = !dut->i_clk; // Toggle clock
        dut->eval();
        tfp->dump(time_counter++);
        bool predDir_rtl = dut->o_pred_taken;
        dut->i_clk = !dut->i_clk; // Toggle clock
        dut->eval();
        tfp->dump(time_counter++);

        // printf ("PC=%08llx, RTL=%d, Model=%d, Result=%d\n", PC, predDir_rtl, predDir, branchTaken);

        if (predDir_rtl != predDir) {
          fprintf (stderr, "Error prediction RTL / Model different! RTL=%d, ISS=%d\n",  predDir_rtl, predDir);
          dut->final();
          tfp->close();
          exit (1);
        }

ビルドできた。波形で検証する。

../rtl_sim/sim_predictor ../traces/SHORT_MOBILE-24.bt9.trace.gz > ../results/bimodal/SHORT_MOBILE-24.res

うまくいっているようだ。