MatchLib
mem_array.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 MEM_ARRAY_H
17 #define MEM_ARRAY_H
18 
19 #include <nvhls_int.h>
20 #include <nvhls_types.h>
21 #include <nvhls_array.h>
22 #include <nvhls_marshaller.h>
23 #include <TypeToBits.h>
24 
25 // T: data type
26 // N: number of lines
27 template <typename T, int N>
28 class mem_array {
29  public:
30  T data[N];
31  mem_array() {
32  T value;
33  for (unsigned i = 0; i < N; i++) {
34 #ifndef SLEC_CPC
35  data[i] = value;
36 #endif
37  }
38  }
39 };
40 
41 // T: data type
42 // N: number of lines
43 // A: associativity
44 template <typename T, int N, int A>
45 class mem_array_2d {
46  public:
47  T data[N / A][A];
48 };
49 
50 template <typename T, int N, int A>
52  public:
53  T data[A][N / A];
54 };
55 
82 template <typename T, int NumEntries, int NumBanks, int NumByteEnables=1>
84  public:
85  typedef Wrapped<T> WData_t;
86  static const unsigned int NumEntriesPerBank = NumEntries/NumBanks;
87  static const unsigned int WordWidth = WData_t::width;
88  static const unsigned int SliceWidth = WordWidth/NumByteEnables;
91  typedef NVUINTW(nvhls::index_width<NumBanks>::val) BankIndex;
92  typedef sc_lv<WordWidth> Data_t;
93  typedef sc_lv<SliceWidth> Slice_t;
94  typedef NVUINTW(NumByteEnables) WriteMask;
95  typedef NVUINTW(nvhls::index_width<NumByteEnables>::val) ByteEnableIndex;
96 
97  typedef Slice_t BankType[NumEntriesPerBank*NumByteEnables];
99  static const int width = NumEntries * WordWidth;
100 
101  mem_array_sep() {
102  Slice_t value;
103  for (unsigned i = 0; i < NumBanks; i++) {
104  for (unsigned j = 0; j < NumByteEnables* NumEntriesPerBank; j++) {
105 #ifndef SLEC_CPC
106  bank[i][j] = value;
107 #endif
108  }
109  }
110  }
111 
112  void clear() {
113  Slice_t value = 0;
114  for (unsigned i = 0; i < NumBanks; i++) {
115  for (unsigned j = 0; j < NumByteEnables * NumEntriesPerBank; j++) {
116  bank[i][j] = value;
117  }
118  }
119  }
120 
121  T read(LocalIndex idx, BankIndex bank_sel=0) {
122  Data_t read_data = TypeToBits<NVUINTW(WordWidth)>(0);
123  #pragma hls_unroll yes
124  for (int i = 0; i < NumByteEnables; i++) {
125  LocalSliceIndex local_slice_index = idx * NumByteEnables + i;
126  NVHLS_ASSERT_MSG(bank_sel<NumBanks, "bank index out of bounds");
127  NVHLS_ASSERT_MSG(idx<NumEntriesPerBank, "local index out of bounds");
128  read_data.range((i+1)*SliceWidth-1, i*SliceWidth) = bank[bank_sel][local_slice_index];
129  }
130  CMOD_ASSERT_MSG(read_data.xor_reduce()!=sc_logic('X'), "Read data is X");
131  return BitsToType<T>(read_data);
132  }
133 
134  void write(LocalIndex idx, BankIndex bank_sel, T val, WriteMask write_mask=~static_cast<WriteMask>(0), bool wce=1) {
135  Slice_t tmp[NumByteEnables];
136  Data_t write_data = TypeToBits<T>(val);
137  #pragma hls_unroll yes
138  for (int i = 0; i < NumByteEnables; i++) {
139  tmp[i] = write_data.range((i+1)*SliceWidth-1, i*SliceWidth);
140  }
141  if (wce) {
142  #pragma hls_unroll yes
143  for (int i = 0; i < NumByteEnables; i++) {
144  if (write_mask[i] == 1) {
145  LocalSliceIndex local_slice_index = idx * NumByteEnables + i;
146  NVHLS_ASSERT_MSG(bank_sel<NumBanks, "bank index out of bounds");
147  NVHLS_ASSERT_MSG(idx<NumEntriesPerBank, "local index out of bounds");
148  bank[bank_sel][local_slice_index] = tmp[i];
149  CMOD_ASSERT_MSG(tmp[i].xor_reduce()!=sc_logic('X'), "Write data is X");
150  }
151  }
152  }
153  }
154 
155  template<unsigned int Size>
156  void Marshall(Marshaller<Size>& m) {
157  for (unsigned i = 0; i < NumBanks; i++) {
158  for (unsigned j = 0; j < NumByteEnables* NumEntriesPerBank; j++) {
159  m & bank[i][j];
160  }
161  }
162  }
163 };
164 
165 
166 #endif
NVUINTW(Wrapped< T >::width) TypeToNVUINT(T in)
Convert Type to NVUINT.
Definition: TypeToBits.h:115
Compute index width of a constant.
Definition: nvhls_int.h:285
Abstract Memory Class.
Definition: mem_array.h:83
#define NVHLS_ASSERT_MSG(X, MSG)
Definition: nvhls_assert.h:116
#define CMOD_ASSERT_MSG(X, MSG)
Definition: nvhls_assert.h:144