|
@@ -46,6 +46,7 @@ using System.Reflection;
|
|
|
using MECF.Framework.UI.Client.CenterViews.Editors.Recipe;
|
|
using MECF.Framework.UI.Client.CenterViews.Editors.Recipe;
|
|
|
using MECF.Framework.Common.Tolerance;
|
|
using MECF.Framework.Common.Tolerance;
|
|
|
using MECF.Framework.Common.CommonData.SorterDefines;
|
|
using MECF.Framework.Common.CommonData.SorterDefines;
|
|
|
|
|
+using MECF.Framework.Common.Extens;
|
|
|
|
|
|
|
|
namespace FurnaceRT.Equipments.Jobs
|
|
namespace FurnaceRT.Equipments.Jobs
|
|
|
{
|
|
{
|
|
@@ -4700,6 +4701,70 @@ namespace FurnaceRT.Equipments.Jobs
|
|
|
var sideDummySlots = GetWaferSlots(layoutRecipeDataExpert, WaferType.SD);
|
|
var sideDummySlots = GetWaferSlots(layoutRecipeDataExpert, WaferType.SD);
|
|
|
var extraDummySlots = GetWaferSlots(layoutRecipeDataExpert, WaferType.ED);
|
|
var extraDummySlots = GetWaferSlots(layoutRecipeDataExpert, WaferType.ED);
|
|
|
|
|
|
|
|
|
|
+ if (layoutRecipeDataConfig.FillDummyTransfer.ToLower() == "exist" && layoutRecipeDataConfig.ProductZeroNotFill.ToLower() == "exist" && layoutRecipeDataConfig.ProductTransferPosition.ToLower() == "none")
|
|
|
|
|
+ {
|
|
|
|
|
+ var pjPWaferCount = GetCurrentWaferNum(pj, WaferType.P, out bool pSlotSelectA);
|
|
|
|
|
+ if (pjPWaferCount == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ reason = $"layout recipe P wafer number={productSlots.Count} greater than current production wafer number={pjPWaferCount}";
|
|
|
|
|
+
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ int currentPWaferNum = GetCurrentDummyWaferNum(WaferType.P, true);
|
|
|
|
|
+ int currentEDWaferNum = GetCurrentDummyWaferNum(WaferType.ED);
|
|
|
|
|
+ int currentSDWaferNum = GetCurrentDummyWaferNum(WaferType.SD);
|
|
|
|
|
+ var needPAndCurrect = productSlots.Count - pjPWaferCount;
|
|
|
|
|
+ //实际p少于配置的P
|
|
|
|
|
+ if (needPAndCurrect > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ //判断dumy是否够补充p类型
|
|
|
|
|
+ var edAndSdComparePWafer = (currentSDWaferNum + currentEDWaferNum) >= needPAndCurrect;
|
|
|
|
|
+ if (edAndSdComparePWafer)
|
|
|
|
|
+ {
|
|
|
|
|
+
|
|
|
|
|
+ for (int i = 0; i < layoutRecipeDataExpert.Items.Count; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (layoutRecipeDataExpert.Items[i].ToLower() == WaferType.P.ToDescription())
|
|
|
|
|
+ {
|
|
|
|
|
+ if (needPAndCurrect == 0)
|
|
|
|
|
+ continue;
|
|
|
|
|
+
|
|
|
|
|
+ if (currentEDWaferNum > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ layoutRecipeDataExpert.Items[i] = WaferType.ED.ToDescription().ToUpper();
|
|
|
|
|
+ currentEDWaferNum--;
|
|
|
|
|
+ needPAndCurrect--;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (currentSDWaferNum > 0 && layoutRecipeDataExpert.Items[i].ToLower() == WaferType.P.ToDescription())
|
|
|
|
|
+ {
|
|
|
|
|
+ layoutRecipeDataExpert.Items[i] = WaferType.SD.ToString();
|
|
|
|
|
+ currentSDWaferNum--;
|
|
|
|
|
+ needPAndCurrect--;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ reason = $"layout recipe P waferNumber={productSlots.Count}, select P waferNumber={pjPWaferCount},current SD waferNumber={currentSDWaferNum},current ED Wafer {currentEDWaferNum}, Not enough to supplement P";
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ productSlots = GetWaferSlots(layoutRecipeDataExpert, WaferType.P);
|
|
|
|
|
+ monitor1Slots = GetWaferSlots(layoutRecipeDataExpert, WaferType.M1);
|
|
|
|
|
+ monitor2Slots = GetWaferSlots(layoutRecipeDataExpert, WaferType.M2);
|
|
|
|
|
+ sideDummySlots = GetWaferSlots(layoutRecipeDataExpert, WaferType.SD);
|
|
|
|
|
+ extraDummySlots = GetWaferSlots(layoutRecipeDataExpert, WaferType.ED);
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
int iNeedCassetteNum;
|
|
int iNeedCassetteNum;
|
|
|
var temp = (float)productSlots.Count / iCassetteSlotCount;
|
|
var temp = (float)productSlots.Count / iCassetteSlotCount;
|
|
|
iNeedCassetteNum = (int)Math.Ceiling(temp);
|
|
iNeedCassetteNum = (int)Math.Ceiling(temp);
|
|
@@ -4736,7 +4801,7 @@ namespace FurnaceRT.Equipments.Jobs
|
|
|
// reason = "extra dummy wafer are short.";
|
|
// reason = "extra dummy wafer are short.";
|
|
|
// return false;
|
|
// return false;
|
|
|
//}
|
|
//}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
|
|
if (SC.GetStringValue("System.ChargingOrderToBoat") == "FromTopToBottom")
|
|
if (SC.GetStringValue("System.ChargingOrderToBoat") == "FromTopToBottom")
|
|
@@ -4755,19 +4820,7 @@ namespace FurnaceRT.Equipments.Jobs
|
|
|
monitor2Slots.Sort((x, y) => x.CompareTo(y));//升序
|
|
monitor2Slots.Sort((x, y) => x.CompareTo(y));//升序
|
|
|
productSlots.Sort((x, y) => x.CompareTo(y));//升序
|
|
productSlots.Sort((x, y) => x.CompareTo(y));//升序
|
|
|
}
|
|
}
|
|
|
- //if (layoutRecipeDataConfig.FillDummyTransfer.ToLower() == "exist" && layoutRecipeDataConfig.ProductZeroNotFill.ToLower() == "exist" && layoutRecipeDataConfig.ProductTransferPosition.ToLower() == "none")
|
|
|
|
|
- //{
|
|
|
|
|
- // int currentPWaferNum = GetCurrentDummyWaferNum(WaferType.P);
|
|
|
|
|
- // //dumy wafer补充p逻辑
|
|
|
|
|
- // var needPAndCurrect = productSlots.Count - iCurrentPWaferNum;
|
|
|
|
|
- // if (needPAndCurrect > 0)
|
|
|
|
|
- // {
|
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
- // }
|
|
|
|
|
-
|
|
|
|
|
- // return false;
|
|
|
|
|
- //}
|
|
|
|
|
pj.SideDummySlots = sideDummySlots;
|
|
pj.SideDummySlots = sideDummySlots;
|
|
|
pj.ExtraDummySlots = extraDummySlots;
|
|
pj.ExtraDummySlots = extraDummySlots;
|
|
|
pj.Monitor1Slots = monitor1Slots;
|
|
pj.Monitor1Slots = monitor1Slots;
|
|
@@ -5314,7 +5367,6 @@ namespace FurnaceRT.Equipments.Jobs
|
|
|
|
|
|
|
|
return iWaferNum;
|
|
return iWaferNum;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
private int GetCurrentDummyWaferNum(WaferType targetWaferType, bool isPWafer = false)
|
|
private int GetCurrentDummyWaferNum(WaferType targetWaferType, bool isPWafer = false)
|
|
|
{
|
|
{
|
|
|
int iWaferNum = 0;
|
|
int iWaferNum = 0;
|
|
@@ -5340,12 +5392,82 @@ namespace FurnaceRT.Equipments.Jobs
|
|
|
{
|
|
{
|
|
|
|
|
|
|
|
if (!wafer.IsEmpty && wafer.WaferType == targetWaferType)
|
|
if (!wafer.IsEmpty && wafer.WaferType == targetWaferType)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (isPWafer)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (wafer.ProcessState == EnumWaferProcessStatus.Idle)
|
|
|
|
|
+ {
|
|
|
|
|
+ iWaferNum++;
|
|
|
|
|
+ }
|
|
|
|
|
+ continue;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
iWaferNum++;
|
|
iWaferNum++;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return iWaferNum;
|
|
return iWaferNum;
|
|
|
}
|
|
}
|
|
|
|
|
+ private Dictionary<string, List<int>> GetCurrentWaferFoupSlot(WaferType targetWaferType, bool isPWafer = false)
|
|
|
|
|
+ {
|
|
|
|
|
+ Dictionary<string, List<int>> result = new Dictionary<string, List<int>>();
|
|
|
|
|
+ int iWaferNum = 0;
|
|
|
|
|
+ var targetCarrierType = (CarrierType)(Enum.Parse(typeof(CarrierType), targetWaferType.ToString()));
|
|
|
|
|
+ foreach (var module in Singleton<EquipmentManager>.Instance.Modules.Keys)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (module == ModuleName.SMIFA || module == ModuleName.SMIFB || module == ModuleName.Boat)
|
|
|
|
|
+ continue;
|
|
|
|
|
+
|
|
|
|
|
+ if (ModuleHelper.IsStocker(module))
|
|
|
|
|
+ {
|
|
|
|
|
+ var carrier = CarrierManager.Instance.GetCarrier(module);
|
|
|
|
|
+ if (carrier == null || carrier.IsEmpty || carrier.CarrierType != targetCarrierType)
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ var wafers = WaferManager.Instance.GetWafers(module);
|
|
|
|
|
+
|
|
|
|
|
+ if (wafers == null)
|
|
|
|
|
+ continue;
|
|
|
|
|
+ List<int> waferSlot = new List<int>();
|
|
|
|
|
+ foreach (var wafer in wafers)
|
|
|
|
|
+ {
|
|
|
|
|
+
|
|
|
|
|
+ if (!wafer.IsEmpty && wafer.WaferType == targetWaferType)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (isPWafer)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (wafer.ProcessState == EnumWaferProcessStatus.Idle)
|
|
|
|
|
+ {
|
|
|
|
|
+ iWaferNum++;
|
|
|
|
|
+
|
|
|
|
|
+ if (!waferSlot.Contains(wafer.Slot))
|
|
|
|
|
+ {
|
|
|
|
|
+ waferSlot.Add(wafer.Slot);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ continue;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ iWaferNum++;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (wafers.Count() > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ result.Add(module.ToString(), waferSlot);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
private bool CassetteShortWaferInCassetteShort(ProcessJobInfo pj, ref List<string> adjustslot, ref int currentEDNum, RecipeLayoutEntityNormal layoutRecipeDataNormal, RecipeLayoutEntityExpert layoutRecipeDataExpert, bool cassetteSupplyED, bool waferSupplyED)
|
|
private bool CassetteShortWaferInCassetteShort(ProcessJobInfo pj, ref List<string> adjustslot, ref int currentEDNum, RecipeLayoutEntityNormal layoutRecipeDataNormal, RecipeLayoutEntityExpert layoutRecipeDataExpert, bool cassetteSupplyED, bool waferSupplyED)
|
|
|
{
|
|
{
|