The CMSIS DSP 5 library

Dependents:   Nucleo-Heart-Rate ejercicioVrms2 PROYECTOFINAL ejercicioVrms ... more

Committer:
xorjoep
Date:
Thu Jun 21 11:56:27 2018 +0000
Revision:
3:4098b9d3d571
Parent:
1:24714b45cd1b
headers is a folder not a library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
xorjoep 1:24714b45cd1b 1 /* ----------------------------------------------------------------------
xorjoep 1:24714b45cd1b 2 * Project: CMSIS DSP Library
xorjoep 1:24714b45cd1b 3 * Title: arm_conv_f32.c
xorjoep 1:24714b45cd1b 4 * Description: Convolution of floating-point sequences
xorjoep 1:24714b45cd1b 5 *
xorjoep 1:24714b45cd1b 6 * $Date: 27. January 2017
xorjoep 1:24714b45cd1b 7 * $Revision: V.1.5.1
xorjoep 1:24714b45cd1b 8 *
xorjoep 1:24714b45cd1b 9 * Target Processor: Cortex-M cores
xorjoep 1:24714b45cd1b 10 * -------------------------------------------------------------------- */
xorjoep 1:24714b45cd1b 11 /*
xorjoep 1:24714b45cd1b 12 * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
xorjoep 1:24714b45cd1b 13 *
xorjoep 1:24714b45cd1b 14 * SPDX-License-Identifier: Apache-2.0
xorjoep 1:24714b45cd1b 15 *
xorjoep 1:24714b45cd1b 16 * Licensed under the Apache License, Version 2.0 (the License); you may
xorjoep 1:24714b45cd1b 17 * not use this file except in compliance with the License.
xorjoep 1:24714b45cd1b 18 * You may obtain a copy of the License at
xorjoep 1:24714b45cd1b 19 *
xorjoep 1:24714b45cd1b 20 * www.apache.org/licenses/LICENSE-2.0
xorjoep 1:24714b45cd1b 21 *
xorjoep 1:24714b45cd1b 22 * Unless required by applicable law or agreed to in writing, software
xorjoep 1:24714b45cd1b 23 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
xorjoep 1:24714b45cd1b 24 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
xorjoep 1:24714b45cd1b 25 * See the License for the specific language governing permissions and
xorjoep 1:24714b45cd1b 26 * limitations under the License.
xorjoep 1:24714b45cd1b 27 */
xorjoep 1:24714b45cd1b 28
xorjoep 1:24714b45cd1b 29 #include "arm_math.h"
xorjoep 1:24714b45cd1b 30
xorjoep 1:24714b45cd1b 31 /**
xorjoep 1:24714b45cd1b 32 * @ingroup groupFilters
xorjoep 1:24714b45cd1b 33 */
xorjoep 1:24714b45cd1b 34
xorjoep 1:24714b45cd1b 35 /**
xorjoep 1:24714b45cd1b 36 * @defgroup Conv Convolution
xorjoep 1:24714b45cd1b 37 *
xorjoep 1:24714b45cd1b 38 * Convolution is a mathematical operation that operates on two finite length vectors to generate a finite length output vector.
xorjoep 1:24714b45cd1b 39 * Convolution is similar to correlation and is frequently used in filtering and data analysis.
xorjoep 1:24714b45cd1b 40 * The CMSIS DSP library contains functions for convolving Q7, Q15, Q31, and floating-point data types.
xorjoep 1:24714b45cd1b 41 * The library also provides fast versions of the Q15 and Q31 functions on Cortex-M4 and Cortex-M3.
xorjoep 1:24714b45cd1b 42 *
xorjoep 1:24714b45cd1b 43 * \par Algorithm
xorjoep 1:24714b45cd1b 44 * Let <code>a[n]</code> and <code>b[n]</code> be sequences of length <code>srcALen</code> and <code>srcBLen</code> samples respectively.
xorjoep 1:24714b45cd1b 45 * Then the convolution
xorjoep 1:24714b45cd1b 46 *
xorjoep 1:24714b45cd1b 47 * <pre>
xorjoep 1:24714b45cd1b 48 * c[n] = a[n] * b[n]
xorjoep 1:24714b45cd1b 49 * </pre>
xorjoep 1:24714b45cd1b 50 *
xorjoep 1:24714b45cd1b 51 * \par
xorjoep 1:24714b45cd1b 52 * is defined as
xorjoep 1:24714b45cd1b 53 * \image html ConvolutionEquation.gif
xorjoep 1:24714b45cd1b 54 * \par
xorjoep 1:24714b45cd1b 55 * Note that <code>c[n]</code> is of length <code>srcALen + srcBLen - 1</code> and is defined over the interval <code>n=0, 1, 2, ..., srcALen + srcBLen - 2</code>.
xorjoep 1:24714b45cd1b 56 * <code>pSrcA</code> points to the first input vector of length <code>srcALen</code> and
xorjoep 1:24714b45cd1b 57 * <code>pSrcB</code> points to the second input vector of length <code>srcBLen</code>.
xorjoep 1:24714b45cd1b 58 * The output result is written to <code>pDst</code> and the calling function must allocate <code>srcALen+srcBLen-1</code> words for the result.
xorjoep 1:24714b45cd1b 59 *
xorjoep 1:24714b45cd1b 60 * \par
xorjoep 1:24714b45cd1b 61 * Conceptually, when two signals <code>a[n]</code> and <code>b[n]</code> are convolved,
xorjoep 1:24714b45cd1b 62 * the signal <code>b[n]</code> slides over <code>a[n]</code>.
xorjoep 1:24714b45cd1b 63 * For each offset \c n, the overlapping portions of a[n] and b[n] are multiplied and summed together.
xorjoep 1:24714b45cd1b 64 *
xorjoep 1:24714b45cd1b 65 * \par
xorjoep 1:24714b45cd1b 66 * Note that convolution is a commutative operation:
xorjoep 1:24714b45cd1b 67 *
xorjoep 1:24714b45cd1b 68 * <pre>
xorjoep 1:24714b45cd1b 69 * a[n] * b[n] = b[n] * a[n].
xorjoep 1:24714b45cd1b 70 * </pre>
xorjoep 1:24714b45cd1b 71 *
xorjoep 1:24714b45cd1b 72 * \par
xorjoep 1:24714b45cd1b 73 * This means that switching the A and B arguments to the convolution functions has no effect.
xorjoep 1:24714b45cd1b 74 *
xorjoep 1:24714b45cd1b 75 * <b>Fixed-Point Behavior</b>
xorjoep 1:24714b45cd1b 76 *
xorjoep 1:24714b45cd1b 77 * \par
xorjoep 1:24714b45cd1b 78 * Convolution requires summing up a large number of intermediate products.
xorjoep 1:24714b45cd1b 79 * As such, the Q7, Q15, and Q31 functions run a risk of overflow and saturation.
xorjoep 1:24714b45cd1b 80 * Refer to the function specific documentation below for further details of the particular algorithm used.
xorjoep 1:24714b45cd1b 81 *
xorjoep 1:24714b45cd1b 82 *
xorjoep 1:24714b45cd1b 83 * <b>Fast Versions</b>
xorjoep 1:24714b45cd1b 84 *
xorjoep 1:24714b45cd1b 85 * \par
xorjoep 1:24714b45cd1b 86 * Fast versions are supported for Q31 and Q15. Cycles for Fast versions are less compared to Q31 and Q15 of conv and the design requires
xorjoep 1:24714b45cd1b 87 * the input signals should be scaled down to avoid intermediate overflows.
xorjoep 1:24714b45cd1b 88 *
xorjoep 1:24714b45cd1b 89 *
xorjoep 1:24714b45cd1b 90 * <b>Opt Versions</b>
xorjoep 1:24714b45cd1b 91 *
xorjoep 1:24714b45cd1b 92 * \par
xorjoep 1:24714b45cd1b 93 * Opt versions are supported for Q15 and Q7. Design uses internal scratch buffer for getting good optimisation.
xorjoep 1:24714b45cd1b 94 * These versions are optimised in cycles and consumes more memory(Scratch memory) compared to Q15 and Q7 versions
xorjoep 1:24714b45cd1b 95 */
xorjoep 1:24714b45cd1b 96
xorjoep 1:24714b45cd1b 97 /**
xorjoep 1:24714b45cd1b 98 * @addtogroup Conv
xorjoep 1:24714b45cd1b 99 * @{
xorjoep 1:24714b45cd1b 100 */
xorjoep 1:24714b45cd1b 101
xorjoep 1:24714b45cd1b 102 /**
xorjoep 1:24714b45cd1b 103 * @brief Convolution of floating-point sequences.
xorjoep 1:24714b45cd1b 104 * @param[in] *pSrcA points to the first input sequence.
xorjoep 1:24714b45cd1b 105 * @param[in] srcALen length of the first input sequence.
xorjoep 1:24714b45cd1b 106 * @param[in] *pSrcB points to the second input sequence.
xorjoep 1:24714b45cd1b 107 * @param[in] srcBLen length of the second input sequence.
xorjoep 1:24714b45cd1b 108 * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1.
xorjoep 1:24714b45cd1b 109 * @return none.
xorjoep 1:24714b45cd1b 110 */
xorjoep 1:24714b45cd1b 111
xorjoep 1:24714b45cd1b 112 void arm_conv_f32(
xorjoep 1:24714b45cd1b 113 float32_t * pSrcA,
xorjoep 1:24714b45cd1b 114 uint32_t srcALen,
xorjoep 1:24714b45cd1b 115 float32_t * pSrcB,
xorjoep 1:24714b45cd1b 116 uint32_t srcBLen,
xorjoep 1:24714b45cd1b 117 float32_t * pDst)
xorjoep 1:24714b45cd1b 118 {
xorjoep 1:24714b45cd1b 119
xorjoep 1:24714b45cd1b 120
xorjoep 1:24714b45cd1b 121 #if defined (ARM_MATH_DSP)
xorjoep 1:24714b45cd1b 122
xorjoep 1:24714b45cd1b 123 /* Run the below code for Cortex-M4 and Cortex-M3 */
xorjoep 1:24714b45cd1b 124
xorjoep 1:24714b45cd1b 125 float32_t *pIn1; /* inputA pointer */
xorjoep 1:24714b45cd1b 126 float32_t *pIn2; /* inputB pointer */
xorjoep 1:24714b45cd1b 127 float32_t *pOut = pDst; /* output pointer */
xorjoep 1:24714b45cd1b 128 float32_t *px; /* Intermediate inputA pointer */
xorjoep 1:24714b45cd1b 129 float32_t *py; /* Intermediate inputB pointer */
xorjoep 1:24714b45cd1b 130 float32_t *pSrc1, *pSrc2; /* Intermediate pointers */
xorjoep 1:24714b45cd1b 131 float32_t sum, acc0, acc1, acc2, acc3; /* Accumulator */
xorjoep 1:24714b45cd1b 132 float32_t x0, x1, x2, x3, c0; /* Temporary variables to hold state and coefficient values */
xorjoep 1:24714b45cd1b 133 uint32_t j, k, count, blkCnt, blockSize1, blockSize2, blockSize3; /* loop counters */
xorjoep 1:24714b45cd1b 134
xorjoep 1:24714b45cd1b 135 /* The algorithm implementation is based on the lengths of the inputs. */
xorjoep 1:24714b45cd1b 136 /* srcB is always made to slide across srcA. */
xorjoep 1:24714b45cd1b 137 /* So srcBLen is always considered as shorter or equal to srcALen */
xorjoep 1:24714b45cd1b 138 if (srcALen >= srcBLen)
xorjoep 1:24714b45cd1b 139 {
xorjoep 1:24714b45cd1b 140 /* Initialization of inputA pointer */
xorjoep 1:24714b45cd1b 141 pIn1 = pSrcA;
xorjoep 1:24714b45cd1b 142
xorjoep 1:24714b45cd1b 143 /* Initialization of inputB pointer */
xorjoep 1:24714b45cd1b 144 pIn2 = pSrcB;
xorjoep 1:24714b45cd1b 145 }
xorjoep 1:24714b45cd1b 146 else
xorjoep 1:24714b45cd1b 147 {
xorjoep 1:24714b45cd1b 148 /* Initialization of inputA pointer */
xorjoep 1:24714b45cd1b 149 pIn1 = pSrcB;
xorjoep 1:24714b45cd1b 150
xorjoep 1:24714b45cd1b 151 /* Initialization of inputB pointer */
xorjoep 1:24714b45cd1b 152 pIn2 = pSrcA;
xorjoep 1:24714b45cd1b 153
xorjoep 1:24714b45cd1b 154 /* srcBLen is always considered as shorter or equal to srcALen */
xorjoep 1:24714b45cd1b 155 j = srcBLen;
xorjoep 1:24714b45cd1b 156 srcBLen = srcALen;
xorjoep 1:24714b45cd1b 157 srcALen = j;
xorjoep 1:24714b45cd1b 158 }
xorjoep 1:24714b45cd1b 159
xorjoep 1:24714b45cd1b 160 /* conv(x,y) at n = x[n] * y[0] + x[n-1] * y[1] + x[n-2] * y[2] + ...+ x[n-N+1] * y[N -1] */
xorjoep 1:24714b45cd1b 161 /* The function is internally
xorjoep 1:24714b45cd1b 162 * divided into three stages according to the number of multiplications that has to be
xorjoep 1:24714b45cd1b 163 * taken place between inputA samples and inputB samples. In the first stage of the
xorjoep 1:24714b45cd1b 164 * algorithm, the multiplications increase by one for every iteration.
xorjoep 1:24714b45cd1b 165 * In the second stage of the algorithm, srcBLen number of multiplications are done.
xorjoep 1:24714b45cd1b 166 * In the third stage of the algorithm, the multiplications decrease by one
xorjoep 1:24714b45cd1b 167 * for every iteration. */
xorjoep 1:24714b45cd1b 168
xorjoep 1:24714b45cd1b 169 /* The algorithm is implemented in three stages.
xorjoep 1:24714b45cd1b 170 The loop counters of each stage is initiated here. */
xorjoep 1:24714b45cd1b 171 blockSize1 = srcBLen - 1U;
xorjoep 1:24714b45cd1b 172 blockSize2 = srcALen - (srcBLen - 1U);
xorjoep 1:24714b45cd1b 173 blockSize3 = blockSize1;
xorjoep 1:24714b45cd1b 174
xorjoep 1:24714b45cd1b 175 /* --------------------------
xorjoep 1:24714b45cd1b 176 * initializations of stage1
xorjoep 1:24714b45cd1b 177 * -------------------------*/
xorjoep 1:24714b45cd1b 178
xorjoep 1:24714b45cd1b 179 /* sum = x[0] * y[0]
xorjoep 1:24714b45cd1b 180 * sum = x[0] * y[1] + x[1] * y[0]
xorjoep 1:24714b45cd1b 181 * ....
xorjoep 1:24714b45cd1b 182 * sum = x[0] * y[srcBlen - 1] + x[1] * y[srcBlen - 2] +...+ x[srcBLen - 1] * y[0]
xorjoep 1:24714b45cd1b 183 */
xorjoep 1:24714b45cd1b 184
xorjoep 1:24714b45cd1b 185 /* In this stage the MAC operations are increased by 1 for every iteration.
xorjoep 1:24714b45cd1b 186 The count variable holds the number of MAC operations performed */
xorjoep 1:24714b45cd1b 187 count = 1U;
xorjoep 1:24714b45cd1b 188
xorjoep 1:24714b45cd1b 189 /* Working pointer of inputA */
xorjoep 1:24714b45cd1b 190 px = pIn1;
xorjoep 1:24714b45cd1b 191
xorjoep 1:24714b45cd1b 192 /* Working pointer of inputB */
xorjoep 1:24714b45cd1b 193 py = pIn2;
xorjoep 1:24714b45cd1b 194
xorjoep 1:24714b45cd1b 195
xorjoep 1:24714b45cd1b 196 /* ------------------------
xorjoep 1:24714b45cd1b 197 * Stage1 process
xorjoep 1:24714b45cd1b 198 * ----------------------*/
xorjoep 1:24714b45cd1b 199
xorjoep 1:24714b45cd1b 200 /* The first stage starts here */
xorjoep 1:24714b45cd1b 201 while (blockSize1 > 0U)
xorjoep 1:24714b45cd1b 202 {
xorjoep 1:24714b45cd1b 203 /* Accumulator is made zero for every iteration */
xorjoep 1:24714b45cd1b 204 sum = 0.0f;
xorjoep 1:24714b45cd1b 205
xorjoep 1:24714b45cd1b 206 /* Apply loop unrolling and compute 4 MACs simultaneously. */
xorjoep 1:24714b45cd1b 207 k = count >> 2U;
xorjoep 1:24714b45cd1b 208
xorjoep 1:24714b45cd1b 209 /* First part of the processing with loop unrolling. Compute 4 MACs at a time.
xorjoep 1:24714b45cd1b 210 ** a second loop below computes MACs for the remaining 1 to 3 samples. */
xorjoep 1:24714b45cd1b 211 while (k > 0U)
xorjoep 1:24714b45cd1b 212 {
xorjoep 1:24714b45cd1b 213 /* x[0] * y[srcBLen - 1] */
xorjoep 1:24714b45cd1b 214 sum += *px++ * *py--;
xorjoep 1:24714b45cd1b 215
xorjoep 1:24714b45cd1b 216 /* x[1] * y[srcBLen - 2] */
xorjoep 1:24714b45cd1b 217 sum += *px++ * *py--;
xorjoep 1:24714b45cd1b 218
xorjoep 1:24714b45cd1b 219 /* x[2] * y[srcBLen - 3] */
xorjoep 1:24714b45cd1b 220 sum += *px++ * *py--;
xorjoep 1:24714b45cd1b 221
xorjoep 1:24714b45cd1b 222 /* x[3] * y[srcBLen - 4] */
xorjoep 1:24714b45cd1b 223 sum += *px++ * *py--;
xorjoep 1:24714b45cd1b 224
xorjoep 1:24714b45cd1b 225 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 226 k--;
xorjoep 1:24714b45cd1b 227 }
xorjoep 1:24714b45cd1b 228
xorjoep 1:24714b45cd1b 229 /* If the count is not a multiple of 4, compute any remaining MACs here.
xorjoep 1:24714b45cd1b 230 ** No loop unrolling is used. */
xorjoep 1:24714b45cd1b 231 k = count % 0x4U;
xorjoep 1:24714b45cd1b 232
xorjoep 1:24714b45cd1b 233 while (k > 0U)
xorjoep 1:24714b45cd1b 234 {
xorjoep 1:24714b45cd1b 235 /* Perform the multiply-accumulate */
xorjoep 1:24714b45cd1b 236 sum += *px++ * *py--;
xorjoep 1:24714b45cd1b 237
xorjoep 1:24714b45cd1b 238 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 239 k--;
xorjoep 1:24714b45cd1b 240 }
xorjoep 1:24714b45cd1b 241
xorjoep 1:24714b45cd1b 242 /* Store the result in the accumulator in the destination buffer. */
xorjoep 1:24714b45cd1b 243 *pOut++ = sum;
xorjoep 1:24714b45cd1b 244
xorjoep 1:24714b45cd1b 245 /* Update the inputA and inputB pointers for next MAC calculation */
xorjoep 1:24714b45cd1b 246 py = pIn2 + count;
xorjoep 1:24714b45cd1b 247 px = pIn1;
xorjoep 1:24714b45cd1b 248
xorjoep 1:24714b45cd1b 249 /* Increment the MAC count */
xorjoep 1:24714b45cd1b 250 count++;
xorjoep 1:24714b45cd1b 251
xorjoep 1:24714b45cd1b 252 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 253 blockSize1--;
xorjoep 1:24714b45cd1b 254 }
xorjoep 1:24714b45cd1b 255
xorjoep 1:24714b45cd1b 256 /* --------------------------
xorjoep 1:24714b45cd1b 257 * Initializations of stage2
xorjoep 1:24714b45cd1b 258 * ------------------------*/
xorjoep 1:24714b45cd1b 259
xorjoep 1:24714b45cd1b 260 /* sum = x[0] * y[srcBLen-1] + x[1] * y[srcBLen-2] +...+ x[srcBLen-1] * y[0]
xorjoep 1:24714b45cd1b 261 * sum = x[1] * y[srcBLen-1] + x[2] * y[srcBLen-2] +...+ x[srcBLen] * y[0]
xorjoep 1:24714b45cd1b 262 * ....
xorjoep 1:24714b45cd1b 263 * sum = x[srcALen-srcBLen-2] * y[srcBLen-1] + x[srcALen] * y[srcBLen-2] +...+ x[srcALen-1] * y[0]
xorjoep 1:24714b45cd1b 264 */
xorjoep 1:24714b45cd1b 265
xorjoep 1:24714b45cd1b 266 /* Working pointer of inputA */
xorjoep 1:24714b45cd1b 267 px = pIn1;
xorjoep 1:24714b45cd1b 268
xorjoep 1:24714b45cd1b 269 /* Working pointer of inputB */
xorjoep 1:24714b45cd1b 270 pSrc2 = pIn2 + (srcBLen - 1U);
xorjoep 1:24714b45cd1b 271 py = pSrc2;
xorjoep 1:24714b45cd1b 272
xorjoep 1:24714b45cd1b 273 /* count is index by which the pointer pIn1 to be incremented */
xorjoep 1:24714b45cd1b 274 count = 0U;
xorjoep 1:24714b45cd1b 275
xorjoep 1:24714b45cd1b 276 /* -------------------
xorjoep 1:24714b45cd1b 277 * Stage2 process
xorjoep 1:24714b45cd1b 278 * ------------------*/
xorjoep 1:24714b45cd1b 279
xorjoep 1:24714b45cd1b 280 /* Stage2 depends on srcBLen as in this stage srcBLen number of MACS are performed.
xorjoep 1:24714b45cd1b 281 * So, to loop unroll over blockSize2,
xorjoep 1:24714b45cd1b 282 * srcBLen should be greater than or equal to 4 */
xorjoep 1:24714b45cd1b 283 if (srcBLen >= 4U)
xorjoep 1:24714b45cd1b 284 {
xorjoep 1:24714b45cd1b 285 /* Loop unroll over blockSize2, by 4 */
xorjoep 1:24714b45cd1b 286 blkCnt = blockSize2 >> 2U;
xorjoep 1:24714b45cd1b 287
xorjoep 1:24714b45cd1b 288 while (blkCnt > 0U)
xorjoep 1:24714b45cd1b 289 {
xorjoep 1:24714b45cd1b 290 /* Set all accumulators to zero */
xorjoep 1:24714b45cd1b 291 acc0 = 0.0f;
xorjoep 1:24714b45cd1b 292 acc1 = 0.0f;
xorjoep 1:24714b45cd1b 293 acc2 = 0.0f;
xorjoep 1:24714b45cd1b 294 acc3 = 0.0f;
xorjoep 1:24714b45cd1b 295
xorjoep 1:24714b45cd1b 296 /* read x[0], x[1], x[2] samples */
xorjoep 1:24714b45cd1b 297 x0 = *(px++);
xorjoep 1:24714b45cd1b 298 x1 = *(px++);
xorjoep 1:24714b45cd1b 299 x2 = *(px++);
xorjoep 1:24714b45cd1b 300
xorjoep 1:24714b45cd1b 301 /* Apply loop unrolling and compute 4 MACs simultaneously. */
xorjoep 1:24714b45cd1b 302 k = srcBLen >> 2U;
xorjoep 1:24714b45cd1b 303
xorjoep 1:24714b45cd1b 304 /* First part of the processing with loop unrolling. Compute 4 MACs at a time.
xorjoep 1:24714b45cd1b 305 ** a second loop below computes MACs for the remaining 1 to 3 samples. */
xorjoep 1:24714b45cd1b 306 do
xorjoep 1:24714b45cd1b 307 {
xorjoep 1:24714b45cd1b 308 /* Read y[srcBLen - 1] sample */
xorjoep 1:24714b45cd1b 309 c0 = *(py--);
xorjoep 1:24714b45cd1b 310
xorjoep 1:24714b45cd1b 311 /* Read x[3] sample */
xorjoep 1:24714b45cd1b 312 x3 = *(px);
xorjoep 1:24714b45cd1b 313
xorjoep 1:24714b45cd1b 314 /* Perform the multiply-accumulate */
xorjoep 1:24714b45cd1b 315 /* acc0 += x[0] * y[srcBLen - 1] */
xorjoep 1:24714b45cd1b 316 acc0 += x0 * c0;
xorjoep 1:24714b45cd1b 317
xorjoep 1:24714b45cd1b 318 /* acc1 += x[1] * y[srcBLen - 1] */
xorjoep 1:24714b45cd1b 319 acc1 += x1 * c0;
xorjoep 1:24714b45cd1b 320
xorjoep 1:24714b45cd1b 321 /* acc2 += x[2] * y[srcBLen - 1] */
xorjoep 1:24714b45cd1b 322 acc2 += x2 * c0;
xorjoep 1:24714b45cd1b 323
xorjoep 1:24714b45cd1b 324 /* acc3 += x[3] * y[srcBLen - 1] */
xorjoep 1:24714b45cd1b 325 acc3 += x3 * c0;
xorjoep 1:24714b45cd1b 326
xorjoep 1:24714b45cd1b 327 /* Read y[srcBLen - 2] sample */
xorjoep 1:24714b45cd1b 328 c0 = *(py--);
xorjoep 1:24714b45cd1b 329
xorjoep 1:24714b45cd1b 330 /* Read x[4] sample */
xorjoep 1:24714b45cd1b 331 x0 = *(px + 1U);
xorjoep 1:24714b45cd1b 332
xorjoep 1:24714b45cd1b 333 /* Perform the multiply-accumulate */
xorjoep 1:24714b45cd1b 334 /* acc0 += x[1] * y[srcBLen - 2] */
xorjoep 1:24714b45cd1b 335 acc0 += x1 * c0;
xorjoep 1:24714b45cd1b 336 /* acc1 += x[2] * y[srcBLen - 2] */
xorjoep 1:24714b45cd1b 337 acc1 += x2 * c0;
xorjoep 1:24714b45cd1b 338 /* acc2 += x[3] * y[srcBLen - 2] */
xorjoep 1:24714b45cd1b 339 acc2 += x3 * c0;
xorjoep 1:24714b45cd1b 340 /* acc3 += x[4] * y[srcBLen - 2] */
xorjoep 1:24714b45cd1b 341 acc3 += x0 * c0;
xorjoep 1:24714b45cd1b 342
xorjoep 1:24714b45cd1b 343 /* Read y[srcBLen - 3] sample */
xorjoep 1:24714b45cd1b 344 c0 = *(py--);
xorjoep 1:24714b45cd1b 345
xorjoep 1:24714b45cd1b 346 /* Read x[5] sample */
xorjoep 1:24714b45cd1b 347 x1 = *(px + 2U);
xorjoep 1:24714b45cd1b 348
xorjoep 1:24714b45cd1b 349 /* Perform the multiply-accumulates */
xorjoep 1:24714b45cd1b 350 /* acc0 += x[2] * y[srcBLen - 3] */
xorjoep 1:24714b45cd1b 351 acc0 += x2 * c0;
xorjoep 1:24714b45cd1b 352 /* acc1 += x[3] * y[srcBLen - 2] */
xorjoep 1:24714b45cd1b 353 acc1 += x3 * c0;
xorjoep 1:24714b45cd1b 354 /* acc2 += x[4] * y[srcBLen - 2] */
xorjoep 1:24714b45cd1b 355 acc2 += x0 * c0;
xorjoep 1:24714b45cd1b 356 /* acc3 += x[5] * y[srcBLen - 2] */
xorjoep 1:24714b45cd1b 357 acc3 += x1 * c0;
xorjoep 1:24714b45cd1b 358
xorjoep 1:24714b45cd1b 359 /* Read y[srcBLen - 4] sample */
xorjoep 1:24714b45cd1b 360 c0 = *(py--);
xorjoep 1:24714b45cd1b 361
xorjoep 1:24714b45cd1b 362 /* Read x[6] sample */
xorjoep 1:24714b45cd1b 363 x2 = *(px + 3U);
xorjoep 1:24714b45cd1b 364 px += 4U;
xorjoep 1:24714b45cd1b 365
xorjoep 1:24714b45cd1b 366 /* Perform the multiply-accumulates */
xorjoep 1:24714b45cd1b 367 /* acc0 += x[3] * y[srcBLen - 4] */
xorjoep 1:24714b45cd1b 368 acc0 += x3 * c0;
xorjoep 1:24714b45cd1b 369 /* acc1 += x[4] * y[srcBLen - 4] */
xorjoep 1:24714b45cd1b 370 acc1 += x0 * c0;
xorjoep 1:24714b45cd1b 371 /* acc2 += x[5] * y[srcBLen - 4] */
xorjoep 1:24714b45cd1b 372 acc2 += x1 * c0;
xorjoep 1:24714b45cd1b 373 /* acc3 += x[6] * y[srcBLen - 4] */
xorjoep 1:24714b45cd1b 374 acc3 += x2 * c0;
xorjoep 1:24714b45cd1b 375
xorjoep 1:24714b45cd1b 376
xorjoep 1:24714b45cd1b 377 } while (--k);
xorjoep 1:24714b45cd1b 378
xorjoep 1:24714b45cd1b 379 /* If the srcBLen is not a multiple of 4, compute any remaining MACs here.
xorjoep 1:24714b45cd1b 380 ** No loop unrolling is used. */
xorjoep 1:24714b45cd1b 381 k = srcBLen % 0x4U;
xorjoep 1:24714b45cd1b 382
xorjoep 1:24714b45cd1b 383 while (k > 0U)
xorjoep 1:24714b45cd1b 384 {
xorjoep 1:24714b45cd1b 385 /* Read y[srcBLen - 5] sample */
xorjoep 1:24714b45cd1b 386 c0 = *(py--);
xorjoep 1:24714b45cd1b 387
xorjoep 1:24714b45cd1b 388 /* Read x[7] sample */
xorjoep 1:24714b45cd1b 389 x3 = *(px++);
xorjoep 1:24714b45cd1b 390
xorjoep 1:24714b45cd1b 391 /* Perform the multiply-accumulates */
xorjoep 1:24714b45cd1b 392 /* acc0 += x[4] * y[srcBLen - 5] */
xorjoep 1:24714b45cd1b 393 acc0 += x0 * c0;
xorjoep 1:24714b45cd1b 394 /* acc1 += x[5] * y[srcBLen - 5] */
xorjoep 1:24714b45cd1b 395 acc1 += x1 * c0;
xorjoep 1:24714b45cd1b 396 /* acc2 += x[6] * y[srcBLen - 5] */
xorjoep 1:24714b45cd1b 397 acc2 += x2 * c0;
xorjoep 1:24714b45cd1b 398 /* acc3 += x[7] * y[srcBLen - 5] */
xorjoep 1:24714b45cd1b 399 acc3 += x3 * c0;
xorjoep 1:24714b45cd1b 400
xorjoep 1:24714b45cd1b 401 /* Reuse the present samples for the next MAC */
xorjoep 1:24714b45cd1b 402 x0 = x1;
xorjoep 1:24714b45cd1b 403 x1 = x2;
xorjoep 1:24714b45cd1b 404 x2 = x3;
xorjoep 1:24714b45cd1b 405
xorjoep 1:24714b45cd1b 406 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 407 k--;
xorjoep 1:24714b45cd1b 408 }
xorjoep 1:24714b45cd1b 409
xorjoep 1:24714b45cd1b 410 /* Store the result in the accumulator in the destination buffer. */
xorjoep 1:24714b45cd1b 411 *pOut++ = acc0;
xorjoep 1:24714b45cd1b 412 *pOut++ = acc1;
xorjoep 1:24714b45cd1b 413 *pOut++ = acc2;
xorjoep 1:24714b45cd1b 414 *pOut++ = acc3;
xorjoep 1:24714b45cd1b 415
xorjoep 1:24714b45cd1b 416 /* Increment the pointer pIn1 index, count by 4 */
xorjoep 1:24714b45cd1b 417 count += 4U;
xorjoep 1:24714b45cd1b 418
xorjoep 1:24714b45cd1b 419 /* Update the inputA and inputB pointers for next MAC calculation */
xorjoep 1:24714b45cd1b 420 px = pIn1 + count;
xorjoep 1:24714b45cd1b 421 py = pSrc2;
xorjoep 1:24714b45cd1b 422
xorjoep 1:24714b45cd1b 423
xorjoep 1:24714b45cd1b 424 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 425 blkCnt--;
xorjoep 1:24714b45cd1b 426 }
xorjoep 1:24714b45cd1b 427
xorjoep 1:24714b45cd1b 428
xorjoep 1:24714b45cd1b 429 /* If the blockSize2 is not a multiple of 4, compute any remaining output samples here.
xorjoep 1:24714b45cd1b 430 ** No loop unrolling is used. */
xorjoep 1:24714b45cd1b 431 blkCnt = blockSize2 % 0x4U;
xorjoep 1:24714b45cd1b 432
xorjoep 1:24714b45cd1b 433 while (blkCnt > 0U)
xorjoep 1:24714b45cd1b 434 {
xorjoep 1:24714b45cd1b 435 /* Accumulator is made zero for every iteration */
xorjoep 1:24714b45cd1b 436 sum = 0.0f;
xorjoep 1:24714b45cd1b 437
xorjoep 1:24714b45cd1b 438 /* Apply loop unrolling and compute 4 MACs simultaneously. */
xorjoep 1:24714b45cd1b 439 k = srcBLen >> 2U;
xorjoep 1:24714b45cd1b 440
xorjoep 1:24714b45cd1b 441 /* First part of the processing with loop unrolling. Compute 4 MACs at a time.
xorjoep 1:24714b45cd1b 442 ** a second loop below computes MACs for the remaining 1 to 3 samples. */
xorjoep 1:24714b45cd1b 443 while (k > 0U)
xorjoep 1:24714b45cd1b 444 {
xorjoep 1:24714b45cd1b 445 /* Perform the multiply-accumulates */
xorjoep 1:24714b45cd1b 446 sum += *px++ * *py--;
xorjoep 1:24714b45cd1b 447 sum += *px++ * *py--;
xorjoep 1:24714b45cd1b 448 sum += *px++ * *py--;
xorjoep 1:24714b45cd1b 449 sum += *px++ * *py--;
xorjoep 1:24714b45cd1b 450
xorjoep 1:24714b45cd1b 451 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 452 k--;
xorjoep 1:24714b45cd1b 453 }
xorjoep 1:24714b45cd1b 454
xorjoep 1:24714b45cd1b 455 /* If the srcBLen is not a multiple of 4, compute any remaining MACs here.
xorjoep 1:24714b45cd1b 456 ** No loop unrolling is used. */
xorjoep 1:24714b45cd1b 457 k = srcBLen % 0x4U;
xorjoep 1:24714b45cd1b 458
xorjoep 1:24714b45cd1b 459 while (k > 0U)
xorjoep 1:24714b45cd1b 460 {
xorjoep 1:24714b45cd1b 461 /* Perform the multiply-accumulate */
xorjoep 1:24714b45cd1b 462 sum += *px++ * *py--;
xorjoep 1:24714b45cd1b 463
xorjoep 1:24714b45cd1b 464 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 465 k--;
xorjoep 1:24714b45cd1b 466 }
xorjoep 1:24714b45cd1b 467
xorjoep 1:24714b45cd1b 468 /* Store the result in the accumulator in the destination buffer. */
xorjoep 1:24714b45cd1b 469 *pOut++ = sum;
xorjoep 1:24714b45cd1b 470
xorjoep 1:24714b45cd1b 471 /* Increment the MAC count */
xorjoep 1:24714b45cd1b 472 count++;
xorjoep 1:24714b45cd1b 473
xorjoep 1:24714b45cd1b 474 /* Update the inputA and inputB pointers for next MAC calculation */
xorjoep 1:24714b45cd1b 475 px = pIn1 + count;
xorjoep 1:24714b45cd1b 476 py = pSrc2;
xorjoep 1:24714b45cd1b 477
xorjoep 1:24714b45cd1b 478 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 479 blkCnt--;
xorjoep 1:24714b45cd1b 480 }
xorjoep 1:24714b45cd1b 481 }
xorjoep 1:24714b45cd1b 482 else
xorjoep 1:24714b45cd1b 483 {
xorjoep 1:24714b45cd1b 484 /* If the srcBLen is not a multiple of 4,
xorjoep 1:24714b45cd1b 485 * the blockSize2 loop cannot be unrolled by 4 */
xorjoep 1:24714b45cd1b 486 blkCnt = blockSize2;
xorjoep 1:24714b45cd1b 487
xorjoep 1:24714b45cd1b 488 while (blkCnt > 0U)
xorjoep 1:24714b45cd1b 489 {
xorjoep 1:24714b45cd1b 490 /* Accumulator is made zero for every iteration */
xorjoep 1:24714b45cd1b 491 sum = 0.0f;
xorjoep 1:24714b45cd1b 492
xorjoep 1:24714b45cd1b 493 /* srcBLen number of MACS should be performed */
xorjoep 1:24714b45cd1b 494 k = srcBLen;
xorjoep 1:24714b45cd1b 495
xorjoep 1:24714b45cd1b 496 while (k > 0U)
xorjoep 1:24714b45cd1b 497 {
xorjoep 1:24714b45cd1b 498 /* Perform the multiply-accumulate */
xorjoep 1:24714b45cd1b 499 sum += *px++ * *py--;
xorjoep 1:24714b45cd1b 500
xorjoep 1:24714b45cd1b 501 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 502 k--;
xorjoep 1:24714b45cd1b 503 }
xorjoep 1:24714b45cd1b 504
xorjoep 1:24714b45cd1b 505 /* Store the result in the accumulator in the destination buffer. */
xorjoep 1:24714b45cd1b 506 *pOut++ = sum;
xorjoep 1:24714b45cd1b 507
xorjoep 1:24714b45cd1b 508 /* Increment the MAC count */
xorjoep 1:24714b45cd1b 509 count++;
xorjoep 1:24714b45cd1b 510
xorjoep 1:24714b45cd1b 511 /* Update the inputA and inputB pointers for next MAC calculation */
xorjoep 1:24714b45cd1b 512 px = pIn1 + count;
xorjoep 1:24714b45cd1b 513 py = pSrc2;
xorjoep 1:24714b45cd1b 514
xorjoep 1:24714b45cd1b 515 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 516 blkCnt--;
xorjoep 1:24714b45cd1b 517 }
xorjoep 1:24714b45cd1b 518 }
xorjoep 1:24714b45cd1b 519
xorjoep 1:24714b45cd1b 520
xorjoep 1:24714b45cd1b 521 /* --------------------------
xorjoep 1:24714b45cd1b 522 * Initializations of stage3
xorjoep 1:24714b45cd1b 523 * -------------------------*/
xorjoep 1:24714b45cd1b 524
xorjoep 1:24714b45cd1b 525 /* sum += x[srcALen-srcBLen+1] * y[srcBLen-1] + x[srcALen-srcBLen+2] * y[srcBLen-2] +...+ x[srcALen-1] * y[1]
xorjoep 1:24714b45cd1b 526 * sum += x[srcALen-srcBLen+2] * y[srcBLen-1] + x[srcALen-srcBLen+3] * y[srcBLen-2] +...+ x[srcALen-1] * y[2]
xorjoep 1:24714b45cd1b 527 * ....
xorjoep 1:24714b45cd1b 528 * sum += x[srcALen-2] * y[srcBLen-1] + x[srcALen-1] * y[srcBLen-2]
xorjoep 1:24714b45cd1b 529 * sum += x[srcALen-1] * y[srcBLen-1]
xorjoep 1:24714b45cd1b 530 */
xorjoep 1:24714b45cd1b 531
xorjoep 1:24714b45cd1b 532 /* In this stage the MAC operations are decreased by 1 for every iteration.
xorjoep 1:24714b45cd1b 533 The blockSize3 variable holds the number of MAC operations performed */
xorjoep 1:24714b45cd1b 534
xorjoep 1:24714b45cd1b 535 /* Working pointer of inputA */
xorjoep 1:24714b45cd1b 536 pSrc1 = (pIn1 + srcALen) - (srcBLen - 1U);
xorjoep 1:24714b45cd1b 537 px = pSrc1;
xorjoep 1:24714b45cd1b 538
xorjoep 1:24714b45cd1b 539 /* Working pointer of inputB */
xorjoep 1:24714b45cd1b 540 pSrc2 = pIn2 + (srcBLen - 1U);
xorjoep 1:24714b45cd1b 541 py = pSrc2;
xorjoep 1:24714b45cd1b 542
xorjoep 1:24714b45cd1b 543 /* -------------------
xorjoep 1:24714b45cd1b 544 * Stage3 process
xorjoep 1:24714b45cd1b 545 * ------------------*/
xorjoep 1:24714b45cd1b 546
xorjoep 1:24714b45cd1b 547 while (blockSize3 > 0U)
xorjoep 1:24714b45cd1b 548 {
xorjoep 1:24714b45cd1b 549 /* Accumulator is made zero for every iteration */
xorjoep 1:24714b45cd1b 550 sum = 0.0f;
xorjoep 1:24714b45cd1b 551
xorjoep 1:24714b45cd1b 552 /* Apply loop unrolling and compute 4 MACs simultaneously. */
xorjoep 1:24714b45cd1b 553 k = blockSize3 >> 2U;
xorjoep 1:24714b45cd1b 554
xorjoep 1:24714b45cd1b 555 /* First part of the processing with loop unrolling. Compute 4 MACs at a time.
xorjoep 1:24714b45cd1b 556 ** a second loop below computes MACs for the remaining 1 to 3 samples. */
xorjoep 1:24714b45cd1b 557 while (k > 0U)
xorjoep 1:24714b45cd1b 558 {
xorjoep 1:24714b45cd1b 559 /* sum += x[srcALen - srcBLen + 1] * y[srcBLen - 1] */
xorjoep 1:24714b45cd1b 560 sum += *px++ * *py--;
xorjoep 1:24714b45cd1b 561
xorjoep 1:24714b45cd1b 562 /* sum += x[srcALen - srcBLen + 2] * y[srcBLen - 2] */
xorjoep 1:24714b45cd1b 563 sum += *px++ * *py--;
xorjoep 1:24714b45cd1b 564
xorjoep 1:24714b45cd1b 565 /* sum += x[srcALen - srcBLen + 3] * y[srcBLen - 3] */
xorjoep 1:24714b45cd1b 566 sum += *px++ * *py--;
xorjoep 1:24714b45cd1b 567
xorjoep 1:24714b45cd1b 568 /* sum += x[srcALen - srcBLen + 4] * y[srcBLen - 4] */
xorjoep 1:24714b45cd1b 569 sum += *px++ * *py--;
xorjoep 1:24714b45cd1b 570
xorjoep 1:24714b45cd1b 571 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 572 k--;
xorjoep 1:24714b45cd1b 573 }
xorjoep 1:24714b45cd1b 574
xorjoep 1:24714b45cd1b 575 /* If the blockSize3 is not a multiple of 4, compute any remaining MACs here.
xorjoep 1:24714b45cd1b 576 ** No loop unrolling is used. */
xorjoep 1:24714b45cd1b 577 k = blockSize3 % 0x4U;
xorjoep 1:24714b45cd1b 578
xorjoep 1:24714b45cd1b 579 while (k > 0U)
xorjoep 1:24714b45cd1b 580 {
xorjoep 1:24714b45cd1b 581 /* Perform the multiply-accumulates */
xorjoep 1:24714b45cd1b 582 /* sum += x[srcALen-1] * y[srcBLen-1] */
xorjoep 1:24714b45cd1b 583 sum += *px++ * *py--;
xorjoep 1:24714b45cd1b 584
xorjoep 1:24714b45cd1b 585 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 586 k--;
xorjoep 1:24714b45cd1b 587 }
xorjoep 1:24714b45cd1b 588
xorjoep 1:24714b45cd1b 589 /* Store the result in the accumulator in the destination buffer. */
xorjoep 1:24714b45cd1b 590 *pOut++ = sum;
xorjoep 1:24714b45cd1b 591
xorjoep 1:24714b45cd1b 592 /* Update the inputA and inputB pointers for next MAC calculation */
xorjoep 1:24714b45cd1b 593 px = ++pSrc1;
xorjoep 1:24714b45cd1b 594 py = pSrc2;
xorjoep 1:24714b45cd1b 595
xorjoep 1:24714b45cd1b 596 /* Decrement the loop counter */
xorjoep 1:24714b45cd1b 597 blockSize3--;
xorjoep 1:24714b45cd1b 598 }
xorjoep 1:24714b45cd1b 599
xorjoep 1:24714b45cd1b 600 #else
xorjoep 1:24714b45cd1b 601
xorjoep 1:24714b45cd1b 602 /* Run the below code for Cortex-M0 */
xorjoep 1:24714b45cd1b 603
xorjoep 1:24714b45cd1b 604 float32_t *pIn1 = pSrcA; /* inputA pointer */
xorjoep 1:24714b45cd1b 605 float32_t *pIn2 = pSrcB; /* inputB pointer */
xorjoep 1:24714b45cd1b 606 float32_t sum; /* Accumulator */
xorjoep 1:24714b45cd1b 607 uint32_t i, j; /* loop counters */
xorjoep 1:24714b45cd1b 608
xorjoep 1:24714b45cd1b 609 /* Loop to calculate convolution for output length number of times */
xorjoep 1:24714b45cd1b 610 for (i = 0U; i < ((srcALen + srcBLen) - 1U); i++)
xorjoep 1:24714b45cd1b 611 {
xorjoep 1:24714b45cd1b 612 /* Initialize sum with zero to carry out MAC operations */
xorjoep 1:24714b45cd1b 613 sum = 0.0f;
xorjoep 1:24714b45cd1b 614
xorjoep 1:24714b45cd1b 615 /* Loop to perform MAC operations according to convolution equation */
xorjoep 1:24714b45cd1b 616 for (j = 0U; j <= i; j++)
xorjoep 1:24714b45cd1b 617 {
xorjoep 1:24714b45cd1b 618 /* Check the array limitations */
xorjoep 1:24714b45cd1b 619 if ((((i - j) < srcBLen) && (j < srcALen)))
xorjoep 1:24714b45cd1b 620 {
xorjoep 1:24714b45cd1b 621 /* z[i] += x[i-j] * y[j] */
xorjoep 1:24714b45cd1b 622 sum += pIn1[j] * pIn2[i - j];
xorjoep 1:24714b45cd1b 623 }
xorjoep 1:24714b45cd1b 624 }
xorjoep 1:24714b45cd1b 625 /* Store the output in the destination buffer */
xorjoep 1:24714b45cd1b 626 pDst[i] = sum;
xorjoep 1:24714b45cd1b 627 }
xorjoep 1:24714b45cd1b 628
xorjoep 1:24714b45cd1b 629 #endif /* #if defined (ARM_MATH_DSP) */
xorjoep 1:24714b45cd1b 630
xorjoep 1:24714b45cd1b 631 }
xorjoep 1:24714b45cd1b 632
xorjoep 1:24714b45cd1b 633 /**
xorjoep 1:24714b45cd1b 634 * @} end of Conv group
xorjoep 1:24714b45cd1b 635 */