/// <summary>
        /// In the tomasolu there will be a register renaming that will happen in the right back
        /// as it will not wait for the register to free up but will rename one and continue the other
        /// </summary>
        /// <param name="instruction"></param>
        /// <param name="instructions"></param>
        /// <param name="functionalUnits"></param>
        /// <param name="registers"></param>
        protected override void ExecuteInstrution(InstructionWithStatusModel instruction, List <InstructionWithStatusModel> instructions, List <FunctionalUnitWithStatusModel> functionalUnits, List <RegisterResultModel> registers)
        {
            //Get the unit that the instruction is working on
            var unit = functionalUnits.SingleOrDefault(item => item.WorkingInstructionID == instruction.ID);

            if (--unit.Time == 0)
            {
                //Set the clock cycle that is completed executing on
                instruction.ExecuteCompletedCycle = ClockCycle;
            }
            else if (unit.Time < 0)
            {
                unit.Time = 0;
                //Get the register the instruction is working on
                var register        = registers.SingleOrDefault(reg => reg.InstructionReservedRegiseter.SingleOrDefault(inst => inst.InstructionId == instruction.ID) != null);
                var instStatusInReg = register.InstructionReservedRegiseter.SingleOrDefault(item => item.InstructionId == instruction.ID);
                //If its value is false it can not write and has to be register renames
                if (!instStatusInReg.LastIssued)
                {
                    //Then rename the target register of the register renameing process
                    //This way will end the WAW hazard
                    instruction.TargetRegistery = "R1";
                }
                //Always right back the value after the instruction finishs executing
                instruction.WriteBackCycle = ClockCycle;
                ClearUnitFunction(functionalUnits.SingleOrDefault(fcn => fcn.WorkingInstructionID == instruction.ID), registers);
            }
        }
        /// <summary>
        /// Compares between the two instructions
        /// +1  for evert correct value
        /// -1 for every unlike value
        /// -0.25 for every null value that has been set by the student
        /// </summary>
        /// <param name="computerSolution"></param>
        /// <param name="studentSolution"></param>
        /// <returns>The student mark</returns>
        public static float CompareInstructions(this InstructionWithStatusModel computerSolution, InstructionWithStatusModel studentSolution)
        {
            //The student mark
            float mark = 0;

            //Correct each filed
            mark += SharedMethods.CompareFiledsAndGetMark(computerSolution.IssueCycle, studentSolution.IssueCycle);
            mark += SharedMethods.CompareFiledsAndGetMark(computerSolution.ReadCycle, studentSolution.ReadCycle);
            mark += SharedMethods.CompareFiledsAndGetMark(computerSolution.ExecuteCompletedCycle, studentSolution.ExecuteCompletedCycle);
            mark += SharedMethods.CompareFiledsAndGetMark(computerSolution.WriteBackCycle, studentSolution.WriteBackCycle);

            return(mark);
        }
        /// <summary>
        /// Checks if all the hazerds are gone and sets the instruction into issue
        /// </summary>
        /// <param name="instruction">The instruction that we want to issue</param>
        /// <returns></returns>
        protected bool IssueIfApproved(InstructionWithStatusModel instruction, List <FunctionalUnitWithStatusModel> functionalUnits, List <RegisterResultModel> registers)
        {
            foreach (var unit in functionalUnits)
            {
                if (unit.Function.TryGetValue(instruction.Name, out bool value))
                {
                    //Issuee only when functional unit is not busy structural hazard and...
                    if (!unit.IsBusy)
                    {
                        //The target register to write in is free WAW hazard
                        RegisterResultModel registerToTarget;
                        if (instruction.Name == FunctionsTypes.SD)
                        {
                            registerToTarget = registers.SingleOrDefault(reg => reg.Name == instruction.SourceRegistery01);
                        }
                        else
                        {
                            registerToTarget = registers.SingleOrDefault(reg => reg.Name == instruction.TargetRegistery);
                        }

                        instruction.IssueCycle = ClockCycle;

                        //Set it to busy
                        unit.IsBusy = true;
                        //Assign it the operation values
                        unit.WorkingInstructionID = instruction.ID;
                        unit.Operation            = instruction.Name.ToString();
                        unit.SourceRegistery01    = instruction.SourceRegistery01;
                        unit.SourceRegistery02    = instruction.SourceRegistery02;
                        unit.TargetRegistery      = instruction.TargetRegistery;

                        var operationOnSource01 = registers.SingleOrDefault(reg => reg.Name == instruction.SourceRegistery01);
                        var operationOnSource02 = registers.SingleOrDefault(reg => reg.Name == instruction.SourceRegistery02);
                        //The is null for the load as it loads from memory
                        if (operationOnSource01 is null || !operationOnSource01.IsBusy)
                        {
                            unit.IsSource01Ready = true;
                        }
                        else
                        {
                            unit.IsSource01Ready             = false;
                            unit.WaitingOperationForSource01 = operationOnSource01.Operation;
                        }
                        if (operationOnSource02 is null)
                        {
                            unit.IsSource02Ready = false;
                        }
                        else if (!operationOnSource02.IsBusy)
                        {
                            unit.IsSource02Ready = true;
                        }
                        else
                        {
                            unit.IsSource02Ready             = false;
                            unit.WaitingOperationForSource02 = operationOnSource02.Operation;
                        }

                        //Set the register as busy
                        registerToTarget.Operation = unit.Operation == "LD" ? string.Format("F[{0}]", unit.SourceRegistery01) : string.Format("F[{0}]", unit.Name);
                        registerToTarget.IsBusy    = true;
                        if (registerToTarget.InstructionReservedRegiseter.Any())
                        {
                            registerToTarget.InstructionReservedRegiseter.LastOrDefault().LastIssued = false;
                        }

                        //Add it to the reserved instructions
                        registerToTarget.InstructionReservedRegiseter.Add(new InstructionRegisterReservationModel
                        {
                            InstructionId = instruction.ID,
                            LastIssued    = true
                        });
                        return(true);
                    }
                }
            }