FPGA開発日記

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

サイクル精度シミュレータSniperでRegion of Interest(ROI)を設定するための手法の調査

サイクル精度シミュレータSniperでは、計測範囲を指定する用語としてROI(Region of Interest)というものがある。 通常、サイクル数などはこの範囲を計測するのだが、これを取得する方法はいくつかあって、Sniperは基本的にC言語用のマクロを用意している。

github.com

ここにはRISC-V用のROI関数が定義されていないので、無理やり自分で定義する。x0への書き込み命令(ADDI x0)をROI用の関数として定義してしまう。

#if defined(__riscv)

#define SimMagic0(cmd) ({                       \
   asm volatile (           \
   "addi x0, x0, %0\n"   \
   :: "i"(cmd)             \
   );                       \
})

#define SimRoiStart()             SimMagic0(SIM_CMD_ROI_START)
#define SimRoiEnd()               SimMagic0(SIM_CMD_ROI_END)

そしてこれらをテストベンチマーク上に埋め込むようにする。

  SimRoiStart();
  spmv(R, val, idx, x, ptr, y);
  SimRoiEnd();

SniperはSIFTファイル生成用にSpikeを使用するので、Spike側を改造してMagicを送信するようにしてみる。

  • riscv/execute.cc
  } else {
    p->get_state()->log_writer->Instruction(addr, size, num_addresses, addresses, is_branch, taken, 0 /*is_predicate*/, 1 /*executed*/);
    if ((MASK_ADDI & sift_executed_insn) == MATCH_ADDI) {
      if ((INSN_FIELD_IMM12 & sift_executed_insn) == 0x00100000) {
        p->get_state()->log_writer->Magic (1, 0, 0);
      }
      if ((INSN_FIELD_IMM12 & sift_executed_insn) == 0x00200000) {
        p->get_state()->log_writer->Magic (2, 0, 0);
      }
    }
  }

ここまでは良かったが、SniperのSIFT Writer/SIFT ReaderはResponseを想定しているらしく、これがよく分からない。Magicを送信するだけで、なんでそんなことがいるんだ?

とりあえず余計な部分をコメントアウトして試行してみる。

diff --git a/sift/sift_reader.cc b/sift/sift_reader.cc
index 300371c..2cf2c0c 100644
--- a/sift/sift_reader.cc
+++ b/sift/sift_reader.cc
@@ -752,21 +752,21 @@ void Sift::Reader::sendSimpleResponse(RecOtherType type, void *data, uint32_t si
    std::cerr << "[DEBUG:" << m_id << "] Write SimpleResponse type=" << type << std::endl;
    #endif

-   if (!initResponse())
-   {
-      std::cerr << "[SIFT:" << m_id << "] Error: initResponse failed\n";
-   }
-
-   Record rec;
-   rec.Other.zero = 0;
-   rec.Other.type = type;
-   rec.Other.size = size;
-   response->write(reinterpret_cast<char*>(&rec), sizeof(rec.Other));
-   if (size > 0)
-   {
-      response->write(reinterpret_cast<char*>(data), size);
-   }
-   response->flush();
+   // if (!initResponse())
+   // {
+   //    std::cerr << "[SIFT:" << m_id << "] Error: initResponse failed\n";
+   // }
+   //
+   // Record rec;
+   // rec.Other.zero = 0;
+   // rec.Other.type = type;
+   // rec.Other.size = size;
+   // response->write(reinterpret_cast<char*>(&rec), sizeof(rec.Other));
+   // if (size > 0)
+   // {
+   //    response->write(reinterpret_cast<char*>(data), size);
+   // }
+   // response->flush();
 }

 uint64_t Sift::Reader::getPosition()
diff --git a/sift/sift_writer.cc b/sift/sift_writer.cc
index 387afd0..20feeaf 100644
--- a/sift/sift_writer.cc
+++ b/sift/sift_writer.cc
@@ -757,6 +757,8 @@ uint64_t Sift::Writer::Magic(uint64_t a, uint64_t b, uint64_t c)
    output->write(reinterpret_cast<char*>(&c), sizeof(uint64_t));
    output->flush();

+   return 0;
+
    initResponse();

    // wait for reply