test(dma,fft): rewrite test programs for dma, fft and fft_dma
This commit is contained in:
@@ -1,9 +1,12 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <common_func.h>
|
#include <common_func.h>
|
||||||
#include <confreg_time.h>
|
#include <confreg_time.h>
|
||||||
|
#include <dma.h>
|
||||||
|
|
||||||
// BSP板级支持包所需全局变量
|
// BSP板级支持包所需全局变量
|
||||||
unsigned long UART_BASE = 0xbf000000;
|
unsigned long UART_BASE = 0xbf000000;
|
||||||
@@ -11,35 +14,12 @@ unsigned long CONFREG_TIMER_BASE = 0xbf20f100;
|
|||||||
unsigned long CONFREG_CLOCKS_PER_SEC = 50000000L;
|
unsigned long CONFREG_CLOCKS_PER_SEC = 50000000L;
|
||||||
unsigned long CORE_CLOCKS_PER_SEC = 33000000L;
|
unsigned long CORE_CLOCKS_PER_SEC = 33000000L;
|
||||||
|
|
||||||
#define FFT_BASE 0xbf400000
|
|
||||||
#define FFT_IN_RE_BASE (FFT_BASE + 0x1000)
|
|
||||||
#define FFT_IN_IM_BASE (FFT_BASE + 0x2000)
|
|
||||||
#define FFT_OUT_RE_BASE (FFT_BASE + 0x3000)
|
|
||||||
#define FFT_OUT_IM_BASE (FFT_BASE + 0x4000)
|
|
||||||
#define FFT_CSR_REG (FFT_BASE + 0xF000)
|
|
||||||
#define FFT_CTRL_START (1 << 4)
|
|
||||||
#define FFT_STAT_DONE (1 << 1)
|
|
||||||
#define FFT_STAT_BUSY (1 << 0)
|
|
||||||
#define FFT_POINT_NUM 1024
|
|
||||||
|
|
||||||
#define DMA_BASE 0xbf300000
|
|
||||||
#define DMA_CTRL (DMA_BASE + 0x0000)
|
|
||||||
#define DMA_LEN (DMA_BASE + 0x0004)
|
|
||||||
#define DMA_SRC_ADDR (DMA_BASE + 0x0008)
|
|
||||||
#define DMA_DST_ADDR (DMA_BASE + 0x000c)
|
|
||||||
#define DMA_STATUS (DMA_BASE + 0x0010)
|
|
||||||
|
|
||||||
const float PI = 3.14159265358979323846;
|
|
||||||
|
|
||||||
// 加上 aligned(64) 是为了防止 DMA 突发传输时跨越缓存行或 AXI 非对齐边界
|
// 加上 aligned(64) 是为了防止 DMA 突发传输时跨越缓存行或 AXI 非对齐边界
|
||||||
uint32_t src_array[64] __attribute__((aligned(64)));
|
uint32_t src_array[64] __attribute__((aligned(64)));
|
||||||
uint32_t dst_array[64] __attribute__((aligned(64)));
|
uint32_t dst_array[64] __attribute__((aligned(64)));
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
unsigned int dma_status = RegRead(DMA_STATUS);
|
|
||||||
printf("dma_status init = %x\n", dma_status);
|
|
||||||
|
|
||||||
uint32_t data_len = 64;
|
uint32_t data_len = 64;
|
||||||
uint32_t byte_len = data_len * 4;
|
uint32_t byte_len = data_len * 4;
|
||||||
|
|
||||||
@@ -65,22 +45,9 @@ int main(int argc, char** argv)
|
|||||||
printf("uncached_src: %x\n", uncached_src);
|
printf("uncached_src: %x\n", uncached_src);
|
||||||
printf("uncached_dst: %x\n", uncached_dst);
|
printf("uncached_dst: %x\n", uncached_dst);
|
||||||
|
|
||||||
|
|
||||||
// 配置 DMA:DMA 只需要最纯粹的物理地址
|
// 配置 DMA:DMA 只需要最纯粹的物理地址
|
||||||
RegWrite(DMA_SRC_ADDR, phys_src_addr);
|
dma_start_transfer(0, phys_src_addr, phys_dst_addr, byte_len);
|
||||||
RegWrite(DMA_DST_ADDR, phys_dst_addr);
|
dma_wait_polling(0);
|
||||||
RegWrite(DMA_LEN, byte_len);
|
|
||||||
|
|
||||||
// burst_len = 15(16拍), burst_size = 2(4字节)
|
|
||||||
uint32_t burst_len = 15;
|
|
||||||
uint32_t burst_size = 2;
|
|
||||||
uint32_t ctrl_val = (burst_len << 6) | (burst_size << 3) | 0x01;
|
|
||||||
RegWrite(DMA_CTRL, ctrl_val);
|
|
||||||
|
|
||||||
// 等待 DMA 完成
|
|
||||||
while ((RegRead(DMA_STATUS) & 0x01) == 0) {
|
|
||||||
printf("polling...\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("dma passed!\n");
|
printf("dma passed!\n");
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include <common_func.h>
|
#include <common_func.h>
|
||||||
#include <confreg_time.h>
|
#include <confreg_time.h>
|
||||||
|
#include <fft.h>
|
||||||
|
|
||||||
// BSP板级支持包所需全局变量
|
// BSP板级支持包所需全局变量
|
||||||
unsigned long UART_BASE = 0xbf000000;
|
unsigned long UART_BASE = 0xbf000000;
|
||||||
@@ -10,24 +12,6 @@ unsigned long CONFREG_TIMER_BASE = 0xbf20f100;
|
|||||||
unsigned long CONFREG_CLOCKS_PER_SEC = 50000000L;
|
unsigned long CONFREG_CLOCKS_PER_SEC = 50000000L;
|
||||||
unsigned long CORE_CLOCKS_PER_SEC = 33000000L;
|
unsigned long CORE_CLOCKS_PER_SEC = 33000000L;
|
||||||
|
|
||||||
#define FFT_BASE 0xbf400000
|
|
||||||
#define FFT_IN_RE_BASE (FFT_BASE + 0x1000)
|
|
||||||
#define FFT_IN_IM_BASE (FFT_BASE + 0x2000)
|
|
||||||
#define FFT_OUT_RE_BASE (FFT_BASE + 0x3000)
|
|
||||||
#define FFT_OUT_IM_BASE (FFT_BASE + 0x4000)
|
|
||||||
#define FFT_CSR_REG (FFT_BASE + 0xF000)
|
|
||||||
#define FFT_CTRL_START (1 << 4)
|
|
||||||
#define FFT_STAT_DONE (1 << 1)
|
|
||||||
#define FFT_STAT_BUSY (1 << 0)
|
|
||||||
#define FFT_POINT_NUM 1024
|
|
||||||
|
|
||||||
#define DMA_BASE 0xbf300000
|
|
||||||
#define DMA_CTRL (DMA_BASE + 0x0000)
|
|
||||||
#define DMA_LEN (DMA_BASE + 0x0004)
|
|
||||||
#define DMA_SRC_ADDR (DMA_BASE + 0x0008)
|
|
||||||
#define DMA_DST_ADDR (DMA_BASE + 0x000c)
|
|
||||||
#define DMA_STATUS (DMA_BASE + 0x0010)
|
|
||||||
|
|
||||||
const float PI = 3.14159265358979323846;
|
const float PI = 3.14159265358979323846;
|
||||||
|
|
||||||
// 读取定时器的当前Tick
|
// 读取定时器的当前Tick
|
||||||
@@ -35,14 +19,12 @@ unsigned int get_timer_ticks() {
|
|||||||
return RegRead(CONFREG_TIMER_BASE);
|
return RegRead(CONFREG_TIMER_BASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------
|
|
||||||
// 软件FFT实现 (基2 DIT-FFT 算法)
|
// 软件FFT实现 (基2 DIT-FFT 算法)
|
||||||
// ---------------------------------------------------------
|
|
||||||
void sw_fft(float re[], float im[], int n) {
|
void sw_fft(float re[], float im[], int n) {
|
||||||
int i, j, k, l;
|
int i, j, k, l;
|
||||||
float tr, ti, ur, ui, wr, wi;
|
float tr, ti, ur, ui, wr, wi;
|
||||||
|
|
||||||
// 1. 比特翻转 (Bit Reversal)
|
// 比特翻转 (Bit Reversal)
|
||||||
j = 0;
|
j = 0;
|
||||||
for (i = 0; i < n - 1; i++) {
|
for (i = 0; i < n - 1; i++) {
|
||||||
if (i < j) {
|
if (i < j) {
|
||||||
@@ -58,7 +40,7 @@ void sw_fft(float re[], float im[], int n) {
|
|||||||
j += k;
|
j += k;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 蝶形运算 (Butterfly Computation)
|
// 蝶形运算 (Butterfly Computation)
|
||||||
for (l = 1; l < n; l *= 2) {
|
for (l = 1; l < n; l *= 2) {
|
||||||
ur = 1.0;
|
ur = 1.0;
|
||||||
ui = 0.0;
|
ui = 0.0;
|
||||||
@@ -110,9 +92,7 @@ int main(int argc, char** argv)
|
|||||||
unsigned int tick_start, tick_end;
|
unsigned int tick_start, tick_end;
|
||||||
unsigned int hw_time, sw_time;
|
unsigned int hw_time, sw_time;
|
||||||
|
|
||||||
// ==========================================
|
// 硬件加速 FFT 测试
|
||||||
// 1. 硬件加速 FFT 测试
|
|
||||||
// ==========================================
|
|
||||||
printf("\n--- Starting Hardware FFT ---\n");
|
printf("\n--- Starting Hardware FFT ---\n");
|
||||||
tick_start = get_ns();
|
tick_start = get_ns();
|
||||||
|
|
||||||
@@ -122,10 +102,8 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RegWrite(FFT_CSR_REG, FFT_CTRL_START);
|
fft_start();
|
||||||
while ((RegRead(FFT_CSR_REG) & FFT_STAT_DONE) == 0) {
|
fft_wait();
|
||||||
// 等待硬件计算完成
|
|
||||||
}
|
|
||||||
|
|
||||||
tick_end = get_ns();
|
tick_end = get_ns();
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <common_func.h>
|
#include <common_func.h>
|
||||||
#include <confreg_time.h>
|
#include <confreg_time.h>
|
||||||
|
#include <dma.h>
|
||||||
|
#include <fft.h>
|
||||||
|
|
||||||
// BSP板级支持包所需全局变量
|
// BSP板级支持包所需全局变量
|
||||||
unsigned long UART_BASE = 0xbf000000;
|
unsigned long UART_BASE = 0xbf000000;
|
||||||
@@ -11,42 +15,8 @@ unsigned long CONFREG_TIMER_BASE = 0xbf20f100;
|
|||||||
unsigned long CONFREG_CLOCKS_PER_SEC = 50000000L;
|
unsigned long CONFREG_CLOCKS_PER_SEC = 50000000L;
|
||||||
unsigned long CORE_CLOCKS_PER_SEC = 33000000L;
|
unsigned long CORE_CLOCKS_PER_SEC = 33000000L;
|
||||||
|
|
||||||
#define FFT_BASE 0xbf400000
|
|
||||||
#define FFT_IN_RE_BASE (FFT_BASE + 0x1000)
|
|
||||||
#define FFT_IN_IM_BASE (FFT_BASE + 0x2000)
|
|
||||||
#define FFT_OUT_RE_BASE (FFT_BASE + 0x3000)
|
|
||||||
#define FFT_OUT_IM_BASE (FFT_BASE + 0x4000)
|
|
||||||
#define FFT_CSR_REG (FFT_BASE + 0xF000)
|
|
||||||
#define FFT_CTRL_START (1 << 4)
|
|
||||||
#define FFT_STAT_DONE (1 << 1)
|
|
||||||
#define FFT_STAT_BUSY (1 << 0)
|
|
||||||
#define FFT_POINT_NUM 1024
|
|
||||||
|
|
||||||
#define DMA_BASE 0xbf300000
|
|
||||||
#define DMA_CTRL (DMA_BASE + 0x0000)
|
|
||||||
#define DMA_LEN (DMA_BASE + 0x0004)
|
|
||||||
#define DMA_SRC_ADDR (DMA_BASE + 0x0008)
|
|
||||||
#define DMA_DST_ADDR (DMA_BASE + 0x000c)
|
|
||||||
#define DMA_STATUS (DMA_BASE + 0x0010)
|
|
||||||
|
|
||||||
const float PI = 3.14159265358979323846;
|
const float PI = 3.14159265358979323846;
|
||||||
|
|
||||||
// DMA 传输通用封装函数 (阻塞等待模式)
|
|
||||||
void dma_transfer(uint32_t phys_src, uint32_t phys_dst, uint32_t byte_len) {
|
|
||||||
RegWrite(DMA_SRC_ADDR, phys_src);
|
|
||||||
RegWrite(DMA_DST_ADDR, phys_dst);
|
|
||||||
RegWrite(DMA_LEN, byte_len);
|
|
||||||
|
|
||||||
// burst_len = 15(16拍), burst_size = 2(4字节), start = 1
|
|
||||||
uint32_t ctrl_val = (15 << 6) | (2 << 3) | 0x01;
|
|
||||||
RegWrite(DMA_CTRL, ctrl_val);
|
|
||||||
|
|
||||||
// 轮询等待 DMA 搬运完成
|
|
||||||
while ((RegRead(DMA_STATUS) & 0x01) == 0) {
|
|
||||||
// CPU 空转等待
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 软件FFT实现 (基2 DIT-FFT 算法)
|
// 软件FFT实现 (基2 DIT-FFT 算法)
|
||||||
void sw_fft(float re[], float im[], int n) {
|
void sw_fft(float re[], float im[], int n) {
|
||||||
int i, j, k, l;
|
int i, j, k, l;
|
||||||
@@ -152,18 +122,22 @@ int main(int argc, char** argv)
|
|||||||
uint32_t transfer_bytes = FFT_POINT_NUM * 4; // 1024个点 * 4字节
|
uint32_t transfer_bytes = FFT_POINT_NUM * 4; // 1024个点 * 4字节
|
||||||
|
|
||||||
// MA 将数据从内存搬运到 FFT 输入外设
|
// MA 将数据从内存搬运到 FFT 输入外设
|
||||||
dma_transfer(((uint32_t)hw_in_re_arr & 0x1FFFFFFF), phys_fft_in_re, transfer_bytes);
|
dma_start_transfer(0, ((uint32_t)hw_in_re_arr & 0x1FFFFFFF), phys_fft_in_re, transfer_bytes, 100);
|
||||||
dma_transfer(((uint32_t)hw_in_im_arr & 0x1FFFFFFF), phys_fft_in_im, transfer_bytes);
|
dma_start_transfer(1, ((uint32_t)hw_in_im_arr & 0x1FFFFFFF), phys_fft_in_im, transfer_bytes, 200);
|
||||||
|
dma_wait_polling(0);
|
||||||
|
dma_wait_polling(1);
|
||||||
|
|
||||||
|
|
||||||
// 启动 FFT 并等待计算完成
|
// 启动 FFT 并等待计算完成
|
||||||
RegWrite(FFT_CSR_REG, FFT_CTRL_START);
|
fft_start();
|
||||||
while ((RegRead(FFT_CSR_REG) & FFT_STAT_DONE) == 0) {
|
fft_wait();
|
||||||
// poll
|
|
||||||
}
|
|
||||||
|
|
||||||
// DMA 将结果从 FFT 输出外设搬回内存
|
// DMA 将结果从 FFT 输出外设搬回内存
|
||||||
dma_transfer(phys_fft_out_re, ((uint32_t)hw_out_re_arr & 0x1FFFFFFF), transfer_bytes);
|
dma_start_transfer(0, phys_fft_out_re, ((uint32_t)hw_out_re_arr & 0x1FFFFFFF), transfer_bytes, 10);
|
||||||
dma_transfer(phys_fft_out_im, ((uint32_t)hw_out_im_arr & 0x1FFFFFFF), transfer_bytes);
|
dma_start_transfer(1, phys_fft_out_im, ((uint32_t)hw_out_im_arr & 0x1FFFFFFF), transfer_bytes, 20);
|
||||||
|
dma_wait_polling(0);
|
||||||
|
dma_wait_polling(1);
|
||||||
|
|
||||||
|
|
||||||
tick_end = get_ns(); // 结束计时
|
tick_end = get_ns(); // 结束计时
|
||||||
hw_time = tick_end - tick_start;
|
hw_time = tick_end - tick_start;
|
||||||
|
|||||||
Reference in New Issue
Block a user