512-Point Radix-8 FFT Processor

ASIC 기반 512-Point FFT 프로세서 설계 및 FPGA 검증

개요

프로젝트 기간

2025.07.21 ~ 2025.08.05

목적

파이프라인 구조의 FFT Processor를 RTL design부터 FPGA 검증까지 수행하여 실무에 적용되는 ASIC 설계 과정을 경험.

  • 1. floating-point -> fixed-point modeling
  • 2. RTL 설계 후, cos, random 입력 벡터 검증
  • 3. Vivado를 통해 RTL verification (FPGA)
  • 4. Synthesis 후, Setup time 통과 및 Area 최소화

개발 환경

  • 사용 언어 : SystemVerilog, MATLAB
  • Tool : VCS, Verdi, Vivado, draw.io
  • editor : vi editor

참고 문헌

  • Shousheng He, Mats Torkelson, “A New Approach to Pipeline FFT Processor.”
  • E. Bidet, D. Castelain, C. Joanblanq, P. Senn, “A Fast Single-Chip Implementation of 8192-Point Complex FFT.”

Pipeline FFT의 핵심 원리

1. Decimation 전략

시간 분할 (DIT) 또는 주파수 분할 (DIF) 방식으로 알고리즘을 선택, 입력 데이터 순서를 적절히 재배열해 각 단계에 공급.
이번 프로젝트에서는 Radix-8 DIF 방식을 채택.

2. Butterfly 연산

Butterfly 연산은 FFT의 핵심 연산으로 덧셈·뺄셈과 twiddle factor(회전 인자) 곱셈을 수행.

3. 파이프라인 스테이지

본 프로젝트의 FFT 프로세서는 입력을 16개 단위로 받아 총 9개 스테이지를 거치며, 각 스테이지에서 butterfly 연산과 delay 요소를 수행.
파이프라인이 채워진 이후에는 매 클럭마다 새로운 입력을 받아들이고 동시에 FFT 결과를 출력.


Fixed-point 모델링 (MATLAB)

1. 시스템 아키텍쳐

2. 데이터 포맷

3. CBFP

  • 스테이지 별로 필요한 만큼만 시프트(스케일링) 해주어 동적 범위를 넓게 확보 가능.
  • 정보 손실을 줄이고 신호 대 잡음비 (SQNR) 개선 가능.
  • CBFP 원리
    • 각 입력에 대한 시프트 값 계산.
    • 블록 내 가장 큰 값 기준 시프트 값 저장.
    • 저장된 시프트 값으로 블록 내 모든 입력에 대해 시프트 수행.
    • 시프트 값을 인덱스 레지스터로 출력, 연산이 끝난 후 복원.

4. SQNR 결과

SQNR : 신호 대 잡음 비로 Fixed-point 설계의 정확도 손실을 수치화할수 있는 지표
40dB이상의 SQNR 확보 성공.

5. Fixed-point modeling 결과 (Cos)


RTL 설계

블록 다이아그램

데이터 흐름

  • 1. 입력: <3.6> 고정소수점(9bit) 16개의 벡터가 [15:0] 형태로 유입. 즉, 512개의 벡터가 들어오기 위해 총 32clk이 소요.
  • 2. 처리: 각 스테이지에 파이프 레지스터를 배치해 setup time slack을 확보하며, 모듈당 3 스테이지 + CBFP로 스케일 조정.
  • 3. 출력: 마지막 스테이지에서 두 번의 CBFP 시프트 복원 후 reordering을 거쳐 <9.4>(13bit) 16샘플 벡터로 배출.

스테이지별 연산 유효 구간(valid) 길이 : 32clk -> 16clk -> 8clk -> 4clk -> 2clk -> 1clk

Stage별 설명

  • Stage_0 ~ Stage_4 : 버터플라이 짝 간격(stride=256→16)이 16개의 벡터보다 커서 즉시 연산이 불가. 16개씩 Shift Register에 누적하다가 짝이 도착하는 시점(예: stage0은 0↔256)에 Valid를 올려 16포인트 버터플라이 → twiddle 곱을 수행. (파이프라인 구조)
  • Stage_5 ~ Stage_8 : 짝 간격(stride = 8, 4, 2, 1)이 16개의 벡터 안에 존재하므로 Shift Register에 누적 시킬 필요 없이 즉시 버터플라이 -> twiddle 곱을 수행.

RTL Simulation 및 Synthesis 결과

Latency 결과

Cos / Random vector 검증

Cos / Random 벡터를 입력으로 주었을 때, MATLAB 시뮬레이션 결과와 RTL 설계 결과가 일치함을 확인.
(왼쪽이 MATLAB fixed-point 결과, 오른쪽이 RTL Simulation 결과)

Synthesis 결과 (Area & Timing)

Gate Simulation 결과 (Cos vector)

  • Synthesis 결과로 나온 netlist 파일을 이용하여 gate simulation 진행.
  • X value 없이 의도한 동작이 나오는 것을 확인.
  • 최종 출력 결과 또한 MATLAB의 결과와 일치.


FPGA 검증

FPGA 구현

  • UltraZed-7EV Carrier Card 보드 Spec 사용.
    • 클럭 입력 : 300MHz
    • I/O 전압 : 3.3V or 1.8V
  • Clocking Wizard IP : Vivado에서 제공하는 clk generator IP.
    • MMCM(Mixd-Mode Clock Manager) 모드 사용.
    • 300MHz differential clock -> 100MHz single clock으로 변환.
  • VIO (Virtual Input/Output) : 특정 신호의 값을 가상으로 읽거나 쓸 수 있게 해주는 IP.
    • input : dour_re[15:0], dout_im[15:0], valid_out
    • output : port 연결 X

시뮬레이션 결과 (Timing Diagram)

Synthesis 결과 (Area & Timing)


트러블 슈팅

bf_cntr 모듈 구조 개선

  • 초기 설계 구조 : valid_in 입력 시 DELAY 후 32 클럭 연산, 완료 시 자동 리셋되는 FSM 구조
  • 문제점 : Cos Generator가 32clk 출력 + 8clk 휴식을 반복함. 첫 512개의 샘플 처리까지는 정상이였는데, 8clk 휴식 후 두 번째 구간에서 연산 결과가 의도와 다르게 변조됨.
  • 원인 분석 : 기존 단일 FSM에서는 Cos Generator를 생각하지 않고 512개의 샘플 입력이 32clk 동안 한 번만 들어오는 것으로 생각함. 8clk 휴식 후, 샘플 입력이 재개될 때, 이전 FSM 상태 전이가 완전히 종료되지 않은 시점에 다음 구간이 시작되어 Valid 신호 타이밍이 꼬임.
  • 해결 방법 : 기능을 두 FSM으로 분리해 독립 진행하도록 재설계.
    • 1) wait_cnt FSM : 초기 valid 신호를 띄울 타이밍을 맞추는 딜레이 제어(예: 16→8→4→…clk).
    • 2) region_cnt FSM : valid 신호를 정확히 32clk 유지.


느낀점

  • 각 연산기에 따른 delay 차이를 이해하고 이에 맞춘 파이프 레지스터 배치 및 분할 전략을 체득함.
  • Verilog/SystemVerilog 문법 이해가 한층 깊어졌고, 테스트벤치 기반의 검증 프로세스를 설계하면서 HDL·검증 역량이 향상됨을 느낌.
  • 실무 규모에 근접한 프로젝트에서 팀장을 맡아 일정에 따른 목표의 관리, 팀원의 역량에 따른 역할 분배에 대한 중요성을 경험했고, 효율적인 분업·협업 체계가 성과에 직결됨을 확인함.

GitHub Source