|
@@ -56,10 +56,13 @@ namespace Venus_RT.Modules
|
|
|
public ModulePriority Priority { get; set; }
|
|
|
public MovingStatus MovingStatus { get; set; }
|
|
|
|
|
|
+ public bool InUsed { get; set; }
|
|
|
+
|
|
|
public ModuleFlag(ModulePriority _priority)
|
|
|
{
|
|
|
Priority = _priority;
|
|
|
MovingStatus = MovingStatus.Idle;
|
|
|
+ InUsed = true;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -80,10 +83,10 @@ namespace Venus_RT.Modules
|
|
|
SchedulerTMRobot _tmRobot = (SchedulerTMRobot)Singleton<TransferModule>.Instance.GetScheduler(ModuleName.TMRobot);
|
|
|
SchedulerEfemRobot _efemRobot = (SchedulerEfemRobot)Singleton<TransferModule>.Instance.GetScheduler(ModuleName.EfemRobot);
|
|
|
|
|
|
- List<SlotItem> _vacReadyOutSlots = new List<SlotItem>();
|
|
|
- List<SlotItem> _vacReadyInSlots = new List<SlotItem>();
|
|
|
- List<SlotItem> _atmReadyOutSlots = new List<SlotItem>();
|
|
|
- List<SlotItem> _atmReadyInSlots = new List<SlotItem>();
|
|
|
+ Dictionary<SlotItem, long> _vacReadyOutSlots = new Dictionary<SlotItem, long>();
|
|
|
+ Dictionary<SlotItem, long> _vacReadyInSlots = new Dictionary<SlotItem, long>();
|
|
|
+ Dictionary<SlotItem, long> _atmReadyOutSlots = new Dictionary<SlotItem, long>();
|
|
|
+ Dictionary<SlotItem, long> _atmReadyInSlots = new Dictionary<SlotItem, long>();
|
|
|
|
|
|
List<int> _LLAInSlot = new List<int> { 0, 1, 2, 3 };
|
|
|
List<int> _LLAOutSlot = new List<int> { 0, 1, 2, 3 };
|
|
@@ -605,7 +608,7 @@ namespace Venus_RT.Modules
|
|
|
|
|
|
if(WaferManager.Instance.CheckHasWafer(mod.Key, slot) && IsVacWaferReadyOut(mod.Key, slot))
|
|
|
{
|
|
|
- _vacReadyOutSlots.Add(new SlotItem(mod.Key, slot));
|
|
|
+ _vacReadyOutSlots.Add(new SlotItem(mod.Key, slot), mod.Value.WaferArrivedTicks(slot));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -617,7 +620,7 @@ namespace Venus_RT.Modules
|
|
|
|
|
|
if (WaferManager.Instance.CheckNoWafer(mod.Key, slot))
|
|
|
{
|
|
|
- _vacReadyInSlots.Add(new SlotItem(mod.Key, slot));
|
|
|
+ _vacReadyInSlots.Add(new SlotItem(mod.Key, slot), mod.Value.WaferArrivedTicks(slot));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -625,15 +628,17 @@ namespace Venus_RT.Modules
|
|
|
{
|
|
|
if(WaferManager.Instance.CheckHasWafer(mod.Key, 0) && IsVacWaferReadyOut(mod.Key, 0)) // processed?
|
|
|
{
|
|
|
- _vacReadyOutSlots.Add(new SlotItem(mod.Key, 0));
|
|
|
+ _vacReadyOutSlots.Add(new SlotItem(mod.Key, 0), mod.Value.WaferArrivedTicks(0));
|
|
|
}
|
|
|
else if(WaferManager.Instance.CheckNoWafer(mod.Key, 0))
|
|
|
{
|
|
|
- _vacReadyInSlots.Add(new SlotItem(mod.Key, 0));
|
|
|
+ _vacReadyInSlots.Add(new SlotItem(mod.Key, 0), mod.Value.WaferArrivedTicks(0));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ _vacReadyOutSlots = _vacReadyOutSlots.OrderByDescending(item => item.Value).ToDictionary(k => k.Key, v => v.Value);
|
|
|
}
|
|
|
|
|
|
bool SearchWaferDestination(SlotItem outSlot, out SlotItem destSlot)
|
|
@@ -651,12 +656,14 @@ namespace Venus_RT.Modules
|
|
|
if (_movingItems.Exists(mItem => mItem.DestinationModule == next_module && mItem.DestinationSlot == nSlot))
|
|
|
continue;
|
|
|
|
|
|
- var ready_in = _vacReadyInSlots.Find(item => item.Module == next_module && item.Slot == nSlot);
|
|
|
- if (ready_in != null && _vacModules[ready_in.Module].MovingStatus != MovingStatus.Moving)
|
|
|
+ foreach(var inItem in _vacReadyInSlots)
|
|
|
{
|
|
|
- destSlot.Module = ready_in.Module;
|
|
|
- destSlot.Slot = nSlot;
|
|
|
- return true;
|
|
|
+ if(inItem.Key.Module == next_module && inItem.Key.Slot == nSlot && _vacModules[next_module].MovingStatus != MovingStatus.Moving)
|
|
|
+ {
|
|
|
+ destSlot.Module = next_module;
|
|
|
+ destSlot.Slot = nSlot;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -721,24 +728,24 @@ namespace Venus_RT.Modules
|
|
|
var validSlots = GetModuleValidSlots(inModule);
|
|
|
foreach(var slot in _vacReadyOutSlots)
|
|
|
{
|
|
|
- if (slot.Module == inModule && _vacModules[slot.Module].MovingStatus == MovingStatus.Moving)
|
|
|
+ if (slot.Key.Module == inModule && _vacModules[slot.Key.Module].MovingStatus == MovingStatus.Moving)
|
|
|
continue;
|
|
|
|
|
|
- if (IsLoadLockReservedByEFEM(slot.Module))
|
|
|
+ if (IsLoadLockReservedByEFEM(slot.Key.Module))
|
|
|
continue;
|
|
|
|
|
|
- var wafer = GetCloneWafer(slot.Module, slot.Slot);
|
|
|
+ var wafer = GetCloneWafer(slot.Key.Module, slot.Key.Slot);
|
|
|
|
|
|
if (wafer.IsEmpty || wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null || wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
|
|
|
continue;
|
|
|
|
|
|
foreach (var next_module in wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules)
|
|
|
{
|
|
|
- if(next_module == inModule && validSlots.Count > 0 && !_movingItems.Exists(item => item.SourceModule == slot.Module && item.SourceSlot == slot.Slot))
|
|
|
+ if(next_module == inModule && validSlots.Count > 0 && !_movingItems.Exists(item => item.SourceModule == slot.Key.Module && item.SourceSlot == slot.Key.Slot))
|
|
|
{
|
|
|
- if(!inSlots.Exists(item => item.SourceModule == slot.Module && item.SourceSlot == slot.Slot))
|
|
|
+ if(!inSlots.Exists(item => item.SourceModule == slot.Key.Module && item.SourceSlot == slot.Key.Slot))
|
|
|
{
|
|
|
- inSlots.Add(new MoveItem(slot.Module, slot.Slot, inModule, validSlots.First(), Hand.None));
|
|
|
+ inSlots.Add(new MoveItem(slot.Key.Module, slot.Key.Slot, inModule, validSlots.First(), Hand.None));
|
|
|
}
|
|
|
|
|
|
validSlots.RemoveAt(0);
|
|
@@ -781,34 +788,36 @@ namespace Venus_RT.Modules
|
|
|
|
|
|
foreach(var slot in _vacReadyOutSlots)
|
|
|
{
|
|
|
- if (_vacModules[slot.Module].MovingStatus != MovingStatus.Idle)
|
|
|
+ if (_vacModules[slot.Key.Module].MovingStatus != MovingStatus.Idle)
|
|
|
continue;
|
|
|
|
|
|
- if (ModuleHelper.IsLoadLock(slot.Module))
|
|
|
+ if (ModuleHelper.IsLoadLock(slot.Key.Module))
|
|
|
{
|
|
|
- if (IsLoadLockReservedByEFEM(slot.Module))
|
|
|
+ if (IsLoadLockReservedByEFEM(slot.Key.Module))
|
|
|
continue;
|
|
|
|
|
|
- if(SearchWaferDestination(slot, out SlotItem destSlot))
|
|
|
+ if(SearchWaferDestination(slot.Key, out SlotItem destSlot))
|
|
|
{
|
|
|
- _movingItems.Add(new MoveItem(slot.Module, slot.Slot, destSlot.Module, destSlot.Slot, Hand.None));
|
|
|
- UpdateModuleMovingStatus(slot.Module);
|
|
|
+ _movingItems.Add(new MoveItem(slot.Key.Module, slot.Key.Slot, destSlot.Module, destSlot.Slot, Hand.None));
|
|
|
+ UpdateModuleMovingStatus(slot.Key.Module);
|
|
|
UpdateModuleMovingStatus(destSlot.Module);
|
|
|
|
|
|
// check whether match double pick pattern
|
|
|
- var out_slot_2 = _vacReadyOutSlots.Find(item => item.Module == slot.Module && item.Slot != slot.Slot);
|
|
|
- if (out_slot_2 != null)
|
|
|
+ foreach(var item in _vacReadyOutSlots)
|
|
|
{
|
|
|
- if(SearchWaferDestination(out_slot_2, out SlotItem destSlot_2))
|
|
|
+ if(item.Key.Module == slot.Key.Module && item.Key.Slot != slot.Key.Slot)
|
|
|
{
|
|
|
- _movingItems.Add(new MoveItem(out_slot_2.Module, out_slot_2.Slot, destSlot_2.Module, destSlot_2.Slot, Hand.None));
|
|
|
- UpdateModuleMovingStatus(out_slot_2.Module);
|
|
|
- UpdateModuleMovingStatus(destSlot_2.Module);
|
|
|
+ if (SearchWaferDestination(item.Key, out SlotItem destSlot_2))
|
|
|
+ {
|
|
|
+ _movingItems.Add(new MoveItem(item.Key.Module, item.Key.Slot, destSlot_2.Module, destSlot_2.Slot, Hand.None));
|
|
|
+ UpdateModuleMovingStatus(item.Key.Module);
|
|
|
+ UpdateModuleMovingStatus(destSlot_2.Module);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// check whether match swap pattern
|
|
|
- var in_slots = SearchWaitInSlots(slot.Module);
|
|
|
+ var in_slots = SearchWaitInSlots(slot.Key.Module);
|
|
|
foreach(var in_slot in in_slots)
|
|
|
{
|
|
|
if(_vacModules[in_slot.Module].MovingStatus == MovingStatus.Idle)
|
|
@@ -823,14 +832,14 @@ namespace Venus_RT.Modules
|
|
|
}
|
|
|
else // PM
|
|
|
{
|
|
|
- if(SearchWaferDestination(slot, out SlotItem destSlot))
|
|
|
+ if(SearchWaferDestination(slot.Key, out SlotItem destSlot))
|
|
|
{
|
|
|
- _movingItems.Add(new MoveItem(slot.Module, slot.Slot, destSlot.Module, destSlot.Slot, Hand.None));
|
|
|
- UpdateModuleMovingStatus(slot.Module);
|
|
|
+ _movingItems.Add(new MoveItem(slot.Key.Module, slot.Key.Slot, destSlot.Module, destSlot.Slot, Hand.None));
|
|
|
+ UpdateModuleMovingStatus(slot.Key.Module);
|
|
|
UpdateModuleMovingStatus(destSlot.Module);
|
|
|
|
|
|
// check whether match swap pattern
|
|
|
- var in_slots = SearchWaitInSlots(slot.Module);
|
|
|
+ var in_slots = SearchWaitInSlots(slot.Key.Module);
|
|
|
if(in_slots.Count >= 1)
|
|
|
{
|
|
|
_movingItems.Add(in_slots.First());
|
|
@@ -1116,7 +1125,7 @@ namespace Venus_RT.Modules
|
|
|
int empty = 0;
|
|
|
foreach (var module in _vacModules)
|
|
|
{
|
|
|
- if (ModuleHelper.IsPm(module.Key))
|
|
|
+ if (ModuleHelper.IsPm(module.Key) && _vacSchedulers[module.Key].IsOnline && module.Value.InUsed)
|
|
|
{
|
|
|
if (WaferManager.Instance.CheckHasWafer(module.Key, 0))
|
|
|
exist++;
|
|
@@ -1183,7 +1192,7 @@ namespace Venus_RT.Modules
|
|
|
int nCount = 0;
|
|
|
foreach(var atmModule in _atmModules)
|
|
|
{
|
|
|
- if (!ModuleHelper.IsEFEMRobot(atmModule.Key) && WaferManager.Instance.CheckHasWafer(atmModule.Key, 0))
|
|
|
+ if (!ModuleHelper.IsEFEMRobot(atmModule.Key) && !ModuleHelper.IsLoadPort(atmModule.Key) && WaferManager.Instance.CheckHasWafer(atmModule.Key, 0))
|
|
|
nCount++;
|
|
|
}
|
|
|
|
|
@@ -1296,11 +1305,13 @@ namespace Venus_RT.Modules
|
|
|
{
|
|
|
if (CheckWaferNeedProcessAndPMAvailable(pjSlotWafer.Item1, pjSlotWafer.Item2))
|
|
|
{
|
|
|
- //return new SlotItem(pjSlotWafer.Item1, pjSlotWafer.Item2);
|
|
|
var wafer = WaferManager.Instance.GetWafer(pjSlotWafer.Item1, pjSlotWafer.Item2);
|
|
|
if(!wafer.IsEmpty && wafer.NextSequenceStep == 0)
|
|
|
{
|
|
|
inSlots.Add(pjSlotWafer.Item2);
|
|
|
+
|
|
|
+ if (inSlots.Count >= 2)
|
|
|
+ return inSlots;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1567,7 +1578,7 @@ namespace Venus_RT.Modules
|
|
|
var pm = _vacSchedulers[stepModule] as SchedulerPM;
|
|
|
if (pm != null)
|
|
|
{
|
|
|
- if (pm.IsAvailable || (pm.IsOnline && pm.Task != SchedulerModule.TaskType.PreJobProcess))
|
|
|
+ if (_vacModules[stepModule].InUsed)
|
|
|
{
|
|
|
hasPmAvailable = true;
|
|
|
break;
|
|
@@ -1690,6 +1701,9 @@ namespace Venus_RT.Modules
|
|
|
{
|
|
|
// wafer arrive
|
|
|
_vacWaferTargets.Remove(tar.Key);
|
|
|
+ if(!ModuleHelper.IsTMRobot(tar.Key.Module))
|
|
|
+ _vacSchedulers[tar.Key.Module].WaferArrived(tar.Key.Slot);
|
|
|
+
|
|
|
LOG.Write(eEvent.EV_ROUTER, ModuleName.System, $"wafer {wafer.WaferOrigin}: {wafer.InnerId} arrived {tar.Key.Module}{tar.Key.Slot + 1}");
|
|
|
if (ModuleHelper.IsPm(tar.Key.Module))
|
|
|
{
|
|
@@ -1735,6 +1749,10 @@ namespace Venus_RT.Modules
|
|
|
{
|
|
|
LOG.Write(eEvent.EV_ROUTER, ModuleName.System, $"wafer {wafer.WaferOrigin}: {wafer.InnerId} arrived {tar.Key.Module}{tar.Key.Slot + 1}");
|
|
|
// wafer arrive
|
|
|
+
|
|
|
+ if(!ModuleHelper.IsLoadPort(tar.Key.Module) && !ModuleHelper.IsEFEMRobot(tar.Key.Module))
|
|
|
+ _atmSchedulers[tar.Key.Module].WaferArrived(tar.Key.Slot);
|
|
|
+
|
|
|
_atmWaferTargets.Remove(tar.Key);
|
|
|
|
|
|
if(ModuleHelper.IsAligner(tar.Key.Module))
|
|
@@ -1859,21 +1877,39 @@ namespace Venus_RT.Modules
|
|
|
}
|
|
|
private bool CheckAllWaferReturned(ProcessJobInfo pj, bool checkAllProcessed)
|
|
|
{
|
|
|
+ bool allWaferReturn = true;
|
|
|
for (int i = 0; i < pj.SlotWafers.Count; ++i)
|
|
|
{
|
|
|
WaferInfo wafer = GetCloneWafer(pj.SlotWafers[i].Item1, pj.SlotWafers[i].Item2);
|
|
|
if (wafer.IsEmpty)
|
|
|
- return false;
|
|
|
+ continue;
|
|
|
|
|
|
- if (checkAllProcessed && IsWaferNeedGotoModule(wafer, ModuleName.PMA) || IsWaferNeedGotoModule(wafer, ModuleName.PMB))
|
|
|
- return false;
|
|
|
+ foreach(var mod in _vacModules)
|
|
|
+ {
|
|
|
+ if(ModuleHelper.IsPm(mod.Key))
|
|
|
+ {
|
|
|
+ if (checkAllProcessed && IsWaferNeedGotoModule(wafer, mod.Key))
|
|
|
+ {
|
|
|
+ mod.Value.InUsed = true;
|
|
|
+ allWaferReturn = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- return true;
|
|
|
+ return allWaferReturn;
|
|
|
}
|
|
|
|
|
|
private void UpdateProcessJobStatus()
|
|
|
{
|
|
|
+ foreach(var mod in _vacModules)
|
|
|
+ {
|
|
|
+ if (ModuleHelper.IsPm(mod.Key))
|
|
|
+ {
|
|
|
+ mod.Value.InUsed = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
foreach (var pj in _lstProcessJobs)
|
|
|
{
|
|
|
if (pj.State == EnumProcessJobState.Processing)
|