CMSIS-DSP: DSP_Lib_TestSuite can be built with cmake.

DSP_Lib_TestSuite can be built with cmake and run on FVP.
Some issues with CMSIS-DSP cmake where discovered and corrected.

Comments added to arm_biqaud_cascade_df2T+f32 since the Neon version
must be initialized differently (and thus the corresponding test
in DSP_Lib_TestSuite will have to be updated to pass with Neon version).
pull/19/head
Christophe Favergeon 7 years ago
parent c0f96fe5d8
commit bf1f324a6d

@ -0,0 +1,86 @@
cmake_minimum_required (VERSION 3.6)
cmake_policy(SET CMP0077 NEW)
# The tests are assuming that MATRIX_CHECK is enabled when building
# CMSIS-DSP.
set(MATRIXCHECK ON)
set(FASTMATHCOMPUTATIONS OFF)
option(DUMPPATTERN "Dump test patterns when test is failing" ON)
project(DSP_Lib_TestSuite)
# Needed to find the config modules
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/..)
set(ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
file(GLOB MAIN "Common/src/*.c")
file(GLOB BASICMATH_TESTS "Common/src/basic_math_tests/*.c")
file(GLOB COMPLEXMATH_TESTS "Common/src/complex_math_tests/*.c")
file(GLOB CONTROLLER_TESTS "Common/src/controller_tests/*.c")
file(GLOB FASTMATH_TESTS "Common/src/fast_math_tests/*.c")
file(GLOB FILTERING_TESTS "Common/src/filtering_tests/*.c")
file(GLOB INTRINSINCS_TESTS "Common/src/intrinsics_tests/*.c")
file(GLOB MATRIX_TESTS "Common/src/matrix_tests/*.c")
file(GLOB STATISTICS_TESTS "Common/src/statistics_tests/*.c")
file(GLOB SUPPORT_TESTS "Common/src/support_tests/*.c")
file(GLOB TRANSFORM_TESTS "Common/src/transform_tests/*.c")
file(GLOB JTEST_MAIN "Common/JTest/src/*.c")
set(TESTSRC ${MAIN}
${BASICMATH_TESTS}
${COMPLEXMATH_TESTS}
${CONTROLLER_TESTS}
${FASTMATH_TESTS}
${FILTERING_TESTS}
${INTRINSINCS_TESTS}
${MATRIX_TESTS}
${STATISTICS_TESTS}
${SUPPORT_TESTS}
${TRANSFORM_TESTS}
${JTEST_MAIN}
)
set(JINCS
Common/JTest/inc
Common/JTest/inc/arr_desc
Common/inc/basic_math_tests
Common/inc/complex_math_tests
Common/inc/controller_tests
Common/inc/fast_math_tests
Common/inc/filtering_tests
Common/inc/intrinsics_tests
Common/inc/matrix_tests
Common/inc/statistics_tests
Common/inc/support_tests
Common/inc/transform_tests
)
add_subdirectory(../Source bin_dsp)
add_subdirectory(RefLibs bin_ref)
add_executable(DSP_Lib_TestSuite)
if (DUMPPATTERN)
target_compile_definitions(DSP_Lib_TestSuite PRIVATE DUMPPATTERN)
endif()
# Change behavior of configBoot for scatter file
set(TESTFRAMEWORK ON)
include(configBoot)
file(COPY ${ROOT}/CMSIS/DSP/Examples/ARM/boot/RTE_Components.h DESTINATION tempLink)
target_link_libraries(DSP_Lib_TestSuite PRIVATE CMSISDSP)
target_link_libraries(DSP_Lib_TestSuite PRIVATE DspRefLibs)
target_sources(DSP_Lib_TestSuite PRIVATE ${TESTSRC})
### Includes
target_include_directories(DSP_Lib_TestSuite PRIVATE "Common/inc")
target_include_directories(DSP_Lib_TestSuite PRIVATE "Common/inc/templates")
target_include_directories(DSP_Lib_TestSuite PRIVATE ${JINCS})

@ -141,13 +141,13 @@ typedef struct JTEST_FW_struct
* Fill the buffer named buf_name with value and dump it to the Keil debugger
* using action.
*/
#ifdef ARMv7A
#if defined(ARMv7A) || defined(FILEIO)
#define JTEST_ACT_DUMP(action, buf_name, value) \
do \
{ \
JTEST_CLEAR_BUFFER(buf_name); \
printf("%s",value); \
printf("%s",value); \
strcpy(JTEST_FW.buf_name, (value)); \
JTEST_TRIGGER_ACTION(action); \
} while (0)
@ -206,7 +206,7 @@ typedef struct JTEST_FW_struct
/**
* Dump a formatted string to the Keil Debugger.
*/
#ifdef ARMv7A
#if defined(ARMv7A) || defined(FILEIO)
#define JTEST_DUMP_STRF(format_str, ... ) \
do \

@ -62,25 +62,45 @@
/**
* Assert that buffers A and B are byte-equivalent for a number of bytes.
*/
#if defined(DUMPPATTERN)
#define TEST_ASSERT_BUFFERS_EQUAL(buf_a, buf_b, bytes) \
do \
{ \
if (memcmp(buf_a, buf_b, bytes) != 0) \
{ \
JTEST_DUMP_STRF("%s","DUMP PATTERNS\n"); \
for(unsigned long i=0;i < bytes; i++) \
{ \
/*JTEST_DUMP_STRF("%0x %0x\n", *a,*b);*/\
} \
return JTEST_TEST_FAILED; \
} \
} while (0)
#else
#define TEST_ASSERT_BUFFERS_EQUAL(buf_a, buf_b, bytes)\
do \
{ \
if (memcmp(buf_a, buf_b, bytes) != 0) \
{ \
return JTEST_TEST_FAILED; \
} \
} while (0)
#endif
/**
* Assert that the two entities are equal.
*/
#define TEST_ASSERT_EQUAL(a, b) \
do \
{ \
if ((a) != (b)) \
{ \
return JTEST_TEST_FAILED; \
} \
#define TEST_ASSERT_EQUAL(a, b) \
do \
{ \
if ((a) != (b)) \
{ \
return JTEST_TEST_FAILED;\
} \
} while (0)
/**
@ -111,31 +131,74 @@
* Assert that the SNR between a reference and test sample is above a given
* threshold.
*/
#define TEST_ASSERT_SNR(ref_ptr, tst_ptr, block_size, threshold) \
#if defined(DUMPPATTERN)
#define TEST_ASSERT_SNR(ref_ptr, tst_ptr, block_size, threshold) \
do \
{ \
float32_t snr = arm_snr_f32(ref_ptr, tst_ptr, block_size);\
if ( snr <= threshold) \
{ \
JTEST_DUMP_STRF("%s","DUMP PATTERNS\n"); \
for(unsigned long i=0;i < block_size; i++) \
{ \
/*JTEST_DUMP_STRF("%f %f\n", ref_ptr[i],tst_ptr[i]);*/\
} \
JTEST_DUMP_STRF("SNR: %f\n", snr); \
return JTEST_TEST_FAILED; \
} \
} while (0)
#else
#define TEST_ASSERT_SNR(ref_ptr, tst_ptr, block_size, threshold) \
do \
{ \
float32_t snr = arm_snr_f32(ref_ptr, tst_ptr, block_size);\
if ( snr <= threshold) \
{ \
JTEST_DUMP_STRF("SNR: %f\n", snr); \
return JTEST_TEST_FAILED; \
} \
} while (0)
#endif
/**
* Assert that the SNR between a reference and test sample is above a given
* threshold. Special case for float64_t
*/
#if defined(DUMPPATTERN)
#define TEST_ASSERT_DBL_SNR(ref_ptr, tst_ptr, block_size, threshold)\
do \
{ \
float32_t snr = arm_snr_f32(ref_ptr, tst_ptr, block_size); \
if ( snr <= threshold) \
float64_t snr = arm_snr_f64(ref_ptr, tst_ptr, block_size); \
if ( snr <= threshold) \
{ \
JTEST_DUMP_STRF("%s","DUMP PATTERNS\n"); \
for(unsigned long i=0;i < block_size; i++) \
{ \
/* JTEST_DUMP_STRF("%f %f\n", ref_ptr[i],tst_ptr[i]);*/ \
} \
JTEST_DUMP_STRF("SNR: %f\n", snr); \
return JTEST_TEST_FAILED; \
} \
} while (0) \
} while (0)
/**
* Assert that the SNR between a reference and test sample is above a given
* threshold. Special case for float64_t
*/
#define TEST_ASSERT_DBL_SNR(ref_ptr, tst_ptr, block_size, threshold) \
#else
#define TEST_ASSERT_DBL_SNR(ref_ptr, tst_ptr, block_size, threshold)\
do \
{ \
float64_t snr = arm_snr_f64(ref_ptr, tst_ptr, block_size); \
if ( snr <= threshold) \
if ( snr <= threshold) \
{ \
JTEST_DUMP_STRF("SNR: %f\n", snr); \
return JTEST_TEST_FAILED; \
} \
} while (0) \
} while (0)
#endif
/**
* Compare test and reference elements by converting to float and

@ -21,6 +21,9 @@ JTEST_DEFINE_GROUP(all_tests)
JTEST_GROUP_CALL(complex_math_tests);
JTEST_GROUP_CALL(controller_tests);
JTEST_GROUP_CALL(fast_math_tests);
/* Biquad df2T_f32 will fail with Neon. The test must be updated.
Neon implementation is requiring a different initialization.
*/
JTEST_GROUP_CALL(filtering_tests);
JTEST_GROUP_CALL(matrix_tests);
JTEST_GROUP_CALL(statistics_tests);

@ -16,12 +16,16 @@ void debug_init(void)
int main(void)
{
#if !defined(FILEIO)
debug_init();
#endif
JTEST_INIT(); /* Initialize test framework. */
JTEST_GROUP_CALL(all_tests); /* Run all tests. */
JTEST_ACT_EXIT_FW(); /* Exit test framework. */
#if !defined(FILEIO)
while (1); /* Never return. */
#endif
}

@ -0,0 +1,78 @@
cmake_minimum_required (VERSION 3.6)
project(DspRefLibs)
# Needed to find the config modules
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../..)
set(REFSRC src/BasicMathFunctions/abs.c
src/BasicMathFunctions/add.c
src/BasicMathFunctions/dot_prod.c
src/BasicMathFunctions/mult.c
src/BasicMathFunctions/negate.c
src/BasicMathFunctions/offset.c
src/BasicMathFunctions/scale.c
src/BasicMathFunctions/shift.c
src/BasicMathFunctions/sub.c
src/ComplexMathFunctions/cmplx_conj.c
src/ComplexMathFunctions/cmplx_dot_prod.c
src/ComplexMathFunctions/cmplx_mag.c
src/ComplexMathFunctions/cmplx_mag_squared.c
src/ComplexMathFunctions/cmplx_mult_cmplx.c
src/ComplexMathFunctions/cmplx_mult_real.c
src/ControllerFunctions/pid.c
src/ControllerFunctions/sin_cos.c
src/FastMathFunctions/cos.c
src/FastMathFunctions/sin.c
src/FastMathFunctions/sqrt.c
src/FilteringFunctions/biquad.c
src/FilteringFunctions/conv.c
src/FilteringFunctions/correlate.c
src/FilteringFunctions/fir.c
src/FilteringFunctions/fir_decimate.c
src/FilteringFunctions/fir_interpolate.c
src/FilteringFunctions/fir_lattice.c
src/FilteringFunctions/fir_sparse.c
src/FilteringFunctions/iir_lattice.c
src/FilteringFunctions/lms.c
src/HelperFunctions/mat_helper.c
src/HelperFunctions/ref_helper.c
src/Intrinsics/intrinsics.c
src/MatrixFunctions/mat_add.c
src/MatrixFunctions/mat_cmplx_mult.c
src/MatrixFunctions/mat_inverse.c
src/MatrixFunctions/mat_mult.c
src/MatrixFunctions/mat_scale.c
src/MatrixFunctions/mat_sub.c
src/MatrixFunctions/mat_trans.c
src/StatisticsFunctions/max.c
src/StatisticsFunctions/mean.c
src/StatisticsFunctions/min.c
src/StatisticsFunctions/power.c
src/StatisticsFunctions/rms.c
src/StatisticsFunctions/std.c
src/StatisticsFunctions/var.c
src/SupportFunctions/copy.c
src/SupportFunctions/fill.c
src/SupportFunctions/fixed_to_fixed.c
src/SupportFunctions/fixed_to_float.c
src/SupportFunctions/float_to_fixed.c
src/TransformFunctions/bitreversal.c
src/TransformFunctions/cfft.c
src/TransformFunctions/dct4.c
src/TransformFunctions/rfft.c
)
add_library(DspRefLibs STATIC ${REFSRC})
include(config)
configdsp(DspRefLibs ../../Source)
### Includes
target_include_directories(DspRefLibs PUBLIC "inc")
target_include_directories(DspRefLibs PUBLIC "../../Include")

@ -59,10 +59,15 @@ extern "C"
} dataType;
#ifndef FLT_MAX
#define FLT_MAX 3.40282347e+38F
#endif
#define DBL_MAX 1.79769313486231571e+308
#ifndef FLT_MIN
#define FLT_MIN 1.175494351e-38F
#endif
#define DBL_MIN 2.22507385850720138e-308
#define SCHAR_MIN (-128)

@ -8,7 +8,7 @@
;* @param[in] *pBitRevTab points to bit reversal table.
;* @return none.
;*/
void arm_bitreversal_32(uint32_t *pSrc, uint32_t bitRevLen, uint32_t *pBitRevTab)
void ref_arm_bitreversal_32(uint32_t *pSrc, uint32_t bitRevLen, uint32_t *pBitRevTab)
{
uint32_t a,b,i,tmp;

@ -27,6 +27,8 @@ add_subdirectory(../../../Source bin_dsp)
add_executable(arm_variance_example)
set(ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../../../..)
include(configBoot)
target_sources(arm_variance_example PRIVATE arm_variance_example_f32.c)

@ -320,6 +320,7 @@
#include "string.h"
#include "math.h"
#include "float.h"
/* evaluate ARM DSP feature */
#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1))
@ -817,8 +818,6 @@ compiler file in Core or Core_A would not make sense.
#if defined(ARM_MATH_NEON)
#define FLT_MIN 1E-37
static inline float32x4_t __arm_vec_sqrt_f32_neon(float32x4_t x)
{
float32x4_t x1 = vmaxq_f32(x, vdupq_n_f32(FLT_MIN));

@ -2,8 +2,7 @@ cmake_minimum_required (VERSION 3.6)
project(CMSISDSPController)
add_library(CMSISDSPController STATIC ${SRC})
add_library(CMSISDSPController STATIC)
configdsp(CMSISDSPController ..)

@ -3,7 +3,7 @@ cmake_minimum_required (VERSION 3.6)
project(CMSISDSPFiltering)
add_library(CMSISDSPFiltering STATIC ${SRC})
add_library(CMSISDSPFiltering STATIC)
include(interpol)
interpol(CMSISDSPFiltering)

@ -46,14 +46,39 @@
@return none
@par Coefficient and State Ordering
The coefficients are stored in the array <code>pCoeffs</code> in the following order:
The coefficients are stored in the array <code>pCoeffs</code> in the following order
in the not Neon version.
<pre>
{b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
</pre>
@par
where <code>b1x</code> and <code>a1x</code> are the coefficients for the first stage,
<code>b2x</code> and <code>a2x</code> are the coefficients for the second stage,
and so on. The <code>pCoeffs</code> array contains a total of <code>5*numStages</code> values.
For Neon version, this array is bigger. If numstages = 4x + y, then the array has size:
32*x + 5*y
and it must be initialized using the function
arm_biquad_cascade_df2T_compute_coefs_f32 which is taking the
standard array coefficient as parameters.
But, an array of 8*numstages is a good approximation.
Then, the initialization can be done with:
<pre>
arm_biquad_cascade_df2T_init_f32(&SNeon, nbCascade, neonCoefs, stateNeon);
arm_biquad_cascade_df2T_compute_coefs_f32(&SNeon,nbCascade,coefs);
</pre>
@par In this example, neonCoefs is a bigger array of size 8 * numStages.
coefs is the standard array:
<pre>
{b10, b11, b12, a11, a12, b20, b21, b22, a21, a22, ...}
</pre>
@par
The <code>pState</code> is a pointer to state array.
Each Biquad stage has 2 state variables <code>d1,</code> and <code>d2</code>.
@ -63,6 +88,16 @@
*/
#if defined(ARM_MATH_NEON)
/*
Must be called after initializing the biquad instance.
pCoeffs has size 5 * nbCascade
Whereas the pCoeffs for the init has size (4*4 + 4*4)* nbCascade
So this pCoeffs is the one which would be used for the not Neon version.
The pCoeffs passed in init is bigger than the one for the not Neon version.
*/
void arm_biquad_cascade_df2T_compute_coefs_f32(
arm_biquad_cascade_df2T_instance_f32 * S,
uint8_t numStages,

@ -38,6 +38,10 @@ target_sources(CMSISDSPTransform PRIVATE arm_cfft_radix4_q31.c)
target_sources(CMSISDSPTransform PRIVATE arm_cfft_q31.c)
endif()
if (NOT CONFIGTABLE OR ALLFFT)
target_sources(CMSISDSPTransform PRIVATE arm_cfft_radix2_init_q15.c)
target_sources(CMSISDSPTransform PRIVATE arm_cfft_radix2_init_q31.c)
endif()
if (NOT CONFIGTABLE OR ALLFFT OR DCT4_F32_128 OR DCT4_F32_512 OR DCT4_F32_2048 OR DCT4_F32_8192)
target_sources(CMSISDSPTransform PRIVATE arm_dct4_f32.c)

@ -1,7 +1,8 @@
include(CMakePrintHelpers)
cmake_policy(SET CMP0077 NEW)
SET(CORTEXM ON)
option(FASTMATH "Fast Math enabled" ON)
option(FASTMATHCOMPUTATIONS "Fast Math enabled" ON)
option(NEON "Neon acceleration" OFF)
option(NEONEXPERIMENTAL "Neon experimental acceleration" OFF)
option(LOOPUNROLL "Loop unrolling" ON)
@ -22,7 +23,7 @@ function(configdsp PROJECTNAME DSP)
target_compile_definitions(${PROJECTNAME} PUBLIC ARM_DSP_CONFIG_TABLES)
endif()
if (FASTMATH)
if (FASTMATHCOMPUTATIONS)
target_compile_options(${PROJECTNAME} PUBLIC "-ffast-math")
endif()

@ -16,7 +16,7 @@ get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
cmake_print_variables(PROJECT_NAME)
set(ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../../../..)
#set(ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../../../..)
if (ARMAC6)
@ -90,6 +90,7 @@ if (ARMAC6)
#
if (ARM_CPU STREQUAL "cortex-a5")
cortexa(ARMCA5)
target_compile_definitions(${PROJECT_NAME} PRIVATE ARMv7A)
endif()
###################
@ -98,6 +99,7 @@ if (ARMAC6)
#
if (ARM_CPU STREQUAL "cortex-a7")
cortexa(ARMCA7)
target_compile_definitions(${PROJECT_NAME} PRIVATE ARMv7A)
endif()
###################
@ -106,6 +108,7 @@ if (ARMAC6)
#
if (ARM_CPU STREQUAL "cortex-a9")
cortexa(ARMCA9)
target_compile_definitions(${PROJECT_NAME} PRIVATE ARMv7A)
endif()
endif()

@ -4,7 +4,13 @@ function(cortexm CORE)
target_include_directories(${PROJECT_NAME} PRIVATE ${ROOT}/Device/ARM/${CORE}/Include)
target_include_directories(${PROJECT_NAME} PRIVATE ${ROOT}/CMSIS/Core/Include)
set(SCATTERFILE "${ROOT}/Device/ARM/${CORE}/Source/ARM/${CORE}_ac6.sct")
if (TESTFRAMEWORK)
# Need bigger sections for test framework
# So we use the test framework scatter file
set(SCATTERFILE "${ROOT}/CMSIS/DSP/DSP_Lib_TestSuite/Common/platform/ARMCLANG/armcc6_arm.sct")
else()
set(SCATTERFILE "${ROOT}/Device/ARM/${CORE}/Source/ARM/${CORE}_ac6.sct")
endif()
target_link_options(${PROJECT_NAME} PRIVATE "--info=sizes;--entry=Reset_Handler;--scatter=${SCATTERFILE}")
@ -20,9 +26,18 @@ function(cortexa CORE)
target_include_directories(${PROJECT_NAME} PRIVATE ${ROOT}/CMSIS/Core_A/Include)
target_sources(${PROJECT_NAME} PRIVATE ${ROOT}/Device/ARM/${CORE}/Source/AC6/startup_${CORE}.c)
set(SCATTERFILE ${CMAKE_CURRENT_BINARY_DIR}/tempLink/${CORE}.sct)
target_include_directories(${PROJECT_NAME} PRIVATE ../boot)
if (TESTFRAMEWORK)
# Test scatter file is missing some sections required by startup file for
# cortex-a
#set(SCATTERFILE "${ROOT}/CMSIS/DSP/DSP_Lib_TestSuite/Common/platform/ARMCLANG/armcc6_arm.sct")
target_include_directories(${PROJECT_NAME} PRIVATE ../Examples/ARM/boot)
else()
target_include_directories(${PROJECT_NAME} PRIVATE ../boot)
endif()
set(SCATTERFILE ${CMAKE_CURRENT_BINARY_DIR}/tempLink/${CORE}.sct)
# Copy the mem file to the build directory
# so that it can be find when preprocessing the scatter file

Loading…
Cancel
Save