FPGA開発日記

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

サイクル精度シミュレータSniperとSpikeでフックを使って情報交換をする

サイクル精度シミュレータSniperで、サイクル計算中に細かな挙動を指定したくて、いろいろ試行錯誤している。 例えば、SpikeからSniperへ特定のシステムレジスタのアップデート情報を送りたいときにどうするか。

こういう時は、SIFTフォーマットのMagicコマンドを使ってSIFTに情報を埋め込む。

  • riscv-isa-sim/riscv/execute.cc
    if ((sift_executed_insn & MASK_VSETVLI) == MATCH_VSETVLI ||
        (sift_executed_insn & MASK_VSETIVLI) == MATCH_VSETIVLI ||
        (sift_executed_insn & MASK_VSETVL)   == MATCH_VSETVL) {
      auto vl = p->VU.vl;
      auto vtype = p->VU.vtype;
      auto vl_value = vl->read();
      auto vtype_value = vtype->read();
      p->get_state()->log_writer->Magic(5, vl_value, vtype_value);  // SIM_CMD_USER = 5 at sim_api.h
    }

Magic(5)というのは、Magicにおけるコマンドの種類を示しており、以下のように定義されている。

  • sniper/include/sim_api.h
#define SIM_CMD_ROI_TOGGLE      0  // Deprecated, for compatibility with programs compiled long ago
#define SIM_CMD_ROI_START       1
#define SIM_CMD_ROI_END         2
#define SIM_CMD_MHZ_SET         3
#define SIM_CMD_MARKER          4
#define SIM_CMD_USER            5
#define SIM_CMD_INSTRUMENT_MODE 6
#define SIM_CMD_MHZ_GET         7
#define SIM_CMD_IN_SIMULATOR    8
#define SIM_CMD_PROC_ID         9
#define SIM_CMD_THREAD_ID       10
#define SIM_CMD_NUM_PROCS       11
#define SIM_CMD_NUM_THREADS     12
#define SIM_CMD_NAMED_MARKER    13
#define SIM_CMD_SET_THREAD_NAME 14

ROI_STARTROI_ENDは既に使用しており、統計情報を取るための範囲として使用している。 SIM_CMD_USERは引数arg0, arg1 を取って情報を渡すことができる。

このコマンドを受け取ると動作する関数を、Hookの機能を使用して定義する。

  • sniper/common/performance_model/performance_models/rob_performance_model/rob_timer.cc
   Sim()->getHooksManager()->registerHook(HookType::HOOK_MAGIC_USER, RobTimer::hookSetVL, (UInt64)this);
   static SInt64 hookSetVL(UInt64 object, UInt64 argument) {
      MagicServer::MagicMarkerType *args = (MagicServer::MagicMarkerType *)argument;

      ((RobTimer *)object)->m_rob_contention->setvl(args->arg0);
      ((RobTimer *)object)->m_rob_contention->setvtype(args->arg1);
      return 0;
   }