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
うまくいっているようだ。