source: trunk/fw_g473rct/Drivers/CMSIS/NN/Include/arm_nnsupportfunctions.h

Last change on this file was 20, checked in by f.jahn, 4 months ago

adc dma funktioniert und modbus funktioniert

File size: 7.4 KB
Line 
1/*
2 * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19/* ----------------------------------------------------------------------
20 * Project: CMSIS NN Library
21 * Title: arm_nnsupportfunctions.h
22 * Description: Public header file of support functions for CMSIS NN Library
23 *
24 * $Date: 13. July 2018
25 * $Revision: V.1.0.0
26 *
27 * Target Processor: Cortex-M cores
28 * -------------------------------------------------------------------- */
29
30#ifndef _ARM_NNSUPPORTFUNCTIONS_H_
31#define _ARM_NNSUPPORTFUNCTIONS_H_
32
33#include "arm_math.h"
34#include "arm_common_tables.h"
35
36#ifdef __cplusplus
37extern "C"
38{
39#endif
40
41#define LEFT_SHIFT(_shift) (_shift > 0 ? _shift : 0)
42#define RIGHT_SHIFT(_shift) (_shift > 0 ? 0 : -_shift)
43#define Q31_MIN (0x80000000L)
44#define Q31_MAX (0x7FFFFFFFL)
45
46/**
47 * @brief Union for SIMD access of Q31/Q15/Q7 types
48 */
49union arm_nnword
50{
51 q31_t word;
52 /**< Q31 type */
53 q15_t half_words[2];
54 /**< Q15 type */
55 q7_t bytes[4];
56 /**< Q7 type */
57};
58
59/**
60 * @brief Struct for specifying activation function types
61 *
62 */
63typedef enum
64{
65 ARM_SIGMOID = 0,
66 /**< Sigmoid activation function */
67 ARM_TANH = 1,
68 /**< Tanh activation function */
69} arm_nn_activation_type;
70
71/**
72 * @defgroup nndata_convert Neural Network Data Conversion Functions
73 *
74 * Perform data type conversion in-between neural network operations
75 *
76 */
77
78/**
79 * @brief Converts the elements of the Q7 vector to Q15 vector without left-shift
80 * @param[in] *pSrc points to the Q7 input vector
81 * @param[out] *pDst points to the Q15 output vector
82 * @param[in] blockSize length of the input vector
83 * @return none.
84 *
85 */
86
87void arm_q7_to_q15_no_shift(const q7_t * pSrc, q15_t * pDst, uint32_t blockSize);
88
89/**
90 * @brief Converts the elements of the Q7 vector to reordered Q15 vector without left-shift
91 * @param[in] *pSrc points to the Q7 input vector
92 * @param[out] *pDst points to the Q15 output vector
93 * @param[in] blockSize length of the input vector
94 * @return none.
95 *
96 */
97
98void arm_q7_to_q15_reordered_no_shift(const q7_t * pSrc, q15_t * pDst, uint32_t blockSize);
99
100#if defined (ARM_MATH_DSP)
101
102/**
103 * @brief read and expand one Q7 word into two Q15 words
104 */
105
106__STATIC_FORCEINLINE void *read_and_pad(void *source, q31_t * out1, q31_t * out2)
107{
108 q31_t inA = *__SIMD32(source)++;
109 q31_t inAbuf1 = __SXTB16(__ROR(inA, 8));
110 q31_t inAbuf2 = __SXTB16(inA);
111
112#ifndef ARM_MATH_BIG_ENDIAN
113 *out2 = __PKHTB(inAbuf1, inAbuf2, 16);
114 *out1 = __PKHBT(inAbuf2, inAbuf1, 16);
115#else
116 *out1 = __PKHTB(inAbuf1, inAbuf2, 16);
117 *out2 = __PKHBT(inAbuf2, inAbuf1, 16);
118#endif
119
120 return source;
121}
122
123/**
124 * @brief read and expand one Q7 word into two Q15 words with reordering
125 */
126
127__STATIC_FORCEINLINE void *read_and_pad_reordered(void *source, q31_t * out1, q31_t * out2)
128{
129 q31_t inA = *__SIMD32(source)++;
130#ifndef ARM_MATH_BIG_ENDIAN
131 *out2 = __SXTB16(__ROR(inA, 8));
132 *out1 = __SXTB16(inA);
133#else
134 *out1 = __SXTB16(__ROR(inA, 8));
135 *out2 = __SXTB16(inA);
136#endif
137
138 return source;
139}
140#endif
141
142/**
143 * @defgroup NNBasicMath Basic Math Functions for Neural Network Computation
144 *
145 * Basic Math Functions for Neural Network Computation
146 *
147 */
148
149/**
150 * @brief Q7 vector multiplication with variable output shifts
151 * @param[in] *pSrcA pointer to the first input vector
152 * @param[in] *pSrcB pointer to the second input vector
153 * @param[out] *pDst pointer to the output vector
154 * @param[in] out_shift amount of right-shift for output
155 * @param[in] blockSize number of samples in each vector
156 * @return none.
157 *
158 * <b>Scaling and Overflow Behavior:</b>
159 * \par
160 * The function uses saturating arithmetic.
161 * Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
162 */
163
164void arm_nn_mult_q15(
165 q15_t * pSrcA,
166 q15_t * pSrcB,
167 q15_t * pDst,
168 const uint16_t out_shift,
169 uint32_t blockSize);
170
171/**
172 * @brief Q7 vector multiplication with variable output shifts
173 * @param[in] *pSrcA pointer to the first input vector
174 * @param[in] *pSrcB pointer to the second input vector
175 * @param[out] *pDst pointer to the output vector
176 * @param[in] out_shift amount of right-shift for output
177 * @param[in] blockSize number of samples in each vector
178 * @return none.
179 *
180 * <b>Scaling and Overflow Behavior:</b>
181 * \par
182 * The function uses saturating arithmetic.
183 * Results outside of the allowable Q7 range [0x80 0x7F] will be saturated.
184 */
185
186void arm_nn_mult_q7(
187 q7_t * pSrcA,
188 q7_t * pSrcB,
189 q7_t * pDst,
190 const uint16_t out_shift,
191 uint32_t blockSize);
192
193/**
194 * @brief macro for adding rounding offset
195 */
196#ifndef ARM_NN_TRUNCATE
197 #define NN_ROUND(out_shift) ( (0x1u << out_shift) >> 1 )
198#else
199 #define NN_ROUND(out_shift) 0
200#endif
201
202/**
203 * @brief Saturating doubling high multiply. Result matches
204 * NEON instruction VQRDMULH.
205 * @param[in] m1 Multiplicand
206 * @param[in] m2 Multiplier
207 * @return Result of multiplication.
208 *
209 */
210__STATIC_FORCEINLINE q31_t arm_nn_sat_doubling_high_mult(const q31_t m1, const q31_t m2)
211{
212 q31_t result = 0;
213 // Rounding offset to add for a right shift of 31
214 q63_t mult = 1 << 30;
215
216 if ((m1 < 0) ^ (m2 < 0))
217 {
218 mult = 1 - mult;
219 }
220 // Gets resolved as a SMLAL instruction
221 mult = mult + (q63_t)m1 * m2;
222
223 // Utilize all of the upper 32 bits. This is the doubling step
224 // as well.
225 result = mult / (1UL << 31);
226
227 if ((m1 == m2) && (m1 == Q31_MIN))
228 {
229 result = Q31_MAX;
230 }
231 return result;
232}
233
234/**
235 * @brief Rounding divide by power of two.
236 * @param[in] dividend - Dividend
237 * @param[in] exponent - Divisor = power(2, exponent)
238 * Range: [0, 31]
239 * @return Rounded result of division. Midpoint is rounded away from zero.
240 *
241 */
242__STATIC_FORCEINLINE q31_t arm_nn_divide_by_power_of_two(const q31_t dividend, const q31_t exponent)
243{
244 q31_t result = 0;
245 const q31_t remainder_mask = (1l << exponent) - 1;
246 int32_t remainder = remainder_mask & dividend;
247
248 // Basic division
249 result = dividend >> exponent;
250
251 // Adjust 'result' for rounding (mid point away from zero)
252 q31_t threshold = remainder_mask >> 1;
253 if (result < 0)
254 {
255 threshold++;
256 }
257 if (remainder > threshold)
258 {
259 result++;
260 }
261
262 return result;
263}
264
265#ifdef __cplusplus
266}
267#endif
268
269#endif
Note: See TracBrowser for help on using the repository browser.