FPGA開発日記

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

サイクルベースシミュレータSniperについて調査する (SniperにRISC-Vベクトルの命令を解析させてみる)

Sniperは現在のところ、1命令につき最大2つしかメモリアクセスをトレースできるようになっておらず、まずはこれを変更する必要がある。 SniperのSIFTトレースフォーマットのうち、MAX_DYNAMIC_ADDRESSESを変更してより多くのメモリアクセスを受け入れることができるように修正する。

diff --git a/sift/sift.h b/sift/sift.h
index be51862..4551531 100644
--- a/sift/sift.h
+++ b/sift/sift.h
@@ -10,7 +10,7 @@

 namespace Sift
 {
-   const uint32_t MAX_DYNAMIC_ADDRESSES = 2;
+   const uint32_t MAX_DYNAMIC_ADDRESSES = 32;

もう一つは、SIFTのバイナリフォーマットにおけるnum_addressesフィールドを変更して、現在は2ビットしか用意されていないフィールドを拡張して8ビットに変更し、より多くのメモリアクセスを受け入れることができるようにする。この変更が分からずにかなり時間がかかってしまった。

diff --git a/sift/sift_format.h b/sift/sift_format.h
index 7be8c86..d981dfd 100644
--- a/sift/sift_format.h
+++ b/sift/sift_format.h
@@ -67,7 +67,7 @@ namespace Sift
       struct {
          uint8_t type:4;   // 0
          uint8_t size:4;   // 1-15
-         uint8_t num_addresses:2;
+         uint8_t num_addresses;
          uint8_t is_branch:1;
          uint8_t taken:1;
          uint8_t is_predicate:1;
make BUILD_RISCV=1 DEBUG=1 -j10

次に、riscv-isa-sim、すなわちSpikeのほうも変更して、ログの記憶容量も増やした。

diff --git a/riscv/processor.h b/riscv/processor.h
index 3b926106..78b46204 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -226,8 +226,8 @@ struct state_t
   uint32_t log_id = 0;
   int log_reset_count = 0;
   Sift::Writer *log_writer = nullptr;
-  reg_t log_addr;
-  bool log_addr_valid;
+  reg_t log_addr[128];
+  unsigned int log_addr_valid;
   bool log_is_branch;
   bool log_is_branch_taken;
 #endif

トレースの格納方法も変更する。

diff --git a/riscv/execute.cc b/riscv/execute.cc
index bcf4f49b..5f7d792d 100644
--- a/riscv/execute.cc
+++ b/riscv/execute.cc
@@ -176,13 +176,14 @@ static void log_print_sift_trace(state_t* state, reg_t pc, insn_t insn)
 #ifdef RISCV_ENABLE_SIFT
   uint64_t addr = pc;
   uint64_t size = insn.length();
-  uint8_t  num_addresses = state->log_addr_valid; // true -> 1, false -> 0
-  uint64_t addresses[1] = {state->log_addr};
+  uint8_t  num_addresses = state->log_addr_valid;
+  uint64_t *addresses = state->log_addr;
   bool     is_branch = state->log_is_branch;
   bool     taken = state->log_is_branch_taken;
+  fprintf(stderr, "Branch = %d, Nmu-Address = %d\n", is_branch, num_addresses);
   state->log_writer->Instruction(addr, size, num_addresses, addresses, is_branch, taken, 0 /*is_predicate*/, 1 /*executed*/);
-  state->log_addr = 0;
-  state->log_addr_valid = false;
+  // state->log_addr = 0;
+  state->log_addr_valid = 0;
   state->log_is_branch = false;
   state->log_is_branch_taken = false;
 #endif
rm -rf spike spike-dasm && make -j10

これにより、とりあえずベクトル向けのSIFTが作られるようになった。ただし、ダンプしてみるとちょっとアドレス値が間違っているようだ。

0000000080002854 (4) A16 .. ..
0000000080002854                                            07 80 05 02
                 -- addr 80002a40 80002a41 80002a42 80002a43 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 80002a4c 80002a4d 80002a4e 80002a4f
                 -- taken

シミュレータ上でも、サイクル計算も様子がおかしい。これも解析が必要そうだ。