docs: chapters 14–19 — GEM 300 standards (Part 2 complete)
Six more chapters finishing Part 2. Together with chapters 10–13 they document every SEMI standard this codebase implements. 14 — E40 + E94: process jobs (8-state lifecycle, S16F11/F5/F7/F9 on the wire) and control jobs (CJ wraps PJs with batch policy, S14F9/S16F27 messages). Worked cascade showing how CJSTART propagates through the PJ FSM and triggers S6F11 CEIDs at each transition. 15 — E87 carriers: three orthogonal sub-machines (CarrierID, SlotMap, CarrierAccess) per carrier and three more (Transfer, Reservation, Association) per load port. S3F17 CarrierAction strings + CAACK codes, S3F19 SlotMap verify, the 5-state slot encoding, multi-port concurrency. 16 — E90 + E157: substrate tracking via three orthogonal axes (STS / SPS / SubstrateIDStatus) and module process tracking (NotExecuting / GeneralExecuting / StepExecuting / StepCompleted). End-to-end PVD example showing E40 + E157 + E90 transitions cascading into CEIDs. 17 — E116 + E120 + E39: equipment performance time-buckets across six states, common equipment model object hierarchy, S14F1/F3 GetAttr/SetAttr as the uniform wire access for any object type across multiple standards. 18 — E84 parallel I/O: ten signal lines, the 9-state handshake FSM, the three TA1/TA2/TA3 timing-critical timers, why a physical handshake gets modeled in software (testability, timer enforcement, CEID emission, multi-port concurrency), the pure-FSM + asio-adapter split. 19 — E42 + E148 + S5F9–F18: formatted recipes (S7F23/F25 typed PPBODY), time synchronization with 16-char + 14-char accepted on set, exception recovery as a persistent multi-step host-supervised FSM (Posted → Recovering → Cleared with abort/retry). Revisits the auto-S9 family and contrasts S9 (transport) vs S5F9 (application). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
# 16 — E90 + E157: Substrate and module tracking
|
||||
|
||||
← [15 E87 — Carriers and load ports](15_e87_carriers.md) | [Back to index](00_index.md) | Next: [17 E116 + E120 + E39 — Performance, CEM, objects](17_e116_e120_e39_objects.md) →
|
||||
|
||||
E87 (chapter 15) tracks the **container**. E90 and E157 track
|
||||
what's *inside* the container — every individual wafer (substrate)
|
||||
and every process module the wafer passes through.
|
||||
|
||||
This chapter is shorter than the others in Part 2 because the
|
||||
ideas overlap E87 (the same three-orthogonal-axes pattern repeats)
|
||||
and E40 (state events drive S6F11 CEIDs).
|
||||
|
||||
---
|
||||
|
||||
## E90 — Substrate tracking
|
||||
|
||||
### What it tracks
|
||||
|
||||
One state-bearing record **per wafer**, identified by a substrate
|
||||
ID (an ASCII string, often the laser-etched serial number).
|
||||
|
||||
E90 has **three orthogonal axes** — the same pattern as E87's
|
||||
carrier (chapter 15 §3):
|
||||
|
||||
#### 1. Substrate State (STS) — location
|
||||
|
||||
```cpp
|
||||
// include/secsgem/gem/substrate_state.hpp:26
|
||||
enum class SubstrateState : uint8_t {
|
||||
AtSource = 0, // in its origin carrier slot
|
||||
AtWork = 1, // in-process at a module
|
||||
AtDestination = 2, // delivered to final location
|
||||
NoState = 255,
|
||||
};
|
||||
```
|
||||
|
||||
Events: `Acquire` (Source→Work), `Release` (Work→Destination),
|
||||
`Return` (Work→Source, for unprocessed return).
|
||||
|
||||
#### 2. Substrate Processing State (SPS) — lifecycle
|
||||
|
||||
```cpp
|
||||
enum class SubstrateProcessingState : uint8_t {
|
||||
NeedsProcessing = 0,
|
||||
InProcess = 1,
|
||||
Processed = 2,
|
||||
Aborted = 3,
|
||||
Stopped = 4,
|
||||
Rejected = 5,
|
||||
Lost = 6,
|
||||
Skipped = 7,
|
||||
NoState = 255,
|
||||
};
|
||||
```
|
||||
|
||||
Events: `StartProcessing`, `EndProcessing`, `Abort`, `Stop`,
|
||||
`Reject`, `ReportLost`, `Skip`.
|
||||
|
||||
#### 3. Substrate ID Status — identity confidence
|
||||
|
||||
```cpp
|
||||
enum class SubstrateIDStatus : uint8_t {
|
||||
NotConfirmed = 0,
|
||||
WaitingForHost = 1,
|
||||
Confirmed = 2,
|
||||
Mismatched = 3,
|
||||
NoState = 255,
|
||||
};
|
||||
```
|
||||
|
||||
Mirrors the `CarrierIDStatus` pattern from E87 — same problem
|
||||
(equipment reads ID, host may need to verify), same shape of
|
||||
solution.
|
||||
|
||||
### Why three axes?
|
||||
|
||||
The same reason E87 has three: these aspects evolve **at different
|
||||
times** and **for different reasons**.
|
||||
|
||||
- A wafer can be `AtWork` + `NeedsProcessing` (just arrived,
|
||||
recipe hasn't started).
|
||||
- A wafer can be `AtWork` + `InProcess` (recipe running).
|
||||
- A wafer can be `AtSource` + `Processed` + `Confirmed` (back in
|
||||
its carrier slot after processing — typical end state).
|
||||
|
||||
Putting all three in one enum would multiply to ~30 valid
|
||||
combinations. Three independent FSMs with ~3 events each is much
|
||||
cleaner.
|
||||
|
||||
### Code
|
||||
|
||||
State machines:
|
||||
[`include/secsgem/gem/substrate_state.hpp`](../include/secsgem/gem/substrate_state.hpp)
|
||||
defines `SubstrateStateMachine`, which composes the three.
|
||||
|
||||
Store:
|
||||
[`include/secsgem/gem/store/substrates.hpp`](../include/secsgem/gem/store/substrates.hpp)
|
||||
holds one record per substrate ID, with a Location string the
|
||||
application updates as the wafer moves.
|
||||
|
||||
Tests:
|
||||
[`tests/test_substrates.cpp`](../tests/test_substrates.cpp) (14
|
||||
cases — every axis, every event); persistence in
|
||||
[`tests/test_substrate_persistence.cpp`](../tests/test_substrate_persistence.cpp)
|
||||
(7 cases).
|
||||
|
||||
CEID-on-wire emission ("Substrate StartProcessing fires the
|
||||
configured SubstrateInProcess CEID") is verified by
|
||||
[`tests/test_wire_ceid_emission.cpp`](../tests/test_wire_ceid_emission.cpp).
|
||||
|
||||
### Wire interaction
|
||||
|
||||
E90 doesn't define its own S/F messages — substrate state changes
|
||||
fire as **CEIDs** that the host has subscribed to via the standard
|
||||
E30 §6.6 Dynamic Event Report Configuration (chapter 13). So:
|
||||
|
||||
- Equipment fires `Acquire` event on substrate `W-2026-06-09-A47`.
|
||||
- `SubstrateStateMachine` transitions Source → Work.
|
||||
- The state-change handler looks up the configured CEID for
|
||||
"SubstrateInProcess" (from `data/equipment.yaml`).
|
||||
- That CEID fires → `compose_reports_for(ceid)` → `S6F11`.
|
||||
|
||||
Host gets one S6F11 per wafer transition. In a 25-wafer FOUP
|
||||
that's 25–50 events per processing pass. Persistent reports +
|
||||
spool (chapter 13 Additionals) handle the burst.
|
||||
|
||||
---
|
||||
|
||||
## E157 — Module Process Tracking
|
||||
|
||||
### What it tracks
|
||||
|
||||
One state-bearing record **per process module**. A cluster tool
|
||||
has multiple modules (Chamber A, Chamber B, Pre-clean, …); each
|
||||
runs its own recipe step in parallel or sequence. E157 lets the
|
||||
host see *which module is in which step of which recipe right
|
||||
now*.
|
||||
|
||||
### The states
|
||||
|
||||
```cpp
|
||||
// include/secsgem/gem/module_state.hpp:20
|
||||
enum class ModuleState : uint8_t {
|
||||
NotExecuting = 0,
|
||||
GeneralExecuting = 1, // setup, pre-process, post-process
|
||||
StepExecuting = 2, // actively running a recipe step
|
||||
StepCompleted = 3,
|
||||
NoState = 255,
|
||||
};
|
||||
```
|
||||
|
||||
Events: `StartGeneral`, `StartStep`, `CompleteStep`, `Reset`,
|
||||
`Abort`.
|
||||
|
||||
Notice this is a much simpler FSM than E90 — one axis only. That's
|
||||
because modules are more deterministic than substrates: a module
|
||||
is either running a step or it isn't; substrates can be in many
|
||||
overlapping conditions.
|
||||
|
||||
### Code
|
||||
|
||||
[`include/secsgem/gem/module_state.hpp`](../include/secsgem/gem/module_state.hpp)
|
||||
defines `ModuleStateMachine`.
|
||||
|
||||
Store:
|
||||
[`include/secsgem/gem/store/modules.hpp`](../include/secsgem/gem/store/modules.hpp).
|
||||
|
||||
Tests:
|
||||
[`tests/test_modules.cpp`](../tests/test_modules.cpp) (5 cases).
|
||||
|
||||
### How E157 plays with E40 and E90
|
||||
|
||||
Concrete example. A PVD tool with three modules (Chamber A, B,
|
||||
C); host submits PJ for wafer W-1, recipe says "process at
|
||||
Chamber B for 90 seconds":
|
||||
|
||||
```
|
||||
1. PJ-1 transitions Queued → SettingUp → WaitingForStart → Processing.
|
||||
(E40 FSM, chapter 14)
|
||||
2. Equipment fires ModuleEvent::StartGeneral on Chamber B.
|
||||
ModuleState: NotExecuting → GeneralExecuting.
|
||||
(E157 FSM)
|
||||
3. Equipment fires SubstrateEvent::Acquire on W-1.
|
||||
Substrate STS: AtSource → AtWork.
|
||||
(E90 FSM)
|
||||
4. Recipe step begins. ModuleEvent::StartStep on Chamber B.
|
||||
ModuleState: GeneralExecuting → StepExecuting.
|
||||
Substrate SPS: NeedsProcessing → InProcess.
|
||||
5. ...90 seconds pass...
|
||||
6. Recipe step ends. ModuleEvent::CompleteStep on Chamber B.
|
||||
ModuleState: StepExecuting → StepCompleted.
|
||||
Substrate SPS: InProcess → Processed.
|
||||
7. Substrate released. SubstrateEvent::Release on W-1.
|
||||
Substrate STS: AtWork → AtDestination.
|
||||
8. PJ-1: ProcessComplete.
|
||||
```
|
||||
|
||||
Each of the eight transitions fires a CEID, which fires an S6F11
|
||||
event report. The host sees the **complete trace** of where every
|
||||
wafer was at every moment.
|
||||
|
||||
---
|
||||
|
||||
## Where to go next
|
||||
|
||||
You now know how every component of in-flight material is
|
||||
tracked. The next chapter covers the three smaller GEM 300
|
||||
standards that round out the suite: equipment performance time
|
||||
tracking, the common equipment model, and generic object
|
||||
services.
|
||||
|
||||
Next: [→ 17 E116 + E120 + E39 — Performance, CEM, objects](17_e116_e120_e39_objects.md)
|
||||
Reference in New Issue
Block a user