/// <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 Test(RvcTestPair pair) { RvcDecoder decoderUT = null; IRvcComposer compuserUT = null; if (pair.TargetArchitecture == Architecture.Rv32I) { decoderUT = decoder32; compuserUT = composer32; } if (pair.TargetArchitecture == Architecture.Rv64I) { decoderUT = decoder64; compuserUT = composer64; } if (pair.IsValid) { var payloadUT = decoderUT.Decode(pair.Coding); Assert.AreEqual(payloadUT.Type, pair.ExpectedPayload.Type); Assert.AreEqual(payloadUT.Op, pair.ExpectedPayload.Op); Assert.AreEqual(payloadUT.Funct3, pair.ExpectedPayload.Funct3); Assert.AreEqual(payloadUT.Rd, pair.ExpectedPayload.Rd); Assert.AreEqual(payloadUT.Rs1, pair.ExpectedPayload.Rs1); Assert.AreEqual(payloadUT.Rs2, pair.ExpectedPayload.Rs2); Assert.AreEqual(payloadUT.Immediate, pair.ExpectedPayload.Immediate); } else { bool excpeptionCaught = false; try { var payload = decoderUT.Decode(pair.Coding); } catch (RiscVSimException) { excpeptionCaught = true; } catch (System.Exception ex) { Assert.Fail("Invalid exception caught!"); } Assert.IsTrue(excpeptionCaught, "Invalid opcode for this architecture!"); } // If InstructionPayload is available generate and compare it via the composer if (pair.ExpectedPayload32 != null) { var payloadUT = decoderUT.Decode(pair.Coding); var instruction = compuserUT.ComposeInstruction(payloadUT); var instructionPayload = compuserUT.Compose(instruction, payloadUT); Assert.AreEqual(pair.ExpectedPayload32.OpCode, instructionPayload.OpCode); Assert.AreEqual(pair.ExpectedPayload32.Rd, instructionPayload.Rd); Assert.AreEqual(pair.ExpectedPayload32.Rs1, instructionPayload.Rs1); Assert.AreEqual(pair.ExpectedPayload32.Rs2, instructionPayload.Rs2); Assert.AreEqual(pair.ExpectedPayload32.Funct3, instructionPayload.Funct3); Assert.AreEqual(pair.ExpectedPayload32.Funct7, instructionPayload.Funct7); Assert.AreEqual(pair.ExpectedPayload32.SignedImmediate, instructionPayload.SignedImmediate); Assert.AreEqual(pair.ExpectedPayload32.UnsignedImmediate, instructionPayload.UnsignedImmediate); Assert.AreEqual(pair.ExpectedPayload32.SignedImmediateComplete, instructionPayload.SignedImmediateComplete); } }