/// <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); } } }