FPGA開発日記

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

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

Gem5に命令を追加する試行続き。ベクトル命令を定義するためにどんなことが必要なのかを試行錯誤していた。

まず、ベクトル命令全体を定義するためにRVVLoadというクラスを定義する。

  • riscv/isa/formats/rvv_mem.isa
def format RVVLoad(memacc_code, base_reg=[],
        mem_flags=[], inst_flags=[]) {{
    (header_output, decoder_output, decode_block, exec_output) = \
        RVVLoadBase(name, Name, memacc_code, base_reg, mem_flags,
        inst_flags, 'RVVLoad', exec_template_base='RVVLoad')
}};

RVVLoadを実際に実行するのが以下の実装だ。 いろいろ訳が分からないだろうが、とりあえず%(...)で書いてあるものは全部DSLにより置き換わると考えてよろしい。

def template RVVLoadExecute {{
    Fault
    %(class_name)s::execute(
        ExecContext *xc, Trace::InstRecord *traceData) const
    {
        Addr EA;

        %(op_decl)s;
        %(op_rd)s;

        EA = Rs1;

        MemElemType memdata = 0;

        {
           for (int i = 0; i < 16; i++) {
               Fault fault =
                   readMemAtomicLE(xc, traceData, EA++, memdata, memAccessFlags);
               if (fault != NoFault)
                   return fault;
           }
        }

        %(memacc_code)s;
        %(op_wb)s;

        return NoFault;
    }
}};

実際にReplaceを行うのが以下のコードとなる。これはPythonで記述してあり、かなりいろんな自動生成したファイルをReplaceするためにわけのわからないことをしている。

let {{
def RVVLoadBase(name, Name, memacc_code, base_reg, mem_flags,
        inst_flags, base_class, postacc_code='', decode_template=BasicDecode,
        exec_template_base=''):
    # Make sure flags are in lists (convert to lists if not).
    mem_flags = makeList(mem_flags)
    inst_flags = makeList(inst_flags)

    iop = InstObjParams(name, Name, base_class,
        {'memacc_code': memacc_code, 'postacc_code': postacc_code,
         'base_reg':  base_reg},
        inst_flags)

    if mem_flags:
        mem_flags = [ 'Request::%s' % flag for flag in mem_flags ]
        s = '\n\tmemAccessFlags = ' + '|'.join(mem_flags) + ';'
        iop.constructor += s

    # select templates

    fullExecTemplate = eval(exec_template_base + 'Execute')
    initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
    completeAccTemplate = eval(exec_template_base + 'CompleteAcc')

    # (header_output, decoder_output, decode_block, exec_output)
    return (RVVLoadStoreDeclare.subst(iop),
        RVVLoadStoreConstructor.subst(iop),
        decode_template.subst(iop),
        fullExecTemplate.subst(iop) +
        initiateAccTemplate.subst(iop) +
        completeAccTemplate.subst(iop))
}};

いちおういろいろ試行錯誤してビルドは通るようになったが、ベンチマークを実行してみるとやはり失敗してしまった。

Global frequency set at 1000000000000 ticks per second
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/cpu/exec_context.hh:129: panic: ExecContext::readMem() should be overridden
Memory Usage: 640752 KBytes
Program aborted at tick 11006500

アドレス生成を間違えたかな。もうちょっと試してみたい。