FPGA開発日記

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

ISSの命令デコーダをDFSに切り替える

これまでのISSデコーダは、命令テーブルを探索していって、一度デコードに失敗すると別のキーは探索しないようになっていた。

uint32_t MIPS_DEC_OPCODE_0x10 (uint32_t inst_hex)
{
    if (ExtractFUNCTField (inst_hex) == 0x00) {
        return MIPS_DEC_OPCODE_0x10_FUNCT_0x0 (inst_hex);
    }
    if (ExtractFUNCTField (inst_hex) == 0x20) {
        return MIPS_DEC_OPCODE_0x10_FUNCT_0x20 (inst_hex);
    }
    if (ExtractFUNCTField (inst_hex) == 0x18) {
        return MIPS_DEC_OPCODE_0x10_FUNCT_0x18 (inst_hex);
    }
    if (IsSameIncludeX (ExtractFUNCTField (inst_hex), "000XXX", 6)) {
        return MIPS_DEC_OPCODE_0x10_FUNCT_0x000XXX (inst_hex);
    }
    return -1;
}

この場合、最初にFUNCTのデコードで0x00に該当して(実際には最後の0b000XXXに引っ掛る場合)、デコードに失敗しても、以降のデコードテーブルを探索せずに失敗してしまう。 そこで、ここを深さ優先探索というか、一度デコード探索に失敗しても、別のデコードキーを使って探索するようにした。

github.com

uint32_t MIPS_DEC_OPCODE_0x10 (uint32_t inst_hex)
{
    if (ExtractFUNCTField (inst_hex) == 0x00) {
        uint32_t ret = MIPS_DEC_OPCODE_0x10_FUNCT_0x0 (inst_hex); if (ret != -1) return ret;
    }
    if (ExtractFUNCTField (inst_hex) == 0x20) {
        uint32_t ret = MIPS_DEC_OPCODE_0x10_FUNCT_0x20 (inst_hex); if (ret != -1) return ret;
    }
    if (ExtractFUNCTField (inst_hex) == 0x18) {
        uint32_t ret = MIPS_DEC_OPCODE_0x10_FUNCT_0x18 (inst_hex); if (ret != -1) return ret;
    }
    if (IsSameIncludeX (ExtractFUNCTField (inst_hex), "000XXX", 6)) {
        uint32_t ret = MIPS_DEC_OPCODE_0x10_FUNCT_0x000XXX (inst_hex); if (ret != -1) return ret;
    }
    return -1;
}

これで、retの値によって、成功するとすぐに親関数に戻っていき、失敗した場合べつのキーを探索するように変更した。 これにより、複雑なデコードもできるようになった。 というか、これをしないと、以降のu-bootのシミュレーションが出来無かったので、がんばって変更したわけだ。