public void Execute(Instruction instruction, InstructionPayload payload) { if (!opCodeRegistry.IsInitialized) { Logger.Error("CPU is not initialized"); throw new RiscVSimException("CPU is not initialized: Please call init() first!"); } var curOpCode = instruction.OpCode; // Execute the command now var opCodeCommand = opCodeRegistry.Get(curOpCode); if (opCodeCommand == null) { string opCodeNotSupportedErrorMessage = String.Format("Implementation for OpCode {0} cannot be found", curOpCode); Logger.Error(opCodeNotSupportedErrorMessage); throw new OpCodeNotSupportedException(opCodeNotSupportedErrorMessage); } var incPc = opCodeCommand.Execute(instruction, payload); if (incPc) { register.NextInstruction(instruction.InstructionLength); } }
/// <summary> /// The generic fetch method for all hart implementations /// </summary> private void Fetch() { // Done! // Fetch the first instruction and run the loop. Get the first 2 Bytes from the Base Address aka PC var pc = register.ReadUnsignedInt(register.ProgramCounter); var instructionCoding = memory.GetHalfWord(pc); Logger.Info("Instruction {ins:X} fetched", BitConverter.ToString(instructionCoding.ToArray())); while (ContinueIfValid(instructionCoding)) { // Loop for the commands var instruction = instructionDecoder.Decode(instructionCoding); if (rvMode) { var isCustom = (instructionCoding.First() & 0x7F) == 0x00; if (isCustom) { Logger.Info("Processing RV custom command."); var customCoding = memory.GetWord(pc); var isHalt = customCoding.SequenceEqual(new byte[] { 0x00, 0x00, 0x00, 0x00 }); if (isHalt) { // Stop the simulation! break; } var payload = typeDecoder.DecodeCustom(instruction, customCoding); var rvOpcode = new RvOpcode(memory, register, environment); var inc = rvOpcode.Execute(instruction, payload); if (inc) { // Go to the next instruction... register.NextInstruction(4); } } else { // Handle instruction as usual.. HandleCompliantMode(pc, instructionCoding, instruction); } } else { HandleCompliantMode(pc, instructionCoding, instruction); } // Stop the instruction fetch if an error occured or the state is stopped var currentState = environment.GetCurrentState(); if (currentState == State.FatalError || currentState == State.Stopped) { break; } // Done. Next run. pc = register.ReadUnsignedInt(register.ProgramCounter); instructionCoding = memory.GetHalfWord(pc); Logger.Info("Instruction {ins:X} fetched", BitConverter.ToString(instructionCoding.ToArray())); } if (environment.GetCurrentState() == State.FatalError) { Console.Error.WriteLine("# FATAL ERROR occured : " + environment.GetStateDescription()); } if (environment.GetCurrentState() == State.Stopped) { Console.Out.WriteLine("# Hart Stopped"); } environment.NotifyStopped(); }