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; }
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; }
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; }