Semiconductor Wafer Test Data with TofuPilot
Semiconductor testing happens in two stages: wafer-level testing (CP, circuit probe) and final test (FT, packaged parts). Each stage generates massive datasets. TofuPilot stores per-die and per-part test results with full measurement data, enabling yield analysis, bin mapping, and lot traceability.
Semiconductor Test Flow
Wafer Fab → Wafer Test (CP) → Packaging → Final Test (FT) → Binning → Ship
↓ ↓
TofuPilot TofuPilot
(per-die data) (per-part data)
Wafer Test (Circuit Probe)
Probes contact each die on the wafer. Tests include:
| Test | What it checks |
|---|---|
| Continuity/opens | Bond pad connectivity |
| Leakage | Junction and oxide integrity |
| Parametric | Vth, Idsat, Rds(on), timing |
| Functional | Basic digital/analog operation |
Final Test (FT)
After packaging, full parametric and functional testing at speed.
| Test | What it checks |
|---|---|
| DC parametric | Input/output levels, power consumption |
| AC parametric | Speed, setup/hold times, rise/fall times |
| Functional | Full device operation at target frequency |
| Burn-in (optional) | Infant mortality screening |
Logging Wafer Test Data
Per-Die Results
from tofupilot import TofuPilotClient
client = TofuPilotClient()
def log_die_test(wafer_id, die_x, die_y, measurements, bin_code):
"""Log test results for a single die."""
die_id = f"{wafer_id}-X{die_x}Y{die_y}"
steps = [{
"name": "Parametric",
"step_type": "measurement",
"status": bin_code == 1, # Bin 1 = good die
"measurements": [
{"name": "vth_mv", "value": measurements["vth"], "unit": "mV", "limit_low": 350, "limit_high": 450},
{"name": "idsat_ua_um", "value": measurements["idsat"], "unit": "uA/um", "limit_low": 500, "limit_high": 700},
{"name": "ioff_pa_um", "value": measurements["ioff"], "unit": "pA/um", "limit_high": 100},
{"name": "rdson_mohm", "value": measurements["rdson"], "unit": "mohm", "limit_high": 50},
],
}]
client.create_run(
procedure_id="WAFER-CP-TEST",
unit_under_test={
"serial_number": die_id,
"part_number": "IC-POWER-MGMT-V3",
},
run_passed=bin_code == 1,
steps=steps,
)
# Test all dies on a wafer
wafer_id = "LOT2025A-W07"
for x in range(20):
for y in range(20):
meas = probe_die(x, y)
bin_code = classify_die(meas)
log_die_test(wafer_id, x, y, meas, bin_code)Wafer-Level Summary
After testing all dies, upload a wafer summary.
# Wafer-level summary
total_dies = 400
good_dies = 352
yield_pct = good_dies / total_dies * 100
client.create_run(
procedure_id="WAFER-CP-SUMMARY",
unit_under_test={
"serial_number": "LOT2025A-W07",
"part_number": "IC-POWER-MGMT-V3",
},
run_passed=yield_pct > 80,
steps=[{
"name": "Wafer Summary",
"step_type": "measurement",
"status": yield_pct > 80,
"measurements": [
{"name": "total_dies", "value": total_dies, "unit": "count"},
{"name": "good_dies", "value": good_dies, "unit": "count"},
{"name": "cp_yield_pct", "value": yield_pct, "unit": "%", "limit_low": 80},
{"name": "bin1_count", "value": 352, "unit": "count"},
{"name": "bin2_count", "value": 30, "unit": "count"},
{"name": "bin3_count", "value": 18, "unit": "count"},
],
}],
)Bin Mapping
Binning assigns each die or part to a category based on test results. Common bin structure:
| Bin | Meaning | Typical criteria |
|---|---|---|
| 1 | Good, full spec | All parametrics within spec |
| 2 | Good, derated | Parametrics within wider limits |
| 3 | Functional fail | Failed functional test |
| 4 | Parametric fail | One or more parametric out of spec |
| 5 | Continuity fail | Open or short detected |
| 6 | Leakage fail | Excessive junction leakage |
Track bin distributions in TofuPilot across wafers, lots, and time periods.
Yield Analysis
Wafer-to-Wafer Yield
Compare CP yield across wafers in a lot.
| Wafer | Total dies | Good (Bin 1) | Yield |
|---|---|---|---|
| W01 | 400 | 360 | 90.0% |
| W02 | 400 | 355 | 88.8% |
| W03 | 400 | 312 | 78.0% |
| W04 | 400 | 358 | 89.5% |
W03 has significantly lower yield. Investigate wafer-level process issues (particle count, lithography focus, etch uniformity).
Lot-to-Lot Yield
Track yield across production lots to monitor fab process stability.
from tofupilot import TofuPilotClient
client = TofuPilotClient()
# Get all wafer summary runs
runs = client.get_runs(
procedure_id="WAFER-CP-SUMMARY",
limit=100,
)
# Group by lot and calculate average yield
lot_yields = {}
for run in runs:
serial = run["unit_under_test"]["serial_number"]
lot = serial.split("-W")[0] # Extract lot ID
for step in run.get("steps", []):
for m in step.get("measurements", []):
if m["name"] == "cp_yield_pct":
if lot not in lot_yields:
lot_yields[lot] = []
lot_yields[lot].append(m["value"])
for lot, yields in sorted(lot_yields.items()):
avg = sum(yields) / len(yields)
print(f"{lot}: {avg:.1f}% avg yield ({len(yields)} wafers)")CP to FT Yield Correlation
Track yield at both test stages to find packaging-related issues.
| Lot | CP Yield | FT Yield | FT/CP Loss |
|---|---|---|---|
| LOT2025A | 89.2% | 87.1% | 2.1% |
| LOT2025B | 91.0% | 88.5% | 2.5% |
| LOT2025C | 90.5% | 82.3% | 8.2% |
LOT2025C shows excessive CP-to-FT yield loss (8.2% vs. typical 2-3%). This points to a packaging issue: wire bond failures, die attach problems, or moisture sensitivity during assembly.
Parametric Distribution Monitoring
Track critical parametric distributions across production to catch process drift.
Key parameters to monitor:
| Parameter | Why it matters |
|---|---|
| Vth (threshold voltage) | Shifts indicate gate oxide or implant dose issues |
| Idsat (saturation current) | Indicates transistor drive strength |
| Ioff (off-state leakage) | Affects standby power, process control indicator |
| Rdson (on-resistance) | Critical for power devices |
| Timing margins | Speed grading, binning into speed grades |
TofuPilot's measurement histograms show the distribution of each parameter across all tested dies. A bimodal distribution suggests two different process conditions. A shifting mean suggests process drift.
Traceability from Part to Wafer
When a packaged part fails in the field, trace back:
- Part serial number → packaging lot
- Packaging lot → wafer ID
- Wafer ID → die position (X, Y)
- Die position → original CP test data
All of this data lives in TofuPilot, linked by serial numbers. Was the die marginal at wafer test? Was it a Bin 2 (derated) part sold as Bin 1? The data answers these questions.