da4ml 0.5.1.post1__cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. da4ml/__init__.py +4 -0
  2. da4ml/_binary/__init__.py +15 -0
  3. da4ml/_binary/dais_bin.cpython-311-x86_64-linux-gnu.so +0 -0
  4. da4ml/_binary/dais_bin.pyi +5 -0
  5. da4ml/_cli/__init__.py +30 -0
  6. da4ml/_cli/convert.py +204 -0
  7. da4ml/_cli/report.py +295 -0
  8. da4ml/_version.py +32 -0
  9. da4ml/cmvm/__init__.py +4 -0
  10. da4ml/cmvm/api.py +264 -0
  11. da4ml/cmvm/core/__init__.py +221 -0
  12. da4ml/cmvm/core/indexers.py +83 -0
  13. da4ml/cmvm/core/state_opr.py +284 -0
  14. da4ml/cmvm/types.py +739 -0
  15. da4ml/cmvm/util/__init__.py +7 -0
  16. da4ml/cmvm/util/bit_decompose.py +86 -0
  17. da4ml/cmvm/util/mat_decompose.py +121 -0
  18. da4ml/codegen/__init__.py +9 -0
  19. da4ml/codegen/hls/__init__.py +4 -0
  20. da4ml/codegen/hls/hls_codegen.py +196 -0
  21. da4ml/codegen/hls/hls_model.py +255 -0
  22. da4ml/codegen/hls/source/ap_types/ap_binary.h +78 -0
  23. da4ml/codegen/hls/source/ap_types/ap_common.h +376 -0
  24. da4ml/codegen/hls/source/ap_types/ap_decl.h +212 -0
  25. da4ml/codegen/hls/source/ap_types/ap_fixed.h +360 -0
  26. da4ml/codegen/hls/source/ap_types/ap_fixed_base.h +2354 -0
  27. da4ml/codegen/hls/source/ap_types/ap_fixed_ref.h +718 -0
  28. da4ml/codegen/hls/source/ap_types/ap_fixed_special.h +230 -0
  29. da4ml/codegen/hls/source/ap_types/ap_int.h +330 -0
  30. da4ml/codegen/hls/source/ap_types/ap_int_base.h +1885 -0
  31. da4ml/codegen/hls/source/ap_types/ap_int_ref.h +1346 -0
  32. da4ml/codegen/hls/source/ap_types/ap_int_special.h +223 -0
  33. da4ml/codegen/hls/source/ap_types/ap_shift_reg.h +138 -0
  34. da4ml/codegen/hls/source/ap_types/etc/ap_private.h +7199 -0
  35. da4ml/codegen/hls/source/ap_types/hls_math.h +27 -0
  36. da4ml/codegen/hls/source/ap_types/hls_stream.h +263 -0
  37. da4ml/codegen/hls/source/ap_types/utils/x_hls_utils.h +80 -0
  38. da4ml/codegen/hls/source/binder_util.hh +71 -0
  39. da4ml/codegen/hls/source/build_binder.mk +22 -0
  40. da4ml/codegen/hls/source/vitis_bitshift.hh +32 -0
  41. da4ml/codegen/rtl/__init__.py +15 -0
  42. da4ml/codegen/rtl/common_source/binder_util.hh +99 -0
  43. da4ml/codegen/rtl/common_source/build_binder.mk +34 -0
  44. da4ml/codegen/rtl/common_source/build_quartus_prj.tcl +104 -0
  45. da4ml/codegen/rtl/common_source/build_vivado_prj.tcl +111 -0
  46. da4ml/codegen/rtl/common_source/ioutil.hh +124 -0
  47. da4ml/codegen/rtl/common_source/template.sdc +27 -0
  48. da4ml/codegen/rtl/common_source/template.xdc +30 -0
  49. da4ml/codegen/rtl/rtl_model.py +486 -0
  50. da4ml/codegen/rtl/verilog/__init__.py +10 -0
  51. da4ml/codegen/rtl/verilog/comb.py +239 -0
  52. da4ml/codegen/rtl/verilog/io_wrapper.py +113 -0
  53. da4ml/codegen/rtl/verilog/pipeline.py +67 -0
  54. da4ml/codegen/rtl/verilog/source/lookup_table.v +27 -0
  55. da4ml/codegen/rtl/verilog/source/multiplier.v +37 -0
  56. da4ml/codegen/rtl/verilog/source/mux.v +58 -0
  57. da4ml/codegen/rtl/verilog/source/negative.v +31 -0
  58. da4ml/codegen/rtl/verilog/source/shift_adder.v +59 -0
  59. da4ml/codegen/rtl/vhdl/__init__.py +9 -0
  60. da4ml/codegen/rtl/vhdl/comb.py +206 -0
  61. da4ml/codegen/rtl/vhdl/io_wrapper.py +120 -0
  62. da4ml/codegen/rtl/vhdl/pipeline.py +71 -0
  63. da4ml/codegen/rtl/vhdl/source/lookup_table.vhd +52 -0
  64. da4ml/codegen/rtl/vhdl/source/multiplier.vhd +40 -0
  65. da4ml/codegen/rtl/vhdl/source/mux.vhd +102 -0
  66. da4ml/codegen/rtl/vhdl/source/negative.vhd +35 -0
  67. da4ml/codegen/rtl/vhdl/source/shift_adder.vhd +101 -0
  68. da4ml/converter/__init__.py +63 -0
  69. da4ml/converter/hgq2/__init__.py +3 -0
  70. da4ml/converter/hgq2/layers/__init__.py +11 -0
  71. da4ml/converter/hgq2/layers/_base.py +132 -0
  72. da4ml/converter/hgq2/layers/activation.py +81 -0
  73. da4ml/converter/hgq2/layers/attn.py +148 -0
  74. da4ml/converter/hgq2/layers/batchnorm.py +15 -0
  75. da4ml/converter/hgq2/layers/conv.py +149 -0
  76. da4ml/converter/hgq2/layers/dense.py +39 -0
  77. da4ml/converter/hgq2/layers/ops.py +246 -0
  78. da4ml/converter/hgq2/layers/pool.py +107 -0
  79. da4ml/converter/hgq2/layers/table.py +176 -0
  80. da4ml/converter/hgq2/parser.py +161 -0
  81. da4ml/trace/__init__.py +6 -0
  82. da4ml/trace/fixed_variable.py +965 -0
  83. da4ml/trace/fixed_variable_array.py +600 -0
  84. da4ml/trace/ops/__init__.py +13 -0
  85. da4ml/trace/ops/einsum_utils.py +305 -0
  86. da4ml/trace/ops/quantization.py +74 -0
  87. da4ml/trace/ops/reduce_utils.py +105 -0
  88. da4ml/trace/pipeline.py +181 -0
  89. da4ml/trace/tracer.py +186 -0
  90. da4ml/typing/__init__.py +3 -0
  91. da4ml-0.5.1.post1.dist-info/METADATA +85 -0
  92. da4ml-0.5.1.post1.dist-info/RECORD +96 -0
  93. da4ml-0.5.1.post1.dist-info/WHEEL +6 -0
  94. da4ml-0.5.1.post1.dist-info/entry_points.txt +3 -0
  95. da4ml-0.5.1.post1.dist-info/sboms/auditwheel.cdx.json +1 -0
  96. da4ml.libs/libgomp-e985bcbb.so.1.0.0 +0 -0
@@ -0,0 +1,1885 @@
1
+ /*
2
+ * Copyright 2011-2019 Xilinx, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ #ifndef __AP_INT_BASE_H__
18
+ #define __AP_INT_BASE_H__
19
+
20
+ #ifndef __AP_INT_H__
21
+ #error "Only ap_fixed.h and ap_int.h can be included directly in user code."
22
+ #endif
23
+
24
+ #ifndef __cplusplus
25
+ #error "C++ is required to include this header file"
26
+ #else
27
+
28
+ #include <ap_common.h>
29
+ #ifndef __SYNTHESIS__
30
+ #if _AP_ENABLE_HALF_ == 1
31
+ #include <hls_half.h>
32
+ #endif
33
+ #include <iostream>
34
+ #include <string.h>
35
+ #endif
36
+
37
+ /* ----------------------------------------------------------------
38
+ * ap_int_base: AutoPilot integer/Arbitrary precision integer.
39
+ * ----------------------------------------------------------------
40
+ */
41
+
42
+ /* helper trait. Selecting the smallest C type that can hold the value,
43
+ * return 64 bit C type if not possible.
44
+ */
45
+ template <int _AP_N, bool _AP_S>
46
+ struct retval;
47
+
48
+ // at least 64 bit
49
+ template <int _AP_N>
50
+ struct retval<_AP_N, true> {
51
+ typedef ap_slong Type;
52
+ };
53
+
54
+ template <int _AP_N>
55
+ struct retval<_AP_N, false> {
56
+ typedef ap_ulong Type;
57
+ };
58
+
59
+ // at least 8 bit
60
+ template <>
61
+ struct retval<1, true> {
62
+ typedef signed char Type;
63
+ };
64
+
65
+ template <>
66
+ struct retval<1, false> {
67
+ typedef unsigned char Type;
68
+ };
69
+
70
+ // at least 16 bit
71
+ template <>
72
+ struct retval<2, true> {
73
+ typedef short Type;
74
+ };
75
+
76
+ template <>
77
+ struct retval<2, false> {
78
+ typedef unsigned short Type;
79
+ };
80
+
81
+ // at least 32 bit
82
+ template <>
83
+ struct retval<3, true> {
84
+ typedef long Type;
85
+ };
86
+
87
+ template <>
88
+ struct retval<3, false> {
89
+ typedef unsigned long Type;
90
+ };
91
+
92
+ template <>
93
+ struct retval<4, true> {
94
+ typedef long Type;
95
+ };
96
+
97
+ template <>
98
+ struct retval<4, false> {
99
+ typedef unsigned long Type;
100
+ };
101
+
102
+ // trait for letting base class to return derived class.
103
+ // Notice that derived class template is incomplete, and we cannot use
104
+ // the member of the derived class.
105
+ template <int _AP_W2, bool _AP_S2>
106
+ struct _ap_int_factory;
107
+ template <int _AP_W2>
108
+ struct _ap_int_factory<_AP_W2,true> { typedef ap_int<_AP_W2> type; };
109
+ template <int _AP_W2>
110
+ struct _ap_int_factory<_AP_W2,false> { typedef ap_uint<_AP_W2> type; };
111
+
112
+ template <int _AP_W, bool _AP_S>
113
+ struct ap_int_base : public _AP_ROOT_TYPE<_AP_W, _AP_S> {
114
+ public:
115
+ typedef _AP_ROOT_TYPE<_AP_W, _AP_S> Base;
116
+
117
+ /* ap_int_base<_AP_W, _AP_S, true>
118
+ * typedef typename retval<(_AP_W + 7) / 8, _AP_S>::Type RetType;
119
+ *
120
+ * ap_int_base<_AP_W, _AP_S, false>
121
+ * typedef typename retval<8, _AP_S>::Type RetType;
122
+ */
123
+ typedef typename retval<AP_MAX((_AP_W + 7) / 8, 8), _AP_S>::Type RetType;
124
+
125
+ static const int width = _AP_W;
126
+
127
+ template <int _AP_W2, bool _AP_S2>
128
+ struct RType {
129
+ enum {
130
+ mult_w = _AP_W + _AP_W2,
131
+ mult_s = _AP_S || _AP_S2,
132
+ plus_w =
133
+ AP_MAX(_AP_W + (_AP_S2 && !_AP_S), _AP_W2 + (_AP_S && !_AP_S2)) + 1,
134
+ plus_s = _AP_S || _AP_S2,
135
+ minus_w =
136
+ AP_MAX(_AP_W + (_AP_S2 && !_AP_S), _AP_W2 + (_AP_S && !_AP_S2)) + 1,
137
+ minus_s = true,
138
+ div_w = _AP_W + _AP_S2,
139
+ div_s = _AP_S || _AP_S2,
140
+ mod_w = AP_MIN(_AP_W, _AP_W2 + (!_AP_S2 && _AP_S)),
141
+ mod_s = _AP_S,
142
+ logic_w = AP_MAX(_AP_W + (_AP_S2 && !_AP_S), _AP_W2 + (_AP_S && !_AP_S2)),
143
+ logic_s = _AP_S || _AP_S2
144
+ };
145
+
146
+
147
+ typedef ap_int_base<mult_w, mult_s> mult_base;
148
+ typedef ap_int_base<plus_w, plus_s> plus_base;
149
+ typedef ap_int_base<minus_w, minus_s> minus_base;
150
+ typedef ap_int_base<logic_w, logic_s> logic_base;
151
+ typedef ap_int_base<div_w, div_s> div_base;
152
+ typedef ap_int_base<mod_w, mod_s> mod_base;
153
+ typedef ap_int_base<_AP_W, _AP_S> arg1_base;
154
+
155
+ typedef typename _ap_int_factory<mult_w, mult_s>::type mult;
156
+ typedef typename _ap_int_factory<plus_w, plus_s>::type plus;
157
+ typedef typename _ap_int_factory<minus_w, minus_s>::type minus;
158
+ typedef typename _ap_int_factory<logic_w, logic_s>::type logic;
159
+ typedef typename _ap_int_factory<div_w, div_s>::type div;
160
+ typedef typename _ap_int_factory<mod_w, mod_s>::type mod;
161
+ typedef typename _ap_int_factory<_AP_W, _AP_S>::type arg1;
162
+ typedef bool reduce;
163
+ };
164
+
165
+ /* Constructors.
166
+ * ----------------------------------------------------------------
167
+ */
168
+ /// default ctor
169
+ INLINE ap_int_base() {
170
+ /*
171
+ #ifdef __SC_COMPATIBLE__
172
+ Base::V = 0;
173
+ #endif
174
+ */
175
+ }
176
+
177
+ /// copy ctor
178
+ template <int _AP_W2, bool _AP_S2>
179
+ INLINE ap_int_base(const ap_int_base<_AP_W2, _AP_S2>& op) {
180
+ Base::V = op.V;
181
+ }
182
+
183
+ /// volatile copy ctor
184
+ template <int _AP_W2, bool _AP_S2>
185
+ INLINE ap_int_base(const volatile ap_int_base<_AP_W2, _AP_S2>& op) {
186
+ Base::V = op.V;
187
+ }
188
+
189
+ // XXX C++11 feature.
190
+ // The explicit specifier specifies that a constructor or conversion function
191
+ // (since C++11) doesn't allow implicit conversions or copy-initialization.
192
+ // ap_int_base<W,S> x = 1;
193
+ // ap_int_base<W,S> foo() { return 1; }
194
+ // but allows
195
+ // ap_int_base<W,S> x(1);
196
+ // ap_int_base<W,S> y {1};
197
+
198
+ /// from all c types.
199
+ #define CTOR_FROM_INT(Type, Size, Signed) \
200
+ INLINE ap_int_base(const Type op) { Base::V = op; }
201
+
202
+ CTOR_FROM_INT(bool, 1, false)
203
+ CTOR_FROM_INT(char, 8, CHAR_IS_SIGNED)
204
+ CTOR_FROM_INT(signed char, 8, true)
205
+ CTOR_FROM_INT(unsigned char, 8, false)
206
+ CTOR_FROM_INT(short, _AP_SIZE_short, true)
207
+ CTOR_FROM_INT(unsigned short, _AP_SIZE_short, false)
208
+ CTOR_FROM_INT(int, _AP_SIZE_int, true)
209
+ CTOR_FROM_INT(unsigned int, _AP_SIZE_int, false)
210
+ CTOR_FROM_INT(long, _AP_SIZE_long, true)
211
+ CTOR_FROM_INT(unsigned long, _AP_SIZE_long, false)
212
+ CTOR_FROM_INT(ap_slong, _AP_SIZE_ap_slong, true)
213
+ CTOR_FROM_INT(ap_ulong, _AP_SIZE_ap_slong, false)
214
+ #undef CTOR_FROM_INT
215
+
216
+ #if _AP_ENABLE_HALF_ == 1
217
+ /// ctor from half.
218
+ // TODO optimize
219
+ INLINE ap_int_base(half op) {
220
+ ap_int_base<_AP_W, _AP_S> t((float)op);
221
+ Base::V = t.V;
222
+ }
223
+ #endif
224
+
225
+ /// ctor from float.
226
+ INLINE ap_int_base(float op) {
227
+ const int BITS = FLOAT_MAN + FLOAT_EXP + 1;
228
+ ap_int_base<BITS, false> reg;
229
+ reg.V = floatToRawBits(op);
230
+ bool is_neg = _AP_ROOT_op_get_bit(reg.V, BITS - 1);
231
+
232
+ ap_int_base<FLOAT_EXP + 1, true> exp = 0;
233
+ exp.V = _AP_ROOT_op_get_range(reg.V, FLOAT_MAN, BITS - 2);
234
+ exp = exp - FLOAT_BIAS;
235
+
236
+ ap_int_base<FLOAT_MAN + 2, true> man;
237
+ man.V = _AP_ROOT_op_get_range(reg.V, 0, FLOAT_MAN - 1);
238
+ // check for NaN
239
+ _AP_WARNING(exp == ((unsigned char)(FLOAT_BIAS + 1)) && man.V != 0,
240
+ "assign NaN to ap integer value");
241
+ // set leading 1.
242
+ man.V = _AP_ROOT_op_set_bit(man.V, FLOAT_MAN, 1);
243
+ //if (is_neg) man = -man;
244
+
245
+ if ((reg.V & 0x7ffffffful) == 0) {
246
+ Base::V = 0;
247
+ } else {
248
+ int sh_amt = FLOAT_MAN - exp.V;
249
+ if (sh_amt == 0) {
250
+ Base::V = man.V;
251
+ } else if (sh_amt > 0) {
252
+ if (sh_amt < FLOAT_MAN + 2) {
253
+ Base::V = man.V >> sh_amt;
254
+ } else {
255
+ if (is_neg)
256
+ Base::V = -1;
257
+ else
258
+ Base::V = 0;
259
+ }
260
+ } else {
261
+ sh_amt = -sh_amt;
262
+ if (sh_amt < _AP_W) {
263
+ Base::V = man.V;
264
+ Base::V <<= sh_amt;
265
+ } else {
266
+ Base::V = 0;
267
+ }
268
+ }
269
+ }
270
+ if (is_neg) *this = -(*this);
271
+ }
272
+
273
+ /// ctor from double.
274
+ INLINE ap_int_base(double op) {
275
+ const int BITS = DOUBLE_MAN + DOUBLE_EXP + 1;
276
+ ap_int_base<BITS, false> reg;
277
+ reg.V = doubleToRawBits(op);
278
+ bool is_neg = _AP_ROOT_op_get_bit(reg.V, BITS - 1);
279
+
280
+ ap_int_base<DOUBLE_EXP + 1, true> exp = 0;
281
+ exp.V = _AP_ROOT_op_get_range(reg.V, DOUBLE_MAN, BITS - 2);
282
+ exp = exp - DOUBLE_BIAS;
283
+
284
+ ap_int_base<DOUBLE_MAN + 2, true> man;
285
+ man.V = _AP_ROOT_op_get_range(reg.V, 0, DOUBLE_MAN - 1);
286
+ // check for NaN
287
+ _AP_WARNING(exp == ((unsigned char)(DOUBLE_BIAS + 1)) && man.V != 0,
288
+ "assign NaN to ap integer value");
289
+ // set leading 1.
290
+ man.V = _AP_ROOT_op_set_bit(man.V, DOUBLE_MAN, 1);
291
+ //if (is_neg) man = -man;
292
+
293
+ if ((reg.V & 0x7fffffffffffffffull) == 0) {
294
+ Base::V = 0;
295
+ } else {
296
+ int sh_amt = DOUBLE_MAN - exp.V;
297
+ if (sh_amt == 0) {
298
+ Base::V = man.V;
299
+ } else if (sh_amt > 0) {
300
+ if (sh_amt < DOUBLE_MAN + 2) {
301
+ Base::V = man.V >> sh_amt;
302
+ } else {
303
+ if (is_neg)
304
+ Base::V = -1;
305
+ else
306
+ Base::V = 0;
307
+ }
308
+ } else {
309
+ sh_amt = -sh_amt;
310
+ if (sh_amt < _AP_W) {
311
+ Base::V = man.V;
312
+ Base::V <<= sh_amt;
313
+ } else {
314
+ Base::V = 0;
315
+ }
316
+ }
317
+ }
318
+ if (is_neg) *this = -(*this);
319
+ }
320
+
321
+ /// from higer rank type.
322
+ template <int _AP_W2, int _AP_I2, bool _AP_S2, ap_q_mode _AP_Q2,
323
+ ap_o_mode _AP_O2, int _AP_N2>
324
+ INLINE ap_int_base(
325
+ const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) {
326
+ Base::V = op.to_ap_int_base().V;
327
+ }
328
+
329
+ template <int _AP_W2, bool _AP_S2>
330
+ INLINE ap_int_base(const ap_range_ref<_AP_W2, _AP_S2>& ref) {
331
+ Base::V = (ref.get()).V;
332
+ }
333
+
334
+ template <int _AP_W2, bool _AP_S2>
335
+ INLINE ap_int_base(const ap_bit_ref<_AP_W2, _AP_S2>& ref) {
336
+ Base::V = ref.operator bool();
337
+ }
338
+
339
+ template <int _AP_W2, typename _AP_T2, int _AP_W3, typename _AP_T3>
340
+ INLINE ap_int_base(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& ref) {
341
+ const ap_int_base<ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>::_AP_WR,
342
+ false>
343
+ tmp = ref.get();
344
+ Base::V = tmp.V;
345
+ }
346
+
347
+ /* radix has default value in set */
348
+
349
+ #ifndef __SYNTHESIS__
350
+ INLINE ap_int_base(const char* s, signed char rd = 0) {
351
+ if (rd == 0)
352
+ rd = guess_radix(s);
353
+ unsigned int length = strlen(s);
354
+ Base::V.fromString(s, length, rd);
355
+ }
356
+ #else
357
+ // XXX __builtin_bit_from_string(...) requires const C string and radix.
358
+ INLINE ap_int_base(const char* s) {
359
+ typeof(Base::V) t;
360
+ _ssdm_string2bits((void*)(&t), (const char*)(s), 10, _AP_W, _AP_S,
361
+ AP_TRN, AP_WRAP, 0, _AP_C99);
362
+ Base::V = t;
363
+ }
364
+ INLINE ap_int_base(const char* s, signed char rd) {
365
+ typeof(Base::V) t;
366
+ _ssdm_string2bits((void*)(&t), (const char*)(s), rd, _AP_W, _AP_S,
367
+ AP_TRN, AP_WRAP, 0, _AP_C99);
368
+ Base::V = t;
369
+ }
370
+ #endif
371
+
372
+ template <int _AP_W2, int _AP_I2, bool _AP_S2, ap_q_mode _AP_Q2,
373
+ ap_o_mode _AP_O2, int _AP_N2>
374
+ INLINE ap_int_base(
375
+ const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& val) {
376
+ Base::V = (val.get()).V;
377
+ }
378
+
379
+ template <int _AP_W2, int _AP_I2, bool _AP_S2, ap_q_mode _AP_Q2,
380
+ ap_o_mode _AP_O2, int _AP_N2>
381
+ INLINE ap_int_base(
382
+ const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& val) {
383
+ Base::V = val.operator bool();
384
+ }
385
+
386
+ INLINE ap_int_base read() volatile {
387
+ /*AP_DEBUG(printf("call read %d\n", Base::V););*/
388
+ ap_int_base ret;
389
+ ret.V = Base::V;
390
+ return ret;
391
+ }
392
+
393
+ INLINE void write(const ap_int_base<_AP_W, _AP_S>& op2) volatile {
394
+ /*AP_DEBUG(printf("call write %d\n", op2.V););*/
395
+ Base::V = op2.V;
396
+ }
397
+
398
+ /* Another form of "write".*/
399
+ template <int _AP_W2, bool _AP_S2>
400
+ INLINE void operator=(
401
+ const volatile ap_int_base<_AP_W2, _AP_S2>& op2) volatile {
402
+ Base::V = op2.V;
403
+ }
404
+
405
+ INLINE void operator=(
406
+ const volatile ap_int_base<_AP_W, _AP_S>& op2) volatile {
407
+ Base::V = op2.V;
408
+ }
409
+
410
+ template <int _AP_W2, bool _AP_S2>
411
+ INLINE void operator=(const ap_int_base<_AP_W2, _AP_S2>& op2) volatile {
412
+ Base::V = op2.V;
413
+ }
414
+
415
+ INLINE void operator=(const ap_int_base<_AP_W, _AP_S>& op2) volatile {
416
+ Base::V = op2.V;
417
+ }
418
+
419
+ template <int _AP_W2, bool _AP_S2>
420
+ INLINE ap_int_base& operator=(
421
+ const volatile ap_int_base<_AP_W2, _AP_S2>& op2) {
422
+ Base::V = op2.V;
423
+ return *this;
424
+ }
425
+
426
+ template <int _AP_W2, bool _AP_S2>
427
+ INLINE ap_int_base& operator=(const ap_int_base<_AP_W2, _AP_S2>& op2) {
428
+ Base::V = op2.V;
429
+ return *this;
430
+ }
431
+
432
+ INLINE ap_int_base& operator=(const volatile ap_int_base<_AP_W, _AP_S>& op2) {
433
+ Base::V = op2.V;
434
+ return *this;
435
+ }
436
+
437
+ INLINE ap_int_base& operator=(const ap_int_base<_AP_W, _AP_S>& op2) {
438
+ Base::V = op2.V;
439
+ return *this;
440
+ }
441
+
442
+
443
+ #define ASSIGN_OP_FROM_INT(Type, Size, Signed) \
444
+ INLINE ap_int_base& operator=(Type op) { \
445
+ Base::V = op; \
446
+ return *this; \
447
+ }
448
+
449
+ ASSIGN_OP_FROM_INT(bool, 1, false)
450
+ ASSIGN_OP_FROM_INT(char, 8, CHAR_IS_SIGNED)
451
+ ASSIGN_OP_FROM_INT(signed char, 8, true)
452
+ ASSIGN_OP_FROM_INT(unsigned char, 8, false)
453
+ ASSIGN_OP_FROM_INT(short, _AP_SIZE_short, true)
454
+ ASSIGN_OP_FROM_INT(unsigned short, _AP_SIZE_short, false)
455
+ ASSIGN_OP_FROM_INT(int, _AP_SIZE_int, true)
456
+ ASSIGN_OP_FROM_INT(unsigned int, _AP_SIZE_int, false)
457
+ ASSIGN_OP_FROM_INT(long, _AP_SIZE_long, true)
458
+ ASSIGN_OP_FROM_INT(unsigned long, _AP_SIZE_long, false)
459
+ ASSIGN_OP_FROM_INT(ap_slong, _AP_SIZE_ap_slong, true)
460
+ ASSIGN_OP_FROM_INT(ap_ulong, _AP_SIZE_ap_slong, false)
461
+
462
+ #undef ASSIGN_OP_FROM_INT
463
+
464
+ template <int _AP_W2, bool _AP_S2>
465
+ INLINE ap_int_base& operator=(const ap_bit_ref<_AP_W2, _AP_S2>& op2) {
466
+ Base::V = (bool)op2;
467
+ return *this;
468
+ }
469
+
470
+ template <int _AP_W2, bool _AP_S2>
471
+ INLINE ap_int_base& operator=(const ap_range_ref<_AP_W2, _AP_S2>& op2) {
472
+ Base::V = (ap_int_base<_AP_W2, false>(op2)).V;
473
+ return *this;
474
+ }
475
+
476
+ template <int _AP_W2, typename _AP_T2, int _AP_W3, typename _AP_T3>
477
+ INLINE ap_int_base& operator=(
478
+ const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& op2) {
479
+ Base::V = op2.get().V;
480
+ return *this;
481
+ }
482
+
483
+ template <int _AP_W2, int _AP_I2, bool _AP_S2, ap_q_mode _AP_Q2,
484
+ ap_o_mode _AP_O2, int _AP_N2>
485
+ INLINE ap_int_base& operator=(
486
+ const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) {
487
+ Base::V = op.to_ap_int_base().V;
488
+ return *this;
489
+ }
490
+
491
+ template <int _AP_W2, int _AP_I2, bool _AP_S2, ap_q_mode _AP_Q2,
492
+ ap_o_mode _AP_O2, int _AP_N2>
493
+ INLINE ap_int_base& operator=(
494
+ const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) {
495
+ Base::V = (bool)op;
496
+ return *this;
497
+ }
498
+
499
+ template <int _AP_W2, int _AP_I2, bool _AP_S2, ap_q_mode _AP_Q2,
500
+ ap_o_mode _AP_O2, int _AP_N2>
501
+ INLINE ap_int_base& operator=(
502
+ const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& op) {
503
+ Base::V = ((const ap_int_base<_AP_W2, false>)(op)).V;
504
+ return *this;
505
+ }
506
+
507
+ // FIXME: UG902 has clearly required user to use to_int() to convert to built-in
508
+ // types, but this implicit conversion is relied on in hls_cordic.h and hls_rsr.h.
509
+ // For example:
510
+ // int d_exp = fps_x.exp - fps_y.exp;
511
+ INLINE operator RetType() const { return (RetType)(Base::V); }
512
+
513
+ /* Explicit conversions to C types.
514
+ * ----------------------------------------------------------------
515
+ */
516
+ INLINE bool to_bool() const { return (bool)(Base::V); }
517
+ INLINE char to_char() const { return (char)(Base::V); }
518
+ INLINE signed char to_schar() const { return (signed char)(Base::V); }
519
+ INLINE unsigned char to_uchar() const { return (unsigned char)(Base::V); }
520
+ INLINE short to_short() const { return (short)(Base::V); }
521
+ INLINE unsigned short to_ushort() const { return (unsigned short)(Base::V); }
522
+ INLINE int to_int() const { return (int)(Base::V); }
523
+ INLINE unsigned to_uint() const { return (unsigned)(Base::V); }
524
+ INLINE long to_long() const { return (long)(Base::V); }
525
+ INLINE unsigned long to_ulong() const { return (unsigned long)(Base::V); }
526
+ INLINE ap_slong to_int64() const { return (ap_slong)(Base::V); }
527
+ INLINE ap_ulong to_uint64() const { return (ap_ulong)(Base::V); }
528
+ INLINE float to_float() const { return (float)(Base::V); }
529
+ INLINE double to_double() const { return (double)(Base::V); }
530
+
531
+ // TODO decide if user-defined conversion should be provided.
532
+ #if 0
533
+ INLINE operator char() const { return (char)(Base::V); }
534
+ INLINE operator signed char() const { return (signed char)(Base::V); }
535
+ INLINE operator unsigned char() const { return (unsigned char)(Base::V); }
536
+ INLINE operator short() const { return (short)(Base::V); }
537
+ INLINE operator unsigned short() const { return (unsigned short)(Base::V); }
538
+ INLINE operator int() const { return (int)(Base::V); }
539
+ INLINE operator unsigned int () const { return (unsigned)(Base::V); }
540
+ INLINE operator long () const { return (long)(Base::V); }
541
+ INLINE operator unsigned long () const { return (unsigned long)(Base::V); }
542
+ INLINE operator ap_slong () { return (ap_slong)(Base::V); }
543
+ INLINE operator ap_ulong () { return (ap_ulong)(Base::V); }
544
+ #endif
545
+
546
+ /* Helper methods.
547
+ ----------------------------------------------------------------
548
+ */
549
+ /* we cannot call a non-volatile function on a volatile instance.
550
+ * but calling a volatile function is ok.
551
+ * XXX deleted non-volatile version.
552
+ */
553
+ INLINE int length() const volatile { return _AP_W; }
554
+
555
+ /*Return true if the value of ap_int_base instance is zero*/
556
+ INLINE bool iszero() const { return Base::V == 0; }
557
+
558
+ /*Return true if the value of ap_int_base instance is zero*/
559
+ INLINE bool is_zero() const { return Base::V == 0; }
560
+
561
+ /* x < 0 */
562
+ INLINE bool sign() const {
563
+ if (_AP_S &&
564
+ _AP_ROOT_op_get_bit(Base::V, _AP_W - 1))
565
+ return true;
566
+ else
567
+ return false;
568
+ }
569
+
570
+ /* x[i] = 0 */
571
+ INLINE void clear(int i) {
572
+ AP_ASSERT(i >= 0 && i < _AP_W, "position out of range");
573
+ Base::V = _AP_ROOT_op_set_bit(Base::V, i, 0);
574
+ }
575
+
576
+ /* x[i] = !x[i]*/
577
+ INLINE void invert(int i) {
578
+ AP_ASSERT(i >= 0 && i < _AP_W, "position out of range");
579
+ bool val = _AP_ROOT_op_get_bit(Base::V, i);
580
+ if (val)
581
+ Base::V = _AP_ROOT_op_set_bit(Base::V, i, 0);
582
+ else
583
+ Base::V = _AP_ROOT_op_set_bit(Base::V, i, 1);
584
+ }
585
+
586
+ INLINE bool test(int i) const {
587
+ AP_ASSERT(i >= 0 && i < _AP_W, "position out of range");
588
+ return _AP_ROOT_op_get_bit(Base::V, i);
589
+ }
590
+
591
+ // Get self. For ap_concat_ref expansion.
592
+ INLINE ap_int_base& get() { return *this; }
593
+
594
+ // Set the ith bit into 1
595
+ INLINE void set(int i) {
596
+ AP_ASSERT(i >= 0 && i < _AP_W, "position out of range");
597
+ Base::V = _AP_ROOT_op_set_bit(Base::V, i, 1);
598
+ }
599
+
600
+ // Set the ith bit into v
601
+ INLINE void set(int i, bool v) {
602
+ AP_ASSERT(i >= 0 && i < _AP_W, "position out of range");
603
+ Base::V = _AP_ROOT_op_set_bit(Base::V, i, v);
604
+ }
605
+
606
+ // This is used for sc_lv and sc_bv, which is implemented by sc_uint
607
+ // Rotate an ap_int_base object n places to the left
608
+ INLINE ap_int_base& lrotate(int n) {
609
+ AP_ASSERT(n >= 0 && n < _AP_W, "shift value out of range");
610
+ // TODO unify this.
611
+ #ifdef __SYNTHESIS__
612
+ typeof(Base::V) l_p = Base::V << n;
613
+ typeof(Base::V) r_p = Base::V >> (_AP_W - n);
614
+ Base::V = l_p | r_p;
615
+ #else
616
+ Base::V.lrotate(n);
617
+ #endif
618
+ return *this;
619
+ }
620
+
621
+ // This is used for sc_lv and sc_bv, which is implemented by sc_uint
622
+ // Rotate an ap_int_base object n places to the right
623
+ INLINE ap_int_base& rrotate(int n) {
624
+ AP_ASSERT(n >= 0 && n < _AP_W, "shift value out of range");
625
+ // TODO unify this.
626
+ #ifdef __SYNTHESIS__
627
+ typeof(Base::V) l_p = Base::V << (_AP_W - n);
628
+ typeof(Base::V) r_p = Base::V >> n;
629
+ Base::V = l_p | r_p;
630
+ #else
631
+ Base::V.rrotate(n);
632
+ #endif
633
+ return *this;
634
+ }
635
+
636
+ // Reverse the contents of ap_int_base instance.
637
+ // I.e. LSB becomes MSB and vise versa.
638
+ INLINE ap_int_base& reverse() {
639
+ Base::V = _AP_ROOT_op_get_range(Base::V, _AP_W - 1, 0);
640
+ return *this;
641
+ }
642
+
643
+ // Set the ith bit into v
644
+ INLINE void set_bit(int i, bool v) {
645
+ Base::V = _AP_ROOT_op_set_bit(Base::V, i, v);
646
+ }
647
+
648
+ // Get the value of ith bit
649
+ INLINE bool get_bit(int i) const {
650
+ return (bool)_AP_ROOT_op_get_bit(Base::V, i);
651
+ }
652
+
653
+ // complements every bit
654
+ INLINE void b_not() { Base::V = ~Base::V; }
655
+
656
+ #define OP_ASSIGN_AP(Sym) \
657
+ template <int _AP_W2, bool _AP_S2> \
658
+ INLINE ap_int_base& operator Sym(const ap_int_base<_AP_W2, _AP_S2>& op2) { \
659
+ Base::V Sym op2.V; \
660
+ return *this; \
661
+ }
662
+
663
+ /* Arithmetic assign.
664
+ * ----------------------------------------------------------------
665
+ */
666
+ OP_ASSIGN_AP(*=)
667
+ OP_ASSIGN_AP(+=)
668
+ OP_ASSIGN_AP(-=)
669
+ OP_ASSIGN_AP(/=)
670
+ OP_ASSIGN_AP(%=)
671
+ #undef OP_ASSIGN_AP
672
+
673
+ /* Bitwise assign: and, or, xor.
674
+ * ----------------------------------------------------------------
675
+ */
676
+ #define OP_ASSIGN_AP_CHK(Sym) \
677
+ template <int _AP_W2, bool _AP_S2> \
678
+ INLINE ap_int_base& operator Sym(const ap_int_base<_AP_W2, _AP_S2>& op2) { \
679
+ _AP_WARNING((_AP_W != _AP_W2), \
680
+ "Bitsize mismatch for ap_[u]int" #Sym "ap_[u]int."); \
681
+ Base::V Sym op2.V; \
682
+ return *this; \
683
+ }
684
+ OP_ASSIGN_AP_CHK(&=)
685
+ OP_ASSIGN_AP_CHK(|=)
686
+ OP_ASSIGN_AP_CHK(^=)
687
+ #undef OP_ASSIGN_AP_CHK
688
+
689
+ /* Prefix increment, decrement.
690
+ * ----------------------------------------------------------------
691
+ */
692
+ INLINE ap_int_base& operator++() {
693
+ operator+=((ap_int_base<1, false>)1);
694
+ return *this;
695
+ }
696
+ INLINE ap_int_base& operator--() {
697
+ operator-=((ap_int_base<1, false>)1);
698
+ return *this;
699
+ }
700
+
701
+ /* Postfix increment, decrement
702
+ * ----------------------------------------------------------------
703
+ */
704
+ INLINE const typename RType<_AP_W,_AP_S>::arg1 operator++(int) {
705
+ ap_int_base t = *this;
706
+ operator+=((ap_int_base<1, false>)1);
707
+ return t;
708
+ }
709
+ INLINE const typename RType<_AP_W,_AP_S>::arg1 operator--(int) {
710
+ ap_int_base t = *this;
711
+ operator-=((ap_int_base<1, false>)1);
712
+ return t;
713
+ }
714
+
715
+ /* Unary arithmetic.
716
+ * ----------------------------------------------------------------
717
+ */
718
+ INLINE typename RType<_AP_W,_AP_S>::arg1 operator+() const { return *this; }
719
+
720
+ // TODO used to be W>64 only... need check.
721
+ INLINE typename RType<1, false>::minus operator-() const {
722
+ return ap_int_base<1, false>(0) - *this;
723
+ }
724
+
725
+ /* Not (!)
726
+ * ----------------------------------------------------------------
727
+ */
728
+ INLINE bool operator!() const { return Base::V == 0; }
729
+
730
+ /* Bitwise (arithmetic) unary: complement
731
+ ----------------------------------------------------------------
732
+ */
733
+ // XXX different from Mentor's ac_int!
734
+ INLINE typename RType<_AP_W,_AP_S>::arg1 operator~() const {
735
+ ap_int_base<_AP_W, _AP_S> r;
736
+ r.V = ~Base::V;
737
+ return r;
738
+ }
739
+
740
+ /* Shift (result constrained by left operand).
741
+ * ----------------------------------------------------------------
742
+ */
743
+ template <int _AP_W2>
744
+ INLINE typename RType<_AP_W,_AP_S>::arg1 operator<<(const ap_int_base<_AP_W2, true>& op2) const {
745
+ bool isNeg = _AP_ROOT_op_get_bit(op2.V, _AP_W2 - 1);
746
+ ap_int_base<_AP_W2, false> sh = op2;
747
+ if (isNeg) {
748
+ sh = -op2;
749
+ return operator>>(sh);
750
+ } else
751
+ return operator<<(sh);
752
+ }
753
+
754
+ template <int _AP_W2>
755
+ INLINE typename RType<_AP_W,_AP_S>::arg1 operator<<(const ap_int_base<_AP_W2, false>& op2) const {
756
+ ap_int_base r;
757
+ r.V = Base::V << op2.to_uint();
758
+ return r;
759
+ }
760
+
761
+ template <int _AP_W2>
762
+ INLINE typename RType<_AP_W,_AP_S>::arg1 operator>>(const ap_int_base<_AP_W2, true>& op2) const {
763
+ bool isNeg = _AP_ROOT_op_get_bit(op2.V, _AP_W2 - 1);
764
+ ap_int_base<_AP_W2, false> sh = op2;
765
+ if (isNeg) {
766
+ sh = -op2;
767
+ return operator<<(sh);
768
+ }
769
+ return operator>>(sh);
770
+ }
771
+
772
+ template <int _AP_W2>
773
+ INLINE typename RType<_AP_W,_AP_S>::arg1 operator>>(const ap_int_base<_AP_W2, false>& op2) const {
774
+ ap_int_base r;
775
+ r.V = Base::V >> op2.to_uint();
776
+ return r;
777
+ }
778
+
779
+ // FIXME we standalone operator>> for ap_int_base and ap_range_ref.
780
+ #if 0
781
+ template <int _AP_W2, bool _AP_S2>
782
+ INLINE ap_int_base operator<<(const ap_range_ref<_AP_W2, _AP_S2>& op2) const {
783
+ return *this << (op2.operator ap_int_base<_AP_W2, false>());
784
+ }
785
+
786
+ template <int _AP_W2, bool _AP_S2>
787
+ INLINE ap_int_base operator>>(const ap_range_ref<_AP_W2, _AP_S2>& op2) const {
788
+ return *this >> (op2.operator ap_int_base<_AP_W2, false>());
789
+ }
790
+ #endif
791
+
792
+ /* Shift assign
793
+ * ----------------------------------------------------------------
794
+ */
795
+ template <int _AP_W2>
796
+ INLINE ap_int_base& operator<<=(const ap_int_base<_AP_W2, true>& op2) {
797
+ bool isNeg = _AP_ROOT_op_get_bit(op2.V, _AP_W2 - 1);
798
+ ap_int_base<_AP_W2, false> sh = op2;
799
+ if (isNeg) {
800
+ sh = -op2;
801
+ return operator>>=(sh);
802
+ } else
803
+ return operator<<=(sh);
804
+ }
805
+
806
+ template <int _AP_W2>
807
+ INLINE ap_int_base& operator<<=(const ap_int_base<_AP_W2, false>& op2) {
808
+ Base::V <<= op2.to_uint();
809
+ return *this;
810
+ }
811
+
812
+ template <int _AP_W2>
813
+ INLINE ap_int_base& operator>>=(const ap_int_base<_AP_W2, true>& op2) {
814
+ bool isNeg = _AP_ROOT_op_get_bit(op2.V, _AP_W2 - 1);
815
+ ap_int_base<_AP_W2, false> sh = op2;
816
+ if (isNeg) {
817
+ sh = -op2;
818
+ return operator<<=(sh);
819
+ }
820
+ return operator>>=(sh);
821
+ }
822
+
823
+ template <int _AP_W2>
824
+ INLINE ap_int_base& operator>>=(const ap_int_base<_AP_W2, false>& op2) {
825
+ Base::V >>= op2.to_uint();
826
+ return *this;
827
+ }
828
+
829
+ // FIXME we standalone operator>> for ap_int_base and ap_range_ref.
830
+ #if 0
831
+ template <int _AP_W2, bool _AP_S2>
832
+ INLINE ap_int_base& operator<<=(const ap_range_ref<_AP_W2, _AP_S2>& op2) {
833
+ return *this <<= (op2.operator ap_int_base<_AP_W2, false>());
834
+ }
835
+ template <int _AP_W2, bool _AP_S2>
836
+ INLINE ap_int_base& operator>>=(const ap_range_ref<_AP_W2, _AP_S2>& op2) {
837
+ return *this >>= (op2.operator ap_int_base<_AP_W2, false>());
838
+ }
839
+ #endif
840
+
841
+ /* Equality and Relational.
842
+ * ----------------------------------------------------------------
843
+ */
844
+ template <int _AP_W2, bool _AP_S2>
845
+ INLINE bool operator==(const ap_int_base<_AP_W2, _AP_S2>& op2) const {
846
+ return Base::V == op2.V;
847
+ }
848
+ template <int _AP_W2, bool _AP_S2>
849
+ INLINE bool operator!=(const ap_int_base<_AP_W2, _AP_S2>& op2) const {
850
+ return !(Base::V == op2.V);
851
+ }
852
+ template <int _AP_W2, bool _AP_S2>
853
+ INLINE bool operator<(const ap_int_base<_AP_W2, _AP_S2>& op2) const {
854
+ return Base::V < op2.V;
855
+ }
856
+ template <int _AP_W2, bool _AP_S2>
857
+ INLINE bool operator>=(const ap_int_base<_AP_W2, _AP_S2>& op2) const {
858
+ return Base::V >= op2.V;
859
+ }
860
+ template <int _AP_W2, bool _AP_S2>
861
+ INLINE bool operator>(const ap_int_base<_AP_W2, _AP_S2>& op2) const {
862
+ return Base::V > op2.V;
863
+ }
864
+ template <int _AP_W2, bool _AP_S2>
865
+ INLINE bool operator<=(const ap_int_base<_AP_W2, _AP_S2>& op2) const {
866
+ return Base::V <= op2.V;
867
+ }
868
+
869
+ /* Bit and Part Select
870
+ * ----------------------------------------------------------------
871
+ */
872
+ INLINE ap_range_ref<_AP_W, _AP_S> range(int Hi, int Lo) {
873
+ _AP_ERROR(Hi >= _AP_W, "Hi(%d)out of bound(%d) in range()", Hi, _AP_W);
874
+ _AP_ERROR(Lo >= _AP_W, "Lo(%d)out of bound(%d) in range()", Lo, _AP_W);
875
+ return ap_range_ref<_AP_W, _AP_S>(this, Hi, Lo);
876
+ }
877
+
878
+ // This is a must to strip constness to produce reference type.
879
+ INLINE ap_range_ref<_AP_W, _AP_S> range(int Hi, int Lo) const {
880
+ _AP_ERROR(Hi >= _AP_W, "Hi(%d)out of bound(%d) in range()", Hi, _AP_W);
881
+ _AP_ERROR(Lo >= _AP_W, "Lo(%d)out of bound(%d) in range()", Lo, _AP_W);
882
+ return ap_range_ref<_AP_W, _AP_S>(const_cast<ap_int_base*>(this), Hi, Lo);
883
+ }
884
+
885
+ template <int _AP_W2, bool _AP_S2, int _AP_W3, bool _AP_S3>
886
+ INLINE ap_range_ref<_AP_W, _AP_S> range(
887
+ const ap_int_base<_AP_W2, _AP_S2>& HiIdx,
888
+ const ap_int_base<_AP_W3, _AP_S3>& LoIdx) {
889
+ int Hi = HiIdx.to_int();
890
+ int Lo = LoIdx.to_int();
891
+ return this->range(Hi, Lo);
892
+ }
893
+
894
+ template <int _AP_W2, bool _AP_S2, int _AP_W3, bool _AP_S3>
895
+ INLINE ap_range_ref<_AP_W, _AP_S> range(
896
+ const ap_int_base<_AP_W2, _AP_S2>& HiIdx,
897
+ const ap_int_base<_AP_W3, _AP_S3>& LoIdx) const {
898
+ int Hi = HiIdx.to_int();
899
+ int Lo = LoIdx.to_int();
900
+ return this->range(Hi, Lo);
901
+ }
902
+
903
+ INLINE ap_range_ref<_AP_W, _AP_S> range() {
904
+ return this->range(_AP_W - 1, 0);
905
+ }
906
+
907
+ INLINE ap_range_ref<_AP_W, _AP_S> range() const {
908
+ return this->range(_AP_W - 1, 0);
909
+ }
910
+
911
+ INLINE ap_range_ref<_AP_W, _AP_S> operator()(int Hi, int Lo) {
912
+ return this->range(Hi, Lo);
913
+ }
914
+
915
+ INLINE ap_range_ref<_AP_W, _AP_S> operator()(int Hi, int Lo) const {
916
+ return this->range(Hi, Lo);
917
+ }
918
+
919
+ template <int _AP_W2, bool _AP_S2, int _AP_W3, bool _AP_S3>
920
+ INLINE ap_range_ref<_AP_W, _AP_S> operator()(
921
+ const ap_int_base<_AP_W2, _AP_S2>& HiIdx,
922
+ const ap_int_base<_AP_W3, _AP_S3>& LoIdx) {
923
+ int Hi = HiIdx.to_int();
924
+ int Lo = LoIdx.to_int();
925
+ return this->range(Hi, Lo);
926
+ }
927
+
928
+ template <int _AP_W2, bool _AP_S2, int _AP_W3, bool _AP_S3>
929
+ INLINE ap_range_ref<_AP_W, _AP_S> operator()(
930
+ const ap_int_base<_AP_W2, _AP_S2>& HiIdx,
931
+ const ap_int_base<_AP_W3, _AP_S3>& LoIdx) const {
932
+ int Hi = HiIdx.to_int();
933
+ int Lo = LoIdx.to_int();
934
+ return this->range(Hi, Lo);
935
+ }
936
+
937
+ #if 0
938
+ template<int Hi, int Lo>
939
+ INLINE ap_int_base<Hi-Lo+1, false> slice() const {
940
+ AP_ASSERT(Hi >= Lo && Hi < _AP_W && Lo < _AP_W, "Out of bounds in slice()");
941
+ ap_int_base<Hi-Lo+1, false> tmp ;
942
+ tmp.V = _AP_ROOT_op_get_range(Base::V, Lo, Hi);
943
+ return tmp;
944
+ }
945
+
946
+ INLINE ap_bit_ref<_AP_W,_AP_S> operator [] ( unsigned int uindex) {
947
+ AP_ASSERT(uindex < _AP_W, "Attempting to read bit beyond MSB");
948
+ ap_bit_ref<_AP_W,_AP_S> bvh( this, uindex );
949
+ return bvh;
950
+ }
951
+ #endif
952
+
953
+ INLINE ap_bit_ref<_AP_W, _AP_S> operator[](int index) {
954
+ AP_ASSERT(index >= 0, "Attempting to read bit with negative index");
955
+ AP_ASSERT(index < _AP_W, "Attempting to read bit beyond MSB");
956
+ ap_bit_ref<_AP_W, _AP_S> bvh(this, index);
957
+ return bvh;
958
+ }
959
+
960
+ template <int _AP_W2, bool _AP_S2>
961
+ INLINE ap_bit_ref<_AP_W, _AP_S> operator[](
962
+ const ap_int_base<_AP_W2, _AP_S2>& index) {
963
+ AP_ASSERT(index >= 0, "Attempting to read bit with negative index");
964
+ AP_ASSERT(index < _AP_W, "Attempting to read bit beyond MSB");
965
+ ap_bit_ref<_AP_W, _AP_S> bvh(this, index.to_int());
966
+ return bvh;
967
+ }
968
+
969
+ INLINE bool operator[](int index) const {
970
+ AP_ASSERT(index >= 0, "Attempting to read bit with negative index");
971
+ AP_ASSERT(index < _AP_W, "Attempting to read bit beyond MSB");
972
+ ap_bit_ref<_AP_W, _AP_S> br(this, index);
973
+ return br.to_bool();
974
+ }
975
+ template <int _AP_W2, bool _AP_S2>
976
+ INLINE bool operator[](const ap_int_base<_AP_W2, _AP_S2>& index) const {
977
+ AP_ASSERT(index < _AP_W, "Attempting to read bit beyond MSB");
978
+ ap_bit_ref<_AP_W, _AP_S> br(this, index.to_int());
979
+ return br.to_bool();
980
+ }
981
+
982
+ INLINE ap_bit_ref<_AP_W, _AP_S> bit(int index) {
983
+ AP_ASSERT(index >= 0, "Attempting to read bit with negative index");
984
+ AP_ASSERT(index < _AP_W, "Attempting to read bit beyond MSB");
985
+ ap_bit_ref<_AP_W, _AP_S> bvh(this, index);
986
+ return bvh;
987
+ }
988
+ template <int _AP_W2, bool _AP_S2>
989
+ INLINE ap_bit_ref<_AP_W, _AP_S> bit(
990
+ const ap_int_base<_AP_W2, _AP_S2>& index) {
991
+ AP_ASSERT(index >= 0, "Attempting to read bit with negative index");
992
+ AP_ASSERT(index < _AP_W, "Attempting to read bit beyond MSB");
993
+ ap_bit_ref<_AP_W, _AP_S> bvh(this, index.to_int());
994
+ return bvh;
995
+ }
996
+
997
+ INLINE bool bit(int index) const {
998
+ AP_ASSERT(index >= 0, "Attempting to read bit with negative index");
999
+ AP_ASSERT(index < _AP_W, "Attempting to read bit beyond MSB");
1000
+ ap_bit_ref<_AP_W, _AP_S> br(this, index);
1001
+ return br.to_bool();
1002
+ }
1003
+
1004
+ template <int _AP_W2, bool _AP_S2>
1005
+ INLINE bool bit(const ap_int_base<_AP_W2, _AP_S2>& index) const {
1006
+ return bit(index.to_int());
1007
+ }
1008
+
1009
+ #if 0
1010
+ template<typename _AP_T>
1011
+ INLINE bool operator[](_AP_T index) const {
1012
+ AP_ASSERT(index < _AP_W, "Attempting to read bit beyond MSB");
1013
+ ap_bit_ref<_AP_W,_AP_S> br = operator[](index);
1014
+ return br.to_bool();
1015
+ }
1016
+ #endif
1017
+
1018
+ // Count the number of zeros from the most significant bit
1019
+ // to the first one bit.
1020
+ INLINE int countLeadingZeros() {
1021
+ #ifdef __SYNTHESIS__
1022
+ if (_AP_W <= 32) {
1023
+ ap_int_base<32, false> t(-1UL), x;
1024
+ x.V = _AP_ROOT_op_get_range(this->V, _AP_W - 1, 0); // reverse
1025
+ t.V = _AP_ROOT_op_set_range(t.V, 0, _AP_W - 1, x.V);
1026
+ return __builtin_ctz(t.V); // count trailing zeros.
1027
+ } else if (_AP_W <= 64) {
1028
+ ap_int_base<64, false> t(-1ULL);
1029
+ ap_int_base<64, false> x;
1030
+ x.V = _AP_ROOT_op_get_range(this->V, _AP_W - 1, 0); // reverse
1031
+ t.V = _AP_ROOT_op_set_range(t.V, 0, _AP_W - 1, x.V);
1032
+ return __builtin_ctzll(t.V); // count trailing zeros.
1033
+ } else {
1034
+ enum { __N = (_AP_W + 63) / 64 };
1035
+ int NZeros = 0;
1036
+ int i = 0;
1037
+ bool hitNonZero = false;
1038
+ for (i = 0; i < __N - 1; ++i) {
1039
+ ap_int_base<64, false> t;
1040
+ t.V = _AP_ROOT_op_get_range(this->V, _AP_W - i * 64 - 64, _AP_W - i * 64 - 1);
1041
+ NZeros += hitNonZero ? 0 : __builtin_clzll(t.V); // count leading zeros.
1042
+ hitNonZero |= (t.V != 0);
1043
+ }
1044
+ if (!hitNonZero) {
1045
+ ap_int_base<64, false> t(-1ULL);
1046
+ enum { REST = (_AP_W - 1) % 64 };
1047
+ ap_int_base<64, false> x;
1048
+ x.V = _AP_ROOT_op_get_range(this->V, 0, REST);
1049
+ t.V = _AP_ROOT_op_set_range(t.V, 63 - REST, 63, x.V);
1050
+ NZeros += __builtin_clzll(t.V);
1051
+ }
1052
+ return NZeros;
1053
+ }
1054
+ #else
1055
+ return (Base::V).countLeadingZeros();
1056
+ #endif
1057
+ } // countLeadingZeros
1058
+
1059
+ template <int _AP_W2, bool _AP_S2>
1060
+ INLINE ap_concat_ref<_AP_W, ap_int_base, _AP_W2, ap_int_base<_AP_W2, _AP_S2> >
1061
+ concat(const ap_int_base<_AP_W2, _AP_S2>& a2) const {
1062
+ return ap_concat_ref<_AP_W, ap_int_base, _AP_W2,
1063
+ ap_int_base<_AP_W2, _AP_S2> >(
1064
+ const_cast<ap_int_base<_AP_W, _AP_S>&>(*this),
1065
+ const_cast<ap_int_base<_AP_W2, _AP_S2>&>(a2));
1066
+ }
1067
+
1068
+ template <int _AP_W2, bool _AP_S2>
1069
+ INLINE ap_concat_ref<_AP_W, ap_int_base, _AP_W2, ap_int_base<_AP_W2, _AP_S2> >
1070
+ concat(ap_int_base<_AP_W2, _AP_S2>& a2) {
1071
+ return ap_concat_ref<_AP_W, ap_int_base, _AP_W2,
1072
+ ap_int_base<_AP_W2, _AP_S2> >(*this, a2);
1073
+ }
1074
+
1075
+ template <int _AP_W2, bool _AP_S2>
1076
+ INLINE
1077
+ ap_concat_ref<_AP_W, ap_int_base, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> >
1078
+ operator,(const ap_range_ref<_AP_W2, _AP_S2> &a2) const {
1079
+ return ap_concat_ref<_AP_W, ap_int_base, _AP_W2,
1080
+ ap_range_ref<_AP_W2, _AP_S2> >(
1081
+ const_cast<ap_int_base<_AP_W, _AP_S>&>(*this),
1082
+ const_cast<ap_range_ref<_AP_W2, _AP_S2>&>(a2));
1083
+ }
1084
+
1085
+ template <int _AP_W2, bool _AP_S2>
1086
+ INLINE
1087
+ ap_concat_ref<_AP_W, ap_int_base, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> >
1088
+ operator,(ap_range_ref<_AP_W2, _AP_S2> &a2) {
1089
+ return ap_concat_ref<_AP_W, ap_int_base, _AP_W2,
1090
+ ap_range_ref<_AP_W2, _AP_S2> >(*this, a2);
1091
+ }
1092
+
1093
+ template <int _AP_W2, bool _AP_S2>
1094
+ INLINE ap_concat_ref<_AP_W, ap_int_base, _AP_W2, ap_int_base<_AP_W2, _AP_S2> >
1095
+ operator,(const ap_int_base<_AP_W2, _AP_S2> &a2) {
1096
+ return ap_concat_ref<_AP_W, ap_int_base, _AP_W2,
1097
+ ap_int_base<_AP_W2, _AP_S2> >(
1098
+ *this, const_cast<ap_int_base<_AP_W2, _AP_S2>&>(a2));
1099
+ }
1100
+
1101
+ template <int _AP_W2, bool _AP_S2>
1102
+ INLINE ap_concat_ref<_AP_W, ap_int_base, _AP_W2, ap_int_base<_AP_W2, _AP_S2> >
1103
+ operator,(ap_int_base<_AP_W2, _AP_S2> &a2) const {
1104
+ return ap_concat_ref<_AP_W, ap_int_base, _AP_W2,
1105
+ ap_int_base<_AP_W2, _AP_S2> >(
1106
+ const_cast<ap_int_base<_AP_W, _AP_S>&>(*this), a2);
1107
+ }
1108
+
1109
+ template <int _AP_W2, bool _AP_S2>
1110
+ INLINE ap_concat_ref<_AP_W, ap_int_base, _AP_W2, ap_int_base<_AP_W2, _AP_S2> >
1111
+ operator,(const ap_int_base<_AP_W2, _AP_S2> &a2) const {
1112
+ return ap_concat_ref<_AP_W, ap_int_base, _AP_W2,
1113
+ ap_int_base<_AP_W2, _AP_S2> >(
1114
+ const_cast<ap_int_base<_AP_W, _AP_S>&>(*this),
1115
+ const_cast<ap_int_base<_AP_W2, _AP_S2>&>(a2));
1116
+ }
1117
+
1118
+ template <int _AP_W2, bool _AP_S2>
1119
+ INLINE ap_concat_ref<_AP_W, ap_int_base, _AP_W2, ap_int_base<_AP_W2, _AP_S2> >
1120
+ operator,(ap_int_base<_AP_W2, _AP_S2> &a2) {
1121
+ return ap_concat_ref<_AP_W, ap_int_base, _AP_W2,
1122
+ ap_int_base<_AP_W2, _AP_S2> >(*this, a2);
1123
+ }
1124
+
1125
+ template <int _AP_W2, bool _AP_S2>
1126
+ INLINE ap_concat_ref<_AP_W, ap_int_base, 1, ap_bit_ref<_AP_W2, _AP_S2> >
1127
+ operator,(const ap_bit_ref<_AP_W2, _AP_S2> &a2) const {
1128
+ return ap_concat_ref<_AP_W, ap_int_base, 1, ap_bit_ref<_AP_W2, _AP_S2> >(
1129
+ const_cast<ap_int_base<_AP_W, _AP_S>&>(*this),
1130
+ const_cast<ap_bit_ref<_AP_W2, _AP_S2>&>(a2));
1131
+ }
1132
+
1133
+ template <int _AP_W2, bool _AP_S2>
1134
+ INLINE ap_concat_ref<_AP_W, ap_int_base, 1, ap_bit_ref<_AP_W2, _AP_S2> >
1135
+ operator,(ap_bit_ref<_AP_W2, _AP_S2> &a2) {
1136
+ return ap_concat_ref<_AP_W, ap_int_base, 1, ap_bit_ref<_AP_W2, _AP_S2> >(
1137
+ *this, a2);
1138
+ }
1139
+
1140
+ template <int _AP_W2, typename _AP_T2, int _AP_W3, typename _AP_T3>
1141
+ INLINE ap_concat_ref<_AP_W, ap_int_base, _AP_W2 + _AP_W3,
1142
+ ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >
1143
+ operator,(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) {
1144
+ return ap_concat_ref<_AP_W, ap_int_base, _AP_W2 + _AP_W3,
1145
+ ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(
1146
+ const_cast<ap_int_base<_AP_W, _AP_S>&>(*this),
1147
+ const_cast<ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>&>(a2));
1148
+ }
1149
+
1150
+ template <int _AP_W2, typename _AP_T2, int _AP_W3, typename _AP_T3>
1151
+ INLINE ap_concat_ref<_AP_W, ap_int_base, _AP_W2 + _AP_W3,
1152
+ ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >
1153
+ operator,(ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) {
1154
+ return ap_concat_ref<_AP_W, ap_int_base, _AP_W2 + _AP_W3,
1155
+ ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(*this,
1156
+ a2);
1157
+ }
1158
+
1159
+ template <int _AP_W2, int _AP_I2, bool _AP_S2, ap_q_mode _AP_Q2,
1160
+ ap_o_mode _AP_O2, int _AP_N2>
1161
+ INLINE ap_concat_ref<
1162
+ _AP_W, ap_int_base, _AP_W2,
1163
+ af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >
1164
+ operator,(const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>
1165
+ &a2) const {
1166
+ return ap_concat_ref<
1167
+ _AP_W, ap_int_base, _AP_W2,
1168
+ af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(
1169
+ const_cast<ap_int_base<_AP_W, _AP_S>&>(*this),
1170
+ const_cast<
1171
+ af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>&>(a2));
1172
+ }
1173
+
1174
+ template <int _AP_W2, int _AP_I2, bool _AP_S2, ap_q_mode _AP_Q2,
1175
+ ap_o_mode _AP_O2, int _AP_N2>
1176
+ INLINE ap_concat_ref<
1177
+ _AP_W, ap_int_base, _AP_W2,
1178
+ af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >
1179
+ operator,(af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> &a2) {
1180
+ return ap_concat_ref<
1181
+ _AP_W, ap_int_base, _AP_W2,
1182
+ af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this,
1183
+ a2);
1184
+ }
1185
+
1186
+ template <int _AP_W2, int _AP_I2, bool _AP_S2, ap_q_mode _AP_Q2,
1187
+ ap_o_mode _AP_O2, int _AP_N2>
1188
+ INLINE
1189
+ ap_concat_ref<_AP_W, ap_int_base, 1,
1190
+ af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >
1191
+ operator,(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>
1192
+ &a2) const {
1193
+ return ap_concat_ref<
1194
+ _AP_W, ap_int_base, 1,
1195
+ af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(
1196
+ const_cast<ap_int_base<_AP_W, _AP_S>&>(*this),
1197
+ const_cast<af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>&>(
1198
+ a2));
1199
+ }
1200
+
1201
+ template <int _AP_W2, int _AP_I2, bool _AP_S2, ap_q_mode _AP_Q2,
1202
+ ap_o_mode _AP_O2, int _AP_N2>
1203
+ INLINE
1204
+ ap_concat_ref<_AP_W, ap_int_base, 1,
1205
+ af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >
1206
+ operator,(
1207
+ af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> &a2) {
1208
+ return ap_concat_ref<
1209
+ _AP_W, ap_int_base, 1,
1210
+ af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(*this, a2);
1211
+ }
1212
+
1213
+ template <int _AP_W2, typename _AP_T2, int _AP_W3, typename _AP_T3>
1214
+ INLINE ap_int_base<AP_MAX(_AP_W2 + _AP_W3, _AP_W), _AP_S> operator&(
1215
+ const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) {
1216
+ return *this & a2.get();
1217
+ }
1218
+
1219
+ template <int _AP_W2, typename _AP_T2, int _AP_W3, typename _AP_T3>
1220
+ INLINE ap_int_base<AP_MAX(_AP_W2 + _AP_W3, _AP_W), _AP_S> operator|(
1221
+ const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) {
1222
+ return *this | a2.get();
1223
+ }
1224
+
1225
+ template <int _AP_W2, typename _AP_T2, int _AP_W3, typename _AP_T3>
1226
+ INLINE ap_int_base<AP_MAX(_AP_W2 + _AP_W3, _AP_W), _AP_S> operator^(
1227
+ const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>& a2) {
1228
+ return *this ^ a2.get();
1229
+ }
1230
+
1231
+ template <int _AP_W3>
1232
+ INLINE void set(const ap_int_base<_AP_W3, false>& val) {
1233
+ Base::V = val.V;
1234
+ }
1235
+
1236
+ /* Reduce operations.
1237
+ * ----------------------------------------------------------------
1238
+ */
1239
+ // XXX non-const version deleted.
1240
+ INLINE bool and_reduce() const { return _AP_ROOT_op_reduce(and, Base::V); }
1241
+ INLINE bool nand_reduce() const { return _AP_ROOT_op_reduce(nand, Base::V); }
1242
+ INLINE bool or_reduce() const { return _AP_ROOT_op_reduce(or, Base::V); }
1243
+ INLINE bool nor_reduce() const { return !(_AP_ROOT_op_reduce(or, Base::V)); }
1244
+ INLINE bool xor_reduce() const { return _AP_ROOT_op_reduce (xor, Base::V); }
1245
+ INLINE bool xnor_reduce() const {
1246
+ return !(_AP_ROOT_op_reduce (xor, Base::V));
1247
+ }
1248
+
1249
+ /* Output as a string.
1250
+ * ----------------------------------------------------------------
1251
+ */
1252
+ #ifndef __SYNTHESIS__
1253
+ std::string to_string(signed char rd = 2, bool sign = _AP_S) const {
1254
+ // XXX in autosim/autowrap.tcl "(${name}).to_string(2).c_str()" is used to
1255
+ // initialize sc_lv, which seems incapable of handling format "-0b".
1256
+ if (rd == 2) sign = false;
1257
+ return (Base::V).to_string(rd, sign);
1258
+ }
1259
+ #else
1260
+ INLINE char* to_string(signed char rd = 2, bool sign = _AP_S) const {
1261
+ return 0;
1262
+ }
1263
+ #endif
1264
+ }; // struct ap_int_base
1265
+
1266
+ // XXX apcc cannot handle global std::ios_base::Init() brought in by <iostream>
1267
+ #ifndef AP_AUTOCC
1268
+ #ifndef __SYNTHESIS__
1269
+ template <int _AP_W, bool _AP_S>
1270
+ INLINE std::ostream& operator<<(std::ostream& os,
1271
+ const ap_int_base<_AP_W, _AP_S>& x) {
1272
+ std::ios_base::fmtflags ff = std::cout.flags();
1273
+ if (ff & std::cout.hex) {
1274
+ os << x.to_string(16); // don't print sign
1275
+ } else if (ff & std::cout.oct) {
1276
+ os << x.to_string(8); // don't print sign
1277
+ } else {
1278
+ os << x.to_string(10);
1279
+ }
1280
+ return os;
1281
+ }
1282
+ #endif // ifndef __SYNTHESIS__
1283
+
1284
+ #ifndef __SYNTHESIS__
1285
+ template <int _AP_W, bool _AP_S>
1286
+ INLINE std::istream& operator>>(std::istream& in,
1287
+ ap_int_base<_AP_W, _AP_S>& op) {
1288
+ std::string str;
1289
+ in >> str;
1290
+ const std::ios_base::fmtflags basefield = in.flags() & std::ios_base::basefield;
1291
+ unsigned radix = (basefield == std::ios_base::dec) ? 0 : (
1292
+ (basefield == std::ios_base::oct) ? 8 : (
1293
+ (basefield == std::ios_base::hex) ? 16 : 0));
1294
+ op = ap_int_base<_AP_W, _AP_S>(str.c_str(), radix);
1295
+ return in;
1296
+ }
1297
+ #endif // ifndef __SYNTHESIS__
1298
+ #endif // ifndef AP_AUTOCC
1299
+
1300
+ /* Operators with another ap_int_base.
1301
+ * ----------------------------------------------------------------
1302
+ */
1303
+ #define OP_BIN_AP(Sym, Rty) \
1304
+ template <int _AP_W, bool _AP_S, int _AP_W2, bool _AP_S2> \
1305
+ INLINE \
1306
+ typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W2, _AP_S2>::Rty \
1307
+ operator Sym(const ap_int_base<_AP_W, _AP_S>& op, \
1308
+ const ap_int_base<_AP_W2, _AP_S2>& op2) { \
1309
+ typename ap_int_base<_AP_W, _AP_S>::template RType< \
1310
+ _AP_W2, _AP_S2>::Rty##_base lhs(op); \
1311
+ typename ap_int_base<_AP_W, _AP_S>::template RType< \
1312
+ _AP_W2, _AP_S2>::Rty##_base rhs(op2); \
1313
+ typename ap_int_base<_AP_W, _AP_S>::template RType< \
1314
+ _AP_W2, _AP_S2>::Rty##_base ret; \
1315
+ ret.V = lhs.V Sym rhs.V; \
1316
+ return ret; \
1317
+ }
1318
+
1319
+ OP_BIN_AP(*, mult)
1320
+ OP_BIN_AP(+, plus)
1321
+ OP_BIN_AP(-, minus)
1322
+ OP_BIN_AP(&, logic)
1323
+ OP_BIN_AP(|, logic)
1324
+ OP_BIN_AP(^, logic)
1325
+
1326
+ #define OP_BIN_AP2(Sym, Rty) \
1327
+ template <int _AP_W, bool _AP_S, int _AP_W2, bool _AP_S2> \
1328
+ INLINE \
1329
+ typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W2, _AP_S2>::Rty \
1330
+ operator Sym(const ap_int_base<_AP_W, _AP_S>& op, \
1331
+ const ap_int_base<_AP_W2, _AP_S2>& op2) { \
1332
+ typename ap_int_base<_AP_W, _AP_S>::template RType< \
1333
+ _AP_W2, _AP_S2>::Rty##_base ret; \
1334
+ ret.V = op.V Sym op2.V; \
1335
+ return ret; \
1336
+ }
1337
+
1338
+ OP_BIN_AP2(/, div)
1339
+ OP_BIN_AP2(%, mod)
1340
+
1341
+ // shift operators are defined inside class.
1342
+ // compound assignment operators are defined inside class.
1343
+
1344
+ /* Operators with a pointer type.
1345
+ * ----------------------------------------------------------------
1346
+ * char a[100];
1347
+ * char* ptr = a;
1348
+ * ap_int<2> n = 3;
1349
+ * char* ptr2 = ptr + n*2;
1350
+ * avoid ambiguous errors.
1351
+ */
1352
+ #define OP_BIN_WITH_PTR(BIN_OP) \
1353
+ template <typename PTR_TYPE, int _AP_W, bool _AP_S> \
1354
+ INLINE PTR_TYPE* operator BIN_OP(PTR_TYPE* i_op, \
1355
+ const ap_int_base<_AP_W, _AP_S>& op) { \
1356
+ ap_slong op2 = op.to_int64(); /* Not all implementation */ \
1357
+ return i_op BIN_OP op2; \
1358
+ } \
1359
+ template <typename PTR_TYPE, int _AP_W, bool _AP_S> \
1360
+ INLINE PTR_TYPE* operator BIN_OP(const ap_int_base<_AP_W, _AP_S>& op, \
1361
+ PTR_TYPE* i_op) { \
1362
+ ap_slong op2 = op.to_int64(); /* Not all implementation */ \
1363
+ return op2 BIN_OP i_op; \
1364
+ }
1365
+
1366
+ OP_BIN_WITH_PTR(+)
1367
+ OP_BIN_WITH_PTR(-)
1368
+
1369
+ /* Operators with a native floating point types.
1370
+ * ----------------------------------------------------------------
1371
+ */
1372
+ // float OP ap_int
1373
+ // when ap_int<wa>'s width > 64, then trunc ap_int<w> to ap_int<64>
1374
+ #define OP_BIN_WITH_FLOAT(BIN_OP, C_TYPE) \
1375
+ template <int _AP_W, bool _AP_S> \
1376
+ INLINE C_TYPE operator BIN_OP(C_TYPE i_op, \
1377
+ const ap_int_base<_AP_W, _AP_S>& op) { \
1378
+ typename ap_int_base<_AP_W, _AP_S>::RetType op2 = op; \
1379
+ return i_op BIN_OP op2; \
1380
+ } \
1381
+ template <int _AP_W, bool _AP_S> \
1382
+ INLINE C_TYPE operator BIN_OP(const ap_int_base<_AP_W, _AP_S>& op, \
1383
+ C_TYPE i_op) { \
1384
+ typename ap_int_base<_AP_W, _AP_S>::RetType op2 = op; \
1385
+ return op2 BIN_OP i_op; \
1386
+ }
1387
+
1388
+ #define ALL_OP_WITH_FLOAT(C_TYPE) \
1389
+ OP_BIN_WITH_FLOAT(*, C_TYPE) \
1390
+ OP_BIN_WITH_FLOAT(/, C_TYPE) \
1391
+ OP_BIN_WITH_FLOAT(+, C_TYPE) \
1392
+ OP_BIN_WITH_FLOAT(-, C_TYPE)
1393
+
1394
+ #if _AP_ENABLE_HALF_ == 1
1395
+ ALL_OP_WITH_FLOAT(half)
1396
+ #endif
1397
+ ALL_OP_WITH_FLOAT(float)
1398
+ ALL_OP_WITH_FLOAT(double)
1399
+
1400
+ // TODO no shift?
1401
+
1402
+ /* Operators with a native integral types.
1403
+ * ----------------------------------------------------------------
1404
+ */
1405
+ // arithmetic and bitwise operators.
1406
+ #define OP_BIN_WITH_INT(BIN_OP, C_TYPE, _AP_W2, _AP_S2, RTYPE) \
1407
+ template <int _AP_W, bool _AP_S> \
1408
+ INLINE typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W2, \
1409
+ _AP_S2>::RTYPE \
1410
+ operator BIN_OP(C_TYPE i_op, const ap_int_base<_AP_W, _AP_S>& op) { \
1411
+ return ap_int_base<_AP_W2, _AP_S2>(i_op) BIN_OP(op); \
1412
+ } \
1413
+ template <int _AP_W, bool _AP_S> \
1414
+ INLINE typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W2, \
1415
+ _AP_S2>::RTYPE \
1416
+ operator BIN_OP(const ap_int_base<_AP_W, _AP_S>& op, C_TYPE i_op) { \
1417
+ return op BIN_OP ap_int_base<_AP_W2, _AP_S2>(i_op); \
1418
+ }
1419
+
1420
+ #define ALL_OP_BIN_WITH_INT(C_TYPE, _AP_W2, _AP_S2) \
1421
+ OP_BIN_WITH_INT(*, C_TYPE, _AP_W2, _AP_S2, mult) \
1422
+ OP_BIN_WITH_INT(+, C_TYPE, _AP_W2, _AP_S2, plus) \
1423
+ OP_BIN_WITH_INT(-, C_TYPE, _AP_W2, _AP_S2, minus) \
1424
+ OP_BIN_WITH_INT(/, C_TYPE, _AP_W2, _AP_S2, div) \
1425
+ OP_BIN_WITH_INT(%, C_TYPE, _AP_W2, _AP_S2, mod) \
1426
+ OP_BIN_WITH_INT(&, C_TYPE, _AP_W2, _AP_S2, logic) \
1427
+ OP_BIN_WITH_INT(|, C_TYPE, _AP_W2, _AP_S2, logic) \
1428
+ OP_BIN_WITH_INT(^, C_TYPE, _AP_W2, _AP_S2, logic)
1429
+
1430
+ ALL_OP_BIN_WITH_INT(bool, 1, false)
1431
+ ALL_OP_BIN_WITH_INT(char, 8, CHAR_IS_SIGNED)
1432
+ ALL_OP_BIN_WITH_INT(signed char, 8, true)
1433
+ ALL_OP_BIN_WITH_INT(unsigned char, 8, false)
1434
+ ALL_OP_BIN_WITH_INT(short, _AP_SIZE_short, true)
1435
+ ALL_OP_BIN_WITH_INT(unsigned short, _AP_SIZE_short, false)
1436
+ ALL_OP_BIN_WITH_INT(int, _AP_SIZE_int, true)
1437
+ ALL_OP_BIN_WITH_INT(unsigned int, _AP_SIZE_int, false)
1438
+ ALL_OP_BIN_WITH_INT(long, _AP_SIZE_long, true)
1439
+ ALL_OP_BIN_WITH_INT(unsigned long, _AP_SIZE_long, false)
1440
+ ALL_OP_BIN_WITH_INT(ap_slong, _AP_SIZE_ap_slong, true)
1441
+ ALL_OP_BIN_WITH_INT(ap_ulong, _AP_SIZE_ap_slong, false)
1442
+
1443
+ #undef OP_BIN_WITH_INT
1444
+ #undef ALL_OP_BIN_WITH_INT
1445
+
1446
+ // shift operators.
1447
+ #define ALL_OP_SHIFT_WITH_INT(C_TYPE, _AP_W2, _AP_S2) \
1448
+ template <int _AP_W, bool _AP_S> \
1449
+ INLINE typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W,_AP_S>::arg1 operator<<( \
1450
+ const ap_int_base<_AP_W, _AP_S>& op, C_TYPE op2) { \
1451
+ ap_int_base<_AP_W, _AP_S> r; \
1452
+ if (_AP_S2) \
1453
+ r.V = op2 >= 0 ? (op.V << op2) : (op.V >> (-op2)); \
1454
+ else \
1455
+ r.V = op.V << op2; \
1456
+ return r; \
1457
+ } \
1458
+ template <int _AP_W, bool _AP_S> \
1459
+ INLINE typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W,_AP_S>::arg1 operator>>( \
1460
+ const ap_int_base<_AP_W, _AP_S>& op, C_TYPE op2) { \
1461
+ ap_int_base<_AP_W, _AP_S> r; \
1462
+ if (_AP_S2) \
1463
+ r.V = op2 >= 0 ? (op.V >> op2) : (op.V << (-op2)); \
1464
+ else \
1465
+ r.V = op.V >> op2; \
1466
+ return r; \
1467
+ }
1468
+
1469
+ ALL_OP_SHIFT_WITH_INT(char, 8, CHAR_IS_SIGNED)
1470
+ ALL_OP_SHIFT_WITH_INT(signed char, 8, true)
1471
+ ALL_OP_SHIFT_WITH_INT(short, _AP_SIZE_short, true)
1472
+ ALL_OP_SHIFT_WITH_INT(int, _AP_SIZE_int, true)
1473
+ ALL_OP_SHIFT_WITH_INT(long, _AP_SIZE_long, true)
1474
+ ALL_OP_SHIFT_WITH_INT(ap_slong, _AP_SIZE_ap_slong, true)
1475
+
1476
+ #undef ALL_OP_SHIFT_WITH_INT
1477
+
1478
+ #define ALL_OP_SHIFT_WITH_INT(C_TYPE, _AP_W2, _AP_S2) \
1479
+ template <int _AP_W, bool _AP_S> \
1480
+ INLINE typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W,_AP_S>::arg1 operator<<( \
1481
+ const ap_int_base<_AP_W, _AP_S>& op, C_TYPE op2) { \
1482
+ ap_int_base<_AP_W, _AP_S> r; \
1483
+ r.V = op.V << op2; \
1484
+ return r; \
1485
+ } \
1486
+ template <int _AP_W, bool _AP_S> \
1487
+ INLINE typename ap_int_base<_AP_W, _AP_S>::template RType<_AP_W,_AP_S>::arg1 operator>>( \
1488
+ const ap_int_base<_AP_W, _AP_S>& op, C_TYPE op2) { \
1489
+ ap_int_base<_AP_W, _AP_S> r; \
1490
+ r.V = op.V >> op2; \
1491
+ return r; \
1492
+ }
1493
+ ALL_OP_SHIFT_WITH_INT(bool, 1, false)
1494
+ ALL_OP_SHIFT_WITH_INT(unsigned char, 8, false)
1495
+ ALL_OP_SHIFT_WITH_INT(unsigned short, _AP_SIZE_short, false)
1496
+ ALL_OP_SHIFT_WITH_INT(unsigned int, _AP_SIZE_int, false)
1497
+ ALL_OP_SHIFT_WITH_INT(unsigned long, _AP_SIZE_long, false)
1498
+ ALL_OP_SHIFT_WITH_INT(ap_ulong, _AP_SIZE_ap_slong, false)
1499
+
1500
+ #undef ALL_OP_SHIFT_WITH_INT
1501
+
1502
+ // compound assign operators.
1503
+ #define OP_ASSIGN_WITH_INT(ASSIGN_OP, C_TYPE, _AP_W2, _AP_S2) \
1504
+ template <int _AP_W, bool _AP_S> \
1505
+ INLINE ap_int_base<_AP_W, _AP_S>& operator ASSIGN_OP( \
1506
+ ap_int_base<_AP_W, _AP_S>& op, C_TYPE op2) { \
1507
+ return op ASSIGN_OP ap_int_base<_AP_W2, _AP_S2>(op2); \
1508
+ }
1509
+
1510
+ // TODO int a; ap_int<16> b; a += b;
1511
+
1512
+ #define ALL_OP_ASSIGN_WITH_INT(C_TYPE, _AP_W2, _AP_S2) \
1513
+ OP_ASSIGN_WITH_INT(+=, C_TYPE, _AP_W2, _AP_S2) \
1514
+ OP_ASSIGN_WITH_INT(-=, C_TYPE, _AP_W2, _AP_S2) \
1515
+ OP_ASSIGN_WITH_INT(*=, C_TYPE, _AP_W2, _AP_S2) \
1516
+ OP_ASSIGN_WITH_INT(/=, C_TYPE, _AP_W2, _AP_S2) \
1517
+ OP_ASSIGN_WITH_INT(%=, C_TYPE, _AP_W2, _AP_S2) \
1518
+ OP_ASSIGN_WITH_INT(&=, C_TYPE, _AP_W2, _AP_S2) \
1519
+ OP_ASSIGN_WITH_INT(|=, C_TYPE, _AP_W2, _AP_S2) \
1520
+ OP_ASSIGN_WITH_INT(^=, C_TYPE, _AP_W2, _AP_S2) \
1521
+ OP_ASSIGN_WITH_INT(>>=, C_TYPE, _AP_W2, _AP_S2) \
1522
+ OP_ASSIGN_WITH_INT(<<=, C_TYPE, _AP_W2, _AP_S2)
1523
+
1524
+ ALL_OP_ASSIGN_WITH_INT(bool, 1, false)
1525
+ ALL_OP_ASSIGN_WITH_INT(char, 8, CHAR_IS_SIGNED)
1526
+ ALL_OP_ASSIGN_WITH_INT(signed char, 8, true)
1527
+ ALL_OP_ASSIGN_WITH_INT(unsigned char, 8, false)
1528
+ ALL_OP_ASSIGN_WITH_INT(short, _AP_SIZE_short, true)
1529
+ ALL_OP_ASSIGN_WITH_INT(unsigned short, _AP_SIZE_short, false)
1530
+ ALL_OP_ASSIGN_WITH_INT(int, _AP_SIZE_int, true)
1531
+ ALL_OP_ASSIGN_WITH_INT(unsigned int, _AP_SIZE_int, false)
1532
+ ALL_OP_ASSIGN_WITH_INT(long, _AP_SIZE_long, true)
1533
+ ALL_OP_ASSIGN_WITH_INT(unsigned long, _AP_SIZE_long, false)
1534
+ ALL_OP_ASSIGN_WITH_INT(ap_slong, _AP_SIZE_ap_slong, true)
1535
+ ALL_OP_ASSIGN_WITH_INT(ap_ulong, _AP_SIZE_ap_slong, false)
1536
+
1537
+ #undef OP_ASSIGN_WITH_INT
1538
+ #undef ALL_OP_ASSIGN_WITH_INT
1539
+
1540
+ // equality and relational operators.
1541
+ #define OP_REL_WITH_INT(REL_OP, C_TYPE, _AP_W2, _AP_S2) \
1542
+ template <int _AP_W, bool _AP_S> \
1543
+ INLINE bool operator REL_OP(C_TYPE i_op, \
1544
+ const ap_int_base<_AP_W, _AP_S>& op) { \
1545
+ return ap_int_base<_AP_W2, _AP_S2>(i_op) REL_OP op; \
1546
+ } \
1547
+ template <int _AP_W, bool _AP_S> \
1548
+ INLINE bool operator REL_OP(const ap_int_base<_AP_W, _AP_S>& op, \
1549
+ C_TYPE op2) { \
1550
+ return op REL_OP ap_int_base<_AP_W2, _AP_S2>(op2); \
1551
+ }
1552
+
1553
+ #define ALL_OP_REL_WITH_INT(C_TYPE, _AP_W2, _AP_S2) \
1554
+ OP_REL_WITH_INT(>, C_TYPE, _AP_W2, _AP_S2) \
1555
+ OP_REL_WITH_INT(<, C_TYPE, _AP_W2, _AP_S2) \
1556
+ OP_REL_WITH_INT(>=, C_TYPE, _AP_W2, _AP_S2) \
1557
+ OP_REL_WITH_INT(<=, C_TYPE, _AP_W2, _AP_S2) \
1558
+ OP_REL_WITH_INT(==, C_TYPE, _AP_W2, _AP_S2) \
1559
+ OP_REL_WITH_INT(!=, C_TYPE, _AP_W2, _AP_S2)
1560
+
1561
+ ALL_OP_REL_WITH_INT(bool, 1, false)
1562
+ ALL_OP_REL_WITH_INT(char, 8, CHAR_IS_SIGNED)
1563
+ ALL_OP_REL_WITH_INT(signed char, 8, true)
1564
+ ALL_OP_REL_WITH_INT(unsigned char, 8, false)
1565
+ ALL_OP_REL_WITH_INT(short, _AP_SIZE_short, true)
1566
+ ALL_OP_REL_WITH_INT(unsigned short, _AP_SIZE_short, false)
1567
+ ALL_OP_REL_WITH_INT(int, _AP_SIZE_int, true)
1568
+ ALL_OP_REL_WITH_INT(unsigned int, _AP_SIZE_int, false)
1569
+ ALL_OP_REL_WITH_INT(long, _AP_SIZE_long, true)
1570
+ ALL_OP_REL_WITH_INT(unsigned long, _AP_SIZE_long, false)
1571
+ ALL_OP_REL_WITH_INT(ap_slong, _AP_SIZE_ap_slong, true)
1572
+ ALL_OP_REL_WITH_INT(ap_ulong, _AP_SIZE_ap_slong, false)
1573
+
1574
+ #undef OP_REL_WITH_INT
1575
+ #undef ALL_OP_BIN_WITH_INT
1576
+
1577
+ #define OP_REL_WITH_DOUBLE_OR_FLOAT(Sym) \
1578
+ template <int _AP_W, bool _AP_S> \
1579
+ INLINE bool operator Sym(const ap_int_base<_AP_W, _AP_S>& op1, \
1580
+ double op2) { \
1581
+ return op1.to_double() Sym op2 ; \
1582
+ } \
1583
+ template <int _AP_W, bool _AP_S> \
1584
+ INLINE bool operator Sym(double op1, \
1585
+ const ap_int_base<_AP_W, _AP_S>& op2) { \
1586
+ return op1 Sym op2.to_double() ; \
1587
+ } \
1588
+ template <int _AP_W, bool _AP_S> \
1589
+ INLINE bool operator Sym(const ap_int_base<_AP_W, _AP_S>& op1, \
1590
+ float op2) { \
1591
+ return op1.to_double() Sym op2 ; \
1592
+ } \
1593
+ template <int _AP_W, bool _AP_S> \
1594
+ INLINE bool operator Sym(float op1, \
1595
+ const ap_int_base<_AP_W, _AP_S>& op2) { \
1596
+ return op1 Sym op2.to_double() ; \
1597
+ }
1598
+ OP_REL_WITH_DOUBLE_OR_FLOAT(>)
1599
+ OP_REL_WITH_DOUBLE_OR_FLOAT(<)
1600
+ OP_REL_WITH_DOUBLE_OR_FLOAT(>=)
1601
+ OP_REL_WITH_DOUBLE_OR_FLOAT(<=)
1602
+ OP_REL_WITH_DOUBLE_OR_FLOAT(==)
1603
+ OP_REL_WITH_DOUBLE_OR_FLOAT(!=)
1604
+
1605
+ #undef OP_REL_WITH_DOUBLE_OR_FLOAT
1606
+
1607
+
1608
+ /* Operators with ap_bit_ref.
1609
+ * ------------------------------------------------------------
1610
+ */
1611
+ // arithmetic, bitwise and shift operators.
1612
+ #define OP_BIN_WITH_RANGE(BIN_OP, RTYPE) \
1613
+ template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1614
+ INLINE typename ap_int_base<_AP_W1, _AP_S1>::template RType<_AP_W2, \
1615
+ _AP_S2>::RTYPE \
1616
+ operator BIN_OP(const ap_range_ref<_AP_W1, _AP_S1>& op1, \
1617
+ const ap_int_base<_AP_W2, _AP_S2>& op2) { \
1618
+ return ap_int_base<_AP_W1, false>(op1) BIN_OP op2; \
1619
+ } \
1620
+ template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1621
+ INLINE typename ap_int_base<_AP_W1, _AP_S1>::template RType<_AP_W2, \
1622
+ _AP_S2>::RTYPE \
1623
+ operator BIN_OP(const ap_int_base<_AP_W1, _AP_S1>& op1, \
1624
+ const ap_range_ref<_AP_W2, _AP_S2>& op2) { \
1625
+ return op1 BIN_OP ap_int_base<_AP_W2, false>(op2); \
1626
+ }
1627
+
1628
+ OP_BIN_WITH_RANGE(+, plus)
1629
+ OP_BIN_WITH_RANGE(-, minus)
1630
+ OP_BIN_WITH_RANGE(*, mult)
1631
+ OP_BIN_WITH_RANGE(/, div)
1632
+ OP_BIN_WITH_RANGE(%, mod)
1633
+ OP_BIN_WITH_RANGE(&, logic)
1634
+ OP_BIN_WITH_RANGE(|, logic)
1635
+ OP_BIN_WITH_RANGE(^, logic)
1636
+ OP_BIN_WITH_RANGE(>>, arg1)
1637
+ OP_BIN_WITH_RANGE(<<, arg1)
1638
+
1639
+ #undef OP_BIN_WITH_RANGE
1640
+
1641
+ // compound assignment operators.
1642
+ #define OP_ASSIGN_WITH_RANGE(ASSIGN_OP) \
1643
+ template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1644
+ INLINE ap_int_base<_AP_W1, _AP_S1>& operator ASSIGN_OP( \
1645
+ ap_int_base<_AP_W1, _AP_S1>& op1, ap_range_ref<_AP_W2, _AP_S2>& op2) { \
1646
+ return op1 ASSIGN_OP ap_int_base<_AP_W2, false>(op2); \
1647
+ } \
1648
+ template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1649
+ INLINE ap_range_ref<_AP_W1, _AP_S1>& operator ASSIGN_OP( \
1650
+ ap_range_ref<_AP_W1, _AP_S1>& op1, ap_int_base<_AP_W2, _AP_S2>& op2) { \
1651
+ ap_int_base<_AP_W1, false> tmp(op1); \
1652
+ tmp ASSIGN_OP op2; \
1653
+ op1 = tmp; \
1654
+ return op1; \
1655
+ }
1656
+
1657
+ OP_ASSIGN_WITH_RANGE(+=)
1658
+ OP_ASSIGN_WITH_RANGE(-=)
1659
+ OP_ASSIGN_WITH_RANGE(*=)
1660
+ OP_ASSIGN_WITH_RANGE(/=)
1661
+ OP_ASSIGN_WITH_RANGE(%=)
1662
+ OP_ASSIGN_WITH_RANGE(&=)
1663
+ OP_ASSIGN_WITH_RANGE(|=)
1664
+ OP_ASSIGN_WITH_RANGE(^=)
1665
+ OP_ASSIGN_WITH_RANGE(>>=)
1666
+ OP_ASSIGN_WITH_RANGE(<<=)
1667
+
1668
+ #undef OP_ASSIGN_WITH_RANGE
1669
+
1670
+ // equality and relational operators
1671
+ #define OP_REL_WITH_RANGE(REL_OP) \
1672
+ template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1673
+ INLINE bool operator REL_OP(const ap_range_ref<_AP_W1, _AP_S1>& op1, \
1674
+ const ap_int_base<_AP_W2, _AP_S2>& op2) { \
1675
+ return ap_int_base<_AP_W1, false>(op1).operator REL_OP(op2); \
1676
+ } \
1677
+ template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1678
+ INLINE bool operator REL_OP(const ap_int_base<_AP_W1, _AP_S1>& op1, \
1679
+ const ap_range_ref<_AP_W2, _AP_S2>& op2) { \
1680
+ return op1.operator REL_OP(op2.operator ap_int_base<_AP_W2, false>()); \
1681
+ }
1682
+
1683
+ OP_REL_WITH_RANGE(==)
1684
+ OP_REL_WITH_RANGE(!=)
1685
+ OP_REL_WITH_RANGE(>)
1686
+ OP_REL_WITH_RANGE(>=)
1687
+ OP_REL_WITH_RANGE(<)
1688
+ OP_REL_WITH_RANGE(<=)
1689
+
1690
+ #undef OP_REL_WITH_RANGE
1691
+
1692
+ /* Operators with ap_bit_ref.
1693
+ * ------------------------------------------------------------
1694
+ */
1695
+ // arithmetic, bitwise and shift operators.
1696
+ #define OP_BIN_WITH_BIT(BIN_OP, RTYPE) \
1697
+ template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1698
+ INLINE typename ap_int_base<_AP_W1, _AP_S1>::template RType<1, false>::RTYPE \
1699
+ operator BIN_OP(const ap_int_base<_AP_W1, _AP_S1>& op1, \
1700
+ const ap_bit_ref<_AP_W2, _AP_S2>& op2) { \
1701
+ return op1 BIN_OP ap_int_base<1, false>(op2); \
1702
+ } \
1703
+ template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1704
+ INLINE typename ap_int_base<1, false>::template RType<_AP_W2, _AP_S2>::RTYPE \
1705
+ operator BIN_OP(const ap_bit_ref<_AP_W1, _AP_S1>& op1, \
1706
+ const ap_int_base<_AP_W2, _AP_S2>& op2) { \
1707
+ return ap_int_base<1, false>(op1) BIN_OP op2; \
1708
+ }
1709
+
1710
+ OP_BIN_WITH_BIT(+, plus)
1711
+ OP_BIN_WITH_BIT(-, minus)
1712
+ OP_BIN_WITH_BIT(*, mult)
1713
+ OP_BIN_WITH_BIT(/, div)
1714
+ OP_BIN_WITH_BIT(%, mod)
1715
+ OP_BIN_WITH_BIT(&, logic)
1716
+ OP_BIN_WITH_BIT(|, logic)
1717
+ OP_BIN_WITH_BIT(^, logic)
1718
+ OP_BIN_WITH_BIT(>>, arg1)
1719
+ OP_BIN_WITH_BIT(<<, arg1)
1720
+
1721
+ #undef OP_BIN_WITH_BIT
1722
+
1723
+ // compound assignment operators.
1724
+ #define OP_ASSIGN_WITH_BIT(ASSIGN_OP) \
1725
+ template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1726
+ INLINE ap_int_base<_AP_W1, _AP_S1>& operator ASSIGN_OP( \
1727
+ ap_int_base<_AP_W1, _AP_S1>& op1, ap_bit_ref<_AP_W2, _AP_S2>& op2) { \
1728
+ return op1 ASSIGN_OP ap_int_base<1, false>(op2); \
1729
+ } \
1730
+ template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1731
+ INLINE ap_bit_ref<_AP_W1, _AP_S1>& operator ASSIGN_OP( \
1732
+ ap_bit_ref<_AP_W1, _AP_S1>& op1, ap_int_base<_AP_W2, _AP_S2>& op2) { \
1733
+ ap_int_base<1, false> tmp(op1); \
1734
+ tmp ASSIGN_OP op2; \
1735
+ op1 = tmp; \
1736
+ return op1; \
1737
+ }
1738
+
1739
+ OP_ASSIGN_WITH_BIT(+=)
1740
+ OP_ASSIGN_WITH_BIT(-=)
1741
+ OP_ASSIGN_WITH_BIT(*=)
1742
+ OP_ASSIGN_WITH_BIT(/=)
1743
+ OP_ASSIGN_WITH_BIT(%=)
1744
+ OP_ASSIGN_WITH_BIT(&=)
1745
+ OP_ASSIGN_WITH_BIT(|=)
1746
+ OP_ASSIGN_WITH_BIT(^=)
1747
+ OP_ASSIGN_WITH_BIT(>>=)
1748
+ OP_ASSIGN_WITH_BIT(<<=)
1749
+
1750
+ #undef OP_ASSIGN_WITH_BIT
1751
+
1752
+ // equality and relational operators.
1753
+ #define OP_REL_WITH_BIT(REL_OP) \
1754
+ template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1755
+ INLINE bool operator REL_OP(const ap_int_base<_AP_W1, _AP_S1>& op1, \
1756
+ const ap_bit_ref<_AP_W2, _AP_S2>& op2) { \
1757
+ return op1 REL_OP ap_int_base<1, false>(op2); \
1758
+ } \
1759
+ template <int _AP_W1, bool _AP_S1, int _AP_W2, bool _AP_S2> \
1760
+ INLINE bool operator REL_OP(const ap_bit_ref<_AP_W1, _AP_S1>& op1, \
1761
+ const ap_int_base<_AP_W2, _AP_S2>& op2) { \
1762
+ return ap_int_base<1, false>(op1) REL_OP op2; \
1763
+ }
1764
+
1765
+ OP_REL_WITH_BIT(==)
1766
+ OP_REL_WITH_BIT(!=)
1767
+ OP_REL_WITH_BIT(>)
1768
+ OP_REL_WITH_BIT(>=)
1769
+ OP_REL_WITH_BIT(<)
1770
+ OP_REL_WITH_BIT(<=)
1771
+
1772
+ #undef OP_REL_WITH_BIT
1773
+
1774
+
1775
+ /* Operators with ap_concat_ref.
1776
+ * ------------------------------------------------------------
1777
+ */
1778
+ // arithmetic, bitwise and shift operators.
1779
+ // bitwise operators are defined in struct.
1780
+ // TODO specify whether to define arithmetic and bitwise operators.
1781
+ #if 0
1782
+ #define OP_BIN_WITH_CONCAT(BIN_OP, RTYPE) \
1783
+ template <int _AP_W1, typename _AP_T1, int _AP_W2, typename _AP_T2, \
1784
+ int _AP_W3, bool _AP_S3> \
1785
+ INLINE typename ap_int_base<_AP_W3, _AP_S3>::template RType<_AP_W1 + _AP_W2, \
1786
+ false>::RTYPE \
1787
+ operator BIN_OP(const ap_int_base<_AP_W3, _AP_S3>& op1, \
1788
+ const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& op2) { \
1789
+ /* convert ap_concat_ref to ap_int_base */ \
1790
+ return op1 BIN_OP op2.get(); \
1791
+ } \
1792
+ template <int _AP_W1, typename _AP_T1, int _AP_W2, typename _AP_T2, \
1793
+ int _AP_W3, bool _AP_S3> \
1794
+ INLINE typename ap_int_base<_AP_W1 + _AP_W2, \
1795
+ false>::template RType<_AP_W3, _AP_S3>::RTYPE \
1796
+ operator BIN_OP(const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& op1, \
1797
+ const ap_int_base<_AP_W3, _AP_S3>& op2) { \
1798
+ /* convert ap_concat_ref to ap_int_base */ \
1799
+ return op1.get() BIN_OP op2; \
1800
+ }
1801
+
1802
+ OP_BIN_WITH_CONCAT(+, plus)
1803
+ OP_BIN_WITH_CONCAT(-, minus)
1804
+ OP_BIN_WITH_CONCAT(*, mult)
1805
+ OP_BIN_WITH_CONCAT(/, div)
1806
+ OP_BIN_WITH_CONCAT(%, mod)
1807
+ OP_BIN_WITH_CONCAT(&, logic)
1808
+ OP_BIN_WITH_CONCAT(|, logic)
1809
+ OP_BIN_WITH_CONCAT(^, logic)
1810
+ OP_BIN_WITH_CONCAT(>>, arg1)
1811
+ OP_BIN_WITH_CONCAT(<<, arg1)
1812
+
1813
+ #undef OP_BIN_WITH_CONCAT
1814
+
1815
+ // compound assignment operators.
1816
+ #define OP_ASSIGN_WITH_CONCAT(ASSIGN_OP) \
1817
+ template <int _AP_W1, typename _AP_T1, int _AP_W2, typename _AP_T2, \
1818
+ int _AP_W3, bool _AP_S3> \
1819
+ INLINE typename ap_int_base<_AP_W3, _AP_S3>::template RType<_AP_W1 + _AP_W2, \
1820
+ false>::RTYPE \
1821
+ operator ASSIGN_OP( \
1822
+ const ap_int_base<_AP_W3, _AP_S3>& op1, \
1823
+ const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& op2) { \
1824
+ /* convert ap_concat_ref to ap_int_base */ \
1825
+ return op1 ASSIGN_OP op2.get(); \
1826
+ } \
1827
+ template <int _AP_W1, typename _AP_T1, int _AP_W2, typename _AP_T2, \
1828
+ int _AP_W3, bool _AP_S3> \
1829
+ INLINE typename ap_int_base<_AP_W1 + _AP_W2, \
1830
+ false>::template RType<_AP_W3, _AP_S3>::RTYPE \
1831
+ operator ASSIGN_OP(const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& op1, \
1832
+ const ap_int_base<_AP_W3, _AP_S3>& op2) { \
1833
+ /* convert ap_concat_ref to ap_int_base */ \
1834
+ ap_int_base<_AP_W1 + _AP_W2, false> tmp = op1.get(); \
1835
+ tmp ASSIGN_OP op2; \
1836
+ op1 = tmp; \
1837
+ return op1; \
1838
+ }
1839
+
1840
+ OP_ASSIGN_WITH_CONCAT(+=)
1841
+ OP_ASSIGN_WITH_CONCAT(-=)
1842
+ OP_ASSIGN_WITH_CONCAT(*=)
1843
+ OP_ASSIGN_WITH_CONCAT(/=)
1844
+ OP_ASSIGN_WITH_CONCAT(%=)
1845
+ OP_ASSIGN_WITH_CONCAT(&=)
1846
+ OP_ASSIGN_WITH_CONCAT(|=)
1847
+ OP_ASSIGN_WITH_CONCAT(^=)
1848
+ OP_ASSIGN_WITH_CONCAT(>>=)
1849
+ OP_ASSIGN_WITH_CONCAT(<<=)
1850
+
1851
+ #undef OP_ASSIGN_WITH_CONCAT
1852
+ #endif
1853
+
1854
+ // equality and relational operators.
1855
+ #define OP_REL_WITH_CONCAT(REL_OP) \
1856
+ template <int _AP_W1, typename _AP_T1, int _AP_W2, typename _AP_T2, \
1857
+ int _AP_W3, bool _AP_S3> \
1858
+ INLINE bool operator REL_OP( \
1859
+ const ap_int_base<_AP_W3, _AP_S3>& op1, \
1860
+ const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& op2) { \
1861
+ /* convert ap_concat_ref to ap_int_base */ \
1862
+ return op1 REL_OP op2.get(); \
1863
+ } \
1864
+ template <int _AP_W1, typename _AP_T1, int _AP_W2, typename _AP_T2, \
1865
+ int _AP_W3, bool _AP_S3> \
1866
+ INLINE bool operator REL_OP( \
1867
+ const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& op1, \
1868
+ const ap_int_base<_AP_W3, _AP_S3>& op2) { \
1869
+ /* convert ap_concat_ref to ap_int_base */ \
1870
+ return op1.get() REL_OP op2; \
1871
+ }
1872
+
1873
+ OP_REL_WITH_CONCAT(==)
1874
+ OP_REL_WITH_CONCAT(!=)
1875
+ OP_REL_WITH_CONCAT(>)
1876
+ OP_REL_WITH_CONCAT(>=)
1877
+ OP_REL_WITH_CONCAT(<)
1878
+ OP_REL_WITH_CONCAT(<=)
1879
+
1880
+ #undef OP_REL_WITH_CONCAT
1881
+
1882
+ #endif // ifndef __cplusplus
1883
+ #endif // ifndef __AP_INT_BASE_H__
1884
+
1885
+ // -*- cpp -*-