WaferTaskManager.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. using Aitex.Core.Common;
  2. using Aitex.Core.RT.Log;
  3. using Aitex.Core.Util;
  4. using MECF.Framework.Common.Equipment;
  5. using MECF.Framework.Common.Jobs;
  6. using MECF.Framework.Common.RecipeCenter;
  7. using MECF.Framework.Common.SubstrateTrackings;
  8. using MECF.Framework.Common.WaferHolder;
  9. using CyberX8_RT.Modules.PUF;
  10. using CyberX8_RT.Modules;
  11. using CyberX8_RT.Schedulers;
  12. using System;
  13. using System.Collections.Concurrent;
  14. using System.Collections.Generic;
  15. using System.Linq;
  16. using System.Text;
  17. using System.Threading.Tasks;
  18. using System.Windows.Markup;
  19. namespace CyberX8_RT.Dispatch
  20. {
  21. public class WaferTaskManager : Singleton<WaferTaskManager>
  22. {
  23. #region 常量
  24. private const string SIDE_A = "SideA";
  25. private const string SIDE_B = "SideB";
  26. #endregion
  27. #region 内部变量
  28. /// <summary>
  29. /// FA回复
  30. /// </summary>
  31. private SchedulerFACallback _schedulerFACallback = new SchedulerFACallback();
  32. /// <summary>
  33. /// 任务锁
  34. /// </summary>
  35. private object _taskLocker = new object();
  36. /// <summary>
  37. /// 任务集合
  38. /// </summary>
  39. private List<WaferTask> _waferTaskList = new List<WaferTask>();
  40. /// <summary>
  41. /// Wafer task字典
  42. /// </summary>
  43. private ConcurrentDictionary<string, WaferTask> _waferTasksDic = new ConcurrentDictionary<string, WaferTask>();
  44. /// <summary>
  45. /// Wafer配对字典(key-自身WaferId,value-配对WaferId)
  46. /// </summary>
  47. private ConcurrentDictionary<string, string> _waferTaskMatchDic = new ConcurrentDictionary<string, string>();
  48. /// <summary>
  49. /// Wafer--WaferHolder任务字典(key-自身WaferId,value-WaferHolder任务)
  50. /// </summary>
  51. private ConcurrentDictionary<string, WaferHolderTask> _waferWaferHolderTaskDic = new ConcurrentDictionary<string, WaferHolderTask>();
  52. #endregion
  53. /// <summary>
  54. /// 初始化Task
  55. /// </summary>
  56. /// <param name="task"></param>
  57. public void InitializeTask(WaferTask task)
  58. {
  59. _waferTasksDic[task.WaferId] = task;
  60. lock(_taskLocker)
  61. {
  62. _waferTaskList.Add(task);
  63. }
  64. }
  65. /// <summary>
  66. /// 获取WaferTask
  67. /// </summary>
  68. /// <param name="waferId"></param>
  69. /// <returns></returns>
  70. public WaferTask GetWaferTask(string waferId)
  71. {
  72. return _waferTasksDic.ContainsKey(waferId) ? _waferTasksDic[waferId] : null;
  73. }
  74. /// <summary>
  75. /// 是否包含
  76. /// </summary>
  77. /// <param name="waferId"></param>
  78. /// <returns></returns>
  79. public bool Contains(string waferId)
  80. {
  81. return _waferTasksDic.ContainsKey(waferId);
  82. }
  83. /// <summary>
  84. /// 移除任务
  85. /// </summary>
  86. /// <param name="waferId"></param>
  87. public void RemoveWaferTask(string waferId)
  88. {
  89. if(_waferTasksDic.ContainsKey(waferId))
  90. {
  91. _waferTasksDic.TryRemove(waferId, out var task);
  92. task.Dispose();
  93. task.OnTaskComplete -= WaferTask_OnTaskComplete;
  94. LOG.WriteBackgroundLog(eEvent.EV_SCHEDULER, "Scheduler", $"remove wafer {waferId} task");
  95. }
  96. if(_waferTaskMatchDic.ContainsKey(waferId))
  97. {
  98. _waferTaskMatchDic.TryRemove(waferId,out var taskMath);
  99. }
  100. lock(_taskLocker)
  101. {
  102. int index = _waferTaskList.FindIndex(O => O.WaferId == waferId);
  103. if (index >= 0)
  104. {
  105. _waferTaskList.RemoveAt(index);
  106. }
  107. }
  108. }
  109. /// <summary>
  110. /// 加载Wafer Task集合
  111. /// </summary>
  112. /// <returns></returns>
  113. public List<WaferTask> LoadWaferTaskList()
  114. {
  115. return _waferTaskList.ToList();
  116. }
  117. /// <summary>
  118. /// 创建Wafer任务
  119. /// </summary>
  120. public int CreateWaferTask(List<ProcessJobInfo> processJobInfos, WaferHolderInfo waferHolderInfo,WaferHolderTask waferHolderTask)
  121. {
  122. int count = 0;
  123. string mateWaferTask = "";
  124. List<WaferInfo> wafers = new List<WaferInfo>();
  125. for(int i=0; i<processJobInfos.Count;i++)
  126. {
  127. ProcessJobInfo processJobInfo = processJobInfos[i];
  128. for(int j=0;j< processJobInfo.SlotWafers.Count; j++)
  129. {
  130. var item = processJobInfo.SlotWafers[j];
  131. if (WaferManager.Instance.CheckHasWafer(item.Item1, item.Item2))
  132. {
  133. WaferInfo waferInfo = WaferManager.Instance.GetWafer(item.Item1, item.Item2);
  134. if (waferInfo != null && waferInfo.ProcessState == EnumWaferProcessStatus.Idle)
  135. {
  136. if (!Contains(waferInfo.WaferID))
  137. {
  138. if (count == 0)
  139. {
  140. wafers.Add(waferInfo);
  141. count++;
  142. }
  143. else
  144. {
  145. wafers.Add(waferInfo);
  146. break;
  147. }
  148. }
  149. }
  150. }
  151. }
  152. }
  153. if (wafers.Count == 1)
  154. {
  155. WaferInfo waferInfo = wafers[0];
  156. ModuleName pufModuleName = ModuleName.PUF1;
  157. string waferSide = "";
  158. string dummySide = "";
  159. bool lastSingleWaferToSideB = processJobInfos[0].SequenceRecipe.LastSingleWaferToSideB;
  160. if (lastSingleWaferToSideB)
  161. {
  162. waferSide = SIDE_B;
  163. dummySide = SIDE_A;
  164. }
  165. else
  166. {
  167. waferSide = SIDE_A;
  168. dummySide = SIDE_B;
  169. }
  170. if (CheckWaferHolderHasSameTypeWafers(waferHolderInfo))
  171. {
  172. List<WaferInfo> dummyWafers = DummyWaferManager.Instance.LoadDummyWafersByWaferHolder(waferHolderInfo);
  173. if (dummyWafers.Count != 0)
  174. {
  175. CreateWaferTaskSchedulerSequence(waferInfo, pufModuleName, waferHolderInfo, waferInfo.ProcessJob.SequenceRecipe, "",waferSide);
  176. WaferInfo dummyInfo = null;
  177. if (dummyWafers.Count > 1)
  178. {
  179. foreach (WaferInfo info in dummyWafers)
  180. {
  181. //最后一片Wafer使用B面,那么dummy片使用0 slot
  182. if (lastSingleWaferToSideB && info.OriginSlot == 0)
  183. {
  184. dummyInfo = info;
  185. break;
  186. }
  187. //最后一片Wafer使用A面,那么dummy片使用1 slot
  188. if (!lastSingleWaferToSideB && info.OriginSlot == 1)
  189. {
  190. dummyInfo = info;
  191. break;
  192. }
  193. }
  194. if (dummyInfo == null)
  195. {
  196. dummyInfo = dummyWafers[0];
  197. }
  198. }
  199. else
  200. {
  201. dummyInfo = dummyWafers[0];
  202. }
  203. CreateDummyWaferTaskSchedulerSequence(waferHolderInfo.SequenceRecipe, dummyInfo, pufModuleName, waferInfo.WaferID,dummySide);
  204. _waferTaskMatchDic[waferInfo.WaferID] = dummyWafers[0].WaferID;
  205. _waferTaskMatchDic[dummyWafers[0].WaferID] = waferInfo.WaferID;
  206. _waferWaferHolderTaskDic[waferInfo.WaferID] = waferHolderTask;
  207. _waferWaferHolderTaskDic[dummyWafers[0].WaferID] = waferHolderTask;
  208. return 2;
  209. }
  210. else
  211. {
  212. CreateWaferTaskSchedulerSequence(waferInfo, pufModuleName, waferHolderInfo, waferInfo.ProcessJob.SequenceRecipe, "",waferSide);
  213. _waferWaferHolderTaskDic[waferInfo.WaferID] = waferHolderTask;
  214. return 1;
  215. }
  216. }
  217. else
  218. {
  219. CreateWaferTaskSchedulerSequence(waferInfo, pufModuleName, waferHolderInfo, waferInfo.ProcessJob.SequenceRecipe, "",waferSide);
  220. _waferWaferHolderTaskDic[waferInfo.WaferID] = waferHolderTask;
  221. return 1;
  222. }
  223. }
  224. else if (wafers.Count >= 2)
  225. {
  226. for (int i = 0; i < 2; i++)
  227. {
  228. WaferInfo waferInfo = wafers[i];
  229. ModuleName pufModuleName = ModuleName.PUF1;
  230. if (i == 0)
  231. {
  232. mateWaferTask = wafers[0].WaferID;
  233. CreateWaferTaskSchedulerSequence(waferInfo, pufModuleName, waferHolderInfo, waferInfo.ProcessJob.SequenceRecipe, "",SIDE_A);
  234. }
  235. else
  236. {
  237. CreateWaferTaskSchedulerSequence(waferInfo, pufModuleName, waferHolderInfo, waferInfo.ProcessJob.SequenceRecipe, mateWaferTask,SIDE_B);
  238. }
  239. }
  240. _waferTaskMatchDic[wafers[0].WaferID] = wafers[1].WaferID;
  241. _waferTaskMatchDic[wafers[1].WaferID] = wafers[0].WaferID;
  242. _waferWaferHolderTaskDic[wafers[0].WaferID] = waferHolderTask;
  243. _waferWaferHolderTaskDic[wafers[1].WaferID] = waferHolderTask;
  244. return 2;
  245. }
  246. return 0;
  247. }
  248. /// <summary>
  249. /// 检验WaferHolder是否存在两片生产片
  250. /// </summary>
  251. /// <param name="waferHolderInfo"></param>
  252. /// <returns></returns>
  253. private bool CheckWaferHolderHasSameTypeWafers(WaferHolderInfo waferHolderInfo)
  254. {
  255. int count = 0;
  256. WaferInfo waferAInfo = WaferManager.Instance.GetWaferByWaferId(waferHolderInfo.WaferAId);
  257. WaferType waferType = WaferType.Production;
  258. if (waferAInfo != null)
  259. {
  260. waferType = waferAInfo.WaferType;
  261. count++;
  262. }
  263. WaferInfo waferBInfo = WaferManager.Instance.GetWaferByWaferId(waferHolderInfo.WaferBId);
  264. if (waferBInfo != null)
  265. {
  266. if (waferBInfo.WaferType == waferType)
  267. {
  268. count++;
  269. }
  270. }
  271. return count >= 2;
  272. }
  273. /// <summary>
  274. /// 检验WaferHolder是否存在两片生产片
  275. /// </summary>
  276. /// <param name="waferHolderInfo"></param>
  277. /// <returns></returns>
  278. private bool CheckWaferHolderHasTwoProductionWafers(WaferHolderInfo waferHolderInfo)
  279. {
  280. int count = 0;
  281. WaferInfo waferAInfo = WaferManager.Instance.GetWaferByWaferId(waferHolderInfo.WaferAId);
  282. if (waferAInfo != null && waferAInfo.WaferType==WaferType.Production)
  283. {
  284. count++;
  285. }
  286. WaferInfo waferBInfo = WaferManager.Instance.GetWaferByWaferId(waferHolderInfo.WaferBId);
  287. if (waferBInfo != null && waferBInfo.WaferType == WaferType.Production)
  288. {
  289. count++;
  290. }
  291. return count >= 2;
  292. }
  293. /// <summary>
  294. /// 创建WaferTask SchedulerSequence
  295. /// </summary>
  296. /// <param name="waferInfo"></param>
  297. /// <param name="pufModuleName"></param>
  298. /// <param name="waferHolderInfo"></param>
  299. /// <param name="sequenceRecipe"></param>
  300. private void CreateWaferTaskSchedulerSequence(WaferInfo waferInfo, ModuleName pufModuleName, WaferHolderInfo waferHolderInfo, SequenceRecipe sequenceRecipe, string mateWafeTask,string side)
  301. {
  302. List<SchedulerSequence> sequences = SchedulerSequenceManager.Instance.AnalyWaferAllSchedulerSequence(waferInfo, pufModuleName,side, waferHolderInfo, sequenceRecipe);
  303. PUFEntity pufEntity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(pufModuleName.ToString());
  304. WaferTask waferTask = new WaferTask(waferInfo, pufEntity, sequences);
  305. if (!string.IsNullOrEmpty(mateWafeTask))
  306. {
  307. waferTask.MateWaferTask = mateWafeTask;
  308. }
  309. waferTask.OnTaskComplete += WaferTask_OnTaskComplete;
  310. LOG.WriteLog(eEvent.EV_SEQUENCE, "Scheduler", $"Create wafer {waferInfo.WaferID} task");
  311. InitializeTask(waferTask);
  312. }
  313. /// <summary>
  314. /// 创建DummyWaferTask
  315. /// </summary>
  316. /// <param name="waferInfos"></param>
  317. public int CreateDummyWaferTask(List<WaferInfo> waferInfos,SequenceRecipe sequenceRecipe,WaferHolderTask waferHolderTask)
  318. {
  319. string mateWaferTask = "";
  320. int waferCount = 0;
  321. for (int i = 0; i < waferInfos.Count; i++)
  322. {
  323. WaferInfo waferInfo = waferInfos[i];
  324. int orginalSlot = waferInfo.OriginSlot;
  325. ModuleName pufModuleName = ModuleName.PUF1;
  326. string side = orginalSlot == 0 ? SIDE_A : SIDE_B;
  327. waferCount = i;
  328. if (!Contains(waferInfo.WaferID))
  329. {
  330. if (i == 0)
  331. {
  332. mateWaferTask = waferInfo.WaferID;
  333. CreateDummyWaferTaskSchedulerSequence(sequenceRecipe,waferInfo, pufModuleName,"", side);
  334. _waferWaferHolderTaskDic[waferInfo.WaferID] = waferHolderTask;
  335. }
  336. else
  337. {
  338. CreateDummyWaferTaskSchedulerSequence(sequenceRecipe,waferInfo, pufModuleName, mateWaferTask,side);
  339. _waferTaskMatchDic[mateWaferTask] = waferInfo.WaferID;
  340. _waferTaskMatchDic[waferInfo.WaferID] = mateWaferTask;
  341. _waferWaferHolderTaskDic[waferInfo.WaferID]= waferHolderTask;
  342. break;
  343. }
  344. }
  345. }
  346. return waferCount + 1;
  347. }
  348. /// <summary>
  349. /// 创建Dummy Wafer Task 调度工序
  350. /// </summary>
  351. /// <param name="waferInfo"></param>
  352. /// <param name="pufModuleName"></param>
  353. /// <param name="mateWaferTask"></param>
  354. private void CreateDummyWaferTaskSchedulerSequence(SequenceRecipe sequenceRecipe,WaferInfo waferInfo,ModuleName pufModuleName,string mateWaferTask,string side)
  355. {
  356. List<SchedulerSequence> sequences = SchedulerSequenceManager.Instance.AnalyDummyWaferAllSchedulerSequence(sequenceRecipe,waferInfo,pufModuleName, side);
  357. PUFEntity pufEntity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(pufModuleName.ToString());
  358. WaferTask waferTask = new WaferTask(waferInfo, pufEntity,sequences);
  359. if (!string.IsNullOrEmpty(mateWaferTask))
  360. {
  361. waferTask.MateWaferTask = mateWaferTask;
  362. }
  363. LOG.WriteLog(eEvent.EV_SEQUENCE, "Scheduler", $"Create Dummy wafer {waferInfo.WaferID} task");
  364. waferTask.OnTaskStart += WaferTask_OnTaskStart;
  365. waferTask.OnTaskComplete += WaferTask_OnTaskComplete;
  366. InitializeTask(waferTask);
  367. }
  368. /// <summary>
  369. /// 任务开始
  370. /// </summary>
  371. /// <param name="id"></param>
  372. /// <exception cref="NotImplementedException"></exception>
  373. private void WaferTask_OnTaskStart(string id)
  374. {
  375. WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(id);
  376. if (waferInfo != null && waferInfo.WaferType == WaferType.Production)
  377. {
  378. ModuleName moduleName = (ModuleName)waferInfo.OriginStation;
  379. if (ModuleHelper.IsLoadPort(moduleName))
  380. {
  381. CycleManager.Instance.UpdateCycleWaferCount(moduleName.ToString());
  382. }
  383. _schedulerFACallback.JobWaferStart(JobProcesser.Instance.GetControlJobInfoByProcessJob(waferInfo.ProcessJob),
  384. waferInfo.SequenceName, waferInfo.OriginSlot);
  385. }
  386. }
  387. /// <summary>
  388. /// Wafer task完成事件
  389. /// </summary>
  390. /// <param name="id"></param>
  391. private void WaferTask_OnTaskComplete(string id)
  392. {
  393. WaferInfo waferInfo=WaferManager.Instance.GetWaferByWaferId(id);
  394. if (waferInfo != null&&waferInfo.WaferType==WaferType.Production)
  395. {
  396. ModuleName moduleName = (ModuleName)waferInfo.OriginStation;
  397. if (ModuleHelper.IsLoadPort(moduleName))
  398. {
  399. CycleManager.Instance.UpdateCycleWaferCount(moduleName.ToString());
  400. }
  401. _schedulerFACallback.JobWaferEnd(JobProcesser.Instance.GetControlJobInfoByProcessJob(waferInfo.ProcessJob),
  402. waferInfo.SequenceName, waferInfo.OriginSlot);
  403. }
  404. RemoveWaferTask(id);
  405. }
  406. /// <summary>
  407. /// 暂停
  408. /// </summary>
  409. public void PauseAllTask()
  410. {
  411. List<WaferTask> waferTasks = _waferTaskList.ToList();
  412. foreach(WaferTask item in waferTasks)
  413. {
  414. item.Pause();
  415. }
  416. }
  417. /// <summary>
  418. /// 恢复所有任务
  419. /// </summary>
  420. public void ResumeAllTask()
  421. {
  422. List<WaferTask> waferTasks = _waferTaskList.ToList();
  423. foreach (WaferTask item in waferTasks)
  424. {
  425. item.Resume();
  426. }
  427. }
  428. /// <summary>
  429. /// 恢复所有任务
  430. /// </summary>
  431. public void RemoveAllTask()
  432. {
  433. List<WaferTask> waferTasks = _waferTaskList.ToList();
  434. foreach (WaferTask item in waferTasks)
  435. {
  436. RemoveWaferTask(item.WaferId);
  437. }
  438. }
  439. /// <summary>
  440. /// 根据WaferId获取配对另一个WaferId
  441. /// </summary>
  442. /// <param name="waferId"></param>
  443. /// <returns></returns>
  444. public string GetMatchWaferIdByWaferId(string waferId)
  445. {
  446. return _waferTaskMatchDic.ContainsKey(waferId) ? _waferTaskMatchDic[waferId] : "";
  447. }
  448. /// <summary>
  449. /// 移除WaferId匹配WaferHolderTask字典
  450. /// </summary>
  451. /// <param name="waferId"></param>
  452. public void RemoveWaferIdMatchWaferHolderTaskDic(string waferId)
  453. {
  454. if(_waferWaferHolderTaskDic.ContainsKey(waferId))
  455. {
  456. _waferWaferHolderTaskDic.TryRemove(waferId, out var waferHolderTask);
  457. }
  458. }
  459. /// <summary>
  460. /// 获取WaferId匹配WaferHolderTask字典
  461. /// </summary>
  462. /// <param name="waferId"></param>
  463. /// <returns></returns>
  464. public WaferHolderTask GetWaferHolderTaskByWaferId(string waferId)
  465. {
  466. return _waferWaferHolderTaskDic.ContainsKey(waferId) ? _waferWaferHolderTaskDic[waferId] : null;
  467. }
  468. /// <summary>
  469. /// 获取WaferHolder Task对应的Wafer Task WaferId集合
  470. /// </summary>
  471. /// <param name="waferHolderId"></param>
  472. /// <returns></returns>
  473. public List<string> GetWaferHolderMathWaferId(string waferHolderId)
  474. {
  475. List<string> keys = _waferWaferHolderTaskDic.Keys.ToList();
  476. List<string> result = new List<string>();
  477. foreach(string item in keys)
  478. {
  479. if(_waferWaferHolderTaskDic[item].WaferHolderInfo.Id==waferHolderId)
  480. {
  481. result.Add(item);
  482. }
  483. }
  484. return result;
  485. }
  486. /// <summary>
  487. /// 检验Wafer存在匹配的wafer任务(wafer是单片任务还是双片任务)
  488. /// </summary>
  489. /// <param name="waferId"></param>
  490. /// <returns></returns>
  491. public string CheckWaferHasMatch(string waferId)
  492. {
  493. if (_waferTaskMatchDic.ContainsKey(waferId))
  494. {
  495. return _waferTaskMatchDic[waferId];
  496. }
  497. else
  498. {
  499. return "";
  500. }
  501. }
  502. }
  503. }