|
@@ -40,6 +40,7 @@ namespace Venus_RT.Modules
|
|
|
Idle,
|
|
|
Waiting,
|
|
|
Moving,
|
|
|
+ Moved,
|
|
|
|
|
|
// PM Status
|
|
|
WaitProcess,
|
|
@@ -152,6 +153,7 @@ namespace Venus_RT.Modules
|
|
|
_cycleSetPoint = _isCycleMode ? SC.GetValue<int>("System.CycleCount") : 0;
|
|
|
_cycledWafer = 0;
|
|
|
_cycledCount = 0;
|
|
|
+ _throughput = 0;
|
|
|
_cycleWatch.Stop();
|
|
|
|
|
|
return RState.Running;
|
|
@@ -525,11 +527,8 @@ namespace Venus_RT.Modules
|
|
|
|
|
|
_lstControlJobs.Clear();
|
|
|
_lstProcessJobs.Clear();
|
|
|
+ _cycleState = RState.End;
|
|
|
|
|
|
- //_mapTarget.Clear();
|
|
|
-
|
|
|
- //queMoveAction.Clear();
|
|
|
- //_curAction.state = ActionState.Done;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -658,7 +657,7 @@ namespace Venus_RT.Modules
|
|
|
bool SearchWaferDestination(SlotItem outSlot, out SlotItem destSlot)
|
|
|
{
|
|
|
destSlot = new SlotItem(ModuleName.System, -1);
|
|
|
- var wafer = GetCloneWafer(outSlot.Module, outSlot.Slot);
|
|
|
+ var wafer = WaferManager.Instance.GetWafer(outSlot.Module, outSlot.Slot);
|
|
|
if (wafer.IsEmpty || wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null || wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
|
|
|
return false;
|
|
|
|
|
@@ -748,7 +747,7 @@ namespace Venus_RT.Modules
|
|
|
if (IsLoadLockReservedByEFEM(slot.Key.Module))
|
|
|
continue;
|
|
|
|
|
|
- var wafer = GetCloneWafer(slot.Key.Module, slot.Key.Slot);
|
|
|
+ var wafer = WaferManager.Instance.GetWafer(slot.Key.Module, slot.Key.Slot);
|
|
|
|
|
|
if (wafer.IsEmpty || wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null || wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
|
|
|
continue;
|
|
@@ -970,7 +969,7 @@ namespace Venus_RT.Modules
|
|
|
|
|
|
private bool IsVacWaferReadyOut(ModuleName mod, int slot)
|
|
|
{
|
|
|
- var wafer = GetCloneWafer(mod, slot);
|
|
|
+ var wafer = WaferManager.Instance.GetWafer(mod, slot);
|
|
|
|
|
|
if (wafer.IsEmpty)
|
|
|
return false;
|
|
@@ -1059,7 +1058,7 @@ namespace Venus_RT.Modules
|
|
|
if (_efemRobotSingleArmOption != 0 && _efemRobotSingleArmOption != i + 1)
|
|
|
continue;
|
|
|
|
|
|
- var wafer = GetCloneWafer(ModuleName.EfemRobot, i);
|
|
|
+ var wafer = WaferManager.Instance.GetWafer(ModuleName.EfemRobot, i);
|
|
|
if (wafer.IsEmpty)
|
|
|
continue;
|
|
|
|
|
@@ -1084,7 +1083,7 @@ namespace Venus_RT.Modules
|
|
|
|
|
|
bool IsAtmWaferReadyOut(ModuleName mod, int slot)
|
|
|
{
|
|
|
- var wafer = GetCloneWafer(mod, slot);
|
|
|
+ var wafer = WaferManager.Instance.GetWafer(mod, slot);
|
|
|
|
|
|
if (wafer.IsEmpty)
|
|
|
return false;
|
|
@@ -1208,10 +1207,18 @@ namespace Venus_RT.Modules
|
|
|
|
|
|
private bool IsLoadLockReservedByTM(ModuleName ll)
|
|
|
{
|
|
|
- if (_movingItems.Exists(item => item.DestinationModule == ll || item.SourceModule == ll))
|
|
|
- return true;
|
|
|
+ List<ModuleName> unfinished = new List<ModuleName>();
|
|
|
+ foreach (var item in _vacWaferTargets)
|
|
|
+ {
|
|
|
+ var moving = _movingItems.Find(m_item => m_item.DestinationModule == item.Key.Module && m_item.DestinationSlot == item.Key.Slot);
|
|
|
+ if (!unfinished.Contains(moving.SourceModule))
|
|
|
+ unfinished.Add(moving.SourceModule);
|
|
|
|
|
|
- return false;
|
|
|
+ if (!unfinished.Contains(moving.DestinationModule))
|
|
|
+ unfinished.Add(moving.DestinationModule);
|
|
|
+ }
|
|
|
+
|
|
|
+ return unfinished.Contains(ll);
|
|
|
}
|
|
|
|
|
|
private Tuple<int, int> GetLLProcessStatusCount(ModuleName ll)
|
|
@@ -1271,14 +1278,14 @@ namespace Venus_RT.Modules
|
|
|
else if(_LLInOutPath == SequenceLLInOutPath.AInAOut || (_LLInOutPath == SequenceLLInOutPath.DInDOut && _vacSchedulers[ModuleName.LLA].IsOnline && !_vacSchedulers[ModuleName.LLB].IsOnline))
|
|
|
{
|
|
|
return llaWaferStatus.Item1 > 0 ? 0 :
|
|
|
- (_LLASlotNumber) / 2 + pmWaferStatus.Item2 - llaWaferStatus.Item2
|
|
|
+ _LLASlotNumber / 2 + pmWaferStatus.Item2 - llaWaferStatus.Item2
|
|
|
- GetTMRobotWaferCount() - GetEfemRoborWaferCount() - GetAtmInerWaferCount();
|
|
|
|
|
|
}
|
|
|
else if (_LLInOutPath == SequenceLLInOutPath.BInBOut || (_LLInOutPath == SequenceLLInOutPath.DInDOut && !_vacSchedulers[ModuleName.LLA].IsOnline && _vacSchedulers[ModuleName.LLB].IsOnline))
|
|
|
{
|
|
|
return llbWaferStatus.Item1 > 0 ? 0 :
|
|
|
- (_LLBSlotNumber) / 2 + pmWaferStatus.Item2 - llbWaferStatus.Item2
|
|
|
+ _LLBSlotNumber / 2 + pmWaferStatus.Item2 - llbWaferStatus.Item2
|
|
|
-GetTMRobotWaferCount() - GetEfemRoborWaferCount() - GetAtmInerWaferCount();
|
|
|
}
|
|
|
else if(_LLInOutPath == SequenceLLInOutPath.DInDOut && _vacSchedulers[ModuleName.LLA].IsOnline && _vacSchedulers[ModuleName.LLB].IsOnline)
|
|
@@ -1298,7 +1305,7 @@ namespace Venus_RT.Modules
|
|
|
|
|
|
private bool IsForwardPathBlocking(ModuleName mod, int slot)
|
|
|
{
|
|
|
- var wafer = GetCloneWafer(mod, slot);
|
|
|
+ var wafer = WaferManager.Instance.GetWafer(mod, slot);
|
|
|
if (wafer.IsEmpty || wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null || wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
|
|
|
return false;
|
|
|
|
|
@@ -1630,7 +1637,7 @@ namespace Venus_RT.Modules
|
|
|
|
|
|
private bool CheckWaferNeedProcessAndPMAvailable(ModuleName waferModule, int waferSlot, ModuleName processIn = ModuleName.System)
|
|
|
{
|
|
|
- WaferInfo wafer = GetCloneWafer(waferModule, waferSlot);
|
|
|
+ WaferInfo wafer = WaferManager.Instance.GetWafer(waferModule, waferSlot);
|
|
|
|
|
|
if (wafer.IsEmpty)
|
|
|
return false;
|
|
@@ -1749,8 +1756,7 @@ namespace Venus_RT.Modules
|
|
|
if (wafer.NextSequenceStep < wafer.ProcessJob.Sequence.Steps.Count && wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(item.DestinationModule))
|
|
|
wafer.NextSequenceStep++;
|
|
|
}
|
|
|
-
|
|
|
- if(wafer.IsEmpty || wafer.ProcessJob == null)
|
|
|
+ else
|
|
|
{
|
|
|
// should not go here
|
|
|
LOG.Write(eEvent.ERR_ROUTER, ModuleName.System, $"UpateSequenceStep() failed, location: {item.DestinationModule}:{item.DestinationSlot + 1}, NextSequenceStep: {wafer.NextSequenceStep}");
|
|
@@ -1758,50 +1764,67 @@ namespace Venus_RT.Modules
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
private void CheckWaferArrived()
|
|
|
{
|
|
|
if (_cycleState != RState.Running)
|
|
|
return;
|
|
|
|
|
|
- foreach (var mod in _vacSchedulers.Append(new KeyValuePair<ModuleName, SchedulerModule>( ModuleName.TMRobot, _tmRobot)))
|
|
|
+ foreach (var mod in _vacSchedulers.Append(new KeyValuePair<ModuleName, SchedulerModule>(ModuleName.TMRobot, _tmRobot)))
|
|
|
{
|
|
|
- //if (mod.Value.IsAvailable)
|
|
|
+ var tars = _vacWaferTargets.Where(item => item.Key.Module == mod.Key).ToArray();
|
|
|
+ foreach (var tar in tars)
|
|
|
{
|
|
|
- var tars = _vacWaferTargets.Where(item => item.Key.Module == mod.Key).ToArray();
|
|
|
- foreach (var tar in tars)
|
|
|
+ var wafer = WaferManager.Instance.GetWafer(tar.Key.Module, tar.Key.Slot);
|
|
|
+ if (wafer.IsEmpty || wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (wafer.InnerId == tar.Value)
|
|
|
{
|
|
|
- var wafer = WaferManager.Instance.GetWafer(tar.Key.Module, tar.Key.Slot);
|
|
|
- if (wafer.IsEmpty)
|
|
|
- continue;
|
|
|
+ // wafer arrive
|
|
|
+ _vacWaferTargets.Remove(tar.Key);
|
|
|
+ if (!ModuleHelper.IsTMRobot(tar.Key.Module))
|
|
|
+ _vacSchedulers[tar.Key.Module].WaferArrived(tar.Key.Slot);
|
|
|
|
|
|
- if (wafer.InnerId == tar.Value)
|
|
|
+ //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))
|
|
|
{
|
|
|
- // 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))
|
|
|
- {
|
|
|
- _vacModules[tar.Key.Module].MovingStatus = MovingStatus.WaitProcess;
|
|
|
- }
|
|
|
+ _vacModules[tar.Key.Module].MovingStatus = MovingStatus.WaitProcess;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ if(ModuleHelper.IsLoadLock(mod.Key))
|
|
|
+ {
|
|
|
+ List<ModuleName> unfinished = new List<ModuleName>();
|
|
|
+ foreach(var item in _vacWaferTargets)
|
|
|
+ {
|
|
|
+ var moving = _movingItems.Find(m_item => m_item.DestinationModule == item.Key.Module && m_item.DestinationSlot == item.Key.Slot);
|
|
|
+ if (!unfinished.Contains(moving.SourceModule))
|
|
|
+ unfinished.Add(moving.SourceModule);
|
|
|
+
|
|
|
+ if (!unfinished.Contains(moving.DestinationModule))
|
|
|
+ unfinished.Add(moving.DestinationModule);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!unfinished.Contains(mod.Key) && mod.Value.IsAvailable)
|
|
|
+ {
|
|
|
+ _vacModules[mod.Key].MovingStatus = MovingStatus.Idle;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- _vacMoveFinishTrig.CLK = _vacWaferTargets.Count == 0;
|
|
|
+ _vacMoveFinishTrig.CLK = _vacWaferTargets.Count == 0 && _tmRobot.RobotStatus != RState.Running;
|
|
|
if (_vacMoveFinishTrig.Q)
|
|
|
{
|
|
|
- foreach(var item in _movingItems)
|
|
|
+ foreach (var item in _movingItems)
|
|
|
{
|
|
|
- if(_vacModules[item.DestinationModule].MovingStatus == MovingStatus.Moving)
|
|
|
+ if (_vacModules[item.DestinationModule].MovingStatus == MovingStatus.Moving)
|
|
|
{
|
|
|
_vacModules[item.DestinationModule].MovingStatus = MovingStatus.Idle;
|
|
|
}
|
|
|
|
|
|
- if(_vacModules[item.SourceModule].MovingStatus == MovingStatus.Moving)
|
|
|
+ if (_vacModules[item.SourceModule].MovingStatus == MovingStatus.Moving)
|
|
|
{
|
|
|
_vacModules[item.SourceModule].MovingStatus = MovingStatus.Idle;
|
|
|
}
|
|
@@ -1811,42 +1834,41 @@ namespace Venus_RT.Modules
|
|
|
_movingItems.Clear();
|
|
|
}
|
|
|
|
|
|
+
|
|
|
foreach (var mod in _atmSchedulers.Append(new KeyValuePair<ModuleName, SchedulerModule>(ModuleName.EfemRobot, _efemRobot)))
|
|
|
{
|
|
|
- //if (mod.Value.IsAvailable)
|
|
|
+ var tars = _atmWaferTargets.Where(item => item.Key.Module == mod.Key).ToArray();
|
|
|
+ foreach (var tar in tars)
|
|
|
{
|
|
|
- var tars = _atmWaferTargets.Where(item => item.Key.Module == mod.Key).ToArray();
|
|
|
- foreach (var tar in tars)
|
|
|
- {
|
|
|
- var wafer = WaferManager.Instance.GetWafer(tar.Key.Module, tar.Key.Slot);
|
|
|
- if (wafer.IsEmpty)
|
|
|
- continue;
|
|
|
+ var wafer = WaferManager.Instance.GetWafer(tar.Key.Module, tar.Key.Slot);
|
|
|
+ if (wafer.IsEmpty || wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
|
|
|
+ continue;
|
|
|
|
|
|
- if (wafer.InnerId == tar.Value)
|
|
|
- {
|
|
|
- //LOG.Write(eEvent.EV_ROUTER, ModuleName.System, $"wafer {wafer.WaferOrigin}: {wafer.InnerId} arrived {tar.Key.Module}{tar.Key.Slot + 1}");
|
|
|
- // wafer arrive
|
|
|
+ if (wafer.InnerId == tar.Value)
|
|
|
+ {
|
|
|
+ //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);
|
|
|
+ if (!ModuleHelper.IsLoadPort(tar.Key.Module) && !ModuleHelper.IsEFEMRobot(tar.Key.Module))
|
|
|
+ _atmSchedulers[tar.Key.Module].WaferArrived(tar.Key.Slot);
|
|
|
|
|
|
- _atmWaferTargets.Remove(tar.Key);
|
|
|
+ _atmWaferTargets.Remove(tar.Key);
|
|
|
|
|
|
- if(ModuleHelper.IsAligner(tar.Key.Module))
|
|
|
- {
|
|
|
- _atmModules[tar.Key.Module].MovingStatus = MovingStatus.WaitAlign;
|
|
|
- }
|
|
|
+ if (ModuleHelper.IsAligner(tar.Key.Module))
|
|
|
+ {
|
|
|
+ _atmModules[tar.Key.Module].MovingStatus = MovingStatus.WaitAlign;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
- _atmMoveFinishTrig.CLK = _atmWaferTargets.Count == 0;
|
|
|
- if(_atmMoveFinishTrig.Q)
|
|
|
+ _atmMoveFinishTrig.CLK = _atmWaferTargets.Count == 0 && _efemRobot.RobotStatus != RState.Running;
|
|
|
+ if (_atmMoveFinishTrig.Q)
|
|
|
{
|
|
|
- foreach(var item in _efemMovingItems)
|
|
|
+ foreach (var item in _efemMovingItems)
|
|
|
{
|
|
|
- if(ModuleHelper.IsLoadLock(item.Module))
|
|
|
+ if (ModuleHelper.IsLoadLock(item.Module))
|
|
|
{
|
|
|
_vacModules[item.Module].MovingStatus = MovingStatus.Idle;
|
|
|
}
|
|
@@ -1855,6 +1877,8 @@ namespace Venus_RT.Modules
|
|
|
UpateSequenceStep(_efemMovingItems);
|
|
|
_efemMovingItems.Clear();
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
private void PreJobClean(ControlJobInfo cj)
|
|
|
{
|
|
@@ -1952,12 +1976,13 @@ namespace Venus_RT.Modules
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
+
|
|
|
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);
|
|
|
+ WaferInfo wafer = WaferManager.Instance.GetWafer(pj.SlotWafers[i].Item1, pj.SlotWafers[i].Item2);
|
|
|
if (wafer.IsEmpty)
|
|
|
continue;
|
|
|
|
|
@@ -1979,6 +2004,9 @@ namespace Venus_RT.Modules
|
|
|
|
|
|
private void UpdateProcessJobStatus()
|
|
|
{
|
|
|
+ if (_efemRobot.RobotStatus == RState.Running)
|
|
|
+ return;
|
|
|
+
|
|
|
foreach(var mod in _vacModules)
|
|
|
{
|
|
|
if (ModuleHelper.IsPm(mod.Key))
|
|
@@ -2022,6 +2050,9 @@ namespace Venus_RT.Modules
|
|
|
if (_lstControlJobs.Count == 0)
|
|
|
return;
|
|
|
|
|
|
+ if (_efemRobot.RobotStatus == RState.Running)
|
|
|
+ return;
|
|
|
+
|
|
|
bool allControlJobComplete = true;
|
|
|
List<ControlJobInfo> cjRemoveList = new List<ControlJobInfo>();
|
|
|
foreach (var cj in _lstControlJobs)
|
|
@@ -2096,16 +2127,24 @@ namespace Venus_RT.Modules
|
|
|
foreach (var pjSlotWafer in pj.SlotWafers)
|
|
|
{
|
|
|
countPerCycle++;
|
|
|
- WaferInfo wafer = GetCloneWafer(pjSlotWafer.Item1, pjSlotWafer.Item2);
|
|
|
+ WaferInfo wafer = WaferManager.Instance.GetWafer(pjSlotWafer.Item1, pjSlotWafer.Item2);
|
|
|
if (!wafer.IsEmpty && !IsWaferNeedGotoModule(wafer, ModuleName.PMA) && !IsWaferNeedGotoModule(wafer, ModuleName.PMB) && !IsWaferNeedGotoModule(wafer, ModuleName.PMC) && !IsWaferNeedGotoModule(wafer, ModuleName.PMD))
|
|
|
countProcessed++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- _cycledWafer = _cycledCount * countPerCycle + countProcessed;
|
|
|
- if(_cycledWafer >= 25)
|
|
|
+ int totalCycleWafer = _cycledCount * countPerCycle + countProcessed;
|
|
|
+ if(_cycledWafer != totalCycleWafer)
|
|
|
{
|
|
|
- _throughput = (float)(_cycledWafer / _cycleWatch.Elapsed.TotalHours);
|
|
|
+ _cycledWafer = totalCycleWafer;
|
|
|
+ if(_cycledWafer >= 25)
|
|
|
+ {
|
|
|
+ _throughput = (float)(_cycledWafer / _cycleWatch.Elapsed.TotalHours);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _throughput = 0;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if (allControlJobComplete)
|