1728 lines
73 KiB
C
1728 lines
73 KiB
C
#include "system/includes.h"
|
||
#include "app_config.h"
|
||
#include "fftvec_math_drv.h"
|
||
#include "_kiss_fft_guts.h"
|
||
|
||
|
||
#if defined CONFIG_ASR_ALGORITHM || defined CONFIG_REVERB_MODE_ENABLE || defined CONFIG_AEC_ENC_ENABLE || defined CONFIG_DNS_ENC_ENABLE || defined CONFIG_M4A_DEC_ENABLE || defined CONFIG_NEW_M4A_DEC_ENABLE || defined CONFIG_AAC_DEC_ENABLE || defined CONFIG_WMA_DEC_ENABLE || defined CONFIG_SPECTRUM_FFT_EFFECT_ENABLE
|
||
|
||
static DEFINE_SPINLOCK(fft_lock);
|
||
|
||
#define FFT_REAL 1 //complex
|
||
#define IFFT_DIV2 (3-FFT_REAL)
|
||
#define FFT_ISR_IE 0
|
||
|
||
//软件fft算法
|
||
/* #define KISS_FFT */
|
||
|
||
#define SHR(a,shift) ((a) >> (shift))
|
||
|
||
#define PSHR(a,shift) ((a)>=0?(SHR((a)+(1<<(shift-1)),shift)):\
|
||
(SHR((a)+(1<<(shift-1))-1,shift)))
|
||
|
||
#if defined CONFIG_WMA_DEC_ENABLE
|
||
#define MAX_FFT_SUPPORT_POINT_NUM 2048
|
||
#else
|
||
#define MAX_FFT_SUPPORT_POINT_NUM 1024
|
||
#endif
|
||
|
||
#if defined CONFIG_CPU_WL82 && defined CONFIG_ASR_ALGORITHM
|
||
sec(.fft_data) static int datain[MAX_FFT_SUPPORT_POINT_NUM];
|
||
sec(.fft_data) static int datain_y[MAX_FFT_SUPPORT_POINT_NUM];
|
||
sec(.fft_data) static int dataout[MAX_FFT_SUPPORT_POINT_NUM + 2];
|
||
#else
|
||
#if defined CONFIG_VIDEO_ENABLE
|
||
sec(.fft_data) static int datain[MAX_FFT_SUPPORT_POINT_NUM + 2];
|
||
sec(.fft_data) static int *dataout = datain;
|
||
sec(.fft_data) static int datain_y[0];
|
||
#else
|
||
sec(.fft_data) static int datain[MAX_FFT_SUPPORT_POINT_NUM];
|
||
sec(.fft_data) static int dataout[MAX_FFT_SUPPORT_POINT_NUM + 2];
|
||
sec(.fft_data) static int datain_y[0];
|
||
#endif
|
||
#endif
|
||
|
||
typedef struct fft_config_dat {
|
||
unsigned long fft0_con;
|
||
unsigned long fft0_iadr;
|
||
unsigned long fft0_oadr;
|
||
unsigned long fft0_null;
|
||
} fft_config_struct;
|
||
|
||
sec(.fft_data) static fft_config_struct fft_config;
|
||
sec(.fft_data) static hwvec_ctx_t g_vector_core_set;
|
||
|
||
static const struct {
|
||
u32 block;
|
||
u32 config;
|
||
} complex_tab[] = {
|
||
{ 128, COMPLEX_FFT128_CONFIG },
|
||
{ 128, COMPLEX_IFFT128_CONFIG },
|
||
{ 256, COMPLEX_FFT256_CONFIG },
|
||
{ 256, COMPLEX_IFFT256_CONFIG },
|
||
{ 512, COMPLEX_FFT512_CONFIG },
|
||
{ 512, COMPLEX_IFFT512_CONFIG },
|
||
{ 1024, COMPLEX_FFT1024_CONFIG },
|
||
{ 1024, COMPLEX_IFFT1024_CONFIG},
|
||
{ 2048, COMPLEX_FFT2048_CONFIG },
|
||
{ 2048, COMPLEX_IFFT2048_CONFIG},
|
||
{ 10, COMPLEX_FFT10_CONFIG },
|
||
{ 10, COMPLEX_IFFT10_CONFIG },
|
||
{ 15, COMPLEX_FFT15_CONFIG },
|
||
{ 15, COMPLEX_IFFT15_CONFIG },
|
||
{ 20, COMPLEX_FFT20_CONFIG },
|
||
{ 20, COMPLEX_IFFT20_CONFIG },
|
||
{ 30, COMPLEX_FFT30_CONFIG },
|
||
{ 30, COMPLEX_IFFT30_CONFIG },
|
||
{ 32, COMPLEX_FFT32_CONFIG },
|
||
{ 32, COMPLEX_IFFT32_CONFIG },
|
||
{ 40, COMPLEX_FFT40_CONFIG },
|
||
{ 40, COMPLEX_IFFT40_CONFIG },
|
||
{ 60, COMPLEX_FFT60_CONFIG },
|
||
{ 60, COMPLEX_IFFT60_CONFIG },
|
||
{ 64, COMPLEX_FFT64_CONFIG },
|
||
{ 64, COMPLEX_IFFT64_CONFIG },
|
||
{ 80, COMPLEX_FFT80_CONFIG },
|
||
{ 80, COMPLEX_IFFT80_CONFIG },
|
||
{ 120, COMPLEX_FFT120_CONFIG },
|
||
{ 120, COMPLEX_IFFT120_CONFIG },
|
||
{ 160, COMPLEX_FFT160_CONFIG },
|
||
{ 160, COMPLEX_IFFT160_CONFIG },
|
||
{ 240, COMPLEX_FFT240_CONFIG },
|
||
{ 240, COMPLEX_IFFT240_CONFIG },
|
||
{ 320, COMPLEX_FFT320_CONFIG },
|
||
{ 320, COMPLEX_IFFT320_CONFIG },
|
||
{ 480, COMPLEX_FFT480_CONFIG },
|
||
{ 480, COMPLEX_IFFT480_CONFIG },
|
||
{ 960, COMPLEX_FFT960_CONFIG },
|
||
{ 960, COMPLEX_IFFT960_CONFIG },
|
||
};
|
||
|
||
static const struct {
|
||
u32 block;
|
||
u32 config;
|
||
} real_tab[] = {
|
||
{ 128, REAL_FFT128_CONFIG },
|
||
{ 128, REAL_IFFT128_CONFIG },
|
||
{ 256, REAL_FFT256_CONFIG },
|
||
{ 256, REAL_IFFT256_CONFIG },
|
||
{ 512, REAL_FFT512_CONFIG },
|
||
{ 512, REAL_IFFT512_CONFIG },
|
||
{ 1024, REAL_FFT1024_CONFIG },
|
||
{ 1024, REAL_IFFT1024_CONFIG},
|
||
{ 2048, REAL_FFT2048_CONFIG },
|
||
{ 2048, REAL_IFFT2048_CONFIG},
|
||
{ 20, REAL_FFT20_CONFIG },
|
||
{ 20, REAL_IFFT20_CONFIG },
|
||
{ 30, REAL_FFT30_CONFIG },
|
||
{ 30, REAL_IFFT30_CONFIG },
|
||
{ 40, REAL_FFT40_CONFIG },
|
||
{ 40, REAL_IFFT40_CONFIG },
|
||
{ 60, REAL_FFT60_CONFIG },
|
||
{ 60, REAL_IFFT60_CONFIG },
|
||
{ 64, REAL_FFT64_CONFIG },
|
||
{ 64, REAL_IFFT64_CONFIG },
|
||
{ 80, REAL_FFT80_CONFIG },
|
||
{ 80, REAL_IFFT80_CONFIG },
|
||
{ 120, REAL_FFT120_CONFIG },
|
||
{ 120, REAL_IFFT120_CONFIG },
|
||
{ 160, REAL_FFT160_CONFIG },
|
||
{ 160, REAL_IFFT160_CONFIG },
|
||
{ 240, REAL_FFT240_CONFIG },
|
||
{ 240, REAL_IFFT240_CONFIG },
|
||
{ 320, REAL_FFT320_CONFIG },
|
||
{ 320, REAL_IFFT320_CONFIG },
|
||
{ 480, REAL_FFT480_CONFIG },
|
||
{ 480, REAL_IFFT480_CONFIG },
|
||
{ 960, REAL_FFT960_CONFIG },
|
||
{ 960, REAL_IFFT960_CONFIG },
|
||
};
|
||
|
||
|
||
#ifdef KISS_FFT
|
||
|
||
//是否使用软硬混合fft
|
||
#define SOFT_FFT_ENABLE
|
||
|
||
typedef struct kiss_config {
|
||
kiss_fft_cfg forward;
|
||
kiss_fft_cfg backward;
|
||
int N;
|
||
float *fft_in;
|
||
float *fft_out;
|
||
} kiss_config_t;
|
||
|
||
static kiss_config_t *kiss_512;
|
||
static kiss_config_t *kiss_1024;
|
||
|
||
|
||
static u8 spin_is_lock()
|
||
{
|
||
return fft_lock.rwlock;
|
||
}
|
||
|
||
//input: only real
|
||
//output: interleave real and image, size is (N/2+1)*2
|
||
__attribute__((always_inline))
|
||
void kiss_cfg_fft(void *table, int *in, int *out)
|
||
{
|
||
kiss_config_t *t = (kiss_config_t *)table;
|
||
|
||
float scale = 1;// / t->N;
|
||
|
||
for (int i = 0; i < t->N; i++) {
|
||
t->fft_in[i * 2] = in[i] * scale;
|
||
t->fft_in[i * 2 + 1] = 0;
|
||
}
|
||
|
||
kiss_fft(t->forward, t->fft_in, t->fft_out);
|
||
|
||
for (int i = 0; i < t->N + 2; i++) {
|
||
out[i] = t->fft_out[i];
|
||
}
|
||
}
|
||
|
||
//output: only real
|
||
//input: interleave real and image, size is (N/2+1)*2
|
||
__attribute__((always_inline))
|
||
void kiss_cfg_ifft(void *table, int *in, int *out)
|
||
{
|
||
kiss_config_t *t = (kiss_config_t *)table;
|
||
|
||
float scale;
|
||
int i;
|
||
scale = 1.0f / t->N;
|
||
|
||
for (int i = 0; i < t->N / 2 + 1; i++) {
|
||
t->fft_in[i * 2] = in[i * 2];
|
||
t->fft_in[i * 2 + 1] = in[i * 2 + 1];
|
||
}
|
||
for (int i = t->N / 2 + 1; i < t->N; i++) {
|
||
t->fft_in[i * 2] = t->fft_in[(t->N - i) * 2];
|
||
t->fft_in[i * 2 + 1] = -t->fft_in[(t->N - i) * 2 + 1];
|
||
}
|
||
|
||
kiss_fft(t->backward, t->fft_in, t->fft_out);
|
||
|
||
for (int i = 0; i < t->N; i++) {
|
||
out[i] = t->fft_out[i * 2];
|
||
}
|
||
|
||
for (i = 0; i < t->N; i++) {
|
||
out[i] *= scale;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
void kiss_config_uninit()
|
||
{
|
||
if (kiss_512->fft_in) {
|
||
free(kiss_512->fft_in);
|
||
kiss_512->fft_in = NULL;
|
||
}
|
||
if (kiss_512->fft_out) {
|
||
free(kiss_512->fft_out);
|
||
kiss_512->fft_out = NULL;
|
||
}
|
||
kiss_fft_free(kiss_512->forward);
|
||
kiss_fft_free(kiss_512->backward);
|
||
free(kiss_512);
|
||
|
||
if (kiss_1024->fft_in) {
|
||
free(kiss_1024->fft_in);
|
||
kiss_1024->fft_in = NULL;
|
||
}
|
||
if (kiss_1024->fft_out) {
|
||
free(kiss_1024->fft_out);
|
||
kiss_1024->fft_out = NULL;
|
||
}
|
||
kiss_fft_free(kiss_1024->forward);
|
||
kiss_fft_free(kiss_1024->backward);
|
||
free(kiss_1024);
|
||
}
|
||
|
||
void kiss_config_init()
|
||
{
|
||
kiss_512 = (kiss_config_t *)calloc(1, sizeof(kiss_config_t));
|
||
if (!kiss_512) {
|
||
printf("%s, kiss_512 malloc fail\n\r", __func__);
|
||
return;
|
||
}
|
||
kiss_1024 = (kiss_config_t *)calloc(1, sizeof(kiss_config_t));
|
||
if (!kiss_1024) {
|
||
printf("%s, kiss_1024 malloc fail\n\r", __func__);
|
||
return;
|
||
}
|
||
|
||
kiss_512->N = 512;
|
||
kiss_512->forward = kiss_fft_alloc(kiss_512->N, 0, NULL, NULL);
|
||
kiss_512->backward = kiss_fft_alloc(kiss_512->N, 1, NULL, NULL);
|
||
|
||
kiss_512->fft_in = (float *)calloc(1, sizeof(float) * kiss_512->N * 2);
|
||
if (!kiss_512->fft_in) {
|
||
printf("%s, kiss_512 fft_in malloc fail\n\r", __func__);
|
||
return;
|
||
}
|
||
kiss_512->fft_out = (float *)calloc(1, sizeof(float) * kiss_512->N * 2);
|
||
if (!kiss_512->fft_out) {
|
||
printf("%s, kiss_512 fft_out malloc fail\n\r", __func__);
|
||
return;
|
||
}
|
||
|
||
kiss_1024->N = 1024;
|
||
kiss_1024->forward = kiss_fft_alloc(kiss_1024->N, 0, NULL, NULL);
|
||
kiss_1024->backward = kiss_fft_alloc(kiss_1024->N, 1, NULL, NULL);
|
||
|
||
kiss_1024->fft_in = (float *)calloc(1, sizeof(float) * kiss_1024->N * 2);
|
||
if (!kiss_1024->fft_in) {
|
||
printf("%s, kiss_1024 fft_in malloc fail\n\r", __func__);
|
||
return;
|
||
}
|
||
kiss_1024->fft_out = (float *)calloc(1, sizeof(float) * kiss_1024->N * 2);
|
||
if (!kiss_1024->fft_out) {
|
||
printf("%s, kiss_1024 fft_out malloc fail\n\r", __func__);
|
||
return;
|
||
}
|
||
|
||
}
|
||
|
||
late_initcall(kiss_config_init);
|
||
|
||
#endif
|
||
|
||
|
||
__attribute__((always_inline))
|
||
static int vc_hw_fft(int *coef_in, int blockbit, int *coef_out, int real, int same)
|
||
{
|
||
//init pi32v2 fft hardware
|
||
int blocklen = 1 << blockbit;
|
||
JL_FFT->CON = 0;
|
||
|
||
#ifdef CONFIG_CPU_WL82
|
||
int i;
|
||
|
||
if (real) {
|
||
for (i = 0; i < ARRAY_SIZE(real_tab); i += 2) {
|
||
if (blocklen == real_tab[i].block) {
|
||
fft_config.fft0_con = real_tab[i].config | (same << 0);
|
||
break;
|
||
}
|
||
}
|
||
if (i >= ARRAY_SIZE(real_tab)) {
|
||
return -1;
|
||
}
|
||
} else {
|
||
for (i = 0; i < ARRAY_SIZE(complex_tab); i += 2) {
|
||
if (blocklen == complex_tab[i].block) {
|
||
fft_config.fft0_con = complex_tab[i].config | (same << 0);
|
||
break;
|
||
}
|
||
}
|
||
if (i >= ARRAY_SIZE(complex_tab)) {
|
||
return -1;
|
||
}
|
||
}
|
||
#else
|
||
fft_config.fft0_con = (blocklen << 16) | ((blockbit - 1 - real) << 8) | ((blockbit - real - 2) << 4) | (0 << 2) | (real << 1) | (same << 0);
|
||
#endif
|
||
fft_config.fft0_iadr = (unsigned int)coef_in;
|
||
fft_config.fft0_oadr = (unsigned int)coef_out;
|
||
|
||
JL_FFT->CADR = (unsigned int)&fft_config;
|
||
JL_FFT->CON = (1 << 8) | (0 << 6) | (FFT_ISR_IE << 2) | (0 << 1) | (1 << 0);
|
||
while ((JL_FFT->CON & (1 << 7)) == 0);
|
||
JL_FFT->CON |= (1 << 6);
|
||
return 0;
|
||
}
|
||
|
||
__attribute__((always_inline))
|
||
static int vc_hw_ifft(int *coef_in, int blockbit, int *coef_out, int real, int same)
|
||
{
|
||
//init pi32v2 fft hardware
|
||
int blocklen = 1 << blockbit;
|
||
JL_FFT->CON = 0;
|
||
|
||
#ifdef CONFIG_CPU_WL82
|
||
int i;
|
||
|
||
if (real) {
|
||
for (i = 0; i < ARRAY_SIZE(real_tab); i += 2) {
|
||
if (blocklen == real_tab[i + 1].block) {
|
||
fft_config.fft0_con = real_tab[i + 1].config | (same << 0);
|
||
break;
|
||
}
|
||
}
|
||
if (i >= ARRAY_SIZE(real_tab)) {
|
||
return -1;
|
||
}
|
||
} else {
|
||
for (i = 0; i < ARRAY_SIZE(complex_tab); i += 2) {
|
||
if (blocklen == complex_tab[i + 1].block) {
|
||
fft_config.fft0_con = complex_tab[i + 1].config | (same << 0);
|
||
break;
|
||
}
|
||
}
|
||
if (i >= ARRAY_SIZE(complex_tab)) {
|
||
return -1;
|
||
}
|
||
}
|
||
#else
|
||
fft_config.fft0_con = (blocklen << 16) | ((blockbit - 1 - real) << 8) | ((3 - real) << 4) | (1 << 2) | (real << 1) | (same << 0);
|
||
#endif
|
||
fft_config.fft0_iadr = (unsigned int)coef_in;
|
||
fft_config.fft0_oadr = (unsigned int)coef_out;
|
||
|
||
JL_FFT->CADR = (unsigned int)&fft_config;
|
||
JL_FFT->CON = (1 << 8) | (0 << 6) | (FFT_ISR_IE << 2) | (0 << 1) | (1 << 0);
|
||
while ((JL_FFT->CON & (1 << 7)) == 0);
|
||
JL_FFT->CON |= (1 << 6);
|
||
return 0;
|
||
}
|
||
|
||
/* SEC_USED(.fft_text) */
|
||
__attribute__((always_inline))
|
||
void jl_fft_1024(short *in, int *out)
|
||
{
|
||
spin_lock(&fft_lock);
|
||
for (int i = 0; i < 1024; i++) {
|
||
datain[i] = in[i];
|
||
}
|
||
vc_hw_fft(datain, 10, dataout, 1, datain == dataout ? 1 : 0);
|
||
memcpy(out, dataout, sizeof(int) * 1026);
|
||
spin_unlock(&fft_lock);
|
||
}
|
||
|
||
/* SEC_USED(.fft_text) */
|
||
__attribute__((always_inline))
|
||
void jl_fft_1024_ex(int *in, int *out)
|
||
{
|
||
#ifdef SOFT_FFT_ENABLE
|
||
if (spin_is_lock()) {
|
||
kiss_cfg_fft(kiss_1024, in, out);
|
||
} else
|
||
#endif
|
||
{
|
||
spin_lock(&fft_lock);
|
||
memcpy(datain, in, sizeof(int) * 1024);
|
||
vc_hw_fft(datain, 10, dataout, 1, datain == dataout ? 1 : 0);
|
||
memcpy(out, dataout, sizeof(int) * 1026);
|
||
spin_unlock(&fft_lock);
|
||
}
|
||
}
|
||
|
||
/* SEC_USED(.fft_text) */
|
||
__attribute__((always_inline))
|
||
void jl_fft_512(int *in, int *out)
|
||
{
|
||
#ifdef SOFT_FFT_ENABLE
|
||
if (spin_is_lock()) {
|
||
kiss_cfg_fft(kiss_512, in, out);
|
||
} else
|
||
#endif
|
||
{
|
||
spin_lock(&fft_lock);
|
||
memcpy(datain, in, sizeof(int) * 512);
|
||
vc_hw_fft(datain, 9, dataout, 1, datain == dataout ? 1 : 0);
|
||
memcpy(out, dataout, sizeof(int) * 514);
|
||
spin_unlock(&fft_lock);
|
||
}
|
||
}
|
||
|
||
/* SEC_USED(.fft_text) */
|
||
__attribute__((always_inline))
|
||
int jl_ifft_1024(int *in, short *out)
|
||
{
|
||
int i;
|
||
int tData_tmp = 0, tData_max = 0, shift = 0;
|
||
spin_lock(&fft_lock);
|
||
memcpy(dataout, in, sizeof(int) * 1026);
|
||
vc_hw_ifft(dataout, 10, datain, 1, dataout == datain ? 1 : 0);
|
||
for (i = 0; i < 1024; i++) {
|
||
tData_tmp = datain[i] > 0 ? datain[i] : (-datain[i]);
|
||
|
||
if (tData_max < tData_tmp) {
|
||
tData_max = tData_tmp;
|
||
}
|
||
}
|
||
while (tData_max > 32767) {
|
||
tData_max >>= 1;
|
||
shift += 1;
|
||
}
|
||
for (i = 0; i < 1024; i += 4) {
|
||
out[i] = PSHR(datain[i], shift);
|
||
out[i + 1] = PSHR(datain[i + 1], shift);
|
||
out[i + 2] = PSHR(datain[i + 2], shift);
|
||
out[i + 3] = PSHR(datain[i + 3], shift);
|
||
}
|
||
spin_unlock(&fft_lock);
|
||
return shift;
|
||
}
|
||
|
||
/* SEC_USED(.fft_text) */
|
||
__attribute__((always_inline))
|
||
void jl_ifft_1024_ex(int *in, int *out)
|
||
{
|
||
#ifdef SOFT_FFT_ENABLE
|
||
if (spin_is_lock()) {
|
||
kiss_cfg_ifft(kiss_1024, in, out);
|
||
} else
|
||
#endif
|
||
{
|
||
spin_lock(&fft_lock);
|
||
memcpy(dataout, in, sizeof(int) * 1026);
|
||
vc_hw_ifft(dataout, 10, datain, 1, dataout == datain ? 1 : 0);
|
||
memcpy(out, datain, sizeof(int) * 1024);
|
||
spin_unlock(&fft_lock);
|
||
}
|
||
}
|
||
|
||
/* SEC_USED(.fft_text) */
|
||
__attribute__((always_inline))
|
||
void jl_ifft_512(int *in, int *out)
|
||
{
|
||
#ifdef SOFT_FFT_ENABLE
|
||
if (spin_is_lock()) {
|
||
kiss_cfg_ifft(kiss_512, in, out);
|
||
} else
|
||
#endif
|
||
{
|
||
spin_lock(&fft_lock);
|
||
memcpy(datain, in, sizeof(int) * 514);
|
||
vc_hw_ifft(datain, 9, dataout, 1, dataout == datain ? 1 : 0);
|
||
memcpy(out, dataout, sizeof(int) * 512);
|
||
spin_unlock(&fft_lock);
|
||
}
|
||
}
|
||
|
||
__attribute__((always_inline))
|
||
static u32 find_pow(u32 value)
|
||
{
|
||
u32 i = 0;
|
||
|
||
while (value) {
|
||
value >>= 1;
|
||
if (++i > 11) {
|
||
ASSERT(NULL, "pow <= 10");
|
||
}
|
||
}
|
||
|
||
return i - 1;
|
||
}
|
||
|
||
__attribute__((always_inline))
|
||
void jl_fft_N(int *in, int *out, int fft_N)
|
||
{
|
||
spin_lock(&fft_lock);
|
||
memcpy(datain, in, sizeof(int) * fft_N);
|
||
vc_hw_fft(datain, find_pow(fft_N), dataout, 1, dataout == datain ? 1 : 0);
|
||
memcpy(out, dataout, sizeof(int) * (fft_N + 2));
|
||
spin_unlock(&fft_lock);
|
||
}
|
||
|
||
__attribute__((always_inline))
|
||
void jl_ifft_N(int *in, int *out, int fft_N)
|
||
{
|
||
spin_lock(&fft_lock);
|
||
memcpy(dataout, in, sizeof(int) * (fft_N + 2));
|
||
vc_hw_ifft(dataout, find_pow(fft_N), datain, 1, dataout == datain ? 1 : 0);
|
||
memcpy(out, datain, sizeof(int) * fft_N);
|
||
spin_unlock(&fft_lock);
|
||
}
|
||
|
||
__attribute__((always_inline))
|
||
void jl_complex_fft_n(int *in, int *out, int bits)
|
||
{
|
||
int len = 1 << bits;
|
||
spin_lock(&fft_lock);
|
||
memcpy(datain, in, sizeof(int) * len);
|
||
vc_hw_fft(datain, bits - 1, dataout, 0, datain == dataout ? 1 : 0);
|
||
memcpy(out, dataout, sizeof(int) * len);
|
||
spin_unlock(&fft_lock);
|
||
}
|
||
|
||
__attribute__((always_inline))
|
||
void jl_complex_ifft_n(int *in, int *out, int bits)
|
||
{
|
||
int len = 1 << bits;
|
||
spin_lock(&fft_lock);
|
||
memcpy(datain, in, sizeof(int) * len);
|
||
vc_hw_ifft(datain, bits - 1, dataout, 0, datain == dataout ? 1 : 0);
|
||
memcpy(out, dataout, sizeof(int) * len);
|
||
spin_unlock(&fft_lock);
|
||
}
|
||
|
||
void hw_fft_run(int cfg, const int *coef_in, int *coef_out)
|
||
{
|
||
int len;
|
||
int *in = datain, *out = dataout;
|
||
|
||
if (!coef_in || !coef_out) {
|
||
return;
|
||
}
|
||
|
||
if (datain == dataout) {
|
||
cfg |= BIT(0);
|
||
} else {
|
||
cfg &= ~BIT(0);
|
||
}
|
||
|
||
if (cfg & BIT(1)) {
|
||
len = (cfg & 0xFFF0000) >> 16;
|
||
if (cfg & BIT(2)) {
|
||
len += 2;
|
||
in = dataout;
|
||
out = datain;
|
||
}
|
||
} else {
|
||
len = (cfg & 0xFFF0000) >> (16 - 1);
|
||
}
|
||
|
||
spin_lock(&fft_lock);
|
||
memcpy(in, coef_in, sizeof(int) * len);
|
||
|
||
JL_FFT->CON = 0;
|
||
fft_config.fft0_con = cfg;
|
||
fft_config.fft0_iadr = (unsigned int)in;
|
||
fft_config.fft0_oadr = (unsigned int)out;
|
||
JL_FFT->CADR = (unsigned int)&fft_config;
|
||
JL_FFT->CON = (1 << 8) | (0 << 6) | (FFT_ISR_IE << 2) | (0 << 1) | (1 << 0);
|
||
while ((JL_FFT->CON & (1 << 7)) == 0);
|
||
JL_FFT->CON |= (1 << 6);
|
||
|
||
if (cfg & BIT(1)) {
|
||
if (cfg & BIT(2)) {
|
||
len -= 2;
|
||
} else {
|
||
len += 2;
|
||
}
|
||
}
|
||
|
||
memcpy(coef_out, out, sizeof(int) * len);
|
||
spin_unlock(&fft_lock);
|
||
}
|
||
|
||
void hw_fft_wrap(fft_config_struct *ctx)
|
||
{
|
||
hw_fft_run(ctx->fft0_con, (const int *)ctx->fft0_iadr, (int *)ctx->fft0_oadr);
|
||
}
|
||
|
||
#if defined CONFIG_NEW_M4A_DEC_ENABLE
|
||
int hw_fft_core(int cfg, const int *coef_in, int *coef_out)
|
||
{
|
||
hw_fft_run(cfg, coef_in, coef_out);
|
||
}
|
||
#endif
|
||
|
||
unsigned int Get_FFT_Base(void)
|
||
{
|
||
return JL_FFT_BASE;
|
||
}
|
||
|
||
__attribute__((always_inline)) inline
|
||
void fast_i2f(const int *in, float *out, int N, float scale)
|
||
{
|
||
int tmp32_1;
|
||
asm volatile(
|
||
" 1: \n\t"
|
||
" rep %1 { \n\t"
|
||
" %0 = [%2++=4] \n\t"
|
||
" %0 = itof(%0) \n\t"
|
||
" %0 = %0 * %4 (f) \n\t"
|
||
" [%3++=4] = %0 \n\t"
|
||
" } \n\t"
|
||
" if(%1>0) goto 1b \n\t"
|
||
: "=&r"(tmp32_1),
|
||
"=&r"(N),
|
||
"=&r"(in),
|
||
"=&r"(out),
|
||
"=&r"(scale)
|
||
: "0"(tmp32_1),
|
||
"1"(N),
|
||
"2"(in),
|
||
"3"(out),
|
||
"4"(scale)
|
||
:);
|
||
}
|
||
|
||
__attribute__((always_inline)) inline
|
||
void fast_f2i(const float *in, int *out, int N, float scale)
|
||
{
|
||
int tmp32_1;
|
||
asm volatile(
|
||
" 1: \n\t"
|
||
" rep %1 { \n\t"
|
||
" %0 = [%2++=4] \n\t"
|
||
" %0 = %0 * %4 (f) \n\t"
|
||
" %0 = ftoi(%0)(even) \n\t"
|
||
" [%3++=4] = %0 \n\t"
|
||
" } \n\t"
|
||
" if(%1>0) goto 1b \n\t"
|
||
: "=&r"(tmp32_1),
|
||
"=&r"(N),
|
||
"=&r"(in),
|
||
"=&r"(out),
|
||
"=&r"(scale)
|
||
: "0"(tmp32_1),
|
||
"1"(N),
|
||
"2"(in),
|
||
"3"(out),
|
||
"4"(scale)
|
||
:);
|
||
}
|
||
|
||
//hwfft_ctx_t结构体和FFT输入输出的数据地址一定要放在内部ram
|
||
|
||
__attribute__((always_inline)) inline
|
||
void hwfft_exec_batch(hwfft_ctx_t *ctx, int nbatch)
|
||
{
|
||
spin_lock(&fft_lock);
|
||
JL_FFT->CADR = (unsigned long)(ctx);
|
||
//CLR //FFT //ie //en
|
||
JL_FFT->CON = (nbatch << 8) | (1 << 6) | (0 << 3) | (FFT_ISR_IE << 2) | (1 << 0);
|
||
while ((JL_FFT->CON & (1 << 7)) == 0);
|
||
JL_FFT->CON |= (1 << 6);
|
||
spin_unlock(&fft_lock);
|
||
};
|
||
|
||
__attribute__((always_inline)) inline
|
||
void hwfft_exec_once(hwfft_ctx_t *ctx)
|
||
{
|
||
spin_lock(&fft_lock);
|
||
JL_FFT->CADR = (unsigned long)(ctx);
|
||
//CLR //FFT //ie //en
|
||
JL_FFT->CON = (1 << 8) | (1 << 6) | (0 << 3) | (FFT_ISR_IE << 2) | (1 << 0);
|
||
while ((JL_FFT->CON & (1 << 7)) == 0);
|
||
JL_FFT->CON |= (1 << 6);
|
||
spin_unlock(&fft_lock);
|
||
};
|
||
|
||
__attribute__((always_inline)) inline
|
||
int hwfft_get_nfft(unsigned long fft_config)
|
||
{
|
||
int nfft = (fft_config >> 16) & 0xfff;
|
||
return nfft;
|
||
};
|
||
|
||
//0---forward 1---backward
|
||
__attribute__((always_inline)) inline
|
||
int hwfft_get_backward(unsigned long fft_config)
|
||
{
|
||
return ((fft_config & (1 << 2)) != 0);
|
||
};
|
||
|
||
//0---complex 1---real
|
||
__attribute__((always_inline)) inline
|
||
int hwfft_get_real(unsigned long fft_config)
|
||
{
|
||
return ((fft_config & (1 << 1)) != 0);
|
||
};
|
||
|
||
__attribute__((always_inline)) inline
|
||
int hwfft_check_fft_config(unsigned long fft_config, int nfft, int backward, int real)
|
||
{
|
||
if (hwfft_get_nfft(fft_config) != nfft) {
|
||
printf("fft nfft mismatch!\n");
|
||
return -1;
|
||
}
|
||
|
||
if (hwfft_get_backward(fft_config) != backward) {
|
||
printf("fft backward direction mismatch!\n");
|
||
return -1;
|
||
}
|
||
|
||
if (hwfft_get_real(fft_config) != real) {
|
||
printf("fft real mode mismatch!\n");
|
||
return -1;
|
||
}
|
||
return 0;
|
||
};
|
||
|
||
__attribute__((always_inline)) inline
|
||
void hwfft_fill_fft_ctx(hwfft_ctx_t *ctx, unsigned long fft_config, long *iadr, long *oadr)
|
||
{
|
||
unsigned long config;
|
||
|
||
if (iadr == oadr) {
|
||
config = fft_config | FFT_SAME_ADR;
|
||
} else {
|
||
config = fft_config & (~FFT_SAME_ADR);
|
||
}
|
||
ctx->fft_con = config;
|
||
ctx->fft_iadr = (unsigned long)iadr;
|
||
ctx->fft_oadr = (unsigned long)oadr;
|
||
ctx->fft_null = 0;
|
||
// printf("config1:%d %x\n",config,ctx->fft_iadr);
|
||
};
|
||
|
||
__attribute__((always_inline)) inline
|
||
void hwfft_ifft_scale(long *iadr, int nfft)
|
||
{
|
||
int scale;
|
||
int q;
|
||
long config = VECX_S32 | VECY_S32 | VECZ_S32;
|
||
// printf("nfft:%d\n",nfft);
|
||
|
||
if (nfft % 15 == 0) {
|
||
scale = 1118481;
|
||
q = 21;
|
||
vector_real_mul_const(iadr, iadr, nfft, q, scale, config);
|
||
} else if (nfft % 10 == 0) {
|
||
scale = 1677722;//1864135;
|
||
q = 21;
|
||
vector_real_mul_const(iadr, iadr, nfft, q, scale, config);
|
||
}
|
||
}
|
||
|
||
__attribute__((always_inline)) inline
|
||
void hwfft_fft_i32(hwfft_ctx_t *ctx)
|
||
{
|
||
hwfft_exec_once(ctx);
|
||
};
|
||
|
||
__attribute__((always_inline)) inline
|
||
void hwfft_ifft_i32(hwfft_ctx_t *ctx)
|
||
{
|
||
int real = hwfft_get_real(ctx->fft_con);
|
||
int nfft = hwfft_get_nfft(ctx->fft_con);
|
||
hwfft_exec_once(ctx);
|
||
|
||
hwfft_ifft_scale((long *)ctx->fft_oadr, nfft * (2 - real));
|
||
};
|
||
|
||
__attribute__((always_inline)) inline
|
||
void hwfft_fft_f32(hwfft_ctx_t *ctx, float scale)
|
||
{
|
||
int nfft = hwfft_get_nfft(ctx->fft_con);
|
||
int real = hwfft_get_real(ctx->fft_con);
|
||
fast_f2i((float *)ctx->fft_iadr, (int *)ctx->fft_iadr, nfft * (2 - real), scale);
|
||
hwfft_fft_i32(ctx);
|
||
fast_i2f((int *)ctx->fft_oadr, (float *)ctx->fft_oadr, nfft * (2 - real) + 2 * real, 1.0f / scale); // com 0 real 1
|
||
};
|
||
|
||
__attribute__((always_inline)) inline
|
||
void hwfft_ifft_f32(hwfft_ctx_t *ctx, float scale)
|
||
{
|
||
int nfft = hwfft_get_nfft(ctx->fft_con);
|
||
int real = hwfft_get_real(ctx->fft_con);
|
||
|
||
fast_f2i((float *)ctx->fft_iadr, (int *)ctx->fft_iadr, nfft * (2 - real) + 2 * real, scale);
|
||
|
||
hwfft_ifft_i32(ctx);
|
||
|
||
fast_i2f((int *)ctx->fft_oadr, (float *)ctx->fft_oadr, nfft * (2 - real), 1.0f / scale);
|
||
};
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
//VECTOR
|
||
__attribute__((always_inline)) inline
|
||
void hwvec_exec(
|
||
void *xptr,
|
||
void *yptr,
|
||
void *zptr,
|
||
short x_inc,
|
||
short y_inc,
|
||
short z_inc,
|
||
short nlen,
|
||
short nloop,
|
||
char q,
|
||
long config,
|
||
long const_dat
|
||
)
|
||
{
|
||
//硬件锁上锁
|
||
spin_lock(&fft_lock);
|
||
|
||
char vec_cpy_real = 0;
|
||
char vec_zptr_cpy_dot = 0;
|
||
|
||
//获取段内数组的地址, 硬件运算数据都需在段内进行
|
||
void *_xptr = &datain[0];
|
||
void *_yptr = &datain_y[0];
|
||
void *_zptr = &dataout[0];
|
||
|
||
//区分复制长度(nlen为数据个数)是实数还是复数, 复数需乘2
|
||
if (config & VEC_CPY_REAL_OR_VEC) {
|
||
vec_cpy_real = 1;
|
||
config &= ~VEC_CPY_REAL_OR_VEC;
|
||
#ifdef CONFIG_CPU_WL82
|
||
if (xptr < (void *)__NONCPU_ADDR__) {
|
||
_xptr = xptr;
|
||
} else
|
||
#endif
|
||
{
|
||
memcpy(_xptr, xptr, nlen * 4);
|
||
}
|
||
//是否需要复制输入YPTR
|
||
if (config & VEC_YPTR_NOCPY) {
|
||
config &= ~VEC_YPTR_NOCPY;
|
||
} else {
|
||
#ifdef CONFIG_CPU_WL82
|
||
if (yptr < (void *)__NONCPU_ADDR__) {
|
||
_yptr = yptr;
|
||
} else
|
||
#endif
|
||
{
|
||
memcpy(_yptr, yptr, nlen * 4);
|
||
}
|
||
}
|
||
} else {
|
||
#ifdef CONFIG_CPU_WL82
|
||
if (xptr < (void *)__NONCPU_ADDR__) {
|
||
_xptr = xptr;
|
||
} else
|
||
#endif
|
||
{
|
||
memcpy(_xptr, xptr, nlen * 4 * 2);
|
||
}
|
||
//是否需要复制输入YPTR
|
||
if (config & VEC_YPTR_NOCPY) {
|
||
config &= ~VEC_YPTR_NOCPY;
|
||
} else {
|
||
#ifdef CONFIG_CPU_WL82
|
||
if (yptr < (void *)__NONCPU_ADDR__) {
|
||
_yptr = yptr;
|
||
} else
|
||
#endif
|
||
{
|
||
memcpy(_yptr, yptr, nlen * 4 * 2);
|
||
}
|
||
}
|
||
}
|
||
|
||
//是否需要输入zptr数据
|
||
if (config & VEC_ZPTR_CPY) {
|
||
config &= ~VEC_ZPTR_CPY;
|
||
if (vec_cpy_real) {
|
||
#ifdef CONFIG_CPU_WL82
|
||
if (zptr < (void *)__NONCPU_ADDR__) {
|
||
_zptr = zptr;
|
||
} else
|
||
#endif
|
||
{
|
||
memcpy(_zptr, zptr, nlen * 4);
|
||
}
|
||
} else {
|
||
#ifdef CONFIG_CPU_WL82
|
||
if (zptr < (void *)__NONCPU_ADDR__) {
|
||
_zptr = zptr;
|
||
} else
|
||
#endif
|
||
{
|
||
memcpy(_zptr, zptr, nlen * 4 * 2);
|
||
}
|
||
}
|
||
} else if (zptr == xptr) {
|
||
_zptr = _xptr;
|
||
} else if (zptr == yptr) {
|
||
_zptr = _yptr;
|
||
}
|
||
|
||
//区分ZPTR输出结果复制长度是一个点还是向量
|
||
if (config & VEC_ZPTR_CPY_DOT) {
|
||
vec_zptr_cpy_dot = 1;
|
||
config &= ~VEC_ZPTR_CPY_DOT;
|
||
}
|
||
|
||
//VECTOR寄存器的配置
|
||
g_vector_core_set.vector_con = config;
|
||
g_vector_core_set.vector_config0 = (q << 24) | (nloop << 12) | (nlen);
|
||
g_vector_core_set.vector_config1 = (z_inc << 20) | (y_inc << 10) | x_inc;
|
||
//printf("nlen0:%d,nloop:%d,q:%d,config:%d,%d\n",nlen,nloop,q,config,const_dat);
|
||
|
||
g_vector_core_set.vector_xadr = (unsigned long)_xptr;
|
||
g_vector_core_set.vector_yadr = (unsigned long)_yptr;
|
||
g_vector_core_set.vector_zadr = (unsigned long)_zptr;
|
||
|
||
JL_FFT->CONST = const_dat;
|
||
|
||
JL_FFT->CADR = (unsigned long)(&g_vector_core_set);
|
||
/*printf("JL_FFT->CONST:%x\n",&g_vector_core_set);
|
||
printf("JL_FFT->vector_xadr:%x\n",g_vector_core_set.vector_xadr);
|
||
printf("JL_FFT->vector_yadr:%x\n",g_vector_core_set.vector_yadr);
|
||
printf("JL_FFT->vector_zadr:%x\n",g_vector_core_set.vector_zadr);
|
||
printf("JL_FFT->vector_config0:%x\n",g_vector_core_set.vector_config0);
|
||
printf("JL_FFT->vector_config1:%x\n",g_vector_core_set.vector_config1);*/
|
||
|
||
//开始运算
|
||
//nu | clr | vector | ie | en
|
||
JL_FFT->CON = (1 << 8) | (1 << 6) | (1 << 3) | (FFT_ISR_IE << 2) | (1 << 0);
|
||
|
||
//等待运算完成中断并清中断
|
||
while ((JL_FFT->CON & (1 << 7)) == 0);
|
||
JL_FFT->CON |= (1 << 6);
|
||
|
||
//获取输出数据
|
||
if (vec_zptr_cpy_dot) {
|
||
*(int *)zptr = *(int *)_zptr;
|
||
} else {
|
||
memcpy(zptr, _zptr, vec_cpy_real ? nlen * 4 : nlen * 4 * 2);
|
||
}
|
||
|
||
//硬件锁解锁
|
||
spin_unlock(&fft_lock);
|
||
}
|
||
|
||
|
||
|
||
//=========================================================================
|
||
// vector_complex_add
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[3:2] : y_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 2: s32 1: s16 0:s8
|
||
// y_dw >= z_dw > x_dw
|
||
//
|
||
// x.real[0] = x[0], x.imge[0] = x[1]
|
||
// y.real[0] = y[0], y.imge[0] = y[1]
|
||
// *zptr, *yptr, *xptr: s32/s16/s8
|
||
// z[n] = saturated( y[n] + x[n] ) // 0 <= n < len*2
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_complex_add(void *zptr, void *yptr, void *xptr, short len, long config)
|
||
{
|
||
config = config;
|
||
hwvec_exec(xptr, yptr, zptr, 0, 0, 0, (len << 1), 1, 0, config, 0);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_complex_sub
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[3:2] : y_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 2: s32 1: s16 0:s8
|
||
// y_dw >= z_dw > x_dw
|
||
//
|
||
// x.real[0] = x[0], x.imge[0] = x[1]
|
||
// y.real[0] = y[0], y.imge[0] = y[1]
|
||
// *zptr, *yptr, *xptr: s32/s16/s8
|
||
// z[n] = saturated( y[n] - x[n] ) // 0 <= n < len*2
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_complex_sub(void *zptr, void *yptr, void *xptr, short len, long config)
|
||
{
|
||
config = config | VEC_SUB;
|
||
hwvec_exec(xptr, yptr, zptr, 0, 0, 0, (len << 1), 1, 0, config, 0);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_complex_mul
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[3:2] : y_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 2: s32 1: s16 0:s8
|
||
// y_dw >= z_dw > x_dw
|
||
// -32 < Q < 31
|
||
// x.real[0] = x[0], x.imge[0] = x[1]
|
||
// y.real[0] = y[0], y.imge[0] = y[1]
|
||
// z.real[0] = z[0], z.imge[0] = z[1]
|
||
// *zptr, *yptr, *xptr: s32/s16/s8
|
||
// z[n] = saturated(y[n]. * x[n]. / 2^q) // 0 <= n < len
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_complex_mul(void *zptr, void *yptr, void *xptr, short len, char q, long config)
|
||
{
|
||
config = config | VEC_CPX_MUL_MODE;
|
||
hwvec_exec(xptr, yptr, zptr, 0, 0, 0, (len << 0), 1, q, config, 0);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_complex_mac32
|
||
// dw bit[1:0] : x_dw 2: s32
|
||
// dw bit[3:2] : y_dw 2: s32
|
||
// dw bit[5:6] : z_dw 2: s32
|
||
// y_dw == z_dw == x_dw == 2
|
||
// -32 < Q < 31
|
||
// x.real[0] = x[0], x.imge[0] = x[1]
|
||
// y.real[0] = y[0], y.imge[0] = y[1]
|
||
// z.real[0] = z[0], z.imge[0] = z[1]
|
||
// *zptr, *yptr, *xptr: s32
|
||
// z[n] = saturated(z. + (y[n]. * x[n]. / 2^q)) // 0 <= n < len*2
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_complex_mac32(void *zptr, void *yptr, void *xptr, short len, char q, long config)
|
||
{
|
||
//config = VEC_MAC32 | VECZ_S32 | VECY_S32 | VECX_S32 | VEC_CPX_MUL_MODE;
|
||
config = config | VEC_MAC32 | VECZ_S32 | VECY_S32 | VECX_S32 | VEC_CPX_MUL_MODE | VEC_ZPTR_CPY;
|
||
hwvec_exec(xptr, yptr, zptr, 0, 0, 0, (len << 0), 1, q, config, 0);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_complex_msc32
|
||
// dw bit[1:0] : x_dw 2: s32
|
||
// dw bit[3:2] : y_dw 2: s32
|
||
// dw bit[5:6] : z_dw 2: s32
|
||
// y_dw == z_dw == x_dw == 2
|
||
// -32 < Q < 31
|
||
// x.real[0] = x[0], x.imge[0] = x[1]
|
||
// y.real[0] = y[0], y.imge[0] = y[1]
|
||
// z.real[0] = z[0], z.imge[0] = z[1]
|
||
// *zptr, *yptr, *xptr: s32
|
||
// z[n] = saturated(z[n]. - (y[n]. * x[n]. / 2^q)) // 0 <= n < len*2
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_complex_msc32(void *zptr, void *yptr, void *xptr, short len, char q, long config)
|
||
{
|
||
config = config | VEC_MAC32 | VECZ_S32 | VECY_S32 | VECX_S32 | VEC_SUB | VEC_CPX_MUL_MODE;
|
||
hwvec_exec(xptr, yptr, zptr, 0, 0, 0, (len << 1), 1, q, config, 0);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_complex_dot_product
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[3:2] : y_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 2: s32 1: s16 0:s8
|
||
// y_dw >= z_dw > x_dw
|
||
// -32 < Q < 31
|
||
// x.real[0] = x[0], x.imge[0] = x[1]
|
||
// y.real[0] = y[0], y.imge[0] = y[1]
|
||
// z.real[0] = z[0], z.imge[0] = z[1]
|
||
// *zptr, *yptr, *xptr: s32/s16/s8
|
||
// z[n] = saturated(sum(y[n]. * x[n]. / 2^q)) // 0 <= n < len*2
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_complex_dot_product(void *zptr, void *yptr, void *xptr, short len, char q, long config)
|
||
{
|
||
config = config | VEC_ACC | VEC_CPX_MUL_MODE;
|
||
hwvec_exec(xptr, yptr, zptr, 0, 0, 0, (len << 1), 1, q, config, 0);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_complex_qdt
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[3:2] : y_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 2: s32 1: s16 0:s8
|
||
// y_dw >= z_dw > x_dw
|
||
// -32 < Q < 31
|
||
// x.real[0] = x[0], x.imge[0] = x[1]
|
||
// z.real[0] = z[0], z.imge[0] = z[1]
|
||
// *zptr, *yptr, *xptr: s32/s16/s8
|
||
// z[n] = saturated((x[n].real^2 + x[n].imag^2) / 2^q) // 0 <= n < len/2
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_complex_qdt(void *zptr, void *xptr, short len, char q, long config)
|
||
{
|
||
config = config | VEC_CPX_QDT | VEC_QDT | VEC_QDT_MODE | VEC_YPTR_NOCPY;
|
||
hwvec_exec(xptr, 0, zptr, 0, 0, 0, (len << 1), 1, q, config, 0);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_complex_qdtsum
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 3: s64 2: s32 1: s16 0:s8
|
||
// -32 < Q < 32
|
||
// *zptr, *yptr, *xptr: s32/s16/s8
|
||
// z[n] = (x[0].real^2 + x[0].image^2 + ... + x[n].real^2+ x[n].image^2) / 2^q) // 0 <= n < len
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_complex_qdtsum(void *zptr, void *xptr, short len, char q, long config)
|
||
{
|
||
config = config | VEC_QDT | VEC_ACC | VEC_QDT_MODE;
|
||
hwvec_exec(xptr, 0, zptr, 0, 0, 0, (len << 1), 1, q, config, 0);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_real_add
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[3:2] : y_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 2: s32 1: s16 0:s8
|
||
// y_dw >= z_dw > x_dw
|
||
//
|
||
// *zptr, *yptr, *xptr: s32/s16/s8
|
||
// z[n] = saturated( y[n] + x[n] ) // 0 <= n < len
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_real_add(void *zptr, void *yptr, void *xptr, short len, long config)
|
||
{
|
||
config = config | VEC_CPY_REAL_OR_VEC;
|
||
hwvec_exec(xptr, yptr, zptr, 0, 0, 0, len, 1, 0, config, 0);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_real_add_dot_product
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[3:2] : y_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 2: s32 1: s16 0:s8
|
||
// y_dw >= z_dw > x_dw
|
||
//
|
||
// *zptr, *yptr, *xptr: s32/s16/s8
|
||
// z = sum( y[n] + x[n] ) // 0 <= n < len
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_real_add_dot_product(void *zptr, void *yptr, void *xptr, short len, long config)
|
||
{
|
||
config = config | VEC_CPY_REAL_OR_VEC | VEC_ZPTR_CPY_DOT;
|
||
hwvec_exec(xptr, yptr, zptr, 0, 0, 0, len, 1, 0, config, 0);
|
||
}
|
||
//=========================================================================
|
||
// vector_real_sub
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[3:2] : y_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 2: s32 1: s16 0:s8
|
||
// y_dw >= z_dw > x_dw
|
||
//
|
||
// *zptr, *yptr, *xptr: s32/s16/s8
|
||
// z[n] = saturated( y[n] - x[n] ) // 0 <= n < len
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_real_sub(void *zptr, void *yptr, void *xptr, short len, long config)
|
||
{
|
||
config = config | VEC_SUB | VEC_CPY_REAL_OR_VEC;
|
||
hwvec_exec(xptr, yptr, zptr, 0, 0, 0, len, 1, 0, config, 0);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_real_mul
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[3:2] : y_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 2: s32 1: s16 0:s8
|
||
// y_dw >= z_dw > x_dw
|
||
// -32 < Q < 32
|
||
// *zptr, *yptr, *xptr: s32/s16/s8
|
||
// z[n] = saturated(y[n] * x[n] / 2^q) // 0 <= n < len
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_real_mul(void *zptr, void *yptr, void *xptr, short len, char q, long config)
|
||
{
|
||
config = config | VEC_REAL_MUL_MODE | VEC_CPY_REAL_OR_VEC;
|
||
hwvec_exec(xptr, yptr, zptr, 0, 0, 0, len, 1, q, config, 0);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_real_mac
|
||
// dw bit[1:0] : x_dw 2: s32
|
||
// dw bit[5:6] : z_dw 2: s32
|
||
// -32 < Q < 32
|
||
// *zptr, *yptr, *xptr: s32/s16/s8
|
||
// z[n] = (z + y*x / 2^q) // 0 <= n < len
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_real_mac32(void *zptr, void *yptr, void *xptr, short len, char q, long config)
|
||
{
|
||
config = config | VEC_MAC32 | VECZ_S32 | VECY_S32 | VECX_S32 | VEC_REAL_MUL_MODE | VEC_CPY_REAL_OR_VEC;
|
||
hwvec_exec(xptr, yptr, zptr, 0, 0, 0, len, 1, q, config, 0);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_real_msc
|
||
// dw bit[1:0] : x_dw 2: s32
|
||
// dw bit[5:6] : z_dw 2: s32
|
||
// -32 < Q < 32
|
||
// *zptr, *yptr, *xptr: s32/s16/s8
|
||
// z[n] = (z - y*x / 2^q) // 0 <= n < len
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_real_msc32(void *zptr, void *yptr, void *xptr, short len, char q, long config)
|
||
{
|
||
config = config | VEC_MAC32 | VECZ_S32 | VECY_S32 | VECX_S32 | VEC_SUB | VEC_REAL_MUL_MODE | VEC_CPY_REAL_OR_VEC;
|
||
hwvec_exec(xptr, yptr, zptr, 0, 0, 0, len, 1, q, config, 0);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_real_dot_product
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[3:2] : y_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 2: s32 1: s16 0:s8
|
||
// y_dw >= z_dw > x_dw
|
||
// -32 < Q < 32
|
||
// *zptr, *yptr, *xptr: s32/s16/s8
|
||
// z[n] = sum(y[n] * x[n] / 2^q) // 0 <= n < len
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_real_dot_product(void *zptr, void *yptr, void *xptr, short len, char q, long config)
|
||
{
|
||
config = config | VEC_ACC | VEC_REAL_MUL_MODE | VEC_CPY_REAL_OR_VEC | VEC_ZPTR_CPY_DOT;
|
||
hwvec_exec(xptr, yptr, zptr, 0, 0, 0, len, 1, q, config, 0);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_real_sum
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 2: s32 1: s16 0:s8
|
||
// z_dw >= x_dw
|
||
// -32 < Q < 32
|
||
// *zptr, *xptr: s32/s16/s8
|
||
// z[n] = sum(x[n]) / 2^q // 0 <= n < len
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_real_sum(void *zptr, void *xptr, short len, char q, long config)
|
||
{
|
||
config = config | VEC_ACC | VEC_QDT_MODE | VEC_CPY_REAL_OR_VEC | VEC_YPTR_NOCPY;
|
||
hwvec_exec(xptr, 0, zptr, 0, 0, 0, len, 1, q, config, 0);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_real_sum_dot_product
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 2: s32 1: s16 0:s8
|
||
// z_dw >= x_dw
|
||
// -32 < Q < 32
|
||
// *zptr, *xptr: s32/s16/s8
|
||
// z = sum(x[n]) / 2^q // 0 <= n < len
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_real_sum_dot_product(void *zptr, void *xptr, short len, char q, long config)
|
||
{
|
||
config = config | VEC_ACC | VEC_QDT_MODE | VEC_CPY_REAL_OR_VEC | VEC_YPTR_NOCPY | VEC_ZPTR_CPY_DOT;
|
||
hwvec_exec(xptr, 0, zptr, 0, 0, 0, len, 1, q, config, 0);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_real_qdt
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 2: s32 1: s16 0:s8
|
||
// z_dw >= x_dw
|
||
// -32 < Q < 32
|
||
// *zptr, *xptr: s32/s16/s8
|
||
// z[n] = x[n]^2 / 2^q // 0 <= n < len
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_real_qdt(void *zptr, void *xptr, short len, char q, long config)
|
||
{
|
||
config = config | VEC_QDT | VEC_QDT_MODE | VEC_CPY_REAL_OR_VEC;
|
||
hwvec_exec(xptr, 0, zptr, 0, 0, 0, len, 1, q, config, 0);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_real_qdtsum
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 2: s32 1: s16
|
||
// -32 < Q < 32
|
||
// *zptr, *yptr, *xptr: s32/s16/s8
|
||
// z[n] = sum(x[n]^2) / 2^q // 0 <= n < len
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_real_qdtsum(void *zptr, void *xptr, short len, char q, long config)
|
||
{
|
||
config = config | VEC_QDT | VEC_ACC | VEC_QDT_MODE | VEC_CPY_REAL_OR_VEC;
|
||
hwvec_exec(xptr, 0, zptr, 0, 0, 0, len, 1, q, config, 0);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_real_mac_const
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 2: s32
|
||
// -32 < Q < 32
|
||
// *zptr, *yptr, *xptr: s32/s16/s8
|
||
// z[n] = x[n] + y[n] * const_dat / 2^q // 0 <= n < len
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_real_mac_const(void *zptr, void *yptr, void *xptr, short len, char q, long const_dat, long config)
|
||
{
|
||
config = config | VEC_CONST_MUL | VEC_REAL_MUL_MODE | VEC_CPY_REAL_OR_VEC;
|
||
hwvec_exec(xptr, yptr, zptr, 0, 0, 0, len, 1, q, config, const_dat);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_real_msc_const
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 2: s32
|
||
// -32 < Q < 32
|
||
// *zptr, *yptr, *xptr: s32/s16/s8
|
||
// z[n] = x[n] - y[n] * const_dat / 2^q // 0 <= n < len
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_real_msc_const(void *zptr, void *yptr, void *xptr, short len, char q, long const_dat, long config)
|
||
{
|
||
config = config | VEC_CONST_MUL | VEC_SUB | VEC_REAL_MUL_MODE | VEC_CPY_REAL_OR_VEC;
|
||
hwvec_exec(xptr, yptr, zptr, 0, 0, 0, len, 1, q, config, const_dat);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_real_mul_const
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 2: s32
|
||
// -32 < Q < 32
|
||
// *zptr, *yptr, *xptr: s32/s16/s8
|
||
// z[n] = (x[n] * const_dat/ 2^q) // 0 <= n < len
|
||
// z, y, x buf size must be(32bit x n), z_buf can be y_buf or x_buf
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_real_mul_const(void *zptr, void *xptr, short len, char q, long const_dat, long config)
|
||
{
|
||
config = config | VEC_CONST_MUL | VEC_QDT | VEC_QDT_MODE | VEC_YPTR_NOCPY | VEC_CPY_REAL_OR_VEC;
|
||
hwvec_exec(xptr, 0, zptr, 0, 0, 0, len, 1, q, config, const_dat);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_real_max
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 2: s32
|
||
// -32 < Q < 32
|
||
// z = x*cosnt /2^q
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_real_max(void *zptr, void *xptr, short len, char q, long config, long const_dat)
|
||
{
|
||
config = config | VEC_MAX | VEC_CONST_MUL | VEC_QDT | VEC_QDT_MODE | VEC_YPTR_NOCPY | VEC_CPY_REAL_OR_VEC;
|
||
hwvec_exec(xptr, 0, zptr, 0, 0, 0, len, 1, q, config, const_dat);
|
||
}
|
||
|
||
//=========================================================================
|
||
// vector_real_min
|
||
// dw bit[1:0] : x_dw 2: s32 1: s16 0:s8
|
||
// dw bit[5:6] : z_dw 2: s32
|
||
// -32 < Q < 32
|
||
// z = x*cosnt /2^q
|
||
//=========================================================================
|
||
__attribute__((always_inline)) inline
|
||
void vector_real_min(void *zptr, void *xptr, short len, char q, long config, long const_dat)
|
||
{
|
||
config = config | VEC_MIN | VEC_CONST_MUL | VEC_QDT | VEC_QDT_MODE | VEC_YPTR_NOCPY | VEC_CPY_REAL_OR_VEC;
|
||
hwvec_exec(xptr, 0, zptr, 0, 0, 0, len, 1, q, config, const_dat);
|
||
}
|
||
|
||
#endif
|
||
|
||
#if defined CONFIG_FPGA_TEST_ENABLE && !defined CONFIG_VIDEO_ENABLE
|
||
|
||
#include "os/os_api.h"
|
||
#include "init.h"
|
||
|
||
void REAL_FFT_FUN(int *data, int blockbit, int *oudata)
|
||
{
|
||
vc_hw_fft(data, blockbit, oudata, 1, data == oudata ? 1 : 0);
|
||
}
|
||
|
||
void REAL_IFFT_FUN(int *data, int blockbit, int *oudata)
|
||
{
|
||
vc_hw_ifft(data, blockbit, oudata, 1, data == oudata ? 1 : 0);
|
||
}
|
||
|
||
void COMPLEX_FFT_FUN(int *data, int blockbit, int *oudata)
|
||
{
|
||
vc_hw_fft(data, blockbit, oudata, 0, data == oudata ? 1 : 0);
|
||
}
|
||
|
||
void COMPLEX_IFFT_FUN(int *data, int blockbit, int *oudata)
|
||
{
|
||
vc_hw_ifft(data, blockbit, oudata, 0, data == oudata ? 1 : 0);
|
||
}
|
||
|
||
static const int real_fft_test_input_data_512[] = {
|
||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 20, -83, 58, -40, 140, -161, 110, -102, 80, -17, 41, -101, 26, 35, -54, -28, 180, -49, -180, 87, 70, 34, -222, 272, -129, 2, 44, 86, -186, 84, 32, -99, 126, -90, 44, -44, 94, -167, 55, 42, 1, -55, 65, -15, -79, 156, -64, -29, 9, 99, -125, -10, 133, -88, -6, 0, 5, 38, -65, 25, -64, 104, -79, -10, 28, -50, 105, -89, 92, -125, 159, -143, 27, 41, -25, 56, -135, 134, -108, 87, -26, 0, -35, 62, 18, -83, 41, 42, -66, -1, 69, -54, -14, 26, 48, -64, 5, 38, -4, -44, 74, -59, 10, 24, 1, -40, 23, 31, -81, 58, -2, -10, 0, 26, -44, 2, 25, -1, -30, 37, -27, 0, 5, 8, -13, -13, 37, -25, 13, -10, 23, -30, 22, -1, -10, 2, 4, -2, -3, 11, -10, 0, 4, 3, -10, 9, -2, -2, -2, 4, -1, -2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||
};
|
||
|
||
static const int real_fft_test_output_data_real_512[] = {
|
||
16, -15, 15, -17, 26, -39, 50, -51, 32, 7, -43, 45, -16, -17, 23, -17, 24, -44, 49, -24, -13, 45, -66, 89, -108, 116, -105, 84, -62, 32, 12, -50, 47, 1, -49, 49, -6, -43, 65, -66, 56, -32, -7, 39, -47, 36, -19, -2, 31, -63, 85, -93, 108, -133, 143, -118, 84, -87, 144, -208, 224, -189, 147, -128, 120, -96, 57, -37, 61, -110, 128, -80, -11, 75, -78, 48, -28, 3, 71, -191, 288, -305, 258, -221, 246, -327, 414, -452, 431, -398, 392, -369, 263, -116, 66, -174, 336, -418, 401, -357, 321, -271, 216, -212, 277, -323, 242, -45, -122, 116, 52, -226, 269, -148, -72, 294, -446, 496, -449, 285, 6, -372, 672, -793, 715, -487, 226, -92, 164, -326, 374, -266, 153, -156, 263, -421, 568, -591, 393, -52, -214, 290, -257, 287, -498, 837, -1075, 991, -594, 77, 383, -612, 327, 521, -1311, 1229, -380, -106, -581, 1888, -2622, 2366, -1699, 1257, -1084, 895, -529, 57, 313, -397, 220, -37, 51, -157, 113, 89, -177, -41, 439, -717, 718, -534, 347, -270, 308, -409, 498, -498, 373, -180, 32, 4, 38, -58, 14, 48, -84, 109, -155, 233, -351, 532, -725, 773, -562, 194, 76, -64, -199, 484, -517, 207, 197, -297, -22, 465, -727, 837, -953, 932, -417, -602, 1538, -1694, 934, 243, -1241, 1793, -1868, 1439, -612, -169, 432, -182, -193, 514, -872, 1058, -524, -755, 1863, -1893, 1041, -279, 131, -279, 279, -114, -20, 88, -168, 270, -355, 420, -474, 507, -516
|
||
};
|
||
|
||
static const int real_fft_test_output_data_img_512[] = {
|
||
0, -5, 14, -22, 29, -28, 16, 9, -34, 43, -20, -21, 43, -30, 3, 9, -11, 30, -72, 111, -127, 123, -115, 104, -81, 46, -12, -11, 29, -44, 44, -10, -43, 70, -40, -19, 53, -42, 11, 18, -44, 66, -68, 41, -3, -31, 52, -72, 86, -85, 73, -67, 68, -59, 29, -5, 23, -75, 105, -72, 3, 49, -60, 55, -65, 83, -80, 49, -17, 34, -102, 172, -181, 123, -49, 3, 29, -85, 150, -164, 99, -11, -22, -23, 100, -146, 128, -66, 22, -23, 28, 6, -32, -55, 252, -417, 433, -339, 248, -200, 166, -132, 130, -154, 123, 18, -207, 293, -212, 59, -11, 151, -404, 636, -750, 718, -573, 374, -153, -62, 203, -174, -50, 381, -688, 861, -833, 633, -438, 418, -536, 604, -526, 389, -308, 327, -484, 777, -1067, 1169, -1061, 910, -887, 1009, -1137, 1074, -736, 284, 1, 27, -367, 1010, -1776, 2123, -1622, 733, -531, 1372, -2304, 2202, -1105, -10, 489, -525, 579, -784, 973, -952, 668, -273, 34, -63, 176, -141, 3, -26, 293, -573, 585, -306, -39, 235, -241, 150, -69, 68, -167, 332, -477, 507, -413, 285, -227, 248, -278, 269, -248, 255, -284, 318, -348, 331, -176, -119, 383, -395, 116, 268, -497, 427, -154, -8, -217, 741, -1159, 1200, -996, 784, -512, -6, 604, -725, 8, 1224, -2201, 2400, -1873, 961, 80, -1027, 1537, -1407, 919, -605, 653, -883, 1299, -2131, 3144, -3489, 2686, -1398, 712, -893, 1285, -1333, 1126, -971, 908, -817, 681, -553, 442, -328, 215, -108, 0
|
||
};
|
||
|
||
static const int complex_fft_test_output_data_256[] = {
|
||
65280, 65536, -21115, 20602, -10685, 10172, -7207, 6694, -5467, 4955, -4423, 3912, -3727, 3214, -3229, 2716, -2855, 2343, -2564, 2053, -2332, 1820, -2142, 1629, -1982, 1470, -1847, 1335, -1731, 1220, -1631, 1119, -1543, 1031, -1465, 953, -1396, 884, -1334, 822, -1278, 766, -1227, 716, -1181, 669, -1139, 627, -1100, 588, -1064, 552, -1030, 519, -1000, 488, -972, 459, -944, 432, -919, 407, -896, 384, -874, 362, -853, 341, -833, 322, -814, 303, -797, 286, -781, 268, -764, 252, -749, 237, -735, 223, -721, 209, -708, 196, -695, 183, -683, 171, -671, 160, -660, 149, -650, 138, -639, 127, -629, 117, -620, 107, -610, 98, -601, 89, -593, 81, -584, 72, -576, 64, -568, 56, -560, 48, -553, 41, -546, 33, -539, 27, -532, 20, -525, 13, -518, 6, -512, 0, -506, -6, -500, -13, -494, -18, -488, -24, -482, -30, -477, -35, -471, -41, -466, -46, -461, -51, -456, -56, -451, -61, -446, -66, -441, -71, -436, -76, -432, -80, -427, -85, -423, -90, -418, -94, -414, -98, -410, -103, -405, -107, -401, -111, -397, -115, -393, -119, -389, -123, -385, -127, -381, -131, -377, -135, -373, -139, -370, -143, -366, -146, -362, -150, -358, -154, -355, -157, -351, -161, -348, -164, -344, -168, -340, -171, -337, -175, -334, -178, -331, -182, -327, -185, -324, -189, -320, -192, -317, -195, -313, -199, -310, -202, -307, -205, -304, -208, -301, -212, -297, -215, -294, -218, -291, -221, -288, -224, -284, -228, -281, -231, -278, -234, -275, -237, -272, -241, -269, -243, -265, -247, -262, -250, -259, -253, -256, -256, -253, -259, -250, -262, -247, -265, -243, -269, -241, -272, -237, -275, -234, -278, -231, -281, -228, -284, -224, -288, -221, -291, -218, -294, -215, -297, -212, -301, -208, -304, -205, -307, -202, -310, -199, -313, -195, -317, -192, -320, -189, -324, -185, -327, -182, -331, -178, -334, -175, -337, -171, -340, -168, -344, -164, -348, -161, -351, -157, -355, -154, -358, -150, -362, -146, -366, -143, -370, -139, -373, -135, -377, -131, -381, -127, -385, -123, -389, -119, -393, -115, -397, -111, -401, -107, -405, -103, -410, -98, -414, -94, -418, -90, -423, -85, -427, -80, -432, -76, -436, -71, -441, -66, -446, -61, -451, -56, -456, -51, -461, -46, -466, -41, -471, -35, -477, -30, -482, -24, -488, -18, -494, -13, -500, -6, -506, 0, -512, 6, -518, 13, -525, 20, -532, 27, -539, 33, -546, 41, -553, 48, -560, 56, -568, 64, -576, 72, -584, 81, -593, 89, -601, 98, -610, 107, -620, 117, -629, 127, -639, 138, -650, 149, -660, 160, -671, 171, -683, 183, -695, 196, -708, 209, -721, 223, -735, 237, -749, 252, -764, 268, -781, 286, -797, 303, -814, 322, -833, 341, -853, 362, -874, 384, -896, 407, -919, 432, -944, 459, -972, 488, -1000, 519, -1030, 552, -1064, 588, -1100, 627, -1139, 669, -1181, 716, -1227, 766, -1278, 822, -1334, 884, -1396, 953, -1465, 1031, -1543, 1119, -1631, 1220, -1731, 1335, -1847, 1470, -1982, 1629, -2142, 1820, -2332, 2053, -2564, 2343, -2855, 2716, -3229, 3214, -3727, 3912, -4423, 4955, -5467, 6694, -7207, 10172, -10685, 20602, -21115
|
||
};
|
||
|
||
static const int complex_fft_test_output_data_512[] = {
|
||
261632, 262144, -83954, 82931, -42230, 41204, -28325, 27297, -21369, 20345, -17196, 16168, -14414, 13386, -12426, 11398, -10934, 9909, -9773, 8752, -8844, 7823, -8084, 7063, -7453, 6429, -6917, 5894, -6457, 5433, -6058, 5036, -5711, 4686, -5402, 4379, -5128, 4105, -4883, 3861, -4663, 3638, -4463, 3438, -4283, 3257, -4117, 3090, -3964, 2939, -3824, 2799, -3694, 2670, -3575, 2551, -3463, 2438, -3358, 2335, -3262, 2238, -3172, 2148, -3086, 2062, -3007, 1983, -2931, 1907, -2859, 1835, -2792, 1769, -2729, 1704, -2668, 1644, -2610, 1587, -2556, 1533, -2503, 1481, -2454, 1431, -2406, 1384, -2362, 1338, -2319, 1294, -2277, 1254, -2238, 1214, -2200, 1176, -2163, 1139, -2128, 1104, -2095, 1070, -2062, 1038, -2030, 1006, -2001, 976, -1971, 947, -1943, 919, -1915, 892, -1890, 866, -1864, 840, -1839, 815, -1815, 792, -1792, 769, -1770, 746, -1748, 724, -1727, 703, -1706, 682, -1687, 662, -1667, 643, -1648, 624, -1630, 606, -1612, 588, -1594, 571, -1578, 554, -1561, 537, -1545, 521, -1529, 505, -1514, 490, -1499, 475, -1484, 461, -1470, 446, -1456, 432, -1442, 419, -1429, 405, -1416, 391, -1403, 378, -1391, 366, -1378, 354, -1366, 342, -1355, 330, -1343, 319, -1332, 308, -1321, 296, -1310, 286, -1299, 275, -1289, 265, -1278, 254, -1269, 244, -1259, 234, -1248, 225, -1239, 215, -1230, 206, -1220, 196, -1211, 188, -1202, 178, -1193, 170, -1185, 161, -1176, 153, -1168, 144, -1160, 136, -1152, 128, -1144, 120, -1136, 112, -1128, 104, -1121, 96, -1113, 89, -1105, 82, -1099, 74, -1091, 67, -1084, 60, -1077, 53, -1070, 46, -1063, 39, -1057, 33, -1050, 26, -1043, 19, -1037, 13, -1030, 6, -1024, 0, -1018, -6, -1012, -12, -1006, -19, -1000, -25, -994, -31, -988, -36, -982, -43, -976, -48, -970, -54, -965, -59, -959, -65, -954, -70, -948, -76, -943, -81, -938, -87, -932, -92, -927, -97, -922, -102, -917, -107, -912, -113, -906, -118, -901, -123, -897, -128, -892, -132, -887, -138, -882, -142, -878, -147, -873, -151, -868, -156, -864, -161, -859, -165, -854, -170, -850, -175, -845, -179, -841, -183, -836, -188, -832, -192, -827, -197, -823, -201, -819, -205, -815, -209, -811, -213, -806, -218, -802, -222, -798, -226, -794, -230, -790, -234, -786, -238, -782, -243, -778, -246, -774, -251, -770, -254, -766, -258, -762, -262, -758, -266, -754, -270, -750, -274, -747, -278, -743, -281, -739, -285, -735, -289, -731, -293, -728, -296, -724, -300, -720, -304, -717, -307, -713, -311, -709, -315, -706, -318, -702, -322, -699, -325, -695, -329, -692, -332, -688, -336, -685, -339, -681, -343, -678, -346, -674, -350, -671, -353, -667, -357, -664, -360, -660, -364, -657, -367, -654, -370, -650, -374, -647, -377, -643, -381, -640, -384, -637, -387, -634, -390, -630, -394, -627, -397, -624, -400, -621, -404, -617, -407, -614, -410, -611, -414, -607, -417, -604, -420, -601, -423, -598, -427, -594, -430, -591, -433, -588, -436, -585, -439, -582, -442, -578, -445, -575, -449, -572, -452, -569, -455, -566, -458, -562, -462, -559, -465, -556, -468, -553, -471, -550, -474, -547, -478, -543, -481, -540, -484, -537, -487, -534, -490, -531, -493, -528, -496, -525, -499, -521, -503, -518, -506, -515, -509, -512, -512, -509, -515, -506, -518, -503, -521, -499, -525, -496, -528, -493, -531, -490, -534, -487, -537, -484, -540, -481, -543, -478, -547, -474, -550, -471, -553, -468, -556, -465, -559, -462, -562, -458, -566, -455, -569, -452, -572, -449, -575, -445, -578, -442, -582, -439, -585, -436, -588, -433, -591, -430, -594, -427, -598, -423, -601, -420, -604, -417, -607, -414, -611, -410, -614, -407, -617, -404, -621, -400, -624, -397, -627, -394, -630, -390, -634, -387, -637, -384, -640, -381, -643, -377, -647, -374, -650, -370, -654, -367, -657, -364, -660, -360, -664, -357, -667, -353, -671, -350, -674, -346, -678, -343, -681, -339, -685, -336, -688, -332, -692, -329, -695, -325, -699, -322, -702, -318, -706, -315, -709, -311, -713, -307, -717, -304, -720, -300, -724, -296, -728, -293, -731, -289, -735, -285, -739, -281, -743, -278, -747, -274, -750, -270, -754, -266, -758, -262, -762, -258, -766, -254, -770, -251, -774, -246, -778, -243, -782, -238, -786, -234, -790, -230, -794, -226, -798, -222, -802, -218, -806, -213, -811, -209, -815, -205, -819, -201, -823, -197, -827, -192, -832, -188, -836, -183, -841, -179, -845, -175, -850, -170, -854, -165, -859, -161, -864, -156, -868, -151, -873, -147, -878, -142, -882, -138, -887, -132, -892, -128, -897, -123, -901, -118, -906, -113, -912, -107, -917, -102, -922, -97, -927, -92, -932, -87, -938, -81, -943, -76, -948, -70, -954, -65, -959, -59, -965, -54, -970, -48, -976, -43, -982, -36, -988, -31, -994, -25, -1000, -19, -1006, -12, -1012, -6, -1018, 0, -1024, 6, -1030, 13, -1037, 19, -1043, 26, -1050, 33, -1057, 39, -1063, 46, -1070, 53, -1077, 60, -1084, 67, -1091, 74, -1099, 82, -1105, 89, -1113, 96, -1121, 104, -1128, 112, -1136, 120, -1144, 128, -1152, 136, -1160, 144, -1168, 153, -1176, 161, -1185, 170, -1193, 178, -1202, 188, -1211, 196, -1220, 206, -1230, 215, -1239, 225, -1248, 234, -1259, 244, -1269, 254, -1278, 265, -1289, 275, -1299, 286, -1310, 296, -1321, 308, -1332, 319, -1343, 330, -1355, 342, -1366, 354, -1378, 366, -1391, 378, -1403, 391, -1416, 405, -1429, 419, -1442, 432, -1456, 446, -1470, 461, -1484, 475, -1499, 490, -1514, 505, -1529, 521, -1545, 537, -1561, 554, -1578, 571, -1594, 588, -1612, 606, -1630, 624, -1648, 643, -1667, 662, -1687, 682, -1706, 703, -1727, 724, -1748, 746, -1770, 769, -1792, 792, -1815, 815, -1839, 840, -1864, 866, -1890, 892, -1915, 919, -1943, 947, -1971, 976, -2001, 1006, -2030, 1038, -2062, 1070, -2095, 1104, -2128, 1139, -2163, 1176, -2200, 1214, -2238, 1254, -2277, 1294, -2319, 1338, -2362, 1384, -2406, 1431, -2454, 1481, -2503, 1533, -2556, 1587, -2610, 1644, -2668, 1704, -2729, 1769, -2792, 1835, -2859, 1907, -2931, 1983, -3007, 2062, -3086, 2148, -3172, 2238, -3262, 2335, -3358, 2438, -3463, 2551, -3575, 2670, -3694, 2799, -3824, 2939, -3964, 3090, -4117, 3257, -4283, 3438, -4463, 3638, -4663, 3861, -4883, 4105, -5128, 4379, -5402, 4686, -5711, 5036, -6058, 5433, -6457, 5894, -6917, 6429, -7453, 7063, -8084, 7823, -8844, 8752, -9773, 9909, -10934, 11398, -12426, 13386, -14414, 16168, -17196, 20345, -21369, 27297, -28325, 41204, -42230, 82931, -83954
|
||
};
|
||
|
||
static const int real_fft_test_output_data_1024[] = {
|
||
523776, 0, -511, 166887, -514, 83437, -515, 55627, -512, 41720, -516, 33372, -515, 27809, -515, 23835, -512, 20855, -510, 18539, -509, 16683, -509, 15164, -513, 13901, -511, 12831, -512, 11912, -511, 11117, -512, 10422, -511, 9808, -512, 9261, -511, 8774, -513, 8333, -514, 7934, -514, 7575, -514, 7243, -513, 6941, -513, 6662, -512, 6405, -512, 6168, -513, 5945, -512, 5739, -512, 5547, -512, 5369, -512, 5198, -512, 5042, -512, 4891, -512, 4749, -511, 4617, -513, 4491, -512, 4372, -512, 4259, -511, 4151, -511, 4048, -511, 3952, -511, 3857, -511, 3769, -513, 3685, -512, 3603, -512, 3526, -512, 3452, -512, 3380, -512, 3311, -513, 3246, -512, 3182, -512, 3120, -513, 3063, -512, 3006, -512, 2950, -512, 2897, -512, 2847, -512, 2797, -512, 2750, -511, 2704, -512, 2659, -512, 2616, -512, 2574, -512, 2533, -512, 2494, -512, 2456, -512, 2419, -512, 2382, -512, 2348, -512, 2313, -512, 2280, -512, 2248, -511, 2216, -511, 2186, -512, 2156, -512, 2127, -512, 2098, -512, 2071, -512, 2044, -512, 2017, -512, 1993, -512, 1967, -512, 1942, -513, 1918, -513, 1895, -513, 1872, -512, 1850, -512, 1828, -512, 1807, -512, 1786, -513, 1765, -512, 1745, -512, 1726, -512, 1708, -512, 1688, -512, 1670, -512, 1652, -512, 1633, -512, 1616, -512, 1599, -512, 1582, -511, 1566, -512, 1550, -511, 1534, -512, 1518, -511, 1503, -512, 1489, -512, 1474, -512, 1459, -512, 1445, -512, 1431, -512, 1417, -512, 1404, -512, 1390, -512, 1377, -512, 1365, -513, 1351, -512, 1340, -512, 1327, -511, 1315, -512, 1303, -512, 1292, -512, 1281, -512, 1269, -512, 1258, -512, 1247, -512, 1236, -512, 1225, -512, 1215, -512, 1205, -512, 1195, -512, 1184, -512, 1174, -512, 1164, -512, 1155, -512, 1146, -511, 1136, -512, 1127, -512, 1118, -512, 1109, -512, 1100, -512, 1091, -512, 1083, -512, 1074, -512, 1066, -512, 1058, -512, 1049, -512, 1040, -512, 1033, -512, 1025, -512, 1017, -512, 1009, -512, 1002, -512, 994, -512, 987, -512, 979, -512, 973, -512, 965, -512, 958, -512, 951, -512, 944, -512, 937, -512, 930, -512, 923, -512, 917, -512, 911, -512, 904, -512, 897, -512, 891, -512, 885, -512, 878, -512, 872, -512, 866, -512, 860, -512, 854, -512, 848, -512, 842, -512, 837, -512, 831, -512, 825, -512, 819, -512, 814, -512, 808, -512, 803, -512, 798, -512, 792, -512, 787, -512, 782, -512, 776, -512, 771, -512, 766, -512, 761, -512, 756, -512, 751, -512, 746, -512, 741, -512, 737, -512, 732, -512, 727, -512, 722, -512, 718, -512, 713, -512, 708, -512, 704, -512, 699, -512, 695, -512, 690, -512, 686, -512, 681, -512, 677, -512, 673, -512, 668, -512, 664, -512, 660, -512, 656, -512, 652, -512, 648, -512, 644, -512, 640, -512, 636, -512, 632, -512, 628, -512, 624, -512, 620, -512, 616, -512, 612, -512, 608, -512, 605, -512, 601, -512, 597, -512, 594, -512, 590, -512, 586, -512, 583, -512, 579, -512, 575, -512, 572, -512, 568, -512, 565, -512, 561, -512, 558, -512, 555, -512, 551, -512, 548, -512, 544, -512, 541, -512, 538, -512, 534, -512, 531, -512, 528, -512, 525, -512, 522, -512, 518, -512, 515, -512, 512, -512, 509, -512, 506, -512, 503, -512, 500, -512, 496, -512, 493, -512, 490, -512, 487, -512, 485, -512, 482, -512, 479, -512, 476, -512, 473, -512, 470, -512, 467, -512, 464, -512, 461, -512, 458, -512, 456, -512, 453, -512, 450, -512, 447, -512, 444, -512, 442, -512, 439, -512, 436, -512, 434, -512, 431, -512, 428, -512, 426, -512, 423, -512, 420, -512, 418, -512, 415, -512, 412, -512, 410, -512, 407, -512, 405, -512, 402, -512, 400, -512, 397, -512, 395, -512, 392, -512, 390, -512, 387, -512, 385, -512, 382, -512, 380, -512, 377, -512, 375, -512, 372, -512, 370, -512, 368, -512, 365, -512, 363, -512, 361, -512, 358, -512, 356, -512, 354, -512, 351, -512, 349, -512, 347, -512, 344, -512, 342, -512, 340, -512, 338, -512, 335, -512, 333, -512, 331, -512, 329, -512, 326, -512, 324, -512, 322, -512, 320, -512, 318, -512, 316, -512, 313, -512, 311, -512, 309, -512, 307, -512, 305, -512, 303, -512, 301, -512, 298, -512, 296, -512, 294, -512, 292, -512, 290, -512, 288, -512, 286, -512, 284, -512, 282, -512, 280, -512, 278, -512, 276, -512, 274, -512, 272, -512, 270, -512, 268, -512, 266, -512, 264, -512, 262, -512, 260, -512, 258, -512, 256, -512, 254, -512, 252, -512, 250, -512, 248, -512, 246, -512, 244, -512, 242, -512, 240, -512, 238, -512, 236, -512, 235, -512, 233, -512, 230, -512, 229, -512, 227, -512, 225, -512, 223, -512, 221, -512, 220, -512, 218, -512, 216, -512, 214, -512, 212, -512, 210, -512, 208, -512, 207, -512, 205, -512, 203, -512, 201, -512, 199, -512, 198, -512, 196, -512, 194, -512, 192, -512, 190, -512, 189, -512, 187, -512, 185, -512, 183, -512, 182, -512, 180, -512, 178, -512, 176, -512, 174, -512, 173, -512, 171, -512, 169, -512, 167, -512, 166, -512, 164, -512, 162, -512, 160, -512, 159, -512, 157, -512, 155, -512, 154, -512, 152, -512, 150, -512, 149, -512, 147, -512, 145, -512, 143, -512, 142, -512, 140, -512, 139, -512, 137, -512, 135, -512, 133, -512, 132, -512, 130, -512, 128, -512, 127, -512, 125, -512, 123, -512, 122, -512, 120, -512, 118, -512, 117, -512, 115, -512, 113, -512, 112, -512, 110, -512, 108, -512, 107, -512, 105, -512, 104, -512, 102, -512, 100, -512, 99, -512, 97, -512, 95, -512, 94, -512, 92, -512, 90, -512, 89, -512, 87, -512, 86, -512, 84, -512, 82, -512, 81, -512, 79, -512, 78, -512, 76, -512, 74, -512, 73, -512, 71, -512, 70, -512, 68, -512, 66, -512, 65, -512, 63, -512, 62, -512, 60, -512, 58, -512, 57, -512, 55, -512, 54, -512, 52, -512, 50, -512, 49, -512, 47, -512, 46, -512, 44, -512, 43, -512, 41, -512, 39, -512, 38, -512, 36, -512, 35, -512, 33, -512, 32, -512, 30, -512, 28, -512, 27, -512, 25, -512, 24, -512, 22, -512, 20, -512, 19, -512, 17, -512, 16, -512, 14, -512, 13, -512, 11, -512, 9, -512, 8, -512, 6, -512, 5, -512, 3, -512, 2, -512, 0
|
||
};
|
||
|
||
SEC_USED(.fft_data) static int test_datain[4096];
|
||
SEC_USED(.fft_data) static int test_dataout[4096];
|
||
SEC_USED(.fft_data) static fft_config_struct test_fft_config;
|
||
|
||
___interrupt
|
||
static void fft_isr(void)
|
||
{
|
||
if (JL_FFT->CON & BIT(7)) {
|
||
|
||
}
|
||
}
|
||
|
||
static void hw_fft_test(void)
|
||
{
|
||
#if 0
|
||
REAL_FFT_FUN(datain, 7, datain); //输入数据为128个实数,放在datain,输出数据是65个复数,排布为实部,虚部,实部,虚部。。。
|
||
puts("REAL_FFT_FUN RES:\n");
|
||
for (int i = 0; i < sizeof(datain) / sizeof(datain[0]); i++) {
|
||
printf("%d, ", datain[i]);
|
||
}
|
||
|
||
REAL_IFFT_FUN(datain, 7, dataout); //反变换,得到128个实数
|
||
puts("REAL_IFFT_FUN RES:\n");
|
||
for (int i = 0; i < sizeof(dataout) / sizeof(dataout[0]); i++) {
|
||
printf("%d, ", dataout[i]);
|
||
}
|
||
|
||
COMPLEX_FFT_FUN(datain, 6, datain); //输入数据为64个复数,放在datain,输出数据是64个复数,排布为实部,虚部,实部,虚部。。。
|
||
puts("COMPLEX_FFT_FUN RES:\n");
|
||
for (int i = 0; i < sizeof(datain) / sizeof(datain[0]); i++) {
|
||
printf("%d, ", datain[i]);
|
||
}
|
||
|
||
COMPLEX_IFFT_FUN(datain, 6, dataout); //反变换,得到64个复数
|
||
puts("COMPLEX_IFFT_FUN RES:\n");
|
||
for (int i = 0; i < sizeof(dataout) / sizeof(dataout[0]); i++) {
|
||
printf("%d, ", dataout[i]);
|
||
}
|
||
#endif
|
||
|
||
/* request_irq(IRQ_FFT_IDX, 0, fft_isr, 0); */
|
||
|
||
static u8 fft_test_cnt = 0;
|
||
int *out_ptr = NULL;
|
||
|
||
if (fft_test_cnt++ % 2) {
|
||
out_ptr = test_datain;
|
||
} else {
|
||
out_ptr = test_dataout;
|
||
}
|
||
|
||
if (fft_test_cnt == 64) {
|
||
fft_test_cnt = 0;
|
||
}
|
||
|
||
hwfft_fill_fft_ctx((hwfft_ctx_t *)&test_fft_config, REAL_FFT512_CONFIG, (long *)test_datain, (long *)out_ptr);
|
||
|
||
for (int i = 0; i < ARRAY_SIZE(real_fft_test_input_data_512); i++) {
|
||
test_datain[i] = real_fft_test_input_data_512[i];
|
||
}
|
||
|
||
hwfft_fft_i32((hwfft_ctx_t *)&test_fft_config);
|
||
|
||
for (int i = 0; i < ARRAY_SIZE(real_fft_test_input_data_512) + 2; i++) {
|
||
/* printf("%d, ", out_ptr[i]); */
|
||
if (i % 2 == 0 && out_ptr[i] != real_fft_test_output_data_real_512[i / 2]) {
|
||
___trig;
|
||
printf("fft test real fail !!!\n");
|
||
put_buf((u8 *)out_ptr, sizeof(real_fft_test_input_data_512) + 8);
|
||
while (1);
|
||
} else if (i % 2 && out_ptr[i] != real_fft_test_output_data_img_512[i / 2]) {
|
||
___trig;
|
||
printf("fft test img fail !!!\n");
|
||
put_buf((u8 *)out_ptr, sizeof(real_fft_test_input_data_512) + 8);
|
||
while (1);
|
||
}
|
||
}
|
||
|
||
if (out_ptr != test_datain) {
|
||
memset(test_datain, 0, sizeof(test_datain));
|
||
}
|
||
|
||
hwfft_fill_fft_ctx((hwfft_ctx_t *)&test_fft_config, REAL_IFFT512_CONFIG, (long *)out_ptr, (long *)test_datain);
|
||
|
||
hwfft_ifft_i32((hwfft_ctx_t *)&test_fft_config);
|
||
|
||
for (int i = 0; i < ARRAY_SIZE(real_fft_test_input_data_512); i++) {
|
||
/* printf("%d, ", test_datain[i]); */
|
||
if (test_datain[i] != real_fft_test_input_data_512[i]) {
|
||
___trig;
|
||
printf("ifft test real fail !!!\n");
|
||
put_buf((u8 *)test_datain, sizeof(real_fft_test_input_data_512));
|
||
while (1);
|
||
}
|
||
}
|
||
|
||
hwfft_fill_fft_ctx((hwfft_ctx_t *)&test_fft_config, COMPLEX_FFT256_CONFIG, (long *)test_datain, (long *)out_ptr);
|
||
|
||
for (int i = 0; i < ARRAY_SIZE(complex_fft_test_output_data_256); i++) {
|
||
test_datain[i] = i;
|
||
}
|
||
|
||
hwfft_fft_i32((hwfft_ctx_t *)&test_fft_config);
|
||
|
||
for (int i = 0; i < ARRAY_SIZE(complex_fft_test_output_data_256); i++) {
|
||
/* printf("%d, ", out_ptr[i]); */
|
||
if (out_ptr[i] != complex_fft_test_output_data_256[i]) {
|
||
___trig;
|
||
printf("fft test complex fail !!!\n");
|
||
put_buf((u8 *)out_ptr, sizeof(complex_fft_test_output_data_256));
|
||
while (1);
|
||
}
|
||
}
|
||
|
||
if (out_ptr != test_datain) {
|
||
memset(test_datain, 0, sizeof(test_datain));
|
||
}
|
||
|
||
hwfft_fill_fft_ctx((hwfft_ctx_t *)&test_fft_config, COMPLEX_IFFT256_CONFIG, (long *)out_ptr, (long *)test_datain);
|
||
|
||
hwfft_ifft_i32((hwfft_ctx_t *)&test_fft_config);
|
||
|
||
for (int i = 0; i < ARRAY_SIZE(complex_fft_test_output_data_256); i++) {
|
||
/* printf("%d, ", test_datain[i]); */
|
||
if (test_datain[i] != i) {
|
||
___trig;
|
||
printf("ifft test complex fail !!!\n");
|
||
put_buf((u8 *)test_datain, sizeof(complex_fft_test_output_data_256));
|
||
while (1);
|
||
}
|
||
}
|
||
|
||
hwfft_fill_fft_ctx((hwfft_ctx_t *)&test_fft_config, COMPLEX_FFT512_CONFIG, (long *)test_datain, (long *)out_ptr);
|
||
|
||
for (int i = 0; i < ARRAY_SIZE(complex_fft_test_output_data_512); i++) {
|
||
test_datain[i] = i;
|
||
}
|
||
|
||
hwfft_fft_i32((hwfft_ctx_t *)&test_fft_config);
|
||
|
||
for (int i = 0; i < ARRAY_SIZE(complex_fft_test_output_data_512); i++) {
|
||
/* printf("%d, ", out_ptr[i]); */
|
||
if (out_ptr[i] != complex_fft_test_output_data_512[i]) {
|
||
___trig;
|
||
printf("fft test complex fail !!!\n");
|
||
put_buf((u8 *)out_ptr, sizeof(complex_fft_test_output_data_512));
|
||
while (1);
|
||
}
|
||
}
|
||
|
||
if (out_ptr != test_datain) {
|
||
memset(test_datain, 0, sizeof(test_datain));
|
||
}
|
||
|
||
hwfft_fill_fft_ctx((hwfft_ctx_t *)&test_fft_config, COMPLEX_IFFT512_CONFIG, (long *)out_ptr, (long *)test_datain);
|
||
|
||
hwfft_ifft_i32((hwfft_ctx_t *)&test_fft_config);
|
||
|
||
for (int i = 0; i < ARRAY_SIZE(complex_fft_test_output_data_512); i++) {
|
||
/* printf("%d, ", test_datain[i]); */
|
||
if (test_datain[i] != i) {
|
||
___trig;
|
||
printf("ifft test complex fail !!!\n");
|
||
put_buf((u8 *)test_datain, sizeof(complex_fft_test_output_data_512));
|
||
while (1);
|
||
}
|
||
}
|
||
|
||
hwfft_fill_fft_ctx((hwfft_ctx_t *)&test_fft_config, REAL_FFT1024_CONFIG, (long *)test_datain, (long *)out_ptr);
|
||
|
||
for (int i = 0; i < ARRAY_SIZE(real_fft_test_output_data_1024) - 2; i++) {
|
||
test_datain[i] = i;
|
||
}
|
||
|
||
hwfft_fft_i32((hwfft_ctx_t *)&test_fft_config);
|
||
|
||
for (int i = 0; i < ARRAY_SIZE(real_fft_test_output_data_1024); i++) {
|
||
/* printf("%d, ", out_ptr[i]); */
|
||
if (out_ptr[i] != real_fft_test_output_data_1024[i]) {
|
||
___trig;
|
||
printf("fft test complex fail !!!\n");
|
||
put_buf((u8 *)out_ptr, sizeof(real_fft_test_output_data_1024));
|
||
while (1);
|
||
}
|
||
}
|
||
|
||
if (out_ptr != test_datain) {
|
||
memset(test_datain, 0, sizeof(test_datain));
|
||
}
|
||
|
||
hwfft_fill_fft_ctx((hwfft_ctx_t *)&test_fft_config, REAL_IFFT1024_CONFIG, (long *)out_ptr, (long *)test_datain);
|
||
|
||
hwfft_ifft_i32((hwfft_ctx_t *)&test_fft_config);
|
||
|
||
for (int i = 0; i < ARRAY_SIZE(real_fft_test_output_data_1024) - 2; i++) {
|
||
/* printf("%d, ", test_datain[i]); */
|
||
if (test_datain[i] != i) {
|
||
___trig;
|
||
printf("ifft test complex fail !!!\n");
|
||
put_buf((u8 *)test_datain, sizeof(real_fft_test_output_data_1024) - 2);
|
||
while (1);
|
||
}
|
||
}
|
||
|
||
//循环测试
|
||
for (int n = 0; n < ARRAY_SIZE(real_tab); n += 2) {
|
||
hwfft_fill_fft_ctx((hwfft_ctx_t *)&test_fft_config, real_tab[n].config, (long *)test_datain, (long *)out_ptr);
|
||
|
||
for (int i = 0; i < real_tab[n].block; i++) {
|
||
test_datain[i] = i * fft_test_cnt;
|
||
}
|
||
|
||
hwfft_fft_i32((hwfft_ctx_t *)&test_fft_config);
|
||
|
||
if (out_ptr != test_datain) {
|
||
memset(test_datain, 0, sizeof(test_datain));
|
||
}
|
||
|
||
hwfft_fill_fft_ctx((hwfft_ctx_t *)&test_fft_config, real_tab[n + 1].config, (long *)out_ptr, (long *)test_datain);
|
||
|
||
hwfft_ifft_i32((hwfft_ctx_t *)&test_fft_config);
|
||
|
||
for (int i = 0; i < real_tab[n + 1].block; i++) {
|
||
/* printf("%d, ", test_datain[i]); */
|
||
if (test_datain[i] != i * fft_test_cnt && test_datain[i] != i * fft_test_cnt + 1 && test_datain[i] != i * fft_test_cnt - 1) {
|
||
___trig;
|
||
printf("real test fail n : %d, i : %d, cnt : %d !!!\n", n, i, fft_test_cnt);
|
||
for (int i = 0; i < real_tab[n + 1].block; i++) {
|
||
printf("%d, ", test_datain[i]);
|
||
}
|
||
/* put_buf((u8 *)test_datain, real_tab[n + 1].block * 4); */
|
||
while (1);
|
||
}
|
||
}
|
||
}
|
||
|
||
for (int n = 0; n < ARRAY_SIZE(complex_tab); n += 2) {
|
||
hwfft_fill_fft_ctx((hwfft_ctx_t *)&test_fft_config, complex_tab[n].config, (long *)test_datain, (long *)out_ptr);
|
||
|
||
for (int i = 0; i < complex_tab[n].block * 2; i++) {
|
||
test_datain[i] = i;
|
||
}
|
||
|
||
hwfft_fft_i32((hwfft_ctx_t *)&test_fft_config);
|
||
|
||
if (out_ptr != test_datain) {
|
||
memset(test_datain, 0, sizeof(test_datain));
|
||
}
|
||
|
||
hwfft_fill_fft_ctx((hwfft_ctx_t *)&test_fft_config, complex_tab[n + 1].config, (long *)out_ptr, (long *)test_datain);
|
||
|
||
hwfft_ifft_i32((hwfft_ctx_t *)&test_fft_config);
|
||
|
||
for (int i = 0; i < complex_tab[n + 1].block * 2; i++) {
|
||
/* printf("%d, ", test_datain[i]); */
|
||
if (test_datain[i] != i) {
|
||
___trig;
|
||
printf("complex test fail n : %d, i : %d, cnt : %d !!!\n", n, i, 2);
|
||
for (int i = 0; i < real_tab[n + 1].block * 2; i++) {
|
||
printf("%d, ", test_datain[i]);
|
||
}
|
||
/* put_buf((u8 *)test_datain, complex_tab[n + 1].block * 2 * 4); */
|
||
while (1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
static void fft_test_task(void *priv)
|
||
{
|
||
while (1) {
|
||
hw_fft_test();
|
||
os_time_dly(1);
|
||
}
|
||
}
|
||
|
||
static int fft_test_init(void)
|
||
{
|
||
return thread_fork("fft_test", 0, 256, 0, 0, fft_test_task, NULL);
|
||
}
|
||
late_initcall(fft_test_init);
|
||
|
||
#endif
|
||
|