/// <summary> /// </summary> /// <param name="pc"></param> /// <param name="instructionCoding"></param> /// <param name="instruction"></param> private void HandleCompliantMode(uint pc, IEnumerable <byte> instructionCoding, Instruction instruction) { Logger.Info("Instruction Detected with Opcode {opcode:X2} and Type {type}", instruction.OpCode, instruction.Type); // If the decoder cannot decode the parameter pattern, throw an exception if (instruction.Type == InstructionType.Unknown) { string unknownOpCodeErrorMessage = String.Format("Error: OpCode = {0}", instruction.OpCode); throw new OpCodeNotSupportedException(unknownOpCodeErrorMessage) { Coding = instructionCoding, Type = instruction.Type, OpCode = instruction.OpCode }; } if (instruction.InstructionLength == 2) { // RVC, Compressed Opcode detected Logger.Info("RVC Compressed Opcode detected"); var payload = rvcDecoder.Decode(instructionCoding); if (payload == null || payload.Type == InstructionType.RVC_Unknown) { Logger.Error("Rvc: No Payload detected"); throw new RiscVSimException("Rvc : No Payload detected!"); } ExecuteRvcOpcode(payload); } if (instruction.InstructionLength == 4) { // Read the complete 32 Bit instruction set for the decoding var inst32Coding = memory.GetWord(pc); var payload = typeDecoder.DecodeType(instruction, inst32Coding); Logger.Info("Instruction to excecute = {ins32}", BitConverter.ToString(inst32Coding.ToArray())); if (payload == null) { Logger.Error("No Payload detected"); throw new RiscVSimException("No Payload detected!"); } // Execute the command environment.NotifyBeforeExec(payload); ExecuteOpcode(instruction, payload); } }
public void Run(IEnumerable <byte> program) { // Init the core Memory.Write(BaseAddres, program); Register.WriteUnsignedInt(Register.ProgramCounter, BaseAddres); var decoder = new InstructionDecoder(EndianCoding); var typeDecoder = new TypeDecoder(); // Create a simple bootstrap CPU var cpu = new Cpu64(); cpu.AssignMemory(Memory); cpu.AssignRegister(Register); cpu.AssignEEI(Environment); cpu.AssignRasStack(RasStack); cpu.AssignCrs(CsrRegister); cpu.Init(); // Fetch the first instruction and run the loop var pc = Register.ReadUnsignedInt(Register.ProgramCounter); // Get the first 2 Bytes from the Base Address aka PC var instructionCoding = Memory.GetHalfWord(pc); while (ContinueIfValid(instructionCoding)) { // Loop for the commands var instruction = decoder.Decode(instructionCoding); InstructionsProcessed.Add(instruction); // If the decoder cannot decode the parameter pattern, throw an exception if (instruction.Type == InstructionType.Unknown) { string unknownOpCodeErrorMessage = String.Format("Error: OpCode = {0}", instruction.OpCode); throw new OpCodeNotSupportedException(unknownOpCodeErrorMessage) { Coding = instructionCoding, Type = instruction.Type, OpCode = instruction.OpCode }; } // Reload the other bytes if required! if (instruction.InstructionLength == 4) { // Read the complete 32 Bit instruction set for the decoding var inst32Coding = Memory.GetWord(pc); var payload = typeDecoder.DecodeType(instruction, inst32Coding); if (payload == null) { throw new RiscVSimException("No Payload available!"); } // For UnitTesting: Add the result to the list InstructionPayloads.Add(payload); // Execute the command cpu.Execute(instruction, payload); } // Done. Next run. pc = Register.ReadUnsignedInt(Register.ProgramCounter); instructionCoding = Memory.GetHalfWord(pc); } }