Exemplo n.º 1
0
        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);
            }
        }
Exemplo n.º 2
0
        /// <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();
        }