Manufacturing Workflow
Your PCB design is only data until a fabricator turns it into copper and fiberglass. The quality of your manufacturing output files directly determines whether you get back exactly what you designed — or a board full of errors.
A Brief History of PCB Manufacturing Files
flowchart LR
A["PCB Design
(EDA tool)"] --> B["Generate Gerbers
+ Drill Files"]
B --> C["Generate BOM
+ PnP Data"]
C --> D["Review &
Verify Files"]
D --> E["Upload to
Fabricator"]
E --> F["Bare PCB
Fabrication"]
F --> G["SMT Assembly
(if ordered)"]
G --> H["Boards
Delivered"]
Manufacturing File Formats
| File Type | Format | Purpose | Extension |
|---|---|---|---|
| Copper layers | Gerber RS-274X | PCB trace patterns | .gtl, .gbl, .gX |
| Solder mask | Gerber RS-274X | Mask openings | .gts, .gbs |
| Silkscreen | Gerber RS-274X | Component labels | .gto, .gbo |
| Board outline | Gerber RS-274X | Board shape | .gm1, .gko |
| Drill data | Excellon | Hole locations/sizes | .drl, .xln |
| BOM | CSV/Excel | Component list | .csv, .xlsx |
| Pick-and-Place | CSV | Component positions | .csv, .pos |
| Fab drawing | PDF/Gerber | Notes & dimensions |
Gerber Files
Layer Mapping
Gerber RS-274X is the industry standard for PCB fabrication data. Each physical layer of your PCB gets its own Gerber file. Here is the standard layer mapping for a 4-layer board:
| Layer | KiCad Name | Gerber Extension | Description |
|---|---|---|---|
| Top copper | F.Cu | .gtl / F_Cu.gbr | Signal + power traces |
| Inner 1 | In1.Cu | .g2 / In1_Cu.gbr | GND plane (typical) |
| Inner 2 | In2.Cu | .g3 / In2_Cu.gbr | Power plane (typical) |
| Bottom copper | B.Cu | .gbl / B_Cu.gbr | Signal + power traces |
| Top solder mask | F.Mask | .gts / F_Mask.gbr | Mask openings (inverted) |
| Bottom solder mask | B.Mask | .gbs / B_Mask.gbr | Mask openings (inverted) |
| Top silkscreen | F.SilkS | .gto / F_SilkS.gbr | Component designators |
| Bottom silkscreen | B.SilkS | .gbo / B_SilkS.gbr | Bottom-side labels |
| Top paste | F.Paste | .gtp / F_Paste.gbr | Stencil apertures |
| Board outline | Edge.Cuts | .gko / Edge_Cuts.gbr | Board shape |
KiCad Gerber Export
# KiCad CLI Gerber export (KiCad 8+)
# Generate all manufacturing files from the command line
# 1. Generate Gerbers
kicad-cli pcb export gerbers \
--output ./gerbers/ \
--layers "F.Cu,In1.Cu,In2.Cu,B.Cu,F.Mask,B.Mask,F.SilkS,B.SilkS,F.Paste,B.Paste,Edge.Cuts" \
--subtract-soldermask \
--use-drill-file-origin \
my_project.kicad_pcb
# 2. Generate drill files (Excellon)
kicad-cli pcb export drill \
--output ./gerbers/ \
--format excellon \
--drill-origin plot \
--excellon-units mm \
--generate-map \
my_project.kicad_pcb
# 3. Generate pick-and-place CSV
kicad-cli pcb export pos \
--output ./assembly/placement.csv \
--format csv \
--units mm \
--side both \
my_project.kicad_pcb
# 4. Generate BOM
kicad-cli sch export bom \
--output ./assembly/bom.csv \
my_project.kicad_sch
echo "Manufacturing files generated in ./gerbers/ and ./assembly/"
Gerber Verification
# Gerber file package verifier
# Checks that all required files exist before upload
import os
required_files = {
"Top Copper": ["F_Cu.gbr", ".gtl"],
"Bottom Copper": ["B_Cu.gbr", ".gbl"],
"Top Solder Mask": ["F_Mask.gbr", ".gts"],
"Bottom Solder Mask": ["B_Mask.gbr", ".gbs"],
"Top Silkscreen": ["F_SilkS.gbr", ".gto"],
"Board Outline": ["Edge_Cuts.gbr", ".gko", ".gm1"],
"Drill File": [".drl", ".xln"],
}
gerber_dir = "./gerbers" # Change to your output directory
print("Gerber Package Verification")
print("=" * 50)
all_files = os.listdir(gerber_dir) if os.path.isdir(gerber_dir) else []
missing = []
for layer, patterns in required_files.items():
found = any(
any(f.endswith(ext) or ext.lstrip('.') in f for f in all_files)
for ext in patterns
)
status = "✓ Found" if found else "✗ MISSING"
if not found:
missing.append(layer)
print(f" {layer:>22}: {status}")
print(f"\nTotal files in directory: {len(all_files)}")
if missing:
print(f"⚠ MISSING LAYERS: {', '.join(missing)}")
print("DO NOT upload until all layers are present!")
else:
print("✓ All required layers present — ready to upload")
Gerber Package Verification
==================================================
Top Copper: ✓ Found
Bottom Copper: ✓ Found
Top Solder Mask: ✓ Found
Bottom Solder Mask: ✓ Found
Top Silkscreen: ✓ Found
Board Outline: ✓ Found
Drill File: ✓ Found
Total files in directory: 11
✓ All required layers present — ready to upload
Drill & Route Files
Excellon Drill Format
Excellon is the standard drill data format. It specifies tool definitions (drill sizes) and hole coordinates. Modern tools use Excellon format 2.4 (2 integer digits, 4 decimal digits, millimeters).
# Example Excellon drill file structure
# M48 = header start
# T1C0.300 = Tool 1, 0.300mm diameter
# % = end of header
# T1 = select tool 1
# X25400Y50800 = drill at (25.4mm, 50.8mm)
# Common drill sizes for embedded PCBs:
# 0.3mm - Standard vias
# 0.4mm - Power vias
# 0.8mm - Through-hole header pins (0.1" pitch)
# 1.0mm - Mounting holes (M2)
# 1.1mm - Through-hole components
# 3.2mm - Mounting holes (M3)
Drill Verification
# Drill file analyzer — count holes by size
drill_tools = {
"T1": {"size_mm": 0.30, "count": 245, "type": "Via"},
"T2": {"size_mm": 0.40, "count": 48, "type": "Power Via"},
"T3": {"size_mm": 0.80, "count": 80, "type": "Header Pin"},
"T4": {"size_mm": 1.00, "count": 4, "type": "M2 Mount"},
"T5": {"size_mm": 1.10, "count": 12, "type": "Through-Hole"},
"T6": {"size_mm": 3.20, "count": 4, "type": "M3 Mount"},
}
print("Drill File Analysis")
print("=" * 60)
print(f"{'Tool':>6} | {'Size (mm)':>9} | {'Count':>6} | {'Type':>15}")
print("-" * 60)
total_holes = 0
for tool, info in drill_tools.items():
total_holes += info["count"]
print(f"{tool:>6} | {info['size_mm']:>7.2f}mm | {info['count']:>6} | {info['type']:>15}")
print(f"\nTotal drill hits: {total_holes}")
print(f"Unique tool sizes: {len(drill_tools)}")
print(f"\nTip: Fewer unique drill sizes = faster fabrication")
print(f"Tip: Minimum via size for standard fab: 0.3mm (12 mil)")
Drill File Analysis
============================================================
Tool | Size (mm) | Count | Type
------------------------------------------------------------
T1 | 0.30mm | 245 | Via
T2 | 0.40mm | 48 | Power Via
T3 | 0.80mm | 80 | Header Pin
T4 | 1.00mm | 4 | M2 Mount
T5 | 1.10mm | 12 | Through-Hole
T6 | 3.20mm | 4 | M3 Mount
Total drill hits: 393
Unique tool sizes: 6
Tip: Fewer unique drill sizes = faster fabrication
Tip: Minimum via size for standard fab: 0.3mm (12 mil)
Bill of Materials (BOM)
Production BOM Format
A production BOM includes everything the assembler needs: component value, package, manufacturer part number (MPN), supplier, and quantity.
| Column | Required | Description | Example |
|---|---|---|---|
| Reference | Yes | Component designators | R1, R2, R5 |
| Value | Yes | Component value | 10kΩ |
| Package | Yes | Footprint/package | 0402 |
| Quantity | Yes | Number of placements | 3 |
| MPN | Yes | Manufacturer part # | RC0402FR-0710KL |
| Manufacturer | Recommended | Component maker | Yageo |
| Supplier | Optional | Distributor | LCSC, DigiKey |
| Supplier PN | Optional | Supplier part # | C60490 |
| DNP | If applicable | Do Not Populate flag | DNP |
BOM Cost Estimator
# BOM cost estimator for prototype and production quantities
bom = [
{"ref": "U1", "value": "STM32F411CEU6", "pkg": "UFQFPN-48", "qty": 1, "unit_1": 3.50, "unit_1k": 2.80},
{"ref": "U2", "value": "AMS1117-3.3", "pkg": "SOT-223", "qty": 1, "unit_1": 0.15, "unit_1k": 0.08},
{"ref": "Y1", "value": "8MHz Crystal", "pkg": "3215", "qty": 1, "unit_1": 0.30, "unit_1k": 0.15},
{"ref": "R1-R10", "value": "10kΩ 0402", "pkg": "0402", "qty": 10,"unit_1": 0.01, "unit_1k": 0.003},
{"ref": "C1-C15", "value": "100nF 0402", "pkg": "0402", "qty": 15,"unit_1": 0.02, "unit_1k": 0.005},
{"ref": "C16-C18", "value": "10µF 0805", "pkg": "0805", "qty": 3, "unit_1": 0.05, "unit_1k": 0.02},
{"ref": "L1", "value": "Ferrite 0805", "pkg": "0805", "qty": 1, "unit_1": 0.08, "unit_1k": 0.03},
{"ref": "J1", "value": "USB-C Connector", "pkg": "USB-C", "qty": 1, "unit_1": 0.50, "unit_1k": 0.30},
{"ref": "J2", "value": "SWD 1.27mm 2x5", "pkg": "2x5 1.27", "qty": 1, "unit_1": 0.40, "unit_1k": 0.20},
]
print("BOM Cost Analysis")
print("=" * 80)
print(f"{'Reference':>10} | {'Value':>18} | {'Qty':>4} | {'Proto @1':>9} | {'Prod @1k':>9}")
print("-" * 80)
total_proto = 0
total_prod = 0
total_parts = 0
for item in bom:
proto_cost = item["qty"] * item["unit_1"]
prod_cost = item["qty"] * item["unit_1k"]
total_proto += proto_cost
total_prod += prod_cost
total_parts += item["qty"]
print(f"{item['ref']:>10} | {item['value']:>18} | {item['qty']:>4} | ${proto_cost:>7.2f} | ${prod_cost:>7.2f}")
print("-" * 80)
print(f"{'TOTAL':>10} | {'':>18} | {total_parts:>4} | ${total_proto:>7.2f} | ${total_prod:>7.2f}")
print(f"\nPCB fabrication (5 pcs, JLCPCB): ~$5.00")
print(f"Assembly (5 pcs, JLCPCB): ~$15.00")
print(f"Total prototype cost (5 boards): ~${5*total_proto + 5.00 + 15.00:.2f}")
BOM Cost Analysis
================================================================================
Reference | Value | Qty | Proto @1 | Prod @1k
--------------------------------------------------------------------------------
U1 | STM32F411CEU6 | 1 | $3.50 | $2.80
U2 | AMS1117-3.3 | 1 | $0.15 | $0.08
Y1 | 8MHz Crystal | 1 | $0.30 | $0.15
R1-R10 | 10kΩ 0402 | 10 | $0.10 | $0.03
C1-C15 | 100nF 0402 | 15 | $0.30 | $0.08
C16-C18 | 10µF 0805 | 3 | $0.15 | $0.06
L1 | Ferrite 0805 | 1 | $0.08 | $0.03
J1 | USB-C Connector | 1 | $0.50 | $0.30
J2 | SWD 1.27mm 2x5 | 1 | $0.40 | $0.20
--------------------------------------------------------------------------------
TOTAL | | 34 | $5.48 | $3.73
PCB fabrication (5 pcs, JLCPCB): ~$5.00
Assembly (5 pcs, JLCPCB): ~$15.00
Total prototype cost (5 boards): ~$47.40
The $500M Gerber Mistake — Therac-25 Manufacturing Chain (1985–1987)
The Therac-25 radiation therapy machine killed six patients between 1985 and 1987 due to software bugs that allowed the electron beam to fire at full intensity (25 MeV) without the beam spreader in place. While the root cause was software, the investigation revealed a systemic manufacturing documentation failure that prevented detection.
The documentation gap: The Therac-25 was a redesign of the Therac-20, which had hardware safety interlocks. When the Therac-25 removed hardware interlocks in favour of software-only safety, the manufacturing documentation — test procedures, acceptance criteria, and assembly drawings — were copied from the Therac-20 without updating the test requirements. The hardware interlock tests were simply deleted from the test plan rather than replaced with software verification tests.
Manufacturing lesson: Your manufacturing package isn’t just Gerbers and BOMs — it includes test procedures and acceptance criteria. When you remove a hardware safety feature and replace it with software, the manufacturing test plan MUST be updated to verify the software alternative. Every design change requires a corresponding documentation change.
BOM Cost Analysis
================================================================================
Reference | Value | Qty | Proto @1 | Prod @1k
--------------------------------------------------------------------------------
U1 | STM32F411CEU6 | 1 | $3.50 | $2.80
U2 | AMS1117-3.3 | 1 | $0.15 | $0.08
Y1 | 8MHz Crystal | 1 | $0.30 | $0.15
R1-R10 | 10kΩ 0402 | 10 | $0.10 | $0.03
C1-C15 | 100nF 0402 | 15 | $0.30 | $0.08
C16-C18 | 10µF 0805 | 3 | $0.15 | $0.06
L1 | Ferrite 0805 | 1 | $0.08 | $0.03
J1 | USB-C Connector | 1 | $0.50 | $0.30
J2 | SWD 1.27mm 2x5 | 1 | $0.40 | $0.20
--------------------------------------------------------------------------------
TOTAL | | 34 | $5.48 | $3.73
PCB fabrication (5 pcs, JLCPCB): ~$5.00
Assembly (5 pcs, JLCPCB): ~$15.00
Total prototype cost (5 boards): ~$47.40
The $500M Gerber Mistake — Therac-25 Manufacturing Chain (1985–1987)
The Therac-25 radiation therapy machine killed six patients between 1985 and 1987 due to software bugs that allowed the electron beam to fire at full intensity (25 MeV) without the beam spreader in place. While the root cause was software, the investigation revealed a systemic manufacturing documentation failure that prevented detection.
The documentation gap: The Therac-25 was a redesign of the Therac-20, which had hardware safety interlocks. When the Therac-25 removed hardware interlocks in favour of software-only safety, the manufacturing documentation — test procedures, acceptance criteria, and assembly drawings — were copied from the Therac-20 without updating the test requirements. The hardware interlock tests were simply deleted from the test plan rather than replaced with software verification tests.
Manufacturing lesson: Your manufacturing package isn’t just Gerbers and BOMs — it includes test procedures and acceptance criteria. When you remove a hardware safety feature and replace it with software, the manufacturing test plan MUST be updated to verify the software alternative. Every design change requires a corresponding documentation change.
Pick-and-Place Data
Pick-and-place (PnP/CPL) files tell the SMT machine exactly where to place each component. The file contains the reference designator, X/Y coordinates, rotation angle, and board side.
# Pick-and-place file format (JLCPCB compatible)
# Columns: Designator, Val, Package, Mid X, Mid Y, Rotation, Layer
pnp_data = [
("U1", "STM32F411CEU6", "UFQFPN-48", 25.40, 38.10, 0, "top"),
("U2", "AMS1117-3.3", "SOT-223", 12.70, 10.16, 90, "top"),
("Y1", "8MHz", "3215", 22.86, 35.56, 0, "top"),
("R1", "10k", "0402", 15.24, 30.48, 0, "top"),
("R2", "10k", "0402", 15.24, 28.44, 0, "top"),
("C1", "100nF", "0402", 27.94, 40.64, 90, "top"),
("C2", "100nF", "0402", 22.86, 40.64, 90, "top"),
("C16", "10uF", "0805", 10.16, 12.70, 0, "top"),
("J1", "USB-C", "USB-C", 5.08, 25.40, 270, "top"),
]
print("Designator,Val,Package,Mid X,Mid Y,Rotation,Layer")
for row in pnp_data:
print(f"{row[0]},{row[1]},{row[2]},{row[3]:.2f}mm,{row[4]:.2f}mm,{row[5]},{row[6]}")
print(f"\nTotal placements: {len(pnp_data)}")
print("Note: Verify rotation matches your EDA tool's convention")
print("JLCPCB uses 0° = component as shown in datasheet")
Designator,Val,Package,Mid X,Mid Y,Rotation,Layer U1,STM32F411CEU6,UFQFPN-48,25.40mm,38.10mm,0,top U2,AMS1117-3.3,SOT-223,12.70mm,10.16mm,90,top Y1,8MHz,3215,22.86mm,35.56mm,0,top R1,10k,0402,15.24mm,30.48mm,0,top R2,10k,0402,15.24mm,28.44mm,0,top C1,100nF,0402,27.94mm,40.64mm,90,top C2,100nF,0402,22.86mm,40.64mm,90,top C16,10uF,0805,10.16mm,12.70mm,0,top J1,USB-C,USB-C,5.08mm,25.40mm,270,top Total placements: 9 Note: Verify rotation matches your EDA tool's convention JLCPCB uses 0° = component as shown in datasheet
SpaceX Falcon 1 — Precision Manufacturing from Gerber to Launch (2006–2008)
SpaceX’s first three Falcon 1 launches all failed between 2006 and 2008. While the failures were mechanical (fuel leak, stage separation timing, residual thrust), the avionics team had a parallel challenge: manufacturing flight-qualified electronics on a startup budget.
The manufacturing approach: SpaceX couldn’t afford traditional aerospace PCB fabrication ($500–$2,000 per board from mil-spec houses with 8-week lead times). Instead, they developed a rigorous Gerber verification workflow using commercial fabricators at 10× lower cost. Every board went through: (1) automated DRC at design, (2) Gerber review with a physical checklist, (3) X-ray inspection of assembled boards, (4) thermal cycling qualification, and (5) vibration testing.
Manufacturing lesson: SpaceX proved that commercial-grade PCBs with rigorous verification can meet flight standards. The key wasn’t the fabricator — it was the verification process. Their Gerber review checklist caught solder mask registration errors, drill offset issues, and impedance control violations that would have been catastrophic in flight. Today, SpaceX launches ~100 missions per year with commercial PCBs verified by thorough manufacturing file review.
Manufacturing Package Tool
Generate a manufacturing package checklist documenting all output files, specifications, and notes for your fabricator.
Manufacturing Package Generator
Create a complete manufacturing package document for your PCB order. Download as Word, Excel, or PDF.
Exercises
Exercise 1: Gerber Layer Audit
You receive a Gerber package from a colleague for a 4-layer board. The zip file contains these files: F_Cu.gbr, B_Cu.gbr, In1_Cu.gbr, F_Mask.gbr, B_Mask.gbr, F_SilkS.gbr, Edge_Cuts.gbr, and board.drl.
- What critical layer is missing? What problems will this cause during fabrication?
- The fabricator emails asking about the inner layer stackup. What file or documentation should you provide, and what information must it contain?
- You open the Gerbers in a viewer and notice the Edge_Cuts layer shows the board as 50×50mm, but the copper extends to 52×50mm on one side. What happened and how do you fix it?
Hint: Count the inner copper layers for a 4-layer board. The stackup document should specify: layer order, copper weights (1oz/2oz), dielectric thickness, and material (FR-4). The copper overshoot means a trace or pour extends beyond the board outline — check Edge.Cuts alignment in the EDA tool.
Exercise 2: BOM Optimization
Your BOM has 47 unique part numbers for a simple IoT sensor board. The assembler charges a $3 setup fee per unique part plus $0.01 per placement. Your board has 120 total placements.
- Calculate the current assembly cost per board (setup fees + placement fees)
- You notice you have three different 10kΩ resistors: 0402 (5 pcs), 0603 (3 pcs), and 0805 (2 pcs). What is the simplest optimization and how much does it save?
- Your BOM has both AMS1117-3.3 (SOT-223) and AP2112K-3.3 (SOT-23-5) as 3.3V LDOs. Both provide 3.3V@800mA. Should you consolidate? What factors determine the decision?
- After optimization, you reduce to 38 unique parts and 115 placements. What is the new cost and percentage savings?
Hint: Original: (47 × $3) + (120 × $0.01) = $142.20. Consolidating to one resistor package saves 2 unique parts ($6). For LDOs, consider: dropout voltage, noise, PSRR, thermal pad, and whether both footprints are already validated.
Exercise 3: Pick-and-Place Rotation Debugging
You ordered 5 prototype boards with JLCPCB assembly. When the boards arrive, you notice: (1) the STM32 MCU pin 1 dot is rotated 90° clockwise from where it should be, (2) the USB-C connector is correctly oriented, (3) all 0402 passives appear correct.
- Explain why the MCU is wrong but passives are correct (think about symmetry)
- You check the PnP file and see
U1,STM32F411,UFQFPN-48,25.40,38.10,0,top. The component should be at 270° in JLCPCB’s convention. What rotation correction offset do you need to add? - Write a strategy for creating a “rotation correction table” that maps your EDA tool’s rotation to the assembler’s convention for each unique package type
- How would you verify the correction before ordering 1,000 boards?
Hint: 0402 passives are symmetric — 0° and 180° look identical, so rotation errors are invisible. QFP/QFN packages have a distinct pin 1 marker, making rotation errors obvious. Correction: 270° - 0° = 270° offset for UFQFPN-48 packages. Verify by ordering 2-5 boards with the corrected PnP file.
Conclusion & Next Steps
You now know how to generate, verify, and organize every manufacturing output file your fabricator needs. From Gerber layers to drill files, BOM to pick-and-place data — a well-prepared manufacturing package means fewer questions, faster turnaround, and boards that match your design.
Next in the Series
In Part 9: Board Bring-Up & Debugging, we’ll power on your freshly assembled boards, perform smoke tests, verify power rails, and debug firmware using oscilloscopes and logic analyzers.