Пример #1
0
        /// <summary>
        /// 引数で渡された32bit長の命令をデコードし、cpuで実行する
        /// </summary>
        /// <param name="instruction">32bit長の命令</param>
        /// <param name="cpu">命令を実行するRV32CPU</param>
        /// <returns>実行の成否</returns>
        internal protected override bool Exec(UInt32[] ins)
        {
            bool result = false;

            // 命令の0~1bit目が "11" でない場合は対象なし
            if ((ins[0] & 0b11U) != 0b11U)
            {
                return(result);
            }

            Register rd     = (Register)ins[1],
                     rs1    = (Register)ins[3],
                     rs2    = (Register)ins[4];
            Opcode   opcode = (Opcode)ins[0];
            Funct3   funct3 = (Funct3)ins[2];
            Funct7   funct7 = (Funct7)(ins[5] + (ins[6] << 6));
            RV32_Mac alu;


            if (opcode == Opcode.miscOp && funct7 == Funct7.mul_div)   // Op系命令(算術論理演算)
            {
                alu = (RV32_Mac)Decoder.Alu(typeof(RV32_Mac));
                switch (funct3)
                {
                case Funct3.mul:     // mul命令
                    result = alu.Mul(rd, rs1, rs2);
                    break;

                case Funct3.mulh:     // mulh命令
                    result = alu.Mulh(rd, rs1, rs2);
                    break;

                case Funct3.mulhsu:     // mulhsu命令
                    result = alu.Mulhsu(rd, rs1, rs2);
                    break;

                case Funct3.mulhu:     // mulhu命令
                    result = alu.Mulhu(rd, rs1, rs2);
                    break;

                case Funct3.div:     // div命令
                    result = alu.Div(rd, rs1, rs2);
                    break;

                case Funct3.divu:     // divu命令
                    result = alu.Divu(rd, rs1, rs2);
                    break;

                case Funct3.rem:     // rem命令
                    result = alu.Rem(rd, rs1, rs2);
                    break;

                case Funct3.remu:     // remu命令
                    result = alu.Remu(rd, rs1, rs2);
                    break;
                }
            }
            return(result);
        }
Пример #2
0
        /// <summary>
        /// 引数で渡された32bit長の命令をデコードし、cpuで実行する
        /// </summary>
        /// <param name="instruction">32bit長の命令</param>
        /// <param name="cpu">命令を実行するRV32CPU</param>
        /// <returns>実行の成否</returns>
        internal protected override bool Exec(UInt32[] ins)
        {
            bool result = false;

            // 命令の0~1bit目が "11" でない場合は対象なし
            if ((ins[0] & 0b11U) != 0b11U)
            {
                return(result);
            }

            Register rd               = (Register)ins[1],
                     rs1              = (Register)ins[3],
                     rs2              = (Register)ins[4];
            Opcode          opcode    = (Opcode)ins[0];
            Funct3          funct3    = (Funct3)ins[2];
            Funct7          funct7    = (Funct7)(ins[5] | (ins[6] << 6));
            Int32           immediate = 0;
            RV32_IntegerAlu alu;
            RV32_IntegerLsu lsu;

            switch (opcode)
            {
            case Opcode.lui:     // lui命令
                immediate = GetImmediate('U', ins);
                alu       = (RV32_IntegerAlu)Decoder.Alu(typeof(RV32_IntegerAlu));
                result    = alu.Lui(rd, immediate);
                break;


            case Opcode.auipc:     // auipc命令
                immediate = GetImmediate('U', ins);
                alu       = (RV32_IntegerAlu)Decoder.Alu(typeof(RV32_IntegerAlu));
                result    = alu.Auipc(rd, immediate);
                break;

            case Opcode.jal:     // jal命令
                immediate = GetImmediate('J', ins);
                result    = Decoder.Reg.Jal(rd, immediate);
                break;

            case Opcode.jalr:     // jalr命令
                if (funct3 == Funct3.jalr)
                {
                    immediate = GetImmediate('I', ins);
                    result    = Decoder.Reg.Jalr(rd, rs1, immediate);
                }
                break;

            case Opcode.branch:     // Branch系命令
                immediate = GetImmediate('B', ins);
                switch (funct3)
                {
                case Funct3.beq:         // beq命令
                    result = Decoder.Reg.Beq(rs1, rs2, immediate);
                    break;

                case Funct3.bne:         // bne命令
                    result = Decoder.Reg.Bne(rs1, rs2, immediate);
                    break;

                case Funct3.blt:         // blt命令
                    result = Decoder.Reg.Blt(rs1, rs2, immediate);
                    break;

                case Funct3.bge:         // bge命令
                    result = Decoder.Reg.Bge(rs1, rs2, immediate);
                    break;

                case Funct3.bltu:         // bltu命令
                    result = Decoder.Reg.Bltu(rs1, rs2, immediate);
                    break;

                case Funct3.bgeu:         // bgeu命令
                    result = Decoder.Reg.Bgeu(rs1, rs2, immediate);
                    break;
                }
                break;

            case Opcode.load:     // Load系命令
                immediate = GetImmediate('I', ins);
                lsu       = (RV32_IntegerLsu)Decoder.Lsu(typeof(RV32_IntegerLsu));
                switch (funct3)
                {
                case Funct3.lb:         // lb命令
                    result = lsu.Lb(rd, rs1, immediate);
                    break;

                case Funct3.lh:         // lh命令
                    result = lsu.Lh(rd, rs1, immediate);
                    break;

                case Funct3.lw:         //010 lw命令
                    result = lsu.Lw(rd, rs1, immediate);
                    break;

                case Funct3.lbu:         //001 lbu命令
                    result = lsu.Lbu(rd, rs1, immediate);
                    break;

                case Funct3.lhu:         //101 lhu命令
                    result = lsu.Lhu(rd, rs1, immediate);
                    break;
                }
                break;

            case Opcode.store:     // Store系命令
                immediate = GetImmediate('S', ins);
                lsu       = (RV32_IntegerLsu)Decoder.Lsu(typeof(RV32_IntegerLsu));
                switch (funct3)
                {
                case Funct3.sb:         // sb命令
                    result = lsu.Sb(rs1, rs2, immediate);
                    break;

                case Funct3.sh:         // sh命令
                    result = lsu.Sh(rs1, rs2, immediate);
                    break;

                case Funct3.sw:         // sw命令
                    result = lsu.Sw(rs1, rs2, immediate);
                    break;
                }
                break;

            case Opcode.miscOpImm:     // Op-imm系命令(即値算術論理演算)
                alu = (RV32_IntegerAlu)Decoder.Alu(typeof(RV32_IntegerAlu));
                switch (funct3)
                {
                case Funct3.addi:         // addi命令
                    immediate = GetImmediate('I', ins);
                    result    = alu.Addi(rd, rs1, immediate);
                    break;

                case Funct3.xori:         // xori命令
                    immediate = GetImmediate('I', ins);
                    result    = alu.Xori(rd, rs1, immediate);
                    break;

                case Funct3.ori:         // ori命令
                    immediate = GetImmediate('I', ins);
                    result    = alu.Ori(rd, rs1, immediate);
                    break;

                case Funct3.andi:         // andi命令
                    immediate = GetImmediate('I', ins);
                    result    = alu.Andi(rd, rs1, immediate);
                    break;

                case Funct3.slti:         // slti命令
                    immediate = GetImmediate('I', ins);
                    result    = alu.Slti(rd, rs1, immediate);
                    break;

                case Funct3.sltiu:         //110 sltiu命令
                    immediate = GetImmediate('I', ins);
                    result    = alu.Sltiu(rd, rs1, immediate);
                    break;

                case Funct3.slli when funct7 == Funct7.slli:         // slli命令
                    result = alu.Slli(rd, rs1, (Int32)ins[4]);
                    break;

                case Funct3.srli_srai when funct7 == Funct7.srli:         // srli命令
                    result = alu.Srli(rd, rs1, (Int32)ins[4]);
                    break;

                case Funct3.srli_srai when funct7 == Funct7.srai:         // srai命令
                    result = alu.Srai(rd, rs1, (Int32)ins[4]);
                    break;
                }
                break;

            case Opcode.miscOp:     // Op系命令(算術論理演算)
                alu = (RV32_IntegerAlu)Decoder.Alu(typeof(RV32_IntegerAlu));
                switch (((UInt16)funct3 | ((UInt16)funct7 << 3)))
                {
                case (UInt16)Funct3.add_sub | ((UInt16)Funct7.add << 3):         // add命令
                    result = alu.Add(rd, rs1, rs2);
                    break;

                case (UInt16)Funct3.add_sub | ((UInt16)Funct7.sub << 3):         // sub命令
                    result = alu.Sub(rd, rs1, rs2);
                    break;

                case (UInt16)Funct3.xor | ((UInt16)Funct7.xor << 3):         // xor命令
                    result = alu.Xor(rd, rs1, rs2);
                    break;

                case (UInt16)Funct3.or | ((UInt16)Funct7.or << 3):         // or命令
                    result = alu.Or(rd, rs1, rs2);
                    break;

                case (UInt16)Funct3.and | ((UInt16)Funct7.and << 3):         // and命令
                    result = alu.And(rd, rs1, rs2);
                    break;

                case (UInt16)Funct3.slt | ((UInt16)Funct7.slt << 3):         // slt命令
                    result = alu.Slt(rd, rs1, rs2);
                    break;

                case (UInt16)Funct3.sltu | ((UInt16)Funct7.sltu << 3):         // sltu命令
                    result = alu.Sltu(rd, rs1, rs2);
                    break;

                case (UInt16)Funct3.sll | ((UInt16)Funct7.sll << 3):         // sll命令
                    result = alu.Sll(rd, rs1, rs2);
                    break;

                case (UInt16)Funct3.srl_sra | ((UInt16)Funct7.srl << 3):         // srl命令
                    result = alu.Srl(rd, rs1, rs2);
                    break;

                case (UInt16)Funct3.srl_sra | ((UInt16)Funct7.sra << 3):         // sra命令
                    result = alu.Sra(rd, rs1, rs2);
                    break;
                }
                break;

            case Opcode.miscMem:     // 同期命令
                switch (funct3)
                {
                case Funct3.fence:         // fence命令
                    result = Decoder.Reg.Fence((byte)(((ins[5] & 0x7) << 5) | ins[4]));
                    break;

                case Funct3.fenceI:         // fence.i命令
                    result = Decoder.Reg.FenceI();
                    break;
                }
                break;

            case Opcode.system:     // システム命令
                switch (funct3)
                {
                case Funct3.privilege:         // 特権命令
                    if (rd == 0 && funct7 == Funct7.sfenceVma)
                    {
                        result = Decoder.Reg.SfenceVma(rs1, rs2);
                    }
                    else if (rd == 0 && rs1 == 0)
                    {
                        Funct12 funct12 = (Funct12)(ins[4] | (ins[5] << 5) | (ins[6] << 11));;
                        switch (funct12)
                        {
                        case Funct12.ecall:
                            result = Decoder.Reg.Ecall();
                            break;

                        case Funct12.ebreak:
                            result = Decoder.Reg.Ebreak();
                            break;

                        case Funct12.mret:
                            result = Decoder.Reg.Mret();
                            break;

                        case Funct12.sret:
                            result = Decoder.Reg.Sret();
                            break;

                        case Funct12.uret:
                            result = Decoder.Reg.Uret();
                            break;

                        case Funct12.wfi:
                            result = Decoder.Reg.Wfi();
                            break;
                        }
                    }
                    break;

                case Funct3.csrrw:         // csrrw命令
                    immediate = (GetImmediate('I', ins) & 0xfff);
                    result    = Decoder.Reg.Csrrw(rd, rs1, (CSR)immediate);
                    break;

                case Funct3.csrrs:         // csrrs命令
                    immediate = (GetImmediate('I', ins) & 0xfff);
                    result    = Decoder.Reg.Csrrs(rd, rs1, (CSR)immediate);
                    break;

                case Funct3.csrrc:         // csrrc命令
                    immediate = (GetImmediate('I', ins) & 0xfff);
                    result    = Decoder.Reg.Csrrc(rd, rs1, (CSR)immediate);
                    break;

                case Funct3.csrrwi:         // csrrwi命令
                    immediate = (GetImmediate('I', ins) & 0xfff);
                    result    = Decoder.Reg.Csrrwi(rd, (byte)ins[3], (CSR)immediate);
                    break;

                case Funct3.csrrsi:         // csrrsi命令
                    immediate = (GetImmediate('I', ins) & 0xfff);
                    result    = Decoder.Reg.Csrrsi(rd, (byte)ins[3], (CSR)immediate);
                    break;

                case Funct3.csrrci:         // csrrci命令
                    immediate = (GetImmediate('I', ins) & 0xfff);
                    result    = Decoder.Reg.Csrrci(rd, (byte)ins[3], (CSR)immediate);
                    break;
                }
                break;
            }
            return(result);
        }