diff options
Diffstat (limited to 'Drivers/CMSIS/DSP/Source/FilteringFunctions/arm_correlate_q15.c')
-rw-r--r-- | Drivers/CMSIS/DSP/Source/FilteringFunctions/arm_correlate_q15.c | 259 |
1 files changed, 124 insertions, 135 deletions
diff --git a/Drivers/CMSIS/DSP/Source/FilteringFunctions/arm_correlate_q15.c b/Drivers/CMSIS/DSP/Source/FilteringFunctions/arm_correlate_q15.c index ce86db409..98378750e 100644 --- a/Drivers/CMSIS/DSP/Source/FilteringFunctions/arm_correlate_q15.c +++ b/Drivers/CMSIS/DSP/Source/FilteringFunctions/arm_correlate_q15.c @@ -3,13 +3,13 @@ * Title: arm_correlate_q15.c * Description: Correlation of Q15 sequences * - * $Date: 27. January 2017 - * $Revision: V.1.5.1 + * $Date: 18. March 2019 + * $Revision: V1.6.0 * * Target Processor: Cortex-M cores * -------------------------------------------------------------------- */ /* - * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved. + * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * @@ -29,64 +29,58 @@ #include "arm_math.h" /** - * @ingroup groupFilters + @ingroup groupFilters */ /** - * @addtogroup Corr - * @{ + @addtogroup Corr + @{ */ /** - * @brief Correlation of Q15 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the location where the output result is written. Length 2 * max(srcALen, srcBLen) - 1. - * @return none. - * - * @details - * <b>Scaling and Overflow Behavior:</b> - * - * \par - * The function is implemented using a 64-bit internal accumulator. - * Both inputs are in 1.15 format and multiplications yield a 2.30 result. - * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. - * This approach provides 33 guard bits and there is no risk of overflow. - * The 34.30 result is then truncated to 34.15 format by discarding the low 15 bits and then saturated to 1.15 format. - * - * \par - * Refer to <code>arm_correlate_fast_q15()</code> for a faster but less precise version of this function for Cortex-M3 and Cortex-M4. - * - * \par - * Refer the function <code>arm_correlate_opt_q15()</code> for a faster implementation of this function using scratch buffers. - * + @brief Correlation of Q15 sequences. + @param[in] pSrcA points to the first input sequence + @param[in] srcALen length of the first input sequence + @param[in] pSrcB points to the second input sequence + @param[in] srcBLen length of the second input sequence + @param[out] pDst points to the location where the output result is written. Length 2 * max(srcALen, srcBLen) - 1. + @return none + + @par Scaling and Overflow Behavior + The function is implemented using a 64-bit internal accumulator. + Both inputs are in 1.15 format and multiplications yield a 2.30 result. + The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. + This approach provides 33 guard bits and there is no risk of overflow. + The 34.30 result is then truncated to 34.15 format by discarding the low 15 bits and then saturated to 1.15 format. + + @remark + Refer to \ref arm_correlate_fast_q15() for a faster but less precise version of this function. + @remark + Refer to \ref arm_correlate_opt_q15() for a faster implementation of this function using scratch buffers. */ void arm_correlate_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst) + const q15_t * pSrcA, + uint32_t srcALen, + const q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst) { -#if (defined(ARM_MATH_CM7) || defined(ARM_MATH_CM4) || defined(ARM_MATH_CM3)) && !defined(UNALIGNED_SUPPORT_DISABLE) - - /* Run the below code for Cortex-M4 and Cortex-M3 */ - - q15_t *pIn1; /* inputA pointer */ - q15_t *pIn2; /* inputB pointer */ - q15_t *pOut = pDst; /* output pointer */ - q63_t sum, acc0, acc1, acc2, acc3; /* Accumulators */ - q15_t *px; /* Intermediate inputA pointer */ - q15_t *py; /* Intermediate inputB pointer */ - q15_t *pSrc1; /* Intermediate pointers */ - q31_t x0, x1, x2, x3, c0; /* temporary variables for holding input and coefficient values */ - uint32_t j, k = 0U, count, blkCnt, outBlockSize, blockSize1, blockSize2, blockSize3; /* loop counter */ - int32_t inc = 1; /* Destination address modifier */ - +#if defined (ARM_MATH_DSP) + + const q15_t *pIn1; /* InputA pointer */ + const q15_t *pIn2; /* InputB pointer */ + q15_t *pOut = pDst; /* Output pointer */ + q63_t sum, acc0, acc1, acc2, acc3; /* Accumulators */ + const q15_t *px; /* Intermediate inputA pointer */ + const q15_t *py; /* Intermediate inputB pointer */ + const q15_t *pSrc1; /* Intermediate pointers */ + q31_t x0, x1, x2, x3, c0; /* Temporary input variables for holding input and coefficient values */ + uint32_t blockSize1, blockSize2, blockSize3; /* Loop counters */ + uint32_t j, k, count, blkCnt; /* Loop counters */ + uint32_t outBlockSize; + int32_t inc = 1; /* Destination address modifier */ /* The algorithm implementation is based on the lengths of the inputs. */ /* srcB is always made to slide across srcA. */ @@ -104,13 +98,13 @@ void arm_correlate_q15( if (srcALen >= srcBLen) { /* Initialization of inputA pointer */ - pIn1 = (pSrcA); + pIn1 = pSrcA; /* Initialization of inputB pointer */ - pIn2 = (pSrcB); + pIn2 = pSrcB; /* Number of output samples is calculated */ - outBlockSize = (2U * srcALen) - 1U; + outBlockSize = (srcALen * 2U) - 1U; /* When srcALen > srcBLen, zero padding is done to srcB * to make their lengths equal. @@ -120,15 +114,14 @@ void arm_correlate_q15( /* Updating the pointer position to non zero value */ pOut += j; - } else { /* Initialization of inputA pointer */ - pIn1 = (pSrcB); + pIn1 = pSrcB; /* Initialization of inputB pointer */ - pIn2 = (pSrcA); + pIn2 = pSrcA; /* srcBLen is always considered as shorter or equal to srcALen */ j = srcBLen; @@ -141,18 +134,18 @@ void arm_correlate_q15( /* Destination address modifier is set to -1 */ inc = -1; - } /* The function is internally - * divided into three parts according to the number of multiplications that has to be - * taken place between inputA samples and inputB samples. In the first part of the + * divided into three stages according to the number of multiplications that has to be + * taken place between inputA samples and inputB samples. In the first stage of the * algorithm, the multiplications increase by one for every iteration. - * In the second part of the algorithm, srcBLen number of multiplications are done. - * In the third part of the algorithm, the multiplications decrease by one - * for every iteration.*/ + * In the second stage of the algorithm, srcBLen number of multiplications are done. + * In the third stage of the algorithm, the multiplications decrease by one + * for every iteration. */ + /* The algorithm is implemented in three stages. - * The loop counters of each stage is initiated here. */ + The loop counters of each stage is initiated here. */ blockSize1 = srcBLen - 1U; blockSize2 = srcALen - (srcBLen - 1U); blockSize3 = blockSize1; @@ -189,18 +182,19 @@ void arm_correlate_q15( sum = 0; /* Apply loop unrolling and compute 4 MACs simultaneously. */ - k = count >> 2; + k = count >> 2U; /* First part of the processing with loop unrolling. Compute 4 MACs at a time. ** a second loop below computes MACs for the remaining 1 to 3 samples. */ while (k > 0U) { + /* Perform the multiply-accumulate */ /* x[0] * y[srcBLen - 4] , x[1] * y[srcBLen - 3] */ - sum = __SMLALD(*__SIMD32(px)++, *__SIMD32(py)++, sum); + sum = __SMLALD(read_q15x2_ia ((q15_t **) &px), read_q15x2_ia ((q15_t **) &py), sum); /* x[3] * y[srcBLen - 1] , x[2] * y[srcBLen - 2] */ - sum = __SMLALD(*__SIMD32(px)++, *__SIMD32(py)++, sum); + sum = __SMLALD(read_q15x2_ia ((q15_t **) &px), read_q15x2_ia ((q15_t **) &py), sum); - /* Decrement the loop counter */ + /* Decrement loop counter */ k--; } @@ -210,11 +204,11 @@ void arm_correlate_q15( while (k > 0U) { - /* Perform the multiply-accumulates */ + /* Perform the multiply-accumulate */ /* x[0] * y[srcBLen - 1] */ sum = __SMLALD(*px++, *py++, sum); - /* Decrement the loop counter */ + /* Decrement loop counter */ k--; } @@ -227,10 +221,10 @@ void arm_correlate_q15( py = pSrc1 - count; px = pIn1; - /* Increment the MAC count */ + /* Increment MAC count */ count++; - /* Decrement the loop counter */ + /* Decrement loop counter */ blockSize1--; } @@ -250,7 +244,7 @@ void arm_correlate_q15( /* Working pointer of inputB */ py = pIn2; - /* count is index by which the pointer pIn1 to be incremented */ + /* count is the index by which the pointer pIn1 to be incremented */ count = 0U; /* ------------------- @@ -259,10 +253,10 @@ void arm_correlate_q15( /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed. * So, to loop unroll over blockSize2, - * srcBLen should be greater than or equal to 4, to loop unroll the srcBLen loop */ + * srcBLen should be greater than or equal to 4 */ if (srcBLen >= 4U) { - /* Loop unroll over blockSize2, by 4 */ + /* Loop unrolling: Compute 4 outputs at a time */ blkCnt = blockSize2 >> 2U; while (blkCnt > 0U) @@ -274,9 +268,10 @@ void arm_correlate_q15( acc3 = 0; /* read x[0], x[1] samples */ - x0 = *__SIMD32(px); + x0 = read_q15x2 ((q15_t *) px); + /* read x[1], x[2] samples */ - x1 = _SIMD32_OFFSET(px + 1); + x1 = read_q15x2 ((q15_t *) px + 1); px += 2U; /* Apply loop unrolling and compute 4 MACs simultaneously. */ @@ -288,7 +283,7 @@ void arm_correlate_q15( { /* Read the first two inputB samples using SIMD: * y[0] and y[1] */ - c0 = *__SIMD32(py)++; + c0 = read_q15x2_ia ((q15_t **) &py); /* acc0 += x[0] * y[0] + x[1] * y[1] */ acc0 = __SMLALD(x0, c0, acc0); @@ -297,10 +292,10 @@ void arm_correlate_q15( acc1 = __SMLALD(x1, c0, acc1); /* Read x[2], x[3] */ - x2 = *__SIMD32(px); + x2 = read_q15x2 ((q15_t *) px); /* Read x[3], x[4] */ - x3 = _SIMD32_OFFSET(px + 1); + x3 = read_q15x2 ((q15_t *) px + 1); /* acc2 += x[2] * y[0] + x[3] * y[1] */ acc2 = __SMLALD(x2, c0, acc2); @@ -309,7 +304,7 @@ void arm_correlate_q15( acc3 = __SMLALD(x3, c0, acc3); /* Read y[2] and y[3] */ - c0 = *__SIMD32(py)++; + c0 = read_q15x2_ia ((q15_t **) &py); /* acc0 += x[2] * y[2] + x[3] * y[3] */ acc0 = __SMLALD(x2, c0, acc0); @@ -318,11 +313,10 @@ void arm_correlate_q15( acc1 = __SMLALD(x3, c0, acc1); /* Read x[4], x[5] */ - x0 = _SIMD32_OFFSET(px + 2); + x0 = read_q15x2 ((q15_t *) px + 2); /* Read x[5], x[6] */ - x1 = _SIMD32_OFFSET(px + 3); - + x1 = read_q15x2 ((q15_t *) px + 3); px += 4U; /* acc2 += x[4] * y[2] + x[5] * y[3] */ @@ -342,21 +336,18 @@ void arm_correlate_q15( /* Read y[4] */ c0 = *py; #ifdef ARM_MATH_BIG_ENDIAN - c0 = c0 << 16U; - #else - c0 = c0 & 0x0000FFFF; +#endif /* #ifdef ARM_MATH_BIG_ENDIAN */ -#endif /* #ifdef ARM_MATH_BIG_ENDIAN */ /* Read x[7] */ - x3 = *__SIMD32(px); + x3 = read_q15x2 ((q15_t *) px); px++; - /* Perform the multiply-accumulates */ - acc0 = __SMLALD(x0, c0, acc0); - acc1 = __SMLALD(x1, c0, acc1); + /* Perform the multiply-accumulate */ + acc0 = __SMLALD (x0, c0, acc0); + acc1 = __SMLALD (x1, c0, acc1); acc2 = __SMLALDX(x1, c0, acc2); acc3 = __SMLALDX(x3, c0, acc3); } @@ -364,16 +355,16 @@ void arm_correlate_q15( if (k == 2U) { /* Read y[4], y[5] */ - c0 = *__SIMD32(py); + c0 = read_q15x2 ((q15_t *) py); /* Read x[7], x[8] */ - x3 = *__SIMD32(px); + x3 = read_q15x2 ((q15_t *) px); /* Read x[9] */ - x2 = _SIMD32_OFFSET(px + 1); + x2 = read_q15x2 ((q15_t *) px + 1); px += 2U; - /* Perform the multiply-accumulates */ + /* Perform the multiply-accumulate */ acc0 = __SMLALD(x0, c0, acc0); acc1 = __SMLALD(x1, c0, acc1); acc2 = __SMLALD(x3, c0, acc2); @@ -383,15 +374,15 @@ void arm_correlate_q15( if (k == 3U) { /* Read y[4], y[5] */ - c0 = *__SIMD32(py)++; + c0 = read_q15x2_ia ((q15_t **) &py); /* Read x[7], x[8] */ - x3 = *__SIMD32(px); + x3 = read_q15x2 ((q15_t *) px); /* Read x[9] */ - x2 = _SIMD32_OFFSET(px + 1); + x2 = read_q15x2 ((q15_t *) px + 1); - /* Perform the multiply-accumulates */ + /* Perform the multiply-accumulate */ acc0 = __SMLALD(x0, c0, acc0); acc1 = __SMLALD(x1, c0, acc1); acc2 = __SMLALD(x3, c0, acc2); @@ -401,19 +392,18 @@ void arm_correlate_q15( /* Read y[6] */ #ifdef ARM_MATH_BIG_ENDIAN - c0 = c0 << 16U; #else - c0 = c0 & 0x0000FFFF; -#endif /* #ifdef ARM_MATH_BIG_ENDIAN */ +#endif /* #ifdef ARM_MATH_BIG_ENDIAN */ + /* Read x[10] */ - x3 = _SIMD32_OFFSET(px + 2); + x3 = read_q15x2 ((q15_t *) px + 2); px += 3U; /* Perform the multiply-accumulates */ acc0 = __SMLALDX(x1, c0, acc0); - acc1 = __SMLALD(x2, c0, acc1); + acc1 = __SMLALD (x2, c0, acc1); acc2 = __SMLALDX(x2, c0, acc2); acc3 = __SMLALDX(x3, c0, acc3); } @@ -439,7 +429,7 @@ void arm_correlate_q15( px = pIn1 + count; py = pIn2; - /* Decrement the loop counter */ + /* Decrement loop counter */ blkCnt--; } @@ -460,12 +450,12 @@ void arm_correlate_q15( while (k > 0U) { /* Perform the multiply-accumulates */ - sum += ((q63_t) * px++ * *py++); - sum += ((q63_t) * px++ * *py++); - sum += ((q63_t) * px++ * *py++); - sum += ((q63_t) * px++ * *py++); + sum += ((q63_t) *px++ * *py++); + sum += ((q63_t) *px++ * *py++); + sum += ((q63_t) *px++ * *py++); + sum += ((q63_t) *px++ * *py++); - /* Decrement the loop counter */ + /* Decrement loop counter */ k--; } @@ -476,7 +466,7 @@ void arm_correlate_q15( while (k > 0U) { /* Perform the multiply-accumulates */ - sum += ((q63_t) * px++ * *py++); + sum += ((q63_t) *px++ * *py++); /* Decrement the loop counter */ k--; @@ -509,13 +499,13 @@ void arm_correlate_q15( /* Accumulator is made zero for every iteration */ sum = 0; - /* Loop over srcBLen */ + /* srcBLen number of MACS should be performed */ k = srcBLen; while (k > 0U) { /* Perform the multiply-accumulate */ - sum += ((q63_t) * px++ * *py++); + sum += ((q63_t) *px++ * *py++); /* Decrement the loop counter */ k--; @@ -538,6 +528,7 @@ void arm_correlate_q15( } } + /* -------------------------- * Initializations of stage3 * -------------------------*/ @@ -576,13 +567,13 @@ void arm_correlate_q15( ** a second loop below computes MACs for the remaining 1 to 3 samples. */ while (k > 0U) { - /* Perform the multiply-accumulates */ + /* Perform the multiply-accumulate */ /* sum += x[srcALen - srcBLen + 4] * y[3] , sum += x[srcALen - srcBLen + 3] * y[2] */ - sum = __SMLALD(*__SIMD32(px)++, *__SIMD32(py)++, sum); + sum = __SMLALD(read_q15x2_ia ((q15_t **) &px), read_q15x2_ia ((q15_t **) &py), sum); /* sum += x[srcALen - srcBLen + 2] * y[1] , sum += x[srcALen - srcBLen + 1] * y[0] */ - sum = __SMLALD(*__SIMD32(px)++, *__SIMD32(py)++, sum); + sum = __SMLALD(read_q15x2_ia ((q15_t **) &px), read_q15x2_ia ((q15_t **) &py), sum); - /* Decrement the loop counter */ + /* Decrement loop counter */ k--; } @@ -592,10 +583,10 @@ void arm_correlate_q15( while (k > 0U) { - /* Perform the multiply-accumulates */ + /* Perform the multiply-accumulate */ sum = __SMLALD(*px++, *py++, sum); - /* Decrement the loop counter */ + /* Decrement loop counter */ k--; } @@ -608,23 +599,21 @@ void arm_correlate_q15( px = ++pSrc1; py = pIn2; - /* Decrement the MAC count */ + /* Decrement MAC count */ count--; - /* Decrement the loop counter */ + /* Decrement loop counter */ blockSize3--; } -#else - -/* Run the below code for Cortex-M0 */ +#else /* #if defined (ARM_MATH_DSP) */ - q15_t *pIn1 = pSrcA; /* inputA pointer */ - q15_t *pIn2 = pSrcB + (srcBLen - 1U); /* inputB pointer */ - q63_t sum; /* Accumulators */ - uint32_t i = 0U, j; /* loop counters */ - uint32_t inv = 0U; /* Reverse order flag */ - uint32_t tot = 0U; /* Length */ + const q15_t *pIn1 = pSrcA; /* InputA pointer */ + const q15_t *pIn2 = pSrcB + (srcBLen - 1U); /* InputB pointer */ + q63_t sum; /* Accumulators */ + uint32_t i = 0U, j; /* Loop counters */ + uint32_t inv = 0U; /* Reverse order flag */ + uint32_t tot = 0U; /* Length */ /* The algorithm implementation is based on the lengths of the inputs. */ /* srcB is always made to slide across srcA. */ @@ -672,10 +661,9 @@ void arm_correlate_q15( /* Setting the reverse flag */ inv = 1; - } - /* Loop to calculate convolution for output length number of times */ + /* Loop to calculate convolution for output length number of values */ for (i = 0U; i <= tot; i++) { /* Initialize sum with zero to carry on MAC operations */ @@ -685,12 +673,13 @@ void arm_correlate_q15( for (j = 0U; j <= i; j++) { /* Check the array limitations */ - if ((((i - j) < srcBLen) && (j < srcALen))) + if (((i - j) < srcBLen) && (j < srcALen)) { /* z[i] += x[i-j] * y[j] */ sum += ((q31_t) pIn1[j] * pIn2[-((int32_t) i - j)]); } } + /* Store the output in the destination buffer */ if (inv == 1) *pDst-- = (q15_t) __SSAT((sum >> 15U), 16U); @@ -698,10 +687,10 @@ void arm_correlate_q15( *pDst++ = (q15_t) __SSAT((sum >> 15U), 16U); } -#endif /* #if (defined(ARM_MATH_CM7) || defined(ARM_MATH_CM4) || defined(ARM_MATH_CM3)) && !defined(UNALIGNED_SUPPORT_DISABLE) */ +#endif /* #if defined (ARM_MATH_DSP) */ } /** - * @} end of Corr group + @} end of Corr group */ |