FPGA開発日記

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

Gem5のインストール試行とベンチマーク実行 (RISC-V命令にベクトル新規命令を追加する)

Gem5の命令定義表を理解したいので、まずは簡単にRISC-Vのベクトル命令を追加していく。 一番簡単なmemcpyを動かすためには、以下の3つの命令が定義できていれば十分だ。

copy_data_vec:
    mv      a3, a0          # Copy destination
.loop:
    vsetvli t0, a3, e8,m1   # Vectors of 8b
    vle8.v  v0, (a1)        # Load bytes
    add     a1, a1, t0          # Bump pointer
    sub     a2, a2, t0          # Decrement count
    vse8.v  v0, (a3)            # Store bytes
    add     a3, a3, t0          # Bump pointer
    bnez    a2, .loop           # Any more?
    ret                         # Return

Gem5の命令テーブルを見ながら、地味に追加していく。

diff --git a/src/arch/riscv/insts/SConscript b/src/arch/riscv/insts/SConscript
index 80592a34e..c20e8810b 100644
--- a/src/arch/riscv/insts/SConscript
+++ b/src/arch/riscv/insts/SConscript
@@ -32,3 +32,4 @@ Source('compressed.cc', tags='riscv isa')
 Source('mem.cc', tags='riscv isa')
 Source('standard.cc', tags='riscv isa')
 Source('static_inst.cc', tags='riscv isa')
+Source('rvv_mem.cc', tags='riscv isa')
diff --git a/src/arch/riscv/insts/static_inst.cc b/src/arch/riscv/insts/static_inst.cc
index 6f6b3fe7b..86efcaf7e 100644
--- a/src/arch/riscv/insts/static_inst.cc
+++ b/src/arch/riscv/insts/static_inst.cc
@@ -62,5 +62,6 @@ RiscvMicroInst::advancePC(ThreadContext *tc) const
     tc->pcState(pc);
 }

+
 } // namespace RiscvISA
 } // namespace gem5
diff --git a/src/arch/riscv/insts/static_inst.hh b/src/arch/riscv/insts/static_inst.hh
index eec9c8828..728ef442d 100644
--- a/src/arch/riscv/insts/static_inst.hh
+++ b/src/arch/riscv/insts/static_inst.hh
@@ -88,6 +88,10 @@ class RiscvStaticInst : public StaticInst
     {
         return simpleAsBytes(buf, size, machInst);
     }
+
+  void printMnemonic(std::ostream &os,
+                     const std::string &suffix = "") const;
+
 };

 /**
diff --git a/src/arch/riscv/isa/decoder.isa b/src/arch/riscv/isa/decoder.isa
index 6cd7d952e..d5340a062 100644
--- a/src/arch/riscv/isa/decoder.isa
+++ b/src/arch/riscv/isa/decoder.isa
@@ -427,6 +427,15 @@ decode QUADRANT default Unknown::unknown() {
                     fd = freg(f64(Mem));
                     Fd_bits = fd.v;
                 }}, inst_flags=FloatMemReadOp);
+                0x0: vle8({{
+                    // STATUS status = xc->readMiscReg(MISCREG_STATUS);
+                    // if (status.fs == FPUStatus::OFF)
+                    //     return std::make_shared<IllegalInstFault>(
+                    //                 "FPU is off", machInst);
+                    freg_t fd;
+                    fd = freg(f16(Mem_uh));
+                    Fd_bits = fd.v;
+                }}, inst_flags=FloatMemReadOp);
             }
         }

@@ -621,6 +630,9 @@ decode QUADRANT default Unknown::unknown() {

                     Mem_ud = Fs2_bits;
                 }}, inst_flags=FloatMemWriteOp);
+                0x0: vse8({{
+                    Mem_uh = (uint16_t)Fs2_bits;
+                }}, inst_flags=FloatMemWriteOp);
             }
         }

@@ -1887,5 +1899,15 @@ decode QUADRANT default Unknown::unknown() {
         }

         0x1e: M5Op::M5Op();
-    }
+
+        0x15: decode FUNCT3 {
+             0x7: decode IMMSIGN {
+                format CSROp {
+                   0x0 : vsetvli({{Rd = data;
+                      data = Rs1;
+                   }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
+                }
+             }
+        }
+  }
 }

再度Gem5をビルドして、memcpyのベンチマークを実行していく。

warn: No dot file generated. Please install pydot to generate the dot file and pdf.
build/RISCV/mem/dram_interface.cc:690: warn: DRAM device capacity (8192 Mbytes) does not match the address range assigned (512 Mbytes)
0: system.remote_gdb: listening for remote gdb on port 7000
**** REAL SIMULATION ****
build/RISCV/sim/simulate.cc:194: info: Entering event queue @ 0.  Starting simulation...
build/RISCV/sim/mem_state.cc:443: info: Increasing stack size by one page.
build/RISCV/sim/syscall_emul.cc:74: warn: ignoring syscall mprotect(...)
build/RISCV/sim/faults.cc:102: panic: panic condition !handled && !tc->getSystemPtr()->trapToGdb(SIGSEGV, tc->contextId()) occurred: Page table fault when accessing virtual address 0xc1050
Memory Usage: 633320 KBytes
Program aborted at tick 5393500

うーん、ページテーブルエラー?普通の命令が動いているはずだからおかしいなあ... VLE8とVSE8をベンチマークから取り除くと動くので、間違いなくこの2つの命令の挙動がおかしい。 もうちょっと解析してみよう。