RISC-V用のISSを実装しているが、それをMIPS用にも活用したい。C++で記述しているので、継承を利用すれば、筋が良く実装することができそうだ。
MIPS用のVerilog-HDLハードウェアデコーダを生成していたので、それに合わせてISS用のデコーダも生成する。
テーブルは、全てRubyで記述した命令テーブルに格納している。
# ['BITFIELD' 31-26, 25-21, 20-16 15-11 10-06 05-00 ] # ['DECODE-KEY', 'OPCODE', 'RS' 'RT', 'RD', 'SHAMT', 'FUNCT' 'TYPE' 'KEY_TABLE' ] $arch_table[ 0] = Array['add d[15:11],d[25:21],d[20:16]', '000000', 'XXXXX', 'XXXXX', 'XXXXX', '00000', '100000', 'ALU', Array[ 'DST_RD', 'R1_RS', 'R2_RT', 'OP_SIGN_ADD' ], Array['OPCODE', 'FUNCT', 'SHAMT'], ] $arch_table[ 1] = Array['addi d[20:16],d[25:21],h[15:0]', '001000', 'XXXXX', 'XXXXX', 'XXXXX', 'XXXXX', 'XXXXXX', 'ALU', Array[ 'DST_RT', 'R1_RS', 'IMM', 'OP_SIGN_ADD' ], Array['OPCODE']] $arch_table[ 2] = Array['addiu d[20:16],d[25:21],h[15:0]', '001001', 'XXXXX', 'XXXXX', 'XXXXX', 'XXXXX', 'XXXXXX', 'ALU', Array[ 'DST_RT', 'R1_RS', 'IMM', 'OP_USIGN_ADD' ], Array['OPCODE']] $arch_table[ 3] = Array['addu d[15:11],d[25:21],d[20:16]', '000000', 'XXXXX', 'XXXXX', 'XXXXX', '00000', '100001', 'ALU', Array[ 'DST_RD', 'R1_RS', 'R2_RT', 'OP_USIGN_ADD' ], Array['OPCODE', 'FUNCT', 'SHAMT']] $arch_table[ 4] = Array['clo d[15:11],d[25:21]', '011100', 'XXXXX', 'XXXXX', 'XXXXX', '00000', '100001', 'ALU', Array[ 'DST_RD', 'R1_RS', 'OP_COUNT_ONE' ], Array['OPCODE', 'FUNCT', 'SHAMT']] ...
デコードテーブルと、デコードに必要な情報、ハードウェア制御信号の生成に必要な情報を格納している。 これによって、ある程度の命令のテンプレートを自動生成する。
class MipsEnv; class InstEnv { private: MipsEnv *m_env; public: InstEnv (MipsEnv *env); typedef void (InstEnv::*InstFunc) (Word_t inst_hex); static const InstFunc m_inst_exec_func[]; void MIPS_Inst_Exec (uint32_t index, Word_t inst_hex); void MIPS_INST_ADD (Word_t inst_hex); void MIPS_INST_ADDI (Word_t inst_hex); void MIPS_INST_ADDIU (Word_t inst_hex); void MIPS_INST_ADDU (Word_t inst_hex); void MIPS_INST_CLO (Word_t inst_hex); void MIPS_INST_CLZ (Word_t inst_hex); void MIPS_INST_DIV (Word_t inst_hex); void MIPS_INST_DIVU (Word_t inst_hex); void MIPS_INST_MADD (Word_t inst_hex); void MIPS_INST_MADDU (Word_t inst_hex); void MIPS_INST_MSUB (Word_t inst_hex); void MIPS_INST_MSUBU (Word_t inst_hex); ...
実装は、自分で行わなければならない。
void InstEnv::MIPS_INST_ADD (Word_t inst_hex)
{
RegAddr_t rs1_addr = ExtractRSField (inst_hex);
RegAddr_t rs2_addr = ExtractRTField (inst_hex);
RegAddr_t rd_addr = ExtractRDField (inst_hex);
Word_t rs1_val = m_env->GRegRead (rs1_addr);
Word_t rs2_val = m_env->GRegRead (rs2_addr);
Word_t res = rs1_val + rs2_val;
m_env->GRegWrite (rd_addr, res);
}
という訳で、MIPSの命令を出来るところから実装していき、何とかビルドできるようになった。。。これからは、このISSを利用してテストしていく。