大概の命令セットシミュレータは同様の構成を取っていると思うが、命令セットシミュレータといえど * 命令デコード * 命令実行 というハードウェアと同じことをしているのは変わらない。 自作シミュレータも多分に漏れず、以下のような構成を取っている。
このときに、命令デコーダから一意にデコードキーを受け取り、それを元に命令実行フェーズに移る。 デコードキーを受け取ると、命令実行については、デコードキーにもとづいた関数ポインタ配列を使っている。
class InstEnv { private: RiscvEnv *m_env; public: InstEnv (RiscvEnv *env); typedef void (InstEnv::*InstFunc) (Word_t inst_hex); static const InstFunc m_inst_exec_func[]; void RISCV_INST_LUI (Word_t inst_hex); void RISCV_INST_AUIPC (Word_t inst_hex); void RISCV_INST_JAL (Word_t inst_hex); ... }; const InstEnv::InstFunc InstEnv::m_inst_exec_func[] = { &InstEnv::RISCV_INST_LUI, &InstEnv::RISCV_INST_AUIPC, &InstEnv::RISCV_INST_JAL, &InstEnv::RISCV_INST_JALR, &InstEnv::RISCV_INST_BEQ, &InstEnv::RISCV_INST_BNE, &InstEnv::RISCV_INST_BLT, &InstEnv::RISCV_INST_BGE, &InstEnv::RISCV_INST_BLTU, &InstEnv::RISCV_INST_BGEU, &InstEnv::RISCV_INST_LB, &InstEnv::RISCV_INST_LH, &InstEnv::RISCV_INST_LW, &InstEnv::RISCV_INST_LBU, &InstEnv::RISCV_INST_LHU, &InstEnv::RISCV_INST_SB, ... };
で、これをC++でどうやって実現しようかというと(C言語ならクラスの改造構造を考えなくてもいいけど、C++だとどう実装するかが問題だ...)、
- 作者: ロベール
- 出版社/メーカー: 毎日コミュニケーションズ
- 発売日: 2007/11/15
- メディア: 単行本(ソフトカバー)
- 購入: 26人 クリック: 25,357回
- この商品を含むブログ (126件) を見る
あたりを参考に実装している。基本的な構造は、
class RiscvEnv { CsrEnv *m_csr_env; // CSRシステムレジスタの階層 InstEnv *m_inst_env; // 命令実行の階層 ... };
InstEnv内は上記の命令毎の実装を記述している。1命令実行する度に、命令をメモリからフェッチ、デコード、デコード結果を関数ポインタに引き渡している。 基本的な構成はこれで大丈夫なはずだけど、とりあえず、まだ動かないなあー...