posts

웨이퍼맵 2D 분석 - 심화 기술 분석 보고서

Oct 1, 2025 updated Oct 1, 2025 3darchitecturecsslegacytypescript

프로젝트 개요

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 모드 적용
}

성능 최적화 전략:

  1. 점진적 렌더링: 사용자 상호작용 차단 최소화
  2. Canvas 렌더링: SVG 대비 높은 성능
  3. 애니메이션 비활성화: 불필요한 계산 제거
  4. 클리핑 최적화: 화면 밖 요소 렌더링 생략

메모리 관리 패턴

// 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 (렌더링)

데이터 흐름 패턴

  1. 단방향 데이터 흐름: Props를 통한 하향식 데이터 전달
  2. 콜백 패턴: 상위 컴포넌트로의 이벤트 전달
  3. 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 환경에 최적화된 새로운 기능들을 추가할 수 있을 것입니다.