MatchLib
nvhls_vector.h
1 /*
2  * Copyright (c) 2016-2019, NVIDIA CORPORATION. All rights reserved.
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 #ifndef NVHLS_VECTOR_H
17 #define NVHLS_VECTOR_H
18 
19 #include <systemc.h>
20 #include <nvhls_int.h>
21 #include <nvhls_types.h>
22 #include <hls_globals.h>
23 #include <nvhls_array.h>
24 #include <ccs_p2p.h>
25 #include <nvhls_assert.h>
26 #include <nvhls_message.h>
27 
28 namespace nvhls {
29 
30 inline std::string synth_to_string(const unsigned int& n) {
31 #ifndef __SYNTHESIS__
32  std::ostringstream stm;
33  stm << n;
34  return stm.str();
35 #else
36  return "DUMMY";
37 #endif
38 }
39 
40 // SystemC vector class
41 // TYPE can be one of the SystemC types - sc_int, sc_uint, sc_bigint, sc_biguint
42 // or AC type ac_int
43 // TYPE cannot be nv_scvector i.e. we cannot have vector of vectors .. Need to
44 // add operators for vectors
76 template <typename Type, unsigned int VectorLength>
77 class nv_scvector : public nvhls_message {
78  public:
79  Type data[VectorLength];
80  typedef Type type;
81  static const unsigned int type_width = Wrapped<Type>::width;
82  static const unsigned int length = VectorLength;
83  static const unsigned int width = type_width * VectorLength;
84  static const bool is_signed = Wrapped<Type>::is_signed;
85 
86  nv_scvector() {
87  }
89 #pragma hls_unroll yes
90  for (unsigned i = 0; i < VectorLength; i++)
91  data[i] = that.data[i];
92  }
93  nv_scvector(const Type newdata[VectorLength]) {
94 #pragma hls_unroll yes
95  for (unsigned i = 0; i < VectorLength; i++)
96  data[i] = newdata[i];
97  }
98  // Constructing vector from rawbits of NVUINT type
99  nv_scvector(const NVUINTW(width) & rawbits) {
100 #pragma hls_unroll yes
101  for (unsigned int i = 0; i < VectorLength; i++) {
102  data[i] = nvhls::get_slc<type_width>(rawbits, i * type_width);
103  }
104  }
105  nv_scvector(const int& rawbits) {
106  const NVUINTW(width) & rawbits_local = rawbits;
107 #pragma hls_unroll yes
108  for (unsigned int i = 0; i < VectorLength; i++) {
109  data[i] = nvhls::get_slc<type_width>(rawbits_local, i * type_width);
110  }
111  }
113  const nv_scvector<Type, VectorLength>& that) {
114 #pragma hls_unroll yes
115  for (unsigned i = 0; i < VectorLength; i++)
116  data[i] = that.data[i];
117  return *this;
118  }
119 
120  inline void copy(nv_scvector<Type, VectorLength>& out) {
121 #pragma hls_unroll yes
122  for (unsigned i = 0; i < VectorLength; i++)
123  out.data[i] = data[i];
124  }
125  Type& operator[](unsigned int i) {
126  return this->data[i];
127  }
128  const Type& operator[](unsigned int i) const {
129  return this->data[i];
130  }
131  // Converting vector to rawbits of NVUINT type
132  NVUINTW(width) to_rawbits() {
133  NVUINTW(width) rawbits = 0;
134 #pragma hls_unroll yes
135  for (unsigned int i = 0; i < VectorLength; i++) {
136  rawbits = nvhls::set_slc(rawbits, data[i], i * type_width);
137  }
138  return rawbits;
139  }
140  // Converting rawbits to vector
141  void to_vector(NVUINTW(width) rawbits) {
142 #pragma hls_unroll yes
143  for (unsigned int i = 0; i < VectorLength; i++) {
144  data[i] = nvhls::get_slc<type_width>(rawbits, i * type_width);
145  }
146  }
147 
148  template <unsigned int Size>
149  void Marshall(Marshaller<Size>& m) {
150  #pragma hls_unroll yes
151  for (unsigned int i = 0; i < VectorLength; i++) {
152  m& data[i];
153  }
154  }
155 };
156 
157 template <typename Type, unsigned int VectorLength>
158 inline bool operator==(
160  const nv_scvector<Type, VectorLength>& rhs) {
161  bool is_equal = true;
162 #pragma hls_unroll yes
163  for (unsigned i = 0; i < VectorLength; i++)
164  is_equal &= (lhs.data[i] == rhs.data[i]);
165  return is_equal;
166  }
167 
168 template <typename Type, unsigned int VectorLength>
169 inline std::ostream& operator<<(std::ostream& os,
170  const nv_scvector<Type, VectorLength>& vec) {
171  for (unsigned i = 0; i < VectorLength; i++) {
172  os << vec.data[i] << " ";
173  }
174  return os;
175 }
176 
208 template <typename InType1, typename InType2, typename OutType,
209  unsigned int VectorLength, bool Unroll>
213 
214  if (Unroll == true) {
215 #pragma hls_unroll yes
216  for (unsigned i = 0; i < VectorLength; i++)
217  out[i] = in1[i] * in2[i];
218  } else {
219  for (unsigned i = 0; i < VectorLength; i++)
220  out[i] = in1[i] * in2[i];
221  }
222 }
223 
224 
256 template <typename InType1, typename InType2, typename OutType,
257  unsigned int VectorLength, bool Unroll>
261  if (Unroll == true) {
262 #pragma hls_unroll yes
263  for (unsigned i = 0; i < VectorLength; i++)
264  out[i] = in1[i] + in2[i];
265  } else {
266  for (unsigned i = 0; i < VectorLength; i++)
267  out[i] = in1[i] + in2[i];
268  }
269 }
270 
271 
302 template <typename InType1, typename InType2, typename OutType,
303  unsigned int VectorLength, bool Unroll>
307  if (Unroll == true) {
308 #pragma hls_unroll yes
309  for (unsigned i = 0; i < VectorLength; i++)
310  out[i] = in1[i] - in2[i];
311  } else {
312  for (unsigned i = 0; i < VectorLength; i++)
313  out[i] = in1[i] - in2[i];
314  }
315 }
316 
317 
348 template <typename InType, typename OutType, unsigned int VectorLength,
349  bool UseReduceTree>
351  OutType sum = 0;
352 
353  if (VectorLength > 1) {
354  if (UseReduceTree == true) {
355 #pragma hls_unroll yes
356 #pragma cluster addtree
357 #pragma cluster_type both
358  for (unsigned i = 0; i < VectorLength; i++)
359  sum += in[i];
360  } else {
361  for (unsigned i = 0; i < VectorLength; i++)
362  sum += in[i];
363  }
364  } else {
365  sum = in[0];
366  }
367  out = sum;
368 }
369 
370 
404 template <typename InType1, typename InType2, typename OutType,
405  unsigned int VectorLength, bool UseReduceTree>
407  nv_scvector<InType2, VectorLength> in2, OutType& out) {
408  OutType sum = 0;
409  if (VectorLength > 1) {
410  if (UseReduceTree == true) {
411 #pragma hls_unroll yes
412 #pragma cluster multadd addtree
413 #pragma cluster_type both
414  for (unsigned i = 0; i < VectorLength; i++)
415  sum += in1[i] * in2[i];
416  } else {
417  for (unsigned i = 0; i < VectorLength; i++)
418  sum += in1[i] * in2[i];
419  }
420  } else {
421  sum = in1[0] * in2[0];
422  }
423 
424  out = sum;
425 }
426 
460 template <typename InType1, typename InType2, typename InType3, typename OutType,
461  unsigned int VectorLength, bool Unroll>
466 
467  if (Unroll == true) {
468 #pragma hls_unroll yes
469  for (unsigned i = 0; i < VectorLength; i++)
470  out[i] = in1[i] * in2[i] + in3[i];
471  } else {
472  for (unsigned i = 0; i < VectorLength; i++)
473  out[i] = in1[i] * in2[i] + in3[i];
474  }
475 }
476 
477 
478 // Function implementing vector dot product followed by accumulate Template
479 // parameters: InType1, InType2,InType3 OutType are the data types for
480 // inputs and output. This function performs dot-product of 2 input vectors
481 // of "InType1" and "InType2" types, adds the results to 3rd scalar input of
482 //"InType3" type and produces scalar output of type "OutType". Vector
483 // length of first 2 inputs is "VectorLength". If InType1, InType2, InType3
484 // and OutType are user-defined types, then OutType = InType3, OutType +=
485 // InType1*InType2 operations should be defined by the user
486 template <typename InType1, typename InType2, typename InType3,
487  typename OutType, unsigned int VectorLength, bool UseReduceTree>
489  nv_scvector<InType2, VectorLength> in2, InType3 in3, OutType& out) {
490  OutType sum = in3;
491  if (UseReduceTree == true) {
492 #pragma hls_unroll yes
493 #pragma cluster addtree
494 #pragma cluster_type both
495  for (unsigned i = 0; i < VectorLength; i++)
496  sum += in1[i] * in2[i];
497  } else {
498  for (unsigned i = 0; i < VectorLength; i++)
499  sum += in1[i] * in2[i];
500  }
501  out = sum;
502 }
503 };
504 
505 #endif
Vector helper container with vector operations.
Definition: nvhls_vector.h:77
void vector_sub(nv_scvector< InType1, VectorLength > in1, nv_scvector< InType2, VectorLength > in2, nv_scvector< OutType, VectorLength > &out)
Function implementing vector subtraction.
Definition: nvhls_vector.h:304
type1 set_slc(type1 X, type2 Y, const unsigned int i)
Function that replaces slice of bits.
Definition: nvhls_int.h:387
void vector_add(nv_scvector< InType1, VectorLength > in1, nv_scvector< InType2, VectorLength > in2, nv_scvector< OutType, VectorLength > &out)
Function implementing vector addition.
Definition: nvhls_vector.h:258
void vector_mac(nv_scvector< InType1, VectorLength > in1, nv_scvector< InType2, VectorLength > in2, nv_scvector< InType3, VectorLength > in3, nv_scvector< OutType, VectorLength > &out)
Function implementing vector multiply and add.
Definition: nvhls_vector.h:462
void vector_mul(nv_scvector< InType1, VectorLength > in1, nv_scvector< InType2, VectorLength > in2, nv_scvector< OutType, VectorLength > &out)
Function implementing vector multiplication.
Definition: nvhls_vector.h:210
void reduction(nv_scvector< InType, VectorLength > in, OutType &out)
Function implementing vector reduction.
Definition: nvhls_vector.h:350
void dp(nv_scvector< InType1, VectorLength > in1, nv_scvector< InType2, VectorLength > in2, OutType &out)
Function implementing vector dot-product.
Definition: nvhls_vector.h:406