#include "riscv_const_structs.h" #include "ref.h" void ref_cfft_f32(const riscv_cfft_instance_f32 *S, float32_t *p1, uint8_t ifftFlag, uint8_t bitReverseFlag) { int n, mmax, m, j, istep, i; float32_t wtemp, wr, wpr, wpi, wi, theta; float32_t tempr, tempi; float32_t *data = p1; uint32_t N = S->fftLen; int32_t dir = (ifftFlag) ? -1 : 1; // decrement pointer since the original version used fortran style indexing. data--; n = N << 1; j = 1; for (i = 1; i < n; i += 2) { if (j > i) { tempr = data[j]; data[j] = data[i]; data[i] = tempr; tempr = data[j + 1]; data[j + 1] = data[i + 1]; data[i + 1] = tempr; } m = n >> 1; while (m >= 2 && j > m) { j -= m; m >>= 1; } j += m; } mmax = 2; while (n > mmax) { istep = 2 * mmax; theta = -6.283185307179586f / (dir * mmax); wtemp = sinf(0.5f * theta); wpr = -2.0f * wtemp * wtemp; wpi = sinf(theta); wr = 1.0f; wi = 0.0f; for (m = 1; m < mmax; m += 2) { for (i = m; i <= n; i += istep) { j = i + mmax; tempr = wr * data[j] - wi * data[j + 1]; tempi = wr * data[j + 1] + wi * data[j]; data[j] = data[i] - tempr; data[j + 1] = data[i + 1] - tempi; data[i] += tempr; data[i + 1] += tempi; } wr = (wtemp = wr) * wpr - wi * wpi + wr; wi = wi * wpr + wtemp * wpi + wi; } mmax = istep; } // Inverse transform is scaled by 1/N if (ifftFlag) { data++; for (i = 0; i < 2 * N; i++) { data[i] /= N; } } } void ref_cfft_q31(const riscv_cfft_instance_q31 *S, q31_t *p1, uint8_t ifftFlag, uint8_t bitReverseFlag) { uint32_t i; // float32_t *fSrc = (float32_t*)p1; float32_t fSrc[S->fftLen * 2]; riscv_q31_to_float(p1, fSrc, S->fftLen * 2); for (i = 0; i < S->fftLen * 2; i++) { // read the q31 data, cast to float, scale down for float fSrc[i] = (float32_t)p1[i] / 2147483648.0f; } switch (S->fftLen) { case 16: ref_cfft_f32(&riscv_cfft_sR_f32_len16, fSrc, ifftFlag, bitReverseFlag); break; case 32: ref_cfft_f32(&riscv_cfft_sR_f32_len32, fSrc, ifftFlag, bitReverseFlag); break; case 64: ref_cfft_f32(&riscv_cfft_sR_f32_len64, fSrc, ifftFlag, bitReverseFlag); break; case 128: ref_cfft_f32(&riscv_cfft_sR_f32_len128, fSrc, ifftFlag, bitReverseFlag); break; case 256: ref_cfft_f32(&riscv_cfft_sR_f32_len256, fSrc, ifftFlag, bitReverseFlag); break; case 512: ref_cfft_f32(&riscv_cfft_sR_f32_len512, fSrc, ifftFlag, bitReverseFlag); break; case 1024: ref_cfft_f32(&riscv_cfft_sR_f32_len1024, fSrc, ifftFlag, bitReverseFlag); break; case 2048: ref_cfft_f32(&riscv_cfft_sR_f32_len2048, fSrc, ifftFlag, bitReverseFlag); break; case 4096: ref_cfft_f32(&riscv_cfft_sR_f32_len4096, fSrc, ifftFlag, bitReverseFlag); break; } if (ifftFlag) { for (i = 0; i < S->fftLen * 2; i++) { // read the float data, scale up for q31, cast to q31 p1[i] = (q31_t)(fSrc[i] * 2147483648.0f); } } else { for (i = 0; i < S->fftLen * 2; i++) { // read the float data, scale up for q31, cast to q31 p1[i] = (q31_t)(fSrc[i] * 2147483648.0f / (float32_t)S->fftLen); } } } void ref_cfft_q15(const riscv_cfft_instance_q15 *S, q15_t *pSrc, uint8_t ifftFlag, uint8_t bitReverseFlag) { uint32_t i; // float32_t *fSrc = (float32_t*)pSrc; float32_t fSrc[S->fftLen * 2]; riscv_q15_to_float(pSrc, fSrc, S->fftLen * 2); for (i = 0; i < S->fftLen * 2; i++) { // read the q15 data, cast to float, scale down for float, place in // temporary buffer scratchArray[i] = (float32_t)pSrc[i] / 32768.0f; } for (i = 0; i < S->fftLen * 2; i++) { // copy from temp buffer to final buffer fSrc[i] = scratchArray[i]; } switch (S->fftLen) { case 16: ref_cfft_f32(&riscv_cfft_sR_f32_len16, fSrc, ifftFlag, bitReverseFlag); break; case 32: ref_cfft_f32(&riscv_cfft_sR_f32_len32, fSrc, ifftFlag, bitReverseFlag); break; case 64: ref_cfft_f32(&riscv_cfft_sR_f32_len64, fSrc, ifftFlag, bitReverseFlag); break; case 128: ref_cfft_f32(&riscv_cfft_sR_f32_len128, fSrc, ifftFlag, bitReverseFlag); break; case 256: ref_cfft_f32(&riscv_cfft_sR_f32_len256, fSrc, ifftFlag, bitReverseFlag); break; case 512: ref_cfft_f32(&riscv_cfft_sR_f32_len512, fSrc, ifftFlag, bitReverseFlag); break; case 1024: ref_cfft_f32(&riscv_cfft_sR_f32_len1024, fSrc, ifftFlag, bitReverseFlag); break; case 2048: ref_cfft_f32(&riscv_cfft_sR_f32_len2048, fSrc, ifftFlag, bitReverseFlag); break; case 4096: ref_cfft_f32(&riscv_cfft_sR_f32_len4096, fSrc, ifftFlag, bitReverseFlag); break; } if (ifftFlag) { for (i = 0; i < S->fftLen * 2; i++) { // read the float data, scale up for q15, cast to q15 pSrc[i] = (q15_t)(fSrc[i] * 32768.0f); } } else { for (i = 0; i < S->fftLen * 2; i++) { // read the float data, scale up for q15, cast to q15 pSrc[i] = (q15_t)(fSrc[i] * 32768.0f / (float32_t)S->fftLen); } } } void ref_cfft_radix2_f32(const riscv_cfft_radix2_instance_f32 *S, float32_t *pSrc) { switch (S->fftLen) { case 16: ref_cfft_f32(&riscv_cfft_sR_f32_len16, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 32: ref_cfft_f32(&riscv_cfft_sR_f32_len32, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 64: ref_cfft_f32(&riscv_cfft_sR_f32_len64, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 128: ref_cfft_f32(&riscv_cfft_sR_f32_len128, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 256: ref_cfft_f32(&riscv_cfft_sR_f32_len256, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 512: ref_cfft_f32(&riscv_cfft_sR_f32_len512, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 1024: ref_cfft_f32(&riscv_cfft_sR_f32_len1024, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 2048: ref_cfft_f32(&riscv_cfft_sR_f32_len2048, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 4096: ref_cfft_f32(&riscv_cfft_sR_f32_len4096, pSrc, S->ifftFlag, S->bitReverseFlag); break; } } void ref_cfft_radix2_q31(const riscv_cfft_radix2_instance_q31 *S, q31_t *pSrc) { uint32_t i; // float32_t *fSrc = (float32_t*)pSrc; float32_t fSrc[S->fftLen * 2]; riscv_q31_to_float(pSrc, fSrc, S->fftLen * 2); for (i = 0; i < S->fftLen * 2; i++) { // read the q31 data, cast to float, scale down for float fSrc[i] = (float32_t)pSrc[i] / 2147483648.0f; } switch (S->fftLen) { case 16: ref_cfft_f32(&riscv_cfft_sR_f32_len16, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 32: ref_cfft_f32(&riscv_cfft_sR_f32_len32, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 64: ref_cfft_f32(&riscv_cfft_sR_f32_len64, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 128: ref_cfft_f32(&riscv_cfft_sR_f32_len128, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 256: ref_cfft_f32(&riscv_cfft_sR_f32_len256, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 512: ref_cfft_f32(&riscv_cfft_sR_f32_len512, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 1024: ref_cfft_f32(&riscv_cfft_sR_f32_len1024, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 2048: ref_cfft_f32(&riscv_cfft_sR_f32_len2048, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 4096: ref_cfft_f32(&riscv_cfft_sR_f32_len4096, fSrc, S->ifftFlag, S->bitReverseFlag); break; } if (S->ifftFlag) { for (i = 0; i < S->fftLen * 2; i++) { // read the float data, scale up for q31, cast to q31 pSrc[i] = (q31_t)(fSrc[i] * 2147483648.0f); } } else { for (i = 0; i < S->fftLen * 2; i++) { // read the float data, scale up for q31, cast to q31 pSrc[i] = (q31_t)(fSrc[i] * 2147483648.0f / (float32_t)S->fftLen); } } } void ref_cfft_radix2_q15(const riscv_cfft_radix2_instance_q15 *S, q15_t *pSrc) { uint32_t i; // float32_t *fSrc = (float32_t*)pSrc; float32_t fSrc[S->fftLen * 2]; riscv_q15_to_float(pSrc, fSrc, S->fftLen * 2); for (i = 0; i < S->fftLen * 2; i++) { // read the q15 data, cast to float, scale down for float, place in // temporary buffer scratchArray[i] = (float32_t)pSrc[i] / 32768.0f; } for (i = 0; i < S->fftLen * 2; i++) { // copy from temp buffer to final buffer fSrc[i] = scratchArray[i]; } switch (S->fftLen) { case 16: ref_cfft_f32(&riscv_cfft_sR_f32_len16, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 32: ref_cfft_f32(&riscv_cfft_sR_f32_len32, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 64: ref_cfft_f32(&riscv_cfft_sR_f32_len64, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 128: ref_cfft_f32(&riscv_cfft_sR_f32_len128, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 256: ref_cfft_f32(&riscv_cfft_sR_f32_len256, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 512: ref_cfft_f32(&riscv_cfft_sR_f32_len512, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 1024: ref_cfft_f32(&riscv_cfft_sR_f32_len1024, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 2048: ref_cfft_f32(&riscv_cfft_sR_f32_len2048, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 4096: ref_cfft_f32(&riscv_cfft_sR_f32_len4096, fSrc, S->ifftFlag, S->bitReverseFlag); break; } if (S->ifftFlag) { for (i = 0; i < S->fftLen * 2; i++) { // read the float data, scale up for q15, cast to q15 pSrc[i] = (q15_t)(fSrc[i] * 32768.0f); } } else { for (i = 0; i < S->fftLen * 2; i++) { // read the float data, scale up for q15, cast to q15 pSrc[i] = (q15_t)(fSrc[i] * 32768.0f / (float32_t)S->fftLen); } } } void ref_cfft_radix4_f32(const riscv_cfft_radix4_instance_f32 *S, float32_t *pSrc) { switch (S->fftLen) { case 16: ref_cfft_f32(&riscv_cfft_sR_f32_len16, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 32: ref_cfft_f32(&riscv_cfft_sR_f32_len32, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 64: ref_cfft_f32(&riscv_cfft_sR_f32_len64, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 128: ref_cfft_f32(&riscv_cfft_sR_f32_len128, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 256: ref_cfft_f32(&riscv_cfft_sR_f32_len256, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 512: ref_cfft_f32(&riscv_cfft_sR_f32_len512, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 1024: ref_cfft_f32(&riscv_cfft_sR_f32_len1024, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 2048: ref_cfft_f32(&riscv_cfft_sR_f32_len2048, pSrc, S->ifftFlag, S->bitReverseFlag); break; case 4096: ref_cfft_f32(&riscv_cfft_sR_f32_len4096, pSrc, S->ifftFlag, S->bitReverseFlag); break; } } void ref_cfft_radix4_q31(const riscv_cfft_radix4_instance_q31 *S, q31_t *pSrc) { uint32_t i; // float32_t *fSrc = (float32_t*)pSrc; float32_t fSrc[S->fftLen * 2]; riscv_q31_to_float(pSrc, fSrc, S->fftLen * 2); for (i = 0; i < S->fftLen * 2; i++) { // read the q31 data, cast to float, scale down for float fSrc[i] = (float32_t)pSrc[i] / 2147483648.0f; } switch (S->fftLen) { case 16: ref_cfft_f32(&riscv_cfft_sR_f32_len16, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 32: ref_cfft_f32(&riscv_cfft_sR_f32_len32, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 64: ref_cfft_f32(&riscv_cfft_sR_f32_len64, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 128: ref_cfft_f32(&riscv_cfft_sR_f32_len128, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 256: ref_cfft_f32(&riscv_cfft_sR_f32_len256, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 512: ref_cfft_f32(&riscv_cfft_sR_f32_len512, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 1024: ref_cfft_f32(&riscv_cfft_sR_f32_len1024, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 2048: ref_cfft_f32(&riscv_cfft_sR_f32_len2048, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 4096: ref_cfft_f32(&riscv_cfft_sR_f32_len4096, fSrc, S->ifftFlag, S->bitReverseFlag); break; } if (S->ifftFlag) { for (i = 0; i < S->fftLen * 2; i++) { // read the float data, scale up for q31, cast to q31 pSrc[i] = (q31_t)(fSrc[i] * 2147483648.0f); } } else { for (i = 0; i < S->fftLen * 2; i++) { // read the float data, scale up for q31, cast to q31 pSrc[i] = (q31_t)(fSrc[i] * 2147483648.0f / (float32_t)S->fftLen); } } } void ref_cfft_radix4_q15(const riscv_cfft_radix4_instance_q15 *S, q15_t *pSrc) { uint32_t i; // float32_t *fSrc = (float32_t*)pSrc; float32_t fSrc[S->fftLen * 2]; riscv_q15_to_float(pSrc, fSrc, S->fftLen * 2); for (i = 0; i < S->fftLen * 2; i++) { // read the q15 data, cast to float, scale down for float, place in // temporary buffer scratchArray[i] = (float32_t)pSrc[i] / 32768.0f; } for (i = 0; i < S->fftLen * 2; i++) { // copy from temp buffer to final buffer fSrc[i] = scratchArray[i]; } switch (S->fftLen) { case 16: ref_cfft_f32(&riscv_cfft_sR_f32_len16, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 32: ref_cfft_f32(&riscv_cfft_sR_f32_len32, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 64: ref_cfft_f32(&riscv_cfft_sR_f32_len64, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 128: ref_cfft_f32(&riscv_cfft_sR_f32_len128, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 256: ref_cfft_f32(&riscv_cfft_sR_f32_len256, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 512: ref_cfft_f32(&riscv_cfft_sR_f32_len512, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 1024: ref_cfft_f32(&riscv_cfft_sR_f32_len1024, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 2048: ref_cfft_f32(&riscv_cfft_sR_f32_len2048, fSrc, S->ifftFlag, S->bitReverseFlag); break; case 4096: ref_cfft_f32(&riscv_cfft_sR_f32_len4096, fSrc, S->ifftFlag, S->bitReverseFlag); break; } if (S->ifftFlag) { for (i = 0; i < S->fftLen * 2; i++) { // read the float data, scale up for q15, cast to q15 pSrc[i] = (q15_t)(fSrc[i] * 32768.0f); } } else { for (i = 0; i < S->fftLen * 2; i++) { // read the float data, scale up for q15, cast to q15 pSrc[i] = (q15_t)(fSrc[i] * 32768.0f / (float32_t)S->fftLen); } } }