Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-dsp by
cmsis_dsp/FilteringFunctions/arm_correlate_opt_q7.c@4:9cee975aadce, 2014-06-23 (annotated)
- Committer:
- mbed_official
- Date:
- Mon Jun 23 09:30:09 2014 +0100
- Revision:
- 4:9cee975aadce
- Parent:
- 3:7a284390b0ce
Synchronized with git revision 6e7c7bcec41226f536474daae3c13d49e4c0e865
Full URL: https://github.com/mbedmicro/mbed/commit/6e7c7bcec41226f536474daae3c13d49e4c0e865/
Fix signed unsigned compare in dsp library
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
emilmont | 1:fdd22bb7aa52 | 1 | /* ---------------------------------------------------------------------- |
mbed_official | 3:7a284390b0ce | 2 | * Copyright (C) 2010-2013 ARM Limited. All rights reserved. |
emilmont | 1:fdd22bb7aa52 | 3 | * |
mbed_official | 3:7a284390b0ce | 4 | * $Date: 17. January 2013 |
mbed_official | 3:7a284390b0ce | 5 | * $Revision: V1.4.1 |
emilmont | 1:fdd22bb7aa52 | 6 | * |
emilmont | 2:da51fb522205 | 7 | * Project: CMSIS DSP Library |
emilmont | 2:da51fb522205 | 8 | * Title: arm_correlate_opt_q7.c |
emilmont | 1:fdd22bb7aa52 | 9 | * |
emilmont | 2:da51fb522205 | 10 | * Description: Correlation of Q7 sequences. |
emilmont | 1:fdd22bb7aa52 | 11 | * |
emilmont | 1:fdd22bb7aa52 | 12 | * Target Processor: Cortex-M4/Cortex-M3 |
emilmont | 1:fdd22bb7aa52 | 13 | * |
mbed_official | 3:7a284390b0ce | 14 | * Redistribution and use in source and binary forms, with or without |
mbed_official | 3:7a284390b0ce | 15 | * modification, are permitted provided that the following conditions |
mbed_official | 3:7a284390b0ce | 16 | * are met: |
mbed_official | 3:7a284390b0ce | 17 | * - Redistributions of source code must retain the above copyright |
mbed_official | 3:7a284390b0ce | 18 | * notice, this list of conditions and the following disclaimer. |
mbed_official | 3:7a284390b0ce | 19 | * - Redistributions in binary form must reproduce the above copyright |
mbed_official | 3:7a284390b0ce | 20 | * notice, this list of conditions and the following disclaimer in |
mbed_official | 3:7a284390b0ce | 21 | * the documentation and/or other materials provided with the |
mbed_official | 3:7a284390b0ce | 22 | * distribution. |
mbed_official | 3:7a284390b0ce | 23 | * - Neither the name of ARM LIMITED nor the names of its contributors |
mbed_official | 3:7a284390b0ce | 24 | * may be used to endorse or promote products derived from this |
mbed_official | 3:7a284390b0ce | 25 | * software without specific prior written permission. |
mbed_official | 3:7a284390b0ce | 26 | * |
mbed_official | 3:7a284390b0ce | 27 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
mbed_official | 3:7a284390b0ce | 28 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
mbed_official | 3:7a284390b0ce | 29 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
mbed_official | 3:7a284390b0ce | 30 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
mbed_official | 3:7a284390b0ce | 31 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
mbed_official | 3:7a284390b0ce | 32 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
mbed_official | 3:7a284390b0ce | 33 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
mbed_official | 3:7a284390b0ce | 34 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
mbed_official | 3:7a284390b0ce | 35 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
mbed_official | 3:7a284390b0ce | 36 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
mbed_official | 3:7a284390b0ce | 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
mbed_official | 3:7a284390b0ce | 38 | * POSSIBILITY OF SUCH DAMAGE. |
emilmont | 1:fdd22bb7aa52 | 39 | * -------------------------------------------------------------------- */ |
emilmont | 1:fdd22bb7aa52 | 40 | |
emilmont | 1:fdd22bb7aa52 | 41 | #include "arm_math.h" |
emilmont | 1:fdd22bb7aa52 | 42 | |
emilmont | 1:fdd22bb7aa52 | 43 | /** |
emilmont | 1:fdd22bb7aa52 | 44 | * @ingroup groupFilters |
emilmont | 1:fdd22bb7aa52 | 45 | */ |
emilmont | 1:fdd22bb7aa52 | 46 | |
emilmont | 1:fdd22bb7aa52 | 47 | /** |
emilmont | 1:fdd22bb7aa52 | 48 | * @addtogroup Corr |
emilmont | 1:fdd22bb7aa52 | 49 | * @{ |
emilmont | 1:fdd22bb7aa52 | 50 | */ |
emilmont | 1:fdd22bb7aa52 | 51 | |
emilmont | 1:fdd22bb7aa52 | 52 | /** |
emilmont | 1:fdd22bb7aa52 | 53 | * @brief Correlation of Q7 sequences. |
emilmont | 1:fdd22bb7aa52 | 54 | * @param[in] *pSrcA points to the first input sequence. |
emilmont | 1:fdd22bb7aa52 | 55 | * @param[in] srcALen length of the first input sequence. |
emilmont | 1:fdd22bb7aa52 | 56 | * @param[in] *pSrcB points to the second input sequence. |
emilmont | 1:fdd22bb7aa52 | 57 | * @param[in] srcBLen length of the second input sequence. |
emilmont | 1:fdd22bb7aa52 | 58 | * @param[out] *pDst points to the location where the output result is written. Length 2 * max(srcALen, srcBLen) - 1. |
emilmont | 1:fdd22bb7aa52 | 59 | * @param[in] *pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. |
emilmont | 1:fdd22bb7aa52 | 60 | * @param[in] *pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). |
emilmont | 1:fdd22bb7aa52 | 61 | * @return none. |
emilmont | 1:fdd22bb7aa52 | 62 | * |
emilmont | 1:fdd22bb7aa52 | 63 | * |
emilmont | 1:fdd22bb7aa52 | 64 | * \par Restrictions |
emilmont | 1:fdd22bb7aa52 | 65 | * If the silicon does not support unaligned memory access enable the macro UNALIGNED_SUPPORT_DISABLE |
emilmont | 2:da51fb522205 | 66 | * In this case input, output, scratch1 and scratch2 buffers should be aligned by 32-bit |
emilmont | 1:fdd22bb7aa52 | 67 | * |
emilmont | 1:fdd22bb7aa52 | 68 | * @details |
emilmont | 1:fdd22bb7aa52 | 69 | * <b>Scaling and Overflow Behavior:</b> |
emilmont | 1:fdd22bb7aa52 | 70 | * |
emilmont | 1:fdd22bb7aa52 | 71 | * \par |
emilmont | 1:fdd22bb7aa52 | 72 | * The function is implemented using a 32-bit internal accumulator. |
emilmont | 1:fdd22bb7aa52 | 73 | * Both the inputs are represented in 1.7 format and multiplications yield a 2.14 result. |
emilmont | 1:fdd22bb7aa52 | 74 | * The 2.14 intermediate results are accumulated in a 32-bit accumulator in 18.14 format. |
emilmont | 1:fdd22bb7aa52 | 75 | * This approach provides 17 guard bits and there is no risk of overflow as long as <code>max(srcALen, srcBLen)<131072</code>. |
emilmont | 1:fdd22bb7aa52 | 76 | * The 18.14 result is then truncated to 18.7 format by discarding the low 7 bits and saturated to 1.7 format. |
emilmont | 1:fdd22bb7aa52 | 77 | * |
emilmont | 1:fdd22bb7aa52 | 78 | * |
emilmont | 1:fdd22bb7aa52 | 79 | */ |
emilmont | 1:fdd22bb7aa52 | 80 | |
emilmont | 1:fdd22bb7aa52 | 81 | |
emilmont | 1:fdd22bb7aa52 | 82 | |
emilmont | 1:fdd22bb7aa52 | 83 | void arm_correlate_opt_q7( |
emilmont | 1:fdd22bb7aa52 | 84 | q7_t * pSrcA, |
emilmont | 1:fdd22bb7aa52 | 85 | uint32_t srcALen, |
emilmont | 1:fdd22bb7aa52 | 86 | q7_t * pSrcB, |
emilmont | 1:fdd22bb7aa52 | 87 | uint32_t srcBLen, |
emilmont | 1:fdd22bb7aa52 | 88 | q7_t * pDst, |
emilmont | 1:fdd22bb7aa52 | 89 | q15_t * pScratch1, |
emilmont | 1:fdd22bb7aa52 | 90 | q15_t * pScratch2) |
emilmont | 1:fdd22bb7aa52 | 91 | { |
emilmont | 1:fdd22bb7aa52 | 92 | q7_t *pOut = pDst; /* output pointer */ |
emilmont | 1:fdd22bb7aa52 | 93 | q15_t *pScr1 = pScratch1; /* Temporary pointer for scratch */ |
emilmont | 1:fdd22bb7aa52 | 94 | q15_t *pScr2 = pScratch2; /* Temporary pointer for scratch */ |
emilmont | 1:fdd22bb7aa52 | 95 | q7_t *pIn1; /* inputA pointer */ |
emilmont | 1:fdd22bb7aa52 | 96 | q7_t *pIn2; /* inputB pointer */ |
emilmont | 1:fdd22bb7aa52 | 97 | q15_t *py; /* Intermediate inputB pointer */ |
emilmont | 1:fdd22bb7aa52 | 98 | q31_t acc0, acc1, acc2, acc3; /* Accumulators */ |
emilmont | 1:fdd22bb7aa52 | 99 | uint32_t j, k = 0u, blkCnt; /* loop counter */ |
emilmont | 1:fdd22bb7aa52 | 100 | int32_t inc = 1; /* output pointer increment */ |
emilmont | 1:fdd22bb7aa52 | 101 | uint32_t outBlockSize; /* loop counter */ |
emilmont | 1:fdd22bb7aa52 | 102 | q15_t x4; /* Temporary input variable */ |
emilmont | 1:fdd22bb7aa52 | 103 | uint32_t tapCnt; /* loop counter */ |
emilmont | 1:fdd22bb7aa52 | 104 | q31_t x1, x2, x3, y1; /* Temporary input variables */ |
emilmont | 1:fdd22bb7aa52 | 105 | |
emilmont | 1:fdd22bb7aa52 | 106 | /* The algorithm implementation is based on the lengths of the inputs. */ |
emilmont | 1:fdd22bb7aa52 | 107 | /* srcB is always made to slide across srcA. */ |
emilmont | 1:fdd22bb7aa52 | 108 | /* So srcBLen is always considered as shorter or equal to srcALen */ |
emilmont | 1:fdd22bb7aa52 | 109 | /* But CORR(x, y) is reverse of CORR(y, x) */ |
emilmont | 1:fdd22bb7aa52 | 110 | /* So, when srcBLen > srcALen, output pointer is made to point to the end of the output buffer */ |
emilmont | 1:fdd22bb7aa52 | 111 | /* and the destination pointer modifier, inc is set to -1 */ |
emilmont | 1:fdd22bb7aa52 | 112 | /* If srcALen > srcBLen, zero pad has to be done to srcB to make the two inputs of same length */ |
emilmont | 1:fdd22bb7aa52 | 113 | /* But to improve the performance, |
emilmont | 1:fdd22bb7aa52 | 114 | * we include zeroes in the output instead of zero padding either of the the inputs*/ |
emilmont | 1:fdd22bb7aa52 | 115 | /* If srcALen > srcBLen, |
emilmont | 1:fdd22bb7aa52 | 116 | * (srcALen - srcBLen) zeroes has to included in the starting of the output buffer */ |
emilmont | 1:fdd22bb7aa52 | 117 | /* If srcALen < srcBLen, |
emilmont | 1:fdd22bb7aa52 | 118 | * (srcALen - srcBLen) zeroes has to included in the ending of the output buffer */ |
emilmont | 1:fdd22bb7aa52 | 119 | if(srcALen >= srcBLen) |
emilmont | 1:fdd22bb7aa52 | 120 | { |
emilmont | 1:fdd22bb7aa52 | 121 | /* Initialization of inputA pointer */ |
emilmont | 1:fdd22bb7aa52 | 122 | pIn1 = (pSrcA); |
emilmont | 1:fdd22bb7aa52 | 123 | |
emilmont | 1:fdd22bb7aa52 | 124 | /* Initialization of inputB pointer */ |
emilmont | 1:fdd22bb7aa52 | 125 | pIn2 = (pSrcB); |
emilmont | 1:fdd22bb7aa52 | 126 | |
emilmont | 1:fdd22bb7aa52 | 127 | /* Number of output samples is calculated */ |
emilmont | 1:fdd22bb7aa52 | 128 | outBlockSize = (2u * srcALen) - 1u; |
emilmont | 1:fdd22bb7aa52 | 129 | |
emilmont | 1:fdd22bb7aa52 | 130 | /* When srcALen > srcBLen, zero padding is done to srcB |
emilmont | 1:fdd22bb7aa52 | 131 | * to make their lengths equal. |
emilmont | 1:fdd22bb7aa52 | 132 | * Instead, (outBlockSize - (srcALen + srcBLen - 1)) |
emilmont | 1:fdd22bb7aa52 | 133 | * number of output samples are made zero */ |
emilmont | 1:fdd22bb7aa52 | 134 | j = outBlockSize - (srcALen + (srcBLen - 1u)); |
emilmont | 1:fdd22bb7aa52 | 135 | |
emilmont | 1:fdd22bb7aa52 | 136 | /* Updating the pointer position to non zero value */ |
emilmont | 1:fdd22bb7aa52 | 137 | pOut += j; |
emilmont | 1:fdd22bb7aa52 | 138 | |
emilmont | 1:fdd22bb7aa52 | 139 | } |
emilmont | 1:fdd22bb7aa52 | 140 | else |
emilmont | 1:fdd22bb7aa52 | 141 | { |
emilmont | 1:fdd22bb7aa52 | 142 | /* Initialization of inputA pointer */ |
emilmont | 1:fdd22bb7aa52 | 143 | pIn1 = (pSrcB); |
emilmont | 1:fdd22bb7aa52 | 144 | |
emilmont | 1:fdd22bb7aa52 | 145 | /* Initialization of inputB pointer */ |
emilmont | 1:fdd22bb7aa52 | 146 | pIn2 = (pSrcA); |
emilmont | 1:fdd22bb7aa52 | 147 | |
emilmont | 1:fdd22bb7aa52 | 148 | /* srcBLen is always considered as shorter or equal to srcALen */ |
emilmont | 1:fdd22bb7aa52 | 149 | j = srcBLen; |
emilmont | 1:fdd22bb7aa52 | 150 | srcBLen = srcALen; |
emilmont | 1:fdd22bb7aa52 | 151 | srcALen = j; |
emilmont | 1:fdd22bb7aa52 | 152 | |
emilmont | 1:fdd22bb7aa52 | 153 | /* CORR(x, y) = Reverse order(CORR(y, x)) */ |
emilmont | 1:fdd22bb7aa52 | 154 | /* Hence set the destination pointer to point to the last output sample */ |
emilmont | 1:fdd22bb7aa52 | 155 | pOut = pDst + ((srcALen + srcBLen) - 2u); |
emilmont | 1:fdd22bb7aa52 | 156 | |
emilmont | 1:fdd22bb7aa52 | 157 | /* Destination address modifier is set to -1 */ |
emilmont | 1:fdd22bb7aa52 | 158 | inc = -1; |
emilmont | 1:fdd22bb7aa52 | 159 | |
emilmont | 1:fdd22bb7aa52 | 160 | } |
emilmont | 1:fdd22bb7aa52 | 161 | |
emilmont | 1:fdd22bb7aa52 | 162 | |
emilmont | 1:fdd22bb7aa52 | 163 | /* Copy (srcBLen) samples in scratch buffer */ |
emilmont | 1:fdd22bb7aa52 | 164 | k = srcBLen >> 2u; |
emilmont | 1:fdd22bb7aa52 | 165 | |
emilmont | 1:fdd22bb7aa52 | 166 | /* First part of the processing with loop unrolling copies 4 data points at a time. |
emilmont | 1:fdd22bb7aa52 | 167 | ** a second loop below copies for the remaining 1 to 3 samples. */ |
emilmont | 1:fdd22bb7aa52 | 168 | while(k > 0u) |
emilmont | 1:fdd22bb7aa52 | 169 | { |
emilmont | 1:fdd22bb7aa52 | 170 | /* copy second buffer in reversal manner */ |
emilmont | 1:fdd22bb7aa52 | 171 | x4 = (q15_t) * pIn2++; |
emilmont | 1:fdd22bb7aa52 | 172 | *pScr2++ = x4; |
emilmont | 1:fdd22bb7aa52 | 173 | x4 = (q15_t) * pIn2++; |
emilmont | 1:fdd22bb7aa52 | 174 | *pScr2++ = x4; |
emilmont | 1:fdd22bb7aa52 | 175 | x4 = (q15_t) * pIn2++; |
emilmont | 1:fdd22bb7aa52 | 176 | *pScr2++ = x4; |
emilmont | 1:fdd22bb7aa52 | 177 | x4 = (q15_t) * pIn2++; |
emilmont | 1:fdd22bb7aa52 | 178 | *pScr2++ = x4; |
emilmont | 1:fdd22bb7aa52 | 179 | |
emilmont | 1:fdd22bb7aa52 | 180 | /* Decrement the loop counter */ |
emilmont | 1:fdd22bb7aa52 | 181 | k--; |
emilmont | 1:fdd22bb7aa52 | 182 | } |
emilmont | 1:fdd22bb7aa52 | 183 | |
emilmont | 1:fdd22bb7aa52 | 184 | /* If the count is not a multiple of 4, copy remaining samples here. |
emilmont | 1:fdd22bb7aa52 | 185 | ** No loop unrolling is used. */ |
emilmont | 1:fdd22bb7aa52 | 186 | k = srcBLen % 0x4u; |
emilmont | 1:fdd22bb7aa52 | 187 | |
emilmont | 1:fdd22bb7aa52 | 188 | while(k > 0u) |
emilmont | 1:fdd22bb7aa52 | 189 | { |
emilmont | 1:fdd22bb7aa52 | 190 | /* copy second buffer in reversal manner for remaining samples */ |
emilmont | 1:fdd22bb7aa52 | 191 | x4 = (q15_t) * pIn2++; |
emilmont | 1:fdd22bb7aa52 | 192 | *pScr2++ = x4; |
emilmont | 1:fdd22bb7aa52 | 193 | |
emilmont | 1:fdd22bb7aa52 | 194 | /* Decrement the loop counter */ |
emilmont | 1:fdd22bb7aa52 | 195 | k--; |
emilmont | 1:fdd22bb7aa52 | 196 | } |
emilmont | 1:fdd22bb7aa52 | 197 | |
emilmont | 1:fdd22bb7aa52 | 198 | /* Fill (srcBLen - 1u) zeros in scratch buffer */ |
emilmont | 1:fdd22bb7aa52 | 199 | arm_fill_q15(0, pScr1, (srcBLen - 1u)); |
emilmont | 1:fdd22bb7aa52 | 200 | |
emilmont | 1:fdd22bb7aa52 | 201 | /* Update temporary scratch pointer */ |
emilmont | 1:fdd22bb7aa52 | 202 | pScr1 += (srcBLen - 1u); |
emilmont | 1:fdd22bb7aa52 | 203 | |
emilmont | 1:fdd22bb7aa52 | 204 | /* Copy (srcALen) samples in scratch buffer */ |
emilmont | 1:fdd22bb7aa52 | 205 | k = srcALen >> 2u; |
emilmont | 1:fdd22bb7aa52 | 206 | |
emilmont | 1:fdd22bb7aa52 | 207 | /* First part of the processing with loop unrolling copies 4 data points at a time. |
emilmont | 1:fdd22bb7aa52 | 208 | ** a second loop below copies for the remaining 1 to 3 samples. */ |
emilmont | 1:fdd22bb7aa52 | 209 | while(k > 0u) |
emilmont | 1:fdd22bb7aa52 | 210 | { |
emilmont | 1:fdd22bb7aa52 | 211 | /* copy second buffer in reversal manner */ |
emilmont | 1:fdd22bb7aa52 | 212 | x4 = (q15_t) * pIn1++; |
emilmont | 1:fdd22bb7aa52 | 213 | *pScr1++ = x4; |
emilmont | 1:fdd22bb7aa52 | 214 | x4 = (q15_t) * pIn1++; |
emilmont | 1:fdd22bb7aa52 | 215 | *pScr1++ = x4; |
emilmont | 1:fdd22bb7aa52 | 216 | x4 = (q15_t) * pIn1++; |
emilmont | 1:fdd22bb7aa52 | 217 | *pScr1++ = x4; |
emilmont | 1:fdd22bb7aa52 | 218 | x4 = (q15_t) * pIn1++; |
emilmont | 1:fdd22bb7aa52 | 219 | *pScr1++ = x4; |
emilmont | 1:fdd22bb7aa52 | 220 | |
emilmont | 1:fdd22bb7aa52 | 221 | /* Decrement the loop counter */ |
emilmont | 1:fdd22bb7aa52 | 222 | k--; |
emilmont | 1:fdd22bb7aa52 | 223 | } |
emilmont | 1:fdd22bb7aa52 | 224 | |
emilmont | 1:fdd22bb7aa52 | 225 | /* If the count is not a multiple of 4, copy remaining samples here. |
emilmont | 1:fdd22bb7aa52 | 226 | ** No loop unrolling is used. */ |
emilmont | 1:fdd22bb7aa52 | 227 | k = srcALen % 0x4u; |
emilmont | 1:fdd22bb7aa52 | 228 | |
emilmont | 1:fdd22bb7aa52 | 229 | while(k > 0u) |
emilmont | 1:fdd22bb7aa52 | 230 | { |
emilmont | 1:fdd22bb7aa52 | 231 | /* copy second buffer in reversal manner for remaining samples */ |
emilmont | 1:fdd22bb7aa52 | 232 | x4 = (q15_t) * pIn1++; |
emilmont | 1:fdd22bb7aa52 | 233 | *pScr1++ = x4; |
emilmont | 1:fdd22bb7aa52 | 234 | |
emilmont | 1:fdd22bb7aa52 | 235 | /* Decrement the loop counter */ |
emilmont | 1:fdd22bb7aa52 | 236 | k--; |
emilmont | 1:fdd22bb7aa52 | 237 | } |
emilmont | 1:fdd22bb7aa52 | 238 | |
emilmont | 1:fdd22bb7aa52 | 239 | #ifndef UNALIGNED_SUPPORT_DISABLE |
emilmont | 1:fdd22bb7aa52 | 240 | |
emilmont | 1:fdd22bb7aa52 | 241 | /* Fill (srcBLen - 1u) zeros at end of scratch buffer */ |
emilmont | 1:fdd22bb7aa52 | 242 | arm_fill_q15(0, pScr1, (srcBLen - 1u)); |
emilmont | 1:fdd22bb7aa52 | 243 | |
emilmont | 1:fdd22bb7aa52 | 244 | /* Update pointer */ |
emilmont | 1:fdd22bb7aa52 | 245 | pScr1 += (srcBLen - 1u); |
emilmont | 1:fdd22bb7aa52 | 246 | |
emilmont | 1:fdd22bb7aa52 | 247 | #else |
emilmont | 1:fdd22bb7aa52 | 248 | |
emilmont | 1:fdd22bb7aa52 | 249 | /* Apply loop unrolling and do 4 Copies simultaneously. */ |
emilmont | 1:fdd22bb7aa52 | 250 | k = (srcBLen - 1u) >> 2u; |
emilmont | 1:fdd22bb7aa52 | 251 | |
emilmont | 1:fdd22bb7aa52 | 252 | /* First part of the processing with loop unrolling copies 4 data points at a time. |
emilmont | 1:fdd22bb7aa52 | 253 | ** a second loop below copies for the remaining 1 to 3 samples. */ |
emilmont | 1:fdd22bb7aa52 | 254 | while(k > 0u) |
emilmont | 1:fdd22bb7aa52 | 255 | { |
emilmont | 1:fdd22bb7aa52 | 256 | /* copy second buffer in reversal manner */ |
emilmont | 1:fdd22bb7aa52 | 257 | *pScr1++ = 0; |
emilmont | 1:fdd22bb7aa52 | 258 | *pScr1++ = 0; |
emilmont | 1:fdd22bb7aa52 | 259 | *pScr1++ = 0; |
emilmont | 1:fdd22bb7aa52 | 260 | *pScr1++ = 0; |
emilmont | 1:fdd22bb7aa52 | 261 | |
emilmont | 1:fdd22bb7aa52 | 262 | /* Decrement the loop counter */ |
emilmont | 1:fdd22bb7aa52 | 263 | k--; |
emilmont | 1:fdd22bb7aa52 | 264 | } |
emilmont | 1:fdd22bb7aa52 | 265 | |
emilmont | 1:fdd22bb7aa52 | 266 | /* If the count is not a multiple of 4, copy remaining samples here. |
emilmont | 1:fdd22bb7aa52 | 267 | ** No loop unrolling is used. */ |
emilmont | 1:fdd22bb7aa52 | 268 | k = (srcBLen - 1u) % 0x4u; |
emilmont | 1:fdd22bb7aa52 | 269 | |
emilmont | 1:fdd22bb7aa52 | 270 | while(k > 0u) |
emilmont | 1:fdd22bb7aa52 | 271 | { |
emilmont | 1:fdd22bb7aa52 | 272 | /* copy second buffer in reversal manner for remaining samples */ |
emilmont | 1:fdd22bb7aa52 | 273 | *pScr1++ = 0; |
emilmont | 1:fdd22bb7aa52 | 274 | |
emilmont | 1:fdd22bb7aa52 | 275 | /* Decrement the loop counter */ |
emilmont | 1:fdd22bb7aa52 | 276 | k--; |
emilmont | 1:fdd22bb7aa52 | 277 | } |
emilmont | 1:fdd22bb7aa52 | 278 | |
emilmont | 2:da51fb522205 | 279 | #endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */ |
emilmont | 1:fdd22bb7aa52 | 280 | |
emilmont | 1:fdd22bb7aa52 | 281 | /* Temporary pointer for second sequence */ |
emilmont | 1:fdd22bb7aa52 | 282 | py = pScratch2; |
emilmont | 1:fdd22bb7aa52 | 283 | |
emilmont | 1:fdd22bb7aa52 | 284 | /* Initialization of pScr2 pointer */ |
emilmont | 1:fdd22bb7aa52 | 285 | pScr2 = pScratch2; |
emilmont | 1:fdd22bb7aa52 | 286 | |
emilmont | 1:fdd22bb7aa52 | 287 | /* Actual correlation process starts here */ |
emilmont | 1:fdd22bb7aa52 | 288 | blkCnt = (srcALen + srcBLen - 1u) >> 2; |
emilmont | 1:fdd22bb7aa52 | 289 | |
emilmont | 1:fdd22bb7aa52 | 290 | while(blkCnt > 0) |
emilmont | 1:fdd22bb7aa52 | 291 | { |
emilmont | 1:fdd22bb7aa52 | 292 | /* Initialze temporary scratch pointer as scratch1 */ |
emilmont | 1:fdd22bb7aa52 | 293 | pScr1 = pScratch1; |
emilmont | 1:fdd22bb7aa52 | 294 | |
emilmont | 1:fdd22bb7aa52 | 295 | /* Clear Accumlators */ |
emilmont | 1:fdd22bb7aa52 | 296 | acc0 = 0; |
emilmont | 1:fdd22bb7aa52 | 297 | acc1 = 0; |
emilmont | 1:fdd22bb7aa52 | 298 | acc2 = 0; |
emilmont | 1:fdd22bb7aa52 | 299 | acc3 = 0; |
emilmont | 1:fdd22bb7aa52 | 300 | |
emilmont | 1:fdd22bb7aa52 | 301 | /* Read two samples from scratch1 buffer */ |
emilmont | 1:fdd22bb7aa52 | 302 | x1 = *__SIMD32(pScr1)++; |
emilmont | 1:fdd22bb7aa52 | 303 | |
emilmont | 1:fdd22bb7aa52 | 304 | /* Read next two samples from scratch1 buffer */ |
emilmont | 1:fdd22bb7aa52 | 305 | x2 = *__SIMD32(pScr1)++; |
emilmont | 1:fdd22bb7aa52 | 306 | |
emilmont | 1:fdd22bb7aa52 | 307 | tapCnt = (srcBLen) >> 2u; |
emilmont | 1:fdd22bb7aa52 | 308 | |
emilmont | 1:fdd22bb7aa52 | 309 | while(tapCnt > 0u) |
emilmont | 1:fdd22bb7aa52 | 310 | { |
emilmont | 1:fdd22bb7aa52 | 311 | |
emilmont | 1:fdd22bb7aa52 | 312 | /* Read four samples from smaller buffer */ |
emilmont | 1:fdd22bb7aa52 | 313 | y1 = _SIMD32_OFFSET(pScr2); |
emilmont | 1:fdd22bb7aa52 | 314 | |
emilmont | 1:fdd22bb7aa52 | 315 | /* multiply and accumlate */ |
emilmont | 1:fdd22bb7aa52 | 316 | acc0 = __SMLAD(x1, y1, acc0); |
emilmont | 1:fdd22bb7aa52 | 317 | acc2 = __SMLAD(x2, y1, acc2); |
emilmont | 1:fdd22bb7aa52 | 318 | |
emilmont | 1:fdd22bb7aa52 | 319 | /* pack input data */ |
emilmont | 1:fdd22bb7aa52 | 320 | #ifndef ARM_MATH_BIG_ENDIAN |
emilmont | 1:fdd22bb7aa52 | 321 | x3 = __PKHBT(x2, x1, 0); |
emilmont | 1:fdd22bb7aa52 | 322 | #else |
emilmont | 1:fdd22bb7aa52 | 323 | x3 = __PKHBT(x1, x2, 0); |
emilmont | 1:fdd22bb7aa52 | 324 | #endif |
emilmont | 1:fdd22bb7aa52 | 325 | |
emilmont | 1:fdd22bb7aa52 | 326 | /* multiply and accumlate */ |
emilmont | 1:fdd22bb7aa52 | 327 | acc1 = __SMLADX(x3, y1, acc1); |
emilmont | 1:fdd22bb7aa52 | 328 | |
emilmont | 1:fdd22bb7aa52 | 329 | /* Read next two samples from scratch1 buffer */ |
emilmont | 1:fdd22bb7aa52 | 330 | x1 = *__SIMD32(pScr1)++; |
emilmont | 1:fdd22bb7aa52 | 331 | |
emilmont | 1:fdd22bb7aa52 | 332 | /* pack input data */ |
emilmont | 1:fdd22bb7aa52 | 333 | #ifndef ARM_MATH_BIG_ENDIAN |
emilmont | 1:fdd22bb7aa52 | 334 | x3 = __PKHBT(x1, x2, 0); |
emilmont | 1:fdd22bb7aa52 | 335 | #else |
emilmont | 1:fdd22bb7aa52 | 336 | x3 = __PKHBT(x2, x1, 0); |
emilmont | 1:fdd22bb7aa52 | 337 | #endif |
emilmont | 1:fdd22bb7aa52 | 338 | |
emilmont | 1:fdd22bb7aa52 | 339 | acc3 = __SMLADX(x3, y1, acc3); |
emilmont | 1:fdd22bb7aa52 | 340 | |
emilmont | 1:fdd22bb7aa52 | 341 | /* Read four samples from smaller buffer */ |
emilmont | 1:fdd22bb7aa52 | 342 | y1 = _SIMD32_OFFSET(pScr2 + 2u); |
emilmont | 1:fdd22bb7aa52 | 343 | |
emilmont | 1:fdd22bb7aa52 | 344 | acc0 = __SMLAD(x2, y1, acc0); |
emilmont | 1:fdd22bb7aa52 | 345 | |
emilmont | 1:fdd22bb7aa52 | 346 | acc2 = __SMLAD(x1, y1, acc2); |
emilmont | 1:fdd22bb7aa52 | 347 | |
emilmont | 1:fdd22bb7aa52 | 348 | acc1 = __SMLADX(x3, y1, acc1); |
emilmont | 1:fdd22bb7aa52 | 349 | |
emilmont | 1:fdd22bb7aa52 | 350 | x2 = *__SIMD32(pScr1)++; |
emilmont | 1:fdd22bb7aa52 | 351 | |
emilmont | 1:fdd22bb7aa52 | 352 | #ifndef ARM_MATH_BIG_ENDIAN |
emilmont | 1:fdd22bb7aa52 | 353 | x3 = __PKHBT(x2, x1, 0); |
emilmont | 1:fdd22bb7aa52 | 354 | #else |
emilmont | 1:fdd22bb7aa52 | 355 | x3 = __PKHBT(x1, x2, 0); |
emilmont | 1:fdd22bb7aa52 | 356 | #endif |
emilmont | 1:fdd22bb7aa52 | 357 | |
emilmont | 1:fdd22bb7aa52 | 358 | acc3 = __SMLADX(x3, y1, acc3); |
emilmont | 1:fdd22bb7aa52 | 359 | |
emilmont | 1:fdd22bb7aa52 | 360 | pScr2 += 4u; |
emilmont | 1:fdd22bb7aa52 | 361 | |
emilmont | 1:fdd22bb7aa52 | 362 | |
emilmont | 1:fdd22bb7aa52 | 363 | /* Decrement the loop counter */ |
emilmont | 1:fdd22bb7aa52 | 364 | tapCnt--; |
emilmont | 1:fdd22bb7aa52 | 365 | } |
emilmont | 1:fdd22bb7aa52 | 366 | |
emilmont | 1:fdd22bb7aa52 | 367 | |
emilmont | 1:fdd22bb7aa52 | 368 | |
emilmont | 1:fdd22bb7aa52 | 369 | /* Update scratch pointer for remaining samples of smaller length sequence */ |
emilmont | 1:fdd22bb7aa52 | 370 | pScr1 -= 4u; |
emilmont | 1:fdd22bb7aa52 | 371 | |
emilmont | 1:fdd22bb7aa52 | 372 | |
emilmont | 1:fdd22bb7aa52 | 373 | /* apply same above for remaining samples of smaller length sequence */ |
emilmont | 1:fdd22bb7aa52 | 374 | tapCnt = (srcBLen) & 3u; |
emilmont | 1:fdd22bb7aa52 | 375 | |
emilmont | 1:fdd22bb7aa52 | 376 | while(tapCnt > 0u) |
emilmont | 1:fdd22bb7aa52 | 377 | { |
emilmont | 1:fdd22bb7aa52 | 378 | |
emilmont | 1:fdd22bb7aa52 | 379 | /* accumlate the results */ |
emilmont | 1:fdd22bb7aa52 | 380 | acc0 += (*pScr1++ * *pScr2); |
emilmont | 1:fdd22bb7aa52 | 381 | acc1 += (*pScr1++ * *pScr2); |
emilmont | 1:fdd22bb7aa52 | 382 | acc2 += (*pScr1++ * *pScr2); |
emilmont | 1:fdd22bb7aa52 | 383 | acc3 += (*pScr1++ * *pScr2++); |
emilmont | 1:fdd22bb7aa52 | 384 | |
emilmont | 1:fdd22bb7aa52 | 385 | pScr1 -= 3u; |
emilmont | 1:fdd22bb7aa52 | 386 | |
emilmont | 1:fdd22bb7aa52 | 387 | /* Decrement the loop counter */ |
emilmont | 1:fdd22bb7aa52 | 388 | tapCnt--; |
emilmont | 1:fdd22bb7aa52 | 389 | } |
emilmont | 1:fdd22bb7aa52 | 390 | |
emilmont | 1:fdd22bb7aa52 | 391 | blkCnt--; |
emilmont | 1:fdd22bb7aa52 | 392 | |
emilmont | 1:fdd22bb7aa52 | 393 | /* Store the result in the accumulator in the destination buffer. */ |
emilmont | 1:fdd22bb7aa52 | 394 | *pOut = (q7_t) (__SSAT(acc0 >> 7u, 8)); |
emilmont | 1:fdd22bb7aa52 | 395 | pOut += inc; |
emilmont | 1:fdd22bb7aa52 | 396 | *pOut = (q7_t) (__SSAT(acc1 >> 7u, 8)); |
emilmont | 1:fdd22bb7aa52 | 397 | pOut += inc; |
emilmont | 1:fdd22bb7aa52 | 398 | *pOut = (q7_t) (__SSAT(acc2 >> 7u, 8)); |
emilmont | 1:fdd22bb7aa52 | 399 | pOut += inc; |
emilmont | 1:fdd22bb7aa52 | 400 | *pOut = (q7_t) (__SSAT(acc3 >> 7u, 8)); |
emilmont | 1:fdd22bb7aa52 | 401 | pOut += inc; |
emilmont | 1:fdd22bb7aa52 | 402 | |
emilmont | 1:fdd22bb7aa52 | 403 | /* Initialization of inputB pointer */ |
emilmont | 1:fdd22bb7aa52 | 404 | pScr2 = py; |
emilmont | 1:fdd22bb7aa52 | 405 | |
emilmont | 1:fdd22bb7aa52 | 406 | pScratch1 += 4u; |
emilmont | 1:fdd22bb7aa52 | 407 | |
emilmont | 1:fdd22bb7aa52 | 408 | } |
emilmont | 1:fdd22bb7aa52 | 409 | |
emilmont | 1:fdd22bb7aa52 | 410 | |
emilmont | 1:fdd22bb7aa52 | 411 | blkCnt = (srcALen + srcBLen - 1u) & 0x3; |
emilmont | 1:fdd22bb7aa52 | 412 | |
emilmont | 1:fdd22bb7aa52 | 413 | /* Calculate correlation for remaining samples of Bigger length sequence */ |
emilmont | 1:fdd22bb7aa52 | 414 | while(blkCnt > 0) |
emilmont | 1:fdd22bb7aa52 | 415 | { |
emilmont | 1:fdd22bb7aa52 | 416 | /* Initialze temporary scratch pointer as scratch1 */ |
emilmont | 1:fdd22bb7aa52 | 417 | pScr1 = pScratch1; |
emilmont | 1:fdd22bb7aa52 | 418 | |
emilmont | 1:fdd22bb7aa52 | 419 | /* Clear Accumlators */ |
emilmont | 1:fdd22bb7aa52 | 420 | acc0 = 0; |
emilmont | 1:fdd22bb7aa52 | 421 | |
emilmont | 1:fdd22bb7aa52 | 422 | tapCnt = (srcBLen) >> 1u; |
emilmont | 1:fdd22bb7aa52 | 423 | |
emilmont | 1:fdd22bb7aa52 | 424 | while(tapCnt > 0u) |
emilmont | 1:fdd22bb7aa52 | 425 | { |
emilmont | 1:fdd22bb7aa52 | 426 | acc0 += (*pScr1++ * *pScr2++); |
emilmont | 1:fdd22bb7aa52 | 427 | acc0 += (*pScr1++ * *pScr2++); |
emilmont | 1:fdd22bb7aa52 | 428 | |
emilmont | 1:fdd22bb7aa52 | 429 | /* Decrement the loop counter */ |
emilmont | 1:fdd22bb7aa52 | 430 | tapCnt--; |
emilmont | 1:fdd22bb7aa52 | 431 | } |
emilmont | 1:fdd22bb7aa52 | 432 | |
emilmont | 1:fdd22bb7aa52 | 433 | tapCnt = (srcBLen) & 1u; |
emilmont | 1:fdd22bb7aa52 | 434 | |
emilmont | 1:fdd22bb7aa52 | 435 | /* apply same above for remaining samples of smaller length sequence */ |
emilmont | 1:fdd22bb7aa52 | 436 | while(tapCnt > 0u) |
emilmont | 1:fdd22bb7aa52 | 437 | { |
emilmont | 1:fdd22bb7aa52 | 438 | |
emilmont | 1:fdd22bb7aa52 | 439 | /* accumlate the results */ |
emilmont | 1:fdd22bb7aa52 | 440 | acc0 += (*pScr1++ * *pScr2++); |
emilmont | 1:fdd22bb7aa52 | 441 | |
emilmont | 1:fdd22bb7aa52 | 442 | /* Decrement the loop counter */ |
emilmont | 1:fdd22bb7aa52 | 443 | tapCnt--; |
emilmont | 1:fdd22bb7aa52 | 444 | } |
emilmont | 1:fdd22bb7aa52 | 445 | |
emilmont | 1:fdd22bb7aa52 | 446 | blkCnt--; |
emilmont | 1:fdd22bb7aa52 | 447 | |
emilmont | 1:fdd22bb7aa52 | 448 | /* Store the result in the accumulator in the destination buffer. */ |
emilmont | 1:fdd22bb7aa52 | 449 | *pOut = (q7_t) (__SSAT(acc0 >> 7u, 8)); |
emilmont | 1:fdd22bb7aa52 | 450 | |
emilmont | 1:fdd22bb7aa52 | 451 | pOut += inc; |
emilmont | 1:fdd22bb7aa52 | 452 | |
emilmont | 1:fdd22bb7aa52 | 453 | /* Initialization of inputB pointer */ |
emilmont | 1:fdd22bb7aa52 | 454 | pScr2 = py; |
emilmont | 1:fdd22bb7aa52 | 455 | |
emilmont | 1:fdd22bb7aa52 | 456 | pScratch1 += 1u; |
emilmont | 1:fdd22bb7aa52 | 457 | |
emilmont | 1:fdd22bb7aa52 | 458 | } |
emilmont | 1:fdd22bb7aa52 | 459 | |
emilmont | 1:fdd22bb7aa52 | 460 | } |
emilmont | 1:fdd22bb7aa52 | 461 | |
emilmont | 1:fdd22bb7aa52 | 462 | /** |
emilmont | 1:fdd22bb7aa52 | 463 | * @} end of Corr group |
emilmont | 1:fdd22bb7aa52 | 464 | */ |