da4ml 0.5.0__cp312-cp312-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-312-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 +194 -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 +240 -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.0.dist-info/METADATA +85 -0
  92. da4ml-0.5.0.dist-info/RECORD +96 -0
  93. da4ml-0.5.0.dist-info/WHEEL +6 -0
  94. da4ml-0.5.0.dist-info/entry_points.txt +3 -0
  95. da4ml-0.5.0.dist-info/sboms/auditwheel.cdx.json +1 -0
  96. da4ml.libs/libgomp-e985bcbb.so.1.0.0 +0 -0
@@ -0,0 +1,1346 @@
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_REF_H__
18
+ #define __AP_INT_REF_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
+
27
+ #else
28
+
29
+ #ifndef __SYNTHESIS__
30
+ #include <iostream>
31
+ #endif
32
+
33
+ /* Concatination reference.
34
+ ----------------------------------------------------------------
35
+ */
36
+ template <int _AP_W1, typename _AP_T1, int _AP_W2, typename _AP_T2>
37
+ struct ap_concat_ref {
38
+ enum {
39
+ _AP_WR = _AP_W1 + _AP_W2,
40
+ };
41
+
42
+ _AP_T1& mbv1;
43
+ _AP_T2& mbv2;
44
+
45
+ INLINE ap_concat_ref(const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& ref)
46
+ : mbv1(ref.mbv1), mbv2(ref.mbv2) {}
47
+
48
+ INLINE ap_concat_ref(_AP_T1& bv1, _AP_T2& bv2) : mbv1(bv1), mbv2(bv2) {}
49
+
50
+ template <int _AP_W3, bool _AP_S3>
51
+ INLINE ap_concat_ref& operator=(const ap_int_base<_AP_W3, _AP_S3>& val) {
52
+ ap_int_base<_AP_W1 + _AP_W2, false> vval(val);
53
+ int W_ref1 = mbv1.length();
54
+ int W_ref2 = mbv2.length();
55
+ ap_int_base<_AP_W1, false> Part1;
56
+ Part1.V = _AP_ROOT_op_get_range(vval.V, W_ref2, W_ref1 + W_ref2 - 1);
57
+ mbv1.set(Part1);
58
+ ap_int_base<_AP_W2, false> Part2;
59
+ Part2.V = _AP_ROOT_op_get_range(vval.V, 0, W_ref2 - 1);
60
+ mbv2.set(Part2);
61
+ return *this;
62
+ }
63
+
64
+ // assign op from hls supported C integral types.
65
+ // FIXME disabled to support legacy code directly assign from sc_signal<T>
66
+ //template <typename T>
67
+ //INLINE typename _ap_type::enable_if<_ap_type::is_integral<T>::value,
68
+ // ap_concat_ref&>::type
69
+ //operator=(T val) {
70
+ // ap_int_base<_AP_W1 + _AP_W2, false> tmpVal(val);
71
+ // return operator=(tmpVal);
72
+ //}
73
+ #define ASSIGN_WITH_CTYPE(_Tp) \
74
+ INLINE ap_concat_ref& operator=(_Tp val) { \
75
+ ap_int_base<_AP_W1 + _AP_W2, false> tmpVal(val); \
76
+ return operator=(tmpVal); \
77
+ }
78
+
79
+ ASSIGN_WITH_CTYPE(bool)
80
+ ASSIGN_WITH_CTYPE(char)
81
+ ASSIGN_WITH_CTYPE(signed char)
82
+ ASSIGN_WITH_CTYPE(unsigned char)
83
+ ASSIGN_WITH_CTYPE(short)
84
+ ASSIGN_WITH_CTYPE(unsigned short)
85
+ ASSIGN_WITH_CTYPE(int)
86
+ ASSIGN_WITH_CTYPE(unsigned int)
87
+ ASSIGN_WITH_CTYPE(long)
88
+ ASSIGN_WITH_CTYPE(unsigned long)
89
+ ASSIGN_WITH_CTYPE(ap_slong)
90
+ ASSIGN_WITH_CTYPE(ap_ulong)
91
+ #if _AP_ENABLE_HALF_ == 1
92
+ ASSIGN_WITH_CTYPE(half)
93
+ #endif
94
+ ASSIGN_WITH_CTYPE(float)
95
+ ASSIGN_WITH_CTYPE(double)
96
+
97
+ #undef ASSIGN_WITH_CTYPE
98
+
99
+ // Be explicit to prevent it from being deleted, as field d_bv
100
+ // is of reference type.
101
+ INLINE ap_concat_ref& operator=(
102
+ const ap_concat_ref<_AP_W1, _AP_T1, _AP_W2, _AP_T2>& val) {
103
+ ap_int_base<_AP_W1 + _AP_W2, false> tmpVal(val);
104
+ return operator=(tmpVal);
105
+ }
106
+
107
+ template <int _AP_W3, typename _AP_T3, int _AP_W4, typename _AP_T4>
108
+ INLINE ap_concat_ref& operator=(
109
+ const ap_concat_ref<_AP_W3, _AP_T3, _AP_W4, _AP_T4>& val) {
110
+ ap_int_base<_AP_W1 + _AP_W2, false> tmpVal(val);
111
+ return operator=(tmpVal);
112
+ }
113
+
114
+ template <int _AP_W3, bool _AP_S3>
115
+ INLINE ap_concat_ref& operator=(const ap_bit_ref<_AP_W3, _AP_S3>& val) {
116
+ ap_int_base<_AP_W1 + _AP_W2, false> tmpVal(val);
117
+ return operator=(tmpVal);
118
+ }
119
+ template <int _AP_W3, bool _AP_S3>
120
+ INLINE ap_concat_ref& operator=(const ap_range_ref<_AP_W3, _AP_S3>& val) {
121
+ ap_int_base<_AP_W1 + _AP_W2, false> tmpVal(val);
122
+ return operator=(tmpVal);
123
+ }
124
+
125
+ template <int _AP_W3, int _AP_I3, bool _AP_S3, ap_q_mode _AP_Q3,
126
+ ap_o_mode _AP_O3, int _AP_N3>
127
+ INLINE ap_concat_ref& operator=(
128
+ const af_range_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3>& val) {
129
+ return operator=((const ap_int_base<_AP_W3, false>)(val));
130
+ }
131
+
132
+ template <int _AP_W3, int _AP_I3, bool _AP_S3, ap_q_mode _AP_Q3,
133
+ ap_o_mode _AP_O3, int _AP_N3>
134
+ INLINE ap_concat_ref& operator=(
135
+ const ap_fixed_base<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3>&
136
+ val) {
137
+ return operator=(val.to_ap_int_base());
138
+ }
139
+
140
+ template <int _AP_W3, int _AP_I3, bool _AP_S3, ap_q_mode _AP_Q3,
141
+ ap_o_mode _AP_O3, int _AP_N3>
142
+ INLINE ap_concat_ref& operator=(
143
+ const af_bit_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3>& val) {
144
+ return operator=((ap_ulong)(bool)(val));
145
+ }
146
+
147
+ INLINE operator ap_int_base<_AP_WR, false>() const { return get(); }
148
+
149
+ INLINE operator ap_ulong() const { return get().to_uint64(); }
150
+
151
+ template <int _AP_W3, bool _AP_S3>
152
+ INLINE ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3,
153
+ ap_range_ref<_AP_W3, _AP_S3> >
154
+ operator,(const ap_range_ref<_AP_W3, _AP_S3> &a2) {
155
+ return ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3,
156
+ ap_range_ref<_AP_W3, _AP_S3> >(
157
+ *this, const_cast<ap_range_ref<_AP_W3, _AP_S3>&>(a2));
158
+ }
159
+
160
+ template <int _AP_W3, bool _AP_S3>
161
+ INLINE
162
+ ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, ap_int_base<_AP_W3, _AP_S3> >
163
+ operator,(ap_int_base<_AP_W3, _AP_S3> &a2) {
164
+ return ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3,
165
+ ap_int_base<_AP_W3, _AP_S3> >(*this, a2);
166
+ }
167
+
168
+ template <int _AP_W3, bool _AP_S3>
169
+ INLINE
170
+ ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, ap_int_base<_AP_W3, _AP_S3> >
171
+ operator,(volatile ap_int_base<_AP_W3, _AP_S3> &a2) {
172
+ return ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3,
173
+ ap_int_base<_AP_W3, _AP_S3> >(
174
+ *this, const_cast<ap_int_base<_AP_W3, _AP_S3>&>(a2));
175
+ }
176
+
177
+ template <int _AP_W3, bool _AP_S3>
178
+ INLINE
179
+ ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, ap_int_base<_AP_W3, _AP_S3> >
180
+ operator,(const ap_int_base<_AP_W3, _AP_S3> &a2) {
181
+ return ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3,
182
+ ap_int_base<_AP_W3, _AP_S3> >(
183
+ *this, const_cast<ap_int_base<_AP_W3, _AP_S3>&>(a2));
184
+ }
185
+
186
+ template <int _AP_W3, bool _AP_S3>
187
+ INLINE
188
+ ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3, ap_int_base<_AP_W3, _AP_S3> >
189
+ operator,(const volatile ap_int_base<_AP_W3, _AP_S3> &a2) {
190
+ // FIXME op's life does not seem long enough
191
+ ap_int_base<_AP_W3, _AP_S3> op(a2);
192
+ return ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3,
193
+ ap_int_base<_AP_W3, _AP_S3> >(
194
+ *this, const_cast<ap_int_base<_AP_W3, _AP_S3>&>(op));
195
+ }
196
+
197
+ template <int _AP_W3, bool _AP_S3>
198
+ INLINE ap_concat_ref<_AP_WR, ap_concat_ref, 1, ap_bit_ref<_AP_W3, _AP_S3> >
199
+ operator,(const ap_bit_ref<_AP_W3, _AP_S3> &a2) {
200
+ return ap_concat_ref<_AP_WR, ap_concat_ref, 1, ap_bit_ref<_AP_W3, _AP_S3> >(
201
+ *this, const_cast<ap_bit_ref<_AP_W3, _AP_S3>&>(a2));
202
+ }
203
+
204
+ template <int _AP_W3, typename _AP_T3, int _AP_W4, typename _AP_T4>
205
+ INLINE ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3 + _AP_W4,
206
+ ap_concat_ref<_AP_W3, _AP_T3, _AP_W4, _AP_T4> >
207
+ operator,(const ap_concat_ref<_AP_W3, _AP_T3, _AP_W4, _AP_T4> &a2) {
208
+ return ap_concat_ref<_AP_WR, ap_concat_ref, _AP_W3 + _AP_W4,
209
+ ap_concat_ref<_AP_W3, _AP_T3, _AP_W4, _AP_T4> >(
210
+ *this, const_cast<ap_concat_ref<_AP_W3, _AP_T3, _AP_W4, _AP_T4>&>(a2));
211
+ }
212
+
213
+ template <int _AP_W3, int _AP_I3, bool _AP_S3, ap_q_mode _AP_Q3,
214
+ ap_o_mode _AP_O3, int _AP_N3>
215
+ INLINE ap_concat_ref<
216
+ _AP_WR, ap_concat_ref, _AP_W3,
217
+ af_range_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> >
218
+ operator,(
219
+ const af_range_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> &a2) {
220
+ return ap_concat_ref<
221
+ _AP_WR, ap_concat_ref, _AP_W3,
222
+ af_range_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> >(
223
+ *this,
224
+ const_cast<
225
+ af_range_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3>&>(a2));
226
+ }
227
+
228
+ template <int _AP_W3, int _AP_I3, bool _AP_S3, ap_q_mode _AP_Q3,
229
+ ap_o_mode _AP_O3, int _AP_N3>
230
+ INLINE
231
+ ap_concat_ref<_AP_WR, ap_concat_ref, 1,
232
+ af_bit_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> >
233
+ operator,(const af_bit_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3>
234
+ &a2) {
235
+ return ap_concat_ref<
236
+ _AP_WR, ap_concat_ref, 1,
237
+ af_bit_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3> >(
238
+ *this,
239
+ const_cast<af_bit_ref<_AP_W3, _AP_I3, _AP_S3, _AP_Q3, _AP_O3, _AP_N3>&>(
240
+ a2));
241
+ }
242
+
243
+ template <int _AP_W3, bool _AP_S3>
244
+ INLINE ap_int_base<AP_MAX(_AP_WR, _AP_W3), _AP_S3> operator&(
245
+ const ap_int_base<_AP_W3, _AP_S3>& a2) {
246
+ return get() & a2;
247
+ }
248
+
249
+ template <int _AP_W3, bool _AP_S3>
250
+ INLINE ap_int_base<AP_MAX(_AP_WR, _AP_W3), _AP_S3> operator|(
251
+ const ap_int_base<_AP_W3, _AP_S3>& a2) {
252
+ return get() | a2;
253
+ }
254
+
255
+ template <int _AP_W3, bool _AP_S3>
256
+ INLINE ap_int_base<AP_MAX(_AP_WR, _AP_W3), _AP_S3> operator^(
257
+ const ap_int_base<_AP_W3, _AP_S3>& a2) {
258
+ return get() ^ a2;
259
+ }
260
+
261
+ #if 0
262
+ template<int Hi, int Lo>
263
+ INLINE ap_int_base<Hi-Lo+1, false> slice() {
264
+ ap_int_base<_AP_WR, false> bv = get();
265
+ return bv.slice<Hi,Lo>();
266
+ }
267
+ #endif
268
+
269
+ INLINE ap_int_base<_AP_WR, false> get() const {
270
+ ap_int_base<_AP_WR, false> tmpVal(0);
271
+ int W_ref1 = mbv1.length();
272
+ int W_ref2 = mbv2.length();
273
+ ap_int_base<_AP_W2, false> v2(mbv2);
274
+ ap_int_base<_AP_W1, false> v1(mbv1);
275
+ tmpVal.V = _AP_ROOT_op_set_range(tmpVal.V, 0, W_ref2 - 1, v2.V);
276
+ tmpVal.V =
277
+ _AP_ROOT_op_set_range(tmpVal.V, W_ref2, W_ref1 + W_ref2 - 1, v1.V);
278
+ return tmpVal;
279
+ }
280
+
281
+ template <int _AP_W3>
282
+ INLINE void set(const ap_int_base<_AP_W3, false>& val) {
283
+ ap_int_base<_AP_W1 + _AP_W2, false> vval(val);
284
+ int W_ref1 = mbv1.length();
285
+ int W_ref2 = mbv2.length();
286
+ ap_int_base<_AP_W1, false> tmpVal1;
287
+ tmpVal1.V = _AP_ROOT_op_get_range(vval.V, W_ref2, W_ref1 + W_ref2 - 1);
288
+ mbv1.set(tmpVal1);
289
+ ap_int_base<_AP_W2, false> tmpVal2;
290
+ tmpVal2.V = _AP_ROOT_op_get_range(vval.V, 0, W_ref2 - 1);
291
+ mbv2.set(tmpVal2);
292
+ }
293
+
294
+ INLINE int length() const { return mbv1.length() + mbv2.length(); }
295
+ }; // struct ap_concat_ref
296
+
297
+ /* Range (slice) reference.
298
+ ----------------------------------------------------------------
299
+ */
300
+ template <int _AP_W, bool _AP_S>
301
+ struct ap_range_ref {
302
+ // struct ssdm_int or its sim model.
303
+ // TODO make it possible to reference to ap_fixed_base/ap_fixed/ap_ufixed
304
+ // and then we can retire af_range_ref.
305
+ typedef ap_int_base<_AP_W, _AP_S> ref_type;
306
+ ref_type& d_bv;
307
+ int l_index;
308
+ int h_index;
309
+
310
+ public:
311
+ INLINE ap_range_ref(const ap_range_ref<_AP_W, _AP_S>& ref)
312
+ : d_bv(ref.d_bv), l_index(ref.l_index), h_index(ref.h_index) {}
313
+
314
+ INLINE ap_range_ref(ref_type* bv, int h, int l)
315
+ : d_bv(*bv), l_index(l), h_index(h) {}
316
+
317
+ INLINE ap_range_ref(const ref_type* bv, int h, int l)
318
+ : d_bv(*const_cast<ref_type*>(bv)), l_index(l), h_index(h) {}
319
+
320
+ INLINE operator ap_int_base<_AP_W, false>() const {
321
+ ap_int_base<_AP_W, false> ret;
322
+ ret.V = _AP_ROOT_op_get_range(d_bv.V, l_index, h_index);
323
+ return ret;
324
+ }
325
+
326
+ INLINE operator ap_ulong() const { return to_uint64(); }
327
+
328
+ /// @name assign operators
329
+ // @{
330
+
331
+ // FIXME disabled to work-around lagacy code assigning from sc_signal<T>,
332
+ // which dependes on implicit type conversion.
333
+ //
334
+ // /// assign from hls supported C integral types.
335
+ // template <typename T>
336
+ // INLINE typename _ap_type::enable_if<_ap_type::is_integral<T>::value,
337
+ // ap_range_ref&>::type
338
+ // operator=(T val) {
339
+ // ap_int_base<_AP_W, false> tmp(val);
340
+ // d_bv.V = _AP_ROOT_op_set_range(d_bv.V, l_index, h_index, tmp.V);
341
+ // return *this;
342
+ // }
343
+ #define ASSIGN_WITH_CTYPE(_Tp) \
344
+ INLINE ap_range_ref& operator=(_Tp val) { \
345
+ ap_int_base<_AP_W, false> tmp(val); \
346
+ d_bv.V = _AP_ROOT_op_set_range(d_bv.V, l_index, h_index, tmp.V); \
347
+ return *this; \
348
+ }
349
+
350
+ ASSIGN_WITH_CTYPE(bool)
351
+ ASSIGN_WITH_CTYPE(char)
352
+ ASSIGN_WITH_CTYPE(signed char)
353
+ ASSIGN_WITH_CTYPE(unsigned char)
354
+ ASSIGN_WITH_CTYPE(short)
355
+ ASSIGN_WITH_CTYPE(unsigned short)
356
+ ASSIGN_WITH_CTYPE(int)
357
+ ASSIGN_WITH_CTYPE(unsigned int)
358
+ ASSIGN_WITH_CTYPE(long)
359
+ ASSIGN_WITH_CTYPE(unsigned long)
360
+ ASSIGN_WITH_CTYPE(ap_slong)
361
+ ASSIGN_WITH_CTYPE(ap_ulong)
362
+ #if _AP_ENABLE_HALF_ == 1
363
+ ASSIGN_WITH_CTYPE(half)
364
+ #endif
365
+ ASSIGN_WITH_CTYPE(float)
366
+ ASSIGN_WITH_CTYPE(double)
367
+
368
+ #undef ASSIGN_WITH_CTYPE
369
+
370
+ /// assign using string. XXX crucial for cosim.
371
+ INLINE ap_range_ref& operator=(const char* val) {
372
+ const ap_int_base<_AP_W, false> tmp(val); // XXX figure out radix
373
+ d_bv.V = _AP_ROOT_op_set_range(d_bv.V, l_index, h_index, tmp.V);
374
+ return *this;
375
+ }
376
+
377
+ /// assign from ap_int_base.
378
+ template <int _AP_W2, bool _AP_S2>
379
+ INLINE ap_range_ref& operator=(const ap_int_base<_AP_W2, _AP_S2>& val) {
380
+ ap_int_base<_AP_W, false> tmp(val);
381
+ d_bv.V = _AP_ROOT_op_set_range(d_bv.V, l_index, h_index, tmp.V);
382
+ return *this;
383
+ }
384
+
385
+ /// copy assign operator
386
+ // XXX Be explicit to prevent it from being deleted, as field d_bv
387
+ // is of reference type.
388
+ INLINE ap_range_ref& operator=(const ap_range_ref& val) {
389
+ return operator=((const ap_int_base<_AP_W, false>)val);
390
+ }
391
+
392
+ /// assign from range reference to ap_int_base.
393
+ template <int _AP_W2, bool _AP_S2>
394
+ INLINE ap_range_ref& operator=(const ap_range_ref<_AP_W2, _AP_S2>& val) {
395
+ return operator=((const ap_int_base<_AP_W2, false>)val);
396
+ }
397
+
398
+ /// assign from bit reference to ap_int_base.
399
+ template <int _AP_W2, bool _AP_S2>
400
+ INLINE ap_range_ref& operator=(const ap_bit_ref<_AP_W2, _AP_S2>& val) {
401
+ return operator=((ap_ulong)(bool)(val));
402
+ }
403
+
404
+ /// assign from ap_fixed_base.
405
+ template <int _AP_W2, int _AP_I2, bool _AP_S2, ap_q_mode _AP_Q2,
406
+ ap_o_mode _AP_O2, int _AP_N2>
407
+ INLINE ap_range_ref& operator=(
408
+ const ap_fixed_base<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>&
409
+ val) {
410
+ return operator=(val.to_ap_int_base());
411
+ }
412
+
413
+ /// assign from range reference to ap_fixed_base.
414
+ template <int _AP_W2, int _AP_I2, bool _AP_S2, ap_q_mode _AP_Q2,
415
+ ap_o_mode _AP_O2, int _AP_N2>
416
+ INLINE ap_range_ref& operator=(
417
+ const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& val) {
418
+ return operator=((const ap_int_base<_AP_W2, false>)val);
419
+ }
420
+
421
+ /// assign from bit reference to ap_fixed_base.
422
+ template <int _AP_W2, int _AP_I2, bool _AP_S2, ap_q_mode _AP_Q2,
423
+ ap_o_mode _AP_O2, int _AP_N2>
424
+ INLINE ap_range_ref& operator=(
425
+ const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& val) {
426
+ return operator=((ap_ulong)(bool)(val));
427
+ }
428
+
429
+ /// assign from compound reference.
430
+ template <int _AP_W2, typename _AP_T2, int _AP_W3, typename _AP_T3>
431
+ INLINE ap_range_ref& operator=(
432
+ const ap_concat_ref<_AP_W2, _AP_T3, _AP_W3, _AP_T3>& val) {
433
+ return operator=((const ap_int_base<_AP_W2 + _AP_W3, false>)(val));
434
+ }
435
+ // @}
436
+
437
+ template <int _AP_W2, bool _AP_S2>
438
+ INLINE
439
+ ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> >
440
+ operator,(const ap_range_ref<_AP_W2, _AP_S2> &a2) {
441
+ return ap_concat_ref<_AP_W, ap_range_ref, _AP_W2,
442
+ ap_range_ref<_AP_W2, _AP_S2> >(
443
+ *this, const_cast<ap_range_ref<_AP_W2, _AP_S2>&>(a2));
444
+ }
445
+
446
+ template <int _AP_W2, bool _AP_S2>
447
+ INLINE
448
+ ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, ap_int_base<_AP_W2, _AP_S2> >
449
+ operator,(ap_int_base<_AP_W2, _AP_S2> &a2) {
450
+ return ap_concat_ref<_AP_W, ap_range_ref, _AP_W2,
451
+ ap_int_base<_AP_W2, _AP_S2> >(*this, a2);
452
+ }
453
+
454
+ INLINE
455
+ ap_concat_ref<_AP_W, ap_range_ref, _AP_W, ap_int_base<_AP_W, _AP_S> >
456
+ operator,(ap_int_base<_AP_W, _AP_S>& a2) {
457
+ return ap_concat_ref<_AP_W, ap_range_ref, _AP_W,
458
+ ap_int_base<_AP_W, _AP_S> >(*this, a2);
459
+ }
460
+
461
+ template <int _AP_W2, bool _AP_S2>
462
+ INLINE
463
+ ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, ap_int_base<_AP_W2, _AP_S2> >
464
+ operator,(volatile ap_int_base<_AP_W2, _AP_S2> &a2) {
465
+ return ap_concat_ref<_AP_W, ap_range_ref, _AP_W2,
466
+ ap_int_base<_AP_W2, _AP_S2> >(
467
+ *this, const_cast<ap_int_base<_AP_W2, _AP_S2>&>(a2));
468
+ }
469
+
470
+ template <int _AP_W2, bool _AP_S2>
471
+ INLINE
472
+ ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, ap_int_base<_AP_W2, _AP_S2> >
473
+ operator,(const ap_int_base<_AP_W2, _AP_S2> &a2) {
474
+ return ap_concat_ref<_AP_W, ap_range_ref, _AP_W2,
475
+ ap_int_base<_AP_W2, _AP_S2> >(
476
+ *this, const_cast<ap_int_base<_AP_W2, _AP_S2>&>(a2));
477
+ }
478
+
479
+ template <int _AP_W2, bool _AP_S2>
480
+ INLINE
481
+ ap_concat_ref<_AP_W, ap_range_ref, _AP_W2, ap_int_base<_AP_W2, _AP_S2> >
482
+ operator,(const volatile ap_int_base<_AP_W2, _AP_S2> &a2) {
483
+ return ap_concat_ref<_AP_W, ap_range_ref, _AP_W2,
484
+ ap_int_base<_AP_W2, _AP_S2> >(
485
+ *this, const_cast<ap_int_base<_AP_W2, _AP_S2>&>(a2));
486
+ }
487
+
488
+ template <int _AP_W2, bool _AP_S2>
489
+ INLINE ap_concat_ref<_AP_W, ap_range_ref, 1, ap_bit_ref<_AP_W2, _AP_S2> >
490
+ operator,(const ap_bit_ref<_AP_W2, _AP_S2> &a2) {
491
+ return ap_concat_ref<_AP_W, ap_range_ref, 1, ap_bit_ref<_AP_W2, _AP_S2> >(
492
+ *this, const_cast<ap_bit_ref<_AP_W2, _AP_S2>&>(a2));
493
+ }
494
+
495
+ template <int _AP_W2, typename _AP_T2, int _AP_W3, typename _AP_T3>
496
+ INLINE ap_concat_ref<_AP_W, ap_range_ref, _AP_W2 + _AP_W3,
497
+ ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >
498
+ operator,(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) {
499
+ return ap_concat_ref<_AP_W, ap_range_ref, _AP_W2 + _AP_W3,
500
+ ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(
501
+ *this, const_cast<ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>&>(a2));
502
+ }
503
+
504
+ template <int _AP_W2, int _AP_I2, bool _AP_S2, ap_q_mode _AP_Q2,
505
+ ap_o_mode _AP_O2, int _AP_N2>
506
+ INLINE ap_concat_ref<
507
+ _AP_W, ap_range_ref, _AP_W2,
508
+ af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >
509
+ operator,(
510
+ const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> a2) {
511
+ return ap_concat_ref<
512
+ _AP_W, ap_range_ref, _AP_W2,
513
+ af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(
514
+ *this,
515
+ const_cast<
516
+ af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>&>(a2));
517
+ }
518
+
519
+ template <int _AP_W2, int _AP_I2, bool _AP_S2, ap_q_mode _AP_Q2,
520
+ ap_o_mode _AP_O2, int _AP_N2>
521
+ INLINE
522
+ ap_concat_ref<_AP_W, ap_range_ref, 1,
523
+ af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >
524
+ operator,(const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>
525
+ &a2) {
526
+ return ap_concat_ref<
527
+ _AP_W, ap_range_ref, 1,
528
+ af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(
529
+ *this,
530
+ const_cast<af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>&>(
531
+ a2));
532
+ }
533
+
534
+ template <int _AP_W2, bool _AP_S2>
535
+ INLINE bool operator==(const ap_range_ref<_AP_W2, _AP_S2>& op2) {
536
+ ap_int_base<_AP_W, false> lop(*this);
537
+ ap_int_base<_AP_W2, false> hop(op2);
538
+ return lop == hop;
539
+ }
540
+
541
+ template <int _AP_W2, bool _AP_S2>
542
+ INLINE bool operator!=(const ap_range_ref<_AP_W2, _AP_S2>& op2) {
543
+ return !(operator==(op2));
544
+ }
545
+
546
+ template <int _AP_W2, bool _AP_S2>
547
+ INLINE bool operator<(const ap_range_ref<_AP_W2, _AP_S2>& op2) {
548
+ ap_int_base<_AP_W, false> lop(*this);
549
+ ap_int_base<_AP_W2, false> hop(op2);
550
+ return lop < hop;
551
+ }
552
+
553
+ template <int _AP_W2, bool _AP_S2>
554
+ INLINE bool operator<=(const ap_range_ref<_AP_W2, _AP_S2>& op2) {
555
+ ap_int_base<_AP_W, false> lop(*this);
556
+ ap_int_base<_AP_W2, false> hop(op2);
557
+ return lop <= hop;
558
+ }
559
+
560
+ template <int _AP_W2, bool _AP_S2>
561
+ INLINE bool operator>(const ap_range_ref<_AP_W2, _AP_S2>& op2) {
562
+ return !(operator<=(op2));
563
+ }
564
+
565
+ template <int _AP_W2, bool _AP_S2>
566
+ INLINE bool operator>=(const ap_range_ref<_AP_W2, _AP_S2>& op2) {
567
+ return !(operator<(op2));
568
+ }
569
+
570
+ template <int _AP_W2, bool _AP_S2>
571
+ INLINE ap_range_ref<_AP_W, _AP_S>& operator|=(
572
+ const ap_range_ref<_AP_W2, _AP_S2>& op2) {
573
+ (this->d_bv).V |= (op2.d_bv).V;
574
+ return *this;
575
+ };
576
+
577
+ template <int _AP_W2, bool _AP_S2>
578
+ INLINE ap_range_ref<_AP_W, _AP_S>& operator|=(
579
+ const ap_int_base<_AP_W2, _AP_S2>& op2) {
580
+ (this->d_bv).V |= op2.V;
581
+ return *this;
582
+ };
583
+
584
+ template <int _AP_W2, bool _AP_S2>
585
+ INLINE ap_range_ref<_AP_W, _AP_S>& operator&=(
586
+ const ap_range_ref<_AP_W2, _AP_S2>& op2) {
587
+ (this->d_bv).V &= (op2.d_bv).V;
588
+ return *this;
589
+ };
590
+
591
+ template <int _AP_W2, bool _AP_S2>
592
+ INLINE ap_range_ref<_AP_W, _AP_S>& operator&=(
593
+ const ap_int_base<_AP_W2, _AP_S2>& op2) {
594
+ (this->d_bv).V &= op2.V;
595
+ return *this;
596
+ };
597
+
598
+ template <int _AP_W2, bool _AP_S2>
599
+ INLINE ap_range_ref<_AP_W, _AP_S>& operator^=(
600
+ const ap_range_ref<_AP_W2, _AP_S2>& op2) {
601
+ (this->d_bv).V ^= (op2.d_bv).V;
602
+ return *this;
603
+ };
604
+
605
+ template <int _AP_W2, bool _AP_S2>
606
+ INLINE ap_range_ref<_AP_W, _AP_S>& operator^=(
607
+ const ap_int_base<_AP_W2, _AP_S2>& op2) {
608
+ (this->d_bv).V ^= op2.V;
609
+ return *this;
610
+ };
611
+
612
+ INLINE ap_int_base<_AP_W, false> get() const {
613
+ ap_int_base<_AP_W, false> ret;
614
+ ret.V = _AP_ROOT_op_get_range(d_bv.V, l_index, h_index);
615
+ return ret;
616
+ }
617
+
618
+ template <int _AP_W2>
619
+ INLINE void set(const ap_int_base<_AP_W2, false>& val) {
620
+ d_bv.V = _AP_ROOT_op_set_range(d_bv.V, l_index, h_index, val.V);
621
+ }
622
+
623
+ INLINE int length() const {
624
+ return h_index >= l_index ? h_index - l_index + 1 : l_index - h_index + 1;
625
+ }
626
+
627
+ INLINE int to_int() const {
628
+ return (int)(_AP_ROOT_op_get_range(d_bv.V, l_index, h_index));
629
+ }
630
+
631
+ INLINE unsigned to_uint() const {
632
+ return (unsigned)(_AP_ROOT_op_get_range(d_bv.V, l_index, h_index));
633
+ }
634
+
635
+ INLINE long to_long() const {
636
+ return (long)(_AP_ROOT_op_get_range(d_bv.V, l_index, h_index));
637
+ }
638
+
639
+ INLINE unsigned long to_ulong() const {
640
+ return (unsigned long)(_AP_ROOT_op_get_range(d_bv.V, l_index, h_index));
641
+ }
642
+
643
+ INLINE ap_slong to_int64() const {
644
+ return (ap_slong)(_AP_ROOT_op_get_range(d_bv.V, l_index, h_index));
645
+ }
646
+
647
+ INLINE ap_ulong to_uint64() const {
648
+ return (ap_ulong)(_AP_ROOT_op_get_range(d_bv.V, l_index, h_index));
649
+ }
650
+
651
+ INLINE bool and_reduce() const {
652
+ bool ret = true;
653
+ bool reverse = l_index > h_index;
654
+ unsigned low = reverse ? h_index : l_index;
655
+ unsigned high = reverse ? l_index : h_index;
656
+ for (unsigned i = low; i != high; ++i) {
657
+ #ifdef __SYNTHESIS__
658
+ #pragma HLS unroll
659
+ #endif
660
+ ret &= _AP_ROOT_op_get_bit(d_bv.V, i);
661
+ }
662
+ return ret;
663
+ }
664
+
665
+ INLINE bool or_reduce() const {
666
+ bool ret = false;
667
+ bool reverse = l_index > h_index;
668
+ unsigned low = reverse ? h_index : l_index;
669
+ unsigned high = reverse ? l_index : h_index;
670
+ for (unsigned i = low; i != high; ++i) {
671
+ #ifdef __SYNTHESIS__
672
+ #pragma HLS unroll
673
+ #endif
674
+ ret |= _AP_ROOT_op_get_bit(d_bv.V, i);
675
+ }
676
+ return ret;
677
+ }
678
+
679
+ INLINE bool xor_reduce() const {
680
+ bool ret = false;
681
+ bool reverse = l_index > h_index;
682
+ unsigned low = reverse ? h_index : l_index;
683
+ unsigned high = reverse ? l_index : h_index;
684
+ for (unsigned i = low; i != high; ++i) {
685
+ #ifdef __SYNTHESIS__
686
+ #pragma HLS unroll
687
+ #endif
688
+ ret ^= _AP_ROOT_op_get_bit(d_bv.V, i);
689
+ }
690
+ return ret;
691
+ }
692
+ #ifndef __SYNTHESIS__
693
+ std::string to_string(signed char radix = 2) const {
694
+ ap_int_base<_AP_W, false> ret;
695
+ ret.V = _AP_ROOT_op_get_range(d_bv.V, l_index, h_index);
696
+ return ret.to_string(radix);
697
+ }
698
+ #else
699
+ // XXX HLS will delete this in synthesis
700
+ INLINE char* to_string(signed char radix = 2) const {
701
+ return 0;
702
+ }
703
+ #endif
704
+ }; // struct ap_range_ref
705
+
706
+ // XXX apcc cannot handle global std::ios_base::Init() brought in by <iostream>
707
+ #ifndef AP_AUTOCC
708
+ #ifndef __SYNTHESIS__
709
+ template <int _AP_W, bool _AP_S>
710
+ INLINE std::ostream& operator<<(std::ostream& os,
711
+ const ap_range_ref<_AP_W, _AP_S>& x) {
712
+ std::ios_base::fmtflags ff = std::cout.flags();
713
+ if (ff & std::cout.hex) {
714
+ os << x.to_string(16); // don't print sign
715
+ } else if (ff & std::cout.oct) {
716
+ os << x.to_string(8); // don't print sign
717
+ } else {
718
+ os << x.to_string(10);
719
+ }
720
+ return os;
721
+ }
722
+ #endif // ifndef __SYNTHESIS__
723
+
724
+ #ifndef __SYNTHESIS__
725
+ template <int _AP_W, bool _AP_S>
726
+ INLINE std::istream& operator>>(std::istream& in,
727
+ ap_range_ref<_AP_W, _AP_S>& op) {
728
+ std::string str;
729
+ in >> str;
730
+ op = ap_int_base<_AP_W, _AP_S>(str.c_str());
731
+ return in;
732
+ }
733
+ #endif // ifndef __SYNTHESIS__
734
+ #endif // ifndef AP_AUTOCC
735
+
736
+ /* Bit reference.
737
+ ----------------------------------------------------------------
738
+ */
739
+ template <int _AP_W, bool _AP_S>
740
+ struct ap_bit_ref {
741
+ // struct ssdm_int or its sim model.
742
+ // TODO make it possible to reference to ap_fixed_base/ap_fixed/ap_ufixed
743
+ // and then we can retire af_bit_ref.
744
+ typedef ap_int_base<_AP_W, _AP_S> ref_type;
745
+ ref_type& d_bv;
746
+ int d_index;
747
+
748
+ public:
749
+ // copy ctor
750
+ INLINE ap_bit_ref(const ap_bit_ref<_AP_W, _AP_S>& ref)
751
+ : d_bv(ref.d_bv), d_index(ref.d_index) {}
752
+
753
+ INLINE ap_bit_ref(ref_type* bv, int index = 0) : d_bv(*bv), d_index(index) {}
754
+
755
+ INLINE ap_bit_ref(const ref_type* bv, int index = 0)
756
+ : d_bv(*const_cast<ref_type*>(bv)), d_index(index) {}
757
+
758
+ INLINE operator bool() const { return _AP_ROOT_op_get_bit(d_bv.V, d_index); }
759
+ INLINE bool to_bool() const { return _AP_ROOT_op_get_bit(d_bv.V, d_index); }
760
+
761
+ // assign op from hls supported C integral types.
762
+ // FIXME disabled to support sc_signal<bool>.
763
+ // NOTE this used to be unsigned long long.
764
+ //template <typename T>
765
+ //INLINE typename _ap_type::enable_if<_ap_type::is_integral<T>::value,
766
+ // ap_bit_ref&>::type
767
+ //operator=(T val) {
768
+ // d_bv.V = _AP_ROOT_op_set_bit(d_bv.V, d_index, val);
769
+ // return *this;
770
+ //}
771
+ #define ASSIGN_WITH_CTYPE(_Tp) \
772
+ INLINE ap_bit_ref& operator=(_Tp val) { \
773
+ d_bv.V = _AP_ROOT_op_set_bit(d_bv.V, d_index, val); \
774
+ return *this; \
775
+ }
776
+
777
+ ASSIGN_WITH_CTYPE(bool)
778
+ ASSIGN_WITH_CTYPE(char)
779
+ ASSIGN_WITH_CTYPE(signed char)
780
+ ASSIGN_WITH_CTYPE(unsigned char)
781
+ ASSIGN_WITH_CTYPE(short)
782
+ ASSIGN_WITH_CTYPE(unsigned short)
783
+ ASSIGN_WITH_CTYPE(int)
784
+ ASSIGN_WITH_CTYPE(unsigned int)
785
+ ASSIGN_WITH_CTYPE(long)
786
+ ASSIGN_WITH_CTYPE(unsigned long)
787
+ ASSIGN_WITH_CTYPE(ap_slong)
788
+ ASSIGN_WITH_CTYPE(ap_ulong)
789
+
790
+ #undef ASSIGN_WITH_CTYPE
791
+
792
+ #define ASSIGN_WITH_CTYPE_FP(_Tp) \
793
+ INLINE ap_bit_ref& operator=(_Tp val) { \
794
+ bool tmp_val = val; \
795
+ d_bv.V = _AP_ROOT_op_set_bit(d_bv.V, d_index,tmp_val); \
796
+ return *this; \
797
+ }
798
+
799
+ #if _AP_ENABLE_HALF_ == 1
800
+ ASSIGN_WITH_CTYPE_FP(half)
801
+ #endif
802
+ ASSIGN_WITH_CTYPE_FP(float)
803
+ ASSIGN_WITH_CTYPE_FP(double)
804
+
805
+ #undef ASSIGN_WITH_CTYPE_FP
806
+
807
+
808
+ template <int _AP_W2, bool _AP_S2>
809
+ INLINE ap_bit_ref& operator=(const ap_int_base<_AP_W2, _AP_S2>& val) {
810
+ return operator=((ap_ulong)(val.V != 0));
811
+ }
812
+
813
+ template <int _AP_W2, bool _AP_S2>
814
+ INLINE ap_bit_ref& operator=(const ap_range_ref<_AP_W2, _AP_S2>& val) {
815
+ return operator=((ap_int_base<_AP_W2, false>)val);
816
+ }
817
+
818
+ // Be explicit to prevent it from being deleted, as field d_bv
819
+ // is of reference type.
820
+ INLINE ap_bit_ref& operator=(const ap_bit_ref& val) {
821
+ return operator=((ap_ulong)(bool)val);
822
+ }
823
+
824
+ template <int _AP_W2, bool _AP_S2>
825
+ INLINE ap_bit_ref& operator=(const ap_bit_ref<_AP_W2, _AP_S2>& val) {
826
+ return operator=((ap_ulong)(bool)val);
827
+ }
828
+
829
+ template <int _AP_W2, int _AP_I2, bool _AP_S2, ap_q_mode _AP_Q2,
830
+ ap_o_mode _AP_O2, int _AP_N2>
831
+ INLINE ap_bit_ref& operator=(
832
+ const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& val) {
833
+ return operator=((const ap_int_base<_AP_W2, false>)val);
834
+ }
835
+
836
+ template <int _AP_W2, int _AP_I2, bool _AP_S2, ap_q_mode _AP_Q2,
837
+ ap_o_mode _AP_O2, int _AP_N2>
838
+ INLINE ap_bit_ref& operator=(
839
+ const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>& val) {
840
+ return operator=((ap_ulong)(bool)val);
841
+ }
842
+
843
+ template <int _AP_W2, typename _AP_T2, int _AP_W3, typename _AP_T3>
844
+ INLINE ap_bit_ref& operator=(
845
+ const ap_concat_ref<_AP_W2, _AP_T3, _AP_W3, _AP_T3>& val) {
846
+ return operator=((const ap_int_base<_AP_W2 + _AP_W3, false>)val);
847
+ }
848
+
849
+ template <int _AP_W2, bool _AP_S2>
850
+ INLINE ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_int_base<_AP_W2, _AP_S2> >
851
+ operator,(ap_int_base<_AP_W2, _AP_S2> &a2) {
852
+ return ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_int_base<_AP_W2, _AP_S2> >(
853
+ *this, a2);
854
+ }
855
+
856
+ template <int _AP_W2, bool _AP_S2>
857
+ INLINE ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_int_base<_AP_W2, _AP_S2> >
858
+ operator,(volatile ap_int_base<_AP_W2, _AP_S2> &a2) {
859
+ return ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_int_base<_AP_W2, _AP_S2> >(
860
+ *this, const_cast<ap_int_base<_AP_W2, _AP_S2>&>(a2));
861
+ }
862
+
863
+ template <int _AP_W2, bool _AP_S2>
864
+ INLINE ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_int_base<_AP_W2, _AP_S2> >
865
+ operator,(const ap_int_base<_AP_W2, _AP_S2> &a2) {
866
+ ap_int_base<_AP_W2, _AP_S2> op(a2);
867
+ return ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_int_base<_AP_W2, _AP_S2> >(
868
+ *this, const_cast<ap_int_base<_AP_W2, _AP_S2>&>(op));
869
+ }
870
+
871
+ template <int _AP_W2, bool _AP_S2>
872
+ INLINE ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_int_base<_AP_W2, _AP_S2> >
873
+ operator,(const volatile ap_int_base<_AP_W2, _AP_S2> &a2) {
874
+ ap_int_base<_AP_W2, _AP_S2> op(a2);
875
+ return ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_int_base<_AP_W2, _AP_S2> >(
876
+ *this, const_cast<ap_int_base<_AP_W2, _AP_S2>&>(op));
877
+ }
878
+
879
+ template <int _AP_W2, bool _AP_S2>
880
+ INLINE ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> >
881
+ operator,(const ap_range_ref<_AP_W2, _AP_S2> &a2) {
882
+ return ap_concat_ref<1, ap_bit_ref, _AP_W2, ap_range_ref<_AP_W2, _AP_S2> >(
883
+ *this, const_cast<ap_range_ref<_AP_W2, _AP_S2>&>(a2));
884
+ }
885
+
886
+ template <int _AP_W2, bool _AP_S2>
887
+ INLINE ap_concat_ref<1, ap_bit_ref, 1, ap_bit_ref<_AP_W2, _AP_S2> > operator,(
888
+ const ap_bit_ref<_AP_W2, _AP_S2> &a2) {
889
+ return ap_concat_ref<1, ap_bit_ref, 1, ap_bit_ref<_AP_W2, _AP_S2> >(
890
+ *this, const_cast<ap_bit_ref<_AP_W2, _AP_S2>&>(a2));
891
+ }
892
+
893
+ template <int _AP_W2, typename _AP_T2, int _AP_W3, typename _AP_T3>
894
+ INLINE ap_concat_ref<1, ap_bit_ref, _AP_W2 + _AP_W3,
895
+ ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >
896
+ operator,(const ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> &a2) {
897
+ return ap_concat_ref<1, ap_bit_ref, _AP_W2 + _AP_W3,
898
+ ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3> >(
899
+ *this, const_cast<ap_concat_ref<_AP_W2, _AP_T2, _AP_W3, _AP_T3>&>(a2));
900
+ }
901
+
902
+ template <int _AP_W2, int _AP_I2, bool _AP_S2, ap_q_mode _AP_Q2,
903
+ ap_o_mode _AP_O2, int _AP_N2>
904
+ INLINE ap_concat_ref<
905
+ 1, ap_bit_ref, _AP_W2,
906
+ af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >
907
+ operator,(
908
+ const af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> &a2) {
909
+ return ap_concat_ref<
910
+ 1, ap_bit_ref, _AP_W2,
911
+ af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> >(
912
+ *this,
913
+ const_cast<
914
+ af_range_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>&>(a2));
915
+ }
916
+
917
+ template <int _AP_W2, int _AP_I2, bool _AP_S2, ap_q_mode _AP_Q2,
918
+ ap_o_mode _AP_O2, int _AP_N2>
919
+ INLINE ap_concat_ref<1, ap_bit_ref, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2,
920
+ _AP_Q2, _AP_O2, _AP_N2> >
921
+ operator,(
922
+ const af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2> &a2) {
923
+ return ap_concat_ref<1, ap_bit_ref, 1, af_bit_ref<_AP_W2, _AP_I2, _AP_S2,
924
+ _AP_Q2, _AP_O2, _AP_N2> >(
925
+ *this,
926
+ const_cast<af_bit_ref<_AP_W2, _AP_I2, _AP_S2, _AP_Q2, _AP_O2, _AP_N2>&>(
927
+ a2));
928
+ }
929
+
930
+ template <int _AP_W2, bool _AP_S2>
931
+ INLINE bool operator==(const ap_bit_ref<_AP_W2, _AP_S2>& op) {
932
+ return get() == op.get();
933
+ }
934
+
935
+ template <int _AP_W2, bool _AP_S2>
936
+ INLINE bool operator!=(const ap_bit_ref<_AP_W2, _AP_S2>& op) {
937
+ return get() != op.get();
938
+ }
939
+
940
+ INLINE bool get() const { return _AP_ROOT_op_get_bit(d_bv.V, d_index); }
941
+
942
+ INLINE bool get() { return _AP_ROOT_op_get_bit(d_bv.V, d_index); }
943
+
944
+ template <int _AP_W3>
945
+ INLINE void set(const ap_int_base<_AP_W3, false>& val) {
946
+ operator=(val);
947
+ }
948
+
949
+ INLINE bool operator~() const {
950
+ bool bit = _AP_ROOT_op_get_bit(d_bv.V, d_index);
951
+ return bit ? false : true;
952
+ }
953
+
954
+ INLINE int length() const { return 1; }
955
+
956
+ #ifndef __SYNTHESIS__
957
+ std::string to_string() const { return get() ? "1" : "0"; }
958
+ #else
959
+ // XXX HLS will delete this in synthesis
960
+ INLINE char* to_string() const { return 0; }
961
+ #endif
962
+ }; // struct ap_bit_ref
963
+
964
+ /* ap_range_ref with int.
965
+ * ------------------------------------------------------------
966
+ */
967
+ // equality and relational operators.
968
+ #define REF_REL_OP_WITH_INT(REL_OP, C_TYPE, _AP_W2, _AP_S2) \
969
+ template <int _AP_W, bool _AP_S> \
970
+ INLINE bool operator REL_OP(const ap_range_ref<_AP_W, _AP_S>& op, \
971
+ C_TYPE op2) { \
972
+ return ap_int_base<_AP_W, false>(op) \
973
+ REL_OP ap_int_base<_AP_W2, _AP_S2>(op2); \
974
+ } \
975
+ template <int _AP_W, bool _AP_S> \
976
+ INLINE bool operator REL_OP(const ap_bit_ref<_AP_W, _AP_S>& op, \
977
+ C_TYPE op2) { \
978
+ return bool(op) REL_OP op2; \
979
+ } \
980
+ template <int _AP_W, bool _AP_S> \
981
+ INLINE bool operator REL_OP(C_TYPE op2, \
982
+ const ap_bit_ref<_AP_W, _AP_S>& op) { \
983
+ return op2 REL_OP bool(op); \
984
+ } \
985
+ template <int _AP_W, typename _AP_T, int _AP_W1, typename _AP_T1> \
986
+ INLINE bool operator REL_OP( \
987
+ const ap_concat_ref<_AP_W, _AP_T, _AP_W1, _AP_T1>& op, C_TYPE op2) { \
988
+ return ap_int_base<_AP_W + _AP_W1, false>(op) \
989
+ REL_OP ap_int_base<_AP_W2, _AP_S2>(op2); \
990
+ }
991
+
992
+ // Make the line shorter than 5000 chars
993
+ #define REF_REL_WITH_INT_1(C_TYPE, _AP_WI, _AP_SI) \
994
+ REF_REL_OP_WITH_INT(>, C_TYPE, _AP_WI, _AP_SI) \
995
+ REF_REL_OP_WITH_INT(<, C_TYPE, _AP_WI, _AP_SI) \
996
+ REF_REL_OP_WITH_INT(>=, C_TYPE, _AP_WI, _AP_SI) \
997
+ REF_REL_OP_WITH_INT(<=, C_TYPE, _AP_WI, _AP_SI)
998
+
999
+ REF_REL_WITH_INT_1(bool, 1, false)
1000
+ REF_REL_WITH_INT_1(char, 8, CHAR_IS_SIGNED)
1001
+ REF_REL_WITH_INT_1(signed char, 8, true)
1002
+ REF_REL_WITH_INT_1(unsigned char, 8, false)
1003
+ REF_REL_WITH_INT_1(short, _AP_SIZE_short, true)
1004
+ REF_REL_WITH_INT_1(unsigned short, _AP_SIZE_short, false)
1005
+ REF_REL_WITH_INT_1(int, _AP_SIZE_int, true)
1006
+ REF_REL_WITH_INT_1(unsigned int, _AP_SIZE_int, false)
1007
+ REF_REL_WITH_INT_1(long, _AP_SIZE_long, true)
1008
+ REF_REL_WITH_INT_1(unsigned long, _AP_SIZE_long, false)
1009
+ REF_REL_WITH_INT_1(ap_slong, _AP_SIZE_ap_slong, true)
1010
+ REF_REL_WITH_INT_1(ap_ulong, _AP_SIZE_ap_slong, false)
1011
+
1012
+ // Make the line shorter than 5000 chars
1013
+ #define REF_REL_WITH_INT_2(C_TYPE, _AP_WI, _AP_SI) \
1014
+ REF_REL_OP_WITH_INT(==, C_TYPE, _AP_WI, _AP_SI) \
1015
+ REF_REL_OP_WITH_INT(!=, C_TYPE, _AP_WI, _AP_SI)
1016
+
1017
+ REF_REL_WITH_INT_2(bool, 1, false)
1018
+ REF_REL_WITH_INT_2(char, 8, CHAR_IS_SIGNED)
1019
+ REF_REL_WITH_INT_2(signed char, 8, true)
1020
+ REF_REL_WITH_INT_2(unsigned char, 8, false)
1021
+ REF_REL_WITH_INT_2(short, _AP_SIZE_short, true)
1022
+ REF_REL_WITH_INT_2(unsigned short, _AP_SIZE_short, false)
1023
+ REF_REL_WITH_INT_2(int, _AP_SIZE_int, true)
1024
+ REF_REL_WITH_INT_2(unsigned int, _AP_SIZE_int, false)
1025
+ REF_REL_WITH_INT_2(long, _AP_SIZE_long, true)
1026
+ REF_REL_WITH_INT_2(unsigned long, _AP_SIZE_long, false)
1027
+ REF_REL_WITH_INT_2(ap_slong, _AP_SIZE_ap_slong, true)
1028
+ REF_REL_WITH_INT_2(ap_ulong, _AP_SIZE_ap_slong, false)
1029
+
1030
+ #undef REF_REL_OP_WITH_INT
1031
+ #undef REF_REL_WITH_INT_1
1032
+ #undef REF_REL_WITH_INT_2
1033
+
1034
+ #define REF_BIN_OP_WITH_INT(BIN_OP, RTYPE, C_TYPE, _AP_W2, _AP_S2) \
1035
+ template <int _AP_W, bool _AP_S> \
1036
+ INLINE typename ap_int_base<_AP_W, false>::template RType<_AP_W2, \
1037
+ _AP_S2>::RTYPE \
1038
+ operator BIN_OP(const ap_range_ref<_AP_W, _AP_S>& op, C_TYPE op2) { \
1039
+ return ap_int_base<_AP_W, false>(op) \
1040
+ BIN_OP ap_int_base<_AP_W2, _AP_S2>(op2); \
1041
+ } \
1042
+ template <int _AP_W, bool _AP_S> \
1043
+ INLINE typename ap_int_base<_AP_W2, _AP_S2>::template RType<_AP_W, \
1044
+ false>::RTYPE \
1045
+ operator BIN_OP(C_TYPE op2, const ap_range_ref<_AP_W, _AP_S>& op) { \
1046
+ return ap_int_base<_AP_W2, _AP_S2>(op2) \
1047
+ BIN_OP ap_int_base<_AP_W, false>(op); \
1048
+ }
1049
+
1050
+ // arithmetic operators.
1051
+ #define REF_BIN_OP_WITH_INT_ARITH(C_TYPE, _AP_W2, _AP_S2) \
1052
+ REF_BIN_OP_WITH_INT(+, plus, C_TYPE, (_AP_W2), (_AP_S2)) \
1053
+ REF_BIN_OP_WITH_INT(-, minus, C_TYPE, (_AP_W2), (_AP_S2)) \
1054
+ REF_BIN_OP_WITH_INT(*, mult, C_TYPE, (_AP_W2), (_AP_S2)) \
1055
+ REF_BIN_OP_WITH_INT(/, div, C_TYPE, (_AP_W2), (_AP_S2)) \
1056
+ REF_BIN_OP_WITH_INT(%, mod, C_TYPE, (_AP_W2), (_AP_S2))
1057
+
1058
+ REF_BIN_OP_WITH_INT_ARITH(bool, 1, false)
1059
+ REF_BIN_OP_WITH_INT_ARITH(char, 8, CHAR_IS_SIGNED)
1060
+ REF_BIN_OP_WITH_INT_ARITH(signed char, 8, true)
1061
+ REF_BIN_OP_WITH_INT_ARITH(unsigned char, 8, false)
1062
+ REF_BIN_OP_WITH_INT_ARITH(short, _AP_SIZE_short, true)
1063
+ REF_BIN_OP_WITH_INT_ARITH(unsigned short, _AP_SIZE_short, false)
1064
+ REF_BIN_OP_WITH_INT_ARITH(int, _AP_SIZE_int, true)
1065
+ REF_BIN_OP_WITH_INT_ARITH(unsigned int, _AP_SIZE_int, false)
1066
+ REF_BIN_OP_WITH_INT_ARITH(long, _AP_SIZE_long, true)
1067
+ REF_BIN_OP_WITH_INT_ARITH(unsigned long, _AP_SIZE_long, false)
1068
+ REF_BIN_OP_WITH_INT_ARITH(ap_slong, _AP_SIZE_ap_slong, true)
1069
+ REF_BIN_OP_WITH_INT_ARITH(ap_ulong, _AP_SIZE_ap_slong, false)
1070
+
1071
+ #undef REF_BIN_OP_WITH_INT_ARITH
1072
+
1073
+ // bitwise and shift operators
1074
+ #define REF_BIN_OP_WITH_INT_BITS(C_TYPE, _AP_W2, _AP_S2) \
1075
+ REF_BIN_OP_WITH_INT(&, logic, C_TYPE, (_AP_W2), (_AP_S2)) \
1076
+ REF_BIN_OP_WITH_INT(|, logic, C_TYPE, (_AP_W2), (_AP_S2)) \
1077
+ REF_BIN_OP_WITH_INT(^, logic, C_TYPE, (_AP_W2), (_AP_S2)) \
1078
+ REF_BIN_OP_WITH_INT(>>, arg1, C_TYPE, (_AP_W2), (_AP_S2)) \
1079
+ REF_BIN_OP_WITH_INT(<<, arg1, C_TYPE, (_AP_W2), (_AP_S2))
1080
+
1081
+ REF_BIN_OP_WITH_INT_BITS(bool, 1, false)
1082
+ REF_BIN_OP_WITH_INT_BITS(char, 8, CHAR_IS_SIGNED)
1083
+ REF_BIN_OP_WITH_INT_BITS(signed char, 8, true)
1084
+ REF_BIN_OP_WITH_INT_BITS(unsigned char, 8, false)
1085
+ REF_BIN_OP_WITH_INT_BITS(short, _AP_SIZE_short, true)
1086
+ REF_BIN_OP_WITH_INT_BITS(unsigned short, _AP_SIZE_short, false)
1087
+ REF_BIN_OP_WITH_INT_BITS(int, _AP_SIZE_int, true)
1088
+ REF_BIN_OP_WITH_INT_BITS(unsigned int, _AP_SIZE_int, false)
1089
+ REF_BIN_OP_WITH_INT_BITS(long, _AP_SIZE_long, true)
1090
+ REF_BIN_OP_WITH_INT_BITS(unsigned long, _AP_SIZE_long, false)
1091
+ REF_BIN_OP_WITH_INT_BITS(ap_slong, _AP_SIZE_ap_slong, true)
1092
+ REF_BIN_OP_WITH_INT_BITS(ap_ulong, _AP_SIZE_ap_slong, false)
1093
+
1094
+ #undef REF_BIN_OP_WITH_INT_BITS
1095
+
1096
+ /* ap_range_ref with ap_range_ref
1097
+ * ------------------------------------------------------------
1098
+ */
1099
+ #define REF_BIN_OP(BIN_OP, RTYPE) \
1100
+ template <int _AP_W, bool _AP_S, int _AP_W2, bool _AP_S2> \
1101
+ INLINE \
1102
+ typename ap_int_base<_AP_W, false>::template RType<_AP_W2, false>::RTYPE \
1103
+ operator BIN_OP(const ap_range_ref<_AP_W, _AP_S>& lhs, \
1104
+ const ap_range_ref<_AP_W2, _AP_S2>& rhs) { \
1105
+ return (lhs.operator ap_int_base<_AP_W, false>())BIN_OP( \
1106
+ rhs.operator ap_int_base<_AP_W2, false>()); \
1107
+ }
1108
+
1109
+ REF_BIN_OP(+, plus)
1110
+ REF_BIN_OP(-, minus)
1111
+ REF_BIN_OP(*, mult)
1112
+ REF_BIN_OP(/, div)
1113
+ REF_BIN_OP(%, mod)
1114
+ REF_BIN_OP(&, logic)
1115
+ REF_BIN_OP(|, logic)
1116
+ REF_BIN_OP(^, logic)
1117
+ REF_BIN_OP(>>, arg1)
1118
+ REF_BIN_OP(<<, arg1)
1119
+
1120
+ /* ap_concat_ref with ap_concat_ref.
1121
+ * ------------------------------------------------------------
1122
+ */
1123
+
1124
+ //************************************************************************
1125
+ // Implement
1126
+ // ap_int_base<M+N> = ap_concat_ref<M> OP ap_concat_ref<N>
1127
+ // for operators +, -, *, /, %, >>, <<, &, |, ^
1128
+ // Without these operators the operands are converted to int64 and
1129
+ // larger results lose informations (higher order bits).
1130
+ //
1131
+ // operand OP
1132
+ // / |
1133
+ // left-concat right-concat
1134
+ // / | / |
1135
+ // <LW1,LT1> <LW2,LT2> <RW1,RT1> <RW2,RT2>
1136
+ //
1137
+ // _AP_LW1, _AP_LT1 (width and type of left-concat's left side)
1138
+ // _AP_LW2, _AP_LT2 (width and type of left-concat's right side)
1139
+ // Similarly for RHS of operand OP: _AP_RW1, AP_RW2, _AP_RT1, _AP_RT2
1140
+ //
1141
+ // In Verilog 2001 result of concatenation is always unsigned even
1142
+ // when both sides are signed.
1143
+ //************************************************************************
1144
+
1145
+ #undef SYN_CONCAT_REF_BIN_OP
1146
+
1147
+ #define SYN_CONCAT_REF_BIN_OP(BIN_OP, RTYPE) \
1148
+ template <int _AP_LW1, typename _AP_LT1, int _AP_LW2, typename _AP_LT2, \
1149
+ int _AP_RW1, typename _AP_RT1, int _AP_RW2, typename _AP_RT2> \
1150
+ INLINE typename ap_int_base<_AP_LW1 + _AP_LW2, false>::template RType< \
1151
+ _AP_RW1 + _AP_RW2, false>::RTYPE \
1152
+ operator BIN_OP( \
1153
+ const ap_concat_ref<_AP_LW1, _AP_LT1, _AP_LW2, _AP_LT2>& lhs, \
1154
+ const ap_concat_ref<_AP_RW1, _AP_RT1, _AP_RW2, _AP_RT2>& rhs) { \
1155
+ return lhs.get() BIN_OP rhs.get(); \
1156
+ }
1157
+
1158
+ SYN_CONCAT_REF_BIN_OP(+, plus)
1159
+ SYN_CONCAT_REF_BIN_OP(-, minus)
1160
+ SYN_CONCAT_REF_BIN_OP(*, mult)
1161
+ SYN_CONCAT_REF_BIN_OP(/, div)
1162
+ SYN_CONCAT_REF_BIN_OP(%, mod)
1163
+ SYN_CONCAT_REF_BIN_OP(&, logic)
1164
+ SYN_CONCAT_REF_BIN_OP(|, logic)
1165
+ SYN_CONCAT_REF_BIN_OP(^, logic)
1166
+ SYN_CONCAT_REF_BIN_OP(>>, arg1)
1167
+ SYN_CONCAT_REF_BIN_OP(<<, arg1)
1168
+
1169
+ #undef SYN_CONCAT_REF_BIN_OP
1170
+
1171
+ #define CONCAT_OP_WITH_INT(C_TYPE, _AP_WI, _AP_SI) \
1172
+ template <int _AP_W, bool _AP_S> \
1173
+ INLINE ap_int_base<_AP_W + _AP_WI, false> operator,( \
1174
+ const ap_int_base<_AP_W, _AP_S> &op1, C_TYPE op2) { \
1175
+ ap_int_base<_AP_WI + _AP_W, false> val(op2); \
1176
+ ap_int_base<_AP_WI + _AP_W, false> ret(op1); \
1177
+ ret <<= _AP_WI; \
1178
+ if (_AP_SI) { \
1179
+ val <<= _AP_W; \
1180
+ val >>= _AP_W; \
1181
+ } \
1182
+ ret |= val; \
1183
+ return ret; \
1184
+ } \
1185
+ template <int _AP_W, bool _AP_S> \
1186
+ INLINE ap_int_base<_AP_W + _AP_WI, false> operator,( \
1187
+ C_TYPE op1, const ap_int_base<_AP_W, _AP_S> &op2) { \
1188
+ ap_int_base<_AP_WI + _AP_W, false> val(op1); \
1189
+ ap_int_base<_AP_WI + _AP_W, false> ret(op2); \
1190
+ if (_AP_S) { \
1191
+ ret <<= _AP_WI; \
1192
+ ret >>= _AP_WI; \
1193
+ } \
1194
+ ret |= val << _AP_W; \
1195
+ return ret; \
1196
+ } \
1197
+ template <int _AP_W, bool _AP_S> \
1198
+ INLINE ap_int_base<_AP_W + _AP_WI, false> operator,( \
1199
+ const ap_range_ref<_AP_W, _AP_S> &op1, C_TYPE op2) { \
1200
+ ap_int_base<_AP_WI + _AP_W, false> val(op2); \
1201
+ ap_int_base<_AP_WI + _AP_W, false> ret(op1); \
1202
+ ret <<= _AP_WI; \
1203
+ if (_AP_SI) { \
1204
+ val <<= _AP_W; \
1205
+ val >>= _AP_W; \
1206
+ } \
1207
+ ret |= val; \
1208
+ return ret; \
1209
+ } \
1210
+ template <int _AP_W, bool _AP_S> \
1211
+ INLINE ap_int_base<_AP_W + _AP_WI, false> operator,( \
1212
+ C_TYPE op1, const ap_range_ref<_AP_W, _AP_S> &op2) { \
1213
+ ap_int_base<_AP_WI + _AP_W, false> val(op1); \
1214
+ ap_int_base<_AP_WI + _AP_W, false> ret(op2); \
1215
+ int len = op2.length(); \
1216
+ val <<= len; \
1217
+ ret |= val; \
1218
+ return ret; \
1219
+ } \
1220
+ template <int _AP_W, bool _AP_S> \
1221
+ INLINE ap_int_base<_AP_WI + 1, false> operator,( \
1222
+ const ap_bit_ref<_AP_W, _AP_S> &op1, C_TYPE op2) { \
1223
+ ap_int_base<_AP_WI + 1, false> val(op2); \
1224
+ val[_AP_WI] = op1; \
1225
+ return val; \
1226
+ } \
1227
+ template <int _AP_W, bool _AP_S> \
1228
+ INLINE ap_int_base<_AP_WI + 1, false> operator,( \
1229
+ C_TYPE op1, const ap_bit_ref<_AP_W, _AP_S> &op2) { \
1230
+ ap_int_base<_AP_WI + 1, false> val(op1); \
1231
+ val <<= 1; \
1232
+ val[0] = op2; \
1233
+ return val; \
1234
+ } \
1235
+ template <int _AP_W, typename _AP_T, int _AP_W2, typename _AP_T2> \
1236
+ INLINE ap_int_base<_AP_W + _AP_W2 + _AP_WI, false> operator,( \
1237
+ const ap_concat_ref<_AP_W, _AP_T, _AP_W2, _AP_T2> &op1, C_TYPE op2) { \
1238
+ ap_int_base<_AP_WI + _AP_W + _AP_W2, _AP_SI> val(op2); \
1239
+ ap_int_base<_AP_WI + _AP_W + _AP_W2, _AP_SI> ret(op1); \
1240
+ if (_AP_SI) { \
1241
+ val <<= _AP_W + _AP_W2; \
1242
+ val >>= _AP_W + _AP_W2; \
1243
+ } \
1244
+ ret <<= _AP_WI; \
1245
+ ret |= val; \
1246
+ return ret; \
1247
+ } \
1248
+ template <int _AP_W, typename _AP_T, int _AP_W2, typename _AP_T2> \
1249
+ INLINE ap_int_base<_AP_W + _AP_W2 + _AP_WI, false> operator,( \
1250
+ C_TYPE op1, const ap_concat_ref<_AP_W, _AP_T, _AP_W2, _AP_T2> &op2) { \
1251
+ ap_int_base<_AP_WI + _AP_W + _AP_W2, _AP_SI> val(op1); \
1252
+ ap_int_base<_AP_WI + _AP_W + _AP_W2, _AP_SI> ret(op2); \
1253
+ int len = op2.length(); \
1254
+ val <<= len; \
1255
+ ret |= val; \
1256
+ return ret; \
1257
+ } \
1258
+ template <int _AP_W, int _AP_I, bool _AP_S, ap_q_mode _AP_Q, \
1259
+ ap_o_mode _AP_O, int _AP_N> \
1260
+ INLINE ap_int_base<_AP_W + _AP_WI, false> operator,( \
1261
+ const af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op1, \
1262
+ C_TYPE op2) { \
1263
+ ap_int_base<_AP_WI + _AP_W, false> val(op2); \
1264
+ ap_int_base<_AP_WI + _AP_W, false> ret(op1); \
1265
+ if (_AP_SI) { \
1266
+ val <<= _AP_W; \
1267
+ val >>= _AP_W; \
1268
+ } \
1269
+ ret <<= _AP_WI; \
1270
+ ret |= val; \
1271
+ return ret; \
1272
+ } \
1273
+ template <int _AP_W, int _AP_I, bool _AP_S, ap_q_mode _AP_Q, \
1274
+ ap_o_mode _AP_O, int _AP_N> \
1275
+ INLINE ap_int_base<_AP_W + _AP_WI, false> operator,( \
1276
+ C_TYPE op1, \
1277
+ const af_range_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op2) { \
1278
+ ap_int_base<_AP_WI + _AP_W, false> val(op1); \
1279
+ ap_int_base<_AP_WI + _AP_W, false> ret(op2); \
1280
+ int len = op2.length(); \
1281
+ val <<= len; \
1282
+ ret |= val; \
1283
+ return ret; \
1284
+ } \
1285
+ template <int _AP_W, int _AP_I, bool _AP_S, ap_q_mode _AP_Q, \
1286
+ ap_o_mode _AP_O, int _AP_N> \
1287
+ INLINE ap_int_base<1 + _AP_WI, false> operator,( \
1288
+ const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op1, \
1289
+ C_TYPE op2) { \
1290
+ ap_int_base<_AP_WI + 1, _AP_SI> val(op2); \
1291
+ val[_AP_WI] = op1; \
1292
+ return val; \
1293
+ } \
1294
+ template <int _AP_W, int _AP_I, bool _AP_S, ap_q_mode _AP_Q, \
1295
+ ap_o_mode _AP_O, int _AP_N> \
1296
+ INLINE ap_int_base<1 + _AP_WI, false> operator,( \
1297
+ C_TYPE op1, \
1298
+ const af_bit_ref<_AP_W, _AP_I, _AP_S, _AP_Q, _AP_O, _AP_N> &op2) { \
1299
+ ap_int_base<_AP_WI + 1, _AP_SI> val(op1); \
1300
+ val <<= 1; \
1301
+ val[0] = op2; \
1302
+ return val; \
1303
+ }
1304
+
1305
+ CONCAT_OP_WITH_INT(bool, 1, false)
1306
+ CONCAT_OP_WITH_INT(char, 8, CHAR_IS_SIGNED)
1307
+ CONCAT_OP_WITH_INT(signed char, 8, true)
1308
+ CONCAT_OP_WITH_INT(unsigned char, 8, false)
1309
+ CONCAT_OP_WITH_INT(short, _AP_SIZE_short, true)
1310
+ CONCAT_OP_WITH_INT(unsigned short, _AP_SIZE_short, false)
1311
+ CONCAT_OP_WITH_INT(int, _AP_SIZE_int, true)
1312
+ CONCAT_OP_WITH_INT(unsigned int, _AP_SIZE_int, false)
1313
+ CONCAT_OP_WITH_INT(long, _AP_SIZE_long, true)
1314
+ CONCAT_OP_WITH_INT(unsigned long, _AP_SIZE_long, false)
1315
+ CONCAT_OP_WITH_INT(ap_slong, _AP_SIZE_ap_slong, true)
1316
+ CONCAT_OP_WITH_INT(ap_ulong, _AP_SIZE_ap_slong, false)
1317
+
1318
+ #undef CONCAT_OP_WITH_INT
1319
+
1320
+ #define CONCAT_SHIFT_WITH_INT(C_TYPE, OP) \
1321
+ template <int _AP_W, typename _AP_T, int _AP_W1, typename _AP_T1> \
1322
+ INLINE ap_uint<_AP_W + _AP_W1> operator OP( \
1323
+ const ap_concat_ref<_AP_W, _AP_T, _AP_W1, _AP_T1> lhs, C_TYPE rhs) { \
1324
+ return ap_uint<_AP_W + _AP_W1>(lhs).get() OP int(rhs); \
1325
+ }
1326
+
1327
+ // FIXME int(rhs) may loose precision.
1328
+
1329
+ CONCAT_SHIFT_WITH_INT(int, <<)
1330
+ CONCAT_SHIFT_WITH_INT(unsigned int, <<)
1331
+ CONCAT_SHIFT_WITH_INT(long, <<)
1332
+ CONCAT_SHIFT_WITH_INT(unsigned long, <<)
1333
+ CONCAT_SHIFT_WITH_INT(ap_slong, <<)
1334
+ CONCAT_SHIFT_WITH_INT(ap_ulong, <<)
1335
+
1336
+ CONCAT_SHIFT_WITH_INT(int, >>)
1337
+ CONCAT_SHIFT_WITH_INT(unsigned int, >>)
1338
+ CONCAT_SHIFT_WITH_INT(long, >>)
1339
+ CONCAT_SHIFT_WITH_INT(unsigned long, >>)
1340
+ CONCAT_SHIFT_WITH_INT(ap_slong, >>)
1341
+ CONCAT_SHIFT_WITH_INT(ap_ulong, >>)
1342
+
1343
+ #endif // ifndef __cplusplus
1344
+ #endif // ifndef __AP_INT_REF_H__
1345
+
1346
+ // -*- cpp -*-