1. DFT 분석
● 연속 vs 이산 시간
- 연속 시간: 주파수 1Hz의 회전 벡터
- 이산 시간: 주파수 1 cycle/sample의 회전 벡터
- 연속 시간에서는 주파수가 t에 따라 바뀌며 각각 다른 벡터
- 이산 시간에서는 n=1,2,3...일 때 모두 같은 벡터가 반복됨
● 주파수 해석의 차이
- 연속 DFT: K번째 주파수 성분은 원래 주파수의 k배인 기저벡터와의 내적 (범위 제한 없음)
- 이산 DFT: 단위원 상에서 1회전 기준으로 범위 제한됨 → 주기함수 형태로 반복
- 결론: 이산 주파수 분석 결과는 주기성을 가지는 특성이 있음
2. C 언어 구현 결과
for (i = 0; i < 1024; i++)
fft_in[i] = (i >= 200 && i < 300) ? 1024 : 0;
fft(fft_in, fft_out);
● 복소수 자료형 정의 및 연산
typedef struct {
int r, i; // 실수부, 허수부
} t_complex;
void complex_add(t_complex* dst, t_complex src0, t_complex src1) {
dst->r = (src0.r + src1.r) >> 1;
dst->i = (src0.i + src1.i) >> 1;
}
void complex_sub(t_complex* dst, t_complex src0, t_complex src1) {
dst->r = (src0.r - src1.r) >> 1;
dst->i = (src0.i - src1.i) >> 1;
}
void complex_mul(t_complex* dst, t_complex src0, t_complex src1) {
dst->r = (src0.r * src1.r - src0.i * src1.i) >> 9;
dst->i = (src0.r * src1.i + src0.i * src1.r) >> 9;
}
3. SPEC 설정
- 뇌파 신호 분석을 목표로 하므로 Sampling rate는 최대 주파수의 2배 이상으로 설정해야 함
- 뇌파는 보통 30
40Hz 내외 → 최소 80100Hz 이상 샘플링 필요
4. FFT 알고리즘
● Cooley-Tukey FFT 핵심 구조
void fft(int in[1024], t_complex out[1024]) {
// 입력을 복소수로 변환
for (i = 0; i < 1024; i++) {
out[i].r = in[i];
out[i].i = 0;
}
for (i = 0, p = 1024; i < 10; i++, p /= 2) {
for (j = 0; j < 1024 / p; j++) {
for (k = 0; k < p / 2; k++) {
t_complex bf0, bf1;
complex_add(&bf0, out[j*p + k], out[j*p + k + p/2]);
complex_sub(&bf1, out[j*p + k], out[j*p + k + p/2]);
twiddle_mul(&bf1, k, p);
out[j*p + k] = bf0;
out[j*p + k + p/2] = bf1;
}
}
}
}
5. Verilog 구현
● 메모리 연동 로직
always @(posedge clk) begin
if (cs) begin
if (we)
mem_data[addr] <= w_data;
else
r_data <= mem_data[addr];
end
end
● FFT 버터플라이 연산 예시
complex_add(&bf0, out[j*p + k], out[j*p + k + p/2]);
complex_sub(&bf1, out[j*p + k], out[j*p + k + p/2]);
twiddle_mul(&bf1, k, p);
out[j*p + k] = bf0;
out[j*p + k + p/2] = bf1;
6. 추후 계획
- 현재 시뮬레이션 오류 원인을 분석 중
- 파이프라인 구조 구현 예정
- RTL 기반 최적화 및 리소스 사용률 개선을 목표로 개발 진행