#include #include #include #include #include #include // BSP板级支持包所需全局变量 unsigned long UART_BASE = 0xbf000000; unsigned long CONFREG_TIMER_BASE = 0xbf20f100; unsigned long CONFREG_CLOCKS_PER_SEC = 50000000L; unsigned long CORE_CLOCKS_PER_SEC = 33000000L; const float PI = 3.14159265358979323846; // 读取定时器的当前Tick unsigned int get_timer_ticks() { return RegRead(CONFREG_TIMER_BASE); } // 软件FFT实现 (基2 DIT-FFT 算法) void sw_fft(float re[], float im[], int n) { int i, j, k, l; float tr, ti, ur, ui, wr, wi; // 比特翻转 (Bit Reversal) j = 0; for (i = 0; i < n - 1; i++) { if (i < j) { tr = re[i]; ti = im[i]; re[i] = re[j]; im[i] = im[j]; re[j] = tr; im[j] = ti; } k = n / 2; while (k <= j) { j -= k; k /= 2; } j += k; } // 蝶形运算 (Butterfly Computation) for (l = 1; l < n; l *= 2) { ur = 1.0; ui = 0.0; wr = cos(PI / l); wi = -sin(PI / l); for (i = 0; i < n; i += 2 * l) { ur = 1.0; ui = 0.0; for (j = 0; j < l; j++) { int p = i + j; int q = p + l; tr = re[q] * ur - im[q] * ui; ti = re[q] * ui + im[q] * ur; re[q] = re[p] - tr; im[q] = im[p] - ti; re[p] += tr; im[p] += ti; float next_ur = ur * wr - ui * wi; ui = ur * wi + ui * wr; ur = next_ur; } } } } int main(int argc, char** argv) { unsigned int fft_csr = RegRead(FFT_CSR_REG); printf("fft_csr = %x\n", fft_csr); // 准备测试数据 float sw_in_re[FFT_POINT_NUM]; float sw_in_im[FFT_POINT_NUM]; for (int i = 0; i < FFT_POINT_NUM; i++) { float dc_part = 4000.0f; float f10_part = 8000.0f * cos(2 * PI * 10.0 * i / FFT_POINT_NUM); float f200_part = 6000.0f * sin(2 * PI * 200.0 * i / FFT_POINT_NUM); float f400_part = 3000.0f * sin(2 * PI * 400.0 * i / FFT_POINT_NUM); sw_in_re[i] = dc_part + f10_part + f200_part + f400_part; sw_in_im[i] = 0.0f; } unsigned int tick_start, tick_end; unsigned int hw_time, sw_time; // 硬件加速 FFT 测试 printf("\n--- Starting Hardware FFT ---\n"); tick_start = get_ns(); for (int i = 0; i < FFT_POINT_NUM; i++) { RegWrite(FFT_IN_RE_BASE + (i * 4), (unsigned int)((int)sw_in_re[i])); RegWrite(FFT_IN_IM_BASE + (i * 4), 0); } fft_start(); fft_wait(); tick_end = get_ns(); // 如果定时器是递减的,这里可能是 tick_start - tick_end // 假设定时器是向上递增的: hw_time = tick_end - tick_start; int hw_out_re[FFT_POINT_NUM]; int hw_out_im[FFT_POINT_NUM]; for (int i = 0; i < FFT_POINT_NUM; i++) { hw_out_re[i] = (int)RegRead(FFT_OUT_RE_BASE + (i * 4)); hw_out_im[i] = (int)RegRead(FFT_OUT_IM_BASE + (i * 4)); } // ========================================== // 2. 纯软件 FFT 测试 // ========================================== printf("--- Starting Software FFT ---\n"); tick_start = get_ns(); sw_fft(sw_in_re, sw_in_im, FFT_POINT_NUM); tick_end = get_ns(); sw_time = tick_end - tick_start; // ========================================== // 3. 打印对比结果 // ========================================== printf("\n--- Performance Comparison ---\n"); printf("Timer Clock Freq : %lu Hz\n", CONFREG_CLOCKS_PER_SEC); printf("Hardware FFT Time: %u ns (%.3f ms)\n", hw_time, (float)hw_time / 1000000.0); printf("Software FFT Time: %u ns (%.3f ms)\n", sw_time, (float)sw_time / 1000000.0); if (hw_time > 0) { printf("Speedup Ratio : %.2fx\n", (float)sw_time / hw_time); } printf("\n--- Verification (Only showing Bins with energy > 10) ---\n"); for (int i = 0; i < FFT_POINT_NUM; i++) { if (fabs(hw_out_re[i]) > 10 || fabs(hw_out_im[i]) > 10) { printf("Bin [%4d] Hz: HW(Re:%6d, Im:%6d) | SW(Re:%6d, Im:%6d)\n", i, hw_out_re[i], hw_out_im[i], (int)sw_in_re[i] / FFT_POINT_NUM, (int)sw_in_im[i] / FFT_POINT_NUM); } } return 0; }