AI가 정말로 FPGA용 Verilog를 작성할 수 있을까? 나의 실전 테스트
풀스택 웹 개발과 FPGA/Verilog 프로그래밍을 모두 하는 사람으로서, 나는 궁금했다. AI 코딩 어시스턴트들이 하드웨어 기술 언어(HDL)를 다룰 수 있을까?
모두가 AI가 JavaScript, Python, Rust 같은 소프트웨어를 작성하는 것에 대해 이야기한다. 하지만 Verilog는 어떨까? VHDL은 어떨까? LLM이 실제로 하드웨어 병렬성, 타이밍 제약 조건, 그리고 FPGA 특유의 문제점들을 이해할 수 있을까?
나는 직접 테스트해보기로 했다. 지난 한 달 동안 나는 실제 FPGA 프로젝트에 AI 도구들(Claude, GPT-4, Cursor)을 사용했다. 무엇이 작동했고, 무엇이 작동하지 않았는지, 그리고 AI가 하드웨어 설계에 실제로 유용한지 여기에 정리한다.
내가 회의적이었던 이유
나는 독학으로 FPGA 개발자가 되었다. 나는 Verilog를 충분히 잘 알아서 동작하는 회로를 설계할 수 있지만, 숙련된 ASIC 엔지니어는 아니다. 그래서 AI가 도움을 줄 수 있을 거라 기대했지만, 동시에 회의적이기도 했다.
하드웨어 기술 언어(HDL)는 소프트웨어와 근본적으로 다르다:
- 병렬 실행: 모든 것이 단계별로가 아니라 한 번에 일어난다.
- 타이밍 중요성: 100MHz에서만 나타나는 버그는 시뮬레이션에서는 보이지 않을 수 있다.
- 자원 제약: FPGA는 고정된 LUT(Look-Up Table), 플립플롭, DSP 블록을 가지고 있다.
- 툴체인 특이점: 모든 FPGA 벤더(Xilinx, Intel, Lattice)는 자신만의 독특한 특징을 가지고 있다.
LLM이 실제로 이것들을 이해할 수 있을까?
테스트 1: 기본 모듈
간단하게 시작해 보자. 나는 Claude에게 UART 송신기를 작성해 달라고 요청했다.
프롬프트: "UART 송신기용 Verilog 모듈을 작성해 주세요. 보율은 115200 baud, 데이터 형식은 8N1이며 클럭 주파수는 50MHz입니다."
결과: 깨끗하고 구조가 잘 잡힌 UART 송신기가 작성되었다. 여기에는 다음 기능들이 포함되어 있었다:
- 보율 생성기(baud rate generator)
- 시프트 레지스터(shift register)
- 시작/정지 비트 로직(Start/stop bit logic)
- 심지어 패리티 비트 옵션까지 추가했다.
이것이 정확했을까? 대부분은 그랬다. 나는 보율 분주기 계산을 수정해야 했다 (50MHz / 115200 ≈ 434를 사용했는데, 이는 맞았다). 하지만 구조 자체는 탄탄했다.
평가: ✅ 표준 빌딩 블록에는 잘 작동한다. UART, SPI, I2C, PWM 등 일반적인 인터페이스 모두 해당된다.
테스트 2: 상태 머신
다음으로 더 복잡한 설계를 요청했습니다: 설정 가능한 레지스터 파일을 가진 SPI 마스터입니다.
프롬프트: "내부 레지스터에 읽기/쓰기가 가능한 Verilog SPI 마스터 모듈을 작성해 줘. 4선식 SPI, 모드 0."
결과: 결과는 좋았습니다. 다음 요소들을 포함하고 있었습니다:
- 적절한 SPI 모드 0 타이밍 (CPOL=0, CPHA=0)
- SPI 트랜잭션을 위한 상태 머신(state machine)
- 내부 레지스터 뱅크
- 칩 선택 처리
하지만 잘못된 점도 있었습니다. 순차 블록에서 비차단 할당(<=)을 사용해야 하는데, 차단 할당(=)을 사용했습니다. 이것은 전형적인 Verilog의 함정(gotcha)입니다. 시뮬레이션에서는 잡지 못할 수도 있지만, 합성(synthesis) 단계에서는 문제가 될 수 있는 종류입니다.
제가 알아야 하니까 잡아냈습니다. 초보자는 그렇지 못할 수도 있습니다.
평가: ⚠️ 구조는 좋지만, 미묘한 Verilog 실수를 주의해야 합니다.
테스트 3: 타이밍 및 제약 조건(Timing and Constraints)
여기서 흥미로워집니다. 타이밍 클로저(timing closure)는 FPGA 설계에서 가장 어려운 부분 중 하나입니다.
프롬프트: "내 디자인은 100MHz 클럭을 사용하는데, 설정 시간 위반(setup time violations)이 발생하고 있어. 어떻게 고칠 수 있을까?"
결과: 표준적인 조언을 해주었습니다:
- 파이프라인 레지스터 추가 (Add pipeline registers)
- 로직 재타이밍 (Retime logic)
- FPGA 내장 RAM 블록 사용
- 조합 루프(combinational loops) 확인
모두 좋은 조언이지만, 너무 일반적입니다. 실제로 제 특정 타이밍 리포트(timing report)를 보고 어떤 경로가 문제인지 말해줄 수는 없었습니다.
평가: ⚠️ 이론적인 조언은 좋지만, 사용자의 특정 타이밍 리포트를 분석할 수는 없습니다.
테스트 4: 기존 코드 디버깅 (Debugging Existing Code)
제가 가장 궁금했던 부분입니다. AI가 고장 난 Verilog를 디버깅하는 데 도움을 줄 수 있을까요?
작동하는 SPI 모듈을 가져와서 버그를 도입했습니다. MOSI 신호와 MISO 신호를 서로 바꾼 것입니다.
프롬프트: "내 SPI 리시버가 작동하지 않아. 내가 받는 데이터가 전부 0이야. 내 코드는 이거야: [붙여넣은 Verilog]"
결과: 코드를 읽고 몇 초 만에 MISO/MOSI 혼동을 발견했습니다. 왜 잘못되었는지, 그리고 어떻게 고쳐야 하는지 설명해 주었습니다.
인상적입니다. 하지만 솔직히 말해서 — 이것은 간단한 버그였습니다. 더 까다로운 버그는 어떨까요?
저는 더 미묘한 버그를 시도해 보았습니다: 비동기 입력(asynchronous input)을 이중 동기화(double-synchronize)하는 것을 깜빡한 메타스테이블리티(metastability) 문제였습니다.
프롬프트: "UART RX 라인에서 무작위 비트 오류가 발생하고 있어요. 설계는 시뮬레이션에서는 작동하지만 하드웨어에서는 실패해요."
결과: 메타스테이블리티 문제를 확인해 보라고 제안했습니다. 비동기 입력은 적절한 동기화(synchronization)가 필요하다고 언급했지만, 전체 설계를 볼 수 없었기 때문에 정확한 문제 지점을 짚어내지는 못했습니다.
평가: ✅ 명백한 버그를 찾는 데는 탁월합니다. ⚠️ 미묘한 타이밍/메타스테이블리티 문제는 더 어렵습니다.
테스트 5: FPGA 전용 지식
Xilinx UltraRAM이나 Intel DSP 블록 같은 FPGA 공급업체별(vendor-specific) 내용은 어떨까요?
프롬프트: "FIR 필터를 구현하기 위해 Xilinx DSP48E2 블록을 사용하는 Verilog 설계를 작성해 주세요."
결과: 구조는 작성했지만, DSP48E2 인스턴스화(instantiation)가 잘못되었습니다. 실제 Xilinx 프리미티브 이름 대신 일반적인 이름을 사용했습니다.
정확한 프리미티브 이름, 포트 및 매개변수(parameters)를 알아야 하는데, AI는 항상 이를 정확하게 파악하지 못합니다.
평가: ⚠️ 범용 로직에는 좋지만, 공급업체별 프리미티브는 수동 수정이 필요합니다.
실제로 시간을 절약해 주는 것들
FPGA 프로젝트에서 한 달 동안 AI를 사용해 본 결과, 실제로 시간이 절약되는 것은 다음과 같습니다:
1. 보일러플레이트 및 공통 인터페이스
UART, SPI, I2C, PWM, I2S 등 모든 표준 빌딩 블록입니다. AI는 이들을 90%의 확률로 정확하게 작성하여 레퍼런스 코드를 찾아보는 시간을 몇 시간이나 절약해 줍니다.
2. 테스트벤치(Testbenches)
테스트벤치를 작성하는 것은 지루한 작업입니다. 하지만 AI는 놀라울 정도로 잘 해냅니다.
이것이 FPGA 설계의 어려운 부분입니다. AI는 타이밍 리포트(timing report)를 읽고 어떤 경로를 수정해야 하는지 정확히 알려줄 수 없습니다. 여전히 사용자가 직접 셋업/홀드 시간(setup/hold time), 클럭 스큐(clock skew), 그리고 리타이밍(retiming)을 이해해야 합니다.
2. 자원 최적화 (Resource Optimization)
"이 설계를 Lattice iCE40의 LUT 1280개에 넣을 수 있을까?" AI는 추정할 수는 있지만, 실제로 합성(synthesis)을 실행하여 실제 자원 사용량을 확인할 수는 없습니다.
Xilinx Vivado, Intel Quartus, Lattice iCEcube2 등은 각각 고유의 Tcl 스크립팅, 제약 조건 형식(constraints format), 그리고 빌드 플로우를 가지고 있습니다. AI는 사용자의 특정 툴체인(toolchain) 내부 사정을 알지 못합니다.
4. 미묘한 하드웨어 버그 (Subtle Hardware Bugs)
메타안정성(Metastability), 레이스 컨디션(race conditions), 글리치(glitches) 등은 시뮬레이션에서는 나타나지 않지만 실제 하드웨어에서 치명적인 버그들입니다. 사용자가 명시적으로 지적하지 않는 한 AI는 이를 잡아내지 못합니다.
현재 나의 작업 흐름 (My Workflow Now)
제가 FPGA 작업을 위해 실제로 AI를 사용하는 방법은 다음과 같습니다:
- 설계 단계(Design phase): 블록 다이어그램은 제가 직접 스케치합니다. AI가 저 대신 아키텍처적 결정을 내리지는 않습니다.
- 구현(Implementation): 저는 AI에게 보일러플레이트 모듈(UART, SPI 등) 작성을 요청합니다.
- 통합(Integration): 모든 것을 수동으로 연결합니다.
- 테스트벤치(Testbench): AI가 테스트벤치를 작성합니다.
- 디버깅(Debugging): 시뮬레이션이 실패하면, 코드를 붙여 넣고 AI에게 도움을 요청합니다.
- 합성(Synthesis): 툴은 제가 직접 실행합니다. AI는 타이밍 제약 조건(timing constraints)에 손대지 않습니다.
AI는 조종사(pilot)가 아니라 부조종사(copilot)입니다. 지루하고 반복적인 부분은 AI가 처리하고, 저는 아키텍처와 까다로운 부분을 담당합니다.
FPGA 개발자가 AI를 사용해야 할까?
네, 단서 조항과 함께 그렇습니다.
AI는 다음 작업에 매우 유용합니다:
- 표준 빌딩 블록 작성
- 테스트벤치 생성
- 명백한 버그 디버깅
- 생소한 코드 설명
하지만 AI가 좋지 않은 영역은 다음과 같습니다:
- 아키텍처적 결정
- 타이밍 클로저(Timing closure)
- 벤더별 최적화
- 미묘한 하드웨어 버그
AI를 주니어 엔지니어처럼 생각하세요. 잘 정의된 작업에 대해서는 작동하는 코드를 대량으로 만들어낼 수 있지만, 여전히 사용자가 주의 깊게 검토해야 합니다. 그리고 어려운 문제들—타이밍, 자원, 아키텍처—은 여전히 사용자 본인이 책임져야 합니다.
결론
AI가 곧바로 FPGA 엔지니어를 대체하지는 못할 것입니다. 하드웨어 설계는 너무 미묘하고, 특정 하드웨어에 너무 의존하며, 실제 측정값에 크게 좌우되기 때문입니다.
하지만 AI는 FPGA 개발자들의 생산성을 높여줄 것입니다. 예전에 몇 시간이 걸리던 지루한 보일러플레이트(boilerplate) 코딩이 이제는 몇 분 만에 끝납니다. 절약된 시간은 실제로 중요한 부분, 즉 아키텍처 설계, 최적화, 테스트 같은 핵심 작업에 투입될 수 있습니다.
만약 당신이 FPGA 개발자인데 아직 AI를 사용하고 있지 않다면, 지금도 UART나 SPI 모듈을 처음부터 코딩하는 데 너무 많은 시간을 쓰고 있는 것입니다.
본 내용은 wuhuajin.com에서 진행된 실제 FPGA 개발 작업을 기반으로 합니다. 만약 당신도 FPGA와 소프트웨어 개발을 함께 하고 있다면, AI 도구를 어떻게 사용하고 있는지 듣고 싶습니다.