웨이퍼맵 2D 분석 - 심화 기술 분석 보고서
프로젝트 개요
wafermap-poc는 반도체 웨이퍼의 결함 정보를 시각화하는 React 기반 프로젝트입니다. KLARF(KLA Tencor's defect reporting file format) 포맷의 데이터를 입력받아 ECharts 기반의 인터랙티브한 2D 웨이퍼맵을 생성합니다.
기술 스택
- Frontend: React 16.9.0, TypeScript
- 차트 라이브러리: wafermap-core (ECharts 기반, Canvas 렌더링)
- 스타일링: Less CSS
- 상태 관리: React Hooks (useState, useRef, useEffect)
- 데이터 처리: KLARF 포맷 파싱 및 좌표 변환
핵심 컴포넌트 구조
1. WaferMap.tsx (메인 컴포넌트)
웨이퍼맵의 핵심 컴포넌트로 다음 기능들을 제공합니다:
주요 Props:
data: WaferKLARF 타입의 웨이퍼 데이터waferSize: 웨이퍼 표시 크기options: 차트 옵션들toolBoxOption: 툴박스 설정miniMap: 미니맵 설정contextMenu: 컨텍스트 메뉴
핵심 기능:
- ECharts 인스턴스 초기화 및 관리
- 3개 시리즈 렌더링 (Die, Defect, Shot)
- 이벤트 처리 (줌, 선택, 브러시)
- 미니맵 기능
- 회전 및 변환 기능
2. WaferParser.ts (데이터 파싱)
KLARF 포맷 데이터를 ECharts에서 사용할 수 있는 형태로 변환합니다:
주요 메서드:
parse(data: WaferKLARF): 원본 데이터를 Wafer 객체로 변환makeDrawData(data: Wafer): 차트 그리기용 데이터 생성findLeftTop/findRightBottom: 웨이퍼 영역 계산getList/getShotList: 다이/샷 리스트 생성
3. ToolBox.tsx (도구 모음)
웨이퍼맵 조작을 위한 다양한 도구들을 제공합니다:
기본 도구들:
- 회전 (좌/우 90도)
- 리셋 (줌 초기화)
- 정보 표시/숨김
- 불량 다이 표시/숨김
- 샷 표시/숨김
전문 도구들:
- ControlTool: 줌, 선택 모드 (단일/다중 박스, 올가미)
- RangeTool: 범위 표시 및 반지름 조절
- DefectSizeTool: 결함 크기 조절
- FlipTool: X/Y축 뒤집기
데이터 파싱 과정 상세 분석
KLARF 데이터 구조 분석
KLARF(KLA Tencor's defect reporting file format)는 반도체 웨이퍼 검사 결과를 표준화된 형태로 저장하는 포맷입니다.
핵심 데이터 필드:
sampleSize: 웨이퍼의 물리적 크기 (mm 단위)diePitch: 다이 간의 간격 [x, y] (mm 단위)shotPitch: 샷 간의 간격 [x, y] (다이 개수 단위)dieOrigin: 다이의 기준점 좌표 [x, y]sampleCenterLocation: 웨이퍼 중심점 좌표 [x, y]sampleTestPlan: 테스트할 다이들의 인덱스 좌표 배열orientationMarkLocation: 웨이퍼 방향 마크 위치 (TOP/BOTTOM/LEFT/RIGHT)defectList: 결함 정보 배열
파싱 과정 단계별 분석
1단계: 웨이퍼 기본 영역 계산
const waferHalf = data.sampleSize / 2;
const waferMin = -waferHalf;
const waferMax = waferHalf;
웨이퍼를 중심점 (0, 0)을 기준으로 하는 좌표계로 설정합니다.
2단계: 다이 영역 경계 계산
const width = data.dieOrigin[0] + data.diePitch[0];
const height = data.dieOrigin[1] + data.diePitch[1];
const leftTopDie = this.findLeftTop(width, height, dieZeroPos, [-waferHalf, waferHalf]);
const rightBottomDie = this.findRightBottom(width, height, dieZeroPos, [waferHalf, -waferHalf]);
findLeftTop/findRightBottom 알고리즘:
- 웨이퍼 중심에서 시작하여 while 루프로 경계 탐색
- 각 다이의 크기와 피치를 고려하여 웨이퍼 경계 내 유효한 위치 계산
- 웨이퍼의 원형 경계를 고려한 유효성 검사
3단계: 샷 영역 계산
const shotWidth = width * data.shotPitch[0];
const shotHeight = height * data.shotPitch[1];
샷은 여러 다이를 포함하는 더 큰 단위로, 다이 크기에 샷 피치를 곱하여 계산합니다.
4단계: 결함 데이터 매핑
각 결함은 다이 인덱스(xIndex, yIndex)와 다이 내 상대 좌표(xRel, yRel)로 정의되며, 이를 웨이퍼 절대 좌표로 변환합니다.
좌표 변환 로직
// 다이 인덱스를 웨이퍼 좌표로 변환
const dieX = dieZeroPos[0] + (xIndex * diePitch[0]);
const dieY = dieZeroPos[1] + (yIndex * diePitch[1]);
// 결함의 절대 좌표 계산
const defectX = dieX + xRel;
const defectY = dieY + yRel;
좌표계 시스템 분석
다중 좌표계 구조
웨이퍼맵은 3개의 서로 다른 좌표계를 사용합니다:
1. 웨이퍼 물리 좌표계
- 원점: 웨이퍼 중심 (0, 0)
- 단위: mm
- 범위: [-waferSize/2, waferSize/2]
- 특징: KLARF 데이터의 기본 좌표계
2. ECharts 좌표계
- 다중 축 시스템: 각 시리즈별로 독립적인 X/Y축 사용
- Die 시리즈: xAxisIndex=0, yAxisIndex=0
- Defect 시리즈: xAxisIndex=1, yAxisIndex=1
- Shot 시리즈: xAxisIndex=2, yAxisIndex=2
- 축 설정: 모든 축이 동일한 min/max 값 사용
- 변환 지원: 축 반전(inverse), 회전(rotate) 기능
3. 화면 좌표계
- 원점: Canvas 좌상단 (0, 0)
- 단위: 픽셀
- 렌더링: Canvas 2D 컨텍스트 사용
좌표 변환 공식
// 웨이퍼 좌표 → 화면 좌표
x_screen = (x_wafer + waferMax) / (2 * waferMax) * canvasWidth;
y_screen = (waferMax - y_wafer) / (2 * waferMax) * canvasHeight;
컴포넌트 구조
데이터 플로우
주요 데이터 구조
WaferKLARF (입력 데이터)
interface WaferKLARF {
sampleSize: number; // 웨이퍼 크기
diePitch: number[]; // 다이 피치 [x, y]
shotPitch: number[]; // 샷 피치 [x, y]
dieOrigin: number[]; // 다이 원점 [x, y]
sampleCenterLocation: number[]; // 샘플 중심 위치
sampleTestPlan?: number[][]; // 테스트 플랜 좌표들
orientationMarkLocation: Direction; // 방향 마크 위치
defectList?: DefectKLARF[]; // 결함 리스트
}
DefectKLARF (결함 데이터)
interface DefectKLARF {
defectId: number; // 결함 ID
xRel: number; // 상대 X 좌표
yRel: number; // 상대 Y 좌표
xIndex: number; // X 인덱스
yIndex: number; // Y 인덱스
xSize: number; // X 크기
ySize: number; // Y 크기
defectArea: number; // 결함 영역
dSize: number; // 결함 크기
classNumber: number; // 클래스 번호
imageCount: number; // 이미지 개수
symbol?: string; // 심볼 타입
status?: number; // 상태
color?: string; // 색상
}
렌더링 로직 및 시리즈 구성
ECharts 시리즈 구조
웨이퍼맵은 4개의 주요 시리즈로 구성되며, 각각 독립적인 렌더링 레이어를 형성합니다:
1. Die 시리즈 (인덱스 0)
{
name: "Die",
type: "wafermap",
xAxisIndex: 0,
yAxisIndex: 0,
clip: false,
z: -2,
zlevel: -1,
selectedMode: true,
dieStyle: {
dead: "#AAAAAA"
},
itemStyle: {
borderColor: "grey",
color: "#ffffff"
}
}
- 기능: 웨이퍼의 개별 다이(칩) 표시
- 데이터 구조: [x, y, rbx, rby, idx, status, isBad]
- 상태 관리: 정상/불량/선택 상태 구분
- 렌더링: 사각형 형태로 다이 영역 표시
2. Defect 시리즈 (인덱스 1)
{
name: "Defect",
type: "wafermap",
xAxisIndex: 1,
yAxisIndex: 1,
clip: true,
progressive: 2000,
progressiveThreshold: 5000,
large: true,
defectStyle: {
scale: 3
}
}
- 기능: 결함 위치 및 정보 표시
- 데이터 구조: [x, y, width, height, textContent, status, symbol, color]
- 심볼 지원: circle, diamond, triangle, square 등
- 성능 최적화: Progressive 렌더링으로 대용량 데이터 처리
3. Shot 시리즈 (인덱스 2)
{
name: "Shot",
type: "wafermap",
xAxisIndex: 2,
yAxisIndex: 2,
clip: false,
z: -1,
zlevel: -1,
itemStyle: {
borderColor: "red",
color: "rgba(255,255,255,0)"
}
}
- 기능: 샷 영역 표시 (여러 다이를 포함하는 단위)
- 데이터 구조: [x, y, rbx, rby, idx, status]
- 시각화: 반투명 테두리로 영역 구분
4. Arrow 시리즈 (인덱스 3, 선택적)
{
type: "custom",
name: "arrow",
renderItem: renderItem,
dimensions: ["x1", "y1", "r", "d", "scale", "color"]
}
- 기능: 방향성 정보 표시 (화살표)
- 커스텀 렌더링: SVG Path를 이용한 화살표 그리기
- 데이터 구조: [x1, y1, rotation, distance, scale, color]
렌더링 최적화 기법
1. Canvas 렌더링
chartInsRef.current = wafermap.init(chartRef.current, undefined, {
renderer: "canvas",
width: waferSize.width,
height: waferSize.height,
});
- Canvas 2D 컨텍스트 사용으로 고성능 렌더링
- 하드웨어 가속 지원
- 메모리 효율성 향상
2. Progressive 렌더링
progressive: 2000,
progressiveThreshold: 5000,
large: true,
largeThreshold: -1
- 점진적 렌더링: 2000개씩 단계별 렌더링
- 대용량 데이터: 5000개 이상 시 자동 활성화
- 사용자 경험: 렌더링 중에도 상호작용 가능
3. 레이어 관리 (Z-Index)
- Die 레이어: z=-2, zlevel=-1 (최하단)
- Shot 레이어: z=-1, zlevel=-1 (중간)
- Defect 레이어: z=기본값 (최상단)
- Arrow 레이어: z=기본값 (최상단)
상호작용 시스템
1. 이벤트 처리 구조
// 선택 이벤트
chartInsRef.current.on("selectchanged", defectSelectHandler);
// 브러시 선택 이벤트
chartInsRef.current.on("brushselected", defectBoxSelectHandler);
// 줌 이벤트
chartInsRef.current.on("datazoom", drawMinimapViewBox);
2. 선택 모드
- 단일 선택: 개별 요소 클릭
- 박스 선택: 사각형 영역 드래그
- 올가미 선택: 자유형 영역 선택
- 다중 선택: Ctrl+클릭으로 여러 요소 선택
3. 줌 및 팬
- 마우스 휠: 줌 인/아웃
- 드래그: 팬 이동
- 툴박스 줌: 영역 지정 줌
- 미니맵: 전체 뷰 대비 현재 위치 표시
미니맵 시스템 분석
미니맵 구현 원리
const initMiniMap = useCallback(() => {
const src = chartInsRef.current.getDataURL({});
const canvas = document.createElement("canvas");
canvas.width = minimapSize.current;
canvas.height = minimapSize.current;
// 웨이퍼 영역만 추출하여 미니맵 생성
ctx?.drawImage(img, drawArea.x * _rate, drawArea.y * _rate,
drawArea.width * _rate, drawArea.height * _rate,
0, 0, minimapSize.current, minimapSize.current);
}, []);
뷰박스 동기화
const drawMinimapViewBox = useCallback((params) => {
const xBatch = {
start: ((_batch.startValue + xAxisSize.max) /
(Math.abs(xAxisSize.min) + Math.abs(xAxisSize.max))) * 100,
end: ((_batch.endValue + xAxisSize.max) /
(Math.abs(xAxisSize.min) + Math.abs(xAxisSize.max))) * 100
};
const rect = getRect(xBatch, yBatch, minimapSize.current);
reDraw(rect);
}, []);
이벤트 시스템 분석
마우스 이벤트 처리
const handleMouseMove = (event) => {
mousePosition.current = [event.layerX, event.layerY];
};
// 툴팁 위치 동적 계산
tooltip: {
position: () => {
return [mousePosition.current[0] + 10, mousePosition.current[1] + 10];
}
}
상태 관리 패턴
- useRef: DOM 참조 및 차트 인스턴스 관리
- useState: UI 상태 관리 (도구 선택, 옵션 등)
- useCallback: 이벤트 핸들러 메모이제이션
- useEffect: 생명주기 관리 및 이벤트 리스너 등록
도구별 상세 기능 분석
ControlTool - 상호작용 모드 관리
const controlToolsHandler = useCallback((e) => {
const tool = e.target.value;
switch (tool) {
case "zoom": zoomActionHandler(); break;
case "singleBox": selectBoxActionHandler("single"); break;
case "multipleBox": selectBoxActionHandler("multiple"); break;
case "lasso": lassoSelectActionHandler(); break;
default: moveActionHandler(); break;
}
}, []);
모드별 기능:
- Move: 기본 이동 모드, 드래그로 팬 이동
- Zoom: 영역 지정 줌, dataZoomSelect 활성화
- Single Box: 단일 박스 선택, 기존 선택 해제
- Multiple Box: 다중 박스 선택, 기존 선택 유지
- Lasso: 자유형 올가미 선택, 복잡한 영역 선택
RangeTool - 거리 기반 분석
const rangeRadiusActionHandler = (value: string | number | undefined) => {
if (chartInsRef.current && value) {
chartInsRef.current.dispatchAction({
type: "range",
distance: +value,
});
}
};
핵심 기능:
- 동심원 표시: 웨이퍼 중심으로부터의 거리 범위
- 실시간 조절: NumberField를 통한 반지름 값 변경
- 시각적 피드백: 범위 내/외 결함 구분 표시
DefectSizeTool - 결함 시각화 제어
const defectSizeActionHandler = useCallback((value: string | number | undefined) => {
if (chartInsRef.current && value) {
chartInsRef.current.dispatchAction({
type: "defectStyle",
scale: +value,
});
}
}, []);
크기 조절 방식:
- 프리셋 버튼: S(3), M(5), L(7) 빠른 선택
- 직접 입력: 1-10 범위 내 정밀 조절
- 실시간 적용: 즉시 화면에 반영
FlipTool - 축 변환 기능
const inverseXActionHandler = useCallback(() => {
chartInsRef.current.dispatchAction({
type: "axis",
xAxis: [
{ inverse: !isXInverse.current },
{ inverse: !isXInverse.current },
{ inverse: !isXInverse.current },
],
});
}, []);
변환 특징:
- 독립적 제어: X축, Y축 각각 독립적 뒤집기
- 전체 적용: 모든 시리즈에 동시 적용
- 상태 추적: 현재 변환 상태 기억 및 관리
성능 분석 및 최적화
렌더링 성능 분석
// 대용량 데이터 처리 설정
{
progressive: 2000, // 2000개씩 점진적 렌더링
progressiveThreshold: 5000, // 5000개 이상 시 progressive 모드
large: true, // 대용량 데이터 모드
largeThreshold: -1, // 모든 데이터에 large 모드 적용
}
성능 최적화 전략:
- 점진적 렌더링: 사용자 상호작용 차단 최소화
- Canvas 렌더링: SVG 대비 높은 성능
- 애니메이션 비활성화: 불필요한 계산 제거
- 클리핑 최적화: 화면 밖 요소 렌더링 생략
메모리 관리 패턴
// React 최적화
const ToolBox = React.memo(({ chartInsRef, ChartDataRef, ... }) => {
const handler = useCallback(() => { /* ... */ }, []);
const ref = useRef(null);
useEffect(() => {
// 이벤트 리스너 정리
return () => {
window.removeEventListener("mousemove", handleMouseMove);
};
}, []);
});
메모리 최적화 기법:
- React.memo: 불필요한 리렌더링 방지
- useCallback: 함수 재생성 방지
- useRef: DOM 참조 및 값 저장
- 이벤트 정리: 메모리 누수 방지
아키텍처 패턴 분석
관심사 분리 (Separation of Concerns)
WaferMap (컨테이너)
├── WaferParser (데이터 처리)
├── ToolBox (UI 제어)
│ ├── ControlTool (상호작용)
│ ├── RangeTool (분석)
│ ├── DefectSizeTool (시각화)
│ └── FlipTool (변환)
└── wafermap-core (렌더링)
데이터 흐름 패턴
- 단방향 데이터 흐름: Props를 통한 하향식 데이터 전달
- 콜백 패턴: 상위 컴포넌트로의 이벤트 전달
- Ref 패턴: 차트 인스턴스 직접 제어
상태 관리 전략
// 로컬 상태 (컴포넌트별)
const [controlToolValue, setControlToolValue] = useState<string>();
// 공유 상태 (Ref 패턴)
const chartInsRef = useRef<ECharts>();
const ChartDataRef = useRef<ChartData>();
// 영속 상태 (차트 옵션)
const option = chartInsRef.current.getOption();
확장성 및 유지보수성 분석
모듈화 구조
- 컴포넌트 분리: 각 도구가 독립적인 컴포넌트
- 인터페이스 정의: TypeScript를 통한 명확한 타입 정의
- 의존성 주입: Props를 통한 차트 인스턴스 전달
확장 포인트
// 1. 커스텀 도구 추가
interface ToolBoxOption {
customTools?: ToolOption[];
}
// 2. 새로운 시리즈 타입
interface CustomSeriesOption extends SeriesOption {
renderItem?: (params: any, api: any) => any;
}
// 3. 데이터 포맷 확장
class CustomWaferParser extends WaferParser {
parseCustomFormat(data: CustomFormat): Wafer { /* ... */ }
}
테스트 가능성
- 순수 함수: 파싱 로직의 테스트 용이성
- 모킹 가능: 차트 인스턴스 모킹을 통한 단위 테스트
- 컴포넌트 분리: 각 도구별 독립적 테스트
브라우저 호환성 및 성능
Canvas 지원
- 모든 모던 브라우저: Chrome, Firefox, Safari, Edge
- 하드웨어 가속: GPU 가속 지원 브라우저에서 성능 향상
- 메모리 효율: SVG 대비 낮은 메모리 사용량
성능 벤치마크
- 소규모 데이터 (< 1,000개): 즉시 렌더링
- 중간 규모 (1,000 ~ 5,000개): 부분 렌더링
- 대규모 데이터 (> 5,000개): Progressive 렌더링
반응형 지원
const waferSize = { width: number, height: number };
// 동적 크기 조절 지원
종합 분석 결론
핵심 아키텍처 특징
wafermap-poc 프로젝트는 반도체 웨이퍼 결함 분석을 위한 고도로 최적화된 2D 시각화 솔루션입니다. 본 분석을 통해 다음과 같은 핵심 아키텍처 특징들을 확인했습니다:
1. 데이터 처리 파이프라인
- KLARF 표준 준수: 업계 표준 포맷 완벽 지원
- 다단계 좌표 변환: 물리 좌표 → ECharts 좌표 → 화면 좌표
- 효율적 파싱: while 루프 기반 경계 탐색 알고리즘
- 메모리 최적화: 필요한 데이터만 선별적 처리
2. 렌더링 엔진 최적화
- Canvas 기반: 고성능 2D 렌더링
- 다중 레이어: 4개 독립 시리즈 (Die, Defect, Shot, Arrow)
- Progressive 렌더링: 대용량 데이터 점진적 처리
- 다중 축 시스템: 시리즈별 독립적 좌표계
3. 상호작용 시스템
- 5가지 조작 모드: Move, Zoom, Single/Multiple Box, Lasso
- 실시간 피드백: 즉시 반영되는 시각적 변화
- 미니맵 연동: 전체 뷰 대비 현재 위치 표시
- 이벤트 기반: 효율적인 상태 관리
기술적 혁신 요소
1. 좌표계 통합 관리
// 3개 좌표계의 완벽한 동기화
웨이퍼 물리 좌표계 ↔ ECharts 좌표계 ↔ 화면 좌표계
- 각 좌표계 간 무손실 변환
- 실시간 동기화 보장
- 축 변환(반전, 회전) 지원
2. 성능 최적화 전략
- 점진적 렌더링: 사용자 경험 최우선
- 메모리 관리: React 최적화 패턴 적용
- 이벤트 최적화: useCallback, React.memo 활용
3. 확장 가능한 아키텍처
- 플러그인 구조: 새로운 도구 쉽게 추가
- 타입 안전성: TypeScript 완전 지원
- 모듈화: 각 기능의 독립적 개발/테스트
산업적 가치
1. 반도체 제조 공정 지원
- 실시간 결함 분석: 생산 라인 즉시 피드백
- 품질 관리: 통계적 분석 도구 제공
- 트렌드 분석: 시간별/영역별 결함 패턴 파악
2. 사용자 경험 최적화
- 직관적 인터페이스: 전문가가 아니어도 쉽게 사용
- 다양한 분석 도구: 거리 기반, 크기 기반, 영역 기반 분석
- 실시간 상호작용: 즉각적인 피드백과 조작
3. 확장성 및 유지보수성
- 모듈화된 구조: 기능별 독립적 개발
- 표준 준수: KLARF 포맷 완벽 지원
- 브라우저 호환성: 모든 모던 브라우저 지원
향후 발전 방향
1. Three.js 마이그레이션 준비
현재 분석 결과를 바탕으로 3D 웨이퍼맵으로의 확장 시:
- 좌표계 시스템: 현재 2D 좌표계를 3D로 확장
- 렌더링 로직: Canvas 2D → WebGL 3D
- 상호작용 모델: 2D 조작을 3D 환경에 적용
2. 성능 개선 포인트
- WebWorker: 데이터 파싱을 별도 스레드에서 처리
- 가상화: 화면에 보이는 요소만 렌더링
- 캐싱: 계산 결과 메모이제이션component-structure.puml
3. 기능 확장 가능성
- AI 기반 결함 분석: 머신러닝 모델 통합
- 실시간 데이터 스트리밍: WebSocket 기반 실시간 업데이트
- 협업 기능: 다중 사용자 동시 분석
최종 평가
wafermap-poc는 반도체 웨이퍼 결함 분석 분야의 모범 사례로 평가됩니다:
기술적 우수성:
- 최적화된 렌더링 파이프라인
- 확장 가능한 아키텍처 설계
- 업계 표준 완벽 준수
사용자 중심 설계:
- 직관적이고 반응성 높은 UI
- 다양한 분석 도구 제공
- 실시간 피드백 시스템
산업적 적용성:
- 실제 제조 환경에서 즉시 활용 가능
- 대용량 데이터 처리 능력
- 확장성과 유지보수성 보장
이러한 분석 결과를 바탕으로, 향후 3D 웨이퍼맵 개발 시 현재 아키텍처의 핵심 설계 원칙들을 계승하면서도 3D 환경에 최적화된 새로운 기능들을 추가할 수 있을 것입니다.