示例#1
0
        public void SingleStep( )
        {
            ControlSignalStruct ctrlSignal = new ControlSignalStruct();

            try {
                int lineNum = (int)(PC - CodeSegStart) / 4;

                if (lineNum >= executeLines.Count)
                {
                    IsReadySimulation = false;
                    return;
                }

                string inst = Compiler.Encode(executeLines[lineNum]);                              // data_in => data in memory

                string pc_out;

                bool zero = false;

                Console.Write("PC = 0x" + Convert.ToString(PC, 16) + " : ");

                cpu_control(inst.Substring(0, 6), inst.Substring(26, 6), zero, out ctrlSignal);
                data_path(inst, ctrlSignal, out pc_out, out zero);

                PC = Convert.ToUInt32(pc_out, 2);

                Console.WriteLine("=======================");
            }catch (Exception except) {
                Console.WriteLine("Single Step Error :\n" + except.Message);

                throw except;
            }


            return;
        }
示例#2
0
        private void data_path(string inst, ControlSignalStruct ctrlsignal,
                               out string pc_out, out bool zero)
        {
            pc_out = string.Empty;
            Console.WriteLine(Decompiler.Decode(inst));
            //ctrlsignal.print( );
            string res      = string.Empty;
            var    PC_4     = PC + 4;
            var    jumpaddr = (Convert.ToString(PC_4, 2).PadLeft(32, '0').Substring(0, 4) +
                               inst.Substring(Decompiler._pos_jumpaddr.Key, Decompiler._pos_jumpaddr.Value)).PadRight(32, '0');
            var reg1 = (ctrlsignal.ALU_Control == ALUOperation.SLL || ctrlsignal.ALU_Control == ALUOperation.SRL ?
                        inst.Substring(Decompiler._pos_secondreg.Key, Decompiler._pos_secondreg.Value)
                                                                : inst.Substring(Decompiler._pos_firstdreg.Key, Decompiler._pos_firstdreg.Value));
            var reg2       = inst.Substring(Decompiler._pos_secondreg.Key, Decompiler._pos_secondreg.Value);
            var read_data1 = Convert.ToString(Registers[Convert.ToInt32(reg1, 2)], 2).PadLeft(32, '0');
            var read_data2 = Convert.ToString(Registers[Convert.ToInt32(reg2, 2)], 2).PadLeft(32, '0');
            var imm32      = inst.Substring(Decompiler._pos_immediate.Key, Decompiler._pos_immediate.Value)
                             .PadLeft(32, inst.ElementAt(Decompiler._pos_immediate.Key));                                                       // Ext_32
            var branch_offset = imm32.Substring(0, 30).PadRight(32, '0');
            var write_reg     = ctrlsignal.RegDst ? inst.Substring(Decompiler._pos_thirdreg.Key, Decompiler._pos_thirdreg.Value)
                                                                                : ctrlsignal.Jal ? "11111" : inst.Substring(Decompiler._pos_secondreg.Key, Decompiler._pos_secondreg.Value);
            var write_data = string.Empty;
            var mem_data   = string.Empty;

            alu(read_data1,
                ctrlsignal.ALUSrc_B ? imm32 : read_data2,
                ctrlsignal.ALU_Control, ctrlsignal.ALU_Unsigned,
                out zero, out res);
            dataMemory(res,
                       read_data2,
                       ctrlsignal.MemWrite, ctrlsignal.MemRead, ctrlsignal.DataWidth,
                       out mem_data);



            if (ctrlsignal.RegWrite)                                    // register file

            {
                switch (ctrlsignal.DatatoReg)
                {
                case DataToRegSrc.ALURes: write_data = res; break;

                case DataToRegSrc.Mem: write_data = mem_data; break;

                case DataToRegSrc.Imm:                                      // lui
                    write_data = inst.Substring(Decompiler._pos_immediate.Key, Decompiler._pos_immediate.Value).PadRight(32, '0');
                    break;

                case DataToRegSrc.RetAddr: write_data = Convert.ToString(PC + 4, 2).PadLeft(32, '0'); break;                               // jr-ret, write_addr = $ra
                }

                Registers[Convert.ToInt32(write_reg, 2)] = Convert.ToUInt32(write_data, 2);
                Console.WriteLine("Register $" + Utils.BintoRegName(write_reg) + " = " + Convert.ToString(Convert.ToUInt32(write_data, 2), 16));
            }

            UInt32 tempPC = 0;

            switch ((Convert.ToInt32(ctrlsignal.Jump) << 1) + Convert.ToInt32(ctrlsignal.Branch))
            {
            case 0: tempPC = PC_4; break;

            case 1: tempPC = PC_4 + ((ctrlsignal.IsBeq && zero) || (!ctrlsignal.IsBeq && !zero) ? Convert.ToUInt32(branch_offset, 2) : 0); break;

            case 2: tempPC = Convert.ToUInt32(read_data1, 2); break;                                            // jr

            case 3: tempPC = Convert.ToUInt32(jumpaddr, 2); break;
            }

            pc_out = Convert.ToString(tempPC, 2).PadLeft(32, '0');
            Console.WriteLine("PC_Out = 0x" + Convert.ToString(Convert.ToUInt32(pc_out, 2), 16));
            return;
        }
示例#3
0
        private void cpu_control(string inst31_26, string inst5_0, bool zero, out ControlSignalStruct ctrlsig)
        {
            ctrlsig = new ControlSignalStruct( );
            ctrlsig.init( );

            // Decode inst(31:26) - opcode

            switch (inst31_26)
            {
            case "000000":                          // R-Type
                ctrlsig.RegWrite = true;
                ctrlsig.RegDst   = true;
                break;

            case "001000":                          // addi
                ctrlsig.RegWrite    = true;
                ctrlsig.ExtSign     = true;
                ctrlsig.ALUSrc_B    = true;                         // imm32
                ctrlsig.ALU_Control = ALUOperation.ADD;
                break;

            case "001001":                          // addiu
                ctrlsig.ALU_Unsigned = true;
                ctrlsig.RegWrite     = true;
                ctrlsig.ALUSrc_B     = true;                        // imm32
                ctrlsig.ALU_Control  = ALUOperation.ADD;
                break;

            case "001100":                          // andi
                ctrlsig.RegWrite    = true;
                ctrlsig.ALUSrc_B    = true;         // imm32
                ctrlsig.ALU_Control = ALUOperation.AND;
                break;

            case "001101":                          // ori
                ctrlsig.RegWrite    = true;
                ctrlsig.ALUSrc_B    = true;         // imm32
                ctrlsig.ALU_Control = ALUOperation.OR;
                break;

            case "001110":                          // xori
                ctrlsig.RegWrite    = true;
                ctrlsig.ALUSrc_B    = true;         // imm32
                ctrlsig.ALU_Control = ALUOperation.XOR;
                break;

            case "000100":                          // beq
                ctrlsig.IsBeq       = true;
                ctrlsig.ALU_Control = ALUOperation.SUB;
                ctrlsig.Branch      = true;
                break;

            case "000101":                          // bne

                ctrlsig.ALU_Control = ALUOperation.SUB;
                ctrlsig.Branch      = true;
                break;

            case "000010":                          // j
                ctrlsig.Jump   = true;
                ctrlsig.Branch = true;
                break;

            case "000011":                          // jal
                // J-Type
                ctrlsig.RegWrite  = true;
                ctrlsig.Jump      = true;
                ctrlsig.Jal       = true;
                ctrlsig.Branch    = true;
                ctrlsig.DatatoReg = DataToRegSrc.RetAddr;
                break;

            case "001111":                          // lui
                ctrlsig.DatatoReg = DataToRegSrc.Imm;
                ctrlsig.RegWrite  = true;
                break;

            case "100011":                          // lw
                // Load
                ctrlsig.ALUSrc_B    = true;
                ctrlsig.MemtoReg    = true;
                ctrlsig.MemRead     = true;
                ctrlsig.RegWrite    = true;
                ctrlsig.DataWidth   = 32;
                ctrlsig.ALU_Control = ALUOperation.ADD;
                break;

            case "101000":                          // sb
                ctrlsig.MemWrite    = true;
                ctrlsig.ALUSrc_B    = true;
                ctrlsig.DataWidth   = 8;
                ctrlsig.ALU_Control = ALUOperation.ADD;
                break;

            case "101001":
                ctrlsig.MemWrite    = true;
                ctrlsig.ALUSrc_B    = true;
                ctrlsig.DataWidth   = 16;
                ctrlsig.ALU_Control = ALUOperation.ADD;
                break;

            case "101011":          // sw
                // Save
                ctrlsig.MemWrite    = true;
                ctrlsig.ALUSrc_B    = true;
                ctrlsig.DataWidth   = 32;
                ctrlsig.ALU_Control = ALUOperation.ADD;
                break;

            case "001010":                          // slti
                ctrlsig.ALU_Control = ALUOperation.SLT;
                ctrlsig.RegWrite    = true;
                ctrlsig.ALUSrc_B    = true;
                break;

            case "001011":                           // sltiu
                ctrlsig.ALU_Control  = ALUOperation.SLT;
                ctrlsig.RegWrite     = true;
                ctrlsig.ALUSrc_B     = true;
                ctrlsig.ALU_Unsigned = true;
                break;

            default:
                throw new MIPSAssemblerException("CPU Control (Opcode) Error");
            }

            // Decode inst(5:0) - function code
            if (inst31_26 == "000000")
            {
                switch (inst5_0)
                {
                case "100001":                          // addu
                    ctrlsig.ALU_Unsigned = true;
                    ctrlsig.ALU_Control  = ALUOperation.ADD;
                    break;

                case "100000":
                    ctrlsig.ALU_Control = ALUOperation.ADD;
                    break;

                case "100100":
                    ctrlsig.ALU_Control = ALUOperation.AND;
                    break;

                case "100111":
                    ctrlsig.ALU_Control = ALUOperation.NOR;
                    break;

                case "100101":
                    ctrlsig.ALU_Control = ALUOperation.OR;
                    break;

                case "101010":
                    ctrlsig.ALU_Control = ALUOperation.SLT;
                    break;

                case "101011":                          // sltu
                    ctrlsig.ALU_Unsigned = true;
                    ctrlsig.ALU_Control  = ALUOperation.SLT;
                    break;

                case "100010":
                    ctrlsig.ALU_Control = ALUOperation.SUB;
                    break;

                case "100011":
                    ctrlsig.ALU_Unsigned = true;
                    ctrlsig.ALU_Control  = ALUOperation.SUB;
                    break;

                case "100110":
                    ctrlsig.ALU_Control = ALUOperation.XOR;
                    break;

                case "001000":                              // jr
                    ctrlsig.ALU_Control = ALUOperation.ERROR;
                    ctrlsig.Jump        = true;
                    break;

                case "000000":                              // sll
                    ctrlsig.ALU_Control = ALUOperation.SLL;
                    ctrlsig.ALUSrc_B    = true;
                    break;

                case "000010":                              // srl
                    ctrlsig.ALU_Control = ALUOperation.SRL;
                    ctrlsig.ALUSrc_B    = true;
                    break;

                default:
                    throw new MIPSAssemblerException("CPU Control (Function Code) Error");
                }
            }
            return;
        }