public static void RunClock() { //Finished running if PC has exceeded instructions and all previous instructions have already finished running (determined by empty instruction queue) if (!IsReady || (PC.Counter >= Instructions.Count && InstructionQueue.Count == 0)) { return; } AwaitingRegisters.Clear(); ForwardedRegisters.Clear(); if (PC.Counter < Instructions.Count && !_isStalled) { Instructions[PC.Counter].Initialize(_clockCycle); InstructionQueue.Enqueue(Instructions[PC.Counter]); } Instruction[] instructionQueueArray = InstructionQueue.ToArray(); bool isJumpTaken = false; int jumpIndex = 0; _isStalled = false; //Run other stages for previous instructions in queue for (int i = 0; i < instructionQueueArray.Length; ++i) { Instruction instruction = instructionQueueArray[i]; //If stall is needed do not advance any further instructions if (!instruction.AdvanceClock()) { _isStalled = true; break; } //Mark register as awaiting values if (instruction.WriteAwaiting != -1) { AwaitingRegisters.Add(instruction.WriteAwaiting); } //Add forwarded values if (instruction.ForwardedRegister.HasValue) { ForwardedRegisters[instruction.WriteAwaiting] = instruction.ForwardedRegister.Value; } if (instruction.IsJumpTaken() && !isJumpTaken) { var jumpData = instruction.GetJumpData(); if (jumpData.Type == Instruction.JumpType.Branch) { PC.Advance(jumpData.Address); } else if (jumpData.Type == Instruction.JumpType.Jump) { PC.Jump(jumpData.Address); } isJumpTaken = true; jumpIndex = i; } } //Discards instructions after jump or branch statement if (isJumpTaken) { InstructionQueue.Clear(); for (int i = 0; i < jumpIndex; ++i) { InstructionQueue.Enqueue(instructionQueueArray[i]); } } //Dequeue finished instructions if (instructionQueueArray[0].RelativeClock == 4) { InstructionQueue.Dequeue(); } //If no jumps were taken advance program counter by 4 if (!isJumpTaken && !_isStalled) { PC.Advance(); } _clockCycle++; }